BsGUIArea.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. #include "BsGUIArea.h"
  2. #include "BsGUIWidget.h"
  3. #include "BsGUILayoutX.h"
  4. #include "BsGUIWidget.h"
  5. #include "BsRenderWindow.h"
  6. #include "BsViewport.h"
  7. namespace BansheeEngine
  8. {
  9. GUIArea::GUIArea(GUIWidget* widget, INT32 x, INT32 y, UINT16 depth)
  10. :mWidget(widget), mLeft(x), mTop(y), mDepth(depth), mIsDirty(true), mIsDisabled(false),
  11. mResizeXWithWidget(false), mResizeYWithWidget(false), mWidth(0), mHeight(0), mRight(0), mBottom(0)
  12. {
  13. mLayout = bs_new<GUILayoutX, PoolAlloc>(this);
  14. mLayout->_changeParentWidget(widget);
  15. mWidget->registerArea(this);
  16. }
  17. GUIArea::~GUIArea()
  18. {
  19. bs_delete<PoolAlloc>(mLayout);
  20. }
  21. GUIArea* GUIArea::create(GUIWidget& widget, INT32 x, INT32 y, UINT32 width, UINT32 height, UINT16 depth)
  22. {
  23. GUIArea* area = new (bs_alloc<GUIArea, PoolAlloc>()) GUIArea(&widget, x, y, depth);
  24. area->mWidth = width;
  25. area->mHeight = height;
  26. return area;
  27. }
  28. GUIArea* GUIArea::createStretchedXY(GUIWidget& widget, UINT32 offsetLeft,
  29. UINT32 offsetRight, UINT32 offsetTop, UINT32 offsetBottom, UINT16 depth)
  30. {
  31. GUIArea* area = new (bs_alloc<GUIArea, PoolAlloc>()) GUIArea(&widget, offsetLeft, offsetTop, depth);
  32. area->mWidth = std::max(0, (INT32)widget.getTarget()->getWidth() - (INT32)offsetLeft - (INT32)offsetRight);
  33. area->mHeight = std::max(0, (INT32)widget.getTarget()->getHeight() - (INT32)offsetTop - (INT32)offsetBottom);
  34. area->mRight = offsetRight;
  35. area->mBottom = offsetBottom;
  36. area->mResizeXWithWidget = true;
  37. area->mResizeYWithWidget = true;
  38. return area;
  39. }
  40. GUIArea* GUIArea::createStretchedX(GUIWidget& widget, UINT32 offsetLeft,
  41. UINT32 offsetRight, UINT32 offsetTop, UINT32 height, UINT16 depth)
  42. {
  43. GUIArea* area = new (bs_alloc<GUIArea, PoolAlloc>()) GUIArea(&widget, offsetLeft, offsetTop, depth);
  44. area->mWidth = std::max(0, (INT32)widget.getTarget()->getWidth() - (INT32)offsetLeft - (INT32)offsetRight);
  45. area->mHeight = height;
  46. area->mRight = offsetRight;
  47. area->mResizeXWithWidget = true;
  48. area->mResizeYWithWidget = false;
  49. return area;
  50. }
  51. GUIArea* GUIArea::createStretchedY(GUIWidget& widget, UINT32 offsetTop,
  52. UINT32 offsetBottom, UINT32 offsetLeft, UINT32 width, UINT16 depth)
  53. {
  54. GUIArea* area = new (bs_alloc<GUIArea, PoolAlloc>()) GUIArea(&widget, offsetLeft, offsetTop, depth);
  55. area->mWidth = width;
  56. area->mHeight = std::max(0, (INT32)widget.getTarget()->getHeight() - (INT32)offsetTop - (INT32)offsetBottom);
  57. area->mBottom = offsetBottom;
  58. area->mResizeXWithWidget = false;
  59. area->mResizeYWithWidget = true;
  60. return area;
  61. }
  62. void GUIArea::destroy(GUIArea* area)
  63. {
  64. if(area->mWidget != nullptr)
  65. area->mWidget->unregisterArea(area);
  66. bs_delete<PoolAlloc>(area);
  67. }
  68. void GUIArea::destroyInternal(GUIArea* area)
  69. {
  70. bs_delete<PoolAlloc>(area);
  71. }
  72. void GUIArea::disable()
  73. {
  74. mIsDisabled = true;
  75. mLayout->disableRecursively();
  76. }
  77. void GUIArea::enable()
  78. {
  79. mIsDisabled = false;
  80. mLayout->enableRecursively();
  81. }
  82. void GUIArea::changeParentWidget(GUIWidget* widget)
  83. {
  84. if(mWidget == widget)
  85. return;
  86. if(mWidget != nullptr)
  87. mWidget->unregisterArea(this);
  88. if(widget != nullptr)
  89. widget->registerArea(this);
  90. mWidget = widget;
  91. mLayout->_changeParentWidget(widget);
  92. if(mWidget != nullptr)
  93. {
  94. // Ensure the size is valid, otherwise next GUI layout update will calculate wrong element coordinates
  95. updateSizeBasedOnParent(mWidget->getTarget()->getWidth(), mWidget->getTarget()->getHeight());
  96. }
  97. mIsDirty = true;
  98. }
  99. void GUIArea::_update()
  100. {
  101. if(!mIsDisabled && isDirty() && (mWidget != nullptr))
  102. {
  103. Rect2I clipRect(mLeft, mTop, mWidth, mHeight);
  104. if (mClipRect.width > 0 && mClipRect.height > 0)
  105. {
  106. Rect2I newClipRect = Rect2I(mLeft + mClipRect.x, mTop + mClipRect.y, mClipRect.width, mClipRect.height);
  107. newClipRect.clip(clipRect);
  108. clipRect = newClipRect;
  109. }
  110. mLayout->_updateLayout(mLeft, mTop, mWidth, mHeight, clipRect, mWidget->getDepth(), mDepth);
  111. mIsDirty = false;
  112. }
  113. }
  114. bool GUIArea::isDirty() const
  115. {
  116. if(mIsDirty)
  117. return true;
  118. return mLayout->_isContentDirty();
  119. }
  120. void GUIArea::setPosition(INT32 x, INT32 y)
  121. {
  122. mLeft = x;
  123. mTop = y;
  124. mIsDirty = true;
  125. }
  126. void GUIArea::setSize(UINT32 width, UINT32 height)
  127. {
  128. mWidth = width;
  129. mHeight = height;
  130. mIsDirty = true;
  131. }
  132. void GUIArea::setClipRect(const Rect2I& clipRect)
  133. {
  134. mClipRect = clipRect;
  135. mIsDirty = true;
  136. }
  137. void GUIArea::updateSizeBasedOnParent(UINT32 parentWidth, UINT32 parentHeight)
  138. {
  139. if(mResizeXWithWidget)
  140. mWidth = (UINT32)std::max(0, (INT32)parentWidth - (INT32)mLeft - (INT32)mRight);
  141. if(mResizeYWithWidget)
  142. mHeight = (UINT32)std::max(0, (INT32)parentHeight - (INT32)mTop - (INT32)mBottom);
  143. if(mResizeXWithWidget || mResizeYWithWidget)
  144. mIsDirty = true;
  145. }
  146. }