No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

sm_value.cpp 5.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. #include <Arduino.h>
  2. #include "config.h"
  3. #include "config_pins.h"
  4. #include "lcd.h"
  5. #include "states.h"
  6. template <typename T>
  7. StateValue<T>::StateValue(State *_parent, T &_value, T _min, T _max) : State(_parent), value(_value) {
  8. min = _min;
  9. max = _max;
  10. heading = NULL;
  11. text = NULL;
  12. onEnterFunc = NULL;
  13. updateFunc = NULL;
  14. updateLiveFunc = NULL;
  15. }
  16. template <typename T>
  17. void StateValue<T>::setMax(T _max) {
  18. max = _max;
  19. }
  20. template <typename T>
  21. void StateValue<T>::onUpdate(UpdateFuncPtr func) {
  22. updateFunc = func;
  23. }
  24. template <typename T>
  25. void StateValue<T>::onLiveUpdate(UpdateFuncPtr func) {
  26. updateLiveFunc = func;
  27. }
  28. template <typename T>
  29. void StateValue<T>::display(void) {
  30. lcd_clear();
  31. if (heading == NULL) {
  32. lcd_set_heading(getTitle());
  33. } else {
  34. lcd_set_heading(heading);
  35. }
  36. String s = String(min) + F(" .. ") + String(value) + F(" .. ") + String(max);
  37. if (text != NULL) {
  38. s = text + String(F("\n")) + s;
  39. }
  40. lcd_set_text(s.c_str());
  41. }
  42. template <typename T>
  43. void StateValue<T>::enterState(void) {
  44. if (onEnterFunc != NULL) {
  45. onEnterFunc();
  46. }
  47. display();
  48. }
  49. template <typename T>
  50. void StateValue<T>::inState(StateMachineInput smi) {
  51. if (smi.encoder != 0) {
  52. float vf = smi.encoder;
  53. vf *= 1.0 + ((float)smi.rpm / ENCODER_RPM_VALUE_FACTOR);
  54. int v = vf;
  55. value -= v;
  56. if (value < min) {
  57. value = min;
  58. }
  59. if (value > max) {
  60. value = max;
  61. }
  62. if (updateLiveFunc != NULL) {
  63. updateLiveFunc(value);
  64. }
  65. display();
  66. }
  67. if (smi.click) {
  68. if (updateFunc != NULL) {
  69. updateFunc(value);
  70. }
  71. if (getChild() != NULL) {
  72. states_go_to(getChild());
  73. } else if (getParent() != NULL) {
  74. states_go_to(getParent());
  75. }
  76. }
  77. }
  78. template class StateValue<int>;
  79. template class StateValue<float>;
  80. // --------------------------------------
  81. template <typename T, size_t N>
  82. StateValues<T, N>::StateValues(State *_parent) : State(_parent) {
  83. heading = NULL;
  84. onEnterFunc = NULL;
  85. updateFunc = NULL;
  86. updateLiveFunc = NULL;
  87. pos = 0;
  88. editing = false;
  89. }
  90. template <typename T, size_t N>
  91. void StateValues<T, N>::setData(size_t index, const char *name, T *value, T min, T max) {
  92. if (index >= N) {
  93. return;
  94. }
  95. values[index] = value;
  96. mins[index] = min;
  97. maxs[index] = max;
  98. texts[index] = name;
  99. }
  100. template <typename T, size_t N>
  101. void StateValues<T, N>::onUpdate(UpdateFuncPtr func) {
  102. updateFunc = func;
  103. }
  104. template <typename T, size_t N>
  105. void StateValues<T, N>::onLiveUpdate(UpdateFuncPtr func) {
  106. updateLiveFunc = func;
  107. }
  108. template <typename T, size_t N>
  109. void StateValues<T, N>::display(void) {
  110. lcd_clear();
  111. if (heading == NULL) {
  112. lcd_set_heading(getTitle());
  113. } else {
  114. lcd_set_heading(heading);
  115. }
  116. for (size_t i = 0; i < (N + 1); i++) {
  117. String s;
  118. if (i == pos) {
  119. if (editing) {
  120. s = F("# ");
  121. } else {
  122. s = F("> ");
  123. }
  124. } else {
  125. s = F(" ");
  126. }
  127. if (i < N) {
  128. s += texts[i] + String(*(values[i])) + F(" (") + String(mins[i]) + F("/") + String(maxs[i]) + F(")");
  129. } else {
  130. if (getChild() != NULL) {
  131. s += F("Continue");
  132. } else {
  133. s += F("Done");
  134. }
  135. }
  136. lcd_set_menu_text(i, s.c_str());
  137. }
  138. }
  139. template <typename T, size_t N>
  140. void StateValues<T, N>::enterState(void) {
  141. pos = 0;
  142. if (onEnterFunc != NULL) {
  143. onEnterFunc();
  144. }
  145. display();
  146. }
  147. template <typename T, size_t N>
  148. void StateValues<T, N>::inState(StateMachineInput smi) {
  149. if (editing) {
  150. if (smi.encoder != 0) {
  151. float vf = smi.encoder;
  152. vf *= 1.0 + ((float)smi.rpm / ENCODER_RPM_VALUE_FACTOR);
  153. int v = vf;
  154. *(values[pos]) -= v;
  155. if (*(values[pos]) < mins[pos]) {
  156. *(values[pos]) = mins[pos];
  157. }
  158. if (*(values[pos]) > maxs[pos]) {
  159. *(values[pos]) = maxs[pos];
  160. }
  161. if (updateLiveFunc != NULL) {
  162. updateLiveFunc(pos, *(values[pos]));
  163. }
  164. display();
  165. }
  166. if (smi.click) {
  167. editing = false;
  168. display();
  169. }
  170. } else {
  171. if (smi.encoder != 0) {
  172. int tmp = pos;
  173. tmp -= smi.encoder;
  174. while (tmp < 0) {
  175. tmp += N + 1;
  176. }
  177. while (tmp >= (N + 1)) {
  178. tmp -= N + 1;
  179. }
  180. pos = tmp;
  181. display();
  182. }
  183. if (smi.click) {
  184. if (pos < N) {
  185. editing = true;
  186. display();
  187. } else {
  188. if (updateFunc != NULL) {
  189. for (size_t i = 0; i < N; i++) {
  190. updateFunc(i, *(values[i]));
  191. }
  192. }
  193. if (getChild() != NULL) {
  194. states_go_to(getChild());
  195. } else if (getParent() != NULL) {
  196. states_go_to(getParent());
  197. }
  198. }
  199. }
  200. }
  201. }
  202. template class StateValues<uint8_t, 2>;
  203. template class StateValues<float, 2>;