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