X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fcontrols%2Fcontrol%2Fcontrol-data-impl.cpp;h=368ab0a538e5926e0c2f8d01a986b5fa92a63c8c;hp=56be1ceb1829d94d769c30e975b512c5d3a7fbf6;hb=ee7b436210b09635d032b50eefecb7369be136e7;hpb=fca202af829a0657805e44461f08f284cdbf0bbb diff --git a/dali-toolkit/internal/controls/control/control-data-impl.cpp b/dali-toolkit/internal/controls/control/control-data-impl.cpp index 56be1ce..368ab0a 100755 --- a/dali-toolkit/internal/controls/control/control-data-impl.cpp +++ b/dali-toolkit/internal/controls/control/control-data-impl.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -229,22 +230,22 @@ static bool DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tra } else if( 0 == strcmp( signalName.c_str(), SIGNAL_TAPPED ) ) { - controlImpl.EnableGestureDetection( Gesture::Tap ); + controlImpl.EnableGestureDetection( GestureType::TAP ); controlImpl.GetTapGestureDetector().DetectedSignal().Connect( tracker, functor ); } else if( 0 == strcmp( signalName.c_str(), SIGNAL_PANNED ) ) { - controlImpl.EnableGestureDetection( Gesture::Pan ); + controlImpl.EnableGestureDetection( GestureType::PAN ); controlImpl.GetPanGestureDetector().DetectedSignal().Connect( tracker, functor ); } else if( 0 == strcmp( signalName.c_str(), SIGNAL_PINCHED ) ) { - controlImpl.EnableGestureDetection( Gesture::Pinch ); + controlImpl.EnableGestureDetection( GestureType::PINCH ); controlImpl.GetPinchGestureDetector().DetectedSignal().Connect( tracker, functor ); } else if( 0 == strcmp( signalName.c_str(), SIGNAL_LONG_PRESSED ) ) { - controlImpl.EnableGestureDetection( Gesture::LongPress ); + controlImpl.EnableGestureDetection( GestureType::LONG_PRESS ); controlImpl.GetLongPressGestureDetector().DetectedSignal().Connect( tracker, functor ); } } @@ -276,19 +277,19 @@ TypeAction registerAction( typeRegistration, ACTION_ACCESSIBILITY_ACTIVATED, &Do DALI_TYPE_REGISTRATION_END() /** - * @brief Iterate through given container and setOffStage any visual found + * @brief Iterate through given container and setOffScene any visual found * * @param[in] container Container of visuals * @param[in] parent Parent actor to remove visuals from */ -void SetVisualsOffStage( const RegisteredVisualContainer& container, Actor parent ) +void SetVisualsOffScene( const RegisteredVisualContainer& container, Actor parent ) { for( auto iter = container.Begin(), end = container.End() ; iter!= end; iter++) { if( (*iter)->visual ) { - DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::SetOffStage Setting visual(%d) off stage\n", (*iter)->index ); - Toolkit::GetImplementation((*iter)->visual).SetOffStage( parent ); + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::SetOffScene Setting visual(%d) off stage\n", (*iter)->index ); + Toolkit::GetImplementation((*iter)->visual).SetOffScene( parent ); } } } @@ -298,8 +299,6 @@ void SetVisualsOffStage( const RegisteredVisualContainer& container, Actor paren // Properties registered without macro to use specific member variables. const PropertyRegistration Control::Impl::PROPERTY_1( typeRegistration, "styleName", Toolkit::Control::Property::STYLE_NAME, Property::STRING, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); -const PropertyRegistration Control::Impl::PROPERTY_2( typeRegistration, "reservedProperty01", Toolkit::Control::Property::RESERVED_PROPERTY_01, Property::VECTOR4, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); -const PropertyRegistration Control::Impl::PROPERTY_3( typeRegistration, "reservedProperty02", Toolkit::Control::Property::RESERVED_PROPERTY_02, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); const PropertyRegistration Control::Impl::PROPERTY_4( typeRegistration, "keyInputFocus", Toolkit::Control::Property::KEY_INPUT_FOCUS, Property::BOOLEAN, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); const PropertyRegistration Control::Impl::PROPERTY_5( typeRegistration, "background", Toolkit::Control::Property::BACKGROUND, Property::MAP, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); const PropertyRegistration Control::Impl::PROPERTY_6( typeRegistration, "margin", Toolkit::Control::Property::MARGIN, Property::EXTENTS, &Control::Impl::SetProperty, &Control::Impl::GetProperty ); @@ -324,7 +323,7 @@ Control::Impl::Impl( Control& controlImpl ) mDownFocusableActorId( -1 ), mStyleName(""), mBackgroundColor(Color::TRANSPARENT), - mStartingPinchScale( NULL ), + mStartingPinchScale(nullptr), mMargin( 0, 0, 0, 0 ), mPadding( 0, 0, 0, 0 ), mKeyEventSignal(), @@ -338,9 +337,12 @@ Control::Impl::Impl( Control& controlImpl ) mLongPressGestureDetector(), mTooltip( NULL ), mInputMethodContext(), + mIdleCallback(nullptr), mFlags( Control::ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ), mIsKeyboardNavigationSupported( false ), - mIsKeyboardFocusGroup( false ) + mIsKeyboardFocusGroup( false ), + mIsEmittingResourceReadySignal(false), + mNeedToEmitResourceReady(false) { } @@ -348,6 +350,12 @@ Control::Impl::~Impl() { // All gesture detectors will be destroyed so no need to disconnect. delete mStartingPinchScale; + + if(mIdleCallback && Adaptor::IsAvailable()) + { + // Removes the callback from the callback manager in case the control is destroyed before the callback is executed. + Adaptor::Get().RemoveIdle(mIdleCallback); + } } Control::Impl& Control::Impl::Get( Internal::Control& internalControl ) @@ -442,7 +450,7 @@ void Control::Impl::RegisterVisual( Property::Index index, Toolkit::Visual::Base { // Visual with same index is already in removal container so current visual pending // Only the the last requested visual will be displayed so remove current visual which is staged but not ready. - Toolkit::GetImplementation( currentRegisteredVisual ).SetOffStage( self ); + Toolkit::GetImplementation( currentRegisteredVisual ).SetOffScene( self ); mVisuals.Erase( registeredVisualsiter ); } else @@ -526,7 +534,7 @@ void Control::Impl::RegisterVisual( Property::Index index, Toolkit::Visual::Base // Put on stage if enabled and the control is already on the stage if( ( enabled == VisualState::ENABLED ) && self.GetProperty< bool >( Actor::Property::CONNECTED_TO_SCENE ) ) { - visualImpl.SetOnStage( self ); + visualImpl.SetOnScene( self ); } else if( visualImpl.IsResourceReady() ) // When not being staged, check if visual already 'ResourceReady' before it was Registered. ( Resource may have been loaded already ) { @@ -547,7 +555,7 @@ void Control::Impl::UnregisterVisual( Property::Index index ) StopObservingVisual( (*iter)->visual ); Actor self( mControlImpl.Self() ); - Toolkit::GetImplementation((*iter)->visual).SetOffStage( self ); + Toolkit::GetImplementation((*iter)->visual).SetOffScene( self ); (*iter)->visual.Reset(); mVisuals.Erase( iter ); } @@ -555,7 +563,7 @@ void Control::Impl::UnregisterVisual( Property::Index index ) if( FindVisual( index, mRemoveVisuals, iter ) ) { Actor self( mControlImpl.Self() ); - Toolkit::GetImplementation( (*iter)->visual ).SetOffStage( self ); + Toolkit::GetImplementation( (*iter)->visual ).SetOffScene( self ); (*iter)->pending = false; (*iter)->visual.Reset(); mRemoveVisuals.Erase( iter ); @@ -588,17 +596,17 @@ void Control::Impl::EnableVisual( Property::Index index, bool enable ) (*iter)->enabled = enable; Actor parentActor = mControlImpl.Self(); - if ( mControlImpl.Self().GetProperty< bool >( Actor::Property::CONNECTED_TO_SCENE ) ) // If control not on Stage then Visual will be added when StageConnection is called. + if ( mControlImpl.Self().GetProperty< bool >( Actor::Property::CONNECTED_TO_SCENE ) ) // If control not on Scene then Visual will be added when SceneConnection is called. { if ( enable ) { DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::EnableVisual Setting %s(%d) on stage \n", (*iter)->visual.GetName().c_str(), index ); - Toolkit::GetImplementation((*iter)->visual).SetOnStage( parentActor ); + Toolkit::GetImplementation((*iter)->visual).SetOnScene( parentActor ); } else { DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::EnableVisual Setting %s(%d) off stage \n", (*iter)->visual.GetName().c_str(), index ); - Toolkit::GetImplementation((*iter)->visual).SetOffStage( parentActor ); // No need to call if control not staged. + Toolkit::GetImplementation((*iter)->visual).SetOffScene( parentActor ); // No need to call if control not staged. } } } @@ -656,7 +664,7 @@ void Control::Impl::ResourceReady( Visual::Base& object) if( FindVisual( (*registeredIter)->index, mRemoveVisuals, visualToRemoveIter ) ) { (*registeredIter)->pending = false; - Toolkit::GetImplementation( (*visualToRemoveIter)->visual ).SetOffStage( self ); + Toolkit::GetImplementation( (*visualToRemoveIter)->visual ).SetOffScene( self ); mRemoveVisuals.Erase( visualToRemoveIter ); } break; @@ -672,8 +680,10 @@ void Control::Impl::ResourceReady( Visual::Base& object) // Emit signal if all enabled visuals registered by the control are ready. if( IsResourceReady() ) { - Dali::Toolkit::Control handle( mControlImpl.GetOwner() ); - mResourceReadySignal.Emit( handle ); + // Reset the flag + mNeedToEmitResourceReady = false; + + EmitResourceReadySignal(); } } @@ -761,7 +771,7 @@ void Control::Impl::AddTransitions( Dali::Animation& animation, Actor child = mControlImpl.Self().FindChildByName( animator->objectName ); if( child ) { - Property::Index propertyIndex = DevelHandle::GetPropertyIndex( child, animator->propertyKey ); + Property::Index propertyIndex = child.GetPropertyIndex( animator->propertyKey ); if( propertyIndex != Property::INVALID_INDEX ) { if( animator->animate == false ) @@ -837,7 +847,7 @@ void Control::Impl::SetProperty( BaseObject* object, Property::Index index, cons { bool withTransitions=true; const Property::Value* valuePtr=&value; - Property::Map* map = value.GetMap(); + const Property::Map* map = value.GetMap(); if(map) { Property::Value* value2 = map->Find("withTransitions"); @@ -1142,7 +1152,7 @@ void Control::Impl::RemoveVisual( RegisteredVisualContainer& visuals, const std: Toolkit::Visual::Base visual = (*visualIter)->visual; if( visual && visual.GetName() == visualName ) { - Toolkit::GetImplementation(visual).SetOffStage( self ); + Toolkit::GetImplementation(visual).SetOffScene( self ); (*visualIter)->visual.Reset(); visuals.Erase( visualIter ); break; @@ -1356,22 +1366,22 @@ void Control::Impl::SetSubState( const std::string& subStateName, bool withTrans } } -void Control::Impl::OnStageDisconnection() +void Control::Impl::OnSceneDisconnection() { Actor self = mControlImpl.Self(); // Any visuals set for replacement but not yet ready should still be registered. - // Reason: If a request was made to register a new visual but the control removed from stage before visual was ready + // Reason: If a request was made to register a new visual but the control removed from scene before visual was ready // then when this control appears back on stage it should use that new visual. - // Iterate through all registered visuals and set off stage - SetVisualsOffStage( mVisuals, self ); + // Iterate through all registered visuals and set off scene + SetVisualsOffScene( mVisuals, self ); - // Visuals pending replacement can now be taken out of the removal list and set off stage - // Iterate through all replacement visuals and add to a move queue then set off stage + // Visuals pending replacement can now be taken out of the removal list and set off scene + // Iterate through all replacement visuals and add to a move queue then set off scene for( auto removalIter = mRemoveVisuals.Begin(), end = mRemoveVisuals.End(); removalIter != end; removalIter++ ) { - Toolkit::GetImplementation((*removalIter)->visual).SetOffStage( self ); + Toolkit::GetImplementation((*removalIter)->visual).SetOffScene( self ); } for( auto replacedIter = mVisuals.Begin(), end = mVisuals.End(); replacedIter != end; replacedIter++ ) @@ -1450,6 +1460,58 @@ void Control::Impl::ClearShadow() mControlImpl.RelayoutRequest(); } +void Control::Impl::EmitResourceReadySignal() +{ + if(!mIsEmittingResourceReadySignal) + { + // Guard against calls to emit the signal during the callback + mIsEmittingResourceReadySignal = true; + + // If the signal handler changes visual, it may become ready during this call & therefore this method will + // get called again recursively. If so, mNeedToEmitResourceReady is set below, and we act on it after that secondary + // invocation has completed by notifying in an Idle callback to prevent further recursion. + Dali::Toolkit::Control handle(mControlImpl.GetOwner()); + mResourceReadySignal.Emit(handle); + + if(mNeedToEmitResourceReady) + { + // Add idler to emit the signal again + if(!mIdleCallback) + { + // The callback manager takes the ownership of the callback object. + mIdleCallback = MakeCallback( this, &Control::Impl::OnIdleCallback); + Adaptor::Get().AddIdle(mIdleCallback, false); + } + } + + mIsEmittingResourceReadySignal = false; + } + else + { + mNeedToEmitResourceReady = true; + } +} + +void Control::Impl::OnIdleCallback() +{ + if(mNeedToEmitResourceReady) + { + // Reset the flag + mNeedToEmitResourceReady = false; + + // A visual is ready so control may need relayouting if staged + if(mControlImpl.Self().GetProperty(Actor::Property::CONNECTED_TO_SCENE)) + { + mControlImpl.RelayoutRequest(); + } + + EmitResourceReadySignal(); + } + + // Set the pointer to null as the callback manager deletes the callback after execute it. + mIdleCallback = nullptr; +} + } // namespace Internal } // namespace Toolkit