diff --git a/src/dlangui/core/events.d b/src/dlangui/core/events.d index 67876b06..4d394d91 100644 --- a/src/dlangui/core/events.d +++ b/src/dlangui/core/events.d @@ -1242,9 +1242,11 @@ class KeyEvent { @property dstring text() { return _text; } /// returns true if no modifier flags are set - @property bool noModifiers() { return (_flags & (KeyFlag.Control | KeyFlag.Alt | KeyFlag.Menu | KeyFlag.Shift)) == 0; } + @property bool noModifiers() { return modifiers == 0; } /// returns true if any modifier flag is set @property bool hasModifiers() { return !noModifiers; } + /// returns modifier flags filtered for KeyFlag.Control | KeyFlag.Alt | KeyFlag.Menu | KeyFlag.Shift only + @property uint modifiers() { return (_flags & (KeyFlag.Control | KeyFlag.Alt | KeyFlag.Menu | KeyFlag.Shift)); } /// create key event this(KeyAction action, uint keyCode, uint flags, dstring text = null) { diff --git a/src/dlangui/dialogs/dialog.d b/src/dlangui/dialogs/dialog.d index 3baea219..d20c88f0 100644 --- a/src/dlangui/dialogs/dialog.d +++ b/src/dlangui/dialogs/dialog.d @@ -55,6 +55,7 @@ class Dialog : VerticalLayout { protected string _icon; protected int _initialWidth; protected int _initialHeight; + protected int _defaultButtonIndex = -1; Signal!DialogResultHandler dialogResult; @@ -124,6 +125,7 @@ class Dialog : VerticalLayout { protected ImageTextButton _cancelButton; /// create panel with buttons based on list of actions Widget createButtonsPanel(const(Action) [] actions, int defaultActionIndex, int splitBeforeIndex) { + _defaultButtonIndex = defaultActionIndex; _buttonActions = actions; LinearLayout res = new HorizontalLayout("buttons"); res.layoutWidth(FILL_PARENT); @@ -229,6 +231,41 @@ class Dialog : VerticalLayout { if (_defaultButton) _defaultButton.setFocus(); } + + /// calls close with default action; returns true if default action is found and invoked + protected bool closeWithDefaultAction() { + if (_defaultButtonIndex >= 0 && _defaultButtonIndex < _buttonActions.length) { + close(_buttonActions[_defaultButtonIndex]); + return true; + } + return false; + } + + /// calls close with cancel action (if found); returns true if cancel action is found and invoked + protected bool closeWithCancelAction() { + for (int i = 0; i < _buttonActions.length; i++) { + if (_buttonActions[i].id == StandardAction.Cancel || _buttonActions[i].id == StandardAction.No) { + close(_buttonActions[_defaultButtonIndex]); + return true; + } + } + return false; + } + + /// pass key event here; returns true if search text is updated and you can move selection using it + override bool onKeyEvent(KeyEvent event) { + if (event.action == KeyAction.KeyUp) { + if (event.keyCode == KeyCode.RETURN && event.modifiers == KeyFlag.Control) { + // Ctrl+Enter: default action + return closeWithDefaultAction(); + } + if (event.keyCode == KeyCode.ESCAPE && event.noModifiers) { + // ESC: cancel/no action + return closeWithCancelAction(); + } + } + return super.onKeyEvent(event); + } } /// frame with caption for dialog diff --git a/src/dlangui/dialogs/filedlg.d b/src/dlangui/dialogs/filedlg.d index 50ed67d0..c776e56b 100644 --- a/src/dlangui/dialogs/filedlg.d +++ b/src/dlangui/dialogs/filedlg.d @@ -606,6 +606,11 @@ class FileDialog : Dialog, CustomGridCellAdapter { } } + /// calls close with default action; returns true if default action is found and invoked + override protected bool closeWithDefaultAction() { + return handleAction(_action); + } + /// Custom handling of actions override bool handleAction(const Action action) { if (action.id == StandardAction.Cancel) { diff --git a/src/dlangui/dialogs/inputbox.d b/src/dlangui/dialogs/inputbox.d index ec308f9c..aeee2780 100644 --- a/src/dlangui/dialogs/inputbox.d +++ b/src/dlangui/dialogs/inputbox.d @@ -13,7 +13,7 @@ import dlangui.dialogs.dialog; class InputBox : Dialog { protected UIString _message; protected const(Action)[] _actions; - protected int _defaultButtonIndex; + protected EditLine _editor; protected dstring _text; this(UIString caption, UIString message, Window parentWindow, dstring initialText, void delegate(dstring result) handler) { super(caption, parentWindow, DialogFlag.Modal | (Platform.instance.uiDialogDisplayMode & DialogDisplayMode.inputBoxInPopup ? DialogFlag.Popup : 0)); @@ -34,15 +34,30 @@ class InputBox : Dialog { TextWidget msg = new MultilineTextWidget("msg", _message); padding(Rect(10, 10, 10, 10)); msg.padding(Rect(10, 10, 10, 10)); - EditLine editor = new EditLine("inputbox_editor"); - editor.layoutWidth = FILL_PARENT; - editor.text = _text; - editor.contentChange = delegate(EditableContent content) { + _editor = new EditLine("inputbox_editor"); + _editor.layoutWidth = FILL_PARENT; + _editor.text = _text; + _editor.editorAction.connect(&onEditorAction); + _editor.contentChange = delegate(EditableContent content) { _text = content.text; }; addChild(msg); - addChild(editor); + addChild(_editor); addChild(createButtonsPanel(_actions, _defaultButtonIndex, 0)); } + protected bool onEditorAction(const Action action) { + if (action.id == EditorActions.InsertNewLine) { + close(_buttonActions[_defaultButtonIndex]); + return true; + } + return false; + } + + /// called after window with dialog is shown + override void onShow() { + super.onShow(); + _editor.selectAll(); + _editor.setFocus(); + } } diff --git a/src/dlangui/dialogs/msgbox.d b/src/dlangui/dialogs/msgbox.d index 985d54d0..71a84489 100644 --- a/src/dlangui/dialogs/msgbox.d +++ b/src/dlangui/dialogs/msgbox.d @@ -41,7 +41,6 @@ import dlangui.dialogs.dialog; class MessageBox : Dialog { protected UIString _message; protected const(Action)[] _actions; - protected int _defaultButtonIndex; this(UIString caption, UIString message, Window parentWindow = null, const(Action) [] buttons = [ACTION_OK], int defaultButtonIndex = 0, bool delegate(const Action result) handler = null) { super(caption, parentWindow, DialogFlag.Modal | (Platform.instance.uiDialogDisplayMode & DialogDisplayMode.messageBoxInPopup ? DialogFlag.Popup : 0)); _message = message;