From ed82063af5f83530afa5cfb5bf5bd516f3d05f2a Mon Sep 17 00:00:00 2001 From: jacqueline Date: Wed, 10 Apr 2024 16:56:10 +1000 Subject: WIP decompose our giant LVGL driver into smaller classes --- src/input/lvgl_input_driver.cpp | 84 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 src/input/lvgl_input_driver.cpp (limited to 'src/input/lvgl_input_driver.cpp') diff --git a/src/input/lvgl_input_driver.cpp b/src/input/lvgl_input_driver.cpp new file mode 100644 index 00000000..70b6eb5d --- /dev/null +++ b/src/input/lvgl_input_driver.cpp @@ -0,0 +1,84 @@ +/* + * Copyright 2023 jacqueline + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#include "lvgl_input_driver.hpp" +#include + +#include +#include + +#include "feedback_haptics.hpp" +#include "input_touch_wheel.hpp" +#include "input_volume_buttons.hpp" +#include "lvgl.h" +#include "service_locator.hpp" + +[[maybe_unused]] static constexpr char kTag[] = "input"; + +namespace input { + +static void read_cb(lv_indev_drv_t* drv, lv_indev_data_t* data) { + LvglInputDriver* instance = + reinterpret_cast(drv->user_data); + instance->read(data); +} + +static void feedback_cb(lv_indev_drv_t* drv, uint8_t event) { + LvglInputDriver* instance = + reinterpret_cast(drv->user_data); + instance->feedback(event); +} + +LvglInputDriver::LvglInputDriver( + std::shared_ptr services) + : services_(services), + driver_(), + registration_(nullptr), + inputs_(), + feedbacks_(), + is_locked_(false) { + lv_indev_drv_init(&driver_); + driver_.type = LV_INDEV_TYPE_ENCODER; + driver_.read_cb = read_cb; + driver_.feedback_cb = feedback_cb; + driver_.user_data = this; + + registration_ = lv_indev_drv_register(&driver_); + + // TODO: Make these devices configurable. I'm thinking each device gets an id + // and then we have: + // - a factory to create instance given an id + // - add/remove device methods on LvglInputDriver that operate on ids + // - the user's enabled devices (+ their configuration) stored in NVS. + auto touchwheel = services_->touchwheel(); + if (touchwheel) { + inputs_.push_back(std::make_unique(**touchwheel)); + } + inputs_.push_back(std::make_unique(services_->gpios())); + feedbacks_.push_back(std::make_unique(services_->haptics())); +} + +auto LvglInputDriver::read(lv_indev_data_t* data) -> void { + // TODO: we should pass lock state on to the individual devices, since they + // may wish to either ignore the lock state, or power down until unlock. + if (is_locked_) { + return; + } + for (auto&& device : inputs_) { + device->read(data); + } +} + +auto LvglInputDriver::feedback(uint8_t event) -> void { + if (is_locked_) { + return; + } + for (auto&& device : feedbacks_) { + device->feedback(event); + } +} + +} // namespace input -- cgit v1.2.3 From 33919e9e3f419e13318fa6b8217d8c8dcd86c1eb Mon Sep 17 00:00:00 2001 From: jacqueline Date: Thu, 11 Apr 2024 15:16:35 +1000 Subject: Migrate all existing control schemes to the cool new world --- src/input/lvgl_input_driver.cpp | 59 ++++++++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 18 deletions(-) (limited to 'src/input/lvgl_input_driver.cpp') diff --git a/src/input/lvgl_input_driver.cpp b/src/input/lvgl_input_driver.cpp index 70b6eb5d..9698aa79 100644 --- a/src/input/lvgl_input_driver.cpp +++ b/src/input/lvgl_input_driver.cpp @@ -9,12 +9,16 @@ #include #include +#include +#include "device_factory.hpp" #include "feedback_haptics.hpp" #include "input_touch_wheel.hpp" +#include "input_trigger.hpp" #include "input_volume_buttons.hpp" #include "lvgl.h" -#include "service_locator.hpp" +#include "nvs.hpp" +#include "property.hpp" [[maybe_unused]] static constexpr char kTag[] = "input"; @@ -32,33 +36,52 @@ static void feedback_cb(lv_indev_drv_t* drv, uint8_t event) { instance->feedback(event); } -LvglInputDriver::LvglInputDriver( - std::shared_ptr services) - : services_(services), +auto intToMode(int raw) -> std::optional { + switch (raw) { + case 0: + return drivers::NvsStorage::InputModes::kButtonsOnly; + case 1: + return drivers::NvsStorage::InputModes::kButtonsWithWheel; + case 2: + return drivers::NvsStorage::InputModes::kDirectionalWheel; + case 3: + return drivers::NvsStorage::InputModes::kRotatingWheel; + default: + return {}; + } +} + +LvglInputDriver::LvglInputDriver(drivers::NvsStorage& nvs, + DeviceFactory& factory) + : nvs_(nvs), + factory_(factory), + mode_(static_cast(nvs.PrimaryInput()), + [&](const lua::LuaValue& val) { + if (!std::holds_alternative(val)) { + return false; + } + auto mode = intToMode(std::get(val)); + if (!mode) { + return false; + } + nvs.PrimaryInput(*mode); + inputs_ = factory.createInputs(*mode); + return true; + }), driver_(), registration_(nullptr), - inputs_(), - feedbacks_(), + inputs_(factory.createInputs(nvs.PrimaryInput())), + feedbacks_(factory.createFeedbacks()), is_locked_(false) { lv_indev_drv_init(&driver_); driver_.type = LV_INDEV_TYPE_ENCODER; driver_.read_cb = read_cb; driver_.feedback_cb = feedback_cb; driver_.user_data = this; + driver_.long_press_time = kLongPressDelayMs; + driver_.long_press_repeat_time = kRepeatDelayMs; registration_ = lv_indev_drv_register(&driver_); - - // TODO: Make these devices configurable. I'm thinking each device gets an id - // and then we have: - // - a factory to create instance given an id - // - add/remove device methods on LvglInputDriver that operate on ids - // - the user's enabled devices (+ their configuration) stored in NVS. - auto touchwheel = services_->touchwheel(); - if (touchwheel) { - inputs_.push_back(std::make_unique(**touchwheel)); - } - inputs_.push_back(std::make_unique(services_->gpios())); - feedbacks_.push_back(std::make_unique(services_->haptics())); } auto LvglInputDriver::read(lv_indev_data_t* data) -> void { -- cgit v1.2.3