• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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_PATTERN_TEXT_TEXT_BASE_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_TEXT_BASE_H
18 
19 #include "base/memory/ace_type.h"
20 #include "core/common/container.h"
21 #include "core/components_ng/manager/select_overlay/select_overlay_client.h"
22 #include "core/components_ng/pattern/scrollable/scrollable_pattern.h"
23 #include "core/components_ng/pattern/text_field/text_selector.h"
24 #include "core/components_ng/render/drawing.h"
25 #include "core/components_ng/render/paragraph.h"
26 #include "core/common/container.h"
27 #include "core/pipeline_ng/pipeline_context.h"
28 
29 namespace OHOS::Ace::NG {
30 using ParagraphT = std::variant<std::shared_ptr<RSParagraph>, RefPtr<Paragraph>>;
31 
32 enum class MouseStatus { PRESSED, RELEASED, MOVE, NONE };
33 
34 struct HandleMoveStatus {
35     bool isFirsthandle = false;
36     int32_t position = -1;
37     OffsetF handleOffset;
38 
ResetHandleMoveStatus39     void Reset()
40     {
41         isFirsthandle = false;
42         position = -1;
43     }
44 
IsValidHandleMoveStatus45     bool IsValid()
46     {
47         return position >= 0;
48     }
49 };
50 
51 template<typename T>
GetTextCaretMetrics(RefPtr<FrameNode> & targetNode,CaretMetricsF & caretMetrics)52 void GetTextCaretMetrics(RefPtr<FrameNode>& targetNode, CaretMetricsF& caretMetrics)
53 {
54     CHECK_NULL_VOID(targetNode);
55     if (targetNode->GetTag() == V2::SEARCH_ETS_TAG) {
56         auto textFieldFrameNode = AceType::DynamicCast<FrameNode>(targetNode->GetChildren().front());
57         CHECK_NULL_VOID(textFieldFrameNode);
58         auto textPattern = textFieldFrameNode->GetPattern<T>();
59         CHECK_NULL_VOID(textPattern);
60         textPattern->GetCaretMetrics(caretMetrics);
61     } else {
62         auto textPattern = targetNode->GetPattern<T>();
63         CHECK_NULL_VOID(textPattern);
64         textPattern->GetCaretMetrics(caretMetrics);
65     }
66 }
67 class TextBase : public SelectOverlayClient {
68     DECLARE_ACE_TYPE(TextBase, SelectOverlayClient);
69 
70 public:
71     TextBase() = default;
72     ~TextBase() override = default;
73 
GetContentOffset()74     virtual OffsetF GetContentOffset()
75     {
76         return OffsetF(0, 0);
77     }
78 
OnBackPressed()79     virtual bool OnBackPressed()
80     {
81         return false;
82     }
83 
IsSelected()84     virtual bool IsSelected() const
85     {
86         return textSelector_.IsValid() && !textSelector_.StartEqualToDest();
87     }
88 
GetMouseStatus()89     MouseStatus GetMouseStatus() const
90     {
91         return mouseStatus_;
92     }
93 
SetSelectionNode(const SelectedByMouseInfo & info)94     static void SetSelectionNode(const SelectedByMouseInfo& info)
95     {
96         auto pipeline = PipelineContext::GetCurrentContext();
97         CHECK_NULL_VOID(pipeline);
98         auto selectOverlayManager = pipeline->GetSelectOverlayManager();
99         selectOverlayManager->SetSelectedNodeByMouse(info);
100     }
101 
102     static int32_t GetGraphemeClusterLength(const std::wstring& text, int32_t extend, bool checkPrev = false)
103     {
104         char16_t aroundChar = 0;
105         if (checkPrev) {
106             if (static_cast<size_t>(extend) <= text.length()) {
107                 aroundChar = text[std::max(0, extend - 1)];
108             }
109         } else {
110             if (static_cast<size_t>(extend) <= (text.length())) {
111                 aroundChar = text[std::min(static_cast<int32_t>(text.length() - 1), extend)];
112             }
113         }
114         return StringUtils::NotInUtf16Bmp(aroundChar) ? 2 : 1;
115     }
116 
CalculateSelectedRect(std::vector<RectF> & selectedRect,float longestLine)117     static void CalculateSelectedRect(std::vector<RectF>& selectedRect, float longestLine)
118     {
119         if (selectedRect.size() <= 1) {
120             return;
121         }
122         std::map<float, RectF> lineGroup;
123         for (auto const& localRect : selectedRect) {
124             if (NearZero(localRect.Width()) && NearZero(localRect.Height())) {
125                 continue;
126             }
127             auto it = lineGroup.find(localRect.GetY());
128             if (it == lineGroup.end()) {
129                 lineGroup.emplace(localRect.GetY(), localRect);
130             } else {
131                 auto lineRect = it->second;
132                 it->second = lineRect.CombineRectT(localRect);
133             }
134         }
135         selectedRect.clear();
136         auto firstRect = lineGroup.begin()->second;
137         if (lineGroup.size() == 1) {
138             selectedRect.emplace_back(firstRect);
139             return;
140         }
141         firstRect.SetWidth(longestLine - firstRect.Left());
142         selectedRect.emplace_back(firstRect);
143         auto endRect = lineGroup.rbegin()->second;
144         endRect.SetWidth(endRect.Right());
145         endRect.SetLeft(0.0f);
146         selectedRect.emplace_back(endRect);
147         const int32_t drawMiddleLineNumberLimit = 2;
148         if (static_cast<int32_t>(lineGroup.size()) > drawMiddleLineNumberLimit || firstRect.Left() <= endRect.Right()) {
149             auto middleRect = RectF(0.0f, firstRect.Bottom(), longestLine, endRect.Top() - firstRect.Bottom());
150             selectedRect.emplace_back(middleRect);
151         }
152     }
153 
154     // The methods that need to be implemented for input class components
GetCaretRect()155     virtual RectF GetCaretRect() const
156     {
157         return { 0, 0, 0, 0 };
158     }
159 
ScrollToSafeArea()160     virtual void ScrollToSafeArea() const {}
161 
UpdateKeyboardOffset(double positionY,double height)162     static void UpdateKeyboardOffset(double positionY, double height)
163     {
164         auto container = Container::Current();
165         CHECK_NULL_VOID(container);
166         auto context = PipelineContext::GetCurrentContext();
167         CHECK_NULL_VOID(context);
168 #ifdef WINDOW_SCENE_SUPPORTED
169         auto uiExtMgr = context->GetUIExtensionManager();
170         if (uiExtMgr && uiExtMgr->IsWindowTypeUIExtension(context)) {
171             return;
172         }
173 #endif
174         auto keyboardArea = container->GetKeyboardSafeArea();
175         auto keyboardLength = keyboardArea.bottom_.Length();
176         Rect keyboardRect;
177         keyboardRect.SetRect(0, keyboardArea.bottom_.start, 0, keyboardLength);
178         context->OnVirtualKeyboardAreaChange(keyboardRect, positionY, height);
179     }
180 
GetCaretMetrics(CaretMetricsF & caretCaretMetric)181     virtual void GetCaretMetrics(CaretMetricsF& caretCaretMetric) {}
182 
OnVirtualKeyboardAreaChanged()183     virtual void OnVirtualKeyboardAreaChanged() {}
184 
185 protected:
186     TextSelector textSelector_;
187     bool showSelect_ = true;
188     std::vector<std::string> dragContents_;
189     MouseStatus mouseStatus_ = MouseStatus::NONE;
190     ACE_DISALLOW_COPY_AND_MOVE(TextBase);
191 };
192 } // namespace OHOS::Ace::NG
193 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_TEXT_BASE_H
194