Merge "Do not substarct outline width in text-controller" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / devel-api / layouting / measure-spec.h
1 #ifndef DALI_TOOLKIT_LAYOUTING_MEASURE_SPEC_H
2 #define DALI_TOOLKIT_LAYOUTING_MEASURE_SPEC_H
3
4 /*
5  * Copyright (c) 2018 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 // EXTERNAL INCLUDES
21 #include <sstream>
22 #include <dali/public-api/common/dali-common.h>
23
24 // INTERNAL INCLUDES
25 #include <dali-toolkit/devel-api/layouting/layout-length.h>
26 #include <dali-toolkit/public-api/dali-toolkit-common.h>
27
28 namespace Dali
29 {
30 namespace Toolkit
31 {
32
33 /**
34  * A MeasureSpec is used during the Measure pass by a LayoutGroup to inform it's children
35  * how to be measured. For instance, it may measure a child with an exact width and an unspecified
36  * height in order to determine height for width.
37  */
38 class DALI_TOOLKIT_API MeasureSpec
39 {
40 public:
41
42   enum class Mode
43   {
44     UNSPECIFIED, ///< This is used by a parent to determine the desired dimension of a child layout.
45     EXACTLY, /** This is used by a parent to impose an exact size on the child. The child must use
46                  this size, and guarantee that all of its descendants will fit within this size */
47     AT_MOST /** This is used by the parent to impose a maximum size on the child. The child must guarantee
48              * that it and all of it's descendants will fit within this size. */
49   };
50
51   MeasureSpec( LayoutLength measureSpec, MeasureSpec::Mode mode )
52   : mSize( measureSpec ),
53     mMode( mode )
54   {
55   }
56
57   MeasureSpec( LayoutLength measureSpec )
58   : mSize( measureSpec ),
59     mMode( Mode::UNSPECIFIED )
60   {
61   }
62
63   ~MeasureSpec() = default;
64
65   MeasureSpec& operator=( const MeasureSpec& rhs )
66   {
67     if( this != &rhs )
68     {
69       this->mSize = rhs.mSize;
70       this->mMode = rhs.mMode;
71     }
72     return *this;
73   }
74
75   bool operator==( MeasureSpec value )
76   {
77     return mSize == value.mSize;
78   }
79
80   bool operator!=( MeasureSpec value )
81   {
82     return mSize != value.mSize;
83   }
84
85   /**
86    * @brief Set the mode of the measure spec.
87    *
88    * @param mode The mode to set
89    */
90   void SetMode( MeasureSpec::Mode mode )
91   {
92     mMode = mode;
93   }
94
95   /**
96    * @brief Get the mode of the measure spec.
97    *
98    * @return The mode of the measure spec
99    */
100   MeasureSpec::Mode GetMode() const
101   {
102     return mMode;
103   }
104
105   /**
106    * @brief Set the size of the measure spec
107    *
108    * @param size the size to set
109    */
110   void SetSize( LayoutLength size )
111   {
112     mSize = size;
113   }
114
115   /**
116    * @brief Get the size of the measure spec
117    *
118    * @return the size of the measure spec
119    */
120   LayoutLength GetSize() const
121   {
122     return mSize;
123   }
124
125   /**
126    * @brief Adjust the measure size by the given delta.
127    *
128    * Used only for EXACT and AT_MOST modes.
129    * @param[in] measureSpec the measure spec to adjust
130    * @param[in] delta A positive or negative value to adjust the measure spec by.
131    *
132    * @note if the adjusted size is negative, it is zeroed.
133    * @return A new measure spec with the adjusted values.
134    */
135   static MeasureSpec Adjust( MeasureSpec measureSpec, int delta )
136   {
137     auto mode = measureSpec.GetMode();
138     auto size = measureSpec.GetSize();
139
140     if( mode == MeasureSpec::Mode::UNSPECIFIED )
141     {
142       return MeasureSpec( size, MeasureSpec::Mode::UNSPECIFIED );
143     }
144
145     if( delta < 0 && measureSpec.mSize < abs(delta) )
146     {
147       size = 0;
148     }
149     else
150     {
151       size += delta;
152     }
153     return MeasureSpec( size, mode );
154   }
155
156 private:
157
158   LayoutLength  mSize; ///< The specified size
159   Mode     mMode; ///< The measure mode
160
161 };
162
163 inline std::ostream& operator<< (std::ostream& o, const MeasureSpec& measureSpec )
164 {
165   return o << ( (measureSpec.GetMode() == MeasureSpec::Mode::UNSPECIFIED ? "Unspecified"
166                  : (measureSpec.GetMode() == MeasureSpec::Mode::EXACTLY ? "Exactly":"At most" ) ) )
167            << " " << measureSpec.GetSize();
168 }
169
170 } //namespace Toolkit
171 } //namespace Dali
172
173
174 #endif // DALI_TOOLKIT_LAYOUTING_MEASURE_SPEC_H