Merge pull request #1150 from storytold/fix/selection-arrow-colours

Icons: the Selection arrow is black and Direct Selection's white in every theme
This commit is contained in:
BFlat 2026-10-11 15:30:34 +07:00 committed by GitHub
commit fad7248e7d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 46 additions and 3 deletions

View File

@ -98,6 +98,7 @@ Generated-in-code art is original and has no file to list. This covers the defau
| `assets/icons/dc-arc.svg` | VectorCraft contributors | Original work, drawn for VectorCraft | MIT OR Apache-2.0 | |
| `assets/icons/dc-arrow-down.svg` | VectorCraft contributors | Original work, drawn for VectorCraft | MIT OR Apache-2.0 | |
| `assets/icons/dc-arrow-extend.svg` | VectorCraft contributors | Original work, drawn for VectorCraft | MIT OR Apache-2.0 | |
| `assets/icons/dc-arrow-fill.svg` | VectorCraft contributors | Original work, drawn for VectorCraft | MIT OR Apache-2.0 | The Selection and Direct Selection arrows' fill, painted black or white under their outline |
| `assets/icons/dc-arrow-tip.svg` | VectorCraft contributors | Original work, drawn for VectorCraft | MIT OR Apache-2.0 | |
| `assets/icons/dc-arrow-up.svg` | VectorCraft contributors | Original work, drawn for VectorCraft | MIT OR Apache-2.0 | |
| `assets/icons/dc-artboard-options.svg` | VectorCraft contributors | Original work, drawn for VectorCraft | MIT OR Apache-2.0 | |

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M6 3 L6 19 L10 15 L13 21 L15.5 20 L12.6 14 L18 14 Z" fill="currentColor"/></svg>

After

Width:  |  Height:  |  Size: 173 B

View File

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M6 3 L6 19 L10 15 L13 21 L15.5 20 L12.6 14 L18 14 Z" fill="currentColor" stroke-width="1"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M6 3 L6 19 L10 15 L13 21 L15.5 20 L12.6 14 L18 14 Z" fill="none"/></svg>

Before

Width:  |  Height:  |  Size: 290 B

After

Width:  |  Height:  |  Size: 265 B

View File

@ -66,6 +66,7 @@ pub static ICONS: &[(&str, &[u8])] = &[
("dc-dir-off", include_bytes!("../../../assets/icons/dc-dir-off.svg")),
("dc-dir-on", include_bytes!("../../../assets/icons/dc-dir-on.svg")),
("dc-direct", include_bytes!("../../../assets/icons/dc-direct.svg")),
("dc-arrow-fill", include_bytes!("../../../assets/icons/dc-arrow-fill.svg")),
("dc-dist-bottom", include_bytes!("../../../assets/icons/dc-dist-bottom.svg")),
("dc-dist-hcenter", include_bytes!("../../../assets/icons/dc-dist-hcenter.svg")),
("dc-dist-hspace", include_bytes!("../../../assets/icons/dc-dist-hspace.svg")),

View File

@ -105,8 +105,19 @@ pub fn source(name: &str) -> ImageSource<'static> {
table().source(name)
}
/// Paint icon `name` into `rect` tinted with `tint`.
/// Paint icon `name` into `rect` tinted with `tint`. The Selection and Direct Selection arrows are
/// black and white whatever the theme, as users know them (a light theme colour would make the
/// Selection arrow look like Direct Selection's): their fill is painted first, then their outline
/// in `tint`.
pub fn paint(ui: &Ui, name: &str, rect: Rect, tint: Color32) {
let fill = match name {
"dc-selection" => Some(Color32::BLACK),
"dc-direct" => Some(Color32::WHITE),
_ => None,
};
if let Some(fill) = fill {
egui::Image::new(source("dc-arrow-fill")).tint(fill).fit_to_exact_size(rect.size()).paint_at(ui, rect);
}
egui::Image::new(source(name)).tint(tint).fit_to_exact_size(rect.size()).paint_at(ui, rect);
}
@ -121,6 +132,35 @@ pub fn icon(ui: &mut Ui, name: &str, size: f32, tint: Color32) -> egui::Response
mod tests {
use super::*;
/// The tints of the images `name` paints, bottom first.
fn tints(name: &str, tint: Color32) -> Vec<Color32> {
let ctx = egui::Context::default();
egui_extras::install_image_loaders(&ctx);
let draw = |ui: &mut Ui| paint(ui, name, Rect::from_min_size(egui::Pos2::ZERO, Vec2::splat(24.0)), tint);
// The first frame loads the images; the second draws them.
ctx.run_ui(egui::RawInput::default(), draw).textures_delta.clear();
let mut out = ctx.run_ui(egui::RawInput::default(), draw);
out.textures_delta.clear();
out.shapes
.iter()
.filter_map(|s| match &s.shape {
egui::Shape::Mesh(m) => m.vertices.first().map(|v| v.color),
egui::Shape::Rect(r) if r.brush.is_some() => Some(r.fill),
_ => None,
})
.collect()
}
/// The Selection arrow is black and Direct Selection's white in every theme (a reported swap
/// in the dark themes), under an outline in the theme's colour; other icons are one layer.
#[test]
fn the_selection_arrows_are_black_and_white_under_the_theme_outline() {
let light = Color32::from_gray(220);
assert_eq!(tints("dc-selection", light), [Color32::BLACK, light]);
assert_eq!(tints("dc-direct", light), [Color32::WHITE, light]);
assert_eq!(tints("dc-group-select", light), [light]);
}
/// Characterize the pre-extraction loader against every embedded asset, including custom
/// icons. A shared-crate update must not silently change our stroke weight or cache keys.
#[test]