1 /* 2 * Copyright (c) 2023-2024 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_RICH_EDITOR_RICH_EDITOR_MODEL_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_RICH_EDITOR_RICH_EDITOR_MODEL_H 18 19 #include <functional> 20 #include <mutex> 21 #include <optional> 22 #include <string> 23 24 #include "base/image/pixel_map.h" 25 #include "base/memory/ace_type.h" 26 #include "base/utils/device_config.h" 27 #include "core/common/ime/text_input_action.h" 28 #include "core/common/resource/resource_object.h" 29 #include "core/components/common/layout/constants.h" 30 #include "core/components/common/properties/text_style.h" 31 #include "core/components_ng/base/view_abstract_model.h" 32 #include "core/components_ng/pattern/rich_editor/rich_editor_event_hub.h" 33 #include "core/components_ng/pattern/rich_editor/rich_editor_theme.h" 34 #include "core/components_ng/pattern/rich_editor/selection_info.h" 35 #include "core/components_ng/pattern/text/layout_info_interface.h" 36 #include "core/components_ng/pattern/text/text_model.h" 37 #include "core/components_ng/pattern/text_field/text_field_event_hub.h" 38 #include "core/components_ng/pattern/text_field/text_field_model.h" 39 #include "core/components_ng/pattern/text_field/text_selector.h" 40 #include "core/components_ng/property/border_property.h" 41 #include "core/components_ng/property/measure_property.h" 42 #include "core/components_ng/render/paragraph.h" 43 namespace OHOS::Ace { 44 struct SpanPositionInfo { SpanPositionInfoSpanPositionInfo45 SpanPositionInfo(int32_t index, int32_t start, int32_t end, int32_t offset) 46 : spanIndex_(index), spanStart_(start), spanEnd_(end), spanOffset_(offset) 47 {} 48 SpanPositionInfoSpanPositionInfo49 SpanPositionInfo() 50 { 51 spanIndex_ = 0; 52 spanStart_ = 0; 53 spanEnd_ = 0; 54 spanOffset_ = 0; 55 } 56 57 int32_t spanIndex_ = 0; 58 int32_t spanStart_ = 0; 59 int32_t spanEnd_ = 0; 60 int32_t spanOffset_ = 0; 61 ToStringSpanPositionInfo62 std::string ToString() const 63 { 64 return "spanIndex: " + std::to_string(spanIndex_) 65 + ", spanStart: " + std::to_string(spanStart_) 66 + ", spanEnd" + std::to_string(spanEnd_) 67 + ", spanOffset: " + std::to_string(spanOffset_); 68 } 69 }; 70 71 struct UpdateSpanStyle { ResetStyleUpdateSpanStyle72 void ResetStyle() 73 { 74 updateTextColor.reset(); 75 updateFontSize.reset(); 76 updateItalicFontStyle.reset(); 77 updateFontWeight.reset(); 78 updateFontFamily.reset(); 79 updateTextDecoration.reset(); 80 updateTextDecorationColor.reset(); 81 updateTextDecorationStyle.reset(); 82 updateLineThicknessScale.reset(); 83 updateTextShadows.reset(); 84 updateFontFeature.reset(); 85 updateTextBackgroundStyle.reset(); 86 updateUrlAddress.reset(); 87 88 updateLineHeight.reset(); 89 updateHalfLeading.reset(); 90 updateLetterSpacing.reset(); 91 92 updateImageWidth.reset(); 93 updateImageHeight.reset(); 94 updateImageVerticalAlign.reset(); 95 updateImageFit.reset(); 96 marginProp.reset(); 97 borderRadius.reset(); 98 isInitDecoration = false; 99 100 updateSymbolColor.reset(); 101 updateSymbolFontSize.reset(); 102 updateSymbolFontWeight.reset(); 103 updateSymbolRenderingStrategy.reset(); 104 updateSymbolEffectStrategy.reset(); 105 } 106 107 std::optional<Color> updateTextColor = std::nullopt; 108 std::optional<CalcDimension> updateFontSize = std::nullopt; 109 std::optional<FontStyle> updateItalicFontStyle = std::nullopt; 110 std::optional<FontWeight> updateFontWeight = std::nullopt; 111 std::optional<std::vector<std::string>> updateFontFamily = std::nullopt; 112 std::optional<TextDecoration> updateTextDecoration = std::nullopt; 113 std::optional<Color> updateTextDecorationColor = std::nullopt; 114 std::optional<TextDecorationStyle> updateTextDecorationStyle = std::nullopt; 115 std::optional<float> updateLineThicknessScale = std::nullopt; 116 std::optional<std::vector<Shadow>> updateTextShadows = std::nullopt; 117 std::optional<NG::FONT_FEATURES_LIST> updateFontFeature = std::nullopt; 118 std::optional<TextBackgroundStyle> updateTextBackgroundStyle = std::nullopt; 119 std::optional<std::u16string> updateUrlAddress = std::nullopt; 120 121 std::optional<CalcDimension> updateLineHeight = std::nullopt; 122 std::optional<bool> updateHalfLeading = std::nullopt; 123 std::optional<CalcDimension> updateLetterSpacing = std::nullopt; 124 125 std::optional<CalcDimension> updateImageWidth = std::nullopt; 126 std::optional<CalcDimension> updateImageHeight = std::nullopt; 127 std::optional<VerticalAlign> updateImageVerticalAlign = std::nullopt; 128 std::optional<ImageFit> updateImageFit = std::nullopt; 129 std::optional<OHOS::Ace::NG::MarginProperty> marginProp = std::nullopt; 130 std::optional<OHOS::Ace::NG::BorderRadiusProperty> borderRadius = std::nullopt; 131 bool useThemeFontColor = true; 132 bool useThemeDecorationColor = true; 133 bool isInitDecoration = false; 134 135 std::optional<std::vector<Color>> updateSymbolColor = std::nullopt; 136 std::optional<CalcDimension> updateSymbolFontSize = std::nullopt; 137 std::optional<FontWeight> updateSymbolFontWeight = std::nullopt; 138 std::optional<uint32_t> updateSymbolRenderingStrategy = std::nullopt; 139 std::optional<uint32_t> updateSymbolEffectStrategy = std::nullopt; 140 UpdateColorByResourceIdUpdateSpanStyle141 void UpdateColorByResourceId() 142 { 143 if (updateTextColor) { 144 updateTextColor->UpdateColorByResourceId(); 145 } 146 if (updateTextDecorationColor) { 147 updateTextDecorationColor->UpdateColorByResourceId(); 148 } 149 if (updateTextShadows) { 150 auto& shadows = updateTextShadows.value(); 151 std::for_each(shadows.begin(), shadows.end(), [](Shadow& sd) { sd.UpdateColorByResourceId(); }); 152 } 153 if (updateSymbolColor) { 154 auto& colors = updateSymbolColor.value(); 155 std::for_each(colors.begin(), colors.end(), [](Color& cl) { cl.UpdateColorByResourceId(); }); 156 } 157 if (updateTextBackgroundStyle) { 158 updateTextBackgroundStyle->UpdateColorByResourceId(); 159 } 160 } 161 ToStringUpdateSpanStyle162 std::string ToString() const 163 { 164 auto jsonValue = JsonUtil::Create(true); 165 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, updateTextColor); 166 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, updateFontSize); 167 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, updateItalicFontStyle); 168 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, updateFontWeight); 169 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, updateTextDecoration); 170 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, updateTextDecorationColor); 171 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, updateTextDecorationStyle); 172 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, updateLineThicknessScale); 173 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, updateSymbolRenderingStrategy); 174 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, updateSymbolEffectStrategy); 175 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, updateImageWidth); 176 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, updateImageHeight); 177 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, updateImageVerticalAlign); 178 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, updateImageFit); 179 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, marginProp); 180 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, borderRadius); 181 JSON_STRING_PUT_BOOL(jsonValue, useThemeFontColor); 182 JSON_STRING_PUT_BOOL(jsonValue, useThemeDecorationColor); 183 return jsonValue->ToString(); 184 } 185 }; 186 187 struct UpdateParagraphStyle { ResetUpdateParagraphStyle188 void Reset() 189 { 190 textAlign.reset(); 191 leadingMargin.reset(); 192 wordBreak.reset(); 193 lineBreakStrategy.reset(); 194 paragraphSpacing.reset(); 195 textVerticalAlign.reset(); 196 } 197 std::optional<TextAlign> textAlign; 198 std::optional<NG::LeadingMargin> leadingMargin; 199 std::optional<WordBreak> wordBreak; 200 std::optional<LineBreakStrategy> lineBreakStrategy; 201 std::optional<Dimension> paragraphSpacing; 202 std::optional<TextVerticalAlign> textVerticalAlign; 203 ToStringUpdateParagraphStyle204 std::string ToString() const 205 { 206 auto jsonValue = JsonUtil::Create(true); 207 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, textAlign); 208 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, leadingMargin); 209 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, wordBreak); 210 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, lineBreakStrategy); 211 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, paragraphSpacing); 212 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, textVerticalAlign); 213 return jsonValue->ToString(); 214 } 215 }; 216 217 struct RangeOptions { 218 std::optional<int32_t> start; 219 std::optional<int32_t> end; 220 ToStringRangeOptions221 std::string ToString() const 222 { 223 return "[" 224 + (start ? std::to_string(*start) : "nullopt") 225 + "," 226 + (end ? std::to_string(*end) : "nullopt") 227 + "]"; 228 } 229 }; 230 231 struct TextSpanOptions : SpanOptionBase { 232 std::optional<int32_t> offset; 233 std::u16string value; 234 std::optional<TextStyle> style; 235 std::optional<UpdateParagraphStyle> paraStyle; 236 std::optional<std::u16string> urlAddress; 237 UserGestureOptions userGestureOption; 238 bool useThemeFontColor = true; 239 bool useThemeDecorationColor = true; 240 ToStringTextSpanOptions241 std::string ToString() const 242 { 243 auto jsonValue = JsonUtil::Create(true); 244 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, offset); 245 JSON_STRING_PUT_STRING(jsonValue, value); 246 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, style); 247 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, paraStyle); 248 JSON_STRING_PUT_BOOL(jsonValue, useThemeFontColor); 249 JSON_STRING_PUT_BOOL(jsonValue, useThemeDecorationColor); 250 return jsonValue->ToString(); 251 } 252 }; 253 254 struct SymbolSpanOptions : SpanOptionBase { 255 std::optional<int32_t> offset; 256 uint32_t symbolId; 257 std::optional<TextStyle> style; 258 std::optional<UpdateParagraphStyle> paraStyle; 259 RefPtr<ResourceObject> resourceObject; 260 ToStringSymbolSpanOptions261 std::string ToString() const 262 { 263 auto jsonValue = JsonUtil::Create(true); 264 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, offset); 265 JSON_STRING_PUT_INT(jsonValue, symbolId); 266 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, style); 267 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, paraStyle); 268 return jsonValue->ToString(); 269 } 270 }; 271 272 struct BuilderSpanOptions : SpanOptionBase { 273 std::optional<int32_t> offset; 274 RefPtr<NG::UINode> customNode; 275 }; 276 277 struct PlaceholderOptions { 278 std::optional<std::u16string> value; 279 std::optional<FontWeight> fontWeight; 280 std::optional<Dimension> fontSize; 281 std::optional<Color> fontColor; 282 std::optional<FontStyle> fontStyle; 283 std::vector<std::string> fontFamilies; 284 ToStringPlaceholderOptions285 std::string ToString() const 286 { 287 auto jsonValue = JsonUtil::Create(true); 288 JSON_STRING_PUT_OPTIONAL_STRING(jsonValue, value); 289 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, fontWeight); 290 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, fontSize); 291 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, fontColor); 292 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, fontStyle); 293 return jsonValue->ToString(); 294 } 295 }; 296 297 struct PreviewTextInfo { 298 std::optional<std::u16string> value; 299 std::optional<int32_t> offset; 300 ToStringPreviewTextInfo301 std::string ToString() const 302 { 303 auto jsonValue = JsonUtil::Create(true); 304 JSON_STRING_PUT_OPTIONAL_STRING(jsonValue, value); 305 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, offset); 306 return jsonValue->ToString(); 307 } 308 }; 309 310 enum class UndoStyle { CLEAR_STYLE = 0, KEEP_STYLE = 1 }; 311 312 class ACE_EXPORT RichEditorBaseControllerBase : public AceType { 313 DECLARE_ACE_TYPE(RichEditorBaseControllerBase, AceType); 314 315 public: 316 virtual int32_t GetCaretOffset() = 0; 317 virtual NG::RectF GetCaretRect() = 0; 318 virtual bool SetCaretOffset(int32_t caretPosition) = 0; 319 virtual void SetTypingStyle(std::optional<struct UpdateSpanStyle> typingStyle, 320 std::optional<TextStyle> textStyle) = 0; 321 virtual void SetTypingParagraphStyle(std::optional<struct UpdateParagraphStyle> typingParagraphStyle) = 0; 322 virtual std::optional<struct UpdateSpanStyle> GetTypingStyle() = 0; 323 virtual void CloseSelectionMenu() = 0; 324 virtual bool IsEditing() = 0; 325 virtual void StopEditing() = 0; 326 #if defined(ACE_STATIC) 327 virtual void SetSelection(int32_t selectionStart, int32_t selectionEnd, 328 const std::optional<SelectionOptions>& options = std::nullopt, bool isForward = false) = 0; 329 #else 330 virtual void SetSelection(int32_t selectionStart, int32_t selectionEnd, 331 const std::optional<SelectionOptions>& options = std::nullopt) = 0; 332 #endif 333 virtual WeakPtr<NG::LayoutInfoInterface> GetLayoutInfoInterface() = 0; 334 virtual const PreviewTextInfo GetPreviewTextInfo() const = 0; 335 virtual ColorMode GetColorMode() = 0; 336 virtual RefPtr<NG::RichEditorTheme> GetTheme() = 0; 337 }; 338 339 class ACE_EXPORT RichEditorControllerBase : virtual public RichEditorBaseControllerBase { 340 DECLARE_ACE_TYPE(RichEditorControllerBase, RichEditorBaseControllerBase); 341 342 public: 343 virtual int32_t AddImageSpan(const ImageSpanOptions& options) = 0; 344 virtual int32_t AddTextSpan(const TextSpanOptions& options) = 0; 345 virtual int32_t AddSymbolSpan(const SymbolSpanOptions& options) = 0; 346 virtual int32_t AddPlaceholderSpan(const RefPtr<NG::UINode>& customNode, const SpanOptionBase& options) = 0; 347 virtual void UpdateParagraphStyle(int32_t start, int32_t end, const UpdateParagraphStyle& style) = 0; 348 virtual void UpdateSpanStyle( 349 int32_t start, int32_t end, TextStyle textStyle, ImageSpanAttribute imageStyle) = 0; 350 virtual void SetUpdateSpanStyle(struct UpdateSpanStyle updateSpanStyle) = 0; 351 virtual SelectionInfo GetSpansInfo(int32_t start, int32_t end) = 0; 352 virtual std::vector<ParagraphInfo> GetParagraphsInfo(int32_t start, int32_t end) = 0; 353 virtual void DeleteSpans(const RangeOptions& options) = 0; 354 virtual SelectionInfo GetSelectionSpansInfo() = 0; 355 virtual RefPtr<SpanStringBase> ToStyledString(int32_t start, int32_t end) = 0; 356 virtual SelectionInfo FromStyledString(RefPtr<SpanStringBase> value) = 0; 357 }; 358 359 class ACE_EXPORT RichEditorStyledStringControllerBase : virtual public RichEditorBaseControllerBase { 360 DECLARE_ACE_TYPE(RichEditorStyledStringControllerBase, RichEditorBaseControllerBase); 361 362 public: 363 virtual void SetStyledString(const RefPtr<SpanStringBase>& value) = 0; 364 virtual RefPtr<SpanStringBase> GetStyledString() = 0; 365 virtual SelectionRangeInfo GetSelection() = 0; 366 virtual void SetOnWillChange(std::function<bool(const NG::StyledStringChangeValue&)> && func) = 0; 367 virtual void SetOnDidChange(std::function<void(const NG::StyledStringChangeValue&)> && func) = 0; 368 }; 369 370 class ACE_FORCE_EXPORT RichEditorModel { 371 public: 372 static RichEditorModel* GetInstance(); 373 virtual ~RichEditorModel() = default; 374 virtual void Create(bool isStyledStringMode = false) = 0; 375 virtual RefPtr<RichEditorBaseControllerBase> GetRichEditorController() = 0; 376 virtual void SetOnReady(std::function<void()>&& func) = 0; 377 virtual void SetOnSelect(std::function<void(const BaseEventInfo*)>&& func) = 0; 378 virtual void SetOnSelectionChange(std::function<void(const BaseEventInfo*)>&& func) = 0; 379 virtual void SetAboutToIMEInput(std::function<bool(const NG::RichEditorInsertValue&)>&& func) = 0; 380 virtual void SetOnIMEInputComplete(std::function<void(const NG::RichEditorAbstractSpanResult&)>&& func) = 0; 381 virtual void SetOnDidIMEInput(std::function<void(const TextRange&)>&& func) = 0; 382 virtual void SetAboutToDelete(std::function<bool(const NG::RichEditorDeleteValue&)>&& func) = 0; 383 virtual void SetOnDeleteComplete(std::function<void()>&& func) = 0; 384 virtual void SetCustomKeyboard(std::function<void()>&& func, bool supportAvoidance = false) = 0; 385 virtual void SetCopyOption(CopyOptions& copyOptions) = 0; 386 virtual void BindSelectionMenu(NG::TextSpanType& editorType, NG::TextResponseType& responseType, 387 std::function<void()>& buildFunc, NG::SelectMenuParam& menuParam) = 0; 388 virtual void SetOnPaste(std::function<void(NG::TextCommonEvent&)>&& func) = 0; 389 virtual void SetPlaceholder(PlaceholderOptions& options) = 0; 390 virtual void SetTextDetectEnable(bool value) = 0; 391 virtual void SetSupportPreviewText(bool value) = 0; 392 virtual void SetTextDetectConfig(const TextDetectConfig& textDetectConfig) = 0; 393 virtual void SetSelectedBackgroundColor(const Color& selectedColor) = 0; 394 virtual void SetCaretColor(const Color& color) = 0; 395 virtual void SetOnEditingChange(std::function<void(const bool&)>&& func) = 0; 396 virtual void SetEnterKeyType(TextInputAction value) = 0; 397 virtual void SetOnSubmit(std::function<void(int32_t, NG::TextFieldCommonEvent&)>&& func) = 0; 398 virtual void SetOnWillChange(std::function<bool(const NG::RichEditorChangeValue&)>&& func) = 0; 399 virtual void SetOnDidChange(std::function<void(const NG::RichEditorChangeValue&)>&& func) = 0; 400 virtual void SetOnCut(std::function<void(NG::TextCommonEvent&)>&& func) = 0; 401 virtual void SetOnCopy(std::function<void(NG::TextCommonEvent&)>&& func) = 0; 402 virtual void SetOnShare(std::function<void(NG::TextCommonEvent&)>&& func) = 0; SetSelectionMenuOptions(const NG::OnCreateMenuCallback && onCreateMenuCallback,const NG::OnMenuItemClickCallback && onMenuItemClick,const NG::OnPrepareMenuCallback && onPrepareMenuCallback)403 virtual void SetSelectionMenuOptions(const NG::OnCreateMenuCallback&& onCreateMenuCallback, 404 const NG::OnMenuItemClickCallback&& onMenuItemClick, 405 const NG::OnPrepareMenuCallback&& onPrepareMenuCallback) {} SetRequestKeyboardOnFocus(bool needToRequest)406 virtual void SetRequestKeyboardOnFocus(bool needToRequest) {} SetEnableHapticFeedback(bool isEnabled)407 virtual void SetEnableHapticFeedback(bool isEnabled) {} SetBarState(DisplayMode mode)408 virtual void SetBarState(DisplayMode mode) {} SetPreviewMenuParam(NG::TextSpanType spanType,std::function<void ()> & buildFunc,const NG::SelectMenuParam & menuParam)409 virtual void SetPreviewMenuParam(NG::TextSpanType spanType, std::function<void()>& buildFunc, 410 const NG::SelectMenuParam& menuParam) {} SetMaxLength(std::optional<int32_t> value)411 virtual void SetMaxLength(std::optional<int32_t> value) {} ResetMaxLength()412 virtual void ResetMaxLength() {} SetMaxLines(uint32_t value)413 virtual void SetMaxLines(uint32_t value) {}; SetEnableAutoSpacing(bool enabled)414 virtual void SetEnableAutoSpacing(bool enabled) {}; SetStopBackPress(bool isStopBackPress)415 virtual void SetStopBackPress(bool isStopBackPress) {}; SetKeyboardAppearance(KeyboardAppearance value)416 virtual void SetKeyboardAppearance(KeyboardAppearance value) {}; SetSupportStyledUndo(bool enabled)417 virtual void SetSupportStyledUndo(bool enabled) {}; 418 419 private: 420 static std::unique_ptr<RichEditorModel> instance_; 421 static std::mutex mutex_; 422 }; 423 } // namespace OHOS::Ace 424 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_RICH_EDITOR_RICH_EDITOR_MODEL_H 425