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