1 /*
2 * Copyright (c) 2021-2022 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_select.h"
17
18 #include "frameworks/bridge/common/dom/dom_option.h"
19 #include "frameworks/bridge/common/utils/utils.h"
20
21 namespace OHOS::Ace::Framework {
22
IsParentNavigation() const23 bool DOMSelect::IsParentNavigation() const
24 {
25 auto parent = GetParentNode();
26 if (!parent) {
27 return false;
28 }
29 return parent->GetTag() == DOM_NODE_TAG_NAVIGATION_BAR;
30 }
31
DOMSelect(NodeId nodeId,const std::string & nodeName)32 DOMSelect::DOMSelect(NodeId nodeId, const std::string& nodeName) : DOMNode(nodeId, nodeName)
33 {
34 selectComponent_ = AceType::MakeRefPtr<SelectComponent>();
35 tipText_ = AceType::MakeRefPtr<TextComponent>("");
36 selectComponent_->SetTipText(tipText_);
37 #if defined(PREVIEW)
38 selectComponent_->SetNodeId(nodeId);
39 #endif
40 }
41
ResetInitializedStyle()42 void DOMSelect::ResetInitializedStyle()
43 {
44 InitializeStyle();
45 }
46
InitializeStyle()47 void DOMSelect::InitializeStyle()
48 {
49 if (!selectComponent_) {
50 return;
51 }
52 selectComponent_->InitTheme(GetThemeManager());
53 theme_ = GetTheme<SelectTheme>();
54 if (theme_ && selectComponent_) {
55 selectComponent_->SetClickedColor(theme_->GetClickedColor());
56 selectComponent_->SetDisabledColor(theme_->GetDisabledColor());
57 selectComponent_->SetSelectedColor(theme_->GetSelectedColor());
58 selectComponent_->SetOptionSize(theme_->GetOptionSize());
59 selectComponent_->SetRRectSize(theme_->GetRRectSize());
60 selectComponent_->SetPopupBorderWidth(theme_->GetPopupBorderWidth());
61 selectComponent_->SetPopupShadowWidth(theme_->GetPopupShadowWidth());
62 selectComponent_->SetFontFamily(theme_->GetFontFamily());
63 selectComponent_->SetFontSize(theme_->GetFontSize());
64 selectComponent_->SetAllowScale(theme_->IsAllowScale());
65 selectComponent_->SetTextColor(theme_->GetFontColor());
66 selectComponent_->SetFontWeight(FontWeight::W500);
67 selectComponent_->SetTextDecoration(theme_->GetTextDecoration());
68 selectComponent_->SetBackgroundColor(Color::TRANSPARENT);
69 }
70 }
71
UpdateBoxSize(const CalcDimension & width,const CalcDimension & height)72 void DOMSelect::UpdateBoxSize(const CalcDimension& width, const CalcDimension& height)
73 {
74 if (!selectComponent_) {
75 return;
76 }
77
78 if (width.Unit() != DimensionUnit::PERCENT && height.Unit() != DimensionUnit::PERCENT) {
79 selectComponent_->SetInnerSize(width, height);
80 return;
81 }
82
83 if (width.Unit() == DimensionUnit::PERCENT && height.Unit() == DimensionUnit::PERCENT) {
84 DOMNode::UpdateBoxSize(width, height);
85 selectComponent_->SetInnerSize(100.0_pct, 100.0_pct);
86 return;
87 }
88
89 if (width.Unit() == DimensionUnit::PERCENT) {
90 DOMNode::UpdateBoxSize(width, height);
91 selectComponent_->SetInnerSize(100.0_pct, height);
92 return;
93 }
94
95 DOMNode::UpdateBoxSize(width, height);
96 selectComponent_->SetInnerSize(100.0_pct, 100.0_pct);
97 }
98
UpdateBoxPadding(const Edge & padding)99 void DOMSelect::UpdateBoxPadding(const Edge& padding)
100 {
101 if (!selectComponent_) {
102 return;
103 }
104
105 selectComponent_->SetInnerPadding(padding);
106 }
107
UpdateBoxBorder(const Border & border)108 void DOMSelect::UpdateBoxBorder(const Border& border)
109 {
110 if (!selectComponent_) {
111 return;
112 }
113
114 selectComponent_->SetInnerBorder(border);
115 }
116
AddSpecializedEvent(int32_t pageId,const std::string & event)117 bool DOMSelect::AddSpecializedEvent(int32_t pageId, const std::string& event)
118 {
119 if (event == DOM_CHANGE) {
120 onChanged_ = EventMarker(GetNodeIdForEvent(), event, pageId);
121 selectComponent_->SetOnChanged(onChanged_);
122 return true;
123 }
124 return false;
125 }
126
SetSpecializedStyle(const std::pair<std::string,std::string> & style)127 bool DOMSelect::SetSpecializedStyle(const std::pair<std::string, std::string>& style)
128 {
129 if (IsParentNavigation()) {
130 // not support style setting for navigation.
131 return true;
132 }
133
134 static const LinearMapNode<void (*)(const std::string&, const DOMSelect&, SelectComponent&)>
135 selectStyleOperators[] = {
136 { DOM_TEXT_ALLOW_SCALE, [](const std::string& val, const DOMSelect& node,
137 SelectComponent& select) { select.SetAllowScale(StringToBool(val)); } },
138 { DOM_BACKGROUND_COLOR, [](const std::string& val, const DOMSelect& node,
139 SelectComponent& select) { select.SetBackgroundColor(node.ParseColor(val)); } },
140 { DOM_TEXT_COLOR, [](const std::string& val, const DOMSelect& node,
141 SelectComponent& select) { select.SetTextColor(node.ParseColor(val)); } },
142 { DOM_TEXT_FONT_FAMILY, [](const std::string& val, const DOMSelect& node,
143 SelectComponent& select) { select.SetFontFamily(val); } },
144 { DOM_TEXT_FONT_SIZE,
145 [](const std::string& val, const DOMSelect& node, SelectComponent& select) {
146 select.SetFontSize(node.ParseDimension(val));
147 select.SetIsFontSetFlag(true);
148 } },
149 { DOM_TEXT_FONT_WEIGHT, [](const std::string& val, const DOMSelect& node,
150 SelectComponent& select) { select.SetFontWeight(ConvertStrToFontWeight(val)); } },
151 { DOM_TEXT_DECORATION,
152 [](const std::string& val, const DOMSelect& node, SelectComponent& select) {
153 select.SetTextDecoration(ConvertStrToTextDecoration(val));
154 } },
155 };
156 auto operatorIter =
157 BinarySearchFindIndex(selectStyleOperators, ArraySize(selectStyleOperators), style.first.c_str());
158 if (operatorIter != -1) {
159 selectStyleOperators[operatorIter].value(style.second, *this, *selectComponent_);
160 return true;
161 }
162 return false;
163 }
164
OnChildNodeAdded(const RefPtr<DOMNode> & child,int32_t slot)165 void DOMSelect::OnChildNodeAdded(const RefPtr<DOMNode>& child, int32_t slot)
166 {
167 if (!child || child->GetTag() != DOM_NODE_TAG_OPTION) {
168 LOGW("DOMSelect child is not tag node");
169 return;
170 }
171
172 auto option = AceType::DynamicCast<DOMOption>(child);
173 if (option) {
174 auto optionComponent = AceType::DynamicCast<OptionComponent>(option->GetSpecializedComponent());
175 if (!optionComponent) {
176 return;
177 }
178 if (!selectComponent_->GetSelectOptionCount() || optionComponent->GetSelected()) {
179 auto text = optionComponent->GetText();
180 if (text) {
181 tipText_->SetData(text->GetData());
182 } else {
183 tipText_->SetData("");
184 }
185 }
186 if (slot < 0) {
187 selectComponent_->AppendSelectOption(optionComponent);
188 } else {
189 selectComponent_->InsertSelectOption(optionComponent, static_cast<uint32_t>(slot));
190 }
191 }
192 }
193
OnChildNodeRemoved(const RefPtr<DOMNode> & child)194 void DOMSelect::OnChildNodeRemoved(const RefPtr<DOMNode>& child)
195 {
196 if (!child || !selectComponent_) {
197 return;
198 }
199
200 auto option = AceType::DynamicCast<OptionComponent>(child->GetSpecializedComponent());
201 if (!option) {
202 return;
203 }
204
205 selectComponent_->RemoveSelectOption(option);
206 }
207
PrepareSpecializedComponent()208 void DOMSelect::PrepareSpecializedComponent()
209 {
210 if (selectComponent_) {
211 selectComponent_->SetTextDirection((IsRightToLeft() ? TextDirection::RTL : TextDirection::LTR));
212 }
213 }
214
215 } // namespace OHOS::Ace::Framework
216