• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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