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