From dccbd988ac8d4f7bb2afae519734d58531627353 Mon Sep 17 00:00:00 2001 From: Raphael Coeffic Date: Fri, 20 May 2022 16:39:26 +0200 Subject: [PATCH] New tools page --- radio/src/gui/colorlcd/radio_tools.cpp | 363 ++++++------------ .../src/gui/colorlcd/themes/etx_lv_theme.cpp | 2 +- 2 files changed, 112 insertions(+), 253 deletions(-) diff --git a/radio/src/gui/colorlcd/radio_tools.cpp b/radio/src/gui/colorlcd/radio_tools.cpp index 35c77e664..8b9851c77 100644 --- a/radio/src/gui/colorlcd/radio_tools.cpp +++ b/radio/src/gui/colorlcd/radio_tools.cpp @@ -72,118 +72,41 @@ void RadioToolsPage::checkEvents() PageTab::checkEvents(); } -struct LuaScript +typedef void (*ToolExec)(Window* parent, const std::string& path); + +struct ToolEntry { - std::string path; std::string label; - bool operator < (const LuaScript &a) { return label < a.label; } + std::string path; + ToolExec exec; }; -inline bool LuaScript_compare_nocase(LuaScript first, LuaScript second) +inline bool tool_compare_nocase(const ToolEntry& first, const ToolEntry& second) { return strcasecmp(first.label.c_str(), second.label.c_str()) < 0; } -class FormGridLayoutEx : public FormGridLayout -{ - public: - using FormGridLayout::FormGridLayout; - - void setLineHeight(uint8_t lineHeight) - { - _lineHeight = lineHeight; - } - - rect_t getFieldSlot(uint8_t count = 1, uint8_t index = 0) const - { - auto rect = FormGridLayout::getFieldSlot(count, index); - rect.h = _lineHeight; - return rect; - } - - rect_t getLabelSlot(bool indent = false) const - { - auto rect = FormGridLayout::getLabelSlot(indent); - rect.h = _lineHeight; - return rect; - } - - void nextLine(coord_t height=PAGE_LINE_HEIGHT) - { - if (height == PAGE_LINE_HEIGHT) - height = _lineHeight; - spacer(height + PAGE_LINE_SPACING); - } - - protected: - uint8_t _lineHeight = PAGE_LINE_HEIGHT; -}; - #if defined(LUA) -void buildLuaUi(std::vector luaScripts, FormWindow *window, FormGridLayoutEx &grid) +static void run_lua_tool(Window* parent, const std::string& path) { - for (auto luaScript : luaScripts) { - auto txt = - new StaticText(window, grid.getLabelSlot(), "lua", BUTTON_BACKGROUND, - COLOR_THEME_PRIMARY1 | CENTERED | VCENTERED); - auto b = new TextButton( - window, grid.getFieldSlot(1), luaScript.label, - [window, luaScript]() -> uint8_t { + char toolPath[FF_MAX_LFN + 1]; + strncpy(toolPath, path.c_str(), sizeof(toolPath)-1); + *((char *)getBasename(toolPath)-1) = '\0'; + f_chdir(toolPath); - char toolPath[FF_MAX_LFN + 1]; - strncpy(toolPath, luaScript.path.c_str(), sizeof(toolPath)-1); - *((char *)getBasename(toolPath)-1) = '\0'; - f_chdir(toolPath); - - luaExec(luaScript.path.c_str()); - auto lua_win = StandaloneLuaWindow::instance(); - lua_win->attach(window); - - return 0; - }, - OPAQUE); - b->setBgColorHandler([=]() { - return COLOR_THEME_PRIMARY2; - }); - b->setFocusHandler([=](bool focus) { - if (focus) { - txt->setBackgroundColor(COLOR_THEME_FOCUS); - txt->setTextFlags(COLOR_THEME_PRIMARY2 | CENTERED | VCENTERED); - } else { - txt->setBackgroundColor(COLOR_THEME_SECONDARY2); - txt->setTextFlags(COLOR_THEME_PRIMARY1 | CENTERED | VCENTERED); - } - txt->invalidate(); - }); - grid.nextLine(); - } + luaExec(path.c_str()); + auto lua_win = StandaloneLuaWindow::instance(); + lua_win->attach(parent); } -#endif - -void RadioToolsPage::rebuild(FormWindow * window) -{ - FormGridLayoutEx grid; - grid.setLineHeight(PAGE_LINE_HEIGHT + 10); - grid.spacer(PAGE_PADDING); - grid.setLabelWidth(100); - - window->clear(); - Window::clearFocus(); // LUA scripts in TOOLS -#if defined(LUA) +static void scanLuaTools(std::list& scripts) +{ FILINFO fno; DIR dir; -#if defined(CROSSFIRE) -// if (isFileAvailable(SCRIPTS_TOOLS_PATH "/CROSSFIRE/crossfire.lua")) -// addRadioScriptTool(index++, SCRIPTS_TOOLS_PATH "/CROSSFIRE/crossfire.lua"); -#endif - FRESULT res = f_opendir(&dir, SCRIPTS_TOOLS_PATH); if (res == FR_OK) { - std::vector luaScripts; // gather them all and then create UI after sort - for (;;) { TCHAR path[FF_MAX_LFN+1] = SCRIPTS_TOOLS_PATH "/"; res = f_readdir(&dir, &fno); /* Read a directory item */ @@ -205,187 +128,123 @@ void RadioToolsPage::rebuild(FormWindow * window) label = getBasename(path); } - luaScripts.emplace_back(LuaScript{ path, label }); + scripts.emplace_back(ToolEntry{ label, path, run_lua_tool }); } } - - std::sort(luaScripts.begin(), luaScripts.end(), LuaScript_compare_nocase); - buildLuaUi(luaScripts, window, grid); } +} +#endif + +#if defined(PXX2) || defined(MULTIMODULE) + +#if defined(HARDWARE_INTERNAL_MODULE) +static void run_spektrum_int(Window* parent, const std::string&) +{ + new RadioSpectrumAnalyser(INTERNAL_MODULE); +} #endif +static void run_spektrum_ext(Window* parent, const std::string&) +{ + new RadioSpectrumAnalyser(EXTERNAL_MODULE); +} +#endif // defined(PXX2) || defined(MULTIMODULE) + #if defined(INTERNAL_MODULE_PXX2) +static void run_pxx2_power(Window* parent, const std::string&) +{ +#if 0 // disabled Power Meter: not yet implemented + new RadioPowerMeter(INTERNAL_MODULE); +#endif +} +#endif + +#if defined(GHOST) +static void run_ghost_config(Window* parent, const std::string&) +{ + new RadioGhostModuleConfig(EXTERNAL_MODULE); +} +#endif + +struct ToolButton : public TextButton { + ToolButton(Window* parent, const ToolEntry& tool) : + TextButton(parent, rect_t{}, tool.label, [=]() { + tool.exec(parent, tool.path); + return 0; + }) + { + setWidth(LV_DPI_DEF); + setHeight(LV_DPI_DEF / 2); + + lv_obj_set_width(label, lv_pct(100)); + lv_obj_set_style_text_align(label, LV_TEXT_ALIGN_CENTER, 0); + lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP); + } +}; + +void RadioToolsPage::rebuild(FormWindow * window) +{ + window->clear(); + Window::clearFocus(); + + std::list tools; + +#if defined(PXX2) + auto hwSettings = &reusableBuffer.hardwareAndSettings; + +#if defined(INTERNAL_MODULE_PXX2) + auto intHwSettings = &hwSettings->modules[INTERNAL_MODULE]; // PXX2 modules tools if (isPXX2ModuleOptionAvailable( - reusableBuffer.hardwareAndSettings.modules[INTERNAL_MODULE] - .information.modelID, + intHwSettings->information.modelID, MODULE_OPTION_SPECTRUM_ANALYSER)) { - auto txt = - new StaticText(window, grid.getLabelSlot(), "access", BUTTON_BACKGROUND, - COLOR_THEME_PRIMARY1 | CENTERED | VCENTERED); - auto b = new TextButton( - window, grid.getFieldSlot(1), STR_SPECTRUM_ANALYSER_INT, - [=]() -> uint8_t { - new RadioSpectrumAnalyser(INTERNAL_MODULE); - return 0; - }, - OPAQUE); - b->setBgColorHandler([=]() -> LcdFlags { return COLOR_THEME_PRIMARY2; }); - b->setFocusHandler([=](bool focus) { - if (focus) { - txt->setBackgroundColor(COLOR_THEME_FOCUS); - txt->setTextFlags(COLOR_THEME_PRIMARY2 | CENTERED | VCENTERED); - } else { - txt->setBackgroundColor(COLOR_THEME_SECONDARY2); - txt->setTextFlags(COLOR_THEME_PRIMARY1 | CENTERED | VCENTERED); - } - txt->invalidate(); - }); - grid.nextLine(); + tools.emplace_back(ToolEntry{ STR_SPECTRUM_ANALYSER_INT, {}, run_spektrum_int }); } + if (isPXX2ModuleOptionAvailable( + intHwSettings->information.modelID, + MODULE_OPTION_POWER_METER)) { + tools.emplace_back(ToolEntry{ STR_POWER_METER_INT, {}, run_pxx2_power }); + } +#endif + auto extHwSettings = &hwSettings->modules[EXTERNAL_MODULE]; if (isPXX2ModuleOptionAvailable( - reusableBuffer.hardwareAndSettings.modules[INTERNAL_MODULE] - .information.modelID, - MODULE_OPTION_POWER_METER)) { - auto txt = - new StaticText(window, grid.getLabelSlot(), "access", BUTTON_BACKGROUND, - COLOR_THEME_PRIMARY1 | CENTERED | VCENTERED); - auto b = new TextButton( - window, grid.getFieldSlot(1), STR_POWER_METER_INT, - [=]() -> uint8_t { - // new RadioPowerMeter(INTERNAL_MODULE); - return 0; - }, - OPAQUE); - b->setBgColorHandler([=]() -> LcdFlags { return COLOR_THEME_PRIMARY2; }); - b->setFocusHandler([=](bool focus) { - if (focus) { - txt->setBackgroundColor(COLOR_THEME_FOCUS); - txt->setTextFlags(COLOR_THEME_PRIMARY2 | CENTERED | VCENTERED); - } else { - txt->setBackgroundColor(COLOR_THEME_SECONDARY2); - txt->setTextFlags(COLOR_THEME_PRIMARY1 | CENTERED | VCENTERED); - } - txt->invalidate(); - }); - grid.nextLine(); + extHwSettings->information.modelID, + MODULE_OPTION_SPECTRUM_ANALYSER)) { + tools.emplace_back(ToolEntry{ STR_SPECTRUM_ANALYSER_EXT, {}, run_spektrum_ext }); } -#endif -#if defined(HARDWARE_INTERNAL_MODULE) - if (g_eeGeneral.internalModule == MODULE_TYPE_MULTIMODULE) - { - auto txt = - new StaticText(window, grid.getLabelSlot(), "multi", BUTTON_BACKGROUND, - COLOR_THEME_PRIMARY1 | CENTERED | VCENTERED); - auto b = new TextButton( - window, grid.getFieldSlot(1), STR_SPECTRUM_ANALYSER_INT, - [=]() -> uint8_t { - new RadioSpectrumAnalyser(INTERNAL_MODULE); - return 0; - }, - OPAQUE); - b->setBgColorHandler([=]() -> LcdFlags { return COLOR_THEME_PRIMARY2; }); - b->setFocusHandler([=](bool focus) { - if (focus) { - txt->setBackgroundColor(COLOR_THEME_FOCUS); - txt->setTextFlags(COLOR_THEME_PRIMARY2 | CENTERED | VCENTERED); - } else { - txt->setBackgroundColor(COLOR_THEME_SECONDARY2); - txt->setTextFlags(COLOR_THEME_PRIMARY1 | CENTERED | VCENTERED); - } - txt->invalidate(); - }); - grid.nextLine(); +#endif // defined(PXX2) + +#if defined(HARDWARE_INTERNAL_MODULE) && defined(MULTIMODULE) + if (g_eeGeneral.internalModule == MODULE_TYPE_MULTIMODULE) { + tools.emplace_back(ToolEntry{ STR_SPECTRUM_ANALYSER_INT, {}, run_spektrum_int }); } #endif + #if defined(PXX2)|| defined(MULTIMODULE) - if (isPXX2ModuleOptionAvailable( - reusableBuffer.hardwareAndSettings.modules[EXTERNAL_MODULE] - .information.modelID, - MODULE_OPTION_SPECTRUM_ANALYSER) || - isModuleMultimodule(EXTERNAL_MODULE)) { - auto txt = new StaticText( - window, grid.getLabelSlot(), - isModuleMultimodule(EXTERNAL_MODULE) ? "multi" : "access", - BUTTON_BACKGROUND, COLOR_THEME_PRIMARY1 | CENTERED | VCENTERED); - auto b = new TextButton( - window, grid.getFieldSlot(1), STR_SPECTRUM_ANALYSER_EXT, - [=]() -> uint8_t { - new RadioSpectrumAnalyser(EXTERNAL_MODULE); - return 0; - }, - OPAQUE); - b->setBgColorHandler([=]() -> LcdFlags { return COLOR_THEME_PRIMARY2; }); - b->setFocusHandler([=](bool focus) { - if (focus) { - txt->setBackgroundColor(COLOR_THEME_FOCUS); - txt->setTextFlags(COLOR_THEME_PRIMARY2 | CENTERED | VCENTERED); - } else { - txt->setBackgroundColor(COLOR_THEME_SECONDARY2); - txt->setTextFlags(COLOR_THEME_PRIMARY1 | CENTERED | VCENTERED); - } - txt->invalidate(); - }); - grid.nextLine(); + if (isModuleMultimodule(EXTERNAL_MODULE)) { + tools.emplace_back(ToolEntry{ STR_SPECTRUM_ANALYSER_EXT, {}, run_spektrum_ext }); } #endif -#if defined(PXX2) -#if 0 // disabled Power Meter: not yet implemented - if (isPXX2ModuleOptionAvailable( - reusableBuffer.hardwareAndSettings.modules[EXTERNAL_MODULE] - .information.modelID, - MODULE_OPTION_POWER_METER)) { - auto txt = - new StaticText(window, grid.getLabelSlot(), "access", BUTTON_BACKGROUND, - COLOR_THEME_PRIMARY1 | CENTERED | VCENTERED); - auto b = new TextButton( - window, grid.getFieldSlot(1), STR_POWER_METER_EXT, - [=]() -> uint8_t { - // new RadioPowerMeter(EXTERNAL_MODULE); - return 0; - }, - OPAQUE); - b->setBgColorHandler([=]() -> LcdFlags { return COLOR_THEME_PRIMARY2; }); - b->setFocusHandler([=](bool focus) { - if (focus) { - txt->setBackgroundColor(COLOR_THEME_FOCUS); - txt->setTextFlags(COLOR_THEME_PRIMARY2 | CENTERED | VCENTERED); - } else { - txt->setBackgroundColor(COLOR_THEME_SECONDARY2); - txt->setTextFlags(COLOR_THEME_PRIMARY1 | CENTERED | VCENTERED); - } - txt->invalidate(); - }); - grid.nextLine(); - } -#endif -#endif #if defined(GHOST) if (isModuleGhost(EXTERNAL_MODULE)) { - auto txt = new StaticText(window, grid.getLabelSlot(), "ghost", - BUTTON_BACKGROUND, CENTERED | VCENTERED); - auto b = new TextButton( - window, grid.getFieldSlot(1), "Ghost module config", - [=]() -> uint8_t { - new RadioGhostModuleConfig(EXTERNAL_MODULE); - return 0; - }, - OPAQUE); - b->setBgColorHandler([=]() -> LcdFlags { return COLOR_THEME_PRIMARY2; }); - b->setFocusHandler([=](bool focus) { - if (focus) { - txt->setBackgroundColor(COLOR_THEME_FOCUS); - txt->setTextFlags(COLOR_THEME_PRIMARY2 | CENTERED | VCENTERED); - } else { - txt->setBackgroundColor(COLOR_THEME_SECONDARY2); - txt->setTextFlags(COLOR_THEME_PRIMARY1 | CENTERED | VCENTERED); - } - txt->invalidate(); - }); - grid.nextLine(); + tools.emplace_back(ToolEntry{ "Ghost module config", {}, run_ghost_config }); } #endif +#if defined(LUA) + scanLuaTools(tools); +#endif + + tools.sort(tool_compare_nocase); + + window->setFlexLayout(LV_FLEX_FLOW_ROW_WRAP, 8); + lv_obj_t* w_obj = window->getLvObj(); + lv_obj_set_style_pad_row(w_obj, 8, 0); + lv_obj_set_style_pad_all(w_obj, 8, 0); + + for (const auto& tool : tools) { + new ToolButton(window, tool); + } } diff --git a/radio/src/gui/colorlcd/themes/etx_lv_theme.cpp b/radio/src/gui/colorlcd/themes/etx_lv_theme.cpp index a1adceaec..df1a409ec 100644 --- a/radio/src/gui/colorlcd/themes/etx_lv_theme.cpp +++ b/radio/src/gui/colorlcd/themes/etx_lv_theme.cpp @@ -293,7 +293,7 @@ static void style_init(void) lv_style_set_shadow_ofs_y(&styles.btn, lv_disp_dpx(theme.disp, LV_DPX(4))); } lv_style_set_text_color(&styles.btn, color_text); - lv_style_set_pad_hor(&styles.btn, PAD_DEF); + lv_style_set_pad_hor(&styles.btn, PAD_SMALL); lv_style_set_pad_ver(&styles.btn, PAD_SMALL); lv_style_set_pad_column(&styles.btn, lv_disp_dpx(theme.disp, 5)); lv_style_set_pad_row(&styles.btn, lv_disp_dpx(theme.disp, 5));