• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/components_ng/pattern/overlay/sheet_view.h"
17 
18 #include "base/i18n/localization.h"
19 #include "base/utils/utils.h"
20 #include "core/common/ace_application_info.h"
21 #include "core/common/container.h"
22 #include "core/components/common/layout/constants.h"
23 #include "core/components/drag_bar/drag_bar_theme.h"
24 #include "core/components_ng/pattern/button/button_pattern.h"
25 #include "core/components_ng/pattern/image/image_pattern.h"
26 #include "core/components_ng/pattern/linear_layout/linear_layout_property.h"
27 #include "core/components_ng/pattern/overlay/sheet_drag_bar_paint_property.h"
28 #include "core/components_ng/pattern/overlay/sheet_drag_bar_pattern.h"
29 #include "core/components_ng/pattern/overlay/sheet_presentation_property.h"
30 #include "core/components_ng/pattern/overlay/sheet_style.h"
31 #include "core/components_ng/pattern/overlay/sheet_wrapper_pattern.h"
32 #include "core/components_ng/pattern/scroll/scroll_pattern.h"
33 #include "core/components_ng/pattern/scrollable/scrollable_paint_property.h"
34 #include "core/components_ng/pattern/sheet/sheet_mask_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_ng/property/measure_property.h"
38 #include "core/components_v2/inspector/inspector_constants.h"
39 #include "core/pipeline/base/element_register.h"
40 #include "core/pipeline_ng/pipeline_context.h"
41 
42 namespace OHOS::Ace::NG {
43 namespace {
44 constexpr int32_t SHEET_DETENTS_ZERO = 0;
45 constexpr int32_t SHEET_DETENTS_ONE = 1;
46 constexpr int32_t SHEET_DETENTS_TWO = 2;
47 constexpr int32_t SHEET_DETENTS_THREE = 3;
48 constexpr int32_t SHEET_OPERATION_INDEX = 0;
49 constexpr int32_t SHEET_CLOSE_ICON_INDEX = 1;
50 constexpr int32_t SHEET_SCROLL_INDEX = 2;
51 } // namespace
CreateSheetPage(int32_t targetId,std::string targetTag,RefPtr<UINode> builder,RefPtr<FrameNode> titleBuilder,std::function<void (const std::string &)> && callback,NG::SheetStyle & sheetStyle)52 RefPtr<FrameNode> SheetView::CreateSheetPage(int32_t targetId, std::string targetTag, RefPtr<UINode> builder,
53     RefPtr<FrameNode> titleBuilder, std::function<void(const std::string&)>&& callback, NG::SheetStyle& sheetStyle)
54 {
55     // create sheet node
56     ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", V2::SHEET_PAGE_TAG, targetId);
57     auto sheetNode = FrameNode::CreateFrameNode(V2::SHEET_PAGE_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
58         AceType::MakeRefPtr<SheetPresentationPattern>(targetId, targetTag, std::move(callback)));
59     sheetNode->SetDragHitTestBlock(true);
60     auto sheetLayoutProperty = sheetNode->GetLayoutProperty<SheetPresentationProperty>();
61     CHECK_NULL_RETURN(sheetLayoutProperty, nullptr);
62     auto sheetPattern = sheetNode->GetPattern<SheetPresentationPattern>();
63     CHECK_NULL_RETURN(sheetPattern, nullptr);
64     sheetLayoutProperty->UpdateSheetStyle(sheetStyle);
65     auto eventConfirmHub = sheetNode->GetOrCreateGestureEventHub();
66     CHECK_NULL_RETURN(eventConfirmHub, nullptr);
67     eventConfirmHub->AddClickEvent(AceType::MakeRefPtr<NG::ClickEvent>(
68         [](const GestureEvent& /* info */) { TAG_LOGD(AceLogTag::ACE_SHEET, "The sheet hits the click event."); }));
69     sheetPattern->UpdateSheetType();
70     sheetPattern->InitSheetObject();
71     auto operationColumn = CreateOperationColumnNode(titleBuilder, sheetStyle, sheetNode);
72     CHECK_NULL_RETURN(operationColumn, nullptr);
73     operationColumn->MountToParent(sheetNode);
74     sheetPattern->SetTitleBuilderNode(WeakPtr<FrameNode>(operationColumn));
75     auto scrollNode = CreateScrollNode(sheetStyle);
76     CHECK_NULL_RETURN(scrollNode, nullptr);
77     sheetPattern->SetScrollNode(WeakPtr<FrameNode>(scrollNode));
78     builder->MountToParent(scrollNode);
79 
80     auto layoutProperty = scrollNode->GetLayoutProperty<ScrollLayoutProperty>();
81     scrollNode->MountToParent(sheetNode);
82     layoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT);
83     CreateCloseIconButtonNode(sheetNode, sheetStyle);
84     return sheetNode;
85 }
86 
CreateOperationColumnNode(RefPtr<FrameNode> titleBuilder,NG::SheetStyle & sheetStyle,RefPtr<FrameNode> sheetNode)87 RefPtr<FrameNode> SheetView::CreateOperationColumnNode(
88     RefPtr<FrameNode> titleBuilder, NG::SheetStyle& sheetStyle, RefPtr<FrameNode> sheetNode)
89 {
90     auto operationColumn = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG,
91         ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<LinearLayoutPattern>(true));
92     CHECK_NULL_RETURN(operationColumn, nullptr);
93     auto layoutProps = operationColumn->GetLayoutProperty<LinearLayoutProperty>();
94     CHECK_NULL_RETURN(layoutProps, nullptr);
95     auto pipeline = PipelineContext::GetCurrentContext();
96     CHECK_NULL_RETURN(pipeline, nullptr);
97     auto sheetTheme = pipeline->GetTheme<SheetTheme>();
98     CHECK_NULL_RETURN(sheetTheme, nullptr);
99     auto sheetDragBarHeight = sheetTheme->GetSheetDragBarHeight();
100     CreateDragBarNode(titleBuilder, operationColumn, sheetStyle, sheetNode, sheetDragBarHeight);
101     MarginProperty margin;
102     margin.right = CalcLength(sheetTheme->GetTitleTextHorizMargin());
103     margin.left = CalcLength(sheetTheme->GetTitleTextHorizMargin());
104     layoutProps->UpdateMargin(margin);
105     auto sheetPattern = sheetNode->GetPattern<SheetPresentationPattern>();
106     layoutProps->UpdateMeasureType(MeasureType::MATCH_PARENT_CROSS_AXIS);
107     if (sheetStyle.isTitleBuilder.has_value() && pipeline->GetFontScale() == sheetTheme->GetSheetNormalScale()) {
108         layoutProps->UpdateUserDefinedIdealSize(CalcSize(
109             std::nullopt, CalcLength(sheetTheme->GetOperationAreaHeight() - sheetTheme->GetSheetTitleAreaMargin() -
110                                      sheetPattern->GetDragBarHeight(sheetPattern->GetDragBarNode()))));
111         if (sheetStyle.sheetTitle.has_value() && sheetStyle.sheetSubtitle.has_value()) {
112             layoutProps->UpdateUserDefinedIdealSize(CalcSize(std::nullopt,
113                 CalcLength(sheetTheme->GetOperationAreaHeightDouble() - sheetTheme->GetSheetTitleAreaMargin() -
114                            sheetPattern->GetDragBarHeight(sheetPattern->GetDragBarNode()))));
115         }
116     }
117 
118     // set accessibilityProperty to sheet operation column
119     auto accessibilityProperty = operationColumn->GetAccessibilityProperty<NG::AccessibilityProperty>();
120     CHECK_NULL_RETURN(accessibilityProperty, nullptr);
121     accessibilityProperty->SetAccessibilityZIndex(SHEET_OPERATION_INDEX);
122     return operationColumn;
123 }
124 
CreateDragBarNode(const RefPtr<FrameNode> & titleBuilder,const RefPtr<FrameNode> & operationColumn,NG::SheetStyle & sheetStyle,const RefPtr<FrameNode> & sheetNode,Dimension sheetDragBarHeight)125 void SheetView::CreateDragBarNode(const RefPtr<FrameNode>& titleBuilder, const RefPtr<FrameNode>& operationColumn,
126     NG::SheetStyle& sheetStyle, const RefPtr<FrameNode>& sheetNode, Dimension sheetDragBarHeight)
127 {
128     auto dragBarNode = FrameNode::GetOrCreateFrameNode("SheetDragBar", ElementRegister::GetInstance()->MakeUniqueId(),
129         []() { return AceType::MakeRefPtr<SheetDragBarPattern>(); });
130     auto dragBarLayoutProperty = dragBarNode->GetLayoutProperty();
131     CHECK_NULL_VOID(dragBarLayoutProperty);
132     dragBarLayoutProperty->UpdateUserDefinedIdealSize(
133         CalcSize(CalcLength(SHEET_DRAG_BAR_WIDTH), CalcLength(sheetDragBarHeight)));
134     dragBarLayoutProperty->UpdateAlignment(Alignment::CENTER);
135     auto showDragIndicator = sheetStyle.showDragBar.value_or(true);
136 
137     // 1. showDragBar && not single detents && sheet in bottom style (only bottom style can show drag bar)
138     // 2. has SystemTitleBar
139     // need set drag bar invisible to occupy place
140     CHECK_NULL_VOID(sheetNode);
141     auto sheetPattern = sheetNode->GetPattern<SheetPresentationPattern>();
142     CHECK_NULL_VOID(sheetPattern);
143     sheetPattern->SetDragBarNode(WeakPtr<FrameNode>(dragBarNode));
144     if ((!IsSingleDetents(sheetStyle) && showDragIndicator && sheetPattern->IsSheetBottomStyle())
145         || sheetStyle.isTitleBuilder.has_value()) {
146         dragBarLayoutProperty->UpdateVisibility(VisibleType::INVISIBLE);
147     } else {
148         dragBarLayoutProperty->UpdateVisibility(VisibleType::GONE);
149     }
150 
151     sheetNode->AddChild(dragBarNode, 0);
152     dragBarNode->MarkModifyDone();
153 
154     if (sheetStyle.isTitleBuilder.has_value()) {
155         auto titleColumn = BuildTitleColumn(sheetNode, sheetStyle);
156         if (titleColumn) {
157             if ((titleBuilder) && (sheetStyle.isTitleBuilder.value())) {
158                 titleColumn->AddChild(titleBuilder);
159                 titleBuilder->MarkModifyDone();
160             }
161             titleColumn->MountToParent(operationColumn);
162             titleColumn->GetRenderContext()->SetClipToBounds(true);
163             titleColumn->GetRenderContext()->UpdateClipEdge(true);
164         }
165     }
166 }
167 
CreateCloseIconButtonNode(RefPtr<FrameNode> sheetNode,NG::SheetStyle & sheetStyle)168 void SheetView::CreateCloseIconButtonNode(RefPtr<FrameNode> sheetNode, NG::SheetStyle& sheetStyle)
169 {
170     if (!Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
171         return;
172     }
173     auto buttonNode = FrameNode::GetOrCreateFrameNode(V2::BUTTON_ETS_TAG,
174         ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<ButtonPattern>(); });
175     CHECK_NULL_VOID(buttonNode);
176     auto buttonLayoutProperty = buttonNode->GetLayoutProperty<ButtonLayoutProperty>();
177     CHECK_NULL_VOID(buttonLayoutProperty);
178     auto pipeline = PipelineContext::GetCurrentContext();
179     CHECK_NULL_VOID(pipeline);
180     auto sheetTheme = pipeline->GetTheme<SheetTheme>();
181     CHECK_NULL_VOID(sheetTheme);
182     buttonNode->GetRenderContext()->UpdateBackgroundColor(sheetTheme->GetCloseIconColor());
183     buttonLayoutProperty->UpdateType(ButtonType::NORMAL);
184     BorderRadiusProperty borderRaduis;
185     borderRaduis.SetRadius(sheetTheme->GetCloseIconRadius());
186     buttonLayoutProperty->UpdateBorderRadius(borderRaduis);
187     buttonLayoutProperty->UpdateButtonStyle(static_cast<ButtonStyleMode>(sheetTheme->GetCloseIconButtonStyle()));
188     auto closeIconButtonSize = CalcLength(sheetTheme->GetCloseIconButtonWidth());
189     buttonLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(closeIconButtonSize, closeIconButtonSize));
190     buttonLayoutProperty->UpdateVisibility(VisibleType::GONE);
191     auto eventConfirmHub = buttonNode->GetOrCreateGestureEventHub();
192     CHECK_NULL_VOID(eventConfirmHub);
193     auto clickCallback = [weak = AceType::WeakClaim(AceType::RawPtr(sheetNode))](const GestureEvent& /* info */) {
194         auto sheet = weak.Upgrade();
195         CHECK_NULL_VOID(sheet);
196         auto sheetPattern = sheet->GetPattern<SheetPresentationPattern>();
197         CHECK_NULL_VOID(sheetPattern);
198         sheetPattern->SheetInteractiveDismiss(BindSheetDismissReason::CLOSE_BUTTON);
199     };
200     eventConfirmHub->AddClickEvent(AceType::MakeRefPtr<NG::ClickEvent>(clickCallback));
201     // make the close button focusable when press tab
202     auto focusHub = buttonNode->GetOrCreateFocusHub();
203     CHECK_NULL_VOID(focusHub);
204     focusHub->SetFocusDependence(FocusDependence::SELF);
205     buttonNode->MarkModifyDone();
206 
207     CreateCloseIconNode(buttonNode);
208     buttonNode->MountToParent(sheetNode);
209     auto sheetPattern = sheetNode->GetPattern<SheetPresentationPattern>();
210     CHECK_NULL_VOID(sheetPattern);
211     sheetPattern->SetCloseButtonNode(WeakPtr<FrameNode>(buttonNode));
212 
213     // set accessibilityProperty to sheet close button
214     auto accessibilityProperty = buttonNode->GetAccessibilityProperty<NG::AccessibilityProperty>();
215     CHECK_NULL_VOID(accessibilityProperty);
216     std::string message = sheetTheme->GetSheetClose();
217     accessibilityProperty->SetAccessibilityText(message);
218     accessibilityProperty->SetAccessibilityZIndex(SHEET_CLOSE_ICON_INDEX);
219 }
220 
CreateCloseIconNode(RefPtr<FrameNode> buttonNode)221 void SheetView::CreateCloseIconNode(RefPtr<FrameNode> buttonNode)
222 {
223     auto pipeline = buttonNode->GetContext();
224     CHECK_NULL_VOID(pipeline);
225     auto sheetTheme = pipeline->GetTheme<SheetTheme>();
226     CHECK_NULL_VOID(sheetTheme);
227     RefPtr<FrameNode> iconNode;
228 
229     // when api >= 12, use symbol format image, else use image format.
230     if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE) &&
231         SystemProperties::IsNeedSymbol()) {
232         iconNode = FrameNode::CreateFrameNode(
233             V2::SYMBOL_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
234         CHECK_NULL_VOID(iconNode);
235         auto symbolLayoutProperty = iconNode->GetLayoutProperty<TextLayoutProperty>();
236         CHECK_NULL_VOID(symbolLayoutProperty);
237         uint32_t symbolId = sheetTheme->GetCloseIconSource();
238         symbolLayoutProperty->UpdateSymbolSourceInfo(SymbolSourceInfo{symbolId});
239         symbolLayoutProperty->UpdateFontSize(sheetTheme->GetCloseIconWidth());
240         symbolLayoutProperty->UpdateSymbolColorList({sheetTheme->GetCloseIconSymbolColor()});
241     } else {
242         iconNode = FrameNode::CreateFrameNode(
243             V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
244         CHECK_NULL_VOID(iconNode);
245         auto imageLayoutProperty = iconNode->GetLayoutProperty<ImageLayoutProperty>();
246         CHECK_NULL_VOID(imageLayoutProperty);
247         imageLayoutProperty->UpdateUserDefinedIdealSize(
248             CalcSize(CalcLength(SHEET_CLOSE_ICON_IMAGE_HEIGHT), CalcLength(SHEET_CLOSE_ICON_IMAGE_HEIGHT)));
249         imageLayoutProperty->UpdateImageFit(ImageFit::FILL);
250         ImageSourceInfo imageSourceInfo;
251         imageSourceInfo.SetResourceId(InternalResource::ResourceId::IC_CANCEL_SVG);
252         imageSourceInfo.SetFillColor(sheetTheme->GetCloseIconImageColor());
253         imageLayoutProperty->UpdateImageSourceInfo(imageSourceInfo);
254     }
255     iconNode->MarkModifyDone();
256     buttonNode->AddChild(iconNode);
257 }
258 
IsSingleDetents(const NG::SheetStyle & sheetStyle)259 bool SheetView::IsSingleDetents(const NG::SheetStyle& sheetStyle)
260 {
261     bool isSingle = true;
262     if (sheetStyle.detents.size() == SHEET_DETENTS_TWO) {
263         isSingle = sheetStyle.detents[SHEET_DETENTS_ZERO] == sheetStyle.detents[SHEET_DETENTS_ONE];
264     } else if (sheetStyle.detents.size() == SHEET_DETENTS_THREE) {
265         isSingle = sheetStyle.detents[SHEET_DETENTS_ZERO] == sheetStyle.detents[SHEET_DETENTS_ONE] &&
266                    sheetStyle.detents[SHEET_DETENTS_ONE] == sheetStyle.detents[SHEET_DETENTS_TWO];
267     }
268     return isSingle;
269 }
270 
CreateScrollNode(const NG::SheetStyle & sheetStyle)271 RefPtr<FrameNode> SheetView::CreateScrollNode(const NG::SheetStyle& sheetStyle)
272 {
273     auto scroll = FrameNode::CreateFrameNode(
274         V2::SCROLL_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ScrollPattern>());
275     CHECK_NULL_RETURN(scroll, nullptr);
276     auto props = scroll->GetLayoutProperty<ScrollLayoutProperty>();
277     CHECK_NULL_RETURN(props, nullptr);
278     props->UpdateScrollEnabled(true);
279     props->UpdateAxis(Axis::VERTICAL);
280     auto paintProps = scroll->GetPaintProperty<ScrollablePaintProperty>();
281     CHECK_NULL_RETURN(paintProps, nullptr);
282     paintProps->UpdateScrollBarMode(DisplayMode::OFF);
283     auto pattern = scroll->GetPattern<ScrollablePattern>();
284     CHECK_NULL_RETURN(pattern, nullptr);
285     if (sheetStyle.sheetEffectEdge.has_value() && sheetStyle.sheetEffectEdge.value() == NG::SheetEffectEdge::NONE) {
286         pattern->SetEdgeEffect(EdgeEffect::NONE, false);
287     } else {
288         pattern->SetEdgeEffect(EdgeEffect::SPRING,
289             false, static_cast<EffectEdge>(sheetStyle.sheetEffectEdge.value_or(NG::SheetEffectEdge::ALL)));
290     }
291     pattern->SetScrollToSafeAreaHelper(false);
292     props->UpdateAlignment(Alignment::TOP_CENTER);
293     if (AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE)) {
294         NestedScrollOptions nestedOpt = {
295             .forward = NestedScrollMode::PARENT_FIRST,
296             .backward = NestedScrollMode::SELF_FIRST,
297         };
298         pattern->SetNestedScroll(nestedOpt);
299     }
300     scroll->MarkModifyDone();
301 
302     // set accessibilityProperty to sheet scroll node
303     auto accessibilityProperty = scroll->GetAccessibilityProperty<NG::AccessibilityProperty>();
304     CHECK_NULL_RETURN(accessibilityProperty, nullptr);
305     accessibilityProperty->SetAccessibilityZIndex(SHEET_SCROLL_INDEX);
306     return scroll;
307 }
308 
BuildMainTitle(RefPtr<FrameNode> sheetNode,NG::SheetStyle & sheetStyle)309 RefPtr<FrameNode> SheetView::BuildMainTitle(RefPtr<FrameNode> sheetNode, NG::SheetStyle& sheetStyle)
310 {
311     auto pattern = sheetNode->GetPattern<SheetPresentationPattern>();
312     CHECK_NULL_RETURN(pattern, nullptr);
313     auto titleId = pattern->GetTitleId();
314     pattern->SetTitleId(titleId);
315     auto sheetTitle = FrameNode::CreateFrameNode(V2::TEXT_ETS_TAG, titleId, AceType::MakeRefPtr<TextPattern>());
316     CHECK_NULL_RETURN(sheetTitle, nullptr);
317     auto pipeline = PipelineContext::GetCurrentContext();
318     CHECK_NULL_RETURN(pipeline, nullptr);
319     auto sheetTheme = pipeline->GetTheme<SheetTheme>();
320     CHECK_NULL_RETURN(sheetTheme, nullptr);
321     auto titleProp = sheetTitle->GetLayoutProperty<TextLayoutProperty>();
322     CHECK_NULL_RETURN(titleProp, nullptr);
323     auto titleTextFontSize = sheetTheme->GetTitleTextFontSize();
324     auto sheetTitleFontWeight = sheetTheme->GetSheetTitleFontWeight();
325     titleTextFontSize.SetUnit(DimensionUnit::FP);
326 
327     auto textTheme = pipeline->GetTheme<TextTheme>();
328     if (textTheme && textTheme->GetIsTextFadeout()) {
329         titleProp->UpdateTextOverflow(TextOverflow::MARQUEE);
330         titleProp->UpdateTextMarqueeStartPolicy(MarqueeStartPolicy::ON_FOCUS);
331         titleProp->UpdateTextMarqueeFadeout(true);
332     } else {
333         titleProp->UpdateMaxLines(SHEET_TITLE_MAX_LINES);
334         titleProp->UpdateTextOverflow(TextOverflow::ELLIPSIS);
335     }
336 
337     titleProp->UpdateAdaptMaxFontSize(titleTextFontSize);
338     titleProp->UpdateAdaptMinFontSize(titleTextFontSize);
339     if (sheetStyle.sheetTitle.has_value()) {
340         titleProp->UpdateContent(sheetStyle.sheetTitle.value());
341     }
342     titleProp->UpdateMaxFontScale(sheetTheme->GetSheetMaxAgingScale());
343     titleProp->UpdateFontSize(titleTextFontSize);
344     titleProp->UpdateFontWeight(sheetTitleFontWeight);
345     titleProp->UpdateTextColor(sheetTheme->GetTitleTextFontColor());
346 
347     auto titleRow = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
348         AceType::MakeRefPtr<LinearLayoutPattern>(false));
349     CHECK_NULL_RETURN(titleRow, nullptr);
350     auto titleRowProps = titleRow->GetLayoutProperty<LinearLayoutProperty>();
351     CHECK_NULL_RETURN(titleRowProps, nullptr);
352     titleRowProps->UpdateMainAxisAlign(FlexAlign::FLEX_START);
353     titleRowProps->UpdateMeasureType(MeasureType::MATCH_CONTENT);
354     sheetTitle->MountToParent(titleRow);
355     sheetTitle->MarkModifyDone();
356     return titleRow;
357 }
358 
BuildSubTitle(RefPtr<FrameNode> sheetNode,NG::SheetStyle & sheetStyle)359 RefPtr<FrameNode> SheetView::BuildSubTitle(RefPtr<FrameNode> sheetNode, NG::SheetStyle& sheetStyle)
360 {
361     CHECK_NULL_RETURN(sheetNode, nullptr);
362     auto pattern = sheetNode->GetPattern<SheetPresentationPattern>();
363     CHECK_NULL_RETURN(pattern, nullptr);
364     auto subtitleId = pattern->GetSubtitleId();
365     pattern->SetSubtitleId(subtitleId);
366     auto sheetSubtitle = FrameNode::CreateFrameNode(V2::TEXT_ETS_TAG, subtitleId, AceType::MakeRefPtr<TextPattern>());
367     CHECK_NULL_RETURN(sheetSubtitle, nullptr);
368     auto pipeline = PipelineContext::GetCurrentContext();
369     CHECK_NULL_RETURN(pipeline, nullptr);
370     auto sheetTheme = pipeline->GetTheme<SheetTheme>();
371     CHECK_NULL_RETURN(sheetTheme, nullptr);
372     auto titleProp = AceType::DynamicCast<TextLayoutProperty>(sheetSubtitle->GetLayoutProperty());
373     CHECK_NULL_RETURN(titleProp, nullptr);
374     auto titleTextFontSize = sheetTheme->GetSubtitleTextFontSize();
375     titleTextFontSize.SetUnit(DimensionUnit::VP);
376 
377     auto textTheme = pipeline->GetTheme<TextTheme>();
378     if (textTheme && textTheme->GetIsTextFadeout()) {
379         titleProp->UpdateTextOverflow(TextOverflow::MARQUEE);
380         titleProp->UpdateTextMarqueeStartPolicy(MarqueeStartPolicy::ON_FOCUS);
381         titleProp->UpdateTextMarqueeFadeout(true);
382     } else {
383         titleProp->UpdateMaxLines(SHEET_TITLE_MAX_LINES);
384         titleProp->UpdateTextOverflow(TextOverflow::ELLIPSIS);
385     }
386 
387     titleProp->UpdateAdaptMaxFontSize(titleTextFontSize);
388     titleProp->UpdateAdaptMinFontSize(titleTextFontSize);
389     if (sheetStyle.sheetSubtitle.has_value()) {
390         titleProp->UpdateContent(sheetStyle.sheetSubtitle.value());
391     }
392     titleProp->UpdateFontSize(titleTextFontSize);
393     titleProp->UpdateTextColor(sheetTheme->GetSubtitleTextFontColor());
394     PaddingProperty titlePadding;
395     titlePadding.top = CalcLength(sheetTheme->GetSubtitleTextMargin());
396     titleProp->UpdatePadding(titlePadding);
397 
398     auto subtitleRow = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
399         AceType::MakeRefPtr<LinearLayoutPattern>(false));
400     CHECK_NULL_RETURN(subtitleRow, nullptr);
401     auto subtitleRowProps = subtitleRow->GetLayoutProperty<LinearLayoutProperty>();
402     CHECK_NULL_RETURN(subtitleRowProps, nullptr);
403     subtitleRowProps->UpdateMainAxisAlign(FlexAlign::FLEX_START);
404     subtitleRowProps->UpdateMeasureType(MeasureType::MATCH_CONTENT);
405     sheetSubtitle->MountToParent(subtitleRow);
406     sheetSubtitle->MarkModifyDone();
407     return subtitleRow;
408 }
409 
SetTitleColumnMinSize(RefPtr<LayoutProperty> layoutProperty,const NG::SheetStyle & sheetStyle,const RefPtr<SheetTheme> & sheetTheme)410 void SheetView::SetTitleColumnMinSize(RefPtr<LayoutProperty> layoutProperty, const NG::SheetStyle& sheetStyle,
411     const RefPtr<SheetTheme>& sheetTheme)
412 {
413     if (sheetStyle.sheetTitle.has_value()) {
414         layoutProperty->UpdateCalcMinSize(CalcSize(std::nullopt, CalcLength(SHEET_OPERATION_AREA_HEIGHT)));
415         if (sheetStyle.sheetSubtitle.has_value()) {
416             layoutProperty->UpdateCalcMinSize(CalcSize(std::nullopt,
417                 CalcLength(sheetTheme->GetOperationAreaHeightDouble() - SHEET_DOUBLE_TITLE_BOTTON_MARGIN)));
418         }
419     }
420 }
421 
CreateSheetMaskShowInSubwindow(const RefPtr<FrameNode> & sheetPageNode,const RefPtr<FrameNode> & sheetWrapperNode,const RefPtr<FrameNode> & targetNode,NG::SheetStyle & sheetStyle)422 RefPtr<FrameNode> SheetView::CreateSheetMaskShowInSubwindow(const RefPtr<FrameNode>& sheetPageNode,
423     const RefPtr<FrameNode>& sheetWrapperNode, const RefPtr<FrameNode>& targetNode, NG::SheetStyle& sheetStyle)
424 {
425     auto container = Container::Current();
426     CHECK_NULL_RETURN(container, nullptr);
427     if (!container->IsSubContainer()) {
428         return nullptr;
429     }
430     // create and mount sheetWrapperNode
431     auto sheetWrapperPattern = sheetWrapperNode->GetPattern<SheetWrapperPattern>();
432     CHECK_NULL_RETURN(sheetWrapperPattern, nullptr);
433     auto maskNode = FrameNode::CreateFrameNode("SheetMask", ElementRegister::GetInstance()->MakeUniqueId(),
434         AceType::MakeRefPtr<SheetMaskPattern>(targetNode->GetId(), targetNode->GetTag()));
435     CHECK_NULL_RETURN(maskNode, nullptr);
436     if (sheetWrapperPattern->ShowInUEC()) {
437         maskNode->MountToParent(sheetWrapperNode);
438     } else {
439         auto subwindowId = sheetWrapperPattern->GetSubWindowId();
440         auto mainWindowId = SubwindowManager::GetInstance()->GetParentContainerId(subwindowId);
441         auto mainWindowContext = PipelineContext::GetContextByContainerId(mainWindowId);
442         CHECK_NULL_RETURN(mainWindowContext, nullptr);
443         auto overlayManager = mainWindowContext->GetOverlayManager();
444         CHECK_NULL_RETURN(overlayManager, nullptr);
445         auto mainWindowRoot = overlayManager->GetRootNode().Upgrade();
446         CHECK_NULL_RETURN(mainWindowRoot, nullptr);
447         overlayManager->MountToParentWithService(mainWindowRoot, maskNode);
448         mainWindowRoot->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
449     }
450     auto sheetNodePattern = sheetPageNode->GetPattern<SheetPresentationPattern>();
451     CHECK_NULL_RETURN(sheetNodePattern, nullptr);
452     TAG_LOGI(AceLogTag::ACE_SHEET, "show in subwindow mount sheet page node");
453     sheetPageNode->MountToParent(sheetWrapperNode);
454     // Update sheet type needs to get subwindow messages which is updated
455     // after sheetWrapper MountToParent root, after sheetPage MountToParent sheetWrapper.
456     sheetNodePattern->UpdateSheetType();
457     sheetNodePattern->UpdateSheetObject(sheetNodePattern->GetSheetTypeNoProcess());
458     sheetWrapperPattern->SetSheetMaskNode(maskNode);
459     sheetWrapperPattern->SetSheetPageNode(sheetPageNode);
460     return maskNode;
461 }
462 
BuildTitleColumn(RefPtr<FrameNode> sheetNode,NG::SheetStyle & sheetStyle)463 RefPtr<FrameNode> SheetView::BuildTitleColumn(RefPtr<FrameNode> sheetNode, NG::SheetStyle& sheetStyle)
464 {
465     auto titleColumn = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
466         AceType::MakeRefPtr<LinearLayoutPattern>(true));
467     CHECK_NULL_RETURN(titleColumn, nullptr);
468     auto layoutProperty = titleColumn->GetLayoutProperty();
469     CHECK_NULL_RETURN(layoutProperty, nullptr);
470     auto pipeline = PipelineContext::GetCurrentContext();
471     CHECK_NULL_RETURN(pipeline, nullptr);
472     auto sheetTheme = pipeline->GetTheme<SheetTheme>();
473     CHECK_NULL_RETURN(sheetTheme, nullptr);
474     SetTitleColumnMinSize(layoutProperty, sheetStyle, sheetTheme);
475     layoutProperty->UpdateMeasureType(MeasureType::MATCH_PARENT_CROSS_AXIS);
476     bool isTitleCustombuilder = sheetStyle.isTitleBuilder.has_value() && sheetStyle.isTitleBuilder.value();
477     if (pipeline->GetFontScale() == sheetTheme->GetSheetNormalScale() || isTitleCustombuilder) {
478         layoutProperty->UpdateUserDefinedIdealSize(
479             CalcSize(std::nullopt, CalcLength(sheetTheme->GetOperationAreaHeight())));
480     }
481     MarginProperty margin;
482     margin.top = CalcLength(sheetTheme->GetSheetTitleAreaMargin());
483     margin.bottom = CalcLength(SHEET_DOUBLE_TITLE_BOTTON_MARGIN);
484     layoutProperty->UpdateMargin(margin);
485     auto columnProps = titleColumn->GetLayoutProperty<LinearLayoutProperty>();
486     CHECK_NULL_RETURN(columnProps, nullptr);
487     columnProps->UpdateCrossAxisAlign(FlexAlign::FLEX_START);
488     if (sheetStyle.sheetTitle.has_value()) {
489         auto titleRow = BuildMainTitle(sheetNode, sheetStyle);
490         CHECK_NULL_RETURN(titleRow, nullptr);
491         titleRow->MountToParent(titleColumn);
492         MarginProperty titleMargin;
493         titleMargin.top = CalcLength(sheetTheme->GetTitleTopPadding());
494         auto titleProp = titleRow->GetLayoutProperty();
495         CHECK_NULL_RETURN(titleProp, nullptr);
496         titleProp->UpdateMargin(titleMargin);
497         if (sheetStyle.sheetSubtitle.has_value()) {
498             auto subtitleRow = BuildSubTitle(sheetNode, sheetStyle);
499             CHECK_NULL_RETURN(subtitleRow, nullptr);
500             subtitleRow->MountToParent(titleColumn);
501             if (pipeline->GetFontScale() == sheetTheme->GetSheetNormalScale()) {
502                 layoutProperty->UpdateUserDefinedIdealSize(CalcSize(std::nullopt, CalcLength(
503                     sheetTheme->GetOperationAreaHeightDouble() - SHEET_DOUBLE_TITLE_BOTTON_MARGIN)));
504             }
505         }
506     } else if (sheetStyle.isTitleBuilder.has_value()) {
507         auto isCustomBuilder = sheetStyle.isTitleBuilder.value();
508 
509         // When title is custombuilder, set FlexAlign to CENTER.
510         if (isCustomBuilder) {
511             columnProps->UpdateMainAxisAlign(FlexAlign::CENTER);
512         }
513     }
514     return titleColumn;
515 }
516 } // namespace OHOS::Ace::NG
517