提交 446bbae5 编写于 作者: W wangtiantian

IssueNo:#I3NSZZ

Description:support UICheckBox animation
Sig:graphic
Feature or Bugfix:Feature
Binary Source:No
上级 edfd5b16
......@@ -13,7 +13,6 @@
* limitations under the License.
*/
#include "common/image.h"
#include "components/ui_checkbox.h"
#include "default_resource/check_box_res.h"
#include "draw/draw_arc.h"
......@@ -23,9 +22,22 @@
#include "imgdecode/cache_manager.h"
namespace OHOS {
namespace {
constexpr uint8_t DEFAULT_UNSELECT_BG_OPA = 168; // default background opacity
constexpr float DEFAULT_COEFFICIENT_START_DX = 0.22; // start point: x-cordinate offset
constexpr float DEFAULT_COEFFICIENT_START_DY = 0.5; // start point: y-cordinate offset
constexpr float DEFAULT_COEFFICIENT_MID_DX = 0.2; // middle point: y-cordinate offset
constexpr float DEFAULT_COEFFICIENT_MID_DY = 0.38; // middle point: y-cordinate offset
constexpr int16_t DEFAULT_RATIO_BORDER_RADIUS_LINE_WIDTH = 4;
#if DEFAULT_ANIMATION
constexpr int16_t DEFAULT_ANIMATOR_TIME = 200;
constexpr float BEZIER_CONTROL_POINT_X_1 = 0.33;
constexpr float BEZIER_CONTROL_POINT_X_2 = 0.67;
#endif
}
UICheckBox::UICheckBox()
: state_(UNSELECTED), onStateChangeListener_(nullptr), width_(DEFAULT_HOT_WIDTH), height_(DEFAULT_HOT_HEIGHT),
borderWidth_(DEFAULT_BORDER_WIDTH)
borderWidth_(DEFAULT_BORDER_WIDTH), backgroundOpacity_(0)
{
touchable_ = true;
style_ = &(StyleDefault::GetBackgroundTransparentStyle());
......@@ -34,26 +46,46 @@ UICheckBox::UICheckBox()
ImageHeader header = { 0 };
image_[UNSELECTED].GetHeader(header);
Resize(header.width, header.height);
#if DEFAULT_ANIMATION
runTime_ = 0;
checkBoxAnimator_ = Animator(this, this, DEFAULT_ANIMATOR_TIME, false);
#endif
}
UICheckBox::~UICheckBox()
{
#if DEFAULT_ANIMATION
checkBoxAnimator_.Stop();
#endif
}
void UICheckBox::SetState(UICheckBoxState state)
{
if (state != state_) {
state_ = state;
if (onStateChangeListener_ != nullptr) {
onStateChangeListener_->OnChange(state);
}
Invalidate();
if (state_ == state) {
return;
}
state_ = state;
if ((image_[SELECTED].GetSrcType() == IMG_SRC_UNKNOWN) || (image_[UNSELECTED].GetSrcType() == IMG_SRC_UNKNOWN)) {
#if DEFAULT_ANIMATION
checkBoxAnimator_.Start();
ResetCallback();
#else
backgroundOpacity_ = (state_ == SELECTED) ? OPA_OPAQUE : 0;
#endif
}
if (onStateChangeListener_ != nullptr) {
onStateChangeListener_->OnChange(state);
}
Invalidate();
}
void UICheckBox::ReverseState()
{
state_ = (state_ == SELECTED) ? UNSELECTED : SELECTED;
if (state_ == SELECTED) {
SetState(UNSELECTED);
} else {
SetState(SELECTED);
}
}
bool UICheckBox::OnClickEvent(const ClickEvent& event)
......@@ -90,21 +122,20 @@ void UICheckBox::CalculateSize()
void UICheckBox::SelectedStateSoftwareDrawing(Rect rect, Rect trunc, int16_t borderRadius, int16_t rectLineWidth)
{
if (backgroundOpacity_ == 0) {
return;
}
Style styleSelect = StyleDefault::GetBackgroundTransparentStyle();
styleSelect.borderRadius_ = borderRadius;
styleSelect.bgColor_ = Color::GetColorFromRGB(0x1F, 0x71, 0xFF);
styleSelect.bgOpa_ = OPA_OPAQUE;
Rect contentRect = GetContentRect();
bool isIntersect = trunc.Intersect(trunc, contentRect);
if (isIntersect) {
DrawRect::Draw(rect, trunc, styleSelect, opaScale_);
}
int16_t dx = borderWidth_ * 0.22; // 0.22 : coefficient,
int16_t dy = borderWidth_ * 0.5; // 0.5 : coefficient,
styleSelect.bgColor_ = Color::GetColorFromRGB(DEFAULT_BG_RED, DEFAULT_BG_GREEN, DEFAULT_BG_BLUE);
styleSelect.bgOpa_ = backgroundOpacity_;
DrawRect::Draw(rect, trunc, styleSelect, opaScale_);
int16_t dx = borderWidth_ * DEFAULT_COEFFICIENT_START_DX;
int16_t dy = borderWidth_ * DEFAULT_COEFFICIENT_START_DY;
Point start = { static_cast<int16_t>(rect.GetX() + dx), static_cast<int16_t>(rect.GetY() + dy) };
dx = borderWidth_ * 0.2; // 0.2 : coefficient
dx = borderWidth_ * DEFAULT_COEFFICIENT_MID_DX;
Point mid = { static_cast<int16_t>(start.x + dx), static_cast<int16_t>(start.y + dx) };
dx = borderWidth_ * 0.38; // 0.38 : coefficient
dx = borderWidth_ * DEFAULT_COEFFICIENT_MID_DY;
Point end = { static_cast<int16_t>(mid.x + dx), static_cast<int16_t>(mid.y - dx) };
const int16_t half = 2; // 2 :half
ArcInfo arcInfoLeft = {
......@@ -120,15 +151,51 @@ void UICheckBox::SelectedStateSoftwareDrawing(Rect rect, Rect trunc, int16_t bor
SEMICIRCLE_IN_DEGREE - QUARTER_IN_DEGREE / half, nullptr
};
styleSelect.lineColor_ = Color::White();
if (isIntersect) {
DrawArc::GetInstance()->Draw(arcInfoLeft, trunc, styleSelect, OPA_OPAQUE, CapType::CAP_NONE);
DrawLine::Draw(start, mid, trunc, rectLineWidth * 2, Color::White(), opaScale_); // 2 : double
DrawArc::GetInstance()->Draw(arcInfoMid, trunc, styleSelect, OPA_OPAQUE, CapType::CAP_NONE);
DrawLine::Draw(mid, end, trunc, rectLineWidth * 2, Color::White(), opaScale_); // 2 : double
DrawArc::GetInstance()->Draw(arcInfoRight, trunc, styleSelect, OPA_OPAQUE, CapType::CAP_NONE);
styleSelect.lineOpa_ = backgroundOpacity_;
uint8_t opa = DrawUtils::GetMixOpacity(opaScale_, backgroundOpacity_);
DrawArc::GetInstance()->Draw(arcInfoLeft, trunc, styleSelect, opaScale_, CapType::CAP_NONE);
DrawLine::Draw(start, mid, trunc, rectLineWidth * 2, Color::White(), opa); // 2 : double
DrawArc::GetInstance()->Draw(arcInfoMid, trunc, styleSelect, opaScale_, CapType::CAP_NONE);
DrawLine::Draw(mid, end, trunc, rectLineWidth * 2, Color::White(), opa); // 2 : double
DrawArc::GetInstance()->Draw(arcInfoRight, trunc, styleSelect, opaScale_, CapType::CAP_NONE);
}
void UICheckBox::UnSelectedStateSoftwareDrawing(Rect rect, Rect trunc, int16_t borderRadius, int16_t rectLineWidth)
{
Rect contentRect = GetContentRect();
Style styleUnSelect = StyleDefault::GetBackgroundTransparentStyle();
styleUnSelect.borderWidth_ = rectLineWidth;
styleUnSelect.borderRadius_ = borderRadius;
styleUnSelect.borderColor_ = Color::White();
styleUnSelect.borderOpa_ = DEFAULT_UNSELECT_BG_OPA;
DrawRect::Draw(rect, trunc, styleUnSelect, opaScale_);
}
#if DEFAULT_ANIMATION
void UICheckBox::ResetCallback()
{
if ((runTime_ != 0) && (checkBoxAnimator_.GetTime() != runTime_)) {
checkBoxAnimator_.SetRunTime(checkBoxAnimator_.GetTime() - runTime_);
}
}
void UICheckBox::Callback(UIView* view)
{
runTime_ = checkBoxAnimator_.GetRunTime();
float x = static_cast<float>(runTime_) / checkBoxAnimator_.GetTime();
float coefficient = Interpolation::GetBezierY(x, BEZIER_CONTROL_POINT_X_1, 0, BEZIER_CONTROL_POINT_X_2, 1);
backgroundOpacity_ = (state_ == SELECTED) ? (static_cast<uint8_t>(coefficient * OPA_OPAQUE)) :
(static_cast<uint8_t>((1 - coefficient) * OPA_OPAQUE));
Invalidate();
}
void UICheckBox::OnStop(UIView& view)
{
backgroundOpacity_ = (state_ == SELECTED) ? OPA_OPAQUE : 0;
Invalidate();
}
#endif
void UICheckBox::OnDraw(const Rect& invalidatedArea)
{
Rect trunc = invalidatedArea;
......@@ -149,33 +216,28 @@ void UICheckBox::OnDraw(const Rect& invalidatedArea)
image_[state_].DrawImage(coords, trunc, *style_, opaScale_);
}
} else {
Rect contentRect = GetContentRect();
bool isIntersect = trunc.Intersect(trunc, contentRect);
if (!isIntersect) {
return;
}
CalculateSize();
int16_t rectLineWidth = borderWidth_ / DEFAULT_BORDER_WIDTH;
int16_t borderRadius = rectLineWidth * 4; // 4 : coefficient
int16_t borderRadius = rectLineWidth * DEFAULT_RATIO_BORDER_RADIUS_LINE_WIDTH;
DrawRect::Draw(GetRect(), invalidatedArea, *style_, opaScale_);
Rect contentRect = GetContentRect();
int16_t x = contentRect.GetX() + (width_ - borderWidth_) / 2; // 2: half
int16_t y = contentRect.GetY() + (height_ - borderWidth_) / 2; // 2: half
Rect rect(x, y, x + borderWidth_, y + borderWidth_);
switch (state_) {
case SELECTED: {
SelectedStateSoftwareDrawing(rect, trunc, borderRadius, rectLineWidth);
break;
}
case UNSELECTED: {
Style styleUnSelect = StyleDefault::GetBackgroundTransparentStyle();
styleUnSelect.borderWidth_ = rectLineWidth;
styleUnSelect.borderRadius_ = borderRadius;
styleUnSelect.borderColor_ = Color::White();
styleUnSelect.borderOpa_ = 0xa8; // 0xa8: opacity
if (trunc.Intersect(trunc, contentRect)) {
DrawRect::Draw(rect, trunc, styleUnSelect, opaScale_);
}
break;
}
default:
break;
#if DEFAULT_ANIMATION
UnSelectedStateSoftwareDrawing(rect, trunc, borderRadius, rectLineWidth);
SelectedStateSoftwareDrawing(rect, trunc, borderRadius, rectLineWidth);
#else
if (state_ == SELECTED) {
SelectedStateSoftwareDrawing(rect, trunc, borderRadius, rectLineWidth);
} else {
UnSelectedStateSoftwareDrawing(rect, trunc, borderRadius, rectLineWidth);
}
#endif
}
}
} // namespace OHOS
......@@ -35,6 +35,8 @@
#ifndef GRAPHIC_LITE_UI_CHECKBOX_H
#define GRAPHIC_LITE_UI_CHECKBOX_H
#include "animator/animator.h"
#include "animator/interpolation.h"
#include "common/image.h"
#include "components/ui_view.h"
......@@ -47,7 +49,11 @@ namespace OHOS {
* @since 1.0
* @version 1.0
*/
#if DEFAULT_ANIMATION
class UICheckBox : public UIView, public AnimatorCallback {
#else
class UICheckBox : public UIView {
#endif
public:
/**
* @brief Enumerates the states of a check box.
......@@ -219,16 +225,30 @@ protected:
virtual void ReverseState();
virtual void CalculateSize();
void SelectedStateSoftwareDrawing(Rect rect, Rect trunc, int16_t borderRadius, int16_t rectLineWidth);
void UnSelectedStateSoftwareDrawing(Rect rect, Rect trunc, int16_t borderRadius, int16_t rectLineWidth);
#if DEFAULT_ANIMATION
virtual void ResetCallback();
void Callback(UIView* view) override;
void OnStop(UIView& view) override;
#endif
static constexpr int16_t DEFAULT_HOT_WIDTH = 46;
static constexpr int16_t DEFAULT_HOT_HEIGHT = 46;
static constexpr int16_t DEFAULT_BORDER_WIDTH = 22;
static constexpr uint8_t DEFAULT_BG_RED = 31;
static constexpr uint8_t DEFAULT_BG_GREEN = 113;
static constexpr uint8_t DEFAULT_BG_BLUE = 255;
UICheckBoxState state_;
OnChangeListener* onStateChangeListener_;
int16_t width_;
int16_t height_;
int16_t borderWidth_;
Image image_[MAX_STATUS_NUM];
uint8_t backgroundOpacity_;
#if DEFAULT_ANIMATION
Animator checkBoxAnimator_;
uint32_t runTime_;
#endif
};
} // namespace OHOS
#endif // GRAPHIC_LITE_UI_CHECKBOX_H
......@@ -113,9 +113,6 @@ private:
static constexpr int16_t DEFAULT_CORNER_RADIUS = 11;
static constexpr int16_t DEAFULT_RADIUS_DIFF = 2;
static constexpr uint8_t DEFAULT_UNSELECTED_OPA = 97;
static constexpr uint8_t DEFAULT_BG_RED = 31;
static constexpr uint8_t DEFAULT_BG_GREEN = 113;
static constexpr uint8_t DEFAULT_BG_BLUE = 255;
uint16_t corner_;
uint16_t radius_;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册