1//************************************ bs::framework - Copyright 2018 Marko Pintera **************************************//
2//*********** Licensed under the MIT license. See LICENSE.md for full terms. This notice is not to be removed. ***********//
3#pragma once
4
5#include "BsPrerequisites.h"
6#include "GUI/BsGUILayout.h"
7
8namespace bs
9{
10 /** @addtogroup GUI
11 * @{
12 */
13
14 /** Represents a GUI panel that you can use for free placement of GUI elements within its bounds. */
15 class BS_EXPORT GUIPanel final : public GUILayout
16 {
17 public:
18 GUIPanel() = default;
19 GUIPanel(INT16 depth, UINT16 depthRangeMin, UINT16 depthRangeMax, const GUIDimensions& dimensions);
20 ~GUIPanel() = default;
21
22 /**
23 * Changes values that control at which depth is GUI panel and its children rendered.
24 *
25 * @param[in] depth Determines rendering order of the GUI panel. Panels with lower depth will be
26 * rendered in front of panels with higher depth. Provided depth is relative to depth
27 * of the parent GUI panel (if any).
28 * @param[in] depthRangeMin Minimum range of depths that children of this GUI panel can have. If any panel has
29 * depth outside of the range [depth - depthRangeMin, depth + depthRangeMax] it will
30 * be clamped to nearest extreme. Value of -1 means infinite range.
31 * @param[in] depthRangeMax Maximum range of depths that children of this GUI panel can have. If any panel has
32 * depth outside of the range [depth - depthRangeMin, depth + depthRangeMax] it will
33 * be clamped to nearest extreme. Value of -1 means infinite range.
34 */
35 void setDepthRange(INT16 depth = 0, UINT16 depthRangeMin = -1, UINT16 depthRangeMax = -1);
36
37 /**
38 * Creates a new GUI panel.
39 *
40 * @param[in] depth Determines rendering order of the GUI panel. Panels with lower depth will be
41 * rendered in front of panels with higher depth. Provided depth is relative to depth
42 * of the parent GUI panel (if any).
43 * @param[in] depthRangeMin Minimum range of depths that children of this GUI panel can have. If any panel has
44 * depth outside of the range [depth - depthRangeMin, depth + depthRangeMax] it will
45 * be clamped to nearest extreme. Value of -1 means infinite range.
46 * @param[in] depthRangeMax Maximum range of depths that children of this GUI panel can have. If any panel has
47 * depth outside of the range [depth - depthRangeMin, depth + depthRangeMax] it will
48 * be clamped to nearest extreme. Value of -1 means infinite range.
49 */
50 static GUIPanel* create(INT16 depth = 0, UINT16 depthRangeMin = -1, UINT16 depthRangeMax = -1);
51
52 /**
53 * Creates a new GUI panel.
54 *
55 * @param[in] options Options that allow you to control how is the element positioned and sized.
56 */
57 static GUIPanel* create(const GUIOptions& options);
58
59 /**
60 * Creates a new GUI panel.
61 *
62 * @param[in] depth Determines rendering order of the GUI panel. Panels with lower depth will be
63 * rendered in front of panels with higher depth. Provided depth is relative to depth
64 * of the parent GUI panel (if any).
65 * @param[in] depthRangeMin Minimum range of depths that children of this GUI panel can have. If any panel has
66 * depth outside of the range [depth - depthRangeMin, depth + depthRangeMax] it will be
67 * clamped to nearest extreme. Value of -1 means infinite range.
68 * @param[in] depthRangeMax Maximum range of depths that children of this GUI panel can have. If any panel has
69 * depth outside of the range [depth - depthRangeMin, depth + depthRangeMax] it will be
70 * clamped to nearest extreme. Value of -1 means infinite range.
71 * @param[in] options Options that allow you to control how is the element positioned and sized.
72 */
73 static GUIPanel* create(INT16 depth, UINT16 depthRangeMin, UINT16 depthRangeMax, const GUIOptions& options);
74
75 public: // ***** INTERNAL ******
76 /** @name Internal
77 * @{
78 */
79
80 /** @copydoc GUIElementBase::_getType */
81 Type _getType() const override { return GUIElementBase::Type::Panel; }
82
83 /** Calculate optimal sizes of all child layout elements. */
84 void _updateOptimalLayoutSizes() override;
85
86 /** @copydoc GUIElementBase::_calculateLayoutSizeRange */
87 LayoutSizeRange _calculateLayoutSizeRange() const override;
88
89 /** @copydoc GUILayout::_getElementAreas */
90 void _getElementAreas(const Rect2I& layoutArea, Rect2I* elementAreas, UINT32 numElements,
91 const Vector<LayoutSizeRange>& sizeRanges, const LayoutSizeRange& mySizeRange) const override;
92
93 /** Calculates the size of the provided child within this layout with the provided dimensions. */
94 Rect2I _getElementArea(const Rect2I& layoutArea, const GUIElementBase* element, const LayoutSizeRange& sizeRange) const;
95
96 /**
97 * Calculates an element size range for the provided child of the GUI panel. Will return cached bounds so make sure
98 * to update optimal size ranges before calling.
99 */
100 LayoutSizeRange _getElementSizeRange(const GUIElementBase* element) const;
101
102 /** Assigns the specified layout information to a child element of a GUI panel. */
103 void _updateChildLayout(GUIElementBase* element, const GUILayoutData& data);
104
105 /** @copydoc GUIElementBase::_updateLayoutInternal */
106 void _updateLayoutInternal(const GUILayoutData& data) override;
107
108 /**
109 * Updates the provided depth range by taking into consideration the depth range of the panel. This depth range
110 * should be passed on to child elements of the panel.
111 */
112 void _updateDepthRange(GUILayoutData& data);
113
114 /** @} */
115
116 protected:
117 INT16 mDepthOffset;
118 UINT16 mDepthRangeMin;
119 UINT16 mDepthRangeMax;
120 };
121
122 /** @} */
123}