fix(ui): auto-size modal dialogs

Measure dialog content before fill layout so fields stay visible.\nKeep the MText preview width tied to its toolbar width.\n\nRefs #608
This commit is contained in:
Hakan Seven 2026-08-01 18:24:05 +03:00
commit 796d7d91d0
11 changed files with 352 additions and 220 deletions

View file

@ -1330,9 +1330,9 @@ impl OpenCADStudio {
viewport_stack = viewport_stack.push(mtext_editor_overlay(
ed,
styles,
canvas,
self.modal_offset,
self.modal_resize,
self.modal_content_size,
));
}
if let Some(ed) = &self.text_inline {
@ -1548,7 +1548,13 @@ impl OpenCADStudio {
let qselect_layer: Element<'_, Message> = if let Some(state) = &self.qselect {
let types = tab.scene.entity_type_names_in_layout();
let properties = tab.scene.qselect_properties(state.type_filter.as_deref());
qselect_overlay(state, &types, &properties)
qselect_overlay(
state,
&types,
&properties,
self.modal_offset,
self.modal_resize,
)
} else {
iced::widget::Space::new().width(0).height(0).into()
};
@ -1613,67 +1619,12 @@ impl OpenCADStudio {
}
}
/// Conservative outer pixel bounds for the active modal, used to clamp drag
/// so it cannot be pushed off-screen. Mirrors the maximum dimensions in
/// [`Self::modal_content`]; content-sized dialogs may render smaller.
/// `None` has no active modal. About uses a safe estimate.
/// Measured outer pixel bounds for whichever shared modal is visible, used
/// to keep its frame on-screen while dragging.
pub(crate) fn modal_outer_size(&self) -> Option<(f32, f32)> {
use super::ModalKind::*;
// Title bar (~26) + spacing (6) + frame padding (10·2) → ~52 vertical;
// frame padding → ~20 horizontal.
const EXTRA_W: f32 = 20.0;
const EXTRA_H: f32 = 52.0;
let (w, h) = match self.active_modal? {
About => (440, 360),
Shortcuts => (720, 520),
Options => (520, 500),
FindReplace => (560, 190),
PluginManager => {
#[cfg(target_arch = "wasm32")]
{
(self.web_plugin_notice_width(), 230)
}
#[cfg(not(target_arch = "wasm32"))]
{
(940, 600)
}
}
UpdateNotice => (560, 460),
Layers => (900, 360),
LayerStateManager => (720, 420),
LayerStateEditor => (1180, 560),
Plot => (760, 540),
LayoutManager => (640, 320),
Plotstyle => (780, 540),
TextStyle => (860, 480),
MlStyle => (620, 420),
TableStyle => (620, 420),
MLeaderStyle => (560, 560),
DimStyle => (720, 560),
AssocPrompt => (440, 210),
Unsaved => (420, 160),
AecDropWarning => (480, 230),
#[cfg(not(target_arch = "wasm32"))]
FileInUse => (560, 250),
#[cfg(not(target_arch = "wasm32"))]
ExternalChange => (620, 250),
#[cfg(target_arch = "wasm32")]
SaveDialog => (420, 200),
#[cfg(not(target_arch = "wasm32"))]
SaveDialog => (420, 150),
PointStyle => (360, 470),
AttributeEditor => (640, 500),
LayerDeleteWarning => (440, 200),
Aliases => (480, 520),
ScaleManager => (520, 360),
AnnoObjectScale => (360, 420),
};
// Include the user's corner-resize growth so the drag clamp tracks the
// dialog's actual footprint.
Some((
w as f32 + EXTRA_W + self.modal_resize.x,
h as f32 + EXTRA_H + self.modal_resize.y,
))
let size = self.modal_content_size?;
// Frame padding is 10 px per side; title + body spacing is 30 px.
Some((size.width + 20.0, size.height + 50.0))
}
}