forked from 1b-agent/opencadstudio-upstream
feat(ribbon): wrap compact panels onto extra rows when still too narrow
DensitySwap now takes a third, narrowest variant: the compact panels flex-wrapped (via WrapFlow) across as many rows as the width needs. The tool area therefore degrades full -> compact -> wrapped as the window shrinks. build_tool_row becomes build_tool_groups, returning fixed-height panel elements so they lay out identically in a row or a wrap flow. The tool bar is no longer a fixed TOOL_BAR_H; DensitySwap reports its measured height into a cell and the ribbon dropdown overlays anchor at tab_bar_height() + tool_bar_height() so they track the taller bar. Second stage of the adaptive tool area (shrink -> wrap -> collapse). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
65dfd4e462
commit
ff36a1bdac
2 files changed
+79
-55
No files matched your search
+15
-3
@@ -621,6 +621,7 @@ impl<'a> From<WrapFlow<'a>> for Element<'a, Message> {
|
||||
pub struct DensitySwap<'a> {
|
||||
variants: Vec<Element<'a, Message>>,
|
||||
chosen: Cell<usize>,
|
||||
height_out: Option<Arc<AtomicU32>>,
|
||||
}
|
||||
|
||||
impl<'a> DensitySwap<'a> {
|
||||
@@ -628,8 +629,16 @@ impl<'a> DensitySwap<'a> {
|
||||
Self {
|
||||
variants,
|
||||
chosen: Cell::new(0),
|
||||
height_out: None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Report the chosen variant's height (bits of an `f32`) so callers can
|
||||
/// anchor overlays below a possibly-taller (wrapped) tool area.
|
||||
pub fn report_height(mut self, out: Arc<AtomicU32>) -> Self {
|
||||
self.height_out = Some(out);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Widget<Message, Theme, Renderer> for DensitySwap<'a> {
|
||||
@@ -643,7 +652,7 @@ impl<'a> Widget<Message, Theme, Renderer> for DensitySwap<'a> {
|
||||
}
|
||||
|
||||
fn size(&self) -> Size<Length> {
|
||||
Size::new(Length::Shrink, Length::Fill)
|
||||
Size::new(Length::Shrink, Length::Shrink)
|
||||
}
|
||||
|
||||
fn layout(
|
||||
@@ -654,10 +663,10 @@ impl<'a> Widget<Message, Theme, Renderer> for DensitySwap<'a> {
|
||||
) -> layout::Node {
|
||||
let max_w = limits.max().width;
|
||||
let natural =
|
||||
layout::Limits::new(Size::ZERO, Size::new(f32::INFINITY, limits.max().height));
|
||||
layout::Limits::new(Size::ZERO, Size::new(f32::INFINITY, f32::INFINITY));
|
||||
|
||||
// Widest-first: keep the first variant whose natural width fits; else the
|
||||
// last (narrowest).
|
||||
// last (which is expected to wrap to fit any width).
|
||||
let mut pick = self.variants.len().saturating_sub(1);
|
||||
for (i, v) in self.variants.iter_mut().enumerate() {
|
||||
let n = v.as_widget_mut().layout(&mut tree.children[i], renderer, &natural);
|
||||
@@ -673,6 +682,9 @@ impl<'a> Widget<Message, Theme, Renderer> for DensitySwap<'a> {
|
||||
.as_widget_mut()
|
||||
.layout(&mut tree.children[pick], renderer, limits);
|
||||
let sz = node.size();
|
||||
if let Some(out) = &self.height_out {
|
||||
out.store(sz.height.to_bits(), Ordering::Relaxed);
|
||||
}
|
||||
layout::Node::with_children(sz, vec![node])
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user