feat(display): night-dim backlight window for screensaver
- DisplaySettings: nightDimEnabled/startHour/endHour/duty (default 22:00-07:00 at duty 20), persisted in display.properties - Display settings page: Night dim switch + Dim from/until hour dropdowns + Dim brightness slider - DisplayIdle: screensaver runs at the dimmed level when the local hour is inside the window (wrap-around aware); falls back to the regular duty when time is unknown (year < 2025)
This commit is contained in:
@@ -42,6 +42,10 @@ struct Context {
|
||||
lv_obj_t* timeoutSwitch = nullptr;
|
||||
lv_obj_t* timeoutDropdown = nullptr;
|
||||
lv_obj_t* screensaverDropdown = nullptr;
|
||||
lv_obj_t* nightDimSwitch = nullptr;
|
||||
lv_obj_t* nightDimStartDropdown = nullptr;
|
||||
lv_obj_t* nightDimEndDropdown = nullptr;
|
||||
lv_obj_t* nightDimDutySlider = nullptr;
|
||||
};
|
||||
|
||||
|
||||
@@ -154,6 +158,82 @@ void onScreensaverChanged(lv_event_t* event) {
|
||||
}
|
||||
}
|
||||
|
||||
static void setNightDimControlsEnabled(Context* ctx, bool enabled) {
|
||||
if (ctx->nightDimStartDropdown != nullptr) {
|
||||
if (enabled) {
|
||||
lv_obj_clear_state(ctx->nightDimStartDropdown, LV_STATE_DISABLED);
|
||||
} else {
|
||||
lv_obj_add_state(ctx->nightDimStartDropdown, LV_STATE_DISABLED);
|
||||
}
|
||||
}
|
||||
if (ctx->nightDimEndDropdown != nullptr) {
|
||||
if (enabled) {
|
||||
lv_obj_clear_state(ctx->nightDimEndDropdown, LV_STATE_DISABLED);
|
||||
} else {
|
||||
lv_obj_add_state(ctx->nightDimEndDropdown, LV_STATE_DISABLED);
|
||||
}
|
||||
}
|
||||
if (ctx->nightDimDutySlider != nullptr) {
|
||||
if (enabled) {
|
||||
lv_obj_clear_state(ctx->nightDimDutySlider, LV_STATE_DISABLED);
|
||||
} else {
|
||||
lv_obj_add_state(ctx->nightDimDutySlider, LV_STATE_DISABLED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const char* hourOptions() {
|
||||
// 00..23, one per line
|
||||
static const char* options =
|
||||
"00\n01\n02\n03\n04\n05\n06\n07\n08\n09\n10\n11\n"
|
||||
"12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23";
|
||||
return options;
|
||||
}
|
||||
|
||||
void onNightDimSwitch(lv_event_t* event) {
|
||||
auto* ctx = static_cast<Context*>(lv_event_get_user_data(event));
|
||||
auto* sw = static_cast<lv_obj_t*>(lv_event_get_target(event));
|
||||
bool enabled = lv_obj_has_state(sw, LV_STATE_CHECKED);
|
||||
ctx->displaySettings.nightDimEnabled = enabled;
|
||||
ctx->displaySettingsUpdated = true;
|
||||
setNightDimControlsEnabled(ctx, enabled);
|
||||
}
|
||||
|
||||
void onNightDimStartChanged(lv_event_t* event) {
|
||||
auto* ctx = static_cast<Context*>(lv_event_get_user_data(event));
|
||||
auto* dropdown = static_cast<lv_obj_t*>(lv_event_get_target(event));
|
||||
uint32_t idx = lv_dropdown_get_selected(dropdown);
|
||||
if (idx > 23) {
|
||||
return;
|
||||
}
|
||||
ctx->displaySettings.nightDimStartHour = static_cast<uint8_t>(idx);
|
||||
ctx->displaySettingsUpdated = true;
|
||||
}
|
||||
|
||||
void onNightDimEndChanged(lv_event_t* event) {
|
||||
auto* ctx = static_cast<Context*>(lv_event_get_user_data(event));
|
||||
auto* dropdown = static_cast<lv_obj_t*>(lv_event_get_target(event));
|
||||
uint32_t idx = lv_dropdown_get_selected(dropdown);
|
||||
if (idx > 23) {
|
||||
return;
|
||||
}
|
||||
ctx->displaySettings.nightDimEndHour = static_cast<uint8_t>(idx);
|
||||
ctx->displaySettingsUpdated = true;
|
||||
}
|
||||
|
||||
void onNightDimDutyChanged(lv_event_t* event) {
|
||||
auto* ctx = static_cast<Context*>(lv_event_get_user_data(event));
|
||||
auto* slider = static_cast<lv_obj_t*>(lv_event_get_target(event));
|
||||
int32_t value = lv_slider_get_value(slider);
|
||||
if (value < 0) {
|
||||
value = 0;
|
||||
} else if (value > 255) {
|
||||
value = 255;
|
||||
}
|
||||
ctx->displaySettings.nightDimDuty = static_cast<uint8_t>(value);
|
||||
ctx->displaySettingsUpdated = true;
|
||||
}
|
||||
|
||||
void createWidgets(lv_obj_t* parent, void* userData) {
|
||||
auto* ctx = static_cast<Context*>(userData);
|
||||
|
||||
@@ -314,6 +394,71 @@ void createWidgets(lv_obj_t* parent, void* userData) {
|
||||
if (!ctx->displaySettings.backlightTimeoutEnabled) {
|
||||
lv_obj_add_state(ctx->screensaverDropdown, LV_STATE_DISABLED);
|
||||
}
|
||||
|
||||
// Night dim: dim the backlight while the screensaver is up, during a time window
|
||||
auto* night_dim_wrapper = lv_obj_create(main_wrapper);
|
||||
lv_obj_set_size(night_dim_wrapper, LV_PCT(100), LV_SIZE_CONTENT);
|
||||
lv_obj_set_style_pad_all(night_dim_wrapper, 0, LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_border_width(night_dim_wrapper, 0, LV_STATE_DEFAULT);
|
||||
|
||||
auto* night_dim_label = lv_label_create(night_dim_wrapper);
|
||||
lv_label_set_text(night_dim_label, "Night dim");
|
||||
lv_obj_align(night_dim_label, LV_ALIGN_LEFT_MID, 0, 0);
|
||||
|
||||
ctx->nightDimSwitch = lv_switch_create(night_dim_wrapper);
|
||||
if (ctx->displaySettings.nightDimEnabled) {
|
||||
lv_obj_add_state(ctx->nightDimSwitch, LV_STATE_CHECKED);
|
||||
}
|
||||
lv_obj_align(ctx->nightDimSwitch, LV_ALIGN_RIGHT_MID, 0, 0);
|
||||
lv_obj_add_event_cb(ctx->nightDimSwitch, onNightDimSwitch, LV_EVENT_VALUE_CHANGED, ctx);
|
||||
|
||||
auto* night_dim_start_wrapper = lv_obj_create(main_wrapper);
|
||||
lv_obj_set_size(night_dim_start_wrapper, LV_PCT(100), LV_SIZE_CONTENT);
|
||||
lv_obj_set_style_pad_all(night_dim_start_wrapper, 0, LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_border_width(night_dim_start_wrapper, 0, LV_STATE_DEFAULT);
|
||||
|
||||
auto* night_dim_start_label = lv_label_create(night_dim_start_wrapper);
|
||||
lv_label_set_text(night_dim_start_label, "Dim from");
|
||||
lv_obj_align(night_dim_start_label, LV_ALIGN_LEFT_MID, 0, 0);
|
||||
|
||||
ctx->nightDimStartDropdown = lv_dropdown_create(night_dim_start_wrapper);
|
||||
lv_dropdown_set_options(ctx->nightDimStartDropdown, hourOptions());
|
||||
lv_obj_align(ctx->nightDimStartDropdown, LV_ALIGN_RIGHT_MID, 0, 0);
|
||||
lv_obj_add_event_cb(ctx->nightDimStartDropdown, onNightDimStartChanged, LV_EVENT_VALUE_CHANGED, ctx);
|
||||
lv_dropdown_set_selected(ctx->nightDimStartDropdown, ctx->displaySettings.nightDimStartHour > 23 ? 0 : ctx->displaySettings.nightDimStartHour);
|
||||
|
||||
auto* night_dim_end_wrapper = lv_obj_create(main_wrapper);
|
||||
lv_obj_set_size(night_dim_end_wrapper, LV_PCT(100), LV_SIZE_CONTENT);
|
||||
lv_obj_set_style_pad_all(night_dim_end_wrapper, 0, LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_border_width(night_dim_end_wrapper, 0, LV_STATE_DEFAULT);
|
||||
|
||||
auto* night_dim_end_label = lv_label_create(night_dim_end_wrapper);
|
||||
lv_label_set_text(night_dim_end_label, "Dim until");
|
||||
lv_obj_align(night_dim_end_label, LV_ALIGN_LEFT_MID, 0, 0);
|
||||
|
||||
ctx->nightDimEndDropdown = lv_dropdown_create(night_dim_end_wrapper);
|
||||
lv_dropdown_set_options(ctx->nightDimEndDropdown, hourOptions());
|
||||
lv_obj_align(ctx->nightDimEndDropdown, LV_ALIGN_RIGHT_MID, 0, 0);
|
||||
lv_obj_add_event_cb(ctx->nightDimEndDropdown, onNightDimEndChanged, LV_EVENT_VALUE_CHANGED, ctx);
|
||||
lv_dropdown_set_selected(ctx->nightDimEndDropdown, ctx->displaySettings.nightDimEndHour > 23 ? 0 : ctx->displaySettings.nightDimEndHour);
|
||||
|
||||
auto* night_dim_duty_wrapper = lv_obj_create(main_wrapper);
|
||||
lv_obj_set_size(night_dim_duty_wrapper, LV_PCT(100), LV_SIZE_CONTENT);
|
||||
lv_obj_set_style_pad_all(night_dim_duty_wrapper, 0, LV_STATE_DEFAULT);
|
||||
lv_obj_set_style_border_width(night_dim_duty_wrapper, 0, LV_STATE_DEFAULT);
|
||||
|
||||
auto* night_dim_duty_label = lv_label_create(night_dim_duty_wrapper);
|
||||
lv_label_set_text(night_dim_duty_label, "Dim brightness");
|
||||
lv_obj_align(night_dim_duty_label, LV_ALIGN_LEFT_MID, 0, 0);
|
||||
|
||||
ctx->nightDimDutySlider = lv_slider_create(night_dim_duty_wrapper);
|
||||
lv_obj_set_width(ctx->nightDimDutySlider, LV_PCT(50));
|
||||
lv_obj_align(ctx->nightDimDutySlider, LV_ALIGN_RIGHT_MID, 0, 0);
|
||||
lv_slider_set_range(ctx->nightDimDutySlider, 0, 255);
|
||||
lv_slider_set_value(ctx->nightDimDutySlider, ctx->displaySettings.nightDimDuty, LV_ANIM_OFF);
|
||||
lv_obj_add_event_cb(ctx->nightDimDutySlider, onNightDimDutyChanged, LV_EVENT_VALUE_CHANGED, ctx);
|
||||
|
||||
setNightDimControlsEnabled(ctx, ctx->displaySettings.nightDimEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user