feat(wallpaper): use dropdown and image button widgets
This commit is contained in:
parent
8175e8df97
commit
dc9db64592
5 changed files with 184 additions and 117 deletions
|
|
@ -6,7 +6,6 @@ mod widgets;
|
|||
use std::{
|
||||
collections::HashMap,
|
||||
path::{Path, PathBuf},
|
||||
time::Instant,
|
||||
};
|
||||
|
||||
use apply::Apply;
|
||||
|
|
@ -22,6 +21,7 @@ use cosmic_settings_page::Section;
|
|||
use cosmic_settings_page::{self as page, section};
|
||||
use image::imageops::FilterType::Lanczos3;
|
||||
use slotmap::{DefaultKey, SecondaryMap, SlotMap};
|
||||
use static_init::dynamic;
|
||||
|
||||
const SYSTEM_WALLPAPER_DIR: &str = "/usr/share/backgrounds/pop/";
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ const HOUR_2: usize = 5;
|
|||
pub enum Message {
|
||||
ChangeCategory(usize),
|
||||
ColorSelect(wallpaper::Color),
|
||||
Fit(String),
|
||||
Fit(usize),
|
||||
Output(segmented_button::Entity),
|
||||
RotationFrequency(usize),
|
||||
SameBackground(bool),
|
||||
|
|
@ -364,11 +364,11 @@ impl Page {
|
|||
#[must_use]
|
||||
pub fn display_image_view(&self) -> cosmic::Element<Message> {
|
||||
match self.cached_display_handle {
|
||||
Some(ref handle) => cosmic::iced::widget::image(handle.clone())
|
||||
Some(ref handle) => cosmic::widget::image(handle.clone())
|
||||
.width(Length::Fixed(SIMULATED_WIDTH as f32))
|
||||
.into(),
|
||||
|
||||
None => cosmic::iced::widget::Space::new(SIMULATED_WIDTH, SIMULATED_HEIGHT).into(),
|
||||
None => cosmic::widget::Space::new(SIMULATED_WIDTH, SIMULATED_HEIGHT).into(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -382,14 +382,8 @@ impl Page {
|
|||
self.cached_display_handle = None;
|
||||
}
|
||||
|
||||
Message::Fit(option) => {
|
||||
self.selected_fit = self
|
||||
.fit_options
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_, key)| **key == option)
|
||||
.map_or(0, |(indice, _)| indice);
|
||||
|
||||
Message::Fit(selection) => {
|
||||
self.selected_fit = selection;
|
||||
self.cache_display_image();
|
||||
}
|
||||
|
||||
|
|
@ -512,8 +506,6 @@ impl page::Page<crate::pages::Message> for Page {
|
|||
|
||||
fn load(&self, _page: page::Entity) -> Option<page::Task<crate::pages::Message>> {
|
||||
Some(Box::pin(async move {
|
||||
let start = Instant::now();
|
||||
|
||||
let (config, outputs) = wallpaper::config();
|
||||
|
||||
let mut backgrounds = wallpaper::load_each_from_path(SYSTEM_WALLPAPER_DIR.into());
|
||||
|
|
@ -533,11 +525,6 @@ impl page::Page<crate::pages::Message> for Page {
|
|||
update.selection_handles.insert(id, selection_handle);
|
||||
}
|
||||
|
||||
tracing::debug!(
|
||||
"loaded wallpapers in {:?}",
|
||||
Instant::now().duration_since(start)
|
||||
);
|
||||
|
||||
crate::pages::Message::DesktopWallpaper(Message::Update(Box::new((
|
||||
config, outputs, update,
|
||||
))))
|
||||
|
|
@ -547,18 +534,28 @@ impl page::Page<crate::pages::Message> for Page {
|
|||
|
||||
impl page::AutoBind<crate::pages::Message> for Page {}
|
||||
|
||||
#[dynamic]
|
||||
static WALLPAPER_SAME: String = fl!("wallpaper", "same");
|
||||
|
||||
#[dynamic]
|
||||
static WALLPAPER_FIT: String = fl!("wallpaper", "fit");
|
||||
|
||||
#[dynamic]
|
||||
static WALLPAPER_SLIDE: String = fl!("wallpaper", "slide");
|
||||
|
||||
#[dynamic]
|
||||
static WALLPAPER_CHANGE: String = fl!("wallpaper", "change");
|
||||
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub fn settings() -> Section<crate::pages::Message> {
|
||||
Section::default()
|
||||
.descriptions(vec![
|
||||
fl!("wallpaper", "same"),
|
||||
fl!("wallpaper", "fit"),
|
||||
fl!("wallpaper", "slide"),
|
||||
fl!("wallpaper", "change"),
|
||||
WALLPAPER_SAME.clone(),
|
||||
WALLPAPER_FIT.clone(),
|
||||
WALLPAPER_SLIDE.clone(),
|
||||
WALLPAPER_CHANGE.clone(),
|
||||
])
|
||||
.view::<Page>(|_binder, page, section| {
|
||||
let descriptions = §ion.descriptions;
|
||||
|
||||
.view::<Page>(|_binder, page, _section| {
|
||||
let mut children = Vec::with_capacity(3);
|
||||
|
||||
let mut show_slideshow_toggle = true;
|
||||
|
|
@ -590,7 +587,7 @@ pub fn settings() -> Section<crate::pages::Message> {
|
|||
.vertical_alignment(alignment::Vertical::Center)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fill)
|
||||
.apply(cosmic::iced::widget::container)
|
||||
.apply(cosmic::widget::container)
|
||||
.width(Length::Fill)
|
||||
.height(Length::Fixed(32.0))
|
||||
.into()
|
||||
|
|
@ -600,32 +597,29 @@ pub fn settings() -> Section<crate::pages::Message> {
|
|||
.into()
|
||||
});
|
||||
|
||||
let background_fit = cosmic::iced::widget::pick_list(
|
||||
&page.fit_options,
|
||||
page.fit_options.get(page.selected_fit).cloned(),
|
||||
Message::Fit,
|
||||
);
|
||||
let background_fit =
|
||||
cosmic::widget::dropdown(&page.fit_options, Some(page.selected_fit), Message::Fit);
|
||||
|
||||
children.push({
|
||||
let mut column = list_column()
|
||||
.add(settings::item(
|
||||
&descriptions[0],
|
||||
&*WALLPAPER_SAME,
|
||||
toggler(None, page.config.same_on_all, Message::SameBackground),
|
||||
))
|
||||
.add(settings::item(&descriptions[1], background_fit));
|
||||
.add(settings::item(&*WALLPAPER_FIT, background_fit));
|
||||
|
||||
if show_slideshow_toggle {
|
||||
column = column.add(settings::item(
|
||||
&descriptions[2],
|
||||
&*WALLPAPER_SLIDE,
|
||||
toggler(None, slideshow_enabled, Message::Slideshow),
|
||||
));
|
||||
}
|
||||
|
||||
// The rotation frequency pick list should only be shown when the slideshow is enabled.
|
||||
// The rotation frequency dropdown should only be shown when the slideshow is enabled.
|
||||
if slideshow_enabled {
|
||||
column
|
||||
.add(settings::item(
|
||||
&descriptions[3],
|
||||
&*WALLPAPER_CHANGE,
|
||||
dropdown(
|
||||
&page.rotation_options,
|
||||
Some(page.selected_rotation),
|
||||
|
|
@ -649,18 +643,31 @@ pub fn settings() -> Section<crate::pages::Message> {
|
|||
match page.active_category {
|
||||
// Displays system wallpapers that are available to select from
|
||||
CATEGORY_SYSTEM_WALLPAPERS => {
|
||||
children.push(widgets::wallpaper_select_options(page));
|
||||
children.push(widgets::wallpaper_select_options(
|
||||
page,
|
||||
if let Choice::Background(selection) = page.selection.active {
|
||||
Some(selection)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
// Displays colors and gradients that are available to select from
|
||||
CATEGORY_COLOR => {
|
||||
children.push(widgets::color_select_options());
|
||||
children.push(widgets::color_select_options(
|
||||
if let Choice::Color(ref color) = page.selection.active {
|
||||
Some(color)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
_ => (),
|
||||
}
|
||||
|
||||
cosmic::iced::widget::column(children)
|
||||
cosmic::widget::column::with_children(children)
|
||||
.spacing(22)
|
||||
.apply(Element::from)
|
||||
.map(crate::pages::Message::DesktopWallpaper)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use super::Message;
|
|||
use cosmic::iced_core::{self, gradient::Linear, Background, BorderRadius, Color, Degrees, Length};
|
||||
use cosmic::iced_runtime::core::image::Handle as ImageHandle;
|
||||
use cosmic::prelude::*;
|
||||
use cosmic::widget::{button, container, image, space};
|
||||
use cosmic::widget::{button, container, space};
|
||||
use cosmic::{iced, Element};
|
||||
use cosmic_settings_desktop::wallpaper;
|
||||
use slotmap::DefaultKey;
|
||||
|
|
@ -15,10 +15,11 @@ const COLUMN_SPACING: u16 = 12;
|
|||
const ROW_SPACING: u16 = 16;
|
||||
|
||||
/// A button for selecting a color or gradient.
|
||||
pub fn color_button(color: wallpaper::Color) -> Element<'static, Message> {
|
||||
pub fn color_button(color: wallpaper::Color, selected: bool) -> Element<'static, Message> {
|
||||
button(color_image(color.clone(), COLOR_WIDTH, COLOR_WIDTH, 8.0))
|
||||
.padding(0)
|
||||
.style(button::Style::IconVertical)
|
||||
.selected(selected)
|
||||
.style(button::Style::Image)
|
||||
.on_press(Message::ColorSelect(color))
|
||||
.into()
|
||||
}
|
||||
|
|
@ -64,22 +65,32 @@ pub fn color_image(
|
|||
}
|
||||
|
||||
/// Color selection list
|
||||
pub fn color_select_options() -> Element<'static, Message> {
|
||||
pub fn color_select_options(selected: Option<&wallpaper::Color>) -> Element<'static, Message> {
|
||||
let mut vec = Vec::with_capacity(wallpaper::DEFAULT_COLORS.len());
|
||||
|
||||
for color in wallpaper::DEFAULT_COLORS {
|
||||
vec.push(color_button(color.clone()));
|
||||
vec.push(color_button(
|
||||
color.clone(),
|
||||
selected.map_or(false, |selection| selection == color),
|
||||
));
|
||||
}
|
||||
|
||||
flex_select_row(vec)
|
||||
}
|
||||
|
||||
/// Background selection list
|
||||
pub fn wallpaper_select_options(page: &super::Page) -> Element<Message> {
|
||||
pub fn wallpaper_select_options(
|
||||
page: &super::Page,
|
||||
selected: Option<DefaultKey>,
|
||||
) -> Element<Message> {
|
||||
let mut vec = Vec::with_capacity(page.selection.selection_handles.len());
|
||||
|
||||
for (id, handle) in &page.selection.selection_handles {
|
||||
vec.push(wallpaper_button(handle, id));
|
||||
vec.push(wallpaper_button(
|
||||
handle,
|
||||
id,
|
||||
selected.map_or(false, |selection| id == selection),
|
||||
));
|
||||
}
|
||||
|
||||
flex_select_row(vec)
|
||||
|
|
@ -95,12 +106,9 @@ fn flex_select_row(elements: Vec<Element<Message>>) -> Element<Message> {
|
|||
.into()
|
||||
}
|
||||
|
||||
fn wallpaper_button(handle: &ImageHandle, id: DefaultKey) -> Element<Message> {
|
||||
let image = image(handle.clone()).apply(iced::Element::from);
|
||||
|
||||
button(image)
|
||||
.padding(0)
|
||||
.style(cosmic::theme::Button::Transparent)
|
||||
fn wallpaper_button(handle: &ImageHandle, id: DefaultKey, selected: bool) -> Element<Message> {
|
||||
cosmic::widget::button::image(handle.clone())
|
||||
.selected(selected)
|
||||
.on_press(Message::Select(id))
|
||||
.into()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue