Add iced cosmic example
This commit is contained in:
parent
167b92f084
commit
699e474427
19 changed files with 532 additions and 121 deletions
318
examples/cosmic/src/main.rs
Normal file
318
examples/cosmic/src/main.rs
Normal file
|
|
@ -0,0 +1,318 @@
|
|||
use iced::widget::{
|
||||
button, checkbox, column, container, horizontal_rule, horizontal_space, progress_bar, radio,
|
||||
row, slider, svg, text, toggler,
|
||||
vertical_space,
|
||||
};
|
||||
use iced::{theme, Alignment, Background, Color, Element, Font, Length, Sandbox, Settings, Theme};
|
||||
|
||||
const FONT: Font = Font::External {
|
||||
name: "Fira Sans Regular",
|
||||
bytes: include_bytes!("../res/Fira/Sans/Regular.otf"),
|
||||
};
|
||||
|
||||
const FONT_LIGHT: Font = Font::External {
|
||||
name: "Fira Sans Light",
|
||||
bytes: include_bytes!("../res/Fira/Sans/Light.otf"),
|
||||
};
|
||||
|
||||
const FONT_SEMIBOLD: Font = Font::External {
|
||||
name: "Fira Sans SemiBold",
|
||||
bytes: include_bytes!("../res/Fira/Sans/SemiBold.otf"),
|
||||
};
|
||||
|
||||
pub fn main() -> iced::Result {
|
||||
let mut settings = Settings::default();
|
||||
settings.default_font = match FONT {
|
||||
Font::Default => None,
|
||||
Font::External { bytes, .. } => Some(bytes),
|
||||
};
|
||||
settings.default_text_size = 18;
|
||||
Window::run(settings)
|
||||
}
|
||||
|
||||
fn icon(name: &str, size: u16) -> svg::Svg {
|
||||
let handle = match freedesktop_icons::lookup(name)
|
||||
.with_size(size)
|
||||
.with_theme("Pop")
|
||||
.with_cache()
|
||||
.force_svg()
|
||||
.find()
|
||||
{
|
||||
Some(path) => svg::Handle::from_path(path),
|
||||
None => {
|
||||
eprintln!("icon '{}' size {} not found", name, size);
|
||||
svg::Handle::from_memory(Vec::new())
|
||||
},
|
||||
};
|
||||
svg::Svg::new(handle)
|
||||
}
|
||||
|
||||
fn sidebar_style(theme: &Theme) -> container::Appearance {
|
||||
container::Appearance {
|
||||
text_color: None,
|
||||
background: Some(Background::Color(
|
||||
match theme {
|
||||
Theme::Dark => Color::from_rgb8(0x29, 0x29, 0x29),
|
||||
Theme::Light => Color::from_rgb8(0xfd, 0xfd, 0xfd),
|
||||
}
|
||||
)),
|
||||
border_radius: 8.0,
|
||||
border_width: 0.0,
|
||||
border_color: Color::TRANSPARENT,
|
||||
}
|
||||
}
|
||||
|
||||
fn listview_style(theme: &Theme) -> container::Appearance {
|
||||
container::Appearance {
|
||||
text_color: None,
|
||||
background: Some(Background::Color(
|
||||
match theme {
|
||||
Theme::Dark => Color::from_rgb8(0x27, 0x27, 0x27),
|
||||
Theme::Light => Color::from_rgb8(0xf7, 0xf7, 0xf7),
|
||||
}
|
||||
)),
|
||||
border_radius: 8.0,
|
||||
border_width: 0.0,
|
||||
border_color: Color::TRANSPARENT,
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct Window {
|
||||
page: u8,
|
||||
debug: bool,
|
||||
theme: Theme,
|
||||
slider_value: f32,
|
||||
checkbox_value: bool,
|
||||
toggler_value: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum Message {
|
||||
Page(u8),
|
||||
Debug(bool),
|
||||
ThemeChanged(Theme),
|
||||
ButtonPressed,
|
||||
SliderChanged(f32),
|
||||
CheckboxToggled(bool),
|
||||
TogglerToggled(bool),
|
||||
}
|
||||
|
||||
impl Sandbox for Window {
|
||||
type Message = Message;
|
||||
|
||||
fn new() -> Self {
|
||||
let mut window = Window::default();
|
||||
window.slider_value = 50.0;
|
||||
window
|
||||
}
|
||||
|
||||
fn title(&self) -> String {
|
||||
String::from("COSMIC Design System - Iced")
|
||||
}
|
||||
|
||||
fn update(&mut self, message: Message) {
|
||||
match message {
|
||||
Message::Page(page) => self.page = page,
|
||||
Message::Debug(debug) => self.debug = debug,
|
||||
Message::ThemeChanged(theme) => self.theme = theme,
|
||||
Message::ButtonPressed => {}
|
||||
Message::SliderChanged(value) => self.slider_value = value,
|
||||
Message::CheckboxToggled(value) => self.checkbox_value = value,
|
||||
Message::TogglerToggled(value) => self.toggler_value = value,
|
||||
}
|
||||
}
|
||||
|
||||
fn view(&self) -> Element<Message> {
|
||||
let sidebar: Element<_> = container(
|
||||
column![
|
||||
//TODO: Support symbolic icons
|
||||
button(
|
||||
row![
|
||||
icon("network-wireless", 16).width(Length::Units(16)),
|
||||
text("Wi-Fi"),
|
||||
horizontal_space(Length::Fill),
|
||||
]
|
||||
.padding([4, 12])
|
||||
.spacing(8)
|
||||
)
|
||||
.on_press(Message::Page(0))
|
||||
.style(if self.page == 0 { theme::Button::Primary } else { theme::Button::Text })
|
||||
,
|
||||
button(
|
||||
row![
|
||||
icon("preferences-desktop", 16).width(Length::Units(16)),
|
||||
text("Desktop"),
|
||||
horizontal_space(Length::Fill),
|
||||
]
|
||||
.padding([4, 12])
|
||||
.spacing(8)
|
||||
)
|
||||
.on_press(Message::Page(1))
|
||||
.style(if self.page == 1 { theme::Button::Primary } else { theme::Button::Text })
|
||||
,
|
||||
button(
|
||||
row![
|
||||
icon("system-software-update", 16).width(Length::Units(16)),
|
||||
text("OS Upgrade & Recovery"),
|
||||
horizontal_space(Length::Fill),
|
||||
]
|
||||
.padding([4, 12])
|
||||
.spacing(8)
|
||||
)
|
||||
.on_press(Message::Page(2))
|
||||
.style(if self.page == 2 { theme::Button::Primary } else { theme::Button::Text })
|
||||
,
|
||||
vertical_space(Length::Fill),
|
||||
]
|
||||
.spacing(12)
|
||||
.padding(12)
|
||||
.max_width(300)
|
||||
)
|
||||
.style(theme::Container::Custom(sidebar_style))
|
||||
.into();
|
||||
|
||||
let choose_theme = [Theme::Light, Theme::Dark].iter().fold(
|
||||
row![text("Theme:")].spacing(10).align_items(Alignment::Center),
|
||||
|row, theme| {
|
||||
row.push(radio(
|
||||
format!("{:?}", theme),
|
||||
*theme,
|
||||
Some(self.theme),
|
||||
Message::ThemeChanged,
|
||||
))
|
||||
},
|
||||
);
|
||||
|
||||
let content: Element<_> = column![
|
||||
choose_theme,
|
||||
vertical_space(Length::Units(16)),
|
||||
toggler(
|
||||
String::from("Debug layout"),
|
||||
self.debug,
|
||||
Message::Debug,
|
||||
)
|
||||
.width(Length::Shrink)
|
||||
.size(24)
|
||||
.spacing(12)
|
||||
,
|
||||
vertical_space(Length::Units(16)),
|
||||
text("Buttons").font(FONT_SEMIBOLD),
|
||||
container(
|
||||
column![
|
||||
row![
|
||||
button("Primary")
|
||||
.style(theme::Button::Primary)
|
||||
.padding([8, 16])
|
||||
.on_press(Message::ButtonPressed)
|
||||
,
|
||||
button("Secondary")
|
||||
.style(theme::Button::Secondary)
|
||||
.padding([8, 16])
|
||||
.on_press(Message::ButtonPressed)
|
||||
,
|
||||
button("Positive")
|
||||
.style(theme::Button::Positive)
|
||||
.padding([8, 16])
|
||||
.on_press(Message::ButtonPressed)
|
||||
,
|
||||
button("Destructive")
|
||||
.style(theme::Button::Destructive)
|
||||
.padding([8, 16])
|
||||
.on_press(Message::ButtonPressed)
|
||||
,
|
||||
button("Text")
|
||||
.style(theme::Button::Text)
|
||||
.padding([8, 16])
|
||||
.on_press(Message::ButtonPressed)
|
||||
,
|
||||
].spacing(12),
|
||||
horizontal_rule(12),
|
||||
row![
|
||||
button("Primary")
|
||||
.style(theme::Button::Primary)
|
||||
.padding([8, 16])
|
||||
,
|
||||
button("Secondary")
|
||||
.style(theme::Button::Secondary)
|
||||
.padding([8, 16])
|
||||
,
|
||||
button("Positive")
|
||||
.style(theme::Button::Positive)
|
||||
.padding([8, 16])
|
||||
,
|
||||
button("Destructive")
|
||||
.style(theme::Button::Destructive)
|
||||
.padding([8, 16])
|
||||
,
|
||||
button("Text")
|
||||
.style(theme::Button::Text)
|
||||
.padding([8, 16])
|
||||
,
|
||||
].spacing(12),
|
||||
]
|
||||
.padding([12, 16])
|
||||
.spacing(12)
|
||||
)
|
||||
.style(theme::Container::Custom(listview_style))
|
||||
,
|
||||
vertical_space(Length::Units(16)),
|
||||
text("Controls").font(FONT_SEMIBOLD),
|
||||
container(
|
||||
column![
|
||||
row![
|
||||
text("Toggler"),
|
||||
horizontal_space(Length::Fill),
|
||||
toggler(None, self.toggler_value, Message::TogglerToggled)
|
||||
.size(24)
|
||||
.width(Length::Shrink),
|
||||
]
|
||||
.padding([0, 8])
|
||||
,
|
||||
horizontal_rule(12),
|
||||
row![
|
||||
text("Slider"),
|
||||
horizontal_space(Length::Fill),
|
||||
slider(0.0..=100.0, self.slider_value, Message::SliderChanged)
|
||||
.width(Length::Units(250)),
|
||||
]
|
||||
.padding([0, 8])
|
||||
,
|
||||
horizontal_rule(12),
|
||||
row![
|
||||
text("Progress"),
|
||||
horizontal_space(Length::Fill),
|
||||
progress_bar(0.0..=100.0, self.slider_value).height(Length::Units(4))
|
||||
.width(Length::Units(250)),
|
||||
]
|
||||
.padding([0, 8])
|
||||
,
|
||||
horizontal_rule(12),
|
||||
checkbox("Checkbox", self.checkbox_value, Message::CheckboxToggled),
|
||||
]
|
||||
.padding([12, 16])
|
||||
.spacing(12)
|
||||
)
|
||||
.style(theme::Container::Custom(listview_style))
|
||||
]
|
||||
.spacing(8)
|
||||
.padding(24)
|
||||
.max_width(600)
|
||||
.into();
|
||||
|
||||
container(row![
|
||||
if self.debug { sidebar.explain(Color::WHITE) } else { sidebar },
|
||||
horizontal_space(Length::Fill),
|
||||
if self.debug { content.explain(Color::WHITE) } else { content },
|
||||
horizontal_space(Length::Fill),
|
||||
])
|
||||
.padding([16, 8])
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
.into()
|
||||
}
|
||||
|
||||
fn theme(&self) -> Theme {
|
||||
self.theme
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue