Clip glow to card inset and simplify slider modal UX
Release PR / Maintain Version Packages PR (push) Canceled after 0s
CI / Identify a merged version PR (push) Canceled after 0s
CI / Rust checks, rendering, and native package (push) Canceled after 0s
CI / Publish release and Homebrew feed (push) Canceled after 0s

Inset glow clip rects by 6px on all card types to prevent radial
glow from bleeding past rounded corners. Simplify slider modal:
remove close button (Back key closes), Left/Right adjust the
focused slider, Up/Down move between sliders.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Kaloyan DanchevandClaude Opus 4.6 committed 2026-10-24 15:55:33 +03:00
1 parent fcc7a41f02
commit a890ba6baf
2 files changed
+11 -33

No files matched your search

+2 -14
View File
@@ -1411,7 +1411,6 @@ impl State {
match &self.focus {
Target::HaSliderBrightness => match direction {
Direction::Up => self.focus(Target::HaSliderClose, controls),
Direction::Down if has_color_temp => {
self.focus(Target::HaSliderColorTemp, controls);
}
@@ -1429,10 +1428,6 @@ impl State {
}
_ => {}
},
Target::HaSliderClose => match direction {
Direction::Down => self.focus(Target::HaSliderBrightness, controls),
_ => {}
},
_ => {}
}
vec![]
@@ -1821,15 +1816,8 @@ impl State {
}
}
}
Target::HaSliderBrightness | Target::HaSliderColorTemp => {
// scroll handles these — OK does nothing on slider tracks
}
Target::HaSliderClose => {
self.ha.slider_open = false;
self.focus = Target::HaCard(self.ha.room,
self.ha.config.rooms[self.ha.room].cards.iter()
.position(|c| c.entity_id == self.ha.slider_entity)
.unwrap_or(0));
Target::HaSliderBrightness | Target::HaSliderColorTemp | Target::HaSliderClose => {
// sliders adjusted via Left/Right/scroll — OK does nothing
}
Target::HaVacuumRoom(index) => {
if index < self.ha.vacuum_selected.len() {
+9 -19
View File
@@ -1909,14 +1909,14 @@ fn ha_toggle_card(
let accent = ha_state_color(entity);
let is_on = entity.is_some_and(|e| e.state == "on" || e.state == "open");
// Radial glow from icon
// Radial glow from icon (inset clip to hide bleed past rounded corners)
if is_on {
let fill_color = ha_fill_color(&card.card_type, entity);
let icon_cx = rect.x + 40.;
let icon_cy = rect.y + 40.;
let glow_size = 80.;
let glow_rect = Rect::new(icon_cx - glow_size, icon_cy - glow_size, glow_size * 2., glow_size * 2.);
out.draw.push(Draw::Clip(Some(rect)));
out.draw.push(Draw::Clip(Some(rect.inset(6.))));
out.glow(glow_rect, glow_size, glow_size * 0.8, fill_color);
out.draw.push(Draw::Clip(None));
}
@@ -2001,7 +2001,7 @@ fn ha_range_card(
c(0xbbbbbb, 0.5)
};
// Radial glow from icon center, clipped to card
// Radial glow from icon center, clipped to card (inset to hide corner bleed)
if is_on && pct > 0 {
let glow_alpha = (pct as f32 / 100.).clamp(0.1, 0.45);
let glow_color = [accent[0], accent[1], accent[2], glow_alpha];
@@ -2009,7 +2009,7 @@ fn ha_range_card(
let icon_cy = rect.y + 40.;
let glow_size = 80.;
let glow_rect = Rect::new(icon_cx - glow_size, icon_cy - glow_size, glow_size * 2., glow_size * 2.);
out.draw.push(Draw::Clip(Some(rect)));
out.draw.push(Draw::Clip(Some(rect.inset(6.))));
out.glow(glow_rect, glow_size, glow_size * 0.8, glow_color);
out.draw.push(Draw::Clip(None));
}
@@ -2096,7 +2096,7 @@ fn ha_climate_card(
let icon_cy = rect.y + 40.;
let glow_size = 80.;
let glow_rect = Rect::new(icon_cx - glow_size, icon_cy - glow_size, glow_size * 2., glow_size * 2.);
out.draw.push(Draw::Clip(Some(rect)));
out.draw.push(Draw::Clip(Some(rect.inset(6.))));
out.glow(glow_rect, glow_size, glow_size * 0.8, glow_color);
out.draw.push(Draw::Clip(None));
}
@@ -2410,7 +2410,7 @@ fn ha_media_card(
let art_cy = art_y + art_size / 2.;
let glow_r = art_size;
let glow_rect = Rect::new(art_cx - glow_r, art_cy - glow_r, glow_r * 2., glow_r * 2.);
out.draw.push(Draw::Clip(Some(rect)));
out.draw.push(Draw::Clip(Some(rect.inset(6.))));
out.glow(glow_rect, glow_r, glow_r * 0.7, [accent[0], accent[1], accent[2], glow_alpha]);
out.draw.push(Draw::Clip(None));
}
@@ -2529,7 +2529,7 @@ fn ha_cover_card(
let fill_color = ha_fill_color(&card.card_type, entity);
let glow_alpha = (open_pct * fill_color[3]).clamp(0.05, 0.40);
let glow_color = [fill_color[0], fill_color[1], fill_color[2], glow_alpha];
out.draw.push(Draw::Clip(Some(rect)));
out.draw.push(Draw::Clip(Some(rect.inset(6.))));
if is_curtain {
// Curtain: glow from center of card
let cx = rect.x + rect.w / 2.;
@@ -2853,7 +2853,7 @@ fn ha_slider_modal(out: &mut Scene, state: &State, assets: &Assets) {
let has_color_temp = matches!(card_type, HaCardType::Range)
&& entity.and_then(|e| e.attributes.get("color_temp")).is_some();
let modal_h = if has_color_temp { 400. } else { 280. };
let modal_h = if has_color_temp { 340. } else { 220. };
let modal = Rect::new(480., (1080. - modal_h) / 2., 960., modal_h);
ha_glass(out, modal, false);
@@ -2879,16 +2879,6 @@ fn ha_slider_modal(out: &mut Scene, state: &State, assets: &Assets) {
false,
);
// Close button
let close_rect = Rect::new(modal.x + modal.w - 72., modal.y + 24., 40., 40.);
out.shape(close_rect, 20., c(0xffffff, 0.08));
out.icon(assets, "close", close_rect.inset(10.), c(0xeeeeee, 0.7));
let close_focused = state.focus == Target::HaSliderClose;
if close_focused {
out.border(close_rect.inset(-3.), 23., 2., WHITE);
}
out.control(Target::HaSliderClose, close_rect, false);
// Primary slider (brightness / temperature / position)
let slider_y = modal.y + 88.;
let slider_x = modal.x + 40.;
@@ -2987,7 +2977,7 @@ fn ha_slider_modal(out: &mut Scene, state: &State, assets: &Assets) {
// Hint text at bottom
let hint_y = modal.y + modal_h - 44.;
out.text(
"Scroll or ◀ ▶ to adjust",
"◀ ▶ to adjust · Back to close",
Rect::new(slider_x, hint_y, slider_w, 20.),
text(14., 400, -0.01),
c(0xeeeeee, 0.4),