Remove obsolete canvas panel focus mode

This commit is contained in:
2026-09-12 15:06:57 -07:00
parent 8112dea7a3
commit 40154983cc
12 changed files with 44 additions and 104 deletions
@@ -52,7 +52,9 @@ pub fn controls<'a>(
text(format!("{:.0}%", scale * 100.)).size(12),
control("ZoomIn", "+", Some(zoom(Some(scale * 1.25)))),
control("ActualSize", "100%", Some(zoom(Some(1.)))),
].spacing(4).align_y(iced::Center);
]
.spacing(4)
.align_y(iced::Center);
tooltip(
controls,
container(text("F6: enter/leave canvas keyboard controls · Tab: next · Enter/Space: activate · Esc: leave").size(12)).padding(7).style(crate::style::card),
@@ -125,7 +127,6 @@ pub enum Event {
CancelGesture,
Pan(Vector),
Zoom { factor: f32, at: Point, base: f32 },
Focus,
Traverse(bool),
ControlFocus(&'static str),
ToggleFocus,
@@ -70,7 +70,6 @@ impl<T: Send + 'static> Operation<T> for Collect {
return operation::Outcome::None;
}
let target = match self.event {
Event::Focus => Some(canvas),
Event::ControlFocus(name) => Some(self.scope.control_id(name)),
Event::ToggleFocus if self.focused.is_none() => Some(canvas),
Event::ToggleFocus | Event::Leave if self.focused.is_some() => None,
@@ -130,7 +130,6 @@ pub enum CanvasEvent {
FormShown(Context, Id),
Zoom(Context, Option<f32>),
Camera(Context, u64, super::canvas_workspace::Event),
Focus(Context),
Shelf(Context, Shelf),
OpenUse(Context, Id),
Back(Context),
@@ -170,7 +169,6 @@ impl CanvasEvent {
| Self::FormShown(context, _)
| Self::Zoom(context, _)
| Self::Camera(context, ..)
| Self::Focus(context)
| Self::Shelf(context, _)
| Self::OpenUse(context, _)
| Self::Back(context)
@@ -320,7 +318,6 @@ impl State {
pub(crate) fn camera_boundary(&self) -> impl PartialEq + use<> {
(
self.canvas_tool,
self.presentation.focused,
self.presentation.shelf,
self.presentation.viewport,
self.presentation.pan,
@@ -359,7 +356,6 @@ impl State {
if self.presentation.identity != Some((document, owner)) {
self.presentation = workspace::Presentation {
identity: Some((document, owner)),
focused: self.presentation.focused,
..Default::default()
};
self.details_offset = iced::Vector::ZERO;
@@ -394,12 +390,6 @@ impl State {
true
}
}
pub(crate) fn focused(&self) -> bool {
self.presentation.focused
}
pub(crate) fn toggle_focus(&mut self) {
self.presentation.focused = !self.presentation.focused;
}
pub(crate) fn toggle_shelf(&mut self, shelf: Shelf) {
self.presentation.shelf = (self.presentation.shelf != Some(shelf)).then_some(shelf);
}
@@ -14,7 +14,6 @@ pub enum Shelf {
pub(super) struct Presentation {
pub(super) identity: Option<(Id, Id)>,
pub(super) viewport: Option<Size>,
pub(super) focused: bool,
pub(super) shelf: Option<Shelf>,
pub(super) pan: iced::Vector,
pub(super) zoom: Option<f32>,
@@ -1040,7 +1040,9 @@ fn scenario_workspace_viewport_events_are_passive_guarded_and_do_not_apply_raw_f
}
app.busy = false;
navigation_event(&mut app, |ctx| CanvasEvent::Shelf(ctx, Shelf::Selection));
navigation_event(&mut app, CanvasEvent::Focus);
let epoch = app.canvas_epoch;
navigation_event(&mut app, |ctx| CanvasEvent::Zoom(ctx, Some(0.8)));
assert_ne!(app.canvas_epoch, epoch);
navigation_event(&mut app, |ctx| CanvasEvent::Zoom(ctx, None));
assert_eq!(app.behavior.recovery_snapshot().unwrap(), raw);
assert!(std::sync::Arc::ptr_eq(&accepted, &app.document.snapshot()));
@@ -1341,7 +1343,7 @@ async fn production_scenario_camera_external_controls_bounds_and_retained_deltas
let mut mounted = Mounted::new(&mut app).await;
let snapshot = app.document.snapshot();
let source = app.document.bundle().clone();
for boundary in ["Fit", "A", "Details", "Panels", "Bounds"] {
for boundary in ["Fit", "A", "Details", "ZoomIn", "Bounds"] {
let toolbar = capture_toolbar(&mut mounted, &app, "Fit");
let bounds = mounted.geometry(&app).bounds("scenario-viewport");
let point = bounds.position() + iced::Vector::new(95., 90.);
@@ -1371,11 +1373,6 @@ async fn production_scenario_camera_external_controls_bounds_and_retained_deltas
let size = Size::new(app.window_size.width + 90., app.window_size.height + 35.);
let task = app.update(Message::WindowResized(size));
mounted.perform(&mut app, task).await;
} else if boundary == "Panels" {
// Panel layout remains a presentation command, not canvas activation.
let context = app.scenario_context().unwrap();
let task = app.update(Message::ScenarioCanvas(CanvasEvent::Focus(context)));
mounted.perform(&mut app, task).await;
} else {
let id = scope(&app).control_id(boundary);
let at = mounted.geometry(&app).containers[&id].center();
@@ -1860,7 +1857,6 @@ async fn scenario_workspace_open_and_back_restore_owner_and_mounted_camera_after
CanvasEvent::Choose(ctx, CanvasTool::Message(MessageStyle::Timer))
});
navigation_event(&mut app, |ctx| CanvasEvent::Shelf(ctx, Shelf::Selection));
navigation_event(&mut app, CanvasEvent::Focus);
let mut mounted = Mounted::new(&mut app).await;
navigation_event(&mut app, |ctx| CanvasEvent::Zoom(ctx, Some(0.75)));
let canvas = mounted.geometry(&app).bounds("scenario-viewport");
@@ -1903,7 +1899,13 @@ async fn scenario_workspace_open_and_back_restore_owner_and_mounted_camera_after
mounted.settle(&mut app).await;
assert_eq!(app.behavior.scenario.presentation.pan, Vector::ZERO);
navigation_event(&mut app, |ctx| CanvasEvent::Zoom(ctx, Some(2.)));
navigation_event(&mut app, CanvasEvent::Focus);
navigation_event(&mut app, |ctx| {
CanvasEvent::Choose(ctx, CanvasTool::Add(Tool::Action))
});
assert_eq!(
app.behavior.scenario.canvas_tool(b),
CanvasTool::Add(Tool::Action)
);
let _ = app.update(Message::Command(Command::Rename(
reference,
"Renamed caller use".into(),
@@ -1921,7 +1923,6 @@ async fn scenario_workspace_open_and_back_restore_owner_and_mounted_camera_after
app.behavior.scenario.canvas_tool(a),
CanvasTool::Message(MessageStyle::Timer)
);
assert!(app.behavior.scenario.focused());
assert_eq!(
app.behavior.scenario.presentation.shelf,
Some(Shelf::Selection)
+10 -9
View File
@@ -86,7 +86,6 @@ pub struct State {
pan: iced::Vector,
zoom: Option<f32>,
fit: bool,
pub(crate) focused: bool,
contextual_expanded: BTreeSet<OccurrenceEndpoint>,
selected_context: Option<oa_core::topology_context::ContextAddress>,
shelf: Option<Shelf>,
@@ -128,7 +127,6 @@ impl State {
pub(crate) fn camera_boundary(&self) -> impl PartialEq + use<> {
(
self.tool,
self.focused,
self.shelf,
self.viewport,
self.pan,
@@ -2148,7 +2146,7 @@ mod tests {
}
#[test]
fn process_fit_disclosures_and_focus_preserve_rejected_raw_draft_and_accepted_source() {
fn process_zoom_and_disclosures_preserve_rejected_raw_draft_and_accepted_source() {
let (p, owner, _, _, _, _) = fixture();
let mut app = App::with_project(p);
let _ = app.update(Message::Select(owner));
@@ -2163,16 +2161,19 @@ mod tests {
let before = app.behavior.recovery_snapshot().unwrap();
let accepted = app.document.snapshot();
assert!(app.behavior.prepare_pending(app.project()).is_err());
for (shelf, expected) in [
(Shelf::Selection, Some(Shelf::Selection)),
(Shelf::Selection, None),
for (shelf, expected, zoom) in [
(Shelf::Selection, Some(Shelf::Selection), 0.6),
(Shelf::Selection, None, 1.2),
] {
let focused = app.behavior.topology.focused;
let _ = app.update(event(Event::Shelf(shelf)));
assert_eq!(app.behavior.topology.shelf, expected);
let context = app.topology_context().unwrap();
let _ = app.update(Message::TopologyCanvas(CanvasEvent::Focus(context)));
assert_eq!(app.behavior.topology.focused, !focused);
let _ = app.update(Message::TopologyCanvas(CanvasEvent::Zoom(
context,
Some(zoom),
)));
assert_ne!(app.canvas_epoch, context.epoch);
assert_eq!(app.behavior.topology.zoom, Some(zoom));
assert_eq!(app.behavior.recovery_snapshot().unwrap(), before);
assert!(app.behavior.prepare_pending(app.project()).is_err());
assert!(std::sync::Arc::ptr_eq(&app.document.snapshot(), &accepted));
@@ -62,7 +62,6 @@ pub enum CanvasEvent {
Back(Context),
Zoom(Context, Option<f32>),
Camera(Context, u64, super::super::canvas_workspace::Event),
Focus(Context),
Viewport(Context, Size),
}
impl CanvasEvent {
@@ -81,7 +80,6 @@ impl CanvasEvent {
| Self::AppendExchange(c)
| Self::Zoom(c, ..)
| Self::Camera(c, ..)
| Self::Focus(c)
| Self::Viewport(c, ..) => *c,
Self::Begin { context, .. }
| Self::Connect { context, .. }
@@ -218,7 +218,7 @@ async fn production_process_camera_external_controls_bounds_and_retained_deltas_
let mut mounted = Mounted::new(&mut app).await;
let snapshot = app.document.snapshot();
let source = app.document.bundle().clone();
for boundary in ["Fit", "OR", "Details", "Panels", "Bounds"] {
for boundary in ["Fit", "OR", "Details", "ZoomIn", "Bounds"] {
let toolbar = capture_toolbar(&mut mounted, &app, "Fit");
let bounds = mounted.geometry(&app).bounds("process-viewport");
let point = bounds.position() + iced::Vector::new(95., 90.);
@@ -248,11 +248,6 @@ async fn production_process_camera_external_controls_bounds_and_retained_deltas_
let size = Size::new(app.window_size.width + 90., app.window_size.height + 35.);
let task = app.update(Message::WindowResized(size));
mounted.perform(&mut app, task).await;
} else if boundary == "Panels" {
// Panel layout remains a presentation command, not canvas activation.
let context = app.topology_context().unwrap();
let task = app.update(Message::TopologyCanvas(CanvasEvent::Focus(context)));
mounted.perform(&mut app, task).await;
} else {
let id = scope(&app).control_id(boundary);
let at = mounted.geometry(&app).containers[&id].center();