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_arc_label.h
28 *
29 * @brief Defines the attributes of an arc label.
30 *
31 * The attributes include the center and radius of an arc, angle range, and text orientation.
32 *
33 * @since 1.0
34 * @version 1.0
35 */
36
37#ifndef GRAPHIC_LITE_UI_ARC_LABEL_H
38#define GRAPHIC_LITE_UI_ARC_LABEL_H
39
40#include "animator/animator.h"
41#include "common/text.h"
42#include "components/ui_view.h"
43
44namespace OHOS {
45class ArcLabelScrollListener : public HeapBase {
46public:
47    virtual void Finish() = 0;
48};
49
50/**
51 * @brief Defines functions related to an arc label.
52 *
53 * @since 1.0
54 * @version 1.0
55 */
56class UIArcLabel : public UIView {
57public:
58    /**
59     * @brief A default constructor used to create a <b>UIArcLabel</b> instance.
60     *
61     * @since 1.0
62     * @version 1.0
63     */
64    UIArcLabel();
65
66    /**
67     * @brief A destructor used to delete the <b>UIArcLabel</b> instance.
68     *
69     * @since 1.0
70     * @version 1.0
71     */
72    virtual ~UIArcLabel();
73
74    /**
75     * @brief Obtains the view type.
76     *
77     * @return Returns <b>UI_ARC_LABEL</b>, as defined in {link UIViewType}.
78     * @since 1.0
79     * @version 1.0
80     */
81    UIViewType GetViewType() const override
82    {
83        return UI_ARC_LABEL;
84    }
85
86    /**
87     * @brief Obtains the width of this arc text.
88     *
89     * @return Returns the width of this arc text.
90     * @since 1.0
91     * @version 1.0
92     */
93    int16_t GetWidth() override
94    {
95        ReMeasure();
96        return UIView::GetWidth();
97    }
98
99    /**
100     * @brief Obtains the height of this arc text.
101     *
102     * @return Returns the height of this arc text.
103     * @since 1.0
104     * @version 1.0
105     */
106    int16_t GetHeight() override
107    {
108        ReMeasure();
109        return UIView::GetHeight();
110    }
111
112    /**
113     * @brief Sets the view style.
114     * @param style Indicates the view style.
115     * @since 1.0
116     * @version 1.0
117     */
118    void SetStyle(Style& style) override
119    {
120        UIView::SetStyle(style);
121    }
122
123    /**
124     * @brief Sets a style.
125     *
126     * @param key Indicates the key of the style to set.
127     * @param value Indicates the value matching the key.
128     * @since 1.0
129     * @version 1.0
130     */
131    void SetStyle(uint8_t key, int64_t value) override;
132
133    /**
134     * @brief Sets the text content for this arc label.
135     *
136     * @param text Indicates the pointer to the text content.
137     * @since 1.0
138     * @version 1.0
139     */
140    void SetText(const char* text);
141
142    /**
143     * @brief Obtains the text of this arc label.
144     *
145     * @return Returns the text.
146     * @since 1.0
147     * @version 1.0
148     */
149    const char* GetText() const;
150
151    /**
152     * @brief Sets the alignment mode for this text.
153     *
154     * @param horizontalAlign Indicates the horizontal alignment mode to set,
155     *                        which can be {@link TEXT_ALIGNMENT_LEFT},
156     *                        {@link TEXT_ALIGNMENT_CENTER}, or {@link TEXT_ALIGNMENT_RIGHT}.
157     * @since 1.0
158     * @version 1.0
159     */
160    void SetAlign(UITextLanguageAlignment horizontalAlign);
161
162    /**
163     * @brief Obtains the horizontal alignment mode.
164     *
165     * @return Returns the horizontal alignment mode.
166     * @since 1.0
167     * @version 1.0
168     */
169    UITextLanguageAlignment GetHorAlign();
170
171    /**
172     * @brief Obtains the direction of this text.
173     *
174     * @return Returns the text direction, as defined in {@link UITextLanguageDirect}.
175     * @since 1.0
176     * @version 1.0
177     */
178    UITextLanguageDirect GetDirect();
179
180    /**
181     * @brief Sets the font ID for this arc label.
182     *
183     * @param fontId Indicates the font ID composed of font name and size.
184     * @since 1.0
185     * @version 1.0
186     */
187    void SetFontId(uint16_t fontId);
188
189    /**
190     * @brief Obtains the font ID composed of font name and size.
191     *
192     * @return Returns the front ID of this arc label.
193     * @since 1.0
194     * @version 1.0
195     */
196    uint16_t GetFontId();
197
198    /**
199     * @brief Sets the font for this arc label.
200     *
201     * @param name Indicates the pointer to the font name.
202     * @param size Indicates the font size to set.
203     * @since 1.0
204     * @version 1.0
205     */
206    void SetFont(const char* name, uint8_t size);
207
208    /**
209     * @brief Sets the center position for this arc text.
210     *
211     * @param x Indicates the x-coordinate to set.
212     * @param y Indicates the y-coordinate to set.
213     * @since 1.0
214     * @version 1.0
215     */
216    void SetArcTextCenter(int16_t x, int16_t y)
217    {
218        if ((arcCenter_.x != x) || (arcCenter_.y != y)) {
219            arcCenter_.x = x;
220            arcCenter_.y = y;
221            RefreshArcLabel();
222        }
223    }
224
225    /**
226     * @brief Obtains the center position of this arc text.
227     *
228     * @return Returns the center position of this arc text.
229     * @since 1.0
230     * @version 1.0
231     */
232    Point GetArcTextCenter() const
233    {
234        return arcCenter_;
235    }
236
237    /**
238     * @brief Sets the radius for this arc text.
239     *
240     * @param radius Indicates the radius to set.
241     * @since 1.0
242     * @version 1.0
243     */
244    void SetArcTextRadius(uint16_t radius)
245    {
246        if (radius_ != radius) {
247            radius_ = radius;
248            RefreshArcLabel();
249        }
250    }
251
252    /**
253     * @brief Obtains the radius of this arc text.
254     *
255     * @return Returns the radius of this arc text.
256     * @since 1.0
257     * @version 1.0
258     */
259    uint16_t GetArcTextRadius() const
260    {
261        return radius_;
262    }
263
264    /**
265     * @brief Sets the start angle and end angle for this arc text.
266     *
267     * The angle in 12 o'clock direction is 0 degrees, and the value increases clockwise.
268     * The text direction is clockwise when the end angle is greater than the start angle, and the text direction is
269     * counterclockwise otherwise.
270     *
271     * @param startAngle Indicates the start angle to set.
272     * @param endAngle Indicates the end angle to set.
273     * @since 1.0
274     * @version 1.0
275     */
276    void SetArcTextAngle(int16_t startAngle, int16_t endAngle)
277    {
278        if ((startAngle_ != startAngle) || (endAngle_ != endAngle)) {
279            startAngle_ = startAngle;
280            endAngle_ = endAngle;
281            RefreshArcLabel();
282        }
283    }
284
285    /**
286     * @brief Obtains the start angle of this arc text.
287     *
288     * @return Returns the start angle of this arc text.
289     * @since 1.0
290     * @version 1.0
291     */
292    int16_t GetArcTextStartAngle() const
293    {
294        return startAngle_;
295    }
296
297    /**
298     * @brief Obtains the end angle of this arc text.
299     *
300     * @return Returns the end angle of this arc text.
301     * @since 1.0
302     * @version 1.0
303     */
304    int16_t GetArcTextEndAngle() const
305    {
306        return endAngle_;
307    }
308
309    /**
310     * @brief Sets the orientation for this arc text.
311     *
312     * @param orientation Indicates the text orientation to set.
313     * @since 1.0
314     * @version 1.0
315     */
316    void SetArcTextOrientation(TextOrientation orientation)
317    {
318        if (orientation_ != orientation) {
319            orientation_ = orientation;
320            RefreshArcLabel();
321        }
322    }
323
324    /**
325     * @brief Obtains the orientation of this arc text.
326     *
327     * @return Returns the orientation of this arc text.
328     * @since 1.0
329     * @version 1.0
330     */
331    TextOrientation GetArcTextOrientation() const
332    {
333        return orientation_;
334    }
335
336    /**
337     * @brief Is it compatible with older versions.
338     *
339     * @param compatibilityMode Indicates compatible with older versions.
340     */
341    void SetCompatibilityMode(bool compatibilityMode)
342    {
343        if (compatibilityMode_ != compatibilityMode) {
344            compatibilityMode_ = compatibilityMode;
345            RefreshArcLabel();
346        }
347    }
348
349    /**
350     * @brief Draws an arc text.
351     *
352     * @param invalidatedArea Indicates the area to draw.
353     * @since 1.0
354     * @version 1.0
355     */
356    void OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea) override;
357
358    /**
359     * @brief Start animation.
360     *
361     */
362    void Start();
363
364    /**
365     * @brief Stop animation.
366     *
367     */
368    void Stop();
369
370    /**
371     * @brief Sets the number of cycles.
372     *
373     * @param rollCount Indicates number of cycles.
374     */
375    void SetRollCount(const uint16_t rollCount);
376
377    /**
378     * @brief Register a listener that contains a callback to be invoked scroll state change.
379     *
380     * @param scrollListener Indicates the listener to register.
381     */
382    void RegisterScrollListener(ArcLabelScrollListener* scrollListener);
383
384    /**
385     * @brief Set animation speed.
386     *
387     * @param speed Indicates the scroll speed to set.
388     */
389    void SetRollSpeed(const uint16_t speed);
390
391    /**
392     * @brief Obtains the scroll speed for this arclabel.
393     *
394     * @return Returns the scroll speed.
395     */
396    uint16_t GetRollSpeed() const;
397
398    void ReMeasure() override;
399protected:
400    Text* arcLabelText_;
401    bool compatibilityMode_;
402    float offsetAngle_;
403    ArcTextInfo arcTextInfo_;
404    bool needRefresh_;
405    bool hasAnimator_;
406
407    virtual void InitArcLabelText()
408    {
409        if (arcLabelText_ == nullptr) {
410            arcLabelText_ = new Text();
411            if (arcLabelText_ == nullptr) {
412                GRAPHIC_LOGE("new Text fail");
413                return;
414            }
415        }
416    }
417    void RefreshArcLabel();
418
419    virtual void DrawArcText(BufferInfo& gfxDstBuffer,
420                             const Rect& mask,
421                             OpacityType opaScale,
422                             ArcTextInfo arcTextInfo,
423                             TextOrientation orientation);
424
425    virtual Rect GetArcTextRect(const char* text,
426                                uint16_t fontId,
427                                uint8_t fontSize,
428                                const Point& arcCenter,
429                                int16_t letterSpace,
430                                TextOrientation orientation,
431                                const ArcTextInfo& arcTextInfo);
432
433    virtual uint32_t GetLineEnd(int16_t maxLength);
434
435    virtual uint16_t GetArcLength();
436private:
437    friend class ArcLabelAnimator;
438    void MeasureArcTextInfo();
439    void OnMeasureArcTextInfo(const uint16_t arcAngle, const uint16_t letterHeight);
440
441    Point textSize_;
442    uint16_t radius_;
443    int16_t startAngle_;
444    int16_t endAngle_;
445    Point arcCenter_;
446    TextOrientation orientation_;
447    struct {
448        Animator* animator;
449        ArcLabelScrollListener* scrollListener;
450        uint16_t speed;
451        uint16_t rollCount;
452        float secondLapOffsetAngle_;
453    } animator_;
454};
455} // namespace OHOS
456#endif // GRAPHIC_LITE_UI_ARC_LABEL_H
457