View Switcher Widget
This commit is contained in:
parent
1eee5513bd
commit
8e6959a3cb
2 changed files with 92 additions and 1 deletions
|
|
@ -9,7 +9,7 @@ use cosmic::{
|
||||||
iced_lazy::responsive,
|
iced_lazy::responsive,
|
||||||
iced_winit::window::{drag, toggle_maximize, minimize},
|
iced_winit::window::{drag, toggle_maximize, minimize},
|
||||||
theme::{self, Theme},
|
theme::{self, Theme},
|
||||||
widget::{button, nav_button, nav_bar, nav_bar_page, nav_bar_section, header_bar, settings, scrollable, toggler},
|
widget::{button, nav_button, nav_bar, header_bar, settings, scrollable, toggler},
|
||||||
Element,
|
Element,
|
||||||
ElementExt,
|
ElementExt,
|
||||||
};
|
};
|
||||||
|
|
@ -62,6 +62,7 @@ pub enum Message {
|
||||||
TogglerToggled(bool),
|
TogglerToggled(bool),
|
||||||
PickListSelected(&'static str),
|
PickListSelected(&'static str),
|
||||||
RowSelected(usize),
|
RowSelected(usize),
|
||||||
|
ViewChanged(usize),
|
||||||
Close,
|
Close,
|
||||||
ToggleSidebar,
|
ToggleSidebar,
|
||||||
Drag,
|
Drag,
|
||||||
|
|
@ -110,6 +111,7 @@ impl Application for Window {
|
||||||
Message::Minimize => return minimize(true),
|
Message::Minimize => return minimize(true),
|
||||||
Message::Maximize => return toggle_maximize(),
|
Message::Maximize => return toggle_maximize(),
|
||||||
Message::RowSelected(row) => println!("Selected row {row}"),
|
Message::RowSelected(row) => println!("Selected row {row}"),
|
||||||
|
Message::ViewChanged(view) => println!("Selected view {view}"),
|
||||||
}
|
}
|
||||||
|
|
||||||
Command::none()
|
Command::none()
|
||||||
|
|
|
||||||
89
src/widget/view_switcher.rs
Normal file
89
src/widget/view_switcher.rs
Normal file
|
|
@ -0,0 +1,89 @@
|
||||||
|
use derive_setters::Setters;
|
||||||
|
use iced::{
|
||||||
|
alignment::{Horizontal, Vertical},
|
||||||
|
theme,
|
||||||
|
widget::{button, container, text, Row},
|
||||||
|
Background, Element, Length, Renderer, Theme, Alignment,
|
||||||
|
};
|
||||||
|
use iced_lazy::Component;
|
||||||
|
|
||||||
|
#[derive(Setters)]
|
||||||
|
pub struct ViewSwitcher<'a, Message> {
|
||||||
|
options: Vec<&'a str>,
|
||||||
|
#[setters(strip_option)]
|
||||||
|
on_view_changed: Option<Box<dyn Fn(usize) -> Message + 'a>>
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn view_switcher<'a, Message>() -> ViewSwitcher<'a, Message> {
|
||||||
|
ViewSwitcher { options: vec![], on_view_changed: None }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum ViewSwitcherEvent {
|
||||||
|
ViewSelected(usize),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct ViewSwitcherState {
|
||||||
|
selected_view: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Message> Component<Message, Renderer> for ViewSwitcher<'a, Message> {
|
||||||
|
type State = ViewSwitcherState;
|
||||||
|
|
||||||
|
type Event = ViewSwitcherEvent;
|
||||||
|
|
||||||
|
fn update(&mut self, state: &mut Self::State, event: Self::Event) -> Option<Message> {
|
||||||
|
match event {
|
||||||
|
ViewSwitcherEvent::ViewSelected(index) => state.selected_view = index,
|
||||||
|
}
|
||||||
|
self.on_view_changed.as_ref().map(|on_view_changed| (on_view_changed)(state.selected_view))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn view(&self, state: &Self::State) -> Element<'_, Self::Event, Renderer> {
|
||||||
|
let mut options: Vec<Element<'a, Self::Event, Renderer>> = vec![];
|
||||||
|
|
||||||
|
for (index, option) in self.options.iter().enumerate() {
|
||||||
|
options.push(
|
||||||
|
button(
|
||||||
|
container(text(option))
|
||||||
|
.width(Length::Fill)
|
||||||
|
.height(Length::Fill)
|
||||||
|
.align_x(Horizontal::Center)
|
||||||
|
.align_y(Vertical::Center),
|
||||||
|
)
|
||||||
|
.width(Length::Fill)
|
||||||
|
.height(Length::Units(32))
|
||||||
|
.style(if state.selected_view == index {
|
||||||
|
theme::Button::Secondary.into()
|
||||||
|
} else {
|
||||||
|
theme::Button::Primary.into()
|
||||||
|
})
|
||||||
|
.on_press(ViewSwitcherEvent::ViewSelected(index))
|
||||||
|
.into(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
container(Row::with_children(options).align_items(Alignment::Fill))
|
||||||
|
.width(Length::Fill)
|
||||||
|
.padding(2)
|
||||||
|
.style(theme::Container::Custom(view_switcher_container_style))
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn view_switcher_container_style(theme: &Theme) -> iced_style::container::Appearance {
|
||||||
|
let accent = &theme.cosmic().accent;
|
||||||
|
iced_style::container::Appearance {
|
||||||
|
text_color: Default::default(),
|
||||||
|
background: Some(Background::Color(accent.base.into())),
|
||||||
|
border_radius: 24.0,
|
||||||
|
border_width: 2.0,
|
||||||
|
border_color: accent.base.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, Message: 'a> From<ViewSwitcher<'a, Message>> for Element<'a, Message> {
|
||||||
|
fn from(view_switcher: ViewSwitcher<'a, Message>) -> Self {
|
||||||
|
iced_lazy::component(view_switcher)
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue