diff --git a/radio/src/gui/colorlcd/LvglWrapper.cpp b/radio/src/gui/colorlcd/LvglWrapper.cpp index ea5a41ec5..666c83823 100644 --- a/radio/src/gui/colorlcd/LvglWrapper.cpp +++ b/radio/src/gui/colorlcd/LvglWrapper.cpp @@ -66,11 +66,10 @@ 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: @@ -90,7 +89,8 @@ static bool evt_to_indev_data(event_t evt, lv_indev_data_t *data) return false; } - if (evt & _KEY_PRESSED) { + event_t flgs = evt & _MSK_KEY_FLAGS; + if (flgs != _MSK_KEY_BREAK && flgs != _MSK_KEY_LONG_BRK) { data->state = LV_INDEV_STATE_PRESSED; } else { data->state = LV_INDEV_STATE_RELEASED; @@ -122,6 +122,12 @@ static void keyboardDriverRead(lv_indev_drv_t *drv, lv_indev_data_t *data) if (isEvent()) { // event waiting event_t evt = getEvent(); + if ((evt & _MSK_KEY_FLAGS) == _MSK_KEY_LONG_BRK) { + data->state = LV_INDEV_STATE_RELEASED; + backup_kb_data(data); + return; + } + if(evt == EVT_KEY_FIRST(KEY_PAGEUP) || evt == EVT_KEY_FIRST(KEY_PAGEDN) || evt == EVT_KEY_FIRST(KEY_ENTER) || diff --git a/radio/src/gui/colorlcd/curve_param.cpp b/radio/src/gui/colorlcd/curve_param.cpp index 340f415c8..103818b4e 100644 --- a/radio/src/gui/colorlcd/curve_param.cpp +++ b/radio/src/gui/colorlcd/curve_param.cpp @@ -46,9 +46,34 @@ void CurveParam::value_changed(lv_event_t* e) param->update(); } +class CurveChoice : public Choice +{ + public: + CurveChoice(Window* parent, CurveRef* ref, std::function setRefValue, std::function refreshView) : + Choice(parent, rect_t{}, -MAX_CURVES, MAX_CURVES, GET_DEFAULT(ref->value), setRefValue), + ref(ref), refreshView(refreshView) + { + setTextHandler([](int value) { return getCurveString(value); }); + } + + bool onLongPress() override + { + if (modelCurvesEnabled()) { + if (ref->value) { + ModelCurvesPage::pushEditCurve(abs(ref->value) - 1, refreshView); + } + } + return true; + } + + protected: + CurveRef* ref; + std::function refreshView; +}; + CurveParam::CurveParam(Window* parent, const rect_t& rect, CurveRef* ref, - std::function setRefValue) : - Window(parent, rect), ref(ref), setRefValue(setRefValue) + std::function setRefValue, std::function refreshView) : + Window(parent, rect), ref(ref) { padAll(PAD_TINY); lv_obj_set_flex_flow(lvobj, LV_FLEX_FLOW_ROW_WRAP); @@ -67,18 +92,16 @@ CurveParam::CurveParam(Window* parent, const rect_t& rect, CurveRef* ref, // CURVE_REF_DIFF // CURVE_REF_EXPO - value_edit = new GVarNumberEdit(this, -100, 100, GET_DEFAULT(ref->value), setRefValue); - value_edit->setSuffix("%"); + auto gv = new GVarNumberEdit(this, -100, 100, GET_DEFAULT(ref->value), setRefValue); + gv->setSuffix("%"); + value_edit = gv; // CURVE_REF_FUNC func_choice = new Choice(this, rect_t{}, STR_VCURVEFUNC, 0, CURVE_BASE - 1, GET_DEFAULT(ref->value), setRefValue); // CURVE_REF_CUSTOM - cust_choice = new Choice(this, rect_t{}, -MAX_CURVES, MAX_CURVES, - GET_DEFAULT(ref->value), setRefValue); - cust_choice->setTextHandler([](int value) { return getCurveString(value); }); - cust_choice->set_lv_LongPressHandler(LongPressHandler, &(ref->value)); + cust_choice = new CurveChoice(this, ref, setRefValue, refreshView); update(); } diff --git a/radio/src/gui/colorlcd/curve_param.h b/radio/src/gui/colorlcd/curve_param.h index 576e33adb..f5859fdee 100644 --- a/radio/src/gui/colorlcd/curve_param.h +++ b/radio/src/gui/colorlcd/curve_param.h @@ -25,20 +25,15 @@ struct CurveRef; -class GVarNumberEdit; -class Choice; - class CurveParam : public Window { // Curve CurveRef* ref; - std::function setRefValue; // Controls - GVarNumberEdit* value_edit; - Choice* func_choice; - Choice* cust_choice; - + Window* value_edit; + Window* func_choice; + Window* cust_choice; Window* act_field = nullptr; void update(); @@ -47,5 +42,6 @@ class CurveParam : public Window public: CurveParam(Window* parent, const rect_t& rect, CurveRef* ref, - std::function setRefValue); + std::function setRefValue, + std::function refreshView = nullptr); }; diff --git a/radio/src/gui/colorlcd/curveedit.cpp b/radio/src/gui/colorlcd/curveedit.cpp index 540a31b5d..7fad54c25 100644 --- a/radio/src/gui/colorlcd/curveedit.cpp +++ b/radio/src/gui/colorlcd/curveedit.cpp @@ -240,8 +240,8 @@ void CurveEdit::checkEvents() Window::checkEvents(); } -CurveEditWindow::CurveEditWindow(uint8_t index) : - Page(ICON_MODEL_CURVES, PAD_ZERO), index(index) +CurveEditWindow::CurveEditWindow(uint8_t index, std::function refreshView) : + Page(ICON_MODEL_CURVES, PAD_ZERO), index(index), refreshView(refreshView) { buildBody(body); buildHeader(header); @@ -392,3 +392,9 @@ void CurveEditWindow::buildBody(Window* window) curveDataEdit->setCurveEdit(curveEdit); } + +void CurveEditWindow::onCancel() +{ + if (refreshView) refreshView(); + Page::onCancel(); +} \ No newline at end of file diff --git a/radio/src/gui/colorlcd/curveedit.h b/radio/src/gui/colorlcd/curveedit.h index 3f4819cd9..17ae694b9 100644 --- a/radio/src/gui/colorlcd/curveedit.h +++ b/radio/src/gui/colorlcd/curveedit.h @@ -82,13 +82,16 @@ class CurveDataEdit : public Window class CurveEditWindow : public Page { public: - CurveEditWindow(uint8_t index); + CurveEditWindow(uint8_t index, std::function refreshView = nullptr); protected: uint8_t index; CurveEdit * curveEdit = nullptr; CurveDataEdit * curveDataEdit = nullptr; + std::function refreshView = nullptr; void buildHeader(Window * window); void buildBody(Window * window); + + void onCancel() override; }; diff --git a/radio/src/gui/colorlcd/fullscreen_dialog.cpp b/radio/src/gui/colorlcd/fullscreen_dialog.cpp index e501bad6f..a29823ed4 100644 --- a/radio/src/gui/colorlcd/fullscreen_dialog.cpp +++ b/radio/src/gui/colorlcd/fullscreen_dialog.cpp @@ -74,8 +74,6 @@ FullScreenDialog::FullScreenDialog( build(); - lv_obj_add_event_cb(lvobj, FullScreenDialog::long_pressed, - LV_EVENT_LONG_PRESSED, nullptr); lv_obj_add_event_cb(lvobj, FullScreenDialog::on_draw, LV_EVENT_DRAW_MAIN_BEGIN, nullptr); } @@ -164,15 +162,11 @@ void FullScreenDialog::closeDialog() deleteLater(); } -void FullScreenDialog::long_pressed(lv_event_t* e) +bool FullScreenDialog::onLongPress() { - auto obj = lv_event_get_target(e); - auto fs = (FullScreenDialog*)lv_obj_get_user_data(obj); - - if (fs) { - fs->closeDialog(); - lv_indev_wait_release(lv_indev_get_act()); - } + closeDialog(); + lv_indev_wait_release(lv_indev_get_act()); + return false; } void FullScreenDialog::onEvent(event_t event) diff --git a/radio/src/gui/colorlcd/fullscreen_dialog.h b/radio/src/gui/colorlcd/fullscreen_dialog.h index 312135aeb..c5c1d9ba2 100644 --- a/radio/src/gui/colorlcd/fullscreen_dialog.h +++ b/radio/src/gui/colorlcd/fullscreen_dialog.h @@ -43,6 +43,7 @@ class FullScreenDialog : public Window void onEvent(event_t event) override; void onCancel() override; + bool onLongPress() override; void deleteLater(bool detach = true, bool trash = true) override; @@ -71,6 +72,5 @@ class FullScreenDialog : public Window virtual void delayedInit() {} void build(); - static void long_pressed(lv_event_t* e); static void on_draw(lv_event_t* e); }; diff --git a/radio/src/gui/colorlcd/input_edit.cpp b/radio/src/gui/colorlcd/input_edit.cpp index c407b4202..f99a4cacf 100644 --- a/radio/src/gui/colorlcd/input_edit.cpp +++ b/radio/src/gui/colorlcd/input_edit.cpp @@ -135,11 +135,15 @@ void InputEditWindow::buildBody(Window* form) line = form->newLine(grid); new StaticText(line, rect_t{}, STR_CURVE); auto param = - new CurveParam(line, rect_t{}, &input->curve, [=](int32_t newValue) { - input->curve.value = newValue; - preview->update(); - SET_DIRTY(); - }); + new CurveParam(line, rect_t{}, &input->curve, + [=](int32_t newValue) { + input->curve.value = newValue; + preview->update(); + SET_DIRTY(); + }, + [=]() { + preview->update(); + }); lv_obj_set_style_grid_cell_x_align(param->getLvObj(), LV_GRID_ALIGN_STRETCH, 0); diff --git a/radio/src/gui/colorlcd/listbox.cpp b/radio/src/gui/colorlcd/listbox.cpp index a1faf0526..1f49e2421 100644 --- a/radio/src/gui/colorlcd/listbox.cpp +++ b/radio/src/gui/colorlcd/listbox.cpp @@ -23,14 +23,6 @@ #include "libopenui.h" -// TODO: -// - split this into 2 handlers: -// - key_cb: PRESSED / LONG_PRESSED (always on) -// - focus_cb: for FOCUSED / DEFOCUSED (only w/ 'auto-edit' mode) -// - add 'auto-edit' mode (add / remove 'focus_cb') -// - when turned on, ESC gets out of the edit-mode -// and ENTER gets into edit-mode -// void ListBox::event_cb(lv_event_t* e) { static bool _nested = false; @@ -51,10 +43,6 @@ void ListBox::event_cb(lv_event_t* e) _nested = true; lv_group_set_editing((lv_group_t*)lv_obj_get_group(obj), false); _nested = false; - } else if (code == LV_EVENT_LONG_PRESSED) { - lb->onLongPressed(); - lv_obj_clear_state(obj, LV_STATE_PRESSED); - lv_indev_wait_release(lv_indev_get_act()); } } @@ -180,12 +168,15 @@ void ListBox::onPress(uint16_t row, uint16_t col) } } -void ListBox::onLongPressed() +bool ListBox::onLongPress() { TRACE("LONG_PRESS"); if (longPressHandler) { longPressHandler(); + lv_indev_wait_release(lv_indev_get_act()); + return false; } + return true; } // TODO: !auto-edit diff --git a/radio/src/gui/colorlcd/listbox.h b/radio/src/gui/colorlcd/listbox.h index 35d094c05..d7aff78db 100644 --- a/radio/src/gui/colorlcd/listbox.h +++ b/radio/src/gui/colorlcd/listbox.h @@ -95,7 +95,7 @@ class ListBox : public TableField bool smallSelectMarker = false; void onPress(uint16_t row, uint16_t col) override; - void onLongPressed(); + bool onLongPress() override; void onClicked() override; void onCancel() override; diff --git a/radio/src/gui/colorlcd/model_curves.cpp b/radio/src/gui/colorlcd/model_curves.cpp index c7b29962d..37936638d 100644 --- a/radio/src/gui/colorlcd/model_curves.cpp +++ b/radio/src/gui/colorlcd/model_curves.cpp @@ -122,7 +122,7 @@ ModelCurvesPage::ModelCurvesPage() : PageTab(STR_MENUCURVES, ICON_MODEL_CURVES) // can be called from any other screen to edit a curve. // currently called from model_mixes.cpp on longpress. -void ModelCurvesPage::pushEditCurve(int index) +void ModelCurvesPage::pushEditCurve(int index, std::function refreshView) { if (!isCurveUsed(index)) { CurveHeader &curve = g_model.curves[index]; @@ -130,7 +130,7 @@ void ModelCurvesPage::pushEditCurve(int index) initPoints(curve, points); } - new CurveEditWindow(index); + new CurveEditWindow(index, refreshView); } void ModelCurvesPage::rebuild(Window *window) diff --git a/radio/src/gui/colorlcd/model_curves.h b/radio/src/gui/colorlcd/model_curves.h index 89a1768d5..2a7ac6f65 100644 --- a/radio/src/gui/colorlcd/model_curves.h +++ b/radio/src/gui/colorlcd/model_curves.h @@ -28,7 +28,7 @@ class ModelCurvesPage : public PageTab { public: ModelCurvesPage(); - static void pushEditCurve(int index); + static void pushEditCurve(int index, std::function refreshView = nullptr); bool isVisible() const override { return modelCurvesEnabled(); } diff --git a/radio/src/gui/colorlcd/sourcechoice.cpp b/radio/src/gui/colorlcd/sourcechoice.cpp index b2ddab042..a5f5040f0 100644 --- a/radio/src/gui/colorlcd/sourcechoice.cpp +++ b/radio/src/gui/colorlcd/sourcechoice.cpp @@ -149,16 +149,14 @@ class SourceChoiceMenuToolbar : public MenuToolbar #endif }; -void SourceChoice::LongPressHandler(void* data) +bool SourceChoice::onLongPress() { - SourceChoice* src = (SourceChoice*)data; - if (src && src->canInvert) { - int16_t val = src->_getValue(); - if (src->isValueAvailable && src->isValueAvailable(-val)) { - src->setValue(-val); - src->invalidate(); - } + if (canInvert) { + int16_t val = _getValue(); + if (isValueAvailable && isValueAvailable(-val)) + setValue(-val); } + return true; } void SourceChoice::setValue(int value) @@ -234,7 +232,5 @@ SourceChoice::SourceChoice(Window *parent, const rect_t &rect, int16_t vmin, return std::string(getSourceString(value)); }); - set_lv_LongPressHandler(LongPressHandler, this); - setAvailableHandler([](int v) { return isSourceAvailable(v); }); } diff --git a/radio/src/gui/colorlcd/sourcechoice.h b/radio/src/gui/colorlcd/sourcechoice.h index 08a7fc368..288006ffd 100644 --- a/radio/src/gui/colorlcd/sourcechoice.h +++ b/radio/src/gui/colorlcd/sourcechoice.h @@ -35,8 +35,6 @@ class SourceChoice : public Choice std::function getValue, std::function setValue, bool allowInvert = false); - static void LongPressHandler(void* data); - protected: friend SourceChoiceMenuToolbar; @@ -45,6 +43,7 @@ class SourceChoice : public Choice void setValue(int value) override; int getIntValue() const override; + bool onLongPress() override; void invertChoice(); diff --git a/radio/src/gui/colorlcd/switchchoice.cpp b/radio/src/gui/colorlcd/switchchoice.cpp index 9c162801a..176ab8a5e 100644 --- a/radio/src/gui/colorlcd/switchchoice.cpp +++ b/radio/src/gui/colorlcd/switchchoice.cpp @@ -103,14 +103,12 @@ class SwitchChoiceMenuToolbar : public MenuToolbar #endif }; -void SwitchChoice::LongPressHandler(void* data) +bool SwitchChoice::onLongPress() { - SwitchChoice* swch = (SwitchChoice*)data; - if (!swch) return; - int16_t val = swch->_getValue(); - if (swch->isValueAvailable && swch->isValueAvailable(-val)) { - swch->setValue(-val); - } + int16_t val = _getValue(); + if (isValueAvailable && isValueAvailable(-val)) + setValue(-val); + return true; } void SwitchChoice::setValue(int value) @@ -182,7 +180,5 @@ SwitchChoice::SwitchChoice(Window* parent, const rect_t& rect, int vmin, return std::string(getSwitchPositionName(value)); }); - set_lv_LongPressHandler(LongPressHandler, this); - setAvailableHandler(isSwitchAvailableInMixes); } diff --git a/radio/src/gui/colorlcd/switchchoice.h b/radio/src/gui/colorlcd/switchchoice.h index 32fa70411..56525ddbb 100644 --- a/radio/src/gui/colorlcd/switchchoice.h +++ b/radio/src/gui/colorlcd/switchchoice.h @@ -33,8 +33,6 @@ class SwitchChoice : public Choice std::function getValue, std::function setValue); - static void LongPressHandler(void* data); - protected: friend SwitchChoiceMenuToolbar; @@ -42,6 +40,7 @@ class SwitchChoice : public Choice void setValue(int value) override; int getIntValue() const override; + bool onLongPress() override; void invertChoice(); diff --git a/radio/src/gui/colorlcd/view_main.cpp b/radio/src/gui/colorlcd/view_main.cpp index b1a9261a1..7d8ce8145 100644 --- a/radio/src/gui/colorlcd/view_main.cpp +++ b/radio/src/gui/colorlcd/view_main.cpp @@ -85,8 +85,6 @@ ViewMain::ViewMain() : lv_obj_add_event_cb(tile_view, tile_view_scroll, LV_EVENT_SCROLL, nullptr); lv_obj_add_event_cb(tile_view, tile_view_scroll, LV_EVENT_SCROLL_END, nullptr); - lv_obj_add_event_cb(lvobj, ViewMain::long_pressed, LV_EVENT_LONG_PRESSED, - nullptr); // create last to be on top topbar = TopbarFactory::create(this); @@ -342,7 +340,7 @@ void ViewMain::ws_timer(lv_timer_t* t) view->enableWidgetSelect(false); } -void ViewMain::longPress() +bool ViewMain::onLongPress() { if (isAppMode()) { int view = getCurrentMainView(); @@ -350,17 +348,8 @@ void ViewMain::longPress() } else { enableWidgetSelect(true); } -} - -void ViewMain::long_pressed(lv_event_t* e) -{ - auto obj = lv_event_get_target(e); - // kill subsequent CLICKED event - lv_obj_clear_state(obj, LV_STATE_PRESSED); lv_indev_wait_release(lv_indev_get_act()); - - auto view = (ViewMain*)lv_obj_get_user_data(obj); - if (view) view->longPress(); + return false; } void ViewMain::show(bool visible) diff --git a/radio/src/gui/colorlcd/view_main.h b/radio/src/gui/colorlcd/view_main.h index abb7d558d..3607badfd 100644 --- a/radio/src/gui/colorlcd/view_main.h +++ b/radio/src/gui/colorlcd/view_main.h @@ -72,7 +72,7 @@ class ViewMain : public NavWindow void onClicked() override; void onCancel() override; void openMenu(); - void longPress(); + bool onLongPress() override; void show(bool visible = true) override; void showTopBarEdgeTxButton(); @@ -103,7 +103,6 @@ class ViewMain : public NavWindow // Set topbar visibility [0.0 -> 1.0] void setTopbarVisible(float visible); - static void long_pressed(lv_event_t* e); static void ws_timer(lv_timer_t* t); #if defined(HARDWARE_KEYS) diff --git a/radio/src/gui/colorlcd/widget.cpp b/radio/src/gui/colorlcd/widget.cpp index 549b8b6f6..71a4d0376 100644 --- a/radio/src/gui/colorlcd/widget.cpp +++ b/radio/src/gui/colorlcd/widget.cpp @@ -144,9 +144,10 @@ void Widget::setFullscreen(bool enable) update(); } -void Widget::onLongPress() +bool Widget::onLongPress() { if (!fullscreen) ButtonBase::onLongPress(); + return true; } const ZoneOption* Widget::getOptions() const diff --git a/radio/src/gui/colorlcd/widget.h b/radio/src/gui/colorlcd/widget.h index 3719d19a6..8b77c7270 100644 --- a/radio/src/gui/colorlcd/widget.h +++ b/radio/src/gui/colorlcd/widget.h @@ -97,7 +97,7 @@ class Widget : public ButtonBase lv_point_t borderPts[5]; void onCancel() override; - void onLongPress() override; + bool onLongPress() override; virtual void onFullscreen(bool enable) {} void openMenu(); diff --git a/radio/src/keys.cpp b/radio/src/keys.cpp index b1f8a2f26..e28a3530c 100644 --- a/radio/src/keys.cpp +++ b/radio/src/keys.cpp @@ -97,9 +97,15 @@ event_t Key::input(bool val) if ((m_state || m_flags) && m_vals == 0) { // key is released +#if defined(COLORLCD) + if ((m_flags & (KFLAG_KILLED)) == 0) { + evt = (m_flags & KFLAG_LONG_PRESS) ? _MSK_KEY_LONG_BRK : _MSK_KEY_BREAK; + } +#else if ((m_flags & (KFLAG_KILLED|KFLAG_LONG_PRESS)) == 0) { evt = _MSK_KEY_BREAK; } +#endif m_state = KSTATE_OFF; m_cnt = 0; m_flags = 0; diff --git a/radio/src/keys.h b/radio/src/keys.h index b631affb1..eda2586f2 100644 --- a/radio/src/keys.h +++ b/radio/src/keys.h @@ -38,6 +38,7 @@ constexpr event_t _MSK_KEY_BREAK = 0x0200; constexpr event_t _MSK_KEY_REPT = 0x0400; constexpr event_t _MSK_KEY_FIRST = 0x0600; constexpr event_t _MSK_KEY_LONG = 0x0800; +constexpr event_t _MSK_KEY_LONG_BRK = 0x0A00; constexpr event_t _MSK_KEY_FLAGS = 0x0E00; #else constexpr event_t _MSK_KEY_BREAK = 0x0020; diff --git a/radio/src/thirdparty/libopenui/src/button.cpp b/radio/src/thirdparty/libopenui/src/button.cpp index 99e86bbc8..65d106c03 100644 --- a/radio/src/thirdparty/libopenui/src/button.cpp +++ b/radio/src/thirdparty/libopenui/src/button.cpp @@ -58,8 +58,6 @@ ButtonBase::ButtonBase(Window* parent, const rect_t& rect, objConstruct ? objConstruct : lv_btn_create), pressHandler(std::move(pressHandler)) { - lv_obj_add_event_cb(lvobj, ButtonBase::long_pressed, LV_EVENT_LONG_PRESSED, - nullptr); } void ButtonBase::check(bool checked) @@ -81,13 +79,15 @@ bool ButtonBase::checked() const void ButtonBase::onPress() { check(pressHandler && pressHandler()); } -void ButtonBase::onLongPress() +bool ButtonBase::onLongPress() { if (longPressHandler) { check(longPressHandler()); lv_obj_clear_state(lvobj, LV_STATE_PRESSED); lv_indev_wait_release(lv_indev_get_act()); + return false; } + return true; } void ButtonBase::onClicked() { onPress(); } @@ -98,13 +98,6 @@ void ButtonBase::checkEvents() if (checkHandler) checkHandler(); } -void ButtonBase::long_pressed(lv_event_t* e) -{ - auto obj = lv_event_get_target(e); - auto btn = (ButtonBase*)lv_obj_get_user_data(obj); - if (obj) btn->onLongPress(); -} - TextButton::TextButton(Window* parent, const rect_t& rect, std::string text, std::function pressHandler) : ButtonBase(parent, rect, pressHandler, button_create), diff --git a/radio/src/thirdparty/libopenui/src/button.h b/radio/src/thirdparty/libopenui/src/button.h index 920339c6b..82e18958d 100644 --- a/radio/src/thirdparty/libopenui/src/button.h +++ b/radio/src/thirdparty/libopenui/src/button.h @@ -36,7 +36,7 @@ class ButtonBase : public FormField #endif virtual void onPress(); - virtual void onLongPress(); + bool onLongPress() override; void onClicked() override; void checkEvents() override; @@ -63,8 +63,6 @@ class ButtonBase : public FormField std::function pressHandler; std::function longPressHandler; std::function checkHandler; - - static void long_pressed(lv_event_t* e); }; class Button : public ButtonBase diff --git a/radio/src/thirdparty/libopenui/src/choice.cpp b/radio/src/thirdparty/libopenui/src/choice.cpp index ab879cd92..6593f1491 100644 --- a/radio/src/thirdparty/libopenui/src/choice.cpp +++ b/radio/src/thirdparty/libopenui/src/choice.cpp @@ -110,8 +110,7 @@ Choice::Choice(Window* parent, const rect_t& rect, int vmin, int vmax, vmax(vmax), menuTitle(title), _getValue(std::move(_getValue)), - _setValue(std::move(_setValue)), - longPressData({}) + _setValue(std::move(_setValue)) { lv_event_send(lvobj, LV_EVENT_VALUE_CHANGED, nullptr); } @@ -124,8 +123,7 @@ Choice::Choice(Window* parent, const rect_t& rect, const char* const values[], vmax(vmax), menuTitle(title), _getValue(std::move(_getValue)), - _setValue(std::move(_setValue)), - longPressData({}) + _setValue(std::move(_setValue)) { setValues(values); lv_event_send(lvobj, LV_EVENT_VALUE_CHANGED, nullptr); @@ -141,8 +139,7 @@ Choice::Choice(Window* parent, const rect_t& rect, vmax(vmax), menuTitle(title), _getValue(std::move(_getValue)), - _setValue(std::move(_setValue)), - longPressData({}) + _setValue(std::move(_setValue)) { lv_event_send(lvobj, LV_EVENT_VALUE_CHANGED, nullptr); } @@ -179,7 +176,7 @@ void Choice::setValue(int val) void Choice::onClicked() { - if (!longPressData.isLongPressed) openMenu(); + openMenu(); } void Choice::fillMenu(Menu* menu, const FilterFct& filter) @@ -235,23 +232,3 @@ void Choice::openMenu() menu->setCloseHandler([=]() { setEditMode(false); }); } - -static void localLongPressHandler(lv_event_t* e) -{ - lv_eventData_t* ld = (lv_eventData_t*)lv_event_get_user_data(e); - ld->isLongPressed = true; - ld->lv_LongPressHandler(ld->userData); -} - -void Choice::set_lv_LongPressHandler(lvHandler_t longPressHandler, void* data) -{ - TRACE("longPressHandler=%p", longPressHandler); - - if (longPressHandler) { - longPressData.userData = data; - longPressData.lv_LongPressHandler = longPressHandler; - lv_obj_add_event_cb(lvobj, localLongPressHandler, LV_EVENT_LONG_PRESSED, - &longPressData); - lv_obj_add_event_cb(lvobj, ClickHandler, LV_EVENT_CLICKED, this); - } -} diff --git a/radio/src/thirdparty/libopenui/src/choice.h b/radio/src/thirdparty/libopenui/src/choice.h index b21be8348..96bea3a49 100644 --- a/radio/src/thirdparty/libopenui/src/choice.h +++ b/radio/src/thirdparty/libopenui/src/choice.h @@ -22,14 +22,6 @@ #include "form.h" -typedef void (*lvHandler_t)(void *); - -typedef struct { - void *userData; - bool isLongPressed; - lvHandler_t lv_LongPressHandler; -} lv_eventData_t; - class Menu; enum ChoiceType { @@ -153,8 +145,6 @@ class Choice : public ChoiceBase std::string getString(int val) { return values[val]; } - void set_lv_LongPressHandler(lvHandler_t longPressHandler, void *data); - int selectedIx0 = 0; protected: @@ -177,13 +167,4 @@ class Choice : public ChoiceBase void fillMenu(Menu *menu, const FilterFct &filter = nullptr); virtual void openMenu(); - - lv_eventData_t longPressData; - std::function longPressHandler = nullptr; - - static void ClickHandler(lv_event_t *e) - { - auto ch = (Choice *)lv_event_get_user_data(e); - if (ch) ch->longPressData.isLongPressed = false; - } }; diff --git a/radio/src/thirdparty/libopenui/src/menu.cpp b/radio/src/thirdparty/libopenui/src/menu.cpp index 6790b3bfa..33ae20a6e 100644 --- a/radio/src/thirdparty/libopenui/src/menu.cpp +++ b/radio/src/thirdparty/libopenui/src/menu.cpp @@ -91,9 +91,6 @@ class MenuBody : public TableField }); lv_group_set_editing(g, true); } - - lv_obj_add_event_cb(lvobj, MenuBody::localLongPressHandler, - LV_EVENT_LONG_PRESSED, this); } #if defined(DEBUG_WINDOWS) @@ -219,13 +216,6 @@ class MenuBody : public TableField isLongPressed = false; } - void longPress() - { - isLongPressed = true; - Menu* menu = getParentMenu(); - if (menu) menu->longPress(); - } - void onDrawBegin(uint16_t row, uint16_t col, lv_obj_draw_part_dsc_t* dsc) override { @@ -284,12 +274,6 @@ class MenuBody : public TableField int selectedIndex = 0; Menu* getParentMenu() { return static_cast(getParent()->getParent()); } - - static void localLongPressHandler(lv_event_t* e) - { - MenuBody* menuBody = (MenuBody*)lv_event_get_user_data(e); - if (menuBody) menuBody->longPress(); - } }; //----------------------------------------------------------------------------- @@ -451,11 +435,6 @@ void Menu::onCancel() deleteLater(); } -void Menu::longPress() -{ - if (toolbar) toolbar->longPress(); -} - void Menu::setCancelHandler(std::function handler) { cancelHandler = std::move(handler); diff --git a/radio/src/thirdparty/libopenui/src/menu.h b/radio/src/thirdparty/libopenui/src/menu.h index 9c4fa8343..c7867f75c 100644 --- a/radio/src/thirdparty/libopenui/src/menu.h +++ b/radio/src/thirdparty/libopenui/src/menu.h @@ -83,8 +83,6 @@ class Menu : public ModalWindow } } - void longPress(); - protected: bool multiple; MenuWindowContent *content; diff --git a/radio/src/thirdparty/libopenui/src/menutoolbar.cpp b/radio/src/thirdparty/libopenui/src/menutoolbar.cpp index 0458b8a84..d9edc9602 100644 --- a/radio/src/thirdparty/libopenui/src/menutoolbar.cpp +++ b/radio/src/thirdparty/libopenui/src/menutoolbar.cpp @@ -22,9 +22,6 @@ #include "themes/etx_lv_theme.h" #include "translations.h" -constexpr uint32_t MENUS_TOOLBAR_BUTTON_WIDTH = 36; -constexpr uint32_t MENUS_TOOLBAR_BUTTON_HEIGHT = 32; - static const lv_obj_class_t menu_button_class = { .base_class = &button_class, .constructor_cb = nullptr, @@ -116,13 +113,13 @@ rect_t MenuToolbar::getButtonRect(bool wideButton) coord_t x = (nxtBtnPos % filterColumns) * (MENUS_TOOLBAR_BUTTON_WIDTH + PAD_SMALL); coord_t y = - (nxtBtnPos / filterColumns) * (MENUS_TOOLBAR_BUTTON_HEIGHT + PAD_SMALL); + (nxtBtnPos / filterColumns) * (EdgeTxStyles::UI_ELEMENT_HEIGHT + PAD_SMALL); coord_t w = wideButton ? (MENUS_TOOLBAR_BUTTON_WIDTH + PAD_SMALL) * (filterColumns - 1) + MENUS_TOOLBAR_BUTTON_WIDTH : MENUS_TOOLBAR_BUTTON_WIDTH; nxtBtnPos += wideButton ? filterColumns : 1; - return {x, y, w, MENUS_TOOLBAR_BUTTON_HEIGHT}; + return {x, y, w, EdgeTxStyles::UI_ELEMENT_HEIGHT}; } bool MenuToolbar::filterMenu(MenuToolbarButton* btn, int16_t filtermin, diff --git a/radio/src/thirdparty/libopenui/src/menutoolbar.h b/radio/src/thirdparty/libopenui/src/menutoolbar.h index 6d287e56f..c0e97d404 100644 --- a/radio/src/thirdparty/libopenui/src/menutoolbar.h +++ b/radio/src/thirdparty/libopenui/src/menutoolbar.h @@ -45,13 +45,8 @@ class MenuToolbar : public Window virtual void longPress() {} - static LAYOUT_VAL(MENUS_TOOLBAR_BUTTON_WIDTH, 32, 32) - -#if PORTRAIT_LCD - static constexpr coord_t MENUS_MAX_HEIGHT = (ListBox::MENUS_LINE_HEIGHT * 10); -#else - static constexpr coord_t MENUS_MAX_HEIGHT = (ListBox::MENUS_LINE_HEIGHT * 7) + 8; -#endif + static LAYOUT_VAL(MENUS_TOOLBAR_BUTTON_WIDTH, 36, 36) + static LAYOUT_VAL(MENUS_MAX_HEIGHT, ListBox::MENUS_LINE_HEIGHT * 7 + 8, ListBox::MENUS_LINE_HEIGHT * 10) protected: Choice* choice; diff --git a/radio/src/thirdparty/libopenui/src/numberedit.cpp b/radio/src/thirdparty/libopenui/src/numberedit.cpp index 43aff5d68..003f1551b 100644 --- a/radio/src/thirdparty/libopenui/src/numberedit.cpp +++ b/radio/src/thirdparty/libopenui/src/numberedit.cpp @@ -45,6 +45,14 @@ class NumberArea : public FormField lv_obj_add_event_cb(lvobj, NumberArea::numberedit_cb, LV_EVENT_KEY, this); + setFocusHandler([=](bool focus) { + if (!focus && editMode) { + setEditMode(false); + hide(); + lv_obj_clear_state(parent->getLvObj(), LV_STATE_FOCUSED); + } + }); + update(); } @@ -150,6 +158,7 @@ class NumberArea : public FormField setEditMode(true); } else { FormField::onClicked(); + if (!editMode) changeEnd(); } } @@ -316,12 +325,12 @@ void NumberEdit::openEdit() this->vmin, this->vmax, _getValue, _setValue, textFlags); edit->setChangeHandler([=]() { update(); - lv_group_focus_obj(lvobj); + if (edit->hasFocus()) + lv_group_focus_obj(lvobj); edit->hide(); }); edit->setCancelHandler([=]() { - lv_group_focus_obj(lvobj); - edit->hide(); + edit->onClicked(); }); } edit->setTextFlag(textFlags); diff --git a/radio/src/thirdparty/libopenui/src/window.cpp b/radio/src/thirdparty/libopenui/src/window.cpp index f1bb8c79e..5ba196d0b 100644 --- a/radio/src/thirdparty/libopenui/src/window.cpp +++ b/radio/src/thirdparty/libopenui/src/window.cpp @@ -24,6 +24,7 @@ #include "themes/etx_lv_theme.h" std::list Window::trash; +bool Window::_longPressed = false; const lv_obj_class_t window_base_class = { .base_class = &lv_obj_class, @@ -43,49 +44,60 @@ lv_obj_t *window_create(lv_obj_t *parent) } void Window::window_event_cb(lv_event_t *e) +{ + Window *window = (Window *)lv_obj_get_user_data(lv_event_get_target(e)); + if (window) + window->eventHandler(e); +} + +void Window::eventHandler(lv_event_t *e) { lv_obj_t *target = lv_event_get_target(e); lv_event_code_t code = lv_event_get_code(e); - Window *window = (Window *)lv_obj_get_user_data(target); - if (window) { - if (code == LV_EVENT_DELETE || window->deleted()) return; + if (code == LV_EVENT_DELETE || deleted()) return; - switch (code) { - case LV_EVENT_SCROLL: { - // exclude pointer based scrolling (only focus scrolling) - if (!lv_obj_is_scrolling(target)) { - lv_point_t *p = (lv_point_t *)lv_event_get_param(e); - lv_coord_t scroll_bottom = lv_obj_get_scroll_bottom(target); + switch (code) { + case LV_EVENT_SCROLL: { + // exclude pointer based scrolling (only focus scrolling) + if (!lv_obj_is_scrolling(target)) { + lv_point_t *p = (lv_point_t *)lv_event_get_param(e); + lv_coord_t scroll_bottom = lv_obj_get_scroll_bottom(target); - lv_coord_t scroll_y = lv_obj_get_scroll_y(target); - TRACE("SCROLL[x=%d;y=%d;top=%d;bottom=%d]", p->x, p->y, scroll_y, - scroll_bottom); + lv_coord_t scroll_y = lv_obj_get_scroll_y(target); + TRACE("SCROLL[x=%d;y=%d;top=%d;bottom=%d]", p->x, p->y, scroll_y, + scroll_bottom); - if (scroll_y <= 45 && p->y > 0) { - lv_obj_scroll_by(target, 0, scroll_y, LV_ANIM_OFF); - } else if (scroll_bottom <= 16 && p->y < 0) { - lv_obj_scroll_by(target, 0, -scroll_bottom, LV_ANIM_OFF); - } + if (scroll_y <= 45 && p->y > 0) { + lv_obj_scroll_by(target, 0, scroll_y, LV_ANIM_OFF); + } else if (scroll_bottom <= 16 && p->y < 0) { + lv_obj_scroll_by(target, 0, -scroll_bottom, LV_ANIM_OFF); } - } break; - case LV_EVENT_CLICKED: - TRACE("CLICKED[%p]", window); - window->onClicked(); - break; - case LV_EVENT_CANCEL: - TRACE("CANCEL[%p]", window); - window->onCancel(); - break; - case LV_EVENT_FOCUSED: - if (window->focusHandler) window->focusHandler(true); - break; - case LV_EVENT_DEFOCUSED: - if (window->focusHandler) window->focusHandler(false); - break; - default: - break; - } + } + } break; + case LV_EVENT_CLICKED: + if (!_longPressed) { + TRACE("CLICKED[%p]", this); + onClicked(); + } + _longPressed = false; + break; + case LV_EVENT_CANCEL: + TRACE("CANCEL[%p]", this); + onCancel(); + break; + case LV_EVENT_FOCUSED: + if (focusHandler) focusHandler(true); + break; + case LV_EVENT_DEFOCUSED: + if (focusHandler) focusHandler(false); + break; + case LV_EVENT_LONG_PRESSED: + TRACE("LONG PRESS[%p]", this); + _longPressed = onLongPress(); + break; + default: + break; } } @@ -295,23 +307,25 @@ void Window::onEvent(event_t event) { TRACE_WINDOWS("%s received event 0x%X", Window::getWindowDebugString("Window").c_str(), event); - if (parent) { + if (parent) parent->onEvent(event); - } } void Window::onClicked() { - if (parent && !(windowFlags & OPAQUE)) { + if (parent && !(windowFlags & OPAQUE)) parent->onClicked(); - } } void Window::onCancel() { - if (parent) { + if (parent) parent->onCancel(); - } +} + +bool Window::onLongPress() +{ + return true; } void Window::addChild(Window *window) @@ -355,21 +369,25 @@ FormLine *Window::newLine(FlexGridLayout &layout) void Window::show(bool visible) { - if (lv_obj_has_flag(lvobj, LV_OBJ_FLAG_HIDDEN) == visible) { - if (visible) - lv_obj_clear_flag(lvobj, LV_OBJ_FLAG_HIDDEN); - else - lv_obj_add_flag(lvobj, LV_OBJ_FLAG_HIDDEN); + if (!_deleted && lvobj) { + if (lv_obj_has_flag(lvobj, LV_OBJ_FLAG_HIDDEN) == visible) { + if (visible) + lv_obj_clear_flag(lvobj, LV_OBJ_FLAG_HIDDEN); + else + lv_obj_add_flag(lvobj, LV_OBJ_FLAG_HIDDEN); + } } } void Window::enable(bool enabled) { - if (lv_obj_has_state(lvobj, LV_STATE_DISABLED) == enabled) { - if (enabled) - lv_obj_clear_state(lvobj, LV_STATE_DISABLED); - else - lv_obj_add_state(lvobj, LV_STATE_DISABLED); + if (!_deleted && lvobj) { + if (lv_obj_has_state(lvobj, LV_STATE_DISABLED) == enabled) { + if (enabled) + lv_obj_clear_state(lvobj, LV_STATE_DISABLED); + else + lv_obj_add_state(lvobj, LV_STATE_DISABLED); + } } } diff --git a/radio/src/thirdparty/libopenui/src/window.h b/radio/src/thirdparty/libopenui/src/window.h index 8f61a96ca..739abec65 100644 --- a/radio/src/thirdparty/libopenui/src/window.h +++ b/radio/src/thirdparty/libopenui/src/window.h @@ -144,6 +144,7 @@ class Window virtual void onEvent(event_t event); virtual void onClicked(); virtual void onCancel(); + virtual bool onLongPress(); void invalidate(); @@ -192,6 +193,7 @@ class Window LcdFlags textFlags = 0; bool _deleted = false; + static bool _longPressed; std::function closeHandler; std::function focusHandler; @@ -201,6 +203,7 @@ class Window virtual void addChild(Window *window); void removeChild(Window *window); + void eventHandler(lv_event_t *e); static void window_event_cb(lv_event_t *e); };