wip
This commit is contained in:
parent
89700a2ed5
commit
4c03483e25
5 changed files with 210 additions and 154 deletions
|
|
@ -260,6 +260,7 @@ impl<Message: 'static + Clone> Widget<Message, crate::Theme, crate::Renderer>
|
||||||
is_overlay: true,
|
is_overlay: true,
|
||||||
window_id: window::Id::NONE,
|
window_id: window::Id::NONE,
|
||||||
depth: 0,
|
depth: 0,
|
||||||
|
on_surface_action: None,
|
||||||
}
|
}
|
||||||
.overlay(),
|
.overlay(),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// From iced_aw, license MIT
|
// From iced_aw, license MIT
|
||||||
|
|
||||||
//! A widget that handles menu trees
|
//! A widget that handles menu trees
|
||||||
use std::collections::HashMap;
|
use std::{collections::HashMap, sync::Arc};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
menu_inner::{
|
menu_inner::{
|
||||||
|
|
@ -12,6 +12,7 @@ use super::{
|
||||||
use crate::{
|
use crate::{
|
||||||
Renderer,
|
Renderer,
|
||||||
style::menu_bar::StyleSheet,
|
style::menu_bar::StyleSheet,
|
||||||
|
surface::action::destroy_popup,
|
||||||
widget::{
|
widget::{
|
||||||
RcWrapper,
|
RcWrapper,
|
||||||
dropdown::menu::{self, State},
|
dropdown::menu::{self, State},
|
||||||
|
|
@ -70,6 +71,7 @@ impl MenuBarStateInner {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn reset(&mut self) {
|
pub(super) fn reset(&mut self) {
|
||||||
|
dbg!("reset");
|
||||||
self.open = false;
|
self.open = false;
|
||||||
self.active_root = Vec::new();
|
self.active_root = Vec::new();
|
||||||
self.menu_states.clear();
|
self.menu_states.clear();
|
||||||
|
|
@ -192,7 +194,8 @@ pub struct MenuBar<Message> {
|
||||||
window_id: window::Id,
|
window_id: window::Id,
|
||||||
#[cfg(all(feature = "wayland", feature = "winit"))]
|
#[cfg(all(feature = "wayland", feature = "winit"))]
|
||||||
positioner: iced_runtime::platform_specific::wayland::popup::SctkPositioner,
|
positioner: iced_runtime::platform_specific::wayland::popup::SctkPositioner,
|
||||||
pub(crate) on_surface_action: Option<Box<dyn Fn(crate::surface::Action) -> Message>>,
|
pub(crate) on_surface_action:
|
||||||
|
Option<Arc<dyn Fn(crate::surface::Action) -> Message + Send + Sync + 'static>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Message> MenuBar<Message>
|
impl<Message> MenuBar<Message>
|
||||||
|
|
@ -348,9 +351,9 @@ where
|
||||||
|
|
||||||
pub fn on_surface_action(
|
pub fn on_surface_action(
|
||||||
mut self,
|
mut self,
|
||||||
handler: impl Fn(crate::surface::Action) -> Message + 'static,
|
handler: impl Fn(crate::surface::Action) -> Message + Send + Sync + 'static,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
self.on_surface_action = Some(Box::new(handler));
|
self.on_surface_action = Some(Arc::new(handler));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -420,9 +423,10 @@ where
|
||||||
shell: &mut Shell<'_, Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
viewport: &Rectangle,
|
viewport: &Rectangle,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
use event::Event::{Mouse, Touch};
|
use event::Event::{Mouse, Touch, Window};
|
||||||
use mouse::{Button::Left, Event::ButtonReleased};
|
use mouse::{Button::Left, Event::ButtonReleased};
|
||||||
use touch::Event::{FingerLifted, FingerLost};
|
use touch::Event::{FingerLifted, FingerLost};
|
||||||
|
use window::Event::Focused;
|
||||||
|
|
||||||
let root_status = process_root_events(
|
let root_status = process_root_events(
|
||||||
&mut self.menu_roots,
|
&mut self.menu_roots,
|
||||||
|
|
@ -439,12 +443,16 @@ where
|
||||||
let my_state = tree.state.downcast_mut::<MenuBarState>();
|
let my_state = tree.state.downcast_mut::<MenuBarState>();
|
||||||
|
|
||||||
// XXX this should reset the state if there are no other copies of the state, which implies no dropdown menus open.
|
// XXX this should reset the state if there are no other copies of the state, which implies no dropdown menus open.
|
||||||
let reset = self.window_id != window::Id::NONE && my_state.inner.with_data(|d| d.open);
|
let reset = self.window_id != window::Id::NONE
|
||||||
|
&& my_state
|
||||||
|
.inner
|
||||||
|
.with_data(|d| !d.open && !d.active_root.is_empty());
|
||||||
|
|
||||||
my_state.inner.with_data_mut(|state| {
|
my_state.inner.with_data_mut(|state| {
|
||||||
if reset {
|
if reset {
|
||||||
if let Some(popup_id) = state.popup_id.get(&self.window_id).copied() {
|
if let Some(popup_id) = state.popup_id.get(&self.window_id).copied() {
|
||||||
dbg!("reset destroy");
|
dbg!("reset destroy");
|
||||||
|
|
||||||
if let Some(handler) = self.on_surface_action.as_ref() {
|
if let Some(handler) = self.on_surface_action.as_ref() {
|
||||||
shell.publish((handler)(crate::surface::Action::DestroyPopup(popup_id)));
|
shell.publish((handler)(crate::surface::Action::DestroyPopup(popup_id)));
|
||||||
state.reset();
|
state.reset();
|
||||||
|
|
@ -457,13 +465,29 @@ where
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
Mouse(ButtonReleased(Left)) | Touch(FingerLifted { .. } | FingerLost { .. }) => {
|
Mouse(ButtonReleased(Left)) | Touch(FingerLifted { .. } | FingerLost { .. }) => {
|
||||||
my_state.inner.with_data_mut(|state| {
|
let create_popup = my_state.inner.with_data_mut(|state| {
|
||||||
|
let mut create_popup = false;
|
||||||
if state.menu_states.is_empty() && view_cursor.is_over(layout.bounds()) {
|
if state.menu_states.is_empty() && view_cursor.is_over(layout.bounds()) {
|
||||||
state.view_cursor = view_cursor;
|
state.view_cursor = view_cursor;
|
||||||
|
dbg!(view_cursor.is_over(layout.bounds()));
|
||||||
state.open = true;
|
state.open = true;
|
||||||
|
create_popup = true;
|
||||||
|
} else if let Some(id) = state.popup_id.remove(&self.window_id) {
|
||||||
|
dbg!("destroy popup...");
|
||||||
|
state.menu_states.clear();
|
||||||
|
state.active_root.clear();
|
||||||
|
let surface_action = self.on_surface_action.as_ref().unwrap();
|
||||||
|
state.open = false;
|
||||||
|
shell.publish(surface_action(destroy_popup(id)));
|
||||||
|
state.view_cursor = view_cursor;
|
||||||
}
|
}
|
||||||
|
create_popup
|
||||||
});
|
});
|
||||||
#[cfg(all(feature = "wayland", feature = "winit"))]
|
dbg!(create_popup);
|
||||||
|
if !create_popup {
|
||||||
|
return root_status;
|
||||||
|
}
|
||||||
|
#[cfg(all(feature = "wayland", feature = "winit", feature = "surface-message"))]
|
||||||
|
|
||||||
dbg!(
|
dbg!(
|
||||||
self.window_id != window::Id::NONE,
|
self.window_id != window::Id::NONE,
|
||||||
|
|
@ -533,6 +557,7 @@ where
|
||||||
is_overlay: false,
|
is_overlay: false,
|
||||||
window_id: id,
|
window_id: id,
|
||||||
depth: 0,
|
depth: 0,
|
||||||
|
on_surface_action: self.on_surface_action.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
init_root_menu(
|
init_root_menu(
|
||||||
|
|
@ -545,7 +570,8 @@ where
|
||||||
layout.bounds(),
|
layout.bounds(),
|
||||||
self.main_offset as f32,
|
self.main_offset as f32,
|
||||||
);
|
);
|
||||||
let anchor_rect = my_state.inner.with_data(|state| {
|
let anchor_rect = my_state.inner.with_data_mut(|state| {
|
||||||
|
state.popup_id.insert(self.window_id, id);
|
||||||
state.menu_states[0]
|
state.menu_states[0]
|
||||||
.iter()
|
.iter()
|
||||||
.find(|s| s.index.is_none())
|
.find(|s| s.index.is_none())
|
||||||
|
|
@ -601,11 +627,15 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Window(Focused) => {
|
// Window(Focused) => {
|
||||||
// if let Some(popup_id) = state.popup_id.get(&self.window_id).copied() {
|
// my_state.inner.with_data_mut(|state| {
|
||||||
// dbg!("window focused");
|
// if let Some(popup_id) = state.popup_id.get(&self.window_id).copied() {
|
||||||
// shell.publish(Message::from(SurfaceMessage::DestroyPopup(popup_id)));
|
// dbg!("window focused");
|
||||||
// }
|
// if let Some(handler) = self.on_surface_action.as_ref() {
|
||||||
// state.reset();
|
// shell.publish((handler)(destroy_popup(popup_id)));
|
||||||
|
// state.reset();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
// }
|
// }
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
|
|
@ -635,7 +665,11 @@ where
|
||||||
// draw path highlight
|
// draw path highlight
|
||||||
if self.path_highlight.is_some() {
|
if self.path_highlight.is_some() {
|
||||||
let styling = theme.appearance(&self.style);
|
let styling = theme.appearance(&self.style);
|
||||||
if let Some(active) = get_mut_or_default(&mut state.active_root, 0).get(0) {
|
if let Some(active) = state
|
||||||
|
.active_root
|
||||||
|
.get(0)
|
||||||
|
.and_then(|active_root| active_root.get(0))
|
||||||
|
{
|
||||||
let active_bounds = layout
|
let active_bounds = layout
|
||||||
.children()
|
.children()
|
||||||
.nth(*active)
|
.nth(*active)
|
||||||
|
|
@ -679,13 +713,13 @@ where
|
||||||
_renderer: &Renderer,
|
_renderer: &Renderer,
|
||||||
translation: Vector,
|
translation: Vector,
|
||||||
) -> Option<overlay::Element<'b, Message, crate::Theme, Renderer>> {
|
) -> Option<overlay::Element<'b, Message, crate::Theme, Renderer>> {
|
||||||
#[cfg(all(feature = "wayland", feature = "winit"))]
|
// #[cfg(all(feature = "wayland", feature = "winit"))]
|
||||||
return None;
|
return None;
|
||||||
|
|
||||||
let state = tree.state.downcast_ref::<MenuBarState>();
|
let state = tree.state.downcast_ref::<MenuBarState>();
|
||||||
if state
|
if state
|
||||||
.inner
|
.inner
|
||||||
.with_data_mut(|state| !state.open || state.active_root.is_empty())
|
.with_data(|state| !state.open || state.active_root.is_empty())
|
||||||
{
|
{
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
|
|
@ -709,6 +743,7 @@ where
|
||||||
is_overlay: true,
|
is_overlay: true,
|
||||||
window_id: window::Id::NONE,
|
window_id: window::Id::NONE,
|
||||||
depth: 0,
|
depth: 0,
|
||||||
|
on_surface_action: self.on_surface_action.clone(),
|
||||||
}
|
}
|
||||||
.overlay(),
|
.overlay(),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
// From iced_aw, license MIT
|
// From iced_aw, license MIT
|
||||||
|
|
||||||
//! Menu tree overlay
|
//! Menu tree overlay
|
||||||
use std::borrow::Cow;
|
use std::{borrow::Cow, sync::Arc};
|
||||||
|
|
||||||
use super::{menu_bar::MenuBarState, menu_tree::MenuTree};
|
use super::{menu_bar::MenuBarState, menu_tree::MenuTree};
|
||||||
use crate::style::menu_bar::StyleSheet;
|
use crate::style::menu_bar::StyleSheet;
|
||||||
|
|
@ -466,6 +466,8 @@ pub(crate) struct Menu<'b, Message: std::clone::Clone> {
|
||||||
/// window id for this popup
|
/// window id for this popup
|
||||||
pub(crate) window_id: window::Id,
|
pub(crate) window_id: window::Id,
|
||||||
pub(crate) depth: usize,
|
pub(crate) depth: usize,
|
||||||
|
pub(crate) on_surface_action:
|
||||||
|
Option<Arc<dyn Fn(crate::surface::Action) -> Message + Send + Sync + 'static>>,
|
||||||
}
|
}
|
||||||
impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
pub(crate) fn overlay(self) -> overlay::Element<'b, Message, crate::Theme, crate::Renderer> {
|
pub(crate) fn overlay(self) -> overlay::Element<'b, Message, crate::Theme, crate::Renderer> {
|
||||||
|
|
@ -473,6 +475,7 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn layout(&self, renderer: &crate::Renderer, limits: Limits) -> Node {
|
pub(crate) fn layout(&self, renderer: &crate::Renderer, limits: Limits) -> Node {
|
||||||
|
dbg!("layout");
|
||||||
// layout children;
|
// layout children;
|
||||||
let position = self.position;
|
let position = self.position;
|
||||||
let mut intrinsic_size = Size::ZERO;
|
let mut intrinsic_size = Size::ZERO;
|
||||||
|
|
@ -480,6 +483,8 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
dbg!(self.depth);
|
dbg!(self.depth);
|
||||||
let empty = Vec::new();
|
let empty = Vec::new();
|
||||||
self.tree.inner.with_data_mut(|data| {
|
self.tree.inner.with_data_mut(|data| {
|
||||||
|
dbg!(data.active_root.len());
|
||||||
|
|
||||||
let overlay_offset = Point::ORIGIN - position;
|
let overlay_offset = Point::ORIGIN - position;
|
||||||
let tree_children = &mut data.tree.children;
|
let tree_children = &mut data.tree.children;
|
||||||
dbg!(&data.active_root,);
|
dbg!(&data.active_root,);
|
||||||
|
|
@ -557,11 +562,12 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
// dbg!(intrinsic_size);
|
// dbg!(intrinsic_size);
|
||||||
// overlay space viewport rectangle
|
// overlay space viewport rectangle
|
||||||
Node::with_children(
|
let node = Node::with_children(
|
||||||
limits.resolve(Length::Shrink, Length::Shrink, intrinsic_size),
|
limits.resolve(Length::Shrink, Length::Shrink, intrinsic_size),
|
||||||
children,
|
children,
|
||||||
)
|
)
|
||||||
.translate(Point::ORIGIN - position)
|
.translate(Point::ORIGIN - position);
|
||||||
|
node
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -574,6 +580,7 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
clipboard: &mut dyn Clipboard,
|
clipboard: &mut dyn Clipboard,
|
||||||
shell: &mut Shell<'_, Message>,
|
shell: &mut Shell<'_, Message>,
|
||||||
) -> (Option<(usize, MenuState)>, event::Status) {
|
) -> (Option<(usize, MenuState)>, event::Status) {
|
||||||
|
// dbg!("on event");
|
||||||
use event::{
|
use event::{
|
||||||
Event::{Mouse, Touch},
|
Event::{Mouse, Touch},
|
||||||
Status::{Captured, Ignored},
|
Status::{Captured, Ignored},
|
||||||
|
|
@ -606,7 +613,6 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
overlay_offset,
|
overlay_offset,
|
||||||
);
|
);
|
||||||
|
|
||||||
dbg!("init_root_menu");
|
|
||||||
init_root_menu(
|
init_root_menu(
|
||||||
self,
|
self,
|
||||||
renderer,
|
renderer,
|
||||||
|
|
@ -650,6 +656,8 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
self.cross_offset as f32,
|
self.cross_offset as f32,
|
||||||
self.is_overlay,
|
self.is_overlay,
|
||||||
);
|
);
|
||||||
|
dbg!(new_root.as_ref().map(|r| r.0));
|
||||||
|
|
||||||
return (new_root, status.merge(menu_status));
|
return (new_root, status.merge(menu_status));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -668,19 +676,24 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
let is_inside = state.menu_states[self.depth]
|
let is_inside = state.menu_states[self.depth]
|
||||||
.iter()
|
.iter()
|
||||||
.any(|ms| ms.menu_bounds.check_bounds.contains(overlay_cursor));
|
.any(|ms| ms.menu_bounds.check_bounds.contains(overlay_cursor));
|
||||||
|
let mut needs_reset = false;
|
||||||
if self.close_condition.click_inside
|
needs_reset |= self.close_condition.click_inside
|
||||||
&& is_inside
|
&& is_inside
|
||||||
&& matches!(
|
&& matches!(
|
||||||
event,
|
event,
|
||||||
Mouse(ButtonReleased(Left)) | Touch(FingerLifted { .. })
|
Mouse(ButtonReleased(Left)) | Touch(FingerLifted { .. })
|
||||||
)
|
);
|
||||||
{
|
|
||||||
state.reset();
|
needs_reset |= self.close_condition.click_outside && !is_inside;
|
||||||
return Captured;
|
|
||||||
}
|
if needs_reset {
|
||||||
|
dbg!("reset");
|
||||||
|
if let Some(handler) = self.on_surface_action.as_ref() {
|
||||||
|
shell.publish((handler)(crate::surface::Action::DestroyPopup(
|
||||||
|
self.window_id,
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
if self.close_condition.click_outside && !is_inside {
|
|
||||||
state.reset();
|
state.reset();
|
||||||
return Captured;
|
return Captured;
|
||||||
}
|
}
|
||||||
|
|
@ -711,11 +724,12 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
view_cursor: Cursor,
|
view_cursor: Cursor,
|
||||||
) {
|
) {
|
||||||
self.tree.inner.with_data(|state| {
|
self.tree.inner.with_data(|state| {
|
||||||
|
if !state.open {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let Some(active_root) = state.active_root.get(self.depth) else {
|
let Some(active_root) = state.active_root.get(self.depth) else {
|
||||||
// dbg!(self.window_id);
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
dbg!(active_root);
|
|
||||||
let viewport = layout.bounds();
|
let viewport = layout.bounds();
|
||||||
let viewport_size = viewport.size();
|
let viewport_size = viewport.size();
|
||||||
let overlay_offset = Point::ORIGIN - viewport.position();
|
let overlay_offset = Point::ORIGIN - viewport.position();
|
||||||
|
|
@ -725,7 +739,6 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
} else {
|
} else {
|
||||||
Rectangle::new(Point::ORIGIN, Size::INFINITY)
|
Rectangle::new(Point::ORIGIN, Size::INFINITY)
|
||||||
};
|
};
|
||||||
// dbg!(self.window_id, &active_root);
|
|
||||||
|
|
||||||
let styling = theme.appearance(&self.style);
|
let styling = theme.appearance(&self.style);
|
||||||
let (active_tree, roots) = active_root.iter().take(self.depth).fold(
|
let (active_tree, roots) = active_root.iter().take(self.depth).fold(
|
||||||
|
|
@ -736,24 +749,8 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
|(tree, mt), next_active_root| (tree, &mt[*next_active_root].children),
|
|(tree, mt), next_active_root| (tree, &mt[*next_active_root].children),
|
||||||
);
|
);
|
||||||
|
|
||||||
dbg!(
|
|
||||||
state.tree.children.len(),
|
|
||||||
state.tree.children[active_root[0]].children.len()
|
|
||||||
);
|
|
||||||
// let tree = &state.tree.children[active_root].children;
|
|
||||||
// let root = &self.menu_roots[active_root];
|
|
||||||
dbg!(&active_root.len());
|
|
||||||
|
|
||||||
let indices = state.get_trimmed_indices(self.depth).collect::<Vec<_>>();
|
let indices = state.get_trimmed_indices(self.depth).collect::<Vec<_>>();
|
||||||
dbg!(self.depth);
|
|
||||||
|
|
||||||
dbg!(
|
|
||||||
self.window_id,
|
|
||||||
state.menu_states.len(),
|
|
||||||
state.menu_states[self.depth].len(),
|
|
||||||
layout.children().count(),
|
|
||||||
layout.bounds()
|
|
||||||
);
|
|
||||||
state.menu_states[self.depth]
|
state.menu_states[self.depth]
|
||||||
.iter()
|
.iter()
|
||||||
.zip(layout.children())
|
.zip(layout.children())
|
||||||
|
|
@ -822,7 +819,7 @@ impl<'b, Message: Clone + 'static> Menu<'b, Message> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if start_index < menu_roots.len() {
|
if start_index < menu_roots.len() {
|
||||||
dbg!(start_index, end_index, menu_roots.len());
|
// dbg!(start_index, end_index, menu_roots.len());
|
||||||
// draw item
|
// draw item
|
||||||
menu_roots[start_index..=end_index]
|
menu_roots[start_index..=end_index]
|
||||||
.iter()
|
.iter()
|
||||||
|
|
@ -906,7 +903,7 @@ impl<'a, Message: std::clone::Clone + 'static> Widget<Message, crate::Theme, cra
|
||||||
renderer: &crate::Renderer,
|
renderer: &crate::Renderer,
|
||||||
limits: &iced_core::layout::Limits,
|
limits: &iced_core::layout::Limits,
|
||||||
) -> iced_core::layout::Node {
|
) -> iced_core::layout::Node {
|
||||||
// dbg!(self.window_id, limits);
|
// dbg!("layout", self.window_id, limits);
|
||||||
Menu::layout(self, renderer, *limits)
|
Menu::layout(self, renderer, *limits)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -935,70 +932,84 @@ impl<'a, Message: std::clone::Clone + 'static> Widget<Message, crate::Theme, cra
|
||||||
_viewport: &Rectangle,
|
_viewport: &Rectangle,
|
||||||
) -> event::Status {
|
) -> event::Status {
|
||||||
let (new_root, status) = self.on_event(event, layout, cursor, renderer, clipboard, shell);
|
let (new_root, status) = self.on_event(event, layout, cursor, renderer, clipboard, shell);
|
||||||
// #[cfg(feature = "wayland")]
|
dbg!(new_root.as_ref().map(|r| r.0));
|
||||||
|
// #[cfg(all(feature = "wayland", feature = "surface-message"))]
|
||||||
// if let Some((new_root, new_ms)) = new_root {
|
// if let Some((new_root, new_ms)) = new_root {
|
||||||
// use iced_runtime::platform_specific::wayland::popup::{
|
// use iced_runtime::platform_specific::wayland::popup::{
|
||||||
// SctkPopupSettings, SctkPositioner,
|
// SctkPopupSettings, SctkPositioner,
|
||||||
// };
|
// };
|
||||||
// let mut guard = self.tree.inner.lock().unwrap();
|
// dbg!(new_root);
|
||||||
// let popup_id = *guard
|
// let Some((mut menu, popup_id)) = self.tree.inner.with_data_mut(|state| {
|
||||||
// .popup_id
|
// let popup_id = *state
|
||||||
// .entry(self.window_id)
|
// .popup_id
|
||||||
// .or_insert_with(window::Id::unique);
|
// .entry(self.window_id)
|
||||||
// let active_roots = &guard.active_root[&self.window_id];
|
// .or_insert_with(window::Id::unique);
|
||||||
// // dbg!(active_roots);
|
// let active_roots = state
|
||||||
// let root_bounds_list = active_roots
|
// .active_root
|
||||||
// .into_iter()
|
// .get(self.depth)
|
||||||
// .fold(layout, |l, active_root| {
|
// .cloned()
|
||||||
// // dbg!(active_root);
|
// .unwrap_or_default(); // dbg!(active_roots);
|
||||||
// l.children().nth(*active_root).unwrap()
|
// // let root_bounds_list = active_roots
|
||||||
// })
|
// // .into_iter()
|
||||||
// .children()
|
// // .fold(layout, |l, active_root| {
|
||||||
// .map(|c| c.bounds())
|
// // // dbg!(active_root);
|
||||||
// .collect();
|
// // l.children().nth(active_root).unwrap()
|
||||||
// drop(guard);
|
// // })
|
||||||
|
// // .children()
|
||||||
|
// // .map(|c| c.bounds())
|
||||||
|
// // .collect();
|
||||||
|
// let root_bounds_list = layout.children().map(|lo| lo.bounds()).collect();
|
||||||
|
// // drop(state);
|
||||||
|
|
||||||
// // dbg!(&root_bounds_list);
|
// // dbg!(&root_bounds_list);
|
||||||
// // dbg!(self.menu_roots.clone().len());
|
// // dbg!(self.menu_roots.clone().len());
|
||||||
// // dbg!(self
|
// // dbg!(self
|
||||||
// // .menu_roots
|
// // .menu_roots
|
||||||
// // .clone()
|
// // .clone()
|
||||||
// // .iter()
|
// // .iter()
|
||||||
// // .map(|r| r.index)
|
// // .map(|r| r.index)
|
||||||
// // .collect::<Vec<_>>());
|
// // .collect::<Vec<_>>());
|
||||||
// let mut popup_menu = Menu {
|
// let mut popup_menu = Menu {
|
||||||
// tree: self.tree.clone(),
|
// tree: self.tree.clone(),
|
||||||
// menu_roots: Cow::Owned(Cow::into_owned(self.menu_roots.clone())),
|
// menu_roots: Cow::Owned(Cow::into_owned(self.menu_roots.clone())),
|
||||||
// bounds_expand: self.bounds_expand,
|
// bounds_expand: self.bounds_expand,
|
||||||
// menu_overlays_parent: false,
|
// menu_overlays_parent: false,
|
||||||
// close_condition: self.close_condition,
|
// close_condition: self.close_condition,
|
||||||
// item_width: self.item_width,
|
// item_width: self.item_width,
|
||||||
// item_height: self.item_height,
|
// item_height: self.item_height,
|
||||||
// bar_bounds: layout.bounds(),
|
// bar_bounds: layout.bounds(),
|
||||||
// main_offset: self.main_offset,
|
// main_offset: self.main_offset,
|
||||||
// cross_offset: self.cross_offset,
|
// cross_offset: self.cross_offset,
|
||||||
// root_bounds_list,
|
// root_bounds_list,
|
||||||
// path_highlight: self.path_highlight,
|
// path_highlight: self.path_highlight,
|
||||||
// style: Cow::Owned(Cow::into_owned(self.style.clone())),
|
// style: Cow::Owned(Cow::into_owned(self.style.clone())),
|
||||||
// position: Point::new(0., 0.),
|
// position: Point::new(0., 0.),
|
||||||
// is_overlay: false,
|
// is_overlay: false,
|
||||||
// window_id: popup_id,
|
// window_id: popup_id,
|
||||||
// depth: self.depth + 1,
|
// depth: self.depth + 1,
|
||||||
// };
|
// on_surface_action: self.on_surface_action.clone(),
|
||||||
// let mut guard = self.tree.inner.lock().unwrap();
|
// };
|
||||||
// // dbg!(guard.menu_states.keys());
|
// // let mut state = self.tree.inner.lock().unwrap();
|
||||||
// let Some(parent_root) = guard.active_root.get(&self.window_id) else {
|
// // dbg!(state.menu_states.keys());
|
||||||
// // TODO log warning
|
// // let Some(parent_root) = state.active_root.get(&self.window_id) else {
|
||||||
|
// // // TODO log warning
|
||||||
|
// // return status;
|
||||||
|
// // };
|
||||||
|
// let Some(parent_root) = state.active_root.get(self.depth).cloned() else {
|
||||||
|
// return None;
|
||||||
|
// };
|
||||||
|
// let mut roots = parent_root.clone();
|
||||||
|
// roots.push(new_root);
|
||||||
|
// // dbg!(&roots);
|
||||||
|
// state.active_root.push(roots);
|
||||||
|
// // _ = state.menu_states.remove(&popup_id);
|
||||||
|
// // drop(state);
|
||||||
|
// Some((popup_menu, popup_id))
|
||||||
|
// }) else {
|
||||||
// return status;
|
// return status;
|
||||||
// };
|
// };
|
||||||
// let mut roots = parent_root.clone();
|
|
||||||
// roots.push(new_root);
|
|
||||||
// // dbg!(&roots);
|
|
||||||
// guard.active_root.insert(popup_id, roots);
|
|
||||||
// _ = guard.menu_states.remove(&popup_id);
|
|
||||||
// drop(guard);
|
|
||||||
// init_root_popup_menu(
|
// init_root_popup_menu(
|
||||||
// &mut popup_menu,
|
// &mut menu,
|
||||||
// renderer,
|
// renderer,
|
||||||
// shell,
|
// shell,
|
||||||
// cursor.position().unwrap(),
|
// cursor.position().unwrap(),
|
||||||
|
|
@ -1007,40 +1018,38 @@ impl<'a, Message: std::clone::Clone + 'static> Widget<Message, crate::Theme, cra
|
||||||
// layout.bounds(),
|
// layout.bounds(),
|
||||||
// self.main_offset as f32,
|
// self.main_offset as f32,
|
||||||
// );
|
// );
|
||||||
// let mut guard = self.tree.inner.lock().unwrap();
|
// let anchor_rect = self.tree.inner.with_data_mut(|state| {
|
||||||
|
// // let mut state = self.tree.inner.lock().unwrap();
|
||||||
|
// state.menu_states.get_mut(self.depth).unwrap().push(new_ms);
|
||||||
|
|
||||||
// guard
|
// state.menu_states[self.depth]
|
||||||
// .menu_states
|
// .iter()
|
||||||
// .get_mut(&self.window_id)
|
// .find(|s| s.index.is_none())
|
||||||
// .unwrap()
|
// .map(|s| s.menu_bounds.parent_bounds)
|
||||||
// .push(new_ms);
|
// .map_or_else(
|
||||||
|
// || {
|
||||||
|
// let bounds = layout.bounds();
|
||||||
|
// Rectangle {
|
||||||
|
// x: bounds.x as i32,
|
||||||
|
// y: bounds.y as i32,
|
||||||
|
// width: bounds.width as i32,
|
||||||
|
// height: bounds.height as i32,
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// |r| Rectangle {
|
||||||
|
// x: r.x as i32,
|
||||||
|
// y: r.y as i32,
|
||||||
|
// width: r.width as i32,
|
||||||
|
// height: r.height as i32,
|
||||||
|
// },
|
||||||
|
// )
|
||||||
|
// });
|
||||||
|
|
||||||
// let anchor_rect = guard.menu_states[&self.window_id]
|
|
||||||
// .iter()
|
|
||||||
// .find(|s| s.index.is_none())
|
|
||||||
// .map(|s| s.menu_bounds.parent_bounds)
|
|
||||||
// .map_or_else(
|
|
||||||
// || {
|
|
||||||
// let bounds = layout.bounds();
|
|
||||||
// Rectangle {
|
|
||||||
// x: bounds.x as i32,
|
|
||||||
// y: bounds.y as i32,
|
|
||||||
// width: bounds.width as i32,
|
|
||||||
// height: bounds.height as i32,
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// |r| Rectangle {
|
|
||||||
// x: r.x as i32,
|
|
||||||
// y: r.y as i32,
|
|
||||||
// width: r.width as i32,
|
|
||||||
// height: r.height as i32,
|
|
||||||
// },
|
|
||||||
// );
|
|
||||||
// // dbg!(&anchor_rect);
|
// // dbg!(&anchor_rect);
|
||||||
|
|
||||||
// drop(guard);
|
// // drop(state);
|
||||||
// let menu_node = Widget::layout(
|
// let menu_node = Widget::layout(
|
||||||
// &popup_menu,
|
// &menu,
|
||||||
// &mut Tree::empty(),
|
// &mut Tree::empty(),
|
||||||
// renderer,
|
// renderer,
|
||||||
// &Limits::NONE.min_width(1.).min_height(1.),
|
// &Limits::NONE.min_width(1.).min_height(1.),
|
||||||
|
|
@ -1051,16 +1060,16 @@ impl<'a, Message: std::clone::Clone + 'static> Widget<Message, crate::Theme, cra
|
||||||
|
|
||||||
// let popup_size = menu_node.size();
|
// let popup_size = menu_node.size();
|
||||||
// let positioner = SctkPositioner {
|
// let positioner = SctkPositioner {
|
||||||
// size: Some((popup_size.width.ceil() as u32 + 2, popup_size.height.ceil() as u32 + 2)),
|
// size: Some((popup_size.width.ceil() as u32 + 2, popup_size.height.ceil() as u32 + 2)),
|
||||||
// anchor_rect,
|
// anchor_rect,
|
||||||
// anchor: cctk::wayland_protocols::xdg::shell::client::xdg_positioner::Anchor::TopRight,
|
// anchor: cctk::wayland_protocols::xdg::shell::client::xdg_positioner::Anchor::TopRight,
|
||||||
// gravity:cctk::wayland_protocols::xdg::shell::client::xdg_positioner::Gravity::BottomRight,
|
// gravity:cctk::wayland_protocols::xdg::shell::client::xdg_positioner::Gravity::BottomRight,
|
||||||
// reactive: true,
|
// reactive: true,
|
||||||
// ..Default::default()
|
// ..Default::default()
|
||||||
// };
|
// };
|
||||||
// let parent = self.window_id;
|
// let parent = self.window_id;
|
||||||
// // dbg!(&positioner);
|
// // dbg!(&positioner);
|
||||||
// shell.publish(crate::app::message::simple_popup(
|
// (self.on_surface_action.as_ref().unwrap())(crate::surface::action::simple_popup(
|
||||||
// move || SctkPopupSettings {
|
// move || SctkPopupSettings {
|
||||||
// parent,
|
// parent,
|
||||||
// id: popup_id,
|
// id: popup_id,
|
||||||
|
|
@ -1068,14 +1077,17 @@ impl<'a, Message: std::clone::Clone + 'static> Widget<Message, crate::Theme, cra
|
||||||
// parent_size: None,
|
// parent_size: None,
|
||||||
// grab: true,
|
// grab: true,
|
||||||
// close_with_children: true,
|
// close_with_children: true,
|
||||||
|
// input_zone: todo!(),
|
||||||
// },
|
// },
|
||||||
// Some(move || {
|
// Some(move || {
|
||||||
// crate::Element::from(
|
// crate::Element::from(
|
||||||
// crate::widget::container(popup_menu.clone()).center(Length::Fill),
|
// crate::widget::container(menu.clone()).center(Length::Fill),
|
||||||
// )
|
// )
|
||||||
// .map(crate::app::Message::App)
|
// .map(crate::action::app)
|
||||||
// }),
|
// }),
|
||||||
// ));
|
// ));
|
||||||
|
|
||||||
|
// return status;
|
||||||
// }
|
// }
|
||||||
status
|
status
|
||||||
}
|
}
|
||||||
|
|
@ -1259,6 +1271,7 @@ pub(super) fn init_root_popup_menu<Message>(
|
||||||
) where
|
) where
|
||||||
Message: std::clone::Clone,
|
Message: std::clone::Clone,
|
||||||
{
|
{
|
||||||
|
dbg!("init");
|
||||||
menu.tree.inner.with_data_mut(|state| {
|
menu.tree.inner.with_data_mut(|state| {
|
||||||
if !(state
|
if !(state
|
||||||
.menu_states
|
.menu_states
|
||||||
|
|
@ -1396,11 +1409,9 @@ fn process_menu_events<'b, Message: std::clone::Clone>(
|
||||||
Cow::Owned(o) => o.as_mut_slice(),
|
Cow::Owned(o) => o.as_mut_slice(),
|
||||||
};
|
};
|
||||||
my_state.inner.with_data_mut(|state| {
|
my_state.inner.with_data_mut(|state| {
|
||||||
dbg!(&state.active_root);
|
|
||||||
let Some(active_root) = state.active_root.get(menu.depth).cloned() else {
|
let Some(active_root) = state.active_root.get(menu.depth).cloned() else {
|
||||||
return Status::Ignored;
|
return Status::Ignored;
|
||||||
};
|
};
|
||||||
dbg!("got the active root");
|
|
||||||
|
|
||||||
let indices = state.get_trimmed_indices(menu.depth);
|
let indices = state.get_trimmed_indices(menu.depth);
|
||||||
|
|
||||||
|
|
@ -1414,7 +1425,6 @@ fn process_menu_events<'b, Message: std::clone::Clone>(
|
||||||
if indices.is_empty() {
|
if indices.is_empty() {
|
||||||
return Status::Ignored;
|
return Status::Ignored;
|
||||||
}
|
}
|
||||||
dbg!(&active_root, &indices);
|
|
||||||
|
|
||||||
// get active item
|
// get active item
|
||||||
// let mt = indices.iter().fold(root | mt, &i | &mut mt.children[i]);
|
// let mt = indices.iter().fold(root | mt, &i | &mut mt.children[i]);
|
||||||
|
|
@ -1425,7 +1435,6 @@ fn process_menu_events<'b, Message: std::clone::Clone>(
|
||||||
),
|
),
|
||||||
|(tree, mt), next_active_root| (tree, &mut mt.children[*next_active_root]),
|
|(tree, mt), next_active_root| (tree, &mut mt.children[*next_active_root]),
|
||||||
);
|
);
|
||||||
dbg!(mt.children.len(), mt.index,);
|
|
||||||
// let Some(i) = state.menu_states[menu.depth].iter().position(|ms| {
|
// let Some(i) = state.menu_states[menu.depth].iter().position(|ms| {
|
||||||
// ms.menu_bounds
|
// ms.menu_bounds
|
||||||
// .check_bounds
|
// .check_bounds
|
||||||
|
|
@ -1437,7 +1446,6 @@ fn process_menu_events<'b, Message: std::clone::Clone>(
|
||||||
|
|
||||||
// widget tree
|
// widget tree
|
||||||
let tree = &mut tree[mt.index];
|
let tree = &mut tree[mt.index];
|
||||||
dbg!(tree.children.len());
|
|
||||||
|
|
||||||
// get layout
|
// get layout
|
||||||
let last_ms = &state.menu_states[menu.depth][indices.len() - 1];
|
let last_ms = &state.menu_states[menu.depth][indices.len() - 1];
|
||||||
|
|
@ -1450,9 +1458,7 @@ fn process_menu_events<'b, Message: std::clone::Clone>(
|
||||||
);
|
);
|
||||||
let child_layout = Layout::new(&child_node);
|
let child_layout = Layout::new(&child_node);
|
||||||
|
|
||||||
dbg!("item on event handler...");
|
|
||||||
// process only the last widget
|
// process only the last widget
|
||||||
dbg!(&event);
|
|
||||||
mt.item.on_event(
|
mt.item.on_event(
|
||||||
tree,
|
tree,
|
||||||
event,
|
event,
|
||||||
|
|
@ -1495,12 +1501,14 @@ where
|
||||||
menu.tree.inner.with_data_mut(|state| {
|
menu.tree.inner.with_data_mut(|state| {
|
||||||
let Some(active_root) = state.active_root.get(menu.depth).clone() else {
|
let Some(active_root) = state.active_root.get(menu.depth).clone() else {
|
||||||
if is_overlay && !menu.bar_bounds.contains(overlay_cursor) {
|
if is_overlay && !menu.bar_bounds.contains(overlay_cursor) {
|
||||||
|
dbg!("overlay");
|
||||||
state.reset();
|
state.reset();
|
||||||
}
|
}
|
||||||
return (new_menu_root, Ignored);
|
return (new_menu_root, Ignored);
|
||||||
};
|
};
|
||||||
|
|
||||||
if state.pressed {
|
if state.pressed {
|
||||||
|
dbg!("pressed");
|
||||||
return (new_menu_root, Ignored);
|
return (new_menu_root, Ignored);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1543,7 +1551,6 @@ where
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// dbg!(menu_states.len());
|
|
||||||
prev_bounds.pop();
|
prev_bounds.pop();
|
||||||
menu_states.pop();
|
menu_states.pop();
|
||||||
}
|
}
|
||||||
|
|
@ -1562,6 +1569,7 @@ where
|
||||||
// keep state.open when the cursor is still inside the menu bar
|
// keep state.open when the cursor is still inside the menu bar
|
||||||
// this allows the overlay to keep drawing when the cursor is
|
// this allows the overlay to keep drawing when the cursor is
|
||||||
// moving aroung the menu bar
|
// moving aroung the menu bar
|
||||||
|
dbg!("oops menu bar shouldn't disable popup");
|
||||||
if !menu.bar_bounds.contains(overlay_cursor) {
|
if !menu.bar_bounds.contains(overlay_cursor) {
|
||||||
state.open = false;
|
state.open = false;
|
||||||
}
|
}
|
||||||
|
|
@ -1621,6 +1629,15 @@ where
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// if last_menu_state
|
||||||
|
// .index
|
||||||
|
// .as_ref()
|
||||||
|
// .is_some_and(|old_index| *old_index == new_index)
|
||||||
|
// {
|
||||||
|
// dbg!("skipping duplicate", last_menu_state.index);
|
||||||
|
// return (None, Captured);
|
||||||
|
// }
|
||||||
|
dbg!(&last_menu_state.index, new_index);
|
||||||
|
|
||||||
let item = &active_menu[new_index];
|
let item = &active_menu[new_index];
|
||||||
// dbg!(new_index);
|
// dbg!(new_index);
|
||||||
|
|
@ -1707,6 +1724,8 @@ where
|
||||||
use mouse::ScrollDelta;
|
use mouse::ScrollDelta;
|
||||||
|
|
||||||
menu.tree.inner.with_data_mut(|state| {
|
menu.tree.inner.with_data_mut(|state| {
|
||||||
|
dbg!(state.active_root.len());
|
||||||
|
|
||||||
let delta_y = match delta {
|
let delta_y = match delta {
|
||||||
ScrollDelta::Lines { y, .. } => y * 60.0,
|
ScrollDelta::Lines { y, .. } => y * 60.0,
|
||||||
ScrollDelta::Pixels { y, .. } => y,
|
ScrollDelta::Pixels { y, .. } => y,
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ impl ResponsiveMenuBar {
|
||||||
core: &Core,
|
core: &Core,
|
||||||
key_binds: &HashMap<menu::KeyBind, A>,
|
key_binds: &HashMap<menu::KeyBind, A>,
|
||||||
id: crate::widget::Id,
|
id: crate::widget::Id,
|
||||||
action_message: impl Fn(crate::surface::Action) -> Message + Clone + 'static,
|
action_message: impl Fn(crate::surface::Action) -> Message + Send + Sync + Clone + 'static,
|
||||||
trees: Vec<(S, Vec<menu::Item<A, S>>)>,
|
trees: Vec<(S, Vec<menu::Item<A, S>>)>,
|
||||||
) -> Element<'a, Message> {
|
) -> Element<'a, Message> {
|
||||||
use crate::widget::id_container;
|
use crate::widget::id_container;
|
||||||
|
|
|
||||||
|
|
@ -1618,6 +1618,7 @@ where
|
||||||
is_overlay: true,
|
is_overlay: true,
|
||||||
window_id: window::Id::NONE,
|
window_id: window::Id::NONE,
|
||||||
depth: 0,
|
depth: 0,
|
||||||
|
on_surface_action: None,
|
||||||
}
|
}
|
||||||
.overlay(),
|
.overlay(),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue