mirror of
https://github.com/openharmony/graphic_ui.git
synced 2026-06-30 23:17:56 -04:00
299 lines
9.2 KiB
C++
Executable File
299 lines
9.2 KiB
C++
Executable File
/*
|
|
* Copyright (c) 2020-2021 Huawei Device Co., Ltd.
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "components/ui_slider.h"
|
|
#include "common/image.h"
|
|
#include "dock/focus_manager.h"
|
|
#include "draw/draw_image.h"
|
|
#include "draw/draw_rect.h"
|
|
#include "graphic_log.h"
|
|
#include "imgdecode/cache_manager.h"
|
|
#include "themes/theme_manager.h"
|
|
|
|
namespace OHOS {
|
|
UISlider::UISlider()
|
|
: knobWidth_(0), knobWidthSetFlag_(false), knobStyleAllocFlag_(false), knobImage_(nullptr), listener_(nullptr)
|
|
{
|
|
touchable_ = true;
|
|
draggable_ = true;
|
|
dragParentInstead_ = false;
|
|
Theme* theme = ThemeManager::GetInstance().GetCurrent();
|
|
if (theme != nullptr) {
|
|
knobStyle_ = &(theme->GetSliderKnobStyle());
|
|
} else {
|
|
knobStyle_ = &(StyleDefault::GetSliderKnobStyle());
|
|
}
|
|
}
|
|
|
|
UISlider::~UISlider()
|
|
{
|
|
if (knobImage_ != nullptr) {
|
|
delete knobImage_;
|
|
knobImage_ = nullptr;
|
|
}
|
|
|
|
if (knobStyleAllocFlag_) {
|
|
delete knobStyle_;
|
|
knobStyle_ = nullptr;
|
|
knobStyleAllocFlag_ = false;
|
|
}
|
|
}
|
|
|
|
void UISlider::SetKnobStyle(const Style& style)
|
|
{
|
|
if (!knobStyleAllocFlag_) {
|
|
knobStyle_ = new Style;
|
|
if (knobStyle_ == nullptr) {
|
|
GRAPHIC_LOGE("new Style fail");
|
|
return;
|
|
}
|
|
knobStyleAllocFlag_ = true;
|
|
}
|
|
*knobStyle_ = style;
|
|
}
|
|
|
|
void UISlider::SetKnobStyle(uint8_t key, int64_t value)
|
|
{
|
|
if (!knobStyleAllocFlag_) {
|
|
knobStyle_ = new Style(*knobStyle_);
|
|
if (knobStyle_ == nullptr) {
|
|
GRAPHIC_LOGE("new Style fail");
|
|
return;
|
|
}
|
|
knobStyleAllocFlag_ = true;
|
|
}
|
|
knobStyle_->SetStyle(key, value);
|
|
}
|
|
|
|
const Style& UISlider::GetKnobStyle() const
|
|
{
|
|
return *knobStyle_;
|
|
}
|
|
|
|
int64_t UISlider::GetKnobStyle(uint8_t key) const
|
|
{
|
|
return knobStyle_->GetStyle(key);
|
|
}
|
|
|
|
int32_t UISlider::CalculateCurrentValue(int16_t length, int16_t totalLength)
|
|
{
|
|
if (totalLength != 0) {
|
|
return static_cast<int32_t>(rangeMin_ + (static_cast<int64_t>(rangeMax_) - rangeMin_) * length / totalLength);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int32_t UISlider::UpdateCurrentValue(const Point& knobPosition)
|
|
{
|
|
Point startPoint;
|
|
Rect rect = GetOrigRect();
|
|
startPoint.x = rect.GetLeft() + style_->borderWidth_ + style_->paddingLeft_;
|
|
startPoint.y = rect.GetTop() + style_->borderWidth_ + style_->paddingTop_;
|
|
|
|
int32_t value = curValue_;
|
|
switch (direction_) {
|
|
case Direction::DIR_LEFT_TO_RIGHT:
|
|
if (knobPosition.x <= startPoint.x) {
|
|
value = rangeMin_;
|
|
} else if (knobPosition.x >= startPoint.x + progressWidth_) {
|
|
value = rangeMax_;
|
|
} else {
|
|
value = CalculateCurrentValue(knobPosition.x - startPoint.x, progressWidth_);
|
|
}
|
|
break;
|
|
case Direction::DIR_RIGHT_TO_LEFT:
|
|
if (knobPosition.x <= startPoint.x) {
|
|
value = rangeMax_;
|
|
} else if (knobPosition.x >= startPoint.x + progressWidth_) {
|
|
value = rangeMin_;
|
|
} else {
|
|
value = CalculateCurrentValue(startPoint.x + progressWidth_ - knobPosition.x, progressWidth_);
|
|
}
|
|
break;
|
|
case Direction::DIR_BOTTOM_TO_TOP:
|
|
if (knobPosition.y <= startPoint.y) {
|
|
value = rangeMax_;
|
|
} else if (knobPosition.y >= startPoint.y + progressHeight_) {
|
|
value = rangeMin_;
|
|
} else {
|
|
value = CalculateCurrentValue(startPoint.y + progressHeight_ - knobPosition.y, progressHeight_);
|
|
}
|
|
break;
|
|
case Direction::DIR_TOP_TO_BOTTOM:
|
|
if (knobPosition.y <= startPoint.y) {
|
|
value = rangeMin_;
|
|
} else if (knobPosition.y >= startPoint.y + progressHeight_) {
|
|
value = rangeMax_;
|
|
} else {
|
|
value = CalculateCurrentValue(knobPosition.y - startPoint.y, progressHeight_);
|
|
}
|
|
break;
|
|
default:
|
|
GRAPHIC_LOGW("UISlider::UpdateCurrentValue Direction error!\n");
|
|
}
|
|
SetValue(value);
|
|
return value;
|
|
}
|
|
|
|
bool UISlider::OnClickEvent(const ClickEvent& event)
|
|
{
|
|
Point knobPosition = event.GetCurrentPos();
|
|
int32_t value = UpdateCurrentValue(knobPosition);
|
|
if (listener_ != nullptr) {
|
|
listener_->OnChange(value);
|
|
}
|
|
bool ret = UIView::OnClickEvent(event);
|
|
Invalidate();
|
|
return ret;
|
|
}
|
|
|
|
bool UISlider::OnDragEvent(const DragEvent& event)
|
|
{
|
|
Point knobPosition = event.GetCurrentPos();
|
|
int32_t value = UpdateCurrentValue(knobPosition);
|
|
if (listener_ != nullptr) {
|
|
listener_->OnChange(value);
|
|
}
|
|
Invalidate();
|
|
return UIView::OnDragEvent(event);
|
|
}
|
|
|
|
bool UISlider::OnDragEndEvent(const DragEvent& event)
|
|
{
|
|
Point knobPosition = event.GetCurrentPos();
|
|
int32_t value = UpdateCurrentValue(knobPosition);
|
|
if (listener_ != nullptr) {
|
|
listener_->OnChange(value);
|
|
listener_->OnRelease(value);
|
|
}
|
|
Invalidate();
|
|
return UIView::OnDragEndEvent(event);
|
|
}
|
|
|
|
#if ENABLE_ROTATE_INPUT
|
|
bool UISlider::OnRotateEvent(const RotateEvent& event)
|
|
{
|
|
if (event.GetRotate() == 0) {
|
|
return false;
|
|
}
|
|
int32_t tmp = event.GetRotate() * rotateFactor_;
|
|
SetValue(curValue_ + tmp);
|
|
#if ENABLE_MOTOR
|
|
MotorFunc motorFunc = FocusManager::GetInstance()->GetMotorFunc();
|
|
if (motorFunc != nullptr) {
|
|
motorFunc(MotorType::MOTOR_TYPE_TWO);
|
|
}
|
|
#endif
|
|
return UIView::OnRotateEvent(event);
|
|
}
|
|
#endif
|
|
|
|
int16_t UISlider::GetKnobWidth()
|
|
{
|
|
if (!knobWidthSetFlag_) {
|
|
if ((direction_ == Direction::DIR_LEFT_TO_RIGHT) || (direction_ == Direction::DIR_RIGHT_TO_LEFT)) {
|
|
knobWidth_ = progressHeight_;
|
|
} else {
|
|
knobWidth_ = progressWidth_;
|
|
}
|
|
}
|
|
return knobWidth_;
|
|
}
|
|
|
|
void UISlider::SetImage(const ImageInfo* backgroundImage, const ImageInfo* foregroundImage, const ImageInfo* knobImage)
|
|
{
|
|
if (!InitImage()) {
|
|
return;
|
|
}
|
|
backgroundImage_->SetSrc(backgroundImage);
|
|
foregroundImage_->SetSrc(foregroundImage);
|
|
knobImage_->SetSrc(knobImage);
|
|
}
|
|
|
|
void UISlider::SetImage(const char* backgroundImage, const char* foregroundImage, const char* knobImage)
|
|
{
|
|
if (!InitImage()) {
|
|
return;
|
|
}
|
|
backgroundImage_->SetSrc(backgroundImage);
|
|
foregroundImage_->SetSrc(foregroundImage);
|
|
knobImage_->SetSrc(knobImage);
|
|
}
|
|
|
|
void UISlider::DrawKnob(const Rect& invalidatedArea, const Rect& foregroundRect)
|
|
{
|
|
int16_t halfKnobWidth = GetKnobWidth() >> 1;
|
|
int16_t offset;
|
|
Rect knobBar;
|
|
switch (direction_) {
|
|
case Direction::DIR_LEFT_TO_RIGHT: {
|
|
offset = (knobWidth_ - progressHeight_) >> 1;
|
|
knobBar.SetRect(foregroundRect.GetRight() - halfKnobWidth, foregroundRect.GetTop() - offset,
|
|
foregroundRect.GetRight() + halfKnobWidth, foregroundRect.GetBottom() + offset);
|
|
break;
|
|
}
|
|
case Direction::DIR_RIGHT_TO_LEFT: {
|
|
offset = (knobWidth_ - progressHeight_) >> 1;
|
|
knobBar.SetRect(foregroundRect.GetLeft() - halfKnobWidth, foregroundRect.GetTop() - offset,
|
|
foregroundRect.GetLeft() + halfKnobWidth, foregroundRect.GetBottom() + offset);
|
|
break;
|
|
}
|
|
case Direction::DIR_BOTTOM_TO_TOP: {
|
|
offset = (knobWidth_ - progressWidth_) >> 1;
|
|
knobBar.SetRect(foregroundRect.GetLeft() - offset, foregroundRect.GetTop() - halfKnobWidth,
|
|
foregroundRect.GetRight() + offset, foregroundRect.GetTop() + halfKnobWidth);
|
|
break;
|
|
}
|
|
case Direction::DIR_TOP_TO_BOTTOM: {
|
|
offset = (knobWidth_ - progressWidth_) >> 1;
|
|
knobBar.SetRect(foregroundRect.GetLeft() - offset, foregroundRect.GetBottom() - halfKnobWidth,
|
|
foregroundRect.GetRight() + offset, foregroundRect.GetBottom() + halfKnobWidth);
|
|
break;
|
|
}
|
|
default: {
|
|
GRAPHIC_LOGW("UISlider::DrawKnob Direction error!\n");
|
|
}
|
|
}
|
|
DrawValidRect(knobImage_, knobBar, invalidatedArea, *knobStyle_, 0);
|
|
}
|
|
|
|
void UISlider::OnDraw(const Rect& invalidatedArea)
|
|
{
|
|
DrawRect::Draw(GetOrigRect(), invalidatedArea, *style_, opaScale_);
|
|
|
|
Rect trunc(invalidatedArea);
|
|
if (trunc.Intersect(trunc, GetOrigRect())) {
|
|
DrawBackground(trunc);
|
|
Rect foregroundRect;
|
|
DrawForeground(trunc, foregroundRect);
|
|
DrawKnob(trunc, foregroundRect);
|
|
}
|
|
}
|
|
|
|
bool UISlider::InitImage()
|
|
{
|
|
if (!UIAbstractProgress::InitImage()) {
|
|
return false;
|
|
}
|
|
if (knobImage_ == nullptr) {
|
|
knobImage_ = new Image();
|
|
if (knobImage_ == nullptr) {
|
|
GRAPHIC_LOGE("new Image fail");
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
} // namespace OHOS
|