RSeries astromech firmware
CommandScreen.h
Go to the documentation of this file.
1 #ifndef CommandScreen_h
2 #define CommandScreen_h
3 
4 #include "ReelTwo.h"
5 
6 #ifdef USE_SCREEN_DEBUG
7 #define MENU_SCREEN_DEBUG_PRINTLN(s) DEBUG_PRINTLN(s)
8 #define MENU_SCREEN_DEBUG_PRINT(s) DEBUG_PRINT(s)
9 #define MENU_SCREEN_DEBUG_PRINTLN_HEX(s) DEBUG_PRINTLN_HEX(s)
10 #define MENU_SCREEN_DEBUG_PRINT_HEX(s) DEBUG_PRINT_HEX(s)
11 #define MENU_SCREEN_DEBUG_FLUSH(s) DEBUG_FLUSH()
12 #else
13 #define MENU_SCREEN_DEBUG_PRINTLN(s)
14 #define MENU_SCREEN_DEBUG_PRINT(s)
15 #define MENU_SCREEN_DEBUG_PRINTLN_HEX(s)
16 #define MENU_SCREEN_DEBUG_PRINT_HEX(s)
17 #define MENU_SCREEN_DEBUG_FLUSH(s)
18 #endif
19 
20 const typedef struct SerialCommand_t {
21  char label[30];
22  char cmd[15];
24 
26 {
27 public:
28  CommandMenu(SerialCommand* cmds, uint8_t siz) :
29  fCommands(cmds),
30  fSize(siz),
31  fValue(0)
32  {
33  }
34 
36  {
37  return &(fCommands[index % fSize]);
38  }
39 
40  const char* getButtonLabel(int index, char* buf, size_t maxSize)
41  {
42  strncpy_P(buf, getSerialCommand(index)->label, maxSize);
43  if (strlen(buf) > 9)
44  {
45  char *ix = buf;
46  int n = 0;
47  while ((ix = strchr(ix, ' ')) != nullptr)
48  {
49  *ix++ = '\n';
50  n++;
51  }
52  }
53  return buf;
54  }
55 
56  const char* getLabel(int index, char* buf, size_t maxSize)
57  {
58  strncpy_P(buf, getSerialCommand(index)->label, maxSize);
59  return buf;
60  }
61 
62  const char* getCommand(int index, char* buf, size_t maxSize)
63  {
64  strncpy_P(buf, getSerialCommand(index)->cmd, maxSize);
65  size_t len = strlen(buf);
66  if (len > 0)
67  {
68  maxSize = (len + 1 < maxSize) ? len : maxSize-2;
69  buf[maxSize] = '\r';
70  buf[maxSize+1] = '\0';
71  }
72  return buf;
73  }
74 
75  uint8_t getSize()
76  {
77  return fSize;
78  }
79 
80  void draw(int x, int y)
81  {
82  if (fSize == 0)
83  return;
84  // if ((GD.inputs.track_tag & 0xff) == kTAG_SLIDER)
85  // fValue = GD.inputs.track_val;
86 
87  // GD.SaveContext();
88 
89  // // Setup slider and track
90  // GD.Tag(kTAG_SLIDER);
91  // GD.cmd_slider(455, 20, 15, 220, 0, fValue, 0xFFFF);
92  // GD.cmd_track(455, 20, 15, 220, kTAG_SLIDER);
93 
94  // // Draw menu buttons
95  // char buf[32];
96  // int lineSize = (0xFFFF / (fSize / 3)) * 2;
97  // for (int gridy = 0; gridy < 5; gridy++)
98  // {
99  // for (int gridx = 0; gridx < 3; gridx++)
100  // {
101  // int tag = (gridy + fValue / lineSize) * 3 + gridx;
102  // if (tag >= fSize)
103  // break;
104  // getButtonLabel(tag, buf, sizeof(buf));
105  // if (buf[0] == '\0')
106  // continue;
107  // GD.Tag(tag+1);
108  // GD.ColorRGB(0xf7931e);
109  // GD.cmd_fgcolor((currentSelection() == tag+1) ? 0x75715e : 0x171812);
110  // GD.cmd_button(x + (90*gridx), y + (50*gridy), 80, 40, 16, 0, buf);
111  // }
112  // }
113  // GD.RestoreContext();
114  }
115 
116  inline uint8_t getSelected()
117  {
118  return fSelected;
119  }
120 
121  bool handleSelection(uint8_t selection)
122  {
123  if (selection > 0 && selection < fSize)
124  {
125  fSelected = selection-1;
126  return true;
127  }
128  return false;
129  }
130 
131  void changeCommands(SerialCommand* newCommands, uint8_t newSize)
132  {
133  fCommands = newCommands;
134  fSize = newSize;
135  fValue = 0;
136  }
137 
138 private:
139  SerialCommand *fCommands;
140  uint8_t fSize;
141  uint16_t fValue;
142  uint8_t fSelected;
143 };
144 
145 class CommandScreen;
146 
148 {
149 public:
150  CommandScreenHandler(uint32_t screenBlankDelay = 15000) :
151  fScreenBlankDelay(screenBlankDelay)
152  {}
153 
155  {
156  return fCurrentScreen;
157  }
158 
159  ScreenID currentID();
160  CommandScreen* findScreen(ScreenID id);
161 
162  unsigned getNumScreens();
163  CommandScreen* getScreenAt(unsigned index);
164 
165  inline void setScreenBlankDelay(uint32_t millis)
166  {
167  fScreenBlankDelay = millis;
168  }
169 
170  inline uint32_t getScreenSleepDuration()
171  {
172  return (isSleeping()) ? millis() - fLastMillis : 0;
173  }
174 
175  void switchToScreen(ScreenID id, bool popStack = true)
176  {
177  CommandScreen* scr = findScreen(id);
178  if (scr != nullptr)
179  {
180  fCurrentScreen = scr;
181  }
182  else
183  {
184  MENU_SCREEN_DEBUG_PRINTLN("SCREEN NOT FOUND: "+String(id));
185  }
186  if (popStack)
187  fScreenIDSP = 0;
188  }
189 
190  void pushScreen(ScreenID id)
191  {
193  {
195  switchToScreen(id, false);
196  }
197  else
198  {
199  MENU_SCREEN_DEBUG_PRINTLN("STACK TOO DEEP");
200  }
201  }
202 
203  void popScreen()
204  {
205  if (fScreenIDSP > 0)
206  {
207  ScreenID id = fScreenIDStack[--fScreenIDSP];
208  switchToScreen(id, false);
209  }
210  }
211 
212  void blankScreen()
213  {
214  if ((fScreenState & 0x1) == 0)
215  {
216  fScreenState |= 0x1;
217  sleepDevice();
218  }
219  }
220 
221  void restoreScreen();
222 
223  bool isSleeping() const
224  {
225  return (fScreenState & 0x1) == 0x1;
226  }
227 
228  void process();
229 
230  uint32_t elapsed()
231  {
232  return millis() - fScreenStartMillis;
233  }
234 
235  inline bool isEnabled() const { return fEnabled; }
236  void setEnabled(bool enabled)
237  {
238  fEnabled = enabled;
239  }
240 
241 protected:
242  friend class CommandScreen;
243  CommandScreen* fHead = nullptr;
244  CommandScreen* fTail = nullptr;
246  uint8_t fScreenState = 0;
247  uint32_t fScreenStartMillis = 0;
248  uint32_t fLastMillis = 0;
251  bool fScreenTouched = false;
252  bool fEnabled = false;
253  uint8_t fScreenIDSP = 0;
254  ScreenID fScreenIDStack[5];
255 
256  virtual void clearContext() {}
257  virtual void wakeDevice() {}
258  virtual void sleepDevice() {}
259  virtual void saveContext() {}
260  virtual void restoreContext() {}
261  virtual bool isTouching() { return false; }
262  virtual void swapDevice() {}
263  virtual uint8_t currentSelection() { return 0; }
264  virtual bool handleEvent() { return false; }
265 
267  {
268  fLastMillis = millis();
269  }
270  void append(CommandScreen* screen);
271 };
272 
274 {
275 public:
276  CommandScreen(CommandScreenHandler &handler, ScreenID id, SerialCommand* cmds = nullptr, uint8_t siz = 0) :
277  fID(id),
278  fMenu(cmds, siz),
279  fLastTag(0),
280  fHandler(handler),
281  fNext(nullptr)
282  {
283  handler.append(this);
284  }
285 
286  inline ScreenID ID() const
287  {
288  return fID;
289  }
290 
291  inline uint8_t getSelected() const
292  {
293  return fLastTag;
294  }
295 
296  virtual void init() {}
297  virtual void exit() {}
298  virtual void handleSelection(uint8_t selection) { UNUSED_ARG(selection) }
299  virtual void render() = 0;
300  virtual bool handleEvent() { return false; }
301  virtual bool isActive() { return false; }
302  virtual bool isStatus() { return false; }
303  void switchToScreen(ScreenID id)
304  {
305  fHandler.switchToScreen(id);
306  }
307  void pushScreen(ScreenID id)
308  {
309  fHandler.pushScreen(id);
310  }
311  void popScreen()
312  {
313  fHandler.popScreen();
314  }
316  {
317  fHandler.restoreScreen();
318  }
319  inline unsigned getKeyRepeatRate() const
320  {
321  return fKeyRepeatRateMS;
322  }
323  void setKeyRepeatRate(unsigned ms)
324  {
325  fKeyRepeatRateMS = ms;
326  }
327  virtual void buttonUpPressed(bool repeat = false) {}
328  virtual void buttonLeftPressed(bool repeat = false) {}
329  virtual void buttonDownPressed(bool repeat = false) {}
330  virtual void buttonRightPressed(bool repeat = false) {}
331  virtual void buttonInPressed(bool repeat = false) {}
332  virtual void buttonUpReleased() {}
333  virtual void buttonLeftReleased() {}
334  virtual void buttonDownReleased() {}
335  virtual void buttonRightReleased() {}
336  virtual void buttonInReleased() {}
337  virtual void buttonDial(long newValue, long oldValue = 0)
338  {
339  if (newValue > oldValue)
340  {
341  buttonUpPressed();
342  }
343  else
344  {
346  }
347  }
348 
349 protected:
350  static void toggleMaskBit(uint8_t &mask, uint8_t bit)
351  {
352  if ((mask & bit) == 0)
353  mask |= bit;
354  else
355  mask &= ~bit;
356  }
357  static void toggleMaskBit(uint16_t &mask, uint16_t bit)
358  {
359  if ((mask & bit) == 0)
360  mask |= bit;
361  else
362  mask &= ~bit;
363  }
365  {
366  fLastTag = 0;
367  }
368  inline bool hasMenu()
369  {
370  return (fMenu.getSize() != 0);
371  }
372  ScreenID fID;
374  uint8_t fLastTag;
375  unsigned fKeyRepeatRateMS = 0;
376 
377 private:
378  friend class CommandScreenHandler;
379  CommandScreenHandler &fHandler;
380  CommandScreen* fNext;
381 };
382 
384 {
385  return (fCurrentScreen != nullptr) ? fCurrentScreen->fID : kInvalid;
386 }
387 
389 {
390  for (CommandScreen* scr = fHead; scr != nullptr; scr = scr->fNext)
391  {
392  if (scr->fID == id)
393  return scr;
394  }
395  return nullptr;
396 }
397 
399 {
400  unsigned count = 0;
401  for (CommandScreen* scr = fHead; scr != nullptr; scr = scr->fNext)
402  count++;
403  return count;
404 }
405 
407 {
408  unsigned i = 0;
409  for (CommandScreen* scr = fHead; scr != nullptr; scr = scr->fNext, i++)
410  {
411  if (i == index)
412  return scr;
413  }
414  return nullptr;
415 }
416 
418 {
420  if ((fScreenState & 0x1) == 0x1)
421  {
422  fScreenState &= ~0x1;
423  wakeDevice();
424  if (fCurrentScreen != nullptr)
425  fCurrentScreen->init();
426  }
427 }
428 
430 {
431  if (!fEnabled)
432  return;
433  if (fCurrentScreen == nullptr)
434  fCurrentScreen = findScreen(ScreenID(0));
435  clearContext();
437  if (fLastScreen != current)
438  {
439  if (fLastScreen != nullptr)
440  {
441  fLastScreen->exit();
442  }
443  // Screen was changed
444  if (current != nullptr)
445  {
447  current->fLastTag = 0;
448  current->init();
449  }
452  }
453  if (current != nullptr && current->isActive())
454  {
455  restoreScreen();
456  }
457  else if ((fScreenState & 0x1) == 0 && fScreenBlankDelay > 0 && fLastMillis + fScreenBlankDelay < millis())
458  {
459  blankScreen();
460  }
461  if (current != nullptr && (fScreenState & 0x1) == 0)
462  {
463  if (isTouching())
465 
466  saveContext();
467  current->render();
468  restoreContext();
469 
470  current->fMenu.draw(180, 10);
471  }
472  else
473  {
474  if (isTouching())
475  {
476  if (!fScreenTouched)
477  fScreenTouched = true;
478  }
479  else if (fScreenTouched)
480  {
481  fScreenTouched = false;
482  restoreScreen();
483  }
484  }
485  swapDevice();
486  if (current != nullptr)
487  {
488  if (handleEvent())
489  {
490  restoreScreen();
491  }
492  }
493  if (currentSelection() == 0 && current->fLastTag != 0)
494  {
496  if (current->fLastTag > 0)
497  {
499  {
500  // char buf[SERIAL_BUFFER_SIZE];
501  // const char* cmd = current->fMenu.getCommand(
502  // current->fMenu.getSelected(), buf, sizeof(buf));
503  // if (*cmd != '\0')
504  // current->sendSerialCommand(cmd);
505  }
506  }
507  current->fLastTag = 0;
508  }
509  else
510  {
511  if (current->fLastTag != 0 && isTouching())
512  {
513  // ignore roaming fingers
514  }
515  else
516  {
518  }
519  }
521 }
522 
524 {
525  if (fHead == nullptr)
526  fHead = screen;
527  if (fTail != nullptr)
528  fTail->fNext = screen;
529  fTail = screen;
530 }
531 #endif
CommandScreen
Definition: CommandScreen.h:273
CommandScreen::toggleMaskBit
static void toggleMaskBit(uint8_t &mask, uint8_t bit)
Definition: CommandScreen.h:350
CommandScreen::buttonLeftPressed
virtual void buttonLeftPressed(bool repeat=false)
Definition: CommandScreen.h:328
CommandScreenHandler::process
void process()
Definition: CommandScreen.h:429
CommandScreenHandler::append
void append(CommandScreen *screen)
Definition: CommandScreen.h:523
CommandScreenHandler::switchToScreen
void switchToScreen(ScreenID id, bool popStack=true)
Definition: CommandScreen.h:175
CommandScreenHandler::getScreenAt
CommandScreen * getScreenAt(unsigned index)
Definition: CommandScreen.h:406
CommandScreenHandler::fScreenBlankDelay
uint32_t fScreenBlankDelay
Definition: CommandScreen.h:250
CommandScreenHandler::sleepDevice
virtual void sleepDevice()
Definition: CommandScreen.h:258
CommandScreen::fKeyRepeatRateMS
unsigned fKeyRepeatRateMS
Definition: CommandScreen.h:375
CommandScreenHandler::handleEvent
virtual bool handleEvent()
Definition: CommandScreen.h:264
MENU_SCREEN_DEBUG_PRINTLN
#define MENU_SCREEN_DEBUG_PRINTLN(s)
Definition: CommandScreen.h:13
ReelTwo.h
CommandScreenHandler::current
CommandScreen * current()
Definition: CommandScreen.h:154
CommandMenu::getSelected
uint8_t getSelected()
Definition: CommandScreen.h:116
CommandScreen::handleEvent
virtual bool handleEvent()
Definition: CommandScreen.h:300
CommandScreen::buttonInReleased
virtual void buttonInReleased()
Definition: CommandScreen.h:336
CommandScreenHandler::fCurrentScreen
CommandScreen * fCurrentScreen
Definition: CommandScreen.h:245
CommandScreenHandler::fScreenIDSP
uint8_t fScreenIDSP
Definition: CommandScreen.h:253
CommandScreenHandler::elapsed
uint32_t elapsed()
Definition: CommandScreen.h:230
CommandScreenHandler::fLastMillis
uint32_t fLastMillis
Definition: CommandScreen.h:248
CommandScreen::setKeyRepeatRate
void setKeyRepeatRate(unsigned ms)
Definition: CommandScreen.h:323
CommandScreen::fLastTag
uint8_t fLastTag
Definition: CommandScreen.h:374
SerialCommand_t::label
char label[30]
Definition: CommandScreen.h:21
CommandScreenHandler::wakeDevice
virtual void wakeDevice()
Definition: CommandScreen.h:257
CommandScreen::clearSelection
void clearSelection()
Definition: CommandScreen.h:364
CommandScreenHandler::CommandScreenHandler
CommandScreenHandler(uint32_t screenBlankDelay=15000)
Definition: CommandScreen.h:150
CommandScreen::isActive
virtual bool isActive()
Definition: CommandScreen.h:301
CommandScreenHandler::restoreScreen
void restoreScreen()
Definition: CommandScreen.h:417
CommandScreenHandler::saveContext
virtual void saveContext()
Definition: CommandScreen.h:259
CommandScreenHandler::findScreen
CommandScreen * findScreen(ScreenID id)
Definition: CommandScreen.h:388
CommandMenu::CommandMenu
CommandMenu(SerialCommand *cmds, uint8_t siz)
Definition: CommandScreen.h:28
CommandMenu::changeCommands
void changeCommands(SerialCommand *newCommands, uint8_t newSize)
Definition: CommandScreen.h:131
CommandMenu::getSerialCommand
SerialCommand * getSerialCommand(int index)
Definition: CommandScreen.h:35
CommandScreen::handleSelection
virtual void handleSelection(uint8_t selection)
Definition: CommandScreen.h:298
CommandScreenHandler::currentID
ScreenID currentID()
Definition: CommandScreen.h:383
CommandScreenHandler
Definition: CommandScreen.h:147
CommandScreenHandler::restoreContext
virtual void restoreContext()
Definition: CommandScreen.h:260
CommandScreen::switchToScreen
void switchToScreen(ScreenID id)
Definition: CommandScreen.h:303
CommandScreenHandler::isEnabled
bool isEnabled() const
Definition: CommandScreen.h:235
CommandScreen::fMenu
CommandMenu fMenu
Definition: CommandScreen.h:373
CommandScreenHandler::setEnabled
void setEnabled(bool enabled)
Definition: CommandScreen.h:236
CommandScreen::isStatus
virtual bool isStatus()
Definition: CommandScreen.h:302
MENU_SCREEN_DEBUG_PRINT
#define MENU_SCREEN_DEBUG_PRINT(s)
Definition: CommandScreen.h:14
CommandScreenHandler::getScreenSleepDuration
uint32_t getScreenSleepDuration()
Definition: CommandScreen.h:170
CommandScreen::buttonRightPressed
virtual void buttonRightPressed(bool repeat=false)
Definition: CommandScreen.h:330
CommandMenu::draw
void draw(int x, int y)
Definition: CommandScreen.h:80
CommandMenu::getButtonLabel
const char * getButtonLabel(int index, char *buf, size_t maxSize)
Definition: CommandScreen.h:40
CommandScreen::restoreScreen
void restoreScreen()
Definition: CommandScreen.h:315
CommandScreenHandler::fEnabled
bool fEnabled
Definition: CommandScreen.h:252
CommandScreenHandler::fScreenState
uint8_t fScreenState
Definition: CommandScreen.h:246
CommandScreen::buttonLeftReleased
virtual void buttonLeftReleased()
Definition: CommandScreen.h:333
CommandScreen::ID
ScreenID ID() const
Definition: CommandScreen.h:286
CommandScreenHandler::resetBlankingTimer
void resetBlankingTimer()
Definition: CommandScreen.h:266
CommandScreenHandler::isSleeping
bool isSleeping() const
Definition: CommandScreen.h:223
CommandScreen::fID
ScreenID fID
Definition: CommandScreen.h:372
CommandScreenHandler::getNumScreens
unsigned getNumScreens()
Definition: CommandScreen.h:398
CommandScreen::getKeyRepeatRate
unsigned getKeyRepeatRate() const
Definition: CommandScreen.h:319
CommandScreen::getSelected
uint8_t getSelected() const
Definition: CommandScreen.h:291
CommandMenu::getCommand
const char * getCommand(int index, char *buf, size_t maxSize)
Definition: CommandScreen.h:62
CommandScreen::CommandScreen
CommandScreen(CommandScreenHandler &handler, ScreenID id, SerialCommand *cmds=nullptr, uint8_t siz=0)
Definition: CommandScreen.h:276
CommandScreenHandler::fHead
CommandScreen * fHead
Definition: CommandScreen.h:243
CommandScreen::buttonDial
virtual void buttonDial(long newValue, long oldValue=0)
Definition: CommandScreen.h:337
CommandMenu::handleSelection
bool handleSelection(uint8_t selection)
Definition: CommandScreen.h:121
CommandScreenHandler::isTouching
virtual bool isTouching()
Definition: CommandScreen.h:261
CommandScreenHandler::setScreenBlankDelay
void setScreenBlankDelay(uint32_t millis)
Definition: CommandScreen.h:165
CommandScreenHandler::pushScreen
void pushScreen(ScreenID id)
Definition: CommandScreen.h:190
CommandScreen::buttonUpPressed
virtual void buttonUpPressed(bool repeat=false)
Definition: CommandScreen.h:327
CommandScreen::popScreen
void popScreen()
Definition: CommandScreen.h:311
CommandScreenHandler::popScreen
void popScreen()
Definition: CommandScreen.h:203
CommandScreenHandler::fScreenTouched
bool fScreenTouched
Definition: CommandScreen.h:251
SerialCommand
const struct SerialCommand_t SerialCommand
CommandScreenHandler::blankScreen
void blankScreen()
Definition: CommandScreen.h:212
CommandScreenHandler::currentSelection
virtual uint8_t currentSelection()
Definition: CommandScreen.h:263
CommandScreen::toggleMaskBit
static void toggleMaskBit(uint16_t &mask, uint16_t bit)
Definition: CommandScreen.h:357
SerialCommand_t
Definition: CommandScreen.h:20
CommandScreenHandler::fScreenStartMillis
uint32_t fScreenStartMillis
Definition: CommandScreen.h:247
CommandScreen::exit
virtual void exit()
Definition: CommandScreen.h:297
CommandScreenHandler::fLastScreen
CommandScreen * fLastScreen
Definition: CommandScreen.h:249
UNUSED_ARG
#define UNUSED_ARG(arg)
Definition: ReelTwo.h:25
CommandScreen::render
virtual void render()=0
CommandScreen::buttonDownReleased
virtual void buttonDownReleased()
Definition: CommandScreen.h:334
CommandScreenHandler::clearContext
virtual void clearContext()
Definition: CommandScreen.h:256
CommandScreenHandler::fScreenIDStack
ScreenID fScreenIDStack[5]
Definition: CommandScreen.h:254
CommandScreen::buttonUpReleased
virtual void buttonUpReleased()
Definition: CommandScreen.h:332
CommandScreen::hasMenu
bool hasMenu()
Definition: CommandScreen.h:368
CommandMenu::getLabel
const char * getLabel(int index, char *buf, size_t maxSize)
Definition: CommandScreen.h:56
CommandScreen::buttonRightReleased
virtual void buttonRightReleased()
Definition: CommandScreen.h:335
CommandScreen::pushScreen
void pushScreen(ScreenID id)
Definition: CommandScreen.h:307
CommandScreen::buttonInPressed
virtual void buttonInPressed(bool repeat=false)
Definition: CommandScreen.h:331
SizeOfArray
#define SizeOfArray(arr)
Definition: ReelTwo.h:213
CommandScreen::buttonDownPressed
virtual void buttonDownPressed(bool repeat=false)
Definition: CommandScreen.h:329
SerialCommand_t::cmd
char cmd[15]
Definition: CommandScreen.h:22
CommandScreenHandler::swapDevice
virtual void swapDevice()
Definition: CommandScreen.h:262
CommandScreenHandler::fTail
CommandScreen * fTail
Definition: CommandScreen.h:244
CommandMenu
Definition: CommandScreen.h:25
CommandScreen::init
virtual void init()
Definition: CommandScreen.h:296
CommandMenu::getSize
uint8_t getSize()
Definition: CommandScreen.h:75