1 /*
2 * Copyright (c) 2022-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 #include "core/components_ng/pattern/text_field/text_field_paint_method.h"
16
17 #include "base/geometry/dimension.h"
18 #include "base/geometry/ng/offset_t.h"
19 #include "base/geometry/ng/rect_t.h"
20 #include "base/geometry/rect.h"
21 #include "base/geometry/rrect.h"
22 #include "base/utils/utils.h"
23 #include "core/components/common/properties/alignment.h"
24 #include "core/components/common/properties/border.h"
25 #include "core/components/common/properties/color.h"
26 #include "core/components/common/properties/decoration.h"
27 #include "core/components/common/properties/placement.h"
28 #include "core/components/popup/popup_theme.h"
29 #include "core/components/theme/theme_manager.h"
30 #include "core/components_ng/pattern/pattern.h"
31 #include "core/components_ng/pattern/search/search_event_hub.h"
32 #include "core/components_ng/pattern/search/search_pattern.h"
33 #include "core/components_ng/pattern/search/search_text_field.h"
34 #include "core/components_ng/pattern/text_field/text_field_pattern.h"
35 #include "core/components_ng/property/measure_utils.h"
36 #include "core/components_ng/render/canvas_image.h"
37 #include "core/components_ng/render/drawing.h"
38 #include "core/components_ng/render/drawing_prop_convertor.h"
39 #include "core/components_ng/render/image_painter.h"
40 #include "core/pipeline_ng/pipeline_context.h"
41
42 namespace OHOS::Ace::NG {
TextFieldPaintMethod(const WeakPtr<Pattern> & pattern,const RefPtr<TextFieldOverlayModifier> & textFieldOverlayModifier,const RefPtr<TextFieldContentModifier> & textFieldContentModifier,const RefPtr<TextFieldForegroundModifier> & textFieldForegroundModifier)43 TextFieldPaintMethod::TextFieldPaintMethod(const WeakPtr<Pattern>& pattern,
44 const RefPtr<TextFieldOverlayModifier>& textFieldOverlayModifier,
45 const RefPtr<TextFieldContentModifier>& textFieldContentModifier,
46 const RefPtr<TextFieldForegroundModifier>& textFieldForegroundModifier)
47 : pattern_(pattern), textFieldOverlayModifier_(textFieldOverlayModifier),
48 textFieldContentModifier_(textFieldContentModifier), textFieldForegroundModifier_(textFieldForegroundModifier)
49 {}
50
GetContentModifier(PaintWrapper * paintWrapper)51 RefPtr<Modifier> TextFieldPaintMethod::GetContentModifier(PaintWrapper* paintWrapper)
52 {
53 return textFieldContentModifier_;
54 }
55
UpdateContentModifier(PaintWrapper * paintWrapper)56 void TextFieldPaintMethod::UpdateContentModifier(PaintWrapper* paintWrapper)
57 {
58 CHECK_NULL_VOID(paintWrapper);
59 CHECK_NULL_VOID(textFieldContentModifier_);
60 auto paintProperty = DynamicCast<TextFieldPaintProperty>(paintWrapper->GetPaintProperty());
61 CHECK_NULL_VOID(paintProperty);
62 OffsetF contentOffset = paintWrapper->GetContentOffset();
63 SizeF contentSize = paintWrapper->GetContentSize();
64 auto textFieldPattern = DynamicCast<TextFieldPattern>(pattern_.Upgrade());
65 CHECK_NULL_VOID(textFieldPattern);
66 if (textFieldPattern->GetContChange()) {
67 textFieldContentModifier_->ChangeDragStatus();
68 textFieldPattern->ResetContChange();
69 }
70
71 auto textFieldLayoutProperty = textFieldPattern->GetLayoutProperty<TextFieldLayoutProperty>();
72 CHECK_NULL_VOID(textFieldLayoutProperty);
73 auto textValue = textFieldPattern->GetTextValue();
74 auto isPasswordType = textFieldPattern->IsInPasswordMode();
75 auto showPlaceHolder = textFieldLayoutProperty->GetValueValue("").empty();
76 auto needObscureText = isPasswordType && textFieldPattern->GetTextObscured() && !showPlaceHolder;
77 auto frameNode = textFieldPattern->GetHost();
78 CHECK_NULL_VOID(frameNode);
79 auto pipeline = frameNode->GetContext();
80 CHECK_NULL_VOID(pipeline);
81 auto theme = pipeline->GetTheme<TextFieldTheme>();
82 CHECK_NULL_VOID(theme);
83 auto text = TextFieldPattern::CreateDisplayText(
84 textValue, textFieldPattern->GetNakedCharPosition(), needObscureText, theme->IsShowPasswordDirectly());
85 auto displayText = StringUtils::Str16ToStr8(text);
86 textFieldContentModifier_->SetTextValue(displayText);
87 textFieldContentModifier_->SetPlaceholderValue(textFieldPattern->GetPlaceHolder());
88
89 auto currentTextRectOffsetX = textFieldPattern->GetTextRect().GetX();
90 auto currentTextRectOffsetY =
91 textFieldPattern->IsTextArea() ? textFieldPattern->GetTextRect().GetY() : contentOffset.GetY();
92 if (textFieldContentModifier_->GetTextRectX() != currentTextRectOffsetX ||
93 (textFieldPattern->IsTextArea() ? textFieldContentModifier_->GetTextRectY()
94 : textFieldContentModifier_->GetContentOffsetY()) != currentTextRectOffsetY) {
95 auto searchField = DynamicCast<SearchTextFieldPattern>(textFieldPattern);
96 if (searchField) {
97 auto parentFrameNode = AceType::DynamicCast<FrameNode>(frameNode->GetParent());
98 CHECK_NULL_VOID(parentFrameNode);
99 auto searchPattern = parentFrameNode->GetPattern<SearchPattern>();
100 CHECK_NULL_VOID(searchPattern);
101 auto textFieldOffset = searchPattern->GetTextFieldOffset();
102 currentTextRectOffsetX += textFieldOffset.GetX();
103 currentTextRectOffsetY += textFieldOffset.GetY();
104 }
105 auto eventHub = frameNode->GetEventHub<TextFieldEventHub>();
106 eventHub->FireOnScrollChangeEvent(currentTextRectOffsetX, currentTextRectOffsetY);
107 }
108 textFieldContentModifier_->SetContentOffset(contentOffset);
109 textFieldContentModifier_->SetContentSize(contentSize);
110 textFieldContentModifier_->SetTextRectY(textFieldPattern->GetTextRect().GetY());
111 textFieldContentModifier_->SetTextRectX(textFieldPattern->GetTextRect().GetX());
112 textFieldContentModifier_->SetTextAlign(textFieldPattern->GetTextAlign());
113 auto layoutProperty = frameNode->GetLayoutProperty<TextFieldLayoutProperty>();
114 CHECK_NULL_VOID(layoutProperty);
115 textFieldContentModifier_->SetTextObscured(textFieldPattern->GetTextObscured());
116 textFieldContentModifier_->SetShowErrorState(
117 layoutProperty->GetShowErrorTextValue(false) && !textFieldPattern->IsNormalInlineState());
118 textFieldContentModifier_->SetErrorTextValue(layoutProperty->GetErrorTextValue(""));
119 textFieldContentModifier_->SetShowUnderlineState(layoutProperty->GetShowUnderlineValue(false));
120 PropertyChangeFlag flag = 0;
121 if (textFieldContentModifier_->NeedMeasureUpdate(flag)) {
122 frameNode->MarkDirtyNode(flag);
123 }
124 }
125
GetOverlayModifier(PaintWrapper * paintWrapper)126 RefPtr<Modifier> TextFieldPaintMethod::GetOverlayModifier(PaintWrapper* paintWrapper)
127 {
128 return textFieldOverlayModifier_;
129 }
130
SetShowUnderlineWidth()131 void TextFieldPaintMethod::SetShowUnderlineWidth()
132 {
133 auto textFieldPattern = DynamicCast<TextFieldPattern>(pattern_.Upgrade());
134 CHECK_NULL_VOID(textFieldPattern);
135 auto textFieldLayoutProperty = textFieldPattern->GetLayoutProperty<TextFieldLayoutProperty>();
136 CHECK_NULL_VOID(textFieldLayoutProperty);
137 if (textFieldLayoutProperty->HasShowUnderline() && textFieldLayoutProperty->GetShowUnderlineValue()) {
138 textFieldOverlayModifier_->SetUnderlineWidth(textFieldPattern->GetUnderlineWidth());
139 textFieldOverlayModifier_->SetUnderlineColor(textFieldPattern->GetUnderlineColor());
140 } else {
141 textFieldOverlayModifier_->SetUnderlineWidth(0.0f);
142 }
143 }
144
UpdateOverlayModifier(PaintWrapper * paintWrapper)145 void TextFieldPaintMethod::UpdateOverlayModifier(PaintWrapper* paintWrapper)
146 {
147 CHECK_NULL_VOID(paintWrapper);
148 CHECK_NULL_VOID(textFieldOverlayModifier_);
149
150 auto textFieldPattern = DynamicCast<TextFieldPattern>(pattern_.Upgrade());
151 CHECK_NULL_VOID(textFieldPattern);
152 auto paintProperty = DynamicCast<TextFieldPaintProperty>(paintWrapper->GetPaintProperty());
153 CHECK_NULL_VOID(paintProperty);
154 auto frameNode = textFieldPattern->GetHost();
155 CHECK_NULL_VOID(frameNode);
156 auto pipelineContext = frameNode->GetContext();
157 CHECK_NULL_VOID(pipelineContext);
158 auto themeManager = pipelineContext->GetThemeManager();
159 CHECK_NULL_VOID(themeManager);
160 auto theme = themeManager->GetTheme<TextFieldTheme>();
161 CHECK_NULL_VOID(theme);
162
163 OffsetF contentOffset = paintWrapper->GetContentOffset();
164 textFieldOverlayModifier_->SetContentOffset(contentOffset);
165 SizeF contentSize = paintWrapper->GetContentSize();
166 textFieldOverlayModifier_->SetContentSize(contentSize);
167 auto frameSize = paintWrapper->GetGeometryNode()->GetFrameSize();
168 textFieldOverlayModifier_->SetFrameSize(frameSize);
169 auto currentOffset = textFieldPattern->GetCurrentOffset();
170 textFieldOverlayModifier_->SetCurrentOffset(currentOffset);
171
172 auto cursorVisible = textFieldPattern->GetCursorVisible();
173 textFieldOverlayModifier_->SetCursorVisible(cursorVisible);
174 auto cursorRect = textFieldPattern->GetCaretRect();
175 textFieldOverlayModifier_->SetCursorOffset(cursorRect.GetOffset());
176 textFieldOverlayModifier_->SetCursorWidth(cursorRect.Width());
177 auto cursorColor = paintProperty->GetCursorColorValue(theme->GetCursorColor());
178 textFieldOverlayModifier_->SetCursorColor(cursorColor);
179
180 InputStyle inputStyle = paintProperty->GetInputStyleValue(InputStyle::DEFAULT);
181 textFieldOverlayModifier_->SetInputStyle(inputStyle);
182
183 auto selectedColor = paintProperty->GetSelectedBackgroundColorValue(theme->GetSelectedColor());
184 textFieldOverlayModifier_->SetSelectedBackGroundColor(selectedColor);
185
186 SetShowUnderlineWidth();
187
188 textFieldOverlayModifier_->SetShowSelect(textFieldPattern->GetShowSelect());
189 textFieldOverlayModifier_->SetChangeSelectedRects(textFieldPattern->NeedPaintSelect());
190 auto textSelectController = textFieldPattern->GetTextSelectController();
191 CHECK_NULL_VOID(textSelectController);
192 textSelectController->FireSelectEvent();
193
194 textFieldOverlayModifier_->SetTextRect(textFieldPattern->GetTextRect());
195 textFieldOverlayModifier_->SetShowPreviewTextDecoration(textFieldPattern->GetIsPreviewText());
196 textFieldOverlayModifier_->SetPreviewTextRects(textFieldPattern->NeedDrawPreviewText());
197 auto previewDecorationColor = paintProperty->GetCursorColorValue(textFieldPattern->GetPreviewDecorationColor());
198 textFieldOverlayModifier_->SetPreviewTextDecorationColor(previewDecorationColor);
199 textFieldOverlayModifier_->SetPreviewTextStyle(textFieldPattern->GetPreviewTextStyle());
200 UpdateScrollBar();
201 }
202
UpdateScrollBar()203 void TextFieldPaintMethod::UpdateScrollBar()
204 {
205 auto scrollBar = scrollBar_.Upgrade();
206 if (!scrollBar || !scrollBar->NeedPaint()) {
207 return;
208 }
209 if (scrollBar->GetPositionModeUpdate()) {
210 textFieldOverlayModifier_->SetPositionMode(scrollBar->GetPositionMode());
211 }
212 OffsetF fgOffset(scrollBar->GetActiveRect().Left(), scrollBar->GetActiveRect().Top());
213 textFieldOverlayModifier_->StartBarAnimation(scrollBar->GetHoverAnimationType(),
214 scrollBar->GetOpacityAnimationType(), scrollBar->GetNeedAdaptAnimation(), scrollBar->GetActiveRect());
215 scrollBar->SetHoverAnimationType(HoverAnimationType::NONE);
216 textFieldOverlayModifier_->SetBarColor(scrollBar->GetForegroundColor());
217 scrollBar->SetOpacityAnimationType(OpacityAnimationType::NONE);
218 }
219
GetForegroundModifier(PaintWrapper * paintWrapper)220 RefPtr<Modifier> TextFieldPaintMethod::GetForegroundModifier(PaintWrapper* paintWrapper)
221 {
222 return textFieldForegroundModifier_;
223 }
224
UpdateForegroundModifier(PaintWrapper * paintWrapper)225 void TextFieldPaintMethod::UpdateForegroundModifier(PaintWrapper* paintWrapper)
226 {
227 CHECK_NULL_VOID(textFieldForegroundModifier_);
228 auto textFieldPattern = DynamicCast<TextFieldPattern>(pattern_.Upgrade());
229 CHECK_NULL_VOID(textFieldPattern);
230 auto paintProperty = textFieldPattern->GetPaintProperty<TextFieldPaintProperty>();
231 CHECK_NULL_VOID(paintProperty);
232 textFieldForegroundModifier_->SetInnerBorderWidth(
233 static_cast<float>(paintProperty->GetInnerBorderWidthValue(Dimension()).ConvertToPx()));
234 }
235 } // namespace OHOS::Ace::NG
236