2 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali-toolkit/public-api/controls/control-impl.h>
22 #include <cstring> // for strcmp
26 #include <dali/public-api/animation/constraint.h>
27 #include <dali/public-api/object/type-registry-helper.h>
28 #include <dali/public-api/size-negotiation/relayout-container.h>
29 #include <dali/devel-api/object/handle-devel.h>
30 #include <dali/devel-api/scripting/scripting.h>
31 #include <dali/integration-api/debug.h>
34 #include <dali-toolkit/public-api/focus-manager/keyboard-focus-manager.h>
35 #include <dali-toolkit/public-api/controls/control.h>
36 #include <dali-toolkit/public-api/styling/style-manager.h>
37 #include <dali-toolkit/public-api/visuals/color-visual-properties.h>
38 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
39 #include <dali-toolkit/devel-api/controls/control-devel.h>
40 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
41 #include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
42 #include <dali-toolkit/internal/styling/style-manager-impl.h>
43 #include <dali-toolkit/internal/visuals/color/color-visual.h>
44 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
45 #include <dali-toolkit/devel-api/align-enums.h>
46 #include <dali-toolkit/internal/controls/control/control-data-impl.h>
60 #if defined(DEBUG_ENABLED)
61 Debug::Filter* gLogFilter = Debug::Filter::New( Debug::NoLogging, false, "LOG_CONTROL_VISUALS");
64 DALI_ENUM_TO_STRING_TABLE_BEGIN( CLIPPING_MODE )
65 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, DISABLED )
66 DALI_ENUM_TO_STRING_WITH_SCOPE( ClippingMode, CLIP_CHILDREN )
67 DALI_ENUM_TO_STRING_TABLE_END( CLIPPING_MODE )
70 * Finds visual in given array, returning true if found along with the iterator for that visual as a out parameter
72 bool FindVisual( Property::Index targetIndex, RegisteredVisualContainer& visuals, RegisteredVisualContainer::Iterator& iter )
74 for ( iter = visuals.Begin(); iter != visuals.End(); iter++ )
76 if ( (*iter)->index == targetIndex )
84 Toolkit::Visual::Base GetVisualByName(
85 RegisteredVisualContainer& visuals,
86 const std::string& visualName )
88 Toolkit::Visual::Base visualHandle;
90 RegisteredVisualContainer::Iterator iter;
91 for ( iter = visuals.Begin(); iter != visuals.End(); iter++ )
93 Toolkit::Visual::Base visual = (*iter)->visual;
94 if( visual && visual.GetName() == visualName )
96 visualHandle = visual;
103 } // unnamed namespace
107 Toolkit::Control Control::New()
109 // Create the implementation, temporarily owned on stack
110 IntrusivePtr<Control> controlImpl = new Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) );
112 // Pass ownership to handle
113 Toolkit::Control handle( *controlImpl );
115 // Second-phase init of the implementation
116 // This can only be done after the CustomActor connection has been made...
117 controlImpl->Initialize();
122 void Control::SetStyleName( const std::string& styleName )
124 if( styleName != mImpl->mStyleName )
126 mImpl->mStyleName = styleName;
128 // Apply new style, if stylemanager is available
129 Toolkit::StyleManager styleManager = Toolkit::StyleManager::Get();
132 GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
137 const std::string& Control::GetStyleName() const
139 return mImpl->mStyleName;
142 void Control::SetBackgroundColor( const Vector4& color )
144 mImpl->mBackgroundColor = color;
146 map[ Toolkit::DevelVisual::Property::TYPE ] = Toolkit::Visual::COLOR;
147 map[ Toolkit::ColorVisual::Property::MIX_COLOR ] = color;
149 SetBackground( map );
152 Vector4 Control::GetBackgroundColor() const
154 return mImpl->mBackgroundColor;
157 void Control::SetBackground( const Property::Map& map )
159 Toolkit::Visual::Base visual = Toolkit::VisualFactory::Get().CreateVisual( map );
162 RegisterVisual( Toolkit::Control::Property::BACKGROUND, visual );
163 visual.SetDepthIndex( DepthIndex::BACKGROUND );
165 // Trigger a size negotiation request that may be needed by the new visual to relayout its contents.
170 void Control::SetBackgroundImage( Image image )
172 Toolkit::Visual::Base visual = Toolkit::VisualFactory::Get().CreateVisual( image );
175 RegisterVisual( Toolkit::Control::Property::BACKGROUND, visual );
176 visual.SetDepthIndex( DepthIndex::BACKGROUND );
180 void Control::ClearBackground()
182 UnregisterVisual( Toolkit::Control::Property::BACKGROUND );
183 mImpl->mBackgroundColor = Color::TRANSPARENT;
185 // Trigger a size negotiation request that may be needed when unregistering a visual.
189 void Control::EnableGestureDetection(Gesture::Type type)
191 if ( (type & Gesture::Pinch) && !mImpl->mPinchGestureDetector )
193 mImpl->mPinchGestureDetector = PinchGestureDetector::New();
194 mImpl->mPinchGestureDetector.DetectedSignal().Connect(mImpl, &Impl::PinchDetected);
195 mImpl->mPinchGestureDetector.Attach(Self());
198 if ( (type & Gesture::Pan) && !mImpl->mPanGestureDetector )
200 mImpl->mPanGestureDetector = PanGestureDetector::New();
201 mImpl->mPanGestureDetector.DetectedSignal().Connect(mImpl, &Impl::PanDetected);
202 mImpl->mPanGestureDetector.Attach(Self());
205 if ( (type & Gesture::Tap) && !mImpl->mTapGestureDetector )
207 mImpl->mTapGestureDetector = TapGestureDetector::New();
208 mImpl->mTapGestureDetector.DetectedSignal().Connect(mImpl, &Impl::TapDetected);
209 mImpl->mTapGestureDetector.Attach(Self());
212 if ( (type & Gesture::LongPress) && !mImpl->mLongPressGestureDetector )
214 mImpl->mLongPressGestureDetector = LongPressGestureDetector::New();
215 mImpl->mLongPressGestureDetector.DetectedSignal().Connect(mImpl, &Impl::LongPressDetected);
216 mImpl->mLongPressGestureDetector.Attach(Self());
220 void Control::DisableGestureDetection(Gesture::Type type)
222 if ( (type & Gesture::Pinch) && mImpl->mPinchGestureDetector )
224 mImpl->mPinchGestureDetector.Detach(Self());
225 mImpl->mPinchGestureDetector.Reset();
228 if ( (type & Gesture::Pan) && mImpl->mPanGestureDetector )
230 mImpl->mPanGestureDetector.Detach(Self());
231 mImpl->mPanGestureDetector.Reset();
234 if ( (type & Gesture::Tap) && mImpl->mTapGestureDetector )
236 mImpl->mTapGestureDetector.Detach(Self());
237 mImpl->mTapGestureDetector.Reset();
240 if ( (type & Gesture::LongPress) && mImpl->mLongPressGestureDetector)
242 mImpl->mLongPressGestureDetector.Detach(Self());
243 mImpl->mLongPressGestureDetector.Reset();
247 PinchGestureDetector Control::GetPinchGestureDetector() const
249 return mImpl->mPinchGestureDetector;
252 PanGestureDetector Control::GetPanGestureDetector() const
254 return mImpl->mPanGestureDetector;
257 TapGestureDetector Control::GetTapGestureDetector() const
259 return mImpl->mTapGestureDetector;
262 LongPressGestureDetector Control::GetLongPressGestureDetector() const
264 return mImpl->mLongPressGestureDetector;
267 void Control::SetKeyboardNavigationSupport(bool isSupported)
269 mImpl->mIsKeyboardNavigationSupported = isSupported;
272 bool Control::IsKeyboardNavigationSupported()
274 return mImpl->mIsKeyboardNavigationSupported;
277 void Control::SetKeyInputFocus()
279 if( Self().OnStage() )
281 Toolkit::KeyInputFocusManager::Get().SetFocus(Toolkit::Control::DownCast(Self()));
285 bool Control::HasKeyInputFocus()
288 if( Self().OnStage() )
290 Toolkit::Control control = Toolkit::KeyInputFocusManager::Get().GetCurrentFocusControl();
291 if( Self() == control )
299 void Control::ClearKeyInputFocus()
301 if( Self().OnStage() )
303 Toolkit::KeyInputFocusManager::Get().RemoveFocus(Toolkit::Control::DownCast(Self()));
307 void Control::SetAsKeyboardFocusGroup(bool isFocusGroup)
309 mImpl->mIsKeyboardFocusGroup = isFocusGroup;
311 // The following line will be removed when the deprecated API in KeyboardFocusManager is deleted
312 Toolkit::KeyboardFocusManager::Get().SetAsFocusGroup(Self(), isFocusGroup);
315 bool Control::IsKeyboardFocusGroup()
317 return Toolkit::KeyboardFocusManager::Get().IsFocusGroup(Self());
320 void Control::AccessibilityActivate()
322 // Inform deriving classes
323 OnAccessibilityActivated();
326 void Control::KeyboardEnter()
328 // Inform deriving classes
332 void Control::RegisterVisual( Property::Index index, Toolkit::Visual::Base& visual )
334 RegisterVisual( index, visual, true );
337 void Control::RegisterVisual( Property::Index index, Toolkit::Visual::Base& visual, bool enabled )
339 bool visualReplaced ( false );
342 if( !mImpl->mVisuals.Empty() )
344 RegisteredVisualContainer::Iterator iter;
345 // Check if visual (index) is already registered. Replace if so.
346 if ( FindVisual( index, mImpl->mVisuals, iter ) )
348 if( (*iter)->visual && self.OnStage() )
350 Toolkit::GetImplementation((*iter)->visual).SetOffStage( self );
353 mImpl->StopObservingVisual( (*iter)->visual );
354 mImpl->StartObservingVisual( visual );
356 (*iter)->visual = visual;
357 visualReplaced = true;
361 // If not set, set the name of the visual to the same name as the control's property.
362 // ( If the control has been type registered )
363 if( visual.GetName().empty() )
365 // Check if the control has been type registered:
366 TypeInfo typeInfo = TypeRegistry::Get().GetTypeInfo( typeid(*this) );
369 // Check if the property index has been registered:
370 Property::IndexContainer indices;
371 typeInfo.GetPropertyIndices( indices );
372 Property::IndexContainer::Iterator iter = std::find( indices.Begin(), indices.End(), index );
373 if( iter != indices.End() )
375 // If it has, then get it's name and use that for the visual
376 std::string visualName = typeInfo.GetPropertyName( index );
377 visual.SetName( visualName );
382 if( !visualReplaced ) // New registration entry
384 mImpl->mVisuals.PushBack( new RegisteredVisual( index, visual, enabled ) );
386 // monitor when the visuals resources are ready
387 mImpl->StartObservingVisual( visual );
391 if( visual && self.OnStage() && enabled )
393 Toolkit::GetImplementation(visual).SetOnStage( self );
396 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::RegisterVisual() Registered %s(%d), enabled:%s\n", visual.GetName().c_str(), index, enabled?"T":"F" );
399 void Control::UnregisterVisual( Property::Index index )
401 RegisteredVisualContainer::Iterator iter;
402 if ( FindVisual( index, mImpl->mVisuals, iter ) )
404 // stop observing visual
405 mImpl->StopObservingVisual( (*iter)->visual );
407 Actor self( Self() );
408 Toolkit::GetImplementation((*iter)->visual).SetOffStage( self );
409 (*iter)->visual.Reset();
410 mImpl->mVisuals.Erase( iter );
414 Toolkit::Visual::Base Control::GetVisual( Property::Index index ) const
416 RegisteredVisualContainer::Iterator iter;
417 if ( FindVisual( index, mImpl->mVisuals, iter ) )
419 return (*iter)->visual;
422 return Toolkit::Visual::Base();
425 void Control::EnableVisual( Property::Index index, bool enable )
427 RegisteredVisualContainer::Iterator iter;
428 if ( FindVisual( index, mImpl->mVisuals, iter ) )
430 if ( (*iter)->enabled == enable )
432 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::EnableVisual Visual %s(%d) already %s\n", (*iter)->visual.GetName().c_str(), index, enable?"enabled":"disabled");
436 (*iter)->enabled = enable;
437 Actor parentActor = Self();
438 if ( Self().OnStage() ) // If control not on Stage then Visual will be added when StageConnection is called.
442 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::EnableVisual Setting %s(%d) on stage \n", (*iter)->visual.GetName().c_str(), index );
443 Toolkit::GetImplementation((*iter)->visual).SetOnStage( parentActor );
447 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::EnableVisual Setting %s(%d) off stage \n", (*iter)->visual.GetName().c_str(), index );
448 Toolkit::GetImplementation((*iter)->visual).SetOffStage( parentActor ); // No need to call if control not staged.
454 bool Control::IsVisualEnabled( Property::Index index ) const
456 RegisteredVisualContainer::Iterator iter;
457 if ( FindVisual( index, mImpl->mVisuals, iter ) )
459 return (*iter)->enabled;
464 Dali::Animation Control::CreateTransition( const Toolkit::TransitionData& handle )
466 Dali::Animation transition;
467 const Internal::TransitionData& transitionData = Toolkit::GetImplementation( handle );
469 if( transitionData.Count() > 0 )
471 // Setup a Transition from TransitionData.
472 TransitionData::Iterator end = transitionData.End();
473 for( TransitionData::Iterator iter = transitionData.Begin() ;
474 iter != end; ++iter )
476 TransitionData::Animator* animator = (*iter);
478 Toolkit::Visual::Base visual = GetVisualByName( mImpl->mVisuals, animator->objectName );
482 Internal::Visual::Base& visualImpl = Toolkit::GetImplementation( visual );
483 visualImpl.AnimateProperty( transition, *animator );
487 // Otherwise, try any actor children of control (Including the control)
488 Actor child = Self().FindChildByName( animator->objectName );
491 Property::Index propertyIndex = DevelHandle::GetPropertyIndex( child, animator->propertyKey );
492 if( propertyIndex != Property::INVALID_INDEX )
494 if( animator->animate == false )
496 if( animator->targetValue.GetType() != Property::NONE )
498 child.SetProperty( propertyIndex, animator->targetValue );
501 else // animate the property
503 if( animator->initialValue.GetType() != Property::NONE )
505 child.SetProperty( propertyIndex, animator->initialValue );
510 transition = Dali::Animation::New( 0.1f );
513 transition.AnimateTo( Property( child, propertyIndex ),
514 animator->targetValue,
515 animator->alphaFunction,
516 TimePeriod( animator->timePeriodDelay,
517 animator->timePeriodDuration ) );
528 bool Control::OnAccessibilityActivated()
530 return false; // Accessibility activation is not handled by default
533 bool Control::OnKeyboardEnter()
535 return false; // Keyboard enter is not handled by default
538 bool Control::OnAccessibilityPan(PanGesture gesture)
540 return false; // Accessibility pan gesture is not handled by default
543 bool Control::OnAccessibilityTouch(const TouchEvent& touchEvent)
545 return false; // Accessibility touch event is not handled by default
548 bool Control::OnAccessibilityValueChange(bool isIncrease)
550 return false; // Accessibility value change action is not handled by default
553 bool Control::OnAccessibilityZoom()
555 return false; // Accessibility zoom action is not handled by default
558 Actor Control::GetNextKeyboardFocusableActor(Actor currentFocusedActor, Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled)
563 void Control::OnKeyboardFocusChangeCommitted(Actor commitedFocusableActor)
567 Toolkit::Control::KeyEventSignalType& Control::KeyEventSignal()
569 return mImpl->mKeyEventSignal;
572 Toolkit::Control::KeyInputFocusSignalType& Control::KeyInputFocusGainedSignal()
574 return mImpl->mKeyInputFocusGainedSignal;
577 Toolkit::Control::KeyInputFocusSignalType& Control::KeyInputFocusLostSignal()
579 return mImpl->mKeyInputFocusLostSignal;
582 bool Control::EmitKeyEventSignal( const KeyEvent& event )
584 // Guard against destruction during signal emission
585 Dali::Toolkit::Control handle( GetOwner() );
587 bool consumed = false;
589 // signals are allocated dynamically when someone connects
590 if ( !mImpl->mKeyEventSignal.Empty() )
592 consumed = mImpl->mKeyEventSignal.Emit( handle, event );
597 // Notification for derived classes
598 consumed = OnKeyEvent(event);
604 Control::Control( ControlBehaviour behaviourFlags )
605 : CustomActorImpl( static_cast< ActorFlags >( behaviourFlags ) ),
606 mImpl(new Impl(*this))
608 mImpl->mFlags = behaviourFlags;
616 void Control::Initialize()
618 // Call deriving classes so initialised before styling is applied to them.
621 if( (mImpl->mFlags & REQUIRES_STYLE_CHANGE_SIGNALS) ||
622 !(mImpl->mFlags & DISABLE_STYLE_CHANGE_SIGNALS) )
624 Toolkit::StyleManager styleManager = StyleManager::Get();
626 // if stylemanager is available
629 StyleManager& styleManagerImpl = GetImpl( styleManager );
631 // Register for style changes
632 styleManagerImpl.ControlStyleChangeSignal().Connect( this, &Control::OnStyleChange );
634 // Apply the current style
635 styleManagerImpl.ApplyThemeStyleAtInit( Toolkit::Control( GetOwner() ) );
639 if( mImpl->mFlags & REQUIRES_KEYBOARD_NAVIGATION_SUPPORT )
641 SetKeyboardNavigationSupport( true );
645 void Control::OnInitialize()
649 void Control::OnControlChildAdd( Actor& child )
653 void Control::OnControlChildRemove( Actor& child )
657 void Control::OnStyleChange( Toolkit::StyleManager styleManager, StyleChange::Type change )
659 // By default the control is only interested in theme (not font) changes
660 if( styleManager && change == StyleChange::THEME_CHANGE )
662 GetImpl( styleManager ).ApplyThemeStyle( Toolkit::Control( GetOwner() ) );
667 void Control::OnPinch(const PinchGesture& pinch)
669 if( !( mImpl->mStartingPinchScale ) )
672 mImpl->mStartingPinchScale = new Vector3;
675 if( pinch.state == Gesture::Started )
677 *( mImpl->mStartingPinchScale ) = Self().GetCurrentScale();
680 Self().SetScale( *( mImpl->mStartingPinchScale ) * pinch.scale );
683 void Control::OnPan( const PanGesture& pan )
687 void Control::OnTap(const TapGesture& tap)
691 void Control::OnLongPress( const LongPressGesture& longPress )
695 void Control::EmitKeyInputFocusSignal( bool focusGained )
697 Dali::Toolkit::Control handle( GetOwner() );
701 // signals are allocated dynamically when someone connects
702 if ( !mImpl->mKeyInputFocusGainedSignal.Empty() )
704 mImpl->mKeyInputFocusGainedSignal.Emit( handle );
709 // signals are allocated dynamically when someone connects
710 if ( !mImpl->mKeyInputFocusLostSignal.Empty() )
712 mImpl->mKeyInputFocusLostSignal.Emit( handle );
717 void Control::OnStageConnection( int depth )
719 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::OnStageConnection number of registered visuals(%d)\n", mImpl->mVisuals.Size() );
721 Actor self( Self() );
723 for(RegisteredVisualContainer::Iterator iter = mImpl->mVisuals.Begin(); iter!= mImpl->mVisuals.End(); iter++)
725 // Check whether the visual is empty and enabled
726 if( (*iter)->visual && (*iter)->enabled )
728 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::OnStageConnection Setting visual(%d) on stage\n", (*iter)->index );
729 Toolkit::GetImplementation((*iter)->visual).SetOnStage( self );
733 if( mImpl->mVisuals.Empty() && ! self.GetRendererCount() )
735 Property::Value clippingValue = self.GetProperty( Actor::Property::CLIPPING_MODE );
736 int clippingMode = ClippingMode::DISABLED;
737 if( clippingValue.Get( clippingMode ) )
739 // Add a transparent background if we do not have any renderers or visuals so we clip our children
741 if( clippingMode == ClippingMode::CLIP_CHILDREN )
743 // Create a transparent background visual which will also get staged.
744 SetBackgroundColor( Color::TRANSPARENT );
750 void Control::OnStageDisconnection()
752 for(RegisteredVisualContainer::Iterator iter = mImpl->mVisuals.Begin(); iter!= mImpl->mVisuals.End(); iter++)
754 // Check whether the visual is empty
755 if( (*iter)->visual )
757 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Control::OnStageDisconnection Setting visual(%d) off stage\n", (*iter)->index );
758 Actor self( Self() );
759 Toolkit::GetImplementation((*iter)->visual).SetOffStage( self );
764 void Control::OnKeyInputFocusGained()
766 EmitKeyInputFocusSignal( true );
769 void Control::OnKeyInputFocusLost()
771 EmitKeyInputFocusSignal( false );
774 void Control::OnChildAdd(Actor& child)
776 // Notify derived classes.
777 OnControlChildAdd( child );
780 void Control::OnChildRemove(Actor& child)
782 // Notify derived classes.
783 OnControlChildRemove( child );
786 void Control::OnPropertySet( Property::Index index, Property::Value propertyValue )
788 Actor self( Self() );
789 if( index == Actor::Property::CLIPPING_MODE )
791 // Only set the background if we're already on the stage and have no renderers or visuals
793 if( mImpl->mVisuals.Empty() && ! self.GetRendererCount() && self.OnStage() )
795 ClippingMode::Type clippingMode = ClippingMode::DISABLED;
796 if( Scripting::GetEnumerationProperty< ClippingMode::Type >( propertyValue, CLIPPING_MODE_TABLE, CLIPPING_MODE_TABLE_COUNT, clippingMode ) )
798 // Add a transparent background if we do not have one so we clip children
800 if( clippingMode == ClippingMode::CLIP_CHILDREN )
802 SetBackgroundColor( Color::TRANSPARENT );
809 void Control::OnSizeSet(const Vector3& targetSize)
811 Toolkit::Visual::Base visual = GetVisual( Toolkit::Control::Property::BACKGROUND );
814 Vector2 size( targetSize );
815 visual.SetTransformAndSize( Property::Map(), size ); // Send an empty map as we do not want to modify the visual's set transform
819 void Control::OnSizeAnimation(Animation& animation, const Vector3& targetSize)
821 // @todo size negotiate background to new size, animate as well?
824 bool Control::OnTouchEvent(const TouchEvent& event)
826 return false; // Do not consume
829 bool Control::OnHoverEvent(const HoverEvent& event)
831 return false; // Do not consume
834 bool Control::OnKeyEvent(const KeyEvent& event)
836 return false; // Do not consume
839 bool Control::OnWheelEvent(const WheelEvent& event)
841 return false; // Do not consume
844 void Control::OnRelayout( const Vector2& size, RelayoutContainer& container )
846 for( unsigned int i = 0, numChildren = Self().GetChildCount(); i < numChildren; ++i )
848 container.Add( Self().GetChildAt( i ), size );
851 Toolkit::Visual::Base visual = GetVisual( Toolkit::Control::Property::BACKGROUND );
854 visual.SetTransformAndSize( Property::Map(), size ); // Send an empty map as we do not want to modify the visual's set transform
858 void Control::OnSetResizePolicy( ResizePolicy::Type policy, Dimension::Type dimension )
862 Vector3 Control::GetNaturalSize()
864 Toolkit::Visual::Base visual = GetVisual( Toolkit::Control::Property::BACKGROUND );
868 visual.GetNaturalSize( naturalSize );
869 return Vector3( naturalSize );
871 return Vector3::ZERO;
874 float Control::CalculateChildSize( const Dali::Actor& child, Dimension::Type dimension )
876 return CalculateChildSizeBase( child, dimension );
879 float Control::GetHeightForWidth( float width )
881 return GetHeightForWidthBase( width );
884 float Control::GetWidthForHeight( float height )
886 return GetWidthForHeightBase( height );
889 bool Control::RelayoutDependentOnChildren( Dimension::Type dimension )
891 return RelayoutDependentOnChildrenBase( dimension );
894 void Control::OnCalculateRelayoutSize( Dimension::Type dimension )
898 void Control::OnLayoutNegotiated( float size, Dimension::Type dimension )
902 void Control::SignalConnected( SlotObserver* slotObserver, CallbackBase* callback )
904 mImpl->SignalConnected( slotObserver, callback );
907 void Control::SignalDisconnected( SlotObserver* slotObserver, CallbackBase* callback )
909 mImpl->SignalDisconnected( slotObserver, callback );
912 Control& GetImplementation( Dali::Toolkit::Control& handle )
914 CustomActorImpl& customInterface = handle.GetImplementation();
915 // downcast to control
916 Control& impl = dynamic_cast< Internal::Control& >( customInterface );
920 const Control& GetImplementation( const Dali::Toolkit::Control& handle )
922 const CustomActorImpl& customInterface = handle.GetImplementation();
923 // downcast to control
924 const Control& impl = dynamic_cast< const Internal::Control& >( customInterface );
928 } // namespace Internal
930 } // namespace Toolkit