cfcc4ef7070852744e807f2e85a350ae5e125b79
[platform/core/csapi/tizenfx.git] / src / ElmSharp / ElmSharp / GenList.cs
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
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
20 namespace ElmSharp
21 {
22     /// <summary>
23     /// Enumeration for setting the genlist item types.
24     /// </summary>
25     /// <since_tizen> preview </since_tizen>
26     public enum GenListItemType
27     {
28         /// <summary>
29         /// If Normal is set, then this item is a normal item.
30         /// </summary>
31         Normal = 0,
32
33         /// <summary>
34         /// If Tree is set, then this item is displayed as an item that is able to expand and have child items.
35         /// </summary>
36         Tree = (1 << 0),
37
38         /// <summary>
39         /// If Group is set, then this item is a group index item that is displayed at the top until the next group comes.
40         /// </summary>
41         Group = (1 << 1),
42     }
43
44     /// <summary>
45     /// Enumeration for setting the genlist's resizing behavior, transverse axis scrolling, and items cropping.
46     /// </summary>
47     /// <since_tizen> preview </since_tizen>
48     public enum GenListMode
49     {
50         /// <summary>
51         /// The genlist won't set any of its size hints to inform how a possible container should resize it.
52         /// Then, if it's not created as a "resize object", it might end up with zeroed dimensions.
53         /// The genlist will respect the container's geometry,and if any of its items won't fit into its transverse axis, one won't be able to scroll it in that direction.
54         /// </summary>
55         Compress = 0,
56
57         /// <summary>
58         /// This is the same as Compress, with the exception that if any of its items won't fit into its transverse axis, one will be able to scroll it in that direction.
59         /// </summary>
60         Scroll,
61
62         /// <summary>
63         /// Sets a minimum size hint on the genlist object, so that containers may respect it (and resize itself to fit the child properly).
64         /// More specifically, a minimum size hint will be set for its transverse axis, so that the largest item in that direction fits well.
65         /// This is naturally bound by the genlist object's maximum size hints, set externally.
66         /// </summary>
67         Limit,
68
69         /// <summary>
70         /// Besides setting a minimum size on the transverse axis, just like on Limit, the genlist will set a minimum size on the longitudinal axis, trying to reserve space to all its children to be visible at a time.
71         /// This is naturally bound by the genlist object's maximum size hints, set externally.
72         /// </summary>
73         Expand
74     }
75
76     /// <summary>
77     /// It inherits System.EventArgs.
78     /// It contains an item which is <see cref="GenListItem"/> type.
79     /// All events of the GenList contain GenListItemEventArgs as a parameter.
80     /// </summary>
81     /// <since_tizen> preview </since_tizen>
82     public class GenListItemEventArgs : EventArgs
83     {
84         /// <summary>
85         /// Gets or sets the genlist item. The return type is <see cref="GenListItem"/>.
86         /// </summary>
87         /// <since_tizen> preview </since_tizen>
88         public GenListItem Item { get; set; }
89
90         internal static GenListItemEventArgs CreateFromSmartEvent(IntPtr data, IntPtr obj, IntPtr info)
91         {
92             GenListItem item = ItemObject.GetItemByHandle(info) as GenListItem;
93             return new GenListItemEventArgs { Item = item };
94         }
95     }
96
97     /// <summary>
98     /// Enumeration for defining where to position the item in the genlist.
99     /// </summary>
100     /// <since_tizen> preview </since_tizen>
101     public enum ScrollToPosition
102     {
103         /// <summary>
104         /// Scrolls to nowhere.
105         /// </summary>
106         None = 0,
107
108         /// <summary>
109         /// Scrolls to the nearest viewport.
110         /// </summary>
111         In = (1 << 0),
112
113         /// <summary>
114         /// Scrolls to the top of the viewport.
115         /// </summary>
116         Top = (1 << 1),
117
118         /// <summary>
119         /// Scrolls to the middle of the viewport.
120         /// </summary>
121         Middle = (1 << 2),
122
123         /// <summary>
124         /// Scrolls to the bottom of the viewport.
125         /// </summary>
126         Bottom = (1 << 3)
127     }
128
129     /// <summary>
130     /// It inherits <see cref="Layout"/>.
131     /// The GenList is a widget that aims to have a more expansive list than the simple <see cref="List"/> in ElmSharp that could have more flexible items and allow many more entries while still being fast and low on memory usage.
132     /// At the same time it was also made to be able to do tree structures.
133     /// But the price to pay is more complex when it comes to usage.
134     /// If all you want is a simple list with icons and a single text, use <see cref="List"/> widget.
135     /// </summary>
136     /// <since_tizen> preview </since_tizen>
137     public class GenList : Layout
138     {
139         HashSet<GenListItem> _children = new HashSet<GenListItem>();
140
141         SmartEvent<GenListItemEventArgs> _selected;
142         SmartEvent<GenListItemEventArgs> _unselected;
143         SmartEvent<GenListItemEventArgs> _activated;
144         SmartEvent<GenListItemEventArgs> _pressed;
145         SmartEvent<GenListItemEventArgs> _released;
146         SmartEvent<GenListItemEventArgs> _doubleClicked;
147         SmartEvent<GenListItemEventArgs> _expanded;
148         SmartEvent<GenListItemEventArgs> _realized;
149         SmartEvent<GenListItemEventArgs> _unrealized;
150         SmartEvent<GenListItemEventArgs> _longpressed;
151         SmartEvent<GenListItemEventArgs> _moved;
152         SmartEvent<GenListItemEventArgs> _movedAfter;
153         SmartEvent<GenListItemEventArgs> _movedBefore;
154         SmartEvent _scrollAnimationStarted;
155         SmartEvent _scrollAnimationStopped;
156         SmartEvent _changed;
157
158         /// <summary>
159         /// Creates and initializes a new instance of the GenList class.
160         /// </summary>
161         /// <param name="parent">The parent is a given container, which will be attached by GenList as a child. It's <see cref="EvasObject"/> type.</param>
162         /// <since_tizen> preview </since_tizen>
163         public GenList(EvasObject parent) : base(parent)
164         {
165         }
166
167         /// <summary>
168         /// Creates and initializes a new instance of the GenList class.
169         /// </summary>
170         /// <since_tizen> preview </since_tizen>
171         protected GenList()
172         {
173         }
174
175         /// <summary>
176         /// Gets or sets whether the homogeneous mode is enabled.
177         /// </summary>
178         /// <remarks>
179         /// If true, the genlist items will have the same height and width.
180         /// </remarks>
181         /// <since_tizen> preview </since_tizen>
182         public bool Homogeneous
183         {
184             get
185             {
186                 return Interop.Elementary.elm_genlist_homogeneous_get(RealHandle);
187             }
188             set
189             {
190                 Interop.Elementary.elm_genlist_homogeneous_set(RealHandle, value);
191             }
192         }
193
194         /// <summary>
195         /// Gets or sets the horizontal stretching mode. This mode used for sizing items horizontally.
196         /// The default value is <see cref="GenListMode.Scroll"/>, which means that if the items are too wide to fit, the scroller scrolls horizontally.
197         /// If set to <see cref="GenListMode.Compress"/>, means that the item width is fixed (restricted to a minimum) to the list width when calculating its size in order to allow the height to be calculated based on it.
198         /// If set to <see cref="GenListMode.Limit"/>, means that items are expanded to the viewport width and limited to that size.
199         /// If set to <see cref="GenListMode.Expand"/>, means that genlist try to reserve space to all its items to be visible at a time.
200         /// </summary>
201         /// <remarks>
202         /// Compress makes the genlist resize slower, as it recalculates every item height again whenever the list width changes.
203         /// The homogeneous mode is so that all items in the genlist are of the same width/height. With Compress, the genlist items are initialized fast.
204         /// However, there are no subobjects in the genlist, which can be on the flying resizable (such as TEXTBLOCK).
205         /// If so, then some dynamic resizable objects in the genlist would not be diplayed properly.
206         /// </remarks>
207         /// <since_tizen> preview </since_tizen>
208         public GenListMode ListMode
209         {
210             get
211             {
212                 return (GenListMode)Interop.Elementary.elm_genlist_mode_get(RealHandle);
213             }
214             set
215             {
216                 Interop.Elementary.elm_genlist_mode_set(RealHandle, (int)value);
217             }
218         }
219
220         /// <summary>
221         /// Gets the first item in the genlist.
222         /// </summary>
223         /// <since_tizen> preview </since_tizen>
224         public GenListItem FirstItem
225         {
226             get
227             {
228                 IntPtr handle = Interop.Elementary.elm_genlist_first_item_get(RealHandle);
229                 return ItemObject.GetItemByHandle(handle) as GenListItem;
230             }
231         }
232
233         /// <summary>
234         /// Gets the last item in the genlist.
235         /// </summary>
236         /// <since_tizen> preview </since_tizen>
237         public GenListItem LastItem
238         {
239             get
240             {
241                 IntPtr handle = Interop.Elementary.elm_genlist_last_item_get(RealHandle);
242                 return ItemObject.GetItemByHandle(handle) as GenListItem;
243             }
244         }
245
246         /// <summary>
247         /// Gets or sets the reorder mode.
248         /// After turning on the reorder mode, longpress on a normal item triggers reordering of the item.
249         /// You can move the item up and down. However, reordering does not work with group items.
250         /// </summary>
251         /// <since_tizen> preview </since_tizen>
252         public bool ReorderMode
253         {
254             get
255             {
256                 return Interop.Elementary.elm_genlist_reorder_mode_get(RealHandle);
257             }
258             set
259             {
260                 Interop.Elementary.elm_genlist_reorder_mode_set(RealHandle, value);
261             }
262         }
263
264         /// <summary>
265         /// Gets or sets the maximum number of items within an item block.
266         /// </summary>
267         /// <since_tizen> preview </since_tizen>
268         public int BlockCount
269         {
270             get
271             {
272                 return Interop.Elementary.elm_genlist_block_count_get(RealHandle);
273             }
274             set
275             {
276                 Interop.Elementary.elm_genlist_block_count_set(RealHandle, value);
277             }
278         }
279
280         /// <summary>
281         /// Gets or sets whether the genlist items should be highlighted when an item is selected.
282         /// </summary>
283         /// <since_tizen> preview </since_tizen>
284         public bool IsHighlight
285         {
286             get
287             {
288                 return Interop.Elementary.elm_genlist_highlight_mode_get(RealHandle);
289             }
290             set
291             {
292                 Interop.Elementary.elm_genlist_highlight_mode_set(RealHandle, value);
293             }
294         }
295
296         /// <summary>
297         /// Gets or sets the timeout in seconds for the longpress event.
298         /// </summary>
299         /// <since_tizen> preview </since_tizen>
300         public double LongPressTimeout
301         {
302             get
303             {
304                 return Interop.Elementary.elm_genlist_longpress_timeout_get(RealHandle);
305             }
306             set
307             {
308                 Interop.Elementary.elm_genlist_longpress_timeout_set(RealHandle, value);
309             }
310         }
311
312         /// <summary>
313         /// Gets or sets the focus upon the items selection mode.
314         /// </summary>
315         /// <remarks>
316         /// When enabled, every selection of an item inside <see cref="GenList"/> will automatically set focus to its first focusable widget from the left.
317         /// This is true of course, if the selection was made by clicking an unfocusable area in an item or selecting it with a key movement.
318         /// Clicking on a focusable widget inside an item will couse this particular item to get focus as usual.
319         /// </remarks>
320         /// <since_tizen> preview </since_tizen>
321         public bool FocusOnSelection
322         {
323             get
324             {
325                 return Interop.Elementary.elm_genlist_focus_on_selection_get(RealHandle);
326             }
327             set
328             {
329                 Interop.Elementary.elm_genlist_focus_on_selection_set(RealHandle, value);
330             }
331         }
332
333         /// <summary>
334         /// Gets or sets whether to enable multi-selection in the genlist.
335         /// </summary>
336         /// <since_tizen> preview </since_tizen>
337         public bool IsMultiSelection
338         {
339             get
340             {
341                 return Interop.Elementary.elm_genlist_multi_select_get(RealHandle);
342             }
343             set
344             {
345                 Interop.Elementary.elm_genlist_multi_select_set(RealHandle, value);
346             }
347         }
348
349         /// <summary>
350         /// Gets the selected item in a given GenList widget.
351         /// </summary>
352         /// <since_tizen> preview </since_tizen>
353         public GenListItem SelectedItem
354         {
355             get
356             {
357                 IntPtr handle = Interop.Elementary.elm_genlist_selected_item_get(RealHandle);
358                 return ItemObject.GetItemByHandle(handle) as GenListItem;
359             }
360         }
361
362         /// <summary>
363         /// Gets or sets the genlist select mode by <see cref="GenItemSelectionMode"/>.
364         /// </summary>
365         /// <since_tizen> preview </since_tizen>
366         public GenItemSelectionMode SelectionMode
367         {
368             get
369             {
370                 return (GenItemSelectionMode)Interop.Elementary.elm_genlist_select_mode_get(RealHandle);
371             }
372             set
373             {
374                 Interop.Elementary.elm_genlist_select_mode_set(RealHandle, (int)value);
375             }
376         }
377
378         /// <summary>
379         /// Gets the count of items in a this genlist widget.
380         /// </summary>
381         /// <since_tizen> preview </since_tizen>
382         public int Count
383         {
384             get
385             {
386                 return Interop.Elementary.elm_genlist_items_count(RealHandle);
387             }
388         }
389
390         /// <summary>
391         /// Sets or gets the value of HorizontalScrollBarVisiblePolicy.
392         /// </summary>
393         /// <remarks>
394         /// ScrollBarVisiblePolicy.Auto means the horizontal scrollbar is made visible if it is needed, and otherwise kept hidden.
395         /// ScrollBarVisiblePolicy.Visible turns it on all the time, and ScrollBarVisiblePolicy.Invisible always keeps it off.
396         /// </remarks>
397         /// <since_tizen> preview </since_tizen>
398         public ScrollBarVisiblePolicy HorizontalScrollBarVisiblePolicy
399         {
400             get
401             {
402                 Interop.Elementary.elm_scroller_policy_get(RealHandle, out int policy, IntPtr.Zero);
403                 return (ScrollBarVisiblePolicy)policy;
404             }
405             set
406             {
407                 ScrollBarVisiblePolicy v = VerticalScrollBarVisiblePolicy;
408                 Interop.Elementary.elm_scroller_policy_set(RealHandle, (int)value, (int)v);
409             }
410         }
411
412         /// <summary>
413         /// Sets or gets the value of VerticalScrollBarVisiblePolicy.
414         /// </summary>
415         /// <remarks>
416         /// ScrollBarVisiblePolicy.Auto means the vertical scrollbar is made visible if it is needed, and otherwise kept hidden.
417         /// ScrollBarVisiblePolicy.Visible turns it on all the time, and ScrollBarVisiblePolicy.Invisible always keeps it off.
418         /// </remarks>
419         /// <since_tizen> preview </since_tizen>
420         public ScrollBarVisiblePolicy VerticalScrollBarVisiblePolicy
421         {
422             get
423             {
424                 Interop.Elementary.elm_scroller_policy_get(RealHandle, IntPtr.Zero, out int policy);
425                 return (ScrollBarVisiblePolicy)policy;
426             }
427             set
428             {
429                 ScrollBarVisiblePolicy h = HorizontalScrollBarVisiblePolicy;
430                 Interop.Elementary.elm_scroller_policy_set(RealHandle, (int)h, (int)value);
431             }
432         }
433
434         /// <summary>
435         /// ItemSelected is raised when a new genlist item is selected.
436         /// </summary>
437         /// <since_tizen> preview </since_tizen>
438         public event EventHandler<GenListItemEventArgs> ItemSelected;
439
440         /// <summary>
441         /// ItemUnselected is raised when the genlist item is unselected.
442         /// </summary>
443         /// <since_tizen> preview </since_tizen>
444         public event EventHandler<GenListItemEventArgs> ItemUnselected;
445
446         /// <summary>
447         /// ItemPressed is raised when a new genlist item is pressed.
448         /// </summary>
449         /// <since_tizen> preview </since_tizen>
450         public event EventHandler<GenListItemEventArgs> ItemPressed;
451
452         /// <summary>
453         /// ItemReleased is raised when a new genlist item is released.
454         /// </summary>
455         /// <since_tizen> preview </since_tizen>
456         public event EventHandler<GenListItemEventArgs> ItemReleased;
457
458         /// <summary>
459         /// ItemActivated is raised when a new genlist item is double-clicked or pressed (enter|return|spacebar).
460         /// </summary>
461         /// <since_tizen> preview </since_tizen>
462         public event EventHandler<GenListItemEventArgs> ItemActivated;
463
464         /// <summary>
465         /// ItemDoubleClicked is raised when a new genlist item is double-clicked.
466         /// </summary>
467         /// <since_tizen> preview </since_tizen>
468         public event EventHandler<GenListItemEventArgs> ItemDoubleClicked;
469
470         /// <summary>
471         /// ItemExpanded is raised when a new genlist item is indicated to expand.
472         /// </summary>
473         /// <since_tizen> preview </since_tizen>
474         public event EventHandler<GenListItemEventArgs> ItemExpanded;
475
476         /// <summary>
477         /// ItemRealized is raised when a new genlist item is created as a real object.
478         /// </summary>
479         /// <since_tizen> preview </since_tizen>
480         public event EventHandler<GenListItemEventArgs> ItemRealized;
481
482         /// <summary>
483         /// ItemUnrealized is raised when a new genlist item is unrealized.
484         /// After calling unrealize, the item's content objects are deleted, and the item object itself is deleted or is put into a floating cache.
485         /// </summary>
486         /// <since_tizen> preview </since_tizen>
487         public event EventHandler<GenListItemEventArgs> ItemUnrealized;
488
489         /// <summary>
490         /// ItemLongPressed is raised when a genlist item is pressed for a certain amount of time. By default, it's 1 second.
491         /// </summary>
492         /// <since_tizen> preview </since_tizen>
493         public event EventHandler<GenListItemEventArgs> ItemLongPressed;
494
495         /// <summary>
496         /// ItemMoved is raised when a genlist item is moved in the reorder mode.
497         /// </summary>
498         /// <since_tizen> preview </since_tizen>
499         public event EventHandler<GenListItemEventArgs> ItemMoved;
500
501         /// <summary>
502         /// ItemMovedAfter is raised when a genlist item is moved after another item in the reorder mode.
503         /// To get the relative previous item, use <see cref="GenListItem.Previous"/>.
504         /// </summary>
505         /// <since_tizen> preview </since_tizen>
506         public event EventHandler<GenListItemEventArgs> ItemMovedAfter;
507
508         /// <summary>
509         /// ItemMovedBefore is raised when a genlist item is moved before another item in the reorder mode.
510         /// To get the relative next item, use <see cref="GenListItem.Next"/>.
511         /// </summary>
512         /// <since_tizen> preview </since_tizen>
513         public event EventHandler<GenListItemEventArgs> ItemMovedBefore;
514
515         /// <summary>
516         /// Changed is raised when the genlist has changed.
517         /// </summary>
518         /// <since_tizen> preview </since_tizen>
519         public event EventHandler Changed
520         {
521             add { _changed.On += value; }
522             remove { _changed.On -= value; }
523         }
524
525         /// <summary>
526         /// ScrollAnimationStarted is raised when the scrolling animation has started.
527         /// </summary>
528         /// <since_tizen> preview </since_tizen>
529         public event EventHandler ScrollAnimationStarted
530         {
531             add { _scrollAnimationStarted.On += value; }
532             remove { _scrollAnimationStarted.On -= value; }
533         }
534
535         /// <summary>
536         /// ScrollAnimationStopped is raised when the scrolling animation has stopped.
537         /// </summary>
538         /// <since_tizen> preview </since_tizen>
539         public event EventHandler ScrollAnimationStopped
540         {
541             add { _scrollAnimationStopped.On += value; }
542             remove { _scrollAnimationStopped.On -= value; }
543         }
544
545         /// <summary>
546         /// Appends a new item to the end of a given GenList widget.
547         /// </summary>
548         /// <param name="itemClass">The itemClass defines how to display the data.</param>
549         /// <param name="data">The item data.</param>
550         /// <returns>Return a newly added genlist item that contains the data and itemClass.</returns>
551         /// <seealso cref="GenItemClass"/>
552         /// <seealso cref="GenListItem"/>
553         /// <since_tizen> preview </since_tizen>
554         public GenListItem Append(GenItemClass itemClass, object data)
555         {
556             return Append(itemClass, data, GenListItemType.Normal);
557         }
558
559         /// <summary>
560         /// Appends a new item with <see cref="GenListItemType"/> to the end of a given GenList widget.
561         /// </summary>
562         /// <param name="itemClass">The itemClass defines how to display the data.</param>
563         /// <param name="data">The item data.</param>
564         /// <param name="type">The genlist item type.</param>
565         /// <returns>Return a newly added genlist item that contains the data and itemClass.</returns>
566         /// <since_tizen> preview </since_tizen>
567         public GenListItem Append(GenItemClass itemClass, object data, GenListItemType type)
568         {
569             return Append(itemClass, data, type, null);
570         }
571
572         /// <summary>
573         /// Appends a new item with <see cref="GenListItemType"/> to the end of a given GenList widget or the end of the children list, if the parent is given.
574         /// </summary>
575         /// <param name="itemClass">The itemClass defines how to display the data.</param>
576         /// <param name="data">The item data.</param>
577         /// <param name="type">The genlist item type.</param>
578         /// <param name="parent">The parent item, otherwise null if there is no parent item.</param>
579         /// <returns>Return a newly added genlist item that contains the data and itemClass.</returns>
580         /// <since_tizen> preview </since_tizen>
581         public GenListItem Append(GenItemClass itemClass, object data, GenListItemType type, GenListItem parent)
582         {
583             GenListItem item = new GenListItem(data, itemClass);
584             IntPtr handle = Interop.Elementary.elm_genlist_item_append(RealHandle, itemClass.UnmanagedPtr, (IntPtr)item.Id, parent, (int)type, null, (IntPtr)item.Id);
585             item.Handle = handle;
586             AddInternal(item);
587             return item;
588         }
589
590         /// <summary>
591         /// Prepends a new item to the beginning of a given GenList widget.
592         /// </summary>
593         /// <param name="itemClass">The itemClass defines how to display the data.</param>
594         /// <param name="data">The item data.</param>
595         /// <returns>Return a newly added genlist item that contains data and itemClass.</returns>
596         /// <since_tizen> preview </since_tizen>
597         public GenListItem Prepend(GenItemClass itemClass, object data)
598         {
599             return Prepend(itemClass, data, GenListItemType.Normal);
600         }
601
602         /// <summary>
603         /// Prepends a new item with <see cref="GenListItemType"/> to the beginning of a given genlist widget.
604         /// </summary>
605         /// <param name="itemClass">The itemClass defines how to display the data.</param>
606         /// <param name="data">The item data.</param>
607         /// <param name="type">The genlist item type.</param>
608         /// <returns>Return a newly added genlist item that contains data and itemClass.</returns>
609         /// <since_tizen> preview </since_tizen>
610         public GenListItem Prepend(GenItemClass itemClass, object data, GenListItemType type)
611         {
612             return Prepend(itemClass, data, type, null);
613         }
614
615         /// <summary>
616         /// Prepends a new item with <see cref="GenListItemType"/> to the beginning of a given GenList widget or the beginning of the children list, if the parent is given.
617         /// </summary>
618         /// <param name="itemClass">The itemClass defines how to display the data.</param>
619         /// <param name="data">The item data.</param>
620         /// <param name="type">The genlist item type.</param>
621         /// <param name="parent">The parent item, otherwise null if there is no parent item.</param>
622         /// <returns>Return a newly added genlist item that contains the data and itemClass.</returns>
623         /// <since_tizen> preview </since_tizen>
624         public GenListItem Prepend(GenItemClass itemClass, object data, GenListItemType type, GenListItem parent)
625         {
626             GenListItem item = new GenListItem(data, itemClass);
627             IntPtr handle = Interop.Elementary.elm_genlist_item_prepend(RealHandle, itemClass.UnmanagedPtr, (IntPtr)item.Id, parent, (int)type, null, (IntPtr)item.Id);
628             item.Handle = handle;
629             AddInternal(item);
630             return item;
631         }
632
633         /// <summary>
634         /// Inserts an item before another item in a genlist widget.
635         /// It is the same tree level or group as the item before which it is inserted.????
636         /// </summary>
637         /// <param name="itemClass">The itemClass defines how to display the data.</param>
638         /// <param name="data">The item data.</param>
639         /// <param name="before">The item before which to place this new one.</param>
640         /// <returns>Return a newly added genlist item that contains data and itemClass.</returns>
641         /// <since_tizen> preview </since_tizen>
642         public GenListItem InsertBefore(GenItemClass itemClass, object data, GenListItem before)
643         {
644             return InsertBefore(itemClass, data, before, GenListItemType.Normal);
645         }
646
647         /// <summary>
648         /// Inserts an item with <see cref="GenListItemType"/> before another item in a GenList widget.
649         /// It is the same tree level or group as the item before which it is inserted.
650         /// </summary>
651         /// <param name="itemClass">The itemClass defines how to display the data.</param>
652         /// <param name="data">The item data.</param>
653         /// <param name="before">The item before which to place this new one.</param>
654         /// <param name="type">The genlist item type.</param>
655         /// <returns>Return a newly added genlist item that contains data and itemClass.</returns>
656         /// <since_tizen> preview </since_tizen>
657         public GenListItem InsertBefore(GenItemClass itemClass, object data, GenListItem before, GenListItemType type)
658         {
659             return InsertBefore(itemClass, data, before, type, null);
660         }
661
662         /// <summary>
663         /// Inserts an item with <see cref="GenListItemType"/> before another item under a parent in a GenList widget.
664         /// </summary>
665         /// <param name="itemClass">The itemClass defines how to display the data.</param>
666         /// <param name="data">The item data.</param>
667         /// <param name="before">The item before which to place this new one.</param>
668         /// <param name="type">The genlist item type.</param>
669         /// <param name="parent">The parent item, otherwise null if there is no parent item.</param>
670         /// <returns>Return a newly added genlist item that contains data and itemClass.</returns>
671         /// <since_tizen> preview </since_tizen>
672         public GenListItem InsertBefore(GenItemClass itemClass, object data, GenListItem before, GenListItemType type, GenListItem parent)
673         {
674             GenListItem item = new GenListItem(data, itemClass);
675             // insert before the `before` list item
676             IntPtr handle = Interop.Elementary.elm_genlist_item_insert_before(
677                 RealHandle, // genlist handle
678                 itemClass.UnmanagedPtr, // item class
679                 (IntPtr)item.Id, // data
680                 parent, // parent
681                 before, // before
682                 (int)type, // item type
683                 null, // select callback
684                 (IntPtr)item.Id); // callback data
685             item.Handle = handle;
686             AddInternal(item);
687             return item;
688         }
689
690         /// <summary>
691         /// Inserts an item with <see cref="GenListItemType"/> after another item under a parent in a GenList widget.
692         /// </summary>
693         /// <param name="itemClass">The itemClass defines how to display the data.</param>
694         /// <param name="data">The item data.</param>
695         /// <param name="after">The item after which to place this new one.</param>
696         /// <param name="type">The genlist item type.</param>
697         /// <param name="parent">The parent item, otherwise null if there is no parent item.</param>
698         /// <returns>Return a newly added genlist item that contains data and itemClass.</returns>
699         /// <since_tizen> preview </since_tizen>
700         public GenListItem InsertAfter(GenItemClass itemClass, object data, GenListItem after, GenListItemType type, GenListItem parent)
701         {
702             GenListItem item = new GenListItem(data, itemClass);
703             // insert before the `before` list item
704             IntPtr handle = Interop.Elementary.elm_genlist_item_insert_before(
705                 RealHandle, // genlist handle
706                 itemClass.UnmanagedPtr, // item class
707                 (IntPtr)item.Id, // data
708                 parent, // parent
709                 after, // after
710                 (int)type, // item type
711                 null, // select callback
712                 (IntPtr)item.Id); // callback data
713             item.Handle = handle;
714             AddInternal(item);
715             return item;
716         }
717
718         /// <summary>
719         /// Inserts an item in a GenList widget using a user-defined sort function.
720         /// </summary>
721         /// <param name="itemClass">The itemClass defines how to display the data.</param>
722         /// <param name="data">The item data.</param>
723         /// <param name="comparison">User-defined comparison function that defines the sort order based on the genlist item and its data.</param>
724         /// <param name="type">The genlist item type.</param>
725         /// <param name="parent">The parent item, otherwise null if there is no parent item.</param>
726         /// <returns>Return a genlist item that contains the data and itemClass.</returns>
727         /// <since_tizen> preview </since_tizen>
728         public GenListItem InsertSorted(GenItemClass itemClass, object data, Comparison<object> comparison, GenListItemType type, GenListItem parent)
729         {
730             GenListItem item = new GenListItem(data, itemClass);
731
732             Interop.Elementary.Eina_Compare_Cb compareCallback = (handle1, handle2) =>
733             {
734                 GenListItem first = (ItemObject.GetItemByHandle(handle1) as GenListItem) ?? item;
735                 GenListItem second = (ItemObject.GetItemByHandle(handle2) as GenListItem) ?? item;
736                 return comparison(first.Data, second.Data);
737             };
738
739             IntPtr handle = Interop.Elementary.elm_genlist_item_sorted_insert(
740                 RealHandle, // genlist handle
741                 itemClass.UnmanagedPtr, // item clas
742                 (IntPtr)item.Id, // data
743                 parent, // parent
744                 (int)type, // item type
745                 compareCallback, // compare callback
746                 null, //select callback
747                 (IntPtr)item.Id); // callback data
748             item.Handle = handle;
749             AddInternal(item);
750             return item;
751         }
752
753         /// <summary>
754         /// Shows the given item with the position type in a genlist.
755         /// When animated is true, the genlist will jump to the given item and display it (by animatedly scrolling), if it is not fully visible. This may use animation and take sometime.
756         /// When animated is false, the genlist will jump to the given item and display it (by jumping to that position), if it is not fully visible.
757         /// </summary>
758         /// <param name="item">The item to display.</param>
759         /// <param name="position">The position to show the given item to <see cref="ScrollToPosition"/>.</param>
760         /// <param name="animated">The animated indicates how to display the item, by scrolling or by jumping.</param>
761         /// <since_tizen> preview </since_tizen>
762         public void ScrollTo(GenListItem item, ScrollToPosition position, bool animated)
763         {
764             if (animated)
765             {
766                 Interop.Elementary.elm_genlist_item_bring_in(item.Handle, (Interop.Elementary.Elm_Genlist_Item_Scrollto_Type)position);
767             }
768             else
769             {
770                 Interop.Elementary.elm_genlist_item_show(item.Handle, (Interop.Elementary.Elm_Genlist_Item_Scrollto_Type)position);
771             }
772         }
773
774         /// <summary>
775         /// Updates the content of all the realized items.
776         /// This updates all the realized items by calling all <see cref="GenItemClass"/> again to get the content, text, and states.
777         /// Use this when the original item data has changed and the changes are desired to reflect.
778         /// To update just one item, use <see cref="GenListItem.Update"/>.
779         /// </summary>
780         /// <seealso cref="GenListItem.Update"/>
781         /// <since_tizen> preview </since_tizen>
782         public void UpdateRealizedItems()
783         {
784             Interop.Elementary.elm_genlist_realized_items_update(RealHandle);
785         }
786
787         /// <summary>
788         /// Removes all the items from a given genlist widget.
789         /// This removes (and deletes) all items in the object, making it empty.
790         /// To delete just one item, use <see cref="ItemObject.Delete"/>.
791         /// </summary>
792         /// <seealso cref="ItemObject.Delete"/>
793         /// <since_tizen> preview </since_tizen>
794         public void Clear()
795         {
796             Interop.Elementary.elm_genlist_clear(RealHandle);
797         }
798
799         /// <summary>
800         /// Gets the item that is at the X, Y canvas coordinates.
801         /// </summary>
802         /// <param name="x">The input X-coordinate.</param>
803         /// <param name="y">The input Y-coordinate.</param>
804         /// <param name="pos">The position relative to the item returned here.
805         ///  -1, 0, or 1 depending on whether the coordinate is on the upper portion of that item (-1), in the middle section (0), or on the lower part (1).
806         /// </param>
807         /// <returns>The item at the given coordinates.</returns>
808         /// <since_tizen> preview </since_tizen>
809         public GenListItem GetItemByPosition(int x, int y, out int pos)
810         {
811             IntPtr handle = Interop.Elementary.elm_genlist_at_xy_item_get(RealHandle, x, y, out pos);
812             return ItemObject.GetItemByHandle(handle) as GenListItem;
813         }
814
815         /// <summary>
816         /// Gets the nth item in a given genlist widget, placed at position nth, in its internal items list.
817         /// </summary>
818         /// <param name="index">The number of the item to grab (0 being the first).</param>
819         /// <returns></returns>
820         /// <since_tizen> preview </since_tizen>
821         public GenListItem GetItemByIndex(int index)
822         {
823             IntPtr handle = Interop.Elementary.elm_genlist_nth_item_get(RealHandle, index);
824             return ItemObject.GetItemByHandle(handle) as GenListItem;
825         }
826
827         /// <summary>
828         /// The callback of the Unrealized event.
829         /// </summary>
830         /// <since_tizen> preview </since_tizen>
831         protected override void OnRealized()
832         {
833             base.OnRealized();
834             ListMode = GenListMode.Compress;
835             InitializeSmartEvent();
836         }
837
838         /// <summary>
839         /// Creates a widget handle.
840         /// </summary>
841         /// <param name="parent">Parent EvasObject.</param>
842         /// <returns>Handle IntPtr.</returns>
843         /// <since_tizen> preview </since_tizen>
844         protected override IntPtr CreateHandle(EvasObject parent)
845         {
846             IntPtr handle = Interop.Elementary.elm_layout_add(parent.Handle);
847             Interop.Elementary.elm_layout_theme_set(handle, "layout", "elm_widget", "default");
848
849             RealHandle = Interop.Elementary.elm_genlist_add(handle);
850             Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
851
852             return handle;
853         }
854
855         void InitializeSmartEvent()
856         {
857             _selected = new SmartEvent<GenListItemEventArgs>(this, this.RealHandle, "selected", GenListItemEventArgs.CreateFromSmartEvent);
858             _unselected = new SmartEvent<GenListItemEventArgs>(this, this.RealHandle, "unselected", GenListItemEventArgs.CreateFromSmartEvent);
859             _activated = new SmartEvent<GenListItemEventArgs>(this, this.RealHandle, "activated", GenListItemEventArgs.CreateFromSmartEvent);
860             _pressed = new SmartEvent<GenListItemEventArgs>(this, this.RealHandle, "pressed", GenListItemEventArgs.CreateFromSmartEvent);
861             _released = new SmartEvent<GenListItemEventArgs>(this, this.RealHandle, "released", GenListItemEventArgs.CreateFromSmartEvent);
862             _doubleClicked = new SmartEvent<GenListItemEventArgs>(this, this.RealHandle, "clicked,double", GenListItemEventArgs.CreateFromSmartEvent);
863             _expanded = new SmartEvent<GenListItemEventArgs>(this, this.RealHandle, "expanded", GenListItemEventArgs.CreateFromSmartEvent);
864             _realized = new SmartEvent<GenListItemEventArgs>(this, this.RealHandle, "realized", GenListItemEventArgs.CreateFromSmartEvent);
865             _unrealized = new SmartEvent<GenListItemEventArgs>(this, this.RealHandle, "unrealized", GenListItemEventArgs.CreateFromSmartEvent);
866             _longpressed = new SmartEvent<GenListItemEventArgs>(this, this.RealHandle, "longpressed", GenListItemEventArgs.CreateFromSmartEvent);
867             _moved = new SmartEvent<GenListItemEventArgs>(this, this.RealHandle, "moved", GenListItemEventArgs.CreateFromSmartEvent);
868             _movedAfter = new SmartEvent<GenListItemEventArgs>(this, this.RealHandle, "moved,after", GenListItemEventArgs.CreateFromSmartEvent);
869             _movedBefore = new SmartEvent<GenListItemEventArgs>(this, this.RealHandle, "moved,before", GenListItemEventArgs.CreateFromSmartEvent);
870             _scrollAnimationStarted = new SmartEvent(this, this.RealHandle, "scroll,anim,start");
871             _scrollAnimationStopped = new SmartEvent(this, this.RealHandle, "scroll,anim,stop");
872             _changed = new SmartEvent(this, this.RealHandle, "changed");
873
874             _selected.On += (s, e) => { if (e.Item != null) ItemSelected?.Invoke(this, e); };
875             _unselected.On += (s, e) => { if (e.Item != null) ItemUnselected?.Invoke(this, e); };
876             _activated.On += (s, e) => { if (e.Item != null) ItemActivated?.Invoke(this, e); };
877             _pressed.On += (s, e) => { if (e.Item != null) ItemPressed?.Invoke(this, e); };
878             _released.On += (s, e) => { if (e.Item != null) ItemReleased?.Invoke(this, e); };
879             _doubleClicked.On += (s, e) => { if (e.Item != null) ItemDoubleClicked?.Invoke(this, e); };
880             _expanded.On += (s, e) => { if (e.Item != null) ItemExpanded?.Invoke(this, e); };
881             _realized.On += (s, e) => { if (e.Item != null) ItemRealized?.Invoke(this, e); };
882             _unrealized.On += (s, e) => { if (e.Item != null) ItemUnrealized?.Invoke(this, e); };
883             _longpressed.On += (s, e) => { if (e.Item != null) ItemLongPressed?.Invoke(this, e); };
884             _moved.On += (s, e) => { if (e.Item != null) ItemMoved?.Invoke(this, e); };
885             _movedAfter.On += (s, e) => { if (e.Item != null) ItemMovedAfter?.Invoke(this, e); };
886             _movedBefore.On += (s, e) => { if (e.Item != null) ItemMovedBefore?.Invoke(this, e); };
887         }
888
889         void AddInternal(GenListItem item)
890         {
891             _children.Add(item);
892             item.Deleted += Item_Deleted;
893         }
894
895         void Item_Deleted(object sender, EventArgs e)
896         {
897             _children.Remove((GenListItem)sender);
898         }
899     }
900 }