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 #include "core/components_ng/pattern/rich_editor/rich_editor_overlay_modifier.h"
17
18 #include "base/utils/utils.h"
19 #include "core/components_ng/pattern/rich_editor/rich_editor_pattern.h"
20 #include "core/components_ng/pattern/rich_editor/rich_editor_theme.h"
21 #include "core/components_ng/render/drawing.h"
22 #include "core/components_ng/render/drawing_prop_convertor.h"
23 #include "core/pipeline_ng/pipeline_context.h"
24
25 namespace OHOS::Ace::NG {
RichEditorOverlayModifier(const WeakPtr<OHOS::Ace::NG::Pattern> & pattern,const WeakPtr<ScrollBarOverlayModifier> & scrollbarOverlayModifier,WeakPtr<ScrollEdgeEffect> && edgeEffect)26 RichEditorOverlayModifier::RichEditorOverlayModifier(const WeakPtr<OHOS::Ace::NG::Pattern>& pattern,
27 const WeakPtr<ScrollBarOverlayModifier>& scrollbarOverlayModifier, WeakPtr<ScrollEdgeEffect>&& edgeEffect)
28 : TextOverlayModifier(), pattern_(pattern), edgeEffect_(edgeEffect),
29 scrollBarOverlayModifier_(scrollbarOverlayModifier)
30 {
31 caretVisible_ = AceType::MakeRefPtr<PropertyBool>(false);
32 AttachProperty(caretVisible_);
33 caretOffset_ = AceType::MakeRefPtr<PropertyOffsetF>(OffsetF());
34 AttachProperty(caretOffset_);
35 caretHeight_ = AceType::MakeRefPtr<PropertyFloat>(0.0f);
36 AttachProperty(caretHeight_);
37 caretWidth_ = AceType::MakeRefPtr<PropertyFloat>(0.0f);
38 AttachProperty(caretWidth_);
39 caretColor_ = AceType::MakeRefPtr<PropertyInt>(0);
40 AttachProperty(caretColor_);
41 scrollOffset_ = AceType::MakeRefPtr<PropertyFloat>(0.0f);
42 AttachProperty(scrollOffset_);
43 frameSize_ = AceType::MakeRefPtr<PropertySizeF>(SizeF());
44 AttachProperty(frameSize_);
45 scrollBarOpacityType_ = AceType::MakeRefPtr<PropertyInt>(-1);
46 AttachProperty(scrollBarOpacityType_);
47 textHeight_ = AceType::MakeRefPtr<PropertyFloat>(0.0f);
48 AttachProperty(textHeight_);
49 }
50
SetCaretOffsetAndHeight(const OffsetF & cursorOffset,float height)51 void RichEditorOverlayModifier::SetCaretOffsetAndHeight(const OffsetF& cursorOffset, float height)
52 {
53 caretOffset_->Set(cursorOffset);
54 if (height > 0.0f) {
55 caretHeight_->Set(height);
56 }
57 }
58
SetCaretColor(uint32_t caretColor)59 void RichEditorOverlayModifier::SetCaretColor(uint32_t caretColor)
60 {
61 CHECK_NULL_VOID(caretColor_);
62 caretColor_->Set(static_cast<int32_t>(caretColor));
63 }
64
SetCaretWidth(float width)65 void RichEditorOverlayModifier::SetCaretWidth(float width)
66 {
67 if (width <= 0.0f) {
68 return;
69 }
70 caretWidth_->Set(width);
71 }
72
GetCaretWidth() const73 float RichEditorOverlayModifier::GetCaretWidth() const
74 {
75 return caretWidth_->Get();
76 }
77
SetCaretVisible(bool value)78 void RichEditorOverlayModifier::SetCaretVisible(bool value)
79 {
80 caretVisible_->Set(value);
81 }
82
SetScrollOffset(float value)83 void RichEditorOverlayModifier::SetScrollOffset(float value)
84 {
85 scrollOffset_->Set(value);
86 }
87
SetScrollBarOpacityType(int32_t value)88 void RichEditorOverlayModifier::SetScrollBarOpacityType(int32_t value)
89 {
90 scrollBarOpacityType_->Set(value);
91 }
92
SetTextHeight(float value)93 void RichEditorOverlayModifier::SetTextHeight(float value)
94 {
95 textHeight_->Set(value);
96 }
97
SetFrameSize(const SizeF & value)98 void RichEditorOverlayModifier::SetFrameSize(const SizeF& value)
99 {
100 frameSize_->Set(value);
101 }
102
GetCaretHeight() const103 float RichEditorOverlayModifier::GetCaretHeight() const
104 {
105 return caretHeight_->Get();
106 }
107
GetCaretOffset() const108 OffsetF RichEditorOverlayModifier::GetCaretOffset() const
109 {
110 return caretOffset_->Get();
111 }
112
PaintCaret(DrawingContext & drawingContext) const113 void RichEditorOverlayModifier::PaintCaret(DrawingContext& drawingContext) const
114 {
115 if (!caretVisible_->Get()) {
116 return;
117 }
118 auto offset = caretOffset_->Get();
119 drawingContext.canvas.Save();
120 RSBrush brush;
121 brush.SetAntiAlias(true);
122 brush.SetColor(caretColor_->Get());
123 drawingContext.canvas.AttachBrush(brush);
124
125 if (GreatOrEqual(offset.GetX() + caretWidth_->Get(), contentRect_.value().Right())) {
126 drawingContext.canvas.DrawRect(RSRect(
127 offset.GetX() - caretWidth_->Get(), offset.GetY(), offset.GetX(), offset.GetY() + caretHeight_->Get()));
128 } else {
129 drawingContext.canvas.DrawRect(RSRect(
130 offset.GetX(), offset.GetY(), offset.GetX() + caretWidth_->Get(), offset.GetY() + caretHeight_->Get()));
131 }
132
133 drawingContext.canvas.DetachBrush();
134 drawingContext.canvas.Restore();
135 }
136
PaintScrollBar(DrawingContext & context)137 void RichEditorOverlayModifier::PaintScrollBar(DrawingContext& context)
138 {
139 auto scrollBarOverlayModifier = scrollBarOverlayModifier_.Upgrade();
140 CHECK_NULL_VOID(scrollBarOverlayModifier);
141 scrollBarOverlayModifier->onDraw(context);
142 }
143
PaintEdgeEffect(const SizeF & frameSize,RSCanvas & canvas)144 void RichEditorOverlayModifier::PaintEdgeEffect(const SizeF& frameSize, RSCanvas& canvas)
145 {
146 auto edgeEffect = edgeEffect_.Upgrade();
147 CHECK_NULL_VOID(edgeEffect);
148 edgeEffect->Paint(canvas, frameSize, { 0.0f, 0.0f });
149 }
150
onDraw(DrawingContext & drawingContext)151 void RichEditorOverlayModifier::onDraw(DrawingContext& drawingContext)
152 {
153 if (!showSelect_->Get()) {
154 PaintScrollBar(drawingContext);
155 PaintEdgeEffect(frameSize_->Get(), drawingContext.canvas);
156 auto pattern = AceType::DynamicCast<RichEditorPattern>(pattern_.Upgrade());
157 CHECK_NULL_VOID(pattern);
158 pattern->SetShowSelect(true);
159 return;
160 }
161 drawingContext.canvas.Save();
162 if (contentRect_.has_value()) {
163 auto pipeline = PipelineContext::GetCurrentContext();
164 CHECK_NULL_VOID(pipeline);
165 auto richEditorTheme = pipeline->GetTheme<RichEditorTheme>();
166 auto defaultCaretHeight = richEditorTheme->GetDefaultCaretHeight().ConvertToPx();
167 if (contentRect_->Height() < defaultCaretHeight) {
168 contentRect_->SetHeight(defaultCaretHeight);
169 }
170 drawingContext.canvas.ClipRect(ToRSRect(contentRect_.value()), RSClipOp::INTERSECT);
171 }
172 PaintCaret(drawingContext);
173 TextOverlayModifier::onDraw(drawingContext);
174 drawingContext.canvas.Restore();
175 PaintScrollBar(drawingContext);
176 PaintEdgeEffect(frameSize_->Get(), drawingContext.canvas);
177 }
178
UpdateScrollBar(PaintWrapper * paintWrapper)179 void RichEditorOverlayModifier::UpdateScrollBar(PaintWrapper* paintWrapper)
180 {
181 auto richEditorPattern = AceType::DynamicCast<RichEditorPattern>(pattern_.Upgrade());
182 CHECK_NULL_VOID(richEditorPattern);
183 auto scrollBar = richEditorPattern->GetScrollControllerBar();
184 if (!scrollBar || !scrollBar->NeedPaint()) {
185 return;
186 }
187 auto scrollBarOverlayModifier = scrollBarOverlayModifier_.Upgrade();
188 CHECK_NULL_VOID(scrollBarOverlayModifier);
189 if (scrollBar->GetPositionModeUpdate()) {
190 scrollBarOverlayModifier->SetPositionMode(scrollBar->GetPositionMode());
191 }
192 SetScrollBarOpacityType(static_cast<int32_t>(scrollBar->GetOpacityAnimationType()));
193 scrollBarOverlayModifier->StartBarAnimation(scrollBar->GetHoverAnimationType(),
194 scrollBar->GetOpacityAnimationType(), scrollBar->GetNeedAdaptAnimation(), scrollBar->GetActiveRect());
195 scrollBar->SetHoverAnimationType(HoverAnimationType::NONE);
196 scrollBarOverlayModifier->SetBarColor(scrollBar->GetForegroundColor());
197 scrollBar->SetOpacityAnimationType(OpacityAnimationType::NONE);
198 }
199 } // namespace OHOS::Ace::NG
200