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