[dali_1.0.36] Merge branch 'tizen'
[platform/core/uifw/dali-core.git] / dali / internal / update / nodes / node.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/update/nodes/node.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/internal/update/node-attachments/node-attachment.h>
23 #include <dali/internal/update/common/discard-queue.h>
24 #include <dali/public-api/common/dali-common.h>
25 #include <dali/public-api/common/constants.h>
26
27 namespace Dali
28 {
29
30 namespace Internal
31 {
32
33 namespace SceneGraph
34 {
35
36 const PositionInheritanceMode Node::DEFAULT_POSITION_INHERITANCE_MODE( INHERIT_PARENT_POSITION );
37 const ColorMode Node::DEFAULT_COLOR_MODE( USE_OWN_MULTIPLY_PARENT_ALPHA );
38
39 Node* Node::New()
40 {
41   return new Node();
42 }
43
44 Node::Node()
45 : mParentOrigin( ParentOrigin::DEFAULT ),
46   mAnchorPoint( AnchorPoint::DEFAULT ),
47   mSize(),     // zero initialized by default
48   mPosition(), // zero initialized by default
49   mOrientation(), // initialized to identity by default
50   mScale( Vector3::ONE ),
51   mVisible( true ),
52   mColor( Color::WHITE ),
53   mWorldPosition(), // zero initialized by default
54   mWorldOrientation(), // initialized to identity by default
55   mWorldScale( Vector3::ONE ),
56   mWorldMatrix(),
57   mWorldColor( Color::WHITE ),
58   mParent( NULL ),
59   mExclusiveRenderTask( NULL ),
60   mAttachment( NULL ),
61   mChildren(),
62   mGeometryScale( Vector3::ONE ),
63   mInitialVolume( Vector3::ONE ),
64   mDirtyFlags(AllFlags),
65   mIsRoot( false ),
66   mInheritOrientation( true ),
67   mInheritScale( true ),
68   mTransmitGeometryScaling( false ),
69   mInhibitLocalTransform( false ),
70   mIsActive( true ),
71   mDrawMode( DrawMode::NORMAL ),
72   mPositionInheritanceMode( DEFAULT_POSITION_INHERITANCE_MODE ),
73   mColorMode( DEFAULT_COLOR_MODE )
74 {
75 }
76
77 Node::~Node()
78 {
79 }
80
81 void Node::OnDestroy()
82 {
83   // Node attachments should be notified about the disconnection.
84   if ( mAttachment )
85   {
86     mAttachment->OnDestroy();
87   }
88
89   // Animators, Constraints etc. should be disconnected from the child's properties.
90   PropertyOwner::Destroy();
91 }
92
93 void Node::Attach( NodeAttachment& object )
94 {
95   DALI_ASSERT_DEBUG(!mAttachment);
96
97   object.SetParent(*this);
98
99   mAttachment = &object;
100   SetAllDirtyFlags();
101 }
102
103 void Node::SetRoot(bool isRoot)
104 {
105   DALI_ASSERT_DEBUG(!isRoot || mParent == NULL); // Root nodes cannot have a parent
106
107   mIsRoot = isRoot;
108 }
109
110 void Node::ConnectChild( Node* childNode, int index )
111 {
112   DALI_ASSERT_ALWAYS( this != childNode );
113   DALI_ASSERT_ALWAYS( IsRoot() || NULL != mParent ); // Parent should be connected first
114   DALI_ASSERT_ALWAYS( !childNode->IsRoot() && NULL == childNode->GetParent() ); // Child should be disconnected
115
116   childNode->SetParent( *this );
117
118   // Everything should be reinherited when reconnected to scene-graph
119   childNode->SetAllDirtyFlags();
120
121   if (index == -1)
122   {
123     mChildren.PushBack( childNode );
124   }
125   else
126   {
127     mChildren.Insert(mChildren.Begin()+index, childNode);
128   }
129
130   childNode->ConnectToSceneGraph();
131 }
132
133 void Node::DisconnectChild( BufferIndex updateBufferIndex, Node& childNode, std::set<Node*>& connectedNodes,  std::set<Node*>& disconnectedNodes )
134 {
135   DALI_ASSERT_ALWAYS( this != &childNode );
136   DALI_ASSERT_ALWAYS( childNode.GetParent() == this );
137
138   // Find the childNode and remove it
139   Node* found( NULL );
140
141   const NodeIter endIter = mChildren.End();
142   for ( NodeIter iter = mChildren.Begin(); iter != endIter; ++iter )
143   {
144     Node* current = *iter;
145     if ( current == &childNode )
146     {
147       found = current;
148       mChildren.Erase( iter ); // order matters here
149       break; // iter is no longer valid
150     }
151   }
152   DALI_ASSERT_ALWAYS( NULL != found );
153
154   found->RecursiveDisconnectFromSceneGraph( updateBufferIndex, connectedNodes, disconnectedNodes );
155 }
156
157 int Node::GetDirtyFlags() const
158 {
159   // get initial dirty flags, they are reset ResetDefaultProperties, but setters may have made the node dirty already
160   int flags = mDirtyFlags;
161   const bool sizeFlag = mSize.IsClean();
162
163   if ( !(flags & TransformFlag) )
164   {
165     // Check whether the transform related properties have changed
166     if( !sizeFlag            ||
167         !mPosition.IsClean() ||
168         !mOrientation.IsClean() ||
169         !mScale.IsClean()    ||
170         mParentOrigin.InputChanged() || // parent origin and anchor point rarely change
171         mAnchorPoint.InputChanged() )
172     {
173       flags |= TransformFlag;
174     }
175   }
176
177   // Check whether the visible property has changed
178   if ( !mVisible.IsClean() )
179   {
180     flags |= VisibleFlag;
181   }
182
183   // Check whether the color property has changed
184   if ( !mColor.IsClean() )
185   {
186     flags |= ColorFlag;
187   }
188
189   // Check whether the size property has changed
190   if ( !sizeFlag )
191   {
192     flags |= SizeFlag;
193    }
194
195   return flags;
196 }
197
198 void Node::ResetDefaultProperties( BufferIndex updateBufferIndex )
199 {
200   // clear dirty flags in parent origin & anchor point
201   mParentOrigin.Clear();
202   mAnchorPoint.Clear();
203   // Reset default properties
204   mSize.ResetToBaseValue( updateBufferIndex );
205   mPosition.ResetToBaseValue( updateBufferIndex );
206   mOrientation.ResetToBaseValue( updateBufferIndex );
207   mScale.ResetToBaseValue( updateBufferIndex );
208   mVisible.ResetToBaseValue( updateBufferIndex );
209   mColor.ResetToBaseValue( updateBufferIndex );
210
211   mDirtyFlags = NothingFlag;
212 }
213
214 bool Node::IsFullyVisible( BufferIndex updateBufferIndex ) const
215 {
216   if( !IsVisible( updateBufferIndex ) )
217   {
218     return false;
219   }
220
221   Node* parent = mParent;
222
223   while( NULL != parent )
224   {
225     if( !parent->IsVisible( updateBufferIndex ) )
226     {
227       return false;
228     }
229
230     parent = parent->GetParent();
231   }
232
233   return true;
234 }
235
236 void Node::SetParent(Node& parentNode)
237 {
238   DALI_ASSERT_ALWAYS(this != &parentNode);
239   DALI_ASSERT_ALWAYS(!mIsRoot);
240   DALI_ASSERT_ALWAYS(mParent == NULL);
241
242   mParent = &parentNode;
243 }
244
245 void Node::RecursiveDisconnectFromSceneGraph( BufferIndex updateBufferIndex, std::set<Node*>& connectedNodes,  std::set<Node*>& disconnectedNodes )
246 {
247   DALI_ASSERT_ALWAYS(!mIsRoot);
248   DALI_ASSERT_ALWAYS(mParent != NULL);
249
250   const NodeIter endIter = mChildren.End();
251   for ( NodeIter iter = mChildren.Begin(); iter != endIter; ++iter )
252   {
253     (*iter)->RecursiveDisconnectFromSceneGraph( updateBufferIndex, connectedNodes, disconnectedNodes );
254   }
255
256   // Animators, Constraints etc. should be disconnected from the child's properties.
257   PropertyOwner::DisconnectFromSceneGraph( updateBufferIndex );
258
259   // Remove back-pointer to parent
260   mParent = NULL;
261
262   // Remove all child pointers
263   mChildren.Clear();
264
265   // Move into disconnectedNodes
266   std::set<Node*>::size_type removed = connectedNodes.erase( this );
267   DALI_ASSERT_ALWAYS( removed );
268   disconnectedNodes.insert( this );
269 }
270
271 } // namespace SceneGraph
272
273 } // namespace Internal
274
275 } // namespace Dali