Replaced focus handling with LVGL groups

This commit is contained in:
Raphael Coeffic
2022-06-11 15:38:08 +02:00
committed by Raphael Coeffic
parent 4af17b49c8
commit 4c8bb99e73
73 changed files with 701 additions and 792 deletions
+102 -81
View File
@@ -30,38 +30,102 @@ LvglWrapper* LvglWrapper::_instance = nullptr;
static lv_indev_drv_t touchDriver;
static lv_indev_drv_t keyboard_drv;
static lv_indev_drv_t rotaryDriver;
static lv_indev_t* rotaryDevice = nullptr;
static lv_indev_t* keyboardDevice = nullptr;
lv_group_t* inputGroup;
#if defined(HARDWARE_TOUCH)
static bool touchOccured = false;
bool getTouchOccured()
static lv_obj_t* get_focus_obj(lv_indev_t* indev)
{
return touchOccured;
lv_group_t * g = indev->group;
if(g == nullptr) return nullptr;
return lv_group_get_focused(g);
}
static TouchState lastState;
TouchState getLastTochState()
{
touchOccured = false;
return lastState;
}
#endif
static lv_indev_data_t kb_data_backup;
extern "C" void keyboardDriverRead(lv_indev_drv_t *drv, lv_indev_data_t *data)
static void backup_kb_data(lv_indev_data_t* data)
{
// if there is a keyboard event then call checkevents
memcpy(&kb_data_backup, data, sizeof(lv_indev_data_t));
}
static void copy_kb_data_backup(lv_indev_data_t* data)
{
memcpy(data, &kb_data_backup, sizeof(lv_indev_data_t));
}
constexpr event_t _KEY_PRESSED = _MSK_KEY_FLAGS & ~_MSK_KEY_BREAK;
static bool evt_to_indev_data(event_t evt, lv_indev_data_t *data)
{
event_t key = EVT_KEY_MASK(evt);
switch(key) {
case KEY_ENTER:
data->key = LV_KEY_ENTER;
break;
case KEY_EXIT:
data->key = LV_KEY_ESC;
break;
default:
// abort LVGL event
return false;
}
if (evt & _KEY_PRESSED) {
data->state = LV_INDEV_STATE_PRESSED;
} else {
data->state = LV_INDEV_STATE_RELEASED;
}
return true;
}
static void dispatch_kb_event(Window* w, event_t evt)
{
if (!w) return;
event_t key = EVT_KEY_MASK(evt);
if (evt == EVT_KEY_BREAK(KEY_ENTER)) {
w->onClicked();
} else if (evt == EVT_KEY_FIRST(KEY_EXIT)) {
w->onCancel();
} else if (key != KEY_ENTER /*&& key != KEY_EXIT*/) {
w->onEvent(evt);
}
}
static void keyboardDriverRead(lv_indev_drv_t *drv, lv_indev_data_t *data)
{
data->key = 0;
if (isEvent()) {
event_t evt = getWindowEvent();
auto focusWindow = Window::getFocus();
if (focusWindow) {
focusWindow->onEvent(evt);
} else {
// no focused item ?
auto obj = get_focus_obj(keyboardDevice);
if (!obj) {
auto w = Layer::back();
if (w) w->onEvent(evt);
dispatch_kb_event(w, evt);
backup_kb_data(data);
return;
}
// not an LVGL key ?
bool is_lvgl_evt = evt_to_indev_data(evt, data);
if (!is_lvgl_evt) {
auto w = (Window*)lv_obj_get_user_data(obj);
dispatch_kb_event(w, evt);
return;
}
backup_kb_data(data);
return;
}
// no event: send a copy of the last one
copy_kb_data_backup(data);
}
static void copy_ts_to_indev_data(const TouchState &st, lv_indev_data_t *data)
@@ -70,30 +134,27 @@ static void copy_ts_to_indev_data(const TouchState &st, lv_indev_data_t *data)
data->point.y = st.y;
}
static lv_indev_data_t indev_data_backup;
static lv_indev_data_t touch_data_backup;
static void backup_indev_data(lv_indev_data_t* data)
static void backup_touch_data(lv_indev_data_t* data)
{
memcpy(&indev_data_backup, data, sizeof(lv_indev_data_t));
memcpy(&touch_data_backup, data, sizeof(lv_indev_data_t));
}
static void copy_indev_data_backup(lv_indev_data_t* data)
static void copy_touch_data_backup(lv_indev_data_t* data)
{
memcpy(data, &indev_data_backup, sizeof(lv_indev_data_t));
memcpy(data, &touch_data_backup, sizeof(lv_indev_data_t));
}
extern "C" void touchDriverRead(lv_indev_drv_t *drv, lv_indev_data_t *data)
{
#if defined(HARDWARE_TOUCH)
if(!touchPanelEventOccured()) {
copy_indev_data_backup(data);
copy_touch_data_backup(data);
return;
}
touchOccured = true;
TouchState st = touchPanelRead();
lastState = st; // hack for now
if(st.event == TE_NONE) {
TRACE("TE_NONE");
} else if(st.event == TE_DOWN || st.event == TE_SLIDE) {
@@ -106,54 +167,20 @@ extern "C" void touchDriverRead(lv_indev_drv_t *drv, lv_indev_data_t *data)
copy_ts_to_indev_data(st, data);
}
backup_indev_data(data);
backup_touch_data(data);
#endif
}
event_t encoderEvent = 0;
bool newEncoderEvent = false;
lv_indev_state_t encoderState = LV_INDEV_STATE_RELEASED;
void lvglPushEncoderEvent(event_t& evt)
static void rotaryDriverRead(lv_indev_drv_t *drv, lv_indev_data_t *data)
{
if (evt != EVT_KEY_FIRST(KEY_ENTER) && evt != EVT_KEY_BREAK(KEY_ENTER) &&
evt != EVT_ROTARY_LEFT && evt != EVT_ROTARY_RIGHT)
return;
static rotenc_t prevPos = 0;
encoderEvent = evt;
evt = 0;
newEncoderEvent = true;
}
rotenc_t newPos = (ROTARY_ENCODER_NAVIGATION_VALUE / ROTARY_ENCODER_GRANULARITY);
auto diff = newPos - prevPos;
prevPos = newPos;
extern "C" void rotaryDriverRead(lv_indev_drv_t *drv, lv_indev_data_t *data)
{
data->enc_diff = 0;
if(newEncoderEvent)
{
switch(encoderEvent)
{
case EVT_KEY_FIRST(KEY_ENTER):
encoderState = LV_INDEV_STATE_PRESSED;
break;
case EVT_KEY_BREAK(KEY_ENTER):
encoderState = LV_INDEV_STATE_RELEASED;
break;
case EVT_KEY_FIRST(KEY_EXIT):
encoderState = LV_INDEV_STATE_PRESSED;
break;
case EVT_KEY_BREAK(KEY_EXIT):
encoderState = LV_INDEV_STATE_RELEASED;
break;
case EVT_ROTARY_LEFT:
data->enc_diff = -1;
break;
case EVT_ROTARY_RIGHT:
data->enc_diff = 1;
break;
}
}
newEncoderEvent = false;
data->state = encoderState;
data->enc_diff = (int16_t)diff;
data->state = LV_INDEV_STATE_RELEASED;
}
/**
@@ -172,27 +199,21 @@ static void init_lvgl_drivers()
// Register the driver and save the created display object
lcdInitDisplayDriver();
// add all lvgl object automatically to a input handling group
inputGroup = lv_group_create();
lv_group_set_default(inputGroup);
// Register the driver in LVGL and save the created input device object
lv_indev_drv_init(&touchDriver); /*Basic initialization*/
touchDriver.type = LV_INDEV_TYPE_POINTER; /*See below.*/
touchDriver.read_cb = touchDriverRead; /*See below.*/
lv_indev_drv_register(&touchDriver);
lv_indev_drv_init(&keyboard_drv);
keyboard_drv.type = LV_INDEV_TYPE_KEYPAD;
keyboard_drv.read_cb = keyboardDriverRead;
lv_indev_drv_register(&keyboard_drv);
lv_indev_drv_init(&rotaryDriver);
rotaryDriver.type = LV_INDEV_TYPE_ENCODER;
rotaryDriver.read_cb = rotaryDriverRead;
rotaryDevice = lv_indev_drv_register(&rotaryDriver);
lv_indev_set_group(rotaryDevice, inputGroup);
lv_indev_drv_init(&keyboard_drv);
keyboard_drv.type = LV_INDEV_TYPE_KEYPAD;
keyboard_drv.read_cb = keyboardDriverRead;
keyboardDevice = lv_indev_drv_register(&keyboard_drv);
}
// The theme code needs to go somewhere else (gui/colorlcd/themes/default.cpp?)
+1 -4
View File
@@ -25,10 +25,7 @@
#include <lvgl/lvgl.h>
#include "opentx_types.h"
extern lv_color_t makeLvColor(uint32_t colorFlags);
#if defined(HARDWARE_TOUCH)
extern TouchState getLastTochState();
#endif
lv_color_t makeLvColor(uint32_t colorFlags);
class LvglWidgetFactory;
typedef std::function<lv_obj_t *(lv_obj_t *parent)> LvObjConstructor;
+14 -14
View File
@@ -133,6 +133,11 @@ BindWaitDialog::BindWaitDialog(Window* parent, uint8_t moduleIdx,
setCloseHandler([=]() { moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; });
}
void BindWaitDialog::deleteLater(bool detach, bool trash)
{
Dialog::deleteLater(detach, trash);
}
void BindWaitDialog::checkEvents()
{
auto& bindInfo = getPXX2BindInformationBuffer();
@@ -178,12 +183,12 @@ void BindWaitDialog::checkEvents()
if (bindInfo.step == BIND_INIT && bindInfo.candidateReceiversCount > 0) {
// create RX choice dialog...
new BindRxChoiceMenu(parent, moduleIdx, receiverIdx);
// ... prevent module mode being reset to NORMAL before exiting
// prevent module mode being reset to NORMAL before exiting
setCloseHandler(nullptr);
deleteLater();
// ... and create RX choice dialog
new BindRxChoiceMenu(Layer::back(), moduleIdx, receiverIdx);
return;
}
@@ -328,11 +333,10 @@ RegisterDialog::RegisterDialog(Window* parent, uint8_t moduleIdx) :
this->deleteLater();
return 0;
});
exitButton->setFocus(SET_FOCUS_DEFAULT);
// exitButton->setFocus(SET_FOCUS_DEFAULT);
grid.nextLine();
grid.spacer(PAGE_PADDING);
FormField::link(exitButton, edit);
form->setHeight(grid.getWindowHeight());
content->adjustHeight();
@@ -364,10 +368,6 @@ void RegisterDialog::checkEvents()
return 0;
});
exitButton->setLeft(left() + rect.w + 10);
FormField::link(uid, rxName);
FormField::link(rxName, okButton);
FormField::link(okButton, exitButton);
okButton->setFocus(SET_FOCUS_DEFAULT);
} else if (modSetup.registerStep == REGISTER_OK) {
deleteLater();
POPUP_INFORMATION(STR_REG_OK);
@@ -393,7 +393,7 @@ ModuleOptions::ModuleOptions(Window* parent, uint8_t moduleIdx):
state = MO_ReadModuleSettings;
#endif
setCloseHandler([=]() { moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; });
setFocus();
// setFocus();
}
void ModuleOptions::checkEvents()
@@ -562,7 +562,7 @@ void ModuleOptions::update()
return 0;
});
exitButton->setFocus(SET_FOCUS_DEFAULT);
// exitButton->setFocus(SET_FOCUS_DEFAULT);
grid.nextLine();
grid.spacer(PAGE_PADDING);
@@ -607,7 +607,7 @@ RxOptions::RxOptions(Window* parent, uint8_t moduleIdx, uint8_t rxIdx):
}
#endif
setCloseHandler([=]() { moduleState[moduleIdx].mode = MODULE_MODE_NORMAL; });
setFocus();
// setFocus();
}
void RxOptions::checkEvents()
@@ -864,7 +864,7 @@ void RxOptions::update()
return 0;
});
exitButton->setFocus(SET_FOCUS_DEFAULT);
// exitButton->setFocus(SET_FOCUS_DEFAULT);
grid.nextLine();
grid.spacer(PAGE_PADDING);
+2
View File
@@ -48,6 +48,8 @@ class BindWaitDialog : public Dialog
BindWaitDialog(Window* parent, uint8_t moduleIdx, uint8_t receiverIdx);
void checkEvents() override;
void deleteLater(bool detach = true, bool trash = true) override;
protected:
uint8_t moduleIdx;
uint8_t receiverIdx;
+2 -2
View File
@@ -187,7 +187,7 @@ ColorEditor::ColorEditor(FormGroup *window, const rect_t rect, uint32_t color,
void ColorEditor::setNextFocusBar()
{
_focusBar = (_focusBar + 1) % MAX_BARS;
setFocus();
// setFocus();
invalidate();
}
@@ -262,7 +262,7 @@ bool ColorEditor::onTouchStart(coord_t x, coord_t y)
_colorType->barInfo[i].value = value;
bFound = true;
_focusBar = i;
setFocus();
// setFocus();
} else {
_colorType->barInfo[i].sliding = false;
}
@@ -226,7 +226,6 @@ ColorEditorPopup::ColorEditorPopup(Window *window, std::function<uint32_t ()> ge
_setValue(rgb);
});
content->setFocus();
bringToTop();
content->setTitle(STR_COLOR_PICKER);
killAllEvents();
+1 -1
View File
@@ -49,5 +49,5 @@ ConfirmDialog::ConfirmDialog(Window * parent, const char * title, const char * m
return 0;
});
noButton->setFocus(SET_FOCUS_DEFAULT);
// noButton->setFocus(SET_FOCUS_DEFAULT);
}
+2 -2
View File
@@ -126,7 +126,7 @@ class ShutdownAnimation: public FormGroup
{
Layer::push(this);
bringToTop();
setFocus(SET_FOCUS_DEFAULT);
// setFocus(SET_FOCUS_DEFAULT);
}
#if defined(DEBUG_WINDOWS)
@@ -244,7 +244,7 @@ class FatalErrorScreen: public FormGroup
{
Layer::push(this);
bringToTop();
setFocus(SET_FOCUS_DEFAULT);
// setFocus(SET_FOCUS_DEFAULT);
}
#if defined(DEBUG_WINDOWS)
+30
View File
@@ -29,6 +29,29 @@
#define CELL_CTRL_DIR LV_TABLE_CELL_CTRL_CUSTOM_1
#define CELL_CTRL_FILE LV_TABLE_CELL_CTRL_CUSTOM_2
static void fb_event(lv_event_t* e)
{
static bool nested = false;
if (nested) return;
lv_event_code_t code = lv_event_get_code(e);
lv_obj_t* obj = lv_event_get_target(e);
if (!obj) return;
lv_group_t* g = (lv_group_t*)lv_obj_get_group(obj);
if (!g) return;
if (code == LV_EVENT_FOCUSED) {
lv_group_set_editing(g, true);
} else if (code == LV_EVENT_DEFOCUSED) {
// hack to get rid 'FOCUSED' event sent
// when calling 'lv_group_set_editing'
nested = true;
lv_group_set_editing(g, false);
nested = false;
}
}
static const char* getFullPath(const char* filename)
{
static char full_path[FF_MAX_LFN + 1];
@@ -82,10 +105,17 @@ static int scan_files(std::list<std::string>& files,
FileBrowser::FileBrowser(Window* parent, const rect_t& rect, const char* dir) :
TableField(parent, rect)
{
lv_obj_add_event_cb(lvobj, fb_event, LV_EVENT_ALL, nullptr);
setColumnCount(1);
setColumnWidth(0, rect.w);
f_chdir(dir);
if (lv_obj_has_state(lvobj, LV_STATE_FOCUSED)) {
lv_group_t* g = (lv_group_t*)lv_obj_get_group(lvobj);
if (g) lv_group_set_editing(g, true);
}
}
void FileBrowser::setFileAction(FileAction fct) { fileAction = std::move(fct); }
+13 -14
View File
@@ -37,17 +37,21 @@ FullScreenDialog::FullScreenDialog(
{
Layer::push(this);
#if defined(HARDWARE_TOUCH)
// TODO: if 'confirmHandler':
// -> add a confirm / cancel button
//
#if defined(HARDWARE_TOUCH) && 0
new FabButton(this, LCD_W - (FAB_BUTTON_SIZE + PAGE_PADDING),
LCD_H - (FAB_BUTTON_SIZE + PAGE_PADDING), ICON_NEXT,
[=]() -> uint8_t {
deleteLater();
if (confirmHandler) confirmHandler();
return 0;
});
#endif
bringToTop();
setFocus(SET_FOCUS_DEFAULT);
// setFocus(SET_FOCUS_DEFAULT);
}
void FullScreenDialog::paint(BitmapBuffer * dc)
@@ -107,21 +111,16 @@ void FullScreenDialog::paint(BitmapBuffer * dc)
}
}
#if defined(HARDWARE_KEYS)
void FullScreenDialog::onEvent(event_t event)
void FullScreenDialog::onClicked()
{
TRACE_WINDOWS("%s received event 0x%X", getWindowDebugString().c_str(), event);
if (confirmHandler) confirmHandler();
deleteLater();
}
if (event == EVT_KEY_BREAK(KEY_ENTER)) {
deleteLater();
if (confirmHandler)
confirmHandler();
}
else if (event == EVT_KEY_BREAK(KEY_EXIT)) {
deleteLater();
}
void FullScreenDialog::onCancel()
{
deleteLater();
}
#endif
#if defined(HARDWARE_TOUCH)
bool FullScreenDialog::onTouchStart(coord_t x, coord_t y)
+3 -3
View File
@@ -54,9 +54,9 @@ class FullScreenDialog : public FormGroup
void paint(BitmapBuffer * dc) override;
#if defined(HARDWARE_KEYS)
void onEvent(event_t event) override;
#endif
// void onEvent(event_t event) override;
void onClicked() override;
void onCancel() override;
#if defined(HARDWARE_TOUCH)
bool onTouchStart(coord_t x, coord_t y) override;
+4 -3
View File
@@ -38,7 +38,7 @@ class GVarNumberEdit : public FormGroup
std::function<void(int32_t)> setValue,
WindowFlags windowFlags = 0, LcdFlags textFlags = 0,
int32_t voffset = 0) :
FormGroup(parent, rect, FORWARD_SCROLL | FORM_FORWARD_FOCUS),
FormGroup(parent, rect, FORWARD_SCROLL /*| FORM_FORWARD_FOCUS*/),
vmin(vmin),
vmax(vmax),
voffset(voffset),
@@ -73,9 +73,10 @@ class GVarNumberEdit : public FormGroup
void onEvent(event_t event) override
{
if (event == EVT_KEY_LONG(KEY_ENTER)) {
killEvents(event);
// TODO: check this...
// killEvents(event);
switchGVarMode();
field->setFocus(SET_FOCUS_DEFAULT);
// field->setFocus(SET_FOCUS_DEFAULT);
} else {
FormGroup::onEvent(event);
}
+1 -1
View File
@@ -130,7 +130,7 @@ void loadCustomScreens()
viewMain->setCurrentMainView(0);
viewMain->updateTopbarVisibility();
viewMain->setFocus();
// viewMain->setFocus();
}
//
+3 -3
View File
@@ -249,9 +249,9 @@ bool ListBase::onTouchEnd(coord_t x, coord_t y)
duration10ms = 0;
if (!hasFocus()) {
setFocus(SET_FOCUS_DEFAULT);
}
// if (!hasFocus()) {
// setFocus(SET_FOCUS_DEFAULT);
// }
if (pressHandler != nullptr) {
pressHandler(0);
+5 -18
View File
@@ -34,18 +34,11 @@ MessageDialog::MessageDialog(Window* parent, const char* title,
width(), PAGE_LINE_HEIGHT},
info, 0, CENTERED);
setCloseWhenClickOutside(true);
setFocus();
}
void MessageDialog::onEvent(event_t event)
void MessageDialog::onClicked()
{
#if defined(HARDWARE_KEYS)
if (event == EVT_KEY_BREAK(KEY_ENTER)) {
deleteLater();
return;
}
#endif
Dialog::onEvent(event);
deleteLater();
}
DynamicMessageDialog::DynamicMessageDialog(
@@ -65,17 +58,11 @@ DynamicMessageDialog::DynamicMessageDialog(
this,
{0, 30 + coord_t(height() - PAGE_LINE_HEIGHT) / 2, width(), lineHeight},
textHandler, textFlags);
setCloseWhenClickOutside(true);
setFocus();
}
void DynamicMessageDialog::onEvent(event_t event)
void DynamicMessageDialog::onClicked()
{
#if defined(HARDWARE_KEYS)
if (event == EVT_KEY_BREAK(KEY_ENTER)) {
deleteLater();
return;
}
#endif
Dialog::onEvent(event);
deleteLater();
}
+2 -2
View File
@@ -40,7 +40,7 @@ class MessageDialog : public Dialog
std::string getName() const override { return "MessageDialog"; }
#endif
void onEvent(event_t event) override;
void onClicked() override;
};
class DynamicMessageDialog : public Dialog
@@ -61,5 +61,5 @@ class DynamicMessageDialog : public Dialog
std::string getName() const override { return "DynamicMessageDialog"; }
#endif
void onEvent(event_t event) override;
void onClicked() override;
};
+6 -6
View File
@@ -386,12 +386,12 @@ void ModelCurvesPage::build(FormWindow * window, int8_t focusIndex)
txt->invalidate();
});
if (focusIndex == index) {
button->setFocus(SET_FOCUS_DEFAULT);
txt->setBackgroundColor(COLOR_THEME_FOCUS);
txt->setTextFlags(COLOR_THEME_PRIMARY2 | CENTERED);
txt->invalidate();
}
// if (focusIndex == index) {
// button->setFocus(SET_FOCUS_DEFAULT);
// txt->setBackgroundColor(COLOR_THEME_FOCUS);
// txt->setTextFlags(COLOR_THEME_PRIMARY2 | CENTERED);
// txt->invalidate();
// }
txt->setHeight(button->height());
grid.spacer(button->height() + 5);
+3 -3
View File
@@ -144,7 +144,7 @@ struct FMTrimSettings : public Dialog {
content->setWidth(LCD_W * 0.8);
content->updateSize();
form->setFocus();
// form->setFocus();
}
};
@@ -159,7 +159,7 @@ FlightModeEdit::FlightModeEdit(uint8_t index) :
title, 0, COLOR_THEME_PRIMARY2);
auto form = new FormWindow(&body, rect_t{0, 0, body.width(), body.height()},
NO_FOCUS | FORM_FORWARD_FOCUS);
NO_FOCUS /*| FORM_FORWARD_FOCUS*/);
form->setFlexLayout();
FlexGridLayout grid(line_col_dsc, line_row_dsc, 2);
@@ -199,7 +199,7 @@ FlightModeEdit::FlightModeEdit(uint8_t index) :
return 0;
});
form->setFocus();
// form->setFocus();
}
class FlightModeBtn: public Button
+14 -12
View File
@@ -354,7 +354,9 @@ class InputEditWindow : public Page
SET_DIRTY();
updateCurveParamField(line);
});
curveParamField = new FormGroup(&body, grid.getFieldSlot(2, 1), FORM_FORWARD_FOCUS);
curveParamField = new FormGroup(&body, grid.getFieldSlot(2, 1)
// , FORM_FORWARD_FOCUS
);
updateCurveParamField(line);
grid.nextLine();
@@ -497,7 +499,7 @@ void ModelInputsPage::rebuild(FormWindow * window, int8_t focusIndex)
void ModelInputsPage::editInput(FormWindow * window, uint8_t input, uint8_t index)
{
Window::clearFocus();
// Window::clearFocus();
Window * editWindow = new InputEditWindow(input, index);
editWindow->setCloseHandler([=]() {
rebuild(window, index);
@@ -582,12 +584,12 @@ void ModelInputsPage::build(FormWindow *window, int8_t focusIndex)
if (focus) button->bringToTop();
});
if (focusIndex == inputIndex) {
button->setFocus(SET_FOCUS_DEFAULT);
txt->setBackgroundColor(COLOR_THEME_FOCUS);
txt->setTextFlags(COLOR_THEME_PRIMARY2 | LEFT);
txt->invalidate();
}
// if (focusIndex == inputIndex) {
// button->setFocus(SET_FOCUS_DEFAULT);
// txt->setBackgroundColor(COLOR_THEME_FOCUS);
// txt->setTextFlags(COLOR_THEME_PRIMARY2 | LEFT);
// txt->invalidate();
// }
grid.spacer(button->height() - 1);
++inputIndex;
++line;
@@ -635,10 +637,10 @@ void ModelInputsPage::build(FormWindow *window, int8_t focusIndex)
}
}
Window *focus = Window::getFocus();
if (focus) {
focus->bringToTop();
}
// Window *focus = Window::getFocus();
// if (focus) {
// focus->bringToTop();
// }
grid.nextLine();
@@ -244,7 +244,8 @@ class LogicalSwitchEditPage: public Page
functionChoice->setAvailableHandler(isLogicalSwitchFunctionAvailable);
grid.nextLine();
logicalSwitchOneWindow = new FormGroup(window, { 0, grid.getWindowHeight(), LCD_W, 0 }, FORM_FORWARD_FOCUS);
logicalSwitchOneWindow = new FormGroup(window, { 0, grid.getWindowHeight(), LCD_W, 0 }// , FORM_FORWARD_FOCUS
);
updateLogicalSwitchOneWindow();
grid.addWindow(logicalSwitchOneWindow);
}
@@ -433,12 +434,12 @@ void ModelLogicalSwitchesPage::build(FormWindow* window, int8_t focusIndex)
txt->invalidate();
});
if (focusIndex == i) {
button->setFocus(SET_FOCUS_DEFAULT);
txt->setBackgroundColor(COLOR_THEME_FOCUS);
txt->setTextFlags(COLOR_THEME_PRIMARY2 | CENTERED);
txt->invalidate();
}
// if (focusIndex == i) {
// button->setFocus(SET_FOCUS_DEFAULT);
// txt->setBackgroundColor(COLOR_THEME_FOCUS);
// txt->setTextFlags(COLOR_THEME_PRIMARY2 | CENTERED);
// txt->invalidate();
// }
txt->setHeight(button->height());
grid.spacer(button->height() + 5);
+14 -14
View File
@@ -174,7 +174,8 @@ class MixEditWindow : public Page
updateCurveParamField(mix);
});
curveParamField =
new FormGroup(&body, grid.getFieldSlot(2, 1), FORM_FORWARD_FOCUS);
new FormGroup(&body, grid.getFieldSlot(2, 1)// , FORM_FORWARD_FOCUS
);
updateCurveParamField(mix);
grid.nextLine();
@@ -388,7 +389,7 @@ void ModelMixesPage::rebuild(FormWindow * window, int8_t focusMixIndex)
void ModelMixesPage::editMix(FormWindow * window, uint8_t channel, uint8_t mixIndex)
{
Window::clearFocus();
// Window::clearFocus();
Window *editWindow = new MixEditWindow(channel, mixIndex);
editWindow->setCloseHandler([=]() {
int8_t newIndex = mixIndex;
@@ -514,13 +515,12 @@ void ModelMixesPage::build(FormWindow * window, int8_t focusMixIndex)
if (focus) button->bringToTop();
});
if (focusMixIndex == mixIndex) {
button->setFocus(SET_FOCUS_DEFAULT);
txt->setBackgroundColor(COLOR_THEME_FOCUS);
txt->setTextFlags(COLOR_THEME_PRIMARY2 | CENTERED);
txt->invalidate();
}
// if (focusMixIndex == mixIndex) {
// button->setFocus(SET_FOCUS_DEFAULT);
// txt->setBackgroundColor(COLOR_THEME_FOCUS);
// txt->setTextFlags(COLOR_THEME_PRIMARY2 | CENTERED);
// txt->invalidate();
// }
grid.spacer(button->height() - 1);
++mixIndex;
@@ -537,7 +537,7 @@ void ModelMixesPage::build(FormWindow * window, int8_t focusMixIndex)
else {
auto button = new TextButton(window, grid.getLabelSlot(),
getSourceString(MIXSRC_CH1 + ch));
if (focusMixIndex == mixIndex) button->setFocus(SET_FOCUS_DEFAULT);
// if (focusMixIndex == mixIndex) button->setFocus(SET_FOCUS_DEFAULT);
button->setPressHandler([=]() -> uint8_t {
button->bringToTop();
Menu *menu = new Menu(window);
@@ -567,10 +567,10 @@ void ModelMixesPage::build(FormWindow * window, int8_t focusMixIndex)
}
}
Window * focus = Window::getFocus();
if (focus) {
focus->bringToTop();
}
// Window * focus = Window::getFocus();
// if (focus) {
// focus->bringToTop();
// }
grid.nextLine();
+7 -7
View File
@@ -370,12 +370,12 @@ void ModelOutputsPage::build(FormWindow *window, int8_t focusChannel)
txt->invalidate();
});
if (focusChannel == ch) {
button->setFocus(SET_FOCUS_DEFAULT);
txt->setBackgroundColor(COLOR_THEME_FOCUS);
txt->setTextFlags(COLOR_THEME_PRIMARY2 | CENTERED);
txt->invalidate();
}
// if (focusChannel == ch) {
// button->setFocus(SET_FOCUS_DEFAULT);
// txt->setBackgroundColor(COLOR_THEME_FOCUS);
// txt->setTextFlags(COLOR_THEME_PRIMARY2 | CENTERED);
// txt->invalidate();
// }
txt->setHeight(button->height());
grid.spacer(button->height() + 5);
@@ -387,7 +387,7 @@ void ModelOutputsPage::build(FormWindow *window, int8_t focusChannel)
void ModelOutputsPage::editOutput(FormWindow *window, uint8_t channel)
{
Window::clearFocus();
// Window::clearFocus();
Window *editWindow = new OutputEditWindow(channel);
editWindow->setCloseHandler([=]() { rebuild(window, channel); });
}
+22 -18
View File
@@ -451,7 +451,8 @@ class ModelCategoryPageBody : public FormWindow
public:
ModelCategoryPageBody(FormWindow *parent, const rect_t &rect,
ModelsCategory *category) :
FormWindow(parent, rect, FORM_FORWARD_FOCUS), category(category)
FormWindow(parent, rect//, FORM_FORWARD_FOCUS
), category(category)
{
update();
}
@@ -577,9 +578,10 @@ class ModelCategoryPageBody : public FormWindow
});
});
}
} else {
button->setFocus(SET_FOCUS_DEFAULT);
}
// else {
// button->setFocus(SET_FOCUS_DEFAULT);
// }
return 1;
});
@@ -601,10 +603,12 @@ class ModelCategoryPageBody : public FormWindow
y += MODEL_SELECT_CELL_HEIGHT + MODEL_CELL_PADDING;
}
if (category->empty()) {
setFocus();
} else if (selectButton) {
selectButton->setFocus();
// if (category->empty()) {
// setFocus();
// } else
if (selectButton) {
lv_group_focus_obj(selectButton->getLvObj());
// selectButton->setFocus();
}
}
@@ -636,17 +640,17 @@ class ModelCategoryPageBody : public FormWindow
#endif
void setFocus(uint8_t flag = SET_FOCUS_DEFAULT,
Window *from = nullptr) override
{
if (category->empty()) {
// use Window::setFocus() to avoid forwarding focus to nowhere
// this crashes currently in libopenui
Window::setFocus(flag, from);
} else {
FormWindow::setFocus(flag, from);
}
}
// void setFocus(uint8_t flag = SET_FOCUS_DEFAULT,
// Window *from = nullptr) override
// {
// if (category->empty()) {
// // use Window::setFocus() to avoid forwarding focus to nowhere
// // this crashes currently in libopenui
// Window::setFocus(flag, from);
// } else {
// FormWindow::setFocus(flag, from);
// }
// }
protected:
ModelsCategory *category;
+1 -1
View File
@@ -191,7 +191,7 @@ void SubScreenButtonMatrix::onPress(uint8_t btn_id)
break;
}
if (w) w->setFocus();
// if (w) w->setFocus();
}
bool SubScreenButtonMatrix::isActive(uint8_t btn_id)
+5 -4
View File
@@ -411,7 +411,8 @@ class SensorEditWindow : public Page {
grid.nextLine();
sensorParametersWindow = new FormGroup(window, {0, grid.getWindowHeight(), LCD_W, 0},
FORM_FORWARD_FOCUS | FORM_NO_BORDER
// FORM_FORWARD_FOCUS |
FORM_NO_BORDER
| FORWARD_SCROLL);
updateSensorParametersWindow();
grid.addWindow(sensorParametersWindow);
@@ -544,9 +545,9 @@ void ModelTelemetryPage::build(FormWindow * window, int8_t focusSensorIndex)
});
if (focusSensorIndex == idx) {
button->setFocus(SET_FOCUS_DEFAULT);
}
// if (focusSensorIndex == idx) {
// button->setFocus(SET_FOCUS_DEFAULT);
// }
grid.nextLine();
}
}
+5 -5
View File
@@ -63,7 +63,7 @@ class ModuleWindow : public FormGroup
ModuleWindow::ModuleWindow(FormWindow *parent, const rect_t &rect,
uint8_t moduleIdx) :
FormGroup(parent, rect, FORWARD_SCROLL | NO_FOCUS | FORM_FORWARD_FOCUS),
FormGroup(parent, rect, FORWARD_SCROLL | NO_FOCUS /*| FORM_FORWARD_FOCUS*/),
moduleIdx(moduleIdx)
{
update();
@@ -306,7 +306,7 @@ void ModuleWindow::update()
resetMultiProtocolsOptions(moduleIdx);
SET_DIRTY();
// update();
if (mmSubProto != nullptr) mmSubProto->setFocus(SET_FOCUS_DEFAULT);
// if (mmSubProto != nullptr) mmSubProto->setFocus(SET_FOCUS_DEFAULT);
});
}
grid.nextLine();
@@ -639,7 +639,7 @@ void ModuleWindow::update()
g_model.moduleData[moduleIdx].failsafeMode = newValue;
SET_DIRTY();
// update();
failSafeChoice->setFocus(SET_FOCUS_DEFAULT);
// failSafeChoice->setFocus(SET_FOCUS_DEFAULT);
});
if (g_model.moduleData[moduleIdx].failsafeMode == FAILSAFE_CUSTOM) {
new TextButton(this, grid.getFieldSlot(2, 1), STR_SET, [=]() -> uint8_t {
@@ -846,8 +846,8 @@ void ModuleSubTypeChoice::update()
}
#if defined(PXX2)
else if (isModulePXX2(moduleIdx)) {
setMin(MODULE_SUBTYPE_R9M_FCC);
setMax(MODULE_SUBTYPE_R9M_LAST);
setMin(MODULE_SUBTYPE_ISRM_PXX2_ACCESS);
setMax(MODULE_SUBTYPE_ISRM_PXX2_ACCST_D16);
setValues(STR_ISRM_RF_PROTOCOLS);
setGetValueHandler(GET_DEFAULT(md->subType));
setSetValueHandler(SET_DEFAULT(md->subType));
+1 -1
View File
@@ -45,7 +45,7 @@ RfScanDialog::RfScanDialog(Window* parent, MultiRfProtocols* protos,
{
// disable canceling dialog
setCloseWhenClickOutside(false);
setFocus();
// setFocus();
}
void RfScanDialog::showProgress()
+9 -29
View File
@@ -44,13 +44,17 @@ void PageHeader::paint(BitmapBuffer * dc)
MENU_HEADER_HEIGHT, COLOR_THEME_SECONDARY1);
}
static constexpr rect_t _get_body_rect()
{
return { 0, MENU_HEADER_HEIGHT, LCD_W, LCD_H - MENU_HEADER_HEIGHT };
}
Page::Page(unsigned icon):
Window(MainWindow::instance(), {0, 0, LCD_W, LCD_H}, OPAQUE),
header(this, icon),
body(this, { 0, MENU_HEADER_HEIGHT, LCD_W, LCD_H - MENU_HEADER_HEIGHT }, FORM_FORWARD_FOCUS)
body(this, _get_body_rect(), FORM_FORWARD_FOCUS)
{
Layer::push(this);
clearFocus();
}
void Page::deleteLater(bool detach, bool trash)
@@ -59,44 +63,20 @@ void Page::deleteLater(bool detach, bool trash)
header.deleteLater(true, false);
body.deleteLater(true, false);
#if defined(HARDWARE_TOUCH)
Keyboard::hide();
#endif
Window::deleteLater(detach, trash);
}
void Page::setFocus(uint8_t flag, Window * from)
{
body.setFocus(flag, from);
}
void Page::paint(BitmapBuffer * dc)
{
dc->clear(COLOR_THEME_SECONDARY3);
}
#if defined(HARDWARE_KEYS)
void Page::onEvent(event_t event)
void Page::onCancel()
{
TRACE_WINDOWS("%s received event 0x%X", getWindowDebugString().c_str(), event);
if (event == EVT_KEY_LONG(KEY_EXIT) || event == EVT_KEY_BREAK(KEY_EXIT)) {
killEvents(event);
deleteLater();
}
deleteLater();
}
#endif
#if defined(HARDWARE_TOUCH)
bool Page::onTouchEnd(coord_t x, coord_t y)
void Page::onClicked()
{
#if defined (SOFTWARE_KEYBOARD)
Keyboard::hide();
#endif
Window::onTouchEnd(x, y);
return true;
}
#endif
+25 -75
View File
@@ -27,100 +27,50 @@
class Page;
class PageHeader: public FormGroup
class PageHeader : public FormGroup
{
public:
PageHeader(Page * parent, uint8_t icon);
public:
PageHeader(Page* parent, uint8_t icon);
#if defined(HARDWARE_TOUCH)
void deleteLater(bool detach = true, bool trash = true) override
{
if (_deleted)
return;
void deleteLater(bool detach = true, bool trash = true) override
{
if (_deleted) return;
back.deleteLater(true, false);
FormGroup::deleteLater(detach, trash);
}
back.deleteLater(true, false);
FormGroup::deleteLater(detach, trash);
}
#endif
void onEvent(event_t event) override
{
if (event == EVT_KEY_BREAK(KEY_PGUP)) {
onKeyPress();
FormField *focus = dynamic_cast<FormField *>(getFocus());
if (focus != nullptr && focus->getPreviousField()) {
focus->getPreviousField()->setFocus(SET_FOCUS_BACKWARD, focus);
}
} else if (event == EVT_KEY_BREAK(KEY_PGDN)) {
onKeyPress();
FormField *focus = dynamic_cast<FormField *>(getFocus());
if (focus != nullptr && focus->getNextField()) {
focus->getNextField()->setFocus(SET_FOCUS_FORWARD, focus);
}
} else if (event == EVT_KEY_FIRST(KEY_EXIT)) {
killEvents(event);
parent->deleteLater(); // destroy the Page
}
else {
FormGroup::onEvent(event);
}
}
void paint(BitmapBuffer* dc) override;
uint8_t getIcon() const { return icon; }
void paint(BitmapBuffer * dc) override;
uint8_t getIcon() const
{
return icon;
}
protected:
uint8_t icon;
protected:
uint8_t icon;
#if defined(HARDWARE_TOUCH)
Button back;
Button back;
#endif
};
class Page: public Window
class Page : public Window
{
public:
explicit Page(unsigned icon);
public:
explicit Page(unsigned icon);
void deleteLater(bool detach = true, bool trash = true) override;
void deleteLater(bool detach = true, bool trash = true) override;
#if defined(DEBUG_WINDOWS)
std::string getName() const override
{
return "Page";
}
std::string getName() const override { return "Page"; }
#endif
#if defined(HARDWARE_KEYS)
void onEvent(event_t event) override;
#endif
void onCancel() override;
void onClicked() override;
#if defined(HARDWARE_TOUCH)
bool onTouchStart(coord_t x, coord_t y) override
{
Window::onTouchStart(x, y);
return true;
}
void paint(BitmapBuffer* dc) override;
bool onTouchEnd(coord_t x, coord_t y) override;
bool onTouchSlide(coord_t x, coord_t y, coord_t startX, coord_t startY, coord_t slideX, coord_t slideY) override
{
Window::onTouchSlide(x, y, startX, startY, slideX, slideY);
return true;
}
#endif
void setFocus(uint8_t flag = SET_FOCUS_DEFAULT, Window * from = nullptr) override;
void paint(BitmapBuffer * dc) override;
protected:
PageHeader header;
FormWindow body;
protected:
PageHeader header;
FormWindow body;
};
#endif // _PAGE_H_
+9 -13
View File
@@ -63,7 +63,6 @@ RadioCalibrationPage::RadioCalibrationPage(bool initial):
{
buildHeader(&header);
buildBody(&body);
Window::setFocus(SET_FOCUS_DEFAULT);
}
void RadioCalibrationPage::buildHeader(Window * window)
@@ -209,24 +208,21 @@ void RadioCalibrationPage::checkEvents()
}
}
#if defined(HARDWARE_KEYS)
void RadioCalibrationPage::onEvent(event_t event)
void RadioCalibrationPage::onClicked()
{
TRACE_WINDOWS("%s received event 0x%X", getWindowDebugString().c_str(), event);
nextStep();
}
if (event == EVT_KEY_BREAK(KEY_ENTER)) {
nextStep();
}
else if (event == EVT_KEY_BREAK(KEY_EXIT) && menuCalibrationState != CALIB_START) {
void RadioCalibrationPage::onCancel()
{
if (menuCalibrationState != CALIB_START &&
menuCalibrationState != CALIB_FINISHED) {
menuCalibrationState = CALIB_START;
text->setText(STR_MENUTOSTART);
}
else {
Page::onEvent(event);
} else {
Page::onCancel();
}
}
#endif
void RadioCalibrationPage::nextStep()
{
+2 -4
View File
@@ -28,10 +28,8 @@ class RadioCalibrationPage: public Page {
explicit RadioCalibrationPage(bool initial = false);
void checkEvents() override;
#if defined(HARDWARE_KEYS)
void onEvent(event_t event) override;
#endif
void onClicked() override;
void onCancel() override;
protected:
StaticText * text = nullptr;
+1 -1
View File
@@ -138,5 +138,5 @@ RadioKeyDiagsPage::RadioKeyDiagsPage() :
{
buildHeader(&header);
buildBody(&body);
setFocus(SET_FOCUS_DEFAULT);
// setFocus(SET_FOCUS_DEFAULT);
}
@@ -27,9 +27,10 @@ class GhostModuleConfigWindow: public Window
{
public:
GhostModuleConfigWindow(Window * parent, const rect_t & rect) :
Window(parent, rect, FORWARD_SCROLL | FORM_FORWARD_FOCUS | REFRESH_ALWAYS)
Window(parent, rect, FORWARD_SCROLL // | FORM_FORWARD_FOCUS
| REFRESH_ALWAYS)
{
setFocus(SET_FOCUS_DEFAULT);
// setFocus(SET_FOCUS_DEFAULT);
}
void paint(BitmapBuffer * dc) override
@@ -88,7 +89,7 @@ RadioGhostModuleConfig::RadioGhostModuleConfig(uint8_t moduleIdx) :
init();
buildHeader(&header);
buildBody(&body);
setFocus(SET_FOCUS_DEFAULT);
// setFocus(SET_FOCUS_DEFAULT);
#if defined(TRIMS_EMULATE_BUTTONS)
setTrimsAsButtons(true); // Use trim joysticks to operate menu (e.g. on NV14)
#endif
+22 -16
View File
@@ -119,7 +119,8 @@ class BluetoothConfigWindow : public FormGroup
{
public:
BluetoothConfigWindow(FormWindow * parent, const rect_t &rect) :
FormGroup(parent, rect, FORWARD_SCROLL | FORM_FORWARD_FOCUS)
FormGroup(parent, rect, FORWARD_SCROLL // | FORM_FORWARD_FOCUS
)
{
update();
}
@@ -154,7 +155,7 @@ class BluetoothConfigWindow : public FormGroup
g_eeGeneral.bluetoothMode = newValue;
update();
SET_DIRTY();
btMode->setFocus(SET_FOCUS_DEFAULT);
// btMode->setFocus(SET_FOCUS_DEFAULT);
modechoiceopen = false;
},
&modechoiceopen);
@@ -201,7 +202,8 @@ class SerialConfigWindow : public FormGroup
{
public:
SerialConfigWindow(FormWindow *parent, const rect_t &rect) :
FormGroup(parent, rect, FORWARD_SCROLL | FORM_FORWARD_FOCUS)
FormGroup(parent, rect, FORWARD_SCROLL // | FORM_FORWARD_FOCUS
)
{
update();
}
@@ -266,7 +268,8 @@ class SerialConfigWindow : public FormGroup
class InternalModuleWindow : public FormGroup {
public:
InternalModuleWindow(FormWindow *parent, const rect_t &rect) :
FormGroup(parent, rect, FORWARD_SCROLL | FORM_FORWARD_FOCUS)
FormGroup(parent, rect, FORWARD_SCROLL),
lastModule(g_eeGeneral.internalModule)
{
update();
}
@@ -350,10 +353,11 @@ void RadioHardwarePage::build(FormWindow * window)
new StaticText(window, grid.getLabelSlot(), STR_INPUTS, 0, COLOR_THEME_PRIMARY1 | FONT(BOLD));
auto calib = new TextButton(window, grid.getFieldSlot(), STR_CALIBRATION);
calib->setPressHandler([=]() -> uint8_t {
auto calibrationPage = new RadioCalibrationPage();
calibrationPage->setCloseHandler([=]() {
calib->setFocus(SET_FOCUS_DEFAULT);
});
// auto calibrationPage =
new RadioCalibrationPage();
// calibrationPage->setCloseHandler([=]() {
// calib->setFocus(SET_FOCUS_DEFAULT);
// });
return 0;
});
grid.nextLine();
@@ -495,19 +499,21 @@ void RadioHardwarePage::build(FormWindow * window)
new StaticText(window, grid.getLabelSlot(), STR_DEBUG, 0, COLOR_THEME_PRIMARY1 | FONT(BOLD));
auto debugAnas = new TextButton(window, grid.getFieldSlot(2, 0), STR_ANALOGS_BTN);
debugAnas->setPressHandler([=]() -> uint8_t {
auto debugAnalogsPage = new RadioAnalogsDiagsViewPageGroup();
debugAnalogsPage->setCloseHandler([=]() {
calib->setFocus(SET_FOCUS_DEFAULT);
});
// auto debugAnalogsPage =
new RadioAnalogsDiagsViewPageGroup();
// debugAnalogsPage->setCloseHandler([=]() {
// calib->setFocus(SET_FOCUS_DEFAULT);
// });
return 0;
});
auto debugKeys = new TextButton(window, grid.getFieldSlot(2, 1), STR_KEYS_BTN);
debugKeys->setPressHandler([=]() -> uint8_t {
auto debugKeysPage = new RadioKeyDiagsPage();
debugKeysPage->setCloseHandler([=]() {
calib->setFocus(SET_FOCUS_DEFAULT);
});
// auto debugKeysPage =
new RadioKeyDiagsPage();
// debugKeysPage->setCloseHandler([=]() {
// calib->setFocus(SET_FOCUS_DEFAULT);
// });
return 0;
});
grid.nextLine();
+1 -1
View File
@@ -117,7 +117,7 @@ class FlashDialog: public FullScreenDialog
device(device),
progress(this, {LCD_W / 2 - 50, LCD_H / 2, 100, 15})
{
setFocus();
// setFocus();
}
void deleteLater(bool detach = true, bool trash = true) override
@@ -41,7 +41,8 @@ class SpectrumFooterWindow: public FormGroup
{
public:
SpectrumFooterWindow(FormGroup * parent, const rect_t & rect, int moduleIdx) :
FormGroup(parent, rect, FORM_FORWARD_FOCUS)
FormGroup(parent, rect// , FORM_FORWARD_FOCUS
)
{
FormGridLayout grid;
grid.spacer(4);
@@ -54,7 +55,7 @@ class SpectrumFooterWindow: public FormGroup
SET_VALUE(reusableBuffer.spectrumAnalyser.track, newValue * 1000000));
tracker->setSuffix("MHz");
tracker->setPrefix("T: ");
tracker->setFocus(SET_FOCUS_DEFAULT);
// tracker->setFocus(SET_FOCUS_DEFAULT);
if (isModuleMultimodule(moduleIdx)) {
char label[16];
+5 -29
View File
@@ -316,30 +316,6 @@ class ThemeEditPage : public Page
buildHeader(&header);
}
#if defined(HARDWARE_KEYS)
void onEvent(event_t event) override
{
if (event == EVT_KEY_BREAK(KEY_PGUP)) {
onKeyPress();
FormField *focus = dynamic_cast<FormField *>(getFocus());
if (focus != nullptr && focus->getPreviousField()) {
focus->getPreviousField()->setFocus(SET_FOCUS_BACKWARD, focus);
}
} else if (event == EVT_KEY_BREAK(KEY_PGDN)) {
onKeyPress();
FormField *focus = dynamic_cast<FormField *>(getFocus());
if (focus != nullptr && focus->getNextField()) {
focus->getNextField()->setFocus(SET_FOCUS_FORWARD, focus);
}
} else if (event == EVT_KEY_FIRST(KEY_EXIT)) {
killEvents(event);
deleteLater();
} else {
Window::onEvent(event);
}
}
#endif
void deleteLater(bool detach = true, bool trash = true) override
{
if (_dirty) {
@@ -398,10 +374,10 @@ class ThemeEditPage : public Page
}, BUTTON_BACKGROUND | OPAQUE, textFont);
// setup the prev next controls so save and details are in the mix
_cList->setNextField(_detailButton);
_cList->setPreviousField(_detailButton);
_detailButton->setNextField(_cList);
_detailButton->setPreviousField(_cList);
// _cList->setNextField(_detailButton);
// _cList->setPreviousField(_detailButton);
// _detailButton->setNextField(_cList);
// _detailButton->setPreviousField(_cList);
}
void buildBody(FormGroup *window)
@@ -459,7 +435,7 @@ bool isTopWindow(Window *window)
Window *parent = window->getParent();
if (parent != nullptr) {
parent = parent->getParent();
return parent == Layer::stack.back().main;
return parent == Layer::back();
}
return false;
}
+1 -1
View File
@@ -185,7 +185,7 @@ struct ToolButton : public TextButton {
void RadioToolsPage::rebuild(FormWindow * window)
{
window->clear();
Window::clearFocus();
// Window::clearFocus();
std::list<ToolEntry> tools;
+2 -1
View File
@@ -59,6 +59,7 @@ class VersionDialog: public Dialog
moduleState[EXTERNAL_MODULE].readModuleInformation(&reusableBuffer.hardwareAndSettings.modules[EXTERNAL_MODULE], PXX2_HW_INFO_TX_ID, PXX2_MAX_RECEIVERS_PER_MODULE - 1);
}
setCloseWhenClickOutside(true);
update();
}
@@ -84,7 +85,7 @@ class VersionDialog: public Dialog
this->deleteLater();
return 0;
});
exitButton->setFocus(SET_FOCUS_DEFAULT);
// exitButton->setFocus(SET_FOCUS_DEFAULT);
grid.nextLine();
grid.spacer(PAGE_PADDING);
+11 -11
View File
@@ -405,7 +405,8 @@ class SpecialFunctionEditPage : public Page
grid.nextLine();
specialFunctionOneWindow = new FormGroup(
window, {0, grid.getWindowHeight(), LCD_W, 0}, FORM_FORWARD_FOCUS);
window, {0, grid.getWindowHeight(), LCD_W, 0}// , FORM_FORWARD_FOCUS
);
updateSpecialFunctionOneWindow();
grid.addWindow(specialFunctionOneWindow);
}
@@ -634,7 +635,7 @@ void SpecialFunctionsPage::build(FormWindow *window, int8_t focusIndex)
grid.spacer(PAGE_PADDING);
grid.setLabelWidth(66);
Window::clearFocus();
// Window::clearFocus();
char s[] = "SFxx";
if (functions == g_eeGeneral.customFn) s[0] = 'G';
@@ -732,20 +733,19 @@ void SpecialFunctionsPage::build(FormWindow *window, int8_t focusIndex)
txt->invalidate();
});
if (focusIndex == i) {
txt->setBackgroundColor(COLOR_THEME_FOCUS);
txt->setTextFlags(COLOR_THEME_PRIMARY2 | CENTERED);
txt->invalidate();
}
// if (focusIndex == i) {
// txt->setBackgroundColor(COLOR_THEME_FOCUS);
// txt->setTextFlags(COLOR_THEME_PRIMARY2 | CENTERED);
// txt->invalidate();
// }
txt->setHeight(button->height());
grid.spacer(button->height() + 5);
}
if (focusIndex == i) { // fix focus #303
button->setFocus(SET_FOCUS_DEFAULT);
}
// if (focusIndex == i) { // fix focus #303
// button->setFocus(SET_FOCUS_DEFAULT);
// }
}
grid.nextLine();
+1 -2
View File
@@ -67,8 +67,7 @@ void drawSplash()
loadSplashImg = false;
if (splashImg == nullptr) {
splashImg =
BitmapBuffer::loadRamBitmap(__bmp_splash, sizeof(__bmp_splash));
splashImg = new LZ4Bitmap(BMP_RGB565, __bmp_splash);
}
splashScreen = window_create(nullptr);
+7 -2
View File
@@ -83,8 +83,7 @@ void StandaloneLuaWindow::attach()
Layer::push(this);
}
setFocus();
// setFocus();
}
void StandaloneLuaWindow::deleteLater(bool detach, bool trash)
@@ -154,6 +153,12 @@ void StandaloneLuaWindow::checkEvents()
luaLcdBuffer = nullptr;
}
void StandaloneLuaWindow::onCancel()
{
// do nothing: wait for long press to kill
// the script
}
#if defined(HARDWARE_KEYS)
void StandaloneLuaWindow::onEvent(event_t evt)
{
+1
View File
@@ -45,6 +45,7 @@ public:
void deleteLater(bool detach = true, bool trash = true) override;
void paint(BitmapBuffer* dc) override;
void checkEvents() override;
void onCancel() override;
#if defined(DEBUG_WINDOWS)
std::string getName() const override { return "StandaloneLuaWindow"; }
+33 -25
View File
@@ -33,10 +33,13 @@
#include <algorithm>
TabCarouselButton::TabCarouselButton(Window* parent, const rect_t& rect, std::vector<PageTab *>& tabs, uint8_t index,
std::function<uint8_t(void)> pressHandler,
WindowFlags flags) :
Button(parent, rect, std::move(pressHandler), flags), tabs(tabs), index(index)
TabCarouselButton::TabCarouselButton(Window* parent, const rect_t& rect,
std::vector<PageTab*>& tabs, uint8_t index,
std::function<uint8_t(void)> pressHandler,
WindowFlags flags) :
Button(parent, rect, std::move(pressHandler), flags, 0, window_create),
tabs(tabs),
index(index)
{
}
@@ -67,7 +70,8 @@ TabsGroupHeader::TabsGroupHeader(TabsGroup* parent, uint8_t icon) :
parent->deleteLater();
return 1;
},
NO_FOCUS | FORM_NO_BORDER),
NO_FOCUS | FORM_NO_BORDER,
0, window_create),
#endif
icon(icon),
carousel(this, parent)
@@ -77,7 +81,7 @@ TabsGroupHeader::TabsGroupHeader(TabsGroup* parent, uint8_t icon) :
void TabsGroupHeader::paint(BitmapBuffer* dc)
{
OpenTxTheme::instance()->drawPageHeaderBackground(dc, icon, title);
OpenTxTheme::instance()->drawPageHeaderBackground(dc, icon, title.c_str());
}
TabsCarousel::TabsCarousel(Window* parent, TabsGroup* menu) :
@@ -130,10 +134,15 @@ void TabsCarousel::paint(BitmapBuffer * dc)
{
}
static constexpr rect_t _get_body_rect()
{
return { 0, MENU_BODY_TOP, LCD_W, MENU_BODY_HEIGHT };
}
TabsGroup::TabsGroup(uint8_t icon):
Window(MainWindow::instance(), { 0, 0, LCD_W, LCD_H }, OPAQUE),
header(this, icon),
body(this, { 0, MENU_BODY_TOP, LCD_W, MENU_BODY_HEIGHT }, NO_FOCUS | FORM_FORWARD_FOCUS)
body(this, _get_body_rect(), NO_FOCUS | FORM_FORWARD_FOCUS)
{
Layer::push(this);
}
@@ -150,15 +159,12 @@ void TabsGroup::deleteLater(bool detach, bool trash)
if (_deleted)
return;
#if defined(HARDWARE_TOUCH)
Keyboard::hide();
#endif
Layer::pop(this);
header.deleteLater(true, false);
body.deleteLater(true, false);
Window::deleteLater(detach, trash);
Layer::pop(this);
}
void TabsGroup::addTab(PageTab * page)
@@ -206,11 +212,7 @@ void TabsGroup::removeAllTabs()
void TabsGroup::setVisibleTab(PageTab* tab)
{
if (tab != currentTab) {
clearFocus();
body.clear();
#if defined(HARDWARE_TOUCH)
Keyboard::hide();
#endif
currentTab = tab;
if (tab->onSetVisible) tab->onSetVisible();
@@ -219,13 +221,13 @@ void TabsGroup::setVisibleTab(PageTab* tab)
(void)start_ms;
#endif
auto form = new FormWindow(&body, rect_t{0, 0, body.width(), body.height()},
NO_FOCUS | FORM_FORWARD_FOCUS);
rect_t r = rect_t{0, 0, body.width(), body.height()};
auto form = new FormWindow(&body, r, NO_FOCUS);
tab->build(form);
form->setFocus();
header.setTitle(tab->title.c_str());
invalidate();
#if defined(DEBUG)
TRACE("tab time: %d ms", RTOS_GET_MS() - start_ms);
#endif
@@ -245,9 +247,9 @@ void TabsGroup::checkEvents()
}
}
#if defined(HARDWARE_KEYS)
void TabsGroup::onEvent(event_t event)
{
#if defined(HARDWARE_KEYS)
TRACE_WINDOWS("%s received event 0x%X", getWindowDebugString().c_str(), event);
#if defined(KEYS_GPIO_REG_PGUP)
@@ -267,15 +269,21 @@ void TabsGroup::onEvent(event_t event)
killEvents(event);
uint8_t current = header.carousel.getCurrentIndex();
setCurrentTab(current == 0 ? tabs.size() - 1 : current - 1);
}
else if (event == EVT_KEY_FIRST(KEY_EXIT)) {
killEvents(event);
deleteLater();
} else if (parent) {
parent->onEvent(event);
}
}
#endif
}
void TabsGroup::onClicked()
{
Keyboard::hide();
}
void TabsGroup::onCancel()
{
deleteLater();
}
void TabsGroup::paint(BitmapBuffer * dc)
{
@@ -285,7 +293,7 @@ void TabsGroup::paint(BitmapBuffer * dc)
#if defined(HARDWARE_TOUCH)
bool TabsGroup::onTouchEnd(coord_t x, coord_t y)
{
Keyboard::hide();
// Keyboard::hide();
Window::onTouchEnd(x, y);
return true;
}
+14 -22
View File
@@ -137,19 +137,7 @@ class TabsGroupHeader: public FormGroup {
public:
TabsGroupHeader(TabsGroup * menu, uint8_t icon);
void deleteLater(bool detach = true, bool trash = true) override
{
if (_deleted)
return;
#if defined(HARDWARE_TOUCH)
back.deleteLater(true, false);
#endif
carousel.deleteLater(true, false);
FormField::deleteLater(detach, trash);
}
void setTitle(const char * value) { title = value; }
#if defined(DEBUG_WINDOWS)
std::string getName() const override
@@ -158,21 +146,25 @@ class TabsGroupHeader: public FormGroup {
}
#endif
void paint(BitmapBuffer * dc) override;
void setTitle(const char * value)
void deleteLater(bool detach = true, bool trash = true) override
{
title = value;
if (_deleted) return;
#if defined(HARDWARE_TOUCH)
back.deleteLater(true, false);
#endif
carousel.deleteLater(true, false);
FormGroup::deleteLater(detach, trash);
}
void paint(BitmapBuffer * dc) override;
protected:
#if defined(HARDWARE_TOUCH)
Button back;
Button back;
#endif
uint8_t icon;
TabsCarousel carousel;
const char * title = nullptr;
std::string title;
};
class TabsGroup: public Window
@@ -216,10 +208,10 @@ class TabsGroup: public Window
}
void checkEvents() override;
#if defined(HARDWARE_KEYS)
void onEvent(event_t event) override;
#endif
void onClicked() override;
void onCancel() override;
void paint(BitmapBuffer * dc) override;
+21 -3
View File
@@ -53,6 +53,7 @@ typedef struct {
lv_style_t bg_color_grey;
lv_style_t bg_color_white;
lv_style_t bg_color_active;
lv_style_t bg_color_focus;
lv_style_t pressed;
lv_style_t disabled;
lv_style_t focus_border;
@@ -66,6 +67,7 @@ typedef struct {
lv_style_t outline_primary;
lv_style_t outline_secondary;
lv_style_t circle;
lv_style_t rounded;
lv_style_t no_radius;
lv_style_t clip_corner;
#if LV_THEME_DEFAULT_GROW
@@ -379,9 +381,21 @@ static void style_init(void)
lv_style_set_bg_opa(&styles.bg_color_active, LV_OPA_COVER);
lv_style_set_text_color(&styles.bg_color_active, makeLvColor(COLOR_THEME_PRIMARY2));
style_init_reset(&styles.bg_color_focus);
lv_style_set_bg_color(&styles.bg_color_focus, makeLvColor(COLOR_THEME_FOCUS));
lv_style_set_bg_opa(&styles.bg_color_focus, LV_OPA_COVER);
lv_style_set_text_color(&styles.bg_color_focus, makeLvColor(COLOR_THEME_PRIMARY2));
style_init_reset(&styles.circle);
lv_style_set_radius(&styles.circle, LV_RADIUS_CIRCLE);
style_init_reset(&styles.rounded);
lv_style_set_radius(
&styles.rounded,
(disp_size == DISP_LARGE ? lv_disp_dpx(theme.disp, 16)
: disp_size == DISP_MEDIUM ? lv_disp_dpx(theme.disp, 12)
: lv_disp_dpx(theme.disp, 8)));
style_init_reset(&styles.no_radius);
lv_style_set_radius(&styles.no_radius, 0);
@@ -775,11 +789,15 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj)
#if LV_USE_BTNMATRIX
else if(lv_obj_check_type(obj, &lv_btnmatrix_class)) {
// main
lv_obj_add_style(obj, &styles.rounded, 0);
// lv_obj_add_style(obj, &styles.focus_border, LV_STATE_FOCUS_KEY);
// items
lv_obj_add_style(obj, &styles.btn, LV_PART_ITEMS);
lv_obj_add_style(obj, &styles.disabled, LV_PART_ITEMS | LV_STATE_DISABLED);
lv_obj_add_style(obj, &styles.pressed, LV_PART_ITEMS | LV_STATE_PRESSED);
lv_obj_add_style(obj, &styles.bg_color_active, LV_PART_ITEMS | LV_STATE_CHECKED);
lv_obj_add_style(obj, &styles.focus_border, LV_PART_ITEMS | LV_STATE_FOCUSED);
lv_obj_add_style(obj, &styles.focus_border, LV_PART_ITEMS | LV_STATE_EDITED);
}
#endif
@@ -814,8 +832,8 @@ static void theme_apply(lv_theme_t * th, lv_obj_t * obj)
lv_obj_add_style(obj, &styles.table_cell, LV_PART_ITEMS);
lv_obj_add_style(obj, &styles.pad_small, LV_PART_ITEMS);
lv_obj_add_style(obj, &styles.pressed, LV_PART_ITEMS | LV_STATE_PRESSED);
lv_obj_add_style(obj, &styles.bg_color_primary, LV_PART_ITEMS | LV_STATE_FOCUS_KEY);
lv_obj_add_style(obj, &styles.bg_color_secondary, LV_PART_ITEMS | LV_STATE_EDITED);
lv_obj_add_style(obj, &styles.bg_color_focus, LV_PART_ITEMS | LV_STATE_FOCUS_KEY);
lv_obj_add_style(obj, &styles.bg_color_focus, LV_PART_ITEMS | LV_STATE_EDITED);
}
#endif
+20 -47
View File
@@ -35,7 +35,7 @@ Topbar * TopbarFactory::create(Window * parent)
}
SetupTopBarWidgetsPage::SetupTopBarWidgetsPage(ScreenMenu* menu):
FormWindow(ViewMain::instance(), {0, 0, 0, 0}, FORM_FORWARD_FOCUS),
FormWindow(ViewMain::instance(), rect_t{}, FORM_FORWARD_FOCUS),
menu(menu)
{
// remember focus
@@ -44,32 +44,39 @@ SetupTopBarWidgetsPage::SetupTopBarWidgetsPage(ScreenMenu* menu):
auto viewMain = ViewMain::instance();
// save current view & switch to 1st one
savedView = viewMain->getCurrentMainView();
viewMain->setCurrentMainView(0);
viewMain->bringToTop();
//TODO: force the topbar to be visible?
// adopt the dimensions of the main view
setRect(viewMain->getRect());
auto topbar = dynamic_cast<TopbarImpl*>(viewMain->getTopbar());
for (unsigned i = 0; i < topbar->getZonesCount(); i++) {
auto rect = topbar->getZone(i);
auto widget = new SetupWidgetsPageSlot(this, rect, topbar, i);
if (i == 0) widget->setFocus();
new SetupWidgetsPageSlot(this, rect, topbar, i);
}
#if defined(HARDWARE_TOUCH)
new Button(
this, {0, 0, MENU_HEADER_BUTTON_WIDTH, MENU_HEADER_BUTTON_WIDTH},
[this]() -> uint8_t {
this->deleteLater();
return 1;
},
NO_FOCUS | FORM_NO_BORDER);
new Button(
this, {0, 0, MENU_HEADER_BUTTON_WIDTH, MENU_HEADER_BUTTON_WIDTH},
[this]() -> uint8_t {
this->deleteLater();
return 1;
},
NO_FOCUS | FORM_NO_BORDER, 0, window_create);
#endif
}
void SetupTopBarWidgetsPage::onClicked()
{
// block event forwarding (window is transparent)
}
void SetupTopBarWidgetsPage::onCancel()
{
deleteLater();
}
void SetupTopBarWidgetsPage::deleteLater(bool detach, bool trash)
{
// restore screen setting tab on top
@@ -81,37 +88,3 @@ void SetupTopBarWidgetsPage::deleteLater(bool detach, bool trash)
storageDirty(EE_MODEL);
}
#if defined(HARDWARE_KEYS)
void SetupTopBarWidgetsPage::onEvent(event_t event)
{
switch (event) {
case EVT_KEY_BREAK(KEY_EXIT):
killEvents(event);
deleteLater();
break;
}
}
#endif
#if defined(HARDWARE_TOUCH)
bool SetupTopBarWidgetsPage::onTouchSlide(coord_t x, coord_t y,
coord_t startX, coord_t startY,
coord_t slideX, coord_t slideY)
{
Window::onTouchSlide(x, y, startX, startY, slideX, slideY);
return true;
}
bool SetupTopBarWidgetsPage::onTouchEnd(coord_t x, coord_t y)
{
#if defined(SOFTWARE_KEYBOARD)
Keyboard::hide();
#endif
if (FormWindow::onTouchEnd(x, y))
return true;
return true;
}
#endif
+13 -25
View File
@@ -32,41 +32,29 @@ class TopbarImpl;
class Topbar
{
public:
virtual void load() = 0;
public:
virtual void load() = 0;
};
class TopbarFactory
{
public:
static Topbar * create(Window * parent);
public:
static Topbar* create(Window* parent);
};
class SetupTopBarWidgetsPage: public FormWindow
class SetupTopBarWidgetsPage : public FormWindow
{
public:
explicit SetupTopBarWidgetsPage(ScreenMenu* menu);
public:
explicit SetupTopBarWidgetsPage(ScreenMenu* menu);
#if defined(DEBUG_WINDOWS)
std::string getName() const override
{
return "SetupTopBarWidgetsPage";
}
std::string getName() const override { return "SetupTopBarWidgetsPage"; }
#endif
void deleteLater(bool detach = true, bool trash = true) override;
void onClicked() override;
void onCancel() override;
void deleteLater(bool detach = true, bool trash = true) override;
#if defined(HARDWARE_KEYS)
void onEvent(event_t event) override;
#endif
#if defined(HARDWARE_TOUCH)
bool onTouchSlide(coord_t x, coord_t y, coord_t startX, coord_t startY,
coord_t slideX, coord_t slideY) override;
bool onTouchEnd(coord_t x, coord_t y) override;
#endif
protected:
ScreenMenu* menu;
unsigned savedView = 0;
protected:
ScreenMenu* menu;
};
+1 -1
View File
@@ -257,7 +257,7 @@ void TrainerModuleWindow::update()
#endif
auto par = getParent();
par->moveWindowsTop(top() + 1, adjustHeight());
par->adjustInnerHeight();
// par->adjustInnerHeight();
}
#if defined(BLUETOOTH)
+47 -41
View File
@@ -51,12 +51,12 @@ ViewMain * ViewMain::_instance = nullptr;
ViewMain::ViewMain():
Window(MainWindow::instance(), MainWindow::instance()->getRect(), NO_SCROLLBAR)
{
focusWindow = this;
Layer::push(this);
setFocusHandler([&](bool focus) {
TRACE("[ViewMain] Focus %s",
focus ? "gained" : "lost");
});
// setFocusHandler([&](bool focus) {
// TRACE("[ViewMain] Focus %s",
// focus ? "gained" : "lost");
// });
tile_view = lv_tileview_create(lvobj);
lv_obj_set_pos(tile_view, rect.x, rect.y);
@@ -78,13 +78,20 @@ ViewMain::~ViewMain()
_instance = nullptr;
}
void ViewMain::deleteLater(bool detach, bool trash)
{
Layer::pop(this);
Window::deleteLater(detach, trash);
}
void ViewMain::addMainView(Window* view, uint32_t viewId)
{
TRACE("addMainView(0x%p, %d)", view, viewId);
auto tile = lv_tileview_add_tile(tile_view, viewId, 0, LV_DIR_LEFT | LV_DIR_RIGHT);
lv_obj_set_parent(view->getLvObj(), tile);
auto view_obj = view->getLvObj();
lv_obj_set_parent(view_obj, tile);
auto user_data = (void*)(unsigned long)viewId;
lv_obj_add_event_cb(tile, tile_view_deleted_cb, LV_EVENT_CHILD_DELETED, user_data);
@@ -211,62 +218,58 @@ void ViewMain::updateTopbarVisibility()
}
}
#if defined(HARDWARE_TOUCH)
// #if defined(HARDWARE_TOUCH)
//#define DEBUG_SLIDE
bool ViewMain::onTouchEnd(coord_t x, coord_t y)
{
openMenu();
// bool ViewMain::onTouchEnd(coord_t x, coord_t y)
// {
// openMenu();
// TODO: remove this hack to preset
// the scrolling on the main menu
int x1 = x;
int w1 = getParent()->width();
while (x1 > w1) x1 -= w1;
if (x1 > w1 / 2)
pushEvent(EVT_ROTARY_LEFT);
// // TODO: remove this hack to preset
// // the scrolling on the main menu
// int x1 = x;
// int w1 = getParent()->width();
// while (x1 > w1) x1 -= w1;
// if (x1 > w1 / 2)
// pushEvent(EVT_ROTARY_LEFT);
return true;
}
#endif
// return true;
// }
// #endif
#if defined(HARDWARE_KEYS)
void ViewMain::onEvent(event_t event)
{
#if defined(HARDWARE_KEYS)
switch (event) {
case EVT_KEY_BREAK(KEY_MODEL):
killEvents(event);
new ModelMenu();
break;
case EVT_KEY_LONG(KEY_MODEL):
killEvents(event);
new ModelSelectMenu();
break;
case EVT_KEY_FIRST(KEY_RADIO):
killEvents(event);
new RadioMenu();
break;
case EVT_KEY_FIRST(KEY_TELEM):
killEvents(event);
new ScreenMenu();
break;
case EVT_KEY_FIRST(KEY_ENTER):
killEvents(event);
openMenu();
break;
// // do not use KEY_FIRST as it would
// // interfere with the menu CLICKED event
// case EVT_KEY_FIRST(KEY_ENTER):
// openMenu();
// break;
#if defined(KEYS_GPIO_REG_PGUP)
case EVT_KEY_FIRST(KEY_PGDN):
#else
case EVT_KEY_BREAK(KEY_PGDN):
#endif
killEvents(event);
nextMainView();
break;
@@ -281,19 +284,22 @@ void ViewMain::onEvent(event_t event)
previousMainView();
break;
case EVT_ROTARY_LEFT:
// decrement
case EVT_ROTARY_RIGHT:
// increment
if (customScreens[g_model.view]) {
customScreens[g_model.view]->setFocus();
}
break;
break;
// case EVT_ROTARY_LEFT:
// // decrement
// case EVT_ROTARY_RIGHT:
// // increment
// if (customScreens[g_model.view]) {
// customScreens[g_model.view]->setFocus();
// }
// break;
}
}
#endif
}
void ViewMain::onClicked()
{
openMenu();
}
void ViewMain::openMenu()
{
+8 -7
View File
@@ -74,9 +74,8 @@ class ViewMain: public Window
Topbar* getTopbar();
#if defined(HARDWARE_KEYS)
void onEvent(event_t event) override;
#endif
void onClicked() override;
protected:
static ViewMain * _instance;
@@ -85,6 +84,8 @@ class ViewMain: public Window
lv_obj_t* tile_view = nullptr;
TopbarImpl* topbar = nullptr;
void deleteLater(bool detach = true, bool trash = true) override;
// Widget setup requires special permissions ;-)
friend class SetupWidgetsPage;
friend class SetupTopBarWidgetsPage;
@@ -92,12 +93,12 @@ class ViewMain: public Window
// Set topbar visibility [0.0 -> 1.0]
void setTopbarVisible(float visible);
#if defined(HARDWARE_TOUCH)
unsigned char prevSlideState = 0;
unsigned int startSlidePage = 0;
// #if defined(HARDWARE_TOUCH)
// unsigned char prevSlideState = 0;
// unsigned int startSlidePage = 0;
bool onTouchEnd(coord_t x, coord_t y) override;
#endif
// bool onTouchEnd(coord_t x, coord_t y) override;
// #endif
void paint(BitmapBuffer * dc) override;
+7 -2
View File
@@ -114,8 +114,8 @@ ViewMainMenu::ViewMainMenu(Window* parent) :
carouselRect.w = lv_obj_get_width(carousel_obj);
carouselRect.h = lv_obj_get_height(carousel_obj);
carousel->setCloseHandler([=]() { deleteLater(); });
carousel->setFocus();
// carousel->setCloseHandler([=]() { deleteLater(); });
// carousel->setFocus();
}
uint16_t* lcdGetBackupBuffer();
@@ -134,3 +134,8 @@ void ViewMainMenu::deleteLater(bool detach, bool trash)
Layer::pop(this);
Window::deleteLater(detach, trash);
}
void ViewMainMenu::onCancel()
{
deleteLater();
}
+22 -31
View File
@@ -23,40 +23,31 @@
#include "form.h"
class ViewMainMenu: public Window
class ViewMainMenu : public Window
{
public:
ViewMainMenu(Window * parent);
void paint(BitmapBuffer * dc) override;
void deleteLater(bool detach=true, bool trash=true) override;
public:
ViewMainMenu(Window* parent);
void onCancel() override;
void paint(BitmapBuffer* dc) override;
void deleteLater(bool detach = true, bool trash = true) override;
#if defined(HARDWARE_TOUCH)
bool onTouchStart(coord_t /*x*/, coord_t /*y*/) override { return true; }
bool onTouchEnd(coord_t x, coord_t y) override
{
onKeyPress();
deleteLater();
return true;
}
bool onTouchSlide(coord_t x, coord_t y, coord_t startX, coord_t startY,
coord_t slideX, coord_t slideY) override
{
Window::onTouchSlide(x, y, startX, startY, slideX, slideY);
return true;
}
#endif
#if defined(HARDWARE_KEYS)
void onEvent(event_t event) override
{
switch (event) {
case EVT_KEY_BREAK(KEY_EXIT):
killEvents(event);
parent->deleteLater();
return;
}
}
bool onTouchStart(coord_t /*x*/, coord_t /*y*/) override { return true; }
bool onTouchEnd(coord_t x, coord_t y) override
{
onKeyPress();
deleteLater();
return true;
}
bool onTouchSlide(coord_t x, coord_t y, coord_t startX, coord_t startY,
coord_t slideX, coord_t slideY) override
{
Window::onTouchSlide(x, y, startX, startY, slideX, slideY);
return true;
}
#endif
protected:
rect_t carouselRect;
protected:
rect_t carouselRect;
};
+58 -57
View File
@@ -66,7 +66,7 @@ void ViewTextWindow::buildBody(Window *window)
// Font is not fixed width, so this is for the worst case...
maxLineLength = static_cast<int>(window->width() / 10 / 10) * 10 - 2;
maxScreenLines = window->height() / (PAGE_LINE_HEIGHT + PAGE_LINE_SPACING);
window->setFocus();
// window->setFocus();
readLinesCount = 0;
lastLoadedLine = 0;
@@ -112,76 +112,77 @@ bool ViewTextWindow::onTouchSlide(coord_t x, coord_t y, coord_t startX,
coord_t startY, coord_t slideX,
coord_t slideY)
{
if (&body == Window::focusWindow) {
const int step = PAGE_LINE_HEIGHT + PAGE_LINE_SPACING;
int deltaY = -slideY;
int lineStep = deltaY / step;
// if (&body == Window::focusWindow) {
// const int step = PAGE_LINE_HEIGHT + PAGE_LINE_SPACING;
// int deltaY = -slideY;
// int lineStep = deltaY / step;
textVerticalOffset += lineStep;
if (textVerticalOffset < 0) textVerticalOffset = 0;
// textVerticalOffset += lineStep;
// if (textVerticalOffset < 0) textVerticalOffset = 0;
if (textVerticalOffset > maxLines - maxScreenLines)
textVerticalOffset = maxLines - maxScreenLines;
sdReadTextFileBlock(fullPath.c_str(), readLinesCount);
}
return Page::onTouchSlide(x, y, startX, startY, slideX, slideY);
// if (textVerticalOffset > maxLines - maxScreenLines)
// textVerticalOffset = maxLines - maxScreenLines;
// sdReadTextFileBlock(fullPath.c_str(), readLinesCount);
// }
// return Page::onTouchSlide(x, y, startX, startY, slideX, slideY);
return true;
}
#endif
void ViewTextWindow::checkEvents()
{
if (&body == Window::focusWindow) {
const int step = PAGE_LINE_HEIGHT + PAGE_LINE_SPACING;
coord_t deltaY;
event_t event = getWindowEvent();
// if (&body == Window::focusWindow) {
// const int step = PAGE_LINE_HEIGHT + PAGE_LINE_SPACING;
// coord_t deltaY;
// event_t event = getWindowEvent();
#if defined(ROTARY_ENCODER_NAVIGATION)
if (event == EVT_ROTARY_LEFT || event == EVT_ROTARY_RIGHT) {
deltaY = ROTARY_ENCODER_SPEED() * step;
} else {
deltaY = step;
}
#else
deltaY = step;
#endif
// #if defined(ROTARY_ENCODER_NAVIGATION)
// if (event == EVT_ROTARY_LEFT || event == EVT_ROTARY_RIGHT) {
// deltaY = ROTARY_ENCODER_SPEED() * step;
// } else {
// deltaY = step;
// }
// #else
// deltaY = step;
// #endif
int lineStep = deltaY / step;
if (lineStep > (maxScreenLines >> 1)) lineStep = maxScreenLines >> 1;
// int lineStep = deltaY / step;
// if (lineStep > (maxScreenLines >> 1)) lineStep = maxScreenLines >> 1;
switch (event) {
CASE_EVT_START:
textVerticalOffset = 0;
readLinesCount = 0;
sdReadTextFileBlock(fullPath.c_str(), readLinesCount);
break;
// switch (event) {
// CASE_EVT_START:
// textVerticalOffset = 0;
// readLinesCount = 0;
// sdReadTextFileBlock(fullPath.c_str(), readLinesCount);
// break;
CASE_EVT_KEY_NEXT_LINE:
if (textBottom && textVerticalOffset)
break;
else {
textVerticalOffset += lineStep;
if (textVerticalOffset > maxLines) textVerticalOffset = maxLines;
}
sdReadTextFileBlock(fullPath.c_str(), readLinesCount);
break;
// CASE_EVT_KEY_NEXT_LINE:
// if (textBottom && textVerticalOffset)
// break;
// else {
// textVerticalOffset += lineStep;
// if (textVerticalOffset > maxLines) textVerticalOffset = maxLines;
// }
// sdReadTextFileBlock(fullPath.c_str(), readLinesCount);
// break;
CASE_EVT_KEY_PREVIOUS_LINE:
if (textVerticalOffset == 0)
break;
else {
textVerticalOffset -= lineStep;
if (textVerticalOffset < 0) textVerticalOffset = 0;
}
// CASE_EVT_KEY_PREVIOUS_LINE:
// if (textVerticalOffset == 0)
// break;
// else {
// textVerticalOffset -= lineStep;
// if (textVerticalOffset < 0) textVerticalOffset = 0;
// }
sdReadTextFileBlock(fullPath.c_str(), readLinesCount);
break;
// sdReadTextFileBlock(fullPath.c_str(), readLinesCount);
// break;
default:
Page::onEvent(event);
break;
}
}
Page::checkEvents();
// default:
// Page::onEvent(event);
// break;
// }
// }
// Page::checkEvents();
}
void ViewTextWindow::loadOneScreen(int offset)
+27 -24
View File
@@ -30,7 +30,7 @@
#include "touch.h"
#endif
constexpr uint32_t WIDGET_FOCUS_TIMEOUT = 10*1000; // 10 seconds
// constexpr uint32_t WIDGET_FOCUS_TIMEOUT = 10*1000; // 10 seconds
static void openWidgetMenu(Widget * parent)
{
@@ -41,16 +41,12 @@ static void openWidgetMenu(Widget * parent)
[=]() { new WidgetSettings(parent, parent); });
}
Widget::Widget(const WidgetFactory *factory, FormGroup *parent,
const rect_t &rect, WidgetPersistentData *persistentData) :
Button(parent, rect), factory(factory), persistentData(persistentData)
Widget::Widget(const WidgetFactory* factory, Window* parent,
const rect_t &rect, WidgetPersistentData* persistentData) :
Button(parent, rect, nullptr, 0, 0, window_create),
factory(factory),
persistentData(persistentData)
{
setFocusHandler([&](bool focus) {
if (focus) { // gained focus
focusGainedTS = RTOS_GET_MS();
}
});
setPressHandler([&]() -> uint8_t {
if (!fullscreen) openWidgetMenu(this);
return 0;
@@ -62,9 +58,9 @@ void Widget::checkEvents()
Button::checkEvents();
// Give the focus back to ViewMain after WIDGET_FOCUS_TIMEOUT milliseconds
if (!fullscreen && hasFocus() && (RTOS_GET_MS() - focusGainedTS >= WIDGET_FOCUS_TIMEOUT)) {
ViewMain::instance()->setFocus();
}
// if (!fullscreen && hasFocus() && (RTOS_GET_MS() - focusGainedTS >= WIDGET_FOCUS_TIMEOUT)) {
// ViewMain::instance()->setFocus();
// }
}
@@ -80,11 +76,11 @@ void Widget::paint(BitmapBuffer * dc)
if (hasFocus() && !fullscreen) {
// Blink from haft-time before expiring (5s)
if ((RTOS_GET_MS() - focusGainedTS >= WIDGET_FOCUS_TIMEOUT / 2)
&& !FAST_BLINK_ON_PHASE) {
return;
}
// // Blink from haft-time before expiring (5s)
// if ((RTOS_GET_MS() - focusGainedTS >= WIDGET_FOCUS_TIMEOUT / 2)
// && !FAST_BLINK_ON_PHASE) {
// return;
// }
dc->drawRect(0, 0, width(), height(), 2, STASHED, COLOR_THEME_FOCUS);
}
}
@@ -96,8 +92,8 @@ void Widget::onEvent(event_t event)
if (!fullscreen) {
if (event == EVT_KEY_BREAK(KEY_EXIT)) {
// [EXIT] -> exit focus mode (if not fullscreen)
killEvents(event);
ViewMain::instance()->setFocus();
// killEvents(event);
// ViewMain::instance()->setFocus();
return;
}
// Forward the rest to the parent class
@@ -106,7 +102,7 @@ void Widget::onEvent(event_t event)
// In fullscreen mode, we react only to that one key:
// [RTN / EXIT LONG] -> exit fullscreen mode
else if (EVT_KEY_LONG(KEY_EXIT) == event) {
killEvents(event);
// killEvents(event);
setFullscreen(false);
}
}
@@ -134,8 +130,10 @@ void Widget::setFullscreen(bool enable)
// and give up focus
ViewMain::instance()->enableTopbar();
ViewMain::instance()->setFocus();
// ViewMain::instance()->setFocus();
fullscreen = false;
lv_group_remove_obj(lvobj);
}
// Enter Fullscreen Mode
else {
@@ -147,6 +145,10 @@ void Widget::setFullscreen(bool enable)
fullscreen = true;
ViewMain::instance()->disableTopbar();
bringToTop();
if (!lv_obj_get_group(lvobj)) {
lv_group_add_obj(lv_group_get_default(), lvobj);
}
}
}
@@ -179,9 +181,10 @@ const WidgetFactory * getWidgetFactory(const char * name)
return nullptr;
}
Widget * loadWidget(const char * name, FormGroup * parent, const rect_t & rect, WidgetPersistentData * persistentData)
Widget* loadWidget(const char* name, Window* parent, const rect_t& rect,
WidgetPersistentData* persistentData)
{
const WidgetFactory * factory = getWidgetFactory(name);
const WidgetFactory* factory = getWidgetFactory(name);
if (factory) {
return factory->create(parent, rect, persistentData, false);
}
+3 -3
View File
@@ -40,7 +40,7 @@ class Widget : public Button
typedef WidgetPersistentData PersistentData;
Widget(const WidgetFactory *factory, FormGroup *parent, const rect_t &rect,
Widget(const WidgetFactory *factory, Window* parent, const rect_t &rect,
WidgetPersistentData *persistentData);
~Widget() override = default;
@@ -164,7 +164,7 @@ class WidgetFactory
}
}
virtual Widget * create(FormGroup * parent, const rect_t & rect, Widget::PersistentData * persistentData, bool init = true) const = 0;
virtual Widget * create(Window* parent, const rect_t & rect, Widget::PersistentData * persistentData, bool init = true) const = 0;
protected:
const char * name;
@@ -177,6 +177,6 @@ inline const ZoneOption * Widget::getOptions() const
return getFactory()->getOptions();
}
Widget * loadWidget(const char * name, FormGroup * parent, const rect_t & rect, Widget::PersistentData * persistentData);
Widget * loadWidget(const char * name, Window* parent, const rect_t & rect, Widget::PersistentData * persistentData);
std::list<const WidgetFactory *> & getRegisteredWidgets();
+10 -10
View File
@@ -171,18 +171,18 @@ WidgetSettings::WidgetSettings(Window* parent, Widget* widget) :
content->updateSize();
setCloseHandler([=]() { widget->update(); });
form->setFocus();
// form->setFocus();
}
#if defined(HARDWARE_KEYS)
// #if defined(HARDWARE_KEYS)
void WidgetSettings::onEvent(event_t event)
{
TRACE_WINDOWS("%s received event 0x%X", getWindowDebugString().c_str(), event);
// void WidgetSettings::onEvent(event_t event)
// {
// TRACE_WINDOWS("%s received event 0x%X", getWindowDebugString().c_str(), event);
if (event == EVT_KEY_LONG(KEY_EXIT) || event == EVT_KEY_BREAK(KEY_EXIT)) {
deleteLater();
}
}
// if (event == EVT_KEY_LONG(KEY_EXIT) || event == EVT_KEY_BREAK(KEY_EXIT)) {
// deleteLater();
// }
// }
#endif
// #endif
+3 -3
View File
@@ -29,7 +29,7 @@ class WidgetSettings : public Dialog
public:
WidgetSettings(Window* parent, Widget* widget);
#if defined(HARDWARE_KEYS)
void onEvent(event_t event) override;
#endif
// #if defined(HARDWARE_KEYS)
// void onEvent(event_t event) override;
// #endif
};
+1 -1
View File
@@ -25,7 +25,7 @@
class GaugeWidget: public Widget
{
public:
GaugeWidget(const WidgetFactory * factory, FormGroup * parent, const rect_t & rect, Widget::PersistentData * persistentData):
GaugeWidget(const WidgetFactory* factory, Window* parent, const rect_t & rect, Widget::PersistentData* persistentData):
Widget(factory, parent, rect, persistentData)
{
}
+1 -1
View File
@@ -27,7 +27,7 @@
class ModelBitmapWidget: public Widget
{
public:
ModelBitmapWidget(const WidgetFactory * factory, FormGroup * parent, const rect_t & rect, Widget::PersistentData * persistentData):
ModelBitmapWidget(const WidgetFactory* factory, Window* parent, const rect_t & rect, Widget::PersistentData* persistentData):
Widget(factory, parent, rect, persistentData)
{
loadBitmap();
+1 -1
View File
@@ -33,7 +33,7 @@ constexpr uint32_t OUTPUTS_REFRESH = 1000 / 5; // 5 Hz
class OutputsWidget : public Widget
{
public:
OutputsWidget(const WidgetFactory* factory, FormGroup* parent,
OutputsWidget(const WidgetFactory* factory, Window* parent,
const rect_t& rect, Widget::PersistentData* persistentData) :
Widget(factory, parent, rect, persistentData)
{
+1 -1
View File
@@ -27,7 +27,7 @@
class TextWidget: public Widget
{
public:
TextWidget(const WidgetFactory * factory, FormGroup * parent, const rect_t & rect, Widget::PersistentData * persistentData):
TextWidget(const WidgetFactory* factory, Window* parent, const rect_t & rect, Widget::PersistentData* persistentData):
Widget(factory, parent, rect, persistentData)
{
}
+1 -1
View File
@@ -41,7 +41,7 @@ STATIC_LZ4_BITMAP(LBM_TIMER_BACKGROUND);
class TimerWidget : public Widget
{
public:
TimerWidget(const WidgetFactory* factory, FormGroup* parent,
TimerWidget(const WidgetFactory* factory, Window* parent,
const rect_t& rect, Widget::PersistentData* persistentData) :
Widget(factory, parent, rect, persistentData)
{
+1 -1
View File
@@ -27,7 +27,7 @@ const coord_t NUMBERS_PADDING = 4;
class ValueWidget: public Widget
{
public:
ValueWidget(const WidgetFactory* factory, FormGroup* parent,
ValueWidget(const WidgetFactory* factory, Window* parent,
const rect_t& rect, Widget::PersistentData* persistentData) :
Widget(factory, parent, rect, persistentData)
{
@@ -65,7 +65,6 @@ class WidgetsContainerImpl : public WidgetsContainer
if (index >= N) return;
if (widgets[index]) {
removeField(widgets[index]);
widgets[index]->deleteLater();
}
@@ -91,7 +90,6 @@ class WidgetsContainerImpl : public WidgetsContainer
for (unsigned int i = 0; i < count; i++) {
// remove old widget
if (widgets[i]) {
removeField(widgets[i]);
widgets[i]->deleteLater();
widgets[i] = nullptr;
}
@@ -159,7 +157,7 @@ class BaseWidgetFactory : public WidgetFactory
{
}
Widget* create(FormGroup* parent, const rect_t& rect,
Widget* create(Window* parent, const rect_t& rect,
Widget::PersistentData* persistentData,
bool init = true) const override
{
+2 -2
View File
@@ -76,10 +76,10 @@ struct TopBarPersistentData {
};
#endif
class WidgetsContainer: public FormGroup
class WidgetsContainer: public Window
{
public:
using FormGroup::FormGroup;
using Window::Window;
virtual unsigned int getZonesCount() const = 0;
virtual rect_t getZone(unsigned int index) const = 0;
+20 -39
View File
@@ -93,9 +93,8 @@ SetupWidgetsPage::SetupWidgetsPage(ScreenMenu* menu, uint8_t customScreenIdx) :
for (unsigned i = 0; i < screen->getZonesCount(); i++) {
auto rect = screen->getZone(i);
auto widget =
new SetupWidgetsPageSlot(this, rect, customScreens[customScreenIdx], i);
if (i == 0) widget->setFocus();
auto widget_container = customScreens[customScreenIdx];
auto widget = new SetupWidgetsPageSlot(this, rect, widget_container, i);
}
#if defined(HARDWARE_TOUCH)
@@ -106,15 +105,28 @@ SetupWidgetsPage::SetupWidgetsPage(ScreenMenu* menu, uint8_t customScreenIdx) :
this->deleteLater();
return 1;
},
NO_FOCUS | FORM_NO_BORDER);
NO_FOCUS | FORM_NO_BORDER,
0, window_create);
#endif
}
void SetupWidgetsPage::onClicked()
{
// block event forwarding (window is transparent)
}
void SetupWidgetsPage::onCancel()
{
deleteLater();
}
void SetupWidgetsPage::deleteLater(bool detach, bool trash)
{
#if defined(HARDWARE_TOUCH)
Keyboard::hide();
#endif
// restore screen setting tab on top
menu->bringToTop();
Layer::pop(this);
// and continue async deletion...
auto screen = customScreens[customScreenIdx];
if (screen) {
auto viewMain = ViewMain::instance();
@@ -122,36 +134,5 @@ void SetupWidgetsPage::deleteLater(bool detach, bool trash)
}
FormWindow::deleteLater(detach, trash);
// restore screen setting tab on top
menu->bringToTop();
Layer::pop(this);
storageDirty(EE_MODEL);
}
#if defined(HARDWARE_TOUCH)
bool SetupWidgetsPage::onTouchSlide(coord_t x, coord_t y, coord_t startX,
coord_t startY, coord_t slideX,
coord_t slideY)
{
FormWindow::onTouchSlide(x, y, startX, startY, slideX, slideY);
return true;
}
bool SetupWidgetsPage::onTouchEnd(coord_t x, coord_t y)
{
FormWindow::onTouchEnd(x, y);
return true;
}
#endif
#if defined(HARDWARE_KEYS)
void SetupWidgetsPage::onEvent(event_t event)
{
TRACE_WINDOWS("%s received event 0x%X", getWindowDebugString().c_str(),
event);
if (event == EVT_KEY_LONG(KEY_EXIT) || event == EVT_KEY_BREAK(KEY_EXIT)) {
killEvents(event);
deleteLater();
}
}
#endif
+2 -10
View File
@@ -39,18 +39,10 @@ class SetupWidgetsPage : public FormWindow
}
#endif
void onClicked() override;
void onCancel() override;
void deleteLater(bool detach = true, bool trash = true) override;
#if defined(HARDWARE_TOUCH)
bool onTouchSlide(coord_t x, coord_t y, coord_t startX, coord_t startY,
coord_t slideX, coord_t slideY) override;
bool onTouchEnd(coord_t x, coord_t y) override;
#endif
#if defined(HARDWARE_KEYS)
void onEvent(event_t event) override;
#endif
protected:
ScreenMenu* menu;
uint8_t customScreenIdx;
+2 -2
View File
@@ -1027,7 +1027,7 @@ static bool resumeLua(bool init, bool allowLcdUsage)
events[EVENT_BUFFER_SIZE - 1] = 0;
if (evt == EVT_KEY_LONG(KEY_EXIT)) {
killEvents(evt);
// killEvents(evt);
luaState = INTERPRETER_RELOAD_PERMANENT_SCRIPTS;
}
}
@@ -1220,7 +1220,7 @@ static bool resumeLua(bool init, bool allowLcdUsage)
if (evt == EVT_KEY_LONG(KEY_EXIT)) {
TRACE("Script force exit");
killEvents(evt);
// killEvents(evt);
luaEmptyEventBuffer();
luaState = INTERPRETER_RELOAD_PERMANENT_SCRIPTS;
}
+2 -2
View File
@@ -228,7 +228,7 @@ class LuaWidget: public Widget
friend class LuaWidgetFactory;
public:
LuaWidget(const WidgetFactory * factory, FormGroup * parent, const rect_t & rect, WidgetPersistentData * persistentData, int luaWidgetDataRef):
LuaWidget(const WidgetFactory * factory, Window* parent, const rect_t & rect, WidgetPersistentData * persistentData, int luaWidgetDataRef):
Widget(factory, parent, rect, persistentData),
luaWidgetDataRef(luaWidgetDataRef),
errorMessage(nullptr)
@@ -325,7 +325,7 @@ class LuaWidgetFactory: public WidgetFactory
unregisterWidget(this);
}
Widget * create(FormGroup * parent, const rect_t & rect, Widget::PersistentData * persistentData, bool init=true) const override
Widget * create(Window* parent, const rect_t & rect, Widget::PersistentData * persistentData, bool init=true) const override
{
if (lsWidgets == 0) return 0;
initPersistentData(persistentData, init);
+3 -2
View File
@@ -173,13 +173,14 @@ void per10ms()
}
#endif
// TODO: to board...
readKeysAndTrims();
#if defined(FUNCTION_SWITCHES)
evalFunctionSwitches();
#endif
#if defined(ROTARY_ENCODER_NAVIGATION)
#if defined(ROTARY_ENCODER_NAVIGATION) && 0
if (IS_ROTARY_ENCODER_NAVIGATION_ENABLE()) {
static rotenc_t rePreviousValue;
static bool cw = false;
@@ -1644,7 +1645,7 @@ void moveTrimsToOffsets() // copy state of 3 primary to subtrim
}
#if defined(ROTARY_ENCODER_NAVIGATION)
uint8_t rotencSpeed;
uint8_t rotencSpeed = ROTENC_LOWSPEED;
#endif
void opentxInit()
-7
View File
@@ -143,16 +143,9 @@
#define TR_FLYSKY_PROTOCOLS "AFHDS3","AFHDS2A"
#define TR_XJT_ACCST_RF_PROTOCOLS "OFF","D16","D8","LR12"
#if defined(INTERNAL_MODULE_PXX1) || defined(PCBHORUS)
#define TR_ISRM_RF_PROTOCOLS "ACCESS","D16","LR12"
#else
#define TR_ISRM_RF_PROTOCOLS "OFF","ACCESS","ACCST D16","ACCST LR12","ACCST D8"
#endif
#define TR_R9M_PXX2_RF_PROTOCOLS "ACCESS","FCC","EU","Flex"
#define TR_SPORT_MODES "S.PORT","F.PORT","FBUS(FPORT2)"
#define TR_R9M_REGION "FCC","EU","868MHz","915MHz"
#define TR_R9M_LITE_FCC_POWER_VALUES "(100mW)"
#define TR_R9M_LITE_LBT_POWER_VALUES "25mW 8CH","25mW 16CH","100mW NoTele"