[NUI] Change all CallingConvention to `Cdecl`
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / BaseComponents / TextFieldEvent.cs
1 /*
2  * Copyright(c) 2021 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 using System;
19 using System.ComponentModel;
20 using System.Runtime.InteropServices;
21
22 namespace Tizen.NUI.BaseComponents
23 {
24     /// <summary>
25     /// A control which provides a single line editable text field.
26     /// </summary>
27     /// <since_tizen> 3 </since_tizen>
28     public partial class TextField
29     {
30         private EventHandler<TextChangedEventArgs> textFieldTextChangedEventHandler;
31         private TextChangedCallbackDelegate textFieldTextChangedCallbackDelegate;
32         private EventHandler textFieldCursorPositionChangedEventHandler;
33         private CursorPositionChangedCallbackDelegate textFieldCursorPositionChangedCallbackDelegate;
34         private EventHandler<MaxLengthReachedEventArgs> textFieldMaxLengthReachedEventHandler;
35         private MaxLengthReachedCallbackDelegate textFieldMaxLengthReachedCallbackDelegate;
36         private EventHandler<AnchorClickedEventArgs> textFieldAnchorClickedEventHandler;
37         private AnchorClickedCallbackDelegate textFieldAnchorClickedCallbackDelegate;
38
39         private EventHandler textFieldSelectionChangedEventHandler;
40         private SelectionChangedCallbackDelegate textFieldSelectionChangedCallbackDelegate;
41
42         private EventHandler<InputFilteredEventArgs> textFieldInputFilteredEventHandler;
43         private InputFilteredCallbackDelegate textFieldInputFilteredCallbackDelegate;
44         private EventHandler textFieldSelectionClearedEventHandler;
45         private SelectionClearedCallbackDelegate textFieldSelectionClearedCallbackDelegate;
46
47         private EventHandler textFieldSelectionStartedEventHandler;
48         private SelectionStartedCallbackDelegate textFieldSelectionStartedCallbackDelegate;
49
50         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
51         private delegate void TextChangedCallbackDelegate(IntPtr textField);
52
53         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
54         private delegate void CursorPositionChangedCallbackDelegate(IntPtr textField, uint oldPosition);
55
56         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
57         private delegate void MaxLengthReachedCallbackDelegate(IntPtr textField);
58
59         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
60         private delegate void AnchorClickedCallbackDelegate(IntPtr textField, IntPtr href, uint hrefLength);
61
62         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
63         private delegate void SelectionChangedCallbackDelegate(IntPtr textField, uint oldStart, uint oldEnd);
64
65         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
66         private delegate void InputFilteredCallbackDelegate(IntPtr textField, InputFilterType type);
67
68         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
69         private delegate void SelectionClearedCallbackDelegate(IntPtr textField);
70
71         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
72         private delegate void SelectionStartedCallbackDelegate(IntPtr textField);
73
74         private bool invokeTextChanged = true;
75
76         /// <summary>
77         /// The TextChanged event.
78         /// </summary>
79         /// <since_tizen> 3 </since_tizen>
80         public event EventHandler<TextChangedEventArgs> TextChanged
81         {
82             add
83             {
84                 if (textFieldTextChangedEventHandler == null)
85                 {
86                     textFieldTextChangedCallbackDelegate = (OnTextChanged);
87                     TextChangedSignal().Connect(textFieldTextChangedCallbackDelegate);
88                 }
89                 textFieldTextChangedEventHandler += value;
90             }
91             remove
92             {
93                 textFieldTextChangedEventHandler -= value;
94                 if (textFieldTextChangedEventHandler == null && TextChangedSignal().Empty() == false)
95                 {
96                     TextChangedSignal().Disconnect(textFieldTextChangedCallbackDelegate);
97                 }
98             }
99         }
100
101         /// <summary>
102         /// The CursorPositionChanged event is emitted whenever the primary cursor position changed.
103         /// </summary>
104         /// <since_tizen> 9 </since_tizen>
105         public event EventHandler CursorPositionChanged
106         {
107             add
108             {
109                 if (textFieldCursorPositionChangedEventHandler == null)
110                 {
111                     textFieldCursorPositionChangedCallbackDelegate = (OnCursorPositionChanged);
112                     CursorPositionChangedSignal().Connect(textFieldCursorPositionChangedCallbackDelegate);
113                 }
114                 textFieldCursorPositionChangedEventHandler += value;
115             }
116             remove
117             {
118                 if (textFieldCursorPositionChangedEventHandler == null && CursorPositionChangedSignal().Empty() == false)
119                 {
120                     this.CursorPositionChangedSignal().Disconnect(textFieldCursorPositionChangedCallbackDelegate);
121                 }
122                 textFieldCursorPositionChangedEventHandler -= value;
123             }
124         }
125
126         /// <summary>
127         /// The MaxLengthReached event.
128         /// </summary>
129         /// <since_tizen> 3 </since_tizen>
130         public event EventHandler<MaxLengthReachedEventArgs> MaxLengthReached
131         {
132             add
133             {
134                 if (textFieldMaxLengthReachedEventHandler == null)
135                 {
136                     textFieldMaxLengthReachedCallbackDelegate = (OnMaxLengthReached);
137                     MaxLengthReachedSignal().Connect(textFieldMaxLengthReachedCallbackDelegate);
138                 }
139                 textFieldMaxLengthReachedEventHandler += value;
140             }
141             remove
142             {
143                 if (textFieldMaxLengthReachedEventHandler == null && MaxLengthReachedSignal().Empty() == false)
144                 {
145                     this.MaxLengthReachedSignal().Disconnect(textFieldMaxLengthReachedCallbackDelegate);
146                 }
147                 textFieldMaxLengthReachedEventHandler -= value;
148             }
149         }
150
151         /// <summary>
152         /// The SelectionStarted event is emitted when the selection has been started.
153         /// </summary>
154         /// <since_tizen> 10 </since_tizen>
155         public event EventHandler SelectionStarted
156         {
157             add
158             {
159                 if (textFieldSelectionStartedEventHandler == null)
160                 {
161                     textFieldSelectionStartedCallbackDelegate = (OnSelectionStarted);
162                     SelectionStartedSignal().Connect(textFieldSelectionStartedCallbackDelegate);
163                 }
164                 textFieldSelectionStartedEventHandler += value;
165             }
166             remove
167             {
168                 if (textFieldSelectionStartedEventHandler == null && SelectionStartedSignal().Empty() == false)
169                 {
170                     this.SelectionStartedSignal().Disconnect(textFieldSelectionStartedCallbackDelegate);
171                 }
172                 textFieldSelectionStartedEventHandler -= value;
173             }
174         }
175
176         /// <summary>
177         /// The SelectionCleared signal is emitted when selection is cleared.
178         /// </summary>
179         /// <since_tizen> 9 </since_tizen>
180         public event EventHandler SelectionCleared
181         {
182             add
183             {
184                 if (textFieldSelectionClearedEventHandler == null)
185                 {
186                     textFieldSelectionClearedCallbackDelegate = (OnSelectionCleared);
187                     SelectionClearedSignal().Connect(textFieldSelectionClearedCallbackDelegate);
188                 }
189                 textFieldSelectionClearedEventHandler += value;
190             }
191             remove
192             {
193                 if (textFieldSelectionClearedEventHandler == null && SelectionClearedSignal().Empty() == false)
194                 {
195                     this.SelectionClearedSignal().Disconnect(textFieldSelectionClearedCallbackDelegate);
196                 }
197                 textFieldSelectionClearedEventHandler -= value;
198             }
199         }
200
201         /// <summary>
202         /// The AnchorClicked signal is emitted when the anchor is clicked.
203         /// </summary>
204         /// <since_tizen> 9 </since_tizen>
205         public event EventHandler<AnchorClickedEventArgs> AnchorClicked
206         {
207             add
208             {
209                 if (textFieldAnchorClickedEventHandler == null)
210                 {
211                     textFieldAnchorClickedCallbackDelegate = (OnAnchorClicked);
212                     AnchorClickedSignal().Connect(textFieldAnchorClickedCallbackDelegate);
213                 }
214                 textFieldAnchorClickedEventHandler += value;
215             }
216             remove
217             {
218                 textFieldAnchorClickedEventHandler -= value;
219                 if (textFieldAnchorClickedEventHandler == null && AnchorClickedSignal().Empty() == false)
220                 {
221                     AnchorClickedSignal().Disconnect(textFieldAnchorClickedCallbackDelegate);
222                 }
223             }
224         }
225
226         /// <summary>
227         /// The SelectionChanged event is emitted whenever the selected text is changed.
228         /// </summary>
229         /// <since_tizen> 9 </since_tizen>
230         public event EventHandler SelectionChanged
231         {
232             add
233             {
234                 if (textFieldSelectionChangedEventHandler == null)
235                 {
236                     textFieldSelectionChangedCallbackDelegate = (OnSelectionChanged);
237                     SelectionChangedSignal().Connect(textFieldSelectionChangedCallbackDelegate);
238                 }
239                 textFieldSelectionChangedEventHandler += value;
240             }
241             remove
242             {
243                 if (textFieldSelectionChangedEventHandler == null && SelectionChangedSignal().Empty() == false)
244                 {
245                     this.SelectionChangedSignal().Disconnect(textFieldSelectionChangedCallbackDelegate);
246                 }
247                 textFieldSelectionChangedEventHandler -= value;
248             }
249         }
250
251         /// <summary>
252         /// The InputFiltered signal is emitted when the input is filtered by InputFilter. <br />
253         /// </summary>
254         /// <remarks>
255         /// See <see cref="InputFilterType"/> and <see cref="InputFilteredEventArgs"/> for a detailed description. <br />
256         /// </remarks>
257         /// <example>
258         /// The following example demonstrates how to use the InputFiltered event.
259         /// <code>
260         /// field.InputFiltered += (s, e) =>
261         /// {
262         ///     if (e.Type == InputFilterType.Accept)
263         ///     {
264         ///         // If input is filtered by InputFilter of Accept type.
265         ///     }
266         ///     else if (e.Type == InputFilterType.Reject)
267         ///     {
268         ///         // If input is filtered by InputFilter of Reject type.
269         ///     }
270         /// };
271         /// </code>
272         /// </example>
273         /// <since_tizen> 9 </since_tizen>
274         public event EventHandler<InputFilteredEventArgs> InputFiltered
275         {
276             add
277             {
278                 if (textFieldInputFilteredEventHandler == null)
279                 {
280                     textFieldInputFilteredCallbackDelegate = (OnInputFiltered);
281                     InputFilteredSignal().Connect(textFieldInputFilteredCallbackDelegate);
282                 }
283                 textFieldInputFilteredEventHandler += value;
284             }
285             remove
286             {
287                 textFieldInputFilteredEventHandler -= value;
288                 if (textFieldInputFilteredEventHandler == null && InputFilteredSignal().Empty() == false)
289                 {
290                     InputFilteredSignal().Disconnect(textFieldInputFilteredCallbackDelegate);
291                 }
292             }
293         }
294
295         internal TextFieldSignal SelectionStartedSignal()
296         {
297             TextFieldSignal ret = new TextFieldSignal(Interop.TextField.SelectionStartedSignal(SwigCPtr), false);
298             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
299             return ret;
300         }
301
302         internal TextFieldSignal SelectionClearedSignal()
303         {
304             TextFieldSignal ret = new TextFieldSignal(Interop.TextField.SelectionClearedSignal(SwigCPtr), false);
305             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
306             return ret;
307         }
308
309         internal TextFieldSignal TextChangedSignal()
310         {
311             TextFieldSignal ret = new TextFieldSignal(Interop.TextField.TextChangedSignal(SwigCPtr), false);
312             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
313             return ret;
314         }
315
316         internal TextFieldSignal CursorPositionChangedSignal()
317         {
318             TextFieldSignal ret = new TextFieldSignal(Interop.TextField.CursorPositionChangedSignal(SwigCPtr), false);
319             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
320             return ret;
321         }
322
323         internal TextFieldSignal MaxLengthReachedSignal()
324         {
325             TextFieldSignal ret = new TextFieldSignal(Interop.TextField.MaxLengthReachedSignal(SwigCPtr), false);
326             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
327             return ret;
328         }
329
330         internal TextFieldSignal AnchorClickedSignal()
331         {
332             TextFieldSignal ret = new TextFieldSignal(Interop.TextField.AnchorClickedSignal(SwigCPtr), false);
333             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
334             return ret;
335         }
336
337         internal TextFieldSignal SelectionChangedSignal()
338         {
339             TextFieldSignal ret = new TextFieldSignal(Interop.TextField.SelectionChangedSignal(SwigCPtr), false);
340             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
341             return ret;
342         }
343
344         internal TextFieldSignal InputFilteredSignal()
345         {
346             TextFieldSignal ret = new TextFieldSignal(Interop.TextField.InputFilteredSignal(SwigCPtr), false);
347             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
348             return ret;
349         }
350
351         private void OnSelectionStarted(IntPtr textField)
352         {
353             //no data to be sent to the user
354             textFieldSelectionStartedEventHandler?.Invoke(this, EventArgs.Empty);
355         }
356
357         private void OnSelectionCleared(IntPtr textField)
358         {
359             //no data to be sent to the user
360             textFieldSelectionClearedEventHandler?.Invoke(this, EventArgs.Empty);
361         }
362
363         private void OnTextChanged(IntPtr textField)
364         {
365             if (textFieldTextChangedEventHandler != null && invokeTextChanged)
366             {
367                 TextChangedEventArgs e = new TextChangedEventArgs();
368
369                 // Populate all members of "e" (TextChangedEventArgs) with real data
370                 e.TextField = Registry.GetManagedBaseHandleFromNativePtr(textField) as TextField;
371                 //here we send all data to user event handlers
372                 textFieldTextChangedEventHandler(this, e);
373             }
374         }
375
376         private void OnCursorPositionChanged(IntPtr textField, uint oldPosition)
377         {
378             // no data to be sent to the user, as in NUI there is no event provide old values.
379             textFieldCursorPositionChangedEventHandler?.Invoke(this, EventArgs.Empty);
380         }
381
382         private void OnMaxLengthReached(IntPtr textField)
383         {
384             if (textFieldMaxLengthReachedEventHandler != null)
385             {
386                 MaxLengthReachedEventArgs e = new MaxLengthReachedEventArgs();
387
388                 // Populate all members of "e" (MaxLengthReachedEventArgs) with real data
389                 e.TextField = Registry.GetManagedBaseHandleFromNativePtr(textField) as TextField;
390                 //here we send all data to user event handlers
391                 textFieldMaxLengthReachedEventHandler(this, e);
392             }
393         }
394
395         private void OnAnchorClicked(IntPtr textField, IntPtr href, uint hrefLength)
396         {
397             // Note: hrefLength is useful for get the length of a const char* (href) in dali-toolkit.
398             // But NUI can get the length of string (href), so hrefLength is not necessary in NUI.
399             AnchorClickedEventArgs e = new AnchorClickedEventArgs();
400
401             // Populate all members of "e" (AnchorClickedEventArgs) with real data
402             e.Href = Marshal.PtrToStringAnsi(href);
403             //here we send all data to user event handlers
404             textFieldAnchorClickedEventHandler?.Invoke(this, e);
405         }
406
407         private void OnSelectionChanged(IntPtr textField, uint oldStart, uint oldEnd)
408         {
409             // no data to be sent to the user, as in NUI there is no event provide old values.
410             textFieldSelectionChangedEventHandler?.Invoke(this, EventArgs.Empty);
411         }
412
413         private void OnInputFiltered(IntPtr textField, InputFilterType type)
414         {
415             InputFilteredEventArgs e = new InputFilteredEventArgs();
416
417             // Populate all members of "e" (InputFilteredEventArgs) with real data
418             e.Type = type;
419             //here we send all data to user event handlers
420             textFieldInputFilteredEventHandler?.Invoke(this, e);
421         }
422
423         /// <summary>
424         /// The TextChanged event arguments.
425         /// </summary>
426         /// <since_tizen> 3 </since_tizen>
427         public class TextChangedEventArgs : EventArgs
428         {
429             private TextField textField;
430
431             /// <summary>
432             /// TextField.
433             /// </summary>
434             /// <since_tizen> 3 </since_tizen>
435             public TextField TextField
436             {
437                 get
438                 {
439                     return textField;
440                 }
441                 set
442                 {
443                     textField = value;
444                 }
445             }
446         }
447
448         /// <summary>
449         /// The MaxLengthReached event arguments.
450         /// </summary>
451         /// <since_tizen> 3 </since_tizen>
452         public class MaxLengthReachedEventArgs : EventArgs
453         {
454             private TextField textField;
455
456             /// <summary>
457             /// TextField.
458             /// </summary>
459             /// <since_tizen> 3 </since_tizen>
460             public TextField TextField
461             {
462                 get
463                 {
464                     return textField;
465                 }
466                 set
467                 {
468                     textField = value;
469                 }
470             }
471         }
472     }
473 }