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 "frameworks/bridge/common/dom/dom_switch.h"
17
18 #include "base/i18n/localization.h"
19 #include "frameworks/bridge/common/utils/utils.h"
20
21 namespace OHOS::Ace::Framework {
22 namespace {
23
24 constexpr Dimension BOX_HOVER_RADIUS = 8.0_vp;
25
26 } // namespace
27
DOMSwitch(NodeId nodeId,const std::string & nodeName)28 DOMSwitch::DOMSwitch(NodeId nodeId, const std::string& nodeName) : DOMNode(nodeId, nodeName)
29 {
30 switchChild_ = AceType::MakeRefPtr<SwitchComponent>(nullptr);
31 switchChild_->SetTextOn(Localization::GetInstance()->GetEntryLetters("switch.on"));
32 switchChild_->SetTextOff(Localization::GetInstance()->GetEntryLetters("switch.off"));
33 }
34
InitializeStyle()35 void DOMSwitch::InitializeStyle()
36 {
37 ResetInitializedStyle();
38 }
39
ResetInitializedStyle()40 void DOMSwitch::ResetInitializedStyle()
41 {
42 RefPtr<SwitchTheme> theme = GetTheme<SwitchTheme>();
43 if (theme) {
44 switchChild_->ApplyTheme(theme);
45 }
46 switchChild_->SetTextOn(Localization::GetInstance()->GetEntryLetters("switch.on"));
47 switchChild_->SetTextOff(Localization::GetInstance()->GetEntryLetters("switch.off"));
48 }
49
SetSpecializedAttr(const std::pair<std::string,std::string> & attr)50 bool DOMSwitch::SetSpecializedAttr(const std::pair<std::string, std::string>& attr)
51 {
52 static const LinearMapNode<void (*)(const std::string&, SwitchComponent&, std::string&, std::string&)>
53 switchAttrOperators[] = {
54 { DOM_CHECKED, [](const std::string& val, SwitchComponent& textSwitch, std::string& textOn,
55 std::string& textOff) { textSwitch.SetValue(StringToBool(val)); } },
56 { DOM_DISABLED, [](const std::string& val, SwitchComponent& textSwitch, std::string& textOn,
57 std::string& textOff) { textSwitch.SetDisabled(StringToBool(val)); } },
58 { DOM_SHOW_TEXT, [](const std::string& val, SwitchComponent& textSwitch, std::string& textOn,
59 std::string& textOff) { textSwitch.SetShowText(StringToBool(val)); } },
60 { DOM_TEXT_OFF,
61 [](const std::string& val, SwitchComponent& textSwitch, std::string& textOn, std::string& textOff) {
62 textSwitch.SetTextOff(val);
63 textOff = val;
64 } },
65 { DOM_TEXT_ON,
66 [](const std::string& val, SwitchComponent& textSwitch, std::string& textOn, std::string& textOff) {
67 textSwitch.SetTextOn(val);
68 textOn = val;
69 } },
70 };
71 auto operatorIter = BinarySearchFindIndex(
72 switchAttrOperators, ArraySize(switchAttrOperators), attr.first.c_str());
73 if (operatorIter != -1) {
74 switchAttrOperators[operatorIter].value(attr.second, *switchChild_, textOn_, textOff_);
75 return true;
76 }
77 return false;
78 }
79
SetSpecializedStyle(const std::pair<std::string,std::string> & style)80 bool DOMSwitch::SetSpecializedStyle(const std::pair<std::string, std::string>& style)
81 {
82 static const LinearMapNode<void (*)(const std::string&, const DOMSwitch&, SwitchComponent&, TextStyle&)>
83 switchTextOperators[] = {
84 { DOM_TEXT_ALLOW_SCALE, [](const std::string& val, const DOMSwitch& node, SwitchComponent& textSwitch,
85 TextStyle& textStyle) { textStyle.SetAllowScale(StringToBool(val)); } },
86 { DOM_TEXT_FONT_FAMILY,
87 [](const std::string& val, const DOMSwitch& node, SwitchComponent& textSwitch, TextStyle& textStyle) {
88 textStyle.SetFontFamilies(node.ParseFontFamilies(val));
89 } },
90 { DOM_TEXT_FONT_SIZE, [](const std::string& val, const DOMSwitch& node, SwitchComponent& textSwitch,
91 TextStyle& textStyle) { textStyle.SetFontSize(node.ParseDimension(val)); } },
92 { DOM_TEXT_FONT_STYLE, [](const std::string& val, const DOMSwitch& node, SwitchComponent& textSwitch,
93 TextStyle& textStyle) { textStyle.SetFontStyle(ConvertStrToFontStyle(val)); } },
94 { DOM_TEXT_FONT_WEIGHT, [](const std::string& val, const DOMSwitch& node, SwitchComponent& textSwitch,
95 TextStyle& textStyle) { textStyle.SetFontWeight(ConvertStrToFontWeight(val)); } },
96 { DOM_TEXT_LETTER_SPACING,
97 [](const std::string& val, const DOMSwitch& node, SwitchComponent& textSwitch, TextStyle& textStyle) {
98 textStyle.SetLetterSpacing(node.ParseDimension(val)); } },
99 { DOM_TEXT_DECORATION,
100 [](const std::string& val, const DOMSwitch& node, SwitchComponent& textSwitch, TextStyle& textStyle) {
101 textStyle.SetTextDecoration(ConvertStrToTextDecoration(val));
102 } },
103 { DOM_TEXT_PADDING, [](const std::string& val, const DOMSwitch& node, SwitchComponent& textSwitch,
104 TextStyle& textStyle) { textSwitch.SetTextPadding(node.ParseDimension(val)); } },
105 { DOM_TEXT_OFF_COLOR, [](const std::string& val, const DOMSwitch& node, SwitchComponent& textSwitch,
106 TextStyle& textStyle) { textSwitch.SetTextColorOff(node.ParseColor(val)); } },
107 { DOM_TEXT_ON_COLOR, [](const std::string& val, const DOMSwitch& node, SwitchComponent& textSwitch,
108 TextStyle& textStyle) { textSwitch.SetTextColorOn(node.ParseColor(val)); } },
109 };
110 auto operatorIter = BinarySearchFindIndex(switchTextOperators, ArraySize(switchTextOperators), style.first.c_str());
111 if (operatorIter != -1) {
112 switchTextOperators[operatorIter].value(style.second, *this, *switchChild_, textStyle_);
113 return true;
114 }
115 return false;
116 }
117
AddSpecializedEvent(int32_t pageId,const std::string & event)118 bool DOMSwitch::AddSpecializedEvent(int32_t pageId, const std::string& event)
119 {
120 if (event == DOM_CHANGE) {
121 changeEvent_ = EventMarker(GetNodeIdForEvent(), event, pageId);
122 switchChild_->SetChangeEvent(changeEvent_);
123 return true;
124 } else if (event == DOM_CLICK) {
125 EventMarker eventMarker(GetNodeIdForEvent(), event, pageId);
126 eventMarker.SetCatchMode(false);
127 switchChild_->SetClickEvent(eventMarker);
128 } else if (event == DOM_CATCH_BUBBLE_CLICK) {
129 EventMarker eventMarker(GetNodeIdForEvent(), event, pageId);
130 eventMarker.SetCatchMode(true);
131 switchChild_->SetClickEvent(eventMarker);
132 }
133 return false;
134 }
135
PrepareCheckedListener()136 void DOMSwitch::PrepareCheckedListener()
137 {
138 auto weak = AceType::WeakClaim(this);
139 auto checkableChangeCallback = [weak](const std::string& checked) {
140 auto domNode = weak.Upgrade();
141 if (!domNode) {
142 return;
143 }
144 bool isChecked = checked.find("\"checked\":true") != std::string::npos;
145 std::string checkedString = isChecked ? "true" : "false";
146 domNode->SetSpecializedAttr(std::make_pair(DOM_CHECKED, checkedString));
147 domNode->OnChecked(isChecked);
148 };
149 auto checkableChangeMarker = BackEndEventManager<void(const std::string&)>::GetInstance().GetAvailableMarker();
150 BackEndEventManager<void(const std::string&)>::GetInstance().BindBackendEvent(
151 checkableChangeMarker, checkableChangeCallback);
152 switchChild_->SetDomChangeEvent(checkableChangeMarker);
153 }
154
PrepareSpecializedComponent()155 void DOMSwitch::PrepareSpecializedComponent()
156 {
157 if (boxComponent_) {
158 boxComponent_->SetMouseAnimationType(HoverAnimationType::OPACITY);
159 if (!boxComponent_->GetBackDecoration()) {
160 RefPtr<Decoration> backDecoration = AceType::MakeRefPtr<Decoration>();
161 backDecoration->SetBorderRadius(Radius(BOX_HOVER_RADIUS));
162 boxComponent_->SetBackDecoration(backDecoration);
163 }
164 }
165 if (HasCheckedPseudo()) {
166 PrepareCheckedListener();
167 }
168 switchChild_->SetTextDirection(IsRightToLeft() ? TextDirection::RTL : TextDirection::LTR);
169 switchChild_->SetTextStyle(textStyle_);
170 if (!textOn_.empty()) {
171 switchChild_->SetTextOn(textOn_);
172 }
173 if (!textOff_.empty()) {
174 switchChild_->SetTextOff(textOff_);
175 }
176 RefPtr<SwitchTheme> theme = GetTheme<SwitchTheme>();
177 if (switchChild_->GetShowText()) {
178 return;
179 }
180 if (boxComponent_ && boxComponent_->GetHeightDimension().Value() < 0.0 && theme) {
181 boxComponent_->SetHeight(theme->GetHeight().Value(), theme->GetHeight().Unit());
182 }
183 if (boxComponent_ && boxComponent_->GetWidthDimension().Value() < 0.0 && theme) {
184 boxComponent_->SetWidth(theme->GetWidth().Value(), theme->GetWidth().Unit());
185 }
186 #ifndef WEARABLE_PRODUCT
187 if (declaration_) {
188 auto& multimodalAttr =
189 static_cast<CommonMultimodalAttribute&>(declaration_->GetAttribute(AttributeTag::COMMON_MULTIMODAL_ATTR));
190 if (multimodalAttr.IsValid() && !multimodalAttr.IsUnavailable() && multimodalAttr.scene == SceneLabel::SWITCH) {
191 switchChild_->SetMultimodalProperties(multimodalAttr);
192 }
193 }
194 #endif
195 }
196
197 } // namespace OHOS::Ace::Framework
198