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