gitkraft_gui/features/theme/
view.rs1use iced::widget::pick_list;
7use iced::{Element, Length};
8
9use crate::message::Message;
10
11#[derive(Debug, Clone, PartialEq, Eq)]
13pub struct ThemeChoice {
14 pub index: usize,
15 pub name: &'static str,
16}
17
18impl std::fmt::Display for ThemeChoice {
19 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
20 f.write_str(self.name)
21 }
22}
23
24pub(crate) fn all_themes() -> Vec<ThemeChoice> {
27 gitkraft_core::THEME_NAMES
28 .iter()
29 .enumerate()
30 .map(|(i, name)| ThemeChoice { index: i, name })
31 .collect()
32}
33
34pub(crate) fn theme_choices() -> Vec<ThemeChoice> {
36 let mut v = vec![ThemeChoice {
37 index: gitkraft_core::THEME_COUNT,
38 name: gitkraft_core::SYSTEM_THEME_NAME,
39 }];
40 v.extend(all_themes());
41 v
42}
43
44pub(crate) fn theme_selector(
49 current_theme_index: usize,
50 follow_system: bool,
51 width: f32,
52) -> Element<'static, Message> {
53 let choices = theme_choices();
54 let selected = if follow_system {
55 choices.first().cloned()
56 } else {
57 choices.get(current_theme_index + 1).cloned()
59 };
60
61 pick_list(choices, selected, |choice| {
62 Message::ThemeChanged(choice.index)
63 })
64 .placeholder("Select theme")
65 .text_size(13.0)
66 .width(Length::Fixed(width))
67 .into()
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 #[test]
75 fn choices_lead_with_system() {
76 let c = theme_choices();
77 assert_eq!(c.len(), gitkraft_core::THEME_COUNT + 1);
78 assert_eq!(c[0].index, gitkraft_core::THEME_COUNT);
79 assert_eq!(c[0].name, "System");
80 assert_eq!(c[1].index, 0);
81 }
82
83 #[test]
84 fn all_themes_match_core() {
85 let t = all_themes();
86 assert_eq!(t.len(), gitkraft_core::THEME_COUNT);
87 assert!(t.iter().enumerate().all(|(i, c)| c.index == i));
88 }
89}