From f2b14d18ebdab7a5ad5266e980e4aed0c0b9b5ca Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Fri, 15 Sep 2023 18:00:11 +0200 Subject: [PATCH] chore(examples): migrated cosmic-design-demo --- .gitmodules | 3 + Cargo.toml | 1 + examples/design-demo | 1 + examples/design-demo/Cargo.toml | 19 - examples/design-demo/justfile | 26 -- .../com.system76.CosmicDesignDemo.desktop | 10 - examples/design-demo/src/buttons.rs | 352 ----------------- examples/design-demo/src/cards.rs | 52 --- examples/design-demo/src/debug.rs | 138 ------- examples/design-demo/src/inputs.rs | 193 ---------- examples/design-demo/src/main.rs | 356 ------------------ examples/design-demo/src/typography.rs | 106 ------ 12 files changed, 5 insertions(+), 1252 deletions(-) create mode 160000 examples/design-demo delete mode 100644 examples/design-demo/Cargo.toml delete mode 100755 examples/design-demo/justfile delete mode 100644 examples/design-demo/resources/com.system76.CosmicDesignDemo.desktop delete mode 100644 examples/design-demo/src/buttons.rs delete mode 100644 examples/design-demo/src/cards.rs delete mode 100644 examples/design-demo/src/debug.rs delete mode 100644 examples/design-demo/src/inputs.rs delete mode 100644 examples/design-demo/src/main.rs delete mode 100644 examples/design-demo/src/typography.rs diff --git a/.gitmodules b/.gitmodules index 367f7f22..2338d056 100644 --- a/.gitmodules +++ b/.gitmodules @@ -2,3 +2,6 @@ path = iced url = https://github.com/pop-os/iced.git branch = master +[submodule "examples/design-demo"] + path = examples/design-demo + url = https://github.com/pop-os/cosmic-design-demo diff --git a/Cargo.toml b/Cargo.toml index ef31ba41..1260b800 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -117,6 +117,7 @@ members = [ "examples/*", ] exclude = [ + "examples/design-demo", "iced", ] diff --git a/examples/design-demo b/examples/design-demo new file mode 160000 index 00000000..ed4af4e6 --- /dev/null +++ b/examples/design-demo @@ -0,0 +1 @@ +Subproject commit ed4af4e6431e30702f6de8031f3a3a11b82da3f0 diff --git a/examples/design-demo/Cargo.toml b/examples/design-demo/Cargo.toml deleted file mode 100644 index 1abe6331..00000000 --- a/examples/design-demo/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "cosmic-design-demo" -version = "0.1.0" -edition = "2021" - -[dependencies] -fraction = "0.13.1" -tracing = "0.1.37" -tracing-subscriber = "0.3.17" - -[dependencies.libcosmic] -path = "../../" -default-features = false -features = ["debug", "winit", "tokio"] - -[dependencies.cosmic-time] -git = "https://github.com/pop-os/cosmic-time" -default-features = false -features = ["libcosmic", "once_cell"] diff --git a/examples/design-demo/justfile b/examples/design-demo/justfile deleted file mode 100755 index 6d8a9e25..00000000 --- a/examples/design-demo/justfile +++ /dev/null @@ -1,26 +0,0 @@ -!include ../../just/rust.just -!include ../../just/packaging.just - -rootdir := '' -prefix := '/usr' - -# Name of the application's binary -bin-name := 'cosmic-design-demo' - -# The AppID of the application -app-id := 'com.system76.CosmicDesignDemo' - -# Application binary executable source and install destination -bin-src := 'target' / 'release' / bin-name -bin-dst := clean(rootdir / prefix) / 'bin' / bin-name - -# Desktop file source and install destination -desktop-file := app-id + '.desktop' -desktop-src := 'examples' / 'design-demo' / 'resources' / desktop-file -desktop-dst := clean(rootdir / prefix) / 'share' / 'applications' / desktop-file - -# Recipe for compiling the application -build *args: - cargo build -p cosmic-design-demo {{args}} - -install: (install-bin bin-src bin-dst) (install-file desktop-src desktop-dst) \ No newline at end of file diff --git a/examples/design-demo/resources/com.system76.CosmicDesignDemo.desktop b/examples/design-demo/resources/com.system76.CosmicDesignDemo.desktop deleted file mode 100644 index fb19890c..00000000 --- a/examples/design-demo/resources/com.system76.CosmicDesignDemo.desktop +++ /dev/null @@ -1,10 +0,0 @@ -[Desktop Entry] -Name=COSMIC Design System Demo -Type=Application -Exec=cosmic-design-demo -Terminal=true -Categories=COSMIC; -Keywords=COSMIC;Design;Demo; -Icon=preferences-pop-desktop-appearance -StartupNotify=true -NoDisplay=false \ No newline at end of file diff --git a/examples/design-demo/src/buttons.rs b/examples/design-demo/src/buttons.rs deleted file mode 100644 index 3fe2e6f0..00000000 --- a/examples/design-demo/src/buttons.rs +++ /dev/null @@ -1,352 +0,0 @@ -// Copyright 2023 System76 -// SPDX-License-Identifier: MPL-2.0 - -use super::{App, Message}; -use cosmic::iced_core::Alignment; -use cosmic::widget::{button, column, icon, row, text}; -use cosmic::Element; - -impl App -where - Self: cosmic::Application, -{ - pub fn view_buttons(&self) -> Element { - column() - .spacing(24) - .push(text::title1("Text Buttons")) - // Suggested button header - .push( - column() - .spacing(8) - .push(text::title3("Suggested Button")) - .push(text("Highest level of attention, there should only be one primary button used on the page.").size(14.0)) - ) - // Suggested button demo - .push( - row() - .spacing(36) - .push(button::suggested("Label").on_press(Message::Clicked)) - .push(button::suggested("Label").on_press(Message::Clicked).leading_icon(self.leading_icon.clone())) - .push(button::suggested("Label").on_press(Message::Clicked).trailing_icon(self.trailing_icon.clone())) - .push(button::suggested("Label").on_press(Message::Clicked).leading_icon(self.app_icon.clone())) - .push( - button::suggested("Label") - .on_press(Message::Clicked) - .leading_icon(self.app_icon.clone()) - .trailing_icon(self.trailing_icon.clone()) - ) - .push( - button::suggested("Disabled") - .leading_icon(self.app_icon.clone()) - .trailing_icon(self.trailing_icon.clone()) - ) - ) - // Destructive button header - .push( - column() - .spacing(8) - .push(text::title3("Destructive Button")) - .push(text("Highest level of attention, there should only be one primary button used on the page.").size(14.0)) - ) - // Destructive button demo - .push( - row() - .spacing(36) - .push(button::destructive("Label").on_press(Message::Clicked)) - .push(button::destructive("Label").on_press(Message::Clicked).leading_icon(self.leading_icon.clone())) - .push(button::destructive("Label").on_press(Message::Clicked).trailing_icon(self.trailing_icon.clone())) - .push(button::destructive("Label").on_press(Message::Clicked).leading_icon(self.app_icon.clone())) - .push( - button::destructive("Label") - .on_press(Message::Clicked) - .leading_icon(self.app_icon.clone()) - .trailing_icon(self.trailing_icon.clone()) - ) - .push( - button::destructive("Disabled") - .leading_icon(self.app_icon.clone()) - .trailing_icon(self.trailing_icon.clone()) - ) - ) - // Standard button header - .push( - column() - .spacing(8) - .push(text::title3("Standard Button")) - .push( - text( - "Requires less attention from the user. Could be more \ - than one button on the page, if necessary." - ) - .size(14.0) - ) - ) - // Standard button demo - .push( - row() - .spacing(36) - .push(button::standard("Label").on_press(Message::Clicked)) - .push(button::standard("Label").on_press(Message::Clicked).leading_icon(self.leading_icon.clone())) - .push(button::standard("Label").on_press(Message::Clicked).trailing_icon(self.trailing_icon.clone())) - .push(button::standard("Label").on_press(Message::Clicked).leading_icon(self.app_icon.clone())) - .push( - button::standard("Label") - .on_press(Message::Clicked) - .leading_icon(self.app_icon.clone()) - .trailing_icon(self.trailing_icon.clone()) - ) - .push( - button::standard("Disabled") - .leading_icon(self.app_icon.clone()) - .trailing_icon(self.trailing_icon.clone()) - ) - ) - // Text button header - .push( - column() - .spacing(8) - .push(text::title3("Text Button")) - .push(text( - "Lowest priority actions, especially when presenting multiple options. Because text buttons \ - don’t have a visible container in their default state, they don’t distract from nearby \ - content. But they are also more difficult to recognize because of that." - ).size(14.0)) - ) - // Text button demo - .push( - row() - .spacing(36) - .push(button::text("Label").on_press(Message::Clicked)) - .push(button::text("Label").on_press(Message::Clicked).leading_icon(self.leading_icon.clone())) - .push(button::text("Label").on_press(Message::Clicked).trailing_icon(self.trailing_icon.clone())) - .push(button::text("Label").on_press(Message::Clicked).leading_icon(self.app_icon.clone())) - .push( - button::text("Label") - .on_press(Message::Clicked) - .leading_icon(self.app_icon.clone()) - .trailing_icon(self.trailing_icon.clone()) - ) - .push( - button::text("Disabled") - .leading_icon(self.app_icon.clone()) - .trailing_icon(self.trailing_icon.clone()) - ) - ) - // Icon buttons - .push(text::title1("Icon Buttons")) - .push(view_icon_buttons(self.bt_icon.clone())) - .push(text::title1("App Icon Buttons")) - .push(view_icon_buttons(self.app_icon.clone())) - .push(text::title1("Hyperlinks")) - .push(text::body("All the buttons have Default, Hover, Pressed, and Disabled states. Buttons in any of the states can have a Focused indicator signifying the button is ready to interact.")) - .push( - row() - .spacing(36) - .push(button::link("Hyperlink").on_press(Message::Clicked)) - .push(button::link("Hyperlink").trailing_icon(true).on_press(Message::Clicked)) - .push(button::link("Hyperlink")) - .push(button::link("Hyperlink").trailing_icon(true)) - ) - .into() - } -} - -fn view_icon_buttons(icon: icon::Handle) -> impl Into> { - row() - .spacing(36) - // Without Labels - .push( - column() - .spacing(24) - .align_items(Alignment::Center) - .push( - button::icon(icon.clone()) - .extra_small() - .on_press(Message::Clicked) - .tooltip("Extra small icon button"), - ) - .push( - button::icon(icon.clone()) - .on_press(Message::Clicked) - .tooltip("Small icon button"), - ) - .push( - button::icon(icon.clone()) - .medium() - .on_press(Message::Clicked) - .tooltip("Medium icon button"), - ) - .push( - button::icon(icon.clone()) - .large() - .on_press(Message::Clicked) - .tooltip("Large icon button"), - ) - .push( - button::icon(icon.clone()) - .extra_large() - .on_press(Message::Clicked) - .tooltip("Extra large icon button"), - ), - ) - // With Labels - .push( - column() - .spacing(24) - .align_items(Alignment::Center) - .push( - button::icon(icon.clone()) - .extra_small() - .on_press(Message::Clicked) - .tooltip("Extra small icon button") - .label("Label"), - ) - .push( - button::icon(icon.clone()) - .on_press(Message::Clicked) - .tooltip("Small icon button") - .label("Label"), - ) - .push( - button::icon(icon.clone()) - .medium() - .on_press(Message::Clicked) - .tooltip("Medium icon button") - .label("Label"), - ) - .push( - button::icon(icon.clone()) - .large() - .on_press(Message::Clicked) - .tooltip("Large icon button") - .label("Label"), - ) - .push( - button::icon(icon.clone()) - .extra_large() - .on_press(Message::Clicked) - .tooltip("Extra large icon button") - .label("Label"), - ), - ) - // Disabled - .push( - column() - .spacing(24) - .align_items(Alignment::Center) - .push( - button::icon(icon.clone()) - .extra_small() - .tooltip("Extra small icon button") - .label("Label"), - ) - .push( - button::icon(icon.clone()) - .tooltip("Small icon button") - .label("Label"), - ) - .push( - button::icon(icon.clone()) - .medium() - .tooltip("Medium icon button") - .label("Label"), - ) - .push( - button::icon(icon.clone()) - .large() - .tooltip("Large icon button") - .label("Label"), - ) - .push( - button::icon(icon.clone()) - .extra_large() - .tooltip("Extra large icon button") - .label("Label"), - ), - ) - // Vertical layout - .push( - column() - .spacing(24) - .align_items(Alignment::Center) - .push( - button::icon(icon.clone()) - .extra_small() - .on_press(Message::Clicked) - .tooltip("Extra small icon button") - .label("Label") - .vertical(true), - ) - .push( - button::icon(icon.clone()) - .on_press(Message::Clicked) - .tooltip("Small icon button") - .label("Label") - .vertical(true), - ) - .push( - button::icon(icon.clone()) - .medium() - .on_press(Message::Clicked) - .tooltip("Medium icon button") - .label("Label") - .vertical(true), - ) - .push( - button::icon(icon.clone()) - .large() - .on_press(Message::Clicked) - .tooltip("Large icon button") - .label("Label") - .vertical(true), - ) - .push( - button::icon(icon.clone()) - .extra_large() - .on_press(Message::Clicked) - .tooltip("Extra large icon button") - .label("Label") - .vertical(true), - ), - ) - // Vertical disabled - .push( - column() - .spacing(24) - .align_items(Alignment::Center) - .push( - button::icon(icon.clone()) - .extra_small() - .tooltip("Extra small icon button") - .label("Label") - .vertical(true), - ) - .push( - button::icon(icon.clone()) - .tooltip("Small icon button") - .label("Label") - .vertical(true), - ) - .push( - button::icon(icon.clone()) - .medium() - .tooltip("Medium icon button") - .label("Label") - .vertical(true), - ) - .push( - button::icon(icon.clone()) - .large() - .tooltip("Large icon button") - .label("Label") - .vertical(true), - ) - .push( - button::icon(icon) - .extra_large() - .tooltip("Extra large icon button") - .label("Label") - .vertical(true), - ), - ) -} diff --git a/examples/design-demo/src/cards.rs b/examples/design-demo/src/cards.rs deleted file mode 100644 index e10e31b6..00000000 --- a/examples/design-demo/src/cards.rs +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright 2023 System76 -// SPDX-License-Identifier: MPL-2.0 - -use super::{App, Message}; -use cosmic::iced_core::Length; -use cosmic::widget::{container, cosmic_container, text}; -use cosmic::Element; -use cosmic_time::{anim, chain, id, once_cell::sync::Lazy}; - -static CARDS: Lazy = Lazy::new(id::Cards::unique); - -impl App -where - Self: cosmic::Application, -{ - pub fn update_cards(&mut self) { - let timeline = &mut self.timeline; - let chain = if self.cards_value { - chain::Cards::on(CARDS.clone(), 1.) - } else { - chain::Cards::off(CARDS.clone(), 1.) - }; - timeline.set_chain(chain); - timeline.start(); - } - - pub fn view_cards(&self) -> Element { - container( - cosmic_container::container(anim!( - CARDS, - &self.timeline, - vec![ - text("Card 1").size(24).width(Length::Fill).into(), - text("Card 2").size(24).width(Length::Fill).into(), - text("Card 3").size(24).width(Length::Fill).into(), - text("Card 4").size(24).width(Length::Fill).into(), - ], - Message::Ignore, - |_, e| Message::CardsToggled(e), - "Show More", - "Show Less", - "Clear All", - None, - self.cards_value, - )) - .layer(cosmic::cosmic_theme::Layer::Secondary) - .padding(16) - .style(cosmic::theme::Container::Secondary), - ) - .into() - } -} diff --git a/examples/design-demo/src/debug.rs b/examples/design-demo/src/debug.rs deleted file mode 100644 index a1f6eaea..00000000 --- a/examples/design-demo/src/debug.rs +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright 2023 System76 -// SPDX-License-Identifier: MPL-2.0 - -use super::{App, Message}; -use cosmic::iced::Length; -use cosmic::prelude::*; -use cosmic::theme::ThemeType; -use cosmic::widget::{ - column, container, divider, list, pick_list, radio, row, settings, spin_button, text, -}; -use cosmic::Element; -use cosmic_time::{anim, id, once_cell::sync::Lazy}; - -pub static DEBUG_TOGGLER: Lazy = Lazy::new(id::Toggler::unique); - -#[derive(Clone, Copy, Debug, PartialEq, PartialOrd, Ord, Eq)] -pub enum ThemeVariant { - Custom, - Dark, - HighContrastDark, - HighContrastLight, - Light, - System, -} - -impl ThemeVariant { - const fn as_str(self) -> &'static str { - match self { - Self::Custom => "Custom", - Self::Dark => "Dark", - Self::HighContrastDark => "HighContrastDark", - Self::HighContrastLight => "HighContrastLight", - Self::Light => "Light", - Self::System => "System", - } - } -} - -impl From<&ThemeType> for ThemeVariant { - fn from(theme: &ThemeType) -> Self { - match theme { - ThemeType::Light => ThemeVariant::Light, - ThemeType::Dark => ThemeVariant::Dark, - ThemeType::HighContrastDark => ThemeVariant::HighContrastDark, - ThemeType::HighContrastLight => ThemeVariant::HighContrastLight, - ThemeType::Custom(_) => ThemeVariant::Custom, - ThemeType::System(_) => ThemeVariant::System, - } - } -} - -impl From for ThemeVariant { - fn from(theme: ThemeType) -> Self { - ThemeVariant::from(&theme) - } -} - -const THEME_CHOICES: &[ThemeVariant] = &[ - ThemeVariant::Light, - ThemeVariant::Dark, - ThemeVariant::System, - ThemeVariant::HighContrastLight, - ThemeVariant::HighContrastDark, - ThemeVariant::Custom, -]; - -impl App -where - Self: cosmic::Application, -{ - pub fn view_debug(&self) -> Element { - let mut theme_choices = THEME_CHOICES.iter().cloned().map(|theme| { - radio( - theme.as_str(), - theme, - if ThemeVariant::from(cosmic::theme::active_type()) == theme { - Some(theme) - } else { - None - }, - Message::ThemeChanged, - ) - .width(200) - }); - - column() - .spacing(24) - .push( - column() - .spacing(8) - .push(text::heading("Change Theme")) - .push(list::container( - column() - .spacing(12) - .padding([0, 18]) - .push(row().extend(theme_choices.by_ref().take(3))) - .push(row().extend(theme_choices)) - .apply(container) - .center_x() - .width(Length::Fill), - )), - ) - .push( - column() - .spacing(8) - .push(text::heading("Debug Options")) - .push(list::container( - column() - .spacing(12) - .push( - container(anim!( - DEBUG_TOGGLER, - &self.timeline, - String::from("Debug layout"), - self.core.debug, - |_chain, enable| { Message::DebugToggled(enable) }, - )) - .padding([0, 18]), - ) - .push(divider::horizontal::light()) - .push(settings::item( - "Scaling Factor", - spin_button(&self.scale_factor_str, Message::ScalingFactorChanged), - )) - .push(divider::horizontal::light()) - .push(settings::item( - "Layer", - pick_list( - &["Default", "Primary", "Secondary"][..], - Some(self.layer_selection), - Message::LayerSelect, - ), - )), - )), - ) - .into() - } -} diff --git a/examples/design-demo/src/inputs.rs b/examples/design-demo/src/inputs.rs deleted file mode 100644 index 27d684ce..00000000 --- a/examples/design-demo/src/inputs.rs +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright 2023 System76 -// SPDX-License-Identifier: MPL-2.0 - -use super::{App, Message}; -use cosmic::iced_core::{Alignment, Length}; -use cosmic::widget::{ - checkbox, column, container, inline_input, pick_list, progress_bar, row, search_input, - secure_input, segmented_selection, slider, text, text_input, view_switcher, -}; -use cosmic::{Apply, Element}; - -static PLACEHOLDER_TEXT: &str = "placeholder text"; - -impl App -where - Self: cosmic::Application, -{ - pub fn view_text_input(&self) -> Element { - column() - .spacing(24) - .push(text::title1("Checkbox")) - .push( - checkbox( - "Checkbox", - self.checkbox_value, - Message::CheckboxToggled, - ) - ) - .push(text::title1("Pick List")) - .push( - pick_list( - &self.pick_list_options, - self.pick_list_selected, - Message::PickListSelected, - ) - ) - .push(text::title1("Progress Bar")) - .push( - progress_bar(0.0..=100.0, self.slider_value) - .width(Length::Fixed(250.0)) - .height(Length::Fixed(4.0)), - ) - .push(text::title1("Segmented Buttons")) - .push(text::title2("Segmented Selection")) - .push( - row() - .spacing(12) - .push(text::body("Horizontal")) - .push( - segmented_selection::horizontal(&self.selection) - .on_activate(Message::Selection), - ) - ) - .push( - row() - .spacing(12) - .align_items(Alignment::Center) - .push(text::body("Vertical")) - .push( - segmented_selection::vertical(&self.selection) - .on_activate(Message::Selection), - ) - ) - - .push(text::title2("View Switcher")) - .push( - row() - .spacing(12) - .push(text::body("Horizontal")) - .push( - view_switcher::horizontal(&self.selection) - .on_activate(Message::Selection), - ) - ) - .push( - row() - .spacing(12) - .align_items(Alignment::Center) - .push(text::body("Vertical")) - .push( - view_switcher::vertical(&self.selection) - .on_activate(Message::Selection), - ) - ) - .push(text::title1("Slider")) - .push( - slider(0.0..=100.0, self.slider_value, Message::SliderChanged) - .width(Length::Fixed(250.0)) - .height(38) - ) - .push(text::title1("Spin Button")) - .push(text::title1("Text Inputs")) - .push(text::body("Collection of different text input variants.")) - .push(text::title2("Text Input")) - .push(text::body("The standard text input widget.")) - .push( - row() - .align_items(Alignment::Center) - .push(text::body("Enabled")) - .spacing(12) - .push( - text_input(PLACEHOLDER_TEXT, &self.text_input_value) - .width(Length::Fill) - .on_input(Message::TextInputChanged) - ) - .push(text::body("Disabled")) - .push( - text_input(PLACEHOLDER_TEXT, &self.text_input_value) - .width(Length::Fill) - ) - ) - .push(text::title2("Search Input")) - .push(text::body("Search inputs should be used where search functionality is desired. They differ from the standard text input by displaying a search icon and a clickable search clear button")) - .push( - row() - .align_items(Alignment::Center) - .push(text::body("Enabled")) - .spacing(12) - .push( - search_input( - PLACEHOLDER_TEXT, - &self.text_input_value, - Some(Message::TextInputChanged("".to_string())), - ) - .width(Length::Fill) - .on_input(Message::TextInputChanged) - ) - .push(text::body("Disabled")) - .push( - search_input( - "", - &self.text_input_value, - Some(Message::TextInputChanged("".to_string())), - ) - .width(Length::Fill) - ) - ) - .push(text::title2("Secure Input")) - .push( - row() - .align_items(Alignment::Center) - .push(text::body("Enabled")) - .spacing(12) - .push( - secure_input( - PLACEHOLDER_TEXT, - &self.text_input_value, - Some(Message::SecureInputToggled), - !self.secure_input_visible, - ) - .label("Test Secure Input Label") - .helper_text("Helper Text") - .width(Length::Fill) - .on_input(Message::TextInputChanged) - ) - .push(text::body("Disabled")) - .push( - secure_input( - "", - &self.text_input_value, - Some(Message::SecureInputToggled), - !self.secure_input_visible, - ) - .label("Test Secure Input Label") - .helper_text("Helper Text") - .width(Length::Fill) - ) - - ) - .push(text::title2("Inline Input")) - .push(text::body("Inline Text Input should be used only inside other widgets, like ListItem or in situations when the input is a quick and transient action (for example, to quickly enter a value in some sort of editing program). ")) - .push( - row() - .align_items(Alignment::Center) - .push(text::body("Enabled")) - .spacing(12) - .push( - inline_input(&self.text_input_value) - .width(Length::Fill) - .on_input(Message::TextInputChanged) - ) - .push(text::body("Disabled")) - .push( - inline_input(&self.text_input_value) - .width(Length::Fill) - ) - ) - .push(text::title1("Toggle")) - .apply(container) - .max_width(800) - .into() - } -} diff --git a/examples/design-demo/src/main.rs b/examples/design-demo/src/main.rs deleted file mode 100644 index 76022755..00000000 --- a/examples/design-demo/src/main.rs +++ /dev/null @@ -1,356 +0,0 @@ -// Copyright 2023 System76 -// SPDX-License-Identifier: MPL-2.0 - -mod buttons; -mod cards; -mod debug; -mod inputs; -mod typography; - -use cosmic::app::{Command, Core, Settings}; -use cosmic::cosmic_theme::palette::{rgb::Rgb, Srgba}; -use cosmic::cosmic_theme::ThemeBuilder; -use cosmic::iced::Length; -use cosmic::widget::{ - button, column, container, icon, nav_bar, scrollable, segmented_button, spin_button, -}; -use cosmic::{executor, ApplicationExt, Apply, Element, Theme}; -use cosmic_time::Timeline; -use debug::ThemeVariant; -use fraction::{Decimal, ToPrimitive}; -use std::sync::Arc; - -#[derive(Clone, Copy)] -pub enum Page { - Buttons, - Cards, - Inputs, - Typography, -} - -impl Page { - const fn as_str(self) -> &'static str { - match self { - Page::Buttons => "Buttons", - Page::Cards => "Cards", - Page::Inputs => "Inputs", - Page::Typography => "Typography", - } - } -} - -/// Runs application with these settings -#[rustfmt::skip] -fn main() -> Result<(), Box> { - let settings = Settings::default() - .antialiasing(true) - .client_decorations(true) - .debug(false) - .size((1280, 768)) - .theme(cosmic::Theme::dark()); - - cosmic::app::run::(settings, ())?; - - Ok(()) -} - -/// Messages that are used specifically by our [`App`]. -#[derive(Clone, Debug)] -pub enum Message { - CardsToggled(bool), - CheckboxToggled(bool), - Clicked, - DebugToggled(bool), - Ignore, - LayerSelect(&'static str), - PickListSelected(&'static str), - ScalingFactorChanged(spin_button::Message), - SecureInputToggled, - Selection(segmented_button::Entity), - SliderChanged(f32), - TextInputChanged(String), - ThemeChanged(ThemeVariant), - Tick(cosmic_time::Instant), - TogglerToggled(bool), -} - -/// The [`App`] stores application-specific state. -pub struct App { - core: Core, - nav_model: nav_bar::Model, - layer_selection: &'static str, - - // cosmic-time dependency - timeline: Timeline, - - // Buttons page - app_icon: icon::Handle, - bt_icon: icon::Handle, - leading_icon: icon::Handle, - trailing_icon: icon::Handle, - - // Cards page - cards_value: bool, - - // Debug page - scale_factor: spin_button::Model, - scale_factor_str: String, - - // Inputs page - checkbox_value: bool, - pick_list_selected: Option<&'static str>, - pick_list_options: Vec<&'static str>, - text_input_value: String, - secure_input_visible: bool, - selection: segmented_button::SingleSelectModel, - slider_value: f32, -} - -/// Implement [`cosmic::Application`] to integrate with COSMIC. -impl cosmic::Application for App { - /// Default async executor to use with the app. - type Executor = executor::Default; - - /// Argument received [`cosmic::Application::new`]. - type Flags = (); - - /// Message type specific to our [`App`]. - type Message = Message; - - /// The unique application ID to supply to the window manager. - const APP_ID: &'static str = "com.system76.CosmicDesignDemo"; - - fn core(&self) -> &Core { - &self.core - } - - fn core_mut(&mut self) -> &mut Core { - &mut self.core - } - - /// Creates the application, and optionally emits command on initialize. - fn init(core: Core, _input: Self::Flags) -> (Self, Command) { - let nav_model = nav_bar::Model::builder() - .insert(|e| e.text(Page::Typography.as_str()).data(Page::Typography)) - .insert(|e| { - e.text(Page::Buttons.as_str()) - .data(Page::Buttons) - .activate() - }) - .insert(|e| e.text(Page::Cards.as_str()).data(Page::Cards)) - .insert(|e| e.text(Page::Inputs.as_str()).data(Page::Inputs)) - .build(); - - let mut app = App { - nav_model, - layer_selection: "Default", - - // cosmic-time dependency - timeline: Timeline::default(), - - // Buttons page - app_icon: icon::from_name("firefox").into(), - bt_icon: icon::from_name("bluetooth-active-symbolic").size(16).into(), - leading_icon: icon::from_name("document-save-symbolic").size(16).into(), - trailing_icon: button::link::icon(), - - // Cards page - cards_value: false, - - // Debug page - scale_factor: spin_button::Model::default() - .value(core.scale_factor()) - .min(0.5) - .max(4.0) - .step(0.25), - scale_factor_str: core.scale_factor().to_string(), - - // Inputs page - checkbox_value: false, - pick_list_selected: Some("Option 1"), - pick_list_options: vec!["Option 1", "Option 2", "Option 3", "Option 4"], - text_input_value: String::new(), - secure_input_visible: false, - selection: segmented_button::Model::builder() - .insert(|b| b.text("Choice A").activate()) - .insert(|b| b.text("Choice B")) - .insert(|b| b.text("Choice C")) - .build(), - slider_value: 0.0, - - core, - }; - - let command = app.update_title(); - - (app, command) - } - - /// Allows COSMIC to integrate with your application's [`nav_bar::Model`]. - fn nav_model(&self) -> Option<&nav_bar::Model> { - Some(&self.nav_model) - } - - /// Called when a navigation item is selected. - fn on_nav_select(&mut self, id: nav_bar::Id) -> Command { - self.nav_model.activate(id); - self.update_title() - } - - /// Handle application events here. - fn update(&mut self, message: Self::Message) -> Command { - match message { - Message::Tick(now) => self.timeline.now(now), - - Message::TextInputChanged(input) => { - self.text_input_value = input; - } - - Message::Clicked => { - eprintln!("button clicked"); - } - - Message::CardsToggled(value) => { - self.cards_value = value; - self.update_cards(); - } - - Message::DebugToggled(value) => { - self.core.debug = value; - self.update_togglers(); - } - - Message::LayerSelect(selection) => { - self.layer_selection = selection; - } - - Message::SecureInputToggled => { - self.secure_input_visible = !self.secure_input_visible; - } - - Message::Selection(key) => self.selection.activate(key), - - Message::CheckboxToggled(value) => { - self.checkbox_value = value; - } - - Message::SliderChanged(value) => { - self.slider_value = value; - } - - Message::TogglerToggled(value) => { - eprintln!("card toggler: {value}"); - } - - Message::PickListSelected(value) => self.pick_list_selected = Some(value), - - Message::ThemeChanged(theme) => { - return cosmic::app::command::set_theme(match theme { - ThemeVariant::Light => Theme::light(), - ThemeVariant::Dark => Theme::dark(), - ThemeVariant::HighContrastDark => Theme::dark_hc(), - ThemeVariant::HighContrastLight => Theme::light_hc(), - ThemeVariant::Custom => Theme::custom(Arc::new( - ThemeBuilder::light() - .bg_color(Srgba::new(1.0, 0.9, 0.9, 1.0)) - .text_tint(Rgb::new(0.0, 1.0, 0.0)) - .neutral_tint(Rgb::new(0.0, 0.5, 1.0)) - .accent(Rgb::new(0.5, 0.1, 0.5)) - .success(Rgb::new(0.0, 0.5, 0.3)) - .warning(Rgb::new(0.894, 0.816, 0.039)) - .destructive(Rgb::new(0.890, 0.145, 0.420)) - .build(), - )), - ThemeVariant::System => cosmic::theme::system_preference(), - }); - } - - Message::ScalingFactorChanged(message) => { - self.scale_factor.update(message); - if let Some(factor) = self.scale_factor.value.to_f32() { - self.scale_factor_str = factor.to_string(); - return cosmic::app::command::set_scaling_factor(factor); - } - } - - Message::Ignore => (), - } - - Command::none() - } - - /// Creates a view after each update. - fn view(&self) -> Element { - // Generate a view for the active page. - let page_view = match self.nav_model.active_data::() { - Some(Page::Buttons) => self.view_buttons(), - Some(Page::Cards) => self.view_cards(), - Some(Page::Inputs) => self.view_text_input(), - Some(Page::Typography) => self.view_typography(), - None => cosmic::widget::text("Unknown page selected").into(), - }; - - column() - .spacing(24) - // Place debug view atop each page - .push(self.view_debug()) - // Insert page view beneath it - .push( - container(page_view) - .width(Length::Fill) - .style(match self.layer_selection { - "Primary" => cosmic::theme::Container::Primary, - "Secondary" => cosmic::theme::Container::Secondary, - _ => cosmic::theme::Container::default(), - }), - ) - // Wrap page views in container that expands up to 1000 px wide. - .apply(container) - .width(Length::Fill) - .max_width(1000) - // Wrap again to center-align the expanded container. - .apply(container) - .center_x() - .width(Length::Fill) - // Make it scrollable if height exceeds window. - .apply(scrollable) - .into() - } - - fn subscription(&self) -> cosmic::iced::Subscription { - cosmic::iced::Subscription::batch(vec![self - .timeline - .as_subscription() - .map(|(_, instant)| Message::Tick(instant))]) - } -} - -impl App -where - Self: cosmic::Application, -{ - fn active_page_title(&mut self) -> &str { - self.nav_model - .text(self.nav_model.active()) - .unwrap_or("Unknown Page") - } - - fn update_title(&mut self) -> Command { - let title = self.active_page_title().to_owned(); - let window_title = format!("{title} - COSMIC Design System"); - self.core.window.header_title = title.clone(); - self.set_title(window_title) - } - - fn update_togglers(&mut self) { - let chain = if self.core.debug { - cosmic_time::chain::Toggler::on(debug::DEBUG_TOGGLER.clone(), 1.) - } else { - cosmic_time::chain::Toggler::off(debug::DEBUG_TOGGLER.clone(), 1.) - }; - - self.timeline.set_chain(chain); - - self.timeline.start(); - } -} diff --git a/examples/design-demo/src/typography.rs b/examples/design-demo/src/typography.rs deleted file mode 100644 index 7135134f..00000000 --- a/examples/design-demo/src/typography.rs +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2023 System76 -// SPDX-License-Identifier: MPL-2.0 - -use super::{App, Message}; -use cosmic::widget::{column, divider, row, text}; -use cosmic::Element; - -impl App -where - Self: cosmic::Application, -{ - pub fn view_typography(&self) -> Element { - // TODO: Implement with grid widget once grid widget is finished. - const WIDTH: u16 = 128; - static SAMPLE_TEXT: &str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit."; - - column() - .spacing(32) - .push( - column() - .spacing(4) - .push( - row() - .push(text::heading("Text Style").width(WIDTH)) - .push(text::heading("Font Size").width(WIDTH)) - .push(text::heading("Line Height").width(WIDTH)) - .push(text::heading("Weight").width(WIDTH)) - .push(text::heading("Two-line Example").width(463)), - ) - .push(divider::horizontal::default()), - ) - .push( - row() - .push(text::title1("Title 1").width(WIDTH)) - .push(text::title1("32px").width(WIDTH)) - .push(text::title1("44px").width(WIDTH)) - .push(text::title1("Light (300)").width(WIDTH)) - .push(text::title1(SAMPLE_TEXT).width(463)), - ) - .push( - row() - .push(text::title2("Title 2").width(WIDTH)) - .push(text::title2("28px").width(WIDTH)) - .push(text::title2("36px").width(WIDTH)) - .push(text::title2("Regular (400)").width(WIDTH)) - .push(text::title2(SAMPLE_TEXT).width(376)), - ) - .push( - row() - .push(text::title3("Title 3").width(WIDTH)) - .push(text::title3("24px").width(WIDTH)) - .push(text::title3("32px").width(WIDTH)) - .push(text::title3("Regular (400)").width(WIDTH)) - .push(text::title3(SAMPLE_TEXT).width(376)), - ) - .push( - row() - .push(text::title4("Title 4").width(WIDTH)) - .push(text::title4("20px").width(WIDTH)) - .push(text::title4("28px").width(WIDTH)) - .push(text::title4("Regular (400)").width(WIDTH)) - .push(text::title4(SAMPLE_TEXT).width(335)), - ) - .push( - row() - .push(text::heading("Heading").width(WIDTH)) - .push(text::heading("14px").width(WIDTH)) - .push(text::heading("20px").width(WIDTH)) - .push(text::heading("Semibold (600)").width(WIDTH)) - .push(text::heading(SAMPLE_TEXT).width(234)), - ) - .push( - row() - .push(text::caption_heading("Caption Heading").width(WIDTH)) - .push(text::caption_heading("10px").width(WIDTH)) - .push(text::caption_heading("14px").width(WIDTH)) - .push(text::caption_heading("Semibold (600)").width(WIDTH)) - .push(text::caption_heading(SAMPLE_TEXT).width(164)), - ) - .push( - row() - .push(text::body("Body").width(WIDTH)) - .push(text::body("14px").width(WIDTH)) - .push(text::body("20px").width(WIDTH)) - .push(text::body("Regular (400)").width(WIDTH)) - .push(text::body(SAMPLE_TEXT).width(234)), - ) - .push( - row() - .push(text::caption("Caption").width(WIDTH)) - .push(text::caption("10px").width(WIDTH)) - .push(text::caption("14px").width(WIDTH)) - .push(text::caption("Regular (400)").width(WIDTH)) - .push(text::caption(SAMPLE_TEXT).width(164)), - ) - .push( - row() - .push(text::monotext("Monotext").width(WIDTH)) - .push(text::monotext("14px").width(WIDTH)) - .push(text::monotext("20px").width(WIDTH)) - .push(text::monotext("Regular (400)").width(WIDTH)) - .push(text::monotext(SAMPLE_TEXT).width(280)), - ) - .into() - } -}