forked from 1b-agent/opencadstudio-upstream
fix(text): keep in-place MText/Text editor on-screen at window edges
The editor overlay's anchor was only clamped to the top/left edge, so an MTEXT placed near the right/bottom of the viewport pushed the 640px panel (and its toolbar buttons) off-screen where they were unclickable. Both the MText editor and the single-line TEXT editor now receive the viewport canvas size and clamp the anchor against the right/bottom edges too, so the whole panel stays visible and usable wherever it is opened. Fixes #52 Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
f0b11acc88
commit
6f64d8d0d9
1 file changed
+22
-7
+22
-7
@@ -799,6 +799,7 @@ impl OpenCADStudio {
|
||||
// In-place MText editor (toolbar + text area), anchored at the
|
||||
// insertion-point click.
|
||||
if !tab.is_start {
|
||||
let canvas = tab.scene.selection.borrow().vp_size;
|
||||
if let Some(ed) = &self.mtext_editor {
|
||||
let styles: Vec<String> = tab
|
||||
.scene
|
||||
@@ -807,10 +808,10 @@ impl OpenCADStudio {
|
||||
.iter()
|
||||
.map(|s| s.name.clone())
|
||||
.collect();
|
||||
viewport_stack = viewport_stack.push(mtext_editor_overlay(ed, styles));
|
||||
viewport_stack = viewport_stack.push(mtext_editor_overlay(ed, styles, canvas));
|
||||
}
|
||||
if let Some(ed) = &self.text_inline {
|
||||
viewport_stack = viewport_stack.push(text_inline_overlay(ed));
|
||||
viewport_stack = viewport_stack.push(text_inline_overlay(ed, canvas));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1372,7 +1373,10 @@ pub(super) const TEXT_INLINE_ID: &str = "text_inline_input";
|
||||
|
||||
/// In-place single-line TEXT editor: a plain text-entry box (no formatting
|
||||
/// toolbar), anchored at the insertion-point click. Enter commits; Esc cancels.
|
||||
fn text_inline_overlay(ed: &super::text_inline::TextInlineState) -> Element<'_, Message> {
|
||||
fn text_inline_overlay(
|
||||
ed: &super::text_inline::TextInlineState,
|
||||
canvas: (f32, f32),
|
||||
) -> Element<'_, Message> {
|
||||
const PANEL_BG: Color = Color { r: 0.16, g: 0.16, b: 0.16, a: 0.98 };
|
||||
const BORDER: Color = Color { r: 0.40, g: 0.40, b: 0.40, a: 1.0 };
|
||||
|
||||
@@ -1392,9 +1396,13 @@ fn text_inline_overlay(ed: &super::text_inline::TextInlineState) -> Element<'_,
|
||||
})
|
||||
.padding(4);
|
||||
|
||||
// Keep the box on-screen so its field stays clickable at the edges.
|
||||
const PANEL_W: f32 = 240.0 + 20.0;
|
||||
const PANEL_H: f32 = 46.0;
|
||||
let (cw, ch) = canvas;
|
||||
let anchor = iced::Point::new(
|
||||
(ed.screen_anchor.x - 6.0).max(0.0),
|
||||
(ed.screen_anchor.y - 18.0).max(0.0),
|
||||
(ed.screen_anchor.x - 6.0).clamp(0.0, (cw - PANEL_W).max(0.0)),
|
||||
(ed.screen_anchor.y - 18.0).clamp(0.0, (ch - PANEL_H).max(0.0)),
|
||||
);
|
||||
position_canvas_overlay(anchor, panel.into())
|
||||
}
|
||||
@@ -1656,6 +1664,7 @@ fn mtext_preview_segments(
|
||||
fn mtext_editor_overlay<'a>(
|
||||
ed: &'a super::mtext_editor::MTextEditorState,
|
||||
styles: Vec<String>,
|
||||
canvas_size: (f32, f32),
|
||||
) -> Element<'a, Message> {
|
||||
use super::mtext_editor::{JustifyChoice, MTextFmt, ParaAlign};
|
||||
use iced::widget::{canvas, svg, text_editor};
|
||||
@@ -1891,9 +1900,15 @@ fn mtext_editor_overlay<'a>(
|
||||
.padding(6)
|
||||
.width(iced::Length::Fixed(640.0));
|
||||
|
||||
// Keep the whole panel on-screen: clamp the anchor so it never spills past
|
||||
// the right/bottom edge (where its toolbar buttons would be unclickable).
|
||||
// Width is fixed; height is the toolbar rows + the fixed VIEW_H body.
|
||||
const PANEL_W: f32 = 640.0 + 14.0; // fixed width + padding/border
|
||||
const PANEL_H: f32 = VIEW_H + 150.0; // body + toolbars/toggle/padding
|
||||
let (cw, ch) = canvas_size;
|
||||
let anchor = iced::Point::new(
|
||||
(ed.screen_anchor.x - 10.0).max(0.0),
|
||||
(ed.screen_anchor.y - 90.0).max(0.0),
|
||||
(ed.screen_anchor.x - 10.0).clamp(0.0, (cw - PANEL_W).max(0.0)),
|
||||
(ed.screen_anchor.y - 90.0).clamp(0.0, (ch - PANEL_H).max(0.0)),
|
||||
);
|
||||
position_canvas_overlay(anchor, panel.into())
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user