1 /*
2 * Copyright (c) 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 "circle_progress_component.h"
17 #include "js_app_context.h"
18
19 namespace OHOS {
20 namespace ACELite {
CircleProgressComponent(jerry_value_t options,jerry_value_t children,AppStyleManager * styleManager)21 CircleProgressComponent::CircleProgressComponent(jerry_value_t options,
22 jerry_value_t children, AppStyleManager *styleManager)
23 : Component(options, children, styleManager),
24 centerX_(INT16_MAX),
25 centerY_(INT16_MAX),
26 radius_(INT16_MAX),
27 startAngle_(DEFAULT_START_ANGLE),
28 totalAngle_(DEFAULT_TOTAL_ANGLE)
29 {
30 }
31
CreateNativeViews()32 bool CircleProgressComponent::CreateNativeViews()
33 {
34 // set default value
35 progressView_.SetBackgroundStyle(StyleDefault::GetBrightStyle());
36 int8_t defaultLineWidth = 32;
37 const uint8_t compatibleApiVersion = 8;
38 if (JsAppContext::GetInstance()->GetCompatibleApi() >= compatibleApiVersion) {
39 defaultLineWidth = 4; // set the default strokeWidth 4px after api version 8
40 }
41 progressView_.SetBackgroundStyle(STYLE_LINE_WIDTH, defaultLineWidth); // Compatible with rich devices
42 progressView_.SetBackgroundStyle(STYLE_LINE_CAP, CapType::CAP_ROUND);
43 uint32_t color = 0;
44 uint8_t alpha = OPA_OPAQUE;
45 const char * const defaultBackgroundColor = "rgba(255,255,255,0.15)";
46 if (ParseColor(defaultBackgroundColor, color, alpha)) {
47 progressView_.SetBackgroundStyle(STYLE_LINE_COLOR, GetRGBColor(color).full);
48 progressView_.SetBackgroundStyle(STYLE_LINE_OPA, alpha);
49 }
50 progressView_.SetForegroundStyle(StyleDefault::GetBrightColorStyle());
51 progressView_.SetForegroundStyle(STYLE_BACKGROUND_OPA, 0);
52 progressView_.SetForegroundStyle(STYLE_BORDER_OPA, 0);
53 progressView_.SetForegroundStyle(STYLE_LINE_WIDTH, defaultLineWidth);
54 progressView_.SetForegroundStyle(STYLE_LINE_CAP, CapType::CAP_ROUND);
55 const char * const defaultColor = "#5EA1FF";
56 if (ParseColor(defaultColor, color, alpha)) {
57 progressView_.SetForegroundStyle(STYLE_LINE_COLOR, GetRGBColor(color).full);
58 progressView_.SetForegroundStyle(STYLE_LINE_OPA, OPA_OPAQUE);
59 }
60 return true;
61 }
62
ApplyPrivateStyle(const AppStyleItem * style)63 bool CircleProgressComponent::ApplyPrivateStyle(const AppStyleItem *style)
64 {
65 return SetArcProgressStyle(style);
66 }
67
GetComponentRootView() const68 UIView *CircleProgressComponent::GetComponentRootView() const
69 {
70 return const_cast<UICircleProgress *>(&progressView_);
71 }
72
SetPrivateAttribute(uint16_t attrKeyId,jerry_value_t attrValue)73 bool CircleProgressComponent::SetPrivateAttribute(uint16_t attrKeyId, jerry_value_t attrValue)
74 {
75 switch (attrKeyId) {
76 case K_PERCENT: {
77 // set the specific attribute of this progress view
78 int16_t rangeMax = 100;
79 int16_t rangeMin = 0;
80 progressView_.SetRange(rangeMax, rangeMin);
81 progressView_.SetValue(IntegerOf(attrValue));
82 return true;
83 }
84 default: {
85 return false;
86 }
87 }
88 }
89
SetAngles()90 void CircleProgressComponent::SetAngles()
91 {
92 if (centerX_ == INT16_MAX) {
93 centerX_ = static_cast<uint16_t>(progressView_.GetWidth()) >> 1;
94 }
95 if (centerY_ == INT16_MAX) {
96 centerY_ = static_cast<uint16_t>(progressView_.GetHeight()) >> 1;
97 }
98 if (radius_ == INT16_MAX) {
99 if (progressView_.GetWidth() <= progressView_.GetHeight()) {
100 radius_ = static_cast<uint16_t>(progressView_.GetWidth()) >> 1;
101 } else {
102 radius_ = static_cast<uint16_t>(progressView_.GetHeight()) >> 1;
103 }
104 }
105
106 progressView_.SetCenterPosition(centerX_, centerY_);
107 progressView_.SetRadius(radius_);
108 progressView_.SetStartAngle(startAngle_);
109 progressView_.SetEndAngle(startAngle_ + totalAngle_);
110 }
111
SetStartAngle(const AppStyleItem * style)112 void CircleProgressComponent::SetStartAngle(const AppStyleItem *style)
113 {
114 const int16_t minStartAngle = 0;
115 const int16_t maxStartAngle = 360;
116 startAngle_ = GetStyleDegValue(style); // Compatible with rich devices, value should between -180 and 0
117 if (startAngle_ > maxStartAngle) {
118 startAngle_ = maxStartAngle;
119 } else if (startAngle_ < minStartAngle) {
120 startAngle_ = minStartAngle;
121 }
122 }
123
SetTotalAngle(const AppStyleItem * style)124 void CircleProgressComponent::SetTotalAngle(const AppStyleItem *style)
125 {
126 const int16_t minStartAngle = -360;
127 const int16_t maxStartAngle = 360;
128 totalAngle_ = GetStyleDegValue(style); // Compatible with rich devices, value should between 0 and 180
129 if (totalAngle_ < minStartAngle) {
130 totalAngle_ = minStartAngle;
131 } else if (totalAngle_ > maxStartAngle) {
132 totalAngle_ = maxStartAngle;
133 }
134 }
135
SetArcColor(const AppStyleItem * style)136 bool CircleProgressComponent::SetArcColor(const AppStyleItem *style)
137 {
138 uint32_t color = 0;
139 uint8_t alpha = OPA_OPAQUE;
140 if (!GetStyleColorValue(style, color, alpha)) {
141 return false;
142 }
143 progressView_.SetForegroundStyle(STYLE_LINE_COLOR, GetRGBColor(color).full);
144 progressView_.SetForegroundStyle(STYLE_LINE_OPA, alpha);
145 return true;
146 }
147
SetArcBackgroundColor(const AppStyleItem * style)148 bool CircleProgressComponent::SetArcBackgroundColor(const AppStyleItem *style)
149 {
150 uint32_t color = 0;
151 uint8_t alpha = OPA_OPAQUE;
152 if (!GetStyleColorValue(style, color, alpha)) {
153 return false;
154 }
155 progressView_.SetBackgroundStyle(STYLE_LINE_COLOR, GetRGBColor(color).full);
156 progressView_.SetBackgroundStyle(STYLE_LINE_OPA, alpha);
157 return true;
158 }
159
SetArcProgressStyle(const AppStyleItem * style)160 bool CircleProgressComponent::SetArcProgressStyle(const AppStyleItem *style)
161 {
162 uint16_t stylePropNameId = GetStylePropNameId(style);
163 switch (stylePropNameId) {
164 case K_CENTER_X: {
165 centerX_ = GetStylePixelValue(style);
166 return true;
167 }
168 case K_CENTER_Y: {
169 centerY_ = GetStylePixelValue(style);
170 return true;
171 }
172 case K_RADIUS: {
173 radius_ = GetStylePixelValue(style);
174 return true;
175 }
176 case K_START_ANGLE: {
177 SetStartAngle(style);
178 return true;
179 }
180 case K_TOTAL_ANGLE: {
181 SetTotalAngle(style);
182 return true;
183 }
184 case K_COLOR: {
185 return SetArcColor(style);
186 }
187 case K_STROKE_WIDTH: {
188 progressView_.SetBackgroundStyle(STYLE_LINE_WIDTH, GetStylePixelValue(style));
189 progressView_.SetForegroundStyle(STYLE_LINE_WIDTH, GetStylePixelValue(style));
190 return true;
191 }
192 case K_BACKGROUND_COLOR: {
193 return SetArcBackgroundColor(style);
194 }
195 default: {
196 return false;
197 }
198 }
199 }
200
OnViewAttached()201 void CircleProgressComponent::OnViewAttached()
202 {
203 HandleExtraUpdate();
204 }
205
PostUpdate(uint16_t attrKeyId)206 void CircleProgressComponent::PostUpdate(uint16_t attrKeyId)
207 {
208 UNUSED(attrKeyId);
209 HandleExtraUpdate();
210 }
211
HandleExtraUpdate()212 void CircleProgressComponent::HandleExtraUpdate()
213 {
214 SetAngles();
215 }
216 } // namespace ACELite
217 } // namespace OHOS
218