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_panel.h"
17
18 #include "base/utils/string_utils.h"
19 #include "frameworks/bridge/common/utils/utils.h"
20
21 namespace OHOS::Ace::Framework {
22 namespace {
23
24 template<typename T>
ConvertStrToEnum(const char * key,const LinearMapNode<T> * map,size_t length,T defaultValue)25 inline T ConvertStrToEnum(const char* key, const LinearMapNode<T>* map, size_t length, T defaultValue)
26 {
27 int64_t index = BinarySearchFindIndex(map, length, key);
28 return index != -1 ? map[index].value : defaultValue;
29 }
30
31 } // namespace
32
DOMPanel(NodeId nodeId,const std::string & nodeName)33 DOMPanel::DOMPanel(NodeId nodeId, const std::string& nodeName) : DOMNode(nodeId, nodeName)
34 {
35 panelChild_ = AceType::MakeRefPtr<PanelComponent>(std::to_string(nodeId), nodeName);
36 if (IsRightToLeft()) {
37 panelChild_->SetTextDirection(TextDirection::RTL);
38 }
39 }
40
PrepareSpecializedComponent()41 void DOMPanel::PrepareSpecializedComponent()
42 {
43 // adjust panel mode
44 if (type_ == PanelType::TEMP_DISPLAY && mode_ == PanelMode::MINI) {
45 mode_ = PanelMode::HALF;
46 } else if (type_ == PanelType::MINI_BAR && mode_ == PanelMode::HALF) {
47 mode_ = PanelMode::MINI;
48 }
49 panelChild_->SetPanelMode(mode_);
50 panelChild_->SetPanelType(type_);
51 panelChild_->SetHasDragBar(hasDragBar_);
52 panelChild_->SetMiniHeight(miniHeight_);
53 panelChild_->SetHalfHeight(halfHeight_);
54 panelChild_->SetFullHeight(fullHeight_);
55 if (declaration_) {
56 panelChild_->SetHasBoxStyle(declaration_->HasBoxStyle());
57 panelChild_->SetHasDecorationStyle(declaration_->HasDecorationStyle());
58 panelChild_->SetHasBackgroundColor(declaration_->HasBackGroundColor());
59 panelChild_->SetHasBorderStyle(declaration_->HasBorderStyle());
60 }
61 if (boxComponent_) {
62 panelChild_->SetBoxStyle(boxComponent_);
63 } else {
64 boxComponent_ = AceType::MakeRefPtr<BoxComponent>();
65 panelChild_->SetBoxStyle(boxComponent_);
66 }
67 }
68
SetSpecializedAttr(const std::pair<std::string,std::string> & attr)69 bool DOMPanel::SetSpecializedAttr(const std::pair<std::string, std::string>& attr)
70 {
71 const LinearMapNode<void (*)(const std::string&, DOMPanel&)> specialAttrSetters[] = {
72 { DOM_PANEL_ATTR_DRAG_BAR,
73 [](const std::string& val, DOMPanel& panel) { panel.hasDragBar_ = StringToBool(val); } },
74 { DOM_PANEL_ATTR_FULL_HEIGHT,
75 [](const std::string& val, DOMPanel& panel) {
76 panel.fullHeight_.second = true;
77 panel.fullHeight_.first = StringToDimension(val);
78 } },
79 { DOM_PANEL_ATTR_HALF_HEIGHT,
80 [](const std::string& val, DOMPanel& panel) {
81 panel.halfHeight_.second = true;
82 panel.halfHeight_.first = StringToDimension(val);
83 } },
84 { DOM_PANEL_ATTR_MIN_HEIGHT,
85 [](const std::string& val, DOMPanel& panel) {
86 panel.miniHeight_.second = true;
87 panel.miniHeight_.first = StringToDimension(val);
88 } },
89 { DOM_PANEL_ATTR_MODE,
90 [](const std::string& val, DOMPanel& panel) {
91 const LinearMapNode<PanelMode> modeTable[] = {
92 { "full", PanelMode::FULL },
93 { "half", PanelMode::HALF },
94 { "mini", PanelMode::MINI },
95 };
96 panel.mode_ = ConvertStrToEnum(val.c_str(), modeTable, ArraySize(modeTable), PanelMode::FULL);
97 } },
98 { DOM_SHOW, [](const std::string& val, DOMPanel& panel) { panel.isShow_ = StringToBool(val); } },
99 { DOM_PANEL_ATTR_TYPE,
100 [](const std::string& val, DOMPanel& panel) {
101 const LinearMapNode<PanelType> typeTable[] = {
102 { "foldable", PanelType::FOLDABLE_BAR },
103 { "minibar", PanelType::MINI_BAR },
104 { "temporary", PanelType::TEMP_DISPLAY },
105 };
106 panel.type_ = ConvertStrToEnum(val.c_str(), typeTable, ArraySize(typeTable), PanelType::FOLDABLE_BAR);
107 } },
108 };
109 auto operatorIter = BinarySearchFindIndex(specialAttrSetters, ArraySize(specialAttrSetters), attr.first.c_str());
110 if (operatorIter != -1) {
111 specialAttrSetters[operatorIter].value(attr.second, *this);
112 return true;
113 } else {
114 return false;
115 }
116 }
117
CallSpecializedMethod(const std::string & method,const std::string & args)118 void DOMPanel::CallSpecializedMethod(const std::string& method, const std::string& args)
119 {
120 if (method == DOM_PANEL_METHOD_SHOW) {
121 const auto& controller = panelChild_->GetPanelController();
122 if (!controller) {
123 return;
124 }
125 controller->ShowPanel();
126 } else if (method == DOM_DIALOG_METHOD_CLOSE) {
127 const auto& controller = panelChild_->GetPanelController();
128 if (!controller) {
129 return;
130 }
131 controller->ClosePanel();
132 } else {
133 LOGW("No method match in panel.");
134 }
135 }
136
OnChildNodeAdded(const RefPtr<DOMNode> & child,int32_t slot)137 void DOMPanel::OnChildNodeAdded(const RefPtr<DOMNode>& child, int32_t slot)
138 {
139 if (!display_) {
140 display_ = AceType::MakeRefPtr<DisplayComponent>(child->GetRootComponent());
141 }
142 display_->SetVisible(isShow_ ? VisibleType::VISIBLE : VisibleType::GONE);
143 if (declaration_) {
144 auto& opacityStyle = static_cast<CommonOpacityStyle&>(declaration_->GetStyle(StyleTag::COMMON_OPACITY_STYLE));
145 if (opacityStyle.IsValid()) {
146 display_->SetOpacity(opacityStyle.opacity);
147 }
148 }
149 panelChild_->SetChild(display_);
150 }
151
OnChildNodeRemoved(const RefPtr<DOMNode> & child)152 void DOMPanel::OnChildNodeRemoved(const RefPtr<DOMNode>& child)
153 {
154 panelChild_->SetChild(nullptr);
155 }
156
AddSpecializedEvent(int32_t pageId,const std::string & event)157 bool DOMPanel::AddSpecializedEvent(int32_t pageId, const std::string& event)
158 {
159 if (event == DOM_PANEL_EVENT_SIZE_CHANGED) {
160 panelChild_->SetOnSizeChanged(EventMarker(GetNodeIdForEvent(), event, pageId));
161 return true;
162 }
163 return false;
164 }
165
CompositeSpecializedComponent(const std::vector<RefPtr<SingleChild>> & components)166 RefPtr<Component> DOMPanel::CompositeSpecializedComponent(const std::vector<RefPtr<SingleChild>>& components)
167 {
168 auto box = AceType::MakeRefPtr<BoxComponent>();
169 box->SetChild(panelChild_);
170 return box;
171 }
172
173 } // namespace OHOS::Ace::Framework
174