dd007ac08d24084c57e7164b98be1f37b24124ac
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Components / Controls / InputField.cs
1 /*
2  * Copyright(c) 2019 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 using System;
18 using Tizen.NUI.BaseComponents;
19 using System.ComponentModel;
20
21 namespace Tizen.NUI.Components
22 {
23     /// <summary>
24     /// InputField is a editable input compoment
25     /// </summary>
26     /// <since_tizen> 6 </since_tizen>
27     /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
28     [EditorBrowsable(EditorBrowsableState.Never)]
29     public class InputField : Control
30     {
31         // the background image
32         private ImageView bgImage = null;
33         // the textField
34         private TextField textField = null;
35         // the attributes of the inputField
36         private InputFieldStyle inputFieldAttrs = null;
37         // the flag indicate should relayout the textField in base class
38         private bool relayoutTextField = true;
39
40         /// <summary>
41         /// Initializes a new instance of the InputField class.
42         /// </summary>
43         /// <since_tizen> 6 </since_tizen>
44         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
45         [EditorBrowsable(EditorBrowsableState.Never)]
46         public InputField() : base()
47         {
48             Initialize();
49         }
50
51         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
52         [EditorBrowsable(EditorBrowsableState.Never)]
53         public InputField(string style) : base(style)
54         {
55             Initialize();
56         }
57
58         /// <summary>
59         /// Initializes a new instance of the InputField class.
60         /// </summary>
61         /// <param name="attributes">Create Header by attributes customized by user.</param>
62         /// <since_tizen> 6 </since_tizen>
63         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
64         [EditorBrowsable(EditorBrowsableState.Never)]
65         public InputField(InputFieldStyle attributes) : base(attributes)
66         {
67             Initialize();
68         }
69
70         /// <summary>
71         /// Gets or sets the property for the enabled state.
72         /// </summary>
73         /// <since_tizen> 6 </since_tizen>
74         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
75         [EditorBrowsable(EditorBrowsableState.Never)]
76         public bool StateEnabled
77         {
78             get
79             {
80                 return Sensitive;
81             }
82             set
83             {
84                 Sensitive = value;
85             }
86         }
87
88         /// <summary>
89         /// Gets or sets the property for the text content.
90         /// </summary>
91         /// <since_tizen> 6 </since_tizen>
92         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
93         [EditorBrowsable(EditorBrowsableState.Never)]
94         public string Text
95         {
96             get
97             {
98                 return textField.Text;
99             }
100             set
101             {
102                 textField.Text = value;
103             }
104         }
105
106         /// <summary>
107         /// Gets or sets the property for the hint text.
108         /// </summary>
109         /// <since_tizen> 6 </since_tizen>
110         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
111         [EditorBrowsable(EditorBrowsableState.Never)]
112         public string HintText
113         {
114             get
115             {
116                 return textField.PlaceholderText;
117             }
118             set
119             {
120                 textField.PlaceholderText = value;
121             }
122         }
123
124         /// <summary>
125         /// Gets or sets the property for the color of the input text.
126         /// </summary>
127         /// <since_tizen> 6 </since_tizen>
128         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
129         [EditorBrowsable(EditorBrowsableState.Never)]
130         public Color TextColor
131         {
132             get
133             {
134                 return textField.TextColor;
135             }
136             set
137             {
138                 CreateTextFieldAttributes();
139                 if (null == inputFieldAttrs.InputBoxAttributes.TextColor)
140                 {
141                     inputFieldAttrs.InputBoxAttributes.TextColor = new Selector<Color>();
142                 }
143                 if (null != inputFieldAttrs.InputBoxAttributes.TextColor)
144                 {
145                     inputFieldAttrs.InputBoxAttributes.TextColor.All = value;
146                 }
147                 textField.TextColor = value;
148             }
149         }
150
151         /// <summary>
152         /// Gets or sets text color.
153         /// </summary>
154         /// <since_tizen> 6 </since_tizen>
155         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
156         [EditorBrowsable(EditorBrowsableState.Never)]
157         public Color HintTextColor
158         {
159             get
160             {
161                 return textField.PlaceholderTextColor;
162             }
163             set
164             {
165                 CreateTextFieldAttributes();
166                 if (null == inputFieldAttrs.InputBoxAttributes.PlaceholderTextColor)
167                 {
168                     inputFieldAttrs.InputBoxAttributes.PlaceholderTextColor = new Selector<Color>();
169                 }
170                 if (null != inputFieldAttrs.InputBoxAttributes.PlaceholderTextColor)
171                 {
172                     inputFieldAttrs.InputBoxAttributes.PlaceholderTextColor.All = value;
173                 }
174                 textField.PlaceholderTextColor = value;
175             }
176         }
177
178         /// <summary>
179         /// Gets or sets primary cursor color.
180         /// </summary>
181         /// <since_tizen> 6 </since_tizen>
182         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
183         [EditorBrowsable(EditorBrowsableState.Never)]
184         public Color PrimaryCursorColor
185         {
186             get
187             {
188                 return textField.PrimaryCursorColor;
189             }
190             set
191             {
192                 CreateTextFieldAttributes();
193                 if (null == inputFieldAttrs.InputBoxAttributes.PrimaryCursorColor)
194                 {
195                     inputFieldAttrs.InputBoxAttributes.PrimaryCursorColor = new Selector<Color>();
196                 }
197                 if (null != inputFieldAttrs.InputBoxAttributes.PrimaryCursorColor)
198                 {
199                     inputFieldAttrs.InputBoxAttributes.PrimaryCursorColor.All = value;
200                 }
201                 textField.PrimaryCursorColor = value;
202             }
203         }
204
205         /// <summary>
206         /// Gets or sets font family of text.
207         /// </summary>
208         /// <since_tizen> 6 </since_tizen>
209         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
210         [EditorBrowsable(EditorBrowsableState.Never)]
211         public string FontFamily
212         {
213             get
214             {
215                 return textField.FontFamily;
216             }
217             set
218             {
219                 CreateTextFieldAttributes();
220                 inputFieldAttrs.InputBoxAttributes.FontFamily = value;
221                 textField.FontFamily = value;
222             }
223         }
224
225         /// <summary>
226         /// Gets or sets enable cursor blink.
227         /// </summary>
228         /// <since_tizen> 6 </since_tizen>
229         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
230         [EditorBrowsable(EditorBrowsableState.Never)]
231         public bool EnableCursorBlink
232         {
233             get
234             {
235                 return textField.EnableCursorBlink;
236             }
237             set
238             {
239                 CreateTextFieldAttributes();
240                 inputFieldAttrs.InputBoxAttributes.EnableCursorBlink = value;
241                 textField.EnableCursorBlink = value;
242             }
243         }
244
245         /// <summary>
246         /// Gets or sets enable selection.
247         /// </summary>
248         /// <since_tizen> 6 </since_tizen>
249         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
250         [EditorBrowsable(EditorBrowsableState.Never)]
251         public bool EnableSelection
252         {
253             get
254             {
255                 return textField.EnableSelection;
256             }
257             set
258             {
259                 CreateTextFieldAttributes();
260                 inputFieldAttrs.InputBoxAttributes.EnableSelection = value;
261                 textField.EnableSelection = value;
262             }
263         }
264
265         /// <summary>
266         /// Gets or sets cursor width.
267         /// </summary>
268         /// <since_tizen> 6 </since_tizen>
269         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
270         [EditorBrowsable(EditorBrowsableState.Never)]
271         public int CursorWidth
272         {
273             get
274             {
275                 return textField.CursorWidth;
276             }
277             set
278             {
279                 CreateTextFieldAttributes();
280                 inputFieldAttrs.InputBoxAttributes.CursorWidth = value;
281                 textField.CursorWidth = value;
282             }
283         }
284
285         /// <summary>
286         /// Gets or sets if enable ellipsis.
287         /// </summary>
288         /// <since_tizen> 6 </since_tizen>
289         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
290         [EditorBrowsable(EditorBrowsableState.Never)]
291         public bool EnableEllipsis
292         {
293             get
294             {
295                 return textField.Ellipsis;
296             }
297             set
298             {
299                 CreateTextFieldAttributes();
300                 inputFieldAttrs.InputBoxAttributes.Ellipsis = value;
301                 textField.Ellipsis = value;
302             }
303         }
304
305         /// <summary>
306         /// Gets or sets background image's resource url of input field.
307         /// </summary>
308         /// <since_tizen> 6 </since_tizen>
309         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
310         [EditorBrowsable(EditorBrowsableState.Never)]
311         public string BackgroundImageURL
312         {
313             get
314             {
315                 return inputFieldAttrs.BackgroundImageAttributes?.ResourceUrl?.All;
316             }
317             set
318             {
319                 if (value != null)
320                 {
321                     CreateBackgroundAttributes();
322                     if (inputFieldAttrs.BackgroundImageAttributes.ResourceUrl == null)
323                     {
324                         inputFieldAttrs.BackgroundImageAttributes.ResourceUrl = new Selector<string>();
325                     }
326                     if (inputFieldAttrs.BackgroundImageAttributes.ResourceUrl != null)
327                     {
328                         inputFieldAttrs.BackgroundImageAttributes.ResourceUrl.All = value;
329                     }
330                     RelayoutRequest();
331                 }
332             }
333         }
334
335         /// <summary>
336         /// Background image's border in Button.
337         /// </summary>
338         /// <since_tizen> 6 </since_tizen>
339         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
340         [EditorBrowsable(EditorBrowsableState.Never)]
341         public Rectangle BackgroundImageBorder
342         {
343             get
344             {
345                 return inputFieldAttrs.BackgroundImageAttributes?.Border?.All;
346             }
347             set
348             {
349                 if (value != null)
350                 {
351                     CreateBackgroundAttributes();
352                     if (inputFieldAttrs.BackgroundImageAttributes.Border == null)
353                     {
354                         inputFieldAttrs.BackgroundImageAttributes.Border = new Selector<Rectangle>();
355                     }
356                     if (inputFieldAttrs.BackgroundImageAttributes.Border != null)
357                     {
358                         inputFieldAttrs.BackgroundImageAttributes.Border.All = value;
359                     }
360                     RelayoutRequest();
361                 }
362             }
363         }
364
365         /// <summary>
366         /// Gets and Sets Space.
367         /// </summary>
368         public int Space
369         {
370             get
371             {
372                 return inputFieldAttrs.Space ?? 0;
373             }
374             set
375             {
376                 inputFieldAttrs.Space = value;
377                 RelayoutRequest();
378             }
379         }
380
381         /// <summary>
382         /// Get Input Field attribues.
383         /// </summary>
384         /// <since_tizen> 6 </since_tizen>
385         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
386         [EditorBrowsable(EditorBrowsableState.Never)]
387         protected override ViewStyle GetViewStyle()
388         {
389             return new InputFieldStyle();
390         }
391
392         /// <summary>
393         /// Dispose Input Field and all children on it.
394         /// </summary>
395         /// <param name="type">Dispose type.</param>
396         /// <since_tizen> 6 </since_tizen>
397         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
398         [EditorBrowsable(EditorBrowsableState.Never)]
399         protected override void Dispose(DisposeTypes type)
400         {
401             if (disposed)
402             {
403                 return;
404             }
405             if (type == DisposeTypes.Explicit)
406             {
407                 if (bgImage != null)
408                 {
409                     this.Remove(bgImage);
410                     bgImage.Dispose();
411                     bgImage = null;
412                 }
413                 if (null != textField)
414                 {
415                     textField.FocusGained -= OnTextFieldFocusGained;
416                     textField.FocusLost -= OnTextFieldFocusLost;
417                     textField.TextChanged -= OnTextFieldTextChanged;
418                     textField.KeyEvent -= OnTextFieldKeyEvent;
419                     this.Remove(textField);
420                     textField.Dispose();
421                     textField = null;
422                 }
423             }
424
425             base.Dispose(type);
426         }
427
428         /// <summary>
429         /// Update Input Field by attributes.
430         /// </summary>
431         /// <since_tizen> 6 </since_tizen>
432         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
433         [EditorBrowsable(EditorBrowsableState.Never)]
434         protected override void OnUpdate()
435         {
436             RelayoutComponent();
437             OnLayoutDirectionChanged();
438         }
439
440         /// <summary>
441         /// Theme change callback when theme is changed, this callback will be trigger.
442         /// </summary>
443         /// <since_tizen> 6 </since_tizen>
444         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
445         [EditorBrowsable(EditorBrowsableState.Never)]
446         protected override void OnThemeChangedEvent(object sender, StyleManager.ThemeChangeEventArgs e)
447         {
448             InputFieldStyle tempStyle = StyleManager.Instance.GetAttributes(style) as InputFieldStyle;
449             if (tempStyle != null)
450             {
451                 Style.CopyFrom(tempStyle);
452                 RelayoutRequest();
453             }
454         }
455
456         /// <summary>
457         /// Theme change callback when text field focus is gained, this callback will be trigger.
458         /// </summary>
459         /// <since_tizen> 6 </since_tizen>
460         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
461         [EditorBrowsable(EditorBrowsableState.Never)]
462         protected virtual void OnTextFieldFocusGained(object source, EventArgs e)
463         {
464         }
465
466         /// <summary>
467         /// Theme change callback when text field is lost, this callback will be trigger.
468         /// </summary>
469         /// <since_tizen> 6 </since_tizen>
470         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
471         [EditorBrowsable(EditorBrowsableState.Never)]
472         protected virtual void OnTextFieldFocusLost(object source, EventArgs e)
473         {
474         }
475
476         /// <summary>
477         /// Theme change callback when text field's text is changed, this callback will be trigger.
478         /// </summary>
479         /// <since_tizen> 6 </since_tizen>
480         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
481         [EditorBrowsable(EditorBrowsableState.Never)]
482         protected virtual void OnTextFieldTextChanged(object sender, TextField.TextChangedEventArgs e)
483         {
484         }
485
486         /// <summary>
487         /// Theme change callback when text field have a key event, this callback will be trigger.
488         /// </summary>
489         /// <since_tizen> 6 </since_tizen>
490         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
491         [EditorBrowsable(EditorBrowsableState.Never)]
492         protected virtual bool OnTextFieldKeyEvent(object source, KeyEventArgs e)
493         {
494             return false;
495         }
496
497         /// <summary>
498         /// Set the text field 2D size
499         /// </summary>
500         /// <param name="w">Input Field' width.</param>
501         /// <param name="h">Input Field' height.</param>
502         /// <since_tizen> 6 </since_tizen>
503         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
504         [EditorBrowsable(EditorBrowsableState.Never)]
505         protected void SetTextFieldSize2D(int w, int h)
506         {
507             if (textField != null)
508             {
509                 textField.Size2D = new Size2D(w, h);
510             }
511         }
512
513         /// <summary>
514         /// Set the text field X pose
515         /// </summary>
516         /// <param name="x">Input Field' X.</param>
517         /// <since_tizen> 6 </since_tizen>
518         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
519         [EditorBrowsable(EditorBrowsableState.Never)]
520         protected void SetTextFieldPosX(int x)
521         {
522             if (textField != null)
523             {
524                 textField.PositionX = x;
525             }
526         }
527
528         /// <summary>
529         /// Set the text field  text color
530         /// </summary>
531         /// <param name="color">Input Field' color.</param>
532         /// <since_tizen> 6 </since_tizen>
533         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
534         [EditorBrowsable(EditorBrowsableState.Never)]
535         protected void SetTextFieldTextColor(Color color)
536         {
537             if (textField != null)
538             {
539                 textField.TextColor = color;
540             }
541         }
542
543         /// <summary>
544         /// Set the text field relayout flag
545         /// </summary>
546         /// <param name="value">relayout text field' value.</param>
547         /// <since_tizen> 6 </since_tizen>
548         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
549         [EditorBrowsable(EditorBrowsableState.Never)]
550         protected void RelayoutTextField(bool value)
551         {
552             relayoutTextField = value;
553         }
554
555         private void Initialize()
556         {
557             inputFieldAttrs = Style as InputFieldStyle;
558             if (null == inputFieldAttrs)
559             {
560                 throw new Exception("Fail to get the InputField attributes.");
561             }
562
563             bgImage = new ImageView();
564             if (null == bgImage)
565             {
566                 throw new Exception("Fail to create background image.");
567             }
568
569             textField = new TextField();
570             if (null == textField)
571             {
572                 throw new Exception("Fail to create text field.");
573             }
574
575             if (null != inputFieldAttrs.BackgroundImageAttributes)
576             {
577                 bgImage.WidthResizePolicy = ResizePolicyType.FillToParent;
578                 bgImage.HeightResizePolicy = ResizePolicyType.FillToParent;
579                 bgImage.ParentOrigin = Tizen.NUI.ParentOrigin.Center;
580                 bgImage.PivotPoint = Tizen.NUI.PivotPoint.Center;
581                 bgImage.PositionUsesPivotPoint = true;
582                 this.Add(bgImage);
583             }
584
585             if (null != inputFieldAttrs.InputBoxAttributes)
586             {
587                 textField.WidthResizePolicy = ResizePolicyType.Fixed;
588                 textField.HeightResizePolicy = ResizePolicyType.Fixed;
589                 textField.ParentOrigin = Tizen.NUI.ParentOrigin.CenterLeft;
590                 textField.PivotPoint = Tizen.NUI.PivotPoint.CenterLeft;
591                 textField.PositionUsesPivotPoint = true;
592                 this.Add(textField);
593
594                 textField.FocusGained += OnTextFieldFocusGained;
595                 textField.FocusLost += OnTextFieldFocusLost;
596                 textField.TextChanged += OnTextFieldTextChanged;
597                 textField.KeyEvent += OnTextFieldKeyEvent;
598             }
599         }
600
601         private void OnLayoutDirectionChanged()
602         {
603             if (inputFieldAttrs == null) return;
604             if (textField != null)
605             {
606                 if (LayoutDirection == ViewLayoutDirectionType.LTR)
607                 {
608                     if(inputFieldAttrs.InputBoxAttributes != null)
609                     {
610                         inputFieldAttrs.InputBoxAttributes.HorizontalAlignment = HorizontalAlignment.Begin;
611                         inputFieldAttrs.InputBoxAttributes.ParentOrigin = Tizen.NUI.ParentOrigin.CenterLeft;
612                         inputFieldAttrs.InputBoxAttributes.PivotPoint = Tizen.NUI.PivotPoint.CenterLeft;
613                         inputFieldAttrs.InputBoxAttributes.PositionUsesPivotPoint = true;
614                     }
615                     textField.HorizontalAlignment = HorizontalAlignment.Begin;
616                     textField.ParentOrigin = Tizen.NUI.ParentOrigin.CenterLeft;
617                     textField.PivotPoint = Tizen.NUI.PivotPoint.CenterLeft;
618                     textField.PositionUsesPivotPoint = true;
619                 }
620                 else //ViewLayoutDirectionType.RTL
621                 {
622                     if (inputFieldAttrs.InputBoxAttributes != null)
623                     {
624                         inputFieldAttrs.InputBoxAttributes.HorizontalAlignment = HorizontalAlignment.End;
625                         inputFieldAttrs.InputBoxAttributes.ParentOrigin = Tizen.NUI.ParentOrigin.CenterRight;
626                         inputFieldAttrs.InputBoxAttributes.PivotPoint = Tizen.NUI.PivotPoint.CenterRight;
627                     }
628                     textField.HorizontalAlignment = HorizontalAlignment.End;
629                     textField.ParentOrigin = Tizen.NUI.ParentOrigin.CenterRight;
630                     textField.PivotPoint = Tizen.NUI.PivotPoint.CenterRight;
631                     textField.PositionUsesPivotPoint = true;
632                 }
633             }
634         }
635
636         private void RelayoutComponent()
637         {
638             if (!relayoutTextField)
639             {
640                 return;
641             }
642             int space = inputFieldAttrs.Space ?? 0;
643
644             if (textField != null)
645             {
646                 textField.Size2D = new Size2D(this.Size2D.Width - space * 2, this.Size2D.Height);
647                 textField.PositionX = space;
648             }
649         }
650
651         private void CreateBackgroundAttributes()
652         {
653             if (null == inputFieldAttrs.BackgroundImageAttributes)
654             {
655                 inputFieldAttrs.BackgroundImageAttributes = new ImageViewStyle();
656             }
657         }
658
659         private void CreateTextFieldAttributes()
660         {
661             if (null == inputFieldAttrs.InputBoxAttributes)
662             {
663                 inputFieldAttrs.InputBoxAttributes = new TextFieldStyle();
664             }
665         }
666     }
667 }