diff --git a/src/app/mod.rs b/src/app/mod.rs index 5ad05e5fa..2e53527e0 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -179,6 +179,8 @@ pub(super) struct OpenCADStudio { isolate_popup_open: bool, /// Clean-screen mode: hide ribbon and side panels for a full canvas. clean_screen: bool, + /// Quick Properties: show a compact floating property panel on selection. + quick_properties: bool, /// Which status-bar pills the user has chosen to show (persisted). statusbar_config: crate::ui::statusbar_config::StatusBarConfig, /// Whether Tangent snap was enabled before a tangent-pick command started. @@ -752,6 +754,8 @@ pub enum Message { ToggleCleanScreen, /// Toggle whether entity transparency is shown on screen. ToggleTransparencyDisplay, + /// Toggle the Quick Properties floating panel. + ToggleQuickProperties, /// Toggle the drawing-units picker open/closed. ToggleUnitsPopup, /// Close the drawing-units picker. @@ -1223,6 +1227,7 @@ impl OpenCADStudio { isolate_popup_open: false, statusbar_config: crate::ui::statusbar_config::StatusBarConfig::load(), clean_screen: false, + quick_properties: false, pre_cmd_tangent: None, ortho_mode: false, polar_mode: false, diff --git a/src/app/update.rs b/src/app/update.rs index 2ca28a942..ec8ed98bb 100644 --- a/src/app/update.rs +++ b/src/app/update.rs @@ -3590,6 +3590,10 @@ impl OpenCADStudio { } Task::none() } + Message::ToggleQuickProperties => { + self.quick_properties ^= true; + Task::none() + } Message::ToggleUnitsPopup => { self.units_popup_open ^= true; Task::none() diff --git a/src/app/view.rs b/src/app/view.rs index 6e75b9e71..e41b6ffe4 100644 --- a/src/app/view.rs +++ b/src/app/view.rs @@ -1005,6 +1005,15 @@ impl OpenCADStudio { } } + // Quick Properties: compact floating property panel on selection, + // anchored at the canvas top-left so it doesn't track the cursor. + if self.quick_properties && !tab.is_start { + if let Some(panel) = tab.properties.quick_view() { + viewport_stack = viewport_stack + .push(position_canvas_overlay(iced::Point::new(12.0, 12.0), panel)); + } + } + // Right-click context menu. Lives inside the viewport stack so // the cursor position (canvas-relative) anchors the menu under // the cursor instead of drifting into window-relative space. @@ -1163,6 +1172,7 @@ impl OpenCADStudio { self.units_popup_open, tab.scene.is_isolation_active(), tab.scene.transparency_display, + self.quick_properties, &self.statusbar_config, ) }) diff --git a/src/ui/properties.rs b/src/ui/properties.rs index 71ac2b004..6c0a011ac 100644 --- a/src/ui/properties.rs +++ b/src/ui/properties.rs @@ -241,6 +241,47 @@ impl PropertiesPanel { .into() } + /// Compact floating panel for Quick Properties: the title plus the same + /// editable section rows as the docked panel, sized to its content. + /// Returns `None` when nothing is selected. + pub fn quick_view(&self) -> Option> { + if self.sections.is_empty() { + return None; + } + let title = container(text(&self.title).size(FONT_SZ).color(SECTION_LABEL)) + .style(|_: &Theme| container::Style { + background: Some(Background::Color(SECTION_BG)), + border: Border { + color: BORDER, + width: 1.0, + radius: 0.0.into(), + }, + ..Default::default() + }) + .width(Length::Fill) + .padding([4, 10]); + + let mut col = column![title].spacing(0); + for section in &self.sections { + col = col.push(self.render_section(section)); + } + + Some( + container(col) + .style(|_: &Theme| container::Style { + background: Some(Background::Color(PANEL_BG)), + border: Border { + color: BORDER, + width: 1.0, + radius: 3.0.into(), + }, + ..Default::default() + }) + .width(230) + .into(), + ) + } + // ── Section renderer ────────────────────────────────────────────────── fn render_section<'a>(&'a self, section: &'a PropSection) -> Element<'a, Message> { diff --git a/src/ui/statusbar.rs b/src/ui/statusbar.rs index ff848fecf..f4d45c47e 100644 --- a/src/ui/statusbar.rs +++ b/src/ui/statusbar.rs @@ -63,6 +63,8 @@ impl StatusBar { isolation_active: bool, // Whether entity transparency is shown (Transparency pill state). transparency_display: bool, + // Whether the Quick Properties floating panel is enabled. + quick_properties: bool, // Which pills the user has chosen to show on the bar. config: &'a StatusBarConfig, ) -> Element<'a, Message> { @@ -193,6 +195,12 @@ impl StatusBar { "Isolate Objects\nClick for Isolate / Hide / End", )); } + if vis(StatusPill::QuickProps) { + right_status = right_status.push(tip( + toggle_pill("QP", quick_properties, Message::ToggleQuickProperties), + "Quick Properties\nFloating panel on selection", + )); + } if vis(StatusPill::Vp) && !vp_label.is_empty() { right_status = right_status.push(tip( status_pill(vp_label).into(), diff --git a/src/ui/statusbar_config.rs b/src/ui/statusbar_config.rs index d4b97a132..e183147bc 100644 --- a/src/ui/statusbar_config.rs +++ b/src/ui/statusbar_config.rs @@ -25,6 +25,7 @@ pub enum StatusPill { Units, Transparency, Isolate, + QuickProps, Vp, CleanScreen, } @@ -47,6 +48,7 @@ impl StatusPill { StatusPill::Units, StatusPill::Transparency, StatusPill::Isolate, + StatusPill::QuickProps, StatusPill::Vp, StatusPill::CleanScreen, ]; @@ -68,6 +70,7 @@ impl StatusPill { StatusPill::Units => "units", StatusPill::Transparency => "transparency", StatusPill::Isolate => "isolate", + StatusPill::QuickProps => "quickprops", StatusPill::Vp => "vp", StatusPill::CleanScreen => "cleanscreen", } @@ -90,6 +93,7 @@ impl StatusPill { StatusPill::Units => "Drawing Units", StatusPill::Transparency => "Show Transparency", StatusPill::Isolate => "Isolate Objects", + StatusPill::QuickProps => "Quick Properties", StatusPill::Vp => "Viewport Count", StatusPill::CleanScreen => "Clean Screen", }