mirror of https://github.com/buggins/dlangui.git
popup menu support
This commit is contained in:
parent
45cafad1cb
commit
0b35db01c7
|
@ -75,6 +75,14 @@ extern (C) int UIAppMain(string[] args) {
|
||||||
editItem.add(new Action(EditorActions.Undo, "Undo"d, "edit-undo", KeyCode.KEY_Z, KeyFlag.Control));
|
editItem.add(new Action(EditorActions.Undo, "Undo"d, "edit-undo", KeyCode.KEY_Z, KeyFlag.Control));
|
||||||
editItem.add(new Action(EditorActions.Redo, "Redo"d, "edit-redo", KeyCode.KEY_Y, KeyFlag.Control));
|
editItem.add(new Action(EditorActions.Redo, "Redo"d, "edit-redo", KeyCode.KEY_Y, KeyFlag.Control));
|
||||||
editItem.add(new Action(20, "Preferences..."d));
|
editItem.add(new Action(20, "Preferences..."d));
|
||||||
|
|
||||||
|
MenuItem editPopupItem = new MenuItem(null);
|
||||||
|
editPopupItem.add(new Action(EditorActions.Copy, "Copy"d, "edit-copy", KeyCode.KEY_C, KeyFlag.Control));
|
||||||
|
editPopupItem.add(new Action(EditorActions.Paste, "Paste"d, "edit-paste", KeyCode.KEY_V, KeyFlag.Control));
|
||||||
|
editPopupItem.add(new Action(EditorActions.Cut, "Cut"d, "edit-cut", KeyCode.KEY_X, KeyFlag.Control));
|
||||||
|
editPopupItem.add(new Action(EditorActions.Undo, "Undo"d, "edit-undo", KeyCode.KEY_Z, KeyFlag.Control));
|
||||||
|
editPopupItem.add(new Action(EditorActions.Redo, "Redo"d, "edit-redo", KeyCode.KEY_Y, KeyFlag.Control));
|
||||||
|
|
||||||
MenuItem windowItem = new MenuItem(new Action(3, "&Window"d));
|
MenuItem windowItem = new MenuItem(new Action(3, "&Window"d));
|
||||||
windowItem.add(new Action(30, "Preferences"d));
|
windowItem.add(new Action(30, "Preferences"d));
|
||||||
MenuItem helpItem = new MenuItem(new Action(4, "Help"d));
|
MenuItem helpItem = new MenuItem(new Action(4, "Help"d));
|
||||||
|
@ -119,7 +127,7 @@ extern (C) int UIAppMain(string[] args) {
|
||||||
hlayout.addChild((new ImageWidget()).drawableId("btn_check").padding(Rect(5,5,5,5)).alignment(Align.Center));
|
hlayout.addChild((new ImageWidget()).drawableId("btn_check").padding(Rect(5,5,5,5)).alignment(Align.Center));
|
||||||
hlayout.addChild((new TextWidget()).text("in horizontal layout"));
|
hlayout.addChild((new TextWidget()).text("in horizontal layout"));
|
||||||
hlayout.addChild((new ImageWidget()).drawableId("exit").padding(Rect(5,5,5,5)).alignment(Align.Center));
|
hlayout.addChild((new ImageWidget()).drawableId("exit").padding(Rect(5,5,5,5)).alignment(Align.Center));
|
||||||
hlayout.addChild((new EditLine("editline", "Some text to edit"d)).alignment(Align.Center).layoutWidth(FILL_PARENT));
|
hlayout.addChild((new EditLine("editline", "Some text to edit"d)).popupMenu(editPopupItem).alignment(Align.Center).layoutWidth(FILL_PARENT));
|
||||||
//hlayout.addChild((new Button()).text(">>")); //.textColor(0x40FF4000)
|
//hlayout.addChild((new Button()).text(">>")); //.textColor(0x40FF4000)
|
||||||
hlayout.backgroundColor = 0x8080C0;
|
hlayout.backgroundColor = 0x8080C0;
|
||||||
layout.addChild(hlayout);
|
layout.addChild(hlayout);
|
||||||
|
@ -278,6 +286,7 @@ extern (C) int UIAppMain(string[] args) {
|
||||||
EditLine editLine = new EditLine("editline1", "Single line editor sample text");
|
EditLine editLine = new EditLine("editline1", "Single line editor sample text");
|
||||||
editors.addChild(createEditorSettingsControl(editLine));
|
editors.addChild(createEditorSettingsControl(editLine));
|
||||||
editors.addChild(editLine);
|
editors.addChild(editLine);
|
||||||
|
editLine.popupMenu = editPopupItem;
|
||||||
|
|
||||||
// EditBox sample
|
// EditBox sample
|
||||||
editors.addChild(new TextWidget(null, "EditBox: Multiline editor"d));
|
editors.addChild(new TextWidget(null, "EditBox: Multiline editor"d));
|
||||||
|
@ -296,6 +305,7 @@ extern (C) int UIAppMain(string[] args) {
|
||||||
editBox.minFontSize(12).maxFontSize(75); // allow font zoom with Ctrl + MouseWheel
|
editBox.minFontSize(12).maxFontSize(75); // allow font zoom with Ctrl + MouseWheel
|
||||||
editors.addChild(createEditorSettingsControl(editBox));
|
editors.addChild(createEditorSettingsControl(editBox));
|
||||||
editors.addChild(editBox);
|
editors.addChild(editBox);
|
||||||
|
editBox.popupMenu = editPopupItem;
|
||||||
|
|
||||||
editors.addChild(new TextWidget(null, "EditBox: additional view for the same content (split view testing)"d));
|
editors.addChild(new TextWidget(null, "EditBox: additional view for the same content (split view testing)"d));
|
||||||
EditBox editBox2 = new EditBox("editbox2", ""d);
|
EditBox editBox2 = new EditBox("editbox2", ""d);
|
||||||
|
|
|
@ -85,10 +85,12 @@ class Window {
|
||||||
|
|
||||||
protected PopupWidget[] _popups;
|
protected PopupWidget[] _popups;
|
||||||
/// show new popup
|
/// show new popup
|
||||||
PopupWidget showPopup(Widget content, Widget anchor = null, uint alignment = PopupAlign.Center) {
|
PopupWidget showPopup(Widget content, Widget anchor = null, uint alignment = PopupAlign.Center, int x = 0, int y = 0) {
|
||||||
PopupWidget res = new PopupWidget(content, this);
|
PopupWidget res = new PopupWidget(content, this);
|
||||||
res.anchor.widget = anchor !is null ? anchor : _mainWidget;
|
res.anchor.widget = anchor !is null ? anchor : _mainWidget;
|
||||||
res.anchor.alignment = alignment;
|
res.anchor.alignment = alignment;
|
||||||
|
res.anchor.x = x;
|
||||||
|
res.anchor.y = y;
|
||||||
_popups ~= res;
|
_popups ~= res;
|
||||||
if (_mainWidget !is null)
|
if (_mainWidget !is null)
|
||||||
_mainWidget.requestLayout();
|
_mainWidget.requestLayout();
|
||||||
|
|
|
@ -25,6 +25,8 @@ import dlangui.widgets.controls;
|
||||||
import dlangui.core.signals;
|
import dlangui.core.signals;
|
||||||
import dlangui.core.collections;
|
import dlangui.core.collections;
|
||||||
import dlangui.platforms.common.platform;
|
import dlangui.platforms.common.platform;
|
||||||
|
import dlangui.widgets.menu;
|
||||||
|
import dlangui.widgets.popup;
|
||||||
|
|
||||||
import std.algorithm;
|
import std.algorithm;
|
||||||
|
|
||||||
|
@ -897,6 +899,36 @@ class EditWidgetBase : WidgetGroup, EditableContentListener {
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected MenuItem _popupMenu;
|
||||||
|
@property MenuItem popupMenu() { return _popupMenu; }
|
||||||
|
@property EditWidgetBase popupMenu(MenuItem popupMenu) {
|
||||||
|
_popupMenu = popupMenu;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/// returns true if widget can show popup (e.g. by mouse right click at point x,y)
|
||||||
|
override bool canShowPopupMenu(int x, int y) {
|
||||||
|
if (_popupMenu is null)
|
||||||
|
return false;
|
||||||
|
if (_popupMenu.onBeforeOpeningSubmenu.assigned)
|
||||||
|
if (!_popupMenu.onBeforeOpeningSubmenu(_popupMenu))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/// shows popup at (x,y)
|
||||||
|
override void showPopupMenu(int x, int y) {
|
||||||
|
/// if preparation signal handler assigned, call it; don't show popup if false is returned from handler
|
||||||
|
if (_popupMenu.onBeforeOpeningSubmenu.assigned)
|
||||||
|
if (!_popupMenu.onBeforeOpeningSubmenu(_popupMenu))
|
||||||
|
return;
|
||||||
|
PopupMenu popupMenu = new PopupMenu(_popupMenu);
|
||||||
|
PopupWidget popup = window.showPopup(popupMenu, this, PopupAlign.Point | PopupAlign.Right, x, y);
|
||||||
|
popup.flags = PopupFlags.CloseOnClickOutside;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onPopupMenuItem(MenuItem item) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
/// when true, Tab / Shift+Tab presses are processed internally in widget (e.g. insert tab character) instead of focus change navigation.
|
/// when true, Tab / Shift+Tab presses are processed internally in widget (e.g. insert tab character) instead of focus change navigation.
|
||||||
@property bool wantTabs() {
|
@property bool wantTabs() {
|
||||||
return _wantTabs;
|
return _wantTabs;
|
||||||
|
@ -1630,7 +1662,7 @@ class EditWidgetBase : WidgetGroup, EditableContentListener {
|
||||||
return handleAction(new Action(EditorActions.ScrollLineUp));
|
return handleAction(new Action(EditorActions.ScrollLineUp));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return super.onMouseEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -97,6 +97,12 @@ class MenuItem {
|
||||||
@property const(Action) action() const { return _action; }
|
@property const(Action) action() const { return _action; }
|
||||||
/// sets item action
|
/// sets item action
|
||||||
@property MenuItem action(Action a) { _action = a; return this; }
|
@property MenuItem action(Action a) { _action = a; return this; }
|
||||||
|
|
||||||
|
/// handle menu item click
|
||||||
|
Signal!(void, MenuItem) onMenuItem;
|
||||||
|
/// prepare for opening of submenu, return true if opening is allowed
|
||||||
|
Signal!(bool, MenuItem) onBeforeOpeningSubmenu;
|
||||||
|
|
||||||
this() {
|
this() {
|
||||||
_enabled = true;
|
_enabled = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,10 +32,14 @@ enum PopupAlign : uint {
|
||||||
Below = 2,
|
Below = 2,
|
||||||
/// place popup below anchor widget close to right bound (when no space enough, align near left bound)
|
/// place popup below anchor widget close to right bound (when no space enough, align near left bound)
|
||||||
Right = 4,
|
Right = 4,
|
||||||
|
/// align to specified point
|
||||||
|
Point = 8,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PopupAnchor {
|
struct PopupAnchor {
|
||||||
Widget widget;
|
Widget widget;
|
||||||
|
int x;
|
||||||
|
int y;
|
||||||
uint alignment = PopupAlign.Center;
|
uint alignment = PopupAlign.Center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,6 +109,10 @@ class PopupWidget : LinearLayout {
|
||||||
Rect r;
|
Rect r;
|
||||||
Point anchorPt;
|
Point anchorPt;
|
||||||
|
|
||||||
|
if (anchor.alignment & PopupAlign.Point) {
|
||||||
|
r.left = anchor.x;
|
||||||
|
r.top = anchor.y;
|
||||||
|
} else {
|
||||||
if (anchor.alignment & PopupAlign.Center) {
|
if (anchor.alignment & PopupAlign.Center) {
|
||||||
// center around center of anchor widget
|
// center around center of anchor widget
|
||||||
r.left = anchorrc.middlex - w / 2;
|
r.left = anchorrc.middlex - w / 2;
|
||||||
|
@ -116,6 +124,7 @@ class PopupWidget : LinearLayout {
|
||||||
r.left = anchorrc.right;
|
r.left = anchorrc.right;
|
||||||
r.top = anchorrc.top;
|
r.top = anchorrc.top;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
r.right = r.left + w;
|
r.right = r.left + w;
|
||||||
r.bottom = r.top + h;
|
r.bottom = r.top + h;
|
||||||
r.moveToFit(rc);
|
r.moveToFit(rc);
|
||||||
|
|
|
@ -866,6 +866,12 @@ class Widget {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (event.action == MouseAction.ButtonDown && event.button == MouseButton.Right) {
|
||||||
|
if (canShowPopupMenu(event.x, event.y)) {
|
||||||
|
showPopupMenu(event.x, event.y);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (canFocus && event.action == MouseAction.ButtonDown && event.button == MouseButton.Left) {
|
if (canFocus && event.action == MouseAction.ButtonDown && event.button == MouseButton.Left) {
|
||||||
setFocus();
|
setFocus();
|
||||||
return true;
|
return true;
|
||||||
|
@ -1034,6 +1040,17 @@ class Widget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ===========================================================
|
||||||
|
// popup menu support
|
||||||
|
/// 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;
|
||||||
|
}
|
||||||
|
/// shows popup menu at (x,y)
|
||||||
|
void showPopupMenu(int x, int y) {
|
||||||
|
// override to show popup
|
||||||
|
}
|
||||||
|
|
||||||
// ===========================================================
|
// ===========================================================
|
||||||
// Widget hierarhy methods
|
// Widget hierarhy methods
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue