diff --git a/src/displayapp/screens/Metronome.cpp b/src/displayapp/screens/Metronome.cpp index 314fde73e0..c1905b28d1 100644 --- a/src/displayapp/screens/Metronome.cpp +++ b/src/displayapp/screens/Metronome.cpp @@ -38,12 +38,17 @@ Metronome::Metronome(Controllers::MotorController& motorController, System::Syst bpmValue = createLabel("120", bpmArc, LV_ALIGN_IN_TOP_MID, &jetbrains_mono_76, 0, 55); createLabel("bpm", bpmValue, LV_ALIGN_OUT_BOTTOM_MID, &jetbrains_mono_bold_20, 0, 0); + bpmCounter.Create(); + bpmCounter.SetValue(bpm); + lv_obj_align(bpmCounter.GetObject(), lv_scr_act(), LV_ALIGN_IN_TOP_MID, 0, 0); + lv_obj_set_hidden(bpmCounter.GetObject(), true); + bpmTap = lv_btn_create(lv_scr_act(), nullptr); bpmTap->user_data = this; lv_obj_set_event_cb(bpmTap, eventHandler); lv_obj_set_style_local_bg_opa(bpmTap, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); lv_obj_set_height(bpmTap, 80); - lv_obj_align(bpmTap, bpmValue, LV_ALIGN_IN_TOP_MID, 0, 0); + lv_obj_align(bpmTap, bpmCounter.GetObject(), LV_ALIGN_CENTER, 0, 0); bpbDropdown = lv_dropdown_create(lv_scr_act(), nullptr); bpbDropdown->user_data = this; @@ -77,6 +82,11 @@ Metronome::~Metronome() { } void Metronome::Refresh() { + if (bpm != bpmCounter.GetValue()) { + bpm = bpmCounter.GetValue(); + lv_arc_set_value(bpmArc, bpm); + lv_label_set_text_fmt(bpmValue, "%03d", bpm); + } if (metronomeStarted) { if (xTaskGetTickCount() - startTime > 60u * configTICK_RATE_HZ / static_cast(bpm)) { startTime += 60 * configTICK_RATE_HZ / bpm; @@ -96,6 +106,7 @@ void Metronome::OnEvent(lv_obj_t* obj, lv_event_t event) { case LV_EVENT_VALUE_CHANGED: { if (obj == bpmArc) { bpm = lv_arc_get_value(bpmArc); + bpmCounter.SetValue(bpm); lv_label_set_text_fmt(bpmValue, "%03d", bpm); } else if (obj == bpbDropdown) { bpb = lv_dropdown_get_selected(obj) + 1; @@ -104,20 +115,27 @@ void Metronome::OnEvent(lv_obj_t* obj, lv_event_t event) { } break; } - case LV_EVENT_PRESSED: { + case LV_EVENT_PRESSED: { // if bmp is tapped, record the tap... + if (obj == bpmTap) { + delta = xTaskGetTickCount() - tappedTime; + tappedTime = xTaskGetTickCount(); + if (lv_obj_get_hidden(bpmCounter.GetObject())) { + allowExit = true; + } + } + break; + } + case LV_EVENT_RELEASED: { // but only commit the change if the tap leaves the button as well, so as not to capture bpm on swipe events if (obj == bpmTap) { - TickType_t delta = xTaskGetTickCount() - tappedTime; if (tappedTime != 0 && delta < configTICK_RATE_HZ * 3) { bpm = configTICK_RATE_HZ * 60 / delta; lv_arc_set_value(bpmArc, bpm); lv_label_set_text_fmt(bpmValue, "%03d", bpm); + bpmCounter.SetValue(bpm); } - tappedTime = xTaskGetTickCount(); - allowExit = true; } break; } - case LV_EVENT_RELEASED: case LV_EVENT_PRESS_LOST: if (obj == bpmTap) { allowExit = false; @@ -141,11 +159,26 @@ void Metronome::OnEvent(lv_obj_t* obj, lv_event_t event) { default: break; } + if (obj == bpbDropdown) { // if the user is interacting with the dropdown, take note + inDropdown = true; + } else { + inDropdown = false; + } } bool Metronome::OnTouchEvent(TouchEvents event) { - if (event == TouchEvents::SwipeDown && allowExit) { - running = false; + if (!inDropdown) { // only parse swipe events when not in the dropdown menu + if (event == TouchEvents::SwipeDown) { + if (allowExit) { + return false; + } + lv_obj_set_hidden(bpmArc, false); + lv_obj_set_hidden(bpmCounter.GetObject(), true); + } else if (event == TouchEvents::SwipeUp) { + lv_obj_set_hidden(bpmCounter.GetObject(), false); + lv_obj_set_hidden(bpmArc, true); + allowExit = false; + } } return true; } diff --git a/src/displayapp/screens/Metronome.h b/src/displayapp/screens/Metronome.h index 13b0d66491..aac18dc950 100644 --- a/src/displayapp/screens/Metronome.h +++ b/src/displayapp/screens/Metronome.h @@ -3,6 +3,7 @@ #include "systemtask/SystemTask.h" #include "components/motor/MotorController.h" #include "displayapp/screens/Screen.h" +#include "displayapp/widgets/Counter.h" namespace Pinetime { namespace Applications { @@ -19,6 +20,7 @@ namespace Pinetime { private: TickType_t startTime = 0; TickType_t tappedTime = 0; + TickType_t delta = 0; Controllers::MotorController& motorController; System::SystemTask& systemTask; int16_t bpm = 120; @@ -27,12 +29,15 @@ namespace Pinetime { bool metronomeStarted = false; bool allowExit = false; + bool inDropdown = false; // used to block swipes while dropdown is open lv_obj_t *bpmArc, *bpmTap, *bpmValue; lv_obj_t *bpbDropdown, *currentBpbText; lv_obj_t* playPause; lv_obj_t* lblPlayPause; + Widgets::Counter bpmCounter = Widgets::Counter(40, 220, jetbrains_mono_76); + lv_task_t* taskRefresh; }; }