Ver Fonte

Added cycling focus with TAB key to UI.
Remove text selection from LineEdit when defocusing.

Lasse Öörni há 15 anos atrás
pai
commit
1d3e0bbe41

+ 8 - 4
Bin/Data/UI/TestLayout.xml

@@ -25,17 +25,17 @@
             <position value="40 130" />
         </element>
         <element type="Slider" name="ViewSliderV">
-            <position value="350 150" />
+            <position value="350 100" />
             <size value="10 100" />
             <orientation value="vertical" />
         </element>
         <element type="Slider" name="ViewSliderH">
-            <position value="150 250" />
+            <position value="150 200" />
             <size value="200 10" />
             <orientation value="horizontal" />
         </element>
         <element type="ScrollView">
-            <position value="150 150" />
+            <position value="150 100" />
             <size value="200 100" />
             <viewsize value="200 150" />
             <horizontalslider name="ViewSliderH" />
@@ -48,7 +48,11 @@
             </element>
         </element>
         <element type="LineEdit">
-            <position value="150 270" />
+            <position value="150 230" />
+            <size value="200 16" />
+        </element>
+        <element type="LineEdit">
+            <position value="150 260" />
             <size value="200 16" />
         </element>
         <element type="Window" name="TestPopup3">

+ 1 - 0
Engine/Engine/RegisterUI.cpp

@@ -146,6 +146,7 @@ static void registerText(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Text", "void setTextAlignment(HorizontalAlignment)", asMETHOD(Text, setTextAlignment), asCALL_THISCALL);
     engine->RegisterObjectMethod("Text", "void setRowSpacing(float)", asMETHOD(Text, setRowSpacing), asCALL_THISCALL);
     engine->RegisterObjectMethod("Text", "void setSelection(uint, uint)", asMETHOD(Text, setSelection), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Text", "void clearSelection()", asMETHOD(Text, clearSelection), asCALL_THISCALL);
     engine->RegisterObjectMethod("Text", "void setSelectionColor(const Color& in)", asMETHOD(Text, setSelectionColor), asCALL_THISCALL);
     engine->RegisterObjectMethod("Text", "void setHoverColor(const Color& in)", asMETHOD(Text, setHoverColor), asCALL_THISCALL);
     engine->RegisterObjectMethod("Text", "Font@+ getFont() const", asMETHOD(Text, getFont), asCALL_THISCALL);

+ 18 - 8
Engine/UI/LineEdit.cpp

@@ -137,7 +137,7 @@ void LineEdit::onClick(const IntVector2& position, const IntVector2& screenPosit
         if (pos != M_MAX_UNSIGNED)
         {
             setCursorPosition(pos);
-            mText->setSelection(0, 0);
+            mText->clearSelection();
         }
     }
 }
@@ -187,7 +187,7 @@ void LineEdit::onKey(int key, int buttons, int qualifiers)
                     mLine = mLine.substr(0, start) + mLine.substr(start + length);
                 else
                     mLine = mLine.substr(0, start);
-                mText->setSelection(0, 0);
+                mText->clearSelection();
                 mCursorPosition = start;
                 changed = true;
             }
@@ -211,7 +211,7 @@ void LineEdit::onKey(int key, int buttons, int qualifiers)
         
     case KEY_LEFT:
         if (!(qualifiers & QUAL_SHIFT))
-            mText->setSelection(0, 0);
+            mText->clearSelection();
         if ((mCursorMovable) && (mCursorPosition > 0))
         {
             if ((mTextSelectable) && (qualifiers & QUAL_SHIFT) && (!mText->getSelectionLength()))
@@ -237,7 +237,7 @@ void LineEdit::onKey(int key, int buttons, int qualifiers)
         
     case KEY_RIGHT:
         if (!(qualifiers & QUAL_SHIFT))
-            mText->setSelection(0, 0);
+            mText->clearSelection();
         if ((mCursorMovable) && (mCursorPosition < mLine.length()))
         {
             if ((mTextSelectable) && (qualifiers & QUAL_SHIFT) && (!mText->getSelectionLength()))
@@ -279,7 +279,7 @@ void LineEdit::onKey(int key, int buttons, int qualifiers)
                 mLine = mLine.substr(0, start) + mLine.substr(start + length);
             else
                 mLine = mLine.substr(0, start);
-            mText->setSelection(0, 0);
+            mText->clearSelection();
             changed = true;
         }
         break;
@@ -328,13 +328,13 @@ void LineEdit::onChar(unsigned char c, int buttons, int qualifiers)
         eventData[P_ELEMENT] = (void*)this;
         sendEvent(EVENT_TEXTFINISHED, eventData);
         
-        mText->setSelection(0, 0);
+        mText->clearSelection();
     }
     else if (c == 27)
     {
         if (mDefocusable)
         {
-            mText->setSelection(0, 0);
+            mText->clearSelection();
             mDefocus = true;
         }
     }
@@ -368,7 +368,7 @@ void LineEdit::onChar(unsigned char c, int buttons, int qualifiers)
     
     if (changed)
     {
-        mText->setSelection(0, 0);
+        mText->clearSelection();
         updateText();
         updateCursor();
         
@@ -381,6 +381,16 @@ void LineEdit::onChar(unsigned char c, int buttons, int qualifiers)
     }
 }
 
+void LineEdit::onFocus()
+{
+    updateCursor();
+}
+
+void LineEdit::onDefocus()
+{
+    mText->clearSelection();
+}
+
 void LineEdit::setText(const std::string& text)
 {
     mLine = text;

+ 4 - 0
Engine/UI/LineEdit.h

@@ -54,6 +54,10 @@ public:
     virtual void onKey(int key, int buttons, int qualifiers);
     //! React to a key press translated to a character
     virtual void onChar(unsigned char c, int buttons, int qualifiers);
+    //! React to gaining focus
+    virtual void onFocus();
+    //! React to losing focus
+    virtual void onDefocus();
     
     //! Set text
     void setText(const std::string& text);

+ 6 - 0
Engine/UI/Text.cpp

@@ -151,6 +151,12 @@ void Text::setSelection(unsigned start, unsigned length)
     validateSelection();
 }
 
+void Text::clearSelection()
+{
+    mSelectionStart = 0;
+    mSelectionLength = 0;
+}
+
 void Text::setSelectionColor(const Color& color)
 {
     mSelectionColor = color;

+ 2 - 0
Engine/UI/Text.h

@@ -58,6 +58,8 @@ public:
     void setRowSpacing(float spacing);
     //! Set selection
     void setSelection(unsigned start, unsigned length);
+    //! Clear selection
+    void clearSelection();
     //! Set selection background color. Color with 0 alpha (default) disables
     void setSelectionColor(const Color& color);
     //! Set hover background color. Color with 0 alpha (default) disables

+ 30 - 1
Engine/UI/UI.cpp

@@ -500,10 +500,39 @@ void UI::handleKeyDown(StringHash eventType, VariantMap& eventData)
     
     mMouseButtons = eventData[P_BUTTONS].getInt();
     mQualifiers = eventData[P_QUALIFIERS].getInt();
+    int key = eventData[P_KEY].getInt();
     
     UIElement* element = getFocusElement();
     if (element)
-        element->onKey(eventData[P_KEY].getInt(), mMouseButtons, mQualifiers);
+    {
+        if (key == KEY_TAB)
+        {
+            // Switch focus between focusable sibling elements
+            UIElement* parent = element->getParent();
+            if (parent)
+            {
+                std::vector<UIElement*> children = parent->getChildren();
+                for (std::vector<UIElement*>::iterator i = children.begin(); i != children.end();)
+                {
+                    if (!(*i)->isFocusable())
+                        i = children.erase(i);
+                    else
+                        ++i;
+                }
+                for (unsigned i = 0; i < children.size(); ++i)
+                {
+                    if (children[i] == element)
+                    {
+                        UIElement* next = children[(i + 1) % children.size()];
+                        setFocusElement(next);
+                        return;
+                    }
+                }
+            }
+        }
+        else
+            element->onKey(key, mMouseButtons, mQualifiers);
+    }
 }
 
 void UI::handleChar(StringHash eventType, VariantMap& eventData)

+ 13 - 0
Engine/UI/UIElement.cpp

@@ -258,6 +258,14 @@ void UIElement::onChar(unsigned char c, int buttons, int qualifiers)
 {
 }
 
+void UIElement::onFocus()
+{
+}
+
+void UIElement::onDefocus()
+{
+}
+
 void UIElement::setName(const std::string& name)
 {
     mName = name;
@@ -398,6 +406,11 @@ void UIElement::setFocus(bool enable)
     {
         mFocus = enable;
         
+        if (enable)
+            onFocus();
+        else
+            onDefocus();
+        
         using namespace Focused;
         
         VariantMap eventData;

+ 4 - 0
Engine/UI/UIElement.h

@@ -102,6 +102,10 @@ public:
     virtual void onKey(int key, int buttons, int qualifiers);
     //! React to a key press translated to a character
     virtual void onChar(unsigned char c, int buttons, int qualifiers);
+    //! React to gaining focus
+    virtual void onFocus();
+    //! React to losing focus
+    virtual void onDefocus();
     
     //! Set name
     void setName(const std::string& name);