diff --git a/ATTRIBUTION.md b/ATTRIBUTION.md index 3c03a6abda..d5d8c80a46 100644 --- a/ATTRIBUTION.md +++ b/ATTRIBUTION.md @@ -30,7 +30,13 @@ next to them. | `epaint_default_fonts::EGUI_ICONS` (build input; deflated into `OUT_DIR/egui_fonts/egui-icons.ttf.deflate`, registered by `crates/ui-egui/src/egui_fonts.rs`) | egui-icons, five-glyph subset of emoji-icon-font | John Slegers | [egui fork at 6d518fc](https://github.com/storytold/egui/tree/6d518fc799681571963842f95b55a6b68431b15a/crates/epaint_default_fonts/fonts), [original](https://github.com/jslegers/emoji-icon-font); egui subset, unmodified here | MIT; Copyright (c) 2014 John Slegers; full upstream notice in [NOTICE](NOTICE) | | `assets/fonts/Inter-Regular.ttf`, `Inter-Medium.ttf`, `Inter-SemiBold.ttf` | Inter 4.001 (UI font) | The Inter Project Authors (Rasmus Andersson) | | SIL OFL 1.1, [`assets/fonts/OFL-Inter.txt`](assets/fonts/OFL-Inter.txt) | | `assets/fonts/JetBrainsMono-Regular.ttf` | JetBrains Mono 2.305 (numeric font) | The JetBrains Mono Project Authors | | SIL OFL 1.1, [`assets/fonts/OFL-JetBrainsMono.txt`](assets/fonts/OFL-JetBrainsMono.txt) | +<<<<<<< HEAD | `assets/icons/*.svg` except `slice-knife.svg`, `slice-select.svg`, `font-similar.svg`, `font-variable.svg`, `sampler.svg`, `artboard.svg`, `perspective-crop.svg`, `frame-placeholder.svg`, `ellipse-dashed.svg`, `gradient.svg`, `type-mask.svg`, `type-mask-vertical.svg`, `text-warp.svg`, `clip-below.svg`, `clip-release.svg`, `layer-mask.svg`, `adjustment-layer.svg`, `brush-replace.svg`, `quick-selection.svg`, `eraser-background.svg`, `eraser-magic.svg`, `lasso-magnetic.svg`, `direct-select.svg`, `convert-point.svg`, `pen-add-anchor.svg`, `pen-delete-anchor.svg`, `pen-freeform.svg`, `pen-curvature.svg`, `bandage-sparkle.svg`, `painting-symmetry.svg`, `symmetry-*.svg`, `path-op-*.svg` and `marquee-{row,column}.svg`, `align-edge-*.svg` and `distribute-*.svg` (113 files; `star-filled.svg` is `star.svg` with a solid fill) | Lucide icons | Lucide Icons and Contributors | (`icons/.svg`; `align-*` are now named `text-align-*` upstream) | ISC, [`assets/icons/LICENSE-lucide.txt`](assets/icons/LICENSE-lucide.txt) | +||||||| 59cb4c49b +| `assets/icons/*.svg` except `slice-knife.svg`, `slice-select.svg`, `sampler.svg`, `artboard.svg`, `perspective-crop.svg`, `frame-placeholder.svg`, `ellipse-dashed.svg`, `gradient.svg`, `type-mask.svg`, `type-mask-vertical.svg`, `text-warp.svg`, `clip-below.svg`, `clip-release.svg`, `layer-mask.svg`, `adjustment-layer.svg`, `brush-replace.svg`, `quick-selection.svg`, `eraser-background.svg`, `eraser-magic.svg`, `lasso-magnetic.svg`, `direct-select.svg`, `convert-point.svg`, `pen-add-anchor.svg`, `pen-delete-anchor.svg`, `pen-freeform.svg`, `pen-curvature.svg`, `bandage-sparkle.svg`, `painting-symmetry.svg`, `symmetry-*.svg` and `marquee-{row,column}.svg`, `align-edge-*.svg` and `distribute-*.svg` (113 files; `star-filled.svg` is `star.svg` with a solid fill) | Lucide icons | Lucide Icons and Contributors | (`icons/.svg`; `align-*` are now named `text-align-*` upstream) | ISC, [`assets/icons/LICENSE-lucide.txt`](assets/icons/LICENSE-lucide.txt) | +======= +| `assets/icons/*.svg` except `slice-knife.svg`, `slice-select.svg`, `sampler.svg`, `artboard.svg`, `perspective-crop.svg`, `frame-placeholder.svg`, `ellipse-dashed.svg`, `gradient.svg`, `type-mask.svg`, `type-mask-vertical.svg`, `text-warp.svg`, `clip-below.svg`, `clip-release.svg`, `layer-mask.svg`, `adjustment-layer.svg`, `brush-replace.svg`, `quick-selection.svg`, `eraser-background.svg`, `eraser-magic.svg`, `lasso-magnetic.svg`, `direct-select.svg`, `convert-point.svg`, `pen-add-anchor.svg`, `pen-delete-anchor.svg`, `pen-freeform.svg`, `pen-curvature.svg`, `bandage-sparkle.svg`, `painting-symmetry.svg`, `symmetry-*.svg` and `marquee-{row,column}.svg`, `align-edge-*.svg` and `distribute-*.svg` (114 files; `star-filled.svg` is `star.svg` with a solid fill, `rotate-ccw.svg` is `rotate-cw.svg` mirrored) | Lucide icons | Lucide Icons and Contributors | (`icons/.svg`; `align-*` are now named `text-align-*` upstream) | ISC, [`assets/icons/LICENSE-lucide.txt`](assets/icons/LICENSE-lucide.txt) | +>>>>>>> 47aea89e9220b996f0d5a0d2bb8b5938100b4ad1 | `assets/icons/{check,chevron-down,chevron-left,chevron-right,chevron-up,chevrons-left,chevrons-right,circle,clock,compass,info,link,link-2,lock,minus,monitor,moon,move,navigation,plus,search,square,trash,triangle,type,x,zoom-in}.svg` | Lucide icons derived from Feather (subset of the row above) | Cole Bemis (Feather), Lucide Contributors | via Lucide | MIT (Feather) and ISC (Lucide), [`assets/icons/LICENSE-lucide.txt`](assets/icons/LICENSE-lucide.txt) | | `assets/icons/slice-knife.svg` | Slice tool glyph | PhotoCraft contributors | Original work | MIT OR Apache-2.0 | | `assets/icons/slice-select.svg` | Slice Select tool glyph | PhotoCraft contributors | Original work | MIT OR Apache-2.0 | diff --git a/assets/icons/rotate-ccw.svg b/assets/icons/rotate-ccw.svg new file mode 100644 index 0000000000..988d5fe949 --- /dev/null +++ b/assets/icons/rotate-ccw.svg @@ -0,0 +1,14 @@ + + + + diff --git a/crates/ui-egui/src/dialogs/liquify_ui.rs b/crates/ui-egui/src/dialogs/liquify_ui.rs index 12425ea81a..97b6124445 100644 --- a/crates/ui-egui/src/dialogs/liquify_ui.rs +++ b/crates/ui-egui/src/dialogs/liquify_ui.rs @@ -805,7 +805,8 @@ fn tool_icon(t: LiquifyTool) -> &'static str { LiquifyTool::Reconstruct => "brush-cleaning", LiquifyTool::Smooth => "droplet", LiquifyTool::TwirlCw => "rotate-cw", - LiquifyTool::TwirlCcw => "undo-2", + // Twirl Clockwise's arrow mirrored: `undo-2` read as Undo (#9547). + LiquifyTool::TwirlCcw => "rotate-ccw", LiquifyTool::Pucker => "scan", LiquifyTool::Bloat => "maximize-2", LiquifyTool::PushLeft => "chevrons-left", diff --git a/crates/ui-egui/src/dialogs/liquify_ui/tests.rs b/crates/ui-egui/src/dialogs/liquify_ui/tests.rs index 743c41197d..148daaead6 100644 --- a/crates/ui-egui/src/dialogs/liquify_ui/tests.rs +++ b/crates/ui-egui/src/dialogs/liquify_ui/tests.rs @@ -153,6 +153,19 @@ fn brush_settings_are_remembered_between_uses() { /// Follow-up to #1494 / #1484: Alt is captured at stroke-down and stays recorded /// through undo, redo and deterministic Liquify field reconstruction. +/// #9547: Twirl Counterclockwise draws Twirl Clockwise's arrow mirrored, not the Undo arrow, +/// and every Liquify tool's icon exists. +#[test] +fn twirl_counterclockwise_has_its_own_mirrored_icon() { + assert_eq!(tool_icon(LiquifyTool::TwirlCcw), "rotate-ccw"); + let svg = |name: &str| crate::icon_data::ICONS.iter().find(|(n, _)| *n == name).map(|(_, b)| String::from_utf8_lossy(b).into_owned()); + let (cw, ccw) = (svg("rotate-cw").unwrap(), svg("rotate-ccw").expect("the rotate-ccw icon")); + assert!(ccw.contains("M3 12a9 9 0 1 0 9-9") && cw.contains("M21 12a9 9 0 1 1-9-9"), "mirror images"); + for t in [LiquifyTool::ForwardWarp, LiquifyTool::TwirlCw, LiquifyTool::TwirlCcw, LiquifyTool::Pucker, LiquifyTool::Bloat] { + assert!(svg(tool_icon(t)).is_some(), "{t:?}: {}", tool_icon(t)); + } +} + #[test] fn alt_reversed_twirl_survives_replay_undo_and_redo() { let ctx = egui::Context::default(); diff --git a/crates/ui-egui/src/icon_data.rs b/crates/ui-egui/src/icon_data.rs index d261e762cd..4dfa76479b 100644 --- a/crates/ui-egui/src/icon_data.rs +++ b/crates/ui-egui/src/icon_data.rs @@ -127,6 +127,7 @@ pub static ICONS: &[(&str, &[u8])] = &[ ("rectangle-horizontal", include_bytes!("../../../assets/icons/rectangle-horizontal.svg")), ("rectangle-vertical", include_bytes!("../../../assets/icons/rectangle-vertical.svg")), ("redo-2", include_bytes!("../../../assets/icons/redo-2.svg")), + ("rotate-ccw", include_bytes!("../../../assets/icons/rotate-ccw.svg")), ("rotate-cw", include_bytes!("../../../assets/icons/rotate-cw.svg")), ("ruler", include_bytes!("../../../assets/icons/ruler.svg")), ("sampler", include_bytes!("../../../assets/icons/sampler.svg")),