graphic design tool
git clone https://git.lucas.co/cce-designer.git
Update system configuration and interface modules
Cargo.lock | 290 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
src/main.rs | 97 +++++++++++++++++++-
2 files changed, 381 insertions(+), 6 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
index 2a97160..7399529 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,6 +2,12 @@
# It is not intended for manual editing.
version = 4
+[[package]]
+name = "adler2"
+version = "2.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
+
[[package]]
name = "android_system_properties"
version = "0.1.5"
@@ -11,6 +17,12 @@ dependencies = [
"libc",
]
+[[package]]
+name = "arrayref"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb"
+
[[package]]
name = "arrayvec"
version = "0.7.6"
@@ -32,6 +44,12 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
+[[package]]
+name = "base64"
+version = "0.22.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
+
[[package]]
name = "bit-set"
version = "0.8.0"
@@ -191,6 +209,7 @@ dependencies = [
"glyphon",
"pollster",
"raw-window-handle",
+ "resvg",
"smithay-client-toolkit",
"tokio",
"wayland-client",
@@ -208,6 +227,12 @@ dependencies = [
"unicode-width",
]
+[[package]]
+name = "color_quant"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
+
[[package]]
name = "concurrent-queue"
version = "2.5.0"
@@ -256,7 +281,7 @@ dependencies = [
"rangemap",
"rayon",
"rustc-hash 1.1.0",
- "rustybuzz",
+ "rustybuzz 0.14.1",
"self_cell",
"swash",
"sys-locale",
@@ -267,6 +292,15 @@ dependencies = [
"unicode-segmentation",
]
+[[package]]
+name = "crc32fast"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
+dependencies = [
+ "cfg-if",
+]
+
[[package]]
name = "crossbeam-deque"
version = "0.8.6"
@@ -298,6 +332,12 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f"
+[[package]]
+name = "data-url"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be1e0bca6c3637f992fc1cc7cbc52a78c1ef6db076dbf1059c4323d6a2048376"
+
[[package]]
name = "dlib"
version = "0.5.3"
@@ -363,12 +403,37 @@ dependencies = [
"num-traits",
]
+[[package]]
+name = "fdeflate"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c"
+dependencies = [
+ "simd-adler32",
+]
+
[[package]]
name = "find-msvc-tools"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582"
+[[package]]
+name = "flate2"
+version = "1.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c"
+dependencies = [
+ "crc32fast",
+ "miniz_oxide",
+]
+
+[[package]]
+name = "float-cmp"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
+
[[package]]
name = "foldhash"
version = "0.1.5"
@@ -390,7 +455,7 @@ version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbc773e24e02d4ddd8395fd30dc147524273a83e54e0f312d986ea30de5f5646"
dependencies = [
- "roxmltree",
+ "roxmltree 0.20.0",
]
[[package]]
@@ -458,6 +523,16 @@ dependencies = [
"slab",
]
+[[package]]
+name = "gif"
+version = "0.13.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ae047235e33e2829703574b54fdec96bfbad892062d97fed2f76022287de61b"
+dependencies = [
+ "color_quant",
+ "weezl",
+]
+
[[package]]
name = "gl_generator"
version = "0.14.0"
@@ -593,6 +668,12 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df"
+[[package]]
+name = "imagesize"
+version = "0.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "029d73f573d8e8d63e6d5020011d3255b28c3ba85d6cf870a07184ed23de9284"
+
[[package]]
name = "indexmap"
version = "2.14.0"
@@ -637,6 +718,12 @@ dependencies = [
"syn",
]
+[[package]]
+name = "jpeg-decoder"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "00810f1d8b74be64b13dbf3db89ac67740615d6c891f0e7b6179326533011a07"
+
[[package]]
name = "js-sys"
version = "0.3.98"
@@ -666,6 +753,17 @@ version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
+[[package]]
+name = "kurbo"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c62026ae44756f8a599ba21140f350303d4f08dcdcc71b5ad9c9bb8128c13c62"
+dependencies = [
+ "arrayvec",
+ "euclid",
+ "smallvec",
+]
+
[[package]]
name = "libc"
version = "0.2.186"
@@ -775,6 +873,16 @@ dependencies = [
"paste",
]
+[[package]]
+name = "miniz_oxide"
+version = "0.8.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316"
+dependencies = [
+ "adler2",
+ "simd-adler32",
+]
+
[[package]]
name = "mio"
version = "1.2.0"
@@ -898,6 +1006,12 @@ version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
+[[package]]
+name = "pico-args"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315"
+
[[package]]
name = "pin-project-lite"
version = "0.2.17"
@@ -910,6 +1024,19 @@ version = "0.3.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e"
+[[package]]
+name = "png"
+version = "0.17.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526"
+dependencies = [
+ "bitflags 1.3.2",
+ "crc32fast",
+ "fdeflate",
+ "flate2",
+ "miniz_oxide",
+]
+
[[package]]
name = "polling"
version = "3.11.0"
@@ -1032,6 +1159,38 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832"
+[[package]]
+name = "resvg"
+version = "0.41.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c2327ced609dadeed3e9702fec3e6b2ddd208758a9268d13e06566c6101ba533"
+dependencies = [
+ "gif",
+ "jpeg-decoder",
+ "log",
+ "pico-args",
+ "png",
+ "rgb",
+ "svgtypes",
+ "tiny-skia",
+ "usvg",
+]
+
+[[package]]
+name = "rgb"
+version = "0.8.53"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47b34b781b31e5d73e9fbc8689c70551fd1ade9a19e3e28cfec8580a79290cc4"
+dependencies = [
+ "bytemuck",
+]
+
+[[package]]
+name = "roxmltree"
+version = "0.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3cd14fd5e3b777a7422cca79358c57a8f6e3a703d9ac187448d0daf220c2407f"
+
[[package]]
name = "roxmltree"
version = "0.20.0"
@@ -1082,6 +1241,22 @@ version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
+[[package]]
+name = "rustybuzz"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "88117946aa1bfb53c2ae0643ceac6506337f44887f8c9fbfb43587b1cc52ba49"
+dependencies = [
+ "bitflags 2.11.1",
+ "bytemuck",
+ "smallvec",
+ "ttf-parser 0.20.0",
+ "unicode-bidi-mirroring",
+ "unicode-ccc",
+ "unicode-properties",
+ "unicode-script",
+]
+
[[package]]
name = "rustybuzz"
version = "0.14.1"
@@ -1176,6 +1351,27 @@ dependencies = [
"libc",
]
+[[package]]
+name = "simd-adler32"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214"
+
+[[package]]
+name = "simplecss"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a9c6883ca9c3c7c90e888de77b7a5c849c779d25d74a1269b0218b14e8b136c"
+dependencies = [
+ "log",
+]
+
+[[package]]
+name = "siphasher"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649"
+
[[package]]
name = "skrifa"
version = "0.22.3"
@@ -1260,6 +1456,15 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
+[[package]]
+name = "strict-num"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731"
+dependencies = [
+ "float-cmp",
+]
+
[[package]]
name = "strum"
version = "0.26.3"
@@ -1288,6 +1493,16 @@ version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0193cc4331cfd2f3d2011ef287590868599a2f33c3e69bc22c1a3d3acf9e02fb"
+[[package]]
+name = "svgtypes"
+version = "0.15.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68c7541fff44b35860c1a7a47a7cadf3e4a304c457b58f9870d9706ece028afc"
+dependencies = [
+ "kurbo",
+ "siphasher",
+]
+
[[package]]
name = "swash"
version = "0.1.19"
@@ -1368,6 +1583,32 @@ dependencies = [
"syn",
]
+[[package]]
+name = "tiny-skia"
+version = "0.11.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab"
+dependencies = [
+ "arrayref",
+ "arrayvec",
+ "bytemuck",
+ "cfg-if",
+ "log",
+ "png",
+ "tiny-skia-path",
+]
+
+[[package]]
+name = "tiny-skia-path"
+version = "0.11.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93"
+dependencies = [
+ "arrayref",
+ "bytemuck",
+ "strict-num",
+]
+
[[package]]
name = "tinyvec"
version = "1.11.0"
@@ -1471,6 +1712,12 @@ version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c"
+[[package]]
+name = "unicode-vo"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1d386ff53b415b7fe27b50bb44679e2cc4660272694b7b6f3326d8480823a94"
+
[[package]]
name = "unicode-width"
version = "0.1.14"
@@ -1483,6 +1730,33 @@ version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
+[[package]]
+name = "usvg"
+version = "0.41.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c704361d822337cfc00387672c7b59eaa72a1f0744f62b2a68aa228a0c6927d"
+dependencies = [
+ "base64",
+ "data-url",
+ "flate2",
+ "fontdb",
+ "imagesize",
+ "kurbo",
+ "log",
+ "pico-args",
+ "roxmltree 0.19.0",
+ "rustybuzz 0.13.0",
+ "simplecss",
+ "siphasher",
+ "strict-num",
+ "svgtypes",
+ "tiny-skia-path",
+ "unicode-bidi",
+ "unicode-script",
+ "unicode-vo",
+ "xmlwriter",
+]
+
[[package]]
name = "version_check"
version = "0.9.5"
@@ -1655,6 +1929,12 @@ dependencies = [
"wasm-bindgen",
]
+[[package]]
+name = "weezl"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88"
+
[[package]]
name = "wgpu"
version = "24.0.5"
@@ -1957,6 +2237,12 @@ version = "0.8.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ae8337f8a065cfc972643663ea4279e04e7256de865aa66fe25cec5fb912d3f"
+[[package]]
+name = "xmlwriter"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9"
+
[[package]]
name = "yazi"
version = "0.1.6"
diff --git a/src/main.rs b/src/main.rs
index 0d5f513..914ec31 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -4331,7 +4331,7 @@ fn geometry_to_spreadsheet_data(geom: &Geometry) -> (Vec<String>, Vec<Vec<String
if prev == i && t.elapsed() < std::time::Duration::from_millis(500) {
let dir_idx = self.node_slots.iter().position(|&x| x == i).unwrap();
let dir = self.current_dir();
- if dir_idx < dir.children.len() && !dir.children[dir_idx].children.is_empty() {
+ if dir_idx < dir.children.len() && (dir.children[dir_idx].node_type == "node" || dir.children[dir_idx].node_type == "opencl" || !dir.children[dir_idx].children.is_empty()) {
self.current_path.push(dir_idx);
self.on_path_changed();
changed = true;
@@ -4543,8 +4543,8 @@ fn geometry_to_spreadsheet_data(geom: &Geometry) -> (Vec<String>, Vec<Vec<String
if let Some(focused) = self.focused_widget {
if let Some(slot_idx) = self.node_slots.iter().position(|&x| x == focused) {
let dir = self.current_dir();
- if slot_idx < dir.children.len() && !dir.children[slot_idx].children.is_empty() {
- self.current_path.push(slot_idx);
+ if slot_idx < dir.children.len() && (dir.children[slot_idx].node_type == "node" || dir.children[slot_idx].node_type == "opencl" || !dir.children[slot_idx].children.is_empty()) {
+ self.current_path.push(slot_idx);
self.on_path_changed();
changed = true;
}
@@ -4560,6 +4560,95 @@ fn geometry_to_spreadsheet_data(geom: &Geometry) -> (Vec<String>, Vec<Vec<String
self.zoom(1.15, None);
changed = true;
}
+ "f" | "F" => {
+ if self.focused_pane == LEFT_MENUBAR_IDX {
+ let active_nodes = self.current_dir().children.len().min(self.node_slots.len());
+ if active_nodes == 0 {
+ self.grid_size_x = 80.0;
+ self.grid_size_y = 40.0;
+ self.skipped_col_w = 20.0;
+ self.skipped_row_h = 20.0;
+ self.pan_x = 20.0;
+ self.pan_y = 20.0;
+ } else {
+ let base_gx = 80.0;
+ let base_gy = 40.0;
+ let base_col_w = 20.0;
+ let base_row_h = 20.0;
+
+ let mut b_xmin = f32::MAX;
+ let mut b_xmax = f32::MIN;
+ let mut b_ymin = f32::MAX;
+ let mut b_ymax = f32::MIN;
+
+ for slot_idx in 0..active_nodes {
+ let (col, row) = self.left_offsets[slot_idx];
+ let x_min = col * (base_gx + base_col_w);
+ let x_max = x_min + base_gx;
+ let y_min = row * (base_gy + base_row_h);
+ let y_max = y_min + base_gy;
+
+ if x_min < b_xmin { b_xmin = x_min; }
+ if x_max > b_xmax { b_xmax = x_max; }
+ if y_min < b_ymin { b_ymin = y_min; }
+ if y_max > b_ymax { b_ymax = y_max; }
+ }
+
+ let w_base = b_xmax - b_xmin;
+ let h_base = b_ymax - b_ymin;
+
+ let viewport_w = self.content_left_w();
+ let body_h = self.body_h();
+ let viewport_h = body_h - MENUBAR_H - BREADCRUMB_H;
+
+ let padding = 40.0;
+ let padded_w = (viewport_w - 2.0 * padding).max(10.0);
+ let padded_h = (viewport_h - 2.0 * padding).max(10.0);
+
+ let fx = padded_w / w_base;
+ let fy = padded_h / h_base;
+ let mut f = fx.min(fy);
+
+ f = f.min(1.0).max(30.0 / base_gx);
+
+ self.grid_size_x = (base_gx * f).clamp(30.0, 500.0);
+ self.grid_size_y = (base_gy * f).clamp(15.0, 250.0);
+ self.skipped_col_w = base_col_w * f;
+ self.skipped_row_h = base_row_h * f;
+
+ let mut actual_xmin = f32::MAX;
+ let mut actual_xmax = f32::MIN;
+ let mut actual_ymin = f32::MAX;
+ let mut actual_ymax = f32::MIN;
+
+ for slot_idx in 0..active_nodes {
+ let (col, row) = self.left_offsets[slot_idx];
+ let x_min = col * (self.grid_size_x + self.skipped_col_w);
+ let x_max = x_min + self.grid_size_x;
+ let y_min = row * (self.grid_size_y + self.skipped_row_h);
+ let y_max = y_min + self.grid_size_y;
+
+ if x_min < actual_xmin { actual_xmin = x_min; }
+ if x_max > actual_xmax { actual_xmax = x_max; }
+ if y_min < actual_ymin { actual_ymin = y_min; }
+ if y_max > actual_ymax { actual_ymax = y_max; }
+ }
+
+ let actual_w = actual_xmax - actual_xmin;
+ let actual_h = actual_ymax - actual_ymin;
+
+ self.pan_x = (viewport_w - actual_w) / 2.0 - actual_xmin;
+ self.pan_y = (viewport_h - actual_h) / 2.0 - actual_ymin;
+ }
+
+ self.sync_grid_settings();
+ self.rebuild_positions();
+ self.apply_layout();
+ self.update_panel_bounds();
+ self.upload_vertices();
+ changed = true;
+ }
+ }
_ => {}
}
}
@@ -5628,7 +5717,7 @@ impl AppState {
}
HttpAction::Enter { slot } => {
let dir = state.current_dir();
- if slot < dir.children.len() && !dir.children[slot].children.is_empty() {
+ if slot < dir.children.len() && (dir.children[slot].node_type == "node" || dir.children[slot].node_type == "opencl" || !dir.children[slot].children.is_empty()) {
state.current_path.push(slot);
state.on_path_changed();
needs_redraw = true;