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_PATTERN_TEXT_DRAG_TEXT_DRAG_PATTERN_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_DRAG_TEXT_DRAG_PATTERN_H 18 19 #include "base/memory/referenced.h" 20 #include "core/components_ng/pattern/text_drag/text_drag_base.h" 21 #include "core/components_ng/pattern/text_drag/text_drag_overlay_modifier.h" 22 #include "core/components_ng/pattern/text_drag/text_drag_paint_method.h" 23 #include "core/components_ng/pattern/rich_editor_drag/rich_editor_drag_info.h" 24 #include "core/components_ng/render/drawing.h" 25 #include "core/components_ng/render/paragraph.h" 26 27 namespace OHOS::Ace::NG { 28 constexpr Dimension TEXT_DRAG_RADIUS_2IN1 = 8.0_vp; 29 constexpr Dimension TEXT_DRAG_RADIUS = 18.0_vp; 30 constexpr Dimension TEXT_DRAG_OFFSET = 8.0_vp; 31 constexpr Dimension TEXT_DRAG_MIN_WIDTH = 64.0_vp; 32 constexpr uint32_t TEXT_DRAG_COLOR_BG = 0xf2ffffff; 33 34 struct SelectPositionInfo { SelectPositionInfoSelectPositionInfo35 SelectPositionInfo() {} SelectPositionInfoSelectPositionInfo36 SelectPositionInfo(float startX, float startY, float endX, float endY) 37 : startX_(startX), startY_(startY), endX_(endX), endY_(endY) 38 {} 39 InitGlobalInfoSelectPositionInfo40 void InitGlobalInfo(float globalX, float globalY) 41 { 42 globalX_ = globalX; 43 globalY_ = globalY; 44 } 45 46 float startX_ = 0; 47 float startY_ = 0; 48 float endX_ = 0; 49 float endY_ = 0; 50 float globalX_ = 0; 51 float globalY_ = 0; 52 }; 53 54 struct TextDragData { TextDragDataTextDragData55 TextDragData() {} TextDragDataTextDragData56 TextDragData(RectF textRect, float frameWidth, float frameHeight, float lineHeight, float lastLineHeight) 57 : textRect_(textRect), frameWidth_(frameWidth), frameHeight_(frameHeight), lineHeight_(lineHeight), 58 lastLineHeight_(lastLineHeight) 59 {} 60 61 RectF textRect_; 62 float frameWidth_ = 0; 63 float frameHeight_ = 0; 64 float lineHeight_ = 0; 65 float lastLineHeight_ = 0; 66 SelectPositionInfo selectPosition_; 67 bool oneLineSelected_ = false; initSelecitonInfoTextDragData68 void initSelecitonInfo(SelectPositionInfo selectionInfo, bool oneLineSelected) 69 { 70 selectPosition_ = selectionInfo; 71 oneLineSelected_ = oneLineSelected; 72 } 73 }; 74 75 struct TextPoint { TextPointTextPoint76 TextPoint() {} TextPointTextPoint77 TextPoint(float x, float y) : x(x), y(y) {} 78 79 float x = 0; 80 float y = 0; 81 }; 82 83 class TextDragPattern : public Pattern { 84 DECLARE_ACE_TYPE(TextDragPattern, Pattern); 85 86 public: 87 TextDragPattern() = default; 88 ~TextDragPattern() override = default; 89 90 static RefPtr<FrameNode> CreateDragNode(const RefPtr<FrameNode>& hostNode); 91 Initialize(const RefPtr<Paragraph> & paragraph,const TextDragData & data)92 void Initialize(const RefPtr<Paragraph>& paragraph, const TextDragData& data) 93 { 94 paragraph_ = paragraph; 95 textDragData_ = data; 96 } 97 UpdateParagraph(const RefPtr<Paragraph> & paragraph)98 void UpdateParagraph(const RefPtr<Paragraph>& paragraph) 99 { 100 paragraph_ = paragraph; 101 } 102 CreateNodePaintMethod()103 RefPtr<NodePaintMethod> CreateNodePaintMethod() override 104 { 105 if (!overlayModifier_) { 106 overlayModifier_ = AceType::MakeRefPtr<TextDragOverlayModifier>(WeakClaim(this)); 107 } 108 auto paintMethod = AceType::MakeRefPtr<TextDragPaintMethod>(WeakClaim(this), overlayModifier_); 109 paintMethod->UpdateHandleInfo(info_); 110 return paintMethod; 111 } 112 GetParagraph()113 const WeakPtr<Paragraph>& GetParagraph() const 114 { 115 return paragraph_; 116 } 117 GetOverlayModifier()118 virtual const RefPtr<TextDragOverlayModifier>& GetOverlayModifier() const 119 { 120 return overlayModifier_; 121 } 122 GetTextRect()123 const RectF& GetTextRect() const 124 { 125 return textDragData_.textRect_; 126 } 127 GetFrameWidth()128 float GetFrameWidth() const 129 { 130 return textDragData_.frameWidth_; 131 } 132 GetFrameHeight()133 float GetFrameHeight() const 134 { 135 return textDragData_.frameHeight_; 136 } 137 GetLineHeight()138 float GetLineHeight() const 139 { 140 return textDragData_.lineHeight_; 141 } 142 GetSelectPosition()143 const SelectPositionInfo& GetSelectPosition() const 144 { 145 return textDragData_.selectPosition_; 146 } 147 OneLineSelected()148 bool OneLineSelected() const 149 { 150 return textDragData_.oneLineSelected_; 151 } 152 GetClipPath()153 const std::shared_ptr<RSPath>& GetClipPath() 154 { 155 if (!clipPath_) { 156 clipPath_ = GenerateClipPath(); 157 } 158 return clipPath_; 159 } 160 GetBackgroundPath()161 const std::shared_ptr<RSPath>& GetBackgroundPath() 162 { 163 if (!backGroundPath_) { 164 backGroundPath_ = GenerateBackgroundPath(TEXT_DRAG_OFFSET.ConvertToPx()); 165 } 166 return backGroundPath_; 167 } 168 GetSelBackgroundPath()169 const std::shared_ptr<RSPath>& GetSelBackgroundPath() 170 { 171 if (!selBackGroundPath_) { 172 selBackGroundPath_ = GenerateSelBackgroundPath(0.0); 173 } 174 return selBackGroundPath_; 175 } 176 177 std::shared_ptr<RSPath> GenerateBackgroundPath(float offset, float radiusRatio = 1.0f); 178 179 std::shared_ptr<RSPath> GenerateSelBackgroundPath(float offset); 180 SetImageChildren(const std::list<RefPtr<FrameNode>> & imageChildren)181 void SetImageChildren(const std::list<RefPtr<FrameNode>>& imageChildren) 182 { 183 imageChildren_ = imageChildren; 184 } 185 GetImageChildren()186 const std::list<RefPtr<FrameNode>>& GetImageChildren() 187 { 188 return imageChildren_; 189 } 190 InitSpanImageLayout(const std::list<RefPtr<FrameNode>> & imageChildren,const std::vector<RectF> & rectsForPlaceholders)191 void InitSpanImageLayout( 192 const std::list<RefPtr<FrameNode>>& imageChildren, const std::vector<RectF>& rectsForPlaceholders) 193 { 194 imageChildren_ = imageChildren; 195 rectsForPlaceholders_ = rectsForPlaceholders; 196 } 197 GetContentOffset()198 OffsetF GetContentOffset() 199 { 200 return contentOffset_; 201 } 202 SetContentOffset(OffsetF contentOffset)203 void SetContentOffset(OffsetF contentOffset) 204 { 205 contentOffset_ = contentOffset; 206 } 207 GetRectsForPlaceholders()208 const std::vector<RectF>& GetRectsForPlaceholders() 209 { 210 return rectsForPlaceholders_; 211 } 212 213 virtual Dimension GetDragCornerRadius(); 214 UpdateHandleAnimationInfo(const TextDragInfo & info)215 void UpdateHandleAnimationInfo(const TextDragInfo& info) 216 { 217 info_ = info; 218 } 219 220 void OnDetachFromMainTree() override; 221 Color GetDragBackgroundColor(); 222 IsAnimating()223 bool IsAnimating() 224 { 225 return overlayModifier_ && overlayModifier_->IsAnimating(); 226 } 227 UpdateAnimatingParagraph()228 void UpdateAnimatingParagraph() 229 { 230 animatingParagraph_ = paragraph_.Upgrade(); 231 } 232 ResetAnimatingParagraph()233 void ResetAnimatingParagraph() 234 { 235 animatingParagraph_.Reset(); 236 } 237 protected: 238 static TextDragData CalculateTextDragData(RefPtr<TextDragBase>& pattern, RefPtr<FrameNode>& dragNode); 239 virtual void AdjustMaxWidth(float& width, const RectF& contentRect, const std::vector<RectF>& boxes); 240 static RectF GetHandler(const bool isLeftHandler, const std::vector<RectF> boxes, const RectF contentRect, 241 const OffsetF globalOffset, const OffsetF textStartOffset); 242 static void AdjustHandlers(const RectF contentRect, RectF& leftHandler, RectF& rightHandler); 243 bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override; 244 std::shared_ptr<RSPath> GenerateClipPath(); 245 void GenerateBackgroundPoints(std::vector<TextPoint>& points, float offset, bool needAdjust = true); 246 void CalculateLineAndArc(std::vector<TextPoint>& points, std::shared_ptr<RSPath>& path, float radiusRatio); 247 void CalculateLine(std::vector<TextPoint>& points, std::shared_ptr<RSPath>& path); 248 static void CalculateOverlayOffset(RefPtr<FrameNode>& dragNode, OffsetF& offset); 249 static void DropBlankLines(std::vector<RectF>& boxes); 250 SetLastLineHeight(float lineHeight)251 void SetLastLineHeight(float lineHeight) 252 { 253 lastLineHeight_ = lineHeight; 254 } 255 SetOnDetachFromMainTree(std::function<void ()> && callback)256 void SetOnDetachFromMainTree(std::function<void()>&& callback) 257 { 258 onDetachFromMainTree_ = std::move(callback); 259 } 260 261 protected: 262 RefPtr<TextDragOverlayModifier> overlayModifier_; 263 264 TextDragData textDragData_; 265 private: 266 float lastLineHeight_ = 0.0f; 267 OffsetF contentOffset_; 268 WeakPtr<Paragraph> paragraph_; 269 RefPtr<Paragraph> animatingParagraph_; 270 std::shared_ptr<RSPath> clipPath_; 271 std::shared_ptr<RSPath> backGroundPath_; 272 std::shared_ptr<RSPath> selBackGroundPath_; 273 std::list<RefPtr<FrameNode>> imageChildren_; 274 std::vector<RectF> rectsForPlaceholders_; 275 TextDragInfo info_; 276 std::function<void()> onDetachFromMainTree_ = nullptr; 277 278 ACE_DISALLOW_COPY_AND_MOVE(TextDragPattern); 279 }; 280 } // namespace OHOS::Ace::NG 281 282 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_DRAG_TEXT_DRAG_PATTERN_H 283