Dialogs standard Ctrl+Enter and Esc key handling; InputBox focus and Enter key action fixes - close #429, close #430

This commit is contained in:
Vadim Lopatin 2017-09-12 11:00:50 +03:00
parent 1b82ea8d6a
commit a4a44b73bf
5 changed files with 66 additions and 8 deletions

View File

@ -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) {

View File

@ -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

View File

@ -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) {

View File

@ -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();
}
}

View File

@ -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;