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