1/*
2 * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16/**
17 * @addtogroup UI_Components
18 * @{
19 *
20 * @brief Defines UI components such as buttons, texts, images, lists, and progress bars.
21 *
22 * @since 1.0
23 * @version 1.0
24 */
25
26/**
27 * @file ui_swipe_view.h
28 *
29 * @brief Defines the attributes and common functions of a swipe view.
30 *
31 * Each swipe view consists of multiple child views, which can be navigated through swiping. The child views can be
32 * either horizontal or vertical.
33 *
34 * @since 1.0
35 * @version 1.0
36 */
37
38#ifndef GRAPHIC_LITE_UI_SWIPE_VIEW_H
39#define GRAPHIC_LITE_UI_SWIPE_VIEW_H
40
41#include "animator/animator.h"
42#include "components/ui_abstract_scroll.h"
43
44namespace OHOS {
45/**
46 * @brief Represents a swipe view.
47 *
48 * Each swipe view consists of multiple child views, which can be navigated through swiping. The child views can be
49 * either horizontal or vertical.
50 *
51 * @see UIAbstractScroll
52 * @since 1.0
53 * @version 1.0
54 */
55class UISwipeView : public UIAbstractScroll {
56public:
57    /**
58     * @brief Represents a listener for changes of the swipe view.
59     *
60     * This is an inner class of <b>UISwipeView</b>. It contains a callback function to be invoked when the swipe view
61     * state changes.
62     *
63     * @since 1.0
64     * @version 1.0
65     */
66    class OnSwipeListener : public HeapBase {
67    public:
68        virtual void OnSwipe(UISwipeView& view) = 0;
69        virtual ~OnSwipeListener() {}
70    };
71
72    enum AlignMode : uint8_t { ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT };
73
74    /**
75     * @brief A constructor used to create a <b>UISwipeView</b> instance.
76     *
77     * @since 1.0
78     * @version 1.0
79     */
80    UISwipeView(uint8_t direction = HORIZONTAL);
81
82    /**
83     * @brief A destructor used to delete the <b>UISwipeView</b> instance.
84     *
85     * @since 1.0
86     * @version 1.0
87     */
88    virtual ~UISwipeView();
89
90    /**
91     * @brief Obtains the component type.
92     *
93     * @return Returns the component type, as defined in {@link UIViewType}.
94     * @since 1.0
95     * @version 1.0
96     */
97    UIViewType GetViewType() const override
98    {
99        return UI_SWIPE_VIEW;
100    }
101
102    /**
103     * @brief Sets the dragging direction.
104     *
105     * @param direction Indicates the dragging direction, either {@link HORIZONTAL} or {@link VERTICAL}.
106     * @since 1.0
107     * @version 1.0
108     */
109    void SetDirection(uint8_t direction)
110    {
111        direction_ = direction;
112    }
113
114    /**
115     * @brief Obtains the dragging direction.
116     *
117     * @return Returns the dragging direction.
118     * @since 1.0
119     * @version 1.0
120     */
121    uint8_t GetDirection() const
122    {
123        return direction_;
124    }
125
126    /**
127     * @brief Adds a view.
128     *
129     * @param view Indicates the view to add.
130     * @since 1.0
131     * @version 1.0
132     */
133    void Add(UIView* view) override;
134
135    /**
136     * @brief Inserts a view.
137     *
138     * @param prevView Indicates the previous view.
139     * @param insertView Indicates the view to insert.
140     * @since 1.0
141     * @version 1.0
142     */
143    void Insert(UIView* prevView, UIView* insertView) override;
144
145    /**
146     * @brief Deletes a view.
147     *
148     * @param view Indicates the view to delete.
149     * @since 1.0
150     * @version 1.0
151     */
152    void Remove(UIView* view) override;
153
154    /**
155     * @brief Sets the index for the current tab.
156     *
157     * @param index Indicates the index of a view.
158     * @param needAnimator Specifies whether a flip animation is needed. <b>false</b> (default value) indicates a flip
159     * animation is not needed, and <b>true</b> indicates the opposite case.
160     * @since 1.0
161     * @version 1.0
162     */
163    void SetCurrentPage(uint16_t index, bool needAnimator = false);
164
165    /**
166     * @brief Obtains the current tab index.
167     *
168     * @return Returns the current tab index.
169     * @since 1.0
170     * @version 1.0
171     */
172    uint16_t GetCurrentPage() const
173    {
174        return curIndex_;
175    }
176
177    /**
178     * @brief Obtains the current view.
179     *
180     * @return Returns the current view.
181     * @since 1.0
182     * @version 1.0
183     */
184    UIView* GetCurrentView() const
185    {
186        return curView_;
187    }
188
189    /**
190     * @brief Sets a blank size, as defined in {@link DEFAULT_BLANK_SIZE}
191     *
192     * @param size Indicates the blank size to set.
193     * @since 1.0
194     * @version 1.0
195     */
196    void SetBlankSize(uint16_t size)
197    {
198        blankSize_ = size;
199    }
200
201    /**
202     * @fn void OnDragEvent(const DragEvent& event) override
203     *
204     * @brief revice drag event, Switch to specified view when drag
205     *
206     * @param event The drag event
207     */
208    bool OnDragEvent(const DragEvent& event) override;
209
210    bool OnDragEndEvent(const DragEvent& event) override;
211
212#if defined(ENABLE_ROTATE_INPUT) && ENABLE_ROTATE_INPUT
213    bool OnRotateEvent(const RotateEvent& event) override;
214
215    bool OnRotateEndEvent(const RotateEvent& event) override;
216#endif
217
218    /**
219     * @brief Sets the time for the page being animated. The page will go beyond the blank during this time.
220     *
221     * @param time Indicates the time of the page being animated.
222     * @since 1.0
223     * @version 1.0
224     */
225    void SetAnimatorTime(uint16_t time);
226
227    /**
228     * @brief Sets whether the swipe view supports a cycle swipe.
229     *
230     * @param loop Indicates the cycle swipe flag. <b>true</b> indicates the cycle swipe is supported, and <b>false</b>
231     * indicates the opposite case.
232     * @since 1.0
233     * @version 1.0
234     */
235    void SetLoopState(bool loop)
236    {
237        loop_ = loop;
238    }
239
240    /**
241     * @brief Obtains a view based on its index.
242     *
243     * @param Indicates the index of a view.
244     * @return Returns the view.
245     * @since 1.0
246     * @version 1.0
247     */
248    UIView* GetViewByIndex(uint16_t index) const;
249
250    /**
251     * @brief Obtains the listener set for swipe events.
252     *
253     * @return Returns the swipe event listener.
254     * @since 1.0
255     * @version 1.0
256     */
257    OnSwipeListener*& GetOnSwipeListener()
258    {
259        return swipeListener_;
260    }
261
262    /**
263     * @brief Sets the listener that contains a callback to be invoked upon a swipe event.
264     *
265     * @param onSwipeListener Indicates the listener to set.
266     * @since 1.0
267     * @version 1.0
268     */
269    void SetOnSwipeListener(OnSwipeListener* onSwipeListener)
270    {
271        swipeListener_ = onSwipeListener;
272    }
273
274    /**
275     * @brief Sets the alignment mode for child components of <b>UISwipeView</b>.
276     *
277     * @param alignMode Indicates the alignment mode to set, as enumerated in {@link AlignMode}.
278     * The default value is <b>ALIGN_CENTER</b>.
279     * @since 1.0
280     * @version 1.0
281     */
282    void SetAlignMode(AlignMode alignMode = ALIGN_CENTER)
283    {
284        alignMode_ = alignMode;
285    }
286
287    /**
288     * @brief Obtains the alignment mode of child components of <b>UISwipeView</b>.
289     *
290     * @return Returns the alignment mode. For details, see {@link AlignMode}.
291     * @since 1.0
292     * @version 1.0
293     */
294    AlignMode GetAlignMode()
295    {
296        return alignMode_;
297    }
298
299    /**
300     * @brief Indicates the horizontal direction.
301     *
302     * @since 1.0
303     * @version 1.0
304     */
305    static constexpr uint8_t HORIZONTAL = 0;
306
307    /**
308     * @brief Indicates the vertical direction.
309     *
310     * @since 1.0
311     * @version 1.0
312     */
313    static constexpr uint8_t VERTICAL = 1;
314
315    void SetXScrollBarVisible(bool visible) = delete;
316
317    void SetYScrollBarVisible(bool visible) = delete;
318
319    void SetScrollBarSide(uint8_t side) = delete;
320
321    void SetScrollBarCenter(Point center) = delete;
322
323protected:
324    bool DragXInner(int16_t distance) override;
325    bool DragYInner(int16_t distance) override;
326    void SortChild();
327    void StopAnimator() override;
328    virtual void SwitchToPage(int16_t dst, bool needAnimator = true);
329    void MoveChildByOffset(int16_t xOffset, int16_t yOffset) override;
330    void MoveHeadOrTailChild();
331
332    /**
333     * @brief Indicates that the animation duration is 12 ticks.
334     *
335     * @since 1.0
336     * @version 1.0
337     */
338    constexpr static uint16_t ANIMATOR_TIME = 12;
339
340    /**
341     * @brief Indicates the maximum distance of an invalid dragging. Dragging is not triggered if the distance is less
342     * than this value.
343     *
344     * @since 1.0
345     * @version 1.0
346     */
347    constexpr static uint16_t STOP_DISTANCE = 5;
348
349    /**
350     * @brief Indicates the maximum distance between the first and the last tab when the current view is not in a cycle
351     * swipe mode. The page can be rebound after the setting.
352     *
353     * @since 1.0
354     * @version 1.0
355     */
356    constexpr static uint16_t DEFAULT_BLANK_SIZE = 30;
357    uint16_t tickTime_;
358    OnSwipeListener* swipeListener_;
359    uint16_t curIndex_;
360    uint16_t blankSize_;
361    UIView* curView_;
362    AlignMode alignMode_ = ALIGN_CENTER;
363    bool loop_;
364
365private:
366    void RefreshCurrentViewByPosition(int16_t (UIView::*pfnGetXOrY)() const, int16_t (UIView::*pfnGetWidthOrHeight)());
367    void RefreshCurrentViewByThrow(int16_t distance,
368                                   uint8_t dragDirection,
369                                   int16_t (UIView::*pfnGetXOrY)() const,
370                                   int16_t (UIView::*pfnGetWidthOrHeight)());
371
372    bool IsNeedLoop();
373    void MoveFirstChildToLast();
374    void MoveLastChildToFirst();
375    void CalculateInvalidate();
376    void CurrentIndexInc();
377    void CurrentIndexDec();
378    void Vibrator();
379};
380} // namespace OHOS
381#endif // GRAPHIC_LITE_UI_SWIPE_VIEW_H
382