feat(gui): save image folder and tab

This commit is contained in:
InioX 2025-04-06 20:50:50 +02:00
parent 32daa15f6f
commit aa2f62e9b1
5 changed files with 143 additions and 29 deletions

View file

@ -41,7 +41,9 @@ harness = false
[dependencies]
# logging
log = "0.4.17"
paris-log = { version = "1.0.2", features = ["icons"] } # TODO replace with using paris directly?
paris-log = { version = "1.0.2", features = [
"icons",
] } # TODO replace with using paris directly?
pretty_env_logger = "0.5.0"
# terminal output
@ -51,13 +53,25 @@ colorsys = { default-features = false, version = "0.6.7" }
owo-colors = "4.0.0"
# templating engine
upon = { features = ["filters", "serde"], default-features = false, version = "0.8.0" }
upon = { features = [
"filters",
"serde",
], default-features = false, version = "0.8.0" }
# config
serde = { version = "1.0.160", features = ["serde_derive", "std"], default-features = false }
toml = { features = ["parse"], default-features = false, version = "0.8.8" }
serde = { version = "1.0.160", features = [
"serde_derive",
"std",
], default-features = false }
toml = { features = [
"parse",
"display",
], default-features = false, version = "0.8.8" }
clap = { version = "4.2.4", features = ["derive", "std"], default-features = true }
clap = { version = "4.2.4", features = [
"derive",
"std",
], default-features = true }
material-colors = { version = "0.4.0", features = ["image"] }
image = { default-features = false, version = "0.25.2" }
directories = "5.0"
@ -80,8 +94,11 @@ reqwest = { version = "0.12.5", default-features = false, features = [
# gui feature
egui = { version = "0.29.1", optional = true }
egui_extras = { version = "0.29.1", optional = true, features = ["image", "file"] }
egui_extras = { version = "0.29.1", optional = true, features = [
"image",
"file",
] }
eframe = { version = "0.29.1", optional = true }
indexmap = { version = "2.7.0", optional = true }
egui_file = { version = "0.19.0", optional = true }
rfd = { version = "0.15.1", optional = true }
rfd = { version = "0.15.1", optional = true }

38
src/gui/cache.rs Normal file
View file

@ -0,0 +1,38 @@
use serde::{Deserialize, Serialize};
use std::{fs, path::PathBuf};
use crate::util::config::get_proj_path;
use crate::util::config::ProjectDirsTypes;
use super::init::Tabs;
#[derive(Serialize, Deserialize)]
pub struct Config {
pub image_folder: PathBuf,
pub selected_tab: Tabs,
}
pub fn save_cache(image_folder: PathBuf, selected_tab: Tabs) {
let config = Config {
image_folder,
selected_tab,
};
let toml = toml::to_string(&config).unwrap();
if let Some(path) = get_proj_path(&ProjectDirsTypes::Cache) {
dbg!(&path);
// std::fs::create_dir_all(&path).expect("Failed to crate cache folder");
fs::write(path, toml).expect("Failed saving cache")
}
}
pub fn read_cache() -> Option<Config> {
if let Some(path) = get_proj_path(&ProjectDirsTypes::Cache) {
let str = match fs::read_to_string(path) {
Ok(v) => v,
Err(_) => return None,
};
Some(toml::from_str(&str).expect("Couldn't parse cache file"))
} else {
None
}
}

View file

@ -14,11 +14,14 @@ use matugen::{
},
scheme::{SchemeTypes, Schemes},
};
use serde::{Deserialize, Serialize};
use crate::{template::TemplateFile, util::arguments::Cli, State};
use super::cache::{read_cache, save_cache};
#[cfg(feature = "ui")]
#[derive(PartialEq)]
#[derive(PartialEq, Serialize, Deserialize, Clone)]
pub enum Tabs {
Images,
Settings,
@ -35,7 +38,8 @@ pub struct MyApp {
selected_tab: Tabs,
app: State,
images_vec: Vec<PathBuf>,
images_folder: Option<PathBuf>,
image_folder: Option<PathBuf>,
load_cache: bool,
}
#[cfg(feature = "ui")]
@ -68,6 +72,15 @@ fn get_images_in_folder(folder_path: &PathBuf) -> Vec<PathBuf> {
#[cfg(feature = "ui")]
impl MyApp {
pub fn new(_cc: &eframe::CreationContext, cli: Box<Cli>) -> Self {
let mut is_cache = false;
let mut selected_tab = Tabs::Settings;
let mut image_folder = None;
if let Some(c) = read_cache() {
is_cache = true;
selected_tab = c.selected_tab;
image_folder = Some(c.image_folder);
} else {
};
Self {
selected_file: None,
app: crate::State::new(*cli.clone()),
@ -76,12 +89,17 @@ impl MyApp {
light: None,
dark: None,
},
selected_tab: Tabs::Settings,
selected_tab,
images_vec: vec![],
images_folder: None,
load_cache: if is_cache { true } else { false },
image_folder,
}
}
fn body(&mut self, ui: &mut Ui) {
if self.load_cache {
self.update_images_tab(ui);
self.load_cache = false;
}
match self.selected_tab {
Tabs::Settings => self.settings(ui),
Tabs::Colors => self.colors(ui),
@ -241,18 +259,23 @@ impl MyApp {
});
}
fn update_images_tab(&mut self, ui: &mut Ui, image_folder: Option<PathBuf>) {
if image_folder == Some("".into()) || image_folder.is_none() {
fn update_images_tab(&mut self, ui: &mut Ui) {
if self.image_folder == Some("".into()) || self.image_folder.is_none() {
return;
}
let images = get_images_in_folder(&image_folder.as_ref().unwrap());
save_cache(
self.image_folder.clone().unwrap(),
self.selected_tab.clone(),
);
let images = get_images_in_folder(&self.image_folder.as_ref().unwrap());
self.images_vec = images;
}
fn top_buttons(&mut self, ui: &mut Ui) {
if ui.button("Image Folder").clicked() {
if let Some(path) = rfd::FileDialog::new().pick_folder() {
self.update_images_tab(ui, Some(path))
self.image_folder = Some(path);
self.update_images_tab(ui)
}
}
if ui.button("Select image").clicked() {
@ -316,9 +339,33 @@ impl eframe::App for MyApp {
egui::TopBottomPanel::top("my_panel").show(ctx, |ui| {
ui.horizontal(|ui| {
ui.horizontal(|ui| {
ui.selectable_value(&mut self.selected_tab, Tabs::Images, "Images");
ui.selectable_value(&mut self.selected_tab, Tabs::Settings, "Settings");
ui.selectable_value(&mut self.selected_tab, Tabs::Colors, "Colors");
if ui
.selectable_value(&mut self.selected_tab, Tabs::Images, "Images")
.clicked()
{
save_cache(
self.image_folder.clone().unwrap(),
self.selected_tab.clone(),
);
};
if ui
.selectable_value(&mut self.selected_tab, Tabs::Settings, "Settings")
.clicked()
{
save_cache(
self.image_folder.clone().unwrap(),
self.selected_tab.clone(),
)
};
if ui
.selectable_value(&mut self.selected_tab, Tabs::Colors, "Colors")
.clicked()
{
save_cache(
self.image_folder.clone().unwrap(),
self.selected_tab.clone(),
)
};
});
ui.with_layout(egui::Layout::right_to_left(egui::Align::TOP), |ui| {

View file

@ -1 +1,2 @@
pub mod cache;
pub mod init;

View file

@ -1,6 +1,6 @@
use directories::ProjectDirs;
use std::collections::HashMap;
use std::fs;
use std::fs::{self, File};
use std::path::PathBuf;
use color_eyre::{Help, Report};
@ -39,6 +39,24 @@ const DEFAULT_CONFIG: &str = r#"
[templates]
"#;
pub enum ProjectDirsTypes {
Config,
Cache,
}
pub fn get_proj_path(dir_type: &ProjectDirsTypes) -> Option<PathBuf> {
if let Some(proj_dirs) = ProjectDirs::from("com", "InioX", "matugen") {
let file = match dir_type {
ProjectDirsTypes::Config => PathBuf::from(proj_dirs.config_dir()).join("config.toml"),
ProjectDirsTypes::Cache => PathBuf::from(proj_dirs.cache_dir()).join("cache.toml"),
};
return Some(file);
} else {
None
}
}
impl ConfigFile {
pub fn read(args: &Cli) -> Result<(ConfigFile, Option<PathBuf>), Report> {
match &args.config {
@ -65,17 +83,10 @@ impl ConfigFile {
}
fn read_from_proj_path() -> Result<(ConfigFile, Option<PathBuf>), Report> {
if let Some(proj_dirs) = ProjectDirs::from("com", "InioX", "matugen") {
let proj_dir = proj_dirs.config_dir();
let config_file = PathBuf::from(proj_dir).join("config.toml");
if !config_file.exists() {
return Ok((Self::read_from_fallback_path()?, None));
}
let content: String = fs::read_to_string(&config_file).unwrap();
if let Some(path) = get_proj_path(&ProjectDirsTypes::Config) {
let content: String = fs::read_to_string(&path).unwrap();
match toml::from_str(&content) {
Ok(res) => Ok((res, Some(config_file))),
Ok(res) => Ok((res, Some(path))),
Err(e) => Err(Report::new(e).suggestion(ERROR_TEXT)),
}
} else {