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_HANDLE_COLOR_FLAG = 1 << 7; 131 inline constexpr SelectOverlayDirtyFlag DIRTY_DOUBLE_HANDLE = DIRTY_FIRST_HANDLE | DIRTY_SECOND_HANDLE; 132 inline constexpr SelectOverlayDirtyFlag DIRTY_ALL = 133 DIRTY_DOUBLE_HANDLE | DIRTY_ALL_MENU_ITEM | DIRTY_SELECT_AREA | DIRTY_SELECT_TEXT | DIRTY_VIEWPORT; 134 135 inline constexpr int32_t REQUEST_RECREATE = 1; 136 137 enum class OptionMenuType { NO_MENU, MOUSE_MENU, TOUCH_MENU }; 138 enum class OptionMenuActionId { COPY, CUT, PASTE, SELECT_ALL, CAMERA_INPUT, AI_WRITE, APPEAR, DISAPPEAR }; 139 enum class CloseReason { 140 CLOSE_REASON_NORMAL = 1, 141 CLOSE_REASON_HOLD_BY_OTHER, 142 CLOSE_REASON_BY_RECREATE, 143 CLOSE_REASON_TOOL_BAR, 144 CLOSE_REASON_BACK_PRESSED, 145 CLOSE_REASON_CLICK_OUTSIDE, 146 CLOSE_REASON_DRAG_FLOATING 147 }; 148 149 struct HoldSelectionInfo { 150 std::function<bool(const PointF&)> checkTouchInArea; 151 std::function<void()> resetSelectionCallback; 152 std::function<bool(SourceType, TouchType)> eventFilter; 153 IsAcceptEventHoldSelectionInfo154 bool IsAcceptEvent(SourceType sourceType, TouchType touchType) 155 { 156 if (eventFilter) { 157 return eventFilter(sourceType, touchType); 158 } 159 return sourceType == SourceType::MOUSE && touchType == TouchType::DOWN; 160 } 161 }; 162 163 // end SelectOverlayManagerNG 164 165 struct SelectMenuInfo { 166 bool menuDisable = false; 167 bool menuIsShow = false; 168 bool singleHandleMenuIsShow = false; 169 bool showCopy = true; 170 bool showPaste = true; 171 bool showCopyAll = true; 172 bool showCut = true; 173 bool showCameraInput = false; 174 bool showAIWrite = false; 175 std::optional<OffsetF> menuOffset; 176 OptionMenuType menuType = OptionMenuType::TOUCH_MENU; 177 178 // Customize menu information. 179 std::optional<int32_t> responseType; 180 std::optional<int32_t> editorType; 181 std::function<void()> menuBuilder; 182 IsIconChangedSelectMenuInfo183 bool IsIconChanged(const SelectMenuInfo& info) const 184 { 185 if (menuBuilder != nullptr || info.menuBuilder != nullptr) { 186 return true; 187 } 188 return !((showCopy == info.showCopy) && (showPaste == info.showPaste) && (showCopyAll == info.showCopyAll) && 189 (showCut == info.showCut) && (showCameraInput == info.showCameraInput) && 190 (showAIWrite == info.showAIWrite)); 191 } 192 ToStringSelectMenuInfo193 std::string ToString() const 194 { 195 auto jsonValue = JsonUtil::Create(true); 196 JSON_STRING_PUT_BOOL(jsonValue, menuDisable); 197 JSON_STRING_PUT_BOOL(jsonValue, menuIsShow); 198 JSON_STRING_PUT_BOOL(jsonValue, singleHandleMenuIsShow); 199 JSON_STRING_PUT_BOOL(jsonValue, showCopy); 200 JSON_STRING_PUT_BOOL(jsonValue, showPaste); 201 JSON_STRING_PUT_BOOL(jsonValue, showCopyAll); 202 JSON_STRING_PUT_BOOL(jsonValue, showCut); 203 JSON_STRING_PUT_BOOL(jsonValue, showCameraInput); 204 return jsonValue->ToString(); 205 } 206 }; 207 208 struct SelectMenuCallback { 209 std::function<void()> onCopy; 210 std::function<void()> onPaste; 211 std::function<void()> onSelectAll; 212 std::function<void()> onCut; 213 std::function<void()> onCameraInput; 214 std::function<void()> onAIWrite; 215 216 std::function<void()> onAppear; 217 std::function<void()> onDisappear; 218 }; 219 220 struct SelectedByMouseInfo { 221 WeakPtr<FrameNode> selectedNode; 222 std::function<void()> onResetSelection; 223 224 bool operator!=(const SelectedByMouseInfo& info) const 225 { 226 CHECK_NULL_RETURN(selectedNode.Upgrade(), true); 227 CHECK_NULL_RETURN(info.selectedNode.Upgrade(), true); 228 return selectedNode.Upgrade() != info.selectedNode.Upgrade(); 229 } 230 clearSelectedByMouseInfo231 void clear() 232 { 233 selectedNode.Reset(); 234 onResetSelection = nullptr; 235 } 236 }; 237 238 struct CallerFrameNodeInfo { 239 RectF paintFrameRect; 240 OffsetF paintOffset; 241 }; 242 243 enum class SelectOverlayMode { 244 ALL, MENU_ONLY, HANDLE_ONLY 245 }; 246 247 enum class HandleLevelMode { 248 OVERLAY, EMBED 249 }; 250 251 struct SelectOverlayInfo { 252 WeakPtr<Pattern> pattern; 253 bool isUsingMouse = false; 254 bool isSingleHandle = false; 255 // when handleReverse is true, The first one is on the right side of the second. 256 bool handleReverse = false; 257 // Used to determine the range of judgment that is parallel to the first and second handles. 258 float singleLineHeight = 10.0f; 259 bool isSelectRegionVisible = false; 260 bool isNewAvoid = false; 261 bool recreateOverlay = false; 262 bool isUseOverlayNG = false; 263 SelectHandleInfo firstHandle; 264 SelectHandleInfo secondHandle; 265 std::function<bool(const RectF&, const RectF&)> checkHandleReverse; 266 std::optional<Color> handlerColor; 267 HitTestMode hitTestMode = HitTestMode::HTMTRANSPARENT_SELF; 268 269 // show area 270 bool useFullScreen = true; 271 RectF showArea; 272 RectF selectArea; 273 274 OffsetF rightClickOffset; 275 276 // handle touch event 277 std::function<void(const TouchEventInfo&)> onTouchDown; 278 std::function<void(const TouchEventInfo&)> onTouchUp; 279 std::function<void(const TouchEventInfo&)> onTouchMove; 280 std::function<void(const GestureEvent&, bool isFirst)> onClick; 281 std::function<void(const GestureEvent&, bool isFirst)> afterOnClick; 282 std::function<void(const MouseInfo&)> onMouseEvent; 283 284 // handle move callback. 285 std::function<void(const GestureEvent&, bool isFirst)> onHandleMoveStart; 286 std::function<void(const RectF&, bool isFirst)> onHandleMove; 287 std::function<void(const RectF&, bool isFirst)> onHandleMoveDone; 288 std::function<void(bool)> onHandleReverse; 289 290 std::function<void(const GestureEvent&, bool isFirst)> onHandlePanMove; 291 std::function<void(const GestureEvent&, bool isFirst)> onHandlePanEnd; 292 std::function<OffsetF()> getDeltaHandleOffset; 293 294 // menu info. 295 SelectMenuInfo menuInfo; 296 SelectMenuCallback menuCallback; 297 298 std::vector<MenuOptionsParam> menuOptionItems; 299 OnMenuItemCallback onCreateCallback; 300 301 // force hide callback, which may be called when other textOverlay shows. 302 std::function<void(bool)> onClose; 303 304 std::function<bool(const PointF&)> checkIsTouchInHostArea; 305 std::function<void()> onHandleIsHidden; 306 307 OHOS::Ace::WeakPtr<FrameNode> callerFrameNode; 308 std::optional<CallerFrameNodeInfo> callerNodeInfo; 309 std::optional<RectF> ancestorViewPort; 310 311 bool isHandleLineShow = true; 312 std::string selectText; 313 bool isSingleLine = false; 314 315 HandleLevelMode handleLevelMode = HandleLevelMode::OVERLAY; 316 bool enableHandleLevel = false; 317 VectorF scale = VectorF(1.0f, 1.0f); 318 bool clipHandleDrawRect = false; 319 std::optional<RectF> clipViewPort; 320 ToStringSelectOverlayInfo321 std::string ToString() const 322 { 323 auto jsonValue = JsonUtil::Create(true); 324 JSON_STRING_PUT_BOOL(jsonValue, isUsingMouse); 325 JSON_STRING_PUT_BOOL(jsonValue, isSingleHandle); 326 JSON_STRING_PUT_BOOL(jsonValue, handleReverse); 327 JSON_STRING_PUT_BOOL(jsonValue, isSelectRegionVisible); 328 JSON_STRING_PUT_BOOL(jsonValue, isNewAvoid); 329 JSON_STRING_PUT_BOOL(jsonValue, recreateOverlay); 330 JSON_STRING_PUT_BOOL(jsonValue, isUseOverlayNG); 331 JSON_STRING_PUT_STRINGABLE(jsonValue, firstHandle); 332 JSON_STRING_PUT_STRINGABLE(jsonValue, secondHandle); 333 JSON_STRING_PUT_STRINGABLE(jsonValue, showArea); 334 JSON_STRING_PUT_STRINGABLE(jsonValue, selectArea); 335 JSON_STRING_PUT_STRINGABLE(jsonValue, rightClickOffset); 336 JSON_STRING_PUT_STRING(jsonValue, selectText); 337 return jsonValue->ToString(); 338 } 339 340 void GetCallerNodeAncestorViewPort(RectF& viewPort); 341 const RectF& GetFirstHandlePaintRect(); 342 const RectF& GetSecondHandlePaintRect(); 343 }; 344 345 } // namespace OHOS::Ace::NG 346 347 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SELECT_OVERLAY_PROPERTY_H 348