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