|
4 | 4 | use std::path::Path; |
5 | 5 |
|
6 | 6 | use iced::{ |
7 | | - Alignment, Background, |
| 7 | + Alignment, Background, Border, |
8 | 8 | Length::Fill, |
9 | | - alignment::Vertical, |
10 | 9 | border::Radius, |
11 | | - widget::{Button, Row, Text, container, image::Viewer}, |
| 10 | + widget::{Button, Row, Text, button, container, image::Viewer}, |
12 | 11 | }; |
13 | 12 |
|
14 | 13 | use crate::{ |
15 | 14 | app::{Message, Page, RUSTCAST_DESC_NAME}, |
16 | 15 | commands::Function, |
| 16 | + config::Theme, |
| 17 | + styles::{tint, with_alpha}, |
17 | 18 | utils::handle_from_icns, |
18 | 19 | }; |
19 | 20 |
|
@@ -111,73 +112,88 @@ impl App { |
111 | 112 | id_num: u32, |
112 | 113 | focussed_id: u32, |
113 | 114 | ) -> impl Into<iced::Element<'a, Message>> { |
114 | | - let mut tile = Row::new().width(Fill).height(55); |
| 115 | + let focused = focussed_id == id_num; |
115 | 116 |
|
116 | | - if theme.show_icons |
117 | | - && let Some(icon) = &self.icons |
118 | | - { |
119 | | - tile = tile |
120 | | - .push(container(Viewer::new(icon).height(35).width(35))) |
121 | | - .align_y(Alignment::Center); |
122 | | - } |
123 | | - |
124 | | - tile = tile.push( |
125 | | - Button::new( |
| 117 | + // Title + subtitle (Raycast style) |
| 118 | + let text_block = iced::widget::Column::new() |
| 119 | + .spacing(2) |
| 120 | + .push( |
126 | 121 | Text::new(&self.name) |
127 | 122 | .font(theme.font()) |
128 | | - .height(Fill) |
129 | | - .width(Fill) |
130 | | - .color(theme.text_color(1.)) |
131 | | - .align_y(Vertical::Center), |
| 123 | + .size(16) |
| 124 | + .color(theme.text_color(1.0)), |
132 | 125 | ) |
133 | | - .on_press_maybe({ |
134 | | - match self.open_command.clone() { |
135 | | - AppCommand::Function(func) => Some(Message::RunFunction(func)), |
136 | | - AppCommand::Message(msg) => Some(msg), |
137 | | - AppCommand::Display => None, |
138 | | - } |
139 | | - }) |
140 | | - .style(|_, _| iced::widget::button::Style { |
141 | | - background: None, |
142 | | - text_color: theme.text_color(1.), |
143 | | - ..Default::default() |
144 | | - }) |
| 126 | + .push( |
| 127 | + Text::new(&self.desc) |
| 128 | + .font(theme.font()) |
| 129 | + .size(13) |
| 130 | + .color(theme.text_color(0.55)), |
| 131 | + ); |
| 132 | + |
| 133 | + let mut row = Row::new() |
| 134 | + .align_y(Alignment::Center) |
145 | 135 | .width(Fill) |
146 | | - .height(55), |
147 | | - ); |
| 136 | + .spacing(0) |
| 137 | + .height(50); |
148 | 138 |
|
149 | | - tile = tile |
150 | | - .push( |
151 | | - container( |
152 | | - Text::new(&self.desc) |
153 | | - .font(theme.font()) |
154 | | - .color(theme.text_color(0.4)), |
155 | | - ) |
156 | | - .padding(12), |
157 | | - ) |
158 | | - .width(Fill); |
| 139 | + if theme.show_icons |
| 140 | + && let Some(icon) = &self.icons |
| 141 | + { |
| 142 | + row = row.push( |
| 143 | + container(Viewer::new(icon).height(40).width(40)) |
| 144 | + .width(40) |
| 145 | + .height(40), |
| 146 | + ); |
| 147 | + } |
| 148 | + row = row.push(container(text_block).width(Fill)); |
159 | 149 |
|
160 | | - let (highlight_opacity, border_width) = if focussed_id == id_num { |
161 | | - (0.7, 0.55) |
162 | | - } else { |
163 | | - (0.5, 0.1) |
| 150 | + let msg = match self.open_command.clone() { |
| 151 | + AppCommand::Function(func) => Some(Message::RunFunction(func)), |
| 152 | + AppCommand::Message(msg) => Some(msg), |
| 153 | + AppCommand::Display => None, |
164 | 154 | }; |
165 | 155 |
|
166 | | - container(tile) |
| 156 | + let content = Button::new(row) |
| 157 | + .on_press_maybe(msg) |
| 158 | + .style(|_, _| result_button_style(theme)) |
| 159 | + .width(Fill) |
| 160 | + .padding(0) |
| 161 | + .height(50); |
| 162 | + |
| 163 | + container(content) |
167 | 164 | .id(format!("result-{}", id_num)) |
168 | | - .style(move |_| iced::widget::container::Style { |
169 | | - text_color: Some(theme.text_color(1.)), |
170 | | - background: Some(Background::Color(theme.bg_color())), |
171 | | - border: iced::Border { |
172 | | - color: theme.text_color(highlight_opacity), |
173 | | - width: border_width, |
174 | | - radius: Radius::new(0), |
175 | | - }, |
176 | | - ..Default::default() |
177 | | - }) |
178 | | - .max_height(55) |
179 | | - .padding(5) |
| 165 | + .style(move |_| result_row_container_style(theme, focused)) |
| 166 | + .padding(8) |
180 | 167 | .width(Fill) |
181 | | - .height(Fill) |
| 168 | + } |
| 169 | +} |
| 170 | + |
| 171 | +fn result_button_style(theme: &Theme) -> button::Style { |
| 172 | + let mut s = button::Style::default(); |
| 173 | + s.text_color = theme.text_color(1.0); |
| 174 | + s.background = None; |
| 175 | + s |
| 176 | +} |
| 177 | + |
| 178 | +fn result_row_container_style(tile: &Theme, focused: bool) -> container::Style { |
| 179 | + let base = tile.bg_color(); |
| 180 | + let row_bg = if focused { |
| 181 | + with_alpha(tint(base, 0.10), 1.0) |
| 182 | + } else { |
| 183 | + with_alpha(tint(base, 0.04), 1.0) |
| 184 | + }; |
| 185 | + |
| 186 | + container::Style { |
| 187 | + background: Some(Background::Color(row_bg)), |
| 188 | + border: Border { |
| 189 | + color: if focused { |
| 190 | + tile.text_color(0.35) |
| 191 | + } else { |
| 192 | + tile.text_color(0.10) |
| 193 | + }, |
| 194 | + width: if focused { 1.1 } else { 0.8 }, |
| 195 | + radius: Radius::new(10.0), |
| 196 | + }, |
| 197 | + ..Default::default() |
182 | 198 | } |
183 | 199 | } |
0 commit comments