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:
parent
54124dc252
commit
796d7d91d0
11 changed files with 352 additions and 220 deletions
|
|
@ -580,6 +580,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
|||
// Cancel layout rename first, then fall through.
|
||||
let i_e = self.active_tab;
|
||||
if self.qselect.take().is_some() {
|
||||
self.reset_modal_geometry();
|
||||
return Task::none();
|
||||
}
|
||||
{
|
||||
|
|
@ -779,8 +780,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
|||
pub(super) fn on_layer_delete_confirm(&mut self) -> Task<Message> {
|
||||
let i = self.active_tab;
|
||||
self.active_modal = None;
|
||||
self.modal_offset = iced::Vector::ZERO;
|
||||
self.modal_resize = iced::Vector::ZERO;
|
||||
self.reset_modal_geometry();
|
||||
let Some((names, _)) = self.layer_delete_pending.take() else {
|
||||
return Task::none();
|
||||
};
|
||||
|
|
@ -1224,6 +1224,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
|||
value: String::new(),
|
||||
append: false,
|
||||
});
|
||||
self.reset_modal_geometry();
|
||||
Task::none()
|
||||
}
|
||||
|
||||
|
|
@ -2041,8 +2042,7 @@ pub(super) fn on_tab_close(&mut self, idx: usize) -> Task<Message> {
|
|||
pub(super) fn cancel_attr_editor(&mut self) {
|
||||
if self.active_modal == Some(crate::app::ModalKind::AttributeEditor) {
|
||||
self.active_modal = None;
|
||||
self.modal_offset = iced::Vector::ZERO;
|
||||
self.modal_resize = iced::Vector::ZERO;
|
||||
self.reset_modal_geometry();
|
||||
}
|
||||
self.attr_editor_handle = None;
|
||||
self.attr_editor_block.clear();
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ impl OpenCADStudio {
|
|||
self.aec_drop_acknowledged = false;
|
||||
if self.active_modal == Some(crate::app::ModalKind::SaveDialog) {
|
||||
self.active_modal = None;
|
||||
self.reset_modal_geometry();
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
|
@ -94,6 +95,7 @@ impl OpenCADStudio {
|
|||
pub(in crate::app) fn close_unsaved_dialog_window(&mut self) -> Task<Message> {
|
||||
if self.active_modal == Some(crate::app::ModalKind::Unsaved) {
|
||||
self.active_modal = None;
|
||||
self.reset_modal_geometry();
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -399,6 +399,7 @@ impl OpenCADStudio {
|
|||
/// Check if a suspended command exists on the active tab and resume it
|
||||
/// with the outcome of the text editor.
|
||||
pub(in crate::app) fn post_editor_closed(&mut self, committed: bool) -> Task<Message> {
|
||||
self.reset_modal_geometry();
|
||||
let i = self.active_tab;
|
||||
if let Some(mut cmd) = self.tabs[i].suspended_cmd.take() {
|
||||
let res = cmd.on_editor_closed(committed);
|
||||
|
|
@ -3328,6 +3329,7 @@ pub(super) fn on_open_file(&mut self) -> Task<Message> {
|
|||
// the runtime paper/scale choices still drive this one plot operation.
|
||||
self.sync_dialog_plot_runtime();
|
||||
self.active_modal = None;
|
||||
self.reset_modal_geometry();
|
||||
|
||||
let plot_style = self.dialog_plot_style(&d);
|
||||
// Extents, Window and Display use one plot path in both spaces. Only
|
||||
|
|
|
|||
|
|
@ -93,6 +93,15 @@ mod util;
|
|||
mod viewport;
|
||||
|
||||
impl OpenCADStudio {
|
||||
pub(in crate::app) fn reset_modal_geometry(&mut self) {
|
||||
self.modal_offset = iced::Vector::ZERO;
|
||||
self.modal_resize = iced::Vector::ZERO;
|
||||
self.modal_content_size = None;
|
||||
self.modal_drag_last = None;
|
||||
self.modal_dragging = false;
|
||||
self.modal_resizing = false;
|
||||
}
|
||||
|
||||
fn sync_open_command_history(&mut self) {
|
||||
if !self.command_line.history_open {
|
||||
return;
|
||||
|
|
@ -167,10 +176,7 @@ impl OpenCADStudio {
|
|||
}
|
||||
self.active_modal = None;
|
||||
// Recentre / reset the size of the next dialog and drop any drag.
|
||||
self.modal_offset = iced::Vector::ZERO;
|
||||
self.modal_resize = iced::Vector::ZERO;
|
||||
self.modal_drag_last = None;
|
||||
self.modal_dragging = false;
|
||||
self.reset_modal_geometry();
|
||||
}
|
||||
|
||||
pub fn update(&mut self, msg: Message) -> Task<Message> {
|
||||
|
|
@ -1423,6 +1429,7 @@ impl OpenCADStudio {
|
|||
if self.active_modal == Some(super::ModalKind::Layers) {
|
||||
self.ribbon.deactivate_tool_if("LAYERS");
|
||||
self.active_modal = None;
|
||||
self.reset_modal_geometry();
|
||||
} else {
|
||||
self.sync_ribbon_layers();
|
||||
self.active_modal = Some(super::ModalKind::Layers);
|
||||
|
|
@ -3335,6 +3342,7 @@ impl OpenCADStudio {
|
|||
|
||||
Message::QSelectClose => {
|
||||
self.qselect = None;
|
||||
self.reset_modal_geometry();
|
||||
Task::none()
|
||||
}
|
||||
|
||||
|
|
@ -3390,6 +3398,7 @@ impl OpenCADStudio {
|
|||
let Some(state) = self.qselect.take() else {
|
||||
return Task::none();
|
||||
};
|
||||
self.reset_modal_geometry();
|
||||
let i = self.active_tab;
|
||||
let matched = self.tabs[i].scene.qselect(
|
||||
state.type_filter.as_deref(),
|
||||
|
|
@ -4402,6 +4411,32 @@ impl OpenCADStudio {
|
|||
self.modal_drag_last = None;
|
||||
Task::none()
|
||||
}
|
||||
Message::ModalContentResized(size) => {
|
||||
if !size.width.is_finite()
|
||||
|| !size.height.is_finite()
|
||||
|| size.width <= 0.0
|
||||
|| size.height <= 0.0
|
||||
{
|
||||
return Task::none();
|
||||
}
|
||||
let first_measurement = self.modal_content_size.replace(size).is_none();
|
||||
if first_measurement {
|
||||
let initial_width = self.mtext_editor.as_ref().and_then(|editor| {
|
||||
editor.editing.is_none().then(|| {
|
||||
(size.width - 2.0 * super::view::overlay::MTEXT_PREVIEW_PAD)
|
||||
.max(80.0)
|
||||
/ editor.preview_scale()
|
||||
})
|
||||
});
|
||||
if let (Some(editor), Some(width)) =
|
||||
(self.mtext_editor.as_mut(), initial_width)
|
||||
{
|
||||
editor.rect_width = f64::from(width.max(1e-6));
|
||||
self.rebuild_mtext_preview();
|
||||
}
|
||||
}
|
||||
Task::none()
|
||||
}
|
||||
Message::RibbonLayerFilterChanged(f) => {
|
||||
self.ribbon.layer_filter = f;
|
||||
Task::none()
|
||||
|
|
@ -4444,8 +4479,11 @@ impl OpenCADStudio {
|
|||
// of being squeezed (the off-centre padding shrinks the
|
||||
// dialog once it overlaps a border).
|
||||
if let Some((cw, ch)) = self.modal_outer_size() {
|
||||
let ww = self.vp_size.0 + 440.0;
|
||||
let wh = self.vp_size.1;
|
||||
let (ww, wh) = if self.mtext_editor.is_some() {
|
||||
self.vp_size
|
||||
} else {
|
||||
self.win_size
|
||||
};
|
||||
let max_x = ((ww - cw) * 0.5).max(0.0);
|
||||
let max_y = ((wh - ch) * 0.5).max(0.0);
|
||||
self.modal_offset.x = self.modal_offset.x.clamp(-max_x, max_x);
|
||||
|
|
@ -5056,6 +5094,7 @@ impl OpenCADStudio {
|
|||
self.file_assoc_enabled = true;
|
||||
self.mark_assoc_prompted();
|
||||
self.active_modal = None;
|
||||
self.reset_modal_geometry();
|
||||
// set_default_app registers the handler first, then makes us the
|
||||
// default — boot no longer does this automatically.
|
||||
Task::perform(
|
||||
|
|
@ -5067,6 +5106,7 @@ impl OpenCADStudio {
|
|||
self.file_assoc_enabled = false;
|
||||
self.mark_assoc_prompted();
|
||||
self.active_modal = None;
|
||||
self.reset_modal_geometry();
|
||||
Task::none()
|
||||
}
|
||||
Message::AssocResult(result) => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue