[dali_1.2.32] Merge branch 'devel/master'
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / text-controls / text-selection-popup-impl.cpp
1 /*
2  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali-toolkit/internal/controls/text-controls/text-selection-popup-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <libintl.h>
23 #include <string.h>
24 #include <cfloat>
25 #include <dali/public-api/animation/animation.h>
26 #include <dali/devel-api/images/nine-patch-image.h>
27 #include <dali/public-api/images/resource-image.h>
28 #include <dali/public-api/math/vector2.h>
29 #include <dali/public-api/math/vector4.h>
30 #include <dali/public-api/object/property-map.h>
31 #include <dali/public-api/object/type-registry-helper.h>
32 #include <dali/integration-api/debug.h>
33
34 // INTERNAL INCLUDES
35 #include <dali-toolkit/public-api/controls/text-controls/text-label.h>
36 #include <dali-toolkit/devel-api/controls/buttons/button-devel.h>
37 #include <dali-toolkit/devel-api/controls/control-depth-index-ranges.h>
38 #include <dali-toolkit/devel-api/controls/text-controls/text-selection-popup-callback-interface.h>
39 #include <dali-toolkit/devel-api/visuals/text-visual-properties.h>
40 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
41 #include <dali-toolkit/internal/helpers/color-conversion.h>
42 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
43
44 namespace Dali
45 {
46
47 namespace Toolkit
48 {
49
50 namespace Internal
51 {
52
53 namespace
54 {
55
56 #define GET_LOCALE_TEXT(string) dgettext("dali-toolkit", string)
57
58 const std::string TEXT_SELECTION_POPUP_BUTTON_STYLE_NAME( "TextSelectionPopupButton" );
59 const Dali::Vector4 DEFAULT_OPTION_PRESSED_COLOR( Dali::Vector4( 0.24f, 0.72f, 0.8f, 1.0f ) );
60
61 #if defined(DEBUG_ENABLED)
62   Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, true, "LOG_TEXT_CONTROLS");
63 #endif
64
65 #ifdef DGETTEXT_ENABLED
66
67 #define POPUP_CUT_STRING GET_LOCALE_TEXT("IDS_COM_BODY_CUT")
68 #define POPUP_COPY_STRING GET_LOCALE_TEXT("IDS_COM_BODY_COPY")
69 #define POPUP_PASTE_STRING GET_LOCALE_TEXT("IDS_COM_BODY_PASTE")
70 #define POPUP_SELECT_STRING GET_LOCALE_TEXT("IDS_COM_SK_SELECT")
71 #define POPUP_SELECT_ALL_STRING GET_LOCALE_TEXT("IDS_COM_BODY_SELECT_ALL")
72 #define POPUP_CLIPBOARD_STRING GET_LOCALE_TEXT("IDS_COM_BODY_CLIPBOARD")
73
74 #else
75
76 #define POPUP_CUT_STRING  "Cut"
77 #define POPUP_COPY_STRING  "Copy"
78 #define POPUP_PASTE_STRING  "Paste"
79 #define POPUP_SELECT_STRING  "Select"
80 #define POPUP_SELECT_ALL_STRING  "Select All"
81 #define POPUP_CLIPBOARD_STRING  "Clipboard"
82
83 #endif
84
85 const char* const OPTION_SELECT_WORD = "option-select_word";                       // "Select Word" popup option.
86 const char* const OPTION_SELECT_ALL("option-select_all");                          // "Select All" popup option.
87 const char* const OPTION_CUT("optionCut");                                        // "Cut" popup option.
88 const char* const OPTION_COPY("optionCopy");                                      // "Copy" popup option.
89 const char* const OPTION_PASTE("optionPaste");                                    // "Paste" popup option.
90 const char* const OPTION_CLIPBOARD("optionClipboard");                            // "Clipboard" popup option.
91
92 const std::string IDS_LTR( "IDS_LTR" );
93 const std::string RTL_DIRECTION( "RTL" );
94
95 BaseHandle Create()
96 {
97   return Toolkit::TextSelectionPopup::New( NULL );
98 }
99
100 // Setup properties, signals and actions using the type-registry.
101
102 DALI_TYPE_REGISTRATION_BEGIN( Toolkit::TextSelectionPopup, Toolkit::Control, Create );
103
104 DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popupMaxSize", VECTOR2,   POPUP_MAX_SIZE )
105 DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popupMinSize", VECTOR2,   POPUP_MIN_SIZE )
106 DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "optionMaxSize", VECTOR2,   OPTION_MAX_SIZE )
107 DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "optionMinSize", VECTOR2,   OPTION_MIN_SIZE )
108 DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "optionDividerSize", VECTOR2,   OPTION_DIVIDER_SIZE )
109 DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popupClipboardButtonImage", STRING, POPUP_CLIPBOARD_BUTTON_ICON_IMAGE )
110 DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popupCutButtonImage", STRING, POPUP_CUT_BUTTON_ICON_IMAGE )
111 DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popupCopyButtonImage", STRING, POPUP_COPY_BUTTON_ICON_IMAGE )
112 DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popupPasteButtonImage", STRING, POPUP_PASTE_BUTTON_ICON_IMAGE )
113 DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popupSelectButtonImage", STRING, POPUP_SELECT_BUTTON_ICON_IMAGE )
114 DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popupSelectAllButtonImage", STRING, POPUP_SELECT_ALL_BUTTON_ICON_IMAGE )
115 DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popupDividerColor", VECTOR4, POPUP_DIVIDER_COLOR )
116 DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popupIconColor", VECTOR4, POPUP_ICON_COLOR )
117 DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popupPressedColor", VECTOR4, POPUP_PRESSED_COLOR )
118 DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popupPressedImage", STRING, POPUP_PRESSED_IMAGE )
119 DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popupFadeInDuration", FLOAT, POPUP_FADE_IN_DURATION )
120 DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "popupFadeOutDuration", FLOAT, POPUP_FADE_OUT_DURATION )
121 DALI_PROPERTY_REGISTRATION( Toolkit, TextSelectionPopup, "backgroundBorder", MAP, BACKGROUND_BORDER )
122
123 DALI_TYPE_REGISTRATION_END()
124
125 } // namespace
126
127
128 Dali::Toolkit::TextSelectionPopup TextSelectionPopup::New( TextSelectionPopupCallbackInterface* callbackInterface )
129 {
130   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "TextSelectionPopup::New\n" );
131
132    // Create the implementation, temporarily owned by this handle on stack
133   IntrusivePtr< TextSelectionPopup > impl = new TextSelectionPopup( callbackInterface );
134
135   // Pass ownership to CustomActor handle
136   Dali::Toolkit::TextSelectionPopup handle( *impl );
137
138   // Second-phase init of the implementation
139   // This can only be done after the CustomActor connection has been made...
140   impl->Initialize();
141
142   return handle;
143 }
144
145 void TextSelectionPopup::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
146 {
147   Toolkit::TextSelectionPopup selectionPopup = Toolkit::TextSelectionPopup::DownCast( Dali::BaseHandle( object ) );
148
149   if( selectionPopup )
150   {
151     TextSelectionPopup& impl( GetImpl( selectionPopup ) );
152
153     switch( index )
154     {
155       case Toolkit::TextSelectionPopup::Property::POPUP_MAX_SIZE:
156       {
157        impl.SetDimensionToCustomise( POPUP_MAXIMUM_SIZE, value.Get< Vector2 >() );
158        break;
159       }
160       case Toolkit::TextSelectionPopup::Property::OPTION_MAX_SIZE:
161       {
162         impl.SetDimensionToCustomise( OPTION_MAXIMUM_SIZE, value.Get< Vector2 >() );
163         break;
164       }
165       case Toolkit::TextSelectionPopup::Property::OPTION_MIN_SIZE:
166       {
167         impl.SetDimensionToCustomise( OPTION_MINIMUM_SIZE, value.Get< Vector2>() );
168         break;
169       }
170       case Toolkit::TextSelectionPopup::Property::OPTION_DIVIDER_SIZE:
171       {
172         impl.SetDimensionToCustomise( OPTION_DIVIDER_SIZE, value.Get< Vector2>() );
173         break;
174       }
175       case Toolkit::TextSelectionPopup::Property::POPUP_CLIPBOARD_BUTTON_ICON_IMAGE:
176       {
177         ResourceImage image = ResourceImage::New( value.Get< std::string >() );
178         impl.SetButtonImage( Toolkit::TextSelectionPopup::CLIPBOARD, image );
179         break;
180       }
181       case Toolkit::TextSelectionPopup::Property::POPUP_CUT_BUTTON_ICON_IMAGE:
182       {
183         ResourceImage image = ResourceImage::New( value.Get< std::string >() );
184         impl.SetButtonImage( Toolkit::TextSelectionPopup::CUT, image );
185         break;
186       }
187       case Toolkit::TextSelectionPopup::Property::POPUP_COPY_BUTTON_ICON_IMAGE:
188       {
189         ResourceImage image = ResourceImage::New( value.Get< std::string >() );
190         impl.SetButtonImage( Toolkit::TextSelectionPopup::COPY, image );
191         break;
192       }
193       case Toolkit::TextSelectionPopup::Property::POPUP_PASTE_BUTTON_ICON_IMAGE:
194       {
195         ResourceImage image = ResourceImage::New( value.Get< std::string >() );
196         impl.SetButtonImage( Toolkit::TextSelectionPopup::PASTE, image );
197         break;
198       }
199       case Toolkit::TextSelectionPopup::Property::POPUP_SELECT_BUTTON_ICON_IMAGE:
200       {
201         ResourceImage image = ResourceImage::New( value.Get< std::string >() );
202         impl.SetButtonImage( Toolkit::TextSelectionPopup::SELECT, image );
203         break;
204       }
205       case Toolkit::TextSelectionPopup::Property::POPUP_SELECT_ALL_BUTTON_ICON_IMAGE:
206       {
207         ResourceImage image = ResourceImage::New( value.Get< std::string >() );
208         impl.SetButtonImage( Toolkit::TextSelectionPopup::SELECT_ALL, image );
209         break;
210       }
211       case Toolkit::TextSelectionPopup::Property::POPUP_DIVIDER_COLOR:
212       {
213         impl.mDividerColor = value.Get< Vector4 >();
214         break;
215       }
216       case Toolkit::TextSelectionPopup::Property::POPUP_ICON_COLOR:
217       {
218         impl.mIconColor = value.Get< Vector4 >();
219         break;
220       }
221       case Toolkit::TextSelectionPopup::Property::POPUP_PRESSED_COLOR:
222       {
223         impl.mPressedColor = value.Get< Vector4 >();
224         break;
225       }
226       case Toolkit::TextSelectionPopup::Property::POPUP_PRESSED_IMAGE:
227       {
228         impl.SetPressedImage( value.Get< std::string >() );
229         break;
230       }
231       case Toolkit::TextSelectionPopup::Property::POPUP_FADE_IN_DURATION:
232       {
233         impl.mFadeInDuration = value.Get < float >();
234         break;
235       }
236       case Toolkit::TextSelectionPopup::Property::POPUP_FADE_OUT_DURATION:
237       {
238         impl.mFadeOutDuration = value.Get < float >();
239         break;
240       }
241       case Toolkit::TextSelectionPopup::Property::BACKGROUND_BORDER:
242       {
243         Property::Map map = value.Get<Property::Map>();
244         impl.CreateBackgroundBorder( map );
245         break;
246       }
247     } // switch
248   } // TextSelectionPopup
249 }
250
251 Property::Value TextSelectionPopup::GetProperty( BaseObject* object, Property::Index index )
252 {
253   Property::Value value;
254
255   Toolkit::TextSelectionPopup selectionPopup = Toolkit::TextSelectionPopup::DownCast( Dali::BaseHandle( object ) );
256
257   if( selectionPopup )
258   {
259     TextSelectionPopup& impl( GetImpl( selectionPopup ) );
260
261     switch( index )
262     {
263       case Toolkit::TextSelectionPopup::Property::POPUP_MAX_SIZE:
264       {
265         value = impl.GetDimensionToCustomise( POPUP_MAXIMUM_SIZE );
266         break;
267       }
268       case Toolkit::TextSelectionPopup::Property::OPTION_MAX_SIZE:
269       {
270         value = impl.GetDimensionToCustomise( OPTION_MAXIMUM_SIZE );
271         break;
272       }
273       case Toolkit::TextSelectionPopup::Property::OPTION_MIN_SIZE:
274       {
275         value = impl.GetDimensionToCustomise( OPTION_MINIMUM_SIZE );
276         break;
277       }
278       case Toolkit::TextSelectionPopup::Property::OPTION_DIVIDER_SIZE:
279       {
280         value = impl.GetDimensionToCustomise( OPTION_DIVIDER_SIZE );
281         break;
282       }
283       case Toolkit::TextSelectionPopup::Property::POPUP_CLIPBOARD_BUTTON_ICON_IMAGE:
284       {
285         ResourceImage image = ResourceImage::DownCast( impl.GetButtonImage( Toolkit::TextSelectionPopup::CLIPBOARD ) );
286         if( image )
287         {
288           value = image.GetUrl();
289         }
290         break;
291       }
292       case Toolkit::TextSelectionPopup::Property::POPUP_CUT_BUTTON_ICON_IMAGE:
293       {
294         ResourceImage image = ResourceImage::DownCast( impl.GetButtonImage( Toolkit::TextSelectionPopup::CUT ) );
295         if( image )
296         {
297           value = image.GetUrl();
298         }
299         break;
300       }
301       case Toolkit::TextSelectionPopup::Property::POPUP_COPY_BUTTON_ICON_IMAGE:
302       {
303         ResourceImage image = ResourceImage::DownCast( impl.GetButtonImage( Toolkit::TextSelectionPopup::COPY ) );
304         if( image )
305         {
306           value = image.GetUrl();
307         }
308         break;
309       }
310       case Toolkit::TextSelectionPopup::Property::POPUP_PASTE_BUTTON_ICON_IMAGE:
311       {
312         ResourceImage image = ResourceImage::DownCast( impl.GetButtonImage( Toolkit::TextSelectionPopup::PASTE ) );
313         if( image )
314         {
315           value = image.GetUrl();
316         }
317         break;
318       }
319       case Toolkit::TextSelectionPopup::Property::POPUP_SELECT_BUTTON_ICON_IMAGE:
320       {
321         ResourceImage image = ResourceImage::DownCast( impl.GetButtonImage( Toolkit::TextSelectionPopup::SELECT ) );
322         if( image )
323         {
324           value = image.GetUrl();
325         }
326         break;
327       }
328       case Toolkit::TextSelectionPopup::Property::POPUP_SELECT_ALL_BUTTON_ICON_IMAGE:
329       {
330         ResourceImage image = ResourceImage::DownCast( impl.GetButtonImage( Toolkit::TextSelectionPopup::SELECT_ALL ) );
331         if( image )
332         {
333           value = image.GetUrl();
334         }
335         break;
336       }
337       case Toolkit::TextSelectionPopup::Property::POPUP_PRESSED_IMAGE:
338       {
339         value = impl.GetPressedImage();
340         break;
341       }
342       case Toolkit::TextSelectionPopup::Property::POPUP_FADE_IN_DURATION:
343       {
344         value = impl.mFadeInDuration;
345         break;
346       }
347       case Toolkit::TextSelectionPopup::Property::POPUP_FADE_OUT_DURATION:
348       {
349         value = impl.mFadeOutDuration;
350         break;
351       }
352       case Toolkit::TextSelectionPopup::Property::BACKGROUND_BORDER:
353       {
354         Property::Map map;
355         Toolkit::Visual::Base visual = impl.GetVisual( Toolkit::TextSelectionPopup::Property::BACKGROUND_BORDER );
356         if( visual )
357         {
358           visual.CreatePropertyMap( map );
359         }
360         value = map;
361         break;
362       }
363     } // switch
364   }
365   return value;
366 }
367
368 void TextSelectionPopup::EnableButtons( Toolkit::TextSelectionPopup::Buttons buttonsToEnable )
369 {
370   mEnabledButtons = buttonsToEnable;
371   mButtonsChanged = true;
372 }
373
374 void TextSelectionPopup::RaiseAbove( Layer target )
375 {
376   if( mToolbar )
377   {
378     mToolbar.RaiseAbove( target );
379   }
380 }
381
382 void TextSelectionPopup::ShowPopup()
383 {
384   if( ( !mPopupShowing || mButtonsChanged ) &&
385       ( Toolkit::TextSelectionPopup::NONE != mEnabledButtons ) )
386   {
387     Actor self = Self();
388     AddPopupOptionsToToolbar( mShowIcons, mShowCaptions );
389
390     Animation animation = Animation::New( mFadeInDuration );
391     animation.AnimateTo( Property(self, Actor::Property::COLOR_ALPHA), 1.0f  );
392     animation.Play();
393     mPopupShowing = true;
394   }
395 }
396
397 void TextSelectionPopup::HidePopup()
398 {
399   if ( mPopupShowing )
400   {
401     mPopupShowing = false;
402     Actor self = Self();
403     Animation animation = Animation::New( mFadeOutDuration );
404     animation.AnimateTo( Property(self, Actor::Property::COLOR_ALPHA), 0.0f  );
405     animation.FinishedSignal().Connect( this, &TextSelectionPopup::HideAnimationFinished );
406     animation.Play();
407   }
408 }
409
410 void TextSelectionPopup::OnInitialize()
411 {
412   DALI_LOG_INFO( gLogFilter, Debug::General, "TextSelectionPopup::OnInitialize\n" );
413   Actor self = Self();
414   self.SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
415   self.SetProperty( Actor::Property::COLOR_ALPHA, 0.0f );
416
417   // The Popup Control background is a nine-patch image. We clip against this so the
418   // contents are correctly clipped against the edges of the nine-patch.
419   self.SetProperty( Actor::Property::CLIPPING_MODE, ClippingMode::CLIP_CHILDREN );
420 }
421
422 void TextSelectionPopup::HideAnimationFinished( Animation& animation )
423 {
424   Actor self = Self();
425   if ( !mPopupShowing ) // During the Hide/Fade animation there could be a call to Show the Popup again, mPopupShowing will be true in this case.
426   {
427     DALI_LOG_INFO( gLogFilter, Debug::General, "TextSelectionPopup::HideAnimationFinished\n" );
428     UnparentAndReset( mToolbar );
429   }
430 }
431
432 bool TextSelectionPopup::OnCutButtonPressed( Toolkit::Button button )
433 {
434   if( mCallbackInterface )
435   {
436     mCallbackInterface->TextPopupButtonTouched( Toolkit::TextSelectionPopup::CUT );
437   }
438
439   return true;
440 }
441
442 bool TextSelectionPopup::OnCopyButtonPressed( Toolkit::Button button )
443 {
444   if( mCallbackInterface )
445   {
446     mCallbackInterface->TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::COPY );
447   }
448
449   return true;
450 }
451
452 bool TextSelectionPopup::OnPasteButtonPressed( Toolkit::Button button )
453 {
454   if( mCallbackInterface )
455   {
456     mCallbackInterface->TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::PASTE );
457   }
458
459   return true;
460 }
461
462 bool TextSelectionPopup::OnSelectButtonPressed( Toolkit::Button button )
463 {
464   if( mCallbackInterface )
465   {
466     mCallbackInterface->TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::SELECT );
467   }
468
469   return true;
470 }
471
472 bool TextSelectionPopup::OnSelectAllButtonPressed( Toolkit::Button button )
473 {
474   if( mCallbackInterface )
475   {
476     mCallbackInterface->TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::SELECT_ALL );
477   }
478
479   return true;
480 }
481
482 bool TextSelectionPopup::OnClipboardButtonPressed( Toolkit::Button button )
483 {
484   if( mCallbackInterface )
485   {
486     mCallbackInterface->TextPopupButtonTouched( Dali::Toolkit::TextSelectionPopup::CLIPBOARD );
487   }
488
489   return true;
490 }
491
492 void TextSelectionPopup::SetDimensionToCustomise( const PopupCustomisations& settingToCustomise, const Size& dimension )
493 {
494   switch( settingToCustomise )
495   {
496     case POPUP_MAXIMUM_SIZE :
497     {
498       mPopupMaxSize = dimension;
499       if ( mToolbar )
500       {
501         mToolbar.SetProperty( Toolkit::TextSelectionToolbar::Property::MAX_SIZE, dimension );
502       }
503       break;
504     }
505     case OPTION_MAXIMUM_SIZE :
506     {
507       mOptionMaxSize = dimension;
508       // Option max size not currently currently supported
509       break;
510     }
511     case OPTION_MINIMUM_SIZE :
512     {
513       mOptionMinSize = dimension;
514       // Option min size not currently currently supported
515       break;
516     }
517     case OPTION_DIVIDER_SIZE :
518     {
519       mOptionDividerSize = dimension;
520       if ( mToolbar )
521       {
522         // Resize Dividers not currently supported
523       }
524       break;
525     }
526   } // switch
527 }
528
529 Size TextSelectionPopup::GetDimensionToCustomise( const PopupCustomisations& settingToCustomise )
530 {
531   switch( settingToCustomise )
532   {
533     case POPUP_MAXIMUM_SIZE :
534     {
535       if ( mToolbar )
536       {
537         return mToolbar.GetProperty( Toolkit::TextSelectionToolbar::Property::MAX_SIZE ).Get< Vector2 >();
538       }
539       else
540       {
541         return mPopupMaxSize;
542       }
543     }
544     case OPTION_MAXIMUM_SIZE :
545     {
546       return mOptionMaxSize;
547     }
548     case OPTION_MINIMUM_SIZE :
549     {
550       return mOptionMinSize;
551     }
552     case OPTION_DIVIDER_SIZE :
553     {
554       return mOptionDividerSize;
555     }
556   } // switch
557
558   return Size::ZERO;
559 }
560
561 void TextSelectionPopup::SetButtonImage( Toolkit::TextSelectionPopup::Buttons button, Dali::Image image )
562 {
563    switch ( button )
564    {
565    break;
566    case Toolkit::TextSelectionPopup::CLIPBOARD:
567    {
568      mClipboardIconImage  = image;
569    }
570    break;
571    case Toolkit::TextSelectionPopup::CUT :
572    {
573      mCutIconImage = image;
574    }
575    break;
576    case Toolkit::TextSelectionPopup::COPY :
577    {
578      mCopyIconImage = image;
579    }
580    break;
581    case Toolkit::TextSelectionPopup::PASTE :
582    {
583      mPasteIconImage = image;
584    }
585    break;
586    case Toolkit::TextSelectionPopup::SELECT :
587    {
588      mSelectIconImage = image;
589    }
590    break;
591    case Toolkit::TextSelectionPopup::SELECT_ALL :
592    {
593      mSelectAllIconImage = image;
594    }
595    break;
596    default :
597    {
598      DALI_ASSERT_DEBUG( "TextSelectionPopup SetPopupImage Unknown Button" );
599    }
600    } // switch
601 }
602
603 Dali::Image TextSelectionPopup::GetButtonImage( Toolkit::TextSelectionPopup::Buttons button )
604 {
605   switch ( button )
606   {
607   case Toolkit::TextSelectionPopup::CLIPBOARD :
608   {
609     return mClipboardIconImage;
610   }
611   break;
612   case Toolkit::TextSelectionPopup::CUT :
613   {
614     return mCutIconImage;
615   }
616   break;
617   case Toolkit::TextSelectionPopup::COPY :
618   {
619     return mCopyIconImage;
620   }
621   break;
622   case Toolkit::TextSelectionPopup::PASTE :
623   {
624     return mPasteIconImage;
625   }
626   break;
627   case Toolkit::TextSelectionPopup::SELECT :
628   {
629     return mSelectIconImage;
630   }
631   break;
632   case Toolkit::TextSelectionPopup::SELECT_ALL :
633   {
634     return mSelectAllIconImage;
635   }
636   break;
637   default :
638   {
639     DALI_ASSERT_DEBUG( "TextSelectionPopup GetPopupImage Unknown Button" );
640   }
641   } // switch
642
643   return Dali::Image();
644 }
645
646 void TextSelectionPopup::SetPressedImage( const std::string& filename )
647 {
648   mPressedImage = filename;
649 }
650
651 std::string TextSelectionPopup::GetPressedImage() const
652 {
653   return mPressedImage;
654 }
655
656  void TextSelectionPopup::CreateOrderedListOfPopupOptions()
657  {
658    mOrderListOfButtons.clear();
659    mOrderListOfButtons.reserve( 8u );
660
661    // Create button for each possible option using Option priority
662    mOrderListOfButtons.push_back( ButtonRequirement( Toolkit::TextSelectionPopup::CUT, mCutOptionPriority, OPTION_CUT, POPUP_CUT_STRING , mCutIconImage, 0 != ( mEnabledButtons & Toolkit::TextSelectionPopup::CUT)  ) );
663    mOrderListOfButtons.push_back( ButtonRequirement( Toolkit::TextSelectionPopup::COPY, mCopyOptionPriority, OPTION_COPY, POPUP_COPY_STRING, mCopyIconImage, 0 != ( mEnabledButtons & Toolkit::TextSelectionPopup::COPY)  ) );
664    mOrderListOfButtons.push_back( ButtonRequirement( Toolkit::TextSelectionPopup::PASTE, mPasteOptionPriority, OPTION_PASTE, POPUP_PASTE_STRING, mPasteIconImage, 0 != ( mEnabledButtons & Toolkit::TextSelectionPopup::PASTE)  ) );
665    mOrderListOfButtons.push_back( ButtonRequirement( Toolkit::TextSelectionPopup::SELECT, mSelectOptionPriority, OPTION_SELECT_WORD, POPUP_SELECT_STRING, mSelectIconImage, 0 != ( mEnabledButtons & Toolkit::TextSelectionPopup::SELECT)  ) );
666    mOrderListOfButtons.push_back( ButtonRequirement( Toolkit::TextSelectionPopup::SELECT_ALL, mSelectAllOptionPriority, OPTION_SELECT_ALL, POPUP_SELECT_ALL_STRING, mSelectAllIconImage, 0 != ( mEnabledButtons & Toolkit::TextSelectionPopup::SELECT_ALL)  ) );
667    mOrderListOfButtons.push_back( ButtonRequirement( Toolkit::TextSelectionPopup::CLIPBOARD, mClipboardOptionPriority, OPTION_CLIPBOARD, POPUP_CLIPBOARD_STRING, mClipboardIconImage, 0 != ( mEnabledButtons & Toolkit::TextSelectionPopup::CLIPBOARD)  ) );
668
669    // Sort the buttons according their priorities.
670    std::sort( mOrderListOfButtons.begin(), mOrderListOfButtons.end(), TextSelectionPopup::ButtonPriorityCompare() );
671  }
672
673  void TextSelectionPopup::AddOption( const ButtonRequirement& button, bool showDivider, bool showIcons, bool showCaption  )
674  {
675    // 1. Create a option.
676    DALI_LOG_INFO( gLogFilter, Debug::General, "TextSelectionPopup::AddOption\n" );
677
678    Toolkit::PushButton option = Toolkit::PushButton::New();
679    option.SetName( button.name );
680    option.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
681
682    switch( button.id )
683    {
684      case Toolkit::TextSelectionPopup::CUT:
685      {
686        option.ClickedSignal().Connect( this, &TextSelectionPopup::OnCutButtonPressed );
687        break;
688      }
689      case Toolkit::TextSelectionPopup::COPY:
690      {
691        option.ClickedSignal().Connect( this, &TextSelectionPopup::OnCopyButtonPressed );
692        break;
693      }
694      case Toolkit::TextSelectionPopup::PASTE:
695      {
696        option.ClickedSignal().Connect( this, &TextSelectionPopup::OnPasteButtonPressed );
697        break;
698      }
699      case Toolkit::TextSelectionPopup::SELECT:
700      {
701        option.ClickedSignal().Connect( this, &TextSelectionPopup::OnSelectButtonPressed );
702        break;
703      }
704      case Toolkit::TextSelectionPopup::SELECT_ALL:
705      {
706        option.ClickedSignal().Connect( this, &TextSelectionPopup::OnSelectAllButtonPressed );
707        break;
708      }
709      case Toolkit::TextSelectionPopup::CLIPBOARD:
710      {
711        option.ClickedSignal().Connect( this, &TextSelectionPopup::OnClipboardButtonPressed );
712        break;
713      }
714      case Toolkit::TextSelectionPopup::NONE:
715      {
716        // Nothing to do:
717        break;
718      }
719    }
720
721    // 2. Set the options contents.
722    if( showCaption )
723    {
724      // PushButton layout properties.
725      option.SetProperty( Toolkit::PushButton::Property::LABEL_PADDING, Vector4( 24.0f, 24.0f, 14.0f, 14.0f ) );
726
727      // Label properties.
728      Property::Map buttonLabelProperties;
729      buttonLabelProperties.Insert( Toolkit::TextVisual::Property::TEXT, button.caption );
730      option.SetProperty( Toolkit::Button::Property::LABEL, buttonLabelProperties );
731    }
732    if( showIcons )
733    {
734      option.SetProperty( Toolkit::PushButton::Property::ICON_PADDING, Vector4( 10.0f, 10.0f, 10.0f, 10.0f ) );
735      option.SetProperty( Toolkit::PushButton::Property::ICON_ALIGNMENT, "TOP" );
736
737      // TODO: This is temporarily disabled until the text-selection-popup image API is changed to strings.
738      //option.SetProperty( Toolkit::PushButton::Property::SELECTED_ICON, button.icon );
739      //option.SetProperty( Toolkit::PushButton::Property::UNSELECTED_ICON, button.icon );
740    }
741
742    // 3. Set the normal option image (blank / Transparent).
743    option.SetProperty( Toolkit::DevelButton::Property::UNSELECTED_BACKGROUND_VISUAL, "" );
744
745    // 4. Set the pressed option image.
746    // The image can be blank, the color can be used regardless.
747    option.SetProperty( Toolkit::DevelButton::Property::SELECTED_BACKGROUND_VISUAL, mPressedImage );
748    option.SetProperty( Toolkit::Button::Property::SELECTED_COLOR, mPressedColor );
749    option.SetProperty( Toolkit::Control::Property::STYLE_NAME, TEXT_SELECTION_POPUP_BUTTON_STYLE_NAME );
750
751    // 5 Add option to tool bar
752    mToolbar.AddOption( option );
753
754    // 6. Add the divider
755    if( showDivider )
756    {
757      const Size size( mOptionDividerSize.width, 0.0f ); // Height FILL_TO_PARENT
758
759      Toolkit::Control divider = Toolkit::Control::New();
760 #ifdef DECORATOR_DEBUG
761      divider.SetName("Text's popup divider");
762 #endif
763      divider.SetSize( size );
764      divider.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::HEIGHT );
765      divider.SetBackgroundColor( mDividerColor  );
766      mToolbar.AddDivider( divider );
767    }
768  }
769
770  std::size_t TextSelectionPopup::GetNumberOfEnabledOptions()
771  {
772    std::size_t numberOfOptions = 0u;
773    for( std::vector<ButtonRequirement>::const_iterator it = mOrderListOfButtons.begin(), endIt = mOrderListOfButtons.end(); ( it != endIt ); ++it )
774    {
775      const ButtonRequirement& button( *it );
776      if( button.enabled )
777      {
778        ++numberOfOptions;
779      }
780    }
781
782    return numberOfOptions;
783  }
784
785  void TextSelectionPopup::AddPopupOptionsToToolbar( bool showIcons, bool showCaptions )
786  {
787    DALI_LOG_INFO( gLogFilter, Debug::General, "TextSelectionPopup::AddPopupOptionsToToolbar\n" );
788
789    CreateOrderedListOfPopupOptions();
790
791    mButtonsChanged = false;
792    UnparentAndReset( mToolbar);
793
794    if( !mToolbar )
795    {
796      Actor self = Self();
797      mToolbar = Toolkit::TextSelectionToolbar::New();
798      if ( mPopupMaxSize != Vector2::ZERO ) // If PopupMaxSize property set then apply to Toolbar. Toolbar currently is not retriving this from json
799      {
800        mToolbar.SetProperty( Toolkit::TextSelectionToolbar::Property::MAX_SIZE, mPopupMaxSize );
801      }
802      mToolbar.SetParentOrigin( ParentOrigin::CENTER );
803 #ifdef DECORATOR_DEBUG
804      mToolbar.SetName("TextSelectionToolbar");
805 #endif
806      self.Add( mToolbar );
807    }
808
809    // Whether to mirror the list of buttons (for right to left languages)
810    bool mirror = false;
811    char* idsLtr = GET_LOCALE_TEXT( IDS_LTR.c_str() );
812    if( NULL != idsLtr )
813    {
814      mirror = ( 0 == strcmp( idsLtr, RTL_DIRECTION.c_str() ) );
815
816      if( mirror )
817      {
818        std::reverse( mOrderListOfButtons.begin(), mOrderListOfButtons.end() );
819      }
820    }
821
822    // Iterate list of buttons and add active ones to Toolbar
823    std::size_t numberOfOptionsRequired =  GetNumberOfEnabledOptions();
824    std::size_t numberOfOptionsAdded = 0u;
825    for( std::vector<ButtonRequirement>::const_iterator it = mOrderListOfButtons.begin(), endIt = mOrderListOfButtons.end(); ( it != endIt ); ++it )
826    {
827      const ButtonRequirement& button( *it );
828      if ( button.enabled )
829      {
830        numberOfOptionsAdded++;
831        AddOption(  button, ( numberOfOptionsAdded < numberOfOptionsRequired ) , showIcons, showCaptions );
832      }
833    }
834
835    if( mirror )
836    {
837      mToolbar.ScrollTo( Vector2( mPopupMaxSize.x, 0.f ) );
838    }
839  }
840
841 void TextSelectionPopup::CreateBackgroundBorder( Property::Map& propertyMap )
842 {
843   // Removes previous image if necessary
844   UnregisterVisual( Toolkit::TextSelectionPopup::Property::BACKGROUND_BORDER );
845
846   if( ! propertyMap.Empty() )
847   {
848     Toolkit::Visual::Base visual = Toolkit::VisualFactory::Get().CreateVisual( propertyMap );
849
850     if( visual )
851     {
852       RegisterVisual( Toolkit::TextSelectionPopup::Property::BACKGROUND_BORDER, visual );
853       visual.SetDepthIndex( DepthIndex::CONTENT );
854     }
855   }
856 }
857
858 TextSelectionPopup::TextSelectionPopup( TextSelectionPopupCallbackInterface* callbackInterface )
859 : Control( ControlBehaviour( CONTROL_BEHAVIOUR_DEFAULT ) ),
860   mToolbar(),
861   mPopupMaxSize(),
862   mOptionMaxSize(),
863   mOptionMinSize(),
864   mOptionDividerSize(),
865   mEnabledButtons( Toolkit::TextSelectionPopup::NONE ),
866   mCallbackInterface( callbackInterface ),
867   mPressedColor( DEFAULT_OPTION_PRESSED_COLOR ),
868   mDividerColor( Color::WHITE ),
869   mIconColor( Color::WHITE ),
870   mSelectOptionPriority( 1 ),
871   mSelectAllOptionPriority ( 2 ),
872   mCutOptionPriority ( 4 ),
873   mCopyOptionPriority ( 3 ),
874   mPasteOptionPriority ( 5 ),
875   mClipboardOptionPriority( 6 ),
876   mFadeInDuration(0.0f),
877   mFadeOutDuration(0.0f),
878   mShowIcons( false ),
879   mShowCaptions( true ),
880   mPopupShowing( false ),
881   mButtonsChanged( false )
882 {
883 }
884
885 TextSelectionPopup::~TextSelectionPopup()
886 {
887 }
888
889
890 } // namespace Internal
891
892 } // namespace Toolkit
893
894 } // namespace Dali