1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/components_ng/pattern/panel/sliding_panel_model_ng.h"
17 
18 #include "base/geometry/dimension.h"
19 #include "base/memory/ace_type.h"
20 #include "base/memory/referenced.h"
21 #include "base/utils/utils.h"
22 #include "core/components/common/layout/constants.h"
23 #include "core/components/drag_bar/drag_bar_theme.h"
24 #include "core/components_ng/base/view_stack_processor.h"
25 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
26 #include "core/components_ng/pattern/linear_layout/linear_layout_property.h"
27 #include "core/components_ng/pattern/panel/drag_bar_pattern.h"
28 #include "core/components_ng/pattern/panel/sliding_panel_node.h"
29 #include "core/components_ng/pattern/panel/sliding_panel_pattern.h"
30 #include "core/components_v2/inspector/inspector_constants.h"
31 #include "core/pipeline_ng/pipeline_context.h"
32 
33 namespace OHOS::Ace::NG {
34 
35 namespace {
36 const Dimension PANEL_RADIUS = 32.0_vp;
37 constexpr Dimension BLANK_MIN_HEIGHT = 8.0_vp;
38 constexpr double HALF_VALUS = 2.0;
39 } // namespace
40 
Create(bool isShow)41 void SlidingPanelModelNG::Create(bool isShow)
42 {
43     auto* stack = ViewStackProcessor::GetInstance();
44     auto nodeId = stack->ClaimNodeId();
45     ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", V2::PANEL_ETS_TAG, nodeId);
46     auto panelNode = GetOrCreateSlidingPanelNode(
47         V2::PANEL_ETS_TAG, nodeId, []() { return AceType::MakeRefPtr<SlidingPanelPattern>(); });
48 
49     // Create Column node to mount to Panel.
50     auto columnId = panelNode->GetColumnId();
51     auto columnNode = FrameNode::GetOrCreateFrameNode(
52         V2::COLUMN_ETS_TAG, columnId, []() { return AceType::MakeRefPtr<LinearLayoutPattern>(true); });
53     columnNode->MountToParent(panelNode);
54     auto contentId = panelNode->GetContentId();
55     auto contentNode = FrameNode::GetOrCreateFrameNode(
56         V2::COLUMN_ETS_TAG, contentId, []() { return AceType::MakeRefPtr<LinearLayoutPattern>(true); });
57     auto contentLayoutProperty = contentNode->GetLayoutProperty<LayoutProperty>();
58     CHECK_NULL_VOID(contentLayoutProperty);
59     contentLayoutProperty->UpdateLayoutWeight(1.0f);
60     contentNode->MountToParent(columnNode);
61 
62     ViewStackProcessor::GetInstance()->Push(panelNode);
63     auto slidingPanelPattern = panelNode->GetPattern<SlidingPanelPattern>();
64     CHECK_NULL_VOID(slidingPanelPattern);
65     auto layoutProperty = slidingPanelPattern->GetLayoutProperty<SlidingPanelLayoutProperty>();
66     CHECK_NULL_VOID(layoutProperty);
67     ACE_UPDATE_LAYOUT_PROPERTY(SlidingPanelLayoutProperty, PanelType,
68         layoutProperty->GetPanelTypeValue(PanelType::FOLDABLE_BAR));    // default value
69     ACE_UPDATE_LAYOUT_PROPERTY(SlidingPanelLayoutProperty, HasDragBar,
70         layoutProperty->GetHasDragBarValue(true));                      // default value
71     ACE_UPDATE_LAYOUT_PROPERTY(SlidingPanelLayoutProperty, PanelMode,
72         layoutProperty->GetPanelModeValue(PanelMode::HALF));            // default value
73     ACE_UPDATE_LAYOUT_PROPERTY(SlidingPanelLayoutProperty, IsShow, isShow);
74 
75     auto renderContext = columnNode->GetRenderContext();
76     if (renderContext) {
77         auto pipeline = PipelineContext::GetCurrentContext();
78         CHECK_NULL_VOID(pipeline);
79         auto dragBarTheme = pipeline->GetTheme<DragBarTheme>();
80         CHECK_NULL_VOID(dragBarTheme);
81         renderContext->UpdateBackgroundColor(dragBarTheme->GetPanelBgColor());
82         BorderRadiusProperty radius;
83         radius.radiusTopLeft = PANEL_RADIUS;
84         radius.radiusTopRight = PANEL_RADIUS;
85         renderContext->UpdateBorderRadius(radius);
86         renderContext->UpdateClipEdge(true);
87     }
88 }
89 
GetOrCreateSlidingPanelNode(const std::string & tag,int32_t nodeId,const std::function<RefPtr<Pattern> (void)> & patternCreator)90 RefPtr<SlidingPanelNode> SlidingPanelModelNG::GetOrCreateSlidingPanelNode(
91     const std::string& tag, int32_t nodeId, const std::function<RefPtr<Pattern>(void)>& patternCreator)
92 {
93     auto panelNode = ElementRegister::GetInstance()->GetSpecificItemById<SlidingPanelNode>(nodeId);
94     if (panelNode) {
95         if (panelNode->GetTag() == tag) {
96             return panelNode;
97         }
98         ElementRegister::GetInstance()->RemoveItemSilently(nodeId);
99         auto parent = panelNode->GetParent();
100         if (parent) {
101             parent->RemoveChild(panelNode);
102         }
103     }
104 
105     auto pattern = patternCreator ? patternCreator() : AceType::MakeRefPtr<Pattern>();
106     panelNode = AceType::MakeRefPtr<SlidingPanelNode>(tag, nodeId, pattern, false);
107     panelNode->InitializePatternAndContext();
108     ElementRegister::GetInstance()->AddUINode(panelNode);
109     return panelNode;
110 }
111 
GetLinearLayoutProperty()112 RefPtr<LinearLayoutProperty> SlidingPanelModelNG::GetLinearLayoutProperty()
113 {
114     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
115     CHECK_NULL_RETURN(frameNode, nullptr);
116     auto columnNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildren().back());
117     CHECK_NULL_RETURN(columnNode, nullptr);
118     auto columnLayoutProperty = columnNode->GetLayoutProperty<LinearLayoutProperty>();
119     CHECK_NULL_RETURN(columnLayoutProperty, nullptr);
120     return columnLayoutProperty;
121 }
122 
SetPanelType(PanelType type)123 void SlidingPanelModelNG::SetPanelType(PanelType type)
124 {
125     ACE_UPDATE_LAYOUT_PROPERTY(SlidingPanelLayoutProperty, PanelType, type);
126 }
127 
SetPanelMode(PanelMode mode)128 void SlidingPanelModelNG::SetPanelMode(PanelMode mode)
129 {
130     ACE_UPDATE_LAYOUT_PROPERTY(SlidingPanelLayoutProperty, PanelMode, mode);
131 }
132 
SetHasDragBar(bool hasDragBar)133 void SlidingPanelModelNG::SetHasDragBar(bool hasDragBar)
134 {
135     ACE_UPDATE_LAYOUT_PROPERTY(SlidingPanelLayoutProperty, HasDragBar, hasDragBar);
136 }
137 
SetCustomHeight(const CalcDimension & customHeight)138 void SlidingPanelModelNG::SetCustomHeight(const CalcDimension& customHeight)
139 {
140     ACE_UPDATE_LAYOUT_PROPERTY(SlidingPanelLayoutProperty, CustomHeight, customHeight);
141 }
142 
SetMiniHeight(const Dimension & miniHeight)143 void SlidingPanelModelNG::SetMiniHeight(const Dimension& miniHeight)
144 {
145     ACE_UPDATE_LAYOUT_PROPERTY(SlidingPanelLayoutProperty, MiniHeight, miniHeight);
146 }
147 
SetHalfHeight(const Dimension & halfHeight)148 void SlidingPanelModelNG::SetHalfHeight(const Dimension& halfHeight)
149 {
150     ACE_UPDATE_LAYOUT_PROPERTY(SlidingPanelLayoutProperty, HalfHeight, halfHeight);
151 }
152 
SetFullHeight(const Dimension & fullHeight)153 void SlidingPanelModelNG::SetFullHeight(const Dimension& fullHeight)
154 {
155     ACE_UPDATE_LAYOUT_PROPERTY(SlidingPanelLayoutProperty, FullHeight, fullHeight);
156 }
157 
SetIsShow(bool isShow)158 void SlidingPanelModelNG::SetIsShow(bool isShow)
159 {
160     ACE_UPDATE_LAYOUT_PROPERTY(SlidingPanelLayoutProperty, IsShow, isShow);
161 }
162 
SetShowCloseIcon(bool showCloseIcon)163 void SlidingPanelModelNG::SetShowCloseIcon(bool showCloseIcon)
164 {
165     ACE_UPDATE_LAYOUT_PROPERTY(SlidingPanelLayoutProperty, ShowCloseIcon, showCloseIcon);
166 }
167 
SetBackgroundMask(const Color & backgroundMask)168 void SlidingPanelModelNG::SetBackgroundMask(const Color& backgroundMask)
169 {
170     ACE_UPDATE_LAYOUT_PROPERTY(SlidingPanelLayoutProperty, BackgroundMask, backgroundMask);
171 }
172 
173 // Set the color of the panel content area
SetBackgroundColor(const Color & backgroundColor)174 void SlidingPanelModelNG::SetBackgroundColor(const Color& backgroundColor)
175 {
176     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
177     CHECK_NULL_VOID(frameNode);
178     auto columnNode = AceType::DynamicCast<FrameNode>(frameNode->GetChildren().front());
179     CHECK_NULL_VOID(columnNode);
180     auto renderContext = columnNode->GetRenderContext();
181     if (renderContext) {
182         ACE_UPDATE_LAYOUT_PROPERTY(SlidingPanelLayoutProperty, BackgroundColor, backgroundColor);
183         renderContext->UpdateBackgroundColor(backgroundColor);
184     }
185 }
186 
SetOnSizeChange(ChangeEvent && changeEvent)187 void SlidingPanelModelNG::SetOnSizeChange(ChangeEvent&& changeEvent)
188 {
189     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
190     CHECK_NULL_VOID(frameNode);
191     auto eventHub = frameNode->GetEventHub<SlidingPanelEventHub>();
192     CHECK_NULL_VOID(eventHub);
193     eventHub->SetOnSizeChange(std::move(changeEvent));
194 }
195 
SetOnHeightChange(HeightChangeEvent && onHeightChange)196 void SlidingPanelModelNG::SetOnHeightChange(HeightChangeEvent&& onHeightChange)
197 {
198     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
199     CHECK_NULL_VOID(frameNode);
200     auto eventHub = frameNode->GetEventHub<SlidingPanelEventHub>();
201     CHECK_NULL_VOID(eventHub);
202     eventHub->SetOnHeightChange(std::move(onHeightChange));
203 }
204 
Pop()205 void SlidingPanelModelNG::Pop()
206 {
207     NG::ViewStackProcessor::GetInstance()->PopContainer();
208 }
209 
SetBorderColor(const Color & borderColor)210 void SlidingPanelModelNG::SetBorderColor(const Color& borderColor)
211 {
212     NG::ViewAbstract::SetBorderColor(borderColor);
213 }
SetBorderWidth(const Dimension & borderWidth)214 void SlidingPanelModelNG::SetBorderWidth(const Dimension& borderWidth)
215 {
216     NG::ViewAbstract::SetBorderWidth(borderWidth);
217 }
SetBorderStyle(const BorderStyle & borderStyle)218 void SlidingPanelModelNG::SetBorderStyle(const BorderStyle& borderStyle)
219 {
220     NG::ViewAbstract::SetBorderStyle(borderStyle);
221 }
222 
SetBorder(const BorderStyle & borderStyle,const Dimension & borderWidth)223 void SlidingPanelModelNG::SetBorder(const BorderStyle& borderStyle, const Dimension& borderWidth) {}
224 
SetModeChangeEvent(ChangeEvent && modeChangeEvent)225 void SlidingPanelModelNG::SetModeChangeEvent(ChangeEvent&& modeChangeEvent)
226 {
227     auto frameNode = ViewStackProcessor::GetInstance()->GetMainFrameNode();
228     CHECK_NULL_VOID(frameNode);
229     auto eventHub = frameNode->GetEventHub<SlidingPanelEventHub>();
230     CHECK_NULL_VOID(eventHub);
231     eventHub->SetModeChangeEvent(std::move(modeChangeEvent));
232 }
233 
SetPanelMode(FrameNode * frameNode,PanelMode mode)234 void SlidingPanelModelNG::SetPanelMode(FrameNode* frameNode, PanelMode mode)
235 {
236     ACE_UPDATE_NODE_LAYOUT_PROPERTY(SlidingPanelLayoutProperty, PanelMode, mode, frameNode);
237 }
238 
SetPanelFullHeight(FrameNode * frameNode,const Dimension & fullHeight)239 void SlidingPanelModelNG::SetPanelFullHeight(FrameNode* frameNode, const Dimension& fullHeight)
240 {
241     ACE_UPDATE_NODE_LAYOUT_PROPERTY(SlidingPanelLayoutProperty, FullHeight, fullHeight, frameNode);
242 }
243 
SetPanelHalfHeight(FrameNode * frameNode,const Dimension & halfHeight)244 void SlidingPanelModelNG::SetPanelHalfHeight(FrameNode* frameNode, const Dimension& halfHeight)
245 {
246     ACE_UPDATE_NODE_LAYOUT_PROPERTY(SlidingPanelLayoutProperty, HalfHeight, halfHeight, frameNode);
247 }
248 
SetPanelMiniHeight(FrameNode * frameNode,const Dimension & miniHeight)249 void SlidingPanelModelNG::SetPanelMiniHeight(FrameNode* frameNode, const Dimension& miniHeight)
250 {
251     ACE_UPDATE_NODE_LAYOUT_PROPERTY(SlidingPanelLayoutProperty, MiniHeight, miniHeight, frameNode);
252 }
253 
SetPanelBackgroundMask(FrameNode * frameNode,const Color & backgroundMask)254 void SlidingPanelModelNG::SetPanelBackgroundMask(FrameNode* frameNode, const Color& backgroundMask)
255 {
256     ACE_UPDATE_NODE_LAYOUT_PROPERTY(SlidingPanelLayoutProperty, BackgroundMask, backgroundMask, frameNode);
257 }
258 
SetPanelType(FrameNode * frameNode,PanelType type)259 void SlidingPanelModelNG::SetPanelType(FrameNode* frameNode, PanelType type)
260 {
261     ACE_UPDATE_NODE_LAYOUT_PROPERTY(SlidingPanelLayoutProperty, PanelType, type, frameNode);
262 }
263 
SetPanelCustomHeight(FrameNode * frameNode,const CalcDimension & customHeight)264 void SlidingPanelModelNG::SetPanelCustomHeight(FrameNode* frameNode, const CalcDimension& customHeight)
265 {
266     ACE_UPDATE_NODE_LAYOUT_PROPERTY(SlidingPanelLayoutProperty, CustomHeight, customHeight, frameNode);
267 }
268 
SetShowCloseIcon(FrameNode * frameNode,bool showCloseIcon)269 void SlidingPanelModelNG::SetShowCloseIcon(FrameNode* frameNode, bool showCloseIcon)
270 {
271     ACE_UPDATE_NODE_LAYOUT_PROPERTY(SlidingPanelLayoutProperty, ShowCloseIcon, showCloseIcon, frameNode);
272 }
273 
SetHasDragBar(FrameNode * frameNode,bool hasDragBar)274 void SlidingPanelModelNG::SetHasDragBar(FrameNode* frameNode, bool hasDragBar)
275 {
276     ACE_UPDATE_NODE_LAYOUT_PROPERTY(SlidingPanelLayoutProperty, HasDragBar, hasDragBar, frameNode);
277 }
278 
SetIsShow(FrameNode * frameNode,bool isShow)279 void SlidingPanelModelNG::SetIsShow(FrameNode* frameNode, bool isShow)
280 {
281     ACE_UPDATE_NODE_LAYOUT_PROPERTY(SlidingPanelLayoutProperty, IsShow, isShow, frameNode);
282 }
283 
ResetPanelHalfHeight(FrameNode * frameNode)284 void SlidingPanelModelNG::ResetPanelHalfHeight(FrameNode* frameNode)
285 {
286     auto layoutProperty = frameNode->GetLayoutProperty<SlidingPanelLayoutProperty>();
287     CHECK_NULL_VOID(layoutProperty);
288     auto geometryNode = frameNode->GetGeometryNode();
289     CHECK_NULL_VOID(geometryNode);
290     auto frameSize = geometryNode->GetFrameSize();
291     if (GreatNotEqual(frameSize.Height(), 0.0)) {
292         auto halfHeight = Dimension((frameSize.Height() - BLANK_MIN_HEIGHT.ConvertToPx()) / HALF_VALUS);
293         ACE_UPDATE_NODE_LAYOUT_PROPERTY(SlidingPanelLayoutProperty, HalfHeight, halfHeight, frameNode);
294     }
295 }
296 
ResetPanelFullHeight(FrameNode * frameNode)297 void SlidingPanelModelNG::ResetPanelFullHeight(FrameNode* frameNode)
298 {
299     auto layoutProperty = frameNode->GetLayoutProperty<SlidingPanelLayoutProperty>();
300     CHECK_NULL_VOID(layoutProperty);
301     auto geometryNode = frameNode->GetGeometryNode();
302     CHECK_NULL_VOID(geometryNode);
303     auto frameSize = geometryNode->GetFrameSize();
304     if (GreatNotEqual(frameSize.Height(), 0.0)) {
305         auto fullHeight = Dimension(frameSize.Height() - BLANK_MIN_HEIGHT.ConvertToPx());
306         ACE_UPDATE_NODE_LAYOUT_PROPERTY(SlidingPanelLayoutProperty, FullHeight, fullHeight, frameNode);
307     }
308 }
309 } // namespace OHOS::Ace::NG
310