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 UpdateShowArea(const RectF& area); 104 105 void SetSelectRegionVisible(bool isSelectRegionVisible); 106 107 void SetHandleReverse(bool reverse); 108 SetSelectInfo(const std::string & selectInfo)109 void SetSelectInfo(const std::string& selectInfo) 110 { 111 info_->selectText = selectInfo; 112 } 113 GetSelectInfo()114 const std::string& GetSelectInfo() const 115 { 116 return info_->selectText; 117 } 118 GetOverlayModifier()119 const RefPtr<SelectOverlayModifier>& GetOverlayModifier() 120 { 121 return selectOverlayModifier_; 122 } 123 GetContentModifier()124 const RefPtr<SelectOverlayContentModifier>& GetContentModifier() 125 { 126 return selectOverlayContentModifier_; 127 } 128 GetDefaultMenuEndOffset()129 const OffsetF& GetDefaultMenuEndOffset() 130 { 131 return defaultMenuEndOffset_; 132 } 133 GetMenuWidth()134 std::optional<float> GetMenuWidth() const 135 { 136 return menuWidth_; 137 } 138 GetMenuHeight()139 std::optional<float> GetMenuHeight() const 140 { 141 return menuHeight_; 142 } 143 GetHandleRegion(bool isFirst)144 const RectF& GetHandleRegion(bool isFirst) const 145 { 146 if (isFirst) { 147 return firstHandleRegion_; 148 } else { 149 return secondHandleRegion_; 150 } 151 } 152 153 void ShowOrHiddenMenu(bool isHidden, bool noAnimation = false); 154 void DisableMenu(bool isDisabled); 155 SetClosedByGlobalTouchEvent(bool closedByGlobalTouch)156 void SetClosedByGlobalTouchEvent(bool closedByGlobalTouch) 157 { 158 closedByGlobalTouchEvent_ = closedByGlobalTouch; 159 } 160 161 bool IsMenuShow(); 162 bool IsSingleHandleMenuShow(); 163 bool IsHandleShow(); 164 bool IsSingleHandle(); 165 SetHasShowAnimation(bool animation)166 void SetHasShowAnimation(bool animation) 167 { 168 hasShowAnimation_ = animation; 169 } 170 IsCustomMenu()171 bool IsCustomMenu() 172 { 173 return info_ && info_->menuInfo.menuBuilder != nullptr; 174 } 175 IsHiddenHandle()176 bool IsHiddenHandle() 177 { 178 return isHiddenHandle_; 179 } 180 181 void StartHiddenHandleTask(bool isDelay = true); 182 virtual void UpdateSelectArea(const RectF& selectArea); 183 void SetIsNewAvoid(bool isNewAvoid); 184 185 bool CheckIfNeedMenu(); 186 bool CheckIfNeedHandle(); 187 GetMode()188 SelectOverlayMode GetMode() 189 { 190 return overlayMode_; 191 } 192 193 void SetGestureEvent(); 194 void InitMouseEvent(); 195 196 static float GetHandleDiameter(); 197 void OnDpiConfigurationUpdate() override; IsDraggingHandle(bool isFirst)198 bool IsDraggingHandle(bool isFirst) 199 { 200 if (isFirst) { 201 return firstHandleDrag_; 202 } else { 203 return secondHandleDrag_; 204 } 205 } 206 CreateEventHub()207 RefPtr<EventHub> CreateEventHub() override 208 { 209 return MakeRefPtr<SelectOverlayEventHub>(); 210 } 211 212 protected: 213 virtual void CheckHandleReverse(); 214 virtual void UpdateHandleHotZone(); 215 RectF GetHandlePaintRect(const SelectHandleInfo& handleInfo); 216 void AddMenuResponseRegion(std::vector<DimensionRect>& responseRegion); 217 std::shared_ptr<SelectOverlayInfo> info_; 218 RefPtr<ClickEvent> clickEvent_; 219 RefPtr<PanEvent> panEvent_; 220 CancelableCallback<void()> hiddenHandleTask_; 221 bool isHiddenHandle_ = false; 222 RectF firstHandleRegion_; 223 RectF secondHandleRegion_; 224 225 private: 226 bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override; 227 void OnAttachToFrameNode() override; 228 void OnDetachFromFrameNode(FrameNode* frameNode) override; 229 230 void HandleOnClick(GestureEvent& info); 231 void HandleTouchEvent(const TouchEventInfo& info); 232 void HandleTouchDownEvent(const TouchEventInfo& info); 233 void HandleOnTouch(GestureEvent& info); 234 void HandlePanStart(GestureEvent& info); 235 void HandlePanMove(GestureEvent& info); 236 void HandlePanEnd(GestureEvent& info); 237 void HandlePanCancel(); 238 void HandleMouseEvent(const MouseInfo& info); 239 240 bool IsHandlesInSameLine(); 241 bool IsFirstHandleMoveStart(const Offset& touchOffset); 242 void StopHiddenHandleTask(); 243 void HiddenHandle(); 244 void UpdateOffsetOnMove(RectF& region, SelectHandleInfo& handleInfo, const OffsetF& offset, bool isFirst); 245 void SetSelectMenuHeight(); 246 void SetContentModifierBounds(const RefPtr<SelectOverlayContentModifier>& modifier); 247 void SwitchHandleToOverlayMode(bool afterRender); 248 249 RefPtr<TouchEventImpl> touchEvent_; 250 251 bool firstHandleDrag_ = false; 252 bool secondHandleDrag_ = false; 253 bool isFirstHandleTouchDown_ = false; 254 bool isSecondHandleTouchDown_ = false; 255 // Used to record the original menu display status when the handle is moved. 256 bool orignMenuIsShow_ = false; 257 bool hasExtensionMenu_ = false; 258 bool hasShowAnimation_ = false; 259 260 int32_t greatThanMaxWidthIndex_ = -1; 261 std::optional<float> menuWidth_; 262 std::optional<float> menuHeight_; 263 264 OffsetF defaultMenuStartOffset_; 265 OffsetF defaultMenuEndOffset_; 266 267 float selectMenuHeight_ = 0.0f; 268 269 RefPtr<SelectOverlayModifier> selectOverlayModifier_; 270 271 RefPtr<SelectOverlayContentModifier> selectOverlayContentModifier_; 272 273 bool paintMethodCreated_ = false; 274 275 bool closedByGlobalTouchEvent_ = false; 276 SelectOverlayMode overlayMode_ = SelectOverlayMode::ALL; 277 278 ACE_DISALLOW_COPY_AND_MOVE(SelectOverlayPattern); 279 }; 280 } // namespace OHOS::Ace::NG 281 282 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_STAGE_PAGE_PATTERN_H 283