2.4 mainview start (#8030)

* Start work on mainview
This commit is contained in:
3djc
2020-10-13 16:39:05 +02:00
committed by GitHub
parent e6dc1b9b5e
commit f06d47732f
23 changed files with 417 additions and 191 deletions
+4 -2
View File
@@ -22,10 +22,12 @@ set(GUI_SRC
fab_button.cpp
# topbar.cpp
layout.cpp
# widget.cpp
widget.cpp
${THEMES_SRC}
${LAYOUTS_SRC}
# ${WIDGETS_SRC}
# ${WIDGETS_SRC}
widgets/text.cpp
widgets/value.cpp
# popups.cpp
draw_functions.cpp
# menus.cpp
+13
View File
@@ -474,6 +474,19 @@ void drawSensorCustomValue(BitmapBuffer * dc, coord_t x, coord_t y, uint8_t sens
}
}
void drawTimer(BitmapBuffer * dc, coord_t x, coord_t y, int32_t tme, LcdFlags flags)
{
char str[LEN_TIMER_STRING];
getTimerString(str, tme, (flags & TIMEHOUR) != 0);
dc->drawText(x, y, str, flags);
}
void drawSourceValue(BitmapBuffer * dc, coord_t x, coord_t y, source_t source, LcdFlags flags)
{
getvalue_t value = getValue(source);
drawSourceCustomValue(dc, x, y, source, value, flags);
}
void drawSourceCustomValue(BitmapBuffer * dc, coord_t x, coord_t y, source_t source, int32_t value, LcdFlags flags)
{
if (source >= MIXSRC_FIRST_TELEM) {
+2
View File
@@ -64,6 +64,8 @@ void drawHorizontalSlider(BitmapBuffer * dc, coord_t x, coord_t y, int len, int
void drawSlider(coord_t x, coord_t y, int len, int val, int min, int max, uint8_t steps, uint32_t options);
void drawValueOrGVar(BitmapBuffer * dc, coord_t x, coord_t y, gvar_t value, gvar_t vmin, gvar_t vmax, LcdFlags flags = 0);
void drawGVarValue(BitmapBuffer * dc, coord_t x, coord_t y, uint8_t gvar, gvar_t value, LcdFlags flags = 0);
void drawTimer(BitmapBuffer * dc, coord_t x, coord_t y, int32_t tme, LcdFlags flags = 0);
void drawSourceValue(BitmapBuffer * dc, coord_t x, coord_t y, source_t source, LcdFlags flags = 0);
void drawSourceCustomValue(BitmapBuffer * dc, coord_t x, coord_t y, source_t source, int32_t value, LcdFlags flags);
void drawSensorCustomValue(BitmapBuffer * dc, coord_t x, coord_t y, uint8_t sensor, int32_t value, LcdFlags flags = 0);
void drawGPSPosition(BitmapBuffer * dc, coord_t x, coord_t y, int32_t longitude, int32_t latitude, LcdFlags flags = 0);
+1 -1
View File
@@ -35,7 +35,7 @@ class Layout: public WidgetsContainer<MAX_LAYOUT_ZONES, MAX_LAYOUT_OPTIONS>
public:
Layout(const LayoutFactory * factory, PersistentData * persistentData):
WidgetsContainer<MAX_LAYOUT_ZONES, MAX_LAYOUT_OPTIONS>(persistentData),
WidgetsContainer<MAX_LAYOUT_ZONES, MAX_LAYOUT_OPTIONS>({0, 0, LCD_W, LCD_H}, persistentData),
factory(factory)
{
}
+2 -2
View File
@@ -50,9 +50,9 @@ class Layout1x1: public Layout
return 1;
}
Zone getZone(unsigned int index) const override
rect_t getZone(unsigned int index) const override
{
Zone zone = { 10, 10, LCD_W - 2*10, LCD_H - 2*10 };
rect_t zone = { 10, 10, LCD_W - 2*10, LCD_H - 2*10 };
if (persistentData->options[0].value.boolValue) {
zone.y += MENU_HEADER_HEIGHT;
zone.h -= MENU_HEADER_HEIGHT;
+2 -2
View File
@@ -32,7 +32,7 @@ const ZoneOption OPTIONS_LAYOUT_2P1[] = {
{ nullptr, ZoneOption::Bool }
};
const Zone ZONES_LAYOUT_2P1[3] = {
const rect_t ZONES_LAYOUT_2P1[3] = {
{ 240, 60, 192, 152 },
{ 48, 60, 180, 70 },
{ 48, 142, 180, 70 }
@@ -60,7 +60,7 @@ class Layout2P1: public Layout
return DIM(ZONES_LAYOUT_2P1);
}
Zone getZone(unsigned int index) const override
rect_t getZone(unsigned int index) const override
{
return ZONES_LAYOUT_2P1[index];
}
+2 -2
View File
@@ -48,9 +48,9 @@ class Layout2x1: public Layout
return 2;
}
Zone getZone(unsigned int index) const override
rect_t getZone(unsigned int index) const override
{
Zone zone;
rect_t zone;
zone.w = (LCD_W-3*10) / 2;
zone.x = (index & 1) ? 20 + zone.w : 10;
if (persistentData->options[0].value.boolValue) {
+2 -2
View File
@@ -48,9 +48,9 @@ class Layout2x2: public Layout
return 4;
}
Zone getZone(unsigned int index) const override
rect_t getZone(unsigned int index) const override
{
Zone zone;
rect_t zone;
zone.w = (LCD_W-3*10) / 2;
zone.x = (index & 1) ? 20 + zone.w : 10;
if (persistentData->options[0].value.boolValue) {
+2 -2
View File
@@ -62,9 +62,9 @@ class Layout2x4: public Layout
return 8;
}
Zone getZone(unsigned int index) const override
rect_t getZone(unsigned int index) const override
{
Zone zone;
rect_t zone;
zone.x = (index >= 4) ? 260 : 60;
zone.y = 56 + (index % 4) * 42;
zone.w = 160;
@@ -0,0 +1,128 @@
/*
* 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"
#include "sliders.h"
#define HAS_TOPBAR() (persistentData->options[0].value.boolValue == true)
#define HAS_FM() (persistentData->options[1].value.boolValue == true)
#define HAS_SLIDERS() (persistentData->options[2].value.boolValue == true)
#define HAS_TRIMS() (persistentData->options[3].value.boolValue == true)
#define IS_MIRRORED() (persistentData->options[4].value.boolValue == true)
const uint8_t LBM_LAYOUT_4P2[] = {
#include "mask_layout4+2.lbm"
};
const ZoneOption OPTIONS_LAYOUT_4P2[] = {
{ STR_TOP_BAR, ZoneOption::Bool },
{ STR_FLIGHT_MODE, ZoneOption::Bool },
{ STR_SLIDERS, ZoneOption::Bool },
{ STR_TRIMS, ZoneOption::Bool },
{ STR_MIRROR, ZoneOption::Bool },
{ NULL, ZoneOption::Bool }
};
constexpr coord_t HTRIM_W = 120;
constexpr coord_t HTRIM_H = 40;
constexpr coord_t HSLIDER_W = 120;
constexpr coord_t HSLIDER_H = 40;
class Layout4P2: public Layout
{
public:
Layout4P2(const LayoutFactory * factory, Layout::PersistentData * persistentData):
Layout(factory, persistentData)
{
decorate();
}
void create() override
{
Layout::create();
persistentData->options[0].value.boolValue = true;
persistentData->options[1].value.boolValue = true;
persistentData->options[2].value.boolValue = true;
persistentData->options[3].value.boolValue = true;
persistentData->options[4].value.boolValue = false;
persistentData->options[5].value.boolValue = false;
decorate();
}
unsigned int getZonesCount() const override
{
return 6;
}
void decorate()
{
if (1 /*HAS_SLIDERS()*/) {
new MainViewHorizontalSlider(this, {0, LCD_H - HTRIM_H - 1, HTRIM_W, HSLIDER_H}, [=] { return calibratedAnalogs[CALIBRATED_POT1]; }, OPTION_SLIDER_TICKS | OPTION_SLIDER_BIG_TICKS | OPTION_SLIDER_SQUARE_BUTTON);
new MainViewHorizontalSlider(this, {LCD_W - HTRIM_W, LCD_H - HTRIM_H, HTRIM_W, HSLIDER_H}, [=] { return calibratedAnalogs[CALIBRATED_POT3]; }, OPTION_SLIDER_TICKS | OPTION_SLIDER_BIG_TICKS | OPTION_SLIDER_SQUARE_BUTTON);
}
}
rect_t getZone(unsigned int index) const override
{
coord_t areaw = LCD_W - (HAS_SLIDERS() ? 55 : 8) - (HAS_TRIMS() ? 55 : 8);
coord_t areah = LCD_H - 4 - (HAS_TOPBAR() ? 55 : 8) - (HAS_SLIDERS() ? HSLIDER_H + 4 : 4) - (HAS_TRIMS() ? HTRIM_H + 4 : 4);
rect_t zone;
zone.x = IS_MIRRORED() ? ((index >= 4) ? (LCD_W - areaw) / 2 - 4 : 245) : ((index >= 4) ? 245 : (LCD_W - areaw) / 2 - 4);
zone.h = (index >= 4) ? (areah / 2) : (areah / 4) - 2;
zone.y = (index >= 4) ? (HAS_TOPBAR() ? 52 : 6) + (index == 5 ? zone.h + ((HAS_TRIMS() + HAS_SLIDERS() == 1) ? 8 : 10): 0): (HAS_TOPBAR() ? 52 : 6) + (index % 4) * (zone.h + 6);
zone.w = areaw / 2;
return zone;
}
//virtual void refresh();
};
//void Layout4P2::refresh()
//{
//theme->drawBackground();
//if (HAS_TOPBAR()) {
// drawTopBar();
//}
//
//if (HAS_FM()) {
// // Flight mode
// lcdDrawSizedText(LCD_W / 2 - getTextWidth(g_model.flightModeData[mixerCurrentFlightMode].name, sizeof(g_model.flightModeData[mixerCurrentFlightMode].name),
// ZCHAR | SMLSIZE) / 2, 232, g_model.flightModeData[mixerCurrentFlightMode].name,
// sizeof(g_model.flightModeData[mixerCurrentFlightMode].name), ZCHAR | SMLSIZE);
//}
//
//if (HAS_SLIDERS()) {
// // Pots and rear sliders positions
// drawMainPots();
//}
//
//if (HAS_TRIMS()) {
// // Trims
// drawTrims(mixerCurrentFlightMode, HAS_SLIDERS());
//}
//Layout::refresh();
//}
BaseLayoutFactory<Layout4P2> layout4P2("Layout4P2", "4 + 2", LBM_LAYOUT_4P2, OPTIONS_LAYOUT_4P2);
Binary file not shown.

After

Width:  |  Height:  |  Size: 239 B

+60
View File
@@ -0,0 +1,60 @@
/*
* 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.
*/
#pragma once
#include "libopenui.h"
class MainViewSlider : public Window
{
public:
MainViewSlider(Window * parent, const rect_t & rect, std::function<int8_t()> getValue, uint32_t options):
Window(parent, rect),
options(options),
getValue(std::move(getValue))
{
}
void checkEvents() override
{
Window::checkEvents();
int8_t newValue = getValue();
if (value != newValue) {
value = newValue;
invalidate();
}
}
protected:
uint32_t options = 0;
std::function<int8_t()> getValue;
int8_t value = 0;
};
class MainViewHorizontalSlider : public MainViewSlider
{
public:
using MainViewSlider::MainViewSlider;
void paint(BitmapBuffer * dc) override
{
drawHorizontalSlider(dc, 0, 0, width(), getValue(), -RESX, RESX, 40, options);
}
};
+14
View File
@@ -82,6 +82,20 @@ class LayoutChoice: public FormField {
}
#endif
#if defined(HARDWARE_TOUCH)
bool onTouchEnd(coord_t, coord_t) override
{
if (enabled) {
if (!hasFocus()) {
setFocus(SET_FOCUS_DEFAULT);
}
onKeyPress();
openMenu();
}
return true;
}
#endif
void openMenu()
{
auto menu = new Menu(parent);
+7 -7
View File
@@ -26,14 +26,14 @@ unsigned int Topbar::getZonesCount() const
return MAX_TOPBAR_ZONES;
}
Zone Topbar::getZone(unsigned int index) const
rect_t Topbar::getZone(unsigned int index) const
{
Zone zone;
zone.x = 49 + (TOPBAR_ZONE_WIDTH + 2*TOPBAR_ZONE_MARGIN) * index;
zone.y = TOPBAR_ZONE_MARGIN;
zone.w = TOPBAR_ZONE_WIDTH;
zone.h = MENU_HEADER_HEIGHT - 2*TOPBAR_ZONE_MARGIN;
return zone;
rect_t rect;
rect.x = 49 + (TOPBAR_ZONE_WIDTH + 2*TOPBAR_ZONE_MARGIN) * index;
rect.y = TOPBAR_ZONE_MARGIN;
rect.w = TOPBAR_ZONE_WIDTH;
rect.h = TOPBAR_HEIGHT;
return rect;
}
const char * const STR_MONTHS[] = TR_MONTHS;
+5 -4
View File
@@ -26,19 +26,20 @@
#define MAX_TOPBAR_ZONES 4
#define MAX_TOPBAR_OPTIONS 1 // just because of VC++ which doesn't like 0-size arrays :(
#define TOPBAR_ZONE_WIDTH 70
#define TOPBAR_ZONE_MARGIN 3
constexpr coord_t TOPBAR_ZONE_MARGIN = 3;
constexpr coord_t TOPBAR_HEIGHT = MENU_HEADER_HEIGHT - 2 * TOPBAR_ZONE_MARGIN;
class Topbar: public WidgetsContainer<MAX_TOPBAR_ZONES, MAX_TOPBAR_OPTIONS>
{
public:
explicit Topbar(PersistentData * persistentData):
WidgetsContainer<MAX_TOPBAR_ZONES, MAX_TOPBAR_OPTIONS>(persistentData)
WidgetsContainer<MAX_TOPBAR_ZONES, MAX_TOPBAR_OPTIONS>({0, 0, LCD_W, TOPBAR_ZONE_WIDTH}, persistentData)
{
}
virtual unsigned int getZonesCount() const;
unsigned int getZonesCount() const override;
virtual Zone getZone(unsigned int index) const;
rect_t getZone(unsigned int index) const override;
};
#endif // _TOPBAR_H_
+18 -9
View File
@@ -239,6 +239,15 @@ void ViewMain::openMenu()
void ViewMain::checkEvents()
{
Window::checkEvents();
// TODO attach elsewhere
for (uint8_t i=0; i<MAX_CUSTOM_SCREENS; i++) {
if (customScreens[i]) {
if (i == g_model.view && !customScreens[i]->getParent()) {
customScreens[i]->attach(this);
}
}
}
}
void ViewMain::paint(BitmapBuffer * dc)
@@ -250,15 +259,15 @@ void ViewMain::paint(BitmapBuffer * dc)
if (g_model.view >= getMainViewsCount()) {
g_model.view = 0;
}
for (uint8_t i=0; i<MAX_CUSTOM_SCREENS; i++) {
if (customScreens[i]) {
if (i == g_model.view) {
customScreens[i]->refresh(); }
else
customScreens[i]->background();
}
}
//
// for (uint8_t i=0; i<MAX_CUSTOM_SCREENS; i++) {
// if (customScreens[i]) {
// if (i == g_model.view) {
// customScreens[i]->refresh(); }
// else
// customScreens[i]->background();
// }
// }
}
#if 0
+2 -2
View File
@@ -43,11 +43,11 @@ const WidgetFactory * getWidgetFactory(const char * name)
return nullptr;
}
Widget * loadWidget(const char * name, const Zone & zone, Widget::PersistentData * persistentData)
Widget * loadWidget(const char * name, Window * parent, const rect_t & rect, Widget::PersistentData * persistentData)
{
const WidgetFactory * factory = getWidgetFactory(name);
if (factory) {
return factory->create(zone, persistentData, false);
return factory->create(parent, rect, persistentData, false);
}
return nullptr;
}
+9 -14
View File
@@ -34,23 +34,21 @@
#endif
class WidgetFactory;
class Widget
class Widget : public Window
{
public:
struct PersistentData {
ZoneOptionValueTyped options[MAX_WIDGET_OPTIONS] USE_IDX;
};
Widget(const WidgetFactory * factory, const Zone & zone, PersistentData * persistentData):
Widget(const WidgetFactory * factory, Window * parent, const rect_t & rect, PersistentData * persistentData):
Window(parent, rect),
factory(factory),
zone(zone),
persistentData(persistentData)
{
}
virtual ~Widget()
{
}
~Widget() override = default;
virtual void update()
{
@@ -73,15 +71,12 @@ class Widget
return &persistentData->options[index].value;
}
virtual void refresh() = 0;
virtual void background()
{
}
protected:
const WidgetFactory * factory;
Zone zone;
PersistentData * persistentData;
};
@@ -90,7 +85,7 @@ void registerWidget(const WidgetFactory * factory);
class WidgetFactory
{
public:
WidgetFactory(const char * name, const ZoneOption * options=nullptr):
explicit WidgetFactory(const char * name, const ZoneOption * options = nullptr):
name(name),
options(options)
{
@@ -121,7 +116,7 @@ class WidgetFactory
}
}
virtual Widget * create(const Zone & zone, Widget::PersistentData * persistentData, bool init=true) const = 0;
virtual Widget * create(Window * parent, const rect_t & rect, Widget::PersistentData * persistentData, bool init = true) const = 0;
protected:
const char * name;
@@ -137,13 +132,13 @@ class BaseWidgetFactory: public WidgetFactory
{
}
virtual Widget * create(const Zone & zone, Widget::PersistentData * persistentData, bool init=true) const
Widget * create(Window * parent, const rect_t & rect, Widget::PersistentData * persistentData, bool init = true) const override
{
if (init) {
initPersistentData(persistentData);
}
return new T(this, zone, persistentData);
return new T(this, parent, rect, persistentData);
}
};
@@ -152,7 +147,7 @@ inline const ZoneOption * Widget::getOptions() const
return getFactory()->getOptions();
}
Widget * loadWidget(const char * name, const Zone & zone, Widget::PersistentData * persistentData);
Widget * loadWidget(const char * name, Window * parent, const rect_t & rect, Widget::PersistentData * persistentData);
std::list<const WidgetFactory *> & getRegisteredWidgets();
+27 -20
View File
@@ -20,17 +20,40 @@
#include "opentx.h"
#define TEXT_WIDGET_DEFAULT_LABEL '\15', '\347', '\0', '\14', '\377', '\376', '\373', '\364' // "My Label"
#define TEXT_WIDGET_DEFAULT_LABEL 'M', 'y', ' ', 'L', 'a', 'b', 'e', 'l' // "My Label"
class TextWidget: public Widget
{
public:
TextWidget(const WidgetFactory * factory, const Zone & zone, Widget::PersistentData * persistentData):
Widget(factory, zone, persistentData)
TextWidget(const WidgetFactory * factory, Window * parent, const rect_t & rect, Widget::PersistentData * persistentData):
Widget(factory, parent, rect, persistentData)
{
}
void refresh() override;
void paint(BitmapBuffer * dc) override
{
// TODO DELETE THOSE TEST INIT VALUE !!
strcpy(persistentData->options[0].value.stringValue, "This is a test string");
persistentData->options[3].value.boolValue = true; // shadow
// TODO END TEST INIT VALUE
// clear the background
dc->clear(DEFAULT_BGCOLOR);
// get font color from options[1]
lcdSetColor(persistentData->options[1].value.unsignedValue);
// get font size from options[2]
LcdFlags fontsize = persistentData->options[2].value.unsignedValue << 8u;
// draw shadow
if (persistentData->options[3].value.boolValue) {
dc->drawText(1, 1, persistentData->options[0].value.stringValue, fontsize | BLACK);
}
// draw text
dc->drawText(0, 0, persistentData->options[0].value.stringValue, fontsize | CUSTOM_COLOR);
}
static const ZoneOption options[];
};
@@ -43,20 +66,4 @@ const ZoneOption TextWidget::options[] = {
{ nullptr, ZoneOption::Bool }
};
void TextWidget::refresh()
{
lcdSetColor(persistentData->options[1].value.unsignedValue);
LcdFlags fontsize = FONTSIZE(persistentData->options[2].value.unsignedValue << 8);
if(persistentData->options[3].value.boolValue) {
lcdDrawSizedText(zone.x+1, zone.y+1,
persistentData->options[0].value.stringValue,
sizeof(persistentData->options[0].value.stringValue),
ZCHAR|fontsize|BLACK);
}
lcdDrawSizedText(zone.x, zone.y,
persistentData->options[0].value.stringValue,
sizeof(persistentData->options[0].value.stringValue),
ZCHAR|fontsize|CUSTOM_COLOR);
}
BaseWidgetFactory<TextWidget> textWidget("Text", TextWidget::options);
+97 -84
View File
@@ -20,17 +20,111 @@
#include "opentx.h"
const coord_t NUMBERS_PADDING = 4;
class ValueWidget: public Widget
{
public:
ValueWidget(const WidgetFactory * factory, const Zone & zone, Widget::PersistentData * persistentData):
Widget(factory, zone, persistentData)
ValueWidget(const WidgetFactory * factory, Window * parent, const rect_t & rect, Widget::PersistentData * persistentData):
Widget(factory, parent, rect, persistentData)
{
}
void refresh() override;
void paint(BitmapBuffer * dc) override
{
// TODO DELETE THOSE TEST INIT VALUE !!
persistentData->options[0].value.unsignedValue = 1;
// TODO END TEST INIT VALUE
// draw the background and border
dc->clear(DEFAULT_BGCOLOR);
dc->drawFilledRect(0,0, width(), height(), SOLID, MAINVIEW_PANES_COLOR | OPACITY(5));
// get source from options[0]
mixsrc_t field = persistentData->options[0].value.unsignedValue;
// get color from options[1]
lcdSetColor(persistentData->options[1].value.unsignedValue);
coord_t xValue, yValue, xLabel, yLabel;
LcdFlags attrValue, attrLabel = 0;
if (width() < 120 && height() < 50) {
xValue = 0;
yValue = 14;
xLabel = 0;
yLabel = 0;
attrValue = LEFT | NO_UNIT | FONT(XS);
attrLabel = FONT(XS);
}
else if (height() < 50) {
xValue = width() - NUMBERS_PADDING;
yValue = -2;
xLabel = NUMBERS_PADDING;
yLabel = +2;
attrValue = RIGHT | NO_UNIT | FONT(XL);
}
else {
xValue = NUMBERS_PADDING;
yValue = 18;
xLabel = NUMBERS_PADDING;
yLabel = 2;
if (field >= MIXSRC_FIRST_TELEM) {
if (isGPSSensor(1 + (field - MIXSRC_FIRST_TELEM) / 3)) {
attrValue = LEFT | FONT(L) | EXPANDED;
}
else {
attrValue = LEFT | FONT(XL);
}
}
#if defined(INTERNAL_GPS)
else if (field == MIXSRC_TX_GPS) {
attrValue = LEFT | FONT(L) | EXPANDED;
}
#endif
else {
attrValue = LEFT | FONT(XL);
}
}
if (field >= MIXSRC_FIRST_TIMER && field <= MIXSRC_LAST_TIMER) {
TimerState & timerState = timersStates[field - MIXSRC_FIRST_TIMER];
if (timerState.val < 0) {
lcdSetColor(lcdColorTable[ALARM_COLOR_INDEX]);
}
drawSource(dc, NUMBERS_PADDING, 2, field, CUSTOM_COLOR);
drawSource(dc, NUMBERS_PADDING + 1, 3, field, BLACK);
drawTimer(dc, xValue, yValue, abs(timerState.val), attrValue | FONT(XL) | CUSTOM_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() || telemetryItem.isOld()) {
lcdSetColor(lcdColorTable[TEXT_DISABLE_COLOR_INDEX]);
}
}
if (persistentData->options[2].value.boolValue) {
drawSource(dc,xLabel + 1, yLabel + 1, field, attrLabel | BLACK);
drawSourceValue(dc, xValue + 1, yValue + 1, field, attrValue | BLACK);
}
drawSource(dc, xLabel, yLabel, field, attrLabel | CUSTOM_COLOR);
drawSourceValue(dc, xValue, yValue, field, attrValue | CUSTOM_COLOR);
}
void checkEvents() override
{
auto newValue = getValue(persistentData->options[0].value.unsignedValue);
if (lastValue != newValue) {
lastValue = newValue;
invalidate();
}
}
static const ZoneOption options[];
int32_t lastValue = 0;
};
const ZoneOption ValueWidget::options[] = {
@@ -40,85 +134,4 @@ const ZoneOption ValueWidget::options[] = {
{ nullptr, ZoneOption::Bool }
};
void ValueWidget::refresh()
{
const int NUMBERS_PADDING = 4;
mixsrc_t field = persistentData->options[0].value.unsignedValue;
lcdSetColor(persistentData->options[1].value.unsignedValue);
int x = zone.x;
int y = zone.y;
// TRACE("w=%d, h=%d", zone.w, zone.h);
// lcdDrawFilledRect(zone.x, zone.y, zone.w, zone.h, SOLID, MAINVIEW_PANES_COLOR | OPACITY(5));
int xValue, yValue, xLabel, yLabel;
LcdFlags attrValue, attrLabel=0;
if (zone.w < 120 && zone.h < 50) {
xValue = x;
yValue = y+14;
xLabel = x;
yLabel = y;
attrValue = LEFT | NO_UNIT | MIDSIZE;
attrLabel = FONT(XS);
}
else if (zone.h < 50) {
xValue = x+zone.w-NUMBERS_PADDING;
yValue = y-2;
xLabel = x+NUMBERS_PADDING;
yLabel = y+2;
attrValue = RIGHT | NO_UNIT | FONT(XL);
}
else {
xValue = x+NUMBERS_PADDING;
yValue = y+18;
xLabel = x+NUMBERS_PADDING;
yLabel = y+2;
if (field >= MIXSRC_FIRST_TELEM) {
if (isGPSSensor(1+(field-MIXSRC_FIRST_TELEM)/3)) {
attrValue = LEFT | MIDSIZE | EXPANDED;
}
else {
attrValue = LEFT | FONT(XL);
}
}
#if defined(INTERNAL_GPS)
else if (field == MIXSRC_TX_GPS) {
attrValue = LEFT | MIDSIZE | EXPANDED;
}
#endif
else {
attrValue = LEFT | FONT(XL);
}
}
if (field >= MIXSRC_FIRST_TIMER && field <= MIXSRC_LAST_TIMER) {
TimerState & timerState = timersStates[field-MIXSRC_FIRST_TIMER];
if (timerState.val < 0) {
lcdSetColor(lcdColorTable[ALARM_COLOR_INDEX]);
}
drawSource(x+NUMBERS_PADDING, y+2, field, CUSTOM_COLOR);
drawSource(x+NUMBERS_PADDING + 1, y + 3, field, BLACK);
drawTimer(xValue, yValue, abs(timerState.val), attrValue|FONT(XL)|CUSTOM_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() || telemetryItem.isOld()) {
lcdSetColor(lcdColorTable[TEXT_DISABLE_COLOR_INDEX]);
}
}
if(persistentData->options[2].value.boolValue) {
drawSource(xLabel + 1, yLabel + 1, field, attrLabel|BLACK);
drawSourceValue(xValue + 1, yValue + 1, field, attrValue|BLACK);
}
drawSource(xLabel, yLabel, field, attrLabel|CUSTOM_COLOR);
drawSourceValue(xValue, yValue, field, attrValue|CUSTOM_COLOR);
}
BaseWidgetFactory<ValueWidget> ValueWidget("Value", ValueWidget::options);
+19 -32
View File
@@ -22,6 +22,7 @@
#define _WIDGETS_CONTAINER_H_
#include <stdlib.h>
#include <window.h>
#include "widget.h"
class WidgetsContainerInterface
@@ -29,7 +30,7 @@ class WidgetsContainerInterface
public:
virtual unsigned int getZonesCount() const = 0;
virtual Zone getZone(unsigned int index) const = 0;
virtual rect_t getZone(unsigned int index) const = 0;
inline Widget * getWidget(unsigned int index)
{
@@ -50,7 +51,7 @@ class WidgetsContainerInterface
#define WIDGET_NAME_LEN 10
template<int N, int O>
class WidgetsContainer: public WidgetsContainerInterface
class WidgetsContainer: public Window, public WidgetsContainerInterface
{
public:
struct ZonePersistentData {
@@ -63,21 +64,10 @@ class WidgetsContainer: public WidgetsContainerInterface
ZoneOptionValueTyped options[O];
};
public:
WidgetsContainer(PersistentData * persistentData):
WidgetsContainer(const rect_t & rect, PersistentData * persistentData):
Window(nullptr, rect),
persistentData(persistentData)
{
widgets = (Widget **)calloc(N, sizeof(Widget *));
}
virtual ~WidgetsContainer()
{
if (widgets) {
for (uint8_t i=0; i<N; i++) {
delete widgets[i];
}
free(widgets);
}
}
void createWidget(unsigned int index, const WidgetFactory * factory) override
@@ -86,7 +76,7 @@ class WidgetsContainer: public WidgetsContainerInterface
memset(persistentData->zones[index].widgetName, 0, sizeof(persistentData->zones[index].widgetName));
if (factory) {
strncpy(persistentData->zones[index].widgetName, factory->getName(), sizeof(persistentData->zones[index].widgetName));
widgets[index] = factory->create(getZone(index), &persistentData->zones[index].widgetData);
widgets[index] = factory->create(this, getZone(index), &persistentData->zones[index].widgetData);
}
else {
widgets[index] = nullptr;
@@ -103,13 +93,20 @@ class WidgetsContainer: public WidgetsContainerInterface
{
if (widgets) {
unsigned int count = getZonesCount();
for (unsigned int i=0; i<count; i++) {
for (unsigned int i = 0; i < count; i++) {
delete widgets[i];
if (persistentData->zones[i].widgetName[0]) {
if (i == 0) {
char name[WIDGET_NAME_LEN + 1] = "Text";
widgets[i] = loadWidget(name, this, getZone(i), &persistentData->zones[i].widgetData);
} else if (i == 1) {
char name[WIDGET_NAME_LEN + 1] = "Value";
widgets[i] = loadWidget(name, this, getZone(i), &persistentData->zones[i].widgetData);
}
else if (persistentData->zones[i].widgetName[0]) {
char name[WIDGET_NAME_LEN + 1];
memset(name, 0, sizeof(name));
strncpy(name, persistentData->zones[i].widgetName, WIDGET_NAME_LEN);
// widgets[i] = loadWidget(name, getZone(i), &persistentData->zones[i].widgetData);
// TODO widgets[i] = loadWidget(name, getZone(i), &persistentData->zones[i].widgetData);
}
else {
widgets[i] = nullptr;
@@ -125,23 +122,12 @@ class WidgetsContainer: public WidgetsContainerInterface
unsigned int getZonesCount() const override = 0;
Zone getZone(unsigned int index) const override = 0;
virtual void refresh()
{
if (widgets) {
for (int i=0; i<N; i++) {
if (widgets[i]) {
widgets[i]->refresh();
}
}
}
}
rect_t getZone(unsigned int index) const override = 0;
virtual void background()
{
if (widgets) {
for (int i=0; i<N; i++) {
for (int i = 0; i < N; i++) {
if (widgets[i]) {
widgets[i]->background();
}
@@ -151,6 +137,7 @@ class WidgetsContainer: public WidgetsContainerInterface
protected:
PersistentData * persistentData;
Widget * widgets[N] = {};
};
#endif // _WIDGETS_CONTAINER_H_
-5
View File
@@ -19,11 +19,6 @@
#define OPTION_VALUE_STRING(...) { .stringValue = { __VA_ARGS__ } }
#endif
struct Zone
{
uint16_t x, y, w, h;
};
union ZoneOptionValue
{
uint32_t unsignedValue;
+1 -1
View File
@@ -183,7 +183,7 @@ void postModelLoad(bool alarms)
referenceModelAudioFiles();
#endif
#if defined(PCBHORUS)
#if defined(COLORLCD)
loadCustomScreens();
#endif