feat(mtext): segmented Edit/Preview toggle, default to preview

The editor opens in preview by default and switches body views with a
segmented Edit | Preview control placed between the toolbar and the body
(active tab highlighted). All toolbar properties feed the rendered preview.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
Hakan SevenandClaude Opus 4.8 committed 2026-05-31 01:59:39 +03:00
1 parent a5ad0666ce
commit a07af32714
4 files changed
+38 -11

No files matched your search

+3 -2
View File
@@ -737,8 +737,9 @@ pub enum Message {
MTextAlign(mtext_editor::ParaAlign),
/// Toolbar line-spacing change.
MTextLineSpacing(f32),
/// Toggle the editor between the raw code input and the rendered preview.
MTextTogglePreview,
/// Switch the editor body between raw code input (`false`) and the
/// rendered preview (`true`).
MTextShowPreview(bool),
/// Commit the editor: create or update the MText entity.
MTextOk,
/// Discard the editor without creating / changing the entity.
+1 -1
View File
@@ -135,7 +135,7 @@ impl MTextEditorState {
width: "1".to_string(),
char_space: "0".to_string(),
preview_wires: Vec::new(),
show_preview: false,
show_preview: true,
attachment: AttachmentPoint::TopLeft,
line_spacing: 1.0,
// Default box ~20 characters wide; overwritten with the entity's
+2 -2
View File
@@ -3539,9 +3539,9 @@ impl OpenCADStudio {
self.rebuild_mtext_preview();
Task::none()
}
Message::MTextTogglePreview => {
Message::MTextShowPreview(on) => {
if let Some(ed) = self.mtext_editor.as_mut() {
ed.show_preview = !ed.show_preview;
ed.show_preview = on;
}
self.rebuild_mtext_preview();
Task::none()
+32 -6
View File
@@ -1550,11 +1550,6 @@ fn mtext_editor_overlay<'a>(
button(lbl("1")).on_press(Message::MTextLineSpacing(1.0)).padding(3).style(btn_style),
button(lbl("1.5")).on_press(Message::MTextLineSpacing(1.5)).padding(3).style(btn_style),
button(lbl("2")).on_press(Message::MTextLineSpacing(2.0)).padding(3).style(btn_style),
iced::widget::Space::new().width(6),
button(lbl(if ed.show_preview { "Code" } else { "Preview" }))
.on_press(Message::MTextTogglePreview)
.padding(3)
.style(btn_style),
iced::widget::Space::new().width(Fill),
icon_btn(include_bytes!("../../assets/icons/mt_ok.svg"), Message::MTextOk),
icon_btn(include_bytes!("../../assets/icons/mt_cancel.svg"), Message::MTextCancel),
@@ -1562,6 +1557,37 @@ fn mtext_editor_overlay<'a>(
.spacing(4)
.align_y(iced::Alignment::Center);
// ── Segmented Edit | Preview toggle (between toolbar and body) ────────
let seg_btn = move |label: &'static str, active: bool, on: Message| -> Element<'static, Message> {
button(text(label).size(12).color(if active {
Color::WHITE
} else {
Color { r: 0.80, g: 0.80, b: 0.80, a: 1.0 }
}))
.on_press(on)
.padding([4, 14])
.style(move |_: &Theme, _| button::Style {
background: Some(Background::Color(if active {
Color { r: 0.20, g: 0.42, b: 0.72, a: 1.0 }
} else {
Color { r: 0.20, g: 0.20, b: 0.20, a: 1.0 }
})),
text_color: TEXT_COL,
border: Border { color: BORDER, width: 1.0, radius: 4.0.into() },
shadow: iced::Shadow::default(),
snap: false,
})
.into()
};
let toggle = container(
row![
seg_btn("Edit", !ed.show_preview, Message::MTextShowPreview(false)),
seg_btn("Preview", ed.show_preview, Message::MTextShowPreview(true)),
]
.spacing(0),
)
.padding([6, 0]);
// ── Body: toggles between raw code input and rendered preview ────────
const VIEW_H: f32 = 150.0;
let body: Element<'a, Message> = if ed.show_preview {
@@ -1604,7 +1630,7 @@ fn mtext_editor_overlay<'a>(
.into()
};
let panel = container(column![row1, row2, body].spacing(5))
let panel = container(column![row1, row2, toggle, body].spacing(5))
.style(move |_: &Theme| container::Style {
background: Some(Background::Color(PANEL_BG)),
border: Border { color: BORDER, width: 1.0, radius: 5.0.into() },