[dali_1.3.41] Merge branch '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 #include <dali/public-api/common/dali-common.h>
21 #include <dali-toolkit/devel-api/layouting/layout-length.h>
22 #include <dali-toolkit/public-api/dali-toolkit-common.h>
23
24 #include <sstream>
25
26 namespace Dali
27 {
28 namespace Toolkit
29 {
30
31 /**
32  * A MeasureSpec is used during the Measure pass by a LayoutGroup to inform it's children
33  * how to be measured. For instance, it may measure a child with an exact width and an unspecified
34  * height in order to determine height for width.
35  */
36 class DALI_TOOLKIT_API MeasureSpec
37 {
38 public:
39   using IntType = LayoutLength::IntType;
40
41   enum class Mode
42   {
43     UNSPECIFIED, ///< This is used by a parent to determine the desired dimension of a child layout.
44     EXACTLY, /** This is used by a parent to impose an exact size on the child. The child must use
45                  this size, and guarantee that all of its descendants will fit within this size */
46     AT_MOST /** This is used by the parent to impose a maximum size on the child. The child must guarantee
47              * that it and all of it's descendants will fit within this size. */
48   };
49
50   MeasureSpec( LayoutLength measureSpec, MeasureSpec::Mode mode )
51   : mSize( measureSpec.mValue ),
52     mMode( mode )
53   {
54   }
55
56   MeasureSpec( IntType measureSpec )
57   : mSize( measureSpec ),
58     mMode( Mode::UNSPECIFIED )
59   {
60   }
61
62   ~MeasureSpec() = default;
63
64   MeasureSpec& operator=( const MeasureSpec& rhs )
65   {
66     if( this != &rhs )
67     {
68       this->mSize = rhs.mSize;
69       this->mMode = rhs.mMode;
70     }
71     return *this;
72   }
73
74   bool operator==( MeasureSpec value )
75   {
76     return mSize == value.mSize;
77   }
78
79   bool operator!=( MeasureSpec value )
80   {
81     return mSize != value.mSize;
82   }
83
84   /**
85    * @brief Get the mode of the measure spec.
86    *
87    * @return The mode of the measure spec
88    */
89   MeasureSpec::Mode GetMode() const
90   {
91     return mMode;
92   }
93
94   /**
95    * @brief Get the size of the measure spec
96    *
97    * @return the size of the measure spec
98    */
99   IntType GetSize() const
100   {
101     return mSize;
102   }
103
104   /**
105    * @brief Adjust the measure size by the given delta.
106    *
107    * Used only for EXACT and AT_MOST modes.
108    * @param[in] measureSpec the measure spec to adjust
109    * @param[in] delta A positive or negative value to adjust the measure spec by.
110    *
111    * @note if the adjusted size is negative, it is zeroed.
112    * @return A new measure spec with the adjusted values.
113    */
114   static MeasureSpec Adjust( MeasureSpec measureSpec, int delta )
115   {
116     auto mode = measureSpec.GetMode();
117     auto size = measureSpec.GetSize();
118
119     if( mode == MeasureSpec::Mode::UNSPECIFIED )
120     {
121       return MeasureSpec( size, MeasureSpec::Mode::UNSPECIFIED );
122     }
123
124     if( delta < 0 && measureSpec.mSize < static_cast<IntType>(abs(delta)) )
125     {
126       size = 0;
127     }
128     else
129     {
130       size += delta;
131     }
132     return MeasureSpec( size, mode );
133   }
134
135 public:
136   IntType  mSize; ///< The specified size
137   Mode     mMode; ///< The measure mode
138 };
139
140 inline std::ostream& operator<< (std::ostream& o, const MeasureSpec& measureSpec )
141 {
142   return o << ( (measureSpec.GetMode() == MeasureSpec::Mode::UNSPECIFIED ? "Unspecified"
143                  : (measureSpec.GetMode() == MeasureSpec::Mode::EXACTLY ? "Exactly":"At most" ) ) )
144            << " " << measureSpec.GetSize();
145 }
146
147 } //namespace Toolkit
148 } //namespace Dali
149
150
151 #endif // DALI_TOOLKIT_LAYOUTING_MEASURE_SPEC_H