feat(zoom): default to window mode
Keep all existing zoom modes available as interactive options.\n\nRefs #804
This commit is contained in:
parent
f4889d4c70
commit
08f4cc97f8
2 changed files with 68 additions and 28 deletions
|
|
@ -920,30 +920,7 @@ impl OpenCADStudio {
|
||||||
self.tabs[i].active_cmd = Some(Box::new(cmd));
|
self.tabs[i].active_cmd = Some(Box::new(cmd));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bare ZOOM prompts with the mode options as clickable keywords;
|
"ZOOM" | "ZOOM WINDOW" | "ZOOM W" | "ZW" => {
|
||||||
// the sub-keyword forms (ZOOM EXTENTS / WINDOW / …) run directly.
|
|
||||||
"ZOOM" => {
|
|
||||||
use crate::command::KeywordCommand;
|
|
||||||
let c = KeywordCommand::new(
|
|
||||||
"ZOOM",
|
|
||||||
"ZOOM [Window / Extents / Previous / Object / All / Dynamic / Extents All / In / Out / Scale]:",
|
|
||||||
vec![
|
|
||||||
("Window", "W", None),
|
|
||||||
("Extents", "E", None),
|
|
||||||
("Previous", "P", None),
|
|
||||||
("Object", "O", None),
|
|
||||||
("All", "A", None),
|
|
||||||
("Dynamic", "D", None),
|
|
||||||
("Extents All", "EA", None),
|
|
||||||
("In", "I", None),
|
|
||||||
("Out", "OUT", None),
|
|
||||||
("Scale", "S", Some("ZOOM scale factor (e.g. 2 or 0.5):")),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
self.command_line.push_info(&c.prompt());
|
|
||||||
self.tabs[i].active_cmd = Some(Box::new(c));
|
|
||||||
}
|
|
||||||
"ZOOM WINDOW" | "ZOOM W" | "ZW" => {
|
|
||||||
use crate::modules::view::zoom_window::ZoomWindowCommand;
|
use crate::modules::view::zoom_window::ZoomWindowCommand;
|
||||||
let new_cmd = ZoomWindowCommand::new();
|
let new_cmd = ZoomWindowCommand::new();
|
||||||
self.command_line.push_info(&new_cmd.prompt());
|
self.command_line.push_info(&new_cmd.prompt());
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
use glam::{DVec3, Vec3};
|
use glam::{DVec3, Vec3};
|
||||||
use crate::t;
|
use crate::t;
|
||||||
|
|
||||||
use crate::command::{CadCommand, CmdResult};
|
use crate::command::{CadCommand, CmdOption, CmdResult};
|
||||||
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
use crate::modules::{IconKind, ModuleEvent, ToolDef};
|
||||||
use crate::scene::model::wire_model::WireModel;
|
use crate::scene::model::wire_model::WireModel;
|
||||||
|
|
||||||
|
|
@ -22,11 +22,15 @@ pub fn tool() -> ToolDef {
|
||||||
|
|
||||||
pub struct ZoomWindowCommand {
|
pub struct ZoomWindowCommand {
|
||||||
first: Option<Vec3>,
|
first: Option<Vec3>,
|
||||||
|
scale_prompt: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ZoomWindowCommand {
|
impl ZoomWindowCommand {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self { first: None }
|
Self {
|
||||||
|
first: None,
|
||||||
|
scale_prompt: false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -36,14 +40,73 @@ impl CadCommand for ZoomWindowCommand {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prompt(&self) -> String {
|
fn prompt(&self) -> String {
|
||||||
if self.first.is_none() {
|
if self.scale_prompt {
|
||||||
|
t!("ZOOM scale factor (e.g. 2 or 0.5):").into_owned()
|
||||||
|
} else if self.first.is_none() {
|
||||||
t!("ZOOM WINDOW Specify first corner:").into_owned()
|
t!("ZOOM WINDOW Specify first corner:").into_owned()
|
||||||
} else {
|
} else {
|
||||||
t!("ZOOM WINDOW Specify opposite corner:").into_owned()
|
t!("ZOOM WINDOW Specify opposite corner:").into_owned()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_point(&mut self, pt: DVec3) -> CmdResult { let pt = pt.as_vec3();
|
fn options(&self) -> Vec<CmdOption> {
|
||||||
|
if self.first.is_some() || self.scale_prompt {
|
||||||
|
return Vec::new();
|
||||||
|
}
|
||||||
|
vec![
|
||||||
|
CmdOption::new("Window", "W"),
|
||||||
|
CmdOption::new("Extents", "E"),
|
||||||
|
CmdOption::new("Previous", "P"),
|
||||||
|
CmdOption::new("Object", "O"),
|
||||||
|
CmdOption::new("All", "A"),
|
||||||
|
CmdOption::new("Dynamic", "D"),
|
||||||
|
CmdOption::new("Extents All", "EA"),
|
||||||
|
CmdOption::new("In", "I"),
|
||||||
|
CmdOption::new("Out", "OUT"),
|
||||||
|
CmdOption::new("Scale", "S"),
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn wants_text_input(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_text_input(&mut self, text: &str) -> Option<CmdResult> {
|
||||||
|
let text = text.trim();
|
||||||
|
if text.is_empty() {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if self.scale_prompt {
|
||||||
|
return Some(CmdResult::Dispatch(format!("ZOOM SCALE {text}")));
|
||||||
|
}
|
||||||
|
let command = match text.to_uppercase().as_str() {
|
||||||
|
"W" | "WINDOW" => {
|
||||||
|
self.first = None;
|
||||||
|
return Some(CmdResult::NeedPoint);
|
||||||
|
}
|
||||||
|
"E" | "EXTENTS" => "ZOOM EXTENTS",
|
||||||
|
"P" | "PREVIOUS" => "ZOOM PREVIOUS",
|
||||||
|
"O" | "OBJECT" => "ZOOM OBJECT",
|
||||||
|
"A" | "ALL" => "ZOOM ALL",
|
||||||
|
"D" | "DYNAMIC" => "ZOOM DYNAMIC",
|
||||||
|
"EA" | "EXTENTS ALL" => "ZOOM EXTENTS ALL",
|
||||||
|
"I" | "IN" => "ZOOM IN",
|
||||||
|
"OUT" => "ZOOM OUT",
|
||||||
|
"S" | "SCALE" => {
|
||||||
|
self.first = None;
|
||||||
|
self.scale_prompt = true;
|
||||||
|
return Some(CmdResult::NeedPoint);
|
||||||
|
}
|
||||||
|
_ => return None,
|
||||||
|
};
|
||||||
|
Some(CmdResult::Dispatch(command.to_string()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn on_point(&mut self, pt: DVec3) -> CmdResult {
|
||||||
|
if self.scale_prompt {
|
||||||
|
return CmdResult::NeedPoint;
|
||||||
|
}
|
||||||
|
let pt = pt.as_vec3();
|
||||||
if let Some(p1) = self.first {
|
if let Some(p1) = self.first {
|
||||||
CmdResult::ZoomToWindow { p1: p1.as_dvec3(), p2: pt.as_dvec3() }
|
CmdResult::ZoomToWindow { p1: p1.as_dvec3(), p2: pt.as_dvec3() }
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue