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/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); } 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/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; } 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) { 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) {