Companion: Russian UI (#7180)
[opentx.git] / radio / src / gui / 128x64 / widgets.cpp
blobef7de1a1074e7ff7538a40fafc0748415b732d37
1 /*
2 * Copyright (C) OpenTX
4 * Based on code named
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.
21 #include "opentx.h"
23 void drawStick(coord_t centrex, int16_t xval, int16_t yval)
25 #define BOX_CENTERY (LCD_H-9-BOX_WIDTH/2)
26 #define MARKER_WIDTH 5
27 lcdDrawSquare(centrex-BOX_WIDTH/2, BOX_CENTERY-BOX_WIDTH/2, BOX_WIDTH);
28 lcdDrawSolidVerticalLine(centrex, BOX_CENTERY-1, 3);
29 lcdDrawSolidHorizontalLine(centrex-1, BOX_CENTERY, 3);
30 lcdDrawSquare(centrex + (xval/((2*RESX)/(BOX_WIDTH-MARKER_WIDTH))) - MARKER_WIDTH/2, BOX_CENTERY - (yval/((2*RESX)/(BOX_WIDTH-MARKER_WIDTH))) - MARKER_WIDTH/2, MARKER_WIDTH, ROUND);
31 #undef BOX_CENTERY
32 #undef MARKER_WIDTH
35 void drawCheckBox(coord_t x, coord_t y, uint8_t value, LcdFlags attr)
37 #if defined(GRAPHICS)
38 if (value)
39 lcdDrawChar(x+1, y, '#');
40 if (attr)
41 lcdDrawSolidFilledRect(x, y, 7, 7);
42 else
43 lcdDrawSquare(x, y, 7);
44 #else
45 /* ON / OFF version */
46 lcdDrawTextAtIndex(x, y, STR_OFFON, value, attr ? INVERS:0) ;
47 #endif
50 void drawScreenIndex(uint8_t index, uint8_t count, uint8_t attr)
52 lcdDrawNumber(LCD_W, 0, count, RIGHT | attr);
53 coord_t x = 1+LCD_W-FW*(count>9 ? 3 : 2);
54 lcdDrawChar(x, 0, '/', attr);
55 lcdDrawNumber(x, 0, index+1, RIGHT | attr);
58 void drawVerticalScrollbar(coord_t x, coord_t y, coord_t h, uint16_t offset, uint16_t count, uint8_t visible)
60 lcdDrawVerticalLine(x, y, h, DOTTED);
61 coord_t yofs = (h * offset) / count;
62 coord_t yhgt = (h * visible) / count;
63 if (yhgt + yofs > h)
64 yhgt = h - yofs;
65 lcdDrawVerticalLine(x, y + yofs, yhgt, SOLID, FORCE);
68 void title(const char * s)
70 lcdDrawText(0, 0, s, INVERS);
73 choice_t editChoice(coord_t x, coord_t y, const char * label, const char *values, choice_t value, choice_t min, choice_t max, LcdFlags attr, event_t event, IsValueAvailable isValueAvailable)
75 drawFieldLabel(x, y, label);
76 if (values) lcdDrawTextAtIndex(x, y, values, value-min, attr);
77 if (attr & (~RIGHT)) value = checkIncDec(event, value, min, max, (isModelMenuDisplayed()) ? EE_MODEL : EE_GENERAL, isValueAvailable);
78 return value;
81 uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const char *label, LcdFlags attr, event_t event )
83 #if defined(GRAPHICS)
84 drawCheckBox(x, y, value, attr);
85 return editChoice(x, y, label, NULL, value, 0, 1, attr, event);
86 #else
87 return editChoice(x, y, label, STR_OFFON, value, 0, 1, attr, event);
88 #endif
91 swsrc_t editSwitch(coord_t x, coord_t y, swsrc_t value, LcdFlags attr, event_t event)
93 drawFieldLabel(x, y, STR_SWITCH);
94 drawSwitch(x, y, value, attr);
95 if (attr & (~RIGHT)) CHECK_INCDEC_MODELSWITCH(event, value, SWSRC_FIRST_IN_MIXES, SWSRC_LAST_IN_MIXES, isSwitchAvailableInMixes);
96 return value;
99 void drawSlider(coord_t x, coord_t y, uint8_t width, uint8_t value, uint8_t max, uint8_t attr)
101 lcdDrawChar(x + (value * (width - FWNUM)) / max, y, '$');
102 lcdDrawSolidHorizontalLine(x, y + 3, width, FORCE);
103 if (attr && (!(attr & BLINK) || !BLINK_ON_PHASE)) {
104 lcdDrawSolidFilledRect(x, y, width, FH - 1);
108 void drawSlider(coord_t x, coord_t y, uint8_t value, uint8_t max, uint8_t attr)
110 drawSlider(x, y, 5*FW - 1, value, max, attr);
113 #if defined(GVARS)
114 void drawGVarValue(coord_t x, coord_t y, uint8_t gvar, gvar_t value, LcdFlags flags)
116 uint8_t prec = g_model.gvars[gvar].prec;
117 if (prec > 0) {
118 flags |= (prec == 1 ? PREC1 : PREC2);
120 drawValueWithUnit(x, y, value, g_model.gvars[gvar].unit ? UNIT_PERCENT : UNIT_RAW, flags);
123 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)
125 uint16_t delta = GV_GET_GV1_VALUE(max);
126 bool invers = (attr & INVERS);
128 // TRACE("editGVarFieldValue(val=%d min=%d max=%d)", value, min, max);
130 if (invers && event == EVT_KEY_LONG(KEY_ENTER)) {
131 s_editMode = !s_editMode;
132 if (attr & PREC1)
133 value = (GV_IS_GV_VALUE(value, min, max) ? GET_GVAR(value, min, max, mixerCurrentFlightMode)*10 : delta);
134 else
135 value = (GV_IS_GV_VALUE(value, min, max) ? GET_GVAR(value, min, max, mixerCurrentFlightMode) : delta);
136 storageDirty(EE_MODEL);
139 if (GV_IS_GV_VALUE(value, min, max)) {
140 attr &= ~PREC1;
141 int8_t idx = (int16_t)GV_INDEX_CALC_DELTA(value, delta);
142 if (invers) {
143 CHECK_INCDEC_MODELVAR(event, idx, -MAX_GVARS, MAX_GVARS-1);
145 if (idx < 0) {
146 value = (int16_t)GV_CALC_VALUE_IDX_NEG(idx, delta);
148 else {
149 value = (int16_t)GV_CALC_VALUE_IDX_POS(idx, delta);
151 drawGVarName(x, y, idx, attr);
153 else {
154 lcdDrawNumber(x, y, value, attr);
155 if (invers) value = checkIncDec(event, value, min, max, EE_MODEL | editflags);
157 return value;
159 #elif defined(GVARS)
160 int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, event_t event)
162 uint16_t delta = GV_GET_GV1_VALUE(max);
163 bool invers = (attr & INVERS);
165 // TRACE("editGVarFieldValue(val=%d min=%d max=%d)", value, min, max);
167 if (invers && event == EVT_KEY_LONG(KEY_ENTER)) {
168 s_editMode = !s_editMode;
169 value = (GV_IS_GV_VALUE(value, min, max) ? GET_GVAR(value, min, max, mixerCurrentFlightMode) : delta);
170 storageDirty(EE_MODEL);
172 if (GV_IS_GV_VALUE(value, min, max)) {
173 if (attr & LEFT)
174 attr -= LEFT; /* because of ZCHAR */
175 else
176 x -= 2*FW+FWNUM;
178 int8_t idx = (int16_t) GV_INDEX_CALC_DELTA(value, delta);
179 if (invers) {
180 idx = checkIncDec(event, idx, -MAX_GVARS, MAX_GVARS-1, EE_MODEL|NO_DBLKEYS); // disable double keys
182 if (idx < 0) {
183 value = (int16_t) GV_CALC_VALUE_IDX_NEG(idx, delta);
184 idx = -idx;
185 lcdDrawChar(x-6, y, '-', attr);
187 else {
188 value = (int16_t) GV_CALC_VALUE_IDX_POS(idx, delta);
189 idx++;
191 drawStringWithIndex(x, y, STR_GV, idx, attr);
193 else {
194 lcdDrawNumber(x, y, value, attr);
195 if (invers) value = checkIncDec(event, value, min, max, EE_MODEL);
197 return value;
199 #else
200 int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, event_t event)
202 lcdDrawNumber(x, y, value, attr);
203 if (attr&INVERS) value = checkIncDec(event, value, min, max, EE_MODEL);
204 return value;
206 #endif
208 #if defined(SDCARD)
209 char statusLineMsg[STATUS_LINE_LENGTH];
210 tmr10ms_t statusLineTime = 0;
211 uint8_t statusLineHeight = 0;
213 void showStatusLine()
215 statusLineTime = get_tmr10ms();
218 #define STATUS_LINE_DELAY (3 * 100) /* 3s */
219 void drawStatusLine()
221 if (statusLineTime) {
222 if ((tmr10ms_t)(get_tmr10ms() - statusLineTime) <= (tmr10ms_t)STATUS_LINE_DELAY) {
223 if (statusLineHeight < FH) statusLineHeight++;
225 else if (statusLineHeight) {
226 statusLineHeight--;
228 else {
229 statusLineTime = 0;
232 lcdDrawFilledRect(0, LCD_H-statusLineHeight, LCD_W, FH, SOLID, ERASE);
233 lcdDrawText(5, LCD_H+1-statusLineHeight, statusLineMsg);
234 lcdDrawFilledRect(0, LCD_H-statusLineHeight, LCD_W, FH, SOLID);
237 #endif