Skip to content

Commit

Permalink
refactor: store animation values in window struct
Browse files Browse the repository at this point in the history
  • Loading branch information
decipher3114 committed Sep 27, 2024
1 parent cecfed9 commit fed81b3
Show file tree
Hide file tree
Showing 11 changed files with 85 additions and 117 deletions.
3 changes: 2 additions & 1 deletion src/entities/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ pub struct App {
#[derive(Debug, Clone)]
pub enum AppEvent {
OpenConfigureWindow,
UpdateConfig(Id),
OpenDirectory,
UpdateDirectory(Id),
OpenCropWindow,
CaptureFullscreen,
CaptureWindow,
Expand Down
14 changes: 2 additions & 12 deletions src/entities/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,15 @@ use serde::{Deserialize, Serialize};

use crate::entities::theme::Theme;

#[derive(Debug, Clone)]
pub struct Config {
pub theme: Spring<Theme>,
pub directory: String,
}

/// The configuration that gets serialized to disk.
/// This is distinct to avoid serializing animated values.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StoredConfig {
#[serde(default)]
pub struct Config {
pub theme: Theme,
#[serde(default = "Config::default_path")]
pub directory: String,
}

#[derive(Debug)]
pub struct ConfigureWindow {
pub config: Config,
pub theme: Spring<Theme>,
pub path: String,
}

Expand Down
46 changes: 30 additions & 16 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

mod assets;
mod entities;
mod style;
mod theme;
mod utils;
mod windows;

Expand All @@ -11,7 +11,7 @@ use std::collections::BTreeMap;
use assets::{APPNAME, FONT_BOLD, FONT_MEDIUM, ICON, MEDIUM};
use entities::{
app::{App, AppEvent},
config::{Config, ConfigEvent, ConfigureWindow},
config::{Config, ConfigureWindow},
crop::CropWindow,
theme::Theme,
window::WindowType,
Expand All @@ -28,13 +28,13 @@ use iced::{
},
Size, Subscription, Task,
};
use iced_anim::Animation;
use interprocess::local_socket::{traits::Stream, GenericNamespaced, ToNsName};
use style::Element;
use theme::Element;
use utils::{
capture::{fullscreen::capture_fullscreen, window::capture_window},
ipc::ipc,
key_listener::global_key_listener,
shorten_path,
tray_icon::{tray_icon, tray_icon_listener, tray_menu_listener},
};

Expand Down Expand Up @@ -72,8 +72,12 @@ impl App {
)
}

pub fn title(&self, _id: Id) -> String {
String::from("Capter")
pub fn title(&self, id: Id) -> String {
match self.windows.get(&id) {
Some(WindowType::ConfigureWindow(_)) => String::from("Capter"),
Some(WindowType::CropWindow(_)) => String::from("Capter: Crop"),
None => String::new(),
}
}

pub fn update(&mut self, message: AppEvent) -> Task<AppEvent> {
Expand Down Expand Up @@ -102,16 +106,22 @@ impl App {
});
self.windows.insert(
id,
WindowType::ConfigureWindow(ConfigureWindow::new(&self.config)),
WindowType::ConfigureWindow(ConfigureWindow::new(
shorten_path(self.config.directory.clone()),
self.config.theme.clone(),
)),
);
open_task.discard().chain(gain_focus(id))
} else {
Task::none()
}
}
AppEvent::UpdateConfig(id) => {
if let Some(WindowType::ConfigureWindow(config_window)) = self.windows.get(&id) {
self.config = config_window.config.clone();
AppEvent::OpenDirectory => self.config.open_directory().into(),
AppEvent::UpdateDirectory(id) => {
self.config.update_directory();
if let Some(WindowType::ConfigureWindow(config_window)) = self.windows.get_mut(&id)
{
config_window.path = shorten_path(self.config.directory.clone());
}
Task::none()
}
Expand Down Expand Up @@ -152,7 +162,10 @@ impl App {
Some(WindowType::CropWindow(crop_window)) => {
crop_window.crop_screenshot(&self.config);
}
Some(WindowType::ConfigureWindow(_)) => self.config.update_config(),
Some(WindowType::ConfigureWindow(config_window)) => {
self.config.theme = config_window.theme.target().clone();
self.config.update_config()
}
None => (),
}
Task::none()
Expand Down Expand Up @@ -190,13 +203,14 @@ impl App {
None => horizontal_space().into(),
};

Animation::new(&self.config.theme, content)
.on_update(move |event| AppEvent::Config(id, ConfigEvent::UpdateTheme(event)))
.into()
content
}

pub fn theme(&self, _id: Id) -> Theme {
self.config.theme.value().clone()
pub fn theme(&self, id: Id) -> Theme {
match self.windows.get(&id) {
Some(WindowType::ConfigureWindow(config_window)) => config_window.theme.value().clone(),
_ => self.config.theme.clone(),
}
}

pub fn style(&self, theme: &Theme) -> Appearance {
Expand Down
File renamed without changes.
File renamed without changes.
40 changes: 20 additions & 20 deletions src/style/mod.rs → src/theme/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use iced::{
daemon::{Appearance, DefaultStyle},
Color,
};
use iced_anim::Animate;

use crate::entities::theme::{Palette, Theme};

Expand All @@ -16,23 +17,23 @@ mod text;
pub type Element<'a, Message> = iced::Element<'a, Message, Theme>;

pub const LIGHT: Palette = Palette {
background: color!(220, 220, 220),
surface: color!(210, 210, 210),
text: color!(50, 50, 50),
primary: color!(190, 190, 190),
secondary: color!(170, 170, 170),
danger_primary: color!(255, 100, 100),
danger_secondary: color!(245, 90, 90),
background: color!(0xdcdcdc),
surface: color!(0xd2d2d2),
text: color!(0x323232),
primary: color!(0xbebebe),
secondary: color!(0xaaaaaa),
danger_primary: color!(0xff6464),
danger_secondary: color!(0xf55a5a),
};

pub const DARK: Palette = Palette {
background: color!(40, 40, 40),
surface: color!(50, 50, 50),
text: color!(210, 210, 210),
primary: color!(70, 70, 70),
secondary: color!(90, 90, 90),
danger_primary: color!(228, 67, 67),
danger_secondary: color!(238, 77, 77),
background: color!(0x282828),
surface: color!(0x323232),
text: color!(0xd2d2d2),
primary: color!(0x464646),
secondary: color!(0x5a5a5a),
danger_primary: color!(0xe44343),
danger_secondary: color!(0xee4d4d),
};

impl Theme {
Expand All @@ -44,7 +45,6 @@ impl Theme {
}
}

/// Toggles the theme between light and dark, defaulting to `Light` if using a custom palette.
pub fn toggle(&self) -> Self {
match self {
Theme::Light => Theme::Dark,
Expand Down Expand Up @@ -72,18 +72,18 @@ impl DefaultStyle for Theme {
}
}

impl iced_anim::Animate for Theme {
impl Animate for Theme {
fn components() -> usize {
Palette::components()
}

fn distance_to(&self, end: &Self) -> Vec<f32> {
self.palette().distance_to(&end.palette())
}

fn update(&mut self, components: &mut impl Iterator<Item = f32>) {
let mut palette = self.palette();
palette.update(components);
*self = Theme::Custom(palette);
}

fn distance_to(&self, end: &Self) -> Vec<f32> {
self.palette().distance_to(&end.palette())
}
}
File renamed without changes.
File renamed without changes.
50 changes: 7 additions & 43 deletions src/utils/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,14 @@ use std::{
process::Command,
};

use iced_anim::Spring;
use rfd::FileDialog;

use crate::entities::config::{Config, ConfigureWindow, StoredConfig};

use super::shorten_path;
use crate::entities::{config::Config, theme::Theme};

impl Default for Config {
fn default() -> Self {
Self {
theme: Spring::default(),
theme: Theme::Light,
directory: Config::default_path(),
}
}
Expand All @@ -29,7 +26,7 @@ impl Config {
let mut file_content = String::new();
let _ = file.read_to_string(&mut file_content).unwrap();
let bool = file_content.is_empty();
let config: Config = match toml::from_str::<StoredConfig>(&file_content) {
let config: Config = match toml::from_str::<Config>(&file_content) {
Ok(config) => config.into(),
Err(_) => {
let config = Self::default();
Expand Down Expand Up @@ -74,8 +71,7 @@ impl Config {
match Self::get_config_file() {
Ok(mut file) => {
file.set_len(0).unwrap();
let config = StoredConfig::from(self);
let contents = toml::to_string(&config).unwrap();
let contents = toml::to_string(self).unwrap();
file.write_all(contents.as_bytes()).unwrap();
}
Err(_) => println!("Config can't be updated"),
Expand Down Expand Up @@ -103,42 +99,13 @@ impl Config {

path
}
}

// From impls to convert betwen different config types
impl From<StoredConfig> for Config {
fn from(config: StoredConfig) -> Self {
Self {
theme: Spring::new(config.theme),
directory: config.directory,
}
}
}

impl From<&Config> for StoredConfig {
fn from(config: &Config) -> Self {
Self {
theme: config.theme.target().clone(),
directory: config.directory.clone(),
}
}
}

impl ConfigureWindow {
pub fn new(config: &Config) -> Self {
Self {
config: config.clone(),
path: shorten_path(config.directory.clone()),
}
}

pub fn update_directory(&mut self) {
if let Some(path) = FileDialog::new()
.set_directory(self.config.directory.clone())
.set_directory(self.directory.clone())
.pick_folder()
{
self.config.directory = path.into_os_string().into_string().unwrap();
self.path = shorten_path(self.config.directory.clone());
self.directory = path.into_os_string().into_string().unwrap();
}
}

Expand All @@ -149,9 +116,6 @@ impl ConfigureWindow {
let cmd = "xdg-open";
#[cfg(target_os = "macos")]
let cmd = "open";
Command::new(cmd)
.arg(&self.config.directory)
.spawn()
.unwrap();
Command::new(cmd).arg(&self.directory).spawn().unwrap();
}
}
47 changes: 23 additions & 24 deletions src/windows/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,32 @@ use iced::{
Length::Fill,
Task,
};
use iced_anim::{Animation, Spring};

use crate::{
assets::{BOLD, SVG_FOLDER_OPEN},
entities::{
config::{ConfigEvent, ConfigureWindow},
style::ButtonClass,
theme::Theme,
},
style::Element,
theme::Element,
AppEvent,
};

impl ConfigureWindow {
pub fn new(path: String, theme: Theme) -> Self {
Self {
path,
theme: Spring::new(theme),
}
}

pub fn update(&mut self, id: Id, message: ConfigEvent) -> Task<AppEvent> {
match message {
ConfigEvent::UpdateFolderPath => {
self.update_directory();
Task::done(AppEvent::UpdateConfig(id))
}
ConfigEvent::OpenFolder => {
self.open_directory();
Task::none()
}
ConfigEvent::UpdateTheme(event) => {
self.config.theme.update(event);
Task::done(AppEvent::UpdateConfig(id))
}
ConfigEvent::UpdateFolderPath => Task::done(AppEvent::UpdateDirectory(id)),
ConfigEvent::OpenFolder => Task::done(AppEvent::OpenDirectory),
ConfigEvent::UpdateTheme(event) => self.theme.update(event).into(),
ConfigEvent::RequestExit => Task::done(AppEvent::ExitApp),
}
}
Expand Down Expand Up @@ -83,16 +83,12 @@ impl ConfigureWindow {
row![
text("App Theme").align_x(Left).size(22).font(BOLD),
horizontal_space().width(Fill),
button(
text(self.config.theme.target().to_string())
.size(20)
.center()
)
.height(40)
.width(160)
.on_press(ConfigEvent::UpdateTheme(
self.config.theme.target().toggle().into()
))
button(text(self.theme.target().to_string()).size(20).center())
.height(40)
.width(160)
.on_press(ConfigEvent::UpdateTheme(
self.theme.target().toggle().into()
))
]
.align_y(Alignment::Center)
.width(Fill)
Expand Down Expand Up @@ -129,7 +125,10 @@ impl ConfigureWindow {
.width(Fill)
.padding(10),
);
let content = column![header, body, footer].spacing(10).padding(15);

column![header, body, footer].spacing(10).padding(15).into()
Animation::new(&self.theme, content)
.on_update(ConfigEvent::UpdateTheme)
.into()
}
}
Loading

0 comments on commit fed81b3

Please sign in to comment.