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-toolkit/internal/controls/text-input/text-input-popup-impl.h>
20 #include <dali-toolkit/public-api/controls/buttons/push-button.h>
21 #include <dali-toolkit/public-api/controls/default-controls/solid-color-actor.h>
28 #define GET_LOCALE_TEXT(string) dgettext("sys_string", string)
34 const Vector4 DEFAULT_POPUP_BACKGROUND( Vector4( .20f, 0.29f, 0.44f, 1.0f ) );
35 const Vector4 DEFAULT_POPUP_BUTTON_PRESSED( Vector4( 0.07f, 0.10f, 0.17f, 1.0f ) );
36 const Vector4 DEFAULT_BORDER_COLOR( Vector4( 0.36f, 0.45f, 0.59f, 1.0f ) );
37 const Vector3 POPUP_BORDER( Vector3(1.0f, 1.0f, 0.0f) );
39 /* Functionality in place to have the end buttons using different images to inner button.
40 * Supply a centre image and then a left and right image, the centre image can have straight ends while
41 * the left image can be rounded on the left and straight on the right, the right image can be straight on the left and rounded on the right.
45 const char* DEFAULT_POPUP_TAIL_BOTTOM( DALI_IMAGE_DIR "00_popup_bubble_tail_bottom.png" );
47 // Popup: Vertical Constraint
48 // TODO: Remove - this should come from application - it is not possible to get the
49 // height of the indicator actor from Dali-Toolkit.
51 const float POP_UP_SCREEN_EDGE_MARGIN( 4.0f );
52 const Vector2 DEFAULT_POPUP_INDICATOR_OFFSET(POP_UP_SCREEN_EDGE_MARGIN, 60.0f);
54 const Vector3 POPUP_TEXT_OFFSET( 0.0f, 0.0f, 0.0f );
55 const Vector3 POPUP_TEXT_ENLARGE( 12.0f, 28.0f, 0.0f );
56 const Vector3 POPUP_MINIMUM_SIZE( 128.0f, 124.0f, 0.0f );
58 const Vector3 BUTTON_TEXT_ENLARGE( 32.0f, 0.0f, 0.0f );
59 const Vector3 BUTTON_TEXT_MINIMUM_SIZE( 128.0f, 126.0f, 0.0f );
60 const Vector3 BUTTON_TEXT_MAXIMUM_SIZE( 190.0f, 126.0f, 0.0f );
61 const Vector3 TEXT_LABEL_MAX_SIZE( 160.0f, 30.0f, 0.0f );
63 const float DIVIDER_WIDTH(2.0f); ///< Width of each button divider
64 const float DIVIDER_MARGIN(0.0f); ///< Top/Bottom Margin between divider and edge of popup.
66 const float DEFAULT_UI_FONT_SIZE(7.0f); ///< Standard font size for Text-Input's UI
68 const float HIDE_POPUP_ANIMATION_DURATION(0.2f); ///< Duration of popup hide animation in seconds.
69 const float SHOW_POPUP_ANIMATION_DURATION(0.2f); ///< Duration of popup show animation in seconds.
71 const Vector2 DEFAULT_ICON_SIZE( 45.0f, 45.0f ); ///< Default icon size for image in options
72 const float TEXT_POSITION_OFFSET( -19.0f ); ///< Default offset for text label
73 const float ICON_POSITION_OFFSET( 19.0f ); ///< Default offset for icon
75 const char* DEFAULT_ICON_CLIPBOARD( DALI_IMAGE_DIR "copy_paste_icon_clipboard.png" );
76 const char* DEFAULT_ICON_COPY( DALI_IMAGE_DIR "copy_paste_icon_copy.png" );
77 const char* DEFAULT_ICON_CUT( DALI_IMAGE_DIR "copy_paste_icon_cut.png" );
78 const char* DEFAULT_ICON_PASTE( DALI_IMAGE_DIR "copy_paste_icon_paste.png" );
79 const char* DEFAULT_ICON_SELECT( DALI_IMAGE_DIR "copy_paste_icon_select.png" );
80 const char* DEFAULT_ICON_SELECT_ALL( DALI_IMAGE_DIR "copy_paste_icon_select_all.png" );
82 // TODO: This should be based on the content for example:
83 // 1. For selection: should be above top of highlighted selection, or below bottom of highlighted selection + end handle.
84 // 2. For cursor: should be above top of cursor, or below bottom of cursor + grab handle.
85 const std::string POPUP_ALTERNATIVE_OFFSET("popup-alternative-offset"); ///< Alternative offset property for confinenment constraint.
89 * Confine Actor to boundaries of reference actor (e.g. Parent)
90 * Actor bounds (top-left position + size) are confined to reference Actor's
93 struct ConfinementConstraint
96 * Confinement constraint constructor.
97 * @param[in] topLeftMargin (optional) Top-Left margins (defaults to 0.0f, 0.0f)
98 * @param[in] bottomRightMargin (optional) Bottom-Right margins (defaults to 0.0f, 0.0f)
99 * @paran[in[ flipHorizontal (optional) whether to flip Actor to other side if near edge
100 * @param[in] flipVertical (optional) whether to flip Actor to the other side if near edge
101 * @param[in] boundingRect Rectangle to bound Popup to.
104 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) )
105 : mMinIndent(topLeftMargin),
106 mMaxIndent(bottomRightMargin),
107 mFlipHorizontal(flipHorizontal),
108 mFlipVertical(flipVertical),
109 mBoundingRect( boundingRect )
113 Vector3 operator()(const Vector3& constPosition,
114 const PropertyInput& sizeProperty,
115 const PropertyInput& parentOriginProperty,
116 const PropertyInput& anchorPointProperty,
117 const PropertyInput& referenceSizeProperty,
118 const PropertyInput& alternativeOffsetProperty)
120 const Vector3& size = sizeProperty.GetVector3();
121 const Vector3& origin = parentOriginProperty.GetVector3();
122 const Vector3& anchor = anchorPointProperty.GetVector3();
123 const Vector3& referenceSize = referenceSizeProperty.GetVector3();
124 const Vector2& alternativeOffset = alternativeOffsetProperty.GetVector2();
126 Vector3 newPosition(constPosition);
128 // Get actual position of Actor relative to parent's Top-Left.
129 Vector3 position(constPosition + origin * referenceSize);
131 // if top-left corner is outside of Top-Left bounds, then push back in screen.
133 Vector3 corner(position - size * anchor - mMinIndent);
135 newPosition.x -= std::max(corner.x, 0.0f);
137 if ( mFlipHorizontal )
139 if( corner.x < mBoundingRect.x + POP_UP_SCREEN_EDGE_MARGIN )
141 // Snap PopUp to left hand boundary so stays visible
142 corner.x = mBoundingRect.x + POP_UP_SCREEN_EDGE_MARGIN ;
144 else if ( ( corner.x + size.x ) > ( ( mBoundingRect.x + mBoundingRect.width ) - POP_UP_SCREEN_EDGE_MARGIN ))
146 // Calculate offset from left boundary PopUp must be placed at so it does not exceed right side boundary.
147 float requiredOffSetFromLeftBoundaryToFit = mBoundingRect.width - POP_UP_SCREEN_EDGE_MARGIN - size.x;
148 corner.x = mBoundingRect.x + requiredOffSetFromLeftBoundaryToFit - ( origin.x * referenceSize.x ) + ( size.x * anchor.x );
150 newPosition.x = corner.x;
153 if(mFlipVertical && corner.y < 0.0f)
156 newPosition.y += size.height + alternativeOffset.height;
159 newPosition.y -= std::min(corner.y, 0.0f);
161 // if bottom-right corner is outside of Bottom-Right bounds, then push back in screen.
162 corner += size - referenceSize + mMinIndent + mMaxIndent;
164 if(mFlipVertical && corner.y > 0.0f)
167 newPosition.y -= size.height + alternativeOffset.height;
173 Vector3 mMinIndent; ///< Top-Left Margin
174 Vector3 mMaxIndent; ///< Bottom-Right Margin.
175 bool mFlipHorizontal; ///< Whether to flip actor's position if exceeds horizontal screen bounds
176 bool mFlipVertical; ///< Whether to flip actor's position if exceeds vertical screen bounds
177 Rect<float> mBoundingRect; ///< Bounding Rect Popup must stay within
180 } // unnamed namespace
191 const char* const TextInputPopup::SIGNAL_PRESSED = "pressed";
192 const char* const TextInputPopup::SIGNAL_HIDE_FINISHED = "hide-finished";
193 const char* const TextInputPopup::SIGNAL_SHOW_FINISHED = "show-finished";
195 const char* const TextInputPopup::OPTION_SELECT_WORD = "option-select_word"; // "Select Word" popup option.
196 const char* const TextInputPopup::OPTION_SELECT_ALL("option-select_all"); // "Select All" popup option.
197 const char* const TextInputPopup::OPTION_CUT("option-cut"); // "Cut" popup option.
198 const char* const TextInputPopup::OPTION_COPY("option-copy"); // "Copy" popup option.
199 const char* const TextInputPopup::OPTION_PASTE("option-paste"); // "Paste" popup option.
200 const char* const TextInputPopup::OPTION_CLIPBOARD("option-clipboard"); // "Clipboard" popup option.
202 TextInputPopup::TextInputPopup()
203 : mState(StateHidden),
204 mRootActor(Layer::New()),
205 mContentSize( Vector3::ZERO ),
206 mCutPasteButtonsColor( DEFAULT_POPUP_BACKGROUND ),
207 mCutPasteButtonsPressedColor( DEFAULT_POPUP_BUTTON_PRESSED ),
208 mBorderColor( DEFAULT_BORDER_COLOR ),
209 mSelectOptionPriority(1),
210 mSelectAllOptionPriority(2),
211 mCutOptionPriority(3),
212 mCopyOptionPriority(4),
213 mPasteOptionPriority(5),
214 mClipboardOptionPriority(6),
216 mHideFinishedSignal(),
217 mShowFinishedSignal()
219 mAlternativeOffsetProperty = mRootActor.RegisterProperty( POPUP_ALTERNATIVE_OFFSET, Vector2::ZERO );
220 mRootActor.SetParentOrigin( ParentOrigin::CENTER );
221 mRootActor.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
222 // constrain popup to size of parent.
225 Actor TextInputPopup::Self()
230 void TextInputPopup::AddToStage()
232 // TODO: Confinement constraint borders should be defined by the application.
233 // It should also not use the stage directly, instead it should add to parent container.
234 Stage::GetCurrent().Add(mRootActor);
236 ApplyConfinementConstraint();
239 void TextInputPopup::ApplyConfinementConstraint()
241 mRootActor.RemoveConstraints();
242 Constraint constraint = Constraint::New<Vector3>( Actor::POSITION,
243 LocalSource( Actor::SIZE ),
244 LocalSource( Actor::PARENT_ORIGIN ),
245 LocalSource( Actor::ANCHOR_POINT ),
246 ParentSource( Actor::SIZE ),
247 LocalSource( mAlternativeOffsetProperty ),
248 ConfinementConstraint( DEFAULT_POPUP_INDICATOR_OFFSET,
251 true, mBoundingRect ) );
252 mRootActor.ApplyConstraint(constraint);
255 void TextInputPopup::CreateLayer( const Vector2& size )
257 mLayer = Layer::New();
258 mLayer.SetParentOrigin(ParentOrigin::CENTER);
259 mLayer.SetAnchorPoint(AnchorPoint::CENTER);
260 mLayer.SetSize( size ); // matches stencil size
261 mLayer.SetName("popup-mLayer");
264 void TextInputPopup::CreateStencil( const Vector2& size )
266 mStencil = CreateSolidColorActor( Color::BLUE );
267 mStencil.SetParentOrigin( Vector3( ParentOrigin::CENTER ) );
268 mStencil.SetAnchorPoint( AnchorPoint::CENTER );
269 mStencil.SetDrawMode( DrawMode::STENCIL );
270 mStencil.SetSize( size ); // slightly smaller than layer and stencil so over shoot always inside.
271 mStencil.SetVisible( true );
272 mStencil.SetName("popup-stencil");
275 void TextInputPopup::OnScrollStarted( const Vector3& position )
277 mBackground.SetSensitive( false );
280 void TextInputPopup::OnScrollCompleted( const Vector3& position )
282 mBackground.SetSensitive( true );
285 void TextInputPopup::CreateScrollView( const Vector2& domainSize, const Vector2& visibleSize )
287 mScrollView = Toolkit::ScrollView::New();
288 mScrollView.SetName("popup-scroll-view");
289 mScrollView.SetAnchorPoint( AnchorPoint::TOP_LEFT );
290 mScrollView.SetParentOrigin( ParentOrigin::TOP_LEFT );
291 mScrollView.SetSize( visibleSize.x, visibleSize.y );
292 mScrollView.SetScrollingDirection( PanGestureDetector::DIRECTION_HORIZONTAL, Degree( 40.0f ) );
293 mScrollView.SetAxisAutoLock( true );
294 mScrollView.ScrollStartedSignal().Connect( this, &TextInputPopup::OnScrollStarted );
295 mScrollView.ScrollCompletedSignal().Connect( this, &TextInputPopup::OnScrollCompleted );
297 RulerPtr rulerX = new DefaultRuler(); // IntrusivePtr which is unreferenced when ScrollView is destroyed.
298 RulerPtr rulerY = new DefaultRuler(); // IntrusivePtr which is unreferenced when ScrollView is destroyed.
300 rulerX->SetDomain( RulerDomain( 0, domainSize.width, true ) );
301 mScrollView.SetRulerX(rulerX);
302 mScrollView.SetRulerY(rulerY);
305 void TextInputPopup::RemoveFromStage()
307 Actor rootActor = Self();
308 Stage::GetCurrent().Remove( rootActor );
311 void TextInputPopup::Clear()
315 UnparentAndReset( mStencil );
316 UnparentAndReset( mBackground );
317 UnparentAndReset( mScrollView );
318 UnparentAndReset( mLayer );
319 mButtonContainer.clear();
320 mDividerContainer.clear();
323 mRootActor.RemoveConstraints();
325 mState = StateHidden;
329 Toolkit::TextView TextInputPopup::CreateOptionText( const MarkupProcessor::StyledTextArray& styledCaption )
331 Toolkit::TextView label = Toolkit::TextView::New( styledCaption );
332 label.SetSizePolicy( Toolkit::Control::Fixed, Toolkit::Control::Fixed );
333 label.SetWidthExceedPolicy( Toolkit::TextView::Fade );
334 label.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
335 label.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
336 label.SetPosition( 0.0f, TEXT_POSITION_OFFSET );
341 ImageActor TextInputPopup::CreateOptionIcon( Image iconImage )
343 ImageActor icon = ImageActor::New( iconImage );
345 icon.SetSize( DEFAULT_ICON_SIZE );
346 icon.SetParentOrigin( ParentOrigin::TOP_CENTER );
347 icon.SetAnchorPoint( AnchorPoint::TOP_CENTER );
348 icon.SetPosition( 0.0f, ICON_POSITION_OFFSET );
353 void TextInputPopup::CreatePopUpBackground()
355 // Create background-panel if not already created (required if we have at least one option)
358 mBackground = Toolkit::CreateSolidColorActor( GetCutPastePopUpColor(), true, mBorderColor );
359 mBackground.SetAnchorPoint( AnchorPoint::TOP_LEFT );
360 mBackground.SetParentOrigin( ParentOrigin::TOP_LEFT );
361 mBackground.SetName("pop-up-background");
362 mContentSize = POPUP_TEXT_OFFSET;
367 Image tailImage = Image::New( DEFAULT_POPUP_TAIL_BOTTOM );
369 mTail = ImageActor::New( tailImage );
370 mTail.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
371 mTail.SetAnchorPoint( AnchorPoint::TOP_CENTER );
372 mBackground.Add( mTail );
373 // TODO: Make tail visible, and positioned in relation to original intended position of popup (i.e. before constrained effects)
374 mTail.SetVisible(false);
378 void TextInputPopup::CreateDivider()
380 if(mButtonContainer.size() > 0)
382 ImageActor divider = Toolkit::CreateSolidColorActor( mBorderColor );
383 divider.SetParentOrigin( ParentOrigin::TOP_LEFT );
384 divider.SetAnchorPoint( AnchorPoint::TOP_LEFT );
385 divider.SetPosition( Vector3( mContentSize.width, POPUP_TEXT_OFFSET.y, 0.0f ) );
386 // Keep track of all the dividers. As their height's need to be updated to the max. of all
387 // buttons currently added.
388 mDividerContainer.push_back(divider);
389 mBackground.Add( divider );
390 mContentSize.width += DIVIDER_WIDTH;
394 ImageActor TextInputPopup::CreatePressedBackground( const Vector3 requiredSize )
396 std::string pressedImageFilename;
397 Vector4 pressedImageBorder;
398 Vector2 pressedImageSize;
400 ImageActor pressedButtonBg = Toolkit::CreateSolidColorActor( GetCutPastePopUpPressedColor() );
402 pressedButtonBg.SetSize ( requiredSize );
403 pressedButtonBg.SetParentOrigin( ParentOrigin::CENTER );
404 pressedButtonBg.SetAnchorPoint( AnchorPoint::CENTER );
406 return pressedButtonBg;
409 TextInputPopup::ButtonRequirement TextInputPopup::CreateRequiredButton( TextInputPopup::Buttons buttonId, std::size_t orderOfPriority,
410 const std::string& name, const std::string& caption, Image iconImage, bool enabled )
412 TextInputPopup::ButtonRequirement currentButton;
414 currentButton.buttonId = buttonId;
415 currentButton.orderOfPriority = orderOfPriority;
416 currentButton.name = name;
417 currentButton.caption = caption;
418 currentButton.iconImage = iconImage;
419 currentButton.enabled = enabled;
421 return currentButton;
424 void TextInputPopup::CreateOrderedListOfOptions()
426 mOrderListOfButtons.clear();
428 for ( std::size_t index= 0; index < ButtonsEnumEnd; index++ )
430 TextInputPopup::ButtonRequirement currentButton;
432 // Create button for each possible option using Option priority
437 Image cutIcon = Image::New( DEFAULT_ICON_CUT );
438 currentButton = CreateRequiredButton( ButtonsCut, mCutOptionPriority, OPTION_CUT, GET_LOCALE_TEXT("IDS_COM_BODY_CUT"), cutIcon, false );
443 Image copyIcon = Image::New( DEFAULT_ICON_COPY );
444 currentButton = CreateRequiredButton( ButtonsCopy, mCopyOptionPriority, OPTION_COPY, GET_LOCALE_TEXT("IDS_COM_BODY_COPY"), copyIcon, false );
449 Image pasteIcon = Image::New( DEFAULT_ICON_PASTE );
450 currentButton = CreateRequiredButton( ButtonsPaste, mPasteOptionPriority, OPTION_PASTE, GET_LOCALE_TEXT("IDS_COM_BODY_PASTE"), pasteIcon, false );
455 Image selectIcon = Image::New( DEFAULT_ICON_SELECT );
456 currentButton = CreateRequiredButton( ButtonsSelect, mSelectOptionPriority, OPTION_SELECT_WORD, GET_LOCALE_TEXT("IDS_COM_SK_SELECT"), selectIcon, false );
459 case ButtonsSelectAll:
461 Image selectAllIcon = Image::New( DEFAULT_ICON_SELECT_ALL );
462 currentButton = CreateRequiredButton( ButtonsSelectAll, mSelectAllOptionPriority, OPTION_SELECT_ALL, GET_LOCALE_TEXT("IDS_COM_BODY_SELECT_ALL"), selectAllIcon, false );
465 case ButtonsClipboard:
467 Image clipboardIcon = Image::New( DEFAULT_ICON_CLIPBOARD );
468 currentButton = CreateRequiredButton( ButtonsClipboard, mClipboardOptionPriority, OPTION_CLIPBOARD, GET_LOCALE_TEXT("IDS_COM_BODY_CLIPBOARD"), clipboardIcon, false );
473 DALI_ASSERT_DEBUG( "ButtonsEnumEnd used but an invalid choice");
474 currentButton.orderOfPriority = 0;
481 // Insert button in list of buttons in order of priority setting.
482 for( std::vector<ButtonRequirement>::iterator it = mOrderListOfButtons.begin(), endIt = mOrderListOfButtons.end(); ( it != endIt && !match ); ++it )
484 const ButtonRequirement& button( *it );
485 if ( currentButton.orderOfPriority < button.orderOfPriority )
487 if ( currentButton.orderOfPriority != 0 ) // If order priority 0 then do not add button as not required.
489 mOrderListOfButtons.insert( it, currentButton );
497 mOrderListOfButtons.push_back( currentButton );
502 void TextInputPopup::AddOption(const std::string& name, const std::string& caption, const Image iconImage, bool finalOption)
504 CreatePopUpBackground();
508 // Create a Button with Text, Icon and highlight when pressed
510 Toolkit::PushButton button = Toolkit::PushButton::New();
511 button.SetSizePolicy( Toolkit::Control::Fixed, Toolkit::Control::Fixed );
512 button.SetName( name );
514 // Create container for text and icon when not pressed
515 Actor iconTextContainer = Actor::New();
516 iconTextContainer.SetParentOrigin( ParentOrigin::TOP_LEFT );
517 iconTextContainer.SetAnchorPoint( AnchorPoint::TOP_LEFT );
521 style.SetFontPointSize( PointSize( DEFAULT_UI_FONT_SIZE ) );
522 MarkupProcessor::StyledTextArray styledCaption;
523 styledCaption.push_back( MarkupProcessor::StyledText( Text( caption ), style ) );
524 Toolkit::TextView label = CreateOptionText( styledCaption );
525 label.SetName( name );
527 iconTextContainer.Add( label );
529 // Get natural size of text and then constrain it to bounds.
530 const Vector3 textSize = label.GetNaturalSize();
531 const Vector3 constrainedTextSize = Min( textSize, TEXT_LABEL_MAX_SIZE );
532 Vector3 buttonSize( Max(constrainedTextSize + BUTTON_TEXT_ENLARGE, BUTTON_TEXT_MINIMUM_SIZE) );
533 buttonSize = ( Min(buttonSize, BUTTON_TEXT_MAXIMUM_SIZE) );
534 label.SetSize( Min( buttonSize, constrainedTextSize ) );
536 button.SetParentOrigin( ParentOrigin::TOP_LEFT );
537 button.SetAnchorPoint( AnchorPoint::TOP_LEFT );
538 button.SetSize( buttonSize );
539 button.SetPosition( Vector3( mContentSize.width, POPUP_BORDER.y, 0.0f ) );
542 ImageActor icon = CreateOptionIcon( iconImage );
544 iconTextContainer.Add( icon );
546 // 3. Add highlight - Pressed state in Pushbutton needs a new image which means creating the text and icon again but including a highlight this time.
547 ImageActor pressedImageBg = CreatePressedBackground( buttonSize );
549 Actor iconPressedTextContainer = Actor::New();
550 iconPressedTextContainer.SetDrawMode( DrawMode::OVERLAY );
552 Toolkit::TextView pressedLabel = CreateOptionText( styledCaption );
553 pressedLabel.SetSize( Min( buttonSize, TEXT_LABEL_MAX_SIZE ) );
554 ImageActor pressedIcon = CreateOptionIcon( iconImage );
556 iconPressedTextContainer.Add( pressedImageBg );
557 iconPressedTextContainer.Add( pressedLabel );
558 iconPressedTextContainer.Add( pressedIcon );
560 // Set Pressed button Image
561 iconPressedTextContainer.SetSize( buttonSize );
562 button.SetPressedImage( iconPressedTextContainer );
564 // Set Normal button Image
565 iconTextContainer.SetSize( buttonSize );
566 button.SetButtonImage( iconTextContainer );
567 mBackground.Add( button );
569 // Update content size (represents size of all content i.e. from top-left of first button, to bottom-right of last button)
570 mContentSize.width += buttonSize.width;
571 mContentSize.height = std::max(mContentSize.height + ( POPUP_BORDER.y ), buttonSize.height);
572 mButtonContainer.push_back(button);
574 // resize all dividers based on the height content (i.e. max of all button heights)
575 const float dividerHeight = mContentSize.height - DIVIDER_MARGIN;
576 for(ActorIter i = mDividerContainer.begin(); i != mDividerContainer.end(); ++i)
578 i->SetSize( DIVIDER_WIDTH, dividerHeight );
581 mTail.SetPosition(Vector3(0.0f, -20.0f, 0.0f));
583 button.ClickedSignal().Connect( this, &TextInputPopup::OnButtonPressed );
586 void TextInputPopup::Hide(bool animate)
598 mAnimation = Animation::New( HIDE_POPUP_ANIMATION_DURATION );
599 mAnimation.AnimateTo( Property(mBackground, Actor::SCALE), Vector3::ZERO, AlphaFunctions::EaseOut );
600 mAnimation.AnimateTo( Property(mBackground, Actor::COLOR_ALPHA), 0.0f, AlphaFunctions::EaseOut );
603 mAnimation.FinishedSignal().Connect( this, &TextInputPopup::OnHideFinished );
604 mState = StateHiding;
608 mBackground.SetProperty(Actor::SCALE, Vector3::ZERO);
609 mBackground.SetProperty(Actor::COLOR_ALPHA, 0.0f);
610 mState = StateHidden;
615 void TextInputPopup::Show(bool animate)
619 mBackground.SetSensitive( true );
629 mAnimation = Animation::New( SHOW_POPUP_ANIMATION_DURATION );
630 mAnimation.AnimateTo( Property(mBackground, Actor::SCALE), Vector3::ONE, AlphaFunctions::EaseOut );
631 mAnimation.AnimateTo( Property(mBackground, Actor::COLOR_ALPHA), 1.0f, AlphaFunctions::EaseOut );
634 mAnimation.FinishedSignal().Connect( this, &TextInputPopup::OnShowFinished );
635 mState = StateShowing;
639 mBackground.SetProperty(Actor::SCALE, Vector3::ONE);
640 mBackground.SetProperty(Actor::COLOR_ALPHA, 1.0f);
646 void TextInputPopup::SetAlternativeOffset(Vector2 offset)
648 mRootActor.SetProperty( mAlternativeOffsetProperty, offset );
649 ApplyConfinementConstraint();
652 TextInputPopup::State TextInputPopup::GetState(void) const
657 Actor TextInputPopup::GetRootActor() const
664 void TextInputPopup::SetCutPastePopUpColor( const Vector4& color )
666 mCutPasteButtonsColor = color;
669 const Vector4& TextInputPopup::GetCutPastePopUpColor() const
671 return mCutPasteButtonsColor;
674 void TextInputPopup::SetCutPastePopUpPressedColor( const Vector4& color )
676 mCutPasteButtonsPressedColor = color;
679 const Vector4& TextInputPopup::GetCutPastePopUpPressedColor() const
681 return mCutPasteButtonsPressedColor;
684 void TextInputPopup::TogglePopUpButtonOnOff( TextInputPopup::Buttons requiredButton, bool enable )
686 bool match ( false );
687 for( std::vector<ButtonRequirement>::iterator it = mOrderListOfButtons.begin(), endIt = mOrderListOfButtons.end(); ( it != endIt && !match ); ++it )
689 ButtonRequirement& button( *it );
690 if ( requiredButton == button.buttonId )
692 button.enabled = enable;
698 void TextInputPopup::SetButtonPriorityPosition( TextInputPopup::Buttons button, unsigned int priority )
704 mCutOptionPriority = priority;
709 mCopyOptionPriority = priority;
714 mPasteOptionPriority = priority;
719 mSelectOptionPriority = priority;
722 case ButtonsSelectAll:
724 mSelectAllOptionPriority = priority;
727 case ButtonsClipboard:
729 mClipboardOptionPriority = priority;
734 DALI_ASSERT_DEBUG( "ButtonsEnumEnd used but an invalid choice");
738 CreateOrderedListOfOptions(); // Update list of options as priority changed.
741 unsigned int TextInputPopup::GetButtonPriorityPosition( TextInputPopup::Buttons button ) const
743 unsigned int priority = 0;
749 priority = mCutOptionPriority;
754 priority = mCopyOptionPriority;
759 priority = mPasteOptionPriority;
764 priority = mSelectOptionPriority;
767 case ButtonsSelectAll:
769 priority = mSelectAllOptionPriority;
772 case ButtonsClipboard:
774 priority = mClipboardOptionPriority;
779 DALI_ASSERT_DEBUG( "ButtonsEnumEnd used but an invalid choice");
787 void TextInputPopup::AddPopupOptions()
789 for( std::vector<ButtonRequirement>::const_iterator it = mOrderListOfButtons.begin(), endIt = mOrderListOfButtons.end(); ( it != endIt ); ++it )
791 const ButtonRequirement& button( *it );
792 if ( button.enabled )
794 AddOption( button.name, button.caption, button.iconImage, false );
798 float visiblePopUpWidth = std::min( mContentSize.width - POP_UP_SCREEN_EDGE_MARGIN*2 , mBoundingRect.width - POP_UP_SCREEN_EDGE_MARGIN *2);
799 float visbilePopUpHeight = std::max( mContentSize.height, POPUP_MINIMUM_SIZE.height );
800 Vector2 visiblePopUpSize = Vector2( visiblePopUpWidth, visbilePopUpHeight );
802 visiblePopUpWidth = std::max( visiblePopUpWidth, POPUP_MINIMUM_SIZE.width );
804 mBackground.SetSize( mContentSize.width, mContentSize.height );
805 mRootActor.SetSize( visiblePopUpWidth, visbilePopUpHeight ); // Make Root Actor reflect the size of its content
807 CreateLayer( visiblePopUpSize );
808 CreateStencil( visiblePopUpSize );
809 CreateScrollView( Vector2( mContentSize.width, mContentSize.height ), visiblePopUpSize );
811 mLayer.Add( mStencil );
812 mLayer.Add( mScrollView );
813 mScrollView.Add( mBackground );
818 void TextInputPopup::SetPopupBoundary( const Rect<float>& boundingRectangle )
820 mBoundingRect = boundingRectangle;
823 bool TextInputPopup::OnButtonPressed( Toolkit::Button button )
825 mPressedSignal.Emit( button );
829 void TextInputPopup::OnHideFinished(Animation& source)
831 source.FinishedSignal().Disconnect( this, &TextInputPopup::OnHideFinished );
833 mState = StateHidden;
834 mHideFinishedSignal.Emit( *this );
837 void TextInputPopup::OnShowFinished(Animation& source)
839 source.FinishedSignal().Disconnect( this, &TextInputPopup::OnShowFinished );
841 mShowFinishedSignal.Emit( *this );
844 TextInputPopup::PressedSignalV2& TextInputPopup::PressedSignal()
846 return mPressedSignal;
849 TextInputPopup::HideFinishedSignalV2& TextInputPopup::HideFinishedSignal()
851 return mHideFinishedSignal;
854 TextInputPopup::ShowFinishedSignalV2& TextInputPopup::ShowFinishedSignal()
856 return mShowFinishedSignal;
859 } // namespace Internal
861 } // namespace Toolkit