fix: ensure editor scales SVG purely by stripping absolute dimensions, disable auto_save, and fix FlowBox columns
This commit is contained in:
+23
-5
@@ -24,8 +24,25 @@ impl CompositeIcon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(&self) -> String {
|
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 {
|
if let Some(emblem) = &self.emblem {
|
||||||
use regex::Regex;
|
|
||||||
|
|
||||||
fn parse_dims(svg: &str) -> (f64, f64) {
|
fn parse_dims(svg: &str) -> (f64, f64) {
|
||||||
if let Some(re) = Regex::new(r#"(?i)<svg[^>]*viewBox\s*=\s*"([^"]+)""#).ok() {
|
if let Some(re) = Regex::new(r#"(?i)<svg[^>]*viewBox\s*=\s*"([^"]+)""#).ok() {
|
||||||
@@ -87,15 +104,16 @@ impl CompositeIcon {
|
|||||||
mapped_x, mapped_y, scale_x, scale_y, emblem_inner
|
mapped_x, mapped_y, scale_x, scale_y, emblem_inner
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(idx) = self.bg.content.rfind("</svg>") {
|
let mut base_svg = strip_dimensions(&self.bg.content);
|
||||||
let mut new_svg = self.bg.content[..idx].to_string();
|
if let Some(idx) = base_svg.rfind("</svg>") {
|
||||||
|
let mut new_svg = base_svg[..idx].to_string();
|
||||||
new_svg.push_str(&emblem_group);
|
new_svg.push_str(&emblem_group);
|
||||||
new_svg
|
new_svg
|
||||||
} else {
|
} else {
|
||||||
self.bg.content.clone() // fallback
|
base_svg
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.bg.content.clone()
|
strip_dimensions(&self.bg.content)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -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) {
|
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,
|
Ok(s) => s,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("Failed to open {}: {e:#}", icon_path.display());
|
eprintln!("Failed to open {}: {e:#}", icon_path.display());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
scheme.auto_save = false;
|
||||||
|
|
||||||
let composite = Rc::new(RefCell::new(CompositeIcon::new(scheme)));
|
let composite = Rc::new(RefCell::new(CompositeIcon::new(scheme)));
|
||||||
|
|
||||||
|
|||||||
+2
-3
@@ -1,5 +1,4 @@
|
|||||||
use crate::composite_icon::CompositeIcon;
|
use crate::composite_icon::CompositeIcon;
|
||||||
use gtk::glib;
|
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk::{
|
use gtk::{
|
||||||
Box as GtkBox, ColorDialog, ColorDialogButton, Label, Orientation, Picture, ScrolledWindow,
|
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 scale_y = scale_y.clone();
|
||||||
let preview = preview.clone();
|
let preview = preview.clone();
|
||||||
move |_, offset_x, offset_y| {
|
move |_, offset_x, offset_y| {
|
||||||
let width = preview.allocated_width() as f64;
|
let width = preview.width() as f64;
|
||||||
let height = preview.allocated_height() as f64;
|
let height = preview.height() as f64;
|
||||||
let size = width.min(height);
|
let size = width.min(height);
|
||||||
if size > 0.0 {
|
if size > 0.0 {
|
||||||
let dx = offset_x * 64.0 / size;
|
let dx = offset_x * 64.0 / size;
|
||||||
|
|||||||
+5
-1
@@ -23,11 +23,15 @@ pub fn build_picker_page(
|
|||||||
|
|
||||||
let flow_box = FlowBox::new();
|
let flow_box = FlowBox::new();
|
||||||
flow_box.set_valign(gtk::Align::Start);
|
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);
|
flow_box.set_selection_mode(gtk::SelectionMode::Single);
|
||||||
|
|
||||||
let scroller = ScrolledWindow::new();
|
let scroller = ScrolledWindow::new();
|
||||||
scroller.set_vexpand(true);
|
scroller.set_vexpand(true);
|
||||||
|
scroller.set_hexpand(true);
|
||||||
|
scroller.set_policy(gtk::PolicyType::Never, gtk::PolicyType::Automatic);
|
||||||
scroller.set_child(Some(&flow_box));
|
scroller.set_child(Some(&flow_box));
|
||||||
root.append(&scroller);
|
root.append(&scroller);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user