// EXTERNAL INCLUDES
#include <cstring> // for strcmp
#include <dali/devel-api/adaptor-framework/physical-keyboard.h>
-#include <dali/devel-api/object/type-registry-helper.h>
+#include <dali/public-api/object/type-registry-helper.h>
#include <dali/integration-api/debug.h>
#include <dali/public-api/adaptor-framework/key.h>
#include <dali/public-api/animation/constraints.h>
#include <dali/public-api/common/stage.h>
#include <dali/public-api/events/key-event.h>
-#include <dali/public-api/events/touch-event.h>
+#include <dali/public-api/events/touch-data.h>
#include <dali/public-api/images/resource-image.h>
#include <dali/public-api/object/type-registry.h>
#include <dali/devel-api/scripting/scripting.h>
// INTERNAL INCLUDES
#include <dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.h>
#include <dali-toolkit/public-api/controls/control-impl.h>
-#include <dali-toolkit/public-api/controls/default-controls/solid-color-actor.h>
+#include <dali-toolkit/public-api/controls/image-view/image-view.h>
#include <dali-toolkit/public-api/accessibility-manager/accessibility-manager.h>
#include <dali-toolkit/internal/focus-manager/keyboard-focus-manager-impl.h>
}
Popup::Popup()
-: Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS | REQUIRES_STYLE_CHANGE_SIGNALS ) ),
- // Main variables:
+: Control( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ),
+ mTouchedOutsideSignal(),
+ mShowingSignal(),
+ mShownSignal(),
+ mHidingSignal(),
+ mHiddenSignal(),
+ mLayer(),
+ mPopupLayout(),
+ mBacking(),
+ mPreviousFocusedActor(),
+ mTailImage(),
+ mPopupContainer(),
+ mAnimation(),
mAlterAddedChild( false ),
mLayoutDirty( true ),
+ mAutoHideTimer(),
mTouchTransparent( false ),
-
- // Property variables:
+ mTitle(),
+ mContent(),
+ mFooter(),
mDisplayState( Toolkit::Popup::HIDDEN ), // Hidden until shown with SetDisplayState()
mTailVisible( false ),
mTailPosition( DEFAULT_TAIL_POSITION ),
mContextualMode( Toolkit::Popup::NON_CONTEXTUAL ),
mAnimationDuration( DEFAULT_POPUP_ANIMATION_DURATION ),
mAnimationMode( Toolkit::Popup::FADE ),
+ mEntryAnimationData(),
+ mExitAnimationData(),
mAutoHideDelay( 0 ),
mBackingEnabled( true ),
mBackingColor( DEFAULT_BACKING_COLOR ),
+ mPopupBackgroundImage(),
+ mBackgroundOuterBorder(),
+ mMargin(),
mTailUpImage( DEFAULT_TAIL_UP_IMAGE_PATH ),
mTailDownImage( DEFAULT_TAIL_DOWN_IMAGE_PATH ),
mTailLeftImage( DEFAULT_TAIL_LEFT_IMAGE_PATH ),
mPopupLayout = Toolkit::TableView::New( 3, 1 );
// Adds the default background image.
- SetPopupBackgroundImage( ImageActor::New( ResourceImage::New( DEFAULT_BACKGROUND_IMAGE_PATH ) ) );
+ SetPopupBackgroundImage( Toolkit::ImageView::New( ResourceImage::New( DEFAULT_BACKGROUND_IMAGE_PATH ) ) );
mPopupLayout.SetName( "popupLayoutTable" );
mPopupLayout.SetParentOrigin( ParentOrigin::CENTER );
mPopupLayout.SetFitHeight( 0 ); // Set row to fit.
mPopupLayout.SetFitHeight( 1 ); // Set row to fit.
- mPopupLayout.TouchedSignal().Connect( this, &Popup::OnDialogTouched );
+ mPopupLayout.TouchSignal().Connect( this, &Popup::OnDialogTouched );
mPopupContainer.Add( mPopupLayout );
// Any content after this point which is added to Self() will be re-parented to mContent.
mAlterAddedChild = true;
- // Make self keyboard focusable and a focus group.
- self.SetKeyboardFocusable( true );
SetAsKeyboardFocusGroup( true );
}
mPopupBackgroundImage.SetParentOrigin( ParentOrigin::CENTER );
// OnDialogTouched only consumes the event. It prevents the touch event to be caught by the backing.
- mPopupBackgroundImage.TouchedSignal().Connect( this, &Popup::OnDialogTouched );
+ mPopupBackgroundImage.TouchSignal().Connect( this, &Popup::OnDialogTouched );
// Set the popup border to be slightly larger than the layout contents.
mPopupBackgroundImage.SetResizePolicy( ResizePolicy::SIZE_FIXED_OFFSET_FROM_PARENT, Dimension::ALL_DIMENSIONS );
// Allow the popup to catch events.
mPopupLayout.SetSensitive( true );
- SetKeyInputFocus();
// Handle the keyboard focus when popup is shown.
Dali::Toolkit::KeyboardFocusManager keyboardFocusManager = Dali::Toolkit::KeyboardFocusManager::Get();
{
mPreviousFocusedActor = keyboardFocusManager.GetCurrentFocusActor();
- if( mContent && mContent.IsKeyboardFocusable() )
+ if( Self().IsKeyboardFocusable() )
{
- // If content is focusable, move the focus to content.
- keyboardFocusManager.SetCurrentFocusActor( mContent );
- }
- else
- {
- DALI_LOG_WARNING( "There is no focusable in popup\n" );
+ // Setup the actgor to start focus from.
+ Actor focusActor;
+ if( mContent && mContent.IsKeyboardFocusable() )
+ {
+ // If the content is focusable, move the focus to the content.
+ focusActor = mContent;
+ }
+ else if( mFooter && mFooter.IsKeyboardFocusable() )
+ {
+ // If the footer is focusable, move the focus to the footer.
+ focusActor = mFooter;
+ }
+ else
+ {
+ DALI_LOG_WARNING( "There is no focusable in popup\n" );
+ }
+
+ if( focusActor )
+ {
+ SetKeyInputFocus();
+ keyboardFocusManager.SetCurrentFocusActor( focusActor );
+ }
}
}
}
{
// Adds the tail actor.
Image tail = ResourceImage::New( image );
- mTailImage = ImageActor::New( tail );
+ mTailImage = Toolkit::ImageView::New( tail );
mTailImage.SetName( "tailImage" );
const Vector3 anchorPoint = AnchorPoint::BOTTOM_RIGHT - position;
mTailImage.SetParentOrigin( position );
backing.SetName( "popupBacking" );
// Must always be positioned top-left of stage, regardless of parent.
- backing.SetPositionInheritanceMode( DONT_INHERIT_POSITION );
+ backing.SetInheritPosition(false);
backing.SetAnchorPoint( AnchorPoint::TOP_LEFT );
// Always the full size of the stage.
// Default to being transparent.
backing.SetProperty( Actor::Property::COLOR_ALPHA, 0.0f );
- backing.TouchedSignal().Connect( this, &Popup::OnBackingTouched );
+ backing.TouchSignal().Connect( this, &Popup::OnBackingTouched );
backing.WheelEventSignal().Connect( this, &Popup::OnBackingWheelEvent );
return backing;
}
Image image = ResourceImage::New( valueString );
if( image )
{
- ImageActor actor = ImageActor::New( image );
+ Toolkit::ImageView actor = Toolkit::ImageView::New( image );
popupImpl.SetPopupBackgroundImage( actor );
}
}
return connected;
}
-bool Popup::OnBackingTouched( Actor actor, const TouchEvent& event )
+bool Popup::OnBackingTouched( Actor actor, const TouchData& touch )
{
// Allow events to pass through if touch transparency is enabled.
if( mTouchTransparent )
return false;
}
- if( event.GetPointCount() > 0 )
+ if( touch.GetPointCount() > 0 )
{
- const TouchPoint& point = event.GetPoint( 0 );
-
- if( point.state == TouchPoint::Down )
+ if( touch.GetState( 0 ) == PointState::DOWN )
{
// Guard against destruction during signal emission.
Toolkit::Popup handle( GetOwner() );
return true;
}
-bool Popup::OnDialogTouched(Actor actor, const TouchEvent& event)
+bool Popup::OnDialogTouched( Actor actor, const TouchData& touch )
{
// Allow events to pass through if touch transparency is enabled.
if( mTouchTransparent )
return true;
}
-void Popup::OnControlStageConnection()
+void Popup::OnStageConnection( int depth )
{
+ Control::OnStageConnection( depth );
+
mLayoutDirty = true;
RelayoutRequest();
}
-void Popup::OnControlChildAdd( Actor& child )
+void Popup::OnChildAdd( Actor& child )
{
+ Control::OnChildAdd( child );
+
// Re-parent any children added by user to the body layer.
if( mAlterAddedChild )
{
return consumed;
}
+void Popup::AddFocusableChildrenRecursive( Actor parent, std::vector< Actor >& focusableActors )
+{
+ if( parent )
+ {
+ Toolkit::Control control = Toolkit::Control::DownCast( parent );
+ bool layoutControl = control && GetImplementation( control ).IsKeyboardNavigationSupported();
+
+ if( parent.IsKeyboardFocusable() || layoutControl )
+ {
+ focusableActors.push_back( parent );
+
+ if( !layoutControl )
+ {
+ for( unsigned int i = 0, numberChildren = parent.GetChildCount(); i < numberChildren; ++i )
+ {
+ Actor child( parent.GetChildAt( i ) );
+ AddFocusableChildrenRecursive( child, focusableActors );
+ }
+ }
+ }
+ }
+}
+
+void Popup::AddFocusableChildren( Actor parent, std::vector< Actor >& focusableActors )
+{
+ if( parent )
+ {
+ Toolkit::Control control = Toolkit::Control::DownCast( parent );
+ if( !GetImplementation( control ).IsKeyboardNavigationSupported() )
+ {
+ for( unsigned int i = 0, numberChildren = parent.GetChildCount(); i < numberChildren; ++i )
+ {
+ Actor child( parent.GetChildAt( i ) );
+ AddFocusableChildrenRecursive( child, focusableActors );
+ }
+ }
+ else
+ {
+ focusableActors.push_back( parent );
+ }
+ }
+}
+
Actor Popup::GetNextKeyboardFocusableActor( Actor currentFocusedActor, Toolkit::Control::KeyboardFocus::Direction direction, bool loopEnabled )
{
+ std::string currentStr;
+ if( currentFocusedActor )
+ {
+ currentStr = currentFocusedActor.GetName();
+ }
+
Actor nextFocusableActor( currentFocusedActor );
+ Actor currentFocusGroup;
+ if( currentFocusedActor )
+ {
+ currentFocusGroup = KeyboardFocusManager::Get().GetFocusGroup( currentFocusedActor );
+ }
// TODO: Needs to be optimised
- if( !currentFocusedActor || ( currentFocusedActor && KeyboardFocusManager::Get().GetFocusGroup( currentFocusedActor ) != Self() ) )
+ // The following statement checks that if we have a current focused actor, then the current focus group is not the popup content or footer.
+ // This is to detect if the focus is currently outside the popup, and if so, move it inside.
+ if( !currentFocusedActor ||
+ ( currentFocusedActor && ( ( !mContent || ( currentFocusGroup != mContent ) ) && ( !mFooter || ( currentFocusGroup != mFooter ) ) ) ) )
{
- // The current focused actor is not within popup
+ // The current focused actor is not within popup.
if( mContent && mContent.IsKeyboardFocusable() )
{
- // If content is focusable, move the focus to content
+ // If the content is focusable, move the focus to the content.
nextFocusableActor = mContent;
}
+ else if( mFooter && mFooter.IsKeyboardFocusable() )
+ {
+ // If the footer is focusable, move the focus to the footer.
+ nextFocusableActor = mFooter;
+ }
}
else
{
// Rebuild the focus chain because controls or content can be added or removed dynamically
std::vector< Actor > focusableActors;
- if( mContent && mContent.IsKeyboardFocusable() )
+
+ AddFocusableChildren( mContent, focusableActors );
+ AddFocusableChildren( mFooter, focusableActors );
+
+ std::vector< Actor >::iterator endIterator = focusableActors.end();
+ std::vector< Actor >::iterator currentIterator = focusableActors.begin();
+ for( std::vector< Actor >::iterator iterator = focusableActors.begin(); iterator != endIterator; ++iterator )
{
- focusableActors.push_back( mContent );
+ if( currentFocusedActor == *iterator )
+ {
+ currentIterator = iterator;
+ }
}
- for( std::vector< Actor >::iterator iter = focusableActors.begin(), end = focusableActors.end(); iter != end; ++iter )
+ if( currentIterator != endIterator )
{
- if( currentFocusedActor == *iter )
+ switch( direction )
{
- switch( direction )
+ case Toolkit::Control::KeyboardFocus::LEFT:
{
- case Toolkit::Control::KeyboardFocus::LEFT:
+ if( currentIterator == focusableActors.begin() )
{
- if( iter == focusableActors.begin() )
- {
- nextFocusableActor = *( focusableActors.end() - 1 );
- }
- else
- {
- nextFocusableActor = *( iter - 1 );
- }
- break;
+ nextFocusableActor = *( endIterator - 1 );
}
- case Toolkit::Control::KeyboardFocus::RIGHT:
+ else
{
- if( iter == focusableActors.end() - 1 )
- {
- nextFocusableActor = *( focusableActors.begin() );
- }
- else
- {
- nextFocusableActor = *( iter + 1 );
- }
- break;
+ nextFocusableActor = *( currentIterator - 1 );
}
-
- case Toolkit::Control::KeyboardFocus::UP:
+ break;
+ }
+ case Toolkit::Control::KeyboardFocus::RIGHT:
+ {
+ if( currentIterator == endIterator - 1 )
{
- if( mContent && *iter == mContent )
- {
- nextFocusableActor = *( focusableActors.end() - 1 );
- }
- else
- {
- if( mContent && mContent.IsKeyboardFocusable() )
- {
- nextFocusableActor = mContent;
- }
- else
- {
- if ( iter == focusableActors.begin() )
- {
- nextFocusableActor = *( focusableActors.end() - 1 );
- }
- else
- {
- nextFocusableActor = *( iter - 1 );
- }
- }
- }
- break;
+ nextFocusableActor = *( focusableActors.begin() );
}
-
- case Toolkit::Control::KeyboardFocus::DOWN:
+ else
{
- if( mContent && mContent.IsKeyboardFocusable() )
- {
- nextFocusableActor = mContent;
- }
- else
- {
- if( iter == focusableActors.end() - 1 )
- {
- nextFocusableActor = *( focusableActors.begin() );
- }
- else
- {
- nextFocusableActor = *( iter + 1 );
- }
- }
- break;
+ nextFocusableActor = *( currentIterator + 1 );
}
+ break;
}
- if( !nextFocusableActor )
+ case Toolkit::Control::KeyboardFocus::UP:
{
- DALI_LOG_WARNING( "Can not decide next focusable actor\n" );
+ nextFocusableActor = *( focusableActors.begin() );
+ break;
}
- break;
+ case Toolkit::Control::KeyboardFocus::DOWN:
+ {
+ nextFocusableActor = *( endIterator - 1 );
+ break;
+ }
+ }
+
+ if( !nextFocusableActor )
+ {
+ DALI_LOG_WARNING( "Can not decide next focusable actor\n" );
}
}
}
return nextFocusableActor;
}
+
} // namespace Internal
} // namespace Toolkit