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_PROPERTY_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SELECT_OVERLAY_PROPERTY_H 18 19 #include <cstdint> 20 #include <functional> 21 #include <vector> 22 23 #include "base/geometry/ng/offset_t.h" 24 #include "base/geometry/ng/point_t.h" 25 #include "base/geometry/ng/rect_t.h" 26 #include "core/components_ng/event/gesture_event_hub.h" 27 #include "core/components_ng/pattern/text/text_menu_extension.h" 28 #include "core/event/ace_events.h" 29 #include "core/event/touch_event.h" 30 #include "frameworks/core/components_ng/pattern/pattern.h" 31 32 namespace OHOS::Ace::NG { 33 34 constexpr int32_t MENU_SHOW_ANIMATION_DURATION = 250; 35 constexpr int32_t MENU_HIDE_ANIMATION_DURATION = 200; 36 constexpr int32_t HANDLE_ANIMATION_DURATION = 150; 37 38 struct OnMenuItemCallback { 39 OnCreateMenuCallback onCreateMenuCallback; 40 OnMenuItemClickCallback onMenuItemClick; 41 std::function<void(int32_t&, int32_t&)> textRangeCallback; 42 }; 43 44 struct SelectHandlePaintInfo { 45 OffsetF startPoint; 46 OffsetF endPoint; 47 float width = 0.0f; 48 49 SelectHandlePaintInfo operator-(const OffsetF& offset) const 50 { 51 return { 52 .startPoint = startPoint - offset, 53 .endPoint = endPoint - offset, 54 .width = width 55 }; 56 } 57 58 SelectHandlePaintInfo operator+(const OffsetF& offset) const 59 { 60 return { 61 .startPoint = startPoint + offset, 62 .endPoint = endPoint + offset, 63 .width = width 64 }; 65 } 66 67 bool operator==(const SelectHandlePaintInfo& info) const 68 { 69 return (startPoint == info.startPoint) && (endPoint == info.endPoint) && (width == info.width); 70 } 71 72 bool operator!=(const SelectHandlePaintInfo& info) const 73 { 74 return !(*this == info); 75 } 76 }; 77 78 struct SelectHandleInfo { 79 bool isShow = true; 80 bool needLayout = false; 81 bool isPaintHandleWithPoints = false; 82 bool isCircleShow = true; 83 // in Global coordinates. 84 RectF paintRect; 85 RectF localPaintRect; 86 SelectHandlePaintInfo paintInfo; 87 std::function<RectF(const SelectHandlePaintInfo&)> paintInfoConverter; 88 89 bool operator==(const SelectHandleInfo& info) const 90 { 91 return (isShow == info.isShow) && (paintRect == info.paintRect) && (paintInfo == info.paintInfo); 92 } 93 94 bool operator!=(const SelectHandleInfo& info) const 95 { 96 return !(*this == info); 97 } 98 GetPaintRectSelectHandleInfo99 const RectF GetPaintRect() const 100 { 101 if (isPaintHandleWithPoints) { 102 auto offsetX = std::max(paintInfo.startPoint.GetX(), paintInfo.endPoint.GetX()); 103 auto offsetY = std::min(paintInfo.startPoint.GetY(), paintInfo.endPoint.GetY()); 104 auto height = paintInfo.endPoint.GetY() - paintInfo.startPoint.GetY(); 105 return RectF(OffsetF(offsetX, offsetY), SizeF(paintInfo.width, std::abs(height))); 106 } 107 return paintRect; 108 } 109 110 static Dimension GetDefaultLineWidth(); 111 ToStringSelectHandleInfo112 std::string ToString() const 113 { 114 auto jsonValue = JsonUtil::Create(true); 115 JSON_STRING_PUT_BOOL(jsonValue, isShow); 116 JSON_STRING_PUT_BOOL(jsonValue, needLayout); 117 JSON_STRING_PUT_STRINGABLE(jsonValue, paintRect); 118 return jsonValue->ToString(); 119 } 120 }; 121 122 using SelectOverlayDirtyFlag = uint32_t; 123 inline constexpr SelectOverlayDirtyFlag DIRTY_FIRST_HANDLE = 1; 124 inline constexpr SelectOverlayDirtyFlag DIRTY_SECOND_HANDLE = 1 << 1; 125 inline constexpr SelectOverlayDirtyFlag DIRTY_SELECT_AREA = 1 << 2; 126 inline constexpr SelectOverlayDirtyFlag DIRTY_ALL_MENU_ITEM = 1 << 3; 127 inline constexpr SelectOverlayDirtyFlag DIRTY_COPY_ALL_ITEM = 1 << 4; 128 inline constexpr SelectOverlayDirtyFlag DIRTY_SELECT_TEXT = 1 << 5; 129 inline constexpr SelectOverlayDirtyFlag DIRTY_VIEWPORT = 1 << 6; 130 inline constexpr SelectOverlayDirtyFlag DIRTY_DOUBLE_HANDLE = DIRTY_FIRST_HANDLE | DIRTY_SECOND_HANDLE; 131 inline constexpr SelectOverlayDirtyFlag DIRTY_ALL = 132 DIRTY_DOUBLE_HANDLE | DIRTY_ALL_MENU_ITEM | DIRTY_SELECT_AREA | DIRTY_SELECT_TEXT | DIRTY_VIEWPORT; 133 134 inline constexpr int32_t REQUEST_RECREATE = 1; 135 136 enum class OptionMenuType { NO_MENU, MOUSE_MENU, TOUCH_MENU }; 137 enum class OptionMenuActionId { COPY, CUT, PASTE, SELECT_ALL, CAMERA_INPUT, AI_WRITE, APPEAR, DISAPPEAR }; 138 enum class CloseReason { 139 CLOSE_REASON_NORMAL = 1, 140 CLOSE_REASON_HOLD_BY_OTHER, 141 CLOSE_REASON_BY_RECREATE, 142 CLOSE_REASON_TOOL_BAR, 143 CLOSE_REASON_BACK_PRESSED, 144 CLOSE_REASON_CLICK_OUTSIDE, 145 CLOSE_REASON_DRAG_FLOATING 146 }; 147 148 struct HoldSelectionInfo { 149 std::function<bool(const PointF&)> checkTouchInArea; 150 std::function<void()> resetSelectionCallback; 151 std::function<bool(SourceType, TouchType)> eventFilter; 152 IsAcceptEventHoldSelectionInfo153 bool IsAcceptEvent(SourceType sourceType, TouchType touchType) 154 { 155 if (eventFilter) { 156 return eventFilter(sourceType, touchType); 157 } 158 return sourceType == SourceType::MOUSE && touchType == TouchType::DOWN; 159 } 160 }; 161 162 // end SelectOverlayManagerNG 163 164 struct SelectMenuInfo { 165 bool menuDisable = false; 166 bool menuIsShow = false; 167 bool singleHandleMenuIsShow = false; 168 bool showCopy = true; 169 bool showPaste = true; 170 bool showCopyAll = true; 171 bool showCut = true; 172 bool showCameraInput = false; 173 bool showAIWrite = false; 174 std::optional<OffsetF> menuOffset; 175 OptionMenuType menuType = OptionMenuType::TOUCH_MENU; 176 177 // Customize menu information. 178 std::optional<int32_t> responseType; 179 std::optional<int32_t> editorType; 180 std::function<void()> menuBuilder; 181 IsIconChangedSelectMenuInfo182 bool IsIconChanged(const SelectMenuInfo& info) const 183 { 184 if (menuBuilder != nullptr || info.menuBuilder != nullptr) { 185 return true; 186 } 187 return !((showCopy == info.showCopy) && (showPaste == info.showPaste) && (showCopyAll == info.showCopyAll) && 188 (showCut == info.showCut) && (showCameraInput == info.showCameraInput) && 189 (showAIWrite == info.showAIWrite)); 190 } 191 ToStringSelectMenuInfo192 std::string ToString() const 193 { 194 auto jsonValue = JsonUtil::Create(true); 195 JSON_STRING_PUT_BOOL(jsonValue, menuDisable); 196 JSON_STRING_PUT_BOOL(jsonValue, menuIsShow); 197 JSON_STRING_PUT_BOOL(jsonValue, singleHandleMenuIsShow); 198 JSON_STRING_PUT_BOOL(jsonValue, showCopy); 199 JSON_STRING_PUT_BOOL(jsonValue, showPaste); 200 JSON_STRING_PUT_BOOL(jsonValue, showCopyAll); 201 JSON_STRING_PUT_BOOL(jsonValue, showCut); 202 JSON_STRING_PUT_BOOL(jsonValue, showCameraInput); 203 return jsonValue->ToString(); 204 } 205 }; 206 207 struct SelectMenuCallback { 208 std::function<void()> onCopy; 209 std::function<void()> onPaste; 210 std::function<void()> onSelectAll; 211 std::function<void()> onCut; 212 std::function<void()> onCameraInput; 213 std::function<void()> onAIWrite; 214 215 std::function<void()> onAppear; 216 std::function<void()> onDisappear; 217 }; 218 219 struct SelectedByMouseInfo { 220 WeakPtr<FrameNode> selectedNode; 221 std::function<void()> onResetSelection; 222 223 bool operator!=(const SelectedByMouseInfo& info) const 224 { 225 CHECK_NULL_RETURN(selectedNode.Upgrade(), true); 226 CHECK_NULL_RETURN(info.selectedNode.Upgrade(), true); 227 return selectedNode.Upgrade() != info.selectedNode.Upgrade(); 228 } 229 clearSelectedByMouseInfo230 void clear() 231 { 232 selectedNode.Reset(); 233 onResetSelection = nullptr; 234 } 235 }; 236 237 struct CallerFrameNodeInfo { 238 RectF paintFrameRect; 239 OffsetF paintOffset; 240 }; 241 242 enum class SelectOverlayMode { 243 ALL, MENU_ONLY, HANDLE_ONLY 244 }; 245 246 enum class HandleLevelMode { 247 OVERLAY, EMBED 248 }; 249 250 struct SelectOverlayInfo { 251 WeakPtr<Pattern> pattern; 252 bool isUsingMouse = false; 253 bool isSingleHandle = false; 254 // when handleReverse is true, The first one is on the right side of the second. 255 bool handleReverse = false; 256 // Used to determine the range of judgment that is parallel to the first and second handles. 257 float singleLineHeight = 10.0f; 258 bool isSelectRegionVisible = false; 259 bool isNewAvoid = false; 260 bool recreateOverlay = false; 261 bool isUseOverlayNG = false; 262 SelectHandleInfo firstHandle; 263 SelectHandleInfo secondHandle; 264 std::function<bool(const RectF&, const RectF&)> checkHandleReverse; 265 std::optional<Color> handlerColor; 266 HitTestMode hitTestMode = HitTestMode::HTMTRANSPARENT_SELF; 267 268 // show area 269 bool useFullScreen = true; 270 RectF showArea; 271 RectF selectArea; 272 273 OffsetF rightClickOffset; 274 275 // handle touch event 276 std::function<void(const TouchEventInfo&)> onTouchDown; 277 std::function<void(const TouchEventInfo&)> onTouchUp; 278 std::function<void(const TouchEventInfo&)> onTouchMove; 279 std::function<void(const GestureEvent&, bool isFirst)> onClick; 280 std::function<void(const GestureEvent&, bool isFirst)> afterOnClick; 281 std::function<void(const MouseInfo&)> onMouseEvent; 282 283 // handle move callback. 284 std::function<void(const GestureEvent&, bool isFirst)> onHandleMoveStart; 285 std::function<void(const RectF&, bool isFirst)> onHandleMove; 286 std::function<void(const RectF&, bool isFirst)> onHandleMoveDone; 287 std::function<void(bool)> onHandleReverse; 288 289 std::function<void(const GestureEvent&, bool isFirst)> onHandlePanMove; 290 std::function<void(const GestureEvent&, bool isFirst)> onHandlePanEnd; 291 std::function<OffsetF()> getDeltaHandleOffset; 292 293 // menu info. 294 SelectMenuInfo menuInfo; 295 SelectMenuCallback menuCallback; 296 297 std::vector<MenuOptionsParam> menuOptionItems; 298 OnMenuItemCallback onCreateCallback; 299 300 // force hide callback, which may be called when other textOverlay shows. 301 std::function<void(bool)> onClose; 302 303 std::function<bool(const PointF&)> checkIsTouchInHostArea; 304 std::function<void()> onHandleIsHidden; 305 306 OHOS::Ace::WeakPtr<FrameNode> callerFrameNode; 307 std::optional<CallerFrameNodeInfo> callerNodeInfo; 308 std::optional<RectF> ancestorViewPort; 309 310 bool isHandleLineShow = true; 311 std::string selectText; 312 bool isSingleLine = false; 313 314 HandleLevelMode handleLevelMode = HandleLevelMode::OVERLAY; 315 bool enableHandleLevel = false; 316 VectorF scale = VectorF(1.0f, 1.0f); 317 bool clipHandleDrawRect = false; 318 std::optional<RectF> clipViewPort; 319 ToStringSelectOverlayInfo320 std::string ToString() const 321 { 322 auto jsonValue = JsonUtil::Create(true); 323 JSON_STRING_PUT_BOOL(jsonValue, isUsingMouse); 324 JSON_STRING_PUT_BOOL(jsonValue, isSingleHandle); 325 JSON_STRING_PUT_BOOL(jsonValue, handleReverse); 326 JSON_STRING_PUT_BOOL(jsonValue, isSelectRegionVisible); 327 JSON_STRING_PUT_BOOL(jsonValue, isNewAvoid); 328 JSON_STRING_PUT_BOOL(jsonValue, recreateOverlay); 329 JSON_STRING_PUT_BOOL(jsonValue, isUseOverlayNG); 330 JSON_STRING_PUT_STRINGABLE(jsonValue, firstHandle); 331 JSON_STRING_PUT_STRINGABLE(jsonValue, secondHandle); 332 JSON_STRING_PUT_STRINGABLE(jsonValue, showArea); 333 JSON_STRING_PUT_STRINGABLE(jsonValue, selectArea); 334 JSON_STRING_PUT_STRINGABLE(jsonValue, rightClickOffset); 335 JSON_STRING_PUT_STRING(jsonValue, selectText); 336 return jsonValue->ToString(); 337 } 338 339 void GetCallerNodeAncestorViewPort(RectF& viewPort); 340 const RectF& GetFirstHandlePaintRect(); 341 const RectF& GetSecondHandlePaintRect(); 342 }; 343 344 } // namespace OHOS::Ace::NG 345 346 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SELECT_OVERLAY_PROPERTY_H 347