COSA
An Object-Oriented Platform for Arduino Programming
Menu.hh
Go to the documentation of this file.
1 
21 #ifndef COSA_MENU_HH
22 #define COSA_MENU_HH
23 
24 #include "Cosa/LCD.hh"
25 #include "Cosa/IOStream.hh"
26 
27 #include <Rotary.h>
28 #include "Cosa/Button.hh"
29 #include "Cosa/Keypad.hh"
30 
35 class Menu {
36 public:
38  enum type_t {
39  ITEM,
46  } __attribute__((packed));
47 
49  struct item_t {
52  };
53  typedef const PROGMEM item_t* item_P;
54  typedef const PROGMEM item_P* item_vec_P;
55 
57  struct item_list_t {
59  item_vec_P list;
60  };
61  typedef const PROGMEM item_list_t* item_list_P;
62 
64  struct one_of_t {
66  item_vec_P list;
67  uint16_t* value;
68  };
69  typedef const PROGMEM one_of_t* one_of_P;
70  static void print(IOStream& outs, one_of_P var);
71 
74  typedef const PROGMEM zero_or_many_t* zero_or_many_P;
75  static void print(IOStream& outs, zero_or_many_P var, bool selected, uint8_t bv);
76 
78  struct bcd_range_t {
80  uint8_t low;
81  uint8_t high;
82  uint8_t* value;
83  };
84  typedef const PROGMEM bcd_range_t* bcd_range_P;
85 
87  struct int_range_t {
89  int16_t low;
90  int16_t high;
91  int16_t* value;
92  };
93  typedef const PROGMEM int_range_t* int_range_P;
94  static void print(IOStream& outs, int_range_P var, bool selected);
95 
101  class Action {
102  public:
110  virtual bool run(Menu::item_P item) = 0;
111  };
112 
114  struct action_t {
117  };
118  typedef const PROGMEM action_t* action_P;
119 
124  class Walker {
125  private:
127  static const uint8_t STACK_MAX = 8;
128  Menu::item_list_P m_stack[STACK_MAX];
129  uint8_t m_top;
130 
132  uint8_t m_ix;
133 
135  uint8_t m_bv;
136 
138  bool m_selected;
139 
141  IOStream m_out;
142 
143  void on_key_down(uint8_t nr, zero_or_many_P var);
144 
145  public:
147  enum {
148  NO_KEY = 0,
153  RIGHT_KEY
154  } __attribute__((packed));
155 
161  Walker(LCD::Device* lcd, item_list_P root) :
162  m_top(0),
163  m_ix(0),
164  m_bv(0),
165  m_selected(false),
166  m_out(lcd)
167  {
168  m_stack[m_top] = root;
169  }
170 
177  void on_key_down(uint8_t nr);
178 
186  friend IOStream& operator<<(IOStream& outs, Walker& walker);
187 
192  void begin(bool flag = true)
193  {
194  if (flag) m_out << clear << *this;
195  }
196 
200  Menu::type_t type();
201  };
202 
208  class KeypadController : public LCD::Keypad {
209  public:
211 
212  public:
217  KeypadController(Walker* walker, Job::Scheduler* scheduler) :
218  LCD::Keypad(scheduler),
219  m_walker(walker)
220  {}
221 
227  virtual void on_key_down(uint8_t nr)
228  {
229  m_walker->on_key_down(nr);
230  }
231  };
232 
239  private:
240  class RotaryButton : public Button {
241  private:
242  Menu::Walker* m_walker;
243 
244  public:
251  RotaryButton(Menu::Walker* walker,
252  Job::Scheduler* scheduler,
254  Button(scheduler, pin, Button::ON_FALLING_MODE),
255  m_walker(walker)
256  {}
257 
263  virtual void on_change(uint8_t type)
264  {
265  UNUSED(type);
266  m_walker->on_key_down(Menu::Walker::SELECT_KEY);
267  }
268  };
269 
271  Menu::Walker* m_walker;
272 
274  RotaryButton m_sw;
275 
276  public:
286  Job::Scheduler* scheduler,
290  Rotary::Encoder(clk, dt),
291  m_walker(walker),
292  m_sw(walker, scheduler, sw)
293  {}
294 
302  virtual void on_event(uint8_t type, uint16_t direction);
303 
307  void begin()
308  {
310  m_sw.start();
311  }
312  };
313 };
314 
326 #define MENU_BEGIN(var,name) \
327  const char var ## _name[] __PROGMEM = name; \
328  const Menu::item_P var ## _list[] __PROGMEM = {
329 
336 #define MENU_ITEM(var) \
337  &var.item,
338 
343 #define MENU_END(var) \
344  0 \
345  }; \
346  const Menu::item_list_t var __PROGMEM = { \
347  { \
348  Menu::ITEM_LIST, \
349  (str_P) var ## _name \
350  }, \
351  var ## _list \
352 };
353 
359 #define MENU_SYMB(var,name) \
360  const char var ## _name[] __PROGMEM = name; \
361  const Menu::item_t var __PROGMEM = { \
362  Menu::ITEM, \
363  (str_P) var ## _name \
364  };
365 
380 #define MENU_ENUM_BEGIN(var) \
381  const Menu::item_P var ## _list[] __PROGMEM = {
382 
388 #define MENU_ENUM_ITEM(var) \
389  &var,
390 
395 #define MENU_ENUM_END(var) \
396  0 \
397  };
398 
406 #define MENU_ONE_OF(type,var,name,value) \
407  const char var ## _name[] __PROGMEM = name; \
408  const Menu::one_of_t var __PROGMEM = { \
409  { \
410  Menu::ONE_OF, \
411  (str_P) var ## _name \
412  }, \
413  type ## _list, \
414  &value \
415 };
416 
424 #define MENU_ZERO_OR_MANY(type,var,name,value) \
425  const char var ## _name[] __PROGMEM = name; \
426  const Menu::zero_or_many_t var __PROGMEM = { \
427  { \
428  Menu::ZERO_OR_MANY, \
429  (str_P) var ## _name \
430  }, \
431  type ## _list, \
432  &value \
433 };
434 
443 #define MENU_INT_RANGE(var,name,low,high,value) \
444  const char var ## _name[] __PROGMEM = name; \
445  const Menu::int_range_t var __PROGMEM = { \
446  { \
447  Menu::INT_RANGE, \
448  (str_P) var ## _name \
449  }, \
450  low, \
451  high, \
452  &value \
453 };
454 
461 #define MENU_ACTION(var,name,obj) \
462  const char var ## _name[] __PROGMEM = name; \
463  const Menu::action_t var __PROGMEM = { \
464  { \
465  Menu::ACTION, \
466  (str_P) var ## _name \
467  }, \
468  &obj \
469  };
470 #endif
item_t item
Item header(ONE_OF).
Definition: Menu.hh:65
Menu integer range variable.
Definition: Menu.hh:44
Walker * m_walker
Definition: Menu.hh:210
Walker(LCD::Device *lcd, item_list_P root)
Definition: Menu.hh:161
type_t
Definition: Menu.hh:38
int16_t low
Range low value.
Definition: Menu.hh:89
Menu action.
Definition: Menu.hh:45
int16_t * value
Pointer to value.
Definition: Menu.hh:91
KeypadController(Walker *walker, Job::Scheduler *scheduler)
Definition: Menu.hh:217
Definition: Button.hh:56
uint8_t high
Range high value.
Definition: Menu.hh:81
const item_P * item_vec_P
Definition: Menu.hh:54
Definition: Keypad.hh:33
IOStream & operator<<(IOStream &outs, SPI::Clock rate)
Definition: SPI.cpp:307
item_t item
Item header(BCD_RANGE).
Definition: Menu.hh:79
item_vec_P list
Item list in program memory.
Definition: Menu.hh:66
item_vec_P list
Item list in program memory.
Definition: Menu.hh:59
item_t item
Item header(INT_RANGE).
Definition: Menu.hh:88
uint8_t low
Range low value.
Definition: Menu.hh:80
RotaryController(Menu::Walker *walker, Job::Scheduler *scheduler, Board::InterruptPin clk=Board::PCI4, Board::InterruptPin dt=Board::PCI3, Board::DigitalPin sw=Board::D2)
Definition: Menu.hh:285
const class prog_str * str_P
Definition: Types.h:187
const zero_or_many_t * zero_or_many_P
Definition: Menu.hh:74
Action * obj
Pointer to action handler.
Definition: Menu.hh:116
one_of_t zero_or_many_t
Definition: Menu.hh:73
const item_t * item_P
Definition: Menu.hh:53
const item_list_t * item_list_P
Definition: Menu.hh:61
#define UNUSED(x)
Definition: ATmega328P.hh:31
type_t type
Item type tag(ITEM).
Definition: Menu.hh:50
uint8_t * value
Pointer to value.
Definition: Menu.hh:82
item_t item
Item header(ACTION).
Definition: Menu.hh:115
static void print(IOStream &outs, one_of_P var)
Definition: Menu.cpp:24
const action_t * action_P
Definition: Menu.hh:118
uint16_t * value
Pointer to value.
Definition: Menu.hh:67
Menu bcd(2) range variable.
Definition: Menu.hh:43
const int_range_t * int_range_P
Definition: Menu.hh:93
Definition: Menu.hh:35
const one_of_t * one_of_P
Definition: Menu.hh:69
const bcd_range_t * bcd_range_P
Definition: Menu.hh:84
Menu item/symbol.
Definition: Menu.hh:39
int16_t high
Range high value.
Definition: Menu.hh:90
Definition: LCD.hh:36
str_P name
Item string in program memory.
Definition: Menu.hh:51
void begin(bool flag=true)
Definition: Menu.hh:192
IOStream & clear(IOStream &outs)
Definition: IOStream.hh:841
Definition: Rotary.hh:40
Menu bitset variable (zero-or-many).
Definition: Menu.hh:42
item_t item
Item header(ITEM_LIST).
Definition: Menu.hh:58
Menu enumeration variable (one-of).
Definition: Menu.hh:41
virtual void on_key_down(uint8_t nr)
Definition: Menu.hh:227
Menu item/enum list.
Definition: Menu.hh:40