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