forked from 1b-agent/opencadstudio-upstream
fix(ribbon): tooltips show again — forward child overlays
Ribbon tooltips died the day the panels moved into CollapsePanels (v0.7.6): its overlay() started with `self.open?`, so with no flyout open — the normal state — it returned None and swallowed every child overlay, and iced tooltips ARE overlays (#411). Buttons still hovered and clicked, which is why only the tips were missing. With no flyout the widget now collects the shown variants' overlays into a Group, borrows split per panel slot. Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
1 parent
a6d4b30dca
commit
4efdeceffd
1 file changed
+55
-15
+55
-15
@@ -494,23 +494,63 @@ impl<'a> Widget<Message, Theme, Renderer> for CollapsePanels<'a> {
|
||||
translation: Vector,
|
||||
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
|
||||
let levels = self.levels_snapshot(self.panels.len());
|
||||
let open_id = self.open.clone()?;
|
||||
let p = self.panels.iter().position(|pan| pan.id == open_id)?;
|
||||
// Only a button-form panel (collapsed or tight) shows a flyout.
|
||||
let lvl = levels.get(p).copied().unwrap_or(FULL);
|
||||
if lvl != COLLAPSED && lvl != TIGHT {
|
||||
return None;
|
||||
|
||||
// An open flyout owns the overlay slot.
|
||||
if let Some(open_id) = self.open.clone() {
|
||||
if let Some(p) = self.panels.iter().position(|pan| pan.id == open_id) {
|
||||
// Only a button-form panel (collapsed or tight) shows a flyout.
|
||||
let lvl = levels.get(p).copied().unwrap_or(FULL);
|
||||
if (lvl == COLLAPSED || lvl == TIGHT) && layout.children().nth(p).is_some() {
|
||||
let child_layout = layout.children().nth(p).unwrap();
|
||||
let b = child_layout.bounds();
|
||||
let anchor =
|
||||
Point::new(b.x + translation.x, b.y + b.height + translation.y);
|
||||
return Some(overlay::Element::new(Box::new(FlyoutOverlay {
|
||||
flyout: &mut self.panels[p].flyout,
|
||||
tree: &mut tree.children[SLOTS * p + 4],
|
||||
anchor,
|
||||
})));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let child_layout = layout.children().nth(p)?;
|
||||
let b = child_layout.bounds();
|
||||
let anchor = Point::new(b.x + translation.x, b.y + b.height + translation.y);
|
||||
|
||||
Some(overlay::Element::new(Box::new(FlyoutOverlay {
|
||||
flyout: &mut self.panels[p].flyout,
|
||||
tree: &mut tree.children[SLOTS * p + 4],
|
||||
anchor,
|
||||
})))
|
||||
// No flyout: forward the SHOWN children's overlays. Every ribbon
|
||||
// tooltip is an iced overlay produced inside these children, so
|
||||
// returning None here left all of them permanently dead (#411 — a
|
||||
// regression from the day this widget replaced the plain row).
|
||||
// Split borrows so each shown child and its tree slot are disjoint.
|
||||
let mut overlays = Vec::new();
|
||||
let mut tree_rest = tree.children.as_mut_slice();
|
||||
for ((i, panel), child_layout) in
|
||||
self.panels.iter_mut().enumerate().zip(layout.children())
|
||||
{
|
||||
if tree_rest.len() < SLOTS {
|
||||
break;
|
||||
}
|
||||
let (chunk, rest) = tree_rest.split_at_mut(SLOTS);
|
||||
tree_rest = rest;
|
||||
let level = levels.get(i).copied().unwrap_or(FULL);
|
||||
let child = match level {
|
||||
FULL => &mut panel.full,
|
||||
COMPACT => &mut panel.compact,
|
||||
COLLAPSED => &mut panel.button,
|
||||
_ => &mut panel.tight,
|
||||
};
|
||||
if let Some(o) = child.as_widget_mut().overlay(
|
||||
&mut chunk[level as usize],
|
||||
child_layout,
|
||||
_renderer,
|
||||
_viewport,
|
||||
translation,
|
||||
) {
|
||||
overlays.push(o);
|
||||
}
|
||||
}
|
||||
if overlays.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(overlay::Group::with_children(overlays).overlay())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user