feat(wallpaper): custom background images and folders
This commit is contained in:
parent
f3e929e769
commit
daa730682a
10 changed files with 928 additions and 250 deletions
194
app/src/pages/desktop/wallpaper/config.rs
Normal file
194
app/src/pages/desktop/wallpaper/config.rs
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
// Copyright 2023 System76 <info@system76.com>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use cosmic::cosmic_config::{self, ConfigGet, ConfigSet};
|
||||
use cosmic_settings_desktop::wallpaper;
|
||||
use std::collections::VecDeque;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
const NAME: &str = "com.system76.CosmicSettings.Wallpaper";
|
||||
const VERSION: u64 = 1;
|
||||
const CURRENT_FOLDER: &str = "current-folder";
|
||||
const CUSTOM_COLORS: &str = "custom-colors";
|
||||
const CUSTOM_IMAGES: &str = "custom-images";
|
||||
const RECENT_FOLDERS: &str = "recent-folders";
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct Config {
|
||||
context: Option<cosmic_config::Config>,
|
||||
current_folder: Option<PathBuf>,
|
||||
custom_colors: Vec<wallpaper::Color>,
|
||||
custom_images: Vec<PathBuf>,
|
||||
recent_folders: VecDeque<PathBuf>,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub fn new() -> Self {
|
||||
let mut config = Self::default();
|
||||
|
||||
let context = match cosmic_config::Config::new(NAME, VERSION) {
|
||||
Ok(context) => context,
|
||||
Err(why) => {
|
||||
tracing::warn!(?why, "failed to get config");
|
||||
return Self::default();
|
||||
}
|
||||
};
|
||||
|
||||
if let Ok(path) = dbg!(context.get::<PathBuf>(CURRENT_FOLDER)) {
|
||||
config.current_folder = Some(path);
|
||||
}
|
||||
|
||||
if let Ok(colors) = context.get::<Vec<wallpaper::Color>>(CUSTOM_COLORS) {
|
||||
config.custom_colors = colors;
|
||||
}
|
||||
|
||||
if let Ok(images) = context.get::<Vec<PathBuf>>(CUSTOM_IMAGES) {
|
||||
config.custom_images = images;
|
||||
}
|
||||
|
||||
if let Ok(folders) = dbg!(context.get::<VecDeque<PathBuf>>(RECENT_FOLDERS)) {
|
||||
config.recent_folders = folders;
|
||||
}
|
||||
|
||||
config.context = Some(context);
|
||||
|
||||
config
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn current_folder(&self) -> &Path {
|
||||
self.current_folder
|
||||
.as_deref()
|
||||
.unwrap_or(Path::new("/usr/share/backgrounds/"))
|
||||
}
|
||||
|
||||
/// Sets the current background folder
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the on-disk configuration could not be updated.
|
||||
pub fn set_current_folder(&mut self, folder: PathBuf) -> Result<(), cosmic_config::Error> {
|
||||
let result = self.update(CURRENT_FOLDER, &folder);
|
||||
self.current_folder = Some(folder);
|
||||
result
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn custom_colors(&self) -> &[wallpaper::Color] {
|
||||
&self.custom_colors
|
||||
}
|
||||
|
||||
/// Adds a custom color
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the on-disk configuration could not be updated.
|
||||
pub fn add_custom_color(
|
||||
&mut self,
|
||||
color: wallpaper::Color,
|
||||
) -> Result<(), cosmic_config::Error> {
|
||||
if !self.custom_colors.contains(&color) {
|
||||
self.custom_colors.push(color);
|
||||
return self.update_custom_colors();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Removes custom background colors.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the on-disk configuration could not be updated.
|
||||
pub fn remove_custom_color(
|
||||
&mut self,
|
||||
color: &wallpaper::Color,
|
||||
) -> Result<(), cosmic_config::Error> {
|
||||
if let Some(position) = self.custom_colors.iter().position(|c| c == color) {
|
||||
self.custom_colors.remove(position);
|
||||
return self.update_custom_colors();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn custom_images(&self) -> &[PathBuf] {
|
||||
&self.custom_images
|
||||
}
|
||||
|
||||
/// Adds a custom background image
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the on-disk configuration could not be updated.
|
||||
pub fn add_custom_image(&mut self, image: PathBuf) -> Result<(), cosmic_config::Error> {
|
||||
if !self.custom_images.contains(&image) {
|
||||
self.custom_images.push(image);
|
||||
return self.update_custom_images();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Removes custom background images.
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the on-disk configuration could not be updated.
|
||||
pub fn remove_custom_image(&mut self, image: &Path) -> Result<(), cosmic_config::Error> {
|
||||
if let Some(position) = self.custom_images.iter().position(|p| p == image) {
|
||||
self.custom_images.remove(position);
|
||||
return self.update_custom_images();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn recent_folders(&self) -> &VecDeque<PathBuf> {
|
||||
&self.recent_folders
|
||||
}
|
||||
|
||||
/// Adds a folder to the recent folders list
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// Returns an error if the on-disk configuration could not be updated.
|
||||
pub fn add_recent_folder(&mut self, folder: PathBuf) -> Result<(), cosmic_config::Error> {
|
||||
while self.recent_folders.len() > 4 {
|
||||
self.recent_folders.pop_front();
|
||||
}
|
||||
|
||||
if !self.recent_folders.contains(&folder) {
|
||||
self.recent_folders.push_back(folder);
|
||||
return self.update_recent_folders();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn update<V: serde::Serialize>(
|
||||
&self,
|
||||
key: &str,
|
||||
value: &V,
|
||||
) -> Result<(), cosmic_config::Error> {
|
||||
if let Some(context) = self.context.as_ref() {
|
||||
context.set(key, value)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn update_custom_colors(&self) -> Result<(), cosmic_config::Error> {
|
||||
self.update(CUSTOM_COLORS, &self.custom_colors)
|
||||
}
|
||||
|
||||
fn update_custom_images(&self) -> Result<(), cosmic_config::Error> {
|
||||
self.update(CUSTOM_IMAGES, &self.custom_images)
|
||||
}
|
||||
|
||||
fn update_recent_folders(&self) -> Result<(), cosmic_config::Error> {
|
||||
self.update(RECENT_FOLDERS, &self.recent_folders)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue