1use crate::{
2 DIM_ALPHA, FOCUS_STATE_LAYER_OPACITY, PRESSED_STATE_LAYER_OPACITY, style::mix_colors,
3 theme::ColorScheme,
4};
5use iced::{Color, border::Radius};
6
7pub enum Button {
8 Primary,
9 InversePrimary,
10 Secondary,
11 InverseSecondary,
12 Tertiary,
13 InverseTertiary,
14 Outlined,
15 Error,
16}
17
18pub fn button(
19 status: iced_widget::button::Status,
20 theme: &impl ColorScheme,
21 style: Button,
22) -> iced_widget::button::Style {
23 let (color_regular, color_hovered, color_pressed, content_color, border_color) = match style {
24 Button::Primary => (
25 theme.primary(),
26 mix_colors(
27 theme.primary(),
28 theme.surface(),
29 1.0 - FOCUS_STATE_LAYER_OPACITY,
30 ),
31 mix_colors(
32 theme.primary(),
33 theme.surface(),
34 1.0 - PRESSED_STATE_LAYER_OPACITY,
35 ),
36 theme.on_primary(),
37 None,
38 ),
39 Button::InversePrimary => (
40 theme.on_primary(),
41 mix_colors(
42 theme.on_primary(),
43 theme.surface(),
44 1.0 - FOCUS_STATE_LAYER_OPACITY,
45 ),
46 mix_colors(
47 theme.on_primary(),
48 theme.surface(),
49 1.0 - PRESSED_STATE_LAYER_OPACITY,
50 ),
51 theme.primary(),
52 None,
53 ),
54 Button::Secondary => (
55 theme.secondary(),
56 mix_colors(
57 theme.secondary(),
58 theme.surface(),
59 1.0 - FOCUS_STATE_LAYER_OPACITY,
60 ),
61 mix_colors(
62 theme.secondary(),
63 theme.surface(),
64 1.0 - PRESSED_STATE_LAYER_OPACITY,
65 ),
66 theme.on_secondary(),
67 None,
68 ),
69 Button::InverseSecondary => (
70 theme.on_secondary(),
71 mix_colors(
72 theme.on_secondary(),
73 theme.surface(),
74 1.0 - FOCUS_STATE_LAYER_OPACITY,
75 ),
76 mix_colors(
77 theme.on_secondary(),
78 theme.surface(),
79 1.0 - PRESSED_STATE_LAYER_OPACITY,
80 ),
81 theme.secondary(),
82 None,
83 ),
84 Button::Tertiary => (
85 theme.tertiary(),
86 mix_colors(
87 theme.tertiary(),
88 theme.surface(),
89 1.0 - FOCUS_STATE_LAYER_OPACITY,
90 ),
91 mix_colors(
92 theme.tertiary(),
93 theme.surface(),
94 1.0 - PRESSED_STATE_LAYER_OPACITY,
95 ),
96 theme.on_tertiary(),
97 None,
98 ),
99 Button::InverseTertiary => (
100 theme.on_tertiary(),
101 mix_colors(
102 theme.on_tertiary(),
103 theme.surface(),
104 1.0 - FOCUS_STATE_LAYER_OPACITY,
105 ),
106 mix_colors(
107 theme.on_tertiary(),
108 theme.surface(),
109 1.0 - PRESSED_STATE_LAYER_OPACITY,
110 ),
111 theme.tertiary(),
112 None,
113 ),
114 Button::Outlined => (
115 Color::TRANSPARENT,
116 theme
117 .on_surface_variant()
118 .scale_alpha(FOCUS_STATE_LAYER_OPACITY),
119 theme
120 .on_surface_variant()
121 .scale_alpha(PRESSED_STATE_LAYER_OPACITY),
122 theme.on_surface_variant(),
123 Some(theme.on_surface_variant()),
124 ),
125 Button::Error => (
126 theme.error(),
127 mix_colors(
128 theme.error(),
129 theme.on_error(),
130 1.0 - FOCUS_STATE_LAYER_OPACITY,
131 ),
132 mix_colors(
133 theme.error(),
134 theme.on_error(),
135 1.0 - PRESSED_STATE_LAYER_OPACITY,
136 ),
137 theme.on_error(),
138 None,
139 ),
140 };
141 iced_widget::button::Style {
142 background: Some(iced::Background::Color(match status {
143 iced_widget::button::Status::Active => color_regular,
144 iced_widget::button::Status::Hovered => color_hovered,
145 iced_widget::button::Status::Pressed => color_pressed,
146 iced_widget::button::Status::Disabled => color_regular.scale_alpha(DIM_ALPHA),
147 })),
148 border: iced::Border {
149 radius: Radius::from(f32::MAX),
150 color: border_color
151 .map(|c| {
152 if status == iced_widget::button::Status::Disabled {
153 c.scale_alpha(DIM_ALPHA)
154 } else {
155 c
156 }
157 })
158 .unwrap_or_default(),
159 width: if border_color.is_some() { 1.0 } else { 0.0 },
160 },
161 text_color: content_color,
162 ..Default::default()
163 }
164}