2 * Copyright(c) 2021 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 using System.ComponentModel;
20 using System.Runtime.InteropServices;
22 namespace Tizen.NUI.BaseComponents
25 /// A control which provides a single line editable text field.
27 /// <since_tizen> 3 </since_tizen>
28 public partial class TextField
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;
39 private EventHandler textFieldSelectionChangedEventHandler;
40 private SelectionChangedCallbackDelegate textFieldSelectionChangedCallbackDelegate;
42 private EventHandler<InputFilteredEventArgs> textFieldInputFilteredEventHandler;
43 private InputFilteredCallbackDelegate textFieldInputFilteredCallbackDelegate;
44 private EventHandler textFieldSelectionClearedEventHandler;
45 private SelectionClearedCallbackDelegate textFieldSelectionClearedCallbackDelegate;
47 private EventHandler textFieldSelectionStartedEventHandler;
48 private SelectionStartedCallbackDelegate textFieldSelectionStartedCallbackDelegate;
50 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
51 private delegate void TextChangedCallbackDelegate(IntPtr textField);
53 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
54 private delegate void CursorPositionChangedCallbackDelegate(IntPtr textField, uint oldPosition);
56 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
57 private delegate void MaxLengthReachedCallbackDelegate(IntPtr textField);
59 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
60 private delegate void AnchorClickedCallbackDelegate(IntPtr textField, IntPtr href, uint hrefLength);
62 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
63 private delegate void SelectionChangedCallbackDelegate(IntPtr textField, uint oldStart, uint oldEnd);
65 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
66 private delegate void InputFilteredCallbackDelegate(IntPtr textField, InputFilterType type);
68 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
69 private delegate void SelectionClearedCallbackDelegate(IntPtr textField);
71 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
72 private delegate void SelectionStartedCallbackDelegate(IntPtr textField);
74 private bool invokeTextChanged = true;
77 /// The TextChanged event.
79 /// <since_tizen> 3 </since_tizen>
80 public event EventHandler<TextChangedEventArgs> TextChanged
84 if (textFieldTextChangedEventHandler == null)
86 textFieldTextChangedCallbackDelegate = (OnTextChanged);
87 TextChangedSignal().Connect(textFieldTextChangedCallbackDelegate);
89 textFieldTextChangedEventHandler += value;
93 textFieldTextChangedEventHandler -= value;
94 if (textFieldTextChangedEventHandler == null && TextChangedSignal().Empty() == false)
96 TextChangedSignal().Disconnect(textFieldTextChangedCallbackDelegate);
102 /// The CursorPositionChanged event is emitted whenever the primary cursor position changed.
104 /// <since_tizen> 9 </since_tizen>
105 public event EventHandler CursorPositionChanged
109 if (textFieldCursorPositionChangedEventHandler == null)
111 textFieldCursorPositionChangedCallbackDelegate = (OnCursorPositionChanged);
112 CursorPositionChangedSignal().Connect(textFieldCursorPositionChangedCallbackDelegate);
114 textFieldCursorPositionChangedEventHandler += value;
118 if (textFieldCursorPositionChangedEventHandler == null && CursorPositionChangedSignal().Empty() == false)
120 this.CursorPositionChangedSignal().Disconnect(textFieldCursorPositionChangedCallbackDelegate);
122 textFieldCursorPositionChangedEventHandler -= value;
127 /// The MaxLengthReached event.
129 /// <since_tizen> 3 </since_tizen>
130 public event EventHandler<MaxLengthReachedEventArgs> MaxLengthReached
134 if (textFieldMaxLengthReachedEventHandler == null)
136 textFieldMaxLengthReachedCallbackDelegate = (OnMaxLengthReached);
137 MaxLengthReachedSignal().Connect(textFieldMaxLengthReachedCallbackDelegate);
139 textFieldMaxLengthReachedEventHandler += value;
143 if (textFieldMaxLengthReachedEventHandler == null && MaxLengthReachedSignal().Empty() == false)
145 this.MaxLengthReachedSignal().Disconnect(textFieldMaxLengthReachedCallbackDelegate);
147 textFieldMaxLengthReachedEventHandler -= value;
152 /// The SelectionStarted event is emitted when the selection has been started.
154 /// <since_tizen> 10 </since_tizen>
155 public event EventHandler SelectionStarted
159 if (textFieldSelectionStartedEventHandler == null)
161 textFieldSelectionStartedCallbackDelegate = (OnSelectionStarted);
162 SelectionStartedSignal().Connect(textFieldSelectionStartedCallbackDelegate);
164 textFieldSelectionStartedEventHandler += value;
168 if (textFieldSelectionStartedEventHandler == null && SelectionStartedSignal().Empty() == false)
170 this.SelectionStartedSignal().Disconnect(textFieldSelectionStartedCallbackDelegate);
172 textFieldSelectionStartedEventHandler -= value;
177 /// The SelectionCleared signal is emitted when selection is cleared.
179 /// <since_tizen> 9 </since_tizen>
180 public event EventHandler SelectionCleared
184 if (textFieldSelectionClearedEventHandler == null)
186 textFieldSelectionClearedCallbackDelegate = (OnSelectionCleared);
187 SelectionClearedSignal().Connect(textFieldSelectionClearedCallbackDelegate);
189 textFieldSelectionClearedEventHandler += value;
193 if (textFieldSelectionClearedEventHandler == null && SelectionClearedSignal().Empty() == false)
195 this.SelectionClearedSignal().Disconnect(textFieldSelectionClearedCallbackDelegate);
197 textFieldSelectionClearedEventHandler -= value;
202 /// The AnchorClicked signal is emitted when the anchor is clicked.
204 /// <since_tizen> 9 </since_tizen>
205 public event EventHandler<AnchorClickedEventArgs> AnchorClicked
209 if (textFieldAnchorClickedEventHandler == null)
211 textFieldAnchorClickedCallbackDelegate = (OnAnchorClicked);
212 AnchorClickedSignal().Connect(textFieldAnchorClickedCallbackDelegate);
214 textFieldAnchorClickedEventHandler += value;
218 textFieldAnchorClickedEventHandler -= value;
219 if (textFieldAnchorClickedEventHandler == null && AnchorClickedSignal().Empty() == false)
221 AnchorClickedSignal().Disconnect(textFieldAnchorClickedCallbackDelegate);
227 /// The SelectionChanged event is emitted whenever the selected text is changed.
229 /// <since_tizen> 9 </since_tizen>
230 public event EventHandler SelectionChanged
234 if (textFieldSelectionChangedEventHandler == null)
236 textFieldSelectionChangedCallbackDelegate = (OnSelectionChanged);
237 SelectionChangedSignal().Connect(textFieldSelectionChangedCallbackDelegate);
239 textFieldSelectionChangedEventHandler += value;
243 if (textFieldSelectionChangedEventHandler == null && SelectionChangedSignal().Empty() == false)
245 this.SelectionChangedSignal().Disconnect(textFieldSelectionChangedCallbackDelegate);
247 textFieldSelectionChangedEventHandler -= value;
252 /// The InputFiltered signal is emitted when the input is filtered by InputFilter. <br />
255 /// See <see cref="InputFilterType"/> and <see cref="InputFilteredEventArgs"/> for a detailed description. <br />
258 /// The following example demonstrates how to use the InputFiltered event.
260 /// field.InputFiltered += (s, e) =>
262 /// if (e.Type == InputFilterType.Accept)
264 /// // If input is filtered by InputFilter of Accept type.
266 /// else if (e.Type == InputFilterType.Reject)
268 /// // If input is filtered by InputFilter of Reject type.
273 /// <since_tizen> 9 </since_tizen>
274 public event EventHandler<InputFilteredEventArgs> InputFiltered
278 if (textFieldInputFilteredEventHandler == null)
280 textFieldInputFilteredCallbackDelegate = (OnInputFiltered);
281 InputFilteredSignal().Connect(textFieldInputFilteredCallbackDelegate);
283 textFieldInputFilteredEventHandler += value;
287 textFieldInputFilteredEventHandler -= value;
288 if (textFieldInputFilteredEventHandler == null && InputFilteredSignal().Empty() == false)
290 InputFilteredSignal().Disconnect(textFieldInputFilteredCallbackDelegate);
295 internal TextFieldSignal SelectionStartedSignal()
297 TextFieldSignal ret = new TextFieldSignal(Interop.TextField.SelectionStartedSignal(SwigCPtr), false);
298 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
302 internal TextFieldSignal SelectionClearedSignal()
304 TextFieldSignal ret = new TextFieldSignal(Interop.TextField.SelectionClearedSignal(SwigCPtr), false);
305 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
309 internal TextFieldSignal TextChangedSignal()
311 TextFieldSignal ret = new TextFieldSignal(Interop.TextField.TextChangedSignal(SwigCPtr), false);
312 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
316 internal TextFieldSignal CursorPositionChangedSignal()
318 TextFieldSignal ret = new TextFieldSignal(Interop.TextField.CursorPositionChangedSignal(SwigCPtr), false);
319 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
323 internal TextFieldSignal MaxLengthReachedSignal()
325 TextFieldSignal ret = new TextFieldSignal(Interop.TextField.MaxLengthReachedSignal(SwigCPtr), false);
326 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
330 internal TextFieldSignal AnchorClickedSignal()
332 TextFieldSignal ret = new TextFieldSignal(Interop.TextField.AnchorClickedSignal(SwigCPtr), false);
333 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
337 internal TextFieldSignal SelectionChangedSignal()
339 TextFieldSignal ret = new TextFieldSignal(Interop.TextField.SelectionChangedSignal(SwigCPtr), false);
340 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
344 internal TextFieldSignal InputFilteredSignal()
346 TextFieldSignal ret = new TextFieldSignal(Interop.TextField.InputFilteredSignal(SwigCPtr), false);
347 if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
351 private void OnSelectionStarted(IntPtr textField)
353 //no data to be sent to the user
354 textFieldSelectionStartedEventHandler?.Invoke(this, EventArgs.Empty);
357 private void OnSelectionCleared(IntPtr textField)
359 //no data to be sent to the user
360 textFieldSelectionClearedEventHandler?.Invoke(this, EventArgs.Empty);
363 private void OnTextChanged(IntPtr textField)
365 if (textFieldTextChangedEventHandler != null && invokeTextChanged)
367 TextChangedEventArgs e = new TextChangedEventArgs();
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);
376 private void OnCursorPositionChanged(IntPtr textField, uint oldPosition)
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);
382 private void OnMaxLengthReached(IntPtr textField)
384 if (textFieldMaxLengthReachedEventHandler != null)
386 MaxLengthReachedEventArgs e = new MaxLengthReachedEventArgs();
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);
395 private void OnAnchorClicked(IntPtr textField, IntPtr href, uint hrefLength)
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();
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);
407 private void OnSelectionChanged(IntPtr textField, uint oldStart, uint oldEnd)
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);
413 private void OnInputFiltered(IntPtr textField, InputFilterType type)
415 InputFilteredEventArgs e = new InputFilteredEventArgs();
417 // Populate all members of "e" (InputFilteredEventArgs) with real data
419 //here we send all data to user event handlers
420 textFieldInputFilteredEventHandler?.Invoke(this, e);
424 /// The TextChanged event arguments.
426 /// <since_tizen> 3 </since_tizen>
427 public class TextChangedEventArgs : EventArgs
429 private TextField textField;
434 /// <since_tizen> 3 </since_tizen>
435 public TextField TextField
449 /// The MaxLengthReached event arguments.
451 /// <since_tizen> 3 </since_tizen>
452 public class MaxLengthReachedEventArgs : EventArgs
454 private TextField textField;
459 /// <since_tizen> 3 </since_tizen>
460 public TextField TextField