• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/components_ng/pattern/container_modal/container_modal_view.h"
17 
18 #include "base/geometry/ng/offset_t.h"
19 #include "base/image/pixel_map.h"
20 #include "base/subwindow/subwindow_manager.h"
21 #include "core/components/common/layout/constants.h"
22 #include "core/components/common/properties/color.h"
23 #include "core/components_ng/gestures/pan_gesture.h"
24 #include "core/components_ng/gestures/tap_gesture.h"
25 #include "core/components_ng/pattern/button/button_layout_property.h"
26 #include "core/components_ng/pattern/button/button_pattern.h"
27 #include "core/components_ng/pattern/container_modal/container_modal_theme.h"
28 #include "core/components_ng/pattern/container_modal/container_modal_utils.h"
29 #include "core/components_ng/pattern/image/image_pattern.h"
30 #include "core/components_ng/pattern/image/image_render_property.h"
31 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
32 #include "core/components_ng/pattern/stack/stack_pattern.h"
33 #include "core/components_ng/pattern/text/text_layout_property.h"
34 #include "core/components_ng/pattern/text/text_pattern.h"
35 #include "core/components_ng/pattern/toolbaritem/toolbar_row_pattern.h"
36 
37 namespace OHOS::Ace::NG {
38 namespace {
39 constexpr char SPLIT_LEFT_KEY[] = "container_modal_split_left_button";
40 constexpr char MAXIMIZE_KEY[] = "container_modal_maximize_button";
41 constexpr char MINIMIZE_KEY[] = "container_modal_minimize_button";
42 constexpr char CLOSE_KEY[] = "container_modal_close_button";
43 constexpr float SPRINGMOTION_RESPONSE = 0.55f;
44 constexpr float CURRENT_RATIO = 0.86f;
45 constexpr float CURRENT_DURATION = 0.25f;
46 } // namespace
47 float ContainerModalView::baseScale = 1.0f;
48 std::function<RefPtr<NG::FrameNode>()> ContainerModalView::customTitileBuilder_ = nullptr;
49 std::function<RefPtr<NG::FrameNode>(
50     const WeakPtr<NG::ContainerModalPatternEnhance>& weakPattern, const RefPtr<NG::FrameNode>& containerTitleRow)>
51     ContainerModalView::customControlButtonBuilder_ = nullptr;
52 
53 /**
54  * The structure of container_modal is designed as follows :
55  * |--container_modal(stack)
56  *   |--column
57  *      |--container_modal_custom_title(row)
58  *          |--custom_node(js)
59  *      |--stack
60  *          |--container_modal_content(stage)
61  *              |--page
62  *          |--dialog(when show)
63  *   |--container_modal_custom_floating_title(row)
64  *          |--custom_node(js)
65  *   |--container_modal_control_buttons(row)
66  *          |--[leftSplit, maxRecover, minimize, close](button)
67  */
68 
Create(RefPtr<FrameNode> & content)69 RefPtr<FrameNode> ContainerModalView::Create(RefPtr<FrameNode>& content)
70 {
71     auto nodeId = ElementRegister::GetInstance()->MakeUniqueId();
72     ACE_LAYOUT_SCOPED_TRACE("Create[ContainerModal][self:%d]", nodeId);
73     auto containerModalNode = FrameNode::CreateFrameNode("ContainerModal", nodeId, MakeRefPtr<ContainerModalPattern>());
74     auto stack = FrameNode::CreateFrameNode(
75         V2::STACK_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr<StackPattern>());
76     auto column = FrameNode::CreateFrameNode(
77         V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr<LinearLayoutPattern>(true));
78     auto controlButtonsRow = FrameNode::CreateFrameNode(
79         V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr<LinearLayoutPattern>(false));
80 
81     column->AddChild(BuildTitle(containerModalNode));
82     stack->AddChild(content);
83     column->AddChild(stack);
84     auto containerPattern = containerModalNode->GetPattern<ContainerModalPattern>();
85     CHECK_NULL_RETURN(containerPattern, nullptr);
86     containerModalNode->AddChild(column);
87     containerModalNode->AddChild(BuildTitle(containerModalNode, true));
88     containerModalNode->AddChild(AddControlButtons(controlButtonsRow));
89 
90     containerPattern->Init();
91 
92     return containerModalNode;
93 }
94 
BuildTitle(RefPtr<FrameNode> & containerNode,bool isFloatingTitle)95 RefPtr<FrameNode> ContainerModalView::BuildTitle(RefPtr<FrameNode>& containerNode, bool isFloatingTitle)
96 {
97     TAG_LOGI(AceLogTag::ACE_APPBAR, "ContainerModalView BuildTitle called");
98     auto customTitleContainer = BuildTitleContainer(containerNode, isFloatingTitle);
99     CHECK_NULL_RETURN(customTitleContainer, nullptr);
100     return customTitleContainer;
101 }
102 
BuildTitleContainer(RefPtr<FrameNode> & containerNode,bool isFloatingTitle)103 RefPtr<FrameNode> ContainerModalView::BuildTitleContainer(RefPtr<FrameNode>& containerNode, bool isFloatingTitle)
104 {
105     auto containerTitleRow = BuildTitleRow(isFloatingTitle);
106     CHECK_NULL_RETURN(containerTitleRow, nullptr);
107 
108     RefPtr<UINode> customTitleBarNode;
109     if (customTitileBuilder_) {
110         customTitleBarNode = customTitileBuilder_();
111     } else {
112         auto isSucc = ExecuteCustomTitleAbc();
113         if (!isSucc) {
114             return nullptr;
115         }
116         customTitleBarNode = NG::ViewStackProcessor::GetInstance()->GetCustomTitleNode();
117     }
118 
119     CHECK_NULL_RETURN(customTitleBarNode, nullptr);
120     auto customTitleBarRow = FrameNode::CreateFrameNode(
121         V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr<LinearLayoutPattern>(false));
122     customTitleBarRow->AddChild(customTitleBarNode);
123     containerTitleRow->AddChild(customTitleBarRow);
124     return containerTitleRow;
125 }
126 
RegistCustomBuilder(std::function<RefPtr<NG::FrameNode> ()> & title,std::function<RefPtr<NG::FrameNode> (const WeakPtr<NG::ContainerModalPatternEnhance> & weakPattern,const RefPtr<NG::FrameNode> & containerTitleRow)> & button)127 void ContainerModalView::RegistCustomBuilder(std::function<RefPtr<NG::FrameNode>()>& title,
128     std::function<RefPtr<NG::FrameNode>(const WeakPtr<NG::ContainerModalPatternEnhance>& weakPattern,
129         const RefPtr<NG::FrameNode>& containerTitleRow)>& button)
130 {
131     customTitileBuilder_ = title;
132     customControlButtonBuilder_ = button;
133 }
134 
BuildTitleRow(bool isFloatingTitle)135 RefPtr<FrameNode> ContainerModalView::BuildTitleRow(bool isFloatingTitle)
136 {
137     auto containerTitleRow = FrameNode::CreateFrameNode(
138         V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr<ToolBarRowPattern>());
139     containerTitleRow->UpdateInspectorId("ContainerModalTitleRow");
140     if (isFloatingTitle) {
141         auto renderContext = containerTitleRow->GetRenderContext();
142         CHECK_NULL_RETURN(renderContext, nullptr);
143         auto pipeline = PipelineContext::GetCurrentContext();
144         CHECK_NULL_RETURN(pipeline, nullptr);
145         auto theme = pipeline->GetTheme<ContainerModalTheme>();
146         renderContext->UpdateBackgroundColor(theme->GetBackGroundColor(true));
147     }
148     return containerTitleRow;
149 }
150 
AddControlButtons(RefPtr<FrameNode> & controlButtonsRow)151 RefPtr<FrameNode> ContainerModalView::AddControlButtons(RefPtr<FrameNode>& controlButtonsRow)
152 {
153     auto pipeline = PipelineContext::GetCurrentContext();
154     CHECK_NULL_RETURN(pipeline, nullptr);
155     auto windowManager = pipeline->GetWindowManager();
156     CHECK_NULL_RETURN(windowManager, nullptr);
157 
158     // add leftSplit / maxRecover / minimize / close button
159     controlButtonsRow->AddChild(BuildControlButton(InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_SPLIT_LEFT,
160         [wk = WeakClaim(RawPtr(windowManager))](GestureEvent& info) {
161             auto windowManager = wk.Upgrade();
162             CHECK_NULL_VOID(windowManager);
163             TAG_LOGI(AceLogTag::ACE_APPBAR, "left split button clicked");
164             windowManager->FireWindowSplitCallBack();
165         }));
166     controlButtonsRow->AddChild(BuildControlButton(InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_MAXIMIZE,
167         [wk = WeakClaim(RawPtr(windowManager))](GestureEvent& info) {
168             auto windowManager = wk.Upgrade();
169             CHECK_NULL_VOID(windowManager);
170             auto mode = windowManager->GetWindowMode();
171             if (mode == WindowMode::WINDOW_MODE_FULLSCREEN) {
172                 TAG_LOGI(AceLogTag::ACE_APPBAR, "recover button clicked");
173                 windowManager->WindowRecover();
174             } else {
175                 TAG_LOGI(AceLogTag::ACE_APPBAR, "maximize button clicked");
176                 windowManager->WindowMaximize();
177             }
178         }));
179     controlButtonsRow->AddChild(BuildControlButton(InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_MINIMIZE,
180         [wk = WeakClaim(RawPtr(windowManager))](GestureEvent& info) {
181             auto windowManager = wk.Upgrade();
182             CHECK_NULL_VOID(windowManager);
183             TAG_LOGI(AceLogTag::ACE_APPBAR, "minimize button clicked");
184             windowManager->WindowMinimize();
185         }));
186     controlButtonsRow->AddChild(BuildControlButton(
187         InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_CLOSE,
188         [wk = WeakClaim(RawPtr(windowManager))](GestureEvent& info) {
189             auto windowManager = wk.Upgrade();
190             CHECK_NULL_VOID(windowManager);
191             TAG_LOGI(AceLogTag::ACE_APPBAR, "close button clicked");
192             windowManager->WindowClose();
193         },
194         true));
195 
196     return controlButtonsRow;
197 }
198 
BuildControlButton(InternalResource::ResourceId icon,GestureEventFunc && clickCallback,bool isCloseButton,bool canDrag)199 RefPtr<FrameNode> ContainerModalView::BuildControlButton(
200     InternalResource::ResourceId icon, GestureEventFunc&& clickCallback, bool isCloseButton, bool canDrag)
201 {
202     static std::unordered_map<InternalResource::ResourceId, std::string> controlButtonKeyMap = {
203         { InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_SPLIT_LEFT, SPLIT_LEFT_KEY },
204         { InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_DEFOCUS_SPLIT_LEFT, SPLIT_LEFT_KEY },
205         { InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_RECOVER, MAXIMIZE_KEY },
206         { InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_MAXIMIZE, MAXIMIZE_KEY },
207         { InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_DEFOCUS_RECOVER, MAXIMIZE_KEY },
208         { InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_DEFOCUS_MAXIMIZE, MAXIMIZE_KEY },
209         { InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_MINIMIZE, MINIMIZE_KEY },
210         { InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_DEFOCUS_MINIMIZE, MINIMIZE_KEY },
211         { InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_CLOSE, CLOSE_KEY },
212         { InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_DEFOCUS_CLOSE, CLOSE_KEY },
213     };
214     auto theme = PipelineContext::GetCurrentContext()->GetTheme<ContainerModalTheme>();
215     CHECK_NULL_RETURN(theme, nullptr);
216     // button image icon
217     ImageSourceInfo imageSourceInfo;
218     auto imageIcon = FrameNode::CreateFrameNode(
219         V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr<ImagePattern>());
220     auto imageEventHub = imageIcon->GetOrCreateGestureEventHub();
221     CHECK_NULL_RETURN(imageEventHub, nullptr);
222     imageEventHub->RemoveDragEvent();
223     imageIcon->SetDraggable(false);
224     auto imageFocus = imageIcon->GetFocusHub();
225     if (imageFocus) {
226         imageFocus->SetFocusable(false);
227     }
228     imageSourceInfo.SetResourceId(icon);
229     imageSourceInfo.SetFillColor(theme->GetControlBtnColor(isCloseButton, ControlBtnColorType::NORMAL_FILL));
230     auto imageLayoutProperty = imageIcon->GetLayoutProperty<ImageLayoutProperty>();
231     CHECK_NULL_RETURN(imageLayoutProperty, nullptr);
232     imageLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(TITLE_ICON_SIZE), CalcLength(TITLE_ICON_SIZE)));
233     imageLayoutProperty->UpdateImageSourceInfo(imageSourceInfo);
234     auto imageRenderProperty = imageIcon->GetPaintProperty<ImageRenderProperty>();
235     CHECK_NULL_RETURN(imageRenderProperty, nullptr);
236     imageRenderProperty->UpdateImageInterpolation(ImageInterpolation::HIGH);
237     imageIcon->MarkModifyDone();
238 
239     auto buttonNode = FrameNode::CreateFrameNode(
240         V2::BUTTON_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr<ButtonPattern>());
241     auto buttonFocus = buttonNode->GetFocusHub();
242     if (buttonFocus) {
243         buttonFocus->SetFocusable(false);
244     }
245     std::string buttonKey = "";
246     auto iter = controlButtonKeyMap.find(icon);
247     if (iter != controlButtonKeyMap.end()) {
248         buttonKey = iter->second;
249     }
250     buttonNode->UpdateInspectorId(buttonKey);
251 
252     AddButtonHover(buttonNode, imageIcon);
253     AddButtonMouse(buttonNode, imageIcon);
254     AddButtonStyleMouseEvent(buttonNode, imageIcon, isCloseButton);
255 
256     auto renderContext = buttonNode->GetRenderContext();
257     CHECK_NULL_RETURN(renderContext, nullptr);
258     renderContext->UpdateBackgroundColor(theme->GetControlBtnColor(isCloseButton, ControlBtnColorType::NORMAL));
259 
260     auto buttonEventHub = buttonNode->GetOrCreateGestureEventHub();
261     CHECK_NULL_RETURN(buttonEventHub, nullptr);
262     auto clickGesture = MakeRefPtr<TapGesture>();
263     clickGesture->SetOnActionId(clickCallback);
264     buttonEventHub->AddGesture(clickGesture);
265     buttonNode->SetDraggable(canDrag);
266 
267     DimensionOffset offsetDimen(TITLE_BUTTON_RESPONSE_REGIOIN_OFFSET_X, TITLE_BUTTON_RESPONSE_REGIOIN_OFFSET_Y);
268     DimensionRect dimenRect(TITLE_BUTTON_RESPONSE_REGIOIN_WIDTH, TITLE_BUTTON_RESPONSE_REGIOIN_HEIGHT, offsetDimen);
269     std::vector<DimensionRect> result;
270     result.emplace_back(dimenRect);
271     auto gestureHub = buttonNode->GetOrCreateGestureEventHub();
272     CHECK_NULL_RETURN(gestureHub, nullptr);
273     gestureHub->SetResponseRegion(result);
274 
275     auto buttonLayoutProperty = buttonNode->GetLayoutProperty<ButtonLayoutProperty>();
276     CHECK_NULL_RETURN(buttonLayoutProperty, nullptr);
277     buttonLayoutProperty->UpdateType(ButtonType::CIRCLE);
278     buttonLayoutProperty->UpdateUserDefinedIdealSize(
279         CalcSize(CalcLength(TITLE_BUTTON_SIZE), CalcLength(TITLE_BUTTON_SIZE)));
280 
281     MarginProperty margin;
282     margin.right = CalcLength(isCloseButton ? TITLE_PADDING_END : TITLE_ELEMENT_MARGIN_HORIZONTAL);
283     buttonLayoutProperty->UpdateMargin(margin);
284     buttonNode->MarkModifyDone();
285 
286     buttonNode->AddChild(imageIcon);
287     return buttonNode;
288 }
289 
AddButtonHover(RefPtr<FrameNode> & buttonNode,RefPtr<FrameNode> & imageNode)290 void ContainerModalView::AddButtonHover(RefPtr<FrameNode>& buttonNode, RefPtr<FrameNode>& imageNode)
291 {
292     auto inputHub = buttonNode->GetOrCreateInputEventHub();
293     CHECK_NULL_VOID(inputHub);
294     auto hoverTask = [buttonWk = WeakClaim(RawPtr(buttonNode)), imageWk = WeakClaim(RawPtr(imageNode))](bool isHover) {
295         auto buttonNode = buttonWk.Upgrade();
296         auto imageNode = imageWk.Upgrade();
297         CHECK_NULL_VOID(buttonNode && imageNode);
298         auto buttonPattern = DynamicCast<ButtonPattern>(buttonNode->GetPattern());
299         CHECK_NULL_VOID(buttonPattern);
300         buttonPattern->SetInHover(isHover);
301         float halfSize = TITLE_ICON_SIZE.Value() / 2.0f;
302         auto icurve = MakeRefPtr<CubicCurve>(0.2f, 0.0f, 0.2f, 1.0f);
303         float maxDis = sqrt(pow(halfSize, 2.0) + pow(halfSize, 2.0));
304         float curDis = sqrt(pow(buttonPattern->GetLocalLocation().GetX() - halfSize, 2.0) +
305                             pow(buttonPattern->GetLocalLocation().GetY() - halfSize, 2.0));
306         float currentScale = 1 + 0.1 * icurve->Move((maxDis - curDis) / (maxDis));
307         baseScale = currentScale > baseScale ? currentScale : baseScale;
308         auto buttonNodeRenderContext = buttonNode->GetRenderContext();
309         auto imageIconRenderContext = imageNode->GetRenderContext();
310         CHECK_NULL_VOID(buttonNodeRenderContext);
311         CHECK_NULL_VOID(imageIconRenderContext);
312         float imageScale = isHover ? baseScale : 1.0f;
313         float btnScale = 1.0f;
314         AnimationOption option = AnimationOption();
315         auto motion = MakeRefPtr<ResponsiveSpringMotion>(SPRINGMOTION_RESPONSE, CURRENT_RATIO, CURRENT_DURATION);
316         option.SetCurve(motion);
317         if (isHover) {
318             AnimationUtils::Animate(option, [buttonNodeRenderContext, imageIconRenderContext, imageScale, btnScale]() {
319                 buttonNodeRenderContext->UpdateTransformScale(VectorF(btnScale, btnScale));
320                 imageIconRenderContext->UpdateTransformScale(VectorF(1 / imageScale, 1 / imageScale));
321             });
322         } else {
323             baseScale = 1.0f;
324             AnimationUtils::Animate(option, [buttonNodeRenderContext, imageIconRenderContext, imageScale, btnScale]() {
325                 buttonNodeRenderContext->UpdateTransformScale(VectorF(btnScale, btnScale));
326                 imageIconRenderContext->UpdateTransformScale(VectorF(imageScale, imageScale));
327             });
328         }
329     };
330     auto hoverEvent = MakeRefPtr<InputEvent>(std::move(hoverTask));
331     inputHub->AddOnHoverEvent(hoverEvent);
332 }
333 
AddButtonMouse(RefPtr<FrameNode> & buttonNode,RefPtr<FrameNode> & imageNode)334 void ContainerModalView::AddButtonMouse(RefPtr<FrameNode>& buttonNode, RefPtr<FrameNode>& imageNode)
335 {
336     auto inputHub = buttonNode->GetOrCreateInputEventHub();
337     CHECK_NULL_VOID(inputHub);
338     auto mouseTask = [buttonWk = WeakClaim(RawPtr(buttonNode)), imageWk = WeakClaim(RawPtr(imageNode))](
339                          MouseInfo& info) {
340         auto buttonNode = buttonWk.Upgrade();
341         auto imageNode = imageWk.Upgrade();
342         CHECK_NULL_VOID(buttonNode && imageNode);
343         auto buttonPattern = DynamicCast<ButtonPattern>(buttonNode->GetPattern());
344         CHECK_NULL_VOID(buttonPattern);
345         if (info.GetAction() != MouseAction::MOVE || !buttonPattern->GetIsInHover()) {
346             buttonPattern->SetLocalLocation(info.GetLocalLocation());
347             return;
348         }
349         auto buttonNodeRenderContext = buttonNode->GetRenderContext();
350         auto imageIconRenderContext = imageNode->GetRenderContext();
351         CHECK_NULL_VOID(imageIconRenderContext);
352         float halfSize = TITLE_ICON_SIZE.Value() / 2.0f;
353         auto icurve = MakeRefPtr<CubicCurve>(0.2f, 0.0f, 0.2f, 1.0f);
354         float maxDis = sqrt(pow(halfSize, 2.0) + pow(halfSize, 2.0));
355         float curDis = sqrt(
356             pow(info.GetLocalLocation().GetX() - halfSize, 2.0) + pow(info.GetLocalLocation().GetY() - halfSize, 2.0));
357         float currentScale = 1 + 0.1 * icurve->Move((maxDis - curDis) / (maxDis));
358         baseScale = currentScale > baseScale ? currentScale : baseScale;
359         float imageScale = baseScale;
360         float btnScale = 1.0f;
361         float response = ResponsiveSpringMotion::DEFAULT_RESPONSIVE_SPRING_MOTION_RESPONSE;
362         float dampingRatio = ResponsiveSpringMotion::DEFAULT_RESPONSIVE_SPRING_MOTION_DAMPING_RATIO;
363         float blendDuration = ResponsiveSpringMotion::DEFAULT_RESPONSIVE_SPRING_MOTION_BLEND_DURATION;
364         auto motion = MakeRefPtr<ResponsiveSpringMotion>(response, dampingRatio, blendDuration);
365         AnimationOption option = AnimationOption();
366         option.SetCurve(motion);
367         AnimationUtils::Animate(option, [buttonNodeRenderContext, imageIconRenderContext, imageScale, btnScale]() {
368             buttonNodeRenderContext->UpdateTransformScale(VectorF(btnScale, btnScale));
369             imageIconRenderContext->UpdateTransformScale(VectorF(imageScale, imageScale));
370         });
371     };
372     auto mouseEvent = MakeRefPtr<InputEvent>(std::move(mouseTask));
373     inputHub->AddOnMouseEvent(mouseEvent);
374 }
375 
AddButtonStyleMouseEvent(RefPtr<FrameNode> & buttonNode,RefPtr<FrameNode> & imageNode,bool isCloseBtn)376 void ContainerModalView::AddButtonStyleMouseEvent(
377     RefPtr<FrameNode>& buttonNode, RefPtr<FrameNode>& imageNode, bool isCloseBtn)
378 {
379     auto inputHub = buttonNode->GetOrCreateInputEventHub();
380     CHECK_NULL_VOID(inputHub);
381     AddButtonHoverEvent(inputHub, buttonNode, imageNode, isCloseBtn);
382     AddButtonOnEvent(inputHub, buttonNode, imageNode, isCloseBtn);
383 }
384 
AddButtonHoverEvent(RefPtr<InputEventHub> & inputHub,RefPtr<FrameNode> & buttonNode,RefPtr<FrameNode> & imageNode,bool isCloseBtn)385 void ContainerModalView::AddButtonHoverEvent(
386     RefPtr<InputEventHub>& inputHub, RefPtr<FrameNode>& buttonNode, RefPtr<FrameNode>& imageNode, bool isCloseBtn)
387 {
388     auto task = [buttonWk = WeakClaim(RawPtr(buttonNode)), imageWk = WeakClaim(RawPtr(imageNode)), isCloseBtn](
389                     bool isHover) {
390         auto buttonNode = buttonWk.Upgrade();
391         CHECK_NULL_VOID(buttonNode);
392         auto imageNode = imageWk.Upgrade();
393         CHECK_NULL_VOID(imageNode);
394         auto pipeline = buttonNode->GetContextRefPtr();
395         CHECK_NULL_VOID(pipeline);
396         auto containerNode = AceType::DynamicCast<FrameNode>(pipeline->GetRootElement()->GetChildAtIndex(0));
397         auto containerModalPattern = containerNode->GetPattern<ContainerModalPattern>();
398         CHECK_NULL_VOID(containerModalPattern);
399         bool isFocus = containerModalPattern->GetIsFocus() || containerModalPattern->GetIsHoveredMenu();
400 
401         auto theme = PipelineContext::GetCurrentContext()->GetTheme<ContainerModalTheme>();
402         auto imageLayoutProperty = imageNode->GetLayoutProperty<ImageLayoutProperty>();
403         auto sourceInfo = imageLayoutProperty->GetImageSourceInfo();
404         ControlBtnColorType isHoverFillType = ControlBtnColorType::HOVER_FILL;
405         ControlBtnColorType isHoverType = ControlBtnColorType::HOVER;
406         if (!isHover) {
407             isHoverFillType = isFocus ? ControlBtnColorType::NORMAL_FILL : ControlBtnColorType::UNFOCUS_FILL;
408             isHoverType = isFocus ? ControlBtnColorType::NORMAL : ControlBtnColorType::UNFOCUS;
409         }
410         sourceInfo->SetFillColor(theme->GetControlBtnColor(isCloseBtn, isHoverFillType));
411         if (isCloseBtn) {
412             auto renderContext = buttonNode->GetRenderContext();
413             renderContext->UpdateBackgroundColor(theme->GetControlBtnColor(isCloseBtn, isHoverType));
414         }
415         if (sourceInfo.has_value()) {
416             imageLayoutProperty->UpdateImageSourceInfo(sourceInfo.value());
417         }
418         buttonNode->MarkModifyDone();
419         imageNode->MarkModifyDone();
420     };
421     auto hoverCallBack = MakeRefPtr<InputEvent>(std::move(task));
422     inputHub->AddOnHoverEvent(hoverCallBack);
423 }
424 
AddButtonOnEvent(RefPtr<InputEventHub> & inputHub,RefPtr<FrameNode> & buttonNode,RefPtr<FrameNode> & imageNode,bool isCloseBtn)425 void ContainerModalView::AddButtonOnEvent(
426     RefPtr<InputEventHub>& inputHub, RefPtr<FrameNode>& buttonNode, RefPtr<FrameNode>& imageNode, bool isCloseBtn)
427 {
428     auto wkTask = [buttonWk = WeakClaim(RawPtr(buttonNode)), imageWk = WeakClaim(RawPtr(imageNode)), isCloseBtn](
429                       MouseInfo& info) {
430         auto buttonNode = buttonWk.Upgrade();
431         CHECK_NULL_VOID(buttonNode);
432         auto imageNode = imageWk.Upgrade();
433         CHECK_NULL_VOID(imageNode);
434         auto theme = PipelineContext::GetCurrentContext()->GetTheme<ContainerModalTheme>();
435         if (info.GetAction() == MouseAction::PRESS || info.GetAction() == MouseAction::RELEASE) {
436             auto imageLayoutProperty = imageNode->GetLayoutProperty<ImageLayoutProperty>();
437             CHECK_NULL_VOID(imageLayoutProperty);
438             auto sourceInfo = imageLayoutProperty->GetImageSourceInfo();
439             CHECK_NULL_VOID(sourceInfo);
440             auto isHoverFillType = info.GetAction() == MouseAction::PRESS ? ControlBtnColorType::PRESS_FILL
441                                                                           : ControlBtnColorType::NORMAL_FILL;
442             sourceInfo->SetFillColor(theme->GetControlBtnColor(isCloseBtn, isHoverFillType));
443             auto renderContext = buttonNode->GetRenderContext();
444             auto isHoverType =
445                 info.GetAction() == MouseAction::PRESS ? ControlBtnColorType::PRESS : ControlBtnColorType::NORMAL;
446             renderContext->UpdateBackgroundColor(theme->GetControlBtnColor(isCloseBtn, isHoverType));
447             buttonNode->MarkModifyDone();
448             imageNode->MarkModifyDone();
449         }
450     };
451     auto onclickCallback = MakeRefPtr<InputEvent>(std::move(wkTask));
452     inputHub->AddOnMouseEvent(onclickCallback);
453 }
454 
ConfigCustomWindowMask(RefPtr<PipelineContext> & pipeline,bool enable)455 bool ContainerModalView::ConfigCustomWindowMask(RefPtr<PipelineContext>& pipeline, bool enable)
456 {
457     CHECK_NULL_RETURN(pipeline, false);
458     auto rootNode = pipeline->GetRootElement();
459     CHECK_NULL_RETURN(rootNode, false);
460     if (!enable) {
461         auto customWindowMaskNode = NG::ViewStackProcessor::GetInstance()->GetCustomWindowMaskNode();
462         CHECK_NULL_RETURN(customWindowMaskNode, false);
463         rootNode->RemoveChild(customWindowMaskNode);
464         rootNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE_SELF);
465         return true;
466     }
467     auto isSucc = ExecuteCustomWindowMaskAbc();
468     if (!isSucc) {
469         return false;
470     }
471     auto customWindowMaskNode = NG::ViewStackProcessor::GetInstance()->GetCustomWindowMaskNode();
472     CHECK_NULL_RETURN(customWindowMaskNode, false);
473     customWindowMaskNode->MountToParent(rootNode);
474     rootNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE_SELF);
475     return true;
476 }
477 } // namespace OHOS::Ace::NG