Feat: viewport display lock, extended properties, VPLAYER and VPORTS commands
- Enforce status.locked in pan_active_viewport and zoom_active_viewport:
locked viewports now reject pan/zoom inputs entirely
- Add perspective, render_mode, shade_plot_mode, hide_plot, ucs_icon_visible
fields to the viewport property panel with appropriate pickers/toggles
- Add VPORTS command: lists all user viewports in the current layout
(id, size, position, scale, on/locked state) in the command line
- Add VPLAYER command: per-viewport layer freeze/thaw from the command line
(F <layer> to freeze, T <layer> to thaw, Enter to exit)
- Add CmdResult::VpLayerUpdate variant and its handler in apply_cmd_result
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 23:52:18 +03:00
|
|
|
use acadrust::entities::{Viewport, ViewportRenderMode};
|
2026-03-22 14:56:27 +03:00
|
|
|
use glam::Vec3;
|
|
|
|
|
|
|
|
|
|
use crate::command::EntityTransform;
|
|
|
|
|
use crate::entities::common::{diamond_grip, edit_prop as edit, parse_f64, square_grip};
|
|
|
|
|
use crate::entities::traits::{Grippable, PropertyEditable, Transformable};
|
2026-03-31 07:27:03 +03:00
|
|
|
use crate::scene::object::{GripApply, GripDef, PropSection, PropValue, Property};
|
|
|
|
|
|
|
|
|
|
// ── Standard scale options ────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
const STANDARD_SCALES: &[(&str, f64)] = &[
|
|
|
|
|
("1:500", 0.002),
|
|
|
|
|
("1:200", 0.005),
|
|
|
|
|
("1:100", 0.01),
|
|
|
|
|
("1:50", 0.02),
|
|
|
|
|
("1:20", 0.05),
|
|
|
|
|
("1:10", 0.1),
|
|
|
|
|
("1:5", 0.2),
|
|
|
|
|
("1:2", 0.5),
|
|
|
|
|
("1:1", 1.0),
|
|
|
|
|
("2:1", 2.0),
|
|
|
|
|
("5:1", 5.0),
|
|
|
|
|
("10:1", 10.0),
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
fn scale_label(scale: f64) -> String {
|
|
|
|
|
for (label, val) in STANDARD_SCALES {
|
|
|
|
|
if (scale - val).abs() < val * 0.01 {
|
|
|
|
|
return label.to_string();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
format!("{:.6}", scale).trim_end_matches('0').trim_end_matches('.').to_string()
|
|
|
|
|
}
|
|
|
|
|
|
Feat: viewport display lock, extended properties, VPLAYER and VPORTS commands
- Enforce status.locked in pan_active_viewport and zoom_active_viewport:
locked viewports now reject pan/zoom inputs entirely
- Add perspective, render_mode, shade_plot_mode, hide_plot, ucs_icon_visible
fields to the viewport property panel with appropriate pickers/toggles
- Add VPORTS command: lists all user viewports in the current layout
(id, size, position, scale, on/locked state) in the command line
- Add VPLAYER command: per-viewport layer freeze/thaw from the command line
(F <layer> to freeze, T <layer> to thaw, Enter to exit)
- Add CmdResult::VpLayerUpdate variant and its handler in apply_cmd_result
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 23:52:18 +03:00
|
|
|
// ── Render mode options ───────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
const RENDER_MODES: &[(&str, ViewportRenderMode)] = &[
|
|
|
|
|
("2D Wireframe", ViewportRenderMode::Wireframe2D),
|
|
|
|
|
("3D Wireframe", ViewportRenderMode::Wireframe3D),
|
|
|
|
|
("Hidden Line", ViewportRenderMode::HiddenLine),
|
|
|
|
|
("Flat Shaded", ViewportRenderMode::FlatShaded),
|
|
|
|
|
("Gouraud Shaded", ViewportRenderMode::GouraudShaded),
|
|
|
|
|
("Flat Shaded + Edges", ViewportRenderMode::FlatShadedWithEdges),
|
|
|
|
|
("Gouraud Shaded + Edges", ViewportRenderMode::GouraudShadedWithEdges),
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
fn render_mode_label(mode: &ViewportRenderMode) -> &'static str {
|
|
|
|
|
for (label, m) in RENDER_MODES {
|
|
|
|
|
if m == mode { return label; }
|
|
|
|
|
}
|
|
|
|
|
"2D Wireframe"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ── Shade plot mode labels ────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
const SHADE_PLOT_LABELS: &[&str] = &["As Displayed", "Wireframe", "Hidden", "Rendered"];
|
|
|
|
|
|
|
|
|
|
fn shade_plot_label(mode: i16) -> &'static str {
|
|
|
|
|
SHADE_PLOT_LABELS.get(mode as usize).copied().unwrap_or("As Displayed")
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-31 07:27:03 +03:00
|
|
|
// ── Standard view options ─────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
const STD_VIEWS: &[&str] = &[
|
|
|
|
|
"Top", "Bottom", "Front", "Back", "Left", "Right",
|
|
|
|
|
"SW Isometric", "SE Isometric", "NE Isometric", "NW Isometric",
|
|
|
|
|
];
|
2026-03-22 14:56:27 +03:00
|
|
|
|
|
|
|
|
fn grips(vp: &Viewport) -> Vec<GripDef> {
|
|
|
|
|
let cx = vp.center.x as f32;
|
|
|
|
|
let cy = vp.center.y as f32;
|
|
|
|
|
let cz = vp.center.z as f32;
|
|
|
|
|
let hw = (vp.width / 2.0) as f32;
|
|
|
|
|
let hh = (vp.height / 2.0) as f32;
|
|
|
|
|
vec![
|
|
|
|
|
diamond_grip(0, Vec3::new(cx, cy, cz)),
|
|
|
|
|
square_grip(1, Vec3::new(cx + hw, cy + hh, cz)),
|
|
|
|
|
square_grip(2, Vec3::new(cx - hw, cy + hh, cz)),
|
|
|
|
|
square_grip(3, Vec3::new(cx - hw, cy - hh, cz)),
|
|
|
|
|
square_grip(4, Vec3::new(cx + hw, cy - hh, cz)),
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn properties(vp: &Viewport) -> PropSection {
|
2026-03-31 07:27:03 +03:00
|
|
|
let scale_opts: Vec<String> = STANDARD_SCALES.iter().map(|(s, _)| s.to_string()).collect();
|
|
|
|
|
let current_scale_label = scale_label(vp.custom_scale);
|
|
|
|
|
|
|
|
|
|
let view_opts: Vec<String> = STD_VIEWS.iter().map(|s| s.to_string()).collect();
|
|
|
|
|
let current_view = viewport_view_label(vp);
|
|
|
|
|
|
Feat: viewport display lock, extended properties, VPLAYER and VPORTS commands
- Enforce status.locked in pan_active_viewport and zoom_active_viewport:
locked viewports now reject pan/zoom inputs entirely
- Add perspective, render_mode, shade_plot_mode, hide_plot, ucs_icon_visible
fields to the viewport property panel with appropriate pickers/toggles
- Add VPORTS command: lists all user viewports in the current layout
(id, size, position, scale, on/locked state) in the command line
- Add VPLAYER command: per-viewport layer freeze/thaw from the command line
(F <layer> to freeze, T <layer> to thaw, Enter to exit)
- Add CmdResult::VpLayerUpdate variant and its handler in apply_cmd_result
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 23:52:18 +03:00
|
|
|
let render_opts: Vec<String> = RENDER_MODES.iter().map(|(s, _)| s.to_string()).collect();
|
|
|
|
|
let current_render = render_mode_label(&vp.render_mode).to_string();
|
|
|
|
|
|
|
|
|
|
let shade_opts: Vec<String> = SHADE_PLOT_LABELS.iter().map(|s| s.to_string()).collect();
|
|
|
|
|
let current_shade = shade_plot_label(vp.shade_plot_mode).to_string();
|
|
|
|
|
|
2026-03-22 14:56:27 +03:00
|
|
|
PropSection {
|
|
|
|
|
title: "Geometry".into(),
|
|
|
|
|
props: vec![
|
|
|
|
|
edit("Center X", "center_x", vp.center.x),
|
|
|
|
|
edit("Center Y", "center_y", vp.center.y),
|
|
|
|
|
edit("Center Z", "center_z", vp.center.z),
|
|
|
|
|
edit("Width", "vp_w", vp.width),
|
|
|
|
|
edit("Height", "vp_h", vp.height),
|
2026-03-31 07:27:03 +03:00
|
|
|
// Numeric scale entry.
|
|
|
|
|
edit("Scale (num)", "vscale", vp.custom_scale),
|
|
|
|
|
// Standard scale picker.
|
|
|
|
|
Property {
|
|
|
|
|
label: "Scale".into(),
|
|
|
|
|
field: "vscale_std",
|
|
|
|
|
value: PropValue::Choice {
|
|
|
|
|
selected: current_scale_label,
|
|
|
|
|
options: scale_opts,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
// Standard view picker.
|
|
|
|
|
Property {
|
|
|
|
|
label: "View".into(),
|
|
|
|
|
field: "vp_view",
|
|
|
|
|
value: PropValue::Choice {
|
|
|
|
|
selected: current_view,
|
|
|
|
|
options: view_opts,
|
|
|
|
|
},
|
|
|
|
|
},
|
Feat: viewport display lock, extended properties, VPLAYER and VPORTS commands
- Enforce status.locked in pan_active_viewport and zoom_active_viewport:
locked viewports now reject pan/zoom inputs entirely
- Add perspective, render_mode, shade_plot_mode, hide_plot, ucs_icon_visible
fields to the viewport property panel with appropriate pickers/toggles
- Add VPORTS command: lists all user viewports in the current layout
(id, size, position, scale, on/locked state) in the command line
- Add VPLAYER command: per-viewport layer freeze/thaw from the command line
(F <layer> to freeze, T <layer> to thaw, Enter to exit)
- Add CmdResult::VpLayerUpdate variant and its handler in apply_cmd_result
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 23:52:18 +03:00
|
|
|
// Render mode picker.
|
|
|
|
|
Property {
|
|
|
|
|
label: "Render Mode".into(),
|
|
|
|
|
field: "vp_render",
|
|
|
|
|
value: PropValue::Choice {
|
|
|
|
|
selected: current_render,
|
|
|
|
|
options: render_opts,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
// Shade plot mode picker.
|
|
|
|
|
Property {
|
|
|
|
|
label: "Shade Plot".into(),
|
|
|
|
|
field: "vp_shade_plot",
|
|
|
|
|
value: PropValue::Choice {
|
|
|
|
|
selected: current_shade,
|
|
|
|
|
options: shade_opts,
|
|
|
|
|
},
|
|
|
|
|
},
|
2026-03-31 07:27:03 +03:00
|
|
|
// Display state toggles.
|
|
|
|
|
Property {
|
|
|
|
|
label: "Locked".into(),
|
|
|
|
|
field: "vp_locked",
|
|
|
|
|
value: PropValue::BoolToggle { field: "vp_locked", value: vp.status.locked },
|
|
|
|
|
},
|
|
|
|
|
Property {
|
|
|
|
|
label: "On".into(),
|
|
|
|
|
field: "vp_on",
|
|
|
|
|
value: PropValue::BoolToggle { field: "vp_on", value: vp.status.is_on },
|
|
|
|
|
},
|
Feat: viewport display lock, extended properties, VPLAYER and VPORTS commands
- Enforce status.locked in pan_active_viewport and zoom_active_viewport:
locked viewports now reject pan/zoom inputs entirely
- Add perspective, render_mode, shade_plot_mode, hide_plot, ucs_icon_visible
fields to the viewport property panel with appropriate pickers/toggles
- Add VPORTS command: lists all user viewports in the current layout
(id, size, position, scale, on/locked state) in the command line
- Add VPLAYER command: per-viewport layer freeze/thaw from the command line
(F <layer> to freeze, T <layer> to thaw, Enter to exit)
- Add CmdResult::VpLayerUpdate variant and its handler in apply_cmd_result
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 23:52:18 +03:00
|
|
|
Property {
|
|
|
|
|
label: "Perspective".into(),
|
|
|
|
|
field: "vp_perspective",
|
|
|
|
|
value: PropValue::BoolToggle { field: "vp_perspective", value: vp.status.perspective },
|
|
|
|
|
},
|
|
|
|
|
Property {
|
|
|
|
|
label: "Hide Plot".into(),
|
|
|
|
|
field: "vp_hide_plot",
|
|
|
|
|
value: PropValue::BoolToggle { field: "vp_hide_plot", value: vp.status.hide_plot },
|
|
|
|
|
},
|
|
|
|
|
Property {
|
|
|
|
|
label: "UCS Icon".into(),
|
|
|
|
|
field: "vp_ucs_icon",
|
|
|
|
|
value: PropValue::BoolToggle { field: "vp_ucs_icon", value: vp.ucs_icon_visible },
|
|
|
|
|
},
|
2026-03-22 14:56:27 +03:00
|
|
|
edit("Target X", "vtgt_x", vp.view_target.x),
|
|
|
|
|
edit("Target Z", "vtgt_z", vp.view_target.z),
|
|
|
|
|
],
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-31 07:27:03 +03:00
|
|
|
/// Identify which standard view matches the viewport's view direction.
|
|
|
|
|
fn viewport_view_label(vp: &Viewport) -> String {
|
|
|
|
|
let d = &vp.view_direction;
|
|
|
|
|
let dx = d.x;
|
|
|
|
|
let dy = d.y;
|
|
|
|
|
let dz = d.z;
|
|
|
|
|
|
|
|
|
|
// Use a simple threshold comparison to classify the view direction.
|
|
|
|
|
if dx.abs() < 0.1 && dy.abs() < 0.1 && dz > 0.5 { return "Top".into(); }
|
|
|
|
|
if dx.abs() < 0.1 && dy.abs() < 0.1 && dz < -0.5 { return "Bottom".into(); }
|
|
|
|
|
if dx.abs() < 0.1 && dy < -0.5 && dz.abs() < 0.1 { return "Front".into(); }
|
|
|
|
|
if dx.abs() < 0.1 && dy > 0.5 && dz.abs() < 0.1 { return "Back".into(); }
|
|
|
|
|
if dx < -0.5 && dy.abs() < 0.1 && dz.abs() < 0.1 { return "Left".into(); }
|
|
|
|
|
if dx > 0.5 && dy.abs() < 0.1 && dz.abs() < 0.1 { return "Right".into(); }
|
|
|
|
|
if dx < -0.4 && dy < -0.4 && dz > 0.4 { return "SW Isometric".into(); }
|
|
|
|
|
if dx > 0.4 && dy < -0.4 && dz > 0.4 { return "SE Isometric".into(); }
|
|
|
|
|
if dx > 0.4 && dy > 0.4 && dz > 0.4 { return "NE Isometric".into(); }
|
|
|
|
|
if dx < -0.4 && dy > 0.4 && dz > 0.4 { return "NW Isometric".into(); }
|
|
|
|
|
"Custom".into()
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-22 14:56:27 +03:00
|
|
|
fn apply_geom_prop(vp: &mut Viewport, field: &str, value: &str) {
|
2026-03-31 07:27:03 +03:00
|
|
|
use acadrust::types::Vector3;
|
|
|
|
|
|
|
|
|
|
// Boolean / toggle fields handled first (value = "toggle" or "true"/"false").
|
|
|
|
|
match field {
|
|
|
|
|
"vp_locked" => {
|
|
|
|
|
vp.status.locked = if value == "toggle" { !vp.status.locked } else { value == "true" };
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
"vp_on" => {
|
|
|
|
|
vp.status.is_on = if value == "toggle" { !vp.status.is_on } else { value == "true" };
|
|
|
|
|
return;
|
|
|
|
|
}
|
Feat: viewport display lock, extended properties, VPLAYER and VPORTS commands
- Enforce status.locked in pan_active_viewport and zoom_active_viewport:
locked viewports now reject pan/zoom inputs entirely
- Add perspective, render_mode, shade_plot_mode, hide_plot, ucs_icon_visible
fields to the viewport property panel with appropriate pickers/toggles
- Add VPORTS command: lists all user viewports in the current layout
(id, size, position, scale, on/locked state) in the command line
- Add VPLAYER command: per-viewport layer freeze/thaw from the command line
(F <layer> to freeze, T <layer> to thaw, Enter to exit)
- Add CmdResult::VpLayerUpdate variant and its handler in apply_cmd_result
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 23:52:18 +03:00
|
|
|
"vp_perspective" => {
|
|
|
|
|
vp.status.perspective = if value == "toggle" { !vp.status.perspective } else { value == "true" };
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
"vp_hide_plot" => {
|
|
|
|
|
vp.status.hide_plot = if value == "toggle" { !vp.status.hide_plot } else { value == "true" };
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
"vp_ucs_icon" => {
|
|
|
|
|
vp.ucs_icon_visible = if value == "toggle" { !vp.ucs_icon_visible } else { value == "true" };
|
|
|
|
|
return;
|
|
|
|
|
}
|
2026-03-31 07:27:03 +03:00
|
|
|
_ => {}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Standard scale picker.
|
|
|
|
|
if field == "vscale_std" {
|
|
|
|
|
if let Some(&(_, scale)) = STANDARD_SCALES.iter().find(|(label, _)| *label == value) {
|
|
|
|
|
vp.custom_scale = scale;
|
|
|
|
|
if scale > 1e-9 {
|
|
|
|
|
vp.view_height = vp.height / scale;
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-03-22 14:56:27 +03:00
|
|
|
return;
|
2026-03-31 07:27:03 +03:00
|
|
|
}
|
|
|
|
|
|
Feat: viewport display lock, extended properties, VPLAYER and VPORTS commands
- Enforce status.locked in pan_active_viewport and zoom_active_viewport:
locked viewports now reject pan/zoom inputs entirely
- Add perspective, render_mode, shade_plot_mode, hide_plot, ucs_icon_visible
fields to the viewport property panel with appropriate pickers/toggles
- Add VPORTS command: lists all user viewports in the current layout
(id, size, position, scale, on/locked state) in the command line
- Add VPLAYER command: per-viewport layer freeze/thaw from the command line
(F <layer> to freeze, T <layer> to thaw, Enter to exit)
- Add CmdResult::VpLayerUpdate variant and its handler in apply_cmd_result
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-31 23:52:18 +03:00
|
|
|
// Render mode picker.
|
|
|
|
|
if field == "vp_render" {
|
|
|
|
|
if let Some(&(_, mode)) = RENDER_MODES.iter().find(|(label, _)| *label == value) {
|
|
|
|
|
vp.render_mode = mode;
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Shade plot mode picker.
|
|
|
|
|
if field == "vp_shade_plot" {
|
|
|
|
|
if let Some(idx) = SHADE_PLOT_LABELS.iter().position(|&s| s == value) {
|
|
|
|
|
vp.shade_plot_mode = idx as i16;
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-31 07:27:03 +03:00
|
|
|
// Standard view direction picker.
|
|
|
|
|
if field == "vp_view" {
|
|
|
|
|
let dir: Option<(f64, f64, f64)> = match value {
|
|
|
|
|
"Top" => Some(( 0.0, 0.0, 1.0)),
|
|
|
|
|
"Bottom" => Some(( 0.0, 0.0, -1.0)),
|
|
|
|
|
"Front" => Some(( 0.0, -1.0, 0.0)),
|
|
|
|
|
"Back" => Some(( 0.0, 1.0, 0.0)),
|
|
|
|
|
"Left" => Some((-1.0, 0.0, 0.0)),
|
|
|
|
|
"Right" => Some(( 1.0, 0.0, 0.0)),
|
|
|
|
|
"SW Isometric" => Some((-1.0, -1.0, 1.0)),
|
|
|
|
|
"SE Isometric" => Some(( 1.0, -1.0, 1.0)),
|
|
|
|
|
"NE Isometric" => Some(( 1.0, 1.0, 1.0)),
|
|
|
|
|
"NW Isometric" => Some((-1.0, 1.0, 1.0)),
|
|
|
|
|
_ => None,
|
|
|
|
|
};
|
|
|
|
|
if let Some((dx, dy, dz)) = dir {
|
|
|
|
|
let len = (dx * dx + dy * dy + dz * dz).sqrt();
|
|
|
|
|
vp.view_direction = Vector3::new(dx / len, dy / len, dz / len);
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Numeric fields.
|
|
|
|
|
let Some(v) = parse_f64(value) else { return };
|
2026-03-22 14:56:27 +03:00
|
|
|
match field {
|
|
|
|
|
"center_x" => vp.center.x = v,
|
|
|
|
|
"center_y" => vp.center.y = v,
|
|
|
|
|
"center_z" => vp.center.z = v,
|
|
|
|
|
"vp_w" if v > 0.0 => vp.width = v,
|
|
|
|
|
"vp_h" if v > 0.0 => vp.height = v,
|
2026-03-31 07:27:03 +03:00
|
|
|
"vscale" if v > 0.0 => {
|
|
|
|
|
vp.custom_scale = v;
|
|
|
|
|
vp.view_height = vp.height / v;
|
|
|
|
|
}
|
2026-03-22 14:56:27 +03:00
|
|
|
"vtgt_x" => vp.view_target.x = v,
|
|
|
|
|
"vtgt_z" => vp.view_target.z = v,
|
|
|
|
|
_ => {}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn apply_grip(vp: &mut Viewport, grip_id: usize, apply: GripApply) {
|
|
|
|
|
match (grip_id, apply) {
|
|
|
|
|
(0, GripApply::Translate(d)) => {
|
|
|
|
|
vp.center.x += d.x as f64;
|
|
|
|
|
vp.center.y += d.y as f64;
|
|
|
|
|
vp.center.z += d.z as f64;
|
|
|
|
|
}
|
|
|
|
|
(0, GripApply::Absolute(p)) => {
|
|
|
|
|
vp.center.x = p.x as f64;
|
|
|
|
|
vp.center.y = p.y as f64;
|
|
|
|
|
vp.center.z = p.z as f64;
|
|
|
|
|
}
|
|
|
|
|
(1..=4, GripApply::Absolute(p)) => {
|
|
|
|
|
let new_hw = (p.x as f64 - vp.center.x).abs();
|
|
|
|
|
let new_hh = (p.y as f64 - vp.center.y).abs();
|
|
|
|
|
if new_hw > 0.01 {
|
|
|
|
|
vp.width = new_hw * 2.0;
|
|
|
|
|
}
|
|
|
|
|
if new_hh > 0.01 {
|
|
|
|
|
vp.height = new_hh * 2.0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
_ => {}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn apply_transform(vp: &mut Viewport, t: &EntityTransform) {
|
|
|
|
|
crate::scene::transform::apply_standard_entity_transform(vp, t, |entity, p1, p2| {
|
|
|
|
|
crate::scene::transform::reflect_xy_point(
|
|
|
|
|
&mut entity.center.x,
|
|
|
|
|
&mut entity.center.y,
|
|
|
|
|
p1,
|
|
|
|
|
p2,
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Grippable for Viewport {
|
|
|
|
|
fn grips(&self) -> Vec<GripDef> {
|
|
|
|
|
grips(self)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn apply_grip(&mut self, grip_id: usize, apply: GripApply) {
|
|
|
|
|
apply_grip(self, grip_id, apply);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl PropertyEditable for Viewport {
|
|
|
|
|
fn geometry_properties(&self, _text_style_names: &[String]) -> PropSection {
|
|
|
|
|
properties(self)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn apply_geom_prop(&mut self, field: &str, value: &str) {
|
|
|
|
|
apply_geom_prop(self, field, value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Transformable for Viewport {
|
|
|
|
|
fn apply_transform(&mut self, t: &EntityTransform) {
|
|
|
|
|
apply_transform(self, t);
|
|
|
|
|
}
|
|
|
|
|
}
|