From 0048cf482b1a66965ce43e599b28d49e0385dbca Mon Sep 17 00:00:00 2001 From: and3md Date: Sun, 18 Feb 2018 15:52:09 +0100 Subject: [PATCH 1/4] Possibility to add popup menu to any widget. --- src/dlangui/widgets/editors.d | 7 ------- src/dlangui/widgets/grid.d | 2 +- src/dlangui/widgets/widget.d | 32 +++++++++++++++++++++++++++++--- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/dlangui/widgets/editors.d b/src/dlangui/widgets/editors.d index ad1a234c..c82159bd 100644 --- a/src/dlangui/widgets/editors.d +++ b/src/dlangui/widgets/editors.d @@ -849,13 +849,6 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction acceleratorMap.add([ACTION_EDITOR_FIND_NEXT, ACTION_EDITOR_FIND_PREV]); } - protected MenuItem _popupMenu; - @property MenuItem popupMenu() { return _popupMenu; } - @property EditWidgetBase popupMenu(MenuItem popupMenu) { - _popupMenu = popupMenu; - return this; - } - /// override bool onMenuItemAction(const Action action) { return dispatchAction(action); diff --git a/src/dlangui/widgets/grid.d b/src/dlangui/widgets/grid.d index 1da108f2..f6133220 100644 --- a/src/dlangui/widgets/grid.d +++ b/src/dlangui/widgets/grid.d @@ -1005,7 +1005,7 @@ class GridWidgetBase : ScrollWidgetBase, GridModelAdapter, MenuItemActionHandler } /// handle popup menu action - protected bool onMenuItemAction(const Action action) { + protected override bool onMenuItemAction(const Action action) { if (menuItemAction.assigned) return menuItemAction(action); return false; diff --git a/src/dlangui/widgets/widget.d b/src/dlangui/widgets/widget.d index bc650887..655d6762 100644 --- a/src/dlangui/widgets/widget.d +++ b/src/dlangui/widgets/widget.d @@ -41,6 +41,7 @@ public { import dlangui.core.i18n; import dlangui.core.collections; import dlangui.widgets.styles; + import dlangui.widgets.menu; import dlangui.graphics.drawbuf; import dlangui.graphics.resources; @@ -153,7 +154,7 @@ enum CursorType { * */ @dmlwidget -class Widget { +class Widget : MenuItemActionHandler { protected: /// widget id string _id; @@ -1506,13 +1507,38 @@ public: // =========================================================== // popup menu support + override bool onMenuItemAction(const Action action) { + return dispatchAction(action); + } + + protected MenuItem _popupMenu; + @property MenuItem popupMenu() { return _popupMenu; } + @property Widget popupMenu(MenuItem popupMenu) { + _popupMenu = popupMenu; + return this; + } + /// returns true if widget can show popup menu (e.g. by mouse right click at point x,y) bool canShowPopupMenu(int x, int y) { - return false; + if (_popupMenu is null) + return false; + if (_popupMenu.openingSubmenu.assigned) + if (!_popupMenu.openingSubmenu(_popupMenu)) + return false; + return true; } /// shows popup menu at (x,y) void showPopupMenu(int x, int y) { - // override to show popup + /// if preparation signal handler assigned, call it; don't show popup if false is returned from handler + if (_popupMenu.openingSubmenu.assigned) + if (!_popupMenu.openingSubmenu(_popupMenu)) + return; + _popupMenu.updateActionState(this); + import dlangui.widgets.popup; + PopupMenu popupMenu = new PopupMenu(_popupMenu); + popupMenu.menuItemAction = this; + PopupWidget popup = window.showPopup(popupMenu, this, PopupAlign.Point | PopupAlign.Right, x, y); + popup.flags = PopupFlags.CloseOnClickOutside; } /// override to change popup menu items state bool isActionEnabled(const Action action) { From b81e34b2361d85257bfbbe8bde74fff7064bac96 Mon Sep 17 00:00:00 2001 From: and3md Date: Sun, 18 Feb 2018 15:54:38 +0100 Subject: [PATCH 2/4] Closing the popupMenu by clicking outside, should not pass the event to the control under the mouse. --- src/dlangui/platforms/common/platform.d | 7 +++++-- src/dlangui/widgets/popup.d | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/dlangui/platforms/common/platform.d b/src/dlangui/platforms/common/platform.d index 2d754884..87909009 100644 --- a/src/dlangui/platforms/common/platform.d +++ b/src/dlangui/platforms/common/platform.d @@ -1505,8 +1505,11 @@ class Window : CustomEventTarget { if (p is modal) break; if (!insideOneOfPopups) { - if (p.onMouseEventOutside(event)) // stop loop when true is returned, but allow other main widget to handle event - break; + if (event.action == MouseAction.ButtonDown) + return true; // mouse button down should do nothing when click outside when popup visible + if (p.onMouseEventOutside(event)) { + return true; // mouse button up should do nothing when click outside when popup visible + } } else { if (dispatchMouseEvent(p, event, cursorIsSet)) return true; diff --git a/src/dlangui/widgets/popup.d b/src/dlangui/widgets/popup.d index 21ca8956..b4cfc352 100644 --- a/src/dlangui/widgets/popup.d +++ b/src/dlangui/widgets/popup.d @@ -174,10 +174,10 @@ class PopupWidget : LinearLayout { if (visibility != Visibility.Visible) return false; if (_flags & PopupFlags.CloseOnClickOutside) { - if (event.action == MouseAction.ButtonDown) { + if (event.action == MouseAction.ButtonUp) { // clicked outside - close popup close(); - return false; + return true; } } if (_flags & PopupFlags.CloseOnMouseMoveOutside) { From c971b68655660be6b91ae60cbdd7ff6a86946f3d Mon Sep 17 00:00:00 2001 From: and3md Date: Sun, 18 Feb 2018 15:56:42 +0100 Subject: [PATCH 3/4] Fix main menu after popup menu fix. --- src/dlangui/widgets/menu.d | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/dlangui/widgets/menu.d b/src/dlangui/widgets/menu.d index 7d7eb308..e1dfe35c 100644 --- a/src/dlangui/widgets/menu.d +++ b/src/dlangui/widgets/menu.d @@ -937,7 +937,7 @@ class MainMenu : MenuWidgetBase { super(null, null, Orientation.Horizontal); id = "MAIN_MENU"; styleId = STYLE_MAIN_MENU; - _clickOnButtonDown = true; + _clickOnButtonDown = false; selectOnHover = false; } @@ -945,7 +945,7 @@ class MainMenu : MenuWidgetBase { super(null, item, Orientation.Horizontal); id = "MAIN_MENU"; styleId = STYLE_MAIN_MENU; - _clickOnButtonDown = true; + _clickOnButtonDown = false; selectOnHover = false; } From dd4eed5ed22d3b4fc1b23b5025ac95a0929a7fbb Mon Sep 17 00:00:00 2001 From: and3md Date: Sun, 18 Feb 2018 15:58:40 +0100 Subject: [PATCH 4/4] Fix AppFrame after add popup menus to all widgets. --- src/dlangui/widgets/appframe.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dlangui/widgets/appframe.d b/src/dlangui/widgets/appframe.d index 11aeef41..7c2acd50 100644 --- a/src/dlangui/widgets/appframe.d +++ b/src/dlangui/widgets/appframe.d @@ -256,7 +256,7 @@ class AppFrame : VerticalLayout, MenuItemClickHandler, MenuItemActionHandler { } /// override to handle main menu actions - bool onMenuItemAction(const Action action) { + override bool onMenuItemAction(const Action action) { // default handling: dispatch action using window (first offered to focused control, then to main widget) return window.dispatchAction(action); }