1 /*
2   ==============================================================================
3 
4    This file is part of the JUCE library.
5    Copyright (c) 2020 - Raw Material Software Limited
6 
7    JUCE is an open source library subject to commercial or open-source
8    licensing.
9 
10    By using JUCE, you agree to the terms of both the JUCE 6 End-User License
11    Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
12 
13    End User License Agreement: www.juce.com/juce-6-licence
14    Privacy Policy: www.juce.com/juce-privacy-policy
15 
16    Or: You may also use this code under the terms of the GPL v3 (see
17    www.gnu.org/licenses).
18 
19    JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20    EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21    DISCLAIMED.
22 
23   ==============================================================================
24 */
25 
26 namespace juce
27 {
28 
29 /**
30     Defines an item in a Grid
31     @see Grid
32 
33     @tags{GUI}
34 */
35 class JUCE_API  GridItem
36 {
37 public:
38     enum class Keyword { autoValue };
39 
40     //==============================================================================
41     /** Represents a span. */
42     struct Span
43     {
SpanSpan44         explicit Span (int numberToUse) noexcept : number (numberToUse)
45         {
46             /* Span must be at least one and positive */
47             jassert (numberToUse > 0);
48         }
49 
SpanSpan50         explicit Span (int numberToUse, const String& nameToUse) : Span (numberToUse)
51         {
52             /* Name must not be empty */
53             jassert (nameToUse.isNotEmpty());
54             name = nameToUse;
55         }
56 
SpanSpan57         explicit Span (const String& nameToUse) : name (nameToUse)
58         {
59             /* Name must not be empty */
60             jassert (nameToUse.isNotEmpty());
61         }
62 
63         int number = 1;
64         String name;
65     };
66 
67     //==============================================================================
68     /** Represents a property. */
69     struct Property
70     {
71         Property() noexcept;
72 
73         Property (Keyword keyword) noexcept;
74 
75         Property (const char* lineNameToUse) noexcept;
76 
77         Property (const String& lineNameToUse) noexcept;
78 
79         Property (int numberToUse) noexcept;
80 
81         Property (int numberToUse, const String& lineNameToUse) noexcept;
82 
83         Property (Span spanToUse) noexcept;
84 
hasSpanProperty85         bool hasSpan() const noexcept          { return isSpan && ! isAuto; }
hasAbsoluteProperty86         bool hasAbsolute() const noexcept      { return ! (isSpan || isAuto);  }
hasAutoProperty87         bool hasAuto() const noexcept          { return isAuto; }
hasNameProperty88         bool hasName() const noexcept          { return name.isNotEmpty(); }
getNameProperty89         const String& getName() const noexcept { return name; }
getNumberProperty90         int getNumber() const noexcept         { return number; }
91 
92     private:
93         String name;
94         int number = 1; /** Either an absolute line number or number of lines to span across. */
95         bool isSpan = false;
96         bool isAuto = false;
97     };
98 
99     //==============================================================================
100     /** Represents start and end properties. */
101     struct StartAndEndProperty { Property start, end; };
102 
103     //==============================================================================
104     /** Possible values for the justifySelf property. */
105     enum class JustifySelf : int
106     {
107         start = 0,               /**< Content inside the item is justified towards the left. */
108         end,                     /**< Content inside the item is justified towards the right. */
109         center,                  /**< Content inside the item is justified towards the center. */
110         stretch,                 /**< Content inside the item is stretched from left to right. */
111         autoValue                /**< Follows the Grid container's justifyItems property. */
112     };
113 
114     /** Possible values for the alignSelf property. */
115     enum class AlignSelf   : int
116     {
117         start = 0,               /**< Content inside the item is aligned towards the top. */
118         end,                     /**< Content inside the item is aligned towards the bottom. */
119         center,                  /**< Content inside the item is aligned towards the center. */
120         stretch,                 /**< Content inside the item is stretched from top to bottom. */
121         autoValue                /**< Follows the Grid container's alignItems property. */
122     };
123 
124     /** Creates an item with default parameters. */
125     GridItem() noexcept;
126     /** Creates an item with a given Component to use. */
127     GridItem (Component& componentToUse) noexcept;
128     /** Creates an item with a given Component to use. */
129     GridItem (Component* componentToUse) noexcept;
130 
131     /** Destructor. */
132     ~GridItem() noexcept;
133 
134     //==============================================================================
135     /** If this is non-null, it represents a Component whose bounds are controlled by this item. */
136     Component* associatedComponent = nullptr;
137 
138     //==============================================================================
139     /** Determines the order used to lay out items in their grid container. */
140     int order = 0;
141 
142     /** This is the justify-self property of the item.
143         This determines the alignment of the item along the row.
144     */
145     JustifySelf  justifySelf = JustifySelf::autoValue;
146 
147     /** This is the align-self property of the item.
148         This determines the alignment of the item along the column.
149     */
150     AlignSelf    alignSelf   = AlignSelf::autoValue;
151 
152     /** These are the start and end properties of the column. */
153     StartAndEndProperty column = { Keyword::autoValue, Keyword::autoValue };
154 
155     /** These are the start and end properties of the row. */
156     StartAndEndProperty row    = { Keyword::autoValue, Keyword::autoValue };
157 
158     /** */
159     String area;
160 
161     //==============================================================================
162     enum
163     {
164         useDefaultValue = -2, /* TODO: useDefaultValue should be named useAuto */
165         notAssigned = -1
166     };
167 
168     /* TODO: move all of this into a common class that is shared with the FlexItem */
169     float width    = notAssigned;
170     float minWidth = 0.0f;
171     float maxWidth = notAssigned;
172 
173     float height    = notAssigned;
174     float minHeight = 0.0f;
175     float maxHeight = notAssigned;
176 
177     /** Represents a margin. */
178     struct Margin
179     {
180         Margin() noexcept;
181         Margin (int size) noexcept;
182         Margin (float size) noexcept;
183         Margin (float top, float right, float bottom, float left) noexcept;   /**< Creates a margin with these sizes. */
184 
185         float left;
186         float right;
187         float top;
188         float bottom;
189     };
190 
191     /** The margin to leave around this item. */
192     Margin margin;
193 
194     /** The item's current bounds. */
195     Rectangle<float> currentBounds;
196 
197     /** Short-hand */
198     void setArea (Property rowStart, Property columnStart, Property rowEnd, Property columnEnd);
199 
200     /** Short-hand, span of 1 by default */
201     void setArea (Property rowStart, Property columnStart);
202 
203     /** Short-hand */
204     void setArea (const String& areaName);
205 
206     /** Short-hand */
207     GridItem withArea (Property rowStart, Property columnStart, Property rowEnd, Property columnEnd) const noexcept;
208 
209     /** Short-hand, span of 1 by default */
210     GridItem withArea (Property rowStart, Property columnStart) const noexcept;
211 
212     /** Short-hand */
213     GridItem withArea (const String& areaName)  const noexcept;
214 
215     /** Returns a copy of this object with a new row property. */
216     GridItem withRow (StartAndEndProperty row) const noexcept;
217 
218     /** Returns a copy of this object with a new column property. */
219     GridItem withColumn (StartAndEndProperty column) const noexcept;
220 
221     /** Returns a copy of this object with a new alignSelf property. */
222     GridItem withAlignSelf (AlignSelf newAlignSelf) const noexcept;
223 
224     /** Returns a copy of this object with a new justifySelf property. */
225     GridItem withJustifySelf (JustifySelf newJustifySelf) const noexcept;
226 
227     /** Returns a copy of this object with a new width. */
228     GridItem withWidth (float newWidth) const noexcept;
229 
230     /** Returns a copy of this object with a new height. */
231     GridItem withHeight (float newHeight) const noexcept;
232 
233     /** Returns a copy of this object with a new size. */
234     GridItem withSize (float newWidth, float newHeight) const noexcept;
235 
236     /** Returns a copy of this object with a new margin. */
237     GridItem withMargin (Margin newMargin) const noexcept;
238 
239     /** Returns a copy of this object with a new order. */
240     GridItem withOrder (int newOrder) const noexcept;
241 };
242 
243 } // namespace juce
244