View backgrounds: reference blend, image adjust, layouts, cleanup, style name

- Gradients: the middle colour sits (horizon - 0.5) viewport widths from the
  centre and blends over height viewport heights each side; two colours
  blend over a viewport height each side.
- Image backgrounds: offset in device pixels (right, down), negative scale
  mirrors, fitted with aspect ratio covers the viewport; the dialog keeps an
  image's offset and scale.
- Layouts: a model-space view restored on a sheet asks for the viewport,
  enters it and gives it the view's camera, background and visual style;
  inside a viewport the view goes there; a paper-space view's background is
  kept on the sheet viewport but not drawn; floating viewports draw their
  background.
- Background objects no view or viewport uses any more are erased; a view
  without a background restored where the viewport already is leaves the
  viewport's background.
- The viewport's named visual style (Realistic, ...) shows by name and the
  render-mode picker records its style on the viewport record.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
ramox81andClaude Opus 5.5 committed 2026-10-12 17:31:01 +03:00
1 parent 1cf13971dc
commit 9ef8f4bedf
12 files changed
+349 -70

No files matched your search

+4 -2
View File
@@ -30,6 +30,7 @@ pub(super) fn viewport_controls<'a>(
tile_count: usize,
render_mode_menu_open: bool,
render_mode_preview: Option<codec::entities::ViewportRenderMode>,
style_name: Option<String>,
) -> Element<'a, Message> {
let render_modes: Vec<RenderModeChoice> = crate::modules::view::visual_style::VISUAL_STYLES
.iter()
@@ -98,7 +99,7 @@ pub(super) fn viewport_controls<'a>(
// flyout keeps the current style unchanged while hovering; a click commits.
let picker_head = button(
row![
text(RenderModeChoice(render_mode).to_string()).size(11),
text(style_name.unwrap_or_else(|| RenderModeChoice(render_mode).to_string())).size(11),
crate::ui::icons::themed_arrow_toggle(render_mode_menu_open, 9.0),
]
.spacing(6)
@@ -379,7 +380,7 @@ mod tests {
#[test]
fn test_viewport_controls_construction() {
for style in crate::modules::view::visual_style::VISUAL_STYLES {
let _el = viewport_controls(style.mode, true, true, true, 1, false, None);
let _el = viewport_controls(style.mode, true, true, true, 1, false, None, None);
let _el_open = viewport_controls(
style.mode,
false,
@@ -388,6 +389,7 @@ mod tests {
2,
true,
Some(M::Wireframe3D),
None,
);
}
}
+14
View File
@@ -1297,6 +1297,18 @@ bg={bg_ms:.1}ms n={view_count}"
let rect = tab.scene.active_model_tile_bounds(vw, vh);
// Unified control chip: split buttons + render-mode picker +
// grid / grid-snap toggles, for the active Model tile.
// A named style (Realistic, …) the tile draws as shows by name.
let style_name = match tab.scene.document.objects.get(&tab.scene.active_visual_style()) {
Some(codec::objects::ObjectType::VisualStyle(style)) => {
match crate::modules::view::visual_style::mode_for_style_name(&style.description) {
Some((mode, true)) if mode == tab.render_mode => {
Some(crate::t!(style.description.as_str()).into_owned())
}
_ => None,
}
}
_ => None,
};
let bar = viewport_controls(
tab.render_mode,
self.show_grid,
@@ -1305,6 +1317,7 @@ bg={bg_ms:.1}ms n={view_count}"
tab.scene.model_tiles.borrow().len(),
self.render_mode_menu_open,
self.render_mode_preview,
style_name,
);
// Adaptive: DensitySwap measures the bar's real width every frame
// (reported into `render_bar_w`, which the ViewCube reads to decide
@@ -1397,6 +1410,7 @@ bg={bg_ms:.1}ms n={view_count}"
0,
self.render_mode_menu_open,
self.render_mode_preview,
None,
);
let adaptive: Element<'_, Message> = DensitySwap::new(vec![
iced::widget::opaque(bar),