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