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