Add InputFilter to TextField, TextEditor
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / public / BaseComponents / TextEditorEvent.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 multi-line editable text editor.
26     /// </summary>
27     /// <since_tizen> 3 </since_tizen>
28     public partial class TextEditor
29     {
30         private EventHandler<TextChangedEventArgs> textEditorTextChangedEventHandler;
31         private TextChangedCallbackDelegate textEditorTextChangedCallbackDelegate;
32
33         private EventHandler<ScrollStateChangedEventArgs> textEditorScrollStateChangedEventHandler;
34         private ScrollStateChangedCallbackDelegate textEditorScrollStateChangedCallbackDelegate;
35
36         private EventHandler<MaxLengthReachedEventArgs> textEditorMaxLengthReachedEventHandler;
37         private MaxLengthReachedCallbackDelegate textEditorMaxLengthReachedCallbackDelegate;
38
39         private EventHandler<AnchorClickedEventArgs> textEditorAnchorClickedEventHandler;
40         private AnchorClickedCallbackDelegate textEditorAnchorClickedCallbackDelegate;
41
42         private EventHandler<InputFilteredEventArgs> textEditorInputFilteredEventHandler;
43         private InputFilteredCallbackDelegate textEditorInputFilteredCallbackDelegate;
44
45         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
46         private delegate void TextChangedCallbackDelegate(IntPtr textEditor);
47
48         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
49         private delegate void ScrollStateChangedCallbackDelegate(IntPtr textEditor, ScrollState state);
50
51         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
52         private delegate void MaxLengthReachedCallbackDelegate(IntPtr textEditor);
53
54         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
55         private delegate void AnchorClickedCallbackDelegate(IntPtr textEditor, IntPtr href, uint hrefLength);
56
57         [UnmanagedFunctionPointer(CallingConvention.StdCall)]
58         private delegate void InputFilteredCallbackDelegate(IntPtr textEditor, InputFilterType type);
59
60         /// <summary>
61         /// An event for the TextChanged signal which can be used to subscribe or unsubscribe the event handler
62         /// provided by the user. The TextChanged signal is emitted when the text changes.<br />
63         /// </summary>
64         /// <since_tizen> 3 </since_tizen>
65         public event EventHandler<TextChangedEventArgs> TextChanged
66         {
67             add
68             {
69                 if (textEditorTextChangedEventHandler == null)
70                 {
71                     textEditorTextChangedCallbackDelegate = (OnTextChanged);
72                     TextChangedSignal().Connect(textEditorTextChangedCallbackDelegate);
73                 }
74                 textEditorTextChangedEventHandler += value;
75             }
76             remove
77             {
78                 textEditorTextChangedEventHandler -= value;
79                 if (textEditorTextChangedEventHandler == null && TextChangedSignal().Empty() == false)
80                 {
81                     TextChangedSignal().Disconnect(textEditorTextChangedCallbackDelegate);
82                 }
83             }
84         }
85
86         /// <summary>
87         /// Event for the ScrollStateChanged signal which can be used to subscribe or unsubscribe the event handler
88         /// provided by the user. The ScrollStateChanged signal is emitted when the scroll state changes.<br />
89         /// </summary>
90         /// <since_tizen> 3 </since_tizen>
91         public event EventHandler<ScrollStateChangedEventArgs> ScrollStateChanged
92         {
93             add
94             {
95                 if (textEditorScrollStateChangedEventHandler == null)
96                 {
97                     textEditorScrollStateChangedCallbackDelegate = OnScrollStateChanged;
98                     ScrollStateChangedSignal(this).Connect(textEditorScrollStateChangedCallbackDelegate);
99                 }
100                 textEditorScrollStateChangedEventHandler += value;
101             }
102             remove
103             {
104                 textEditorScrollStateChangedEventHandler -= value;
105                 if (textEditorScrollStateChangedEventHandler == null && ScrollStateChangedSignal(this).Empty() == false)
106                 {
107                     ScrollStateChangedSignal(this).Disconnect(textEditorScrollStateChangedCallbackDelegate);
108                 }
109             }
110         }
111
112         /// <summary>
113         /// The MaxLengthReached event.
114         /// </summary>
115         /// This will be public opened in tizen_6.5 after ACR done. Before ACR, need to be hidden as inhouse API.
116         [EditorBrowsable(EditorBrowsableState.Never)]
117         public event EventHandler<MaxLengthReachedEventArgs> MaxLengthReached
118         {
119             add
120             {
121                 if (textEditorMaxLengthReachedEventHandler == null)
122                 {
123                     textEditorMaxLengthReachedCallbackDelegate = (OnMaxLengthReached);
124                     MaxLengthReachedSignal().Connect(textEditorMaxLengthReachedCallbackDelegate);
125                 }
126                 textEditorMaxLengthReachedEventHandler += value;
127             }
128             remove
129             {
130                 if (textEditorMaxLengthReachedEventHandler == null && MaxLengthReachedSignal().Empty() == false)
131                 {
132                     this.MaxLengthReachedSignal().Disconnect(textEditorMaxLengthReachedCallbackDelegate);
133                 }
134                 textEditorMaxLengthReachedEventHandler -= value;
135             }
136         }
137
138         /// <summary>
139         /// The AnchorClicked signal is emitted when the anchor is clicked.
140         /// </summary>
141         /// <since_tizen> 9 </since_tizen>
142         public event EventHandler<AnchorClickedEventArgs> AnchorClicked
143         {
144             add
145             {
146                 if (textEditorAnchorClickedEventHandler == null)
147                 {
148                     textEditorAnchorClickedCallbackDelegate = (OnAnchorClicked);
149                     AnchorClickedSignal().Connect(textEditorAnchorClickedCallbackDelegate);
150                 }
151                 textEditorAnchorClickedEventHandler += value;
152             }
153             remove
154             {
155                 textEditorAnchorClickedEventHandler -= value;
156                 if (textEditorAnchorClickedEventHandler == null && AnchorClickedSignal().Empty() == false)
157                 {
158                     AnchorClickedSignal().Disconnect(textEditorAnchorClickedCallbackDelegate);
159                 }
160             }
161         }
162
163         /// <summary>
164         /// The InputFiltered signal is emitted when the input is filtered by InputFilter. <br />
165         /// </summary>
166         /// <remarks>
167         /// See <see cref="InputFilterType"/> and <see cref="InputFilteredEventArgs"/> for a detailed description. <br />
168         /// </remarks>
169         /// <example>
170         /// The following example demonstrates how to use the InputFiltered event.
171         /// <code>
172         /// editor.InputFiltered += (s, e) =>
173         /// {
174         ///     if (e.Type == InputFilterType.Accept)
175         ///     {
176         ///         // If input is filtered by InputFilter of Accept type.
177         ///     }
178         ///     else if (e.Type == InputFilterType.Reject)
179         ///     {
180         ///         // If input is filtered by InputFilter of Reject type.
181         ///     }
182         /// };
183         /// </code>
184         /// </example>
185         [EditorBrowsable(EditorBrowsableState.Never)]
186         public event EventHandler<InputFilteredEventArgs> InputFiltered
187         {
188             add
189             {
190                 if (textEditorInputFilteredEventHandler == null)
191                 {
192                     textEditorInputFilteredCallbackDelegate = (OnInputFiltered);
193                     InputFilteredSignal().Connect(textEditorInputFilteredCallbackDelegate);
194                 }
195                 textEditorInputFilteredEventHandler += value;
196             }
197             remove
198             {
199                 textEditorInputFilteredEventHandler -= value;
200                 if (textEditorInputFilteredEventHandler == null && InputFilteredSignal().Empty() == false)
201                 {
202                     InputFilteredSignal().Disconnect(textEditorInputFilteredCallbackDelegate);
203                 }
204             }
205         }
206
207         internal TextEditorSignal TextChangedSignal()
208         {
209             TextEditorSignal ret = new TextEditorSignal(Interop.TextEditor.TextChangedSignal(SwigCPtr), false);
210             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
211             return ret;
212         }
213
214         internal ScrollStateChangedSignal ScrollStateChangedSignal(TextEditor textEditor)
215         {
216             ScrollStateChangedSignal ret = new ScrollStateChangedSignal(Interop.TextEditor.ScrollStateChangedSignal(TextEditor.getCPtr(textEditor)), false);
217             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
218             return ret;
219         }
220
221         internal TextEditorSignal MaxLengthReachedSignal()
222         {
223             TextEditorSignal ret = new TextEditorSignal(Interop.TextEditor.MaxLengthReachedSignal(SwigCPtr), false);
224             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
225             return ret;
226         }
227
228         internal TextEditorSignal AnchorClickedSignal()
229         {
230             TextEditorSignal ret = new TextEditorSignal(Interop.TextEditor.AnchorClickedSignal(SwigCPtr), false);
231             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
232             return ret;
233         }
234
235         internal TextEditorSignal InputFilteredSignal()
236         {
237             TextEditorSignal ret = new TextEditorSignal(Interop.TextEditor.InputFilteredSignal(SwigCPtr), false);
238             if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
239             return ret;
240         }
241
242         private void OnTextChanged(IntPtr textEditor)
243         {
244             if (textEditorTextChangedEventHandler != null)
245             {
246                 TextChangedEventArgs e = new TextChangedEventArgs();
247
248                 // Populate all members of "e" (TextChangedEventArgs) with real data
249                 e.TextEditor = Registry.GetManagedBaseHandleFromNativePtr(textEditor) as TextEditor;
250                 //here we send all data to user event handlers
251                 textEditorTextChangedEventHandler(this, e);
252             }
253         }
254
255         private void OnScrollStateChanged(IntPtr textEditor, ScrollState state)
256         {
257             if (textEditorScrollStateChangedEventHandler != null)
258             {
259                 ScrollStateChangedEventArgs e = new ScrollStateChangedEventArgs();
260
261                 if (textEditor != global::System.IntPtr.Zero)
262                 {
263                     // Populate all members of "e" (ScrollStateChangedEventArgs) with real data
264                     e.TextEditor = Registry.GetManagedBaseHandleFromNativePtr(textEditor) as TextEditor;
265                     e.ScrollState = state;
266                 }
267                 //here we send all data to user event handlers
268                 textEditorScrollStateChangedEventHandler(this, e);
269             }
270         }
271
272         private void OnMaxLengthReached(IntPtr textEditor)
273         {
274             if (textEditorMaxLengthReachedEventHandler != null)
275             {
276                 MaxLengthReachedEventArgs e = new MaxLengthReachedEventArgs();
277
278                 // Populate all members of "e" (MaxLengthReachedEventArgs) with real data
279                 e.TextEditor = Registry.GetManagedBaseHandleFromNativePtr(textEditor) as TextEditor;
280                 //here we send all data to user event handlers
281                 textEditorMaxLengthReachedEventHandler(this, e);
282             }
283         }
284
285         private void OnAnchorClicked(IntPtr textEditor, IntPtr href, uint hrefLength)
286         {
287             // Note: hrefLength is useful for get the length of a const char* (href) in dali-toolkit.
288             // But NUI can get the length of string (href), so hrefLength is not necessary in NUI.
289             AnchorClickedEventArgs e = new AnchorClickedEventArgs();
290
291             // Populate all members of "e" (AnchorClickedEventArgs) with real data
292             e.Href = Marshal.PtrToStringAnsi(href);
293             //here we send all data to user event handlers
294             textEditorAnchorClickedEventHandler?.Invoke(this, e);
295         }
296
297         private void OnInputFiltered(IntPtr textEditor, InputFilterType type)
298         {
299             InputFilteredEventArgs e = new InputFilteredEventArgs();
300
301             // Populate all members of "e" (InputFilteredEventArgs) with real data
302             e.Type = type;
303             //here we send all data to user event handlers
304             textEditorInputFilteredEventHandler?.Invoke(this, e);
305         }
306
307         /// <summary>
308         /// Event arguments that passed via the TextChanged signal.
309         /// </summary>
310         /// <since_tizen> 3 </since_tizen>
311         public class TextChangedEventArgs : EventArgs
312         {
313             private TextEditor textEditor;
314
315             /// <summary>
316             /// TextEditor - is the texteditor control which has the text contents changed.
317             /// </summary>
318             /// <since_tizen> 3 </since_tizen>
319             public TextEditor TextEditor
320             {
321                 get
322                 {
323                     return textEditor;
324                 }
325                 set
326                 {
327                     textEditor = value;
328                 }
329             }
330         }
331
332         /// <summary>
333         /// Event arguments that passed via the ScrollStateChanged signal.
334         /// </summary>
335         /// <since_tizen> 3 </since_tizen>
336         public class ScrollStateChangedEventArgs : EventArgs
337         {
338             private TextEditor textEditor;
339             private ScrollState scrollState;
340
341             /// <summary>
342             /// TextEditor - is the texteditor control which has the scroll state changed.
343             /// </summary>
344             /// <since_tizen> 3 </since_tizen>
345             public TextEditor TextEditor
346             {
347                 get
348                 {
349                     return textEditor;
350                 }
351                 set
352                 {
353                     textEditor = value;
354                 }
355             }
356
357             /// <summary>
358             /// ScrollState - is the texteditor control scroll state.
359             /// </summary>
360             /// <since_tizen> 3 </since_tizen>
361             public ScrollState ScrollState
362             {
363                 get
364                 {
365                     return scrollState;
366                 }
367                 set
368                 {
369                     scrollState = value;
370                 }
371             }
372         }
373
374         /// <summary>
375         /// The MaxLengthReached event arguments.
376         /// </summary>
377         /// This will be public opened in tizen_6.5 after ACR done. Before ACR, need to be hidden as inhouse API.
378         [EditorBrowsable(EditorBrowsableState.Never)]
379         public class MaxLengthReachedEventArgs : EventArgs
380         {
381             private TextEditor textEditor;
382
383             /// <summary>
384             /// TextEditor.
385             /// </summary>
386             /// This will be public opened in tizen_6.5 after ACR done. Before ACR, need to be hidden as inhouse API.
387             [EditorBrowsable(EditorBrowsableState.Never)]
388             public TextEditor TextEditor
389             {
390                 get
391                 {
392                     return textEditor;
393                 }
394                 set
395                 {
396                     textEditor = value;
397                 }
398             }
399         }
400     }
401 }