diff --git a/radio/src/CMakeLists.txt b/radio/src/CMakeLists.txt index a9a323215..23d1e2e05 100644 --- a/radio/src/CMakeLists.txt +++ b/radio/src/CMakeLists.txt @@ -65,7 +65,7 @@ if(PCB STREQUAL HORUS) add_definitions(-DPCBHORUS -DCOLORLCD -DSTM32F429_439xx -DPPM_PIN_HW_SERIAL) add_definitions(-DEEPROM_VARIANT=0 -DAUDIO -DVOICE -DRTCLOCK) add_definitions(-DLUAINPUTS -DXCURVES -DVARIO) - include_directories(${RADIO_SRC_DIRECTORY}/fonts/horus gui/${GUI_DIR}) + include_directories(${RADIO_SRC_DIRECTORY}/fonts/horus gui/${GUI_DIR} gui/${GUI_DIR}/layouts) file(GLOB LAYOUTS_SRC RELATIVE ${RADIO_SRC_DIRECTORY}/gui/horus ${RADIO_SRC_DIRECTORY}/gui/horus/layouts/*.cpp) file(GLOB WIDGETS_SRC RELATIVE ${RADIO_SRC_DIRECTORY}/gui/horus ${RADIO_SRC_DIRECTORY}/gui/horus/widgets/*.cpp) set(GUI_SRC diff --git a/radio/src/bitmaps/horus/CMakeLists.txt b/radio/src/bitmaps/horus/CMakeLists.txt index 906fa2a0a..0a6c29a9e 100644 --- a/radio/src/bitmaps/horus/CMakeLists.txt +++ b/radio/src/bitmaps/horus/CMakeLists.txt @@ -13,5 +13,6 @@ add_bitmaps_target(horus_alpha_bitmaps "${RADIO_SRC_DIRECTORY}/bitmaps/horus/alp add_bitmaps_target(horus_alpha_calibration_bitmaps "${RADIO_SRC_DIRECTORY}/bitmaps/horus/calibration/alpha_*.png" 480 5/6/5/8) add_bitmaps_target(horus_masks ${RADIO_SRC_DIRECTORY}/bitmaps/horus/mask_*.png 480 8bits) add_bitmaps_target(horus_slider_masks "${RADIO_SRC_DIRECTORY}/bitmaps/horus/slider/*.png" 480 8bits) +add_bitmaps_target(horus_layouts_masks "${RADIO_SRC_DIRECTORY}/gui/horus/layouts/*.png" 480 8bits) add_bitmaps_target(horus_fonts ${RADIO_SRC_DIRECTORY}/fonts/horus/*.png 480 8bits) -add_dependencies(horus_bitmaps horus_calibration_bitmaps horus_alpha_bitmaps horus_alpha_calibration_bitmaps horus_masks horus_slider_masks horus_fonts) +add_dependencies(horus_bitmaps horus_calibration_bitmaps horus_alpha_bitmaps horus_alpha_calibration_bitmaps horus_masks horus_slider_masks horus_layouts_masks horus_fonts) diff --git a/radio/src/gui/horus/bitmaps.cpp b/radio/src/gui/horus/bitmaps.cpp index aa141b294..65ffc7295 100644 --- a/radio/src/gui/horus/bitmaps.cpp +++ b/radio/src/gui/horus/bitmaps.cpp @@ -307,3 +307,12 @@ const uint8_t LBM_SLIDER_POINT_MID[] __DMA = { const uint8_t LBM_SLIDER_POINT_IN[] __DMA = { #include "point_in.lbm" }; + +const uint8_t LBM_CARROUSSEL_LEFT[] __DMA = { +#include "mask_carroussel_left.lbm" +}; + +const uint8_t LBM_CARROUSSEL_RIGHT[] __DMA = { +#include "mask_carroussel_right.lbm" +}; + diff --git a/radio/src/gui/horus/bitmaps.h b/radio/src/gui/horus/bitmaps.h index fc5270f6f..e78fe7ff3 100644 --- a/radio/src/gui/horus/bitmaps.h +++ b/radio/src/gui/horus/bitmaps.h @@ -85,4 +85,8 @@ extern const uint8_t LBM_SLIDER_POINT_OUT[]; extern const uint8_t LBM_SLIDER_POINT_MID[]; extern const uint8_t LBM_SLIDER_POINT_IN[]; +// Carroussel bitmaps +extern const uint8_t LBM_CARROUSSEL_LEFT[]; +extern const uint8_t LBM_CARROUSSEL_RIGHT[]; + #endif // _BITMAPS_H_ diff --git a/radio/src/gui/horus/layout.cpp b/radio/src/gui/horus/layout.cpp index 888a2b104..2eeaf95be 100644 --- a/radio/src/gui/horus/layout.cpp +++ b/radio/src/gui/horus/layout.cpp @@ -81,15 +81,6 @@ const LayoutFactory * getLayoutFactory(const char * name) return NULL; } -Layout * createLayout(const char * name, Layout::PersistentData * persistentData) -{ - const LayoutFactory * factory = getLayoutFactory(name); - if (factory) { - return factory->create(persistentData); - } - return NULL; -} - Layout * loadLayout(const char * name, Layout::PersistentData * persistentData) { const LayoutFactory * factory = getLayoutFactory(name); diff --git a/radio/src/gui/horus/layout.h b/radio/src/gui/horus/layout.h index f56089ceb..f22ffa7de 100644 --- a/radio/src/gui/horus/layout.h +++ b/radio/src/gui/horus/layout.h @@ -99,7 +99,7 @@ class LayoutFactory registerLayout(this); } const char * getName() const { return name; } - virtual void drawThumb(uint16_t x, uint16_t y, uint32_t flags) = 0; + virtual void drawThumb(uint16_t x, uint16_t y, uint32_t flags) const = 0; virtual const ZoneOption * getOptions() const = 0; virtual Layout * create(Layout::PersistentData * persistentData) const = 0; virtual Layout * load(Layout::PersistentData * persistentData) const = 0; @@ -119,7 +119,7 @@ class BaseLayoutFactory: public LayoutFactory { } - virtual void drawThumb(uint16_t x, uint16_t y, uint32_t flags) + virtual void drawThumb(uint16_t x, uint16_t y, uint32_t flags) const { extern void lcdDrawBitmapPattern(int x, int y, const uint8_t * bitmap, uint32_t flags, int width=0, int offset=0); lcdDrawBitmapPattern(x, y, bitmap, flags); @@ -152,7 +152,6 @@ class BaseLayoutFactory: public LayoutFactory extern unsigned int countRegisteredLayouts; extern const LayoutFactory * registeredLayouts[MAX_REGISTERED_LAYOUTS]; -Layout * createLayout(const char * name, Layout::PersistentData * persistentData); Layout * loadLayout(const char * name, Layout::PersistentData * persistentData); #endif // _LAYOUT_H_ diff --git a/radio/src/gui/horus/layouts/layout2+1.cpp b/radio/src/gui/horus/layouts/layout2+1.cpp index 15a9fa328..a7d660e6a 100644 --- a/radio/src/gui/horus/layouts/layout2+1.cpp +++ b/radio/src/gui/horus/layouts/layout2+1.cpp @@ -100,4 +100,8 @@ void Layout2P1::refresh(bool setup) Layout::refresh(setup); } -BaseLayoutFactory layout2P1("Layout2P1", NULL, Layout2P1::options); +const uint8_t LBM_LAYOUT_2P1[] __DMA = { +#include "mask_layout2+1.lbm" +}; + +BaseLayoutFactory layout2P1("Layout2P1", LBM_LAYOUT_2P1, Layout2P1::options); diff --git a/radio/src/gui/horus/layouts/layout2x2.cpp b/radio/src/gui/horus/layouts/layout2x2.cpp index 92959bdc5..1d370dabe 100644 --- a/radio/src/gui/horus/layouts/layout2x2.cpp +++ b/radio/src/gui/horus/layouts/layout2x2.cpp @@ -83,4 +83,8 @@ void Layout2x2::refresh(bool setup) Layout::refresh(setup); } -BaseLayoutFactory layout2x2("Layout2x2", NULL, Layout2x2::options); +const uint8_t LBM_LAYOUT_2x2[] __DMA = { +#include "mask_layout2x2.lbm" +}; + +BaseLayoutFactory layout2x2("Layout2x2", LBM_LAYOUT_2x2, Layout2x2::options); diff --git a/radio/src/gui/horus/layouts/layout2x4.cpp b/radio/src/gui/horus/layouts/layout2x4.cpp index 04a9d62af..ecfea25f3 100644 --- a/radio/src/gui/horus/layouts/layout2x4.cpp +++ b/radio/src/gui/horus/layouts/layout2x4.cpp @@ -30,7 +30,6 @@ class Layout2x4: public Layout virtual void create() { - TRACE("create"); persistentData->options[0].boolValue = true; persistentData->options[1].boolValue = true; persistentData->options[2].boolValue = true; @@ -116,4 +115,8 @@ void Layout2x4::refresh(bool setup) Layout::refresh(setup); } -BaseLayoutFactory layout2x4("Layout2x4", NULL, Layout2x4::options); +const uint8_t LBM_LAYOUT_2x4[] __DMA = { +#include "mask_layout2x4.lbm" +}; + +BaseLayoutFactory layout2x4("Layout2x4", LBM_LAYOUT_2x4, Layout2x4::options); diff --git a/radio/src/gui/horus/layouts/mask_layout2+1.png b/radio/src/gui/horus/layouts/mask_layout2+1.png new file mode 100644 index 000000000..6924d82c6 Binary files /dev/null and b/radio/src/gui/horus/layouts/mask_layout2+1.png differ diff --git a/radio/src/gui/horus/layouts/mask_layout2x2.png b/radio/src/gui/horus/layouts/mask_layout2x2.png new file mode 100644 index 000000000..af1f38398 Binary files /dev/null and b/radio/src/gui/horus/layouts/mask_layout2x2.png differ diff --git a/radio/src/gui/horus/layouts/mask_layout2x4.png b/radio/src/gui/horus/layouts/mask_layout2x4.png new file mode 100644 index 000000000..25cecf3cc Binary files /dev/null and b/radio/src/gui/horus/layouts/mask_layout2x4.png differ diff --git a/radio/src/gui/horus/menus.h b/radio/src/gui/horus/menus.h index b18988402..4ac4e0616 100644 --- a/radio/src/gui/horus/menus.h +++ b/radio/src/gui/horus/menus.h @@ -185,7 +185,8 @@ extern int8_t s_editMode; // global editmode // mawrow special values #define TITLE_ROW ((uint8_t)-1) -#define HIDDEN_ROW ((uint8_t)-2) +#define ORPHAN_ROW ((uint8_t)-2) +#define HIDDEN_ROW ((uint8_t)-3) struct CheckIncDecStops { const int count; diff --git a/radio/src/gui/horus/navigation.cpp b/radio/src/gui/horus/navigation.cpp index 291293d58..fbf726447 100644 --- a/radio/src/gui/horus/navigation.cpp +++ b/radio/src/gui/horus/navigation.cpp @@ -597,7 +597,6 @@ bool check(check_event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, u } linesCount = rowcount; - int maxBodyLines = (menuTab ? NUM_BODY_LINES : NUM_BODY_LINES+1); if (menuVerticalPosition <= MENU_FIRST_LINE_EDIT) { menuVerticalOffset = 0; @@ -611,7 +610,7 @@ bool check(check_event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, u } } else if (horTab) { - if (rowcount > maxBodyLines) { + if (rowcount > linesDisplayed) { while (1) { vertpos_t firstLine = 0; for (int numLines=0; firstLine= horTabMax || horTab[lastLine] != HIDDEN_ROW) { numLines++; } } - if (menuVerticalPosition >= lastLine) { + if (menuVerticalPosition >= lastLine || horTab[firstLine] == ORPHAN_ROW) { menuVerticalOffset++; } else { - linesCount = menuVerticalOffset + maxBodyLines; + linesCount = menuVerticalOffset + linesDisplayed; for (int i=lastLine; i horTabMax || horTab[i] != HIDDEN_ROW) { linesCount++; @@ -646,8 +645,8 @@ bool check(check_event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, u } } else { - if (menuVerticalPosition >= maxBodyLines + menuVerticalOffset) { - menuVerticalOffset = menuVerticalPosition-maxBodyLines+1; + if (menuVerticalPosition >= linesDisplayed + menuVerticalOffset) { + menuVerticalOffset = menuVerticalPosition-linesDisplayed+1; } else if (menuVerticalPosition < menuVerticalOffset) { menuVerticalOffset = menuVerticalPosition; diff --git a/radio/src/gui/horus/screens_setup.cpp b/radio/src/gui/horus/screens_setup.cpp index 8d251d3eb..8be8a7938 100644 --- a/radio/src/gui/horus/screens_setup.cpp +++ b/radio/src/gui/horus/screens_setup.cpp @@ -32,7 +32,7 @@ void onWidgetChoiceMenu(const char * result) ZoneOptionValue editZoneOption(coord_t y, const ZoneOption * option, ZoneOptionValue value, LcdFlags attr, evt_t event) { - lcdDrawText(MENUS_MARGIN_LEFT + INDENT_WIDTH, y, option->name); + lcdDrawText(MENUS_MARGIN_LEFT, y, option->name); if (option->type == ZoneOption::Bool) { value.boolValue = editCheckBox(value.boolValue, SCREENS_SETUP_2ND_COLUMN, y, attr, event); @@ -162,6 +162,9 @@ bool menuSetupWidgets(evt_t event) bool menuSetupScreensView(evt_t event) { + static uint8_t menuHorizontalOffset; + static uint8_t lastPositionVertical; + currentScreen = customScreens[0]; unsigned int layoutIndex = 0; @@ -172,40 +175,77 @@ bool menuSetupScreensView(evt_t event) } } - linesCount = 1; + linesCount = 3; const ZoneOption * options = currentScreen->getFactory()->getOptions(); for (const ZoneOption * option = options; option->name; option++) { linesCount++; } - SUBMENU_WITH_OPTIONS("Main views setup", LBM_MAINVIEWS_ICON, linesCount, OPTION_MENU_TITLE_BAR, { 0, 0, 0 }); + SUBMENU_WITH_OPTIONS("Main views setup", LBM_MAINVIEWS_ICON, linesCount, OPTION_MENU_TITLE_BAR, { countRegisteredLayouts-1, ORPHAN_ROW, 0, 0, 0, 0 }); - for (int i=0; i0) ? BLINK|INVERS : INVERS); LcdFlags attr = (menuVerticalPosition == k ? blink : 0); - if (k == 0) { - lcdDrawText(MENUS_MARGIN_LEFT, y, "Layout"); - lcdDrawText(SCREENS_SETUP_2ND_COLUMN, y, currentScreen->getFactory()->getName(), attr); - if (attr) { - layoutIndex = checkIncDec(event, layoutIndex, 0, countRegisteredLayouts-1, EE_MODEL); - if (checkIncDec_Ret) { - customScreens[0] = registeredLayouts[layoutIndex]->create(&g_model.screenData[0].layoutData); - strncpy(g_model.screenData[0].layoutName, customScreens[0]->getFactory()->getName(), sizeof(g_model.screenData[0].layoutName)); + switch(k) { + case 0: { + lcdDrawText(MENUS_MARGIN_LEFT, y + FH / 2, "Layout"); + if (attr) { + if (lastPositionVertical != menuVerticalPosition) { + menuHorizontalOffset = max(0, min(layoutIndex - 1, countRegisteredLayouts - 4)); + menuHorizontalPosition = layoutIndex; + } + else if (menuHorizontalPosition < menuHorizontalOffset) { + menuHorizontalOffset = menuHorizontalPosition; + } + else if (menuHorizontalPosition > menuHorizontalOffset + 3) { + menuHorizontalOffset = menuHorizontalPosition - 3; + } } - else if (event == EVT_KEY_LONG(KEY_ENTER)) { + lastPositionVertical = menuVerticalPosition; + int lastDisplayedLayout = min(menuHorizontalOffset + 4, countRegisteredLayouts); + for (int i=menuHorizontalOffset, x=SCREENS_SETUP_2ND_COLUMN; idrawThumb(x, y, currentScreen->getFactory() == factory ? TEXT_INVERTED_BGCOLOR : LINE_COLOR); + } + if (menuHorizontalOffset > 0) + lcdDrawBitmapPattern(SCREENS_SETUP_2ND_COLUMN - 12, y, LBM_CARROUSSEL_LEFT, LINE_COLOR); + if (lastDisplayedLayout < countRegisteredLayouts) + lcdDrawBitmapPattern(SCREENS_SETUP_2ND_COLUMN + 4 * 56, y, LBM_CARROUSSEL_RIGHT, LINE_COLOR); + if (attr) { + lcdDrawSolidRect(SCREENS_SETUP_2ND_COLUMN + (menuHorizontalPosition - menuHorizontalOffset) * 56 - 3, y - 2, 57, 35, TEXT_INVERTED_BGCOLOR); + if (menuHorizontalPosition != layoutIndex && event == EVT_KEY_BREAK(KEY_ENTER)) { + s_editMode = 0; + customScreens[0] = registeredLayouts[menuHorizontalPosition]->create(&g_model.screenData[0].layoutData); + strncpy(g_model.screenData[0].layoutName, customScreens[0]->getFactory()->getName(), sizeof(g_model.screenData[0].layoutName)); + return false; + } + } + break; + } + + case 1: + break; + + case 2: + drawButton(SCREENS_SETUP_2ND_COLUMN, y, "Setup widgets", attr); + if (attr && event == EVT_KEY_BREAK(KEY_ENTER)) { pushMenu(menuSetupWidgets); } - } - } - else if (k < linesCount) { - const ZoneOption * option = &options[k-1]; - ZoneOptionValue value = currentScreen->getOptionValue(k-1); - value = editZoneOption(y, option, value, attr, event); - if (attr) { - currentScreen->setOptionValue(k-1, value); - } + break; + + default: + if (k < linesCount) { + uint8_t index = k - 3; + const ZoneOption *option = &options[index]; + ZoneOptionValue value = currentScreen->getOptionValue(index); + value = editZoneOption(y, option, value, attr, event); + if (attr) { + currentScreen->setOptionValue(index, value); + } + } + break; } } diff --git a/radio/src/gui/horus/widgets.cpp b/radio/src/gui/horus/widgets.cpp index bb97fd630..3261929b4 100644 --- a/radio/src/gui/horus/widgets.cpp +++ b/radio/src/gui/horus/widgets.cpp @@ -130,9 +130,10 @@ void drawShadow(coord_t x, coord_t y, coord_t w, coord_t h) lcdDrawSolidHorizontalLine(x+2, y+h+1, w, LINE_COLOR); } +uint8_t linesDisplayed; + void drawScreenTemplate(const char * title, const uint8_t * icon, uint32_t options) { - uint8_t linesDisplayed; coord_t bodyTop, bodyBottom; // Header @@ -152,7 +153,7 @@ void drawScreenTemplate(const char * title, const uint8_t * icon, uint32_t optio } } else { - linesDisplayed = NUM_BODY_LINES; + linesDisplayed = NUM_BODY_LINES + 1; bodyTop = MENU_HEADER_HEIGHT; if (title) { lcdDrawText(50, 3, title, MENU_TITLE_COLOR); diff --git a/radio/src/gui/horus/widgets.h b/radio/src/gui/horus/widgets.h index 056ecc973..2cc61aa7f 100644 --- a/radio/src/gui/horus/widgets.h +++ b/radio/src/gui/horus/widgets.h @@ -79,4 +79,6 @@ void drawMainViewTopBar(); void drawMainPots(); void drawTrims(uint8_t flightMode); +extern uint8_t linesDisplayed; + #endif // _WIDGETS_H_