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