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 #include "core/components_ng/pattern/app_bar/atomic_service_pattern.h"
16 #include <string>
17
18 #include "core/components_ng/pattern/button/button_pattern.h"
19 #include "core/components_ng/pattern/divider/divider_render_property.h"
20 #include "core/components_ng/pattern/image/image_layout_property.h"
21 #include "core/components_ng/pattern/image/image_render_property.h"
22 #include "core/components_ng/base/inspector.h"
23 #include "core/components_ng/pattern/app_bar/app_bar_view.h"
24 namespace OHOS::Ace::NG {
25 constexpr int32_t ATOMIC_SERVICE_MIN_SIZE = 2;
26 constexpr int32_t FIRST_OVERLAY_INDEX = 1;
27
28 std::atomic<int32_t> g_nextListenerId = 1;
29
30 std::function<void(RefPtr<FrameNode> host, std::optional<bool> settedColorMode)>
31 AtomicServicePattern::beforeCreateLayoutBuilder_ = nullptr;
32
RegisterBeforeCreateLayoutBuilder(std::function<void (RefPtr<FrameNode> host,std::optional<bool> settedColorMode)> beforeCreateLayoutBuilder)33 void AtomicServicePattern::RegisterBeforeCreateLayoutBuilder(
34 std::function<void(RefPtr<FrameNode> host, std::optional<bool> settedColorMode)> beforeCreateLayoutBuilder)
35 {
36 beforeCreateLayoutBuilder_ = beforeCreateLayoutBuilder;
37 }
38
BeforeCreateLayoutWrapper()39 void AtomicServicePattern::BeforeCreateLayoutWrapper()
40 {
41 // before create layout builder for cj frontend
42 if (beforeCreateLayoutBuilder_) {
43 beforeCreateLayoutBuilder_(GetHost(), settedColorMode);
44 return;
45 }
46 MenuBarSafeAreaCallBack();
47 ContentSafeAreaCallBack();
48 ColorConfigurationCallBack();
49 }
50
MenuBarSafeAreaCallBack()51 void AtomicServicePattern::MenuBarSafeAreaCallBack()
52 {
53 auto pipeline = PipelineContext::GetCurrentContext();
54 CHECK_NULL_VOID(pipeline);
55 auto theme = pipeline->GetTheme<AppBarTheme>();
56 CHECK_NULL_VOID(theme);
57 auto host = GetHost();
58 CHECK_NULL_VOID(host);
59 auto manager = pipeline->GetSafeAreaManager();
60 CHECK_NULL_VOID(manager);
61 manager->SetIsAtomicService(true);
62 manager->AddGeoRestoreNode(host);
63 auto systemSafeArea = manager->GetSystemSafeArea();
64 auto menuSafeTopValue = systemSafeArea.top_.Length();
65 auto menuSafeTopVp = Dimension(menuSafeTopValue, DimensionUnit::PX).ConvertToVp();
66 auto customAppBar = GetJSAppBarContainer();
67 CHECK_NULL_VOID(customAppBar);
68 customAppBar->FireCustomCallback(ARKUI_APP_BAR_MENU_SAFE_AREA, std::to_string(menuSafeTopVp));
69 }
70
ContentSafeAreaCallBack()71 void AtomicServicePattern::ContentSafeAreaCallBack()
72 {
73 auto pipeline = PipelineContext::GetCurrentContext();
74 CHECK_NULL_VOID(pipeline);
75 auto safeArea = pipeline->GetSafeArea();
76 auto manager = pipeline->GetSafeAreaManager();
77 CHECK_NULL_VOID(manager);
78 if (manager->KeyboardSafeAreaEnabled()) {
79 safeArea.bottom_ = safeArea.bottom_.Combine(manager->GetKeyboardInset());
80 }
81 auto left = Dimension(safeArea.left_.Length(), DimensionUnit::PX).ConvertToVp();
82 auto right = Dimension(safeArea.right_.Length(), DimensionUnit::PX).ConvertToVp();
83 auto top = Dimension(safeArea.top_.Length(), DimensionUnit::PX).ConvertToVp();
84 auto bottom = Dimension(safeArea.bottom_.Length(), DimensionUnit::PX).ConvertToVp();
85 auto customAppBar = GetJSAppBarContainer();
86 CHECK_NULL_VOID(customAppBar);
87 std::vector<float> values = { top, left, right, bottom };
88 std::string result;
89 for (size_t i = 0; i < values.size(); ++i) {
90 result += std::to_string(values[i]);
91 if (i < values.size() - 1) {
92 result += "|";
93 }
94 }
95 customAppBar->FireCustomCallback(ARKUI_APP_BAR_CONTENT_SAFE_AREA, result);
96 }
97
ColorConfigurationCallBack()98 void AtomicServicePattern::ColorConfigurationCallBack()
99 {
100 auto customAppBar = GetJSAppBarContainer();
101 CHECK_NULL_VOID(customAppBar);
102 auto context = GetContext();
103 CHECK_NULL_VOID(context);
104 customAppBar->FireCustomCallback(ARKUI_APP_BAR_COLOR_CONFIGURATION,
105 settedColorMode.has_value() ? !settedColorMode.value() : context->GetColorMode() == ColorMode::DARK);
106 }
107
AppInfoCallBack()108 void AtomicServicePattern::AppInfoCallBack()
109 {
110 auto atom = GetHost();
111 CHECK_NULL_VOID(atom);
112 auto pipeline = atom->GetContextRefPtr();
113 CHECK_NULL_VOID(pipeline);
114 auto themeManager = pipeline->GetThemeManager();
115 CHECK_NULL_VOID(themeManager);
116 auto themeConstants = themeManager->GetThemeConstants();
117 CHECK_NULL_VOID(themeConstants);
118 auto windowManager = pipeline->GetWindowManager();
119 CHECK_NULL_VOID(windowManager);
120 auto customAppBar = GetJSAppBarContainer();
121 CHECK_NULL_VOID(customAppBar);
122 auto id = windowManager->GetAppIconId();
123 auto pixelMap = themeConstants->GetPixelMap(id);
124 if (pixelMap) {
125 const RefPtr<PixelMap> icon = PixelMap::CreatePixelMap(&pixelMap);
126 customAppBar->FireAppIconCallback(icon);
127 } else {
128 TAG_LOGW(AceLogTag::ACE_APPBAR, "App bar Cannot get pixelmap, try media path.");
129 }
130 auto result = AceApplicationInfo::GetInstance().GetProcessName() + "|" +
131 themeConstants->GetString(windowManager->GetAppLabelId());
132 customAppBar->FireCustomCallback(ARKUI_APP_BAR_BAR_INFO, result);
133 }
134
AppScreenCallBack()135 void AtomicServicePattern::AppScreenCallBack()
136 {
137 auto customAppBar = GetJSAppBarContainer();
138 CHECK_NULL_VOID(customAppBar);
139 auto container = Container::Current();
140 CHECK_NULL_VOID(container);
141 customAppBar->FireCustomCallback(ARKUI_APP_BAR_SCREEN, container->UIExtensionIsHalfScreen());
142 }
143
SetOnBackPressedConsumed()144 void AtomicServicePattern::SetOnBackPressedConsumed()
145 {
146 if (onBackPressedConsumed_.has_value()) {
147 onBackPressedConsumed_ = true;
148 }
149 }
150
OnBackPressedCallback()151 bool AtomicServicePattern::OnBackPressedCallback()
152 {
153 auto customAppBar = GetJSAppBarContainer();
154 CHECK_NULL_RETURN(customAppBar, false);
155 onBackPressedConsumed_ = false;
156 customAppBar->FireCustomCallback(ARKUI_APP_BAR_ON_BACK_PRESSED, true);
157 bool consumed = onBackPressedConsumed_.value();
158 onBackPressedConsumed_.reset();
159 return consumed;
160 }
161
AppBgColorCallBack()162 void AtomicServicePattern::AppBgColorCallBack()
163 {
164 auto host = GetHost();
165 CHECK_NULL_VOID(host);
166 auto pipeline = host->GetContextRefPtr();
167 CHECK_NULL_VOID(pipeline);
168 auto customAppBar = GetJSAppBarContainer();
169 CHECK_NULL_VOID(customAppBar);
170 customAppBar->FireCustomCallback(ARKUI_APP_BG_COLOR, pipeline->GetAppBgColor().ColorToString());
171 }
172
UpdateLayoutMargin()173 void AtomicServicePattern::UpdateLayoutMargin()
174 {
175 auto pipeline = PipelineContext::GetCurrentContext();
176 CHECK_NULL_VOID(pipeline);
177 auto safeArea = pipeline->GetSafeArea();
178 auto atom = GetHost();
179 CHECK_NULL_VOID(atom);
180 MarginProperty margin;
181 margin.left = CalcLength(safeArea.left_.Length());
182 margin.right = CalcLength(safeArea.right_.Length());
183 margin.top = CalcLength(safeArea.top_.Length());
184 margin.bottom = CalcLength(safeArea.bottom_.Length());
185 // update stage margin
186 auto stage = GetContent();
187 CHECK_NULL_VOID(stage);
188 auto layoutProperty = stage->GetLayoutProperty();
189 CHECK_NULL_VOID(layoutProperty);
190 layoutProperty->UpdateMargin(margin);
191 stage->MarkModifyDone();
192 stage->MarkDirtyNode();
193 }
194
UpdateOverlayLayout()195 void AtomicServicePattern::UpdateOverlayLayout()
196 {
197 auto atom = GetHost();
198 CHECK_NULL_VOID(atom);
199 if (atom->GetChildren().size() <= ATOMIC_SERVICE_MIN_SIZE) {
200 return;
201 }
202 for (int index = FIRST_OVERLAY_INDEX;
203 index <= static_cast<int32_t>(atom->GetChildren().size()) - ATOMIC_SERVICE_MIN_SIZE; index++) {
204 auto overlay = AceType::DynamicCast<FrameNode>(atom->GetChildAtIndex(index));
205 CHECK_NULL_VOID(overlay);
206 auto overlayRender = overlay->GetRenderContext();
207 overlayRender->UpdatePosition(OffsetT<Dimension>());
208 overlay->MarkModifyDone();
209 overlay->MarkDirtyNode();
210 }
211 }
212
OnAttachToFrameNode()213 void AtomicServicePattern::OnAttachToFrameNode()
214 {
215 auto host = GetHost();
216 CHECK_NULL_VOID(host);
217 host->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_PARENT);
218 AppBgColorCallBack();
219 }
220
OnColorConfigurationUpdate()221 void AtomicServicePattern::OnColorConfigurationUpdate()
222 {
223 AppBgColorCallBack();
224 ColorConfigurationCallBack();
225 }
226
OnLanguageConfigurationUpdate()227 void AtomicServicePattern::OnLanguageConfigurationUpdate()
228 {
229 AppInfoCallBack();
230 }
231
GetJSAppBarContainer()232 RefPtr<CustomAppBarNode> AtomicServicePattern::GetJSAppBarContainer()
233 {
234 auto customAppBarNode = NG::ViewStackProcessor::GetInstance()->GetCustomAppBarNode();
235 return AceType::DynamicCast<CustomAppBarNode>(customAppBarNode);
236 }
237
GetStageNodeWrapper()238 RefPtr<FrameNode> AtomicServicePattern::GetStageNodeWrapper()
239 {
240 return NG::Inspector::GetFrameNodeByKey("AtomicServiceStageId");
241 }
242
GetContent()243 RefPtr<FrameNode> AtomicServicePattern::GetContent()
244 {
245 auto stageNodeWrapper = GetStageNodeWrapper();
246 CHECK_NULL_RETURN(stageNodeWrapper, nullptr);
247 return AceType::DynamicCast<FrameNode>(stageNodeWrapper->GetChildAtIndex(0));
248 }
249
GetMenuBarRow()250 RefPtr<FrameNode> AtomicServicePattern::GetMenuBarRow()
251 {
252 return NG::Inspector::GetFrameNodeByKey("AtomicServiceMenubarRowId");
253 }
254
GetMenuBar()255 RefPtr<FrameNode> AtomicServicePattern::GetMenuBar()
256 {
257 return NG::Inspector::GetFrameNodeByKey("AtomicServiceMenubarId");
258 }
259
GetMenuButton()260 RefPtr<FrameNode> AtomicServicePattern::GetMenuButton()
261 {
262 return NG::Inspector::GetFrameNodeByKey("AtomicServiceMenuId");
263 }
264
GetDivider()265 RefPtr<FrameNode> AtomicServicePattern::GetDivider()
266 {
267 return NG::Inspector::GetFrameNodeByKey("AtomicServiceDividerId");
268 }
269
GetCloseButton()270 RefPtr<FrameNode> AtomicServicePattern::GetCloseButton()
271 {
272 return NG::Inspector::GetFrameNodeByKey("AtomicServiceCloseId");
273 }
274
GetMenuIcon()275 RefPtr<FrameNode> AtomicServicePattern::GetMenuIcon()
276 {
277 return NG::Inspector::GetFrameNodeByKey("AtomicServiceMenuIconId");
278 }
279
GetCloseIcon()280 RefPtr<FrameNode> AtomicServicePattern::GetCloseIcon()
281 {
282 return NG::Inspector::GetFrameNodeByKey("AtomicServiceCloseIconId");
283 }
284
UpdateColor(std::optional<bool> isLight)285 void AtomicServicePattern::UpdateColor(std::optional<bool> isLight)
286 {
287 auto pipeline = PipelineContext::GetCurrentContext();
288 CHECK_NULL_VOID(pipeline);
289 auto theme = pipeline->GetTheme<AppBarTheme>();
290 if (!(isLight.has_value())) {
291 isLight = pipeline->GetColorMode() != ColorMode::DARK;
292 }
293 auto menuButton = GetMenuButton();
294 UpdateButtonColor(theme, menuButton, isLight.value());
295 auto divider = GetDivider();
296 UpdateDividerColor(theme, divider, isLight.value());
297 auto closeButton = GetCloseButton();
298 UpdateButtonColor(theme, closeButton, isLight.value());
299
300 auto menuIcon = GetMenuIcon();
301 UpdateIconColor(theme, menuIcon, isLight.value());
302 auto closeIcon = GetCloseIcon();
303 UpdateIconColor(theme, closeIcon, isLight.value());
304 }
305
UpdateMenuBarColor(RefPtr<AppBarTheme> & theme,RefPtr<FrameNode> & menuBar,bool isLight)306 void AtomicServicePattern::UpdateMenuBarColor(RefPtr<AppBarTheme>& theme, RefPtr<FrameNode>& menuBar, bool isLight)
307 {
308 CHECK_NULL_VOID(theme);
309 CHECK_NULL_VOID(menuBar);
310 auto renderContext = menuBar->GetRenderContext();
311 // background effect、border color
312 EffectOption option;
313 BorderColorProperty borderColor;
314 option.radius = theme->GetBlurRadius();
315 if (isLight) {
316 option.color = theme->GetBlurColorLight();
317 borderColor.SetColor(theme->GetBorderColorLight());
318 } else {
319 option.color = theme->GetBlurColorDark();
320 borderColor.SetColor(theme->GetBorderColorDark());
321 }
322 renderContext->UpdateBackgroundEffect(option);
323 renderContext->UpdateBorderColor(borderColor);
324
325 menuBar->MarkModifyDone();
326 menuBar->MarkDirtyNode(PROPERTY_UPDATE_LAYOUT);
327 }
328
UpdateButtonColor(RefPtr<AppBarTheme> & theme,RefPtr<FrameNode> & button,bool isLight)329 void AtomicServicePattern::UpdateButtonColor(RefPtr<AppBarTheme>& theme, RefPtr<FrameNode>& button, bool isLight)
330 {
331 CHECK_NULL_VOID(theme);
332 CHECK_NULL_VOID(button);
333 // pressed color
334 auto buttonPattern = button->GetPattern<ButtonPattern>();
335 CHECK_NULL_VOID(buttonPattern);
336 if (isLight) {
337 buttonPattern->SetClickedColor(theme->GetClickEffectColorLight());
338 } else {
339 buttonPattern->SetClickedColor(theme->GetClickEffectColorDark());
340 }
341 // focus border color
342 if (isLight) {
343 buttonPattern->SetFocusBorderColor(theme->GetFocusedOutlineColorLight());
344 } else {
345 buttonPattern->SetFocusBorderColor(theme->GetFocusedOutlineColorDark());
346 }
347
348 button->MarkModifyDone();
349 button->MarkDirtyNode();
350 }
351
UpdateDividerColor(RefPtr<AppBarTheme> & theme,RefPtr<FrameNode> & divider,bool isLight)352 void AtomicServicePattern::UpdateDividerColor(RefPtr<AppBarTheme>& theme, RefPtr<FrameNode>& divider, bool isLight)
353 {
354 CHECK_NULL_VOID(theme);
355 CHECK_NULL_VOID(divider);
356
357 auto renderProperty = divider->GetPaintProperty<DividerRenderProperty>();
358 if (isLight) {
359 renderProperty->UpdateDividerColor(theme->GetDividerColorLight());
360 } else {
361 renderProperty->UpdateDividerColor(theme->GetDividerColorDark());
362 }
363
364 divider->MarkModifyDone();
365 divider->MarkDirtyNode();
366 }
367
UpdateIconColor(RefPtr<AppBarTheme> & theme,RefPtr<FrameNode> & icon,bool isLight)368 void AtomicServicePattern::UpdateIconColor(RefPtr<AppBarTheme>& theme, RefPtr<FrameNode>& icon, bool isLight)
369 {
370 CHECK_NULL_VOID(theme);
371 CHECK_NULL_VOID(icon);
372 // fill color
373 auto color = isLight ? theme->GetIconColorLight() : theme->GetIconColorDark();
374 ACE_UPDATE_NODE_PAINT_PROPERTY(ImageRenderProperty, SvgFillColor, color, icon);
375 ACE_UPDATE_NODE_RENDER_CONTEXT(ForegroundColor, color, icon);
376 icon->MarkModifyDone();
377 icon->MarkDirtyNode();
378 }
379
UpdateLayout()380 void AtomicServicePattern::UpdateLayout()
381 {
382 auto pipeline = PipelineContext::GetCurrentContext();
383 CHECK_NULL_VOID(pipeline);
384 auto theme = pipeline->GetTheme<AppBarTheme>();
385 CHECK_NULL_VOID(theme);
386 bool isRtl = AceApplicationInfo::GetInstance().IsRightToLeft();
387
388 auto menuBar = GetMenuBar();
389 UpdateMenuBarLayout(theme, menuBar, isRtl);
390
391 auto menuButton = GetMenuButton();
392 UpdateButtonLayout(theme, menuButton, !isRtl);
393 auto closeButton = GetCloseButton();
394 UpdateButtonLayout(theme, closeButton, isRtl);
395
396 auto menuIcon = GetMenuIcon();
397 UpdateIconLayout(theme, menuIcon, !isRtl);
398 auto closeIcon = GetCloseIcon();
399 UpdateIconLayout(theme, closeIcon, isRtl);
400 }
401
UpdateMenuBarLayout(RefPtr<AppBarTheme> & theme,RefPtr<FrameNode> & menuBar,bool isRtl)402 void AtomicServicePattern::UpdateMenuBarLayout(RefPtr<AppBarTheme>& theme, RefPtr<FrameNode>& menuBar, bool isRtl)
403 {
404 CHECK_NULL_VOID(theme);
405 CHECK_NULL_VOID(menuBar);
406
407 MarginProperty margin;
408 auto pipeline = PipelineContext::GetCurrentContext();
409 CHECK_NULL_VOID(pipeline);
410 auto safeArea = pipeline->GetSafeArea();
411
412 Dimension safeAreaLeft(pipeline->Px2VpWithCurrentDensity(safeArea.left_.Length()), DimensionUnit::VP);
413 Dimension safeAreaRight(pipeline->Px2VpWithCurrentDensity(safeArea.right_.Length()), DimensionUnit::VP);
414
415 if (isRtl) {
416 margin.left = CalcLength(theme->GetMenuBarRightMargin() + safeAreaLeft);
417 margin.right = CalcLength(theme->GetMenuBarLeftMargin() + safeAreaRight);
418 } else {
419 margin.left = CalcLength(theme->GetMenuBarLeftMargin() + safeAreaLeft);
420 margin.right = CalcLength(theme->GetMenuBarRightMargin() + safeAreaRight);
421 }
422 menuBar->GetLayoutProperty<LinearLayoutProperty>()->UpdateMargin(margin);
423
424 menuBar->MarkModifyDone();
425 menuBar->MarkDirtyNode();
426 }
427
UpdateButtonLayout(RefPtr<AppBarTheme> & theme,RefPtr<FrameNode> & button,bool isLeft)428 void AtomicServicePattern::UpdateButtonLayout(RefPtr<AppBarTheme>& theme, RefPtr<FrameNode>& button, bool isLeft)
429 {
430 CHECK_NULL_VOID(theme);
431 CHECK_NULL_VOID(button);
432
433 auto bent = theme->GetBentRadius();
434 auto rightAngle = theme->GetRightAngle();
435 auto leftBorderRadius = BorderRadiusProperty(bent, rightAngle, rightAngle, bent);
436 auto rightBorderRadius = BorderRadiusProperty(rightAngle, bent, bent, rightAngle);
437
438 auto layoutProperty = button->GetLayoutProperty<ButtonLayoutProperty>();
439 layoutProperty->UpdateBorderRadius(isLeft ? leftBorderRadius : rightBorderRadius);
440
441 button->MarkModifyDone();
442 button->MarkDirtyNode();
443 }
444
UpdateIconLayout(RefPtr<AppBarTheme> & theme,RefPtr<FrameNode> & icon,bool isLeft)445 void AtomicServicePattern::UpdateIconLayout(RefPtr<AppBarTheme>& theme, RefPtr<FrameNode>& icon, bool isLeft)
446 {
447 CHECK_NULL_VOID(theme);
448 CHECK_NULL_VOID(icon);
449
450 MarginProperty margin;
451 margin.top = CalcLength(theme->GetIconVerticalMargin());
452 margin.bottom = CalcLength(theme->GetIconVerticalMargin());
453 if (isLeft) {
454 margin.left = CalcLength(theme->GetIconOutsideMargin());
455 margin.right = CalcLength(theme->GetIconInsideMargin());
456 } else {
457 margin.left = CalcLength(theme->GetIconInsideMargin());
458 margin.right = CalcLength(theme->GetIconOutsideMargin());
459 }
460 auto layoutProperty = icon->GetLayoutProperty<ImageLayoutProperty>();
461 CHECK_NULL_VOID(layoutProperty);
462 layoutProperty->UpdateMargin(margin);
463
464 icon->MarkModifyDone();
465 icon->MarkDirtyNode();
466 }
467
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,const DirtySwapConfig & config)468 bool AtomicServicePattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config)
469 {
470 auto atom = GetHost();
471 CHECK_NULL_RETURN(atom, false);
472 auto pipeline = atom->GetContextRefPtr();
473 CHECK_NULL_RETURN(pipeline, false);
474 pipeline->AddAfterLayoutTask([weak = WeakClaim(this)]() {
475 auto pattern = weak.Upgrade();
476 CHECK_NULL_VOID(pattern);
477 pattern->CallRectChange();
478 });
479 return false;
480 }
481
AddRectChangeListener(std::function<void (const RectF & rect)> && listener)482 int32_t AtomicServicePattern::AddRectChangeListener(std::function<void(const RectF& rect)>&& listener)
483 {
484 auto id = g_nextListenerId.fetch_add(1);
485 rectChangeListeners_.emplace(id, listener);
486 return id;
487 }
488
RemoveRectChangeListener(int32_t id)489 void AtomicServicePattern::RemoveRectChangeListener(int32_t id)
490 {
491 auto it = rectChangeListeners_.find(id);
492 if (it != rectChangeListeners_.end()) {
493 rectChangeListeners_.erase(it);
494 }
495 }
496
NotifyRectChange(const RectF & rect)497 void AtomicServicePattern::NotifyRectChange(const RectF& rect)
498 {
499 for (auto& pair : rectChangeListeners_) {
500 if (pair.second) {
501 pair.second(rect);
502 }
503 }
504 }
505
CallRectChange()506 void AtomicServicePattern::CallRectChange()
507 {
508 auto host = GetHost();
509 CHECK_NULL_VOID(host);
510 auto pipeline = host->GetContextRefPtr();
511 CHECK_NULL_VOID(pipeline);
512 auto container = Container::GetContainer(pipeline->GetInstanceId());
513 CHECK_NULL_VOID(container);
514 auto appbar = container->GetAppBar();
515 CHECK_NULL_VOID(appbar);
516 auto rect = appbar->GetAppBarRect();
517 if (!rect.has_value()) {
518 TAG_LOGW(AceLogTag::ACE_APPBAR, "Get rect of app bar failed, app bar is hidden");
519 return;
520 }
521 if (appBarRect_.has_value() && appBarRect_.value() == rect.value()) {
522 TAG_LOGD(AceLogTag::ACE_APPBAR, "App bar rect is not changed, no need to notify");
523 return;
524 }
525 NotifyRectChange(rect.value());
526 appBarRect_ = rect;
527 }
528 } // namespace OHOS::Ace::NG
529