1 /*
2 * Copyright (c) 2023 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 #include "frameworks/bridge/declarative_frontend/jsview/js_symbol.h"
16
17 #include "core/components_ng/pattern/symbol/constants.h"
18 #include "frameworks/bridge/declarative_frontend/engine/bindings.h"
19 #include "frameworks/bridge/declarative_frontend/engine/js_ref_ptr.h"
20 #include "frameworks/bridge/declarative_frontend/jsview/js_interactable_view.h"
21 #include "frameworks/bridge/declarative_frontend/jsview/js_view_abstract.h"
22 #include "frameworks/core/components_ng/pattern/symbol/symbol_model.h"
23 #include "frameworks/core/components_ng/pattern/symbol/symbol_model_ng.h"
24
25 namespace OHOS::Ace {
26
27 std::unique_ptr<SymbolModel> SymbolModel::instance_ = nullptr;
28 std::mutex SymbolModel::mutex_;
29
GetInstance()30 SymbolModel* SymbolModel::GetInstance()
31 {
32 static NG::SymbolModelNG instance;
33 return &instance;
34 }
35
36 } // namespace OHOS::Ace
37
38 namespace OHOS::Ace::Framework {
39
40 const std::map<std::string, Ace::SymbolEffectType> SYMBOL_EFFECT_TYPE_MAP = {
41 { "ScaleSymbolEffect", SymbolEffectType::SCALE },
42 { "HierarchicalSymbolEffect", SymbolEffectType::HIERARCHICAL },
43 { "AppearSymbolEffect", SymbolEffectType::APPEAR },
44 { "DisappearSymbolEffect", SymbolEffectType::DISAPPEAR },
45 { "BounceSymbolEffect", SymbolEffectType::BOUNCE },
46 { "ReplaceSymbolEffect", SymbolEffectType::REPLACE },
47 { "PulseSymbolEffect", SymbolEffectType::PULSE },
48 };
49
JSBind(BindingTarget globalObj)50 void JSSymbol::JSBind(BindingTarget globalObj)
51 {
52 JSClass<JSSymbol>::Declare("SymbolGlyph");
53
54 MethodOptions opt = MethodOptions::NONE;
55 JSClass<JSSymbol>::StaticMethod("create", &JSSymbol::Create, opt);
56 JSClass<JSSymbol>::StaticMethod("fontWeight", &JSSymbol::SetFontWeight, opt);
57 JSClass<JSSymbol>::StaticMethod("fontSize", &JSSymbol::SetFontSize, opt);
58 JSClass<JSSymbol>::StaticMethod("renderingStrategy", &JSSymbol::SetSymbolRenderingStrategy, opt);
59 JSClass<JSSymbol>::StaticMethod("fontColor", &JSSymbol::SetFontColor, opt);
60 JSClass<JSSymbol>::StaticMethod("effectStrategy", &JSSymbol::SetSymbolEffect, opt);
61 JSClass<JSSymbol>::StaticMethod("onTouch", &JSInteractableView::JsOnTouch);
62 JSClass<JSSymbol>::StaticMethod("onAttach", &JSInteractableView::JsOnAttach);
63 JSClass<JSSymbol>::StaticMethod("onAppear", &JSInteractableView::JsOnAppear);
64 JSClass<JSSymbol>::StaticMethod("onDetach", &JSInteractableView::JsOnDetach);
65 JSClass<JSSymbol>::StaticMethod("onDisAppear", &JSInteractableView::JsOnDisAppear);
66 JSClass<JSSymbol>::StaticMethod("clip", &JSSymbol::JsClip);
67 JSClass<JSSymbol>::StaticMethod("symbolEffect", &JSSymbol::SetSymbolEffectOptions, opt);
68 JSClass<JSSymbol>::InheritAndBind<JSViewAbstract>(globalObj);
69 }
70
Create(const JSCallbackInfo & info)71 void JSSymbol::Create(const JSCallbackInfo& info)
72 {
73 if (info[0]->IsUndefined()) {
74 SymbolModel::GetInstance()->Create(0);
75 return;
76 }
77 uint32_t symbolId;
78 RefPtr<ResourceObject> resourceObject;
79 ParseJsSymbolId(info[0], symbolId, resourceObject);
80 SymbolModel::GetInstance()->Create(symbolId);
81 }
82
SetFontSize(const JSCallbackInfo & info)83 void JSSymbol::SetFontSize(const JSCallbackInfo& info)
84 {
85 if (info.Length() < 1) {
86 return;
87 }
88 auto theme = GetTheme<TextTheme>();
89 CHECK_NULL_VOID(theme);
90 CalcDimension fontSize = theme->GetTextStyle().GetFontSize();
91 if (!ParseJsDimensionFpNG(info[0], fontSize, false)) {
92 fontSize = theme->GetTextStyle().GetFontSize();
93 SymbolModel::GetInstance()->SetFontSize(fontSize);
94 return;
95 }
96 if (fontSize.IsNegative()) {
97 fontSize = theme->GetTextStyle().GetFontSize();
98 }
99
100 SymbolModel::GetInstance()->SetFontSize(fontSize);
101 }
102
SetFontWeight(const std::string & value)103 void JSSymbol::SetFontWeight(const std::string& value)
104 {
105 SymbolModel::GetInstance()->SetFontWeight(ConvertStrToFontWeight(value));
106 }
107
SetSymbolRenderingStrategy(const JSCallbackInfo & info)108 void JSSymbol::SetSymbolRenderingStrategy(const JSCallbackInfo& info)
109 {
110 uint32_t strategy = 0;
111 ParseJsInteger(info[0], strategy);
112 SymbolModel::GetInstance()->SetSymbolRenderingStrategy(strategy);
113 }
114
SetFontColor(const JSCallbackInfo & info)115 void JSSymbol::SetFontColor(const JSCallbackInfo& info)
116 {
117 std::vector<Color> symbolColor;
118 if (!ParseJsSymbolColor(info[0], symbolColor)) {
119 return;
120 }
121 SymbolModel::GetInstance()->SetFontColor(symbolColor);
122 }
123
SetSymbolEffect(const JSCallbackInfo & info)124 void JSSymbol::SetSymbolEffect(const JSCallbackInfo& info)
125 {
126 uint32_t strategy = 0;
127 ParseJsInteger(info[0], strategy);
128 SymbolModel::GetInstance()->SetSymbolEffect(strategy);
129 }
130
JsClip(const JSCallbackInfo & info)131 void JSSymbol::JsClip(const JSCallbackInfo& info)
132 {
133 JSViewAbstract::JsClip(info);
134 if (info[0]->IsBoolean()) {
135 SymbolModel::GetInstance()->SetClipEdge();
136 }
137 }
138
SetSymbolEffectOptions(const JSCallbackInfo & info)139 void JSSymbol::SetSymbolEffectOptions(const JSCallbackInfo& info)
140 {
141 if (info.Length() < 1 || !info[0]->IsObject()) {
142 return;
143 }
144
145 auto symbolEffectObj = JSRef<JSObject>::Cast(info[0]);
146 NG::SymbolEffectOptions symbolEffectOptions;
147 parseSymbolEffect(symbolEffectObj, symbolEffectOptions);
148
149 if (info.Length() > 1 && !info[1]->IsUndefined()) {
150 parseSymbolSwitch(info[1], symbolEffectOptions);
151 }
152
153 SymbolModel::GetInstance()->SetSymbolEffectOptions(symbolEffectOptions);
154 }
155
parseSymbolEffect(const JSRef<JSObject> symbolEffectObj,NG::SymbolEffectOptions & symbolEffectOptions)156 void JSSymbol::parseSymbolEffect(const JSRef<JSObject> symbolEffectObj, NG::SymbolEffectOptions& symbolEffectOptions)
157 {
158 auto typeParam = symbolEffectObj->GetProperty("type");
159 if (typeParam->IsString()) {
160 auto type = typeParam->ToString();
161 auto iter = SYMBOL_EFFECT_TYPE_MAP.find(type);
162 if (iter != SYMBOL_EFFECT_TYPE_MAP.end()) {
163 symbolEffectOptions.SetEffectType(iter->second);
164 }
165 }
166
167 auto scopeTypeProperty = symbolEffectObj->GetProperty("scope");
168 if (scopeTypeProperty->IsNumber()) {
169 auto scopeTypeNum = scopeTypeProperty->ToNumber<uint32_t>();
170 if (scopeTypeNum >= static_cast<uint32_t>(ScopeType::LAYER) &&
171 scopeTypeNum <= static_cast<uint32_t>(ScopeType::WHOLE)) {
172 symbolEffectOptions.SetScopeType(static_cast<ScopeType>(scopeTypeNum));
173 }
174 }
175
176 auto commonSubTypeProperty = symbolEffectObj->GetProperty("direction");
177 if (commonSubTypeProperty->IsNumber()) {
178 auto commonSubTypeNum = commonSubTypeProperty->ToNumber<uint32_t>();
179 if (commonSubTypeNum >= static_cast<uint32_t>(CommonSubType::DOWN) &&
180 commonSubTypeNum <= static_cast<uint32_t>(CommonSubType::UP)) {
181 symbolEffectOptions.SetCommonSubType(static_cast<CommonSubType>(commonSubTypeNum));
182 }
183 }
184
185 auto fillStyleProperty = symbolEffectObj->GetProperty("fillStyle");
186 if (fillStyleProperty->IsNumber()) {
187 auto fillStyleNum = fillStyleProperty->ToNumber<uint32_t>();
188 if (fillStyleNum >= static_cast<uint32_t>(FillStyle::CUMULATIVE) &&
189 fillStyleNum <= static_cast<uint32_t>(FillStyle::ITERATIVE)) {
190 symbolEffectOptions.SetFillStyle(static_cast<FillStyle>(fillStyleNum));
191 }
192 }
193 }
194
parseSymbolSwitch(const JSRef<JSVal> jsVal,NG::SymbolEffectOptions & symbolEffectOptions)195 void JSSymbol::parseSymbolSwitch(const JSRef<JSVal> jsVal, NG::SymbolEffectOptions& symbolEffectOptions)
196 {
197 if (jsVal->IsBoolean()) {
198 symbolEffectOptions.SetIsActive(jsVal->ToBoolean());
199 }
200
201 if (jsVal->IsNumber()) {
202 int32_t triggerValue = -1;
203 ParseJsInteger(jsVal, triggerValue);
204 symbolEffectOptions.SetTriggerNum(triggerValue);
205 }
206 }
207 } // namespace OHOS::Ace::Framework