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 16 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SELECT_OVERLAY_SELECT_OVERLAY_PATTERN_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SELECT_OVERLAY_SELECT_OVERLAY_PATTERN_H 18 19 #include <utility> 20 21 #include "base/geometry/ng/rect_t.h" 22 #include "base/memory/referenced.h" 23 #include "base/utils/noncopyable.h" 24 #include "base/utils/utils.h" 25 #include "core/components_ng/event/click_event.h" 26 #include "core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.h" 27 #include "core/components_ng/pattern/pattern.h" 28 #include "core/components_ng/pattern/select_overlay/select_overlay_content_modifier.h" 29 #include "core/components_ng/pattern/select_overlay/select_overlay_event_hub.h" 30 #include "core/components_ng/pattern/select_overlay/select_overlay_layout_algorithm.h" 31 #include "core/components_ng/pattern/select_overlay/select_overlay_modifier.h" 32 #include "core/components_ng/pattern/select_overlay/select_overlay_paint_method.h" 33 34 namespace OHOS::Ace::NG { 35 36 class ACE_EXPORT SelectOverlayPattern : public MenuWrapperPattern { 37 DECLARE_ACE_TYPE(SelectOverlayPattern, MenuWrapperPattern); 38 39 public: SelectOverlayPattern(std::shared_ptr<SelectOverlayInfo> info,SelectOverlayMode mode)40 explicit SelectOverlayPattern(std::shared_ptr<SelectOverlayInfo> info, SelectOverlayMode mode) 41 : MenuWrapperPattern(-1), info_(std::move(info)), overlayMode_(mode) 42 { 43 CheckHandleReverse(); 44 } 45 ~SelectOverlayPattern() override = default; 46 IsMeasureBoundary()47 bool IsMeasureBoundary() const override 48 { 49 return true; 50 } 51 IsAtomicNode()52 bool IsAtomicNode() const override 53 { 54 return false; 55 } 56 CreateLayoutAlgorithm()57 RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override 58 { 59 return MakeRefPtr<SelectOverlayLayoutAlgorithm>(info_, defaultMenuEndOffset_, menuWidth_, menuHeight_); 60 } 61 CreateNodePaintMethod()62 RefPtr<NodePaintMethod> CreateNodePaintMethod() override 63 { 64 auto layoutProps = GetLayoutProperty<LayoutProperty>(); 65 CHECK_NULL_RETURN(layoutProps, nullptr); 66 bool isReverse = layoutProps->GetNonAutoLayoutDirection() == TextDirection::RTL; 67 if (!selectOverlayModifier_ && CheckIfNeedMenu()) { 68 selectOverlayModifier_ = 69 AceType::MakeRefPtr<SelectOverlayModifier>(defaultMenuEndOffset_, isReverse, WeakClaim(this)); 70 } 71 if (!selectOverlayContentModifier_ && CheckIfNeedHandle()) { 72 selectOverlayContentModifier_ = AceType::MakeRefPtr<SelectOverlayContentModifier>(WeakClaim(this)); 73 } 74 SetContentModifierBounds(selectOverlayContentModifier_); 75 SetSelectMenuHeight(); 76 77 if (paintMethodCreated_) { 78 return MakeRefPtr<SelectOverlayPaintMethod>(selectOverlayModifier_, selectOverlayContentModifier_, *info_, 79 defaultMenuEndOffset_, selectMenuHeight_, hasExtensionMenu_, hasShowAnimation_, true, isHiddenHandle_, 80 defaultMenuStartOffset_, isReverse, WeakClaim(this)); 81 } else { 82 paintMethodCreated_ = true; 83 return MakeRefPtr<SelectOverlayPaintMethod>(selectOverlayModifier_, selectOverlayContentModifier_, *info_, 84 defaultMenuEndOffset_, selectMenuHeight_, hasExtensionMenu_, hasShowAnimation_, false, isHiddenHandle_, 85 defaultMenuStartOffset_, isReverse, WeakClaim(this)); 86 } 87 } 88 GetSelectOverlayInfo()89 const std::shared_ptr<SelectOverlayInfo>& GetSelectOverlayInfo() const 90 { 91 return info_; 92 } 93 94 void UpdateFirstSelectHandleInfo(const SelectHandleInfo& info); 95 96 void UpdateSecondSelectHandleInfo(const SelectHandleInfo& info); 97 98 void UpdateFirstAndSecondHandleInfo(const SelectHandleInfo& firstInfo, const SelectHandleInfo& secondInfo); 99 100 void UpdateSelectMenuInfo(const SelectMenuInfo& info); 101 102 void UpdateSelectMenuInfo(std::function<void(SelectMenuInfo& menuInfo)> updateAction); 103 104 void UpdateAncestorViewPort(const std::optional<RectF>& ancestorViewPort) const; 105 106 void UpdateShowArea(const RectF& area); 107 108 void SetSelectRegionVisible(bool isSelectRegionVisible); 109 110 void SetHandleReverse(bool reverse); 111 SetSelectInfo(const std::string & selectInfo)112 void SetSelectInfo(const std::string& selectInfo) 113 { 114 info_->selectText = selectInfo; 115 } 116 GetSelectInfo()117 const std::string& GetSelectInfo() const 118 { 119 return info_->selectText; 120 } 121 GetOverlayModifier()122 const RefPtr<SelectOverlayModifier>& GetOverlayModifier() 123 { 124 return selectOverlayModifier_; 125 } 126 GetContentModifier()127 const RefPtr<SelectOverlayContentModifier>& GetContentModifier() 128 { 129 return selectOverlayContentModifier_; 130 } 131 GetDefaultMenuEndOffset()132 const OffsetF& GetDefaultMenuEndOffset() 133 { 134 return defaultMenuEndOffset_; 135 } 136 GetMenuWidth()137 std::optional<float> GetMenuWidth() const 138 { 139 return menuWidth_; 140 } 141 GetMenuHeight()142 std::optional<float> GetMenuHeight() const 143 { 144 return menuHeight_; 145 } 146 GetHandleRegion(bool isFirst)147 const RectF& GetHandleRegion(bool isFirst) const 148 { 149 if (isFirst) { 150 return firstHandleRegion_; 151 } else { 152 return secondHandleRegion_; 153 } 154 } 155 156 void ShowOrHiddenMenu(bool isHidden, bool noAnimation = false); 157 void DisableMenu(bool isDisabled); 158 SetClosedByGlobalTouchEvent(bool closedByGlobalTouch)159 void SetClosedByGlobalTouchEvent(bool closedByGlobalTouch) 160 { 161 closedByGlobalTouchEvent_ = closedByGlobalTouch; 162 } 163 164 bool IsMenuShow(); 165 bool IsSingleHandleMenuShow(); 166 bool IsHandleShow(); 167 bool IsSingleHandle(); 168 SetHasShowAnimation(bool animation)169 void SetHasShowAnimation(bool animation) 170 { 171 hasShowAnimation_ = animation; 172 } 173 IsCustomMenu()174 bool IsCustomMenu() 175 { 176 return info_ && info_->menuInfo.menuBuilder != nullptr; 177 } 178 IsHiddenHandle()179 bool IsHiddenHandle() 180 { 181 return isHiddenHandle_; 182 } 183 184 void StartHiddenHandleTask(bool isDelay = true); 185 virtual void UpdateSelectArea(const RectF& selectArea); 186 void SetIsNewAvoid(bool isNewAvoid); 187 188 bool CheckIfNeedMenu(); 189 bool CheckIfNeedHandle(); 190 GetMode()191 SelectOverlayMode GetMode() 192 { 193 return overlayMode_; 194 } 195 196 void SetGestureEvent(); 197 void InitMouseEvent(); 198 199 static float GetHandleDiameter(); 200 void OnDpiConfigurationUpdate() override; IsDraggingHandle(bool isFirst)201 bool IsDraggingHandle(bool isFirst) 202 { 203 if (isFirst) { 204 return firstHandleDrag_; 205 } else { 206 return secondHandleDrag_; 207 } 208 } 209 void OnColorConfigurationUpdate() override; 210 void OnLanguageConfigurationUpdate() override; 211 CreateEventHub()212 RefPtr<EventHub> CreateEventHub() override 213 { 214 return MakeRefPtr<SelectOverlayEventHub>(); 215 } GetIsMenuShowInSubWindow()216 bool GetIsMenuShowInSubWindow() const 217 { 218 return isMenuShowInSubWindow_; 219 } 220 SetIsMenuShowInSubWindow(bool isMenuShowInSubWindow)221 void SetIsMenuShowInSubWindow(bool isMenuShowInSubWindow) 222 { 223 isMenuShowInSubWindow_ = isMenuShowInSubWindow; 224 } 225 226 void DeleteHotAreas(); 227 228 protected: 229 virtual void CheckHandleReverse(); 230 virtual void UpdateHandleHotZone(); 231 RectF GetHandlePaintRect(const SelectHandleInfo& handleInfo); 232 void AddMenuResponseRegion(std::vector<DimensionRect>& responseRegion); 233 std::shared_ptr<SelectOverlayInfo> info_; 234 RefPtr<ClickEvent> clickEvent_; 235 RefPtr<PanEvent> panEvent_; 236 CancelableCallback<void()> hiddenHandleTask_; 237 bool isHiddenHandle_ = false; 238 RectF firstHandleRegion_; 239 RectF secondHandleRegion_; 240 241 private: 242 bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override; 243 void OnAttachToFrameNode() override; 244 void OnDetachFromFrameNode(FrameNode* frameNode) override; 245 246 void HandleOnClick(GestureEvent& info); 247 void HandleTouchEvent(const TouchEventInfo& info); 248 void HandleTouchDownEvent(const TouchEventInfo& info); 249 void HandleOnTouch(GestureEvent& info); 250 void HandlePanStart(GestureEvent& info); 251 void HandlePanMove(GestureEvent& info); 252 void HandlePanEnd(GestureEvent& info); 253 void HandlePanCancel(); 254 void HandleMouseEvent(const MouseInfo& info); 255 256 bool IsHandlesInSameLine(); 257 bool IsFirstHandleMoveStart(const Offset& touchOffset); 258 void StopHiddenHandleTask(); 259 void HiddenHandle(); 260 void UpdateOffsetOnMove(RectF& region, SelectHandleInfo& handleInfo, const OffsetF& offset, bool isFirst); 261 void SetSelectMenuHeight(); 262 void SetContentModifierBounds(const RefPtr<SelectOverlayContentModifier>& modifier); 263 void SwitchHandleToOverlayMode(bool afterRender); 264 void SetHotAreas(const RefPtr<LayoutWrapper>& layoutWrapper); 265 266 RefPtr<TouchEventImpl> touchEvent_; 267 268 bool firstHandleDrag_ = false; 269 bool secondHandleDrag_ = false; 270 bool isFirstHandleTouchDown_ = false; 271 bool isSecondHandleTouchDown_ = false; 272 // Used to record the original menu display status when the handle is moved. 273 bool orignMenuIsShow_ = false; 274 bool hasExtensionMenu_ = false; 275 bool hasShowAnimation_ = false; 276 277 int32_t greatThanMaxWidthIndex_ = -1; 278 std::optional<float> menuWidth_; 279 std::optional<float> menuHeight_; 280 281 OffsetF defaultMenuStartOffset_; 282 OffsetF defaultMenuEndOffset_; 283 284 float selectMenuHeight_ = 0.0f; 285 286 RefPtr<SelectOverlayModifier> selectOverlayModifier_; 287 288 RefPtr<SelectOverlayContentModifier> selectOverlayContentModifier_; 289 290 bool paintMethodCreated_ = false; 291 292 bool closedByGlobalTouchEvent_ = false; 293 SelectOverlayMode overlayMode_ = SelectOverlayMode::ALL; 294 // Used to identify whether the menu is actually displayed in the subwindow. 295 bool isMenuShowInSubWindow_ = false; 296 297 ACE_DISALLOW_COPY_AND_MOVE(SelectOverlayPattern); 298 }; 299 } // namespace OHOS::Ace::NG 300 301 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_STAGE_PAGE_PATTERN_H 302