1 /* 2 * Copyright (c) 2022-2023 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 16 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_MENU_MENU_LAYOUT_ALGORITHM_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_MENU_MENU_LAYOUT_ALGORITHM_H 18 19 #include <list> 20 21 #include "base/geometry/ng/offset_t.h" 22 #include "base/memory/referenced.h" 23 #include "core/components/common/properties/placement.h" 24 #include "core/components_ng/layout/box_layout_algorithm.h" 25 #include "core/components_ng/pattern/menu/menu_layout_property.h" 26 #include "core/components_ng/pattern/menu/menu_paint_property.h" 27 28 namespace OHOS::Ace::NG { 29 class MenuLayoutProperty; 30 class MenuPattern; 31 class MenuLayoutAlgorithm : public BoxLayoutAlgorithm { 32 DECLARE_ACE_TYPE(MenuLayoutAlgorithm, BoxLayoutAlgorithm) 33 public: 34 MenuLayoutAlgorithm(int32_t id, const std::string& tag); 35 MenuLayoutAlgorithm() = default; 36 ~MenuLayoutAlgorithm() override; 37 38 // override measureSelf and measureChildren. 39 void Measure(LayoutWrapper* layoutWrapper) override; 40 41 void Layout(LayoutWrapper* layoutWrapper) override; 42 GetPlacement()43 Placement GetPlacement() const 44 { 45 return placement_; 46 } 47 48 bool hierarchicalParameters_ = false; 49 void InitHierarchicalParameters(bool isShowInSubWindow); 50 51 protected: 52 float VerticalLayout(const SizeF& size, float clickPosition, bool IsContextMenu = false); 53 float HorizontalLayout(const SizeF& size, float clickPosition, bool IsSelectMenu = false); 54 55 RefPtr<MenuPaintProperty> GetPaintProperty(const LayoutWrapper* layoutWrapper); 56 OffsetF GetMenuWrapperOffset(const LayoutWrapper* layoutWrapper); 57 58 // position input is relative to main window left top point, 59 // menu show position is relative to menuWrapper. 60 OffsetF position_; 61 OffsetF positionOffset_; 62 SizeF wrapperSize_; 63 // rect is relative to menuWrapper 64 Rect wrapperRect_; 65 66 private: 67 enum class ErrorPositionType { 68 NORMAL = 0, 69 TOP_LEFT_ERROR, 70 BOTTOM_RIGHT_ERROR, 71 }; 72 struct PreviewMenuParam { 73 SizeF windowGlobalSizeF; 74 float windowsOffsetX = 0.0f; 75 float windowsOffsetY = 0.0f; 76 float top = 0.0f; 77 float bottom = 0.0f; 78 float topSecurity = 0.0f; 79 float bottomSecurity = 0.0f; 80 float previewMenuGap = 0.0f; 81 float menuItemTotalHeight = 0.0f; 82 }; 83 84 void Initialize(LayoutWrapper* layoutWrapper); 85 void InitializePadding(LayoutWrapper* layoutWrapper); 86 void InitializePaddingAPI11(LayoutWrapper* layoutWrapper); 87 void InitWrapperRect(const RefPtr<MenuLayoutProperty>& props, const RefPtr<MenuPattern>& menuPattern); 88 void InitSpace(const RefPtr<MenuLayoutProperty>& props, const RefPtr<MenuPattern>& menuPattern); 89 void ModifyPositionToWrapper(LayoutWrapper* layoutWrapper, OffsetF& position); 90 LayoutConstraintF CreateChildConstraint(LayoutWrapper* layoutWrapper); 91 void UpdateConstraintWidth(LayoutWrapper* layoutWrapper, LayoutConstraintF& constraint); 92 void UpdateConstraintHeight(LayoutWrapper* layoutWrapper, LayoutConstraintF& constraint); 93 void UpdateConstraintBaseOnOptions(LayoutWrapper* layoutWrapper, LayoutConstraintF& constraint); 94 void UpdateOptionConstraint(std::list<RefPtr<LayoutWrapper>>& options, float width); 95 void AdjustSelectOverlayMenuPosition(OffsetF& menuPosition, const RefPtr<GeometryNode>& geometryNode); 96 97 void ComputeMenuPositionByAlignType(const RefPtr<MenuLayoutProperty>& menuProp, const SizeF& menuSize); 98 OffsetF ComputeMenuPositionByOffset( 99 const RefPtr<MenuLayoutProperty>& menuProp, const RefPtr<GeometryNode>& geometryNode); 100 OffsetF MenuLayoutAvoidAlgorithm(const RefPtr<MenuLayoutProperty>& menuProp, const RefPtr<MenuPattern>& menuPattern, 101 const SizeF& size, bool didNeedArrow = false); 102 void SetMenuPlacementForAnimation(LayoutWrapper* layoutWrapper); 103 104 void LayoutArrow(const LayoutWrapper* layoutWrapper); 105 OffsetF GetArrowPositionWithPlacement(const SizeF& menuSize); 106 bool GetIfNeedArrow(const LayoutWrapper* layoutWrapper, const SizeF& menuSize); 107 void UpdateArrowOffsetWithMenuLimit(const SizeF& menuSize); 108 void UpdatePropArrowOffset(); 109 void LimitContainerModalMenuRect(double& rectWidth, double& rectHeight); 110 111 // get option LayoutWrapper for measure get max width 112 std::list<RefPtr<LayoutWrapper>> GetOptionsLayoutWrappper(LayoutWrapper* layoutWrapper); 113 114 OffsetF GetPositionWithPlacement(const SizeF& childSize, const OffsetF& topPosition, const OffsetF& bottomPosition); 115 void InitTargetSizeAndPosition(const LayoutWrapper* layoutWrapper, bool isContextMenu, 116 const RefPtr<MenuPattern>& menuPattern); 117 OffsetF GetChildPosition(const SizeF& childSize, bool didNeedArrow = false); 118 OffsetF FitToScreen(const OffsetF& position, const SizeF& childSize, bool didNeedArrow = false); 119 bool CheckPosition(const OffsetF& position, const SizeF& childSize); 120 121 OffsetF GetPositionWithPlacementTop(const SizeF&, const OffsetF&, const OffsetF&); 122 OffsetF GetPositionWithPlacementTopLeft(const SizeF&, const OffsetF&, const OffsetF&); 123 OffsetF GetPositionWithPlacementTopRight(const SizeF&, const OffsetF&, const OffsetF&); 124 OffsetF GetPositionWithPlacementBottom(const SizeF&, const OffsetF&, const OffsetF&); 125 OffsetF GetPositionWithPlacementBottomLeft(const SizeF&, const OffsetF&, const OffsetF&); 126 OffsetF GetPositionWithPlacementBottomRight(const SizeF&, const OffsetF&, const OffsetF&); 127 OffsetF GetPositionWithPlacementLeft(const SizeF&, const OffsetF&, const OffsetF&); 128 OffsetF GetPositionWithPlacementLeftTop(const SizeF&, const OffsetF&, const OffsetF&); 129 OffsetF GetPositionWithPlacementLeftBottom(const SizeF&, const OffsetF&, const OffsetF&); 130 OffsetF GetPositionWithPlacementRight(const SizeF&, const OffsetF&, const OffsetF&); 131 OffsetF GetPositionWithPlacementRightTop(const SizeF&, const OffsetF&, const OffsetF&); 132 OffsetF GetPositionWithPlacementRightBottom(const SizeF&, const OffsetF&, const OffsetF&); 133 OffsetF AddTargetSpace(const OffsetF& position); 134 OffsetF AddOffset(const OffsetF& position); 135 bool CheckPositionInPlacementRect(const Rect& rect, const OffsetF& position, const SizeF& childSize); 136 OffsetF AdjustPosition(const OffsetF& position, float width, float height, float space); 137 OffsetF GetAdjustPosition(std::vector<Placement>& currentPlacementStates, size_t step, const SizeF& childSize, 138 const OffsetF& topPosition, const OffsetF& bottomPosition); 139 140 RefPtr<PipelineContext> GetCurrentPipelineContext(); 141 142 void LayoutPreviewMenu(LayoutWrapper* layoutWrapper); 143 void ModifyPreviewMenuPlacement(LayoutWrapper* layoutWrapper); 144 void ModifyNormalPreviewMenuPlacement(LayoutWrapper* layoutWrapper); 145 void ModifyNormalPreviewMenuPortraitPlacement(LayoutWrapper* layoutWrapper); 146 SizeF GetPreviewNodeAndMenuNodeTotalSize(const RefPtr<FrameNode>& frameNode, 147 RefPtr<LayoutWrapper>& previewLayoutWrapper, RefPtr<LayoutWrapper>& menuLayoutWrapper); 148 149 void LayoutNormalPreviewMenu(LayoutWrapper* layoutWrapper); 150 void LayoutNormalTopPreviewBottomMenu(const RefPtr<GeometryNode>& previewGeometryNode, 151 const RefPtr<GeometryNode>& menuGeometryNode, SizeF& totalSize, float menuItemTotalHeight); 152 void LayoutNormalTopPreviewBottomMenuLessThan(const RefPtr<GeometryNode>& previewGeometryNode, 153 const RefPtr<GeometryNode>& menuGeometryNode, const PreviewMenuParam& param, SizeF& totalSize); 154 void LayoutNormalTopPreviewBottomMenuGreateThan(const RefPtr<GeometryNode>& previewGeometryNode, 155 const RefPtr<GeometryNode>& menuGeometryNode, const PreviewMenuParam& param, SizeF& totalSize); 156 void LayoutNormalBottomPreviewTopMenu(const RefPtr<GeometryNode>& previewGeometryNode, 157 const RefPtr<GeometryNode>& menuGeometryNode, SizeF& totalSize, float menuItemTotalHeight); 158 void LayoutNormalBottomPreviewTopMenuLessThan(const RefPtr<GeometryNode>& previewGeometryNode, 159 const RefPtr<GeometryNode>& menuGeometryNode, const PreviewMenuParam& param, SizeF& totalSize); 160 void LayoutNormalBottomPreviewTopMenuGreateThan(const RefPtr<GeometryNode>& previewGeometryNode, 161 const RefPtr<GeometryNode>& menuGeometryNode, const PreviewMenuParam& param, SizeF& totalSize); 162 163 void LayoutOtherDevicePreviewMenu(LayoutWrapper* layoutWrapper); 164 void LayoutOtherDeviceLeftPreviewRightMenu(const RefPtr<GeometryNode>& previewGeometryNode, 165 const RefPtr<GeometryNode>& menuGeometryNode, SizeF& totalSize, float menuItemTotalHeight); 166 void LayoutOtherDeviceLeftPreviewRightMenuLessThan(const RefPtr<GeometryNode>& previewGeometryNode, 167 const RefPtr<GeometryNode>& menuGeometryNode, const PreviewMenuParam& param, SizeF& totalSize); 168 void LayoutOtherDeviceLeftPreviewRightMenuGreateThan(const RefPtr<GeometryNode>& previewGeometryNode, 169 const RefPtr<GeometryNode>& menuGeometryNode, const PreviewMenuParam& param, SizeF& totalSize); 170 void UpdateScrollAndColumnLayoutConstraint( 171 const RefPtr<LayoutWrapper>& previewLayoutWrapper, const RefPtr<LayoutWrapper>& menuLayoutWrapper); 172 float GetMenuItemTotalHeight(const RefPtr<LayoutWrapper>& menuLayoutWrapper); 173 OffsetF FixMenuOriginOffset(float beforeAnimationScale, float afterAnimationScale); 174 175 OffsetF targetOffset_; 176 SizeF targetSize_; 177 Placement placement_ = Placement::BOTTOM_LEFT; 178 int32_t targetNodeId_ = -1; 179 std::string targetTag_; 180 float targetSecurity_ = TARGET_SECURITY.ConvertToPx(); 181 182 // current page offset relative to window. 183 float topSpace_ = 0.0f; 184 float bottomSpace_ = 0.0f; 185 float leftSpace_ = 0.0f; 186 float rightSpace_ = 0.0f; 187 188 // arrow 189 float menuRadius_ = 0.0f; 190 float targetSpace_ = 0.0f; 191 float arrowMinLimit_ = 0.0f; 192 float arrowOffset_ = 0.0f; 193 float arrowWidth_ = 0.0f; 194 bool arrowInMenu_ = false; 195 bool propNeedArrow_ = false; 196 OffsetF arrowPosition_; 197 Dimension propArrowOffset_; 198 std::unordered_set<Placement> setHorizontal_; 199 std::unordered_set<Placement> setVertical_; 200 Placement arrowPlacement_ = Placement::NONE; 201 202 float margin_ = 0.0f; 203 float paddingStart_ = 0.0f; 204 float paddingEnd_ = 0.0f; 205 float paddingTop_ = 0.0f; 206 float paddingBottom_ = 0.0f; 207 float optionPadding_ = 0.0f; 208 OffsetF targetCenterOffset_; 209 OffsetF previewOriginOffset_; 210 OffsetF previewOffset_; 211 SizeF previewSize_; 212 213 // previewSacle_ must be greater than 0 214 float previewScale_ = 1.0f; 215 216 using PlacementFunc = OffsetF (MenuLayoutAlgorithm::*)(const SizeF&, const OffsetF&, const OffsetF&); 217 std::map<Placement, PlacementFunc> placementFuncMap_; 218 219 ACE_DISALLOW_COPY_AND_MOVE(MenuLayoutAlgorithm); 220 }; 221 } // namespace OHOS::Ace::NG 222 223 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_MENU_MENU_LAYOUT_ALGORITHM_H 224