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