wip
This commit is contained in:
parent
9e9449d302
commit
2cfef8814e
2 changed files with 147 additions and 115 deletions
|
|
@ -50,15 +50,15 @@ pub(crate) struct MenuBarStateInner {
|
||||||
pub(crate) bar_pressed: bool,
|
pub(crate) bar_pressed: bool,
|
||||||
pub(crate) view_cursor: Cursor,
|
pub(crate) view_cursor: Cursor,
|
||||||
pub(crate) open: bool,
|
pub(crate) open: bool,
|
||||||
pub(crate) active_root: HashMap<window::Id, Vec<usize>>,
|
pub(crate) active_root: Vec<Vec<usize>>,
|
||||||
pub(crate) horizontal_direction: Direction,
|
pub(crate) horizontal_direction: Direction,
|
||||||
pub(crate) vertical_direction: Direction,
|
pub(crate) vertical_direction: Direction,
|
||||||
pub(crate) menu_states: HashMap<window::Id, Vec<MenuState>>,
|
pub(crate) menu_states: Vec<Vec<MenuState>>,
|
||||||
}
|
}
|
||||||
impl MenuBarStateInner {
|
impl MenuBarStateInner {
|
||||||
pub(super) fn get_trimmed_indices(&self, id: &window::Id) -> impl Iterator<Item = usize> + '_ {
|
pub(super) fn get_trimmed_indices(&self, index: usize) -> impl Iterator<Item = usize> + '_ {
|
||||||
self.menu_states
|
self.menu_states
|
||||||
.get(id)
|
.get(index)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|v| v.iter())
|
.map(|v| v.iter())
|
||||||
.flatten()
|
.flatten()
|
||||||
|
|
@ -68,7 +68,7 @@ impl MenuBarStateInner {
|
||||||
|
|
||||||
pub(super) fn reset(&mut self) {
|
pub(super) fn reset(&mut self) {
|
||||||
self.open = false;
|
self.open = false;
|
||||||
self.active_root = HashMap::new();
|
self.active_root = Vec::new();
|
||||||
self.menu_states.clear();
|
self.menu_states.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -79,10 +79,10 @@ impl Default for MenuBarStateInner {
|
||||||
pressed: false,
|
pressed: false,
|
||||||
view_cursor: Cursor::Available([-0.5, -0.5].into()),
|
view_cursor: Cursor::Available([-0.5, -0.5].into()),
|
||||||
open: false,
|
open: false,
|
||||||
active_root: HashMap::new(),
|
active_root: Vec::new(),
|
||||||
horizontal_direction: Direction::Positive,
|
horizontal_direction: Direction::Positive,
|
||||||
vertical_direction: Direction::Positive,
|
vertical_direction: Direction::Positive,
|
||||||
menu_states: HashMap::new(),
|
menu_states: Vec::new(),
|
||||||
popup_id: HashMap::new(),
|
popup_id: HashMap::new(),
|
||||||
bar_pressed: false,
|
bar_pressed: false,
|
||||||
}
|
}
|
||||||
|
|
@ -161,6 +161,15 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_mut_or_default<T: Default>(vec: &mut Vec<T>, index: usize) -> &mut T {
|
||||||
|
if index < vec.len() {
|
||||||
|
&mut vec[index]
|
||||||
|
} else {
|
||||||
|
vec.resize_with(index + 1, T::default);
|
||||||
|
&mut vec[index]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A `MenuBar` collects `MenuTree`s and handles all the layout, event processing, and drawing.
|
/// A `MenuBar` collects `MenuTree`s and handles all the layout, event processing, and drawing.
|
||||||
#[allow(missing_debug_implementations)]
|
#[allow(missing_debug_implementations)]
|
||||||
pub struct MenuBar<Message> {
|
pub struct MenuBar<Message> {
|
||||||
|
|
@ -479,11 +488,7 @@ where
|
||||||
// draw path highlight
|
// draw path highlight
|
||||||
if self.path_highlight.is_some() {
|
if self.path_highlight.is_some() {
|
||||||
let styling = theme.appearance(&self.style);
|
let styling = theme.appearance(&self.style);
|
||||||
if let Some(active) = state
|
if let Some(active) = get_mut_or_default(&mut state.active_root, 0).get(0) {
|
||||||
.active_root
|
|
||||||
.get(&self.window_id)
|
|
||||||
.and_then(|active| active.get(0))
|
|
||||||
{
|
|
||||||
let active_bounds = layout
|
let active_bounds = layout
|
||||||
.children()
|
.children()
|
||||||
.nth(*active)
|
.nth(*active)
|
||||||
|
|
@ -527,11 +532,14 @@ where
|
||||||
_renderer: &Renderer,
|
_renderer: &Renderer,
|
||||||
translation: Vector,
|
translation: Vector,
|
||||||
) -> Option<overlay::Element<'b, Message, crate::Theme, Renderer>> {
|
) -> Option<overlay::Element<'b, Message, crate::Theme, Renderer>> {
|
||||||
// #[cfg(feature = "wayland")]
|
//#[cfg(feature = "wayland")]
|
||||||
// return None;
|
//return None;
|
||||||
|
|
||||||
let state = tree.state.downcast_ref::<MenuBarState>();
|
let state = tree.state.downcast_ref::<MenuBarState>();
|
||||||
if state.inner.with_data_mut(|state| !state.open) {
|
if state
|
||||||
|
.inner
|
||||||
|
.with_data_mut(|state| !state.open || state.active_root.is_empty())
|
||||||
|
{
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -329,7 +329,7 @@ impl MenuState {
|
||||||
// for mt in &menu_tree.children[start_index..=end_index] {
|
// for mt in &menu_tree.children[start_index..=end_index] {
|
||||||
// dbg!(mt.index);
|
// dbg!(mt.index);
|
||||||
// }
|
// }
|
||||||
dbg!((start_index, end_index));
|
dbg!((start_index, end_index, menu_tree.len()));
|
||||||
|
|
||||||
// viewport space children bounds
|
// viewport space children bounds
|
||||||
let children_bounds = self.menu_bounds.children_bounds + overlay_offset;
|
let children_bounds = self.menu_bounds.children_bounds + overlay_offset;
|
||||||
|
|
@ -360,7 +360,7 @@ impl MenuState {
|
||||||
}
|
}
|
||||||
|
|
||||||
mt.item
|
mt.item
|
||||||
.layout(&mut tree[mt.index], renderer, &limits)
|
.layout(&mut tree[i], renderer, &limits)
|
||||||
.move_to(Point::new(0.0, position + self.scroll_offset))
|
.move_to(Point::new(0.0, position + self.scroll_offset))
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
@ -469,21 +469,28 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
pub(crate) fn overlay(self) -> overlay::Element<'b, Message, crate::Theme, crate::Renderer> {
|
pub(crate) fn overlay(self) -> overlay::Element<'b, Message, crate::Theme, crate::Renderer> {
|
||||||
overlay::Element::new(Box::new(self))
|
overlay::Element::new(Box::new(self))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn layout(&mut self, renderer: &crate::Renderer, limits: Limits) -> Node {
|
fn layout(&mut self, renderer: &crate::Renderer, limits: Limits) -> Node {
|
||||||
// layout children
|
// layout children;
|
||||||
let position = self.position;
|
let position = self.position;
|
||||||
let mut intrinsic_size = Size::ZERO;
|
let mut intrinsic_size = Size::ZERO;
|
||||||
|
|
||||||
|
dbg!(self.depth);
|
||||||
|
let empty = Vec::new();
|
||||||
self.tree.inner.with_data_mut(|data| {
|
self.tree.inner.with_data_mut(|data| {
|
||||||
let overlay_offset = Point::ORIGIN - position;
|
let overlay_offset = Point::ORIGIN - position;
|
||||||
let tree_children = &mut data.tree.children;
|
let tree_children = &mut data.tree.children;
|
||||||
|
dbg!(&data.active_root,);
|
||||||
let children = data
|
let children = data
|
||||||
.active_root
|
.active_root
|
||||||
.get(&self.window_id)
|
.get(self.depth)
|
||||||
.cloned()
|
.cloned()
|
||||||
.map(|active_root| {
|
.map(|active_root| {
|
||||||
|
if active_root.is_empty() || self.menu_roots.is_empty() {
|
||||||
|
return (&empty, vec![]);
|
||||||
|
}
|
||||||
let (active_tree, roots) = if self.depth > 0 {
|
let (active_tree, roots) = if self.depth > 0 {
|
||||||
active_root.iter().skip(1).take(self.depth).fold(
|
active_root.iter().take(self.depth).fold(
|
||||||
(
|
(
|
||||||
&mut tree_children[active_root[0]].children,
|
&mut tree_children[active_root[0]].children,
|
||||||
&self.menu_roots[active_root[0]].children,
|
&self.menu_roots[active_root[0]].children,
|
||||||
|
|
@ -491,7 +498,7 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
|(tree, mt), next_active_root| (tree, &mt[*next_active_root].children),
|
|(tree, mt), next_active_root| (tree, &mt[*next_active_root].children),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
(tree_children, self.menu_roots.as_ref())
|
(tree_children, &self.menu_roots[active_root[0]].children)
|
||||||
};
|
};
|
||||||
|
|
||||||
dbg!(roots.len());
|
dbg!(roots.len());
|
||||||
|
|
@ -512,32 +519,41 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
data.menu_states[&self.window_id]
|
if let Some(ms) = data.menu_states.get(self.depth + 1) {
|
||||||
.iter()
|
ms.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.filter(|ms| self.is_overlay || ms.0 < active_root.len())
|
.filter(|ms| self.is_overlay || ms.0 < active_root.len())
|
||||||
.fold((roots, Vec::new()), |(menu_root, mut nodes), (_i, ms)| {
|
.fold((roots, Vec::new()), |(menu_root, mut nodes), (_i, ms)| {
|
||||||
dbg!(ms.index);
|
dbg!(ms.index);
|
||||||
let slice = ms.slice(limits.max(), overlay_offset, self.item_height);
|
let slice =
|
||||||
let _start_index = slice.start_index;
|
ms.slice(limits.max(), overlay_offset, self.item_height);
|
||||||
let _end_index = slice.end_index;
|
let _start_index = slice.start_index;
|
||||||
dbg!(&self.window_id, menu_root.len());
|
let _end_index = slice.end_index;
|
||||||
let children_node =
|
dbg!(&self.depth, &self.window_id, menu_root.len());
|
||||||
ms.layout(overlay_offset, slice, renderer, menu_root, active_tree);
|
let children_node = ms.layout(
|
||||||
let node_size = children_node.size();
|
overlay_offset,
|
||||||
// dbg!(node_size.height);
|
slice,
|
||||||
intrinsic_size.height += node_size.height;
|
renderer,
|
||||||
intrinsic_size.width = intrinsic_size.width.max(node_size.width);
|
menu_root,
|
||||||
nodes.push(children_node);
|
active_tree,
|
||||||
// if popup just use len 1?
|
);
|
||||||
// only the last menu can have a None active index
|
let node_size = children_node.size();
|
||||||
// dbg!(ms.index);
|
// dbg!(node_size.height);
|
||||||
(
|
intrinsic_size.height += node_size.height;
|
||||||
ms.index
|
intrinsic_size.width = intrinsic_size.width.max(node_size.width);
|
||||||
.map_or(menu_root, |active| &menu_root[active].children),
|
nodes.push(children_node);
|
||||||
nodes,
|
// if popup just use len 1?
|
||||||
)
|
// only the last menu can have a None active index
|
||||||
})
|
// dbg!(ms.index);
|
||||||
|
(
|
||||||
|
ms.index
|
||||||
|
.map_or(menu_root, |active| &menu_root[active].children),
|
||||||
|
nodes,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
(&empty, vec![])
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.map(|(_, l)| l)
|
.map(|(_, l)| l)
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
@ -592,6 +608,7 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
overlay_offset,
|
overlay_offset,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
dbg!("init_root_menu");
|
||||||
init_root_menu(
|
init_root_menu(
|
||||||
self,
|
self,
|
||||||
renderer,
|
renderer,
|
||||||
|
|
@ -650,7 +667,7 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
.distance(view_cursor.position().unwrap_or_default())
|
.distance(view_cursor.position().unwrap_or_default())
|
||||||
< 2.0
|
< 2.0
|
||||||
{
|
{
|
||||||
let is_inside = state.menu_states[&self.window_id]
|
let is_inside = state.menu_states[self.depth + 1]
|
||||||
.iter()
|
.iter()
|
||||||
.any(|ms| ms.menu_bounds.check_bounds.contains(overlay_cursor));
|
.any(|ms| ms.menu_bounds.check_bounds.contains(overlay_cursor));
|
||||||
|
|
||||||
|
|
@ -696,7 +713,7 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
view_cursor: Cursor,
|
view_cursor: Cursor,
|
||||||
) {
|
) {
|
||||||
self.tree.inner.with_data(|state| {
|
self.tree.inner.with_data(|state| {
|
||||||
let Some(active_root) = state.active_root.get(&self.window_id) else {
|
let Some(active_root) = state.active_root.get(self.depth) else {
|
||||||
// dbg!(self.window_id);
|
// dbg!(self.window_id);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
@ -713,7 +730,7 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
|
|
||||||
let styling = theme.appearance(&self.style);
|
let styling = theme.appearance(&self.style);
|
||||||
let (active_tree, roots) = if self.depth > 0 {
|
let (active_tree, roots) = if self.depth > 0 {
|
||||||
active_root.iter().skip(1).take(self.depth).fold(
|
active_root.iter().take(self.depth).fold(
|
||||||
(
|
(
|
||||||
&state.tree.children[active_root[0]].children,
|
&state.tree.children[active_root[0]].children,
|
||||||
&self.menu_roots[active_root[0]].children,
|
&self.menu_roots[active_root[0]].children,
|
||||||
|
|
@ -726,9 +743,7 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
// let tree = &state.tree.children[active_root].children;
|
// let tree = &state.tree.children[active_root].children;
|
||||||
// let root = &self.menu_roots[active_root];
|
// let root = &self.menu_roots[active_root];
|
||||||
|
|
||||||
let indices = state
|
let indices = state.get_trimmed_indices(self.depth).collect::<Vec<_>>();
|
||||||
.get_trimmed_indices(&self.window_id)
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
// dbg!(
|
// dbg!(
|
||||||
// self.window_id,
|
// self.window_id,
|
||||||
// state.menu_states[&self.window_id].len(),
|
// state.menu_states[&self.window_id].len(),
|
||||||
|
|
@ -736,7 +751,7 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
// root.children.len(),
|
// root.children.len(),
|
||||||
// layout.bounds()
|
// layout.bounds()
|
||||||
// );
|
// );
|
||||||
state.menu_states[&self.window_id]
|
state.menu_states[self.depth + 1]
|
||||||
.iter()
|
.iter()
|
||||||
.zip(layout.children())
|
.zip(layout.children())
|
||||||
.enumerate()
|
.enumerate()
|
||||||
|
|
@ -893,7 +908,7 @@ pub(super) fn init_root_menu<Message: Clone>(
|
||||||
menu.tree.inner.with_data_mut(|state| {
|
menu.tree.inner.with_data_mut(|state| {
|
||||||
if !(state
|
if !(state
|
||||||
.menu_states
|
.menu_states
|
||||||
.get(&menu.window_id)
|
.get(menu.depth + 1)
|
||||||
.is_none_or(|s| s.is_empty())
|
.is_none_or(|s| s.is_empty())
|
||||||
&& (!menu.is_overlay || bar_bounds.contains(overlay_cursor)))
|
&& (!menu.is_overlay || bar_bounds.contains(overlay_cursor)))
|
||||||
{
|
{
|
||||||
|
|
@ -901,48 +916,53 @@ pub(super) fn init_root_menu<Message: Clone>(
|
||||||
}
|
}
|
||||||
|
|
||||||
println!(
|
println!(
|
||||||
"init root menu {} {:?}",
|
"init root menu {} {} {:?}",
|
||||||
menu.window_id, menu.root_bounds_list
|
menu.depth, menu.window_id, &menu.root_bounds_list
|
||||||
);
|
);
|
||||||
dbg!(menu.menu_roots.len());
|
dbg!(menu.menu_roots.len());
|
||||||
// dbg!(state
|
dbg!(
|
||||||
// .menu_states
|
state
|
||||||
// .get(&menu.window_id)
|
.menu_states
|
||||||
// .is_none_or(|s| s.is_empty()));
|
.get(menu.depth + 1)
|
||||||
// dbg!(menu
|
.is_none_or(|s| s.is_empty())
|
||||||
// .menu_roots
|
);
|
||||||
// .as_slice()
|
dbg!(
|
||||||
// .iter()
|
menu.menu_roots
|
||||||
// .map(|r| r.index)
|
.as_slice()
|
||||||
// .collect::<Vec<_>>());
|
.iter()
|
||||||
|
.map(|r| r.index)
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
);
|
||||||
|
|
||||||
// dbg!(state
|
dbg!(
|
||||||
// .active_root
|
state
|
||||||
// .get(&menu.window_id)
|
.active_root
|
||||||
// .into_iter()
|
.get(menu.depth)
|
||||||
// .flatten()
|
.into_iter()
|
||||||
// .count()
|
.flatten()
|
||||||
// .saturating_sub(1));
|
.count()
|
||||||
// let root = state
|
.saturating_sub(1)
|
||||||
// .active_root
|
);
|
||||||
// .get(&menu.window_id)
|
let root = state
|
||||||
// .iter()
|
.active_root
|
||||||
// .map(|l| l.into_iter())
|
.get(menu.depth)
|
||||||
// .flatten()
|
.iter()
|
||||||
// .take(
|
.map(|l| l.into_iter())
|
||||||
// state
|
.flatten()
|
||||||
// .active_root
|
.take(
|
||||||
// .get(&menu.window_id)
|
state
|
||||||
// .into_iter()
|
.active_root
|
||||||
// .flatten()
|
.get(menu.depth)
|
||||||
// .count()
|
.into_iter()
|
||||||
// .saturating_sub(1),
|
.flatten()
|
||||||
// )
|
.count()
|
||||||
// .fold(menu.menu_roots.as_slice(), |m, i| {
|
.saturating_sub(1),
|
||||||
// dbg!(m.len());
|
)
|
||||||
// m[*i].children.as_slice()
|
.fold(menu.menu_roots.as_slice(), |m, i| {
|
||||||
// });
|
dbg!(m.len());
|
||||||
// dbg!(root.len());
|
m[*i].children.as_slice()
|
||||||
|
});
|
||||||
|
dbg!(root.len());
|
||||||
|
|
||||||
let mut set = false;
|
let mut set = false;
|
||||||
for (i, (&root_bounds, mt)) in menu
|
for (i, (&root_bounds, mt)) in menu
|
||||||
|
|
@ -955,7 +975,8 @@ pub(super) fn init_root_menu<Message: Clone>(
|
||||||
// dbg!("skipping menu with no children");
|
// dbg!("skipping menu with no children");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// dbg!(i, root_bounds.contains(overlay_cursor));
|
dbg!(mt.children.len());
|
||||||
|
dbg!(i, root_bounds.contains(overlay_cursor));
|
||||||
if root_bounds.contains(overlay_cursor) {
|
if root_bounds.contains(overlay_cursor) {
|
||||||
dbg!(root_bounds);
|
dbg!(root_bounds);
|
||||||
// dbg!(i, root_bounds, mt.width, mt.height);
|
// dbg!(i, root_bounds, mt.width, mt.height);
|
||||||
|
|
@ -992,18 +1013,20 @@ pub(super) fn init_root_menu<Message: Clone>(
|
||||||
menu.is_overlay,
|
menu.is_overlay,
|
||||||
);
|
);
|
||||||
set = true;
|
set = true;
|
||||||
// dbg!(i);
|
dbg!(i);
|
||||||
// dbg!("inserting root menu state");
|
|
||||||
// dbg!(&menu_bounds.children_bounds);
|
dbg!("inserting root menu state");
|
||||||
// dbg!((&menu_bounds.child_positions));
|
dbg!(&menu_bounds.children_bounds);
|
||||||
state.active_root.insert(menu.window_id, vec![i]);
|
dbg!((&menu_bounds.child_positions));
|
||||||
|
state.active_root.insert(menu.depth, vec![i]);
|
||||||
// do we need to insert the rest now too?
|
// do we need to insert the rest now too?
|
||||||
let ms = MenuState {
|
let ms = MenuState {
|
||||||
index: None,
|
index: None,
|
||||||
scroll_offset: 0.0,
|
scroll_offset: 0.0,
|
||||||
menu_bounds,
|
menu_bounds,
|
||||||
};
|
};
|
||||||
let v = state.menu_states.entry(menu.window_id).or_default();
|
dbg!("pushing to menu states...");
|
||||||
|
let v = super::menu_bar::get_mut_or_default(&mut state.menu_states, menu.depth + 1);
|
||||||
v.push(ms);
|
v.push(ms);
|
||||||
|
|
||||||
// Hack to ensure menu opens properly
|
// Hack to ensure menu opens properly
|
||||||
|
|
@ -1014,6 +1037,7 @@ pub(super) fn init_root_menu<Message: Clone>(
|
||||||
}
|
}
|
||||||
if !set {
|
if !set {
|
||||||
dbg!(overlay_cursor);
|
dbg!(overlay_cursor);
|
||||||
|
panic!("huh");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -1033,7 +1057,7 @@ pub(super) fn init_root_popup_menu<Message>(
|
||||||
menu.tree.inner.with_data_mut(|state| {
|
menu.tree.inner.with_data_mut(|state| {
|
||||||
if !(state
|
if !(state
|
||||||
.menu_states
|
.menu_states
|
||||||
.get(&menu.window_id)
|
.get(menu.depth + 1)
|
||||||
.is_none_or(|s| s.is_empty())
|
.is_none_or(|s| s.is_empty())
|
||||||
&& (!menu.is_overlay || bar_bounds.contains(overlay_cursor)))
|
&& (!menu.is_overlay || bar_bounds.contains(overlay_cursor)))
|
||||||
{
|
{
|
||||||
|
|
@ -1063,7 +1087,7 @@ pub(super) fn init_root_popup_menu<Message>(
|
||||||
// .count());
|
// .count());
|
||||||
let active_roots = state
|
let active_roots = state
|
||||||
.active_root
|
.active_root
|
||||||
.get(&menu.window_id)
|
.get(menu.depth)
|
||||||
.cloned()
|
.cloned()
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
dbg!(&active_roots);
|
dbg!(&active_roots);
|
||||||
|
|
@ -1132,7 +1156,7 @@ pub(super) fn init_root_popup_menu<Message>(
|
||||||
scroll_offset: 0.0,
|
scroll_offset: 0.0,
|
||||||
menu_bounds,
|
menu_bounds,
|
||||||
};
|
};
|
||||||
let v = state.menu_states.entry(menu.window_id).or_default();
|
let v = super::menu_bar::get_mut_or_default(&mut state.menu_states, menu.depth + 1);
|
||||||
v.push(ms);
|
v.push(ms);
|
||||||
|
|
||||||
// Hack to ensure menu opens properly
|
// Hack to ensure menu opens properly
|
||||||
|
|
@ -1167,11 +1191,11 @@ fn process_menu_events<'b, Message: std::clone::Clone>(
|
||||||
Cow::Owned(o) => o.as_mut_slice(),
|
Cow::Owned(o) => o.as_mut_slice(),
|
||||||
};
|
};
|
||||||
my_state.inner.with_data_mut(|state| {
|
my_state.inner.with_data_mut(|state| {
|
||||||
let Some(active_root) = state.active_root.get(&window_id).cloned() else {
|
let Some(active_root) = state.active_root.get(menu.depth).cloned() else {
|
||||||
return Status::Ignored;
|
return Status::Ignored;
|
||||||
};
|
};
|
||||||
|
|
||||||
let indices = state.get_trimmed_indices(&window_id);
|
let indices = state.get_trimmed_indices(menu.depth);
|
||||||
|
|
||||||
let indices = if is_overlay {
|
let indices = if is_overlay {
|
||||||
indices.collect::<Vec<_>>()
|
indices.collect::<Vec<_>>()
|
||||||
|
|
@ -1185,7 +1209,7 @@ fn process_menu_events<'b, Message: std::clone::Clone>(
|
||||||
|
|
||||||
// get active item
|
// get active item
|
||||||
// let mt = indices.iter().fold(root | mt, &i | &mut mt.children[i]);
|
// let mt = indices.iter().fold(root | mt, &i | &mut mt.children[i]);
|
||||||
let (tree, mt) = active_root.iter().take(menu.depth).skip(1).fold(
|
let (tree, mt) = active_root.iter().take(menu.depth).fold(
|
||||||
(
|
(
|
||||||
&mut state.tree.children[active_root[0]].children,
|
&mut state.tree.children[active_root[0]].children,
|
||||||
&mut menu_roots[active_root[0]],
|
&mut menu_roots[active_root[0]],
|
||||||
|
|
@ -1197,7 +1221,7 @@ fn process_menu_events<'b, Message: std::clone::Clone>(
|
||||||
let tree = &mut tree[mt.index];
|
let tree = &mut tree[mt.index];
|
||||||
|
|
||||||
// get layout
|
// get layout
|
||||||
let last_ms = &state.menu_states[&window_id][indices.len() - 1];
|
let last_ms = &state.menu_states[menu.depth + 1][indices.len() - 1];
|
||||||
let child_node = last_ms.layout_single(
|
let child_node = last_ms.layout_single(
|
||||||
overlay_offset,
|
overlay_offset,
|
||||||
last_ms.index.expect("missing index within menu state."),
|
last_ms.index.expect("missing index within menu state."),
|
||||||
|
|
@ -1248,7 +1272,7 @@ where
|
||||||
let mut new_menu_root = None;
|
let mut new_menu_root = None;
|
||||||
|
|
||||||
menu.tree.inner.with_data_mut(|state| {
|
menu.tree.inner.with_data_mut(|state| {
|
||||||
let Some(active_root) = state.active_root.get(&menu.window_id).clone() else {
|
let Some(active_root) = state.active_root.get(menu.depth).clone() else {
|
||||||
if is_overlay && !menu.bar_bounds.contains(overlay_cursor) {
|
if is_overlay && !menu.bar_bounds.contains(overlay_cursor) {
|
||||||
state.reset();
|
state.reset();
|
||||||
}
|
}
|
||||||
|
|
@ -1266,13 +1290,13 @@ where
|
||||||
// * remove invalid menus
|
// * remove invalid menus
|
||||||
let mut prev_bounds = std::iter::once(menu.bar_bounds)
|
let mut prev_bounds = std::iter::once(menu.bar_bounds)
|
||||||
.chain(
|
.chain(
|
||||||
state.menu_states[&menu.window_id]
|
state.menu_states[menu.depth + 1]
|
||||||
[..state.menu_states.len().saturating_sub(1).min(1)]
|
[..state.menu_states.len().saturating_sub(1).min(1)]
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ms| ms.menu_bounds.children_bounds),
|
.map(|ms| ms.menu_bounds.children_bounds),
|
||||||
)
|
)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let menu_states = state.menu_states.get_mut(&menu.window_id).unwrap();
|
let menu_states = state.menu_states.get_mut(menu.depth + 1).unwrap();
|
||||||
|
|
||||||
if menu.close_condition.leave {
|
if menu.close_condition.leave {
|
||||||
for i in (0..menu_states.len()).rev() {
|
for i in (0..menu_states.len()).rev() {
|
||||||
|
|
@ -1313,7 +1337,7 @@ where
|
||||||
let Some(last_menu_state) = menu_states.last_mut() else {
|
let Some(last_menu_state) = menu_states.last_mut() else {
|
||||||
// no menus left
|
// no menus left
|
||||||
// TODO do we want to avoid this for popups?
|
// TODO do we want to avoid this for popups?
|
||||||
state.active_root.remove(&menu.window_id);
|
state.active_root.remove(menu.depth);
|
||||||
|
|
||||||
// keep state.open when the cursor is still inside the menu bar
|
// keep state.open when the cursor is still inside the menu bar
|
||||||
// this allows the overlay to keep drawing when the cursor is
|
// this allows the overlay to keep drawing when the cursor is
|
||||||
|
|
@ -1351,7 +1375,7 @@ where
|
||||||
// |(tree, mr), next_active_root| (tree, &mr.children[*next_active_root]),
|
// |(tree, mr), next_active_root| (tree, &mr.children[*next_active_root]),
|
||||||
// );
|
// );
|
||||||
let (active_tree, roots) = if menu.depth > 0 {
|
let (active_tree, roots) = if menu.depth > 0 {
|
||||||
active_root.iter().skip(1).take(menu.depth).fold(
|
active_root.iter().take(menu.depth).fold(
|
||||||
(
|
(
|
||||||
&mut state.tree.children[active_root[0]].children,
|
&mut state.tree.children[active_root[0]].children,
|
||||||
&menu.menu_roots[active_root[0]].children,
|
&menu.menu_roots[active_root[0]].children,
|
||||||
|
|
@ -1450,7 +1474,7 @@ where
|
||||||
new_menu_root = Some((new_index, ms.clone()));
|
new_menu_root = Some((new_index, ms.clone()));
|
||||||
}
|
}
|
||||||
if should_add {
|
if should_add {
|
||||||
let v = state.menu_states.entry(menu.window_id).or_default();
|
let v = super::menu_bar::get_mut_or_default(&mut state.menu_states, menu.depth);
|
||||||
v.push(ms);
|
v.push(ms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1487,7 +1511,7 @@ where
|
||||||
(viewport_size.height - (children_bounds.y + children_bounds.height)).min(0.0);
|
(viewport_size.height - (children_bounds.y + children_bounds.height)).min(0.0);
|
||||||
(max_offset, min_offset)
|
(max_offset, min_offset)
|
||||||
};
|
};
|
||||||
let menu_states = state.menu_states.get_mut(&menu.window_id).unwrap();
|
let menu_states = state.menu_states.get_mut(menu.depth + 1).unwrap();
|
||||||
|
|
||||||
// update
|
// update
|
||||||
if menu_states.is_empty() {
|
if menu_states.is_empty() {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue