2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 using System.Collections.Generic;
23 /// Enumeration for setting list's resizing behavior, transverse axis scrolling and items cropping.
28 /// The list won't set any of its size hints to inform how a possible container should resize it.
29 /// Then, if it's not created as a "resize object", it might end with zeroed dimensions.
30 /// The list 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.
34 /// 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.
38 /// Sets a minimum size hint on the genlist object, so that containers may respect it (and resize itself to fit the child properly).
39 /// More specifically, a minimum size hint will be set for its transverse axis, so that the largest item in that direction fits well.
40 /// This is naturally bound by the list object's maximum size hints, set externally.
44 /// Besides setting a minimum size on the transverse axis, just like on Limit, the list will set a minimum size on th longitudinal axis, trying to reserve space to all its children to be visible at a time.
45 /// This is naturally bound by the list object's maximum size hints, set externally.
51 /// It inherits System.EventArgs.
52 /// It contains Item which is <see cref="ListItem"/> type.
53 /// All events of List contain ListItemEventArgs as a parameter.
55 public class ListItemEventArgs : EventArgs
58 /// Gets or sets List item. The return type is <see cref="ListItem"/>.
60 public ListItem Item { get; set; }
62 internal static ListItemEventArgs CreateFromSmartEvent(IntPtr data, IntPtr obj, IntPtr info)
64 ListItem item = ItemObject.GetItemByHandle(info) as ListItem;
65 return new ListItemEventArgs() { Item = item };
70 /// It inherits <see cref="Layout"/>.
71 /// The List is a widget that aims to display simple list item which has 2 icons and 1 text, and can be selected.
72 /// For more robust lists, <see cref="GenList"/> should probably be used.
74 /// <seealso cref="GenList"/>
75 /// <seealso cref="GenGrid"/>
76 public class List : Layout, IScrollable
78 ScrollableAdapter _scroller;
79 HashSet<ListItem> _children = new HashSet<ListItem>();
80 SmartEvent<ListItemEventArgs> _selected;
81 SmartEvent<ListItemEventArgs> _unselected;
82 SmartEvent<ListItemEventArgs> _doubleClicked;
83 SmartEvent<ListItemEventArgs> _longpressed;
84 SmartEvent<ListItemEventArgs> _activated;
87 /// Creates and initializes a new instance of the List class.
89 /// <param name="parent">The parent is a given container which will be attached by List as a child. It's <see cref="EvasObject"/> type.</param>
90 public List(EvasObject parent) : base(parent)
92 _selected = new SmartEvent<ListItemEventArgs>(this, this.RealHandle, "selected", ListItemEventArgs.CreateFromSmartEvent);
93 _unselected = new SmartEvent<ListItemEventArgs>(this, this.RealHandle, "unselected", ListItemEventArgs.CreateFromSmartEvent);
94 _doubleClicked = new SmartEvent<ListItemEventArgs>(this, this.RealHandle, "clicked,double", ListItemEventArgs.CreateFromSmartEvent);
95 _longpressed = new SmartEvent<ListItemEventArgs>(this, this.RealHandle, "longpressed", ListItemEventArgs.CreateFromSmartEvent);
96 _activated = new SmartEvent<ListItemEventArgs>(this, this.RealHandle, "activated", ListItemEventArgs.CreateFromSmartEvent);
97 _selected.On += (s, e) => { ItemSelected?.Invoke(this, e); };
98 _unselected.On += (s, e) => { ItemUnselected?.Invoke(this, e); };
99 _doubleClicked.On += (s, e) => { ItemDoubleClicked?.Invoke(this, e); };
100 _longpressed.On += (s, e) => { ItemLongPressed?.Invoke(this, e); };
101 _activated.On += (s, e) => { ItemActivated?.Invoke(this, e); };
105 /// Gets or sets which mode to use for the list.
111 return (ListMode)Interop.Elementary.elm_list_mode_get(RealHandle);
115 Interop.Elementary.elm_list_mode_set(RealHandle, (Interop.Elementary.Elm_List_Mode)value);
120 /// Gets the selected item.
122 public ListItem SelectedItem
126 IntPtr item = Interop.Elementary.elm_list_selected_item_get(RealHandle);
127 return ItemObject.GetItemByHandle(item) as ListItem;
132 /// ItemSelected is raised when a new list item is selected.
134 public event EventHandler<ListItemEventArgs> ItemSelected;
137 /// ItemUnselected is raised when the list item is Unselected.
139 public event EventHandler<ListItemEventArgs> ItemUnselected;
142 /// ItemDoubleClicked is raised when a new list item is double clicked.
144 public event EventHandler<ListItemEventArgs> ItemDoubleClicked;
147 /// ItemLongPressed is raised when a list item is pressed for a certain amount of time. By default it's 1 second.
149 public event EventHandler<ListItemEventArgs> ItemLongPressed;
152 /// ItemActivated is raised when a new list item is double clicked or pressed (enter|return|spacebar).
154 public event EventHandler<ListItemEventArgs> ItemActivated;
158 /// Call before running <see cref="EvasObject.Show"/> on the list object.
159 /// If not called, it won't display the list properly.
163 Interop.Elementary.elm_list_go(RealHandle);
167 /// Appends a new item with a text to the end of a given list widget.
169 /// <param name="label">The text for the item.</param>
170 /// <returns>Return a new added list item that contains a text.</returns>
171 /// <seealso cref="ListItem"/>
172 public ListItem Append(string label)
174 return Append(label, null, null);
178 /// Appends a new item with a text and 2 icons to the end of a given list widget.
180 /// <param name="label">The text for the item.</param>
181 /// <param name="leftIcon">The left icon for the item.</param>
182 /// <param name="rightIcon">The right icon for the item.</param>
183 /// <returns>Return a new added list item that contains a text and 2 icons.</returns>
184 /// <seealso cref="ListItem"/>
185 public ListItem Append(string label, EvasObject leftIcon, EvasObject rightIcon)
187 ListItem item = new ListItem(label, leftIcon, rightIcon);
188 item.Handle = Interop.Elementary.elm_list_item_append(RealHandle, label, leftIcon, rightIcon, null, (IntPtr)item.Id);
194 /// Prepends a new item with a text to the beginning of a given list widget.
196 /// <param name="label">The text for the item.</param>
197 /// <returns>Return a new added list item that contains a text.</returns>
198 public ListItem Prepend(string label)
200 return Prepend(label, null, null);
204 /// Prepends a new item with a text and 2 icons to the beginning of a given list widget.
206 /// <param name="label">The text for the item.</param>
207 /// <param name="leftIcon">The left icon for the item.</param>
208 /// <param name="rigthIcon">The right icon for the item.</param>
209 /// <returns>Return a new added list item that contains a text and 2 icons.</returns>
210 public ListItem Prepend(string label, EvasObject leftIcon, EvasObject rigthIcon)
212 ListItem item = new ListItem(label, leftIcon, rigthIcon);
213 item.Handle = Interop.Elementary.elm_list_item_prepend(RealHandle, label, leftIcon, rigthIcon, null, (IntPtr)item.Id);
219 /// Removes all items from a given list widget.
220 /// To delete just one item, use <see cref="ItemObject.Delete"/>.
224 Interop.Elementary.elm_list_clear(RealHandle);
225 foreach (var item in _children)
227 item.Deleted -= Item_Deleted;
233 /// Creates a widget handle.
235 /// <param name="parent">Parent EvasObject</param>
236 /// <returns>Handle IntPtr</returns>
237 protected override IntPtr CreateHandle(EvasObject parent)
239 IntPtr handle = Interop.Elementary.elm_layout_add(parent.Handle);
240 Interop.Elementary.elm_layout_theme_set(handle, "layout", "elm_widget", "default");
242 RealHandle = Interop.Elementary.elm_list_add(handle);
243 Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
245 _scroller = new ScrollableAdapter(this);
250 #region IScroller Implementation
253 /// Scrolled will be triggered when the content has been scrolled.
255 public event EventHandler Scrolled
257 add => _scroller.Scrolled += value;
258 remove => _scroller.Scrolled -= value;
262 /// DragStart will be triggered when dragging the contents around has started.
264 public event EventHandler DragStart
266 add => _scroller.DragStart += value;
267 remove => _scroller.DragStart -= value;
271 /// DragStop will be triggered when dragging the contents around has stopped.
273 public event EventHandler DragStop
275 add => _scroller.DragStop += value;
276 remove => _scroller.DragStop -= value;
280 /// PageScrolled will be triggered when the visible page has changed.
282 public event EventHandler PageScrolled
284 add => _scroller.PageScrolled += value;
285 remove => _scroller.PageScrolled -= value;
289 /// Gets the current region in the content object that is visible through the Scroller.
291 public Rect CurrentRegion => _scroller.CurrentRegion;
294 /// Sets or gets the value of HorizontalScrollBarVisiblePolicy
297 /// ScrollBarVisiblePolicy.Auto means the horizontal scrollbar is made visible if it is needed, and otherwise kept hidden.
298 /// ScrollBarVisiblePolicy.Visible turns it on all the time, and ScrollBarVisiblePolicy.Invisible always keeps it off.
300 public virtual ScrollBarVisiblePolicy HorizontalScrollBarVisiblePolicy
302 get => _scroller.HorizontalScrollBarVisiblePolicy;
303 set => _scroller.HorizontalScrollBarVisiblePolicy = value;
307 /// Sets or gets the value of VerticalScrollBarVisiblePolicy
310 /// ScrollBarVisiblePolicy.Auto means the vertical scrollbar is made visible if it is needed, and otherwise kept hidden.
311 /// ScrollBarVisiblePolicy.Visible turns it on all the time, and ScrollBarVisiblePolicy.Invisible always keeps it off.
313 public virtual ScrollBarVisiblePolicy VerticalScrollBarVisiblePolicy
315 get => _scroller.VerticalScrollBarVisiblePolicy;
316 set => _scroller.VerticalScrollBarVisiblePolicy = value;
320 /// Sets or gets the value of ScrollBlock.
323 /// This function will block scrolling movement in a given direction.One can disable movements in the X axis, the Y axis or both.
324 /// The default value is ScrollBlock.None, where movements are allowed in both directions.
326 public ScrollBlock ScrollBlock
328 get => _scroller.ScrollBlock;
329 set => _scroller.ScrollBlock = value;
333 /// Sets or gets scroll current page number.
336 /// Current page means the page which meets the top of the viewport.
337 /// If there are two or more pages in the viewport, it returns the number of the page which meets the top of the viewport.
338 /// The page number starts from 0. 0 is the first page.
340 public int VerticalPageIndex => _scroller.VerticalPageIndex;
343 /// Sets or gets scroll current page number.
346 /// Current page means the page which meets the left of the viewport.
347 /// If there are two or more pages in the viewport, it returns the number of the page which meets the left of the viewport.
348 /// The page number starts from 0. 0 is the first page.
350 public int HorizontalPageIndex => _scroller.HorizontalPageIndex;
353 /// Sets or gets the maximum limit of the movable page at vertical direction.
355 public int VerticalPageScrollLimit
357 get => _scroller.VerticalPageScrollLimit;
358 set => _scroller.VerticalPageScrollLimit = value;
362 /// Sets or gets the maximum limit of the movable page at horizontal direction.
364 public int HorizontalPageScrollLimit
366 get => _scroller.HorizontalPageScrollLimit;
367 set => _scroller.HorizontalPageScrollLimit = value;
371 /// Sets or gets the vertical bounce behaviour.
372 /// When scrolling, the scroller may "bounce" when reaching an edge of the content object.
373 /// This is a visual way to indicate the end has been reached.
374 /// This is enabled by default for both axis.
375 /// This API will set if it is enabled for the given axis with the boolean parameters for each axis.
377 public bool VerticalBounce
379 get => _scroller.VerticalBounce;
380 set => _scroller.VerticalBounce = value;
384 /// Sets or gets the horizontal bounce behaviour.
385 /// When scrolling, the scroller may "bounce" when reaching an edge of the content object.
386 /// This is a visual way to indicate the end has been reached.
387 /// This is enabled by default for both axis.
388 /// This API will set if it is enabled for the given axis with the boolean parameters for each axis.
390 public bool HorizontalBounce
392 get => _scroller.HorizontalBounce;
393 set => _scroller.HorizontalBounce = value;
397 /// Gets the width of the content object of the scroller.
399 public int ChildWidth
401 get => _scroller.ChildWidth;
405 /// Gets the height of the content object of the scroller.
407 public int ChildHeight
409 get => _scroller.ChildHeight;
413 /// Set scrolling gravity values for a scroller.
414 /// The gravity, defines how the scroller will adjust its view when the size of the scroller contents increase.
415 /// The scroller will adjust the view to glue itself as follows.
416 /// 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
417 /// Default values for x and y are 0.0
419 public double HorizontalGravity
421 get => _scroller.HorizontalGravity;
422 set => _scroller.HorizontalGravity = value;
426 /// Set scrolling gravity values for a scroller.
427 /// The gravity, defines how the scroller will adjust its view when the size of the scroller contents increase.
428 /// The scroller will adjust the view to glue itself as follows.
429 /// 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
430 /// Default values for x and y are 0.0
432 public double VerticalGravity
434 get => _scroller.VerticalGravity;
435 set => _scroller.VerticalGravity = value;
439 /// Get scroll last page number.
440 /// The page number starts from 0. 0 is the first page. This returns the last page number among the pages.
442 public int LastVerticalPageNumber => _scroller.LastVerticalPageNumber;
445 /// Get scroll last page number.
446 /// The page number starts from 0. 0 is the first page. This returns the last page number among the pages.
448 public int LastHorizontalPageNumber => _scroller.LastHorizontalPageNumber;
451 /// Set an infinite loop_ for a scroller.
452 /// This function sets the infinite loop vertically.
453 /// If the content is set, it will be shown repeatedly.
455 public bool VerticalLoop
457 get => _scroller.VerticalLoop;
458 set => _scroller.VerticalLoop = value;
462 /// Set an infinite loop_ for a scroller.
463 /// This function sets the infinite loop horizontally.
464 /// If the content is set, it will be shown repeatedly.
466 public bool HorizontalLoop
468 get => _scroller.HorizontalLoop;
469 set => _scroller.HorizontalLoop = value;
473 /// Gets or sets the page size to an absolute fixed value, with 0 turning it off for that axis.
475 public int HorizontalPageSize
477 get => _scroller.HorizontalPageSize;
478 set => _scroller.HorizontalPageSize = value;
482 /// Gets or sets the page size to an absolute fixed value, with 0 turning it off for that axis.
484 public int VerticalPageSize
486 get => _scroller.VerticalPageSize;
487 set => _scroller.VerticalPageSize = value;
491 /// Gets or sets a given scroller widget's scrolling page size, relative to its viewport size.
493 public double VerticalRelativePageSize
495 get => _scroller.VerticalRelativePageSize;
496 set => _scroller.VerticalRelativePageSize = value;
500 /// Gets or sets a given scroller widget's scrolling page size, relative to its viewport size.
502 public double HorizontalRelativePageSize
504 get => _scroller.HorizontalRelativePageSize;
505 set => _scroller.HorizontalRelativePageSize = value;
509 /// Gets or Sets the page snapping behavior of a scroller.
512 /// When scrolling, if a scroller is paged (see VerticalRelativePageSize),
513 /// the scroller may snap to pages when being scrolled, i.e., even if it had momentum to scroll further,
514 /// it will stop at the next page boundaries. This is disabled, by default, for both axis.
515 /// This function will set if it that is enabled or not, for each axis.
517 public bool VerticalSnap
519 get => _scroller.VerticalSnap;
520 set => _scroller.VerticalSnap = value;
524 /// Gets or Sets the page snapping behavior of a scroller.
527 /// When scrolling, if a scroller is paged (see HorizontalRelativePageSize),
528 /// the scroller may snap to pages when being scrolled, i.e., even if it had momentum to scroll further,
529 /// it will stop at the next page boundaries. This is disabled, by default, for both axis.
530 /// This function will set if it that is enabled or not, for each axis.
532 public bool HorizontalSnap
534 get => _scroller.HorizontalSnap;
535 set => _scroller.HorizontalSnap = value;
539 /// Gets or sets the page size to an absolute fixed value, with 0 turning it off for that axis.
541 public int PageHeight
543 get => _scroller.PageHeight;
544 set => _scroller.PageHeight = value;
548 /// Gets or sets the page size to an absolute fixed value, with 0 turning it off for that axis.
552 get => _scroller.PageWidth;
553 set => _scroller.PageWidth = value;
557 /// Gets or sets the step size to move scroller by key event.
559 public int HorizontalStepSize
561 get => _scroller.HorizontalStepSize;
562 set => _scroller.HorizontalStepSize = value;
566 /// Gets or sets the step size to move scroller by key event.
568 public int VerticalStepSize
570 get => _scroller.VerticalStepSize;
571 set => _scroller.VerticalStepSize = value;
575 /// Gets or sets a value whether mouse wheel is enabled or not over the scroller.
577 public bool WheelDisabled
579 get => _scroller.WheelDisabled;
580 set => _scroller.WheelDisabled = value;
584 /// Gets or sets the type of single direction scroll.
586 public ScrollSingleDirection SingleDirection
588 get => _scroller.SingleDirection;
589 set => _scroller.SingleDirection = value;
593 /// Sets the scroller minimum size limited to the minimum size of the content.
594 /// By default the scroller will be as small as its design allows, irrespective of its content.
595 /// This will make the scroller minimum size the right size horizontally and/or vertically to perfectly fit its content in that direction.
597 /// <param name="horizontal">Enable limiting minimum size horizontally</param>
598 /// <param name="vertical">Enable limiting minimum size vertically</param>
599 public void MinimumLimit(bool horizontal, bool vertical)
601 _scroller.MinimumLimit(horizontal, vertical);
605 /// Shows a specific virtual region within the scroller content object by the page number.
606 /// (0, 0) of the indicated page is located at the top-left corner of the viewport.
608 /// <param name="horizontalPageIndex">The horizontal page number.</param>
609 /// <param name="verticalPageIndex">The vertical page number.</param>
610 /// <param name="animated">True means slider with animation.</param>
611 public void ScrollTo(int horizontalPageIndex, int verticalPageIndex, bool animated)
613 _scroller.ScrollTo(horizontalPageIndex, verticalPageIndex, animated);
617 /// Shows a specific virtual region within the scroller content object.
620 /// This ensures that all (or part, if it does not fit) of the designated region in the virtual content object ((0, 0)
621 /// starting at the top-left of the virtual content object) is shown within the scroller.
622 /// If set "animated" to true, it will allows the scroller to "smoothly slide" to this location
623 /// (if configuration in general calls for transitions).
624 /// It may not jump immediately to the new location and may take a while and show other content along the way.
626 /// <param name="region">Rect struct of region.</param>
627 /// <param name="animated">True means allows the scroller to "smoothly slide" to this location.</param>
628 public void ScrollTo(Rect region, bool animated)
630 _scroller.ScrollTo(region, animated);
635 void AddInternal(ListItem item)
638 item.Deleted += Item_Deleted;
641 void Item_Deleted(object sender, EventArgs e)
643 _children.Remove((ListItem)sender);