• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "components/ui_checkbox.h"
17 #include "default_resource/check_box_res.h"
18 #include "draw/draw_image.h"
19 #include "engines/gfx/gfx_engine_manager.h"
20 #include "imgdecode/cache_manager.h"
21 
22 namespace OHOS {
23 namespace {
24 constexpr uint8_t DEFAULT_UNSELECT_BG_OPA = 168;     // default background opacity
25 constexpr float DEFAULT_COEFFICIENT_START_DX = 0.22; // start point: x-cordinate offset
26 constexpr float DEFAULT_COEFFICIENT_START_DY = 0.5;  // start point: y-cordinate offset
27 constexpr float DEFAULT_COEFFICIENT_MID_DX = 0.2;    // middle point: y-cordinate offset
28 constexpr float DEFAULT_COEFFICIENT_MID_DY = 0.38;   // middle point: y-cordinate offset
29 constexpr int16_t DEFAULT_RATIO_BORDER_RADIUS_LINE_WIDTH = 4;
30 constexpr uint8_t DEFAULT_BG_RED = 31;
31 constexpr uint8_t DEFAULT_BG_GREEN = 113;
32 constexpr uint8_t DEFAULT_BG_BLUE = 255;
33 #if DEFAULT_ANIMATION
34 constexpr int16_t DEFAULT_ANIMATOR_TIME = 200;
35 constexpr float BEZIER_CONTROL_POINT_X_1 = 0.33;
36 constexpr float BEZIER_CONTROL_POINT_X_2 = 0.67;
37 #endif
38 } // namespace
UICheckBox()39 UICheckBox::UICheckBox()
40     : state_(UNSELECTED),
41       onStateChangeListener_(nullptr),
42       width_(DEFAULT_HOT_WIDTH),
43       height_(DEFAULT_HOT_HEIGHT),
44       borderWidth_(DEFAULT_BORDER_WIDTH),
45       backgroundOpacity_(0)
46 {
47     touchable_ = true;
48     style_ = &(StyleDefault::GetBackgroundTransparentStyle());
49 #if defined(ENABLE_DEFAULT_CHECKBOX_IMAGE) && (ENABLE_DEFAULT_CHECKBOX_IMAGE == 1)
50     image_[UNSELECTED].SetSrc(GetCheckBoxOffInfo());
51     image_[SELECTED].SetSrc(GetCheckBoxOnInfo());
52 #endif
53     ImageHeader header = {0};
54     image_[UNSELECTED].GetHeader(header);
55     Resize(header.width, header.height);
56 #if DEFAULT_ANIMATION
57     runTime_ = 0;
58     checkBoxAnimator_ = Animator(this, this, DEFAULT_ANIMATOR_TIME, false);
59 #endif
60     selectedStateColor_ = Color::GetColorFromRGB(DEFAULT_BG_RED, DEFAULT_BG_GREEN, DEFAULT_BG_BLUE);
61 }
62 
SetState(UICheckBoxState state,bool needAnimater)63 void UICheckBox::SetState(UICheckBoxState state, bool needAnimater)
64 {
65     if (state_ == state) {
66         return;
67     }
68     state_ = state;
69     if ((image_[SELECTED].GetSrcType() == IMG_SRC_UNKNOWN) || (image_[UNSELECTED].GetSrcType() == IMG_SRC_UNKNOWN)) {
70 #if DEFAULT_ANIMATION
71         if (needAnimater) {
72             checkBoxAnimator_.Start();
73             ResetCallback();
74         } else {
75             backgroundOpacity_ = (state_ == SELECTED) ? OPA_OPAQUE : 0;
76         }
77 #else
78         backgroundOpacity_ = (state_ == SELECTED) ? OPA_OPAQUE : 0;
79 #endif
80     }
81     if (onStateChangeListener_ != nullptr) {
82         onStateChangeListener_->OnChange(state);
83     }
84     Invalidate();
85 }
86 
ReverseState()87 void UICheckBox::ReverseState()
88 {
89     if (state_ == SELECTED) {
90         SetState(UNSELECTED, true);
91     } else {
92         SetState(SELECTED, true);
93     }
94 }
95 
OnClickEvent(const ClickEvent & event)96 bool UICheckBox::OnClickEvent(const ClickEvent& event)
97 {
98     ReverseState();
99     Invalidate();
100     return UIView::OnClickEvent(event);
101 }
102 
SetImages(const char * selectedImageSrc,const char * unselectedImageSrc)103 void UICheckBox::SetImages(const char* selectedImageSrc, const char* unselectedImageSrc)
104 {
105     image_[SELECTED].SetSrc(selectedImageSrc);
106     image_[UNSELECTED].SetSrc(unselectedImageSrc);
107 }
108 
SetImages(const ImageInfo * selectedImageSrc,const ImageInfo * unselectedImageSrc)109 void UICheckBox::SetImages(const ImageInfo* selectedImageSrc, const ImageInfo* unselectedImageSrc)
110 {
111     image_[SELECTED].SetSrc(selectedImageSrc);
112     image_[UNSELECTED].SetSrc(unselectedImageSrc);
113 }
114 
CalculateSize()115 void UICheckBox::CalculateSize()
116 {
117     int16_t width = GetWidth();
118     int16_t height = GetHeight();
119     if ((width_ == width) && (height_ == height)) {
120         return;
121     }
122     width_ = width;
123     height_ = height;
124     int16_t minValue = (width_ > height_) ? height_ : width_;
125     borderWidth_ = DEFAULT_BORDER_WIDTH * minValue / DEFAULT_HOT_WIDTH;
126 }
127 
SelectedStateSoftwareDrawing(BufferInfo & gfxDstBuffer,Rect rect,Rect trunc,int16_t borderRadius,int16_t rectLineWidth)128 void UICheckBox::SelectedStateSoftwareDrawing(BufferInfo& gfxDstBuffer,
129                                               Rect rect,
130                                               Rect trunc,
131                                               int16_t borderRadius,
132                                               int16_t rectLineWidth)
133 {
134     if (backgroundOpacity_ == 0) {
135         return;
136     }
137     Style styleSelect = StyleDefault::GetBackgroundTransparentStyle();
138     styleSelect.borderRadius_ = borderRadius;
139     styleSelect.bgColor_ = selectedStateColor_;
140     styleSelect.bgOpa_ = backgroundOpacity_;
141     BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, rect, trunc, styleSelect, opaScale_);
142     int16_t dx = static_cast<int16_t>(borderWidth_ * DEFAULT_COEFFICIENT_START_DX);
143     int16_t dy = static_cast<int16_t>(borderWidth_ * DEFAULT_COEFFICIENT_START_DY);
144     Point start = {static_cast<int16_t>(rect.GetX() + dx), static_cast<int16_t>(rect.GetY() + dy)};
145     dx = static_cast<int16_t>(borderWidth_ * DEFAULT_COEFFICIENT_MID_DX);
146     Point mid = {static_cast<int16_t>(start.x + dx), static_cast<int16_t>(start.y + dx)};
147     dx = static_cast<int16_t>(borderWidth_ * DEFAULT_COEFFICIENT_MID_DY);
148     Point end = {static_cast<int16_t>(mid.x + dx), static_cast<int16_t>(mid.y - dx)};
149     const int16_t half = 2; // 2 :half
150     ArcInfo arcInfoLeft = {start,
151                            {0, 0},
152                            static_cast<uint16_t>(rectLineWidth),
153                            SEMICIRCLE_IN_DEGREE + QUARTER_IN_DEGREE / half,
154                            QUARTER_IN_DEGREE / half,
155                            nullptr};
156     ArcInfo arcInfoMid = {mid,
157                           {0, 0},
158                           static_cast<uint16_t>(rectLineWidth),
159                           SEMICIRCLE_IN_DEGREE - QUARTER_IN_DEGREE / half,
160                           SEMICIRCLE_IN_DEGREE + QUARTER_IN_DEGREE / half,
161                           nullptr};
162     ArcInfo arcInfoRight = {end,
163                             {0, 0},
164                             static_cast<uint16_t>(rectLineWidth),
165                             CIRCLE_IN_DEGREE - QUARTER_IN_DEGREE / half,
166                             SEMICIRCLE_IN_DEGREE - QUARTER_IN_DEGREE / half,
167                             nullptr};
168     styleSelect.lineColor_ = Color::White();
169     styleSelect.lineOpa_ = backgroundOpacity_;
170     uint8_t opa = DrawUtils::GetMixOpacity(opaScale_, backgroundOpacity_);
171     BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfoLeft, trunc, styleSelect, opaScale_, CapType::CAP_NONE);
172     // 2 : double
173     BaseGfxEngine::GetInstance()->DrawLine(gfxDstBuffer, start, mid, trunc, rectLineWidth * 2, Color::White(), opa);
174     BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfoMid, trunc, styleSelect, opaScale_, CapType::CAP_NONE);
175     // 2 : double
176     BaseGfxEngine::GetInstance()->DrawLine(gfxDstBuffer, mid, end, trunc, rectLineWidth * 2, Color::White(), opa);
177     BaseGfxEngine::GetInstance()->DrawArc(gfxDstBuffer, arcInfoRight, trunc, styleSelect, opaScale_, CapType::CAP_NONE);
178 }
179 
UnSelectedStateSoftwareDrawing(BufferInfo & gfxDstBuffer,Rect rect,Rect trunc,int16_t borderRadius,int16_t rectLineWidth)180 void UICheckBox::UnSelectedStateSoftwareDrawing(BufferInfo& gfxDstBuffer,
181                                                 Rect rect,
182                                                 Rect trunc,
183                                                 int16_t borderRadius,
184                                                 int16_t rectLineWidth)
185 {
186     Style styleUnSelect = StyleDefault::GetBackgroundTransparentStyle();
187     styleUnSelect.borderWidth_ = rectLineWidth;
188     styleUnSelect.borderRadius_ = borderRadius;
189     styleUnSelect.borderColor_ = Color::White();
190     styleUnSelect.borderOpa_ = DEFAULT_UNSELECT_BG_OPA;
191     BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, rect, trunc, styleUnSelect, opaScale_);
192 }
193 
194 #if DEFAULT_ANIMATION
ResetCallback()195 void UICheckBox::ResetCallback()
196 {
197     if ((runTime_ != 0) && (checkBoxAnimator_.GetTime() != runTime_)) {
198         checkBoxAnimator_.SetRunTime(checkBoxAnimator_.GetTime() - runTime_);
199     }
200 }
201 
Callback(UIView * view)202 void UICheckBox::Callback(UIView* view)
203 {
204     runTime_ = checkBoxAnimator_.GetRunTime();
205     float x = static_cast<float>(runTime_) / checkBoxAnimator_.GetTime();
206     float coefficient = Interpolation::GetBezierY(x, BEZIER_CONTROL_POINT_X_1, 0, BEZIER_CONTROL_POINT_X_2, 1);
207     backgroundOpacity_ = (state_ == SELECTED) ? (static_cast<uint8_t>(coefficient * OPA_OPAQUE)) :
208                                                 (static_cast<uint8_t>((1 - coefficient) * OPA_OPAQUE));
209     Invalidate();
210 }
211 
OnStop(UIView & view)212 void UICheckBox::OnStop(UIView& view)
213 {
214     backgroundOpacity_ = (state_ == SELECTED) ? OPA_OPAQUE : 0;
215     Invalidate();
216 }
217 #endif
218 
OnDraw(BufferInfo & gfxDstBuffer,const Rect & invalidatedArea)219 void UICheckBox::OnDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea)
220 {
221     Rect trunc = invalidatedArea;
222     if ((image_[SELECTED].GetSrcType() != IMG_SRC_UNKNOWN) && (image_[UNSELECTED].GetSrcType() != IMG_SRC_UNKNOWN)) {
223         ImageHeader header = {0};
224         image_[state_].GetHeader(header);
225         int16_t imgWidth = header.width;
226         int16_t imgHeight = header.height;
227         Rect coords = GetContentRect();
228         coords.SetWidth(imgWidth);
229         coords.SetHeight(imgHeight);
230         BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, GetRect(), invalidatedArea, *style_, opaScale_);
231         int16_t offsetLeft = (GetWidth() - imgWidth) / 2;  // 2 : half
232         int16_t offsetTop = (GetHeight() - imgHeight) / 2; // 2 : half
233         coords.SetX(coords.GetX() + offsetLeft);
234         coords.SetY(coords.GetY() + offsetTop);
235         if (trunc.Intersect(trunc, coords)) {
236             image_[state_].DrawImage(gfxDstBuffer, coords, trunc, *style_, opaScale_);
237         }
238     } else {
239         Rect contentRect = GetContentRect();
240         bool isIntersect = trunc.Intersect(trunc, contentRect);
241         if (!isIntersect) {
242             return;
243         }
244         CalculateSize();
245         int16_t rectLineWidth = borderWidth_ / DEFAULT_BORDER_WIDTH;
246         int16_t borderRadius = rectLineWidth * DEFAULT_RATIO_BORDER_RADIUS_LINE_WIDTH;
247         BaseGfxEngine::GetInstance()->DrawRect(gfxDstBuffer, GetRect(), invalidatedArea, *style_, opaScale_);
248         int16_t x = contentRect.GetX() + (width_ - borderWidth_) / 2;  // 2: half
249         int16_t y = contentRect.GetY() + (height_ - borderWidth_) / 2; // 2: half
250         Rect rect(x, y, x + borderWidth_, y + borderWidth_);
251 #if DEFAULT_ANIMATION
252         UnSelectedStateSoftwareDrawing(gfxDstBuffer, rect, trunc, borderRadius, rectLineWidth);
253         SelectedStateSoftwareDrawing(gfxDstBuffer, rect, trunc, borderRadius, rectLineWidth);
254 #else
255         if (state_ == SELECTED) {
256             SelectedStateSoftwareDrawing(gfxDstBuffer, rect, trunc, borderRadius, rectLineWidth);
257         } else {
258             UnSelectedStateSoftwareDrawing(gfxDstBuffer, rect, trunc, borderRadius, rectLineWidth);
259         }
260 #endif
261     }
262 }
263 
SetSelectedStateColor(ColorType color)264 void UICheckBox::SetSelectedStateColor(ColorType color)
265 {
266     selectedStateColor_ = color;
267 }
268 
GetSelectedStateColor() const269 ColorType UICheckBox::GetSelectedStateColor() const
270 {
271     return selectedStateColor_;
272 }
273 } // namespace OHOS
274