3b67ce2e6735cc9020ae646d74350089bca58cf6
[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                 inputFieldAttrs.InputBoxAttributes.TextColor.All = value;
144                 textField.TextColor = value;
145             }
146         }
147
148         /// <summary>
149         /// Gets or sets text color.
150         /// </summary>
151         /// <since_tizen> 6 </since_tizen>
152         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
153         [EditorBrowsable(EditorBrowsableState.Never)]
154         public Color HintTextColor
155         {
156             get
157             {
158                 return textField.PlaceholderTextColor;
159             }
160             set
161             {
162                 CreateTextFieldAttributes();
163                 if (null == inputFieldAttrs.InputBoxAttributes.PlaceholderTextColor)
164                 {
165                     inputFieldAttrs.InputBoxAttributes.PlaceholderTextColor = new Selector<Color>();
166                 }
167                 inputFieldAttrs.InputBoxAttributes.PlaceholderTextColor.All = value;
168                 textField.PlaceholderTextColor = value;
169             }
170         }
171
172         /// <summary>
173         /// Gets or sets primary cursor color.
174         /// </summary>
175         /// <since_tizen> 6 </since_tizen>
176         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
177         [EditorBrowsable(EditorBrowsableState.Never)]
178         public Color PrimaryCursorColor
179         {
180             get
181             {
182                 return textField.PrimaryCursorColor;
183             }
184             set
185             {
186                 CreateTextFieldAttributes();
187                 if (null == inputFieldAttrs.InputBoxAttributes.PrimaryCursorColor)
188                 {
189                     inputFieldAttrs.InputBoxAttributes.PrimaryCursorColor = new Selector<Color>();
190                 }
191                 inputFieldAttrs.InputBoxAttributes.PrimaryCursorColor.All = value;
192                 textField.PrimaryCursorColor = value;
193             }
194         }
195
196         /// <summary>
197         /// Gets or sets font family of text.
198         /// </summary>
199         /// <since_tizen> 6 </since_tizen>
200         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
201         [EditorBrowsable(EditorBrowsableState.Never)]
202         public string FontFamily
203         {
204             get
205             {
206                 return textField.FontFamily;
207             }
208             set
209             {
210                 CreateTextFieldAttributes();
211                 inputFieldAttrs.InputBoxAttributes.FontFamily = value;
212                 textField.FontFamily = value;
213             }
214         }
215
216         /// <summary>
217         /// Gets or sets enable cursor blink.
218         /// </summary>
219         /// <since_tizen> 6 </since_tizen>
220         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
221         [EditorBrowsable(EditorBrowsableState.Never)]
222         public bool EnableCursorBlink
223         {
224             get
225             {
226                 return textField.EnableCursorBlink;
227             }
228             set
229             {
230                 CreateTextFieldAttributes();
231                 inputFieldAttrs.InputBoxAttributes.EnableCursorBlink = value;
232                 textField.EnableCursorBlink = value;
233             }
234         }
235
236         /// <summary>
237         /// Gets or sets enable selection.
238         /// </summary>
239         /// <since_tizen> 6 </since_tizen>
240         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
241         [EditorBrowsable(EditorBrowsableState.Never)]
242         public bool EnableSelection
243         {
244             get
245             {
246                 return textField.EnableSelection;
247             }
248             set
249             {
250                 CreateTextFieldAttributes();
251                 inputFieldAttrs.InputBoxAttributes.EnableSelection = value;
252                 textField.EnableSelection = value;
253             }
254         }
255
256         /// <summary>
257         /// Gets or sets cursor width.
258         /// </summary>
259         /// <since_tizen> 6 </since_tizen>
260         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
261         [EditorBrowsable(EditorBrowsableState.Never)]
262         public int CursorWidth
263         {
264             get
265             {
266                 return textField.CursorWidth;
267             }
268             set
269             {
270                 CreateTextFieldAttributes();
271                 inputFieldAttrs.InputBoxAttributes.CursorWidth = value;
272                 textField.CursorWidth = value;
273             }
274         }
275
276         /// <summary>
277         /// Gets or sets if enable ellipsis.
278         /// </summary>
279         /// <since_tizen> 6 </since_tizen>
280         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
281         [EditorBrowsable(EditorBrowsableState.Never)]
282         public bool EnableEllipsis
283         {
284             get
285             {
286                 return textField.Ellipsis;
287             }
288             set
289             {
290                 CreateTextFieldAttributes();
291                 inputFieldAttrs.InputBoxAttributes.Ellipsis = value;
292                 textField.Ellipsis = value;
293             }
294         }
295
296         /// <summary>
297         /// Gets or sets background image's resource url of input field.
298         /// </summary>
299         /// <since_tizen> 6 </since_tizen>
300         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
301         [EditorBrowsable(EditorBrowsableState.Never)]
302         public string BackgroundImageURL
303         {
304             get
305             {
306                 return inputFieldAttrs.BackgroundImageAttributes?.ResourceUrl?.All;
307             }
308             set
309             {
310                 if (value != null)
311                 {
312                     CreateBackgroundAttributes();
313                     if (inputFieldAttrs.BackgroundImageAttributes.ResourceUrl == null)
314                     {
315                         inputFieldAttrs.BackgroundImageAttributes.ResourceUrl = new Selector<string>();
316                     }
317                     inputFieldAttrs.BackgroundImageAttributes.ResourceUrl.All = value;
318                     RelayoutRequest();
319                 }
320             }
321         }
322
323         /// <summary>
324         /// Background image's border in Button.
325         /// </summary>
326         /// <since_tizen> 6 </since_tizen>
327         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
328         [EditorBrowsable(EditorBrowsableState.Never)]
329         public Rectangle BackgroundImageBorder
330         {
331             get
332             {
333                 return inputFieldAttrs.BackgroundImageAttributes?.Border?.All;
334             }
335             set
336             {
337                 if (value != null)
338                 {
339                     CreateBackgroundAttributes();
340                     if (inputFieldAttrs.BackgroundImageAttributes.Border == null)
341                     {
342                         inputFieldAttrs.BackgroundImageAttributes.Border = new Selector<Rectangle>();
343                     }
344                     inputFieldAttrs.BackgroundImageAttributes.Border.All = value;
345                     RelayoutRequest();
346                 }
347             }
348         }
349
350         /// <summary>
351         /// Gets and Sets Space.
352         /// </summary>
353         public int Space
354         {
355             get
356             {
357                 return inputFieldAttrs.Space ?? 0;
358             }
359             set
360             {
361                 inputFieldAttrs.Space = value;
362                 RelayoutRequest();
363             }
364         }
365
366         /// <summary>
367         /// Get Input Field attribues.
368         /// </summary>
369         /// <since_tizen> 6 </since_tizen>
370         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
371         [EditorBrowsable(EditorBrowsableState.Never)]
372         protected override ViewStyle GetViewStyle()
373         {
374             return new InputFieldStyle();
375         }
376
377         /// <summary>
378         /// Dispose Input Field and all children on it.
379         /// </summary>
380         /// <param name="type">Dispose type.</param>
381         /// <since_tizen> 6 </since_tizen>
382         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
383         [EditorBrowsable(EditorBrowsableState.Never)]
384         protected override void Dispose(DisposeTypes type)
385         {
386             if (disposed)
387             {
388                 return;
389             }
390             if (type == DisposeTypes.Explicit)
391             {
392                 if (bgImage != null)
393                 {
394                     this.Remove(bgImage);
395                     bgImage.Dispose();
396                     bgImage = null;
397                 }
398                 if (null != textField)
399                 {
400                     textField.FocusGained -= OnTextFieldFocusGained;
401                     textField.FocusLost -= OnTextFieldFocusLost;
402                     textField.TextChanged -= OnTextFieldTextChanged;
403                     textField.KeyEvent -= OnTextFieldKeyEvent;
404                     this.Remove(textField);
405                     textField.Dispose();
406                     textField = null;
407                 }
408             }
409
410             base.Dispose(type);
411         }
412
413         /// <summary>
414         /// Update Input Field by attributes.
415         /// </summary>
416         /// <since_tizen> 6 </since_tizen>
417         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
418         [EditorBrowsable(EditorBrowsableState.Never)]
419         protected override void OnUpdate()
420         {
421             RelayoutComponent();
422             OnLayoutDirectionChanged();
423         }
424
425         /// <summary>
426         /// Theme change callback when theme is changed, this callback will be trigger.
427         /// </summary>
428         /// <since_tizen> 6 </since_tizen>
429         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
430         [EditorBrowsable(EditorBrowsableState.Never)]
431         protected override void OnThemeChangedEvent(object sender, StyleManager.ThemeChangeEventArgs e)
432         {
433             InputFieldStyle tempStyle = StyleManager.Instance.GetAttributes(style) as InputFieldStyle;
434             if (tempStyle != null)
435             {
436                 Style.CopyFrom(tempStyle);
437                 RelayoutRequest();
438             }
439         }
440
441         /// <summary>
442         /// Theme change callback when text field focus is gained, this callback will be trigger.
443         /// </summary>
444         /// <since_tizen> 6 </since_tizen>
445         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
446         [EditorBrowsable(EditorBrowsableState.Never)]
447         protected virtual void OnTextFieldFocusGained(object source, EventArgs e)
448         {
449         }
450
451         /// <summary>
452         /// Theme change callback when text field is lost, this callback will be trigger.
453         /// </summary>
454         /// <since_tizen> 6 </since_tizen>
455         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
456         [EditorBrowsable(EditorBrowsableState.Never)]
457         protected virtual void OnTextFieldFocusLost(object source, EventArgs e)
458         {
459         }
460
461         /// <summary>
462         /// Theme change callback when text field's text is changed, this callback will be trigger.
463         /// </summary>
464         /// <since_tizen> 6 </since_tizen>
465         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
466         [EditorBrowsable(EditorBrowsableState.Never)]
467         protected virtual void OnTextFieldTextChanged(object sender, TextField.TextChangedEventArgs e)
468         {
469         }
470
471         /// <summary>
472         /// Theme change callback when text field have a key event, this callback will be trigger.
473         /// </summary>
474         /// <since_tizen> 6 </since_tizen>
475         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
476         [EditorBrowsable(EditorBrowsableState.Never)]
477         protected virtual bool OnTextFieldKeyEvent(object source, KeyEventArgs e)
478         {
479             return false;
480         }
481
482         /// <summary>
483         /// Set the text field 2D size
484         /// </summary>
485         /// <param name="w">Input Field' width.</param>
486         /// <param name="h">Input Field' height.</param>
487         /// <since_tizen> 6 </since_tizen>
488         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
489         [EditorBrowsable(EditorBrowsableState.Never)]
490         protected void SetTextFieldSize2D(int w, int h)
491         {
492             if (textField != null)
493             {
494                 textField.Size2D = new Size2D(w, h);
495             }
496         }
497
498         /// <summary>
499         /// Set the text field X pose
500         /// </summary>
501         /// <param name="x">Input Field' X.</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 SetTextFieldPosX(int x)
506         {
507             if (textField != null)
508             {
509                 textField.PositionX = x;
510             }
511         }
512
513         /// <summary>
514         /// Set the text field  text color
515         /// </summary>
516         /// <param name="color">Input Field' color.</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 SetTextFieldTextColor(Color color)
521         {
522             if (textField != null)
523             {
524                 textField.TextColor = color;
525             }
526         }
527
528         /// <summary>
529         /// Set the text field relayout flag
530         /// </summary>
531         /// <param name="value">relayout text field' value.</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 RelayoutTextField(bool value)
536         {
537             relayoutTextField = value;
538         }
539
540         private void Initialize()
541         {
542             inputFieldAttrs = Style as InputFieldStyle;
543             if (null == inputFieldAttrs)
544             {
545                 throw new Exception("Fail to get the InputField attributes.");
546             }
547
548             bgImage = new ImageView();
549             if (null == bgImage)
550             {
551                 throw new Exception("Fail to create background image.");
552             }
553
554             textField = new TextField();
555             if (null == textField)
556             {
557                 throw new Exception("Fail to create text field.");
558             }
559
560             if (null != inputFieldAttrs.BackgroundImageAttributes)
561             {
562                 bgImage.WidthResizePolicy = ResizePolicyType.FillToParent;
563                 bgImage.HeightResizePolicy = ResizePolicyType.FillToParent;
564                 bgImage.ParentOrigin = Tizen.NUI.ParentOrigin.Center;
565                 bgImage.PivotPoint = Tizen.NUI.PivotPoint.Center;
566                 bgImage.PositionUsesPivotPoint = true;
567                 this.Add(bgImage);
568             }
569
570             if (null != inputFieldAttrs.InputBoxAttributes)
571             {
572                 textField.WidthResizePolicy = ResizePolicyType.Fixed;
573                 textField.HeightResizePolicy = ResizePolicyType.Fixed;
574                 textField.ParentOrigin = Tizen.NUI.ParentOrigin.CenterLeft;
575                 textField.PivotPoint = Tizen.NUI.PivotPoint.CenterLeft;
576                 textField.PositionUsesPivotPoint = true;
577                 this.Add(textField);
578
579                 textField.FocusGained += OnTextFieldFocusGained;
580                 textField.FocusLost += OnTextFieldFocusLost;
581                 textField.TextChanged += OnTextFieldTextChanged;
582                 textField.KeyEvent += OnTextFieldKeyEvent;
583             }
584         }
585
586         private void OnLayoutDirectionChanged()
587         {
588             if (inputFieldAttrs == null) return;
589             if (textField != null)
590             {
591                 if (LayoutDirection == ViewLayoutDirectionType.LTR)
592                 {
593                     if(inputFieldAttrs.InputBoxAttributes != null)
594                     {
595                         inputFieldAttrs.InputBoxAttributes.HorizontalAlignment = HorizontalAlignment.Begin;
596                         inputFieldAttrs.InputBoxAttributes.ParentOrigin = Tizen.NUI.ParentOrigin.CenterLeft;
597                         inputFieldAttrs.InputBoxAttributes.PivotPoint = Tizen.NUI.PivotPoint.CenterLeft;
598                         inputFieldAttrs.InputBoxAttributes.PositionUsesPivotPoint = true;
599                     }
600                     textField.HorizontalAlignment = HorizontalAlignment.Begin;
601                     textField.ParentOrigin = Tizen.NUI.ParentOrigin.CenterLeft;
602                     textField.PivotPoint = Tizen.NUI.PivotPoint.CenterLeft;
603                     textField.PositionUsesPivotPoint = true;
604                 }
605                 else //ViewLayoutDirectionType.RTL
606                 {
607                     if (inputFieldAttrs.InputBoxAttributes != null)
608                     {
609                         inputFieldAttrs.InputBoxAttributes.HorizontalAlignment = HorizontalAlignment.End;
610                         inputFieldAttrs.InputBoxAttributes.ParentOrigin = Tizen.NUI.ParentOrigin.CenterRight;
611                         inputFieldAttrs.InputBoxAttributes.PivotPoint = Tizen.NUI.PivotPoint.CenterRight;
612                     }
613                     textField.HorizontalAlignment = HorizontalAlignment.End;
614                     textField.ParentOrigin = Tizen.NUI.ParentOrigin.CenterRight;
615                     textField.PivotPoint = Tizen.NUI.PivotPoint.CenterRight;
616                     textField.PositionUsesPivotPoint = true;
617                 }
618             }
619         }
620
621         private void RelayoutComponent()
622         {
623             if (!relayoutTextField)
624             {
625                 return;
626             }
627             int space = inputFieldAttrs.Space ?? 0;
628
629             if (textField != null)
630             {
631                 textField.Size2D = new Size2D(this.Size2D.Width - space * 2, this.Size2D.Height);
632                 textField.PositionX = space;
633             }
634         }
635
636         private void CreateBackgroundAttributes()
637         {
638             if (null == inputFieldAttrs.BackgroundImageAttributes)
639             {
640                 inputFieldAttrs.BackgroundImageAttributes = new ImageViewStyle();
641             }
642         }
643
644         private void CreateTextFieldAttributes()
645         {
646             if (null == inputFieldAttrs.InputBoxAttributes)
647             {
648                 inputFieldAttrs.InputBoxAttributes = new TextFieldStyle();
649             }
650         }
651     }
652 }