feat: implement emblem picker and dynamic editor rebuild
This commit is contained in:
+71
-34
@@ -46,10 +46,10 @@ fn main() -> glib::ExitCode {
|
||||
let stack = Stack::new();
|
||||
window.set_child(Some(&stack));
|
||||
|
||||
build_picker(&stack, &window, breeze_path);
|
||||
build_picker(&stack, &window, breeze_path.clone());
|
||||
|
||||
if let Some(Ok(path)) = initial_icon {
|
||||
build_editor(&stack, &window, path);
|
||||
build_editor(&stack, &window, path, breeze_path);
|
||||
}
|
||||
|
||||
window.present();
|
||||
@@ -84,14 +84,16 @@ fn resolve_icon_arg(arg: &str, breeze_path: &Path) -> anyhow::Result<PathBuf> {
|
||||
fn build_picker(stack: &Stack, window: &ApplicationWindow, breeze_path: PathBuf) {
|
||||
let stack_for_callback = stack.clone();
|
||||
let window_for_callback = window.clone();
|
||||
let breeze_for_editor = breeze_path.clone();
|
||||
|
||||
let widget = ui::picker::build_picker_page(breeze_path, move |icon_path| {
|
||||
build_editor(&stack_for_callback, &window_for_callback, icon_path);
|
||||
build_editor(&stack_for_callback, &window_for_callback, icon_path, breeze_for_editor.clone());
|
||||
});
|
||||
stack.add_named(&widget, Some("picker"));
|
||||
stack.set_visible_child_name("picker");
|
||||
}
|
||||
|
||||
fn build_editor(stack: &Stack, window: &ApplicationWindow, icon_path: PathBuf) {
|
||||
fn build_editor(stack: &Stack, window: &ApplicationWindow, icon_path: PathBuf, breeze_path: PathBuf) {
|
||||
let scheme = match ColorScheme::load(&icon_path) {
|
||||
Ok(s) => s,
|
||||
Err(e) => {
|
||||
@@ -102,43 +104,78 @@ fn build_editor(stack: &Stack, window: &ApplicationWindow, icon_path: PathBuf) {
|
||||
|
||||
let composite = Rc::new(RefCell::new(CompositeIcon::new(scheme)));
|
||||
|
||||
let stack_for_callback = stack.clone();
|
||||
let editor_container = gtk::Box::new(gtk::Orientation::Vertical, 0);
|
||||
|
||||
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 rebuild_editor = {
|
||||
let composite = Rc::clone(&composite);
|
||||
let stack = stack.clone();
|
||||
let window = window.clone();
|
||||
let editor_container = editor_container.clone();
|
||||
|
||||
Rc::new(move || {
|
||||
while let Some(child) = editor_container.first_child() {
|
||||
editor_container.remove(&child);
|
||||
}
|
||||
},
|
||||
{
|
||||
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() {
|
||||
if let Err(e) = std::fs::write(&path, comp.borrow().render()) {
|
||||
eprintln!("Failed to save composite to {}: {e}", path.display());
|
||||
|
||||
let stack_clone = stack.clone();
|
||||
let stack_emblem = stack.clone();
|
||||
let window_clone = window.clone();
|
||||
let comp = Rc::clone(&composite);
|
||||
|
||||
let page = ui::editor::build_editor_page(
|
||||
Rc::clone(&composite),
|
||||
move || {
|
||||
stack_clone.set_visible_child_name("picker");
|
||||
},
|
||||
move || {
|
||||
stack_emblem.set_visible_child_name("emblem_picker");
|
||||
},
|
||||
move || {
|
||||
let dialog = gtk::FileDialog::builder()
|
||||
.title("Save Composite Icon As...")
|
||||
.build();
|
||||
let c = Rc::clone(&comp);
|
||||
dialog.save(Some(&window_clone), gtk::gio::Cancellable::NONE, move |res| {
|
||||
if let Ok(file) = res {
|
||||
if let Some(path) = file.path() {
|
||||
if let Err(e) = std::fs::write(&path, c.borrow().render()) {
|
||||
eprintln!("Failed to save composite to {}: {e}", path.display());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
editor_container.append(&page);
|
||||
})
|
||||
};
|
||||
|
||||
rebuild_editor();
|
||||
|
||||
if let Some(existing) = stack.child_by_name("editor") {
|
||||
stack.remove(&existing);
|
||||
}
|
||||
stack.add_named(&widget, Some("editor"));
|
||||
stack.add_named(&editor_container, Some("editor"));
|
||||
|
||||
let rebuild_editor_clone = Rc::clone(&rebuild_editor);
|
||||
let stack_emblem_callback = stack.clone();
|
||||
let comp_for_picker = Rc::clone(&composite);
|
||||
|
||||
let emblem_picker = ui::picker::build_picker_page(breeze_path, move |emblem_path| {
|
||||
if let Ok(mut emblem_scheme) = ColorScheme::load_with_namespace(&emblem_path, "Emblem") {
|
||||
emblem_scheme.auto_save = false;
|
||||
comp_for_picker.borrow_mut().set_emblem(emblem_scheme);
|
||||
rebuild_editor_clone();
|
||||
stack_emblem_callback.set_visible_child_name("editor");
|
||||
} else {
|
||||
eprintln!("Failed to load emblem: {}", emblem_path.display());
|
||||
}
|
||||
});
|
||||
|
||||
if let Some(existing) = stack.child_by_name("emblem_picker") {
|
||||
stack.remove(&existing);
|
||||
}
|
||||
stack.add_named(&emblem_picker, Some("emblem_picker"));
|
||||
|
||||
stack.set_visible_child_name("editor");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user