Remove misleading canvas activation controls

This commit is contained in:
2026-09-12 07:07:15 -07:00
parent 956a584132
commit b25065c442
6 changed files with 40 additions and 83 deletions
@@ -29,7 +29,6 @@ pub fn controls<'a>(
keyboard: bool,
scale: f32,
details: Message,
focus: Option<Message>,
zoom: impl Fn(Option<f32>) -> Message,
publish: impl Fn(Event) -> Message + Copy + 'a,
) -> Element<'a, Message> {
@@ -46,17 +45,19 @@ pub fn controls<'a>(
publish,
)
};
row![
let controls = row![
control("Details", "Details", Some(details)),
tooltip(control("Canvas", "Canvas", focus),
container(text("F6: enter/leave canvas controls · Tab: next · Enter/Space: activate · Esc: leave").size(12)).padding(7).style(crate::style::card),
tooltip::Position::Bottom),
control("Fit", "Fit", Some(zoom(None))),
control("ZoomOut", "−", Some(zoom(Some(scale / 1.25)))),
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).into()
].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),
tooltip::Position::Bottom,
).into()
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -628,7 +628,7 @@ pub(crate) async fn retained_toolbar_boundaries(
use iced::keyboard::key::Named;
for boundary in ["Chooser", "Dirty", "Picker"] {
let mut packets = vec![];
for name in ["Fit", tool, "Details", "Panels", "Canvas"] {
for name in ["Fit", tool, "Details"] {
packets.push(capture_toolbar(mounted, app, name));
}
let lifetime = app.camera_epoch;
@@ -106,35 +106,7 @@ pub fn view<'a>(app: &'a App, owner: Id, out: Column<'a, Message>) -> Element<'a
.height(Fill)
.style(style::card)
.into();
let mut navigation = row![
out.width(Fill),
super::super::canvas_workspace::Control::new(
button(
text(if presentation.focused {
"Restore panels"
} else {
"Focus canvas"
})
.size(12)
)
.padding(6)
.on_press(super::super::canvas_workspace::intent(
scope,
"Panels",
Message::ScenarioCanvas(CanvasEvent::Focus(context))
)),
scope,
"Panels",
keyboard,
Some(super::super::canvas_workspace::intent(
scope,
"Panels",
Message::ScenarioCanvas(CanvasEvent::Focus(context))
)),
camera
)
]
.spacing(6);
let mut navigation = row![out.width(Fill)].spacing(6);
if state.can_back(p, context) {
navigation =
navigation.push(button(text("Back").size(12)).padding(6).on_press_maybe(
@@ -148,11 +120,6 @@ pub fn view<'a>(app: &'a App, owner: Id, out: Column<'a, Message>) -> Element<'a
keyboard,
scale,
Message::ScenarioCanvas(CanvasEvent::Shelf(context, Shelf::Selection)),
clean.then_some(Message::ScenarioCanvas(CanvasEvent::Camera(
context,
scope.epoch,
super::super::canvas_workspace::Event::Focus
))),
move |zoom| Message::ScenarioCanvas(CanvasEvent::Zoom(context, zoom)),
camera
)
@@ -12,6 +12,15 @@ async fn production_scenario_canvas_keeps_bounds_draft_identity_and_camera_throu
let _ = app.update(Message::Page(crate::app::Page::Behavior));
app.window_size = Size::new(1100., 700.);
let mut mounted = Mounted::new(&mut app).await;
let geometry = mounted.geometry(&app);
let scope = canvas_workspace::tests::scope(&app);
for removed in ["Canvas", "Panels"] {
assert!(!geometry.containers.contains_key(&scope.control_id(removed)));
}
assert!(
!canvas_workspace::tests::focused(&mut mounted, &app, "viewport"),
"direct editing needs no activation or initial keyboard focus grab"
);
for size in [Size::new(1100., 700.), Size::new(1440., 900.)] {
app.window_size = size;
mounted.settle(&mut app).await;
@@ -1362,6 +1371,11 @@ 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();
@@ -1531,10 +1545,7 @@ async fn production_scenario_keyboard_enters_activates_draws_focus_and_returns_t
)));
assert_eq!(app.behavior.scenario.presentation.pan, iced::Vector::ZERO);
assert!(focused(&mut mounted, &app, "Fit"));
tab_to(&mut mounted, &mut app, "Canvas").await;
mounted
.batch(&mut app, &[key(Named::Enter)], mouse::Cursor::Unavailable)
.await;
tab_to(&mut mounted, &mut app, "viewport").await;
assert!(focused(&mut mounted, &app, "viewport"));
mounted
.batch(&mut app, &[key(Named::Escape)], mouse::Cursor::Unavailable)
@@ -18,6 +18,15 @@ async fn production_process_canvas_scaled_path_creation_preserves_source_and_edi
let _ = app.update(Message::Page(crate::app::Page::Behavior));
app.window_size = size;
mounted.settle(&mut app).await;
let geometry = mounted.geometry(&app);
let scope = canvas_workspace::tests::scope(&app);
for removed in ["Canvas", "Panels"] {
assert!(!geometry.containers.contains_key(&scope.control_id(removed)));
}
assert!(
!canvas_workspace::tests::focused(&mut mounted, &app, "viewport"),
"direct editing needs no activation or initial keyboard focus grab"
);
for scale in [0.5, 1., 2.] {
let context = app.topology_context().unwrap();
let _ = app.update(Message::TopologyCanvas(CanvasEvent::Zoom(
@@ -239,6 +248,11 @@ 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();
@@ -399,10 +413,7 @@ async fn production_process_keyboard_enters_activates_draws_focus_and_returns_to
)));
assert_eq!(app.behavior.topology.pan, iced::Vector::ZERO);
assert!(focused(&mut mounted, &app, "Fit"));
tab_to(&mut mounted, &mut app, "Canvas").await;
mounted
.batch(&mut app, &[key(Named::Enter)], mouse::Cursor::Unavailable)
.await;
tab_to(&mut mounted, &mut app, "viewport").await;
assert!(focused(&mut mounted, &app, "viewport"));
mounted
.batch(&mut app, &[key(Named::Escape)], mouse::Cursor::Unavailable)
@@ -221,45 +221,12 @@ pub(super) fn view<'a>(app: &'a App, owner: Id, out: Column<'a, Message>) -> Ele
.style(style::card)
.into();
let header = column![
row![
out.width(Fill),
super::super::canvas_workspace::Control::new(
button(
text(if state.focused {
"Restore panels"
} else {
"Focus canvas"
})
.size(12)
)
.padding(6)
.on_press(super::super::canvas_workspace::intent(
scope,
"Panels",
Message::TopologyCanvas(CanvasEvent::Focus(context))
)),
scope,
"Panels",
keyboard,
Some(super::super::canvas_workspace::intent(
scope,
"Panels",
Message::TopologyCanvas(CanvasEvent::Focus(context))
)),
camera
)
]
.spacing(6),
super::super::canvas_workspace::controls(
scope,
keyboard,
scale,
event(Event::Shelf(Shelf::Selection)),
clean.then_some(Message::TopologyCanvas(CanvasEvent::Camera(
context,
scope.epoch,
super::super::canvas_workspace::Event::Focus
))),
move |zoom| Message::TopologyCanvas(CanvasEvent::Zoom(context, zoom)),
camera
)