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 "core/components/tool_bar/tool_bar_item_element.h"
17
18 #include "base/geometry/dimension.h"
19 #include "base/geometry/size.h"
20 #include "core/components/tool_bar/render_tool_bar_item.h"
21 #include "core/event/ace_event_helper.h"
22 #include "core/pipeline/base/constants.h"
23
24 namespace OHOS::Ace {
25
Prepare(const WeakPtr<Element> & parent)26 void ToolBarItemElement::Prepare(const WeakPtr<Element>& parent)
27 {
28 RenderElement::Prepare(parent);
29 if (renderNode_) {
30 auto renderToolBarItem = AceType::DynamicCast<RenderToolBarItem>(renderNode_);
31 if (renderToolBarItem) {
32 renderToolBarItem->Initialize();
33 renderToolBarItem->SetTargetMenuCallBack(
34 [weak = WeakClaim(this)](const Offset& leftTop, const Offset& rightBottom) {
35 auto toolBarItemElement = weak.Upgrade();
36 if (toolBarItemElement) {
37 toolBarItemElement->OnTargetCallback(leftTop, rightBottom);
38 }
39 });
40 }
41 }
42 }
43
Update()44 void ToolBarItemElement::Update()
45 {
46 if (popup_) {
47 popup_->ClearAllOptions();
48 popup_ = nullptr;
49 }
50 RefPtr<ToolBarItemComponent> toolBarItemComponent = AceType::DynamicCast<ToolBarItemComponent>(component_);
51 if (!toolBarItemComponent) {
52 LOGE("ToolBarItemElement::Update: get ToolBarItemComponent failed!");
53 return;
54 }
55 isEndItem_ = toolBarItemComponent->GetIsEndItem();
56 if (isEndItem_) {
57 optionChildrenCallBack_ = toolBarItemComponent->GetOptionChildrenCallBack();
58 if (optionChildrenCallBack_ && renderNode_) {
59 auto renderToolBarItem = AceType::DynamicCast<RenderToolBarItem>(renderNode_);
60 if (renderToolBarItem) {
61 InitSelectPopup();
62 renderToolBarItem->Initialize();
63 }
64 }
65 }
66 SoleChildElement::Update();
67 }
68
InitSelectPopup()69 void ToolBarItemElement::InitSelectPopup()
70 {
71 if (!popup_) {
72 popup_ = AceType::MakeRefPtr<SelectPopupComponent>();
73 popup_->InitTheme(GetThemeManager());
74 }
75 if (optionChildrenCallBack_) {
76 std::list<RefPtr<Component>> children = optionChildrenCallBack_();
77 if (children.empty()) {
78 return;
79 }
80 for (const auto& pos : children) {
81 RefPtr<OptionComponent> option = AceType::DynamicCast<OptionComponent>(pos);
82 if (option) {
83 option->InitTheme(GetThemeManager());
84 option->SetSelectable(false);
85 popup_->AppendSelectOption(option);
86 }
87 }
88 popup_->SetOptionClickedCallback([weak = WeakClaim(this)](std::size_t index) {
89 auto refPtr = weak.Upgrade();
90 if (!refPtr) {
91 return;
92 }
93 refPtr->OnOptionCallback(index);
94 });
95 }
96 }
97
OnOptionCallback(std::size_t index)98 void ToolBarItemElement::OnOptionCallback(std::size_t index)
99 {
100 if (popup_) {
101 auto option = popup_->GetSelectOption(index);
102 if (!option) {
103 LOGE("option of the index is null.");
104 return;
105 }
106 auto onClick = AceAsyncEvent<void()>::Create(option->GetClickEventForToolBarItem(), context_);
107 if (onClick) {
108 onClick();
109 }
110 }
111 }
112
OnTargetCallback(const Offset & leftTop,const Offset & rightBottom)113 void ToolBarItemElement::OnTargetCallback(const Offset& leftTop, const Offset& rightBottom)
114 {
115 auto context = context_.Upgrade();
116 if (!context) {
117 LOGE("context is null.");
118 return;
119 }
120
121 auto stack = context->GetLastStack();
122 if (!stack) {
123 LOGE("can not get last stack.");
124 return;
125 }
126
127 if (!popup_) {
128 LOGE("can not get popup component.");
129 return;
130 }
131 popup_->ShowDialog(stack, leftTop, rightBottom, false);
132 }
133
OnFocus()134 void ToolBarItemElement::OnFocus()
135 {
136 const auto& renderToolBarItem = AceType::DynamicCast<RenderToolBarItem>(renderNode_);
137 if (!renderToolBarItem) {
138 return;
139 }
140 renderToolBarItem->ChangeStatus(RenderStatus::FOCUS);
141 renderToolBarItem->SetFocusEventFlag(true);
142 renderToolBarItem->MarkNeedLayout();
143 }
144
OnBlur()145 void ToolBarItemElement::OnBlur()
146 {
147 const auto& renderToolBarItem = AceType::DynamicCast<RenderToolBarItem>(renderNode_);
148 if (!renderToolBarItem) {
149 return;
150 }
151 renderToolBarItem->SetFocusEventFlag(false);
152 renderToolBarItem->MarkNeedLayout();
153 auto focusAnimation = renderToolBarItem->GetFocusAnimation();
154 if (!focusAnimation) {
155 return;
156 }
157 focusAnimation->CancelFocusAnimation();
158 }
159
OnClick()160 void ToolBarItemElement::OnClick()
161 {
162 const auto& renderToolBarItem = AceType::DynamicCast<RenderToolBarItem>(renderNode_);
163 if (!renderToolBarItem) {
164 return;
165 }
166 renderToolBarItem->HandleClickEvent();
167 }
168
169 } // namespace OHOS::Ace