audio_processor_iced_design_system/
tabs.rs1use std::fmt::Debug;
24
25use iced::{
26 widget::button, widget::Button, widget::Column, widget::Container, widget::Row, widget::Text,
27 Background, Color, Element, Length,
28};
29
30use crate::spacing::Spacing;
31use crate::style;
32
33#[derive(Clone, Debug)]
34pub enum Message<InnerMessage> {
35 SetTab(usize),
36 Inner(InnerMessage),
37}
38
39#[derive(Default)]
40pub struct State {
41 selected_tab: usize,
42}
43
44impl State {
45 pub fn new() -> Self {
46 State { selected_tab: 0 }
47 }
48
49 pub fn update<InnerMessage: Clone + Debug>(&mut self, message: Message<InnerMessage>) {
50 if let Message::SetTab(index) = message {
51 self.selected_tab = index;
52 }
53 }
54
55 pub fn view<'a, InnerMessage: 'static + Clone + Debug>(
56 &'a self,
57 mut items: Vec<Tab<'a, InnerMessage>>,
58 ) -> Element<Message<InnerMessage>> {
59 let selected_tab = self.selected_tab;
60 let heading = Row::with_children(
61 items
62 .iter()
63 .enumerate()
64 .map(|(index, tab)| {
65 Button::new(Text::new(tab.title.clone()).size(Spacing::small_font_size()))
66 .style(
67 style::button::Button::default()
68 .set_active(button::Appearance {
69 background: if index == selected_tab {
70 Some(Background::Color(Color::BLACK))
71 } else {
72 None
73 },
74 border_width: 0.0,
75 ..style::button::button_base_style()
76 })
77 .into(),
78 )
79 .on_press(Message::SetTab(index))
80 .into()
81 })
82 .collect(),
83 );
84
85 let tab = items.swap_remove(self.selected_tab);
86 let element = tab.content.map(Message::Inner);
87
88 Container::new(Column::with_children(vec![
89 heading.into(),
90 iced::widget::rule::Rule::horizontal(1)
91 .style(style::Rule)
92 .into(),
93 element,
94 ]))
95 .style(style::Container0::default())
96 .width(Length::Fill)
97 .height(Length::Fill)
98 .into()
99 }
100}
101
102pub struct Tab<'a, InnerMessage> {
103 title: String,
104 content: Element<'a, InnerMessage>,
105}
106
107impl<'a, InnerMessage> Tab<'a, InnerMessage> {
108 pub fn new(title: impl Into<String>, content: impl Into<Element<'a, InnerMessage>>) -> Self {
109 Tab {
110 title: title.into(),
111 content: content.into(),
112 }
113 }
114}