diff --git a/include/eepp/scene/event.hpp b/include/eepp/scene/event.hpp index 7669add13..51146c428 100644 --- a/include/eepp/scene/event.hpp +++ b/include/eepp/scene/event.hpp @@ -1,7 +1,8 @@ -#ifndef EE_UICUIEVENT_HPP -#define EE_UICUIEVENT_HPP +#ifndef EE_SCENE_EVENT_HPP +#define EE_SCENE_EVENT_HPP #include +#include #include namespace EE { namespace UI { @@ -19,6 +20,7 @@ class TextInputEvent; class WindowEvent; class ItemValueEvent; class RowCreatedEvent; +class FocusEvent; class EE_API Event { public: @@ -141,6 +143,8 @@ class EE_API Event { const RowCreatedEvent* asRowCreatedEvent() const; + const FocusEvent* asFocusEvent() const; + protected: friend class Node; Node* mNode; @@ -200,6 +204,17 @@ class EE_API RowCreatedEvent : public Event { UI::UITableRow* row; }; +class EE_API FocusEvent : public Event { + public: + FocusEvent( Node* node, const Uint32& EventNum, NodeFocusReason reason ) : + Event( node, EventNum ), mReason( reason ) {} + + const NodeFocusReason& getReason() const { return mReason; } + + protected: + NodeFocusReason mReason; +}; + }} // namespace EE::Scene #endif diff --git a/include/eepp/scene/eventdispatcher.hpp b/include/eepp/scene/eventdispatcher.hpp index 26c7d75f2..11f521f7d 100644 --- a/include/eepp/scene/eventdispatcher.hpp +++ b/include/eepp/scene/eventdispatcher.hpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include using namespace EE::System; using namespace EE::Math; @@ -38,7 +38,7 @@ class EE_API EventDispatcher { Node* getFocusNode() const; - void setFocusNode( Node* node ); + void setFocusNode( Node* node, NodeFocusReason reason = NodeFocusReason::Unknown ); Node* getMouseOverNode() const; diff --git a/include/eepp/scene/node.hpp b/include/eepp/scene/node.hpp index 14c04702b..07450ac97 100644 --- a/include/eepp/scene/node.hpp +++ b/include/eepp/scene/node.hpp @@ -357,7 +357,7 @@ class EE_API Node : public Transformable { bool hasFocusWithin() const; - virtual Node* setFocus(); + virtual Node* setFocus( NodeFocusReason reason = NodeFocusReason::Unknown ); Node* getFirstWidget() const; @@ -546,7 +546,7 @@ class EE_API Node : public Transformable { virtual void onSceneChange(); - virtual Uint32 onFocus(); + virtual Uint32 onFocus( NodeFocusReason reason ); virtual Uint32 onFocusLoss(); diff --git a/include/eepp/scene/nodefocusreason.hpp b/include/eepp/scene/nodefocusreason.hpp new file mode 100644 index 000000000..de7a11802 --- /dev/null +++ b/include/eepp/scene/nodefocusreason.hpp @@ -0,0 +1,10 @@ +#ifndef EE_SCENE_NODEFOCUSREASON_HPP +#define EE_SCENE_NODEFOCUSREASON_HPP + +namespace EE { namespace Scene { + +enum class NodeFocusReason { Unknown, Click, Tab }; + +}} // namespace EE::Scene + +#endif // EE_SCENE_NODEFOCUSREASON_HPP diff --git a/include/eepp/ui/abstract/uiabstracttableview.hpp b/include/eepp/ui/abstract/uiabstracttableview.hpp index 3d09c7428..306a1952b 100644 --- a/include/eepp/ui/abstract/uiabstracttableview.hpp +++ b/include/eepp/ui/abstract/uiabstracttableview.hpp @@ -184,7 +184,7 @@ class EE_API UIAbstractTableView : public UIAbstractView { virtual void updateColumnsWidth(); - virtual Uint32 onFocus(); + virtual Uint32 onFocus( NodeFocusReason reason ); virtual Uint32 onFocusLoss(); diff --git a/include/eepp/ui/uicodeeditor.hpp b/include/eepp/ui/uicodeeditor.hpp index d6b3f6084..175c7ba47 100644 --- a/include/eepp/ui/uicodeeditor.hpp +++ b/include/eepp/ui/uicodeeditor.hpp @@ -768,7 +768,7 @@ class EE_API UICodeEditor : public UIWidget, public TextDocument::Client { std::pair findLongestLineInRange( const TextRange& range ); - virtual Uint32 onFocus(); + virtual Uint32 onFocus( NodeFocusReason reason ); virtual Uint32 onFocusLoss(); diff --git a/include/eepp/ui/uiconsole.hpp b/include/eepp/ui/uiconsole.hpp index 4d1488163..153f28f9f 100644 --- a/include/eepp/ui/uiconsole.hpp +++ b/include/eepp/ui/uiconsole.hpp @@ -218,7 +218,7 @@ class EE_API UIConsole : public UIWidget, virtual Uint32 onMouseUp( const Vector2i& position, const Uint32& flags ); - virtual Uint32 onFocus(); + virtual Uint32 onFocus( NodeFocusReason reason ); virtual Uint32 onFocusLoss(); diff --git a/include/eepp/ui/uinode.hpp b/include/eepp/ui/uinode.hpp index 63f00d5f5..d160d2061 100644 --- a/include/eepp/ui/uinode.hpp +++ b/include/eepp/ui/uinode.hpp @@ -235,7 +235,7 @@ class EE_API UINode : public Node { const Uint32& getDragButton() const; - virtual Node* setFocus(); + virtual Node* setFocus( NodeFocusReason reason = NodeFocusReason::Unknown ); Float getPropertyRelativeTargetContainerLength( const CSS::PropertyRelativeTarget& relativeTarget, @@ -382,7 +382,7 @@ class EE_API UINode : public Node { virtual Uint32 onMouseLeave( const Vector2i& position, const Uint32& flags ); - virtual Uint32 onFocus(); + virtual Uint32 onFocus( NodeFocusReason reason ); virtual Uint32 onFocusLoss(); diff --git a/include/eepp/ui/uiscenenode.hpp b/include/eepp/ui/uiscenenode.hpp index bb4b3bd1a..2e8e53788 100644 --- a/include/eepp/ui/uiscenenode.hpp +++ b/include/eepp/ui/uiscenenode.hpp @@ -197,7 +197,7 @@ class EE_API UISceneNode : public SceneNode { virtual void onDrawDebugDataChange(); - virtual Node* setFocus(); + virtual Node* setFocus( NodeFocusReason reason = NodeFocusReason::Unknown); virtual void onParentChange(); diff --git a/include/eepp/ui/uitablecell.hpp b/include/eepp/ui/uitablecell.hpp index d4ad01585..4587e6b0b 100644 --- a/include/eepp/ui/uitablecell.hpp +++ b/include/eepp/ui/uitablecell.hpp @@ -58,9 +58,9 @@ class EE_API UITableCell : public UIPushButton { virtual void onModelIndexChange() {} - Uint32 onFocus() { + Uint32 onFocus( NodeFocusReason reason ) { getUISceneNode()->getWindow()->startTextInput(); - return UIPushButton::onFocus(); + return UIPushButton::onFocus( reason ); } Uint32 onFocusLoss() { diff --git a/include/eepp/ui/uitextinput.hpp b/include/eepp/ui/uitextinput.hpp index b281de7de..51f05798a 100644 --- a/include/eepp/ui/uitextinput.hpp +++ b/include/eepp/ui/uitextinput.hpp @@ -119,6 +119,10 @@ class EE_API UITextInput : public UITextView, public TextDocument::Client { HintDisplay getHintDisplay() const; + bool getSelectAllDocOnTabNavigate() const; + + void setSelectAllDocOnTabNavigate( bool selectAllDocOnTabNavigate ); + protected: TextDocument mDoc; Float mWaitCursorTime; @@ -134,6 +138,7 @@ class EE_API UITextInput : public UITextView, public TextDocument::Client { bool mCreateDefaultContextMenuOptions{ true }; bool mEscapePastedText{ false }; bool mEnabledCreateContextMenu{ true }; + bool mSelectAllDocOnTabNavigate{ true }; Uint32 mMaxLength{ 0 }; KeyBindings mKeyBindings; Clock mLastDoubleClick; @@ -164,7 +169,7 @@ class EE_API UITextInput : public UITextView, public TextDocument::Client { virtual Uint32 onMouseLeave( const Vector2i& position, const Uint32& flags ); - virtual Uint32 onFocus(); + virtual Uint32 onFocus( NodeFocusReason reason ); virtual Uint32 onFocusLoss(); @@ -206,9 +211,9 @@ class EE_API UITextInput : public UITextView, public TextDocument::Client { virtual void onDocumentMoved( TextDocument* ); - void onDocumentClosed( TextDocument* ){}; + void onDocumentClosed( TextDocument* ) {}; - void onDocumentDirtyOnFileSystem( TextDocument* ){}; + void onDocumentDirtyOnFileSystem( TextDocument* ) {}; void registerKeybindings(); diff --git a/include/eepp/ui/uiwidget.hpp b/include/eepp/ui/uiwidget.hpp index a35eaba20..c400968e6 100644 --- a/include/eepp/ui/uiwidget.hpp +++ b/include/eepp/ui/uiwidget.hpp @@ -349,7 +349,7 @@ class EE_API UIWidget : public UINode { virtual void onFocusNextWidget(); - virtual Uint32 onFocus(); + virtual Uint32 onFocus( NodeFocusReason reason ); virtual Uint32 onFocusLoss(); diff --git a/projects/linux/ee.files b/projects/linux/ee.files index b4e6542e9..79e0a58ad 100644 --- a/projects/linux/ee.files +++ b/projects/linux/ee.files @@ -228,6 +228,7 @@ ../../include/eepp/scene/keyevent.hpp ../../include/eepp/scene/mouseevent.hpp ../../include/eepp/scene/node.hpp +../../include/eepp/scene/nodefocusreason.hpp ../../include/eepp/scene/nodemessage.hpp ../../include/eepp/scene/scenemanager.hpp ../../include/eepp/scene/scenenode.hpp diff --git a/src/eepp/scene/event.cpp b/src/eepp/scene/event.cpp index 95bf0d9bf..3359a70be 100644 --- a/src/eepp/scene/event.cpp +++ b/src/eepp/scene/event.cpp @@ -53,4 +53,8 @@ const RowCreatedEvent* Event::asRowCreatedEvent() const { return static_cast( this ); } +const FocusEvent* Event::asFocusEvent() const { + return static_cast( this ); +} + }} // namespace EE::Scene diff --git a/src/eepp/scene/eventdispatcher.cpp b/src/eepp/scene/eventdispatcher.cpp index 09ae09829..0f2ea4d90 100644 --- a/src/eepp/scene/eventdispatcher.cpp +++ b/src/eepp/scene/eventdispatcher.cpp @@ -133,7 +133,7 @@ void EventDispatcher::update( const Time& time ) { if ( NULL != mFocusNode && mDownNode == mOverNode && ( mInput->getPressTrigger() & ( EE_BUTTON_LMASK | EE_BUTTON_RMASK ) ) && ( !nodeWasDragging || mMousePos == mLastMousePos ) ) { - setFocusNode( mOverNode ); + setFocusNode( mOverNode, NodeFocusReason::Click ); } } else if ( NULL != mOverNode && mInput->getReleaseTrigger() && !( mInput->getPressTrigger() & mInput->getReleaseTrigger() ) && @@ -149,7 +149,7 @@ void EventDispatcher::update( const Time& time ) { if ( NULL != mFocusNode && mDownNode == mOverNode && ( mInput->getReleaseTrigger() & ( EE_BUTTON_LMASK | EE_BUTTON_RMASK ) ) && ( !nodeWasDragging || mMousePos == mLastMousePos ) ) { - setFocusNode( mOverNode ); + setFocusNode( mOverNode, NodeFocusReason::Click ); } } @@ -291,7 +291,7 @@ void EventDispatcher::sendMouseDown( Node* toNode, const Vector2i& pos, const Ui toNode->onMouseDown( pos, flags ); } -void EventDispatcher::setFocusNode( Node* node ) { +void EventDispatcher::setFocusNode( Node* node, NodeFocusReason reason ) { if ( NULL != mFocusNode && NULL != node && node != mFocusNode ) { mWindow->getIME().stop(); @@ -302,7 +302,7 @@ void EventDispatcher::setFocusNode( Node* node ) { mLossFocusNode->onFocusLoss(); sendMsg( mLossFocusNode, NodeMessage::FocusLoss ); - mFocusNode->onFocus(); + mFocusNode->onFocus( reason ); sendMsg( mFocusNode, NodeMessage::Focus ); if ( !mFocusCbs.empty() ) { diff --git a/src/eepp/scene/node.cpp b/src/eepp/scene/node.cpp index 413814a94..78f2a10f0 100644 --- a/src/eepp/scene/node.cpp +++ b/src/eepp/scene/node.cpp @@ -1646,10 +1646,11 @@ void Node::setRotationOrigin( float x, float y ) { setRotationOriginPoint( OriginPoint( x, y ) ); } -Uint32 Node::onFocus() { +Uint32 Node::onFocus( NodeFocusReason reason ) { mNodeFlags |= NODE_FLAG_HAS_FOCUS; - sendCommonEvent( Event::OnFocus ); + FocusEvent event( this, Event::OnFocus, reason ); + sendEvent( &event ); invalidateDraw(); @@ -1674,7 +1675,7 @@ bool Node::hasFocusWithin() const { return hasFocus() || inParentTreeOf( getEventDispatcher()->getFocusNode() ); } -Node* Node::setFocus() { +Node* Node::setFocus( NodeFocusReason ) { return this; } diff --git a/src/eepp/ui/abstract/uiabstracttableview.cpp b/src/eepp/ui/abstract/uiabstracttableview.cpp index 358003f3b..21aa47533 100644 --- a/src/eepp/ui/abstract/uiabstracttableview.cpp +++ b/src/eepp/ui/abstract/uiabstracttableview.cpp @@ -338,10 +338,10 @@ void UIAbstractTableView::updateColumnsWidth() { } } -Uint32 UIAbstractTableView::onFocus() { +Uint32 UIAbstractTableView::onFocus( NodeFocusReason reason ) { if ( !Sys::isMobile() ) getUISceneNode()->getWindow()->startTextInput(); - return UIAbstractView::onFocus(); + return UIAbstractView::onFocus( reason ); } Uint32 UIAbstractTableView::onFocusLoss() { diff --git a/src/eepp/ui/tools/uidocfindreplace.cpp b/src/eepp/ui/tools/uidocfindreplace.cpp index 20a5fa4cf..df7a190f0 100644 --- a/src/eepp/ui/tools/uidocfindreplace.cpp +++ b/src/eepp/ui/tools/uidocfindreplace.cpp @@ -289,6 +289,8 @@ UIDocFindReplace::UIDocFindReplace( UIWidget* parent, const std::shared_ptrsetTabStop(); mReplaceInput->setTabStop(); + mFindInput->setSelectAllDocOnTabNavigate( false ); + mReplaceInput->setSelectAllDocOnTabNavigate( false ); mFindInput->addEventListener( Event::OnTabNavigate, [this]( const Event* ) { if ( mReplaceDisabled ) return; diff --git a/src/eepp/ui/uicodeeditor.cpp b/src/eepp/ui/uicodeeditor.cpp index 3379b23f3..9dfd43b1d 100644 --- a/src/eepp/ui/uicodeeditor.cpp +++ b/src/eepp/ui/uicodeeditor.cpp @@ -882,7 +882,7 @@ void UICodeEditor::invalidateLongestLineWidth() { mLongestLineWidthLastUpdate.restart(); } -Uint32 UICodeEditor::onFocus() { +Uint32 UICodeEditor::onFocus( NodeFocusReason reason ) { if ( !mLocked ) { mLastExecuteEventId = getUISceneNode()->getWindow()->getInput()->getEventsSentId(); resetCursor(); @@ -893,7 +893,7 @@ Uint32 UICodeEditor::onFocus() { for ( auto& plugin : mPlugins ) plugin->onFocus( this ); mLastActivity.restart(); - return UIWidget::onFocus(); + return UIWidget::onFocus( reason ); } Uint32 UICodeEditor::onFocusLoss() { diff --git a/src/eepp/ui/uiconsole.cpp b/src/eepp/ui/uiconsole.cpp index b05752621..93640d5a4 100644 --- a/src/eepp/ui/uiconsole.cpp +++ b/src/eepp/ui/uiconsole.cpp @@ -1019,8 +1019,8 @@ void UIConsole::resetCursor() { mBlinkTimer.restart(); } -Uint32 UIConsole::onFocus() { - UIWidget::onFocus(); +Uint32 UIConsole::onFocus( NodeFocusReason reason ) { + UIWidget::onFocus( reason ); resetCursor(); diff --git a/src/eepp/ui/uinode.cpp b/src/eepp/ui/uinode.cpp index 053e6ddac..4bdb4187c 100644 --- a/src/eepp/ui/uinode.cpp +++ b/src/eepp/ui/uinode.cpp @@ -1559,9 +1559,9 @@ void UINode::onWidgetFocusLoss() { invalidateDraw(); } -Node* UINode::setFocus() { +Node* UINode::setFocus( NodeFocusReason reason ) { if ( NULL != getEventDispatcher() ) - getEventDispatcher()->setFocusNode( this ); + getEventDispatcher()->setFocusNode( this, reason ); return this; } @@ -1646,10 +1646,10 @@ Float UINode::lengthFromValueAsDp( const CSS::StyleSheetProperty& property, property.getIndex() ); } -Uint32 UINode::onFocus() { +Uint32 UINode::onFocus( NodeFocusReason reason ) { pushState( UIState::StateFocus ); - return Node::onFocus(); + return Node::onFocus( reason ); } Uint32 UINode::onFocusLoss() { diff --git a/src/eepp/ui/uiscenenode.cpp b/src/eepp/ui/uiscenenode.cpp index 606cdc4ca..971fefb67 100644 --- a/src/eepp/ui/uiscenenode.cpp +++ b/src/eepp/ui/uiscenenode.cpp @@ -106,9 +106,9 @@ void UISceneNode::onDrawDebugDataChange() { } } -Node* UISceneNode::setFocus() { +Node* UISceneNode::setFocus( NodeFocusReason reason ) { if ( NULL != getEventDispatcher() ) - getEventDispatcher()->setFocusNode( mRoot ); + getEventDispatcher()->setFocusNode( mRoot, reason ); return this; } diff --git a/src/eepp/ui/uitextinput.cpp b/src/eepp/ui/uitextinput.cpp index 55d8721c1..58b7486f4 100644 --- a/src/eepp/ui/uitextinput.cpp +++ b/src/eepp/ui/uitextinput.cpp @@ -162,8 +162,8 @@ void UITextInput::draw() { } } -Uint32 UITextInput::onFocus() { - UIWidget::onFocus(); +Uint32 UITextInput::onFocus( NodeFocusReason reason ) { + UIWidget::onFocus( reason ); if ( mAllowEditing ) { resetWaitCursor(); @@ -175,6 +175,9 @@ Uint32 UITextInput::onFocus() { updateIMELocation(); } + if ( mSelectAllDocOnTabNavigate && reason == NodeFocusReason::Tab ) + mDoc.selectAll(); + return 1; } @@ -960,4 +963,12 @@ HintDisplay UITextInput::getHintDisplay() const { return mHintDisplay; } +bool UITextInput::getSelectAllDocOnTabNavigate() const { + return mSelectAllDocOnTabNavigate; +} + +void UITextInput::setSelectAllDocOnTabNavigate( bool selectAllDocOnTabNavigate ) { + mSelectAllDocOnTabNavigate = selectAllDocOnTabNavigate; +} + }} // namespace EE::UI diff --git a/src/eepp/ui/uiwidget.cpp b/src/eepp/ui/uiwidget.cpp index 9309ef3b9..0569a9230 100644 --- a/src/eepp/ui/uiwidget.cpp +++ b/src/eepp/ui/uiwidget.cpp @@ -1040,7 +1040,7 @@ void UIWidget::popState( const Uint32& State, bool emitEvent ) { } } -Uint32 UIWidget::onFocus() { +Uint32 UIWidget::onFocus( NodeFocusReason reason ) { pushState( UIState::StateFocusWithin ); Node* parent = mParentNode; @@ -1050,7 +1050,7 @@ Uint32 UIWidget::onFocus() { parent = parent->getParent(); } - return UINode::onFocus(); + return UINode::onFocus( reason ); } Uint32 UIWidget::onFocusLoss() { @@ -2218,7 +2218,7 @@ void UIWidget::onFocusPrevWidget() { if ( !isTabStop() ) { Node* node = getPrevTabWidget(); if ( NULL != node ) { - node->setFocus(); + node->setFocus( NodeFocusReason::Tab ); sendCommonEvent( Event::OnTabNavigate ); } } else { @@ -2230,7 +2230,7 @@ void UIWidget::onFocusNextWidget() { if ( !isTabStop() ) { Node* node = getNextTabWidget(); if ( NULL != node ) { - node->setFocus(); + node->setFocus( NodeFocusReason::Tab ); sendCommonEvent( Event::OnTabNavigate ); } } else { diff --git a/src/modules/eterm/include/eterm/ui/uiterminal.hpp b/src/modules/eterm/include/eterm/ui/uiterminal.hpp index 068c78b1c..a88f4cd3b 100644 --- a/src/modules/eterm/include/eterm/ui/uiterminal.hpp +++ b/src/modules/eterm/include/eterm/ui/uiterminal.hpp @@ -155,7 +155,7 @@ class UITerminal : public UIWidget { virtual void onPaddingChange(); - virtual Uint32 onFocus(); + virtual Uint32 onFocus( NodeFocusReason reason ); virtual Uint32 onFocusLoss(); diff --git a/src/modules/eterm/src/eterm/ui/uiterminal.cpp b/src/modules/eterm/src/eterm/ui/uiterminal.cpp index 38e779a7b..25f0b2e14 100644 --- a/src/modules/eterm/src/eterm/ui/uiterminal.cpp +++ b/src/modules/eterm/src/eterm/ui/uiterminal.cpp @@ -512,13 +512,13 @@ void UITerminal::onSizeChange() { UIWidget::onSizeChange(); } -Uint32 UITerminal::onFocus() { +Uint32 UITerminal::onFocus( NodeFocusReason reason ) { getUISceneNode()->getWindow()->startTextInput(); updateScreenPos(); mTerm->setPosition( mScreenPosi.asFloat() ); mTerm->setFocus( true ); invalidateDraw(); - return UIWidget::onFocus(); + return UIWidget::onFocus( reason ); } Uint32 UITerminal::onFocusLoss() { diff --git a/src/tools/ecode/docsearchcontroller.cpp b/src/tools/ecode/docsearchcontroller.cpp index 4c0b56b6d..01a6c7300 100644 --- a/src/tools/ecode/docsearchcontroller.cpp +++ b/src/tools/ecode/docsearchcontroller.cpp @@ -158,6 +158,9 @@ void DocSearchController::initSearchBar( addClickListener( findReplaceButton, "find-and-replace" ); addClickListener( replaceAllButton, "replace-all" ); addClickListener( closeButton, "close-searchbar" ); + + mFindInput->setSelectAllDocOnTabNavigate( false ); + mReplaceInput->setSelectAllDocOnTabNavigate( false ); mReplaceInput->addEventListener( Event::OnTabNavigate, [this]( const Event* ) { mFindInput->setFocus(); } ); } diff --git a/src/tools/ecode/globalsearchcontroller.cpp b/src/tools/ecode/globalsearchcontroller.cpp index 0aae91630..f0d1a5816 100644 --- a/src/tools/ecode/globalsearchcontroller.cpp +++ b/src/tools/ecode/globalsearchcontroller.cpp @@ -248,6 +248,8 @@ void GlobalSearchController::initGlobalSearchBar( mGlobalSearchTree->forceKeyDown( keyEvent ); } }; + mGlobalSearchInput->setSelectAllDocOnTabNavigate( false ); + mGlobalSearchWhereInput->setSelectAllDocOnTabNavigate( false ); mGlobalSearchInput->on( Event::OnPressEnter, pressEnterCb ); mGlobalSearchWhereInput->on( Event::OnPressEnter, pressEnterCb ); mGlobalSearchWhereInput->on( Event::OnTabNavigate,