[ElmSharp*] Add Scrollable interface
[platform/core/csapi/tizenfx.git] / src / ElmSharp / ElmSharp / Scroller.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
19 namespace ElmSharp
20 {
21     /// <summary>
22     /// The Scroller is a container that holds and clips a single object and allows you to scroll across it.
23     /// </summary>
24     public class Scroller : Layout, IScrollable
25     {
26         ScrollableAdapter _adapter;
27
28         /// <summary>
29         /// Creates and initializes a new instance of the Scroller class.
30         /// </summary>
31         /// <param name="parent">The <see cref="EvasObject"/> to which the new Scroller will be attached as a child.</param>
32         public Scroller(EvasObject parent) : base(parent)
33         {
34         }
35
36         /// <summary>
37         /// Creates and initializes a new instance of the Scroller class.
38         /// </summary>
39         public Scroller() : base()
40         {
41         }
42
43         /// <summary>
44         /// Scrolled will be triggered when the content has been scrolled.
45         /// </summary>
46         public event EventHandler Scrolled
47         {
48             add => _adapter.Scrolled += value;
49             remove => _adapter.Scrolled -= value;
50         }
51
52         /// <summary>
53         /// DragStart will be triggered when dragging the contents around has started.
54         /// </summary>
55         public event EventHandler DragStart
56         {
57             add => _adapter.DragStart += value;
58             remove => _adapter.DragStart -= value;
59         }
60
61         /// <summary>
62         /// DragStop will be triggered when dragging the contents around has stopped.
63         /// </summary>
64         public event EventHandler DragStop
65         {
66             add => _adapter.DragStop += value;
67             remove => _adapter.DragStop -= value;
68         }
69
70         /// <summary>
71         /// PageScrolled will be triggered when the visible page has changed.
72         /// </summary>
73         public event EventHandler PageScrolled
74         {
75             add => _adapter.PageScrolled += value;
76             remove => _adapter.PageScrolled -= value;
77         }
78
79         /// <summary>
80         /// Gets the current region in the content object that is visible through the Scroller.
81         /// </summary>
82         public Rect CurrentRegion => _adapter.CurrentRegion;
83
84         /// <summary>
85         /// Sets or gets the value of HorizontalScrollBarVisiblePolicy
86         /// </summary>
87         /// <remarks>
88         /// ScrollBarVisiblePolicy.Auto means the horizontal scrollbar is made visible if it is needed, and otherwise kept hidden.
89         /// ScrollBarVisiblePolicy.Visible turns it on all the time, and ScrollBarVisiblePolicy.Invisible always keeps it off.
90         /// </remarks>
91         public virtual ScrollBarVisiblePolicy HorizontalScrollBarVisiblePolicy
92         {
93             get => _adapter.HorizontalScrollBarVisiblePolicy;
94             set => _adapter.HorizontalScrollBarVisiblePolicy = value;
95         }
96
97         /// <summary>
98         /// Sets or gets the value of VerticalScrollBarVisiblePolicy
99         /// </summary>
100         /// <remarks>
101         /// ScrollBarVisiblePolicy.Auto means the vertical scrollbar is made visible if it is needed, and otherwise kept hidden.
102         /// ScrollBarVisiblePolicy.Visible turns it on all the time, and ScrollBarVisiblePolicy.Invisible always keeps it off.
103         /// </remarks>
104         public virtual ScrollBarVisiblePolicy VerticalScrollBarVisiblePolicy
105         {
106             get => _adapter.VerticalScrollBarVisiblePolicy;
107             set => _adapter.VerticalScrollBarVisiblePolicy = value;
108         }
109
110         /// <summary>
111         /// Sets or gets the value of ScrollBlock.
112         /// </summary>
113         /// <remarks>
114         /// This function will block scrolling movement  in a given direction.One can disable movements in the X axis, the Y axis or both.
115         /// The default value is ScrollBlock.None, where movements are allowed in both directions.
116         /// </remarks>
117         public ScrollBlock ScrollBlock
118         {
119             get => _adapter.ScrollBlock;
120             set => _adapter.ScrollBlock = value;
121         }
122
123         /// <summary>
124         /// Sets or gets scroll current page number.
125         /// </summary>
126         /// <remarks>
127         /// Current page means the page which meets the top of the viewport.
128         /// If there are two or more pages in the viewport, it returns the number of the page which meets the top of the viewport.
129         /// The page number starts from 0. 0 is the first page.
130         /// </remarks>
131         public int VerticalPageIndex => _adapter.VerticalPageIndex;
132
133         /// <summary>
134         /// Sets or gets scroll current page number.
135         /// </summary>
136         /// <remarks>
137         /// Current page means the page which meets the left of the viewport.
138         /// If there are two or more pages in the viewport, it returns the number of the page which meets the left of the viewport.
139         /// The page number starts from 0. 0 is the first page.
140         /// </remarks>
141         public int HorizontalPageIndex => _adapter.HorizontalPageIndex;
142
143         /// <summary>
144         /// Sets or gets the maximum limit of the movable page at vertical direction.
145         /// </summary>
146         public int VerticalPageScrollLimit
147         {
148             get => _adapter.VerticalPageScrollLimit;
149             set => _adapter.VerticalPageScrollLimit = value;
150         }
151
152         /// <summary>
153         /// Sets or gets the maximum limit of the movable page at horizontal direction.
154         /// </summary>
155         public int HorizontalPageScrollLimit
156         {
157             get => _adapter.HorizontalPageScrollLimit;
158             set => _adapter.HorizontalPageScrollLimit = value;
159         }
160
161         /// <summary>
162         /// Sets or gets the vertical bounce behaviour.
163         /// When scrolling, the scroller may "bounce" when reaching an edge of the content object.
164         /// This is a visual way to indicate the end has been reached.
165         /// This is enabled by default for both axis.
166         /// This API will set if it is enabled for the given axis with the boolean parameters for each axis.
167         /// </summary>
168         public bool VerticalBounce
169         {
170             get => _adapter.VerticalBounce;
171             set => _adapter.VerticalBounce = value;
172         }
173
174         /// <summary>
175         /// Sets or gets the horizontal bounce behaviour.
176         /// When scrolling, the scroller may "bounce" when reaching an edge of the content object.
177         /// This is a visual way to indicate the end has been reached.
178         /// This is enabled by default for both axis.
179         /// This API will set if it is enabled for the given axis with the boolean parameters for each axis.
180         /// </summary>
181         public bool HorizontalBounce
182         {
183             get => _adapter.HorizontalBounce;
184             set => _adapter.HorizontalBounce = value;
185         }
186
187         /// <summary>
188         /// Gets the width of the content object of the scroller.
189         /// </summary>
190         public int ChildWidth
191         {
192             get => _adapter.ChildWidth;
193         }
194
195         /// <summary>
196         /// Gets the height of the content object of the scroller.
197         /// </summary>
198         public int ChildHeight
199         {
200             get => _adapter.ChildHeight;
201         }
202
203         /// <summary>
204         /// Set scrolling gravity values for a scroller.
205         /// The gravity, defines how the scroller will adjust its view when the size of the scroller contents increase.
206         /// The scroller will adjust the view to glue itself as follows.
207         /// 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
208         /// Default values for x and y are 0.0
209         /// </summary>
210         public double HorizontalGravity
211         {
212             get => _adapter.HorizontalGravity;
213             set => _adapter.HorizontalGravity = value;
214         }
215
216         /// <summary>
217         /// Set scrolling gravity values for a scroller.
218         /// The gravity, defines how the scroller will adjust its view when the size of the scroller contents increase.
219         /// The scroller will adjust the view to glue itself as follows.
220         /// 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
221         /// Default values for x and y are 0.0
222         /// </summary>
223         public double VerticalGravity
224         {
225             get => _adapter.VerticalGravity;
226             set => _adapter.VerticalGravity = value;
227         }
228
229         /// <summary>
230         /// Get scroll last page number.
231         /// The page number starts from 0. 0 is the first page. This returns the last page number among the pages.
232         /// </summary>
233         public int LastVerticalPageNumber => _adapter.LastVerticalPageNumber;
234
235         /// <summary>
236         /// Get scroll last page number.
237         /// The page number starts from 0. 0 is the first page. This returns the last page number among the pages.
238         /// </summary>
239         public int LastHorizontalPageNumber => _adapter.LastHorizontalPageNumber;
240
241         /// <summary>
242         /// Set an infinite loop_ for a scroller.
243         /// This function sets the infinite loop vertically.
244         /// If the content is set, it will be shown repeatedly.
245         /// </summary>
246         public bool VerticalLoop
247         {
248             get => _adapter.VerticalLoop;
249             set => _adapter.VerticalLoop = value;
250         }
251
252         /// <summary>
253         /// Set an infinite loop_ for a scroller.
254         /// This function sets the infinite loop horizontally.
255         /// If the content is set, it will be shown repeatedly.
256         /// </summary>
257         public bool HorizontalLoop
258         {
259             get => _adapter.HorizontalLoop;
260             set => _adapter.HorizontalLoop = value;
261         }
262
263         /// <summary>
264         /// Gets or sets the page size to an absolute fixed value, with 0 turning it off for that axis.
265         /// </summary>
266         public int HorizontalPageSize
267         {
268             get => _adapter.HorizontalPageSize;
269             set => _adapter.HorizontalPageSize = value;
270         }
271
272         /// <summary>
273         /// Gets or sets the page size to an absolute fixed value, with 0 turning it off for that axis.
274         /// </summary>
275         public int VerticalPageSize
276         {
277             get => _adapter.VerticalPageSize;
278             set => _adapter.VerticalPageSize = value;
279         }
280
281         /// <summary>
282         /// Gets or sets a given scroller widget's scrolling page size, relative to its viewport size.
283         /// </summary>
284         public double VerticalRelativePageSize
285         {
286             get => _adapter.VerticalRelativePageSize;
287             set => _adapter.VerticalRelativePageSize = value;
288         }
289
290         /// <summary>
291         /// Gets or sets a given scroller widget's scrolling page size, relative to its viewport size.
292         /// </summary>
293         public double HorizontalRelativePageSize
294         {
295             get => _adapter.HorizontalRelativePageSize;
296             set => _adapter.HorizontalRelativePageSize = value;
297         }
298
299         /// <summary>
300         /// Gets or Sets the page snapping behavior of a scroller.
301         /// </summary>
302         /// <remarks>
303         /// When scrolling, if a scroller is paged (see VerticalRelativePageSize),
304         /// the scroller may snap to pages when being scrolled, i.e., even if it had momentum to scroll further,
305         /// it will stop at the next page boundaries. This is disabled, by default, for both axis.
306         /// This function will set if it that is enabled or not, for each axis.
307         /// </remarks>
308         public bool VerticalSnap
309         {
310             get => _adapter.VerticalSnap;
311             set => _adapter.VerticalSnap = value;
312         }
313
314         /// <summary>
315         /// Gets or Sets the page snapping behavior of a scroller.
316         /// </summary>
317         /// <remarks>
318         /// When scrolling, if a scroller is paged (see HorizontalRelativePageSize),
319         /// the scroller may snap to pages when being scrolled, i.e., even if it had momentum to scroll further,
320         /// it will stop at the next page boundaries. This is disabled, by default, for both axis.
321         /// This function will set if it that is enabled or not, for each axis.
322         /// </remarks>
323         public bool HorizontalSnap
324         {
325             get => _adapter.HorizontalSnap;
326             set => _adapter.HorizontalSnap = value;
327         }
328
329         /// <summary>
330         /// Gets or sets the page size to an absolute fixed value, with 0 turning it off for that axis.
331         /// </summary>
332         public int PageHeight
333         {
334             get => _adapter.PageHeight;
335             set => _adapter.PageHeight = value;
336         }
337
338         /// <summary>
339         /// Gets or sets the page size to an absolute fixed value, with 0 turning it off for that axis.
340         /// </summary>
341         public int PageWidth
342         {
343             get => _adapter.PageWidth;
344             set => _adapter.PageWidth = value;
345         }
346
347         /// <summary>
348         /// Gets or sets the event propagation for a scroller.
349         /// This enables or disables event propagation from the scroller content to the scroller and its parent.
350         /// By default event propagation is enabled.
351         /// </summary>
352         public bool ContentPropagateEvents
353         {
354             get
355             {
356                 return Interop.Elementary.elm_scroller_propagate_events_get(RealHandle);
357             }
358             set
359             {
360                 Interop.Elementary.elm_scroller_propagate_events_set(RealHandle, value);
361             }
362         }
363
364         /// <summary>
365         /// Gets or sets the step size to move scroller by key event.
366         /// </summary>
367         public int HorizontalStepSize
368         {
369             get => _adapter.HorizontalStepSize;
370             set => _adapter.HorizontalStepSize = value;
371         }
372
373         /// <summary>
374         /// Gets or sets the step size to move scroller by key event.
375         /// </summary>
376         public int VerticalStepSize
377         {
378             get => _adapter.VerticalStepSize;
379             set => _adapter.VerticalStepSize = value;
380         }
381
382         /// <summary>
383         /// Gets or sets a value whether mouse wheel is enabled or not over the scroller.
384         /// </summary>
385         public bool WheelDisabled
386         {
387             get => _adapter.WheelDisabled;
388             set => _adapter.WheelDisabled = value;
389         }
390
391         /// <summary>
392         /// Gets or sets the type of single direction scroll.
393         /// </summary>
394         public ScrollSingleDirection SingleDirection
395         {
396             get => _adapter.SingleDirection;
397             set => _adapter.SingleDirection = value;
398         }
399
400         /// <summary>
401         /// Sets the scroller minimum size limited to the minimum size of the content.
402         /// By default the scroller will be as small as its design allows, irrespective of its content.
403         /// This will make the scroller minimum size the right size horizontally and/or vertically to perfectly fit its content in that direction.
404         /// </summary>
405         /// <param name="horizontal">Enable limiting minimum size horizontally</param>
406         /// <param name="vertical">Enable limiting minimum size vertically</param>
407         public void MinimumLimit(bool horizontal, bool vertical)
408         {
409             _adapter.MinimumLimit(horizontal, vertical);
410         }
411
412         /// <summary>
413         /// Sets the page size to an absolute fixed value, with 0 turning it off for that axis.
414         /// </summary>
415         /// <param name="width">The horizontal page size.</param>
416         /// <param name="height">The vertical page size.</param>
417         public void SetPageSize(int width, int height)
418         {
419             Interop.Elementary.elm_scroller_page_size_set(RealHandle, width, height);
420         }
421
422         /// <summary>
423         /// Sets the scroll page size relative to the viewport size.
424         /// </summary>
425         /// <remarks>
426         /// The scroller is capable of limiting scrolling by the user to "pages".
427         /// That is to jump by and only show a "whole page" at a time as if the continuous area of the scroller
428         /// content is split into page sized pieces. This sets the size of a page relative to the viewport of the scroller.
429         /// 1.0 is "1 viewport" which is the size (horizontally or vertically). 0.0 turns it off in that axis.
430         /// This is mutually exclusive with the page size (see elm_scroller_page_size_set() for more information).
431         /// Likewise 0.5 is "half a viewport". Usable values are normally between 0.0 and 1.0 including 1.0.
432         /// If you only want 1 axis to be page "limited", use 0.0 for the other axis.
433         /// </remarks>
434         /// <param name="width">The horizontal page relative size.</param>
435         /// <param name="height">The vertical page relative size.</param>
436         public void SetPageSize(double width, double height)
437         {
438             Interop.Elementary.elm_scroller_page_relative_set(RealHandle, width, height);
439         }
440
441         /// <summary>
442         /// Shows a specific virtual region within the scroller content object by the page number.
443         /// (0, 0) of the indicated page is located at the top-left corner of the viewport.
444         /// </summary>
445         /// <param name="horizontalPageIndex">The horizontal page number.</param>
446         /// <param name="verticalPageIndex">The vertical page number.</param>
447         /// <param name="animated">True means slider with animation.</param>
448         public void ScrollTo(int horizontalPageIndex, int verticalPageIndex, bool animated)
449         {
450             _adapter.ScrollTo(horizontalPageIndex, verticalPageIndex, animated);
451         }
452
453         /// <summary>
454         /// Shows a specific virtual region within the scroller content object.
455         /// </summary>
456         /// <remarks>
457         /// This ensures that all (or part, if it does not fit) of the designated region in the virtual content object ((0, 0)
458         /// starting at the top-left of the virtual content object) is shown within the scroller.
459         /// If set "animated" to true, it will allows the scroller to "smoothly slide" to this location
460         /// (if configuration in general calls for transitions).
461         /// It may not jump immediately to the new location and may take a while and show other content along the way.
462         /// </remarks>
463         /// <param name="region">Rect struct of region.</param>
464         /// <param name="animated">True means allows the scroller to "smoothly slide" to this location.</param>
465         public void ScrollTo(Rect region, bool animated)
466         {
467             _adapter.ScrollTo(region, animated);
468         }
469
470         /// <summary>
471         /// Creates a widget handle.
472         /// </summary>
473         /// <param name="parent">Parent EvasObject</param>
474         /// <returns>Handle IntPtr</returns>
475         protected override IntPtr CreateHandle(EvasObject parent)
476         {
477             IntPtr handle = Interop.Elementary.elm_layout_add(parent.Handle);
478             Interop.Elementary.elm_layout_theme_set(handle, "layout", "elm_widget", "default");
479
480             RealHandle = Interop.Elementary.elm_scroller_add(handle);
481             Interop.Elementary.elm_object_part_content_set(handle, "elm.swallow.content", RealHandle);
482
483             _adapter = new ScrollableAdapter(this);
484
485             return handle;
486         }
487     }
488 }