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