1 /*
2 * Copyright (c) 2022-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/side_bar/side_bar_container_pattern.h"
17
18 #include <optional>
19 #include "base/log/ace_trace.h"
20
21 #if defined(OHOS_STANDARD_SYSTEM) and !defined(ACE_UNITTEST)
22 #include "accessibility_element_info.h"
23 #endif
24 #include "base/log/log_wrapper.h"
25 #include "base/memory/ace_type.h"
26 #include "base/mousestyle/mouse_style.h"
27 #include "base/resource/internal_resource.h"
28 #include "base/utils/utils.h"
29 #include "core/common/ace_application_info.h"
30 #include "core/common/agingadapation/aging_adapation_dialog_util.h"
31 #include "core/common/agingadapation/aging_adapation_dialog_theme.h"
32 #include "core/common/container.h"
33 #include "core/common/recorder/event_recorder.h"
34 #include "core/components/common/layout/constants.h"
35 #include "core/components/common/properties/shadow_config.h"
36 #include "core/components_ng/base/frame_node.h"
37 #include "core/components_ng/pattern/button/button_layout_property.h"
38 #include "core/components_ng/pattern/button/button_pattern.h"
39 #include "core/components_ng/pattern/divider/divider_layout_property.h"
40 #include "core/components_ng/pattern/divider/divider_pattern.h"
41 #include "core/components_ng/pattern/divider/divider_render_property.h"
42 #include "core/components_ng/pattern/image/image_layout_property.h"
43 #include "core/components_ng/pattern/image/image_pattern.h"
44 #include "core/components_ng/pattern/side_bar/side_bar_container_paint_method.h"
45 #include "core/components_ng/pattern/side_bar/side_bar_theme.h"
46 #include "core/components_ng/pattern/text/text_layout_property.h"
47 #include "core/components_ng/pattern/text/text_pattern.h"
48
49 #ifdef WINDOW_SCENE_SUPPORTED
50 #include "core/components_ng/pattern/window_scene/helper/window_scene_helper.h"
51 #endif
52 namespace OHOS::Ace::NG {
53
54 namespace {
55 constexpr int32_t DEFAULT_MIN_CHILDREN_SIZE = 3;
56 constexpr int32_t DIVIDER_HOT_ZONE_HORIZONTAL_PADDING_VALUE = 2;
57 constexpr float RATIO_NEGATIVE = -1.0f;
58 constexpr float RATIO_ZERO = 0.0f;
59 constexpr Dimension DEFAULT_DRAG_REGION = 20.0_vp;
60 constexpr int32_t SIDEBAR_DURATION = 500;
61 const RefPtr<CubicCurve> SIDEBAR_CURVE = AceType::MakeRefPtr<CubicCurve>(0.2f, 0.2f, 0.1f, 1.0f);
62 constexpr Dimension DEFAULT_DIVIDER_STROKE_WIDTH = 1.0_vp;
63 constexpr Dimension DEFAULT_DIVIDER_HOT_ZONE_HORIZONTAL_PADDING_VP = 2.0_vp;
64 constexpr Color DEFAULT_DIVIDER_COLOR = Color(0x08000000);
65 constexpr static int32_t PLATFORM_VERSION_TEN = 10;
66 constexpr static int32_t SIDE_BAR_INDEX = 2;
67 constexpr static int32_t CONTENT_INDEX = 3;
68 Dimension DEFAULT_CONTROL_BUTTON_WIDTH = 32.0_vp;
69 Dimension DEFAULT_CONTROL_BUTTON_HEIGHT = 32.0_vp;
70 Dimension SIDEBAR_WIDTH_NEGATIVE = -1.0_vp;
71 constexpr static Dimension DEFAULT_SIDE_BAR_WIDTH = 240.0_vp;
72 constexpr Dimension DEFAULT_MIN_SIDE_BAR_WIDTH = 240.0_vp;
73 constexpr Dimension DEFAULT_MAX_SIDE_BAR_WIDTH = 280.0_vp;
74 constexpr int32_t DEFAULT_MIN_CHILDREN_SIZE_WITHOUT_BUTTON_AND_DIVIDER = 1;
75 constexpr static int32_t DEFAULT_CONTROL_BUTTON_ZINDEX = 3;
76 constexpr static int32_t DEFAULT_SIDE_BAR_ZINDEX_EMBED = 0;
77 constexpr static int32_t DEFAULT_DIVIDER_ZINDEX_EMBED = 1;
78 constexpr static int32_t DEFAULT_CONTENT_ZINDEX_EMBED = 2;
79 constexpr static int32_t DEFAULT_SIDE_BAR_ZINDEX_OVERLAY = 2;
80 constexpr static int32_t DEFAULT_DIVIDER_ZINDEX_OVERLAY = 1;
81 constexpr static int32_t DEFAULT_CONTENT_ZINDEX_OVERLAY = 0;
82 constexpr static int32_t DEFAULT_DOUBLE_DRAG_REGION = 2;
83 } // namespace
84
OnAttachToFrameNode()85 void SideBarContainerPattern::OnAttachToFrameNode()
86 {
87 auto host = GetHost();
88 CHECK_NULL_VOID(host);
89 host->GetRenderContext()->SetClipToBounds(true);
90
91 auto layoutProperty = host->GetLayoutProperty<SideBarContainerLayoutProperty>();
92 CHECK_NULL_VOID(layoutProperty);
93 userSetSidebarWidth_ = layoutProperty->GetSideBarWidth().value_or(SIDEBAR_WIDTH_NEGATIVE);
94 auto pipelineContext = host->GetContext();
95 CHECK_NULL_VOID(pipelineContext);
96 pipelineContext->AddWindowSizeChangeCallback(host->GetId());
97 auto sideBarTheme = pipelineContext->GetTheme<SideBarTheme>();
98 if (sideBarTheme && sideBarTheme->GetSideBarUnfocusEffectEnable()) {
99 pipelineContext->AddWindowFocusChangedCallback(host->GetId());
100 }
101 }
102
OnDetachFromFrameNode(FrameNode * frameNode)103 void SideBarContainerPattern::OnDetachFromFrameNode(FrameNode* frameNode)
104 {
105 CHECK_NULL_VOID(frameNode);
106 auto pipeline = frameNode->GetContextWithCheck();
107 CHECK_NULL_VOID(pipeline);
108 pipeline->RemoveWindowSizeChangeCallback(frameNode->GetId());
109 pipeline->RemoveWindowFocusChangedCallback(frameNode->GetId());
110 }
111
OnUpdateShowSideBar(const RefPtr<SideBarContainerLayoutProperty> & layoutProperty)112 void SideBarContainerPattern::OnUpdateShowSideBar(const RefPtr<SideBarContainerLayoutProperty>& layoutProperty)
113 {
114 CHECK_NULL_VOID(layoutProperty);
115
116 type_ = layoutProperty->GetSideBarContainerType().value_or(SideBarContainerType::EMBED);
117
118 if (realSideBarWidth_.IsNegative()) {
119 realSideBarWidth_ = layoutProperty->GetSideBarWidth().value_or(SIDEBAR_WIDTH_NEGATIVE);
120 }
121
122 auto newShowSideBar = layoutProperty->GetShowSideBar().value_or(true);
123 if (newShowSideBar == userSetShowSideBar_) {
124 return;
125 }
126
127 if (hasInit_ && ((sideBarStatus_ == SideBarStatus::HIDDEN && newShowSideBar) ||
128 (sideBarStatus_ == SideBarStatus::SHOW && !newShowSideBar))) {
129 FireChangeEvent(newShowSideBar);
130 }
131
132 userSetShowSideBar_ = newShowSideBar;
133 SetSideBarStatus(newShowSideBar ? SideBarStatus::SHOW : SideBarStatus::HIDDEN);
134 UpdateControlButtonIcon();
135 auto host = GetHost();
136 CHECK_NULL_VOID(host);
137 auto sideBarNode = GetSideBarNode(host);
138 CHECK_NULL_VOID(sideBarNode);
139 if (!newShowSideBar && sideBarNode->IsFirstBuilding()) {
140 SetSideBarActive(false, false);
141 }
142 }
143
OnUpdateShowControlButton(const RefPtr<SideBarContainerLayoutProperty> & layoutProperty,const RefPtr<FrameNode> & host)144 void SideBarContainerPattern::OnUpdateShowControlButton(
145 const RefPtr<SideBarContainerLayoutProperty>& layoutProperty, const RefPtr<FrameNode>& host)
146 {
147 CHECK_NULL_VOID(layoutProperty);
148 CHECK_NULL_VOID(host);
149
150 auto showControlButton = layoutProperty->GetShowControlButton().value_or(true);
151
152 auto children = host->GetChildren();
153 if (children.empty()) {
154 return;
155 }
156
157 auto controlButtonNode = children.back();
158 if (controlButtonNode->GetTag() != V2::BUTTON_ETS_TAG || !AceType::InstanceOf<FrameNode>(controlButtonNode)) {
159 return;
160 }
161
162 controlImageWidth_ = layoutProperty->GetControlButtonWidth().value_or(DEFAULT_CONTROL_BUTTON_WIDTH);
163 controlImageHeight_ = layoutProperty->GetControlButtonHeight().value_or(DEFAULT_CONTROL_BUTTON_HEIGHT);
164 auto imageNode = controlButtonNode->GetFirstChild();
165 auto imageFrameNode = AceType::DynamicCast<FrameNode>(imageNode);
166 if (!imageFrameNode || imageFrameNode ->GetTag() != V2::IMAGE_ETS_TAG) {
167 return;
168 }
169 auto imageLayoutProperty = imageFrameNode->GetLayoutProperty<ImageLayoutProperty>();
170 CHECK_NULL_VOID(imageLayoutProperty);
171 CalcSize imageCalcSize((CalcLength(controlImageWidth_)), CalcLength(controlImageHeight_));
172 imageLayoutProperty->UpdateUserDefinedIdealSize(imageCalcSize);
173
174 auto buttonFrameNode = AceType::DynamicCast<FrameNode>(controlButtonNode);
175 auto buttonLayoutProperty = buttonFrameNode->GetLayoutProperty<ButtonLayoutProperty>();
176 CHECK_NULL_VOID(buttonLayoutProperty);
177
178 buttonLayoutProperty->UpdateVisibility(showControlButton ? VisibleType::VISIBLE : VisibleType::GONE);
179 buttonFrameNode->MarkModifyDone();
180 }
181
OnUpdateShowDivider(const RefPtr<SideBarContainerLayoutProperty> & layoutProperty,const RefPtr<FrameNode> & host)182 void SideBarContainerPattern::OnUpdateShowDivider(
183 const RefPtr<SideBarContainerLayoutProperty>& layoutProperty, const RefPtr<FrameNode>& host)
184 {
185 CHECK_NULL_VOID(layoutProperty);
186 CHECK_NULL_VOID(host);
187
188 auto dividerColor = layoutProperty->GetDividerColor().value_or(DEFAULT_DIVIDER_COLOR);
189 auto dividerStrokeWidth = layoutProperty->GetDividerStrokeWidth().value_or(DEFAULT_DIVIDER_STROKE_WIDTH);
190
191 auto children = host->GetChildren();
192 if (children.size() < DEFAULT_MIN_CHILDREN_SIZE) {
193 return;
194 }
195
196 auto begin = children.rbegin();
197 auto dividerNode = *(++begin);
198 CHECK_NULL_VOID(dividerNode);
199 if (dividerNode->GetTag() != V2::DIVIDER_ETS_TAG || !AceType::InstanceOf<FrameNode>(dividerNode)) {
200 return;
201 }
202
203 auto dividerFrameNode = AceType::DynamicCast<FrameNode>(dividerNode);
204 CHECK_NULL_VOID(dividerFrameNode);
205 auto dividerRenderProperty = dividerFrameNode->GetPaintProperty<DividerRenderProperty>();
206 CHECK_NULL_VOID(dividerRenderProperty);
207 dividerRenderProperty->UpdateDividerColor(dividerColor);
208
209 auto dividerLayoutProperty = dividerFrameNode->GetLayoutProperty<DividerLayoutProperty>();
210 CHECK_NULL_VOID(dividerLayoutProperty);
211 dividerLayoutProperty->UpdateStrokeWidth(dividerStrokeWidth);
212 dividerFrameNode->MarkModifyDone();
213 }
214
GetControlImageSize(Dimension & width,Dimension & height)215 void SideBarContainerPattern::GetControlImageSize(Dimension& width, Dimension& height)
216 {
217 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TEN)) {
218 DEFAULT_CONTROL_BUTTON_WIDTH = 24.0_vp;
219 DEFAULT_CONTROL_BUTTON_HEIGHT = 24.0_vp;
220 }
221 auto layoutProperty = GetLayoutProperty<SideBarContainerLayoutProperty>();
222 CHECK_NULL_VOID(layoutProperty);
223 controlImageWidth_ = layoutProperty->GetControlButtonWidth().value_or(DEFAULT_CONTROL_BUTTON_WIDTH);
224 controlImageHeight_ = layoutProperty->GetControlButtonHeight().value_or(DEFAULT_CONTROL_BUTTON_HEIGHT);
225 width = controlImageWidth_;
226 height = controlImageHeight_;
227 }
228
GetContentNode(const RefPtr<FrameNode> & host) const229 RefPtr<FrameNode> SideBarContainerPattern::GetContentNode(const RefPtr<FrameNode>& host) const
230 {
231 CHECK_NULL_RETURN(host, nullptr);
232
233 const auto& children = host->GetChildren();
234 if (children.size() <= CONTENT_INDEX) {
235 return nullptr;
236 }
237
238 auto iter = children.rbegin();
239 std::advance(iter, CONTENT_INDEX);
240 auto contentNode = AceType::DynamicCast<FrameNode>(*iter);
241 if (!contentNode) {
242 contentNode = GetFirstFrameNode(*iter);
243 }
244
245 return contentNode;
246 }
247
GetSideBarNode(const RefPtr<FrameNode> & host) const248 RefPtr<FrameNode> SideBarContainerPattern::GetSideBarNode(const RefPtr<FrameNode>& host) const
249 {
250 CHECK_NULL_RETURN(host, nullptr);
251
252 const auto& children = host->GetChildren();
253 if (children.size() < DEFAULT_MIN_CHILDREN_SIZE) {
254 return nullptr;
255 }
256
257 auto iter = children.rbegin();
258 std::advance(iter, SIDE_BAR_INDEX);
259 auto sideBarNode = AceType::DynamicCast<FrameNode>(*iter);
260 if (!sideBarNode) {
261 sideBarNode = GetFirstFrameNode(*iter);
262 }
263
264 return sideBarNode;
265 }
266
GetFirstFrameNode(const RefPtr<UINode> & host) const267 RefPtr<FrameNode> SideBarContainerPattern::GetFirstFrameNode(const RefPtr<UINode>& host) const
268 {
269 CHECK_NULL_RETURN(host, nullptr);
270 auto children = host->GetChildren();
271 while (!children.empty()) {
272 auto firstChild = children.front();
273 auto firstChildNode = AceType::DynamicCast<FrameNode>(firstChild);
274 if (firstChildNode) {
275 return firstChildNode;
276 }
277 children = firstChild->GetChildren();
278 }
279 TAG_LOGI(AceLogTag::ACE_SIDEBAR, "SideBarContainer can't find child frameNode to set ZIndex");
280 return nullptr;
281 }
282
OnColorConfigurationUpdate()283 void SideBarContainerPattern::OnColorConfigurationUpdate()
284 {
285 if (!SystemProperties::ConfigChangePerform()) {
286 return;
287 }
288 OnModifyDone();
289 }
290
GetSideBarNodeOrFirstChild() const291 RefPtr<FrameNode> SideBarContainerPattern::GetSideBarNodeOrFirstChild() const
292 {
293 auto host = GetHost();
294 CHECK_NULL_RETURN(host, nullptr);
295 const auto& children = host->GetChildren();
296 if (children.size() < DEFAULT_MIN_CHILDREN_SIZE) {
297 return nullptr;
298 }
299
300 auto iter = children.rbegin();
301 std::advance(iter, SIDE_BAR_INDEX);
302 if (AceType::InstanceOf<NG::CustomNode>(*iter)) {
303 auto sideBarNode = AceType::DynamicCast<CustomNode>(*iter);
304 CHECK_NULL_RETURN(sideBarNode, nullptr);
305 auto sideBarFirstChild = sideBarNode->GetChildren().front();
306 CHECK_NULL_RETURN(sideBarFirstChild, nullptr);
307 auto sideBarFirstChildNode = AceType::DynamicCast<FrameNode>(sideBarFirstChild);
308 CHECK_NULL_RETURN(sideBarFirstChildNode, nullptr);
309 return sideBarFirstChildNode;
310 }
311 auto sideBarNode = AceType::DynamicCast<FrameNode>(*iter);
312 CHECK_NULL_RETURN(sideBarNode, nullptr);
313 return sideBarNode;
314 }
315
GetControlButtonNode() const316 RefPtr<FrameNode> SideBarContainerPattern::GetControlButtonNode() const
317 {
318 auto host = GetHost();
319 CHECK_NULL_RETURN(host, nullptr);
320 auto children = host->GetChildren();
321 if (children.empty()) {
322 return nullptr;
323 }
324 auto controlButtonNode = children.back();
325 if (controlButtonNode->GetTag() != V2::BUTTON_ETS_TAG || !AceType::InstanceOf<FrameNode>(controlButtonNode)) {
326 return nullptr;
327 }
328 return AceType::DynamicCast<FrameNode>(controlButtonNode);
329 }
330
GetControlImageNode() const331 RefPtr<FrameNode> SideBarContainerPattern::GetControlImageNode() const
332 {
333 auto host = GetHost();
334 CHECK_NULL_RETURN(host, nullptr);
335
336 auto children = host->GetChildren();
337 if (children.empty()) {
338 return nullptr;
339 }
340
341 auto controlButtonNode = children.back();
342 if (controlButtonNode->GetTag() != V2::BUTTON_ETS_TAG || !AceType::InstanceOf<FrameNode>(controlButtonNode)) {
343 return nullptr;
344 }
345
346 auto buttonChildren = controlButtonNode->GetChildren();
347 if (buttonChildren.empty()) {
348 return nullptr;
349 }
350
351 auto imageNode = buttonChildren.front();
352 if (imageNode->GetTag() != V2::IMAGE_ETS_TAG || !AceType::InstanceOf<FrameNode>(imageNode)) {
353 return nullptr;
354 }
355 return AceType::DynamicCast<FrameNode>(imageNode);
356 }
357
GetDividerNode() const358 RefPtr<FrameNode> SideBarContainerPattern::GetDividerNode() const
359 {
360 auto host = GetHost();
361 CHECK_NULL_RETURN(host, nullptr);
362 auto children = host->GetChildren();
363 if (children.size() < DEFAULT_MIN_CHILDREN_SIZE) {
364 return nullptr;
365 }
366
367 auto begin = children.rbegin();
368 auto dividerNode = *(++begin);
369 CHECK_NULL_RETURN(dividerNode, nullptr);
370 if (dividerNode->GetTag() != V2::DIVIDER_ETS_TAG || !AceType::InstanceOf<FrameNode>(dividerNode)) {
371 return nullptr;
372 }
373
374 return AceType::DynamicCast<FrameNode>(dividerNode);
375 }
376
OnUpdateSideBarAndContent(const RefPtr<FrameNode> & host)377 void SideBarContainerPattern::OnUpdateSideBarAndContent(const RefPtr<FrameNode>& host)
378 {
379 CHECK_NULL_VOID(host);
380 auto sideBarNode = GetSideBarNode(host);
381 CHECK_NULL_VOID(sideBarNode);
382 auto sideBarContext = sideBarNode->GetRenderContext();
383 CHECK_NULL_VOID(sideBarContext);
384
385 if (!sideBarContext->GetClipEdge().has_value() && !sideBarContext->GetClipShape().has_value()) {
386 sideBarContext->SetClipToBounds(true);
387 }
388
389 auto contentNode = GetContentNode(host);
390 CHECK_NULL_VOID(contentNode);
391 auto contentContext = contentNode->GetRenderContext();
392 CHECK_NULL_VOID(contentContext);
393 if (!contentContext->GetClipEdge().has_value() && !contentContext->GetClipShape().has_value()) {
394 contentContext->SetClipToBounds(true);
395 }
396 }
397
OnModifyDone()398 void SideBarContainerPattern::OnModifyDone()
399 {
400 Pattern::OnModifyDone();
401
402 auto host = GetHost();
403 CHECK_NULL_VOID(host);
404
405 CreateAndMountNodes();
406
407 auto hub = host->GetOrCreateEventHub<EventHub>();
408 CHECK_NULL_VOID(hub);
409 auto gestureHub = hub->GetOrCreateGestureEventHub();
410 CHECK_NULL_VOID(gestureHub);
411
412 InitPanEvent(gestureHub);
413
414 auto layoutProperty = host->GetLayoutProperty<SideBarContainerLayoutProperty>();
415 OnUpdateShowSideBar(layoutProperty);
416 OnUpdateShowControlButton(layoutProperty, host);
417 OnUpdateShowDivider(layoutProperty, host);
418 UpdateControlButtonIcon();
419
420 auto pipeline = host->GetContextRefPtr();
421 CHECK_NULL_VOID(pipeline);
422 if (pipeline->GetMinPlatformVersion() >= PLATFORM_VERSION_TEN) {
423 OnUpdateSideBarAndContent(host);
424 }
425
426 CHECK_NULL_VOID(layoutProperty);
427 if ((userSetSidebarWidth_ != layoutProperty->GetSideBarWidth().value_or(SIDEBAR_WIDTH_NEGATIVE)) ||
428 (layoutProperty->GetSideBarWidth().value_or(SIDEBAR_WIDTH_NEGATIVE) == DEFAULT_SIDE_BAR_WIDTH)) {
429 preSidebarWidth_.Reset();
430 userSetSidebarWidth_ = layoutProperty->GetSideBarWidth().value_or(SIDEBAR_WIDTH_NEGATIVE);
431 }
432
433 if (!hasInit_) {
434 hasInit_ = true;
435 }
436 SideBarModifyDoneToolBarManager();
437 UpdateSideBarColorToToolbarManager();
438 }
439
CreateAndMountNodes()440 void SideBarContainerPattern::CreateAndMountNodes()
441 {
442 auto host = GetHost();
443 CHECK_NULL_VOID(host);
444
445 auto children = host->GetChildren();
446 if (children.size() < DEFAULT_MIN_CHILDREN_SIZE_WITHOUT_BUTTON_AND_DIVIDER) {
447 return;
448 }
449
450 if (HasControlButton()) {
451 UpdateDividerShadow();
452 return;
453 }
454 auto sideBarNode = children.front();
455 sideBarNode->MovePosition(DEFAULT_NODE_SLOT);
456 auto sideBarFrameNode = AceType::DynamicCast<FrameNode>(sideBarNode);
457 if (sideBarFrameNode) {
458 auto renderContext = sideBarFrameNode->GetRenderContext();
459 CHECK_NULL_VOID(renderContext);
460 if (!renderContext->HasBackgroundColor()) {
461 auto context = host->GetContextRefPtr();
462 CHECK_NULL_VOID(context);
463 auto sideBarTheme = context->GetTheme<SideBarTheme>();
464 CHECK_NULL_VOID(sideBarTheme);
465 Color bgColor = sideBarTheme->GetSideBarBackgroundColor();
466 renderContext->UpdateBackgroundColor(bgColor);
467 }
468 if (SystemProperties::GetSideBarContainerBlurEnable() &&
469 Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN) &&
470 !renderContext->GetBackBlurStyle().has_value()) {
471 BlurStyleOption blurStyleOption;
472 blurStyleOption.blurStyle = BlurStyle::COMPONENT_THICK;
473 renderContext->UpdateBackBlurStyle(blurStyleOption);
474 }
475 }
476 host->RebuildRenderContextTree();
477 CreateAndMountDivider(host);
478 CreateAndMountControlButton(host);
479 UpdateDividerShadow();
480 }
481
UpdateDividerShadow() const482 void SideBarContainerPattern::UpdateDividerShadow() const
483 {
484 auto host = GetHost();
485 CHECK_NULL_VOID(host);
486 auto context = host->GetContextRefPtr();
487 CHECK_NULL_VOID(context);
488 auto sidebarTheme = context->GetTheme<SideBarTheme>();
489 CHECK_NULL_VOID(sidebarTheme);
490 auto layoutProperty = host->GetLayoutProperty<SideBarContainerLayoutProperty>();
491 CHECK_NULL_VOID(layoutProperty);
492 if (!sidebarTheme->GetDividerShadowEnable()) {
493 return;
494 }
495
496 auto sideBarContainerType = layoutProperty->GetSideBarContainerType().value_or(SideBarContainerType::EMBED);
497 auto sidebarNode = GetSideBarNode(host);
498 if (sidebarNode) {
499 auto renderContext = sidebarNode->GetRenderContext();
500 renderContext->UpdateZIndex(SideBarContainerType::EMBED == sideBarContainerType
501 ? DEFAULT_SIDE_BAR_ZINDEX_EMBED
502 : DEFAULT_SIDE_BAR_ZINDEX_OVERLAY);
503 }
504 auto dividerNode = GetDividerNode();
505 if (dividerNode) {
506 auto renderContext = dividerNode->GetRenderContext();
507 renderContext->UpdateZIndex(SideBarContainerType::EMBED == sideBarContainerType
508 ? DEFAULT_DIVIDER_ZINDEX_EMBED
509 : DEFAULT_DIVIDER_ZINDEX_OVERLAY);
510 renderContext->UpdateBackShadow(ShadowConfig::DefaultShadowXS);
511 }
512 auto contentNode = GetContentNode(host);
513 if (contentNode) {
514 auto renderContext = contentNode->GetRenderContext();
515 renderContext->UpdateZIndex(SideBarContainerType::EMBED == sideBarContainerType
516 ? DEFAULT_CONTENT_ZINDEX_EMBED
517 : DEFAULT_CONTENT_ZINDEX_OVERLAY);
518 }
519 auto controlBtnNode = GetControlButtonNode();
520 if (controlBtnNode) {
521 auto renderContext = controlBtnNode->GetRenderContext();
522 renderContext->UpdateZIndex(DEFAULT_CONTROL_BUTTON_ZINDEX);
523 }
524 }
525
SetSideBarActive(bool isActive,bool onlyJsActive) const526 void SideBarContainerPattern::SetSideBarActive(bool isActive, bool onlyJsActive) const
527 {
528 auto host = GetHost();
529 CHECK_NULL_VOID(host);
530 auto sideBarNode = GetSideBarNode(host);
531 CHECK_NULL_VOID(sideBarNode);
532 sideBarNode->SetJSViewActive(isActive);
533 if (!onlyJsActive) {
534 sideBarNode->SetActive(isActive);
535 }
536 }
537
CreateAndMountDivider(const RefPtr<NG::FrameNode> & parentNode)538 void SideBarContainerPattern::CreateAndMountDivider(const RefPtr<NG::FrameNode>& parentNode)
539 {
540 CHECK_NULL_VOID(parentNode);
541 auto layoutProperty = parentNode->GetLayoutProperty<SideBarContainerLayoutProperty>();
542 CHECK_NULL_VOID(layoutProperty);
543
544 auto dividerColor = layoutProperty->GetDividerColor().value_or(DEFAULT_DIVIDER_COLOR);
545 auto dividerStrokeWidth = layoutProperty->GetDividerStrokeWidth().value_or(DEFAULT_DIVIDER_STROKE_WIDTH);
546
547 int32_t dividerNodeId = ElementRegister::GetInstance()->MakeUniqueId();
548 auto dividerNode = FrameNode::GetOrCreateFrameNode(
549 V2::DIVIDER_ETS_TAG, dividerNodeId, []() { return AceType::MakeRefPtr<DividerPattern>(); });
550
551 auto dividerHub = dividerNode->GetOrCreateEventHub<EventHub>();
552 CHECK_NULL_VOID(dividerHub);
553 auto inputHub = dividerHub->GetOrCreateInputEventHub();
554 CHECK_NULL_VOID(inputHub);
555 InitDividerMouseEvent(inputHub);
556
557 auto dividerRenderProperty = dividerNode->GetPaintProperty<DividerRenderProperty>();
558 CHECK_NULL_VOID(dividerRenderProperty);
559 dividerRenderProperty->UpdateDividerColor(dividerColor);
560
561 auto dividerLayoutProperty = dividerNode->GetLayoutProperty<DividerLayoutProperty>();
562 CHECK_NULL_VOID(dividerLayoutProperty);
563 dividerLayoutProperty->UpdateVertical(true);
564 dividerLayoutProperty->UpdateStrokeWidth(dividerStrokeWidth);
565 auto host = GetHost();
566 CHECK_NULL_VOID(host);
567 auto context = host->GetContextRefPtr();
568 CHECK_NULL_VOID(context);
569 auto sideBarTheme = context->GetTheme<SideBarTheme>();
570 CHECK_NULL_VOID(sideBarTheme);
571 auto renderContext = dividerNode->GetRenderContext();
572 CHECK_NULL_VOID(renderContext);
573 if (sideBarTheme->GetDividerShadowEnable()) {
574 renderContext->UpdateBackShadow(ShadowConfig::DefaultShadowXS);
575 }
576 renderContext->UpdateZIndex(DEFAULT_DIVIDER_ZINDEX_EMBED);
577 dividerNode->MountToParent(parentNode);
578 dividerNode->MarkModifyDone();
579 }
580
CreateAndMountControlButton(const RefPtr<NG::FrameNode> & parentNode)581 void SideBarContainerPattern::CreateAndMountControlButton(const RefPtr<NG::FrameNode>& parentNode)
582 {
583 auto host = GetHost();
584 CHECK_NULL_VOID(host);
585 auto context = host->GetContextRefPtr();
586 CHECK_NULL_VOID(context);
587 auto sideBarTheme = context->GetTheme<SideBarTheme>(host->GetThemeScopeId());
588 CHECK_NULL_VOID(sideBarTheme);
589
590 auto buttonNode = CreateControlButton(sideBarTheme);
591 CHECK_NULL_VOID(buttonNode);
592 RegisterElementInfoCallBack(buttonNode);
593 auto imgNode = CreateControlImage(sideBarTheme, parentNode);
594 CHECK_NULL_VOID(imgNode);
595
596 auto buttonHub = buttonNode->GetOrCreateEventHub<EventHub>();
597 CHECK_NULL_VOID(buttonHub);
598 auto gestureHub = buttonHub->GetOrCreateGestureEventHub();
599 CHECK_NULL_VOID(gestureHub);
600 SetHasControlButton(true);
601 InitControlButtonTouchEvent(gestureHub);
602 InitLongPressEvent(buttonNode);
603
604 imgNode->MountToParent(buttonNode);
605 buttonNode->MountToParent(parentNode);
606 imgNode->MarkModifyDone();
607 buttonNode->MarkModifyDone();
608 }
609
CreateControlButton(const RefPtr<SideBarTheme> & sideBarTheme)610 RefPtr<FrameNode> SideBarContainerPattern::CreateControlButton(const RefPtr<SideBarTheme>& sideBarTheme)
611 {
612 CHECK_NULL_RETURN(sideBarTheme, nullptr);
613 int32_t buttonId = ElementRegister::GetInstance()->MakeUniqueId();
614 auto buttonNode = FrameNode::GetOrCreateFrameNode(
615 V2::BUTTON_ETS_TAG, buttonId, []() { return AceType::MakeRefPtr<ButtonPattern>(); });
616 CHECK_NULL_RETURN(buttonNode, nullptr);
617 auto buttonLayoutProperty = buttonNode->GetLayoutProperty<ButtonLayoutProperty>();
618 CHECK_NULL_RETURN(buttonLayoutProperty, nullptr);
619 buttonLayoutProperty->UpdateType(ButtonType::NORMAL);
620 auto buttonRadius = sideBarTheme->GetControlButtonRadius();
621 buttonLayoutProperty->UpdateBorderRadius(BorderRadiusProperty(buttonRadius));
622 buttonLayoutProperty->UpdateCreateWithLabel(false);
623 auto buttonRenderContext = buttonNode->GetRenderContext();
624 CHECK_NULL_RETURN(buttonRenderContext, nullptr);
625 buttonRenderContext->UpdateBackgroundColor(Color::TRANSPARENT);
626 buttonRenderContext->UpdateZIndex(DEFAULT_CONTROL_BUTTON_ZINDEX);
627 auto focusHub = buttonNode->GetOrCreateFocusHub();
628 CHECK_NULL_RETURN(focusHub, nullptr);
629 focusHub->SetFocusDependence(FocusDependence::SELF);
630 return buttonNode;
631 }
632
CreateControlImage(const RefPtr<SideBarTheme> & sideBarTheme,const RefPtr<FrameNode> & parentNode)633 RefPtr<FrameNode> SideBarContainerPattern::CreateControlImage(
634 const RefPtr<SideBarTheme>& sideBarTheme, const RefPtr<FrameNode>& parentNode)
635 {
636 CHECK_NULL_RETURN(sideBarTheme, nullptr);
637 int32_t imgNodeId = ElementRegister::GetInstance()->MakeUniqueId();
638 auto imgNode = FrameNode::GetOrCreateFrameNode(
639 V2::IMAGE_ETS_TAG, imgNodeId, []() { return AceType::MakeRefPtr<ImagePattern>(); });
640 CHECK_NULL_RETURN(imgNode, nullptr);
641
642 auto layoutProperty = parentNode->GetLayoutProperty<SideBarContainerLayoutProperty>();
643 CHECK_NULL_RETURN(layoutProperty, nullptr);
644 auto isShowSideBar = layoutProperty->GetShowSideBar().value_or(true);
645 std::optional<ImageSourceInfo> info = std::nullopt;
646 if (isShowSideBar) {
647 info = layoutProperty->GetControlButtonShowIconInfo();
648 } else {
649 info = layoutProperty->GetControlButtonHiddenIconInfo();
650 }
651 if (!info.has_value()) {
652 info = std::make_optional<ImageSourceInfo>();
653 info->SetResourceId(InternalResource::ResourceId::SIDE_BAR);
654 Color controlButtonColor = sideBarTheme->GetControlImageColor();
655 info->SetFillColor(controlButtonColor);
656 }
657 imageInfo_ = info.value();
658 auto imageLayoutProperty = imgNode->GetLayoutProperty<ImageLayoutProperty>();
659 CHECK_NULL_RETURN(imageLayoutProperty, nullptr);
660 imageLayoutProperty->UpdateImageSourceInfo(info.value());
661 imageLayoutProperty->UpdateImageFit(ImageFit::FILL);
662 imageLayoutProperty->UpdateAlignment(Alignment::CENTER);
663 Dimension imageWidth;
664 Dimension imageHeight;
665 GetControlImageSize(imageWidth, imageHeight);
666 CalcSize imageCalcSize((CalcLength(imageWidth)), CalcLength(imageHeight));
667 imageLayoutProperty->UpdateUserDefinedIdealSize(imageCalcSize);
668 InitImageErrorCallback(sideBarTheme, imgNode);
669 return imgNode;
670 }
671
InitPanEvent(const RefPtr<GestureEventHub> & gestureHub)672 void SideBarContainerPattern::InitPanEvent(const RefPtr<GestureEventHub>& gestureHub)
673 {
674 CHECK_NULL_VOID(!dragEvent_);
675
676 auto actionStartTask = [weak = WeakClaim(this)](const GestureEvent& info) {
677 auto pattern = weak.Upgrade();
678 CHECK_NULL_VOID(pattern);
679 pattern->HandleDragStart();
680 };
681
682 auto actionUpdateTask = [weak = WeakClaim(this)](const GestureEvent& info) {
683 auto pattern = weak.Upgrade();
684 CHECK_NULL_VOID(pattern);
685 pattern->HandleDragUpdate(static_cast<float>(info.GetOffsetX()));
686 };
687
688 auto actionEndTask = [weak = WeakClaim(this)](const GestureEvent& info) {
689 auto pattern = weak.Upgrade();
690 CHECK_NULL_VOID(pattern);
691 pattern->HandleDragEnd();
692 };
693
694 auto actionCancelTask = [weak = WeakClaim(this)]() {
695 auto pattern = weak.Upgrade();
696 CHECK_NULL_VOID(pattern);
697 pattern->HandleDragEnd();
698 };
699
700 dragEvent_ = MakeRefPtr<PanEvent>(
701 std::move(actionStartTask), std::move(actionUpdateTask), std::move(actionEndTask), std::move(actionCancelTask));
702 PanDirection panDirection = { .type = PanDirection::HORIZONTAL };
703
704 auto dividerNode = GetDividerNode();
705 CHECK_NULL_VOID(dividerNode);
706 auto dividerGestureHub = dividerNode->GetOrCreateGestureEventHub();
707 CHECK_NULL_VOID(dividerGestureHub);
708 PanDistanceMap distanceMap = { { SourceTool::UNKNOWN, DEFAULT_PAN_DISTANCE.ConvertToPx() },
709 { SourceTool::PEN, DEFAULT_PEN_PAN_DISTANCE.ConvertToPx() } };
710 dividerGestureHub->AddPanEvent(dragEvent_, panDirection, DEFAULT_PAN_FINGER, distanceMap);
711 }
712
CreateAnimation()713 void SideBarContainerPattern::CreateAnimation()
714 {
715 auto host = GetHost();
716 CHECK_NULL_VOID(host);
717
718 if (!controller_) {
719 controller_ = CREATE_ANIMATOR(host->GetContextRefPtr());
720 }
721
722 auto weak = AceType::WeakClaim(this);
723 if (!rightToLeftAnimation_) {
724 rightToLeftAnimation_ =
725 AceType::MakeRefPtr<CurveAnimation<float>>(RATIO_ZERO, RATIO_NEGATIVE, Curves::FRICTION);
726 rightToLeftAnimation_->AddListener(Animation<float>::ValueCallback([weak](float value) {
727 auto pattern = weak.Upgrade();
728 if (pattern) {
729 pattern->UpdateSideBarPosition(value);
730 }
731 }));
732 }
733
734 if (!leftToRightAnimation_) {
735 leftToRightAnimation_ =
736 AceType::MakeRefPtr<CurveAnimation<float>>(RATIO_NEGATIVE, RATIO_ZERO, Curves::FRICTION);
737 leftToRightAnimation_->AddListener(Animation<float>::ValueCallback([weak](float value) {
738 auto pattern = weak.Upgrade();
739 if (pattern) {
740 pattern->UpdateSideBarPosition(value);
741 }
742 }));
743 }
744 }
745
InitControlButtonTouchEvent(const RefPtr<GestureEventHub> & gestureHub)746 void SideBarContainerPattern::InitControlButtonTouchEvent(const RefPtr<GestureEventHub>& gestureHub)
747 {
748 CHECK_NULL_VOID(!controlButtonClickEvent_);
749
750 auto clickTask = [weak = WeakClaim(this)](const GestureEvent& info) {
751 auto pattern = weak.Upgrade();
752 CHECK_NULL_VOID(pattern);
753 if (!pattern->inAnimation_) {
754 pattern->SetControlButtonClick(true);
755 pattern->DoAnimation();
756 }
757 };
758 controlButtonClickEvent_ = MakeRefPtr<ClickEvent>(std::move(clickTask));
759 gestureHub->AddClickEvent(controlButtonClickEvent_);
760 }
761
UpdateAnimDir()762 void SideBarContainerPattern::UpdateAnimDir()
763 {
764 auto layoutProperty = GetLayoutProperty<SideBarContainerLayoutProperty>();
765 CHECK_NULL_VOID(layoutProperty);
766 auto sideBarPosition = GetSideBarPositionWithRtl(layoutProperty);
767
768 switch (sideBarStatus_) {
769 case SideBarStatus::HIDDEN:
770 if (sideBarPosition == SideBarPosition::START) {
771 animDir_ = SideBarAnimationDirection::LTR;
772 } else {
773 animDir_ = SideBarAnimationDirection::RTL;
774 }
775 break;
776 case SideBarStatus::SHOW:
777 if (sideBarPosition == SideBarPosition::START) {
778 animDir_ = SideBarAnimationDirection::RTL;
779 } else {
780 animDir_ = SideBarAnimationDirection::LTR;
781 }
782 break;
783 default:
784 break;
785 }
786 }
787
DoAnimation()788 void SideBarContainerPattern::DoAnimation()
789 {
790 auto host = GetHost();
791 CHECK_NULL_VOID(host);
792
793 if (autoHide_) {
794 sideBarStatus_ = SideBarStatus::HIDDEN;
795 }
796
797 SetSideBarActive(true, false);
798 UpdateAnimDir();
799
800 AnimationOption option = AnimationOption();
801 option.SetDuration(SIDEBAR_DURATION);
802 option.SetCurve(SIDEBAR_CURVE);
803 option.SetFillMode(FillMode::FORWARDS);
804
805 auto sideBarStatus = sideBarStatus_;
806 sideBarStatus_ = SideBarStatus::CHANGING;
807 UpdateControlButtonIcon();
808
809 // fire before animation to include user changes in onChange event
810 FireChangeEvent(sideBarStatus == SideBarStatus::HIDDEN);
811
812 auto weak = AceType::WeakClaim(this);
813 auto context = host->GetContextRefPtr();
814 CHECK_NULL_VOID(context);
815 inAnimation_ = true;
816 context->OpenImplicitAnimation(option, option.GetCurve(), [weak, sideBarStatus]() {
817 auto pattern = weak.Upgrade();
818 if (pattern) {
819 if (sideBarStatus == SideBarStatus::HIDDEN) {
820 pattern->SetSideBarStatus(SideBarStatus::SHOW);
821 pattern->UpdateControlButtonIcon();
822 } else {
823 pattern->SetSideBarStatus(SideBarStatus::HIDDEN);
824 pattern->UpdateControlButtonIcon();
825 pattern->SetSideBarActive(false, false);
826 }
827 pattern->inAnimation_ = false;
828 }
829 });
830
831 auto layoutProperty = GetLayoutProperty<SideBarContainerLayoutProperty>();
832 CHECK_NULL_VOID(layoutProperty);
833 auto sideBarPosition = GetSideBarPositionWithRtl(layoutProperty);
834 auto realSideBarWidthPx = DimensionConvertToPx(realSideBarWidth_).value_or(0.0);
835 if (sideBarPosition == SideBarPosition::START) {
836 if (animDir_ == SideBarAnimationDirection::LTR) {
837 currentOffset_ = 0.0f;
838 } else {
839 currentOffset_ = -realSideBarWidthPx - realDividerWidth_;
840 }
841 } else {
842 if (animDir_ == SideBarAnimationDirection::LTR) {
843 currentOffset_ = 0.0f + realDividerWidth_;
844 } else {
845 currentOffset_ = -realSideBarWidthPx;
846 }
847 }
848
849 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
850 context->FlushUITasks();
851 context->CloseImplicitAnimation();
852 }
853
HandlePanEventEnd()854 void SideBarContainerPattern::HandlePanEventEnd()
855 {
856 if (sideBarStatus_ == SideBarStatus::HIDDEN) {
857 DoAnimation();
858 }
859 }
860
UpdateSideBarPosition(float value)861 void SideBarContainerPattern::UpdateSideBarPosition(float value)
862 {
863 auto host = GetHost();
864 CHECK_NULL_VOID(host);
865
866 if (sideBarStatus_ != SideBarStatus::CHANGING) {
867 sideBarStatus_ = SideBarStatus::CHANGING;
868 UpdateControlButtonIcon();
869 }
870
871 auto realSideBarWidthPx = DimensionConvertToPx(realSideBarWidth_).value_or(0.0);
872 currentOffset_ = value * (realSideBarWidthPx + realDividerWidth_);
873 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
874 }
875
FireChangeEvent(bool isShow)876 void SideBarContainerPattern::FireChangeEvent(bool isShow)
877 {
878 auto sideBarContainerEventHub = GetOrCreateEventHub<SideBarContainerEventHub>();
879 CHECK_NULL_VOID(sideBarContainerEventHub);
880
881 sideBarContainerEventHub->FireChangeEvent(isShow);
882
883 if (Recorder::EventRecorder::Get().IsComponentRecordEnable()) {
884 Recorder::EventParamsBuilder builder;
885 auto host = GetHost();
886 CHECK_NULL_VOID(host);
887 auto inspectorId = host->GetInspectorId().value_or("");
888 builder.SetId(inspectorId)
889 .SetType(host->GetTag())
890 .SetChecked(isShow)
891 .SetHost(host)
892 .SetDescription(host->GetAutoEventParamValue(""));
893 Recorder::EventRecorder::Get().OnChange(std::move(builder));
894 }
895 }
896
UpdateControlButtonIcon()897 void SideBarContainerPattern::UpdateControlButtonIcon()
898 {
899 auto layoutProperty = GetLayoutProperty<SideBarContainerLayoutProperty>();
900 CHECK_NULL_VOID(layoutProperty);
901
902 auto imgFrameNode = GetControlImageNode();
903 CHECK_NULL_VOID(imgFrameNode);
904
905 auto imgRenderContext = imgFrameNode->GetRenderContext();
906 auto imageLayoutProperty = imgFrameNode->GetLayoutProperty<ImageLayoutProperty>();
907 CHECK_NULL_VOID(imageLayoutProperty);
908 std::optional<ImageSourceInfo> imgSourceInfo = std::nullopt;
909
910 auto host = GetHost();
911 CHECK_NULL_VOID(host);
912 auto context = host->GetContextRefPtr();
913 CHECK_NULL_VOID(context);
914 auto sideBarTheme = context->GetTheme<SideBarTheme>(host->GetThemeScopeId());
915 CHECK_NULL_VOID(sideBarTheme);
916 Color controlButtonColor = sideBarTheme->GetControlImageColor();
917
918 switch (sideBarStatus_) {
919 case SideBarStatus::SHOW:
920 imgSourceInfo = layoutProperty->GetControlButtonShowIconInfo();
921 break;
922 case SideBarStatus::HIDDEN:
923 imgSourceInfo = layoutProperty->GetControlButtonHiddenIconInfo();
924 break;
925 case SideBarStatus::CHANGING:
926 imgSourceInfo = layoutProperty->GetControlButtonSwitchingIconInfo();
927 break;
928 default:
929 break;
930 }
931
932 if (!imgSourceInfo.has_value()) {
933 imgSourceInfo = std::make_optional<ImageSourceInfo>();
934 imgSourceInfo->SetResourceId(InternalResource::ResourceId::SIDE_BAR);
935 imgSourceInfo->SetFillColor(controlButtonColor);
936 }
937 imageInfo_ = imgSourceInfo.value();
938 imageLayoutProperty->UpdateImageSourceInfo(imgSourceInfo.value());
939 imgFrameNode->MarkModifyDone();
940 }
941
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,const DirtySwapConfig & config)942 bool SideBarContainerPattern::OnDirtyLayoutWrapperSwap(
943 const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config)
944 {
945 auto layoutAlgorithmWrapper = DynamicCast<LayoutAlgorithmWrapper>(dirty->GetLayoutAlgorithm());
946 CHECK_NULL_RETURN(layoutAlgorithmWrapper, false);
947 auto layoutAlgorithm = DynamicCast<SideBarContainerLayoutAlgorithm>(layoutAlgorithmWrapper->GetLayoutAlgorithm());
948 CHECK_NULL_RETURN(layoutAlgorithm, false);
949
950 realDividerWidth_ = layoutAlgorithm->GetRealDividerWidth();
951 realSideBarWidth_ = layoutAlgorithm->GetRealSideBarWidth();
952 realSideBarHeight_ = layoutAlgorithm->GetRealSideBarHeight();
953 AddDividerHotZoneRect(layoutAlgorithm);
954
955 if (needInitRealSideBarWidth_) {
956 needInitRealSideBarWidth_ = false;
957 }
958
959 if (isControlButtonClick_) {
960 isControlButtonClick_ = false;
961 }
962
963 if (autoHide_ != layoutAlgorithm->GetAutoHide()) {
964 FireChangeEvent(layoutAlgorithm->GetSideBarStatus() == SideBarStatus::SHOW);
965 }
966
967 if (!inAnimation_) {
968 SetSideBarActive(layoutAlgorithm->GetSideBarStatus() == SideBarStatus::SHOW, true);
969 }
970
971 adjustMaxSideBarWidth_ = layoutAlgorithm->GetAdjustMaxSideBarWidth();
972 adjustMinSideBarWidth_ = layoutAlgorithm->GetAdjustMinSideBarWidth();
973 type_ = layoutAlgorithm->GetSideBarContainerType();
974 autoHide_ = layoutAlgorithm->GetAutoHide();
975
976 auto layoutProperty = GetLayoutProperty<SideBarContainerLayoutProperty>();
977 CHECK_NULL_RETURN(layoutProperty, false);
978 const auto& paddingProperty = layoutProperty->GetPaddingProperty();
979 UpdateSideBarStatus();
980 return paddingProperty != nullptr;
981 }
982
UpdateSideBarStatus()983 void SideBarContainerPattern::UpdateSideBarStatus()
984 {
985 auto host = GetHost();
986 auto geometryNode = host->GetGeometryNode();
987 CHECK_NULL_VOID(geometryNode);
988 auto layoutProperty = GetLayoutProperty<SideBarContainerLayoutProperty>();
989 CHECK_NULL_VOID(layoutProperty);
990 auto frameSize = geometryNode->GetFrameSize();
991 bool showSideBar = true;
992 if (type_ == SideBarContainerType::OVERLAY) {
993 showSideBar = false;
994 } else if (autoHide_) {
995 showSideBar = false;
996 } else {
997 switch (sideBarStatus_) {
998 case SideBarStatus::SHOW: {
999 showSideBar = true;
1000 break;
1001 }
1002 case SideBarStatus::HIDDEN: {
1003 showSideBar = false;
1004 break;
1005 }
1006 case SideBarStatus::CHANGING: {
1007 if (inAnimation_) {
1008 showSideBar = !showSideBar_;
1009 }
1010 break;
1011 }
1012 default: {
1013 showSideBar = layoutProperty->GetShowSideBar().value_or(true);
1014 break;
1015 }
1016 }
1017 }
1018 SetSideBarWidthToolBarManager(
1019 showSideBar, realSideBarWidth_.ConvertToPxWithSize(frameSize.Width()), realDividerWidth_);
1020 }
1021
AddDividerHotZoneRect(const RefPtr<SideBarContainerLayoutAlgorithm> & layoutAlgorithm)1022 void SideBarContainerPattern::AddDividerHotZoneRect(const RefPtr<SideBarContainerLayoutAlgorithm>& layoutAlgorithm)
1023 {
1024 CHECK_NULL_VOID(layoutAlgorithm);
1025 if (realDividerWidth_ < 0.0f) {
1026 return;
1027 }
1028
1029 auto dividerFrameNode = GetDividerNode();
1030 CHECK_NULL_VOID(dividerFrameNode);
1031 auto geometryNode = dividerFrameNode->GetGeometryNode();
1032 CHECK_NULL_VOID(geometryNode);
1033 auto dividerHeight = geometryNode->GetFrameSize().Height();
1034 auto layoutProperty = GetLayoutProperty<SideBarContainerLayoutProperty>();
1035 CHECK_NULL_VOID(layoutProperty);
1036
1037 OffsetF hotZoneOffset;
1038 hotZoneOffset.SetX(-DEFAULT_DIVIDER_HOT_ZONE_HORIZONTAL_PADDING_VP.ConvertToPx());
1039 SizeF hotZoneSize;
1040 auto baseWidth = NearZero(realDividerWidth_, 0.0f) ?
1041 DEFAULT_DIVIDER_STROKE_WIDTH.ConvertToPx() : realDividerWidth_;
1042 hotZoneSize.SetWidth(baseWidth + DIVIDER_HOT_ZONE_HORIZONTAL_PADDING_VALUE *
1043 DEFAULT_DIVIDER_HOT_ZONE_HORIZONTAL_PADDING_VP.ConvertToPx());
1044 hotZoneSize.SetHeight(dividerHeight);
1045
1046 DimensionRect hotZoneRegion;
1047 hotZoneRegion.SetSize(DimensionSize(Dimension(hotZoneSize.Width()), Dimension(hotZoneSize.Height())));
1048 hotZoneRegion.SetOffset(DimensionOffset(Dimension(hotZoneOffset.GetX()), Dimension(hotZoneOffset.GetY())));
1049
1050 std::vector<DimensionRect> mouseRegion;
1051 mouseRegion.emplace_back(hotZoneRegion);
1052
1053 dividerFrameNode->SetHitTestMode(HitTestMode::HTMTRANSPARENT);
1054 auto dividerGestureHub = dividerFrameNode->GetOrCreateGestureEventHub();
1055 CHECK_NULL_VOID(dividerGestureHub);
1056 dividerGestureHub->SetMouseResponseRegion(mouseRegion);
1057
1058 auto dragRectOffset = layoutAlgorithm->GetSideBarOffset();
1059 dragRectOffset.SetX(-DEFAULT_DRAG_REGION.ConvertToPx());
1060 dragRect_.SetOffset(dragRectOffset);
1061
1062 // divider drag rect height = dividerHeight - divider start margin - divider end margin
1063 dragRect_.SetSize(SizeF(DEFAULT_DRAG_REGION.ConvertToPx() * DEFAULT_DOUBLE_DRAG_REGION + realDividerWidth_,
1064 dividerHeight));
1065
1066 std::vector<DimensionRect> responseRegion;
1067 DimensionOffset responseOffset(dragRectOffset);
1068 DimensionRect responseRect(Dimension(dragRect_.Width(), DimensionUnit::PX),
1069 Dimension(dragRect_.Height(), DimensionUnit::PX), responseOffset);
1070 responseRegion.emplace_back(responseRect);
1071 dividerGestureHub->SetResponseRegion(responseRegion);
1072 }
1073
HandleDragStart()1074 void SideBarContainerPattern::HandleDragStart()
1075 {
1076 if (!isDividerDraggable_ || sideBarStatus_ != SideBarStatus::SHOW) {
1077 return;
1078 }
1079 isInDividerDrag_ = true;
1080 SetMouseStyle(MouseFormat::RESIZE_LEFT_RIGHT);
1081 preSidebarWidth_ = realSideBarWidth_;
1082 }
1083
HandleDragUpdate(float xOffset)1084 void SideBarContainerPattern::HandleDragUpdate(float xOffset)
1085 {
1086 if (sideBarStatus_ != SideBarStatus::SHOW) {
1087 return;
1088 }
1089
1090 auto layoutProperty = GetLayoutProperty<SideBarContainerLayoutProperty>();
1091 CHECK_NULL_VOID(layoutProperty);
1092
1093 auto host = GetHost();
1094 CHECK_NULL_VOID(host);
1095 auto pipeline = host->GetContextRefPtr();
1096 CHECK_NULL_VOID(pipeline);
1097 if (pipeline->GetMinPlatformVersion() < PLATFORM_VERSION_TEN) {
1098 auto geometryNode = host->GetGeometryNode();
1099 CHECK_NULL_VOID(geometryNode);
1100
1101 auto frameSize = geometryNode->GetFrameSize();
1102 auto parentWidth = frameSize.Width();
1103 auto constraint = layoutProperty->GetLayoutConstraint();
1104 auto scaleProperty = constraint->scaleProperty;
1105 minSideBarWidth_ = ConvertToPx(adjustMinSideBarWidth_, scaleProperty, parentWidth).value_or(0);
1106 maxSideBarWidth_ = ConvertToPx(adjustMaxSideBarWidth_, scaleProperty, parentWidth).value_or(0);
1107 }
1108
1109 auto sideBarPosition = GetSideBarPositionWithRtl(layoutProperty);
1110 bool isSideBarStart = sideBarPosition == SideBarPosition::START;
1111
1112 bool isPercent = realSideBarWidth_.Unit() == DimensionUnit::PERCENT;
1113 auto preSidebarWidthPx = DimensionConvertToPx(preSidebarWidth_).value_or(0.0);
1114 auto sideBarLine = preSidebarWidthPx + (isSideBarStart ? xOffset : -xOffset);
1115 auto eventHub = host->GetOrCreateEventHub<SideBarContainerEventHub>();
1116 CHECK_NULL_VOID(eventHub);
1117
1118 if (sideBarLine > minSideBarWidth_ && sideBarLine < maxSideBarWidth_) {
1119 realSideBarWidth_ = isPercent ? ConvertPxToPercent(sideBarLine) : Dimension(sideBarLine, DimensionUnit::PX);
1120 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1121 FireSideBarWidthChangeEvent();
1122 return;
1123 }
1124
1125 if (sideBarLine >= maxSideBarWidth_) {
1126 realSideBarWidth_ =
1127 isPercent ? ConvertPxToPercent(maxSideBarWidth_) : Dimension(maxSideBarWidth_, DimensionUnit::PX);
1128 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1129 FireSideBarWidthChangeEvent();
1130 return;
1131 }
1132
1133 auto halfDragRegionWidth = dragRect_.Width() / 2;
1134 if (sideBarLine > minSideBarWidth_ - halfDragRegionWidth) {
1135 realSideBarWidth_ =
1136 isPercent ? ConvertPxToPercent(minSideBarWidth_) : Dimension(minSideBarWidth_, DimensionUnit::PX);
1137 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1138 FireSideBarWidthChangeEvent();
1139 return;
1140 }
1141 realSideBarWidth_ =
1142 isPercent ? ConvertPxToPercent(minSideBarWidth_) : Dimension(minSideBarWidth_, DimensionUnit::PX);
1143 FireSideBarWidthChangeEvent();
1144
1145 auto autoHideProperty = layoutProperty->GetAutoHide().value_or(true);
1146 if (autoHideProperty) {
1147 DoAnimation();
1148 }
1149 }
1150
HandleDragEnd()1151 void SideBarContainerPattern::HandleDragEnd()
1152 {
1153 isInDividerDrag_ = false;
1154 SetMouseStyle(MouseFormat::DEFAULT);
1155 if (!isDividerDraggable_ || sideBarStatus_ != SideBarStatus::SHOW) {
1156 return;
1157 }
1158 preSidebarWidth_ = realSideBarWidth_;
1159 }
1160
FireSideBarWidthChangeEvent()1161 void SideBarContainerPattern::FireSideBarWidthChangeEvent()
1162 {
1163 auto host = GetHost();
1164 CHECK_NULL_VOID(host);
1165 auto eventHub = host->GetOrCreateEventHub<SideBarContainerEventHub>();
1166 CHECK_NULL_VOID(eventHub);
1167 auto layoutProperty = GetLayoutProperty<SideBarContainerLayoutProperty>();
1168 CHECK_NULL_VOID(layoutProperty);
1169 auto userSetDimensionUnit = layoutProperty->GetSideBarWidthValue(DEFAULT_SIDE_BAR_WIDTH).Unit();
1170 auto realSideBarWidthPx = DimensionConvertToPx(realSideBarWidth_).value_or(0.0);
1171 Dimension usrSetUnitWidth = DimensionUnit::PERCENT == userSetDimensionUnit ?
1172 ConvertPxToPercent(realSideBarWidthPx) :
1173 Dimension(realSideBarWidth_.GetNativeValue(userSetDimensionUnit), userSetDimensionUnit);
1174 UpdateSideBarStatus();
1175 eventHub->FireSideBarWidthChangeEvent(usrSetUnitWidth);
1176 }
1177
InitDividerMouseEvent(const RefPtr<InputEventHub> & inputHub)1178 void SideBarContainerPattern::InitDividerMouseEvent(const RefPtr<InputEventHub>& inputHub)
1179 {
1180 CHECK_NULL_VOID(inputHub);
1181 CHECK_NULL_VOID(!hoverEvent_);
1182
1183 if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
1184 CHECK_NULL_VOID(!dividerMouseEvent_);
1185 auto mouseTask = [weak = WeakClaim(this)](MouseInfo& info) {
1186 auto pattern = weak.Upgrade();
1187 if (pattern) {
1188 pattern->OnDividerMouseEvent(info);
1189 }
1190 };
1191 dividerMouseEvent_ = MakeRefPtr<InputEvent>(std::move(mouseTask));
1192 inputHub->AddOnMouseEvent(dividerMouseEvent_);
1193 }
1194
1195 auto hoverTask = [weak = WeakClaim(this)](bool isHover) {
1196 auto pattern = weak.Upgrade();
1197 if (pattern) {
1198 pattern->OnHover(isHover);
1199 }
1200 };
1201 hoverEvent_ = MakeRefPtr<InputEvent>(std::move(hoverTask));
1202 inputHub->AddOnHoverEvent(hoverEvent_);
1203 }
1204
OnDividerMouseEvent(MouseInfo & info)1205 void SideBarContainerPattern::OnDividerMouseEvent(MouseInfo& info)
1206 {
1207 // release the mouse button, to check if still in the divider's region
1208 if (info.GetAction() != MouseAction::RELEASE) {
1209 return;
1210 }
1211 auto dividerFrameNode = GetDividerNode();
1212 CHECK_NULL_VOID(dividerFrameNode);
1213 auto defaultRect = RectF();
1214 auto responseMouseRegionList = dividerFrameNode->GetResponseRegionList(defaultRect,
1215 static_cast<int32_t>(SourceType::MOUSE));
1216 auto localParentPoint = PointF(static_cast<float>(info.GetLocalLocation().GetX()),
1217 static_cast<float>(info.GetLocalLocation().GetY()));
1218
1219 if (dividerFrameNode->InResponseRegionList(localParentPoint, responseMouseRegionList)) {
1220 return;
1221 }
1222 TAG_LOGI(AceLogTag::ACE_SIDEBAR, "sideBarContainer Divider is out of region.");
1223 SetMouseStyle(MouseFormat::DEFAULT);
1224 }
1225
OnHover(bool isHover)1226 void SideBarContainerPattern::OnHover(bool isHover)
1227 {
1228 if (isInDividerDrag_) {
1229 return;
1230 }
1231 TAG_LOGD(AceLogTag::ACE_SIDEBAR, "sideBarContainer onHover");
1232 auto layoutProperty = GetLayoutProperty<SideBarContainerLayoutProperty>();
1233 CHECK_NULL_VOID(layoutProperty);
1234 auto dividerStrokeWidth = layoutProperty->GetDividerStrokeWidth().value_or(DEFAULT_DIVIDER_STROKE_WIDTH);
1235 auto minSideBarWidth = layoutProperty->GetMinSideBarWidthValue(DEFAULT_MIN_SIDE_BAR_WIDTH);
1236 auto maxSideBarWidth = layoutProperty->GetMaxSideBarWidthValue(DEFAULT_MAX_SIDE_BAR_WIDTH);
1237 if (Negative(dividerStrokeWidth.Value()) || GreatOrEqual(minSideBarWidth.Value(), maxSideBarWidth.Value())) {
1238 isDividerDraggable_ = false;
1239 return;
1240 }
1241 isDividerDraggable_ = true;
1242
1243 MouseFormat format = isHover ? MouseFormat::RESIZE_LEFT_RIGHT : MouseFormat::DEFAULT;
1244 if (sideBarStatus_ == SideBarStatus::SHOW) {
1245 SetMouseStyle(format);
1246 }
1247 }
1248
GetSideBarPositionWithRtl(const RefPtr<SideBarContainerLayoutProperty> & layoutProperty)1249 SideBarPosition SideBarContainerPattern::GetSideBarPositionWithRtl(
1250 const RefPtr<SideBarContainerLayoutProperty>& layoutProperty)
1251 {
1252 auto sideBarPosition = layoutProperty->GetSideBarPosition().value_or(SideBarPosition::START);
1253 if (layoutProperty->GetLayoutDirection() == TextDirection::RTL ||
1254 AceApplicationInfo::GetInstance().IsRightToLeft()) {
1255 sideBarPosition = (sideBarPosition == SideBarPosition::START) ? SideBarPosition::END : SideBarPosition::START;
1256 }
1257 return sideBarPosition;
1258 }
1259
OnLanguageConfigurationUpdate()1260 void SideBarContainerPattern::OnLanguageConfigurationUpdate()
1261 {
1262 auto host = GetHost();
1263 CHECK_NULL_VOID(host);
1264 if (isRightToLeft_ != AceApplicationInfo::GetInstance().IsRightToLeft()) {
1265 host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1266 isRightToLeft_ = AceApplicationInfo::GetInstance().IsRightToLeft();
1267 }
1268 }
1269
CreateNodePaintMethod()1270 RefPtr<NodePaintMethod> SideBarContainerPattern::CreateNodePaintMethod()
1271 {
1272 auto layoutProperty = GetLayoutProperty<SideBarContainerLayoutProperty>();
1273 CHECK_NULL_RETURN(layoutProperty, nullptr);
1274 const auto& paddingProperty = layoutProperty->GetPaddingProperty();
1275 bool needClipPadding = paddingProperty != nullptr;
1276 auto paintMethod = MakeRefPtr<SideBarContainerPaintMethod>();
1277 paintMethod->SetNeedClipPadding(needClipPadding);
1278 return paintMethod;
1279 }
1280
DimensionConvertToPx(const Dimension & value) const1281 std::optional<float> SideBarContainerPattern::DimensionConvertToPx(const Dimension& value) const
1282 {
1283 auto host = GetHost();
1284 CHECK_NULL_RETURN(host, std::nullopt);
1285 auto geometryNode = host->GetGeometryNode();
1286 CHECK_NULL_RETURN(geometryNode, std::nullopt);
1287 auto frameSize = geometryNode->GetFrameSize();
1288 auto parentWidth = frameSize.Width();
1289 auto layoutProperty = GetLayoutProperty<SideBarContainerLayoutProperty>();
1290 CHECK_NULL_RETURN(layoutProperty, std::nullopt);
1291 auto constraint = layoutProperty->GetLayoutConstraint();
1292 auto scaleProperty = constraint->scaleProperty;
1293 return ConvertToPx(value, scaleProperty, parentWidth);
1294 }
1295
ConvertPxToPercent(float value) const1296 Dimension SideBarContainerPattern::ConvertPxToPercent(float value) const
1297 {
1298 auto result = Dimension(0.0, DimensionUnit::PERCENT);
1299 auto host = GetHost();
1300 CHECK_NULL_RETURN(host, result);
1301 auto geometryNode = host->GetGeometryNode();
1302 CHECK_NULL_RETURN(geometryNode, result);
1303
1304 auto frameSize = geometryNode->GetFrameSize();
1305 auto parentWidth = frameSize.Width();
1306 if (!NearZero(parentWidth)) {
1307 result = Dimension(value / parentWidth, DimensionUnit::PERCENT);
1308 }
1309
1310 return result;
1311 }
1312
InitLongPressEvent(const RefPtr<FrameNode> & buttonNode)1313 void SideBarContainerPattern::InitLongPressEvent(const RefPtr<FrameNode>& buttonNode)
1314 {
1315 if (longPressEvent_) {
1316 return;
1317 }
1318
1319 auto buttonHub = buttonNode->GetOrCreateEventHub<EventHub>();
1320 CHECK_NULL_VOID(buttonHub);
1321 auto gestureHub = buttonHub->GetOrCreateGestureEventHub();
1322 CHECK_NULL_VOID(gestureHub);
1323
1324 auto longPressTask = [weak = WeakClaim(this)](GestureEvent& info) {
1325 auto pattern = weak.Upgrade();
1326 if (pattern) {
1327 pattern->HandleLongPressEvent();
1328 }
1329 };
1330 longPressEvent_ = MakeRefPtr<LongPressEvent>(std::move(longPressTask));
1331 gestureHub->SetLongPressEvent(longPressEvent_, false, false);
1332
1333 auto longPressRecognizer = gestureHub->GetLongPressRecognizer();
1334 CHECK_NULL_VOID(longPressRecognizer);
1335 if (!longPressActionEnd_) {
1336 auto longPressActionEnd = [weak = WeakClaim(this)] (GestureEvent& info) {
1337 auto pattern = weak.Upgrade();
1338 CHECK_NULL_VOID(pattern);
1339 pattern->HandleLongPressActionEnd();
1340 };
1341 longPressActionEnd_ = longPressActionEnd;
1342 }
1343 longPressRecognizer->SetOnActionEnd(longPressActionEnd_);
1344 }
1345
HandleLongPressEvent()1346 void SideBarContainerPattern::HandleLongPressEvent()
1347 {
1348 auto host = GetHost();
1349 CHECK_NULL_VOID(host);
1350 auto pipeline = host->GetContextRefPtr();
1351 CHECK_NULL_VOID(pipeline);
1352 float scale = pipeline->GetFontScale();
1353 if (LessNotEqual(scale, AgingAdapationDialogUtil::GetDialogBigFontSizeScale())) {
1354 return;
1355 }
1356 ShowDialogWithNode();
1357 }
1358
HandleLongPressActionEnd()1359 void SideBarContainerPattern::HandleLongPressActionEnd()
1360 {
1361 if (!isDialogShow_) {
1362 return;
1363 }
1364 auto host = GetHost();
1365 CHECK_NULL_VOID(host);
1366 auto pipeline = host->GetContextRefPtr();
1367 CHECK_NULL_VOID(pipeline);
1368 auto overlayManager = pipeline->GetOverlayManager();
1369 CHECK_NULL_VOID(overlayManager);
1370 overlayManager->CloseDialog(dialogNode_);
1371 dialogNode_ = nullptr;
1372 isDialogShow_ = false;
1373 }
1374
ShowDialogWithNode()1375 void SideBarContainerPattern::ShowDialogWithNode()
1376 {
1377 if (isDialogShow_) {
1378 return;
1379 }
1380 auto host = GetHost();
1381 CHECK_NULL_VOID(host);
1382 auto buttonNode = DynamicCast<FrameNode>(host->GetLastChild());
1383 CHECK_NULL_VOID(buttonNode);
1384 auto accessibilityProperty = buttonNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
1385 CHECK_NULL_VOID(accessibilityProperty);
1386 auto text = accessibilityProperty->GetAccessibilityText();
1387
1388 dialogNode_ = AgingAdapationDialogUtil::ShowLongPressDialog(text, imageInfo_, host->GetThemeScopeId());
1389
1390 isDialogShow_ = true;
1391 }
1392
OnWindowSizeChanged(int32_t width,int32_t height,WindowSizeChangeReason type)1393 void SideBarContainerPattern::OnWindowSizeChanged(int32_t width, int32_t height, WindowSizeChangeReason type)
1394 {
1395 TAG_LOGI(AceLogTag::ACE_SIDEBAR, "mark need retrieve sidebar property because of window rotation or resize");
1396 MarkNeedInitRealSideBarWidth(true);
1397 auto host = GetHost();
1398 CHECK_NULL_VOID(host);
1399 auto eventHub = host->GetOrCreateEventHub<SideBarContainerEventHub>();
1400 CHECK_NULL_VOID(eventHub);
1401 FireSideBarWidthChangeEvent();
1402 }
1403
RegisterElementInfoCallBack(const RefPtr<FrameNode> & buttonNode)1404 void SideBarContainerPattern::RegisterElementInfoCallBack(const RefPtr<FrameNode>& buttonNode)
1405 {
1406 #if defined(OHOS_STANDARD_SYSTEM) and !defined(ACE_UNITTEST)
1407 CHECK_NULL_VOID(buttonNode);
1408 auto accessibilityProperty = buttonNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
1409 CHECK_NULL_VOID(accessibilityProperty);
1410 auto callBack = [weak = WeakClaim(this)] (Accessibility::ExtraElementInfo& extraElementInfo) {
1411 auto pattern = weak.Upgrade();
1412 CHECK_NULL_VOID(pattern);
1413 auto showSideBar = pattern->GetShowSideBar();
1414 extraElementInfo.SetExtraElementInfo(
1415 "SideBarContainerStates", static_cast<int32_t>(showSideBar));
1416 };
1417 accessibilityProperty->SetRelatedElementInfoCallback(callBack);
1418 #endif
1419 }
1420
SetAccessibilityEvent()1421 void SideBarContainerPattern::SetAccessibilityEvent()
1422 {
1423 auto controlButton = GetControlButtonNode();
1424 CHECK_NULL_VOID(controlButton);
1425 // use TEXT_CHANGE event to report information update
1426 controlButton->OnAccessibilityEvent(AccessibilityEventType::TEXT_CHANGE, "", "");
1427 }
1428
InitImageErrorCallback(const RefPtr<SideBarTheme> & sideBarTheme,const RefPtr<FrameNode> & imgNode)1429 void SideBarContainerPattern::InitImageErrorCallback(const RefPtr<SideBarTheme>& sideBarTheme,
1430 const RefPtr<FrameNode>& imgNode)
1431 {
1432 auto eventHub = imgNode->GetOrCreateEventHub<ImageEventHub>();
1433 CHECK_NULL_VOID(eventHub);
1434 auto errorCallback = [weakPattern = WeakClaim(this), weakNode = WeakClaim(RawPtr(imgNode)),
1435 weakTheme = WeakClaim(RawPtr(sideBarTheme))] (const LoadImageFailEvent& info) {
1436 auto imgNode = weakNode.Upgrade();
1437 CHECK_NULL_VOID(imgNode);
1438 auto imageLayoutProperty = imgNode->GetLayoutProperty<ImageLayoutProperty>();
1439 CHECK_NULL_VOID(imageLayoutProperty);
1440 auto imageSourceInfo = imageLayoutProperty->GetImageSourceInfo();
1441 if (!imageSourceInfo.has_value()) {
1442 return;
1443 }
1444 auto infoValue = imageSourceInfo.value();
1445 infoValue.SetResourceId(InternalResource::ResourceId::SIDE_BAR);
1446 auto sideBarTheme = weakTheme.Upgrade();
1447 CHECK_NULL_VOID(sideBarTheme);
1448 auto controlButtonColor = sideBarTheme->GetControlImageColor();
1449 infoValue.SetFillColor(controlButtonColor);
1450 imageLayoutProperty->UpdateImageSourceInfo(infoValue);
1451 auto pattern = weakPattern.Upgrade();
1452 CHECK_NULL_VOID(pattern);
1453 pattern->SetImageInfo(infoValue);
1454 imgNode->MarkModifyDone();
1455 };
1456 eventHub->SetOnError(errorCallback);
1457 }
1458
SetMouseStyle(MouseFormat format)1459 void SideBarContainerPattern::SetMouseStyle(MouseFormat format)
1460 {
1461 auto host = GetHost();
1462 CHECK_NULL_VOID(host);
1463 auto pipeline = host->GetContextWithCheck();
1464 CHECK_NULL_VOID(pipeline);
1465 auto frameNodeId = host->GetId();
1466 int32_t windowId = static_cast<int32_t>(pipeline->GetFocusWindowId());
1467 #ifdef WINDOW_SCENE_SUPPORTED
1468 windowId = static_cast<int32_t>(WindowSceneHelper::GetFocusSystemWindowId(host));
1469 #endif
1470 pipeline->SetMouseStyleHoldNode(frameNodeId);
1471 pipeline->ChangeMouseStyle(frameNodeId, format, windowId);
1472 pipeline->FreeMouseStyleHoldNode(frameNodeId);
1473 }
1474
OnThemeScopeUpdate(int32_t themeScopeId)1475 bool SideBarContainerPattern::OnThemeScopeUpdate(int32_t themeScopeId)
1476 {
1477 auto imgFrameNode = GetControlImageNode();
1478 CHECK_NULL_RETURN(imgFrameNode, false);
1479 UpdateControlButtonIcon();
1480 imgFrameNode->MarkDirtyNode();
1481 return false;
1482 }
1483
SetSideBarWidthToolBarManager(bool isShow,float sideBarWidth,float dividerWidth)1484 void SideBarContainerPattern::SetSideBarWidthToolBarManager(bool isShow, float sideBarWidth, float dividerWidth)
1485 {
1486 CHECK_NULL_VOID(toolbarManager_);
1487 auto host = GetHost();
1488 CHECK_NULL_VOID(host);
1489 toolbarManager_->SetSideBarContainerModel(host);
1490 auto sideBarInfo = toolbarManager_->GetSideBarInfo();
1491 if (sideBarInfo.isShow != isShow || !NearEqual(sideBarInfo.width, sideBarWidth)) {
1492 sideBarInfo.isShow = isShow;
1493 sideBarInfo.width = sideBarWidth;
1494 toolbarManager_->SetHasSideBar(true);
1495 toolbarManager_->SetSideBarInfo(sideBarInfo);
1496 toolbarManager_->SetSiderBarNode(GetSideBarNode(host));
1497 }
1498 auto dividerInfo = toolbarManager_->GetSideBarDividerInfo();
1499 if (!NearEqual(dividerInfo.width, dividerWidth)) {
1500 dividerInfo.width = dividerWidth;
1501 toolbarManager_->SetSideBarDividerInfo(dividerInfo);
1502 toolbarManager_->SetSiderBarDividerNode(GetDividerNode());
1503 }
1504 }
1505
SideBarModifyDoneToolBarManager()1506 void SideBarContainerPattern::SideBarModifyDoneToolBarManager()
1507 {
1508 CHECK_NULL_VOID(toolbarManager_);
1509 toolbarManager_->OnToolBarManagerModifyDone();
1510 }
1511
UpdateSideBarColorToToolbarManager()1512 void SideBarContainerPattern::UpdateSideBarColorToToolbarManager()
1513 {
1514 CHECK_NULL_VOID(toolbarManager_);
1515 if (!toolbarManager_->GetIsMoveUp()) {
1516 return;
1517 }
1518 auto host = GetHost();
1519 CHECK_NULL_VOID(host);
1520 auto ctx = host->GetRenderContext();
1521 if (ctx) {
1522 auto bgColor = ctx->GetBackgroundColor().value_or(Color::TRANSPARENT);
1523 toolbarManager_->SetSideBarContainerColor(bgColor);
1524 }
1525 auto children = host->GetChildren();
1526 if (children.size() < DEFAULT_MIN_CHILDREN_SIZE_WITHOUT_BUTTON_AND_DIVIDER) {
1527 return;
1528 }
1529 auto sideBarNode = children.front();
1530 auto sideBarFrameNode = AceType::DynamicCast<FrameNode>(sideBarNode);
1531 CHECK_NULL_VOID(sideBarFrameNode);
1532 ctx = sideBarFrameNode->GetRenderContext();
1533 CHECK_NULL_VOID(ctx);
1534 auto context = host->GetContextRefPtr();
1535 CHECK_NULL_VOID(context);
1536 auto sideBarTheme = context->GetTheme<SideBarTheme>();
1537 CHECK_NULL_VOID(sideBarTheme);
1538 Color bgColor = ctx->GetBackgroundColor().value_or(sideBarTheme->GetSideBarBackgroundColor());
1539 toolbarManager_->SetSideBarColor(bgColor);
1540 auto blurStyleOption = ctx->GetBackBlurStyle();
1541 auto blurStyle = blurStyleOption.has_value() ? blurStyleOption.value().blurStyle : BlurStyle::NO_MATERIAL;
1542 toolbarManager_->SetSideBarBlurStyle(blurStyle);
1543 toolbarManager_->OnChangeSideBarColor();
1544 }
1545 } // namespace OHOS::Ace::NG
1546