Support TranslatablePlaceholderTextFocused to TextField
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Components / Controls / DropDown.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 System.Collections.Generic;
19 using Tizen.NUI.BaseComponents;
20 using System.ComponentModel;
21 using Tizen.NUI.Binding;
22 using Tizen.NUI.Accessibility;
23
24 namespace Tizen.NUI.Components
25 {
26     /// <summary>
27     /// DropDown is one kind of common component, a dropdown allows the user click dropdown button to choose one value from a list.
28     /// </summary>
29     /// <since_tizen> 6 </since_tizen>
30     /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
31     [EditorBrowsable(EditorBrowsableState.Never)]
32     public partial class DropDown : Control
33     {
34         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
35         [EditorBrowsable(EditorBrowsableState.Never)]
36         public static readonly BindableProperty ListPaddingProperty = BindableProperty.Create(nameof(ListPadding), typeof(Extents), typeof(DropDown), null, propertyChanged: (bindable, oldValue, newValue) =>
37         {
38             var instance = (DropDown)bindable;
39             if (newValue != null)
40             {
41                 instance.dropDownStyle.ListPadding.CopyFrom((Extents)newValue);
42                 instance.UpdateDropDown();
43             }
44         },
45         defaultValueCreator: (bindable) =>
46         {
47             var instance = (DropDown)bindable;
48             return instance.dropDownStyle.ListPadding;
49         });
50         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
51         [EditorBrowsable(EditorBrowsableState.Never)]
52         public static readonly BindableProperty SelectedItemIndexProperty = BindableProperty.Create(nameof(SelectedItemIndex), typeof(int), typeof(DropDown), 0, propertyChanged: (bindable, oldValue, newValue) =>
53         {
54             var instance = (DropDown)bindable;
55             if (newValue != null)
56             {
57                 int selectedItemIndex = (int)newValue;
58                 if (selectedItemIndex == instance.dropDownStyle.SelectedItemIndex || instance.adapter == null || selectedItemIndex < 0 || selectedItemIndex >= instance.adapter.GetItemCount())
59                 {
60                     return;
61                 }
62                 instance.SetListItemToSelected((uint)selectedItemIndex);
63             }
64         },
65         defaultValueCreator: (bindable) =>
66         {
67             var instance = (DropDown)bindable;
68             return instance.dropDownStyle.SelectedItemIndex;
69         });
70         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
71         [EditorBrowsable(EditorBrowsableState.Never)]
72         public static readonly BindableProperty ListMarginProperty = BindableProperty.Create(nameof(ListMargin), typeof(Extents), typeof(DropDown), null, propertyChanged: (bindable, oldValue, newValue) =>
73         {
74             var instance = (DropDown)bindable;
75             if (newValue != null)
76             {
77                 instance.dropDownStyle.ListMargin.CopyFrom((Extents)newValue);
78                 instance.UpdateDropDown();
79             }
80         },
81         defaultValueCreator: (bindable) =>
82         {
83             var instance = (DropDown)bindable;
84             return instance.dropDownStyle.ListMargin;
85         });
86         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
87         [EditorBrowsable(EditorBrowsableState.Never)]
88         public static readonly BindableProperty ListRelativeOrientationProperty = BindableProperty.Create(nameof(ListRelativeOrientation), typeof(ListOrientation), typeof(DropDown), ListOrientation.Left, propertyChanged: (bindable, oldValue, newValue) =>
89         {
90             var instance = (DropDown)bindable;
91             if (newValue != null)
92             {
93                 instance.dropDownStyle.ListRelativeOrientation = (ListOrientation)newValue;
94                 instance.UpdateDropDown();
95             }
96         },
97         defaultValueCreator: (bindable) =>
98         {
99             var instance = (DropDown)bindable;
100             return instance.dropDownStyle.ListRelativeOrientation;
101         });
102         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
103         [EditorBrowsable(EditorBrowsableState.Never)]
104         public static readonly BindableProperty SpaceBetweenButtonTextAndIconProperty = BindableProperty.Create(nameof(SpaceBetweenButtonTextAndIcon), typeof(int), typeof(DropDown), 0, propertyChanged: (bindable, oldValue, newValue) =>
105         {
106             var instance = (DropDown)bindable;
107             if (newValue != null)
108             {
109                 instance.dropDownStyle.SpaceBetweenButtonTextAndIcon = (int)newValue;
110             }
111         },
112         defaultValueCreator: (bindable) =>
113         {
114             var instance = (DropDown)bindable;
115             return instance.dropDownStyle.SpaceBetweenButtonTextAndIcon;
116         });
117
118         #region DropDown
119         private Button button = null;
120         private TextLabel headerText = null;
121         private TextLabel buttonText = null;
122         private ImageView listBackgroundImage = null;
123         // Component that scrolls the child added to it.
124         private ScrollableBase scrollableBase = null;
125
126         // The LinearLayout container to house the items in the drop down list.
127         private View dropDownMenuFullList = null;
128         private DropDownListBridge adapter = new DropDownListBridge();
129         private DropDownItemView selectedItemView = null;
130         private TapGestureDetector tapGestureDetector = null;
131
132         private bool itemPressed = false;
133
134         static DropDown() { }
135
136         /// <summary>
137         /// Creates a new instance of a DropDown.
138         /// </summary>
139         /// <since_tizen> 6 </since_tizen>
140         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
141         [EditorBrowsable(EditorBrowsableState.Never)]
142         public DropDown() : base()
143         {
144             AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Trait, "DropDown");
145         }
146
147         /// <summary>
148         /// Creates a new instance of a DropDown with style.
149         /// </summary>
150         /// <param name="style">Create DropDown by special style defined in UX.</param>
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 DropDown(string style) : base(style)
155         {
156             AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Trait, "DropDown");
157         }
158
159         /// <summary>
160         /// Creates a new instance of a DropDown with style.
161         /// </summary>
162         /// <param name="dropDownStyle">Create DropDown by style customized by user.</param>
163         /// <since_tizen> 6 </since_tizen>
164         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
165         [EditorBrowsable(EditorBrowsableState.Never)]
166         public DropDown(DropDownStyle dropDownStyle) : base(dropDownStyle)
167         {
168             AccessibilityManager.Instance.SetAccessibilityAttribute(this, AccessibilityManager.AccessibilityAttribute.Trait, "DropDown");
169         }
170
171         /// <summary>
172         /// An event for the item clicked signal which can be used to subscribe or unsubscribe the event handler provided by the user.<br />
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 event EventHandler<ItemClickEventArgs> ItemClickEvent;
178
179         /// <summary>
180         /// List position in relation to the main button.
181         /// </summary>
182         /// <since_tizen> 6 </since_tizen>
183         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
184         [EditorBrowsable(EditorBrowsableState.Never)]
185         public enum ListOrientation
186         {
187             /// <summary>
188             /// Left.
189             /// </summary>
190             /// <since_tizen> 6 </since_tizen>
191             /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
192             [EditorBrowsable(EditorBrowsableState.Never)]
193             Left,
194             /// <summary>
195             /// Right.
196             /// </summary>
197             /// <since_tizen> 6 </since_tizen>
198             /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
199             [EditorBrowsable(EditorBrowsableState.Never)]
200             Right,
201         }
202
203         /// <summary>
204         /// Get or set header text.
205         /// </summary>
206         /// This will be public opened in tizen_next after ACR done. Before ACR, need to be hidden as inhouse API.
207         [EditorBrowsable(EditorBrowsableState.Never)]
208         public TextLabel HeaderText
209         {
210             get
211             {
212                 if (null == headerText)
213                 {
214                     headerText = new TextLabel()
215                     {
216                         WidthResizePolicy = ResizePolicyType.UseNaturalSize,
217                         HeightResizePolicy = ResizePolicyType.UseNaturalSize,
218                         HorizontalAlignment = HorizontalAlignment.Center,
219                         VerticalAlignment = VerticalAlignment.Center,
220                         ParentOrigin = NUI.ParentOrigin.Center,
221                         PivotPoint = NUI.ParentOrigin.Center,
222                         PositionUsesPivotPoint = true,
223                         Name = "DropDownHeaderText"
224                     };
225                     Add(headerText);
226                 }
227                 return headerText;
228             }
229             internal set
230             {
231                 headerText = value;
232             }
233         }
234
235         /// <summary>
236         /// Get or set button.
237         /// </summary>
238         /// This will be public opened in tizen_next after ACR done. Before ACR, need to be hidden as inhouse API.
239         [EditorBrowsable(EditorBrowsableState.Never)]
240         public Button Button
241         {
242             get
243             {
244                 if (null == button)
245                 {
246                     button = new Button()
247                     {
248                         ParentOrigin = NUI.ParentOrigin.TopLeft,
249                         PivotPoint = NUI.PivotPoint.TopLeft,
250                         PositionUsesPivotPoint = true,
251                         HeightResizePolicy = ResizePolicyType.FitToChildren,
252                         IconRelativeOrientation = Button.IconOrientation.Right,
253                         Name = "DropDownButton"
254                     };
255                     button.ClickEvent += ButtonClickEvent;
256                     Add(button);
257
258                     if (null == buttonText)
259                     {
260                         buttonText = new TextLabel();
261                     }
262                 }
263                 return button;
264             }
265             internal set
266             {
267                 button = value;
268             }
269         }
270
271         /// <summary>
272         /// Get or set the background image of list.
273         /// </summary>
274         /// This will be public opened in tizen_next after ACR done. Before ACR, need to be hidden as inhouse API.
275         [EditorBrowsable(EditorBrowsableState.Never)]
276         public ImageView ListBackgroundImage
277         {
278             get
279             {
280                 if (null == listBackgroundImage)
281                 {
282                     listBackgroundImage = new ImageView()
283                     {
284                         Name = "ListBackgroundImage",
285                         PositionUsesPivotPoint = true,
286                         ParentOrigin = Tizen.NUI.ParentOrigin.TopLeft,
287                         PivotPoint = Tizen.NUI.PivotPoint.TopLeft,
288                         WidthResizePolicy = ResizePolicyType.FitToChildren,
289                         HeightResizePolicy = ResizePolicyType.FitToChildren,
290                     };
291                     Add(listBackgroundImage);
292
293                     if (null == scrollableBase) // scrollableBase used to test of ListContainer Setup invoked already
294                     {
295                         SetUpListContainer();
296                     }
297                 }
298                 return listBackgroundImage;
299             }
300             internal set
301             {
302                 listBackgroundImage = value;
303             }
304         }
305
306         /// <summary>
307         /// Return a copied Style instance of DropDown
308         /// </summary>
309         /// <remarks>
310         /// It returns copied Style instance and changing it does not effect to the DropDown.
311         /// Style setting is possible by using constructor or the function of ApplyStyle(ViewStyle viewStyle)
312         /// </remarks>
313         /// This will be public opened in tizen_next after ACR done. Before ACR, need to be hidden as inhouse API.
314         [EditorBrowsable(EditorBrowsableState.Never)]
315         public new DropDownStyle Style
316         {
317             get
318             {
319                 var result = new DropDownStyle(dropDownStyle);
320                 result.CopyPropertiesFromView(this);
321                 result.Button.CopyPropertiesFromView(Button);
322                 result.HeaderText.CopyPropertiesFromView(HeaderText);
323                 result.ListBackgroundImage.CopyPropertiesFromView(ListBackgroundImage);
324                 return result;
325             }
326         }
327
328         /// <summary>
329         /// Space between button text and button icon in DropDown.
330         /// </summary>
331         /// <since_tizen> 6 </since_tizen>
332         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
333         public int SpaceBetweenButtonTextAndIcon
334         {
335             get => (int)GetValue(SpaceBetweenButtonTextAndIconProperty);
336             set => SetValue(SpaceBetweenButtonTextAndIconProperty, value);
337         }
338
339         /// <summary>
340         /// List relative orientation in DropDown.
341         /// </summary>
342         /// <since_tizen> 6 </since_tizen>
343         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
344         public ListOrientation ListRelativeOrientation
345         {
346             get => (ListOrientation)GetValue(ListRelativeOrientationProperty);
347             set => SetValue(ListRelativeOrientationProperty, value);
348         }
349
350         /// <summary>
351         /// Space in list.
352         /// </summary>
353         /// <since_tizen> 6 </since_tizen>
354         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
355         public Extents ListMargin
356         {
357             get
358             {
359                 Extents tmp = (Extents)GetValue(ListMarginProperty);
360                 return new Extents((ushort start, ushort end, ushort top, ushort bottom) => { ListMargin = new Extents(start, end, top, bottom); }, tmp.Start, tmp.End, tmp.Top, tmp.Bottom);
361             }
362             set => SetValue(ListMarginProperty, value);
363         }
364
365         /// <summary>
366         /// Selected item index in list.
367         /// </summary>
368         /// <since_tizen> 6 </since_tizen>
369         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
370         public int SelectedItemIndex
371         {
372             get => (int)GetValue(SelectedItemIndexProperty);
373             set => SetValue(SelectedItemIndexProperty, value);
374         }
375
376         /// <summary>
377         /// List padding in DropDown.
378         /// </summary>
379         /// <since_tizen> 6 </since_tizen>
380         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
381         public Extents ListPadding
382         {
383             get
384             {
385                 Extents tmp = (Extents)GetValue(ListPaddingProperty);
386                 return new Extents((ushort start, ushort end, ushort top, ushort bottom) => { ListPadding = new Extents(start, end, top, bottom); }, tmp.Start, tmp.End, tmp.Top, tmp.Bottom);
387             }
388             set => SetValue(ListPaddingProperty, value);
389         }
390
391         private DropDownStyle dropDownStyle => ViewStyle as DropDownStyle;
392
393         /// <summary>
394         /// Add list item by item data. The added item will be added to end of all items automatically.
395         /// </summary>
396         /// <param name="itemData">Item data which will apply to tab item view.</param>
397         /// <since_tizen> 6 </since_tizen>
398         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
399         [EditorBrowsable(EditorBrowsableState.Never)]
400         public void AddItem(DropDownDataItem itemData)
401         {
402            // Add item to adaptor, will be added to list via AddItemAt during OnUpdate()
403            int insertionPosition = adapter.GetItemCount();
404            adapter.InsertData(insertionPosition, itemData);
405         }
406
407         /// <summary>
408         /// Delete list item by index.
409         /// </summary>
410         /// <param name="index">Position index where will be deleted.</param>
411         /// <since_tizen> 6 </since_tizen>
412         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
413         [EditorBrowsable(EditorBrowsableState.Never)]
414         public void DeleteItem(int index)
415         {
416             if (index < 0 || index >= adapter?.GetItemCount()) return;
417             if (null == dropDownMenuFullList) return;
418
419             if (dropDownStyle.SelectedItemIndex == index)
420             {
421                 dropDownStyle.SelectedItemIndex = -1;
422             }
423             else if(dropDownStyle.SelectedItemIndex > index)
424             {
425                 dropDownStyle.SelectedItemIndex--;
426             }
427
428             adapter?.RemoveData(index);
429
430             if(index < dropDownMenuFullList.ChildCount)
431             {
432                 View childToRemove = dropDownMenuFullList.GetChildAt((uint)index);
433                 if (childToRemove)
434                 {
435                     childToRemove.TouchEvent -= ListItemTouchEvent;
436                     dropDownMenuFullList.Remove(childToRemove);
437                     dropDownMenuFullList?.Layout?.RequestLayout();
438                 }
439             }
440         }
441
442         /// <summary>
443         /// Insert list item by item data. The inserted item will be added to the special position by index automatically.
444         /// </summary>
445         /// <param name="item">Item data which will apply to tab item view.</param>
446         /// <param name="index">Position index where will be inserted.</param>
447         /// <since_tizen> 6 </since_tizen>
448         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
449         [EditorBrowsable(EditorBrowsableState.Never)]
450         public void InsertItem(DropDownDataItem item, int index)
451         {
452             if (index < 0 || index >= adapter.GetItemCount())
453             {
454                 return;
455             }
456
457             if (dropDownStyle.SelectedItemIndex >= index)
458             {
459                 dropDownStyle.SelectedItemIndex++;
460             }
461
462             adapter.InsertData(index, item);
463         }
464
465         /// <summary>
466         /// Add scroll bar to list.
467         /// </summary>
468         /// <param name="scrollBar">Scroll bar defined by user which will be added to list.</param>
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         public void AttachScrollBar(ScrollBar scrollBar)
473         {
474             if (scrollableBase == null)
475             {
476                 return;
477             }
478             Tizen.Log.Error("DropDown","Feature unsupported");
479         }
480
481         /// <summary>
482         /// Detach scroll bar to list.
483         /// </summary>
484         /// <since_tizen> 6 </since_tizen>
485         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
486         [EditorBrowsable(EditorBrowsableState.Never)]
487         public void DetachScrollBar()
488         {
489             if (scrollableBase == null)
490             {
491                 return;
492             }
493             Tizen.Log.Error("DropDown","Feature unsupported");
494         }
495
496         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
497         [EditorBrowsable(EditorBrowsableState.Never)]
498         public override void ApplyStyle(ViewStyle viewStyle)
499         {
500             base.ApplyStyle(viewStyle);
501
502             DropDownStyle dropDownStyle = viewStyle as DropDownStyle;
503             if (null != dropDownStyle)
504             {
505                 if (null != dropDownStyle.Button)
506                 {
507                     Button.ApplyStyle(dropDownStyle.Button);
508                 }
509                 if (null != dropDownStyle.HeaderText)
510                 {
511                     HeaderText.ApplyStyle(dropDownStyle.HeaderText);
512                 }
513                 if (null != dropDownStyle.ListBackgroundImage)
514                 {
515                     ListBackgroundImage.ApplyStyle(dropDownStyle.ListBackgroundImage);
516                 }
517                 UpdateDropDown();
518             }
519         }
520
521         /// <summary>
522         /// Update DropDown by style.
523         /// </summary>
524         /// <since_tizen> 6 </since_tizen>
525         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
526         [EditorBrowsable(EditorBrowsableState.Never)]
527         protected void UpdateDropDown()
528         {
529             if (null == scrollableBase || null == listBackgroundImage || null == dropDownMenuFullList) return;
530             if (null == ListBackgroundImage.Size) return;
531             // Resize and position scrolling list within the drop down list container.  Can be used to position list in relation to the background image.
532             scrollableBase.Size = ListBackgroundImage.Size - new Size((dropDownStyle.ListPadding.Start + dropDownStyle.ListPadding.End), (dropDownStyle.ListPadding.Top + dropDownStyle.ListPadding.Bottom), 0);
533             scrollableBase.Position2D = new Position2D(dropDownStyle.ListPadding.Start, dropDownStyle.ListPadding.Top);
534
535             int listBackgroundImageX = 0;
536             int listBackgroundImageY = 0;
537             if (dropDownStyle.ListRelativeOrientation == ListOrientation.Left)
538             {
539                 listBackgroundImageX = (int)dropDownStyle.ListMargin.Start;
540                 listBackgroundImageY = (int)dropDownStyle.ListMargin.Top;
541             }
542             else if (dropDownStyle.ListRelativeOrientation == ListOrientation.Right)
543             {
544                 listBackgroundImageX = -(int)dropDownStyle.ListMargin.End;
545                 listBackgroundImageY = (int)dropDownStyle.ListMargin.Top;
546             }
547             listBackgroundImage.Position2D = new Position2D(listBackgroundImageX, listBackgroundImageY);
548             dropDownMenuFullList?.Layout?.RequestLayout();
549         }
550
551         /// <summary>
552         /// update.
553         /// </summary>
554         protected override void OnUpdate()
555         {
556             float buttonTextWidth = 0;
557             if (null != buttonText)
558             {
559                 buttonText.Text = Button.TextLabel.Text;
560                 buttonText.PointSize = Button.TextLabel.PointSize;
561                 buttonTextWidth = buttonText.NaturalSize.Width;
562             }
563             float fitWidth = (Button.Icon.Size?.Width ?? 48) + dropDownStyle.SpaceBetweenButtonTextAndIcon + buttonTextWidth;
564             fitWidth += (button.IconPadding.Start + button.IconPadding.End);
565             button.SizeWidth = Math.Max(button.Size.Width, fitWidth);
566             RelayoutRequest();
567
568             int numberOfItemsToAdd = adapter.GetItemCount();
569
570             if (adapter.AdapterPurge == true)
571             {
572                 adapter.AdapterPurge = false;
573                 for (int i = 0; i < numberOfItemsToAdd; i++)
574                 {
575                     AddItemAt(adapter.GetData(i), i);
576                 }
577             }
578             // Set selection icon on View
579             if (dropDownStyle.SelectedItemIndex > 0)
580             {
581                 SetListItemToSelected((uint)dropDownStyle.SelectedItemIndex, selectedItemView);
582             }
583         }
584
585         /// <summary>
586         /// Dispose DropDown and all children on it.
587         /// </summary>
588         /// <param name="type">Dispose type.</param>
589         /// <since_tizen> 6 </since_tizen>
590         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
591         [EditorBrowsable(EditorBrowsableState.Never)]
592         protected override void Dispose(DisposeTypes type)
593         {
594             if (disposed)
595             {
596                 return;
597             }
598
599             if (type == DisposeTypes.Explicit)
600             {
601                 Utility.Dispose(headerText);
602                 Utility.Dispose(buttonText);
603                 Utility.Dispose(button);
604                 Utility.Dispose(scrollableBase);
605                 Utility.Dispose(dropDownMenuFullList);
606                 Utility.Dispose(listBackgroundImage);
607             }
608
609             base.Dispose(type);
610         }
611
612         /// <summary>
613         /// Get DropDown style.
614         /// </summary>
615         /// <returns>The default dropdown style.</returns>
616         /// <since_tizen> 6 </since_tizen>
617         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
618         [EditorBrowsable(EditorBrowsableState.Never)]
619         protected override ViewStyle CreateViewStyle()
620         {
621             return new DropDownStyle();
622         }
623
624         private void AddItemAt(DropDownDataItem itemData,int index)
625         {
626             ViewHolder viewHolder = adapter.OnCreateViewHolder();
627             if (!viewHolder.IsBound)
628             {
629                 adapter.BindViewHolder(viewHolder, index);
630                 viewHolder.IsBound = true;
631             }
632
633             if (tapGestureDetector == null)
634             {
635                 tapGestureDetector = new TapGestureDetector();
636             }
637             View view = viewHolder.ItemView;
638             view.ApplyStyle(itemData.itemDataStyle);
639             view.TouchEvent += ListItemTouchEvent;
640             dropDownMenuFullList.Add(view);
641         }
642
643         private void OnClickEvent(object sender, ItemClickEventArgs e)
644         {
645             ItemClickEvent?.Invoke(sender, e);
646         }
647
648         private void CreateButtonText()
649         {
650             if (null == buttonText)
651             {
652                 buttonText = new TextLabel();
653             }
654         }
655
656         private void CreateButton()
657         {
658             if (null == button)
659             {
660                 button = new Button()
661                 {
662                     ParentOrigin = NUI.ParentOrigin.CenterLeft,
663                     PivotPoint = NUI.PivotPoint.CenterLeft,
664                     PositionUsesPivotPoint = true,
665                     HeightResizePolicy = ResizePolicyType.FitToChildren,
666                     IconRelativeOrientation = Button.IconOrientation.Right,
667                 };
668                 button.Name = "DropDownButton";
669                 button.ClickEvent += ButtonClickEvent;
670                 Add(button);
671             }
672         }
673
674         private void SetUpListContainer()
675         {
676             LinearLayout linear = new LinearLayout()
677             {
678                 LinearOrientation = LinearLayout.Orientation.Vertical,
679             };
680
681             dropDownMenuFullList = new View()
682             {
683                 Layout = linear,
684                 Name = "DropDownMenuList",
685                 WidthSpecification = LayoutParamPolicies.MatchParent,
686                 HeightSpecification = LayoutParamPolicies.WrapContent,
687                 Focusable = true,
688             };
689
690             scrollableBase = new ScrollableBase()
691             {
692                 Name = "Scrollable",
693             };
694             scrollableBase.Add(dropDownMenuFullList);
695
696             listBackgroundImage.Add(scrollableBase);
697             listBackgroundImage.Hide();
698         }
699
700         private View GetViewFromIndex(uint index)
701         {
702             if ((index < dropDownMenuFullList.ChildCount) && (index >=0) )
703             {
704                 return dropDownMenuFullList.GetChildAt(index);
705             }
706             else
707             {
708                 return null;
709             }
710         }
711
712         private void SetListItemToSelected(DropDownItemView view)
713         {
714             if (dropDownMenuFullList == null || view == null || view == selectedItemView)
715             {
716                 return;
717             }
718
719             uint newSelectedIndex = 0;
720             for (; newSelectedIndex < dropDownMenuFullList.ChildCount; newSelectedIndex++)
721             {
722                 var itemView = dropDownMenuFullList.GetChildAt(newSelectedIndex) as DropDownItemView;
723                 if (itemView == view)
724                 {
725                     SetListItemToSelected(newSelectedIndex, view);
726                     return;
727                 }
728             }
729         }
730
731         private void SetListItemToSelected(uint index)
732         {
733             if (dropDownMenuFullList == null || index == dropDownStyle.SelectedItemIndex)
734             {
735                 return;
736             }
737
738             SetListItemToSelected(index, GetViewFromIndex(index) as DropDownItemView);
739         }
740
741         private void SetListItemToSelected(uint index, DropDownItemView view)
742         {
743             if (adapter == null)
744             {
745                 return;
746             }
747
748             if (selectedItemView != null)
749             {
750                 selectedItemView.IsSelected = false;
751                 adapter.GetData(dropDownStyle.SelectedItemIndex).IsSelected = false;
752             }
753
754             if (view == null || index >= dropDownMenuFullList.ChildCount)
755             {
756                 dropDownStyle.SelectedItemIndex = -1;
757                 selectedItemView = null;
758                 return;
759             }
760
761             dropDownStyle.SelectedItemIndex = (int)index;
762             selectedItemView = view;
763             selectedItemView.IsSelected = true;
764             adapter.GetData(dropDownStyle.SelectedItemIndex).IsSelected = true;
765             dropDownMenuFullList.Layout?.RequestLayout();
766         }
767
768         private bool ListItemTouchEvent(object sender, TouchEventArgs e)
769         {
770             PointStateType state = e.Touch.GetState(0);
771             DropDownItemView touchedView = sender as DropDownItemView;
772             if (touchedView == null)
773             {
774                 return true;
775             }
776
777             touchedView.OnTouch(e.Touch); // Handle control state change
778
779             switch (state)
780             {
781                 case PointStateType.Down:
782                     itemPressed = true;  // if matched with a Up then a click event.
783                     break;
784                 case PointStateType.Motion:
785                     itemPressed = false;
786                     break;
787                 case PointStateType.Up:
788                     if (touchedView != null)
789                     {
790                         if (itemPressed)  // if Down was previously sent without motion (Scrolling) in-between then a clicked event occurred.
791                         {
792                             // List item clicked
793                             Console.WriteLine("Tapped{0}", touchedView.Name);
794                             SetListItemToSelected(touchedView);
795                             button.Text = touchedView.Text;
796                             button.Show();
797                             listBackgroundImage.Hide();
798                         }
799                     }
800                     break;
801                 default:
802                     break;
803             }
804             return true;
805         }
806
807         private void ButtonClickEvent(object sender, Button.ClickEventArgs e)
808         {
809             button.Hide();
810             listBackgroundImage.Show();
811             dropDownMenuFullList?.Layout?.RequestLayout();
812             listBackgroundImage.RaiseToTop();
813         }
814
815         #endregion
816
817         #region ItemClickEventArgs
818         /// <summary>
819         /// ItemClickEventArgs is a class to record item click event arguments which will sent to user.
820         /// </summary>
821         /// <since_tizen> 6 </since_tizen>
822         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
823         [EditorBrowsable(EditorBrowsableState.Never)]
824         public class ItemClickEventArgs : EventArgs
825         {
826             /// <summary> Clicked item index of DropDown's list </summary>
827             /// <since_tizen> 6 </since_tizen>
828             /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
829             [EditorBrowsable(EditorBrowsableState.Never)]
830             public int Index { get; set; }
831             /// <summary> Clicked item text string of DropDown's list </summary>
832             /// <since_tizen> 6 </since_tizen>
833             /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
834             [EditorBrowsable(EditorBrowsableState.Never)]
835             public string Text { get; set; }
836         }
837         #endregion
838
839         #region ViewHolder
840
841         /// <summary>
842         /// A ViewHolder is a class that holds a View created from DropDownListBridge data.
843         /// </summary>
844         /// <since_tizen> 6 </since_tizen>
845         /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
846         [EditorBrowsable(EditorBrowsableState.Never)]
847         public class ViewHolder
848         {
849             /// <summary>
850             /// ViewHolder constructor.
851             /// </summary>
852             /// <param name="itemView">View</param>
853             /// <since_tizen> 6 </since_tizen>
854             /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
855             [EditorBrowsable(EditorBrowsableState.Never)]
856             public ViewHolder(View itemView)
857             {
858                 ItemView = itemView ?? throw new ArgumentNullException(nameof(itemView), "itemView may not be null");
859             }
860
861             /// <summary>
862             /// Returns the view.
863             /// </summary>
864             /// <since_tizen> 6 </since_tizen>
865             /// This will be public opened in tizen_5.5 after ACR done. Before ACR, need to be hidden as inhouse API.
866             [EditorBrowsable(EditorBrowsableState.Never)]
867             public View ItemView { get; }
868
869             internal bool IsBound { get; set; }
870         }
871
872         #endregion
873     }
874 }