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