2 * Copyright (c) 2014 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.
18 #include <dali/integration-api/debug.h>
20 #include <dali-toolkit/internal/controls/text-input/text-input-popup-impl.h>
21 #include <dali-toolkit/public-api/controls/buttons/push-button.h>
22 #include <dali-toolkit/public-api/controls/default-controls/solid-color-actor.h>
29 #define GET_LOCALE_TEXT(string) dgettext("sys_string", string)
33 const Vector2 DEFAULT_POPUP_INDICATOR_OFFSET(0.0f, 60.0f);
36 // TODO: This should be based on the content for example:
37 // 1. For selection: should be above top of highlighted selection, or below bottom of highlighted selection + end handle.
38 // 2. For cursor: should be above top of cursor, or below bottom of cursor + grab handle.
39 const std::string POPUP_ALTERNATIVE_OFFSET("popup-alternative-offset"); ///< Alternative offset property for confinenment constraint.
40 const std::string POPUP_REQUESTED_POSITION("popup-requested-position"); ///< Position the Popup was requested to be, for confinenment constraint.
43 * Image resource paths
45 const std::string POPUP_BACKGROUND( DALI_IMAGE_DIR "popup_bubble_bg.#.png" );
46 const std::string POPUP_BACKGROUND_EFFECT( DALI_IMAGE_DIR "popup_bubble_bg_ef.#.png" );
47 const std::string POPUP_BACKGROUND_LINE( DALI_IMAGE_DIR "popup_bubble_bg_line.#.png" );
48 const std::string POPUP_TAIL_BOTTOM( DALI_IMAGE_DIR "popup_bubble_tail_bottom.png" );
49 const std::string POPUP_TAIL_BOTTOM_EFFECT( DALI_IMAGE_DIR "popup_bubble_tail_bottom_ef.png" );
50 const std::string POPUP_TAIL_BOTTOM_LINE( DALI_IMAGE_DIR "popup_bubble_tail_bottom_line.png" );
51 const std::string OPTION_ICON_CLIPBOARD( DALI_IMAGE_DIR "copy_paste_icon_clipboard.png" );
52 const std::string OPTION_ICON_COPY( DALI_IMAGE_DIR "copy_paste_icon_copy.png" );
53 const std::string OPTION_ICON_CUT( DALI_IMAGE_DIR "copy_paste_icon_cut.png" );
54 const std::string OPTION_ICON_PASTE( DALI_IMAGE_DIR "copy_paste_icon_paste.png" );
55 const std::string OPTION_ICON_SELECT( DALI_IMAGE_DIR "copy_paste_icon_select.png" );
56 const std::string OPTION_ICON_SELECT_ALL( DALI_IMAGE_DIR "copy_paste_icon_select_all.png" );
59 * Constant values for building the GUI
61 const Vector4 POPUP_BORDER( 14.0f, 14.0f, 14.0f, 14.0f ); ///< The margin of the popup.
62 const Vector2 POPUP_MIN_SIZE( 0.0f, 126.0f ); ///< The minimum size of the popup.
63 const Vector2 POPUP_MAX_SIZE( 720.0f, 126.0f ); ///< The maximum size of the popup.
64 const float POPUP_TAIL_Y_OFFSET( -2.25f ); ///< The y offset of the tail.
65 const Vector2 POPUP_TAIL_SIZE( 36.0f, 36.0f ); ///< The size of the tail.
66 const Vector2 POPUP_DIVIDER_SIZE( 1.0f, 126.0f ); ///< The size of the divider.
68 const Vector4 OPTION_MARGIN( 0.0f, 0.0f, 24.0f, 19.0f ); ///< The margin of the icon. the order is left, right, top and bottom
69 const Vector2 OPTION_MAX_SIZE( 360.0f, 126.0f ); ///< The maximum size of the option.
70 const Vector2 OPTION_MIN_SIZE( 128.0f, 126.0f ); ///< The minimum size of the option.
71 const Vector2 OPTION_ICON_SIZE( 45.0f, 45.0f ); ///< The size of the icon.
72 const Vector2 OPTION_TEXT_MIN_SIZE( 128.0f, 30.0f ); ///< The minimum size of the text.
73 const float OPTION_GAP_ICON_TEXT( 8.0f ); ///< The gap between the icon and the text
75 const float HIDE_POPUP_ANIMATION_DURATION( 0.2f ); ///< Duration of popup hide animation in seconds.
76 const float SHOW_POPUP_ANIMATION_DURATION( 0.2f ); ///< Duration of popup show animation in seconds.
81 const Vector4 DEFAULT_POPUP_BACKGROUND( Vector4( .20f, 0.29f, 0.44f, 1.0f ) );
82 const Vector4 DEFAULT_POPUP_BACKGROUND_PRESSED( Vector4( 0.07f, 0.10f, 0.17f, 1.0f ) );
83 const Vector4 DEFAULT_POPUP_LINE_COLOR( Vector4( 0.36f, 0.45f, 0.59f, 1.0f ) );
84 const Vector4 DEFAULT_OPTION_ICON( Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) );
85 const Vector4 DEFAULT_OPTION_ICON_PRESSED( Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) );
86 const Vector4 DEFAULT_OPTION_TEXT( Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) );
87 const Vector4 DEFAULT_OPTION_TEXT_PRESSED( Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) );
91 * Confine Actor to boundaries of reference actor (e.g. Parent)
92 * Actor bounds (top-left position + size) are confined to reference Actor's
95 struct ConfinementConstraint
98 * Confinement constraint constructor.
99 * @param[in] topLeftMargin (optional) Top-Left margins (defaults to 0.0f, 0.0f)
100 * @param[in] bottomRightMargin (optional) Bottom-Right margins (defaults to 0.0f, 0.0f)
101 * @paran[in[ flipHorizontal (optional) whether to flip Actor to other side if near edge
102 * @param[in] flipVertical (optional) whether to flip Actor to the other side if near edge
103 * @param[in] boundingRect Rectangle to bound Popup to.
106 ConfinementConstraint(Vector2 topLeftMargin = Vector2::ZERO, Vector2 bottomRightMargin = Vector2::ZERO, bool flipHorizontal = false, bool flipVertical = false, Rect<float> boundingRect = Rect<float>(0.0f, 0.0f, 0.0f, 0.0f) )
107 : mMinIndent(topLeftMargin),
108 mMaxIndent(bottomRightMargin),
109 mFlipHorizontal(flipHorizontal),
110 mFlipVertical(flipVertical),
111 mBoundingRect( boundingRect )
115 Vector3 operator()(const Vector3& constPosition,
116 const PropertyInput& sizeProperty,
117 const PropertyInput& parentOriginProperty,
118 const PropertyInput& anchorPointProperty,
119 const PropertyInput& referenceSizeProperty,
120 const PropertyInput& alternativeOffsetProperty,
121 const PropertyInput& requestedPositionProperty )
123 const Vector3& size = sizeProperty.GetVector3();
124 const Vector3& origin = parentOriginProperty.GetVector3();
125 const Vector3& anchor = anchorPointProperty.GetVector3();
126 const Vector3& referenceSize = referenceSizeProperty.GetVector3();
127 const Vector2& alternativeOffset = alternativeOffsetProperty.GetVector2();
128 const Vector3& requestedPosition = requestedPositionProperty.GetVector3();
130 Vector3 newPosition( requestedPosition );
132 // Get actual position of Actor relative to parent's Top-Left.
133 Vector3 position(constPosition + origin * referenceSize);
135 // if top-left corner is outside of Top-Left bounds, then push back in screen.
137 Vector3 corner(position - size * anchor - mMinIndent);
139 if ( mFlipHorizontal )
141 if( corner.x < mBoundingRect.x )
143 // Snap Popup to left hand boundary so stays visible
144 corner.x = mBoundingRect.x - ( origin.x * referenceSize.x ) + ( size.x * anchor.x );
145 newPosition.x = corner.x;
147 else if ( ( corner.x + size.x ) > ( mBoundingRect.x + mBoundingRect.width ))
149 // Calculate offset from left boundary Popup must be placed at so it does not exceed right side boundary.
150 float requiredOffSetFromLeftBoundaryToFit = mBoundingRect.width - size.x;
151 corner.x = mBoundingRect.x + requiredOffSetFromLeftBoundaryToFit - ( origin.x * referenceSize.x ) + ( size.x * anchor.x );
152 newPosition.x = corner.x;
156 if(mFlipVertical && corner.y < 0.0f)
159 newPosition.y += size.height + alternativeOffset.height;
162 newPosition.y -= std::min(corner.y, 0.0f);
164 // if bottom-right corner is outside of Bottom-Right bounds, then push back in screen.
165 corner += size - referenceSize + mMinIndent + mMaxIndent;
167 if(mFlipVertical && corner.y > 0.0f)
170 newPosition.y -= size.height + alternativeOffset.height;
176 Vector3 mMinIndent; ///< Top-Left Margin
177 Vector3 mMaxIndent; ///< Bottom-Right Margin.
178 bool mFlipHorizontal; ///< Whether to flip actor's position if exceeds horizontal screen bounds
179 bool mFlipVertical; ///< Whether to flip actor's position if exceeds vertical screen bounds
180 Rect<float> mBoundingRect; ///< Bounding Rect Popup must stay within
184 * Confine actor to the x axis boundaries of reference actor (e.g. Parent)
186 struct ParentXAxisConstraint
189 * Confinement constraint constructor.
191 ParentXAxisConstraint( float handlesMidPoint = 0.0f )
192 : mHandlesMidPoint( handlesMidPoint )
196 float operator()( const float constXPosition,
197 const PropertyInput& localSizeWidthProperty,
198 const PropertyInput& parentWidthProperty,
199 const PropertyInput& anchorPointXProperty )
201 const float localSizeProperty = localSizeWidthProperty.GetFloat();
202 const float size = parentWidthProperty.GetFloat();
204 float newPosition = std::max( mHandlesMidPoint, -size/2 + localSizeProperty );
205 newPosition = std::min( newPosition, size/2 - localSizeProperty );
209 float mHandlesMidPoint;
213 } // unnamed namespace
224 const char* const TextInputPopup::SIGNAL_PRESSED = "pressed";
225 const char* const TextInputPopup::SIGNAL_HIDE_FINISHED = "hide-finished";
226 const char* const TextInputPopup::SIGNAL_SHOW_FINISHED = "show-finished";
228 const char* const TextInputPopup::OPTION_SELECT_WORD = "option-select_word"; // "Select Word" popup option.
229 const char* const TextInputPopup::OPTION_SELECT_ALL("option-select_all"); // "Select All" popup option.
230 const char* const TextInputPopup::OPTION_CUT("option-cut"); // "Cut" popup option.
231 const char* const TextInputPopup::OPTION_COPY("option-copy"); // "Copy" popup option.
232 const char* const TextInputPopup::OPTION_PASTE("option-paste"); // "Paste" popup option.
233 const char* const TextInputPopup::OPTION_CLIPBOARD("option-clipboard"); // "Clipboard" popup option.
235 TextInputPopup::TextInputPopup()
236 : mState(StateHidden),
238 mPopupTailXPosition( 0.0f ),
239 mContentSize( POPUP_MIN_SIZE ),
240 mBackgroundColor( DEFAULT_POPUP_BACKGROUND ),
241 mBackgroundPressedColor( DEFAULT_POPUP_BACKGROUND_PRESSED ),
242 mLineColor( DEFAULT_POPUP_LINE_COLOR ),
243 mIconColor( DEFAULT_OPTION_ICON ),
244 mIconPressedColor( DEFAULT_OPTION_ICON_PRESSED ),
245 mTextColor( DEFAULT_OPTION_TEXT ),
246 mTextPressedColor( DEFAULT_OPTION_TEXT_PRESSED ),
247 mSelectOptionPriority(1),
248 mSelectAllOptionPriority(2),
249 mCutOptionPriority(3),
250 mCopyOptionPriority(4),
251 mPasteOptionPriority(5),
252 mClipboardOptionPriority(6),
254 mHideFinishedSignal(),
255 mShowFinishedSignal()
257 mAlternativeOffsetProperty = mRoot.RegisterProperty( POPUP_ALTERNATIVE_OFFSET, Vector2::ZERO );
258 mRequestionPositionProperty = mRoot.RegisterProperty( POPUP_REQUESTED_POSITION, Vector3::ZERO );
259 mRoot.SetParentOrigin( ParentOrigin::CENTER );
260 mRoot.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
261 // constrain popup to size of parent.
264 void TextInputPopup::AddToStage()
266 // TODO: Confinement constraint borders should be defined by the application.
267 // It should also not use the stage directly, instead it should add to parent container.
268 Stage::GetCurrent().Add(mRoot);
270 ApplyConfinementConstraint();
273 void TextInputPopup::ApplyConfinementConstraint()
275 mRoot.RemoveConstraints();
276 Constraint constraint = Constraint::New<Vector3>( Actor::POSITION,
277 LocalSource( Actor::SIZE ),
278 LocalSource( Actor::PARENT_ORIGIN ),
279 LocalSource( Actor::ANCHOR_POINT ),
280 ParentSource( Actor::SIZE ),
281 LocalSource( mAlternativeOffsetProperty ),
282 LocalSource( mRequestionPositionProperty),
283 ConfinementConstraint( DEFAULT_POPUP_INDICATOR_OFFSET,
286 true, mBoundingRect ) );
287 mRoot.ApplyConstraint(constraint);
290 void TextInputPopup::ApplyTailConstraint()
292 mTail.RemoveConstraints();
293 Constraint constraint = Constraint::New<float>( Actor::POSITION_X,
294 LocalSource( Actor::SIZE_WIDTH ),
295 ParentSource( Actor::SIZE_WIDTH ),
296 LocalSource( Actor::PARENT_ORIGIN_X ),
297 ParentXAxisConstraint( mPopupTailXPosition ));
298 mTail.ApplyConstraint( constraint );
301 void TextInputPopup::CreateStencil( const Vector2& size)
303 mStencil = CreateSolidColorActor( Color::BLUE );
304 mStencil.SetParentOrigin( ParentOrigin::CENTER );
305 mStencil.SetAnchorPoint( AnchorPoint::CENTER );
306 mStencil.SetDrawMode( DrawMode::STENCIL );
307 mStencil.SetVisible( true );
308 mStencil.SetName( "popup-stencil" );
309 mStencil.SetSize( size );
312 void TextInputPopup::OnScrollStarted( const Vector3& position )
314 mBackground.SetSensitive( false );
317 void TextInputPopup::OnScrollCompleted( const Vector3& position )
319 mBackground.SetSensitive( true );
322 void TextInputPopup::CreateScrollView()
324 mScrollView = Toolkit::ScrollView::New();
325 mScrollView.SetName("popup-scroll-view");
326 mScrollView.SetAnchorPoint( AnchorPoint::TOP_LEFT );
327 mScrollView.SetParentOrigin( ParentOrigin::TOP_LEFT );
328 mScrollView.SetPosition( POPUP_BORDER.x, POPUP_BORDER.y );
329 mScrollView.SetScrollingDirection( PanGestureDetector::DIRECTION_HORIZONTAL, Degree( 40.0f ) );
330 mScrollView.SetAxisAutoLock( true );
331 mScrollView.ScrollStartedSignal().Connect( this, &TextInputPopup::OnScrollStarted );
332 mScrollView.ScrollCompletedSignal().Connect( this, &TextInputPopup::OnScrollCompleted );
335 void TextInputPopup::UpdateScrollViewProperty( const Vector2& visibleSize )
337 mScrollView.SetSize( visibleSize.x, visibleSize.y );
339 RulerPtr rulerX = new DefaultRuler(); // IntrusivePtr which is unreferenced when ScrollView is destroyed.
340 RulerPtr rulerY = new DefaultRuler(); // IntrusivePtr which is unreferenced when ScrollView is destroyed.
342 rulerX->SetDomain( RulerDomain( 0, mContentSize.width, true ) );
343 mScrollView.SetRulerX(rulerX);
344 mScrollView.SetRulerY(rulerY);
347 void TextInputPopup::RemoveFromStage()
349 Stage::GetCurrent().Remove( mRoot );
352 void TextInputPopup::Clear()
356 UnparentAndReset( mTail );
357 UnparentAndReset( mStencil );
358 UnparentAndReset( mBackground );
359 UnparentAndReset( mScrollView );
360 mButtonContainer.clear();
361 mDividerContainer.clear();
364 mRoot.RemoveConstraints();
366 mState = StateHidden;
370 ImageActor TextInputPopup::CreateOptionIcon( Image iconImage, const Vector4& color )
372 ImageActor icon = ImageActor::New( iconImage );
373 icon.SetSize( OPTION_ICON_SIZE );
374 icon.SetParentOrigin( ParentOrigin::TOP_CENTER );
375 icon.SetAnchorPoint( AnchorPoint::TOP_CENTER );
376 icon.SetColor( color );
377 icon.SetY( OPTION_MARGIN.z );
381 Toolkit::TextView TextInputPopup::CreateOptionCaption( const std::string& caption, const Vector4& color )
384 style.SetTextColor( color );
386 PointSize pointSize( Font::PixelsToPoints( OPTION_TEXT_MIN_SIZE.y ) );
387 style.SetFontPointSize( pointSize );
389 MarkupProcessor::StyledTextArray styledCaption;
390 styledCaption.push_back( MarkupProcessor::StyledText( Text( caption ), style ) );
392 Toolkit::TextView textView = Toolkit::TextView::New( styledCaption );
393 textView.SetSizePolicy( Toolkit::Control::Fixed, Toolkit::Control::Fixed );
394 textView.SetWidthExceedPolicy( Toolkit::TextView::ShrinkToFit );
395 textView.SetHeightExceedPolicy( Toolkit::TextView::ShrinkToFit );
396 textView.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
397 textView.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
398 textView.SetY( -OPTION_MARGIN.w );
400 const float textWidth = textView.GetWidthForHeight( OPTION_TEXT_MIN_SIZE.y );
401 textView.SetSize( textWidth, OPTION_TEXT_MIN_SIZE.y );
406 void TextInputPopup::CreateBackground()
408 // Create background-panel if not already created (required if we have at least one option)
411 Image bgImg = Image::New( POPUP_BACKGROUND );
412 mBackground = ImageActor::New( bgImg );
413 mBackground.SetAnchorPoint( AnchorPoint::CENTER );
414 mBackground.SetParentOrigin( ParentOrigin::CENTER );
415 mBackground.SetName( "text-input-popup-background" );
416 mBackground.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
417 mBackground.SetColor( mBackgroundColor );
419 Image bgEffectImg = Image::New( POPUP_BACKGROUND_EFFECT );
420 mBackgroundEffect = ImageActor::New( bgEffectImg );
421 mBackgroundEffect.SetAnchorPoint( AnchorPoint::CENTER );
422 mBackgroundEffect.SetParentOrigin( ParentOrigin::CENTER );
423 mBackgroundEffect.SetName( "text-input-popup-background-effect" );
424 mBackgroundEffect.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
425 mBackgroundEffect.SetZ( 1.0f );
426 mBackground.Add( mBackgroundEffect );
428 Image bgLine = Image::New( POPUP_BACKGROUND_LINE );
429 mBackgroundLine = ImageActor::New( bgLine );
430 mBackgroundLine.SetAnchorPoint( AnchorPoint::CENTER);
431 mBackgroundLine.SetParentOrigin( ParentOrigin::CENTER );
432 mBackgroundLine.SetName( "text-input-popup-background-effect" );
433 mBackgroundLine.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
434 mBackgroundLine.SetColor( mLineColor );
435 mBackgroundLine.SetZ( 0.1f );
436 mBackgroundEffect.Add( mBackgroundLine );
443 void TextInputPopup::CreateTail()
447 Image tail = Image::New( POPUP_TAIL_BOTTOM );
448 mTail = ImageActor::New( tail );
449 mTail.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
450 mTail.SetAnchorPoint( AnchorPoint::TOP_CENTER );
451 mTail.SetName( "text-input-popup-tail" );
452 mTail.SetPosition( 0.0f, POPUP_TAIL_Y_OFFSET - POPUP_BORDER.w, 1.2f );
453 mTail.SetColor( mBackgroundColor );
455 Image tailEffect = Image::New( POPUP_TAIL_BOTTOM_EFFECT );
456 mTailEffect = ImageActor::New( tailEffect );
457 mTailEffect.SetParentOrigin( ParentOrigin::CENTER );
458 mTailEffect.SetAnchorPoint( AnchorPoint::CENTER );
459 mTailEffect.SetName( "text-input-popup-tail-effect" );
460 mTailEffect.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
461 mTailEffect.SetZ( 0.1f );
462 mTail.Add( mTailEffect );
464 Image tailLine = Image::New( POPUP_TAIL_BOTTOM_LINE );
465 mTailLine = ImageActor::New( tailLine );
466 mTailLine.SetParentOrigin( ParentOrigin::CENTER );
467 mTailLine.SetAnchorPoint( AnchorPoint::CENTER );
468 mTailLine.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
469 mTailLine.SetName( "text-input-popup-tail-line" );
470 mTailLine.SetColor( mLineColor );
471 mTailLine.SetZ( 0.1f );
472 mTailEffect.Add( mTailLine );
476 ImageActor TextInputPopup::CreateDivider()
478 ImageActor divider = Toolkit::CreateSolidColorActor( mLineColor );
479 divider.SetParentOrigin( ParentOrigin::TOP_LEFT );
480 divider.SetAnchorPoint( AnchorPoint::TOP_LEFT );
481 divider.SetSize( POPUP_DIVIDER_SIZE );
482 divider.SetPosition( mContentSize.width - POPUP_DIVIDER_SIZE.width, 0.0f );
484 // Keep track of all the dividers. As their height's need to be updated to the max. of all
485 // buttons currently added.
486 mDividerContainer.push_back( divider );
491 ImageActor TextInputPopup::CreatePressedBackground( const Vector2& requiredSize )
493 ImageActor pressedBg = Toolkit::CreateSolidColorActor( mBackgroundPressedColor );
494 pressedBg.SetDrawMode( DrawMode::OVERLAY );
495 pressedBg.SetParentOrigin( ParentOrigin::CENTER );
496 pressedBg.SetAnchorPoint( AnchorPoint::CENTER );
497 pressedBg.SetSize( requiredSize );
501 TextInputPopup::ButtonRequirement TextInputPopup::CreateRequiredButton( TextInputPopup::Buttons buttonId, std::size_t orderOfPriority,
502 const std::string& name, const std::string& caption, Image iconImage, bool enabled )
504 TextInputPopup::ButtonRequirement currentButton;
505 currentButton.buttonId = buttonId;
506 currentButton.orderOfPriority = orderOfPriority;
507 currentButton.name = name;
508 currentButton.caption = caption;
509 currentButton.iconImage = iconImage;
510 currentButton.enabled = enabled;
512 return currentButton;
515 void TextInputPopup::CreateOrderedListOfOptions()
517 mOrderListOfButtons.clear();
519 for ( std::size_t index= 0; index < ButtonsEnumEnd; index++ )
521 TextInputPopup::ButtonRequirement currentButton;
523 // Create button for each possible option using Option priority
528 Image cutIcon = Image::New( OPTION_ICON_CUT );
529 currentButton = CreateRequiredButton( ButtonsCut, mCutOptionPriority, OPTION_CUT, GET_LOCALE_TEXT("IDS_COM_BODY_CUT"), cutIcon, false );
534 Image copyIcon = Image::New( OPTION_ICON_COPY );
535 currentButton = CreateRequiredButton( ButtonsCopy, mCopyOptionPriority, OPTION_COPY, GET_LOCALE_TEXT("IDS_COM_BODY_COPY"), copyIcon, false );
540 Image pasteIcon = Image::New( OPTION_ICON_PASTE );
541 currentButton = CreateRequiredButton( ButtonsPaste, mPasteOptionPriority, OPTION_PASTE, GET_LOCALE_TEXT("IDS_COM_BODY_PASTE"), pasteIcon, false );
546 Image selectIcon = Image::New( OPTION_ICON_SELECT );
547 currentButton = CreateRequiredButton( ButtonsSelect, mSelectOptionPriority, OPTION_SELECT_WORD, GET_LOCALE_TEXT("IDS_COM_SK_SELECT"), selectIcon, false );
550 case ButtonsSelectAll:
552 Image selectAllIcon = Image::New( OPTION_ICON_SELECT_ALL );
553 currentButton = CreateRequiredButton( ButtonsSelectAll, mSelectAllOptionPriority, OPTION_SELECT_ALL, GET_LOCALE_TEXT("IDS_COM_BODY_SELECT_ALL"), selectAllIcon, false );
556 case ButtonsClipboard:
558 Image clipboardIcon = Image::New( OPTION_ICON_CLIPBOARD );
559 currentButton = CreateRequiredButton( ButtonsClipboard, mClipboardOptionPriority, OPTION_CLIPBOARD, GET_LOCALE_TEXT("IDS_COM_BODY_CLIPBOARD"), clipboardIcon, false );
564 DALI_ASSERT_DEBUG( "ButtonsEnumEnd used but an invalid choice");
565 currentButton.orderOfPriority = 0;
572 // Insert button in list of buttons in order of priority setting.
573 for( std::vector<ButtonRequirement>::iterator it = mOrderListOfButtons.begin(), endIt = mOrderListOfButtons.end(); ( it != endIt && !match ); ++it )
575 const ButtonRequirement& button( *it );
576 if ( currentButton.orderOfPriority < button.orderOfPriority )
578 if ( currentButton.orderOfPriority != 0 ) // If order priority 0 then do not add button as not required.
580 mOrderListOfButtons.insert( it, currentButton );
588 mOrderListOfButtons.push_back( currentButton );
593 void TextInputPopup::AddOption(const std::string& name, const std::string& caption, const Image iconImage, bool finalOption)
595 // 1. Create container for text and icon when not pressed.
596 Actor optionContainer = Actor::New();
597 optionContainer.SetParentOrigin( ParentOrigin::TOP_LEFT );
598 optionContainer.SetAnchorPoint( AnchorPoint::TOP_LEFT );
601 Toolkit::TextView captionTextView = CreateOptionCaption( caption, mTextColor );
602 optionContainer.Add( captionTextView );
605 ImageActor icon = CreateOptionIcon( iconImage, mIconColor );
606 optionContainer.Add( icon );
608 // 4. Calculate the size of option.
609 const Vector2 textSize = Vector2( captionTextView.GetNaturalSize() );
610 const Vector2 optionSize( std::max( textSize.x, OPTION_ICON_SIZE.x ),
611 OPTION_MARGIN.z + OPTION_ICON_SIZE.y + OPTION_GAP_ICON_TEXT + textSize.y + OPTION_MARGIN.w );
612 const Vector2 constrainedOptionSize = Min( Max( optionSize, OPTION_MIN_SIZE ), OPTION_MAX_SIZE );
614 // 5. Create a option.
615 Toolkit::PushButton option = Toolkit::PushButton::New();
616 option.SetSizePolicy( Toolkit::Control::Fixed, Toolkit::Control::Fixed );
617 option.SetParentOrigin( ParentOrigin::TOP_LEFT );
618 option.SetAnchorPoint( AnchorPoint::TOP_LEFT );
619 option.SetSize( constrainedOptionSize );
620 option.SetX( mContentSize.x );
621 option.SetName( name );
622 option.SetAnimationTime( 0.0f );
623 option.ClickedSignal().Connect( this, &TextInputPopup::OnButtonPressed );
624 mScrollView.Add( option );
626 // 6. Set the normal option image.
627 option.SetButtonImage( optionContainer );
629 // 7. Update the content size.
630 mContentSize.x += constrainedOptionSize.x;
632 // 8. Create the pressed container.
633 Actor optionPressedContainer = Actor::New();
635 // 9. Add option pressed background.
636 Vector2 optionPressedBackgroundSize( constrainedOptionSize.x - 1.0f, constrainedOptionSize.y - 2.0f );
637 ImageActor optionPressedBackground = CreatePressedBackground( optionPressedBackgroundSize );
638 optionPressedContainer.Add( optionPressedBackground );
640 // 10. Add pressed text
641 Toolkit::TextView pressedCaptionTextView = CreateOptionCaption( caption, mTextPressedColor );
642 optionPressedBackground.Add( pressedCaptionTextView );
644 // 11. Add pressed icon
645 ImageActor pressedIcon = CreateOptionIcon( iconImage, mIconPressedColor );
646 optionPressedBackground.Add( pressedIcon );
648 // 12. Set the pressed option image
649 option.SetPressedImage( optionPressedContainer );
651 // 13. Add the divider
654 ImageActor divider = CreateDivider();
655 mScrollView.Add( divider );
659 void TextInputPopup::Hide(bool animate)
671 mAnimation = Animation::New( HIDE_POPUP_ANIMATION_DURATION );
672 mAnimation.AnimateTo( Property(mRoot, Actor::SCALE), Vector3::ZERO, AlphaFunctions::EaseOut );
673 mAnimation.AnimateTo( Property(mRoot, Actor::COLOR_ALPHA), 0.0f, AlphaFunctions::EaseOut );
676 mAnimation.FinishedSignal().Connect( this, &TextInputPopup::OnHideFinished );
677 mState = StateHiding;
681 mRoot.SetProperty(Actor::SCALE, Vector3::ZERO);
682 mRoot.SetProperty(Actor::COLOR_ALPHA, 0.0f);
683 mState = StateHidden;
688 void TextInputPopup::Show(bool animate)
692 mRoot.SetSensitive( true );
702 mAnimation = Animation::New( SHOW_POPUP_ANIMATION_DURATION );
703 mAnimation.AnimateTo( Property(mRoot, Actor::SCALE), Vector3::ONE, AlphaFunctions::EaseOut );
704 mAnimation.AnimateTo( Property(mRoot, Actor::COLOR_ALPHA), 1.0f, AlphaFunctions::EaseOut );
707 mAnimation.FinishedSignal().Connect( this, &TextInputPopup::OnShowFinished );
708 mState = StateShowing;
712 mRoot.SetProperty(Actor::SCALE, Vector3::ONE);
713 mRoot.SetProperty(Actor::COLOR_ALPHA, 1.0f);
719 void TextInputPopup::SetAlternativeOffset(Vector2 offset)
721 mRoot.SetProperty( mAlternativeOffsetProperty, offset );
722 ApplyConfinementConstraint();
725 TextInputPopup::State TextInputPopup::GetState(void) const
730 Actor TextInputPopup::GetRootActor() const
737 void TextInputPopup::SetCutPastePopupColor( const Vector4& color )
739 mBackgroundColor = color;
742 const Vector4& TextInputPopup::GetCutPastePopupColor() const
744 return mBackgroundColor;
747 void TextInputPopup::SetCutPastePopupPressedColor( const Vector4& color )
749 mBackgroundPressedColor = color;
752 const Vector4& TextInputPopup::GetCutPastePopupPressedColor() const
754 return mBackgroundPressedColor;
757 void TextInputPopup::SetCutPastePopupBorderColor( const Vector4& color )
762 const Vector4& TextInputPopup::GetCutPastePopupBorderColor() const
767 void TextInputPopup::SetCutPastePopupIconColor( const Vector4& color )
772 const Vector4& TextInputPopup::GetCutPastePopupIconColor() const
777 void TextInputPopup::SetCutPastePopupIconPressedColor( const Vector4& color )
779 mIconPressedColor = color;
782 const Vector4& TextInputPopup::GetCutPastePopupIconPressedColor()
784 return mIconPressedColor;
787 void TextInputPopup::SetCutPastePopupTextColor( const Vector4& color )
792 const Vector4& TextInputPopup::GetCutPastePopupTextColor()
797 void TextInputPopup::SetCutPastePopupTextPressedColor( const Vector4& color )
799 mTextPressedColor = color;
802 const Vector4& TextInputPopup::GetCutPastePopupTextPressedColor()
804 return mTextPressedColor;
807 void TextInputPopup::TogglePopupButtonOnOff( TextInputPopup::Buttons requiredButton, bool enable )
809 bool match ( false );
810 for( std::vector<ButtonRequirement>::iterator it = mOrderListOfButtons.begin(), endIt = mOrderListOfButtons.end(); ( it != endIt && !match ); ++it )
812 ButtonRequirement& button( *it );
813 if ( requiredButton == button.buttonId )
815 button.enabled = enable;
821 void TextInputPopup::SetButtonPriorityPosition( TextInputPopup::Buttons button, unsigned int priority )
827 mCutOptionPriority = priority;
832 mCopyOptionPriority = priority;
837 mPasteOptionPriority = priority;
842 mSelectOptionPriority = priority;
845 case ButtonsSelectAll:
847 mSelectAllOptionPriority = priority;
850 case ButtonsClipboard:
852 mClipboardOptionPriority = priority;
857 DALI_ASSERT_DEBUG( "ButtonsEnumEnd used but an invalid choice");
861 CreateOrderedListOfOptions(); // Update list of options as priority changed.
864 unsigned int TextInputPopup::GetButtonPriorityPosition( TextInputPopup::Buttons button ) const
866 unsigned int priority = 0;
872 priority = mCutOptionPriority;
877 priority = mCopyOptionPriority;
882 priority = mPasteOptionPriority;
887 priority = mSelectOptionPriority;
890 case ButtonsSelectAll:
892 priority = mSelectAllOptionPriority;
895 case ButtonsClipboard:
897 priority = mClipboardOptionPriority;
902 DALI_ASSERT_DEBUG( "ButtonsEnumEnd used but an invalid choice");
910 void TextInputPopup::AddPopupOptions()
912 mContentSize = POPUP_MIN_SIZE;
914 // 1. Create the background.
916 mRoot.Add(mBackground);
918 // 2. Create the tail.
920 mBackground.Add( mTail );
922 // 3. Create the scroll view.
924 mBackground.Add( mScrollView );
926 // 4. Create the options and add into the scroll view.
927 for( std::vector<ButtonRequirement>::const_iterator it = mOrderListOfButtons.begin(), endIt = mOrderListOfButtons.end(); ( it != endIt ); ++it )
929 const ButtonRequirement& button( *it );
930 if ( button.enabled )
932 AddOption( button.name, button.caption, button.iconImage, it != ( endIt - 1 ) ? false : true );
936 // 5. Calcurate a lot of size to make the layout.
937 const Vector2 visibleContentSize = Vector2( std::min( mContentSize.x, POPUP_MAX_SIZE.x - POPUP_BORDER.x - POPUP_BORDER.y ), mContentSize.y );
938 const Vector2 popupSize = Vector2( POPUP_BORDER.x + visibleContentSize.x + POPUP_BORDER.y,
939 POPUP_BORDER.z + visibleContentSize.y + POPUP_BORDER.w );
941 // 6. Set the scroll view ruller.
942 UpdateScrollViewProperty( visibleContentSize );
945 const Vector2 stencilSize = Vector2( popupSize.x, popupSize.y + POPUP_TAIL_SIZE.x + POPUP_TAIL_Y_OFFSET );
946 CreateStencil( stencilSize );
947 mRoot.Add( mStencil );
949 // 7. Set the root size.
950 mRoot.SetSize( popupSize ); // Make Root Actor reflect the size of its content
954 void TextInputPopup::SetPopupBoundary( const Rect<float>& boundingRectangle )
956 mBoundingRect = boundingRectangle;
959 void TextInputPopup::SetTailPosition( const Vector3& position )
961 mRoot.SetProperty( mRequestionPositionProperty, position );
962 mPopupTailXPosition = position.x;
963 ApplyConfinementConstraint();
964 ApplyTailConstraint();
967 bool TextInputPopup::OnButtonPressed( Toolkit::Button button )
969 mPressedSignal.Emit( button );
973 void TextInputPopup::OnHideFinished(Animation& source)
975 source.FinishedSignal().Disconnect( this, &TextInputPopup::OnHideFinished );
977 mState = StateHidden;
978 mHideFinishedSignal.Emit( *this );
981 void TextInputPopup::OnShowFinished(Animation& source)
983 source.FinishedSignal().Disconnect( this, &TextInputPopup::OnShowFinished );
985 mShowFinishedSignal.Emit( *this );
988 TextInputPopup::PressedSignalV2& TextInputPopup::PressedSignal()
990 return mPressedSignal;
993 TextInputPopup::HideFinishedSignalV2& TextInputPopup::HideFinishedSignal()
995 return mHideFinishedSignal;
998 TextInputPopup::ShowFinishedSignalV2& TextInputPopup::ShowFinishedSignal()
1000 return mShowFinishedSignal;
1003 } // namespace Internal
1005 } // namespace Toolkit