mirror of https://github.com/buggins/dlangui.git
popup and menu improvements
This commit is contained in:
parent
8d5833640f
commit
321e657661
|
@ -78,6 +78,7 @@ class Window {
|
||||||
for (int j = i; j < _popups.length - 1; j++)
|
for (int j = i; j < _popups.length - 1; j++)
|
||||||
_popups[j] = _popups[j + 1];
|
_popups[j] = _popups[j + 1];
|
||||||
_popups.length--;
|
_popups.length--;
|
||||||
|
p.onClose();
|
||||||
destroy(p);
|
destroy(p);
|
||||||
// force redraw
|
// force redraw
|
||||||
_mainWidget.invalidate();
|
_mainWidget.invalidate();
|
||||||
|
@ -340,14 +341,25 @@ class Window {
|
||||||
processed = checkRemoveTracking(event);
|
processed = checkRemoveTracking(event);
|
||||||
}
|
}
|
||||||
if (!res) {
|
if (!res) {
|
||||||
|
bool insideOneOfPopups = false;
|
||||||
for (int i = cast(int)_popups.length - 1; i >= 0; i--) {
|
for (int i = cast(int)_popups.length - 1; i >= 0; i--) {
|
||||||
auto p = _popups[i];
|
auto p = _popups[i];
|
||||||
if (dispatchMouseEvent(p, event))
|
if (p.isPointInside(event.x, event.y))
|
||||||
return true;
|
insideOneOfPopups = true;
|
||||||
|
}
|
||||||
|
for (int i = cast(int)_popups.length - 1; i >= 0; i--) {
|
||||||
|
auto p = _popups[i];
|
||||||
|
if (!insideOneOfPopups) {
|
||||||
|
if (p.onMouseEventOutside(event)) // stop loop when true is returned, but allow other main widget to handle event
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
if (dispatchMouseEvent(p, event))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
res = dispatchMouseEvent(_mainWidget, event);
|
res = dispatchMouseEvent(_mainWidget, event);
|
||||||
}
|
}
|
||||||
return res || processed;
|
return res || processed || _mainWidget.needDraw;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// checks content widgets for necessary redraw and/or layout
|
/// checks content widgets for necessary redraw and/or layout
|
||||||
|
|
|
@ -102,11 +102,20 @@ class MenuWidgetBase : ListWidget {
|
||||||
ownAdapter = adapter;
|
ownAdapter = adapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void onPopupClosed(PopupWidget p) {
|
||||||
|
_openedPopup = null;
|
||||||
|
_openedMenu = null;
|
||||||
|
selectItem(-1);
|
||||||
|
}
|
||||||
|
|
||||||
protected void openSubmenu(MenuItemWidget itemWidget) {
|
protected void openSubmenu(MenuItemWidget itemWidget) {
|
||||||
if (_openedPopup !is null)
|
if (_openedPopup !is null) {
|
||||||
_openedPopup.close();
|
_openedPopup.close();
|
||||||
|
}
|
||||||
PopupMenu popupMenu = new PopupMenu(itemWidget.item, this);
|
PopupMenu popupMenu = new PopupMenu(itemWidget.item, this);
|
||||||
PopupWidget popup = window.showPopup(popupMenu, itemWidget, PopupAlign.Below);
|
PopupWidget popup = window.showPopup(popupMenu, itemWidget, PopupAlign.Below);
|
||||||
|
popup.onPopupCloseListener = &onPopupClosed;
|
||||||
|
popup.flags = PopupFlags.CloseOnClickOutside;
|
||||||
_openedPopup = popup;
|
_openedPopup = popup;
|
||||||
_openedMenu = popupMenu;
|
_openedMenu = popupMenu;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,10 +17,29 @@ struct PopupAnchor {
|
||||||
uint alignment = PopupAlign.Center;
|
uint alignment = PopupAlign.Center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// popup behavior flags - for PopupWidget.flags property
|
||||||
|
enum PopupFlags : uint {
|
||||||
|
/// close popup when mouse button clicked outside of its bounds
|
||||||
|
CloseOnClickOutside = 1,
|
||||||
|
}
|
||||||
|
|
||||||
/// popup widget container
|
/// popup widget container
|
||||||
class PopupWidget : LinearLayout {
|
class PopupWidget : LinearLayout {
|
||||||
protected PopupAnchor _anchor;
|
protected PopupAnchor _anchor;
|
||||||
protected bool _modal;
|
protected bool _modal;
|
||||||
|
|
||||||
|
protected uint _flags;
|
||||||
|
protected void delegate(PopupWidget popup) _onPopupCloseListener;
|
||||||
|
/// popup close listener (called right before closing)
|
||||||
|
@property void delegate(PopupWidget popup) onPopupCloseListener() { return _onPopupCloseListener; }
|
||||||
|
/// set popup close listener (to call right before closing)
|
||||||
|
@property PopupWidget onPopupCloseListener(void delegate(PopupWidget popup) listener) { _onPopupCloseListener = listener; return this; }
|
||||||
|
|
||||||
|
/// returns popup behavior flags (combination of PopupFlags)
|
||||||
|
@property uint flags() { return _flags; }
|
||||||
|
/// set popup behavior flags (combination of PopupFlags)
|
||||||
|
@property PopupWidget flags(uint flags) { _flags = flags; return this; }
|
||||||
|
|
||||||
/// access to popup anchor
|
/// access to popup anchor
|
||||||
@property ref PopupAnchor anchor() { return _anchor; }
|
@property ref PopupAnchor anchor() { return _anchor; }
|
||||||
/// returns true if popup is modal
|
/// returns true if popup is modal
|
||||||
|
@ -37,6 +56,12 @@ class PopupWidget : LinearLayout {
|
||||||
window.removePopup(this);
|
window.removePopup(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// just call on close listener
|
||||||
|
void onClose() {
|
||||||
|
if (_onPopupCloseListener !is null)
|
||||||
|
_onPopupCloseListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
/// Set widget rectangle to specified value and layout widget contents. (Step 2 of two phase layout).
|
/// Set widget rectangle to specified value and layout widget contents. (Step 2 of two phase layout).
|
||||||
override void layout(Rect rc) {
|
override void layout(Rect rc) {
|
||||||
if (visibility == Visibility.Gone) {
|
if (visibility == Visibility.Gone) {
|
||||||
|
@ -77,4 +102,18 @@ class PopupWidget : LinearLayout {
|
||||||
//styleId = "POPUP_MENU";
|
//styleId = "POPUP_MENU";
|
||||||
addChild(content);
|
addChild(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// called for mouse activity outside shown popup bounds
|
||||||
|
bool onMouseEventOutside(MouseEvent event) {
|
||||||
|
if (visibility != Visibility.Visible)
|
||||||
|
return false;
|
||||||
|
if (_flags & PopupFlags.CloseOnClickOutside) {
|
||||||
|
if (event.action == MouseAction.ButtonDown) {
|
||||||
|
// clicked outside - close popup
|
||||||
|
close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue