fix(hatch): follow block grip movement

This commit is contained in:
Hakan Seven committed 2026-08-01 21:52:25 +03:00
1 parent c17e31c1ed
commit c4c673336c
3 files changed
+79 -9

No files matched your search

+61 -1
View File
@@ -1026,6 +1026,61 @@ impl Scene {
hatch_bg: [f32; 4],
tint_selected: bool,
frozen: Option<&rustc_hash::FxHashSet<Handle>>,
) -> Vec<HatchModel> {
self.exploded_insert_hatch_models_filtered(
layout_block,
hatch_bg,
tint_selected,
frozen,
None,
false,
)
}
/// Build live hatch overlays for INSERT grip previews. The edited INSERT
/// is intentionally hidden from the resident scene while its current
/// document entity moves, so include that hidden target and reuse the full
/// block-expansion path for nested inserts, inherited styles and XCLIP.
pub(super) fn preview_insert_hatch_models(&self, handles: &[Handle]) -> Vec<HatchModel> {
let targets: rustc_hash::FxHashSet<Handle> = handles
.iter()
.copied()
.filter(|&handle| {
matches!(self.document.get_entity(handle), Some(EntityType::Insert(_)))
})
.collect();
if targets.is_empty() {
return Vec::new();
}
let hatch_bg = if self.current_layout != "Model" {
self.paper_bg_color
} else {
self.bg_color
};
let frozen: rustc_hash::FxHashSet<Handle> = self
.interaction_viewport_frozen_layers()
.into_iter()
.flatten()
.copied()
.collect();
self.exploded_insert_hatch_models_filtered(
self.interaction_block_handle(),
hatch_bg,
true,
(!frozen.is_empty()).then_some(&frozen),
Some(&targets),
true,
)
}
fn exploded_insert_hatch_models_filtered(
&self,
layout_block: Handle,
hatch_bg: [f32; 4],
tint_selected: bool,
frozen: Option<&rustc_hash::FxHashSet<Handle>>,
targets: Option<&rustc_hash::FxHashSet<Handle>>,
include_preview_hidden: bool,
) -> Vec<HatchModel> {
let layer_hidden = |layer: &str| {
self.document
@@ -1117,8 +1172,13 @@ impl Scene {
let EntityType::Insert(ins) = contextual.as_ref() else {
continue;
};
if targets.is_some_and(|targets| !targets.contains(&ins.common.handle)) {
continue;
}
let temporarily_hidden = self.object_isolation.hides(ins.common.handle)
|| (!include_preview_hidden && self.preview_hidden.contains(&ins.common.handle));
if ins.common.invisible
|| self.entity_temporarily_hidden(ins.common.handle)
|| temporarily_hidden
|| layer_hidden(&ins.common.layer)
{
continue;
+14 -8
View File
@@ -5104,14 +5104,19 @@ impl Scene {
let cache = self.hatch_cache.borrow();
match cache.get(&space) {
// Selection tint is baked in, so the selected set must also
// match; category = a changed handle that is a hatch/solid fill.
// match; category = a changed direct fill or an INSERT
// whose expanded block tree can contain hatch fills.
Some((cached_epoch, cached_sel, arc))
if *cached_sel == sel_sig
&& self.category_cache_valid(
*cached_epoch,
CACHE_CATEGORY_HATCH,
CACHE_CATEGORY_HATCH | CACHE_CATEGORY_INSERT_HATCH,
|h| {
self.hatches.contains_key(&h)
self.hatches.contains_key(&h)
|| matches!(
self.document.get_entity(h),
Some(EntityType::Insert(_))
)
},
) =>
{
@@ -5149,11 +5154,12 @@ impl Scene {
fn selected_hatch_sig(&self) -> u64 {
let mut sig = 0u64;
let mut count = 0u64;
for h in self
.selected
.iter()
.filter(|handle| self.hatches.contains_key(handle))
{
for &h in &self.selected {
if !self.hatches.contains_key(&h)
&& !matches!(self.document.get_entity(h), Some(EntityType::Insert(_)))
{
continue;
}
count += 1;
sig ^= h.value().wrapping_mul(0x9E37_79B9_7F4A_7C15);
}
+4
View File
@@ -18,8 +18,12 @@ impl Scene {
pub fn set_preview_hatches(&mut self, handles: &[Handle]) {
let mut models = Vec::new();
for &handle in handles {
// Keep the existing direct Hatch/Solid preview path. INSERT has no
// entry in `self.hatches`, so this is a no-op for it and the full
// block expansion below supplies its fills.
self.append_preview_hatch(handle, &mut models);
}
models.extend(self.preview_insert_hatch_models(handles));
self.preview_hatches = std::sync::Arc::new(models);
}