123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- #include <Arduino.h>
-
- #include "config.h"
- #include "config_pins.h"
- #include "lcd.h"
- #include "states.h"
-
- template <typename T, size_t N>
- void array_print(Array<T, N> *arr) {
- Serial.print(F("Array length: "));
- Serial.print(arr->size());
- Serial.println(F(" contents:"));
- for (int i = 0; i < arr->size(); i++) {
- Serial.print(i);
- Serial.print(F(": "));
- 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;
- }
-
- // --------------------------------------
-
- 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 = F("> ");
- } else {
- s = F(" ");
- }
- 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;
- prefix = "";
- countFunc = NULL;
- getFunc = NULL;
- callFunc = NULL;
- }
-
- 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 = F("> ");
- } else {
- s = F(" ");
- }
- if (i == count) {
- s += getParent()->getTitle();
- } else {
- s += contents.at(i);
- }
- lcd_set_menu_text(i - menuOff, s.c_str());
- }
- }
-
- void StateDynamicMenu::setPrefix(String pre) {
- prefix = pre;
- }
-
- 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(prefix + String(getFunc(i)));
- } else {
- contents.push_back(prefix + String(i + 1));
- }
- }
-
- 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);
- }
- }
- }
- }
|