123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325 |
- #include <Arduino.h>
-
- #include "config.h"
- #include "config_pins.h"
- #include "lcd.h"
- #include "states.h"
-
- State::State(State *_parent) : parent(_parent), child(NULL), title("no title") {
- if (_parent != NULL) {
- _parent->setChild(this);
- }
- }
-
- // --------------------------------------
-
- StateText::StateText(State *_parent) : State(_parent) {
- heading = "no heading";
- text = "text missing";
- onEnterFunc = []() { };
- whenInFunc = [](StateMachineInput smi) {
- State *s = states_get();
- if (smi.click && (s != NULL)) {
- if (s->getChild() != NULL) {
- states_go_to(s->getChild());
- } else if (s->getParent() != NULL) {
- states_go_to(s->getParent());
- }
- }
- };
- }
-
- void StateText::setHeading(const char *_heading) {
- heading = _heading;
- }
-
- void StateText::setText(const char *_text) {
- text = _text;
- }
-
- void StateText::onEnter(EnterFuncPtr func) {
- onEnterFunc = func;
- }
-
- void StateText::whenIn(InFuncPtr func) {
- whenInFunc = func;
- }
-
- void StateText::enterState(void) {
- if (onEnterFunc != NULL) {
- onEnterFunc();
- }
-
- lcd_clear();
- lcd_set_heading(heading);
- lcd_set_text(text);
- }
-
- void StateText::inState(struct StateMachineInput smi) {
- if (whenInFunc != NULL) {
- whenInFunc(smi);
- }
- }
-
- // --------------------------------------
-
- StateMenu::StateMenu(State *_parent, bool _show_parent) : State(_parent) {
- show_parent = _show_parent;
- menuPos = 0;
- menuOff = 0;
- }
-
- void StateMenu::setChild(State *_child) {
- children.push_back(_child);
- }
-
- void StateMenu::addChild(State *_child, int pos) {
- if (pos < 0) {
- setChild(_child);
- } else {
- array_insert_at_pos(&children, _child, pos);
- }
- }
-
- void StateMenu::enterState(void) {
- display();
- }
-
- void StateMenu::display(void) {
- lcd_clear();
- lcd_set_heading(getTitle());
-
- int size = children.size();
- if (show_parent) {
- size++;
- }
-
- for (int i = menuOff; (i < menuOff + lcd_text_lines()) && (i < size); i++) {
- String s = "";
- if (i == menuPos) {
- s += "> ";
- } else {
- s += " ";
- }
- if (i == children.size()) {
- s += getParent()->getTitle();
- } else {
- s += children.at(i)->getTitle();
- }
- lcd_set_menu_text(i - menuOff, s.c_str());
- }
- }
-
- void StateMenu::inState(struct StateMachineInput smi) {
- int size = children.size();
- if (show_parent) {
- size++;
- }
-
- if (smi.encoder != 0) {
- menuPos -= smi.encoder;
-
- while (menuPos < 0) {
- menuPos += size;
- }
-
- while (menuPos >= size) {
- menuPos -= size;
- }
-
- while (menuPos < menuOff) {
- menuOff--;
- }
-
- while (menuPos >= (menuOff + lcd_text_lines())) {
- menuOff++;
- }
-
- display();
- }
-
- if (smi.click) {
- if (menuPos == children.size()) {
- menuPos = 0;
- menuOff = 0;
- states_go_to(getParent());
- } else {
- states_go_to(children.at(menuPos));
- }
- }
- }
-
- // --------------------------------------
-
- StateDynamicMenu::StateDynamicMenu(State *_parent) : State(_parent) {
- menuPos = 0;
- menuOff = 0;
- }
-
- void StateDynamicMenu::dataCount(CountFuncPtr count) {
- countFunc = count;
- }
-
- void StateDynamicMenu::dataGet(GetFuncPtr get) {
- getFunc = get;
- }
-
- void StateDynamicMenu::dataCall(CallFuncPtr call) {
- callFunc = call;
- }
-
- void StateDynamicMenu::display(void) {
- lcd_clear();
- lcd_set_heading(getTitle());
-
- for (int i = menuOff; (i < menuOff + lcd_text_lines()) && (i < count + 1); i++) {
- String s = "";
- if (i == menuPos) {
- s += "> ";
- } else {
- s += " ";
- }
- if (i == count) {
- s += getParent()->getTitle();
- } else {
- s += contents.at(i);
- }
- lcd_set_menu_text(i - menuOff, s.c_str());
- }
- }
-
- void StateDynamicMenu::enterState(void) {
- // cache all entries on entering state
- if (countFunc != NULL) {
- count = countFunc();
- } else {
- count = 0;
- }
- contents.clear();
- for (int i = 0; i < count; i++) {
- if (getFunc != NULL) {
- contents.push_back(getFunc(i));
- } else {
- contents.push_back("no get func");
- }
- }
-
- display();
- }
-
- void StateDynamicMenu::inState(StateMachineInput smi) {
- if (smi.encoder != 0) {
- menuPos -= smi.encoder;
-
- while (menuPos < 0) {
- menuPos += count + 1;
- }
-
- while (menuPos >= count + 1) {
- menuPos -= count + 1;
- }
-
- while (menuPos < menuOff) {
- menuOff--;
- }
-
- while (menuPos >= (menuOff + lcd_text_lines())) {
- menuOff++;
- }
-
- display();
- }
-
- if (smi.click) {
- if (menuPos == count) {
- menuPos = 0;
- menuOff = 0;
- states_go_to(getParent());
- } else {
- if (callFunc != NULL) {
- callFunc(menuPos);
- }
- }
- }
- }
-
- // --------------------------------------
-
- template <typename T>
- StateValue<T>::StateValue(State *_parent, T &_value, T _min, T _max) : State(_parent), value(_value) {
- min = _min;
- max = _max;
- updateFunc = NULL;
- }
-
- template <typename T>
- void StateValue<T>::onUpdate(UpdateFuncPtr func) {
- updateFunc = func;
- }
-
- template <typename T>
- void StateValue<T>::display(void) {
- String s = String(min) + " .. " + String(value) + " .. " + String(max);
- lcd_set_text(s.c_str());
- }
-
- template <typename T>
- void StateValue<T>::enterState(void) {
- lcd_clear();
- lcd_set_heading(getTitle());
-
- display();
- }
-
- template <typename T>
- void StateValue<T>::inState(StateMachineInput smi) {
- if (smi.encoder != 0) {
- value -= smi.encoder;
- if (value < min) {
- value = min;
- }
- if (value > max) {
- value = max;
- }
- display();
- }
- if (smi.click) {
- if (updateFunc != NULL) {
- updateFunc(value);
- }
- states_go_to(getParent());
- }
- }
-
- template class StateValue<float>;
-
- // --------------------------------------
-
- template <typename T, size_t N>
- void array_print(Array<T, N> *arr) {
- Serial.print("Array length: ");
- Serial.print(arr->size());
- Serial.println(" contents:");
- for (int i = 0; i < arr->size(); i++) {
- Serial.print(i);
- Serial.print(": ");
- Serial.println(arr->at(i)->getTitle());
- }
- }
-
- template <typename T, size_t N>
- void array_insert_at_pos(Array<T, N> *arr, T value, size_t pos) {
- // make additional space
- arr->push_back(value);
-
- if ((pos >= arr->max_size()) || (pos >= arr->size())) {
- // we can not shift it to the given position
- return;
- }
-
- for (int i = arr->size() - 2; i >= pos; i--) {
- arr->at(i + 1) = arr->at(i);
- }
-
- arr->at(pos) = value;
- }
|