Selection tools on the right-edge toolbar instead of contextual tabs

The PDF Underlay and External Reference ribbon tabs are gone. While only
PDF underlays are selected their tools (Display in Monochrome, Create
Clipping Boundary, Remove Clipping, Show Underlay, Enable Snap, External
References, Edit Layers, Import As Objects) sit on the right-edge toolbar,
the switches drawn as on while on; while only xrefs are selected the xref
tools do. Contrast and fade stay in Properties. Toolbar tooltips are
translated.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
ramox81andClaude Opus 5.5 committed 2026-09-25 14:25:22 +03:00
1 parent 5d3987791e
commit 5a31d2089a
10 files changed
+163 -412

No files matched your search

+12 -49
View File
@@ -1,9 +1,9 @@
//! The contextual PDF Underlay ribbon tab: its values come from the selected
//! underlays, its buttons edit them.
//! The right-edge PDF underlay and xref tools: their state comes from the
//! selection, their buttons edit it.
use super::*;
use codec::entities::{Underlay, UnderlayDisplayFlags, UnderlayType};
use crate::ui::ribbon::{UnderlayContext, UnderlayTabMsg};
use crate::ui::ribbon::UnderlayContext;
impl OpenCADStudio {
/// The selected PDF underlays, or nothing when anything else is selected.
@@ -40,8 +40,9 @@ impl OpenCADStudio {
out
}
/// Show the PDF Underlay tab while only PDF underlays are selected, the
/// External Reference tab while only xrefs are.
/// The selection context for the right-edge tools: the selected PDF
/// underlay's switches while only underlays are selected, or that only
/// xrefs are.
pub(in crate::app) fn sync_underlay_tab(&mut self) {
let i = self.active_tab;
let xref = !self.tabs[i].is_start && !self.selected_xrefs(i).is_empty();
@@ -49,13 +50,11 @@ impl OpenCADStudio {
None
} else {
self.selected_pdf_underlays(i).first().map(|(_, u)| {
UnderlayContext::new(
u.contrast,
u.fade,
u.flags.contains(UnderlayDisplayFlags::MONOCHROME),
u.flags.contains(UnderlayDisplayFlags::ON),
crate::scene::model::pdf_vector::pdf_osnap(),
)
UnderlayContext {
monochrome: u.flags.contains(UnderlayDisplayFlags::MONOCHROME),
shown: u.flags.contains(UnderlayDisplayFlags::ON),
snap: crate::scene::model::pdf_vector::pdf_osnap(),
}
})
};
self.ribbon.set_underlay_context(context, xref);
@@ -90,43 +89,7 @@ impl OpenCADStudio {
self.refresh_properties();
}
pub(in crate::app) fn update_underlay_tab(&mut self, message: UnderlayTabMsg) -> Task<Message> {
let i = self.active_tab;
let Some(ctx) = self.ribbon.underlay_context_mut() else {
return Task::none();
};
match message {
UnderlayTabMsg::Contrast(v) => {
ctx.contrast = v;
ctx.contrast_text = v.to_string();
}
UnderlayTabMsg::Fade(v) => {
ctx.fade = v;
ctx.fade_text = v.to_string();
}
UnderlayTabMsg::ContrastText(s) => ctx.contrast_text = s,
UnderlayTabMsg::FadeText(s) => ctx.fade_text = s,
UnderlayTabMsg::Commit => {
// A typed value outside 0–100 or not a number keeps the value.
let parse = |s: &str, old: u8| {
s.trim().parse::<u8>().ok().filter(|v| *v <= 100).unwrap_or(old)
};
let (contrast, fade) = (
parse(&ctx.contrast_text, ctx.contrast),
parse(&ctx.fade_text, ctx.fade),
);
ctx.contrast_text = contrast.to_string();
ctx.fade_text = fade.to_string();
self.edit_selected_underlays(i, "PDFADJUST", |u| {
u.set_contrast(contrast);
u.set_fade(fade);
});
}
}
Task::none()
}
/// The tab's buttons (host-only command names).
/// The right-edge tools (host-only command names).
pub(super) fn dispatch_pdf_underlay(&mut self, cmd: &str, i: usize) -> Option<Task<Message>> {
match cmd {
"_PDFULMONO" => {
+1 -2
View File
@@ -700,8 +700,7 @@ impl OpenCADStudio {
state.selected = pages;
return Ok(Task::none());
}
// Bring a ribbon tab forward by module id ("pdf_underlay" for the
// contextual underlay tab).
// Bring a ribbon tab forward by module id.
"ribbon_tab" => {
let id = string(req, "value")?;
if !self.ribbon.select_by_id(id) {
-3
View File
@@ -3827,11 +3827,8 @@ pub enum Message {
PdfAttachPick,
/// PDFIMPORT File: pick the PDF to import.
PdfImportPick,
/// The contextual PDF Underlay tab.
RibbonSelectUnderlayTab,
/// An edit in one of the PDF dialogs.
PdfDialog(crate::ui::window::pdf_dialogs::PdfDialogMsg),
UnderlayTab(crate::ui::ribbon::UnderlayTabMsg),
PdfImportPickResult(Result<(std::path::PathBuf, std::sync::Arc<Vec<u8>>), String>),
/// Result of the PDFATTACH file picker.
PdfAttachPickResult(Result<(std::path::PathBuf, std::sync::Arc<Vec<u8>>), String>),
-5
View File
@@ -1784,11 +1784,6 @@ impl OpenCADStudio {
Task::none()
}
Message::RibbonSelectUnderlayTab => {
self.ribbon.select_underlay_tab();
Task::none()
}
Message::UnderlayTab(message) => self.update_underlay_tab(message),
Message::PdfDialog(message) => self.update_pdf_dialog(message),
Message::RibbonSelectTab(idx) => {
self.ribbon.select(idx);
+26 -3
View File
@@ -1601,9 +1601,32 @@ bg={bg_ms:.1}ms n={view_count}"
}
}
// Paper-space context actions: a right-edge vertical toolbar
// (viewport / page setup / plot) instead of a contextual ribbon tab.
if is_paper && !tab.is_start {
// Selection actions: with only PDF underlays or only xrefs
// selected, their tools take the right edge (over the paper-space
// tools, which come back when the selection changes).
// ponytail: one right-edge toolbar at a time; stack them if both
// are ever needed together.
let selection_tools = if tab.is_start {
None
} else if self.ribbon.xref_context() {
crate::ui::side_toolbar::view(&crate::ui::ribbon::xref_tools())
} else if let Some(ctx) = self.ribbon.underlay_context() {
let ctx = ctx.clone();
crate::ui::side_toolbar::view_with_active(
&crate::ui::ribbon::pdf_underlay_tools(),
&move |id| match id {
"_PDFULMONO" => ctx.monochrome,
"_PDFULSHOW" => ctx.shown,
"_PDFULSNAP" => ctx.snap,
_ => false,
},
)
} else {
None
};
if let Some(tb) = selection_tools {
viewport_stack = viewport_stack.push(tb);
} else if is_paper && !tab.is_start {
if let Some(tb) =
crate::ui::side_toolbar::view(&crate::modules::layout::paper_space_tools())
{