refactor(cosmic): Separate states across views

This commit is contained in:
Michael Aaron Murphy 2022-12-30 17:40:16 +01:00 committed by Ashley Wulber
parent ad0443af3f
commit 0cea2023f8
6 changed files with 278 additions and 108 deletions

View file

@ -3,16 +3,32 @@ use cosmic::{
iced::widget::{column, text},
widget::{list_column, settings, toggler},
};
use super::{Message, Page, Window};
use super::{Page, Window};
impl Window {
pub(super) fn view_bluetooth(&self) -> Element<Message> {
#[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![
self.page_title(Page::Bluetooth),
window.page_title(Page::Bluetooth),
column!(
list_column()
.add(settings::item("Bluetooth", toggler(None, self.toggler_value, Message::TogglerToggled))),
.add(settings::item("Bluetooth", toggler(None, self.enabled, Message::Enable))),
text("Now visible as \"TODO\", just kidding")
).spacing(8).into(),

View file

@ -1,12 +1,12 @@
use cosmic::{
iced::widget::{checkbox, pick_list, progress_bar, radio, row, slider},
iced::{Alignment, Length},
theme::{self, Button as ButtonTheme, Theme},
widget::{button, segmented_button::cosmic::{view_switcher, segmented_selection}, settings, toggler},
theme::{Button as ButtonTheme, Theme},
widget::{button, segmented_button::{self, cosmic::{view_switcher, segmented_selection}}, settings, toggler, Orientation, spin_button::{SpinButtonModel, SpinMessage}},
Element,
};
use super::{Message, Page, Window};
use super::{Page, Window};
pub enum DemoView {
TabA,
@ -14,33 +14,82 @@ pub enum DemoView {
TabC,
}
impl Window {
pub(super) fn view_demo(&self) -> Element<Message> {
#[derive(Clone, Copy, Debug)]
pub enum Message {
ButtonPressed,
CheckboxToggled(bool),
Debug(bool),
PickListSelected(&'static str),
RowSelected(usize),
Selection(segmented_button::Key),
SliderChanged(f32),
SpinButton(SpinMessage),
ThemeChanged(Theme),
TogglerToggled(bool),
ViewSwitcher(segmented_button::Key),
}
pub enum Output {
Debug(bool),
ThemeChanged(Theme)
}
#[derive(Default)]
pub struct State {
pub checkbox_value: bool,
pub pick_list_selected: Option<&'static str>,
pub selection: segmented_button::State<()>,
pub slider_value: f32,
pub spin_button: SpinButtonModel<i32>,
pub toggler_value: bool,
pub view_switcher: segmented_button::State<DemoView>,
}
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::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::TogglerToggled(value) => self.toggler_value = value,
Message::ViewSwitcher(key) => self.view_switcher.activate(key),
}
None
}
pub(super) fn view<'a>(&'a self, window: &'a Window) -> Element<'a, Message> {
let choose_theme = [Theme::Light, Theme::Dark].iter().fold(
row![].spacing(10).align_items(Alignment::Center),
|row, theme| {
row.push(radio(
format!("{:?}", theme),
*theme,
Some(self.theme),
Some(window.theme),
Message::ThemeChanged,
))
},
);
settings::view_column(vec![
self.page_title(Page::Demo),
view_switcher(&self.demo_view_switcher)
.on_activate(Message::DemoTabActivate)
window.page_title(Page::Demo),
view_switcher(&self.view_switcher)
.on_activate(Message::ViewSwitcher)
.into(),
match self.demo_view_switcher.active_data() {
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 layout",
toggler(None, self.debug, Message::Debug),
toggler(None, window.debug, Message::Debug),
))
.into(),
settings::view_section("Buttons")
@ -118,12 +167,59 @@ impl Window {
.into(),
Some(DemoView::TabB) => {
settings::view_column(vec![
cosmic::iced::widget::text("SegmentedButton::Selection")
cosmic::iced::widget::text("Selection")
.font(cosmic::font::FONT_SEMIBOLD)
.into(),
segmented_selection(&self.demo_selection)
.on_activate(Message::DemoSelectionActivate)
.into()
segmented_selection(&self.selection)
.on_activate(Message::Selection)
.into(),
segmented_selection(&self.selection)
.on_activate(Message::Selection)
.orientation(Orientation::Vertical)
.into(),
cosmic::iced::widget::row(vec![
segmented_selection(&self.selection)
.on_activate(Message::Selection)
.orientation(Orientation::Vertical)
.width(Length::FillPortion(1))
.into(),
segmented_selection(&self.selection)
.on_activate(Message::Selection)
.orientation(Orientation::Vertical)
.width(Length::FillPortion(1))
.into(),
segmented_selection(&self.selection)
.on_activate(Message::Selection)
.orientation(Orientation::Vertical)
.width(Length::FillPortion(1))
.into(),
])
.spacing(12)
.width(Length::Fill)
.into(),
cosmic::iced::widget::text("ViewSwitcher")
.font(cosmic::font::FONT_SEMIBOLD)
.into(),
cosmic::iced::widget::row(vec![
view_switcher(&self.selection)
.on_activate(Message::Selection)
.orientation(Orientation::Vertical)
.width(Length::FillPortion(1))
.into(),
view_switcher(&self.selection)
.on_activate(Message::Selection)
.orientation(Orientation::Vertical)
.width(Length::FillPortion(1))
.into(),
view_switcher(&self.selection)
.on_activate(Message::Selection)
.orientation(Orientation::Vertical)
.width(Length::FillPortion(1))
.into(),
])
.spacing(12)
.width(Length::Fill)
.into()
])
.padding(0)
.into()

View file

@ -6,7 +6,7 @@ use cosmic::{
widget::{list_column, settings, toggler},
};
use super::{Message, Page, SubPage, Window};
use super::{Page, SubPage, Window};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum DesktopPage {
@ -18,6 +18,39 @@ pub enum DesktopPage {
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 {
@ -66,30 +99,45 @@ impl SubPage for DesktopPage {
}
}
impl Window {
pub(super) fn view_desktop(&self, desktop_page_opt: Option<DesktopPage>) -> Element<Message> {
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![
self.page_title(self.page),
window.page_title(window.page),
column!(
self.sub_page_button(DesktopPage::DesktopOptions),
self.sub_page_button(DesktopPage::Wallpaper),
self.sub_page_button(DesktopPage::Appearance),
self.sub_page_button(DesktopPage::DockAndTopPanel),
self.sub_page_button(DesktopPage::Workspaces),
self.sub_page_button(DesktopPage::Notifications),
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(),
Some(DesktopPage::Wallpaper) => self.view_desktop_wallpaper(),
Some(DesktopPage::Workspaces) => self.view_desktop_workspaces(),
Some(sub_page) => self.view_unimplemented_sub_page(sub_page),
])
.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(&self) -> Element<Message> {
fn view_desktop_options<'a>(&'a self, window: &'a Window) -> Element<'a, Message> {
settings::view_column(vec![
self.parent_page_button(DesktopPage::DesktopOptions),
window.parent_page_button(DesktopPage::DesktopOptions),
settings::view_section("Super Key Action")
.add(settings::item("Launcher", horizontal_space(Length::Fill)))
@ -98,22 +146,22 @@ impl Window {
.into(),
settings::view_section("Hot Corner")
.add(settings::item("Enable top-left hot corner for Workspaces", toggler(None, self.toggler_value, Message::TogglerToggled)))
.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.toggler_value, Message::TogglerToggled)))
.add(settings::item("Show Applications Button", toggler(None, self.toggler_value, Message::TogglerToggled)))
.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.toggler_value, Message::TogglerToggled)))
.add(settings::item("Show Maximize Button", toggler(None, self.toggler_value, Message::TogglerToggled)))
.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(&self) -> Element<Message> {
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
@ -150,7 +198,7 @@ impl Window {
}
settings::view_column(vec![
self.parent_page_button(DesktopPage::Wallpaper),
window.parent_page_button(DesktopPage::Wallpaper),
row!(
horizontal_space(Length::Fill),
@ -165,18 +213,18 @@ impl Window {
).into(),
list_column()
.add(settings::item("Same background on all displays", toggler(None, self.toggler_value, Message::TogglerToggled)))
.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.toggler_value, Message::TogglerToggled)))
.add(settings::item("Slideshow", toggler(None, self.slideshow, Message::Slideshow)))
.into(),
column(image_column).spacing(16).into(),
]).into()
}
fn view_desktop_workspaces(&self) -> Element<Message> {
fn view_desktop_workspaces<'a>(&'a self, window: &'a Window) -> Element<'a, Message> {
settings::view_column(vec![
self.parent_page_button(DesktopPage::Wallpaper),
window.parent_page_button(DesktopPage::Wallpaper),
settings::view_section("Workspace Behavior")
.add(settings::item("Dynamic workspaces", horizontal_space(Length::Fill)))

View file

@ -7,6 +7,9 @@ use cosmic::{
use super::{Message, Page, SubPage, Window};
#[derive(Default)]
pub struct State {}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum SystemAndAccountsPage {
Users,
@ -53,10 +56,10 @@ impl SubPage for SystemAndAccountsPage {
}
}
impl Window {
pub(super) fn view_system_and_accounts_about(&self) -> Element<Message> {
impl State {
pub(super) fn view<'a>(&'a self, window: &'a Window) -> Element<'a, Message> {
settings::view_column(vec![
self.parent_page_button(SystemAndAccountsPage::About),
window.parent_page_button(SystemAndAccountsPage::About),
row!(
horizontal_space(Length::Fill),