Skip to content

Commit 6192775

Browse files
Riksu9000JF002
authored andcommitted
Improve metronome
1 parent 7c28de0 commit 6192775

3 files changed

Lines changed: 69 additions & 99 deletions

File tree

src/displayapp/DisplayApp.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,7 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction)
414414
break;
415415
case Apps::Metronome:
416416
currentScreen = std::make_unique<Screens::Metronome>(this, motorController, *systemTask);
417+
ReturnApp(Apps::Launcher, FullRefreshDirections::Down, TouchEvents::None);
417418
break;
418419
case Apps::Motion:
419420
currentScreen = std::make_unique<Screens::Motion>(this, motionController);
Lines changed: 44 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,15 @@
11
#include "Metronome.h"
2-
3-
#include "Screen.h"
42
#include "Symbols.h"
5-
#include "lvgl/lvgl.h"
6-
#include "FreeRTOSConfig.h"
7-
#include "task.h"
8-
9-
#include <string>
10-
#include <tuple>
113

124
using namespace Pinetime::Applications::Screens;
135

146
namespace {
15-
float calculateDelta(const TickType_t startTime, const TickType_t currentTime) {
16-
TickType_t delta = 0;
17-
// Take care of overflow
18-
if (startTime > currentTime) {
19-
delta = 0xffffffff - startTime;
20-
delta += (currentTime + 1);
21-
} else {
22-
delta = currentTime - startTime;
23-
}
24-
return static_cast<float>(delta) / static_cast<float>(configTICK_RATE_HZ);
25-
}
26-
27-
static void eventHandler(lv_obj_t* obj, lv_event_t event) {
28-
Metronome* screen = static_cast<Metronome*>(obj->user_data);
7+
void eventHandler(lv_obj_t* obj, lv_event_t event) {
8+
auto* screen = static_cast<Metronome*>(obj->user_data);
299
screen->OnEvent(obj, event);
3010
}
3111

32-
lv_obj_t* createLabel(const char* name, lv_obj_t* reference, lv_align_t align, lv_font_t* font, uint8_t x = 0, uint8_t y = 0) {
12+
lv_obj_t* createLabel(const char* name, lv_obj_t* reference, lv_align_t align, lv_font_t* font, uint8_t x, uint8_t y) {
3313
lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr);
3414
lv_obj_set_style_local_text_font(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font);
3515
lv_obj_set_style_local_text_color(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY);
@@ -41,7 +21,7 @@ namespace {
4121
}
4222

4323
Metronome::Metronome(DisplayApp* app, Controllers::MotorController& motorController, System::SystemTask& systemTask)
44-
: Screen(app), running {true}, currentState {States::Stopped}, startTime {}, motorController {motorController}, systemTask {systemTask} {
24+
: Screen(app), motorController {motorController}, systemTask {systemTask} {
4525

4626
bpmArc = lv_arc_create(lv_scr_act(), nullptr);
4727
bpmArc->user_data = this;
@@ -52,10 +32,10 @@ Metronome::Metronome(DisplayApp* app, Controllers::MotorController& motorControl
5232
lv_arc_set_value(bpmArc, bpm);
5333
lv_obj_set_size(bpmArc, 210, 210);
5434
lv_arc_set_adjustable(bpmArc, true);
55-
lv_obj_align(bpmArc, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 0, 7);
35+
lv_obj_align(bpmArc, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 0, 0);
5636

57-
bpmValue = createLabel(std::to_string(lv_arc_get_value(bpmArc)).c_str(), bpmArc, LV_ALIGN_IN_TOP_MID, &jetbrains_mono_76, 0, 55);
58-
bpmLegend = createLabel("bpm", bpmValue, LV_ALIGN_OUT_BOTTOM_MID, &jetbrains_mono_bold_20, 0, 0);
37+
bpmValue = createLabel("120", bpmArc, LV_ALIGN_IN_TOP_MID, &jetbrains_mono_76, 0, 55);
38+
createLabel("bpm", bpmValue, LV_ALIGN_OUT_BOTTOM_MID, &jetbrains_mono_bold_20, 0, 0);
5939

6040
bpmTap = lv_btn_create(lv_scr_act(), nullptr);
6141
bpmTap->user_data = this;
@@ -69,20 +49,23 @@ Metronome::Metronome(DisplayApp* app, Controllers::MotorController& motorControl
6949
lv_obj_set_event_cb(bpbDropdown, eventHandler);
7050
lv_obj_set_style_local_pad_left(bpbDropdown, LV_DROPDOWN_PART_MAIN, LV_STATE_DEFAULT, 20);
7151
lv_obj_set_style_local_pad_left(bpbDropdown, LV_DROPDOWN_PART_LIST, LV_STATE_DEFAULT, 20);
72-
lv_obj_align(bpbDropdown, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 15, -4);
52+
lv_obj_set_size(bpbDropdown, 115, 50);
53+
lv_obj_align(bpbDropdown, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 0, 0);
7354
lv_dropdown_set_options(bpbDropdown, "1\n2\n3\n4\n5\n6\n7\n8\n9");
7455
lv_dropdown_set_selected(bpbDropdown, bpb - 1);
75-
bpbLegend = lv_label_create(bpbDropdown, nullptr);
76-
lv_label_set_text(bpbLegend, "bpb");
77-
lv_obj_align(bpbLegend, bpbDropdown, LV_ALIGN_IN_RIGHT_MID, -15, 0);
56+
lv_dropdown_set_show_selected(bpbDropdown, false);
57+
lv_dropdown_set_text(bpbDropdown, "");
58+
59+
currentBpbText = lv_label_create(bpbDropdown, nullptr);
60+
lv_label_set_text_fmt(currentBpbText, "%d bpb", bpb);
61+
lv_obj_align(currentBpbText, bpbDropdown, LV_ALIGN_CENTER, 0, 0);
7862

7963
playPause = lv_btn_create(lv_scr_act(), nullptr);
8064
playPause->user_data = this;
8165
lv_obj_set_event_cb(playPause, eventHandler);
82-
lv_obj_align(playPause, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, -15, -10);
83-
lv_obj_set_height(playPause, 39);
84-
playPauseLabel = lv_label_create(playPause, nullptr);
85-
lv_label_set_text(playPauseLabel, Symbols::play);
66+
lv_obj_set_size(playPause, 115, 50);
67+
lv_obj_align(playPause, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0);
68+
lv_obj_set_style_local_value_str(playPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Symbols::play);
8669

8770
app->SetTouchMode(DisplayApp::TouchModes::Polling);
8871
}
@@ -93,28 +76,17 @@ Metronome::~Metronome() {
9376
lv_obj_clean(lv_scr_act());
9477
}
9578

96-
bool Metronome::OnTouchEvent(Pinetime::Applications::TouchEvents event) {
97-
return true;
98-
}
99-
10079
bool Metronome::Refresh() {
101-
switch (currentState) {
102-
case States::Stopped: {
103-
break;
104-
}
105-
case States::Running: {
106-
if (calculateDelta(startTime, xTaskGetTickCount()) >= (60.0 / bpm)) {
107-
counter--;
108-
startTime -= 60.0 / bpm;
109-
startTime = xTaskGetTickCount();
110-
if (counter == 0) {
111-
counter = bpb;
112-
motorController.SetDuration(90);
113-
} else {
114-
motorController.SetDuration(30);
115-
}
80+
if (metronomeStarted) {
81+
if (xTaskGetTickCount() - startTime > 60 * configTICK_RATE_HZ / bpm) {
82+
startTime += 60 * configTICK_RATE_HZ / bpm;
83+
counter--;
84+
if (counter == 0) {
85+
counter = bpb;
86+
motorController.SetDuration(90);
87+
} else {
88+
motorController.SetDuration(30);
11689
}
117-
break;
11890
}
11991
}
12092
return running;
@@ -128,42 +100,39 @@ void Metronome::OnEvent(lv_obj_t* obj, lv_event_t event) {
128100
lv_label_set_text_fmt(bpmValue, "%03d", bpm);
129101
} else if (obj == bpbDropdown) {
130102
bpb = lv_dropdown_get_selected(obj) + 1;
103+
lv_label_set_text_fmt(currentBpbText, "%d bpb", bpb);
104+
lv_obj_realign(currentBpbText);
131105
}
132106
break;
133107
}
134108
case LV_EVENT_PRESSED: {
135109
if (obj == bpmTap) {
136-
float timeDelta = calculateDelta(tappedTime, xTaskGetTickCount());
137-
if (tappedTime == 0 || timeDelta > 3) {
138-
tappedTime = xTaskGetTickCount();
139-
} else {
140-
bpm = ceil(60.0 / timeDelta);
110+
TickType_t delta = xTaskGetTickCount() - tappedTime;
111+
if (tappedTime != 0 && delta < configTICK_RATE_HZ * 3) {
112+
bpm = configTICK_RATE_HZ * 60 / delta;
141113
lv_arc_set_value(bpmArc, bpm);
142114
lv_label_set_text_fmt(bpmValue, "%03d", bpm);
143-
tappedTime = xTaskGetTickCount();
144115
}
116+
tappedTime = xTaskGetTickCount();
145117
}
146118
break;
147119
}
148120
case LV_EVENT_CLICKED: {
149121
if (obj == playPause) {
150-
currentState = (currentState == States::Stopped ? States::Running : States::Stopped);
151-
switch (currentState) {
152-
case States::Stopped: {
153-
lv_label_set_text(playPauseLabel, Symbols::play);
154-
systemTask.PushMessage(System::Messages::EnableSleeping);
155-
break;
156-
}
157-
case States::Running: {
158-
lv_label_set_text(playPauseLabel, Symbols::pause);
159-
systemTask.PushMessage(System::Messages::DisableSleeping);
160-
startTime = xTaskGetTickCount();
161-
counter = 1;
162-
break;
163-
}
122+
metronomeStarted = !metronomeStarted;
123+
if (metronomeStarted) {
124+
lv_obj_set_style_local_value_str(playPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Symbols::pause);
125+
systemTask.PushMessage(System::Messages::DisableSleeping);
126+
startTime = xTaskGetTickCount();
127+
counter = 1;
128+
} else {
129+
lv_obj_set_style_local_value_str(playPause, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, Symbols::play);
130+
systemTask.PushMessage(System::Messages::EnableSleeping);
164131
}
165132
}
166133
break;
167134
}
135+
default:
136+
break;
168137
}
169138
}

src/displayapp/screens/Metronome.h

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,32 @@
33
#include "systemtask/SystemTask.h"
44
#include "components/motor/MotorController.h"
55

6-
#include <array>
6+
namespace Pinetime {
7+
namespace Applications {
8+
namespace Screens {
79

8-
namespace Pinetime::Applications::Screens {
10+
class Metronome : public Screen {
11+
public:
12+
Metronome(DisplayApp* app, Controllers::MotorController& motorController, System::SystemTask& systemTask);
13+
~Metronome() override;
14+
bool Refresh() override;
15+
void OnEvent(lv_obj_t* obj, lv_event_t event);
916

10-
class Metronome : public Screen {
11-
public:
12-
Metronome(DisplayApp* app, Controllers::MotorController& motorController, System::SystemTask& systemTask);
13-
~Metronome() override;
14-
bool Refresh() override;
15-
bool OnTouchEvent(TouchEvents event) override;
16-
void OnEvent(lv_obj_t* obj, lv_event_t event);
17-
enum class States { Running, Stopped };
17+
private:
18+
TickType_t startTime = 0;
19+
TickType_t tappedTime = 0;
20+
Controllers::MotorController& motorController;
21+
System::SystemTask& systemTask;
22+
int16_t bpm = 120;
23+
uint8_t bpb = 4;
24+
uint8_t counter = 1;
1825

19-
private:
20-
bool running;
21-
States currentState;
22-
TickType_t startTime;
23-
TickType_t tappedTime = 0;
24-
Controllers::MotorController& motorController;
25-
System::SystemTask& systemTask;
26-
uint16_t bpm = 120;
27-
uint8_t bpb = 4;
28-
uint8_t counter = 1;
26+
bool metronomeStarted = false;
2927

30-
lv_obj_t *bpmArc, *bpmTap, *bpmValue, *bpmLegend;
31-
lv_obj_t *bpbDropdown, *bpbLegend;
32-
lv_obj_t *playPause, *playPauseLabel;
33-
};
28+
lv_obj_t *bpmArc, *bpmTap, *bpmValue;
29+
lv_obj_t *bpbDropdown, *currentBpbText;
30+
lv_obj_t *playPause;
31+
};
32+
}
33+
}
3434
}

0 commit comments

Comments
 (0)