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_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 "core/common/ime/text_input_action.h" 27 #include "core/components/common/layout/constants.h" 28 #include "core/components/common/properties/text_style.h" 29 #include "core/components_ng/base/view_abstract_model.h" 30 #include "core/components_ng/pattern/rich_editor/rich_editor_event_hub.h" 31 #include "core/components_ng/pattern/rich_editor/selection_info.h" 32 #include "core/components_ng/pattern/text/layout_info_interface.h" 33 #include "core/components_ng/pattern/text/text_model.h" 34 #include "core/components_ng/pattern/text_field/text_field_event_hub.h" 35 #include "core/components_ng/pattern/text_field/text_field_model.h" 36 #include "core/components_ng/pattern/text_field/text_selector.h" 37 #include "core/components_ng/property/border_property.h" 38 #include "core/components_ng/property/measure_property.h" 39 #include "core/components_ng/render/paragraph.h" 40 namespace OHOS::Ace { 41 struct SpanPositionInfo { SpanPositionInfoSpanPositionInfo42 SpanPositionInfo(int32_t index, int32_t start, int32_t end, int32_t offset) 43 : spanIndex_(index), spanStart_(start), spanEnd_(end), spanOffset_(offset) 44 {} 45 SpanPositionInfoSpanPositionInfo46 SpanPositionInfo() 47 { 48 spanIndex_ = 0; 49 spanStart_ = 0; 50 spanEnd_ = 0; 51 spanOffset_ = 0; 52 } 53 54 int32_t spanIndex_ = 0; 55 int32_t spanStart_ = 0; 56 int32_t spanEnd_ = 0; 57 int32_t spanOffset_ = 0; 58 ToStringSpanPositionInfo59 std::string ToString() const 60 { 61 return "spanIndex: " + std::to_string(spanIndex_) 62 + ", spanStart: " + std::to_string(spanStart_) 63 + ", spanEnd" + std::to_string(spanEnd_) 64 + ", spanOffset: " + std::to_string(spanOffset_); 65 } 66 }; 67 68 struct UpdateSpanStyle { ResetStyleUpdateSpanStyle69 void ResetStyle() 70 { 71 updateTextColor.reset(); 72 updateFontSize.reset(); 73 updateItalicFontStyle.reset(); 74 updateFontWeight.reset(); 75 updateFontFamily.reset(); 76 updateTextDecoration.reset(); 77 updateTextDecorationColor.reset(); 78 updateTextDecorationStyle.reset(); 79 updateTextShadows.reset(); 80 updateFontFeature.reset(); 81 82 updateLineHeight.reset(); 83 updateLetterSpacing.reset(); 84 85 updateImageWidth.reset(); 86 updateImageHeight.reset(); 87 updateImageVerticalAlign.reset(); 88 updateImageFit.reset(); 89 marginProp.reset(); 90 borderRadius.reset(); 91 useThemeFontColor = true; 92 useThemeDecorationColor = true; 93 isInitDecoration = false; 94 95 updateSymbolColor.reset(); 96 updateSymbolFontSize.reset(); 97 updateSymbolFontWeight.reset(); 98 updateSymbolRenderingStrategy.reset(); 99 updateSymbolEffectStrategy.reset(); 100 } 101 102 std::optional<Color> updateTextColor = std::nullopt; 103 std::optional<CalcDimension> updateFontSize = std::nullopt; 104 std::optional<FontStyle> updateItalicFontStyle = std::nullopt; 105 std::optional<FontWeight> updateFontWeight = std::nullopt; 106 std::optional<std::vector<std::string>> updateFontFamily = std::nullopt; 107 std::optional<TextDecoration> updateTextDecoration = std::nullopt; 108 std::optional<Color> updateTextDecorationColor = std::nullopt; 109 std::optional<TextDecorationStyle> updateTextDecorationStyle = std::nullopt; 110 std::optional<std::vector<Shadow>> updateTextShadows = std::nullopt; 111 std::optional<NG::FONT_FEATURES_LIST> updateFontFeature = std::nullopt; 112 113 std::optional<CalcDimension> updateLineHeight = std::nullopt; 114 std::optional<CalcDimension> updateLetterSpacing = std::nullopt; 115 116 std::optional<CalcDimension> updateImageWidth = std::nullopt; 117 std::optional<CalcDimension> updateImageHeight = std::nullopt; 118 std::optional<VerticalAlign> updateImageVerticalAlign = std::nullopt; 119 std::optional<ImageFit> updateImageFit = std::nullopt; 120 121 std::optional<OHOS::Ace::NG::MarginProperty> marginProp = std::nullopt; 122 std::optional<OHOS::Ace::NG::BorderRadiusProperty> borderRadius = std::nullopt; 123 bool useThemeFontColor = true; 124 bool useThemeDecorationColor = true; 125 bool isInitDecoration = false; 126 127 std::optional<std::vector<Color>> updateSymbolColor = std::nullopt; 128 std::optional<CalcDimension> updateSymbolFontSize = std::nullopt; 129 std::optional<FontWeight> updateSymbolFontWeight = std::nullopt; 130 std::optional<uint32_t> updateSymbolRenderingStrategy = std::nullopt; 131 std::optional<uint32_t> updateSymbolEffectStrategy = std::nullopt; 132 UpdateColorByResourceIdUpdateSpanStyle133 void UpdateColorByResourceId() 134 { 135 if (updateTextColor) { 136 updateTextColor->UpdateColorByResourceId(); 137 } 138 if (updateTextDecorationColor) { 139 updateTextDecorationColor->UpdateColorByResourceId(); 140 } 141 if (updateTextShadows) { 142 auto& shadows = updateTextShadows.value(); 143 std::for_each(shadows.begin(), shadows.end(), [](Shadow& sd) { sd.UpdateColorByResourceId(); }); 144 } 145 if (updateSymbolColor) { 146 auto& colors = updateSymbolColor.value(); 147 std::for_each(colors.begin(), colors.end(), [](Color& cl) { cl.UpdateColorByResourceId(); }); 148 } 149 } 150 ToStringUpdateSpanStyle151 std::string ToString() const 152 { 153 auto jsonValue = JsonUtil::Create(true); 154 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, updateTextColor); 155 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, updateFontSize); 156 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, updateItalicFontStyle); 157 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, updateFontWeight); 158 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, updateTextDecoration); 159 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, updateTextDecorationColor); 160 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, updateTextDecorationStyle); 161 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, updateSymbolRenderingStrategy); 162 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, updateSymbolEffectStrategy); 163 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, updateImageWidth); 164 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, updateImageHeight); 165 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, updateImageVerticalAlign); 166 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, updateImageFit); 167 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, marginProp); 168 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, borderRadius); 169 JSON_STRING_PUT_BOOL(jsonValue, useThemeFontColor); 170 JSON_STRING_PUT_BOOL(jsonValue, useThemeDecorationColor); 171 return jsonValue->ToString(); 172 } 173 }; 174 175 struct UpdateParagraphStyle { ResetUpdateParagraphStyle176 void Reset() 177 { 178 textAlign.reset(); 179 leadingMargin.reset(); 180 wordBreak.reset(); 181 lineBreakStrategy.reset(); 182 } 183 std::optional<TextAlign> textAlign; 184 std::optional<NG::LeadingMargin> leadingMargin; 185 std::optional<WordBreak> wordBreak; 186 std::optional<LineBreakStrategy> lineBreakStrategy; 187 ToStringUpdateParagraphStyle188 std::string ToString() const 189 { 190 auto jsonValue = JsonUtil::Create(true); 191 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, textAlign); 192 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, leadingMargin); 193 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, wordBreak); 194 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, lineBreakStrategy); 195 return jsonValue->ToString(); 196 } 197 }; 198 199 struct RangeOptions { 200 std::optional<int32_t> start; 201 std::optional<int32_t> end; 202 ToStringRangeOptions203 std::string ToString() const 204 { 205 return "[" 206 + (start ? std::to_string(*start) : "nullopt") 207 + "," 208 + (end ? std::to_string(*end) : "nullopt") 209 + "]"; 210 } 211 }; 212 213 struct TextSpanOptions : SpanOptionBase { 214 std::optional<int32_t> offset; 215 std::string value; 216 std::optional<TextStyle> style; 217 std::optional<UpdateParagraphStyle> paraStyle; 218 UserGestureOptions userGestureOption; 219 bool useThemeFontColor = true; 220 bool useThemeDecorationColor = true; 221 ToStringTextSpanOptions222 std::string ToString() const 223 { 224 auto jsonValue = JsonUtil::Create(true); 225 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, offset); 226 JSON_STRING_PUT_STRING(jsonValue, value); 227 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, style); 228 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, paraStyle); 229 JSON_STRING_PUT_BOOL(jsonValue, useThemeFontColor); 230 JSON_STRING_PUT_BOOL(jsonValue, useThemeDecorationColor); 231 return jsonValue->ToString(); 232 } 233 }; 234 235 struct SymbolSpanOptions : SpanOptionBase { 236 std::optional<int32_t> offset; 237 uint32_t symbolId; 238 std::optional<TextStyle> style; 239 RefPtr<ResourceObject> resourceObject; 240 ToStringSymbolSpanOptions241 std::string ToString() const 242 { 243 auto jsonValue = JsonUtil::Create(true); 244 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, offset); 245 JSON_STRING_PUT_INT(jsonValue, symbolId); 246 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, style); 247 return jsonValue->ToString(); 248 } 249 }; 250 251 struct PlaceholderOptions { 252 std::optional<std::string> value; 253 std::optional<FontWeight> fontWeight; 254 std::optional<Dimension> fontSize; 255 std::optional<Color> fontColor; 256 std::optional<FontStyle> fontStyle; 257 std::vector<std::string> fontFamilies; 258 ToStringPlaceholderOptions259 std::string ToString() const 260 { 261 auto jsonValue = JsonUtil::Create(true); 262 JSON_STRING_PUT_OPTIONAL_STRING(jsonValue, value); 263 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, fontWeight); 264 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, fontSize); 265 JSON_STRING_PUT_OPTIONAL_STRINGABLE(jsonValue, fontColor); 266 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, fontStyle); 267 return jsonValue->ToString(); 268 } 269 }; 270 271 struct PreviewTextInfo { 272 std::optional<std::string> value; 273 std::optional<int32_t> offset; 274 ToStringPreviewTextInfo275 std::string ToString() const 276 { 277 auto jsonValue = JsonUtil::Create(true); 278 JSON_STRING_PUT_OPTIONAL_STRING(jsonValue, value); 279 JSON_STRING_PUT_OPTIONAL_INT(jsonValue, offset); 280 return jsonValue->ToString(); 281 } 282 }; 283 284 class ACE_EXPORT RichEditorBaseControllerBase : public AceType { 285 DECLARE_ACE_TYPE(RichEditorBaseControllerBase, AceType); 286 287 public: 288 virtual int32_t GetCaretOffset() = 0; 289 virtual bool SetCaretOffset(int32_t caretPosition) = 0; 290 virtual void SetTypingStyle(std::optional<struct UpdateSpanStyle> typingStyle, 291 std::optional<TextStyle> textStyle) = 0; 292 virtual std::optional<struct UpdateSpanStyle> GetTypingStyle() = 0; 293 virtual void CloseSelectionMenu() = 0; 294 virtual bool IsEditing() = 0; 295 virtual void StopEditing() = 0; 296 virtual void SetSelection(int32_t selectionStart, int32_t selectionEnd, 297 const std::optional<SelectionOptions>& options = std::nullopt) = 0; 298 virtual WeakPtr<NG::LayoutInfoInterface> GetLayoutInfoInterface() = 0; 299 virtual const PreviewTextInfo GetPreviewTextInfo() const = 0; 300 }; 301 302 class ACE_EXPORT RichEditorControllerBase : virtual public RichEditorBaseControllerBase { 303 DECLARE_ACE_TYPE(RichEditorControllerBase, RichEditorBaseControllerBase); 304 305 public: 306 virtual int32_t AddImageSpan(const ImageSpanOptions& options) = 0; 307 virtual int32_t AddTextSpan(const TextSpanOptions& options) = 0; 308 virtual int32_t AddSymbolSpan(const SymbolSpanOptions& options) = 0; 309 virtual int32_t AddPlaceholderSpan(const RefPtr<NG::UINode>& customNode, const SpanOptionBase& options) = 0; 310 virtual void UpdateParagraphStyle(int32_t start, int32_t end, const UpdateParagraphStyle& style) = 0; 311 virtual void UpdateSpanStyle( 312 int32_t start, int32_t end, TextStyle textStyle, ImageSpanAttribute imageStyle) = 0; 313 virtual void SetUpdateSpanStyle(struct UpdateSpanStyle updateSpanStyle) = 0; 314 virtual SelectionInfo GetSpansInfo(int32_t start, int32_t end) = 0; 315 virtual std::vector<ParagraphInfo> GetParagraphsInfo(int32_t start, int32_t end) = 0; 316 virtual void DeleteSpans(const RangeOptions& options) = 0; 317 virtual SelectionInfo GetSelectionSpansInfo() = 0; 318 virtual RefPtr<SpanStringBase> ToStyledString(int32_t start, int32_t end) = 0; 319 virtual SelectionInfo FromStyledString(RefPtr<SpanStringBase> value) = 0; 320 }; 321 322 class ACE_EXPORT RichEditorStyledStringControllerBase : virtual public RichEditorBaseControllerBase { 323 DECLARE_ACE_TYPE(RichEditorStyledStringControllerBase, RichEditorBaseControllerBase); 324 325 public: 326 virtual void SetStyledString(const RefPtr<SpanStringBase>& value) = 0; 327 virtual RefPtr<SpanStringBase> GetStyledString() = 0; 328 virtual SelectionRangeInfo GetSelection() = 0; 329 virtual void SetOnWillChange(std::function<bool(const NG::StyledStringChangeValue&)> && func) = 0; 330 virtual void SetOnDidChange(std::function<void(const NG::StyledStringChangeValue&)> && func) = 0; 331 }; 332 333 class ACE_FORCE_EXPORT RichEditorModel { 334 public: 335 static RichEditorModel* GetInstance(); 336 virtual ~RichEditorModel() = default; 337 virtual void Create(bool isStyledStringMode = false) = 0; 338 virtual RefPtr<RichEditorBaseControllerBase> GetRichEditorController() = 0; 339 virtual void SetOnReady(std::function<void()>&& func) = 0; 340 virtual void SetOnSelect(std::function<void(const BaseEventInfo*)>&& func) = 0; 341 virtual void SetOnSelectionChange(std::function<void(const BaseEventInfo*)>&& func) = 0; 342 virtual void SetAboutToIMEInput(std::function<bool(const NG::RichEditorInsertValue&)>&& func) = 0; 343 virtual void SetOnIMEInputComplete(std::function<void(const NG::RichEditorAbstractSpanResult&)>&& func) = 0; 344 virtual void SetOnDidIMEInput(std::function<void(const TextRange&)>&& func) = 0; 345 virtual void SetAboutToDelete(std::function<bool(const NG::RichEditorDeleteValue&)>&& func) = 0; 346 virtual void SetOnDeleteComplete(std::function<void()>&& func) = 0; 347 virtual void SetCustomKeyboard(std::function<void()>&& func, bool supportAvoidance = false) = 0; 348 virtual void SetCopyOption(CopyOptions& copyOptions) = 0; 349 virtual void BindSelectionMenu(NG::TextSpanType& editorType, NG::TextResponseType& responseType, 350 std::function<void()>& buildFunc, NG::SelectMenuParam& menuParam) = 0; 351 virtual void SetOnPaste(std::function<void(NG::TextCommonEvent&)>&& func) = 0; 352 virtual void SetPlaceholder(PlaceholderOptions& options) = 0; 353 virtual void SetTextDetectEnable(bool value) = 0; 354 virtual void SetSupportPreviewText(bool value) = 0; 355 virtual void SetTextDetectConfig(const TextDetectConfig& textDetectConfig) = 0; 356 virtual void SetSelectedBackgroundColor(const Color& selectedColor) = 0; 357 virtual void SetCaretColor(const Color& color) = 0; 358 virtual void SetOnEditingChange(std::function<void(const bool&)>&& func) = 0; 359 virtual void SetEnterKeyType(TextInputAction value) = 0; 360 virtual void SetOnSubmit(std::function<void(int32_t, NG::TextFieldCommonEvent&)>&& func) = 0; 361 virtual void SetOnWillChange(std::function<bool(const NG::RichEditorChangeValue&)>&& func) = 0; 362 virtual void SetOnDidChange(std::function<void(const NG::RichEditorChangeValue&)>&& func) = 0; 363 virtual void SetOnCut(std::function<void(NG::TextCommonEvent&)>&& func) = 0; 364 virtual void SetOnCopy(std::function<void(NG::TextCommonEvent&)>&& func) = 0; SetSelectionMenuOptions(const NG::OnCreateMenuCallback && onCreateMenuCallback,const NG::OnMenuItemClickCallback && onMenuItemClick)365 virtual void SetSelectionMenuOptions( 366 const NG::OnCreateMenuCallback&& onCreateMenuCallback, const NG::OnMenuItemClickCallback&& onMenuItemClick) {} SetRequestKeyboardOnFocus(bool needToRequest)367 virtual void SetRequestKeyboardOnFocus(bool needToRequest) {} SetEnableHapticFeedback(bool isEnabled)368 virtual void SetEnableHapticFeedback(bool isEnabled) {} SetBarState(DisplayMode mode)369 virtual void SetBarState(DisplayMode mode) {} SetImagePreviewMenuParam(std::function<void ()> & buildFunc,const NG::SelectMenuParam & menuParam)370 virtual void SetImagePreviewMenuParam(std::function<void()>& buildFunc, const NG::SelectMenuParam& menuParam) {} 371 private: 372 static std::unique_ptr<RichEditorModel> instance_; 373 static std::mutex mutex_; 374 }; 375 } // namespace OHOS::Ace 376 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_RICH_EDITOR_RICH_EDITOR_MODEL_H 377