1a3e0fd82Sopenharmony_ci/*
2a3e0fd82Sopenharmony_ci * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3a3e0fd82Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4a3e0fd82Sopenharmony_ci * you may not use this file except in compliance with the License.
5a3e0fd82Sopenharmony_ci * You may obtain a copy of the License at
6a3e0fd82Sopenharmony_ci *
7a3e0fd82Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8a3e0fd82Sopenharmony_ci *
9a3e0fd82Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10a3e0fd82Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11a3e0fd82Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12a3e0fd82Sopenharmony_ci * See the License for the specific language governing permissions and
13a3e0fd82Sopenharmony_ci * limitations under the License.
14a3e0fd82Sopenharmony_ci */
15a3e0fd82Sopenharmony_ci
16a3e0fd82Sopenharmony_ci#include "components/ui_analog_clock.h"
17a3e0fd82Sopenharmony_ci
18a3e0fd82Sopenharmony_ci#include "components/ui_image_view.h"
19a3e0fd82Sopenharmony_ci#include "draw/draw_image.h"
20a3e0fd82Sopenharmony_ci#include "engines/gfx/gfx_engine_manager.h"
21a3e0fd82Sopenharmony_ci#include "gfx_utils/graphic_log.h"
22a3e0fd82Sopenharmony_ci#include "gfx_utils/style.h"
23a3e0fd82Sopenharmony_ci#include "imgdecode/cache_manager.h"
24a3e0fd82Sopenharmony_ci#include "themes/theme.h"
25a3e0fd82Sopenharmony_ci
26a3e0fd82Sopenharmony_cinamespace OHOS {
27a3e0fd82Sopenharmony_ciUIAnalogClock::UIAnalogClock()
28a3e0fd82Sopenharmony_ci{
29a3e0fd82Sopenharmony_ci    touchable_ = true;
30a3e0fd82Sopenharmony_ci}
31a3e0fd82Sopenharmony_ci
32a3e0fd82Sopenharmony_civoid UIAnalogClock::SetHandImage(HandType type, const UIImageView& img, Point position, Point center)
33a3e0fd82Sopenharmony_ci{
34a3e0fd82Sopenharmony_ci    Hand* hand = nullptr;
35a3e0fd82Sopenharmony_ci    if (type == HandType::HOUR_HAND) {
36a3e0fd82Sopenharmony_ci        hand = &hourHand_;
37a3e0fd82Sopenharmony_ci    } else if (type == HandType::MINUTE_HAND) {
38a3e0fd82Sopenharmony_ci        hand = &minuteHand_;
39a3e0fd82Sopenharmony_ci    } else {
40a3e0fd82Sopenharmony_ci        hand = &secondHand_;
41a3e0fd82Sopenharmony_ci    }
42a3e0fd82Sopenharmony_ci
43a3e0fd82Sopenharmony_ci    hand->center_ = center;
44a3e0fd82Sopenharmony_ci    hand->position_ = position;
45a3e0fd82Sopenharmony_ci    hand->initAngle_ = 0;
46a3e0fd82Sopenharmony_ci    hand->preAngle_ = 0;
47a3e0fd82Sopenharmony_ci    hand->nextAngle_ = 0;
48a3e0fd82Sopenharmony_ci    hand->drawtype_ = DrawType::DRAW_IMAGE;
49a3e0fd82Sopenharmony_ci
50a3e0fd82Sopenharmony_ci    if (img.GetSrcType() == IMG_SRC_FILE) {
51a3e0fd82Sopenharmony_ci        CacheEntry entry;
52a3e0fd82Sopenharmony_ci        RetCode ret = CacheManager::GetInstance().Open(img.GetPath(), *style_, entry);
53a3e0fd82Sopenharmony_ci        if (ret != RetCode::OK) {
54a3e0fd82Sopenharmony_ci            return;
55a3e0fd82Sopenharmony_ci        }
56a3e0fd82Sopenharmony_ci        hand->imageInfo_ = entry.GetImageInfo();
57a3e0fd82Sopenharmony_ci    } else {
58a3e0fd82Sopenharmony_ci        if (img.GetImageInfo() == nullptr) {
59a3e0fd82Sopenharmony_ci            hand->imageInfo_.data = nullptr;
60a3e0fd82Sopenharmony_ci            return;
61a3e0fd82Sopenharmony_ci        }
62a3e0fd82Sopenharmony_ci        hand->imageInfo_ = *(img.GetImageInfo());
63a3e0fd82Sopenharmony_ci    }
64a3e0fd82Sopenharmony_ci}
65a3e0fd82Sopenharmony_ci
66a3e0fd82Sopenharmony_civoid UIAnalogClock::SetHandLine(HandType type,
67a3e0fd82Sopenharmony_ci                                Point position,
68a3e0fd82Sopenharmony_ci                                Point center,
69a3e0fd82Sopenharmony_ci                                ColorType color,
70a3e0fd82Sopenharmony_ci                                uint16_t width,
71a3e0fd82Sopenharmony_ci                                uint16_t height,
72a3e0fd82Sopenharmony_ci                                OpacityType opacity)
73a3e0fd82Sopenharmony_ci{
74a3e0fd82Sopenharmony_ci    Hand* hand = nullptr;
75a3e0fd82Sopenharmony_ci    if (type == HandType::HOUR_HAND) {
76a3e0fd82Sopenharmony_ci        hand = &hourHand_;
77a3e0fd82Sopenharmony_ci    } else if (type == HandType::MINUTE_HAND) {
78a3e0fd82Sopenharmony_ci        hand = &minuteHand_;
79a3e0fd82Sopenharmony_ci    } else {
80a3e0fd82Sopenharmony_ci        hand = &secondHand_;
81a3e0fd82Sopenharmony_ci    }
82a3e0fd82Sopenharmony_ci
83a3e0fd82Sopenharmony_ci    hand->color_ = color;
84a3e0fd82Sopenharmony_ci    hand->height_ = height;
85a3e0fd82Sopenharmony_ci    hand->width_ = width;
86a3e0fd82Sopenharmony_ci    hand->position_ = position;
87a3e0fd82Sopenharmony_ci    hand->center_ = center;
88a3e0fd82Sopenharmony_ci    hand->opacity_ = opacity;
89a3e0fd82Sopenharmony_ci    hand->initAngle_ = 0;
90a3e0fd82Sopenharmony_ci    hand->preAngle_ = 0;
91a3e0fd82Sopenharmony_ci    hand->nextAngle_ = 0;
92a3e0fd82Sopenharmony_ci    hand->drawtype_ = DrawType::DRAW_LINE;
93a3e0fd82Sopenharmony_ci}
94a3e0fd82Sopenharmony_ci
95a3e0fd82Sopenharmony_ciPoint UIAnalogClock::GetHandRotateCenter(HandType type) const
96a3e0fd82Sopenharmony_ci{
97a3e0fd82Sopenharmony_ci    if (type == HandType::HOUR_HAND) {
98a3e0fd82Sopenharmony_ci        return hourHand_.center_;
99a3e0fd82Sopenharmony_ci    } else if (type == HandType::MINUTE_HAND) {
100a3e0fd82Sopenharmony_ci        return minuteHand_.center_;
101a3e0fd82Sopenharmony_ci    } else {
102a3e0fd82Sopenharmony_ci        return secondHand_.center_;
103a3e0fd82Sopenharmony_ci    }
104a3e0fd82Sopenharmony_ci}
105a3e0fd82Sopenharmony_ci
106a3e0fd82Sopenharmony_ciPoint UIAnalogClock::GetHandPosition(HandType type) const
107a3e0fd82Sopenharmony_ci{
108a3e0fd82Sopenharmony_ci    if (type == HandType::HOUR_HAND) {
109a3e0fd82Sopenharmony_ci        return hourHand_.position_;
110a3e0fd82Sopenharmony_ci    } else if (type == HandType::MINUTE_HAND) {
111a3e0fd82Sopenharmony_ci        return minuteHand_.position_;
112a3e0fd82Sopenharmony_ci    } else {
113a3e0fd82Sopenharmony_ci        return secondHand_.position_;
114a3e0fd82Sopenharmony_ci    }
115a3e0fd82Sopenharmony_ci}
116a3e0fd82Sopenharmony_ci
117a3e0fd82Sopenharmony_ciuint16_t UIAnalogClock::GetHandInitAngle(HandType type) const
118a3e0fd82Sopenharmony_ci{
119a3e0fd82Sopenharmony_ci    if (type == HandType::HOUR_HAND) {
120a3e0fd82Sopenharmony_ci        return hourHand_.initAngle_;
121a3e0fd82Sopenharmony_ci    } else if (type == HandType::MINUTE_HAND) {
122a3e0fd82Sopenharmony_ci        return minuteHand_.initAngle_;
123a3e0fd82Sopenharmony_ci    } else {
124a3e0fd82Sopenharmony_ci        return secondHand_.initAngle_;
125a3e0fd82Sopenharmony_ci    }
126a3e0fd82Sopenharmony_ci}
127a3e0fd82Sopenharmony_ci
128a3e0fd82Sopenharmony_ciuint16_t UIAnalogClock::GetHandCurrentAngle(HandType type) const
129a3e0fd82Sopenharmony_ci{
130a3e0fd82Sopenharmony_ci    if (type == HandType::HOUR_HAND) {
131a3e0fd82Sopenharmony_ci        return hourHand_.nextAngle_;
132a3e0fd82Sopenharmony_ci    } else if (type == HandType::MINUTE_HAND) {
133a3e0fd82Sopenharmony_ci        return minuteHand_.nextAngle_;
134a3e0fd82Sopenharmony_ci    } else {
135a3e0fd82Sopenharmony_ci        return secondHand_.nextAngle_;
136a3e0fd82Sopenharmony_ci    }
137a3e0fd82Sopenharmony_ci}
138a3e0fd82Sopenharmony_ci
139a3e0fd82Sopenharmony_civoid UIAnalogClock::SetInitTime24Hour(uint8_t hour, uint8_t minute, uint8_t second)
140a3e0fd82Sopenharmony_ci{
141a3e0fd82Sopenharmony_ci    currentHour_ = hour % ONE_DAY_IN_HOUR;
142a3e0fd82Sopenharmony_ci    currentMinute_ = minute % ONE_HOUR_IN_MINUTE;
143a3e0fd82Sopenharmony_ci    currentSecond_ = second % ONE_MINUTE_IN_SECOND;
144a3e0fd82Sopenharmony_ci
145a3e0fd82Sopenharmony_ci    hourHand_.initAngle_ = ConvertHandValueToAngle(currentHour_, HALF_DAY_IN_HOUR, currentMinute_, ONE_HOUR_IN_MINUTE);
146a3e0fd82Sopenharmony_ci    hourHand_.preAngle_ = hourHand_.initAngle_;
147a3e0fd82Sopenharmony_ci    hourHand_.nextAngle_ = hourHand_.initAngle_;
148a3e0fd82Sopenharmony_ci
149a3e0fd82Sopenharmony_ci    minuteHand_.initAngle_ =
150a3e0fd82Sopenharmony_ci        ConvertHandValueToAngle(currentMinute_, ONE_HOUR_IN_MINUTE, currentSecond_, ONE_MINUTE_IN_SECOND);
151a3e0fd82Sopenharmony_ci    minuteHand_.preAngle_ = minuteHand_.initAngle_;
152a3e0fd82Sopenharmony_ci    minuteHand_.nextAngle_ = minuteHand_.initAngle_;
153a3e0fd82Sopenharmony_ci
154a3e0fd82Sopenharmony_ci    secondHand_.initAngle_ = ConvertHandValueToAngle(currentSecond_, ONE_MINUTE_IN_SECOND);
155a3e0fd82Sopenharmony_ci    secondHand_.preAngle_ = secondHand_.initAngle_;
156a3e0fd82Sopenharmony_ci    secondHand_.nextAngle_ = secondHand_.initAngle_;
157a3e0fd82Sopenharmony_ci
158a3e0fd82Sopenharmony_ci    UpdateClock(true);
159a3e0fd82Sopenharmony_ci    Invalidate();
160a3e0fd82Sopenharmony_ci}
161a3e0fd82Sopenharmony_ci
162a3e0fd82Sopenharmony_civoid UIAnalogClock::SetInitTime12Hour(uint8_t hour, uint8_t minute, uint8_t second, bool am)
163a3e0fd82Sopenharmony_ci{
164a3e0fd82Sopenharmony_ci    SetInitTime24Hour((hour % HALF_DAY_IN_HOUR) + (am ? 0 : HALF_DAY_IN_HOUR), minute, second);
165a3e0fd82Sopenharmony_ci}
166a3e0fd82Sopenharmony_ci
167a3e0fd82Sopenharmony_ciuint16_t UIAnalogClock::ConvertHandValueToAngle(uint8_t handValue,
168a3e0fd82Sopenharmony_ci                                                uint8_t range,
169a3e0fd82Sopenharmony_ci                                                uint8_t secondHandValue,
170a3e0fd82Sopenharmony_ci                                                uint8_t ratio) const
171a3e0fd82Sopenharmony_ci{
172a3e0fd82Sopenharmony_ci    if ((range == 0) || (ratio == 0)) {
173a3e0fd82Sopenharmony_ci        GRAPHIC_LOGW("UIAnalogClock::ConvertHandValueToAngle Invalid range or ratio\n");
174a3e0fd82Sopenharmony_ci        return 0;
175a3e0fd82Sopenharmony_ci    }
176a3e0fd82Sopenharmony_ci    /*
177a3e0fd82Sopenharmony_ci     * Example: calculate the angle of hour hand
178a3e0fd82Sopenharmony_ci     * Assume that the time is 5: 30, then range is 12, radio is 60
179a3e0fd82Sopenharmony_ci     * angle is [(5 * 60  + 30) / (12 * 60)] * 360
180a3e0fd82Sopenharmony_ci     */
181a3e0fd82Sopenharmony_ci    uint32_t degree = (static_cast<uint16_t>(handValue) * ratio + secondHandValue);
182a3e0fd82Sopenharmony_ci    degree = static_cast<uint32_t>(CIRCLE_IN_DEGREE * degree / (static_cast<uint16_t>(range) * ratio));
183a3e0fd82Sopenharmony_ci
184a3e0fd82Sopenharmony_ci    return static_cast<uint16_t>(degree % CIRCLE_IN_DEGREE);
185a3e0fd82Sopenharmony_ci}
186a3e0fd82Sopenharmony_ci
187a3e0fd82Sopenharmony_ciuint16_t UIAnalogClock::ConvertHandValueToAngle(uint8_t handValue, uint8_t range) const
188a3e0fd82Sopenharmony_ci{
189a3e0fd82Sopenharmony_ci    if (range == 0) {
190a3e0fd82Sopenharmony_ci        GRAPHIC_LOGW("UIAnalogClock::ConvertHandValueToAngle Invalid range or ratio\n");
191a3e0fd82Sopenharmony_ci        return 0;
192a3e0fd82Sopenharmony_ci    }
193a3e0fd82Sopenharmony_ci    /*
194a3e0fd82Sopenharmony_ci     * Example: calculate the angle of second hand without millisecond handle
195a3e0fd82Sopenharmony_ci     * Assume that the time is 5:30:30, then range is 60
196a3e0fd82Sopenharmony_ci     * angle is (30 / 60) * 360
197a3e0fd82Sopenharmony_ci     */
198a3e0fd82Sopenharmony_ci    return (static_cast<uint16_t>(handValue) * CIRCLE_IN_DEGREE / range);
199a3e0fd82Sopenharmony_ci}
200a3e0fd82Sopenharmony_ci
201a3e0fd82Sopenharmony_civoid UIAnalogClock::UpdateClock(bool clockInit)
202a3e0fd82Sopenharmony_ci{
203a3e0fd82Sopenharmony_ci    hourHand_.nextAngle_ = ConvertHandValueToAngle(currentHour_, HALF_DAY_IN_HOUR, currentMinute_, ONE_HOUR_IN_MINUTE);
204a3e0fd82Sopenharmony_ci    minuteHand_.nextAngle_ =
205a3e0fd82Sopenharmony_ci        ConvertHandValueToAngle(currentMinute_, ONE_HOUR_IN_MINUTE, currentSecond_, ONE_MINUTE_IN_SECOND);
206a3e0fd82Sopenharmony_ci    secondHand_.nextAngle_ = ConvertHandValueToAngle(currentSecond_, ONE_MINUTE_IN_SECOND);
207a3e0fd82Sopenharmony_ci
208a3e0fd82Sopenharmony_ci    Rect rect = GetRect();
209a3e0fd82Sopenharmony_ci    CalculateRedrawArea(rect, hourHand_, clockInit);
210a3e0fd82Sopenharmony_ci    CalculateRedrawArea(rect, minuteHand_, clockInit);
211a3e0fd82Sopenharmony_ci    if (GetWorkMode() == WorkMode::NORMAL) {
212a3e0fd82Sopenharmony_ci        CalculateRedrawArea(rect, secondHand_, clockInit);
213a3e0fd82Sopenharmony_ci    }
214a3e0fd82Sopenharmony_ci}
215a3e0fd82Sopenharmony_ci
216a3e0fd82Sopenharmony_civoid UIAnalogClock::OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea)
217a3e0fd82Sopenharmony_ci{
218a3e0fd82Sopenharmony_ci    BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, GetRect(), invalidatedArea, *style_, opaScale_);
219a3e0fd82Sopenharmony_ci}
220a3e0fd82Sopenharmony_ci
221a3e0fd82Sopenharmony_civoid UIAnalogClock::OnPostDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea)
222a3e0fd82Sopenharmony_ci{
223a3e0fd82Sopenharmony_ci    UpdateClock(true);
224a3e0fd82Sopenharmony_ci    Rect current = GetOrigRect();
225a3e0fd82Sopenharmony_ci    DrawHand(gfxDstBuffer, current, invalidatedArea, hourHand_);
226a3e0fd82Sopenharmony_ci    DrawHand(gfxDstBuffer, current, invalidatedArea, minuteHand_);
227a3e0fd82Sopenharmony_ci    if (GetWorkMode() == WorkMode::NORMAL) {
228a3e0fd82Sopenharmony_ci        DrawHand(gfxDstBuffer, current, invalidatedArea, secondHand_);
229a3e0fd82Sopenharmony_ci    }
230a3e0fd82Sopenharmony_ci    UIView::OnPostDraw(gfxDstBuffer, invalidatedArea);
231a3e0fd82Sopenharmony_ci}
232a3e0fd82Sopenharmony_ci
233a3e0fd82Sopenharmony_civoid UIAnalogClock::CalculateRedrawArea(const Rect& current, Hand& hand, bool clockInit)
234a3e0fd82Sopenharmony_ci{
235a3e0fd82Sopenharmony_ci    /*
236a3e0fd82Sopenharmony_ci     * Use the current image as an independent rectangular area
237a3e0fd82Sopenharmony_ci     * to calculate the coordinate conversion coefficient.
238a3e0fd82Sopenharmony_ci     */
239a3e0fd82Sopenharmony_ci    int16_t imgWidth = hand.imageInfo_.header.width;
240a3e0fd82Sopenharmony_ci    int16_t imgHeight = hand.imageInfo_.header.height;
241a3e0fd82Sopenharmony_ci
242a3e0fd82Sopenharmony_ci    int16_t left = hand.position_.x + current.GetLeft();
243a3e0fd82Sopenharmony_ci    int16_t right = left + imgWidth - 1;
244a3e0fd82Sopenharmony_ci    int16_t top = hand.position_.y + current.GetTop();
245a3e0fd82Sopenharmony_ci    int16_t bottom = top + imgHeight - 1;
246a3e0fd82Sopenharmony_ci    Rect imgRect(left, top, right, bottom);
247a3e0fd82Sopenharmony_ci    TransformMap backwardMap(imgRect);
248a3e0fd82Sopenharmony_ci    Vector2<float> pivot;
249a3e0fd82Sopenharmony_ci    pivot.x_ = hand.center_.x;
250a3e0fd82Sopenharmony_ci    pivot.y_ = hand.center_.y;
251a3e0fd82Sopenharmony_ci
252a3e0fd82Sopenharmony_ci    /* Rotate the specified angle,  */
253a3e0fd82Sopenharmony_ci    backwardMap.Rotate(hand.nextAngle_ - hand.initAngle_, pivot);
254a3e0fd82Sopenharmony_ci    Rect redraw = hand.target_;
255a3e0fd82Sopenharmony_ci    hand.target_ = backwardMap.GetBoxRect();
256a3e0fd82Sopenharmony_ci    hand.trans_ = backwardMap;
257a3e0fd82Sopenharmony_ci    hand.preAngle_ = hand.nextAngle_;
258a3e0fd82Sopenharmony_ci    if (!clockInit) {
259a3e0fd82Sopenharmony_ci        /* Prevent old images from being residued */
260a3e0fd82Sopenharmony_ci        redraw.Join(redraw, hand.target_);
261a3e0fd82Sopenharmony_ci        InvalidateRect(redraw);
262a3e0fd82Sopenharmony_ci    }
263a3e0fd82Sopenharmony_ci}
264a3e0fd82Sopenharmony_ci
265a3e0fd82Sopenharmony_civoid UIAnalogClock::DrawHand(BufferInfo& gfxDstBuffer, const Rect& current, const Rect& invalidatedArea, Hand& hand)
266a3e0fd82Sopenharmony_ci{
267a3e0fd82Sopenharmony_ci    if (hand.drawtype_ == DrawType::DRAW_IMAGE) {
268a3e0fd82Sopenharmony_ci        DrawHandImage(gfxDstBuffer, current, invalidatedArea, hand);
269a3e0fd82Sopenharmony_ci    } else {
270a3e0fd82Sopenharmony_ci        DrawHandLine(gfxDstBuffer, invalidatedArea, hand);
271a3e0fd82Sopenharmony_ci    }
272a3e0fd82Sopenharmony_ci}
273a3e0fd82Sopenharmony_ci
274a3e0fd82Sopenharmony_civoid UIAnalogClock::DrawHandImage(BufferInfo& gfxDstBuffer,
275a3e0fd82Sopenharmony_ci                                  const Rect& current,
276a3e0fd82Sopenharmony_ci                                  const Rect& invalidatedArea,
277a3e0fd82Sopenharmony_ci                                  Hand& hand)
278a3e0fd82Sopenharmony_ci{
279a3e0fd82Sopenharmony_ci    if (hand.imageInfo_.data == nullptr) {
280a3e0fd82Sopenharmony_ci        return;
281a3e0fd82Sopenharmony_ci    }
282a3e0fd82Sopenharmony_ci    uint8_t pxSize = DrawUtils::GetPxSizeByColorMode(hand.imageInfo_.header.colorMode);
283a3e0fd82Sopenharmony_ci    TransformDataInfo imageTranDataInfo = {hand.imageInfo_.header, hand.imageInfo_.data, pxSize, BlurLevel::LEVEL0,
284a3e0fd82Sopenharmony_ci                                           TransformAlgorithm::BILINEAR};
285a3e0fd82Sopenharmony_ci    BaseGfxEngine::GetInstance()->DrawTransform(gfxDstBuffer, invalidatedArea, {0, 0}, Color::Black(), opaScale_,
286a3e0fd82Sopenharmony_ci                                                hand.trans_, imageTranDataInfo);
287a3e0fd82Sopenharmony_ci}
288a3e0fd82Sopenharmony_ci
289a3e0fd82Sopenharmony_civoid UIAnalogClock::DrawHandLine(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea, Hand& hand)
290a3e0fd82Sopenharmony_ci{
291a3e0fd82Sopenharmony_ci    float sinma = Sin(hand.nextAngle_);
292a3e0fd82Sopenharmony_ci    float cosma = Sin(hand.nextAngle_ + THREE_QUARTER_IN_DEGREE);
293a3e0fd82Sopenharmony_ci    int32_t handLength = hand.height_;
294a3e0fd82Sopenharmony_ci    Rect rect = GetRect();
295a3e0fd82Sopenharmony_ci    Point start;
296a3e0fd82Sopenharmony_ci    Point end;
297a3e0fd82Sopenharmony_ci    Point curCenter;
298a3e0fd82Sopenharmony_ci    curCenter.x = hand.position_.x + hand.center_.x + rect.GetLeft();
299a3e0fd82Sopenharmony_ci    curCenter.y = hand.position_.y + hand.center_.y + rect.GetTop();
300a3e0fd82Sopenharmony_ci
301a3e0fd82Sopenharmony_ci    int32_t startToCenterLength = hand.center_.y;
302a3e0fd82Sopenharmony_ci
303a3e0fd82Sopenharmony_ci    int32_t xPointLength = static_cast<int32_t>(startToCenterLength * sinma);
304a3e0fd82Sopenharmony_ci    int32_t yPointLength = static_cast<int32_t>(startToCenterLength * cosma);
305a3e0fd82Sopenharmony_ci
306a3e0fd82Sopenharmony_ci    start.x = xPointLength + curCenter.x;
307a3e0fd82Sopenharmony_ci    start.y = yPointLength + curCenter.y;
308a3e0fd82Sopenharmony_ci
309a3e0fd82Sopenharmony_ci    /*
310a3e0fd82Sopenharmony_ci     * @ startToCenterLength: means the length between StartPoint and CenterPoint.
311a3e0fd82Sopenharmony_ci     * @ handlength: means the hand height.
312a3e0fd82Sopenharmony_ci     * @ xlength: means X-axis length relative to the center point
313a3e0fd82Sopenharmony_ci     * @ ylength: means Y-axis length relative to the center point
314a3e0fd82Sopenharmony_ci     */
315a3e0fd82Sopenharmony_ci    int32_t xlength = static_cast<int32_t>((startToCenterLength - handLength) * sinma);
316a3e0fd82Sopenharmony_ci    int32_t ylength = static_cast<int32_t>((startToCenterLength - handLength) * cosma);
317a3e0fd82Sopenharmony_ci    end.x = xlength + curCenter.x;
318a3e0fd82Sopenharmony_ci    end.y = ylength + curCenter.y;
319a3e0fd82Sopenharmony_ci
320a3e0fd82Sopenharmony_ci    BaseGfxEngine::GetInstance()->DrawLine(gfxDstBuffer, start, end, invalidatedArea, hand.width_, hand.color_,
321a3e0fd82Sopenharmony_ci                                           hand.opacity_);
322a3e0fd82Sopenharmony_ci}
323a3e0fd82Sopenharmony_ci
324a3e0fd82Sopenharmony_civoid UIAnalogClock::SetWorkMode(WorkMode newMode)
325a3e0fd82Sopenharmony_ci{
326a3e0fd82Sopenharmony_ci    WorkMode oldMode = mode_;
327a3e0fd82Sopenharmony_ci
328a3e0fd82Sopenharmony_ci    if (oldMode != newMode) {
329a3e0fd82Sopenharmony_ci        /*
330a3e0fd82Sopenharmony_ci         * After entering the alwayson mode, all child controls are no longer drawn,
331a3e0fd82Sopenharmony_ci         * making the simplest analog clock.
332a3e0fd82Sopenharmony_ci         */
333a3e0fd82Sopenharmony_ci        isViewGroup_ = (newMode == ALWAYS_ON) ? false : true;
334a3e0fd82Sopenharmony_ci        mode_ = newMode;
335a3e0fd82Sopenharmony_ci        Invalidate();
336a3e0fd82Sopenharmony_ci    }
337a3e0fd82Sopenharmony_ci}
338a3e0fd82Sopenharmony_ci} // namespace OHOS
339