feat: implement emblem picker and dynamic editor rebuild

This commit is contained in:
2026-08-03 21:28:45 -04:00
parent d88aadd40f
commit e1e27bb4ff
+71 -34
View File
@@ -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");
}