Set scaling mode from args and configs
This commit is contained in:
parent
84186d3d66
commit
7fc8c0051f
@ -7,7 +7,7 @@ use std::path::PathBuf;
|
|||||||
#[derive(Debug, Deserialize, Serialize)]
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub background_image: String,
|
pub background_image: String,
|
||||||
pub mode: Option<String>, // Unused now, deal with it later
|
pub mode: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use anyhow::Result;
|
use anyhow::{Context, Result};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use crate::{args, config, wallpaper};
|
use crate::{args, config, wallpaper};
|
||||||
@ -12,6 +12,13 @@ pub fn resolve_wallpaper(
|
|||||||
args: &args::Args,
|
args: &args::Args,
|
||||||
config: Option<config::Config>,
|
config: Option<config::Config>,
|
||||||
) -> Result<WallpaperSettings> {
|
) -> Result<WallpaperSettings> {
|
||||||
|
// Borrow the config once as `Option<&Config>`.
|
||||||
|
//
|
||||||
|
// Avoids moving `config`, allows to:
|
||||||
|
// - read values multiple times
|
||||||
|
// - decide later whether we need to write a new config
|
||||||
|
let cfg_ref = config.as_ref();
|
||||||
|
|
||||||
// Resolve wallpaper image path by precedence:
|
// Resolve wallpaper image path by precedence:
|
||||||
// 1. args (`--set`, `--update`): Use path from args.
|
// 1. args (`--set`, `--update`): Use path from args.
|
||||||
// 2. config: Use path from config.
|
// 2. config: Use path from config.
|
||||||
@ -21,10 +28,16 @@ pub fn resolve_wallpaper(
|
|||||||
|
|
||||||
// Case: arg `--update`. Persist wallpaper path to config (create if missing), then apply it.
|
// Case: arg `--update`. Persist wallpaper path to config (create if missing), then apply it.
|
||||||
(None, Some(path)) => {
|
(None, Some(path)) => {
|
||||||
let cfg = config.unwrap_or_else(|| config::Config {
|
// Use existing config if present.
|
||||||
background_image: String::new(),
|
// Otherwise, create a minimal temporary config only for writing.
|
||||||
mode: None,
|
// Avoids moving or cloning the original config, keeps ownership simple.
|
||||||
});
|
let cfg = match cfg_ref {
|
||||||
|
Some(cfg) => cfg,
|
||||||
|
None => &config::Config {
|
||||||
|
background_image: String::new(),
|
||||||
|
mode: None,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
// Write to config.
|
// Write to config.
|
||||||
cfg.update_background_image(
|
cfg.update_background_image(
|
||||||
@ -37,21 +50,42 @@ pub fn resolve_wallpaper(
|
|||||||
|
|
||||||
// Case: No args. Fallback to config file.
|
// Case: No args. Fallback to config file.
|
||||||
(None, None) => {
|
(None, None) => {
|
||||||
let cfg = config.ok_or_else(|| {
|
let cfg = cfg_ref.ok_or_else(|| {
|
||||||
// No CLI args and no valid config.
|
// No CLI args and no valid config.
|
||||||
anyhow::anyhow!("No or invalid image path specified in config or args.")
|
anyhow::anyhow!("No or invalid image path specified in config or args.")
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// Successfully loaded.
|
// Successfully loaded.
|
||||||
cfg.background_image.into()
|
cfg.background_image.clone().into()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Case: Both args `--set` & `--update`. This case is already rejected during argument parsing.
|
// Case: Both args `--set` & `--update`. This case is already rejected during argument parsing.
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
//let mode = wallpaper::ScalingMode::Stretch; //
|
// Resolve scaling mode by precedence:
|
||||||
let mode = wallpaper::ScalingMode::Fill; // Default
|
// 1. CLI argument (`--mode`) if provided
|
||||||
|
// 2. Config file value if present
|
||||||
|
// 3. Default to Fill
|
||||||
|
let mode = if let Some(mode_arg) = &args.mode {
|
||||||
|
// CLI has highest priority
|
||||||
|
mode_arg
|
||||||
|
.parse::<wallpaper::ScalingMode>()
|
||||||
|
.with_context(|| "Invalid wallpaper mode in CLI")?
|
||||||
|
} else if let Some(cfg) = cfg_ref {
|
||||||
|
if let Some(mode_str) = &cfg.mode {
|
||||||
|
// Config-specified mode
|
||||||
|
mode_str
|
||||||
|
.parse::<wallpaper::ScalingMode>()
|
||||||
|
.with_context(|| "Invalid wallpaper mode in config")?
|
||||||
|
} else {
|
||||||
|
// Config exists, but mode not specified
|
||||||
|
wallpaper::ScalingMode::Fill
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// No CLI and no config → default
|
||||||
|
wallpaper::ScalingMode::Fill
|
||||||
|
};
|
||||||
|
|
||||||
Ok(WallpaperSettings { path, mode })
|
Ok(WallpaperSettings { path, mode })
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +1,26 @@
|
|||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use image::{RgbaImage, imageops};
|
use image::{RgbaImage, imageops};
|
||||||
use std::path::Path;
|
use std::{path::Path, str::FromStr};
|
||||||
|
|
||||||
/// Supported wallpaper scaling modes.
|
/// Supported wallpaper scaling modes.
|
||||||
///
|
|
||||||
/// Others are defined so the public API does not need to change later.
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum ScalingMode {
|
pub enum ScalingMode {
|
||||||
Stretch,
|
Stretch,
|
||||||
Fill,
|
Fill,
|
||||||
// Fit,
|
}
|
||||||
|
|
||||||
|
impl FromStr for ScalingMode {
|
||||||
|
type Err = anyhow::Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> Result<Self> {
|
||||||
|
// Accept human-friendly strings from CLI / config.
|
||||||
|
// Case-insensitive to reduce user friction.
|
||||||
|
match s.to_lowercase().as_str() {
|
||||||
|
"fill" => Ok(ScalingMode::Fill),
|
||||||
|
"stretch" => Ok(ScalingMode::Stretch),
|
||||||
|
_ => Err(anyhow::anyhow!("Invalid wallpaper mode: {s}")),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Result of preparing a wallpaper image for the screen.
|
/// Result of preparing a wallpaper image for the screen.
|
||||||
@ -116,9 +127,10 @@ pub fn prepare_wallpaper(
|
|||||||
.with_context(|| format!("Failed to open image: {}", image_path.display()))?
|
.with_context(|| format!("Failed to open image: {}", image_path.display()))?
|
||||||
.to_rgba8();
|
.to_rgba8();
|
||||||
|
|
||||||
|
// Scaling mode
|
||||||
let prepared = match mode {
|
let prepared = match mode {
|
||||||
|
ScalingMode::Fill => prepare_fill(&img, screen_width, screen_height), // Default
|
||||||
ScalingMode::Stretch => prepare_stretch(&img, screen_width, screen_height),
|
ScalingMode::Stretch => prepare_stretch(&img, screen_width, screen_height),
|
||||||
ScalingMode::Fill => prepare_fill(&img, screen_width, screen_height),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(prepared)
|
Ok(prepared)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user