BsGUILayoutUtility.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #include "BsGUILayoutUtility.h"
  2. #include "BsGUIElementBase.h"
  3. #include "BsGUILayout.h"
  4. #include "BsGUIElement.h"
  5. #include "BsGUIElementStyle.h"
  6. #include "BsGUIWidget.h"
  7. #include "BsViewport.h"
  8. #include "BsGUIPanel.h"
  9. namespace BansheeEngine
  10. {
  11. Vector2I GUILayoutUtility::calcOptimalSize(const GUIElementBase* elem)
  12. {
  13. return elem->_calculateLayoutSizeRange().optimal;
  14. }
  15. Rect2I GUILayoutUtility::calcBounds(const GUIElementBase* elem, GUIPanel* relativeTo)
  16. {
  17. Rect2I parentArea;
  18. GUIElementBase* parent = elem->_getParent();
  19. if (parent != nullptr)
  20. {
  21. parentArea = calcBounds(parent);
  22. if (parent->_getType() == GUIElementBase::Type::Panel && (relativeTo == nullptr || relativeTo == parent))
  23. {
  24. parentArea.x = 0;
  25. parentArea.y = 0;
  26. }
  27. }
  28. else
  29. {
  30. GUIWidget* parentWidget = elem->_getParentWidget();
  31. if (parentWidget != nullptr)
  32. {
  33. parentArea.width = parentWidget->getTarget()->getWidth();
  34. parentArea.height = parentWidget->getTarget()->getHeight();
  35. }
  36. return parentArea;
  37. }
  38. UINT32 numElements = (UINT32)parent->_getNumChildren();
  39. UINT32 myIndex = 0;
  40. Vector<LayoutSizeRange> sizeRanges;
  41. for (UINT32 i = 0; i < numElements; i++)
  42. {
  43. GUIElementBase* child = parent->_getChild(i);
  44. if (child == elem)
  45. myIndex = i;
  46. sizeRanges.push_back(child->_calculateLayoutSizeRange());
  47. }
  48. Rect2I* elementAreas = nullptr;
  49. if (numElements > 0)
  50. elementAreas = stackConstructN<Rect2I>(numElements);
  51. parent->_getElementAreas(parentArea.x, parentArea.y, parentArea.width, parentArea.height, elementAreas,
  52. numElements, sizeRanges, parent->_calculateLayoutSizeRange());
  53. Rect2I myArea = elementAreas[myIndex];
  54. if (elementAreas != nullptr)
  55. stackDeallocLast(elementAreas);
  56. return myArea;
  57. }
  58. Vector2I GUILayoutUtility::calcActualSize(UINT32 width, UINT32 height, const GUILayout* layout)
  59. {
  60. UINT32 numElements = (UINT32)layout->_getNumChildren();
  61. Vector<LayoutSizeRange> sizeRanges;
  62. for (UINT32 i = 0; i < numElements; i++)
  63. {
  64. GUIElementBase* child = layout->_getChild(i);
  65. sizeRanges.push_back(child->_calculateLayoutSizeRange());
  66. }
  67. Rect2I* elementAreas = nullptr;
  68. if (numElements > 0)
  69. elementAreas = stackConstructN<Rect2I>(numElements);
  70. layout->_getElementAreas(0, 0, width, height, elementAreas, numElements, sizeRanges, layout->_calculateLayoutSizeRange());
  71. Rect2I* actualAreas = elementAreas; // We re-use the same array
  72. for (UINT32 i = 0; i < numElements; i++)
  73. {
  74. GUIElementBase* child = layout->_getChild(i);
  75. Rect2I childArea = elementAreas[i];
  76. if (child->_getType() == GUIElementBase::Type::Layout || child->_getType() == GUIElementBase::Type::Panel)
  77. {
  78. Vector2I childActualSize = calcActualSize(childArea.width, childArea.height, static_cast<GUILayout*>(child));
  79. actualAreas[i].width = (UINT32)childActualSize.x;
  80. actualAreas[i].height = (UINT32)childActualSize.y;
  81. }
  82. else if (child->_getType() == GUIElementBase::Type::Element)
  83. {
  84. RectOffset padding = child->_getPadding();
  85. actualAreas[i].width = elementAreas[i].width + padding.left + padding.right;
  86. actualAreas[i].height = elementAreas[i].height + padding.top + padding.bottom;
  87. }
  88. else
  89. {
  90. actualAreas[i].width = elementAreas[i].width;
  91. actualAreas[i].height = elementAreas[i].height;
  92. }
  93. }
  94. Vector2I actualSize = layout->_calcActualSize(0, 0, actualAreas, numElements);
  95. if (elementAreas != nullptr)
  96. stackDeallocLast(elementAreas);
  97. return actualSize;
  98. }
  99. }