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 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(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 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 setPriority(int)", asMETHOD(T, setPriority), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void setOpacity(float)", asMETHOD(T, setOpacity), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void setOpacity(float)", asMETHOD(T, setOpacity), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "void setBringToFront(bool)", asMETHOD(T, setBringToFront), 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, "VerticalAlignment getVerticalAlignment() const", asMETHOD(T, getVerticalAlignment), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "const IntRect& getClipBorder() const", asMETHOD(T, getClipBorder), 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& 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, "int getPriority() const", asMETHOD(T, getPriority), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "float getOpacity() const", asMETHOD(T, getOpacity), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "float getOpacity() const", asMETHOD(T, getOpacity), asCALL_THISCALL);
     engine->RegisterObjectMethod(className, "bool getBringToFront() const", asMETHOD(T, getBringToFront), 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) :
 LineEdit::LineEdit(const std::string& name, const std::string& text) :
     BorderImage(name),
     BorderImage(name),
+    mLastFont(0),
+    mLastFontSize(0),
     mCursorPosition(0),
     mCursorPosition(0),
     mCursorBlinkRate(1.0f),
     mCursorBlinkRate(1.0f),
     mCursorBlinkTimer(0.0f),
     mCursorBlinkTimer(0.0f),
@@ -90,32 +92,17 @@ void LineEdit::update(float timeStep)
     else
     else
         mCursorBlinkTimer = 0.0f;
         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;
     bool cursorVisible = false;
-    
     if (mFocus)
     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;
         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);
     mCursor->setVisible(cursorVisible);
     
     
     if (mDefocus)
     if (mDefocus)
@@ -135,7 +122,7 @@ void LineEdit::onClick(const IntVector2& position, const IntVector2& screenPosit
         {
         {
             if (textPosition.mX >= charPositions[i].mX)
             if (textPosition.mX >= charPositions[i].mX)
             {
             {
-                mCursorPosition = i;
+                setCursorPosition(i);
                 break;
                 break;
             }
             }
         }
         }
@@ -177,13 +164,10 @@ void LineEdit::onKey(int key)
         break;
         break;
     }
     }
     
     
-    // Restart cursor blinking from the visible state
-    if (cursorMoved)
-        mCursorBlinkTimer = 0.0f;
-    
     if (changed)
     if (changed)
     {
     {
         updateText();
         updateText();
+        updateCursor();
         
         
         using namespace TextChanged;
         using namespace TextChanged;
         
         
@@ -192,6 +176,8 @@ void LineEdit::onKey(int key)
         eventData[P_TEXT] = mLine;
         eventData[P_TEXT] = mLine;
         sendEvent(EVENT_TEXTCHANGED, eventData);
         sendEvent(EVENT_TEXTCHANGED, eventData);
     }
     }
+    else if (cursorMoved)
+        updateCursor();
 }
 }
 
 
 void LineEdit::onChar(unsigned char c)
 void LineEdit::onChar(unsigned char c)
@@ -238,9 +224,8 @@ void LineEdit::onChar(unsigned char c)
     
     
     if (changed)
     if (changed)
     {
     {
-        // Restart cursor blinking from the visible state
-        mCursorBlinkTimer = 0.0f;
         updateText();
         updateText();
+        updateCursor();
         
         
         using namespace TextChanged;
         using namespace TextChanged;
         
         
@@ -262,7 +247,12 @@ void LineEdit::setCursorPosition(unsigned position)
 {
 {
     if (position > mLine.length())
     if (position > mLine.length())
         position = mLine.length();
         position = mLine.length();
-    mCursorPosition = position;
+    
+    if (position != mCursorPosition)
+    {
+        mCursorPosition = position;
+        updateCursor();
+    }
 }
 }
 
 
 void LineEdit::setCursorBlinkRate(float rate)
 void LineEdit::setCursorBlinkRate(float rate)
@@ -299,5 +289,32 @@ void LineEdit::updateText()
         mText->setText(echoText);
         mText->setText(echoText);
     }
     }
     if (mCursorPosition > mLine.length())
     if (mCursorPosition > mLine.length())
+    {
         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"
 #include "BorderImage.h"
 
 
+class Font;
 class Text;
 class Text;
 
 
 class LineEdit : public BorderImage
 class LineEdit : public BorderImage
@@ -83,9 +84,19 @@ public:
 protected:
 protected:
     //! Update displayed text
     //! Update displayed text
     void updateText();
     void updateText();
+    //! Update cursor position and restart cursor blinking
+    void updateCursor();
     
     
+    //! Text element
+    SharedPtr<Text> mText;
+    //! Cursor element
+    SharedPtr<BorderImage> mCursor;
     //! Text line
     //! Text line
     std::string mLine;
     std::string mLine;
+    //! Last known text font
+    Font* mLastFont;
+    //! Last known text size
+    int mLastFontSize;
     //! Cursor position
     //! Cursor position
     unsigned mCursorPosition;
     unsigned mCursorPosition;
     //! Cursor blink rate
     //! Cursor blink rate
@@ -98,10 +109,6 @@ protected:
     char mEchoCharacter;
     char mEchoCharacter;
     //! ESC defocus flag
     //! ESC defocus flag
     bool mDefocusable;
     bool mDefocusable;
-    //! Text element
-    SharedPtr<Text> mText;
-    //! Cursor element
-    SharedPtr<BorderImage> mCursor;
     //! Defocus flag (defocus on next update)
     //! Defocus flag (defocus on next update)
     bool mDefocus;
     bool mDefocus;
 };
 };

+ 3 - 0
Engine/UI/Text.cpp

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

+ 1 - 1
Engine/UI/Text.h

@@ -48,7 +48,7 @@ public:
     
     
     //! Set font and font size
     //! Set font and font size
     bool setFont(Font* font, int size = DEFAULT_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);
     void setMaxWidth(int maxWidth);
     //! Set text
     //! Set text
     void setText(const std::string& 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
     else
     {
     {
         Color color = element.getColor(C_TOPLEFT);
         Color color = element.getColor(C_TOPLEFT);
-        if ((element.isHovering()) || (element.isSelected()))
-            color += element.getHoverColor();
         color.mA *= element.getDerivedOpacity();
         color.mA *= element.getDerivedOpacity();
         // If alpha is 0, nothing will be rendered, so exit without adding the quad
         // If alpha is 0, nothing will be rendered, so exit without adding the quad
         if (color.mA <= 0.0f)
         if (color.mA <= 0.0f)
@@ -111,8 +109,6 @@ void UIBatch::addQuad(UIElement& element, int x, int y, int width, int height, i
     else
     else
     {
     {
         Color color = element.getColor(C_TOPLEFT);
         Color color = element.getColor(C_TOPLEFT);
-        if ((element.isHovering()) || (element.isSelected()))
-            color += element.getHoverColor();
         color.mA *= element.getDerivedOpacity();
         color.mA *= element.getDerivedOpacity();
         // If alpha is 0, nothing will be rendered, so exit without adding the quad
         // If alpha is 0, nothing will be rendered, so exit without adding the quad
         if (color.mA <= 0.0f)
         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 topColor = element.getColor(C_TOPLEFT).lerp(element.getColor(C_TOPRIGHT), cLerpX);
         Color bottomColor = element.getColor(C_BOTTOMLEFT).lerp(element.getColor(C_BOTTOMRIGHT), cLerpX);
         Color bottomColor = element.getColor(C_BOTTOMLEFT).lerp(element.getColor(C_BOTTOMRIGHT), cLerpX);
         Color color = topColor.lerp(bottomColor, cLerpY);
         Color color = topColor.lerp(bottomColor, cLerpY);
-        if ((element.isHovering()) || (element.isSelected()))
-            color += element.getHoverColor();
         color.mA *= element.getDerivedOpacity();
         color.mA *= element.getDerivedOpacity();
         return getD3DColor(color);
         return getD3DColor(color);
     }
     }
     else
     else
     {
     {
         Color color = element.getColor(C_TOPLEFT);
         Color color = element.getColor(C_TOPLEFT);
-        if ((element.isHovering()) || (element.isSelected()))
-            color += element.getHoverColor();
         color.mA *= element.getDerivedOpacity();
         color.mA *= element.getDerivedOpacity();
         return getD3DColor(color);
         return getD3DColor(color);
     }
     }

+ 0 - 8
Engine/UI/UIElement.cpp

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

+ 0 - 6
Engine/UI/UIElement.h

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