| 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 | } |