mirror of
https://github.com/InioX/matugen.git
synced 2025-05-13 05:20:35 +01:00
feat(gui): add images tab
This commit is contained in:
parent
25617214af
commit
c708abab2f
3 changed files with 151 additions and 10 deletions
60
Cargo.lock
generated
60
Cargo.lock
generated
|
@ -1336,6 +1336,20 @@ dependencies = [
|
||||||
"winit",
|
"winit",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "egui_extras"
|
||||||
|
version = "0.29.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bf3c1f5cd8dfe2ade470a218696c66cf556fcfd701e7830fa2e9f4428292a2a1"
|
||||||
|
dependencies = [
|
||||||
|
"ahash",
|
||||||
|
"egui",
|
||||||
|
"enum-map",
|
||||||
|
"image",
|
||||||
|
"log",
|
||||||
|
"mime_guess2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "egui_file"
|
name = "egui_file"
|
||||||
version = "0.19.0"
|
version = "0.19.0"
|
||||||
|
@ -1407,6 +1421,27 @@ dependencies = [
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "enum-map"
|
||||||
|
version = "2.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6866f3bfdf8207509a033af1a75a7b08abda06bbaaeae6669323fd5a097df2e9"
|
||||||
|
dependencies = [
|
||||||
|
"enum-map-derive",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "enum-map-derive"
|
||||||
|
version = "0.17.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.75",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "enumflags2"
|
name = "enumflags2"
|
||||||
version = "0.7.10"
|
version = "0.7.10"
|
||||||
|
@ -2512,6 +2547,7 @@ dependencies = [
|
||||||
"directories",
|
"directories",
|
||||||
"eframe",
|
"eframe",
|
||||||
"egui",
|
"egui",
|
||||||
|
"egui_extras",
|
||||||
"egui_file",
|
"egui_file",
|
||||||
"enquote",
|
"enquote",
|
||||||
"execute",
|
"execute",
|
||||||
|
@ -2588,6 +2624,16 @@ version = "0.3.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mime_guess2"
|
||||||
|
version = "2.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "25a3333bb1609500601edc766a39b4c1772874a4ce26022f4d866854dc020c41"
|
||||||
|
dependencies = [
|
||||||
|
"mime",
|
||||||
|
"unicase",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "minimal-lexical"
|
name = "minimal-lexical"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
|
@ -3293,18 +3339,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "profiling"
|
name = "profiling"
|
||||||
version = "1.0.15"
|
version = "1.0.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "43d84d1d7a6ac92673717f9f6d1518374ef257669c24ebc5ac25d5033828be58"
|
checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"profiling-procmacros",
|
"profiling-procmacros",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "profiling-procmacros"
|
name = "profiling-procmacros"
|
||||||
version = "1.0.15"
|
version = "1.0.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8021cf59c8ec9c432cfc2526ac6b8aa508ecaf29cd415f271b8406c1b851c3fd"
|
checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
"syn 2.0.75",
|
"syn 2.0.75",
|
||||||
|
@ -4468,6 +4514,12 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicase"
|
||||||
|
version = "2.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-bidi"
|
name = "unicode-bidi"
|
||||||
version = "0.3.15"
|
version = "0.3.15"
|
||||||
|
|
|
@ -28,6 +28,7 @@ ui = [
|
||||||
"dep:indexmap",
|
"dep:indexmap",
|
||||||
"dep:egui_file",
|
"dep:egui_file",
|
||||||
"dep:rfd",
|
"dep:rfd",
|
||||||
|
"dep:egui_extras",
|
||||||
]
|
]
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
@ -79,6 +80,7 @@ reqwest = { version = "0.12.5", default-features = false, features = [
|
||||||
|
|
||||||
# gui feature
|
# gui feature
|
||||||
egui = { version = "0.29.1", optional = true }
|
egui = { version = "0.29.1", optional = true }
|
||||||
|
egui_extras = { version = "0.29.1", optional = true, features = ["image", "file"] }
|
||||||
eframe = { version = "0.29.1", optional = true }
|
eframe = { version = "0.29.1", optional = true }
|
||||||
indexmap = { version = "2.7.0", optional = true }
|
indexmap = { version = "2.7.0", optional = true }
|
||||||
egui_file = { version = "0.19.0", optional = true }
|
egui_file = { version = "0.19.0", optional = true }
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::path::PathBuf;
|
use std::{ffi::OsStr, path::PathBuf};
|
||||||
|
|
||||||
#[cfg(feature = "ui")]
|
#[cfg(feature = "ui")]
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
@ -20,6 +20,7 @@ use crate::{template::TemplateFile, util::arguments::Cli, State};
|
||||||
#[cfg(feature = "ui")]
|
#[cfg(feature = "ui")]
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
pub enum Tabs {
|
pub enum Tabs {
|
||||||
|
Images,
|
||||||
Settings,
|
Settings,
|
||||||
Colors,
|
Colors,
|
||||||
}
|
}
|
||||||
|
@ -33,6 +34,8 @@ pub struct MyApp {
|
||||||
colors: ColorsMap,
|
colors: ColorsMap,
|
||||||
selected_tab: Tabs,
|
selected_tab: Tabs,
|
||||||
app: State,
|
app: State,
|
||||||
|
images_vec: Vec<PathBuf>,
|
||||||
|
images_folder: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "ui")]
|
#[cfg(feature = "ui")]
|
||||||
|
@ -41,6 +44,25 @@ pub struct ColorsMap {
|
||||||
pub dark: Option<IndexMap<String, Color32>>,
|
pub dark: Option<IndexMap<String, Color32>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_images_in_folder(folder_path: &PathBuf) -> Vec<PathBuf> {
|
||||||
|
let valid_extensions = ["jpg", "jpeg", "png", "gif", "bmp", "tiff", "webp"];
|
||||||
|
|
||||||
|
std::fs::read_dir(folder_path)
|
||||||
|
.ok()
|
||||||
|
.into_iter()
|
||||||
|
.flatten()
|
||||||
|
.flatten()
|
||||||
|
.map(|entry| entry.path())
|
||||||
|
.filter(|path| path.is_file())
|
||||||
|
.filter(|path| {
|
||||||
|
path.extension()
|
||||||
|
.and_then(|ext| ext.to_str())
|
||||||
|
.map(|ext| valid_extensions.contains(&ext.to_lowercase().as_str()))
|
||||||
|
.unwrap_or(false)
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: Cleanup code, reorganize stuff into its own functions
|
// FIXME: Cleanup code, reorganize stuff into its own functions
|
||||||
|
|
||||||
#[cfg(feature = "ui")]
|
#[cfg(feature = "ui")]
|
||||||
|
@ -55,12 +77,15 @@ impl MyApp {
|
||||||
dark: None,
|
dark: None,
|
||||||
},
|
},
|
||||||
selected_tab: Tabs::Settings,
|
selected_tab: Tabs::Settings,
|
||||||
|
images_vec: vec![],
|
||||||
|
images_folder: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn body(&mut self, ui: &mut Ui) {
|
fn body(&mut self, ui: &mut Ui) {
|
||||||
match self.selected_tab {
|
match self.selected_tab {
|
||||||
Tabs::Settings => self.settings(ui),
|
Tabs::Settings => self.settings(ui),
|
||||||
Tabs::Colors => self.colors(ui),
|
Tabs::Colors => self.colors(ui),
|
||||||
|
Tabs::Images => self.images(ui),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +98,7 @@ impl MyApp {
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
ui.label("Scheme type");
|
ui.label("Scheme type");
|
||||||
egui::ComboBox::from_label("Select one!")
|
egui::ComboBox::from_label("")
|
||||||
.selected_text(format!("{:?}", self.app.args.r#type.unwrap()))
|
.selected_text(format!("{:?}", self.app.args.r#type.unwrap()))
|
||||||
.show_ui(ui, |ui| {
|
.show_ui(ui, |ui| {
|
||||||
ui.selectable_value(
|
ui.selectable_value(
|
||||||
|
@ -172,20 +197,80 @@ impl MyApp {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn images(&mut self, ui: &mut Ui) {
|
||||||
|
if self.images_vec.is_empty() {
|
||||||
|
ui.label("No image folder selected or no images to show.");
|
||||||
|
} else {
|
||||||
|
ui.with_layout(
|
||||||
|
egui::Layout::left_to_right(egui::Align::Max).with_cross_justify(true),
|
||||||
|
|ui| {
|
||||||
|
self.show_images(ui);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show_images(&mut self, ui: &mut Ui) {
|
||||||
|
egui::ScrollArea::vertical().show(ui, |ui| {
|
||||||
|
egui::Grid::new("image_grid")
|
||||||
|
.num_columns(3) // Set number of columns
|
||||||
|
.spacing([10.0, 10.0]) // Spacing between items
|
||||||
|
.show(ui, |ui| {
|
||||||
|
for (i, path) in self.images_vec.clone().iter().enumerate() {
|
||||||
|
let img_widget = egui::Image::from_uri(format!(
|
||||||
|
"file://{}",
|
||||||
|
path.clone().into_os_string().into_string().unwrap()
|
||||||
|
))
|
||||||
|
.max_height(300.0)
|
||||||
|
.max_width(300.0)
|
||||||
|
.maintain_aspect_ratio(true)
|
||||||
|
.fit_to_original_size(1.0);
|
||||||
|
|
||||||
|
if ui.add(img_widget.sense(egui::Sense::click())).clicked() {
|
||||||
|
self.selected_file = Some(path.to_path_buf());
|
||||||
|
self.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i + 1) % 3 == 0 {
|
||||||
|
ui.end_row();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_images_tab(&mut self, ui: &mut Ui, image_folder: Option<PathBuf>) {
|
||||||
|
if image_folder == Some("".into()) || image_folder.is_none() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let images = get_images_in_folder(&image_folder.as_ref().unwrap());
|
||||||
|
self.images_vec = images;
|
||||||
|
}
|
||||||
|
|
||||||
fn top_buttons(&mut self, ui: &mut Ui) {
|
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))
|
||||||
|
}
|
||||||
|
}
|
||||||
if ui.button("Select image").clicked() {
|
if ui.button("Select image").clicked() {
|
||||||
if let Some(path) = rfd::FileDialog::new().pick_file() {
|
if let Some(path) = rfd::FileDialog::new().pick_file() {
|
||||||
self.selected_file = Some(path);
|
self.selected_file = Some(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ui.button("Run").clicked() {
|
if ui.button("Run").clicked() {
|
||||||
if self.selected_file != Some("".into()) || self.selected_file.is_some() {
|
self.run()
|
||||||
self.update_colors_tab();
|
|
||||||
self.generate_tempalates();
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn run(&mut self) {
|
||||||
|
if self.selected_file == Some("".into()) || self.selected_file.is_none() {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
self.generate_tempalates();
|
||||||
|
self.update_colors_tab();
|
||||||
|
}
|
||||||
|
|
||||||
fn generate_tempalates(&mut self) {
|
fn generate_tempalates(&mut self) {
|
||||||
let mut engine = self.app.init_engine();
|
let mut engine = self.app.init_engine();
|
||||||
let mut render_data = self.app.init_render_data().unwrap();
|
let mut render_data = self.app.init_render_data().unwrap();
|
||||||
|
@ -225,9 +310,11 @@ fn argb_to_color32(color: &Argb) -> Color32 {
|
||||||
#[cfg(feature = "ui")]
|
#[cfg(feature = "ui")]
|
||||||
impl eframe::App for MyApp {
|
impl eframe::App for MyApp {
|
||||||
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
||||||
|
egui_extras::install_image_loaders(ctx);
|
||||||
egui::TopBottomPanel::top("my_panel").show(ctx, |ui| {
|
egui::TopBottomPanel::top("my_panel").show(ctx, |ui| {
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|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::Settings, "Settings");
|
||||||
ui.selectable_value(&mut self.selected_tab, Tabs::Colors, "Colors");
|
ui.selectable_value(&mut self.selected_tab, Tabs::Colors, "Colors");
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue