5 * th9x - http://code.google.com/p/th9x
6 * er9x - http://code.google.com/p/er9x
7 * gruvin9x - http://code.google.com/p/gruvin9x
9 * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
27 #define MENU_COLUMN2_X 280
28 #define MIXES_2ND_COLUMN 140
29 #define COLUMN_HEADER_X 150
31 extern uint8_t menuPageIndex
;
32 extern uint8_t menuPageCount
;
33 extern uint16_t linesCount
;
34 extern uint8_t linesDisplayed
;
35 extern int menuVerticalPosition
;
36 extern int menuHorizontalPosition
;
37 extern int menuVerticalOffset
;
38 extern uint8_t menuCalibrationState
;
40 // Temporary no highlight
41 extern uint8_t noHighlightCounter
;
42 #define NO_HIGHLIGHT() (noHighlightCounter > 0)
43 #define START_NO_HIGHLIGHT() do { noHighlightCounter = 25; } while(0)
45 typedef bool (*MenuHandlerFunc
)(event_t event
);
47 extern MenuHandlerFunc menuHandlers
[5];
48 extern uint8_t menuVerticalPositions
[4];
49 extern uint8_t menuLevel
;
50 extern event_t menuEvent
;
52 void chainMenu(MenuHandlerFunc newMenu
);
53 void pushMenu(MenuHandlerFunc newMenu
);
57 inline bool isRadioMenuDisplayed()
59 return menuVerticalPositions
[0] == 1;
62 inline bool isModelMenuDisplayed()
64 return menuVerticalPositions
[0] == 0;
71 ICON_RADIO_SD_MANAGER
,
73 ICON_RADIO_GLOBAL_FUNCTIONS
,
76 ICON_RADIO_CALIBRATION
,
81 ICON_MODEL_FLIGHT_MODES
,
87 ICON_MODEL_LOGICAL_SWITCHES
,
88 ICON_MODEL_SPECIAL_FUNCTIONS
,
89 ICON_MODEL_LUA_SCRIPTS
,
100 ICON_STATS_THROTTLE_GRAPH
,
105 ICON_MONITOR_CHANNELS1
,
106 ICON_MONITOR_CHANNELS2
,
107 ICON_MONITOR_CHANNELS3
,
108 ICON_MONITOR_CHANNELS4
,
109 ICON_MONITOR_LOGICAL_SWITCHES
,
110 ICON_RADIO_SPECTRUM_ANALYSER
,
116 CASE_HELI(MENU_MODEL_HELI
)
117 CASE_FLIGHT_MODES(MENU_MODEL_FLIGHT_MODES
)
122 CASE_GVARS(MENU_MODEL_GVARS
)
123 MENU_MODEL_LOGICAL_SWITCHES
,
124 MENU_MODEL_SPECIAL_FUNCTIONS
,
125 #if defined(LUA_MODEL_SCRIPTS)
126 MENU_MODEL_CUSTOM_SCRIPTS
,
128 MENU_MODEL_TELEMETRY
,
129 MENU_MODEL_PAGES_COUNT
132 const uint8_t MODEL_ICONS
[MENU_MODEL_PAGES_COUNT
+ 1] = {
135 CASE_HELI(ICON_MODEL_HELI
)
136 CASE_FLIGHT_MODES(ICON_MODEL_FLIGHT_MODES
)
141 CASE_GVARS(ICON_MODEL_GVARS
)
142 ICON_MODEL_LOGICAL_SWITCHES
,
143 ICON_MODEL_SPECIAL_FUNCTIONS
,
144 #if defined(LUA_MODEL_SCRIPTS)
145 ICON_MODEL_LUA_SCRIPTS
,
150 const uint8_t STATS_ICONS
[] = {
152 ICON_STATS_THROTTLE_GRAPH
,
155 #if defined(DEBUG_TRACE_BUFFER)
160 const uint8_t MONITOR_ICONS
[] = {
162 ICON_MONITOR_CHANNELS1
,
163 ICON_MONITOR_CHANNELS2
,
164 ICON_MONITOR_CHANNELS3
,
165 ICON_MONITOR_CHANNELS4
,
166 ICON_MONITOR_LOGICAL_SWITCHES
169 bool menuModelSetup(event_t event
);
170 bool menuModelFailsafe(event_t event
);
171 bool menuModelHeli(event_t event
);
172 bool menuModelFlightModesAll(event_t event
);
173 bool menuModelExposAll(event_t event
);
174 bool menuModelMixAll(event_t event
);
175 bool menuModelLimits(event_t event
);
176 bool menuModelCurvesAll(event_t event
);
177 bool menuModelCurveOne(event_t event
);
178 bool menuModelGVars(event_t event
);
179 bool menuModelLogicalSwitches(event_t event
);
180 bool menuModelSpecialFunctions(event_t event
);
181 bool menuModelCustomScripts(event_t event
);
182 bool menuModelTelemetry(event_t event
);
183 bool menuModelSensor(event_t event
);
184 bool menuModelExpoOne(event_t event
);
185 bool menuModelModuleOptions(event_t event
);
186 bool menuModelReceiverOptions(event_t event
);
187 bool menuRadioDiagKeys(event_t event
);
188 bool menuRadioDiagAnalogs(event_t event
);
190 extern const MenuHandlerFunc menuTabModel
[MENU_MODEL_PAGES_COUNT
];
194 MENU_RADIO_SD_MANAGER
,
195 #if defined(LUA) || defined(PXX2)
198 MENU_RADIO_SPECIAL_FUNCTIONS
,
202 MENU_RADIO_PAGES_COUNT
205 const uint8_t RADIO_ICONS
[MENU_RADIO_PAGES_COUNT
+ 1] = {
208 ICON_RADIO_SD_MANAGER
,
209 #if defined(LUA) || defined(PXX2)
212 ICON_RADIO_GLOBAL_FUNCTIONS
,
218 bool menuRadioSetup(event_t event
);
219 bool menuRadioSdManager(event_t event
);
220 bool menuRadioTools(event_t event
);
221 bool menuRadioSpecialFunctions(event_t event
);
222 bool menuRadioTrainer(event_t event
);
223 bool menuRadioVersion(event_t event
);
224 bool menuRadioHardware(event_t event
);
225 bool menuRadioCalibration(event_t event
);
226 bool menuRadioSpectrumAnalyser(event_t event
);
227 bool menuRadioPowerMeter(event_t event
);
229 extern const MenuHandlerFunc menuTabGeneral
[MENU_RADIO_PAGES_COUNT
];
231 enum MenuRadioIndexes
236 #if defined(DEBUG_TRACE_BUFFER)
241 bool menuStatsGraph(event_t event
);
242 bool menuStatsDebug(event_t event
);
243 bool menuStatsAnalogs(event_t event
);
244 bool menuStatsTraces(event_t event
);
246 static const MenuHandlerFunc menuTabStats
[] = {
250 #if defined(DEBUG_TRACE_BUFFER)
258 e_MonChannels1
= e_MonChannelsFirst
,
262 e_MonLogicalSwitches
,
263 e_MonTabChannelsPagesCount
266 extern const MenuHandlerFunc menuTabMonitors
[e_MonTabChannelsPagesCount
];
267 extern uint8_t lastMonitorPage
;
268 extern void drawSingleMixerBar(coord_t
, coord_t
, coord_t
, coord_t
, uint8_t);
269 extern void drawSingleOutputBar(coord_t
, coord_t
, coord_t
, coord_t
, uint8_t);
271 extern const MenuHandlerFunc menuTabScreensSetup
[1+MAX_CUSTOM_SCREENS
] ;
273 bool menuFirstCalib(event_t event
);
274 bool menuMainView(event_t event
);
275 bool menuSpecialFunctions(event_t event
, CustomFunctionData
* functions
, CustomFunctionsContext
& functionsContext
);
276 bool menuModelSelect(event_t event
);
277 bool menuAboutView(event_t event
);
278 bool menuMainViewChannelsMonitor(event_t event
);
279 bool menuTextView(event_t event
);
280 bool menuScreensTheme(event_t event
);
282 extern int8_t checkIncDec_Ret
; // global helper vars
284 #define EDIT_SELECT_FIELD 0
285 #define EDIT_MODIFY_FIELD 1
286 #define EDIT_MODIFY_STRING 2
287 extern int8_t s_editMode
; // global editmode
290 #define EE_GENERAL 0x01
291 #define EE_MODEL 0x02
292 #define NO_INCDEC_MARKS 0x04
293 #define INCDEC_SWITCH 0x08
294 #define INCDEC_SOURCE 0x10
295 #define INCDEC_REP10 0x40
296 #define NO_DBLKEYS 0x80
298 // mawrow special values
299 #define ORPHAN_ROW ((uint8_t)-3)
300 #define NAVIGATION_LINE_BY_LINE 0x40
301 #define CURSOR_ON_LINE() (menuHorizontalPosition<0)
303 struct CheckIncDecStops
{
312 return stops
[count
-1];
314 bool contains(int value
) const
316 for (int i
=0; i
<count
; ++i
) {
320 else if (value
< stop
)
326 extern const CheckIncDecStops
&stops100
;
327 extern const CheckIncDecStops
&stops1000
;
328 extern const CheckIncDecStops
&stopsSwitch
;
330 #define INIT_STOPS(var, ...) \
331 const int _ ## var[] = { __VA_ARGS__ }; \
332 const CheckIncDecStops &var = (const CheckIncDecStops&)_ ## var;
333 #define CATEGORY_END(val) \
336 int checkIncDec(event_t event
, int val
, int i_min
, int i_max
, unsigned int i_flags
=0, IsValueAvailable isValueAvailable
=NULL
, const CheckIncDecStops
&stops
=stops100
);
338 #define checkIncDecModel(event, i_val, i_min, i_max) checkIncDec(event, i_val, i_min, i_max, EE_MODEL)
339 #define checkIncDecModelZero(event, i_val, i_max) checkIncDec(event, i_val, 0, i_max, EE_MODEL)
340 #define checkIncDecGen(event, i_val, i_min, i_max) checkIncDec(event, i_val, i_min, i_max, EE_GENERAL)
342 #define CHECK_INCDEC_MODELVAR(event, var, min, max) \
343 var = checkIncDecModel(event, var, min, max)
345 #define CHECK_INCDEC_MODELVAR_ZERO(event, var, max) \
346 var = checkIncDecModelZero(event, var, max)
348 #define CHECK_INCDEC_MODELVAR_CHECK(event, var, min, max, check) \
349 var = checkIncDec(event, var, min, max, EE_MODEL, check)
351 #define CHECK_INCDEC_MODELVAR_ZERO_CHECK(event, var, max, check) \
352 var = checkIncDec(event, var, 0, max, EE_MODEL, check)
354 #define AUTOSWITCH_ENTER_LONG() (attr && event==EVT_KEY_LONG(KEY_ENTER))
355 #define CHECK_INCDEC_SWITCH(event, var, min, max, flags, available) \
356 var = checkIncDec(event, var, min, max, (flags)|INCDEC_SWITCH, available)
357 #define CHECK_INCDEC_MODELSWITCH(event, var, min, max, available) \
358 CHECK_INCDEC_SWITCH(event, var, min, max, EE_MODEL, available)
360 #define CHECK_INCDEC_MODELSOURCE(event, var, min, max) \
361 var = checkIncDec(event, var, min, max, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isSourceAvailable)
363 #define CHECK_INCDEC_GENVAR(event, var, min, max) \
364 var = checkIncDecGen(event, var, min, max)
366 #define INCDEC_DECLARE_VARS(f) uint8_t incdecFlag = (f); IsValueAvailable isValueAvailable = NULL
367 #define INCDEC_SET_FLAG(f) incdecFlag = (f)
368 #define INCDEC_ENABLE_CHECK(fn) isValueAvailable = fn
369 #define CHECK_INCDEC_PARAM(event, var, min, max) \
370 checkIncDec(event, var, min, max, incdecFlag, isValueAvailable)
372 int8_t navigate(event_t event
, int count
, int rows
, int columns
=1, bool loop
=true);
373 bool check(event_t event
, uint8_t curr
, const MenuHandlerFunc
* menuTab
, uint8_t menuTabSize
, const uint8_t * horTab
, uint8_t horTabMax
, int maxrow
, uint8_t flags
=0);
374 bool check_simple(event_t event
, uint8_t curr
, const MenuHandlerFunc
* menuTab
, uint8_t menuTabSize
, int maxrow
);
375 bool check_submenu_simple(event_t event
, uint8_t maxrow
);
377 #define MENU_TAB(...) const uint8_t mstate_tab[] = __VA_ARGS__
379 #define MENU_WITH_OPTIONS(title, icons, tab, tabCount, menu, lines_count, ...) \
380 MENU_TAB(__VA_ARGS__); \
381 if (event == EVT_ENTRY || event == EVT_ENTRY_UP) TRACE("Menu %s displayed ...", title); \
382 if (!check(event, menu, tab, tabCount, mstate_tab, DIM(mstate_tab)-1, lines_count)) return false; \
383 drawMenuTemplate(title, 0, icons, OPTION_MENU_TITLE_BAR);
385 #define CUSTOM_MENU_WITH_OPTIONS(title, icons, tab, tabCount, menu, lines_count) \
386 if (event == EVT_ENTRY || event == EVT_ENTRY_UP) TRACE("Menu %s displayed ...", title); \
387 if (!check(event, menu, tab, tabCount, mstate_tab, DIM(mstate_tab)-1, lines_count)) return false; \
388 drawMenuTemplate(title, 0, icons, OPTION_MENU_TITLE_BAR);
390 #define MENU(title, icons, tab, menu, lines_count, ...) \
391 MENU_WITH_OPTIONS(title, icons, tab, DIM(tab), menu, lines_count, __VA_ARGS__)
393 #define SIMPLE_MENU_WITH_OPTIONS(title, icons, tab, tabCount, menu, lines_count) \
394 if (event == EVT_ENTRY || event == EVT_ENTRY_UP) TRACE("Menu %s displayed ...", title); \
395 if (!check_simple(event, menu, tab, tabCount, lines_count)) return false; \
396 drawMenuTemplate(title, 0, icons, OPTION_MENU_TITLE_BAR);
398 #define SIMPLE_MENU(title, icons, tab, menu, lines_count) \
399 SIMPLE_MENU_WITH_OPTIONS(title, icons, tab, DIM(tab), menu, lines_count)
401 #define SUBMENU(title, icon, lines_count, ...) \
402 MENU_TAB(__VA_ARGS__); \
403 if (!check(event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, lines_count)) return false; \
404 drawMenuTemplate(title, icon);
406 #define SUBMENU_WITH_OPTIONS(title, icon, lines_count, options, ...) \
407 MENU_TAB(__VA_ARGS__); \
408 if (!check(event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, lines_count)) return false; \
409 drawMenuTemplate(title, icon, NULL, options);
411 #define CUSTOM_SUBMENU_WITH_OPTIONS(title, icon, lines_count, options) \
412 if (!check(event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, lines_count)) return false; \
413 drawMenuTemplate(title, icon, NULL, options);
415 #define SIMPLE_SUBMENU(title, icon, lines_count) \
416 if (!check_submenu_simple(event, lines_count)) return false; \
417 drawMenuTemplate(title, icon, NULL)
419 #define SIMPLE_SUBMENU_WITH_OPTIONS(title, icon, lines_count, options) \
420 if (!check_submenu_simple(event, lines_count)) return false; \
421 drawMenuTemplate(title, icon, NULL, options)
424 #define GVAR_MENU_ITEM(x, y, v, min, max, lcdattr, editflags, event) editGVarFieldValue(x, y, v, min, max, lcdattr, editflags, event)
426 #define GVAR_MENU_ITEM(x, y, v, min, max, lcdattr, editflags, event) editGVarFieldValue(x, y, v, min, max, lcdattr, event)
430 int16_t editGVarFieldValue(coord_t x
, coord_t y
, int16_t value
, int16_t min
, int16_t max
, LcdFlags attr
, uint8_t editflags
, event_t event
);
431 #define displayGVar(x, y, v, min, max) GVAR_MENU_ITEM(x, y, v, min, max, 0, 0, 0)
433 int16_t editGVarFieldValue(coord_t x
, coord_t y
, int16_t value
, int16_t min
, int16_t max
, LcdFlags attr
, event_t event
);
434 #define displayGVar(x, y, v, min, max) lcdDrawNumber(x, y, v)
437 extern uint8_t editNameCursorPos
;
438 void editName(coord_t x
, coord_t y
, char *name
, uint8_t size
, event_t event
, uint8_t active
, LcdFlags flags
=ZCHAR
);
440 uint8_t editDelay(coord_t x
, coord_t y
, event_t event
, uint8_t attr
, uint8_t delay
);
441 void editCurveRef(coord_t x
, coord_t y
, CurveRef
& curve
, event_t event
, LcdFlags flags
);
443 extern uint8_t s_curveChan
;
449 WARNING_TYPE_ASTERISK
,
450 WARNING_TYPE_CONFIRM
,
455 extern const char * warningText
;
456 extern const char * warningInfoText
;
457 extern uint8_t warningInfoLength
;
458 extern uint8_t warningResult
;
459 extern uint8_t warningType
;
463 extern uint8_t s_copyMode
;
464 extern int8_t s_copySrcRow
;
465 extern int8_t s_copyTgtOfs
;
466 extern uint8_t s_currIdx
;
467 extern int8_t s_currCh
;
468 extern uint8_t s_copySrcIdx
;
469 extern uint8_t s_copySrcCh
;
471 uint8_t getExposCount();
472 void deleteExpo(uint8_t idx
);
473 void insertExpo(uint8_t idx
);
475 uint8_t getMixesCount();
476 void deleteMix(uint8_t idx
);
477 void insertMix(uint8_t idx
);
480 #define MENU_W LCD_W-(2*MENU_X)
485 #define WARNING_LINE_LEN 32
486 #define WARNING_LINE_X (POPUP_X+66)
487 #define WARNING_LINE_Y (POPUP_Y+9)
488 #define WARNING_INFOLINE_Y (WARNING_LINE_Y+68)
490 void copySelection(char * dst
, const char * src
, uint8_t size
);
491 void drawPopupBackgroundAndBorder(coord_t x
, coord_t y
, coord_t w
, coord_t h
);
492 void showMessageBox(const char * title
);
493 void runPopupWarning(event_t event
);
495 typedef void (* PopupFunc
)(event_t event
);
496 extern PopupFunc popupFunc
;
498 extern uint8_t warningInfoFlags
;
500 inline void DISPLAY_WARNING(event_t event
)
505 #define POPUP_MENU_MAX_LINES 12
506 #define MENU_MAX_DISPLAY_LINES 9
507 #define MENU_LINE_LENGTH (LEN_MODEL_NAME+12)
509 extern const char * popupMenuItems
[POPUP_MENU_MAX_LINES
];
510 extern uint16_t popupMenuItemsCount
;
511 extern uint16_t popupMenuOffset
;
513 MENU_OFFSET_INTERNAL
,
516 extern uint8_t popupMenuOffsetType
;
517 extern uint8_t popupMenuSelectedItem
;
518 const char * runPopupMenu(event_t event
);
520 typedef void (* PopupMenuHandler
)(const char * result
);
521 extern PopupMenuHandler popupMenuHandler
;
523 inline void POPUP_INPUT(const char * s
, PopupFunc func
)
526 warningInfoText
= nullptr;
527 warningType
= WARNING_TYPE_INPUT
;
531 inline void SET_WARNING_INFO(const char * info
, uint8_t length
, uint8_t flags
)
533 warningInfoText
= info
;
534 warningInfoLength
= length
;
535 warningInfoFlags
= flags
;
538 inline void POPUP_MENU_ADD_ITEM(const char * s
)
540 popupMenuOffsetType
= MENU_OFFSET_INTERNAL
;
541 if (popupMenuItemsCount
< POPUP_MENU_MAX_LINES
)
542 popupMenuItems
[popupMenuItemsCount
++] = s
;
545 inline void POPUP_MENU_SELECT_ITEM(uint8_t index
)
547 popupMenuSelectedItem
= (index
> 0 ? (index
< popupMenuItemsCount
? index
: popupMenuItemsCount
- 1) : 0);
550 inline void POPUP_MENU_START(PopupMenuHandler handler
)
552 if (handler
!= popupMenuHandler
) {
555 popupMenuHandler
= handler
;
559 inline void CLEAR_POPUP()
561 warningText
= nullptr;
562 warningInfoText
= nullptr;
563 popupMenuHandler
= nullptr;
564 popupMenuItemsCount
= 0;
567 inline void POPUP_WAIT(const char * s
)
570 warningInfoText
= nullptr;
571 warningType
= WARNING_TYPE_WAIT
;
572 popupFunc
= runPopupWarning
;
575 inline void POPUP_INFORMATION(const char * s
)
578 warningInfoText
= nullptr;
579 warningType
= WARNING_TYPE_INFO
;
580 popupFunc
= runPopupWarning
;
583 inline void POPUP_WARNING(const char * s
)
586 warningInfoText
= nullptr;
587 warningType
= WARNING_TYPE_ASTERISK
;
588 popupFunc
= runPopupWarning
;
591 typedef void (* PopupMenuHandler
)(const char * result
);
592 extern PopupMenuHandler popupMenuHandler
;
594 inline void POPUP_CONFIRMATION(const char *s
, PopupMenuHandler confirmHandler
)
597 warningType
= WARNING_TYPE_CONFIRM
;
598 warningInfoText
= nullptr;
599 popupFunc
= runPopupWarning
;
600 popupMenuHandler
= confirmHandler
;
603 void pushMenuTextView(const char * filename
);
604 void pushModelNotes();
605 void readModelNotes();
607 #define CURSOR_MOVED_LEFT(event) (event==EVT_ROTARY_LEFT || EVT_KEY_MASK(event) == KEY_LEFT)
608 #define CURSOR_MOVED_RIGHT(event) (event==EVT_ROTARY_RIGHT || EVT_KEY_MASK(event) == KEY_RIGHT)
609 #define REPEAT_LAST_CURSOR_MOVE(last, refresh) { if (CURSOR_MOVED_RIGHT(event)) menuHorizontalPosition = (menuHorizontalPosition >= (last) ? 0 : menuHorizontalPosition + 1); else menuHorizontalPosition = (menuHorizontalPosition <= (0) ? last : menuHorizontalPosition - 1); if (refresh) putEvent(EVT_REFRESH); }
610 #define POS_HORZ_INIT(posVert) ((COLATTR(posVert) & NAVIGATION_LINE_BY_LINE) ? -1 : 0)
611 #define EDIT_MODE_INIT 0 // TODO enum
613 typedef int (*FnFuncP
) (int x
);
614 void drawFunction(FnFuncP fn
, int x
, int y
, int width
);
616 void onSourceLongEnterPress(const char *result
);
618 uint8_t switchToMix(uint8_t source
);