• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "bridge/cj_frontend/frontend/container_modal_cj_utils.h"
17 
18 #include "base/geometry/ng/offset_t.h"
19 #include "base/image/pixel_map.h"
20 #include "base/memory/referenced.h"
21 #include "base/subwindow/subwindow_manager.h"
22 #include "core/components/common/layout/constants.h"
23 #include "core/components/common/properties/color.h"
24 #include "core/components/theme/advanced_pattern_theme.h"
25 #include "core/components_ng/gestures/pan_gesture.h"
26 #include "core/components_ng/gestures/tap_gesture.h"
27 #include "core/components_ng/pattern/button/button_layout_property.h"
28 #include "core/components_ng/pattern/button/button_pattern.h"
29 #include "core/components_ng/pattern/container_modal/container_modal_theme.h"
30 #include "core/components_ng/pattern/container_modal/container_modal_utils.h"
31 #include "core/components_ng/pattern/image/image_pattern.h"
32 #include "core/components_ng/pattern/image/image_render_property.h"
33 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
34 #include "core/components_ng/pattern/stack/stack_pattern.h"
35 #include "core/components_ng/pattern/text/text_layout_property.h"
36 #include "core/components_ng/pattern/text/text_pattern.h"
37 #include "core/components_v2/inspector/inspector_constants.h"
38 
39 namespace OHOS::Ace::NG {
40 namespace {
41 constexpr char SPLIT_LEFT_KEY[] = "container_modal_split_left_button";
42 constexpr char MAXIMIZE_KEY[] = "container_modal_maximize_button";
43 constexpr char MINIMIZE_KEY[] = "container_modal_minimize_button";
44 constexpr char CLOSE_KEY[] = "container_modal_close_button";
45 constexpr float SPRINGMOTION_RESPONSE = 0.55f;
46 constexpr float CURRENT_RATIO = 0.86f;
47 constexpr float CURRENT_DURATION = 0.25f;
48 float g_baseScale = 1.0f;
49 
BuildCjTextNode(const std::string label)50 RefPtr<FrameNode> BuildCjTextNode(const std::string label)
51 {
52     auto textNode = FrameNode::CreateFrameNode(
53         V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
54     CHECK_NULL_RETURN(textNode, nullptr);
55     auto textProps = textNode->GetLayoutProperty<TextLayoutProperty>();
56     CHECK_NULL_RETURN(textNode, nullptr);
57 
58     // Modifying the onFocuse event is currently not supported
59     textNode->GetOrCreateFocusHub()->SetFocusable(true);
60 
61     // The magic number in the following style refer to the native arkts application titile_node style
62     Dimension DEFAULT_TEXT_FONTSIZE = 16.0_fp;
63     textProps->UpdateFontSize(DEFAULT_TEXT_FONTSIZE);
64     textProps->UpdateFontWeight(Ace::FontWeight::W500);
65     textProps->UpdateMaxLines(1);
66     textProps->UpdateTextOverflow(TextOverflow::ELLIPSIS);
67     textProps->UpdateTextAlign(TextAlign::START);
68     textProps->UpdateContent(label);
69     return textNode;
70 }
71 
72 #ifdef PIXEL_MAP_SUPPORTED
BuildCjImageNode(std::shared_ptr<Media::PixelMap> pixelMap)73 RefPtr<FrameNode> BuildCjImageNode(std::shared_ptr<Media::PixelMap> pixelMap)
74 {
75     auto imageNode = FrameNode::CreateFrameNode(
76         V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
77     auto imageLayoutProperty = imageNode->GetLayoutProperty<ImageLayoutProperty>();
78     CHECK_NULL_RETURN(imageLayoutProperty, nullptr);
79     RefPtr<PixelMap> icon = PixelMap::CreatePixelMap(&pixelMap);
80     CHECK_NULL_RETURN(icon, nullptr);
81     ImageSourceInfo info(icon);
82     imageLayoutProperty->UpdateImageSourceInfo(info);
83 
84     // The magic number in the following style refer to the native arkts application titile_node style
85     Dimension size = 20.0_vp;
86     Dimension marginSize = 12.0_vp;
87     auto targetSize = CalcSize(NG::CalcLength(size), NG::CalcLength(size));
88     MarginProperty imageMargin;
89     imageMargin.left = CalcLength(marginSize);
90     imageMargin.left = CalcLength(marginSize);
91     imageLayoutProperty->UpdateMargin(imageMargin);
92     imageLayoutProperty->UpdateUserDefinedIdealSize(targetSize);
93     auto imageRenderProperty = imageNode->GetPaintProperty<ImageRenderProperty>();
94     imageRenderProperty->UpdateImageInterpolation(ImageInterpolation::MEDIUM);
95     return imageNode;
96 }
97 #endif
98 
AddButtonOnEvent(RefPtr<InputEventHub> & inputHub,RefPtr<FrameNode> & buttonNode,RefPtr<FrameNode> & imageNode,bool isCloseBtn)99 void AddButtonOnEvent(
100     RefPtr<InputEventHub>& inputHub, RefPtr<FrameNode>& buttonNode, RefPtr<FrameNode>& imageNode, bool isCloseBtn)
101 {
102     auto wkTask = [buttonWk = AceType::WeakClaim(AceType::RawPtr(buttonNode)),
103                       imageWk = AceType::WeakClaim(AceType::RawPtr(imageNode)), isCloseBtn](MouseInfo& info) {
104         auto buttonNode = buttonWk.Upgrade();
105         CHECK_NULL_VOID(buttonNode);
106         auto imageNode = imageWk.Upgrade();
107         CHECK_NULL_VOID(imageNode);
108         auto theme = PipelineContext::GetCurrentContext()->GetTheme<ContainerModalTheme>();
109         if (info.GetAction() == MouseAction::PRESS || info.GetAction() == MouseAction::RELEASE) {
110             auto imageLayoutProperty = imageNode->GetLayoutProperty<ImageLayoutProperty>();
111             CHECK_NULL_VOID(imageLayoutProperty);
112             auto sourceInfo = imageLayoutProperty->GetImageSourceInfo();
113             CHECK_NULL_VOID(sourceInfo);
114             auto isHoverFillType = info.GetAction() == MouseAction::PRESS ? ControlBtnColorType::PRESS_FILL
115                                                                           : ControlBtnColorType::NORMAL_FILL;
116             sourceInfo->SetFillColor(theme->GetControlBtnColor(isCloseBtn, isHoverFillType));
117             auto renderContext = buttonNode->GetRenderContext();
118             auto isHoverType =
119                 info.GetAction() == MouseAction::PRESS ? ControlBtnColorType::PRESS : ControlBtnColorType::NORMAL;
120             renderContext->UpdateBackgroundColor(theme->GetControlBtnColor(isCloseBtn, isHoverType));
121             buttonNode->MarkModifyDone();
122             imageNode->MarkModifyDone();
123         }
124     };
125     auto onclickCallback = AceType::MakeRefPtr<InputEvent>(std::move(wkTask));
126     inputHub->AddOnMouseEvent(onclickCallback);
127 }
128 
AddButtonHoverEvent(RefPtr<InputEventHub> & inputHub,RefPtr<FrameNode> & buttonNode,RefPtr<FrameNode> & imageNode,bool isCloseBtn)129 void AddButtonHoverEvent(
130     RefPtr<InputEventHub>& inputHub, RefPtr<FrameNode>& buttonNode, RefPtr<FrameNode>& imageNode, bool isCloseBtn)
131 {
132     auto task = [buttonWk = AceType::WeakClaim(AceType::RawPtr(buttonNode)),
133                     imageWk = AceType::WeakClaim(AceType::RawPtr(imageNode)), isCloseBtn](bool isHover) {
134         auto buttonNode = buttonWk.Upgrade();
135         CHECK_NULL_VOID(buttonNode);
136         auto imageNode = imageWk.Upgrade();
137         CHECK_NULL_VOID(imageNode);
138         auto pipeline = buttonNode->GetContextRefPtr();
139         CHECK_NULL_VOID(pipeline);
140         auto containerNode = AceType::DynamicCast<FrameNode>(pipeline->GetRootElement()->GetChildAtIndex(0));
141         auto containerModalPattern = containerNode->GetPattern<ContainerModalPattern>();
142         CHECK_NULL_VOID(containerModalPattern);
143         bool isFocus = containerModalPattern->GetIsFocus() || containerModalPattern->GetIsHoveredMenu();
144 
145         auto theme = PipelineContext::GetCurrentContext()->GetTheme<ContainerModalTheme>();
146         auto imageLayoutProperty = imageNode->GetLayoutProperty<ImageLayoutProperty>();
147         auto sourceInfo = imageLayoutProperty->GetImageSourceInfo();
148         ControlBtnColorType isHoverFillType = ControlBtnColorType::HOVER_FILL;
149         ControlBtnColorType isHoverType = ControlBtnColorType::HOVER;
150         if (!isHover) {
151             isHoverFillType = isFocus ? ControlBtnColorType::NORMAL_FILL : ControlBtnColorType::UNFOCUS_FILL;
152             isHoverType = isFocus ? ControlBtnColorType::NORMAL : ControlBtnColorType::UNFOCUS;
153         }
154         sourceInfo->SetFillColor(theme->GetControlBtnColor(isCloseBtn, isHoverFillType));
155         if (isCloseBtn) {
156             auto renderContext = buttonNode->GetRenderContext();
157             renderContext->UpdateBackgroundColor(theme->GetControlBtnColor(isCloseBtn, isHoverType));
158         }
159         imageLayoutProperty->UpdateImageSourceInfo(sourceInfo.value());
160         buttonNode->MarkModifyDone();
161         imageNode->MarkModifyDone();
162     };
163     auto hoverCallBack = AceType::MakeRefPtr<InputEvent>(std::move(task));
164     inputHub->AddOnHoverEvent(hoverCallBack);
165 }
166 
AddButtonStyleMouseEvent(RefPtr<FrameNode> & buttonNode,RefPtr<FrameNode> & imageNode,bool isCloseBtn)167 void AddButtonStyleMouseEvent(RefPtr<FrameNode>& buttonNode, RefPtr<FrameNode>& imageNode, bool isCloseBtn)
168 {
169     auto inputHub = buttonNode->GetOrCreateInputEventHub();
170     CHECK_NULL_VOID(inputHub);
171     AddButtonHoverEvent(inputHub, buttonNode, imageNode, isCloseBtn);
172     AddButtonOnEvent(inputHub, buttonNode, imageNode, isCloseBtn);
173 }
174 
AddButtonMouse(RefPtr<FrameNode> & buttonNode,RefPtr<FrameNode> & imageNode)175 void AddButtonMouse(RefPtr<FrameNode>& buttonNode, RefPtr<FrameNode>& imageNode)
176 {
177     auto inputHub = buttonNode->GetOrCreateInputEventHub();
178     CHECK_NULL_VOID(inputHub);
179     auto mouseTask = [buttonWk = AceType::WeakClaim(AceType::RawPtr(buttonNode)),
180                          imageWk = AceType::WeakClaim(AceType::RawPtr(imageNode))](MouseInfo& info) {
181         auto buttonNode = buttonWk.Upgrade();
182         auto imageNode = imageWk.Upgrade();
183         CHECK_NULL_VOID(buttonNode && imageNode);
184         auto buttonPattern = AceType::DynamicCast<ButtonPattern>(buttonNode->GetPattern());
185         CHECK_NULL_VOID(buttonPattern);
186         if (info.GetAction() != MouseAction::MOVE || !buttonPattern->GetIsInHover()) {
187             buttonPattern->SetLocalLocation(info.GetLocalLocation());
188             return;
189         }
190         auto buttonNodeRenderContext = buttonNode->GetRenderContext();
191         auto imageIconRenderContext = imageNode->GetRenderContext();
192         CHECK_NULL_VOID(imageIconRenderContext);
193         float halfSize = TITLE_ICON_SIZE.Value() / 2.0f;
194         auto icurve = AceType::MakeRefPtr<CubicCurve>(0.2f, 0.0f, 0.2f, 1.0f);
195         float maxDis = sqrt(pow(halfSize, 2.0) + pow(halfSize, 2.0));
196         float curDis = sqrt(
197             pow(info.GetLocalLocation().GetX() - halfSize, 2.0) + pow(info.GetLocalLocation().GetY() - halfSize, 2.0));
198         float currentScale = 1 + 0.1 * icurve->Move((maxDis - curDis) / (maxDis));
199         g_baseScale = currentScale > g_baseScale ? currentScale : g_baseScale;
200         float imageScale = g_baseScale;
201         float btnScale = 1.0f;
202         float response = ResponsiveSpringMotion::DEFAULT_RESPONSIVE_SPRING_MOTION_RESPONSE;
203         float dampingRatio = ResponsiveSpringMotion::DEFAULT_RESPONSIVE_SPRING_MOTION_DAMPING_RATIO;
204         float blendDuration = ResponsiveSpringMotion::DEFAULT_RESPONSIVE_SPRING_MOTION_BLEND_DURATION;
205         auto motion = AceType::MakeRefPtr<ResponsiveSpringMotion>(response, dampingRatio, blendDuration);
206         AnimationOption option = AnimationOption();
207         option.SetCurve(motion);
208         AnimationUtils::Animate(option, [buttonNodeRenderContext, imageIconRenderContext, imageScale, btnScale]() {
209             buttonNodeRenderContext->UpdateTransformScale(VectorF(btnScale, btnScale));
210             imageIconRenderContext->UpdateTransformScale(VectorF(imageScale, imageScale));
211         });
212     };
213     auto mouseEvent = AceType::MakeRefPtr<InputEvent>(std::move(mouseTask));
214     inputHub->AddOnMouseEvent(mouseEvent);
215 }
216 
AddButtonHover(RefPtr<FrameNode> & buttonNode,RefPtr<FrameNode> & imageNode)217 void AddButtonHover(RefPtr<FrameNode>& buttonNode, RefPtr<FrameNode>& imageNode)
218 {
219     auto inputHub = buttonNode->GetOrCreateInputEventHub();
220     CHECK_NULL_VOID(inputHub);
221     auto hoverTask = [buttonWk = AceType::WeakClaim(AceType::RawPtr(buttonNode)),
222                          imageWk = AceType::WeakClaim(AceType::RawPtr(imageNode))](bool isHover) {
223         auto buttonNode = buttonWk.Upgrade();
224         auto imageNode = imageWk.Upgrade();
225         CHECK_NULL_VOID(buttonNode && imageNode);
226         auto buttonPattern = AceType::DynamicCast<ButtonPattern>(buttonNode->GetPattern());
227         CHECK_NULL_VOID(buttonPattern);
228         buttonPattern->SetInHover(isHover);
229         float halfSize = TITLE_ICON_SIZE.Value() / 2.0f;
230         auto icurve = AceType::MakeRefPtr<CubicCurve>(0.2f, 0.0f, 0.2f, 1.0f);
231         float maxDis = sqrt(pow(halfSize, 2.0) + pow(halfSize, 2.0));
232         float curDis = sqrt(pow(buttonPattern->GetLocalLocation().GetX() - halfSize, 2.0) +
233                             pow(buttonPattern->GetLocalLocation().GetY() - halfSize, 2.0));
234         float currentScale = 1 + 0.1 * icurve->Move((maxDis - curDis) / (maxDis));
235         g_baseScale = currentScale > g_baseScale ? currentScale : g_baseScale;
236         auto buttonNodeRenderContext = buttonNode->GetRenderContext();
237         auto imageIconRenderContext = imageNode->GetRenderContext();
238         CHECK_NULL_VOID(buttonNodeRenderContext);
239         CHECK_NULL_VOID(imageIconRenderContext);
240         float imageScale = isHover ? g_baseScale : 1.0f;
241         float btnScale = 1.0f;
242         AnimationOption option = AnimationOption();
243         auto motion =
244             AceType::MakeRefPtr<ResponsiveSpringMotion>(SPRINGMOTION_RESPONSE, CURRENT_RATIO, CURRENT_DURATION);
245         option.SetCurve(motion);
246         if (isHover) {
247             AnimationUtils::Animate(option, [buttonNodeRenderContext, imageIconRenderContext, imageScale, btnScale]() {
248                 buttonNodeRenderContext->UpdateTransformScale(VectorF(btnScale, btnScale));
249                 imageIconRenderContext->UpdateTransformScale(VectorF(1 / imageScale, 1 / imageScale));
250             });
251         } else {
252             g_baseScale = 1.0f;
253             AnimationUtils::Animate(option, [buttonNodeRenderContext, imageIconRenderContext, imageScale, btnScale]() {
254                 buttonNodeRenderContext->UpdateTransformScale(VectorF(btnScale, btnScale));
255                 imageIconRenderContext->UpdateTransformScale(VectorF(imageScale, imageScale));
256             });
257         }
258     };
259     auto hoverEvent = AceType::MakeRefPtr<InputEvent>(std::move(hoverTask));
260     inputHub->AddOnHoverEvent(hoverEvent);
261 }
262 } // namespace
263 
BuildControlButtonForCj(InternalResource::ResourceId icon,GestureEventFunc && clickCallback,bool isCloseButton,bool canDrag)264 RefPtr<FrameNode> BuildControlButtonForCj(
265     InternalResource::ResourceId icon, GestureEventFunc&& clickCallback, bool isCloseButton, bool canDrag)
266 {
267     static std::unordered_map<InternalResource::ResourceId, std::string> controlButtonKeyMap = {
268         { InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_SPLIT_LEFT, SPLIT_LEFT_KEY },
269         { InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_DEFOCUS_SPLIT_LEFT, SPLIT_LEFT_KEY },
270         { InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_RECOVER, MAXIMIZE_KEY },
271         { InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_MAXIMIZE, MAXIMIZE_KEY },
272         { InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_DEFOCUS_RECOVER, MAXIMIZE_KEY },
273         { InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_DEFOCUS_MAXIMIZE, MAXIMIZE_KEY },
274         { InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_MINIMIZE, MINIMIZE_KEY },
275         { InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_DEFOCUS_MINIMIZE, MINIMIZE_KEY },
276         { InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_CLOSE, CLOSE_KEY },
277         { InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_DEFOCUS_CLOSE, CLOSE_KEY },
278     };
279     auto theme = PipelineContext::GetCurrentContext()->GetTheme<ContainerModalTheme>();
280     CHECK_NULL_RETURN(theme, nullptr);
281     // button image icon
282     ImageSourceInfo imageSourceInfo;
283     auto imageIcon = FrameNode::CreateFrameNode(
284         V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
285     auto imageEventHub = imageIcon->GetOrCreateGestureEventHub();
286     CHECK_NULL_RETURN(imageEventHub, nullptr);
287     imageEventHub->RemoveDragEvent();
288     imageIcon->SetDraggable(false);
289     auto imageFocus = imageIcon->GetFocusHub();
290     if (imageFocus) {
291         imageFocus->SetFocusable(false);
292     }
293     imageSourceInfo.SetResourceId(icon);
294     imageSourceInfo.SetFillColor(theme->GetControlBtnColor(isCloseButton, ControlBtnColorType::NORMAL_FILL));
295     auto imageLayoutProperty = imageIcon->GetLayoutProperty<ImageLayoutProperty>();
296     CHECK_NULL_RETURN(imageLayoutProperty, nullptr);
297     imageLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(TITLE_ICON_SIZE), CalcLength(TITLE_ICON_SIZE)));
298     imageLayoutProperty->UpdateImageSourceInfo(imageSourceInfo);
299     auto imageRenderProperty = imageIcon->GetPaintProperty<ImageRenderProperty>();
300     CHECK_NULL_RETURN(imageRenderProperty, nullptr);
301     imageRenderProperty->UpdateImageInterpolation(ImageInterpolation::HIGH);
302     imageIcon->MarkModifyDone();
303 
304     auto buttonNode = FrameNode::CreateFrameNode(
305         V2::BUTTON_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ButtonPattern>());
306     auto buttonFocus = buttonNode->GetFocusHub();
307     if (buttonFocus) {
308         buttonFocus->SetFocusable(false);
309     }
310     std::string buttonKey = "";
311     auto iter = controlButtonKeyMap.find(icon);
312     if (iter != controlButtonKeyMap.end()) {
313         buttonKey = iter->second;
314     }
315     buttonNode->UpdateInspectorId(buttonKey);
316 
317     AddButtonHover(buttonNode, imageIcon);
318     AddButtonMouse(buttonNode, imageIcon);
319     AddButtonStyleMouseEvent(buttonNode, imageIcon, isCloseButton);
320 
321     auto renderContext = buttonNode->GetRenderContext();
322     CHECK_NULL_RETURN(renderContext, nullptr);
323     renderContext->UpdateBackgroundColor(theme->GetControlBtnColor(isCloseButton, ControlBtnColorType::NORMAL));
324 
325     auto buttonEventHub = buttonNode->GetOrCreateGestureEventHub();
326     CHECK_NULL_RETURN(buttonEventHub, nullptr);
327     auto clickGesture = AceType::MakeRefPtr<TapGesture>();
328     clickGesture->SetOnActionId(clickCallback);
329     buttonEventHub->AddGesture(clickGesture);
330     buttonNode->SetDraggable(canDrag);
331 
332     DimensionOffset offsetDimen(TITLE_BUTTON_RESPONSE_REGIOIN_OFFSET_X, TITLE_BUTTON_RESPONSE_REGIOIN_OFFSET_Y);
333     DimensionRect dimenRect(TITLE_BUTTON_RESPONSE_REGIOIN_WIDTH, TITLE_BUTTON_RESPONSE_REGIOIN_HEIGHT, offsetDimen);
334     std::vector<DimensionRect> result;
335     result.emplace_back(dimenRect);
336     auto gestureHub = buttonNode->GetOrCreateGestureEventHub();
337     CHECK_NULL_RETURN(gestureHub, nullptr);
338     gestureHub->SetResponseRegion(result);
339 
340     auto buttonLayoutProperty = buttonNode->GetLayoutProperty<ButtonLayoutProperty>();
341     CHECK_NULL_RETURN(buttonLayoutProperty, nullptr);
342     buttonLayoutProperty->UpdateType(ButtonType::CIRCLE);
343     buttonLayoutProperty->UpdateUserDefinedIdealSize(
344         CalcSize(CalcLength(TITLE_BUTTON_SIZE), CalcLength(TITLE_BUTTON_SIZE)));
345 
346     MarginProperty margin;
347     margin.right = CalcLength(isCloseButton ? TITLE_PADDING_END : TITLE_ELEMENT_MARGIN_HORIZONTAL);
348     buttonLayoutProperty->UpdateMargin(margin);
349     buttonNode->MarkModifyDone();
350 
351     buttonNode->AddChild(imageIcon);
352     return buttonNode;
353 }
354 
AddControlButtonsForCj(const WeakPtr<ContainerModalPatternEnhance> & weakPattern,const RefPtr<FrameNode> & containerTitleRow)355 RefPtr<FrameNode> AddControlButtonsForCj(
356     const WeakPtr<ContainerModalPatternEnhance>& weakPattern, const RefPtr<FrameNode>& containerTitleRow)
357 {
358     RefPtr<FrameNode> maximizeBtn = BuildControlButtonForCj(
359         InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_MAXIMIZE, [weakPattern](GestureEvent& info) {
360             auto pattern = weakPattern.Upgrade();
361             CHECK_NULL_VOID(pattern);
362             pattern->OnMaxButtonClick(info);
363         });
364     maximizeBtn->UpdateInspectorId("EnhanceMaximizeBtn");
365 
366     // add long press event
367     WeakPtr<FrameNode> weakMaximizeBtn = maximizeBtn;
368     auto longPressCallback = [weakPattern, weakMaximizeBtn](GestureEvent& info) {
369         auto pattern = weakPattern.Upgrade();
370         CHECK_NULL_VOID(pattern);
371         auto maximizeBtn = weakMaximizeBtn.Upgrade();
372         CHECK_NULL_VOID(maximizeBtn);
373         pattern->ShowMaxMenu(maximizeBtn);
374     };
375     // diable mouse left!
376     auto hub = maximizeBtn->GetOrCreateGestureEventHub();
377     auto longPressEvent = AceType::MakeRefPtr<LongPressEvent>(longPressCallback);
378     hub->SetLongPressEvent(longPressEvent, false, true);
379 
380     auto eventHub = maximizeBtn->GetOrCreateInputEventHub();
381     auto hoverMoveFuc = [weakPattern](MouseInfo& info) {
382         auto pattern = weakPattern.Upgrade();
383         CHECK_NULL_VOID(pattern);
384         pattern->OnMaxBtnInputEvent(info);
385     };
386     eventHub->AddOnMouseEvent(AceType::MakeRefPtr<InputEvent>(std::move(hoverMoveFuc)));
387 
388     // add hover in out event
389     auto hoverEventFuc = [weakPattern, weakMaximizeBtn](bool hover) mutable {
390         auto pattern = weakPattern.Upgrade();
391         CHECK_NULL_VOID(pattern);
392         pattern->OnMaxBtnHoverEvent(hover, weakMaximizeBtn);
393     };
394     eventHub->AddOnHoverEvent(AceType::MakeRefPtr<InputEvent>(std::move(hoverEventFuc)));
395     containerTitleRow->AddChild(maximizeBtn);
396 
397     RefPtr<FrameNode> minimizeBtn = BuildControlButtonForCj(
398         InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_MINIMIZE, [weakPattern](GestureEvent& info) {
399             auto pattern = weakPattern.Upgrade();
400             CHECK_NULL_VOID(pattern);
401             pattern->OnMinButtonClick(info);
402         });
403     // minimizeBtn add empty panEvent to over fater container event
404     minimizeBtn->UpdateInspectorId("EnhanceMinimizeBtn");
405     containerTitleRow->AddChild(minimizeBtn);
406 
407     RefPtr<FrameNode> closeBtn = BuildControlButtonForCj(
408         InternalResource::ResourceId::CONTAINER_MODAL_WINDOW_CLOSE,
409         [weakPattern](GestureEvent& info) {
410             auto pattern = weakPattern.Upgrade();
411             CHECK_NULL_VOID(pattern);
412             pattern->OnCloseButtonClick(info);
413         },
414         true);
415     // closeBtn add empty panEvent to over fater container event
416     closeBtn->UpdateInspectorId("EnhanceCloseBtn");
417     containerTitleRow->AddChild(closeBtn);
418 
419     return containerTitleRow;
420 }
421 
BuildTitleNodeForCj()422 RefPtr<FrameNode> BuildTitleNodeForCj()
423 {
424     auto titleRow = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
425         AceType::MakeRefPtr<LinearLayoutPattern>(false));
426     CHECK_NULL_RETURN(titleRow, nullptr);
427     auto rowLayoutProperty = titleRow->GetLayoutProperty<LinearLayoutProperty>();
428     CHECK_NULL_RETURN(rowLayoutProperty, nullptr);
429 
430     // The magic number in the following style refer to the native arkts application titile_node style
431     PaddingProperty padding = { CalcLength(6), CalcLength(6), CalcLength(8), CalcLength(8) };
432     rowLayoutProperty->UpdatePadding(padding);
433     // Set the width to 100%
434     Dimension width(1.0, DimensionUnit::PERCENT);
435     // Set the height to 37.0vp
436     Dimension height = 37.0_vp;
437     rowLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(NG::CalcLength(width), NG::CalcLength(height)));
438     rowLayoutProperty->UpdateAlignment(WrapAlignment::CENTER);
439     rowLayoutProperty->UpdateAlignSelf(FlexAlign::FLEX_START);
440 
441     // read the configuration in the application and set the naiconme of window title node
442     auto pipeline = PipelineContext::GetCurrentContext();
443     CHECK_NULL_RETURN(pipeline, nullptr);
444     auto themeManager = pipeline->GetThemeManager();
445     CHECK_NULL_RETURN(themeManager, nullptr);
446     auto themeContants = themeManager->GetThemeConstants();
447     CHECK_NULL_RETURN(themeContants, nullptr);
448 
449 #ifdef PIXEL_MAP_SUPPORTED
450     auto iconId = pipeline->GetWindowManager()->GetAppIconId();
451     auto pixelMap = themeContants->GetPixelMap(iconId);
452     if (pixelMap != nullptr) {
453         titleRow->AddChild(BuildCjImageNode(pixelMap));
454     }
455 #endif
456     auto labelId = pipeline->GetWindowManager()->GetAppLabelId();
457     auto label = themeContants->GetString(labelId);
458     titleRow->AddChild(BuildCjTextNode(label));
459     return titleRow;
460 }
461 } // namespace OHOS::Ace::NG
462