1 /*
2  * Copyright (c) 2024 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_ng/pattern/navigation/tool_bar_pattern.h"
17 
18 #include "base/i18n/localization.h"
19 #include "core/common/agingadapation/aging_adapation_dialog_theme.h"
20 #include "core/common/agingadapation/aging_adapation_dialog_util.h"
21 #include "core/components_ng/pattern/image/image_layout_property.h"
22 #include "core/components_ng/pattern/image/image_pattern.h"
23 #include "core/components_ng/pattern/navigation/tool_bar_node.h"
24 #include "core/components_ng/pattern/text/text_layout_property.h"
25 #include "core/components_ng/pattern/text/text_pattern.h"
26 
27 namespace OHOS::Ace::NG {
SetToolbarOptions(NavigationToolbarOptions && opt)28 void NavToolbarPattern::SetToolbarOptions(NavigationToolbarOptions&& opt)
29 {
30     if (opt == options_) {
31         return;
32     }
33 
34     options_ = std::move(opt);
35     auto host = GetHost();
36     CHECK_NULL_VOID(host);
37     UpdateBackgroundStyle(host);
38 }
39 
UpdateBackgroundStyle(RefPtr<FrameNode> & host)40 void NavToolbarPattern::UpdateBackgroundStyle(RefPtr<FrameNode>& host)
41 {
42     auto renderContext = host->GetRenderContext();
43     CHECK_NULL_VOID(renderContext);
44     if (options_.bgOptions.color.has_value()) {
45         renderContext->UpdateBackgroundColor(options_.bgOptions.color.value());
46     } else {
47         SetDefaultBackgroundColorIfNeeded(host);
48     }
49     if (options_.bgOptions.blurStyle.has_value()) {
50         BlurStyleOption blur;
51         blur.blurStyle = options_.bgOptions.blurStyle.value();
52         renderContext->UpdateBackBlurStyle(blur);
53     } else {
54         renderContext->ResetBackBlurStyle();
55     }
56 }
57 
OnModifyDone()58 void NavToolbarPattern::OnModifyDone()
59 {
60     auto hostNode = AceType::DynamicCast<NavToolbarNode>(GetHost());
61     CHECK_NULL_VOID(hostNode);
62     auto containerNode = AceType::DynamicCast<FrameNode>(hostNode->GetToolbarContainerNode());
63     CHECK_NULL_VOID(containerNode);
64     auto gestureHub = containerNode->GetOrCreateGestureEventHub();
65     CHECK_NULL_VOID(gestureHub);
66     auto context = PipelineBase::GetCurrentContext();
67     CHECK_NULL_VOID(context);
68     float scale = context->GetFontScale();
69     if (LessNotEqual(scale, AgingAdapationDialogUtil::GetDialogBigFontSizeScale())) {
70         return;
71     }
72     InitLongPressEvent(gestureHub);
73     InitDragEvent(gestureHub);
74     auto accessibilityProperty = containerNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
75     CHECK_NULL_VOID(accessibilityProperty);
76     accessibilityProperty->SetAccessibilityLevel(AccessibilityProperty::Level::NO_STR);
77 }
78 
InitLongPressEvent(const RefPtr<GestureEventHub> & gestureHub)79 void NavToolbarPattern::InitLongPressEvent(const RefPtr<GestureEventHub>& gestureHub)
80 {
81     auto longPressTask = [weak = WeakClaim(this)](GestureEvent& info) {
82         auto toolBarPattern = weak.Upgrade();
83         CHECK_NULL_VOID(toolBarPattern);
84         toolBarPattern->HandleLongPressEvent(info);
85     };
86     auto longPressEvent = AceType::MakeRefPtr<LongPressEvent>(std::move(longPressTask));
87     gestureHub->SetLongPressEvent(longPressEvent);
88 
89     auto longPressRecognizer = gestureHub->GetLongPressRecognizer();
90     CHECK_NULL_VOID(longPressRecognizer);
91     auto longPressActionEnd = [weak = WeakClaim(this)](GestureEvent& info) {
92         auto toolBarPattern = weak.Upgrade();
93         CHECK_NULL_VOID(toolBarPattern);
94         toolBarPattern->HandleLongPressActionEnd();
95     };
96     longPressRecognizer->SetOnActionEnd(longPressActionEnd);
97 }
98 
InitDragEvent(const RefPtr<GestureEventHub> & gestureHub)99 void NavToolbarPattern::InitDragEvent(const RefPtr<GestureEventHub>& gestureHub)
100 {
101     auto actionUpdateTask = [weak = WeakClaim(this)](const GestureEvent& info) {
102         auto toolBarPattern = weak.Upgrade();
103         CHECK_NULL_VOID(toolBarPattern);
104         auto hostNode = AceType::DynamicCast<NavToolbarNode>(toolBarPattern->GetHost());
105         CHECK_NULL_VOID(hostNode);
106         auto containerNode = AceType::DynamicCast<FrameNode>(hostNode->GetToolbarContainerNode());
107         CHECK_NULL_VOID(containerNode);
108         auto toolBarItemNode =
109             containerNode->FindChildByPosition(info.GetGlobalLocation().GetX(), info.GetGlobalLocation().GetY());
110         CHECK_NULL_VOID(toolBarItemNode);
111         auto index = containerNode->GetChildIndex(toolBarItemNode);
112         auto totalCount = containerNode->TotalChildCount();
113         if (toolBarPattern->dialogNode_ && index >= 0 && index < totalCount) {
114             if (!toolBarPattern->moveIndex_.has_value()) {
115                 toolBarPattern->moveIndex_ = index;
116             }
117 
118             if (toolBarPattern->moveIndex_ != index) {
119                 toolBarPattern->HandleLongPressActionEnd();
120                 toolBarPattern->moveIndex_ = index;
121                 auto barItemNode = AceType::DynamicCast<BarItemNode>(toolBarItemNode->GetFirstChild());
122                 CHECK_NULL_VOID(barItemNode);
123                 toolBarPattern->ShowDialogWithNode(barItemNode);
124             }
125         }
126     };
127 
128     auto dragEvent = MakeRefPtr<DragEvent>(nullptr, std::move(actionUpdateTask), nullptr, nullptr);
129     PanDirection panDirection = { .type = PanDirection::ALL };
130     gestureHub->SetDragEvent(dragEvent, panDirection, DEFAULT_PAN_FINGER, DEFAULT_PAN_DISTANCE);
131 }
132 
HandleLongPressEvent(const GestureEvent & info)133 void NavToolbarPattern::HandleLongPressEvent(const GestureEvent& info)
134 {
135     auto hostNode = AceType::DynamicCast<NavToolbarNode>(GetHost());
136     CHECK_NULL_VOID(hostNode);
137     auto containerNode = AceType::DynamicCast<FrameNode>(hostNode->GetToolbarContainerNode());
138     CHECK_NULL_VOID(containerNode);
139     auto toolBarItem =
140         containerNode->FindChildByPosition(info.GetGlobalLocation().GetX(), info.GetGlobalLocation().GetY());
141     CHECK_NULL_VOID(toolBarItem);
142     RefPtr<BarItemNode> barItemNode = AceType::DynamicCast<BarItemNode>(toolBarItem->GetFirstChild());
143     CHECK_NULL_VOID(barItemNode);
144     ShowDialogWithNode(barItemNode);
145 }
146 
HandleLongPressActionEnd()147 void NavToolbarPattern::HandleLongPressActionEnd()
148 {
149     CHECK_NULL_VOID(dialogNode_);
150     auto host = GetHost();
151     CHECK_NULL_VOID(host);
152     auto pipeline = host->GetContextRefPtr();
153     CHECK_NULL_VOID(pipeline);
154     auto overlayManager = pipeline->GetOverlayManager();
155     CHECK_NULL_VOID(overlayManager);
156     overlayManager->CloseDialog(dialogNode_);
157     dialogNode_ = nullptr;
158 }
159 
ShowDialogWithNode(const RefPtr<BarItemNode> & barItemNode)160 void NavToolbarPattern::ShowDialogWithNode(const RefPtr<BarItemNode>& barItemNode)
161 {
162     HandleLongPressActionEnd();
163     CHECK_NULL_VOID(barItemNode);
164     std::string message;
165     auto accessibilityProperty = barItemNode->GetAccessibilityProperty<AccessibilityProperty>();
166     CHECK_NULL_VOID(accessibilityProperty);
167     message = accessibilityProperty->GetAccessibilityText();
168     if (barItemNode->IsMoreItemNode()) {
169         auto theme = NavigationGetTheme();
170         CHECK_NULL_VOID(theme);
171         message = Localization::GetInstance()->GetEntryLetters("common.more");
172         if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
173             auto symbolNode = AceType::DynamicCast<FrameNode>(barItemNode->GetFirstChild());
174             CHECK_NULL_VOID(symbolNode);
175             dialogNode_ = AgingAdapationDialogUtil::ShowLongPressDialog(message, symbolNode);
176             return;
177         }
178         auto info = ImageSourceInfo("");
179         info.SetResourceId(theme->GetMoreResourceId());
180         dialogNode_ = AgingAdapationDialogUtil::ShowLongPressDialog(message, info);
181         return;
182     }
183     RefPtr<FrameNode> textNode = AceType::DynamicCast<FrameNode>(barItemNode->GetTextNode());
184     RefPtr<FrameNode> imageNode = AceType::DynamicCast<FrameNode>(barItemNode->GetIconNode());
185     if (textNode != nullptr) {
186         auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
187         CHECK_NULL_VOID(textLayoutProperty);
188         auto textValue = textLayoutProperty->GetContent();
189         if (!textValue.value().empty()) {
190             message = textValue.value();
191         }
192     }
193     if (imageNode != nullptr) {
194         if (imageNode->GetTag() == V2::SYMBOL_ETS_TAG) {
195             dialogNode_ = AgingAdapationDialogUtil::ShowLongPressDialog(message, imageNode);
196             return;
197         }
198         auto imageLayoutProperty = imageNode->GetLayoutProperty<ImageLayoutProperty>();
199         CHECK_NULL_VOID(imageLayoutProperty);
200         auto imageSourceInfo = imageLayoutProperty->GetImageSourceInfo().value_or(ImageSourceInfo());
201         dialogNode_ = AgingAdapationDialogUtil::ShowLongPressDialog(message, imageSourceInfo);
202         return;
203     }
204     auto imageSourceInfo = ImageSourceInfo("");
205     dialogNode_ = AgingAdapationDialogUtil::ShowLongPressDialog(message, imageSourceInfo);
206 }
207 
SetDefaultBackgroundColorIfNeeded(RefPtr<FrameNode> & host)208 void NavToolbarPattern::SetDefaultBackgroundColorIfNeeded(RefPtr<FrameNode>& host)
209 {
210     if (options_.bgOptions.color.has_value()) {
211         return;
212     }
213 
214     auto renderContext = host->GetRenderContext();
215     CHECK_NULL_VOID(renderContext);
216     auto theme = NavigationGetTheme();
217     CHECK_NULL_VOID(theme);
218     renderContext->UpdateBackgroundColor(theme->GetToolBarBgColor());
219 }
220 
OnColorConfigurationUpdate()221 void NavToolbarPattern::OnColorConfigurationUpdate()
222 {
223     auto host = GetHost();
224     CHECK_NULL_VOID(host);
225     UpdateBackgroundStyle(host);
226 }
227 } // namespace OHOS::Ace::NG
228