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_slider.h"
17a3e0fd82Sopenharmony_ci
18a3e0fd82Sopenharmony_ci#include "common/image.h"
19a3e0fd82Sopenharmony_ci#include "dock/focus_manager.h"
20a3e0fd82Sopenharmony_ci#include "dock/vibrator_manager.h"
21a3e0fd82Sopenharmony_ci#include "draw/draw_image.h"
22a3e0fd82Sopenharmony_ci#include "engines/gfx/gfx_engine_manager.h"
23a3e0fd82Sopenharmony_ci#include "gfx_utils/graphic_log.h"
24a3e0fd82Sopenharmony_ci#include "imgdecode/cache_manager.h"
25a3e0fd82Sopenharmony_ci#include "themes/theme_manager.h"
26a3e0fd82Sopenharmony_ci
27a3e0fd82Sopenharmony_cinamespace OHOS {
28a3e0fd82Sopenharmony_ciUISlider::UISlider() : knobWidth_(0), knobStyleAllocFlag_(false), knobImage_(nullptr), listener_(nullptr)
29a3e0fd82Sopenharmony_ci{
30a3e0fd82Sopenharmony_ci    touchable_ = true;
31a3e0fd82Sopenharmony_ci    draggable_ = true;
32a3e0fd82Sopenharmony_ci    dragParentInstead_ = false;
33a3e0fd82Sopenharmony_ci#if ENABLE_FOCUS_MANAGER
34a3e0fd82Sopenharmony_ci    focusable_ = true;
35a3e0fd82Sopenharmony_ci#endif
36a3e0fd82Sopenharmony_ci#if ENABLE_ROTATE_INPUT
37a3e0fd82Sopenharmony_ci    rotateFactor_ = DEFAULT_SLIDER_ROTATE_FACTOR;
38a3e0fd82Sopenharmony_ci    cachedRotation_ = 0;
39a3e0fd82Sopenharmony_ci#endif
40a3e0fd82Sopenharmony_ci
41a3e0fd82Sopenharmony_ci    Theme* theme = ThemeManager::GetInstance().GetCurrent();
42a3e0fd82Sopenharmony_ci    if (theme != nullptr) {
43a3e0fd82Sopenharmony_ci        knobStyle_ = &(theme->GetSliderKnobStyle());
44a3e0fd82Sopenharmony_ci    } else {
45a3e0fd82Sopenharmony_ci        knobStyle_ = &(StyleDefault::GetSliderKnobStyle());
46a3e0fd82Sopenharmony_ci    }
47a3e0fd82Sopenharmony_ci}
48a3e0fd82Sopenharmony_ci
49a3e0fd82Sopenharmony_ciUISlider::~UISlider()
50a3e0fd82Sopenharmony_ci{
51a3e0fd82Sopenharmony_ci    if (knobImage_ != nullptr) {
52a3e0fd82Sopenharmony_ci        delete knobImage_;
53a3e0fd82Sopenharmony_ci        knobImage_ = nullptr;
54a3e0fd82Sopenharmony_ci    }
55a3e0fd82Sopenharmony_ci
56a3e0fd82Sopenharmony_ci    if (knobStyleAllocFlag_) {
57a3e0fd82Sopenharmony_ci        delete knobStyle_;
58a3e0fd82Sopenharmony_ci        knobStyle_ = nullptr;
59a3e0fd82Sopenharmony_ci        knobStyleAllocFlag_ = false;
60a3e0fd82Sopenharmony_ci    }
61a3e0fd82Sopenharmony_ci}
62a3e0fd82Sopenharmony_ci
63a3e0fd82Sopenharmony_civoid UISlider::SetKnobStyle(const Style& style)
64a3e0fd82Sopenharmony_ci{
65a3e0fd82Sopenharmony_ci    if (!knobStyleAllocFlag_) {
66a3e0fd82Sopenharmony_ci        knobStyle_ = new Style;
67a3e0fd82Sopenharmony_ci        if (knobStyle_ == nullptr) {
68a3e0fd82Sopenharmony_ci            GRAPHIC_LOGE("new Style fail");
69a3e0fd82Sopenharmony_ci            return;
70a3e0fd82Sopenharmony_ci        }
71a3e0fd82Sopenharmony_ci        knobStyleAllocFlag_ = true;
72a3e0fd82Sopenharmony_ci    }
73a3e0fd82Sopenharmony_ci    *knobStyle_ = style;
74a3e0fd82Sopenharmony_ci}
75a3e0fd82Sopenharmony_ci
76a3e0fd82Sopenharmony_civoid UISlider::SetKnobStyle(uint8_t key, int64_t value)
77a3e0fd82Sopenharmony_ci{
78a3e0fd82Sopenharmony_ci    if (!knobStyleAllocFlag_) {
79a3e0fd82Sopenharmony_ci        knobStyle_ = new Style(*knobStyle_);
80a3e0fd82Sopenharmony_ci        if (knobStyle_ == nullptr) {
81a3e0fd82Sopenharmony_ci            GRAPHIC_LOGE("new Style fail");
82a3e0fd82Sopenharmony_ci            return;
83a3e0fd82Sopenharmony_ci        }
84a3e0fd82Sopenharmony_ci        knobStyleAllocFlag_ = true;
85a3e0fd82Sopenharmony_ci    }
86a3e0fd82Sopenharmony_ci    knobStyle_->SetStyle(key, value);
87a3e0fd82Sopenharmony_ci}
88a3e0fd82Sopenharmony_ci
89a3e0fd82Sopenharmony_ciconst Style& UISlider::GetKnobStyle() const
90a3e0fd82Sopenharmony_ci{
91a3e0fd82Sopenharmony_ci    return *knobStyle_;
92a3e0fd82Sopenharmony_ci}
93a3e0fd82Sopenharmony_ci
94a3e0fd82Sopenharmony_ciint64_t UISlider::GetKnobStyle(uint8_t key) const
95a3e0fd82Sopenharmony_ci{
96a3e0fd82Sopenharmony_ci    return knobStyle_->GetStyle(key);
97a3e0fd82Sopenharmony_ci}
98a3e0fd82Sopenharmony_ci
99a3e0fd82Sopenharmony_civoid UISlider::SetKnobImage(const ImageInfo* knobImage)
100a3e0fd82Sopenharmony_ci{
101a3e0fd82Sopenharmony_ci    if (!InitImage()) {
102a3e0fd82Sopenharmony_ci        return;
103a3e0fd82Sopenharmony_ci    }
104a3e0fd82Sopenharmony_ci    knobImage_->SetSrc(knobImage);
105a3e0fd82Sopenharmony_ci}
106a3e0fd82Sopenharmony_ci
107a3e0fd82Sopenharmony_civoid UISlider::SetKnobImage(const char* knobImage)
108a3e0fd82Sopenharmony_ci{
109a3e0fd82Sopenharmony_ci    if (!InitImage()) {
110a3e0fd82Sopenharmony_ci        return;
111a3e0fd82Sopenharmony_ci    }
112a3e0fd82Sopenharmony_ci    knobImage_->SetSrc(knobImage);
113a3e0fd82Sopenharmony_ci}
114a3e0fd82Sopenharmony_ci
115a3e0fd82Sopenharmony_civoid UISlider::DrawKnob(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea, const Rect& foregroundRect)
116a3e0fd82Sopenharmony_ci{
117a3e0fd82Sopenharmony_ci    int16_t halfKnobWidth = GetKnobWidth() / 2; // 2: half
118a3e0fd82Sopenharmony_ci    int16_t offset;
119a3e0fd82Sopenharmony_ci    Rect knobBar;
120a3e0fd82Sopenharmony_ci    switch (direction_) {
121a3e0fd82Sopenharmony_ci        case Direction::DIR_LEFT_TO_RIGHT: {
122a3e0fd82Sopenharmony_ci            offset = (knobWidth_ - progressHeight_) / 2; // 2: half
123a3e0fd82Sopenharmony_ci            knobBar.SetRect(foregroundRect.GetRight() - halfKnobWidth, foregroundRect.GetTop() - offset,
124a3e0fd82Sopenharmony_ci                            foregroundRect.GetRight() + halfKnobWidth, foregroundRect.GetBottom() + offset);
125a3e0fd82Sopenharmony_ci            break;
126a3e0fd82Sopenharmony_ci        }
127a3e0fd82Sopenharmony_ci        case Direction::DIR_RIGHT_TO_LEFT: {
128a3e0fd82Sopenharmony_ci            offset = (knobWidth_ - progressHeight_) / 2; // 2: half
129a3e0fd82Sopenharmony_ci            knobBar.SetRect(foregroundRect.GetLeft() - halfKnobWidth, foregroundRect.GetTop() - offset,
130a3e0fd82Sopenharmony_ci                            foregroundRect.GetLeft() + halfKnobWidth, foregroundRect.GetBottom() + offset);
131a3e0fd82Sopenharmony_ci            break;
132a3e0fd82Sopenharmony_ci        }
133a3e0fd82Sopenharmony_ci        case Direction::DIR_BOTTOM_TO_TOP: {
134a3e0fd82Sopenharmony_ci            offset = (knobWidth_ - progressWidth_) / 2; // 2: half
135a3e0fd82Sopenharmony_ci            knobBar.SetRect(foregroundRect.GetLeft() - offset, foregroundRect.GetTop() - halfKnobWidth,
136a3e0fd82Sopenharmony_ci                            foregroundRect.GetRight() + offset, foregroundRect.GetTop() + halfKnobWidth);
137a3e0fd82Sopenharmony_ci            break;
138a3e0fd82Sopenharmony_ci        }
139a3e0fd82Sopenharmony_ci        case Direction::DIR_TOP_TO_BOTTOM: {
140a3e0fd82Sopenharmony_ci            offset = (knobWidth_ - progressWidth_) / 2; // 2: half
141a3e0fd82Sopenharmony_ci            knobBar.SetRect(foregroundRect.GetLeft() - offset, foregroundRect.GetBottom() - halfKnobWidth,
142a3e0fd82Sopenharmony_ci                            foregroundRect.GetRight() + offset, foregroundRect.GetBottom() + halfKnobWidth);
143a3e0fd82Sopenharmony_ci            break;
144a3e0fd82Sopenharmony_ci        }
145a3e0fd82Sopenharmony_ci        default: {
146a3e0fd82Sopenharmony_ci            GRAPHIC_LOGW("UISlider::DrawKnob Direction error!\n");
147a3e0fd82Sopenharmony_ci        }
148a3e0fd82Sopenharmony_ci    }
149a3e0fd82Sopenharmony_ci    DrawValidRect(gfxDstBuffer, knobImage_, knobBar, invalidatedArea, *knobStyle_, 0);
150a3e0fd82Sopenharmony_ci}
151a3e0fd82Sopenharmony_ci
152a3e0fd82Sopenharmony_cibool UISlider::InitImage()
153a3e0fd82Sopenharmony_ci{
154a3e0fd82Sopenharmony_ci    if (!UIAbstractProgress::InitImage()) {
155a3e0fd82Sopenharmony_ci        return false;
156a3e0fd82Sopenharmony_ci    }
157a3e0fd82Sopenharmony_ci    if (knobImage_ == nullptr) {
158a3e0fd82Sopenharmony_ci        knobImage_ = new Image();
159a3e0fd82Sopenharmony_ci        if (knobImage_ == nullptr) {
160a3e0fd82Sopenharmony_ci            GRAPHIC_LOGE("new Image fail");
161a3e0fd82Sopenharmony_ci            return false;
162a3e0fd82Sopenharmony_ci        }
163a3e0fd82Sopenharmony_ci    }
164a3e0fd82Sopenharmony_ci    return true;
165a3e0fd82Sopenharmony_ci}
166a3e0fd82Sopenharmony_ci
167a3e0fd82Sopenharmony_civoid UISlider::SetImage(const ImageInfo* backgroundImage, const ImageInfo* foregroundImage)
168a3e0fd82Sopenharmony_ci{
169a3e0fd82Sopenharmony_ci    if (!InitImage()) {
170a3e0fd82Sopenharmony_ci        return;
171a3e0fd82Sopenharmony_ci    }
172a3e0fd82Sopenharmony_ci    backgroundImage_->SetSrc(backgroundImage);
173a3e0fd82Sopenharmony_ci    foregroundImage_->SetSrc(foregroundImage);
174a3e0fd82Sopenharmony_ci}
175a3e0fd82Sopenharmony_ci
176a3e0fd82Sopenharmony_civoid UISlider::SetImage(const char* backgroundImage, const char* foregroundImage)
177a3e0fd82Sopenharmony_ci{
178a3e0fd82Sopenharmony_ci    if (!InitImage()) {
179a3e0fd82Sopenharmony_ci        return;
180a3e0fd82Sopenharmony_ci    }
181a3e0fd82Sopenharmony_ci    backgroundImage_->SetSrc(backgroundImage);
182a3e0fd82Sopenharmony_ci    foregroundImage_->SetSrc(foregroundImage);
183a3e0fd82Sopenharmony_ci}
184a3e0fd82Sopenharmony_ci
185a3e0fd82Sopenharmony_civoid UISlider::DrawForeground(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea, Rect& coords)
186a3e0fd82Sopenharmony_ci{
187a3e0fd82Sopenharmony_ci    Point startPoint;
188a3e0fd82Sopenharmony_ci    int16_t progressWidth;
189a3e0fd82Sopenharmony_ci    int16_t progressHeight;
190a3e0fd82Sopenharmony_ci    uint16_t radius;
191a3e0fd82Sopenharmony_ci    GetBackgroundParam(startPoint, progressWidth, progressHeight, radius, *foregroundStyle_);
192a3e0fd82Sopenharmony_ci
193a3e0fd82Sopenharmony_ci    int16_t left;
194a3e0fd82Sopenharmony_ci    int16_t right;
195a3e0fd82Sopenharmony_ci    int16_t top;
196a3e0fd82Sopenharmony_ci    int16_t bottom;
197a3e0fd82Sopenharmony_ci    int16_t length;
198a3e0fd82Sopenharmony_ci    Rect foregroundRect;
199a3e0fd82Sopenharmony_ci
200a3e0fd82Sopenharmony_ci    switch (direction_) {
201a3e0fd82Sopenharmony_ci        case Direction::DIR_LEFT_TO_RIGHT: {
202a3e0fd82Sopenharmony_ci            length = GetCurrentPos(progressWidth_ + 1);
203a3e0fd82Sopenharmony_ci            foregroundRect.SetRect(startPoint.x, startPoint.y, startPoint.x + progressWidth - 1,
204a3e0fd82Sopenharmony_ci                                   startPoint.y + progressHeight_ - 1);
205a3e0fd82Sopenharmony_ci
206a3e0fd82Sopenharmony_ci            left = startPoint.x - radius - 1;
207a3e0fd82Sopenharmony_ci            right = left + length;
208a3e0fd82Sopenharmony_ci            coords.SetRect(left, startPoint.y, right, startPoint.y + progressHeight_ - 1);
209a3e0fd82Sopenharmony_ci            break;
210a3e0fd82Sopenharmony_ci        }
211a3e0fd82Sopenharmony_ci        case Direction::DIR_RIGHT_TO_LEFT: {
212a3e0fd82Sopenharmony_ci            length = GetCurrentPos(progressWidth_ + 1);
213a3e0fd82Sopenharmony_ci            foregroundRect.SetRect(startPoint.x, startPoint.y, startPoint.x + progressWidth - 1,
214a3e0fd82Sopenharmony_ci                                   startPoint.y + progressHeight_ - 1);
215a3e0fd82Sopenharmony_ci
216a3e0fd82Sopenharmony_ci            right = startPoint.x + progressWidth + radius + 1;
217a3e0fd82Sopenharmony_ci            left = right - length;
218a3e0fd82Sopenharmony_ci            coords.SetRect(left, startPoint.y, right, startPoint.y + progressHeight_ - 1);
219a3e0fd82Sopenharmony_ci            break;
220a3e0fd82Sopenharmony_ci        }
221a3e0fd82Sopenharmony_ci        case Direction::DIR_TOP_TO_BOTTOM: {
222a3e0fd82Sopenharmony_ci            length = GetCurrentPos(progressHeight_ + 1);
223a3e0fd82Sopenharmony_ci            foregroundRect.SetRect(startPoint.x, startPoint.y, startPoint.x + progressWidth_ - 1,
224a3e0fd82Sopenharmony_ci                                   startPoint.y + progressHeight - 1);
225a3e0fd82Sopenharmony_ci
226a3e0fd82Sopenharmony_ci            top = startPoint.y - radius - 1;
227a3e0fd82Sopenharmony_ci            bottom = top + length;
228a3e0fd82Sopenharmony_ci            coords.SetRect(startPoint.x, top, startPoint.x + progressWidth_ - 1, bottom);
229a3e0fd82Sopenharmony_ci            break;
230a3e0fd82Sopenharmony_ci        }
231a3e0fd82Sopenharmony_ci        case Direction::DIR_BOTTOM_TO_TOP: {
232a3e0fd82Sopenharmony_ci            length = GetCurrentPos(progressHeight_ + 1);
233a3e0fd82Sopenharmony_ci            foregroundRect.SetRect(startPoint.x, startPoint.y, startPoint.x + progressWidth_ - 1,
234a3e0fd82Sopenharmony_ci                                   startPoint.y + progressHeight - 1);
235a3e0fd82Sopenharmony_ci
236a3e0fd82Sopenharmony_ci            bottom = startPoint.y + progressHeight + radius + 1;
237a3e0fd82Sopenharmony_ci            top = bottom - length;
238a3e0fd82Sopenharmony_ci            coords.SetRect(startPoint.x, top, startPoint.x + progressWidth_ - 1, bottom);
239a3e0fd82Sopenharmony_ci            break;
240a3e0fd82Sopenharmony_ci        }
241a3e0fd82Sopenharmony_ci        default: {
242a3e0fd82Sopenharmony_ci            GRAPHIC_LOGE("UISlider: DrawForeground direction Err!\n");
243a3e0fd82Sopenharmony_ci            return;
244a3e0fd82Sopenharmony_ci        }
245a3e0fd82Sopenharmony_ci    }
246a3e0fd82Sopenharmony_ci    if (coords.Intersect(coords, invalidatedArea)) {
247a3e0fd82Sopenharmony_ci        DrawValidRect(gfxDstBuffer, foregroundImage_, foregroundRect, coords, *foregroundStyle_, radius);
248a3e0fd82Sopenharmony_ci    }
249a3e0fd82Sopenharmony_ci}
250a3e0fd82Sopenharmony_ci
251a3e0fd82Sopenharmony_civoid UISlider::OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea)
252a3e0fd82Sopenharmony_ci{
253a3e0fd82Sopenharmony_ci    BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, GetOrigRect(), invalidatedArea, *style_, opaScale_);
254a3e0fd82Sopenharmony_ci
255a3e0fd82Sopenharmony_ci    Rect trunc(invalidatedArea);
256a3e0fd82Sopenharmony_ci    if (trunc.Intersect(trunc, GetOrigRect())) {
257a3e0fd82Sopenharmony_ci        DrawBackground(gfxDstBuffer, trunc);
258a3e0fd82Sopenharmony_ci        Rect foregroundRect;
259a3e0fd82Sopenharmony_ci        DrawForeground(gfxDstBuffer, trunc, foregroundRect);
260a3e0fd82Sopenharmony_ci        DrawKnob(gfxDstBuffer, trunc, foregroundRect);
261a3e0fd82Sopenharmony_ci    }
262a3e0fd82Sopenharmony_ci}
263a3e0fd82Sopenharmony_ci
264a3e0fd82Sopenharmony_ciint32_t UISlider::CalculateCurrentValue(int16_t length, int16_t totalLength)
265a3e0fd82Sopenharmony_ci{
266a3e0fd82Sopenharmony_ci    if (totalLength != 0) {
267a3e0fd82Sopenharmony_ci        return static_cast<int32_t>(rangeMin_ + (static_cast<int64_t>(rangeMax_) - rangeMin_) * length / totalLength);
268a3e0fd82Sopenharmony_ci    }
269a3e0fd82Sopenharmony_ci    return 0;
270a3e0fd82Sopenharmony_ci}
271a3e0fd82Sopenharmony_ci
272a3e0fd82Sopenharmony_ciint32_t UISlider::UpdateCurrentValue(const Point& knobPosition)
273a3e0fd82Sopenharmony_ci{
274a3e0fd82Sopenharmony_ci    Point startPoint;
275a3e0fd82Sopenharmony_ci    Rect rect = GetOrigRect();
276a3e0fd82Sopenharmony_ci    // 2: Half of the gap
277a3e0fd82Sopenharmony_ci    startPoint.x = rect.GetLeft() + style_->borderWidth_ + style_->paddingLeft_ + (GetWidth() - progressWidth_) / 2;
278a3e0fd82Sopenharmony_ci    // 2: Half of the gap
279a3e0fd82Sopenharmony_ci    startPoint.y = rect.GetTop() + style_->borderWidth_ + style_->paddingTop_ + (GetHeight() - progressHeight_) / 2;
280a3e0fd82Sopenharmony_ci
281a3e0fd82Sopenharmony_ci    int32_t value = curValue_;
282a3e0fd82Sopenharmony_ci    switch (direction_) {
283a3e0fd82Sopenharmony_ci        case Direction::DIR_LEFT_TO_RIGHT:
284a3e0fd82Sopenharmony_ci            if (knobPosition.x <= startPoint.x) {
285a3e0fd82Sopenharmony_ci                value = rangeMin_;
286a3e0fd82Sopenharmony_ci            } else if (knobPosition.x >= startPoint.x + progressWidth_) {
287a3e0fd82Sopenharmony_ci                value = rangeMax_;
288a3e0fd82Sopenharmony_ci            } else {
289a3e0fd82Sopenharmony_ci                value = CalculateCurrentValue(knobPosition.x - startPoint.x, progressWidth_);
290a3e0fd82Sopenharmony_ci            }
291a3e0fd82Sopenharmony_ci            break;
292a3e0fd82Sopenharmony_ci        case Direction::DIR_RIGHT_TO_LEFT:
293a3e0fd82Sopenharmony_ci            if (knobPosition.x <= startPoint.x) {
294a3e0fd82Sopenharmony_ci                value = rangeMax_;
295a3e0fd82Sopenharmony_ci            } else if (knobPosition.x >= startPoint.x + progressWidth_) {
296a3e0fd82Sopenharmony_ci                value = rangeMin_;
297a3e0fd82Sopenharmony_ci            } else {
298a3e0fd82Sopenharmony_ci                value = CalculateCurrentValue(startPoint.x + progressWidth_ - knobPosition.x, progressWidth_);
299a3e0fd82Sopenharmony_ci            }
300a3e0fd82Sopenharmony_ci            break;
301a3e0fd82Sopenharmony_ci        case Direction::DIR_BOTTOM_TO_TOP:
302a3e0fd82Sopenharmony_ci            if (knobPosition.y <= startPoint.y) {
303a3e0fd82Sopenharmony_ci                value = rangeMax_;
304a3e0fd82Sopenharmony_ci            } else if (knobPosition.y >= startPoint.y + progressHeight_) {
305a3e0fd82Sopenharmony_ci                value = rangeMin_;
306a3e0fd82Sopenharmony_ci            } else {
307a3e0fd82Sopenharmony_ci                value = CalculateCurrentValue(startPoint.y + progressHeight_ - knobPosition.y, progressHeight_);
308a3e0fd82Sopenharmony_ci            }
309a3e0fd82Sopenharmony_ci            break;
310a3e0fd82Sopenharmony_ci        case Direction::DIR_TOP_TO_BOTTOM:
311a3e0fd82Sopenharmony_ci            if (knobPosition.y <= startPoint.y) {
312a3e0fd82Sopenharmony_ci                value = rangeMin_;
313a3e0fd82Sopenharmony_ci            } else if (knobPosition.y >= startPoint.y + progressHeight_) {
314a3e0fd82Sopenharmony_ci                value = rangeMax_;
315a3e0fd82Sopenharmony_ci            } else {
316a3e0fd82Sopenharmony_ci                value = CalculateCurrentValue(knobPosition.y - startPoint.y, progressHeight_);
317a3e0fd82Sopenharmony_ci            }
318a3e0fd82Sopenharmony_ci            break;
319a3e0fd82Sopenharmony_ci        default:
320a3e0fd82Sopenharmony_ci            GRAPHIC_LOGW("UISlider::UpdateCurrentValue Direction error!\n");
321a3e0fd82Sopenharmony_ci    }
322a3e0fd82Sopenharmony_ci    SetValue(value);
323a3e0fd82Sopenharmony_ci    return value;
324a3e0fd82Sopenharmony_ci}
325a3e0fd82Sopenharmony_ci
326a3e0fd82Sopenharmony_cibool UISlider::OnClickEvent(const ClickEvent& event)
327a3e0fd82Sopenharmony_ci{
328a3e0fd82Sopenharmony_ci    Point knobPosition = event.GetCurrentPos();
329a3e0fd82Sopenharmony_ci    int32_t value = UpdateCurrentValue(knobPosition);
330a3e0fd82Sopenharmony_ci    if (listener_ != nullptr) {
331a3e0fd82Sopenharmony_ci        listener_->OnChange(value);
332a3e0fd82Sopenharmony_ci    }
333a3e0fd82Sopenharmony_ci    bool ret = UIView::OnClickEvent(event);
334a3e0fd82Sopenharmony_ci    Invalidate();
335a3e0fd82Sopenharmony_ci    return ret;
336a3e0fd82Sopenharmony_ci}
337a3e0fd82Sopenharmony_ci
338a3e0fd82Sopenharmony_cibool UISlider::OnDragEvent(const DragEvent& event)
339a3e0fd82Sopenharmony_ci{
340a3e0fd82Sopenharmony_ci    Point knobPosition = event.GetCurrentPos();
341a3e0fd82Sopenharmony_ci    int32_t value = UpdateCurrentValue(knobPosition);
342a3e0fd82Sopenharmony_ci    if (listener_ != nullptr) {
343a3e0fd82Sopenharmony_ci        listener_->OnChange(value);
344a3e0fd82Sopenharmony_ci    }
345a3e0fd82Sopenharmony_ci    Invalidate();
346a3e0fd82Sopenharmony_ci    return UIView::OnDragEvent(event);
347a3e0fd82Sopenharmony_ci}
348a3e0fd82Sopenharmony_ci
349a3e0fd82Sopenharmony_cibool UISlider::OnDragEndEvent(const DragEvent& event)
350a3e0fd82Sopenharmony_ci{
351a3e0fd82Sopenharmony_ci    Point knobPosition = event.GetCurrentPos();
352a3e0fd82Sopenharmony_ci    int32_t value = UpdateCurrentValue(knobPosition);
353a3e0fd82Sopenharmony_ci    if (listener_ != nullptr) {
354a3e0fd82Sopenharmony_ci        listener_->OnChange(value);
355a3e0fd82Sopenharmony_ci        listener_->OnRelease(value);
356a3e0fd82Sopenharmony_ci    }
357a3e0fd82Sopenharmony_ci    Invalidate();
358a3e0fd82Sopenharmony_ci    return UIView::OnDragEndEvent(event);
359a3e0fd82Sopenharmony_ci}
360a3e0fd82Sopenharmony_ci
361a3e0fd82Sopenharmony_ci#if ENABLE_ROTATE_INPUT
362a3e0fd82Sopenharmony_cibool UISlider::OnRotateEvent(const RotateEvent& event)
363a3e0fd82Sopenharmony_ci{
364a3e0fd82Sopenharmony_ci    int32_t realRotation = 0;
365a3e0fd82Sopenharmony_ci    cachedRotation_ += event.GetRotate() * rotateFactor_;
366a3e0fd82Sopenharmony_ci    realRotation = static_cast<int32_t>(cachedRotation_);
367a3e0fd82Sopenharmony_ci    if (realRotation == 0) {
368a3e0fd82Sopenharmony_ci        return UIView::OnRotateEvent(event);
369a3e0fd82Sopenharmony_ci    }
370a3e0fd82Sopenharmony_ci    cachedRotation_ = 0;
371a3e0fd82Sopenharmony_ci#if ENABLE_VIBRATOR
372a3e0fd82Sopenharmony_ci    int32_t lastValue = curValue_;
373a3e0fd82Sopenharmony_ci#endif
374a3e0fd82Sopenharmony_ci    SetValue(curValue_ + realRotation);
375a3e0fd82Sopenharmony_ci    if (listener_ != nullptr) {
376a3e0fd82Sopenharmony_ci        listener_->OnChange(curValue_);
377a3e0fd82Sopenharmony_ci    }
378a3e0fd82Sopenharmony_ci#if ENABLE_VIBRATOR
379a3e0fd82Sopenharmony_ci    VibratorFunc vibratorFunc = VibratorManager::GetInstance()->GetVibratorFunc();
380a3e0fd82Sopenharmony_ci    if (vibratorFunc != nullptr && lastValue != curValue_) {
381a3e0fd82Sopenharmony_ci        if (curValue_ == rangeMin_ || curValue_ == rangeMax_) {
382a3e0fd82Sopenharmony_ci            GRAPHIC_LOGI("UISlider::OnRotateEvent calls TYPE_THREE vibrator");
383a3e0fd82Sopenharmony_ci            vibratorFunc(VibratorType::VIBRATOR_TYPE_THREE);
384a3e0fd82Sopenharmony_ci        } else {
385a3e0fd82Sopenharmony_ci            int32_t changedValue = MATH_ABS(curValue_ - lastValue);
386a3e0fd82Sopenharmony_ci            for (int32_t i = 0; i < changedValue; i++) {
387a3e0fd82Sopenharmony_ci                GRAPHIC_LOGI("UISlider::OnRotateEvent calls TYPE_TWO vibrator");
388a3e0fd82Sopenharmony_ci                vibratorFunc(VibratorType::VIBRATOR_TYPE_TWO);
389a3e0fd82Sopenharmony_ci            }
390a3e0fd82Sopenharmony_ci        }
391a3e0fd82Sopenharmony_ci    }
392a3e0fd82Sopenharmony_ci#endif
393a3e0fd82Sopenharmony_ci    return UIView::OnRotateEvent(event);
394a3e0fd82Sopenharmony_ci}
395a3e0fd82Sopenharmony_ci
396a3e0fd82Sopenharmony_cibool UISlider::OnRotateEndEvent(const RotateEvent& event)
397a3e0fd82Sopenharmony_ci{
398a3e0fd82Sopenharmony_ci    cachedRotation_ = 0;
399a3e0fd82Sopenharmony_ci    return UIView::OnRotateEndEvent(event);
400a3e0fd82Sopenharmony_ci}
401a3e0fd82Sopenharmony_ci#endif
402a3e0fd82Sopenharmony_ci} // namespace OHOS
403