1 /*
2 * Copyright (c) 2023 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/app_bar/app_bar_view.h"
17 #include <cstdint>
18 #include "ui/base/geometry/dimension.h"
19 #include "ui/base/utils/utils.h"
20
21 #include "bridge/declarative_frontend/view_stack_processor.h"
22 #include "core/common/app_bar_helper.h"
23 #include "core/common/container.h"
24 #include "core/common/container_scope.h"
25 #include "core/components_ng/base/view_stack_processor.h"
26 #include "core/components_ng/event/focus_hub.h"
27 #include "core/components_ng/layout/layout_property.h"
28 #include "core/components_ng/pattern/app_bar/atomic_service_pattern.h"
29 #include "core/components_ng/pattern/button/button_layout_property.h"
30 #include "core/components_ng/pattern/button/button_pattern.h"
31 #include "core/components_ng/pattern/divider/divider_pattern.h"
32 #include "core/components_ng/pattern/linear_layout/linear_layout_property.h"
33 #include "core/components_ng/pattern/text/text_pattern.h"
34 #include "core/components_ng/pattern/app_bar/app_bar_utils.h"
35 #include "core/components_ng/base/inspector.h"
36
37 namespace OHOS::Ace::NG {
38 std::function<RefPtr<FrameNode>(NG::AppBarView* appBar, const RefPtr<FrameNode>& stage)>
39 AppBarView::appBarNodeBuilder_ = nullptr;
40 namespace {
41
42 constexpr int32_t ATOMIC_SERVICE_MENU_BAR_WIDTH = 96;
43 constexpr int32_t ATOMIC_SERVICE_MENU_BAR_MARGIN_RIGHT = 8;
44 constexpr int32_t ATOMIC_SERVICE_MENU_BAR_MARGIN_LEFT = 12;
45 constexpr int32_t INVALID_LISTENER_ID = -1;
46 constexpr int32_t MENU_BAR_AY_Z_INDEX = -2;
47
GetAppBarTheme()48 RefPtr<AppBarTheme> GetAppBarTheme()
49 {
50 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
51 CHECK_NULL_RETURN(pipeline, nullptr);
52 return pipeline->GetTheme<AppBarTheme>();
53 }
54
55 #ifndef PREVIEW
AssembleUiExtensionParams(bool firstTry,std::string & appGalleryBundleName,std::map<std::string,std::string> & params)56 void AssembleUiExtensionParams(
57 bool firstTry, std::string& appGalleryBundleName, std::map<std::string, std::string>& params)
58 {
59 auto missionId = AceApplicationInfo::GetInstance().GetMissionId();
60 params.try_emplace("bundleName", AceApplicationInfo::GetInstance().GetProcessName());
61 params.try_emplace("abilityName", AceApplicationInfo::GetInstance().GetAbilityName());
62 auto container = Container::Current();
63 CHECK_NULL_VOID(container);
64 params.try_emplace("module", container->GetModuleName());
65 if (missionId != -1) {
66 params.try_emplace("missionId", std::to_string(missionId));
67 }
68 auto frontend = container->GetFrontend();
69 if (frontend) {
70 auto info = frontend->GetTopNavDestinationInfo(false, true);
71 params.try_emplace("TopNavPathInfo", info);
72 }
73 if (firstTry) {
74 params.try_emplace("ability.want.params.uiExtensionType", "sysDialog/atomicServicePanel");
75 appGalleryBundleName = OHOS::Ace::SystemProperties::GetAtomicServiceBundleName();
76 } else {
77 params.try_emplace("ability.want.params.uiExtensionType", "sys/commonUI");
78 appGalleryBundleName = OHOS::Ace::AppBarHelper::QueryAppGalleryBundleName();
79 }
80 }
81 #endif
82 } // namespace
83
SetOnBackPressedConsumed()84 void AppBarView::SetOnBackPressedConsumed()
85 {
86 auto atomicService = atomicService_.Upgrade();
87 CHECK_NULL_VOID(atomicService);
88 auto atomicServicePattern = atomicService->GetPattern<NG::AtomicServicePattern>();
89 CHECK_NULL_VOID(atomicServicePattern);
90 atomicServicePattern->SetOnBackPressedConsumed();
91 }
92
GetAtomicServicePattern()93 RefPtr<Pattern> AppBarView::GetAtomicServicePattern()
94 {
95 auto atomicService = atomicService_.Upgrade();
96 CHECK_NULL_RETURN(atomicService, nullptr);
97 return atomicService->GetPattern<NG::AtomicServicePattern>();
98 }
99
RegistAppBarNodeBuilder(std::function<RefPtr<FrameNode> (NG::AppBarView * appBar,const RefPtr<FrameNode> & stage)> appBarNodeBuilder)100 void AppBarView::RegistAppBarNodeBuilder(
101 std::function<RefPtr<FrameNode>(NG::AppBarView* appBar, const RefPtr<FrameNode>& stage)> appBarNodeBuilder)
102 {
103 appBarNodeBuilder_ = appBarNodeBuilder;
104 }
105
Create(const RefPtr<FrameNode> & stage)106 RefPtr<FrameNode> AppBarView::Create(const RefPtr<FrameNode>& stage)
107 {
108 auto atom = FrameNode::CreateFrameNode(V2::ATOMIC_SERVICE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
109 AceType::MakeRefPtr<AtomicServicePattern>());
110 // add children
111 if (appBarNodeBuilder_) {
112 // app bar builder for cj frontend
113 return appBarNodeBuilder_(this, stage);
114 }
115 contentStage_ = stage;
116 atomicService_ = atom;
117 BindJSContainer();
118 // init
119 atom->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_PARENT);
120 stage->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_PARENT);
121 return atom;
122 }
123
BindJSContainer()124 void AppBarView::BindJSContainer()
125 {
126 auto atom = atomicService_.Upgrade();
127 CHECK_NULL_VOID(atom);
128 auto isSucc = ExecuteCustomAppBarAbc();
129 if (!isSucc) {
130 return;
131 }
132 auto customAppBarNode = NG::ViewStackProcessor::GetInstance()->GetCustomAppBarNode();
133 CHECK_NULL_VOID(customAppBarNode);
134 atom->AddChild(customAppBarNode);
135 auto pattern = atom->GetPattern<AtomicServicePattern>();
136 CHECK_NULL_VOID(pattern);
137 pattern->AppInfoCallBack();
138 pattern->AppScreenCallBack();
139 pattern->AppBgColorCallBack();
140 }
141
BuildAppbar(RefPtr<PipelineBase> pipleline)142 void AppBarView::BuildAppbar(RefPtr<PipelineBase> pipleline)
143 {
144 CHECK_NULL_VOID(pipleline);
145 auto pipelineContext = AceType::DynamicCast<PipelineContext>(pipleline);
146 CHECK_NULL_VOID(pipelineContext);
147 auto container = Container::GetContainer(pipelineContext->GetInstanceId());
148 CHECK_NULL_VOID(container);
149 auto appbar = container->GetAppBar();
150 CHECK_NULL_VOID(appbar);
151 auto atom = appbar->atomicService_.Upgrade();
152 CHECK_NULL_VOID(atom);
153 auto customAppBarNode = NG::ViewStackProcessor::GetInstance()->GetCustomAppBarNode();
154 CHECK_NULL_VOID(customAppBarNode);
155 customAppBarNode->Build(nullptr);
156 auto stageNodeWrapperNode = Inspector::GetInspectorByKey(atom, "AtomicServiceStageId");
157 CHECK_NULL_VOID(stageNodeWrapperNode);
158 auto stageNodeWrapper = AceType::DynamicCast<FrameNode>(stageNodeWrapperNode);
159 CHECK_NULL_VOID(stageNodeWrapper);
160 CHECK_NULL_VOID(appbar->contentStage_);
161 auto pattern = atom->GetPattern<AtomicServicePattern>();
162 CHECK_NULL_VOID(pattern);
163 pattern->BeforeCreateLayoutWrapper();
164 InitAccessibility(Inspector::GetInspectorByKey(atom, "AtomicServiceMenubarRowId"));
165 stageNodeWrapper->AddChild(appbar->contentStage_);
166 stageNodeWrapper->MarkModifyDone();
167 stageNodeWrapper->MarkDirtyNode(PROPERTY_UPDATE_MEASURE | PROPERTY_UPDATE_RENDER);
168 }
169
InitAccessibility(RefPtr<UINode> uiNode)170 void AppBarView::InitAccessibility(RefPtr<UINode> uiNode)
171 {
172 CHECK_NULL_VOID(uiNode);
173 auto frameNode = AceType::DynamicCast<FrameNode>(uiNode);
174 CHECK_NULL_VOID(frameNode);
175 auto accessibilityProperty = frameNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
176 CHECK_NULL_VOID(accessibilityProperty);
177 accessibilityProperty->SetAccessibilityZIndex(MENU_BAR_AY_Z_INDEX);
178 }
179
BuildMenuBarRow()180 RefPtr<FrameNode> AppBarView::BuildMenuBarRow()
181 {
182 auto menuBarRow = FrameNode::CreateFrameNode(V2::APP_BAR_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
183 AceType::MakeRefPtr<LinearLayoutPattern>(false));
184 auto theme = GetAppBarTheme();
185 CHECK_NULL_RETURN(theme, nullptr);
186
187 auto menuBar = BuildMenuBar();
188 menuBarRow->AddChild(menuBar);
189
190 auto layoutProperty = menuBarRow->GetLayoutProperty<LinearLayoutProperty>();
191 auto renderContext = menuBarRow->GetRenderContext();
192 // size
193 layoutProperty->UpdateUserDefinedIdealSize(
194 CalcSize(CalcLength(1.0, DimensionUnit::PERCENT), CalcLength(theme->GetMenuBarHeight())));
195 // main axis align
196 layoutProperty->UpdateMainAxisAlign(FlexAlign::FLEX_END);
197 // position
198 renderContext->UpdatePosition(OffsetT<Dimension>(0.0_vp, theme->GetMenuBarTopMargin()));
199 // background color
200 renderContext->UpdateBackgroundColor(Color::TRANSPARENT);
201 // hit test mode
202 menuBarRow->SetHitTestMode(HitTestMode::HTMTRANSPARENT_SELF);
203
204 menuBarRow->MarkModifyDone();
205 return menuBarRow;
206 }
207
BuildMenuBar()208 RefPtr<FrameNode> AppBarView::BuildMenuBar()
209 {
210 auto menuBar = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
211 AceType::MakeRefPtr<LinearLayoutPattern>(false));
212 auto theme = GetAppBarTheme();
213 CHECK_NULL_RETURN(theme, nullptr);
214
215 auto menuButton = BuildButton(true);
216 BindMenuCallback(menuButton);
217 menuBar->AddChild(menuButton);
218 auto divider = BuildDivider();
219 menuBar->AddChild(divider);
220 auto closeButton = BuildButton(false);
221 BindCloseCallback(closeButton);
222 menuBar->AddChild(closeButton);
223
224 auto layoutProperty = menuBar->GetLayoutProperty<LinearLayoutProperty>();
225 auto renderContext = menuBar->GetRenderContext();
226 // main axis align
227 layoutProperty->UpdateMainAxisAlign(FlexAlign::FLEX_START);
228 // border width
229 BorderWidthProperty borderWidth;
230 borderWidth.SetBorderWidth(theme->GetBorderWidth());
231 layoutProperty->UpdateBorderWidth(borderWidth);
232 renderContext->UpdateBorderWidth(borderWidth);
233 // border radius
234 auto bent = theme->GetBentRadius();
235 renderContext->UpdateBorderRadius(BorderRadiusProperty(bent));
236
237 menuBar->MarkModifyDone();
238 return menuBar;
239 }
240
BuildButton(bool isMenuButton)241 RefPtr<FrameNode> AppBarView::BuildButton(bool isMenuButton)
242 {
243 auto button = FrameNode::CreateFrameNode(
244 V2::BUTTON_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ButtonPattern>());
245 auto renderContext = button->GetRenderContext();
246 renderContext->UpdateBackgroundColor(Color::TRANSPARENT);
247 auto theme = GetAppBarTheme();
248 CHECK_NULL_RETURN(theme, nullptr);
249
250 auto icon = BuildIcon(isMenuButton);
251 button->AddChild(icon);
252
253 auto layoutProperty = button->GetLayoutProperty<ButtonLayoutProperty>();
254 // type
255 layoutProperty->UpdateType(ButtonType::NORMAL);
256 // size
257 layoutProperty->UpdateUserDefinedIdealSize(
258 CalcSize(CalcLength(theme->GetButtonWidth()), CalcLength(theme->GetButtonHeight())));
259 // focus style type
260 auto focusHub = button->GetFocusHub();
261 CHECK_NULL_RETURN(focusHub, nullptr);
262 focusHub->SetFocusStyleType(FocusStyleType::INNER_BORDER);
263 // focus border width
264 auto buttonPattern = button->GetPattern<ButtonPattern>();
265 CHECK_NULL_RETURN(buttonPattern, nullptr);
266 buttonPattern->SetFocusBorderWidth(theme->GetFocusedOutlineWidth());
267
268 button->MarkModifyDone();
269 return button;
270 }
271
BuildIcon(bool isMenuIcon)272 RefPtr<FrameNode> AppBarView::BuildIcon(bool isMenuIcon)
273 {
274 auto icon = FrameNode::CreateFrameNode(
275 V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
276 auto theme = GetAppBarTheme();
277 CHECK_NULL_RETURN(theme, nullptr);
278
279 ImageSourceInfo imageSourceInfo;
280 imageSourceInfo.SetResourceId(
281 isMenuIcon ? InternalResource::ResourceId::APP_BAR_MENU_SVG : InternalResource::ResourceId::APP_BAR_CLOSE_SVG);
282 auto layoutProperty = icon->GetLayoutProperty<ImageLayoutProperty>();
283 layoutProperty->UpdateImageSourceInfo(imageSourceInfo);
284 // size
285 layoutProperty->UpdateUserDefinedIdealSize(
286 CalcSize(CalcLength(theme->GetNewIconSize()), CalcLength(theme->GetNewIconSize())));
287 // focusable
288 auto focusHub = icon->GetFocusHub();
289 CHECK_NULL_RETURN(focusHub, nullptr);
290 focusHub->SetFocusable(true);
291
292 icon->MarkModifyDone();
293 return icon;
294 }
295
BuildDivider()296 RefPtr<FrameNode> AppBarView::BuildDivider()
297 {
298 auto divider = FrameNode::CreateFrameNode(
299 V2::DIVIDER_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<DividerPattern>());
300 auto theme = GetAppBarTheme();
301 CHECK_NULL_RETURN(theme, nullptr);
302
303 auto layoutProperty = divider->GetLayoutProperty<DividerLayoutProperty>();
304 // size
305 layoutProperty->UpdateUserDefinedIdealSize(
306 CalcSize(CalcLength(theme->GetDividerWidth()), CalcLength(theme->GetDividerHeight())));
307 // direction
308 layoutProperty->UpdateVertical(true);
309 // stroke width
310 layoutProperty->UpdateStrokeWidth(theme->GetDividerWidth());
311 // marigin
312 MarginProperty margin;
313 margin.left = CalcLength(-(theme->GetDividerWidth()));
314 auto renderProperty = divider->GetPaintProperty<DividerRenderProperty>();
315 // line cap
316 renderProperty->UpdateLineCap(LineCap::ROUND);
317
318 divider->MarkModifyDone();
319 return divider;
320 }
321
BindMenuCallback(const RefPtr<FrameNode> & menuButton)322 void AppBarView::BindMenuCallback(const RefPtr<FrameNode>& menuButton)
323 {
324 auto clickCallback = [wp = WeakClaim(this)](GestureEvent& info) {
325 #ifdef PREVIEW
326 LOGW("[Engine Log] Unable to show the SharePanel in the Previewer. "
327 "Perform this operation on the emulator or a real device instead.");
328 #else
329 auto appbarView = wp.Upgrade();
330 CHECK_NULL_VOID(appbarView);
331 auto node = appbarView->atomicService_.Upgrade();
332 auto pipeline = node->GetContext();
333 CHECK_NULL_VOID(pipeline);
334 auto theme = pipeline->GetTheme<AppBarTheme>();
335 CHECK_NULL_VOID(theme);
336 if (SystemProperties::GetExtSurfaceEnabled()) {
337 LOGI("start panel bundleName is %{public}s, abilityName is %{public}s", theme->GetBundleName().c_str(),
338 theme->GetAbilityName().c_str());
339 pipeline->FireSharePanelCallback(theme->GetBundleName(), theme->GetAbilityName());
340 } else {
341 appbarView->CreateServicePanel(true);
342 }
343 #endif
344 };
345 auto eventHub = menuButton->GetOrCreateGestureEventHub();
346 if (eventHub) {
347 eventHub->AddClickEvent(AceType::MakeRefPtr<ClickEvent>(std::move(clickCallback)));
348 }
349 }
350
BindCloseCallback(const RefPtr<FrameNode> & closeButton)351 void AppBarView::BindCloseCallback(const RefPtr<FrameNode>& closeButton)
352 {
353 auto clickCallback = [](GestureEvent& info) {
354 auto pipeline = PipelineContext::GetCurrentContext();
355 CHECK_NULL_VOID(pipeline);
356 auto container = Container::Current();
357 CHECK_NULL_VOID(container);
358 if (container->IsUIExtensionWindow()) {
359 container->TerminateUIExtension();
360 } else {
361 auto windowManager = pipeline->GetWindowManager();
362 CHECK_NULL_VOID(windowManager);
363 windowManager->WindowPerformBack();
364 }
365 };
366 auto eventHub = closeButton->GetOrCreateGestureEventHub();
367 if (eventHub) {
368 eventHub->AddClickEvent(AceType::MakeRefPtr<ClickEvent>(std::move(clickCallback)));
369 }
370 }
371
DestroyServicePanel()372 void AppBarView::DestroyServicePanel()
373 {
374 auto node = atomicService_.Upgrade();
375 auto pipeline = node->GetContext();
376 CHECK_NULL_VOID(pipeline);
377 auto overlayManager = pipeline->GetOverlayManager();
378 CHECK_NULL_VOID(overlayManager);
379 ContainerScope scope(pipeline->GetInstanceId());
380 overlayManager->CloseModalUIExtension(sessionId_);
381 LOGI("ServicePanel release session:%{public}d", sessionId_);
382 }
383
CreateServicePanel(const std::string & appGalleryBundleName,const std::string & abilityName,std::map<std::string,std::string> & params)384 void AppBarView::CreateServicePanel(
385 const std::string& appGalleryBundleName, const std::string& abilityName, std::map<std::string, std::string>& params)
386 {
387 #ifndef PREVIEW
388 if (OHOS::Ace::SystemProperties::GetAtomicServiceBundleName().empty() &&
389 OHOS::Ace::AppBarHelper::QueryAppGalleryBundleName().empty()) {
390 LOGE("UIExtension BundleName is empty.");
391 return;
392 }
393
394 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
395 CHECK_NULL_VOID(pipeline);
396 auto overlayManager = pipeline->GetOverlayManager();
397 CHECK_NULL_VOID(overlayManager);
398
399 ModalUIExtensionCallbacks callbacks;
400 callbacks.onRelease = [wp = WeakClaim(this)](int32_t releaseCode) {
401 auto bar = wp.Upgrade();
402 bar->DestroyServicePanel();
403 };
404 callbacks.onError = [wp = WeakClaim(this)](int32_t code, const std::string& name, const std::string& message) {
405 auto bar = wp.Upgrade();
406 bar->DestroyServicePanel();
407 };
408 auto wantWrap = WantWrap::CreateWantWrap(appGalleryBundleName, abilityName);
409 wantWrap->SetWantParam(params);
410 LOGI("ServicePanel request bundle: %{public}s, ability: %{public}s. "
411 "UIExtension bundle: %{public}s, ability: %{public}s, module: %{public}s",
412 appGalleryBundleName.c_str(), abilityName.c_str(), params["bundleName"].c_str(), params["abilityName"].c_str(),
413 params["module"].c_str());
414 ModalUIExtensionConfig config;
415 sessionId_ = overlayManager->CreateModalUIExtension(wantWrap, callbacks, config);
416 #endif
417 }
418
CreateServicePanel(bool firstTry)419 void AppBarView::CreateServicePanel(bool firstTry)
420 {
421 #ifndef PREVIEW
422 if (OHOS::Ace::SystemProperties::GetAtomicServiceBundleName().empty() &&
423 OHOS::Ace::AppBarHelper::QueryAppGalleryBundleName().empty()) {
424 LOGE("UIExtension BundleName is empty.");
425 return;
426 }
427
428 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
429 CHECK_NULL_VOID(pipeline);
430 auto overlayManager = pipeline->GetOverlayManager();
431 CHECK_NULL_VOID(overlayManager);
432
433 ModalUIExtensionCallbacks callbacks;
434 callbacks.onRelease = [wp = WeakClaim(this)](int32_t releaseCode) {
435 auto bar = wp.Upgrade();
436 bar->DestroyServicePanel();
437 };
438 callbacks.onError = [wp = WeakClaim(this), firstTry](
439 int32_t code, const std::string& name, const std::string& message) {
440 auto bar = wp.Upgrade();
441 bar->DestroyServicePanel();
442 if (firstTry) {
443 bar->CreateServicePanel(false);
444 }
445 };
446 std::string abilityName;
447 auto theme = pipeline->GetTheme<AppBarTheme>();
448 if (theme) {
449 abilityName = theme->GetStageAbilityName();
450 }
451 std::string appGalleryBundleName;
452 std::map<std::string, std::string> params;
453 AssembleUiExtensionParams(firstTry, appGalleryBundleName, params);
454 auto wantWrap = WantWrap::CreateWantWrap(appGalleryBundleName, abilityName);
455 wantWrap->SetWantParam(params);
456 LOGI("ServicePanel request bundle: %{public}s, ability: %{public}s. "
457 "UIExtension bundle: %{public}s, ability: %{public}s, module: %{public}s",
458 appGalleryBundleName.c_str(), abilityName.c_str(), params["bundleName"].c_str(), params["abilityName"].c_str(),
459 params["module"].c_str());
460 ModalUIExtensionConfig config;
461 sessionId_ = overlayManager->CreateModalUIExtension(wantWrap, callbacks, config);
462 #endif
463 }
464
InitUIExtensionNode(const RefPtr<FrameNode> & uiExtNode)465 void AppBarView::InitUIExtensionNode(const RefPtr<FrameNode>& uiExtNode)
466 {
467 CHECK_NULL_VOID(uiExtNode);
468 // Update ideal size of UIExtension.
469 auto layoutProperty = uiExtNode->GetLayoutProperty();
470 layoutProperty->UpdateUserDefinedIdealSize(CalcSize(
471 CalcLength(Dimension(1.0, DimensionUnit::PERCENT)), CalcLength(Dimension(1.0, DimensionUnit::PERCENT))));
472 uiExtNode->MarkModifyDone();
473 }
474
GetAppBarRect()475 std::optional<RectF> AppBarView::GetAppBarRect()
476 {
477 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
478 if (!pipeline || !pipeline->GetInstallationFree()) {
479 return std::nullopt;
480 }
481 auto theme = GetAppBarTheme();
482 CHECK_NULL_RETURN(theme, std::nullopt);
483 auto atom = atomicService_.Upgrade();
484 CHECK_NULL_RETURN(atom, std::nullopt);
485 auto pattern = atom->GetPattern<AtomicServicePattern>();
486 CHECK_NULL_RETURN(pattern, std::nullopt);
487 auto menuBarRow = pattern->GetMenuBarRow();
488 CHECK_NULL_RETURN(menuBarRow, std::nullopt);
489 auto rowGeometryNode = menuBarRow->GetGeometryNode();
490 CHECK_NULL_RETURN(rowGeometryNode, std::nullopt);
491 auto menuBar = pattern->GetMenuBar();
492 CHECK_NULL_RETURN(menuBar, std::nullopt);
493 auto geometryNode = menuBar->GetGeometryNode();
494 CHECK_NULL_RETURN(geometryNode, std::nullopt);
495 auto size = geometryNode->GetMarginFrameSize();
496 auto offset = geometryNode->GetMarginFrameOffset();
497 auto parent = menuBar->GetParent();
498 while (parent) {
499 auto frameNode = AceType::DynamicCast<FrameNode>(parent);
500 if (frameNode) {
501 offset += frameNode->GetGeometryNode()->GetFrameOffset();
502 }
503 parent = parent->GetParent();
504 }
505 auto atomRect = atom->GetGeometryNode()->GetFrameRect();
506 bool isRtl = AceApplicationInfo::GetInstance().IsRightToLeft();
507 auto defalutLeftMargin = Dimension(ATOMIC_SERVICE_MENU_BAR_MARGIN_LEFT, DimensionUnit::VP).ConvertToPx();
508 auto defalutRightMargin = Dimension(ATOMIC_SERVICE_MENU_BAR_MARGIN_RIGHT, DimensionUnit::VP).ConvertToPx();
509 auto left = defalutLeftMargin;
510 auto right = defalutRightMargin;
511 if (rowGeometryNode->GetMargin()) {
512 left = rowGeometryNode->GetMargin()->left.value_or(defalutLeftMargin);
513 right = rowGeometryNode->GetMargin()->right.value_or(defalutRightMargin);
514 }
515 if (LessOrEqual(offset.GetX(), 0.0) && atomRect.Width() > 0) {
516 auto width = Dimension(ATOMIC_SERVICE_MENU_BAR_WIDTH, DimensionUnit::VP).ConvertToPx();
517 offset.SetX(isRtl ? (right) : (atomRect.Width() - width - left));
518 } else {
519 auto addEnd = isRtl ? left : right;
520 size.AddWidth((defalutLeftMargin + addEnd));
521 offset.AddX(isRtl ? -addEnd : -defalutLeftMargin);
522 }
523 return RectF(offset, size);
524 }
525
SetStatusBarItemColor(bool isLight)526 void AppBarView::SetStatusBarItemColor(bool isLight)
527 {
528 auto atom = atomicService_.Upgrade();
529 CHECK_NULL_VOID(atom);
530 auto pattern = atom->GetPattern<AtomicServicePattern>();
531 CHECK_NULL_VOID(pattern);
532 auto theme = GetAppBarTheme();
533 auto menuBar = pattern->GetMenuBar();
534 pattern->settedColorMode = isLight;
535 pattern->ColorConfigurationCallBack();
536 }
537
OnMenuClick()538 void AppBarView::OnMenuClick()
539 {
540 auto atom = atomicService_.Upgrade();
541 CHECK_NULL_VOID(atom);
542 auto pipeline = atom->GetContext();
543 CHECK_NULL_VOID(pipeline);
544 auto theme = pipeline->GetTheme<AppBarTheme>();
545 CHECK_NULL_VOID(theme);
546 if (SystemProperties::GetExtSurfaceEnabled()) {
547 LOGI("start panel bundleName is %{public}s, abilityName is %{public}s", theme->GetBundleName().c_str(),
548 theme->GetAbilityName().c_str());
549 pipeline->FireSharePanelCallback(theme->GetBundleName(), theme->GetAbilityName());
550 } else {
551 CreateServicePanel(true);
552 }
553 }
554
OnCloseClick()555 void AppBarView::OnCloseClick()
556 {
557 auto atom = atomicService_.Upgrade();
558 CHECK_NULL_VOID(atom);
559 auto pipeline = atom->GetContext();
560 CHECK_NULL_VOID(pipeline);
561 auto container = Container::Current();
562 CHECK_NULL_VOID(container);
563 TAG_LOGI(AceLogTag::ACE_APPBAR, "AppBar OnCloseClick");
564 if (container->IsUIExtensionWindow()) {
565 container->TerminateUIExtension();
566 } else {
567 auto windowManager = pipeline->GetWindowManager();
568 CHECK_NULL_VOID(windowManager);
569 windowManager->WindowPerformBack();
570 }
571 }
572
RequestAtomicServiceTerminate()573 void AppBarView::RequestAtomicServiceTerminate()
574 {
575 auto atom = atomicService_.Upgrade();
576 CHECK_NULL_VOID(atom);
577 auto pipeline = atom->GetContext();
578 CHECK_NULL_VOID(pipeline);
579 auto container = Container::Current();
580 CHECK_NULL_VOID(container);
581 TAG_LOGI(AceLogTag::ACE_APPBAR, "AppBar RequestAtomicServiceTerminate");
582 if (container->IsUIExtensionWindow()) {
583 container->RequestAtomicServiceTerminate();
584 } else {
585 auto windowManager = pipeline->GetWindowManager();
586 CHECK_NULL_VOID(windowManager);
587 windowManager->WindowPerformBack();
588 }
589 }
590
AddRectChangeListener(const RefPtr<PipelineContext> & pipelineContext,std::function<void (const RectF & rect)> && listener)591 int32_t AppBarView::AddRectChangeListener(
592 const RefPtr<PipelineContext>& pipelineContext, std::function<void(const RectF& rect)>&& listener)
593 {
594 CHECK_NULL_RETURN(pipelineContext, INVALID_LISTENER_ID);
595 auto container = Container::GetContainer(pipelineContext->GetInstanceId());
596 CHECK_NULL_RETURN(container, INVALID_LISTENER_ID);
597 auto appbar = container->GetAppBar();
598 CHECK_NULL_RETURN(appbar, INVALID_LISTENER_ID);
599 auto atom = appbar->atomicService_.Upgrade();
600 CHECK_NULL_RETURN(atom, INVALID_LISTENER_ID);
601 auto pattern = atom->GetPattern<AtomicServicePattern>();
602 CHECK_NULL_RETURN(pattern, INVALID_LISTENER_ID);
603 return pattern->AddRectChangeListener(std::move(listener));
604 }
605
RemoveRectChangeListener(const RefPtr<PipelineContext> & pipelineContext,int32_t id)606 void AppBarView::RemoveRectChangeListener(const RefPtr<PipelineContext>& pipelineContext, int32_t id)
607 {
608 CHECK_NULL_VOID(pipelineContext);
609 auto container = Container::GetContainer(pipelineContext->GetInstanceId());
610 CHECK_NULL_VOID(container);
611 auto appbar = container->GetAppBar();
612 CHECK_NULL_VOID(appbar);
613 auto atom = appbar->atomicService_.Upgrade();
614 CHECK_NULL_VOID(atom);
615 auto pattern = atom->GetPattern<AtomicServicePattern>();
616 CHECK_NULL_VOID(pattern);
617 pattern->RemoveRectChangeListener(id);
618 }
619 } // namespace OHOS::Ace::NG
620