Merge pull request #175 from default0/master

Change Textbox Behaviour
This commit is contained in:
Vadim Lopatin 2016-02-02 10:41:02 +03:00
commit b5b15d0b44
6 changed files with 37 additions and 13 deletions

View File

@ -467,6 +467,8 @@ enum State : uint {
WindowFocused = 256, WindowFocused = 256,
/// widget is default control for form (should be focused when window gains focus first time) /// widget is default control for form (should be focused when window gains focus first time)
Default = 512, // widget is default for form (e.g. default button will be focused on show) Default = 512, // widget is default for form (e.g. default button will be focused on show)
/// widget has been focused by keyboard navigation
KeyboardFocused = 1024,
/// return state of parent instead of widget's state when requested /// return state of parent instead of widget's state when requested
Parent = 0x10000, // use parent's state Parent = 0x10000, // use parent's state
} }

View File

@ -523,19 +523,22 @@ class Window : CustomEventTarget {
} }
/// change focus to widget /// change focus to widget
Widget setFocus(Widget newFocus) { Widget setFocus(Widget newFocus, FocusReason reason = FocusReason.Unspecified) {
if (!isChild(_focusedWidget)) if (!isChild(_focusedWidget))
_focusedWidget = null; _focusedWidget = null;
Widget oldFocus = _focusedWidget; Widget oldFocus = _focusedWidget;
auto targetState = State.Focused;
if(reason == FocusReason.TabFocus)
targetState = State.Focused | State.KeyboardFocused;
if (oldFocus is newFocus) if (oldFocus is newFocus)
return oldFocus; return oldFocus;
if (oldFocus !is null) if (oldFocus !is null)
oldFocus.resetState(State.Focused); oldFocus.resetState(targetState);
if (newFocus is null || isChild(newFocus)) { if (newFocus is null || isChild(newFocus)) {
if (newFocus !is null) { if (newFocus !is null) {
// when calling, setState(focused), window.focusedWidget is still previously focused widget // when calling, setState(focused), window.focusedWidget is still previously focused widget
debug(DebugFocus) Log.d("new focus: ", newFocus.id); debug(DebugFocus) Log.d("new focus: ", newFocus.id);
newFocus.setState(State.Focused); newFocus.setState(targetState);
} }
_focusedWidget = newFocus; _focusedWidget = newFocus;
// after focus change, ask for actions update automatically // after focus change, ask for actions update automatically

View File

@ -241,6 +241,9 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
protected int _iconsWidth = 0; protected int _iconsWidth = 0;
protected int _foldingWidth = 0; protected int _foldingWidth = 0;
protected bool _selectAllWhenFocusedWithTab = false;
protected bool _deselectAllWhenUnfocused = false;
protected bool _replaceMode; protected bool _replaceMode;
// TODO: move to styles // TODO: move to styles
@ -920,13 +923,20 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
} }
/// override to handle focus changes /// override to handle focus changes
override protected void handleFocusChange(bool focused) { override protected void handleFocusChange(bool focused, bool receivedFocusFromKeyboard = false) {
if (focused) if (focused)
startCaretBlinking(); startCaretBlinking();
else { else {
stopCaretBlinking(); stopCaretBlinking();
cancelHoverTimer(); cancelHoverTimer();
if(_deselectAllWhenUnfocused) {
_selectionRange.start = _caretPos;
_selectionRange.end = _caretPos;
} }
}
if(focused && _selectAllWhenFocusedWithTab && receivedFocusFromKeyboard)
handleAction(ACTION_EDITOR_SELECT_ALL);
super.handleFocusChange(focused); super.handleFocusChange(focused);
} }
@ -1643,7 +1653,9 @@ class EditWidgetBase : ScrollWidgetBase, EditableContentListener, MenuItemAction
if (event.doubleClick) { if (event.doubleClick) {
selectWordByMouse(event.x - _clientRect.left, event.y - _clientRect.top); selectWordByMouse(event.x - _clientRect.left, event.y - _clientRect.top);
} else { } else {
updateCaretPositionByMouse(event.x - _clientRect.left, event.y - _clientRect.top, false); auto doSelect = cast(bool)(event.keyFlags & MouseFlag.Shift);
updateCaretPositionByMouse(event.x - _clientRect.left, event.y - _clientRect.top, doSelect);
if (event.keyFlags == MouseFlag.Control) if (event.keyFlags == MouseFlag.Control)
onControlClick(); onControlClick();
} }
@ -1730,6 +1742,8 @@ class EditLine : EditWidgetBase {
super(ID, ScrollBarMode.Invisible, ScrollBarMode.Invisible); super(ID, ScrollBarMode.Invisible, ScrollBarMode.Invisible);
_content = new EditableContent(false); _content = new EditableContent(false);
_content.contentChanged = this; _content.contentChanged = this;
_selectAllWhenFocusedWithTab = true;
_deselectAllWhenUnfocused = true;
wantTabs = false; wantTabs = false;
styleId = STYLE_EDIT_LINE; styleId = STYLE_EDIT_LINE;
text = initialContent; text = initialContent;

View File

@ -732,7 +732,7 @@ class ListWidget : WidgetGroup, OnScrollHandler, OnAdapterChangeHandler {
} }
/// override to handle focus changes /// override to handle focus changes
override protected void handleFocusChange(bool focused) { override protected void handleFocusChange(bool focused, bool receivedFocusFromKeyboard = false) {
updateSelectedItemFocus(); updateSelectedItemFocus();
} }

View File

@ -887,7 +887,7 @@ class MainMenu : MenuWidgetBase {
} }
/// override to handle focus changes /// override to handle focus changes
override protected void handleFocusChange(bool focused) { override protected void handleFocusChange(bool focused, bool receivedFocusFromKeyboard = false) {
debug(DebugMenus) Log.d("menu ", id, "handling focus change to ", focused); debug(DebugMenus) Log.d("menu ", id, "handling focus change to ", focused);
if (focused && _openedPopup is null) { if (focused && _openedPopup is null) {
// activating! // activating!

View File

@ -71,6 +71,11 @@ enum Orientation : ubyte {
Horizontal Horizontal
} }
enum FocusReason : ubyte {
TabFocus,
Unspecified
}
/// interface - slot for onClick /// interface - slot for onClick
interface OnClickHandler { interface OnClickHandler {
bool onClick(Widget source); bool onClick(Widget source);
@ -280,7 +285,7 @@ public:
return _state | State.WindowFocused; // TODO: return _state | State.WindowFocused; // TODO:
} }
/// override to handle focus changes /// override to handle focus changes
protected void handleFocusChange(bool focused) { protected void handleFocusChange(bool focused, bool receivedFocusFromKeyboard = false) {
invalidate(); invalidate();
focusChange(this, focused); focusChange(this, focused);
} }
@ -300,7 +305,7 @@ public:
if ((oldState & State.Focused) && !(newState & State.Focused)) if ((oldState & State.Focused) && !(newState & State.Focused))
handleFocusChange(false); handleFocusChange(false);
else if (!(oldState & State.Focused) && (newState & State.Focused)) else if (!(oldState & State.Focused) && (newState & State.Focused))
handleFocusChange(true); handleFocusChange(true, cast(bool)(newState & State.KeyboardFocused));
// notify checked changes // notify checked changes
if ((oldState & State.Checked) && !(newState & State.Checked)) if ((oldState & State.Checked) && !(newState & State.Checked))
handleCheckChange(false); handleCheckChange(false);
@ -990,7 +995,7 @@ public:
Widget nextWidget = findNextFocusWidget(direction); Widget nextWidget = findNextFocusWidget(direction);
if (!nextWidget) if (!nextWidget)
return false; return false;
nextWidget.setFocus(); nextWidget.setFocus(FocusReason.TabFocus);
return true; return true;
} }
@ -1009,7 +1014,7 @@ public:
} }
/// sets focus to this widget or suitable focusable child, returns previously focused widget /// sets focus to this widget or suitable focusable child, returns previously focused widget
Widget setFocus() { Widget setFocus(FocusReason reason = FocusReason.Unspecified) {
if (window is null) if (window is null)
return null; return null;
if (!visible) if (!visible)
@ -1020,11 +1025,11 @@ public:
if (!w) if (!w)
w = findFocusableChild(false); w = findFocusableChild(false);
if (w) if (w)
return window.setFocus(w); return window.setFocus(w, reason);
// try to find focusable child // try to find focusable child
return window.focusedWidget; return window.focusedWidget;
} }
return window.setFocus(this); return window.setFocus(this, reason);
} }
/// searches children for first focusable item, returns null if not found /// searches children for first focusable item, returns null if not found
Widget findFocusableChild(bool defaultOnly) { Widget findFocusableChild(bool defaultOnly) {