gitkraft_gui/widgets/
tab_bar.rs1use iced::widget::{button, container, row, scrollable, text, Space};
5use iced::{Alignment, Element, Length};
6
7use crate::icons;
8use crate::message::Message;
9use crate::state::GitKraft;
10use crate::theme;
11use crate::theme::ThemeColors;
12
13pub fn view(state: &GitKraft) -> Element<'_, Message> {
15 let c = state.colors();
16
17 let mut tabs_row = row![].spacing(0).align_y(Alignment::Center);
18
19 for (idx, tab) in state.tabs.iter().enumerate() {
20 let is_active = idx == state.active_tab;
21 let name = tab.display_name().to_string();
22
23 let icon = if tab.has_repo() {
25 icon!(
26 icons::FOLDER_OPEN,
27 12,
28 if is_active { c.accent } else { c.muted }
29 )
30 } else {
31 icon!(
32 icons::PERSON_FILL,
33 12,
34 if is_active { c.accent } else { c.muted }
35 )
36 };
37
38 let label = text(name).size(12).color(if is_active {
40 c.text_primary
41 } else {
42 c.text_secondary
43 });
44
45 let close_btn: Element<'_, Message> = if state.tabs.len() > 1 {
47 button(icon!(icons::X_CIRCLE, 10, c.muted))
48 .padding([0, 4])
49 .style(theme::ghost_button)
50 .on_press(Message::CloseTab(idx))
51 .into()
52 } else {
53 Space::with_width(0).into()
54 };
55
56 let tab_content = row![
57 icon,
58 Space::with_width(6),
59 label,
60 Space::with_width(4),
61 close_btn
62 ]
63 .align_y(Alignment::Center);
64
65 let tab_btn = button(tab_content)
66 .padding([6, 12])
67 .style(if is_active {
68 theme::active_tab_button
69 } else {
70 theme::ghost_button
71 })
72 .on_press(Message::SwitchTab(idx));
73
74 tabs_row = tabs_row.push(tab_btn);
75 }
76
77 let new_tab_btn = button(icon!(icons::PLUS_CIRCLE, 14, c.text_secondary))
79 .padding([6, 10])
80 .style(theme::ghost_button)
81 .on_press(Message::NewTab);
82
83 tabs_row = tabs_row.push(new_tab_btn);
84
85 let scrollable_tabs = scrollable(tabs_row)
86 .direction(scrollable::Direction::Horizontal(
87 scrollable::Scrollbar::new(),
88 ))
89 .style(crate::theme::overlay_scrollbar)
90 .width(Length::Fill);
91
92 container(scrollable_tabs)
93 .width(Length::Fill)
94 .style(tab_bar_style)
95 .into()
96}
97
98fn tab_bar_style(theme: &iced::Theme) -> container::Style {
100 let c = ThemeColors::from_theme(theme);
101 container::Style {
102 background: Some(iced::Background::Color(iced::Color {
103 r: (c.bg.r - 0.02).max(0.0),
104 g: (c.bg.g - 0.02).max(0.0),
105 b: (c.bg.b - 0.02).max(0.0),
106 a: 1.0,
107 })),
108 border: iced::Border {
109 color: c.border,
110 width: 0.0,
111 radius: 0.0.into(),
112 },
113 ..Default::default()
114 }
115}