Conversion to Apache 2.0 license
[platform/core/uifw/dali-core.git] / dali / internal / event / actors / layer-list.cpp
1 /*
2  * Copyright (c) 2014 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/event/common/stage-impl.h>
28 #include <dali/internal/update/manager/update-manager.h>
29
30 namespace Dali
31 {
32
33 namespace Internal
34 {
35
36
37
38 namespace // unnamed namespace
39 {
40
41 typedef std::vector<Layer*> LayerContainer;
42 typedef LayerContainer::iterator LayerIter;
43 typedef LayerContainer::reverse_iterator ReverseLayerIter;
44
45 /**
46  * A private helper template to return an iterator to the layer passed in.
47  * @param[in] first position to start searching from
48  * @param[in] last position to search to
49  * @param[in] layer to search for
50  * @return iterator to layer if found
51  */
52 template<class InputIterator> InputIterator Find( InputIterator first, InputIterator last, const Layer& layer )
53 {
54   for( ; first != last ; ++first )
55   {
56     if( *first == &layer )
57     {
58       break;
59     }
60  }
61  return first;
62 }
63
64 } // unnamed namespace
65
66 LayerList* LayerList::New( Stage& stage, bool systemLevel )
67 {
68   return new LayerList( stage, systemLevel );
69 }
70
71 LayerList::~LayerList()
72 {
73 }
74
75 unsigned int LayerList::GetLayerCount() const
76 {
77   return mLayers.size();
78 }
79
80 Layer* LayerList::GetLayer( unsigned int depth ) const
81 {
82   DALI_ASSERT_ALWAYS( depth < mLayers.size() );
83
84   return mLayers[ depth ];
85 }
86
87 unsigned int LayerList::GetDepth( const Layer* layer ) const
88 {
89   for( unsigned int count = 0; count < mLayers.size(); ++count )
90   {
91     if( layer == mLayers[ count ] )
92     {
93       return count;
94     }
95   }
96   return 0;
97 }
98
99 void LayerList::RegisterLayer(Layer& layer)
100 {
101   DALI_ASSERT_DEBUG(  mLayers.end() == Find( mLayers.begin(), mLayers.end(), layer) );
102   mLayers.push_back(&layer);
103
104   SetLayerDepths();
105 }
106
107 void LayerList::UnregisterLayer(Layer& layer)
108 {
109   // Find the layer...
110   LayerIter iter = Find( mLayers.begin(), mLayers.end(), layer);
111   DALI_ASSERT_DEBUG(iter != mLayers.end());
112
113   // ...and remove it
114   mLayers.erase(iter);
115
116   SetLayerDepths();
117 }
118
119 void LayerList::RaiseLayer(Layer& raiseLayer)
120 {
121   LayerIter iter = Find( mLayers.begin(), mLayers.end(), raiseLayer);
122
123   if (iter   != mLayers.end() &&
124       iter+1 != mLayers.end())
125   {
126     LayerIter nextIter = iter+1;
127
128     // Swap the pointers
129     std::swap(*iter, *nextIter);
130
131     SetLayerDepths();
132   }
133 }
134
135 void LayerList::LowerLayer(Layer& lowerLayer)
136 {
137   ReverseLayerIter iter =  Find( mLayers.rbegin(), mLayers.rend(), lowerLayer);
138
139   if (iter   != mLayers.rend() &&
140       iter+1 != mLayers.rend())
141   {
142     ReverseLayerIter nextIter = iter+1;
143
144     // Swap the pointers
145     std::swap(*iter, *nextIter);
146
147     SetLayerDepths();
148   }
149 }
150
151 void LayerList::RaiseLayerToTop( const Layer& layer )
152 {
153   LayerIter iter = Find( mLayers.begin(), mLayers.end(), layer);
154
155   if (iter   != mLayers.end() &&
156       iter+1 != mLayers.end())
157   {
158     Layer* raised = *iter;
159
160     copy(iter+1, mLayers.end(), iter);
161     mLayers.back() = raised;
162
163     SetLayerDepths();
164   }
165 }
166
167 void LayerList::LowerLayerToBottom( const Layer& layer )
168 {
169   ReverseLayerIter iter =  Find( mLayers.rbegin(), mLayers.rend(), layer);
170
171   if (iter   != mLayers.rend() &&
172       iter+1 != mLayers.rend())
173   {
174     Layer* lowered = *iter;
175
176     copy(iter+1, mLayers.rend(), iter);
177     mLayers.front() = lowered;
178
179     SetLayerDepths();
180   }
181 }
182
183 void LayerList::MoveLayerAbove( const Layer& layer, const Layer& target )
184 {
185   // check if it already is
186   if( layer.GetDepth() == ( target.GetDepth() + 1 ) )
187   {
188     return;
189   }
190
191   // find the layer to move
192   LayerIter iter = Find( mLayers.begin(), mLayers.end(), layer);
193
194   if( iter != mLayers.end() )
195   {
196     Layer* moved = *iter;
197     mLayers.erase( iter );
198     // find target
199     LayerIter iterT = Find( mLayers.begin(), mLayers.end(), target);
200     // if target is not found there's a programming error somewhere
201     DALI_ASSERT_DEBUG( iterT != mLayers.end() );
202     // iterT might be the last
203     if( ( iterT+1 ) == mLayers.end() )
204     {
205       mLayers.push_back( moved );
206     }
207     else
208     {
209       mLayers.insert( iterT+1, moved );
210     }
211
212     SetLayerDepths();
213   }
214 }
215
216 void LayerList::MoveLayerBelow( const Layer& layer, const Layer& target )
217 {
218   // check if it already is in correct order
219   if( layer.GetDepth() == ( target.GetDepth() - 1 ) )
220   {
221     return;
222   }
223
224   // find the layer to move
225   LayerIter iter = Find( mLayers.begin(), mLayers.end(), layer);
226   if( iter != mLayers.end() )
227   {
228     Layer* moved = *iter;
229     mLayers.erase( iter );
230     // find target
231     LayerIter iterT = Find( mLayers.begin(), mLayers.end(), target);
232     // if target is not found there's a programming error somewhere
233     DALI_ASSERT_DEBUG( iterT != mLayers.end() );
234     mLayers.insert( iterT, moved );
235
236     SetLayerDepths();
237   }
238 }
239
240 LayerList::LayerList( Stage& stage, bool systemLevel )
241 : mStage( stage ),
242   mIsSystemLevel( systemLevel )
243 {
244 }
245
246 void LayerList::SetLayerDepths()
247 {
248   // we've got a list of on-stage layers on actor side, need to get their stage
249   // pointers so we can send them to the update manager
250   std::vector< SceneGraph::Layer* > layers;
251   layers.reserve( mLayers.size() );
252
253   // Set the layers (possibly) new depth
254   for (LayerIter iter = mLayers.begin(); iter != mLayers.end(); ++iter)
255   {
256     SceneGraph::Layer* layerPtr = const_cast< SceneGraph::Layer* >( &( (*iter)->GetSceneLayerOnStage() ) );
257     layers.push_back( layerPtr );
258   }
259
260   // Layers are being used in a separate thread; queue a message to set order
261   SetLayerDepthsMessage( mStage.GetUpdateManager(), layers, mIsSystemLevel );
262 }
263
264 } // namespace Internal
265
266 } // namespace Dali