From 8643f02ce7ebd8e89d307df65b6b63b8ca92f946 Mon Sep 17 00:00:00 2001 From: captchaKing Date: Mon, 7 Feb 2022 15:07:23 +0300 Subject: [PATCH 1/3] Fix MenuBar behaviour --- crates/kas-widgets/src/menu/menubar.rs | 89 +++++++++++++------------- 1 file changed, 44 insertions(+), 45 deletions(-) diff --git a/crates/kas-widgets/src/menu/menubar.rs b/crates/kas-widgets/src/menu/menubar.rs index b24a577fe..9af110e3d 100644 --- a/crates/kas-widgets/src/menu/menubar.rs +++ b/crates/kas-widgets/src/menu/menubar.rs @@ -24,8 +24,6 @@ widget! { core: CoreData, #[widget] pub bar: IndexedList>, - // Open mode. Used to close with click on root only when previously open. - opening: bool, delayed_open: Option, } @@ -49,7 +47,6 @@ widget! { MenuBar { core: Default::default(), bar: IndexedList::new_with_direction(direction, menus), - opening: false, delayed_open: None, } } @@ -75,28 +72,31 @@ widget! { } => { if start_id.as_ref().map(|id| self.is_ancestor_of(id)).unwrap_or(false) { if source.is_primary() { - mgr.grab_press_unique(self.id(), source, coord, None); + let any_menu_open = self.bar.iter().any(|w| w.menu_is_open()); + let press_in_the_bar = self.rect().contains(coord); + + match press_in_the_bar { + true if !any_menu_open => mgr.grab_press_unique(self.id(), source, coord, None), + false => mgr.grab_press_unique(self.id(), source, coord, None), + _ => (), + } mgr.set_grab_depress(source, start_id.clone()); - self.opening = false; - if self.rect().contains(coord) { + if press_in_the_bar { if self .bar .iter() .any(|w| w.eq_id(&start_id) && !w.menu_is_open()) { - self.opening = true; self.set_menu_path(mgr, start_id.as_ref(), false); } else { self.set_menu_path(mgr, None, false); } - } else { - let delay = mgr.config().menu_delay(); - mgr.update_on_timer(delay, self.id(), WidgetId::opt_to_u64(start_id.as_ref())); - self.delayed_open = start_id; } } Response::Used } else { + // Click happened out of the menubar or submenus, + // while one or more submenus are opened. self.delayed_open = None; Response::Unused } @@ -107,46 +107,45 @@ widget! { coord, .. } => { - mgr.set_grab_depress(source, cur_id.clone()); - if let Some(id) = cur_id { - if self.bar.is_strict_ancestor_of(&id) { - // We instantly open a sub-menu on motion over the bar, - // but delay when over a sub-menu (most intuitive?) - if self.rect().contains(coord) && !self.bar.eq_id(&id) { - self.set_menu_path(mgr, Some(&id), false); - } else if id != self.delayed_open { - mgr.set_nav_focus(id.clone(), false); - let delay = mgr.config().menu_delay(); - mgr.update_on_timer(delay, self.id(), id.as_u64()); - self.delayed_open = Some(id); - } - } + if !mgr.set_grab_depress(source, cur_id.clone()) { + // If redraw hasn't happened, force it to fix + // highligting of previously selected menu-item + mgr.send_action(TkAction::REDRAW); } - Response::Used - } - Event::PressEnd { coord, end_id, success, .. } if success => { - if end_id.as_ref().map(|id| self.is_ancestor_of(id)).unwrap_or(false) { - // end_id is a child of self - let id = end_id.unwrap(); + + let id = match cur_id { + Some(x) => x, + None => return Response::Used, + }; + if self.bar.is_strict_ancestor_of(&id) { + // We instantly open a sub-menu on motion over the bar, + // but delay when over a sub-menu (most intuitive?) if self.rect().contains(coord) { - // end coordinate is on the menubar - if !self.opening { - self.delayed_open = None; - for i in 0..self.bar.len() { - if self.bar[i].eq_id(&id) { - self.bar[i].set_menu_path(mgr, None, false); - } - } - } - } else { - // not on the menubar, thus on a sub-menu + mgr.set_nav_focus(self.id(), false); self.delayed_open = None; - return self.send(mgr, id, Event::Activate); + self.set_menu_path(mgr, Some(&id), false); + } else if id != self.delayed_open { + mgr.set_nav_focus(id.clone(), false); + let delay = mgr.config().menu_delay(); + mgr.update_on_timer(delay, self.id(), id.as_u64()); + self.delayed_open = Some(id.clone()); } } else { - // not on the menu - self.set_menu_path(mgr, None, false); + self.delayed_open = None; + } + Response::Used + } + Event::PressEnd { coord, end_id, success, .. } if success => { + let id = match end_id { + Some(x) => x, + None => return Response::Used, + }; + + if !self.rect().contains(coord) { + // not on the menubar + self.delayed_open = None; + return self.send(mgr, id, Event::Activate); } Response::Used } From f7217376015c8b14756031987b9fc7a3bbc53d33 Mon Sep 17 00:00:00 2001 From: captchaKing Date: Thu, 10 Feb 2022 04:21:35 +0300 Subject: [PATCH 2/3] Attempt to fix menu highlighting --- crates/kas-widgets/src/menu/menubar.rs | 8 +++----- crates/kas-widgets/src/menu/submenu.rs | 8 +++++++- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/crates/kas-widgets/src/menu/menubar.rs b/crates/kas-widgets/src/menu/menubar.rs index 9af110e3d..d2df17e06 100644 --- a/crates/kas-widgets/src/menu/menubar.rs +++ b/crates/kas-widgets/src/menu/menubar.rs @@ -75,10 +75,8 @@ widget! { let any_menu_open = self.bar.iter().any(|w| w.menu_is_open()); let press_in_the_bar = self.rect().contains(coord); - match press_in_the_bar { - true if !any_menu_open => mgr.grab_press_unique(self.id(), source, coord, None), - false => mgr.grab_press_unique(self.id(), source, coord, None), - _ => (), + if !press_in_the_bar || !any_menu_open { + mgr.grab_press_unique(self.id(), source, coord, None); } mgr.set_grab_depress(source, start_id.clone()); if press_in_the_bar { @@ -112,7 +110,7 @@ widget! { // highligting of previously selected menu-item mgr.send_action(TkAction::REDRAW); } - + let id = match cur_id { Some(x) => x, None => return Response::Used, diff --git a/crates/kas-widgets/src/menu/submenu.rs b/crates/kas-widgets/src/menu/submenu.rs index 6c3e20662..8cddb3de5 100644 --- a/crates/kas-widgets/src/menu/submenu.rs +++ b/crates/kas-widgets/src/menu/submenu.rs @@ -26,6 +26,7 @@ widget! { #[widget] pub list: Column, popup_id: Option, + closing_menu: bool, } impl Self where D: Default { @@ -68,6 +69,7 @@ widget! { frame_store: Default::default(), list: Column::new(list), popup_id: None, + closing_menu: false, } } @@ -86,6 +88,7 @@ widget! { fn close_menu(&mut self, mgr: &mut EventMgr, restore_focus: bool) { if let Some(id) = self.popup_id { mgr.close_window(id, restore_focus); + self.closing_menu = true; } } @@ -145,7 +148,9 @@ widget! { fn draw(&mut self, mut draw: DrawMgr) { let mut draw = draw.with_core(self.core_data()); if self.popup_id.is_some() { - draw.state.insert(InputState::DEPRESS); + if !self.closing_menu { + draw.state.insert(InputState::DEPRESS); + } } draw.menu_entry(self.core.rect); draw.text_accel( @@ -171,6 +176,7 @@ widget! { Event::PopupRemoved(id) => { debug_assert_eq!(Some(id), self.popup_id); self.popup_id = None; + self.closing_menu = false; Response::Used } Event::Command(cmd, _) => self.handle_dir_key(mgr, cmd), From b49b2638a151316e4e25e6c72006bfd95d576e2f Mon Sep 17 00:00:00 2001 From: captchaKing Date: Sat, 12 Feb 2022 18:24:36 +0300 Subject: [PATCH 3/3] Remove useless redraw, merge if's --- crates/kas-widgets/src/menu/menubar.rs | 6 +----- crates/kas-widgets/src/menu/submenu.rs | 6 ++---- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/crates/kas-widgets/src/menu/menubar.rs b/crates/kas-widgets/src/menu/menubar.rs index d2df17e06..d528e41f1 100644 --- a/crates/kas-widgets/src/menu/menubar.rs +++ b/crates/kas-widgets/src/menu/menubar.rs @@ -105,11 +105,7 @@ widget! { coord, .. } => { - if !mgr.set_grab_depress(source, cur_id.clone()) { - // If redraw hasn't happened, force it to fix - // highligting of previously selected menu-item - mgr.send_action(TkAction::REDRAW); - } + mgr.set_grab_depress(source, cur_id.clone()); let id = match cur_id { Some(x) => x, diff --git a/crates/kas-widgets/src/menu/submenu.rs b/crates/kas-widgets/src/menu/submenu.rs index 8cddb3de5..3096d016e 100644 --- a/crates/kas-widgets/src/menu/submenu.rs +++ b/crates/kas-widgets/src/menu/submenu.rs @@ -147,10 +147,8 @@ widget! { fn draw(&mut self, mut draw: DrawMgr) { let mut draw = draw.with_core(self.core_data()); - if self.popup_id.is_some() { - if !self.closing_menu { - draw.state.insert(InputState::DEPRESS); - } + if self.popup_id.is_some() && !self.closing_menu { + draw.state.insert(InputState::DEPRESS); } draw.menu_entry(self.core.rect); draw.text_accel(