mod color_scheme; mod config; mod icon_index; mod ui; use gtk::prelude::*; use gtk::{glib, Application, ApplicationWindow, Stack}; use std::path::{Path, PathBuf}; const APP_ID: &str = "dev.rootiest.IconColorTool"; fn main() -> glib::ExitCode { let app = Application::builder().application_id(APP_ID).build(); app.connect_activate(|app| { let breeze_path = match config::load_breeze_path() { Ok(p) => p, Err(e) => { eprintln!("Failed to resolve breeze-icons path: {e:#}"); std::process::exit(1); } }; let initial_arg = std::env::args().nth(1); let initial_icon = initial_arg .as_deref() .map(|a| resolve_icon_arg(a, &breeze_path)); if let Some(Err(e)) = &initial_icon { eprintln!("Error: {e}"); std::process::exit(1); } let window = ApplicationWindow::builder() .application(app) .title("Icon Color Tool") .default_width(900) .default_height(650) .build(); let stack = Stack::new(); window.set_child(Some(&stack)); build_picker(&stack, breeze_path); if let Some(Ok(path)) = initial_icon { build_editor(&stack, path); } window.present(); }); app.run() } fn resolve_icon_arg(arg: &str, breeze_path: &Path) -> anyhow::Result { let as_given = PathBuf::from(arg); if as_given.is_absolute() { anyhow::ensure!( as_given.exists(), "Icon not found at {}", as_given.display() ); return Ok(as_given); } if as_given.exists() { return Ok(as_given.canonicalize()?); } let under_breeze = breeze_path.join(arg); anyhow::ensure!( under_breeze.exists(), "Icon not found at {} or {}", as_given.display(), under_breeze.display() ); Ok(under_breeze.canonicalize()?) } fn build_picker(stack: &Stack, breeze_path: PathBuf) { let stack_for_callback = stack.clone(); let widget = ui::picker::build_picker_page(breeze_path, move |icon_path| { build_editor(&stack_for_callback, icon_path); stack_for_callback.set_visible_child_name("editor"); }); stack.add_named(&widget, Some("picker")); stack.set_visible_child_name("picker"); } fn build_editor(stack: &Stack, icon_path: PathBuf) { let stack_for_callback = stack.clone(); match ui::editor::build_editor_page(&icon_path, move || { 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) => { eprintln!("Failed to open {}: {e:#}", icon_path.display()); } } }