mirror of
https://github.com/opentx/opentx.git
synced 2025-07-16 04:45:17 +03:00
[CLI] reboot command added
This commit is contained in:
parent
0f4f49b64e
commit
67a599e0b9
45 changed files with 920 additions and 605 deletions
|
@ -80,6 +80,7 @@ if(PCB STREQUAL HORUS)
|
|||
view_text.cpp
|
||||
screens_setup.cpp
|
||||
theme.cpp
|
||||
topbar.cpp
|
||||
layout.cpp
|
||||
widget.cpp
|
||||
${THEMES_SRC}
|
||||
|
@ -256,6 +257,7 @@ if(CPU_TYPE STREQUAL STM32F4)
|
|||
include_directories(${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/inc)
|
||||
include_directories(${STM32LIB_DIR}/CMSIS/Device/ST/STM32F4xx/Include)
|
||||
include_directories(${STM32LIB_DIR}/CMSIS/include)
|
||||
# add_definitions(-DSTM32F4)
|
||||
set(STM32LIB_SRC
|
||||
${STM32LIB_SRC}
|
||||
CMSIS/Device/ST/STM32F4xx/Source/Templates/gcc_ride7/startup_stm32f40_41xxx.s
|
||||
|
|
|
@ -249,8 +249,6 @@ void referenceSystemAudioFiles()
|
|||
fn = *fno.lfname ? fno.lfname : fno.fname;
|
||||
uint8_t len = strlen(fn);
|
||||
|
||||
TRACE("%s", fn);
|
||||
|
||||
// Eliminates directories / non wav files
|
||||
if (len < 5 || strcasecmp(fn+len-4, SOUNDS_EXT) || (fno.fattrib & AM_DIR)) continue;
|
||||
|
||||
|
@ -509,7 +507,7 @@ void audioTask(void * pdata)
|
|||
AUDIO_TADA();
|
||||
#elif defined(SDCARD)
|
||||
if (!unexpectedShutdown) {
|
||||
sdInit();
|
||||
// sdInit();
|
||||
AUDIO_TADA();
|
||||
}
|
||||
#endif
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 15 KiB |
BIN
radio/src/bitmaps/horus/bmp_asterisk.png
Normal file
BIN
radio/src/bitmaps/horus/bmp_asterisk.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.2 KiB |
BIN
radio/src/bitmaps/horus/bmp_sleep.png
Normal file
BIN
radio/src/bitmaps/horus/bmp_sleep.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
|
@ -204,22 +204,36 @@ const uint8_t LBM_MAINVIEWS_TOPBAR_ICON[] = {
|
|||
#include "mask_mainviews_topbar.lbm"
|
||||
};
|
||||
|
||||
const uint8_t LBM_MAINVIEWS_ITEM_OUT_ICON[] = {
|
||||
#include "mask_mainviews_item_out.lbm"
|
||||
const uint8_t LBM_MAINVIEWS_1_ICON[] = {
|
||||
#include "mask_mainviews_1.lbm"
|
||||
};
|
||||
|
||||
const uint8_t LBM_MAINVIEWS_2_ICON[] = {
|
||||
#include "mask_mainviews_2.lbm"
|
||||
};
|
||||
|
||||
const uint8_t LBM_MAINVIEWS_3_ICON[] = {
|
||||
#include "mask_mainviews_3.lbm"
|
||||
};
|
||||
|
||||
const uint8_t LBM_MAINVIEWS_4_ICON[] = {
|
||||
#include "mask_mainviews_4.lbm"
|
||||
};
|
||||
|
||||
const uint8_t LBM_MAINVIEWS_5_ICON[] = {
|
||||
#include "mask_mainviews_5.lbm"
|
||||
};
|
||||
|
||||
const uint8_t LBM_MAINVIEWS_ADD_ICON[] = {
|
||||
#include "mask_mainviews_add.lbm"
|
||||
};
|
||||
|
||||
const uint8_t * LBM_MAINVIEWS_ICONS[] = {
|
||||
LBM_MAINVIEWS_ICON,
|
||||
LBM_MAINVIEWS_TOPBAR_ICON,
|
||||
LBM_MAINVIEWS_ITEM_OUT_ICON,
|
||||
LBM_MAINVIEWS_ITEM_OUT_ICON,
|
||||
LBM_MAINVIEWS_ITEM_OUT_ICON,
|
||||
LBM_MAINVIEWS_ITEM_OUT_ICON,
|
||||
LBM_MAINVIEWS_ITEM_OUT_ICON
|
||||
const uint8_t * const LBM_MAINVIEWS_ICONS[] = {
|
||||
LBM_MAINVIEWS_1_ICON,
|
||||
LBM_MAINVIEWS_2_ICON,
|
||||
LBM_MAINVIEWS_3_ICON,
|
||||
LBM_MAINVIEWS_4_ICON,
|
||||
LBM_MAINVIEWS_5_ICON
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -299,7 +313,7 @@ const uint8_t LBM_SHUTDOWN[] __DMA = {
|
|||
};
|
||||
|
||||
const uint8_t LBM_SLEEP[] __DMA = {
|
||||
#include "alpha_sleep.lbm"
|
||||
#include "bmp_sleep.lbm"
|
||||
};
|
||||
|
||||
const uint8_t LBM_SHUTDOWN_CIRCLE[] __DMA = {
|
||||
|
|
|
@ -53,9 +53,8 @@ extern const uint8_t LBM_TELEMETRY_ICON[];
|
|||
// UI (theme / layout / widgets bitmaps
|
||||
extern const uint8_t LBM_MAINVIEWS_ICON[];
|
||||
extern const uint8_t LBM_MAINVIEWS_TOPBAR_ICON[];
|
||||
extern const uint8_t LBM_MAINVIEWS_ITEM_OUT_ICON[];
|
||||
extern const uint8_t LBM_MAINVIEWS_ADD_ICON[];
|
||||
extern const uint8_t * LBM_MAINVIEWS_ICONS[];
|
||||
extern const uint8_t * const LBM_MAINVIEWS_ICONS[];
|
||||
|
||||
// Model selection icons
|
||||
extern const uint8_t LBM_LIBRARY_ICON[];
|
||||
|
|
|
@ -81,5 +81,5 @@ void drawCurveHorizontalScale();
|
|||
void drawCurveCoord(int x, int y, const char * text, bool active=false);
|
||||
void drawCurvePoint(int x, int y, LcdFlags color);
|
||||
|
||||
// TODO one screen for now
|
||||
extern Layout * customScreens[MAX_CUSTOM_SCREENS];
|
||||
extern Topbar * topbar;
|
||||
|
|
|
@ -20,40 +20,12 @@
|
|||
|
||||
#include "opentx.h"
|
||||
|
||||
void Layout::createWidget(unsigned int index, const WidgetFactory * factory)
|
||||
{
|
||||
memset(persistentData->zones[index].widgetName, 0, sizeof(persistentData->zones[index].widgetName));
|
||||
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()
|
||||
{
|
||||
unsigned int count = getZonesCount();
|
||||
for (unsigned int i=0; i<count; i++) {
|
||||
if (persistentData->zones[i].widgetName[0]) {
|
||||
char name[sizeof(persistentData->zones[i].widgetName)+1];
|
||||
memset(name, 0, sizeof(name));
|
||||
strncpy(name, persistentData->zones[i].widgetName, sizeof(persistentData->zones[i].widgetName));
|
||||
widgets[i] = loadWidget(name, getZone(i), &persistentData->zones[i].widgetData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Layout::refresh(bool setup)
|
||||
{
|
||||
for (int i = 0; i < MAX_LAYOUT_ZONES; i++) {
|
||||
if (widgets[i]) {
|
||||
widgets[i]->refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const LayoutFactory * registeredLayouts[MAX_REGISTERED_LAYOUTS]; // TODO dynamic
|
||||
unsigned int countRegisteredLayouts = 0;
|
||||
void registerLayout(const LayoutFactory * factory)
|
||||
{
|
||||
if (countRegisteredLayouts < MAX_REGISTERED_LAYOUTS) {
|
||||
TRACE("register layout %s", factory->getName());
|
||||
registeredLayouts[countRegisteredLayouts++] = factory;
|
||||
}
|
||||
}
|
||||
|
@ -90,4 +62,6 @@ void loadCustomScreens()
|
|||
if (customScreens[0] == NULL) {
|
||||
customScreens[0] = registeredLayouts[0]->create(&g_model.screenData[0].layoutData);
|
||||
}
|
||||
|
||||
topbar->load();
|
||||
}
|
||||
|
|
|
@ -21,86 +21,31 @@
|
|||
#ifndef _LAYOUT_H_
|
||||
#define _LAYOUT_H_
|
||||
|
||||
#include "widget.h"
|
||||
#include "widgets_container.h"
|
||||
|
||||
#define MAX_LAYOUT_ZONES 10
|
||||
#define MAX_LAYOUT_OPTIONS 10
|
||||
|
||||
class LayoutFactory;
|
||||
class Layout
|
||||
|
||||
class Layout: public WidgetsContainer<MAX_LAYOUT_ZONES, MAX_LAYOUT_OPTIONS>
|
||||
{
|
||||
friend class LayoutFactory;
|
||||
|
||||
public:
|
||||
struct ZonePersistentData {
|
||||
char widgetName[10];
|
||||
Widget::PersistentData widgetData;
|
||||
};
|
||||
|
||||
struct PersistentData {
|
||||
ZonePersistentData zones[MAX_LAYOUT_ZONES];
|
||||
ZoneOptionValue options[MAX_LAYOUT_OPTIONS];
|
||||
};
|
||||
|
||||
public:
|
||||
Layout(const LayoutFactory * factory, PersistentData * persistentData):
|
||||
factory(factory),
|
||||
persistentData(persistentData)
|
||||
WidgetsContainer<MAX_LAYOUT_ZONES, MAX_LAYOUT_OPTIONS>(persistentData),
|
||||
factory(factory)
|
||||
{
|
||||
memset(widgets, 0, sizeof(widgets));
|
||||
}
|
||||
|
||||
virtual ~Layout()
|
||||
{
|
||||
for (uint8_t i=0; i<MAX_LAYOUT_ZONES; i++) {
|
||||
delete widgets[i];
|
||||
}
|
||||
memset(widgets, 0, sizeof(widgets));
|
||||
}
|
||||
|
||||
const LayoutFactory * getFactory() const
|
||||
inline const LayoutFactory * getFactory() const
|
||||
{
|
||||
return factory;
|
||||
}
|
||||
|
||||
Widget * getWidget(unsigned int index)
|
||||
{
|
||||
return widgets[index];
|
||||
}
|
||||
|
||||
void setWidget(unsigned int index, Widget * widget)
|
||||
{
|
||||
widgets[index] = widget;
|
||||
}
|
||||
|
||||
void createWidget(unsigned int index, const WidgetFactory * factory);
|
||||
|
||||
virtual void create()
|
||||
{
|
||||
memset(persistentData, 0, sizeof(PersistentData));
|
||||
}
|
||||
|
||||
virtual void load();
|
||||
|
||||
ZoneOptionValue getOptionValue(unsigned int index) const
|
||||
{
|
||||
return persistentData->options[index];
|
||||
}
|
||||
|
||||
void setOptionValue(unsigned int index, ZoneOptionValue value) const
|
||||
{
|
||||
persistentData->options[index] = value;
|
||||
}
|
||||
|
||||
virtual unsigned int getZonesCount() const = 0;
|
||||
virtual Zone getZone(unsigned int index) const = 0;
|
||||
|
||||
virtual void refresh(bool setup=false);
|
||||
|
||||
protected:
|
||||
const LayoutFactory * factory;
|
||||
Widget * widgets[MAX_LAYOUT_ZONES];
|
||||
PersistentData * persistentData;
|
||||
};
|
||||
|
||||
void registerLayout(const LayoutFactory * factory);
|
||||
|
|
|
@ -20,6 +20,16 @@
|
|||
|
||||
#include "opentx.h"
|
||||
|
||||
const uint8_t LBM_LAYOUT_1x1[] = {
|
||||
#include "mask_layout1x1.lbm"
|
||||
};
|
||||
|
||||
const ZoneOption OPTIONS_LAYOUT_1x1[] = {
|
||||
{ "Top bar", ZoneOption::Bool },
|
||||
{ "Sliders+Trims", ZoneOption::Bool },
|
||||
{ NULL, ZoneOption::Bool }
|
||||
};
|
||||
|
||||
class Layout1x1: public Layout
|
||||
{
|
||||
public:
|
||||
|
@ -55,25 +65,15 @@ class Layout1x1: public Layout
|
|||
return zone;
|
||||
}
|
||||
|
||||
virtual void refresh(bool setup=false);
|
||||
|
||||
static const ZoneOption options[];
|
||||
|
||||
virtual void refresh();
|
||||
};
|
||||
|
||||
const ZoneOption Layout1x1::options[] = {
|
||||
{ "Top bar", ZoneOption::Bool },
|
||||
{ "Sliders+Trims", ZoneOption::Bool },
|
||||
{ NULL, ZoneOption::Bool }
|
||||
};
|
||||
|
||||
void Layout1x1::refresh(bool setup)
|
||||
void Layout1x1::refresh()
|
||||
{
|
||||
theme->drawBackground();
|
||||
|
||||
if (persistentData->options[0].boolValue) {
|
||||
// Top Bar
|
||||
drawMainViewTopBar();
|
||||
drawTopBar();
|
||||
}
|
||||
|
||||
if (persistentData->options[1].boolValue) {
|
||||
|
@ -86,11 +86,7 @@ void Layout1x1::refresh(bool setup)
|
|||
drawTrims(mixerCurrentFlightMode);
|
||||
}
|
||||
|
||||
Layout::refresh(setup);
|
||||
Layout::refresh();
|
||||
}
|
||||
|
||||
const uint8_t LBM_LAYOUT_1x1[] __DMA = {
|
||||
#include "mask_layout1x1.lbm"
|
||||
};
|
||||
|
||||
BaseLayoutFactory<Layout1x1> layout1x1("Layout1x1", LBM_LAYOUT_1x1, Layout1x1::options);
|
||||
BaseLayoutFactory<Layout1x1> layout1x1("Layout1x1", LBM_LAYOUT_1x1, OPTIONS_LAYOUT_1x1);
|
||||
|
|
|
@ -20,6 +20,24 @@
|
|||
|
||||
#include "opentx.h"
|
||||
|
||||
const uint8_t LBM_LAYOUT_2P1[] = {
|
||||
#include "mask_layout2+1.lbm"
|
||||
};
|
||||
|
||||
const ZoneOption OPTIONS_LAYOUT_2P1[] = {
|
||||
{ "Top bar", ZoneOption::Bool },
|
||||
{ "Flight mode", ZoneOption::Bool },
|
||||
{ "Sliders", ZoneOption::Bool },
|
||||
{ "Trims", ZoneOption::Bool },
|
||||
{ NULL, ZoneOption::Bool }
|
||||
};
|
||||
|
||||
const Zone ZONES_LAYOUT_2P1[3] = {
|
||||
{ 240, 60, 192, 152 },
|
||||
{ 48, 60, 180, 70 },
|
||||
{ 48, 142, 180, 70 }
|
||||
};
|
||||
|
||||
class Layout2P1: public Layout
|
||||
{
|
||||
public:
|
||||
|
@ -39,43 +57,23 @@ class Layout2P1: public Layout
|
|||
|
||||
virtual unsigned int getZonesCount() const
|
||||
{
|
||||
return 3;
|
||||
return DIM(ZONES_LAYOUT_2P1);
|
||||
}
|
||||
|
||||
virtual Zone getZone(unsigned int index) const
|
||||
{
|
||||
return zones[index];
|
||||
return ZONES_LAYOUT_2P1[index];
|
||||
}
|
||||
|
||||
virtual void refresh(bool setup=false);
|
||||
|
||||
static const ZoneOption options[];
|
||||
|
||||
protected:
|
||||
static const Zone zones[3];
|
||||
virtual void refresh();
|
||||
};
|
||||
|
||||
const Zone Layout2P1::zones[3] = {
|
||||
{ 240, 60, 192, 145 },
|
||||
{ 46, 60, 182, 66 },
|
||||
{ 46, 139, 182, 66 }
|
||||
};
|
||||
|
||||
const ZoneOption Layout2P1::options[] = {
|
||||
{ "Top bar", ZoneOption::Bool },
|
||||
{ "Flight mode", ZoneOption::Bool },
|
||||
{ "Sliders", ZoneOption::Bool },
|
||||
{ "Trims", ZoneOption::Bool },
|
||||
{ NULL, ZoneOption::Bool }
|
||||
};
|
||||
|
||||
void Layout2P1::refresh(bool setup)
|
||||
void Layout2P1::refresh()
|
||||
{
|
||||
theme->drawBackground();
|
||||
|
||||
if (persistentData->options[0].boolValue) {
|
||||
// Top Bar
|
||||
drawMainViewTopBar();
|
||||
drawTopBar();
|
||||
}
|
||||
|
||||
if (persistentData->options[1].boolValue) {
|
||||
|
@ -98,11 +96,7 @@ void Layout2P1::refresh(bool setup)
|
|||
drawTrims(mixerCurrentFlightMode);
|
||||
}
|
||||
|
||||
Layout::refresh(setup);
|
||||
Layout::refresh();
|
||||
}
|
||||
|
||||
const uint8_t LBM_LAYOUT_2P1[] __DMA = {
|
||||
#include "mask_layout2+1.lbm"
|
||||
};
|
||||
|
||||
BaseLayoutFactory<Layout2P1> layout2P1("Layout2P1", LBM_LAYOUT_2P1, Layout2P1::options);
|
||||
BaseLayoutFactory<Layout2P1> layout2P1("Layout2P1", LBM_LAYOUT_2P1, OPTIONS_LAYOUT_2P1);
|
||||
|
|
|
@ -20,6 +20,15 @@
|
|||
|
||||
#include "opentx.h"
|
||||
|
||||
const uint8_t LBM_LAYOUT_2x1[] = {
|
||||
#include "mask_layout2x1.lbm"
|
||||
};
|
||||
|
||||
const ZoneOption OPTIONS_LAYOUT_2x1[] = {
|
||||
{ "Top bar", ZoneOption::Bool },
|
||||
{ NULL, ZoneOption::Bool }
|
||||
};
|
||||
|
||||
class Layout2x1: public Layout
|
||||
{
|
||||
public:
|
||||
|
@ -55,31 +64,18 @@ class Layout2x1: public Layout
|
|||
return zone;
|
||||
}
|
||||
|
||||
virtual void refresh(bool setup=false);
|
||||
|
||||
static const ZoneOption options[];
|
||||
|
||||
virtual void refresh();
|
||||
};
|
||||
|
||||
const ZoneOption Layout2x1::options[] = {
|
||||
{ "Top bar", ZoneOption::Bool },
|
||||
{ NULL, ZoneOption::Bool }
|
||||
};
|
||||
|
||||
void Layout2x1::refresh(bool setup)
|
||||
void Layout2x1::refresh()
|
||||
{
|
||||
theme->drawBackground();
|
||||
|
||||
if (persistentData->options[0].boolValue) {
|
||||
// Top Bar
|
||||
drawMainViewTopBar();
|
||||
drawTopBar();
|
||||
}
|
||||
|
||||
Layout::refresh(setup);
|
||||
Layout::refresh();
|
||||
}
|
||||
|
||||
const uint8_t LBM_LAYOUT_2x1[] __DMA = {
|
||||
#include "mask_layout2x1.lbm"
|
||||
};
|
||||
|
||||
BaseLayoutFactory<Layout2x1> Layout2x1("Layout2x1", LBM_LAYOUT_2x1, Layout2x1::options);
|
||||
BaseLayoutFactory<Layout2x1> Layout2x1("Layout2x1", LBM_LAYOUT_2x1, OPTIONS_LAYOUT_2x1);
|
||||
|
|
|
@ -20,6 +20,15 @@
|
|||
|
||||
#include "opentx.h"
|
||||
|
||||
const uint8_t LBM_LAYOUT_2x2[] = {
|
||||
#include "mask_layout2x2.lbm"
|
||||
};
|
||||
|
||||
const ZoneOption OPTIONS_LAYOUT_2x2[] = {
|
||||
{ "Top bar", ZoneOption::Bool },
|
||||
{ NULL, ZoneOption::Bool }
|
||||
};
|
||||
|
||||
class Layout2x2: public Layout
|
||||
{
|
||||
public:
|
||||
|
@ -58,31 +67,18 @@ class Layout2x2: public Layout
|
|||
return zone;
|
||||
}
|
||||
|
||||
virtual void refresh(bool setup=false);
|
||||
|
||||
static const ZoneOption options[];
|
||||
|
||||
virtual void refresh();
|
||||
};
|
||||
|
||||
const ZoneOption Layout2x2::options[] = {
|
||||
{ "Top bar", ZoneOption::Bool },
|
||||
{ NULL, ZoneOption::Bool }
|
||||
};
|
||||
|
||||
void Layout2x2::refresh(bool setup)
|
||||
void Layout2x2::refresh()
|
||||
{
|
||||
theme->drawBackground();
|
||||
|
||||
if (persistentData->options[0].boolValue) {
|
||||
// Top Bar
|
||||
drawMainViewTopBar();
|
||||
drawTopBar();
|
||||
}
|
||||
|
||||
Layout::refresh(setup);
|
||||
Layout::refresh();
|
||||
}
|
||||
|
||||
const uint8_t LBM_LAYOUT_2x2[] __DMA = {
|
||||
#include "mask_layout2x2.lbm"
|
||||
};
|
||||
|
||||
BaseLayoutFactory<Layout2x2> layout2x2("Layout2x2", LBM_LAYOUT_2x2, Layout2x2::options);
|
||||
BaseLayoutFactory<Layout2x2> layout2x2("Layout2x2", LBM_LAYOUT_2x2, OPTIONS_LAYOUT_2x2);
|
||||
|
|
|
@ -20,6 +20,22 @@
|
|||
|
||||
#include "opentx.h"
|
||||
|
||||
const uint8_t LBM_LAYOUT_2x4[] = {
|
||||
#include "mask_layout2x4.lbm"
|
||||
};
|
||||
|
||||
const ZoneOption OPTIONS_LAYOUT_2x4[] = {
|
||||
{ "Top bar", ZoneOption::Bool },
|
||||
{ "Flight mode", ZoneOption::Bool },
|
||||
{ "Sliders", ZoneOption::Bool },
|
||||
{ "Trims", ZoneOption::Bool },
|
||||
{ "Panel1 background", ZoneOption::Bool },
|
||||
{ " Color", ZoneOption::Color },
|
||||
{ "Panel2 background", ZoneOption::Bool },
|
||||
{ " Color", ZoneOption::Color },
|
||||
{ NULL, ZoneOption::Bool }
|
||||
};
|
||||
|
||||
class Layout2x4: public Layout
|
||||
{
|
||||
public:
|
||||
|
@ -56,31 +72,15 @@ class Layout2x4: public Layout
|
|||
return zone;
|
||||
}
|
||||
|
||||
virtual void refresh(bool setup=false);
|
||||
|
||||
static const ZoneOption options[];
|
||||
|
||||
virtual void refresh();
|
||||
};
|
||||
|
||||
const ZoneOption Layout2x4::options[] = {
|
||||
{ "Top bar", ZoneOption::Bool },
|
||||
{ "Flight mode", ZoneOption::Bool },
|
||||
{ "Sliders", ZoneOption::Bool },
|
||||
{ "Trims", ZoneOption::Bool },
|
||||
{ "Panel1 background", ZoneOption::Bool },
|
||||
{ " Color", ZoneOption::Color },
|
||||
{ "Panel2 background", ZoneOption::Bool },
|
||||
{ " Color", ZoneOption::Color },
|
||||
{ NULL, ZoneOption::Bool }
|
||||
};
|
||||
|
||||
void Layout2x4::refresh(bool setup)
|
||||
void Layout2x4::refresh()
|
||||
{
|
||||
theme->drawBackground();
|
||||
|
||||
if (persistentData->options[0].boolValue) {
|
||||
// Top Bar
|
||||
drawMainViewTopBar();
|
||||
drawTopBar();
|
||||
}
|
||||
|
||||
if (persistentData->options[1].boolValue) {
|
||||
|
@ -113,11 +113,7 @@ void Layout2x4::refresh(bool setup)
|
|||
lcdDrawSolidFilledRect(250, 50, 180, 170, CUSTOM_COLOR);
|
||||
}
|
||||
|
||||
Layout::refresh(setup);
|
||||
Layout::refresh();
|
||||
}
|
||||
|
||||
const uint8_t LBM_LAYOUT_2x4[] __DMA = {
|
||||
#include "mask_layout2x4.lbm"
|
||||
};
|
||||
|
||||
BaseLayoutFactory<Layout2x4> layout2x4("Layout2x4", LBM_LAYOUT_2x4, Layout2x4::options);
|
||||
BaseLayoutFactory<Layout2x4> layout2x4("Layout2x4", LBM_LAYOUT_2x4, OPTIONS_LAYOUT_2x4);
|
||||
|
|
|
@ -109,24 +109,17 @@ int getFontHeight(LcdFlags flags)
|
|||
return heightTable[FONTSIZE(flags) >> 8];
|
||||
}
|
||||
|
||||
int getBitmapScale(const uint8_t * bmp, int dstWidth, int dstHeight)
|
||||
float getBitmapScale(const uint8_t * bmp, int dstWidth, int dstHeight)
|
||||
{
|
||||
int widthScale, heightScale;
|
||||
|
||||
int bmpWidth = getBitmapWidth(bmp);
|
||||
int bmpHeight = getBitmapHeight(bmp);
|
||||
|
||||
if (bmpWidth == 0 || bmpHeight == 0)
|
||||
return 0;
|
||||
|
||||
if (bmpWidth > dstWidth)
|
||||
widthScale = -((bmpWidth+dstWidth-1) / dstWidth);
|
||||
else
|
||||
widthScale = (dstWidth / bmpWidth);
|
||||
if (bmpHeight > dstHeight)
|
||||
heightScale = -((bmpHeight+dstHeight-1) / dstHeight);
|
||||
else
|
||||
heightScale = (dstHeight / bmpHeight);
|
||||
float widthScale = float(dstWidth) / bmpWidth;
|
||||
float heightScale = float(dstHeight) / bmpHeight;
|
||||
|
||||
return min(widthScale, heightScale);
|
||||
}
|
||||
|
||||
|
@ -882,7 +875,7 @@ void lcdDrawVerticalLine(coord_t x, coord_t y, coord_t h, uint8_t pat, LcdFlags
|
|||
#if defined(SIMU)
|
||||
inline void lcdDrawBitmapDMA(coord_t x, coord_t y, coord_t width, coord_t height, const uint8_t * img)
|
||||
{
|
||||
lcdDrawBitmap(x, y, img-4, 0, 0, -1);
|
||||
lcdDrawBitmap(x, y, img-4, 0, 0, 1.0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -906,7 +899,7 @@ void lcdDrawAlphaBitmap(coord_t x, coord_t y, const uint8_t * bmp)
|
|||
}
|
||||
}
|
||||
|
||||
void lcdDrawBitmap(coord_t x, coord_t y, const uint8_t * bmp, coord_t offset, coord_t height, int scale)
|
||||
void lcdDrawBitmap(coord_t x, coord_t y, const uint8_t * bmp, coord_t offset, coord_t height, float scale)
|
||||
{
|
||||
int width = getBitmapWidth(bmp);
|
||||
int h = getBitmapHeight(bmp);
|
||||
|
@ -926,29 +919,17 @@ void lcdDrawBitmap(coord_t x, coord_t y, const uint8_t * bmp, coord_t offset, co
|
|||
if (scale == 0) {
|
||||
lcdDrawBitmapDMA(x, y, width, height, bmp + 4 + offset * width * 2);
|
||||
}
|
||||
else if (scale < 0) {
|
||||
for (coord_t i=0, row=0; row<height; i+=1, row-=scale) {
|
||||
display_t * p = &displayBuf[(y+i)*LCD_W + x];
|
||||
const uint8_t * q = bmp + 4 + (offset+row)*width*2;
|
||||
for (coord_t col=0; col<width; col-=scale) {
|
||||
lcdDrawPixel(p, *((uint16_t *)q));
|
||||
p++; q-=2*scale;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (coord_t row=0; row<height; row++) {
|
||||
for (int i=0; i<scale; i++) {
|
||||
display_t * p = &displayBuf[(y+scale*row+i)*LCD_W + x];
|
||||
const uint8_t * q = bmp + 4 + (offset+row)*width*2;
|
||||
for (coord_t col=0; col<width; col++) {
|
||||
for (int j=0; j<scale; j++) {
|
||||
int dstwidth = width * scale;
|
||||
int dstheight = height * scale;
|
||||
for (coord_t i=0; i<dstheight; i++) {
|
||||
display_t * p = &displayBuf[(y+i)*LCD_W + x];
|
||||
const uint8_t * qs = bmp + 4 + (offset+int(i/scale))*width*2;
|
||||
for (coord_t j=0; j<dstwidth; j++) {
|
||||
const uint8_t * q = qs + int(j/scale) * 2;
|
||||
lcdDrawPixel(p, *((uint16_t *)q));
|
||||
p++;
|
||||
}
|
||||
q+=2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -956,7 +937,7 @@ void lcdDrawBitmap(coord_t x, coord_t y, const uint8_t * bmp, coord_t offset, co
|
|||
|
||||
void lcdDrawBlackOverlay()
|
||||
{
|
||||
lcdDrawFilledRect(0, 0, LCD_W, LCD_H, SOLID, OVERLAY_COLOR | (8<<24));
|
||||
lcdDrawFilledRect(0, 0, LCD_W, LCD_H, SOLID, OVERLAY_COLOR | OPACITY(8));
|
||||
}
|
||||
|
||||
void lcdDrawCircle(int x0, int y0, int radius)
|
||||
|
|
|
@ -306,19 +306,17 @@ inline int getBitmapHeight(const uint8_t * bmp)
|
|||
return *(((const uint16_t *)bmp)+1);
|
||||
}
|
||||
|
||||
inline int getBitmapScaledSize(int size, int scale)
|
||||
inline int getBitmapScaledSize(int size, float scale)
|
||||
{
|
||||
if (scale >= -1 && scale <= 1)
|
||||
if (scale == 0.0)
|
||||
return size;
|
||||
else if (scale < 0)
|
||||
return -(size / scale);
|
||||
else
|
||||
return size * scale;
|
||||
}
|
||||
|
||||
int getBitmapScale(const uint8_t * bmp, int dstWidth, int dstHeight);
|
||||
float getBitmapScale(const uint8_t * bmp, int dstWidth, int dstHeight);
|
||||
int getTextWidth(const pm_char *s, int len=0, LcdFlags flags=0);
|
||||
void lcdDrawBitmap(coord_t x, coord_t y, const uint8_t * img, coord_t offset=0, coord_t height=0, int scale=0);
|
||||
void lcdDrawBitmap(coord_t x, coord_t y, const uint8_t * img, coord_t offset=0, coord_t height=0, float scale=0);
|
||||
void lcdDrawBitmapPattern(coord_t x, coord_t y, const uint8_t * img, LcdFlags flags=0, coord_t offset=0, coord_t width=0);
|
||||
void lcdDrawAlphaBitmap(coord_t x, coord_t y, const uint8_t * bmp);
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#define MODEL_CUSTOM_FUNC_4TH_COLUMN 440
|
||||
#define MODEL_CUSTOM_FUNC_4TH_COLUMN_ONOFF 450
|
||||
|
||||
void onCustomFunctionsFileSelectionMenu(const char *result)
|
||||
void onCustomFunctionsFileSelectionMenu(const char * result)
|
||||
{
|
||||
int sub = menuVerticalPosition;
|
||||
CustomFunctionData * cf = &g_model.customFn[sub];
|
||||
|
|
|
@ -544,9 +544,9 @@ bool menuModelSetup(evt_t event)
|
|||
lcdDrawText(MENUS_MARGIN_LEFT, y, STR_MODE);
|
||||
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_TARANIS_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].type, (menuHorizontalPosition==0 ? attr : 0));
|
||||
if (IS_MODULE_XJT(EXTERNAL_MODULE))
|
||||
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+40, y, STR_XJT_PROTOCOLS, 1+g_model.moduleData[EXTERNAL_MODULE].rfProtocol, (menuHorizontalPosition==1 ? attr : 0));
|
||||
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+70, y, STR_XJT_PROTOCOLS, 1+g_model.moduleData[EXTERNAL_MODULE].rfProtocol, (menuHorizontalPosition==1 ? attr : 0));
|
||||
else if (IS_MODULE_DSM2(EXTERNAL_MODULE))
|
||||
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+40, y, STR_DSM_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, (menuHorizontalPosition==1 ? attr : 0));
|
||||
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN+70, y, STR_DSM_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].rfProtocol, (menuHorizontalPosition==1 ? attr : 0));
|
||||
if (attr && s_editMode>0) {
|
||||
switch (menuHorizontalPosition) {
|
||||
case 0:
|
||||
|
@ -672,7 +672,9 @@ bool menuModelSetup(evt_t event)
|
|||
lcdDrawText(MENUS_MARGIN_LEFT, y, TR_FAILSAFE);
|
||||
if (IS_MODULE_XJT(moduleIdx)) {
|
||||
lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_VFAILSAFE, moduleData.failsafeMode, menuHorizontalPosition==0 ? attr : 0);
|
||||
if (moduleData.failsafeMode == FAILSAFE_CUSTOM) lcdDrawText(MODEL_SETUP_2ND_COLUMN + MODEL_SETUP_SET_FAILSAFE_OFS, y, STR_SET, menuHorizontalPosition==1 ? attr : 0);
|
||||
if (moduleData.failsafeMode == FAILSAFE_CUSTOM) {
|
||||
drawButton(MODEL_SETUP_2ND_COLUMN + MODEL_SETUP_SET_FAILSAFE_OFS, y, STR_SET, menuHorizontalPosition==1 ? attr : 0);
|
||||
}
|
||||
if (attr) {
|
||||
if (moduleData.failsafeMode != FAILSAFE_CUSTOM)
|
||||
menuHorizontalPosition = 0;
|
||||
|
@ -700,7 +702,7 @@ bool menuModelSetup(evt_t event)
|
|||
}
|
||||
|
||||
if (IS_RANGECHECK_ENABLE()) {
|
||||
displayPopup("RSSI :");
|
||||
theme->drawMessageBox("RSSI :", NULL, NULL, 0);
|
||||
lcdDrawNumber(WARNING_LINE_X, WARNING_INFOLINE_Y, TELEMETRY_RSSI(), DBLSIZE|LEFT);
|
||||
}
|
||||
|
||||
|
|
|
@ -144,7 +144,7 @@ static const MenuHandlerFunc menuTabGeneral[] PROGMEM = {
|
|||
menuGeneralVersion,
|
||||
};
|
||||
|
||||
extern MenuHandlerFunc menuTabMainviews[1+MAX_CUSTOM_SCREENS];
|
||||
extern const MenuHandlerFunc menuTabScreensSetup[1+MAX_CUSTOM_SCREENS] PROGMEM;
|
||||
|
||||
bool menuFirstCalib(evt_t event);
|
||||
bool menuMainView(evt_t event);
|
||||
|
@ -274,10 +274,13 @@ bool check_submenu_simple(check_event_t event, uint8_t maxrow);
|
|||
#define MENU(title, icons, tab, menu, lines_count, ...) \
|
||||
MENU_WITH_OPTIONS(title, icons, tab, DIM(tab), menu, lines_count, __VA_ARGS__)
|
||||
|
||||
#define SIMPLE_MENU(title, icons, tab, menu, lines_count) \
|
||||
#define SIMPLE_MENU_WITH_OPTIONS(title, icons, tab, tabCount, menu, lines_count) \
|
||||
if (event == EVT_ENTRY || event == EVT_ENTRY_UP) TRACE("Menu %s displayed ...", title); \
|
||||
if (!check_simple(event, menu, tab, DIM(tab), lines_count)) return false; \
|
||||
drawMenuTemplate(title, icons); \
|
||||
if (!check_simple(event, menu, tab, tabCount, lines_count)) return false; \
|
||||
drawMenuTemplate(title, icons);
|
||||
|
||||
#define SIMPLE_MENU(title, icons, tab, menu, lines_count) \
|
||||
SIMPLE_MENU_WITH_OPTIONS(title, icons, tab, DIM(tab), menu, lines_count)
|
||||
|
||||
#define SUBMENU(title, icon, lines_count, ...) \
|
||||
MENU_TAB(__VA_ARGS__); \
|
||||
|
|
|
@ -53,7 +53,7 @@ void displayMessageBox()
|
|||
|
||||
void drawAlertBox(const char * title, const char * text, const char * action)
|
||||
{
|
||||
theme->drawAlertBox(title, text, action);
|
||||
theme->drawMessageBox(title, text, action, MESSAGEBOX_TYPE_ALERT);
|
||||
}
|
||||
|
||||
void message(const pm_char * title, const pm_char * text, const char * action, uint8_t sound)
|
||||
|
|
|
@ -20,66 +20,120 @@
|
|||
|
||||
#include "opentx.h"
|
||||
|
||||
const uint8_t * LBM_SCREENS_SETUP_ICONS[] = {
|
||||
LBM_MAINVIEWS_ICON,
|
||||
LBM_MAINVIEWS_TOPBAR_ICON,
|
||||
LBM_MAINVIEWS_ICONS[0],
|
||||
LBM_MAINVIEWS_ICONS[1],
|
||||
LBM_MAINVIEWS_ICONS[2],
|
||||
LBM_MAINVIEWS_ICONS[3],
|
||||
LBM_MAINVIEWS_ICONS[4]
|
||||
};
|
||||
|
||||
Layout * currentScreen;
|
||||
WidgetsContainerInterface * currentContainer;
|
||||
Widget * currentWidget;
|
||||
uint8_t currentZone;
|
||||
|
||||
#define SCREENS_SETUP_2ND_COLUMN 200
|
||||
|
||||
ZoneOptionValue editZoneOption(coord_t y, const ZoneOption * option, ZoneOptionValue value, LcdFlags attr, evt_t event)
|
||||
char fileSelection[sizeof(ZoneOptionValue::stringValue)];
|
||||
uint8_t fileSelectionDone;
|
||||
|
||||
int updateMainviewsMenu();
|
||||
bool menuScreenAdd(evt_t event);
|
||||
void onScreenSetupMenu(const char * result);
|
||||
|
||||
void onZoneOptionFileSelectionMenu(const char * result)
|
||||
{
|
||||
if (result == STR_UPDATE_LIST) {
|
||||
if (!sdListFiles(BITMAPS_PATH, BITMAPS_EXT, sizeof(ZoneOptionValue::stringValue), NULL)) {
|
||||
POPUP_WARNING(STR_NO_BITMAPS_ON_SD);
|
||||
}
|
||||
}
|
||||
else {
|
||||
fileSelectionDone = true;
|
||||
memcpy(fileSelection, result, sizeof(fileSelection));
|
||||
}
|
||||
}
|
||||
|
||||
void editZoneOption(coord_t y, const ZoneOption * option, ZoneOptionValue * value, LcdFlags attr, uint32_t i_flags, evt_t event)
|
||||
{
|
||||
lcdDrawText(MENUS_MARGIN_LEFT, y, option->name);
|
||||
|
||||
if (option->type == ZoneOption::Bool) {
|
||||
value.boolValue = editCheckBox(value.boolValue, SCREENS_SETUP_2ND_COLUMN, y, attr, event);
|
||||
value->boolValue = editCheckBox(value->boolValue, SCREENS_SETUP_2ND_COLUMN, y, attr, event); // TODO always does storageDirty(EE_MODEL)
|
||||
}
|
||||
else if (option->type == ZoneOption::Integer) {
|
||||
lcdDrawNumber(SCREENS_SETUP_2ND_COLUMN, y, value.signedValue, attr | LEFT);
|
||||
lcdDrawNumber(SCREENS_SETUP_2ND_COLUMN, y, value->signedValue, attr | LEFT);
|
||||
if (attr) {
|
||||
CHECK_INCDEC_MODELVAR(event, value.signedValue, -30000, 30000);
|
||||
CHECK_INCDEC_MODELVAR(event, value->signedValue, -30000, 30000); // TODO i_flags
|
||||
}
|
||||
}
|
||||
else if (option->type == ZoneOption::String) {
|
||||
editName(SCREENS_SETUP_2ND_COLUMN, y, value.stringValue, sizeof(value.stringValue), event, attr);
|
||||
editName(SCREENS_SETUP_2ND_COLUMN, y, value->stringValue, sizeof(value->stringValue), event, attr); // TODO i_flags?
|
||||
}
|
||||
else if (option->type == ZoneOption::File) {
|
||||
if (ZEXIST(value->stringValue))
|
||||
lcdDrawSizedText(SCREENS_SETUP_2ND_COLUMN, y, value->stringValue, sizeof(value->stringValue), attr);
|
||||
else
|
||||
lcdDrawTextAtIndex(SCREENS_SETUP_2ND_COLUMN, y, STR_VCSWFUNC, 0, attr); // TODO define
|
||||
if (attr) {
|
||||
if (event==EVT_KEY_BREAK(KEY_ENTER)) {
|
||||
s_editMode = 0;
|
||||
if (sdListFiles(BITMAPS_PATH, BITMAPS_EXT, sizeof(value->stringValue), value->stringValue, LIST_NONE_SD_FILE)) {
|
||||
fileSelectionDone = false;
|
||||
popupMenuHandler = onZoneOptionFileSelectionMenu;
|
||||
}
|
||||
else {
|
||||
POPUP_WARNING(STR_NO_BITMAPS_ON_SD);
|
||||
}
|
||||
}
|
||||
else if (fileSelectionDone) {
|
||||
memcpy(value->stringValue, fileSelection, sizeof(fileSelection));
|
||||
fileSelectionDone = false;
|
||||
storageDirty(i_flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (option->type == ZoneOption::TextSize) {
|
||||
lcdDrawTextAtIndex(SCREENS_SETUP_2ND_COLUMN, y, "\010StandardTiny\0 Small\0 Mid\0 Double", value.unsignedValue, attr);
|
||||
lcdDrawTextAtIndex(SCREENS_SETUP_2ND_COLUMN, y, "\010StandardTiny\0 Small\0 Mid\0 Double", value->unsignedValue, attr);
|
||||
if (attr) {
|
||||
value.unsignedValue = checkIncDec(event, value.unsignedValue, 0, 4, EE_MODEL);
|
||||
value->unsignedValue = checkIncDec(event, value->unsignedValue, 0, 4, i_flags);
|
||||
}
|
||||
}
|
||||
else if (option->type == ZoneOption::Timer) {
|
||||
drawStringWithIndex(SCREENS_SETUP_2ND_COLUMN, y, STR_TIMER, value.unsignedValue + 1, attr);
|
||||
drawStringWithIndex(SCREENS_SETUP_2ND_COLUMN, y, STR_TIMER, value->unsignedValue + 1, attr);
|
||||
if (attr) {
|
||||
value.unsignedValue = checkIncDec(event, value.unsignedValue, 0, MAX_TIMERS - 1, EE_MODEL);
|
||||
value->unsignedValue = checkIncDec(event, value->unsignedValue, 0, MAX_TIMERS - 1, i_flags);
|
||||
}
|
||||
}
|
||||
else if (option->type == ZoneOption::Source) {
|
||||
putsMixerSource(SCREENS_SETUP_2ND_COLUMN, y, value.unsignedValue, attr);
|
||||
putsMixerSource(SCREENS_SETUP_2ND_COLUMN, y, value->unsignedValue, attr);
|
||||
if (attr) {
|
||||
CHECK_INCDEC_MODELSOURCE(event, value.unsignedValue, 1, MIXSRC_LAST);
|
||||
CHECK_INCDEC_MODELSOURCE(event, value->unsignedValue, 1, MIXSRC_LAST);
|
||||
}
|
||||
}
|
||||
else if (option->type == ZoneOption::Color) {
|
||||
lcdSetColor(value.unsignedValue);
|
||||
lcdSetColor(value->unsignedValue);
|
||||
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);
|
||||
value->unsignedValue = checkIncDec(event, value->unsignedValue, i_flags, 65535, 0);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
bool menuWidgetSettings(evt_t event)
|
||||
template <class T>
|
||||
bool menuSettings(const char * title, const T * object, uint32_t i_flags, evt_t event)
|
||||
{
|
||||
linesCount = 0;
|
||||
const ZoneOption * options = currentWidget->getFactory()->getOptions();
|
||||
const ZoneOption * options = object->getOptions();
|
||||
for (const ZoneOption * option = options; option->name; option++) {
|
||||
linesCount++;
|
||||
}
|
||||
|
||||
SUBMENU_WITH_OPTIONS("Widget settings", LBM_MAINVIEWS_ICON, linesCount, OPTION_MENU_TITLE_BAR, { 0, 0, 0 });
|
||||
SUBMENU_WITH_OPTIONS(title, LBM_MAINVIEWS_ICON, linesCount, OPTION_MENU_TITLE_BAR, { 0, 0, 0 });
|
||||
|
||||
for (int i=0; i<NUM_BODY_LINES+1; i++) {
|
||||
coord_t y = MENU_CONTENT_TOP + i * FH;
|
||||
|
@ -88,17 +142,24 @@ bool menuWidgetSettings(evt_t event)
|
|||
LcdFlags attr = (menuVerticalPosition == k ? blink : 0);
|
||||
if (k < linesCount) {
|
||||
const ZoneOption * option = &options[k];
|
||||
ZoneOptionValue value = currentWidget->getOptionValue(k);
|
||||
value = editZoneOption(y, option, value, attr, event);
|
||||
if (attr) {
|
||||
currentWidget->setOptionValue(k, value);
|
||||
}
|
||||
ZoneOptionValue * value = object->getOptionValue(k);
|
||||
editZoneOption(y, option, value, attr, i_flags, event);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool menuWidgetSettings(evt_t event)
|
||||
{
|
||||
return menuSettings<Widget>("Widget settings", currentWidget, EE_MODEL, event);
|
||||
}
|
||||
|
||||
bool menuThemeSettings(evt_t event)
|
||||
{
|
||||
return menuSettings<Theme>("Theme settings", theme, EE_GENERAL, event);
|
||||
}
|
||||
|
||||
bool menuWidgetChoice(evt_t event)
|
||||
{
|
||||
static Widget * previousWidget;
|
||||
|
@ -108,8 +169,8 @@ bool menuWidgetChoice(evt_t event)
|
|||
case EVT_ENTRY:
|
||||
{
|
||||
const WidgetFactory * factory;
|
||||
previousWidget = currentScreen->getWidget(currentZone);
|
||||
currentScreen->setWidget(currentZone, NULL);
|
||||
previousWidget = currentContainer->getWidget(currentZone);
|
||||
currentContainer->setWidget(currentZone, NULL);
|
||||
menuHorizontalPosition = 0;
|
||||
if (previousWidget) {
|
||||
factory = previousWidget->getFactory();
|
||||
|
@ -123,19 +184,19 @@ bool menuWidgetChoice(evt_t event)
|
|||
else {
|
||||
factory = registeredWidgets[0];
|
||||
}
|
||||
currentWidget = factory->create(currentScreen->getZone(currentZone), &tempData);
|
||||
currentWidget = factory->create(currentContainer->getZone(currentZone), &tempData);
|
||||
break;
|
||||
}
|
||||
|
||||
case EVT_KEY_BREAK(KEY_EXIT):
|
||||
delete currentWidget;
|
||||
currentScreen->setWidget(currentZone, previousWidget);
|
||||
currentContainer->setWidget(currentZone, previousWidget);
|
||||
popMenu();
|
||||
return false;
|
||||
|
||||
case EVT_KEY_BREAK(KEY_ENTER):
|
||||
delete previousWidget;
|
||||
currentScreen->createWidget(currentZone, registeredWidgets[menuHorizontalPosition]);
|
||||
currentContainer->createWidget(currentZone, registeredWidgets[menuHorizontalPosition]);
|
||||
storageDirty(EE_MODEL);
|
||||
popMenu();
|
||||
return false;
|
||||
|
@ -143,21 +204,21 @@ bool menuWidgetChoice(evt_t event)
|
|||
case EVT_ROTARY_RIGHT:
|
||||
if (menuHorizontalPosition < int(countRegisteredWidgets-1)) {
|
||||
delete currentWidget;
|
||||
currentWidget = registeredWidgets[++menuHorizontalPosition]->create(currentScreen->getZone(currentZone), &tempData);
|
||||
currentWidget = registeredWidgets[++menuHorizontalPosition]->create(currentContainer->getZone(currentZone), &tempData);
|
||||
}
|
||||
break;
|
||||
|
||||
case EVT_ROTARY_LEFT:
|
||||
if (menuHorizontalPosition > 0) {
|
||||
delete currentWidget;
|
||||
currentWidget = registeredWidgets[--menuHorizontalPosition]->create(currentScreen->getZone(currentZone), &tempData);
|
||||
currentWidget = registeredWidgets[--menuHorizontalPosition]->create(currentContainer->getZone(currentZone), &tempData);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
currentScreen->refresh();
|
||||
|
||||
Zone zone = currentScreen->getZone(currentZone);
|
||||
Zone zone = currentContainer->getZone(currentZone);
|
||||
lcdDrawFilledRect(0, 0, zone.x-2, LCD_H, SOLID, OVERLAY_COLOR | (8<<24));
|
||||
lcdDrawFilledRect(zone.x+zone.w+2, 0, LCD_W-zone.x-zone.w-2, LCD_H, SOLID, OVERLAY_COLOR | (8<<24));
|
||||
lcdDrawFilledRect(zone.x-2, 0, zone.w+4, zone.y-2, SOLID, OVERLAY_COLOR | (8<<24));
|
||||
|
@ -176,20 +237,18 @@ bool menuWidgetChoice(evt_t event)
|
|||
void onZoneMenu(const char * result)
|
||||
{
|
||||
if (result == STR_SELECT_WIDGET) {
|
||||
currentZone = menuVerticalPosition;
|
||||
pushMenu(menuWidgetChoice);
|
||||
}
|
||||
else if (result == STR_WIDGET_SETTINGS) {
|
||||
currentWidget = currentScreen->getWidget(menuVerticalPosition);
|
||||
pushMenu(menuWidgetSettings);
|
||||
}
|
||||
else if (result == STR_REMOVE_WIDGET) {
|
||||
currentScreen->setWidget(menuVerticalPosition, NULL);
|
||||
currentContainer->setWidget(currentZone, NULL);
|
||||
storageDirty(EE_MODEL);
|
||||
}
|
||||
}
|
||||
|
||||
bool menuSetupWidgets(evt_t event)
|
||||
bool menuWidgetsSetup(evt_t event)
|
||||
{
|
||||
switch (event) {
|
||||
case EVT_ENTRY:
|
||||
|
@ -200,17 +259,30 @@ bool menuSetupWidgets(evt_t event)
|
|||
return false;
|
||||
}
|
||||
|
||||
currentScreen->refresh(true);
|
||||
currentScreen->refresh();
|
||||
|
||||
for (int i=currentScreen->getZonesCount()-1; i>=0; i--) {
|
||||
Zone zone = currentScreen->getZone(i);
|
||||
for (int i=currentContainer->getZonesCount()-1; i>=0; i--) {
|
||||
Zone zone = currentContainer->getZone(i);
|
||||
LcdFlags color;
|
||||
int padding, thickness;
|
||||
if (currentContainer == topbar) {
|
||||
color = MENU_TITLE_COLOR;
|
||||
padding = 2;
|
||||
thickness = 1;
|
||||
}
|
||||
else {
|
||||
color = TEXT_INVERTED_BGCOLOR;
|
||||
padding = 4;
|
||||
thickness = 2;
|
||||
}
|
||||
if (menuVerticalPosition == i) {
|
||||
lcdDrawSolidRect(zone.x-4, zone.y-4, zone.w+8, zone.h+8, 2, TEXT_INVERTED_BGCOLOR);
|
||||
lcdDrawSolidRect(zone.x-padding, zone.y-padding, zone.w+2*padding, zone.h+2*padding, thickness, color);
|
||||
if (event == EVT_KEY_BREAK(KEY_ENTER)) {
|
||||
Widget * widget = currentScreen->getWidget(i);
|
||||
if (widget) {
|
||||
currentZone = menuVerticalPosition;
|
||||
currentWidget = currentContainer->getWidget(menuVerticalPosition);
|
||||
if (currentWidget) {
|
||||
POPUP_MENU_ADD_ITEM(STR_SELECT_WIDGET);
|
||||
if (widget->getFactory()->getOptions())
|
||||
if (currentWidget->getFactory()->getOptions())
|
||||
POPUP_MENU_ADD_ITEM(STR_WIDGET_SETTINGS);
|
||||
POPUP_MENU_ADD_ITEM(STR_REMOVE_WIDGET);
|
||||
popupMenuHandler = onZoneMenu;
|
||||
|
@ -221,15 +293,13 @@ bool menuSetupWidgets(evt_t event)
|
|||
}
|
||||
}
|
||||
else {
|
||||
lcdDrawRect(zone.x-4, zone.y-4, zone.w+8, zone.h+8, 2, 0x3F, TEXT_INVERTED_BGCOLOR);
|
||||
lcdDrawRect(zone.x-padding, zone.y-padding, zone.w+2*padding, zone.h+2*padding, thickness, 0x3F, color);
|
||||
}
|
||||
}
|
||||
navigate(event, currentScreen->getZonesCount(), currentScreen->getZonesCount(), 1);
|
||||
navigate(event, currentContainer->getZonesCount(), currentContainer->getZonesCount(), 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
extern int updateMainviewsMenu();
|
||||
|
||||
template <class T>
|
||||
T * editThemeChoice(coord_t x, coord_t y, T * array[], uint8_t count, T * current, bool needsOffsetCheck, LcdFlags attr, evt_t event)
|
||||
{
|
||||
|
@ -291,12 +361,19 @@ T * editThemeChoice(coord_t x, coord_t y, T * array[], uint8_t count, T * curren
|
|||
return NULL;
|
||||
}
|
||||
|
||||
enum menuScreensThemeItems {
|
||||
ITEM_SCREEN_SETUP_THEME,
|
||||
ITEM_SCREEN_SETUP_THEME_SETTINGS = ITEM_SCREEN_SETUP_THEME+2,
|
||||
ITEM_SCREEN_SETUP_TOPBAR,
|
||||
ITEM_SCREEN_SETUP_MAX
|
||||
};
|
||||
|
||||
bool menuScreensTheme(evt_t event)
|
||||
{
|
||||
bool needsOffsetCheck = (menuVerticalPosition != 0 || menuHorizontalPosition < 0);
|
||||
|
||||
menuPageCount = updateMainviewsMenu();
|
||||
MENU_WITH_OPTIONS("User interface", LBM_MAINVIEWS_ICONS, menuTabMainviews, menuPageCount, 0, 1, { uint8_t(NAVIGATION_LINE_BY_LINE|uint8_t(countRegisteredThemes-1)), ORPHAN_ROW, 0, 0, 0, 0 });
|
||||
MENU_WITH_OPTIONS("User interface", LBM_SCREENS_SETUP_ICONS, menuTabScreensSetup, menuPageCount, 0, ITEM_SCREEN_SETUP_MAX, { uint8_t(NAVIGATION_LINE_BY_LINE|uint8_t(countRegisteredThemes-1)), ORPHAN_ROW, 0, 0, 0, 0 });
|
||||
|
||||
for (int i=0; i<NUM_BODY_LINES; i++) {
|
||||
coord_t y = MENU_CONTENT_TOP + i * FH;
|
||||
|
@ -304,10 +381,11 @@ bool menuScreensTheme(evt_t event)
|
|||
LcdFlags blink = ((s_editMode > 0) ? BLINK | INVERS : INVERS);
|
||||
LcdFlags attr = (menuVerticalPosition == k ? blink : 0);
|
||||
switch (k) {
|
||||
case 0: {
|
||||
case ITEM_SCREEN_SETUP_THEME: {
|
||||
lcdDrawText(MENUS_MARGIN_LEFT, y + FH / 2, "Theme");
|
||||
const Theme * new_theme = editThemeChoice<const Theme>(SCREENS_SETUP_2ND_COLUMN, y, registeredThemes, countRegisteredThemes, theme, needsOffsetCheck, attr, event);
|
||||
if (new_theme) {
|
||||
new_theme->init();
|
||||
loadTheme(new_theme);
|
||||
strncpy(g_eeGeneral.themeName, new_theme->getName(), sizeof(g_eeGeneral.themeName));
|
||||
storageDirty(EE_GENERAL);
|
||||
|
@ -315,34 +393,56 @@ bool menuScreensTheme(evt_t event)
|
|||
break;
|
||||
}
|
||||
|
||||
case 1:
|
||||
case ITEM_SCREEN_SETUP_THEME_SETTINGS:
|
||||
drawButton(SCREENS_SETUP_2ND_COLUMN, y, "Theme settings", attr);
|
||||
if (attr && event == EVT_KEY_BREAK(KEY_ENTER) && theme->getOptions()) {
|
||||
s_editMode = 0;
|
||||
pushMenu(menuThemeSettings);
|
||||
}
|
||||
break;
|
||||
|
||||
case ITEM_SCREEN_SETUP_TOPBAR:
|
||||
lcdDrawText(MENUS_MARGIN_LEFT, y, "Top bar");
|
||||
drawButton(SCREENS_SETUP_2ND_COLUMN, y, "Setup", attr);
|
||||
if (attr && event == EVT_KEY_BREAK(KEY_ENTER)) {
|
||||
currentScreen = customScreens[0];
|
||||
currentContainer = topbar;
|
||||
pushMenu(menuWidgetsSetup);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool menuScreenAdd(evt_t event);
|
||||
void onScreenSetupMenu(const char * result);
|
||||
enum menuScreenSetup {
|
||||
ITEM_SCREEN_SETUP_LAYOUT,
|
||||
ITEM_SCREEN_SETUP_WIDGETS_SETUP = ITEM_SCREEN_SETUP_LAYOUT+2,
|
||||
ITEM_SCREEN_SETUP_LAYOUT_OPTION1,
|
||||
};
|
||||
|
||||
template <int T>
|
||||
bool menuScreenSetup(evt_t event)
|
||||
bool menuScreenSetup(int index, evt_t event)
|
||||
{
|
||||
currentScreen = customScreens[T];
|
||||
if (customScreens[index] == NULL) {
|
||||
return menuScreenAdd(event);
|
||||
}
|
||||
|
||||
currentScreen = customScreens[index];
|
||||
currentContainer = currentScreen;
|
||||
bool needsOffsetCheck = (menuVerticalPosition != 0 || menuHorizontalPosition < 0);
|
||||
|
||||
linesCount = 3;
|
||||
linesCount = ITEM_SCREEN_SETUP_LAYOUT_OPTION1;
|
||||
const ZoneOption * options = currentScreen->getFactory()->getOptions();
|
||||
for (const ZoneOption * option = options; option->name; option++) {
|
||||
linesCount++;
|
||||
}
|
||||
|
||||
char title[] = "Main view X";
|
||||
title[sizeof(title)-2] = '1' + T;
|
||||
title[sizeof(title)-2] = '1' + index;
|
||||
menuPageCount = updateMainviewsMenu();
|
||||
MENU_WITH_OPTIONS(title, LBM_MAINVIEWS_ICONS, menuTabMainviews, menuPageCount, T+1, linesCount, { uint8_t(NAVIGATION_LINE_BY_LINE|uint8_t(countRegisteredLayouts-1)), ORPHAN_ROW, 0, 0, 0, 0 });
|
||||
MENU_WITH_OPTIONS(title, LBM_SCREENS_SETUP_ICONS, menuTabScreensSetup, menuPageCount, index+1, linesCount, { uint8_t(NAVIGATION_LINE_BY_LINE|uint8_t(countRegisteredLayouts-1)), ORPHAN_ROW, 0, 0, 0, 0 });
|
||||
|
||||
for (int i=0; i<NUM_BODY_LINES; i++) {
|
||||
coord_t y = MENU_CONTENT_TOP + i * FH;
|
||||
|
@ -350,46 +450,43 @@ bool menuScreenSetup(evt_t event)
|
|||
LcdFlags blink = ((s_editMode>0) ? BLINK|INVERS : INVERS);
|
||||
LcdFlags attr = (menuVerticalPosition == k ? blink : 0);
|
||||
switch(k) {
|
||||
case 0:
|
||||
case ITEM_SCREEN_SETUP_LAYOUT:
|
||||
{
|
||||
lcdDrawText(MENUS_MARGIN_LEFT, y + FH / 2, "Layout");
|
||||
const LayoutFactory * factory = editThemeChoice<const LayoutFactory>(SCREENS_SETUP_2ND_COLUMN, y, registeredLayouts, countRegisteredLayouts, currentScreen->getFactory(), needsOffsetCheck, attr, event);
|
||||
if (factory) {
|
||||
delete customScreens[T];
|
||||
customScreens[T] = factory->create(&g_model.screenData[T].layoutData);
|
||||
strncpy(g_model.screenData[T].layoutName, factory->getName(), sizeof(g_model.screenData[T].layoutName));
|
||||
delete customScreens[index];
|
||||
customScreens[index] = factory->create(&g_model.screenData[index].layoutData);
|
||||
strncpy(g_model.screenData[index].layoutName, factory->getName(), sizeof(g_model.screenData[index].layoutName));
|
||||
storageDirty(EE_MODEL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 1:
|
||||
case ITEM_SCREEN_SETUP_LAYOUT+1:
|
||||
break;
|
||||
|
||||
case 2:
|
||||
case ITEM_SCREEN_SETUP_WIDGETS_SETUP:
|
||||
drawButton(SCREENS_SETUP_2ND_COLUMN, y, "Setup widgets", attr);
|
||||
if (attr && event == EVT_KEY_BREAK(KEY_ENTER)) {
|
||||
pushMenu(menuSetupWidgets);
|
||||
pushMenu(menuWidgetsSetup);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (k < linesCount) {
|
||||
uint8_t index = k - 3;
|
||||
uint8_t index = k - ITEM_SCREEN_SETUP_LAYOUT_OPTION1;
|
||||
const ZoneOption * option = &options[index];
|
||||
ZoneOptionValue value = currentScreen->getOptionValue(index);
|
||||
value = editZoneOption(y, option, value, attr, event);
|
||||
if (attr) {
|
||||
currentScreen->setOptionValue(index, value);
|
||||
}
|
||||
ZoneOptionValue * value = currentScreen->getOptionValue(index);
|
||||
editZoneOption(y, option, value, attr, EE_MODEL, event);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (menuVerticalPosition == -1 && T > 0 && event == EVT_KEY_LONG(KEY_ENTER)) {
|
||||
if (menuVerticalPosition == -1 && index > 0 && event == EVT_KEY_LONG(KEY_ENTER)) {
|
||||
killEvents(KEY_ENTER);
|
||||
menuHorizontalPosition = T;
|
||||
menuHorizontalPosition = index;
|
||||
POPUP_MENU_ADD_ITEM(STR_REMOVE_SCREEN);
|
||||
popupMenuHandler = onScreenSetupMenu;
|
||||
}
|
||||
|
@ -397,33 +494,29 @@ bool menuScreenSetup(evt_t event)
|
|||
return true;
|
||||
}
|
||||
|
||||
MenuHandlerFunc menuTabMainviews[1+MAX_CUSTOM_SCREENS] = {
|
||||
menuScreensTheme,
|
||||
menuScreenSetup<0>,
|
||||
menuScreenSetup<1>,
|
||||
menuScreenSetup<2>,
|
||||
menuScreenSetup<3>,
|
||||
menuScreenSetup<4>
|
||||
};
|
||||
template<int N>
|
||||
bool menuCustomScreenSetup(evt_t event)
|
||||
{
|
||||
return menuScreenSetup(N, event);
|
||||
}
|
||||
|
||||
const MenuHandlerFunc menuMainviews[MAX_CUSTOM_SCREENS] = {
|
||||
menuScreenSetup<0>,
|
||||
menuScreenSetup<1>,
|
||||
menuScreenSetup<2>,
|
||||
menuScreenSetup<3>,
|
||||
menuScreenSetup<4>
|
||||
const MenuHandlerFunc menuTabScreensSetup[1+MAX_CUSTOM_SCREENS] = {
|
||||
menuScreensTheme,
|
||||
menuCustomScreenSetup<0>,
|
||||
menuCustomScreenSetup<1>,
|
||||
menuCustomScreenSetup<2>,
|
||||
menuCustomScreenSetup<3>,
|
||||
menuCustomScreenSetup<4>
|
||||
};
|
||||
|
||||
int updateMainviewsMenu()
|
||||
{
|
||||
for (int index=1; index<MAX_CUSTOM_SCREENS; index++) {
|
||||
if (customScreens[index]) {
|
||||
menuTabMainviews[1+index] = menuMainviews[index];
|
||||
LBM_MAINVIEWS_ICONS[2+index] = LBM_MAINVIEWS_ITEM_OUT_ICON;
|
||||
LBM_SCREENS_SETUP_ICONS[2+index] = LBM_MAINVIEWS_ICONS[index];
|
||||
}
|
||||
else {
|
||||
menuTabMainviews[1+index] = menuScreenAdd;
|
||||
LBM_MAINVIEWS_ICONS[2+index] = LBM_MAINVIEWS_ADD_ICON;
|
||||
LBM_SCREENS_SETUP_ICONS[2+index] = LBM_MAINVIEWS_ADD_ICON;
|
||||
return 2+index;
|
||||
}
|
||||
}
|
||||
|
@ -436,12 +529,11 @@ bool menuScreenAdd(evt_t event)
|
|||
|
||||
if (event == EVT_KEY_BREAK(KEY_ENTER)) {
|
||||
customScreens[menuPageCount-2] = registeredLayouts[0]->create(&g_model.screenData[menuPageCount-2].layoutData);
|
||||
chainMenu(menuMainviews[menuPageCount-2]);
|
||||
s_editMode = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
MENU_WITH_OPTIONS("Add main view", LBM_MAINVIEWS_ICONS, menuTabMainviews, menuPageCount, menuPageCount-1, 0, { uint8_t(NAVIGATION_LINE_BY_LINE|uint8_t(countRegisteredLayouts-1)), ORPHAN_ROW, 0, 0, 0, 0 });
|
||||
|
||||
SIMPLE_MENU_WITH_OPTIONS("Add main view", LBM_SCREENS_SETUP_ICONS, menuTabScreensSetup, menuPageCount, menuPageCount-1, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -455,6 +547,6 @@ void onScreenSetupMenu(const char * result)
|
|||
}
|
||||
memset(&g_model.screenData[MAX_CUSTOM_SCREENS-1], 0, sizeof(CustomScreenData));
|
||||
customScreens[MAX_CUSTOM_SCREENS-1] = NULL;
|
||||
chainMenu(menuMainviews[menuHorizontalPosition > 0 ? menuHorizontalPosition-1 : 0]);
|
||||
// chainMenu(menuMainviews[menuHorizontalPosition > 0 ? menuHorizontalPosition-1 : 0]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,23 +20,54 @@
|
|||
|
||||
#include "opentx.h"
|
||||
|
||||
void Theme::init() const
|
||||
{
|
||||
memset(&g_eeGeneral.themeData, 0, sizeof(Theme::PersistentData));
|
||||
if (options) {
|
||||
int i = 0;
|
||||
for (const ZoneOption * option = options; option->name; option++, i++) {
|
||||
// TODO compiler bug? The CPU freezes ... g_eeGeneral.themeData.options[i] = &option->deflt;
|
||||
memcpy(&g_eeGeneral.themeData.options[i], &option->deflt, sizeof(ZoneOptionValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ZoneOptionValue * Theme::getOptionValue(unsigned int index) const
|
||||
{
|
||||
return &g_eeGeneral.themeData.options[index];
|
||||
}
|
||||
|
||||
void Theme::drawThumb(uint16_t x, uint16_t y, uint32_t flags) const
|
||||
{
|
||||
lcdDrawBitmap(x, y, bitmap);
|
||||
}
|
||||
|
||||
void Theme::drawBackground() const
|
||||
{
|
||||
lcdDrawSolidFilledRect(0, 0, LCD_W, LCD_H, TEXT_BGCOLOR);
|
||||
}
|
||||
|
||||
void Theme::drawAlertBox(const char * title, const char * text, const char * action) const
|
||||
void Theme::drawMessageBox(const char * title, const char * text, const char * action, uint32_t flags) const
|
||||
{
|
||||
//if (flags & MESSAGEBOX_TYPE_ALERT) {
|
||||
drawBackground();
|
||||
lcdDrawFilledRect(0, POPUP_Y, LCD_W, POPUP_H, SOLID, TEXT_INVERTED_COLOR | OPACITY(8));
|
||||
//}
|
||||
|
||||
if ((flags & MESSAGEBOX_TYPE_ALERT) || (flags & MESSAGEBOX_TYPE_WARNING)) {
|
||||
lcdDrawAlphaBitmap(POPUP_X-80, POPUP_Y+12, LBM_ASTERISK);
|
||||
}
|
||||
|
||||
#if defined(TRANSLATIONS_FR) || defined(TRANSLATIONS_IT) || defined(TRANSLATIONS_CZ)
|
||||
if ((flags & MESSAGEBOX_TYPE_ALERT) || (flags & MESSAGEBOX_TYPE_WARNING)) {
|
||||
lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y, STR_WARNING, ALARM_COLOR|DBLSIZE);
|
||||
}
|
||||
lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y+28, title, ALARM_COLOR|DBLSIZE);
|
||||
#else
|
||||
lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y, title, ALARM_COLOR|DBLSIZE);
|
||||
if ((flags & MESSAGEBOX_TYPE_ALERT) || (flags & MESSAGEBOX_TYPE_WARNING)) {
|
||||
lcdDrawText(WARNING_LINE_X, WARNING_LINE_Y+28, STR_WARNING, ALARM_COLOR|DBLSIZE);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (text) {
|
||||
|
@ -53,6 +84,7 @@ unsigned int countRegisteredThemes = 0;
|
|||
void registerTheme(const Theme * theme)
|
||||
{
|
||||
if (countRegisteredThemes < MAX_REGISTERED_THEMES) {
|
||||
TRACE("register theme %s", theme->getName());
|
||||
registeredThemes[countRegisteredThemes++] = theme;
|
||||
}
|
||||
}
|
||||
|
@ -70,6 +102,7 @@ const Theme * getTheme(const char * name)
|
|||
|
||||
void loadTheme(const Theme * new_theme)
|
||||
{
|
||||
TRACE("load theme %s", new_theme->getName());
|
||||
theme = new_theme;
|
||||
theme->load();
|
||||
}
|
||||
|
@ -80,5 +113,11 @@ void loadTheme()
|
|||
memset(name, 0, sizeof(name));
|
||||
strncpy(name, g_eeGeneral.themeName, sizeof(g_eeGeneral.themeName));
|
||||
const Theme * new_theme = getTheme(name);
|
||||
loadTheme(new_theme ? new_theme : theme);
|
||||
if (new_theme) {
|
||||
loadTheme(new_theme);
|
||||
}
|
||||
else {
|
||||
theme->init();
|
||||
theme->load();
|
||||
}
|
||||
}
|
|
@ -21,42 +21,59 @@
|
|||
#ifndef _THEME_H_
|
||||
#define _THEME_H_
|
||||
|
||||
class Theme;
|
||||
#define MAX_THEME_OPTIONS 5
|
||||
|
||||
class Theme;
|
||||
void registerTheme(const Theme * theme);
|
||||
|
||||
#define MESSAGEBOX_TYPE_INFO 0
|
||||
#define MESSAGEBOX_TYPE_QUESTION 1
|
||||
#define MESSAGEBOX_TYPE_WARNING 2
|
||||
#define MESSAGEBOX_TYPE_ALERT 4
|
||||
|
||||
class Theme
|
||||
{
|
||||
public:
|
||||
Theme(const char * name, const uint8_t * bitmap):
|
||||
struct PersistentData {
|
||||
ZoneOptionValue options[MAX_THEME_OPTIONS];
|
||||
};
|
||||
|
||||
Theme(const char * name, const uint8_t * bitmap, const ZoneOption * options=NULL):
|
||||
name(name),
|
||||
bitmap(bitmap)
|
||||
bitmap(bitmap),
|
||||
options(options)
|
||||
{
|
||||
registerTheme(this);
|
||||
}
|
||||
|
||||
const char * getName() const
|
||||
inline const char * getName() const
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
virtual void drawThumb(uint16_t x, uint16_t y, uint32_t flags) const
|
||||
inline const ZoneOption * getOptions() const
|
||||
{
|
||||
extern void lcdDrawBitmap(int x, int y, const uint8_t * bitmap, int offset=0, int height=0, int scale=0);
|
||||
lcdDrawBitmap(x, y, bitmap);
|
||||
return options;
|
||||
}
|
||||
|
||||
void init() const;
|
||||
|
||||
ZoneOptionValue * getOptionValue(unsigned int index) const;
|
||||
|
||||
virtual void drawThumb(uint16_t x, uint16_t y, uint32_t flags) const;
|
||||
|
||||
virtual void load() const = 0;
|
||||
|
||||
virtual void drawBackground() const;
|
||||
|
||||
virtual void drawTopbarBackground(const uint8_t * icon) const = 0;
|
||||
|
||||
virtual void drawAlertBox(const char * title, const char * text, const char * action) const;
|
||||
virtual void drawMessageBox(const char * title, const char * text, const char * action, uint32_t flags) const;
|
||||
|
||||
protected:
|
||||
const char * name;
|
||||
const uint8_t * bitmap;
|
||||
const ZoneOption * options;
|
||||
};
|
||||
|
||||
extern const Theme * theme;
|
||||
|
|
|
@ -20,15 +20,19 @@
|
|||
|
||||
#include "opentx.h"
|
||||
|
||||
const uint8_t LBM_TOPMENU_BMP_OPENTX[] = {
|
||||
const uint8_t LBM_TOPMENU_BMP_OPENTX[] __DMA = {
|
||||
#include "bmp_topmenu_opentx.lbm"
|
||||
};
|
||||
|
||||
const uint8_t LBM_THEME_DARKBLUE[] __DMA = {
|
||||
#include "bmp_darkblue.lbm"
|
||||
};
|
||||
|
||||
class DarkblueTheme: public Theme
|
||||
{
|
||||
public:
|
||||
DarkblueTheme(const char * name, const uint8_t * bitmap):
|
||||
Theme(name, bitmap)
|
||||
DarkblueTheme():
|
||||
Theme("Darkblue", LBM_THEME_DARKBLUE)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -77,8 +81,4 @@ class DarkblueTheme: public Theme
|
|||
}
|
||||
};
|
||||
|
||||
const uint8_t LBM_THEME_DARKBLUE[] __DMA = {
|
||||
#include "bmp_darkblue.lbm"
|
||||
};
|
||||
|
||||
DarkblueTheme darkblueTheme("Darkblue", LBM_THEME_DARKBLUE);
|
||||
DarkblueTheme darkblueTheme;
|
||||
|
|
100
radio/src/gui/horus/topbar.cpp
Normal file
100
radio/src/gui/horus/topbar.cpp
Normal file
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* 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"
|
||||
|
||||
unsigned int Topbar::getZonesCount() const
|
||||
{
|
||||
return MAX_TOPBAR_ZONES;
|
||||
}
|
||||
|
||||
Zone Topbar::getZone(unsigned int index) const
|
||||
{
|
||||
Zone zone;
|
||||
zone.x = 50 + (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;
|
||||
}
|
||||
|
||||
void drawTopBar()
|
||||
{
|
||||
theme->drawTopbarBackground(NULL);
|
||||
|
||||
// USB icon
|
||||
if (usbPlugged()) {
|
||||
lcdDrawBitmapPattern(378, 8, LBM_TOPMENU_USB, MENU_TITLE_COLOR);
|
||||
}
|
||||
|
||||
// RSSI
|
||||
const uint8_t rssiBarsValue[] = {30, 40, 50, 60, 80};
|
||||
const uint8_t rssiBarsHeight[] = {5, 10, 15, 21, 31};
|
||||
for (unsigned int i = 0; i < DIM(rssiBarsHeight); i++) {
|
||||
uint8_t height = rssiBarsHeight[i];
|
||||
lcdDrawSolidFilledRect(390 + i * 6, 38 - height, 4, height, TELEMETRY_RSSI() >= rssiBarsValue[i] ? MENU_TITLE_COLOR : MENU_TITLE_DISABLE_COLOR);
|
||||
}
|
||||
|
||||
topbar->refresh();
|
||||
|
||||
#if 0
|
||||
// Radio battery - TODO
|
||||
// putsValueWithUnit(370, 8, g_vbat100mV, UNIT_VOLTS, PREC1|SMLSIZE|MENU_TITLE_COLOR);
|
||||
// lcdDrawSolidRect(300, 3, 20, 50, MENU_TITLE_COLOR);
|
||||
// lcdDrawRect(batt_icon_x+FW, BAR_Y+1, 13, 7);
|
||||
// lcdDrawSolidVerticalLine(batt_icon_x+FW+13, BAR_Y+2, 5);
|
||||
|
||||
// Rx battery
|
||||
if (g_model.frsky.voltsSource) { // TODO should not be in frsky struct
|
||||
TelemetryItem & item = telemetryItems[g_model.frsky.voltsSource-1];
|
||||
if (item.isAvailable()) {
|
||||
int32_t value = item.value;
|
||||
TelemetrySensor & sensor = g_model.telemetrySensors[g_model.frsky.altitudeSource-1];
|
||||
LcdFlags att = 0;
|
||||
if (sensor.prec == 2) {
|
||||
att |= PREC1;
|
||||
value /= 10;
|
||||
}
|
||||
else if (sensor.prec == 1) {
|
||||
att |= PREC1;
|
||||
}
|
||||
att |= (item.isOld() ? ALARM_COLOR : TEXT_COLOR);
|
||||
lcdDrawSolidFilledRect(ALTITUDE_X, VOLTS_Y, ALTITUDE_W, ALTITUDE_H, TEXT_BGCOLOR);
|
||||
lcdDrawText(ALTITUDE_X+PADDING, VOLTS_Y+2, "Voltage", att);
|
||||
putsValueWithUnit(ALTITUDE_X+PADDING, VOLTS_Y+12, value, UNIT_VOLTS, DBLSIZE|LEFT|att);
|
||||
}
|
||||
}
|
||||
|
||||
// Model altitude
|
||||
if (g_model.frsky.altitudeSource) {
|
||||
TelemetryItem & item = telemetryItems[g_model.frsky.altitudeSource-1];
|
||||
if (item.isAvailable()) {
|
||||
int32_t value = item.value;
|
||||
TelemetrySensor & sensor = g_model.telemetrySensors[g_model.frsky.altitudeSource-1];
|
||||
if (sensor.prec) value /= sensor.prec == 2 ? 100 : 10;
|
||||
LcdFlags att = (item.isOld() ? ALARM_COLOR : TEXT_COLOR);
|
||||
lcdDrawSolidFilledRect(ALTITUDE_X, ALTITUDE_Y, ALTITUDE_W, ALTITUDE_H, TEXT_BGCOLOR);
|
||||
lcdDrawText(ALTITUDE_X+PADDING, ALTITUDE_Y+2, "Alt", att);
|
||||
putsValueWithUnit(ALTITUDE_X+PADDING, ALTITUDE_Y+12, value, UNIT_METERS, DBLSIZE|LEFT|att);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
44
radio/src/gui/horus/topbar.h
Normal file
44
radio/src/gui/horus/topbar.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _TOPBAR_H_
|
||||
#define _TOPBAR_H_
|
||||
|
||||
#include "widgets_container.h"
|
||||
|
||||
#define MAX_TOPBAR_ZONES 5
|
||||
#define MAX_TOPBAR_OPTIONS 0
|
||||
#define TOPBAR_ZONE_WIDTH 60
|
||||
#define TOPBAR_ZONE_MARGIN 3
|
||||
|
||||
class Topbar: public WidgetsContainer<MAX_TOPBAR_ZONES, MAX_TOPBAR_OPTIONS>
|
||||
{
|
||||
public:
|
||||
explicit Topbar(PersistentData * persistentData):
|
||||
WidgetsContainer<MAX_TOPBAR_ZONES, MAX_TOPBAR_OPTIONS>(persistentData)
|
||||
{
|
||||
}
|
||||
|
||||
virtual unsigned int getZonesCount() const;
|
||||
|
||||
virtual Zone getZone(unsigned int index) const;
|
||||
};
|
||||
|
||||
#endif // _TOPBAR_H_
|
|
@ -30,6 +30,7 @@
|
|||
#define POTS_LINE_Y 252
|
||||
|
||||
Layout * customScreens[MAX_CUSTOM_SCREENS];
|
||||
Topbar * topbar;
|
||||
|
||||
void drawMainPots()
|
||||
{
|
||||
|
@ -79,72 +80,6 @@ void drawTrims(uint8_t flightMode)
|
|||
}
|
||||
}
|
||||
|
||||
void drawMainViewTopBar()
|
||||
{
|
||||
const int ALTITUDE_Y = 16;
|
||||
const int VOLTS_Y = 16+16+30;
|
||||
const int ALTITUDE_W = 56;
|
||||
const int ALTITUDE_X = LCD_W-ALTITUDE_Y-ALTITUDE_W;
|
||||
const int ALTITUDE_H = 30;
|
||||
const int PADDING = 4;
|
||||
|
||||
theme->drawTopbarBackground(NULL);
|
||||
|
||||
// USB icon
|
||||
if (usbPlugged()) {
|
||||
lcdDrawBitmapPattern(378, 8, LBM_TOPMENU_USB, MENU_TITLE_COLOR);
|
||||
}
|
||||
|
||||
// RSSI
|
||||
const uint8_t rssiBarsValue[] = { 30, 40, 50, 60, 80 };
|
||||
const uint8_t rssiBarsHeight[] = { 5, 10, 15, 21, 31 };
|
||||
for (unsigned int i=0; i<DIM(rssiBarsHeight); i++) {
|
||||
uint8_t height = rssiBarsHeight[i];
|
||||
lcdDrawSolidFilledRect(390+i*6, 38-height, 4, height, TELEMETRY_RSSI() >= rssiBarsValue[i] ? MENU_TITLE_COLOR : MENU_TITLE_DISABLE_COLOR);
|
||||
}
|
||||
|
||||
// Radio battery - TODO
|
||||
// putsValueWithUnit(370, 8, g_vbat100mV, UNIT_VOLTS, PREC1|SMLSIZE|MENU_TITLE_COLOR);
|
||||
// lcdDrawSolidRect(300, 3, 20, 50, MENU_TITLE_COLOR);
|
||||
// lcdDrawRect(batt_icon_x+FW, BAR_Y+1, 13, 7);
|
||||
// lcdDrawSolidVerticalLine(batt_icon_x+FW+13, BAR_Y+2, 5);
|
||||
|
||||
// Rx battery
|
||||
if (g_model.frsky.voltsSource) { // TODO should not be in frsky struct
|
||||
TelemetryItem & item = telemetryItems[g_model.frsky.voltsSource-1];
|
||||
if (item.isAvailable()) {
|
||||
int32_t value = item.value;
|
||||
TelemetrySensor & sensor = g_model.telemetrySensors[g_model.frsky.altitudeSource-1];
|
||||
LcdFlags att = 0;
|
||||
if (sensor.prec == 2) {
|
||||
att |= PREC1;
|
||||
value /= 10;
|
||||
}
|
||||
else if (sensor.prec == 1) {
|
||||
att |= PREC1;
|
||||
}
|
||||
att |= (item.isOld() ? ALARM_COLOR : TEXT_COLOR);
|
||||
lcdDrawSolidFilledRect(ALTITUDE_X, VOLTS_Y, ALTITUDE_W, ALTITUDE_H, TEXT_BGCOLOR);
|
||||
lcdDrawText(ALTITUDE_X+PADDING, VOLTS_Y+2, "Voltage", att);
|
||||
putsValueWithUnit(ALTITUDE_X+PADDING, VOLTS_Y+12, value, UNIT_VOLTS, DBLSIZE|LEFT|att);
|
||||
}
|
||||
}
|
||||
|
||||
// Model altitude
|
||||
if (g_model.frsky.altitudeSource) {
|
||||
TelemetryItem & item = telemetryItems[g_model.frsky.altitudeSource-1];
|
||||
if (item.isAvailable()) {
|
||||
int32_t value = item.value;
|
||||
TelemetrySensor & sensor = g_model.telemetrySensors[g_model.frsky.altitudeSource-1];
|
||||
if (sensor.prec) value /= sensor.prec == 2 ? 100 : 10;
|
||||
LcdFlags att = (item.isOld() ? ALARM_COLOR : TEXT_COLOR);
|
||||
lcdDrawSolidFilledRect(ALTITUDE_X, ALTITUDE_Y, ALTITUDE_W, ALTITUDE_H, TEXT_BGCOLOR);
|
||||
lcdDrawText(ALTITUDE_X+PADDING, ALTITUDE_Y+2, "Alt", att);
|
||||
putsValueWithUnit(ALTITUDE_X+PADDING, ALTITUDE_Y+12, value, UNIT_METERS, DBLSIZE|LEFT|att);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool isViewAvailable(int index)
|
||||
{
|
||||
if (index <= VIEW_CHANNELS)
|
||||
|
@ -187,7 +122,7 @@ void onMainViewMenu(const char *result)
|
|||
chainMenu(menuStatisticsView);
|
||||
}
|
||||
else if (result == STR_SETUP_SCREENS) {
|
||||
pushMenu(menuTabMainviews[1]);
|
||||
pushMenu(menuTabScreensSetup[1]);
|
||||
}
|
||||
else if (result == STR_ABOUT_US) {
|
||||
chainMenu(menuAboutView);
|
||||
|
|
|
@ -25,6 +25,7 @@ unsigned int countRegisteredWidgets = 0;
|
|||
void registerWidget(const WidgetFactory * factory)
|
||||
{
|
||||
if (countRegisteredWidgets < MAX_REGISTERED_WIDGETS) {
|
||||
TRACE("register widget %s", factory->getName());
|
||||
registeredWidgets[countRegisteredWidgets++] = factory;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
#include <inttypes.h>
|
||||
|
||||
#define MAX_WIDGET_OPTIONS 4
|
||||
#define MAX_WIDGET_OPTIONS 5
|
||||
|
||||
struct Zone
|
||||
{
|
||||
|
@ -45,6 +45,7 @@ struct ZoneOption
|
|||
Source,
|
||||
Bool,
|
||||
String,
|
||||
File,
|
||||
TextSize,
|
||||
Timer,
|
||||
Switch,
|
||||
|
@ -75,19 +76,16 @@ class Widget
|
|||
{
|
||||
}
|
||||
|
||||
const WidgetFactory * getFactory() const
|
||||
inline const WidgetFactory * getFactory() const
|
||||
{
|
||||
return factory;
|
||||
}
|
||||
|
||||
virtual ZoneOptionValue getOptionValue(unsigned int index) const
|
||||
{
|
||||
return persistentData->options[index];
|
||||
}
|
||||
inline const ZoneOption * getOptions() const;
|
||||
|
||||
virtual void setOptionValue(unsigned int index, ZoneOptionValue value) const
|
||||
inline ZoneOptionValue * getOptionValue(unsigned int index) const
|
||||
{
|
||||
persistentData->options[index] = value;
|
||||
return &persistentData->options[index];
|
||||
}
|
||||
|
||||
virtual void refresh() = 0;
|
||||
|
@ -103,7 +101,7 @@ void registerWidget(const WidgetFactory * factory);
|
|||
class WidgetFactory
|
||||
{
|
||||
public:
|
||||
WidgetFactory(const char * name, const ZoneOption * options):
|
||||
WidgetFactory(const char * name, const ZoneOption * options=NULL):
|
||||
name(name),
|
||||
options(options)
|
||||
{
|
||||
|
@ -126,7 +124,8 @@ class WidgetFactory
|
|||
if (options) {
|
||||
int i = 0;
|
||||
for (const ZoneOption * option = options; option->name; option++) {
|
||||
persistentData->options[i++] = option->deflt;
|
||||
// TODO compiler bug? The CPU freezes ... persistentData->options[i++] = option->deflt;
|
||||
memcpy(&persistentData->options[i++], &option->deflt, sizeof(ZoneOptionValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -157,6 +156,11 @@ class BaseWidgetFactory: public WidgetFactory
|
|||
}
|
||||
};
|
||||
|
||||
inline const ZoneOption * Widget::getOptions() const
|
||||
{
|
||||
return getFactory()->getOptions();
|
||||
}
|
||||
|
||||
#define MAX_REGISTERED_WIDGETS 10
|
||||
extern unsigned int countRegisteredWidgets;
|
||||
extern const WidgetFactory * registeredWidgets[MAX_REGISTERED_WIDGETS];
|
||||
|
|
|
@ -426,7 +426,7 @@ int16_t editGVarFieldValue(coord_t x, coord_t y, int16_t value, int16_t min, int
|
|||
void drawSleepBitmap()
|
||||
{
|
||||
lcdClear();
|
||||
lcdDrawAlphaBitmap((LCD_W-SLEEP_BITMAP_WIDTH)/2, (LCD_H-SLEEP_BITMAP_HEIGHT)/2, LBM_SLEEP);
|
||||
lcdDrawBitmap((LCD_W-SLEEP_BITMAP_WIDTH)/2, (LCD_H-SLEEP_BITMAP_HEIGHT)/2, LBM_SLEEP);
|
||||
lcdRefresh();
|
||||
}
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ void drawSleepBitmap();
|
|||
void drawShutdownBitmap(uint32_t index);
|
||||
|
||||
// Main view standard widgets
|
||||
void drawMainViewTopBar();
|
||||
void drawTopBar();
|
||||
void drawMainPots();
|
||||
void drawTrims(uint8_t flightMode);
|
||||
|
||||
|
|
|
@ -63,9 +63,9 @@ void GaugeWidget::refresh()
|
|||
|
||||
// Gauge
|
||||
lcdSetColor(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);
|
||||
lcdDrawSolidFilledRect(zone.x, zone.y + 16, zone.w, 16, TEXT_INVERTED_COLOR);
|
||||
lcdDrawNumber((percent >= 100 ? 20 : (percent >= 10 ? 10 : 0)) + zone.x+zone.w/2, zone.y + 17, percent, SMLSIZE | CUSTOM_COLOR, 0, NULL, "%");
|
||||
lcdInvertRect(zone.x + w, zone.y + 16, zone.w - w, 16, CUSTOM_COLOR);
|
||||
}
|
||||
|
||||
BaseWidgetFactory<GaugeWidget> gaugeWidget("Gauge", GaugeWidget::options);
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
|
||||
#include "opentx.h"
|
||||
|
||||
class ModelPanelWidget: public Widget
|
||||
class ModelBitmapWidget: public Widget
|
||||
{
|
||||
public:
|
||||
ModelPanelWidget(const WidgetFactory * factory, const Zone & zone, Widget::PersistentData * persistentData):
|
||||
ModelBitmapWidget(const WidgetFactory * factory, const Zone & zone, Widget::PersistentData * persistentData):
|
||||
Widget(factory, zone, persistentData)
|
||||
{
|
||||
}
|
||||
|
@ -31,26 +31,24 @@ class ModelPanelWidget: public Widget
|
|||
virtual void refresh();
|
||||
};
|
||||
|
||||
void ModelPanelWidget::refresh()
|
||||
void ModelBitmapWidget::refresh()
|
||||
{
|
||||
if (zone.h >= MODEL_BITMAP_HEIGHT) {
|
||||
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);
|
||||
lcdDrawSolidFilledRect(zone.x + 39, zone.y + 27, zone.w - 48, 2, MAINVIEW_GRAPHICS_COLOR);
|
||||
int scale = getBitmapScale(modelBitmap, zone.w, zone.h - 25);
|
||||
float scale = getBitmapScale(modelBitmap, zone.w, zone.h - 25);
|
||||
int width = getBitmapScaledSize(getBitmapWidth(modelBitmap), scale);
|
||||
int height = getBitmapScaledSize(getBitmapHeight(modelBitmap), scale);
|
||||
lcdDrawBitmap(zone.x + (zone.w - width) / 2, zone.y + zone.h - height / 2 - height / 2, modelBitmap, 0, 0, scale);
|
||||
}
|
||||
else {
|
||||
int scale = getBitmapScale(modelBitmap, zone.w, zone.h);
|
||||
float scale = getBitmapScale(modelBitmap, 1000, zone.h);
|
||||
int width = getBitmapScaledSize(getBitmapWidth(modelBitmap), scale);
|
||||
int height = getBitmapScaledSize(getBitmapHeight(modelBitmap), scale);
|
||||
lcdDrawFilledRect(zone.x, zone.y, zone.w, height, SOLID, MAINVIEW_PANES_COLOR | OPACITY(5));
|
||||
lcdDrawSizedText(zone.x + 5, zone.y + 10, g_model.header.name, LEN_MODEL_NAME, ZCHAR | SMLSIZE);
|
||||
lcdDrawBitmap(zone.x + zone.w - width, zone.y, modelBitmap, 0, 0, scale);
|
||||
lcdDrawBitmap(zone.x + (zone.w - width) / 2, zone.y + (zone.h - height) / 2, modelBitmap, 0, 0, scale);
|
||||
}
|
||||
}
|
||||
|
||||
BaseWidgetFactory<ModelPanelWidget> modelPanelWidget("ModelPanel", NULL);
|
||||
BaseWidgetFactory<ModelBitmapWidget> modelBitmapWidget("ModelBmp", NULL);
|
|
@ -41,21 +41,35 @@ const ZoneOption TimerWidget::options[] = {
|
|||
void TimerWidget::refresh()
|
||||
{
|
||||
uint32_t index = persistentData->options[0].unsignedValue;
|
||||
|
||||
TimerData & timerData = g_model.timers[index];
|
||||
TimerState & timerState = timersStates[index];
|
||||
|
||||
if (zone.w >= 180 && zone.h >= 70) {
|
||||
lcdDrawBitmapPattern(zone.x, zone.y, LBM_TIMER_BACKGROUND, MAINVIEW_PANES_COLOR);
|
||||
if (timerData.start) {
|
||||
lcdDrawBitmapPatternPie(zone.x+2, zone.y+3, LBM_RSCALE, MAINVIEW_GRAPHICS_COLOR, 0, timerState.val <= 0 ? 360 : 360*(timerData.start-timerState.val)/timerData.start);
|
||||
lcdDrawBitmapPatternPie(
|
||||
zone.x + 2,
|
||||
zone.y + 3, LBM_RSCALE, MAINVIEW_GRAPHICS_COLOR, 0,
|
||||
timerState.val <= 0 ? 360 : 360 * (timerData.start - timerState.val) / timerData.start);
|
||||
}
|
||||
else {
|
||||
lcdDrawBitmapPattern(zone.x+3, zone.y+4, LBM_TIMER, MAINVIEW_GRAPHICS_COLOR);
|
||||
lcdDrawBitmapPattern(zone.x + 3, zone.y + 4, LBM_TIMER, MAINVIEW_GRAPHICS_COLOR);
|
||||
}
|
||||
putsTimer(zone.x+76, zone.y+31, abs(timerState.val), TEXT_COLOR|DBLSIZE|LEFT);
|
||||
putsTimer(zone.x + 76, zone.y + 31, abs(timerState.val), TEXT_COLOR | DBLSIZE | LEFT);
|
||||
if (ZLEN(timerData.name) > 0) {
|
||||
lcdDrawSizedText(zone.x+78, zone.y+20, timerData.name, LEN_TIMER_NAME, ZCHAR|SMLSIZE|TEXT_COLOR);
|
||||
lcdDrawSizedText(zone.x + 78, zone.y + 20, timerData.name, LEN_TIMER_NAME, ZCHAR | SMLSIZE | TEXT_COLOR);
|
||||
}
|
||||
drawStringWithIndex(zone.x + 137, zone.y + 17, "TMR", index + 1, SMLSIZE | TEXT_COLOR);
|
||||
}
|
||||
else {
|
||||
drawStringWithIndex(zone.x, zone.y, "TMR", index + 1, SMLSIZE | TEXT_INVERTED_COLOR);
|
||||
if (zone.w > 100) {
|
||||
putsTimer(zone.x, zone.y + 16, abs(timerState.val), TEXT_INVERTED_COLOR | LEFT | MIDSIZE);
|
||||
}
|
||||
else {
|
||||
putsTimer(zone.x, zone.y + 14, abs(timerState.val), TEXT_INVERTED_COLOR | LEFT);
|
||||
}
|
||||
}
|
||||
drawStringWithIndex(zone.x+137, zone.y+17, "TMR", index+1, SMLSIZE|TEXT_COLOR);
|
||||
}
|
||||
|
||||
BaseWidgetFactory<TimerWidget> timerWidget("Timer", TimerWidget::options);
|
||||
|
|
|
@ -44,23 +44,35 @@ void ValueWidget::refresh()
|
|||
|
||||
mixsrc_t field = persistentData->options[0].unsignedValue;
|
||||
|
||||
LcdFlags color = TEXT_COLOR;
|
||||
LcdFlags color = TEXT_INVERTED_COLOR;
|
||||
int x = zone.x;
|
||||
int y = zone.y;
|
||||
|
||||
lcdDrawFilledRect(zone.x, zone.y, zone.w, zone.h, SOLID, MAINVIEW_PANES_COLOR | OPACITY(5));
|
||||
// lcdDrawFilledRect(zone.x, zone.y, zone.w, zone.h, SOLID, MAINVIEW_PANES_COLOR | OPACITY(5));
|
||||
|
||||
int xValue, yValue;
|
||||
LcdFlags attr;
|
||||
if (zone.h < 50) {
|
||||
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 = SMLSIZE;
|
||||
}
|
||||
else if (zone.h < 50) {
|
||||
xValue = x+zone.w-NUMBERS_PADDING;
|
||||
yValue = y-2;
|
||||
attr = NO_UNIT;
|
||||
xLabel = x+NUMBERS_PADDING;
|
||||
yLabel = y+2;
|
||||
attrValue = NO_UNIT | DBLSIZE;
|
||||
}
|
||||
else {
|
||||
xValue = x+NUMBERS_PADDING;
|
||||
yValue = y+16;
|
||||
attr = LEFT;
|
||||
xLabel = x+NUMBERS_PADDING;
|
||||
yLabel = y+2;
|
||||
attrValue = LEFT | DBLSIZE;
|
||||
}
|
||||
|
||||
if (field >= MIXSRC_FIRST_TIMER && field <= MIXSRC_LAST_TIMER) {
|
||||
|
@ -69,7 +81,7 @@ void ValueWidget::refresh()
|
|||
color = ALARM_COLOR;
|
||||
}
|
||||
putsMixerSource(x+NUMBERS_PADDING, y+2, field, color);
|
||||
putsTimer(xValue, yValue, abs(timerState.val), attr|DBLSIZE|color);
|
||||
putsTimer(xValue, yValue, abs(timerState.val), attrValue|DBLSIZE|color);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -83,8 +95,8 @@ void ValueWidget::refresh()
|
|||
}
|
||||
}
|
||||
|
||||
putsMixerSource(x+NUMBERS_PADDING, y+2, field, color);
|
||||
putsChannel(xValue, yValue, field, attr|DBLSIZE|color);
|
||||
putsMixerSource(xLabel, yLabel, field, attrLabel|color);
|
||||
putsChannel(xValue, yValue, field, attrValue|color);
|
||||
}
|
||||
|
||||
BaseWidgetFactory<ValueWidget> ValueWidget("Value", ValueWidget::options);
|
||||
|
|
133
radio/src/gui/horus/widgets_container.h
Normal file
133
radio/src/gui/horus/widgets_container.h
Normal file
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _WIDGETS_CONTAINER_H_
|
||||
#define _WIDGETS_CONTAINER_H_
|
||||
|
||||
#include "widget.h"
|
||||
|
||||
class WidgetsContainerInterface
|
||||
{
|
||||
public:
|
||||
virtual unsigned int getZonesCount() const = 0;
|
||||
|
||||
virtual Zone getZone(unsigned int index) const = 0;
|
||||
|
||||
inline Widget * getWidget(unsigned int index)
|
||||
{
|
||||
return widgets[index];
|
||||
}
|
||||
|
||||
inline void setWidget(unsigned int index, Widget * widget)
|
||||
{
|
||||
widgets[index] = widget;
|
||||
}
|
||||
|
||||
virtual void createWidget(unsigned int index, const WidgetFactory * factory) = 0;
|
||||
|
||||
protected:
|
||||
Widget ** widgets;
|
||||
};
|
||||
|
||||
template<int N, int O>
|
||||
class WidgetsContainer: public WidgetsContainerInterface
|
||||
{
|
||||
public:
|
||||
struct ZonePersistentData {
|
||||
char widgetName[10];
|
||||
Widget::PersistentData widgetData;
|
||||
};
|
||||
|
||||
struct PersistentData {
|
||||
ZonePersistentData zones[N];
|
||||
ZoneOptionValue options[O];
|
||||
};
|
||||
|
||||
public:
|
||||
WidgetsContainer(PersistentData * persistentData):
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void createWidget(unsigned int index, const WidgetFactory * factory)
|
||||
{
|
||||
if (widgets) {
|
||||
memset(persistentData->zones[index].widgetName, 0, sizeof(persistentData->zones[index].widgetName));
|
||||
strncpy(persistentData->zones[index].widgetName, factory->getName(), sizeof(persistentData->zones[index].widgetName));
|
||||
widgets[index] = factory->create(getZone(index), &persistentData->zones[index].widgetData);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void create()
|
||||
{
|
||||
memset(persistentData, 0, sizeof(PersistentData));
|
||||
}
|
||||
|
||||
virtual void load()
|
||||
{
|
||||
if (widgets) {
|
||||
unsigned int count = getZonesCount();
|
||||
for (unsigned int i=0; i<count; i++) {
|
||||
if (persistentData->zones[i].widgetName[0]) {
|
||||
char name[sizeof(persistentData->zones[i].widgetName)+1];
|
||||
memset(name, 0, sizeof(name));
|
||||
strncpy(name, persistentData->zones[i].widgetName, sizeof(persistentData->zones[i].widgetName));
|
||||
widgets[i] = loadWidget(name, getZone(i), &persistentData->zones[i].widgetData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline ZoneOptionValue * getOptionValue(unsigned int index) const
|
||||
{
|
||||
return &persistentData->options[index];
|
||||
}
|
||||
|
||||
virtual unsigned int getZonesCount() const = 0;
|
||||
|
||||
virtual Zone getZone(unsigned int index) const = 0;
|
||||
|
||||
virtual void refresh()
|
||||
{
|
||||
if (widgets) {
|
||||
for (int i=0; i<N; i++) {
|
||||
if (widgets[i]) {
|
||||
widgets[i]->refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
PersistentData * persistentData;
|
||||
};
|
||||
|
||||
#endif // _WIDGETS_CONTAINER_H_
|
|
@ -776,13 +776,61 @@ void exec(int function, int nresults=0)
|
|||
}
|
||||
}
|
||||
|
||||
ZoneOption * createOptionsArray(int reference)
|
||||
{
|
||||
if (reference == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, reference);
|
||||
for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
|
||||
count++;
|
||||
}
|
||||
|
||||
ZoneOption * options = (ZoneOption *)malloc(sizeof(ZoneOption) * (count+1));
|
||||
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, reference);
|
||||
ZoneOption * option = options;
|
||||
for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
|
||||
luaL_checktype(L, -2, LUA_TNUMBER); // key is number
|
||||
luaL_checktype(L, -1, LUA_TTABLE); // value is table
|
||||
uint8_t field = 0;
|
||||
for (lua_pushnil(L); lua_next(L, -2) && field<3; lua_pop(L, 1), field++) {
|
||||
switch (field) {
|
||||
case 0:
|
||||
luaL_checktype(L, -2, LUA_TNUMBER); // key is number
|
||||
luaL_checktype(L, -1, LUA_TSTRING); // value is string
|
||||
option->name = lua_tostring(L, -1);
|
||||
break;
|
||||
case 1:
|
||||
luaL_checktype(L, -2, LUA_TNUMBER); // key is number
|
||||
luaL_checktype(L, -1, LUA_TNUMBER); // value is number
|
||||
option->type = (ZoneOption::Type)lua_tointeger(L, -1);
|
||||
break;
|
||||
case 2:
|
||||
luaL_checktype(L, -2, LUA_TNUMBER); // key is number
|
||||
luaL_checktype(L, -1, LUA_TNUMBER); // value is number
|
||||
option->deflt.signedValue = lua_tointeger(L, -1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
TRACE("option %s %d %d", option->name, option->type, option->deflt.signedValue);
|
||||
option++;
|
||||
}
|
||||
|
||||
option->name = NULL; // sentinel
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
class LuaTheme: public Theme
|
||||
{
|
||||
friend void luaLoadThemeCallback();
|
||||
|
||||
public:
|
||||
LuaTheme(const char * name, const uint8_t * bitmap):
|
||||
Theme(name, bitmap),
|
||||
LuaTheme(const char * name, const uint8_t * bitmap, int options):
|
||||
Theme(name, bitmap, createOptionsArray(options)),
|
||||
loadFunction(0),
|
||||
drawBackgroundFunction(0),
|
||||
drawTopbarBackgroundFunction(0),
|
||||
|
@ -823,7 +871,7 @@ class LuaTheme: public Theme
|
|||
void luaLoadThemeCallback()
|
||||
{
|
||||
const char * name=NULL, * bitmap=NULL;
|
||||
int loadFunction=0, drawBackgroundFunction=0, drawTopbarBackgroundFunction=0;
|
||||
int themeOptions=0, loadFunction=0, drawBackgroundFunction=0, drawTopbarBackgroundFunction=0;
|
||||
|
||||
luaL_checktype(L, -1, LUA_TTABLE);
|
||||
|
||||
|
@ -835,6 +883,10 @@ void luaLoadThemeCallback()
|
|||
else if (!strcmp(key, "bitmap")) {
|
||||
bitmap = luaL_checkstring(L, -1);
|
||||
}
|
||||
else if (!strcmp(key, "options")) {
|
||||
themeOptions = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
lua_pushnil(L);
|
||||
}
|
||||
else if (!strcmp(key, "load")) {
|
||||
loadFunction = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
lua_pushnil(L);
|
||||
|
@ -854,8 +906,9 @@ void luaLoadThemeCallback()
|
|||
strcpy(path, THEMES_PATH "/");
|
||||
strcpy(path+sizeof(THEMES_PATH), bitmap);
|
||||
uint8_t * bitmapData = (uint8_t *)malloc(BITMAP_BUFFER_SIZE(51, 31));
|
||||
TRACE("path=%s bitmapData=%p %d %p", path, bitmapData, BITMAP_BUFFER_SIZE(51, 31), path);
|
||||
bmpLoad(bitmapData, path, 51, 31);
|
||||
LuaTheme * theme = new LuaTheme(name, bitmapData);
|
||||
LuaTheme * theme = new LuaTheme(name, bitmapData, themeOptions);
|
||||
theme->loadFunction = loadFunction;
|
||||
theme->drawBackgroundFunction = drawBackgroundFunction;
|
||||
theme->drawTopbarBackgroundFunction = drawTopbarBackgroundFunction;
|
||||
|
@ -882,55 +935,6 @@ class LuaWidget: public Widget
|
|||
int widgetData;
|
||||
};
|
||||
|
||||
ZoneOption * createOptionsArray(int reference)
|
||||
{
|
||||
int count = 0;
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, reference);
|
||||
for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
|
||||
count++;
|
||||
}
|
||||
|
||||
ZoneOption * options = (ZoneOption *)malloc(sizeof(ZoneOption) * (count+1));
|
||||
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, reference);
|
||||
ZoneOption * option = options;
|
||||
for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) {
|
||||
luaL_checktype(L, -2, LUA_TNUMBER); // key is number
|
||||
luaL_checktype(L, -1, LUA_TTABLE); // value is table
|
||||
// const char * key = NULL;
|
||||
// ZoneOption::Type type = ZoneOption::Integer;
|
||||
// int val = 0;
|
||||
uint8_t field = 0;
|
||||
for (lua_pushnil(L); lua_next(L, -2) && field<3; lua_pop(L, 1), field++) {
|
||||
switch (field) {
|
||||
case 0:
|
||||
luaL_checktype(L, -2, LUA_TNUMBER); // key is number
|
||||
luaL_checktype(L, -1, LUA_TSTRING); // value is string
|
||||
option->name = lua_tostring(L, -1);
|
||||
break;
|
||||
case 1:
|
||||
luaL_checktype(L, -2, LUA_TNUMBER); // key is number
|
||||
luaL_checktype(L, -1, LUA_TNUMBER); // value is number
|
||||
option->type = (ZoneOption::Type)lua_tointeger(L, -1);
|
||||
break;
|
||||
case 2:
|
||||
luaL_checktype(L, -2, LUA_TNUMBER); // key is number
|
||||
luaL_checktype(L, -1, LUA_TNUMBER); // value is number
|
||||
option->deflt.signedValue = lua_tointeger(L, -1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// TRACE("option[%d] = %s %d %d", i, key, type, val);
|
||||
option++;
|
||||
// options[i++]. = (ZoneOption) { key, type, { .signedValue = val } };
|
||||
}
|
||||
|
||||
option->name = NULL; // sentinel
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
void l_pushtableint(const char * key, int value)
|
||||
{
|
||||
lua_pushstring(L, key);
|
||||
|
@ -998,7 +1002,7 @@ void LuaWidget::refresh()
|
|||
|
||||
void luaLoadWidgetCallback()
|
||||
{
|
||||
const char * name=NULL, * options=NULL;
|
||||
const char * name=NULL;
|
||||
int widgetOptions=0, createFunction=0, refreshFunction=0;
|
||||
|
||||
luaL_checktype(L, -1, LUA_TTABLE);
|
||||
|
@ -1071,6 +1075,7 @@ void luaLoadFiles(const char * directory, void (*callback)())
|
|||
int pathlen = strlen(path);
|
||||
|
||||
FRESULT res = f_opendir(&dir, path); /* Open the directory */
|
||||
|
||||
if (res == FR_OK) {
|
||||
path[pathlen++] = '/';
|
||||
for (;;) {
|
||||
|
@ -1078,12 +1083,15 @@ void luaLoadFiles(const char * directory, void (*callback)())
|
|||
if (res != FR_OK || fno.fname[0] == 0) break; /* Break on error or end of dir */
|
||||
fn = * fno.lfname ? fno.lfname : fno.fname;
|
||||
uint8_t len = strlen(fn);
|
||||
// Eliminates directories / non wav files
|
||||
// Eliminates directories / non scripts files
|
||||
if (len < 5 || strcasecmp(fn+len-4, SCRIPTS_EXT) || (fno.fattrib & AM_DIR)) continue;
|
||||
strcpy(&path[pathlen], fn);
|
||||
luaLoadFile(path, callback);
|
||||
}
|
||||
}
|
||||
else {
|
||||
TRACE("f_opendir(%s) failed, code=%d", path, res);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -440,8 +440,7 @@ enum UartModes {
|
|||
char anaNames[NUM_STICKS+NUM_POTS][LEN_ANA_NAME]; \
|
||||
char currModelFilename[LEN_MODEL_FILENAME+1]; \
|
||||
uint8_t bluetoothEnable; \
|
||||
char bluetoothName[LEN_BLUETOOTH_NAME]; \
|
||||
char themeName[8];
|
||||
char bluetoothName[LEN_BLUETOOTH_NAME];
|
||||
#elif defined(PCBFLAMENCO)
|
||||
#define LEN_SWITCH_NAME 3
|
||||
#define LEN_ANA_NAME 3
|
||||
|
@ -840,6 +839,31 @@ PACK(typedef struct {
|
|||
#endif
|
||||
|
||||
#define ALTERNATE_VIEW 0x10
|
||||
|
||||
#if defined(COLORLCD)
|
||||
#include "layout.h"
|
||||
#include "theme.h"
|
||||
#include "topbar.h"
|
||||
#define SWITCHES_WARNING_DATA \
|
||||
swarnstate_t switchWarningState;
|
||||
PACK(typedef struct {
|
||||
char layoutName[10];
|
||||
Layout::PersistentData layoutData;
|
||||
}) CustomScreenData;
|
||||
#define CUSTOM_SCREENS_DATA \
|
||||
CustomScreenData screenData[MAX_CUSTOM_SCREENS]; \
|
||||
Topbar::PersistentData topbarData;
|
||||
#define THEME_DATA \
|
||||
char themeName[8]; \
|
||||
Theme::PersistentData themeData;
|
||||
#else
|
||||
#define SWITCHES_WARNING_DATA \
|
||||
swarnstate_t switchWarningState; \
|
||||
swarnenable_t switchWarningEnable;
|
||||
#define CUSTOM_SCREENS_DATA
|
||||
#define THEME_DATA
|
||||
#endif
|
||||
|
||||
PACK(typedef struct {
|
||||
uint8_t version;
|
||||
uint16_t variant;
|
||||
|
@ -885,6 +909,8 @@ PACK(typedef struct {
|
|||
|
||||
EXTRA_GENERAL_FIELDS
|
||||
|
||||
THEME_DATA
|
||||
|
||||
}) EEGeneral;
|
||||
|
||||
#define SWITCHES_DELAY() uint8_t(15+g_eeGeneral.switchesDelay)
|
||||
|
@ -2288,23 +2314,6 @@ enum DisplayTrims
|
|||
DISPLAY_TRIMS_ALWAYS
|
||||
};
|
||||
|
||||
#if defined(COLORLCD)
|
||||
#include "layout.h"
|
||||
#define SWITCHES_WARNING_DATA \
|
||||
swarnstate_t switchWarningState;
|
||||
PACK(typedef struct {
|
||||
char layoutName[10];
|
||||
Layout::PersistentData layoutData;
|
||||
}) CustomScreenData;
|
||||
#define CUSTOM_SCREENS_DATA \
|
||||
CustomScreenData screenData[MAX_CUSTOM_SCREENS];
|
||||
#else
|
||||
#define SWITCHES_WARNING_DATA \
|
||||
swarnstate_t switchWarningState; \
|
||||
swarnenable_t switchWarningEnable;
|
||||
#define CUSTOM_SCREENS_DATA
|
||||
#endif
|
||||
|
||||
PACK(typedef struct {
|
||||
ModelHeader header;
|
||||
TimerData timers[MAX_TIMERS];
|
||||
|
|
|
@ -2469,15 +2469,25 @@ uint16_t stackAvailable()
|
|||
|
||||
void opentxInit(OPENTX_INIT_ARGS)
|
||||
{
|
||||
#if defined(DEBUG) && defined(USB_SERIAL)
|
||||
CoTickDelay(5000); // 10s
|
||||
#endif
|
||||
|
||||
TRACE("opentxInit()");
|
||||
|
||||
sdInit();
|
||||
|
||||
#if defined(COLORLCD)
|
||||
topbar = new Topbar(&g_model.topbarData);
|
||||
luaInit();
|
||||
loadTheme();
|
||||
#endif
|
||||
|
||||
storageReadAll();
|
||||
|
||||
#if defined(COLORLCD)
|
||||
loadTheme();
|
||||
#endif
|
||||
|
||||
#if defined(CPUARM)
|
||||
if (UNEXPECTED_SHUTDOWN()) {
|
||||
unexpectedShutdown = 1;
|
||||
|
|
|
@ -352,7 +352,6 @@ long Open9xSim::onTimeout(FXObject*, FXSelector, void*)
|
|||
updateKeysAndSwitches();
|
||||
|
||||
#if defined(PCBHORUS)
|
||||
extern rotenc_t rotencValue;
|
||||
#define ROTENC_VALUE rotencValue
|
||||
#else
|
||||
#define ROTENC_VALUE g_rotenc[0]
|
||||
|
|
|
@ -337,12 +337,17 @@ void * main_thread(void *)
|
|||
menuHandlers[1] = menuModelSelect;
|
||||
|
||||
#if defined(COLORLCD)
|
||||
topbar = new Topbar(&g_model.topbarData);
|
||||
luaInit();
|
||||
loadTheme();
|
||||
// TODO the theme is not initialized, in case of sdcard error, we should have something strange
|
||||
#endif
|
||||
|
||||
storageReadAll(); // load general setup and selected model
|
||||
|
||||
#if defined(COLORLCD)
|
||||
loadTheme();
|
||||
#endif
|
||||
|
||||
#if defined(SIMU_DISKIO)
|
||||
f_mount(&g_FATFS_Obj, "", 1);
|
||||
// call sdGetFreeSectors() now because f_getfree() takes a long time first time it's called
|
||||
|
|
|
@ -222,6 +222,7 @@ uint32_t readTrims(void);
|
|||
|
||||
#if defined(REV9E)
|
||||
// Rotary Encoder driver
|
||||
extern int32_t rotencValue;
|
||||
void rotencInit(void);
|
||||
void rotencEnd(void);
|
||||
void checkRotaryEncoder(void);
|
||||
|
|
|
@ -951,8 +951,8 @@
|
|||
#define TR_BYTES "bytes"
|
||||
#define TR_MODULE_BIND BUTTON(TR("Bnd", "Bind"))
|
||||
#define TR_MODULE_RANGE BUTTON(TR("Rng", "Range"))
|
||||
#define TR_RESET_BTN "[Reset]"
|
||||
#define TR_SET "[Set]"
|
||||
#define TR_RESET_BTN BUTTON("Reset")
|
||||
#define TR_SET BUTTON("Set")
|
||||
#define TR_TRAINER "Trainer Port"
|
||||
#define TR_ANTENNAPROBLEM CENTER "TX Antenna problem!"
|
||||
#define TR_MODELIDUSED TR("ID already used","Model ID already used")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue