Merge main into codex/graphic-attributes-cleanup

Conflicts were additions on both sides, kept together: the Count palette
and Sheet Set toggles next to the Graphic Attributes toggle in the ribbon,
main's new locale groups and catalog entries next to graphic-attributes,
and module declarations. The palette code follows main's crate renames
(acadrust -> codec, cadkernel -> kernel).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VgkJN8DEojuPTumAXLHotu
This commit is contained in:
Claude committed 2026-10-07 20:11:05 +00:00
commit 7a03e1c43c
625 files changed
+104397 -28053

No files matched your search

+125
View File
@@ -45,6 +45,14 @@ pub enum PanelId {
ExternalReferences,
/// Outline of the drawing's origin planes, open sketch and solid bodies.
Browser,
/// Node library of the node graph overlay.
NodeGraph,
/// Regions and scans of the drawing's point clouds.
PointCloudManager,
/// Block counts (COUNTLIST).
Count,
/// The open sheet sets: subsets and sheets.
SheetSetManager,
}
impl PanelId {
@@ -56,6 +64,10 @@ impl PanelId {
PanelId::BlockPalette => "Block Palette",
PanelId::ExternalReferences => "External References",
PanelId::Browser => "Browser",
PanelId::NodeGraph => "Node Graph",
PanelId::PointCloudManager => "Point Cloud Manager",
PanelId::Count => "Count",
PanelId::SheetSetManager => "Sheet Set Manager",
}
}
@@ -67,6 +79,10 @@ impl PanelId {
PanelId::BlockPalette => 260.0,
PanelId::ExternalReferences => 460.0,
PanelId::Browser => 230.0,
PanelId::NodeGraph => 220.0,
PanelId::PointCloudManager => 280.0,
PanelId::Count => 280.0,
PanelId::SheetSetManager => 280.0,
}
}
@@ -156,6 +172,10 @@ impl DockState {
PanelId::BlockPalette,
PanelId::ExternalReferences,
PanelId::Browser,
PanelId::NodeGraph,
PanelId::PointCloudManager,
PanelId::Count,
PanelId::SheetSetManager,
] {
self.panels.entry(id).or_insert_with(|| DockPanel::for_id(id));
}
@@ -256,6 +276,111 @@ pub const DOCK_MIN_W: f32 = 200.0;
/// Largest docked width a panel may be dragged or sized to.
pub const DOCK_MAX_W: f32 = 600.0;
// ── Shared panel chrome ─────────────────────────────────────────────────
use crate::app::Message;
use iced::widget::{button, container, mouse_area, row, text, tooltip, Space};
use iced::{Background, Border, Color, Element, Length, Theme};
/// The row every docked panel starts with: its title, the auto-collapse pin
/// and close. Pressing the row starts re-docking the panel.
pub fn title_bar<'a>(id: PanelId, title: String, auto_collapse: bool) -> Element<'a, Message> {
let pin_icon = if auto_collapse {
crate::ui::icons::themed_primary_weak_text(crate::ui::icons::PIN, 12.0)
} else {
crate::ui::icons::themed_secondary(crate::ui::icons::PIN, 12.0)
};
let pin = button(pin_icon)
.on_press(Message::Dock(DockMsg::AutoCollapseToggle(id)))
.style(move |theme: &Theme, status| {
let mut style = button::subtle(theme, status);
if auto_collapse {
let palette = theme.palette();
style.background = Some(Background::Color(palette.primary.weak.color));
style.text_color = palette.primary.weak.text;
style.border.color = palette.primary.base.color;
style.border.width = 1.0;
}
style
})
.padding([3, 5]);
let pin = tooltip(pin, text(crate::t!("Auto")).size(10), tooltip::Position::Bottom).gap(4);
let close = button(crate::ui::icons::themed_secondary(crate::ui::icons::CLOSE, 12.0))
.on_press(Message::Dock(DockMsg::Close(id)))
.style(button::subtle)
.padding([3, 5]);
let close = tooltip(close, text(crate::t!("Close")).size(10), tooltip::Position::Bottom).gap(4);
mouse_area(
container(
row![text(title).size(12), Space::new().width(Length::Fill), pin, close]
.spacing(3)
.align_y(iced::Center),
)
.style(|theme: &Theme| container::Style {
background: Some(Background::Color(theme.palette().background.weak.color)),
..Default::default()
})
.width(Length::Fill)
.padding([3, 6]),
)
.on_press(Message::Dock(DockMsg::DockGrab(id)))
.interaction(iced::mouse::Interaction::Grab)
.into()
}
/// Side length of a panel toolbar button's icon.
pub const TOOL_H: f32 = 22.0;
/// A panel toolbar icon button, placed on the row under the title bar.
pub fn tool_button<'a>(
icon: Element<'a, Message>,
tip: String,
message: Message,
) -> Element<'a, Message> {
let button = button(icon)
.on_press(message)
.width(Length::Fixed(TOOL_H + 8.0))
.height(Length::Fixed(TOOL_H + 8.0))
.style(|theme: &Theme, status| button::Style {
background: Some(Background::Color(match status {
button::Status::Hovered | button::Status::Pressed => {
theme.palette().background.strong.color
}
_ => Color::TRANSPARENT,
})),
border: Border {
radius: 3.0.into(),
..Default::default()
},
text_color: crate::ui::window::block_palette::block_icon_button_text_color(
theme, status,
),
..Default::default()
});
tooltip(button, text(tip).size(10), tooltip::Position::Bottom)
.gap(4)
.into()
}
/// A docked panel's body: fixed width, full height, padded, on the base
/// background with a neutral edge.
pub fn frame<'a>(content: impl Into<Element<'a, Message>>, width: f32) -> Element<'a, Message> {
container(content)
.padding(6)
.width(Length::Fixed(width))
.height(Length::Fill)
.style(|theme: &Theme| container::Style {
background: Some(Background::Color(theme.palette().background.base.color)),
border: Border {
color: theme.palette().background.neutral.color,
width: 1.0,
radius: 0.0.into(),
},
..Default::default()
})
.into()
}
#[cfg(test)]
mod tests {
use super::*;