From 5cf8b7f769aa49f40e291a3c5b788c0e93550a21 Mon Sep 17 00:00:00 2001 From: Piotr Rzeszut Date: Tue, 11 Jan 2022 21:26:06 +0100 Subject: [PATCH 01/22] initial version of clickable checklist --- radio/src/gui/common/stdlcd/view_text.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/radio/src/gui/common/stdlcd/view_text.cpp b/radio/src/gui/common/stdlcd/view_text.cpp index 5185074ee36..b78cd2b46e0 100644 --- a/radio/src/gui/common/stdlcd/view_text.cpp +++ b/radio/src/gui/common/stdlcd/view_text.cpp @@ -22,6 +22,7 @@ #include "opentx.h" constexpr uint32_t TEXT_FILE_MAXSIZE = 2048; +int checklistPosition; static void sdReadTextFile(const char * filename, char lines[TEXT_VIEWER_LINES][LCD_COLS + 1], int & lines_count) { @@ -126,6 +127,7 @@ void menuTextView(event_t event) { if (event == EVT_ENTRY) { menuVerticalOffset = 0; + checklistPosition = 0; reusableBuffer.viewText.linesCount = 0; sdReadTextFile(reusableBuffer.viewText.filename, reusableBuffer.viewText.lines, reusableBuffer.viewText.linesCount); } else if (IS_PREVIOUS_EVENT(event)) { @@ -137,13 +139,24 @@ void menuTextView(event_t event) if (menuVerticalOffset + LCD_LINES-1 < reusableBuffer.viewText.linesCount) { ++menuVerticalOffset; sdReadTextFile(reusableBuffer.viewText.filename, reusableBuffer.viewText.lines, reusableBuffer.viewText.linesCount); - } + } else if (event == EVT_KEY_BREAK(KEY_ENTER)) { + if (checklistPosition < reusableBuffer.viewText.linesCount) { + ++checklistPosition; + if (checklistPosition-(int)menuVerticalOffset == LCD_LINES-1 && menuVerticalOffset+LCD_LINES-1 < reusableBuffer.viewText.linesCount) { + ++menuVerticalOffset; + sdReadTextFile(reusableBuffer.viewText.filename, reusableBuffer.viewText.lines, reusableBuffer.viewText.linesCount); + } + } + else { + popMenu(); + } } else if (event == EVT_KEY_BREAK(KEY_EXIT)) { popMenu(); } for (int i=0; i Date: Tue, 11 Jan 2022 22:30:52 +0100 Subject: [PATCH 02/22] do not display checkboxes for empty lines if checklist is shorter than screen size --- radio/src/gui/common/stdlcd/view_text.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/radio/src/gui/common/stdlcd/view_text.cpp b/radio/src/gui/common/stdlcd/view_text.cpp index b78cd2b46e0..493fd54d211 100644 --- a/radio/src/gui/common/stdlcd/view_text.cpp +++ b/radio/src/gui/common/stdlcd/view_text.cpp @@ -155,7 +155,8 @@ void menuTextView(event_t event) } for (int i=0; i Date: Tue, 11 Jan 2022 22:40:01 +0100 Subject: [PATCH 03/22] remove checklist exit after completing it cannot exit menu from menuTextView as level above there is while loop that cannot be stopped from thic place in code --- radio/src/gui/common/stdlcd/view_text.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/radio/src/gui/common/stdlcd/view_text.cpp b/radio/src/gui/common/stdlcd/view_text.cpp index 493fd54d211..2db822f9a66 100644 --- a/radio/src/gui/common/stdlcd/view_text.cpp +++ b/radio/src/gui/common/stdlcd/view_text.cpp @@ -147,9 +147,6 @@ void menuTextView(event_t event) sdReadTextFile(reusableBuffer.viewText.filename, reusableBuffer.viewText.lines, reusableBuffer.viewText.linesCount); } } - else { - popMenu(); - } } else if (event == EVT_KEY_BREAK(KEY_EXIT)) { popMenu(); } From ee531b9d59271242659e420f391520eba732cc38 Mon Sep 17 00:00:00 2001 From: Piotr Rzeszut Date: Tue, 11 Jan 2022 23:32:19 +0100 Subject: [PATCH 04/22] menu entry to enable and disable interactive checklist --- radio/src/datastructs_private.h | 3 ++- radio/src/gui/128x64/model_setup.cpp | 6 +++++- radio/src/gui/212x64/model_setup.cpp | 6 +++++- radio/src/gui/common/stdlcd/view_text.cpp | 13 ++++++++++--- radio/src/translations.cpp | 1 + radio/src/translations.h | 1 + radio/src/translations/cn.h | 1 + radio/src/translations/cz.h | 1 + radio/src/translations/da.h | 1 + radio/src/translations/de.h | 1 + radio/src/translations/en.h | 1 + radio/src/translations/es.h | 1 + radio/src/translations/fi.h | 1 + radio/src/translations/fr.h | 1 + radio/src/translations/it.h | 1 + radio/src/translations/jp.h | 1 + radio/src/translations/nl.h | 1 + radio/src/translations/pl.h | 1 + radio/src/translations/pt.h | 1 + radio/src/translations/se.h | 1 + radio/src/translations/tw.h | 1 + 21 files changed, 39 insertions(+), 6 deletions(-) diff --git a/radio/src/datastructs_private.h b/radio/src/datastructs_private.h index 727974e9202..948a41aaac2 100644 --- a/radio/src/datastructs_private.h +++ b/radio/src/datastructs_private.h @@ -678,7 +678,8 @@ PACK(struct ModelData { uint8_t enableCustomThrottleWarning:1; uint8_t disableTelemetryWarning:1; uint8_t showInstanceIds:1; - uint8_t spare3:5 SKIP; + uint8_t checklistInteractiveBW:1; + uint8_t spare3:4 SKIP; int8_t customThrottleWarningPosition; BeepANACenter beepANACenter; MixData mixData[MAX_MIXERS] NO_IDX; diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index e31d2dbc73e..dce4d4edf31 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -99,6 +99,7 @@ enum MenuModelSetupItems { ITEM_MODEL_SETUP_THROTTLE_TRIM_SWITCH, ITEM_MODEL_SETUP_PREFLIGHT_LABEL, ITEM_MODEL_SETUP_CHECKLIST_DISPLAY, + ITEM_MODEL_SETUP_CHECKLIST_INTERACTIVE, ITEM_MODEL_SETUP_THROTTLE_WARNING, ITEM_MODEL_SETUP_CUSTOM_THROTTLE_WARNING, ITEM_MODEL_SETUP_CUSTOM_THROTTLE_WARNING_VALUE, @@ -586,7 +587,6 @@ void menuModelSetup(event_t event) PREFLIGHT_ROW(0), // Checklist PREFLIGHT_ROW(0), // Throttle warning PREFLIGHT_ROW(0), // Custom position for throttle warning enable - PREFLIGHT_ROW(0), // Custom position for throttle warning value WARN_ROWS uint8_t(NAVIGATION_LINE_BY_LINE | (adcGetInputOffset(ADC_INPUT_POT + 1) - 1)), // Center beeps @@ -923,6 +923,10 @@ void menuModelSetup(event_t event) case ITEM_MODEL_SETUP_CHECKLIST_DISPLAY: g_model.displayChecklist = editCheckBox(g_model.displayChecklist, MODEL_SETUP_2ND_COLUMN, y, STR_CHECKLIST, attr, event); break; + + case ITEM_MODEL_SETUP_CHECKLIST_INTERACTIVE: + g_model.checklistInteractiveBW = editCheckBox(g_model.checklistInteractiveBW, MODEL_SETUP_2ND_COLUMN, y, STR_CHECKLIST_INTERACTIVE, attr, event); + break; case ITEM_MODEL_SETUP_THROTTLE_WARNING: g_model.disableThrottleWarning = !editCheckBox(!g_model.disableThrottleWarning, MODEL_SETUP_2ND_COLUMN, y, STR_THROTTLE_WARNING, attr, event); diff --git a/radio/src/gui/212x64/model_setup.cpp b/radio/src/gui/212x64/model_setup.cpp index 5d86a23f8c4..ce6bf6501c8 100644 --- a/radio/src/gui/212x64/model_setup.cpp +++ b/radio/src/gui/212x64/model_setup.cpp @@ -87,6 +87,7 @@ enum MenuModelSetupItems { ITEM_MODEL_SETUP_THROTTLE_TRIM_SWITCH, ITEM_MODEL_SETUP_PREFLIGHT_LABEL, ITEM_MODEL_SETUP_CHECKLIST_DISPLAY, + ITEM_MODEL_SETUP_CHECKLIST_INTERACTIVE, ITEM_MODEL_SETUP_THROTTLE_WARNING, ITEM_MODEL_SETUP_CUSTOM_THROTTLE_WARNING, ITEM_MODEL_SETUP_CUSTOM_THROTTLE_WARNING_VALUE, @@ -530,7 +531,6 @@ void menuModelSetup(event_t event) PREFLIGHT_ROW(0), // Checklist PREFLIGHT_ROW(0), // Throttle warning PREFLIGHT_ROW(0), // Custom position for throttle warning enable - PREFLIGHT_ROW(0), // Custom position for throttle warning value SW_WARN_ROWS, // Switch warning POT_WARN_ROWS, // Pot warning @@ -819,6 +819,10 @@ void menuModelSetup(event_t event) case ITEM_MODEL_SETUP_CHECKLIST_DISPLAY: g_model.displayChecklist = editCheckBox(g_model.displayChecklist, MODEL_SETUP_2ND_COLUMN, y, STR_CHECKLIST, attr, event); break; + + case ITEM_MODEL_SETUP_CHECKLIST_INTERACTIVE: + g_model.checklistInteractiveBW = editCheckBox(g_model.checklistInteractiveBW, MODEL_SETUP_2ND_COLUMN, y, STR_CHECKLIST_INTERACTIVE, attr, event); + break; case ITEM_MODEL_SETUP_THROTTLE_WARNING: g_model.disableThrottleWarning = !editCheckBox(!g_model.disableThrottleWarning, MODEL_SETUP_2ND_COLUMN, y, STR_THROTTLE_WARNING, attr, event); diff --git a/radio/src/gui/common/stdlcd/view_text.cpp b/radio/src/gui/common/stdlcd/view_text.cpp index 2db822f9a66..a17303b1b07 100644 --- a/radio/src/gui/common/stdlcd/view_text.cpp +++ b/radio/src/gui/common/stdlcd/view_text.cpp @@ -140,6 +140,7 @@ void menuTextView(event_t event) ++menuVerticalOffset; sdReadTextFile(reusableBuffer.viewText.filename, reusableBuffer.viewText.lines, reusableBuffer.viewText.linesCount); } else if (event == EVT_KEY_BREAK(KEY_ENTER)) { + if (g_model.checklistInteractiveBW){ if (checklistPosition < reusableBuffer.viewText.linesCount) { ++checklistPosition; if (checklistPosition-(int)menuVerticalOffset == LCD_LINES-1 && menuVerticalOffset+LCD_LINES-1 < reusableBuffer.viewText.linesCount) { @@ -147,14 +148,20 @@ void menuTextView(event_t event) sdReadTextFile(reusableBuffer.viewText.filename, reusableBuffer.viewText.lines, reusableBuffer.viewText.linesCount); } } + } } else if (event == EVT_KEY_BREAK(KEY_EXIT)) { popMenu(); } for (int i=0; i Date: Wed, 12 Jan 2022 01:17:04 +0100 Subject: [PATCH 05/22] only when complete interactive checklist is closed --- radio/src/gui/common/stdlcd/model_notes.cpp | 3 +-- radio/src/gui/common/stdlcd/view_text.cpp | 17 ++++++++++++++--- radio/src/opentx.h | 2 ++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/radio/src/gui/common/stdlcd/model_notes.cpp b/radio/src/gui/common/stdlcd/model_notes.cpp index bf2bb09f21e..d6945323708 100644 --- a/radio/src/gui/common/stdlcd/model_notes.cpp +++ b/radio/src/gui/common/stdlcd/model_notes.cpp @@ -18,7 +18,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ - #include "opentx.h" void menuModelNotes(event_t event) @@ -34,7 +33,7 @@ void menuModelNotes(event_t event) strcpy(buf, TEXT_EXT); } } - + reusableBuffer.viewText.pushMenu = true; menuTextView(event); } diff --git a/radio/src/gui/common/stdlcd/view_text.cpp b/radio/src/gui/common/stdlcd/view_text.cpp index a17303b1b07..886d64f5afd 100644 --- a/radio/src/gui/common/stdlcd/view_text.cpp +++ b/radio/src/gui/common/stdlcd/view_text.cpp @@ -103,7 +103,8 @@ void readModelNotes() waitKeysReleased(); event_t event = EVT_ENTRY; - while (event != EVT_KEY_BREAK(KEY_EXIT)) { + reusableBuffer.viewText.pushMenu = false; + while (true) { uint32_t power = pwrCheck(); if (power != e_power_press) { lcdRefreshWait(); @@ -118,6 +119,7 @@ void readModelNotes() } event = getEvent(); WDG_RESET(); + if (reusableBuffer.viewText.checklistComplete) break; } LED_ERROR_END(); @@ -128,6 +130,7 @@ void menuTextView(event_t event) if (event == EVT_ENTRY) { menuVerticalOffset = 0; checklistPosition = 0; + reusableBuffer.viewText.checklistComplete = false; reusableBuffer.viewText.linesCount = 0; sdReadTextFile(reusableBuffer.viewText.filename, reusableBuffer.viewText.lines, reusableBuffer.viewText.linesCount); } else if (IS_PREVIOUS_EVENT(event)) { @@ -147,10 +150,17 @@ void menuTextView(event_t event) ++menuVerticalOffset; sdReadTextFile(reusableBuffer.viewText.filename, reusableBuffer.viewText.lines, reusableBuffer.viewText.linesCount); } - } + } + else { + if (reusableBuffer.viewText.pushMenu == true) popMenu(); + reusableBuffer.viewText.checklistComplete = true; + } } } else if (event == EVT_KEY_BREAK(KEY_EXIT)) { - popMenu(); + if (!g_model.checklistInteractiveBW || reusableBuffer.viewText.pushMenu == true) { + if (reusableBuffer.viewText.pushMenu == true) popMenu(); + reusableBuffer.viewText.checklistComplete = true; + } } for (int i=0; i Date: Wed, 12 Jan 2022 15:56:01 +0100 Subject: [PATCH 06/22] config updated & not display checkboxes when entered from "View Notes" --- radio/src/gui/128x64/model_setup.cpp | 2 +- radio/src/gui/212x64/model_setup.cpp | 2 +- radio/src/gui/common/stdlcd/view_text.cpp | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index dce4d4edf31..27d1850b7a2 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -925,7 +925,7 @@ void menuModelSetup(event_t event) break; case ITEM_MODEL_SETUP_CHECKLIST_INTERACTIVE: - g_model.checklistInteractiveBW = editCheckBox(g_model.checklistInteractiveBW, MODEL_SETUP_2ND_COLUMN, y, STR_CHECKLIST_INTERACTIVE, attr, event); + g_model.checklistInteractive = editCheckBox(g_model.checklistInteractive, MODEL_SETUP_2ND_COLUMN, y, STR_CHECKLIST_INTERACTIVE, attr, event); break; case ITEM_MODEL_SETUP_THROTTLE_WARNING: diff --git a/radio/src/gui/212x64/model_setup.cpp b/radio/src/gui/212x64/model_setup.cpp index ce6bf6501c8..e02acd7d8b5 100644 --- a/radio/src/gui/212x64/model_setup.cpp +++ b/radio/src/gui/212x64/model_setup.cpp @@ -821,7 +821,7 @@ void menuModelSetup(event_t event) break; case ITEM_MODEL_SETUP_CHECKLIST_INTERACTIVE: - g_model.checklistInteractiveBW = editCheckBox(g_model.checklistInteractiveBW, MODEL_SETUP_2ND_COLUMN, y, STR_CHECKLIST_INTERACTIVE, attr, event); + g_model.checklistInteractive = editCheckBox(g_model.checklistInteractive, MODEL_SETUP_2ND_COLUMN, y, STR_CHECKLIST_INTERACTIVE, attr, event); break; case ITEM_MODEL_SETUP_THROTTLE_WARNING: diff --git a/radio/src/gui/common/stdlcd/view_text.cpp b/radio/src/gui/common/stdlcd/view_text.cpp index 886d64f5afd..fafcdb2684a 100644 --- a/radio/src/gui/common/stdlcd/view_text.cpp +++ b/radio/src/gui/common/stdlcd/view_text.cpp @@ -143,7 +143,7 @@ void menuTextView(event_t event) ++menuVerticalOffset; sdReadTextFile(reusableBuffer.viewText.filename, reusableBuffer.viewText.lines, reusableBuffer.viewText.linesCount); } else if (event == EVT_KEY_BREAK(KEY_ENTER)) { - if (g_model.checklistInteractiveBW){ + if (g_model.checklistInteractive && !reusableBuffer.viewText.pushMenu){ if (checklistPosition < reusableBuffer.viewText.linesCount) { ++checklistPosition; if (checklistPosition-(int)menuVerticalOffset == LCD_LINES-1 && menuVerticalOffset+LCD_LINES-1 < reusableBuffer.viewText.linesCount) { @@ -157,15 +157,15 @@ void menuTextView(event_t event) } } } else if (event == EVT_KEY_BREAK(KEY_EXIT)) { - if (!g_model.checklistInteractiveBW || reusableBuffer.viewText.pushMenu == true) { + if (!g_model.checklistInteractive || reusableBuffer.viewText.pushMenu) { if (reusableBuffer.viewText.pushMenu == true) popMenu(); reusableBuffer.viewText.checklistComplete = true; } } for (int i=0; i Date: Sun, 16 Jan 2022 22:18:12 +0100 Subject: [PATCH 07/22] add setup entry for colorlcd --- radio/src/gui/colorlcd/preflight_checks.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/radio/src/gui/colorlcd/preflight_checks.cpp b/radio/src/gui/colorlcd/preflight_checks.cpp index 781067687bc..a147006c5de 100644 --- a/radio/src/gui/colorlcd/preflight_checks.cpp +++ b/radio/src/gui/colorlcd/preflight_checks.cpp @@ -120,6 +120,11 @@ PreflightChecks::PreflightChecks() : Page(ICON_MODEL_SETUP) new StaticText(line, rect_t{}, STR_CHECKLIST, 0, COLOR_THEME_PRIMARY1); new ToggleSwitch(line, rect_t{}, GET_SET_DEFAULT(g_model.displayChecklist)); + // Interactive checklist + auto line = form->newLine(&grid); + new StaticText(line, rect_t{}, STR_CHECKLIST_INTERACTIVE, 0, COLOR_THEME_PRIMARY1); + new CheckBox(line, rect_t{}, GET_SET_DEFAULT(g_model.displayChecklist)); + // Throttle warning line = form->newLine(&grid); new StaticText(line, rect_t{}, STR_THROTTLE_WARNING, 0, COLOR_THEME_PRIMARY1); From 38fb36ba2b40d55ca8f84b2532778044a6ac18a6 Mon Sep 17 00:00:00 2001 From: Piotr Rzeszut Date: Sun, 23 Jan 2022 01:40:31 +0100 Subject: [PATCH 08/22] do not make interactive checkist when loaded from menu --- radio/src/gui/colorlcd/view_main_menu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/radio/src/gui/colorlcd/view_main_menu.cpp b/radio/src/gui/colorlcd/view_main_menu.cpp index d5efe112b5e..d36fda303f1 100644 --- a/radio/src/gui/colorlcd/view_main_menu.cpp +++ b/radio/src/gui/colorlcd/view_main_menu.cpp @@ -55,7 +55,7 @@ ViewMainMenu::ViewMainMenu(Window* parent, std::function closeHandler) : if (modelHasNotes()) { carousel->addButton(ICON_MODEL_NOTES, STR_MAIN_MENU_MODEL_NOTES, [=]() -> uint8_t { deleteLater(); - readModelNotes(); + readModelNotes(true); return 0; }); } From 725df9cd1fb0d075ea45c3c0ddc57f5772653890 Mon Sep 17 00:00:00 2001 From: Piotr Rzeszut Date: Thu, 27 Jan 2022 02:14:42 +0100 Subject: [PATCH 09/22] fix datastruct size after merge --- radio/src/datastructs_private.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/radio/src/datastructs_private.h b/radio/src/datastructs_private.h index 948a41aaac2..88fe4300988 100644 --- a/radio/src/datastructs_private.h +++ b/radio/src/datastructs_private.h @@ -678,8 +678,8 @@ PACK(struct ModelData { uint8_t enableCustomThrottleWarning:1; uint8_t disableTelemetryWarning:1; uint8_t showInstanceIds:1; - uint8_t checklistInteractiveBW:1; - uint8_t spare3:4 SKIP; + uint8_t checklistInteractive:1; + uint8_t spare2:7 SKIP; // padding to 8-bit aligment int8_t customThrottleWarningPosition; BeepANACenter beepANACenter; MixData mixData[MAX_MIXERS] NO_IDX; From a916e5ce112097eebb0ae67982598af7d659934b Mon Sep 17 00:00:00 2001 From: Piotr Rzeszut Date: Thu, 27 Jan 2022 03:54:15 +0100 Subject: [PATCH 10/22] Companion support for interactive checklist --- companion/src/firmwares/edgetx/yaml_modeldata.cpp | 2 ++ companion/src/firmwares/modeldata.h | 1 + companion/src/modeledit/setup.cpp | 7 +++++++ companion/src/modeledit/setup.h | 1 + companion/src/modeledit/setup.ui | 10 ++++++++++ 5 files changed, 21 insertions(+) diff --git a/companion/src/firmwares/edgetx/yaml_modeldata.cpp b/companion/src/firmwares/edgetx/yaml_modeldata.cpp index 1da4e3520fd..5ca2d5a5de4 100644 --- a/companion/src/firmwares/edgetx/yaml_modeldata.cpp +++ b/companion/src/firmwares/edgetx/yaml_modeldata.cpp @@ -920,6 +920,7 @@ Node convert::encode(const ModelData& rhs) node["extendedLimits"] = (int)rhs.extendedLimits; node["extendedTrims"] = (int)rhs.extendedTrims; node["throttleReversed"] = (int)rhs.throttleReversed; + node["checklistInteractive"] = (int)rhs.checklistInteractive; for (int i = 0; i < CPN_MAX_FLIGHT_MODES; i++) { if (!rhs.flightModeData[i].isEmpty(i)) { @@ -1201,6 +1202,7 @@ bool convert::decode(const Node& node, ModelData& rhs) node["extendedLimits"] >> rhs.extendedLimits; node["extendedTrims"] >> rhs.extendedTrims; node["throttleReversed"] >> rhs.throttleReversed; + node["checklistInteractive"] >> rhs.checklistInteractive; node["flightModeData"] >> rhs.flightModeData; node["mixData"] >> rhs.mixData; diff --git a/companion/src/firmwares/modeldata.h b/companion/src/firmwares/modeldata.h index 09e1b000aef..806f1c1d3ac 100644 --- a/companion/src/firmwares/modeldata.h +++ b/companion/src/firmwares/modeldata.h @@ -145,6 +145,7 @@ class ModelData { bool extendedLimits; // TODO xml bool extendedTrims; bool throttleReversed; + bool checklistInteractive; FlightModeData flightModeData[CPN_MAX_FLIGHT_MODES]; MixData mixData[CPN_MAX_MIXERS]; LimitData limitData[CPN_MAX_CHNOUT]; diff --git a/companion/src/modeledit/setup.cpp b/companion/src/modeledit/setup.cpp index f7b081b2f8d..fe1576c427c 100644 --- a/companion/src/modeledit/setup.cpp +++ b/companion/src/modeledit/setup.cpp @@ -1795,6 +1795,7 @@ void SetupPanel::update() ui->extendedLimits->setChecked(model->extendedLimits); ui->extendedTrims->setChecked(model->extendedTrims); ui->displayText->setChecked(model->displayChecklist); + ui->checklistInteractive->setChecked(model->checklistInteractive); ui->gfEnabled->setChecked(!model->noGlobalFunctions); ui->jitterFilter->setCurrentIndex(model->jitterFilter); @@ -1942,6 +1943,12 @@ void SetupPanel::on_displayText_toggled(bool checked) emit modified(); } +void SetupPanel::on_checklistInteractive_toggled(bool checked) +{ + model->checklistInteractive = checked; + emit modified(); +} + void SetupPanel::on_gfEnabled_toggled(bool checked) { model->noGlobalFunctions = !checked; diff --git a/companion/src/modeledit/setup.h b/companion/src/modeledit/setup.h index af83bce3797..841e23f45a6 100644 --- a/companion/src/modeledit/setup.h +++ b/companion/src/modeledit/setup.h @@ -190,6 +190,7 @@ class SetupPanel : public ModelPanel void on_customThrottleWarningPosition_valueChanged(int value); void on_throttleReverse_toggled(bool checked); void on_displayText_toggled(bool checked); + void on_checklistInteractive_toggled(bool checked); void on_gfEnabled_toggled(bool checked); void on_image_currentIndexChanged(int index); void on_trimIncrement_currentIndexChanged(int index); diff --git a/companion/src/modeledit/setup.ui b/companion/src/modeledit/setup.ui index 010ce675806..9ff59393630 100644 --- a/companion/src/modeledit/setup.ui +++ b/companion/src/modeledit/setup.ui @@ -579,6 +579,16 @@ + + + + Qt::LeftToRight + + + Interactive Checklist + + + From aed6ba217aa12e69f9aa22ba68894f2fc0f02ab3 Mon Sep 17 00:00:00 2001 From: Piotr Rzeszut Date: Sun, 30 Jan 2022 02:09:03 +0100 Subject: [PATCH 11/22] mark checklist lines as non-checkable with '=' for B&W radios --- radio/src/gui/common/stdlcd/view_text.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/radio/src/gui/common/stdlcd/view_text.cpp b/radio/src/gui/common/stdlcd/view_text.cpp index fafcdb2684a..f24843e85e9 100644 --- a/radio/src/gui/common/stdlcd/view_text.cpp +++ b/radio/src/gui/common/stdlcd/view_text.cpp @@ -22,6 +22,7 @@ #include "opentx.h" constexpr uint32_t TEXT_FILE_MAXSIZE = 2048; +constexpr char NON_CHECKABLE_PREFIX = '='; int checklistPosition; static void sdReadTextFile(const char * filename, char lines[TEXT_VIEWER_LINES][LCD_COLS + 1], int & lines_count) @@ -165,9 +166,22 @@ void menuTextView(event_t event) for (int i=0; i Date: Mon, 31 Jan 2022 00:07:15 +0100 Subject: [PATCH 12/22] Process only items visible on screen This is also crucial when it comes to analyse non-checkable items on a checklist, as in this way there is no need to load non-visible items from SD-card --- radio/src/gui/common/stdlcd/view_text.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/radio/src/gui/common/stdlcd/view_text.cpp b/radio/src/gui/common/stdlcd/view_text.cpp index f24843e85e9..2d506f7725c 100644 --- a/radio/src/gui/common/stdlcd/view_text.cpp +++ b/radio/src/gui/common/stdlcd/view_text.cpp @@ -144,12 +144,14 @@ void menuTextView(event_t event) ++menuVerticalOffset; sdReadTextFile(reusableBuffer.viewText.filename, reusableBuffer.viewText.lines, reusableBuffer.viewText.linesCount); } else if (event == EVT_KEY_BREAK(KEY_ENTER)) { - if (g_model.checklistInteractive && !reusableBuffer.viewText.pushMenu){ + if (g_model.checklistInteractive && !reusableBuffer.viewText.pushMenu && checklistPosition-(int)menuVerticalOffset >= 0){ if (checklistPosition < reusableBuffer.viewText.linesCount) { - ++checklistPosition; - if (checklistPosition-(int)menuVerticalOffset == LCD_LINES-1 && menuVerticalOffset+LCD_LINES-1 < reusableBuffer.viewText.linesCount) { - ++menuVerticalOffset; - sdReadTextFile(reusableBuffer.viewText.filename, reusableBuffer.viewText.lines, reusableBuffer.viewText.linesCount); + if (checklistPosition-(int)menuVerticalOffset < LCD_LINES-1) { + ++checklistPosition; + if (checklistPosition-(int)menuVerticalOffset >= LCD_LINES-2 && menuVerticalOffset+LCD_LINES-1 < reusableBuffer.viewText.linesCount) { + ++menuVerticalOffset; + sdReadTextFile(reusableBuffer.viewText.filename, reusableBuffer.viewText.lines, reusableBuffer.viewText.linesCount); + } } } else { From 49fadc195d4a1284a8ca2d8b12ef7eb3dc50a350 Mon Sep 17 00:00:00 2001 From: gagarinlg Date: Fri, 5 May 2023 20:19:55 +0200 Subject: [PATCH 13/22] WIP fix merge problems --- radio/src/datastructs_private.h | 2 +- radio/src/gui/colorlcd/preflight_checks.cpp | 2 +- radio/src/gui/colorlcd/view_text.cpp | 10 +++++----- radio/src/gui/colorlcd/view_text.h | 8 +++++--- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/radio/src/datastructs_private.h b/radio/src/datastructs_private.h index 88fe4300988..325b2af76f5 100644 --- a/radio/src/datastructs_private.h +++ b/radio/src/datastructs_private.h @@ -679,7 +679,7 @@ PACK(struct ModelData { uint8_t disableTelemetryWarning:1; uint8_t showInstanceIds:1; uint8_t checklistInteractive:1; - uint8_t spare2:7 SKIP; // padding to 8-bit aligment + uint8_t spare3:4 SKIP; // padding to 8-bit aligment int8_t customThrottleWarningPosition; BeepANACenter beepANACenter; MixData mixData[MAX_MIXERS] NO_IDX; diff --git a/radio/src/gui/colorlcd/preflight_checks.cpp b/radio/src/gui/colorlcd/preflight_checks.cpp index a147006c5de..5ef776e7784 100644 --- a/radio/src/gui/colorlcd/preflight_checks.cpp +++ b/radio/src/gui/colorlcd/preflight_checks.cpp @@ -121,7 +121,7 @@ PreflightChecks::PreflightChecks() : Page(ICON_MODEL_SETUP) new ToggleSwitch(line, rect_t{}, GET_SET_DEFAULT(g_model.displayChecklist)); // Interactive checklist - auto line = form->newLine(&grid); + line = form->newLine(&grid); new StaticText(line, rect_t{}, STR_CHECKLIST_INTERACTIVE, 0, COLOR_THEME_PRIMARY1); new CheckBox(line, rect_t{}, GET_SET_DEFAULT(g_model.displayChecklist)); diff --git a/radio/src/gui/colorlcd/view_text.cpp b/radio/src/gui/colorlcd/view_text.cpp index acf47397d58..b40db662387 100644 --- a/radio/src/gui/colorlcd/view_text.cpp +++ b/radio/src/gui/colorlcd/view_text.cpp @@ -192,19 +192,19 @@ static void replaceSpaceWithUnderscore(std::string &name) #define MODEL_FILE_EXT MODELS_EXT #endif -bool openNotes(const char buf[], std::string modelNotesName) +bool openNotes(const char buf[], std::string modelNotesName, bool fromMenu = false) { std::string fullPath = std::string(buf) + PATH_SEPARATOR + modelNotesName; if (isFileAvailable(fullPath.c_str())) { - new ViewTextWindow(std::string(buf), modelNotesName, ICON_MODEL); + new ViewTextWindow(std::string(buf), modelNotesName, ICON_MODEL, fromMenu); return true; } else { return false; } } -void readModelNotes() +void readModelNotes(bool fromMenu) { bool notesFound = false; LED_ERROR_BEGIN(); @@ -213,10 +213,10 @@ void readModelNotes() modelNotesName.append(TEXT_EXT); const char buf[] = {MODELS_PATH}; - notesFound = openNotes(buf, modelNotesName); + notesFound = openNotes(buf, modelNotesName, fromMenu); if (!notesFound) { replaceSpaceWithUnderscore(modelNotesName); - notesFound = openNotes(buf, modelNotesName); + notesFound = openNotes(buf, modelNotesName, fromMenu); } #if !defined(EEPROM) diff --git a/radio/src/gui/colorlcd/view_text.h b/radio/src/gui/colorlcd/view_text.h index 77bb7be0254..c384664f794 100644 --- a/radio/src/gui/colorlcd/view_text.h +++ b/radio/src/gui/colorlcd/view_text.h @@ -35,8 +35,8 @@ class ViewTextWindow : public Page { public: ViewTextWindow(const std::string path, const std::string name, - unsigned int icon = ICON_RADIO_SD_MANAGER) : - Page(icon), path(std::move(path)), name(std::move(name)) + unsigned int icon = ICON_RADIO_SD_MANAGER, bool fromMenu = false) : + Page(icon), path(std::move(path)), name(std::move(name)), fromMenu(fromMenu) { fullPath = this->path + std::string(PATH_SEPARATOR) + this->name; extractNameSansExt(); @@ -66,6 +66,8 @@ class ViewTextWindow : public Page std::string fullPath; std::string extension; + bool fromMenu; + lv_obj_t* lb; int offset = 0; @@ -80,4 +82,4 @@ class ViewTextWindow : public Page void onEvent(event_t event) override; }; -void readModelNotes(); +void readModelNotes(bool fromMenu = false); From 132af0e0c366c73260787843f1cdc7a382c1b0a7 Mon Sep 17 00:00:00 2001 From: gagarinlg Date: Fri, 5 May 2023 20:20:29 +0200 Subject: [PATCH 14/22] update yaml datastructs --- radio/src/storage/yaml/yaml_datastructs_128x64.cpp | 3 ++- radio/src/storage/yaml/yaml_datastructs_nv14.cpp | 3 ++- radio/src/storage/yaml/yaml_datastructs_t20.cpp | 3 ++- radio/src/storage/yaml/yaml_datastructs_tpro.cpp | 3 ++- radio/src/storage/yaml/yaml_datastructs_x10.cpp | 3 ++- radio/src/storage/yaml/yaml_datastructs_x12s.cpp | 3 ++- radio/src/storage/yaml/yaml_datastructs_x9d.cpp | 3 ++- radio/src/storage/yaml/yaml_datastructs_x9e.cpp | 3 ++- radio/src/storage/yaml/yaml_datastructs_x9lite.cpp | 3 ++- radio/src/storage/yaml/yaml_datastructs_xlites.cpp | 3 ++- 10 files changed, 20 insertions(+), 10 deletions(-) diff --git a/radio/src/storage/yaml/yaml_datastructs_128x64.cpp b/radio/src/storage/yaml/yaml_datastructs_128x64.cpp index cd48c94e699..9b7c0311c81 100644 --- a/radio/src/storage/yaml/yaml_datastructs_128x64.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_128x64.cpp @@ -787,7 +787,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_UNSIGNED( "enableCustomThrottleWarning", 1 ), YAML_UNSIGNED( "disableTelemetryWarning", 1 ), YAML_UNSIGNED( "showInstanceIds", 1 ), - YAML_PADDING( 5 ), + YAML_UNSIGNED( "checklistInteractive", 1 ), + YAML_PADDING( 4 ), YAML_SIGNED( "customThrottleWarningPosition", 8 ), YAML_UNSIGNED( "beepANACenter", 16 ), YAML_ARRAY("mixData", 160, 64, struct_MixData, NULL), diff --git a/radio/src/storage/yaml/yaml_datastructs_nv14.cpp b/radio/src/storage/yaml/yaml_datastructs_nv14.cpp index 2417bfe1592..c2a41ab5d0e 100644 --- a/radio/src/storage/yaml/yaml_datastructs_nv14.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_nv14.cpp @@ -816,7 +816,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_UNSIGNED( "enableCustomThrottleWarning", 1 ), YAML_UNSIGNED( "disableTelemetryWarning", 1 ), YAML_UNSIGNED( "showInstanceIds", 1 ), - YAML_PADDING( 5 ), + YAML_UNSIGNED( "checklistInteractive", 1 ), + YAML_PADDING( 4 ), YAML_SIGNED( "customThrottleWarningPosition", 8 ), YAML_UNSIGNED( "beepANACenter", 16 ), YAML_ARRAY("mixData", 160, 64, struct_MixData, NULL), diff --git a/radio/src/storage/yaml/yaml_datastructs_t20.cpp b/radio/src/storage/yaml/yaml_datastructs_t20.cpp index 3cb3d757193..1e5d12278ff 100644 --- a/radio/src/storage/yaml/yaml_datastructs_t20.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_t20.cpp @@ -785,7 +785,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_UNSIGNED( "enableCustomThrottleWarning", 1 ), YAML_UNSIGNED( "disableTelemetryWarning", 1 ), YAML_UNSIGNED( "showInstanceIds", 1 ), - YAML_PADDING( 5 ), + YAML_UNSIGNED( "checklistInteractive", 1 ), + YAML_PADDING( 4 ), YAML_SIGNED( "customThrottleWarningPosition", 8 ), YAML_UNSIGNED( "beepANACenter", 16 ), YAML_ARRAY("mixData", 160, 64, struct_MixData, NULL), diff --git a/radio/src/storage/yaml/yaml_datastructs_tpro.cpp b/radio/src/storage/yaml/yaml_datastructs_tpro.cpp index 18458320d54..11ec05137b7 100644 --- a/radio/src/storage/yaml/yaml_datastructs_tpro.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_tpro.cpp @@ -785,7 +785,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_UNSIGNED( "enableCustomThrottleWarning", 1 ), YAML_UNSIGNED( "disableTelemetryWarning", 1 ), YAML_UNSIGNED( "showInstanceIds", 1 ), - YAML_PADDING( 5 ), + YAML_UNSIGNED( "checklistInteractive", 1 ), + YAML_PADDING( 4 ), YAML_SIGNED( "customThrottleWarningPosition", 8 ), YAML_UNSIGNED( "beepANACenter", 16 ), YAML_ARRAY("mixData", 160, 64, struct_MixData, NULL), diff --git a/radio/src/storage/yaml/yaml_datastructs_x10.cpp b/radio/src/storage/yaml/yaml_datastructs_x10.cpp index 54ba13f5ffa..b1a14f08ca2 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x10.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x10.cpp @@ -824,7 +824,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_UNSIGNED( "enableCustomThrottleWarning", 1 ), YAML_UNSIGNED( "disableTelemetryWarning", 1 ), YAML_UNSIGNED( "showInstanceIds", 1 ), - YAML_PADDING( 5 ), + YAML_UNSIGNED( "checklistInteractive", 1 ), + YAML_PADDING( 4 ), YAML_SIGNED( "customThrottleWarningPosition", 8 ), YAML_UNSIGNED( "beepANACenter", 16 ), YAML_ARRAY("mixData", 160, 64, struct_MixData, NULL), diff --git a/radio/src/storage/yaml/yaml_datastructs_x12s.cpp b/radio/src/storage/yaml/yaml_datastructs_x12s.cpp index 54ba13f5ffa..b1a14f08ca2 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x12s.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x12s.cpp @@ -824,7 +824,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_UNSIGNED( "enableCustomThrottleWarning", 1 ), YAML_UNSIGNED( "disableTelemetryWarning", 1 ), YAML_UNSIGNED( "showInstanceIds", 1 ), - YAML_PADDING( 5 ), + YAML_UNSIGNED( "checklistInteractive", 1 ), + YAML_PADDING( 4 ), YAML_SIGNED( "customThrottleWarningPosition", 8 ), YAML_UNSIGNED( "beepANACenter", 16 ), YAML_ARRAY("mixData", 160, 64, struct_MixData, NULL), diff --git a/radio/src/storage/yaml/yaml_datastructs_x9d.cpp b/radio/src/storage/yaml/yaml_datastructs_x9d.cpp index d06903e3aa8..81521746adc 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x9d.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x9d.cpp @@ -788,7 +788,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_UNSIGNED( "enableCustomThrottleWarning", 1 ), YAML_UNSIGNED( "disableTelemetryWarning", 1 ), YAML_UNSIGNED( "showInstanceIds", 1 ), - YAML_PADDING( 5 ), + YAML_UNSIGNED( "checklistInteractive", 1 ), + YAML_PADDING( 4 ), YAML_SIGNED( "customThrottleWarningPosition", 8 ), YAML_UNSIGNED( "beepANACenter", 16 ), YAML_ARRAY("mixData", 160, 64, struct_MixData, NULL), diff --git a/radio/src/storage/yaml/yaml_datastructs_x9e.cpp b/radio/src/storage/yaml/yaml_datastructs_x9e.cpp index 86e2aeef5f8..88fe37e42f2 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x9e.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x9e.cpp @@ -788,7 +788,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_UNSIGNED( "enableCustomThrottleWarning", 1 ), YAML_UNSIGNED( "disableTelemetryWarning", 1 ), YAML_UNSIGNED( "showInstanceIds", 1 ), - YAML_PADDING( 5 ), + YAML_UNSIGNED( "checklistInteractive", 1 ), + YAML_PADDING( 4 ), YAML_SIGNED( "customThrottleWarningPosition", 8 ), YAML_UNSIGNED( "beepANACenter", 16 ), YAML_ARRAY("mixData", 160, 64, struct_MixData, NULL), diff --git a/radio/src/storage/yaml/yaml_datastructs_x9lite.cpp b/radio/src/storage/yaml/yaml_datastructs_x9lite.cpp index a3a4dd488d5..f691029cc03 100644 --- a/radio/src/storage/yaml/yaml_datastructs_x9lite.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_x9lite.cpp @@ -785,7 +785,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_UNSIGNED( "enableCustomThrottleWarning", 1 ), YAML_UNSIGNED( "disableTelemetryWarning", 1 ), YAML_UNSIGNED( "showInstanceIds", 1 ), - YAML_PADDING( 5 ), + YAML_UNSIGNED( "checklistInteractive", 1 ), + YAML_PADDING( 4 ), YAML_SIGNED( "customThrottleWarningPosition", 8 ), YAML_UNSIGNED( "beepANACenter", 16 ), YAML_ARRAY("mixData", 160, 64, struct_MixData, NULL), diff --git a/radio/src/storage/yaml/yaml_datastructs_xlites.cpp b/radio/src/storage/yaml/yaml_datastructs_xlites.cpp index a27f02d078b..819a6678bda 100644 --- a/radio/src/storage/yaml/yaml_datastructs_xlites.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_xlites.cpp @@ -791,7 +791,8 @@ static const struct YamlNode struct_ModelData[] = { YAML_UNSIGNED( "enableCustomThrottleWarning", 1 ), YAML_UNSIGNED( "disableTelemetryWarning", 1 ), YAML_UNSIGNED( "showInstanceIds", 1 ), - YAML_PADDING( 5 ), + YAML_UNSIGNED( "checklistInteractive", 1 ), + YAML_PADDING( 4 ), YAML_SIGNED( "customThrottleWarningPosition", 8 ), YAML_UNSIGNED( "beepANACenter", 16 ), YAML_ARRAY("mixData", 160, 64, struct_MixData, NULL), From b3771d9fbce6661c4ac52b788e3898326526ef41 Mon Sep 17 00:00:00 2001 From: gagarinlg Date: Fri, 5 May 2023 22:58:14 +0200 Subject: [PATCH 15/22] restore most functionalities for interactive check lists on color LCD radios currently no automatic line wrapping and you can always exit the checklist, even when it is not fully done --- radio/src/gui/colorlcd/view_text.cpp | 104 ++++++++++++++++++++++++--- radio/src/gui/colorlcd/view_text.h | 1 + 2 files changed, 97 insertions(+), 8 deletions(-) diff --git a/radio/src/gui/colorlcd/view_text.cpp b/radio/src/gui/colorlcd/view_text.cpp index b40db662387..0df9f000d9f 100644 --- a/radio/src/gui/colorlcd/view_text.cpp +++ b/radio/src/gui/colorlcd/view_text.cpp @@ -24,6 +24,14 @@ #include "opentx.h" #include "sdcard.h" +static void checkbox_event_handler(lv_event_t* e) +{ + lv_obj_t* target = lv_event_get_target(e); + ViewTextWindow* vtw = (ViewTextWindow*)lv_obj_get_user_data(target); + + if (vtw) vtw->updateCheckboxes(lv_obj_get_parent(target)); +} + void ViewTextWindow::extractNameSansExt() { uint8_t nameLength; @@ -70,13 +78,63 @@ void ViewTextWindow::buildBody(Window *window) lv_obj_clear_flag(obj, LV_OBJ_FLAG_CLICK_FOCUSABLE); auto g = lv_group_get_default(); - lb = lv_label_create(obj); - lv_obj_set_size(lb, lv_pct(100), LV_SIZE_CONTENT); - lv_obj_set_style_pad_all(lb, lv_dpx(8), 0); + if(fromMenu) + { + lb = lv_label_create(obj); + lv_obj_set_size(lb, lv_pct(100), LV_SIZE_CONTENT); + lv_obj_set_style_pad_all(lb, lv_dpx(8), 0); + + lv_group_add_obj(g, obj); + lv_group_set_editing(g, true); + lv_label_set_text_static(lb, buffer); + } else { + lv_obj_set_style_pad_all(obj, 3, LV_PART_MAIN); + lv_obj_set_style_pad_row(obj, 3, LV_PART_MAIN); + lv_obj_set_style_pad_column(obj, 0, LV_PART_MAIN); + + lv_obj_set_layout(obj, LV_LAYOUT_FLEX); + lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_COLUMN); + + lv_obj_t* cb; - lv_group_add_obj(g, obj); - lv_group_set_editing(g, true); - lv_label_set_text_static(lb, buffer); + size_t cur = 0; + size_t line = 0; + bool first = true; + for(int i=0; ipath + std::string(PATH_SEPARATOR) + this->name; + extractNameSansExt(); + + header.setTitle(this->name); + + lv_obj_add_event_cb(lvobj, ViewTextWindow::on_draw, LV_EVENT_DRAW_MAIN_BEGIN, nullptr); +}; - if (vtw) vtw->updateCheckboxes(lv_obj_get_parent(target)); +void ViewTextWindow::on_draw(lv_event_t * e) +{ + lv_obj_t* target = lv_event_get_target(e); + auto view = (ViewTextWindow*)lv_obj_get_user_data(target); + if (view) { + if (view->buffer == nullptr) + view->buildBody(&view->body); + } } void ViewTextWindow::onCancel() { - if(!g_model.checklistInteractive || fromMenu || allChecked()) - Page::onCancel(); + Page::onCancel(); } void ViewTextWindow::extractNameSansExt() @@ -46,14 +61,11 @@ void ViewTextWindow::extractNameSansExt() const char *ext = getFileExtension(name.c_str(), 0, 0, &nameLength, &extLength); extension = std::string(ext); - if (nameLength > TEXT_FILENAME_MAXLEN) nameLength = TEXT_FILENAME_MAXLEN; - nameLength -= extLength; - name.substr(nameLength); openFromEnd = !strcmp(ext, LOGS_EXT); } -void ViewTextWindow::buildBody(Window *window) +bool ViewTextWindow::openFile() { FILINFO info; @@ -75,80 +87,38 @@ void ViewTextWindow::buildBody(Window *window) TRACE("info.fsize=%d\tbufSize=%d\toffset=%d", info.fsize, bufSize, int(info.fsize) - bufSize + 1); if (sdReadTextFileBlock(bufSize, offset) == FR_OK) { - auto obj = window->getLvObj(); - lv_obj_add_flag( - obj, LV_OBJ_FLAG_SCROLLABLE | LV_OBJ_FLAG_SCROLL_WITH_ARROW | - LV_OBJ_FLAG_SCROLL_MOMENTUM | LV_OBJ_FLAG_CLICK_FOCUSABLE); - lv_obj_set_scrollbar_mode(obj, LV_SCROLLBAR_MODE_AUTO); - // prevents resetting the group's edit mode - lv_obj_clear_flag(obj, LV_OBJ_FLAG_CLICK_FOCUSABLE); - - auto g = lv_group_get_default(); - if(fromMenu || !g_model.checklistInteractive) - { - lb = lv_label_create(obj); - lv_obj_set_size(lb, lv_pct(100), LV_SIZE_CONTENT); - lv_obj_set_style_pad_all(lb, lv_dpx(8), 0); - - lv_group_add_obj(g, obj); - lv_group_set_editing(g, true); - lv_label_set_text_static(lb, buffer); - } else { - lv_obj_set_style_pad_all(obj, 3, LV_PART_MAIN); - lv_obj_set_style_pad_row(obj, 3, LV_PART_MAIN); - lv_obj_set_style_pad_column(obj, 0, LV_PART_MAIN); - - lv_obj_set_layout(obj, LV_LAYOUT_FLEX); - lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_COLUMN); - - lv_obj_t* cb; - - size_t cur = 0; - size_t line = 0; - bool first = true; - for(int i=0; i checkBoxes; + + void updateCheckboxes() + { + bool lastState = true; + + for (auto it = checkBoxes.cbegin(); it != checkBoxes.cend(); ++it) { + auto cb = *it; + if (lastState) + { + lv_obj_clear_state(cb, LV_STATE_DISABLED); + if (!(lv_obj_get_state(cb) & LV_STATE_CHECKED)) + lv_group_focus_obj(cb); + } else { + lv_obj_add_state(cb, LV_STATE_DISABLED); + lv_obj_clear_state(cb, LV_STATE_CHECKED); + } + + lastState = lv_obj_get_state(cb) & LV_STATE_CHECKED; + } + + setCloseState(); + } + + bool allChecked() + { + for (auto it = checkBoxes.cbegin(); it != checkBoxes.cend(); ++it) { + auto cb = *it; + if (!(lv_obj_get_state(cb) & LV_STATE_CHECKED)) + return false; + } + + return true; + } + + void setCloseState() + { + if (allChecked()) { + lv_obj_clear_state(closeButton->getLvObj(), LV_STATE_DISABLED); + lv_group_focus_obj(closeButton->getLvObj()); + } else { + lv_obj_add_state(closeButton->getLvObj(), LV_STATE_DISABLED); + } + } + + void onEvent(event_t event) override + { +#if defined(HARDWARE_KEYS) + if(event == EVT_KEY_BREAK(KEY_EXIT)) + onCancel(); +#endif + } + + static void checkbox_event_handler(lv_event_t* e) + { + lv_obj_t* target = lv_event_get_target(e); + ViewChecklistWindow* vtw = (ViewChecklistWindow*)lv_obj_get_user_data(target); + + if (vtw) vtw->updateCheckboxes(); + } -#include "datastructs.h" + void buildBody(Window* window) override + { + if (openFile()) { + auto obj = window->getLvObj(); + lv_obj_add_flag( + obj, LV_OBJ_FLAG_SCROLLABLE | LV_OBJ_FLAG_SCROLL_WITH_ARROW | + LV_OBJ_FLAG_SCROLL_MOMENTUM | LV_OBJ_FLAG_CLICK_FOCUSABLE); + lv_obj_set_scrollbar_mode(obj, LV_SCROLLBAR_MODE_AUTO); + // prevents resetting the group's edit mode + lv_obj_clear_flag(obj, LV_OBJ_FLAG_CLICK_FOCUSABLE); + + lv_obj_set_layout(obj, LV_LAYOUT_FLEX); + lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_COLUMN); + lv_obj_set_style_pad_all(obj, 3, LV_PART_MAIN); + lv_obj_set_style_pad_row(obj, 0, LV_PART_MAIN); + + auto g = lv_group_get_default(); + + checkBoxes.clear(); + + size_t cur = 0; + + for(int i=0; i