[dali_1.0.5] 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( Vector3::ZERO ),
48   mPosition( Vector3::ZERO ),
49   mRotation( Quaternion::IDENTITY ),
50   mScale( Vector3::ONE ),
51   mVisible( true ),
52   mColor( Color::WHITE ),
53   mWorldPosition( Vector3::ZERO ),
54   mWorldRotation( Quaternion::IDENTITY ),
55   mWorldScale( Vector3::ONE ),
56   mWorldMatrix( Matrix::IDENTITY ),
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   mInheritRotation( 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::DisconnectFromSceneGraph();
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 )
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   mChildren.PushBack( childNode );
122 }
123
124 void Node::DisconnectChild( BufferIndex updateBufferIndex, Node& childNode, std::set<Node*>& connectedNodes,  std::set<Node*>& disconnectedNodes )
125 {
126   DALI_ASSERT_ALWAYS( this != &childNode );
127   DALI_ASSERT_ALWAYS( childNode.GetParent() == this );
128
129   // Find the childNode and remove it
130   Node* found( NULL );
131
132   const NodeIter endIter = mChildren.End();
133   for ( NodeIter iter = mChildren.Begin(); iter != endIter; ++iter )
134   {
135     Node* current = *iter;
136     if ( current == &childNode )
137     {
138       found = current;
139       mChildren.Erase( iter ); // order matters here
140       break; // iter is no longer valid
141     }
142   }
143   DALI_ASSERT_ALWAYS( NULL != found );
144
145   found->RecursiveDisconnectFromSceneGraph( updateBufferIndex, connectedNodes, disconnectedNodes );
146 }
147
148 int Node::GetDirtyFlags() const
149 {
150   // get initial dirty flags, they are reset ResetDefaultProperties, but setters may have made the node dirty already
151   int flags = mDirtyFlags;
152   const bool sizeFlag = mSize.IsClean();
153
154   if ( !(flags & TransformFlag) )
155   {
156     // Check whether the transform related properties have changed
157     if( !sizeFlag            ||
158         !mPosition.IsClean() ||
159         !mRotation.IsClean() ||
160         !mScale.IsClean()    ||
161         mParentOrigin.InputChanged() || // parent origin and anchor point rarely change
162         mAnchorPoint.InputChanged() )
163     {
164       flags |= TransformFlag;
165     }
166   }
167
168   // Check whether the visible property has changed
169   if ( !mVisible.IsClean() )
170   {
171     flags |= VisibleFlag;
172   }
173
174   // Check whether the color property has changed
175   if ( !mColor.IsClean() )
176   {
177     flags |= ColorFlag;
178   }
179
180   // Check whether the size property has changed
181   if ( !sizeFlag )
182   {
183     flags |= SizeFlag;
184    }
185
186   return flags;
187 }
188
189 void Node::ResetDefaultProperties( BufferIndex updateBufferIndex )
190 {
191   // clear dirty flags in parent origin & anchor point
192   mParentOrigin.Clear();
193   mAnchorPoint.Clear();
194   // Reset default properties
195   mSize.ResetToBaseValue( updateBufferIndex );
196   mPosition.ResetToBaseValue( updateBufferIndex );
197   mRotation.ResetToBaseValue( updateBufferIndex );
198   mScale.ResetToBaseValue( updateBufferIndex );
199   mVisible.ResetToBaseValue( updateBufferIndex );
200   mColor.ResetToBaseValue( updateBufferIndex );
201
202   mDirtyFlags = NothingFlag;
203 }
204
205 bool Node::IsFullyVisible( BufferIndex updateBufferIndex ) const
206 {
207   if( !IsVisible( updateBufferIndex ) )
208   {
209     return false;
210   }
211
212   Node* parent = mParent;
213
214   while( NULL != parent )
215   {
216     if( !parent->IsVisible( updateBufferIndex ) )
217     {
218       return false;
219     }
220
221     parent = parent->GetParent();
222   }
223
224   return true;
225 }
226
227 void Node::SetParent(Node& parentNode)
228 {
229   DALI_ASSERT_ALWAYS(this != &parentNode);
230   DALI_ASSERT_ALWAYS(!mIsRoot);
231   DALI_ASSERT_ALWAYS(mParent == NULL);
232
233   mParent = &parentNode;
234 }
235
236 void Node::RecursiveDisconnectFromSceneGraph( BufferIndex updateBufferIndex, std::set<Node*>& connectedNodes,  std::set<Node*>& disconnectedNodes )
237 {
238   DALI_ASSERT_ALWAYS(!mIsRoot);
239   DALI_ASSERT_ALWAYS(mParent != NULL);
240
241   const NodeIter endIter = mChildren.End();
242   for ( NodeIter iter = mChildren.Begin(); iter != endIter; ++iter )
243   {
244     (*iter)->RecursiveDisconnectFromSceneGraph( updateBufferIndex, connectedNodes, disconnectedNodes );
245   }
246
247   // Animators, Constraints etc. should be disconnected from the child's properties.
248   PropertyOwner::DisconnectFromSceneGraph();
249
250   // Remove back-pointer to parent
251   mParent = NULL;
252
253   // Remove all child pointers
254   mChildren.Clear();
255
256   // Move into disconnectedNodes
257   std::set<Node*>::size_type removed = connectedNodes.erase( this );
258   DALI_ASSERT_ALWAYS( removed );
259   disconnectedNodes.insert( this );
260 }
261
262 } // namespace SceneGraph
263
264 } // namespace Internal
265
266 } // namespace Dali