diff --git a/examples/cosmic/src/main.rs b/examples/cosmic/src/main.rs index 3849d646..5c123954 100644 --- a/examples/cosmic/src/main.rs +++ b/examples/cosmic/src/main.rs @@ -8,11 +8,13 @@ use cosmic::{ nav_bar, nav_button, toggler, + HeaderBar, }, settings, - iced::{theme, Alignment, Color, Element, Length, Sandbox, Theme}, + iced::{self, theme, Alignment, Application, Color, Command, Element, Length, Theme}, iced::widget::{ checkbox, + column, container, horizontal_space, pick_list, @@ -24,17 +26,22 @@ use cosmic::{ scrollable, }, iced_lazy::responsive, + iced_winit::window::drag, + WindowMsg }; pub fn main() -> cosmic::iced::Result { let mut settings = settings(); settings.window.min_size = Some((600, 300)); + // TODO: Window resize handles not functioning yet + // settings.window.decorations = false; Window::run(settings) } #[derive(Default)] struct Window { + headerbar: HeaderBar, page: u8, debug: bool, theme: Theme, @@ -42,6 +49,7 @@ struct Window { checkbox_value: bool, toggler_value: bool, pick_list_selected: Option<&'static str>, + exit: bool, } #[derive(Clone, Copy, Debug)] @@ -54,23 +62,38 @@ enum Message { CheckboxToggled(bool), TogglerToggled(bool), PickListSelected(&'static str), + Window(WindowMsg) } -impl Sandbox for Window { - type Message = Message; +impl From for Message { + fn from(message: WindowMsg) -> Self { + Self::Window(message) + } +} - fn new() -> Self { +impl Application for Window { + type Executor = iced::executor::Default; + type Flags = (); + type Message = Message; + type Theme = Theme; + + fn new(_flags: ()) -> (Self, Command) { let mut window = Window::default(); + window.headerbar.title = String::from("COSMIC Design System - Iced"); + window.headerbar.nav_title = String::from("WiFi Settings"); + window.headerbar.sidebar_active = true; + window.headerbar.show_minimize = true; + window.headerbar.show_maximize = true; window.slider_value = 50.0; window.pick_list_selected = Some("Option 1"); - window + (window, Command::none()) } fn title(&self) -> String { - String::from("COSMIC Design System - Iced") + self.headerbar.title.clone() } - fn update(&mut self, message: Message) { + fn update(&mut self, message: Message) -> iced::Command { match message { Message::Page(page) => self.page = page, Message::Debug(debug) => self.debug = debug, @@ -80,35 +103,54 @@ impl Sandbox for Window { Message::CheckboxToggled(value) => self.checkbox_value = value, Message::TogglerToggled(value) => self.toggler_value = value, Message::PickListSelected(value) => self.pick_list_selected = Some(value), + Message::Window(msg) => match msg { + WindowMsg::Close => self.exit = true, + WindowMsg::ToggleSidebar => self.headerbar.sidebar_active = !self.headerbar.sidebar_active, + WindowMsg::Drag => return drag(), + WindowMsg::Minimize => {} + WindowMsg::Maximize => {} + } } + + iced::Command::none() } fn view(&self) -> Element { + let mut header = self.headerbar.render(); + if self.debug { + header = header.explain(Color::WHITE); + } + // TODO: Adding responsive makes this regenerate on every size change, and regeneration // involves allocations for many different items. Ideally, we could only make the nav bar // responsive and leave the content to be sized normally. - responsive(|size| { + let content = responsive(|size| { let condensed = size.width < 900.0; - let sidebar: Element<_> = nav_bar!( - //TODO: Support symbolic icons - nav_button!("network-wireless", "Wi-Fi", condensed) - .on_press(Message::Page(0)) - .style(if self.page == 0 { theme::Button::Primary } else { theme::Button::Text }) - , - nav_button!("preferences-desktop", "Desktop", condensed) - .on_press(Message::Page(1)) - .style(if self.page == 1 { theme::Button::Primary } else { theme::Button::Text }) - , - nav_button!("system-software-update", "OS Upgrade & Recovery", condensed) - .on_press(Message::Page(2)) - .style(if self.page == 2 { theme::Button::Primary } else { theme::Button::Text }) - ) - .max_width(if condensed { - 56 + + let sidebar: Option> = if self.headerbar.sidebar_active { + Some(nav_bar!( + //TODO: Support symbolic icons + nav_button!("network-wireless", "Wi-Fi", condensed) + .on_press(Message::Page(0)) + .style(if self.page == 0 { theme::Button::Primary } else { theme::Button::Text }) + , + nav_button!("preferences-desktop", "Desktop", condensed) + .on_press(Message::Page(1)) + .style(if self.page == 1 { theme::Button::Primary } else { theme::Button::Text }) + , + nav_button!("system-software-update", "OS Upgrade & Recovery", condensed) + .on_press(Message::Page(2)) + .style(if self.page == 2 { theme::Button::Primary } else { theme::Button::Text }) + ) + .max_width(if condensed { + 56 + } else { + 300 + }) + .into()) } else { - 300 - }) - .into(); + None + }; let choose_theme = [Theme::Light, Theme::Dark].iter().fold( row![text("Debug theme:")].spacing(10).align_items(Alignment::Center), @@ -210,8 +252,13 @@ impl Sandbox for Window { ) .into(); - container(row![ - if self.debug { sidebar.explain(Color::WHITE) } else { sidebar }, + let mut widgets = Vec::with_capacity(2); + + if let Some(sidebar) = sidebar { + widgets.push(if self.debug { sidebar.explain(Color::WHITE) } else { sidebar }); + } + + widgets.push( scrollable(row![ horizontal_space(Length::Fill), if self.debug { content.explain(Color::WHITE) } else { content }, @@ -219,12 +266,21 @@ impl Sandbox for Window { ]) .scrollbar_width(12) .scroller_width(6) - ]) + .into() + ); + + container(row(widgets)) .padding([16, 8]) .width(Length::Fill) .height(Length::Fill) .into() - }).into() + }).into(); + + column(vec![header, content]).into() + } + + fn should_exit(&self) -> bool { + self.exit } fn theme(&self) -> Theme {