feat(view): zoom-window ribbon button and bare ZOOM command

Bare `ZOOM` had no dispatch arm — only the sub-keyword forms (ZOOM
EXTENTS/IN/OUT/WINDOW/…) were handled, so typing `ZOOM` fell through to
an unknown-command error. It now starts the interactive window zoom.

Add the missing Zoom Window ribbon button: the command existed but had no
tool()/icon, so it was reachable only by typing. Wire it into View ▸
Navigate with a new dashed-rectangle magnifier icon.

Closes #210

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Hakan Seven 2026-06-28 16:56:45 +03:00
commit 9928cbf0e5
4 changed files with 24 additions and 1 deletions

View file

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="64" height="64" fill="none" stroke-linecap="round" stroke-linejoin="round">
<circle cx="11" cy="11" r="7" stroke="#e0e0e0" stroke-width="1.5"/>
<line x1="16.5" y1="16.5" x2="21" y2="21" stroke="#e0e0e0" stroke-width="1.5"/>
<rect x="7.5" y="8" width="7" height="6" stroke="#4cc9f0" stroke-width="1.5" stroke-dasharray="2 1.5"/>
</svg>

After

Width:  |  Height:  |  Size: 408 B

View file

@ -304,7 +304,10 @@ impl OpenCADStudio {
self.tabs[i].active_cmd = Some(Box::new(cmd));
}
"ZOOM WINDOW" | "ZOOM W" | "ZW" => {
// Bare ZOOM enters the interactive window zoom (pick two corners) —
// the common "zoom to a rectangle" action. The sub-keyword forms
// (ZOOM EXTENTS / IN / OUT / …) are matched above.
"ZOOM WINDOW" | "ZOOM W" | "ZW" | "ZOOM" => {
use crate::modules::view::zoom_window::ZoomWindowCommand;
let new_cmd = ZoomWindowCommand::new();
self.command_line.push_info(&new_cmd.prompt());

View file

@ -60,6 +60,7 @@ impl CadModule for ViewModule {
title: "Navigate",
tools: vec![
RibbonItem::LargeTool(zoom_ext::tool()),
RibbonItem::Tool(zoom_window::tool()),
RibbonItem::Tool(zoom_in::tool()),
RibbonItem::Tool(zoom_out::tool()),
RibbonItem::Tool(pan::tool()),

View file

@ -3,8 +3,22 @@
use glam::{DVec3, Vec3};
use crate::command::{CadCommand, CmdResult};
use crate::modules::{IconKind, ModuleEvent, ToolDef};
use crate::scene::model::wire_model::WireModel;
pub const ICON: IconKind =
IconKind::Svg(include_bytes!("../../../assets/icons/zoom_window.svg"));
/// Ribbon button: zoom into a rectangle picked by two corners.
pub fn tool() -> ToolDef {
ToolDef {
id: "ZOOM_WINDOW",
label: "Zoom Window",
icon: ICON,
event: ModuleEvent::Command("ZOOM WINDOW".to_string()),
}
}
pub struct ZoomWindowCommand {
first: Option<Vec3>,
}