mirror of
https://github.com/storytold/photocraft.git
synced 2026-10-14 19:26:51 -04:00
* fix(ui): use a linear gradient ramp glyph for the Gradient tool icon (#4172) * test(ui): verify Gradient tool icon rasterizes a left-to-right ramp (#4172)
This commit is contained in:
1 parent
ec61df6f06
commit
4122bc6918
5 files changed
+47
-3
No files matched your search
+2
-1
@@ -25,7 +25,7 @@ next to them.
|
||||
| `crates/ui-egui/src/i18n/tr.tsv` | Turkish UI translations | PhotoCraft contributors | Original translations of PhotoCraft's English labels | MIT OR Apache-2.0, [`LICENSE-translations.txt`](crates/ui-egui/src/i18n/LICENSE-translations.txt) |
|
||||
| `assets/fonts/Inter-Regular.ttf`, `Inter-Medium.ttf`, `Inter-SemiBold.ttf` | Inter 4.001 (UI font) | The Inter Project Authors (Rasmus Andersson) | <https://github.com/rsms/inter> | 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 | <https://github.com/JetBrains/JetBrainsMono> | SIL OFL 1.1, [`assets/fonts/OFL-JetBrainsMono.txt`](assets/fonts/OFL-JetBrainsMono.txt) |
|
||||
| `assets/icons/*.svg` except `slice-knife.svg`, `sampler.svg`, `artboard.svg`, `perspective-crop.svg`, `frame-placeholder.svg`, `type-mask.svg`, `type-mask-vertical.svg`, `clip-below.svg`, `clip-release.svg`, `layer-mask.svg`, `adjustment-layer.svg`, `brush-replace.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` (113 files; `star-filled.svg` is `star.svg` with a solid fill) | Lucide icons | Lucide Icons and Contributors | <https://github.com/lucide-icons/lucide> (`icons/<name>.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`, `sampler.svg`, `artboard.svg`, `perspective-crop.svg`, `frame-placeholder.svg`, `gradient.svg`, `type-mask.svg`, `type-mask-vertical.svg`, `clip-below.svg`, `clip-release.svg`, `layer-mask.svg`, `adjustment-layer.svg`, `brush-replace.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` (113 files; `star-filled.svg` is `star.svg` with a solid fill) | Lucide icons | Lucide Icons and Contributors | <https://github.com/lucide-icons/lucide> (`icons/<name>.svg`; `align-*` are now named `text-align-*` upstream) | ISC, [`assets/icons/LICENSE-lucide.txt`](assets/icons/LICENSE-lucide.txt) |
|
||||
| `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 | <https://github.com/feathericons/feather> 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/sampler.svg` | Color Sampler tool glyph: a target reticle marking a sampled pixel | PhotoCraft contributors | Original work | MIT OR Apache-2.0 |
|
||||
@@ -37,6 +37,7 @@ next to them.
|
||||
| `assets/icons/clip-below.svg`, `assets/icons/clip-release.svg` | Clipping-mask cursors (⌥ over the line between two layers): a hooked arrow onto the layer below; the same with a small "no" badge to release | PhotoCraft contributors | Original work | MIT OR Apache-2.0 |
|
||||
| `assets/icons/layer-mask.svg`, `assets/icons/adjustment-layer.svg` | Layers panel footer glyphs: Add a mask (a frame around a solid disc) and New Fill or Adjustment Layer (a circle, one half solid), drawn on Lucide's 24 px grid and stroke | PhotoCraft contributors | Original work | MIT OR Apache-2.0 |
|
||||
| `assets/icons/frame-placeholder.svg` | Frame tool glyph: an empty placeholder frame, crossed corner to corner | PhotoCraft contributors | Original work | MIT OR Apache-2.0 |
|
||||
| `assets/icons/gradient.svg` | Gradient tool glyph: a rounded rectangle filled with a left-to-right linear ramp, drawn on Lucide's 24 px grid and stroke | PhotoCraft contributors | Original work | MIT OR Apache-2.0 |
|
||||
| `assets/icons/eraser-background.svg`, `assets/icons/eraser-magic.svg` | Background Eraser and Magic Eraser tool glyphs: Lucide `eraser` plus added marks | Lucide Icons and Contributors; marks by PhotoCraft contributors | Derived from <https://github.com/lucide-icons/lucide> `icons/eraser.svg` | ISC, [`assets/icons/LICENSE-lucide.txt`](assets/icons/LICENSE-lucide.txt) |
|
||||
| `assets/icons/brush-replace.svg` | Color Replacement tool glyph: Lucide `brush` plus two swap arrows | Lucide Icons and Contributors; arrows by PhotoCraft contributors | Derived from <https://github.com/lucide-icons/lucide> `icons/brush.svg` | ISC, [`assets/icons/LICENSE-lucide.txt`](assets/icons/LICENSE-lucide.txt) |
|
||||
| `assets/icons/bandage-sparkle.svg` | Remove tool glyph: Lucide `bandage` moved down, plus a sparkle mark | Lucide Icons and Contributors; mark by PhotoCraft contributors | Derived from <https://github.com/lucide-icons/lucide> `icons/bandage.svg` | ISC, [`assets/icons/LICENSE-lucide.txt`](assets/icons/LICENSE-lucide.txt) |
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<defs>
|
||||
<linearGradient id="g" x1="3" y1="0" x2="20" y2="0" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0%" stop-color="currentColor" stop-opacity="0.9" />
|
||||
<stop offset="100%" stop-color="currentColor" stop-opacity="0" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<rect width="18" height="16" x="3" y="4" rx="2" fill="url(#g)" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 549 B |
@@ -54,6 +54,8 @@ pub static ICONS: &[(&str, &[u8])] = &[
|
||||
("folder-plus", include_bytes!("../../../assets/icons/folder-plus.svg")),
|
||||
("frame-placeholder", include_bytes!("../../../assets/icons/frame-placeholder.svg")),
|
||||
("gauge", include_bytes!("../../../assets/icons/gauge.svg")),
|
||||
// PhotoCraft original: the Gradient tool glyph (a rectangle filled with a linear ramp).
|
||||
("gradient", include_bytes!("../../../assets/icons/gradient.svg")),
|
||||
("grid-2x2", include_bytes!("../../../assets/icons/grid-2x2.svg")),
|
||||
("grid-3x3", include_bytes!("../../../assets/icons/grid-3x3.svg")),
|
||||
("hand", include_bytes!("../../../assets/icons/hand.svg")),
|
||||
|
||||
@@ -111,7 +111,7 @@ pub fn tool_icon(t: Tool) -> &'static str {
|
||||
Tool::Slice => "slice-knife",
|
||||
Tool::SliceSelect => "square-dashed-mouse-pointer",
|
||||
Tool::Frame => "frame-placeholder",
|
||||
Tool::Gradient => "blend",
|
||||
Tool::Gradient => "gradient",
|
||||
Tool::PaintBucket => "paint-bucket",
|
||||
Tool::Type | Tool::VerticalType => "type",
|
||||
Tool::HorizontalTypeMask => "type-mask",
|
||||
@@ -218,6 +218,28 @@ mod tests {
|
||||
for t in Tool::ALL {
|
||||
assert!(exists(tool_icon(t)), "{t:?}");
|
||||
}
|
||||
assert_eq!(tool_icon(Tool::Gradient), "gradient");
|
||||
assert_ne!(tool_icon(Tool::Gradient), tool_icon(Tool::PaintBucket));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gradient_tool_icon_rasterizes_left_to_right_ramp() {
|
||||
let egui::ImageSource::Bytes { bytes, .. } = white_icons().source(tool_icon(Tool::Gradient)) else {
|
||||
panic!("icon source must be embedded bytes");
|
||||
};
|
||||
let image = egui_extras::image::load_svg_bytes_with_size(
|
||||
bytes.as_ref(),
|
||||
egui::load::SizeHint::Size { width: 24, height: 24, maintain_aspect_ratio: true },
|
||||
&Default::default(),
|
||||
)
|
||||
.unwrap();
|
||||
let left_alpha = image[(6, 12)].a();
|
||||
let mid_alpha = image[(12, 12)].a();
|
||||
let right_alpha = image[(18, 12)].a();
|
||||
assert!(
|
||||
left_alpha > mid_alpha && mid_alpha > right_alpha,
|
||||
"interior ramp should fade from left ({left_alpha}) through middle ({mid_alpha}) to right ({right_alpha})"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -1187,7 +1187,7 @@ pub fn options_bar(app: &mut PhotocraftApp, ui: &mut egui::Ui) {
|
||||
ui.spacing_mut().item_spacing.x = 2.0;
|
||||
let before = app.ui.tool_options.clone();
|
||||
for (style, icon, tip) in [
|
||||
("linear", "blend", tl!("Linear Gradient")),
|
||||
("linear", "gradient", tl!("Linear Gradient")),
|
||||
("radial", "circle", tl!("Radial Gradient")),
|
||||
("angle", "rotate-cw", tl!("Angle Gradient")),
|
||||
("reflected", "arrow-left-right", tl!("Reflected Gradient")),
|
||||
|
||||
Reference in new issue
Block a user