[ElmSharp*] Add Scrollable interface
[platform/core/csapi/tizenfx.git] / src / ElmSharp / ElmSharp / Entry.cs
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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 using System;
18 using System.Collections.Generic;
19 using System.Runtime.InteropServices;
20
21 namespace ElmSharp
22 {
23     /// <summary>
24     /// Enumeration for describing InputPanel layout type.
25     /// </summary>
26     public enum InputPanelLayout
27     {
28         /// <summary>
29         /// InputPanel layout type default.
30         /// </summary>
31         Normal,
32
33         /// <summary>
34         /// InputPanel layout type number.
35         /// </summary>
36         Number,
37
38         /// <summary>
39         /// InputPanel layout type email.
40         /// </summary>
41         Email,
42
43         /// <summary>
44         /// InputPanel layout type url.
45         /// </summary>
46         Url,
47
48         /// <summary>
49         /// InputPanel layout type phone.
50         /// </summary>
51         PhoneNumber,
52
53         /// <summary>
54         /// InputPanel layout type ip.
55         /// </summary>
56         Ip,
57
58         /// <summary>
59         /// InputPanel layout type month.
60         /// </summary>
61         Month,
62
63         /// <summary>
64         /// InputPanel layout type number.
65         /// </summary>
66         NumberOnly,
67
68         /// <summary>
69         /// InputPanel layout type error type. Do not use it directly!
70         /// </summary>
71         Invalid,
72
73         /// <summary>
74         /// InputPanel layout type hexadecimal.
75         /// </summary>
76         Hex,
77
78         /// <summary>
79         /// InputPanel layout type terminal type, esc, alt, ctrl, etc.
80         /// </summary>
81         Terminal,
82
83         /// <summary>
84         /// InputPanel layout type password.
85         /// </summary>
86         Password,
87
88         /// <summary>
89         /// Keyboard layout type date and time.
90         /// </summary>
91         DateTime,
92
93         /// <summary>
94         /// InputPanel layout type emoticons.
95         /// </summary>
96         Emoticon
97     }
98
99     /// <summary>
100     /// Enumeration that defines the "Return" key types on the input panel (virtual keyboard).
101     /// </summary>
102     public enum InputPanelReturnKeyType
103     {
104         /// <summary>
105         /// Default key type
106         /// </summary>
107         Default,
108
109         /// <summary>
110         /// Done key type
111         /// </summary>
112         Done,
113
114         /// <summary>
115         /// Go key type
116         /// </summary>
117         Go,
118
119         /// <summary>
120         /// Join key type
121         /// </summary>
122         Join,
123
124         /// <summary>
125         /// Login key type
126         /// </summary>
127         Login,
128
129         /// <summary>
130         /// Next key type
131         /// </summary>
132         Next,
133
134         /// <summary>
135         /// Search string or magnifier icon key type
136         /// </summary>
137         Search,
138
139         /// <summary>
140         /// Send key type
141         /// </summary>
142         Send,
143
144         /// <summary>
145         /// Sign-in key type
146         /// </summary>
147         Signin
148     }
149
150     /// <summary>
151     /// Enumeration that defines the autocapitalization types.
152     /// </summary>
153     public enum AutoCapital
154     {
155         /// <summary>
156         /// No autocapitalization when typing
157         /// </summary>
158         None,
159
160         /// <summary>
161         /// Autocapitalize each typed word
162         /// </summary>
163         Word,
164
165         /// <summary>
166         /// Autocapitalize the start of each sentence
167         /// </summary>
168         Sentence,
169
170         /// <summary>
171         /// Autocapitalize all letters
172         /// </summary>
173         All
174     }
175
176     /// <summary>
177     /// Enumeration that defines the entry's copy and paste policy.
178     /// </summary>
179     public enum CopyAndPasteMode
180     {
181         /// <summary>
182         /// Copy and paste text with markup tag
183         /// </summary>
184         Markup,
185
186         /// <summary>
187         /// Copy and paste text without item(image) tag
188         /// </summary>
189         NoImage,
190
191         /// <summary>
192         /// Copy and paste text without markup tag
193         /// </summary>
194         PlainText
195     }
196
197     /// <summary>
198     /// Enumeration that defines the text format types.
199     /// </summary>
200     public enum TextFormat
201     {
202         /// <summary>
203         /// Plain type
204         /// </summary>
205         Plain,
206
207         /// <summary>
208         /// Markup type
209         /// </summary>
210         Markup
211     }
212
213     /// <summary>
214     /// Enumeration that defines the types of Input Hints.
215     /// </summary>
216     public enum InputHints
217     {
218         /// <summary>
219         /// No active hints
220         /// </summary>
221         None,
222
223         /// <summary>
224         /// suggest word auto completion
225         /// </summary>
226         AutoComplete,
227
228         /// <summary>
229         /// typed text should not be stored.
230         /// </summary>
231         SensitiveData,
232     }
233
234     /// <summary>
235     /// Enumeration that defines the input panel (virtual keyboard) language modes.
236     /// </summary>
237     public enum InputPanelLanguage
238     {
239         /// <summary>
240         /// Automatic language mode
241         /// </summary>
242         Automatic,
243
244         /// <summary>
245         /// Alphabet language mode
246         /// </summary>
247         Alphabet,
248     }
249
250     /// <summary>
251     /// The entry is a convenience widget that shows a box in which the user can enter text.
252     /// </summary>
253     public class Entry : Layout, IScrollable
254     {
255         ScrollableAdapter _scroller;
256         SmartEvent _clicked;
257         SmartEvent _changedByUser;
258         SmartEvent _cursorChanged;
259         SmartEvent _activated;
260
261         Dictionary<Func<string, EvasObject>, Interop.Elementary.Elm_Entry_Item_Provider_Cb> _itemsProvider = new Dictionary<Func<string, EvasObject>, Interop.Elementary.Elm_Entry_Item_Provider_Cb>();
262         Dictionary<Func<Entry, string, string>, Interop.Elementary.Elm_Entry_Filter_Cb> _textFilters = new Dictionary<Func<Entry, string, string>, Interop.Elementary.Elm_Entry_Filter_Cb>();
263
264         /// <summary>
265         /// Creates and initializes a new instance of the Entry class.
266         /// </summary>
267         /// <param name="parent">The EvasObject to which the new Entry will be attached as a child.</param>
268         public Entry(EvasObject parent) : base(parent)
269         {
270             _clicked = new SmartEvent(this, this.RealHandle, "clicked");
271             _clicked.On += (s, e) => Clicked?.Invoke(this, EventArgs.Empty);
272
273             _changedByUser = new SmartEvent(this, this.RealHandle, "changed,user");
274             _changedByUser.On += (s, e) => ChangedByUser?.Invoke(this, EventArgs.Empty);
275
276             _cursorChanged = new SmartEvent(this, this.RealHandle, "cursor,changed");
277             _cursorChanged.On += (s, e) => CursorChanged?.Invoke(this, EventArgs.Empty);
278
279             _activated = new SmartEvent(this, this.RealHandle, "activated");
280             _activated.On += (s, e) => Activated?.Invoke(this, EventArgs.Empty);
281
282             _scroller = new ScrollableAdapter(this);
283         }
284
285         /// <summary>
286         /// Activated will be triggered when the entry in Activated stated.
287         /// </summary>
288         public event EventHandler Activated;
289
290         /// <summary>
291         /// Clicked will be triggered when the entry is clicked.
292         /// </summary>
293         public event EventHandler Clicked;
294
295         /// <summary>
296         /// ChangedByUser will be triggered when the entry changed by user.
297         /// </summary>
298         public event EventHandler ChangedByUser;
299
300         /// <summary>
301         /// CursorChanged will be triggered when the Cursor in the entry is changed.
302         /// </summary>
303         public event EventHandler CursorChanged;
304
305         /// <summary>
306         /// Sets or gets the entry to the single line mode.
307         /// </summary>
308         public bool IsSingleLine
309         {
310             get
311             {
312                 return Interop.Elementary.elm_entry_single_line_get(RealHandle);
313             }
314             set
315             {
316                 Interop.Elementary.elm_entry_single_line_set(RealHandle, value);
317             }
318         }
319
320         /// <summary>
321         /// Sets or gets the entry to the password mode.
322         /// </summary>
323         public bool IsPassword
324         {
325             get
326             {
327                 return Interop.Elementary.elm_entry_password_get(RealHandle);
328             }
329             set
330             {
331                 Interop.Elementary.elm_entry_password_set(RealHandle, value);
332             }
333         }
334
335         /// <summary>
336         /// Sets or gets whether the entry is editable.
337         /// </summary>
338         public bool IsEditable
339         {
340             get
341             {
342                 return Interop.Elementary.elm_entry_editable_get(RealHandle);
343             }
344             set
345             {
346                 Interop.Elementary.elm_entry_editable_set(RealHandle, value);
347             }
348         }
349
350         /// <summary>
351         /// Sets or gets whether the entry is empty.
352         /// </summary>
353         public bool IsEmpty
354         {
355             get
356             {
357                 return Interop.Elementary.elm_entry_is_empty(RealHandle);
358             }
359         }
360
361         /// <summary>
362         /// Sets or gets text currently shown in the object entry.
363         /// </summary>
364         public override string Text
365         {
366             get
367             {
368                 return Interop.Elementary.elm_entry_entry_get(RealHandle);
369             }
370             set
371             {
372                 Interop.Elementary.elm_entry_entry_set(RealHandle, value);
373             }
374         }
375
376         /// <summary>
377         /// Sets or gets the style on the top of the user style stack.
378         /// </summary>
379         /// <remarks>If there is styles in the user style stack, the properties in the top style of user style stack will replace the properties in current theme. The input style is specified in format tag='property=value' (i.e. DEFAULT='font=Sans font_size=60'hilight=' + font_weight=Bold').</remarks>
380         public string TextStyle
381         {
382             get
383             {
384                 return Interop.Elementary.elm_entry_text_style_user_peek(RealHandle);
385             }
386             set
387             {
388                 Interop.Elementary.elm_entry_text_style_user_push(RealHandle, value);
389             }
390         }
391
392         /// <summary>
393         /// Sets or gets the current position of the cursor in the entry.
394         /// </summary>
395         public int CursorPosition
396         {
397             get
398             {
399                 return Interop.Elementary.elm_entry_cursor_pos_get(RealHandle);
400             }
401             set
402             {
403                 Interop.Elementary.elm_entry_cursor_pos_set(RealHandle, value);
404             }
405         }
406
407         /// <summary>
408         /// Sets or gets the scrollable state of the entry.
409         /// </summary>
410         public bool Scrollable
411         {
412             get
413             {
414                 return Interop.Elementary.elm_entry_scrollable_get(RealHandle);
415             }
416             set
417             {
418                 // HACK: Enabling the scrollable property of an entry causes its internal
419                 //       hierarchy to change, making the internal edje object inaccessible.
420                 //       Access it before the property is set, to cache the edje object's handle.
421                 if (value)
422                 {
423                     var dummy = EdjeObject;
424                 }
425                 Interop.Elementary.elm_entry_scrollable_set(RealHandle, value);
426             }
427         }
428
429         /// <summary>
430         /// Sets or Gets the autocapitalization type on the immodule.
431         /// </summary>
432         public AutoCapital AutoCapital
433         {
434             get
435             {
436                 return (AutoCapital)Interop.Elementary.elm_entry_autocapital_type_get(RealHandle);
437             }
438             set
439             {
440                 Interop.Elementary.elm_entry_autocapital_type_set(RealHandle, (Interop.Elementary.AutocapitalType)value);
441             }
442         }
443
444         /// <summary>
445         /// Sets or Gets the entry object's 'autosave' status.
446         /// </summary>
447         public bool IsAutoSave
448         {
449             get
450             {
451                 return Interop.Elementary.elm_entry_autosave_get(RealHandle);
452             }
453             set
454             {
455                 Interop.Elementary.elm_entry_autosave_set(RealHandle, value);
456             }
457         }
458
459         /// <summary>
460         /// Sets or Gets entry text paste/drop mode.
461         /// </summary>
462         public CopyAndPasteMode CopyAndPasteMode
463         {
464             get
465             {
466                 return (CopyAndPasteMode)Interop.Elementary.elm_entry_cnp_mode_get(RealHandle);
467             }
468             set
469             {
470                 Interop.Elementary.elm_entry_cnp_mode_set(RealHandle, (Interop.Elementary.CopyAndPasteMode)value);
471             }
472         }
473
474         /// <summary>
475         /// Gets the geometry of the cursor.
476         /// </summary>
477         public Rect CursorGeometry
478         {
479             get
480             {
481                 int x, y, w, h;
482                 Interop.Elementary.elm_entry_cursor_geometry_get(RealHandle, out x, out y, out w, out h);
483                 return new Rect(x, y, w, h);
484             }
485         }
486
487         /// <summary>
488         /// Gets whether a format node exists at the current cursor position.
489         /// </summary>
490         public bool IsCursorFormat
491         {
492             get
493             {
494                 return Interop.Elementary.elm_entry_cursor_is_format_get(RealHandle);
495             }
496         }
497
498         /// <summary>
499         /// Gets if the current cursor position holds a visible format node.
500         /// </summary>
501         public bool IsCursorVisibelFormat
502         {
503             get
504             {
505                 return Interop.Elementary.elm_entry_cursor_is_visible_format_get(RealHandle);
506             }
507         }
508
509         /// <summary>
510         /// Sets or Gets the value of input hint.
511         /// </summary>
512         public InputHints InputHint
513         {
514             get
515             {
516                 return (InputHints)Interop.Elementary.elm_entry_input_hint_get(RealHandle);
517             }
518             set
519             {
520                 Interop.Elementary.elm_entry_input_hint_set(RealHandle, (Interop.Elementary.InputHints)value);
521             }
522         }
523
524         /// <summary>
525         ///  Sets or gets the language mode of the input panel.
526         /// </summary>
527         public InputPanelLanguage InputPanelLanguage
528         {
529             get
530             {
531                 return (InputPanelLanguage)Interop.Elementary.elm_entry_input_panel_language_get(RealHandle);
532             }
533             set
534             {
535                 Interop.Elementary.elm_entry_input_panel_language_set(RealHandle, (Interop.Elementary.InputPanelLanguage)value);
536             }
537         }
538
539         /// <summary>
540         /// Sets or gets the input panel layout variation of the entry.
541         /// </summary>
542         public int InputPanelVariation
543         {
544             get
545             {
546                 return Interop.Elementary.elm_entry_input_panel_layout_variation_get(RealHandle);
547             }
548             set
549             {
550                 Interop.Elementary.elm_entry_input_panel_layout_variation_set(RealHandle, value);
551             }
552         }
553
554         /// <summary>
555         /// Sets or gets the line wrap type to use on multi-line entries.
556         /// </summary>
557         public WrapType LineWrapType
558         {
559             get
560             {
561                 return (WrapType)Interop.Elementary.elm_entry_line_wrap_get(RealHandle);
562             }
563             set
564             {
565                 Interop.Elementary.elm_entry_line_wrap_set(RealHandle, (Interop.Elementary.WrapType)value);
566             }
567         }
568
569         /// <summary>
570         /// Sets or gets whether the entry should allow to use the text prediction.
571         /// </summary>
572         public bool PredictionAllowed
573         {
574             get
575             {
576                 return Interop.Elementary.elm_entry_prediction_allow_get(RealHandle);
577             }
578             set
579             {
580                 Interop.Elementary.elm_entry_prediction_allow_set(RealHandle, value);
581             }
582         }
583
584         /// <summary>
585         /// Sets or gets whether the return key on the input panel should be disabled or not.
586         /// </summary>
587         public bool InputPanelReturnKeyDisabled
588         {
589             get
590             {
591                 return Interop.Elementary.elm_entry_input_panel_return_key_disabled_get(RealHandle);
592             }
593             set
594             {
595                 Interop.Elementary.elm_entry_input_panel_return_key_disabled_set(RealHandle, value);
596             }
597         }
598
599         /// <summary>
600         /// Sets or gets the attribute to show the input panel in case of only an user's explicit Mouse Up event.
601         /// It doesn't request to show the input panel even though it has focus.
602         /// If true, the input panel will be shown in case of only Mouse up event. (Focus event will be ignored.)
603         /// </summary>
604         public bool InputPanelShowByOnDemand
605         {
606             get
607             {
608                 return Interop.Elementary.elm_entry_input_panel_show_on_demand_get(RealHandle);
609             }
610             set
611             {
612                 Interop.Elementary.elm_entry_input_panel_show_on_demand_set(RealHandle, value);
613             }
614         }
615
616         /// <summary>
617         /// Sets the file (and implicitly loads it) for the text to display and then edit.
618         /// </summary>
619         /// <param name="file">The path to the file to load and save</param>
620         /// <param name="textFormat">The file format</param>
621         public void SetFile(string file, TextFormat textFormat)
622         {
623             Interop.Elementary.elm_entry_file_set(RealHandle, file, (Interop.Elementary.TextFormat)textFormat);
624         }
625
626         /// <summary>
627         /// Converts a markup (HTML-like) string into UTF-8.
628         /// </summary>
629         /// <param name="markup">The string (in markup) to be converted</param>
630         /// <returns>The converted string (in UTF-8) </returns>
631         public static string ConvertMarkupToUtf8(string markup)
632         {
633             return Interop.Elementary.elm_entry_markup_to_utf8(markup);
634         }
635
636         /// <summary>
637         /// Moves the cursor by one position to the right within the entry.
638         /// </summary>
639         /// <returns></returns>
640         public bool MoveCursorNext()
641         {
642             return Interop.Elementary.elm_entry_cursor_next(RealHandle);
643         }
644
645         /// <summary>
646         /// Moves the cursor one place to the left within the entry.
647         /// </summary>
648         /// <returns>TRUE on success, otherwise FALSE on failure</returns>
649         public bool MoveCursorPrev()
650         {
651             return Interop.Elementary.elm_entry_cursor_prev(RealHandle);
652         }
653
654         /// <summary>
655         /// Moves the cursor one line up within the entry.
656         /// </summary>
657         /// <returns>TRUE on success, otherwise FALSE on failure</returns>
658         public bool MoveCursorUp()
659         {
660             return Interop.Elementary.elm_entry_cursor_up(RealHandle);
661         }
662
663         /// <summary>
664         /// Moves the cursor one line down within the entry.
665         /// </summary>
666         /// <returns>TRUE on success, otherwise FALSE on failure</returns>
667         public bool MoveCursorDown()
668         {
669             return Interop.Elementary.elm_entry_cursor_down(RealHandle);
670         }
671
672         /// <summary>
673         /// Moves the cursor to the beginning of the entry.
674         /// </summary>
675         public void MoveCursorBegin()
676         {
677             Interop.Elementary.elm_entry_cursor_begin_set(RealHandle);
678         }
679
680         /// <summary>
681         /// Moves the cursor to the end of the entry.
682         /// </summary>
683         public void MoveCursorEnd()
684         {
685             Interop.Elementary.elm_entry_cursor_end_set(RealHandle);
686         }
687
688         /// <summary>
689         /// Moves the cursor to the beginning of the current line.
690         /// </summary>
691         public void MoveCursorLineBegin()
692         {
693             Interop.Elementary.elm_entry_cursor_line_begin_set(RealHandle);
694         }
695
696         /// <summary>
697         /// Moves the cursor to the end of the current line.
698         /// </summary>
699         public void MoveCursorLineEnd()
700         {
701             Interop.Elementary.elm_entry_cursor_line_end_set(RealHandle);
702         }
703
704         /// <summary>
705         /// Sets the input panel layout of the entry.
706         /// </summary>
707         /// <param name="layout">The layout type</param>
708         public void SetInputPanelLayout(InputPanelLayout layout)
709         {
710             Interop.Elementary.elm_entry_input_panel_layout_set(RealHandle, (Interop.Elementary.InputPanelLayout)layout);
711         }
712
713         /// <summary>
714         /// Sets the attribute to show the input panel automatically.
715         /// </summary>
716         /// <param name="enabled">If true the input panel appears when the entry is clicked or has focus, otherwise false</param>
717         public void SetInputPanelEnabled(bool enabled)
718         {
719             Interop.Elementary.elm_entry_input_panel_enabled_set(RealHandle, enabled);
720         }
721
722         /// <summary>
723         /// Sets the "return" key type. This type is used to set the string or icon on the "return" key of the input panel.
724         /// </summary>
725         /// <param name="keyType">The type of "return" key on the input panel</param>
726         public void SetInputPanelReturnKeyType(InputPanelReturnKeyType keyType)
727         {
728             Interop.Elementary.elm_entry_input_panel_return_key_type_set(RealHandle, (Interop.Elementary.ReturnKeyType)keyType);
729         }
730
731         /// <summary>
732         /// Hides the input panel (virtual keyboard).
733         /// </summary>
734         /// <remarks>
735         /// Note that the input panel is shown or hidden automatically according to the focus state of the entry widget.
736         /// This API can be used in case of manually controlling by using SetInputPanelEnabled(false).
737         /// </remarks>
738         public void HideInputPanel()
739         {
740             Interop.Elementary.elm_entry_input_panel_hide(RealHandle);
741         }
742
743         /// <summary>
744         /// Selects all the text within the entry.
745         /// </summary>
746         public void SelectAll()
747         {
748             Interop.Elementary.elm_entry_select_all(RealHandle);
749         }
750
751         /// <summary>
752         /// Drops any existing text selection within the entry.
753         /// </summary>
754         public void SelectNone()
755         {
756             Interop.Elementary.elm_entry_select_none(RealHandle);
757         }
758
759         /// <summary>
760         /// Forces calculation of the entry size and text layouting.
761         /// </summary>
762         public void ForceCalculation()
763         {
764             Interop.Elementary.elm_entry_calc_force(RealHandle);
765         }
766
767         /// <summary>
768         /// Gets the string by the cursor at its current position.
769         /// </summary>
770         /// <returns></returns>
771         public string GetCursorContent()
772         {
773             return Interop.Elementary.elm_entry_cursor_content_get(RealHandle);
774         }
775
776         /// <summary>
777         /// Begins a selection within the entry as though the user were holding down the mouse button to make a selection.
778         /// </summary>
779         public void BeginCursorSelection()
780         {
781             Interop.Elementary.elm_entry_cursor_selection_begin(RealHandle);
782         }
783
784         /// <summary>
785         /// Appends the text of the entry.
786         /// </summary>
787         /// <param name="text">The text to be displayed</param>
788         public void AppendText(string text)
789         {
790             Interop.Elementary.elm_entry_entry_append(RealHandle, text);
791         }
792
793         /// <summary>
794         /// Inserts the given text into the entry at the current cursor position.
795         /// </summary>
796         /// <param name="text"></param>
797         public void InsertTextToCursor(string text)
798         {
799             Interop.Elementary.elm_entry_entry_insert(RealHandle, text);
800         }
801
802         /// <summary>
803         /// Ends a selection within the entry as though the user had just released the mouse button while making a selection.
804         /// </summary>
805         public void EndCursorSelection()
806         {
807             Interop.Elementary.elm_entry_cursor_selection_end(RealHandle);
808         }
809
810         /// <summary>
811         /// Writes any changes made to the file that is set by File.
812         /// </summary>
813         public void SaveFile()
814         {
815             Interop.Elementary.elm_entry_file_save(RealHandle);
816         }
817
818         /// <summary>
819         /// Show the input panel (virtual keyboard) based on the input panel property of entry such as layout, autocapital types, and so on.
820         /// </summary>
821         /// <remarks>
822         /// Note that input panel is shown or hidden automatically according to the focus state of entry widget.
823         /// This API can be used in the case of manually controlling by using SetInputPanelEnabled(false).
824         /// </remarks>
825         public void ShowInputPanel()
826         {
827             Interop.Elementary.elm_entry_input_panel_show(RealHandle);
828         }
829
830         /// <summary>
831         /// This appends a custom item provider to the list for that entry.
832         /// </summary>
833         /// <param name="func">This function is used to provide items.</param>
834         public void AppendItemProvider(Func<string, EvasObject> func)
835         {
836             if (func != null)
837             {
838                 if (!_itemsProvider.ContainsKey(func))
839                 {
840                     Interop.Elementary.Elm_Entry_Item_Provider_Cb itemProviderCallback;
841
842                     itemProviderCallback = (d, o, t) =>
843                     {
844                         return func?.Invoke(t);
845                     };
846                     Interop.Elementary.elm_entry_item_provider_append(RealHandle, itemProviderCallback, IntPtr.Zero);
847                     _itemsProvider.Add(func, itemProviderCallback);
848                 }
849             }
850         }
851
852         /// <summary>
853         /// This prepends a custom item provider to the list for that entry.
854         /// </summary>
855         /// <param name="func">This function is used to provide items.</param>
856         public void PrependItemProvider(Func<string, EvasObject> func)
857         {
858             if (!_itemsProvider.ContainsKey(func))
859             {
860                 Interop.Elementary.Elm_Entry_Item_Provider_Cb itemProviderCallback;
861
862                 itemProviderCallback = (d, o, t) =>
863                 {
864                     return func?.Invoke(t);
865                 };
866                 Interop.Elementary.elm_entry_item_provider_prepend(RealHandle, itemProviderCallback, IntPtr.Zero);
867                 _itemsProvider.Add(func, itemProviderCallback);
868             }
869         }
870
871         /// <summary>
872         /// This removes a custom item provider to the list for that entry.
873         /// </summary>
874         /// <param name="func">This function is used to provide items.</param>
875         public void RemoveItemProvider(Func<string, EvasObject> func)
876         {
877             if (_itemsProvider.ContainsKey(func))
878             {
879                 Interop.Elementary.Elm_Entry_Item_Provider_Cb itemProviderCallback;
880                 _itemsProvider.TryGetValue(func, out itemProviderCallback);
881
882                 Interop.Elementary.elm_entry_item_provider_remove(RealHandle, itemProviderCallback, IntPtr.Zero);
883                 _itemsProvider.Remove(func);
884             }
885         }
886
887         /// <summary>
888         /// Append a markup filter function for text inserted in the entry.
889         /// </summary>
890         /// <param name="filter">This function type is used by entry filters to modify text.</param>
891         public void AppendMarkUpFilter(Func<Entry, string, string> filter)
892         {
893             if (!_textFilters.ContainsKey(filter))
894             {
895                 Interop.Elementary.Elm_Entry_Filter_Cb textFilterCallback = (IntPtr d, IntPtr e, ref IntPtr t) =>
896                 {
897                     var text = Marshal.PtrToStringAnsi(t);
898
899                     var updateText = filter(this, text);
900
901                     if (updateText != text)
902                     {
903                         Interop.Libc.Free(t);
904                         t = Marshal.StringToHGlobalAnsi(updateText);
905                     }
906                 };
907                 Interop.Elementary.elm_entry_markup_filter_append(RealHandle, textFilterCallback, IntPtr.Zero);
908                 _textFilters.Add(filter, textFilterCallback);
909             }
910         }
911
912         /// <summary>
913         /// Prepend a markup filter function for text inserted in the entry.
914         /// </summary>
915         /// <param name="filter">This function type is used by entry filters to modify text.</param>
916         public void PrependMarkUpFilter(Func<Entry, string, string> filter)
917         {
918             if (!_textFilters.ContainsKey(filter))
919             {
920                 Interop.Elementary.Elm_Entry_Filter_Cb textFilterCallback = (IntPtr d, IntPtr e, ref IntPtr t) =>
921                 {
922                     var text = Marshal.PtrToStringAnsi(t);
923
924                     var updateText = filter(this, text);
925
926                     if (updateText != text)
927                     {
928                         Interop.Libc.Free(t);
929                         t = Marshal.StringToHGlobalAnsi(updateText);
930                     }
931                 };
932                 Interop.Elementary.elm_entry_markup_filter_prepend(RealHandle, textFilterCallback, IntPtr.Zero);
933                 _textFilters.Add(filter, textFilterCallback);
934             }
935         }
936
937         /// <summary>
938         /// Remove a markup filter
939         /// </summary>
940         /// <param name="filter">This function type is used by entry filters to modify text.</param>
941         public void RemoveMarkUpFilter(Func<Entry, string, string> filter)
942         {
943             if (_textFilters.ContainsKey(filter))
944             {
945                 Interop.Elementary.Elm_Entry_Filter_Cb textFilterCallback;
946                 _textFilters.TryGetValue(filter, out textFilterCallback);
947
948                 Interop.Elementary.elm_entry_markup_filter_remove(RealHandle, textFilterCallback, IntPtr.Zero);
949                 _textFilters.Remove(filter);
950             }
951         }
952
953         /// <summary>
954         /// This executes a "copy" action on the selected text in the entry.
955         /// </summary>
956         public void CopySelection()
957         {
958             Interop.Elementary.elm_entry_selection_copy(RealHandle);
959         }
960
961         /// <summary>
962         /// This executes a "cut" action on the selected text in the entry.
963         /// </summary>
964         public void CutSelection()
965         {
966             Interop.Elementary.elm_entry_selection_cut(RealHandle);
967         }
968
969         /// <summary>
970         /// This executes a "paste" action in the entry.
971         /// </summary>
972         public void PasteSelection()
973         {
974             Interop.Elementary.elm_entry_selection_paste(RealHandle);
975         }
976
977         /// <summary>
978         /// This disabled the entry's selection.
979         /// </summary>
980         /// <param name="disable">If true, the selection are disabled.</param>
981         public void DisableSelection(bool disable)
982         {
983             Interop.Elementary.elm_entry_selection_handler_disabled_set(RealHandle, disable);
984         }
985
986         /// <summary>
987         /// Get any selected text within the entry.
988         /// </summary>
989         /// <returns>Selection's value</returns>
990         public string GetSelection()
991         {
992             return Interop.Elementary.elm_entry_selection_get(RealHandle);
993         }
994
995         /// <summary>
996         /// This selects a region of text within the entry.
997         /// </summary>
998         /// <param name="start">The starting position.</param>
999         /// <param name="end">The end position.</param>
1000         public void SetSelectionRegion(int start, int end)
1001         {
1002             Interop.Elementary.elm_entry_select_region_set(RealHandle, start, end);
1003         }
1004
1005         /// <summary>
1006         /// Sets the visibility of the left-side widget of the entry
1007         /// </summary>
1008         /// <param name="isDisplay">true if the object should be displayed, false if not.</param>
1009         public void SetIconVisible(bool isDisplay)
1010         {
1011             Interop.Elementary.elm_entry_icon_visible_set(RealHandle, isDisplay);
1012         }
1013
1014         /// <summary>
1015         /// Set whether the return key on the input panel is disabled automatically when entry has no text.
1016         /// </summary>
1017         /// <param name="enable">If enabled is true, the return key is automatically disabled when the entry has no text.</param>
1018         public void SetInputPanelReturnKeyAutoEnable(bool enable)
1019         {
1020             Interop.Elementary.elm_entry_input_panel_return_key_autoenabled_set(RealHandle, enable);
1021         }
1022
1023         /// <summary>
1024         /// Creates a widget handle.
1025         /// </summary>
1026         /// <param name="parent">Parent EvasObject</param>
1027         /// <returns>Handle IntPtr</returns>
1028         protected override IntPtr CreateHandle(EvasObject parent)
1029         {
1030             return Interop.Elementary.elm_entry_add(parent.Handle);
1031         }
1032
1033         #region IScroller Implementation
1034
1035         /// <summary>
1036         /// Scrolled will be triggered when the content has been scrolled.
1037         /// </summary>
1038         public event EventHandler Scrolled
1039         {
1040             add => _scroller.Scrolled += value;
1041             remove => _scroller.Scrolled -= value;
1042         }
1043
1044         /// <summary>
1045         /// DragStart will be triggered when dragging the contents around has started.
1046         /// </summary>
1047         public event EventHandler DragStart
1048         {
1049             add => _scroller.DragStart += value;
1050             remove => _scroller.DragStart -= value;
1051         }
1052
1053         /// <summary>
1054         /// DragStop will be triggered when dragging the contents around has stopped.
1055         /// </summary>
1056         public event EventHandler DragStop
1057         {
1058             add => _scroller.DragStop += value;
1059             remove => _scroller.DragStop -= value;
1060         }
1061
1062         /// <summary>
1063         /// PageScrolled will be triggered when the visible page has changed.
1064         /// </summary>
1065         public event EventHandler PageScrolled
1066         {
1067             add => _scroller.PageScrolled += value;
1068             remove => _scroller.PageScrolled -= value;
1069         }
1070
1071         /// <summary>
1072         /// Gets the current region in the content object that is visible through the Scroller.
1073         /// </summary>
1074         public Rect CurrentRegion => _scroller.CurrentRegion;
1075
1076         /// <summary>
1077         /// Sets or gets the value of HorizontalScrollBarVisiblePolicy
1078         /// </summary>
1079         /// <remarks>
1080         /// ScrollBarVisiblePolicy.Auto means the horizontal scrollbar is made visible if it is needed, and otherwise kept hidden.
1081         /// ScrollBarVisiblePolicy.Visible turns it on all the time, and ScrollBarVisiblePolicy.Invisible always keeps it off.
1082         /// </remarks>
1083         public virtual ScrollBarVisiblePolicy HorizontalScrollBarVisiblePolicy
1084         {
1085             get => _scroller.HorizontalScrollBarVisiblePolicy;
1086             set => _scroller.HorizontalScrollBarVisiblePolicy = value;
1087         }
1088
1089         /// <summary>
1090         /// Sets or gets the value of VerticalScrollBarVisiblePolicy
1091         /// </summary>
1092         /// <remarks>
1093         /// ScrollBarVisiblePolicy.Auto means the vertical scrollbar is made visible if it is needed, and otherwise kept hidden.
1094         /// ScrollBarVisiblePolicy.Visible turns it on all the time, and ScrollBarVisiblePolicy.Invisible always keeps it off.
1095         /// </remarks>
1096         public virtual ScrollBarVisiblePolicy VerticalScrollBarVisiblePolicy
1097         {
1098             get => _scroller.VerticalScrollBarVisiblePolicy;
1099             set => _scroller.VerticalScrollBarVisiblePolicy = value;
1100         }
1101
1102         /// <summary>
1103         /// Sets or gets the value of ScrollBlock.
1104         /// </summary>
1105         /// <remarks>
1106         /// This function will block scrolling movement  in a given direction.One can disable movements in the X axis, the Y axis or both.
1107         /// The default value is ScrollBlock.None, where movements are allowed in both directions.
1108         /// </remarks>
1109         public ScrollBlock ScrollBlock
1110         {
1111             get => _scroller.ScrollBlock;
1112             set => _scroller.ScrollBlock = value;
1113         }
1114
1115         /// <summary>
1116         /// Sets or gets scroll current page number.
1117         /// </summary>
1118         /// <remarks>
1119         /// Current page means the page which meets the top of the viewport.
1120         /// If there are two or more pages in the viewport, it returns the number of the page which meets the top of the viewport.
1121         /// The page number starts from 0. 0 is the first page.
1122         /// </remarks>
1123         public int VerticalPageIndex => _scroller.VerticalPageIndex;
1124
1125         /// <summary>
1126         /// Sets or gets scroll current page number.
1127         /// </summary>
1128         /// <remarks>
1129         /// Current page means the page which meets the left of the viewport.
1130         /// If there are two or more pages in the viewport, it returns the number of the page which meets the left of the viewport.
1131         /// The page number starts from 0. 0 is the first page.
1132         /// </remarks>
1133         public int HorizontalPageIndex => _scroller.HorizontalPageIndex;
1134
1135         /// <summary>
1136         /// Sets or gets the maximum limit of the movable page at vertical direction.
1137         /// </summary>
1138         public int VerticalPageScrollLimit
1139         {
1140             get => _scroller.VerticalPageScrollLimit;
1141             set => _scroller.VerticalPageScrollLimit = value;
1142         }
1143
1144         /// <summary>
1145         /// Sets or gets the maximum limit of the movable page at horizontal direction.
1146         /// </summary>
1147         public int HorizontalPageScrollLimit
1148         {
1149             get => _scroller.HorizontalPageScrollLimit;
1150             set => _scroller.HorizontalPageScrollLimit = value;
1151         }
1152
1153         /// <summary>
1154         /// Sets or gets the vertical bounce behaviour.
1155         /// When scrolling, the scroller may "bounce" when reaching an edge of the content object.
1156         /// This is a visual way to indicate the end has been reached.
1157         /// This is enabled by default for both axis.
1158         /// This API will set if it is enabled for the given axis with the boolean parameters for each axis.
1159         /// </summary>
1160         public bool VerticalBounce
1161         {
1162             get => _scroller.VerticalBounce;
1163             set => _scroller.VerticalBounce = value;
1164         }
1165
1166         /// <summary>
1167         /// Sets or gets the horizontal bounce behaviour.
1168         /// When scrolling, the scroller may "bounce" when reaching an edge of the content object.
1169         /// This is a visual way to indicate the end has been reached.
1170         /// This is enabled by default for both axis.
1171         /// This API will set if it is enabled for the given axis with the boolean parameters for each axis.
1172         /// </summary>
1173         public bool HorizontalBounce
1174         {
1175             get => _scroller.HorizontalBounce;
1176             set => _scroller.HorizontalBounce = value;
1177         }
1178
1179         /// <summary>
1180         /// Gets the width of the content object of the scroller.
1181         /// </summary>
1182         public int ChildWidth
1183         {
1184             get => _scroller.ChildWidth;
1185         }
1186
1187         /// <summary>
1188         /// Gets the height of the content object of the scroller.
1189         /// </summary>
1190         public int ChildHeight
1191         {
1192             get => _scroller.ChildHeight;
1193         }
1194
1195         /// <summary>
1196         /// Set scrolling gravity values for a scroller.
1197         /// The gravity, defines how the scroller will adjust its view when the size of the scroller contents increase.
1198         /// The scroller will adjust the view to glue itself as follows.
1199         /// x=0.0, for staying where it is relative to the left edge of the content x=1.0, for staying where it is relative to the rigth edge of the content y=0.0, for staying where it is relative to the top edge of the content y=1.0, for staying where it is relative to the bottom edge of the content
1200         /// Default values for x and y are 0.0
1201         /// </summary>
1202         public double HorizontalGravity
1203         {
1204             get => _scroller.HorizontalGravity;
1205             set => _scroller.HorizontalGravity = value;
1206         }
1207
1208         /// <summary>
1209         /// Set scrolling gravity values for a scroller.
1210         /// The gravity, defines how the scroller will adjust its view when the size of the scroller contents increase.
1211         /// The scroller will adjust the view to glue itself as follows.
1212         /// x=0.0, for staying where it is relative to the left edge of the content x=1.0, for staying where it is relative to the rigth edge of the content y=0.0, for staying where it is relative to the top edge of the content y=1.0, for staying where it is relative to the bottom edge of the content
1213         /// Default values for x and y are 0.0
1214         /// </summary>
1215         public double VerticalGravity
1216         {
1217             get => _scroller.VerticalGravity;
1218             set => _scroller.VerticalGravity = value;
1219         }
1220
1221         /// <summary>
1222         /// Get scroll last page number.
1223         /// The page number starts from 0. 0 is the first page. This returns the last page number among the pages.
1224         /// </summary>
1225         public int LastVerticalPageNumber => _scroller.LastVerticalPageNumber;
1226
1227         /// <summary>
1228         /// Get scroll last page number.
1229         /// The page number starts from 0. 0 is the first page. This returns the last page number among the pages.
1230         /// </summary>
1231         public int LastHorizontalPageNumber => _scroller.LastHorizontalPageNumber;
1232
1233         /// <summary>
1234         /// Set an infinite loop_ for a scroller.
1235         /// This function sets the infinite loop vertically.
1236         /// If the content is set, it will be shown repeatedly.
1237         /// </summary>
1238         public bool VerticalLoop
1239         {
1240             get => _scroller.VerticalLoop;
1241             set => _scroller.VerticalLoop = value;
1242         }
1243
1244         /// <summary>
1245         /// Set an infinite loop_ for a scroller.
1246         /// This function sets the infinite loop horizontally.
1247         /// If the content is set, it will be shown repeatedly.
1248         /// </summary>
1249         public bool HorizontalLoop
1250         {
1251             get => _scroller.HorizontalLoop;
1252             set => _scroller.HorizontalLoop = value;
1253         }
1254
1255         /// <summary>
1256         /// Gets or sets the page size to an absolute fixed value, with 0 turning it off for that axis.
1257         /// </summary>
1258         public int HorizontalPageSize
1259         {
1260             get => _scroller.HorizontalPageSize;
1261             set => _scroller.HorizontalPageSize = value;
1262         }
1263
1264         /// <summary>
1265         /// Gets or sets the page size to an absolute fixed value, with 0 turning it off for that axis.
1266         /// </summary>
1267         public int VerticalPageSize
1268         {
1269             get => _scroller.VerticalPageSize;
1270             set => _scroller.VerticalPageSize = value;
1271         }
1272
1273         /// <summary>
1274         /// Gets or sets a given scroller widget's scrolling page size, relative to its viewport size.
1275         /// </summary>
1276         public double VerticalRelativePageSize
1277         {
1278             get => _scroller.VerticalRelativePageSize;
1279             set => _scroller.VerticalRelativePageSize = value;
1280         }
1281
1282         /// <summary>
1283         /// Gets or sets a given scroller widget's scrolling page size, relative to its viewport size.
1284         /// </summary>
1285         public double HorizontalRelativePageSize
1286         {
1287             get => _scroller.HorizontalRelativePageSize;
1288             set => _scroller.HorizontalRelativePageSize = value;
1289         }
1290
1291         /// <summary>
1292         /// Gets or Sets the page snapping behavior of a scroller.
1293         /// </summary>
1294         /// <remarks>
1295         /// When scrolling, if a scroller is paged (see VerticalRelativePageSize),
1296         /// the scroller may snap to pages when being scrolled, i.e., even if it had momentum to scroll further,
1297         /// it will stop at the next page boundaries. This is disabled, by default, for both axis.
1298         /// This function will set if it that is enabled or not, for each axis.
1299         /// </remarks>
1300         public bool VerticalSnap
1301         {
1302             get => _scroller.VerticalSnap;
1303             set => _scroller.VerticalSnap = value;
1304         }
1305
1306         /// <summary>
1307         /// Gets or Sets the page snapping behavior of a scroller.
1308         /// </summary>
1309         /// <remarks>
1310         /// When scrolling, if a scroller is paged (see HorizontalRelativePageSize),
1311         /// the scroller may snap to pages when being scrolled, i.e., even if it had momentum to scroll further,
1312         /// it will stop at the next page boundaries. This is disabled, by default, for both axis.
1313         /// This function will set if it that is enabled or not, for each axis.
1314         /// </remarks>
1315         public bool HorizontalSnap
1316         {
1317             get => _scroller.HorizontalSnap;
1318             set => _scroller.HorizontalSnap = value;
1319         }
1320
1321         /// <summary>
1322         /// Gets or sets the page size to an absolute fixed value, with 0 turning it off for that axis.
1323         /// </summary>
1324         public int PageHeight
1325         {
1326             get => _scroller.PageHeight;
1327             set => _scroller.PageHeight = value;
1328         }
1329
1330         /// <summary>
1331         /// Gets or sets the page size to an absolute fixed value, with 0 turning it off for that axis.
1332         /// </summary>
1333         public int PageWidth
1334         {
1335             get => _scroller.PageWidth;
1336             set => _scroller.PageWidth = value;
1337         }
1338
1339         /// <summary>
1340         /// Gets or sets the step size to move scroller by key event.
1341         /// </summary>
1342         public int HorizontalStepSize
1343         {
1344             get => _scroller.HorizontalStepSize;
1345             set => _scroller.HorizontalStepSize = value;
1346         }
1347
1348         /// <summary>
1349         /// Gets or sets the step size to move scroller by key event.
1350         /// </summary>
1351         public int VerticalStepSize
1352         {
1353             get => _scroller.VerticalStepSize;
1354             set => _scroller.VerticalStepSize = value;
1355         }
1356
1357         /// <summary>
1358         /// Gets or sets a value whether mouse wheel is enabled or not over the scroller.
1359         /// </summary>
1360         public bool WheelDisabled
1361         {
1362             get => _scroller.WheelDisabled;
1363             set => _scroller.WheelDisabled = value;
1364         }
1365
1366         /// <summary>
1367         /// Gets or sets the type of single direction scroll.
1368         /// </summary>
1369         public ScrollSingleDirection SingleDirection
1370         {
1371             get => _scroller.SingleDirection;
1372             set => _scroller.SingleDirection = value;
1373         }
1374
1375         /// <summary>
1376         /// Sets the scroller minimum size limited to the minimum size of the content.
1377         /// By default the scroller will be as small as its design allows, irrespective of its content.
1378         /// This will make the scroller minimum size the right size horizontally and/or vertically to perfectly fit its content in that direction.
1379         /// </summary>
1380         /// <param name="horizontal">Enable limiting minimum size horizontally</param>
1381         /// <param name="vertical">Enable limiting minimum size vertically</param>
1382         public void MinimumLimit(bool horizontal, bool vertical)
1383         {
1384             _scroller.MinimumLimit(horizontal, vertical);
1385         }
1386
1387         /// <summary>
1388         /// Shows a specific virtual region within the scroller content object by the page number.
1389         /// (0, 0) of the indicated page is located at the top-left corner of the viewport.
1390         /// </summary>
1391         /// <param name="horizontalPageIndex">The horizontal page number.</param>
1392         /// <param name="verticalPageIndex">The vertical page number.</param>
1393         /// <param name="animated">True means slider with animation.</param>
1394         public void ScrollTo(int horizontalPageIndex, int verticalPageIndex, bool animated)
1395         {
1396             _scroller.ScrollTo(horizontalPageIndex, verticalPageIndex, animated);
1397         }
1398
1399         /// <summary>
1400         /// Shows a specific virtual region within the scroller content object.
1401         /// </summary>
1402         /// <remarks>
1403         /// This ensures that all (or part, if it does not fit) of the designated region in the virtual content object ((0, 0)
1404         /// starting at the top-left of the virtual content object) is shown within the scroller.
1405         /// If set "animated" to true, it will allows the scroller to "smoothly slide" to this location
1406         /// (if configuration in general calls for transitions).
1407         /// It may not jump immediately to the new location and may take a while and show other content along the way.
1408         /// </remarks>
1409         /// <param name="region">Rect struct of region.</param>
1410         /// <param name="animated">True means allows the scroller to "smoothly slide" to this location.</param>
1411         public void ScrollTo(Rect region, bool animated)
1412         {
1413             _scroller.ScrollTo(region, animated);
1414         }
1415
1416         #endregion
1417     }
1418 }