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; } @property dstring text() { return _text; }
/// returns true if no modifier flags are set /// 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 /// returns true if any modifier flag is set
@property bool hasModifiers() { return !noModifiers; } @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 /// create key event
this(KeyAction action, uint keyCode, uint flags, dstring text = null) { this(KeyAction action, uint keyCode, uint flags, dstring text = null) {

View File

@ -55,6 +55,7 @@ class Dialog : VerticalLayout {
protected string _icon; protected string _icon;
protected int _initialWidth; protected int _initialWidth;
protected int _initialHeight; protected int _initialHeight;
protected int _defaultButtonIndex = -1;
Signal!DialogResultHandler dialogResult; Signal!DialogResultHandler dialogResult;
@ -124,6 +125,7 @@ class Dialog : VerticalLayout {
protected ImageTextButton _cancelButton; protected ImageTextButton _cancelButton;
/// create panel with buttons based on list of actions /// create panel with buttons based on list of actions
Widget createButtonsPanel(const(Action) [] actions, int defaultActionIndex, int splitBeforeIndex) { Widget createButtonsPanel(const(Action) [] actions, int defaultActionIndex, int splitBeforeIndex) {
_defaultButtonIndex = defaultActionIndex;
_buttonActions = actions; _buttonActions = actions;
LinearLayout res = new HorizontalLayout("buttons"); LinearLayout res = new HorizontalLayout("buttons");
res.layoutWidth(FILL_PARENT); res.layoutWidth(FILL_PARENT);
@ -229,6 +231,41 @@ class Dialog : VerticalLayout {
if (_defaultButton) if (_defaultButton)
_defaultButton.setFocus(); _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 /// 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 /// Custom handling of actions
override bool handleAction(const Action action) { override bool handleAction(const Action action) {
if (action.id == StandardAction.Cancel) { if (action.id == StandardAction.Cancel) {

View File

@ -13,7 +13,7 @@ import dlangui.dialogs.dialog;
class InputBox : Dialog { class InputBox : Dialog {
protected UIString _message; protected UIString _message;
protected const(Action)[] _actions; protected const(Action)[] _actions;
protected int _defaultButtonIndex; protected EditLine _editor;
protected dstring _text; protected dstring _text;
this(UIString caption, UIString message, Window parentWindow, dstring initialText, void delegate(dstring result) handler) { 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)); 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); TextWidget msg = new MultilineTextWidget("msg", _message);
padding(Rect(10, 10, 10, 10)); padding(Rect(10, 10, 10, 10));
msg.padding(Rect(10, 10, 10, 10)); msg.padding(Rect(10, 10, 10, 10));
EditLine editor = new EditLine("inputbox_editor"); _editor = new EditLine("inputbox_editor");
editor.layoutWidth = FILL_PARENT; _editor.layoutWidth = FILL_PARENT;
editor.text = _text; _editor.text = _text;
editor.contentChange = delegate(EditableContent content) { _editor.editorAction.connect(&onEditorAction);
_editor.contentChange = delegate(EditableContent content) {
_text = content.text; _text = content.text;
}; };
addChild(msg); addChild(msg);
addChild(editor); addChild(_editor);
addChild(createButtonsPanel(_actions, _defaultButtonIndex, 0)); 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 { class MessageBox : Dialog {
protected UIString _message; protected UIString _message;
protected const(Action)[] _actions; 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) { 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)); super(caption, parentWindow, DialogFlag.Modal | (Platform.instance.uiDialogDisplayMode & DialogDisplayMode.messageBoxInPopup ? DialogFlag.Popup : 0));
_message = message; _message = message;