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.
24 #include "gui_common.h"
28 #define MENUS_SCROLLBAR_WIDTH 0
32 #define HEADER_LINE_COLUMNS
35 #define HEADER_LINE_COLUMNS 0,
39 #define drawFieldLabel(x, y, str) lcdDrawTextAlignedLeft(y, str)
41 #define NUM_BODY_LINES (LCD_LINES-1)
42 #define MENU_HEADER_HEIGHT FH
43 #define MENU_INIT_VPOS 0
45 #define CURVE_SIDE_WIDTH (LCD_H/2)
46 #define CURVE_CENTER_X (LCD_W-CURVE_SIDE_WIDTH-2)
47 #define CURVE_CENTER_Y (LCD_H/2)
49 #define MIXES_2ND_COLUMN (12*FW)
51 // Temporary no highlight
52 extern uint8_t noHighlightCounter
;
53 #define NO_HIGHLIGHT() (noHighlightCounter > 0)
54 #define START_NO_HIGHLIGHT() do { noHighlightCounter = 25; } while(0)
58 void drawSlider(coord_t x
, coord_t y
, uint8_t value
, uint8_t max
, uint8_t attr
);
59 #elif defined(GRAPHICS)
60 void display5posSlider(coord_t x
, coord_t y
, uint8_t value
, uint8_t attr
);
61 #define drawSlider(x, y, value, max, attr) lcdDrawNumber(x, y, value, attr|LEFT)
63 #define drawSlider(x, y, value, max, attr) lcdDrawNumber(x, y, value, attr|LEFT)
66 #if defined(NAVIGATION_POT1)
67 extern int16_t p1valdiff
;
72 #if defined(NAVIGATION_POT2)
73 extern int8_t p2valdiff
;
78 extern int8_t checkIncDec_Ret
; // global helper vars
80 #define EDIT_SELECT_MENU -1
81 #define EDIT_SELECT_FIELD 0
82 #define EDIT_MODIFY_FIELD 1
83 #define EDIT_MODIFY_STRING 2
84 extern int8_t s_editMode
; // global editmode
87 #define EE_GENERAL 0x01
89 #define NO_INCDEC_MARKS 0x04
90 #define INCDEC_SWITCH 0x08
91 #define INCDEC_SOURCE 0x10
92 #define INCDEC_REP10 0x40
93 #define NO_DBLKEYS 0x80
96 #define INCDEC_DECLARE_VARS(f) uint8_t incdecFlag = (f); IsValueAvailable isValueAvailable = NULL
97 #define INCDEC_SET_FLAG(f) incdecFlag = (f)
98 #define INCDEC_ENABLE_CHECK(fn) isValueAvailable = fn
99 #define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, incdecFlag, isValueAvailable)
100 #elif defined(CPUM64)
101 #define INCDEC_DECLARE_VARS(f)
102 #define INCDEC_SET_FLAG(f)
103 #define INCDEC_ENABLE_CHECK(fn)
104 #define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, EE_MODEL)
106 #define INCDEC_DECLARE_VARS(f) uint8_t incdecFlag = (f)
107 #define INCDEC_SET_FLAG(f) incdecFlag = (f)
108 #define INCDEC_ENABLE_CHECK(fn)
109 #define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, incdecFlag)
112 // mawrow special values
113 #define TITLE_ROW ((uint8_t)-1)
114 #define HIDDEN_ROW ((uint8_t)-2)
117 struct CheckIncDecStops
{
126 return stops
[count
-1];
128 bool contains(int value
) const
130 for (int i
=0; i
<count
; ++i
) {
134 else if (value
< stop
)
140 extern const CheckIncDecStops
&stops100
;
141 extern const CheckIncDecStops
&stops1000
;
142 extern const CheckIncDecStops
&stopsSwitch
;
143 #define INIT_STOPS(var, ...) \
144 const int _ ## var[] = { __VA_ARGS__ }; \
145 const CheckIncDecStops &var = (const CheckIncDecStops&)_ ## var;
146 #define CATEGORY_END(val) \
148 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
);
150 int16_t checkIncDec(event_t event
, int16_t i_pval
, int16_t i_min
, int16_t i_max
, uint8_t i_flags
=0);
154 int8_t checkIncDecModel(event_t event
, int8_t i_val
, int8_t i_min
, int8_t i_max
);
155 int8_t checkIncDecModelZero(event_t event
, int8_t i_val
, int8_t i_max
);
156 int8_t checkIncDecGen(event_t event
, int8_t i_val
, int8_t i_min
, int8_t i_max
);
158 #define checkIncDecModel(event, i_val, i_min, i_max) checkIncDec(event, i_val, i_min, i_max, EE_MODEL)
159 #define checkIncDecModelZero(event, i_val, i_max) checkIncDec(event, i_val, 0, i_max, EE_MODEL)
160 #define checkIncDecGen(event, i_val, i_min, i_max) checkIncDec(event, i_val, i_min, i_max, EE_GENERAL)
163 #define CHECK_INCDEC_MODELVAR(event, var, min, max) \
164 var = checkIncDecModel(event, var, min, max)
166 #define CHECK_INCDEC_MODELVAR_ZERO(event, var, max) \
167 var = checkIncDecModelZero(event, var, max)
170 #define CHECK_INCDEC_MODELVAR_CHECK(event, var, min, max, check) \
171 var = checkIncDec(event, var, min, max, EE_MODEL, check)
172 #define CHECK_INCDEC_MODELVAR_ZERO_CHECK(event, var, max, check) \
173 var = checkIncDec(event, var, 0, max, EE_MODEL, check)
175 #define CHECK_INCDEC_MODELVAR_CHECK(event, var, min, max, check) \
176 var = checkIncDec(event, var, min, max, EE_MODEL)
177 #define CHECK_INCDEC_MODELVAR_ZERO_CHECK(event, var, max, check) \
178 CHECK_INCDEC_MODELVAR_ZERO(event, var, max)
182 #define AUTOSWITCH_ENTER_LONG() (attr && event==EVT_KEY_LONG(KEY_ENTER))
183 #define CHECK_INCDEC_SWITCH(event, var, min, max, flags, available) \
184 var = checkIncDec(event, var, min, max, (flags)|INCDEC_SWITCH, available)
185 #define CHECK_INCDEC_MODELSWITCH(event, var, min, max, available) \
186 CHECK_INCDEC_SWITCH(event, var, min, max, EE_MODEL, available)
187 #elif defined(AUTOSWITCH)
188 #define AUTOSWITCH_ENTER_LONG() (attr && event==EVT_KEY_LONG(KEY_ENTER))
189 #define CHECK_INCDEC_SWITCH(event, var, min, max, flags, available) \
190 var = checkIncDec(event, var, min, max, (flags)|INCDEC_SWITCH)
191 #define CHECK_INCDEC_MODELSWITCH(event, var, min, max, available) \
192 CHECK_INCDEC_SWITCH(event, var, min, max, EE_MODEL, available)
194 #define AUTOSWITCH_ENTER_LONG() (0)
195 #define CHECK_INCDEC_SWITCH(event, var, min, max, flags, available) \
196 CHECK_INCDEC_MODELVAR(event, var, min, max)
197 #define CHECK_INCDEC_MODELSWITCH(event, var, min, max, available) \
198 CHECK_INCDEC_MODELVAR(event, var, min, max)
202 #define CHECK_INCDEC_MODELSOURCE(event, var, min, max) \
203 var = checkIncDec(event,var,min,max,EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isSourceAvailable)
204 #elif defined(AUTOSOURCE)
205 #define CHECK_INCDEC_MODELSOURCE(event, var, min, max) \
206 var = checkIncDec(event,var,min,max,EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS)
208 #define CHECK_INCDEC_MODELSOURCE CHECK_INCDEC_MODELVAR
211 #define CHECK_INCDEC_GENVAR(event, var, min, max) \
212 var = checkIncDecGen(event, var, min, max)
214 #if defined(PCBTARANIS)
215 #define CURSOR_ON_LINE() (menuHorizontalPosition < 0)
217 #define CURSOR_ON_LINE() (0)
220 void check(event_t event
, uint8_t curr
, const MenuHandlerFunc
*menuTab
, uint8_t menuTabSize
, const pm_uint8_t
*horTab
, uint8_t horTabMax
, vertpos_t maxrow
);
221 void check_simple(event_t event
, uint8_t curr
, const MenuHandlerFunc
*menuTab
, uint8_t menuTabSize
, vertpos_t maxrow
);
222 void check_submenu_simple(event_t event
, uint8_t maxrow
);
224 void title(const pm_char
* s
);
225 #define TITLE(str) title(str)
228 #define MENU_TAB(...) const uint8_t mstate_tab[] = __VA_ARGS__
230 #define MENU_TAB(...) static const pm_uint8_t mstate_tab[] PROGMEM = __VA_ARGS__
234 #define MENU_CHECK(tab, menu, lines_count) \
235 check(event, menu, tab, DIM(tab), mstate_tab, DIM(mstate_tab)-1, lines_count)
237 #define MENU_CHECK(tab, menu, lines_count) \
238 check(event, menu, tab, DIM(tab), mstate_tab, DIM(mstate_tab)-1, (lines_count)-1)
241 #define MENU(title, tab, menu, lines_count, ...) \
242 MENU_TAB(__VA_ARGS__); \
243 MENU_CHECK(tab, menu, lines_count); \
247 #define SIMPLE_MENU_NOTITLE(tab, menu, lines_count) \
248 check_simple(event, menu, tab, DIM(tab), lines_count);
249 #define SUBMENU_NOTITLE(lines_count, ...) { \
250 MENU_TAB(__VA_ARGS__); \
251 check(event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, lines_count); \
253 #define SUBMENU(title, lines_count, ...) \
254 MENU_TAB(__VA_ARGS__); \
255 check(event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, lines_count); \
257 #define SIMPLE_SUBMENU_NOTITLE(lines_count) \
258 check_submenu_simple(event, lines_count);
260 #define SIMPLE_MENU_NOTITLE(tab, menu, lines_count) \
261 check_simple(event, menu, tab, DIM(tab), (lines_count)-1);
262 #define SUBMENU_NOTITLE(lines_count, ...) { \
263 MENU_TAB(__VA_ARGS__); \
264 check(event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, (lines_count)-1); \
267 #define SUBMENU(title, lines_count, ...) \
268 MENU_TAB(__VA_ARGS__); \
269 check(event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, (lines_count)-1); \
272 #define SIMPLE_SUBMENU_NOTITLE(lines_count) \
273 check_submenu_simple(event, (lines_count)-1);
279 #define SIMPLE_MENU(title, tab, menu, lines_count) \
280 SIMPLE_MENU_NOTITLE(tab, menu, lines_count); \
283 #define SIMPLE_SUBMENU(title, lines_count) \
284 SIMPLE_SUBMENU_NOTITLE(lines_count); \
288 typedef int choice_t
;
290 typedef int8_t choice_t
;
293 choice_t
editChoice(coord_t x
, coord_t y
, const pm_char
* label
, const pm_char
*values
, choice_t value
, choice_t min
, choice_t max
, LcdFlags attr
, event_t event
);
294 uint8_t editCheckBox(uint8_t value
, coord_t x
, coord_t y
, const pm_char
* label
, LcdFlags attr
, event_t event
);
295 int8_t editSwitch(coord_t x
, coord_t y
, int8_t value
, LcdFlags attr
, event_t event
);
297 #define ON_OFF_MENU_ITEM(value, x, y, label, attr, event) value = editCheckBox(value, x, y, label, attr, event)
299 #if defined(CPUARM) && defined(GVARS)
300 #define GVAR_MENU_ITEM(x, y, v, min, max, attr, editflags, event) editGVarFieldValue(x, y, v, min, max, attr, editflags, event)
302 #define GVAR_MENU_ITEM(x, y, v, min, max, attr, editflags, event) editGVarFieldValue(x, y, v, min, max, attr, event)
305 #if defined(GVARS) && defined(CPUARM)
306 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
);
307 void drawGVarName(coord_t x
, coord_t y
, int8_t index
, LcdFlags flags
=0);
308 void drawGVarValue(coord_t x
, coord_t y
, uint8_t gvar
, gvar_t value
, LcdFlags flags
=0);
310 int16_t editGVarFieldValue(coord_t x
, coord_t y
, int16_t value
, int16_t min
, int16_t max
, LcdFlags attr
, event_t event
);
312 int16_t editGVarFieldValue(coord_t x
, coord_t y
, int16_t value
, int16_t min
, int16_t max
, LcdFlags attr
, event_t event
);
315 void gvarWeightItem(coord_t x
, coord_t y
, MixData
* md
, LcdFlags attr
, event_t event
);
318 #define displayGVar(x, y, v, min, max) GVAR_MENU_ITEM(x, y, v, min, max, 0, 0, 0)
320 #define displayGVar(x, y, v, min, max) lcdDraw8bitsNumber(x, y, v)
324 void editName(coord_t x
, coord_t y
, char * name
, uint8_t size
, event_t event
, uint8_t active
, LcdFlags attr
=ZCHAR
);
326 void editName(coord_t x
, coord_t y
, char * name
, uint8_t size
, event_t event
, uint8_t active
);
330 #define editSingleName(x, y, label, name, size, event, active) editName(x, y, name, size, event, active)
332 void editSingleName(coord_t x
, coord_t y
, const pm_char
* label
, char * name
, uint8_t size
, event_t event
, uint8_t active
);
335 uint8_t editDelay(coord_t y
, event_t event
, uint8_t attr
, const pm_char
* str
, uint8_t delay
);
336 #define EDIT_DELAY(x, y, event, attr, str, delay) editDelay(y, event, attr, str, delay)
338 #define WARNING_TYPE_ASTERISK 0
339 #define WARNING_TYPE_CONFIRM 1
340 #define WARNING_TYPE_INPUT 2
342 extern const pm_char
* warningText
;
343 extern const pm_char
* warningInfoText
;
344 extern uint8_t warningInfoLength
;
345 extern uint8_t warningResult
;
346 extern uint8_t warningType
;
350 extern uint8_t s_copyMode
;
351 extern int8_t s_copySrcRow
;
352 extern int8_t s_copyTgtOfs
;
353 extern uint8_t s_currIdx
;
354 extern uint8_t s_curveChan
;
355 extern uint8_t s_copySrcIdx
;
356 extern uint8_t s_copySrcCh
;
357 extern int8_t s_currCh
;
358 extern uint8_t s_maxLines
;
361 #define STATUS_LINE_LENGTH 32
362 extern char statusLineMsg
[STATUS_LINE_LENGTH
];
363 void showStatusLine();
364 void drawStatusLine();
366 #define drawStatusLine()
370 #define TEXT_FILENAME_MAXLEN 40
371 extern char s_text_file
[TEXT_FILENAME_MAXLEN
];
372 void menuTextView(event_t event
);
373 void pushMenuTextView(const char *filename
);
374 void pushModelNotes();
377 #define LABEL(...) (uint8_t)-1
379 #define CURSOR_MOVED_LEFT(event) (IS_ROTARY_LEFT(event) || EVT_KEY_MASK(event) == KEY_LEFT)
380 #define CURSOR_MOVED_RIGHT(event) (IS_ROTARY_RIGHT(event) || EVT_KEY_MASK(event) == KEY_RIGHT)
382 #if defined(ROTARY_ENCODERS)
383 #define CASE_EVT_ROTARY_BREAK case EVT_ROTARY_BREAK:
384 #define CASE_EVT_ROTARY_LONG case EVT_ROTARY_LONG:
386 #define CASE_EVT_ROTARY_BREAK
387 #define CASE_EVT_ROTARY_LONG
390 #if defined(ROTARY_ENCODER_NAVIGATION)
391 #define IS_ROTARY_LEFT(evt) (evt == EVT_ROTARY_LEFT)
392 #define IS_ROTARY_RIGHT(evt) (evt == EVT_ROTARY_RIGHT)
393 #define IS_ROTARY_BREAK(evt) (evt == EVT_ROTARY_BREAK)
394 #define IS_ROTARY_LONG(evt) (evt == EVT_ROTARY_LONG)
395 #define IS_ROTARY_EVENT(evt) (EVT_KEY_MASK(evt) >= 0x0e)
396 void repeatLastCursorMove(event_t event
);
397 #define REPEAT_LAST_CURSOR_MOVE() { if (EVT_KEY_MASK(event) >= 0x0e) putEvent(event); else repeatLastCursorMove(event); }
398 #define MOVE_CURSOR_FROM_HERE() if (menuHorizontalPosition > 0) REPEAT_LAST_CURSOR_MOVE()
400 #define IS_ROTARY_LEFT(evt) (0)
401 #define IS_ROTARY_RIGHT(evt) (0)
402 #define IS_ROTARY_BREAK(evt) (0)
403 #define IS_ROTARY_LONG(evt) (0)
404 #define IS_ROTARY_EVENT(evt) (0)
405 void repeatLastCursorMove(event_t event
);
406 #define REPEAT_LAST_CURSOR_MOVE() repeatLastCursorMove(event)
407 #define MOVE_CURSOR_FROM_HERE() REPEAT_LAST_CURSOR_MOVE()
412 #define EDIT_MODE_INIT 0
414 #define EDIT_MODE_INIT -1
418 #define editNameCursorPos menuHorizontalPosition
420 extern uint8_t editNameCursorPos
;
423 #if defined(VIRTUAL_INPUTS)
424 uint8_t getExposCount();
425 void insertExpo(uint8_t idx
);
426 void deleteExpo(uint8_t idx
);
427 uint8_t getMixesCount();
428 void insertMix(uint8_t idx
);
429 void deleteMix(uint8_t idx
);
432 typedef int (*FnFuncP
) (int x
);
433 void drawFunction(FnFuncP fn
, uint8_t offset
=0);
435 void onSourceLongEnterPress(const char *result
);
437 uint8_t switchToMix(uint8_t source
);
439 void deleteExpoMix(uint8_t expo
, uint8_t idx
);
441 void drawCheckBox(coord_t x
, coord_t y
, uint8_t value
, LcdFlags attr
);
443 extern const pm_uchar sticks
[] PROGMEM
;
446 void drawSecondSplash();
447 void drawScreenIndex(uint8_t index
, uint8_t count
, uint8_t attr
);
448 void drawStick(coord_t centrex
, int16_t xval
, int16_t yval
);
450 void doMainScreenGraphics();
452 void drawProgressBar(const char * label
, int num
, int den
);
453 void drawSleepBitmap();
456 void drawVerticalScrollbar(coord_t x
, coord_t y
, coord_t h
, uint16_t offset
, uint16_t count
, uint8_t visible
);
459 #if defined(PCBTARANIS)
460 void drawAlertBox(const pm_char
* title
, const pm_char
* text
, const char * action
);
464 #define ALERT_SOUND_ARG , uint8_t sound
466 #define ALERT_SOUND_ARG
469 void showAlertBox(const pm_char
* title
, const pm_char
* text
, const char * action ALERT_SOUND_ARG
);
471 #define SET_SCROLLBAR_X(x)
472 #define LOAD_MODEL_BITMAP()
474 #define IS_MAIN_VIEW_DISPLAYED() menuHandlers[0] == menuMainView
475 #if defined(TELEMETRY_FRSKY)
476 #define IS_TELEMETRY_VIEW_DISPLAYED() menuHandlers[0] == menuViewTelemetryFrsky
478 #define IS_TELEMETRY_VIEW_DISPLAYED() false
480 #define IS_OTHER_VIEW_DISPLAYED() false
483 void editCurveRef(coord_t x
, coord_t y
, CurveRef
& curve
, event_t event
, LcdFlags flags
);
486 #if defined(FLIGHT_MODES)
487 void displayFlightModes(coord_t x
, coord_t y
, FlightModesType value
);
488 FlightModesType
editFlightModes(coord_t x
, coord_t y
, event_t event
, FlightModesType value
, uint8_t attr
);
490 #define displayFlightModes(...)