Ken Van Hoeylandt 9f721e6655
Refactor LVGL code into kernel module (#472)
* **New Features**
  * Added a standalone LVGL module and enabled LVGL support in the simulator for richer local UI testing.

* **Refactor**
  * HAL and LVGL split into distinct modules; startup and device attach/detach flows reorganized for clearer lifecycle management.
  * Public APIs tightened with clearer nullability/documentation.

* **Bug Fixes**
  * More consistent LVGL start/stop and device attach/detach behavior for improved stability.
2026-02-01 22:57:45 +01:00

113 lines
3.1 KiB
C++

#pragma once
#include <Tactility/hal/encoder/EncoderDevice.h>
#include <Tactility/hal/gpio/Gpio.h>
#include <Tactility/TactilityCore.h>
#include <Tactility/Thread.h>
class ButtonControl final : public tt::hal::encoder::EncoderDevice {
public:
enum class Event {
ShortPress,
LongPress
};
enum class Action {
UiSelectNext,
UiSelectPrevious,
UiPressSelected,
AppClose,
};
struct PinConfiguration {
tt::hal::gpio::Pin pin;
Event event;
Action action;
};
private:
struct PinState {
long pressStartTime = 0;
long pressReleaseTime = 0;
bool pressState = false;
bool triggerShortPress = false;
bool triggerLongPress = false;
};
lv_indev_t* deviceHandle = nullptr;
std::shared_ptr<tt::Thread> driverThread;
bool interruptDriverThread = false;
tt::Mutex mutex;
std::vector<PinConfiguration> pinConfigurations;
std::vector<PinState> pinStates;
bool shouldInterruptDriverThread() const;
static void updatePin(std::vector<PinConfiguration>::const_reference value, std::vector<PinState>::reference pin_state);
void driverThreadMain();
static void readCallback(lv_indev_t* indev, lv_indev_data_t* data);
void startThread();
void stopThread();
public:
explicit ButtonControl(const std::vector<PinConfiguration>& pinConfigurations);
~ButtonControl() override;
std::string getName() const override { return "ButtonControl"; }
std::string getDescription() const override { return "ButtonControl input driver"; }
bool startLvgl(lv_display_t* display) override;
bool stopLvgl() override;
/** Could return nullptr if not started */
lv_indev_t* getLvglIndev() override { return deviceHandle; }
static std::shared_ptr<ButtonControl> createOneButtonControl(tt::hal::gpio::Pin pin) {
return std::make_shared<ButtonControl>(std::vector {
PinConfiguration {
.pin = pin,
.event = Event::ShortPress,
.action = Action::UiSelectNext
},
PinConfiguration {
.pin = pin,
.event = Event::LongPress,
.action = Action::UiPressSelected
}
});
}
static std::shared_ptr<ButtonControl> createTwoButtonControl(tt::hal::gpio::Pin primaryPin, tt::hal::gpio::Pin secondaryPin) {
return std::make_shared<ButtonControl>(std::vector {
PinConfiguration {
.pin = primaryPin,
.event = Event::ShortPress,
.action = Action::UiPressSelected
},
PinConfiguration {
.pin = primaryPin,
.event = Event::LongPress,
.action = Action::AppClose
},
PinConfiguration {
.pin = secondaryPin,
.event = Event::ShortPress,
.action = Action::UiSelectNext
},
PinConfiguration {
.pin = secondaryPin,
.event = Event::LongPress,
.action = Action::UiSelectPrevious
}
});
}
};