• 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 #include "core/pipeline_ng/pipeline_context.h"
31 #include "core/components_ng/pattern/select/select_model.h"
32 namespace OHOS::Ace::NG {
33 enum class ArrowOfTargetOffset {
34     START,
35     CENTER,
36     END,
37     NONE,
38 };
39 struct BubbleDumpInfo {
40     bool enableArrow = false;
41     bool mask = true;
42     bool avoidKeyboard = false;
43     bool enableHoverMode = false;
44     std::string targetNode;
45     int32_t targetID = -1;
46     OffsetF targetOffset;
47     SizeF targetSize;
48     RectF touchRegion;
49     float top = 0.0f;
50     float bottom = 0.0f;
51     OffsetF userOffset;
52     Dimension targetSpace;
53     std::string originPlacement;
54     std::string finalPlacement = "NONE";
55 };
56 struct PopupCanPlacement {
57     bool bottom = false;
58     bool top = false;
59     bool left = false;
60     bool right = false;
61 };
62 struct PopupMaxAreaInfo {
63     Placement placement = Placement::BOTTOM;
64     OffsetF position;
65     SizeF size;
66     OffsetF arrowPosition;
67 };
68 
69 // BubbleLayoutAlgorithm uses for Popup Node.
70 class ACE_EXPORT BubbleLayoutAlgorithm : public LayoutAlgorithm {
71     DECLARE_ACE_TYPE(BubbleLayoutAlgorithm, LayoutAlgorithm);
72 
73 public:
74     BubbleLayoutAlgorithm() = default;
75     BubbleLayoutAlgorithm(int32_t id, const std::string& tag, const std::optional<OffsetF>& targetOffset = std::nullopt,
76         const std::optional<SizeF>& targetSize = std::nullopt, const std::optional<Offset>& mouseOffset = std::nullopt);
77     ~BubbleLayoutAlgorithm() override = default;
78 
79     void Measure(LayoutWrapper* layoutWrapper) override;
80 
81     void Layout(LayoutWrapper* layoutWrapper) override;
82 
GetTargetSize()83     SizeF GetTargetSize() const
84     {
85         return targetSize_;
86     }
87 
GetTargetOffset()88     OffsetF GetTargetOffset() const
89     {
90         return targetOffsetForPaint_;
91     }
92 
GetChildSize()93     SizeF GetChildSize() const
94     {
95         return childSize_;
96     }
97 
GetChildOffset()98     OffsetF GetChildOffset() const
99     {
100         return childOffsetForPaint_;
101     }
102 
ShowArrow()103     bool ShowArrow() const
104     {
105         return showArrow_;
106     }
107 
GetArrowPosition()108     OffsetF GetArrowPosition() const
109     {
110         return arrowPositionForPaint_;
111     }
112 
GetTouchRegion()113     RectF GetTouchRegion() const
114     {
115         return touchRegion_;
116     }
117 
GetHostWindowRect()118     Rect GetHostWindowRect() const
119     {
120         return hostWindowRect_;
121     }
122 
GetBorder()123     const Border& GetBorder() const
124     {
125         return border_;
126     }
127 
GetArrowPlacement()128     Placement GetArrowPlacement() const
129     {
130         return arrowPlacement_;
131     }
GetArrowOffsetByClips()132     std::vector<float>& GetArrowOffsetByClips()
133     {
134         return arrowOffsetByClips_;
135     }
GetClipPath()136     std::string GetClipPath() const
137     {
138         return clipPath_;
139     }
GetClipFrameNode()140     RefPtr<FrameNode> GetClipFrameNode()
141     {
142         return clipFrameNode_;
143     }
144 
GetArrowOffsetsFromClip()145     const std::vector<std::vector<float>>& GetArrowOffsetsFromClip() const
146     {
147         return arrowOffsetsFromClip_;
148     }
149 
GetArrowWidth()150     const float& GetArrowWidth() const
151     {
152         return realArrowWidth_;
153     }
154 
GetArrowHeight()155     const float& GetArrowHeight() const
156     {
157         return realArrowHeight_;
158     }
159 
160     void UpdateMarginByWidth();
161 
GetDumpInfo()162     BubbleDumpInfo GetDumpInfo() const
163     {
164         return dumpInfo_;
165     }
166 
GetArrowBuildPlacement()167     const Placement& GetArrowBuildPlacement() const
168     {
169         return arrowBuildPlacement_;
170     }
171 
172 protected:
173     OffsetF positionOffset_;
174     SizeF wrapperSize_;
175     // rect is relative to popupWrapper
176     Rect wrapperRect_;
177 
178 private:
179     enum class ErrorPositionType {
180         NORMAL = 0,
181         TOP_LEFT_ERROR,
182         BOTTOM_RIGHT_ERROR,
183     };
184     bool CheckPositionBottom(
185         const OffsetF& position, const SizeF& childSize, size_t step, size_t& i, const OffsetF& arrowPosition);
186     bool CheckPositionTop(
187         const OffsetF& position, const SizeF& childSize, size_t step, size_t& i, const OffsetF& arrowPosition);
188     bool CheckPositionRight(
189         const OffsetF& position, const SizeF& childSize, size_t step, size_t& i, const OffsetF& arrowPosition);
190     bool CheckPositionLeft(
191         const OffsetF& position, const SizeF& childSize, size_t step, size_t& i, const OffsetF& arrowPosition);
192     bool CheckPosition(
193         const OffsetF& position, const SizeF& childSize, size_t step, size_t& i, const OffsetF& arrowPosition);
194     OffsetF GetPositionWithPlacementTop(const SizeF&, const OffsetF&, const OffsetF&, OffsetF&);
195     OffsetF GetPositionWithPlacementTopLeft(const SizeF&, const OffsetF&, const OffsetF&, OffsetF&);
196     OffsetF GetPositionWithPlacementTopRight(const SizeF&, const OffsetF&, const OffsetF&, OffsetF&);
197     OffsetF GetPositionWithPlacementBottom(const SizeF&, const OffsetF&, const OffsetF&, OffsetF&);
198     OffsetF GetPositionWithPlacementBottomLeft(const SizeF&, const OffsetF&, const OffsetF&, OffsetF&);
199     OffsetF GetPositionWithPlacementBottomRight(const SizeF&, const OffsetF&, const OffsetF&, OffsetF&);
200     OffsetF GetPositionWithPlacementLeft(const SizeF&, const OffsetF&, const OffsetF&, OffsetF&);
201     OffsetF GetPositionWithPlacementLeftTop(const SizeF&, const OffsetF&, const OffsetF&, OffsetF&);
202     OffsetF GetPositionWithPlacementLeftBottom(const SizeF&, const OffsetF&, const OffsetF&, OffsetF&);
203     OffsetF GetPositionWithPlacementRight(const SizeF&, const OffsetF&, const OffsetF&, OffsetF&);
204     OffsetF GetPositionWithPlacementRightTop(const SizeF&, const OffsetF&, const OffsetF&, OffsetF&);
205     OffsetF GetPositionWithPlacementRightBottom(const SizeF&, const OffsetF&, const OffsetF&, OffsetF&);
206     OffsetF AddTargetSpace(const OffsetF& position);
207     OffsetF AddOffset(const OffsetF& position);
208     bool CheckPositionInPlacementRect(const Rect& rect, const OffsetF& position, const SizeF& childSize);
209     OffsetF AdjustPosition(const OffsetF& position, float width, float height, float space);
210     OffsetF AdjustPositionNew(const OffsetF& position, float width, float height);
211     OffsetF GetBubblePosition(const OffsetF& position, float xMin, float xMax, float yMin, float yMax);
212     bool CheckIfNeedRemoveArrow(float& xMin, float& xMax, float& yMin, float& yMax);
213     void CheckArrowPosition(OffsetF& position, float width, float height);
214     bool IsUIExtensionWindow();
215     void HandleUIExtensionKeyboard(LayoutWrapper* layoutWrapper, bool showInSubWindow);
216     OffsetF GetAdjustPosition(std::vector<Placement>& currentPlacementStates, size_t step, const SizeF& childSize,
217         const OffsetF& topPosition, const OffsetF& bottomPosition, OffsetF& arrowPosition);
218     void InitTargetSizeAndPosition(bool showInSubWindow, LayoutWrapper* layoutWrapper);
219     void InitCaretTargetSizeAndPosition();
220     void InitProps(const RefPtr<BubbleLayoutProperty>& layoutProp, bool showInSubWindow, LayoutWrapper* layoutWrapper);
221     void InitArrowState(const RefPtr<BubbleLayoutProperty>& layoutProp);
222     OffsetF GetPositionWithPlacementNew(
223         const SizeF& childSize, const OffsetF& topPosition, const OffsetF& bottomPosition, OffsetF& arrowPosition);
224     OffsetF GetChildPositionNew(
225         const SizeF& childSize, const RefPtr<BubbleLayoutProperty>& bubbleProp, const RefPtr<LayoutWrapper> child);
226     OffsetF FitToScreenNew(
227         const OffsetF& position, size_t step, size_t& i, const SizeF& childSize, bool didNeedArrow = false);
228     bool GetIfNeedArrow(const RefPtr<BubbleLayoutProperty>& bubbleProp, const SizeF& childSize);
229     void UpdateChildPosition(OffsetF& childOffset);
230     void UpdateTouchRegion();
231     void InitWrapperRect(LayoutWrapper* layoutWrapper, const RefPtr<BubbleLayoutProperty>& layoutProp);
232     void UpdateScrollHeight(LayoutWrapper* layoutWrapper, bool showInSubWindow);
233     std::string MoveTo(double x, double y);
234     std::string LineTo(double x, double y);
235     std::string ArcTo(double rx, double ry, double rotation, int32_t arc_flag, double x, double y);
236     void UpdateClipOffset(const RefPtr<FrameNode>& frameNode);
237     void UpdateBubbleMaxSize(LayoutWrapper* layoutWrapper, bool showInSubWindow);
238 
239     std::string ClipBubbleWithPath();
240     float GetArrowOffset(const Placement& placement);
241     void InitEdgeSize(Edge& edge);
242     float ModifyBorderRadius(float borderRadius, float halfChildHeight);
243     void GetArrowBuildPlacement(Placement& arrowBuildplacement);
244     std::string BuildTopLinePath(float arrowOffset, float radius, Placement& arrowBuildplacement);
245     std::string BuildRightLinePath(float arrowOffset, float radius, Placement& arrowBuildplacement);
246     std::string BuildBottomLinePath(float arrowOffset, float radius, Placement& arrowBuildplacement);
247     std::string BuildLeftLinePath(float arrowOffset, float radius, Placement& arrowBuildplacement);
248     std::string ReplaceArrowTopLeft(const float arrowOffset, const float childOffset);
249     std::string ReplaceArrowTopRight(const float arrowOffset, const float childOffset);
250     std::string ReplaceArrowRightTop(const float arrowOffset, const float childOffset);
251     std::string ReplaceArrowRightBottom(const float arrowOffset, const float childOffset);
252     std::string ReplaceArrowBottomLeft(const float arrowOffset, const float childOffset);
253     std::string ReplaceArrowBottomRight(const float arrowOffset, const float childOffset);
254     std::string ReplaceArrowLeftTop(const float arrowOffset, const float childOffset);
255     std::string ReplaceArrowLeftBottom(const float arrowOffset, const float childOffset);
256     std::string BuildCornerPath(const Placement& placement, float radius);
257     void UpdateArrowOffset(const std::optional<Dimension>& offset, const Placement& placement);
258     void BubbleAvoidanceRule(RefPtr<LayoutWrapper> child, RefPtr<BubbleLayoutProperty> bubbleProp,
259         RefPtr<FrameNode> bubbleNode, bool showInSubWindow, LayoutWrapper* layoutWrapper);
260     void SetArrowOffsetsFromClip(const int16_t index, const float offsetX, const float offsetY);
261     void SetHotAreas(bool showInSubWindow, bool isBlock, RefPtr<FrameNode> frameNode, int32_t containerId);
262     void SetBubbleRadius();
263     void UpdateHostWindowRect();
264     void HandleKeyboard(LayoutWrapper* layoutWrapper, bool showInSubWindow);
265     void FitAvailableRect(LayoutWrapper* layoutWrapper, bool showInSubWindow);
266     void FitMouseOffset(LayoutWrapper* layoutWrapper);
267 
268     void UpdateTextNodeMaxLines(const RefPtr<LayoutWrapper>& childWrapper, const LayoutConstraintF& layoutConstraint);
269     void MeasureTipsRegion(const RefPtr<LayoutWrapper>& childWrapper, const LayoutConstraintF& childContraint);
270     void MeasureTipsFollowTarget(const RefPtr<LayoutWrapper>& childWrapper, const LayoutConstraintF& childContraint);
271     Placement CalculateTipsDirections(SizeF& newSize);
272 
273     OffsetF GetChildPosition(
274         const SizeF& childSize, const RefPtr<BubbleLayoutProperty>& layoutProp, bool UseArrowOffset);
275     void InitArrowTopAndBottomPosition(OffsetF& topArrowPosition, OffsetF& bottomArrowPosition, OffsetF& topPosition,
276         OffsetF& bottomPosition, const SizeF& childSize);
277     void GetPositionWithPlacement(
278         OffsetF& childPosition, OffsetF& arrowPosition, const SizeF& childSize, Placement placement);
279     void UpdateContentPositionRange(float& xMin, float& xMax, float& yMin, float& yMax);
280     ErrorPositionType GetErrorPositionType(const OffsetF& childOffset, const SizeF& childSize);
281     OffsetF FitToScreen(const OffsetF& fitPosition, const SizeF& childSize);
282     SizeF GetPopupMaxWidthAndHeight(bool showInSubWindow, const RefPtr<FrameNode>& frameNode);
283     void UpdateDumpInfo();
284     OffsetF CoverParent(const SizeF& childSize, Placement originPlacement);
285     OffsetF AvoidOrCoverParent(const SizeF& childSize, const RefPtr<BubbleLayoutProperty>& bubbleProp,
286         const RefPtr<LayoutWrapper> child, Placement originPlacement, OffsetF& arrowOffset);
287     bool AvoidToTargetPlacement(
288         const SizeF& childSize, OffsetF& arrowPosition, OffsetF& resultPosition, SizeF& resultSize, bool canCompress);
289     bool AvoidToTargetBottom(
290         const SizeF& childSize, OffsetF& arrowPosition, OffsetF& resultPosition, SizeF& resultSize, bool canCompress);
291     bool AvoidToTargetTop(
292         const SizeF& childSize, OffsetF& arrowPosition, OffsetF& resultPosition, SizeF& resultSize, bool canCompress);
293     bool AvoidToTargetTopMid(
294         const SizeF& childSize, OffsetF& arrowPosition, OffsetF& resultPosition, SizeF& resultSize, bool canCompress);
295     bool AvoidToTargetRight(
296         const SizeF& childSize, OffsetF& arrowPosition, OffsetF& resultPosition, SizeF& resultSize, bool canCompress);
297     bool AvoidToTargetLeft(
298         const SizeF& childSize, OffsetF& arrowPosition, OffsetF& resultPosition, SizeF& resultSize, bool canCompress);
299     void RecordMaxSpace(const float maxAreaSpace, const OffsetF& position, const float maxWidth, const float maxHeight,
300         const OffsetF& arrowPosition);
301     void BottomAndTopPosition(OffsetF& bottomPosition, OffsetF& topPosition, const SizeF& childSize);
302     Rect GetBottomRect(const Dimension& targetSpace);
303     Rect GetTopRect(const Dimension& targetSpace);
304     Rect GetRightRect(const Dimension& targetSpace);
305     Rect GetLeftRect(const Dimension& targetSpace);
306     OffsetF AvoidToTopOrBottomByWidth(const SizeF& childSize, OffsetF& arrowPosition, SizeF& resultSize);
307     OffsetF AdjustAvoidPosition(const OffsetF& position, float width, float height, OffsetF& arrowPosition);
308 
309     ArrowOfTargetOffset arrowOfTargetOffset_ = ArrowOfTargetOffset::NONE;
310     Dimension arrowOffset_;
311 
312     int32_t targetNodeId_ = -1;
313     std::string targetTag_;
314     bool bCaretMode_ = false;
315     bool useCustom_ = false;
316     bool isTips_ = false;
317     bool followCursor_ = false;
318     bool resetTipsSize_ = false;
319     Placement tipsPlacement_ = Placement::BOTTOM_LEFT;
320 
321     BubbleDumpInfo dumpInfo_;
322     SizeF targetSize_;
323     OffsetF targetOffset_;
324     OffsetF targetOffsetForPaint_;
325     SizeF childSize_;
326     OffsetF childOffset_;
327     // Offset from upper left corner of the screen
328     OffsetF childOffsetForPaint_;
329     OffsetF arrowPosition_;
330     OffsetF arrowPositionForPaint_;
331     SizeF selfSize_;
332     RectF touchRegion_;
333     Rect hostWindowRect_;
334     SizeF buttonRowSize_;
335     OffsetF buttonRowOffset_;
336     // top right bottom left
337     std::vector<float> arrowOffsetByClips_ = { 0.0f, 0.0f, 0.0f, 0.0f };
338     Edge padding_;
339     Edge margin_;
340     Border border_;
341     Placement arrowPlacement_ = Placement::BOTTOM;
342     Placement placement_ = Placement::BOTTOM;
343     Placement arrowBuildPlacement_ = Placement::BOTTOM;
344     Dimension targetSpace_;
345     Dimension borderRadius_;
346     Dimension userSetTargetSpace_;
347     Dimension minHeight_;
348     uint32_t maxColumns_ = 0;
349     bool showArrow_ = false;
350     bool enableArrow_ = false;
351     bool isCaretMode_ = true;
352     bool followTransformOfTarget_ = false;
353     bool enableFoldedArea_ = false;
354     bool needRemoveArrow_ = false;
355     float scaledBubbleSpacing_ = 0.0f;
356     float arrowHeight_ = 0.0f;
357     float realArrowWidth_ = 20.0f;
358     float realArrowHeight_ = 10.0f;
359 
360     float marginStart_ = 0.0f;
361     float marginEnd_ = 0.0f;
362     float marginTop_ = 0.0f;
363     float marginBottom_ = 0.0f;
364     float top_ = 0.0f;
365     float bottom_ = 0.0f;
366     bool avoidKeyboard_ = false;
367     bool bHorizontal_ = false;
368     bool bVertical_ = false;
369     std::unordered_set<Placement> setHorizontal_;
370     std::unordered_set<Placement> setVertical_;
371     bool hasPlacement_ = false;
372     bool hasWidth_ = false;
373 
374     std::optional<AvoidanceMode> avoidTarget_ = std::nullopt;
375     PopupCanPlacement canPlacement_;
376     float maxAreaSpace_ = 0.0f;
377     OffsetF checkArrowPosition_; // transfer arrowPosition to CheckPosition
378     PopupMaxAreaInfo maxAreaInfo_;
379     float targetSecurity_ = 0.0f;
380     using PlacementFunc = OffsetF (BubbleLayoutAlgorithm::*)(const SizeF&, const OffsetF&, const OffsetF&, OffsetF&);
381     std::map<Placement, PlacementFunc> placementFuncMap_;
382     std::string clipPath_;
383     RefPtr<FrameNode> clipFrameNode_;
384     SizeF layoutChildSize_;
385     SizeF measureChildSizeLast_;
386     SizeF measureChildSizeAfter_;
387     SizeF measureChildSizeBefore_;
388     ACE_DISALLOW_COPY_AND_MOVE(BubbleLayoutAlgorithm);
389     std::vector<std::vector<float>> arrowOffsetsFromClip_
390         = { {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f}, {0.0f, 0.0f} };
391     bool isGreatWrapperWidth_ = false;
392     double foldCreaseTop_ = 0.0;
393     double foldCreaseBottom_ = 0.0;
394     bool isHalfFoldHover_ = false;
395     bool doubleBorderEnable_ = false;
396     bool expandDisplay_ = false;
397 };
398 } // namespace OHOS::Ace::NG
399 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_BUBBLE_BUBBLE_LAYOUT_ALGORITHM_H
400