• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "frameworks/core/components_ng/manager/safe_area/safe_area_manager.h"
32 
33 namespace OHOS::Ace::NG {
34 
35 constexpr int32_t MENU_SHOW_ANIMATION_DURATION = 250;
36 constexpr int32_t MENU_HIDE_ANIMATION_DURATION = 200;
37 constexpr int32_t HANDLE_ANIMATION_DURATION = 150;
38 
39 struct OnMenuItemCallback {
40     OnCreateMenuCallback onCreateMenuCallback;
41     OnMenuItemClickCallback onMenuItemClick;
42     OnPrepareMenuCallback onPrepareMenuCallback;
43     std::function<void(int32_t&, int32_t&)> textRangeCallback;
44     std::function<void()> beforeOnPrepareMenuCallback;
45 };
46 
47 struct SelectHandlePaintInfo {
48     OffsetF startPoint;
49     OffsetF endPoint;
50     float width = 0.0f;
51 
52     SelectHandlePaintInfo operator-(const OffsetF& offset) const
53     {
54         return {
55             .startPoint = startPoint - offset,
56             .endPoint = endPoint - offset,
57             .width = width
58         };
59     }
60 
61     SelectHandlePaintInfo operator+(const OffsetF& offset) const
62     {
63         return {
64             .startPoint = startPoint + offset,
65             .endPoint = endPoint + offset,
66             .width = width
67         };
68     }
69 
70     bool operator==(const SelectHandlePaintInfo& info) const
71     {
72         return (startPoint == info.startPoint) && (endPoint == info.endPoint) && (width == info.width);
73     }
74 
75     bool operator!=(const SelectHandlePaintInfo& info) const
76     {
77         return !(*this == info);
78     }
79 };
80 
81 struct SelectHandleInfo {
82     bool isShow = true;
83     bool needLayout = false;
84     bool isPaintHandleWithPoints = false;
85     bool isCircleShow = true;
86     bool forceDraw = false;
87     bool isTouchable = true;
88     // in Global coordinates.
89     RectF paintRect;
90     RectF localPaintRect;
91     SelectHandlePaintInfo paintInfo;
92     std::function<RectF(const SelectHandlePaintInfo&)> paintInfoConverter;
93 
94     bool operator==(const SelectHandleInfo& info) const
95     {
96         return (isShow == info.isShow) && (paintRect == info.paintRect) && (paintInfo == info.paintInfo) &&
97                (localPaintRect == info.localPaintRect);
98     }
99 
100     bool operator!=(const SelectHandleInfo& info) const
101     {
102         return !(*this == info);
103     }
104 
GetPaintRectSelectHandleInfo105     const RectF GetPaintRect() const
106     {
107         if (isPaintHandleWithPoints) {
108             auto offsetX = std::max(paintInfo.startPoint.GetX(), paintInfo.endPoint.GetX());
109             auto offsetY = std::min(paintInfo.startPoint.GetY(), paintInfo.endPoint.GetY());
110             auto height = paintInfo.endPoint.GetY() - paintInfo.startPoint.GetY();
111             return RectF(OffsetF(offsetX, offsetY), SizeF(paintInfo.width, std::abs(height)));
112         }
113         return paintRect;
114     }
115 
116     static Dimension GetDefaultLineWidth();
117 
ToStringSelectHandleInfo118     std::string ToString() const
119     {
120         auto jsonValue = JsonUtil::Create(true);
121         JSON_STRING_PUT_BOOL(jsonValue, isShow);
122         JSON_STRING_PUT_BOOL(jsonValue, needLayout);
123         JSON_STRING_PUT_STRINGABLE(jsonValue, paintRect);
124         JSON_STRING_PUT_STRINGABLE(jsonValue, localPaintRect);
125         return jsonValue->ToString();
126     }
127 };
128 
129 using SelectOverlayDirtyFlag = uint32_t;
130 inline constexpr SelectOverlayDirtyFlag DIRTY_FIRST_HANDLE = 1;
131 inline constexpr SelectOverlayDirtyFlag DIRTY_SECOND_HANDLE = 1 << 1;
132 inline constexpr SelectOverlayDirtyFlag DIRTY_SELECT_AREA = 1 << 2;
133 inline constexpr SelectOverlayDirtyFlag DIRTY_ALL_MENU_ITEM = 1 << 3;
134 inline constexpr SelectOverlayDirtyFlag DIRTY_COPY_ALL_ITEM = 1 << 4;
135 inline constexpr SelectOverlayDirtyFlag DIRTY_SELECT_TEXT = 1 << 5;
136 inline constexpr SelectOverlayDirtyFlag DIRTY_VIEWPORT = 1 << 6;
137 inline constexpr SelectOverlayDirtyFlag DIRTY_HANDLE_COLOR_FLAG = 1 << 7;
138 inline constexpr SelectOverlayDirtyFlag DIRTY_AI_MENU_ITEM = 1 << 8;
139 inline constexpr SelectOverlayDirtyFlag DIRTY_ASK_CELIA = 1 << 9;
140 inline constexpr SelectOverlayDirtyFlag DIRTY_DOUBLE_HANDLE = DIRTY_FIRST_HANDLE | DIRTY_SECOND_HANDLE;
141 inline constexpr SelectOverlayDirtyFlag DIRTY_ALL =
142     DIRTY_DOUBLE_HANDLE | DIRTY_ALL_MENU_ITEM | DIRTY_SELECT_AREA | DIRTY_SELECT_TEXT | DIRTY_VIEWPORT;
143 
144 inline constexpr int32_t REQUEST_RECREATE = 1;
145 
146 using SystemServiceMenuDisableFlag = uint32_t;
147 inline constexpr SystemServiceMenuDisableFlag DISABLE_NORMAL_FLAG = 0;
148 inline constexpr SystemServiceMenuDisableFlag DISABLE_ALL_FLAG = 1;
149 inline constexpr SystemServiceMenuDisableFlag DISABLE_TRANSLATE_FLAG = 1 << 1;
150 inline constexpr SystemServiceMenuDisableFlag DISABLE_SEARCH_FLAG = 1 << 2;
151 inline constexpr SystemServiceMenuDisableFlag DISABLE_SHARE_FLAG = 1 << 3;
152 inline constexpr SystemServiceMenuDisableFlag DISABLE_CAMERA_INPUT_FLAG = 1 << 4;
153 inline constexpr SystemServiceMenuDisableFlag DISABLE_AI_WRITER_FLAG = 1 << 5;
154 inline constexpr SystemServiceMenuDisableFlag DISABLE_COLLABORATION_SERVICE_FLAG = 1 << 6;
155 inline constexpr SystemServiceMenuDisableFlag DISABLE_AI_MENU_PHONE_FLAG = 1 << 7;
156 inline constexpr SystemServiceMenuDisableFlag DISABLE_AI_MENU_URL_FLAG = 1 << 8;
157 inline constexpr SystemServiceMenuDisableFlag DISABLE_AI_MENU_EMAIL_FLAG = 1 << 9;
158 inline constexpr SystemServiceMenuDisableFlag DISABLE_AI_MENU_ADDRESS_FLAG = 1 << 10;
159 inline constexpr SystemServiceMenuDisableFlag DISABLE_AI_MENU_DATETIME_FLAG = 1 << 11;
160 inline constexpr SystemServiceMenuDisableFlag DISABLE_ASK_CELIA_FLAG = 1 << 12;
161 
162 inline constexpr char OH_DEFAULT_CUT[] = "OH_DEFAULT_CUT";
163 inline constexpr char OH_DEFAULT_COPY[] = "OH_DEFAULT_COPY";
164 inline constexpr char OH_DEFAULT_PASTE[] = "OH_DEFAULT_PASTE";
165 inline constexpr char OH_DEFAULT_SELECT_ALL[] = "OH_DEFAULT_SELECT_ALL";
166 inline constexpr char OH_DEFAULT_TRANSLATE[] = "OH_DEFAULT_TRANSLATE";
167 inline constexpr char OH_DEFAULT_SEARCH[] = "OH_DEFAULT_SEARCH";
168 inline constexpr char OH_DEFAULT_SHARE[] = "OH_DEFAULT_SHARE";
169 inline constexpr char OH_DEFAULT_CAMERA_INPUT[] = "OH_DEFAULT_CAMERA_INPUT";
170 inline constexpr char OH_DEFAULT_AI_WRITE[] = "OH_DEFAULT_AI_WRITE";
171 inline constexpr char OH_DEFAULT_AI_MENU_PHONE[] = "OH_DEFAULT_AI_MENU_PHONE";
172 inline constexpr char OH_DEFAULT_AI_MENU_URL[] = "OH_DEFAULT_AI_MENU_URL";
173 inline constexpr char OH_DEFAULT_AI_MENU_EMAIL[] = "OH_DEFAULT_AI_MENU_EMAIL";
174 inline constexpr char OH_DEFAULT_AI_MENU_ADDRESS[] = "OH_DEFAULT_AI_MENU_ADDRESS";
175 inline constexpr char OH_DEFAULT_AI_MENU_DATETIME[] = "OH_DEFAULT_AI_MENU_DATETIME";
176 inline constexpr char OH_DEFAULT_ASK_CELIA[] = "OH_DEFAULT_ASK_CELIA";
177 
178 inline constexpr char OH_DEFAULT_COLLABORATION_SERVICE[] = "OH_DEFAULT_COLLABORATION_SERVICE";
179 
180 enum class OptionMenuType { NO_MENU, MOUSE_MENU, TOUCH_MENU };
181 enum class OptionMenuActionId {
182     COPY,
183     CUT,
184     PASTE,
185     SELECT_ALL,
186     TRANSLATE,
187     SHARE,
188     SEARCH,
189     CAMERA_INPUT,
190     AI_WRITE,
191     APPEAR,
192     DISAPPEAR,
193     AI_MENU_OPTION,
194     ASK_CELIA
195 };
196 enum class CloseReason {
197     CLOSE_REASON_NORMAL = 1,
198     CLOSE_REASON_HOLD_BY_OTHER,
199     CLOSE_REASON_BY_RECREATE,
200     CLOSE_REASON_TOOL_BAR,
201     CLOSE_REASON_BACK_PRESSED,
202     CLOSE_REASON_CLICK_OUTSIDE,
203     CLOSE_REASON_DRAG_FLOATING,
204     CLOSE_REASON_WINDOW_SIZE_CHANGE,
205     CLOSE_REASON_SELECT_ALL
206 };
207 
208 struct HoldSelectionInfo {
209     std::function<bool(const PointF&, bool)> checkTouchInArea;
210     std::function<void()> resetSelectionCallback;
211     std::function<bool(SourceType, TouchType)> eventFilter;
212 
IsAcceptEventHoldSelectionInfo213     bool IsAcceptEvent(SourceType sourceType, TouchType touchType)
214     {
215         if (eventFilter) {
216             return eventFilter(sourceType, touchType);
217         }
218         return sourceType == SourceType::MOUSE && touchType == TouchType::DOWN;
219     }
220 };
221 
222 // end SelectOverlayManagerNG
223 
224 struct SelectMenuInfo {
225     bool menuDisable = false;
226     bool menuIsShow = false;
227     bool singleHandleMenuIsShow = false;
228     bool showCopy = true;
229     bool showPaste = true;
230     bool showCopyAll = true;
231     bool showCut = true;
232     bool showTranslate = false;
233     bool showShare = false;
234     bool showSearch = false;
235     bool showCameraInput = false;
236     bool showAIWrite = false;
237     bool hasOnPrepareMenuCallback = false;
238     OHOS::Ace::TextDataDetectType aiMenuOptionType = TextDataDetectType::INVALID;
239     std::optional<OffsetF> menuOffset;
240     OptionMenuType menuType = OptionMenuType::TOUCH_MENU;
241     bool isAskCeliaEnabled = false;
242     bool isShowAIMenuOptionChanged = false;
243 
244     // Customize menu information.
245     std::optional<int32_t> responseType;
246     std::optional<int32_t> editorType;
247     std::function<void()> menuBuilder;
248 
IsIconChangedSelectMenuInfo249     bool IsIconChanged(const SelectMenuInfo& info) const
250     {
251         if (menuBuilder != nullptr || info.menuBuilder != nullptr) {
252             return true;
253         }
254         return !((showCopy == info.showCopy) && (showPaste == info.showPaste) && (showCopyAll == info.showCopyAll) &&
255                  (showCut == info.showCut) && (showTranslate == info.showTranslate) &&
256                  (showSearch == info.showSearch) && (showShare == info.showShare) &&
257                  (showCameraInput == info.showCameraInput) && (showAIWrite == info.showAIWrite) &&
258                  (aiMenuOptionType == info.aiMenuOptionType) && !info.hasOnPrepareMenuCallback &&
259                  (isAskCeliaEnabled == info.isAskCeliaEnabled));
260     }
261 
ToStringSelectMenuInfo262     std::string ToString() const
263     {
264         auto jsonValue = JsonUtil::Create(true);
265         JSON_STRING_PUT_BOOL(jsonValue, menuDisable);
266         JSON_STRING_PUT_BOOL(jsonValue, menuIsShow);
267         JSON_STRING_PUT_BOOL(jsonValue, singleHandleMenuIsShow);
268         JSON_STRING_PUT_BOOL(jsonValue, showCopy);
269         JSON_STRING_PUT_BOOL(jsonValue, showPaste);
270         JSON_STRING_PUT_BOOL(jsonValue, showCopyAll);
271         JSON_STRING_PUT_BOOL(jsonValue, showCut);
272         JSON_STRING_PUT_BOOL(jsonValue, showTranslate);
273         JSON_STRING_PUT_BOOL(jsonValue, showSearch);
274         JSON_STRING_PUT_BOOL(jsonValue, showShare);
275         JSON_STRING_PUT_BOOL(jsonValue, showCameraInput);
276         JSON_STRING_PUT_INT(jsonValue, aiMenuOptionType);
277         JSON_STRING_PUT_INT(jsonValue, hasOnPrepareMenuCallback);
278         JSON_STRING_PUT_INT(jsonValue, isAskCeliaEnabled);
279         return jsonValue->ToString();
280     }
281 };
282 
283 struct SelectMenuCallback {
284     std::function<void()> onCopy;
285     std::function<void()> onPaste;
286     std::function<void()> onSelectAll;
287     std::function<void()> onCut;
288     std::function<void()> onTranslate;
289     std::function<void()> onSearch;
290     std::function<void()> onShare;
291     std::function<void()> onCameraInput;
292     std::function<void()> onAIWrite;
293     std::function<void(std::string)> onAIMenuOption;
294     std::function<void()> onAskCelia;
295 
296     std::function<void()> onAppear;
297     std::function<void()> onDisappear;
298     std::function<void()> onMenuShow;
299     std::function<void()> onMenuHide;
300     std::function<bool()> showMenuOnMoveDone;
301 };
302 
303 struct SelectedByMouseInfo {
304     WeakPtr<FrameNode> selectedNode;
305     std::function<void()> onResetSelection;
306 
307     bool operator!=(const SelectedByMouseInfo& info) const
308     {
309         CHECK_NULL_RETURN(selectedNode.Upgrade(), true);
310         CHECK_NULL_RETURN(info.selectedNode.Upgrade(), true);
311         return selectedNode.Upgrade() != info.selectedNode.Upgrade();
312     }
313 
clearSelectedByMouseInfo314     void clear()
315     {
316         selectedNode.Reset();
317         onResetSelection = nullptr;
318     }
319 };
320 
321 struct CallerFrameNodeInfo {
322     RectF paintFrameRect;
323     OffsetF paintOffset;
324 };
325 
326 enum class SelectOverlayMode {
327     ALL, MENU_ONLY, HANDLE_ONLY
328 };
329 
330 enum class HandleLevelMode {
331     OVERLAY, EMBED
332 };
333 
334 struct SelectOverlayInfo {
335     WeakPtr<Pattern> pattern;
336     bool isUsingMouse = false;
337     bool isSingleHandle = false;
338     // when handleReverse is true, The first one is on the right side of the second.
339     bool handleReverse = false;
340     // Used to determine the range of judgment that is parallel to the first and second handles.
341     float singleLineHeight = 10.0f;
342     bool isSelectRegionVisible = false;
343     bool isNewAvoid = false;
344     bool recreateOverlay = false;
345     bool isUseOverlayNG = false;
346     SelectHandleInfo firstHandle;
347     SelectHandleInfo secondHandle;
348     std::function<bool(const RectF&, const RectF&)> checkHandleReverse;
349     std::optional<Color> handlerColor;
350     HitTestMode hitTestMode = HitTestMode::HTMTRANSPARENT_SELF;
351 
352     // show area
353     bool useFullScreen = true;
354     RectF showArea;
355     RectF selectArea;
356 
357     OffsetF rightClickOffset;
358 
359     // handle touch event
360     std::function<void(const TouchEventInfo&)> onTouchDown;
361     std::function<void(const TouchEventInfo&)> onTouchUp;
362     std::function<void(const TouchEventInfo&)> onTouchMove;
363     std::function<void(const GestureEvent&, bool isFirst)> onClick;
364     std::function<void(const GestureEvent&, bool isFirst)> afterOnClick;
365     std::function<void(const MouseInfo&)> onMouseEvent;
366 
367     // handle move callback.
368     std::function<void(const GestureEvent&, bool isFirst)> onHandleMoveStart;
369     std::function<void(const RectF&, bool isFirst)> onHandleMove;
370     std::function<void(const RectF&, bool isFirst)> onHandleMoveDone;
371     std::function<void(bool)> onHandleReverse;
372 
373     std::function<void(const GestureEvent&, bool isFirst)> onHandlePanMove;
374     std::function<void(const GestureEvent&, bool isFirst)> onHandlePanEnd;
375     std::function<OffsetF()> getDeltaHandleOffset;
376 
377     // menu info.
378     SelectMenuInfo menuInfo;
379     SelectMenuCallback menuCallback;
380 
381     std::vector<MenuOptionsParam> menuOptionItems;
382     OnMenuItemCallback onCreateCallback;
383 
384     // force hide callback, which may be called when other textOverlay shows.
385     std::function<void(bool)> onClose;
386 
387     std::function<bool(const PointF&)> checkIsTouchInHostArea;
388     std::function<void()> onHandleIsHidden;
389 
390     OHOS::Ace::WeakPtr<FrameNode> callerFrameNode;
391     std::optional<CallerFrameNodeInfo> callerNodeInfo;
392     std::optional<RectF> ancestorViewPort;
393 
394     bool isHandleLineShow = true;
395     std::string selectText;
396     bool isSingleLine = false;
397 
398     HandleLevelMode handleLevelMode = HandleLevelMode::OVERLAY;
399     bool enableHandleLevel = false;
400     VectorF scale = VectorF(1.0f, 1.0f);
401     bool clipHandleDrawRect = false;
402     std::optional<RectF> clipViewPort;
403 
ToStringSelectOverlayInfo404     std::string ToString() const
405     {
406         auto jsonValue = JsonUtil::Create(true);
407         JSON_STRING_PUT_INT(jsonValue, handleLevelMode);
408         JSON_STRING_PUT_BOOL(jsonValue, isUsingMouse);
409         JSON_STRING_PUT_BOOL(jsonValue, isSingleHandle);
410         JSON_STRING_PUT_BOOL(jsonValue, handleReverse);
411         JSON_STRING_PUT_BOOL(jsonValue, isSelectRegionVisible);
412         JSON_STRING_PUT_BOOL(jsonValue, isNewAvoid);
413         JSON_STRING_PUT_BOOL(jsonValue, recreateOverlay);
414         JSON_STRING_PUT_BOOL(jsonValue, isUseOverlayNG);
415         JSON_STRING_PUT_STRINGABLE(jsonValue, firstHandle);
416         JSON_STRING_PUT_STRINGABLE(jsonValue, secondHandle);
417         JSON_STRING_PUT_STRINGABLE(jsonValue, showArea);
418         JSON_STRING_PUT_STRINGABLE(jsonValue, selectArea);
419         JSON_STRING_PUT_STRINGABLE(jsonValue, rightClickOffset);
420         JSON_STRING_PUT_STRING(jsonValue, selectText);
421         return jsonValue->ToString();
422     }
423 
424     void GetCallerNodeAncestorViewPort(RectF& viewPort);
425     const RectF& GetFirstHandlePaintRect();
426     const RectF& GetSecondHandlePaintRect();
427     bool enableSubWindowMenu = false;
428     OffsetF containerModalOffset;
429 
430     // menu avoid keyboard adjust ark_ui and web
431     std::function<bool(LayoutWrapper *, OffsetF &, const RectF, OffsetF &, std::shared_ptr<SelectOverlayInfo> &)>
432         computeMenuOffset = nullptr;
433 };
434 
435 enum class TextMenuShowMode {
436     BEGIN = -1,
437     UNSPECIFIED = BEGIN,
438     // Display the text selection menu in the current window
439     DEFAULT = 0,
440     /**
441      * Prefer to display the text selection menu in a separate window
442      * and continue to display it within the current window if a separate window is not supported
443      */
444     PREFER_WINDOW = 1,
445     END = PREFER_WINDOW,
446 };
447 
448 TextMenuShowMode CastToTextMenuShowMode(int32_t value);
449 
450 struct TextMenuOptions {
451     std::optional<TextMenuShowMode> showMode;
452 };
453 
454 #define DEFINE_MENU_CHECK_METHOD(name) bool IsShow##name()
455 
456 #define DEFINE_MENU_CHECK_METHOD_IMPL(name, flag) \
457 bool IsShow##name() {                             \
458     return !IsDisableMenuItem(flag);              \
459 }                                                 \
460 
461 namespace TextSystemMenu {
462 bool IsDisableMenuItem(SystemServiceMenuDisableFlag flag);
463 DEFINE_MENU_CHECK_METHOD(Translate);
464 DEFINE_MENU_CHECK_METHOD(Search);
465 DEFINE_MENU_CHECK_METHOD(Share);
466 DEFINE_MENU_CHECK_METHOD(CameraInput);
467 DEFINE_MENU_CHECK_METHOD(AIWriter);
468 DEFINE_MENU_CHECK_METHOD(CollaborationService);
469 DEFINE_MENU_CHECK_METHOD(AIUrl);
470 DEFINE_MENU_CHECK_METHOD(AIPhone);
471 DEFINE_MENU_CHECK_METHOD(AIEmail);
472 DEFINE_MENU_CHECK_METHOD(AIAddress);
473 DEFINE_MENU_CHECK_METHOD(AIDatetime);
474 DEFINE_MENU_CHECK_METHOD(AskCelia);
475 } // namespace TextSystemMenu
476 } // namespace OHOS::Ace::NG
477 
478 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SELECT_OVERLAY_PROPERTY_H
479