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_picker.h
28 *
29 * @brief Defines the attributes and functions of the <b>UIPicker</b> class.
30 *
31 * @since 1.0
32 * @version 1.0
33 */
34
35#ifndef UI_PICKER_H
36#define UI_PICKER_H
37
38#include "components/text_adapter.h"
39#include "components/ui_list.h"
40
41namespace OHOS {
42class UIPicker;
43
44class PickerListScrollListener : public ListScrollListener {
45public:
46    PickerListScrollListener(UIPicker* picker, UIList* list);
47    virtual ~PickerListScrollListener() {}
48
49    void OnItemSelected(int16_t index, UIView* view) override;
50
51    void OnScrollEnd(int16_t index, UIView* view) override;
52
53    void SetSelectView(UIView* view)
54    {
55        selectView_ = view;
56        lastSelectView_ = view;
57    }
58
59    const UIView* GetSelectView() const
60    {
61        return selectView_;
62    }
63
64    void SetSelectIndex(uint16_t index)
65    {
66        selectIndex_ = index;
67    }
68
69    uint16_t GetSelectIndex() const
70    {
71        return selectIndex_;
72    }
73
74    void SetInitStatus(bool status)
75    {
76        isInitted_ = status;
77    }
78
79private:
80    UIList* listView_;
81    UIPicker* pickerView_;
82    UIView* selectView_;
83    UIView* lastSelectView_;
84    uint16_t selectIndex_;
85    bool isInitted_;
86};
87
88/**
89 * @brief Defines a picker. Multiple texts or numbers can be put into a sliding list for selection.
90 *        The selected text or numbers are highlighted.
91 *
92 * @since 1.0
93 * @version 1.0
94 */
95class UIPicker : public UIViewGroup {
96public:
97    /**
98     * @brief A constructor used to create a <b>UIPicker</b> instance.
99     *
100     * @since 1.0
101     * @version 1.0
102     */
103    UIPicker();
104
105    /**
106     * @brief A destructor used to delete the <b>UIPicker</b> instance.
107     *
108     * @since 1.0
109     * @version 1.0
110     */
111    virtual ~UIPicker();
112
113    /**
114     * @brief Obtains the view type.
115     *
116     * @return Returns the view type. For details, see {@link UIViewType}.
117     * @since 1.0
118     * @version 1.0
119     */
120    UIViewType GetViewType() const override
121    {
122        return UI_PICKER;
123    }
124
125    bool OnPreDraw(Rect& invalidatedArea) const override
126    {
127        return false;
128    }
129
130    /**
131     * @brief Sets dynamic text data in the picker by using a string array.
132     *
133     * @param value[] Indicates the array of text data.
134     * @param count   Indicates the array size.
135     * @return Returns <b>true</b> if the setting is successful; returns <b>false</b> otherwise.
136     * @since 1.0
137     * @version 1.0
138     */
139    virtual bool SetValues(const char* value[], uint16_t count);
140
141    /**
142     * @brief Sets the numeric data in the picker by using a given numeric range.
143     *
144     * All integers in the range are automatically generated based on the start value and end value and placed in
145     * the picker in sequence. The start value must be smaller or equal to the end value.
146     *
147     * @param start Indicates the start integer.
148     * @param end   Indicates the end integer.
149     * @return Returns <b>true</b> if the setting is successful; returns <b>false</b> otherwise.
150     * @since 1.0
151     * @version 1.0
152     */
153    virtual bool SetValues(int16_t start, int16_t end);
154
155    /**
156     * @brief Clears all values in the picker.
157     *
158     * @since 1.0
159     * @version 1.0
160     */
161    virtual void ClearValues();
162
163    /**
164     * @brief Sets the font IDs of dynamic text, which is the string array set through {@link SetValues}.
165     *
166     * @param backgroundFontId Indicates the font ID of the background text.
167     * @param highlightFontId  Indicates the font ID of the highlighted text.
168     * @since 1.0
169     * @version 1.0
170     */
171    void SetFontId(uint16_t backgroundFontId, uint16_t highlightFontId);
172
173    /**
174     * @brief Sets the font name and size for the background text.
175     *
176     * @param name Indicates the pointer to the font name to set.
177     * @param size Indicates the font size to set.
178     * @since 1.0
179     * @version 1.0
180     */
181    void SetBackgroundFont(const char* name, uint8_t size);
182
183    /**
184     * @brief Sets the font name and size for the highlighted text.
185     *
186     * @param name Indicates the pointer to the font name to set.
187     * @param size Indicates the font size to set.
188     * @since 1.0
189     * @version 1.0
190     */
191    void SetHighlightFont(const char* name, uint8_t size);
192
193    /**
194     * @brief Obtains the font ID of the background text.
195     *
196     * @return Returns the font ID.
197     * @since 1.0
198     * @version 1.0
199     */
200    uint16_t GetBackgroundFontId() const
201    {
202        return backgroundFontId_;
203    }
204
205    /**
206     * @brief Obtains the font ID of the highlighted text.
207     *
208     * @return Returns the font ID.
209     * @since 1.0
210     * @version 1.0
211     */
212    uint16_t GetHighlightFontId() const
213    {
214        return highlightFontId_;
215    }
216
217    /**
218     * @brief Sets the text color.
219     *
220     * @param backgroundColor Indicates the color of the background text.
221     * @param highlightColor  Indicates the color of the highlighted text.
222     * @since 1.0
223     * @version 1.0
224     */
225    void SetTextColor(ColorType backgroundColor, ColorType highlightColor);
226
227    /**
228     * @brief Obtains the color of the background text.
229     *
230     * @return Returns the color.
231     * @since 1.0
232     * @version 1.0
233     */
234    ColorType GetBackgroundTextColor() const
235    {
236        return backgroundColor_;
237    }
238
239    /**
240     * @brief Obtains the color of the highlighted text.
241     *
242     * @return Returns the color of the highlighted text.
243     * @since 1.0
244     * @version 1.0
245     */
246    ColorType GetHighlightTextColor() const
247    {
248        return highlightColor_;
249    }
250
251    /**
252     * @brief Sets the index of the item currently selected in the picker.
253     *
254     * @param index Indicates the index to set.
255     * @return Returns <b>true</b> if the setting is successful; returns <b>false</b> otherwise.
256     * @since 1.0
257     * @version 1.0
258     */
259    bool SetSelected(uint16_t index);
260
261    /**
262     * @brief Obtains the index of the item currently selected in the picker.
263     *
264     * @return Returns the index.
265     * @since 1.0
266     * @version 1.0
267     */
268    uint16_t GetSelected() const;
269
270    /**
271     * @brief Sets the height of each item in the picker.
272     *
273     * @param height Indicates the height to set.
274     * @since 1.0
275     * @version 1.0
276     */
277    void SetItemHeight(int16_t height);
278
279    /**
280     * @brief Sets the width for this component.
281     *
282     * @param width Indicates the width to set.
283     * @since 1.0
284     * @version 1.0
285     */
286    void SetWidth(int16_t width) override;
287
288    /**
289     * @brief Sets the height for this component.
290     *
291     * @param height Indicates the height to set.
292     * @since 1.0
293     * @version 1.0
294     */
295    void SetHeight(int16_t height) override;
296
297    /**
298     * @brief Sets whether a picker can slide cyclically.
299     *
300     * @param state Specifies whether the picker can slide cyclically. Value <b>true</b> indicates that the picker
301     *              can slide cyclically, and value <b>false</b> indicates that the picker cannot
302     *              slide cyclically. The default value is <b>false</b>.
303     * @since 1.0
304     * @version 1.0
305     */
306    void SetLoopState(bool state);
307
308    /**
309     * @brief Defines the listener used by a picker. This listener is triggered when an item
310     *        is selected after sliding stops.
311     *
312     * @since 1.0
313     * @version 1.0
314     */
315    class SelectedListener : public HeapBase {
316    public:
317        /**
318         * @brief A constructor used to create a <b>SelectedListener</b> instance.
319         *
320         * @since 1.0
321         * @version 1.0
322         */
323        SelectedListener() {}
324
325        /**
326         * @brief A destructor used to delete the <b>SelectedListener</b> instance.
327         *
328         * @since 1.0
329         * @version 1.0
330         */
331        virtual ~SelectedListener() {}
332
333        /**
334         * @brief Called when an item is selected after sliding stops. This function is implemented by applications.
335         *
336         * @param picker Indicates the picker instance.
337         * @since 1.0
338         * @version 1.0
339         */
340        virtual void OnPickerStoped(UIPicker& picker) {}
341        /**
342         * @brief Called when an item is selected during sliding. This function is implemented by applications.
343         *
344         * @param picker Indicates the picker instance.
345         * @since 1.0
346         * @version 1.0
347         */
348        virtual void OnPickerChanged(UIPicker& picker) {}
349    };
350
351    /**
352     * @brief Registers a listener for a selected event.
353     *
354     * @param pickerListener Indicates the listener for a selected event in the picker. For details,
355     *                       see {@link SelectedListener}.
356     *
357     * @since 1.0
358     * @version 1.0
359     */
360    void RegisterSelectedListener(SelectedListener* pickerListener)
361    {
362        pickerListener_ = pickerListener;
363    }
364
365    /**
366     * @brief Sets the text direction.
367     *
368     * @param direct Indicates the text direction to set. For details, see {@link UITextLanguageDirect}.
369     *
370     * @since 1.0
371     * @version 1.0
372     */
373    void SetDirect(UITextLanguageDirect direct);
374
375    /**
376     * @brief Sets the text formatter.
377     *
378     * @param formatter Indicates the pointer to the text formatter. For details, see {@link TextFormatter}.
379     *
380     * @since 1.0
381     * @version 1.0
382     */
383    void SetTextFormatter(TextFormatter* formatter);
384
385    /**
386     * @brief Sets the easing function that specifies a scroll animation after a finger lifts the screen.
387     *
388     * @param func Indicates the easing function to set. The default function is {@link EasingEquation::CubicEaseOut}.
389     *             For details, see {@link EasingEquation}.
390     * @since 5.0
391     * @version 3.0
392     */
393    void SetDragFunc(EasingFunc func)
394    {
395        list_.SetDragFunc(func);
396    }
397
398    /**
399     * @brief Sets the rebound size, which is the distance a knob moves after being released when it reaches the end of
400     *        a scrollbar.
401     *
402     * @param size Indicates the rebound size to set.
403     * @since 5.0
404     * @version 3.0
405     */
406    void SetReboundSize(uint16_t size)
407    {
408        list_.SetReboundSize(size);
409    }
410
411    /**
412     * @brief 设置自动对齐动画时长,单位为毫秒,默认为100毫秒。该功能依赖EnableAutoAlign()方法,自动对齐设置为true情况下才生效。
413     *
414     * @param value 自动对齐动画时长,0表示无动画。
415     * @since 5.0
416     * @version 3.0
417     */
418    void SetAutoAlignTime(uint16_t time)
419    {
420        list_.SetAutoAlignTime(time);
421    }
422
423    /**
424     * @brief Sets the drag acceleration.
425     *
426     * @param value Indicates the drag acceleration to set. The default value is <b>10</b>. A larger drag acceleration
427     *              indicates a higher inertial scroll velocity.
428     * @since 5.0
429     * @version 3.0
430     */
431    void SetDragACCLevel(uint16_t value)
432    {
433        list_.SetDragACCLevel(value);
434    }
435
436    /**
437     * @brief Sets the compensation distance after a finger lifts the screen.
438     *
439     * @param value Indicates the compensation distance to set. The default value is <b>0</b>.
440     * @since 5.0
441     * @version 3.0
442     */
443    void SetSwipeACCLevel(uint16_t value)
444    {
445        list_.SetSwipeACCLevel(value);
446    }
447
448    /**
449     * @brief Sets the blank size for this scroll view.
450     *
451     *
452     * @param value Indicates the blank size to set. The default value is <b>0</b>. Taking a vertical scroll as an
453     *              example, the value <b>0</b> indicates that the head node can only scroll downwards the top of the
454     *              view and the tail node scroll upwards the bottom; the value <b>10</b> indicates that the head node
455     *              can continue scrolling down by 10 pixels after it reaches the top of the view.
456     * @since 5.0
457     * @version 3.0
458     */
459    void SetScrollBlankSize(uint16_t size)
460    {
461        scrollBlankSize_ = size;
462        isScrollBlankSizeSet_ = true;
463        Refresh();
464    }
465
466#if ENABLE_ROTATE_INPUT
467    /**
468     * @brief Requests the focus on the view.
469     *
470     * @since 5.0
471     * @version 3.0
472     */
473    void RequestFocus() override
474    {
475        list_.RequestFocus();
476    }
477
478    /**
479     * @brief Clears the focus on the view.
480     *
481     * @since 5.0
482     * @version 3.0
483     */
484    void ClearFocus() override
485    {
486        list_.ClearFocus();
487    }
488
489    /**
490     * @brief Sets the rotation factor.
491     *
492     * @param factor Indicates the rotation factor to set.
493     * @since 5.0
494     * @version 3.0
495     */
496    void SetRotateFactor(float factor)
497    {
498        list_.SetRotateFactor(factor);
499    }
500
501    /**
502     * @brief Obtains the rotation factor.
503     *
504     * @return Returns the rotation factor.
505     * @since 5.0
506     * @version 3.0
507     */
508    float GetRotateFactor()
509    {
510        return list_.GetRotateFactor();
511    }
512
513    /**
514     * @brief 设置触发惯性滑动的组件大小比例阈值.
515     *
516     * @param threshold 设置触发惯性滑动的比例阈值.
517     *                  旋转表冠结束,如果最后一次旋转位移数值大于组件的宽或高除以threshold,则触发惯性滑动.
518     * @since 6
519     */
520    void SetRotateThrowThreshold(uint8_t threshold)
521    {
522        list_.SetRotateThrowThreshold(threshold);
523    }
524#endif
525
526protected:
527    bool RefreshSelected(uint16_t index);
528    void RefreshList();
529    virtual void ClearList();
530    virtual void Refresh();
531    virtual void InitTextAdapter()
532    {
533        if (textAdapter_ == nullptr) {
534            textAdapter_ = new TextAdapter();
535            if (textAdapter_ == nullptr) {
536                GRAPHIC_LOGE("new TextAdapter fail");
537                return;
538            }
539        }
540    }
541    virtual void ClearTextAdapter();
542
543    bool isWidthSet_ : 1;
544    bool isHeightSet_ : 1;
545    TextAdapter* textAdapter_;
546    uint16_t maxCount_;
547    PickerListScrollListener* listListener_;
548
549private:
550    friend class PickerListScrollListener;
551    bool RefreshValues(const char* value[], uint16_t count);
552    bool RefreshValues(int16_t start, int16_t end);
553
554    bool isScrollBlankSizeSet_ : 1;
555    uint16_t scrollBlankSize_;
556
557    uint16_t backgroundFontId_;
558    uint16_t highlightFontId_;
559    uint8_t backgroundFontSize_;
560    uint8_t highlightFontSize_;
561    char* backgroundFontName_;
562    char* highlightFontName_;
563
564    uint16_t itemsWidth_;
565    uint16_t itemsHeight_;
566    const char** rangeValue_;
567    uint16_t rangeValueCount_;
568    int16_t startValue_;
569    int16_t endValue_;
570    ColorType backgroundColor_;
571    ColorType highlightColor_;
572    List<const char*> dataList_;
573    bool isSetAdaptered_ : 1;
574    UIList list_;
575
576    SelectedListener* pickerListener_;
577    UITextLanguageDirect direct_;
578};
579} // namespace OHOS
580#endif
581