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_ = AceType::MakeRefPtr<SelectOverlayModifier>(defaultMenuEndOffset_, isReverse); 69 } 70 if (!selectOverlayContentModifier_ && CheckIfNeedHandle()) { 71 selectOverlayContentModifier_ = AceType::MakeRefPtr<SelectOverlayContentModifier>(WeakClaim(this)); 72 } 73 SetContentModifierBounds(selectOverlayContentModifier_); 74 SetSelectMenuHeight(); 75 76 if (paintMethodCreated_) { 77 return MakeRefPtr<SelectOverlayPaintMethod>(selectOverlayModifier_, selectOverlayContentModifier_, *info_, 78 defaultMenuEndOffset_, selectMenuHeight_, hasExtensionMenu_, hasShowAnimation_, true, isHiddenHandle_, 79 defaultMenuStartOffset_, isReverse); 80 } else { 81 paintMethodCreated_ = true; 82 return MakeRefPtr<SelectOverlayPaintMethod>(selectOverlayModifier_, selectOverlayContentModifier_, *info_, 83 defaultMenuEndOffset_, selectMenuHeight_, hasExtensionMenu_, hasShowAnimation_, false, isHiddenHandle_, 84 defaultMenuStartOffset_, isReverse); 85 } 86 } 87 GetSelectOverlayInfo()88 const std::shared_ptr<SelectOverlayInfo>& GetSelectOverlayInfo() const 89 { 90 return info_; 91 } 92 93 void UpdateFirstSelectHandleInfo(const SelectHandleInfo& info); 94 95 void UpdateSecondSelectHandleInfo(const SelectHandleInfo& info); 96 97 void UpdateFirstAndSecondHandleInfo(const SelectHandleInfo& firstInfo, const SelectHandleInfo& secondInfo); 98 99 void UpdateSelectMenuInfo(const SelectMenuInfo& info); 100 101 void UpdateSelectMenuInfo(std::function<void(SelectMenuInfo& menuInfo)> updateAction); 102 103 void UpdateAncestorViewPort(const std::optional<RectF>& ancestorViewPort) const; 104 105 void UpdateShowArea(const RectF& area); 106 107 void SetSelectRegionVisible(bool isSelectRegionVisible); 108 109 void SetHandleReverse(bool reverse); 110 SetSelectInfo(const std::string & selectInfo)111 void SetSelectInfo(const std::string& selectInfo) 112 { 113 info_->selectText = selectInfo; 114 } 115 GetSelectInfo()116 const std::string& GetSelectInfo() const 117 { 118 return info_->selectText; 119 } 120 GetOverlayModifier()121 const RefPtr<SelectOverlayModifier>& GetOverlayModifier() 122 { 123 return selectOverlayModifier_; 124 } 125 GetContentModifier()126 const RefPtr<SelectOverlayContentModifier>& GetContentModifier() 127 { 128 return selectOverlayContentModifier_; 129 } 130 GetDefaultMenuEndOffset()131 const OffsetF& GetDefaultMenuEndOffset() 132 { 133 return defaultMenuEndOffset_; 134 } 135 GetMenuWidth()136 std::optional<float> GetMenuWidth() const 137 { 138 return menuWidth_; 139 } 140 GetMenuHeight()141 std::optional<float> GetMenuHeight() const 142 { 143 return menuHeight_; 144 } 145 GetHandleRegion(bool isFirst)146 const RectF& GetHandleRegion(bool isFirst) const 147 { 148 if (isFirst) { 149 return firstHandleRegion_; 150 } else { 151 return secondHandleRegion_; 152 } 153 } 154 155 void ShowOrHiddenMenu(bool isHidden, bool noAnimation = false); 156 void DisableMenu(bool isDisabled); 157 SetClosedByGlobalTouchEvent(bool closedByGlobalTouch)158 void SetClosedByGlobalTouchEvent(bool closedByGlobalTouch) 159 { 160 closedByGlobalTouchEvent_ = closedByGlobalTouch; 161 } 162 163 bool IsMenuShow(); 164 bool IsSingleHandleMenuShow(); 165 bool IsHandleShow(); 166 bool IsSingleHandle(); 167 SetHasShowAnimation(bool animation)168 void SetHasShowAnimation(bool animation) 169 { 170 hasShowAnimation_ = animation; 171 } 172 IsCustomMenu()173 bool IsCustomMenu() 174 { 175 return info_ && info_->menuInfo.menuBuilder != nullptr; 176 } 177 IsHiddenHandle()178 bool IsHiddenHandle() 179 { 180 return isHiddenHandle_; 181 } 182 183 void StartHiddenHandleTask(bool isDelay = true); 184 virtual void UpdateSelectArea(const RectF& selectArea); 185 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