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 bool forceDraw = false; 84 bool isTouchable = true; 85 // in Global coordinates. 86 RectF paintRect; 87 RectF localPaintRect; 88 SelectHandlePaintInfo paintInfo; 89 std::function<RectF(const SelectHandlePaintInfo&)> paintInfoConverter; 90 91 bool operator==(const SelectHandleInfo& info) const 92 { 93 return (isShow == info.isShow) && (paintRect == info.paintRect) && (paintInfo == info.paintInfo); 94 } 95 96 bool operator!=(const SelectHandleInfo& info) const 97 { 98 return !(*this == info); 99 } 100 GetPaintRectSelectHandleInfo101 const RectF GetPaintRect() const 102 { 103 if (isPaintHandleWithPoints) { 104 auto offsetX = std::max(paintInfo.startPoint.GetX(), paintInfo.endPoint.GetX()); 105 auto offsetY = std::min(paintInfo.startPoint.GetY(), paintInfo.endPoint.GetY()); 106 auto height = paintInfo.endPoint.GetY() - paintInfo.startPoint.GetY(); 107 return RectF(OffsetF(offsetX, offsetY), SizeF(paintInfo.width, std::abs(height))); 108 } 109 return paintRect; 110 } 111 112 static Dimension GetDefaultLineWidth(); 113 ToStringSelectHandleInfo114 std::string ToString() const 115 { 116 auto jsonValue = JsonUtil::Create(true); 117 JSON_STRING_PUT_BOOL(jsonValue, isShow); 118 JSON_STRING_PUT_BOOL(jsonValue, needLayout); 119 JSON_STRING_PUT_STRINGABLE(jsonValue, paintRect); 120 JSON_STRING_PUT_STRINGABLE(jsonValue, localPaintRect); 121 return jsonValue->ToString(); 122 } 123 }; 124 125 using SelectOverlayDirtyFlag = uint32_t; 126 inline constexpr SelectOverlayDirtyFlag DIRTY_FIRST_HANDLE = 1; 127 inline constexpr SelectOverlayDirtyFlag DIRTY_SECOND_HANDLE = 1 << 1; 128 inline constexpr SelectOverlayDirtyFlag DIRTY_SELECT_AREA = 1 << 2; 129 inline constexpr SelectOverlayDirtyFlag DIRTY_ALL_MENU_ITEM = 1 << 3; 130 inline constexpr SelectOverlayDirtyFlag DIRTY_COPY_ALL_ITEM = 1 << 4; 131 inline constexpr SelectOverlayDirtyFlag DIRTY_SELECT_TEXT = 1 << 5; 132 inline constexpr SelectOverlayDirtyFlag DIRTY_VIEWPORT = 1 << 6; 133 inline constexpr SelectOverlayDirtyFlag DIRTY_HANDLE_COLOR_FLAG = 1 << 7; 134 inline constexpr SelectOverlayDirtyFlag DIRTY_DOUBLE_HANDLE = DIRTY_FIRST_HANDLE | DIRTY_SECOND_HANDLE; 135 inline constexpr SelectOverlayDirtyFlag DIRTY_ALL = 136 DIRTY_DOUBLE_HANDLE | DIRTY_ALL_MENU_ITEM | DIRTY_SELECT_AREA | DIRTY_SELECT_TEXT | DIRTY_VIEWPORT; 137 138 inline constexpr int32_t REQUEST_RECREATE = 1; 139 140 enum class OptionMenuType { NO_MENU, MOUSE_MENU, TOUCH_MENU }; 141 enum class OptionMenuActionId { 142 COPY, 143 CUT, 144 PASTE, 145 SELECT_ALL, 146 TRANSLATE, 147 SHARE, 148 SEARCH, 149 CAMERA_INPUT, 150 AI_WRITE, 151 APPEAR, 152 DISAPPEAR 153 }; 154 enum class CloseReason { 155 CLOSE_REASON_NORMAL = 1, 156 CLOSE_REASON_HOLD_BY_OTHER, 157 CLOSE_REASON_BY_RECREATE, 158 CLOSE_REASON_TOOL_BAR, 159 CLOSE_REASON_BACK_PRESSED, 160 CLOSE_REASON_CLICK_OUTSIDE, 161 CLOSE_REASON_DRAG_FLOATING, 162 CLOSE_REASON_WINDOW_SIZE_CHANGE 163 }; 164 165 struct HoldSelectionInfo { 166 std::function<bool(const PointF&)> checkTouchInArea; 167 std::function<void()> resetSelectionCallback; 168 std::function<bool(SourceType, TouchType)> eventFilter; 169 IsAcceptEventHoldSelectionInfo170 bool IsAcceptEvent(SourceType sourceType, TouchType touchType) 171 { 172 if (eventFilter) { 173 return eventFilter(sourceType, touchType); 174 } 175 return sourceType == SourceType::MOUSE && touchType == TouchType::DOWN; 176 } 177 }; 178 179 // end SelectOverlayManagerNG 180 181 struct SelectMenuInfo { 182 bool menuDisable = false; 183 bool menuIsShow = false; 184 bool singleHandleMenuIsShow = false; 185 bool showCopy = true; 186 bool showPaste = true; 187 bool showCopyAll = true; 188 bool showCut = true; 189 bool showTranslate = false; 190 bool showSearch = false; 191 bool showShare = false; 192 bool showCameraInput = false; 193 bool showAIWrite = false; 194 std::optional<OffsetF> menuOffset; 195 OptionMenuType menuType = OptionMenuType::TOUCH_MENU; 196 197 // Customize menu information. 198 std::optional<int32_t> responseType; 199 std::optional<int32_t> editorType; 200 std::function<void()> menuBuilder; 201 IsIconChangedSelectMenuInfo202 bool IsIconChanged(const SelectMenuInfo& info) const 203 { 204 if (menuBuilder != nullptr || info.menuBuilder != nullptr) { 205 return true; 206 } 207 return !((showCopy == info.showCopy) && (showPaste == info.showPaste) && (showCopyAll == info.showCopyAll) && 208 (showTranslate == info.showTranslate) && 209 (showCut == info.showCut) && (showSearch == info.showSearch) && (showShare == info.showShare) && 210 (showCameraInput == info.showCameraInput) && 211 (showAIWrite == info.showAIWrite)); 212 } 213 ToStringSelectMenuInfo214 std::string ToString() const 215 { 216 auto jsonValue = JsonUtil::Create(true); 217 JSON_STRING_PUT_BOOL(jsonValue, menuDisable); 218 JSON_STRING_PUT_BOOL(jsonValue, menuIsShow); 219 JSON_STRING_PUT_BOOL(jsonValue, singleHandleMenuIsShow); 220 JSON_STRING_PUT_BOOL(jsonValue, showCopy); 221 JSON_STRING_PUT_BOOL(jsonValue, showPaste); 222 JSON_STRING_PUT_BOOL(jsonValue, showCopyAll); 223 JSON_STRING_PUT_BOOL(jsonValue, showCut); 224 JSON_STRING_PUT_BOOL(jsonValue, showTranslate); 225 JSON_STRING_PUT_BOOL(jsonValue, showSearch); 226 JSON_STRING_PUT_BOOL(jsonValue, showShare); 227 JSON_STRING_PUT_BOOL(jsonValue, showCameraInput); 228 return jsonValue->ToString(); 229 } 230 }; 231 232 struct SelectMenuCallback { 233 std::function<void()> onCopy; 234 std::function<void()> onPaste; 235 std::function<void()> onSelectAll; 236 std::function<void()> onCut; 237 std::function<void()> onTranslate; 238 std::function<void()> onSearch; 239 std::function<void()> onShare; 240 std::function<void()> onCameraInput; 241 std::function<void()> onAIWrite; 242 243 std::function<void()> onAppear; 244 std::function<void()> onDisappear; 245 std::function<void()> onMenuShow; 246 std::function<void()> onMenuHide; 247 std::function<bool()> showMenuOnMoveDone; 248 }; 249 250 struct SelectedByMouseInfo { 251 WeakPtr<FrameNode> selectedNode; 252 std::function<void()> onResetSelection; 253 254 bool operator!=(const SelectedByMouseInfo& info) const 255 { 256 CHECK_NULL_RETURN(selectedNode.Upgrade(), true); 257 CHECK_NULL_RETURN(info.selectedNode.Upgrade(), true); 258 return selectedNode.Upgrade() != info.selectedNode.Upgrade(); 259 } 260 clearSelectedByMouseInfo261 void clear() 262 { 263 selectedNode.Reset(); 264 onResetSelection = nullptr; 265 } 266 }; 267 268 struct CallerFrameNodeInfo { 269 RectF paintFrameRect; 270 OffsetF paintOffset; 271 }; 272 273 enum class SelectOverlayMode { 274 ALL, MENU_ONLY, HANDLE_ONLY 275 }; 276 277 enum class HandleLevelMode { 278 OVERLAY, EMBED 279 }; 280 281 struct SelectOverlayInfo { 282 WeakPtr<Pattern> pattern; 283 bool isUsingMouse = false; 284 bool isSingleHandle = false; 285 // when handleReverse is true, The first one is on the right side of the second. 286 bool handleReverse = false; 287 // Used to determine the range of judgment that is parallel to the first and second handles. 288 float singleLineHeight = 10.0f; 289 bool isSelectRegionVisible = false; 290 bool isNewAvoid = false; 291 bool recreateOverlay = false; 292 bool isUseOverlayNG = false; 293 SelectHandleInfo firstHandle; 294 SelectHandleInfo secondHandle; 295 std::function<bool(const RectF&, const RectF&)> checkHandleReverse; 296 std::optional<Color> handlerColor; 297 HitTestMode hitTestMode = HitTestMode::HTMTRANSPARENT_SELF; 298 299 // show area 300 bool useFullScreen = true; 301 RectF showArea; 302 RectF selectArea; 303 304 OffsetF rightClickOffset; 305 306 // handle touch event 307 std::function<void(const TouchEventInfo&)> onTouchDown; 308 std::function<void(const TouchEventInfo&)> onTouchUp; 309 std::function<void(const TouchEventInfo&)> onTouchMove; 310 std::function<void(const GestureEvent&, bool isFirst)> onClick; 311 std::function<void(const GestureEvent&, bool isFirst)> afterOnClick; 312 std::function<void(const MouseInfo&)> onMouseEvent; 313 314 // handle move callback. 315 std::function<void(const GestureEvent&, bool isFirst)> onHandleMoveStart; 316 std::function<void(const RectF&, bool isFirst)> onHandleMove; 317 std::function<void(const RectF&, bool isFirst)> onHandleMoveDone; 318 std::function<void(bool)> onHandleReverse; 319 320 std::function<void(const GestureEvent&, bool isFirst)> onHandlePanMove; 321 std::function<void(const GestureEvent&, bool isFirst)> onHandlePanEnd; 322 std::function<OffsetF()> getDeltaHandleOffset; 323 324 // menu info. 325 SelectMenuInfo menuInfo; 326 SelectMenuCallback menuCallback; 327 328 std::vector<MenuOptionsParam> menuOptionItems; 329 OnMenuItemCallback onCreateCallback; 330 331 // force hide callback, which may be called when other textOverlay shows. 332 std::function<void(bool)> onClose; 333 334 std::function<bool(const PointF&)> checkIsTouchInHostArea; 335 std::function<void()> onHandleIsHidden; 336 337 OHOS::Ace::WeakPtr<FrameNode> callerFrameNode; 338 std::optional<CallerFrameNodeInfo> callerNodeInfo; 339 std::optional<RectF> ancestorViewPort; 340 341 bool isHandleLineShow = true; 342 std::string selectText; 343 bool isSingleLine = false; 344 345 HandleLevelMode handleLevelMode = HandleLevelMode::OVERLAY; 346 bool enableHandleLevel = false; 347 VectorF scale = VectorF(1.0f, 1.0f); 348 bool clipHandleDrawRect = false; 349 std::optional<RectF> clipViewPort; 350 ToStringSelectOverlayInfo351 std::string ToString() const 352 { 353 auto jsonValue = JsonUtil::Create(true); 354 JSON_STRING_PUT_INT(jsonValue, handleLevelMode); 355 JSON_STRING_PUT_BOOL(jsonValue, isUsingMouse); 356 JSON_STRING_PUT_BOOL(jsonValue, isSingleHandle); 357 JSON_STRING_PUT_BOOL(jsonValue, handleReverse); 358 JSON_STRING_PUT_BOOL(jsonValue, isSelectRegionVisible); 359 JSON_STRING_PUT_BOOL(jsonValue, isNewAvoid); 360 JSON_STRING_PUT_BOOL(jsonValue, recreateOverlay); 361 JSON_STRING_PUT_BOOL(jsonValue, isUseOverlayNG); 362 JSON_STRING_PUT_STRINGABLE(jsonValue, firstHandle); 363 JSON_STRING_PUT_STRINGABLE(jsonValue, secondHandle); 364 JSON_STRING_PUT_STRINGABLE(jsonValue, showArea); 365 JSON_STRING_PUT_STRINGABLE(jsonValue, selectArea); 366 JSON_STRING_PUT_STRINGABLE(jsonValue, rightClickOffset); 367 JSON_STRING_PUT_STRING(jsonValue, selectText); 368 return jsonValue->ToString(); 369 } 370 371 void GetCallerNodeAncestorViewPort(RectF& viewPort); 372 const RectF& GetFirstHandlePaintRect(); 373 const RectF& GetSecondHandlePaintRect(); 374 bool enableSubWindowMenu = false; 375 OffsetF containerModalOffset; 376 }; 377 378 enum class TextMenuShowMode { 379 BEGIN = -1, 380 UNSPECIFIED = BEGIN, 381 // Display the text selection menu in the current window 382 DEFAULT = 0, 383 /** 384 * Prefer to display the text selection menu in a separate window 385 * and continue to display it within the current window if a separate window is not supported 386 */ 387 PREFER_WINDOW = 1, 388 END = PREFER_WINDOW, 389 }; 390 391 TextMenuShowMode CastToTextMenuShowMode(int32_t value); 392 393 struct TextMenuOptions { 394 std::optional<TextMenuShowMode> showMode; 395 }; 396 } // namespace OHOS::Ace::NG 397 398 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SELECT_OVERLAY_PROPERTY_H 399