#include #include "config.h" #include "config_pins.h" #include "lcd.h" #include "states.h" template StateValue::StateValue(State *_parent, T &_value, T _min, T _max) : State(_parent), value(_value) { min = _min; max = _max; heading = NULL; text = NULL; onEnterFunc = NULL; updateFunc = NULL; updateLiveFunc = NULL; } template void StateValue::setMax(T _max) { max = _max; } template void StateValue::onUpdate(UpdateFuncPtr func) { updateFunc = func; } template void StateValue::onLiveUpdate(UpdateFuncPtr func) { updateLiveFunc = func; } template void StateValue::display(void) { lcd_clear(); if (heading == NULL) { lcd_set_heading(getTitle()); } else { lcd_set_heading(heading); } String s = String(min) + F(" .. ") + String(value) + F(" .. ") + String(max); if (text != NULL) { s = text + String(F("\n")) + s; } lcd_set_text(s.c_str()); } template void StateValue::enterState(void) { if (onEnterFunc != NULL) { onEnterFunc(); } display(); } template void StateValue::inState(StateMachineInput smi) { if (smi.encoder != 0) { float vf = smi.encoder; vf *= 1.0 + ((float)smi.rpm / ENCODER_RPM_VALUE_FACTOR); int v = vf; value -= v; if (value < min) { value = min; } if (value > max) { value = max; } if (updateLiveFunc != NULL) { updateLiveFunc(value); } display(); } if (smi.click) { if (updateFunc != NULL) { updateFunc(value); } if (getChild() != NULL) { states_go_to(getChild()); } else if (getParent() != NULL) { states_go_to(getParent()); } } } template class StateValue; template class StateValue; // -------------------------------------- template StateValues::StateValues(State *_parent) : State(_parent) { heading = NULL; onEnterFunc = NULL; updateFunc = NULL; updateLiveFunc = NULL; pos = 0; editing = false; } template void StateValues::setData(size_t index, const char *name, T *value, T min, T max) { if (index >= N) { return; } values[index] = value; mins[index] = min; maxs[index] = max; texts[index] = name; } template void StateValues::onUpdate(UpdateFuncPtr func) { updateFunc = func; } template void StateValues::onLiveUpdate(UpdateFuncPtr func) { updateLiveFunc = func; } template void StateValues::display(void) { lcd_clear(); if (heading == NULL) { lcd_set_heading(getTitle()); } else { lcd_set_heading(heading); } for (size_t i = 0; i < (N + 1); i++) { String s; if (i == pos) { if (editing) { s = F("# "); } else { s = F("> "); } } else { s = F(" "); } if (i < N) { s += texts[i] + String(*(values[i])) + F(" (") + String(mins[i]) + F("/") + String(maxs[i]) + F(")"); } else { if (getChild() != NULL) { s += F("Continue"); } else { s += F("Done"); } } lcd_set_menu_text(i, s.c_str()); } } template void StateValues::enterState(void) { pos = 0; if (onEnterFunc != NULL) { onEnterFunc(); } display(); } template void StateValues::inState(StateMachineInput smi) { if (editing) { if (smi.encoder != 0) { float vf = smi.encoder; vf *= 1.0 + ((float)smi.rpm / ENCODER_RPM_VALUE_FACTOR); int v = vf; *(values[pos]) -= v; if (*(values[pos]) < mins[pos]) { *(values[pos]) = mins[pos]; } if (*(values[pos]) > maxs[pos]) { *(values[pos]) = maxs[pos]; } if (updateLiveFunc != NULL) { updateLiveFunc(pos, *(values[pos])); } display(); } if (smi.click) { editing = false; display(); } } else { if (smi.encoder != 0) { int tmp = pos; tmp -= smi.encoder; while (tmp < 0) { tmp += N + 1; } while (tmp >= (N + 1)) { tmp -= N + 1; } pos = tmp; display(); } if (smi.click) { if (pos < N) { editing = true; display(); } else { if (updateFunc != NULL) { for (size_t i = 0; i < N; i++) { updateFunc(i, *(values[i])); } } if (getChild() != NULL) { states_go_to(getChild()); } else if (getParent() != NULL) { states_go_to(getParent()); } } } } } template class StateValues; template class StateValues;