fix(paper): make active-viewport picker & ViewCube clickable
Picker ve ViewCube paper_canvas içinde gömülü olduğundan tümüyle viewport mouse_area'nın altında kalıyor ve tıklamaları o yakalıyordu. İkisi de ana view stack'ine, mouse_area'nın üstüne taşındı; aktif viewport'un ekran dikdörtgeninin köşelerine konumlandırılıyor. - model picker artık yalnızca model layout'ta gösteriliyor (paper'da viewport kendi picker'ını alıyor) - ViewCube hit alanı aktif viewport rect'inin sağ üst köşesinde - CursorMoved ve ViewportClick, ViewCube hit-test'ini full canvas yerine aktif viewport rect'ine göre eşliyor; böylece paper'da gizmo ile tıklama hizalı - picker/viewcube dışı tıklamalar alttaki mouse_area'ya geçtiği için viewport içi seçim/çizim etkilenmiyor Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
a41a05baa1
commit
eeb7df5fec
2 changed files with 112 additions and 38 deletions
|
|
@ -1570,11 +1570,26 @@ impl OpenCADStudio {
|
|||
|
||||
// ── Cursor / viewport messages ─────────────────────────────────
|
||||
Message::CursorMoved(p) => {
|
||||
let (vw, _vh) = self.tabs[self.active_tab].scene.selection.borrow().vp_size;
|
||||
self.cursor_pos = iced::Point::new(
|
||||
vw - VIEWCUBE_PAD - VIEWCUBE_HIT_SIZE + p.x,
|
||||
VIEWCUBE_PAD + p.y,
|
||||
);
|
||||
// `p` is relative to the ViewCube hit area's top-left. Map
|
||||
// it back to full-canvas coordinates so ViewportClick's
|
||||
// hit-test lines up. The hit area sits in the top-right of
|
||||
// the full canvas in model space, or of the active
|
||||
// viewport's screen rectangle in a paper layout.
|
||||
let i = self.active_tab;
|
||||
let (vw, _vh) = self.tabs[i].scene.selection.borrow().vp_size;
|
||||
let (ox, oy) = match self
|
||||
.tabs[i]
|
||||
.scene
|
||||
.active_viewport
|
||||
.and_then(|h| self.tabs[i].scene.viewport_screen_rect(h, (vw, _vh)))
|
||||
{
|
||||
Some(rect) => (
|
||||
rect.x + rect.width - VIEWCUBE_PAD - VIEWCUBE_HIT_SIZE,
|
||||
rect.y + VIEWCUBE_PAD,
|
||||
),
|
||||
None => (vw - VIEWCUBE_PAD - VIEWCUBE_HIT_SIZE, VIEWCUBE_PAD),
|
||||
};
|
||||
self.cursor_pos = iced::Point::new(ox + p.x, oy + p.y);
|
||||
Task::none()
|
||||
}
|
||||
|
||||
|
|
@ -2637,14 +2652,26 @@ impl OpenCADStudio {
|
|||
let i = self.active_tab;
|
||||
let rot = self.tabs[i].scene.active_view_rotation_mat();
|
||||
let (vw, vh) = self.tabs[i].scene.selection.borrow().vp_size;
|
||||
if let Some(region) = scene::hit_test(
|
||||
self.cursor_pos.x,
|
||||
self.cursor_pos.y,
|
||||
vw,
|
||||
vh,
|
||||
rot,
|
||||
VIEWCUBE_PX,
|
||||
) {
|
||||
// The ViewCube draws in the top-right of whichever area
|
||||
// owns it: the full canvas in model space, or the active
|
||||
// viewport's screen rectangle in a paper layout. Map the
|
||||
// cursor into that area before hit-testing so paper-space
|
||||
// picks line up with the gizmo.
|
||||
let (cx, cy, w, h) = match self
|
||||
.tabs[i]
|
||||
.scene
|
||||
.active_viewport
|
||||
.and_then(|hndl| self.tabs[i].scene.viewport_screen_rect(hndl, (vw, vh)))
|
||||
{
|
||||
Some(rect) => (
|
||||
self.cursor_pos.x - rect.x,
|
||||
self.cursor_pos.y - rect.y,
|
||||
rect.width,
|
||||
rect.height,
|
||||
),
|
||||
None => (self.cursor_pos.x, self.cursor_pos.y, vw, vh),
|
||||
};
|
||||
if let Some(region) = scene::hit_test(cx, cy, w, h, rot, VIEWCUBE_PX) {
|
||||
return Task::done(Message::ViewCubeSnap(region));
|
||||
}
|
||||
Task::none()
|
||||
|
|
|
|||
Loading…
Reference in a new issue