Windows' crosshair cursor inverts the pixels under it, so it vanishes over mid-grey (the pasteboard, many photos). On Windows the canvas now draws a black-and-white crosshair itself and hides the system one. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
d64f809e4d
commit
3d003bd9d0
|
|
@ -213,6 +213,23 @@ pub(crate) fn stroke_command(tool: Tool) -> &'static str {
|
|||
if tool == Tool::Pencil { "paint.pencil" } else { "paint.stroke" }
|
||||
}
|
||||
|
||||
/// Windows' crosshair cursor inverts the pixels under it, so over mid-grey (the pasteboard, many
|
||||
/// photos) it vanishes (#737). There the canvas draws a black-and-white crosshair itself, like
|
||||
/// Photoshop's, and hides the system one.
|
||||
fn visible_crosshair(icon: egui::CursorIcon, painter: &egui::Painter, p: Pos2, draw: bool) -> egui::CursorIcon {
|
||||
if !draw || icon != egui::CursorIcon::Crosshair {
|
||||
return icon;
|
||||
}
|
||||
let p = pos2(p.x.round() + 0.5, p.y.round() + 0.5);
|
||||
let (gap, len) = (2.0, 8.0);
|
||||
for (w, c) in [(3.0, Color32::from_black_alpha(160)), (1.0, Color32::from_white_alpha(235))] {
|
||||
for d in [vec2(1.0, 0.0), vec2(-1.0, 0.0), vec2(0.0, 1.0), vec2(0.0, -1.0)] {
|
||||
painter.line_segment([p + d * gap, p + d * len], Stroke::new(w, c));
|
||||
}
|
||||
}
|
||||
egui::CursorIcon::None
|
||||
}
|
||||
|
||||
/// The Pencil's cursor at `doc` (document pixels): the whole-pixel square its dab fills
|
||||
/// (`paint::grid_square`), in screen points with its edges on physical pixels (`ppp` = pixels
|
||||
/// per point), so it lines up with the pixel grid at any zoom.
|
||||
|
|
@ -2060,6 +2077,7 @@ pub fn canvas_view(app: &mut PhotocraftApp, ui: &mut egui::Ui, idx: usize, rect:
|
|||
Tool::MagneticLasso => crate::magnetic_lasso_ui::cursor(app, &painter, p, view.zoom),
|
||||
_ => egui::CursorIcon::Crosshair,
|
||||
};
|
||||
let icon = visible_crosshair(icon, &painter, p, cfg!(target_os = "windows"));
|
||||
ui.ctx().set_cursor_icon(icon);
|
||||
// Selection tools: + / − / × badge for the effective mode (#170). A gesture keeps the
|
||||
// mode it started with (⇧ then constrains the marquee instead of adding).
|
||||
|
|
@ -2892,6 +2910,17 @@ fn hex(c: [f32; 4]) -> String {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
#[test]
|
||||
fn windows_draws_its_own_crosshair() {
|
||||
// #737: Windows' inverting crosshair vanishes over mid-grey; the canvas draws one instead.
|
||||
let ctx = egui::Context::default();
|
||||
let painter = egui::Painter::new(ctx, egui::LayerId::background(), egui::Rect::EVERYTHING);
|
||||
let p = egui::pos2(10.0, 10.0);
|
||||
assert_eq!(super::visible_crosshair(egui::CursorIcon::Crosshair, &painter, p, true), egui::CursorIcon::None);
|
||||
assert_eq!(super::visible_crosshair(egui::CursorIcon::Crosshair, &painter, p, false), egui::CursorIcon::Crosshair);
|
||||
assert_eq!(super::visible_crosshair(egui::CursorIcon::Move, &painter, p, true), egui::CursorIcon::Move);
|
||||
}
|
||||
|
||||
use super::*;
|
||||
|
||||
/// #569: displays 1 (sRGB) and 4 (Display P3) side by side, and a document filled with an
|
||||
|
|
|
|||
Loading…
Reference in New Issue