1 /*
2  * Copyright (c) 2022 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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_BUBBLE_BUBBLE_LAYOUT_ALGORITHM_H
16 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_BUBBLE_BUBBLE_LAYOUT_ALGORITHM_H
17 
18 #include <optional>
19 #include <string>
20 
21 #include "base/geometry/ng/offset_t.h"
22 #include "base/geometry/ng/size_t.h"
23 #include "core/components/common/properties/border.h"
24 #include "core/components/common/properties/edge.h"
25 #include "core/components/common/properties/placement.h"
26 #include "core/components_ng/layout/layout_algorithm.h"
27 #include "core/components_ng/pattern/bubble/bubble_layout_property.h"
28 namespace OHOS::Ace::NG {
29 enum class ArrowOfTargetOffset {
30     START,
31     CENTER,
32     END,
33     NONE,
34 };
35 // BubbleLayoutAlgorithm uses for Popup Node.
36 class ACE_EXPORT BubbleLayoutAlgorithm : public LayoutAlgorithm {
37     DECLARE_ACE_TYPE(BubbleLayoutAlgorithm, LayoutAlgorithm);
38 
39 public:
40     BubbleLayoutAlgorithm() = default;
41     BubbleLayoutAlgorithm(int32_t id, const std::string& tag, const std::optional<OffsetF>& targetOffset = std::nullopt,
42         const std::optional<SizeF>& targetSize = std::nullopt);
43     ~BubbleLayoutAlgorithm() override = default;
44 
45     void Measure(LayoutWrapper* layoutWrapper) override;
46 
47     void Layout(LayoutWrapper* layoutWrapper) override;
48 
GetTargetSize()49     SizeF GetTargetSize() const
50     {
51         return targetSize_;
52     }
53 
GetTargetOffset()54     OffsetF GetTargetOffset() const
55     {
56         return targetOffsetForPaint_;
57     }
58 
GetChildSize()59     SizeF GetChildSize() const
60     {
61         return childSize_;
62     }
63 
GetChildOffset()64     OffsetF GetChildOffset() const
65     {
66         return childOffsetForPaint_;
67     }
68 
ShowArrow()69     bool ShowArrow() const
70     {
71         return showArrow_;
72     }
73 
GetArrowPosition()74     OffsetF GetArrowPosition() const
75     {
76         return arrowPositionForPaint_;
77     }
78 
GetTouchRegion()79     RectF GetTouchRegion() const
80     {
81         return touchRegion_;
82     }
83 
GetHostWindowRect()84     Rect GetHostWindowRect() const
85     {
86         return hostWindowRect_;
87     }
88 
GetBorder()89     const Border& GetBorder() const
90     {
91         return border_;
92     }
93 
GetArrowPlacement()94     Placement GetArrowPlacement() const
95     {
96         return arrowPlacement_;
97     }
98 
GetArrowOffsetByClips()99     std::vector<float>& GetArrowOffsetByClips()
100     {
101         return arrowOffsetByClips_;
102     }
103 
GetClipPath()104     std::string GetClipPath() const
105     {
106         return clipPath_;
107     }
GetClipFrameNode()108     RefPtr<FrameNode> GetClipFrameNode()
109     {
110         return clipFrameNode_;
111     }
112 
GetArrowOffsetsFromClip()113     const std::vector<std::vector<float>>& GetArrowOffsetsFromClip() const
114     {
115         return arrowOffsetsFromClip_;
116     }
117 
GetArrowWidth()118     const float& GetArrowWidth() const
119     {
120         return realArrowWidth_;
121     }
122 
GetArrowHeight()123     const float& GetArrowHeight() const
124     {
125         return realArrowHeight_;
126     }
127 
128     void UpdateMarginByWidth();
129 
130 protected:
131     OffsetF positionOffset_;
132     SizeF wrapperSize_;
133 
134 private:
135     enum class ErrorPositionType {
136         NORMAL = 0,
137         TOP_LEFT_ERROR,
138         BOTTOM_RIGHT_ERROR,
139     };
140     bool CheckPosition(const OffsetF& position, const SizeF& childSize, size_t step, size_t& i);
141     OffsetF GetPositionWithPlacementTop(const SizeF&, const OffsetF&, const OffsetF&, OffsetF&);
142     OffsetF GetPositionWithPlacementTopLeft(const SizeF&, const OffsetF&, const OffsetF&, OffsetF&);
143     OffsetF GetPositionWithPlacementTopRight(const SizeF&, const OffsetF&, const OffsetF&, OffsetF&);
144     OffsetF GetPositionWithPlacementBottom(const SizeF&, const OffsetF&, const OffsetF&, OffsetF&);
145     OffsetF GetPositionWithPlacementBottomLeft(const SizeF&, const OffsetF&, const OffsetF&, OffsetF&);
146     OffsetF GetPositionWithPlacementBottomRight(const SizeF&, const OffsetF&, const OffsetF&, OffsetF&);
147     OffsetF GetPositionWithPlacementLeft(const SizeF&, const OffsetF&, const OffsetF&, OffsetF&);
148     OffsetF GetPositionWithPlacementLeftTop(const SizeF&, const OffsetF&, const OffsetF&, OffsetF&);
149     OffsetF GetPositionWithPlacementLeftBottom(const SizeF&, const OffsetF&, const OffsetF&, OffsetF&);
150     OffsetF GetPositionWithPlacementRight(const SizeF&, const OffsetF&, const OffsetF&, OffsetF&);
151     OffsetF GetPositionWithPlacementRightTop(const SizeF&, const OffsetF&, const OffsetF&, OffsetF&);
152     OffsetF GetPositionWithPlacementRightBottom(const SizeF&, const OffsetF&, const OffsetF&, OffsetF&);
153     OffsetF AddTargetSpace(const OffsetF& position);
154     OffsetF AddOffset(const OffsetF& position);
155     bool CheckPositionInPlacementRect(const Rect& rect, const OffsetF& position, const SizeF& childSize);
156     OffsetF AdjustPosition(const OffsetF& position, float width, float height, float space);
157     OffsetF GetAdjustPosition(std::vector<Placement>& currentPlacementStates, size_t step, const SizeF& childSize,
158         const OffsetF& topPosition, const OffsetF& bottomPosition, OffsetF& arrowPosition);
159     void InitTargetSizeAndPosition(bool showInSubWindow);
160     void InitCaretTargetSizeAndPosition();
161     void InitProps(const RefPtr<BubbleLayoutProperty>& layoutProp, bool showInSubWindow);
162     void InitArrowState(const RefPtr<BubbleLayoutProperty>& layoutProp);
163     OffsetF GetPositionWithPlacementNew(
164         const SizeF& childSize, const OffsetF& topPosition, const OffsetF& bottomPosition, OffsetF& arrowPosition);
165     OffsetF GetChildPositionNew(const SizeF& childSize, const RefPtr<BubbleLayoutProperty>& bubbleProp);
166     OffsetF FitToScreenNew(
167         const OffsetF& position, size_t step, size_t& i, const SizeF& childSize, bool didNeedArrow = false);
168     bool GetIfNeedArrow(const RefPtr<BubbleLayoutProperty>& bubbleProp, const SizeF& childSize);
169     void UpdateChildPosition(OffsetF& childOffset);
170     void UpdateTouchRegion();
171 
172     std::string MoveTo(double x, double y);
173     std::string LineTo(double x, double y);
174     std::string ArcTo(double rx, double ry, double rotation, int32_t arc_flag, double x, double y);
175     void UpdateClipOffset(const RefPtr<FrameNode>& frameNode);
176 
177     std::string ClipBubbleWithPath();
178     float GetArrowOffset(const Placement& placement);
179     void InitEdgeSize(Edge& edge);
180     float ModifyBorderRadius(float borderRadius, float halfChildHeight);
181     void GetArrowBuildPlacement(Placement& arrowBuildplacement);
182     std::string BuildTopLinePath(float arrowOffset, float radius, Placement& arrowBuildplacement);
183     std::string BuildRightLinePath(float arrowOffset, float radius, Placement& arrowBuildplacement);
184     std::string BuildBottomLinePath(float arrowOffset, float radius, Placement& arrowBuildplacement);
185     std::string BuildLeftLinePath(float arrowOffset, float radius, Placement& arrowBuildplacement);
186     std::string ReplaceArrowTopLeft(const float arrowOffset, const float childOffset);
187     std::string ReplaceArrowTopRight(const float arrowOffset, const float childOffset);
188     std::string ReplaceArrowRightTop(const float arrowOffset, const float childOffset);
189     std::string ReplaceArrowRightBottom(const float arrowOffset, const float childOffset);
190     std::string ReplaceArrowBottomLeft(const float arrowOffset, const float childOffset);
191     std::string ReplaceArrowBottomRight(const float arrowOffset, const float childOffset);
192     std::string ReplaceArrowLeftTop(const float arrowOffset, const float childOffset);
193     std::string ReplaceArrowLeftBottom(const float arrowOffset, const float childOffset);
194     std::string BuildCornerPath(const Placement& placement, float radius);
195     void UpdateArrowOffset(const std::optional<Dimension>& offset, const Placement& placement);
196     void BubbleAvoidanceRule(RefPtr<LayoutWrapper> child, RefPtr<BubbleLayoutProperty> bubbleProp,
197         RefPtr<FrameNode> bubbleNode, bool showInSubWindow);
198     void SetArrowOffsetsFromClip(const int16_t index, const float offsetX, const float offsetY);
199     void SetHotAreas(bool showInSubWindow, bool isBlock, RefPtr<FrameNode> frameNode, int32_t containerId);
200     void SetBubbleRadius();
201     void UpdateHostWindowRect();
202 
203     OffsetF GetChildPosition(
204         const SizeF& childSize, const RefPtr<BubbleLayoutProperty>& layoutProp, bool UseArrowOffset);
205     void InitArrowTopAndBottomPosition(OffsetF& topArrowPosition, OffsetF& bottomArrowPosition, OffsetF& topPosition,
206         OffsetF& bottomPosition, const SizeF& childSize);
207     void GetPositionWithPlacement(
208         OffsetF& childPosition, OffsetF& arrowPosition, const SizeF& childSize, Placement placement);
209     ErrorPositionType GetErrorPositionType(const OffsetF& childOffset, const SizeF& childSize);
210     OffsetF FitToScreen(const OffsetF& fitPosition, const SizeF& childSize);
211     SizeF GetPopupMaxWidthAndHeight(bool showInSubWindow, const float& width);
212     ArrowOfTargetOffset arrowOfTargetOffset_ = ArrowOfTargetOffset::NONE;
213     Dimension arrowOffset_;
214 
215     int32_t targetNodeId_ = -1;
216     std::string targetTag_;
217     bool bCaretMode_ = false;
218     bool useCustom_ = false;
219 
220     SizeF targetSize_;
221     OffsetF targetOffset_;
222     OffsetF targetOffsetForPaint_;
223     SizeF childSize_;
224     OffsetF childOffset_;
225     // Offset from upper left corner of the screen
226     OffsetF childOffsetForPaint_;
227     OffsetF arrowPosition_;
228     OffsetF arrowPositionForPaint_;
229     // top right bottom left
230     std::vector<float> arrowOffsetByClips_ = { 0.0f, 0.0f, 0.0f, 0.0f };
231     SizeF selfSize_;
232     RectF touchRegion_;
233     Rect hostWindowRect_;
234     SizeF buttonRowSize_;
235     OffsetF buttonRowOffset_;
236 
237     Edge padding_;
238     Edge margin_;
239     Border border_;
240     Placement arrowPlacement_ = Placement::BOTTOM;
241     Placement placement_ = Placement::BOTTOM;
242     Dimension targetSpace_;
243     Dimension borderRadius_;
244     Dimension userSetTargetSpace_;
245     bool showArrow_ = false;
246     bool enableArrow_ = false;
247     bool isCaretMode_ = true;
248     bool followTransformOfTarget_ = false;
249     float scaledBubbleSpacing_ = 0.0f;
250     float arrowHeight_ = 0.0f;
251     float realArrowWidth_ = 20.0f;
252     float realArrowHeight_ = 10.0f;
253 
254     float marginStart_ = 0.0f;
255     float marginEnd_ = 0.0f;
256     float marginTop_ = 0.0f;
257     float marginBottom_ = 0.0f;
258     float top_ = 0.0f;
259     float bottom_ = 0.0f;
260     bool bHorizontal_ = false;
261     bool bVertical_ = false;
262     std::unordered_set<Placement> setHorizontal_;
263     std::unordered_set<Placement> setVertical_;
264     float targetSecurity_ = 0.0f;
265     using PlacementFunc = OffsetF (BubbleLayoutAlgorithm::*)(const SizeF&, const OffsetF&, const OffsetF&, OffsetF&);
266     std::map<Placement, PlacementFunc> placementFuncMap_;
267     std::string clipPath_;
268     RefPtr<FrameNode> clipFrameNode_;
269     SizeF layoutChildSize_;
270     SizeF measureChildSizeLast_;
271     SizeF measureChildSizeAfter_;
272     SizeF measureChildSizeBefore_;
273     ACE_DISALLOW_COPY_AND_MOVE(BubbleLayoutAlgorithm);
274     std::vector<std::vector<float>> arrowOffsetsFromClip_
275         = { {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f} };
276     bool isGreatWrapperWidth_ = false;
277 };
278 } // namespace OHOS::Ace::NG
279 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_BUBBLE_BUBBLE_LAYOUT_ALGORITHM_H
280