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_grid_container.h"
17 
18 #include "core/components/common/layout/grid_system_manager.h"
19 #include "frameworks/bridge/common/dom/dom_grid_row.h"
20 #include "frameworks/bridge/common/dom/dom_reflect_map.h"
21 #include "frameworks/bridge/common/utils/utils.h"
22 
23 namespace OHOS::Ace::Framework {
24 
DomGridContainer(NodeId nodeId,const std::string & nodeName)25 DomGridContainer::DomGridContainer(NodeId nodeId, const std::string& nodeName) : DOMDiv(nodeId, nodeName)
26 {
27     direction_ = DOM_FLEX_COLUMN;
28 }
29 
GetSpecializedComponent()30 RefPtr<Component> DomGridContainer::GetSpecializedComponent()
31 {
32     if (!gridContainerInfo_) {
33         gridContainerInfo_ = infoBuilder_.Build();
34         boxComponent_->SetGridLayoutInfo(gridContainerInfo_);
35     }
36     return DOMDiv::GetSpecializedComponent();
37 }
38 
OnChildNodeAdded(const RefPtr<DOMNode> & child,int32_t slot)39 void DomGridContainer::OnChildNodeAdded(const RefPtr<DOMNode>& child, int32_t slot)
40 {
41     ACE_DCHECK(child);
42     DOMDiv::OnChildNodeAdded(child, slot);
43     auto gridRow = AceType::DynamicCast<DomGridRow>(child);
44     if (gridRow) {
45         gridRow->SetParentGridInfo(gridContainerInfo_);
46     }
47 }
48 
OnChildNodeRemoved(const RefPtr<DOMNode> & child)49 void DomGridContainer::OnChildNodeRemoved(const RefPtr<DOMNode>& child)
50 {
51     ACE_DCHECK(child);
52     DOMDiv::OnChildNodeRemoved(child);
53     auto gridRow = AceType::DynamicCast<DomGridRow>(child);
54     if (gridRow) {
55         gridRow->SetParentGridInfo(nullptr);
56     }
57 }
58 
CallSpecializedMethod(const std::string & method,const std::string & args)59 void DomGridContainer::CallSpecializedMethod(const std::string& method, const std::string& args)
60 {
61     std::string result;
62     if (method == DOM_GRID_CONTAINER_GET_COLUMNS) {
63         result = std::to_string(gridContainerInfo_->GetColumns());
64     } else if (method == DOM_GRID_CONTAINER_GET_COLUMN_WIDTH) {
65         result = std::to_string(gridContainerInfo_->GetColumnWidth());
66     } else if (method == DOM_GRID_CONTAINER_GET_GUTTER_WIDTH) {
67         auto dipScale = GridSystemManager::GetInstance().GetDipScale();
68         result = std::to_string(gridContainerInfo_->GetGutterWidth().ConvertToPx(dipScale));
69     } else if (method == DOM_GRID_CONTAINER_GET_SIZE_TYPE) {
70         auto sizeType = gridContainerInfo_->GetSizeType();
71         result.append("\"");
72         if (sizeType == GridSizeType::LG) {
73             result.append(DOM_GRID_SIZE_TYPE_LG);
74         } else if (sizeType == GridSizeType::MD) {
75             result.append(DOM_GRID_SIZE_TYPE_MD);
76         } else if (sizeType == GridSizeType::SM) {
77             result.append(DOM_GRID_SIZE_TYPE_SM);
78         } else if (sizeType == GridSizeType::XS) {
79             result.append(DOM_GRID_SIZE_TYPE_XS);
80         }
81         result.append("\"");
82     } else {
83         return;
84     }
85     std::unique_ptr<JsonValue> argsValue = JsonUtil::ParseJsonString(args);
86     if (!argsValue || !argsValue->IsArray() || argsValue->GetArraySize() != 1) {
87         LOGW("Image animator parse args error");
88         return;
89     }
90     auto callbackId = argsValue->GetArrayItem(0)->GetString();
91     auto content = pipelineContext_.Upgrade();
92     if (!content) {
93         return;
94     }
95     content->SendCallbackMessageToFrontend(callbackId, result);
96 }
97 
SetSpecializedAttr(const std::pair<std::string,std::string> & attr)98 bool DomGridContainer::SetSpecializedAttr(const std::pair<std::string, std::string>& attr)
99 {
100     static const LinearMapNode<void (*)(const std::string&, DomGridContainer&)> attrOperators[] {
101         { DOM_GRID_CONTAINER_COLUMNS,
102             [](const std::string& value, DomGridContainer& container) {
103                 container.infoBuilder_.SetColumns(StringUtils::StringToInt(value));
104             } },
105         { DOM_GRID_CONTAINER_TEMPLATE,
106             [](const std::string& value, DomGridContainer& container) {
107                 auto templateType = GridTemplateType::NORMAL;
108                 auto iter = GridTemplateMap.find(value);
109                 if (iter != GridTemplateMap.end()) {
110                     templateType = iter->second;
111                 }
112                 container.infoBuilder_.SetGridTemplateType(templateType);
113             } },
114         { DOM_GRID_CONTAINER_GUTTER,
115             [](const std::string& value, DomGridContainer& container) {
116                 container.infoBuilder_.SetGutterWidth(Dimension(StringUtils::StringToDouble(value), DimensionUnit::PX));
117             } },
118         { DOM_GRID_CONTAINER_GUTTER_WIDTH,
119             [](const std::string& value, DomGridContainer& container) {
120                 container.infoBuilder_.SetGutterWidth(Dimension(StringUtils::StringToDouble(value), DimensionUnit::PX));
121             } },
122         { DOM_GRID_CONTAINER_SIZE_TYPE,
123             [](const std::string& value, DomGridContainer& container) {
124                 auto sizeType = GridSizeType::UNDEFINED;
125                 auto iter = GridSizeTypeMap.find(value);
126                 if (iter != GridSizeTypeMap.end()) {
127                     sizeType = iter->second;
128                 }
129                 container.infoBuilder_.SetSizeType(sizeType);
130             } },
131     };
132 
133     auto operatorIter = BinarySearchFindIndex(attrOperators, ArraySize(attrOperators), attr.first.c_str());
134     if (operatorIter != -1) {
135         attrOperators[operatorIter].value(attr.second, *this);
136         return true;
137     }
138     return false;
139 }
140 
SetSpecializedStyle(const std::pair<std::string,std::string> & style)141 bool DomGridContainer::SetSpecializedStyle(const std::pair<std::string, std::string>& style)
142 {
143     static const std::list<const char*> notSupportStyles {
144         DOM_FLEX_DIRECTION,
145         DOM_GRID_COLUMN_END,
146         DOM_GRID_COLUMN_START,
147         DOM_GRID_COLUMN_GAP,
148         DOM_GRID_ROW_END,
149         DOM_GRID_ROW_START,
150         DOM_GRID_ROW_GAP,
151         DOM_GRID_TEMPLATE_COLUMNS,
152         DOM_GRID_TEMPLATE_ROWS,
153     };
154 
155     if (std::find(notSupportStyles.begin(), notSupportStyles.end(), style.first.c_str()) != notSupportStyles.end()) {
156         // not support
157         return true;
158     }
159     if (style.first == DOM_MARGIN_LEFT) {
160         infoBuilder_.SetMarginLeft(StringToDimension(style.second));
161         return DOMNode::SetSpecializedStyle(style);
162     } else if (style.first == DOM_MARGIN_RIGHT) {
163         infoBuilder_.SetMarginRight(StringToDimension(style.second));
164         return DOMNode::SetSpecializedStyle(style);
165     } else if (style.first == DOM_MARGIN_START) {
166         if (IsRightToLeft()) {
167             infoBuilder_.SetMarginRight(StringToDimension(style.second));
168         } else {
169             infoBuilder_.SetMarginLeft(StringToDimension(style.second));
170         }
171         return DOMNode::SetSpecializedStyle(style);
172     } else if (style.first == DOM_MARGIN_END) {
173         if (IsRightToLeft()) {
174             infoBuilder_.SetMarginLeft(StringToDimension(style.second));
175         } else {
176             infoBuilder_.SetMarginRight(StringToDimension(style.second));
177         }
178         return DOMNode::SetSpecializedStyle(style);
179     } else if (style.first == DOM_PADDING_LEFT) {
180         infoBuilder_.SetPaddingLeft(StringToDimension(style.second));
181         return DOMNode::SetSpecializedStyle(style);
182     } else if (style.first == DOM_PADDING_RIGHT) {
183         infoBuilder_.SetPaddingRight(StringToDimension(style.second));
184         return DOMNode::SetSpecializedStyle(style);
185     } else if (style.first == DOM_PADDING_START) {
186         if (IsRightToLeft()) {
187             infoBuilder_.SetPaddingRight(StringToDimension(style.second));
188         } else {
189             infoBuilder_.SetPaddingLeft(StringToDimension(style.second));
190         }
191         return DOMNode::SetSpecializedStyle(style);
192     } else if (style.first == DOM_PADDING_END) {
193         if (IsRightToLeft()) {
194             infoBuilder_.SetPaddingLeft(StringToDimension(style.second));
195         } else {
196             infoBuilder_.SetPaddingRight(StringToDimension(style.second));
197         }
198         return DOMNode::SetSpecializedStyle(style);
199     }
200     return DOMDiv::SetSpecializedStyle(style);
201 }
202 
203 } // namespace OHOS::Ace::Framework
204