Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(color): allow changing the size of topbar widgets #5235

Merged
merged 14 commits into from
Jul 27, 2024
12 changes: 11 additions & 1 deletion companion/src/firmwares/edgetx/yaml_modeldata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1179,6 +1179,9 @@ Node convert<ModelData>::encode(const ModelData& rhs)
if (topbarData && topbarData.IsMap()) {
node["topbarData"] = topbarData;
}
for (int i = 0; i < MAX_TOPBAR_ZONES; i += 1)
if (rhs.topbarWidgetWidth[i] > 0)
node["topbarWidgetWidth"][std::to_string(i)]["val"] = (int)rhs.topbarWidgetWidth[i];
node["view"] = rhs.view;
}

Expand Down Expand Up @@ -1447,8 +1450,15 @@ bool convert<ModelData>::decode(const Node& node, ModelData& rhs)

node["screenData"] >> rhs.customScreens.customScreenData;
node["topbarData"] >> rhs.topBarData;

if (node["topbarWidgetWidth"]) {
for (int i = 0; i < MAX_TOPBAR_ZONES; i += 1) {
if (node["topbarWidgetWidth"][std::to_string(i)]) {
node["topbarWidgetWidth"][std::to_string(i)]["val"] >> rhs.topbarWidgetWidth[i];
}
}
}
node["view"] >> rhs.view;

node["modelRegistrationID"] >> rhs.registrationId;
node["hatsMode"] >> hatsModeLut >> rhs.hatsMode;

Expand Down
1 change: 1 addition & 0 deletions companion/src/firmwares/modeldata.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ class ModelData {

RadioLayout::CustomScreens customScreens;
TopBarPersistentData topBarData;
uint8_t topbarWidgetWidth[MAX_TOPBAR_ZONES];
unsigned int view;

char registrationId[8+1];
Expand Down
8 changes: 4 additions & 4 deletions radio/src/datastructs.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,13 @@ static inline void check_struct()
#elif defined(PCBX7) || defined(PCBXLITE) || defined(PCBX9LITE)
CHKSIZE(ModelData, 6329);
#elif defined(PCBNV14)
CHKSIZE(ModelData, 15655);
CHKSIZE(ModelData, 15659);
#elif defined(PCBPL18)
CHKSIZE(ModelData, 15835);
CHKSIZE(ModelData, 15841);
#elif defined(RADIO_T15)
CHKSIZE(ModelData, 15824);
CHKSIZE(ModelData, 15830);
#elif defined(PCBHORUS)
CHKSIZE(ModelData, 15799);
CHKSIZE(ModelData, 15805);
#else
#error CHKSIZE not set up
#endif
Expand Down
5 changes: 3 additions & 2 deletions radio/src/datastructs_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ PACK(struct MixData {
uint16_t mltpx:2 ENUM(MixerMultiplex);
uint16_t speedPrec:1;
uint16_t flightModes:9 CUST(r_flightModes, w_flightModes);
uint16_t spare:2;
uint16_t spare:2 SKIP;
uint32_t weight:11 CUST(r_sourceNumVal,w_sourceNumVal);
uint32_t offset:11 CUST(r_sourceNumVal,w_sourceNumVal);
int32_t swtch:10 CUST(r_swtchSrc,w_swtchSrc);
Expand Down Expand Up @@ -123,7 +123,7 @@ PACK(struct ExpoData {
CurveRef curve;
uint16_t chn:5;
uint16_t flightModes:9 CUST(r_flightModes, w_flightModes);
uint16_t spare:2;
uint16_t spare:2 SKIP;
NOBACKUP(char name[LEN_EXPOMIX_NAME]);
});

Expand Down Expand Up @@ -596,6 +596,7 @@ PACK(struct CustomScreenData {
#define CUSTOM_SCREENS_DATA \
NOBACKUP(CustomScreenData screenData[MAX_CUSTOM_SCREENS]); \
NOBACKUP(TopBarPersistentData topbarData); \
NOBACKUP(uint8_t topbarWidgetWidth[MAX_TOPBAR_ZONES]); \
NOBACKUP(uint8_t view);
#else
#define CUSTOM_SCREENS_DATA \
Expand Down
27 changes: 14 additions & 13 deletions radio/src/gui/colorlcd/layouts/topbar_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,24 +50,25 @@ TopBar::TopBar(Window * parent) :

unsigned int TopBar::getZonesCount() const
{
return MAX_TOPBAR_ZONES;
unsigned int zoneCount = 0;
for (int i = 0; i < MAX_TOPBAR_ZONES; i += 1)
if (g_model.topbarWidgetWidth[i] > 0)
zoneCount += 1;
return zoneCount;
}

rect_t TopBar::getZone(unsigned int index) const
{
#if PORTRAIT_LCD
if (index == MAX_TOPBAR_ZONES - 1) {
coord_t size = LCD_W - HDR_DATE_XO - (MAX_TOPBAR_ZONES - 1) * (TOPBAR_ZONE_WIDTH + TOPBAR_ZONE_HMARGIN);
return {LCD_W - size, TOPBAR_ZONE_VMARGIN, size, TOPBAR_ZONE_HEIGHT};
}
#endif
coord_t x = MENU_HEADER_BUTTONS_LEFT + 1;

for (int i = 0; i < index; i += 1)
x += (g_model.topbarWidgetWidth[i] * (TOPBAR_ZONE_WIDTH + TOPBAR_ZONE_HMARGIN));

coord_t size = ((g_model.topbarWidgetWidth[index] - 1) * (TOPBAR_ZONE_WIDTH + TOPBAR_ZONE_HMARGIN) + TOPBAR_ZONE_WIDTH);

if ((x + size) > LCD_W) size = LCD_W - x;

return {
coord_t(MENU_HEADER_BUTTONS_LEFT + 1 + (TOPBAR_ZONE_WIDTH + TOPBAR_ZONE_HMARGIN) * index),
TOPBAR_ZONE_VMARGIN,
TOPBAR_ZONE_WIDTH,
TOPBAR_ZONE_HEIGHT
};
return {x, TOPBAR_ZONE_VMARGIN, size, TOPBAR_ZONE_HEIGHT};
}

void TopBar::setVisible(float visible) // 0.0 -> 1.0
Expand Down
66 changes: 60 additions & 6 deletions radio/src/gui/colorlcd/screen_user_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include "file_preview.h"
#include "menu_screen.h"
#include "theme_manager.h"
#include "topbar_impl.h"
#include "view_main.h"

#if !PORTRAIT_LCD // landscape

Expand Down Expand Up @@ -146,12 +148,64 @@ void ScreenUserInterfacePage::build(Window* window)
auto line = window->newLine(grid);
new StaticText(line, rect_t{}, STR_TOP_BAR);

auto setupTopbarWidgets = new TextButton(line, rect_t{}, STR_SETUP_WIDGETS);
setupTopbarWidgets->setPressHandler([=]() -> uint8_t {
menu->deleteLater();
new SetupTopBarWidgetsPage();
return 0;
});
auto setupTopbarWidgets = new TextButton(line, rect_t{}, STR_SETUP_WIDGETS,
[=]() -> uint8_t {
menu->deleteLater();
new SetupTopBarWidgetsPage();
return 0;
});

line = window->newLine(grid);
new StaticText(line, rect_t{}, STR_WIDGET_SIZE);
line = window->newLine(grid);
auto box = new Window(line, rect_t{});
box->setFlexLayout(LV_FLEX_FLOW_ROW, PAD_TINY);
box->padAll(PAD_TINY);
box->padLeft(PAD_MEDIUM);
for (int i = 0; i < MAX_TOPBAR_ZONES; i += 1) {
coord_t w = (g_model.topbarWidgetWidth[i] * (WWBTN_W + PAD_TINY)) - PAD_TINY;
if (w < WWBTN_W) w = WWBTN_W;
widths[i] = new Choice(box, {0, 0, w, 0}, 0, MAX_TOPBAR_ZONES,
[=]() {
return g_model.topbarWidgetWidth[i];
},
[=](int value) {
g_model.topbarWidgetWidth[i] = value;
coord_t w = (g_model.topbarWidgetWidth[i] * (WWBTN_W + PAD_TINY)) - PAD_TINY;
widths[i]->setWidth(w);
int remaining = MAX_TOPBAR_ZONES;
for (int n = 0; n < MAX_TOPBAR_ZONES; n += 1) {
if (n > i) {
if (remaining > 0) {
if (g_model.topbarWidgetWidth[n] == 0) {
g_model.topbarWidgetWidth[n] = 1;
widths[n]->setWidth(WWBTN_W);
widths[n]->show();
widths[n]->update();
}
} else {
if (g_model.topbarWidgetWidth[n] != 0) {
g_model.topbarWidgetWidth[n] = 0;
widths[n]->setWidth(WWBTN_W);
widths[n]->hide();
ViewMain::instance()->getTopbar()->removeWidget(n);
}
}
}
ViewMain::instance()->getTopbar()->load();
remaining -= g_model.topbarWidgetWidth[n];
}
storageDirty(EE_MODEL);
}, STR_WIDGET_SIZE);
widths[i]->setAvailableHandler([=](int value) {
int remaining = MAX_TOPBAR_ZONES;
for (int n = 0; n < i; n += 1)
remaining -= g_model.topbarWidgetWidth[n];
return value > 0 && value <= remaining;
});
if (g_model.topbarWidgetWidth[i] == 0)
widths[i]->hide();
}

// Theme choice
line = window->newLine(grid);
Expand Down
5 changes: 5 additions & 0 deletions radio/src/gui/colorlcd/screen_user_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@
#pragma once

#include "tabsgroup.h"
#include "widgets_container.h"

class ScreenMenu;
class ThemeView;
class Choice;

class ScreenUserInterfacePage : public PageTab
{
Expand All @@ -33,7 +35,10 @@ class ScreenUserInterfacePage : public PageTab

void build(Window* window) override;

static LAYOUT_VAL(WWBTN_W, 60, 60)

protected:
ScreenMenu* menu;
Choice* widths[MAX_TOPBAR_ZONES];
ThemeView* themeView = nullptr;
};
36 changes: 21 additions & 15 deletions radio/src/storage/storage_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,23 +161,29 @@ static void sanitizeMixerLines()
void postModelLoad(bool alarms)
{
#if defined(COLORLCD)
// Load 'date time' widget if slot is empty
if (g_model.topbarData.zones[MAX_TOPBAR_ZONES-1].widgetName[0] == 0) {
strAppend(g_model.topbarData.zones[MAX_TOPBAR_ZONES-1].widgetName, "Date Time", WIDGET_NAME_LEN);
storageDirty(EE_MODEL);
}
// Load 'radio info' widget if slot is empty
if (g_model.topbarData.zones[MAX_TOPBAR_ZONES-2].widgetName[0] == 0) {
strAppend(g_model.topbarData.zones[MAX_TOPBAR_ZONES-2].widgetName, "Radio Info", WIDGET_NAME_LEN);
storageDirty(EE_MODEL);
}
if (g_model.topbarWidgetWidth[0] == 0) {
// Set default width for top bar widgets
for (int i = 0; i < MAX_TOPBAR_ZONES; i += 1)
g_model.topbarWidgetWidth[i] = 1;

// Load 'date time' widget if slot is empty
if (g_model.topbarData.zones[MAX_TOPBAR_ZONES-1].widgetName[0] == 0) {
strAppend(g_model.topbarData.zones[MAX_TOPBAR_ZONES-1].widgetName, "Date Time", WIDGET_NAME_LEN);
storageDirty(EE_MODEL);
}
// Load 'radio info' widget if slot is empty
if (g_model.topbarData.zones[MAX_TOPBAR_ZONES-2].widgetName[0] == 0) {
strAppend(g_model.topbarData.zones[MAX_TOPBAR_ZONES-2].widgetName, "Radio Info", WIDGET_NAME_LEN);
storageDirty(EE_MODEL);
}
#if defined(INTERNAL_GPS)
// Load 'internal gps' widget if slot is empty
if (g_model.topbarData.zones[MAX_TOPBAR_ZONES-3].widgetName[0] == 0) {
strAppend(g_model.topbarData.zones[MAX_TOPBAR_ZONES-3].widgetName, "Internal GPS", WIDGET_NAME_LEN);
storageDirty(EE_MODEL);
}
// Load 'internal gps' widget if slot is empty
if (g_model.topbarData.zones[MAX_TOPBAR_ZONES-3].widgetName[0] == 0) {
strAppend(g_model.topbarData.zones[MAX_TOPBAR_ZONES-3].widgetName, "Internal GPS", WIDGET_NAME_LEN);
storageDirty(EE_MODEL);
}
#endif
}
#elif LCD_W == 128
// Prevent GVARS to be off when imported or manually modified yaml
// Since there is no way to have those back
Expand Down
4 changes: 2 additions & 2 deletions radio/src/storage/yaml/yaml_datastructs_128x64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ static const struct YamlNode struct_MixData[] = {
YAML_ENUM("mltpx", 2, enum_MixerMultiplex),
YAML_UNSIGNED( "speedPrec", 1 ),
YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ),
YAML_UNSIGNED( "spare", 2 ),
YAML_PADDING( 2 ),
YAML_UNSIGNED_CUST( "weight", 11, r_sourceNumVal, w_sourceNumVal ),
YAML_UNSIGNED_CUST( "offset", 11, r_sourceNumVal, w_sourceNumVal ),
YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ),
Expand Down Expand Up @@ -440,7 +440,7 @@ static const struct YamlNode struct_ExpoData[] = {
YAML_STRUCT("curve", 16, struct_CurveRef, NULL),
YAML_UNSIGNED( "chn", 5 ),
YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ),
YAML_UNSIGNED( "spare", 2 ),
YAML_PADDING( 2 ),
YAML_STRING("name", 6),
YAML_END
};
Expand Down
5 changes: 3 additions & 2 deletions radio/src/storage/yaml/yaml_datastructs_nv14.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ static const struct YamlNode struct_MixData[] = {
YAML_ENUM("mltpx", 2, enum_MixerMultiplex),
YAML_UNSIGNED( "speedPrec", 1 ),
YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ),
YAML_UNSIGNED( "spare", 2 ),
YAML_PADDING( 2 ),
YAML_UNSIGNED_CUST( "weight", 11, r_sourceNumVal, w_sourceNumVal ),
YAML_UNSIGNED_CUST( "offset", 11, r_sourceNumVal, w_sourceNumVal ),
YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ),
Expand Down Expand Up @@ -466,7 +466,7 @@ static const struct YamlNode struct_ExpoData[] = {
YAML_STRUCT("curve", 16, struct_CurveRef, NULL),
YAML_UNSIGNED( "chn", 5 ),
YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ),
YAML_UNSIGNED( "spare", 2 ),
YAML_PADDING( 2 ),
YAML_STRING("name", 6),
YAML_END
};
Expand Down Expand Up @@ -864,6 +864,7 @@ static const struct YamlNode struct_ModelData[] = {
YAML_ARRAY("telemetrySensors", 112, 60, struct_TelemetrySensor, NULL),
YAML_ARRAY("screenData", 6816, 10, struct_CustomScreenData, NULL),
YAML_STRUCT("topbarData", 2400, struct_TopBarPersistentData, NULL),
YAML_ARRAY("topbarWidgetWidth", 8, 4, struct_unsigned_8, NULL),
YAML_UNSIGNED( "view", 8 ),
YAML_STRING("modelRegistrationID", 8),
YAML_UNSIGNED( "usbJoystickExtMode", 1 ),
Expand Down
5 changes: 3 additions & 2 deletions radio/src/storage/yaml/yaml_datastructs_pl18.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ static const struct YamlNode struct_MixData[] = {
YAML_ENUM("mltpx", 2, enum_MixerMultiplex),
YAML_UNSIGNED( "speedPrec", 1 ),
YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ),
YAML_UNSIGNED( "spare", 2 ),
YAML_PADDING( 2 ),
YAML_UNSIGNED_CUST( "weight", 11, r_sourceNumVal, w_sourceNumVal ),
YAML_UNSIGNED_CUST( "offset", 11, r_sourceNumVal, w_sourceNumVal ),
YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ),
Expand Down Expand Up @@ -466,7 +466,7 @@ static const struct YamlNode struct_ExpoData[] = {
YAML_STRUCT("curve", 16, struct_CurveRef, NULL),
YAML_UNSIGNED( "chn", 5 ),
YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ),
YAML_UNSIGNED( "spare", 2 ),
YAML_PADDING( 2 ),
YAML_STRING("name", 6),
YAML_END
};
Expand Down Expand Up @@ -864,6 +864,7 @@ static const struct YamlNode struct_ModelData[] = {
YAML_ARRAY("telemetrySensors", 112, 60, struct_TelemetrySensor, NULL),
YAML_ARRAY("screenData", 6816, 10, struct_CustomScreenData, NULL),
YAML_STRUCT("topbarData", 3552, struct_TopBarPersistentData, NULL),
YAML_ARRAY("topbarWidgetWidth", 8, 6, struct_unsigned_8, NULL),
YAML_UNSIGNED( "view", 8 ),
YAML_STRING("modelRegistrationID", 8),
YAML_UNSIGNED( "usbJoystickExtMode", 1 ),
Expand Down
5 changes: 3 additions & 2 deletions radio/src/storage/yaml/yaml_datastructs_t15.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ static const struct YamlNode struct_MixData[] = {
YAML_ENUM("mltpx", 2, enum_MixerMultiplex),
YAML_UNSIGNED( "speedPrec", 1 ),
YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ),
YAML_UNSIGNED( "spare", 2 ),
YAML_PADDING( 2 ),
YAML_UNSIGNED_CUST( "weight", 11, r_sourceNumVal, w_sourceNumVal ),
YAML_UNSIGNED_CUST( "offset", 11, r_sourceNumVal, w_sourceNumVal ),
YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ),
Expand Down Expand Up @@ -468,7 +468,7 @@ static const struct YamlNode struct_ExpoData[] = {
YAML_STRUCT("curve", 16, struct_CurveRef, NULL),
YAML_UNSIGNED( "chn", 5 ),
YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ),
YAML_UNSIGNED( "spare", 2 ),
YAML_PADDING( 2 ),
YAML_STRING("name", 6),
YAML_END
};
Expand Down Expand Up @@ -870,6 +870,7 @@ static const struct YamlNode struct_ModelData[] = {
YAML_ARRAY("telemetrySensors", 112, 60, struct_TelemetrySensor, NULL),
YAML_ARRAY("screenData", 6816, 10, struct_CustomScreenData, NULL),
YAML_STRUCT("topbarData", 3552, struct_TopBarPersistentData, NULL),
YAML_ARRAY("topbarWidgetWidth", 8, 6, struct_unsigned_8, NULL),
YAML_UNSIGNED( "view", 8 ),
YAML_STRING("modelRegistrationID", 8),
YAML_UNSIGNED( "functionSwitchConfig", 16 ),
Expand Down
4 changes: 2 additions & 2 deletions radio/src/storage/yaml/yaml_datastructs_t20.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ static const struct YamlNode struct_MixData[] = {
YAML_ENUM("mltpx", 2, enum_MixerMultiplex),
YAML_UNSIGNED( "speedPrec", 1 ),
YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ),
YAML_UNSIGNED( "spare", 2 ),
YAML_PADDING( 2 ),
YAML_UNSIGNED_CUST( "weight", 11, r_sourceNumVal, w_sourceNumVal ),
YAML_UNSIGNED_CUST( "offset", 11, r_sourceNumVal, w_sourceNumVal ),
YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ),
Expand Down Expand Up @@ -440,7 +440,7 @@ static const struct YamlNode struct_ExpoData[] = {
YAML_STRUCT("curve", 16, struct_CurveRef, NULL),
YAML_UNSIGNED( "chn", 5 ),
YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ),
YAML_UNSIGNED( "spare", 2 ),
YAML_PADDING( 2 ),
YAML_STRING("name", 6),
YAML_END
};
Expand Down
4 changes: 2 additions & 2 deletions radio/src/storage/yaml/yaml_datastructs_tpro.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ static const struct YamlNode struct_MixData[] = {
YAML_ENUM("mltpx", 2, enum_MixerMultiplex),
YAML_UNSIGNED( "speedPrec", 1 ),
YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ),
YAML_UNSIGNED( "spare", 2 ),
YAML_PADDING( 2 ),
YAML_UNSIGNED_CUST( "weight", 11, r_sourceNumVal, w_sourceNumVal ),
YAML_UNSIGNED_CUST( "offset", 11, r_sourceNumVal, w_sourceNumVal ),
YAML_SIGNED_CUST( "swtch", 10, r_swtchSrc, w_swtchSrc ),
Expand Down Expand Up @@ -440,7 +440,7 @@ static const struct YamlNode struct_ExpoData[] = {
YAML_STRUCT("curve", 16, struct_CurveRef, NULL),
YAML_UNSIGNED( "chn", 5 ),
YAML_UNSIGNED_CUST( "flightModes", 9, r_flightModes, w_flightModes ),
YAML_UNSIGNED( "spare", 2 ),
YAML_PADDING( 2 ),
YAML_STRING("name", 6),
YAML_END
};
Expand Down
Loading
Loading