Browse Source

Add Filled mode in UIImage.

aster2013 11 years ago
parent
commit
acb22d134e
3 changed files with 305 additions and 6 deletions
  1. 268 2
      Source/Engine/UIX/UIImage.cpp
  2. 35 4
      Source/Engine/UIX/UIImage.h
  3. 2 0
      Source/Engine/UIX/UIRect.h

+ 268 - 2
Source/Engine/UIX/UIImage.cpp

@@ -43,6 +43,15 @@ static const char* uiImageDrawModes[] =
     "Simple",
     "Simple",
     "Tiled",
     "Tiled",
     "Sliced",
     "Sliced",
+    "Filled",
+    0
+};
+
+static const char* uiFillTypes[] = 
+{
+    "Horizontal",
+    "Vertical",
+    "Radial",
     0
     0
 };
 };
 
 
@@ -51,7 +60,10 @@ UIImage::UIImage(Context* context) :
     color_(Color::WHITE),
     color_(Color::WHITE),
     drawMode_(UIIDM_SIMPLE),
     drawMode_(UIIDM_SIMPLE),
     xSliceSize_(4),
     xSliceSize_(4),
-    ySliceSize_(4)
+    ySliceSize_(4),
+    fillType_(UIFT_HORIZONTAL),
+    fillAmount_(1.0f),
+    fillInverse_(false)
 {
 {
 }
 }
 
 
@@ -69,6 +81,9 @@ void UIImage::RegisterObject(Context* context)
     ENUM_ACCESSOR_ATTRIBUTE("Draw Mode", GetDrawMode, SetDrawMode, UIImageDrawMode, uiImageDrawModes, UIIDM_SIMPLE, AM_FILE);
     ENUM_ACCESSOR_ATTRIBUTE("Draw Mode", GetDrawMode, SetDrawMode, UIImageDrawMode, uiImageDrawModes, UIIDM_SIMPLE, AM_FILE);
     ACCESSOR_ATTRIBUTE("X Slice Size", GetXSliceSize, SetXSliceSize, int, 4, AM_FILE);
     ACCESSOR_ATTRIBUTE("X Slice Size", GetXSliceSize, SetXSliceSize, int, 4, AM_FILE);
     ACCESSOR_ATTRIBUTE("Y Slice Size", GetYSliceSize, SetYSliceSize, int, 4, AM_FILE);
     ACCESSOR_ATTRIBUTE("Y Slice Size", GetYSliceSize, SetYSliceSize, int, 4, AM_FILE);
+    ENUM_ACCESSOR_ATTRIBUTE("Fill Type", GetFillType, SetFillType, UIFillType, uiFillTypes, UIFT_HORIZONTAL, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Fill Amount", GetFillAmount, SetFillAmount, float, 1.0f, AM_FILE);
+    ACCESSOR_ATTRIBUTE("Fill Inverse", IsFillInverse, SetFillInverse, bool, false, AM_FILE);
     COPY_BASE_ATTRIBUTES(Drawable2D);
     COPY_BASE_ATTRIBUTES(Drawable2D);
 }
 }
 
 
@@ -123,6 +138,41 @@ void UIImage::SetYSliceSize(int size)
         verticesDirty_ = true;
         verticesDirty_ = true;
 }
 }
 
 
+void UIImage::SetFillType(UIFillType fillType)
+{
+    if (fillType == fillType_)
+        return;
+
+    fillType_ = fillType;
+
+    if (drawMode_ == UIIDM_FILLED)
+        verticesDirty_ = true;
+}
+
+void UIImage::SetFillAmount(float amount)
+{
+    amount = Clamp(amount, 0.0f, 1.0f);
+
+    if (amount == fillAmount_)
+        return;
+
+    fillAmount_ = amount;
+
+    if (drawMode_ == UIIDM_FILLED)
+        verticesDirty_ = true;
+}
+
+void UIImage::SetFillInverse(bool inverse)
+{
+    if (inverse == fillInverse_)
+        return;
+
+    fillInverse_ = inverse;
+
+    if (drawMode_ == UIIDM_FILLED)
+        verticesDirty_ = true;
+}
+
 Sprite2D* UIImage::GetSprite() const
 Sprite2D* UIImage::GetSprite() const
 {
 {
     return sprite_;
     return sprite_;
@@ -196,6 +246,9 @@ void UIImage::UpdateVertices()
     case UIIDM_SLICED:
     case UIIDM_SLICED:
         UpdateVerticesSlicedMode();
         UpdateVerticesSlicedMode();
         break;
         break;
+        case UIIDM_FILLED:
+        UpdateVerticesFilledMode();
+        break;
     }
     }
 
 
     verticesDirty_ = false;
     verticesDirty_ = false;
@@ -267,7 +320,15 @@ void UIImage::UpdateVerticesSlicedMode()
 {
 {
     if (xSliceSize_ == 0 && ySliceSize_ == 0)
     if (xSliceSize_ == 0 && ySliceSize_ == 0)
     {
     {
-        UpdateVerticesSimpleMode();
+        float left = uiRect_->GetLeft();
+        float right = uiRect_->GetRight();
+        float top = uiRect_->GetTop();
+        float bottom = uiRect_->GetBottom();
+
+        float uLeft, uRight, vTop, vBottom;
+        GetSpriteTextureCoords(uLeft, uRight, vTop, vBottom);
+
+        AddQuad(left, right, top, bottom, uLeft, uRight, vTop, vBottom);
         return;
         return;
     }
     }
 
 
@@ -312,6 +373,211 @@ void UIImage::UpdateVerticesSlicedMode()
     AddQuad(x2  , right, y2, bottom, u2   , uRight, v2, vBottom);
     AddQuad(x2  , right, y2, bottom, u2   , uRight, v2, vBottom);
 }
 }
 
 
+void UIImage::UpdateVerticesFilledMode()
+{
+    if (fillType_ != UIFT_RADIAL)
+    {
+        float left = uiRect_->GetLeft();
+        float right = uiRect_->GetRight();
+        float top = uiRect_->GetTop();
+        float bottom = uiRect_->GetBottom();
+
+        float uLeft, uRight, vTop, vBottom;
+        GetSpriteTextureCoords(uLeft, uRight, vTop, vBottom);
+
+        if (fillType_ == UIFT_HORIZONTAL)
+        {
+            if (!fillInverse_)
+            {
+                right = left + (right - left) * fillAmount_;
+                uRight = uLeft + (uRight - uLeft) * fillAmount_;
+            }
+            else
+            {
+                left = right - (right - left) * fillAmount_;
+                uLeft = uRight - (uRight - uLeft) * fillAmount_;
+            }
+        }
+        else
+        {
+            if (!fillInverse_)
+            {
+                top = bottom + (top - bottom) * fillAmount_;
+                vTop = vBottom + (vTop - vBottom) * fillAmount_;
+            }
+            else
+            {
+                bottom = top - (top - bottom) * fillAmount_;
+                vBottom = vTop - (vTop - vBottom) * fillAmount_;
+            }
+        }
+        AddQuad(left, right, top, bottom, uLeft, uRight, vTop, vBottom);
+    }
+    else
+        UpdateVerticesFilledModeRadial();
+}
+
+void UIImage::UpdateVerticesFilledModeRadial()
+{
+    float x = uiRect_->GetX();
+    float y = uiRect_->GetY();
+    float left = uiRect_->GetLeft();
+    float right = uiRect_->GetRight();
+    float top = uiRect_->GetTop();
+    float bottom = uiRect_->GetBottom();
+
+    unsigned color = color_.ToUInt();
+
+    float uLeft, uRight, vTop, vBottom;
+    GetSpriteTextureCoords(uLeft, uRight, vTop, vBottom);
+    float u = (uLeft + uRight) * 0.5f;
+    float v = (vTop + vBottom) * 0.5f;
+
+    //  5----1----2
+    //  | \  |a1 /|
+    //  |  \ | /  |
+    //  |    0 ---| 
+    //  |  /   \  |
+    //  |/       \|
+    //  4---------3
+    Vertex2D vertices[6] = 
+    {
+        { Vector3(x    , y     ),  color, Vector2(u     , v      ) }, // 0
+        { Vector3(x    , top   ),  color, Vector2(u     , vTop   ) }, // 1
+        { Vector3(right, top   ),  color, Vector2(uRight, vTop   ) }, // 2
+        { Vector3(right, bottom),  color, Vector2(uRight, vBottom) }, // 3
+        { Vector3(left , bottom),  color, Vector2(uLeft , vBottom) }, // 4
+        { Vector3(left , top   ),  color, Vector2(uLeft , vTop   ) }, // 5
+    };
+
+    float angle = 360.0f * fillAmount_;
+    float width = uiRect_->GetWidth();
+    float height = uiRect_->GetHeight();
+    float angle1 = Atan2(width, height);
+
+    if (angle <= angle1)
+    {
+        float x1 = x + height * 0.5f * Tan(angle);
+        if (fillInverse_)
+            x1 = x + x1;
+        else
+            x1 = x - x1;
+        float u1 = uLeft + (uRight - uLeft) /  width * (x1 - left);
+        Vertex2D vertex = {Vector3(x1, top), color, Vector2(u1, vTop) };
+        vertices_.Push(vertices[0]);
+        vertices_.Push(vertices[1]);
+        vertices_.Push(vertex);
+        vertices_.Push(vertex);
+        return;
+    }
+
+    if (angle <= 180.0f - angle1)
+    {
+        float y1 = y + width * 0.5f * Tan(90.0f - angle);
+        float v1 = vBottom + (vTop - vBottom) / height * (y1 - bottom);
+        vertices_.Push(vertices[0]);
+        vertices_.Push(vertices[1]);
+        if (fillInverse_)
+        {
+            Vertex2D vertex = { Vector3(right, y1), color, Vector2(uRight, v1) };
+            vertices_.Push(vertices[2]);
+            vertices_.Push(vertex);
+        }
+        else
+        {
+            Vertex2D vertex = { Vector3(left, y1), color, Vector2(uLeft, v1) };
+            vertices_.Push(vertices[5]);
+            vertices_.Push(vertex);
+        }
+        return;
+    }
+    
+    vertices_.Push(vertices[0]);
+    vertices_.Push(vertices[1]);
+    if (fillInverse_)
+    {
+        vertices_.Push(vertices[2]);
+        vertices_.Push(vertices[3]);
+    }
+    else
+    {
+        vertices_.Push(vertices[5]);
+        vertices_.Push(vertices[4]);
+    }
+
+    if (angle <= 180.0f + angle1)
+    {
+        float x1 = height * 0.5f * Tan(180.0f - angle);
+        if (fillInverse_)
+            x1 = x + x1;
+        else
+            x1 = x - x1;
+        float u1 = uLeft + (uRight - uLeft) /  width * (x1 - left);
+        Vertex2D vertex = { Vector3(x1, bottom), color, Vector2(u1, vBottom) };
+        vertices_.Push(vertices[0]);
+        if (fillInverse_)
+            vertices_.Push(vertices[3]);
+        else
+            vertices_.Push(vertices[4]);
+        vertices_.Push(vertex);
+        vertices_.Push(vertex);
+        return;
+    }
+
+    if (angle <= 360.0f - angle1)
+    {
+        float y1 = y + width * 0.5f * Tan(angle - 270.0f);
+        float v1 = vBottom + (vTop - vBottom) / height * (y1 - bottom);
+        if (fillInverse_)
+        {
+            Vertex2D vertex = { Vector3(left, y1), color, Vector2(uLeft, v1) };
+            vertices_.Push(vertices[0]);
+            vertices_.Push(vertices[3]);
+            vertices_.Push(vertices[4]);
+            vertices_.Push(vertex);
+        }
+        else
+        {
+            Vertex2D vertex = { Vector3(right, y1), color, Vector2(uRight, v1) };
+            vertices_.Push(vertices[0]);
+            vertices_.Push(vertices[4]);
+            vertices_.Push(vertices[3]);
+            vertices_.Push(vertex);
+        }
+        return;
+    }
+
+    if (fillInverse_)
+    {
+        vertices_.Push(vertices[0]);
+        vertices_.Push(vertices[3]);
+        vertices_.Push(vertices[4]);
+        vertices_.Push(vertices[5]);
+    }
+    else
+    {
+        vertices_.Push(vertices[0]);
+        vertices_.Push(vertices[4]);
+        vertices_.Push(vertices[3]);        
+        vertices_.Push(vertices[2]);
+    }
+
+    float x1 = height * 0.5f * Tan(angle - 360.0f);
+    if (fillInverse_)
+        x1 = x + x1;
+    else
+        x1 = x - x1;
+    float u1 = uLeft + (uRight - uLeft) /  width * (x1 - left);
+    Vertex2D vertex = { Vector3(x1, top), color, Vector2(u1, vTop) };
+    vertices_.Push(vertices[0]);
+    if (fillInverse_)
+        vertices_.Push(vertices[5]);
+    else
+        vertices_.Push(vertices[2]);
+    vertices_.Push(vertex);
+    vertices_.Push(vertex);
+}
+
 void UIImage::GetSpriteTextureCoords(float& left, float& right, float& top, float& bottom) const
 void UIImage::GetSpriteTextureCoords(float& left, float& right, float& top, float& bottom) const
 { 
 { 
     Texture2D* texture = GetTexture();
     Texture2D* texture = GetTexture();

+ 35 - 4
Source/Engine/UIX/UIImage.h

@@ -36,6 +36,15 @@ enum UIImageDrawMode
     UIIDM_SIMPLE = 0,
     UIIDM_SIMPLE = 0,
     UIIDM_TILED,
     UIIDM_TILED,
     UIIDM_SLICED,
     UIIDM_SLICED,
+    UIIDM_FILLED,
+};
+
+/// UI image fill type.
+enum UIFillType
+{
+    UIFT_HORIZONTAL = 0,
+    UIFT_VERTICAL,
+    UIFT_RADIAL,
 };
 };
 
 
 /// UI drawable component.
 /// UI drawable component.
@@ -57,10 +66,16 @@ public:
     void SetColor(const Color& color);
     void SetColor(const Color& color);
     /// Set draw mode.
     /// Set draw mode.
     void SetDrawMode(UIImageDrawMode mode);
     void SetDrawMode(UIImageDrawMode mode);
-    /// Set X slice size.
+    /// Set X slice size (for sliced mode).
     void SetXSliceSize(int size);
     void SetXSliceSize(int size);
-    /// Set Y slice size.
+    /// Set Y slice size (for sliced mode).
     void SetYSliceSize(int size);
     void SetYSliceSize(int size);
+    /// Set fill type (for fill mode).
+    void SetFillType(UIFillType fillType);
+    /// Set fill amount (for fill mode).
+    void SetFillAmount(float amount);
+    /// Set Fill inverse (for fill mode).
+    void SetFillInverse(bool inverse);
 
 
     /// Return sprite.
     /// Return sprite.
     Sprite2D* GetSprite() const;
     Sprite2D* GetSprite() const;
@@ -68,10 +83,16 @@ public:
     const Color& GetColor() const { return color_; }
     const Color& GetColor() const { return color_; }
     /// Return draw mode.
     /// Return draw mode.
     UIImageDrawMode GetDrawMode() const { return drawMode_; }
     UIImageDrawMode GetDrawMode() const { return drawMode_; }
-    /// Return X slice size.
+    /// Return X slice size (for sliced mode).
     int GetXSliceSize() const { return xSliceSize_;}
     int GetXSliceSize() const { return xSliceSize_;}
-    /// Return Y slice size.
+    /// Return Y slice size (for sliced mode).
     int GetYSliceSize() const { return ySliceSize_;}
     int GetYSliceSize() const { return ySliceSize_;}
+    /// Return fill type (for filled mode).
+    UIFillType GetFillType() const { return fillType_; }
+    /// Return fill amount (for fill mode).
+    float GetFillAmount() const { return fillAmount_; }
+    /// Return is fill inverse (for fill mode).
+    bool IsFillInverse() const { return fillInverse_; }
 
 
     /// Set sprite attribute.
     /// Set sprite attribute.
     void SetSpriteAttr(const ResourceRef& value);
     void SetSpriteAttr(const ResourceRef& value);
@@ -91,6 +112,10 @@ private:
     void UpdateVerticesTiledMode();
     void UpdateVerticesTiledMode();
     /// Update vertices sliced mode.
     /// Update vertices sliced mode.
     void UpdateVerticesSlicedMode();
     void UpdateVerticesSlicedMode();
+    /// Update vertices filled mode.
+    void UpdateVerticesFilledMode();
+    /// Update vertices filled  mode radial.
+    void UpdateVerticesFilledModeRadial();
     /// Return sprite texture coords.
     /// Return sprite texture coords.
     void GetSpriteTextureCoords(float& left, float& right, float& top, float& bottom) const;
     void GetSpriteTextureCoords(float& left, float& right, float& top, float& bottom) const;
     /// Add quad.
     /// Add quad.
@@ -110,6 +135,12 @@ private:
     int xSliceSize_;
     int xSliceSize_;
     /// Y slice size.
     /// Y slice size.
     int ySliceSize_;
     int ySliceSize_;
+    /// Fill type.
+    UIFillType fillType_;
+    /// Fill amount.
+    float fillAmount_;
+    /// Fill inverse.
+    bool fillInverse_;
 };
 };
 
 
 }
 }

+ 2 - 0
Source/Engine/UIX/UIRect.h

@@ -120,6 +120,8 @@ public:
     float GetX() const { return GetRect().Center().x_; }
     float GetX() const { return GetRect().Center().x_; }
     /// Get y.
     /// Get y.
     float GetY() const { return GetRect().Center().y_; }
     float GetY() const { return GetRect().Center().y_; }
+    /// Get center.
+    Vector2 GetCenter() const { return GetRect().Center(); }
     /// Return left.
     /// Return left.
     float GetLeft() const { return GetRect().min_.x_; }
     float GetLeft() const { return GetRect().min_.x_; }
     /// Return right.
     /// Return right.