feat: add save as dialog and auto_save toggle
This commit is contained in:
+11
-3
@@ -8,6 +8,7 @@ pub struct ColorScheme {
|
|||||||
pub colors: Vec<(String, String)>,
|
pub colors: Vec<(String, String)>,
|
||||||
history: Vec<String>,
|
history: Vec<String>,
|
||||||
redo_history: Vec<String>,
|
redo_history: Vec<String>,
|
||||||
|
pub auto_save: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ColorScheme {
|
impl ColorScheme {
|
||||||
@@ -33,6 +34,7 @@ impl ColorScheme {
|
|||||||
colors,
|
colors,
|
||||||
history: Vec::new(),
|
history: Vec::new(),
|
||||||
redo_history: Vec::new(),
|
redo_history: Vec::new(),
|
||||||
|
auto_save: true,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +56,9 @@ impl ColorScheme {
|
|||||||
.push(std::mem::replace(&mut self.content, new_content));
|
.push(std::mem::replace(&mut self.content, new_content));
|
||||||
self.redo_history.clear();
|
self.redo_history.clear();
|
||||||
self.colors = parse_colors(&self.content);
|
self.colors = parse_colors(&self.content);
|
||||||
self.save()?;
|
if self.auto_save {
|
||||||
|
self.save()?;
|
||||||
|
}
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,7 +74,9 @@ impl ColorScheme {
|
|||||||
self.redo_history
|
self.redo_history
|
||||||
.push(std::mem::replace(&mut self.content, prev));
|
.push(std::mem::replace(&mut self.content, prev));
|
||||||
self.colors = parse_colors(&self.content);
|
self.colors = parse_colors(&self.content);
|
||||||
self.save()?;
|
if self.auto_save {
|
||||||
|
self.save()?;
|
||||||
|
}
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,7 +87,9 @@ impl ColorScheme {
|
|||||||
self.history
|
self.history
|
||||||
.push(std::mem::replace(&mut self.content, next));
|
.push(std::mem::replace(&mut self.content, next));
|
||||||
self.colors = parse_colors(&self.content);
|
self.colors = parse_colors(&self.content);
|
||||||
self.save()?;
|
if self.auto_save {
|
||||||
|
self.save()?;
|
||||||
|
}
|
||||||
Ok(true)
|
Ok(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+53
-17
@@ -7,6 +7,10 @@ mod ui;
|
|||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk::{glib, Application, ApplicationWindow, Stack};
|
use gtk::{glib, Application, ApplicationWindow, Stack};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
use crate::color_scheme::ColorScheme;
|
||||||
|
use crate::composite_icon::CompositeIcon;
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
const APP_ID: &str = "dev.rootiest.IconColorTool";
|
const APP_ID: &str = "dev.rootiest.IconColorTool";
|
||||||
|
|
||||||
@@ -42,10 +46,10 @@ fn main() -> glib::ExitCode {
|
|||||||
let stack = Stack::new();
|
let stack = Stack::new();
|
||||||
window.set_child(Some(&stack));
|
window.set_child(Some(&stack));
|
||||||
|
|
||||||
build_picker(&stack, breeze_path);
|
build_picker(&stack, &window, breeze_path);
|
||||||
|
|
||||||
if let Some(Ok(path)) = initial_icon {
|
if let Some(Ok(path)) = initial_icon {
|
||||||
build_editor(&stack, path);
|
build_editor(&stack, &window, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.present();
|
window.present();
|
||||||
@@ -77,30 +81,62 @@ fn resolve_icon_arg(arg: &str, breeze_path: &Path) -> anyhow::Result<PathBuf> {
|
|||||||
Ok(under_breeze.canonicalize()?)
|
Ok(under_breeze.canonicalize()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_picker(stack: &Stack, breeze_path: PathBuf) {
|
fn build_picker(stack: &Stack, window: &ApplicationWindow, breeze_path: PathBuf) {
|
||||||
let stack_for_callback = stack.clone();
|
let stack_for_callback = stack.clone();
|
||||||
|
let window_for_callback = window.clone();
|
||||||
let widget = ui::picker::build_picker_page(breeze_path, move |icon_path| {
|
let widget = ui::picker::build_picker_page(breeze_path, move |icon_path| {
|
||||||
build_editor(&stack_for_callback, icon_path);
|
build_editor(&stack_for_callback, &window_for_callback, icon_path);
|
||||||
stack_for_callback.set_visible_child_name("editor");
|
|
||||||
});
|
});
|
||||||
stack.add_named(&widget, Some("picker"));
|
stack.add_named(&widget, Some("picker"));
|
||||||
stack.set_visible_child_name("picker");
|
stack.set_visible_child_name("picker");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_editor(stack: &Stack, icon_path: PathBuf) {
|
fn build_editor(stack: &Stack, window: &ApplicationWindow, icon_path: PathBuf) {
|
||||||
let stack_for_callback = stack.clone();
|
let scheme = match ColorScheme::load(&icon_path) {
|
||||||
match ui::editor::build_editor_page(&icon_path, move || {
|
Ok(s) => s,
|
||||||
stack_for_callback.set_visible_child_name("picker");
|
|
||||||
}) {
|
|
||||||
Ok(widget) => {
|
|
||||||
if let Some(existing) = stack.child_by_name("editor") {
|
|
||||||
stack.remove(&existing);
|
|
||||||
}
|
|
||||||
stack.add_named(&widget, Some("editor"));
|
|
||||||
stack.set_visible_child_name("editor");
|
|
||||||
}
|
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("Failed to open {}: {e:#}", icon_path.display());
|
eprintln!("Failed to open {}: {e:#}", icon_path.display());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let composite = Rc::new(RefCell::new(CompositeIcon::new(scheme)));
|
||||||
|
|
||||||
|
let stack_for_callback = stack.clone();
|
||||||
|
|
||||||
|
let widget = ui::editor::build_editor_page(
|
||||||
|
Rc::clone(&composite),
|
||||||
|
move || {
|
||||||
|
stack_for_callback.set_visible_child_name("picker");
|
||||||
|
},
|
||||||
|
{
|
||||||
|
let stack_clone = stack.clone();
|
||||||
|
move || {
|
||||||
|
stack_clone.set_visible_child_name("emblem_picker");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
let composite = Rc::clone(&composite);
|
||||||
|
let window = window.clone();
|
||||||
|
move || {
|
||||||
|
let dialog = gtk::FileDialog::builder()
|
||||||
|
.title("Save Composite Icon As...")
|
||||||
|
.build();
|
||||||
|
let comp = Rc::clone(&composite);
|
||||||
|
dialog.save(Some(&window), gtk::gio::Cancellable::NONE, move |res| {
|
||||||
|
if let Ok(file) = res {
|
||||||
|
if let Some(path) = file.path() {
|
||||||
|
let _ = std::fs::write(path, comp.borrow().render());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(existing) = stack.child_by_name("editor") {
|
||||||
|
stack.remove(&existing);
|
||||||
}
|
}
|
||||||
|
stack.add_named(&widget, Some("editor"));
|
||||||
|
stack.set_visible_child_name("editor");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user