/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
// CLASS HEADER
#include <dali-toolkit/internal/controls/text-controls/text-selection-toolbar-impl.h>
-// INTERNAL INCLUDES
-#include <dali-toolkit/public-api/controls/control-depth-index-ranges.h>
-#include <dali-toolkit/public-api/controls/default-controls/solid-color-actor.h>
-
// EXTERNAL INCLUDES
-#include <dali/public-api/images/resource-image.h>
+#include <cfloat>
#include <dali/public-api/math/vector2.h>
#include <dali/public-api/math/vector4.h>
-#include <dali/devel-api/object/type-registry-helper.h>
-#include <cfloat>
+#include <dali/public-api/object/property-map.h>
+#include <dali/public-api/object/type-registry-helper.h>
+
+// INTERNAL INCLUDES
+#include <dali-toolkit/public-api/controls/image-view/image-view.h>
+#include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
+#include <dali-toolkit/internal/helpers/color-conversion.h>
+#include <dali-toolkit/internal/controls/control/control-data-impl.h>
namespace Dali
{
namespace
{
-const Dali::Vector2 DEFAULT_MAX_SIZE( 400.0f, 65.0f ); ///< The maximum size of the Toolbar.
+
+const Dali::Vector2 DEFAULT_SCROLL_BAR_PADDING( 8.0f, 6.0f );
BaseHandle Create()
{
DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextSelectionToolbar, Toolkit::Control, Create );
-DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionToolbar, "max-size", VECTOR2, MAX_SIZE )
-DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionToolbar, "enable-overshoot", BOOLEAN, ENABLE_OVERSHOOT )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionToolbar, "maxSize", VECTOR2, MAX_SIZE )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionToolbar, "enableOvershoot", BOOLEAN, ENABLE_OVERSHOOT )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionToolbar, "enableScrollBar", BOOLEAN, ENABLE_SCROLL_BAR )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionToolbar, "scrollBarPadding", VECTOR2, SCROLL_BAR_PADDING )
+DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionToolbar, "scrollView", MAP, SCROLL_VIEW )
DALI_TYPE_REGISTRATION_END()
}
case Toolkit::TextSelectionToolbar::Property::ENABLE_OVERSHOOT:
{
+ if( !impl.mScrollView )
+ {
+ impl.mScrollView = Toolkit::ScrollView::New();
+ }
impl.mScrollView.SetOvershootEnabled( value.Get< bool >() );
break;
}
+ case Toolkit::TextSelectionToolbar::Property::ENABLE_SCROLL_BAR:
+ {
+ impl.SetUpScrollBar( value.Get< bool >() );
+ break;
+ }
+ case Toolkit::TextSelectionToolbar::Property::SCROLL_BAR_PADDING:
+ {
+ impl.SetScrollBarPadding( value.Get< Vector2 >() );
+ break;
+ }
+ case Toolkit::TextSelectionToolbar::Property::SCROLL_VIEW:
+ {
+ // Get a Property::Map from the property if possible.
+ Property::Map setPropertyMap;
+ if( value.Get( setPropertyMap ) )
+ {
+ impl.ConfigureScrollview( setPropertyMap );
+ }
+ break;
+ }
} // switch
} // TextSelectionToolbar
}
value = impl.mScrollView.IsOvershootEnabled();
break;
}
+ case Toolkit::TextSelectionToolbar::Property::ENABLE_SCROLL_BAR:
+ {
+ value = impl.mScrollBar ? true : false;
+ break;
+ }
+ case Toolkit::TextSelectionToolbar::Property::SCROLL_BAR_PADDING:
+ {
+ value = impl.GetScrollBarPadding();
+ break;
+ }
} // switch
}
return value;
void TextSelectionToolbar::OnInitialize()
{
SetUp();
+
+ DevelControl::SetAccessibilityConstructor( Self(), []( Dali::Actor actor ) {
+ return std::unique_ptr< Dali::Accessibility::Accessible >(
+ new Control::Impl::AccessibleImpl( actor, Dali::Accessibility::Role::TOOL_BAR ));
+ } );
}
void TextSelectionToolbar::OnRelayout( const Vector2& size, RelayoutContainer& container )
float width = std::max ( mTableOfButtons.GetNaturalSize().width, size.width );
mRulerX->SetDomain( RulerDomain( 0.0, width, true ) );
mScrollView.SetRulerX( mRulerX );
-}
-
-void TextSelectionToolbar::OnStageConnection( int depth )
-{
- // Call the Control::OnStageConnection() to set the depth of the background.
- Control::OnStageConnection( depth );
- // Traverse the dividers and set the depth.
- for( unsigned int i = 0; i < mDividerIndexes.Count(); ++i )
+ if( mScrollBar )
{
- Actor divider = mTableOfButtons.GetChildAt( Toolkit::TableView::CellPosition( 0, mDividerIndexes[ i ] ) );
-
- ImageActor dividerImageActor = ImageActor::DownCast( divider );
- if( dividerImageActor )
- {
- dividerImageActor.SetSortModifier( DECORATION_DEPTH_INDEX + depth );
- }
- else
- {
- // TODO at the moment divider are image actors.
- }
+ float barWidth = std::min( mTableOfButtons.GetNaturalSize().width, size.width ) - 2.f * mScrollBarPadding.x;
+ mScrollBar.SetProperty( Actor::Property::SIZE, Vector2( 0.0f, barWidth ) );
}
-
- // Texts are controls, they have their own OnStageConnection() implementation.
- // Icons are inside a TableView. It has it's own OnStageConnection() implementation.
}
void TextSelectionToolbar::SetPopupMaxSize( const Size& maxSize )
{
mMaxSize = maxSize;
- if (mScrollView && mStencilLayer )
+ if( mScrollView && mToolbarActor )
{
- mScrollView.SetMaximumSize( mMaxSize );
- mStencilLayer.SetMaximumSize( mMaxSize );
+ mScrollView.SetProperty( Actor::Property::MAXIMUM_SIZE, mMaxSize );
+ mToolbarActor.SetProperty( Actor::Property::MAXIMUM_SIZE, mMaxSize );
}
}
void TextSelectionToolbar::SetUpScrollView()
{
+ mScrollView.SetProperty( Dali::Actor::Property::NAME,"TextSelectionScrollView");
mScrollView.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
- mScrollView.SetParentOrigin( ParentOrigin::CENTER_LEFT );
- mScrollView.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
+ mScrollView.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER_LEFT );
+ mScrollView.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER_LEFT );
mScrollView.SetScrollingDirection( PanGestureDetector::DIRECTION_HORIZONTAL, Degree( 40.0f ) );
mScrollView.SetAxisAutoLock( true );
mScrollView.ScrollStartedSignal().Connect( this, &TextSelectionToolbar::OnScrollStarted );
mScrollView.ScrollCompletedSignal().Connect( this, &TextSelectionToolbar::OnScrollCompleted );
+ mScrollView.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_TO_BOUNDING_BOX ); // In a new layer, so clip to scroll-view's bounding box
mRulerX = new DefaultRuler(); // IntrusivePtr which is unreferenced when ScrollView is destroyed.
void TextSelectionToolbar::SetUp()
{
Actor self = Self();
- self.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
- // Create Layer and Stencil. Layer enable's clipping when content exceed maximum defined width.
- mStencilLayer = Layer::New();
- mStencilLayer.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
- mStencilLayer.SetParentOrigin( ParentOrigin::CENTER );
+ self.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
- ImageActor stencil = CreateSolidColorActor( Color::RED );
- stencil.SetDrawMode( DrawMode::STENCIL );
- stencil.SetVisible( true );
- stencil.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
- stencil.SetParentOrigin( ParentOrigin::CENTER );
+ // Create Actor to house the toolbar.
+ mToolbarActor = Actor::New();
+ mToolbarActor.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
+ mToolbarActor.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER );
+ mToolbarActor.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER );
- mScrollView = Toolkit::ScrollView::New();
+ if( !mScrollView )
+ {
+ mScrollView = Toolkit::ScrollView::New();
+ }
SetUpScrollView();
// Toolbar must start with at least one option, adding further options with increase it's size
mTableOfButtons = Dali::Toolkit::TableView::New( 1, 1 );
mTableOfButtons.SetFitHeight( 0 );
- mTableOfButtons.SetParentOrigin( ParentOrigin::CENTER_LEFT );
- mTableOfButtons.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
-
+ mTableOfButtons.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER_LEFT );
+ mTableOfButtons.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER_LEFT );
- mStencilLayer.Add( stencil );
- mStencilLayer.Add( mScrollView );
mScrollView.Add( mTableOfButtons );
- self.Add( mStencilLayer );
+ mToolbarActor.Add( mScrollView );
+
+ self.Add( mToolbarActor );
+}
+
+void TextSelectionToolbar::SetUpScrollBar( bool enable )
+{
+ if( enable )
+ {
+ if( ! mScrollBar )
+ {
+ Toolkit::ImageView indicator = Toolkit::ImageView::New();
+ indicator.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::TOP_LEFT );
+ indicator.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
+ indicator.SetStyleName( "TextSelectionScrollIndicator" );
+
+ mScrollBar = Toolkit::ScrollBar::New( Toolkit::ScrollBar::HORIZONTAL );
+ mScrollBar.SetProperty( Dali::Actor::Property::NAME, "Text popup scroll bar" );
+ mScrollBar.SetStyleName( "TextSelectionScrollBar" );
+ mScrollBar.SetProperty( Actor::Property::PARENT_ORIGIN, ParentOrigin::BOTTOM_LEFT );
+ mScrollBar.SetProperty( Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT );
+ mScrollBar.SetProperty( Actor::Property::POSITION, Vector2( mScrollBarPadding.x, -mScrollBarPadding.y ));
+ mScrollBar.SetResizePolicy( Dali::ResizePolicy::FIT_TO_CHILDREN, Dali::Dimension::WIDTH );
+ mScrollBar.SetProperty( Actor::Property::ORIENTATION, Quaternion( Quaternion( Radian( 1.5f * Math::PI ), Vector3::ZAXIS ) ) );
+ mScrollBar.SetScrollIndicator( indicator );
+ mScrollBar.GetPanGestureDetector().DetachAll();
+ mScrollView.Add( mScrollBar );
+ }
+ }
+ else
+ {
+ UnparentAndReset( mScrollBar );
+ }
}
void TextSelectionToolbar::OnScrollStarted( const Vector2& position )
{
- mTableOfButtons.SetSensitive( false );
+ if( mFirstScrollEnd )
+ {
+ mScrollView.SetOvershootEnabled( true );
+ }
+ mTableOfButtons.SetProperty( Actor::Property::SENSITIVE, false );
}
void TextSelectionToolbar::OnScrollCompleted( const Vector2& position )
{
- mTableOfButtons.SetSensitive( true );
+ mFirstScrollEnd = true;
+ mTableOfButtons.SetProperty( Actor::Property::SENSITIVE, true );
}
void TextSelectionToolbar::AddOption( Actor& option )
for( unsigned int i = 0; i < mDividerIndexes.Count(); ++i )
{
Actor divider = mTableOfButtons.GetChildAt( Toolkit::TableView::CellPosition( 0, mDividerIndexes[ i ] ) );
- divider.SetSize( size );
+ divider.SetProperty( Actor::Property::SIZE, size );
}
RelayoutRequest();
}
-void TextSelectionToolbar::RaiseAbove( Layer target )
+void TextSelectionToolbar::RaiseAbove( Actor target )
+{
+ mToolbarActor.RaiseAbove( target );
+}
+
+void TextSelectionToolbar::SetScrollBarPadding( const Vector2& padding )
+{
+ mScrollBarPadding = padding;
+ if( mScrollBar )
+ {
+ mScrollBar.SetProperty( Actor::Property::POSITION, Vector2( mScrollBarPadding.x, -mScrollBarPadding.y ));
+ }
+
+ RelayoutRequest();
+}
+
+void TextSelectionToolbar::ScrollTo( const Vector2& position )
+{
+ mFirstScrollEnd = false;
+ mScrollView.SetOvershootEnabled( false );
+ mScrollView.ScrollTo( position, 0.f );
+}
+
+void TextSelectionToolbar::ConfigureScrollview( const Property::Map& properties )
+{
+ // Set any properties specified for the label by iterating through all property key-value pairs.
+ for( unsigned int i = 0, mapCount = properties.Count(); i < mapCount; ++i )
+ {
+ const StringValuePair& propertyPair( properties.GetPair( i ) );
+
+ // Convert the property string to a property index.
+ Property::Index setPropertyIndex = mScrollView.GetPropertyIndex( propertyPair.first );
+ if( setPropertyIndex != Property::INVALID_INDEX )
+ {
+ // Convert the string representation of a color into a Vector4
+ if( setPropertyIndex == Toolkit::Scrollable::Property::OVERSHOOT_EFFECT_COLOR )
+ {
+ Vector4 color;
+ if( ConvertPropertyToColor( propertyPair.second, color ) )
+ {
+ mScrollView.SetOvershootEffectColor( color );
+ }
+ }
+ else
+ {
+ // If the conversion worked, we have a valid property index,
+ // Set the property to the new value.
+ mScrollView.SetProperty( setPropertyIndex, propertyPair.second );
+ }
+ }
+ }
+
+ RelayoutRequest();
+}
+
+const Vector2& TextSelectionToolbar::GetScrollBarPadding() const
{
- mStencilLayer.RaiseAbove( target );
+ return mScrollBarPadding;
}
TextSelectionToolbar::TextSelectionToolbar()
-: Control( ControlBehaviour( ControlBehaviour( REQUIRES_STYLE_CHANGE_SIGNALS ) ) ),
+: Control( ControlBehaviour( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ) ),
mMaxSize (),
+ mScrollBarPadding( DEFAULT_SCROLL_BAR_PADDING ),
mIndexInTable( 0 ),
- mDividerIndexes()
+ mDividerIndexes(),
+ mFirstScrollEnd( false )
{
}