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

Interactive/progressive checklist #1417

Closed
wants to merge 30 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
03cb9ea
initial version of clickable checklist
piotrva Jan 11, 2022
7a3da5a
do not display checkboxes for empty lines if checklist is shorter tha…
piotrva Jan 11, 2022
8755465
remove checklist exit after completing it
piotrva Jan 11, 2022
8a812e8
repair translation.py script to correctly process utf-8 files
piotrva Jan 11, 2022
9d89732
menu entry to enable and disable interactive checklist
piotrva Jan 11, 2022
a32f418
only when complete interactive checklist is closed
piotrva Jan 12, 2022
153fd8a
config updated & not display checkboxes when entered from "View Notes"
piotrva Jan 12, 2022
f69f674
corrected handling of padding bits in ModelData structure
piotrva Jan 13, 2022
708aa86
add setup entry for colorlcd
piotrva Jan 16, 2022
9fc8885
fix scrolling of checklist when having exactly number of lines screen…
piotrva Jan 22, 2022
d8002c2
initial interactive checklist for colorlcd
piotrva Jan 22, 2022
1039b13
auto scroll the checklist
piotrva Jan 23, 2022
8af8cf0
do not make interactive checkist when loaded from menu
piotrva Jan 23, 2022
71a0413
checklist enter and exit conditions fixed
piotrva Jan 23, 2022
a34fa57
remove unused code
piotrva Jan 23, 2022
dfe0e1d
Merge branch 'main' of https://github.com/EdgeTX/edgetx into bw-progr…
piotrva Jan 23, 2022
72da66b
libopenui updte
piotrva Jan 23, 2022
0c7ec60
remove debug settings override
piotrva Jan 23, 2022
da01b88
Merge branch 'main' of https://github.com/EdgeTX/edgetx into bw-progr…
piotrva Jan 27, 2022
b4e65cd
fix datastruct size after merge
piotrva Jan 27, 2022
086f144
Companion support for interactive checklist
piotrva Jan 27, 2022
4f11cd8
mark checklist lines as non-checkable with '=' for B&W radios
piotrva Jan 30, 2022
75aee91
correctly displaying checkboxes but not updating
piotrva Jan 30, 2022
110a4b8
fixed updating checkboxes
piotrva Jan 30, 2022
71d8d87
corrected checkbox hiding
piotrva Jan 30, 2022
9a8c4c9
hiding non-checkable lines
piotrva Jan 30, 2022
c050ef8
correct colorlcd display with non-checkable items
piotrva Jan 30, 2022
1454ea7
Process only items visible on screen
piotrva Jan 30, 2022
4f05cd6
Merge branch 'main' of https://github.com/EdgeTX/edgetx into bw-progr…
piotrva Jan 30, 2022
3bb0b23
Merge branch 'main' into bw-progressive-checklist
piotrva Jun 4, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions companion/src/firmwares/edgetx/yaml_modeldata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,7 @@ Node convert<ModelData>::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)) {
Expand Down Expand Up @@ -1012,6 +1013,7 @@ bool convert<ModelData>::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;
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 @@ -131,6 +131,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];
Expand Down
7 changes: 7 additions & 0 deletions companion/src/modeledit/setup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1659,6 +1659,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);

Expand Down Expand Up @@ -1806,6 +1807,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;
Expand Down
1 change: 1 addition & 0 deletions companion/src/modeledit/setup.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,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);
Expand Down
10 changes: 10 additions & 0 deletions companion/src/modeledit/setup.ui
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,16 @@
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QCheckBox" name="checklistInteractive">
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
<string>Interactive Checklist</string>
</property>
</widget>
</item>
<item row="3" column="4">
<widget class="QLabel" name="label_jitterFilter">
<property name="font">
Expand Down
3 changes: 2 additions & 1 deletion radio/src/datastructs_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -643,8 +643,9 @@ PACK(struct ModelData {
uint8_t extendedLimits:1;
uint8_t extendedTrims:1;
uint8_t throttleReversed:1;
uint8_t checklistInteractive:1;
uint8_t enableCustomThrottleWarning:1;
uint8_t spare3:7 SKIP;
uint8_t spare3:6 SKIP;
int8_t customThrottleWarningPosition;
BeepANACenter beepANACenter;
MixData mixData[MAX_MIXERS] NO_IDX;
Expand Down
6 changes: 6 additions & 0 deletions radio/src/gui/128x64/model_setup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,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,
Expand Down Expand Up @@ -450,6 +451,7 @@ void menuModelSetup(event_t event)

LABEL(PreflightCheck),
0, // Checklist
0, // Checklist interactive mode
0, // Throttle warning
0, // Custom position for throttle warning enable
0, // Custom position for throttle warning value
Expand Down Expand Up @@ -751,6 +753,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.checklistInteractive = editCheckBox(g_model.checklistInteractive, 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);
Expand Down
6 changes: 6 additions & 0 deletions radio/src/gui/212x64/model_setup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,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,
Expand Down Expand Up @@ -394,6 +395,7 @@ void menuModelSetup(event_t event)

LABEL(PreflightCheck),
0, // Checklist
0, // Checklist interactive mode
0, // Throttle warning
0, // Custom position for throttle warning enable
0, // Custom position for throttle warning value
Expand Down Expand Up @@ -661,6 +663,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.checklistInteractive = editCheckBox(g_model.checklistInteractive, 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);
Expand Down
5 changes: 5 additions & 0 deletions radio/src/gui/colorlcd/model_setup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1522,6 +1522,11 @@ void ModelSetupPage::build(FormWindow * window)
new CheckBox(window, grid.getFieldSlot(), GET_SET_DEFAULT(g_model.displayChecklist));
grid.nextLine();

// Interactive checklist
new StaticText(window, grid.getLabelSlot(true), STR_CHECKLIST_INTERACTIVE, 0, COLOR_THEME_PRIMARY1);
new CheckBox(window, grid.getFieldSlot(), GET_SET_DEFAULT(g_model.checklistInteractive));
grid.nextLine();

// Throttle warning
new StaticText(window, grid.getLabelSlot(true), STR_THROTTLE_WARNING, 0, COLOR_THEME_PRIMARY1);
new CheckBox(window, grid.getFieldSlot(), GET_SET_INVERTED(g_model.disableThrottleWarning));
Expand Down
2 changes: 1 addition & 1 deletion radio/src/gui/colorlcd/view_main_menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ ViewMainMenu::ViewMainMenu(Window* parent) :
if (modelHasNotes()) {
carousel->addButton(ICON_MODEL_NOTES, STR_MAIN_MENU_MODEL_NOTES, [=]() -> uint8_t {
deleteLater();
readModelNotes();
readModelNotes(true);
return 0;
});
}
Expand Down
146 changes: 117 additions & 29 deletions radio/src/gui/colorlcd/view_text.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,60 @@
case EVT_KEY_BREAK(KEY_PGUP): \
case EVT_KEY_BREAK(KEY_UP)

#define CASE_EVT_START \
case EVT_ENTRY: \
case EVT_KEY_BREAK(KEY_ENTER): \
case EVT_KEY_BREAK(KEY_TELEM)
constexpr char NON_CHECKABLE_PREFIX = '=';

class CheckBoxStatic : public Window {
public:
CheckBoxStatic(Window * parent, const rect_t & rect, std::function<bool()> getChecked,
std::function<bool()> getFocus, std::function<bool()> getVisible, WindowFlags flags = 0) :
Window(parent, rect, flags, 0),
_getChecked(getChecked),
_getFocus(getFocus),
_getVisible(getVisible)
{
coord_t size = min(rect.w, rect.h);
setWidth(size);
setHeight(size);
_checked = _getChecked();
_focus = _getFocus();
_visible = _getVisible();
}

#if defined(DEBUG_WINDOWS)
std::string getName() const override
{
return "CheckBoxStatic";
}
#endif

void paint(BitmapBuffer * dc)
{
if(_visible)
theme->drawCheckBox(dc, _checked, 0, FIELD_PADDING_TOP, _focus);
}

void checkEvents() override
{
Window::checkEvents();
bool checked = _getChecked();
bool focus = _getFocus();
bool visible = _getVisible();
if (checked != _checked || focus != _focus || visible != _visible) {
_checked = checked;
_focus = focus;
_visible = visible;
invalidate();
}
}

protected:
std::function<bool()> _getChecked;
std::function<bool()> _getFocus;
std::function<bool()> _getVisible;
bool _checked;
bool _focus;
bool _visible;
};

void ViewTextWindow::extractNameSansExt()
{
Expand All @@ -57,8 +107,9 @@ void ViewTextWindow::extractNameSansExt()

void ViewTextWindow::buildBody(Window *window)
{
GridLayout grid(window);
FormGridLayout grid(window->width());
grid.spacer();
grid.setLabelWidth(PAGE_LINE_HEIGHT + 3UL * PAGE_LINE_SPACING); // width of "first column" for checkboxes
int i;
FIL file;

Expand Down Expand Up @@ -98,11 +149,25 @@ void ViewTextWindow::buildBody(Window *window)
loadOneScreen(openFromEnd ? (maxLines - maxScreenLines) : 0);

for (i = 0; i < maxScreenLines; i++) {
new DynamicText(window, grid.getSlot(), [=]() {
std::string str =
(lines[i][0]) ? std::string(lines[i]) : std::string(" ");
return std::string(str);
});
if (g_model.checklistInteractive) {
if (!fromMenu) {
new CheckBoxStatic(window, grid.getLabelSlot(),
[=]() { return i < checklistPosition-(int)textVerticalOffset;},
[=]() { return i == checklistPosition-(int)textVerticalOffset;},
[=]() { return lines[i][0] && lines[i][0]!=NON_CHECKABLE_PREFIX;});
}
new DynamicText(window, grid.getFieldSlot(), [=]() {
std::string str =
(lines[i][0]) ? std::string(lines[i]).substr(lines[i][0]==NON_CHECKABLE_PREFIX ? 1 : 0, std::string::npos) : std::string(" ");
return std::string(str);
});
}
else {
new DynamicText(window, grid.getSlot(), [=]() {
std::string str = (lines[i][0]) ? std::string(lines[i]) : std::string(" ");
return std::string(str);
});
}
grid.nextLine();
}
}
Expand Down Expand Up @@ -149,14 +214,28 @@ void ViewTextWindow::checkEvents()
if (lineStep > (maxScreenLines >> 1)) lineStep = maxScreenLines >> 1;

switch (event) {
CASE_EVT_START:
textVerticalOffset = 0;
readLinesCount = 0;
sdReadTextFileBlock(fullPath.c_str(), readLinesCount);
case EVT_KEY_BREAK(KEY_ENTER):
// check if interactive checklist enabled and process only items displayed on screen (cannot mark item that is out of the screen)
if (g_model.checklistInteractive && !fromMenu && checklistPosition-(int)textVerticalOffset >= 0) {
if (checklistPosition < readLinesCount) {
if (checklistPosition-(int)textVerticalOffset < maxScreenLines) {
do{
++checklistPosition;
if (checklistPosition-(int)textVerticalOffset >= maxScreenLines-1 && textVerticalOffset + maxScreenLines < readLinesCount) {
++textVerticalOffset;
sdReadTextFileBlock(fullPath.c_str(), readLinesCount);
}
}while(checklistPosition < readLinesCount && lines[checklistPosition-(int)textVerticalOffset][0] == NON_CHECKABLE_PREFIX);
}
}
else {
Page::onEvent(EVT_KEY_BREAK(KEY_EXIT));
}
}
break;

CASE_EVT_KEY_NEXT_LINE:
if (textBottom && textVerticalOffset)
if(textVerticalOffset + maxScreenLines >= readLinesCount)
break;
else {
textVerticalOffset += lineStep;
Expand All @@ -175,10 +254,19 @@ void ViewTextWindow::checkEvents()

sdReadTextFileBlock(fullPath.c_str(), readLinesCount);
break;

default:

case EVT_KEY_FIRST(KEY_EXIT):
case EVT_KEY_LONG(KEY_EXIT):
case EVT_KEY_REPT(KEY_EXIT):
case EVT_KEY_BREAK(KEY_EXIT):
if (!(g_model.checklistInteractive && !fromMenu)) {
Page::onEvent(event);
break;
}
break;

default:
Page::onEvent(event);
break;
}
}
Page::checkEvents();
Expand All @@ -197,15 +285,14 @@ void ViewTextWindow::sdReadTextFileBlock(const char *filename, int &lines_count)
int result;
char c;
unsigned int sz = 0;
int line_length = 1;
int line_length = 0;
uint8_t escape = 0;
char escape_chars[4] = {0};
int current_line = 0;
textBottom = false;

for (int i = 0; i < maxScreenLines; i++) {
memclear(lines[i], maxLineLength + 1);
lines[i][0] = ' ';
}

result = f_open(&file, (TCHAR *)filename, FA_OPEN_EXISTING | FA_READ);
Expand All @@ -216,7 +303,7 @@ void ViewTextWindow::sdReadTextFileBlock(const char *filename, int &lines_count)
{
if (c == '\n' || line_length >= maxLineLength) {
++current_line;
line_length = 1;
line_length = 0;
escape = 0;
}
if (c != '\r' && c != '\n' && current_line >= textVerticalOffset &&
Expand Down Expand Up @@ -302,16 +389,17 @@ 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)
{
if (isFileAvailable(modelNotesName.c_str())) {
new ViewTextWindow(std::string(buf), modelNotesName, ICON_MODEL);
if (isFileAvailable(modelNotesName.c_str())) {
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();
Expand All @@ -321,10 +409,10 @@ void readModelNotes()
const char buf[] = {MODELS_PATH};
f_chdir((TCHAR *)buf);

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)
Expand All @@ -334,11 +422,11 @@ void readModelNotes()
if (index != std::string::npos) {
modelNotesName.erase(index);
modelNotesName.append(TEXT_EXT);
notesFound = openNotes(buf, modelNotesName);
notesFound = openNotes(buf, modelNotesName, fromMenu);
}
if (!notesFound) {
replaceSpaceWithUnderscore(modelNotesName);
notesFound = openNotes(buf, modelNotesName);
notesFound = openNotes(buf, modelNotesName, fromMenu);
}
}
#endif
Expand Down
Loading