BorderImage.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. //
  2. // Urho3D Engine
  3. // Copyright (c) 2008-2011 Lasse Öörni
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. #include "Precompiled.h"
  24. #include "BorderImage.h"
  25. #include "ResourceCache.h"
  26. #include "Texture2D.h"
  27. #include "DebugNew.h"
  28. BorderImage::BorderImage(const std::string& name) :
  29. UIElement(name),
  30. mImageRect(IntRect::sZero),
  31. mBorder(IntRect::sZero),
  32. mHoverOffset(IntVector2::sZero)
  33. {
  34. }
  35. BorderImage::~BorderImage()
  36. {
  37. }
  38. void BorderImage::setStyle(const XMLElement& element, ResourceCache* cache)
  39. {
  40. UIElement::setStyle(element, cache);
  41. if (element.hasChildElement("texture"))
  42. setTexture(cache->getResource<Texture2D>(element.getChildElement("texture").getString("name")));
  43. if (element.hasChildElement("imagerect"))
  44. setImageRect(element.getChildElement("imagerect").getIntRect("value"));
  45. if (element.hasChildElement("border"))
  46. setBorder(element.getChildElement("border").getIntRect("value"));
  47. if (element.hasChildElement("hoveroffset"))
  48. setHoverOffset(element.getChildElement("hoveroffset").getIntVector2("value"));
  49. }
  50. void BorderImage::getBatches(std::vector<UIBatch>& batches, std::vector<UIQuad>& quads, const IntRect& currentScissor)
  51. {
  52. bool allOpaque = true;
  53. if ((getDerivedOpacity() < 1.0f) || (mColor[C_TOPLEFT].mA < 1.0f) || (mColor[C_TOPRIGHT].mA < 1.0f) ||
  54. (mColor[C_BOTTOMLEFT].mA < 1.0f) || (mColor[C_BOTTOMRIGHT].mA < 1.0f))
  55. allOpaque = false;
  56. UIBatch batch;
  57. batch.begin(&quads);
  58. batch.mBlendMode = allOpaque ? BLEND_REPLACE : BLEND_ALPHA;
  59. batch.mScissor = currentScissor;
  60. batch.mTexture = mTexture;
  61. // Calculate size of the inner rect, and texture dimensions of the inner rect
  62. const IntVector2& size = getSize();
  63. IntVector2 innerSize(
  64. max(size.mX - mBorder.mLeft - mBorder.mRight, 0),
  65. max(size.mY - mBorder.mTop - mBorder.mBottom, 0));
  66. IntVector2 innerTextureSize(
  67. max(mImageRect.mRight - mImageRect.mLeft - mBorder.mLeft - mBorder.mRight, 0),
  68. max(mImageRect.mBottom - mImageRect.mTop - mBorder.mTop - mBorder.mBottom, 0));
  69. IntVector2 topLeft(mImageRect.mLeft, mImageRect.mTop);
  70. if ((mHovering) || (mSelected))
  71. topLeft += mHoverOffset;
  72. // Top
  73. if (mBorder.mTop)
  74. {
  75. if (mBorder.mLeft)
  76. batch.addQuad(*this, 0, 0, mBorder.mLeft, mBorder.mTop, topLeft.mX, topLeft.mY);
  77. if (innerSize.mX)
  78. batch.addQuad(*this, mBorder.mLeft, 0, innerSize.mX, mBorder.mTop,
  79. topLeft.mX + mBorder.mLeft, topLeft.mY, innerTextureSize.mX, mBorder.mTop);
  80. if (mBorder.mRight)
  81. batch.addQuad(*this, mBorder.mLeft + innerSize.mX, 0, mBorder.mRight, mBorder.mTop,
  82. topLeft.mX + mBorder.mLeft + innerTextureSize.mX, topLeft.mY);
  83. }
  84. // Middle
  85. if (innerSize.mY)
  86. {
  87. if (mBorder.mLeft)
  88. batch.addQuad(*this, 0, mBorder.mTop, mBorder.mLeft, innerSize.mY,
  89. topLeft.mX, topLeft.mY + mBorder.mTop, mBorder.mLeft, innerTextureSize.mY);
  90. if (innerSize.mX)
  91. batch.addQuad(*this, mBorder.mLeft, mBorder.mTop, innerSize.mX, innerSize.mY,
  92. topLeft.mX + mBorder.mLeft, topLeft.mY + mBorder.mTop, innerTextureSize.mX, innerTextureSize.mY);
  93. if (mBorder.mRight)
  94. batch.addQuad(*this, mBorder.mLeft + innerSize.mX, mBorder.mTop, mBorder.mRight,
  95. innerSize.mY, topLeft.mX + mBorder.mLeft + innerTextureSize.mX, topLeft.mY + mBorder.mTop,
  96. mBorder.mRight, innerTextureSize.mY);
  97. }
  98. // Bottom
  99. if (mBorder.mBottom)
  100. {
  101. if (mBorder.mLeft)
  102. batch.addQuad(*this, 0, mBorder.mTop + innerSize.mY, mBorder.mLeft, mBorder.mBottom,
  103. topLeft.mX, topLeft.mY + mBorder.mTop + innerTextureSize.mY);
  104. if (innerSize.mX)
  105. batch.addQuad(*this, mBorder.mLeft, mBorder.mTop + innerSize.mY, innerSize.mX,
  106. mBorder.mBottom, topLeft.mX + mBorder.mLeft, topLeft.mY + mBorder.mTop + innerTextureSize.mY,
  107. innerTextureSize.mX, mBorder.mBottom);
  108. if (mBorder.mRight)
  109. batch.addQuad(*this, mBorder.mLeft + innerSize.mX, mBorder.mTop + innerSize.mY,
  110. mBorder.mRight, mBorder.mBottom, topLeft.mX + mBorder.mLeft + innerTextureSize.mX,
  111. topLeft.mY + mBorder.mTop + innerTextureSize.mY);
  112. }
  113. UIBatch::addOrMerge(batch, batches);
  114. // Reset hovering for next frame
  115. mHovering = false;
  116. }
  117. void BorderImage::setTexture(Texture* texture)
  118. {
  119. mTexture = texture;
  120. if (mImageRect == IntRect::sZero)
  121. setFullImageRect();
  122. }
  123. void BorderImage::setImageRect(const IntRect& rect)
  124. {
  125. mImageRect = rect;
  126. }
  127. void BorderImage::setImageRect(int left, int top, int right, int bottom)
  128. {
  129. mImageRect.mLeft = left;
  130. mImageRect.mTop = top;
  131. mImageRect.mRight = right;
  132. mImageRect.mBottom = bottom;
  133. }
  134. void BorderImage::setFullImageRect()
  135. {
  136. if (mTexture)
  137. {
  138. mImageRect.mLeft = 0;
  139. mImageRect.mTop = 0;
  140. mImageRect.mRight = mTexture->getWidth();
  141. mImageRect.mBottom = mTexture->getHeight();
  142. }
  143. }
  144. void BorderImage::setBorder(const IntRect& rect)
  145. {
  146. mBorder.mLeft = max(rect.mLeft, 0);
  147. mBorder.mTop = max(rect.mTop, 0);
  148. mBorder.mRight = max(rect.mRight, 0);
  149. mBorder.mBottom = max(rect.mBottom, 0);
  150. }
  151. void BorderImage::setBorder(int left, int top, int right, int bottom)
  152. {
  153. mBorder.mLeft = max(left, 0);
  154. mBorder.mTop = max(top, 0);
  155. mBorder.mRight = max(right, 0);
  156. mBorder.mBottom = max(bottom, 0);
  157. }
  158. void BorderImage::setHoverOffset(const IntVector2& offset)
  159. {
  160. mHoverOffset = offset;
  161. }
  162. void BorderImage::setHoverOffset(int x, int y)
  163. {
  164. mHoverOffset = IntVector2(x, y);
  165. }