menu_bar: allow custom width on menu items
This commit is contained in:
parent
097c76f0e5
commit
5ae1b961dc
2 changed files with 99 additions and 30 deletions
|
|
@ -69,7 +69,8 @@ pub use menu_bar::{MenuBar, menu_bar as bar};
|
||||||
mod menu_inner;
|
mod menu_inner;
|
||||||
mod menu_tree;
|
mod menu_tree;
|
||||||
pub use menu_tree::{
|
pub use menu_tree::{
|
||||||
MenuItem as Item, MenuTree as Tree, menu_button, menu_items as items, menu_root as root,
|
MenuItem as Item, MenuItemKind as ItemKind, MenuTree as Tree, menu_button, menu_items as items,
|
||||||
|
menu_root as root,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub use crate::style::menu_bar::{Appearance, StyleSheet};
|
pub use crate::style::menu_bar::{Appearance, StyleSheet};
|
||||||
|
|
|
||||||
|
|
@ -155,24 +155,12 @@ where
|
||||||
.class(theme::Button::MenuItem)
|
.class(theme::Button::MenuItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The type of menu item
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
/// Represents a menu item that performs an action when selected or a separator between menu items.
|
pub enum MenuItemKind<A: MenuAction, L: Into<Cow<'static, str>>> {
|
||||||
///
|
|
||||||
/// - `Action` - Represents a menu item that performs an action when selected.
|
|
||||||
/// - `L` - The label of the menu item.
|
|
||||||
/// - `A` - The action to perform when the menu item is selected, the action must implement the `MenuAction` trait.
|
|
||||||
/// - `CheckBox` - Represents a checkbox menu item.
|
|
||||||
/// - `L` - The label of the menu item.
|
|
||||||
/// - `bool` - The state of the checkbox.
|
|
||||||
/// - `A` - The action to perform when the menu item is selected, the action must implement the `MenuAction` trait.
|
|
||||||
/// - `Folder` - Represents a folder menu item.
|
|
||||||
/// - `L` - The label of the menu item.
|
|
||||||
/// - `Vec<MenuItem<A, L>>` - A vector of menu items.
|
|
||||||
/// - `Divider` - Represents a divider between menu items.
|
|
||||||
pub enum MenuItem<A: MenuAction, L: Into<Cow<'static, str>>> {
|
|
||||||
/// Represents a button menu item.
|
/// Represents a button menu item.
|
||||||
Button(L, Option<icon::Handle>, A),
|
Button(L, Option<icon::Handle>, A),
|
||||||
/// Represents a button menu item that is disabled.
|
/// Represents a button menu item that's disabled.
|
||||||
ButtonDisabled(L, Option<icon::Handle>, A),
|
ButtonDisabled(L, Option<icon::Handle>, A),
|
||||||
/// Represents a checkbox menu item.
|
/// Represents a checkbox menu item.
|
||||||
CheckBox(L, Option<icon::Handle>, bool, A),
|
CheckBox(L, Option<icon::Handle>, bool, A),
|
||||||
|
|
@ -182,6 +170,54 @@ pub enum MenuItem<A: MenuAction, L: Into<Cow<'static, str>>> {
|
||||||
Divider,
|
Divider,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
/// A menu item with optional width configuration
|
||||||
|
pub struct MenuItem<A: MenuAction, L: Into<Cow<'static, str>>> {
|
||||||
|
/// Kind of menu item.
|
||||||
|
kind: MenuItemKind<A, L>,
|
||||||
|
/// Optional width override for this item's submenu.
|
||||||
|
width: Option<u16>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: MenuAction, L: Into<Cow<'static, str>>> MenuItem<A, L> {
|
||||||
|
/// Create from a kind with no width set
|
||||||
|
pub fn new(kind: MenuItemKind<A, L>) -> Self {
|
||||||
|
Self { kind, width: None }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Builder method to set width
|
||||||
|
pub fn width(mut self, width: u16) -> Self {
|
||||||
|
self.width = Some(width);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn button(label: L, icon: Option<icon::Handle>, action: A) -> Self {
|
||||||
|
Self::new(MenuItemKind::Button(label, icon, action))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn button_disabled(label: L, icon: Option<icon::Handle>, action: A) -> Self {
|
||||||
|
Self::new(MenuItemKind::ButtonDisabled(label, icon, action))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn checkbox(label: L, icon: Option<icon::Handle>, checked: bool, action: A) -> Self {
|
||||||
|
Self::new(MenuItemKind::CheckBox(label, icon, checked, action))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn folder(label: L, children: Vec<MenuItem<A, L>>) -> Self {
|
||||||
|
Self::new(MenuItemKind::Folder(label, children))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn divider() -> Self {
|
||||||
|
Self::new(MenuItemKind::Divider)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: MenuAction, L: Into<Cow<'static, str>>> From<MenuItemKind<A, L>> for MenuItem<A, L> {
|
||||||
|
fn from(kind: MenuItemKind<A, L>) -> Self {
|
||||||
|
Self::new(kind)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a root menu item.
|
/// Create a root menu item.
|
||||||
///
|
///
|
||||||
/// # Arguments
|
/// # Arguments
|
||||||
|
|
@ -246,9 +282,10 @@ pub fn menu_items<
|
||||||
.flat_map(|(i, item)| {
|
.flat_map(|(i, item)| {
|
||||||
let mut trees = vec![];
|
let mut trees = vec![];
|
||||||
let spacing = crate::theme::spacing();
|
let spacing = crate::theme::spacing();
|
||||||
|
let item_width = item.width;
|
||||||
|
|
||||||
match item {
|
match item.kind {
|
||||||
MenuItem::Button(label, icon, action) => {
|
MenuItemKind::Button(label, icon, action) => {
|
||||||
let l: Cow<'static, str> = label.into();
|
let l: Cow<'static, str> = label.into();
|
||||||
let key = find_key(&action, key_binds);
|
let key = find_key(&action, key_binds);
|
||||||
let mut items = vec![
|
let mut items = vec![
|
||||||
|
|
@ -264,9 +301,16 @@ pub fn menu_items<
|
||||||
|
|
||||||
let menu_button = menu_button(items).on_press(action.message());
|
let menu_button = menu_button(items).on_press(action.message());
|
||||||
|
|
||||||
trees.push(MenuTree::<Message>::from(Element::from(menu_button)));
|
// Add a user designated width
|
||||||
|
let mut tree = MenuTree::<Message>::from(Element::from(menu_button));
|
||||||
|
|
||||||
|
if let Some(width) = item_width {
|
||||||
|
tree = tree.width(width);
|
||||||
|
}
|
||||||
|
|
||||||
|
trees.push(tree);
|
||||||
}
|
}
|
||||||
MenuItem::ButtonDisabled(label, icon, action) => {
|
MenuItemKind::ButtonDisabled(label, icon, action) => {
|
||||||
let l: Cow<'static, str> = label.into();
|
let l: Cow<'static, str> = label.into();
|
||||||
|
|
||||||
let key = find_key(&action, key_binds);
|
let key = find_key(&action, key_binds);
|
||||||
|
|
@ -284,9 +328,15 @@ pub fn menu_items<
|
||||||
|
|
||||||
let menu_button = menu_button(items);
|
let menu_button = menu_button(items);
|
||||||
|
|
||||||
trees.push(MenuTree::<Message>::from(Element::from(menu_button)));
|
let mut tree = MenuTree::<Message>::from(Element::from(menu_button));
|
||||||
|
|
||||||
|
if let Some(width) = item_width {
|
||||||
|
tree = tree.width(width);
|
||||||
|
}
|
||||||
|
|
||||||
|
trees.push(tree);
|
||||||
}
|
}
|
||||||
MenuItem::CheckBox(label, icon, value, action) => {
|
MenuItemKind::CheckBox(label, icon, value, action) => {
|
||||||
let key = find_key(&action, key_binds);
|
let key = find_key(&action, key_binds);
|
||||||
let mut items = vec![
|
let mut items = vec![
|
||||||
if value {
|
if value {
|
||||||
|
|
@ -314,14 +364,20 @@ pub fn menu_items<
|
||||||
items.insert(2, widget::icon::icon(icon).size(14).into());
|
items.insert(2, widget::icon::icon(icon).size(14).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
trees.push(MenuTree::from(Element::from(
|
let mut tree = MenuTree::from(Element::from(
|
||||||
menu_button(items).on_press(action.message()),
|
menu_button(items).on_press(action.message()),
|
||||||
)));
|
));
|
||||||
|
|
||||||
|
if let Some(width) = item_width {
|
||||||
|
tree = tree.width(width);
|
||||||
|
}
|
||||||
|
|
||||||
|
trees.push(tree);
|
||||||
}
|
}
|
||||||
MenuItem::Folder(label, children) => {
|
MenuItemKind::Folder(label, children) => {
|
||||||
let l: Cow<'static, str> = label.into();
|
let l: Cow<'static, str> = label.into();
|
||||||
|
|
||||||
trees.push(MenuTree::<Message>::with_children(
|
let mut tree = MenuTree::<Message>::with_children(
|
||||||
RcElementWrapper::new(crate::Element::from(
|
RcElementWrapper::new(crate::Element::from(
|
||||||
menu_button::<'static, _>(vec![
|
menu_button::<'static, _>(vec![
|
||||||
widget::text(l.clone()).into(),
|
widget::text(l.clone()).into(),
|
||||||
|
|
@ -343,13 +399,25 @@ pub fn menu_items<
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
menu_items(key_binds, children),
|
menu_items(key_binds, children),
|
||||||
));
|
);
|
||||||
|
|
||||||
|
if let Some(width) = item_width {
|
||||||
|
tree = tree.width(width);
|
||||||
|
}
|
||||||
|
|
||||||
|
trees.push(tree);
|
||||||
}
|
}
|
||||||
MenuItem::Divider => {
|
MenuItemKind::Divider => {
|
||||||
if i != size - 1 {
|
if i != size - 1 {
|
||||||
trees.push(MenuTree::<Message>::from(Element::from(
|
let mut tree = MenuTree::<Message>::from(Element::from(
|
||||||
widget::divider::horizontal::light(),
|
widget::divider::horizontal::light(),
|
||||||
)));
|
));
|
||||||
|
|
||||||
|
if let Some(width) = item_width {
|
||||||
|
tree = tree.width(width);
|
||||||
|
}
|
||||||
|
|
||||||
|
trees.push(tree);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue