2026-04-23 15:12:29 +08:00
|
|
|
#include <stdbool.h>
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
#include <app_event_manager.h>
|
|
|
|
|
|
|
|
|
|
#define MODULE settings_module
|
|
|
|
|
#include <caf/events/click_event.h>
|
|
|
|
|
#include <caf/events/module_state_event.h>
|
|
|
|
|
#include <caf/events/power_event.h>
|
|
|
|
|
|
|
|
|
|
#include <zephyr/logging/log.h>
|
|
|
|
|
|
|
|
|
|
#include "encoder_event.h"
|
|
|
|
|
#include "module_lifecycle.h"
|
|
|
|
|
#include "settings_mode_event.h"
|
|
|
|
|
#include "theme_color.h"
|
|
|
|
|
#include "theme_rgb_update_event.h"
|
2026-04-23 18:46:55 +08:00
|
|
|
#include "ui/ui_settings_controller.h"
|
2026-04-23 15:12:29 +08:00
|
|
|
|
|
|
|
|
LOG_MODULE_REGISTER(MODULE, LOG_LEVEL_INF);
|
|
|
|
|
|
|
|
|
|
#define SETTINGS_MUTE_KEY_ID 0x180U
|
|
|
|
|
|
|
|
|
|
struct settings_module_ctx {
|
|
|
|
|
struct module_lifecycle_ctx lc;
|
|
|
|
|
bool active;
|
|
|
|
|
struct theme_rgb current_theme;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static int do_init(void);
|
|
|
|
|
static int do_start(void);
|
|
|
|
|
static int do_stop(void);
|
|
|
|
|
|
|
|
|
|
static const struct module_lifecycle_cfg lifecycle_cfg = {
|
|
|
|
|
.mode = ML_MODE_POWER,
|
|
|
|
|
.stopped_state = MODULE_STATE_STANDBY,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const struct module_lifecycle_ops lifecycle_ops = {
|
|
|
|
|
.do_init = do_init,
|
|
|
|
|
.do_start = do_start,
|
|
|
|
|
.do_stop = do_stop,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static struct settings_module_ctx ctx = {
|
|
|
|
|
.lc = {
|
|
|
|
|
.state = LC_UNINIT,
|
|
|
|
|
.cfg = &lifecycle_cfg,
|
|
|
|
|
.ops = &lifecycle_ops,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void settings_exit(void)
|
|
|
|
|
{
|
|
|
|
|
if (!ctx.active) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ctx.active = false;
|
2026-04-23 18:46:55 +08:00
|
|
|
ui_settings_controller_close();
|
2026-04-23 15:12:29 +08:00
|
|
|
submit_settings_mode_event(false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void settings_enter(void)
|
|
|
|
|
{
|
|
|
|
|
if (ctx.active) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ctx.active = true;
|
|
|
|
|
submit_settings_mode_event(true);
|
2026-04-23 18:46:55 +08:00
|
|
|
ui_settings_controller_open();
|
2026-04-23 15:12:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int do_init(void)
|
|
|
|
|
{
|
|
|
|
|
ctx.active = false;
|
|
|
|
|
ctx.current_theme = (struct theme_rgb) {
|
|
|
|
|
.r = BLINKY_THEME_DEFAULT_R,
|
|
|
|
|
.g = BLINKY_THEME_DEFAULT_G,
|
|
|
|
|
.b = BLINKY_THEME_DEFAULT_B,
|
|
|
|
|
};
|
2026-04-23 18:46:55 +08:00
|
|
|
ui_settings_theme_set_current(ctx.current_theme);
|
2026-04-23 15:12:29 +08:00
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int do_start(void)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int do_stop(void)
|
|
|
|
|
{
|
|
|
|
|
settings_exit();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool handle_click_event(const struct click_event *event)
|
|
|
|
|
{
|
|
|
|
|
if (!module_lifecycle_is_running(&ctx.lc) ||
|
|
|
|
|
(event->key_id != SETTINGS_MUTE_KEY_ID)) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!ctx.active) {
|
|
|
|
|
if (event->click == CLICK_LONG) {
|
|
|
|
|
settings_enter();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (event->click) {
|
|
|
|
|
case CLICK_SHORT:
|
2026-04-23 18:46:55 +08:00
|
|
|
ui_settings_controller_select();
|
2026-04-23 15:12:29 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case CLICK_LONG:
|
2026-04-23 18:46:55 +08:00
|
|
|
{
|
|
|
|
|
bool active = ui_settings_controller_back();
|
|
|
|
|
|
|
|
|
|
if (!active) {
|
|
|
|
|
settings_exit();
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-04-23 15:12:29 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool handle_encoder_event(const struct encoder_event *event)
|
|
|
|
|
{
|
|
|
|
|
if (!module_lifecycle_is_running(&ctx.lc) || !ctx.active) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-23 18:46:55 +08:00
|
|
|
ui_settings_controller_move(event->detents);
|
2026-04-23 15:12:29 +08:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool handle_theme_rgb_update_event(
|
|
|
|
|
const struct theme_rgb_update_event *event)
|
|
|
|
|
{
|
|
|
|
|
ctx.current_theme = event->theme;
|
2026-04-23 18:46:55 +08:00
|
|
|
ui_settings_theme_set_current(event->theme);
|
2026-04-23 15:12:29 +08:00
|
|
|
|
|
|
|
|
if (ctx.active) {
|
2026-04-23 18:46:55 +08:00
|
|
|
ui_settings_controller_refresh(false);
|
2026-04-23 15:12:29 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static bool app_event_handler(const struct app_event_header *aeh)
|
|
|
|
|
{
|
|
|
|
|
if (is_click_event(aeh)) {
|
|
|
|
|
return handle_click_event(cast_click_event(aeh));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (is_encoder_event(aeh)) {
|
|
|
|
|
return handle_encoder_event(cast_encoder_event(aeh));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (is_theme_rgb_update_event(aeh)) {
|
|
|
|
|
return handle_theme_rgb_update_event(
|
|
|
|
|
cast_theme_rgb_update_event(aeh));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (is_module_state_event(aeh)) {
|
|
|
|
|
const struct module_state_event *event = cast_module_state_event(aeh);
|
|
|
|
|
|
|
|
|
|
if (check_state(event, MODULE_ID(main), MODULE_STATE_READY)) {
|
|
|
|
|
(void)module_set_lifecycle(&ctx.lc, LC_RUNNING);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (is_power_down_event(aeh)) {
|
|
|
|
|
if (module_lifecycle_is_initialized(&ctx.lc)) {
|
|
|
|
|
(void)module_set_lifecycle(&ctx.lc, LC_STOPPED);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (is_wake_up_event(aeh)) {
|
|
|
|
|
if (module_lifecycle_is_initialized(&ctx.lc)) {
|
|
|
|
|
(void)module_set_lifecycle(&ctx.lc, LC_RUNNING);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
APP_EVENT_LISTENER(MODULE, app_event_handler);
|
|
|
|
|
APP_EVENT_SUBSCRIBE(MODULE, click_event);
|
|
|
|
|
APP_EVENT_SUBSCRIBE(MODULE, encoder_event);
|
|
|
|
|
APP_EVENT_SUBSCRIBE(MODULE, module_state_event);
|
|
|
|
|
APP_EVENT_SUBSCRIBE(MODULE, theme_rgb_update_event);
|
|
|
|
|
APP_EVENT_SUBSCRIBE_EARLY(MODULE, power_down_event);
|
|
|
|
|
APP_EVENT_SUBSCRIBE(MODULE, wake_up_event);
|