mirror of
https://github.com/ZSeven-W/openpencil.git
synced 2026-05-31 19:04:29 +07:00
fix(canvas): align rust z-order with renderer
Some checks failed
Rust check (native) / macos-latest / 1.94 (push) Waiting to run
Rust check (native) / windows-latest / 1.94 (push) Waiting to run
Rust multi-platform build / linux-aarch64 (push) Waiting to run
Rust multi-platform build / macos-aarch64 (push) Waiting to run
Rust multi-platform build / windows-x86_64 (push) Waiting to run
Rust multi-platform build / macos-x86_64 (push) Waiting to run
Rust multi-platform build / windows-aarch64 (push) Waiting to run
Rust multi-platform build / ios-aarch64 (cargo check only) (push) Waiting to run
Rust multi-platform build / ios-aarch64-sim (cargo check only) (push) Waiting to run
Rust check (native) / ubuntu-latest / 1.94 (push) Failing after 2s
Rust check (native) / cargo-deny (native) (push) Failing after 2s
Rust check (native) / diagnostics golden drift (push) Failing after 2s
Rust multi-platform build / linux-x86_64 (push) Failing after 1s
Rust multi-platform build / wasm32-unknown-unknown / op-host-web (compile guard) (push) Failing after 2s
Rust multi-platform build / android-aarch64 (cargo check only) (push) Failing after 1s
Rust multi-platform build / android-x86_64 (cargo check only) (push) Failing after 1s
WASM bundle check (kickoff §1.2) / cargo check --target wasm32-unknown-unknown (push) Failing after 1s
WASM bundle check (kickoff §1.2) / cargo-deny --target wasm32-unknown-unknown check bans (push) Failing after 2s
Some checks failed
Rust check (native) / macos-latest / 1.94 (push) Waiting to run
Rust check (native) / windows-latest / 1.94 (push) Waiting to run
Rust multi-platform build / linux-aarch64 (push) Waiting to run
Rust multi-platform build / macos-aarch64 (push) Waiting to run
Rust multi-platform build / windows-x86_64 (push) Waiting to run
Rust multi-platform build / macos-x86_64 (push) Waiting to run
Rust multi-platform build / windows-aarch64 (push) Waiting to run
Rust multi-platform build / ios-aarch64 (cargo check only) (push) Waiting to run
Rust multi-platform build / ios-aarch64-sim (cargo check only) (push) Waiting to run
Rust check (native) / ubuntu-latest / 1.94 (push) Failing after 2s
Rust check (native) / cargo-deny (native) (push) Failing after 2s
Rust check (native) / diagnostics golden drift (push) Failing after 2s
Rust multi-platform build / linux-x86_64 (push) Failing after 1s
Rust multi-platform build / wasm32-unknown-unknown / op-host-web (compile guard) (push) Failing after 2s
Rust multi-platform build / android-aarch64 (cargo check only) (push) Failing after 1s
Rust multi-platform build / android-x86_64 (cargo check only) (push) Failing after 1s
WASM bundle check (kickoff §1.2) / cargo check --target wasm32-unknown-unknown (push) Failing after 1s
WASM bundle check (kickoff §1.2) / cargo-deny --target wasm32-unknown-unknown check bans (push) Failing after 2s
This commit is contained in:
parent
b0b52a7842
commit
e1ba222e87
5 changed files with 27 additions and 27 deletions
|
|
@ -238,28 +238,28 @@ fn root_ids(s: &crate::state::EditorState) -> Vec<String> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn reorder_selected_up_moves_to_higher_index() {
|
fn reorder_selected_up_moves_toward_front_index() {
|
||||||
let mut s = three_rects();
|
let mut s = three_rects();
|
||||||
s.set_single_selection(NodeId::new("n2"));
|
s.set_single_selection(NodeId::new("n2"));
|
||||||
assert!(s.reorder_selected(ReorderDirection::Up));
|
assert!(s.reorder_selected(ReorderDirection::Up));
|
||||||
assert_eq!(root_ids(&s), vec!["n1", "n3", "n2"]);
|
assert_eq!(root_ids(&s), vec!["n2", "n1", "n3"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn reorder_selected_down_moves_to_lower_index() {
|
fn reorder_selected_down_moves_toward_back_index() {
|
||||||
let mut s = three_rects();
|
let mut s = three_rects();
|
||||||
s.set_single_selection(NodeId::new("n2"));
|
s.set_single_selection(NodeId::new("n2"));
|
||||||
assert!(s.reorder_selected(ReorderDirection::Down));
|
assert!(s.reorder_selected(ReorderDirection::Down));
|
||||||
assert_eq!(root_ids(&s), vec!["n2", "n1", "n3"]);
|
assert_eq!(root_ids(&s), vec!["n1", "n3", "n2"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn reorder_selected_at_edges_is_noop() {
|
fn reorder_selected_at_edges_is_noop() {
|
||||||
let mut s = three_rects();
|
let mut s = three_rects();
|
||||||
s.set_single_selection(NodeId::new("n1"));
|
s.set_single_selection(NodeId::new("n1"));
|
||||||
assert!(!s.reorder_selected(ReorderDirection::Down));
|
|
||||||
s.set_single_selection(NodeId::new("n3"));
|
|
||||||
assert!(!s.reorder_selected(ReorderDirection::Up));
|
assert!(!s.reorder_selected(ReorderDirection::Up));
|
||||||
|
s.set_single_selection(NodeId::new("n3"));
|
||||||
|
assert!(!s.reorder_selected(ReorderDirection::Down));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,10 @@ use std::collections::HashSet;
|
||||||
/// selected node swaps with in its parent's children vec.
|
/// selected node swaps with in its parent's children vec.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum ReorderDirection {
|
pub enum ReorderDirection {
|
||||||
/// Towards the front of the paint order (higher index, drawn on
|
/// Towards the front of the paint order (lower index,
|
||||||
/// top). Bound to `]`.
|
/// `children[0]` is top). Bound to `]`.
|
||||||
Up,
|
Up,
|
||||||
/// Towards the back of the paint order (lower index, drawn
|
/// Towards the back of the paint order (higher index, drawn
|
||||||
/// underneath). Bound to `[`.
|
/// underneath). Bound to `[`.
|
||||||
Down,
|
Down,
|
||||||
}
|
}
|
||||||
|
|
@ -193,12 +193,12 @@ pub fn reorder_in_children(
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if let Some(idx) = children.iter().position(|n| n.id_str() == target.as_str()) {
|
if let Some(idx) = children.iter().position(|n| n.id_str() == target.as_str()) {
|
||||||
match direction {
|
match direction {
|
||||||
ReorderDirection::Up if idx + 1 < children.len() => {
|
ReorderDirection::Up if idx > 0 => {
|
||||||
children.swap(idx, idx + 1);
|
children.swap(idx, idx - 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
ReorderDirection::Down if idx > 0 => {
|
ReorderDirection::Down if idx + 1 < children.len() => {
|
||||||
children.swap(idx, idx - 1);
|
children.swap(idx, idx + 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
_ => return false,
|
_ => return false,
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
//! reads the same resolved geometry the painter walks.
|
//! reads the same resolved geometry the painter walks.
|
||||||
//!
|
//!
|
||||||
//! Hit semantics are preserved bit-for-bit from `document/walkers.rs`:
|
//! Hit semantics are preserved bit-for-bit from `document/walkers.rs`:
|
||||||
//! top-most-first z-order, per-node rotation inverse-transform, the
|
//! top-most-first z-order (`children[0]` is frontmost), per-node rotation inverse-transform, the
|
||||||
//! tighter Ellipse / Polygon / Line geometry, the locked-node
|
//! tighter Ellipse / Polygon / Line geometry, the locked-node
|
||||||
//! body-opts-out-children-stay rule, and the hidden-subtree skip.
|
//! body-opts-out-children-stay rule, and the hidden-subtree skip.
|
||||||
|
|
||||||
|
|
@ -18,15 +18,15 @@ use crate::{Point2D, Rect};
|
||||||
|
|
||||||
impl LayoutScene {
|
impl LayoutScene {
|
||||||
/// Topmost node id whose geometry contains `point` (doc space)
|
/// Topmost node id whose geometry contains `point` (doc space)
|
||||||
/// on the active page. Walks children in reverse z-order so the
|
/// on the active page. Walks children in front-to-back z-order
|
||||||
/// most-recently-painted node wins. `None` on dead space.
|
/// (`children[0]` is frontmost). `None` on dead space.
|
||||||
///
|
///
|
||||||
/// `zoom` is the live viewport zoom — it scales the Line stroke
|
/// `zoom` is the live viewport zoom — it scales the Line stroke
|
||||||
/// hit slack so a thin line stays clickable at any zoom.
|
/// hit slack so a thin line stays clickable at any zoom.
|
||||||
pub fn node_at_doc_point(&self, point: Point2D, zoom: f32) -> Option<String> {
|
pub fn node_at_doc_point(&self, point: Point2D, zoom: f32) -> Option<String> {
|
||||||
let zoom = zoom.max(0.0001);
|
let zoom = zoom.max(0.0001);
|
||||||
let page = self.active_page()?;
|
let page = self.active_page()?;
|
||||||
for child in page.children.iter().rev() {
|
for child in &page.children {
|
||||||
if let Some(hit) = hit_test_walk(child, point, zoom) {
|
if let Some(hit) = hit_test_walk(child, point, zoom) {
|
||||||
return Some(hit);
|
return Some(hit);
|
||||||
}
|
}
|
||||||
|
|
@ -92,7 +92,7 @@ fn hit_test_walk(node: &SceneNode, point: Point2D, zoom: f32) -> Option<String>
|
||||||
} else {
|
} else {
|
||||||
point
|
point
|
||||||
};
|
};
|
||||||
for child in node.children.iter().rev() {
|
for child in &node.children {
|
||||||
if let Some(hit) = hit_test_walk(child, local, zoom) {
|
if let Some(hit) = hit_test_walk(child, local, zoom) {
|
||||||
return Some(hit);
|
return Some(hit);
|
||||||
}
|
}
|
||||||
|
|
@ -292,22 +292,22 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn node_at_doc_point_picks_topmost_overlapping_node() {
|
fn node_at_doc_point_treats_first_child_as_frontmost() {
|
||||||
let scene = one_page(vec![
|
let scene = one_page(vec![
|
||||||
leaf("under", NodeKind::Rect, Rect::xywh(0.0, 0.0, 50.0, 50.0)),
|
leaf("over", NodeKind::Rect, Rect::xywh(0.0, 0.0, 50.0, 50.0)),
|
||||||
leaf("over", NodeKind::Rect, Rect::xywh(10.0, 10.0, 50.0, 50.0)),
|
leaf("under", NodeKind::Rect, Rect::xywh(10.0, 10.0, 50.0, 50.0)),
|
||||||
]);
|
]);
|
||||||
// Overlap region → the later-painted "over" wins.
|
// Overlap region -> children[0] is the top layer.
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
scene
|
scene
|
||||||
.node_at_doc_point(Point2D::new(20.0, 20.0), 1.0)
|
.node_at_doc_point(Point2D::new(20.0, 20.0), 1.0)
|
||||||
.as_deref(),
|
.as_deref(),
|
||||||
Some("over")
|
Some("over")
|
||||||
);
|
);
|
||||||
// Only "under" covers (5, 5).
|
// Only "under" covers (55, 55).
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
scene
|
scene
|
||||||
.node_at_doc_point(Point2D::new(5.0, 5.0), 1.0)
|
.node_at_doc_point(Point2D::new(55.0, 55.0), 1.0)
|
||||||
.as_deref(),
|
.as_deref(),
|
||||||
Some("under")
|
Some("under")
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -415,7 +415,7 @@ impl<'a> Widget for CanvasViewport<'a> {
|
||||||
rect.size.y + CULL_MARGIN * 2.0,
|
rect.size.y + CULL_MARGIN * 2.0,
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
for child in &page.children {
|
for child in page.children.iter().rev() {
|
||||||
super::canvas_viewport_paint::paint_node(
|
super::canvas_viewport_paint::paint_node(
|
||||||
cx,
|
cx,
|
||||||
child,
|
child,
|
||||||
|
|
|
||||||
|
|
@ -263,7 +263,7 @@ pub fn paint_node(
|
||||||
} else {
|
} else {
|
||||||
paint_fill_then_stroke(cx, node, world_rect, zoom, node.fill);
|
paint_fill_then_stroke(cx, node, world_rect, zoom, node.fill);
|
||||||
}
|
}
|
||||||
for child in &node.children {
|
for child in node.children.iter().rev() {
|
||||||
paint_node(cx, child, viewport_origin, zoom, edit_caret.clone(), cull);
|
paint_node(cx, child, viewport_origin, zoom, edit_caret.clone(), cull);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -275,7 +275,7 @@ pub fn paint_node(
|
||||||
node.fill,
|
node.fill,
|
||||||
),
|
),
|
||||||
NodeKind::Group | NodeKind::Other(_) => {
|
NodeKind::Group | NodeKind::Other(_) => {
|
||||||
for child in &node.children {
|
for child in node.children.iter().rev() {
|
||||||
paint_node(cx, child, viewport_origin, zoom, edit_caret.clone(), cull);
|
paint_node(cx, child, viewport_origin, zoom, edit_caret.clone(), cull);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue