uh... converter?

This commit is contained in:
2026-05-11 16:20:51 +02:00
parent 200e76b899
commit 2903819626
12 changed files with 148 additions and 4415 deletions
+15 -70
View File
@@ -1,5 +1,4 @@
use anyhow::{Context, Result};
use directories::ProjectDirs;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
@@ -7,50 +6,19 @@ use std::path::PathBuf;
/// Serialized to/from ~/.config/rs-pictures/config.toml
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Config {
/// Directory where screenshots are saved.
pub save_directory: PathBuf,
/// File format for saved screenshots: "png" or "jpeg".
pub save_format: String,
/// Filename template. Supports strftime-style tokens via chrono.
/// Example: "screenshot_%Y-%m-%d_%H-%M-%S"
pub filename_template: String,
/// When true, automatically save to disk after capture without opening
/// the review window.
#[serde(default)]
pub auto_save: bool,
/// When true, automatically copy to the clipboard after capture without
/// opening the review window.
#[serde(default)]
pub auto_copy: bool,
/// Milliseconds to wait after launch before capturing the desktop snapshot.
/// Increase this if the overlay background still shows the terminal/launcher
/// that started rs-pictures. Default: 200.
#[serde(default = "default_capture_delay_ms")]
pub capture_delay_ms: u64,
/// If true, the selection overlay will be transparent (live preview) instead of
/// a frozen screenshot. The final capture happens after selection.
#[serde(default)]
pub live_mode: bool,
/// Visual effects applied after capture.
/// Visual effects applied to images.
pub effects: EffectsConfig,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EffectsConfig {
/// Apply rounded corners to the screenshot.
/// Apply rounded corners to the image.
pub rounded_corners: bool,
/// Radius in pixels for rounded corners.
pub corner_radius: f32,
/// Apply a drop shadow beneath the screenshot.
/// Apply a drop shadow beneath the image.
pub drop_shadow: bool,
/// Blur radius for the drop shadow (higher = softer shadow).
@@ -82,28 +50,25 @@ impl Default for EffectsConfig {
impl Default for Config {
fn default() -> Self {
let save_directory = dirs_default_pictures().unwrap_or_else(|| PathBuf::from("."));
Self {
save_directory,
save_format: "png".into(),
filename_template: "screenshot_%Y-%m-%d_%H-%M-%S".into(),
auto_save: false,
auto_copy: false,
capture_delay_ms: default_capture_delay_ms(),
live_mode: false,
effects: EffectsConfig::default(),
}
}
}
impl Config {
/// Returns the path to the config file, creating parent directories if needed.
/// Returns the path to the config file: ~/.config/rs-pictures/config.toml
pub fn config_path() -> Option<PathBuf> {
ProjectDirs::from("", "", "rs-pictures")
.map(|pd| pd.config_dir().join("config.toml"))
let home = std::env::var("HOME").ok()?;
Some(
PathBuf::from(home)
.join(".config")
.join("rs-pictures")
.join("config.toml"),
)
}
/// Load config from disk, or return the default config if the file doesn't exist.
/// Load config from disk, or write and return the default config if the file doesn't exist.
pub fn load() -> Result<Self> {
let path = match Self::config_path() {
Some(p) => p,
@@ -125,39 +90,19 @@ impl Config {
/// Persist the current config to disk.
pub fn save(&self) -> Result<()> {
let path = Self::config_path()
.context("Could not determine config directory")?;
let path =
Self::config_path().context("Could not determine config directory (HOME not set)")?;
if let Some(parent) = path.parent() {
std::fs::create_dir_all(parent)
.with_context(|| format!("Failed to create config dir {}", parent.display()))?;
}
let serialized = toml::to_string_pretty(self)
.context("Failed to serialize config")?;
let serialized = toml::to_string_pretty(self).context("Failed to serialize config")?;
std::fs::write(&path, serialized)
.with_context(|| format!("Failed to write config to {}", path.display()))?;
Ok(())
}
/// Build the full output path for a new screenshot using chrono formatting.
pub fn output_path(&self) -> PathBuf {
let now = chrono::Local::now();
let filename = now.format(&self.filename_template).to_string();
let ext = &self.save_format;
self.save_directory.join(format!("{filename}.{ext}"))
}
}
fn default_capture_delay_ms() -> u64 { 200 }
fn dirs_default_pictures() -> Option<PathBuf> {
// Use XDG_PICTURES_DIR if available, otherwise ~/Pictures
if let Ok(val) = std::env::var("XDG_PICTURES_DIR") {
return Some(PathBuf::from(val));
}
directories::UserDirs::new()
.and_then(|ud| ud.picture_dir().map(|p| p.to_path_buf()))
}