• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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_TEXT_TEXT_PATTERN_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TEXT_TEXT_PATTERN_H
18 
19 #include <optional>
20 #include <string>
21 
22 #include "base/geometry/dimension.h"
23 #include "base/geometry/ng/offset_t.h"
24 #include "base/memory/referenced.h"
25 #include "base/utils/noncopyable.h"
26 #include "base/utils/utils.h"
27 #include "core/components_ng/event/long_press_event.h"
28 #include "core/components_ng/pattern/pattern.h"
29 #include "core/components_ng/pattern/text/span_node.h"
30 #include "core/components_ng/pattern/text/text_base.h"
31 #include "core/components_ng/pattern/text/text_accessibility_property.h"
32 #include "core/components_ng/pattern/text/text_content_modifier.h"
33 #include "core/components_ng/pattern/text/text_layout_algorithm.h"
34 #include "core/components_ng/pattern/text/text_layout_property.h"
35 #include "core/components_ng/pattern/text/text_overlay_modifier.h"
36 #include "core/components_ng/pattern/text/text_paint_method.h"
37 #include "core/components_ng/pattern/text_drag/text_drag_base.h"
38 #include "core/components_ng/pattern/text_field/text_selector.h"
39 #include "core/components_ng/property/property.h"
40 #include "core/pipeline_ng/ui_task_scheduler.h"
41 
42 namespace OHOS::Ace::NG {
43 // TextPattern is the base class for text render node to perform paint text.
44 class TextPattern : public Pattern, public TextDragBase, public TextBase {
45     DECLARE_ACE_TYPE(TextPattern, Pattern, TextDragBase, TextBase);
46 
47 public:
48     TextPattern() = default;
49     ~TextPattern() override = default;
50 
CreateNodePaintMethod()51     RefPtr<NodePaintMethod> CreateNodePaintMethod() override
52     {
53         if (!textContentModifier_) {
54             textContentModifier_ = MakeRefPtr<TextContentModifier>(textStyle_);
55         }
56         if (!textOverlayModifier_) {
57             textOverlayModifier_ = MakeRefPtr<TextOverlayModifier>();
58         }
59         if (isCustomFont_) {
60             textContentModifier_->SetIsCustomFont(true);
61         }
62         auto paintMethod = MakeRefPtr<TextPaintMethod>(
63             WeakClaim(this), paragraph_, baselineOffset_, textContentModifier_, textOverlayModifier_);
64         auto host = GetHost();
65         CHECK_NULL_RETURN(host, paintMethod);
66         auto context = host->GetRenderContext();
67         CHECK_NULL_RETURN(context, paintMethod);
68         if (context->GetClipEdge().has_value()) {
69             auto geometryNode = host->GetGeometryNode();
70             auto frameOffset = geometryNode->GetFrameOffset();
71             auto frameSize = geometryNode->GetFrameSize();
72             CHECK_NULL_RETURN(paragraph_, paintMethod);
73             auto height = static_cast<float>(paragraph_->GetHeight() + std::fabs(baselineOffset_));
74             if (context->GetClipEdge().value() == false && LessNotEqual(frameSize.Height(), height)) {
75                 RectF boundsRect(frameOffset.GetX(), frameOffset.GetY(), frameSize.Width(), height);
76                 textOverlayModifier_->SetBoundsRect(boundsRect);
77             }
78         }
79         return paintMethod;
80     }
81 
CreateLayoutProperty()82     RefPtr<LayoutProperty> CreateLayoutProperty() override
83     {
84         return MakeRefPtr<TextLayoutProperty>();
85     }
86 
CreateLayoutAlgorithm()87     RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override
88     {
89         return MakeRefPtr<TextLayoutAlgorithm>(spanItemChildren_, paragraph_);
90     }
91 
CreateAccessibilityProperty()92     RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override
93     {
94         return MakeRefPtr<TextAccessibilityProperty>();
95     }
96 
IsAtomicNode()97     bool IsAtomicNode() const override
98     {
99         return false;
100     }
101 
DefaultSupportDrag()102     bool DefaultSupportDrag() override
103     {
104         return true;
105     }
106 
107     void OnModifyDone() override;
108 
109     void BeforeCreateLayoutWrapper() override;
110 
111     void AddChildSpanItem(const RefPtr<UINode>& child);
112 
GetFocusPattern()113     FocusPattern GetFocusPattern() const override
114     {
115         return { FocusType::NODE, false };
116     }
117 
118     void DumpInfo() override;
119 
GetTextSelector()120     TextSelector GetTextSelector() const
121     {
122         return textSelector_;
123     }
124 
GetTextForDisplay()125     std::string GetTextForDisplay() const
126     {
127         return textForDisplay_;
128     }
129 
GetStartOffset()130     const OffsetF& GetStartOffset() const
131     {
132         return textSelector_.selectionBaseOffset;
133     }
134 
GetEndOffset()135     const OffsetF& GetEndOffset() const
136     {
137         return textSelector_.selectionDestinationOffset;
138     }
139 
GetSelectHeight()140     double GetSelectHeight() const
141     {
142         return textSelector_.GetSelectHeight();
143     }
144 
145     void GetGlobalOffset(Offset& offset);
146 
GetTextContentRect()147     const RectF& GetTextContentRect() const override
148     {
149         return contentRect_;
150     }
151 
GetBaselineOffset()152     float GetBaselineOffset() const
153     {
154         return baselineOffset_;
155     }
156 
GetContentModifier()157     RefPtr<TextContentModifier> GetContentModifier()
158     {
159         return textContentModifier_;
160     }
161 
SetMenuOptionItems(std::vector<MenuOptionsParam> && menuOptionItems)162     void SetMenuOptionItems(std::vector<MenuOptionsParam>&& menuOptionItems)
163     {
164         menuOptionItems_ = std::move(menuOptionItems);
165     }
166 
GetMenuOptionItems()167     const std::vector<MenuOptionsParam>&& GetMenuOptionItems() const
168     {
169         return std::move(menuOptionItems_);
170     }
171 
172     void OnVisibleChange(bool isVisible) override;
173 
GetSpanItemChildren()174     std::list<RefPtr<SpanItem>> GetSpanItemChildren()
175     {
176         return spanItemChildren_;
177     }
178 
GetDisplayWideTextLength()179     int32_t GetDisplayWideTextLength()
180     {
181         return StringUtils::ToWstring(textForDisplay_).length();
182     }
183 
184     // ===========================================================
185     // TextDragBase implementations
186 
IsTextArea()187     bool IsTextArea() const override
188     {
189         return false;
190     }
191 
GetTextRect()192     const RectF& GetTextRect() override
193     {
194         return contentRect_;
195     }
196     float GetLineHeight() const override;
197 
198     std::vector<RSTypographyProperties::TextBox> GetTextBoxes() override;
199     OffsetF GetParentGlobalOffset() const override;
200 
MoveDragNode()201     RefPtr<FrameNode> MoveDragNode() override
202     {
203         return std::move(dragNode_);
204     }
205 
GetDragParagraph()206     ParagraphT GetDragParagraph() const override
207     {
208         return { paragraph_ };
209     }
210 
CloseKeyboard(bool)211     bool CloseKeyboard(bool /* forceClose */) override
212     {
213         return true;
214     }
215     virtual void CloseSelectOverlay() override;
216     void CloseSelectOverlay(bool animation);
217     void CreateHandles() override;
218 
219     bool BetweenSelectedPosition(const Offset& globalOffset) override;
220 
221     // end of TextDragBase implementations
222     // ===========================================================
223 
224     void InitSurfaceChangedCallback();
225     void InitSurfacePositionChangedCallback();
226     virtual void HandleSurfaceChanged(int32_t newWidth, int32_t newHeight, int32_t prevWidth, int32_t prevHeight);
HandleSurfacePositionChanged(int32_t posX,int32_t posY)227     virtual void HandleSurfacePositionChanged(int32_t posX, int32_t posY) {};
HasSurfaceChangedCallback()228     bool HasSurfaceChangedCallback()
229     {
230         return surfaceChangedCallbackId_.has_value();
231     }
UpdateSurfaceChangedCallbackId(int32_t id)232     void UpdateSurfaceChangedCallbackId(int32_t id)
233     {
234         surfaceChangedCallbackId_ = id;
235     }
236 
HasSurfacePositionChangedCallback()237     bool HasSurfacePositionChangedCallback()
238     {
239         return surfacePositionChangedCallbackId_.has_value();
240     }
UpdateSurfacePositionChangedCallbackId(int32_t id)241     void UpdateSurfacePositionChangedCallbackId(int32_t id)
242     {
243         surfacePositionChangedCallbackId_ = id;
244     }
245 
SetOnClickEvent(GestureEventFunc && onClick)246     void SetOnClickEvent(GestureEventFunc&& onClick)
247     {
248         onClick_ = std::move(onClick);
249     }
250     void OnColorConfigurationUpdate() override;
251 
252 #ifdef ENABLE_DRAG_FRAMEWORK
253     DragDropInfo OnDragStart(const RefPtr<Ace::DragEvent>& event, const std::string& extraParams);
254     void InitDragEvent();
255     virtual std::function<void(Offset)> GetThumbnailCallback();
256 #endif
257 
InitSpanImageLayout(const std::vector<int32_t> & placeHolderIndex,const std::vector<Rect> & rectsForPlaceholders,OffsetF contentOffset)258     void InitSpanImageLayout(const std::vector<int32_t>& placeHolderIndex,
259         const std::vector<Rect>& rectsForPlaceholders, OffsetF contentOffset) override
260     {
261         placeHolderIndex_ = placeHolderIndex;
262         imageOffset_ = contentOffset;
263         rectsForPlaceholders_ = rectsForPlaceholders;
264     }
265 
GetPlaceHolderIndex()266     const std::vector<int32_t>& GetPlaceHolderIndex()
267     {
268         return placeHolderIndex_;
269     }
270 
GetRectsForPlaceholders()271     const std::vector<Rect>& GetRectsForPlaceholders()
272     {
273         return rectsForPlaceholders_;
274     }
275 
GetContentOffset()276     OffsetF GetContentOffset() override
277     {
278         return imageOffset_;
279     }
280 
IsMeasureBoundary()281     bool IsMeasureBoundary() const override
282     {
283         return isMeasureBoundary_;
284     }
285 
SetIsMeasureBoundary(bool isMeasureBoundary)286     void SetIsMeasureBoundary(bool isMeasureBoundary)
287     {
288         isMeasureBoundary_ = isMeasureBoundary;
289     }
290 
SetIsCustomFont(bool isCustomFont)291     void SetIsCustomFont(bool isCustomFont)
292     {
293         isCustomFont_ = isCustomFont;
294     }
295 
GetIsCustomFont()296     bool GetIsCustomFont()
297     {
298         return isCustomFont_;
299     }
300     void UpdateSelectOverlayOrCreate(SelectOverlayInfo selectInfo, bool animation = false);
301     void CheckHandles(SelectHandleInfo& handleInfo);
302     OffsetF GetDragUpperLeftCoordinates() override;
303 
304 protected:
305     virtual void HandleOnCopy();
306     void InitMouseEvent();
307     void ResetSelection();
308     virtual void HandleOnSelectAll();
309     void InitSelection(const Offset& pos);
310     void HandleLongPress(GestureEvent& info);
311     void HandleClickEvent(GestureEvent& info);
312     bool IsDraggable(const Offset& localOffset);
313     void InitClickEvent(const RefPtr<GestureEventHub>& gestureHub);
314     void CalculateHandleOffsetAndShowOverlay(bool isUsingMouse = false);
315     void ShowSelectOverlay(const RectF& firstHandle, const RectF& secondHandle);
316     void ShowSelectOverlay(const RectF& firstHandle, const RectF& secondHandle, bool animation);
317     int32_t GetGraphemeClusterLength(int32_t extend) const;
318     bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override;
319     bool IsSelectAll();
320     virtual void OnHandleMoveDone(const RectF& handleRect, bool isFirstHandle);
321     virtual void OnHandleMove(const RectF& handleRect, bool isFirstHandle);
322     std::wstring GetWideText() const;
323     std::string GetSelectedText(int32_t start, int32_t end) const;
324     OffsetF CalcCursorOffsetByPosition(int32_t position, float& selectLineHeight);
325     RectF contentRect_;
326     WeakPtr<FrameNode> dragNodeWk_;
327     RefPtr<FrameNode> dragNode_;
328     RefPtr<Paragraph> paragraph_;
329     RefPtr<LongPressEvent> longPressEvent_;
330     RefPtr<SelectOverlayProxy> selectOverlayProxy_;
331     RefPtr<Clipboard> clipboard_;
332     CopyOptions copyOption_ = CopyOptions::None;
333 
334     OffsetF imageOffset_;
335     std::string textForDisplay_;
336     std::optional<TextStyle> textStyle_;
337     std::list<RefPtr<SpanItem>> spanItemChildren_;
338     std::vector<MenuOptionsParam> menuOptionItems_;
339     std::vector<int32_t> placeHolderIndex_;
340     float baselineOffset_ = 0.0f;
341     bool clickEventInitialized_ = false;
342     bool mouseEventInitialized_ = false;
343     bool touchEventInitialized_ = false;
344     std::vector<Rect> rectsForPlaceholders_;
345     int32_t imageCount_ = 0;
346     SelectMenuInfo selectMenuInfo_;
347     bool isMeasureBoundary_ = false;
348     bool isCustomFont_ = false;
349     std::vector<RSTypographyProperties::TextBox> dragBoxes_;
350     bool ignoreEvent_ = false;
351 
352 private:
353     void OnDetachFromFrameNode(FrameNode* node) override;
354     void OnAttachToFrameNode() override;
355     void InitLongPressEvent(const RefPtr<GestureEventHub>& gestureHub);
356     void HandleMouseEvent(const MouseInfo& info);
357     void OnHandleTouchUp();
358     void InitPanEvent(const RefPtr<GestureEventHub>& gestureHub);
359     void HandlePanStart(const GestureEvent& info);
360     void HandlePanUpdate(const GestureEvent& info);
361     void HandlePanEnd(const GestureEvent& info);
362     void InitTouchEvent();
363     void HandleTouchEvent(const TouchEventInfo& info);
364     inline RSTypographyProperties::TextBox ConvertRect(const Rect& rect);
365     void UpdateChildProperty(const RefPtr<SpanNode>& child) const;
366     void ActSetSelection(int32_t start, int32_t end);
367     void SetAccessibilityAction();
368     void CollectSpanNodes(std::stack<RefPtr<UINode>> nodes, bool& isSpanHasClick);
369     // to check if drag is in progress
370 
371     OffsetF contentOffset_;
372     GestureEventFunc onClick_;
373     bool panEventInitialized_ = false;
374     bool isMousePressed_ = false;
375     bool blockPress_ = false;
376     RefPtr<DragWindow> dragWindow_;
377     RefPtr<DragDropProxy> dragDropProxy_;
378     RefPtr<TextContentModifier> textContentModifier_;
379     RefPtr<TextOverlayModifier> textOverlayModifier_;
380     std::optional<int32_t> surfaceChangedCallbackId_;
381     std::optional<int32_t> surfacePositionChangedCallbackId_;
382     ACE_DISALLOW_COPY_AND_MOVE(TextPattern);
383 };
384 } // namespace OHOS::Ace::NG
385 
386 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_TEXT_TEXT_PATTERN_H
387