From e904da89e70f3364124a8e3f177bebb5c5c450d0 Mon Sep 17 00:00:00 2001 From: philmoz Date: Sat, 18 Oct 2025 16:08:44 +1100 Subject: [PATCH] chore(bw): refactor and cleanup of code (#6481) --- radio/src/edgetx.h | 2 + radio/src/gui/128x64/CMakeLists.txt | 3 +- radio/src/gui/128x64/gui.h | 157 +---- radio/src/gui/128x64/lcd.cpp | 614 +----------------- radio/src/gui/128x64/lcd.h | 148 +---- radio/src/gui/128x64/menu_model.cpp | 74 --- radio/src/gui/128x64/menus.h | 121 +--- radio/src/gui/128x64/model_gvars.cpp | 30 - .../src/gui/128x64/model_logical_switches.cpp | 18 +- radio/src/gui/128x64/model_mix_edit.cpp | 15 +- radio/src/gui/128x64/model_outputs.cpp | 7 +- radio/src/gui/128x64/model_setup.cpp | 31 +- radio/src/gui/128x64/model_telemetry.cpp | 15 +- .../src/gui/128x64/model_telemetry_sensor.cpp | 8 +- radio/src/gui/128x64/model_templates.cpp | 50 -- radio/src/gui/128x64/popups.h | 11 +- radio/src/gui/128x64/radio_calibration.cpp | 2 +- radio/src/gui/128x64/view_main.cpp | 9 +- radio/src/gui/128x64/widgets.cpp | 223 ------- radio/src/gui/212x64/CMakeLists.txt | 3 +- radio/src/gui/212x64/gui.h | 142 +--- radio/src/gui/212x64/lcd.cpp | 507 +-------------- radio/src/gui/212x64/lcd.h | 147 +---- radio/src/gui/212x64/menu_radio.cpp | 40 -- radio/src/gui/212x64/menus.h | 99 +-- radio/src/gui/212x64/model_custom_scripts.cpp | 2 +- radio/src/gui/212x64/model_failsafe.cpp | 2 +- radio/src/gui/212x64/model_gvars.cpp | 30 - radio/src/gui/212x64/model_mix_edit.cpp | 8 +- radio/src/gui/212x64/model_setup.cpp | 8 +- .../gui/212x64/model_special_functions.cpp | 2 +- radio/src/gui/212x64/model_telemetry.cpp | 2 +- radio/src/gui/212x64/popups.h | 11 +- radio/src/gui/212x64/radio_calibration.cpp | 2 +- radio/src/gui/212x64/view_channels.cpp | 2 +- radio/src/gui/212x64/view_main.cpp | 8 +- radio/src/gui/212x64/widgets.cpp | 198 ------ radio/src/gui/CMakeLists.txt | 1 + radio/src/gui/common/stdlcd/CMakeLists.txt | 8 +- .../src/gui/common/stdlcd/draw_functions.cpp | 111 ++++ radio/src/gui/common/stdlcd/draw_functions.h | 19 + .../stdlcd/{features.h => feature_control.h} | 0 radio/src/gui/common/stdlcd/lcd_common.cpp | 533 +++++++++++++++ radio/src/gui/common/stdlcd/lcd_common.h | 175 +++++ .../{212x64 => common/stdlcd}/menu_model.cpp | 21 +- .../{128x64 => common/stdlcd}/menu_radio.cpp | 4 +- radio/src/gui/common/stdlcd/menus.h | 63 -- .../stdlcd/{menus.cpp => menus_common.cpp} | 0 radio/src/gui/common/stdlcd/menus_common.h | 213 ++++++ radio/src/gui/common/stdlcd/model_heli.cpp | 46 +- radio/src/gui/common/stdlcd/model_notes.cpp | 1 + .../stdlcd/{popups.cpp => popups_common.cpp} | 1 - radio/src/gui/common/stdlcd/popups_common.h | 29 +- .../src/gui/common/stdlcd/radio_hardware.cpp | 24 +- .../src/gui/common/stdlcd/widgets_common.cpp | 181 ++++++ radio/src/gui/common/stdlcd/widgets_common.h | 76 +++ radio/src/translations/i18n/cn.h | 3 +- radio/src/translations/i18n/cz.h | 3 +- radio/src/translations/i18n/da.h | 3 +- radio/src/translations/i18n/de.h | 3 +- radio/src/translations/i18n/en.h | 3 +- radio/src/translations/i18n/es.h | 3 +- radio/src/translations/i18n/fi.h | 3 +- radio/src/translations/i18n/fr.h | 3 +- radio/src/translations/i18n/he.h | 3 +- radio/src/translations/i18n/it.h | 3 +- radio/src/translations/i18n/jp.h | 3 +- radio/src/translations/i18n/ko.h | 3 +- radio/src/translations/i18n/nl.h | 3 +- radio/src/translations/i18n/pl.h | 3 +- radio/src/translations/i18n/pt.h | 3 +- radio/src/translations/i18n/ru.h | 3 +- radio/src/translations/i18n/se.h | 3 +- radio/src/translations/i18n/tw.h | 3 +- radio/src/translations/i18n/ua.h | 3 +- radio/src/translations/string_list.h | 1 + 76 files changed, 1523 insertions(+), 2792 deletions(-) delete mode 100644 radio/src/gui/128x64/menu_model.cpp delete mode 100644 radio/src/gui/128x64/model_templates.cpp delete mode 100644 radio/src/gui/212x64/menu_radio.cpp rename radio/src/gui/common/stdlcd/{features.h => feature_control.h} (100%) create mode 100644 radio/src/gui/common/stdlcd/lcd_common.cpp create mode 100644 radio/src/gui/common/stdlcd/lcd_common.h rename radio/src/gui/{212x64 => common/stdlcd}/menu_model.cpp (70%) rename radio/src/gui/{128x64 => common/stdlcd}/menu_radio.cpp (93%) delete mode 100644 radio/src/gui/common/stdlcd/menus.h rename radio/src/gui/common/stdlcd/{menus.cpp => menus_common.cpp} (100%) create mode 100644 radio/src/gui/common/stdlcd/menus_common.h rename radio/src/gui/common/stdlcd/{popups.cpp => popups_common.cpp} (99%) create mode 100644 radio/src/gui/common/stdlcd/widgets_common.cpp create mode 100644 radio/src/gui/common/stdlcd/widgets_common.h diff --git a/radio/src/edgetx.h b/radio/src/edgetx.h index c32d03259..a44fd9c53 100644 --- a/radio/src/edgetx.h +++ b/radio/src/edgetx.h @@ -244,6 +244,8 @@ inline void ALERT(const char *title, const char *msg, uint8_t sound) #else // !COLORLCD && GUI +#include "popups.h" + inline void RAISE_ALERT(const char *title, const char *msg, const char *info, uint8_t sound) { diff --git a/radio/src/gui/128x64/CMakeLists.txt b/radio/src/gui/128x64/CMakeLists.txt index 296b28ecc..f0070f908 100644 --- a/radio/src/gui/128x64/CMakeLists.txt +++ b/radio/src/gui/128x64/CMakeLists.txt @@ -6,7 +6,6 @@ set(GUI_SRC widgets.cpp startup_shutdown.cpp model_select.cpp - menu_model.cpp model_setup.cpp model_failsafe.cpp model_logical_switches.cpp @@ -14,7 +13,6 @@ set(GUI_SRC model_outputs.cpp model_telemetry.cpp model_telemetry_sensor.cpp - menu_radio.cpp radio_setup.cpp radio_calibration.cpp view_main.cpp @@ -43,6 +41,7 @@ include(gui/common/stdlcd/CMakeLists.txt) set(BOOTLOADER_SRC ${BOOTLOADER_SRC} ${RADIO_SRC_DIR}/gui/128x64/lcd.cpp + ${RADIO_SRC_DIR}/gui/common/stdlcd/lcd_common.cpp ${RADIO_SRC_DIR}/gui/common/stdlcd/fonts.cpp ${RADIO_SRC_DIR}/gui/common/stdlcd/utf8.cpp ) diff --git a/radio/src/gui/128x64/gui.h b/radio/src/gui/128x64/gui.h index d83a51af4..e95119701 100644 --- a/radio/src/gui/128x64/gui.h +++ b/radio/src/gui/128x64/gui.h @@ -23,174 +23,21 @@ #include "gui_common.h" #include "menus.h" -#include "popups.h" +#include "widgets_common.h" #include "navigation/navigation.h" -#include "common/stdlcd/draw_functions.h" +#include "draw_functions.h" #define MENUS_SCROLLBAR_WIDTH 0 -#define NUM_BODY_LINES (LCD_LINES-1) -#define TEXT_VIEWER_LINES NUM_BODY_LINES -#define MENU_HEADER_HEIGHT FH - -#define CURVE_SIDE_WIDTH (LCD_H/2-2) -#define CURVE_CENTER_X (LCD_W-CURVE_SIDE_WIDTH-3) -#define CURVE_CENTER_Y (LCD_H/2) - #define MIXES_2ND_COLUMN (10*FW) -// Temporary no highlight -extern uint8_t noHighlightCounter; -#define NO_HIGHLIGHT() (noHighlightCounter > 0) -#define START_NO_HIGHLIGHT() do { noHighlightCounter = 25; } while(0) - -void drawSlider(coord_t x, coord_t y, uint8_t width, uint8_t value, uint8_t max, uint8_t attr); -void drawSlider(coord_t x, coord_t y, uint8_t value, uint8_t max, uint8_t attr); - -void title(const char * s); - -typedef int choice_t; - -choice_t editChoice(coord_t x, coord_t y, const char *label, - const char *const *values, choice_t value, choice_t min, - choice_t max, LcdFlags attr, event_t event); -choice_t editChoice(coord_t x, coord_t y, const char *label, - const char *const *values, choice_t value, choice_t min, - choice_t max, LcdFlags attr, event_t event, coord_t lblX); -choice_t editChoice(coord_t x, coord_t y, const char *label, - const char *const *values, choice_t value, choice_t min, - choice_t max, LcdFlags attr, event_t event, coord_t lblX, - IsValueAvailable isValueAvailable); - -uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const char *label, - LcdFlags attr, event_t event); -uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const char *label, - LcdFlags attr, event_t event, coord_t lblX); - -swsrc_t editSwitch(coord_t x, coord_t y, swsrc_t value, LcdFlags attr, - event_t event); - -uint16_t editSrcVarFieldValue(coord_t x, coord_t y, const char* title, uint16_t value, - int16_t min, int16_t max, LcdFlags attr, event_t event, - IsValueAvailable isValueAvailable, int16_t sourceMin, int16_t sourceMax); - -#if defined(GVARS) - -#define GVAR_MENU_ITEM(x, y, v, min, max, attr, editflags, event) \ - editGVarFieldValue(x, y, v, min, max, attr, editflags, event) - -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); - -void drawGVarValue(coord_t x, coord_t y, uint8_t gvar, gvar_t value, - LcdFlags flags = 0); - -void editGVarValue(coord_t x, coord_t y, event_t event, uint8_t gvar, - uint8_t flightMode, LcdFlags flags); - -#define displayGVar(x, y, v, min, max) \ - GVAR_MENU_ITEM(x, y, v, min, max, 0, 0, 0) - -#else // GVARS - -int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, - int16_t max, LcdFlags attr, event_t event); - -#define GVAR_MENU_ITEM(x, y, v, min, max, attr, editflags, event) \ - editGVarFieldValue(x, y, v, min, max, attr, event) - -#define displayGVar(x, y, v, min, max) lcdDraw8bitsNumber(x, y, v) - -#endif - -void editName(coord_t x, coord_t y, char *name, uint8_t size, event_t event, - uint8_t active, LcdFlags attr, uint8_t old_editMode); - -void editSingleName(coord_t x, coord_t y, const char *label, char *name, - uint8_t size, event_t event, uint8_t active, - uint8_t old_editMode, coord_t lblX = 0); - -uint8_t editDelay(coord_t y, event_t event, uint8_t attr, const char * str, uint8_t delay, uint8_t prec); - -#define EDIT_DELAY(x, y, event, attr, str, delay, prec) editDelay(y, event, attr, str, delay, prec) - -#define COPY_MODE 1 -#define MOVE_MODE 2 - -extern uint8_t s_copyMode; -extern int8_t s_copySrcRow; -extern int8_t s_copyTgtOfs; -extern uint8_t s_currIdx; -extern uint8_t s_currIdxSubMenu; -extern mixsrc_t s_currSrcRaw; -extern uint16_t s_currScale; -extern uint8_t s_copySrcIdx; -extern uint8_t s_copySrcCh; -extern int8_t s_currCh; -extern uint8_t s_maxLines; - -#define STATUS_LINE_LENGTH 32 -extern char statusLineMsg[STATUS_LINE_LENGTH]; -void showStatusLine(); -void drawStatusLine(); - -void menuTextView(event_t event); -void pushMenuTextView(const char *filename); -void pushModelNotes(); -void readModelNotes(); - -void menuChannelsView(event_t event); -void menuChannelsViewCommon(event_t event); - -#define EDIT_MODE_INIT 0 - -extern uint8_t editNameCursorPos; - -uint8_t getExposCount(); -void insertExpo(uint8_t idx); -void deleteExpo(uint8_t idx); - -void onSwitchLongEnterPress(const char *result); -void onSourceLongEnterPress(const char *result); - -uint8_t switchToMix(uint8_t source); - -void drawCheckBox(coord_t x, coord_t y, uint8_t value, LcdFlags attr); - -extern const unsigned char sticks[] ; - -void drawSplash(); -void drawScreenIndex(uint8_t index, uint8_t count, uint8_t attr); -void drawStick(coord_t centrex, int16_t xval, int16_t yval); void drawWheel(coord_t centrex, int16_t wval); void drawThrottle(coord_t centrex, int16_t tval); -void drawPotsBars(); -void doMainScreenGraphics(); void drawProgressScreen(const char * title, const char * message, int num, int den); -void drawSleepBitmap(); - -void drawVerticalScrollbar(coord_t x, coord_t y, coord_t h, uint16_t offset, uint16_t count, uint8_t visible); -void drawGauge(coord_t x, coord_t y, coord_t w, coord_t h, int32_t val, int32_t max); - -void drawAlertBox(const char * title, const char * text, const char * action); -void showAlertBox(const char * title, const char * text, const char * action , uint8_t sound); #define SET_SCROLLBAR_X(x) #define LOAD_MODEL_BITMAP() -#define IS_MAIN_VIEW_DISPLAYED() menuHandlers[0] == menuMainView -#define IS_TELEMETRY_VIEW_DISPLAYED() menuHandlers[0] == menuViewTelemetry #define IS_OTHER_VIEW_DISPLAYED() menuHandlers[0] == menuChannelsView - -void editCurveRef(coord_t x, coord_t y, CurveRef & curve, event_t event, LcdFlags flags, - IsValueAvailable isValueAvailable, int16_t sourceMin, int16_t sourceMax); - -#if defined(FLIGHT_MODES) -void displayFlightModes(coord_t x, coord_t y, FlightModesType value); -FlightModesType editFlightModes(coord_t x, coord_t y, event_t event, FlightModesType value, uint8_t attr); -#else -#define displayFlightModes(...) -#endif diff --git a/radio/src/gui/128x64/lcd.cpp b/radio/src/gui/128x64/lcd.cpp index a67501b8c..3d4979a95 100644 --- a/radio/src/gui/128x64/lcd.cpp +++ b/radio/src/gui/128x64/lcd.cpp @@ -19,13 +19,9 @@ * GNU General Public License for more details. */ -#include -#include - #include "lcd.h" #include "bitfield.h" -#include "gui/common/stdlcd/fonts.h" -#include "gui/common/stdlcd/utf8.h" +#include "utf8.h" #if !defined(SIMU) #define assert(x) @@ -35,237 +31,9 @@ #if !defined(BOOT) #include "edgetx.h" - #include "hal/switch_driver.h" - #include "hal/adc_driver.h" - #include "switches.h" #endif -pixel_t displayBuf[DISPLAY_BUFFER_SIZE] __DMA; - -void lcdClear() -{ - memset(displayBuf, 0, DISPLAY_BUFFER_SIZE); -} - -coord_t lcdLastRightPos; -coord_t lcdNextPos; -coord_t lcdLastLeftPos; - -void lcdPutPattern(coord_t x, coord_t y, const uint8_t * pattern, uint8_t width, uint8_t height, LcdFlags flags) -{ - bool blink = false; - bool inv = false; - if (flags & BLINK) { - if (BLINK_ON_PHASE) { - if (flags & INVERS) - inv = true; - else { - blink = true; - } - } - } - else if (flags & INVERS) { - inv = true; - } - - uint8_t lines = (height+7)/8; - assert(lines <= 5); - - for (int8_t i=0; i= 0 && x < LCD_W) { - uint8_t b[5] = { 0 }; - if (i==0) { - if (x==0 || !inv) { - lcdNextPos++; - continue; - } - else { - // we need to work on the previous x when INVERS - x--; - } - } - else if (i<=width) { - uint8_t skip = true; - for (uint8_t j=0; j= 12) continue; - if (j<0 && !inv) continue; - if (y+j < 0) continue; - } - else { - uint8_t line = (j / 8); - uint8_t pixel = (j % 8); - plot = b[line] & (1 << pixel); - } - if (inv) plot = !plot; - if (!blink) { - if (flags & VERTICAL) - lcdDrawPoint(y+j, LCD_H-x, plot ? FORCE : ERASE); - else - lcdDrawPoint(x, y+j, plot ? FORCE : ERASE); - } - } - } - x++; - lcdNextPos++; - } -} - -struct PatternData -{ - uint8_t width; - uint8_t height; - const uint8_t * data; -}; - -uint8_t getPatternWidth(const PatternData * pattern) -{ - uint8_t result = 0; - uint8_t lines = (pattern->height+7)/8; - const uint8_t * data = pattern->data; - for (int8_t i=0; iwidth; i++) { - for (uint8_t j=0; j= ',' && c <= ':') - c_remapped = c - ',' + 1; - else if (c >= 'A' && c <= 'Z') - c_remapped = c - 'A' + 16; - else if (c >= 'a' && c <= 'z') - c_remapped = c - 'a' + 42; - else if (c == '_') - c_remapped = 4; - else if (c != ' ') - flags &= ~BOLD; // For BOLD use Standard font if character is not in BOLD - } - - uint8_t fontIdx = fontsize >> 8; - if (fontIdx == 0 && flags & BOLD) fontIdx = 6; - - pattern->width = fontWidth[fontIdx]; - pattern->height = fontHeight[fontIdx]; - int charSize = (pattern->height + 7) / 8 * pattern->width; - - switch (fontIdx) { - case 0: // Standard - pattern->data = &font_5x7[(c - FONT_BASE_START) * charSize]; - break; - case 1: // TINSIZE - pattern->data = &font_3x5[(c - FONT_BASE_START) * charSize]; - break; - case 2: // SMLSIZE - // Adjust language special characters offset - if (c >= FONT_LANG_START) - c = c - (FONT_SYMS_CNT - FONT_SYMS_CNT_4x6); - pattern->data = &font_4x6[(c - FONT_BASE_START) * charSize]; - break; - case 3: // MDLSIZE - // Adjust language special characters offset - if (c >= FONT_LANG_START) - c = c - FONT_SYMS_CNT; - pattern->data = &font_8x10[(c - FONT_BASE_START) * charSize]; - break; - case 4: // DBLSIZE - // Adjust language special characters offset and symbols offset - if (c >= FONT_LANG_START) - c_remapped = c - (FONT_BASE_CNT - FONT_BASE_CNT_10x14) - (FONT_SYMS_CNT - FONT_SYMS_CNT_10x14) - FONT_BASE_START; - else if (c >= FONT_SYMS_START) - c_remapped = c - (FONT_BASE_CNT - FONT_BASE_CNT_10x14) - FONT_BASE_START; - pattern->data = &font_10x14[(c_remapped) * charSize]; - break; - case 5: // XXLSIZE - pattern->data = &font_22x38_num[(c - '0' + 5) * charSize]; - break; - case 6: // BOLD - pattern->data = &font_5x7_B[c_remapped * charSize]; - break; - }; -#else - pattern->width = 5; - pattern->height = 7; - pattern->data = &font_5x7[(c - FONT_BASE_START) * 5]; -#endif - return flags; -} - -uint8_t getCharWidth(char c, LcdFlags flags) -{ - PatternData pattern; - getCharPattern(&pattern, c, flags); - return getPatternWidth(&pattern); -} - -void lcdDrawChar(coord_t x, coord_t y, uint8_t c, LcdFlags flags) -{ - lcdNextPos = x - 1; - PatternData pattern; - flags = getCharPattern(&pattern, c, flags); - lcdPutPattern(x, y, pattern.data, pattern.width, pattern.height, flags); -} - -void lcdDrawChar(coord_t x, coord_t y, uint8_t c) -{ - lcdDrawChar(x, y, c, 0); -} - -uint8_t getTextWidth(const char * s, uint8_t len, LcdFlags flags) -{ - uint8_t width = 0; - if (len == 0) len = strlen(s); - while (len--) { - unsigned char c = map_utf8_char(s, len); - if (!c) { - break; - } - width += getCharWidth(c, flags) + 1; - s++; - } - return width; -} +extern LcdFlags getCharPattern(PatternData * pattern, unsigned char c, LcdFlags flags); void lcdDrawSizedText(coord_t x, coord_t y, const char * s, uint8_t len, LcdFlags flags) { @@ -345,43 +113,7 @@ void lcdDrawSizedText(coord_t x, coord_t y, const char * s, uint8_t len, LcdFlag #endif } -void lcdDrawSizedText(coord_t x, coord_t y, const char * s, uint8_t len) -{ - lcdDrawSizedText(x, y, s, len, 0); -} - -void lcdDrawText(coord_t x, coord_t y, const char * s, LcdFlags flags) -{ - lcdDrawSizedText(x, y, s, 255, flags); -} - -void lcdDrawCenteredText(coord_t y, const char * s, LcdFlags flags) -{ - coord_t x = (LCD_W - getTextWidth(s, flags)) / 2; - lcdDrawText(x, y, s, flags); -} - -void lcdDrawText(coord_t x, coord_t y, const char * s) -{ - lcdDrawText(x, y, s, 0); -} - -void lcdDrawTextAlignedLeft(coord_t y, const char * s) -{ - lcdDrawText(0, y, s); -} - -void lcdDrawTextIndented(coord_t y, const char * s) -{ - lcdDrawText(INDENT_WIDTH, y, s); -} - #if !defined(BOOT) -void lcdDrawTextAtIndex(coord_t x, coord_t y, const char *const *s,uint8_t idx, LcdFlags flags) -{ - lcdDrawSizedText(x, y, s[idx], UINT8_MAX, flags); -} - void lcdDrawHexNumber(coord_t x, coord_t y, uint32_t val, LcdFlags flags) { x += FWNUM*4+1; @@ -393,184 +125,9 @@ void lcdDrawHexNumber(coord_t x, coord_t y, uint32_t val, LcdFlags flags) val >>= 4; } } - -void lcdDrawHexChar(coord_t x, coord_t y, uint8_t val, LcdFlags flags) -{ - x += FWNUM*2; - for (int i=0; i<2; i++) { - x -= FWNUM; - char c = val & 0xf; - c = c>9 ? c+'A'-10 : c+'0'; - lcdDrawChar(x, y, c, flags|(c>='A' ? CONDENSED : 0)); - val >>= 4; - } -} - -void lcdDraw8bitsNumber(coord_t x, coord_t y, int8_t val) -{ - lcdDrawNumber(x, y, val); -} - -void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags flags) -{ - lcdDrawNumber(x, y, val, flags, 0); -} - -void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags flags, uint8_t len) -{ - char str[16+1]; - char *s = str+16; - *s = '\0'; - int idx = 0; - int mode = MODE(flags); - bool neg = false; - - if (val == INT_MAX) { - flags &= ~(LEADING0 | PREC1 | PREC2); - lcdDrawText(x, y, "INT_MAX", flags); - return; - } - - if (val < 0) { - if (val == INT_MIN) { - flags &= ~(LEADING0 | PREC1 | PREC2); - lcdDrawText(x, y, "INT_MIN", flags); - return; - } - val = -val; - neg = true; - } - do { - *--s = '0' + (val % 10); - ++idx; - val /= 10; - if (mode!=0 && idx==mode) { - mode = 0; - *--s = '.'; - if (val==0) { - *--s = '0'; - } - } - } while (val!=0 || mode>0 || (mode==MODE(LEADING0) && idx>1; - int y = dxabs>>1; - int px = x1; - int py = y1; - - if (dxabs >= dyabs) { - /* the line is more horizontal than vertical */ - for (int i=0; i<=dxabs; i++) { - if ((1<<(px%8)) & pat) { - lcdDrawPoint(px, py, att); - } - y += dyabs; - if (y>=dxabs) { - y -= dxabs; - py += sdy; - } - px += sdx; - } - } - else { - /* the line is more vertical than horizontal */ - for (int i=0; i<=dyabs; i++) { - if ((1<<(py%8)) & pat) { - lcdDrawPoint(px, py, att); - } - x += dxabs; - if (x >= dyabs) { - x -= dyabs; - px += sdx; - } - py += sdy; - } - } -} -#endif - - -void lcdDrawVerticalLine(coord_t x, coord_t y, coord_t h, uint8_t pat, LcdFlags att) -{ - if (x < 0 || x >= LCD_W || h == 0) return; - if (h < 0) { y = y + h + 1; h = -h; } - if (y + h <= 0 || y >= LCD_H) return; - if (y < 0) { h += y; y = 0; } - if (y + h > LCD_H) { h = LCD_H - y; } - - if (pat==DOTTED && !(y%2)) - pat = ~pat; - - uint8_t * p = &displayBuf[ y / 8 * LCD_W + x ]; - y = (y & 0x07); - if (y) { - ASSERT_IN_DISPLAY(p); - uint8_t msk = ~(bfBitmask(y)); - h -= 8-y; - if (h < 0) - msk -= ~(bfBitmask(8 + h)); - lcdMaskPoint(p, msk & pat, att); - p += LCD_W; - } - while (h >= 8) { - ASSERT_IN_DISPLAY(p); - lcdMaskPoint(p, pat, att); - p += LCD_W; - h -= 8; - } - if (h > 0) { - ASSERT_IN_DISPLAY(p); - lcdMaskPoint(p, (bfBitmask(h)) & pat, att); - } -} - -void lcdDrawSolidVerticalLine(coord_t x, coord_t y, coord_t h, LcdFlags att) -{ - lcdDrawVerticalLine(x, y, h, SOLID, att); -} - -void lcdDrawRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat, LcdFlags att) -{ - lcdDrawVerticalLine(x, y, h, pat, att); - lcdDrawVerticalLine(x+w-1, y, h, pat, att); - if (~att & ROUND) { x+=1; w-=2; } - lcdDrawHorizontalLine(x, y+h-1, w, pat, att); - lcdDrawHorizontalLine(x, y, w, pat, att); -} - -#if !defined(BOOT) -void lcdDrawFilledRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat, LcdFlags att) -{ - for (coord_t i=y; i> 1) + ((pat & 1) << 7); - } -} - void drawTelemetryTopBar() { if (g_model.timers[0].mode) { @@ -593,135 +150,6 @@ void drawTelemetryTopBar() lcdInvertLine(0); } -#if defined(RTCLOCK) -void drawRtcTime(coord_t x, coord_t y, LcdFlags att) -{ - drawTimer(x, y, getValue(MIXSRC_TX_TIME), att, att); -} -#endif - -void drawTimer(coord_t x, coord_t y, int32_t tme, LcdFlags att, LcdFlags att2) -{ - div_t qr; - if (IS_RIGHT_ALIGNED(att)) { - att -= RIGHT; - if (att & DBLSIZE) - x -= 5*(2*FWNUM)-4; - else if (att & MIDSIZE) - x -= 5*8-8; - else - x -= 5*FWNUM+1; - } - - if (tme < 0) { - lcdDrawChar(x - ((att & DBLSIZE) ? FW+2 : ((att & MIDSIZE) ? FW+0 : FWNUM)), y, '-', att); - tme = -tme; - } - - qr = div((int)tme, 60); - - char separator = ':'; - if (att & TIMEHOUR) { - div_t qr2 = div(qr.quot, 60); - if (qr2.quot < 100) { - lcdDrawNumber(x, y, qr2.quot, att|LEADING0|LEFT, 2); - } - else { - lcdDrawNumber(x, y, qr2.quot, att|LEFT); - } - lcdDrawChar(lcdNextPos, y, separator, att); - qr.quot = qr2.rem; - x = lcdNextPos; - } - if (FONTSIZE(att) == MIDSIZE) { - lcdLastRightPos--; - } - if (separator == CHR_HOUR) - att &= ~DBLSIZE; - lcdDrawNumber(x, y, qr.quot, att|LEADING0|LEFT, 2); -#if defined(RTCLOCK) - if (att & TIMEBLINK) - lcdDrawChar(lcdLastRightPos, y, separator, BLINK); - else -#endif - lcdDrawChar(lcdLastRightPos, y, separator, att&att2); - lcdDrawNumber(lcdNextPos, y, qr.rem, (att2|LEADING0|LEFT) & (~RIGHT), 2); -} - -// TODO to be optimized with drawValueWithUnit -void putsVolts(coord_t x, coord_t y, uint16_t volts, LcdFlags att) -{ - lcdDrawNumber(x, y, (int16_t)volts, (~NO_UNIT) & (att | ((att&PREC2)==PREC2 ? 0 : PREC1))); - if (~att & NO_UNIT) lcdDrawChar(lcdLastRightPos, y, 'V', att); -} - -void putsVBat(coord_t x, coord_t y, LcdFlags att) -{ - putsVolts(x, y, g_vbat100mV, att); -} - -void putsChn(coord_t x, coord_t y, uint8_t idx, LcdFlags att) -{ - drawStringWithIndex(x, y, STR_CH, idx, att); -} - -void putsChnLetter(coord_t x, coord_t y, uint8_t idx, LcdFlags att) -{ - lcdDrawText(x, y, getAnalogShortLabel(idx), att); -} - -void drawModelName(coord_t x, coord_t y, char *name, uint8_t id, LcdFlags att) -{ - uint8_t len = sizeof(g_model.header.name); - while (len>0 && !name[len-1]) --len; - if (len==0) { - drawStringWithIndex(x, y, STR_MODEL, id+1, att|LEADING0); - } - else { - lcdDrawSizedText(x, y, name, sizeof(g_model.header.name), att); - } -} - -void drawSwitch(coord_t x, coord_t y, swsrc_t idx, LcdFlags flags, bool autoBold) -{ - char s[8]; - getSwitchPositionName(s, idx); - if (autoBold && idx != SWSRC_NONE && getSwitch(idx)) - flags |= BOLD; - lcdDrawText(x, y, s, flags); -} - -void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags att) -{ - char s[8]; - getCurveString(s, idx); - lcdDrawText(x, y, s, att); -} - -void drawTimerMode(coord_t x, coord_t y, swsrc_t mode, LcdFlags att) -{ - if (mode >= 0) { - if (mode < TMRMODE_COUNT) - return lcdDrawTextAtIndex(x, y, STR_VTMRMODES, mode, att); - else - mode -= (TMRMODE_COUNT-1); - } - drawSwitch(x, y, mode, att); -} - -void drawShortTrimMode(coord_t x, coord_t y, uint8_t fm, uint8_t idx, LcdFlags att) -{ - trim_t v = getRawTrimValue(fm, idx); - uint8_t mode = v.mode; - uint8_t p = v.mode >> 1; - if (mode == TRIM_MODE_NONE) { - putsChnLetter(x, y, idx, att); - } - else { - lcdDrawChar(x, y, '0' + p, att); - } -} - void drawGPSCoord(coord_t x, coord_t y, int32_t value, const char * direction, LcdFlags att, bool seconds=true) { att &= ~RIGHT & ~BOLD; @@ -848,10 +276,6 @@ void drawGPSSensorValue(coord_t x, coord_t y, TelemetryItem & telemetryItem, Lcd drawGPSPosition(x, y, telemetryItem.gps.longitude, telemetryItem.gps.latitude, flags); } - -#define LCD_BYTE_FILTER(p, keep, add) *(p) = (*(p) & (keep)) | (add) - - void lcdDraw1bitBitmap(coord_t x, coord_t y, const uint8_t * img, uint8_t idx, LcdFlags att) { const uint8_t * q = img; @@ -958,4 +382,36 @@ void lcdDrawHorizontalLine(coord_t x, coord_t y, coord_t w, uint8_t pat, LcdFlag } } -void lcdFlushed() {} +void lcdDrawVerticalLine(coord_t x, coord_t y, coord_t h, uint8_t pat, LcdFlags att) +{ + if (x < 0 || x >= LCD_W || h == 0) return; + if (h < 0) { y = y + h + 1; h = -h; } + if (y + h <= 0 || y >= LCD_H) return; + if (y < 0) { h += y; y = 0; } + if (y + h > LCD_H) { h = LCD_H - y; } + + if (pat==DOTTED && !(y%2)) + pat = ~pat; + + uint8_t * p = &displayBuf[ y / 8 * LCD_W + x ]; + y = (y & 0x07); + if (y) { + ASSERT_IN_DISPLAY(p); + uint8_t msk = ~(bfBitmask(y)); + h -= 8-y; + if (h < 0) + msk -= ~(bfBitmask(8 + h)); + lcdMaskPoint(p, msk & pat, att); + p += LCD_W; + } + while (h >= 8) { + ASSERT_IN_DISPLAY(p); + lcdMaskPoint(p, pat, att); + p += LCD_W; + h -= 8; + } + if (h > 0) { + ASSERT_IN_DISPLAY(p); + lcdMaskPoint(p, (bfBitmask(h)) & pat, att); + } +} diff --git a/radio/src/gui/128x64/lcd.h b/radio/src/gui/128x64/lcd.h index 0a721f45c..bf1a6a3fd 100644 --- a/radio/src/gui/128x64/lcd.h +++ b/radio/src/gui/128x64/lcd.h @@ -26,142 +26,18 @@ #include "edgetx_types.h" #include "board.h" -#define BOX_WIDTH 23 -#define CENTER_OFS 0 -#define OFS_CHECKTRIMS CENTER_OFS+(9*FW) -#define INDENT_WIDTH (FW/2) +constexpr coord_t BOX_WIDTH = 23; +constexpr coord_t BOX_CENTERY = LCD_H - BOX_WIDTH/2 - 9; +constexpr coord_t MARKER_WIDTH = 5; +#define CENTER_OFS 0 -#define FW 6 -#define FWNUM 5 -#define FH 8 +#define BITMAP_BUFFER_SIZE(w, h) (2 + (w) * (((h)+7)/8)) +#define DISPLAY_BUFFER_SIZE (LCD_W*((LCD_H+7)/8)) -#define LCD_LINES (LCD_H/FH) -#define LCD_COLS (LCD_W/FW) +#include "lcd_common.h" -#define BITMAP_BUFFER_SIZE(w, h) (2 + (w) * (((h)+7)/8)) - -/* lcdDrawText flags */ -#define BLINK 0x01 -#define INVERS 0x02 -#define BOLD 0x40 -#define LEFT 0x00 /* fake */ -#define RIGHT 0x04 /* align right */ -#define CENTERED 0x20 -#define CONDENSED 0x08 -#define FIXEDWIDTH 0x10 -/* no 0x80 here because of "GV"1 which is aligned LEFT */ -/* no 0x10 here because of "MODEL"01 which uses LEADING0 */ - -/* lcdDrawNumber additional flags */ -#define LEADING0 0x10 -#define PREC1 0x20 -#define PREC2 0x30 -#define MODE(flags) ((((int8_t)(flags) & 0x30) - 0x10) >> 4) - -#define IS_LEFT_ALIGNED(att) !((att) & RIGHT) -#define IS_RIGHT_ALIGNED(att) (!IS_LEFT_ALIGNED(att)) - -/* line, rect, square flags */ -#define FORCE 0x02 -#define ERASE 0x04 -#define ROUND 0x08 - -/* telemetry flags */ -#define NO_UNIT 0x40 - -#define FONTSIZE_MASK 0x0700 -#define FONTSIZE(x) ((x) & FONTSIZE_MASK) -#define TINSIZE 0x0100 -#define SMLSIZE 0x0200 -#define MIDSIZE 0x0300 -#define DBLSIZE 0x0400 -#define XXLSIZE 0x0500 -#define ERASEBG 0x8000 -#define VERTICAL 0x0800 - -#define TIMEBLINK 0x1000 -#define TIMEHOUR 0x2000 -#define STREXPANDED 0x4000 - -#define DISPLAY_BUFFER_SIZE (LCD_W*((LCD_H+7)/8)) - -extern pixel_t displayBuf[DISPLAY_BUFFER_SIZE]; -extern coord_t lcdLastRightPos; -extern coord_t lcdLastLeftPos; -extern coord_t lcdNextPos; - -#define DISPLAY_END (displayBuf + DISPLAY_BUFFER_SIZE) -#define IS_IN_DISPLAY(p) ((p) >= displayBuf && (p) < DISPLAY_END) -#define ASSERT_IN_DISPLAY(p) assert((p) >= displayBuf && (p) < DISPLAY_END) - -void lcdDrawChar(coord_t x, coord_t y, uint8_t c); -void lcdDrawChar(coord_t x, coord_t y, uint8_t c, LcdFlags flags); -void lcdDrawCenteredText(coord_t y, const char * s, LcdFlags flags = 0); -void lcdDrawText(coord_t x, coord_t y, const char * s, LcdFlags flags); -void lcdDrawTextAtIndex(coord_t x, coord_t y, const char *const *s, uint8_t idx, LcdFlags flags); -void lcdDrawSizedText(coord_t x, coord_t y, const char * s, unsigned char len, LcdFlags flags); -void lcdDrawText(coord_t x, coord_t y, const char * s); -void lcdDrawSizedText(coord_t x, coord_t y, const char * s, unsigned char len); -void lcdDrawTextAlignedLeft(coord_t y, const char * s); -void lcdDrawTextIndented(coord_t y, const char * s); void drawTimerWithMode(coord_t x, coord_t y, uint8_t index, LcdFlags att); -void lcdDrawHexNumber(coord_t x, coord_t y, uint32_t val, LcdFlags mode=0); -void lcdDrawHexChar(coord_t x, coord_t y, uint8_t val, LcdFlags flags=0); - -void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags mode, uint8_t len); -void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags mode=0); -void lcdDraw8bitsNumber(coord_t x, coord_t y, int8_t val); - -void drawModelName(coord_t x, coord_t y, char * name, uint8_t id, LcdFlags att); -#if !defined(BOOT) // TODO not here ... -void drawSwitch(coord_t x, coord_t y, swsrc_t swtch, LcdFlags att=0, bool autoBold = true); -#endif -void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags att=0); -void drawTimerMode(coord_t x, coord_t y, swsrc_t mode, LcdFlags att=0); - -void drawShortTrimMode(coord_t x, coord_t y, uint8_t mode, uint8_t idx, LcdFlags att); - -void putsChn(coord_t x, coord_t y, uint8_t idx, LcdFlags attr); -void putsChnLetter(coord_t x, coord_t y, uint8_t idx, LcdFlags attr); - -void putsVolts(coord_t x, coord_t y, uint16_t volts, LcdFlags att); -void putsVBat(coord_t x, coord_t y, LcdFlags att); - -#define SOLID 0xff -#define DOTTED 0x55 - -void lcdDrawPoint(coord_t x, coord_t y, LcdFlags att=0); -void lcdMaskPoint(uint8_t *p, uint8_t mask, LcdFlags att=0); -void lcdDrawSolidHorizontalLine(coord_t x, coord_t y, coord_t w, LcdFlags att=0); -void lcdDrawHorizontalLine(coord_t x, coord_t y, coord_t w, uint8_t pat, LcdFlags att=0); -void lcdDrawSolidVerticalLine(coord_t x, coord_t y, coord_t h, LcdFlags att=0); -void lcdDrawVerticalLine(coord_t x, coord_t y, coord_t h, uint8_t pat, LcdFlags att=0); -void lcdDrawLine(coord_t x1, coord_t y1, coord_t x2, coord_t y2, uint8_t pat=SOLID, LcdFlags att=0); -void lcdDrawFilledRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat=SOLID, LcdFlags att=0); -inline void lcdDrawSolidFilledRect(coord_t x, coord_t y, coord_t w, coord_t h, LcdFlags att=0) -{ - lcdDrawFilledRect(x, y, w, h, SOLID, att); -} -void lcdDrawRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat=SOLID, LcdFlags att=0); - -void lcdInvertLine(int8_t line); -#define lcdInvertLastLine() lcdInvertLine(LCD_LINES-1) -inline void lcdDrawSquare(coord_t x, coord_t y, coord_t w, LcdFlags att=0) -{ - lcdDrawRect(x, y, w, w, SOLID, att); -} - -void drawTelemetryTopBar(); - -#define V_BAR(xx, yy, ll) \ - lcdDrawSolidVerticalLine(xx-1,yy-ll,ll); \ - lcdDrawSolidVerticalLine(xx ,yy-ll,ll); \ - lcdDrawSolidVerticalLine(xx+1,yy-ll,ll) - - -void lcdClear(); -void lcdDraw1bitBitmap(coord_t x, coord_t y, const unsigned char * img, uint8_t idx, LcdFlags att=0); inline void lcdDrawBitmap(coord_t x, coord_t y, const uint8_t * bitmap) { lcdDraw1bitBitmap(x, y, bitmap, 0); @@ -169,14 +45,6 @@ inline void lcdDrawBitmap(coord_t x, coord_t y, const uint8_t * bitmap) uint8_t * lcdLoadBitmap(uint8_t * dest, const char * filename, uint8_t width, uint8_t height); -#if defined(BOOT) - #define BLINK_ON_PHASE (0) -#else - #define SLOW_BLINK_ON_PHASE (g_blinkTmr10ms & (1<<7)) - #define BLINK_ON_PHASE (g_blinkTmr10ms & (1<<6)) - #define FAST_BLINK_ON_PHASE (g_blinkTmr10ms & (1<<4)) -#endif - inline pixel_t getPixel(uint8_t x, uint8_t y) { if (x>=LCD_W || y>=LCD_H) { @@ -187,5 +55,3 @@ inline pixel_t getPixel(uint8_t x, uint8_t y) pixel_t mask = 1 << (y & 7); return ((pixel & mask) ? 0xf : 0); } - -uint8_t getTextWidth(const char * s, uint8_t len=0, LcdFlags flags=0); diff --git a/radio/src/gui/128x64/menu_model.cpp b/radio/src/gui/128x64/menu_model.cpp deleted file mode 100644 index 0cd77c52a..000000000 --- a/radio/src/gui/128x64/menu_model.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) EdgeTX - * - * Based on code named - * opentx - https://github.com/opentx/opentx - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "edgetx.h" - -const MenuHandler menuTabModel[MENU_MODEL_PAGES_COUNT] = { - { menuModelSelect, nullptr }, - { menuModelSetup, nullptr }, -#if defined(HELI) - { menuModelHeli, modelHeliEnabled }, -#endif -#if defined(FLIGHT_MODES) - { menuModelFlightModesAll, modelFMEnabled }, -#endif - { menuModelExposAll, nullptr }, - { menuModelMixAll, nullptr }, - { menuModelLimits, nullptr }, - { menuModelCurvesAll, modelCurvesEnabled }, - { menuModelLogicalSwitches, modelLSEnabled }, - { menuModelSpecialFunctions, modelSFEnabled }, -#if defined(LUA_MODEL_SCRIPTS) - { menuModelCustomScripts, modelCustomScriptsEnabled }, -#endif - { menuModelTelemetry, modelTelemetryEnabled }, - { menuModelDisplay, nullptr } -}; - -uint8_t editDelay(coord_t y, event_t event, uint8_t attr, const char * str, uint8_t delay, uint8_t prec) -{ - lcdDrawTextAlignedLeft(y, str); - lcdDrawNumber(MIXES_2ND_COLUMN, y, delay, attr|prec|LEFT); - if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, delay, DELAY_MAX); - return delay; -} - -uint8_t s_copyMode = 0; -int8_t s_copySrcRow; -int8_t s_copyTgtOfs; -uint8_t s_maxLines = 8; -uint8_t s_copySrcIdx; -uint8_t s_copySrcCh; - -uint8_t editNameCursorPos = 0; - -void editSingleName(coord_t x, coord_t y, const char* label, char* name, - uint8_t size, event_t event, uint8_t active, - uint8_t old_editMode, coord_t lblX) -{ - lcdDrawText(lblX, y, label); - editName(x, y, name, size, event, active, 0, old_editMode); -} - -uint8_t s_currIdx; -uint8_t s_currIdxSubMenu; -mixsrc_t s_currSrcRaw; -uint16_t s_currScale; diff --git a/radio/src/gui/128x64/menus.h b/radio/src/gui/128x64/menus.h index 27e5c526b..d4407125a 100644 --- a/radio/src/gui/128x64/menus.h +++ b/radio/src/gui/128x64/menus.h @@ -21,125 +21,6 @@ #pragma once -#include "keys.h" -#include "common/stdlcd/menus.h" -#include "common/stdlcd/features.h" +#include "menus_common.h" -#if defined(PCBTARANIS) -#define NAVIGATION_LINE_BY_LINE 0x40 -#define IS_LINE_SELECTED(sub, k) ((sub)==(k) && menuHorizontalPosition < 0) -#else -#define NAVIGATION_LINE_BY_LINE 0 -#define IS_LINE_SELECTED(sub, k) (false) -#endif - -inline bool isRadioMenuDisplayed() -{ - return menuVerticalPositions[0] == 1; -} - -inline bool isModelMenuDisplayed() -{ - return menuVerticalPositions[0] == 0; -} - -void onMainViewMenu(const char * result); -void menuFirstCalib(event_t event); -void menuMainView(event_t event); -void menuViewTelemetry(event_t event); -void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomFunctionsContext * functionsContext); - -enum MenuRadioIndexes -{ -#if defined(RADIO_TOOLS) - MENU_RADIO_TOOLS, -#endif - MENU_RADIO_SD_MANAGER, - MENU_RADIO_SETUP, - MENU_RADIO_SPECIAL_FUNCTIONS, - MENU_RADIO_TRAINER, - MENU_RADIO_HARDWARE, - MENU_RADIO_VERSION, - MENU_RADIO_PAGES_COUNT -}; - -void menuRadioSetup(event_t event); -void menuRadioSdManager(event_t event); -void menuRadioSpecialFunctions(event_t event); -void menuRadioTrainer(event_t event); -void menuRadioVersion(event_t event); -void menuRadioDiagKeys(event_t event); -void menuRadioDiagAnalogs(event_t event); -void menuRadioDiagFS(event_t event); -void menuRadioHardware(event_t event); -void menuRadioTools(event_t event); -void menuRadioSpectrumAnalyser(event_t event); -void menuRadioPowerMeter(event_t event); -void menuRadioCalibration(event_t event); -void menuGhostModuleConfig(event_t event); - -extern bool radioGFEnabled(); -extern bool radioTrainerEnabled(); - -extern const MenuHandler menuTabGeneral[MENU_RADIO_PAGES_COUNT]; - -enum MenuModelIndexes { - MENU_MODEL_SELECT, - MENU_MODEL_SETUP, - CASE_HELI(MENU_MODEL_HELI) - CASE_FLIGHT_MODES(MENU_MODEL_FLIGHT_MODES) - MENU_MODEL_INPUTS, - MENU_MODEL_MIXES, - MENU_MODEL_OUTPUTS, - MENU_MODEL_CURVES, - MENU_MODEL_LOGICAL_SWITCHES, - MENU_MODEL_SPECIAL_FUNCTIONS, -#if defined(LUA_MODEL_SCRIPTS) - MENU_MODEL_CUSTOM_SCRIPTS, -#endif - MENU_MODEL_TELEMETRY, - MENU_MODEL_DISPLAY, - MENU_MODEL_PAGES_COUNT -}; - -void menuModelSelect(event_t event); -void menuModelSetup(event_t event); -void menuModelFailsafe(event_t event); -void menuModelModuleOptions(event_t event); -void menuModelReceiverOptions(event_t event); -void menuModelHeli(event_t event); -void menuModelFlightModesAll(event_t event); -void menuModelExpoOne(event_t event); -void menuModelExposAll(event_t event); -void menuModelMixOne(event_t event); -void menuModelMixAll(event_t event); -void menuModelLimits(event_t event); -void menuModelCurvesAll(event_t event); -void menuModelCurveOne(event_t event); -void menuModelGVars(event_t event); -void menuModelLogicalSwitches(event_t event); -void menuModelSpecialFunctions(event_t event); -void menuModelCustomScripts(event_t event); -void menuModelTelemetry(event_t event); -void menuModelSensor(event_t event); -void menuModelDisplay(event_t event); -void menuModelTemplates(event_t event); void menuModelGVarOne(event_t event); -#if defined(USBJ_EX) -void menuModelUSBJoystick(event_t event); -#endif - -extern bool modelHeliEnabled(); -extern bool modelFMEnabled(); -extern bool modelCurvesEnabled(); -extern bool modelLSEnabled(); -extern bool modelSFEnabled(); -extern bool modelCustomScriptsEnabled(); -extern bool modelTelemetryEnabled(); - -extern const MenuHandler menuTabModel[MENU_MODEL_PAGES_COUNT]; - -void menuStatisticsView(event_t event); -void menuStatisticsDebug(event_t event); -void menuStatisticsDebug2(event_t event); -void menuAboutView(event_t event); diff --git a/radio/src/gui/128x64/model_gvars.cpp b/radio/src/gui/128x64/model_gvars.cpp index 1ba07f29f..a7d99e28f 100644 --- a/radio/src/gui/128x64/model_gvars.cpp +++ b/radio/src/gui/128x64/model_gvars.cpp @@ -21,36 +21,6 @@ #include "edgetx.h" -void editGVarValue(coord_t x, coord_t y, event_t event, uint8_t gvar, uint8_t flightMode, LcdFlags flags) -{ - FlightModeData * fm = &g_model.flightModeData[flightMode]; - gvar_t * v = &fm->gvars[gvar]; - int16_t vmin, vmax; - if (*v > GVAR_MAX) { - uint8_t fm = *v - GVAR_MAX - 1; - if (fm >= flightMode) fm++; - drawFlightMode(x, y, fm + 1, flags&(~LEFT)); - vmin = GVAR_MAX + 1; - vmax = GVAR_MAX + MAX_FLIGHT_MODES - 1; - } - else { - drawGVarValue(x, y, gvar, *v, flags); - vmin = GVAR_MIN + g_model.gvars[gvar].min; - vmax = GVAR_MAX - g_model.gvars[gvar].max; - } - - if (flags & INVERS) { - if (event == EVT_KEY_LONG(KEY_ENTER) && flightMode > 0) { - killEvents(event); - *v = (*v > GVAR_MAX ? 0 : GVAR_MAX+1); - storageDirty(EE_MODEL); - } - else if (s_editMode > 0) { - *v = checkIncDec(event, *v, vmin, vmax, EE_MODEL); - } - } -} - enum GVarFields { GVAR_FIELD_NAME, GVAR_FIELD_UNIT, diff --git a/radio/src/gui/128x64/model_logical_switches.cpp b/radio/src/gui/128x64/model_logical_switches.cpp index 6f5a5a437..fe33e436c 100644 --- a/radio/src/gui/128x64/model_logical_switches.cpp +++ b/radio/src/gui/128x64/model_logical_switches.cpp @@ -206,25 +206,11 @@ void menuModelLogicalSwitchOne(event_t event) break; case LS_FIELD_DURATION: - lcdDrawTextAlignedLeft(y, STR_DURATION); - if (cs->duration > 0) - lcdDrawNumber(CSWONE_2ND_COLUMN, y, cs->duration, attr|PREC1|LEFT); - else - lcdDrawMMM(CSWONE_2ND_COLUMN, y, attr); - if (attr) { - CHECK_INCDEC_MODELVAR_ZERO(event, cs->duration, MAX_LS_DURATION); - } + cs->duration = editNumberField(STR_DURATION, 0, CSWONE_2ND_COLUMN, y, cs->duration, 0, MAX_LS_DURATION, attr|PREC1, event, STR_MMMINV[0]); break; case LS_FIELD_DELAY: - lcdDrawTextAlignedLeft(y, STR_DELAY); - if (cs->delay > 0) - lcdDrawNumber(CSWONE_2ND_COLUMN, y, cs->delay, attr|PREC1|LEFT); - else - lcdDrawMMM(CSWONE_2ND_COLUMN, y, attr); - if (attr) { - CHECK_INCDEC_MODELVAR_ZERO(event, cs->delay, MAX_LS_DELAY); - } + cs->delay = editNumberField(STR_DELAY, 0, CSWONE_2ND_COLUMN, y, cs->delay, 0, MAX_LS_DELAY, attr|PREC1, event, STR_MMMINV[0]); break; case LS_FIELD_PERSIST: diff --git a/radio/src/gui/128x64/model_mix_edit.cpp b/radio/src/gui/128x64/model_mix_edit.cpp index 83764d9a9..ab664112c 100644 --- a/radio/src/gui/128x64/model_mix_edit.cpp +++ b/radio/src/gui/128x64/model_mix_edit.cpp @@ -172,12 +172,7 @@ void menuModelMixOne(event_t event) break; case MIX_FIELD_WARNING: - lcdDrawTextAlignedLeft(y, STR_MIXWARNING); - if (md2->mixWarn) - lcdDrawNumber(MIXES_2ND_COLUMN, y, md2->mixWarn, attr|LEFT); - else - lcdDrawText(MIXES_2ND_COLUMN, y, STR_OFF, attr); - if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, md2->mixWarn, 3); + md2->mixWarn = editNumberField(STR_MIXWARNING, 0, MIXES_2ND_COLUMN, y, md2->mixWarn, 0, 3, attr, event, STR_OFF); break; case MIX_FIELD_MLTPX: @@ -189,11 +184,11 @@ void menuModelMixOne(event_t event) break; case MIX_FIELD_DELAY_UP: - md2->delayUp = EDIT_DELAY(0, y, event, attr, STR_DELAYUP, md2->delayUp, (md2->delayPrec ? PREC2 : PREC1)); + md2->delayUp = editDelay(y, event, attr, STR_DELAYUP, md2->delayUp, (md2->delayPrec ? PREC2 : PREC1)); break; case MIX_FIELD_DELAY_DOWN: - md2->delayDown = EDIT_DELAY(0, y, event, attr, STR_DELAYDOWN, md2->delayDown, (md2->delayPrec ? PREC2 : PREC1)); + md2->delayDown = editDelay(y, event, attr, STR_DELAYDOWN, md2->delayDown, (md2->delayPrec ? PREC2 : PREC1)); break; case MIX_FIELD_SLOW_PREC: @@ -201,11 +196,11 @@ void menuModelMixOne(event_t event) break; case MIX_FIELD_SLOW_UP: - md2->speedUp = EDIT_DELAY(0, y, event, attr, STR_SLOWUP, md2->speedUp, (md2->speedPrec ? PREC2 : PREC1)); + md2->speedUp = editDelay(y, event, attr, STR_SLOWUP, md2->speedUp, (md2->speedPrec ? PREC2 : PREC1)); break; case MIX_FIELD_SLOW_DOWN: - md2->speedDown = EDIT_DELAY(0, y, event, attr, STR_SLOWDOWN, md2->speedDown, (md2->speedPrec ? PREC2 : PREC1)); + md2->speedDown = editDelay(y, event, attr, STR_SLOWDOWN, md2->speedDown, (md2->speedPrec ? PREC2 : PREC1)); break; } y += FH; diff --git a/radio/src/gui/128x64/model_outputs.cpp b/radio/src/gui/128x64/model_outputs.cpp index 467353f18..7f1b2b461 100644 --- a/radio/src/gui/128x64/model_outputs.cpp +++ b/radio/src/gui/128x64/model_outputs.cpp @@ -164,11 +164,8 @@ void menuModelLimitsOne(event_t event) #if defined(PPM_CENTER_ADJUSTABLE) case ITEM_OUTPUTONE_PPM_CENTER: - lcdDrawTextAlignedLeft(y, STR_LIMITS_HEADERS_PPMCENTER); - lcdDrawNumber(LIMITS_ONE_2ND_COLUMN, y, PPM_CENTER+ld->ppmCenter, attr); - if (active) { - CHECK_INCDEC_MODELVAR(event, ld->ppmCenter, -PPM_CENTER_MAX, +PPM_CENTER_MAX); - } + ld->ppmCenter = editNumberField(STR_LIMITS_HEADERS_PPMCENTER, 0, LIMITS_ONE_2ND_COLUMN, y, ld->ppmCenter, + -PPM_CENTER_MAX, PPM_CENTER_MAX, attr, event, nullptr, PPM_CENTER); break; #endif diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index 9b118c484..b9e3f2fb9 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -492,13 +492,13 @@ void editTimerCountdown(int timerIdx, coord_t y, LcdFlags attr, event_t event) } } -#include "common/stdlcd/model_setup_pxx1.cpp" +#include "model_setup_pxx1.cpp" #if defined(PXX2) -#include "common/stdlcd/model_setup_pxx2.cpp" +#include "model_setup_pxx2.cpp" #endif #if defined(AFHDS3) -#include "common/stdlcd/model_setup_afhds3.cpp" +#include "model_setup_afhds3.cpp" #endif #if defined(HARDWARE_INTERNAL_MODULE) @@ -1217,13 +1217,8 @@ void menuModelSetup(event_t event) break; case ITEM_MODEL_SETUP_CUSTOM_THROTTLE_WARNING_VALUE: - { - lcdDrawText(INDENT_WIDTH * 4, y, STR_CUSTOM_THROTTLE_WARNING_VAL); - lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, g_model.customThrottleWarningPosition, attr | LEFT, 2); - if (attr) { - CHECK_INCDEC_MODELVAR(event, g_model.customThrottleWarningPosition, -100, 100); - } - } + g_model.customThrottleWarningPosition = editNumberField(STR_CUSTOM_THROTTLE_WARNING_VAL, INDENT_WIDTH * 4, MODEL_SETUP_2ND_COLUMN, y, + g_model.customThrottleWarningPosition, -100, 100, attr, event); break; case ITEM_MODEL_SETUP_SWITCHES_WARNING2: @@ -1754,7 +1749,7 @@ void menuModelSetup(event_t event) } if (bluetooth.distantAddr[0]) { lcdDrawText(INDENT_WIDTH, y+1, bluetooth.distantAddr, TINSIZE); - lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_CLEAR, attr); + lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_CLEAR_BTN, attr); if (attr && event == EVT_KEY_BREAK(KEY_ENTER)) { bluetooth.state = BLUETOOTH_STATE_CLEAR_REQUESTED; memclear(bluetooth.distantAddr, sizeof(bluetooth.distantAddr)); @@ -1896,17 +1891,11 @@ void menuModelSetup(event_t event) #if defined(HARDWARE_EXTERNAL_MODULE) case ITEM_MODEL_SETUP_EXTERNAL_MODULE_PXX2_MODEL_NUM: #endif - { - lcdDrawTextIndented(y, STR_RECEIVER_NUM); - lcdDrawNumber(MODEL_SETUP_2ND_COLUMN, y, g_model.header.modelId[moduleIdx], attr | LEADING0 | LEFT, 2); - if (attr) { - CHECK_INCDEC_MODELVAR_ZERO(event, g_model.header.modelId[moduleIdx], getMaxRxNum(moduleIdx)); - if (checkIncDec_Ret) { + g_model.header.modelId[moduleIdx] = editNumberField(STR_RECEIVER_NUM, INDENT_WIDTH, MODEL_SETUP_2ND_COLUMN, y, + g_model.header.modelId[moduleIdx], 0, getMaxRxNum(moduleIdx), attr|LEADING0, event); + if (attr && checkIncDec_Ret) modelHeaders[g_eeGeneral.currModel].modelId[moduleIdx] = g_model.header.modelId[moduleIdx]; - } - } - } - break; + break; case ITEM_MODEL_SETUP_INTERNAL_MODULE_PXX2_REGISTER_RANGE: #if defined(HARDWARE_EXTERNAL_MODULE) diff --git a/radio/src/gui/128x64/model_telemetry.cpp b/radio/src/gui/128x64/model_telemetry.cpp index f529c28c8..476f706b8 100644 --- a/radio/src/gui/128x64/model_telemetry.cpp +++ b/radio/src/gui/128x64/model_telemetry.cpp @@ -239,19 +239,12 @@ void menuModelTelemetry(event_t event) break; case ITEM_TELEMETRY_RSSI_ALARM1: + g_model.rfAlarms.warning = editNumberField(STR_LOWALARM, INDENT_WIDTH, TELEM_COL3, y, g_model.rfAlarms.warning, 0, 100, attr, event); + break; + case ITEM_TELEMETRY_RSSI_ALARM2: - { - bool warning = (k==ITEM_TELEMETRY_RSSI_ALARM1); - lcdDrawTextIndented(y, (warning ? STR_LOWALARM : STR_CRITICALALARM)); - lcdDrawNumber(TELEM_COL3, y, warning? g_model.rfAlarms.warning : g_model.rfAlarms.critical, attr, 3); - if (attr && s_editMode>0) { - if (warning) - CHECK_INCDEC_MODELVAR(event, g_model.rfAlarms.warning, 0, 100); - else - CHECK_INCDEC_MODELVAR(event, g_model.rfAlarms.critical, 0, 100); - } + g_model.rfAlarms.critical = editNumberField(STR_CRITICALALARM, INDENT_WIDTH, TELEM_COL3, y, g_model.rfAlarms.critical, 0, 100, attr, event); break; - } case ITEM_TELEMETRY_DISABLE_ALARMS: g_model.disableTelemetryWarning = editCheckBox(g_model.disableTelemetryWarning, TELEM_COL3, y, STR_DISABLE_ALARM, attr, event, INDENT_WIDTH); diff --git a/radio/src/gui/128x64/model_telemetry_sensor.cpp b/radio/src/gui/128x64/model_telemetry_sensor.cpp index 180e0ed48..54642c098 100644 --- a/radio/src/gui/128x64/model_telemetry_sensor.cpp +++ b/radio/src/gui/128x64/model_telemetry_sensor.cpp @@ -212,9 +212,7 @@ void menuModelSensor(event_t event) } else { if (sensor->unit == UNIT_RPMS) { - lcdDrawTextAlignedLeft(y, STR_BLADES); - if (attr) CHECK_INCDEC_MODELVAR(event, sensor->custom.ratio, 1, 30000); - lcdDrawNumber(SENSOR_2ND_COLUMN, y, sensor->custom.ratio, LEFT|attr); + sensor->custom.ratio = editNumberField(STR_BLADES, 0, SENSOR_2ND_COLUMN, y, sensor->custom.ratio, 1, 30000, attr, event); break; } else { @@ -288,10 +286,8 @@ void menuModelSensor(event_t event) break; } else { - lcdDrawTextAlignedLeft(y, STR_OFFSET); - if (attr) CHECK_INCDEC_MODELVAR(event, sensor->custom.offset, -30000, +30000); if (sensor->prec > 0) attr |= (sensor->prec == 2 ? PREC2 : PREC1); - lcdDrawNumber(SENSOR_2ND_COLUMN, y, sensor->custom.offset, LEFT|attr); + sensor->custom.offset = editNumberField(STR_OFFSET, 0, SENSOR_2ND_COLUMN, y, sensor->custom.offset, -30000, 30000, attr, event); break; } // no break diff --git a/radio/src/gui/128x64/model_templates.cpp b/radio/src/gui/128x64/model_templates.cpp deleted file mode 100644 index 36587fbbd..000000000 --- a/radio/src/gui/128x64/model_templates.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) EdgeTX - * - * Based on code named - * opentx - https://github.com/opentx/opentx - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "edgetx.h" - -void menuModelTemplates(event_t event) -{ - SIMPLE_MENU(STR_MENUTEMPLATES, menuTabModel, MENU_MODEL_TEMPLATES, 1+TMPL_COUNT); - - uint8_t sub = menuVerticalPosition - 1; - - if (sub < TMPL_COUNT) { - if (warningResult) { - warningResult = 0; - applyTemplate(sub); - AUDIO_WARNING2(); - } - if (event==EVT_KEY_BREAK(KEY_ENTER)) { - POPUP_CONFIRMATION(STR_VTEMPLATES+1 + (sub * LEN2_VTEMPLATES), nullptr); - s_editMode = 0; - } - } - - coord_t y = MENU_HEADER_HEIGHT + 1; - uint8_t k = 0; - for (uint8_t i=0; i9 ? 3 : 2); - lcdDrawChar(x, 0, '/', attr); - lcdDrawNumber(x, 0, index+1, RIGHT | attr); -} - -void drawVerticalScrollbar(coord_t x, coord_t y, coord_t h, uint16_t offset, uint16_t count, uint8_t visible) -{ - lcdDrawVerticalLine(x, y, h, DOTTED); - coord_t yofs = (h * offset) / count; - coord_t yhgt = (h * visible) / count; - if (yhgt + yofs > h) - yhgt = h - yofs; - lcdDrawVerticalLine(x, y + yofs, yhgt, SOLID, FORCE); -} - -void drawGauge(coord_t x, coord_t y, coord_t w, coord_t h, int32_t val, int32_t max) -{ -#if defined(PCBX7) || defined(PCBX9LITE) || defined(PCBX9LITES) // X7/X9 LCD doesn't like too many horizontal lines - h++; -#else - lcdDrawRect(x, y, w+1, h); -#endif - lcdDrawFilledRect(x+1, y+1, w-1, 4, SOLID, ERASE); - coord_t len = limit((uint8_t)1, uint8_t((abs(val) * w/2 + max/2) / max), uint8_t(w/2)); - coord_t x0 = (val>0) ? x+w/2 : x+1+w/2-len; - for (coord_t i=h-2; i>0; i--) { - lcdDrawSolidHorizontalLine(x0, y+i, len); - } -} - -void title(const char * s) -{ - lcdDrawText(0, 0, s, INVERS); -} - -choice_t editChoice(coord_t x, coord_t y, const char * label, const char *const *values, choice_t value, choice_t min, choice_t max, LcdFlags attr, event_t event, coord_t lblX, IsValueAvailable isValueAvailable) -{ - if (label) { - lcdDrawText(lblX, y, label); - } - if (values) lcdDrawTextAtIndex(x, y, values, value-min, attr); - if (attr & (~RIGHT)) value = checkIncDec(event, value, min, max, (isModelMenuDisplayed()) ? EE_MODEL : EE_GENERAL, isValueAvailable); - return value; -} - -choice_t editChoice(coord_t x, coord_t y, const char * label, const char *const *values, choice_t value, choice_t min, choice_t max, LcdFlags attr, event_t event, coord_t lblX) -{ - return editChoice(x, y, label, values, value, min, max, attr, event, lblX, nullptr); -} - -choice_t editChoice(coord_t x, coord_t y, const char * label, const char *const *values, choice_t value, choice_t min, choice_t max, LcdFlags attr, event_t event) -{ - return editChoice(x, y, label, values, value, min, max, attr, event, 0, nullptr); -} - -uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const char *label, LcdFlags attr, event_t event, coord_t lblX) -{ - drawCheckBox(x, y, value, attr); - return editChoice(x, y, label, nullptr, value, 0, 1, attr, event, lblX); -} - -uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const char *label, LcdFlags attr, event_t event) -{ - return editCheckBox(value, x, y, label, attr, event, 0); -} - -swsrc_t editSwitch(coord_t x, coord_t y, swsrc_t value, LcdFlags attr, event_t event) -{ - lcdDrawTextAlignedLeft(y, STR_SWITCH); - drawSwitch(x, y, value, attr); - if (attr & (~RIGHT)) CHECK_INCDEC_MODELSWITCH(event, value, SWSRC_FIRST_IN_MIXES, SWSRC_LAST_IN_MIXES, isSwitchAvailableInMixes); - return value; -} - -void drawSlider(coord_t x, coord_t y, uint8_t width, uint8_t value, uint8_t max, uint8_t attr) -{ - lcdDrawChar(x + (value * (width - FWNUM)) / max, y, '$'); - lcdDrawSolidHorizontalLine(x, y + 3, width, FORCE); - if (attr && (!(attr & BLINK) || !BLINK_ON_PHASE)) { - lcdDrawSolidFilledRect(x, y, width, FH - 1); - } -} - -void drawSlider(coord_t x, coord_t y, uint8_t value, uint8_t max, uint8_t attr) -{ - drawSlider(x, y, 5*FW - 1, value, max, attr); -} - -uint16_t editSrcVarFieldValue(coord_t x, coord_t y, const char* title, uint16_t value, - int16_t min, int16_t max, LcdFlags attr, event_t event, - IsValueAvailable isValueAvailable, int16_t sourceMin, int16_t sourceMax) -{ - if (title) - lcdDrawTextAlignedLeft(y, title); - SourceNumVal v; - v.rawValue = value; - if (v.isSource) { - drawSource(x, y, v.value, attr); - if (attr & (~RIGHT)) { - value = checkIncDec(event, value, sourceMin, sourceMax, - EE_MODEL|INCDEC_SOURCE|INCDEC_SOURCE_VALUE|INCDEC_SOURCE_INVERT|NO_INCDEC_MARKS, isValueAvailable); - } - } else { - lcdDrawNumber(x, y, v.value, attr); - if (attr & (~RIGHT)) { - value = checkIncDec(event, value, min, max, sourceMin, sourceMax, - EE_MODEL|INCDEC_SOURCE_VALUE|NO_INCDEC_MARKS|INCDEC_SKIP_VAL_CHECK_FUNC, - isValueAvailable); - } - } - return value; -} - -#if defined(GVARS) -void drawGVarValue(coord_t x, coord_t y, uint8_t gvar, gvar_t value, LcdFlags flags) -{ - uint8_t prec = g_model.gvars[gvar].prec; - if (prec > 0) { - flags |= (prec == 1 ? PREC1 : PREC2); - } - drawValueWithUnit(x, y, value, g_model.gvars[gvar].unit ? UNIT_PERCENT : UNIT_RAW, flags); -} - -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) -{ - bool invers = (attr & INVERS); - - // TRACE("editGVarFieldValue(val=%d min=%d max=%d)", value, min, max); - - if (modelGVEnabled() && invers && event == EVT_KEY_LONG(KEY_ENTER)) { - killEvents(event); - s_editMode = !s_editMode; - if (attr & PREC1) - value = (GV_IS_GV_VALUE(value) ? GET_GVAR(value, min, max, mixerCurrentFlightMode)*10 : GV_VALUE_FROM_INDEX(0)); - else - value = (GV_IS_GV_VALUE(value) ? GET_GVAR(value, min, max, mixerCurrentFlightMode) : GV_VALUE_FROM_INDEX(0)); - storageDirty(EE_MODEL); - } - - if (GV_IS_GV_VALUE(value)) { - attr &= ~PREC1; - int8_t idx = (int16_t)GV_INDEX_FROM_VALUE(value); - if (invers) { - CHECK_INCDEC_MODELVAR(event, idx, -MAX_GVARS, MAX_GVARS-1); - } - value = (int16_t)GV_VALUE_FROM_INDEX(idx); - drawGVarName(x, y, idx, attr); - } - else { - lcdDrawNumber(x, y, value, attr); - if (invers) value = checkIncDec(event, value, min, max, EE_MODEL | editflags); - } - return value; -} -#else -int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, event_t event) -{ - lcdDrawNumber(x, y, value, attr); - if (attr&INVERS) value = checkIncDec(event, value, min, max, EE_MODEL); - return value; -} -#endif - -char statusLineMsg[STATUS_LINE_LENGTH]; -tmr10ms_t statusLineTime = 0; -uint8_t statusLineHeight = 0; - -void showStatusLine() -{ - statusLineTime = get_tmr10ms(); -} - -#define STATUS_LINE_DELAY (3 * 100) /* 3s */ -void drawStatusLine() -{ - if (statusLineTime) { - if ((tmr10ms_t)(get_tmr10ms() - statusLineTime) <= (tmr10ms_t)STATUS_LINE_DELAY) { - if (statusLineHeight < FH) statusLineHeight++; - } - else if (statusLineHeight) { - statusLineHeight--; - } - else { - statusLineTime = 0; - } - - lcdDrawFilledRect(0, LCD_H-statusLineHeight, LCD_W, FH, SOLID, ERASE); - lcdDrawText(5, LCD_H+1-statusLineHeight, statusLineMsg); - lcdDrawFilledRect(0, LCD_H-statusLineHeight, LCD_W, FH, SOLID); - } -} diff --git a/radio/src/gui/212x64/CMakeLists.txt b/radio/src/gui/212x64/CMakeLists.txt index c348de55a..195ad310b 100644 --- a/radio/src/gui/212x64/CMakeLists.txt +++ b/radio/src/gui/212x64/CMakeLists.txt @@ -5,7 +5,6 @@ set(GUI_SRC popups.cpp widgets.cpp startup_shutdown.cpp - menu_model.cpp model_select.cpp model_setup.cpp model_failsafe.cpp @@ -14,7 +13,6 @@ set(GUI_SRC model_outputs.cpp model_telemetry.cpp model_telemetry_sensor.cpp - menu_radio.cpp radio_setup.cpp radio_calibration.cpp view_main.cpp @@ -45,6 +43,7 @@ include(gui/common/stdlcd/CMakeLists.txt) set(BOOTLOADER_SRC ${BOOTLOADER_SRC} ${RADIO_SRC_DIR}/gui/212x64/lcd.cpp + ${RADIO_SRC_DIR}/gui/common/stdlcd/lcd_common.cpp ${RADIO_SRC_DIR}/gui/common/stdlcd/fonts.cpp ${RADIO_SRC_DIR}/gui/common/stdlcd/utf8.cpp ) diff --git a/radio/src/gui/212x64/gui.h b/radio/src/gui/212x64/gui.h index 01d1b1df5..e89ac9c1f 100644 --- a/radio/src/gui/212x64/gui.h +++ b/radio/src/gui/212x64/gui.h @@ -22,26 +22,18 @@ #pragma once #include "gui_common.h" -#include "lcd.h" #include "menus.h" #include "popups.h" +#include "widgets_common.h" #include "navigation/navigation.h" -#include "common/stdlcd/draw_functions.h" - -#define NUM_BODY_LINES (LCD_LINES-1) -#define TEXT_VIEWER_LINES NUM_BODY_LINES -#define MENU_HEADER_HEIGHT FH +#include "draw_functions.h" #define MODEL_BITMAP_WIDTH 64 #define MODEL_BITMAP_HEIGHT 32 #define MODEL_BITMAP_SIZE BITMAP_BUFFER_SIZE(MODEL_BITMAP_WIDTH, MODEL_BITMAP_HEIGHT) #define LOAD_MODEL_BITMAP() loadModelBitmap(g_model.header.bitmap, modelBitmap) -#define CURVE_SIDE_WIDTH (LCD_H/2-2) -#define CURVE_CENTER_X (LCD_W-CURVE_SIDE_WIDTH-3) -#define CURVE_CENTER_Y (LCD_H/2) - #define MIXES_2ND_COLUMN (18*FW) #define MENUS_SCROLLBAR_WIDTH 2 @@ -49,141 +41,11 @@ extern uint8_t modelBitmap[MODEL_BITMAP_SIZE]; bool loadModelBitmap(char * name, uint8_t * bitmap); -// Temporary no highlight -extern uint8_t noHighlightCounter; -#define NO_HIGHLIGHT() (noHighlightCounter > 0) -#define START_NO_HIGHLIGHT() do { noHighlightCounter = 25; } while(0) - -void drawCheckBox(coord_t x, coord_t y, uint8_t value, LcdFlags attr); -void drawSlider(coord_t x, coord_t y, uint8_t value, uint8_t max, uint8_t attr); -void drawSplash(); -void drawScreenIndex(uint8_t index, uint8_t count, uint8_t attr); -void drawVerticalScrollbar(coord_t x, coord_t y, coord_t h, uint16_t offset, uint16_t count, uint8_t visible); -void drawGauge(coord_t x, coord_t y, coord_t w, coord_t h, int32_t val, int32_t max); void drawColumnHeader(const char * const * headers, uint8_t index); -void drawStick(coord_t centrex, int16_t xval, int16_t yval); - -void drawAlertBox(const char * title, const char * text, const char * action); -void showAlertBox(const char * title, const char * text, const char * action, uint8_t sound); - -void doMainScreenGraphics(); - -void title(const char * s); - -typedef int choice_t; - -choice_t editChoice(coord_t x, coord_t y, const char *label, - const char *const *values, choice_t value, choice_t min, - choice_t max, LcdFlags attr, event_t event, coord_t lblX = 0); -choice_t editChoice(coord_t x, coord_t y, const char *label, - const char *const *values, choice_t value, choice_t min, - choice_t max, LcdFlags attr, event_t event, coord_t lblX, - IsValueAvailable isValueAvailable); - -uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const char *label, - LcdFlags attr, event_t event, coord_t lblX = 0); - -swsrc_t editSwitch(coord_t x, coord_t y, swsrc_t value, LcdFlags attr, - event_t event); - -uint16_t editSrcVarFieldValue(coord_t x, coord_t y, const char* title, uint16_t value, - int16_t min, int16_t max, LcdFlags attr, event_t event, - IsValueAvailable isValueAvailable, int16_t sourceMin, int16_t sourceMax); - -#if defined(GVARS) -void drawGVarValue(coord_t x, coord_t y, uint8_t gvar, gvar_t value, - LcdFlags flags = 0); - -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); - -#define GVAR_MENU_ITEM(x, y, v, min, max, lcdattr, editflags, event) \ - editGVarFieldValue(x, y, v, min, max, lcdattr, editflags, event) - -#define displayGVar(x, y, v, min, max) \ - GVAR_MENU_ITEM(x, y, v, min, max, 0, 0, 0) - -#else // GVARS - -#define GVAR_MENU_ITEM(x, y, v, min, max, lcdattr, editflags, event) \ - editGVarFieldValue(x, y, v, min, max, lcdattr, event) - -int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, - int16_t max, LcdFlags attr, event_t event); - -#define displayGVar(x, y, v, min, max) lcdDrawNumber(x, y, v) - -#endif - -void editCurveRef(coord_t x, coord_t y, CurveRef & curve, event_t event, LcdFlags flags, - IsValueAvailable isValueAvailable, int16_t sourceMin, int16_t sourceMax); - -extern uint8_t editNameCursorPos; - -void editName(coord_t x, coord_t y, char *name, uint8_t size, event_t event, - uint8_t active, LcdFlags attr, uint8_t old_editMode); - -void editSingleName(coord_t x, coord_t y, const char *label, char *name, - uint8_t size, event_t event, uint8_t active, - uint8_t old_editMode, coord_t lblX = 0); - -uint8_t editDelay(coord_t y, event_t event, uint8_t attr, const char * str, uint8_t delay, uint8_t prec); - -#define EDIT_DELAY(y, event, attr, str, delay, prec) editDelay(y, event, attr, str, delay, prec) void copySelection(char * dst, const char * src, uint8_t size); -#define COPY_MODE 1 -#define MOVE_MODE 2 - -extern uint8_t s_copyMode; -extern int8_t s_copySrcRow; -extern int8_t s_copyTgtOfs; -extern uint8_t s_currIdx; -extern uint8_t s_currIdxSubMenu; -extern mixsrc_t s_currSrcRaw; -extern uint16_t s_currScale; -extern uint8_t s_copySrcIdx; -extern uint8_t s_copySrcCh; -extern int8_t s_currCh; -extern uint8_t s_maxLines; - -uint8_t getExposCount(); -void deleteExpo(uint8_t idx); -void insertExpo(uint8_t idx); - -#define STATUS_LINE_LENGTH 32 -extern char statusLineMsg[STATUS_LINE_LENGTH]; -void showStatusLine(); -void drawStatusLine(); - -void menuTextView(event_t event); -void pushMenuTextView(const char *filename); -void pushModelNotes(); -void readModelNotes(); - -void menuChannelsView(event_t event); - -#define EDIT_MODE_INIT 0 - -void onSwitchLongEnterPress(const char *result); -void onSourceLongEnterPress(const char *result); - -uint8_t switchToMix(uint8_t source); - extern coord_t scrollbar_X; #define SET_SCROLLBAR_X(x) scrollbar_X = (x); -extern const unsigned char sticks[] ; - -#if defined(FLIGHT_MODES) -void displayFlightModes(coord_t x, coord_t y, FlightModesType value); -FlightModesType editFlightModes(coord_t x, coord_t y, event_t event, FlightModesType value, uint8_t attr); -#else -#define displayFlightModes(...) -#endif - -#define IS_MAIN_VIEW_DISPLAYED() menuHandlers[0] == menuMainView -#define IS_TELEMETRY_VIEW_DISPLAYED() menuHandlers[0] == menuViewTelemetry #define IS_OTHER_VIEW_DISPLAYED() (menuHandlers[0] == menuMainViewChannelsMonitor || menuHandlers[0] == menuChannelsView) diff --git a/radio/src/gui/212x64/lcd.cpp b/radio/src/gui/212x64/lcd.cpp index 23f42a4d1..b0db9890b 100644 --- a/radio/src/gui/212x64/lcd.cpp +++ b/radio/src/gui/212x64/lcd.cpp @@ -19,12 +19,8 @@ * GNU General Public License for more details. */ -#include -#include - #include "lcd.h" -#include "common/stdlcd/fonts.h" -#include "common/stdlcd/utf8.h" +#include "utf8.h" #if !defined(SIMU) #define assert(x) @@ -34,243 +30,15 @@ #if !defined(BOOT) #include "edgetx.h" - #include "hal/switch_driver.h" - #include "hal/adc_driver.h" - #include "switches.h" #endif -pixel_t displayBuf[DISPLAY_BUFFER_SIZE] __DMA; +extern LcdFlags getCharPattern(PatternData * pattern, unsigned char c, LcdFlags flags); inline bool lcdIsPointOutside(coord_t x, coord_t y) { return (x<0 || x>=LCD_W || y<0 || y>=LCD_H); } -void lcdClear() -{ - memset(displayBuf, 0, DISPLAY_BUFFER_SIZE * sizeof(pixel_t)); -} - -coord_t lcdLastRightPos; -coord_t lcdLastLeftPos; -coord_t lcdNextPos; - -struct PatternData -{ - uint8_t width; - uint8_t height; - const uint8_t * data; -}; - -uint8_t getPatternWidth(const PatternData * pattern) -{ - uint8_t result = 0; - uint8_t lines = (pattern->height+7)/8; - const uint8_t * data = pattern->data; - for (int8_t i=0; iwidth; i++) { - for (uint8_t j=0; j= 12) - continue; - if (j < 0 && !inv) - continue; - if (y + j < 0) - continue; - } - else { - uint8_t line = (j / 8); - uint8_t pixel = (j % 8); - plot = b[line] & (1 << pixel); - } - if (inv) - plot = !plot; - if (!blink) { - if (flags & VERTICAL) - lcdDrawPoint(y+j, LCD_H-x, plot ? FORCE : ERASE); - else - lcdDrawPoint(x, y+j, plot ? FORCE : ERASE); - } - } - } - - x++; - lcdNextPos++; - } -} - -LcdFlags getCharPattern(PatternData * pattern, unsigned char c, LcdFlags flags) -{ -#if !defined(BOOT) - static const uint8_t fontWidth[] = { 5, 3, 5, 8, 10, 22, 5 }; - static const uint8_t fontHeight[] = { 7, 5, 6, 12, 16, 38, 7 }; - - uint32_t fontsize = FONTSIZE(flags); - unsigned char c_remapped = 0; - - if (fontsize == DBLSIZE || (flags & BOLD)) { - // To save space only some DBLSIZE and BOLD chars are available - // c has to be remapped. All non existing chars mapped to 0 (space) - if (c >= ',' && c <= ':') - c_remapped = c - ',' + 1; - else if (c >= 'A' && c <= 'Z') - c_remapped = c - 'A' + 16; - else if (c >= 'a' && c <= 'z') - c_remapped = c - 'a' + 42; - else if (c == '_') - c_remapped = 4; - else if (c != ' ') - flags &= ~BOLD; // For BOLD use Standard font if character is not in BOLD - } - - uint8_t fontIdx = fontsize >> 8; - if (fontIdx == 0 && flags & BOLD) fontIdx = 6; - - pattern->width = fontWidth[fontIdx]; - pattern->height = fontHeight[fontIdx]; - int charSize = (pattern->height + 7) / 8 * pattern->width; - - switch (fontIdx) { - case 0: // Standard - pattern->data = &font_5x7[(c - FONT_BASE_START) * charSize]; - break; - case 1: // TINSIZE - pattern->data = &font_3x5[(c - FONT_BASE_START) * charSize]; - break; - case 2: // SMLSIZE - // Adjust language special characters offset - if (c >= FONT_LANG_START) - c = c - (FONT_SYMS_CNT - FONT_SYMS_CNT_4x6); - pattern->data = &font_4x6[(c - FONT_BASE_START) * charSize]; - break; - case 3: // MDLSIZE - // Adjust language special characters offset - if (c >= FONT_LANG_START) - c = c - FONT_SYMS_CNT; - pattern->data = &font_8x10[(c - FONT_BASE_START) * charSize]; - break; - case 4: // DBLSIZE - // Adjust language special characters offset and symbols offset - if (c >= FONT_LANG_START) - c_remapped = c - (FONT_BASE_CNT - FONT_BASE_CNT_10x14) - (FONT_SYMS_CNT - FONT_SYMS_CNT_10x14) - FONT_BASE_START; - else if (c >= FONT_SYMS_START) - c_remapped = c - (FONT_BASE_CNT - FONT_BASE_CNT_10x14) - FONT_BASE_START; - pattern->data = &font_10x14[(c_remapped) * charSize]; - break; - case 5: // XXLSIZE - pattern->data = &font_22x38_num[(c - '0' + 5) * charSize]; - break; - case 6: // BOLD - pattern->data = &font_5x7_B[c_remapped * charSize]; - break; - }; -#else - pattern->width = 5; - pattern->height = 7; - pattern->data = &font_5x7[(c - FONT_BASE_START) * 5]; -#endif - return flags; -} - -uint8_t getCharWidth(char c, LcdFlags flags) -{ - PatternData pattern; - getCharPattern(&pattern, c, flags); - return getPatternWidth(&pattern); -} - -void lcdDrawChar(coord_t x, coord_t y, uint8_t c, LcdFlags flags) -{ - lcdNextPos = x - 1; - PatternData pattern; - flags = getCharPattern(&pattern, c, flags); - lcdPutPattern(x, y, pattern.data, pattern.width, pattern.height, flags); -} - -void lcdDrawChar(coord_t x, coord_t y, uint8_t c) -{ - lcdDrawChar(x, y, c, 0); -} - -uint8_t getTextWidth(const char * s, uint8_t len, LcdFlags flags) -{ - uint8_t width = 0; - for (int i = 0; len == 0 || i < len; ++i) { - unsigned char c = map_utf8_char(s, len); - if (!c) { - break; - } - width += getCharWidth(c, flags) + 1; - s++; - } - return width; -} - void lcdDrawSizedText(coord_t x, coord_t y, const char * s, uint8_t len, LcdFlags flags) { const coord_t orig_x = x; @@ -364,43 +132,7 @@ void lcdDrawSizedText(coord_t x, coord_t y, const char * s, uint8_t len, LcdFlag } } -void lcdDrawSizedText(coord_t x, coord_t y, const char * s, uint8_t len) -{ - lcdDrawSizedText(x, y, s, len, 0); -} - -void lcdDrawCenteredText(coord_t y, const char * s, LcdFlags flags) -{ - coord_t x = (LCD_W - getTextWidth(s, flags)) / 2; - lcdDrawText(x, y, s, flags); -} - -void lcdDrawText(coord_t x, coord_t y, const char * s, LcdFlags flags) -{ - lcdDrawSizedText(x, y, s, 255, flags); -} - -void lcdDrawText(coord_t x, coord_t y, const char * s) -{ - lcdDrawText(x, y, s, 0); -} - -void lcdDrawTextAlignedLeft(coord_t y, const char * s) -{ - lcdDrawText(0, y, s); -} - -void lcdDrawTextIndented(coord_t y, const char * s) -{ - lcdDrawText(INDENT_WIDTH, y, s); -} - #if !defined(BOOT) -void lcdDrawTextAtIndex(coord_t x, coord_t y, const char *const *s,uint8_t idx, LcdFlags flags) -{ - lcdDrawSizedText(x, y, s[idx], UINT8_MAX, flags); -} - void lcdDrawHexNumber(coord_t x, coord_t y, uint32_t val, LcdFlags flags) { for (int i=12; i>=0; i-=4) { @@ -410,133 +142,9 @@ void lcdDrawHexNumber(coord_t x, coord_t y, uint32_t val, LcdFlags flags) x = lcdNextPos; } } - -void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags flags) -{ - lcdDrawNumber(x, y, val, flags, 0); -} - -void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags flags, uint8_t len) -{ - char str[16+1]; - char *s = str+16; - *s = '\0'; - int idx = 0; - int mode = MODE(flags); - bool neg = false; - - if (val == INT_MAX) { - flags &= ~(LEADING0 | PREC1 | PREC2); - lcdDrawText(x, y, "INT_MAX", flags); - return; - } - - if (val < 0) { - if (val == INT_MIN) { - flags &= ~(LEADING0 | PREC1 | PREC2); - lcdDrawText(x, y, "INT_MIN", flags); - return; - } - val = -val; - neg = true; - } - do { - *--s = '0' + (val % 10); - ++idx; - val /= 10; - if (mode!=0 && idx==mode) { - mode = 0; - *--s = '.'; - if (val==0) { - *--s = '0'; - } - } - } while (val!=0 || mode>0 || (mode==MODE(LEADING0) && idx>1; - int y = dxabs>>1; - int px = x1; - int py = y1; - - if (dxabs >= dyabs) { - /* the line is more horizontal than vertical */ - for (int i=0; i<=dxabs; i++) { - if ((1<<(px%8)) & pat) { - lcdDrawPoint(px, py, att); - } - y += dyabs; - if (y>=dxabs) { - y -= dxabs; - py += sdy; - } - px += sdx; - } - } - else { - /* the line is more vertical than horizontal */ - for (int i=0; i<=dyabs; i++) { - if ((1<<(py%8)) & pat) { - lcdDrawPoint(px, py, att); - } - x += dxabs; - if (x >= dyabs) { - x -= dyabs; - px += sdx; - } - py += sdy; - } - } -} -#endif - -void lcdDrawSolidVerticalLine(coord_t x, coord_t y, coord_t h, LcdFlags att) -{ - lcdDrawVerticalLine(x, y, h, SOLID, att); -} - -void lcdDrawRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat, LcdFlags att) -{ - lcdDrawVerticalLine(x, y, h, pat, att); - lcdDrawVerticalLine(x+w-1, y, h, pat, att); - if (~att & ROUND) { x+=1; w-=2; } - lcdDrawHorizontalLine(x, y+h-1, w, pat, att); - lcdDrawHorizontalLine(x, y, w, pat, att); -} - -#if !defined(BOOT) -void lcdDrawFilledRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat, LcdFlags att) -{ - for (coord_t i=y; i> 1) + ((pat & 1) << 7); - } -} - void drawTelemetryTopBar() { drawModelName(0, 0, g_model.header.name, g_eeGeneral.currModel, 0); @@ -567,120 +175,11 @@ void drawTelemetryTopBar() lcdInvertLine(0); } -void drawRtcTime(coord_t x, coord_t y, LcdFlags att) -{ - drawTimer(x, y, getValue(MIXSRC_TX_TIME), att, att); -} - -void drawTimer(coord_t x, coord_t y, int32_t tme, LcdFlags att, LcdFlags att2) -{ - div_t qr; - - if (att & RIGHT) { - att -= RIGHT; - if (att & DBLSIZE) - x -= 5*(2*FWNUM)-4; - else if (att & MIDSIZE) - x -= 5*8-4; - else - x -= 5*FWNUM+1; - } - - if (tme < 0) { - lcdDrawChar(x - ((att & DBLSIZE) ? FW+2 : ((att & MIDSIZE) ? FW+0 : FWNUM)), y, '-', att); - tme = -tme; - } - - qr = div((int)tme, 60); - -#define separator ':' - if (att & TIMEHOUR) { - div_t qr2 = div(qr.quot, 60); - if (qr2.quot < 100) { - lcdDrawNumber(x, y, qr2.quot, att|LEADING0|LEFT, 2); - } - else { - lcdDrawNumber(x, y, qr2.quot, att|LEFT); - } - lcdDrawChar(lcdNextPos, y, separator, att); - qr.quot = qr2.rem; - x = lcdNextPos; - } - - lcdDrawNumber(x, y, qr.quot, att|LEADING0|LEFT, 2); - if (att & TIMEBLINK) - lcdDrawChar(lcdNextPos, y, separator, BLINK); - else - lcdDrawChar(lcdNextPos, y, separator, att&att2); - lcdDrawNumber(lcdNextPos, y, qr.rem, (att2|LEADING0) & (~RIGHT), 2); -} - -// TODO to be optimized with drawValueWithUnit -void putsVolts(coord_t x, coord_t y, uint16_t volts, LcdFlags att) -{ - lcdDrawNumber(x, y, (int16_t)volts, (~NO_UNIT) & (att | ((att&PREC2)==PREC2 ? 0 : PREC1))); - if (~att & NO_UNIT) lcdDrawChar(lcdLastRightPos, y, 'V', att); -} - -void putsVBat(coord_t x, coord_t y, LcdFlags att) -{ - putsVolts(x, y, g_vbat100mV, att); -} - void drawMainControlLabel(coord_t x, coord_t y, uint8_t idx, LcdFlags att) { lcdDrawSizedText(x, y, getMainControlLabel(idx), UINT8_MAX, att); } -void putsChn(coord_t x, coord_t y, uint8_t idx, LcdFlags att) -{ - drawStringWithIndex(x, y, STR_CH, idx, att); -} - -void putsChnLetter(coord_t x, coord_t y, uint8_t idx, LcdFlags att) -{ - lcdDrawText(x, y, getAnalogShortLabel(idx), att); -} - -void drawModelName(coord_t x, coord_t y, char *name, uint8_t id, LcdFlags att) -{ - uint8_t len = sizeof(g_model.header.name); - while (len>0 && !name[len-1]) --len; - if (len==0) { - drawStringWithIndex(x, y, STR_MODEL, id+1, att|LEADING0); - } - else { - lcdDrawSizedText(x, y, name, sizeof(g_model.header.name), att); - } -} - -void drawSwitch(coord_t x, coord_t y, int32_t idx, LcdFlags flags, bool autoBold) -{ - char s[8]; - getSwitchPositionName(s, idx); - if (autoBold && idx != SWSRC_NONE && getSwitch(idx)) - flags |= BOLD; - lcdDrawText(x, y, s, flags); -} - -void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags flags) -{ - char s[8]; - getCurveString(s, idx); - lcdDrawText(x, y, s, flags); -} - -void drawTimerMode(coord_t x, coord_t y, swsrc_t mode, LcdFlags att) -{ - if (mode >= 0) { - if (mode < TMRMODE_COUNT) - return lcdDrawTextAtIndex(x, y, STR_VTMRMODES, mode, att); - else - mode -= (TMRMODE_COUNT-1); - } - drawSwitch(x, y, mode, att); -} - void drawGPSCoord(coord_t x, coord_t y, int32_t value, const char * direction, LcdFlags att, bool seconds=true) { uint32_t absvalue = abs(value); @@ -976,5 +475,3 @@ void lcdDrawRleBitmap(coord_t x, coord_t y, const uint8_t * img, coord_t offset, } } #endif - -void lcdFlushed() {} diff --git a/radio/src/gui/212x64/lcd.h b/radio/src/gui/212x64/lcd.h index f5ab483e2..7e898a1b9 100644 --- a/radio/src/gui/212x64/lcd.h +++ b/radio/src/gui/212x64/lcd.h @@ -26,152 +26,29 @@ #include "edgetx_types.h" #include "board.h" -#define BOX_WIDTH 31 -#define CENTER_OFS (7*FW-FW/2) -#define OFS_CHECKTRIMS CENTER_OFS+(9*FW) -#define INDENT_WIDTH (FW/2) +constexpr coord_t BOX_WIDTH = 31; +constexpr coord_t BOX_CENTERY = LCD_H - BOX_WIDTH / 2 - 10; +constexpr coord_t MARKER_WIDTH = 5; +#define CENTER_OFS (7 * FW - FW / 2) -#define FW 6 -#define FWNUM 5 -#define FH 8 +#define BITMAP_BUFFER_SIZE(w, h) (2 + (w) * (((h)+7)/8)*4) +#define DISPLAY_BUFFER_SIZE (LCD_W*LCD_H*4/8) -#define LCD_LINES (LCD_H/FH) -#define LCD_COLS (LCD_W/FW) +#define GREY(x) ((x) * 0x010000) +#define WHITE GREY(0xf) +#define GREY_DEFAULT GREY(11) +#define COLOUR_MASK(x) ((x) & 0x0F0000) -#define BITMAP_BUFFER_SIZE(w, h) (2 + (w) * (((h)+7)/8)*4) +#include "lcd_common.h" -/* lcdDrawText flags */ -#define BLINK 0x01 -#define INVERS 0x02 -#define BOLD 0x04 -#define LEFT 0x00 -#define RIGHT 0x08 -#define CENTERED 0x20 -#define FIXEDWIDTH 0x10 -/* no 0x80 here because of "GV"1 which is aligned LEFT */ -/* no 0x10 here because of "MODEL"01 which uses LEADING0 */ -#define ZCHAR 0x80 - -/* lcdDrawNumber additional flags */ -#define LEADING0 0x10 -#define PREC1 0x20 -#define PREC2 0x30 -#define MODE(flags) ((((int8_t)(flags) & 0x30) - 0x10) >> 4) - -/* line, rect, square flags */ -#define FORCE 0x02 -#define ERASE 0x04 -#define ROUND 0x08 -#define FILL_WHITE 0x10 - -/* telemetry flags */ -#define NO_UNIT 0x40 - -#define FONTSIZE_MASK 0x0700 -#define FONTSIZE(x) ((x) & FONTSIZE_MASK) -#define TINSIZE 0x0100 -#define SMLSIZE 0x0200 -#define MIDSIZE 0x0300 -#define DBLSIZE 0x0400 -#define XXLSIZE 0x0500 -#define ERASEBG 0x8000 -#define VERTICAL 0x0800 - -#define TIMEBLINK 0x1000 -#define TIMEHOUR 0x2000 -#define STREXPANDED 0x4000 - -#define GREY(x) ((x) * 0x010000) -#define WHITE GREY(0xf) -#define GREY_DEFAULT GREY(11) -#define COLOUR_MASK(x) ((x) & 0x0F0000) - -#define DISPLAY_BUFFER_SIZE (LCD_W*LCD_H*4/8) - -extern pixel_t displayBuf[DISPLAY_BUFFER_SIZE]; -extern coord_t lcdLastRightPos; -extern coord_t lcdLastLeftPos; -extern coord_t lcdNextPos; - -#define DISPLAY_END (displayBuf + DISPLAY_BUFFER_SIZE) -#define ASSERT_IN_DISPLAY(p) assert((p) >= displayBuf && (p) < DISPLAY_END) - -void lcdDrawChar(coord_t x, coord_t y, uint8_t c); -void lcdDrawChar(coord_t x, coord_t y, uint8_t c, LcdFlags mode); -void lcdDrawCenteredText(coord_t y, const char * s, LcdFlags flags = 0); -void lcdDrawText(coord_t x, coord_t y, const char * s, LcdFlags mode); -void lcdDrawTextAtIndex(coord_t x, coord_t y, const char *const *s,uint8_t idx, LcdFlags mode); -void lcdDrawSizedText(coord_t x, coord_t y, const char * s, unsigned char len, LcdFlags mode); -void lcdDrawText(coord_t x, coord_t y, const char * s); -void lcdDrawSizedText(coord_t x, coord_t y, const char * s, unsigned char len); -void lcdDrawTextAlignedLeft(coord_t y, const char * s); -void lcdDrawTextIndented(coord_t y, const char * s); - -void lcdDrawHexNumber(coord_t x, coord_t y, uint32_t val, LcdFlags mode=0); -void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags mode, uint8_t len); -void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags mode=0); - -void drawModelName(coord_t x, coord_t y, char *name, uint8_t id, LcdFlags att); -void drawSwitch(coord_t x, coord_t y, int32_t swtch, LcdFlags att=0, bool autoBold = true); void drawMainControlLabel(coord_t x, coord_t y, uint8_t idx, LcdFlags att=0); -void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags att=0); -void drawTimerMode(coord_t x, coord_t y, swsrc_t mode, LcdFlags att=0); - -void putsChn(coord_t x, coord_t y, uint8_t idx, LcdFlags attr); -void putsChnLetter(coord_t x, coord_t y, uint8_t idx, LcdFlags attr); - -void putsVolts(coord_t x, coord_t y, uint16_t volts, LcdFlags att); -void putsVBat(coord_t x, coord_t y, LcdFlags att); - -#define SOLID 0xff -#define DOTTED 0x55 - -void lcdDrawPoint(coord_t x, coord_t y, LcdFlags att=0); -void lcdMaskPoint(uint8_t *p, uint8_t mask, LcdFlags att=0); -void lcdDrawSolidHorizontalLine(coord_t x, coord_t y, coord_t w, LcdFlags att=0); -void lcdDrawHorizontalLine(coord_t x, coord_t y, coord_t w, uint8_t pat, LcdFlags att=0); -void lcdDrawSolidVerticalLine(coord_t x, coord_t y, coord_t h, LcdFlags att=0); -void lcdDrawVerticalLine(coord_t x, coord_t y, coord_t h, uint8_t pat, LcdFlags att=0); -void lcdDrawLine(coord_t x1, coord_t y1, coord_t x2, coord_t y2, uint8_t pat=SOLID, LcdFlags att=0); -void lcdDrawFilledRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat=SOLID, LcdFlags att=0); -inline void lcdDrawSolidFilledRect(coord_t x, coord_t y, coord_t w, coord_t h, LcdFlags att=0) -{ - lcdDrawFilledRect(x, y, w, h, SOLID, att); -} -void lcdDrawRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat=SOLID, LcdFlags att=0); -inline void lcdDrawSquare(coord_t x, coord_t y, coord_t w, LcdFlags att=0) -{ - lcdDrawRect(x, y, w, w, SOLID, att); -} - -void lcdInvertLine(int8_t line); -#define lcdInvertLastLine() lcdInvertLine(LCD_LINES-1) - -void drawTelemetryTopBar(); - -#define V_BAR(xx, yy, ll) \ - lcdDrawSolidVerticalLine(xx-1,yy-ll,ll); \ - lcdDrawSolidVerticalLine(xx ,yy-ll,ll); \ - lcdDrawSolidVerticalLine(xx+1,yy-ll,ll) - -void lcdDraw1bitBitmap(coord_t x, coord_t y, const unsigned char * img, uint8_t idx, LcdFlags att=0); void lcdDrawBitmap(coord_t x, coord_t y, const uint8_t * img, coord_t offset=0, coord_t width=0); void lcdDrawRleBitmap(coord_t x, coord_t y, const uint8_t * img, coord_t offset=0, coord_t width=0, bool overlay=false); #define LCD_ICON(x, y, icon) lcdDrawRleBitmap(x, y, icons, icon) - -void lcdClear(); - uint8_t * lcdLoadBitmap(uint8_t * dest, const char * filename, uint16_t width, uint16_t height); -#if defined(BOOT) - #define BLINK_ON_PHASE (0) -#else - #define BLINK_ON_PHASE (g_blinkTmr10ms & (1 << 6)) - #define SLOW_BLINK_ON_PHASE (g_blinkTmr10ms & (1 << 7)) -#endif - inline pixel_t getPixel(unsigned int x, unsigned int y) { if (x>=LCD_W || y>=LCD_H) { @@ -182,8 +59,6 @@ inline pixel_t getPixel(unsigned int x, unsigned int y) return (y & 1) ? (*p >> 4) : (*p & 0x0F); } -uint8_t getTextWidth(const char * s, uint8_t len=0, LcdFlags flags=0); - class RleBitmap { public: diff --git a/radio/src/gui/212x64/menu_radio.cpp b/radio/src/gui/212x64/menu_radio.cpp deleted file mode 100644 index db3b37647..000000000 --- a/radio/src/gui/212x64/menu_radio.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) EdgeTX - * - * Based on code named - * opentx - https://github.com/opentx/opentx - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include "edgetx.h" - -const MenuHandler menuTabGeneral[MENU_RADIO_PAGES_COUNT] = { -#if defined(RADIO_TOOLS) - { menuRadioTools, nullptr }, -#endif - { menuRadioSdManager, nullptr }, - { menuRadioSetup, nullptr }, - { menuRadioSpecialFunctions, radioGFEnabled }, - { menuRadioTrainer, radioTrainerEnabled }, - { menuRadioHardware, nullptr }, - { menuRadioVersion, nullptr } -}; - -void menuRadioSpecialFunctions(event_t event) -{ - MENU(STR_MENUSPECIALFUNCS, menuTabGeneral, MENU_RADIO_SPECIAL_FUNCTIONS, MAX_SPECIAL_FUNCTIONS, { NAVIGATION_LINE_BY_LINE|5/*repeated*/ }); - return menuSpecialFunctions(event, g_eeGeneral.customFn, &globalFunctionsContext); -} diff --git a/radio/src/gui/212x64/menus.h b/radio/src/gui/212x64/menus.h index 511ed7196..683402798 100644 --- a/radio/src/gui/212x64/menus.h +++ b/radio/src/gui/212x64/menus.h @@ -21,109 +21,12 @@ #pragma once -#include "keys.h" -#include "common/stdlcd/menus.h" -#include "common/stdlcd/features.h" +#include "menus_common.h" -inline bool isRadioMenuDisplayed() -{ - return menuVerticalPositions[0] == 1; -} - -inline bool isModelMenuDisplayed() -{ - return menuVerticalPositions[0] == 0; -} - -void onMainViewMenu(const char * result); -void menuFirstCalib(event_t event); void menuMainViewChannelsMonitor(event_t event); -void menuChannelsView(event_t event); -void menuMainView(event_t event); -void menuViewTelemetry(event_t event); -void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomFunctionsContext * functionsContext); -void menuModelNotes(event_t event); -void menuStatisticsView(event_t event); -void menuStatisticsDebug(event_t event); -void menuStatisticsDebug2(event_t event); -void menuAboutView(event_t event); #if defined(DEBUG_TRACE_BUFFER) void menuTraceBuffer(event_t event); #endif -enum MenuRadioIndexes { -#if defined(LUA) || defined(PXX2) || defined(MULTIMODULE) - MENU_RADIO_TOOLS, -#endif - MENU_RADIO_SD_MANAGER, - MENU_RADIO_SETUP, - MENU_RADIO_SPECIAL_FUNCTIONS, - MENU_RADIO_TRAINER, - MENU_RADIO_HARDWARE, - MENU_RADIO_VERSION, - MENU_RADIO_PAGES_COUNT -}; - -void menuRadioSetup(event_t event); -void menuRadioSdManager(event_t event); -void menuRadioSpecialFunctions(event_t event); -void menuRadioTrainer(event_t event); -void menuRadioVersion(event_t event); -void menuRadioDiagKeys(event_t event); -void menuRadioDiagAnalogs(event_t event); -void menuRadioHardware(event_t event); -void menuRadioTools(event_t event); -void menuRadioCalibration(event_t event); -void menuRadioSpectrumAnalyser(event_t event); -void menuRadioPowerMeter(event_t event); -void menuGhostModuleConfig(event_t event); - -extern const MenuHandler menuTabGeneral[MENU_RADIO_PAGES_COUNT]; - -enum MenuModelIndexes { - MENU_MODEL_SELECT, - MENU_MODEL_SETUP, - CASE_HELI(MENU_MODEL_HELI) - CASE_FLIGHT_MODES(MENU_MODEL_FLIGHT_MODES) - MENU_MODEL_INPUTS, - MENU_MODEL_MIXES, - MENU_MODEL_OUTPUTS, - MENU_MODEL_CURVES, - CASE_GVARS(MENU_MODEL_GVARS) - MENU_MODEL_LOGICAL_SWITCHES, - MENU_MODEL_SPECIAL_FUNCTIONS, -#if defined(LUA_MODEL_SCRIPTS) - MENU_MODEL_CUSTOM_SCRIPTS, -#endif - MENU_MODEL_TELEMETRY, - MENU_MODEL_DISPLAY, - MENU_MODEL_PAGES_COUNT -}; - -void menuModelSelect(event_t event); -void menuModelSetup(event_t event); -void menuModelFailsafe(event_t event); -void menuModelModuleOptions(event_t event); -void menuModelReceiverOptions(event_t event); -void menuModelHeli(event_t event); -void menuModelFlightModesAll(event_t event); -void menuModelExpoOne(event_t event); -void menuModelExposAll(event_t event); -void menuModelMixOne(event_t event); -void menuModelMixAll(event_t event); -void menuModelLimits(event_t event); -void menuModelCurvesAll(event_t event); -void menuModelCurveOne(event_t event); void menuModelGVars(event_t event); -void menuModelLogicalSwitches(event_t event); -void menuModelSpecialFunctions(event_t event); -void menuModelCustomScripts(event_t event); -void menuModelTelemetry(event_t event); -void menuModelSensor(event_t event); -void menuModelDisplay(event_t event); -#if defined(USBJ_EX) -void menuModelUSBJoystick(event_t event); -#endif - -extern const MenuHandler menuTabModel[MENU_MODEL_PAGES_COUNT]; diff --git a/radio/src/gui/212x64/model_custom_scripts.cpp b/radio/src/gui/212x64/model_custom_scripts.cpp index d1b30b1f5..f9daeed85 100644 --- a/radio/src/gui/212x64/model_custom_scripts.cpp +++ b/radio/src/gui/212x64/model_custom_scripts.cpp @@ -164,6 +164,6 @@ void menuModelCustomScripts(event_t event) } // Script name - lcdDrawSizedText(16*FW, y, sd.name, sizeof(sd.name), ZCHAR); + lcdDrawSizedText(16*FW, y, sd.name, sizeof(sd.name)); } } diff --git a/radio/src/gui/212x64/model_failsafe.cpp b/radio/src/gui/212x64/model_failsafe.cpp index 1f52f99bd..e59b8f8e2 100644 --- a/radio/src/gui/212x64/model_failsafe.cpp +++ b/radio/src/gui/212x64/model_failsafe.cpp @@ -106,7 +106,7 @@ void menuModelFailsafe(event_t event) if (lenLabel > 0) { if (lenLabel > reusableBuffer.modelFailsafe.maxNameLen) reusableBuffer.modelFailsafe.maxNameLen = lenLabel; - lcdDrawSizedText(x - colW, y, g_model.limitData[ch+channelStart].name, sizeof(g_model.limitData[ch+channelStart].name), ZCHAR | SMLSIZE); + lcdDrawSizedText(x - colW, y, g_model.limitData[ch+channelStart].name, sizeof(g_model.limitData[ch+channelStart].name), SMLSIZE); } else { putsChn(x - colW, y, ch+1, SMLSIZE); diff --git a/radio/src/gui/212x64/model_gvars.cpp b/radio/src/gui/212x64/model_gvars.cpp index 812957932..f3e8bac53 100644 --- a/radio/src/gui/212x64/model_gvars.cpp +++ b/radio/src/gui/212x64/model_gvars.cpp @@ -23,36 +23,6 @@ static int numFlightModes() { return modelFMEnabled() ? MAX_FLIGHT_MODES : 1; } -void editGVarValue(coord_t x, coord_t y, event_t event, uint8_t gvar, uint8_t flightMode, LcdFlags flags) -{ - FlightModeData * fm = &g_model.flightModeData[flightMode]; - gvar_t * v = &fm->gvars[gvar]; - int16_t vmin, vmax; - if (*v > GVAR_MAX) { - uint8_t fm = *v - GVAR_MAX - 1; - if (fm >= flightMode) fm++; - drawFlightMode(x, y, fm + 1, flags&(~LEFT)); - vmin = GVAR_MAX + 1; - vmax = GVAR_MAX + MAX_FLIGHT_MODES - 1; - } - else { - drawGVarValue(x, y, gvar, *v, flags); - vmin = GVAR_MIN + g_model.gvars[gvar].min; - vmax = GVAR_MAX - g_model.gvars[gvar].max; - } - - if (flags & INVERS) { - if (event == EVT_KEY_LONG(KEY_ENTER) && flightMode > 0) { - killEvents(event); - *v = (*v > GVAR_MAX ? 0 : GVAR_MAX+1); - storageDirty(EE_MODEL); - } - else if (s_editMode > 0) { - *v = checkIncDec(event, *v, vmin, vmax, EE_MODEL); - } - } -} - enum GVarFields { GVAR_FIELD_NAME, GVAR_FIELD_UNIT, diff --git a/radio/src/gui/212x64/model_mix_edit.cpp b/radio/src/gui/212x64/model_mix_edit.cpp index 190ef86a9..ca958b2fe 100644 --- a/radio/src/gui/212x64/model_mix_edit.cpp +++ b/radio/src/gui/212x64/model_mix_edit.cpp @@ -190,11 +190,11 @@ void menuModelMixOne(event_t event) break; case MIX_FIELD_DELAY_UP: - md2->delayUp = EDIT_DELAY(y, event, attr, STR_DELAYUP, md2->delayUp, (md2->delayPrec ? PREC2 : PREC1)); + md2->delayUp = editDelay(y, event, attr, STR_DELAYUP, md2->delayUp, (md2->delayPrec ? PREC2 : PREC1)); break; case MIX_FIELD_DELAY_DOWN: - md2->delayDown = EDIT_DELAY(y, event, attr, STR_DELAYDOWN, md2->delayDown, (md2->delayPrec ? PREC2 : PREC1)); + md2->delayDown = editDelay(y, event, attr, STR_DELAYDOWN, md2->delayDown, (md2->delayPrec ? PREC2 : PREC1)); break; case MIX_FIELD_SLOW_PREC: @@ -202,11 +202,11 @@ void menuModelMixOne(event_t event) break; case MIX_FIELD_SLOW_UP: - md2->speedUp = EDIT_DELAY(y, event, attr, STR_SLOWUP, md2->speedUp, (md2->speedPrec ? PREC2 : PREC1)); + md2->speedUp = editDelay(y, event, attr, STR_SLOWUP, md2->speedUp, (md2->speedPrec ? PREC2 : PREC1)); break; case MIX_FIELD_SLOW_DOWN: - md2->speedDown = EDIT_DELAY(y, event, attr, STR_SLOWDOWN, md2->speedDown, (md2->speedPrec ? PREC2 : PREC1)); + md2->speedDown = editDelay(y, event, attr, STR_SLOWDOWN, md2->speedDown, (md2->speedPrec ? PREC2 : PREC1)); break; } y += FH; diff --git a/radio/src/gui/212x64/model_setup.cpp b/radio/src/gui/212x64/model_setup.cpp index a1fc5652f..db48b1fe4 100644 --- a/radio/src/gui/212x64/model_setup.cpp +++ b/radio/src/gui/212x64/model_setup.cpp @@ -459,13 +459,13 @@ void onBluetoothConnectMenu(const char * result) } #endif -#include "common/stdlcd/model_setup_pxx1.cpp" +#include "model_setup_pxx1.cpp" #if defined(PXX2) -#include "common/stdlcd/model_setup_pxx2.cpp" +#include "model_setup_pxx2.cpp" #endif #if defined(AFHDS3) -#include "common/stdlcd/model_setup_afhds3.cpp" +#include "model_setup_afhds3.cpp" #endif #if defined(USBJ_EX) @@ -1358,7 +1358,7 @@ void menuModelSetup(event_t event) } if (bluetooth.distantAddr[0]) { lcdDrawText(INDENT_WIDTH, y+1, bluetooth.distantAddr, TINSIZE); - lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_CLEAR, attr); + lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_CLEAR_BTN, attr); if (attr && event == EVT_KEY_BREAK(KEY_ENTER)) { bluetooth.state = BLUETOOTH_STATE_CLEAR_REQUESTED; memclear(bluetooth.distantAddr, sizeof(bluetooth.distantAddr)); diff --git a/radio/src/gui/212x64/model_special_functions.cpp b/radio/src/gui/212x64/model_special_functions.cpp index 0e08e6643..f2c63b15e 100644 --- a/radio/src/gui/212x64/model_special_functions.cpp +++ b/radio/src/gui/212x64/model_special_functions.cpp @@ -288,7 +288,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF } else { TelemetrySensor * sensor = & g_model.telemetrySensors[param-FUNC_RESET_PARAM_FIRST_TELEM]; - lcdDrawSizedText(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, sensor->label, TELEM_LABEL_LEN, attr|ZCHAR); + lcdDrawSizedText(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, sensor->label, TELEM_LABEL_LEN, attr); } if (active) INCDEC_ENABLE_CHECK(functionsContext == &globalFunctionsContext ? isSourceAvailableInGlobalResetSpecialFunction : isSourceAvailableInResetSpecialFunction); } diff --git a/radio/src/gui/212x64/model_telemetry.cpp b/radio/src/gui/212x64/model_telemetry.cpp index 4f7dac8d1..f5adc4b5e 100644 --- a/radio/src/gui/212x64/model_telemetry.cpp +++ b/radio/src/gui/212x64/model_telemetry.cpp @@ -147,7 +147,7 @@ void menuModelTelemetry(event_t event) int index = k - ITEM_TELEMETRY_SENSOR_FIRST; lcdDrawNumber(INDENT_WIDTH, y, index+1, LEFT|attr); lcdDrawChar(lcdLastRightPos, y, ':', attr); - lcdDrawSizedText(3*FW, y, g_model.telemetrySensors[index].label, TELEM_LABEL_LEN, ZCHAR); + lcdDrawSizedText(3*FW, y, g_model.telemetrySensors[index].label, TELEM_LABEL_LEN); if (telemetryItems[index].isFresh()) { lcdDrawChar(10*FW, y, '*'); } diff --git a/radio/src/gui/212x64/popups.h b/radio/src/gui/212x64/popups.h index e4d479e58..8ca0e53b9 100644 --- a/radio/src/gui/212x64/popups.h +++ b/radio/src/gui/212x64/popups.h @@ -33,13 +33,4 @@ #define WARNING_LINE_X 16 #define WARNING_LINE_Y MESSAGEBOX_Y + 2 -#define POPUP_MENU_MAX_LINES 13 -#define MENU_MAX_DISPLAY_LINES 6 -#define MENU_LINE_LENGTH (LEN_MODEL_NAME+12) - -enum { - MENU_OFFSET_INTERNAL, - MENU_OFFSET_EXTERNAL -}; - -#include "common/stdlcd/popups_common.h" +#include "popups_common.h" diff --git a/radio/src/gui/212x64/radio_calibration.cpp b/radio/src/gui/212x64/radio_calibration.cpp index e02f200ed..14edbe079 100644 --- a/radio/src/gui/212x64/radio_calibration.cpp +++ b/radio/src/gui/212x64/radio_calibration.cpp @@ -21,7 +21,7 @@ #include "edgetx.h" #include "hal/adc_driver.h" -#include "gui/common/stdlcd/calibration.h" +#include "calibration.h" #define XPOT_DELTA 10 #define XPOT_DELAY 10 /* cycles */ diff --git a/radio/src/gui/212x64/view_channels.cpp b/radio/src/gui/212x64/view_channels.cpp index 01d505257..1d3e1f4cd 100644 --- a/radio/src/gui/212x64/view_channels.cpp +++ b/radio/src/gui/212x64/view_channels.cpp @@ -84,7 +84,7 @@ void menuChannelsView(event_t event) if (lenLabel > 0) { if (lenLabel > 4) viewChannels.longNames = true; - lcdDrawSizedText(x+1-ofs, y, g_model.limitData[ch].name, sizeof(g_model.limitData[ch].name), ZCHAR | SMLSIZE); + lcdDrawSizedText(x+1-ofs, y, g_model.limitData[ch].name, sizeof(g_model.limitData[ch].name), SMLSIZE); } else { putsChn(x+1-ofs, y, ch+1, SMLSIZE); diff --git a/radio/src/gui/212x64/view_main.cpp b/radio/src/gui/212x64/view_main.cpp index acbe07a73..610c86f06 100644 --- a/radio/src/gui/212x64/view_main.cpp +++ b/radio/src/gui/212x64/view_main.cpp @@ -40,7 +40,6 @@ #define BITMAP_Y (LCD_H/2) #define PHASE_X BITMAP_X #define PHASE_Y (3*FH) -#define PHASE_FLAGS (0) #define TIMERS_X 145 #define TIMERS_Y 20 #define TIMERS_H 25 @@ -54,7 +53,6 @@ #define TRIM_RH_X (LCD_W-32-9) #define TRIM_LEN 27 -#define MARKER_WIDTH 5 const unsigned char logo_taranis[] = { #include "logo.lbm" @@ -358,7 +356,7 @@ void displayTimers() TimerData & timerData = g_model.timers[i]; uint8_t y = TIMERS_Y + i*TIMERS_H; if (ZLEN(timerData.name) > 0) { - lcdDrawSizedText(TIMERS_X, y-7, timerData.name, LEN_TIMER_NAME, ZCHAR|SMLSIZE); + lcdDrawSizedText(TIMERS_X, y-7, timerData.name, LEN_TIMER_NAME, SMLSIZE); } else { lcdDrawTextAtIndex(TIMERS_X, y-7, STR_VTMRMODES, timerData.mode, SMLSIZE); @@ -519,7 +517,7 @@ void menuMainView(event_t event) // Flight Mode Name int mode = mixerCurrentFlightMode; - lcdDrawSizedText(PHASE_X, PHASE_Y, g_model.flightModeData[mode].name, sizeof(g_model.flightModeData[mode].name), ZCHAR|PHASE_FLAGS); + lcdDrawSizedText(PHASE_X, PHASE_Y, g_model.flightModeData[mode].name, sizeof(g_model.flightModeData[mode].name)); // Model Name drawModelName(MODELNAME_X, MODELNAME_Y, g_model.header.name, g_eeGeneral.currModel, BIGSIZE); @@ -621,7 +619,7 @@ void menuMainView(event_t event) lcdDrawFilledRect(BITMAP_X, BITMAP_Y, 64, 32, SOLID, ERASE); lcdDrawRect(BITMAP_X, BITMAP_Y, 64, 32); drawStringWithIndex(BITMAP_X+FW, BITMAP_Y+FH-1, STR_GV, gvarLastChanged+1); - lcdDrawSizedText(BITMAP_X+4*FW+FW/2, BITMAP_Y+FH-1, g_model.gvars[gvarLastChanged].name, LEN_GVAR_NAME, ZCHAR); + lcdDrawSizedText(BITMAP_X+4*FW+FW/2, BITMAP_Y+FH-1, g_model.gvars[gvarLastChanged].name, LEN_GVAR_NAME); lcdDrawText(BITMAP_X+FW, BITMAP_Y+2*FH+3, "[", BOLD); drawGVarValue(BITMAP_X+2*FW, BITMAP_Y+2*FH+3, gvarLastChanged, GVAR_VALUE(gvarLastChanged, getGVarFlightMode(mixerCurrentFlightMode, gvarLastChanged)), LEFT|BOLD); lcdDrawText(lcdLastRightPos, BITMAP_Y+2*FH+3, "]", BOLD); diff --git a/radio/src/gui/212x64/widgets.cpp b/radio/src/gui/212x64/widgets.cpp index fe0114a42..7c2dcb29f 100644 --- a/radio/src/gui/212x64/widgets.cpp +++ b/radio/src/gui/212x64/widgets.cpp @@ -21,207 +21,9 @@ #include "edgetx.h" -void drawStick(coord_t centrex, int16_t xval, int16_t yval) -{ -#define BOX_CENTERY (LCD_H-BOX_WIDTH/2-10) -#define MARKER_WIDTH 5 - lcdDrawSquare(centrex-BOX_WIDTH/2, BOX_CENTERY-BOX_WIDTH/2, BOX_WIDTH); - lcdDrawSolidVerticalLine(centrex, BOX_CENTERY-1, 3); - lcdDrawSolidHorizontalLine(centrex-1, BOX_CENTERY, 3); - 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); -#undef BOX_CENTERY -#undef MARKER_WIDTH -} - void drawColumnHeader(const char * const *headers, uint8_t index) { lcdDrawText(16*FW+3, 0, " ", 0); lcdDrawText(17*FW, 0, headers[index], 0); lcdDrawText(lcdNextPos, 0, " ", 0); } - -void drawCheckBox(coord_t x, coord_t y, uint8_t value, LcdFlags attr) -{ - if (value) - lcdDrawChar(x+1, y, '#'); - if (attr) - lcdDrawFilledRect(x, y, 7, 7); - else - lcdDrawSquare(x, y, 7); -} - -void drawScreenIndex(uint8_t index, uint8_t count, uint8_t attr) -{ - lcdDrawNumber(LCD_W, 0, count, RIGHT | attr); - coord_t x = 1+LCD_W-FW*(count>9 ? 3 : 2); - lcdDrawChar(x, 0, '/', attr); - lcdDrawNumber(x, 0, index+1, RIGHT | attr); -} - -void drawVerticalScrollbar(coord_t x, coord_t y, coord_t h, uint16_t offset, uint16_t count, uint8_t visible) -{ - lcdDrawVerticalLine(x, y, h, DOTTED); - coord_t yofs = (h * offset) / count; - coord_t yhgt = (h * visible) / count; - if (yhgt + yofs > h) - yhgt = h - yofs; - lcdDrawVerticalLine(x, y + yofs, yhgt, SOLID, FORCE); -} - -void drawGauge(coord_t x, coord_t y, coord_t w, coord_t h, int32_t val, int32_t max) -{ - lcdDrawRect(x, y, w+1, h); - lcdDrawFilledRect(x+1, y+1, w-1, 4, SOLID, ERASE); - coord_t len = limit((uint8_t)1, uint8_t((abs(val) * w/2 + max/2) / max), uint8_t(w/2)); - coord_t x0 = (val>0) ? x+w/2 : x+1+w/2-len; - for (coord_t i=h-2; i>0; i--) { - lcdDrawSolidHorizontalLine(x0, y+i, len); - } -} - -void title(const char * s) -{ - lcdDrawText(0, 0, s, INVERS); -} - -choice_t editChoice(coord_t x, coord_t y, const char * label, const char* const* values, choice_t value, choice_t min, choice_t max, LcdFlags attr, event_t event, coord_t lblX, IsValueAvailable isValueAvailable) -{ - if (label) { - lcdDrawText(lblX, y, label); - } - if (values) lcdDrawTextAtIndex(x, y, values, value-min, attr); - if (attr & (~RIGHT)) value = checkIncDec(event, value, min, max, (isModelMenuDisplayed()) ? EE_MODEL : EE_GENERAL, isValueAvailable); - return value; -} - -choice_t editChoice(coord_t x, coord_t y, const char * label, const char* const* values, choice_t value, choice_t min, choice_t max, LcdFlags attr, event_t event, coord_t lblX) -{ - return editChoice(x, y, label, values, value, min, max, attr, event, lblX, nullptr); -} - -uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const char *label, LcdFlags attr, event_t event, coord_t lblX) -{ - drawCheckBox(x, y, value, attr); - return editChoice(x, y, label, nullptr, value, 0, 1, attr, event, lblX); -} - -swsrc_t editSwitch(coord_t x, coord_t y, swsrc_t value, LcdFlags attr, event_t event) -{ - lcdDrawTextAlignedLeft(y, STR_SWITCH); - drawSwitch(x, y, value, attr); - if (attr & (~RIGHT)) CHECK_INCDEC_MODELSWITCH(event, value, SWSRC_FIRST_IN_MIXES, SWSRC_LAST_IN_MIXES, isSwitchAvailableInMixes); - return value; -} - -void drawSlider(coord_t x, coord_t y, uint8_t value, uint8_t max, uint8_t attr) -{ - lcdDrawChar(x+(value*4*FW)/max, y, '$'); - lcdDrawSolidHorizontalLine(x, y+3, 5*FW-1, FORCE); - if (attr && (!(attr & BLINK) || !BLINK_ON_PHASE)) lcdDrawFilledRect(x, y, 5*FW-1, FH-1); -} - -uint16_t editSrcVarFieldValue(coord_t x, coord_t y, const char* title, uint16_t value, - int16_t min, int16_t max, LcdFlags attr, event_t event, - IsValueAvailable isValueAvailable, int16_t sourceMin, int16_t sourceMax) -{ - if (title) - lcdDrawTextAlignedLeft(y, title); - SourceNumVal v; - v.rawValue = value; - if (v.isSource) { - drawSource(x, y, v.value, attr); - if (attr & (~RIGHT)) { - value = checkIncDec(event, value, sourceMin, sourceMax, - EE_MODEL|INCDEC_SOURCE|INCDEC_SOURCE_VALUE|INCDEC_SOURCE_INVERT|NO_INCDEC_MARKS, isValueAvailable); - } - } else { - lcdDrawNumber(x, y, v.value, attr); - if (attr & (~RIGHT)) { - value = checkIncDec(event, value, min, max, sourceMin, sourceMax, - EE_MODEL|INCDEC_SOURCE_VALUE|NO_INCDEC_MARKS|INCDEC_SKIP_VAL_CHECK_FUNC, - isValueAvailable); - } - } - return value; -} - -#if defined(GVARS) -void drawGVarValue(coord_t x, coord_t y, uint8_t gvar, gvar_t value, LcdFlags flags) -{ - uint8_t prec = g_model.gvars[gvar].prec; - if (prec > 0) { - flags |= (prec == 1 ? PREC1 : PREC2); - } - drawValueWithUnit(x, y, value, g_model.gvars[gvar].unit ? UNIT_PERCENT : UNIT_RAW, flags); -} - -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) -{ - bool invers = (attr & INVERS); - - // TRACE("editGVarFieldValue(val=%d min=%d max=%d)", value, min, max); - - if (modelGVEnabled() && invers && event == EVT_KEY_LONG(KEY_ENTER)) { - killEvents(event); - s_editMode = !s_editMode; - if (attr & PREC1) { - value = (GV_IS_GV_VALUE(value) ? GET_GVAR(value, min, max, mixerCurrentFlightMode)*10 : GV_VALUE_FROM_INDEX(0)); - } - else { - value = (GV_IS_GV_VALUE(value) ? GET_GVAR(value, min, max, mixerCurrentFlightMode) : GV_VALUE_FROM_INDEX(0)); - } - storageDirty(EE_MODEL); - } - - if (GV_IS_GV_VALUE(value)) { - attr &= ~PREC1; - int8_t idx = (int16_t)GV_INDEX_FROM_VALUE(value); - if (invers) { - CHECK_INCDEC_MODELVAR(event, idx, -MAX_GVARS, MAX_GVARS-1); - } - value = (int16_t)GV_VALUE_FROM_INDEX(idx); - drawGVarName(x, y, idx, attr); - } - else { - lcdDrawNumber(x, y, value, attr); - if (invers) value = checkIncDec(event, value, min, max, EE_MODEL | editflags); - } - return value; -} -#else -int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int16_t max, LcdFlags attr, event_t event) -{ - lcdDrawNumber(x, y, value, attr); - if (attr&INVERS) value = checkIncDec(event, value, min, max, EE_MODEL); - return value; -} -#endif - -char statusLineMsg[STATUS_LINE_LENGTH]; -tmr10ms_t statusLineTime = 0; -uint8_t statusLineHeight = 0; - -void showStatusLine() -{ - statusLineTime = get_tmr10ms(); -} - -#define STATUS_LINE_DELAY (3 * 100) /* 3s */ -void drawStatusLine() -{ - if (statusLineTime) { - if ((tmr10ms_t)(get_tmr10ms() - statusLineTime) <= (tmr10ms_t)STATUS_LINE_DELAY) { - if (statusLineHeight < FH) statusLineHeight++; - } - else if (statusLineHeight) { - statusLineHeight--; - } - else { - statusLineTime = 0; - } - - lcdDrawFilledRect(0, LCD_H-statusLineHeight, LCD_W, FH, SOLID, ERASE); - lcdDrawText(5, LCD_H+1-statusLineHeight, statusLineMsg, 0); - lcdDrawFilledRect(0, LCD_H-statusLineHeight, LCD_W, FH, SOLID); - } -} diff --git a/radio/src/gui/CMakeLists.txt b/radio/src/gui/CMakeLists.txt index 836ad3cff..c30facaf9 100644 --- a/radio/src/gui/CMakeLists.txt +++ b/radio/src/gui/CMakeLists.txt @@ -7,6 +7,7 @@ if(NOT GUI_DIR STREQUAL colorlcd) gui/navigation/common.cpp gui/navigation/navigation.cpp ) + include_directories(gui gui/common/stdlcd) endif() set(SRC diff --git a/radio/src/gui/common/stdlcd/CMakeLists.txt b/radio/src/gui/common/stdlcd/CMakeLists.txt index b58311f3a..a9e4328e2 100644 --- a/radio/src/gui/common/stdlcd/CMakeLists.txt +++ b/radio/src/gui/common/stdlcd/CMakeLists.txt @@ -1,10 +1,12 @@ set(GUI_SRC ${GUI_SRC} - ../common/stdlcd/menus.cpp + ../common/stdlcd/menu_model.cpp + ../common/stdlcd/menu_radio.cpp + ../common/stdlcd/menus_common.cpp ../common/stdlcd/draw_functions.cpp ../common/stdlcd/fonts.cpp ../common/stdlcd/utf8.cpp - ../common/stdlcd/popups.cpp + ../common/stdlcd/popups_common.cpp ../common/stdlcd/model_inputs.cpp ../common/stdlcd/model_mixes.cpp ../common/stdlcd/view_text.cpp @@ -17,6 +19,8 @@ set(GUI_SRC ../common/stdlcd/calibration.cpp ../common/stdlcd/splash.cpp ../common/stdlcd/radio_sdmanager.cpp + ../common/stdlcd/widgets_common.cpp + ../common/stdlcd/lcd_common.cpp model_curve_edit.cpp ) diff --git a/radio/src/gui/common/stdlcd/draw_functions.cpp b/radio/src/gui/common/stdlcd/draw_functions.cpp index a7d4a73cd..b5df73b75 100644 --- a/radio/src/gui/common/stdlcd/draw_functions.cpp +++ b/radio/src/gui/common/stdlcd/draw_functions.cpp @@ -173,6 +173,8 @@ static int nameCharIdx(char v) return 0; } +uint8_t editNameCursorPos = 0; + void editName(coord_t x, coord_t y, char* name, uint8_t size, event_t event, uint8_t active, LcdFlags attr, uint8_t old_editMode) { @@ -603,3 +605,112 @@ void drawSource(coord_t x, coord_t y, mixsrc_t idx, LcdFlags att) lcdDrawText(x, y, s, att); } } + +void drawCheckBox(coord_t x, coord_t y, uint8_t value, LcdFlags attr) +{ + if (value) + lcdDrawChar(x+1, y, '#'); + if (attr) + lcdDrawSolidFilledRect(x, y, 7, 7); + else + lcdDrawSquare(x, y, 7); +} + +void drawScreenIndex(uint8_t index, uint8_t count, uint8_t attr) +{ + lcdDrawNumber(LCD_W, 0, count, RIGHT | attr); + coord_t x = 1+LCD_W-FW*(count>9 ? 3 : 2); + lcdDrawChar(x, 0, '/', attr); + lcdDrawNumber(x, 0, index+1, RIGHT | attr); +} + +void drawVerticalScrollbar(coord_t x, coord_t y, coord_t h, uint16_t offset, uint16_t count, uint8_t visible) +{ + lcdDrawVerticalLine(x, y, h, DOTTED); + coord_t yofs = (h * offset) / count; + coord_t yhgt = (h * visible) / count; + if (yhgt + yofs > h) + yhgt = h - yofs; + lcdDrawVerticalLine(x, y + yofs, yhgt, SOLID, FORCE); +} + +void title(const char * s) +{ + lcdDrawText(0, 0, s, INVERS); +} + +#if defined(GVARS) +void drawGVarValue(coord_t x, coord_t y, uint8_t gvar, gvar_t value, LcdFlags flags) +{ + uint8_t prec = g_model.gvars[gvar].prec; + if (prec > 0) { + flags |= (prec == 1 ? PREC1 : PREC2); + } + drawValueWithUnit(x, y, value, g_model.gvars[gvar].unit ? UNIT_PERCENT : UNIT_RAW, flags); +} +#endif + +char statusLineMsg[STATUS_LINE_LENGTH]; +static tmr10ms_t statusLineTime = 0; +static uint8_t statusLineHeight = 0; + +void showStatusLine() +{ + statusLineTime = get_tmr10ms(); +} + +#define STATUS_LINE_DELAY (3 * 100) /* 3s */ +void drawStatusLine() +{ + if (statusLineTime) { + if ((tmr10ms_t)(get_tmr10ms() - statusLineTime) <= (tmr10ms_t)STATUS_LINE_DELAY) { + if (statusLineHeight < FH) statusLineHeight++; + } + else if (statusLineHeight) { + statusLineHeight--; + } + else { + statusLineTime = 0; + } + + lcdDrawFilledRect(0, LCD_H-statusLineHeight, LCD_W, FH, SOLID, ERASE); + lcdDrawText(5, LCD_H+1-statusLineHeight, statusLineMsg); + lcdDrawFilledRect(0, LCD_H-statusLineHeight, LCD_W, FH, SOLID); + } +} + +void drawGauge(coord_t x, coord_t y, coord_t w, coord_t h, int32_t val, int32_t max) +{ +#if defined(PCBX7) || defined(PCBX9LITE) || defined(PCBX9LITES) // X7/X9 LCD doesn't like too many horizontal lines + h++; +#else + lcdDrawRect(x, y, w+1, h); +#endif + lcdDrawFilledRect(x+1, y+1, w-1, 4, SOLID, ERASE); + coord_t len = limit((uint8_t)1, uint8_t((abs(val) * w/2 + max/2) / max), uint8_t(w/2)); + coord_t x0 = (val>0) ? x+w/2 : x+1+w/2-len; + for (coord_t i=h-2; i>0; i--) + lcdDrawSolidHorizontalLine(x0, y+i, len); +} + +void drawSlider(coord_t x, coord_t y, uint8_t width, uint8_t value, uint8_t max, uint8_t attr) +{ + lcdDrawChar(x + (value * (width - FWNUM)) / max, y, '$'); + lcdDrawSolidHorizontalLine(x, y + 3, width, FORCE); + if (attr && (!(attr & BLINK) || !BLINK_ON_PHASE)) { + lcdDrawSolidFilledRect(x, y, width, FH - 1); + } +} + +void drawSlider(coord_t x, coord_t y, uint8_t value, uint8_t max, uint8_t attr) +{ + drawSlider(x, y, 5*FW - 1, value, max, attr); +} + +void drawStick(coord_t centrex, int16_t xval, int16_t yval) +{ + lcdDrawSquare(centrex-BOX_WIDTH/2, BOX_CENTERY-BOX_WIDTH/2, BOX_WIDTH); + lcdDrawSolidVerticalLine(centrex, BOX_CENTERY-1, 3); + lcdDrawSolidHorizontalLine(centrex-1, BOX_CENTERY, 3); + 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); +} diff --git a/radio/src/gui/common/stdlcd/draw_functions.h b/radio/src/gui/common/stdlcd/draw_functions.h index 0f22d8548..fe4ab6665 100644 --- a/radio/src/gui/common/stdlcd/draw_functions.h +++ b/radio/src/gui/common/stdlcd/draw_functions.h @@ -55,3 +55,22 @@ void drawCursor(FnFuncP fn, uint8_t offset = 0); void drawCurve(coord_t offset = 0); void drawSource(coord_t x, coord_t y, mixsrc_t idx, LcdFlags att=0); + +void drawCheckBox(coord_t x, coord_t y, uint8_t value, LcdFlags attr); +void drawScreenIndex(uint8_t index, uint8_t count, uint8_t attr); +void drawVerticalScrollbar(coord_t x, coord_t y, coord_t h, uint16_t offset, uint16_t count, uint8_t visible); +void drawGauge(coord_t x, coord_t y, coord_t w, coord_t h, int32_t val, int32_t max); +#if defined(GVARS) +void drawGVarValue(coord_t x, coord_t y, uint8_t gvar, gvar_t value, LcdFlags flags = 0); +#endif + +void drawStick(coord_t centrex, int16_t xval, int16_t yval); +void drawSlider(coord_t x, coord_t y, uint8_t width, uint8_t value, uint8_t max, uint8_t attr); +void drawSlider(coord_t x, coord_t y, uint8_t value, uint8_t max, uint8_t attr); + +void title(const char * s); + +#define STATUS_LINE_LENGTH 32 +extern char statusLineMsg[STATUS_LINE_LENGTH]; +void showStatusLine(); +void drawStatusLine(); diff --git a/radio/src/gui/common/stdlcd/features.h b/radio/src/gui/common/stdlcd/feature_control.h similarity index 100% rename from radio/src/gui/common/stdlcd/features.h rename to radio/src/gui/common/stdlcd/feature_control.h diff --git a/radio/src/gui/common/stdlcd/lcd_common.cpp b/radio/src/gui/common/stdlcd/lcd_common.cpp new file mode 100644 index 000000000..893f9ff95 --- /dev/null +++ b/radio/src/gui/common/stdlcd/lcd_common.cpp @@ -0,0 +1,533 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +#include "lcd.h" +#include "fonts.h" +#include "utf8.h" + +#if !defined(SIMU) + #define assert(x) +#else + #include +#endif + +#if !defined(BOOT) + #include "edgetx.h" +#endif + +pixel_t displayBuf[DISPLAY_BUFFER_SIZE] __DMA; + +coord_t lcdLastRightPos; +coord_t lcdLastLeftPos; +coord_t lcdNextPos; + +void lcdFlushed() {} + +void lcdClear() +{ + memset(displayBuf, 0, DISPLAY_BUFFER_SIZE * sizeof(pixel_t)); +} + +LcdFlags getCharPattern(PatternData * pattern, unsigned char c, LcdFlags flags) +{ +#if !defined(BOOT) + static const uint8_t fontWidth[] = { 5, 3, 5, 8, 10, 22, 5 }; + static const uint8_t fontHeight[] = { 7, 5, 6, 12, 16, 38, 7 }; + + uint32_t fontsize = FONTSIZE(flags); + unsigned char c_remapped = 0; + + if (fontsize == DBLSIZE || (flags & BOLD)) { + // To save space only some DBLSIZE and BOLD chars are available + // c has to be remapped. All non existing chars mapped to 0 (space) + if (c >= ',' && c <= ':') + c_remapped = c - ',' + 1; + else if (c >= 'A' && c <= 'Z') + c_remapped = c - 'A' + 16; + else if (c >= 'a' && c <= 'z') + c_remapped = c - 'a' + 42; + else if (c == '_') + c_remapped = 4; + else if (c != ' ') + flags &= ~BOLD; // For BOLD use Standard font if character is not in BOLD + } + + uint8_t fontIdx = fontsize >> 8; + if (fontIdx == 0 && flags & BOLD) fontIdx = 6; + + pattern->width = fontWidth[fontIdx]; + pattern->height = fontHeight[fontIdx]; + int charSize = (pattern->height + 7) / 8 * pattern->width; + + switch (fontIdx) { + case 0: // Standard + pattern->data = &font_5x7[(c - FONT_BASE_START) * charSize]; + break; + case 1: // TINSIZE + pattern->data = &font_3x5[(c - FONT_BASE_START) * charSize]; + break; + case 2: // SMLSIZE + // Adjust language special characters offset + if (c >= FONT_LANG_START) + c = c - (FONT_SYMS_CNT - FONT_SYMS_CNT_4x6); + pattern->data = &font_4x6[(c - FONT_BASE_START) * charSize]; + break; + case 3: // MDLSIZE + // Adjust language special characters offset + if (c >= FONT_LANG_START) + c = c - FONT_SYMS_CNT; + pattern->data = &font_8x10[(c - FONT_BASE_START) * charSize]; + break; + case 4: // DBLSIZE + // Adjust language special characters offset and symbols offset + if (c >= FONT_LANG_START) + c_remapped = c - (FONT_BASE_CNT - FONT_BASE_CNT_10x14) - (FONT_SYMS_CNT - FONT_SYMS_CNT_10x14) - FONT_BASE_START; + else if (c >= FONT_SYMS_START) + c_remapped = c - (FONT_BASE_CNT - FONT_BASE_CNT_10x14) - FONT_BASE_START; + pattern->data = &font_10x14[(c_remapped) * charSize]; + break; + case 5: // XXLSIZE + pattern->data = &font_22x38_num[(c - '0' + 5) * charSize]; + break; + case 6: // BOLD + pattern->data = &font_5x7_B[c_remapped * charSize]; + break; + }; +#else + pattern->width = 5; + pattern->height = 7; + pattern->data = &font_5x7[(c - FONT_BASE_START) * 5]; +#endif + return flags; +} + +static uint8_t getPatternWidth(const PatternData * pattern) +{ + uint8_t result = 0; + uint8_t lines = (pattern->height+7)/8; + const uint8_t * data = pattern->data; + for (int8_t i=0; iwidth; i++) { + for (uint8_t j=0; j= 0 && x < LCD_W) { + uint8_t b[5] = { 0 }; + if (i==0) { + if (x==0 || !inv) { + lcdNextPos++; + continue; + } + else { + // we need to work on the previous x when INVERS + x--; + } + } + else if (i<=width) { + uint8_t skip = true; + for (uint8_t j=0; j= 12) continue; + if (j<0 && !inv) continue; + if (y+j < 0) continue; + } + else { + uint8_t line = (j / 8); + uint8_t pixel = (j % 8); + plot = b[line] & (1 << pixel); + } + if (inv) plot = !plot; + if (!blink) { + if (flags & VERTICAL) + lcdDrawPoint(y+j, LCD_H-x, plot ? FORCE : ERASE); + else + lcdDrawPoint(x, y+j, plot ? FORCE : ERASE); + } + } + } + x++; + lcdNextPos++; + } +} + +void lcdDrawChar(coord_t x, coord_t y, uint8_t c, LcdFlags flags) +{ + lcdNextPos = x - 1; + PatternData pattern; + flags = getCharPattern(&pattern, c, flags); + lcdPutPattern(x, y, pattern.data, pattern.width, pattern.height, flags); +} + +void lcdDrawChar(coord_t x, coord_t y, uint8_t c) +{ + lcdDrawChar(x, y, c, 0); +} + +void lcdDrawSizedText(coord_t x, coord_t y, const char * s, uint8_t len) +{ + lcdDrawSizedText(x, y, s, len, 0); +} + +void lcdDrawText(coord_t x, coord_t y, const char * s, LcdFlags flags) +{ + lcdDrawSizedText(x, y, s, 255, flags); +} + +void lcdDrawCenteredText(coord_t y, const char * s, LcdFlags flags) +{ + coord_t x = (LCD_W - getTextWidth(s, flags)) / 2; + lcdDrawText(x, y, s, flags); +} + +void lcdDrawText(coord_t x, coord_t y, const char * s) +{ + lcdDrawText(x, y, s, 0); +} + +void lcdDrawTextAlignedLeft(coord_t y, const char * s) +{ + lcdDrawText(0, y, s); +} + +void lcdDrawTextIndented(coord_t y, const char * s) +{ + lcdDrawText(INDENT_WIDTH, y, s); +} + +#if !defined(BOOT) +void lcdDrawTextAtIndex(coord_t x, coord_t y, const char *const *s,uint8_t idx, LcdFlags flags) +{ + lcdDrawSizedText(x, y, s[idx], UINT8_MAX, flags); +} + +void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags flags) +{ + lcdDrawNumber(x, y, val, flags, 0); +} + +void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags flags, uint8_t len) +{ + char str[16+1]; + char *s = str+16; + *s = '\0'; + int idx = 0; + int mode = MODE(flags); + bool neg = false; + + if (val == INT_MAX) { + flags &= ~(LEADING0 | PREC1 | PREC2); + lcdDrawText(x, y, "INT_MAX", flags); + return; + } + + if (val < 0) { + if (val == INT_MIN) { + flags &= ~(LEADING0 | PREC1 | PREC2); + lcdDrawText(x, y, "INT_MIN", flags); + return; + } + val = -val; + neg = true; + } + do { + *--s = '0' + (val % 10); + ++idx; + val /= 10; + if (mode!=0 && idx==mode) { + mode = 0; + *--s = '.'; + if (val==0) { + *--s = '0'; + } + } + } while (val!=0 || mode>0 || (mode==MODE(LEADING0) && idx0 && !name[len-1]) --len; + if (len==0) { + drawStringWithIndex(x, y, STR_MODEL, id+1, att|LEADING0); + } + else { + lcdDrawSizedText(x, y, name, sizeof(g_model.header.name), att); + } +} + +void drawSwitch(coord_t x, coord_t y, swsrc_t idx, LcdFlags flags, bool autoBold) +{ + char s[8]; + getSwitchPositionName(s, idx); + if (autoBold && idx != SWSRC_NONE && getSwitch(idx)) + flags |= BOLD; + lcdDrawText(x, y, s, flags); +} + +void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags att) +{ + char s[8]; + getCurveString(s, idx); + lcdDrawText(x, y, s, att); +} + +void drawTimerMode(coord_t x, coord_t y, swsrc_t mode, LcdFlags att) +{ + if (mode >= 0) { + if (mode < TMRMODE_COUNT) + return lcdDrawTextAtIndex(x, y, STR_VTMRMODES, mode, att); + else + mode -= (TMRMODE_COUNT-1); + } + drawSwitch(x, y, mode, att); +} + +#if defined(RTCLOCK) +void drawRtcTime(coord_t x, coord_t y, LcdFlags att) +{ + drawTimer(x, y, getValue(MIXSRC_TX_TIME), att, att); +} +#endif + +void lcdDrawFilledRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat, LcdFlags att) +{ + for (coord_t i=y; i> 1) + ((pat & 1) << 7); + } +} + +void lcdDrawLine(coord_t x1, coord_t y1, coord_t x2, coord_t y2, uint8_t pat, LcdFlags att) +{ + int dx = x2-x1; /* the horizontal distance of the line */ + int dy = y2-y1; /* the vertical distance of the line */ + int dxabs = abs(dx); + int dyabs = abs(dy); + int sdx = sgn(dx); + int sdy = sgn(dy); + int x = dyabs>>1; + int y = dxabs>>1; + int px = x1; + int py = y1; + + if (dxabs >= dyabs) { + /* the line is more horizontal than vertical */ + for (int i=0; i<=dxabs; i++) { + if ((1<<(px%8)) & pat) { + lcdDrawPoint(px, py, att); + } + y += dyabs; + if (y>=dxabs) { + y -= dxabs; + py += sdy; + } + px += sdx; + } + } + else { + /* the line is more vertical than horizontal */ + for (int i=0; i<=dyabs; i++) { + if ((1<<(py%8)) & pat) { + lcdDrawPoint(px, py, att); + } + x += dxabs; + if (x >= dyabs) { + x -= dyabs; + px += sdx; + } + py += sdy; + } + } +} +#endif // !BOOT + +void lcdDrawSolidVerticalLine(coord_t x, coord_t y, coord_t h, LcdFlags att) +{ + lcdDrawVerticalLine(x, y, h, SOLID, att); +} + +void lcdDrawRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat, LcdFlags att) +{ + lcdDrawVerticalLine(x, y, h, pat, att); + lcdDrawVerticalLine(x+w-1, y, h, pat, att); + if (~att & ROUND) { x+=1; w-=2; } + lcdDrawHorizontalLine(x, y+h-1, w, pat, att); + lcdDrawHorizontalLine(x, y, w, pat, att); +} + +void lcdDrawSolidHorizontalLine(coord_t x, coord_t y, coord_t w, LcdFlags att) +{ + if (w < 0) { x += w; w = -w; } + lcdDrawHorizontalLine(x, y, w, 0xff, att); +} diff --git a/radio/src/gui/common/stdlcd/lcd_common.h b/radio/src/gui/common/stdlcd/lcd_common.h new file mode 100644 index 000000000..de0fb2754 --- /dev/null +++ b/radio/src/gui/common/stdlcd/lcd_common.h @@ -0,0 +1,175 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#pragma once + +#define OFS_CHECKTRIMS CENTER_OFS+(9*FW) +#define INDENT_WIDTH (FW/2) + +#define FW 6 +#define FWNUM 5 +#define FH 8 + +#define LCD_LINES (LCD_H/FH) +#define LCD_COLS (LCD_W/FW) + +#define NUM_BODY_LINES (LCD_LINES-1) +#define TEXT_VIEWER_LINES NUM_BODY_LINES +#define MENU_HEADER_HEIGHT FH + +#define CURVE_SIDE_WIDTH (LCD_H/2-2) +#define CURVE_CENTER_X (LCD_W-CURVE_SIDE_WIDTH-3) +#define CURVE_CENTER_Y (LCD_H/2) + +/* lcdDrawText flags */ +#define BLINK 0x01 +#define INVERS 0x02 +#define BOLD 0x40 +#define LEFT 0x00 +#define RIGHT 0x04 +#define CENTERED 0x20 +#define CONDENSED 0x08 +#define FIXEDWIDTH 0x10 +/* no 0x80 here because of "GV"1 which is aligned LEFT */ +/* no 0x10 here because of "MODEL"01 which uses LEADING0 */ + +/* lcdDrawNumber additional flags */ +#define LEADING0 0x10 +#define PREC1 0x20 +#define PREC2 0x30 +#define MODE(flags) ((((int8_t)(flags) & 0x30) - 0x10) >> 4) + +#define IS_LEFT_ALIGNED(att) !((att) & RIGHT) +#define IS_RIGHT_ALIGNED(att) (!IS_LEFT_ALIGNED(att)) + +/* line, rect, square flags */ +#define FORCE 0x02 +#define ERASE 0x04 +#define ROUND 0x08 +#define FILL_WHITE 0x10 + +/* telemetry flags */ +#define NO_UNIT 0x40 + +#define FONTSIZE_MASK 0x0700 +#define FONTSIZE(x) ((x) & FONTSIZE_MASK) +#define TINSIZE 0x0100 +#define SMLSIZE 0x0200 +#define MIDSIZE 0x0300 +#define DBLSIZE 0x0400 +#define XXLSIZE 0x0500 +#define ERASEBG 0x8000 +#define VERTICAL 0x0800 + +#define TIMEBLINK 0x1000 +#define TIMEHOUR 0x2000 +#define STREXPANDED 0x4000 + +extern pixel_t displayBuf[DISPLAY_BUFFER_SIZE]; +extern coord_t lcdLastRightPos; +extern coord_t lcdLastLeftPos; +extern coord_t lcdNextPos; + +#define DISPLAY_END (displayBuf + DISPLAY_BUFFER_SIZE) +#define IS_IN_DISPLAY(p) ((p) >= displayBuf && (p) < DISPLAY_END) +#define ASSERT_IN_DISPLAY(p) assert((p) >= displayBuf && (p) < DISPLAY_END) + +#define SOLID 0xff +#define DOTTED 0x55 + +#if defined(BOOT) + #define BLINK_ON_PHASE (0) +#else + #define SLOW_BLINK_ON_PHASE (g_blinkTmr10ms & (1<<7)) + #define BLINK_ON_PHASE (g_blinkTmr10ms & (1<<6)) + #define FAST_BLINK_ON_PHASE (g_blinkTmr10ms & (1<<4)) +#endif + +struct PatternData +{ + uint8_t width; + uint8_t height; + const uint8_t * data; +}; + +void lcdClear(); + +void lcdDrawChar(coord_t x, coord_t y, uint8_t c); +void lcdDrawChar(coord_t x, coord_t y, uint8_t c, LcdFlags flags); +void lcdDrawCenteredText(coord_t y, const char * s, LcdFlags flags = 0); +void lcdDrawText(coord_t x, coord_t y, const char * s, LcdFlags flags); +void lcdDrawTextAtIndex(coord_t x, coord_t y, const char *const *s, uint8_t idx, LcdFlags flags); +void lcdDrawSizedText(coord_t x, coord_t y, const char * s, unsigned char len, LcdFlags flags); +void lcdDrawText(coord_t x, coord_t y, const char * s); +void lcdDrawSizedText(coord_t x, coord_t y, const char * s, unsigned char len); +void lcdDrawTextAlignedLeft(coord_t y, const char * s); +void lcdDrawTextIndented(coord_t y, const char * s); + +void lcdDrawHexNumber(coord_t x, coord_t y, uint32_t val, LcdFlags mode=0); + +void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags mode, uint8_t len); +void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags mode=0); + +void drawModelName(coord_t x, coord_t y, char * name, uint8_t id, LcdFlags att); +void drawSwitch(coord_t x, coord_t y, swsrc_t swtch, LcdFlags att=0, bool autoBold = true); +void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags att=0); +void drawTimerMode(coord_t x, coord_t y, swsrc_t mode, LcdFlags att=0); + +void putsChn(coord_t x, coord_t y, uint8_t idx, LcdFlags attr); +void putsChnLetter(coord_t x, coord_t y, uint8_t idx, LcdFlags attr); + +void putsVolts(coord_t x, coord_t y, uint16_t volts, LcdFlags att); +void putsVBat(coord_t x, coord_t y, LcdFlags att); + +void lcdDrawPoint(coord_t x, coord_t y, LcdFlags att=0); +void lcdMaskPoint(uint8_t *p, uint8_t mask, LcdFlags att=0); +void lcdDrawSolidHorizontalLine(coord_t x, coord_t y, coord_t w, LcdFlags att=0); +void lcdDrawHorizontalLine(coord_t x, coord_t y, coord_t w, uint8_t pat, LcdFlags att=0); +void lcdDrawSolidVerticalLine(coord_t x, coord_t y, coord_t h, LcdFlags att=0); +void lcdDrawVerticalLine(coord_t x, coord_t y, coord_t h, uint8_t pat, LcdFlags att=0); +void lcdDrawLine(coord_t x1, coord_t y1, coord_t x2, coord_t y2, uint8_t pat=SOLID, LcdFlags att=0); + +void lcdDrawFilledRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat=SOLID, LcdFlags att=0); +void lcdDrawRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat=SOLID, LcdFlags att=0); + +inline void lcdDrawSolidFilledRect(coord_t x, coord_t y, coord_t w, coord_t h, LcdFlags att=0) +{ + lcdDrawFilledRect(x, y, w, h, SOLID, att); +} + +inline void lcdDrawSquare(coord_t x, coord_t y, coord_t w, LcdFlags att=0) +{ + lcdDrawRect(x, y, w, w, SOLID, att); +} + +void lcdInvertLine(int8_t line); +#define lcdInvertLastLine() lcdInvertLine(LCD_LINES-1) + +void drawTelemetryTopBar(); + +#define V_BAR(xx, yy, ll) \ + lcdDrawSolidVerticalLine(xx-1,yy-ll,ll); \ + lcdDrawSolidVerticalLine(xx ,yy-ll,ll); \ + lcdDrawSolidVerticalLine(xx+1,yy-ll,ll) + +void lcdDraw1bitBitmap(coord_t x, coord_t y, const unsigned char * img, uint8_t idx, LcdFlags att=0); + +uint8_t getTextWidth(const char * s, uint8_t len=0, LcdFlags flags=0); diff --git a/radio/src/gui/212x64/menu_model.cpp b/radio/src/gui/common/stdlcd/menu_model.cpp similarity index 70% rename from radio/src/gui/212x64/menu_model.cpp rename to radio/src/gui/common/stdlcd/menu_model.cpp index f6974de4f..f58523e59 100644 --- a/radio/src/gui/212x64/menu_model.cpp +++ b/radio/src/gui/common/stdlcd/menu_model.cpp @@ -34,7 +34,7 @@ const MenuHandler menuTabModel[] = { { menuModelMixAll, nullptr }, { menuModelLimits, nullptr }, { menuModelCurvesAll, modelCurvesEnabled }, -#if defined(GVARS) && defined(FLIGHT_MODES) +#if defined(GVARS) && defined(FLIGHT_MODES) && (LCD_W >= 212) { menuModelGVars, modelGVEnabled }, #endif { menuModelLogicalSwitches, modelLSEnabled }, @@ -46,16 +46,6 @@ const MenuHandler menuTabModel[] = { { menuModelDisplay, nullptr } }; -uint8_t editDelay(coord_t y, event_t event, uint8_t attr, const char * str, uint8_t delay, uint8_t prec) -{ - lcdDrawTextAlignedLeft(y, str); - lcdDrawNumber(MIXES_2ND_COLUMN, y, delay, attr|prec|LEFT); - if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, delay, DELAY_MAX); - return delay; -} - -#define COPY_MODE 1 -#define MOVE_MODE 2 uint8_t s_copyMode = 0; int8_t s_copySrcRow; int8_t s_copyTgtOfs; @@ -63,15 +53,6 @@ uint8_t s_maxLines = 8; uint8_t s_copySrcIdx; uint8_t s_copySrcCh; -uint8_t editNameCursorPos = 0; - -void editSingleName(coord_t x, coord_t y, const char * label, char *name, uint8_t size, event_t event, uint8_t active, uint8_t old_editMode, coord_t lblX) -{ - lcdDrawText(lblX, y, label); - TRACE("EDIT SINGLE NAME %s", name); - editName(x, y, name, size, event, active, 0, old_editMode); -} - uint8_t s_currIdx; uint8_t s_currIdxSubMenu; mixsrc_t s_currSrcRaw; diff --git a/radio/src/gui/128x64/menu_radio.cpp b/radio/src/gui/common/stdlcd/menu_radio.cpp similarity index 93% rename from radio/src/gui/128x64/menu_radio.cpp rename to radio/src/gui/common/stdlcd/menu_radio.cpp index 57afdae53..febadf0b3 100644 --- a/radio/src/gui/128x64/menu_radio.cpp +++ b/radio/src/gui/common/stdlcd/menu_radio.cpp @@ -42,8 +42,8 @@ void menuRadioSpecialFunctions(event_t event) } #endif - MENU(STR_MENUSPECIALFUNCS, menuTabGeneral, MENU_RADIO_SPECIAL_FUNCTIONS, HEADER_LINE+MAX_SPECIAL_FUNCTIONS, { HEADER_LINE_COLUMNS NAVIGATION_LINE_BY_LINE|5/*repeated*/ }); - + MENU(STR_MENUSPECIALFUNCS, menuTabGeneral, MENU_RADIO_SPECIAL_FUNCTIONS, + HEADER_LINE+MAX_SPECIAL_FUNCTIONS, { HEADER_LINE_COLUMNS NAVIGATION_LINE_BY_LINE|5/*repeated*/ }); menuSpecialFunctions(event, g_eeGeneral.customFn, &globalFunctionsContext); #if defined(NAVIGATION_X7) diff --git a/radio/src/gui/common/stdlcd/menus.h b/radio/src/gui/common/stdlcd/menus.h deleted file mode 100644 index f63250856..000000000 --- a/radio/src/gui/common/stdlcd/menus.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) EdgeTX - * - * Based on code named - * opentx - https://github.com/opentx/opentx - * th9x - http://code.google.com/p/th9x - * er9x - http://code.google.com/p/er9x - * gruvin9x - http://code.google.com/p/gruvin9x - * - * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#pragma once - -#include "edgetx_types.h" - -typedef int8_t horzpos_t; -typedef uint16_t vertpos_t; - -typedef void (* MenuHandlerFunc)(event_t event); -typedef bool (* MenuEnabledFunc)(); - -typedef struct _MenuHandler { - MenuHandlerFunc menuFunc; - MenuEnabledFunc enabledFunc; - - bool isEnabled() const - { - if (enabledFunc) - return enabledFunc(); - return true; - } -} MenuHandler; - -extern tmr10ms_t menuEntryTime; -extern vertpos_t menuVerticalPosition; -extern horzpos_t menuHorizontalPosition; -extern vertpos_t menuVerticalOffset; -extern uint8_t menuCalibrationState; -extern MenuHandlerFunc menuHandlers[5]; -extern uint8_t menuVerticalPositions[4]; -extern uint8_t menuVerticalOffsets[4]; -extern uint8_t menuLevel; -extern event_t menuEvent; - -void chainMenu(MenuHandlerFunc newMenu); -void pushMenu(MenuHandlerFunc newMenu); -void popMenu(); -void abortPopMenu(); - -inline MenuHandlerFunc lastPopMenu() -{ - return menuHandlers[menuLevel + 1]; -} diff --git a/radio/src/gui/common/stdlcd/menus.cpp b/radio/src/gui/common/stdlcd/menus_common.cpp similarity index 100% rename from radio/src/gui/common/stdlcd/menus.cpp rename to radio/src/gui/common/stdlcd/menus_common.cpp diff --git a/radio/src/gui/common/stdlcd/menus_common.h b/radio/src/gui/common/stdlcd/menus_common.h new file mode 100644 index 000000000..dff3e5f0f --- /dev/null +++ b/radio/src/gui/common/stdlcd/menus_common.h @@ -0,0 +1,213 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#pragma once + +#include "edgetx_types.h" +#include "keys.h" +#include "feature_control.h" + +#define COPY_MODE 1 +#define MOVE_MODE 2 +#define EDIT_MODE_INIT 0 + +typedef int8_t horzpos_t; +typedef uint16_t vertpos_t; + +typedef void (* MenuHandlerFunc)(event_t event); +typedef bool (* MenuEnabledFunc)(); + +typedef struct _MenuHandler { + MenuHandlerFunc menuFunc; + MenuEnabledFunc enabledFunc; + + bool isEnabled() const + { + if (enabledFunc) + return enabledFunc(); + return true; + } +} MenuHandler; + +extern tmr10ms_t menuEntryTime; +extern vertpos_t menuVerticalPosition; +extern horzpos_t menuHorizontalPosition; +extern vertpos_t menuVerticalOffset; +extern uint8_t menuCalibrationState; +extern MenuHandlerFunc menuHandlers[5]; +extern uint8_t menuVerticalPositions[4]; +extern uint8_t menuVerticalOffsets[4]; +extern uint8_t menuLevel; +extern event_t menuEvent; + +void chainMenu(MenuHandlerFunc newMenu); +void pushMenu(MenuHandlerFunc newMenu); +void popMenu(); +void abortPopMenu(); + +inline MenuHandlerFunc lastPopMenu() +{ + return menuHandlers[menuLevel + 1]; +} + +inline bool isRadioMenuDisplayed() +{ + return menuVerticalPositions[0] == 1; +} + +inline bool isModelMenuDisplayed() +{ + return menuVerticalPositions[0] == 0; +} + +void onMainViewMenu(const char * result); +void menuFirstCalib(event_t event); +void menuChannelsViewCommon(event_t event); +void menuChannelsView(event_t event); +void menuMainView(event_t event); +void menuViewTelemetry(event_t event); +void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomFunctionsContext * functionsContext); +void menuStatisticsView(event_t event); +void menuStatisticsDebug(event_t event); +void menuStatisticsDebug2(event_t event); +void menuAboutView(event_t event); + +enum MenuRadioIndexes +{ +#if defined(RADIO_TOOLS) + MENU_RADIO_TOOLS, +#endif + MENU_RADIO_SD_MANAGER, + MENU_RADIO_SETUP, + MENU_RADIO_SPECIAL_FUNCTIONS, + MENU_RADIO_TRAINER, + MENU_RADIO_HARDWARE, + MENU_RADIO_VERSION, + MENU_RADIO_PAGES_COUNT +}; + +enum MenuModelIndexes { + MENU_MODEL_SELECT, + MENU_MODEL_SETUP, + CASE_HELI(MENU_MODEL_HELI) + CASE_FLIGHT_MODES(MENU_MODEL_FLIGHT_MODES) + MENU_MODEL_INPUTS, + MENU_MODEL_MIXES, + MENU_MODEL_OUTPUTS, + MENU_MODEL_CURVES, +#if LCD_W >= 212 + CASE_GVARS(MENU_MODEL_GVARS) +#endif + MENU_MODEL_LOGICAL_SWITCHES, + MENU_MODEL_SPECIAL_FUNCTIONS, +#if defined(LUA_MODEL_SCRIPTS) + MENU_MODEL_CUSTOM_SCRIPTS, +#endif + MENU_MODEL_TELEMETRY, + MENU_MODEL_DISPLAY, + MENU_MODEL_PAGES_COUNT +}; + +void menuRadioSetup(event_t event); +void menuRadioSdManager(event_t event); +void menuRadioSpecialFunctions(event_t event); +void menuRadioTrainer(event_t event); +void menuRadioVersion(event_t event); +void menuRadioDiagKeys(event_t event); +void menuRadioDiagAnalogs(event_t event); +void menuRadioDiagFS(event_t event); +void menuRadioHardware(event_t event); +void menuRadioTools(event_t event); +void menuRadioSpectrumAnalyser(event_t event); +void menuRadioPowerMeter(event_t event); +void menuRadioCalibration(event_t event); +void menuGhostModuleConfig(event_t event); + +void menuModelSelect(event_t event); +void menuModelSetup(event_t event); +void menuModelFailsafe(event_t event); +void menuModelModuleOptions(event_t event); +void menuModelReceiverOptions(event_t event); +void menuModelHeli(event_t event); +void menuModelFlightModesAll(event_t event); +void menuModelExpoOne(event_t event); +void menuModelExposAll(event_t event); +void menuModelMixOne(event_t event); +void menuModelMixAll(event_t event); +void menuModelLimits(event_t event); +void menuModelCurvesAll(event_t event); +void menuModelCurveOne(event_t event); +void menuModelLogicalSwitches(event_t event); +void menuModelSpecialFunctions(event_t event); +void menuModelCustomScripts(event_t event); +void menuModelTelemetry(event_t event); +void menuModelSensor(event_t event); +void menuModelDisplay(event_t event); +#if defined(USBJ_EX) +void menuModelUSBJoystick(event_t event); +#endif + +extern const MenuHandler menuTabGeneral[MENU_RADIO_PAGES_COUNT]; +extern const MenuHandler menuTabModel[MENU_MODEL_PAGES_COUNT]; + +extern const unsigned char sticks[]; + +extern uint8_t s_copyMode; +extern int8_t s_copySrcRow; +extern int8_t s_copyTgtOfs; +extern uint8_t s_currIdx; +extern uint8_t s_currIdxSubMenu; +extern mixsrc_t s_currSrcRaw; +extern uint16_t s_currScale; +extern uint8_t s_copySrcIdx; +extern uint8_t s_copySrcCh; +extern int8_t s_currCh; +extern uint8_t s_maxLines; + +// Temporary no highlight +extern uint8_t noHighlightCounter; +#define NO_HIGHLIGHT() (noHighlightCounter > 0) +#define START_NO_HIGHLIGHT() do { noHighlightCounter = 25; } while(0) + +void menuTextView(event_t event); +void pushMenuTextView(const char *filename); +void pushModelNotes(); +void readModelNotes(); + +uint8_t getExposCount(); +void insertExpo(uint8_t idx); +void deleteExpo(uint8_t idx); + +uint8_t switchToMix(uint8_t source); + +void drawSplash(); +void doMainScreenGraphics(); +void drawAlertBox(const char * title, const char * text, const char * action); + +#if defined(FLIGHT_MODES) +void displayFlightModes(coord_t x, coord_t y, FlightModesType value); +FlightModesType editFlightModes(coord_t x, coord_t y, event_t event, FlightModesType value, uint8_t attr); +#else +#define displayFlightModes(...) +#endif + +#define IS_MAIN_VIEW_DISPLAYED() menuHandlers[0] == menuMainView +#define IS_TELEMETRY_VIEW_DISPLAYED() menuHandlers[0] == menuViewTelemetry diff --git a/radio/src/gui/common/stdlcd/model_heli.cpp b/radio/src/gui/common/stdlcd/model_heli.cpp index 3785f5e59..5a6364032 100644 --- a/radio/src/gui/common/stdlcd/model_heli.cpp +++ b/radio/src/gui/common/stdlcd/model_heli.cpp @@ -39,14 +39,28 @@ enum MenuModelHeliItems { #define MODEL_HELI_2ND_COLUMN (14*FW) #endif +static int numberField(const char* name, coord_t y, int val, int min, LcdFlags attr, event_t event) +{ + return editNumberField(name, INDENT_WIDTH, MODEL_HELI_2ND_COLUMN, y, val, min, 100, attr, event); +} + +static uint8_t sourceField(const char* name, coord_t y, uint8_t val, LcdFlags attr, event_t event) +{ + lcdDrawTextAlignedLeft(y, name); + drawSource(MODEL_HELI_2ND_COLUMN, y, val, attr); + if (attr) CHECK_INCDEC_MODELSOURCE(event, val, 0, MIXSRC_LAST_CH); + return val; +} + void menuModelHeli(event_t event) { SIMPLE_MENU(STR_MENUHELISETUP, menuTabModel, MENU_MODEL_HELI, HEADER_LINE+ITEM_HELI_MAX); uint8_t sub = menuVerticalPosition - HEADER_LINE; + coord_t y = MENU_HEADER_HEIGHT + 1; + for (uint8_t i=0; i 0 ? BLINK|INVERS : INVERS); LcdFlags attr = (sub == k ? blink : 0); @@ -57,46 +71,34 @@ void menuModelHeli(event_t event) break; case ITEM_HELI_SWASHRING: - lcdDrawTextAlignedLeft(y, STR_SWASHRING); - lcdDrawNumber(MODEL_HELI_2ND_COLUMN, y, g_model.swashR.value, LEFT|attr); - if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, g_model.swashR.value, 100); + g_model.swashR.value = numberField(STR_SWASHRING, y, g_model.swashR.value, 0, attr, event); break; case ITEM_HELI_ELE: - lcdDrawTextAlignedLeft(y, STR_ELEVATOR); - drawSource(MODEL_HELI_2ND_COLUMN, y, g_model.swashR.elevatorSource, attr); - if (attr) CHECK_INCDEC_MODELSOURCE(event, g_model.swashR.elevatorSource, 0, MIXSRC_LAST_CH); + g_model.swashR.elevatorSource = sourceField(STR_ELEVATOR, y, g_model.swashR.elevatorSource, attr, event); break; case ITEM_HELI_ELE_WEIGHT: - lcdDrawTextIndented(y, STR_WEIGHT); - lcdDrawNumber(MODEL_HELI_2ND_COLUMN, y, g_model.swashR.elevatorWeight, LEFT|attr); - if (attr) CHECK_INCDEC_MODELVAR(event, g_model.swashR.elevatorWeight, -100, 100); + g_model.swashR.elevatorWeight = numberField(STR_WEIGHT, y, g_model.swashR.elevatorWeight, -100, attr, event); break; case ITEM_HELI_AIL: - lcdDrawTextAlignedLeft(y, STR_AILERON); - drawSource(MODEL_HELI_2ND_COLUMN, y, g_model.swashR.aileronSource, attr); - if (attr) CHECK_INCDEC_MODELSOURCE(event, g_model.swashR.aileronSource, 0, MIXSRC_LAST_CH); + g_model.swashR.aileronSource = sourceField(STR_AILERON, y, g_model.swashR.aileronSource, attr, event); break; case ITEM_HELI_AIL_WEIGHT: - lcdDrawTextIndented(y, STR_WEIGHT); - lcdDrawNumber(MODEL_HELI_2ND_COLUMN, y, g_model.swashR.aileronWeight, LEFT|attr); - if (attr) CHECK_INCDEC_MODELVAR(event, g_model.swashR.aileronWeight, -100, 100); + g_model.swashR.aileronWeight = numberField(STR_WEIGHT, y, g_model.swashR.aileronWeight, -100, attr, event); break; case ITEM_HELI_COL: - lcdDrawTextAlignedLeft(y, STR_COLLECTIVE); - drawSource(MODEL_HELI_2ND_COLUMN, y, g_model.swashR.collectiveSource, attr); - if (attr) CHECK_INCDEC_MODELSOURCE(event, g_model.swashR.collectiveSource, 0, MIXSRC_LAST_CH); + g_model.swashR.collectiveSource = sourceField(STR_COLLECTIVE, y, g_model.swashR.collectiveSource, attr, event); break; case ITEM_HELI_COL_WEIGHT: - lcdDrawTextIndented(y, STR_WEIGHT); - lcdDrawNumber(MODEL_HELI_2ND_COLUMN, y, g_model.swashR.collectiveWeight, LEFT|attr); - if (attr) CHECK_INCDEC_MODELVAR(event, g_model.swashR.collectiveWeight, -100, 100); + g_model.swashR.collectiveWeight = numberField(STR_WEIGHT, y, g_model.swashR.collectiveWeight, -100, attr, event); break; } + + y += FH; } } diff --git a/radio/src/gui/common/stdlcd/model_notes.cpp b/radio/src/gui/common/stdlcd/model_notes.cpp index 8a06de327..67a7e0f38 100644 --- a/radio/src/gui/common/stdlcd/model_notes.cpp +++ b/radio/src/gui/common/stdlcd/model_notes.cpp @@ -18,6 +18,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ + #include "edgetx.h" void menuModelNotes(event_t event) diff --git a/radio/src/gui/common/stdlcd/popups.cpp b/radio/src/gui/common/stdlcd/popups_common.cpp similarity index 99% rename from radio/src/gui/common/stdlcd/popups.cpp rename to radio/src/gui/common/stdlcd/popups_common.cpp index 1a3f5d05e..1728b2dbc 100644 --- a/radio/src/gui/common/stdlcd/popups.cpp +++ b/radio/src/gui/common/stdlcd/popups_common.cpp @@ -20,7 +20,6 @@ */ #include "edgetx.h" -#include const char * warningText = nullptr; const char * warningInfoText; diff --git a/radio/src/gui/common/stdlcd/popups_common.h b/radio/src/gui/common/stdlcd/popups_common.h index e503788b4..c09b9b48a 100644 --- a/radio/src/gui/common/stdlcd/popups_common.h +++ b/radio/src/gui/common/stdlcd/popups_common.h @@ -26,6 +26,25 @@ #include "lcd.h" #include "keys.h" +#define POPUP_MENU_MAX_LINES 13 +#define MENU_MAX_DISPLAY_LINES 6 +#define MENU_LINE_LENGTH (LEN_MODEL_NAME+12) + +enum { + MENU_OFFSET_INTERNAL, + MENU_OFFSET_EXTERNAL +}; + +enum WarningType +{ + WARNING_TYPE_WAIT, + WARNING_TYPE_INFO, + WARNING_TYPE_ASTERISK, + WARNING_TYPE_CONFIRM, + WARNING_TYPE_INPUT, + WARNING_TYPE_ALERT +}; + extern const char * warningText; extern const char * warningInfoText; extern uint8_t warningInfoLength; @@ -61,16 +80,6 @@ void showAlertBox(const char * title, const char * text, const char * action , u void drawProgressScreen(const char * title, const char * message, int num, int den); typedef void (* ProgressHandler)(const char *, const char *, int, int); -enum WarningType -{ - WARNING_TYPE_WAIT, - WARNING_TYPE_INFO, - WARNING_TYPE_ASTERISK, - WARNING_TYPE_CONFIRM, - WARNING_TYPE_INPUT, - WARNING_TYPE_ALERT -}; - #if !defined(GUI) #define DISPLAY_WARNING(...) inline void POPUP_WAIT(const char * s) { } diff --git a/radio/src/gui/common/stdlcd/radio_hardware.cpp b/radio/src/gui/common/stdlcd/radio_hardware.cpp index 8dbc7766d..d9de31a32 100644 --- a/radio/src/gui/common/stdlcd/radio_hardware.cpp +++ b/radio/src/gui/common/stdlcd/radio_hardware.cpp @@ -367,6 +367,13 @@ static void _init_menu_tab_array(uint8_t* tab, size_t len) #endif } +static bool editInversion(bool state, event_t event, coord_t y, LcdFlags flags) +{ + lcdDrawChar(LCD_W - 8, y, state ? 127 : 126, flags); + if (flags & (~RIGHT)) state = checkIncDec(event, state, 0, 1, EE_GENERAL); + return state; +} + void menuRadioHardware(event_t event) { uint8_t old_editMode = s_editMode; @@ -634,15 +641,10 @@ void menuRadioHardware(event_t event) // Sticks int idx = k - ITEM_RADIO_HARDWARE_STICK; - LcdFlags flags = menuHorizontalPosition == 0 ? attr : 0; - editStickHardwareSettings(HW_SETTINGS_COLUMN1, y, - idx, event, flags, old_editMode); + editStickHardwareSettings(HW_SETTINGS_COLUMN1, y, idx, event, + menuHorizontalPosition == 0 ? attr : 0, old_editMode); // ADC inversion - flags = menuHorizontalPosition == 1 ? attr : 0; - bool stickinversion = getStickInversion(idx); - lcdDrawChar(LCD_W - 8, y, stickinversion ? 127 : 126, flags); - if (flags & (~RIGHT)) stickinversion = checkIncDec(event, stickinversion, 0, 1, EE_GENERAL); - setStickInversion(idx, stickinversion); + setStickInversion(idx, editInversion(getStickInversion(idx), event, y, menuHorizontalPosition == 1 ? attr : 0)); } else if (k <= ITEM_RADIO_HARDWARE_POT_END) { // Pots & sliders @@ -673,11 +675,7 @@ void menuRadioHardware(event_t event) if (!IS_POT_MULTIPOS(idx)) { // ADC inversion - flags = menuHorizontalPosition == 2 ? attr : 0; - bool potinversion = getPotInversion(idx); - lcdDrawChar(LCD_W - 8, y, potinversion ? 127 : 126, flags); - if (flags & (~RIGHT)) potinversion = checkIncDec(event, potinversion, 0, 1, EE_GENERAL); - setPotInversion(idx, potinversion); + setPotInversion(idx, editInversion(getPotInversion(idx), event, y, menuHorizontalPosition == 2 ? attr : 0)); } else if (getPotInversion(idx)) { setPotInversion(idx, 0); storageDirty(EE_GENERAL); diff --git a/radio/src/gui/common/stdlcd/widgets_common.cpp b/radio/src/gui/common/stdlcd/widgets_common.cpp new file mode 100644 index 000000000..ed00e7f65 --- /dev/null +++ b/radio/src/gui/common/stdlcd/widgets_common.cpp @@ -0,0 +1,181 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "edgetx.h" + +choice_t editChoice(coord_t x, coord_t y, const char * label, const char *const *values, choice_t value, choice_t min, choice_t max, LcdFlags attr, event_t event, coord_t lblX, IsValueAvailable isValueAvailable) +{ + if (label) { + lcdDrawText(lblX, y, label); + } + if (values) lcdDrawTextAtIndex(x, y, values, value-min, attr); + if (attr & (~RIGHT)) value = checkIncDec(event, value, min, max, (isModelMenuDisplayed()) ? EE_MODEL : EE_GENERAL, isValueAvailable); + return value; +} + +choice_t editChoice(coord_t x, coord_t y, const char * label, const char *const *values, choice_t value, choice_t min, choice_t max, LcdFlags attr, event_t event, coord_t lblX) +{ + return editChoice(x, y, label, values, value, min, max, attr, event, lblX, nullptr); +} + +choice_t editChoice(coord_t x, coord_t y, const char * label, const char *const *values, choice_t value, choice_t min, choice_t max, LcdFlags attr, event_t event) +{ + return editChoice(x, y, label, values, value, min, max, attr, event, 0, nullptr); +} + +uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const char *label, LcdFlags attr, event_t event, coord_t lblX) +{ + drawCheckBox(x, y, value, attr); + return editChoice(x, y, label, nullptr, value, 0, 1, attr, event, lblX); +} + +uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const char *label, LcdFlags attr, event_t event) +{ + return editCheckBox(value, x, y, label, attr, event, 0); +} + +swsrc_t editSwitch(coord_t x, coord_t y, swsrc_t value, LcdFlags attr, event_t event) +{ + lcdDrawTextAlignedLeft(y, STR_SWITCH); + drawSwitch(x, y, value, attr); + if (attr & (~RIGHT)) CHECK_INCDEC_MODELSWITCH(event, value, SWSRC_FIRST_IN_MIXES, SWSRC_LAST_IN_MIXES, isSwitchAvailableInMixes); + return value; +} + +uint16_t editSrcVarFieldValue(coord_t x, coord_t y, const char* title, uint16_t value, + int16_t min, int16_t max, LcdFlags attr, event_t event, + IsValueAvailable isValueAvailable, int16_t sourceMin, int16_t sourceMax) +{ + if (title) + lcdDrawTextAlignedLeft(y, title); + SourceNumVal v; + v.rawValue = value; + if (v.isSource) { + drawSource(x, y, v.value, attr); + if (attr & (~RIGHT)) { + value = checkIncDec(event, value, sourceMin, sourceMax, + EE_MODEL|INCDEC_SOURCE|INCDEC_SOURCE_VALUE|INCDEC_SOURCE_INVERT|NO_INCDEC_MARKS, isValueAvailable); + } + } else { + lcdDrawNumber(x, y, v.value, attr); + if (attr & (~RIGHT)) { + value = checkIncDec(event, value, min, max, sourceMin, sourceMax, + EE_MODEL|INCDEC_SOURCE_VALUE|NO_INCDEC_MARKS|INCDEC_SKIP_VAL_CHECK_FUNC, + isValueAvailable); + } + } + return value; +} + +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) +{ +#if defined(GVARS) + bool invers = (attr & INVERS); + + // TRACE("editGVarFieldValue(val=%d min=%d max=%d)", value, min, max); + + if (modelGVEnabled() && invers && event == EVT_KEY_LONG(KEY_ENTER)) { + killEvents(event); + s_editMode = !s_editMode; + if (attr & PREC1) + value = (GV_IS_GV_VALUE(value) ? GET_GVAR(value, min, max, mixerCurrentFlightMode)*10 : GV_VALUE_FROM_INDEX(0)); + else + value = (GV_IS_GV_VALUE(value) ? GET_GVAR(value, min, max, mixerCurrentFlightMode) : GV_VALUE_FROM_INDEX(0)); + storageDirty(EE_MODEL); + } + + if (GV_IS_GV_VALUE(value)) { + attr &= ~PREC1; + int8_t idx = (int16_t)GV_INDEX_FROM_VALUE(value); + if (invers) { + CHECK_INCDEC_MODELVAR(event, idx, -MAX_GVARS, MAX_GVARS-1); + } + value = (int16_t)GV_VALUE_FROM_INDEX(idx); + drawGVarName(x, y, idx, attr); + } + else { + lcdDrawNumber(x, y, value, attr); + if (invers) value = checkIncDec(event, value, min, max, EE_MODEL | editflags); + } +#else + lcdDrawNumber(x, y, value, attr); + if (attr&INVERS) value = checkIncDec(event, value, min, max, EE_MODEL); +#endif + return value; +} + +#if defined(GVARS) +void editGVarValue(coord_t x, coord_t y, event_t event, uint8_t gvar, uint8_t flightMode, LcdFlags flags) +{ + FlightModeData * fm = &g_model.flightModeData[flightMode]; + gvar_t * v = &fm->gvars[gvar]; + int16_t vmin, vmax; + if (*v > GVAR_MAX) { + uint8_t fm = *v - GVAR_MAX - 1; + if (fm >= flightMode) fm++; + drawFlightMode(x, y, fm + 1, flags&(~LEFT)); + vmin = GVAR_MAX + 1; + vmax = GVAR_MAX + MAX_FLIGHT_MODES - 1; + } + else { + drawGVarValue(x, y, gvar, *v, flags); + vmin = GVAR_MIN + g_model.gvars[gvar].min; + vmax = GVAR_MAX - g_model.gvars[gvar].max; + } + + if (flags & INVERS) { + if (event == EVT_KEY_LONG(KEY_ENTER) && flightMode > 0) { + killEvents(event); + *v = (*v > GVAR_MAX ? 0 : GVAR_MAX+1); + storageDirty(EE_MODEL); + } + else if (s_editMode > 0) { + *v = checkIncDec(event, *v, vmin, vmax, EE_MODEL); + } + } +} +#endif + +void editSingleName(coord_t x, coord_t y, const char * label, char *name, uint8_t size, event_t event, uint8_t active, uint8_t old_editMode, coord_t lblX) +{ + lcdDrawText(lblX, y, label); + editName(x, y, name, size, event, active, 0, old_editMode); +} + +uint8_t editDelay(coord_t y, event_t event, uint8_t attr, const char * str, uint8_t delay, uint8_t prec) +{ + lcdDrawTextAlignedLeft(y, str); + lcdDrawNumber(MIXES_2ND_COLUMN, y, delay, attr|prec|LEFT); + if (attr) CHECK_INCDEC_MODELVAR_ZERO(event, delay, DELAY_MAX); + return delay; +} + +int editNumberField(const char* name, coord_t lx, coord_t vx, coord_t y, int val, + int min, int max, LcdFlags attr, event_t event, const char* zeroStr, int ofst) +{ + lcdDrawText(lx, y, name); + if (zeroStr && val == 0) + lcdDrawText(vx, y, zeroStr, attr & (~PREC1)); + else + lcdDrawNumber(vx, y, val + ofst, LEFT|attr); + if (attr & INVERS) CHECK_INCDEC_MODELVAR(event, val, min, max); + return val; +} diff --git a/radio/src/gui/common/stdlcd/widgets_common.h b/radio/src/gui/common/stdlcd/widgets_common.h new file mode 100644 index 000000000..a6d204ca0 --- /dev/null +++ b/radio/src/gui/common/stdlcd/widgets_common.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) EdgeTX + * + * Based on code named + * opentx - https://github.com/opentx/opentx + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#pragma once + +typedef int choice_t; + +choice_t editChoice(coord_t x, coord_t y, const char *label, + const char *const *values, choice_t value, choice_t min, + choice_t max, LcdFlags attr, event_t event); +choice_t editChoice(coord_t x, coord_t y, const char *label, + const char *const *values, choice_t value, choice_t min, + choice_t max, LcdFlags attr, event_t event, coord_t lblX); +choice_t editChoice(coord_t x, coord_t y, const char *label, + const char *const *values, choice_t value, choice_t min, + choice_t max, LcdFlags attr, event_t event, coord_t lblX, + IsValueAvailable isValueAvailable); + +uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const char *label, + LcdFlags attr, event_t event); +uint8_t editCheckBox(uint8_t value, coord_t x, coord_t y, const char *label, + LcdFlags attr, event_t event, coord_t lblX); + +swsrc_t editSwitch(coord_t x, coord_t y, swsrc_t value, LcdFlags attr, + event_t event); + +uint16_t editSrcVarFieldValue(coord_t x, coord_t y, const char* title, uint16_t value, + int16_t min, int16_t max, LcdFlags attr, event_t event, + IsValueAvailable isValueAvailable, int16_t sourceMin, int16_t sourceMax); + +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); + +#define GVAR_MENU_ITEM(x, y, v, min, max, attr, editflags, event) \ + editGVarFieldValue(x, y, v, min, max, attr, editflags, event) + +#if defined(GVARS) +void editGVarValue(coord_t x, coord_t y, event_t event, uint8_t gvar, + uint8_t flightMode, LcdFlags flags); +#endif + +void editCurveRef(coord_t x, coord_t y, CurveRef & curve, event_t event, LcdFlags flags, + IsValueAvailable isValueAvailable, int16_t sourceMin, int16_t sourceMax); + +extern uint8_t editNameCursorPos; + +void editName(coord_t x, coord_t y, char *name, uint8_t size, event_t event, + uint8_t active, LcdFlags attr, uint8_t old_editMode); + +void editSingleName(coord_t x, coord_t y, const char *label, char *name, + uint8_t size, event_t event, uint8_t active, + uint8_t old_editMode, coord_t lblX = 0); + +uint8_t editDelay(coord_t y, event_t event, uint8_t attr, const char * str, uint8_t delay, uint8_t prec); + +int editNumberField(const char* name, coord_t lx, coord_t vx, coord_t y, int val, + int min, int max, LcdFlags attr, event_t event, const char* zeroStr = nullptr, int ofst = 0); diff --git a/radio/src/translations/i18n/cn.h b/radio/src/translations/i18n/cn.h index be8f5d8fe..0ed345a73 100644 --- a/radio/src/translations/i18n/cn.h +++ b/radio/src/translations/i18n/cn.h @@ -1078,7 +1078,8 @@ #define TR_CURVE_PRESET "预设..." #define TR_PRESET "预设" #define TR_MIRROR "镜像" -#define TR_CLEAR BUTTON("清除") +#define TR_CLEAR "清除" +#define TR_CLEAR_BTN BUTTON("清除") #define TR_RESET "复位" #define TR_RESET_SUBMENU "复位..." #define TR_COUNT "点数" diff --git a/radio/src/translations/i18n/cz.h b/radio/src/translations/i18n/cz.h index c6b575574..d1907fc12 100644 --- a/radio/src/translations/i18n/cz.h +++ b/radio/src/translations/i18n/cz.h @@ -1081,7 +1081,8 @@ #define TR_CURVE_PRESET "Šablona" #define TR_PRESET "Šablona" #define TR_MIRROR "Zrcadlit" -#define TR_CLEAR BUTTON("Smazat") +#define TR_CLEAR "Smazat" +#define TR_CLEAR_BTN BUTTON("Smazat") #define TR_RESET "Reset" #define TR_RESET_SUBMENU "Inicializovat ..." #define TR_COUNT "Velikost" diff --git a/radio/src/translations/i18n/da.h b/radio/src/translations/i18n/da.h index 8a7dc4656..dc5231853 100644 --- a/radio/src/translations/i18n/da.h +++ b/radio/src/translations/i18n/da.h @@ -1083,7 +1083,8 @@ #define TR_CURVE_PRESET TR ("Forudindstil", "Forudind.") #define TR_PRESET "Forudindstil" #define TR_MIRROR "Spejle" -#define TR_CLEAR BUTTON("Slet") +#define TR_CLEAR "Slet" +#define TR_CLEAR_BTN BUTTON("Slet") #define TR_RESET "Nulstil" #define TR_RESET_SUBMENU "Nulstil..." #define TR_COUNT "Tæller" diff --git a/radio/src/translations/i18n/de.h b/radio/src/translations/i18n/de.h index 903a64930..2b2ec6f33 100644 --- a/radio/src/translations/i18n/de.h +++ b/radio/src/translations/i18n/de.h @@ -1078,7 +1078,8 @@ #define TR_CURVE_PRESET "Gerade 0 11 22 33 45" #define TR_PRESET "Preset" #define TR_MIRROR "Spiegeln" -#define TR_CLEAR BUTTON("Löschen") +#define TR_CLEAR "Löschen" +#define TR_CLEAR_BTN BUTTON("Löschen") #define TR_RESET TR("Servowert reset","Servowerte zurücksetzen") #define TR_RESET_SUBMENU TR("Reset Werte ==>", "Reset=>Timer Flug Telem") #define TR_COUNT "Punkte" diff --git a/radio/src/translations/i18n/en.h b/radio/src/translations/i18n/en.h index 70d018c14..6a7c272d4 100644 --- a/radio/src/translations/i18n/en.h +++ b/radio/src/translations/i18n/en.h @@ -1079,7 +1079,8 @@ #define TR_CURVE_PRESET "Preset..." #define TR_PRESET "Preset" #define TR_MIRROR "Mirror" -#define TR_CLEAR BUTTON("Clear") +#define TR_CLEAR "Clear" +#define TR_CLEAR_BTN BUTTON("Clear") #define TR_RESET "Reset" #define TR_RESET_SUBMENU "Reset..." #define TR_COUNT "Count" diff --git a/radio/src/translations/i18n/es.h b/radio/src/translations/i18n/es.h index edd46d15b..edb7e8916 100644 --- a/radio/src/translations/i18n/es.h +++ b/radio/src/translations/i18n/es.h @@ -1079,7 +1079,8 @@ #define TR_CURVE_PRESET "Preset..." #define TR_PRESET "Preset" #define TR_MIRROR "Mirror" -#define TR_CLEAR BUTTON("Borrar") +#define TR_CLEAR "Borrar" +#define TR_CLEAR_BTN BUTTON("Borrar") #define TR_RESET "Reset" #define TR_RESET_SUBMENU "Reset..." #define TR_COUNT "Puntos" diff --git a/radio/src/translations/i18n/fi.h b/radio/src/translations/i18n/fi.h index 1d11439f0..2ce0cffe9 100644 --- a/radio/src/translations/i18n/fi.h +++ b/radio/src/translations/i18n/fi.h @@ -1078,7 +1078,8 @@ #define TR_CURVE_PRESET "Preset..." #define TR_PRESET "Preset" #define TR_MIRROR "Mirror" -#define TR_CLEAR BUTTON("Clear") +#define TR_CLEAR "Clear" +#define TR_CLEAR_BTN BUTTON("Clear") #define TR_RESET "Reset" #define TR_RESET_SUBMENU "Reset..." #define TR_COUNT "Count" diff --git a/radio/src/translations/i18n/fr.h b/radio/src/translations/i18n/fr.h index 74e592755..7b95ef2ad 100644 --- a/radio/src/translations/i18n/fr.h +++ b/radio/src/translations/i18n/fr.h @@ -1081,7 +1081,8 @@ #define TR_CURVE_PRESET "Courbe standard..." #define TR_PRESET "Pente" #define TR_MIRROR "Miroir" -#define TR_CLEAR BUTTON("Effacer") +#define TR_CLEAR "Effacer" +#define TR_CLEAR_BTN BUTTON("Effacer") #define TR_RESET "Réinit." #define TR_RESET_SUBMENU "Réinit..." #define TR_COUNT "Nb points" diff --git a/radio/src/translations/i18n/he.h b/radio/src/translations/i18n/he.h index 2d72395ea..9618607c3 100644 --- a/radio/src/translations/i18n/he.h +++ b/radio/src/translations/i18n/he.h @@ -1081,7 +1081,8 @@ #define TR_CURVE_PRESET "Preset..." #define TR_PRESET "Preset" #define TR_MIRROR "היפוך" -#define TR_CLEAR BUTTON("ניקוי") +#define TR_CLEAR "ניקוי" +#define TR_CLEAR_BTN BUTTON("ניקוי") #define TR_RESET "איפוס" #define TR_RESET_SUBMENU "...איפוס" #define TR_COUNT "ספירה" diff --git a/radio/src/translations/i18n/it.h b/radio/src/translations/i18n/it.h index c7b6ab63d..bdb0cd75b 100644 --- a/radio/src/translations/i18n/it.h +++ b/radio/src/translations/i18n/it.h @@ -1078,7 +1078,8 @@ #define TR_CURVE_PRESET "Preimpostate..." #define TR_PRESET "Preimpostate" #define TR_MIRROR "Mirror" -#define TR_CLEAR BUTTON("Cancella") +#define TR_CLEAR "Cancella" +#define TR_CLEAR_BTN BUTTON("Cancella") #define TR_RESET "Azzera" #define TR_RESET_SUBMENU "Azzera..." #define TR_COUNT "Punti" diff --git a/radio/src/translations/i18n/jp.h b/radio/src/translations/i18n/jp.h index 2e09a1321..c80404c76 100644 --- a/radio/src/translations/i18n/jp.h +++ b/radio/src/translations/i18n/jp.h @@ -1077,7 +1077,8 @@ #define TR_CURVE_PRESET "プリセット..." #define TR_PRESET "プリセット" #define TR_MIRROR "ミラー" -#define TR_CLEAR BUTTON("消去") +#define TR_CLEAR "消去" +#define TR_CLEAR_BTN BUTTON("消去") #define TR_RESET "リセット" #define TR_RESET_SUBMENU "リセット..." #define TR_COUNT "カウント" diff --git a/radio/src/translations/i18n/ko.h b/radio/src/translations/i18n/ko.h index b2b7066c7..8575e9ebe 100644 --- a/radio/src/translations/i18n/ko.h +++ b/radio/src/translations/i18n/ko.h @@ -1127,7 +1127,8 @@ #define TR_CURVE_PRESET "프리셋..." #define TR_PRESET "프리셋" #define TR_MIRROR "미러" -#define TR_CLEAR BUTTON("지우기") +#define TR_CLEAR "지우기" +#define TR_CLEAR_BTN BUTTON("지우기") #define TR_RESET "초기화" #define TR_RESET_SUBMENU "초기화..." #define TR_COUNT "카운트" diff --git a/radio/src/translations/i18n/nl.h b/radio/src/translations/i18n/nl.h index 3cfa622c4..d08701557 100644 --- a/radio/src/translations/i18n/nl.h +++ b/radio/src/translations/i18n/nl.h @@ -1079,7 +1079,8 @@ #define TR_CURVE_PRESET "Preset..." #define TR_PRESET "Preset" #define TR_MIRROR "Spiegelen" -#define TR_CLEAR BUTTON("Wissen") +#define TR_CLEAR "Wissen" +#define TR_CLEAR_BTN BUTTON("Wissen") #define TR_RESET "Reset Servowaardes" #define TR_RESET_SUBMENU "Reset..." #define TR_COUNT "Punten" diff --git a/radio/src/translations/i18n/pl.h b/radio/src/translations/i18n/pl.h index 428862e47..02d11733a 100644 --- a/radio/src/translations/i18n/pl.h +++ b/radio/src/translations/i18n/pl.h @@ -1076,7 +1076,8 @@ #define TR_CURVE_PRESET "Predef..." #define TR_PRESET "Predef." #define TR_MIRROR "Lustro" -#define TR_CLEAR BUTTON("Wyczyść") +#define TR_CLEAR "Wyczyść" +#define TR_CLEAR_BTN BUTTON("Wyczyść") #define TR_RESET "Resetuj" #define TR_RESET_SUBMENU "Reset..." #define TR_COUNT "Punkty" diff --git a/radio/src/translations/i18n/pt.h b/radio/src/translations/i18n/pt.h index 8133619b4..ec6d9f696 100644 --- a/radio/src/translations/i18n/pt.h +++ b/radio/src/translations/i18n/pt.h @@ -1079,7 +1079,8 @@ #define TR_CURVE_PRESET "Preset..." #define TR_PRESET "Preset" #define TR_MIRROR "Espelhar" -#define TR_CLEAR BUTTON("Clear") +#define TR_CLEAR "Clear" +#define TR_CLEAR_BTN BUTTON("Clear") #define TR_RESET "Reset" #define TR_RESET_SUBMENU "Reset..." #define TR_COUNT "Quantidade" diff --git a/radio/src/translations/i18n/ru.h b/radio/src/translations/i18n/ru.h index 7965da1d5..917a47ed9 100644 --- a/radio/src/translations/i18n/ru.h +++ b/radio/src/translations/i18n/ru.h @@ -1080,7 +1080,8 @@ #define TR_CURVE_PRESET "Предустановка..." #define TR_PRESET "Предустановка" #define TR_MIRROR "Зеркало" -#define TR_CLEAR BUTTON("Очистить") +#define TR_CLEAR "Очистить" +#define TR_CLEAR_BTN BUTTON("Очистить") #define TR_RESET "Сброс" #define TR_RESET_SUBMENU "Сброс..." #define TR_COUNT "Колличество" diff --git a/radio/src/translations/i18n/se.h b/radio/src/translations/i18n/se.h index ab8a154ae..49e9821e8 100644 --- a/radio/src/translations/i18n/se.h +++ b/radio/src/translations/i18n/se.h @@ -1086,7 +1086,8 @@ #define TR_CURVE_PRESET "Förinställd..." #define TR_PRESET "Lutning" #define TR_MIRROR "Spegla" -#define TR_CLEAR BUTTON("Rensa") +#define TR_CLEAR "Rensa" +#define TR_CLEAR_BTN BUTTON("Rensa") #define TR_RESET "Återställ" #define TR_RESET_SUBMENU "Återställ..." #define TR_COUNT "Antal" diff --git a/radio/src/translations/i18n/tw.h b/radio/src/translations/i18n/tw.h index f7f3a92fb..2223fa8df 100644 --- a/radio/src/translations/i18n/tw.h +++ b/radio/src/translations/i18n/tw.h @@ -1076,7 +1076,8 @@ #define TR_CURVE_PRESET "預設..." #define TR_PRESET "預設" #define TR_MIRROR "鏡像" -#define TR_CLEAR BUTTON("清除") +#define TR_CLEAR "清除" +#define TR_CLEAR_BTN BUTTON("清除") #define TR_RESET "重啟" #define TR_RESET_SUBMENU "重啟..." #define TR_COUNT "點數" diff --git a/radio/src/translations/i18n/ua.h b/radio/src/translations/i18n/ua.h index 2d4f4a0a7..edf898461 100644 --- a/radio/src/translations/i18n/ua.h +++ b/radio/src/translations/i18n/ua.h @@ -1079,7 +1079,8 @@ #define TR_CURVE_PRESET "Передвстановлення..." #define TR_PRESET "Передвстановлення" #define TR_MIRROR "Дзеркало" -#define TR_CLEAR BUTTON("Очистити") +#define TR_CLEAR "Очистити" +#define TR_CLEAR_BTN BUTTON("Очистити") #define TR_RESET "Скидання" #define TR_RESET_SUBMENU "Скидання..." #define TR_COUNT "Кількість" diff --git a/radio/src/translations/string_list.h b/radio/src/translations/string_list.h index e748f684f..9430d859a 100644 --- a/radio/src/translations/string_list.h +++ b/radio/src/translations/string_list.h @@ -743,6 +743,7 @@ STR(INVERTED) STR(CURVE_PRESET) STR(PRESET) STR(CLEAR) +STR(CLEAR_BTN) STR(RESET) STR(ADD_ALL_TRIMS_TO_SUBTRIMS) STR(COUNT)