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