diff --git a/Cargo.toml b/Cargo.toml index f6a275f8..0c0fd341 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -51,7 +51,7 @@ default = [ "wrap", "selection_list", "split", - #"menu", + "menu", "quad", "context_menu", "spinner", @@ -108,7 +108,7 @@ members = [ "examples/selection_list", "examples/split", "examples/split_scroller", - #"examples/menu", + "examples/menu", "examples/spinner", "examples/context_menu" ] diff --git a/examples/menu/src/main.rs b/examples/menu/src/main.rs index d12c69e4..69178fd6 100644 --- a/examples/menu/src/main.rs +++ b/examples/menu/src/main.rs @@ -231,7 +231,7 @@ impl button::StyleSheet for ButtonStyle { fn active(&self, style: &Self::Style) -> button::Appearance { button::Appearance { text_color: style.extended_palette().background.base.text, - border_radius: 4.0, + border_radius: [4.0; 4].into(), background: Some(Color::TRANSPARENT.into()), ..Default::default() } @@ -323,7 +323,7 @@ fn debug_sub_menu<'a>( fn separator<'a>() -> MenuTree<'a, Message, iced::Renderer> { menu_tree!(quad::Quad { color: [0.5; 3].into(), - border_radius: 4.0.into(), + border_radius: [4.0; 4].into(), inner_bounds: quad::InnerBounds::Ratio(0.98, 0.1), ..Default::default() }) @@ -341,13 +341,13 @@ fn dot_separator<'a>() -> MenuTree<'a, Message, iced::Renderer> { fn labeled_separator(label: &'_ str) -> MenuTree<'_, Message, iced::Renderer> { let q_1 = quad::Quad { color: [0.5; 3].into(), - border_radius: 4.0.into(), + border_radius: [4.0; 4].into(), inner_bounds: quad::InnerBounds::Ratio(0.98, 0.1), ..Default::default() }; let q_2 = quad::Quad { color: [0.5; 3].into(), - border_radius: 4.0.into(), + border_radius: [4.0; 4].into(), inner_bounds: quad::InnerBounds::Ratio(0.98, 0.1), ..Default::default() }; @@ -367,7 +367,7 @@ fn circle(color: Color) -> quad::Quad { quad::Quad { color, inner_bounds: quad::InnerBounds::Square(radius * 2.0), - border_radius: radius.into(), + border_radius: [radius; 4].into(), ..Default::default() } } diff --git a/src/core/date.rs b/src/core/date.rs index bdb0ead7..0d422316 100644 --- a/src/core/date.rs +++ b/src/core/date.rs @@ -53,8 +53,9 @@ impl From for Date { } } +/// # Panics /// Creates a date with the previous month based on the given date. - +/// panics if year, month or day doesnt exist. #[must_use] pub fn pred_month(date: NaiveDate) -> NaiveDate { let (year, month) = if date.month() == 1 { @@ -68,8 +69,9 @@ pub fn pred_month(date: NaiveDate) -> NaiveDate { NaiveDate::from_ymd_opt(year, month, day).expect("Year, Month or Day doesnt Exist") } +/// # Panics /// Creates a date with the next month based on given date. - +/// panics if year, month or day doesnt exist. #[must_use] pub fn succ_month(date: NaiveDate) -> NaiveDate { let (year, month) = if date.month() == 12 { @@ -83,7 +85,9 @@ pub fn succ_month(date: NaiveDate) -> NaiveDate { NaiveDate::from_ymd_opt(year, month, day).expect("Year, Month or Day doesnt Exist") } +/// # Panics /// Creates a date with the previous year based on the given date. +// panics if year, month or day doesnt exist. #[must_use] pub fn pred_year(date: NaiveDate) -> NaiveDate { @@ -93,7 +97,9 @@ pub fn pred_year(date: NaiveDate) -> NaiveDate { NaiveDate::from_ymd_opt(year, date.month(), day).expect("Year, Month or Day doesnt Exist") } +/// # Panics /// Creates a date with the next year based on the given date. +// panics if year, month or day doesnt exist. #[must_use] pub fn succ_year(date: NaiveDate) -> NaiveDate { @@ -146,9 +152,10 @@ pub enum IsInMonth { Next, } +/// # Panics /// Calculates the day number at the given position in the calendar table based /// on the given year and month. - +/// panics if year, month or day does not exist. #[must_use] pub fn position_to_day(x: usize, y: usize, year: i32, month: u32) -> (usize, IsInMonth) { let (x, y) = (x as isize, y as isize); diff --git a/src/native/helpers.rs b/src/native/helpers.rs index a1409e0f..062d0840 100644 --- a/src/native/helpers.rs +++ b/src/native/helpers.rs @@ -84,7 +84,7 @@ pub fn menu_bar( menu_roots: Vec>, ) -> crate::menu::menu_bar::MenuBar where - Renderer: iced_native::Renderer, + Renderer: core::Renderer, Renderer::Theme: crate::style::menu_bar::StyleSheet, { crate::menu::menu_bar::MenuBar::new(menu_roots) @@ -98,7 +98,7 @@ pub fn menu_tree<'a, Message, Renderer>( children: Vec>>, ) -> crate::menu::menu_tree::MenuTree<'a, Message, Renderer> where - Renderer: iced_native::Renderer, + Renderer: core::Renderer, { crate::menu::menu_tree::MenuTree::with_children(item, children) } diff --git a/src/native/menu.rs b/src/native/menu.rs index 32442ca5..850461c9 100644 --- a/src/native/menu.rs +++ b/src/native/menu.rs @@ -59,9 +59,7 @@ pub mod menu_tree; pub use crate::style::menu_bar::{Appearance, StyleSheet}; /// A `MenuBar` collects `MenuTree`s and handles -pub type MenuBar<'a, Message, Backend, Theme> = - menu_bar::MenuBar<'a, Message, iced_graphics::Renderer>; +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, Backend, Theme> = - menu_tree::MenuTree<'a, Message, iced_graphics::Renderer>; +pub type MenuTree<'a, Message, Renderer> = menu_tree::MenuTree<'a, Message, Renderer>; diff --git a/src/native/menu/flex.rs b/src/native/menu/flex.rs index fe46e079..96dcf865 100644 --- a/src/native/menu/flex.rs +++ b/src/native/menu/flex.rs @@ -17,8 +17,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -use iced_native::layout::{Limits, Node}; -use iced_native::{renderer, Alignment, Element, Padding, Point, Size}; +use iced_widget::core::{ + layout::{Limits, Node}, + renderer, Alignment, Element, Padding, Point, Size, +}; /// The main axis of a flex layout. #[derive(Debug)] @@ -88,7 +90,7 @@ where if align_items == Alignment::Center { let mut fill_cross = axis.cross(limits.min()); - for child in items.iter() { + for child in items { let child = child.borrow(); let cross_fill_factor = match axis { Axis::Horizontal => child.as_widget().height(), diff --git a/src/native/menu/menu_bar.rs b/src/native/menu/menu_bar.rs index 19608735..806adbfb 100644 --- a/src/native/menu/menu_bar.rs +++ b/src/native/menu/menu_bar.rs @@ -5,15 +5,19 @@ use super::menu_inner::{ }; use super::menu_tree::MenuTree; use crate::style::menu_bar::StyleSheet; -use iced_native::widget::{tree, Tree}; -use iced_native::{ - event, layout, mouse, overlay, renderer, touch, Alignment, Clipboard, Color, Element, Length, - Padding, Point, Rectangle, Shell, Widget, + +use iced_widget::core::{ + event, + layout::{Limits, Node}, + mouse::{self, Cursor}, + overlay, renderer, touch, + widget::{tree, Tree}, + Alignment, Clipboard, Color, Element, Layout, Length, Padding, Rectangle, Shell, Widget, }; pub(super) struct MenuBarState { pub(super) pressed: bool, - pub(super) view_cursor: Point, + pub(super) view_cursor: Cursor, pub(super) open: bool, pub(super) active_root: Option, pub(super) horizontal_direction: Direction, @@ -38,7 +42,7 @@ impl Default for MenuBarState { fn default() -> Self { Self { pressed: false, - view_cursor: Point::new(-0.5, -0.5), + view_cursor: Cursor::Available([-0.5, -0.5].into()), open: false, active_root: None, horizontal_direction: Direction::Positive, @@ -51,7 +55,7 @@ impl Default for MenuBarState { /// A `MenuBar` collects `MenuTree`s and handles /// all the layout, event processing and drawing #[allow(missing_debug_implementations)] -pub struct MenuBar<'a, Message, Renderer> +pub struct MenuBar<'a, Message, Renderer = crate::Renderer> where Renderer: renderer::Renderer, Renderer::Theme: StyleSheet, @@ -247,7 +251,7 @@ where .collect() } - fn layout(&self, renderer: &Renderer, limits: &layout::Limits) -> layout::Node { + fn layout(&self, renderer: &Renderer, limits: &Limits) -> Node { use super::flex; let limits = limits.width(self.width).height(self.height); @@ -271,11 +275,12 @@ where &mut self, tree: &mut Tree, event: event::Event, - layout: layout::Layout<'_>, - view_cursor: Point, + layout: Layout<'_>, + view_cursor: Cursor, renderer: &Renderer, clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + viewport: &Rectangle, ) -> event::Status { use event::Event::{Mouse, Touch}; use mouse::{Button::Left, Event::ButtonReleased}; @@ -290,13 +295,14 @@ where renderer, clipboard, shell, + viewport, ); let state = tree.state.downcast_mut::(); match event { Mouse(ButtonReleased(Left)) | Touch(FingerLifted { .. } | FingerLost { .. }) => { - if state.menu_states.is_empty() && layout.bounds().contains(view_cursor) { + if state.menu_states.is_empty() && view_cursor.is_over(layout.bounds()) { state.view_cursor = view_cursor; state.open = true; } @@ -312,13 +318,13 @@ where renderer: &mut Renderer, theme: &::Theme, style: &renderer::Style, - layout: layout::Layout<'_>, - view_cursor: Point, + layout: Layout<'_>, + view_cursor: Cursor, viewport: &Rectangle, ) { let state = tree.state.downcast_ref::(); - - let position = if state.open && (view_cursor.x < 0.0 || view_cursor.y < 0.0) { + let cursor_pos = view_cursor.position().unwrap_or_default(); + let position = if state.open && (cursor_pos.x < 0.0 || cursor_pos.y < 0.0) { state.view_cursor } else { view_cursor @@ -364,7 +370,7 @@ where fn overlay<'b>( &'b mut self, tree: &'b mut Tree, - layout: layout::Layout<'_>, + layout: Layout<'_>, _renderer: &Renderer, ) -> Option> { let state = tree.state.downcast_ref::(); @@ -403,13 +409,14 @@ where #[allow(unused_results, clippy::too_many_arguments)] fn process_root_events( menu_roots: &mut [MenuTree<'_, Message, Renderer>], - view_cursor: Point, + view_cursor: Cursor, tree: &mut Tree, event: &event::Event, - layout: layout::Layout<'_>, + layout: Layout<'_>, renderer: &Renderer, clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, + viewport: &Rectangle, ) -> event::Status where Renderer: renderer::Renderer, @@ -428,6 +435,7 @@ where renderer, clipboard, shell, + viewport, ) }) .fold(event::Status::Ignored, event::Status::merge) diff --git a/src/native/menu/menu_inner.rs b/src/native/menu/menu_inner.rs index 78b7c6fe..807503cb 100644 --- a/src/native/menu/menu_inner.rs +++ b/src/native/menu/menu_inner.rs @@ -3,10 +3,14 @@ use super::menu_bar::MenuBarState; use super::menu_tree::MenuTree; use crate::style::menu_bar::StyleSheet; -use iced_native::widget::Tree; -use iced_native::{ - event, layout, mouse, overlay, renderer, touch, Clipboard, Color, Padding, Point, Rectangle, - Shell, Size, Vector, + +use iced_widget::core::{ + event, + layout::{Limits, Node}, + mouse::{self, Cursor}, + overlay, renderer, touch, + widget::Tree, + Clipboard, Color, Layout, Padding, Point, Rectangle, Shell, Size, Vector, }; /// The condition of when to close a menu @@ -259,7 +263,7 @@ impl MenuState { item_height: ItemHeight, renderer: &Renderer, menu_tree: &MenuTree<'_, Message, Renderer>, - ) -> layout::Node + ) -> Node where Renderer: renderer::Renderer, { @@ -293,7 +297,7 @@ impl MenuState { size.height = upper_bound_rel - position; } - let limits = layout::Limits::new(Size::ZERO, size); + let limits = Limits::new(Size::ZERO, size); let mut node = mt.item.as_widget().layout(renderer, &limits); node.move_to(Point::new(0.0, position + self.scroll_offset)); @@ -301,7 +305,7 @@ impl MenuState { }) .collect::>(); - let mut node = layout::Node::with_children(children_bounds.size(), child_nodes); + let mut node = Node::with_children(children_bounds.size(), child_nodes); node.move_to(children_bounds.position()); node } @@ -313,7 +317,7 @@ impl MenuState { item_height: ItemHeight, renderer: &Renderer, menu_tree: &MenuTree<'_, Message, Renderer>, - ) -> layout::Node + ) -> Node where Renderer: renderer::Renderer, { @@ -321,7 +325,7 @@ impl MenuState { let children_bounds = self.menu_bounds.children_bounds + overlay_offset; let position = self.menu_bounds.child_positions[index]; - let limits = layout::Limits::new( + let limits = Limits::new( Size::ZERO, get_item_size(menu_tree, children_bounds.width, item_height), ); @@ -421,16 +425,16 @@ where Renderer: renderer::Renderer, Renderer::Theme: StyleSheet, { - fn layout(&self, _renderer: &Renderer, bounds: Size, position: Point) -> layout::Node { + fn layout(&self, _renderer: &Renderer, bounds: Size, position: Point) -> Node { // overlay space viewport rectangle - layout::Node::new(bounds).translate(Point::ORIGIN - position) + Node::new(bounds).translate(Point::ORIGIN - position) } fn on_event( &mut self, event: event::Event, - layout: layout::Layout<'_>, - view_cursor: Point, + layout: Layout<'_>, + view_cursor: Cursor, renderer: &Renderer, clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, @@ -452,7 +456,7 @@ where let viewport = layout.bounds(); let viewport_size = viewport.size(); let overlay_offset = Point::ORIGIN - viewport.position(); - let overlay_cursor = view_cursor - overlay_offset; + let overlay_cursor = view_cursor.position().unwrap_or_default() - overlay_offset; let menu_status = process_menu_events( self.tree, @@ -488,8 +492,8 @@ where } Mouse(CursorMoved { position }) | Touch(FingerMoved { position, .. }) => { - let view_cursor = position; - let overlay_cursor = view_cursor - overlay_offset; + let view_cursor = Cursor::Available(position); + let overlay_cursor = view_cursor.position().unwrap_or_default() - overlay_offset; process_overlay_events( self, viewport_size, @@ -505,7 +509,13 @@ where state.pressed = false; // process close condition - if state.view_cursor.distance(view_cursor) < 2.0 { + if state + .view_cursor + .position() + .unwrap_or_default() + .distance(view_cursor.position().unwrap_or_default()) + < 2.0 + { let is_inside = state .menu_states .iter() @@ -541,8 +551,8 @@ where renderer: &mut Renderer, theme: &Renderer::Theme, style: &renderer::Style, - layout: layout::Layout<'_>, - view_cursor: Point, + layout: Layout<'_>, + view_cursor: Cursor, ) { let state = self.tree.state.downcast_ref::(); let Some(active_root) = state.active_root else { @@ -576,7 +586,7 @@ where let view_cursor = if i == state.menu_states.len() - 1 { view_cursor } else { - [-1.0; 2].into() + Cursor::Available([-1.0; 2].into()) }; let draw_menu = |r: &mut Renderer| { @@ -589,7 +599,7 @@ where // calc layout let children_node = ms.layout(overlay_offset, slice, self.item_height, r, menu_root); - let children_layout = layout::Layout::new(&children_node); + let children_layout = Layout::new(&children_node); let children_bounds = children_layout.bounds(); // draw menu background @@ -727,7 +737,7 @@ fn process_menu_events<'b, Message, Renderer>( menu_roots: &'b mut [MenuTree<'_, Message, Renderer>], item_height: ItemHeight, event: event::Event, - view_cursor: Point, + view_cursor: Cursor, renderer: &Renderer, clipboard: &mut dyn Clipboard, shell: &mut Shell<'_, Message>, @@ -763,7 +773,7 @@ where renderer, mt, ); - let child_layout = layout::Layout::new(&child_node); + let child_layout = Layout::new(&child_node); // widget tree let tree = &mut tree.children[active_root].children[mt.index]; @@ -777,6 +787,7 @@ where renderer, clipboard, shell, + &Rectangle::default(), ) } @@ -785,7 +796,7 @@ fn process_overlay_events( menu: &mut Menu<'_, '_, Message, Renderer>, viewport_size: Size, overlay_offset: Vector, - view_cursor: Point, + view_cursor: Cursor, overlay_cursor: Point, ) -> event::Status where diff --git a/src/native/menu/menu_tree.rs b/src/native/menu/menu_tree.rs index 6d6768f6..21f8be3a 100644 --- a/src/native/menu/menu_tree.rs +++ b/src/native/menu/menu_tree.rs @@ -1,7 +1,6 @@ //! A tree structure for constructing a hierarchical menu -use iced_native::{renderer, Element}; - +use iced_widget::core::{renderer, Element}; /// Nested menu is essentially a tree of items, a menu is a collection of items /// a menu itself can also be an item of another menu. /// @@ -11,7 +10,7 @@ use iced_native::{renderer, Element}; /// but there's no need to explicitly distinguish them here, if a menu tree /// has children, it's a menu, otherwise it's an item #[allow(missing_debug_implementations)] -pub struct MenuTree<'a, Message, Renderer> { +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,