mirror of
https://github.com/storytold/designcraft.git
synced 2026-11-05 10:10:35 +00:00
This commit is contained in:
1 parent
dffef02773
commit
df9f0656ca
5 files changed
+51
-3
No files matched your search
@@ -632,6 +632,22 @@ impl Document {
|
||||
None
|
||||
}
|
||||
|
||||
/// Hit test on a parent spread (master page): like [`Self::hit_item`], but also skips locked
|
||||
/// items. Items on hidden or locked layers can't be picked there either.
|
||||
pub fn hit_parent_item(&self, sr: SpreadRef, p: Point, tol: f64) -> Option<ItemId> {
|
||||
let sp = self.spread(sr)?;
|
||||
let mut items: Vec<&Arc<Item>> = sp.items.iter().collect();
|
||||
items.sort_by_key(|i| self.layer_rank(i.layer));
|
||||
items
|
||||
.into_iter()
|
||||
.rev()
|
||||
.find(|it| {
|
||||
let layer = self.layer(it.layer);
|
||||
!it.locked && !it.hidden && !layer.is_some_and(|l| !l.visible || l.locked) && item_hit(it, p, tol)
|
||||
})
|
||||
.map(|it| it.id)
|
||||
}
|
||||
|
||||
/// The first item on a document or parent spread whose geometry isn't finite
|
||||
/// ([`Item::geometry_is_finite`]).
|
||||
pub fn non_finite_item(&self) -> Option<ItemId> {
|
||||
|
||||
@@ -235,6 +235,20 @@ fn hit_testing_respects_layers() {
|
||||
assert_eq!(d.hit_item(0, designcraft_geom::Point::new(50.0, 50.0), 2.0), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parent_hit_testing_respects_layers() {
|
||||
let mut d = doc();
|
||||
let lid = d.default_layer();
|
||||
let (a, _) = d.add_text_frame(SpreadRef::Parent(0), Rect::new(10.0, 10.0, 100.0, 100.0), lid, "x", ParaFormat::default()).unwrap();
|
||||
let at = designcraft_geom::Point::new(50.0, 50.0);
|
||||
assert_eq!(d.hit_parent_item(SpreadRef::Parent(0), at, 2.0), Some(a));
|
||||
d.layer_mut(lid).unwrap().visible = false;
|
||||
assert_eq!(d.hit_parent_item(SpreadRef::Parent(0), at, 2.0), None);
|
||||
d.layer_mut(lid).unwrap().visible = true;
|
||||
d.layer_mut(lid).unwrap().locked = true;
|
||||
assert_eq!(d.hit_parent_item(SpreadRef::Parent(0), at, 2.0), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn page_numbers_saturate_at_the_largest_start() {
|
||||
// A start number from a file or an old command: page 2 overflowed (a panic in debug builds).
|
||||
|
||||
@@ -300,8 +300,7 @@ impl ToolContext<'_> {
|
||||
}
|
||||
|
||||
fn hit_parent(&self, sr: SpreadRef, sp: Point) -> Option<(SpreadRef, ItemId)> {
|
||||
let s = self.doc.spread(sr)?;
|
||||
s.items.iter().rev().find(|it| !it.locked && designcraft_doc::edit_hit(it, sp, self.tol(4.0))).map(|it| (sr, it.id))
|
||||
self.doc.hit_parent_item(sr, sp, self.tol(4.0)).map(|id| (sr, id))
|
||||
}
|
||||
|
||||
/// Spread-space → canvas transform of the spread holding item `id`.
|
||||
|
||||
@@ -220,6 +220,25 @@ fn parent_hit_reaches_base_parent_items_topmost_first() {
|
||||
assert_eq!(hit(&d, 120.0, 120.0), None);
|
||||
}
|
||||
|
||||
/// While editing parent pages, a click doesn't pick items on a hidden or locked layer (#2221).
|
||||
#[test]
|
||||
fn parent_mode_hit_skips_hidden_and_locked_layers() {
|
||||
let mut d = Document::new(&NewDocument { pages: 1, facing_pages: false, ..Default::default() });
|
||||
let lid = d.default_layer();
|
||||
let (id, _) = d.add_text_frame(SpreadRef::Parent(0), Rect::new(100.0, 100.0, 200.0, 200.0), lid, "a", ParaFormat::default()).unwrap();
|
||||
let hit = |d: &Document| {
|
||||
let (s, c, l) = (Selection::default(), Cache::new(), CanvasLayout::new(d, true));
|
||||
let p = l.to_canvas(SpreadRef::Parent(0), Point::new(150.0, 150.0));
|
||||
ctx(d, &s, &c, &l).hit(p)
|
||||
};
|
||||
assert_eq!(hit(&d), Some((SpreadRef::Parent(0), id)));
|
||||
d.layer_mut(lid).unwrap().visible = false;
|
||||
assert_eq!(hit(&d), None, "hidden layer");
|
||||
d.layer_mut(lid).unwrap().visible = true;
|
||||
d.layer_mut(lid).unwrap().locked = true;
|
||||
assert_eq!(hit(&d), None, "locked layer");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gradient_tool_drag_sets_the_vector() {
|
||||
let mut d = Document::new(&NewDocument::default());
|
||||
|
||||
@@ -164,7 +164,7 @@ fn item_at(app: &DesignApp, p: Point, zoom: f64) -> Option<(designcraft_doc::Ite
|
||||
let tol = 4.0 / zoom.max(1e-6);
|
||||
let id = match sr {
|
||||
SpreadRef::Doc(si) => st.doc.hit_item(si, sp, tol)?,
|
||||
_ => st.doc.spread(sr)?.items.iter().rev().find(|it| !it.locked && designcraft_doc::edit_hit(it, sp, tol))?.id,
|
||||
SpreadRef::Parent(_) => st.doc.hit_parent_item(sr, sp, tol)?,
|
||||
};
|
||||
Some((id, sp))
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user