Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
Binary file not shown.
9 changes: 9 additions & 0 deletions crates/draw-engine/src/engine/frame.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ pub struct PaintView<'a> {
/// picture of the board, which it changes on every press without touching.
pub flowchart_pending: Vec<&'a DrawElement>,
pub selected: Vec<&'a DrawElement>,
/// The selectable element currently beneath the pointer, before a press commits selection.
pub hovered: Option<&'a DrawElement>,
/// Where a multi-selection's box and handles go: around what a transform carries,
/// the same box the handles are hit on. `None` when fewer than two are carried.
pub group_box: Option<WorldBounds>,
Expand Down Expand Up @@ -169,6 +171,7 @@ fn without_editor_chrome(view: &mut PaintView<'_>) {
view.flowchart_pending = Vec::new();
view.laser = Vec::new();
view.peer_lasers = Vec::new();
view.hovered = None;
view.peer_marks = Vec::new();
view.snap_guides = Vec::new();
view.linear_handles = Vec::new();
Expand Down Expand Up @@ -403,6 +406,11 @@ impl DrawEngine {
.filter_map(|id| self.scene.get(id))
.filter(|el| !el.is_deleted)
.collect();
let hovered = self
.hovered_id
.as_deref()
.and_then(|id| self.scene.get(id))
.filter(|el| !el.is_deleted);
let lasso = match &self.interaction {
Some(super::Interaction::Lasso { path, .. }) => path.clone(),
_ => Vec::new(),
Expand Down Expand Up @@ -554,6 +562,7 @@ impl DrawEngine {
erasing_revision: self.erasing_revision,
flowchart_pending,
selected,
hovered,
group_box,
marquee,
lasso,
Expand Down
18 changes: 16 additions & 2 deletions crates/draw-engine/src/engine/hover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,18 @@ impl DrawEngine {
/// outline a few units off an intersection lights whatever that intersection is over, and
/// near the tolerance's edge it lights **nothing** at all.
pub fn hover_pointer(&mut self, sx: f64, sy: f64) {
if self.tool != DrawTool::Arrow || self.interaction.is_some() || self.multi_linear.is_some()
{
if self.interaction.is_some() || self.multi_linear.is_some() {
return;
}
if self.tool == DrawTool::Select {
let next = self.pressed_at(sx, sy).map(|el| el.id.clone());
if next != self.hovered_id {
self.hovered_id = next;
self.request_draw();
}
return;
}
if self.tool != DrawTool::Arrow {
return;
}
let world = self.screen_to_world(sx, sy);
Expand Down Expand Up @@ -145,10 +155,14 @@ impl DrawEngine {
if self.interaction.is_some() || self.multi_linear.is_some() {
return;
}
let hover_changed = self.hovered_id.take().is_some();
if self.binding_highlight.take().is_some() {
self.binding_point = None;
self.request_draw();
}
if hover_changed {
self.request_draw();
}
}

/// Ctrl/Cmd, as held for the pointer event about to be reported: while it is down an
Expand Down
6 changes: 6 additions & 0 deletions crates/draw-engine/src/engine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,8 @@ pub struct DrawEngine {
settled_selection: std::rc::Rc<stamp::SelectionState>,
/// Between a press and its release, when what the press selects is not settled yet.
pointer_open: bool,
/// Element currently under the pointer in the Select tool, for immediate hover feedback.
hovered_id: Option<String>,
/// The right-button session in progress, if one is. Outlives the gesture it holds,
/// because the platform's `contextmenu` can arrive after the release that ended it —
/// see [`Self::consumes_context_menu`] and [`crate::pan`].
Expand Down Expand Up @@ -406,6 +408,7 @@ impl DrawEngine {
history_seq: 0,
settled_selection: std::rc::Rc::default(),
pointer_open: false,
hovered_id: None,
secondary_pan: None,
suppress_next_context_menu: false,
remote_refused: std::collections::HashMap::new(),
Expand Down Expand Up @@ -803,6 +806,9 @@ impl DrawEngine {
}

pub fn set_tool(&mut self, tool: DrawTool) {
if self.tool != tool {
self.hovered_id = None;
}
self.set_tool_step(tool);
self.refresh_live();
}
Expand Down
10 changes: 10 additions & 0 deletions crates/draw-engine/src/wasm/paint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2059,6 +2059,16 @@ fn paint_overlay(ctx: &CanvasRenderingContext2d, view: &PaintView) {
}
}

if let Some(hovered) = view.hovered {
// Hover feedback is deliberately an outline only: it previews the click without
// adding handles or changing the committed selection.
ctx.save();
set_stroke(ctx, &view.theme.accent);
ctx.set_global_alpha(0.75);
paint_element_outline(ctx, view, hovered);
ctx.restore();
}

if view.selected.len() == 1 {
paint_shape_selection(ctx, view, view.selected[0]);
paint_radius_handles(ctx, view);
Expand Down
8 changes: 4 additions & 4 deletions crates/draw-engine/tests/ci_svg_fonts_bytes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,11 @@ const SHIPPED_CRC32: [(&str, u32); 10] = [
),
(
"Lilita/Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYEF8RXi4EwQ.woff2",
0x1380_bdc3,
0x9a95_2276,
),
(
"Lilita/Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYE98RXi4EwSsbg.woff2",
0x8a23_e0d0,
0xda05_848c,
),
];

Expand Down Expand Up @@ -362,11 +362,11 @@ fn the_shipped_files_hash_to_the_recorded_values() {
),
(
include_bytes!("../assets/fonts/Lilita/Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYEF8RXi4EwQ.woff2"),
0x1380_bdc3,
0x9a95_2276,
),
(
include_bytes!("../assets/fonts/Lilita/Lilita-Regular-i7dPIFZ9Zz-WBtRtedDbYE98RXi4EwSsbg.woff2"),
0x8a23_e0d0,
0xda05_848c,
),
];
for (bytes, expected) in &files {
Expand Down
Loading