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 Vector4 DEFAULT_POPUP_ICON( Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) );
38 const Vector4 DEFAULT_POPUP_ICON_PRESSED( Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) );
39 const Vector4 DEFAULT_POPUP_TEXT( Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) );
40 const Vector4 DEFAULT_POPUP_TEXT_PRESSED( Vector4( 1.0f, 1.0f, 1.0f, 1.0f ) );
41 const Vector3 POPUP_BORDER( Vector3( 1.0f, 1.0f, 0.0f ) );
43 /* Functionality in place to have the end buttons using different images to inner button.
44 * Supply a centre image and then a left and right image, the centre image can have straight ends while
45 * 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.
49 const char* DEFAULT_POPUP_TAIL_BOTTOM( DALI_IMAGE_DIR "popup_bubble_tail_bottom.png" );
50 const char* DEFAULT_POPUP_TAIL_BOTTOM_OUTLINE( DALI_IMAGE_DIR "popup_bubble_tail_bottom_line.png" );
51 const float TAIL_Y_POSITION( -1.5f );
53 // Popup: Vertical Constraint
54 // TODO: Remove - this should come from application - it is not possible to get the
55 // height of the indicator actor from Dali-Toolkit.
57 const float POP_UP_SCREEN_EDGE_MARGIN( 4.0f );
58 const Vector2 DEFAULT_POPUP_INDICATOR_OFFSET(POP_UP_SCREEN_EDGE_MARGIN, 60.0f);
60 const Vector3 POPUP_TEXT_OFFSET( 0.0f, 0.0f, 0.0f );
61 const Vector3 POPUP_TEXT_ENLARGE( 12.0f, 28.0f, 0.0f );
62 const Vector3 POPUP_MINIMUM_SIZE( 128.0f, 124.0f, 0.0f );
64 const Vector3 BUTTON_TEXT_ENLARGE( 32.0f, 0.0f, 0.0f );
65 const Vector3 BUTTON_TEXT_MINIMUM_SIZE( 128.0f, 126.0f, 0.0f );
66 const Vector3 BUTTON_TEXT_MAXIMUM_SIZE( 190.0f, 126.0f, 0.0f );
67 const Vector3 TEXT_LABEL_MAX_SIZE( 160.0f, 30.0f, 0.0f );
69 const float DIVIDER_WIDTH(2.0f); ///< Width of each button divider
70 const float DIVIDER_MARGIN(0.0f); ///< Top/Bottom Margin between divider and edge of popup.
72 const float DEFAULT_UI_FONT_SIZE(7.0f); ///< Standard font size for Text-Input's UI
74 const float HIDE_POPUP_ANIMATION_DURATION(0.2f); ///< Duration of popup hide animation in seconds.
75 const float SHOW_POPUP_ANIMATION_DURATION(0.2f); ///< Duration of popup show animation in seconds.
77 const Vector2 DEFAULT_ICON_SIZE( 45.0f, 45.0f ); ///< Default icon size for image in options
78 const float TEXT_POSITION_OFFSET( -19.0f ); ///< Default offset for text label
79 const float ICON_POSITION_OFFSET( 19.0f ); ///< Default offset for icon
81 const char* DEFAULT_ICON_CLIPBOARD( DALI_IMAGE_DIR "copy_paste_icon_clipboard.png" );
82 const char* DEFAULT_ICON_COPY( DALI_IMAGE_DIR "copy_paste_icon_copy.png" );
83 const char* DEFAULT_ICON_CUT( DALI_IMAGE_DIR "copy_paste_icon_cut.png" );
84 const char* DEFAULT_ICON_PASTE( DALI_IMAGE_DIR "copy_paste_icon_paste.png" );
85 const char* DEFAULT_ICON_SELECT( DALI_IMAGE_DIR "copy_paste_icon_select.png" );
86 const char* DEFAULT_ICON_SELECT_ALL( DALI_IMAGE_DIR "copy_paste_icon_select_all.png" );
88 // TODO: This should be based on the content for example:
89 // 1. For selection: should be above top of highlighted selection, or below bottom of highlighted selection + end handle.
90 // 2. For cursor: should be above top of cursor, or below bottom of cursor + grab handle.
91 const std::string POPUP_ALTERNATIVE_OFFSET("popup-alternative-offset"); ///< Alternative offset property for confinenment constraint.
95 * Confine Actor to boundaries of reference actor (e.g. Parent)
96 * Actor bounds (top-left position + size) are confined to reference Actor's
99 struct ConfinementConstraint
102 * Confinement constraint constructor.
103 * @param[in] topLeftMargin (optional) Top-Left margins (defaults to 0.0f, 0.0f)
104 * @param[in] bottomRightMargin (optional) Bottom-Right margins (defaults to 0.0f, 0.0f)
105 * @paran[in[ flipHorizontal (optional) whether to flip Actor to other side if near edge
106 * @param[in] flipVertical (optional) whether to flip Actor to the other side if near edge
107 * @param[in] boundingRect Rectangle to bound Popup to.
110 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) )
111 : mMinIndent(topLeftMargin),
112 mMaxIndent(bottomRightMargin),
113 mFlipHorizontal(flipHorizontal),
114 mFlipVertical(flipVertical),
115 mBoundingRect( boundingRect )
119 Vector3 operator()(const Vector3& constPosition,
120 const PropertyInput& sizeProperty,
121 const PropertyInput& parentOriginProperty,
122 const PropertyInput& anchorPointProperty,
123 const PropertyInput& referenceSizeProperty,
124 const PropertyInput& alternativeOffsetProperty)
126 const Vector3& size = sizeProperty.GetVector3();
127 const Vector3& origin = parentOriginProperty.GetVector3();
128 const Vector3& anchor = anchorPointProperty.GetVector3();
129 const Vector3& referenceSize = referenceSizeProperty.GetVector3();
130 const Vector2& alternativeOffset = alternativeOffsetProperty.GetVector2();
132 Vector3 newPosition(constPosition);
134 // Get actual position of Actor relative to parent's Top-Left.
135 Vector3 position(constPosition + origin * referenceSize);
137 // if top-left corner is outside of Top-Left bounds, then push back in screen.
139 Vector3 corner(position - size * anchor - mMinIndent);
141 newPosition.x -= std::max(corner.x, 0.0f);
143 if ( mFlipHorizontal )
145 if( corner.x < mBoundingRect.x + POP_UP_SCREEN_EDGE_MARGIN )
147 // Snap PopUp to left hand boundary so stays visible
148 corner.x = mBoundingRect.x + POP_UP_SCREEN_EDGE_MARGIN ;
150 else if ( ( corner.x + size.x ) > ( ( mBoundingRect.x + mBoundingRect.width ) - POP_UP_SCREEN_EDGE_MARGIN ))
152 // Calculate offset from left boundary PopUp must be placed at so it does not exceed right side boundary.
153 float requiredOffSetFromLeftBoundaryToFit = mBoundingRect.width - POP_UP_SCREEN_EDGE_MARGIN - size.x;
154 corner.x = mBoundingRect.x + requiredOffSetFromLeftBoundaryToFit - ( origin.x * referenceSize.x ) + ( size.x * anchor.x );
156 newPosition.x = corner.x;
159 if(mFlipVertical && corner.y < 0.0f)
162 newPosition.y += size.height + alternativeOffset.height;
165 newPosition.y -= std::min(corner.y, 0.0f);
167 // if bottom-right corner is outside of Bottom-Right bounds, then push back in screen.
168 corner += size - referenceSize + mMinIndent + mMaxIndent;
170 if(mFlipVertical && corner.y > 0.0f)
173 newPosition.y -= size.height + alternativeOffset.height;
179 Vector3 mMinIndent; ///< Top-Left Margin
180 Vector3 mMaxIndent; ///< Bottom-Right Margin.
181 bool mFlipHorizontal; ///< Whether to flip actor's position if exceeds horizontal screen bounds
182 bool mFlipVertical; ///< Whether to flip actor's position if exceeds vertical screen bounds
183 Rect<float> mBoundingRect; ///< Bounding Rect Popup must stay within
187 * Confine actor to the x axis boundaries of reference actor (e.g. Parent)
189 struct ParentXAxisConstraint
192 * Confinement constraint constructor.
194 ParentXAxisConstraint( float handlesMidPoint = 0.0f )
195 : mHandlesMidPoint( handlesMidPoint )
199 float operator()( const float constXPosition,
200 const PropertyInput& localWidthProperty,
201 const PropertyInput& anchorPointXProperty )
203 const float size = localWidthProperty.GetFloat();
204 const float anchor = anchorPointXProperty.GetFloat();
206 float newPosition = Clamp( mHandlesMidPoint, constXPosition - size * anchor , constXPosition + size * anchor);
211 float mHandlesMidPoint;
215 } // unnamed namespace
226 const char* const TextInputPopup::SIGNAL_PRESSED = "pressed";
227 const char* const TextInputPopup::SIGNAL_HIDE_FINISHED = "hide-finished";
228 const char* const TextInputPopup::SIGNAL_SHOW_FINISHED = "show-finished";
230 const char* const TextInputPopup::OPTION_SELECT_WORD = "option-select_word"; // "Select Word" popup option.
231 const char* const TextInputPopup::OPTION_SELECT_ALL("option-select_all"); // "Select All" popup option.
232 const char* const TextInputPopup::OPTION_CUT("option-cut"); // "Cut" popup option.
233 const char* const TextInputPopup::OPTION_COPY("option-copy"); // "Copy" popup option.
234 const char* const TextInputPopup::OPTION_PASTE("option-paste"); // "Paste" popup option.
235 const char* const TextInputPopup::OPTION_CLIPBOARD("option-clipboard"); // "Clipboard" popup option.
237 TextInputPopup::TextInputPopup()
238 : mState(StateHidden),
239 mRootActor(Layer::New()),
240 mPopupTailXPosition( 0.0f ),
241 mContentSize( Vector3::ZERO ),
242 mCutPasteButtonsColor( DEFAULT_POPUP_BACKGROUND ),
243 mCutPasteButtonsPressedColor( DEFAULT_POPUP_BUTTON_PRESSED ),
244 mBorderColor( DEFAULT_BORDER_COLOR ),
245 mCutPasteIconsColor( DEFAULT_POPUP_ICON ),
246 mCutPasteIconsPressedColor( DEFAULT_POPUP_ICON_PRESSED ),
247 mCutPasteTextsColor( DEFAULT_POPUP_TEXT ),
248 mCutPasteTextsPressedColor( DEFAULT_POPUP_TEXT_PRESSED ),
249 mSelectOptionPriority(1),
250 mSelectAllOptionPriority(2),
251 mCutOptionPriority(3),
252 mCopyOptionPriority(4),
253 mPasteOptionPriority(5),
254 mClipboardOptionPriority(6),
256 mHideFinishedSignal(),
257 mShowFinishedSignal()
259 mAlternativeOffsetProperty = mRootActor.RegisterProperty( POPUP_ALTERNATIVE_OFFSET, Vector2::ZERO );
260 mRootActor.SetParentOrigin( ParentOrigin::CENTER );
261 mRootActor.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
262 // constrain popup to size of parent.
265 Actor TextInputPopup::Self()
270 void TextInputPopup::AddToStage()
272 // TODO: Confinement constraint borders should be defined by the application.
273 // It should also not use the stage directly, instead it should add to parent container.
274 Stage::GetCurrent().Add(mRootActor);
276 ApplyConfinementConstraint();
279 void TextInputPopup::ApplyConfinementConstraint()
281 mRootActor.RemoveConstraints();
282 Constraint constraint = Constraint::New<Vector3>( Actor::POSITION,
283 LocalSource( Actor::SIZE ),
284 LocalSource( Actor::PARENT_ORIGIN ),
285 LocalSource( Actor::ANCHOR_POINT ),
286 ParentSource( Actor::SIZE ),
287 LocalSource( mAlternativeOffsetProperty ),
288 ConfinementConstraint( DEFAULT_POPUP_INDICATOR_OFFSET,
291 true, mBoundingRect ) );
292 mRootActor.ApplyConstraint(constraint);
295 void TextInputPopup::ApplyTailConstraint()
297 mTail.RemoveConstraints();
298 Constraint constraint = Constraint::New<float>( Actor::POSITION_X,
299 LocalSource( Actor::SIZE_WIDTH ),
300 LocalSource( Actor::ANCHOR_POINT_X ),
301 ParentXAxisConstraint());
304 void TextInputPopup::CreateLayer( const Vector2& size )
306 mLayer = Layer::New();
307 mLayer.SetParentOrigin(ParentOrigin::CENTER);
308 mLayer.SetAnchorPoint(AnchorPoint::CENTER);
309 mLayer.SetSize( size ); // matches stencil size
310 mLayer.SetName("popup-mLayer");
313 void TextInputPopup::CreateStencil( const Vector2& size )
315 mStencil = CreateSolidColorActor( Color::BLUE );
316 mStencil.SetParentOrigin( Vector3( ParentOrigin::CENTER ) );
317 mStencil.SetAnchorPoint( AnchorPoint::CENTER );
318 mStencil.SetDrawMode( DrawMode::STENCIL );
319 mStencil.SetSize( size ); // slightly smaller than layer and stencil so over shoot always inside.
320 mStencil.SetVisible( true );
321 mStencil.SetName("popup-stencil");
324 void TextInputPopup::OnScrollStarted( const Vector3& position )
326 mBackground.SetSensitive( false );
329 void TextInputPopup::OnScrollCompleted( const Vector3& position )
331 mBackground.SetSensitive( true );
334 void TextInputPopup::CreateScrollView( const Vector2& domainSize, const Vector2& visibleSize )
336 mScrollView = Toolkit::ScrollView::New();
337 mScrollView.SetName("popup-scroll-view");
338 mScrollView.SetAnchorPoint( AnchorPoint::TOP_LEFT );
339 mScrollView.SetParentOrigin( ParentOrigin::TOP_LEFT );
340 mScrollView.SetSize( visibleSize.x, visibleSize.y );
341 mScrollView.SetScrollingDirection( PanGestureDetector::DIRECTION_HORIZONTAL, Degree( 40.0f ) );
342 mScrollView.SetAxisAutoLock( true );
343 mScrollView.ScrollStartedSignal().Connect( this, &TextInputPopup::OnScrollStarted );
344 mScrollView.ScrollCompletedSignal().Connect( this, &TextInputPopup::OnScrollCompleted );
346 RulerPtr rulerX = new DefaultRuler(); // IntrusivePtr which is unreferenced when ScrollView is destroyed.
347 RulerPtr rulerY = new DefaultRuler(); // IntrusivePtr which is unreferenced when ScrollView is destroyed.
349 rulerX->SetDomain( RulerDomain( 0, domainSize.width, true ) );
350 mScrollView.SetRulerX(rulerX);
351 mScrollView.SetRulerY(rulerY);
354 void TextInputPopup::RemoveFromStage()
356 Actor rootActor = Self();
357 Stage::GetCurrent().Remove( rootActor );
360 void TextInputPopup::Clear()
364 UnparentAndReset( mTail );
365 UnparentAndReset( mStencil );
366 UnparentAndReset( mBackground );
367 UnparentAndReset( mScrollView );
368 UnparentAndReset( mLayer );
369 mButtonContainer.clear();
370 mDividerContainer.clear();
373 mRootActor.RemoveConstraints();
375 mState = StateHidden;
379 Toolkit::TextView TextInputPopup::CreateOptionText( const MarkupProcessor::StyledTextArray& styledCaption )
381 Toolkit::TextView label = Toolkit::TextView::New( styledCaption );
382 label.SetSizePolicy( Toolkit::Control::Fixed, Toolkit::Control::Fixed );
383 label.SetWidthExceedPolicy( Toolkit::TextView::Fade );
384 label.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
385 label.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
386 label.SetPosition( 0.0f, TEXT_POSITION_OFFSET );
391 ImageActor TextInputPopup::CreateOptionIcon( Image iconImage, const Vector4& color )
393 ImageActor icon = ImageActor::New( iconImage );
395 icon.SetSize( DEFAULT_ICON_SIZE );
396 icon.SetParentOrigin( ParentOrigin::TOP_CENTER );
397 icon.SetAnchorPoint( AnchorPoint::TOP_CENTER );
398 icon.SetPosition( 0.0f, ICON_POSITION_OFFSET );
399 icon.SetColor( color );
404 void TextInputPopup::CreatePopUpBackground()
406 // Create background-panel if not already created (required if we have at least one option)
409 mBackground = Toolkit::CreateSolidColorActor( GetCutPastePopUpColor(), true, mBorderColor );
410 mBackground.SetAnchorPoint( AnchorPoint::TOP_LEFT );
411 mBackground.SetParentOrigin( ParentOrigin::TOP_LEFT );
412 mBackground.SetName("pop-up-background");
413 mContentSize = POPUP_TEXT_OFFSET;
418 Image tailImage = Image::New( DEFAULT_POPUP_TAIL_BOTTOM );
419 Image tailImageOutline = Image::New( DEFAULT_POPUP_TAIL_BOTTOM_OUTLINE );
421 mTailOutline = ImageActor::New ( tailImageOutline );
422 mTailOutline.SetParentOrigin( ParentOrigin::CENTER );
423 mTailOutline.SetAnchorPoint( AnchorPoint::CENTER );
424 mTailOutline.ApplyConstraint( Constraint::New<Vector3>( Actor::SIZE, ParentSource( Actor::SIZE ), EqualToConstraint() ) );
426 mTail = ImageActor::New( tailImage );
427 mTail.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
428 mTail.SetAnchorPoint( AnchorPoint::TOP_CENTER );
429 // TODO: Make tail visible, and positioned in relation to original intended position of popup (i.e. before constrained effects)
430 mTail.SetVisible(true);
431 mTail.SetColor( mCutPasteButtonsColor );
432 mTailOutline.SetColor( mBorderColor );
433 mTail.Add( mTailOutline);
437 void TextInputPopup::CreateDivider()
439 if(mButtonContainer.size() > 0)
441 ImageActor divider = Toolkit::CreateSolidColorActor( mBorderColor );
442 divider.SetParentOrigin( ParentOrigin::TOP_LEFT );
443 divider.SetAnchorPoint( AnchorPoint::TOP_LEFT );
444 divider.SetPosition( Vector3( mContentSize.width, POPUP_TEXT_OFFSET.y, 0.0f ) );
445 divider.SetColor( mBorderColor );
446 // Keep track of all the dividers. As their height's need to be updated to the max. of all
447 // buttons currently added.
448 mDividerContainer.push_back(divider);
449 mBackground.Add( divider );
450 mContentSize.width += DIVIDER_WIDTH;
454 ImageActor TextInputPopup::CreatePressedBackground( const Vector3 requiredSize )
456 std::string pressedImageFilename;
457 Vector4 pressedImageBorder;
458 Vector2 pressedImageSize;
460 ImageActor pressedButtonBg = Toolkit::CreateSolidColorActor( GetCutPastePopUpPressedColor() );
462 pressedButtonBg.SetSize ( requiredSize );
463 pressedButtonBg.SetParentOrigin( ParentOrigin::CENTER );
464 pressedButtonBg.SetAnchorPoint( AnchorPoint::CENTER );
466 return pressedButtonBg;
469 TextInputPopup::ButtonRequirement TextInputPopup::CreateRequiredButton( TextInputPopup::Buttons buttonId, std::size_t orderOfPriority,
470 const std::string& name, const std::string& caption, Image iconImage, bool enabled )
472 TextInputPopup::ButtonRequirement currentButton;
474 currentButton.buttonId = buttonId;
475 currentButton.orderOfPriority = orderOfPriority;
476 currentButton.name = name;
477 currentButton.caption = caption;
478 currentButton.iconImage = iconImage;
479 currentButton.enabled = enabled;
481 return currentButton;
484 void TextInputPopup::CreateOrderedListOfOptions()
486 mOrderListOfButtons.clear();
488 for ( std::size_t index= 0; index < ButtonsEnumEnd; index++ )
490 TextInputPopup::ButtonRequirement currentButton;
492 // Create button for each possible option using Option priority
497 Image cutIcon = Image::New( DEFAULT_ICON_CUT );
498 currentButton = CreateRequiredButton( ButtonsCut, mCutOptionPriority, OPTION_CUT, GET_LOCALE_TEXT("IDS_COM_BODY_CUT"), cutIcon, false );
503 Image copyIcon = Image::New( DEFAULT_ICON_COPY );
504 currentButton = CreateRequiredButton( ButtonsCopy, mCopyOptionPriority, OPTION_COPY, GET_LOCALE_TEXT("IDS_COM_BODY_COPY"), copyIcon, false );
509 Image pasteIcon = Image::New( DEFAULT_ICON_PASTE );
510 currentButton = CreateRequiredButton( ButtonsPaste, mPasteOptionPriority, OPTION_PASTE, GET_LOCALE_TEXT("IDS_COM_BODY_PASTE"), pasteIcon, false );
515 Image selectIcon = Image::New( DEFAULT_ICON_SELECT );
516 currentButton = CreateRequiredButton( ButtonsSelect, mSelectOptionPriority, OPTION_SELECT_WORD, GET_LOCALE_TEXT("IDS_COM_SK_SELECT"), selectIcon, false );
519 case ButtonsSelectAll:
521 Image selectAllIcon = Image::New( DEFAULT_ICON_SELECT_ALL );
522 currentButton = CreateRequiredButton( ButtonsSelectAll, mSelectAllOptionPriority, OPTION_SELECT_ALL, GET_LOCALE_TEXT("IDS_COM_BODY_SELECT_ALL"), selectAllIcon, false );
525 case ButtonsClipboard:
527 Image clipboardIcon = Image::New( DEFAULT_ICON_CLIPBOARD );
528 currentButton = CreateRequiredButton( ButtonsClipboard, mClipboardOptionPriority, OPTION_CLIPBOARD, GET_LOCALE_TEXT("IDS_COM_BODY_CLIPBOARD"), clipboardIcon, false );
533 DALI_ASSERT_DEBUG( "ButtonsEnumEnd used but an invalid choice");
534 currentButton.orderOfPriority = 0;
541 // Insert button in list of buttons in order of priority setting.
542 for( std::vector<ButtonRequirement>::iterator it = mOrderListOfButtons.begin(), endIt = mOrderListOfButtons.end(); ( it != endIt && !match ); ++it )
544 const ButtonRequirement& button( *it );
545 if ( currentButton.orderOfPriority < button.orderOfPriority )
547 if ( currentButton.orderOfPriority != 0 ) // If order priority 0 then do not add button as not required.
549 mOrderListOfButtons.insert( it, currentButton );
557 mOrderListOfButtons.push_back( currentButton );
562 void TextInputPopup::AddOption(const std::string& name, const std::string& caption, const Image iconImage, bool finalOption)
564 CreatePopUpBackground();
568 // Create a Button with Text, Icon and highlight when pressed
570 Toolkit::PushButton button = Toolkit::PushButton::New();
571 button.SetSizePolicy( Toolkit::Control::Fixed, Toolkit::Control::Fixed );
572 button.SetName( name );
574 // Create container for text and icon when not pressed
575 Actor iconTextContainer = Actor::New();
576 iconTextContainer.SetParentOrigin( ParentOrigin::TOP_LEFT );
577 iconTextContainer.SetAnchorPoint( AnchorPoint::TOP_LEFT );
581 style.SetFontPointSize( PointSize( DEFAULT_UI_FONT_SIZE ) );
582 style.SetTextColor( mCutPasteTextsColor );
583 MarkupProcessor::StyledTextArray styledCaption;
584 styledCaption.push_back( MarkupProcessor::StyledText( Text( caption ), style ) );
585 Toolkit::TextView label = CreateOptionText( styledCaption );
586 label.SetName( name );
588 iconTextContainer.Add( label );
590 // Get natural size of text and then constrain it to bounds.
591 const Vector3 textSize = label.GetNaturalSize();
592 const Vector3 constrainedTextSize = Min( textSize, TEXT_LABEL_MAX_SIZE );
593 Vector3 buttonSize( Max(constrainedTextSize + BUTTON_TEXT_ENLARGE, BUTTON_TEXT_MINIMUM_SIZE) );
594 buttonSize = ( Min(buttonSize, BUTTON_TEXT_MAXIMUM_SIZE) );
595 label.SetSize( Min( buttonSize, constrainedTextSize ) );
597 button.SetParentOrigin( ParentOrigin::TOP_LEFT );
598 button.SetAnchorPoint( AnchorPoint::TOP_LEFT );
599 button.SetSize( buttonSize );
600 button.SetPosition( Vector3( mContentSize.width, POPUP_BORDER.y, 0.0f ) );
603 ImageActor icon = CreateOptionIcon( iconImage, mCutPasteIconsColor );
605 iconTextContainer.Add( icon );
607 // 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.
608 ImageActor pressedImageBg = CreatePressedBackground( buttonSize );
610 Actor iconPressedTextContainer = Actor::New();
611 iconPressedTextContainer.SetDrawMode( DrawMode::OVERLAY );
613 style.SetTextColor( mCutPasteTextsPressedColor );
614 styledCaption.clear();
615 styledCaption.push_back( MarkupProcessor::StyledText( Text( caption ), style ) );
616 Toolkit::TextView pressedLabel = CreateOptionText( styledCaption );
617 pressedLabel.SetSize( Min( buttonSize, TEXT_LABEL_MAX_SIZE ) );
618 ImageActor pressedIcon = CreateOptionIcon( iconImage, mCutPasteIconsPressedColor );
620 iconPressedTextContainer.Add( pressedImageBg );
621 iconPressedTextContainer.Add( pressedLabel );
622 iconPressedTextContainer.Add( pressedIcon );
624 // Set Pressed button Image
625 iconPressedTextContainer.SetSize( buttonSize );
626 button.SetPressedImage( iconPressedTextContainer );
628 // Set Normal button Image
629 iconTextContainer.SetSize( buttonSize );
630 button.SetButtonImage( iconTextContainer );
631 mBackground.Add( button );
633 // Update content size (represents size of all content i.e. from top-left of first button, to bottom-right of last button)
634 mContentSize.width += buttonSize.width;
635 mContentSize.height = std::max(mContentSize.height + ( POPUP_BORDER.y ), buttonSize.height);
636 mButtonContainer.push_back(button);
638 // resize all dividers based on the height content (i.e. max of all button heights)
639 const float dividerHeight = mContentSize.height - DIVIDER_MARGIN;
640 for(ActorIter i = mDividerContainer.begin(); i != mDividerContainer.end(); ++i)
642 i->SetSize( DIVIDER_WIDTH, dividerHeight );
644 button.ClickedSignal().Connect( this, &TextInputPopup::OnButtonPressed );
647 void TextInputPopup::Hide(bool animate)
659 mAnimation = Animation::New( HIDE_POPUP_ANIMATION_DURATION );
660 mAnimation.AnimateTo( Property(mRootActor, Actor::SCALE), Vector3::ZERO, AlphaFunctions::EaseOut );
661 mAnimation.AnimateTo( Property(mRootActor, Actor::COLOR_ALPHA), 0.0f, AlphaFunctions::EaseOut );
664 mAnimation.FinishedSignal().Connect( this, &TextInputPopup::OnHideFinished );
665 mState = StateHiding;
669 mRootActor.SetProperty(Actor::SCALE, Vector3::ZERO);
670 mRootActor.SetProperty(Actor::COLOR_ALPHA, 0.0f);
671 mState = StateHidden;
676 void TextInputPopup::Show(bool animate)
680 mRootActor.SetSensitive( true );
682 mTail.SetPosition(Vector3( mPopupTailXPosition, TAIL_Y_POSITION, 0.0f));
692 mAnimation = Animation::New( SHOW_POPUP_ANIMATION_DURATION );
693 mAnimation.AnimateTo( Property(mRootActor, Actor::SCALE), Vector3::ONE, AlphaFunctions::EaseOut );
694 mAnimation.AnimateTo( Property(mRootActor, Actor::COLOR_ALPHA), 1.0f, AlphaFunctions::EaseOut );
697 mAnimation.FinishedSignal().Connect( this, &TextInputPopup::OnShowFinished );
698 mState = StateShowing;
702 mRootActor.SetProperty(Actor::SCALE, Vector3::ONE);
703 mRootActor.SetProperty(Actor::COLOR_ALPHA, 1.0f);
709 void TextInputPopup::SetAlternativeOffset(Vector2 offset)
711 mRootActor.SetProperty( mAlternativeOffsetProperty, offset );
712 ApplyConfinementConstraint();
715 TextInputPopup::State TextInputPopup::GetState(void) const
720 Actor TextInputPopup::GetRootActor() const
727 void TextInputPopup::SetCutPastePopUpColor( const Vector4& color )
729 mCutPasteButtonsColor = color;
732 const Vector4& TextInputPopup::GetCutPastePopUpColor() const
734 return mCutPasteButtonsColor;
737 void TextInputPopup::SetCutPastePopUpPressedColor( const Vector4& color )
739 mCutPasteButtonsPressedColor = color;
742 const Vector4& TextInputPopup::GetCutPastePopUpPressedColor() const
744 return mCutPasteButtonsPressedColor;
747 void TextInputPopup::SetCutPastePopUpBorderColor( const Vector4& color )
749 mBorderColor = color;
752 const Vector4& TextInputPopup::GetCutPastePopUpBorderColor() const
757 void TextInputPopup::SetCutPastePopUpIconColor( const Vector4& color )
759 mCutPasteIconsColor = color;
762 const Vector4& TextInputPopup::GetCutPastePopUpIconColor() const
764 return mCutPasteIconsColor;
767 void TextInputPopup::SetCutPastePopUpIconPressedColor( const Vector4& color )
769 mCutPasteIconsPressedColor = color;
772 const Vector4& TextInputPopup::GetCutPastePopUpIconPressedColor()
774 return mCutPasteIconsPressedColor;
777 void TextInputPopup::SetCutPastePopUpTextColor( const Vector4& color )
779 mCutPasteTextsColor = color;
782 const Vector4& TextInputPopup::GetCutPastePopUpTextColor()
784 return mCutPasteTextsColor;
787 void TextInputPopup::SetCutPastePopUpTextPressedColor( const Vector4& color )
789 mCutPasteTextsPressedColor = color;
792 const Vector4& TextInputPopup::GetCutPastePopUpTextPressedColor()
794 return mCutPasteTextsPressedColor;
797 void TextInputPopup::TogglePopUpButtonOnOff( TextInputPopup::Buttons requiredButton, bool enable )
799 bool match ( false );
800 for( std::vector<ButtonRequirement>::iterator it = mOrderListOfButtons.begin(), endIt = mOrderListOfButtons.end(); ( it != endIt && !match ); ++it )
802 ButtonRequirement& button( *it );
803 if ( requiredButton == button.buttonId )
805 button.enabled = enable;
811 void TextInputPopup::SetButtonPriorityPosition( TextInputPopup::Buttons button, unsigned int priority )
817 mCutOptionPriority = priority;
822 mCopyOptionPriority = priority;
827 mPasteOptionPriority = priority;
832 mSelectOptionPriority = priority;
835 case ButtonsSelectAll:
837 mSelectAllOptionPriority = priority;
840 case ButtonsClipboard:
842 mClipboardOptionPriority = priority;
847 DALI_ASSERT_DEBUG( "ButtonsEnumEnd used but an invalid choice");
851 CreateOrderedListOfOptions(); // Update list of options as priority changed.
854 unsigned int TextInputPopup::GetButtonPriorityPosition( TextInputPopup::Buttons button ) const
856 unsigned int priority = 0;
862 priority = mCutOptionPriority;
867 priority = mCopyOptionPriority;
872 priority = mPasteOptionPriority;
877 priority = mSelectOptionPriority;
880 case ButtonsSelectAll:
882 priority = mSelectAllOptionPriority;
885 case ButtonsClipboard:
887 priority = mClipboardOptionPriority;
892 DALI_ASSERT_DEBUG( "ButtonsEnumEnd used but an invalid choice");
900 void TextInputPopup::AddPopupOptions()
902 for( std::vector<ButtonRequirement>::const_iterator it = mOrderListOfButtons.begin(), endIt = mOrderListOfButtons.end(); ( it != endIt ); ++it )
904 const ButtonRequirement& button( *it );
905 if ( button.enabled )
907 AddOption( button.name, button.caption, button.iconImage, false );
911 float visiblePopUpWidth = std::min( mContentSize.width - POP_UP_SCREEN_EDGE_MARGIN*2 , mBoundingRect.width - POP_UP_SCREEN_EDGE_MARGIN *2);
912 float visbilePopUpHeight = std::max( mContentSize.height, POPUP_MINIMUM_SIZE.height );
913 Vector2 visiblePopUpSize = Vector2( visiblePopUpWidth, visbilePopUpHeight );
915 visiblePopUpWidth = std::max( visiblePopUpWidth, POPUP_MINIMUM_SIZE.width );
917 mBackground.SetSize( mContentSize.width, mContentSize.height );
918 mRootActor.SetSize( visiblePopUpWidth, visbilePopUpHeight ); // Make Root Actor reflect the size of its content
920 CreateLayer( visiblePopUpSize );
921 CreateStencil( visiblePopUpSize );
922 CreateScrollView( Vector2( mContentSize.width, mContentSize.height ), visiblePopUpSize );
924 mLayer.Add( mStencil );
925 mLayer.Add( mScrollView );
926 mScrollView.Add( mBackground );
927 mRootActor.Add( mTail );
934 void TextInputPopup::SetPopupBoundary( const Rect<float>& boundingRectangle )
936 mBoundingRect = boundingRectangle;
939 void TextInputPopup::SetTailPosition( const Vector3& position )
941 mPopupTailXPosition = position.x;
942 ApplyTailConstraint();
945 bool TextInputPopup::OnButtonPressed( Toolkit::Button button )
947 mPressedSignal.Emit( button );
951 void TextInputPopup::OnHideFinished(Animation& source)
953 source.FinishedSignal().Disconnect( this, &TextInputPopup::OnHideFinished );
955 mState = StateHidden;
956 mHideFinishedSignal.Emit( *this );
959 void TextInputPopup::OnShowFinished(Animation& source)
961 source.FinishedSignal().Disconnect( this, &TextInputPopup::OnShowFinished );
963 mShowFinishedSignal.Emit( *this );
966 TextInputPopup::PressedSignalV2& TextInputPopup::PressedSignal()
968 return mPressedSignal;
971 TextInputPopup::HideFinishedSignalV2& TextInputPopup::HideFinishedSignal()
973 return mHideFinishedSignal;
976 TextInputPopup::ShowFinishedSignalV2& TextInputPopup::ShowFinishedSignal()
978 return mShowFinishedSignal;
981 } // namespace Internal
983 } // namespace Toolkit