forked from 1b-agent/opencadstudio-upstream
fix(ui): open the OSNAP settings popup near its button, not the corner
The snap popup used a hardcoded 4 px right offset, pinning it to the window's right edge — but the Osnap button sits well to the left, with up to ten pills after it (Space, Scale, Units, Transparency, Isolate, …). Anchor it by the summed width of the pills that follow Osnap, honouring the user's per-pill visibility. iced gives the view no real layout metrics, so the pill widths are estimated (icon pills fixed, labelled pills approximate); the popup now opens by the button instead of the corner. Closes #248 Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
3bcb5a04c5
commit
0a60b36b66
2 files changed
+42
-1
No files matched your search
+7
-1
@@ -1262,7 +1262,13 @@ impl OpenCADStudio {
|
||||
.height(Fill);
|
||||
|
||||
let snap_layer: Element<'_, Message> = if self.snap_popup_open {
|
||||
crate::ui::popup::snap_popup::snap_popup_overlay(&self.snapper, 4.0)
|
||||
crate::ui::popup::snap_popup::snap_popup_overlay(
|
||||
&self.snapper,
|
||||
crate::ui::statusbar::osnap_popup_right_offset(
|
||||
&self.statusbar_config,
|
||||
tab.scene.viewport_count(),
|
||||
),
|
||||
)
|
||||
} else {
|
||||
iced::widget::Space::new().width(0).height(0).into()
|
||||
};
|
||||
|
||||
@@ -404,6 +404,41 @@ fn tip_node<'a>(content: Element<'a, Message>, body: Element<'a, Message>) -> El
|
||||
/// A status-bar toggle, drawn as a tinted icon (issue #216: the old size-10
|
||||
/// text labels were too small to read). The name lives in the tooltip each
|
||||
/// call site already wraps it with.
|
||||
/// Approximate distance (px) from the window's right edge to the right edge of
|
||||
/// the Osnap button — used to anchor the OSNAP settings popup above the button
|
||||
/// instead of at the window corner (#248). The status-bar pills that follow
|
||||
/// Osnap are summed by estimated width (icon pills are fixed; labelled pills are
|
||||
/// approximate), honouring the user's per-pill visibility. iced gives the view
|
||||
/// no real layout metrics, so this positions the popup near the button rather
|
||||
/// than pixel-exact.
|
||||
pub fn osnap_popup_right_offset(config: &StatusBarConfig, viewport_count: usize) -> f32 {
|
||||
const SP: f32 = 2.0; // right_status row spacing between pills
|
||||
const TOGGLE: f32 = 33.0; // icon toggle pill (17px icon + [4,7] pad + border)
|
||||
// Pills after Osnap, in bar order, with estimated widths.
|
||||
let after = [
|
||||
(StatusPill::Space, 58.0),
|
||||
(StatusPill::Scale, 92.0),
|
||||
(StatusPill::Units, 42.0),
|
||||
(StatusPill::Transparency, TOGGLE),
|
||||
(StatusPill::Isolate, TOGGLE),
|
||||
(StatusPill::QuickProps, TOGGLE),
|
||||
(StatusPill::SelFilter, TOGGLE),
|
||||
(StatusPill::SelCycle, TOGGLE),
|
||||
(StatusPill::Vp, 46.0),
|
||||
(StatusPill::CleanScreen, TOGGLE),
|
||||
];
|
||||
// Bar right margin + the always-present customization button.
|
||||
let mut w = 6.0 + 30.0 + SP;
|
||||
for (pill, pw) in after {
|
||||
let shown =
|
||||
config.is_visible(pill) && !(matches!(pill, StatusPill::Vp) && viewport_count == 0);
|
||||
if shown {
|
||||
w += pw + SP;
|
||||
}
|
||||
}
|
||||
w
|
||||
}
|
||||
|
||||
fn toggle_pill(icon: &'static [u8], active: bool, msg: Message) -> Element<'static, Message> {
|
||||
let color = if active { OSNAP_ON_TEXT } else { OSNAP_OFF_TEXT };
|
||||
button(crate::ui::icons::tinted(icon, 17.0, color))
|
||||
|
||||
Reference in new issue
Block a user