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_list_item_group.h"
17
18 #include "base/log/event_report.h"
19 #include "core/components/focus_animation/focus_animation_theme.h"
20 #include "frameworks/bridge/common/dom/dom_list.h"
21 #include "frameworks/bridge/common/utils/utils.h"
22
23 namespace OHOS::Ace::Framework {
24 namespace {
25
26 constexpr int32_t DEFAULT_NODE_INDEX = -1;
27
28 } // namespace
29
DOMListItemGroup(NodeId nodeId,const std::string & nodeName,int32_t itemIndex)30 DOMListItemGroup::DOMListItemGroup(NodeId nodeId, const std::string& nodeName, int32_t itemIndex)
31 : DOMListItem(nodeId, nodeName, itemIndex)
32 {}
33
SetSpecializedAttr(const std::pair<std::string,std::string> & attr)34 bool DOMListItemGroup::SetSpecializedAttr(const std::pair<std::string, std::string>& attr)
35 {
36 auto parent = AceType::DynamicCast<DOMList>(parentNode_.Upgrade());
37 if (!parent) {
38 return false;
39 }
40 if (attr.first == DOM_LISTITEM_TYPE) {
41 type_ = attr.second;
42 return true;
43 }
44 if (attr.first == DOM_LISTITEM_CARD_TYPE) {
45 isCard_ = StringToBool(attr.second);
46 return true;
47 }
48 if (attr.first == DOM_LISTITEM_CARD_BLUR) {
49 isCardBlur_ = StringToBool(attr.second);
50 return true;
51 }
52 if (attr.first == DOM_ID) {
53 // Do not return true, ID still need be handled outside.
54 groupId_ = attr.second;
55 }
56 return false;
57 }
58
SetCardThemeAttrs()59 void DOMListItemGroup::SetCardThemeAttrs()
60 {
61 cardTheme_ = GetTheme<CardTheme>();
62 if (!cardTheme_) {
63 EventReport::SendComponentException(ComponentExcepType::GET_THEME_ERR);
64 return;
65 }
66 if (boxComponent_) {
67 if (isCard_) {
68 RefPtr<Decoration> backDecoration = boxComponent_->GetBackDecoration();
69 if (!backDecoration) {
70 RefPtr<Decoration> decoration = AceType::MakeRefPtr<Decoration>();
71 decoration->SetBackgroundColor(cardTheme_->GetBackgroundColor());
72 decoration->SetBorderRadius(Radius(cardTheme_->GetBorderRadius()));
73 boxComponent_->SetBackDecoration(decoration);
74 }
75 if (backDecoration && !backDecoration->GetBorder().HasRadius()) {
76 backDecoration->SetBorderRadius(Radius(cardTheme_->GetBorderRadius()));
77 }
78 if (backDecoration && (backDecoration->GetBackgroundColor() == Color::TRANSPARENT)) {
79 backDecoration->SetBackgroundColor(cardTheme_->GetBackgroundColor());
80 }
81 if (isCardBlur_) {
82 RefPtr<Decoration> frontDecoration = boxComponent_->GetFrontDecoration();
83 if (!frontDecoration) {
84 RefPtr<Decoration> frontDecoration = AceType::MakeRefPtr<Decoration>();
85 frontDecoration->SetBlurRadius(cardTheme_->GetBlurRadius());
86 boxComponent_->SetFrontDecoration(frontDecoration);
87 }
88 if (frontDecoration && !frontDecoration->GetBlurRadius().IsValid()) {
89 frontDecoration->SetBlurRadius(cardTheme_->GetBlurRadius());
90 }
91 } else {
92 RefPtr<Decoration> frontDecoration = boxComponent_->GetFrontDecoration();
93 if (frontDecoration && frontDecoration->GetBlurRadius().IsValid()) {
94 frontDecoration->SetBlurRadius(Dimension());
95 }
96 }
97 }
98 }
99 }
100
AddSpecializedEvent(int32_t pageId,const std::string & event)101 bool DOMListItemGroup::AddSpecializedEvent(int32_t pageId, const std::string& event)
102 {
103 static const LinearMapNode<void (*)(int32_t, DOMListItemGroup&)> eventOperators[] = {
104 {
105 DOM_LIST_ITEM_GROUP_EVENT_GROUPCLICK,
106 [](int32_t pageId, DOMListItemGroup& listItemGroup) {
107 listItemGroup.onClicked_ =
108 EventMarker(listItemGroup.GetNodeIdForEvent(), DOM_LIST_ITEM_GROUP_EVENT_GROUPCLICK, pageId);
109 },
110 },
111 {
112 DOM_LIST_ITEM_GROUP_EVENT_GROUPCOLLAPSE,
113 [](int32_t pageId, DOMListItemGroup& listItemGroup) {
114 listItemGroup.onCollapse_ =
115 EventMarker(listItemGroup.GetNodeIdForEvent(), DOM_LIST_ITEM_GROUP_EVENT_GROUPCOLLAPSE, pageId);
116 },
117 },
118 {
119 DOM_LIST_ITEM_GROUP_EVENT_GROUPEXPAND,
120 [](int32_t pageId, DOMListItemGroup& listItemGroup) {
121 listItemGroup.onExpand_ =
122 EventMarker(listItemGroup.GetNodeIdForEvent(), DOM_LIST_ITEM_GROUP_EVENT_GROUPEXPAND, pageId);
123 },
124 },
125 };
126 auto iter = BinarySearchFindIndex(eventOperators, ArraySize(eventOperators), event.c_str());
127 if (iter != -1) {
128 eventOperators[iter].value(pageId, *this);
129 return true;
130 }
131 return false;
132 }
133
OnChildNodeAdded(const RefPtr<DOMNode> & child,int32_t slot)134 void DOMListItemGroup::OnChildNodeAdded(const RefPtr<DOMNode>& child, int32_t slot)
135 {
136 if (child) {
137 const auto& childComponent = child->GetRootComponent();
138 listItemGroupComponent_->AppendChild(childComponent);
139 }
140 }
141
OnChildNodeRemoved(const RefPtr<DOMNode> & child)142 void DOMListItemGroup::OnChildNodeRemoved(const RefPtr<DOMNode>& child)
143 {
144 if (child) {
145 const auto& childComponent = child->GetRootComponent();
146 listItemGroupComponent_->RemoveChild(childComponent);
147 }
148 }
149
PrepareSpecializedComponent()150 void DOMListItemGroup::PrepareSpecializedComponent()
151 {
152 if (!listItemGroupComponent_) {
153 listItemGroupComponent_ = AceType::MakeRefPtr<ListItemGroupComponent>(type_);
154 }
155
156 ResetInitializedStyle();
157 listItemGroupComponent_->SetGroupId(groupId_);
158 listItemGroupComponent_->SetType(type_);
159 listItemGroupComponent_->SetFlags(LIST_ITEM_FLAG_FROM_CHILD);
160 listItemGroupComponent_->SetTopLeftRadius(topLeftRadius_);
161 listItemGroupComponent_->SetTopRightRadius(topRightRadius_);
162 listItemGroupComponent_->SetBottomLeftRadius(bottomLeftRadius_);
163 listItemGroupComponent_->SetBottomRightRadius(bottomRightRadius_);
164 listItemGroupComponent_->SetOnClicked(onClicked_);
165 listItemGroupComponent_->SetOnCollapse(onCollapse_);
166 listItemGroupComponent_->SetOnExpand(onExpand_);
167
168 auto domList = AceType::DynamicCast<DOMList>(parentNode_.Upgrade());
169 if (domList) {
170 listItemGroupComponent_->SetDirection(domList->GetDirection());
171 }
172 }
173
ResetInitializedStyle()174 void DOMListItemGroup::ResetInitializedStyle()
175 {
176 if (!listItemGroupComponent_) {
177 EventReport::SendComponentException(ComponentExcepType::LIST_ITEM_ERR);
178 return;
179 }
180 RefPtr<FocusAnimationTheme> theme = GetTheme<FocusAnimationTheme>();
181 if (theme) {
182 listItemGroupComponent_->SetFocusAnimationColor(theme->GetColor());
183 }
184 if (isCard_ || (isCard_ && isCardBlur_)) {
185 SetCardThemeAttrs();
186 }
187 }
188
GetSpecializedComponent()189 RefPtr<Component> DOMListItemGroup::GetSpecializedComponent()
190 {
191 SetCardThemeAttrs();
192 return listItemGroupComponent_;
193 }
194
CompositeSpecializedComponent(const std::vector<RefPtr<SingleChild>> & components)195 RefPtr<Component> DOMListItemGroup::CompositeSpecializedComponent(const std::vector<RefPtr<SingleChild>>& components)
196 {
197 return DOMNode::CompositeSpecializedComponent(components);
198 }
199
Update()200 void DOMListItemGroup::Update()
201 {
202 auto pipelineContext = pipelineContext_.Upgrade();
203 if (pipelineContext) {
204 pipelineContext->ScheduleUpdate(GetRootComponent());
205 }
206 }
207
GetItemIndex() const208 int32_t DOMListItemGroup::GetItemIndex() const
209 {
210 if (listItemGroupComponent_) {
211 return listItemGroupComponent_->GetIndex();
212 }
213 return DEFAULT_NODE_INDEX;
214 }
215
216 } // namespace OHOS::Ace::Framework
217