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