feat: Transiciones hover en Select widget
SelectState ahora incluye: - hover: HoverTransition para transiciones suaves - last_time_ms: tracking de tiempo para delta El color de fondo del botón principal del Select ahora transiciona suavemente entre normal y hover (lighten 5%). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
25728c151c
commit
74e83d2334
1 changed files with 17 additions and 4 deletions
|
|
@ -2,6 +2,7 @@
|
||||||
//!
|
//!
|
||||||
//! A dropdown menu for selecting one option from a list.
|
//! A dropdown menu for selecting one option from a list.
|
||||||
//! The dropdown opens on click and closes when an option is selected.
|
//! The dropdown opens on click and closes when an option is selected.
|
||||||
|
//! Supports smooth hover transitions via HoverTransition.
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const Context = @import("../core/context.zig").Context;
|
const Context = @import("../core/context.zig").Context;
|
||||||
|
|
@ -9,6 +10,7 @@ const Command = @import("../core/command.zig");
|
||||||
const Layout = @import("../core/layout.zig");
|
const Layout = @import("../core/layout.zig");
|
||||||
const Style = @import("../core/style.zig");
|
const Style = @import("../core/style.zig");
|
||||||
const Input = @import("../core/input.zig");
|
const Input = @import("../core/input.zig");
|
||||||
|
const animation = @import("../render/animation.zig");
|
||||||
|
|
||||||
/// Select state (caller-managed)
|
/// Select state (caller-managed)
|
||||||
pub const SelectState = struct {
|
pub const SelectState = struct {
|
||||||
|
|
@ -20,6 +22,10 @@ pub const SelectState = struct {
|
||||||
scroll_offset: usize = 0,
|
scroll_offset: usize = 0,
|
||||||
/// Whether this widget has focus
|
/// Whether this widget has focus
|
||||||
focused: bool = false,
|
focused: bool = false,
|
||||||
|
/// Hover transition for smooth effects
|
||||||
|
hover: animation.HoverTransition = .{},
|
||||||
|
/// Last frame time for delta calculation
|
||||||
|
last_time_ms: u64 = 0,
|
||||||
|
|
||||||
/// Get selected index as optional usize
|
/// Get selected index as optional usize
|
||||||
pub fn selectedIndex(self: SelectState) ?usize {
|
pub fn selectedIndex(self: SelectState) ?usize {
|
||||||
|
|
@ -110,15 +116,22 @@ pub fn selectRect(
|
||||||
const has_focus = ctx.hasFocus(widget_id);
|
const has_focus = ctx.hasFocus(widget_id);
|
||||||
state.focused = has_focus;
|
state.focused = has_focus;
|
||||||
|
|
||||||
// Determine button colors
|
// Update hover transition
|
||||||
|
const current_time = ctx.current_time_ms;
|
||||||
|
const dt_ms: u64 = if (state.last_time_ms > 0 and current_time > state.last_time_ms)
|
||||||
|
current_time - state.last_time_ms
|
||||||
|
else
|
||||||
|
16;
|
||||||
|
state.last_time_ms = current_time;
|
||||||
|
state.hover.update(hovered and !config.disabled and !state.open, dt_ms);
|
||||||
|
|
||||||
|
// Determine button colors with smooth transition
|
||||||
const bg_color = if (config.disabled)
|
const bg_color = if (config.disabled)
|
||||||
theme.button_bg.darken(20)
|
theme.button_bg.darken(20)
|
||||||
else if (state.open)
|
else if (state.open)
|
||||||
theme.button_bg.lighten(10)
|
theme.button_bg.lighten(10)
|
||||||
else if (hovered)
|
|
||||||
theme.button_bg.lighten(5)
|
|
||||||
else
|
else
|
||||||
theme.button_bg;
|
state.hover.blend(theme.button_bg, theme.button_bg.lighten(5));
|
||||||
|
|
||||||
const border_color = if (has_focus or state.open) theme.primary else theme.border;
|
const border_color = if (has_focus or state.open) theme.primary else theme.border;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue