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