Merge "Clean up the code to build successfully on macOS" into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / event / actors / layer-list.cpp
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/event/actors/layer-list.h>
20
21 // EXTERNAL INCLUDES
22 #include <algorithm>  // for std::swap
23
24 // INTERNAL INCLUDES
25 #include <dali/integration-api/debug.h>
26 #include <dali/internal/event/actors/layer-impl.h>
27 #include <dali/internal/update/manager/update-manager.h>
28
29 namespace Dali
30 {
31
32 namespace Internal
33 {
34
35 namespace // unnamed namespace
36 {
37
38 typedef std::vector<Layer*> LayerContainer;
39 using LayerIter        = LayerContainer::iterator;
40 using ReverseLayerIter = LayerContainer::reverse_iterator;
41
42 /**
43  * A private helper template to return an iterator to the layer passed in.
44  * @param[in] first position to start searching from
45  * @param[in] last position to search to
46  * @param[in] layer to search for
47  * @return iterator to layer if found
48  */
49 template<class InputIterator> InputIterator Find( InputIterator first, InputIterator last, const Layer& layer )
50 {
51   for( ; first != last ; ++first )
52   {
53     if( *first == &layer )
54     {
55       break;
56     }
57  }
58  return first;
59 }
60
61 } // unnamed namespace
62
63 LayerList* LayerList::New( SceneGraph::UpdateManager& updateManager )
64 {
65   return new LayerList( updateManager );
66 }
67
68 LayerList::~LayerList() = default;
69
70 uint32_t LayerList::GetLayerCount() const
71 {
72   return static_cast<uint32_t>( mLayers.size() ); //  // only 4,294,967,295 layers supported
73 }
74
75 Layer* LayerList::GetLayer( uint32_t depth ) const
76 {
77   DALI_ASSERT_ALWAYS( depth < mLayers.size() );
78
79   return mLayers[ depth ];
80 }
81
82 uint32_t LayerList::GetDepth( const Layer* layer ) const
83 {
84   for( uint32_t count = 0; count < mLayers.size(); ++count )
85   {
86     if( layer == mLayers[ count ] )
87     {
88       return count;
89     }
90   }
91   return 0;
92 }
93
94 void LayerList::RegisterLayer(Layer& layer)
95 {
96   DALI_ASSERT_DEBUG(  mLayers.end() == Find( mLayers.begin(), mLayers.end(), layer) );
97   mLayers.push_back(&layer);
98
99   SetLayerDepths();
100 }
101
102 void LayerList::UnregisterLayer(Layer& layer)
103 {
104   // Find the layer...
105   LayerIter iter = Find( mLayers.begin(), mLayers.end(), layer);
106   DALI_ASSERT_DEBUG(iter != mLayers.end());
107
108   // ...and remove it
109   mLayers.erase(iter);
110
111   SetLayerDepths();
112 }
113
114 void LayerList::RaiseLayer(Layer& raiseLayer)
115 {
116   LayerIter iter = Find( mLayers.begin(), mLayers.end(), raiseLayer);
117
118   if (iter   != mLayers.end() &&
119       iter+1 != mLayers.end())
120   {
121     LayerIter nextIter = iter+1;
122
123     // Swap the pointers
124     std::swap(*iter, *nextIter);
125
126     SetLayerDepths();
127   }
128 }
129
130 void LayerList::LowerLayer(Layer& lowerLayer)
131 {
132   ReverseLayerIter iter =  Find( mLayers.rbegin(), mLayers.rend(), lowerLayer);
133
134   if (iter   != mLayers.rend() &&
135       iter+1 != mLayers.rend())
136   {
137     ReverseLayerIter nextIter = iter+1;
138
139     // Swap the pointers
140     std::swap(*iter, *nextIter);
141
142     SetLayerDepths();
143   }
144 }
145
146 void LayerList::RaiseLayerToTop( const Layer& layer )
147 {
148   LayerIter iter = Find( mLayers.begin(), mLayers.end(), layer);
149
150   if (iter   != mLayers.end() &&
151       iter+1 != mLayers.end())
152   {
153     Layer* raised = *iter;
154
155     copy(iter+1, mLayers.end(), iter);
156     mLayers.back() = raised;
157
158     SetLayerDepths();
159   }
160 }
161
162 void LayerList::LowerLayerToBottom( const Layer& layer )
163 {
164   ReverseLayerIter iter =  Find( mLayers.rbegin(), mLayers.rend(), layer);
165
166   if (iter   != mLayers.rend() &&
167       iter+1 != mLayers.rend())
168   {
169     Layer* lowered = *iter;
170
171     copy(iter+1, mLayers.rend(), iter);
172     mLayers.front() = lowered;
173
174     SetLayerDepths();
175   }
176 }
177
178 void LayerList::MoveLayerAbove( const Layer& layer, const Layer& target )
179 {
180   // check if it already is
181   if( layer.GetDepth() == ( target.GetDepth() + 1 ) )
182   {
183     return;
184   }
185
186   // find the layer to move
187   LayerIter iter = Find( mLayers.begin(), mLayers.end(), layer);
188
189   if( iter != mLayers.end() )
190   {
191     Layer* moved = *iter;
192     mLayers.erase( iter );
193     // find target
194     LayerIter iterT = Find( mLayers.begin(), mLayers.end(), target);
195     // if target is not found there's a programming error somewhere
196     DALI_ASSERT_DEBUG( iterT != mLayers.end() );
197     // iterT might be the last
198     if( ( iterT+1 ) == mLayers.end() )
199     {
200       mLayers.push_back( moved );
201     }
202     else
203     {
204       mLayers.insert( iterT+1, moved );
205     }
206
207     SetLayerDepths();
208   }
209 }
210
211 void LayerList::MoveLayerBelow( const Layer& layer, const Layer& target )
212 {
213   // check if it already is in correct order
214   if( layer.GetDepth() == ( target.GetDepth() - 1 ) )
215   {
216     return;
217   }
218
219   // find the layer to move
220   LayerIter iter = Find( mLayers.begin(), mLayers.end(), layer);
221   if( iter != mLayers.end() )
222   {
223     Layer* moved = *iter;
224     mLayers.erase( iter );
225     // find target
226     LayerIter iterT = Find( mLayers.begin(), mLayers.end(), target);
227     // if target is not found there's a programming error somewhere
228     DALI_ASSERT_DEBUG( iterT != mLayers.end() );
229     mLayers.insert( iterT, moved );
230
231     SetLayerDepths();
232   }
233 }
234
235 LayerList::LayerList( SceneGraph::UpdateManager& updateManager )
236 : mUpdateManager( updateManager ),
237   mRoot( nullptr )
238 {
239 }
240
241 void LayerList::SetLayerDepths()
242 {
243   // we've got a list of on-stage layers on actor side, need to get their stage
244   // pointers so we can send them to the update manager
245   std::vector< SceneGraph::Layer* > layers;
246   layers.reserve( mLayers.size() );
247
248   // Set the layers (possibly) new depth
249   for (LayerIter iter = mLayers.begin(); iter != mLayers.end(); ++iter)
250   {
251     SceneGraph::Layer* layerPtr = const_cast< SceneGraph::Layer* >( &( (*iter)->GetSceneGraphLayer() ) );
252     layers.push_back( layerPtr );
253   }
254
255   // Layers are being used in a separate thread; queue a message to set order
256   SetLayerDepthsMessage( mUpdateManager, layers, &( mRoot->GetSceneGraphLayer() ) );
257 }
258
259 void LayerList::SetRootLayer(Layer* rootLayer)
260 {
261   mRoot = rootLayer;
262
263   SetLayerDepths();
264 }
265
266 } // namespace Internal
267
268 } // namespace Dali