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 updateTextShadows.reset(); 83 updateFontFeature.reset(); 84 updateTextBackgroundStyle.reset(); 85 updateUrlAddress.reset(); 86 87 updateLineHeight.reset(); 88 updateHalfLeading.reset(); 89 updateLetterSpacing.reset(); 90 91 updateImageWidth.reset(); 92 updateImageHeight.reset(); 93 updateImageVerticalAlign.reset(); 94 updateImageFit.reset(); 95 marginProp.reset(); 96 borderRadius.reset(); 97 isInitDecoration = false; 98 99 updateSymbolColor.reset(); 100 updateSymbolFontSize.reset(); 101 updateSymbolFontWeight.reset(); 102 updateSymbolRenderingStrategy.reset(); 103 updateSymbolEffectStrategy.reset(); 104 } 105 106 std::optional<Color> updateTextColor = std::nullopt; 107 std::optional<CalcDimension> updateFontSize = std::nullopt; 108 std::optional<FontStyle> updateItalicFontStyle = std::nullopt; 109 std::optional<FontWeight> updateFontWeight = std::nullopt; 110 std::optional<std::vector<std::string>> updateFontFamily = std::nullopt; 111 std::optional<TextDecoration> updateTextDecoration = std::nullopt; 112 std::optional<Color> updateTextDecorationColor = std::nullopt; 113 std::optional<TextDecorationStyle> updateTextDecorationStyle = std::nullopt; 114 std::optional<std::vector<Shadow>> updateTextShadows = std::nullopt; 115 std::optional<NG::FONT_FEATURES_LIST> updateFontFeature = std::nullopt; 116 std::optional<TextBackgroundStyle> updateTextBackgroundStyle = std::nullopt; 117 std::optional<std::u16string> updateUrlAddress = std::nullopt; 118 119 std::optional<CalcDimension> updateLineHeight = std::nullopt; 120 std::optional<bool> updateHalfLeading = std::nullopt; 121 std::optional<CalcDimension> updateLetterSpacing = std::nullopt; 122 123 std::optional<CalcDimension> updateImageWidth = std::nullopt; 124 std::optional<CalcDimension> updateImageHeight = std::nullopt; 125 std::optional<VerticalAlign> updateImageVerticalAlign = std::nullopt; 126 std::optional<ImageFit> updateImageFit = std::nullopt; 127 std::optional<OHOS::Ace::NG::MarginProperty> marginProp = std::nullopt; 128 std::optional<OHOS::Ace::NG::BorderRadiusProperty> borderRadius = std::nullopt; 129 bool useThemeFontColor = true; 130 bool useThemeDecorationColor = true; 131 bool isInitDecoration = false; 132 133 std::optional<std::vector<Color>> updateSymbolColor = std::nullopt; 134 std::optional<CalcDimension> updateSymbolFontSize = std::nullopt; 135 std::optional<FontWeight> updateSymbolFontWeight = std::nullopt; 136 std::optional<uint32_t> updateSymbolRenderingStrategy = std::nullopt; 137 std::optional<uint32_t> updateSymbolEffectStrategy = std::nullopt; 138 UpdateColorByResourceIdUpdateSpanStyle139 void UpdateColorByResourceId() 140 { 141 if (updateTextColor) { 142 updateTextColor->UpdateColorByResourceId(); 143 } 144 if (updateTextDecorationColor) { 145 updateTextDecorationColor->UpdateColorByResourceId(); 146 } 147 if (updateTextShadows) { 148 auto& shadows = updateTextShadows.value(); 149 std::for_each(shadows.begin(), shadows.end(), [](Shadow& sd) { sd.UpdateColorByResourceId(); }); 150 } 151 if (updateSymbolColor) { 152 auto& colors = updateSymbolColor.value(); 153 std::for_each(colors.begin(), colors.end(), [](Color& cl) { cl.UpdateColorByResourceId(); }); 154 } 155 if (updateTextBackgroundStyle) { 156 updateTextBackgroundStyle->UpdateColorByResourceId(); 157 } 158 } 159 ToStringUpdateSpanStyle160 std::string ToString() const 161 { 162 auto jsonValue = JsonUtil::Create(true); 163 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, updateTextColor); 164 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, updateFontSize); 165 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, updateItalicFontStyle); 166 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, updateFontWeight); 167 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, updateTextDecoration); 168 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, updateTextDecorationColor); 169 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, updateTextDecorationStyle); 170 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, updateSymbolRenderingStrategy); 171 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, updateSymbolEffectStrategy); 172 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, updateImageWidth); 173 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, updateImageHeight); 174 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, updateImageVerticalAlign); 175 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, updateImageFit); 176 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, marginProp); 177 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, borderRadius); 178 JSON_STRING_PUT_BOOL(jsonValue, useThemeFontColor); 179 JSON_STRING_PUT_BOOL(jsonValue, useThemeDecorationColor); 180 return jsonValue->ToString(); 181 } 182 }; 183 184 struct UpdateParagraphStyle { ResetUpdateParagraphStyle185 void Reset() 186 { 187 textAlign.reset(); 188 leadingMargin.reset(); 189 wordBreak.reset(); 190 lineBreakStrategy.reset(); 191 paragraphSpacing.reset(); 192 } 193 std::optional<TextAlign> textAlign; 194 std::optional<NG::LeadingMargin> leadingMargin; 195 std::optional<WordBreak> wordBreak; 196 std::optional<LineBreakStrategy> lineBreakStrategy; 197 std::optional<Dimension> paragraphSpacing; 198 ToStringUpdateParagraphStyle199 std::string ToString() const 200 { 201 auto jsonValue = JsonUtil::Create(true); 202 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, textAlign); 203 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, leadingMargin); 204 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, wordBreak); 205 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, lineBreakStrategy); 206 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, paragraphSpacing); 207 return jsonValue->ToString(); 208 } 209 }; 210 211 struct RangeOptions { 212 std::optional<int32_t> start; 213 std::optional<int32_t> end; 214 ToStringRangeOptions215 std::string ToString() const 216 { 217 return "[" 218 + (start ? std::to_string(*start) : "nullopt") 219 + "," 220 + (end ? std::to_string(*end) : "nullopt") 221 + "]"; 222 } 223 }; 224 225 struct TextSpanOptions : SpanOptionBase { 226 std::optional<int32_t> offset; 227 std::u16string value; 228 std::optional<TextStyle> style; 229 std::optional<UpdateParagraphStyle> paraStyle; 230 std::optional<std::u16string> urlAddress; 231 UserGestureOptions userGestureOption; 232 bool useThemeFontColor = true; 233 bool useThemeDecorationColor = true; 234 ToStringTextSpanOptions235 std::string ToString() const 236 { 237 auto jsonValue = JsonUtil::Create(true); 238 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, offset); 239 JSON_STRING_PUT_STRING(jsonValue, value); 240 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, style); 241 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, paraStyle); 242 JSON_STRING_PUT_BOOL(jsonValue, useThemeFontColor); 243 JSON_STRING_PUT_BOOL(jsonValue, useThemeDecorationColor); 244 return jsonValue->ToString(); 245 } 246 }; 247 248 struct SymbolSpanOptions : SpanOptionBase { 249 std::optional<int32_t> offset; 250 uint32_t symbolId; 251 std::optional<TextStyle> style; 252 RefPtr<ResourceObject> resourceObject; 253 ToStringSymbolSpanOptions254 std::string ToString() const 255 { 256 auto jsonValue = JsonUtil::Create(true); 257 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, offset); 258 JSON_STRING_PUT_INT(jsonValue, symbolId); 259 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, style); 260 return jsonValue->ToString(); 261 } 262 }; 263 264 struct PlaceholderOptions { 265 std::optional<std::u16string> value; 266 std::optional<FontWeight> fontWeight; 267 std::optional<Dimension> fontSize; 268 std::optional<Color> fontColor; 269 std::optional<FontStyle> fontStyle; 270 std::vector<std::string> fontFamilies; 271 ToStringPlaceholderOptions272 std::string ToString() const 273 { 274 auto jsonValue = JsonUtil::Create(true); 275 JSON_STRING_PUT_OPTIONAL_STRING(jsonValue, value); 276 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, fontWeight); 277 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, fontSize); 278 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, fontColor); 279 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, fontStyle); 280 return jsonValue->ToString(); 281 } 282 }; 283 284 struct PreviewTextInfo { 285 std::optional<std::u16string> value; 286 std::optional<int32_t> offset; 287 ToStringPreviewTextInfo288 std::string ToString() const 289 { 290 auto jsonValue = JsonUtil::Create(true); 291 JSON_STRING_PUT_OPTIONAL_STRING(jsonValue, value); 292 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, offset); 293 return jsonValue->ToString(); 294 } 295 }; 296 297 class ACE_EXPORT RichEditorBaseControllerBase : public AceType { 298 DECLARE_ACE_TYPE(RichEditorBaseControllerBase, AceType); 299 300 public: 301 virtual int32_t GetCaretOffset() = 0; 302 virtual NG::RectF GetCaretRect() = 0; 303 virtual bool SetCaretOffset(int32_t caretPosition) = 0; 304 virtual void SetTypingStyle(std::optional<struct UpdateSpanStyle> typingStyle, 305 std::optional<TextStyle> textStyle) = 0; 306 virtual std::optional<struct UpdateSpanStyle> GetTypingStyle() = 0; 307 virtual void CloseSelectionMenu() = 0; 308 virtual bool IsEditing() = 0; 309 virtual void StopEditing() = 0; 310 virtual void SetSelection(int32_t selectionStart, int32_t selectionEnd, 311 const std::optional<SelectionOptions>& options = std::nullopt, bool isForward = false) = 0; 312 virtual WeakPtr<NG::LayoutInfoInterface> GetLayoutInfoInterface() = 0; 313 virtual const PreviewTextInfo GetPreviewTextInfo() const = 0; 314 virtual ColorMode GetColorMode() = 0; 315 virtual RefPtr<NG::RichEditorTheme> GetTheme() = 0; 316 }; 317 318 class ACE_EXPORT RichEditorControllerBase : virtual public RichEditorBaseControllerBase { 319 DECLARE_ACE_TYPE(RichEditorControllerBase, RichEditorBaseControllerBase); 320 321 public: 322 virtual int32_t AddImageSpan(const ImageSpanOptions& options) = 0; 323 virtual int32_t AddTextSpan(const TextSpanOptions& options) = 0; 324 virtual int32_t AddSymbolSpan(const SymbolSpanOptions& options) = 0; 325 virtual int32_t AddPlaceholderSpan(const RefPtr<NG::UINode>& customNode, const SpanOptionBase& options) = 0; 326 virtual void UpdateParagraphStyle(int32_t start, int32_t end, const UpdateParagraphStyle& style) = 0; 327 virtual void UpdateSpanStyle( 328 int32_t start, int32_t end, TextStyle textStyle, ImageSpanAttribute imageStyle) = 0; 329 virtual void SetUpdateSpanStyle(struct UpdateSpanStyle updateSpanStyle) = 0; 330 virtual SelectionInfo GetSpansInfo(int32_t start, int32_t end) = 0; 331 virtual std::vector<ParagraphInfo> GetParagraphsInfo(int32_t start, int32_t end) = 0; 332 virtual void DeleteSpans(const RangeOptions& options) = 0; 333 virtual SelectionInfo GetSelectionSpansInfo() = 0; 334 virtual RefPtr<SpanStringBase> ToStyledString(int32_t start, int32_t end) = 0; 335 virtual SelectionInfo FromStyledString(RefPtr<SpanStringBase> value) = 0; 336 }; 337 338 class ACE_EXPORT RichEditorStyledStringControllerBase : virtual public RichEditorBaseControllerBase { 339 DECLARE_ACE_TYPE(RichEditorStyledStringControllerBase, RichEditorBaseControllerBase); 340 341 public: 342 virtual void SetStyledString(const RefPtr<SpanStringBase>& value) = 0; 343 virtual RefPtr<SpanStringBase> GetStyledString() = 0; 344 virtual SelectionRangeInfo GetSelection() = 0; 345 virtual void SetOnWillChange(std::function<bool(const NG::StyledStringChangeValue&)> && func) = 0; 346 virtual void SetOnDidChange(std::function<void(const NG::StyledStringChangeValue&)> && func) = 0; 347 }; 348 349 class ACE_FORCE_EXPORT RichEditorModel { 350 public: 351 static RichEditorModel* GetInstance(); 352 virtual ~RichEditorModel() = default; 353 virtual void Create(bool isStyledStringMode = false) = 0; 354 virtual RefPtr<RichEditorBaseControllerBase> GetRichEditorController() = 0; 355 virtual void SetOnReady(std::function<void()>&& func) = 0; 356 virtual void SetOnSelect(std::function<void(const BaseEventInfo*)>&& func) = 0; 357 virtual void SetOnSelectionChange(std::function<void(const BaseEventInfo*)>&& func) = 0; 358 virtual void SetAboutToIMEInput(std::function<bool(const NG::RichEditorInsertValue&)>&& func) = 0; 359 virtual void SetOnIMEInputComplete(std::function<void(const NG::RichEditorAbstractSpanResult&)>&& func) = 0; 360 virtual void SetOnDidIMEInput(std::function<void(const TextRange&)>&& func) = 0; 361 virtual void SetAboutToDelete(std::function<bool(const NG::RichEditorDeleteValue&)>&& func) = 0; 362 virtual void SetOnDeleteComplete(std::function<void()>&& func) = 0; 363 virtual void SetCustomKeyboard(std::function<void()>&& func, bool supportAvoidance = false) = 0; 364 virtual void SetCopyOption(CopyOptions& copyOptions) = 0; 365 virtual void BindSelectionMenu(NG::TextSpanType& editorType, NG::TextResponseType& responseType, 366 std::function<void()>& buildFunc, NG::SelectMenuParam& menuParam) = 0; 367 virtual void SetOnPaste(std::function<void(NG::TextCommonEvent&)>&& func) = 0; 368 virtual void SetPlaceholder(PlaceholderOptions& options) = 0; 369 virtual void SetTextDetectEnable(bool value) = 0; 370 virtual void SetSupportPreviewText(bool value) = 0; 371 virtual void SetTextDetectConfig(const TextDetectConfig& textDetectConfig) = 0; 372 virtual void SetSelectedBackgroundColor(const Color& selectedColor) = 0; 373 virtual void SetCaretColor(const Color& color) = 0; 374 virtual void SetOnEditingChange(std::function<void(const bool&)>&& func) = 0; 375 virtual void SetEnterKeyType(TextInputAction value) = 0; 376 virtual void SetOnSubmit(std::function<void(int32_t, NG::TextFieldCommonEvent&)>&& func) = 0; 377 virtual void SetOnWillChange(std::function<bool(const NG::RichEditorChangeValue&)>&& func) = 0; 378 virtual void SetOnDidChange(std::function<void(const NG::RichEditorChangeValue&)>&& func) = 0; 379 virtual void SetOnCut(std::function<void(NG::TextCommonEvent&)>&& func) = 0; 380 virtual void SetOnCopy(std::function<void(NG::TextCommonEvent&)>&& func) = 0; 381 virtual void SetOnShare(std::function<void(NG::TextCommonEvent&)>&& func) = 0; SetSelectionMenuOptions(const NG::OnCreateMenuCallback && onCreateMenuCallback,const NG::OnMenuItemClickCallback && onMenuItemClick)382 virtual void SetSelectionMenuOptions( 383 const NG::OnCreateMenuCallback&& onCreateMenuCallback, const NG::OnMenuItemClickCallback&& onMenuItemClick) {} SetRequestKeyboardOnFocus(bool needToRequest)384 virtual void SetRequestKeyboardOnFocus(bool needToRequest) {} SetEnableHapticFeedback(bool isEnabled)385 virtual void SetEnableHapticFeedback(bool isEnabled) {} SetBarState(DisplayMode mode)386 virtual void SetBarState(DisplayMode mode) {} SetPreviewMenuParam(NG::TextSpanType spanType,std::function<void ()> & buildFunc,const NG::SelectMenuParam & menuParam)387 virtual void SetPreviewMenuParam(NG::TextSpanType spanType, std::function<void()>& buildFunc, 388 const NG::SelectMenuParam& menuParam) {} SetMaxLength(std::optional<int32_t> value)389 virtual void SetMaxLength(std::optional<int32_t> value) {} ResetMaxLength()390 virtual void ResetMaxLength() {} SetMaxLines(uint32_t value)391 virtual void SetMaxLines(uint32_t value) {}; SetStopBackPress(bool isStopBackPress)392 virtual void SetStopBackPress(bool isStopBackPress) {}; SetKeyboardAppearance(KeyboardAppearance value)393 virtual void SetKeyboardAppearance(KeyboardAppearance value) {}; 394 395 private: 396 static std::unique_ptr<RichEditorModel> instance_; 397 static std::mutex mutex_; 398 }; 399 } // namespace OHOS::Ace 400 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_RICH_EDITOR_RICH_EDITOR_MODEL_H 401