forked from 1b-agent/opencadstudio-upstream
refactor(selection): split 31-field SelectionState into five sub-structs
SelectionState now holds view, gesture, input, menu and orbit sub-structs; all 450 access sites updated mechanically with no behavior change. Deletes three write-only dead fields (box_last, box_last_crossing, poly_last_crossing). Hand-rolled clears in commands and dim_viewport route through the new clear methods; bench fixture updated. Full suite: 1976 passed / 0 failed / 25 ignored.
This commit is contained in:
1 parent
8c2cfa2c8f
commit
7aafd9c710
27 files changed
+512
-469
No files matched your search
@@ -19,7 +19,7 @@ impl OpenCADStudio {
|
||||
pub(in crate::app) fn context_menu_open(&self) -> bool {
|
||||
self.tabs
|
||||
.get(self.active_tab)
|
||||
.is_some_and(|tab| tab.scene.selection.borrow().context_menu.is_some())
|
||||
.is_some_and(|tab| tab.scene.selection.borrow().menu.open_at.is_some())
|
||||
}
|
||||
|
||||
/// Everything the menu builder needs, read from the active tab. Called by
|
||||
@@ -71,7 +71,7 @@ impl OpenCADStudio {
|
||||
.scene
|
||||
.selection
|
||||
.borrow()
|
||||
.context_menu_ui
|
||||
.menu.ui
|
||||
.open_submenu;
|
||||
build_context_menu(&self.context_menu_context(), open)
|
||||
}
|
||||
@@ -80,10 +80,10 @@ impl OpenCADStudio {
|
||||
pub(in crate::app) fn close_context_menu(&mut self) -> Task<Message> {
|
||||
let i = self.active_tab;
|
||||
let mut sel = self.tabs[i].scene.selection.borrow_mut();
|
||||
if sel.context_menu.is_none() {
|
||||
if sel.menu.open_at.is_none() {
|
||||
return Task::none();
|
||||
}
|
||||
sel.close_context_menu();
|
||||
sel.menu.close();
|
||||
drop(sel);
|
||||
self.focus_cmd_input()
|
||||
}
|
||||
@@ -91,7 +91,7 @@ impl OpenCADStudio {
|
||||
pub(in crate::app) fn on_context_menu_submenu_toggle(&mut self, id: SubmenuId) -> Task<Message> {
|
||||
let i = self.active_tab;
|
||||
let mut sel = self.tabs[i].scene.selection.borrow_mut();
|
||||
let ui = &mut sel.context_menu_ui;
|
||||
let ui = &mut sel.menu.ui;
|
||||
ui.open_submenu = if ui.open_submenu == Some(id) { None } else { Some(id) };
|
||||
drop(sel);
|
||||
// Keep the keyboard highlight on the header that was toggled.
|
||||
@@ -101,8 +101,8 @@ impl OpenCADStudio {
|
||||
.iter()
|
||||
.position(|s| s.header == Some(id));
|
||||
let mut sel = self.tabs[i].scene.selection.borrow_mut();
|
||||
if sel.context_menu_ui.highlighted.is_some() {
|
||||
sel.context_menu_ui.highlighted = header;
|
||||
if sel.menu.ui.highlighted.is_some() {
|
||||
sel.menu.ui.highlighted = header;
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
@@ -118,10 +118,10 @@ impl OpenCADStudio {
|
||||
let i = self.active_tab;
|
||||
{
|
||||
let mut sel = self.tabs[i].scene.selection.borrow_mut();
|
||||
sel.close_context_menu();
|
||||
sel.menu.close();
|
||||
// A pick counts as "another interaction" for the Enter-first
|
||||
// right-click cycle: the next right-click acts as Enter again.
|
||||
sel.right_click_entered = false;
|
||||
sel.input.right_click_entered = false;
|
||||
}
|
||||
let focus = self.focus_cmd_input();
|
||||
let task = match action {
|
||||
@@ -174,7 +174,7 @@ impl OpenCADStudio {
|
||||
if rows.is_empty() {
|
||||
return Task::none();
|
||||
}
|
||||
let current = self.tabs[i].scene.selection.borrow().context_menu_ui.highlighted;
|
||||
let current = self.tabs[i].scene.selection.borrow().menu.ui.highlighted;
|
||||
let next_enabled = |from: usize, step: isize| -> usize {
|
||||
let n = rows.len() as isize;
|
||||
let mut idx = from as isize;
|
||||
@@ -193,7 +193,7 @@ impl OpenCADStudio {
|
||||
None => menu.default_index(),
|
||||
Some(cur) => next_enabled(cur, 1),
|
||||
};
|
||||
self.tabs[i].scene.selection.borrow_mut().context_menu_ui.highlighted = Some(idx);
|
||||
self.tabs[i].scene.selection.borrow_mut().menu.ui.highlighted = Some(idx);
|
||||
Task::none()
|
||||
}
|
||||
ContextMenuNav::Up => {
|
||||
@@ -201,7 +201,7 @@ impl OpenCADStudio {
|
||||
None => menu.default_index(),
|
||||
Some(cur) => next_enabled(cur, -1),
|
||||
};
|
||||
self.tabs[i].scene.selection.borrow_mut().context_menu_ui.highlighted = Some(idx);
|
||||
self.tabs[i].scene.selection.borrow_mut().menu.ui.highlighted = Some(idx);
|
||||
Task::none()
|
||||
}
|
||||
ContextMenuNav::Enter => {
|
||||
@@ -220,7 +220,7 @@ impl OpenCADStudio {
|
||||
if unique {
|
||||
self.on_context_menu_pick(rows[idx].action.clone())
|
||||
} else {
|
||||
self.tabs[i].scene.selection.borrow_mut().context_menu_ui.highlighted =
|
||||
self.tabs[i].scene.selection.borrow_mut().menu.ui.highlighted =
|
||||
Some(idx);
|
||||
Task::none()
|
||||
}
|
||||
@@ -244,7 +244,7 @@ impl OpenCADStudio {
|
||||
ArrowKey::Left | ArrowKey::Right => {
|
||||
// On a submenu header, Right expands and Left collapses.
|
||||
let i = self.active_tab;
|
||||
let ui = self.tabs[i].scene.selection.borrow().context_menu_ui.clone();
|
||||
let ui = self.tabs[i].scene.selection.borrow().menu.ui.clone();
|
||||
let menu = self.current_context_menu();
|
||||
let rows = menu.selectable();
|
||||
let header = ui.highlighted.and_then(|c| rows.get(c)).and_then(|r| r.header);
|
||||
@@ -410,7 +410,7 @@ mod tests {
|
||||
fn app() -> OpenCADStudio {
|
||||
let mut app = OpenCADStudio::new_for_test();
|
||||
app.automation_op(r#"{"op":"new"}"#);
|
||||
app.tabs[0].scene.selection.borrow_mut().vp_size = (800.0, 600.0);
|
||||
app.tabs[0].scene.selection.borrow_mut().view.vp_size = (800.0, 600.0);
|
||||
let _ = app.update(Message::ViewportMove(Point::new(200.0, 150.0)));
|
||||
app
|
||||
}
|
||||
@@ -428,7 +428,7 @@ mod tests {
|
||||
}
|
||||
|
||||
fn menu_open(app: &OpenCADStudio) -> bool {
|
||||
app.tabs[0].scene.selection.borrow().context_menu.is_some()
|
||||
app.tabs[0].scene.selection.borrow().menu.open_at.is_some()
|
||||
}
|
||||
|
||||
fn active(app: &OpenCADStudio) -> Option<&'static str> {
|
||||
@@ -491,7 +491,7 @@ mod tests {
|
||||
let _ = app.update(Message::ViewportRightPress);
|
||||
{
|
||||
let mut sel = app.tabs[0].scene.selection.borrow_mut();
|
||||
sel.right_press_time = iced::time::Instant::now()
|
||||
sel.input.right_press_time = iced::time::Instant::now()
|
||||
.checked_sub(std::time::Duration::from_millis(400));
|
||||
}
|
||||
let _ = app.update(Message::ViewportRightRelease);
|
||||
@@ -558,7 +558,7 @@ mod tests {
|
||||
let _ = app.update(Message::ContextMenuPick(MenuAction::Command("LINE".into())));
|
||||
assert!(!menu_open(&app));
|
||||
assert_eq!(active(&app), Some("LINE"));
|
||||
assert!(!app.tabs[0].scene.selection.borrow().right_click_entered);
|
||||
assert!(!app.tabs[0].scene.selection.borrow().input.right_click_entered);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -582,7 +582,7 @@ mod tests {
|
||||
right_click(&mut app);
|
||||
let _ = app.update(Message::ContextMenuNavigate(ContextMenuNav::Down)); // Enter row
|
||||
assert_eq!(
|
||||
app.tabs[0].scene.selection.borrow().context_menu_ui.highlighted,
|
||||
app.tabs[0].scene.selection.borrow().menu.ui.highlighted,
|
||||
Some(0)
|
||||
);
|
||||
let _ = app.update(Message::ContextMenuNavigate(ContextMenuNav::Down)); // Cancel
|
||||
@@ -853,7 +853,7 @@ mod transparent_tests {
|
||||
fn line_app() -> OpenCADStudio {
|
||||
let mut app = OpenCADStudio::new_for_test();
|
||||
app.automation_op(r#"{"op":"new"}"#);
|
||||
app.tabs[0].scene.selection.borrow_mut().vp_size = (800.0, 600.0);
|
||||
app.tabs[0].scene.selection.borrow_mut().view.vp_size = (800.0, 600.0);
|
||||
let _ = app.dispatch_command("LINE");
|
||||
let _ = app.feed_command(StepInput::Point(DVec3::ZERO));
|
||||
app
|
||||
|
||||
Reference in new issue
Block a user