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"
30 #define HEADER_LINE_COLUMNS
32 #define DEFAULT_SCROLLBAR_X (LCD_W-1)
33 #define NUM_BODY_LINES (LCD_LINES-1)
34 #define MENU_HEADER_HEIGHT FH
35 #define MENU_INIT_VPOS 0
37 #define MODEL_BITMAP_WIDTH 64
38 #define MODEL_BITMAP_HEIGHT 32
39 #define MODEL_BITMAP_SIZE BITMAP_BUFFER_SIZE(MODEL_BITMAP_WIDTH, MODEL_BITMAP_HEIGHT)
40 #define LOAD_MODEL_BITMAP() loadModelBitmap(g_model.header.bitmap, modelBitmap)
42 #define CURVE_SIDE_WIDTH (LCD_H/2)
43 #define CURVE_CENTER_X (LCD_W-CURVE_SIDE_WIDTH-2)
44 #define CURVE_CENTER_Y (LCD_H/2)
46 #define MIXES_2ND_COLUMN (18*FW)
48 #define MENUS_SCROLLBAR_WIDTH 2
50 inline void drawFieldLabel(coord_t x
, coord_t y
, const char * str
)
52 lcdDrawText(0, y
, str
);
55 extern uint8_t modelBitmap
[MODEL_BITMAP_SIZE
];
56 bool loadModelBitmap(char * name
, uint8_t * bitmap
);
60 const MenuHandlerFunc action
;
63 // Temporary no highlight
64 extern uint8_t noHighlightCounter
;
65 #define NO_HIGHLIGHT() (noHighlightCounter > 0)
66 #define START_NO_HIGHLIGHT() do { noHighlightCounter = 25; } while(0)
68 void drawCheckBox(coord_t x
, coord_t y
, uint8_t value
, LcdFlags attr
);
69 void drawSlider(coord_t x
, coord_t y
, uint8_t value
, uint8_t max
, uint8_t attr
);
71 void drawSecondSplash();
72 void drawScreenIndex(uint8_t index
, uint8_t count
, uint8_t attr
);
73 void drawVerticalScrollbar(coord_t x
, coord_t y
, coord_t h
, uint16_t offset
, uint16_t count
, uint8_t visible
);
74 void displayMenuBar(const MenuItem
* menu
, int index
);
75 void drawProgressBar(const char * label
, int num
, int den
);
76 void drawGauge(coord_t x
, coord_t y
, coord_t w
, coord_t h
, int32_t val
, int32_t max
);
77 void drawColumnHeader(const char * const * headers
, uint8_t index
);
78 void drawStick(coord_t centrex
, int16_t xval
, int16_t yval
);
80 void drawAlertBox(const char * title
, const char * text
, const char * action
);
81 #define ALERT_SOUND_ARG , uint8_t sound
82 void showAlertBox(const char * title
, const char * text
, const char * action
, uint8_t sound
);
84 void doMainScreenGraphics();
86 typedef uint16_t FlightModesType
;
88 extern int8_t checkIncDec_Ret
; // global helper vars
90 #define EDIT_SELECT_MENU -1
91 #define EDIT_SELECT_FIELD 0
92 #define EDIT_MODIFY_FIELD 1
93 #define EDIT_MODIFY_STRING 2
94 extern int8_t s_editMode
; // global editmode
97 #define EE_GENERAL 0x01
99 #define NO_INCDEC_MARKS 0x04
100 #define INCDEC_SWITCH 0x08
101 #define INCDEC_SOURCE 0x10
102 #define INCDEC_REP10 0x40
103 #define NO_DBLKEYS 0x80
105 #define INCDEC_DECLARE_VARS(f) uint8_t incdecFlag = (f); IsValueAvailable isValueAvailable = NULL
106 #define INCDEC_SET_FLAG(f) incdecFlag = (f)
107 #define INCDEC_ENABLE_CHECK(fn) isValueAvailable = fn
108 #define CHECK_INCDEC_PARAM(event, var, min, max) checkIncDec(event, var, min, max, incdecFlag, isValueAvailable)
110 // mawrow special values
111 #define TITLE_ROW ((uint8_t)-1)
112 #define HIDDEN_ROW ((uint8_t)-2)
114 struct CheckIncDecStops
124 return stops
[count
-1];
126 bool contains(int value
) const
128 for (int i
=0; i
<count
; ++i
) {
132 else if (value
< stop
)
139 extern const CheckIncDecStops
&stops100
;
140 extern const CheckIncDecStops
&stops1000
;
141 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) \
149 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 #define checkIncDecModel(event, i_val, i_min, i_max) checkIncDec(event, i_val, i_min, i_max, EE_MODEL)
151 #define checkIncDecModelZero(event, i_val, i_max) checkIncDec(event, i_val, 0, i_max, EE_MODEL)
152 #define checkIncDecGen(event, i_val, i_min, i_max) checkIncDec(event, i_val, i_min, i_max, EE_GENERAL)
154 #define CHECK_INCDEC_MODELVAR(event, var, min, max) \
155 var = checkIncDecModel(event, var, min, max)
157 #define CHECK_INCDEC_MODELVAR_ZERO(event, var, max) \
158 var = checkIncDecModelZero(event, var, max)
160 #define CHECK_INCDEC_MODELVAR_CHECK(event, var, min, max, check) \
161 var = checkIncDec(event, var, min, max, EE_MODEL, check)
163 #define CHECK_INCDEC_MODELVAR_ZERO_CHECK(event, var, max, check) \
164 var = checkIncDec(event, var, 0, max, EE_MODEL, check)
166 #define AUTOSWITCH_ENTER_LONG() (attr && event==EVT_KEY_LONG(KEY_ENTER))
167 #define CHECK_INCDEC_SWITCH(event, var, min, max, flags, available) \
168 var = checkIncDec(event, var, min, max, (flags)|INCDEC_SWITCH, available)
169 #define CHECK_INCDEC_MODELSWITCH(event, var, min, max, available) \
170 CHECK_INCDEC_SWITCH(event, var, min, max, EE_MODEL, available)
172 #define CHECK_INCDEC_MODELSOURCE(event, var, min, max) \
173 var = checkIncDec(event, var, min, max, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isSourceAvailable)
175 #define CHECK_INCDEC_GENVAR(event, var, min, max) \
176 var = checkIncDecGen(event, var, min, max)
178 #define NAVIGATION_LINE_BY_LINE 0x40
179 #define CURSOR_ON_LINE() (menuHorizontalPosition<0)
181 #define CHECK_FLAG_NO_SCREEN_INDEX 1
182 void check(const char * title
, event_t event
, uint8_t curr
, const MenuHandlerFunc
*menuTab
, uint8_t menuTabSize
, const pm_uint8_t
*horTab
, uint8_t horTabMax
, vertpos_t maxrow
, uint8_t flags
=0);
183 void check_simple(const char *title
, event_t event
, uint8_t curr
, const MenuHandlerFunc
*menuTab
, uint8_t menuTabSize
, vertpos_t maxrow
);
184 void check_submenu_simple(const char * title
, event_t event
, uint8_t maxrow
);
186 void title(const pm_char
* s
);
187 #define TITLE(str) title(str)
189 #define MENU_TAB(...) const uint8_t mstate_tab[] = __VA_ARGS__
191 #define MENU_CHECK(title, tab, menu, lines_count) \
192 check(title, event, menu, tab, DIM(tab), mstate_tab, DIM(mstate_tab)-1, lines_count)
194 #define MENU_CHECK_FLAGS(title, tab, menu, flags, lines_count) \
195 check(title, event, menu, tab, DIM(tab), mstate_tab, DIM(mstate_tab)-1, lines_count, flags)
197 #define MENU(title, tab, menu, lines_count, ...) \
198 MENU_TAB(__VA_ARGS__); \
199 MENU_CHECK(title, tab, menu, lines_count)
201 #define MENU_FLAGS(title, tab, menu, flags, lines_count, ...) \
202 MENU_TAB(__VA_ARGS__); \
203 MENU_CHECK_FLAGS(title, tab, menu, flags, lines_count)
205 #define SIMPLE_MENU_FLAGS(title, tab, menu, flags, lines_count, ...) \
206 check(title, event, menu, tab, DIM(tab), NULL, 0, lines_count, flags)
208 #define SIMPLE_MENU(title, tab, menu, lines_count) \
209 check_simple(title, event, menu, tab, DIM(tab), lines_count)
211 #define SUBMENU_NOTITLE(lines_count, ...) { \
212 MENU_TAB(__VA_ARGS__); \
213 check(NULL, event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, lines_count); \
216 #define SUBMENU(title, lines_count, ...) \
217 MENU_TAB(__VA_ARGS__); \
218 check(title, event, 0, NULL, 0, mstate_tab, DIM(mstate_tab)-1, lines_count)
220 #define SIMPLE_SUBMENU_NOTITLE(lines_count) \
221 check_submenu_simple(NULL, event, lines_count);
223 #define SIMPLE_SUBMENU(title, lines_count) \
224 check_submenu_simple(title, event, lines_count)
226 typedef int choice_t
;
228 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
);
229 uint8_t editCheckBox(uint8_t value
, coord_t x
, coord_t y
, const pm_char
*label
, LcdFlags attr
, event_t event
);
230 swsrc_t
editSwitch(coord_t x
, coord_t y
, swsrc_t value
, LcdFlags attr
, event_t event
);
232 #define ON_OFF_MENU_ITEM(value, x, y, label, attr, event) value = editCheckBox(value, x, y, label, attr, event)
235 void drawGVarName(coord_t x
, coord_t y
, int8_t index
, LcdFlags flags
=0);
236 void drawGVarValue(coord_t x
, coord_t y
, uint8_t gvar
, gvar_t value
, LcdFlags flags
=0);
237 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
);
238 #define GVAR_MENU_ITEM(x, y, v, min, max, lcdattr, editflags, event) editGVarFieldValue(x, y, v, min, max, lcdattr, editflags, event)
239 #define displayGVar(x, y, v, min, max) GVAR_MENU_ITEM(x, y, v, min, max, 0, 0, 0)
241 #define GVAR_MENU_ITEM(x, y, v, min, max, lcdattr, editflags, event) editGVarFieldValue(x, y, v, min, max, lcdattr, event)
242 int16_t editGVarFieldValue(coord_t x
, coord_t y
, int16_t value
, int16_t min
, int16_t max
, LcdFlags attr
, event_t event
);
243 #define displayGVar(x, y, v, min, max) lcdDrawNumber(x, y, v)
246 void gvarWeightItem(coord_t x
, coord_t y
, MixData
* md
, LcdFlags attr
, event_t event
);
248 extern uint8_t s_curveChan
;
249 void editCurveRef(coord_t x
, coord_t y
, CurveRef
& curve
, event_t event
, LcdFlags flags
);
251 extern uint8_t editNameCursorPos
;
252 void editName(coord_t x
, coord_t y
, char * name
, uint8_t size
, event_t event
, uint8_t active
, LcdFlags attr
=ZCHAR
);
253 void editSingleName(coord_t x
, coord_t y
, const pm_char
* label
, char * name
, uint8_t size
, event_t event
, uint8_t active
);
255 uint8_t editDelay(coord_t y
, event_t event
, uint8_t attr
, const char * str
, uint8_t delay
);
256 #define EDIT_DELAY(y, event, attr, str, delay) editDelay(y, event, attr, str, delay)
258 #define WARNING_TYPE_ASTERISK 0
259 #define WARNING_TYPE_CONFIRM 1
260 #define WARNING_TYPE_INPUT 2
262 void copySelection(char * dst
, const char * src
, uint8_t size
);
264 extern const pm_char
* warningText
;
265 extern const pm_char
* warningInfoText
;
266 extern uint8_t warningInfoLength
;
267 extern uint8_t warningResult
;
268 extern uint8_t warningType
;
272 extern uint8_t s_copyMode
;
273 extern int8_t s_copySrcRow
;
274 extern int8_t s_copyTgtOfs
;
275 extern uint8_t s_currIdx
;
276 extern uint8_t s_maxLines
;
277 extern uint8_t s_copySrcIdx
;
278 extern uint8_t s_copySrcCh
;
279 extern int8_t s_currCh
;
281 uint8_t getExposCount();
282 void deleteExpo(uint8_t idx
);
283 void insertExpo(uint8_t idx
);
285 uint8_t getMixesCount();
286 void deleteMix(uint8_t idx
);
287 void insertMix(uint8_t idx
);
289 #define STATUS_LINE_LENGTH 32
290 extern char statusLineMsg
[STATUS_LINE_LENGTH
];
291 void showStatusLine();
292 void drawStatusLine();
294 #define TEXT_FILENAME_MAXLEN 40
295 extern char s_text_file
[TEXT_FILENAME_MAXLEN
];
296 void menuTextView(event_t event
);
297 void pushMenuTextView(const char *filename
);
298 void pushModelNotes();
300 void menuChannelsView(event_t event
);
302 #define LABEL(...) (uint8_t)-1
304 #if defined(ROTARY_ENCODER_NAVIGATION)
305 #define CURSOR_MOVED_LEFT(event) (event==EVT_ROTARY_LEFT)
306 #define CURSOR_MOVED_RIGHT(event) (event==EVT_ROTARY_RIGHT)
308 #define CURSOR_MOVED_LEFT(event) (EVT_KEY_MASK(event) == KEY_LEFT)
309 #define CURSOR_MOVED_RIGHT(event) (EVT_KEY_MASK(event) == KEY_RIGHT)
312 #define REPEAT_LAST_CURSOR_MOVE() { if (CURSOR_MOVED_LEFT(event) || CURSOR_MOVED_RIGHT(event)) putEvent(event); else menuHorizontalPosition = 0; }
313 #define MOVE_CURSOR_FROM_HERE() if (menuHorizontalPosition > 0) REPEAT_LAST_CURSOR_MOVE()
315 #define MENU_FIRST_LINE_EDIT (menuTab ? (MAXCOL((uint16_t)0) >= HIDDEN_ROW ? (MAXCOL((uint16_t)1) >= HIDDEN_ROW ? 2 : 1) : 0) : 0)
316 #define POS_HORZ_INIT(posVert) ((COLATTR(posVert) & NAVIGATION_LINE_BY_LINE) ? -1 : 0)
317 #define EDIT_MODE_INIT 0 // TODO enum
319 typedef int (*FnFuncP
) (int x
);
320 void drawFunction(FnFuncP fn
, uint8_t offset
=0);
322 void onSourceLongEnterPress(const char *result
);
324 uint8_t switchToMix(uint8_t source
);
326 extern coord_t scrollbar_X
;
327 #define SET_SCROLLBAR_X(x) scrollbar_X = (x);
329 extern const pm_uchar sticks
[] PROGMEM
;
331 #if defined(FLIGHT_MODES)
332 void displayFlightModes(coord_t x
, coord_t y
, FlightModesType value
);
333 FlightModesType
editFlightModes(coord_t x
, coord_t y
, event_t event
, FlightModesType value
, uint8_t attr
);
335 #define displayFlightModes(...)
338 #define IS_MAIN_VIEW_DISPLAYED() menuHandlers[0] == menuMainView
339 #define IS_TELEMETRY_VIEW_DISPLAYED() menuHandlers[0] == menuViewTelemetryFrsky
340 #define IS_OTHER_VIEW_DISPLAYED() (menuHandlers[0] == menuMainViewChannelsMonitor || menuHandlers[0] == menuChannelsView)