Add text selection popup style
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / text-controls / text-selection-popup-impl.h
1 #ifndef DALI_TOOLKIT_INTERNAL_TEXT_SELECTION_POPUP_H
2 #define DALI_TOOLKIT_INTERNAL_TEXT_SELECTION_POPUP_H
3
4 /*
5  * Copyright (c) 2021 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <dali/public-api/actors/layer.h>
23 #include <dali/public-api/object/property-map.h>
24 #include <string>
25
26 // INTERNAL INCLUDES
27 #include <dali-toolkit/devel-api/controls/control-devel.h>
28 #include <dali-toolkit/devel-api/controls/table-view/table-view.h>
29 #include <dali-toolkit/devel-api/controls/text-controls/text-selection-popup.h>
30 #include <dali-toolkit/devel-api/controls/text-controls/text-selection-toolbar.h>
31 #include <dali-toolkit/public-api/controls/buttons/push-button.h>
32 #include <dali-toolkit/public-api/controls/control-impl.h>
33 #include <dali-toolkit/public-api/controls/image-view/image-view.h>
34
35 namespace Dali
36 {
37 namespace Toolkit
38 {
39 namespace Internal
40 {
41 enum PopupCustomisations
42 {
43   POPUP_MAXIMUM_SIZE,
44   OPTION_MAXIMUM_SIZE,
45   OPTION_MINIMUM_SIZE,
46   OPTION_DIVIDER_SIZE
47 };
48
49 class TextSelectionPopup : public Control
50 {
51 public:
52   struct ButtonRequirement
53   {
54     ButtonRequirement()
55     : id(Toolkit::TextSelectionPopup::NONE),
56       priority(0u),
57       name(),
58       caption(),
59       enabled(false)
60     {
61     }
62
63     ButtonRequirement(Toolkit::TextSelectionPopup::Buttons buttonId,
64                       std::size_t                          buttonPriority,
65                       const std::string&                   buttonName,
66                       const std::string&                   buttonCaption,
67                       bool                                 buttonEnabled)
68     : id(buttonId),
69       priority(buttonPriority),
70       name(buttonName),
71       caption(buttonCaption),
72       enabled(buttonEnabled)
73     {
74     }
75
76     Toolkit::TextSelectionPopup::Buttons id;
77     std::size_t                          priority;
78     std::string                          name;
79     std::string                          caption;
80     bool                                 enabled;
81   };
82
83   struct ButtonPriorityCompare
84   {
85     bool operator()(const ButtonRequirement& lhs, const ButtonRequirement& rhs) const
86     {
87       return lhs.priority < rhs.priority;
88     }
89   };
90
91   /**
92    * @brief New constructor with provided buttons to enable.
93    * @param[in] callbackInterface The text popup callback interface which receives the button click callbacks.
94    * @return A handle to the TextSelectionPopup control.
95    */
96   static Toolkit::TextSelectionPopup New(TextSelectionPopupCallbackInterface* callbackInterface);
97
98   // Properties
99
100   /**
101    * @brief Called when a property of an object of this type is set.
102    * @param[in] object The object whose property is set.
103    * @param[in] index The property index.
104    * @param[in] value The new property value.
105    */
106   static void SetProperty(BaseObject* object, Property::Index index, const Property::Value& value);
107
108   /**
109    * @brief Called to retrieve a property of an object of this type.
110    *
111    * @param[in] object The object whose property is to be retrieved.
112    * @param[in] index The property index.
113    * @return The current value of the property.
114    */
115   static Property::Value GetProperty(BaseObject* object, Property::Index index);
116
117   /**
118    * @brief Toolkit::TextSelectionPopup::SetProperties()
119    */
120   void SetProperties(const Property::Map& properties);
121
122   /**
123    * @brief Toolkit::TextSelectionPopup::GetProperties()
124    */
125   void GetProperties(Property::Map& properties);
126
127   /**
128    * @copydoc Toolkit::EnableButtons
129    */
130   void EnableButtons(Toolkit::TextSelectionPopup::Buttons buttonsToEnable);
131
132   /**
133    * @copydoc Toolkit::TextSelectionPopup::RaiseAbove()
134    */
135   void RaiseAbove(Actor target);
136
137   /**
138    * @copydoc Toolkit::TextSelectionPopup::ShowPopup()
139    */
140   void ShowPopup();
141
142   /**
143    * @copydoc Toolkiut::TextSelectionPopup::HidePopup()
144    */
145   void HidePopup();
146
147 private: // From Control
148   /**
149    * @copydoc Control::OnInitialize()
150    */
151   void OnInitialize() override;
152
153   /**
154    * @copydoc Toolkit::Internal::Control::CreateAccessibleObject()
155    */
156   DevelControl::ControlAccessible* CreateAccessibleObject() override;
157
158 private: // Implementation
159   void HideAnimationFinished(Animation& animation);
160
161   /**
162    * @brief When the cut button is pressed.
163    * @param[in] button the button pressed
164    * @return @e true to consume the event.
165    */
166   bool OnCutButtonPressed(Toolkit::Button button);
167
168   /**
169    * @brief When the copy button is pressed.
170    * @param[in] button the button pressed
171    * @return @e true to consume the event.
172    */
173   bool OnCopyButtonPressed(Toolkit::Button button);
174
175   /**
176    * @brief When the paste button is pressed.
177    * @param[in] button the button pressed
178    * @return @e true to consume the event.
179    */
180   bool OnPasteButtonPressed(Toolkit::Button button);
181
182   /**
183    * @brief When the select button is pressed.
184    * @param[in] button the button pressed
185    * @return @e true to consume the event.
186    */
187   bool OnSelectButtonPressed(Toolkit::Button button);
188
189   /**
190    * @brief When the select all button is pressed.
191    * @param[in] button the button pressed
192    * @return @e true to consume the event.
193    */
194   bool OnSelectAllButtonPressed(Toolkit::Button button);
195
196   /**
197    * @brief When the clipboard button is pressed.
198    * @param[in] button the button pressed
199    * @return @e true to consume the event.
200    */
201   bool OnClipboardButtonPressed(Toolkit::Button button);
202
203   /**
204    * @brief Method to set the dimension or dimension constraint on certain aspects of the Popup.
205    *
206    * @param[in] settingToCustomise The setting for the PopupCustomisations enum that can be customised
207    * @param[in] dimension The size to customise with
208    */
209   void SetDimensionToCustomise(const PopupCustomisations& settingToCustomise, const Size& dimension);
210
211   /**
212    * @brief Method to get the dimension or dimension constraint on certain aspects of the Popup that was previously customised
213    *
214    * @param[in] setting The setting from the PopupCustomisations enum
215    */
216   Size GetDimensionToCustomise(const PopupCustomisations& setting) const;
217
218   /**
219    * @brief Sets the image for the given button of the Popup.
220    *
221    * @param[in] button  The button the image should be used for from the Buttons Enum.
222    * @param[in] image The image to use.
223    */
224   void SetButtonImage(Toolkit::TextSelectionPopup::Buttons button, const std::string& image);
225
226   /**
227    * @brief Retrieves the image of the given button used by the popup
228    *
229    * @param[in] button The button to get the image from
230    * @return The image used for that button.
231    */
232   const std::string& GetButtonImage(Toolkit::TextSelectionPopup::Buttons button) const;
233
234   /**
235    * @brief Sets the image for the pressed state of a popup option.
236    *
237    * @param[in]  filename The image filename to use.
238    */
239   void SetPressedImage(const std::string& filename);
240
241   /**
242    * @brief Gets the image used for the pressed state of a popup option.
243    *
244    * @return     The image filename used.
245    */
246   std::string GetPressedImage() const;
247
248   /**
249    * Set option divider padding
250    * @param[in] padding BEGIN END BOTTOM TOP
251    */
252   void SetOptionDividerPadding(const Padding& padding);
253
254   /**
255    * Get option divider padding
256    * @return Padding
257    */
258   Padding GetOptionDividerPadding() const;
259
260   /**
261    * Set label padding
262    * @param[in] padding BEGIN END BOTTOM TOP
263    */
264   void SetLabelPadding(const Padding& padding);
265
266   /**
267    * Get label padding
268    * @return Padding
269    */
270   Padding GetLabelPadding() const;
271
272   void CreateOrderedListOfPopupOptions();
273
274   void AddOption(const ButtonRequirement& button, bool showDivider, bool showIcons, bool showCaption);
275
276   std::size_t GetNumberOfEnabledOptions() const;
277
278   void AddPopupOptionsToToolbar(bool showIcons, bool showCaptions);
279
280   /**
281    * Creates the background-border image
282    *
283    * @param[in] propertyMap The properties describing the background-border
284    */
285   void CreateBackgroundBorder(Property::Map& propertyMap);
286
287   /**
288    * Creates the background image
289    *
290    * @param[in] propertyMap The properties describing the background
291    */
292   void CreateBackground(Property::Map& propertyMap);
293
294
295   /**
296    * Construct a new TextField.
297    */
298   TextSelectionPopup(TextSelectionPopupCallbackInterface* callbackInterface);
299
300   /**
301    * A reference counted object may only be deleted by calling Unreference()
302    */
303   virtual ~TextSelectionPopup();
304
305 protected:
306   struct PropertyHandler;
307
308   class TextSelectionPopupAccessible : public DevelControl::ControlAccessible
309   {
310   public:
311     using DevelControl::ControlAccessible::ControlAccessible;
312
313     /**
314      * @copydoc DevelControl::ControlAccessible::CalculateStates()
315      */
316     Dali::Accessibility::States CalculateStates() override;
317   };
318
319 private:
320   // Undefined copy constructor and assignment operators
321   TextSelectionPopup(const TextSelectionPopup&);
322   TextSelectionPopup& operator=(const TextSelectionPopup& rhs);
323
324 private: // Data
325   Dali::Toolkit::TextSelectionToolbar mToolbar;
326
327   Dali::Toolkit::TableView mTableOfButtons; // Actor which holds all the buttons, sensitivity can be set on buttons via this actor
328
329   // Images paths to be used by the Popup buttons
330   std::string mCutIconImage;
331   std::string mCopyIconImage;
332   std::string mPasteIconImage;
333   std::string mClipboardIconImage;
334   std::string mSelectIconImage;
335   std::string mSelectAllIconImage;
336
337   Size    mPopupMaxSize;         // Maximum size of the Popup
338   Size    mOptionMaxSize;        // Maximum size of an Option button
339   Size    mOptionMinSize;        // Minimum size of an Option button
340   Size    mOptionDividerSize;    // Size of divider line
341   Padding mOptionDividerPadding; // Padding of divider line
342
343   Vector2       mLabelMinimumSize; // Minimum size of label
344   Padding       mLabelPadding;     // Padding of label
345   Property::Map mLabelTextVisual;  // Text visual map of label
346   bool          mEnableScrollBar;  // Enable scrollbar
347
348   std::vector<ButtonRequirement> mOrderListOfButtons; // List of buttons in the order to be displayed and a flag to indicate if needed.
349
350   Toolkit::TextSelectionPopup::Buttons          mEnabledButtons; // stores enabled buttons
351   Toolkit::TextSelectionPopupCallbackInterface* mCallbackInterface;
352
353   std::string mPressedImage;        // Image used for the popup option when pressed.
354   Vector4     mPressedColor;        // Color of the popup option when pressed.
355   float       mPressedCornerRadius; // Corner radius of the popup option when pressed.
356   Vector4     mDividerColor;        // Color of the divider between buttons
357   Vector4     mIconColor;           // Color of the popup icon.
358
359   // Priority of Options/Buttons in the Cut and Paste pop-up, higher priority buttons are displayed first, left to right.
360   std::size_t mSelectOptionPriority;    // Position of Select Button
361   std::size_t mSelectAllOptionPriority; // Position of Select All button
362   std::size_t mCutOptionPriority;       // Position of Cut button
363   std::size_t mCopyOptionPriority;      // Position of Copy button
364   std::size_t mPasteOptionPriority;     // Position of Paste button
365   std::size_t mClipboardOptionPriority; // Position of Clipboard button
366   float       mFadeInDuration;          // Duration of the animation to fade in the Popup
367   float       mFadeOutDuration;         // Duration of the animation to fade out the Popup
368
369   bool mShowIcons : 1;      // Flag to show icons
370   bool mShowCaptions : 1;   // Flag to show text captions
371   bool mPopupShowing : 1;   // Flag to indicate Popup showing
372   bool mButtonsChanged : 1; // Flag to indicate the Popup Buttons have changed
373 };
374
375 } // namespace Internal
376
377 // Helpers for public-api forwarding methods
378
379 inline Toolkit::Internal::TextSelectionPopup& GetImpl(Toolkit::TextSelectionPopup& textSelectionPopup)
380 {
381   DALI_ASSERT_ALWAYS(textSelectionPopup);
382
383   Dali::RefObject& handle = textSelectionPopup.GetImplementation();
384
385   return static_cast<Toolkit::Internal::TextSelectionPopup&>(handle);
386 }
387
388 inline const Toolkit::Internal::TextSelectionPopup& GetImpl(const Toolkit::TextSelectionPopup& textSelectionPopup)
389 {
390   DALI_ASSERT_ALWAYS(textSelectionPopup);
391
392   const Dali::RefObject& handle = textSelectionPopup.GetImplementation();
393
394   return static_cast<const Toolkit::Internal::TextSelectionPopup&>(handle);
395 }
396
397 } // namespace Toolkit
398
399 } // namespace Dali
400
401 #endif // DALI_TOOLKIT_INTERNAL_TEXT_SELECTION_POPUP_H