WiP
This commit is contained in:
@@ -46,6 +46,9 @@ const LayoutFactory * getLayoutFactory(const char * name)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//
|
||||
// Loads a layout, but does not attach it to any window
|
||||
//
|
||||
Layout * loadLayout(const char * name, Layout::PersistentData * persistentData)
|
||||
{
|
||||
const LayoutFactory * factory = getLayoutFactory(name);
|
||||
@@ -55,10 +58,12 @@ Layout * loadLayout(const char * name, Layout::PersistentData * persistentData)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//
|
||||
// Detaches and deletes all custom screens
|
||||
//
|
||||
void deleteCustomScreens()
|
||||
{
|
||||
for (unsigned int i = 0; i < MAX_CUSTOM_SCREENS; i++) {
|
||||
auto& screen = customScreens[i];
|
||||
for (auto& screen : customScreens) {
|
||||
if (screen) {
|
||||
screen->detach();
|
||||
delete screen;
|
||||
@@ -75,6 +80,7 @@ void loadDefaultLayout()
|
||||
auto& screenData = g_model.screenData[0];
|
||||
|
||||
if (screen == nullptr && defaultLayout != nullptr) {
|
||||
|
||||
strcpy(screenData.LayoutId, defaultLayout->getId());
|
||||
screen = defaultLayout->create(&screenData.layoutData);
|
||||
if (screen) {
|
||||
@@ -83,6 +89,9 @@ void loadDefaultLayout()
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Loads and attaches all configured custom screens
|
||||
//
|
||||
void loadCustomScreens()
|
||||
{
|
||||
for (unsigned int i = 0; i < MAX_CUSTOM_SCREENS; i++) {
|
||||
@@ -97,6 +106,53 @@ void loadCustomScreens()
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Creates a new customer screen from factory:
|
||||
// - the old screen is detached & deleted (including children)
|
||||
// - new screen is configured into g_model
|
||||
// - the new screen is returned (not attached)
|
||||
//
|
||||
Layout* createCustomScreen(const LayoutFactory* factory, unsigned customScreenIndex)
|
||||
{
|
||||
if (!factory || (customScreenIndex >= MAX_CUSTOM_SCREENS))
|
||||
return nullptr;
|
||||
|
||||
if (customScreens[customScreenIndex]) {
|
||||
customScreens[customScreenIndex]->deleteLater(true, false);
|
||||
delete customScreens[customScreenIndex];
|
||||
}
|
||||
|
||||
auto screen = factory->create(&g_model.screenData[customScreenIndex].layoutData);
|
||||
customScreens[customScreenIndex] = screen;
|
||||
|
||||
if (screen) {
|
||||
auto dst = g_model.screenData[customScreenIndex].LayoutId;
|
||||
auto src = factory->getId();
|
||||
strncpy(dst, src, sizeof(CustomScreenData::LayoutId));
|
||||
|
||||
return screen;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void disposeCustomScreen(unsigned idx)
|
||||
{
|
||||
// move custom screen data
|
||||
if (idx >= MAX_CUSTOM_SCREENS) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto dst = &g_model.screenData[idx];
|
||||
auto src = dst + 1;
|
||||
auto len = sizeof(CustomScreenData) * (MAX_CUSTOM_SCREENS - idx - 1);
|
||||
memmove(dst, src, len);
|
||||
|
||||
dst = &g_model.screenData[MAX_CUSTOM_SCREENS - 1];
|
||||
len = sizeof(CustomScreenData);
|
||||
memset(dst, 0, len);
|
||||
}
|
||||
|
||||
void Layout::decorate()
|
||||
{
|
||||
// Check if deco setting are still up-to-date
|
||||
|
||||
@@ -68,6 +68,13 @@ class Layout: public LayoutBase
|
||||
decorate();
|
||||
}
|
||||
|
||||
#if defined(DEBUG_WINDOWS)
|
||||
std::string getName() const override
|
||||
{
|
||||
return "Layout";
|
||||
}
|
||||
#endif
|
||||
|
||||
void create() override
|
||||
{
|
||||
setOptionValue(OPTION_TOPBAR, OPTION_VALUE_BOOL(true));
|
||||
@@ -197,4 +204,12 @@ void loadDefaultLayout();
|
||||
// intended for existing models
|
||||
void loadCustomScreens();
|
||||
|
||||
// delete all custom screens from memory
|
||||
void deleteCustomScreens();
|
||||
|
||||
Layout* createCustomScreen(const LayoutFactory* factory, unsigned customScreenIndex);
|
||||
|
||||
// Remove custom screen from the model
|
||||
void disposeCustomScreen(unsigned idx);
|
||||
|
||||
std::list<const LayoutFactory *> & getRegisteredLayouts();
|
||||
|
||||
@@ -36,7 +36,7 @@ void ScreenMenu::updateTabs()
|
||||
|
||||
for (int index = 0; index < MAX_CUSTOM_SCREENS; index++) {
|
||||
if (customScreens[index]) {
|
||||
auto tab = new ScreenSetupPage(this, customScreens[index], g_model.screenData[index]);
|
||||
auto tab = new ScreenSetupPage(this, getTabs(), index);
|
||||
std::string title(STR_MAIN_VIEW_X);
|
||||
title.back() = index + '1';
|
||||
tab->setTitle(title);
|
||||
@@ -45,7 +45,7 @@ void ScreenMenu::updateTabs()
|
||||
addTab(tab);
|
||||
}
|
||||
else {
|
||||
addTab(new ScreenAddPage(this, index));
|
||||
addTab(new ScreenAddPage(this, getTabs()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,72 +26,14 @@
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_MODEL)
|
||||
|
||||
ScreenUserInterfacePage::ScreenUserInterfacePage():
|
||||
PageTab(STR_USER_INTERFACE, ICON_THEME_SETUP)
|
||||
class LayoutChoice: public FormField
|
||||
{
|
||||
}
|
||||
|
||||
void ScreenUserInterfacePage::build(FormWindow * window)
|
||||
{
|
||||
FormGridLayout grid;
|
||||
|
||||
// Theme choice
|
||||
new StaticText(window, grid.getLabelSlot(), STR_THEME, 0, 0);
|
||||
// TODO: Theme picklist
|
||||
grid.nextLine();
|
||||
|
||||
// Theme options ?
|
||||
|
||||
// Top Bar
|
||||
new StaticText(window, grid.getLabelSlot(), STR_TOP_BAR, 0, 0);
|
||||
// TODO: enable settings topbar widgets
|
||||
grid.nextLine();
|
||||
}
|
||||
|
||||
ScreenAddPage::ScreenAddPage(ScreenMenu * menu, uint8_t pageIndex):
|
||||
PageTab(),
|
||||
menu(menu),
|
||||
pageIndex(pageIndex)
|
||||
{
|
||||
setTitle(STR_ADD_MAIN_VIEW);
|
||||
setIcon(ICON_THEME_ADD_VIEW);
|
||||
}
|
||||
|
||||
void ScreenAddPage::build(FormWindow * window)
|
||||
{
|
||||
rect_t buttonRect = {LCD_W / 2 - 100, (window->height() - 24) / 2, 200, 24};
|
||||
auto button = new TextButton(window, buttonRect, STR_ADD_MAIN_VIEW);
|
||||
button->setPressHandler([=]() -> uint8_t {
|
||||
|
||||
auto& screen = customScreens[pageIndex];
|
||||
auto& screenData = g_model.screenData[pageIndex];
|
||||
|
||||
const LayoutFactory * factory = getRegisteredLayouts().front();
|
||||
|
||||
screen = factory->create(&screenData.layoutData);
|
||||
strncpy(screenData.LayoutId, factory->getId(), sizeof(screenData.LayoutId));
|
||||
|
||||
auto tab = new ScreenSetupPage(menu, screen, screenData);
|
||||
std::string title(STR_MAIN_VIEW_X);
|
||||
title.back() = pageIndex + '0';
|
||||
tab->setTitle(title);
|
||||
tab->setIcon(ICON_THEME_VIEW1 + pageIndex);
|
||||
|
||||
menu->removeTab(pageIndex);
|
||||
menu->addTab(tab);
|
||||
menu->setCurrentTab(pageIndex);
|
||||
|
||||
if (pageIndex < MAX_CUSTOM_SCREENS - 1) {
|
||||
menu->addTab(new ScreenAddPage(menu, pageIndex + 1));
|
||||
}
|
||||
storageDirty(EE_MODEL);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
class LayoutChoice: public FormField {
|
||||
public:
|
||||
LayoutChoice(Window * parent, const rect_t & rect, std::function<const LayoutFactory *()> getValue, std::function<void(const LayoutFactory *)> setValue):
|
||||
|
||||
typedef std::function<const LayoutFactory *()> LayoutFactoryGetter;
|
||||
typedef std::function<void(const LayoutFactory *)> LayoutFactorySetter;
|
||||
|
||||
LayoutChoice(Window * parent, const rect_t & rect, LayoutFactoryGetter getValue, LayoutFactorySetter setValue):
|
||||
FormField(parent, {rect.x, rect.y, 59, 33}),
|
||||
getValue(std::move(getValue)),
|
||||
setValue(std::move(setValue))
|
||||
@@ -102,7 +44,9 @@ class LayoutChoice: public FormField {
|
||||
{
|
||||
FormField::paint(dc);
|
||||
auto layout = getValue();
|
||||
layout->drawThumb(dc, 4, 4, editMode ? FOCUS_COLOR : LINE_COLOR);
|
||||
if (layout) {
|
||||
layout->drawThumb(dc, 4, 4, editMode ? FOCUS_COLOR : LINE_COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(HARDWARE_KEYS)
|
||||
@@ -162,94 +106,91 @@ class LayoutChoice: public FormField {
|
||||
std::function<void(const LayoutFactory *)> setValue;
|
||||
};
|
||||
|
||||
ScreenSetupPage::ScreenSetupPage(ScreenMenu * menu, Layout*& screen, CustomScreenData& screenData):
|
||||
PageTab(),
|
||||
menu(menu),
|
||||
screen(screen),
|
||||
screenData(screenData)
|
||||
{
|
||||
}
|
||||
|
||||
class SetupWidgetsPageSlot: public Button
|
||||
{
|
||||
public:
|
||||
SetupWidgetsPageSlot(FormGroup * parent, const rect_t & rect, Layout* screen, uint8_t slotIndex):
|
||||
Button(parent, rect),
|
||||
screen(screen),
|
||||
slotIndex(slotIndex)
|
||||
Button(parent, rect)
|
||||
{
|
||||
widget = screen->getWidget(slotIndex);
|
||||
setPressHandler([=]() -> uint8_t {
|
||||
if (widget) {
|
||||
Menu * menu = new Menu(this);
|
||||
menu->addLine(TR_SELECT_WIDGET, [=]() {
|
||||
Menu * menu = new Menu(this);
|
||||
for (auto factory: getRegisteredWidgets()) {
|
||||
menu->addLine(factory->getName(), [=]() {
|
||||
if (widget) widget->deleteLater();
|
||||
widget = screen->createWidget(slotIndex, factory);
|
||||
});
|
||||
}
|
||||
});
|
||||
menu->addLine(TR_WIDGET_SETTINGS, [=]() {
|
||||
new WidgetSettings(this, widget);
|
||||
});
|
||||
//auto parent = (Window*)this;
|
||||
setPressHandler([parent, screen, slotIndex]() -> uint8_t {
|
||||
|
||||
Menu * menu = new Menu(parent);
|
||||
menu->addLine(TR_SELECT_WIDGET, [=]() {
|
||||
Menu * menu = new Menu(parent);
|
||||
for (auto factory: getRegisteredWidgets()) {
|
||||
menu->addLine(factory->getName(), [=]() {
|
||||
screen->createWidget(slotIndex, factory);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (screen->getWidget(slotIndex)) {
|
||||
menu->addLine(TR_WIDGET_SETTINGS, [=]() {
|
||||
auto widget = screen->getWidget(slotIndex);
|
||||
new WidgetSettings(parent, widget);
|
||||
});
|
||||
menu->addLine(STR_REMOVE_WIDGET, [=]() {
|
||||
widget->deleteLater();
|
||||
widget = nullptr;
|
||||
screen->removeWidget(slotIndex);
|
||||
});
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
Menu * menu = new Menu(this);
|
||||
for (auto factory: getRegisteredWidgets()) {
|
||||
menu->addLine(factory->getName(), [=]() {
|
||||
if (widget) widget->deleteLater();
|
||||
widget = screen->createWidget(slotIndex, factory);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
// }
|
||||
// else {
|
||||
// Menu * menu = new Menu(this);
|
||||
// for (auto factory: getRegisteredWidgets()) {
|
||||
// menu->addLine(factory->getName(), [=]() {
|
||||
// if (widget) widget->deleteLater();
|
||||
// widget = screen->createWidget(slotIndex, factory);
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// return 0;
|
||||
});
|
||||
}
|
||||
|
||||
void paint(BitmapBuffer * dc) override
|
||||
{
|
||||
if (hasFocus()) {
|
||||
dc->drawSolidRect(0, 0, width(), height(), 1, DEFAULT_COLOR);
|
||||
}
|
||||
else {
|
||||
dc->drawRect(0, 0, width(), height(), 1, DOTTED, DEFAULT_COLOR);
|
||||
dc->drawRect(0, 0, width()-2, height()-2, 2, DOTTED, CHECKBOX_COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
Layout * screen;
|
||||
uint8_t slotIndex;
|
||||
Widget * widget = nullptr;
|
||||
};
|
||||
|
||||
class SetupWidgetsPage: public FormWindow
|
||||
{
|
||||
public:
|
||||
SetupWidgetsPage(Layout * screen):
|
||||
FormWindow(MainWindow::instance(), {0, 0, LCD_W, LCD_H}, OPAQUE | FORM_FORWARD_FOCUS),
|
||||
screen(screen),
|
||||
oldParent(screen->getParent())
|
||||
SetupWidgetsPage(ScreenMenu* menu, uint8_t customScreenIdx):
|
||||
FormWindow(ViewMain::instance(), {0, 0, LCD_W, LCD_H}, /*OPAQUE |*/ FORM_FORWARD_FOCUS),
|
||||
menu(menu),
|
||||
customScreenIdx(customScreenIdx)
|
||||
{
|
||||
Layer::push(this);
|
||||
clearFocus();
|
||||
|
||||
// attach this custom screen here so we can display it
|
||||
screen->attach(this);
|
||||
|
||||
// attach this custom screen here so we can display it
|
||||
auto screen = customScreens[customScreenIdx];
|
||||
if (screen) {
|
||||
screen->attach(this);
|
||||
setRect(screen->getRect());
|
||||
}
|
||||
|
||||
ViewMain::instance()->bringToTop();
|
||||
|
||||
for (unsigned i = 0; i < screen->getZonesCount(); i++) {
|
||||
auto rect = screen->getZone(i);
|
||||
new SetupWidgetsPageSlot(this, {rect.x - 1, rect.y - 1, rect.w + 2, rect.h + 2}, screen, i);
|
||||
auto widget = new SetupWidgetsPageSlot(this, rect, customScreens[customScreenIdx], i);
|
||||
if (i == 0) widget->setFocus();
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(DEBUG_WINDOWS)
|
||||
std::string getName() const override
|
||||
{
|
||||
return "SetupWidgetPage(idx=" + std::to_string(customScreenIdx) + ")";
|
||||
}
|
||||
#endif
|
||||
|
||||
void deleteLater(bool detach = true, bool trash = true) override
|
||||
{
|
||||
Layer::pop(this);
|
||||
@@ -257,12 +198,14 @@ class SetupWidgetsPage: public FormWindow
|
||||
#if defined(HARDWARE_TOUCH)
|
||||
Keyboard::hide();
|
||||
#endif
|
||||
if (oldParent) {
|
||||
// give it back to its old parent before it gets deleted
|
||||
screen->attach(oldParent);
|
||||
auto screen = customScreens[customScreenIdx];
|
||||
if (screen) {
|
||||
screen->attach(ViewMain::instance());
|
||||
}
|
||||
|
||||
FormWindow::deleteLater(detach, trash);
|
||||
|
||||
// restore screen setting tab on top
|
||||
menu->bringToTop();
|
||||
}
|
||||
|
||||
#if defined(HARDWARE_KEYS)
|
||||
@@ -279,16 +222,100 @@ class SetupWidgetsPage: public FormWindow
|
||||
#endif
|
||||
|
||||
protected:
|
||||
Layout* screen;
|
||||
Window* oldParent;
|
||||
|
||||
void paint(BitmapBuffer * dc) override
|
||||
{
|
||||
dc->clear(DEFAULT_BGCOLOR);
|
||||
}
|
||||
ScreenMenu* menu;
|
||||
uint8_t customScreenIdx;
|
||||
|
||||
// void paint(BitmapBuffer * dc) override
|
||||
// {
|
||||
// //ViewMain::instance()->fullPaint(dc);
|
||||
// //dc->clear(DEFAULT_BGCOLOR);
|
||||
// }
|
||||
};
|
||||
|
||||
ScreenUserInterfacePage::ScreenUserInterfacePage():
|
||||
PageTab(STR_USER_INTERFACE, ICON_THEME_SETUP)
|
||||
{
|
||||
}
|
||||
|
||||
void ScreenUserInterfacePage::build(FormWindow * window)
|
||||
{
|
||||
FormGridLayout grid;
|
||||
|
||||
// Theme choice
|
||||
new StaticText(window, grid.getLabelSlot(), STR_THEME, 0, 0);
|
||||
// TODO: Theme picklist
|
||||
grid.nextLine();
|
||||
|
||||
// Theme options ?
|
||||
|
||||
// Top Bar
|
||||
new StaticText(window, grid.getLabelSlot(), STR_TOP_BAR, 0, 0);
|
||||
// TODO: enable settings topbar widgets
|
||||
grid.nextLine();
|
||||
}
|
||||
|
||||
ScreenAddPage::ScreenAddPage(ScreenMenu * menu, uint8_t pageIndex):
|
||||
PageTab(),
|
||||
menu(menu),
|
||||
pageIndex(pageIndex)
|
||||
{
|
||||
setTitle(STR_ADD_MAIN_VIEW);
|
||||
setIcon(ICON_THEME_ADD_VIEW);
|
||||
}
|
||||
|
||||
extern const LayoutFactory * defaultLayout;
|
||||
|
||||
void ScreenAddPage::build(FormWindow * window)
|
||||
{
|
||||
rect_t buttonRect = {LCD_W / 2 - 100, (window->height() - 24) / 2, 200, 24};
|
||||
auto button = new TextButton(window, buttonRect, STR_ADD_MAIN_VIEW);
|
||||
|
||||
auto pageIndex = this->pageIndex;
|
||||
auto menu = this->menu;
|
||||
|
||||
button->setPressHandler([menu,pageIndex]() -> uint8_t {
|
||||
|
||||
auto newPageIdx = menu->getTabs();
|
||||
auto newIdx = newPageIdx - 2;
|
||||
|
||||
auto& screen = customScreens[newIdx];
|
||||
auto& screenData = g_model.screenData[newIdx];
|
||||
|
||||
const LayoutFactory * factory = defaultLayout;
|
||||
screen = factory->create(&screenData.layoutData);
|
||||
strncpy(screenData.LayoutId, factory->getId(), sizeof(screenData.LayoutId));
|
||||
|
||||
auto tab = new ScreenSetupPage(menu, newPageIdx, newIdx);
|
||||
std::string title(STR_MAIN_VIEW_X);
|
||||
title.back() = newIdx + '1';
|
||||
tab->setTitle(title);
|
||||
tab->setIcon(ICON_THEME_VIEW1 + newIdx);
|
||||
|
||||
// remove current tab first
|
||||
menu->setCurrentTab(0);
|
||||
menu->removeTab(pageIndex);
|
||||
|
||||
// add the new one
|
||||
menu->addTab(tab);
|
||||
menu->setCurrentTab(newPageIdx);
|
||||
|
||||
if (menu->getTabs() < MAX_CUSTOM_SCREENS) {
|
||||
menu->addTab(new ScreenAddPage(menu, menu->getTabs()));
|
||||
}
|
||||
|
||||
storageDirty(EE_MODEL);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
ScreenSetupPage::ScreenSetupPage(ScreenMenu * menu, unsigned pageIndex, unsigned customScreenIndex):
|
||||
PageTab(),
|
||||
menu(menu),
|
||||
pageIndex(pageIndex),
|
||||
customScreenIndex(customScreenIndex)
|
||||
{
|
||||
}
|
||||
|
||||
void ScreenSetupPage::build(FormWindow * window)
|
||||
{
|
||||
FormGridLayout grid;
|
||||
@@ -296,46 +323,95 @@ void ScreenSetupPage::build(FormWindow * window)
|
||||
|
||||
// Layout choice...
|
||||
new StaticText(window, grid.getLabelSlot(false), STR_LAYOUT);
|
||||
|
||||
auto layoutSlot = grid.getFieldSlot();
|
||||
layoutSlot.h = 2 * PAGE_LINE_HEIGHT - 1;
|
||||
layoutChoice = new LayoutChoice(window, layoutSlot, GET_VALUE(screen->getFactory()), [=](const LayoutFactory *factory) {
|
||||
delete screen;
|
||||
screen = factory->create(&screenData.layoutData);
|
||||
strncpy(screenData.LayoutId, factory->getId(), sizeof(CustomScreenData::LayoutId));
|
||||
SET_DIRTY();
|
||||
updateLayoutOptions();
|
||||
});
|
||||
|
||||
auto idx = customScreenIndex;
|
||||
LayoutChoice::LayoutFactoryGetter getFactory = GET_VALUE(customScreens[idx]->getFactory());
|
||||
LayoutChoice::LayoutFactorySetter setLayout = [idx](const LayoutFactory *factory) {
|
||||
createCustomScreen(factory, idx);
|
||||
SET_DIRTY();
|
||||
};
|
||||
|
||||
auto layoutChoice = new LayoutChoice(window, layoutSlot, getFactory, setLayout);
|
||||
grid.nextLine(layoutChoice->height());
|
||||
TRACE("layoutChoice = %p", layoutChoice);
|
||||
|
||||
// Setup widgets button...
|
||||
setupWidgetsButton = new TextButton(window, grid.getFieldSlot(), STR_SETUP_WIDGETS);
|
||||
setupWidgetsButton->setPressHandler([=]() -> uint8_t {
|
||||
new SetupWidgetsPage(screen);
|
||||
auto setupWidgetsButton = new TextButton(window, grid.getFieldSlot(), STR_SETUP_WIDGETS);
|
||||
TRACE("setupWidgetsButton = %p", setupWidgetsButton);
|
||||
|
||||
auto menu = this->menu;
|
||||
setupWidgetsButton->setPressHandler([idx,menu]() -> uint8_t {
|
||||
new SetupWidgetsPage(menu, idx);
|
||||
return 0;
|
||||
});
|
||||
grid.nextLine();
|
||||
|
||||
// Dynamic options window...
|
||||
optionsWindow = new FormGroup(window, {0, grid.getWindowHeight(), LCD_W, 0}, FORWARD_SCROLL | FORM_FORWARD_FOCUS);
|
||||
grid.addWindow(optionsWindow);
|
||||
updateLayoutOptions();
|
||||
// rect_t r = {0, grid.getWindowHeight(), LCD_W, 0};
|
||||
// auto optionsWindow = new FormGroup(window, r, FORWARD_SCROLL | FORM_FORWARD_FOCUS);
|
||||
// grid.addWindow(optionsWindow);
|
||||
// updateLayoutOptions();
|
||||
|
||||
// Prevent removing the last page
|
||||
if (customScreens[1] != nullptr) {
|
||||
auto button = new TextButton(window, grid.getFieldSlot(), STR_REMOVE_SCREEN);
|
||||
auto menu = this->menu;
|
||||
button->setPressHandler([menu,idx]() -> uint8_t {
|
||||
|
||||
// Set the current tab to "User interface" to trigger body clearing
|
||||
menu->setCurrentTab(0);
|
||||
|
||||
// Remove this screen from the model
|
||||
disposeCustomScreen(idx);
|
||||
|
||||
// Delete all custom screens
|
||||
deleteCustomScreens();
|
||||
|
||||
// ... and reload
|
||||
loadCustomScreens();
|
||||
menu->updateTabs();
|
||||
|
||||
// Let's try to stay on the same page
|
||||
// (first tab is "User interface")
|
||||
auto pageIdx = idx + 1;
|
||||
|
||||
// Subtract one more as the last one is "New main screen"
|
||||
if (pageIdx > menu->getTabs() - 2) {
|
||||
pageIdx = menu->getTabs() - 2;
|
||||
}
|
||||
menu->setCurrentTab(pageIdx);
|
||||
|
||||
// save the changes
|
||||
storageDirty(EE_MODEL);
|
||||
return 0;
|
||||
});
|
||||
}
|
||||
|
||||
// optionsWindow->adjustHeight();
|
||||
// optionsWindow->getParent()->adjustInnerHeight();
|
||||
}
|
||||
|
||||
void ScreenSetupPage::updateLayoutOptions()
|
||||
{
|
||||
#if 0
|
||||
FormGridLayout grid;
|
||||
optionsWindow->clear();
|
||||
|
||||
// Layout options...
|
||||
int index = 0;
|
||||
for (auto * option = screen->getFactory()->getOptions(); option->name; option++, index++) {
|
||||
ZoneOptionValue * value = screen->getOptionValue(index);
|
||||
auto factory = customScreen[customScreenIndex]->getFactory();
|
||||
if (factory) {
|
||||
for (auto * option = factory->getOptions(); option->name; option++, index++) {
|
||||
ZoneOptionValue * value = customScreens[customScreenIndex]->getOptionValue(index);
|
||||
|
||||
// Option label
|
||||
new StaticText(optionsWindow, grid.getLabelSlot(false), option->name);
|
||||
// Option label
|
||||
new StaticText(optionsWindow, grid.getLabelSlot(false), option->name);
|
||||
|
||||
// Option value
|
||||
switch (option->type) {
|
||||
// Option value
|
||||
switch (option->type) {
|
||||
case ZoneOption::Bool:
|
||||
new CheckBox(optionsWindow, grid.getFieldSlot(), GET_SET_DEFAULT(value->boolValue));
|
||||
break;
|
||||
@@ -346,25 +422,10 @@ void ScreenSetupPage::updateLayoutOptions()
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
grid.nextLine();
|
||||
}
|
||||
grid.nextLine();
|
||||
}
|
||||
|
||||
//if (pageIndex > 0 || customScreens[1]) {
|
||||
auto button = new TextButton(optionsWindow, grid.getFieldSlot(), STR_REMOVE_SCREEN);
|
||||
button->setPressHandler([=]() -> uint8_t {
|
||||
// if (pageIndex < MAX_CUSTOM_SCREENS - 1) {
|
||||
// memmove(&g_model.screenData[pageIndex], &g_model.screenData[pageIndex + 1], sizeof(CustomScreenData) * (MAX_CUSTOM_SCREENS - pageIndex - 1));
|
||||
// }
|
||||
// memset(&g_model.screenData[MAX_CUSTOM_SCREENS - 1], 0, sizeof(CustomScreenData));
|
||||
memset(&screenData, 0, sizeof(CustomScreenData));
|
||||
loadCustomScreens();
|
||||
menu->updateTabs();
|
||||
storageDirty(EE_MODEL);
|
||||
return 0;
|
||||
});
|
||||
//}
|
||||
|
||||
optionsWindow->adjustHeight();
|
||||
optionsWindow->getParent()->adjustInnerHeight();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -44,17 +44,19 @@ class ScreenAddPage: public PageTab {
|
||||
|
||||
class ScreenSetupPage: public PageTab {
|
||||
public:
|
||||
ScreenSetupPage(ScreenMenu * menu, Layout*& screen, CustomScreenData& screenData);
|
||||
ScreenSetupPage(ScreenMenu * menu, unsigned pageIndex, unsigned customScreenIndex);
|
||||
|
||||
void build(FormWindow * window) override;
|
||||
|
||||
protected:
|
||||
ScreenMenu * menu;
|
||||
Layout *& screen;
|
||||
CustomScreenData& screenData;
|
||||
FormGroup * optionsWindow = nullptr;
|
||||
TextButton * setupWidgetsButton = nullptr;
|
||||
FormField * layoutChoice = nullptr;
|
||||
unsigned pageIndex;
|
||||
unsigned customScreenIndex;
|
||||
|
||||
// FormGroup * optionsWindow = nullptr;
|
||||
// TextButton * setupWidgetsButton = nullptr;
|
||||
// FormField * layoutChoice = nullptr;
|
||||
|
||||
void updateLayoutOptions();
|
||||
//void disposeCustomScreen();
|
||||
};
|
||||
|
||||
@@ -94,6 +94,19 @@ void TabsGroup::addTab(PageTab * page)
|
||||
setCurrentTab(0);
|
||||
}
|
||||
header.carousel.updateInnerWidth();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
int TabsGroup::removeTab(PageTab * page)
|
||||
{
|
||||
auto tabIter = std::find(tabs.begin(), tabs.end(), page);
|
||||
if (tabIter != tabs.end()) {
|
||||
auto idx = tabIter - tabs.begin();
|
||||
removeTab(idx);
|
||||
return idx;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void TabsGroup::removeTab(unsigned index)
|
||||
@@ -103,6 +116,7 @@ void TabsGroup::removeTab(unsigned index)
|
||||
}
|
||||
tabs.erase(tabs.begin() + index);
|
||||
header.carousel.updateInnerWidth();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
void TabsGroup::removeAllTabs()
|
||||
@@ -132,6 +146,11 @@ void TabsGroup::setVisibleTab(PageTab * tab)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: add a mechanism to trigger a rebuild of a PageTab
|
||||
// -> rebuild():
|
||||
// - as in setVisibleTab() (clear & build)
|
||||
// - but without changing tab
|
||||
|
||||
void TabsGroup::checkEvents()
|
||||
{
|
||||
Window::checkEvents();
|
||||
|
||||
@@ -193,8 +193,17 @@ class TabsGroup: public Window
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned getTabs() const
|
||||
{
|
||||
return tabs.size();
|
||||
}
|
||||
|
||||
void addTab(PageTab * page);
|
||||
|
||||
// Return the index of the found tab
|
||||
// or -1 if the tab could not be found
|
||||
int removeTab(PageTab * page);
|
||||
|
||||
void removeTab(unsigned index);
|
||||
|
||||
void removeAllTabs();
|
||||
@@ -206,7 +215,7 @@ class TabsGroup: public Window
|
||||
setVisibleTab(tabs[index]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void checkEvents() override;
|
||||
|
||||
#if defined(HARDWARE_KEYS)
|
||||
|
||||
@@ -34,6 +34,13 @@ class TopBar: public WidgetsContainer<MAX_TOPBAR_ZONES, MAX_TOPBAR_OPTIONS>
|
||||
public:
|
||||
explicit TopBar(Window * parent);
|
||||
|
||||
#if defined(DEBUG_WINDOWS)
|
||||
std::string getName() const override
|
||||
{
|
||||
return "TopBar";
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned int getZonesCount() const override;
|
||||
|
||||
rect_t getZone(unsigned int index) const override;
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <memory>
|
||||
|
||||
class TopBar;
|
||||
class SetupWidgetsPage;
|
||||
|
||||
class ViewMain: public FormWindow
|
||||
{
|
||||
@@ -88,6 +89,8 @@ class ViewMain: public FormWindow
|
||||
Window* sliders[SLIDERS_MAX];
|
||||
Window* trims[TRIMS_MAX];
|
||||
Window* flightMode;
|
||||
|
||||
friend class SetupWidgetsPage;
|
||||
|
||||
#if defined(HARDWARE_KEYS)
|
||||
void onEvent(event_t event) override;
|
||||
|
||||
@@ -58,17 +58,38 @@ class WidgetsContainer: public FormGroup, public WidgetsContainerInterface
|
||||
|
||||
Widget * createWidget(unsigned int index, const WidgetFactory * factory) override
|
||||
{
|
||||
if (index >= N)
|
||||
return nullptr;
|
||||
|
||||
// remove old one if existing
|
||||
removeWidget(index);
|
||||
|
||||
Widget * widget = nullptr;
|
||||
memset(persistentData->zones[index].widgetName, 0, sizeof(persistentData->zones[index].widgetName));
|
||||
if (factory) {
|
||||
strncpy(persistentData->zones[index].widgetName, factory->getName(), sizeof(persistentData->zones[index].widgetName));
|
||||
strncpy(persistentData->zones[index].widgetName, factory->getName(), sizeof(ZonePersistentData::widgetName));
|
||||
widget = factory->create(this, getZone(index), &persistentData->zones[index].widgetData);
|
||||
}
|
||||
widgets[index] = widget;
|
||||
|
||||
if (widget)
|
||||
widget->attach(this);
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
||||
void removeWidget(unsigned int index)
|
||||
{
|
||||
if (index >= N)
|
||||
return;
|
||||
|
||||
if (widgets[index])
|
||||
widgets[index]->deleteLater();
|
||||
|
||||
widgets[index] = nullptr;
|
||||
memset(persistentData->zones[index].widgetName, 0, sizeof(ZonePersistentData::widgetName));
|
||||
memset(&persistentData->zones[index].widgetData, 0, sizeof(Widget::PersistentData));
|
||||
}
|
||||
|
||||
Widget * getWidget(unsigned int index) override
|
||||
{
|
||||
if (index < N)
|
||||
|
||||
Reference in New Issue
Block a user