[Horus] UI continued

This commit is contained in:
Bertrand Songis
2016-02-15 21:28:31 +01:00
parent c07e965542
commit 79a5f65a2c
24 changed files with 343 additions and 240 deletions
@@ -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"
+3 -18
View File
@@ -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;
}
+11 -4
View File
@@ -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();
@@ -30,6 +30,7 @@ class Layout1x1: public Layout
virtual void create()
{
Layout::create();
persistentData->options[0].boolValue = true;
persistentData->options[1].boolValue = true;
}
+3 -2
View File
@@ -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[] = {
+85
View File
@@ -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("Layout2x1", LBM_LAYOUT_2x1, Layout2x1::options);
@@ -30,6 +30,7 @@ class Layout2x2: public Layout
virtual void create()
{
Layout::create();
persistentData->options[0].boolValue = true;
}
+3 -2
View File
@@ -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;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 178 B

+11 -6
View File
@@ -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; i<thickness; i++) {
lcdDrawVerticalLine(x+i, y, h, pat, att);
lcdDrawVerticalLine(x+w-1-i, y, h, pat, att);
lcdDrawHorizontalLine(x, y+h-1-i, w, pat, att);
lcdDrawHorizontalLine(x, y+i, w, pat, att);
}
}
}
+7 -7
View File
@@ -217,7 +217,7 @@ void putsTimer(coord_t x, coord_t y, putstime_t tme, LcdFlags att=0);
#define SOLID 0xff
#define DOTTED 0x55
#define STASHED 0x70
#define STASHED 0x33
#define PIXEL_PTR(x, y) &displayBuf[(y)*LCD_W + (x)]
@@ -276,17 +276,17 @@ inline void lcdDrawSolidVerticalLine(coord_t x, scoord_t y, coord_t h, LcdFlags
lcdDrawSolidFilledRect(x, y, 1, h, att);
}
inline void lcdDrawSolidRect(coord_t x, scoord_t y, coord_t w, coord_t h, LcdFlags att)
inline void lcdDrawSolidRect(coord_t x, scoord_t y, coord_t w, coord_t h, uint8_t thickness=1, LcdFlags att=0)
{
lcdDrawSolidVerticalLine(x, y, h, att);
lcdDrawSolidVerticalLine(x+w-1, y, h, att);
lcdDrawSolidHorizontalLine(x, y, w, att);
lcdDrawSolidHorizontalLine(x, y+h-1, w, att);
lcdDrawSolidFilledRect(x, y, thickness, h, att);
lcdDrawSolidFilledRect(x+w-thickness, y, thickness, h, att);
lcdDrawSolidFilledRect(x, y, w, thickness, att);
lcdDrawSolidFilledRect(x, y+h-thickness, w, thickness, att);
}
void lcdDrawFilledRect(coord_t x, scoord_t y, coord_t w, coord_t h, uint8_t pat, LcdFlags att=0);
void lcdDrawBlackOverlay();
void lcdDrawRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t pat=SOLID, LcdFlags att=0);
void lcdDrawRect(coord_t x, coord_t y, coord_t w, coord_t h, uint8_t thickness=1, uint8_t pat=SOLID, LcdFlags att=0);
void lcdDrawCircle(int x0, int y0, int radius);
void lcdDrawPie(int x0, int y0, int radius, int angle1=0, int angle2=360);
void lcdDrawBitmapPie(int x0, int y0, const uint16_t * img, int startAngle, int endAngle);
+1 -1
View File
@@ -307,7 +307,7 @@ bool menuModelExpoOne(evt_t event)
void lineExpoSurround(coord_t y, LcdFlags flags=CURVE_AXIS_COLOR)
{
lcdDrawRect(EXPO_LINE_SELECT_POS, y-INVERT_VERT_MARGIN+1, EXPO_LINE_SELECT_WIDTH, INVERT_LINE_HEIGHT, s_copyMode == COPY_MODE ? SOLID : DOTTED, flags);
lcdDrawRect(EXPO_LINE_SELECT_POS, y-INVERT_VERT_MARGIN+1, EXPO_LINE_SELECT_WIDTH, INVERT_LINE_HEIGHT, 1, s_copyMode == COPY_MODE ? SOLID : DOTTED, flags);
}
void onExposMenu(const char * result)
+2 -2
View File
@@ -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
*
@@ -283,7 +283,7 @@ bool menuModelMixOne(evt_t event)
void lineMixSurround(coord_t y, LcdFlags flags=CURVE_AXIS_COLOR)
{
lcdDrawRect(MIX_LINE_SELECT_POS, y-INVERT_VERT_MARGIN+1, MIX_LINE_SELECT_WIDTH, INVERT_LINE_HEIGHT, s_copyMode == COPY_MODE ? SOLID : DOTTED, flags);
lcdDrawRect(MIX_LINE_SELECT_POS, y-INVERT_VERT_MARGIN+1, MIX_LINE_SELECT_WIDTH, INVERT_LINE_HEIGHT, 1, s_copyMode == COPY_MODE ? SOLID : DOTTED, flags);
}
void onMixesMenu(const char * result)
+2 -2
View File
@@ -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
*
@@ -70,7 +70,7 @@ void drawModel(coord_t x, coord_t y, const char * name, bool selected)
}
lcdDrawSolidHorizontalLine(x+5, y+19, 143, LINE_COLOR);
if (selected) {
lcdDrawSolidRect(x, y, MODELCELL_WIDTH, MODELCELL_HEIGHT, TITLE_BGCOLOR);
lcdDrawSolidRect(x, y, MODELCELL_WIDTH, MODELCELL_HEIGHT, 1, TITLE_BGCOLOR);
drawShadow(x, y, MODELCELL_WIDTH, MODELCELL_HEIGHT);
}
}
+2
View File
@@ -145,6 +145,8 @@ static const MenuHandlerFunc menuTabGeneral[] PROGMEM = {
menuGeneralVersion,
};
extern MenuHandlerFunc menuTabMainviews[1+MAX_CUSTOM_SCREENS];
bool menuFirstCalib(evt_t event);
bool menuMainView(evt_t event);
bool menuCustomFunctions(evt_t event, CustomFunctionData * functions, CustomFunctionsContext & functionsContext);
+5 -8
View File
@@ -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
*
@@ -41,24 +41,21 @@ void displayAlertBox()
{
lcdClear();
lcdDrawSolidFilledRect(POPUP_X, POPUP_Y, POPUP_W, POPUP_H, TEXT_BGCOLOR);
lcdDrawSolidRect(POPUP_X, POPUP_Y, POPUP_W, POPUP_H, ALARM_COLOR);
lcdDrawSolidRect(POPUP_X+1, POPUP_Y+1, POPUP_W-2, POPUP_H-2, ALARM_COLOR);
lcdDrawSolidRect(POPUP_X, POPUP_Y, POPUP_W, POPUP_H, 2, ALARM_COLOR);
lcdDrawBitmap(POPUP_X-80, POPUP_Y-30, LBM_ASTERISK);
}
void displayWarningBox()
{
lcdDrawSolidFilledRect(POPUP_X, POPUP_Y, POPUP_W, POPUP_H, TEXT_BGCOLOR);
lcdDrawSolidRect(POPUP_X, POPUP_Y, POPUP_W, POPUP_H, ALARM_COLOR);
lcdDrawSolidRect(POPUP_X+1, POPUP_Y+1, POPUP_W-2, POPUP_H-2, ALARM_COLOR);
lcdDrawSolidRect(POPUP_X, POPUP_Y, POPUP_W, POPUP_H, 2, ALARM_COLOR);
// lcdDrawBitmap(POPUP_X+15, POPUP_Y+20, LBM_WARNING);
}
void displayMessageBox()
{
lcdDrawSolidFilledRect(POPUP_X, POPUP_Y, POPUP_W, POPUP_H, TEXT_BGCOLOR);
lcdDrawSolidRect(POPUP_X, POPUP_Y, POPUP_W, POPUP_H, WARNING_COLOR);
lcdDrawSolidRect(POPUP_X+1, POPUP_Y+1, POPUP_W-2, POPUP_H-2, WARNING_COLOR);
lcdDrawSolidRect(POPUP_X, POPUP_Y, POPUP_W, POPUP_H, 2, WARNING_COLOR);
// lcdDrawBitmap(POPUP_X+15, POPUP_Y+20, LBM_MESSAGE);
}
@@ -184,7 +181,7 @@ const char * displayPopupMenu(evt_t event)
int y = (LCD_H - (display_count*(FH+1))) / 2;
lcdDrawSolidFilledRect(MENU_X, y, MENU_W, display_count * (FH+1), TEXT_BGCOLOR);
lcdDrawSolidRect(MENU_X, y, MENU_W, display_count * (FH+1) + 1, ALARM_COLOR);
lcdDrawSolidRect(MENU_X, y, MENU_W, display_count * (FH+1) + 1, 1, ALARM_COLOR);
for (uint8_t i=0; i<display_count; i++) {
if (i == s_menu_item) {
+75 -17
View File
@@ -22,15 +22,10 @@
Layout * currentScreen;
Widget * currentWidget;
uint8_t currentZone;
#define SCREENS_SETUP_2ND_COLUMN 200
void onWidgetChoiceMenu(const char * result)
{
customScreens[0]->setWidget(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; i<countRegisteredWidgets; i++) {
if (factory->getName() == 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; i<countRegisteredWidgets; i++) {
POPUP_MENU_ADD_ITEM(registeredWidgets[i]->getName());
}
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 <class T>
@@ -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;
}
}
+1 -1
View File
@@ -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);
+2 -145
View File
@@ -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<NUM_LINE_ITEMS; j++) {
source_t field = screen.lines[i].sources[j];
if (field) {
LcdFlags color = WHITE;
coord_t pos[] = { NUMBERS_MARGIN, (LCD_W-NUMBERS_W)/2, LCD_W-NUMBERS_MARGIN-NUMBERS_W };
int x = pos[j];
int y = NUMBERS_MARGIN + i*(NUMBERS_H+NUMBERS_MARGIN);
lcdDrawSolidFilledRect(x, y, NUMBERS_W, NUMBERS_H, TEXT_BGCOLOR);
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()) {
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);
}
}
+3 -3
View File
@@ -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);
}
}
}
+5 -5
View File
@@ -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> gaugeWidget("Gauge", "", GaugeWidget::options);
BaseWidgetFactory<GaugeWidget> gaugeWidget("Gauge", "", GaugeWidget::options);
+1 -1
View File
@@ -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);
+99
View File
@@ -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> ValueWidget("Value", "", ValueWidget::options);
+18 -16
View File
@@ -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");