diff --git a/src/composite_icon.rs b/src/composite_icon.rs index 82777c4..7ef8d97 100644 --- a/src/composite_icon.rs +++ b/src/composite_icon.rs @@ -24,8 +24,25 @@ impl CompositeIcon { } pub fn render(&self) -> String { + use regex::Regex; + + let strip_dimensions = |svg: &str| -> String { + if let Some(root_svg_end) = svg.find('>') { + let mut root_tag = svg[..=root_svg_end].to_string(); + let re_w = Regex::new(r#"(?i)\s+width\s*=\s*"[^"]*""#).unwrap(); + root_tag = re_w.replace_all(&root_tag, "").into_owned(); + let re_h = Regex::new(r#"(?i)\s+height\s*=\s*"[^"]*""#).unwrap(); + root_tag = re_h.replace_all(&root_tag, "").into_owned(); + + let mut new_svg = root_tag; + new_svg.push_str(&svg[root_svg_end + 1..]); + new_svg + } else { + svg.to_string() + } + }; + if let Some(emblem) = &self.emblem { - use regex::Regex; fn parse_dims(svg: &str) -> (f64, f64) { if let Some(re) = Regex::new(r#"(?i)]*viewBox\s*=\s*"([^"]+)""#).ok() { @@ -87,15 +104,16 @@ impl CompositeIcon { mapped_x, mapped_y, scale_x, scale_y, emblem_inner ); - if let Some(idx) = self.bg.content.rfind("") { - let mut new_svg = self.bg.content[..idx].to_string(); + let mut base_svg = strip_dimensions(&self.bg.content); + if let Some(idx) = base_svg.rfind("") { + let mut new_svg = base_svg[..idx].to_string(); new_svg.push_str(&emblem_group); new_svg } else { - self.bg.content.clone() // fallback + base_svg } } else { - self.bg.content.clone() + strip_dimensions(&self.bg.content) } } } diff --git a/src/main.rs b/src/main.rs index 97d1ed5..821f545 100644 --- a/src/main.rs +++ b/src/main.rs @@ -94,13 +94,14 @@ fn build_picker(stack: &Stack, window: &ApplicationWindow, breeze_path: PathBuf) } fn build_editor(stack: &Stack, window: &ApplicationWindow, icon_path: PathBuf, breeze_path: PathBuf) { - let scheme = match ColorScheme::load(&icon_path) { + let mut scheme = match ColorScheme::load(&icon_path) { Ok(s) => s, Err(e) => { eprintln!("Failed to open {}: {e:#}", icon_path.display()); return; } }; + scheme.auto_save = false; let composite = Rc::new(RefCell::new(CompositeIcon::new(scheme))); diff --git a/src/ui/editor.rs b/src/ui/editor.rs index 7a2457a..1a31ea2 100644 --- a/src/ui/editor.rs +++ b/src/ui/editor.rs @@ -1,5 +1,4 @@ use crate::composite_icon::CompositeIcon; -use gtk::glib; use gtk::prelude::*; use gtk::{ Box as GtkBox, ColorDialog, ColorDialogButton, Label, Orientation, Picture, ScrolledWindow, @@ -111,8 +110,8 @@ pub fn build_editor_page( let scale_y = scale_y.clone(); let preview = preview.clone(); move |_, offset_x, offset_y| { - let width = preview.allocated_width() as f64; - let height = preview.allocated_height() as f64; + let width = preview.width() as f64; + let height = preview.height() as f64; let size = width.min(height); if size > 0.0 { let dx = offset_x * 64.0 / size; diff --git a/src/ui/picker.rs b/src/ui/picker.rs index f013ad6..76e1867 100644 --- a/src/ui/picker.rs +++ b/src/ui/picker.rs @@ -23,11 +23,15 @@ pub fn build_picker_page( let flow_box = FlowBox::new(); flow_box.set_valign(gtk::Align::Start); - flow_box.set_max_children_per_line(10); + flow_box.set_halign(gtk::Align::Fill); + flow_box.set_max_children_per_line(20); + flow_box.set_min_children_per_line(4); flow_box.set_selection_mode(gtk::SelectionMode::Single); let scroller = ScrolledWindow::new(); scroller.set_vexpand(true); + scroller.set_hexpand(true); + scroller.set_policy(gtk::PolicyType::Never, gtk::PolicyType::Automatic); scroller.set_child(Some(&flow_box)); root.append(&scroller);