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