Make example runnable as example

Trying to run examples as usual (and as described in the README) fails:

    > cargo run --release --example cosmic
    error: no example target named `cosmic`.

The examples themselves are written as separate crates, and are
therefore not usable as examples (they also won't build via `cargo build
--examples`).

This commit makes the example fit the style that cargo can understand.
That is:

- Don't declare the example as a separate crate.
- Remove the nested `src` inside the example directory.
- Put example-only dependencies in dev-dependencies

No rust code was modified, files were only moved.
This commit is contained in:
Hugo Osvaldo Barrera 2023-03-12 11:24:49 +01:00
parent e3ec7e3b7d
commit 6ce9f4fc7a
12 changed files with 3 additions and 14 deletions

View file

@ -0,0 +1,43 @@
use super::{Page, Window};
use cosmic::{
iced::widget::{column, text},
widget::{list_column, settings, toggler},
Element,
};
#[derive(Clone, Copy, Debug)]
pub enum Message {
Enable(bool),
}
#[derive(Default)]
pub struct State {
enabled: bool,
}
impl State {
pub(super) fn update(&mut self, message: Message) {
match message {
Message::Enable(value) => self.enabled = value,
}
}
pub(super) fn view<'a>(&'a self, window: &'a Window) -> Element<'a, Message> {
settings::view_column(vec![
window.page_title(Page::Bluetooth),
column!(
list_column().add(settings::item(
"Bluetooth",
toggler(None, self.enabled, Message::Enable)
)),
text("Now visible as \"TODO\", just kidding")
)
.spacing(8)
.into(),
settings::view_section("Devices")
.add(settings::item("No devices found", text("")))
.into(),
])
.into()
}
}

View file

@ -0,0 +1,414 @@
use apply::Apply;
use cosmic::{
cosmic_theme,
iced::widget::{checkbox, pick_list, progress_bar, radio, row, slider, text, text_input},
iced::{Alignment, Length},
theme::{self, Button as ButtonTheme, Theme},
widget::{
button, container, icon, segmented_button, segmented_selection, settings, spin_button,
toggler, view_switcher,
},
Element,
};
use fraction::{Decimal, ToPrimitive};
use once_cell::sync::Lazy;
use super::{Page, Window};
pub enum DemoView {
TabA,
TabB,
TabC,
}
#[allow(dead_code)]
pub enum MultiOption {
OptionA,
OptionB,
OptionC,
OptionD,
OptionE,
}
static INPUT_ID: Lazy<text_input::Id> = Lazy::new(text_input::Id::unique);
#[derive(Clone, Debug)]
pub enum Message {
ButtonPressed,
CheckboxToggled(bool),
Debug(bool),
IconTheme(segmented_button::Entity),
MultiSelection(segmented_button::Entity),
PickListSelected(&'static str),
RowSelected(usize),
ScalingFactor(spin_button::Message),
Selection(segmented_button::Entity),
SliderChanged(f32),
SpinButton(spin_button::Message),
ThemeChanged(Theme),
ToggleWarning,
TogglerToggled(bool),
ViewSwitcher(segmented_button::Entity),
InputChanged(String),
}
pub enum Output {
Debug(bool),
ScalingFactor(f32),
ThemeChanged(Theme),
ToggleWarning,
}
pub struct State {
pub checkbox_value: bool,
pub icon_themes: segmented_button::SingleSelectModel,
pub multi_selection: segmented_button::MultiSelectModel,
pub pick_list_selected: Option<&'static str>,
pub pick_list_options: Vec<&'static str>,
pub scaling_value: spin_button::Model<Decimal>,
pub selection: segmented_button::SingleSelectModel,
pub slider_value: f32,
pub spin_button: spin_button::Model<i32>,
pub toggler_value: bool,
pub view_switcher: segmented_button::SingleSelectModel,
pub entry_value: String,
}
impl Default for State {
fn default() -> State {
State {
checkbox_value: false,
pick_list_selected: Some("Option 1"),
pick_list_options: vec!["Option 1", "Option 2", "Option 3", "Option 4"],
scaling_value: spin_button::Model::default()
.value(1.0)
.min(0.5)
.max(2.0)
.step(0.25),
slider_value: 50.0,
spin_button: spin_button::Model::default().min(-10).max(10),
toggler_value: false,
icon_themes: segmented_button::Model::builder()
.insert(|b| b.text("Pop").activate())
.insert(|b| b.text("Adwaita"))
.build(),
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(),
multi_selection: segmented_button::Model::builder()
.insert(|b| b.text("Option A").data(MultiOption::OptionA).activate())
.insert(|b| b.text("Option B").data(MultiOption::OptionB))
.insert(|b| b.text("Option C").data(MultiOption::OptionC))
.insert(|b| b.text("Option D").data(MultiOption::OptionD))
.insert(|b| b.text("Option E").data(MultiOption::OptionE))
.build(),
view_switcher: segmented_button::Model::builder()
.insert(|b| b.text("Controls").data(DemoView::TabA).activate())
.insert(|b| b.text("Segmented Button").data(DemoView::TabB))
.insert(|b| b.text("Tab C").data(DemoView::TabC))
.build(),
entry_value: String::new(),
}
}
}
impl State {
pub(super) fn update(&mut self, message: Message) -> Option<Output> {
match message {
Message::ButtonPressed => (),
Message::CheckboxToggled(value) => self.checkbox_value = value,
Message::Debug(value) => return Some(Output::Debug(value)),
Message::PickListSelected(value) => self.pick_list_selected = Some(value),
Message::RowSelected(row) => println!("Selected row {row}"),
Message::MultiSelection(key) => self.multi_selection.activate(key),
Message::ScalingFactor(message) => {
self.scaling_value.update(message);
if let Some(factor) = self.scaling_value.value.to_f32() {
return Some(Output::ScalingFactor(factor));
}
}
Message::Selection(key) => self.selection.activate(key),
Message::SliderChanged(value) => self.slider_value = value,
Message::SpinButton(msg) => self.spin_button.update(msg),
Message::ThemeChanged(theme) => return Some(Output::ThemeChanged(theme)),
Message::ToggleWarning => return Some(Output::ToggleWarning),
Message::TogglerToggled(value) => self.toggler_value = value,
Message::ViewSwitcher(key) => self.view_switcher.activate(key),
Message::IconTheme(key) => {
self.icon_themes.activate(key);
if let Some(theme) = self.icon_themes.text(key) {
cosmic::settings::set_default_icon_theme(theme);
}
}
Message::InputChanged(s) => {
self.entry_value = s;
}
}
None
}
pub(super) fn view<'a>(&'a self, window: &'a Window) -> Element<'a, Message> {
let choose_theme = [
Theme::light(),
Theme::dark(),
Theme::light_hc(),
Theme::dark_hc(),
]
.iter()
.fold(
row![].spacing(10).align_items(Alignment::Center),
|row, theme| {
row.push(radio(
format!("{:?}", theme.theme_type),
*theme,
if window.theme == *theme {
Some(*theme)
} else {
None
},
Message::ThemeChanged,
))
},
);
let choose_icon_theme =
segmented_selection::horizontal(&self.icon_themes).on_activate(Message::IconTheme);
settings::view_column(vec![
window.page_title(Page::Demo),
view_switcher::horizontal(&self.view_switcher)
.on_activate(Message::ViewSwitcher)
.into(),
match self.view_switcher.active_data() {
None => panic!("no tab is active"),
Some(DemoView::TabA) => settings::view_column(vec![
settings::view_section("Debug")
.add(settings::item("Debug theme", choose_theme))
.add(settings::item("Debug icon theme", choose_icon_theme))
.add(settings::item(
"Debug layout",
toggler(None, window.debug, Message::Debug),
))
.add(settings::item(
"Scaling Factor",
spin_button(&window.scale_factor_string, Message::ScalingFactor),
))
.add(settings::item_row(vec![button(ButtonTheme::Destructive)
.on_press(Message::ToggleWarning)
.custom(vec![
icon("dialog-warning-symbolic", 16)
.style(theme::Svg::SymbolicPrimary)
.into(),
text("Do Not Touch").into(),
])
.into()]))
.into(),
settings::view_section("Buttons")
.add(settings::item_row(vec![
button(ButtonTheme::Primary)
.text("Primary")
.on_press(Message::ButtonPressed)
.into(),
button(ButtonTheme::Secondary)
.text("Secondary")
.on_press(Message::ButtonPressed)
.into(),
button(ButtonTheme::Positive)
.text("Positive")
.on_press(Message::ButtonPressed)
.into(),
button(ButtonTheme::Destructive)
.text("Destructive")
.on_press(Message::ButtonPressed)
.into(),
button(ButtonTheme::Text)
.text("Text")
.on_press(Message::ButtonPressed)
.into(),
]))
.add(settings::item_row(vec![
button(ButtonTheme::Primary).text("Primary").into(),
button(ButtonTheme::Secondary).text("Secondary").into(),
button(ButtonTheme::Positive).text("Positive").into(),
button(ButtonTheme::Destructive).text("Destructive").into(),
button(ButtonTheme::Text).text("Text").into(),
]))
.into(),
settings::view_section("Controls")
.add(settings::item(
"Toggler",
toggler(None, self.toggler_value, Message::TogglerToggled),
))
.add(settings::item(
"Pick List (TODO)",
pick_list(
&self.pick_list_options,
self.pick_list_selected,
Message::PickListSelected,
)
.padding([8, 0, 8, 16]),
))
.add(settings::item(
"Slider",
slider(0.0..=100.0, self.slider_value, Message::SliderChanged)
.width(Length::Units(250)),
))
.add(settings::item(
"Progress",
progress_bar(0.0..=100.0, self.slider_value)
.width(Length::Units(250))
.height(Length::Units(4)),
))
.add(settings::item_row(vec![checkbox(
"Checkbox",
self.checkbox_value,
Message::CheckboxToggled,
)
.into()]))
.add(settings::item(
format!(
"Spin Button (Range {}:{})",
self.spin_button.min, self.spin_button.max
),
spin_button(format!("{}", self.spin_button.value), Message::SpinButton),
))
.into(),
])
.padding(0)
.into(),
Some(DemoView::TabB) => settings::view_column(vec![
text("Selection").font(cosmic::font::FONT_SEMIBOLD).into(),
text("Horizontal").into(),
segmented_selection::horizontal(&self.selection)
.on_activate(Message::Selection)
.into(),
text("Horizontal With Spacing").into(),
segmented_selection::horizontal(&self.selection)
.spacing(8)
.on_activate(Message::Selection)
.into(),
text("Horizontal Multi-Select").into(),
segmented_selection::horizontal(&self.multi_selection)
.spacing(8)
.on_activate(Message::MultiSelection)
.into(),
text("Vertical").into(),
segmented_selection::vertical(&self.selection)
.on_activate(Message::Selection)
.into(),
text("Vertical Multi-Select Shrunk").into(),
segmented_selection::vertical(&self.multi_selection)
.width(Length::Shrink)
.on_activate(Message::MultiSelection)
.apply(container)
.center_x()
.width(Length::Fill)
.into(),
text("Vertical With Spacing").into(),
cosmic::iced::widget::row(vec![
segmented_selection::vertical(&self.selection)
.spacing(8)
.on_activate(Message::Selection)
.width(Length::FillPortion(1))
.into(),
segmented_selection::vertical(&self.selection)
.spacing(8)
.on_activate(Message::Selection)
.width(Length::FillPortion(1))
.into(),
segmented_selection::vertical(&self.selection)
.spacing(8)
.on_activate(Message::Selection)
.width(Length::FillPortion(1))
.into(),
])
.spacing(12)
.width(Length::Fill)
.into(),
text("View Switcher")
.font(cosmic::font::FONT_SEMIBOLD)
.into(),
text("Horizontal").into(),
view_switcher::horizontal(&self.selection)
.on_activate(Message::Selection)
.into(),
text("Horizontal Multi-Select").into(),
view_switcher::horizontal(&self.multi_selection)
.on_activate(Message::MultiSelection)
.into(),
text("Horizontal With Spacing").into(),
view_switcher::horizontal(&self.selection)
.spacing(8)
.on_activate(Message::Selection)
.into(),
text("Vertical").into(),
view_switcher::vertical(&self.selection)
.on_activate(Message::Selection)
.into(),
text("Vertical Multi-Select").into(),
view_switcher::vertical(&self.multi_selection)
.on_activate(Message::MultiSelection)
.into(),
text("Vertical With Spacing").into(),
cosmic::iced::widget::row(vec![
view_switcher::vertical(&self.selection)
.spacing(8)
.on_activate(Message::Selection)
.width(Length::FillPortion(1))
.into(),
view_switcher::vertical(&self.selection)
.spacing(8)
.on_activate(Message::Selection)
.width(Length::FillPortion(1))
.into(),
view_switcher::vertical(&self.selection)
.spacing(8)
.on_activate(Message::Selection)
.width(Length::FillPortion(1))
.into(),
])
.spacing(12)
.width(Length::Fill)
.into(),
])
.padding(0)
.into(),
Some(DemoView::TabC) => {
settings::view_column(vec![settings::view_section("Tab C")
.add(text("Nothing here yet").width(Length::Fill))
.into()])
.padding(0)
.into()
}
},
container(text("Background container with some text").size(24))
.layer(cosmic_theme::Layer::Background)
.padding(8)
.width(Length::Fill)
.into(),
container(text("Primary container with some text").size(24))
.layer(cosmic_theme::Layer::Primary)
.padding(8)
.width(Length::Fill)
.into(),
container(text("Secondary container with some text").size(24))
.layer(cosmic_theme::Layer::Secondary)
.padding(8)
.width(Length::Fill)
.into(),
text_input(
"Type to search apps or type “?” for more options...",
&self.entry_value,
Message::InputChanged,
)
// .on_submit(Message::Activate(None))
.padding(8)
.size(20)
.id(INPUT_ID.clone())
.into(),
])
.into()
}
}

View file

@ -0,0 +1,286 @@
use cosmic::{
iced::widget::{column, container, horizontal_space, image, row, svg, text},
iced::Length,
theme,
widget::{list_column, settings, toggler},
Element,
};
use super::{Page, SubPage, Window};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum DesktopPage {
DesktopOptions,
Wallpaper,
Appearance,
DockAndTopPanel,
Workspaces,
Notifications,
}
#[derive(Debug, Default)]
pub struct State {
pub top_left_hot_corner: bool,
pub show_workspaces_button: bool,
pub show_applications_button: bool,
pub show_minimize_button: bool,
pub show_maximize_button: bool,
pub slideshow: bool,
pub same_background: bool,
}
#[derive(Clone, Copy, Debug)]
pub enum Message {
Page(Page),
Slideshow(bool),
SameBackground(bool),
ShowWorkspacesButton(bool),
ShowApplicationsButton(bool),
ShowMinimizeButton(bool),
ShowMaximizeButton(bool),
TopLeftHotCorner(bool),
}
impl From<Page> for Message {
fn from(page: Page) -> Message {
Message::Page(page)
}
}
pub enum Output {
Page(Page),
}
impl SubPage for DesktopPage {
//TODO: translate
fn title(&self) -> &'static str {
use DesktopPage::*;
match self {
DesktopOptions => "Desktop Options",
Wallpaper => "Wallpaper",
Appearance => "Appearance",
DockAndTopPanel => "Dock & Top Panel",
Workspaces => "Workspaces",
Notifications => "Notifications",
}
}
//TODO: translate
fn description(&self) -> &'static str {
use DesktopPage::*;
match self {
DesktopOptions => "Super Key action, hot corners, window control options.",
Wallpaper => "Background images, colors, and slideshow options.",
Appearance => "Accent colors and COSMIC theming",
DockAndTopPanel => "Customize size, positions, and more for Dock and Top Panel.",
Workspaces => "Set workspace number, behavior, and placement.",
Notifications => {
"Do Not Disturb, lockscreen notifications, and per-application settings."
}
}
}
fn icon_name(&self) -> &'static str {
use DesktopPage::*;
match self {
DesktopOptions => "video-display-symbolic",
Wallpaper => "preferences-desktop-wallpaper-symbolic",
Appearance => "preferences-pop-desktop-appearance-symbolic",
DockAndTopPanel => "preferences-pop-desktop-dock-symbolic",
Workspaces => "preferences-pop-desktop-workspaces-symbolic",
Notifications => "preferences-system-notifications-symbolic",
}
}
fn parent_page(&self) -> Page {
Page::Desktop(None)
}
fn into_page(self) -> Page {
Page::Desktop(Some(self))
}
}
impl State {
pub(super) fn update(&mut self, message: Message) -> Option<Output> {
match message {
Message::Page(page) => return Some(Output::Page(page)),
Message::SameBackground(value) => self.same_background = value,
Message::ShowApplicationsButton(value) => self.show_applications_button = value,
Message::ShowMaximizeButton(value) => self.show_maximize_button = value,
Message::ShowMinimizeButton(value) => self.show_maximize_button = value,
Message::ShowWorkspacesButton(value) => self.show_workspaces_button = value,
Message::Slideshow(value) => self.slideshow = value,
Message::TopLeftHotCorner(value) => self.top_left_hot_corner = value,
}
None
}
pub(super) fn view<'a>(
&'a self,
window: &'a Window,
desktop_page_opt: Option<DesktopPage>,
) -> Element<'a, Message> {
match desktop_page_opt {
None => settings::view_column(vec![
window.page_title(window.page),
column!(
window.sub_page_button(DesktopPage::DesktopOptions),
window.sub_page_button(DesktopPage::Wallpaper),
window.sub_page_button(DesktopPage::Appearance),
window.sub_page_button(DesktopPage::DockAndTopPanel),
window.sub_page_button(DesktopPage::Workspaces),
window.sub_page_button(DesktopPage::Notifications),
)
.spacing(16)
.into(),
])
.into(),
Some(DesktopPage::DesktopOptions) => self.view_desktop_options(window),
Some(DesktopPage::Wallpaper) => self.view_desktop_wallpaper(window),
Some(DesktopPage::Workspaces) => self.view_desktop_workspaces(window),
Some(sub_page) => window.view_unimplemented_sub_page(sub_page),
}
}
fn view_desktop_options<'a>(&'a self, window: &'a Window) -> Element<'a, Message> {
settings::view_column(vec![
window.parent_page_button(DesktopPage::DesktopOptions),
settings::view_section("Super Key Action")
.add(settings::item("Launcher", horizontal_space(Length::Fill)))
.add(settings::item("Workspaces", horizontal_space(Length::Fill)))
.add(settings::item(
"Applications",
horizontal_space(Length::Fill),
))
.into(),
settings::view_section("Hot Corner")
.add(settings::item(
"Enable top-left hot corner for Workspaces",
toggler(None, self.top_left_hot_corner, Message::TopLeftHotCorner),
))
.into(),
settings::view_section("Top Panel")
.add(settings::item(
"Show Workspaces Button",
toggler(
None,
self.show_workspaces_button,
Message::ShowWorkspacesButton,
),
))
.add(settings::item(
"Show Applications Button",
toggler(
None,
self.show_applications_button,
Message::ShowApplicationsButton,
),
))
.into(),
settings::view_section("Window Controls")
.add(settings::item(
"Show Minimize Button",
toggler(None, self.show_minimize_button, Message::ShowMinimizeButton),
))
.add(settings::item(
"Show Maximize Button",
toggler(None, self.show_maximize_button, Message::ShowMaximizeButton),
))
.into(),
])
.into()
}
fn view_desktop_wallpaper<'a>(&'a self, window: &'a Window) -> Element<'a, Message> {
let mut image_paths: Vec<std::path::PathBuf> = Vec::new();
/*
//TODO: load image paths, do this asynchronously somehow
if let Ok(entries) = std::fs::read_dir("/usr/share/backgrounds") {
for entry_res in entries {
let entry = match entry_res {
Ok(ok) => ok,
Err(_) => continue,
};
let path = entry.path();
if path.is_dir() {
//TODO: recursive
} else {
image_paths.push(path);
}
}
}
*/
let mut image_column = Vec::with_capacity(image_paths.len() / 4);
for chunk in image_paths.chunks(4) {
let mut image_row = Vec::with_capacity(chunk.len());
for image_path in chunk.iter() {
image_row.push(if image_path.ends_with(".svg") {
svg(svg::Handle::from_path(image_path))
.width(Length::Units(150))
.into()
} else {
image(image_path).width(Length::Units(150)).into()
});
}
image_column.push(row(image_row).spacing(16).into());
}
settings::view_column(vec![
window.parent_page_button(DesktopPage::Wallpaper),
row!(
horizontal_space(Length::Fill),
container(
image("/usr/share/backgrounds/pop/kate-hazen-COSMIC-desktop-wallpaper.png")
.width(Length::Units(300))
)
.padding(4)
.style(theme::Container::Background),
horizontal_space(Length::Fill),
)
.into(),
list_column()
.add(settings::item(
"Same background on all displays",
toggler(None, self.same_background, Message::SameBackground),
))
.add(settings::item("Background fit", text("TODO")))
.add(settings::item(
"Slideshow",
toggler(None, self.slideshow, Message::Slideshow),
))
.into(),
column(image_column).spacing(16).into(),
])
.into()
}
fn view_desktop_workspaces<'a>(&'a self, window: &'a Window) -> Element<'a, Message> {
settings::view_column(vec![
window.parent_page_button(DesktopPage::Wallpaper),
settings::view_section("Workspace Behavior")
.add(settings::item(
"Dynamic workspaces",
horizontal_space(Length::Fill),
))
.add(settings::item(
"Fixed Number of Workspaces",
horizontal_space(Length::Fill),
))
.into(),
settings::view_section("Multi-monitor Behavior")
.add(settings::item(
"Workspaces Span Displays",
horizontal_space(Length::Fill),
))
.add(settings::item(
"Displays Have Separate Workspaces",
horizontal_space(Length::Fill),
))
.into(),
])
.into()
}
}

View file

@ -0,0 +1,79 @@
use apply::Apply;
use cosmic::iced::widget::{horizontal_space, row, scrollable};
use cosmic::iced::Length;
use cosmic::iced_winit::Alignment;
use cosmic::widget::{button, segmented_button, view_switcher};
use cosmic::{theme, Element};
use slotmap::Key;
#[derive(Clone, Copy, Debug)]
pub enum Message {
Activate(segmented_button::Entity),
AddNew,
Close(segmented_button::Entity),
}
pub struct State {
pub pages: segmented_button::SingleSelectModel,
}
impl Default for State {
fn default() -> Self {
let mut state = Self {
pages: segmented_button::Model::default(),
};
let id = state.tab_add_new();
state.pages.activate(id);
state
}
}
impl State {
pub(super) fn update(&mut self, message: Message) {
match message {
Message::Activate(id) => self.pages.activate(id),
Message::AddNew => {
self.tab_add_new();
}
Message::Close(id) => self.tab_close(id),
}
}
pub fn tab_add_new(&mut self) -> segmented_button::Entity {
let id = self.pages.insert().closable().id();
self.pages
.text_set(id, format!("Tab {}", id.data().as_ffi() & 0xffff_ffff));
id
}
pub fn tab_close(&mut self, id: segmented_button::Entity) {
if self.pages.is_active(id) {
if let Some(pos) = self.pages.position(id) {
let next = if pos == 0 { pos + 1 } else { pos - 1 };
self.pages.activate_position(next);
}
}
self.pages.remove(id);
}
pub(super) fn view<'a>(&'a self, window: &'a super::Window) -> Element<'a, Message> {
let tabs = view_switcher::horizontal(&self.pages)
.show_close_icon_on_hover(true)
.on_activate(Message::Activate)
.on_close(Message::Close)
.width(Length::Shrink);
let new_tab_button = button(theme::Button::Text)
.icon(theme::Svg::Symbolic, "tab-new-symbolic", 20)
.on_press(Message::AddNew);
let tab_header = row!(tabs, new_tab_button).align_items(Alignment::Center);
row!(tab_header, horizontal_space(Length::Fill)).into()
}
}

View file

@ -0,0 +1,47 @@
use super::{Page, SubPage};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum InputDevicesPage {
Keyboard,
Touchpad,
Mouse,
}
impl SubPage for InputDevicesPage {
//TODO: translate
fn title(&self) -> &'static str {
use InputDevicesPage::*;
match self {
Keyboard => "Keyboard",
Touchpad => "Touchpad",
Mouse => "Mouse",
}
}
//TODO: translate
fn description(&self) -> &'static str {
use InputDevicesPage::*;
match self {
Keyboard => "Input sources, switching, special character entry, shortcuts.",
Touchpad => "Touchpad speed, click options, gestures.",
Mouse => "Mouse speed, acceleration, natural scrolling.",
}
}
fn icon_name(&self) -> &'static str {
use InputDevicesPage::*;
match self {
Keyboard => "input-keyboard-symbolic",
Touchpad => "input-touchpad-symbolic",
Mouse => "input-mouse-symbolic",
}
}
fn parent_page(&self) -> Page {
Page::InputDevices(None)
}
fn into_page(self) -> Page {
Page::InputDevices(Some(self))
}
}

View file

@ -0,0 +1,43 @@
use super::{Page, SubPage};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum NetworkingPage {
Wired,
OnlineAccounts,
}
impl SubPage for NetworkingPage {
//TODO: translate
fn title(&self) -> &'static str {
use NetworkingPage::*;
match self {
Wired => "Wired",
OnlineAccounts => "Online Accounts",
}
}
//TODO: translate
fn description(&self) -> &'static str {
use NetworkingPage::*;
match self {
Wired => "Wired connection, connection profiles",
OnlineAccounts => "Add accounts, IMAP and SMTP, enterprise logins",
}
}
fn icon_name(&self) -> &'static str {
use NetworkingPage::*;
match self {
Wired => "network-workgroup-symbolic",
OnlineAccounts => "goa-panel-symbolic", //TODO: new icon
}
}
fn parent_page(&self) -> Page {
Page::Networking(None)
}
fn into_page(self) -> Page {
Page::Networking(Some(self))
}
}

View file

@ -0,0 +1,94 @@
use cosmic::{
iced::widget::{horizontal_space, row, text},
iced::Length,
widget::{icon, list_column, settings},
Element,
};
use super::{Message, Page, SubPage, Window};
#[derive(Default)]
pub struct State {}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum SystemAndAccountsPage {
Users,
About,
Firmware,
}
impl SubPage for SystemAndAccountsPage {
//TODO: translate
fn title(&self) -> &'static str {
use SystemAndAccountsPage::*;
match self {
Users => "Users",
About => "About",
Firmware => "Firmware",
}
}
//TODO: translate
fn description(&self) -> &'static str {
use SystemAndAccountsPage::*;
match self {
Users => "Authentication and login, lock screen.",
About => "Device name, hardware information, operating system defaults.",
Firmware => "Firmware details.",
}
}
fn icon_name(&self) -> &'static str {
use SystemAndAccountsPage::*;
match self {
Users => "system-users-symbolic",
About => "help-about-symbolic",
Firmware => "firmware-manager-symbolic",
}
}
fn parent_page(&self) -> Page {
Page::SystemAndAccounts(None)
}
fn into_page(self) -> Page {
Page::SystemAndAccounts(Some(self))
}
}
impl State {
pub(super) fn view<'a>(&'a self, window: &'a Window) -> Element<'a, Message> {
settings::view_column(vec![
window.parent_page_button(SystemAndAccountsPage::About),
row!(
horizontal_space(Length::Fill),
icon("distributor-logo", 78),
horizontal_space(Length::Fill),
)
.into(),
list_column()
.add(settings::item("Device name", text("TODO")))
.into(),
settings::view_section("Hardware")
.add(settings::item("Hardware model", text("TODO")))
.add(settings::item("Memory", text("TODO")))
.add(settings::item("Processor", text("TODO")))
.add(settings::item("Graphics", text("TODO")))
.add(settings::item("Disk Capacity", text("TODO")))
.into(),
settings::view_section("Operating System")
.add(settings::item("Operating system", text("TODO")))
.add(settings::item(
"Operating system architecture",
text("TODO"),
))
.add(settings::item("Desktop environment", text("TODO")))
.add(settings::item("Windowing system", text("TODO")))
.into(),
settings::view_section("Related settings")
.add(settings::item("Get support", text("TODO")))
.into(),
])
.into()
}
}

View file

@ -0,0 +1,43 @@
use super::{Page, SubPage};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum TimeAndLanguagePage {
DateAndTime,
RegionAndLanguage,
}
impl SubPage for TimeAndLanguagePage {
//TODO: translate
fn title(&self) -> &'static str {
use TimeAndLanguagePage::*;
match self {
DateAndTime => "Date & Time",
RegionAndLanguage => "Region & Language",
}
}
//TODO: translate
fn description(&self) -> &'static str {
use TimeAndLanguagePage::*;
match self {
DateAndTime => "Time zone, automatic clock settings, and some time formatting.",
RegionAndLanguage => "Format dates, times, and numbers based on your region",
}
}
fn icon_name(&self) -> &'static str {
use TimeAndLanguagePage::*;
match self {
DateAndTime => "preferences-system-time-symbolic",
RegionAndLanguage => "preferences-desktop-locale-symbolic",
}
}
fn parent_page(&self) -> Page {
Page::TimeAndLanguage(None)
}
fn into_page(self) -> Page {
Page::TimeAndLanguage(Some(self))
}
}