Browse Source

LineEdit scrolling fix and code cleanup.
Removed the HoverColor feature from UIElement, as it is rarely useful.
If Text has nonzero max line width, it also fixes the element width.

Lasse Öörni 15 years ago
parent
commit
3dddb2be16

+ 0 - 2
Engine/Engine/RegisterTemplates.h

@@ -406,7 +406,6 @@ template <class T> void registerUIElement(asIScriptEngine* engine, const char* c
     engine->RegisterObjectMethod(className, "void setClipBorder(int, int, int, int)", asMETHODPR(T, setClipBorder, (int, int, int, int), void), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void setColor(const Color& in)", asMETHODPR(T, setColor, (const Color&), void), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void setColor(UIElementCorner, const Color& in)", asMETHODPR(T, setColor, (UIElementCorner, const Color&), void), asCALL_THISCALL);
-    engine->RegisterObjectMethod(className, "void setHoverColor(const Color& in)", asMETHOD(T, setHoverColor), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void setPriority(int)", asMETHOD(T, setPriority), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void setOpacity(float)", asMETHOD(T, setOpacity), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void setBringToFront(bool)", asMETHOD(T, setBringToFront), asCALL_THISCALL);
@@ -435,7 +434,6 @@ template <class T> void registerUIElement(asIScriptEngine* engine, const char* c
     engine->RegisterObjectMethod(className, "VerticalAlignment getVerticalAlignment() const", asMETHOD(T, getVerticalAlignment), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "const IntRect& getClipBorder() const", asMETHOD(T, getClipBorder), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "const Color& getColor(UIElementCorner) const", asMETHOD(T, getColor), asCALL_THISCALL);
-    engine->RegisterObjectMethod(className, "const Color& getHoverColor() const", asMETHOD(T, getHoverColor), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "int getPriority() const", asMETHOD(T, getPriority), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "float getOpacity() const", asMETHOD(T, getOpacity), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "bool getBringToFront() const", asMETHOD(T, getBringToFront), asCALL_THISCALL);

+ 48 - 31
Engine/UI/LineEdit.cpp

@@ -31,6 +31,8 @@
 
 LineEdit::LineEdit(const std::string& name, const std::string& text) :
     BorderImage(name),
+    mLastFont(0),
+    mLastFontSize(0),
     mCursorPosition(0),
     mCursorBlinkRate(1.0f),
     mCursorBlinkTimer(0.0f),
@@ -90,32 +92,17 @@ void LineEdit::update(float timeStep)
     else
         mCursorBlinkTimer = 0.0f;
     
+    // Update cursor position if font has changed
+    if ((mText->getFont() != mLastFont) || (mText->getFontSize() != mLastFontSize))
+    {
+        mLastFont = mText->getFont();
+        mLastFontSize = mText->getFontSize();
+        updateCursor();
+    }
+   
     bool cursorVisible = false;
-    
     if (mFocus)
-    {
-        int x;
-        const std::vector<IntVector2>& charPositions = mText->getCharPositions();
-        if (charPositions.size())
-            x = mCursorPosition < charPositions.size() ? charPositions[mCursorPosition].mX : charPositions.back().mX;
-        else
-            x = 0;
-        
-        // This assumes text alignment is top-left
-        mCursor->setPosition(mText->getPosition() + IntVector2(x, 0));
-        mCursor->setSize(mCursor->getWidth(), mText->getRowHeight());
         cursorVisible = mCursorBlinkTimer < 0.5f;
-        
-        // Scroll if text is longer than what can be visible at once
-        int scrollThreshold = max(getWidth() - mClipBorder.mLeft - mClipBorder.mRight - mCursor->getWidth(), 0);
-        if (x > scrollThreshold)
-            setChildOffset(IntVector2(-x + scrollThreshold, 0));
-        else
-            setChildOffset(IntVector2::sZero);
-    }
-    else
-        setChildOffset(IntVector2::sZero);
-    
     mCursor->setVisible(cursorVisible);
     
     if (mDefocus)
@@ -135,7 +122,7 @@ void LineEdit::onClick(const IntVector2& position, const IntVector2& screenPosit
         {
             if (textPosition.mX >= charPositions[i].mX)
             {
-                mCursorPosition = i;
+                setCursorPosition(i);
                 break;
             }
         }
@@ -177,13 +164,10 @@ void LineEdit::onKey(int key)
         break;
     }
     
-    // Restart cursor blinking from the visible state
-    if (cursorMoved)
-        mCursorBlinkTimer = 0.0f;
-    
     if (changed)
     {
         updateText();
+        updateCursor();
         
         using namespace TextChanged;
         
@@ -192,6 +176,8 @@ void LineEdit::onKey(int key)
         eventData[P_TEXT] = mLine;
         sendEvent(EVENT_TEXTCHANGED, eventData);
     }
+    else if (cursorMoved)
+        updateCursor();
 }
 
 void LineEdit::onChar(unsigned char c)
@@ -238,9 +224,8 @@ void LineEdit::onChar(unsigned char c)
     
     if (changed)
     {
-        // Restart cursor blinking from the visible state
-        mCursorBlinkTimer = 0.0f;
         updateText();
+        updateCursor();
         
         using namespace TextChanged;
         
@@ -262,7 +247,12 @@ void LineEdit::setCursorPosition(unsigned position)
 {
     if (position > mLine.length())
         position = mLine.length();
-    mCursorPosition = position;
+    
+    if (position != mCursorPosition)
+    {
+        mCursorPosition = position;
+        updateCursor();
+    }
 }
 
 void LineEdit::setCursorBlinkRate(float rate)
@@ -299,5 +289,32 @@ void LineEdit::updateText()
         mText->setText(echoText);
     }
     if (mCursorPosition > mLine.length())
+    {
         mCursorPosition = mLine.length();
+        updateCursor();
+    }
+}
+
+void LineEdit::updateCursor()
+{
+    int x = 0;
+    const std::vector<IntVector2>& charPositions = mText->getCharPositions();
+    if (charPositions.size())
+        x = mCursorPosition < charPositions.size() ? charPositions[mCursorPosition].mX : charPositions.back().mX;
+    
+    mCursor->setPosition(mText->getPosition() + IntVector2(x, 0));
+    mCursor->setSize(mCursor->getWidth(), mText->getRowHeight());
+    
+    // Scroll if necessary
+    int sx = -getChildOffset().mX;
+    int left = mClipBorder.mLeft;
+    int right = getWidth() - mClipBorder.mLeft - mClipBorder.mRight - mCursor->getWidth();
+    if (x - sx > right)
+        sx = x - right;
+    if (x - sx < left)
+        sx = x - left;
+    setChildOffset(IntVector2(-sx, 0));
+    
+    // Restart blinking
+    mCursorBlinkTimer = 0.0f;
 }

+ 11 - 4
Engine/UI/LineEdit.h

@@ -26,6 +26,7 @@
 
 #include "BorderImage.h"
 
+class Font;
 class Text;
 
 class LineEdit : public BorderImage
@@ -83,9 +84,19 @@ public:
 protected:
     //! Update displayed text
     void updateText();
+    //! Update cursor position and restart cursor blinking
+    void updateCursor();
     
+    //! Text element
+    SharedPtr<Text> mText;
+    //! Cursor element
+    SharedPtr<BorderImage> mCursor;
     //! Text line
     std::string mLine;
+    //! Last known text font
+    Font* mLastFont;
+    //! Last known text size
+    int mLastFontSize;
     //! Cursor position
     unsigned mCursorPosition;
     //! Cursor blink rate
@@ -98,10 +109,6 @@ protected:
     char mEchoCharacter;
     //! ESC defocus flag
     bool mDefocusable;
-    //! Text element
-    SharedPtr<Text> mText;
-    //! Cursor element
-    SharedPtr<BorderImage> mCursor;
     //! Defocus flag (defocus on next update)
     bool mDefocus;
 };

+ 3 - 0
Engine/UI/Text.cpp

@@ -316,6 +316,9 @@ void Text::calculateTextSize()
         mCharPositions[mText.length()] = IntVector2(x, y);
     }
     
+    // If maxwidth is nonzero, fix the element width
+    if (mMaxWidth)
+        width = mMaxWidth;
     setSize(width, height);
 }
 

+ 1 - 1
Engine/UI/Text.h

@@ -48,7 +48,7 @@ public:
     
     //! Set font and font size
     bool setFont(Font* font, int size = DEFAULT_FONT_SIZE);
-    //! Set maximum row width
+    //! Set maximum row width. If not 0, also fixes the element width to this value
     void setMaxWidth(int maxWidth);
     //! Set text
     void setText(const std::string& text);

+ 0 - 8
Engine/UI/UIBatch.cpp

@@ -67,8 +67,6 @@ void UIBatch::addQuad(UIElement& element, int x, int y, int width, int height, i
     else
     {
         Color color = element.getColor(C_TOPLEFT);
-        if ((element.isHovering()) || (element.isSelected()))
-            color += element.getHoverColor();
         color.mA *= element.getDerivedOpacity();
         // If alpha is 0, nothing will be rendered, so exit without adding the quad
         if (color.mA <= 0.0f)
@@ -111,8 +109,6 @@ void UIBatch::addQuad(UIElement& element, int x, int y, int width, int height, i
     else
     {
         Color color = element.getColor(C_TOPLEFT);
-        if ((element.isHovering()) || (element.isSelected()))
-            color += element.getHoverColor();
         color.mA *= element.getDerivedOpacity();
         // If alpha is 0, nothing will be rendered, so exit without adding the quad
         if (color.mA <= 0.0f)
@@ -268,16 +264,12 @@ unsigned UIBatch::getInterpolatedColor(UIElement& element, int x, int y)
         Color topColor = element.getColor(C_TOPLEFT).lerp(element.getColor(C_TOPRIGHT), cLerpX);
         Color bottomColor = element.getColor(C_BOTTOMLEFT).lerp(element.getColor(C_BOTTOMRIGHT), cLerpX);
         Color color = topColor.lerp(bottomColor, cLerpY);
-        if ((element.isHovering()) || (element.isSelected()))
-            color += element.getHoverColor();
         color.mA *= element.getDerivedOpacity();
         return getD3DColor(color);
     }
     else
     {
         Color color = element.getColor(C_TOPLEFT);
-        if ((element.isHovering()) || (element.isSelected()))
-            color += element.getHoverColor();
         color.mA *= element.getDerivedOpacity();
         return getD3DColor(color);
     }

+ 0 - 8
Engine/UI/UIElement.cpp

@@ -34,7 +34,6 @@ UIElement::UIElement(const std::string& name) :
     mParent(0),
     mOrigin(0),
     mClipBorder(IntRect::sZero),
-    mHoverColor(Color(0.0f, 0.0f, 0.0f, 0.0f)),
     mPriority(0),
     mOpacity(1.0f),
     mBringToFront(false),
@@ -130,8 +129,6 @@ void UIElement::setStyle(const XMLElement& element, ResourceCache* cache)
         if (colorElem.hasAttribute("bottomright"))
             setColor(C_BOTTOMRIGHT, colorElem.getColor("bottomright"));
     }
-    if (element.hasChildElement("hovercolor"))
-        setHoverColor(element.getChildElement("hovercolor").getColor("value"));
     if (element.hasChildElement("bringtofront"))
         setBringToFront(element.getChildElement("bringtofront").getBool("enable"));
     if (element.hasChildElement("bringtoback"))
@@ -352,11 +349,6 @@ void UIElement::setColor(UIElementCorner corner, const Color& color)
     }
 }
 
-void UIElement::setHoverColor(const Color& color)
-{
-    mHoverColor = color;
-}
-
 void UIElement::setPriority(int priority)
 {
     mPriority = priority;

+ 0 - 6
Engine/UI/UIElement.h

@@ -131,8 +131,6 @@ public:
     void setColor(const Color& color);
     //! Set color on one corner
     void setColor(UIElementCorner corner, const Color& color);
-    //! Set color modification used on hover
-    void setHoverColor(const Color& color);
     //! Set priority
     void setPriority(int priority);
     //! Set opacity
@@ -190,8 +188,6 @@ public:
     const IntRect& getClipBorder() const { return mClipBorder; }
     //! Return corner color
     const Color& getColor(UIElementCorner corner) const { return mColor[corner]; }
-    //! Return color modification used on hover
-    const Color& getHoverColor() { return mHoverColor; }
     //! Return priority
     int getPriority() const { return mPriority; }
     //! Return opacity
@@ -274,8 +270,6 @@ protected:
     IntRect mClipBorder;
     //! Colors
     Color mColor[MAX_UIELEMENT_CORNERS];
-    //! Color modification on hover
-    Color mHoverColor;
     //! Priority
     int mPriority;
     //! Bring to front when focused flag