feat!(segmented_button): Add context menu support and integrations

This commit is contained in:
Michael Aaron Murphy 2024-04-09 16:54:50 +02:00 committed by Michael Murphy
parent d54af65a2a
commit 59a913c15d
13 changed files with 612 additions and 118 deletions

View file

@ -19,14 +19,14 @@ use iced_widget::core::{
Alignment, Clipboard, Element, Layout, Length, Padding, Rectangle, Shell, Widget,
};
pub(super) struct MenuBarState {
pub(super) pressed: bool,
pub(super) view_cursor: Cursor,
pub(super) open: bool,
pub(super) active_root: Option<usize>,
pub(super) horizontal_direction: Direction,
pub(super) vertical_direction: Direction,
pub(super) menu_states: Vec<MenuState>,
pub(crate) struct MenuBarState {
pub(crate) pressed: bool,
pub(crate) view_cursor: Cursor,
pub(crate) open: bool,
pub(crate) active_root: Option<usize>,
pub(crate) horizontal_direction: Direction,
pub(crate) vertical_direction: Direction,
pub(crate) menu_states: Vec<MenuState>,
}
impl MenuBarState {
pub(super) fn get_trimmed_indices(&self) -> impl Iterator<Item = usize> + '_ {
@ -422,6 +422,7 @@ where
tree,
menu_roots: &mut self.menu_roots,
bounds_expand: self.bounds_expand,
menu_overlays_parent: false,
close_condition: self.close_condition,
item_width: self.item_width,
item_height: self.item_height,

View file

@ -221,11 +221,11 @@ impl Aod {
/// only items inside the viewport will be displayed,
/// when scrolling happens, this should be updated
#[derive(Debug, Clone, Copy)]
struct MenuSlice {
start_index: usize,
end_index: usize,
lower_bound_rel: f32,
upper_bound_rel: f32,
pub(super) struct MenuSlice {
pub(super) start_index: usize,
pub(super) end_index: usize,
pub(super) lower_bound_rel: f32,
pub(super) upper_bound_rel: f32,
}
/// Menu bounds in overlay space
@ -295,7 +295,7 @@ pub(super) struct MenuState {
menu_bounds: MenuBounds,
}
impl MenuState {
fn layout<Message, Renderer>(
pub(super) fn layout<Message, Renderer>(
&self,
overlay_offset: Vector,
slice: MenuSlice,
@ -373,7 +373,7 @@ impl MenuState {
))
}
fn slice(
pub(super) fn slice(
&self,
viewport_size: Size,
overlay_offset: Vector,
@ -427,28 +427,30 @@ impl MenuState {
}
}
pub(super) struct Menu<'a, 'b, Message, Renderer>
pub(crate) struct Menu<'a, 'b, Message, Renderer>
where
Renderer: renderer::Renderer,
{
pub(super) tree: &'b mut Tree,
pub(super) menu_roots: &'b mut Vec<MenuTree<'a, Message, Renderer>>,
pub(super) bounds_expand: u16,
pub(super) close_condition: CloseCondition,
pub(super) item_width: ItemWidth,
pub(super) item_height: ItemHeight,
pub(super) bar_bounds: Rectangle,
pub(super) main_offset: i32,
pub(super) cross_offset: i32,
pub(super) root_bounds_list: Vec<Rectangle>,
pub(super) path_highlight: Option<PathHighlight>,
pub(super) style: &'b <crate::Theme as StyleSheet>::Style,
pub(crate) tree: &'b mut Tree,
pub(crate) menu_roots: &'b mut Vec<MenuTree<'a, Message, Renderer>>,
pub(crate) bounds_expand: u16,
/// Allows menu overlay items to overlap the parent
pub(crate) menu_overlays_parent: bool,
pub(crate) close_condition: CloseCondition,
pub(crate) item_width: ItemWidth,
pub(crate) item_height: ItemHeight,
pub(crate) bar_bounds: Rectangle,
pub(crate) main_offset: i32,
pub(crate) cross_offset: i32,
pub(crate) root_bounds_list: Vec<Rectangle>,
pub(crate) path_highlight: Option<PathHighlight>,
pub(crate) style: &'b <crate::Theme as StyleSheet>::Style,
}
impl<'a, 'b, Message, Renderer> Menu<'a, 'b, Message, Renderer>
where
Renderer: renderer::Renderer,
{
pub(super) fn overlay(self) -> overlay::Element<'b, Message, crate::Theme, Renderer> {
pub(crate) fn overlay(self) -> overlay::Element<'b, Message, crate::Theme, Renderer> {
overlay::Element::new(Point::ORIGIN, Box::new(self))
}
}
@ -746,7 +748,7 @@ fn pad_rectangle(rect: Rectangle, padding: Padding) -> Rectangle {
}
}
fn init_root_menu<Message, Renderer>(
pub(super) fn init_root_menu<Message, Renderer>(
menu: &mut Menu<'_, '_, Message, Renderer>,
renderer: &Renderer,
shell: &mut Shell<'_, Message>,
@ -986,7 +988,7 @@ where
let last_parent_bounds = last_menu_bounds.parent_bounds;
let last_children_bounds = last_menu_bounds.children_bounds;
if last_parent_bounds.contains(overlay_cursor)
if (!menu.menu_overlays_parent && last_parent_bounds.contains(overlay_cursor))
// cursor is in the parent part
|| !last_children_bounds.contains(overlay_cursor)
// cursor is outside

View file

@ -25,16 +25,16 @@ use crate::{theme, widget};
pub struct MenuTree<'a, Message, Renderer = crate::Renderer> {
/// The menu tree will be flatten into a vector to build a linear widget tree,
/// the `index` field is the index of the item in that vector
pub(super) index: usize,
pub(crate) index: usize,
/// The item of the menu tree
pub(super) item: Element<'a, Message, crate::Theme, Renderer>,
pub(crate) item: Element<'a, Message, crate::Theme, Renderer>,
/// The children of the menu tree
pub(super) children: Vec<MenuTree<'a, Message, Renderer>>,
pub(crate) children: Vec<MenuTree<'a, Message, Renderer>>,
/// The width of the menu tree
pub(super) width: Option<u16>,
pub(crate) width: Option<u16>,
/// The height of the menu tree
pub(super) height: Option<u16>,
pub(crate) height: Option<u16>,
}
impl<'a, Message, Renderer> MenuTree<'a, Message, Renderer>
@ -89,7 +89,7 @@ where
/* Keep `set_index()` and `flattern()` recurse in the same order */
/// Set the index of each item
pub(super) fn set_index(&mut self) {
pub(crate) fn set_index(&mut self) {
/// inner counting function.
fn rec<Message, Renderer>(mt: &mut MenuTree<'_, Message, Renderer>, count: &mut usize) {
// keep items under the same menu line up
@ -108,7 +108,7 @@ where
}
/// Flatten the menu tree
pub(super) fn flattern(&'a self) -> Vec<&Self> {
pub(crate) fn flattern(&'a self) -> Vec<&Self> {
/// Inner flattening function
fn rec<'a, Message, Renderer>(
mt: &'a MenuTree<'a, Message, Renderer>,