Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Menu #209

Merged
merged 6 commits into from
Nov 16, 2023
Merged

Menu #209

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ path = "./iced/renderer"

[dependencies.iced_core]
path = "./iced/core"
features = ["serde"]

[dependencies.iced_widget]
path = "./iced/widget"
Expand Down
3 changes: 2 additions & 1 deletion cosmic-config/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ macro = ["cosmic-config-derive"]
subscription = ["iced_futures"]

[dependencies]
atomicwrites = "0.4.0"
# For redox support
atomicwrites = { git = "https://github.com/jackpot51/rust-atomicwrites" }
calloop = { version = "0.12.2", optional = true }
dirs = "5.0.1"
notify = "6.0.0"
Expand Down
15 changes: 15 additions & 0 deletions src/theme/style/button.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ pub enum Button {
Transparent,
AppletMenu,
AppletIcon,
MenuRoot,
MenuItem,
}

pub fn appearance(
Expand Down Expand Up @@ -120,6 +122,19 @@ pub fn appearance(
appearance.icon_color = Some(cosmic.background.on.into());
appearance.text_color = Some(cosmic.background.on.into());
}
Button::MenuRoot => {
appearance.background = None;
appearance.icon_color = Some(cosmic.accent.base.into());
appearance.text_color = Some(cosmic.accent.base.into());
}
Button::MenuItem => {
let (background, _, _) = color(&cosmic.background.component);
appearance.background = Some(Background::Color(background));

appearance.icon_color = Some(cosmic.background.on.into());
appearance.text_color = Some(cosmic.background.on.into());
corner_radii = &cosmic.corner_radii.radius_s;
}
}

appearance.border_radius = (*corner_radii).into();
Expand Down
80 changes: 80 additions & 0 deletions src/theme/style/menu_bar.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// From iced_aw, license MIT

//! Change the appearance of menu bars and their menus.
use crate::Theme;
use iced_widget::core::Color;

/// The appearance of a menu bar and its menus.
#[derive(Debug, Clone, Copy)]
pub struct Appearance {
/// The background color of the menu bar and its menus.
pub background: Color,
/// The border width of the menu bar and its menus.
pub border_width: f32,
/// The border radius of the menu bar.
pub bar_border_radius: [f32; 4],
/// The border radius of the menus.
pub menu_border_radius: [f32; 4],
/// The border [`Color`] of the menu bar and its menus.
pub border_color: Color,
/// The expand value of the menus' background
pub background_expand: [u16; 4],
/// The highlighted path [`Color`] of the the menu bar and its menus.
pub path: Color,
}

/// The style sheet of a menu bar and its menus.
pub trait StyleSheet {
/// The supported style of the [`StyleSheet`].
type Style: Default;

/// Produces the [`Appearance`] of a menu bar and its menus.
fn appearance(&self, style: &Self::Style) -> Appearance;
}

/// The style of a menu bar and its menus
#[derive(Default)]
#[allow(missing_debug_implementations)]
pub enum MenuBarStyle {
/// The default style.
#[default]
Default,
/// A [`Theme`] that uses a `Custom` palette.
Custom(Box<dyn StyleSheet<Style = Theme>>),
}

impl From<fn(&Theme) -> Appearance> for MenuBarStyle {
fn from(f: fn(&Theme) -> Appearance) -> Self {
Self::Custom(Box::new(f))
}
}

impl StyleSheet for fn(&Theme) -> Appearance {
type Style = Theme;

fn appearance(&self, style: &Self::Style) -> Appearance {
(self)(style)
}
}

impl StyleSheet for Theme {
type Style = MenuBarStyle;

fn appearance(&self, style: &Self::Style) -> Appearance {
let cosmic = self.cosmic();
let component = &cosmic.background.component;

match style {
MenuBarStyle::Default => Appearance {
background: component.base.into(),
border_width: 1.0,
bar_border_radius: cosmic.corner_radii.radius_xl,
menu_border_radius: cosmic.corner_radii.radius_s,
border_color: component.divider.into(),
background_expand: [1; 4],
path: component.hover.into(),
},
MenuBarStyle::Custom(c) => c.appearance(self),
}
}
}
2 changes: 2 additions & 0 deletions src/theme/style/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ pub use self::iced::Rule;
pub use self::iced::Svg;
pub use self::iced::Text;

pub mod menu_bar;

mod segmented_button;
pub use self::segmented_button::SegmentedButton;

Expand Down
67 changes: 67 additions & 0 deletions src/widget/menu.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// From iced_aw, license MIT

//! A [`MenuBar`] widget for displaying [`MenuTree`]s
//!
//! *This API requires the following crate features to be activated: `menu`*
//!
//! # Example
//!
//! ```ignore
//! use iced::widget::button;
//! use iced_aw::menu::{MenuTree, MenuBar};
//!
//! let sub_2 = MenuTree::with_children(
//! button("Sub Menu 2"),
//! vec![
//! MenuTree::new(button("item_1")),
//! MenuTree::new(button("item_2")),
//! MenuTree::new(button("item_3")),
//! ]
//! );
//!
//! let sub_1 = MenuTree::with_children(
//! button("Sub Menu 1"),
//! vec![
//! MenuTree::new(button("item_1")),
//! sub_2,
//! MenuTree::new(button("item_2")),
//! MenuTree::new(button("item_3")),
//! ]
//! );
//!
//!
//! let root_1 = MenuTree::with_children(
//! button("Menu 1"),
//! vec![
//! MenuTree::new(button("item_1")),
//! MenuTree::new(button("item_2")),
//! sub_1,
//! MenuTree::new(button("item_3")),
//! ]
//! );
//!
//! let root_2 = MenuTree::with_children(
//! button("Menu 2"),
//! vec![
//! MenuTree::new(button("item_1")),
//! MenuTree::new(button("item_2")),
//! MenuTree::new(button("item_3")),
//! ]
//! );
//!
//! let menu_bar = MenuBar::new(vec![root_1, root_2]);
//!
//! ```
//!

mod flex;
pub mod menu_bar;
mod menu_inner;
pub mod menu_tree;

pub use crate::style::menu_bar::{Appearance, StyleSheet};
/// A `MenuBar` collects `MenuTree`s and handles
pub type MenuBar<'a, Message, Renderer> = menu_bar::MenuBar<'a, Message, Renderer>;
pub use menu_inner::{CloseCondition, ItemHeight, ItemWidth, PathHighlight};
/// Nested menu is essentially a tree of items, a menu is a collection of items
pub type MenuTree<'a, Message, Renderer> = menu_tree::MenuTree<'a, Message, Renderer>;
Loading
Loading