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