Skip to content

Commit

Permalink
Add operation to menu and partial overlay support
Browse files Browse the repository at this point in the history
  • Loading branch information
genusistimelord committed Jul 24, 2024
1 parent 7ffa0de commit 1242f5e
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 3 deletions.
20 changes: 19 additions & 1 deletion src/widgets/menu/menu_bar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use iced::{
advanced::{
layout::{Limits, Node},
mouse, overlay, renderer,
widget::{tree, Tree},
widget::{tree, Operation, Tree},
Clipboard, Layout, Shell, Widget,
},
alignment, event, Element, Event, Length, Padding, Rectangle, Size,
Expand Down Expand Up @@ -258,6 +258,24 @@ where
.merge(status)
}

fn operate(
&self,
tree: &mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn Operation<()>,
) {
operation.container(None, layout.bounds(), &mut |operation| {
self.roots
.iter() // [Item...]
.zip(tree.children.iter_mut()) // [item_tree...]
.zip(layout.children()) // [widget_node...]
.for_each(|((child, state), layout)| {
child.operate(state, layout, renderer, operation);
});
});
}

fn mouse_interaction(
&self,
tree: &Tree,
Expand Down
60 changes: 59 additions & 1 deletion src/widgets/menu/menu_bar_overlay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use iced::{
advanced::{
layout::{Limits, Node},
mouse, overlay, renderer,
widget::Tree,
widget::{Operation, Tree},
Clipboard, Layout, Shell,
},
event, Event, Point, Rectangle, Size, Vector,
Expand Down Expand Up @@ -404,6 +404,64 @@ where
)
}

fn operate(
&mut self,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn Operation<()>,
) {
let bar = self.tree.state.downcast_ref::<MenuBarState>();
let Some(active) = bar.active_root else {
return;
};

// let viewport = layout.bounds();
let mut lc = layout.children();
let _bar_bounds = lc.next().unwrap().bounds();
let _roots_layout = lc.next().unwrap();

// let parent_bounds = roots_layout.children().nth(active).unwrap().bounds();
let menu_layouts_layout = lc.next().unwrap(); // Node{0, [menu_node...]}
let mut menu_layouts = menu_layouts_layout.children(); // [menu_node...]

let active_root = &self.roots[active];
let active_tree = &mut self.tree.children[active];

fn rec<'a, 'b, Message, Theme: Catalog, Renderer: renderer::Renderer>(
tree: &mut Tree,
item: &Item<'a, Message, Theme, Renderer>,
layout_iter: &mut impl Iterator<Item = Layout<'b>>,
renderer: &Renderer,
operation: &mut dyn Operation<()>,
) {
let menu = item.menu.as_ref().expect("No menu defined in this item");
let menu_tree = &mut tree.children[1];

let Some(menu_layout) = layout_iter.next() else {
return;
};

menu.operate(menu_tree, menu_layout, renderer, operation);

operation.container(None, menu_layout.bounds(), &mut |operation| {
menu.items
.iter() // [Item...]
.zip(menu_tree.children.iter_mut()) // [item_tree...] // [widget_node...]
.for_each(|(child, state)| {
rec(state, child, layout_iter, renderer, operation);
});
});
}

rec(
active_tree,
active_root,
&mut menu_layouts,
renderer,
operation,
);
}

fn draw(
&self,
renderer: &mut Renderer,
Expand Down
85 changes: 84 additions & 1 deletion src/widgets/menu/menu_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@

use super::common::*;
use super::flex;
use iced::advanced::overlay::Group;
use iced::advanced::widget::Operation;
use iced::{
advanced::{
layout::{Layout, Limits, Node},
mouse, renderer,
mouse, overlay, renderer,
widget::tree::{self, Tree},
Clipboard, Shell,
},
Expand Down Expand Up @@ -374,6 +376,62 @@ where
.merge(status)
}

pub(super) fn operate(
&self,
tree: &mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn Operation<()>,
) {
let mut lc = layout.children();
let slice_layout = lc.next().unwrap();
let _prescroll = lc.next().unwrap().bounds();
let _offset_bounds = lc.next().unwrap().bounds();
let _check_bounds = lc.next().unwrap().bounds();

let menu_state = tree.state.downcast_mut::<MenuState>();
let slice = &menu_state.slice;

operation.container(None, layout.bounds(), &mut |operation| {
self.items[slice.start_index..=slice.end_index] // [item...]
.iter()
.zip(tree.children[slice.start_index..=slice.end_index].iter_mut()) // [item_tree...]
.zip(slice_layout.children())
.for_each(|((child, state), layout)| {
child.operate(state, layout, renderer, operation);
});
});
}

#[allow(dead_code)]
pub(super) fn overlay<'b>(
&'b mut self,
tree: &'b mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
let mut lc = layout.children();
let slice_layout = lc.next()?;
let _prescroll = lc.next()?.bounds();
let _offset_bounds = lc.next()?.bounds();
let _check_bounds = lc.next()?.bounds();

let menu_state = tree.state.downcast_mut::<MenuState>();
let slice = &menu_state.slice;

let children = self.items[slice.start_index..=slice.end_index] // [item...]
.iter_mut()
.zip(tree.children[slice.start_index..=slice.end_index].iter_mut()) // [item_tree...]
.zip(slice_layout.children())
.filter_map(|((child, state), layout)| {
child.overlay(state, layout, renderer, translation)
})
.collect::<Vec<_>>();

(!children.is_empty()).then(|| Group::with_children(children).overlay())
}

/// tree: Tree{ menu_state, \[item_tree...] }
///
/// layout: Node{inf, \[ slice_node, prescroll, offset_bounds, check_bounds ]}
Expand Down Expand Up @@ -774,6 +832,31 @@ where
viewport,
);
}

pub(super) fn operate(
&self,
tree: &mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn Operation<()>,
) {
self.item
.as_widget()
.operate(&mut tree.children[0], layout, renderer, operation);
}

#[allow(dead_code)]
pub(super) fn overlay<'b>(
&'b mut self,
tree: &'b mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
translation: Vector,
) -> Option<overlay::Element<'b, Message, Theme, Renderer>> {
self.item
.as_widget_mut()
.overlay(&mut tree.children[0], layout, renderer, translation)
}
}

/// Adaptive open direction
Expand Down

0 comments on commit 1242f5e

Please sign in to comment.