summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/system_fsm/booting.cpp26
-rw-r--r--src/ui/CMakeLists.txt2
-rw-r--r--src/ui/encoder_input.cpp46
-rw-r--r--src/ui/include/encoder_input.hpp47
-rw-r--r--src/ui/include/lvgl_task.hpp9
-rw-r--r--src/ui/include/ui_fsm.hpp4
-rw-r--r--src/ui/include/wheel_encoder.hpp33
-rw-r--r--src/ui/lvgl_task.cpp18
-rw-r--r--src/ui/ui_fsm.cpp13
-rw-r--r--src/ui/wheel_encoder.cpp44
10 files changed, 124 insertions, 118 deletions
diff --git a/src/system_fsm/booting.cpp b/src/system_fsm/booting.cpp
index 7914a5c3..08a1c083 100644
--- a/src/system_fsm/booting.cpp
+++ b/src/system_fsm/booting.cpp
@@ -4,39 +4,37 @@
* SPDX-License-Identifier: GPL-3.0-only
*/
+#include "system_fsm.hpp"
+
#include <stdint.h>
-#include "adc.hpp"
#include "assert.h"
-#include "audio_fsm.hpp"
-#include "battery.hpp"
-#include "bluetooth.hpp"
-#include "bluetooth_types.hpp"
-#include "core/lv_obj.h"
-#include "display_init.hpp"
#include "esp_err.h"
#include "esp_log.h"
-#include "event_queue.hpp"
#include "freertos/FreeRTOS.h"
#include "freertos/portmacro.h"
#include "freertos/projdefs.h"
#include "freertos/timers.h"
+
+#include "adc.hpp"
+#include "audio_fsm.hpp"
+#include "battery.hpp"
+#include "bluetooth.hpp"
+#include "bluetooth_types.hpp"
+#include "display_init.hpp"
+#include "event_queue.hpp"
#include "gpios.hpp"
-#include "lvgl/lvgl.h"
+#include "i2c.hpp"
#include "nvs.hpp"
-#include "relative_wheel.hpp"
#include "samd.hpp"
#include "service_locator.hpp"
#include "spi.hpp"
#include "system_events.hpp"
-#include "system_fsm.hpp"
#include "tag_parser.hpp"
+#include "touchwheel.hpp"
#include "track_queue.hpp"
#include "ui_fsm.hpp"
-#include "i2c.hpp"
-#include "touchwheel.hpp"
-
namespace system_fsm {
namespace states {
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt
index e331d96f..5f2d64d7 100644
--- a/src/ui/CMakeLists.txt
+++ b/src/ui/CMakeLists.txt
@@ -4,7 +4,7 @@
idf_component_register(
SRCS "lvgl_task.cpp" "ui_fsm.cpp" "screen_splash.cpp" "screen_menu.cpp"
- "wheel_encoder.cpp" "screen_track_browser.cpp" "screen_playing.cpp"
+ "encoder_input.cpp" "screen_track_browser.cpp" "screen_playing.cpp"
"themes.cpp" "widget_top_bar.cpp" "screen.cpp" "screen_onboarding.cpp"
"modal_progress.cpp" "modal.cpp" "modal_confirm.cpp" "screen_settings.cpp"
"event_binding.cpp"
diff --git a/src/ui/encoder_input.cpp b/src/ui/encoder_input.cpp
new file mode 100644
index 00000000..62cb4c8b
--- /dev/null
+++ b/src/ui/encoder_input.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2023 jacqueline <me@jacqueline.id.au>
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#include "encoder_input.hpp"
+
+#include <sys/_stdint.h>
+#include <memory>
+
+#include "core/lv_group.h"
+#include "gpios.hpp"
+#include "hal/lv_hal_indev.h"
+#include "relative_wheel.hpp"
+#include "touchwheel.hpp"
+
+namespace ui {
+
+static void encoder_read(lv_indev_drv_t* drv, lv_indev_data_t* data) {
+ EncoderInput* instance = reinterpret_cast<EncoderInput*>(drv->user_data);
+ instance->Read(data);
+}
+
+EncoderInput::EncoderInput(drivers::IGpios& gpios, drivers::TouchWheel& wheel)
+ : gpios_(gpios),
+ raw_wheel_(wheel),
+ relative_wheel_(std::make_unique<drivers::RelativeWheel>(wheel)) {
+ lv_indev_drv_init(&driver_);
+ driver_.type = LV_INDEV_TYPE_ENCODER;
+ driver_.read_cb = encoder_read;
+ driver_.user_data = this;
+
+ registration_ = lv_indev_drv_register(&driver_);
+}
+
+auto EncoderInput::Read(lv_indev_data_t* data) -> void {
+ raw_wheel_.Update();
+ relative_wheel_->Update();
+
+ data->enc_diff = relative_wheel_->ticks();
+ data->state = relative_wheel_->is_clicking() ? LV_INDEV_STATE_PRESSED
+ : LV_INDEV_STATE_RELEASED;
+}
+
+} // namespace ui
diff --git a/src/ui/include/encoder_input.hpp b/src/ui/include/encoder_input.hpp
new file mode 100644
index 00000000..9c114e80
--- /dev/null
+++ b/src/ui/include/encoder_input.hpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2023 jacqueline <me@jacqueline.id.au>
+ *
+ * SPDX-License-Identifier: GPL-3.0-only
+ */
+
+#pragma once
+
+#include <memory>
+
+#include "core/lv_group.h"
+#include "gpios.hpp"
+#include "hal/lv_hal_indev.h"
+
+#include "relative_wheel.hpp"
+#include "touchwheel.hpp"
+
+namespace ui {
+
+/*
+ * Main input device abstracting that handles turning lower-level input device
+ * drivers into events and LVGL inputs.
+ *
+ * As far as LVGL is concerned, this class represents an ordinary rotary
+ * encoder, supporting only left and right ticks, and clicking.
+ */
+class EncoderInput {
+ public:
+ EncoderInput(drivers::IGpios& gpios, drivers::TouchWheel& wheel);
+
+ auto Read(lv_indev_data_t* data) -> void;
+ auto registration() -> lv_indev_t* { return registration_; }
+
+ auto lock(bool l) -> void { is_locked_ = l; }
+
+ private:
+ lv_indev_drv_t driver_;
+ lv_indev_t* registration_;
+
+ drivers::IGpios& gpios_;
+ drivers::TouchWheel& raw_wheel_;
+ std::unique_ptr<drivers::RelativeWheel> relative_wheel_;
+
+ bool is_locked_;
+};
+
+} // namespace ui
diff --git a/src/ui/include/lvgl_task.hpp b/src/ui/include/lvgl_task.hpp
index 4362249b..f212ab9d 100644
--- a/src/ui/include/lvgl_task.hpp
+++ b/src/ui/include/lvgl_task.hpp
@@ -15,30 +15,27 @@
#include "freertos/timers.h"
#include "display.hpp"
+#include "encoder_input.hpp"
#include "relative_wheel.hpp"
#include "screen.hpp"
#include "themes.hpp"
#include "touchwheel.hpp"
-#include "wheel_encoder.hpp"
namespace ui {
class UiTask {
public:
static auto Start() -> UiTask*;
-
~UiTask();
- // FIXME: Once we have more input devices, this function should accept a more
- // generic interface.
- auto SetInputDevice(std::shared_ptr<TouchWheelEncoder> dev) -> void;
+ auto input(std::shared_ptr<EncoderInput> input) -> void;
private:
UiTask();
auto Main() -> void;
- std::shared_ptr<TouchWheelEncoder> input_device_;
+ std::shared_ptr<EncoderInput> input_;
std::shared_ptr<Screen> current_screen_;
};
diff --git a/src/ui/include/ui_fsm.hpp b/src/ui/include/ui_fsm.hpp
index 24f0c270..4db8257d 100644
--- a/src/ui/include/ui_fsm.hpp
+++ b/src/ui/include/ui_fsm.hpp
@@ -26,6 +26,7 @@
#include "tinyfsm.hpp"
#include "display.hpp"
+#include "encoder_input.hpp"
#include "modal.hpp"
#include "screen.hpp"
#include "storage.hpp"
@@ -34,7 +35,6 @@
#include "track.hpp"
#include "track_queue.hpp"
#include "ui_events.hpp"
-#include "wheel_encoder.hpp"
namespace ui {
@@ -87,7 +87,7 @@ class UiState : public tinyfsm::Fsm<UiState> {
static std::unique_ptr<UiTask> sTask;
static std::shared_ptr<system_fsm::ServiceLocator> sServices;
static std::unique_ptr<drivers::Display> sDisplay;
- static std::shared_ptr<TouchWheelEncoder> sEncoder;
+ static std::shared_ptr<EncoderInput> sInput;
static std::stack<std::shared_ptr<Screen>> sScreens;
static std::shared_ptr<Screen> sCurrentScreen;
diff --git a/src/ui/include/wheel_encoder.hpp b/src/ui/include/wheel_encoder.hpp
deleted file mode 100644
index fcac5edd..00000000
--- a/src/ui/include/wheel_encoder.hpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2023 jacqueline <me@jacqueline.id.au>
- *
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-#pragma once
-
-#include <memory>
-
-#include "core/lv_group.h"
-#include "hal/lv_hal_indev.h"
-
-#include "relative_wheel.hpp"
-
-namespace ui {
-
-class TouchWheelEncoder {
- public:
- explicit TouchWheelEncoder(std::unique_ptr<drivers::RelativeWheel> wheel);
-
- auto Read(lv_indev_data_t* data) -> void;
- auto registration() -> lv_indev_t* { return registration_; }
-
- private:
- lv_indev_drv_t driver_;
- lv_indev_t* registration_;
-
- lv_key_t last_key_;
- std::unique_ptr<drivers::RelativeWheel> wheel_;
-};
-
-} // namespace ui
diff --git a/src/ui/lvgl_task.cpp b/src/ui/lvgl_task.cpp
index 74f68cf5..ff85a055 100644
--- a/src/ui/lvgl_task.cpp
+++ b/src/ui/lvgl_task.cpp
@@ -40,7 +40,6 @@
#include "tasks.hpp"
#include "touchwheel.hpp"
#include "ui_fsm.hpp"
-#include "wheel_encoder.hpp"
#include "widgets/lv_label.h"
#include "display.hpp"
@@ -67,15 +66,15 @@ auto UiTask::Main() -> void {
std::shared_ptr<Screen> screen = UiState::current_screen();
if (screen != current_screen_ && screen != nullptr) {
lv_scr_load(screen->root());
- if (input_device_) {
- lv_indev_set_group(input_device_->registration(), screen->group());
+ if (input_) {
+ lv_indev_set_group(input_->registration(), screen->group());
}
current_screen_ = screen;
}
- if (input_device_ && current_screen_->group() != current_group) {
+ if (input_ && current_screen_->group() != current_group) {
current_group = current_screen_->group();
- lv_indev_set_group(input_device_->registration(), current_group);
+ lv_indev_set_group(input_->registration(), current_group);
}
if (current_screen_) {
@@ -87,11 +86,10 @@ auto UiTask::Main() -> void {
}
}
-auto UiTask::SetInputDevice(std::shared_ptr<TouchWheelEncoder> dev) -> void {
- input_device_ = std::move(dev);
- if (current_screen_ && input_device_) {
- lv_indev_set_group(input_device_->registration(), current_screen_->group());
- }
+auto UiTask::input(std::shared_ptr<EncoderInput> input) -> void {
+ assert(current_screen_);
+ input_ = input;
+ lv_indev_set_group(input_->registration(), current_screen_->group());
}
auto UiTask::Start() -> UiTask* {
diff --git a/src/ui/ui_fsm.cpp b/src/ui/ui_fsm.cpp
index f66e3e8a..bc976eab 100644
--- a/src/ui/ui_fsm.cpp
+++ b/src/ui/ui_fsm.cpp
@@ -15,6 +15,7 @@
#include "audio_events.hpp"
#include "display.hpp"
+#include "encoder_input.hpp"
#include "event_queue.hpp"
#include "gpios.hpp"
#include "lvgl_task.hpp"
@@ -35,7 +36,6 @@
#include "touchwheel.hpp"
#include "track_queue.hpp"
#include "ui_events.hpp"
-#include "wheel_encoder.hpp"
#include "widget_top_bar.hpp"
namespace ui {
@@ -47,7 +47,7 @@ static const std::size_t kRecordsPerPage = 15;
std::unique_ptr<UiTask> UiState::sTask;
std::shared_ptr<system_fsm::ServiceLocator> UiState::sServices;
std::unique_ptr<drivers::Display> UiState::sDisplay;
-std::shared_ptr<TouchWheelEncoder> UiState::sEncoder;
+std::shared_ptr<EncoderInput> UiState::sInput;
std::stack<std::shared_ptr<Screen>> UiState::sScreens;
std::shared_ptr<Screen> UiState::sCurrentScreen;
@@ -88,8 +88,7 @@ void UiState::PopScreen() {
void UiState::react(const system_fsm::KeyLockChanged& ev) {
sDisplay->SetDisplayOn(ev.falling);
- sTask->SetInputDevice(ev.falling ? sEncoder
- : std::shared_ptr<TouchWheelEncoder>());
+ sInput->lock(!ev.falling);
}
void UiState::react(const system_fsm::BatteryStateChanged& ev) {
@@ -138,10 +137,8 @@ void Splash::react(const system_fsm::BootComplete& ev) {
auto touchwheel = sServices->touchwheel();
if (touchwheel) {
- auto relative_wheel =
- std::make_unique<drivers::RelativeWheel>(**touchwheel);
- sEncoder = std::make_shared<TouchWheelEncoder>(std::move(relative_wheel));
- sTask->SetInputDevice(sEncoder);
+ sInput = std::make_shared<EncoderInput>(sServices->gpios(), **touchwheel);
+ sTask->input(sInput);
} else {
ESP_LOGE(kTag, "no input devices initialised!");
}
diff --git a/src/ui/wheel_encoder.cpp b/src/ui/wheel_encoder.cpp
deleted file mode 100644
index 2f2e7f68..00000000
--- a/src/ui/wheel_encoder.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2023 jacqueline <me@jacqueline.id.au>
- *
- * SPDX-License-Identifier: GPL-3.0-only
- */
-
-#include "wheel_encoder.hpp"
-#include <sys/_stdint.h>
-#include "core/lv_group.h"
-#include "hal/lv_hal_indev.h"
-
-namespace ui {
-
-void encoder_read(lv_indev_drv_t* drv, lv_indev_data_t* data) {
- TouchWheelEncoder* instance =
- reinterpret_cast<TouchWheelEncoder*>(drv->user_data);
- instance->Read(data);
-}
-
-void encoder_feedback(lv_indev_drv_t* drv, uint8_t event_code) {
- ESP_LOGI("Touchwheel Event", "Event code: %d", event_code);
-}
-
-TouchWheelEncoder::TouchWheelEncoder(
- std::unique_ptr<drivers::RelativeWheel> wheel)
- : last_key_(0), wheel_(std::move(wheel)) {
- lv_indev_drv_init(&driver_);
- driver_.type = LV_INDEV_TYPE_ENCODER;
- driver_.read_cb = encoder_read;
- // driver_.feedback_cb = encoder_feedback;
- driver_.user_data = this;
-
- registration_ = lv_indev_drv_register(&driver_);
-}
-
-auto TouchWheelEncoder::Read(lv_indev_data_t* data) -> void {
- wheel_->Update();
-
- data->enc_diff = wheel_->ticks();
- data->state =
- wheel_->is_clicking() ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
-}
-
-} // namespace ui