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