[ElmSharp*] Add Scrollable interface
[platform/core/csapi/tizenfx.git] / src / ElmSharp / ElmSharp / GenGrid.cs
1 /*
2  * Copyright (c) 2016 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     /// It inherits System.EventArgs.
24     /// It contains Item which is <see cref="GenGridItem"/> type.
25     /// All events of GenGrid contain GenGridItemEventArgs as a parameter.
26     /// </summary>
27     public class GenGridItemEventArgs : EventArgs
28     {
29         /// <summary>
30         /// Gets or sets GenGrid item.The return type is <see cref="GenGridItem"/>.
31         /// </summary>
32         public GenGridItem Item { get; set; }
33
34         internal static GenGridItemEventArgs CreateFromSmartEvent(IntPtr data, IntPtr obj, IntPtr info)
35         {
36             GenGridItem item = ItemObject.GetItemByHandle(info) as GenGridItem;
37             return new GenGridItemEventArgs() { Item = item };
38         }
39     }
40
41     /// <summary>
42     /// It inherits <see cref="Layout"/>.
43     /// The GenGrid is a widget that aims to position objects in a grid layout while actually creating and rendering only the visible ones.
44     /// It has two direction in which a given GenGrid widget expands while placing its items, horizontal and vertical.
45     /// The GenGrid items are represented through <see cref="GenItemClass"/> definition field details.
46     /// </summary>
47     public class GenGrid : Layout, IScrollable
48     {
49         ScrollableAdapter _scroller;
50         HashSet<GenGridItem> _children = new HashSet<GenGridItem>();
51
52         SmartEvent<GenGridItemEventArgs> _selected;
53         SmartEvent<GenGridItemEventArgs> _unselected;
54         SmartEvent<GenGridItemEventArgs> _activated;
55         SmartEvent<GenGridItemEventArgs> _pressed;
56         SmartEvent<GenGridItemEventArgs> _released;
57         SmartEvent<GenGridItemEventArgs> _doubleClicked;
58         SmartEvent<GenGridItemEventArgs> _realized;
59         SmartEvent<GenGridItemEventArgs> _unrealized;
60         SmartEvent<GenGridItemEventArgs> _longpressed;
61         SmartEvent _changed;
62
63         /// <summary>
64         /// Creates and initializes a new instance of the GenGrid class.
65         /// </summary>
66         /// <param name="parent">The parent is a given container which will be attached by GenGrid as a child. It's <see cref="EvasObject"/> type.</param>
67         public GenGrid(EvasObject parent) : base(parent)
68         {
69             InitializeSmartEvent();
70             _scroller = new ScrollableAdapter(this);
71         }
72
73         /// <summary>
74         /// ItemSelected is raised when a new gengrid item is selected.
75         /// </summary>
76         public event EventHandler<GenGridItemEventArgs> ItemSelected;
77
78         /// <summary>
79         /// ItemUnselected is raised when the gengrid item is Unselected.
80         /// </summary>
81         public event EventHandler<GenGridItemEventArgs> ItemUnselected;
82
83         /// <summary>
84         /// ItemPressed is raised when a new gengrid item is pressed.
85         /// </summary>
86         public event EventHandler<GenGridItemEventArgs> ItemPressed;
87
88         /// <summary>
89         /// ItemReleased is raised when a new gengrid item is released.
90         /// </summary>
91         public event EventHandler<GenGridItemEventArgs> ItemReleased;
92
93         /// <summary>
94         /// ItemActivated is raised when a new gengrid item is double clicked or pressed (enter|return|spacebar).
95         /// </summary>
96         public event EventHandler<GenGridItemEventArgs> ItemActivated;
97
98         /// <summary>
99         /// ItemDoubleClicked is raised when a new gengrid item is double clicked.
100         /// </summary>
101         public event EventHandler<GenGridItemEventArgs> ItemDoubleClicked;
102
103         /// <summary>
104         /// ItemRealized is raised when a gengrid item is implementing through <see cref="GenItemClass"/>.
105         /// </summary>
106         public event EventHandler<GenGridItemEventArgs> ItemRealized;
107
108         /// <summary>
109         /// ItemUnrealized is raised when the gengrid item is deleted.
110         /// </summary>
111         public event EventHandler<GenGridItemEventArgs> ItemUnrealized;
112
113         /// <summary>
114         /// ItemLongPressed is raised when a gengrid item is pressed for a certain amount of time. By default it's 1 second.
115         /// </summary>
116         public event EventHandler<GenGridItemEventArgs> ItemLongPressed;
117
118         /// <summary>
119         ///  Changed is raised when an item is added, removed, resized or moved and when the gengrid is resized or gets "horizontal" property changes.
120         /// </summary>
121         public event EventHandler Changed;
122
123         /// <summary>
124         /// Gets or sets the item's grid alignment along x-axis within a given gengrid widget.
125         /// Accepted values are in the 0.0 to 1.0 range, with the special value -1.0 used to specify "justify" or "fill" by some users.
126         /// By default, value is 0.0, meaning that the gengrid has its items grid placed exactly in the left along x-axis.
127         /// </summary>
128         public double ItemAlignmentX
129         {
130             get
131             {
132                 double align;
133                 Interop.Elementary.elm_gengrid_align_get(RealHandle, out align, IntPtr.Zero);
134                 return align;
135             }
136             set
137             {
138                 double aligny = ItemAlignmentY;
139                 Interop.Elementary.elm_gengrid_align_set(RealHandle, value, aligny);
140             }
141         }
142
143         /// <summary>
144         /// Gets or sets the item's grid alignment on y-axis within a given gengrid widget.
145         /// Accepted values are in the 0.0 to 1.0 range, with the special value -1.0 used to specify "justify" or "fill" by some users.
146         /// By default, value is 0.0, meaning that the gengrid has its items grid placed exactly in the top along y-axis.
147         /// </summary>
148         public double ItemAlignmentY
149         {
150             get
151             {
152                 double align;
153                 Interop.Elementary.elm_gengrid_align_get(RealHandle, IntPtr.Zero, out align);
154                 return align;
155             }
156             set
157             {
158                 double alignx = ItemAlignmentX;
159                 Interop.Elementary.elm_gengrid_align_set(RealHandle, alignx, value);
160             }
161         }
162
163         /// <summary>
164         /// Gets or sets the manner in which the items grid is filled within a given gengrid widget.
165         /// It is filled if true, otherwise false.
166         /// </summary>
167         public bool FillItems
168         {
169             get
170             {
171                 return Interop.Elementary.elm_gengrid_filled_get(RealHandle);
172             }
173             set
174             {
175                 Interop.Elementary.elm_gengrid_filled_set(RealHandle, value);
176             }
177         }
178
179         /// <summary>
180         /// Gets or sets whether multi-selection is enabled or disabled for a given gengrid widget.
181         /// </summary>
182         /// <remarks>
183         /// Multi-selection is the ability to have more than one item selected, on a given gengrid, simultaneously.
184         /// When it is enabled, a sequence of clicks on different items makes them all selected, progressively.
185         /// A click on an already selected item unselects it. If interacting via the keyboard, multi-selection is enabled while holding the "Shift" key.
186         /// By default, multi-selection is disabled.
187         /// </remarks>
188         public bool MultipleSelection
189         {
190             get
191             {
192                 return Interop.Elementary.elm_gengrid_multi_select_get(RealHandle);
193             }
194             set
195             {
196                 Interop.Elementary.elm_gengrid_multi_select_set(RealHandle, value);
197             }
198         }
199
200         /// <summary>
201         /// Gets or sets the width for the items of a given gengrid widget.
202         /// </summary>
203         /// <remarks>
204         /// A gengrid, after creation, still has no information on the size to give to each of its cells.
205         /// The default width and height just have one finger wide.
206         /// Use this property to force a custom width for your items, making them as big as you wish.
207         /// </remarks>
208         public int ItemWidth
209         {
210             get
211             {
212                 int width;
213                 Interop.Elementary.elm_gengrid_item_size_get(RealHandle, out width, IntPtr.Zero);
214                 return width;
215             }
216             set
217             {
218                 int height = ItemHeight;
219                 Interop.Elementary.elm_gengrid_item_size_set(RealHandle, value, height);
220             }
221         }
222
223         /// <summary>
224         /// Gets or sets the height for the items of a given gengrid widget.
225         /// </summary>
226         /// <remarks>
227         /// A gengrid, after creation, still has no information on the size to give to each of its cells.
228         /// The default width and height just have one finger wide.
229         /// Use this property to force a custom height for your items, making them as big as you wish.
230         /// </remarks>
231         public int ItemHeight
232         {
233             get
234             {
235                 int height;
236                 Interop.Elementary.elm_gengrid_item_size_get(RealHandle, IntPtr.Zero, out height);
237                 return height;
238             }
239             set
240             {
241                 int width = ItemWidth;
242                 Interop.Elementary.elm_gengrid_item_size_set(RealHandle, width, value);
243             }
244         }
245
246         /// <summary>
247         /// Gets or sets the gengrid select mode by <see cref="GenItemSelectionMode"/>.
248         /// </summary>
249         public GenItemSelectionMode SelectionMode
250         {
251             get
252             {
253                 return (GenItemSelectionMode)Interop.Elementary.elm_gengrid_select_mode_get(RealHandle);
254             }
255             set
256             {
257                 Interop.Elementary.elm_gengrid_select_mode_set(RealHandle, (int)value);
258             }
259         }
260
261         /// <summary>
262         /// Gets or sets the direction for which a given gengrid widget expands while placing its items.
263         /// </summary>
264         /// <remarks>
265         /// If true, items are placed in columns from top to bottom and when the space for a column is filled, another one is started on the right, thus expanding the grid horizontally.
266         /// If false, items are placed in rows from left to right, and when the space for a row is filled, another one is started below, thus expanding the grid vertically.
267         /// </remarks>
268         public bool IsHorizontal
269         {
270             get
271             {
272                 return Interop.Elementary.elm_gengrid_horizontal_get(RealHandle);
273             }
274             set
275             {
276                 Interop.Elementary.elm_gengrid_horizontal_set(RealHandle, value);
277             }
278         }
279
280         /// <summary>
281         /// Gets or sets whether the gengrid items should be highlighted when an item is selected.
282         /// </summary>
283         public bool IsHighlight
284         {
285             get
286             {
287                 return Interop.Elementary.elm_gengrid_highlight_mode_get(RealHandle);
288             }
289             set
290             {
291                 Interop.Elementary.elm_gengrid_highlight_mode_set(RealHandle, value);
292             }
293         }
294
295         /// <summary>
296         /// Gets the first item in a given gengrid widget.
297         /// </summary>
298         public GenGridItem FirstItem
299         {
300             get
301             {
302                 IntPtr handle = Interop.Elementary.elm_gengrid_first_item_get(RealHandle);
303                 return ItemObject.GetItemByHandle(handle) as GenGridItem;
304             }
305         }
306
307         /// <summary>
308         /// Gets the last item in a given gengrid widget.
309         /// </summary>
310         public GenGridItem LastItem
311         {
312             get
313             {
314                 IntPtr handle = Interop.Elementary.elm_gengrid_last_item_get(RealHandle);
315                 return ItemObject.GetItemByHandle(handle) as GenGridItem;
316             }
317         }
318
319         /// <summary>
320         /// Gets the items count in a given gengrid widget.
321         /// </summary>
322         public uint ItemCount
323         {
324             get
325             {
326                 return Interop.Elementary.elm_gengrid_items_count(RealHandle);
327             }
328         }
329
330         /// <summary>
331         /// Gets the selected item in a given gengrid widget.
332         /// </summary>
333         public GenGridItem SelectedItem
334         {
335             get
336             {
337                 IntPtr handle = Interop.Elementary.elm_gengrid_selected_item_get(RealHandle);
338                 return ItemObject.GetItemByHandle(handle) as GenGridItem;
339             }
340         }
341
342         /// <summary>
343         /// Gets or sets whether a given gengrid widget is or not able have items reordered.
344         /// </summary>
345         public bool ReorderMode
346         {
347             get
348             {
349                 return Interop.Elementary.elm_gengrid_reorder_mode_get(RealHandle);
350             }
351             set
352             {
353                 Interop.Elementary.elm_gengrid_reorder_mode_set(RealHandle, value);
354             }
355         }
356
357         /// <summary>
358         /// Appends a new item to a given gengrid widget. This adds an item to the end of the gengrid.
359         /// </summary>
360         /// <param name="itemClass">The itemClass defines how to display the data.</param>
361         /// <param name="data">The item data.</param>
362         /// <returns>Return a gengrid item that contains data and itemClass.</returns>
363         /// <seealso cref="GenItemClass"/>
364         /// <seealso cref="GenGridItem"/>
365         public GenGridItem Append(GenItemClass itemClass, object data)
366         {
367             GenGridItem item = new GenGridItem(data, itemClass);
368             IntPtr handle = Interop.Elementary.elm_gengrid_item_append(RealHandle, itemClass.UnmanagedPtr, (IntPtr)item.Id, null, (IntPtr)item.Id);
369             item.Handle = handle;
370             AddInternal(item);
371             return item;
372         }
373
374         /// <summary>
375         /// Prepends a new item to a given gengrid widget. This adds an item to the beginning of the gengrid.
376         /// </summary>
377         /// <param name="itemClass">The itemClass defines how to display the data.</param>
378         /// <param name="data">The item data.</param>
379         /// <returns>Return a gengrid item that contains data and itemClass.</returns>
380         /// <seealso cref="GenItemClass"/>
381         /// <seealso cref="GenGridItem"/>
382         public GenGridItem Prepend(GenItemClass itemClass, object data)
383         {
384             GenGridItem item = new GenGridItem(data, itemClass);
385             IntPtr handle = Interop.Elementary.elm_gengrid_item_prepend(RealHandle, itemClass.UnmanagedPtr, (IntPtr)item.Id, null, (IntPtr)item.Id);
386             item.Handle = handle;
387             AddInternal(item);
388             return item;
389         }
390
391         /// <summary>
392         /// Inserts an item before another in a gengrid widget. This inserts an item before another in the gengrid.
393         /// </summary>
394         /// <param name="itemClass">The itemClass defines how to display the data.</param>
395         /// <param name="data">The item data.</param>
396         /// <param name="before">The item before which to place this new one.</param>
397         /// <returns>Return a gengrid item that contains data and itemClass./></returns>
398         /// <seealso cref="GenItemClass"/>
399         /// <seealso cref="GenGridItem"/>
400         public GenGridItem InsertBefore(GenItemClass itemClass, object data, GenGridItem before)
401         {
402             GenGridItem item = new GenGridItem(data, itemClass);
403             IntPtr handle = Interop.Elementary.elm_gengrid_item_insert_before(RealHandle, itemClass.UnmanagedPtr, (IntPtr)item.Id, before, null, (IntPtr)item.Id);
404             item.Handle = handle;
405             AddInternal(item);
406             return item;
407         }
408
409         /// <summary>
410         /// Inserts an item before another in a gengrid widget. This inserts an item after another in the gengrid.
411         /// </summary>
412         /// <param name="itemClass">The itemClass defines how to display the data.</param>
413         /// <param name="data">The item data.</param>
414         /// <param name="after">The item after which to place this new one.</param>
415         /// <returns>Return a gengrid item that contains data and itemClass.</returns>
416         /// <seealso cref="GenItemClass"/>
417         /// <seealso cref="GenGridItem"/>
418         public GenGridItem InsertAfter(GenItemClass itemClass, object data, GenGridItem after)
419         {
420             GenGridItem item = new GenGridItem(data, itemClass);
421             IntPtr handle = Interop.Elementary.elm_gengrid_item_insert_after(RealHandle, itemClass.UnmanagedPtr, (IntPtr)item.Id, after, null, (IntPtr)item.Id);
422             item.Handle = handle;
423             AddInternal(item);
424             return item;
425         }
426
427         /// <summary>
428         /// Insert an item in a gengrid widget using a user-defined sort function.
429         /// </summary>
430         /// <param name="itemClass">The itemClass defines how to display the data.</param>
431         /// <param name="data">The item data.</param>
432         /// <param name="comparison">User defined comparison function that defines the sort order based on gengrid item and its data.</param>
433         /// <returns>Return a gengrid item that contains data and itemClass.</returns>
434         public GenGridItem InsertSorted(GenItemClass itemClass, object data, Comparison<object> comparison)
435         {
436             GenGridItem item = new GenGridItem(data, itemClass);
437
438             Interop.Elementary.Eina_Compare_Cb compareCallback = (handle1, handle2) =>
439             {
440                 GenGridItem first = (ItemObject.GetItemByHandle(handle1) as GenGridItem) ?? item;
441                 GenGridItem second = (ItemObject.GetItemByHandle(handle2) as GenGridItem) ?? item;
442                 return comparison(first.Data, second.Data);
443             };
444
445             IntPtr handle = Interop.Elementary.elm_gengrid_item_sorted_insert(RealHandle, itemClass.UnmanagedPtr, (IntPtr)item.Id, compareCallback, null, (IntPtr)item.Id);
446             item.Handle = handle;
447             AddInternal(item);
448             return item;
449         }
450
451         /// <summary>
452         /// Shows a given item to the visible area of a gengrid.
453         /// </summary>
454         /// <param name="item">The gengrid item to display.</param>
455         /// <param name="position">The position of the item in the viewport.</param>
456         /// <param name="animated">The type of how to show the item.</param>
457         /// <remarks>
458         /// If animated is true, the gengrid shows item by scrolling if it's not fully visible.
459         /// If animated is false, the gengrid shows item by jumping if it's not fully visible.
460         /// </remarks>
461         /// <seealso cref="ScrollToPosition"/>
462         public void ScrollTo(GenGridItem item, ScrollToPosition position, bool animated)
463         {
464             if (animated)
465             {
466                 Interop.Elementary.elm_gengrid_item_bring_in(item.Handle, (int)position);
467             }
468             else
469             {
470                 Interop.Elementary.elm_gengrid_item_show(item.Handle, (int)position);
471             }
472         }
473
474         /// <summary>
475         /// Updates the contents of all the realized items.
476         /// This updates all realized items by calling all the <see cref="GenItemClass"/> again to get the content, text, and states.
477         /// Use this when the original item data has changed and the changes are desired to reflect.
478         /// </summary>
479         /// <remarks>
480         /// <see cref="GenItem.Update()"/> to update just one item.
481         /// </remarks>
482         public void UpdateRealizedItems()
483         {
484             Interop.Elementary.elm_gengrid_realized_items_update(RealHandle);
485         }
486
487         /// <summary>
488         /// Removes all items from a given gengrid widget.
489         /// This removes(and deletes) all items in obj, making it empty.
490         /// </summary>
491         /// <remarks>
492         /// <see cref="ItemObject.Delete()"/> to delete just one item.
493         /// </remarks>
494         public void Clear()
495         {
496             Interop.Elementary.elm_gengrid_clear(RealHandle);
497         }
498
499         /// <summary>
500         /// Get the item that is at the x, y canvas coords.
501         /// </summary>
502         /// <param name="x">The input x coordinate</param>
503         /// <param name="y">The input y coordinate</param>
504         /// <param name="portionX">The position relative to the item returned here.
505         /// -1, 0 or 1, depending if the coordinate is on the left portion of that item(-1), on the middle section(0) or on the right part(1).
506         /// </param>
507         /// <param name="portionY">The position relative to the item returned here
508         /// -1, 0 or 1, depending if the coordinate is on the upper portion of that item (-1), on the middle section (0) or on the lower part (1).
509         /// </param>
510         /// <returns></returns>
511         public GenGridItem GetItemByPosition(int x, int y, out int portionX, out int portionY)
512         {
513             IntPtr handle = Interop.Elementary.elm_gengrid_at_xy_item_get(RealHandle, x, y, out portionX, out portionY);
514             return ItemObject.GetItemByHandle(handle) as GenGridItem;
515         }
516
517         /// <summary>
518         /// Creates a widget handle.
519         /// </summary>
520         /// <param name="parent">Parent EvasObject</param>
521         /// <returns>Handle IntPtr</returns>
522         protected override IntPtr CreateHandle(EvasObject parent)
523         {
524             IntPtr handle = Interop.Elementary.elm_layout_add(parent.Handle);
525             Interop.Elementary.elm_layout_theme_set(handle, "layout", "elm_widget", "default");
526
527             RealHandle = Interop.Elementary.elm_gengrid_add(handle);
528             Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
529
530             return handle;
531         }
532
533         #region IScroller Implementation
534
535         /// <summary>
536         /// Scrolled will be triggered when the content has been scrolled.
537         /// </summary>
538         public event EventHandler Scrolled
539         {
540             add => _scroller.Scrolled += value;
541             remove => _scroller.Scrolled -= value;
542         }
543
544         /// <summary>
545         /// DragStart will be triggered when dragging the contents around has started.
546         /// </summary>
547         public event EventHandler DragStart
548         {
549             add => _scroller.DragStart += value;
550             remove => _scroller.DragStart -= value;
551         }
552
553         /// <summary>
554         /// DragStop will be triggered when dragging the contents around has stopped.
555         /// </summary>
556         public event EventHandler DragStop
557         {
558             add => _scroller.DragStop += value;
559             remove => _scroller.DragStop -= value;
560         }
561
562         /// <summary>
563         /// PageScrolled will be triggered when the visible page has changed.
564         /// </summary>
565         public event EventHandler PageScrolled
566         {
567             add => _scroller.PageScrolled += value;
568             remove => _scroller.PageScrolled -= value;
569         }
570
571         /// <summary>
572         /// Gets the current region in the content object that is visible through the Scroller.
573         /// </summary>
574         public Rect CurrentRegion => _scroller.CurrentRegion;
575
576         /// <summary>
577         /// Sets or gets the value of HorizontalScrollBarVisiblePolicy
578         /// </summary>
579         /// <remarks>
580         /// ScrollBarVisiblePolicy.Auto means the horizontal scrollbar is made visible if it is needed, and otherwise kept hidden.
581         /// ScrollBarVisiblePolicy.Visible turns it on all the time, and ScrollBarVisiblePolicy.Invisible always keeps it off.
582         /// </remarks>
583         public virtual ScrollBarVisiblePolicy HorizontalScrollBarVisiblePolicy
584         {
585             get => _scroller.HorizontalScrollBarVisiblePolicy;
586             set => _scroller.HorizontalScrollBarVisiblePolicy = value;
587         }
588
589         /// <summary>
590         /// Sets or gets the value of VerticalScrollBarVisiblePolicy
591         /// </summary>
592         /// <remarks>
593         /// ScrollBarVisiblePolicy.Auto means the vertical scrollbar is made visible if it is needed, and otherwise kept hidden.
594         /// ScrollBarVisiblePolicy.Visible turns it on all the time, and ScrollBarVisiblePolicy.Invisible always keeps it off.
595         /// </remarks>
596         public virtual ScrollBarVisiblePolicy VerticalScrollBarVisiblePolicy
597         {
598             get => _scroller.VerticalScrollBarVisiblePolicy;
599             set => _scroller.VerticalScrollBarVisiblePolicy = value;
600         }
601
602         /// <summary>
603         /// Sets or gets the value of ScrollBlock.
604         /// </summary>
605         /// <remarks>
606         /// This function will block scrolling movement  in a given direction.One can disable movements in the X axis, the Y axis or both.
607         /// The default value is ScrollBlock.None, where movements are allowed in both directions.
608         /// </remarks>
609         public ScrollBlock ScrollBlock
610         {
611             get => _scroller.ScrollBlock;
612             set => _scroller.ScrollBlock = value;
613         }
614
615         /// <summary>
616         /// Sets or gets scroll current page number.
617         /// </summary>
618         /// <remarks>
619         /// Current page means the page which meets the top of the viewport.
620         /// If there are two or more pages in the viewport, it returns the number of the page which meets the top of the viewport.
621         /// The page number starts from 0. 0 is the first page.
622         /// </remarks>
623         public int VerticalPageIndex => _scroller.VerticalPageIndex;
624
625         /// <summary>
626         /// Sets or gets scroll current page number.
627         /// </summary>
628         /// <remarks>
629         /// Current page means the page which meets the left of the viewport.
630         /// If there are two or more pages in the viewport, it returns the number of the page which meets the left of the viewport.
631         /// The page number starts from 0. 0 is the first page.
632         /// </remarks>
633         public int HorizontalPageIndex => _scroller.HorizontalPageIndex;
634
635         /// <summary>
636         /// Sets or gets the maximum limit of the movable page at vertical direction.
637         /// </summary>
638         public int VerticalPageScrollLimit
639         {
640             get => _scroller.VerticalPageScrollLimit;
641             set => _scroller.VerticalPageScrollLimit = value;
642         }
643
644         /// <summary>
645         /// Sets or gets the maximum limit of the movable page at horizontal direction.
646         /// </summary>
647         public int HorizontalPageScrollLimit
648         {
649             get => _scroller.HorizontalPageScrollLimit;
650             set => _scroller.HorizontalPageScrollLimit = value;
651         }
652
653         /// <summary>
654         /// Sets or gets the vertical bounce behaviour.
655         /// When scrolling, the scroller may "bounce" when reaching an edge of the content object.
656         /// This is a visual way to indicate the end has been reached.
657         /// This is enabled by default for both axis.
658         /// This API will set if it is enabled for the given axis with the boolean parameters for each axis.
659         /// </summary>
660         public bool VerticalBounce
661         {
662             get => _scroller.VerticalBounce;
663             set => _scroller.VerticalBounce = value;
664         }
665
666         /// <summary>
667         /// Sets or gets the horizontal bounce behaviour.
668         /// When scrolling, the scroller may "bounce" when reaching an edge of the content object.
669         /// This is a visual way to indicate the end has been reached.
670         /// This is enabled by default for both axis.
671         /// This API will set if it is enabled for the given axis with the boolean parameters for each axis.
672         /// </summary>
673         public bool HorizontalBounce
674         {
675             get => _scroller.HorizontalBounce;
676             set => _scroller.HorizontalBounce = value;
677         }
678
679         /// <summary>
680         /// Gets the width of the content object of the scroller.
681         /// </summary>
682         public int ChildWidth
683         {
684             get => _scroller.ChildWidth;
685         }
686
687         /// <summary>
688         /// Gets the height of the content object of the scroller.
689         /// </summary>
690         public int ChildHeight
691         {
692             get => _scroller.ChildHeight;
693         }
694
695         /// <summary>
696         /// Set scrolling gravity values for a scroller.
697         /// The gravity, defines how the scroller will adjust its view when the size of the scroller contents increase.
698         /// The scroller will adjust the view to glue itself as follows.
699         /// x=0.0, for staying where it is relative to the left edge of the content x=1.0, for staying where it is relative to the rigth edge of the content y=0.0, for staying where it is relative to the top edge of the content y=1.0, for staying where it is relative to the bottom edge of the content
700         /// Default values for x and y are 0.0
701         /// </summary>
702         public double HorizontalGravity
703         {
704             get => _scroller.HorizontalGravity;
705             set => _scroller.HorizontalGravity = value;
706         }
707
708         /// <summary>
709         /// Set scrolling gravity values for a scroller.
710         /// The gravity, defines how the scroller will adjust its view when the size of the scroller contents increase.
711         /// The scroller will adjust the view to glue itself as follows.
712         /// x=0.0, for staying where it is relative to the left edge of the content x=1.0, for staying where it is relative to the rigth edge of the content y=0.0, for staying where it is relative to the top edge of the content y=1.0, for staying where it is relative to the bottom edge of the content
713         /// Default values for x and y are 0.0
714         /// </summary>
715         public double VerticalGravity
716         {
717             get => _scroller.VerticalGravity;
718             set => _scroller.VerticalGravity = value;
719         }
720
721         /// <summary>
722         /// Get scroll last page number.
723         /// The page number starts from 0. 0 is the first page. This returns the last page number among the pages.
724         /// </summary>
725         public int LastVerticalPageNumber => _scroller.LastVerticalPageNumber;
726
727         /// <summary>
728         /// Get scroll last page number.
729         /// The page number starts from 0. 0 is the first page. This returns the last page number among the pages.
730         /// </summary>
731         public int LastHorizontalPageNumber => _scroller.LastHorizontalPageNumber;
732
733         /// <summary>
734         /// Set an infinite loop_ for a scroller.
735         /// This function sets the infinite loop vertically.
736         /// If the content is set, it will be shown repeatedly.
737         /// </summary>
738         public bool VerticalLoop
739         {
740             get => _scroller.VerticalLoop;
741             set => _scroller.VerticalLoop = value;
742         }
743
744         /// <summary>
745         /// Set an infinite loop_ for a scroller.
746         /// This function sets the infinite loop horizontally.
747         /// If the content is set, it will be shown repeatedly.
748         /// </summary>
749         public bool HorizontalLoop
750         {
751             get => _scroller.HorizontalLoop;
752             set => _scroller.HorizontalLoop = value;
753         }
754
755         /// <summary>
756         /// Gets or sets the page size to an absolute fixed value, with 0 turning it off for that axis.
757         /// </summary>
758         public int HorizontalPageSize
759         {
760             get => _scroller.HorizontalPageSize;
761             set => _scroller.HorizontalPageSize = value;
762         }
763
764         /// <summary>
765         /// Gets or sets the page size to an absolute fixed value, with 0 turning it off for that axis.
766         /// </summary>
767         public int VerticalPageSize
768         {
769             get => _scroller.VerticalPageSize;
770             set => _scroller.VerticalPageSize = value;
771         }
772
773         /// <summary>
774         /// Gets or sets a given scroller widget's scrolling page size, relative to its viewport size.
775         /// </summary>
776         public double VerticalRelativePageSize
777         {
778             get => _scroller.VerticalRelativePageSize;
779             set => _scroller.VerticalRelativePageSize = value;
780         }
781
782         /// <summary>
783         /// Gets or sets a given scroller widget's scrolling page size, relative to its viewport size.
784         /// </summary>
785         public double HorizontalRelativePageSize
786         {
787             get => _scroller.HorizontalRelativePageSize;
788             set => _scroller.HorizontalRelativePageSize = value;
789         }
790
791         /// <summary>
792         /// Gets or Sets the page snapping behavior of a scroller.
793         /// </summary>
794         /// <remarks>
795         /// When scrolling, if a scroller is paged (see VerticalRelativePageSize),
796         /// the scroller may snap to pages when being scrolled, i.e., even if it had momentum to scroll further,
797         /// it will stop at the next page boundaries. This is disabled, by default, for both axis.
798         /// This function will set if it that is enabled or not, for each axis.
799         /// </remarks>
800         public bool VerticalSnap
801         {
802             get => _scroller.VerticalSnap;
803             set => _scroller.VerticalSnap = value;
804         }
805
806         /// <summary>
807         /// Gets or Sets the page snapping behavior of a scroller.
808         /// </summary>
809         /// <remarks>
810         /// When scrolling, if a scroller is paged (see HorizontalRelativePageSize),
811         /// the scroller may snap to pages when being scrolled, i.e., even if it had momentum to scroll further,
812         /// it will stop at the next page boundaries. This is disabled, by default, for both axis.
813         /// This function will set if it that is enabled or not, for each axis.
814         /// </remarks>
815         public bool HorizontalSnap
816         {
817             get => _scroller.HorizontalSnap;
818             set => _scroller.HorizontalSnap = value;
819         }
820
821         /// <summary>
822         /// Gets or sets the page size to an absolute fixed value, with 0 turning it off for that axis.
823         /// </summary>
824         public int PageHeight
825         {
826             get => _scroller.PageHeight;
827             set => _scroller.PageHeight = value;
828         }
829
830         /// <summary>
831         /// Gets or sets the page size to an absolute fixed value, with 0 turning it off for that axis.
832         /// </summary>
833         public int PageWidth
834         {
835             get => _scroller.PageWidth;
836             set => _scroller.PageWidth = value;
837         }
838
839         /// <summary>
840         /// Gets or sets the step size to move scroller by key event.
841         /// </summary>
842         public int HorizontalStepSize
843         {
844             get => _scroller.HorizontalStepSize;
845             set => _scroller.HorizontalStepSize = value;
846         }
847
848         /// <summary>
849         /// Gets or sets the step size to move scroller by key event.
850         /// </summary>
851         public int VerticalStepSize
852         {
853             get => _scroller.VerticalStepSize;
854             set => _scroller.VerticalStepSize = value;
855         }
856
857         /// <summary>
858         /// Gets or sets a value whether mouse wheel is enabled or not over the scroller.
859         /// </summary>
860         public bool WheelDisabled
861         {
862             get => _scroller.WheelDisabled;
863             set => _scroller.WheelDisabled = value;
864         }
865
866         /// <summary>
867         /// Gets or sets the type of single direction scroll.
868         /// </summary>
869         public ScrollSingleDirection SingleDirection
870         {
871             get => _scroller.SingleDirection;
872             set => _scroller.SingleDirection = value;
873         }
874
875         /// <summary>
876         /// Sets the scroller minimum size limited to the minimum size of the content.
877         /// By default the scroller will be as small as its design allows, irrespective of its content.
878         /// This will make the scroller minimum size the right size horizontally and/or vertically to perfectly fit its content in that direction.
879         /// </summary>
880         /// <param name="horizontal">Enable limiting minimum size horizontally</param>
881         /// <param name="vertical">Enable limiting minimum size vertically</param>
882         public void MinimumLimit(bool horizontal, bool vertical)
883         {
884             _scroller.MinimumLimit(horizontal, vertical);
885         }
886
887         /// <summary>
888         /// Shows a specific virtual region within the scroller content object by the page number.
889         /// (0, 0) of the indicated page is located at the top-left corner of the viewport.
890         /// </summary>
891         /// <param name="horizontalPageIndex">The horizontal page number.</param>
892         /// <param name="verticalPageIndex">The vertical page number.</param>
893         /// <param name="animated">True means slider with animation.</param>
894         public void ScrollTo(int horizontalPageIndex, int verticalPageIndex, bool animated)
895         {
896             _scroller.ScrollTo(horizontalPageIndex, verticalPageIndex, animated);
897         }
898
899         /// <summary>
900         /// Shows a specific virtual region within the scroller content object.
901         /// </summary>
902         /// <remarks>
903         /// This ensures that all (or part, if it does not fit) of the designated region in the virtual content object ((0, 0)
904         /// starting at the top-left of the virtual content object) is shown within the scroller.
905         /// If set "animated" to true, it will allows the scroller to "smoothly slide" to this location
906         /// (if configuration in general calls for transitions).
907         /// It may not jump immediately to the new location and may take a while and show other content along the way.
908         /// </remarks>
909         /// <param name="region">Rect struct of region.</param>
910         /// <param name="animated">True means allows the scroller to "smoothly slide" to this location.</param>
911         public void ScrollTo(Rect region, bool animated)
912         {
913             _scroller.ScrollTo(region, animated);
914         }
915
916         #endregion
917
918         void InitializeSmartEvent()
919         {
920             _selected = new SmartEvent<GenGridItemEventArgs>(this, this.RealHandle, "selected", GenGridItemEventArgs.CreateFromSmartEvent);
921             _unselected = new SmartEvent<GenGridItemEventArgs>(this, this.RealHandle, "unselected", GenGridItemEventArgs.CreateFromSmartEvent);
922             _activated = new SmartEvent<GenGridItemEventArgs>(this, this.RealHandle, "activated", GenGridItemEventArgs.CreateFromSmartEvent);
923             _pressed = new SmartEvent<GenGridItemEventArgs>(this, this.RealHandle, "pressed", GenGridItemEventArgs.CreateFromSmartEvent);
924             _released = new SmartEvent<GenGridItemEventArgs>(this, this.RealHandle, "released", GenGridItemEventArgs.CreateFromSmartEvent);
925             _doubleClicked = new SmartEvent<GenGridItemEventArgs>(this, this.RealHandle, "clicked,double", GenGridItemEventArgs.CreateFromSmartEvent);
926             _realized = new SmartEvent<GenGridItemEventArgs>(this, this.RealHandle, "realized", GenGridItemEventArgs.CreateFromSmartEvent);
927             _unrealized = new SmartEvent<GenGridItemEventArgs>(this, this.RealHandle, "unrealized", GenGridItemEventArgs.CreateFromSmartEvent);
928             _longpressed = new SmartEvent<GenGridItemEventArgs>(this, this.RealHandle, "longpressed", GenGridItemEventArgs.CreateFromSmartEvent);
929             _changed = new SmartEvent(this, this.RealHandle, "changed");
930
931             _selected.On += (s, e) => { if (e.Item != null) ItemSelected?.Invoke(this, e); };
932             _unselected.On += (s, e) => { if (e.Item != null) ItemUnselected?.Invoke(this, e); };
933             _activated.On += (s, e) => { if (e.Item != null) ItemActivated?.Invoke(this, e); };
934             _pressed.On += (s, e) => { if (e.Item != null) ItemPressed?.Invoke(this, e); };
935             _released.On += (s, e) => { if (e.Item != null) ItemReleased?.Invoke(this, e); };
936             _doubleClicked.On += (s, e) => { if (e.Item != null) ItemDoubleClicked?.Invoke(this, e); };
937             _realized.On += (s, e) => { if (e.Item != null) ItemRealized?.Invoke(this, e); };
938             _unrealized.On += (s, e) => { if (e.Item != null) ItemUnrealized?.Invoke(this, e); };
939             _longpressed.On += (s, e) => { if (e.Item != null) ItemLongPressed?.Invoke(this, e); };
940             _changed.On += (s, e) => { Changed?.Invoke(this, e); };
941         }
942
943         void AddInternal(GenGridItem item)
944         {
945             _children.Add(item);
946             item.Deleted += Item_Deleted;
947         }
948
949         void Item_Deleted(object sender, EventArgs e)
950         {
951             _children.Remove((GenGridItem)sender);
952         }
953     }
954 }