diff --git a/companion/src/firmwares/opentx/simulator/opentxsimulator.cpp b/companion/src/firmwares/opentx/simulator/opentxsimulator.cpp index 13c9a6eb7..3a0ad12a6 100644 --- a/companion/src/firmwares/opentx/simulator/opentxsimulator.cpp +++ b/companion/src/firmwares/opentx/simulator/opentxsimulator.cpp @@ -179,8 +179,10 @@ namespace NAMESPACE { #include "radio/src/gui/horus/themes/darkblue.cpp" #include "radio/src/gui/horus/layouts/layout2+1.cpp" #include "radio/src/gui/horus/layouts/layout1x1.cpp" +#include "radio/src/gui/horus/layouts/layout2x1.cpp" #include "radio/src/gui/horus/layouts/layout2x2.cpp" #include "radio/src/gui/horus/layouts/layout2x4.cpp" +#include "radio/src/gui/horus/widgets/value.cpp" #include "radio/src/gui/horus/widgets/gauge.cpp" #include "radio/src/gui/horus/widgets/modelpanel.cpp" #include "radio/src/gui/horus/widgets/text.cpp" diff --git a/radio/src/gui/horus/layout.cpp b/radio/src/gui/horus/layout.cpp index 2eeaf95be..e22f8b629 100644 --- a/radio/src/gui/horus/layout.cpp +++ b/radio/src/gui/horus/layout.cpp @@ -20,21 +20,11 @@ #include "opentx.h" -void Layout::setWidget(unsigned int index, const char * name) +void Layout::createWidget(unsigned int index, const WidgetFactory * factory) { memset(persistentData->zones[index].widgetName, 0, sizeof(persistentData->zones[index].widgetName)); - if (name) { - strncpy(persistentData->zones[index].widgetName, name, sizeof(persistentData->zones[index].widgetName)); - widgets[index] = createWidget(name, getZone(index), &persistentData->zones[index].widgetData); - } - else { - widgets[index] = NULL; - } -} - -void Layout::create() -{ - memset(persistentData, 0, sizeof(PersistentData)); + strncpy(persistentData->zones[index].widgetName, factory->getName(), sizeof(persistentData->zones[index].widgetName)); + widgets[index] = factory->create(getZone(index), &persistentData->zones[index].widgetData); } void Layout::load() @@ -50,10 +40,6 @@ void Layout::load() void Layout::refresh(bool setup) { - if (setup) { - lcdDrawBlackOverlay(); - } - for (int i = 0; i < MAX_LAYOUT_ZONES; i++) { if (widgets[i]) { widgets[i]->refresh(); @@ -89,4 +75,3 @@ Layout * loadLayout(const char * name, Layout::PersistentData * persistentData) } return NULL; } - diff --git a/radio/src/gui/horus/layout.h b/radio/src/gui/horus/layout.h index f4f28a3af..885ecf38e 100644 --- a/radio/src/gui/horus/layout.h +++ b/radio/src/gui/horus/layout.h @@ -32,8 +32,7 @@ class Layout friend class LayoutFactory; public: - struct ZonePersistentData - { + struct ZonePersistentData { char widgetName[10]; Widget::PersistentData widgetData; }; @@ -61,9 +60,17 @@ class Layout return widgets[index]; } - void setWidget(unsigned int index, const char * name); + void setWidget(unsigned int index, Widget * widget) + { + widgets[index] = widget; + } - virtual void create(); + void createWidget(unsigned int index, const WidgetFactory * factory); + + virtual void create() + { + memset(persistentData, 0, sizeof(PersistentData)); + } virtual void load(); diff --git a/radio/src/gui/horus/layouts/layout1x1.cpp b/radio/src/gui/horus/layouts/layout1x1.cpp index 102b1855a..525b0f946 100644 --- a/radio/src/gui/horus/layouts/layout1x1.cpp +++ b/radio/src/gui/horus/layouts/layout1x1.cpp @@ -30,6 +30,7 @@ class Layout1x1: public Layout virtual void create() { + Layout::create(); persistentData->options[0].boolValue = true; persistentData->options[1].boolValue = true; } diff --git a/radio/src/gui/horus/layouts/layout2+1.cpp b/radio/src/gui/horus/layouts/layout2+1.cpp index 477641fbd..625140894 100644 --- a/radio/src/gui/horus/layouts/layout2+1.cpp +++ b/radio/src/gui/horus/layouts/layout2+1.cpp @@ -30,6 +30,7 @@ class Layout2P1: public Layout virtual void create() { + Layout::create(); persistentData->options[0].boolValue = true; persistentData->options[1].boolValue = true; persistentData->options[2].boolValue = true; @@ -56,8 +57,8 @@ class Layout2P1: public Layout const Zone Layout2P1::zones[3] = { { 240, 60, 192, 145 }, - { 46, 60, 192, 70 }, - { 46, 135, 192, 70 } + { 46, 60, 182, 66 }, + { 46, 139, 182, 66 } }; const ZoneOption Layout2P1::options[] = { diff --git a/radio/src/gui/horus/layouts/layout2x1.cpp b/radio/src/gui/horus/layouts/layout2x1.cpp new file mode 100644 index 000000000..b7433f63e --- /dev/null +++ b/radio/src/gui/horus/layouts/layout2x1.cpp @@ -0,0 +1,85 @@ +/* + * 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" + +class Layout2x1: public Layout +{ + public: + Layout2x1(const LayoutFactory * factory, Layout::PersistentData * persistentData): + Layout(factory, persistentData) + { + } + + virtual void create() + { + Layout::create(); + persistentData->options[0].boolValue = true; + } + + virtual unsigned int getZonesCount() const + { + return 4; + } + + virtual Zone getZone(unsigned int index) const + { + Zone zone; + zone.w = (LCD_W-3*10) / 2; + zone.x = (index & 1) ? 20 + zone.w : 10; + if (persistentData->options[0].boolValue) { + zone.h = (LCD_H-MENU_HEADER_HEIGHT-2*10); + zone.y = MENU_HEADER_HEIGHT + 10; + } + else { + zone.h = (LCD_H-2*10); + zone.y = 10; + } + return zone; + } + + virtual void refresh(bool setup=false); + + static const ZoneOption options[]; + +}; + +const ZoneOption Layout2x1::options[] = { + { "Top bar", ZoneOption::Bool }, + { NULL, ZoneOption::Bool } +}; + +void Layout2x1::refresh(bool setup) +{ + theme->drawBackground(); + + if (persistentData->options[0].boolValue) { + // Top Bar + drawMainViewTopBar(); + } + + Layout::refresh(setup); +} + +const uint8_t LBM_LAYOUT_2x1[] __DMA = { +#include "mask_layout2x1.lbm" +}; + +BaseLayoutFactory Layout2x1("Layout2x1", LBM_LAYOUT_2x1, Layout2x1::options); diff --git a/radio/src/gui/horus/layouts/layout2x2.cpp b/radio/src/gui/horus/layouts/layout2x2.cpp index d73175cc6..b10c55e64 100644 --- a/radio/src/gui/horus/layouts/layout2x2.cpp +++ b/radio/src/gui/horus/layouts/layout2x2.cpp @@ -30,6 +30,7 @@ class Layout2x2: public Layout virtual void create() { + Layout::create(); persistentData->options[0].boolValue = true; } diff --git a/radio/src/gui/horus/layouts/layout2x4.cpp b/radio/src/gui/horus/layouts/layout2x4.cpp index f0d3ede5f..1c6f441a2 100644 --- a/radio/src/gui/horus/layouts/layout2x4.cpp +++ b/radio/src/gui/horus/layouts/layout2x4.cpp @@ -30,6 +30,7 @@ class Layout2x4: public Layout virtual void create() { + Layout::create(); persistentData->options[0].boolValue = true; persistentData->options[1].boolValue = true; persistentData->options[2].boolValue = true; @@ -49,9 +50,9 @@ class Layout2x4: public Layout { Zone zone; zone.x = (index >= 4) ? 260 : 60; - zone.y = 55 + (index % 4) * 40; + zone.y = 56 + (index % 4) * 42; zone.w = 160; - zone.h = 40; + zone.h = 32; return zone; } diff --git a/radio/src/gui/horus/layouts/mask_layout2x1.png b/radio/src/gui/horus/layouts/mask_layout2x1.png new file mode 100644 index 000000000..eac35c92a Binary files /dev/null and b/radio/src/gui/horus/layouts/mask_layout2x1.png differ diff --git a/radio/src/gui/horus/lcd.cpp b/radio/src/gui/horus/lcd.cpp index 8407e5b78..f4fc2be33 100644 --- a/radio/src/gui/horus/lcd.cpp +++ b/radio/src/gui/horus/lcd.cpp @@ -330,19 +330,24 @@ void lcdDrawLine(coord_t x1, coord_t y1, coord_t x2, coord_t y2, uint8_t pat, Lc } #endif -void lcdDrawRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat, LcdFlags att) +void lcdDrawRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t thickness, uint8_t pat, LcdFlags att) { +#if 0 if (att & ROUND) { lcdDrawVerticalLine(x, y+1, h-2, pat, att); lcdDrawVerticalLine(x+w-1, y+1, h-2, pat, att); lcdDrawHorizontalLine(x+1, y+h-1, w-2, pat, att); lcdDrawHorizontalLine(x+1, y, w-2, pat, att); } - else { - lcdDrawVerticalLine(x, y, h, pat, att); - lcdDrawVerticalLine(x+w-1, y, h, pat, att); - lcdDrawHorizontalLine(x+1, y+h-1, w-2, pat, att); - lcdDrawHorizontalLine(x+1, y, w-2, pat, att); + else +#endif + { + for (int i=0; isetWidget(menuVerticalPosition, result); - storageDirty(EE_MODEL); -} - ZoneOptionValue editZoneOption(coord_t y, const ZoneOption * option, ZoneOptionValue value, LcdFlags attr, evt_t event) { lcdDrawText(MENUS_MARGIN_LEFT, y, option->name); @@ -67,7 +62,7 @@ ZoneOptionValue editZoneOption(coord_t y, const ZoneOption * option, ZoneOptionV } else if (option->type == ZoneOption::Color) { lcdSetColor(value.unsignedValue); - lcdDrawSolidRect(SCREENS_SETUP_2ND_COLUMN, y, 40, 15, attr ? TEXT_INVERTED_BGCOLOR : TEXT_COLOR); + lcdDrawSolidRect(SCREENS_SETUP_2ND_COLUMN, y, 40, 15, 1, attr ? TEXT_INVERTED_BGCOLOR : TEXT_COLOR); lcdDrawSolidFilledRect(SCREENS_SETUP_2ND_COLUMN + 1, y + 1, 38, 13, CUSTOM_COLOR); if (attr) { CHECK_INCDEC_MODELVAR(event, value.unsignedValue, 0, 65535); @@ -104,13 +99,78 @@ bool menuWidgetSettings(evt_t event) return true; } +bool menuWidgetChoice(evt_t event) +{ + static Widget * previousWidget; + static Widget::PersistentData tempData; + + switch (event) { + case EVT_ENTRY: + { + const WidgetFactory * factory; + previousWidget = currentScreen->getWidget(currentZone); + currentScreen->setWidget(currentZone, NULL); + menuHorizontalPosition = 0; + if (previousWidget) { + factory = previousWidget->getFactory(); + for (unsigned int i=0; igetName() == registeredWidgets[i]->getName()) { + menuHorizontalPosition = i; + break; + } + } + } + else { + factory = registeredWidgets[0]; + } + currentWidget = factory->create(currentScreen->getZone(currentZone), &tempData); + break; + } + + case EVT_KEY_BREAK(KEY_EXIT): + delete currentWidget; + currentScreen->setWidget(currentZone, previousWidget); + popMenu(); + return false; + + case EVT_KEY_BREAK(KEY_ENTER): + delete previousWidget; + currentScreen->createWidget(currentZone, registeredWidgets[menuHorizontalPosition]); + storageDirty(EE_MODEL); + popMenu(); + return false; + + case EVT_ROTARY_RIGHT: + if (menuHorizontalPosition < countRegisteredWidgets-1) { + delete currentWidget; + currentWidget = registeredWidgets[++menuHorizontalPosition]->create(currentScreen->getZone(currentZone), &tempData); + } + break; + + case EVT_ROTARY_LEFT: + if (menuHorizontalPosition > 0) { + delete currentWidget; + currentWidget = registeredWidgets[--menuHorizontalPosition]->create(currentScreen->getZone(currentZone), &tempData); + } + break; + } + + currentScreen->refresh(); + lcdDrawBlackOverlay(); + currentWidget->refresh(); + + Zone zone = currentScreen->getZone(currentZone); + lcdDrawBitmapPattern(zone.x+2, zone.y+zone.h/2-15, LBM_CARROUSSEL_LEFT, menuHorizontalPosition > 0 ? LINE_COLOR : CURVE_AXIS_COLOR); + lcdDrawBitmapPattern(zone.x+zone.w-8, zone.y+zone.h/2-15, LBM_CARROUSSEL_RIGHT, menuHorizontalPosition < countRegisteredWidgets-1 ? LINE_COLOR : CURVE_AXIS_COLOR); + + return true; +} + void onZoneMenu(const char * result) { if (result == STR_SELECT_WIDGET) { - for (unsigned int i=0; igetName()); - } - popupMenuHandler = onWidgetChoiceMenu; + currentZone = menuVerticalPosition; + pushMenu(menuWidgetChoice); } else if (result == STR_WIDGET_SETTINGS) { currentWidget = currentScreen->getWidget(menuVerticalPosition); @@ -138,8 +198,7 @@ bool menuSetupWidgets(evt_t event) for (int i=currentScreen->getZonesCount()-1; i>=0; i--) { Zone zone = currentScreen->getZone(i); if (menuVerticalPosition == i) { - lcdDrawSolidRect(zone.x, zone.y, zone.w, zone.h, TEXT_INVERTED_COLOR); - lcdDrawSolidRect(zone.x-1, zone.y-1, zone.w+2, zone.h+2, TEXT_INVERTED_COLOR); + lcdDrawSolidRect(zone.x-4, zone.y-4, zone.w+8, zone.h+8, 2, TEXT_INVERTED_BGCOLOR); if (event == EVT_KEY_BREAK(KEY_ENTER)) { Widget * widget = currentScreen->getWidget(i); if (widget) { @@ -155,14 +214,13 @@ bool menuSetupWidgets(evt_t event) } } else { - lcdDrawRect(zone.x, zone.y, zone.w, zone.h, DOTTED, TEXT_INVERTED_COLOR); + lcdDrawRect(zone.x-4, zone.y-4, zone.w+8, zone.h+8, 2, 0x3F, TEXT_INVERTED_BGCOLOR); } } navigate(event, currentScreen->getZonesCount(), currentScreen->getZonesCount(), 1); return true; } -extern MenuHandlerFunc menuTabMainviews[1+MAX_CUSTOM_SCREENS]; extern int updateMainviewsMenu(); template @@ -217,7 +275,7 @@ T * editThemeChoice(coord_t x, coord_t y, T * array[], uint8_t count, T * curren lcdDrawBitmapPattern(x + 4 * 56, y, LBM_CARROUSSEL_RIGHT, last < countRegisteredLayouts ? LINE_COLOR : CURVE_AXIS_COLOR); } if (attr && menuHorizontalPosition >= 0) { - lcdDrawSolidRect(x + (menuHorizontalPosition - menuHorizontalOffset) * 56 - 3, y - 2, 57, 35, TEXT_INVERTED_BGCOLOR); + lcdDrawSolidRect(x + (menuHorizontalPosition - menuHorizontalOffset) * 56 - 3, y - 2, 57, 35, 1, TEXT_INVERTED_BGCOLOR); if (menuHorizontalPosition != currentIndex && event == EVT_KEY_BREAK(KEY_ENTER)) { s_editMode = 0; return array[menuHorizontalPosition]; @@ -360,4 +418,4 @@ int updateMainviewsMenu() } } return 1+MAX_CUSTOM_SCREENS; -} \ No newline at end of file +} diff --git a/radio/src/gui/horus/view_main.cpp b/radio/src/gui/horus/view_main.cpp index 272f618c7..52b16c717 100644 --- a/radio/src/gui/horus/view_main.cpp +++ b/radio/src/gui/horus/view_main.cpp @@ -187,7 +187,7 @@ void onMainViewMenu(const char *result) chainMenu(menuStatisticsView); } else if (result == STR_SETUP_SCREENS) { - pushMenu(menuScreensTheme); + pushMenu(menuTabMainviews[1]); } else if (result == STR_ABOUT_US) { chainMenu(menuAboutView); diff --git a/radio/src/gui/horus/view_telemetry.cpp b/radio/src/gui/horus/view_telemetry.cpp index d39fb1c57..5806865b4 100644 --- a/radio/src/gui/horus/view_telemetry.cpp +++ b/radio/src/gui/horus/view_telemetry.cpp @@ -2,7 +2,7 @@ * Copyright (C) OpenTX * * Based on code named - * th9x - http://code.google.com/p/th9x + * th9x - http://code.google.com/p/th9x * er9x - http://code.google.com/p/er9x * gruvin9x - http://code.google.com/p/gruvin9x * @@ -23,145 +23,6 @@ #define STATUS_BAR_Y (7*FH+1) #define TELEM_2ND_COLUMN (11*10) -#if defined(FRSKY_HUB) && defined(GAUGES) -bar_threshold_t barsThresholds[THLD_MAX]; -#endif - -int barCoord(int value, int min, int max, int width) -{ - if (value <= min) - return 0; - else if (value >= max) - return width; - else - return (width * (value - min) + (max - min)/2) / (max - min); -} - -void displayGaugesTelemetryScreen(FrSkyScreenData & screen) -{ - const int GAUGE_MARGIN = 16; - const int GAUGE_HEIGHT = 25; - const int GAUGE_WIDTH = LCD_W - 2*GAUGE_MARGIN; - const int GAUGE_PADDING_HORZ = 4; - const int GAUGE_PADDING_VERT = 2; - const int VAL_WIDTH = 50; - const int BAR_WIDTH = GAUGE_WIDTH-2*GAUGE_PADDING_HORZ-VAL_WIDTH; - - for (int i=0; i<4; ++i) { - FrSkyBarData & bar = screen.bars[i]; - source_t source = bar.source; - getvalue_t barMin = bar.barMin; - getvalue_t barMax = bar.barMax; - if (source <= MIXSRC_LAST_CH) { - barMin = calc100toRESX(barMin); - barMax = calc100toRESX(barMax); - } - if (source && barMax > barMin) { - int y = GAUGE_MARGIN + i*(GAUGE_HEIGHT+GAUGE_MARGIN); - - // The black background - lcdDrawSolidFilledRect(GAUGE_MARGIN, y, GAUGE_WIDTH, GAUGE_HEIGHT, TEXT_BGCOLOR); - - getvalue_t value = getValue(source); - LcdFlags color = TEXT_COLOR; - if (source >= MIXSRC_FIRST_TELEM) { - TelemetryItem & telemetryItem = telemetryItems[(source-MIXSRC_FIRST_TELEM)/3]; // TODO macro to convert a source to a telemetry index - if (!telemetryItem.isAvailable()) { - continue; - } - else if (telemetryItem.isOld()) { - color = ALARM_COLOR; - } - } - else if (source >= MIXSRC_FIRST_TIMER && source <= MIXSRC_LAST_TIMER) { - if (value < 0) { - putsMixerSource(GAUGE_MARGIN+GAUGE_PADDING_HORZ, y+GAUGE_PADDING_VERT, source, ALARM_COLOR); - putsTimer(GAUGE_MARGIN+GAUGE_WIDTH-VAL_WIDTH, y+GAUGE_PADDING_VERT+3, -value, LEFT|DBLSIZE|ALARM_COLOR); - // TODO lcdDrawSolidFilledRect(GAUGE_MARGIN+GAUGE_PADDING_HORZ, y+15, BAR_WIDTH, 6, ALARM_BGCOLOR); - continue; - } - } - - // The label - putsMixerSource(GAUGE_MARGIN+GAUGE_PADDING_HORZ, y+GAUGE_PADDING_VERT, source, color); - - // The value - putsChannel(GAUGE_MARGIN+GAUGE_WIDTH-VAL_WIDTH, y+GAUGE_PADDING_VERT+3, source, LEFT|DBLSIZE|NO_UNIT|color); - - // The bar - // TODO lcdDrawSolidFilledRect(GAUGE_MARGIN+GAUGE_PADDING_HORZ, y+15, BAR_WIDTH, 6, SOLID, color); - //uint8_t thresholdX = 0; - int width = barCoord(value, barMin, barMax, BAR_WIDTH-2); - //uint8_t barShade = SOLID; - lcdDrawSolidFilledRect(GAUGE_MARGIN+GAUGE_PADDING_HORZ+1, y+16, width, 4, TEXT_BGCOLOR); -/* for (uint8_t j=24; j<99; j+=25) { - if (j>thresholdX || j>width) { - lcdDrawSolidVerticalLine(j*BAR_WIDTH/100+BAR_LEFT+1, y+1, barHeight); - } - } - if (thresholdX) { - lcdDrawVerticalLine(BAR_LEFT+1+thresholdX, y-2, barHeight+3, DOTTED); - lcdDrawSolidHorizontalLine(BAR_LEFT+thresholdX, y-2, 3); - } - */ - } - } -} - -void displayNumbersTelemetryScreen(FrSkyScreenData & screen) -{ - const int NUMBERS_W = 56; - const int NUMBERS_H = 30; - const int NUMBERS_MARGIN = 16; - const int NUMBERS_PADDING = 4; - - for (int i=0; i<4; i++) { - for (int j=0; j= MIXSRC_FIRST_TELEM) { - TelemetryItem & telemetryItem = telemetryItems[(field-MIXSRC_FIRST_TELEM)/3]; // TODO macro to convert a source to a telemetry index - if (!telemetryItem.isAvailable()) { - continue; - } - else if (telemetryItem.isOld()) { - color = RED; - } - } - else if (field >= MIXSRC_FIRST_TIMER && field <= MIXSRC_LAST_TIMER) { - TimerState & timerState = timersStates[field-MIXSRC_FIRST_TIMER]; - if (timerState.val < 0) { - color = RED; - } - putsMixerSource(x+NUMBERS_PADDING, y+2, field, color); - putsTimer(x+NUMBERS_PADDING, y+12, abs(timerState.val), LEFT|DBLSIZE|color); - continue; - } - putsMixerSource(x+NUMBERS_PADDING, y+2, field, color); - putsChannel(x+NUMBERS_PADDING, y+12, field, LEFT|DBLSIZE|NO_UNIT|color); - } - } - } -} - -void displayCustomTelemetryScreen(uint8_t index) -{ - FrSkyScreenData & screen = g_model.frsky.screens[index]; - -#if defined(GAUGES) - if (IS_BARS_SCREEN(index)) { - return displayGaugesTelemetryScreen(screen); - } -#endif - - displayNumbersTelemetryScreen(screen); -} - void displayTelemetryScreen(int index, unsigned int evt) { #if defined(LUA) @@ -174,13 +35,9 @@ void displayTelemetryScreen(int index, unsigned int evt) if (TELEMETRY_SCREEN_TYPE(index) == TELEMETRY_SCREEN_TYPE_NONE) { return; } - - if (index < MAX_TELEMETRY_SCREENS) { - return displayCustomTelemetryScreen(index); - } } NOINLINE uint8_t getRssiAlarmValue(uint8_t alarm) { return (45 - 3*alarm + g_model.frsky.rssiAlarms[alarm].value); -} \ No newline at end of file +} diff --git a/radio/src/gui/horus/widgets.cpp b/radio/src/gui/horus/widgets.cpp index 924786965..8365229a1 100644 --- a/radio/src/gui/horus/widgets.cpp +++ b/radio/src/gui/horus/widgets.cpp @@ -61,7 +61,7 @@ void drawButton(coord_t x, coord_t y, const char * label, LcdFlags attr) if (attr & (BUTTON_OFF|BUTTON_ON)) { padding = 5; } - lcdDrawSolidRect(x-1, y-1, padding+width+18+padding, 20, TEXT_COLOR); + lcdDrawSolidRect(x-1, y-1, padding+width+18+padding, 20, 1, TEXT_COLOR); if (attr & INVERS) { lcdDrawSolidFilledRect(x, y, padding+width+16+padding, 18, TEXT_INVERTED_BGCOLOR); lcdDrawText(x+padding+8, y, label, TEXT_INVERTED_COLOR); @@ -87,10 +87,10 @@ void drawCheckBox(coord_t x, coord_t y, uint8_t value, LcdFlags attr) else { if (value) { lcdDrawSolidFilledRect(x+2, y+5, 7, 7, SCROLLBOX_COLOR); - lcdDrawSolidRect(x, y+3, 11, 11, LINE_COLOR); + lcdDrawSolidRect(x, y+3, 11, 11, 1, LINE_COLOR); } else { - lcdDrawSolidRect(x, y+3, 11, 11, LINE_COLOR); + lcdDrawSolidRect(x, y+3, 11, 11, 1, LINE_COLOR); } } } diff --git a/radio/src/gui/horus/widgets/gauge.cpp b/radio/src/gui/horus/widgets/gauge.cpp index fba3fd38c..22141ea84 100644 --- a/radio/src/gui/horus/widgets/gauge.cpp +++ b/radio/src/gui/horus/widgets/gauge.cpp @@ -67,13 +67,13 @@ void GaugeWidget::refresh() int percent = divRoundClosest(100 * (value_in_range - min), (max - min)); // Gauge label - putsMixerSource(zone.x, zone.y + 5, index, SMLSIZE | TEXT_INVERTED_COLOR); + putsMixerSource(zone.x, zone.y, index, SMLSIZE | TEXT_INVERTED_COLOR); // Gauge lcdSetColor(color); - lcdDrawSolidFilledRect(zone.x, zone.y + 20, zone.w, 16, TEXT_INVERTED_COLOR); - lcdDrawNumber(zone.x+zone.w/2+20, zone.y + 21, percent, SMLSIZE | CUSTOM_COLOR, 0, NULL, "%"); - lcdInvertRect(zone.x + w, zone.y + 20, zone.w - w, 16, CUSTOM_COLOR); + lcdDrawSolidFilledRect(zone.x, zone.y + 15, zone.w, 16, TEXT_INVERTED_COLOR); + lcdDrawNumber((percent >= 100 ? 20 : (percent >= 10 ? 10 : 0)) + zone.x+zone.w/2, zone.y + 16, percent, SMLSIZE | CUSTOM_COLOR, 0, NULL, "%"); + lcdInvertRect(zone.x + w, zone.y + 15, zone.w - w, 16, CUSTOM_COLOR); } -BaseWidgetFactory gaugeWidget("Gauge", "", GaugeWidget::options); \ No newline at end of file +BaseWidgetFactory gaugeWidget("Gauge", "", GaugeWidget::options); diff --git a/radio/src/gui/horus/widgets/modelpanel.cpp b/radio/src/gui/horus/widgets/modelpanel.cpp index b3830294f..87c036d9c 100644 --- a/radio/src/gui/horus/widgets/modelpanel.cpp +++ b/radio/src/gui/horus/widgets/modelpanel.cpp @@ -37,7 +37,7 @@ void ModelPanelWidget::refresh() lcdDrawFilledRect(zone.x, zone.y, zone.w, zone.h, SOLID, MAINVIEW_PANES_COLOR | OPACITY(5)); lcdDrawBitmapPattern(zone.x + 6, zone.y + 4, LBM_MODEL_ICON, MAINVIEW_GRAPHICS_COLOR); lcdDrawSizedText(zone.x + 45, zone.y + 10, g_model.header.name, LEN_MODEL_NAME, ZCHAR | SMLSIZE); - lcdDrawSolidHorizontalLine(zone.x + 39, zone.y + 27, zone.w - 48, MAINVIEW_GRAPHICS_COLOR); + lcdDrawSolidFilledRect(zone.x + 39, zone.y + 27, zone.w - 48, 2, MAINVIEW_GRAPHICS_COLOR); int scale = getBitmapScale(modelBitmap, zone.w, zone.h - 25); int width = getBitmapScaledSize(getBitmapWidth(modelBitmap), scale); int height = getBitmapScaledSize(getBitmapHeight(modelBitmap), scale); diff --git a/radio/src/gui/horus/widgets/value.cpp b/radio/src/gui/horus/widgets/value.cpp new file mode 100644 index 000000000..e2de9c3b3 --- /dev/null +++ b/radio/src/gui/horus/widgets/value.cpp @@ -0,0 +1,99 @@ +/* + * 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" + +class ValueWidget: public Widget +{ + public: + ValueWidget(const WidgetFactory * factory, const Zone & zone, Widget::PersistentData * persistentData): + Widget(factory, zone, persistentData) + { + } + + virtual void create() + { + persistentData->options[0].unsignedValue = 1; + persistentData->options[3].unsignedValue = RED; + } + + void refresh(); + + static const ZoneOption options[]; +}; + +const ZoneOption ValueWidget::options[] = { + { "Source", ZoneOption::Source }, + { NULL, ZoneOption::Bool } +}; + +void ValueWidget::refresh() +{ + const int NUMBERS_W = 56; + const int NUMBERS_H = 30; + const int NUMBERS_MARGIN = 16; + const int NUMBERS_PADDING = 4; + + mixsrc_t field = persistentData->options[0].unsignedValue; + + LcdFlags color = TEXT_COLOR; + int x = zone.x; + int y = zone.y; + + lcdDrawFilledRect(zone.x, zone.y, zone.w, zone.h, SOLID, MAINVIEW_PANES_COLOR | OPACITY(5)); + + int xValue, yValue; + LcdFlags attr; + if (zone.h < 50) { + xValue = x+zone.w-NUMBERS_PADDING; + yValue = y-2; + attr = NO_UNIT; + } + else { + xValue = x+NUMBERS_PADDING; + yValue = y+16; + attr = LEFT; + } + + if (field >= MIXSRC_FIRST_TIMER && field <= MIXSRC_LAST_TIMER) { + TimerState & timerState = timersStates[field-MIXSRC_FIRST_TIMER]; + if (timerState.val < 0) { + color = ALARM_COLOR; + } + putsMixerSource(x+NUMBERS_PADDING, y+2, field, color); + putsTimer(xValue, yValue, abs(timerState.val), attr|DBLSIZE|color); + return; + } + + if (field >= MIXSRC_FIRST_TELEM) { + TelemetryItem & telemetryItem = telemetryItems[(field-MIXSRC_FIRST_TELEM)/3]; // TODO macro to convert a source to a telemetry index + if (!telemetryItem.isAvailable()) { + return; + } + else if (telemetryItem.isOld()) { + color = ALARM_COLOR; + } + } + + putsMixerSource(x+NUMBERS_PADDING, y+2, field, color); + putsChannel(xValue, yValue, field, attr|DBLSIZE|color); +} + +BaseWidgetFactory ValueWidget("Value", "", ValueWidget::options); diff --git a/radio/src/main_arm.cpp b/radio/src/main_arm.cpp index bebad8960..b28cb3361 100644 --- a/radio/src/main_arm.cpp +++ b/radio/src/main_arm.cpp @@ -2,7 +2,7 @@ * Copyright (C) OpenTX * * Based on code named - * th9x - http://code.google.com/p/th9x + * th9x - http://code.google.com/p/th9x * er9x - http://code.google.com/p/er9x * gruvin9x - http://code.google.com/p/gruvin9x * @@ -35,14 +35,14 @@ void handleUsbConnection() /* We used to initialize USB peripheral and driver here. According to my tests this is way too late. The USB peripheral - therefore does not have enough information to start responding to - USB host request, which causes very slow USB device recognition, + therefore does not have enough information to start responding to + USB host request, which causes very slow USB device recognition, multiple USB device resets, etc... If we want to change the USB profile, the procedure is simple: * USB cable must be disconnected * call usbDeInit(); - * call usbUnit(); which initializes USB with the new profile. + * call usbUnit(); which initializes USB with the new profile. Obviously the usbInit() should be modified to have a runtime selection of the USB profile. */ @@ -55,13 +55,13 @@ void handleUsbConnection() if (usbStarted && !usbPlugged()) { usbStarted = false; } - + #if defined(USB_JOYSTICK) if (usbStarted ) { usbJoystickUpdate(); } #endif - + #endif // defined(CPUSTM32) && !defined(SIMU) } @@ -108,9 +108,9 @@ void guiMain(evt_t evt) // run Lua scripts that don't use LCD (to use CPU time while LCD DMA is running) luaTask(0, RUN_MIX_SCRIPT | RUN_FUNC_SCRIPT | RUN_TELEM_BG_SCRIPT, false); - // wait for LCD DMA to finish before continuing, because code from this point + // wait for LCD DMA to finish before continuing, because code from this point // is allowed to change the contents of LCD buffer - // + // // WARNING: make sure no code above this line does any change to the LCD display buffer! // lcdRefreshWait(); @@ -153,8 +153,10 @@ void guiMain(evt_t evt) const char * result = displayPopupMenu(evt); if (result) { popupMenuHandler(result); - evt = EVT_REFRESH; - continue; + if (menuEvent == 0) { + evt = EVT_REFRESH; + continue; + } } } refreshNeeded = true; @@ -197,7 +199,7 @@ void guiMain(evt_t evt) void handleGui(uint8_t event) { // if Lua standalone, run it and don't clear the screen (Lua will do it) // else if Lua telemetry view, run it and don't clear the screen - // else clear scren and show normal menus + // else clear scren and show normal menus #if defined(LUA) if (luaTask(event, RUN_STNDAL_SCRIPT, true)) { // standalone script is active @@ -217,7 +219,7 @@ void handleGui(uint8_t event) { menuHandlers[menuLevel](event); // todo drawStatusLine(); here??? } - else + else #endif { lcdClear(); @@ -249,15 +251,15 @@ void guiMain(evt_t evt) } #endif //#if defined(LUA) - // wait for LCD DMA to finish before continuing, because code from this point + // wait for LCD DMA to finish before continuing, because code from this point // is allowed to change the contents of LCD buffer - // + // // WARNING: make sure no code above this line does any change to the LCD display buffer! // lcdRefreshWait(); if (menuEvent) { - // we have a popupMenuActive entry or exit event + // we have a popupMenuActive entry or exit event menuVerticalPosition = (menuEvent == EVT_ENTRY_UP) ? menuVerticalPositions[menuLevel] : 0; menuHorizontalPosition = 0; evt = menuEvent; @@ -283,7 +285,7 @@ void guiMain(evt_t evt) DISPLAY_WARNING(evt); } else if (popupMenuNoItems > 0) { - // popup menu is active display it on top of normal menus + // popup menu is active display it on top of normal menus handleGui(0); // suppress events, they are handled by the popup if (!inPopupMenu) { TRACE("Popup Menu started");