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 "Math/BsVector2I.h" |
7 | #include "Math/BsRect2I.h" |
8 | |
9 | namespace bs |
10 | { |
11 | /** @addtogroup GUI-Internal |
12 | * @{ |
13 | */ |
14 | |
15 | /** |
16 | * Determines how will the drop down box be positioned. Usually the system will attempt to position the drop box in a |
17 | * way so all elements can fit, and this class allows you to specify some limitations on how that works. |
18 | * |
19 | * @note For example, list boxes usually want drop down boxes to be placed above or below them, while |
20 | * context menus may want to have them placed around a single point in any direction. |
21 | */ |
22 | class BS_EXPORT DropDownAreaPlacement |
23 | { |
24 | public: |
25 | /** Determines how will the drop down box be positioned. */ |
26 | enum class Type |
27 | { |
28 | Position, |
29 | BoundsVert, |
30 | BoundsHorz, |
31 | BoundsAll |
32 | }; |
33 | |
34 | /** |
35 | * Preferred horizontal direction of the placement bounds, either to the left or to the right of the wanted |
36 | * position/bounds. |
37 | */ |
38 | enum class HorzDir |
39 | { |
40 | Left, Right |
41 | }; |
42 | |
43 | /** |
44 | * Preferred horizontal direction of the placement bounds, either upward or downward of the wanted position/bounds. |
45 | */ |
46 | enum class VertDir |
47 | { |
48 | Up, Down |
49 | }; |
50 | |
51 | DropDownAreaPlacement() = default; |
52 | |
53 | /** |
54 | * Drop down box will be placed at the specified position. By default the system prefers the top left corner of the |
55 | * box to correspond to the position, but if other corners offer more space for the contents, those will be used |
56 | * instead. |
57 | */ |
58 | static DropDownAreaPlacement aroundPosition(const Vector2I& position); |
59 | |
60 | /** |
61 | * Drop down box will be placed at the specified bounds. Box will be horizontally aligned to the left of the |
62 | * provided bounds. Vertically system prefers placing the box at the bottom of the bounds, but may choose to align |
63 | * it with the top of the bounds if it offers more space for the contents. |
64 | */ |
65 | static DropDownAreaPlacement aroundBoundsVert(const Rect2I& bounds); |
66 | |
67 | /** |
68 | * Drop down box will be placed at the specified bounds. Box will be vertically aligned to the top of the provided |
69 | * bounds. Horizontally system prefers placing the box at the right of the bounds, but may choose to align it with |
70 | * the left of the bounds if it offers more space for the contents. |
71 | */ |
72 | static DropDownAreaPlacement aroundBoundsHorz(const Rect2I& bounds); |
73 | |
74 | /** |
75 | * Drop down box will be placed at the specified bounds. Box will be vertically aligned to the top or bottom of the |
76 | * provided bounds, with bottom being preferred. Horizontally system prefers placing the box at the right of the |
77 | * bounds, but may choose to align it with the left of the bounds if it offers more space for the contents. |
78 | */ |
79 | static DropDownAreaPlacement aroundBounds(const Rect2I& bounds); |
80 | |
81 | /** Returns drop down box positioning type. */ |
82 | Type getType() const { return mType; } |
83 | |
84 | /** Returns bounds around which to position the drop down box if one of the bounds positioning types is used. */ |
85 | const Rect2I& getBounds() const { return mBounds; } |
86 | |
87 | /** Returns position around which to position the drop down box if position positioning type is used. */ |
88 | const Vector2I& getPosition() const { return mPosition; } |
89 | |
90 | /** |
91 | * Calculates the optimal bounds to place an element of the specified size, within the available area using the |
92 | * internal data as a guide. |
93 | * |
94 | * @param[in] width Width of the element to try to position, in pixels. |
95 | * @param[in] height Height of the element to try to position, in pixels. |
96 | * @param[in] availableArea Available area to try to position the element in, in pixels. |
97 | * @param[in] horzDir Output parameter that signals the preferred horizontal direction of the bounds |
98 | * (left or right). |
99 | * @param[in] vertDir Output parameter that signals the preferred vertical direction of the bounds |
100 | * (up or down). |
101 | */ |
102 | Rect2I getOptimalBounds(UINT32 width, UINT32 height, const Rect2I& availableArea, HorzDir& horzDir, |
103 | VertDir& vertDir) const; |
104 | |
105 | private: |
106 | Type mType; |
107 | Rect2I mBounds; |
108 | Vector2I mPosition; |
109 | }; |
110 | |
111 | /** @} */ |
112 | } |