• 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_TEXT_OVERLAY_TEXT_OVERLAY_MANAGER_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_TEXT_OVERLAY_TEXT_OVERLAY_MANAGER_H
18 
19 #include "core/components/common/layout/constants.h"
20 #include "core/components/common/properties/color.h"
21 #include "frameworks/base/geometry/offset.h"
22 #include "frameworks/base/geometry/rect.h"
23 #include "frameworks/base/memory/ace_type.h"
24 #include "frameworks/core/common/ime/text_editing_value.h"
25 #include "frameworks/core/pipeline/base/overlay_show_option.h"
26 
27 namespace txt {
28 class Paragraph;
29 }
30 
31 class SkCanvas;
32 
33 namespace OHOS::Ace {
34 
35 class RenderNode;
36 class Animator;
37 class StackElement;
38 class PipelineContext;
39 class TextOverlayComponent;
40 class TextOverlayManager;
41 
42 enum class CursorPositionType {
43     NONE = 0,
44     END,      // end of paragraph
45     BOUNDARY, // boundary of LTR and RTL
46     NORMAL,
47 };
48 
49 enum class DirectionStatus : uint8_t {
50     LEFT_LEFT = 0, // System direction is LTR, text direction is LTR.
51     LEFT_RIGHT,
52     RIGHT_LEFT,
53     RIGHT_RIGHT,
54 };
55 
56 // Describe where caret is and how tall visually.
57 struct CaretMetrics {
ResetCaretMetrics58     void Reset()
59     {
60         offset.Reset();
61         height = 0.0;
62     }
63 
64     Offset offset;
65     // When caret is close to different glyphs, the height will be different.
66     double height = 0.0;
ToStringCaretMetrics67     std::string ToString() const
68     {
69         std::string result = "Offset: ";
70         result += offset.ToString();
71         result += ", height: ";
72         result += std::to_string(height);
73         return result;
74     }
75 };
76 
77 class TextOverlayBase : public virtual AceType {
78     DECLARE_ACE_TYPE(TextOverlayBase, AceType);
79 
80 public:
81     TextOverlayBase() = default;
82     ~TextOverlayBase() override;
83 
SetUpdateHandlePosition(const std::function<void (const OverlayShowOption &)> & updateHandlePosition)84     void SetUpdateHandlePosition(const std::function<void(const OverlayShowOption&)>& updateHandlePosition)
85     {
86         updateHandlePosition_ = updateHandlePosition;
87     }
88 
SetUpdateHandleDiameter(const std::function<void (const double &)> & updateHandleDiameter)89     void SetUpdateHandleDiameter(const std::function<void(const double&)>& updateHandleDiameter)
90     {
91         updateHandleDiameter_ = updateHandleDiameter;
92     }
93 
SetUpdateHandleDiameterInner(const std::function<void (const double &)> & updateHandleDiameterInner)94     void SetUpdateHandleDiameterInner(const std::function<void(const double&)>& updateHandleDiameterInner)
95     {
96         updateHandleDiameterInner_ = updateHandleDiameterInner;
97     }
98 
SetOnClipRectChanged(const std::function<void (const Rect &)> & onClipRectChanged)99     void SetOnClipRectChanged(const std::function<void(const Rect&)>& onClipRectChanged)
100     {
101         onClipRectChanged_ = onClipRectChanged;
102     }
103 
IsSelectiveDevice()104     static bool IsSelectiveDevice()
105     {
106         return (SystemProperties::GetDeviceType() != DeviceType::TV &&
107                 SystemProperties::GetDeviceType() != DeviceType::WATCH);
108     }
109 
MarkIsOverlayShowed(bool isOverlayShowed)110     void MarkIsOverlayShowed(bool isOverlayShowed)
111     {
112         isOverlayShowed_ = isOverlayShowed;
113     }
114 
IsOverlayShowed()115     bool IsOverlayShowed() const
116     {
117         return isOverlayShowed_;
118     }
119 
GetSelectedRect()120     const std::vector<Rect>& GetSelectedRect() const
121     {
122         return selectedRect_;
123     }
124 
GetSelectHeight()125     double GetSelectHeight() const
126     {
127         return selectHeight_;
128     }
129 
130     void ChangeSelection(int32_t start, int32_t end);
131     void InitAnimation(const WeakPtr<PipelineContext>& pipelineContext);
132     bool GetCaretRect(int32_t extent, Rect& caretRect, double caretHeightOffset = 0.0) const;
133     void PaintSelection(SkCanvas* canvas, const Offset& globalOffset);
134     virtual void InitSelection(const Offset& pos, const Offset& globalOffset);
135     virtual void UpdateStartSelection(int32_t end, const Offset& pos, const Offset& globalOffset);
136     virtual void UpdateEndSelection(int32_t start, const Offset& pos, const Offset& globalOffset);
137     virtual void ShowTextOverlay(const Offset& showOffset) = 0;
138     virtual void RegisterCallbacksToOverlay() = 0;
139     virtual Offset GetHandleOffset(int32_t extend) = 0;
140     virtual std::string GetSelectedContent() const = 0;
141     RefPtr<TextOverlayManager> GetTextOverlayManager(const WeakPtr<PipelineContext>& pipelineContext);
142     bool IsSelectedText(const Offset& pos, const Offset& globalOffset);
143 
144 protected:
145     std::shared_ptr<txt::Paragraph> paragraph_;
146     CursorPositionType cursorPositionType_ = CursorPositionType::NORMAL;
147     DirectionStatus directionStatus_ = DirectionStatus::LEFT_LEFT;
148     Offset clickOffset_;
149     // For ensuring caret is visible on screen, we take a strategy that move the whole text painting area.
150     // It maybe seems rough, and doesn't support scrolling smoothly.
151     Offset textOffsetForShowCaret_;
152     // An outline for caret. It is used by default when the actual size cannot be retrieved.
153     Rect caretProto_;
154     Rect textOverlayPaintRect_;
155     Color selectedColor_ = Color(0x330a59f7);
156     double selectHeight_ = 0.0;
157     // Default to the start of text (according to RTL/LTR).
158     TextAlign textAlign_ = TextAlign::START;
159     // RTL/LTR is inherit from parent.
160     TextDirection defaultTextDirection_ = TextDirection::INHERIT;
161     TextDirection realTextDirection_ = TextDirection::INHERIT;
162     TextAffinity textAffinity_ = TextAffinity::DOWNSTREAM;
163     TextEditingValue textValue_;
164     std::string textForDisplay_;
165     int32_t cursorPositionForShow_ = 0;
166     double cursorWidth_ = 0.0;     // The unit is px.
167     bool isOverlayShowed_ = false; // Whether overlay has showed.
168     RefPtr<Animator> animator_;
169     std::function<void(const OverlayShowOption&)> updateHandlePosition_;
170     std::function<void(const double&)> updateHandleDiameter_;
171     std::function<void(const double&)> updateHandleDiameterInner_;
172     std::function<void(const Rect&)> onClipRectChanged_;
173     RefPtr<TextOverlayComponent> textOverlay_;
174     std::vector<Rect> selectedRect_;
175 
176 private:
177     Offset MakeEmptyOffset() const;
178     double GetBoundaryOfParagraph(bool isLeftBoundary) const;
179     bool ComputeOffsetForCaretUpstream(int32_t extent, CaretMetrics& result) const;
180     bool ComputeOffsetForCaretDownstream(int32_t extent, CaretMetrics& result) const;
181     bool ComputeOffsetForCaretCloserToClick(int32_t extent, CaretMetrics& result) const;
182     DirectionStatus GetDirectionStatusOfPosition(int32_t position) const;
183     int32_t GetCursorPositionForClick(const Offset& offset, const Offset& globalOffset);
184     int32_t GetGraphemeClusterLength(int32_t extend, bool isPrefix) const;
185 };
186 
187 class PipelineContext;
188 class TextOverlayManager : public virtual AceType {
189     DECLARE_ACE_TYPE(TextOverlayManager, AceType);
190 
191 public:
192     explicit TextOverlayManager(const WeakPtr<PipelineContext>& context);
193     ~TextOverlayManager() override;
194 
SetTextOverlayBase(const WeakPtr<TextOverlayBase> & textOverlayBase)195     void SetTextOverlayBase(const WeakPtr<TextOverlayBase>& textOverlayBase)
196     {
197         textOverlayBase_ = textOverlayBase;
198     }
199 
GetTextOverlayBase()200     const RefPtr<TextOverlayBase> GetTextOverlayBase() const
201     {
202         auto textOverlayBase = textOverlayBase_.Upgrade();
203         if (!textOverlayBase) {
204             return nullptr;
205         }
206         return textOverlayBase;
207     }
208 
GetTextOverlayRect()209     const std::vector<Rect>& GetTextOverlayRect() const
210     {
211         return textOverlayRect_;
212     }
213 
AddTextOverlayRect(const Rect & textOverlayRect)214     void AddTextOverlayRect(const Rect& textOverlayRect)
215     {
216         textOverlayRect_.emplace_back(textOverlayRect);
217     }
218 
ClearTextOverlayRect()219     void ClearTextOverlayRect()
220     {
221         textOverlayRect_.clear();
222     }
223 
224     // Coordinate offset is used to calculate the local location of the touch point in the event manager.
SetCoordinateOffset(const Offset & coordinateOffset)225     void SetCoordinateOffset(const Offset& coordinateOffset)
226     {
227         coordinateOffset_ = coordinateOffset;
228     }
229 
230     // Gets the coordinate offset to calculate the local location of the touch point by manually.
GetCoordinateOffset()231     const Offset& GetCoordinateOffset() const
232     {
233         return coordinateOffset_;
234     }
235 
236     const RefPtr<RenderNode> GetTargetNode() const;
237     void PopTextOverlay();
238     void PushTextOverlayToStack(
239         const RefPtr<TextOverlayComponent>& textOverlay, const WeakPtr<PipelineContext>& context);
240 
241     void HandleCtrlC() const;
242 
243 private:
244     WeakPtr<TextOverlayBase> textOverlayBase_;
245     WeakPtr<StackElement> stackElement_;
246     WeakPtr<PipelineContext> context_;
247     std::vector<Rect> textOverlayRect_;
248     Offset coordinateOffset_;
249 };
250 
251 } // namespace OHOS::Ace
252 
253 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_TEXT_OVERLAY_TEXT_OVERLAY_MANAGER_H
254