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