diff options
| author | jacqueline <me@jacqueline.id.au> | 2023-06-01 15:28:32 +1000 |
|---|---|---|
| committer | jacqueline <me@jacqueline.id.au> | 2023-06-01 15:28:54 +1000 |
| commit | 6fd588e970470b15936187980829916d0dbe77bb (patch) | |
| tree | 1b1e73ef52bef2e41499ee5ceadc45efd408050b /src/ui | |
| parent | db2e29a72d9b934e7b58f1d20ac3768eae484ab5 (diff) | |
| download | tangara-fw-6fd588e970470b15936187980829916d0dbe77bb.tar.gz | |
Add touchwheel -> encoder adapter
Diffstat (limited to 'src/ui')
| -rw-r--r-- | src/ui/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/ui/include/lvgl_task.hpp | 3 | ||||
| -rw-r--r-- | src/ui/include/screen.hpp | 28 | ||||
| -rw-r--r-- | src/ui/include/screen_menu.hpp | 29 | ||||
| -rw-r--r-- | src/ui/include/screen_splash.hpp | 30 | ||||
| -rw-r--r-- | src/ui/include/ui_fsm.hpp | 10 | ||||
| -rw-r--r-- | src/ui/include/ui_tick.hpp | 11 | ||||
| -rw-r--r-- | src/ui/include/wheel_encoder.hpp | 30 | ||||
| -rw-r--r-- | src/ui/lvgl_task.cpp | 16 | ||||
| -rw-r--r-- | src/ui/screen_menu.cpp | 52 | ||||
| -rw-r--r-- | src/ui/screen_splash.cpp | 38 | ||||
| -rw-r--r-- | src/ui/ui_fsm.cpp | 12 | ||||
| -rw-r--r-- | src/ui/wheel_encoder.cpp | 39 |
13 files changed, 283 insertions, 17 deletions
diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 9a41ae0d..bd0b76f0 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -3,7 +3,7 @@ # SPDX-License-Identifier: GPL-3.0-only idf_component_register( - SRCS "lvgl_task.cpp" "ui_fsm.cpp" "screen_splash.cpp" "screen_menu.cpp" + SRCS "lvgl_task.cpp" "ui_fsm.cpp" "screen_splash.cpp" "screen_menu.cpp" "wheel_encoder.cpp" INCLUDE_DIRS "include" REQUIRES "drivers" "lvgl" "tinyfsm" "events" "system_fsm" "database" "esp_timer") target_compile_options(${COMPONENT_LIB} PRIVATE ${EXTRA_WARNINGS}) diff --git a/src/ui/include/lvgl_task.hpp b/src/ui/include/lvgl_task.hpp index 25e7dd14..8e387683 100644 --- a/src/ui/include/lvgl_task.hpp +++ b/src/ui/include/lvgl_task.hpp @@ -14,11 +14,12 @@ #include "freertos/task.h" #include "display.hpp" +#include "relative_wheel.hpp" #include "touchwheel.hpp" namespace ui { -auto StartLvgl(std::weak_ptr<drivers::TouchWheel> touch_wheel, +auto StartLvgl(std::weak_ptr<drivers::RelativeWheel> touch_wheel, std::weak_ptr<drivers::Display> display) -> void; } // namespace ui diff --git a/src/ui/include/screen.hpp b/src/ui/include/screen.hpp new file mode 100644 index 00000000..87a0d9b8 --- /dev/null +++ b/src/ui/include/screen.hpp @@ -0,0 +1,28 @@ +/* + * Copyright 2023 jacqueline <me@jacqueline.id.au> + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#pragma once + +#include <memory> + +#include "core/lv_obj.h" +#include "core/lv_obj_tree.h" +#include "lvgl.h" + +namespace ui { + +class Screen { + public: + Screen() : root_(lv_obj_create(NULL)) {} + virtual ~Screen() { lv_obj_del(root_); } + + auto root() -> lv_obj_t* { return root_; } + + protected: + lv_obj_t* const root_; +}; + +} // namespace ui diff --git a/src/ui/include/screen_menu.hpp b/src/ui/include/screen_menu.hpp new file mode 100644 index 00000000..a0b07b9e --- /dev/null +++ b/src/ui/include/screen_menu.hpp @@ -0,0 +1,29 @@ +/* + * Copyright 2023 jacqueline <me@jacqueline.id.au> + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#pragma once + +#include <memory> + +#include "lvgl.h" + +#include "screen.hpp" + +namespace ui { +namespace screens { + +class Menu : public Screen { + public: + Menu(); + ~Menu(); + + private: + lv_obj_t* container_; + lv_obj_t* label_; +}; + +} // namespace screens +} // namespace ui diff --git a/src/ui/include/screen_splash.hpp b/src/ui/include/screen_splash.hpp new file mode 100644 index 00000000..1ee7dd89 --- /dev/null +++ b/src/ui/include/screen_splash.hpp @@ -0,0 +1,30 @@ +/* + * Copyright 2023 jacqueline <me@jacqueline.id.au> + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#pragma once + +#include <memory> + +#include "lvgl.h" + +#include "screen.hpp" + +namespace ui { +namespace screens { + +class Splash : public Screen { + public: + Splash(); + ~Splash(); + + private: + lv_obj_t* container_; + lv_obj_t* label_; + lv_obj_t* spinner_; +}; + +} // namespace screens +} // namespace ui diff --git a/src/ui/include/ui_fsm.hpp b/src/ui/include/ui_fsm.hpp index 2afcfa86..d4d23bb0 100644 --- a/src/ui/include/ui_fsm.hpp +++ b/src/ui/include/ui_fsm.hpp @@ -8,9 +8,9 @@ #include <memory> +#include "relative_wheel.hpp" #include "tinyfsm.hpp" -#include "database.hpp" #include "display.hpp" #include "screen.hpp" #include "storage.hpp" @@ -22,9 +22,8 @@ namespace ui { class UiState : public tinyfsm::Fsm<UiState> { public: static auto Init(drivers::GpioExpander* gpio_expander, - std::weak_ptr<drivers::TouchWheel> touchwheel, - std::weak_ptr<drivers::Display> display, - std::weak_ptr<database::Database> database) -> void; + std::weak_ptr<drivers::RelativeWheel> touchwheel, + std::weak_ptr<drivers::Display> display) -> void; virtual ~UiState() {} @@ -43,9 +42,8 @@ class UiState : public tinyfsm::Fsm<UiState> { protected: static drivers::GpioExpander* sGpioExpander; - static std::weak_ptr<drivers::TouchWheel> sTouchWheel; + static std::weak_ptr<drivers::RelativeWheel> sTouchWheel; static std::weak_ptr<drivers::Display> sDisplay; - static std::weak_ptr<database::Database> sDatabase; static std::shared_ptr<Screen> sCurrentScreen; }; diff --git a/src/ui/include/ui_tick.hpp b/src/ui/include/ui_tick.hpp new file mode 100644 index 00000000..37f8a8bd --- /dev/null +++ b/src/ui/include/ui_tick.hpp @@ -0,0 +1,11 @@ +/* + * Copyright 2023 jacqueline <me@jacqueline.id.au> + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#pragma once + +#include "esp_timer.h" + +#define LV_TICK_CUSTOM_SYS_TIME_EXPR (esp_timer_get_time() / 1000) diff --git a/src/ui/include/wheel_encoder.hpp b/src/ui/include/wheel_encoder.hpp new file mode 100644 index 00000000..0651ce0b --- /dev/null +++ b/src/ui/include/wheel_encoder.hpp @@ -0,0 +1,30 @@ +/* + * Copyright 2023 jacqueline <me@jacqueline.id.au> + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#pragma once + +#include <memory> + +#include "hal/lv_hal_indev.h" + +#include "relative_wheel.hpp" + +namespace ui { + +class TouchWheelEncoder { + public: + explicit TouchWheelEncoder(std::weak_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_; + std::weak_ptr<drivers::RelativeWheel> wheel_; +}; + +} // namespace ui diff --git a/src/ui/lvgl_task.cpp b/src/ui/lvgl_task.cpp index f2f7c67c..1ce7fd40 100644 --- a/src/ui/lvgl_task.cpp +++ b/src/ui/lvgl_task.cpp @@ -15,6 +15,8 @@ #include <memory> #include "core/lv_disp.h" +#include "core/lv_group.h" +#include "core/lv_indev.h" #include "core/lv_obj.h" #include "core/lv_obj_pos.h" #include "core/lv_obj_tree.h" @@ -25,15 +27,18 @@ #include "freertos/projdefs.h" #include "freertos/timers.h" #include "hal/gpio_types.h" +#include "hal/lv_hal_indev.h" #include "hal/spi_types.h" #include "lv_api_map.h" #include "lvgl/lvgl.h" #include "misc/lv_color.h" #include "misc/lv_style.h" #include "misc/lv_timer.h" +#include "relative_wheel.hpp" #include "tasks.hpp" #include "touchwheel.hpp" #include "ui_fsm.hpp" +#include "wheel_encoder.hpp" #include "widgets/lv_label.h" #include "display.hpp" @@ -43,11 +48,16 @@ namespace ui { static const char* kTag = "lv_task"; -void LvglMain(std::weak_ptr<drivers::TouchWheel> weak_touch_wheel, +void LvglMain(std::weak_ptr<drivers::RelativeWheel> weak_touch_wheel, std::weak_ptr<drivers::Display> weak_display) { ESP_LOGI(kTag, "init lvgl"); lv_init(); + TouchWheelEncoder encoder(weak_touch_wheel); + lv_group_t *nav_group = lv_group_create(); + lv_group_set_default(nav_group); + lv_indev_set_group(encoder.registration(), nav_group); + std::shared_ptr<Screen> current_screen; auto& events = events::EventQueue::GetInstance(); while (1) { @@ -65,10 +75,12 @@ void LvglMain(std::weak_ptr<drivers::TouchWheel> weak_touch_wheel, // 30 FPS // TODO(jacqueline): make this dynamic vTaskDelay(pdMS_TO_TICKS(33)); + lv_indev_data_t d; + encoder.Read(&d); } } -auto StartLvgl(std::weak_ptr<drivers::TouchWheel> touch_wheel, +auto StartLvgl(std::weak_ptr<drivers::RelativeWheel> touch_wheel, std::weak_ptr<drivers::Display> display) -> void { tasks::StartPersistent<tasks::Type::kUi>( [=]() { LvglMain(touch_wheel, display); }); diff --git a/src/ui/screen_menu.cpp b/src/ui/screen_menu.cpp new file mode 100644 index 00000000..da0a7d3c --- /dev/null +++ b/src/ui/screen_menu.cpp @@ -0,0 +1,52 @@ +/* + * Copyright 2023 jacqueline <me@jacqueline.id.au> + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#include "screen_menu.hpp" + +#include "core/lv_group.h" +#include "core/lv_obj_pos.h" +#include "extra/widgets/menu/lv_menu.h" +#include "extra/widgets/spinner/lv_spinner.h" +#include "hal/lv_hal_disp.h" +#include "misc/lv_area.h" +#include "widgets/lv_label.h" + +namespace ui { +namespace screens { + +Menu::Menu() { + lv_obj_t *menu = lv_menu_create(root_); + lv_obj_set_size(menu, lv_disp_get_hor_res(NULL), lv_disp_get_ver_res(NULL)); + lv_obj_center(menu); + + lv_obj_t *main_page = lv_menu_page_create(menu, NULL); + + lv_obj_t *container; + lv_obj_t *label; + + container = lv_menu_cont_create(main_page); + label = lv_label_create(container); + lv_label_set_text(label, "I am an item"); + + container = lv_menu_cont_create(main_page); + label = lv_label_create(container); + lv_label_set_text(label, "I am also an item"); + + container = lv_menu_cont_create(main_page); + label = lv_label_create(container); + lv_label_set_text(label, "Item #3"); + + container = lv_menu_cont_create(main_page); + label = lv_label_create(container); + lv_label_set_text(label, "Yay!"); + + lv_menu_set_page(menu, main_page); +} + +Menu::~Menu() {} + +} // namespace screens +} // namespace ui diff --git a/src/ui/screen_splash.cpp b/src/ui/screen_splash.cpp new file mode 100644 index 00000000..2b2a7b1e --- /dev/null +++ b/src/ui/screen_splash.cpp @@ -0,0 +1,38 @@ +/* + * Copyright 2023 jacqueline <me@jacqueline.id.au> + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#include "screen_splash.hpp" + +#include "core/lv_obj_pos.h" +#include "extra/widgets/spinner/lv_spinner.h" +#include "misc/lv_area.h" +#include "widgets/lv_label.h" + +namespace ui { +namespace screens { + +Splash::Splash() { + container_ = lv_obj_create(root_); + lv_obj_set_align(container_, LV_ALIGN_CENTER); + lv_obj_set_size(container_, LV_SIZE_CONTENT, LV_SIZE_CONTENT); + + label_ = lv_label_create(container_); + lv_label_set_text_static(label_, "TANGARA"); + lv_obj_set_align(label_, LV_ALIGN_TOP_MID); + + spinner_ = lv_spinner_create(container_, 1000, 60); + lv_obj_set_size(spinner_, 32, 32); + lv_obj_align_to(spinner_, label_, LV_ALIGN_OUT_BOTTOM_MID, 0, 8); +} + +Splash::~Splash() { + lv_obj_del(spinner_); + lv_obj_del(label_); + lv_obj_del(container_); +} + +} // namespace screens +} // namespace ui diff --git a/src/ui/ui_fsm.cpp b/src/ui/ui_fsm.cpp index b08722aa..f12104e6 100644 --- a/src/ui/ui_fsm.cpp +++ b/src/ui/ui_fsm.cpp @@ -7,6 +7,7 @@ #include "ui_fsm.hpp" #include "display.hpp" #include "lvgl_task.hpp" +#include "relative_wheel.hpp" #include "screen.hpp" #include "screen_menu.hpp" #include "screen_splash.hpp" @@ -16,20 +17,17 @@ namespace ui { drivers::GpioExpander* UiState::sGpioExpander; -std::weak_ptr<drivers::TouchWheel> UiState::sTouchWheel; +std::weak_ptr<drivers::RelativeWheel> UiState::sTouchWheel; std::weak_ptr<drivers::Display> UiState::sDisplay; -std::weak_ptr<database::Database> UiState::sDatabase; std::shared_ptr<Screen> UiState::sCurrentScreen; auto UiState::Init(drivers::GpioExpander* gpio_expander, - std::weak_ptr<drivers::TouchWheel> touchwheel, - std::weak_ptr<drivers::Display> display, - std::weak_ptr<database::Database> database) -> void { + std::weak_ptr<drivers::RelativeWheel> touchwheel, + std::weak_ptr<drivers::Display> display) -> void { sGpioExpander = gpio_expander; sTouchWheel = touchwheel; sDisplay = display; - sDatabase = database; } namespace states { @@ -47,7 +45,7 @@ void Splash::react(const system_fsm::BootComplete& ev) { } void Interactive::entry() { - // sCurrentScreen.reset(new screens::Menu()); + //sCurrentScreen.reset(new screens::Menu()); } } // namespace states diff --git a/src/ui/wheel_encoder.cpp b/src/ui/wheel_encoder.cpp new file mode 100644 index 00000000..0129434d --- /dev/null +++ b/src/ui/wheel_encoder.cpp @@ -0,0 +1,39 @@ +/* + * Copyright 2023 jacqueline <me@jacqueline.id.au> + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#include "wheel_encoder.hpp" +#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); +} + + TouchWheelEncoder::TouchWheelEncoder(std::weak_ptr<drivers::RelativeWheel> wheel) : wheel_(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 TouchWheelEncoder::Read(lv_indev_data_t *data) -> void { + auto lock = wheel_.lock(); + if (lock == nullptr) { + data->state = LV_INDEV_STATE_RELEASED; + data->enc_diff = 0; + return; + } + + lock->Update(); + data->state = lock->is_pressed() ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED; + data->enc_diff = lock->ticks(); +} + +} // namespace ui |
