BsGUIElement.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #include "BsGUIElement.h"
  2. #include "BsGUIWidget.h"
  3. #include "BsGUISkin.h"
  4. #include "BsGUILayout.h"
  5. #include "CmException.h"
  6. using namespace CamelotFramework;
  7. namespace BansheeEngine
  8. {
  9. GUIElement::GUIElement(GUIWidget& parent, const GUIElementStyle* style, const GUILayoutOptions& layoutOptions, bool acceptsKeyboardFocus)
  10. :mParent(parent), mLayoutOptions(layoutOptions), mWidth(0), mHeight(0), mDepth(0), mStyle(style),
  11. mAcceptsKeyboardFocus(acceptsKeyboardFocus)
  12. {
  13. mParent.registerElement(this);
  14. }
  15. GUIElement::~GUIElement()
  16. {
  17. if(mParentLayout != nullptr)
  18. mParentLayout->removeElement(this);
  19. }
  20. void GUIElement::updateRenderElements()
  21. {
  22. updateRenderElementsInternal();
  23. _markAsClean();
  24. }
  25. void GUIElement::setLayoutOptions(const GUILayoutOptions& layoutOptions)
  26. {
  27. if(layoutOptions.maxWidth < layoutOptions.minWidth)
  28. {
  29. CM_EXCEPT(InvalidParametersException, "Maximum width is less than minimum width! Max width: " +
  30. toString(layoutOptions.maxWidth) + ". Min width: " + toString(layoutOptions.minWidth));
  31. }
  32. if(layoutOptions.maxHeight < layoutOptions.minHeight)
  33. {
  34. CM_EXCEPT(InvalidParametersException, "Maximum height is less than minimum height! Max height: " +
  35. toString(layoutOptions.maxHeight) + ". Min height: " + toString(layoutOptions.minHeight));
  36. }
  37. mLayoutOptions = layoutOptions;
  38. }
  39. bool GUIElement::mouseEvent(const GUIMouseEvent& ev)
  40. {
  41. return false;
  42. }
  43. bool GUIElement::keyEvent(const GUIKeyEvent& ev)
  44. {
  45. return false;
  46. }
  47. bool GUIElement::commandEvent(const GUICommandEvent& ev)
  48. {
  49. return false;
  50. }
  51. void GUIElement::_setWidgetDepth(UINT8 depth)
  52. {
  53. mDepth |= depth << 24;
  54. markMeshAsDirty();
  55. }
  56. void GUIElement::_setAreaDepth(UINT16 depth)
  57. {
  58. mDepth |= depth << 8;
  59. markMeshAsDirty();
  60. }
  61. void GUIElement::_setOffset(const CM::Int2& offset)
  62. {
  63. if(mOffset != offset)
  64. markMeshAsDirty();
  65. mOffset = offset;
  66. }
  67. void GUIElement::_setWidth(UINT32 width)
  68. {
  69. if(mWidth != width)
  70. markContentAsDirty();
  71. mWidth = width;
  72. }
  73. void GUIElement::_setHeight(UINT32 height)
  74. {
  75. if(mHeight != height)
  76. markContentAsDirty();
  77. mHeight = height;
  78. }
  79. void GUIElement::_setClipRect(const CM::Rect& clipRect)
  80. {
  81. if(mClipRect != clipRect)
  82. markMeshAsDirty();
  83. mClipRect = clipRect;
  84. }
  85. Rect GUIElement::getVisibleBounds() const
  86. {
  87. Rect bounds = _getBounds();
  88. bounds.x += mStyle->margins.left;
  89. bounds.y += mStyle->margins.top;
  90. bounds.width = (UINT32)std::max(0, (INT32)bounds.width - (INT32)(mStyle->margins.left + mStyle->margins.right));
  91. bounds.height = (UINT32)std::max(0, (INT32)bounds.height - (INT32)(mStyle->margins.top + mStyle->margins.bottom));
  92. return bounds;
  93. }
  94. Rect GUIElement::getContentBounds() const
  95. {
  96. Rect bounds;
  97. bounds.x = mOffset.x + mStyle->margins.left + mStyle->contentOffset.left;
  98. bounds.y = mOffset.y + mStyle->margins.top + mStyle->contentOffset.top;
  99. bounds.width = (UINT32)std::max(0, (INT32)mWidth -
  100. (INT32)(mStyle->margins.left + mStyle->margins.right + mStyle->contentOffset.left + mStyle->contentOffset.right));
  101. bounds.height = (UINT32)std::max(0, (INT32)mHeight -
  102. (INT32)(mStyle->margins.top + mStyle->margins.bottom + mStyle->contentOffset.top + mStyle->contentOffset.bottom));
  103. return bounds;
  104. }
  105. bool GUIElement::_isInBounds(const CM::Int2 position) const
  106. {
  107. Rect contentBounds = getVisibleBounds();
  108. return contentBounds.contains(position);
  109. }
  110. GUILayoutOptions GUIElement::getDefaultLayoutOptions(const GUIElementStyle* style)
  111. {
  112. GUILayoutOptions layoutOptions;
  113. layoutOptions.fixedWidth = style->fixedWidth;
  114. layoutOptions.fixedHeight = style->fixedHeight;
  115. layoutOptions.width = style->width;
  116. layoutOptions.height = style->height;
  117. layoutOptions.minWidth = style->minWidth;
  118. layoutOptions.maxWidth = style->maxWidth;
  119. layoutOptions.minHeight = style->minHeight;
  120. layoutOptions.maxHeight = style->maxHeight;
  121. return layoutOptions;
  122. }
  123. void GUIElement::_destroyInternal(GUIElement* element)
  124. {
  125. cm_delete<PoolAlloc>(element);
  126. }
  127. void GUIElement::destroy(GUIElement* element)
  128. {
  129. element->mParent.unregisterElement(element);
  130. cm_delete<PoolAlloc>(element);
  131. }
  132. }