fix(wallpaper): improvements and fixes
This commit is contained in:
parent
39eccde230
commit
bf70b14cda
12 changed files with 261 additions and 168 deletions
|
|
@ -34,20 +34,51 @@ impl Config {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Get the active background folder from cosmic-config.
|
||||||
if let Ok(path) = context.get::<Option<PathBuf>>(CURRENT_FOLDER) {
|
if let Ok(path) = context.get::<Option<PathBuf>>(CURRENT_FOLDER) {
|
||||||
config.current_folder = path;
|
// Set current folder if it exists.
|
||||||
|
config.current_folder = path.filter(|path| path.exists());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get custom colors stored in cosmic-config.
|
||||||
if let Ok(colors) = context.get::<Vec<wallpaper::Color>>(CUSTOM_COLORS) {
|
if let Ok(colors) = context.get::<Vec<wallpaper::Color>>(CUSTOM_COLORS) {
|
||||||
config.custom_colors = colors;
|
config.custom_colors = colors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get custom background images stored in cosmic-config.
|
||||||
if let Ok(images) = context.get::<Vec<PathBuf>>(CUSTOM_IMAGES) {
|
if let Ok(images) = context.get::<Vec<PathBuf>>(CUSTOM_IMAGES) {
|
||||||
config.custom_images = images;
|
// Update config if images are missing.
|
||||||
|
let mut update_config = false;
|
||||||
|
|
||||||
|
for image in images {
|
||||||
|
if image.exists() {
|
||||||
|
config.custom_images.push(image);
|
||||||
|
} else {
|
||||||
|
update_config = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if update_config {
|
||||||
|
let _res = config.update_custom_images();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(folders) = dbg!(context.get::<VecDeque<PathBuf>>(RECENT_FOLDERS)) {
|
// Get recently-added background folders from cosmic-config.
|
||||||
config.recent_folders = folders;
|
if let Ok(folders) = context.get::<VecDeque<PathBuf>>(RECENT_FOLDERS) {
|
||||||
|
// Update config if folders are missing
|
||||||
|
let mut update_config = false;
|
||||||
|
|
||||||
|
for folder in folders {
|
||||||
|
if folder.exists() {
|
||||||
|
config.recent_folders.push_back(folder);
|
||||||
|
} else {
|
||||||
|
update_config = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if update_config {
|
||||||
|
let _res = config.update_recent_folders();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
config.context = Some(context);
|
config.context = Some(context);
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,15 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use apply::Apply;
|
use apply::Apply;
|
||||||
use cosmic::iced::{wayland::actions::window::SctkWindowSettings, window, Color, Length};
|
use cosmic::{
|
||||||
use cosmic::iced_sctk::commands::window::{close_window, get_window};
|
iced::{wayland::actions::window::SctkWindowSettings, window, Color, Length},
|
||||||
|
prelude::CollectionWidget,
|
||||||
|
};
|
||||||
|
use cosmic::{
|
||||||
|
iced_core::Alignment,
|
||||||
|
iced_sctk::commands::window::{close_window, get_window},
|
||||||
|
widget::icon,
|
||||||
|
};
|
||||||
use cosmic::{
|
use cosmic::{
|
||||||
iced_core::{alignment, layout},
|
iced_core::{alignment, layout},
|
||||||
iced_runtime::core::image::Handle as ImageHandle,
|
iced_runtime::core::image::Handle as ImageHandle,
|
||||||
|
|
@ -57,35 +64,44 @@ pub type Image = ImageBuffer<Rgba<u8>, Vec<u8>>;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum Message {
|
pub enum Message {
|
||||||
|
ChangeCategory(Category),
|
||||||
ChangeFolder(Context),
|
ChangeFolder(Context),
|
||||||
ColorAddDialog,
|
ColorAddDialog,
|
||||||
ColorDialogUpdate(ColorPickerUpdate),
|
ColorDialogUpdate(ColorPickerUpdate),
|
||||||
ColorRemove(wallpaper::Color),
|
ColorRemove(wallpaper::Color),
|
||||||
ChangeCategory(Category),
|
|
||||||
ColorSelect(wallpaper::Color),
|
ColorSelect(wallpaper::Color),
|
||||||
DragColorDialog,
|
DragColorDialog,
|
||||||
Fit(usize),
|
Fit(usize),
|
||||||
ImageAdd(Option<Arc<(PathBuf, Image, Image)>>),
|
ImageAdd(Option<Arc<(PathBuf, Image, Image)>>),
|
||||||
ImageAddDialog,
|
ImageAddDialog,
|
||||||
ImageRemove(DefaultKey),
|
ImageRemove(DefaultKey),
|
||||||
|
Init(Box<(wallpaper::Config, HashMap<String, String>, Context)>),
|
||||||
Output(segmented_button::Entity),
|
Output(segmented_button::Entity),
|
||||||
RotationFrequency(usize),
|
RotationFrequency(usize),
|
||||||
SameBackground(bool),
|
SameWallpaper(bool),
|
||||||
Select(DefaultKey),
|
Select(DefaultKey),
|
||||||
Slideshow(bool),
|
Slideshow(bool),
|
||||||
Init(Box<(wallpaper::Config, HashMap<String, String>, Context)>),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum Category {
|
pub enum Category {
|
||||||
Backgrounds,
|
AddFolder,
|
||||||
Colors,
|
Colors,
|
||||||
RecentFolder(usize),
|
RecentFolder(usize),
|
||||||
|
Wallpapers,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
enum ActiveDialog {
|
||||||
|
AddFolder,
|
||||||
|
AddImage,
|
||||||
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Page {
|
pub struct Page {
|
||||||
pub active_output: Option<String>,
|
pub active_output: Option<String>,
|
||||||
pub background_service_config: wallpaper::Config,
|
active_dialog: ActiveDialog,
|
||||||
|
pub wallpaper_service_config: wallpaper::Config,
|
||||||
pub cached_display_handle: Option<ImageHandle>,
|
pub cached_display_handle: Option<ImageHandle>,
|
||||||
pub categories: dropdown::multi::Model<String, Category>,
|
pub categories: dropdown::multi::Model<String, Category>,
|
||||||
pub color_dialog: window::Id,
|
pub color_dialog: window::Id,
|
||||||
|
|
@ -116,21 +132,41 @@ impl page::Page<crate::pages::Message> for Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn file_chooser(&mut self, selections: Vec<url::Url>) -> Command<crate::pages::Message> {
|
fn file_chooser(&mut self, selections: Vec<url::Url>) -> Command<crate::pages::Message> {
|
||||||
|
let active_dialog = self.active_dialog;
|
||||||
|
self.active_dialog = ActiveDialog::None;
|
||||||
|
|
||||||
if let Some(selection) = selections.first() {
|
if let Some(selection) = selections.first() {
|
||||||
let path = PathBuf::from(selection.path());
|
let path = PathBuf::from(selection.path());
|
||||||
|
|
||||||
if path.is_dir() {
|
match active_dialog {
|
||||||
self.add_recent_folder(path);
|
ActiveDialog::AddFolder => {
|
||||||
} else {
|
if path.is_dir() {
|
||||||
if let Some(parent) = path.parent() {
|
self.add_recent_folder(path.clone());
|
||||||
self.add_recent_folder(parent.to_owned());
|
|
||||||
|
let _res = self.config.set_current_folder(Some(path.clone()));
|
||||||
|
|
||||||
|
return cosmic::command::future(async move {
|
||||||
|
crate::pages::Message::DesktopWallpaper(Message::ChangeFolder(
|
||||||
|
change_folder(path).await,
|
||||||
|
))
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return cosmic::command::future(async move {
|
ActiveDialog::AddImage => {
|
||||||
let result = wallpaper::load_image_with_thumbnail(&mut Vec::new(), path).await;
|
if path.is_file() {
|
||||||
|
return cosmic::command::future(async move {
|
||||||
|
let result =
|
||||||
|
wallpaper::load_image_with_thumbnail(&mut Vec::new(), path).await;
|
||||||
|
|
||||||
crate::pages::Message::DesktopWallpaper(Message::ImageAdd(result.map(Arc::new)))
|
crate::pages::Message::DesktopWallpaper(Message::ImageAdd(
|
||||||
});
|
result.map(Arc::new),
|
||||||
|
))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ActiveDialog::None => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -141,12 +177,12 @@ impl page::Page<crate::pages::Message> for Page {
|
||||||
let current_folder = self.config.current_folder().to_owned();
|
let current_folder = self.config.current_folder().to_owned();
|
||||||
|
|
||||||
Some(Box::pin(async move {
|
Some(Box::pin(async move {
|
||||||
let (background_service_config, outputs) = wallpaper::config();
|
let (wallpaper_service_config, outputs) = wallpaper::config();
|
||||||
|
|
||||||
let update = change_folder(current_folder).await;
|
let update = change_folder(current_folder).await;
|
||||||
|
|
||||||
crate::pages::Message::DesktopWallpaper(Message::Init(Box::new((
|
crate::pages::Message::DesktopWallpaper(Message::Init(Box::new((
|
||||||
background_service_config,
|
wallpaper_service_config,
|
||||||
outputs,
|
outputs,
|
||||||
update,
|
update,
|
||||||
))))
|
))))
|
||||||
|
|
@ -159,6 +195,7 @@ impl page::AutoBind<crate::pages::Message> for Page {}
|
||||||
impl Default for Page {
|
impl Default for Page {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let mut page = Page {
|
let mut page = Page {
|
||||||
|
active_dialog: ActiveDialog::None,
|
||||||
active_output: None,
|
active_output: None,
|
||||||
cached_display_handle: None,
|
cached_display_handle: None,
|
||||||
categories: {
|
categories: {
|
||||||
|
|
@ -166,7 +203,7 @@ impl Default for Page {
|
||||||
|
|
||||||
categories.insert(dropdown::multi::list(
|
categories.insert(dropdown::multi::list(
|
||||||
None,
|
None,
|
||||||
vec![(fl!("system-backgrounds"), Category::Backgrounds)],
|
vec![(fl!("wallpaper", "plural"), Category::Wallpapers)],
|
||||||
));
|
));
|
||||||
|
|
||||||
categories.insert(dropdown::multi::list(
|
categories.insert(dropdown::multi::list(
|
||||||
|
|
@ -174,16 +211,21 @@ impl Default for Page {
|
||||||
vec![(fl!("colors"), Category::Colors)],
|
vec![(fl!("colors"), Category::Colors)],
|
||||||
));
|
));
|
||||||
|
|
||||||
|
categories.insert(dropdown::multi::list(
|
||||||
|
None,
|
||||||
|
vec![(fl!("open-new-folder"), Category::AddFolder)],
|
||||||
|
));
|
||||||
|
|
||||||
categories.insert(dropdown::multi::list(
|
categories.insert(dropdown::multi::list(
|
||||||
Some(fl!("recent-folders")),
|
Some(fl!("recent-folders")),
|
||||||
Vec::with_capacity(5),
|
Vec::with_capacity(5),
|
||||||
));
|
));
|
||||||
|
|
||||||
categories.selected = Some(Category::Backgrounds);
|
categories.selected = Some(Category::Wallpapers);
|
||||||
|
|
||||||
categories
|
categories
|
||||||
},
|
},
|
||||||
background_service_config: wallpaper::Config::default(),
|
wallpaper_service_config: wallpaper::Config::default(),
|
||||||
color_dialog: window::Id::unique(),
|
color_dialog: window::Id::unique(),
|
||||||
color_model: ColorPickerModel::new(fl!("hex"), fl!("rgb"), None, Some(Color::WHITE)),
|
color_model: ColorPickerModel::new(fl!("hex"), fl!("rgb"), None, Some(Color::WHITE)),
|
||||||
config: Config::new(),
|
config: Config::new(),
|
||||||
|
|
@ -233,7 +275,7 @@ impl Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assign_recent_folders(&mut self) {
|
fn assign_recent_folders(&mut self) {
|
||||||
let recent_list = &mut self.categories.lists[2];
|
let recent_list = &mut self.categories.lists[3];
|
||||||
recent_list.options.clear();
|
recent_list.options.clear();
|
||||||
|
|
||||||
for (id, folder) in self.config.recent_folders().iter().enumerate() {
|
for (id, folder) in self.config.recent_folders().iter().enumerate() {
|
||||||
|
|
@ -248,7 +290,7 @@ impl Page {
|
||||||
|
|
||||||
fn cache_display_image(&mut self) {
|
fn cache_display_image(&mut self) {
|
||||||
let choice = match self.selection.active {
|
let choice = match self.selection.active {
|
||||||
Choice::Background(id) => self.selection.display_images.get(id),
|
Choice::Wallpaper(id) => self.selection.display_images.get(id),
|
||||||
|
|
||||||
Choice::Slideshow => self.selection.display_images.values().next(),
|
Choice::Slideshow => self.selection.display_images.values().next(),
|
||||||
|
|
||||||
|
|
@ -312,7 +354,7 @@ impl Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn config_output(&self) -> Option<String> {
|
fn config_output(&self) -> Option<String> {
|
||||||
if self.background_service_config.same_on_all {
|
if self.wallpaper_service_config.same_on_all {
|
||||||
Some(String::from("all"))
|
Some(String::from("all"))
|
||||||
} else {
|
} else {
|
||||||
self.outputs.active_data::<String>().cloned()
|
self.outputs.active_data::<String>().cloned()
|
||||||
|
|
@ -325,13 +367,13 @@ impl Page {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
if self.background_service_config.same_on_all {
|
if self.wallpaper_service_config.same_on_all {
|
||||||
self.background_service_config.outputs.clear();
|
self.wallpaper_service_config.outputs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
let entry = match self.selection.active {
|
let entry = match self.selection.active {
|
||||||
Choice::Slideshow => {
|
Choice::Slideshow => {
|
||||||
match self.config_background_entry(
|
match self.config_wallpaper_entry(
|
||||||
output.clone(),
|
output.clone(),
|
||||||
self.config.current_folder().to_path_buf(),
|
self.config.current_folder().to_path_buf(),
|
||||||
) {
|
) {
|
||||||
|
|
@ -339,9 +381,10 @@ impl Page {
|
||||||
None => return,
|
None => return,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Choice::Background(key) => {
|
|
||||||
|
Choice::Wallpaper(key) => {
|
||||||
if let Some(path) = self.selection.paths.get(key) {
|
if let Some(path) = self.selection.paths.get(key) {
|
||||||
match self.config_background_entry(output.clone(), path.clone()) {
|
match self.config_wallpaper_entry(output.clone(), path.clone()) {
|
||||||
Some(entry) => entry,
|
Some(entry) => entry,
|
||||||
None => return,
|
None => return,
|
||||||
}
|
}
|
||||||
|
|
@ -356,30 +399,30 @@ impl Page {
|
||||||
};
|
};
|
||||||
|
|
||||||
if output != "all" {
|
if output != "all" {
|
||||||
self.background_service_config.backgrounds.clear();
|
self.wallpaper_service_config.backgrounds.clear();
|
||||||
self.background_service_config.outputs.clear();
|
self.wallpaper_service_config.outputs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
wallpaper::set(&mut self.background_service_config, entry);
|
wallpaper::set(&mut self.wallpaper_service_config, entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Locate the ID of a background that's already stored in memory
|
/// Locate the ID of a wallpaper that's already stored in memory
|
||||||
fn background_id_from_path(&self, path: &Path) -> Option<DefaultKey> {
|
fn wallpaper_id_from_path(&self, path: &Path) -> Option<DefaultKey> {
|
||||||
self.selection
|
self.selection
|
||||||
.paths
|
.paths
|
||||||
.iter()
|
.iter()
|
||||||
.find(|(_id, background)| *background == path)
|
.find(|(_id, wallpaper)| *wallpaper == path)
|
||||||
.map(|(id, _)| id)
|
.map(|(id, _)| id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates configuration from the background service.
|
/// Updates configuration from the wallpaper service.
|
||||||
fn background_service_config_update(
|
fn wallpaper_service_config_update(
|
||||||
&mut self,
|
&mut self,
|
||||||
background_service_config: wallpaper::Config,
|
wallpaper_service_config: wallpaper::Config,
|
||||||
displays: HashMap<String, String>,
|
displays: HashMap<String, String>,
|
||||||
selection: Context,
|
selection: Context,
|
||||||
) {
|
) {
|
||||||
self.background_service_config = background_service_config;
|
self.wallpaper_service_config = wallpaper_service_config;
|
||||||
self.selection = selection;
|
self.selection = selection;
|
||||||
self.outputs.clear();
|
self.outputs.clear();
|
||||||
|
|
||||||
|
|
@ -400,43 +443,30 @@ impl Page {
|
||||||
self.outputs.activate(id);
|
self.outputs.activate(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.background_service_config.same_on_all
|
if self.wallpaper_service_config.same_on_all
|
||||||
|| self.background_service_config.backgrounds.is_empty()
|
|| self.wallpaper_service_config.backgrounds.is_empty()
|
||||||
{
|
{
|
||||||
let entry = self.background_service_config.default_background.clone();
|
let entry = self.wallpaper_service_config.default_background.clone();
|
||||||
self.select_background_entry(&entry);
|
self.select_wallpaper_entry(&entry);
|
||||||
|
|
||||||
if let Some(current) = entry_directory(self.config.current_folder(), &entry) {
|
|
||||||
if let Err(why) = self.config.set_current_folder(Some(current)) {
|
|
||||||
tracing::error!(?why, "cannot set current folder");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if let Some(data) = self.outputs.active_data::<String>() {
|
} else if let Some(data) = self.outputs.active_data::<String>() {
|
||||||
let mut backgrounds = Vec::new();
|
let mut wallpapers = Vec::new();
|
||||||
std::mem::swap(
|
std::mem::swap(
|
||||||
&mut self.background_service_config.backgrounds,
|
&mut self.wallpaper_service_config.backgrounds,
|
||||||
&mut backgrounds,
|
&mut wallpapers,
|
||||||
);
|
);
|
||||||
|
|
||||||
for background in &backgrounds {
|
for wallpaper in &wallpapers {
|
||||||
if &background.output == data {
|
if &wallpaper.output == data {
|
||||||
self.active_output = Some(data.clone());
|
self.active_output = Some(data.clone());
|
||||||
self.select_background_entry(background);
|
self.select_wallpaper_entry(wallpaper);
|
||||||
|
|
||||||
if let Some(current) = entry_directory(self.config.current_folder(), background)
|
|
||||||
{
|
|
||||||
if let Err(why) = self.config.set_current_folder(Some(current)) {
|
|
||||||
tracing::error!(?why, "cannot set current folder");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::mem::swap(
|
std::mem::swap(
|
||||||
&mut self.background_service_config.backgrounds,
|
&mut self.wallpaper_service_config.backgrounds,
|
||||||
&mut backgrounds,
|
&mut wallpapers,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -446,7 +476,7 @@ impl Page {
|
||||||
let mut command = Command::none();
|
let mut command = Command::none();
|
||||||
|
|
||||||
match category {
|
match category {
|
||||||
Category::Backgrounds => {
|
Category::Wallpapers => {
|
||||||
if self.config.current_folder.is_some() {
|
if self.config.current_folder.is_some() {
|
||||||
let _ = self.config.set_current_folder(None);
|
let _ = self.config.set_current_folder(None);
|
||||||
command = cosmic::command::future(async move {
|
command = cosmic::command::future(async move {
|
||||||
|
|
@ -457,7 +487,7 @@ impl Page {
|
||||||
))
|
))
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
self.select_first_background();
|
self.select_first_wallpaper();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -479,6 +509,19 @@ impl Page {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Category::AddFolder => {
|
||||||
|
self.active_dialog = ActiveDialog::AddFolder;
|
||||||
|
return cosmic::command::message(crate::Message::FileChooser(
|
||||||
|
crate::app::FileChooser::Open {
|
||||||
|
title: fl!("wallpaper", "folder-dialog"),
|
||||||
|
accept_label: fl!("dialog-add"),
|
||||||
|
include_directories: true,
|
||||||
|
modal: false,
|
||||||
|
multiple_files: false,
|
||||||
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.categories.selected = Some(category);
|
self.categories.selected = Some(category);
|
||||||
|
|
@ -493,7 +536,7 @@ impl Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Changes the slideshow background rotation frequency
|
/// Changes the slideshow wallpaper rotation frequency
|
||||||
pub fn change_rotation_frequency(&mut self, option: usize) {
|
pub fn change_rotation_frequency(&mut self, option: usize) {
|
||||||
self.selected_rotation = option;
|
self.selected_rotation = option;
|
||||||
|
|
||||||
|
|
@ -508,8 +551,8 @@ impl Page {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates configuration for background image.
|
/// Updates configuration for wallpaper image.
|
||||||
fn config_background_entry(&self, output: String, path: PathBuf) -> Option<Entry> {
|
fn config_wallpaper_entry(&self, output: String, path: PathBuf) -> Option<Entry> {
|
||||||
let scaling_mode = match self.selected_fit {
|
let scaling_mode = match self.selected_fit {
|
||||||
FIT => ScalingMode::Fit([0.0, 0.0, 0.0]),
|
FIT => ScalingMode::Fit([0.0, 0.0, 0.0]),
|
||||||
STRETCH => ScalingMode::Stretch,
|
STRETCH => ScalingMode::Stretch,
|
||||||
|
|
@ -589,13 +632,11 @@ impl Page {
|
||||||
let selection = context.selection_handles.remove(image);
|
let selection = context.selection_handles.remove(image);
|
||||||
|
|
||||||
if let Some(((display, selection), path)) = display.zip(selection).zip(path) {
|
if let Some(((display, selection), path)) = display.zip(selection).zip(path) {
|
||||||
let key = self.selection.paths.insert(path);
|
self.selection.add_custom_image(path, display, selection);
|
||||||
self.selection.display_images.insert(key, display);
|
|
||||||
self.selection.selection_handles.insert(key, selection);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.select_first_background();
|
self.select_first_wallpaper();
|
||||||
}
|
}
|
||||||
|
|
||||||
Message::ColorAddDialog => {
|
Message::ColorAddDialog => {
|
||||||
|
|
@ -622,14 +663,23 @@ impl Page {
|
||||||
tracing::error!(?path, ?why, "could add custom image to config");
|
tracing::error!(?path, ?why, "could add custom image to config");
|
||||||
}
|
}
|
||||||
|
|
||||||
self.selection.add_custom_image(path, display, selection);
|
self.selection.add_custom_image(
|
||||||
|
path,
|
||||||
|
display,
|
||||||
|
ImageHandle::from_pixels(
|
||||||
|
selection.width(),
|
||||||
|
selection.height(),
|
||||||
|
selection.into_vec(),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Message::ImageAddDialog => {
|
Message::ImageAddDialog => {
|
||||||
|
self.active_dialog = ActiveDialog::AddImage;
|
||||||
return cosmic::command::message(crate::Message::FileChooser(
|
return cosmic::command::message(crate::Message::FileChooser(
|
||||||
crate::app::FileChooser::Open {
|
crate::app::FileChooser::Open {
|
||||||
title: fl!("wallpaper-dialog-image"),
|
title: fl!("wallpaper", "image-dialog"),
|
||||||
accept_label: fl!("wallpaper-dialog-image", "accept"),
|
accept_label: fl!("dialog-add"),
|
||||||
include_directories: false,
|
include_directories: false,
|
||||||
modal: false,
|
modal: false,
|
||||||
multiple_files: false,
|
multiple_files: false,
|
||||||
|
|
@ -663,13 +713,13 @@ impl Page {
|
||||||
|
|
||||||
Message::RotationFrequency(pos) => self.change_rotation_frequency(pos),
|
Message::RotationFrequency(pos) => self.change_rotation_frequency(pos),
|
||||||
|
|
||||||
Message::SameBackground(value) => {
|
Message::SameWallpaper(value) => {
|
||||||
self.background_service_config.same_on_all = value;
|
self.wallpaper_service_config.same_on_all = value;
|
||||||
self.background_service_config.backgrounds.clear();
|
self.wallpaper_service_config.backgrounds.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
Message::Select(id) => {
|
Message::Select(id) => {
|
||||||
self.selection.active = Choice::Background(id);
|
self.selection.active = Choice::Wallpaper(id);
|
||||||
self.cache_display_image();
|
self.cache_display_image();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -678,12 +728,12 @@ impl Page {
|
||||||
self.selection.active = Choice::Slideshow;
|
self.selection.active = Choice::Slideshow;
|
||||||
self.cache_display_image();
|
self.cache_display_image();
|
||||||
} else {
|
} else {
|
||||||
self.select_first_background();
|
self.select_first_wallpaper();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Message::Init(update) => {
|
Message::Init(update) => {
|
||||||
self.background_service_config_update(update.0, update.1, update.2);
|
self.wallpaper_service_config_update(update.0, update.1, update.2);
|
||||||
self.config_apply();
|
self.config_apply();
|
||||||
|
|
||||||
// Sync custom colors from config.
|
// Sync custom colors from config.
|
||||||
|
|
@ -692,7 +742,7 @@ impl Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the default selection if an image was selected.
|
// Set the default selection if an image was selected.
|
||||||
if let Choice::Background(_) | Choice::Slideshow = self.selection.active {
|
if let Choice::Wallpaper(_) | Choice::Slideshow = self.selection.active {
|
||||||
let folder = self.config.current_folder();
|
let folder = self.config.current_folder();
|
||||||
for (id, recent) in self.config.recent_folders().iter().enumerate() {
|
for (id, recent) in self.config.recent_folders().iter().enumerate() {
|
||||||
if recent == folder {
|
if recent == folder {
|
||||||
|
|
@ -723,15 +773,15 @@ impl Page {
|
||||||
Command::none()
|
Command::none()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Selects the given background entry.
|
/// Selects the given wallpaper entry.
|
||||||
fn select_background_entry(&mut self, entry: &wallpaper::Entry) {
|
fn select_wallpaper_entry(&mut self, entry: &wallpaper::Entry) {
|
||||||
match entry.source {
|
match entry.source {
|
||||||
wallpaper::Source::Path(ref path) => {
|
wallpaper::Source::Path(ref path) => {
|
||||||
if path.is_dir() {
|
if path.is_dir() {
|
||||||
self.selection.active = Choice::Slideshow;
|
self.selection.active = Choice::Slideshow;
|
||||||
self.cache_display_image();
|
self.cache_display_image();
|
||||||
} else if let Some(entity) = self.background_id_from_path(path) {
|
} else if let Some(entity) = self.wallpaper_id_from_path(path) {
|
||||||
self.select_background(entry, entity, path.is_dir());
|
self.select_wallpaper(entry, entity, path.is_dir());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -743,25 +793,32 @@ impl Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Selects the first background from the wallpaper select options.
|
/// Selects the first wallpaper from the wallpaper select options.
|
||||||
fn select_first_background(&mut self) {
|
fn select_first_wallpaper(&mut self) {
|
||||||
let (entity, path) = match self.selection.custom_images.last() {
|
let (entity, path) = if let Some(Category::Wallpapers) = self.categories.selected {
|
||||||
Some(entity) => (*entity, &self.selection.paths[*entity]),
|
match self.selection.custom_images.last() {
|
||||||
None => match self.selection.paths.iter().next() {
|
Some(entity) => (*entity, &self.selection.paths[*entity]),
|
||||||
|
None => match self.selection.paths.iter().next() {
|
||||||
|
Some(value) => value,
|
||||||
|
None => return,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
match self.selection.paths.iter().next() {
|
||||||
Some(value) => value,
|
Some(value) => value,
|
||||||
None => return,
|
None => return,
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(output) = self.config_output() {
|
if let Some(output) = self.config_output() {
|
||||||
if let Some(entry) = self.config_background_entry(output, path.clone()) {
|
if let Some(entry) = self.config_wallpaper_entry(output, path.clone()) {
|
||||||
self.select_background(&entry, entity, path.is_dir());
|
self.select_wallpaper(&entry, entity, path.is_dir());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Selects the given background
|
/// Selects the given wallpaper
|
||||||
fn select_background(
|
fn select_wallpaper(
|
||||||
&mut self,
|
&mut self,
|
||||||
entry: &wallpaper::Entry,
|
entry: &wallpaper::Entry,
|
||||||
entity: DefaultKey,
|
entity: DefaultKey,
|
||||||
|
|
@ -770,7 +827,7 @@ impl Page {
|
||||||
self.selection.active = if is_slideshow {
|
self.selection.active = if is_slideshow {
|
||||||
Choice::Slideshow
|
Choice::Slideshow
|
||||||
} else {
|
} else {
|
||||||
Choice::Background(entity)
|
Choice::Wallpaper(entity)
|
||||||
};
|
};
|
||||||
|
|
||||||
match entry.scaling_mode {
|
match entry.scaling_mode {
|
||||||
|
|
@ -805,14 +862,14 @@ impl Page {
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
enum Choice {
|
enum Choice {
|
||||||
Background(DefaultKey),
|
Wallpaper(DefaultKey),
|
||||||
Color(wallpaper::Color),
|
Color(wallpaper::Color),
|
||||||
Slideshow,
|
Slideshow,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Choice {
|
impl Default for Choice {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::Background(DefaultKey::default())
|
Self::Wallpaper(DefaultKey::default())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -822,7 +879,7 @@ pub struct Context {
|
||||||
custom_images: Vec<DefaultKey>,
|
custom_images: Vec<DefaultKey>,
|
||||||
custom_colors: Vec<wallpaper::Color>,
|
custom_colors: Vec<wallpaper::Color>,
|
||||||
paths: SlotMap<DefaultKey, PathBuf>,
|
paths: SlotMap<DefaultKey, PathBuf>,
|
||||||
is_custom: SecondaryMap<DefaultKey, bool>,
|
is_custom: SecondaryMap<DefaultKey, ()>,
|
||||||
display_images: SecondaryMap<DefaultKey, image::RgbaImage>,
|
display_images: SecondaryMap<DefaultKey, image::RgbaImage>,
|
||||||
selection_handles: SecondaryMap<DefaultKey, ImageHandle>,
|
selection_handles: SecondaryMap<DefaultKey, ImageHandle>,
|
||||||
}
|
}
|
||||||
|
|
@ -834,15 +891,12 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_custom_image(&mut self, path: PathBuf, display: Image, selection: Image) {
|
fn add_custom_image(&mut self, path: PathBuf, display: Image, selection: ImageHandle) {
|
||||||
let key = self.paths.insert(path);
|
let key = self.paths.insert(path);
|
||||||
self.is_custom.insert(key, true);
|
self.is_custom.insert(key, ());
|
||||||
self.display_images.insert(key, display);
|
self.display_images.insert(key, display);
|
||||||
self.custom_images.push(key);
|
self.custom_images.push(key);
|
||||||
self.selection_handles.insert(
|
self.selection_handles.insert(key, selection);
|
||||||
key,
|
|
||||||
ImageHandle::from_pixels(selection.width(), selection.height(), selection.into_vec()),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_custom_color(&mut self, color: &wallpaper::Color) {
|
fn remove_custom_color(&mut self, color: &wallpaper::Color) {
|
||||||
|
|
@ -852,13 +906,14 @@ impl Context {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_custom_image(&mut self, image: DefaultKey) -> Option<PathBuf> {
|
fn remove_custom_image(&mut self, image: DefaultKey) -> Option<PathBuf> {
|
||||||
if let Some(true) = self.is_custom.remove(image) {
|
if self.is_custom.contains_key(image) {
|
||||||
if let Some(id) = self.custom_images.iter().position(|i| i == &image) {
|
if let Some(id) = self.custom_images.iter().position(|i| i == &image) {
|
||||||
self.custom_images.remove(id);
|
self.custom_images.remove(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.display_images.remove(image);
|
self.display_images.remove(image);
|
||||||
self.selection_handles.remove(image);
|
self.selection_handles.remove(image);
|
||||||
|
self.is_custom.remove(image);
|
||||||
return self.paths.remove(image);
|
return self.paths.remove(image);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -868,9 +923,9 @@ impl Context {
|
||||||
|
|
||||||
pub async fn change_folder(current_folder: PathBuf) -> Context {
|
pub async fn change_folder(current_folder: PathBuf) -> Context {
|
||||||
let mut update = Context::default();
|
let mut update = Context::default();
|
||||||
let mut backgrounds = wallpaper::load_each_from_path(current_folder);
|
let mut wallpapers = wallpaper::load_each_from_path(current_folder);
|
||||||
|
|
||||||
while let Some((path, display_image, selection_image)) = backgrounds.recv().await {
|
while let Some((path, display_image, selection_image)) = wallpapers.recv().await {
|
||||||
let id = update.paths.insert(path);
|
let id = update.paths.insert(path);
|
||||||
|
|
||||||
update.display_images.insert(id, display_image);
|
update.display_images.insert(id, display_image);
|
||||||
|
|
@ -916,14 +971,14 @@ pub fn settings() -> Section<crate::pages::Message> {
|
||||||
|
|
||||||
children.push(crate::widget::display_container(
|
children.push(crate::widget::display_container(
|
||||||
match page.selection.active {
|
match page.selection.active {
|
||||||
// Shows background options, with the slideshow toggle enabled
|
// Shows wallpaper options, with the slideshow toggle enabled
|
||||||
Choice::Slideshow => {
|
Choice::Slideshow => {
|
||||||
slideshow_enabled = true;
|
slideshow_enabled = true;
|
||||||
page.display_image_view()
|
page.display_image_view()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shows background options, with the slideshow toggle visible
|
// Shows wallpaper options, with the slideshow toggle visible
|
||||||
Choice::Background(_) => page.display_image_view(),
|
Choice::Wallpaper(_) => page.display_image_view(),
|
||||||
|
|
||||||
// Displays color options, and hides the slideshow toggle
|
// Displays color options, and hides the slideshow toggle
|
||||||
Choice::Color(ref color) => {
|
Choice::Color(ref color) => {
|
||||||
|
|
@ -938,7 +993,7 @@ pub fn settings() -> Section<crate::pages::Message> {
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
|
||||||
children.push(if page.background_service_config.same_on_all {
|
children.push(if page.wallpaper_service_config.same_on_all {
|
||||||
text(fl!("all-displays"))
|
text(fl!("all-displays"))
|
||||||
.font(cosmic::font::FONT_SEMIBOLD)
|
.font(cosmic::font::FONT_SEMIBOLD)
|
||||||
.horizontal_alignment(alignment::Horizontal::Center)
|
.horizontal_alignment(alignment::Horizontal::Center)
|
||||||
|
|
@ -955,7 +1010,7 @@ pub fn settings() -> Section<crate::pages::Message> {
|
||||||
.into()
|
.into()
|
||||||
});
|
});
|
||||||
|
|
||||||
let background_fit =
|
let wallpaper_fit =
|
||||||
cosmic::widget::dropdown(&page.fit_options, Some(page.selected_fit), Message::Fit);
|
cosmic::widget::dropdown(&page.fit_options, Some(page.selected_fit), Message::Fit);
|
||||||
|
|
||||||
children.push({
|
children.push({
|
||||||
|
|
@ -964,11 +1019,11 @@ pub fn settings() -> Section<crate::pages::Message> {
|
||||||
&*WALLPAPER_SAME,
|
&*WALLPAPER_SAME,
|
||||||
toggler(
|
toggler(
|
||||||
None,
|
None,
|
||||||
page.background_service_config.same_on_all,
|
page.wallpaper_service_config.same_on_all,
|
||||||
Message::SameBackground,
|
Message::SameWallpaper,
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
.add(settings::item(&*WALLPAPER_FIT, background_fit));
|
.add(settings::item(&*WALLPAPER_FIT, wallpaper_fit));
|
||||||
|
|
||||||
if show_slideshow_toggle {
|
if show_slideshow_toggle {
|
||||||
column = column.add(settings::item(
|
column = column.add(settings::item(
|
||||||
|
|
@ -997,38 +1052,50 @@ pub fn settings() -> Section<crate::pages::Message> {
|
||||||
let category_selection =
|
let category_selection =
|
||||||
dropdown::multi::dropdown(&page.categories, Message::ChangeCategory);
|
dropdown::multi::dropdown(&page.categories, Message::ChangeCategory);
|
||||||
|
|
||||||
let add_button = {
|
// Show the add button only on the Colors and Wallpapers pages
|
||||||
let (text, message) = if Some(Category::Colors) == page.categories.selected {
|
let add_button =
|
||||||
(fl!("add-color"), Message::ColorAddDialog)
|
if let Some(Category::Colors | Category::Wallpapers) = page.categories.selected {
|
||||||
} else {
|
let (text, message) = if Some(Category::Colors) == page.categories.selected {
|
||||||
(fl!("add-image"), Message::ImageAddDialog)
|
(fl!("add-color"), Message::ColorAddDialog)
|
||||||
};
|
} else {
|
||||||
|
(fl!("add-image"), Message::ImageAddDialog)
|
||||||
|
};
|
||||||
|
|
||||||
button::link(text)
|
let button = button::link(text).trailing_icon(true).on_press(message);
|
||||||
.trailing_icon(true)
|
|
||||||
.on_press(message)
|
Some(button)
|
||||||
.apply(cosmic::widget::container)
|
} else {
|
||||||
.align_y(alignment::Vertical::Bottom)
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
children.push(
|
children.push(
|
||||||
row::with_capacity(2)
|
row::with_capacity(2)
|
||||||
|
.align_items(Alignment::Center)
|
||||||
|
// Show a folder icon if the active category is a custom folder.
|
||||||
|
.push_maybe(
|
||||||
|
if let Some(Category::RecentFolder(_)) = page.categories.selected {
|
||||||
|
Some(icon::from_name("folder-symbolic").size(16).icon())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
},
|
||||||
|
)
|
||||||
.push(category_selection)
|
.push(category_selection)
|
||||||
.push(cosmic::widget::horizontal_space(Length::Fill))
|
.push(cosmic::widget::horizontal_space(Length::Fill))
|
||||||
.push(add_button)
|
.push_maybe(add_button)
|
||||||
.into(),
|
.into(),
|
||||||
);
|
);
|
||||||
|
|
||||||
match page.categories.selected {
|
match page.categories.selected {
|
||||||
// Displays system wallpapers that are available to select from
|
// Displays system wallpapers that are available to select from
|
||||||
Some(Category::Backgrounds | Category::RecentFolder(_)) => {
|
Some(Category::Wallpapers | Category::RecentFolder(_)) => {
|
||||||
children.push(widgets::wallpaper_select_options(
|
children.push(widgets::wallpaper_select_options(
|
||||||
page,
|
page,
|
||||||
if let Choice::Background(selection) = page.selection.active {
|
if let Choice::Wallpaper(selection) = page.selection.active {
|
||||||
Some(selection)
|
Some(selection)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
},
|
},
|
||||||
|
matches!(page.categories.selected, Some(Category::Wallpapers)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1044,7 +1111,7 @@ pub fn settings() -> Section<crate::pages::Message> {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
None => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
||||||
cosmic::widget::column::with_children(children)
|
cosmic::widget::column::with_children(children)
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ const COLUMN_SPACING: u16 = 12;
|
||||||
const ROW_SPACING: u16 = 16;
|
const ROW_SPACING: u16 = 16;
|
||||||
|
|
||||||
/// A button for selecting a color or gradient.
|
/// A button for selecting a color or gradient.
|
||||||
|
#[must_use]
|
||||||
pub fn color_button(
|
pub fn color_button(
|
||||||
color: wallpaper::Color,
|
color: wallpaper::Color,
|
||||||
removable: bool,
|
removable: bool,
|
||||||
|
|
@ -36,6 +37,7 @@ pub fn color_button(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A sized container that's filled with a color or gradient.
|
/// A sized container that's filled with a color or gradient.
|
||||||
|
#[must_use]
|
||||||
pub fn color_image<'a, M: 'a>(
|
pub fn color_image<'a, M: 'a>(
|
||||||
color: wallpaper::Color,
|
color: wallpaper::Color,
|
||||||
width: u16,
|
width: u16,
|
||||||
|
|
@ -78,6 +80,7 @@ pub fn color_image<'a, M: 'a>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Color selection list
|
/// Color selection list
|
||||||
|
#[must_use]
|
||||||
pub fn color_select_options(
|
pub fn color_select_options(
|
||||||
context: &super::Context,
|
context: &super::Context,
|
||||||
selected: Option<&wallpaper::Color>,
|
selected: Option<&wallpaper::Color>,
|
||||||
|
|
@ -106,22 +109,26 @@ pub fn color_select_options(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Background selection list
|
/// Background selection list
|
||||||
|
#[must_use]
|
||||||
pub fn wallpaper_select_options(
|
pub fn wallpaper_select_options(
|
||||||
page: &super::Page,
|
page: &super::Page,
|
||||||
selected: Option<DefaultKey>,
|
selected: Option<DefaultKey>,
|
||||||
|
show_custom_images: bool,
|
||||||
) -> Element<Message> {
|
) -> Element<Message> {
|
||||||
let mut vec = Vec::with_capacity(page.selection.selection_handles.len());
|
let mut vec = Vec::with_capacity(page.selection.selection_handles.len());
|
||||||
|
|
||||||
// Place removable custom images first
|
if show_custom_images {
|
||||||
for id in page.selection.custom_images.iter().rev() {
|
// Place removable custom images first
|
||||||
let handle = &page.selection.selection_handles[*id];
|
for id in page.selection.custom_images.iter().rev() {
|
||||||
|
let handle = &page.selection.selection_handles[*id];
|
||||||
|
|
||||||
vec.push(wallpaper_button(
|
vec.push(wallpaper_button(
|
||||||
handle,
|
handle,
|
||||||
*id,
|
*id,
|
||||||
true,
|
true,
|
||||||
selected.map_or(false, |selection| id == &selection),
|
selected.map_or(false, |selection| id == &selection),
|
||||||
));
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then place non-removable images from the current folder
|
// Then place non-removable images from the current folder
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,6 @@ all-displays = Všechny monitory
|
||||||
colors = Barvy
|
colors = Barvy
|
||||||
fit-to-screen = Vyplnit obrazovku
|
fit-to-screen = Vyplnit obrazovku
|
||||||
stretch = Roztáhnout
|
stretch = Roztáhnout
|
||||||
system-backgrounds = Systémové pozadí
|
|
||||||
zoom = Přiblížení
|
zoom = Přiblížení
|
||||||
|
|
||||||
x-minutes = { $number } minut
|
x-minutes = { $number } minut
|
||||||
|
|
|
||||||
|
|
@ -144,25 +144,26 @@ panel-missing = Panel Configuration is Missing
|
||||||
## Desktop: Wallpaper
|
## Desktop: Wallpaper
|
||||||
|
|
||||||
wallpaper = Wallpaper
|
wallpaper = Wallpaper
|
||||||
.desc = Background images, colors, and slideshow options.
|
|
||||||
.same = Same background on all displays
|
|
||||||
.fit = Background fit
|
|
||||||
.slide = Slideshow
|
|
||||||
.change = Change image every
|
.change = Change image every
|
||||||
|
.desc = Wallpaper images, colors, and slideshow options.
|
||||||
|
.fit = Wallpaper fit
|
||||||
|
.folder-dialog = Choose wallpaper folder
|
||||||
|
.image-dialog = Choose wallpaper image
|
||||||
|
.plural = Wallpapers
|
||||||
|
.same = Same wallpaper on all displays
|
||||||
|
.slide = Slideshow
|
||||||
|
|
||||||
add-color = Add color
|
add-color = Add color
|
||||||
add-image = Add image
|
add-image = Add image
|
||||||
all-displays = All Displays
|
all-displays = All Displays
|
||||||
colors = Colors
|
colors = Colors
|
||||||
|
dialog-add = _Add
|
||||||
fit-to-screen = Fit to Screen
|
fit-to-screen = Fit to Screen
|
||||||
|
open-new-folder = Open new folder
|
||||||
recent-folders = Recent Folders
|
recent-folders = Recent Folders
|
||||||
stretch = Stretch
|
stretch = Stretch
|
||||||
system-backgrounds = System backgrounds
|
|
||||||
zoom = Zoom
|
zoom = Zoom
|
||||||
|
|
||||||
wallpaper-dialog-image = Choose wallpaper image
|
|
||||||
.accept = _Add
|
|
||||||
|
|
||||||
x-minutes = { $number } minutes
|
x-minutes = { $number } minutes
|
||||||
x-hours = { $number ->
|
x-hours = { $number ->
|
||||||
[1] 1 hour
|
[1] 1 hour
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,6 @@ all-displays = Tutti gli Schermi
|
||||||
colors = Colori
|
colors = Colori
|
||||||
fit-to-screen = Adatta allo Schermo
|
fit-to-screen = Adatta allo Schermo
|
||||||
stretch = Allarga
|
stretch = Allarga
|
||||||
system-backgrounds = Sfondi di sistema
|
|
||||||
zoom = Zoom
|
zoom = Zoom
|
||||||
|
|
||||||
x-minutes = { $number } minuti
|
x-minutes = { $number } minuti
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,6 @@ all-displays = Все экраны
|
||||||
colors = Цвета
|
colors = Цвета
|
||||||
fit-to-screen = Подгонять под экран
|
fit-to-screen = Подгонять под экран
|
||||||
stretch = Растянуть
|
stretch = Растянуть
|
||||||
system-backgrounds = Системные фоны
|
|
||||||
zoom = Увеличить
|
zoom = Увеличить
|
||||||
|
|
||||||
x-minutes = { $number } минут
|
x-minutes = { $number } минут
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,6 @@ all-displays = Сви екрани
|
||||||
colors = Боје
|
colors = Боје
|
||||||
fit-to-screen = Уклопи у екран
|
fit-to-screen = Уклопи у екран
|
||||||
stretch = Развуци
|
stretch = Развуци
|
||||||
system-backgrounds = Системске позадине
|
|
||||||
zoom = Увећај
|
zoom = Увећај
|
||||||
|
|
||||||
x-minutes = { $number } мин.
|
x-minutes = { $number } мин.
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,6 @@ all-displays = Svi ekrani
|
||||||
colors = Boje
|
colors = Boje
|
||||||
fit-to-screen = Uklopi u ekran
|
fit-to-screen = Uklopi u ekran
|
||||||
stretch = Razvuci
|
stretch = Razvuci
|
||||||
system-backgrounds = Sistemske pozadine
|
|
||||||
zoom = Uvećaj
|
zoom = Uvećaj
|
||||||
|
|
||||||
x-minutes = { $number } min.
|
x-minutes = { $number } min.
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,6 @@ all-displays = Tüm Ekranlar
|
||||||
colors = Renkler
|
colors = Renkler
|
||||||
fit-to-screen = Ekrana Sığdır
|
fit-to-screen = Ekrana Sığdır
|
||||||
stretch = Uzat
|
stretch = Uzat
|
||||||
system-backgrounds = Sistem duvar kağıtları
|
|
||||||
zoom = Yakınlaştır
|
zoom = Yakınlaştır
|
||||||
|
|
||||||
x-minutes = { $number } dakika
|
x-minutes = { $number } dakika
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,6 @@ all-displays = 所有顯示器
|
||||||
colors = 顏色
|
colors = 顏色
|
||||||
fit-to-screen = 延伸至全螢幕
|
fit-to-screen = 延伸至全螢幕
|
||||||
stretch = 延伸
|
stretch = 延伸
|
||||||
system-backgrounds = 系統背景
|
|
||||||
zoom = 縮放
|
zoom = 縮放
|
||||||
|
|
||||||
x-minutes = { $number } 分鐘
|
x-minutes = { $number } 分鐘
|
||||||
|
|
|
||||||
|
|
@ -69,12 +69,6 @@ pub fn config() -> (Config, HashMap<String, String>) {
|
||||||
|
|
||||||
pub fn set(config: &mut Config, entry: Entry) {
|
pub fn set(config: &mut Config, entry: Entry) {
|
||||||
if let Ok(context) = Config::helper() {
|
if let Ok(context) = Config::helper() {
|
||||||
tracing::debug!(
|
|
||||||
output = entry.output.to_string(),
|
|
||||||
source = ?entry.source,
|
|
||||||
"setting wallpaper",
|
|
||||||
);
|
|
||||||
|
|
||||||
let _res = Config::set_same_on_all(&context, config.same_on_all);
|
let _res = Config::set_same_on_all(&context, config.same_on_all);
|
||||||
|
|
||||||
if let Err(why) = config.set_entry(&context, entry) {
|
if let Err(why) = config.set_entry(&context, entry) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue