diff --git a/src/ui/editor.rs b/src/ui/editor.rs index 45f2430..a55f638 100644 --- a/src/ui/editor.rs +++ b/src/ui/editor.rs @@ -1,19 +1,18 @@ -use crate::color_scheme::ColorScheme; -use anyhow::Result; +use crate::composite_icon::CompositeIcon; use gtk::glib; use gtk::prelude::*; use gtk::{ - Box as GtkBox, ColorDialog, ColorDialogButton, InfoBar, Label, MessageType, Orientation, - Picture, ScrolledWindow, + Box as GtkBox, ColorDialog, ColorDialogButton, Label, Orientation, Picture, ScrolledWindow, }; use std::cell::RefCell; -use std::path::Path; use std::rc::Rc; -pub fn build_editor_page(icon_path: &Path, on_back: impl Fn() + 'static) -> Result { - let scheme = ColorScheme::load(icon_path)?; - let scheme = Rc::new(RefCell::new(scheme)); - +pub fn build_editor_page( + composite: Rc>, + on_back: impl Fn() + 'static, + on_add_emblem: impl Fn() + 'static, + on_save_as: impl Fn() + 'static, +) -> gtk::Widget { let root = GtkBox::new(Orientation::Vertical, 8); root.set_margin_top(8); root.set_margin_bottom(8); @@ -25,29 +24,36 @@ pub fn build_editor_page(icon_path: &Path, on_back: impl Fn() + 'static) -> Resu back_button.connect_clicked(move |_| on_back()); toolbar.append(&back_button); + let add_emblem_button = gtk::Button::with_label("Add Emblem"); + add_emblem_button.connect_clicked(move |_| on_add_emblem()); + toolbar.append(&add_emblem_button); + + let save_as_button = gtk::Button::with_label("Save As..."); + save_as_button.connect_clicked(move |_| on_save_as()); + toolbar.append(&save_as_button); + let undo_button = gtk::Button::with_label("Undo"); let redo_button = gtk::Button::with_label("Redo"); toolbar.append(&undo_button); toolbar.append(&redo_button); root.append(&toolbar); - if scheme.borrow().colors.is_empty() { - let info = InfoBar::new(); - info.set_message_type(MessageType::Warning); - info.add_child(&Label::new(Some( - "No ColorScheme tags were found in this SVG.", - ))); - root.append(&info); - } - let content = GtkBox::new(Orientation::Horizontal, 8); content.set_vexpand(true); + let side_panel = GtkBox::new(Orientation::Vertical, 8); let swatches_scroller = ScrolledWindow::new(); swatches_scroller.set_min_content_width(300); + swatches_scroller.set_vexpand(true); let swatches_box = GtkBox::new(Orientation::Vertical, 4); swatches_scroller.set_child(Some(&swatches_box)); - content.append(&swatches_scroller); + side_panel.append(&swatches_scroller); + + // Geometry sliders will go here in Task 4 + let geometry_box = GtkBox::new(Orientation::Vertical, 4); + side_panel.append(&geometry_box); + + content.append(&side_panel); let preview = Picture::new(); preview.set_hexpand(true); @@ -56,10 +62,10 @@ pub fn build_editor_page(icon_path: &Path, on_back: impl Fn() + 'static) -> Resu root.append(&content); let refresh_preview = { - let scheme = Rc::clone(&scheme); + let composite = Rc::clone(&composite); let preview = preview.clone(); move || { - let bytes = glib::Bytes::from_owned(scheme.borrow().content.clone().into_bytes()); + let bytes = glib::Bytes::from_owned(composite.borrow().render().into_bytes()); match gtk::gdk::Texture::from_bytes(&bytes) { Ok(texture) => preview.set_paintable(Some(&texture)), Err(_) => preview.set_paintable(gtk::gdk::Paintable::NONE), @@ -70,7 +76,7 @@ pub fn build_editor_page(icon_path: &Path, on_back: impl Fn() + 'static) -> Resu let rebuild_swatches: Rc>> = Rc::new(RefCell::new(Box::new(|| {}))); { - let scheme = Rc::clone(&scheme); + let composite = Rc::clone(&composite); let swatches_box = swatches_box.clone(); let refresh_preview = refresh_preview.clone(); let rebuild_swatches_for_closure = Rc::clone(&rebuild_swatches); @@ -80,8 +86,18 @@ pub fn build_editor_page(icon_path: &Path, on_back: impl Fn() + 'static) -> Resu swatches_box.remove(&child); } - let tags: Vec<(String, String)> = scheme.borrow().colors.clone(); - for (tag, hex) in tags { + let comp = composite.borrow(); + let mut all_colors = Vec::new(); + for c in &comp.bg.colors { + all_colors.push((c.0.clone(), c.1.clone(), false)); + } + if let Some(emblem) = &comp.emblem { + for c in &emblem.colors { + all_colors.push((c.0.clone(), c.1.clone(), true)); + } + } + + for (tag, hex, is_emblem) in all_colors { let row = GtkBox::new(Orientation::Horizontal, 8); let label = Label::new(Some(&tag)); label.set_hexpand(true); @@ -93,7 +109,7 @@ pub fn build_editor_page(icon_path: &Path, on_back: impl Fn() + 'static) -> Resu button.set_rgba(&rgba); { - let scheme = Rc::clone(&scheme); + let composite = Rc::clone(&composite); let tag = tag.clone(); let refresh_preview = refresh_preview.clone(); let rebuild_swatches_for_closure = Rc::clone(&rebuild_swatches_for_closure); @@ -105,10 +121,12 @@ pub fn build_editor_page(icon_path: &Path, on_back: impl Fn() + 'static) -> Resu (new_rgba.green() * 255.0).round() as u8, (new_rgba.blue() * 255.0).round() as u8, ); - let changed = scheme - .borrow_mut() - .update_color(&tag, &new_hex) - .unwrap_or(false); + let mut comp = composite.borrow_mut(); + let changed = if is_emblem { + comp.emblem.as_mut().unwrap().update_color(&tag, &new_hex).unwrap_or(false) + } else { + comp.bg.update_color(&tag, &new_hex).unwrap_or(false) + }; if changed { refresh_preview(); (rebuild_swatches_for_closure.borrow())(); @@ -127,27 +145,37 @@ pub fn build_editor_page(icon_path: &Path, on_back: impl Fn() + 'static) -> Resu (rebuild_swatches.borrow())(); { - let scheme = Rc::clone(&scheme); + let composite = Rc::clone(&composite); let refresh_preview = refresh_preview.clone(); let rebuild_swatches = Rc::clone(&rebuild_swatches); undo_button.connect_clicked(move |_| { - if scheme.borrow_mut().undo().unwrap_or(false) { + let mut comp = composite.borrow_mut(); + let mut changed = comp.bg.undo().unwrap_or(false); + if let Some(emblem) = &mut comp.emblem { + changed |= emblem.undo().unwrap_or(false); + } + if changed { refresh_preview(); (rebuild_swatches.borrow())(); } }); } { - let scheme = Rc::clone(&scheme); + let composite = Rc::clone(&composite); let refresh_preview = refresh_preview.clone(); let rebuild_swatches = Rc::clone(&rebuild_swatches); redo_button.connect_clicked(move |_| { - if scheme.borrow_mut().redo().unwrap_or(false) { + let mut comp = composite.borrow_mut(); + let mut changed = comp.bg.redo().unwrap_or(false); + if let Some(emblem) = &mut comp.emblem { + changed |= emblem.redo().unwrap_or(false); + } + if changed { refresh_preview(); (rebuild_swatches.borrow())(); } }); } - Ok(root.upcast()) + root.upcast() }