bevy_ui_builders/button/
types.rs

1//! Button component types and markers
2
3use bevy::prelude::*;
4
5/// Marker component for styled buttons
6#[derive(Component)]
7pub struct StyledButton;
8
9/// Component storing button-specific state colors
10/// This is kept for compatibility with existing button code
11/// but new code should use HoverColors from systems::hover
12#[derive(Component)]
13pub struct ButtonStateColors {
14    pub normal_bg: Color,
15    pub hover_bg: Color,
16    pub pressed_bg: Color,
17    pub normal_border: Color,
18    pub hover_border: Color,
19    pub pressed_border: Color,
20}
21
22/// Component for button-specific animation state
23/// This is kept for compatibility with existing button code
24/// but new code should use HoverAnimationState from systems::hover
25#[derive(Component)]
26pub struct ButtonAnimationState {
27    /// Current scale value (animated)
28    pub current_scale: f32,
29    /// Target scale value
30    pub target_scale: f32,
31    /// Current color blend factor (0.0 = normal, 1.0 = hover/pressed)
32    pub current_color_blend: f32,
33    /// Target color blend factor
34    pub target_color_blend: f32,
35    /// Animation speed (higher = faster)
36    pub animation_speed: f32,
37}
38
39// Note: HoverScale, HoverBrightness, and OriginalColors have been moved to
40// systems::hover for universal use across all UI elements
41
42// ============================================================================
43// Selection State Components
44// ============================================================================
45
46/// Marker component indicating this button supports selection/toggle behavior.
47/// Buttons with this component will automatically respond to clicks by toggling
48/// their Selected state (if auto_toggle is true).
49#[derive(Component)]
50pub struct SelectableButton {
51    /// Whether the button auto-toggles Selected on click (default: true)
52    pub auto_toggle: bool,
53}
54
55impl Default for SelectableButton {
56    fn default() -> Self {
57        Self { auto_toggle: true }
58    }
59}
60
61/// Marker component indicating button is currently selected.
62/// Used for toggle buttons, checkboxes, or items in a list.
63/// Can be added/removed at runtime to change selection state.
64#[derive(Component)]
65pub struct Selected;
66
67/// Marker component indicating button is currently active.
68/// Used for current tab in a tab bar, current page in navigation, etc.
69/// Active state takes visual precedence over Selected state.
70/// Can coexist with Selected component.
71#[derive(Component)]
72pub struct Active;
73
74/// Color configuration for all button states.
75/// Auto-generated from ButtonStyle by default, but can be overridden.
76#[derive(Component, Clone)]
77pub struct ButtonSelectionColors {
78    pub normal: StateColorSet,
79    pub selected: StateColorSet,
80    pub active: StateColorSet,
81}
82
83/// Color set for a specific state (normal/selected/active).
84/// Contains colors for all interaction states (normal/hover/pressed).
85#[derive(Clone, Debug)]
86pub struct StateColorSet {
87    pub normal_bg: Color,
88    pub hover_bg: Color,
89    pub pressed_bg: Color,
90    pub normal_border: Color,
91    pub hover_border: Color,
92    pub pressed_border: Color,
93}
94
95impl StateColorSet {
96    /// Create a new StateColorSet with the given colors
97    pub fn new(
98        normal_bg: Color,
99        hover_bg: Color,
100        pressed_bg: Color,
101        normal_border: Color,
102        hover_border: Color,
103        pressed_border: Color,
104    ) -> Self {
105        Self {
106            normal_bg,
107            hover_bg,
108            pressed_bg,
109            normal_border,
110            hover_border,
111            pressed_border,
112        }
113    }
114
115    /// Create a StateColorSet from a single background and border color
116    /// (generates hover/pressed variants automatically)
117    pub fn from_base(bg: Color, border: Color) -> Self {
118        Self {
119            normal_bg: bg,
120            hover_bg: adjust_brightness(bg, 1.1),
121            pressed_bg: adjust_brightness(bg, 0.9),
122            normal_border: border,
123            hover_border: border,
124            pressed_border: border,
125        }
126    }
127}
128
129/// Message emitted when a selectable button's selection state changes
130#[derive(Message, Clone, Debug)]
131pub struct SelectionChanged {
132    /// The button entity that changed
133    pub entity: Entity,
134    /// Whether the button is now selected
135    pub selected: bool,
136}
137
138// ============================================================================
139// Helper Functions
140// ============================================================================
141
142/// Adjust brightness of a color by a multiplier
143fn adjust_brightness(color: Color, multiplier: f32) -> Color {
144    let linear = color.to_linear();
145    Color::LinearRgba(LinearRgba {
146        red: (linear.red * multiplier).min(1.0),
147        green: (linear.green * multiplier).min(1.0),
148        blue: (linear.blue * multiplier).min(1.0),
149        alpha: linear.alpha,
150    })
151}