diff --git a/radio/src/gui/colorlcd/layout.cpp b/radio/src/gui/colorlcd/layout.cpp index c5bd2f3f9..a56a29684 100644 --- a/radio/src/gui/colorlcd/layout.cpp +++ b/radio/src/gui/colorlcd/layout.cpp @@ -99,7 +99,7 @@ void loadCustomScreens() void Layout::decorate() { - // check if deco setting are still up-to-date + // Check if deco setting are still up-to-date uint8_t checkSettings = (hasTopbar() ? 1 << 0 : 0) | (hasSliders() ? 1 << 1 : 0) | @@ -111,139 +111,20 @@ void Layout::decorate() return; } - // kill all decorations & re-decorate - for (auto deco: decorations) { - deco->deleteLater(); - } - decorations.clear(); - topBar = nullptr; - - // effect a full redraw - invalidate(); - - // save settings + // Save settings decorationSettings = checkSettings; - if (hasTopbar()) { - topBar = new TopBar(this); - topBar->load(); - decorations.push_back(topBar); - } + auto viewMain = ViewMain::instance(); - if (hasSliders()) { -#if defined(HARDWARE_EXT1) || defined(HARDWARE_EXT2) - coord_t yOffset = (hasTrims() ? - TRIM_SQUARE_SIZE : 0) + (hasTopbar() ? TOPBAR_HEIGHT / 2 : 0); -#endif + // Set visible decoration + viewMain->setTopbarVisible(hasTopbar()); + viewMain->setSlidersVisible(hasSliders()); + viewMain->setTrimsVisible(hasTrims()); + viewMain->setFlightModeVisible(hasFlightMode()); - decorations.push_back( - new MainViewHorizontalSlider(this, {HMARGIN, LCD_H - TRIM_SQUARE_SIZE, HORIZONTAL_SLIDERS_WIDTH, TRIM_SQUARE_SIZE}, - [=] { return calibratedAnalogs[CALIBRATED_POT1]; }) - ); - - if (IS_POT_MULTIPOS(POT2)) { - decorations.push_back( - new MainView6POS(this, {LCD_W / 2 - MULTIPOS_W / 2, LCD_H - TRIM_SQUARE_SIZE, MULTIPOS_W + 1, MULTIPOS_H}, - [=] { return (1 + (potsPos[1] & 0x0f)); }) - ); - } - else if (IS_POT(POT2)) { - decorations.push_back( - new MainViewHorizontalSlider(this, {LCD_W - HORIZONTAL_SLIDERS_WIDTH - HMARGIN, LCD_H - TRIM_SQUARE_SIZE, HORIZONTAL_SLIDERS_WIDTH, TRIM_SQUARE_SIZE}, - [=] { return calibratedAnalogs[CALIBRATED_POT2]; }) - ); - } - -#if defined(HARDWARE_POT3) - decorations.push_back( - new MainViewHorizontalSlider(this, {LCD_W - HORIZONTAL_SLIDERS_WIDTH - HMARGIN, LCD_H - TRIM_SQUARE_SIZE, HORIZONTAL_SLIDERS_WIDTH, TRIM_SQUARE_SIZE}, - [=] { return calibratedAnalogs[CALIBRATED_POT3]; }) - ); -#endif - -#if defined(HARDWARE_EXT1) - if (IS_POT_SLIDER_AVAILABLE(EXT1)) { - decorations.push_back( - new MainViewVerticalSlider(this, {HMARGIN, LCD_H / 2 - VERTICAL_SLIDERS_HEIGHT(hasTopbar()) / 2 + yOffset, TRIM_SQUARE_SIZE, VERTICAL_SLIDERS_HEIGHT(hasTopbar()) / 2}, - [=] { return calibratedAnalogs[CALIBRATED_SLIDER_REAR_LEFT]; }) - ); - decorations.push_back( - new MainViewVerticalSlider(this, {HMARGIN, LCD_H / 2 + yOffset, TRIM_SQUARE_SIZE, VERTICAL_SLIDERS_HEIGHT(hasTopbar()) / 2}, - [=] { return calibratedAnalogs[CALIBRATED_POT_EXT1]; }) - ); - } - else { - decorations.push_back( - new MainViewVerticalSlider(this, {HMARGIN, LCD_H / 2 - VERTICAL_SLIDERS_HEIGHT(hasTopbar()) / 2 + yOffset, TRIM_SQUARE_SIZE, VERTICAL_SLIDERS_HEIGHT(hasTopbar())}, - [=] { return calibratedAnalogs[CALIBRATED_SLIDER_REAR_LEFT]; }) - ); - } -#endif - -#if defined(HARDWARE_EXT2) - if (IS_POT_SLIDER_AVAILABLE(EXT2)) { - decorations.push_back( - new MainViewVerticalSlider(this, {LCD_W - HMARGIN - TRIM_SQUARE_SIZE, LCD_H / 2 - VERTICAL_SLIDERS_HEIGHT(hasTopbar()) / 2 + yOffset, TRIM_SQUARE_SIZE, - VERTICAL_SLIDERS_HEIGHT(hasTopbar()) / 2}, - [=] { return calibratedAnalogs[CALIBRATED_SLIDER_REAR_RIGHT]; }) - ); - decorations.push_back( - new MainViewVerticalSlider(this, {LCD_W - HMARGIN - TRIM_SQUARE_SIZE, LCD_H / 2 + yOffset, TRIM_SQUARE_SIZE, - VERTICAL_SLIDERS_HEIGHT(hasTopbar()) / 2}, - [=] { return calibratedAnalogs[CALIBRATED_POT_EXT2]; }) - ); - } - else { - decorations.push_back( - new MainViewVerticalSlider(this, {LCD_W - HMARGIN - TRIM_SQUARE_SIZE, LCD_H / 2 - VERTICAL_SLIDERS_HEIGHT(hasTopbar()) / 2 + yOffset, TRIM_SQUARE_SIZE, - VERTICAL_SLIDERS_HEIGHT(hasTopbar())}, - [=] { return calibratedAnalogs[CALIBRATED_SLIDER_REAR_RIGHT]; }) - ); - } -#endif - } - - if (hasTrims()) { -#if defined(HARDWARE_POT3) || defined(HARDWARE_EXT1) - coord_t xOffset = hasSliders() ? TRIM_SQUARE_SIZE : 0; -#else - coord_t xOffset = 0; -#endif - coord_t yOffset = (hasTrims() ? - TRIM_SQUARE_SIZE : 0); - - // Trim order TRIM_LH, TRIM_LV, TRIM_RV, TRIM_RH - - // Left - decorations.push_back( - new MainViewHorizontalTrim(this, {HMARGIN, LCD_H - TRIM_SQUARE_SIZE + yOffset, HORIZONTAL_SLIDERS_WIDTH, TRIM_SQUARE_SIZE}, - [=] { return getTrimValue(mixerCurrentFlightMode, 0); }) - ); - - // Right - decorations.push_back( - new MainViewHorizontalTrim(this, {LCD_W - HORIZONTAL_SLIDERS_WIDTH - HMARGIN, LCD_H - TRIM_SQUARE_SIZE + yOffset, HORIZONTAL_SLIDERS_WIDTH, TRIM_SQUARE_SIZE}, - [=] { return getTrimValue(mixerCurrentFlightMode, 3); }) - ); - - // Left - decorations.push_back( - new MainViewVerticalTrim(this, {HMARGIN + xOffset, LCD_H /2 - VERTICAL_SLIDERS_HEIGHT(hasTopbar()) / 2 + yOffset + (hasTopbar() ? TOPBAR_HEIGHT / 2 : 0), TRIM_SQUARE_SIZE, VERTICAL_SLIDERS_HEIGHT(hasTopbar())}, - [=] { return getTrimValue(mixerCurrentFlightMode, 1); }) - ); - - // Right - decorations.push_back( - new MainViewVerticalTrim(this, {LCD_W - HMARGIN - TRIM_SQUARE_SIZE - xOffset, LCD_H /2 - VERTICAL_SLIDERS_HEIGHT(hasTopbar()) / 2 + yOffset + (hasTopbar() ? TOPBAR_HEIGHT / 2 : 0), TRIM_SQUARE_SIZE, VERTICAL_SLIDERS_HEIGHT(hasTopbar())}, - [=] { return getTrimValue(mixerCurrentFlightMode, 2); }) - ); - } - - if (hasFlightMode()) { - decorations.push_back( - new DynamicText(this, {50, LCD_H - 4 - (hasSliders() ? 2 * TRIM_SQUARE_SIZE: TRIM_SQUARE_SIZE), LCD_W - 100, 20}, [=] { - return g_model.flightModeData[mixerCurrentFlightMode].name; - }, CENTERED) - ); - } + // Re-compute positions + viewMain->adjustDecoration(); + viewMain->invalidate(); } rect_t Layout::getMainZone(rect_t zone) const diff --git a/radio/src/gui/colorlcd/layout.h b/radio/src/gui/colorlcd/layout.h index bdaf18c30..8c0befb1c 100644 --- a/radio/src/gui/colorlcd/layout.h +++ b/radio/src/gui/colorlcd/layout.h @@ -111,14 +111,14 @@ class Layout: public LayoutBase protected: const LayoutFactory * factory; - TopBar * topBar = nullptr; - uint8_t decorationSettings = 0; - std::list decorations; - // adds trims, sliders, pots, etc... + // Decoration settings bitmask to detect updates + uint8_t decorationSettings = 0; + + // Updates settings for trims, sliders, pots, etc... void decorate(); - // get the Zone rect without decoration + // Get the Zone rect without decoration rect_t getMainZone(rect_t zone) const; }; diff --git a/radio/src/gui/colorlcd/layouts/sliders.h b/radio/src/gui/colorlcd/layouts/sliders.h index 72cc539b4..02857af61 100644 --- a/radio/src/gui/colorlcd/layouts/sliders.h +++ b/radio/src/gui/colorlcd/layouts/sliders.h @@ -32,6 +32,7 @@ constexpr coord_t HMARGIN = 5; constexpr coord_t HORIZONTAL_SLIDERS_WIDTH = SLIDER_TICKS_COUNT * 4 + TRIM_SQUARE_SIZE; constexpr coord_t MULTIPOS_H = 20; constexpr coord_t MULTIPOS_W = 50; + inline coord_t VERTICAL_SLIDERS_HEIGHT(bool topbar) { return topbar ? SLIDER_TICKS_COUNT * 4 + TRIM_SQUARE_SIZE : SLIDER_TICKS_COUNT * 5 + TRIM_SQUARE_SIZE; @@ -40,16 +41,16 @@ inline coord_t VERTICAL_SLIDERS_HEIGHT(bool topbar) class MainViewSlider : public Window { public: - MainViewSlider(Window * parent, const rect_t & rect, std::function getValue): + MainViewSlider(Window * parent, const rect_t & rect, uint8_t idx): Window(parent, rect), - getValue(std::move(getValue)) + idx(idx) { } void checkEvents() override { Window::checkEvents(); - int16_t newValue = getValue(); + int16_t newValue = calibratedAnalogs[idx]; if (value != newValue) { value = newValue; invalidate(); @@ -57,8 +58,8 @@ class MainViewSlider : public Window } protected: - std::function getValue; - int8_t value = 0; + uint8_t idx; + int16_t value = 0; }; class MainViewHorizontalSlider : public MainViewSlider @@ -80,7 +81,6 @@ class MainViewHorizontalSlider : public MainViewSlider } // The square - auto value = - getValue(); x = width() - TRIM_SQUARE_SIZE - divRoundClosest((width() - TRIM_SQUARE_SIZE) * (value + RESX), 2 * RESX); drawTrimSquare(dc, x, 0, TRIM_BGCOLOR); } @@ -102,7 +102,7 @@ class MainView6POS : public MainViewSlider } // The square - auto value = getValue(); + auto value = 1 + (potsPos[idx] & 0x0f); x = TRIM_SQUARE_SIZE / 2 + divRoundClosest((width() - TRIM_SQUARE_SIZE) * (value -1) , 6); drawTrimSquare(dc, x, 0, TRIM_BGCOLOR); dc->drawNumber(x + 1, 0, value, FOCUS_COLOR); @@ -129,7 +129,6 @@ class MainViewVerticalSlider : public MainViewSlider } // The square - auto value = getValue(); y = height() - TRIM_SQUARE_SIZE - divRoundClosest((height() - TRIM_SQUARE_SIZE) * (value + RESX), 2 * RESX); drawTrimSquare(dc, 0, y, TRIM_BGCOLOR); } diff --git a/radio/src/gui/colorlcd/layouts/trims.cpp b/radio/src/gui/colorlcd/layouts/trims.cpp new file mode 100644 index 000000000..013ba9bc6 --- /dev/null +++ b/radio/src/gui/colorlcd/layouts/trims.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * 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 "trims.h" +#include "opentx.h" + +void MainViewTrim::checkEvents() +{ + Window::checkEvents(); + int8_t newValue = getTrimValue(mixerCurrentFlightMode, idx); + if (value != newValue) { + value = newValue; + invalidate(); + } +} + +void MainViewHorizontalTrim::paint(BitmapBuffer * dc) +{ + int32_t trimMin, trimMax; + if (g_model.extendedTrims) { + trimMin = TRIM_EXTENDED_MIN; + trimMax = TRIM_EXTENDED_MAX; + } + else { + trimMin = TRIM_MIN; + trimMax = TRIM_MAX; + } + + // Trim line + lcdSetColor(GREY); // TODO add a color + dc->drawSolidFilledRect(TRIM_SQUARE_SIZE / 2, (height() - TRIM_LINE_WIDTH - 1) / 2, width() - TRIM_SQUARE_SIZE + 1, TRIM_LINE_WIDTH, CUSTOM_COLOR); + + // Trim square + coord_t x = divRoundClosest((width() - TRIM_SQUARE_SIZE) * (value - trimMin), trimMax - trimMin); + drawTrimSquare(dc, x, 0, (value < TRIM_MIN || value > TRIM_MAX) ? HIGHLIGHT_COLOR /* TODO add a color */ : TRIM_BGCOLOR); + + // Trim value / small lines on the square + if (g_model.displayTrims == DISPLAY_TRIMS_ALWAYS) { + // TODO DISPLAY_TRIMS_CHANGE + dc->drawNumber(x + (TRIM_SQUARE_SIZE + 1) / 2, 3, divRoundClosest(value * 100, trimMax), FONT(XXS) | FOCUS_COLOR | CENTERED); + } + else { + if (value >= 0) { + dc->drawSolidVerticalLine(x + 4, 3, 9, FOCUS_COLOR); + } + if (value <= 0) { + dc->drawSolidVerticalLine(x + 10, 3, 9, FOCUS_COLOR); + } + } +} + +void MainViewVerticalTrim::paint(BitmapBuffer * dc) +{ + int32_t trimMin, trimMax; + if (g_model.extendedTrims) { + trimMin = TRIM_EXTENDED_MIN; + trimMax = TRIM_EXTENDED_MAX; + } + else { + trimMin = TRIM_MIN; + trimMax = TRIM_MAX; + } + + // Trim line + lcdSetColor(GREY); // TODO add a color + dc->drawSolidFilledRect((width() - TRIM_LINE_WIDTH) / 2, TRIM_SQUARE_SIZE / 2, TRIM_LINE_WIDTH, height() - TRIM_SQUARE_SIZE + 1, CUSTOM_COLOR); + + // Trim square + coord_t y = height() - TRIM_SQUARE_SIZE - divRoundClosest((height() - TRIM_SQUARE_SIZE) * (value - trimMin), trimMax - trimMin); + drawTrimSquare(dc, 0, y, (value < TRIM_MIN || value > TRIM_MAX) ? HIGHLIGHT_COLOR /* TODO add a color */ : TRIM_BGCOLOR); + + // Trim value / small lines on the square + if (g_model.displayTrims == DISPLAY_TRIMS_ALWAYS) { + // TODO DISPLAY_TRIMS_CHANGE + dc->drawNumber((TRIM_SQUARE_SIZE + 1) / 2, y + 3, divRoundClosest(value * 100, trimMax), FONT(XXS) | FOCUS_COLOR | CENTERED); + } + else { + if (value >= 0) { + dc->drawSolidHorizontalLine(3, y + 4, 9, FOCUS_COLOR); + } + if (value <= 0) { + dc->drawSolidHorizontalLine(3, y + 10, 9, FOCUS_COLOR); + } + } +} diff --git a/radio/src/gui/colorlcd/layouts/trims.h b/radio/src/gui/colorlcd/layouts/trims.h index 9d090c498..ba8326f71 100644 --- a/radio/src/gui/colorlcd/layouts/trims.h +++ b/radio/src/gui/colorlcd/layouts/trims.h @@ -25,25 +25,17 @@ class MainViewTrim : public Window { public: - MainViewTrim(Window * parent, const rect_t & rect, std::function getValue): + MainViewTrim(Window * parent, const rect_t & rect, uint8_t idx): Window(parent, rect), - getValue(std::move(getValue)) + idx(idx) { } - void checkEvents() override - { - Window::checkEvents(); - int8_t newValue = getValue(); - if (value != newValue) { - value = newValue; - invalidate(); - } - } + void checkEvents() override; protected: - std::function getValue; - int8_t value = 0; + uint8_t idx; + int value = 0; }; class MainViewHorizontalTrim : public MainViewTrim @@ -51,41 +43,7 @@ class MainViewHorizontalTrim : public MainViewTrim public: using MainViewTrim::MainViewTrim; - void paint(BitmapBuffer * dc) override - { - int32_t trimMin, trimMax; - if (g_model.extendedTrims) { - trimMin = TRIM_EXTENDED_MIN; - trimMax = TRIM_EXTENDED_MAX; - } - else { - trimMin = TRIM_MIN; - trimMax = TRIM_MAX; - } - - // Trim line - lcdSetColor(GREY); // TODO add a color - dc->drawSolidFilledRect(TRIM_SQUARE_SIZE / 2, (height() - TRIM_LINE_WIDTH - 1) / 2, width() - TRIM_SQUARE_SIZE + 1, TRIM_LINE_WIDTH, CUSTOM_COLOR); - - // Trim square - auto value = getValue(); - coord_t x = divRoundClosest((width() - TRIM_SQUARE_SIZE) * (value - trimMin), trimMax - trimMin); - drawTrimSquare(dc, x, 0, (value < TRIM_MIN || value > TRIM_MAX) ? HIGHLIGHT_COLOR /* TODO add a color */ : TRIM_BGCOLOR); - - // Trim value / small lines on the square - if (g_model.displayTrims == DISPLAY_TRIMS_ALWAYS) { - // TODO DISPLAY_TRIMS_CHANGE - dc->drawNumber(x + (TRIM_SQUARE_SIZE + 1) / 2, 3, divRoundClosest(value * 100, trimMax), FONT(XXS) | FOCUS_COLOR | CENTERED); - } - else { - if (value >= 0) { - dc->drawSolidVerticalLine(x + 4, 3, 9, FOCUS_COLOR); - } - if (value <= 0) { - dc->drawSolidVerticalLine(x + 10, 3, 9, FOCUS_COLOR); - } - } - } + void paint(BitmapBuffer * dc) override; }; class MainViewVerticalTrim : public MainViewTrim @@ -93,39 +51,5 @@ class MainViewVerticalTrim : public MainViewTrim public: using MainViewTrim::MainViewTrim; - void paint(BitmapBuffer * dc) override - { - int32_t trimMin, trimMax; - if (g_model.extendedTrims) { - trimMin = TRIM_EXTENDED_MIN; - trimMax = TRIM_EXTENDED_MAX; - } - else { - trimMin = TRIM_MIN; - trimMax = TRIM_MAX; - } - - // Trim line - lcdSetColor(GREY); // TODO add a color - dc->drawSolidFilledRect((width() - TRIM_LINE_WIDTH) / 2, TRIM_SQUARE_SIZE / 2, TRIM_LINE_WIDTH, height() - TRIM_SQUARE_SIZE + 1, CUSTOM_COLOR); - - // Trim square - auto value = getValue(); - coord_t y = height() - TRIM_SQUARE_SIZE - divRoundClosest((height() - TRIM_SQUARE_SIZE) * (value - trimMin), trimMax - trimMin); - drawTrimSquare(dc, 0, y, (value < TRIM_MIN || value > TRIM_MAX) ? HIGHLIGHT_COLOR /* TODO add a color */ : TRIM_BGCOLOR); - - // Trim value / small lines on the square - if (g_model.displayTrims == DISPLAY_TRIMS_ALWAYS) { - // TODO DISPLAY_TRIMS_CHANGE - dc->drawNumber((TRIM_SQUARE_SIZE + 1) / 2, y + 3, divRoundClosest(value * 100, trimMax), FONT(XXS) | FOCUS_COLOR | CENTERED); - } - else { - if (value >= 0) { - dc->drawSolidHorizontalLine(3, y + 4, 9, FOCUS_COLOR); - } - if (value <= 0) { - dc->drawSolidHorizontalLine(3, y + 10, 9, FOCUS_COLOR); - } - } - } -}; \ No newline at end of file + void paint(BitmapBuffer * dc) override; +}; diff --git a/radio/src/gui/colorlcd/radio_calibration.cpp b/radio/src/gui/colorlcd/radio_calibration.cpp index 527a040f2..b83f5b0a2 100644 --- a/radio/src/gui/colorlcd/radio_calibration.cpp +++ b/radio/src/gui/colorlcd/radio_calibration.cpp @@ -83,28 +83,25 @@ void RadioCalibrationPage::buildBody(FormWindow * window) #if defined(PCBHORUS) - new MainViewHorizontalSlider(this, {HMARGIN, LCD_H - TRIM_SQUARE_SIZE, HORIZONTAL_SLIDERS_WIDTH, TRIM_SQUARE_SIZE}, - [=] { return calibratedAnalogs[CALIBRATED_POT1]; }); + new MainViewHorizontalSlider(this, {HMARGIN, LCD_H - TRIM_SQUARE_SIZE, HORIZONTAL_SLIDERS_WIDTH, TRIM_SQUARE_SIZE}, CALIBRATED_POT1); if (IS_POT_MULTIPOS(POT2)) { - new MainView6POS(this, {LCD_W / 2 - MULTIPOS_W / 2, LCD_H - TRIM_SQUARE_SIZE, MULTIPOS_W + 1, MULTIPOS_H}, - [=] { return (1 + (potsPos[1] & 0x0f)); }); + new MainView6POS(this, {LCD_W / 2 - MULTIPOS_W / 2, LCD_H - TRIM_SQUARE_SIZE, MULTIPOS_W + 1, MULTIPOS_H}, 1); } - new MainViewHorizontalSlider(this, {LCD_W - HORIZONTAL_SLIDERS_WIDTH - HMARGIN, LCD_H - TRIM_SQUARE_SIZE, HORIZONTAL_SLIDERS_WIDTH, TRIM_SQUARE_SIZE}, - [=] { return calibratedAnalogs[CALIBRATED_POT3]; }); + new MainViewHorizontalSlider(this, {LCD_W - HORIZONTAL_SLIDERS_WIDTH - HMARGIN, LCD_H - TRIM_SQUARE_SIZE, HORIZONTAL_SLIDERS_WIDTH, TRIM_SQUARE_SIZE}, CALIBRATED_POT3); #if defined(HARDWARE_EXT1) coord_t yOffset = TOPBAR_HEIGHT / 2; if (IS_POT_SLIDER_AVAILABLE(EXT1)) { new MainViewVerticalSlider(this, {HMARGIN, LCD_H / 2 - VERTICAL_SLIDERS_HEIGHT(true) / 2 + yOffset, TRIM_SQUARE_SIZE, VERTICAL_SLIDERS_HEIGHT(true) / 2}, - [=] { return calibratedAnalogs[CALIBRATED_SLIDER_REAR_LEFT]; }); + CALIBRATED_SLIDER_REAR_LEFT); new MainViewVerticalSlider(this, {HMARGIN, LCD_H / 2 + yOffset, TRIM_SQUARE_SIZE, VERTICAL_SLIDERS_HEIGHT(true) / 2}, - [=] { return calibratedAnalogs[CALIBRATED_POT_EXT1]; }); + CALIBRATED_POT_EXT1); } else { new MainViewVerticalSlider(this, {HMARGIN, LCD_H / 2 - VERTICAL_SLIDERS_HEIGHT(true) / 2 + yOffset, TRIM_SQUARE_SIZE, VERTICAL_SLIDERS_HEIGHT(true)}, - [=] { return calibratedAnalogs[CALIBRATED_SLIDER_REAR_LEFT]; }); + CALIBRATED_SLIDER_REAR_LEFT); } #endif @@ -112,23 +109,22 @@ void RadioCalibrationPage::buildBody(FormWindow * window) if (IS_POT_SLIDER_AVAILABLE(EXT2)) { new MainViewVerticalSlider(this, {LCD_W - HMARGIN - TRIM_SQUARE_SIZE, LCD_H / 2 - VERTICAL_SLIDERS_HEIGHT(true) / 2 + yOffset, TRIM_SQUARE_SIZE, VERTICAL_SLIDERS_HEIGHT(true) / 2}, - [=] { return calibratedAnalogs[CALIBRATED_SLIDER_REAR_RIGHT]; }); + CALIBRATED_SLIDER_REAR_RIGHT); new MainViewVerticalSlider(this, {LCD_W - HMARGIN - TRIM_SQUARE_SIZE, LCD_H / 2 + yOffset, TRIM_SQUARE_SIZE, VERTICAL_SLIDERS_HEIGHT(true) / 2}, - [=] { return calibratedAnalogs[CALIBRATED_POT_EXT2]; }); + CALIBRATED_POT_EXT2); } else { new MainViewVerticalSlider(this, {LCD_W - HMARGIN - TRIM_SQUARE_SIZE, LCD_H / 2 - VERTICAL_SLIDERS_HEIGHT(true) / 2 + yOffset, TRIM_SQUARE_SIZE, VERTICAL_SLIDERS_HEIGHT(true)}, - [=] { return calibratedAnalogs[CALIBRATED_SLIDER_REAR_RIGHT]; }); + CALIBRATED_SLIDER_REAR_RIGHT); } #endif -#elif defined(PCBNV14) - new MainViewHorizontalSlider(this, {HMARGIN, LCD_H - TRIM_SQUARE_SIZE, HORIZONTAL_SLIDERS_WIDTH, TRIM_SQUARE_SIZE}, - [=] { return calibratedAnalogs[CALIBRATED_POT1]; }); - new MainViewHorizontalSlider(this, {LCD_W - HORIZONTAL_SLIDERS_WIDTH - HMARGIN, LCD_H - TRIM_SQUARE_SIZE, HORIZONTAL_SLIDERS_WIDTH, TRIM_SQUARE_SIZE}, - [=] { return calibratedAnalogs[CALIBRATED_POT2]; }); +#elif defined(PCBNV14) + new MainViewHorizontalSlider(this, {HMARGIN, LCD_H - TRIM_SQUARE_SIZE, HORIZONTAL_SLIDERS_WIDTH, TRIM_SQUARE_SIZE}, CALIBRATED_POT1); + + new MainViewHorizontalSlider(this, {LCD_W - HORIZONTAL_SLIDERS_WIDTH - HMARGIN, LCD_H - TRIM_SQUARE_SIZE, HORIZONTAL_SLIDERS_WIDTH, TRIM_SQUARE_SIZE}, CALIBRATED_POT2); new TextButton(window, {LCD_W - 120, LCD_H - 140, 90, 40}, "Next", [=]() -> uint8_t { diff --git a/radio/src/gui/colorlcd/screens_setup_old.cpp b/radio/src/gui/colorlcd/screens_setup_old.cpp deleted file mode 100644 index cc12cc312..000000000 --- a/radio/src/gui/colorlcd/screens_setup_old.cpp +++ /dev/null @@ -1,690 +0,0 @@ -/* - * Copyright (C) OpenTX - * - * Based on code named - * 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 "opentx.h" - -uint8_t THEME_ICONS[] = { - ICON_THEME, - ICON_THEME_SETUP, - ICON_THEME_VIEW1, - ICON_THEME_VIEW2, - ICON_THEME_VIEW3, - ICON_THEME_VIEW4, - ICON_THEME_VIEW5, - ICON_THEME_ADD_VIEW, -}; - -Layout * currentScreen; -WidgetsContainerInterface * currentContainer; -Widget * currentWidget; -uint8_t currentZone; -bool widgetNeedsSettings; - -#define SCREENS_SETUP_2ND_COLUMN 200 - -char fileSelection[LEN_ZONE_OPTION_STRING]; -uint8_t fileSelectionDone; - -int updateMainviewsMenu(); -bool menuScreenAdd(event_t event); -void onScreenSetupMenu(const char * result); - -void onZoneOptionFileSelectionMenu(const char * result) -{ - if (result == STR_UPDATE_LIST) { - if (!sdListFiles(BITMAPS_PATH, BITMAPS_EXT, LEN_ZONE_OPTION_STRING, nullptr)) { - POPUP_WARNING(STR_NO_BITMAPS_ON_SD); - } - } - else if (result != STR_EXIT) { - fileSelectionDone = true; - memcpy(fileSelection, result, sizeof(fileSelection)); - } -} - -uint8_t getZoneOptionColumns(const ZoneOption * option) -{ - if (option->type == ZoneOption::Color) { - return uint8_t(2 | NAVIGATION_LINE_BY_LINE); - } - else { - return 0; - } -} - -uint8_t editColorPart(coord_t x, coord_t y, event_t event, uint8_t part, uint8_t value, LcdFlags attr, uint32_t i_flags) -{ - const char * STR_COLOR_PARTS = "\002" "R:" "G:" "B:"; - uint8_t PART_BITS[] = { 5, 6, 5 }; - lcdDrawTextAtIndex(x, y, STR_COLOR_PARTS, part, (attr && menuHorizontalPosition < 0) ? FOCUS_COLOR : DEFAULT_COLOR); - lcdDrawNumber(x + 20, y, value << (8-PART_BITS[part]), LEFT|DEFAULT_COLOR|((attr && (menuHorizontalPosition < 0 || menuHorizontalPosition == part)) ? attr : DEFAULT_COLOR)); - if (attr && menuHorizontalPosition == part) { - value = checkIncDec(event, value, 0, (1 << PART_BITS[part])-1, i_flags); - } - return value; -} - -bool editZoneOption(coord_t y, const ZoneOption * option, ZoneOptionValue * value, LcdFlags attr, uint32_t i_flags, event_t event) -{ - lcdDrawText(MENUS_MARGIN_LEFT, y, option->name); - - if (option->type == ZoneOption::Bool) { - value->boolValue = editCheckBox(value->boolValue, SCREENS_SETUP_2ND_COLUMN, y, attr, event); // TODO always does storageDirty(EE_MODEL) - } - else if (option->type == ZoneOption::Integer) { - lcdDrawNumber(SCREENS_SETUP_2ND_COLUMN, y, value->signedValue, attr | LEFT); - if (attr) { - CHECK_INCDEC_MODELVAR(event, value->signedValue, option->min.signedValue, option->max.signedValue); // TODO i_flags - } - } - else if (option->type == ZoneOption::String) { - editName(SCREENS_SETUP_2ND_COLUMN, y, value->stringValue, sizeof(value->stringValue), event, attr); // TODO i_flags? - } - else if (option->type == ZoneOption::File) { - if (ZEXIST(value->stringValue)) - lcdDrawSizedText(SCREENS_SETUP_2ND_COLUMN, y, value->stringValue, sizeof(value->stringValue), attr); - else - lcdDrawTextAtIndex(SCREENS_SETUP_2ND_COLUMN, y, STR_VCSWFUNC, 0, attr); // TODO define - if (attr) { - if (event==EVT_KEY_FIRST(KEY_ENTER)) { - s_editMode = 0; - if (sdListFiles(BITMAPS_PATH, BITMAPS_EXT, sizeof(value->stringValue), value->stringValue, LIST_NONE_SD_FILE)) { - fileSelectionDone = false; - POPUP_MENU_START(onZoneOptionFileSelectionMenu); - } - else { - POPUP_WARNING(STR_NO_BITMAPS_ON_SD); - } - } - else if (fileSelectionDone) { - memcpy(value->stringValue, fileSelection, sizeof(fileSelection)); - fileSelectionDone = false; - storageDirty(i_flags); - } - } - } - else if (option->type == ZoneOption::TextSize) { - lcdDrawTextAtIndex(SCREENS_SETUP_2ND_COLUMN, y, STR_TEXT_SIZE, value->unsignedValue, attr); - if (attr) { - value->unsignedValue = checkIncDec(event, value->unsignedValue, 0, 4, i_flags); - } - } - else if (option->type == ZoneOption::Timer) { - drawStringWithIndex(SCREENS_SETUP_2ND_COLUMN, y, STR_TIMER, value->unsignedValue + 1, attr); - if (attr) { - value->unsignedValue = checkIncDec(event, value->unsignedValue, 0, MAX_TIMERS - 1, i_flags); - } - } - else if (option->type == ZoneOption::Source) { - drawSource(SCREENS_SETUP_2ND_COLUMN, y, value->unsignedValue, attr); - if (attr) { - CHECK_INCDEC_MODELSOURCE(event, value->unsignedValue, 1, MIXSRC_LAST_TELEM); - } - } - else if (option->type == ZoneOption::Color) { - RGB_SPLIT(value->unsignedValue, r, g, b); - - if (attr && menuHorizontalPosition < 0) { - lcdDrawSolidFilledRect(SCREENS_SETUP_2ND_COLUMN-3, y-1, 230, FH+1, FOCUS_BGCOLOR); - } - - lcdSetColor(value->unsignedValue); - lcdDrawSolidFilledRect(SCREENS_SETUP_2ND_COLUMN-1, y+1, 42, 17, DEFAULT_COLOR); - lcdDrawSolidFilledRect(SCREENS_SETUP_2ND_COLUMN, y+2, 40, 15, CUSTOM_COLOR); - - r = editColorPart(SCREENS_SETUP_2ND_COLUMN + 50, y, event, 0, r, attr, i_flags); - g = editColorPart(SCREENS_SETUP_2ND_COLUMN + 110, y, event, 1, g, attr, i_flags); - b = editColorPart(SCREENS_SETUP_2ND_COLUMN + 170, y, event, 2, b, attr, i_flags); - - if (attr && checkIncDec_Ret) { - value->unsignedValue = RGB_JOIN(r, g, b); - } - } - - return (attr && checkIncDec_Ret); -} - -int getOptionsCount(const ZoneOption * options) -{ - if (options == nullptr) { - return 0; - } - else { - int count = 0; - for (const ZoneOption * option = options; option->name; option++) { - count++; - } - return count; - } -} - -template -bool menuSettings(const char * title, T * object, uint32_t i_flags, event_t event) -{ - - if (object->getErrorMessage()) { - // display error instead of widget settings - // TODO nicer display (proper word-wrap) - SIMPLE_SUBMENU("Widget Error", ICON_MODEL_LUA_SCRIPTS, 1); - int len = strlen(object->getErrorMessage()); - int y = 3*FH; - const char * p = object->getErrorMessage(); - while (len > 0) { - lcdDrawSizedText(MENUS_MARGIN_LEFT, y, p, 30); - p += 30; - y += FH; - len -= 30; - } - return true; - } - - const ZoneOption * options = object->getOptions(); - linesCount = getOptionsCount(options); - uint8_t mstate_tab[MAX_WIDGET_OPTIONS]; - for (int i=0; i0) ? BLINK|INVERS : INVERS); - LcdFlags attr = (menuVerticalPosition == k ? blink : 0); - if (k < linesCount) { - const ZoneOption * option = &options[k]; - ZoneOptionValue * value = object->getOptionValue(k); - if (editZoneOption(y, option, value, attr, i_flags, event)) { - object->update(); - } - } - } - - return true; -} - -bool menuWidgetSettings(event_t event) -{ - return menuSettings(STR_WIDGET_SETTINGS, currentWidget, EE_MODEL, event); -} - -bool menuWidgetChoice(event_t event) -{ - static Widget * previousWidget = nullptr; - static Widget * currentWidget = nullptr; - static std::list::const_iterator iterator; - static Widget::PersistentData tempData; - - switch (event) { - case EVT_ENTRY: - { - previousWidget = currentContainer->getWidget(currentZone); - currentContainer->setWidget(currentZone, nullptr); - iterator = getRegisteredWidgets().cbegin(); - if (previousWidget) { - const WidgetFactory * factory = previousWidget->getFactory(); - std::list::const_iterator it = getRegisteredWidgets().cbegin(); - for (; it != getRegisteredWidgets().cend(); ++it) { - if (factory->getName() == (*it)->getName()) { - iterator = it; - break; - } - } - } - if (iterator != getRegisteredWidgets().cend()) - currentWidget = (*iterator)->create(currentContainer->getZone(currentZone), &tempData); - break; - } - - case EVT_KEY_FIRST(KEY_EXIT): - if (previousWidget) { - if (currentWidget) - delete currentWidget; - currentContainer->setWidget(currentZone, previousWidget); - } - popMenu(); - return false; - - case EVT_KEY_FIRST(KEY_ENTER): - if (iterator != getRegisteredWidgets().cend()) { - if (previousWidget) - delete previousWidget; - currentContainer->createWidget(currentZone, *iterator); - widgetNeedsSettings = currentContainer->getWidget(currentZone)->getFactory()->getOptions(); - storageDirty(EE_MODEL); - } - popMenu(); - return false; - - case EVT_ROTARY_RIGHT: - if (iterator != getRegisteredWidgets().cend() && iterator != --getRegisteredWidgets().cend()) { - ++iterator; - if (currentWidget) - delete currentWidget; - currentWidget = (*iterator)->create(currentContainer->getZone(currentZone), &tempData); - } - break; - - case EVT_ROTARY_LEFT: - if (iterator != getRegisteredWidgets().cbegin()) { - --iterator; - if (currentWidget) - delete currentWidget; - currentWidget = (*iterator)->create(currentContainer->getZone(currentZone), &tempData); - } - break; - } - - currentScreen->refresh(); - - Zone zone = currentContainer->getZone(currentZone); - lcdDrawFilledRect(0, 0, zone.x-2, LCD_H, SOLID, OVERLAY_COLOR | OPACITY(8)); - lcdDrawFilledRect(zone.x+zone.w+2, 0, LCD_W-zone.x-zone.w-2, LCD_H, SOLID, OVERLAY_COLOR | OPACITY(8)); - lcdDrawFilledRect(zone.x-2, 0, zone.w+4, zone.y-2, SOLID, OVERLAY_COLOR | OPACITY(8)); - lcdDrawFilledRect(zone.x-2, zone.y+zone.h+2, zone.w+4, LCD_H-zone.y-zone.h-2, SOLID, OVERLAY_COLOR | OPACITY(8)); - - if (currentWidget) - currentWidget->refresh(); - - if (iterator != getRegisteredWidgets().cbegin()) { - lcdDrawBitmapPattern(zone.x-10, zone.y+zone.h/2-10, LBM_SWIPE_CIRCLE, FOCUS_BGCOLOR); - lcdDrawBitmapPattern(zone.x-10, zone.y+zone.h/2-10, LBM_SWIPE_LEFT, FOCUS_COLOR); - } - if (iterator != --getRegisteredWidgets().cend()) { - lcdDrawBitmapPattern(zone.x+zone.w-9, zone.y+zone.h/2-10, LBM_SWIPE_CIRCLE, FOCUS_BGCOLOR); - lcdDrawBitmapPattern(zone.x+zone.w-9, zone.y+zone.h/2-10, LBM_SWIPE_RIGHT, FOCUS_COLOR); - } - if (currentWidget) - lcdDrawText(zone.x + zone.w, zone.y-1, currentWidget->getFactory()->getName(), RIGHT | DEFAULT_COLOR | FONT(XS) | INVERS); - - return true; -} - -void onZoneMenu(const char * result) -{ - if (result == STR_SELECT_WIDGET) { - pushMenu(menuWidgetChoice); - } - else if (result == STR_WIDGET_SETTINGS) { - pushMenu(menuWidgetSettings); - } - else if (result == STR_REMOVE_WIDGET) { - currentContainer->createWidget(currentZone, nullptr); - storageDirty(EE_MODEL); - } -} - -bool menuWidgetsSetup(event_t event) -{ - switch (event) { - case EVT_ENTRY: - menuVerticalPosition = 0; - break; - case EVT_KEY_FIRST(KEY_EXIT): - killEvents(KEY_EXIT); - popMenu(); - return false; - } - - currentScreen->refresh(); - - for (int i = currentContainer->getZonesCount() - 1; i >= 0; i--) { - Zone zone = currentContainer->getZone(i); - LcdFlags color; - int padding, thickness; - if (currentContainer == topbar) { - color = MENU_COLOR; - padding = 2; - thickness = 1; - } - else { - color = FOCUS_BGCOLOR; - padding = 4; - thickness = 2; - } - if (menuVerticalPosition == i) { - lcdDrawSolidRect(zone.x-padding, zone.y-padding, zone.w+2*padding, zone.h+2*padding, thickness, color); - if (event == EVT_KEY_FIRST(KEY_ENTER)) { - killEvents(KEY_ENTER); - currentZone = menuVerticalPosition; - currentWidget = currentContainer->getWidget(menuVerticalPosition); - if (currentWidget) { - POPUP_MENU_ADD_ITEM(STR_SELECT_WIDGET); - if (currentWidget->getFactory()->getOptions()) - POPUP_MENU_ADD_ITEM(STR_WIDGET_SETTINGS); - POPUP_MENU_ADD_ITEM(STR_REMOVE_WIDGET); - POPUP_MENU_START(onZoneMenu); - } - else { - onZoneMenu(STR_SELECT_WIDGET); - } - } - } - else { - if (widgetNeedsSettings) { - currentWidget = currentContainer->getWidget(menuVerticalPosition); - if (currentWidget) { - widgetNeedsSettings = false; - onZoneMenu(STR_WIDGET_SETTINGS); - } - } - lcdDrawRect(zone.x-padding, zone.y-padding, zone.w+2*padding, zone.h+2*padding, thickness, 0x3F, color); - } - } - navigate(event, currentContainer->getZonesCount(), currentContainer->getZonesCount(), 1); - return true; -} - -template -T * editThemeChoice(coord_t x, coord_t y, std::list & elList, T * current, bool needsOffsetCheck, LcdFlags attr, event_t event) -{ - static uint8_t menuHorizontalOffset = 0; - uint8_t elCount = elList.size(), last, idx; - coord_t pos; - int currentIndex = 0; - typename std::list::const_iterator elItr = elList.cbegin(); - - if (!elCount) - return nullptr; - - for (; elItr != elList.cend(); ++elItr, ++currentIndex) { - if ((*elItr) == current) - break; - } - - if (event == EVT_ENTRY) { - menuHorizontalOffset = 0; - needsOffsetCheck = true; - } - - if (needsOffsetCheck) { - if (currentIndex < menuHorizontalOffset) { - menuHorizontalOffset = currentIndex; - } - else if (currentIndex > menuHorizontalOffset + 3) { - menuHorizontalOffset = currentIndex - 3; - } - } - if (attr) { - if (menuHorizontalPosition < 0) { - lcdDrawSolidFilledRect(x-3, y-1, min(4, elCount)*56+1, 2*FH-5, FOCUS_BGCOLOR); - } - else { - if (needsOffsetCheck) { - menuHorizontalPosition = currentIndex; - } - else if (menuHorizontalPosition < menuHorizontalOffset) { - menuHorizontalOffset = menuHorizontalPosition; - } - else if (menuHorizontalPosition > menuHorizontalOffset + 3) { - menuHorizontalOffset = menuHorizontalPosition - 3; - } - } - } - last = min(menuHorizontalOffset + 4, elCount); - idx = menuHorizontalOffset; - pos = x; - elItr = elList.cbegin(); - std::advance(elItr, min(menuHorizontalOffset, elCount - 1)); - for (; idx < last && elItr != elList.cend(); ++idx, ++elItr, pos += 56) { - (*elItr)->drawThumb(pos, y+1, current == (*elItr) ? ((attr && menuHorizontalPosition < 0) ? FOCUS_COLOR : FOCUS_BGCOLOR) : LINE_COLOR); - } - if (elCount > 4) { - lcdDrawBitmapPattern(x - 12, y+1, LBM_CARROUSSEL_LEFT, menuHorizontalOffset > 0 ? LINE_COLOR : DISABLE_COLOR); - lcdDrawBitmapPattern(x + 4 * 56, y+1, LBM_CARROUSSEL_RIGHT, last < getRegisteredLayouts().size() ? LINE_COLOR : DISABLE_COLOR); - } - if (attr && menuHorizontalPosition >= 0) { - lcdDrawSolidRect(x + (menuHorizontalPosition - menuHorizontalOffset) * 56 - 3, y - 1, 57, 35, 1, FOCUS_BGCOLOR); - if (event == EVT_KEY_FIRST(KEY_ENTER)) { - s_editMode = 0; - elItr = elList.cbegin(); - if (menuHorizontalPosition < (int)elList.size()) - std::advance(elItr, menuHorizontalPosition); - if (elItr != elList.cend()) - return (*elItr); - else - return nullptr; - } - } - return nullptr; -} - -enum menuScreensThemeItems { - ITEM_SCREEN_SETUP_THEME, - ITEM_SCREEN_SETUP_THEME_OPTION1 = ITEM_SCREEN_SETUP_THEME+2 -}; - -bool menuScreensTheme(event_t event) -{ - bool needsOffsetCheck = (menuVerticalPosition != 0 || menuHorizontalPosition < 0); - const ZoneOption * options = theme->getOptions(); - int optionsCount = getOptionsCount(options); - linesCount = ITEM_SCREEN_SETUP_THEME_OPTION1 + optionsCount + 1; - - menuPageCount = updateMainviewsMenu(); - uint8_t mstate_tab[2 + MAX_THEME_OPTIONS + 1] = { uint8_t(NAVIGATION_LINE_BY_LINE | uint8_t(getRegisteredThemes().size()-1)), ORPHAN_ROW }; - for (int i=0; i 0) ? BLINK | INVERS : INVERS); - LcdFlags attr = (menuVerticalPosition == k ? blink : 0); - switch (k) { - case ITEM_SCREEN_SETUP_THEME: { - lcdDrawText(MENUS_MARGIN_LEFT, y + FH / 2, STR_THEME); - Theme * new_theme = editThemeChoice(SCREENS_SETUP_2ND_COLUMN, y, getRegisteredThemes(), theme, needsOffsetCheck, attr, event); - if (new_theme) { - new_theme->init(); - loadTheme(new_theme); - strncpy(g_eeGeneral.themeName, new_theme->getName(), sizeof(g_eeGeneral.themeName)); - killEvents(KEY_ENTER); - storageDirty(EE_GENERAL); - } - break; - } - - case ITEM_SCREEN_SETUP_THEME+1: - break; - - default: - { - uint8_t index = k - ITEM_SCREEN_SETUP_THEME_OPTION1; - if (index < optionsCount) { - const ZoneOption * option = &options[index]; - ZoneOptionValue * value = theme->getOptionValue(index); - bool ret = editZoneOption(y, option, value, attr, EE_GENERAL, event); - if (option->type == ZoneOption::Color) { - if (attr && event == EVT_KEY_FIRST(KEY_EXIT)) { - theme->update(); - } - } - else if (ret) { - theme->update(); - } - } - else if (index == optionsCount) { - lcdDrawText(MENUS_MARGIN_LEFT, y, STR_TOP_BAR); - drawButton(SCREENS_SETUP_2ND_COLUMN, y, STR_SETUP, attr); - if (attr && event == EVT_KEY_FIRST(KEY_ENTER)) { - currentScreen = customScreens[0]; - currentContainer = topbar; - pushMenu(menuWidgetsSetup); - } - } - break; - } - } - } - - return true; -} - -enum MenuScreenSetupItems { - ITEM_SCREEN_SETUP_LAYOUT, - ITEM_SCREEN_SETUP_WIDGETS_SETUP = ITEM_SCREEN_SETUP_LAYOUT+2, - ITEM_SCREEN_SETUP_LAYOUT_OPTION1, -}; - -bool menuScreenSetup(int index, event_t event) -{ - if (customScreens[index] == nullptr) { - return menuScreenAdd(event); - } - - currentScreen = customScreens[index]; - currentContainer = currentScreen; - bool needsOffsetCheck = (menuVerticalPosition != 0 || menuHorizontalPosition < 0); - - char title[] = TR_MAIN_VIEW_X; - title[sizeof(title)-2] = '1' + index; - menuPageCount = updateMainviewsMenu(); - - const ZoneOption * options = currentScreen->getFactory()->getOptions(); - int optionsCount = getOptionsCount(options); - linesCount = ITEM_SCREEN_SETUP_LAYOUT_OPTION1 + optionsCount; - if (menuPageCount > 3) - ++linesCount; - - uint8_t mstate_tab[2 + MAX_LAYOUT_OPTIONS + 1] = { uint8_t(NAVIGATION_LINE_BY_LINE | uint8_t(getRegisteredLayouts().size()-1)), ORPHAN_ROW }; - for (int i=0; i0) ? BLINK|INVERS : INVERS); - LcdFlags attr = (menuVerticalPosition == k ? blink : 0); - switch(k) { - case ITEM_SCREEN_SETUP_LAYOUT: - { - lcdDrawText(MENUS_MARGIN_LEFT, y + FH / 2, STR_LAYOUT); - const LayoutFactory * factory = editThemeChoice(SCREENS_SETUP_2ND_COLUMN, y, getRegisteredLayouts(), currentScreen->getFactory(), needsOffsetCheck, attr, event); - if (factory) { - delete customScreens[index]; - currentScreen = customScreens[index] = factory->create(&g_model.screenData[index].layoutData); - strncpy(g_model.screenData[index].layoutName, factory->getName(), sizeof(g_model.screenData[index].layoutName)); - killEvents(KEY_ENTER); - storageDirty(EE_MODEL); - } - break; - } - - case ITEM_SCREEN_SETUP_LAYOUT+1: - break; - - case ITEM_SCREEN_SETUP_WIDGETS_SETUP: - drawButton(SCREENS_SETUP_2ND_COLUMN, y, STR_SETUP_WIDGETS, attr); - if (attr && event == EVT_KEY_FIRST(KEY_ENTER)) { - pushMenu(menuWidgetsSetup); - } - break; - - default: - { - uint8_t o = k - ITEM_SCREEN_SETUP_LAYOUT_OPTION1; - if (o < optionsCount) { - const ZoneOption * option = &options[o]; - ZoneOptionValue * value = currentScreen->getOptionValue(o); - if (editZoneOption(y, option, value, attr, EE_MODEL, event)) { - currentScreen->update(); - loadCustomScreens(); - } - } - else if (menuPageCount > 3 && o == optionsCount) { - drawButton(SCREENS_SETUP_2ND_COLUMN, y, STR_REMOVE_SCREEN, attr); - if (attr && event == EVT_KEY_LONG(KEY_ENTER)) { - delete currentScreen; - if (index != MAX_CUSTOM_SCREENS-1) { - memmove(&g_model.screenData[index], &g_model.screenData[index + 1], sizeof(CustomScreenData) * (MAX_CUSTOM_SCREENS - index - 1)); - memmove(&customScreens[index], &customScreens[index + 1], sizeof(Layout *) * (MAX_CUSTOM_SCREENS - index - 1)); - } - memset(&g_model.screenData[MAX_CUSTOM_SCREENS-1], 0, sizeof(CustomScreenData)); - customScreens[MAX_CUSTOM_SCREENS-1] = nullptr; - loadCustomScreens(); - killEvents(KEY_ENTER); - chainMenu(menuTabScreensSetup[index > 0 ? index : 1]); - return false; - } - } - break; - } - } - } - - return true; -} - -template -bool menuCustomScreenSetup(event_t event) -{ - return menuScreenSetup(N, event); -} - -const MenuHandlerFunc menuTabScreensSetup[1+MAX_CUSTOM_SCREENS] = { - menuScreensTheme, - menuCustomScreenSetup<0>, - menuCustomScreenSetup<1>, - menuCustomScreenSetup<2>, - menuCustomScreenSetup<3>, - menuCustomScreenSetup<4> -}; - -int updateMainviewsMenu() -{ - for (int index=1; indexcreate(&g_model.screenData[menuPageCount-2].layoutData); - strncpy(g_model.screenData[menuPageCount-2].layoutName, lf->getName(), sizeof(g_model.screenData[menuPageCount-2].layoutName)); - s_editMode = 0; - menuHorizontalPosition = -1; - killEvents(KEY_ENTER); - storageDirty(EE_MODEL); - return false; - } - - SIMPLE_MENU_WITH_OPTIONS(STR_ADD_MAIN_VIEW, THEME_ICONS, menuTabScreensSetup, menuPageCount, menuPageCount-1, 0); - return true; -} diff --git a/radio/src/gui/colorlcd/topbar.cpp b/radio/src/gui/colorlcd/topbar.cpp index cbe773a1e..7224f5e5d 100644 --- a/radio/src/gui/colorlcd/topbar.cpp +++ b/radio/src/gui/colorlcd/topbar.cpp @@ -41,6 +41,11 @@ rect_t TopBar::getZone(unsigned int index) const }; } +void TopBar::setVisible(bool visible) +{ + setHeight(visible ? TOPBAR_HEIGHT : 0); +} + const char * const STR_MONTHS[] = TR_MONTHS; void TopBar::paint(BitmapBuffer * dc) diff --git a/radio/src/gui/colorlcd/topbar.h b/radio/src/gui/colorlcd/topbar.h index 7a566dd0f..34aac2b69 100644 --- a/radio/src/gui/colorlcd/topbar.h +++ b/radio/src/gui/colorlcd/topbar.h @@ -38,6 +38,8 @@ class TopBar: public WidgetsContainer rect_t getZone(unsigned int index) const override; + void setVisible(bool visible); + void paint(BitmapBuffer * dc) override; void checkEvents() override diff --git a/radio/src/gui/colorlcd/view_main.cpp b/radio/src/gui/colorlcd/view_main.cpp index a8c817951..f74fe4ad2 100644 --- a/radio/src/gui/colorlcd/view_main.cpp +++ b/radio/src/gui/colorlcd/view_main.cpp @@ -22,30 +22,16 @@ #include "menu_model.h" #include "menu_radio.h" #include "menu_screen.h" -// #include "menu_screens.h" #include "model_select.h" #include "view_channels.h" #include "view_statistics.h" +#include "topbar.h" +#include "layouts/sliders.h" +#include "layouts/trims.h" #include "opentx.h" Layout * customScreens[MAX_CUSTOM_SCREENS] = {}; -void onMainViewMenu(const char *result) -{ - /*if (result == STR_VIEW_NOTES) { - pushModelNotes(); - } - else if (result == STR_STATISTICS) { - pushMenu(menuTabStats[0]); - } - else if (result == STR_ABOUT_US) { - chainMenu(menuAboutView); - } - else if (result == STR_MONITOR_SCREENS) { - pushMenu(menuTabMonitors[lastMonitorPage]); - }*/ -} - int getMainViewsCount() { for (int index=1; index uint8_t { @@ -87,7 +72,7 @@ ViewMain::ViewMain(): return 0; }, NO_FOCUS); #endif - + createDecoration(); focusWindow = this; } @@ -95,6 +80,72 @@ ViewMain::~ViewMain() { } +void ViewMain::setTopbarVisible(bool visible) +{ + topbar->setVisible(visible); +} + +void ViewMain::setTrimsVisible(bool visible) +{ + trims[TRIMS_LH]->setHeight(visible ? TRIM_SQUARE_SIZE : 0); + trims[TRIMS_RH]->setHeight(visible ? TRIM_SQUARE_SIZE : 0); + + trims[TRIMS_LV]->setWidth(visible ? TRIM_SQUARE_SIZE : 0); + trims[TRIMS_RV]->setWidth(visible ? TRIM_SQUARE_SIZE : 0); +} + +void ViewMain::setSlidersVisible(bool visible) +{ + // + // Horizontal Sliders + // + sliders[SLIDERS_POT1]->setHeight(visible ? TRIM_SQUARE_SIZE : 0); + + //TODO: might change depending on hardware settings + if (IS_POT_MULTIPOS(POT2)) { + sliders[SLIDERS_POT2]->setHeight(visible ? MULTIPOS_H : 0); + } + else if (IS_POT(POT2)) { + sliders[SLIDERS_POT2]->setHeight(visible ? TRIM_SQUARE_SIZE : 0); + } + +#if defined(HARDWARE_POT3) + sliders[SLIDERS_POT3]->setHeight(visible ? TRIM_SQUARE_SIZE : 0); +#endif + + // + // Vertical sliders + // + sliders[SLIDERS_REAR_LEFT]->setWidth(visible ? TRIM_SQUARE_SIZE : 0); + +#if defined(HARDWARE_EXT1) + //TODO: might change depending on hardware settings + if (IS_POT_SLIDER_AVAILABLE(EXT1)) { + sliders[SLIDERS_EXT1]->setWidth(visible ? TRIM_SQUARE_SIZE : 0); + } +#endif + + sliders[SLIDERS_REAR_RIGHT]->setWidth(visible ? TRIM_SQUARE_SIZE : 0); + +#if defined(HARDWARE_EXT2) + //TODO: might change depending on hardware settings + if (IS_POT_SLIDER_AVAILABLE(EXT2)) { + sliders[SLIDERS_EXT2]->setWidth(visible ? TRIM_SQUARE_SIZE : 0); + } +#endif +} + +void ViewMain::setFlightModeVisible(bool visible) +{ + flightMode->setHeight(visible ? 20 : 0); +} + +void ViewMain::adjustDecoration() +{ + // TODO: + // -> re-compute all the components' positions +} + #if defined(HARDWARE_KEYS) void ViewMain::onEvent(event_t event) { @@ -169,27 +220,204 @@ void ViewMain::paint(BitmapBuffer * dc) if (g_model.view >= getMainViewsCount()) { g_model.view = 0; } -// -// for (uint8_t i=0; irefresh(); } -// else -// customScreens[i]->background(); -// } -// } } -#if 0 -bool menuMainViewChannelsMonitor(event_t event) +void ViewMain::createDecoration() { - switch (event) { - case EVT_KEY_BREAK(KEY_EXIT): - chainMenu(menuMainView); - event = 0; - return false; + createTopbar(); + createSliders(); + createTrims(); + createFlightMode(); +} + +void ViewMain::createTopbar() +{ + topbar = new TopBar(this); + topbar->load(); +} + +void ViewMain::createSliders() +{ + // TODO: + // - layout must become really dynamic (see adjustDecoration()) + // - components should be created in "folded" state + // - it should not be required to call hasXXXX() at all + +#if defined(HARDWARE_EXT1) || defined(HARDWARE_EXT2) + coord_t yOffset = /*(hasTrims() ?*/ - TRIM_SQUARE_SIZE /*: 0)*/ + /*(hasTopbar() ?*/ TOPBAR_HEIGHT / 2 /*: 0)*/; +#endif + + // fixed size array, so that works + memset(sliders, 0, sizeof(sliders)); + + rect_t r = { + HMARGIN, + LCD_H - TRIM_SQUARE_SIZE, + HORIZONTAL_SLIDERS_WIDTH, + TRIM_SQUARE_SIZE + }; + + sliders[SLIDERS_POT1] = new MainViewHorizontalSlider(this, r, CALIBRATED_POT1); + + if (IS_POT_MULTIPOS(POT2)) { + + r = rect_t { + LCD_W / 2 - MULTIPOS_W / 2, + LCD_H - TRIM_SQUARE_SIZE, + MULTIPOS_W + 1, + MULTIPOS_H + }; + + sliders[SLIDERS_POT2] = new MainView6POS(this, r, 1); + } + else if (IS_POT(POT2)) { + + r = { + LCD_W - HORIZONTAL_SLIDERS_WIDTH - HMARGIN, + LCD_H - TRIM_SQUARE_SIZE, + HORIZONTAL_SLIDERS_WIDTH, + TRIM_SQUARE_SIZE + }; + + sliders[SLIDERS_POT2] = new MainViewHorizontalSlider(this, r, CALIBRATED_POT2); } - return menuChannelsView(event); -} +#if defined(HARDWARE_POT3) + r = rect_t { + LCD_W - HORIZONTAL_SLIDERS_WIDTH - HMARGIN, + LCD_H - TRIM_SQUARE_SIZE, + HORIZONTAL_SLIDERS_WIDTH, + TRIM_SQUARE_SIZE + }; + + sliders[SLIDERS_POT3] = new MainViewHorizontalSlider(this, r, CALIBRATED_POT3); #endif + +#if defined(HARDWARE_EXT1) + if (IS_POT_SLIDER_AVAILABLE(EXT1)) { + r = rect_t { + HMARGIN, + LCD_H / 2 - VERTICAL_SLIDERS_HEIGHT(true/*hasTopbar()*/) / 2 + yOffset, + TRIM_SQUARE_SIZE, + VERTICAL_SLIDERS_HEIGHT(true/*hasTopbar()*/) / 2 + }; + + sliders[SLIDERS_REAR_LEFT] = new MainViewVerticalSlider(this, r, CALIBRATED_SLIDER_REAR_LEFT); + + r = rect_t { + HMARGIN, + LCD_H / 2 + yOffset, + TRIM_SQUARE_SIZE, + VERTICAL_SLIDERS_HEIGHT(true/*hasTopbar()*/) / 2 + }; + + sliders[SLIDERS_EXT1] = new MainViewVerticalSlider(this, r, CALIBRATED_POT_EXT1); + } + else { + r = rect_t { + HMARGIN, + LCD_H / 2 - VERTICAL_SLIDERS_HEIGHT(true/*hasTopbar()*/) / 2 + yOffset, + TRIM_SQUARE_SIZE, + VERTICAL_SLIDERS_HEIGHT(true/*hasTopbar()*/) + }; + + sliders[SLIDERS_REAR_LEFT] = new MainViewVerticalSlider(this, r, CALIBRATED_SLIDER_REAR_LEFT); + } +#endif + +#if defined(HARDWARE_EXT2) + if (IS_POT_SLIDER_AVAILABLE(EXT2)) { + r = rect_t { + LCD_W - HMARGIN - TRIM_SQUARE_SIZE, + LCD_H / 2 - VERTICAL_SLIDERS_HEIGHT(true/*hasTopbar()*/) / 2 + yOffset, + TRIM_SQUARE_SIZE, + VERTICAL_SLIDERS_HEIGHT(true/*hasTopbar()*/) / 2 + }; + + sliders[SLIDERS_REAR_RIGHT] = new MainViewVerticalSlider(this, r, CALIBRATED_SLIDER_REAR_RIGHT); + + r = rect_t { + LCD_W - HMARGIN - TRIM_SQUARE_SIZE, + LCD_H / 2 + yOffset, + TRIM_SQUARE_SIZE, + VERTICAL_SLIDERS_HEIGHT(true/*hasTopbar()*/) / 2 + }; + + sliders[SLIDERS_EXT2] = new MainViewVerticalSlider(this, r, CALIBRATED_POT_EXT2); + } + else { + r = rect_t { + LCD_W - HMARGIN - TRIM_SQUARE_SIZE, + LCD_H / 2 - VERTICAL_SLIDERS_HEIGHT(true/*hasTopbar()*/) / 2 + yOffset, + TRIM_SQUARE_SIZE, + VERTICAL_SLIDERS_HEIGHT(true/*hasTopbar()*/) + }; + + sliders[SLIDERS_REAR_RIGHT] = new MainViewVerticalSlider(this, r, CALIBRATED_SLIDER_REAR_RIGHT); + } +#endif +} + +void ViewMain::createTrims() +{ +#if defined(HARDWARE_POT3) || defined(HARDWARE_EXT1) + coord_t xOffset = /*hasSliders() ?*/ TRIM_SQUARE_SIZE /*: 0*/; +#else + coord_t xOffset = 0; +#endif + coord_t yOffset = /*hasTrims() ?*/ - TRIM_SQUARE_SIZE /*: 0)*/; + + // Trim order TRIM_LH, TRIM_LV, TRIM_RV, TRIM_RH + + rect_t r = { + HMARGIN, + LCD_H - TRIM_SQUARE_SIZE + yOffset, + HORIZONTAL_SLIDERS_WIDTH, + TRIM_SQUARE_SIZE + }; + + trims[TRIMS_LH] = new MainViewHorizontalTrim(this, r, 0); + + r = rect_t { + LCD_W - HORIZONTAL_SLIDERS_WIDTH - HMARGIN, + LCD_H - TRIM_SQUARE_SIZE + yOffset, + HORIZONTAL_SLIDERS_WIDTH, + TRIM_SQUARE_SIZE + }; + + trims[TRIMS_RH] = new MainViewHorizontalTrim(this, r, 3); + + r = rect_t { + HMARGIN + xOffset, + LCD_H /2 - VERTICAL_SLIDERS_HEIGHT(true/*hasTopbar()*/) / 2 + yOffset + /*(hasTopbar() ?*/ TOPBAR_HEIGHT / 2 /*: 0)*/, + TRIM_SQUARE_SIZE, + VERTICAL_SLIDERS_HEIGHT(true/*hasTopbar()*/) + }; + + trims[TRIMS_LV] = new MainViewVerticalTrim(this, r, 1); + + r = rect_t { + LCD_W - HMARGIN - TRIM_SQUARE_SIZE - xOffset, + LCD_H /2 - VERTICAL_SLIDERS_HEIGHT(true/*hasTopbar()*/) / 2 + yOffset + /*(hasTopbar() ?*/ TOPBAR_HEIGHT / 2 /*: 0)*/, + TRIM_SQUARE_SIZE, + VERTICAL_SLIDERS_HEIGHT(true/*hasTopbar()*/) + }; + + trims[TRIMS_RV] = new MainViewVerticalTrim(this, r, 2); +} + +void ViewMain::createFlightMode() +{ + rect_t r = { + 50, + LCD_H - 4 - /*(hasSliders() ?*/ 2 * TRIM_SQUARE_SIZE /*: TRIM_SQUARE_SIZE)*/, + LCD_W - 100, + 20 + }; + + std::function getFM = []() -> std::string { + return g_model.flightModeData[mixerCurrentFlightMode].name; + }; + + flightMode = new DynamicText(this, r, getFM, CENTERED); +} diff --git a/radio/src/gui/colorlcd/view_main.h b/radio/src/gui/colorlcd/view_main.h index 69243fa48..2f5231a32 100644 --- a/radio/src/gui/colorlcd/view_main.h +++ b/radio/src/gui/colorlcd/view_main.h @@ -22,6 +22,9 @@ #define _VIEW_MAIN_H_ #include "form.h" +#include + +class TopBar; class ViewMain: public FormWindow { @@ -46,14 +49,54 @@ class ViewMain: public FormWindow } #endif + // Set decoration visibility + void setTopbarVisible(bool visible); + void setTrimsVisible(bool visible); + void setSlidersVisible(bool visible); + void setFlightModeVisible(bool visible); + + // Re-calculate positions + void adjustDecoration(); + protected: static ViewMain * _instance; + enum { + SLIDERS_POT1 = 0, + SLIDERS_POT2, + SLIDERS_POT3, + SLIDERS_REAR_LEFT, + SLIDERS_EXT1, + SLIDERS_REAR_RIGHT, + SLIDERS_EXT2, + SLIDERS_MAX + }; + + enum { + TRIMS_LH = 0, + TRIMS_LV, + TRIMS_RV, + TRIMS_RH, + TRIMS_MAX + }; + + TopBar* topbar; + Window* sliders[SLIDERS_MAX]; + Window* trims[TRIMS_MAX]; + Window* flightMode; + #if defined(HARDWARE_KEYS) void onEvent(event_t event) override; #endif void paint(BitmapBuffer * dc) override; + void openMenu(); + + void createDecoration(); + void createTopbar(); + void createSliders(); + void createTrims(); + void createFlightMode(); }; #endif // _VIEW_MAIN_H_