• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/text_field/text_input_response_area.h"
17 
18 #include "base/geometry/dimension.h"
19 #include "base/geometry/ng/offset_t.h"
20 #include "base/geometry/ng/size_t.h"
21 #include "base/memory/referenced.h"
22 #include "base/utils/utils.h"
23 #include "core/common/container.h"
24 #include "core/common/ime/text_input_type.h"
25 #include "core/components/common/layout/constants.h"
26 #include "core/components/theme/icon_theme.h"
27 #include "core/components_ng/pattern/stack/stack_pattern.h"
28 #include "core/components_ng/pattern/text/text_pattern.h"
29 #include "core/components_ng/pattern/text_field/text_field_pattern.h"
30 
31 namespace OHOS::Ace::NG {
32 
33 namespace {
34 constexpr float MAX_FONT_SCALE = 2.0f;
35 constexpr Dimension ICON_MAX_SIZE = 40.0_vp;
36 constexpr Dimension DEFAULT_ICON_HOT_ZONE = 40.0_vp;
37 constexpr Dimension ICON_FOCUS_PADDING = 2.0_vp;
38 constexpr Dimension DEFAULT_HOVER_SIZE = 32.0_vp;
39 constexpr int HALF_SPACE = 2;
40 constexpr int DOUBLE_PADDING = 2;
41 } // namespace
42 
43 // TextInputResponseArea begin
LayoutChild(LayoutWrapper * layoutWrapper,int32_t index,float & nodeWidth)44 void TextInputResponseArea::LayoutChild(LayoutWrapper* layoutWrapper, int32_t index, float& nodeWidth)
45 {
46     auto frameNode = layoutWrapper->GetHostNode();
47     CHECK_NULL_VOID(frameNode);
48     auto children = frameNode->GetChildren();
49     CHECK_NULL_VOID(!children.empty());
50     auto pattern = frameNode->GetPattern<TextFieldPattern>();
51     CHECK_NULL_VOID(pattern);
52     auto textInputGeometryNode = layoutWrapper->GetGeometryNode();
53     CHECK_NULL_VOID(textInputGeometryNode);
54     auto contentRect = textInputGeometryNode->GetContentRect();
55     auto textInputFrameSize = textInputGeometryNode->GetFrameSize();
56     auto childWrapper = layoutWrapper->GetOrCreateChildByIndex(index);
57     CHECK_NULL_VOID(childWrapper);
58     auto childGeometryNode = childWrapper->GetGeometryNode();
59     CHECK_NULL_VOID(childGeometryNode);
60     auto childFrameSize = childGeometryNode->GetFrameSize();
61     auto childOffset = GetChildOffset(textInputFrameSize, contentRect, childFrameSize, nodeWidth);
62     childGeometryNode->SetFrameOffset(childOffset);
63     childWrapper->GetGeometryNode()->SetFrameSize(childFrameSize);
64     areaRect_.SetSize(childFrameSize);
65     areaRect_.SetOffset(childOffset);
66     childWrapper->Layout();
67     nodeWidth += childFrameSize.Width();
68 }
69 
GetChildOffset(SizeF parentSize,RectF contentRect,SizeF childSize,float nodeWidth)70 OffsetF TextInputResponseArea::GetChildOffset(SizeF parentSize, RectF contentRect, SizeF childSize, float nodeWidth)
71 {
72     auto offset = Alignment::GetAlignPosition(parentSize, childSize, Alignment::CENTER);
73     auto textFieldPattern = hostPattern_.Upgrade();
74     auto layoutProperty = textFieldPattern->GetLayoutProperty<TextFieldLayoutProperty>();
75     auto isRTL = layoutProperty->GetNonAutoLayoutDirection() == TextDirection::RTL;
76     if (isRTL) {
77         return OffsetF(nodeWidth, offset.GetY());
78     } else {
79         return OffsetF(parentSize.Width() - childSize.Width() - nodeWidth, offset.GetY());
80     }
81 }
82 
Measure(LayoutWrapper * layoutWrapper,int32_t index)83 SizeF TextInputResponseArea::Measure(LayoutWrapper* layoutWrapper, int32_t index)
84 {
85     SizeF size(0, 0);
86     CHECK_NULL_RETURN(layoutWrapper, size);
87     auto childWrapper = layoutWrapper->GetOrCreateChildByIndex(index);
88     auto textfieldLayoutProperty = AceType::DynamicCast<TextFieldLayoutProperty>(layoutWrapper->GetLayoutProperty());
89     CHECK_NULL_RETURN(textfieldLayoutProperty, size);
90     auto childLayoutConstraint = textfieldLayoutProperty->CreateChildConstraint();
91     CHECK_NULL_RETURN(childWrapper, size);
92     auto childLayoutProperty = childWrapper->GetLayoutProperty();
93     childWrapper->Measure(childLayoutConstraint);
94     auto geometryNode = childWrapper->GetGeometryNode();
95     CHECK_NULL_RETURN(geometryNode, size);
96     return geometryNode->GetFrameSize();
97 }
98 
GetFrameSize(bool withSafeArea)99 SizeF TextInputResponseArea::GetFrameSize(bool withSafeArea)
100 {
101     auto frameNode = GetFrameNode();
102     CHECK_NULL_RETURN(frameNode, SizeF(0, 0));
103     auto geometryNode = frameNode->GetGeometryNode();
104     CHECK_NULL_RETURN(geometryNode, SizeF(0, 0));
105     return geometryNode->GetFrameSize(withSafeArea);
106 }
107 
GetStackAlignment(const TextDirection & userDirection)108 Alignment TextInputResponseArea::GetStackAlignment(const TextDirection& userDirection)
109 {
110     bool isSysRtl = AceApplicationInfo::GetInstance().IsRightToLeft();
111     if ((isSysRtl && userDirection == TextDirection::LTR) ||
112         (!isSysRtl && userDirection == TextDirection::RTL)) {
113         return Alignment::CENTER_RIGHT;
114     }
115     return Alignment::CENTER_LEFT;
116 }
117 
CreateResponseAreaImageNode(const ImageSourceInfo & imageSourceInfo,ImageFit imageFit,const CalcSize & userDefinedIdealSize)118 RefPtr<FrameNode> TextInputResponseArea::CreateResponseAreaImageNode(const ImageSourceInfo& imageSourceInfo,
119     ImageFit imageFit, const CalcSize& userDefinedIdealSize)
120 {
121     auto imageNode = FrameNode::CreateFrameNode(
122         V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
123     CHECK_NULL_RETURN(imageNode, nullptr);
124     imageNode->SetDraggable(false);
125     auto imageLayoutProperty = imageNode->GetLayoutProperty<ImageLayoutProperty>();
126     CHECK_NULL_RETURN(imageLayoutProperty, nullptr); // return nullptr as this is severe situation
127     imageLayoutProperty->UpdateImageSourceInfo(imageSourceInfo);
128     imageLayoutProperty->UpdateImageFit(imageFit);
129     imageLayoutProperty->UpdateUserDefinedIdealSize(userDefinedIdealSize);
130     return imageNode;
131 }
132 
SetHoverRect(RefPtr<FrameNode> & stackNode,RectF & rect,float iconSize,float hoverRectHeight,bool isFocus)133 void TextInputResponseArea::SetHoverRect(RefPtr<FrameNode>& stackNode, RectF& rect, float iconSize,
134     float hoverRectHeight, bool isFocus)
135 {
136     auto textFieldPattern = hostPattern_.Upgrade();
137     CHECK_NULL_VOID(textFieldPattern);
138     auto layoutProperty = textFieldPattern->GetLayoutProperty<TextFieldLayoutProperty>();
139     CHECK_NULL_VOID(layoutProperty);
140     CHECK_NULL_VOID(stackNode);
141     auto stackGeometryNode = stackNode->GetGeometryNode();
142     CHECK_NULL_VOID(stackGeometryNode);
143     auto stackRect = stackGeometryNode->GetFrameRect();
144     auto imageFrameNode = AceType::DynamicCast<FrameNode>(stackNode->GetFirstChild());
145     CHECK_NULL_VOID(imageFrameNode);
146     auto imageGeometryNode = imageFrameNode->GetGeometryNode();
147     CHECK_NULL_VOID(imageGeometryNode);
148     auto imageRect = imageGeometryNode->GetFrameRect();
149     if (isFocus) {
150         hoverRectHeight = hoverRectHeight - ICON_FOCUS_PADDING.ConvertToPx();
151     }
152 
153     auto iconHoverPadding = (hoverRectHeight - iconSize) / HALF_SPACE;
154     auto stackHoverPadding = (hoverRectHeight - stackRect.Height()) / HALF_SPACE;
155     auto isRTL = layoutProperty->GetNonAutoLayoutDirection() == TextDirection::RTL;
156     if (isRTL) {
157         rect = RectF(stackRect.GetX() + stackRect.Width() - imageRect.Width() - iconHoverPadding,
158             stackRect.GetY() - stackHoverPadding, hoverRectHeight, hoverRectHeight);
159     } else {
160         rect = RectF(stackRect.GetX() - iconHoverPadding, stackRect.GetY() - stackHoverPadding,
161             hoverRectHeight, hoverRectHeight);
162     }
163 }
164 
SetHotZoneRect(DimensionRect & hotZoneRegion,float iconSize,float hotZoneHeight)165 void TextInputResponseArea::SetHotZoneRect(DimensionRect& hotZoneRegion, float iconSize, float hotZoneHeight)
166 {
167     auto hotZoneX = - (hotZoneHeight - iconSize) / HALF_SPACE;
168     auto hotZoneY = - (hotZoneHeight - iconSize) / HALF_SPACE;
169 
170     OffsetF hotZoneOffset;
171     hotZoneOffset.SetX(hotZoneX);
172     hotZoneOffset.SetY(hotZoneY);
173     SizeF hotZoneSize;
174     hotZoneSize.SetWidth(hotZoneHeight);
175     hotZoneSize.SetHeight(hotZoneHeight);
176     hotZoneRegion.SetSize(DimensionSize(Dimension(hotZoneSize.Width()), Dimension(hotZoneSize.Height())));
177     hotZoneRegion.SetOffset(DimensionOffset(Dimension(hotZoneOffset.GetX()), Dimension(hotZoneOffset.GetY())));
178 }
179 // TextInputResponseArea end
180 
181 // PasswordResponseArea begin
InitResponseArea()182 void PasswordResponseArea::InitResponseArea()
183 {
184     ClearArea();
185     auto pattern = hostPattern_.Upgrade();
186     CHECK_NULL_VOID(pattern);
187     auto host = pattern->GetHost();
188     CHECK_NULL_VOID(host);
189     if (!IsShowPasswordIcon()) {
190         return;
191     }
192     auto passwordNode = CreateNode();
193     CHECK_NULL_VOID(passwordNode);
194     passwordNode->MountToParent(host);
195 }
196 
GetFrameNode()197 const RefPtr<FrameNode> PasswordResponseArea::GetFrameNode()
198 {
199     auto frameNode = passwordNode_.Upgrade();
200     CHECK_NULL_RETURN(frameNode, nullptr);
201     auto stackNode = frameNode->GetParent();
202     CHECK_NULL_RETURN(stackNode, nullptr);
203     auto ret = AceType::DynamicCast<FrameNode>(stackNode);
204     CHECK_NULL_RETURN(ret, nullptr);
205     return ret;
206 }
207 
CreateNode()208 RefPtr<FrameNode> PasswordResponseArea::CreateNode()
209 {
210     auto textFieldPattern = DynamicCast<TextFieldPattern>(hostPattern_.Upgrade());
211     CHECK_NULL_RETURN(textFieldPattern, nullptr);
212     auto iconSize = GetIconSize();
213     auto rightOffset = GetIconRightOffset();
214     auto hotZoneSize = iconSize + rightOffset;
215 
216     auto stackNode = FrameNode::CreateFrameNode(
217         V2::STACK_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<StackPattern>());
218     auto stackLayoutProperty = stackNode->GetLayoutProperty<LayoutProperty>();
219     CHECK_NULL_RETURN(stackLayoutProperty, nullptr);
220     stackLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(hotZoneSize), std::nullopt));
221     auto layoutProperty = textFieldPattern->GetLayoutProperty<TextFieldLayoutProperty>();
222     CHECK_NULL_RETURN(layoutProperty, nullptr);
223     stackLayoutProperty->UpdateAlignment(GetStackAlignment(layoutProperty->GetLayoutDirection()));
224     AddEvent(stackNode);
225     stackNode->MarkModifyDone();
226 
227     if (IsShowSymbol() && SystemProperties::IsNeedSymbol()) {
228         auto symbolNode = FrameNode::GetOrCreateFrameNode(V2::SYMBOL_ETS_TAG,
229             ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<TextPattern>(); });
230         CHECK_NULL_RETURN(symbolNode, nullptr);
231         passwordNode_ = symbolNode;
232         InitSymbolEffectOptions();
233         UpdateSymbolSource();
234 
235         symbolNode->MountToParent(stackNode);
236         stackNode_ = stackNode;
237         return stackNode;
238     }
239 
240     LoadImageSourceInfo();
241     auto currentImageSourceInfo = GetCurrentSourceInfo();
242     CHECK_NULL_RETURN(currentImageSourceInfo, nullptr);
243     auto imageNode = CreateResponseAreaImageNode(currentImageSourceInfo.value(), ImageFit::FILL,
244         CalcSize(CalcLength(iconSize), CalcLength(iconSize)));
245     CHECK_NULL_RETURN(imageNode, nullptr);
246 
247     passwordNode_ = imageNode;
248     AddImageEventOnError();
249     imageNode->MarkModifyDone();
250     imageNode->MountToParent(stackNode);
251     stackNode_ = stackNode;
252     return stackNode;
253 }
254 
AddIconHotZoneRect()255 void PasswordResponseArea::AddIconHotZoneRect()
256 {
257     auto pattern = hostPattern_.Upgrade();
258     CHECK_NULL_VOID(pattern);
259     auto host = pattern->GetHost();
260     CHECK_NULL_VOID(host);
261     if (host->LessThanAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
262         return;
263     }
264     CHECK_NULL_VOID(stackNode_);
265     auto stackGeometryNode = stackNode_->GetGeometryNode();
266     CHECK_NULL_VOID(stackGeometryNode);
267     auto stackRect = stackGeometryNode->GetFrameRect();
268 
269     auto iconSize = stackRect.Width() - GetIconRightOffset();
270     auto hotZoneHeight = static_cast<float>(DEFAULT_ICON_HOT_ZONE.ConvertToPx());
271     hotZoneHeight = passwordHoverSize_ > hotZoneHeight ? passwordHoverSize_ : hotZoneHeight;
272     DimensionRect hotZoneRegion;
273     SetHotZoneRect(hotZoneRegion, iconSize, hotZoneHeight);
274 
275     auto defaultHoverSize = static_cast<float>(DEFAULT_HOVER_SIZE.ConvertToPx());
276     auto mouseHotZoneHeight = NearZero(passwordHoverSize_) ? defaultHoverSize : passwordHoverSize_;
277     DimensionRect mouseHotZoneRegion;
278     SetHotZoneRect(mouseHotZoneRegion, iconSize, mouseHotZoneHeight);
279 
280     std::vector<DimensionRect> mouseRegion;
281     mouseRegion.emplace_back(mouseHotZoneRegion);
282 
283     auto stackGestureHub = stackNode_->GetOrCreateGestureEventHub();
284     CHECK_NULL_VOID(stackGestureHub);
285     stackGestureHub->SetMouseResponseRegion(mouseRegion);
286 
287     std::vector<DimensionRect> responseRegion;
288     responseRegion.emplace_back(hotZoneRegion);
289     stackGestureHub->SetResponseRegion(responseRegion);
290 }
291 
CreateIconRect(RoundRect & paintRect,bool isFocus)292 void PasswordResponseArea::CreateIconRect(RoundRect& paintRect, bool isFocus)
293 {
294     CHECK_NULL_VOID(stackNode_);
295     auto imageFrameNode = AceType::DynamicCast<FrameNode>(stackNode_->GetFirstChild());
296     CHECK_NULL_VOID(imageFrameNode);
297     auto imageGeometryNode = imageFrameNode->GetGeometryNode();
298     CHECK_NULL_VOID(imageGeometryNode);
299     auto imageRect = imageGeometryNode->GetFrameRect();
300     auto textInputNode = stackNode_->GetParentFrameNode();
301     CHECK_NULL_VOID(textInputNode);
302     auto textInputRect = textInputNode->GetGeometryNode()->GetFrameRect();
303     auto iconSize = imageRect.Height();
304     auto defaultRectHeight = DEFAULT_HOVER_SIZE.ConvertToPx();
305     auto rectHeight = iconSize > defaultRectHeight ? iconSize : defaultRectHeight;
306     auto hoverRectHeight = rectHeight > textInputRect.Height() ? textInputRect.Height() : rectHeight;
307     auto maxHoverRectHeight = iconSize + DOUBLE_PADDING * GetIconRightOffset();
308     hoverRectHeight = hoverRectHeight > maxHoverRectHeight ? maxHoverRectHeight : hoverRectHeight;
309     passwordHoverSize_ = hoverRectHeight;
310     hoverIconPadding_ = (hoverRectHeight - iconSize) / HALF_SPACE;
311     RectF rect;
312     SetHoverRect(stackNode_, rect, iconSize, hoverRectHeight, isFocus);
313     paintRect.SetRect(rect);
314 }
315 
AddEvent(const RefPtr<FrameNode> & node)316 void PasswordResponseArea::AddEvent(const RefPtr<FrameNode>& node)
317 {
318     CHECK_NULL_VOID(node);
319     auto focusHub = node->GetOrCreateFocusHub();
320     CHECK_NULL_VOID(focusHub);
321     auto gesture = node->GetOrCreateGestureEventHub();
322     auto clickCallback = [weak = WeakClaim(this)](GestureEvent& info) {
323         auto button = weak.Upgrade();
324         CHECK_NULL_VOID(button);
325         button->OnPasswordIconClicked();
326         auto context = PipelineContext::GetCurrentContextSafelyWithCheck();
327         CHECK_NULL_VOID(context);
328         auto theme = context->GetTheme<TextFieldTheme>();
329         CHECK_NULL_VOID(theme);
330         auto node = button->GetFrameNode();
331         CHECK_NULL_VOID(node);
332         auto message = !button->IsObscured() ? theme->GetHasShowedPassword() : theme->GetHasHiddenPassword();
333         node->OnAccessibilityEvent(AccessibilityEventType::ANNOUNCE_FOR_ACCESSIBILITY, message);
334     };
335     auto mouseTask = [id = Container::CurrentId(), weak = hostPattern_](MouseInfo& info) {
336         info.SetStopPropagation(true);
337         auto pattern = weak.Upgrade();
338         CHECK_NULL_VOID(pattern);
339         auto textfield = DynamicCast<TextFieldPattern>(pattern);
340         CHECK_NULL_VOID(textfield);
341         textfield->RestoreDefaultMouseState();
342     };
343     auto touchTask = [weak = WeakClaim(this)](TouchEventInfo& info) {
344         info.SetStopPropagation(true);
345     };
346 
347     auto inputHub = node->GetOrCreateInputEventHub();
348     auto mouseEvent = MakeRefPtr<InputEvent>(std::move(mouseTask));
349     inputHub->AddOnMouseEvent(mouseEvent);
350     gesture->AddClickEvent(MakeRefPtr<ClickEvent>(std::move(clickCallback)));
351     gesture->AddTouchEvent(MakeRefPtr<TouchEventImpl>(std::move(touchTask)));
352 }
353 
Refresh()354 void PasswordResponseArea::Refresh()
355 {
356     auto iconNode = passwordNode_.Upgrade();
357     if (!iconNode) {
358         InitResponseArea();
359         return;
360     }
361 
362     auto textFieldPattern = hostPattern_.Upgrade();
363     if (textFieldPattern && stackNode_) {
364         auto layoutProperty = textFieldPattern->GetLayoutProperty<TextFieldLayoutProperty>();
365         auto stackLayoutProperty = stackNode_->GetLayoutProperty<LayoutProperty>();
366         if (stackLayoutProperty && layoutProperty) {
367             stackLayoutProperty->UpdateAlignment(GetStackAlignment(layoutProperty->GetLayoutDirection()));
368         }
369     }
370 
371     // update node symbol
372     if (IsShowSymbol() && IsSymbolIcon() && SystemProperties::IsNeedSymbol()) {
373         UpdateSymbolColor();
374         return;
375     }
376 
377     // update node image
378     if (!IsShowSymbol() && !IsSymbolIcon()) {
379         auto imageLayoutProperty = iconNode->GetLayoutProperty<ImageLayoutProperty>();
380         CHECK_NULL_VOID(imageLayoutProperty);
381         CHECK_NULL_VOID(imageLayoutProperty->HasImageSourceInfo());
382         auto currentSrc = imageLayoutProperty->GetImageSourceInfoValue().GetSrc();
383         LoadImageSourceInfo();
384         auto src = isObscured_ ? hideIcon_->GetSrc() : showIcon_->GetSrc();
385         if (currentSrc != src) {
386             UpdateImageSource();
387         }
388         return;
389     }
390 
391     ReplaceNode();
392 }
393 
ClearArea()394 void PasswordResponseArea::ClearArea()
395 {
396     auto hostPattern = hostPattern_.Upgrade();
397     CHECK_NULL_VOID(hostPattern);
398     auto host = hostPattern->GetHost();
399     CHECK_NULL_VOID(host);
400     CHECK_NULL_VOID(stackNode_);
401     host->RemoveChildAndReturnIndex(stackNode_);
402     passwordNode_.Reset();
403     areaRect_.Reset();
404 }
405 
ReplaceNode()406 void PasswordResponseArea::ReplaceNode()
407 {
408     auto oldFrameNode = passwordNode_.Upgrade();
409     CHECK_NULL_VOID(oldFrameNode);
410 
411     if (IsShowSymbol() && SystemProperties::IsNeedSymbol()) {
412         auto symbolNode = FrameNode::GetOrCreateFrameNode(V2::SYMBOL_ETS_TAG,
413             ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<TextPattern>(); });
414         CHECK_NULL_VOID(symbolNode);
415         stackNode_->ReplaceChild(oldFrameNode, symbolNode);
416         passwordNode_ = symbolNode;
417         InitSymbolEffectOptions();
418         UpdateSymbolSource();
419         return;
420     }
421 
422     auto iconSize = GetIconSize();
423     LoadImageSourceInfo();
424     auto currentImageSourceInfo = GetCurrentSourceInfo();
425     CHECK_NULL_VOID(currentImageSourceInfo);
426     auto imageNode = CreateResponseAreaImageNode(currentImageSourceInfo.value(), ImageFit::FILL,
427         CalcSize(CalcLength(iconSize), CalcLength(iconSize)));
428     CHECK_NULL_VOID(imageNode);
429 
430     stackNode_->ReplaceChild(oldFrameNode, imageNode);
431     passwordNode_ = imageNode;
432     AddImageEventOnError();
433     imageNode->MarkModifyDone();
434     imageNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
435 }
436 
OnPasswordIconClicked()437 void PasswordResponseArea::OnPasswordIconClicked()
438 {
439     isObscured_ = !isObscured_;
440     ChangeObscuredState();
441 }
442 
UpdatePasswordIconColor(const Color & color)443 void PasswordResponseArea::UpdatePasswordIconColor(const Color& color)
444 {
445     showIcon_->SetFillColor(color);
446     hideIcon_->SetFillColor(color);
447 
448     if (IsSymbolIcon()) {
449         UpdateSymbolColor();
450     } else {
451         UpdateImageSource();
452     }
453 }
454 
ChangeObscuredState()455 void PasswordResponseArea::ChangeObscuredState()
456 {
457     auto textFieldPattern = DynamicCast<TextFieldPattern>(hostPattern_.Upgrade());
458     CHECK_NULL_VOID(textFieldPattern);
459     if (IsSymbolIcon() && SystemProperties::IsNeedSymbol()) {
460         UpdateSymbolSource();
461     } else {
462         UpdateImageSource();
463     }
464     textFieldPattern->OnObscuredChanged(isObscured_);
465 }
466 
Measure(LayoutWrapper * layoutWrapper,int32_t index)467 SizeF PasswordResponseArea::Measure(LayoutWrapper* layoutWrapper, int32_t index)
468 {
469     if (!IsShowPasswordIcon()) {
470         return SizeF(0, 0);
471     }
472     auto textInputMeasure = TextInputResponseArea::Measure(layoutWrapper, index);
473     AddIconHotZoneRect();
474     return textInputMeasure;
475 }
476 
Layout(LayoutWrapper * layoutWrapper,int32_t index,float & nodeWidth)477 void PasswordResponseArea::Layout(LayoutWrapper* layoutWrapper, int32_t index, float& nodeWidth)
478 {
479     if (!IsShowPasswordIcon()) {
480         return;
481     }
482     LayoutChild(layoutWrapper, index, nodeWidth);
483 }
484 
GetIconSize()485 float PasswordResponseArea::GetIconSize()
486 {
487     auto textFieldPattern = hostPattern_.Upgrade();
488     CHECK_NULL_RETURN(textFieldPattern, 0.0f);
489     auto tmpHost = textFieldPattern->GetHost();
490     CHECK_NULL_RETURN(tmpHost, 0.0f);
491     auto pipeline = tmpHost->GetContextRefPtr();
492     CHECK_NULL_RETURN(pipeline, 0.0f);
493     auto themeManager = pipeline->GetThemeManager();
494     CHECK_NULL_RETURN(themeManager, 0.0f);
495     auto textFieldTheme = themeManager->GetTheme<TextFieldTheme>();
496     CHECK_NULL_RETURN(textFieldTheme, 0.0f);
497     auto iconSize = textFieldTheme->GetIconSize().ConvertToPx();
498     if (tmpHost->GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
499         iconSize = textFieldTheme->GetPasswordIconSize().ConvertToPx();
500     }
501     return static_cast<float>(iconSize);
502 }
503 
GetIconRightOffset()504 float PasswordResponseArea::GetIconRightOffset()
505 {
506     auto textFieldPattern = hostPattern_.Upgrade();
507     CHECK_NULL_RETURN(textFieldPattern, 0.0f);
508     auto tmpHost = textFieldPattern->GetHost();
509     auto pipeline = tmpHost->GetContextRefPtr();
510     CHECK_NULL_RETURN(pipeline, 0.0f);
511     auto themeManager = pipeline->GetThemeManager();
512     CHECK_NULL_RETURN(themeManager, 0.0f);
513     auto textFieldTheme = themeManager->GetTheme<TextFieldTheme>();
514     CHECK_NULL_RETURN(textFieldTheme, 0.0f);
515     auto themePadding = textFieldTheme->GetPadding();
516     if (tmpHost->GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
517         auto passwordIconPadding = textFieldTheme->GetPasswordIconPadding();
518         return static_cast<float>(passwordIconPadding.ConvertToPx());
519     }
520     return static_cast<float>(themePadding.Left().ConvertToPx());
521 }
522 
LoadImageSourceInfo()523 void PasswordResponseArea::LoadImageSourceInfo()
524 {
525     auto textFieldPattern = hostPattern_.Upgrade();
526     CHECK_NULL_VOID(textFieldPattern);
527     auto layoutProperty = textFieldPattern->GetLayoutProperty<TextFieldLayoutProperty>();
528     CHECK_NULL_VOID(layoutProperty);
529     showIcon_ = layoutProperty->GetShowPasswordSourceInfoValue(GetDefaultSourceInfo(false));
530     hideIcon_ = layoutProperty->GetHidePasswordSourceInfoValue(GetDefaultSourceInfo(true));
531     auto tmpHost = textFieldPattern->GetHost();
532     CHECK_NULL_VOID(tmpHost);
533     auto pipeline = tmpHost->GetContextRefPtr();
534     CHECK_NULL_VOID(pipeline);
535     auto themeManager = pipeline->GetThemeManager();
536     CHECK_NULL_VOID(themeManager);
537     auto textFieldTheme = themeManager->GetTheme<TextFieldTheme>(tmpHost->GetThemeScopeId());
538     CHECK_NULL_VOID(textFieldTheme);
539     if (showIcon_->GetResourceId() == InternalResource::ResourceId::SHOW_PASSWORD_SVG) {
540         showIcon_->SetFillColor(textFieldTheme->GetTextColor());
541     }
542     if (hideIcon_->GetResourceId() == InternalResource::ResourceId::HIDE_PASSWORD_SVG) {
543         hideIcon_->SetFillColor(textFieldTheme->GetTextColor());
544     }
545     if (layoutProperty->GetIsDisabledValue(false)) {
546         auto iconTheme = pipeline->GetTheme<IconTheme>();
547         CHECK_NULL_VOID(iconTheme);
548         auto textDisableColor = textFieldTheme->GetTextColorDisable();
549         auto hideIconPath = iconTheme->GetIconPath(hideIcon_->GetResourceId());
550         hideIcon_->SetSrc(hideIconPath, textDisableColor);
551         auto showIconPath = iconTheme->GetIconPath(showIcon_->GetResourceId());
552         showIcon_->SetSrc(showIconPath, textDisableColor);
553         UpdateImageSource();
554     }
555 }
556 
AddImageEventOnError()557 void PasswordResponseArea::AddImageEventOnError()
558 {
559     auto imageNode = passwordNode_.Upgrade();
560     auto eventHub = imageNode->GetOrCreateEventHub<ImageEventHub>();
561     CHECK_NULL_VOID(eventHub);
562     eventHub->SetOnError([ weakNode = WeakClaim(AceType::RawPtr(imageNode)), weakArea = WeakClaim(this) ]
563         (const LoadImageFailEvent& info) {
564         auto host = weakNode.Upgrade();
565         CHECK_NULL_VOID(host);
566         auto area = weakArea.Upgrade();
567         CHECK_NULL_VOID(area);
568         auto imagePattern = host->GetPattern<ImagePattern>();
569         CHECK_NULL_VOID(imagePattern);
570         auto layoutProperty = host->GetLayoutProperty<ImageLayoutProperty>();
571         CHECK_NULL_VOID(layoutProperty);
572         layoutProperty->UpdateImageSourceInfo(area->GetDefaultSourceInfo(area->isObscured_));
573         imagePattern->LoadImageDataIfNeed();
574     });
575 }
576 
GetDefaultSourceInfo(bool isObscured)577 ImageSourceInfo PasswordResponseArea::GetDefaultSourceInfo(bool isObscured)
578 {
579     if (isObscured) {
580         ImageSourceInfo hideSystemSourceInfo;
581         hideSystemSourceInfo.SetResourceId(InternalResource::ResourceId::HIDE_PASSWORD_SVG);
582         return hideSystemSourceInfo;
583     }
584     ImageSourceInfo showSystemSourceInfo;
585     showSystemSourceInfo.SetResourceId(InternalResource::ResourceId::SHOW_PASSWORD_SVG);
586     return showSystemSourceInfo;
587 }
588 
UpdateImageSource()589 void PasswordResponseArea::UpdateImageSource()
590 {
591     auto frameNode = passwordNode_.Upgrade();
592     CHECK_NULL_VOID(frameNode);
593     auto layoutProperty = frameNode->GetLayoutProperty<ImageLayoutProperty>();
594     CHECK_NULL_VOID(layoutProperty);
595     auto currentImageSourceInfo = GetCurrentSourceInfo();
596     CHECK_NULL_VOID(currentImageSourceInfo);
597     layoutProperty->UpdateImageSourceInfo(currentImageSourceInfo.value());
598     auto imagePattern = frameNode->GetPattern<ImagePattern>();
599     CHECK_NULL_VOID(imagePattern);
600     imagePattern->LoadImageDataIfNeed();
601 }
602 
UpdateSymbolSource()603 void PasswordResponseArea::UpdateSymbolSource()
604 {
605     auto textFieldPattern = DynamicCast<TextFieldPattern>(hostPattern_.Upgrade());
606     CHECK_NULL_VOID(textFieldPattern);
607     auto host = textFieldPattern->GetHost();
608     CHECK_NULL_VOID(host);
609     auto pipeline = host->GetContextRefPtr();
610     CHECK_NULL_VOID(pipeline);
611     auto themeManager = pipeline->GetThemeManager();
612     CHECK_NULL_VOID(themeManager);
613     auto textFieldTheme = themeManager->GetTheme<TextFieldTheme>(host->GetThemeScopeId());
614     CHECK_NULL_VOID(textFieldTheme);
615     auto symbolNode = passwordNode_.Upgrade();
616     CHECK_NULL_VOID(symbolNode);
617     auto symbolProperty = symbolNode->GetLayoutProperty<TextLayoutProperty>();
618     CHECK_NULL_VOID(symbolProperty);
619     auto currentSymbolId = isObscured_ ? textFieldTheme->GetHideSymbolId() : textFieldTheme->GetShowSymbolId();
620     symbolProperty->UpdateSymbolSourceInfo(SymbolSourceInfo(currentSymbolId));
621     symbolProperty->UpdateFontSize(textFieldTheme->GetSymbolSize());
622     symbolColor_ = textFieldTheme->GetSymbolColor();
623     symbolProperty->UpdateSymbolColorList({ symbolColor_ });
624     symbolProperty->UpdateMaxFontScale(MAX_FONT_SCALE);
625     if (host->GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
626         symbolProperty->UpdateFontSize(textFieldTheme->GetPasswordIconSize());
627     }
628 
629     symbolNode->MarkModifyDone();
630     symbolNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
631 }
632 
UpdateSymbolColor()633 void PasswordResponseArea::UpdateSymbolColor()
634 {
635     auto textFieldPattern = DynamicCast<TextFieldPattern>(hostPattern_.Upgrade());
636     CHECK_NULL_VOID(textFieldPattern);
637     auto host = textFieldPattern->GetHost();
638     CHECK_NULL_VOID(host);
639     auto pipeline = host->GetContextRefPtr();
640     CHECK_NULL_VOID(pipeline);
641     auto themeManager = pipeline->GetThemeManager();
642     CHECK_NULL_VOID(themeManager);
643     auto textFieldTheme = themeManager->GetTheme<TextFieldTheme>(host->GetThemeScopeId());
644     CHECK_NULL_VOID(textFieldTheme);
645     auto symbolNode = passwordNode_.Upgrade();
646     CHECK_NULL_VOID(symbolNode);
647     auto symbolProperty = symbolNode->GetLayoutProperty<TextLayoutProperty>();
648     CHECK_NULL_VOID(symbolProperty);
649     auto layoutProperty = textFieldPattern->GetLayoutProperty<TextFieldLayoutProperty>();
650     CHECK_NULL_VOID(layoutProperty);
651 
652     Color color = textFieldTheme->GetSymbolColor();
653     if (layoutProperty->GetIsDisabledValue(false)) {
654         color = textFieldTheme->GetTextColorDisable();
655     }
656 
657     // frame bug, MarkDirtyNode will trigger symbol effect
658     // add a temp variable for record color, prevent frequent MarkDirtyNode triggering
659     if (symbolColor_ != color) {
660         symbolColor_ = color;
661         symbolProperty->UpdateSymbolColorList({ symbolColor_ });
662         symbolNode->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
663     }
664 }
665 
InitSymbolEffectOptions()666 void PasswordResponseArea::InitSymbolEffectOptions()
667 {
668     auto symbolNode = passwordNode_.Upgrade();
669     CHECK_NULL_VOID(symbolNode);
670     auto symbolProperty = symbolNode->GetLayoutProperty<TextLayoutProperty>();
671     CHECK_NULL_VOID(symbolProperty);
672     auto symbolEffectOptions = symbolProperty->GetSymbolEffectOptionsValue(SymbolEffectOptions());
673     symbolEffectOptions.SetEffectType(SymbolEffectType::REPLACE);
674     symbolEffectOptions.SetScopeType(Ace::ScopeType::WHOLE);
675     symbolEffectOptions.SetIsTxtActive(true);
676     symbolEffectOptions.SetIsTxtActiveSource(0);
677     symbolProperty->UpdateSymbolEffectOptions(symbolEffectOptions);
678 }
679 
IsShowSymbol()680 bool PasswordResponseArea::IsShowSymbol()
681 {
682     auto textFieldPattern = AceType::DynamicCast<TextFieldPattern>(hostPattern_.Upgrade());
683     CHECK_NULL_RETURN(textFieldPattern, false);
684     return textFieldPattern->IsShowPasswordSymbol();
685 }
686 
IsSymbolIcon()687 bool PasswordResponseArea::IsSymbolIcon()
688 {
689     auto iconFrameNode = passwordNode_.Upgrade();
690     CHECK_NULL_RETURN(iconFrameNode, false);
691     return iconFrameNode->GetTag() == V2::SYMBOL_ETS_TAG;
692 }
693 
IsShowPasswordIcon()694 bool PasswordResponseArea::IsShowPasswordIcon()
695 {
696     auto textFieldPattern = AceType::DynamicCast<TextFieldPattern>(hostPattern_.Upgrade());
697     CHECK_NULL_RETURN(textFieldPattern, false);
698     return textFieldPattern->IsShowPasswordIcon();
699 }
700 
OnThemeScopeUpdate(const RefPtr<TextFieldTheme> & theme)701 void PasswordResponseArea::OnThemeScopeUpdate(const RefPtr<TextFieldTheme>& theme)
702 {
703     // no interface to set password icon color, should update every time
704     CHECK_NULL_VOID(theme);
705     UpdatePasswordIconColor(theme->GetSymbolColor());
706 } // PasswordResponseArea end
707 
708 // UnitResponseArea begin
InitResponseArea()709 void UnitResponseArea::InitResponseArea()
710 {
711     auto pattern = hostPattern_.Upgrade();
712     CHECK_NULL_VOID(pattern);
713     auto host = pattern->GetHost();
714     CHECK_NULL_VOID(host);
715     if (!IsShowUnit()) {
716         return;
717     }
718     CHECK_NULL_VOID(unitNode_);
719     unitNode_->MountToParent(host);
720 }
721 
GetFrameNode()722 const RefPtr<FrameNode> UnitResponseArea::GetFrameNode()
723 {
724     auto frameNode = AceType::DynamicCast<FrameNode>(unitNode_);
725     CHECK_NULL_RETURN(frameNode, nullptr);
726     return frameNode;
727 }
728 
ClearArea()729 void UnitResponseArea::ClearArea()
730 {
731     auto hostPattern = hostPattern_.Upgrade();
732     CHECK_NULL_VOID(hostPattern);
733     auto host = hostPattern->GetHost();
734     CHECK_NULL_VOID(host);
735     CHECK_NULL_VOID(unitNode_);
736     host->RemoveChildAndReturnIndex(unitNode_);
737     areaRect_.Reset();
738 }
739 
Measure(LayoutWrapper * layoutWrapper,int32_t index)740 SizeF UnitResponseArea::Measure(LayoutWrapper* layoutWrapper, int32_t index)
741 {
742     if (!IsShowUnit()) {
743         return SizeF(0, 0);
744     }
745     return TextInputResponseArea::Measure(layoutWrapper, index);
746 }
747 
Layout(LayoutWrapper * layoutWrapper,int32_t index,float & nodeWidth)748 void UnitResponseArea::Layout(LayoutWrapper* layoutWrapper, int32_t index, float& nodeWidth)
749 {
750     if (!IsShowUnit()) {
751         return;
752     }
753     LayoutChild(layoutWrapper, index, nodeWidth);
754 }
755 
IsShowUnit()756 bool UnitResponseArea::IsShowUnit()
757 {
758     auto pattern = hostPattern_.Upgrade();
759     CHECK_NULL_RETURN(pattern, false);
760     auto textFieldPattern = AceType::DynamicCast<TextFieldPattern>(pattern);
761     CHECK_NULL_RETURN(textFieldPattern, false);
762     return textFieldPattern->IsUnderlineMode();
763 } // UnitResponseArea end
764 
InitResponseArea()765 void CleanNodeResponseArea::InitResponseArea()
766 {
767     auto pattern = hostPattern_.Upgrade();
768     CHECK_NULL_VOID(pattern);
769     auto host = pattern->GetHost();
770     CHECK_NULL_VOID(host);
771     LoadingImageProperty();
772     auto cleanNode = CreateNode();
773     CHECK_NULL_VOID(cleanNode);
774     cleanNode->MountToParent(host);
775 }
776 
Measure(LayoutWrapper * layoutWrapper,int32_t index)777 SizeF CleanNodeResponseArea::Measure(LayoutWrapper* layoutWrapper, int32_t index)
778 {
779     auto textInputMeasure = TextInputResponseArea::Measure(layoutWrapper, index);
780     AddIconHotZoneRect();
781     return textInputMeasure;
782 }
783 
AddIconHotZoneRect()784 void CleanNodeResponseArea::AddIconHotZoneRect()
785 {
786     auto pattern = hostPattern_.Upgrade();
787     CHECK_NULL_VOID(pattern);
788     auto host = pattern->GetHost();
789     CHECK_NULL_VOID(host);
790     if (host->LessThanAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
791         return;
792     }
793     CHECK_NULL_VOID(cleanNode_);
794     auto imageFrameNode = AceType::DynamicCast<FrameNode>(cleanNode_->GetFirstChild());
795     CHECK_NULL_VOID(imageFrameNode);
796     auto imageGeometryNode = imageFrameNode->GetGeometryNode();
797     CHECK_NULL_VOID(imageGeometryNode);
798     auto imageRect = imageGeometryNode->GetFrameRect();
799     auto iconSize = imageRect.Height();
800     auto hotZoneHeight = static_cast<float>(DEFAULT_ICON_HOT_ZONE.ConvertToPx());
801     hotZoneHeight = cancelHoverSize_ > hotZoneHeight ? cancelHoverSize_ : hotZoneHeight;
802     DimensionRect hotZoneRegion;
803     SetHotZoneRect(hotZoneRegion, iconSize, hotZoneHeight);
804 
805     auto defaultHoverSize = static_cast<float>(DEFAULT_HOVER_SIZE.ConvertToPx());
806     auto mouseHotZoneHeight = NearZero(cancelHoverSize_) ? defaultHoverSize : cancelHoverSize_;
807     DimensionRect mouseHotZoneRegion;
808     SetHotZoneRect(mouseHotZoneRegion, iconSize, mouseHotZoneHeight);
809 
810     std::vector<DimensionRect> mouseRegion;
811     mouseRegion.emplace_back(mouseHotZoneRegion);
812 
813     auto stackGestureHub = cleanNode_->GetOrCreateGestureEventHub();
814     CHECK_NULL_VOID(stackGestureHub);
815     stackGestureHub->SetMouseResponseRegion(mouseRegion);
816 
817     std::vector<DimensionRect> responseRegion;
818     responseRegion.emplace_back(hotZoneRegion);
819     stackGestureHub->SetResponseRegion(responseRegion);
820 }
821 
GetCancelButtonPadding(const RefPtr<TextFieldTheme> & textFieldTheme)822 float GetCancelButtonPadding(const RefPtr<TextFieldTheme>& textFieldTheme)
823 {
824     CHECK_NULL_RETURN(textFieldTheme, 0.0f);
825     auto themePadding = textFieldTheme->GetPadding();
826     if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
827         auto cancelButtonPadding = textFieldTheme->GetCancelIconPadding();
828         return static_cast<float>(cancelButtonPadding.ConvertToPx());
829     }
830     return static_cast<float>(themePadding.Left().ConvertToPx());
831 }
832 
CreateIconRect(RoundRect & paintRect,bool isFocus)833 void CleanNodeResponseArea::CreateIconRect(RoundRect& paintRect, bool isFocus)
834 {
835     CHECK_NULL_VOID(cleanNode_);
836     auto pattern = hostPattern_.Upgrade();
837     CHECK_NULL_VOID(pattern);
838     auto imageFrameNode = AceType::DynamicCast<FrameNode>(cleanNode_->GetFirstChild());
839     CHECK_NULL_VOID(imageFrameNode);
840     auto imageGeometryNode = imageFrameNode->GetGeometryNode();
841     CHECK_NULL_VOID(imageGeometryNode);
842     auto imageRect = imageGeometryNode->GetFrameRect();
843     auto textInputNode = cleanNode_->GetParentFrameNode();
844     CHECK_NULL_VOID(textInputNode);
845     auto textInputRect = textInputNode->GetGeometryNode()->GetFrameRect();
846     auto iconSize = imageRect.Height();
847     auto defaultRectHeight = DEFAULT_HOVER_SIZE.ConvertToPx();
848     auto host = pattern->GetHost();
849     CHECK_NULL_VOID(host);
850     auto pipeline = host->GetContext();
851     CHECK_NULL_VOID(pipeline);
852     auto theme = pipeline->GetTheme<TextFieldTheme>(host->GetThemeScopeId());
853     CHECK_NULL_VOID(theme);
854     auto rectHeight = iconSize > defaultRectHeight ? iconSize : defaultRectHeight;
855     auto hoverRectHeight = rectHeight > textInputRect.Height() ? textInputRect.Height() : rectHeight;
856     auto maxHoverRectHeight = iconSize + DOUBLE_PADDING * GetCancelButtonPadding(theme);
857     hoverRectHeight = hoverRectHeight > maxHoverRectHeight ? maxHoverRectHeight : hoverRectHeight;
858     cancelHoverSize_ = hoverRectHeight;
859     hoverIconPadding_ = (hoverRectHeight - iconSize) / HALF_SPACE;
860     RectF rect;
861     SetHoverRect(cleanNode_, rect, iconSize, hoverRectHeight, isFocus);
862     paintRect.SetRect(rect);
863 }
864 
IsShowClean() const865 bool CleanNodeResponseArea::IsShowClean() const
866 {
867     auto pattern = hostPattern_.Upgrade();
868     CHECK_NULL_RETURN(pattern, false);
869     auto textFieldPattern = AceType::DynamicCast<TextFieldPattern>(pattern);
870     CHECK_NULL_RETURN(textFieldPattern, false);
871     return textFieldPattern->IsShowCancelButtonMode();
872 }
873 
IsShowSymbol() const874 bool CleanNodeResponseArea::IsShowSymbol() const
875 {
876     auto pattern = hostPattern_.Upgrade();
877     CHECK_NULL_RETURN(pattern, false);
878     auto textFieldLayoutProperty = pattern->GetLayoutProperty<TextFieldLayoutProperty>();
879     CHECK_NULL_RETURN(textFieldLayoutProperty, false);
880     return textFieldLayoutProperty->GetIsShowSymbolValue(true);
881 }
882 
IsSymbolIcon() const883 bool CleanNodeResponseArea::IsSymbolIcon() const
884 {
885     CHECK_NULL_RETURN(cleanNode_, false);
886     CHECK_NULL_RETURN(cleanNode_->GetFirstChild(), false);
887     auto iconFrameNode = AceType::DynamicCast<FrameNode>(cleanNode_->GetFirstChild());
888     CHECK_NULL_RETURN(iconFrameNode, false);
889     return iconFrameNode->GetTag() == V2::SYMBOL_ETS_TAG;
890 }
891 
Layout(LayoutWrapper * layoutWrapper,int32_t index,float & nodeWidth)892 void CleanNodeResponseArea::Layout(LayoutWrapper *layoutWrapper, int32_t index, float &nodeWidth)
893 {
894     if (!IsShowClean()) {
895         return;
896     }
897     LayoutChild(layoutWrapper, index, nodeWidth);
898 }
899 
GetFrameNode()900 const RefPtr<FrameNode> CleanNodeResponseArea::GetFrameNode()
901 {
902     return cleanNode_;
903 }
904 
CreateNode()905 RefPtr<FrameNode> CleanNodeResponseArea::CreateNode()
906 {
907     auto stackNode = FrameNode::CreateFrameNode(
908         V2::STACK_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<StackPattern>());
909     auto stackLayoutProperty = stackNode->GetLayoutProperty<LayoutProperty>();
910     CHECK_NULL_RETURN(stackLayoutProperty, nullptr);
911     stackLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(0.0f), std::nullopt));
912     stackLayoutProperty->UpdateVisibility(VisibleType::INVISIBLE);
913     auto textFieldPattern = hostPattern_.Upgrade();
914     CHECK_NULL_RETURN(textFieldPattern, nullptr);
915     auto layoutProperty = textFieldPattern->GetLayoutProperty<TextFieldLayoutProperty>();
916     CHECK_NULL_RETURN(layoutProperty, nullptr);
917     stackLayoutProperty->UpdateAlignment(GetStackAlignment(layoutProperty->GetLayoutDirection()));
918     stackNode->MarkModifyDone();
919 
920     if (IsShowSymbol() && SystemProperties::IsNeedSymbol()) {
921         auto symbolNode = FrameNode::GetOrCreateFrameNode(V2::SYMBOL_ETS_TAG,
922             ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<TextPattern>(); });
923         CHECK_NULL_RETURN(symbolNode, nullptr);
924         cleanNode_ = stackNode;
925         symbolNode->MountToParent(stackNode);
926         InitClickEvent(stackNode);
927         SetCancelSymbolIconSize();
928         UpdateSymbolSource();
929         return stackNode;
930     }
931 
932     auto info = CreateImageSourceInfo();
933     auto imageNode = CreateResponseAreaImageNode(info, ImageFit::COVER, CalcSize(CalcLength(0.0f), CalcLength(0.0f)));
934     CHECK_NULL_RETURN(imageNode, nullptr);
935     auto imageLayoutProperty = imageNode->GetLayoutProperty<ImageLayoutProperty>();
936     CHECK_NULL_RETURN(imageLayoutProperty, nullptr);
937     imageLayoutProperty->UpdateVisibility(VisibleType::INVISIBLE);
938 
939     cleanNode_ = stackNode;
940     imageNode->MarkModifyDone();
941     imageNode->MountToParent(stackNode);
942     InitClickEvent(stackNode);
943     return stackNode;
944 }
945 
SetCancelSymbolIconSize()946 void CleanNodeResponseArea::SetCancelSymbolIconSize()
947 {
948     auto textFieldPattern = DynamicCast<TextFieldPattern>(hostPattern_.Upgrade());
949     CHECK_NULL_VOID(textFieldPattern);
950     auto host = textFieldPattern->GetHost();
951     CHECK_NULL_VOID(host);
952     auto pipeline = host->GetContextRefPtr();
953     CHECK_NULL_VOID(pipeline);
954     auto themeManager = pipeline->GetThemeManager();
955     CHECK_NULL_VOID(themeManager);
956     auto textFieldTheme = themeManager->GetTheme<TextFieldTheme>();
957     CHECK_NULL_VOID(textFieldTheme);
958     auto symbolNode = cleanNode_->GetFirstChild();
959     CHECK_NULL_VOID(symbolNode);
960     auto symbolFrameNode = AceType::DynamicCast<FrameNode>(symbolNode);
961     CHECK_NULL_VOID(symbolFrameNode);
962     auto symbolProperty = symbolFrameNode->GetLayoutProperty<TextLayoutProperty>();
963     CHECK_NULL_VOID(symbolProperty);
964     symbolProperty->UpdateFontSize(textFieldTheme->GetSymbolSize());
965     if (host->GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
966         symbolProperty->UpdateFontSize(textFieldTheme->GetCancelIconSize());
967     }
968 }
969 
GetSymbolDefaultSize()970 CalcDimension CleanNodeResponseArea::GetSymbolDefaultSize()
971 {
972     auto textFieldPattern = DynamicCast<TextFieldPattern>(hostPattern_.Upgrade());
973     CHECK_NULL_RETURN(textFieldPattern, CalcDimension());
974     auto host = textFieldPattern->GetHost();
975     CHECK_NULL_RETURN(host, CalcDimension());
976     auto pipeline = host->GetContextRefPtr();
977     CHECK_NULL_RETURN(pipeline, CalcDimension());
978     auto themeManager = pipeline->GetThemeManager();
979     CHECK_NULL_RETURN(themeManager, CalcDimension());
980     auto textTheme = themeManager->GetTheme<TextTheme>();
981     CHECK_NULL_RETURN(textTheme, CalcDimension());
982     return textTheme->GetTextStyle().GetFontSize();
983 }
984 
UpdateSymbolSource()985 void CleanNodeResponseArea::UpdateSymbolSource()
986 {
987     auto textFieldPattern = DynamicCast<TextFieldPattern>(hostPattern_.Upgrade());
988     CHECK_NULL_VOID(textFieldPattern);
989     auto host = textFieldPattern->GetHost();
990     CHECK_NULL_VOID(host);
991     auto pipeline = host->GetContextRefPtr();
992     CHECK_NULL_VOID(pipeline);
993     auto themeManager = pipeline->GetThemeManager();
994     CHECK_NULL_VOID(themeManager);
995     auto textFieldTheme = themeManager->GetTheme<TextFieldTheme>(host->GetThemeScopeId());
996     CHECK_NULL_VOID(textFieldTheme);
997     auto symbolNode = cleanNode_->GetFirstChild();
998     CHECK_NULL_VOID(symbolNode);
999     auto symbolFrameNode = AceType::DynamicCast<FrameNode>(symbolNode);
1000     CHECK_NULL_VOID(symbolFrameNode);
1001     auto symbolProperty = symbolFrameNode->GetLayoutProperty<TextLayoutProperty>();
1002     CHECK_NULL_VOID(symbolProperty);
1003     auto layoutProperty = host->GetLayoutProperty<TextFieldLayoutProperty>();
1004     CHECK_NULL_VOID(layoutProperty);
1005     auto lastFontSize = symbolProperty->GetFontSize().value_or(GetSymbolDefaultSize());
1006     symbolProperty->UpdateSymbolSourceInfo(SymbolSourceInfo(textFieldTheme->GetCancelSymbolId()));
1007     symbolProperty->UpdateSymbolColorList({ textFieldTheme->GetSymbolColor() });
1008     auto maxFontScale = layoutProperty->GetMaxFontScale().value_or(MAX_FONT_SCALE);
1009     symbolProperty->UpdateMaxFontScale(std::min(MAX_FONT_SCALE, maxFontScale));
1010     symbolProperty->UpdateMinFontScale(layoutProperty->GetMinFontScale().value_or(0.0f));
1011 
1012     auto iconSymbol = layoutProperty->GetCancelIconSymbol();
1013     if (iconSymbol && host->GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
1014         iconSymbol(AccessibilityManager::WeakClaim(AccessibilityManager::RawPtr(symbolFrameNode)));
1015         // reset symbol effect
1016         auto symbolEffectOptions = symbolProperty->GetSymbolEffectOptionsValue(SymbolEffectOptions());
1017         symbolEffectOptions.SetIsTxtActive(false);
1018         symbolProperty->UpdateSymbolEffectOptions(symbolEffectOptions);
1019     }
1020 
1021     Dimension fontSize;
1022     if (host->GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
1023         fontSize = symbolProperty->GetFontSize().value_or(textFieldTheme->GetCancelIconSize());
1024     } else {
1025         fontSize = symbolProperty->GetFontSize().value_or(textFieldTheme->GetSymbolSize());
1026     }
1027     if (GreatOrEqualCustomPrecision(fontSize.ConvertToPx(), ICON_MAX_SIZE.ConvertToPx())) {
1028         fontSize = ICON_MAX_SIZE;
1029     }
1030     iconSize_ = fontSize;
1031     symbolProperty->UpdateFontSize(lastFontSize);
1032 
1033     symbolFrameNode->MarkModifyDone();
1034     symbolFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1035 }
1036 
InitClickEvent(const RefPtr<FrameNode> & frameNode)1037 void CleanNodeResponseArea::InitClickEvent(const RefPtr<FrameNode>& frameNode)
1038 {
1039     auto focusHub = frameNode->GetOrCreateFocusHub();
1040     CHECK_NULL_VOID(focusHub);
1041     auto gesture = frameNode->GetOrCreateGestureEventHub();
1042     auto clickCallback = [weak = WeakClaim(this)](GestureEvent& info) {
1043         auto cleanNode = weak.Upgrade();
1044         CHECK_NULL_VOID(cleanNode);
1045         cleanNode->OnCleanNodeClicked();
1046     };
1047     gesture->AddClickEvent(MakeRefPtr<ClickEvent>(std::move(clickCallback)));
1048 }
1049 
OnCleanNodeClicked()1050 void CleanNodeResponseArea::OnCleanNodeClicked()
1051 {
1052     auto textFieldPattern = DynamicCast<TextFieldPattern>(hostPattern_.Upgrade());
1053     CHECK_NULL_VOID(textFieldPattern);
1054     CHECK_NULL_VOID(!textFieldPattern->IsDragging());
1055     textFieldPattern->CleanNodeResponseKeyEvent();
1056     auto host = textFieldPattern->GetHost();
1057     CHECK_NULL_VOID(host);
1058     host->OnAccessibilityEvent(AccessibilityEventType::REQUEST_FOCUS);
1059 }
1060 
UpdateCleanNode(bool isShow)1061 void CleanNodeResponseArea::UpdateCleanNode(bool isShow)
1062 {
1063     isShow_ = isShow;
1064     auto textFieldPattern = DynamicCast<TextFieldPattern>(hostPattern_.Upgrade());
1065     CHECK_NULL_VOID(textFieldPattern);
1066     CHECK_NULL_VOID(cleanNode_);
1067     auto stackLayoutProperty = cleanNode_->GetLayoutProperty<LayoutProperty>();
1068     CHECK_NULL_VOID(stackLayoutProperty);
1069     auto iconNode = cleanNode_->GetFirstChild();
1070     CHECK_NULL_VOID(iconNode);
1071     auto iconFrameNode = AceType::DynamicCast<FrameNode>(iconNode);
1072     CHECK_NULL_VOID(iconFrameNode);
1073     auto iconLayoutProperty = iconFrameNode->GetLayoutProperty<LayoutProperty>();
1074     CHECK_NULL_VOID(iconLayoutProperty);
1075     if (isShow) {
1076         auto host = textFieldPattern->GetHost();
1077         CHECK_NULL_VOID(host);
1078         auto pipeline = host->GetContextRefPtr();
1079         CHECK_NULL_VOID(pipeline);
1080         auto themeManager = pipeline->GetThemeManager();
1081         CHECK_NULL_VOID(themeManager);
1082         auto textFieldTheme = themeManager->GetTheme<TextFieldTheme>();
1083         CHECK_NULL_VOID(textFieldTheme);
1084         auto rightOffset = GetCancelButtonPadding(textFieldTheme);
1085         auto geometryNode = host->GetGeometryNode();
1086         CHECK_NULL_VOID(geometryNode);
1087         auto frameSize = geometryNode->GetFrameSize();
1088         auto iconSize = GetIconSize();
1089         if (!NearZero(frameSize.Height())) {
1090             iconSize = std::min(iconSize, frameSize.Height());
1091         }
1092         auto hotZoneSize = NearZero(iconSize) ? 0.0f : iconSize + rightOffset;
1093         stackLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(hotZoneSize), CalcLength(iconSize)));
1094         iconLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(iconSize), CalcLength(iconSize)));
1095         if (IsSymbolIcon()) {
1096             auto symbolProperty = iconFrameNode->GetLayoutProperty<TextLayoutProperty>();
1097             CHECK_NULL_VOID(symbolProperty);
1098             symbolProperty->UpdateFontSize(CalcDimension(iconSize));
1099         }
1100         stackLayoutProperty->UpdateVisibility(VisibleType::VISIBLE);
1101         iconLayoutProperty->UpdateVisibility(VisibleType::VISIBLE);
1102     } else {
1103         stackLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(0.0f), std::nullopt));
1104         iconLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(0.0f), CalcLength(0.0f)));
1105         stackLayoutProperty->UpdateVisibility(VisibleType::INVISIBLE);
1106         iconLayoutProperty->UpdateVisibility(VisibleType::INVISIBLE);
1107     }
1108     iconFrameNode->MarkModifyDone();
1109     iconFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1110 }
1111 
CheckUpdateCleanNode()1112 bool CleanNodeResponseArea::CheckUpdateCleanNode()
1113 {
1114     CHECK_NULL_RETURN(cleanNode_, false);
1115     auto cleanNodeGeometryNode = cleanNode_->GetGeometryNode();
1116     CHECK_NULL_RETURN(cleanNodeGeometryNode, false);
1117     auto textFieldPattern = DynamicCast<TextFieldPattern>(hostPattern_.Upgrade());
1118     CHECK_NULL_RETURN(textFieldPattern, false);
1119     auto host = textFieldPattern->GetHost();
1120     CHECK_NULL_RETURN(host, false);
1121     auto geometryNode = host->GetGeometryNode();
1122     CHECK_NULL_RETURN(geometryNode, false);
1123     auto textFieldFrameSize = geometryNode->GetFrameSize();
1124     auto cleanNodeFrameSize = cleanNodeGeometryNode->GetFrameSize();
1125     return GreatNotEqual(cleanNodeFrameSize.Height(), textFieldFrameSize.Height());
1126 }
1127 
ClearArea()1128 void CleanNodeResponseArea::ClearArea()
1129 {
1130     auto hostPattern = hostPattern_.Upgrade();
1131     CHECK_NULL_VOID(hostPattern);
1132     auto host = hostPattern->GetHost();
1133     CHECK_NULL_VOID(host);
1134     CHECK_NULL_VOID(cleanNode_);
1135     host->RemoveChildAndReturnIndex(cleanNode_);
1136     cleanNode_.Reset();
1137     areaRect_.Reset();
1138 }
1139 
Refresh()1140 void CleanNodeResponseArea::Refresh()
1141 {
1142     auto textFieldPattern = hostPattern_.Upgrade();
1143     if (textFieldPattern && cleanNode_) {
1144         auto layoutProperty = textFieldPattern->GetLayoutProperty<TextFieldLayoutProperty>();
1145         auto stackLayoutProperty = cleanNode_->GetLayoutProperty<LayoutProperty>();
1146         if (layoutProperty && stackLayoutProperty) {
1147             stackLayoutProperty->UpdateAlignment(GetStackAlignment(layoutProperty->GetLayoutDirection()));
1148         }
1149     }
1150 
1151     // update node symbol
1152     if (IsShowSymbol() && IsSymbolIcon() && SystemProperties::IsNeedSymbol()) {
1153         UpdateSymbolSource();
1154         return;
1155     }
1156 
1157     // update node image
1158     if (!IsShowSymbol() && !IsSymbolIcon()) {
1159         LoadingImageProperty();
1160         auto info = CreateImageSourceInfo();
1161         CHECK_NULL_VOID(cleanNode_);
1162         auto imageNode = cleanNode_->GetFirstChild();
1163         CHECK_NULL_VOID(imageNode);
1164         auto imageFrameNode = AceType::DynamicCast<FrameNode>(imageNode);
1165         CHECK_NULL_VOID(imageFrameNode);
1166         auto imageLayoutProperty = imageFrameNode->GetLayoutProperty<ImageLayoutProperty>();
1167         CHECK_NULL_VOID(imageLayoutProperty);
1168         imageLayoutProperty->UpdateImageSourceInfo(info);
1169         imageFrameNode->MarkModifyDone();
1170         imageFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1171         return;
1172     }
1173 
1174     ReplaceNode();
1175 }
1176 
ReplaceNode()1177 void CleanNodeResponseArea::ReplaceNode()
1178 {
1179     CHECK_NULL_VOID(cleanNode_);
1180     CHECK_NULL_VOID(cleanNode_->GetFirstChild());
1181     auto oldFrameNode = AceType::DynamicCast<FrameNode>(cleanNode_->GetFirstChild());
1182     CHECK_NULL_VOID(oldFrameNode);
1183 
1184     if (IsShowSymbol() && SystemProperties::IsNeedSymbol()) {
1185         auto symbolNode = FrameNode::GetOrCreateFrameNode(V2::SYMBOL_ETS_TAG,
1186             ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<TextPattern>(); });
1187         CHECK_NULL_VOID(symbolNode);
1188         cleanNode_->ReplaceChild(oldFrameNode, symbolNode);
1189         UpdateSymbolSource();
1190         return;
1191     }
1192 
1193     LoadingImageProperty();
1194     auto info = CreateImageSourceInfo();
1195     auto imageNode = CreateResponseAreaImageNode(info, ImageFit::COVER, CalcSize(CalcLength(0.0f), CalcLength(0.0f)));
1196     CHECK_NULL_VOID(imageNode);
1197 
1198     cleanNode_->ReplaceChild(oldFrameNode, imageNode);
1199     imageNode->MarkModifyDone();
1200     imageNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1201 }
1202 
LoadingImageProperty()1203 void CleanNodeResponseArea::LoadingImageProperty()
1204 {
1205     auto pattern = hostPattern_.Upgrade();
1206     CHECK_NULL_VOID(pattern);
1207     auto textFieldLayoutProperty = pattern->GetLayoutProperty<TextFieldLayoutProperty>();
1208     CHECK_NULL_VOID(textFieldLayoutProperty);
1209     if (textFieldLayoutProperty->HasIconSize()) {
1210         auto iconSizeValue = textFieldLayoutProperty->GetIconSizeValue();
1211         if (iconSizeValue.Unit() == DimensionUnit::PERCENT) {
1212             iconSize_ = iconSizeValue;
1213         } else {
1214             auto host = pattern->GetHost();
1215             CHECK_NULL_VOID(host);
1216             auto pipeline = host->GetContext();
1217             CHECK_NULL_VOID(pipeline);
1218             auto maxFontScale = pipeline->GetFontScale();
1219             auto minFontScale = 0.0f;
1220             if (textFieldLayoutProperty->HasMaxFontScale()) {
1221                 maxFontScale = std::min(textFieldLayoutProperty->GetMaxFontScale().value(), maxFontScale);
1222             }
1223             if (textFieldLayoutProperty->HasMinFontScale()) {
1224                 minFontScale = textFieldLayoutProperty->GetMinFontScale().value();
1225             }
1226             iconSize_ = Dimension(iconSizeValue).ConvertToPxDistribute(minFontScale, maxFontScale);
1227         }
1228     }
1229     if (textFieldLayoutProperty->HasIconSrc()) {
1230         iconSrc_ = textFieldLayoutProperty->GetIconSrcValue();
1231     }
1232     LoadingCancelButtonColor();
1233     if (textFieldLayoutProperty->HasBundleName()) {
1234         bundleName_ = textFieldLayoutProperty->GetBundleNameValue();
1235     }
1236     if (textFieldLayoutProperty->HasModuleName()) {
1237         moduleName_ = textFieldLayoutProperty->GetModuleNameValue();
1238     }
1239 }
1240 
LoadingCancelButtonColor()1241 void CleanNodeResponseArea::LoadingCancelButtonColor()
1242 {
1243     auto pattern = hostPattern_.Upgrade();
1244     CHECK_NULL_VOID(pattern);
1245     auto textFieldLayoutProperty = pattern->GetLayoutProperty<TextFieldLayoutProperty>();
1246     CHECK_NULL_VOID(textFieldLayoutProperty);
1247     if (textFieldLayoutProperty->GetIsDisabledValue(false)) {
1248         auto host = pattern->GetHost();
1249         CHECK_NULL_VOID(host);
1250         auto pipeline = host->GetContext();
1251         CHECK_NULL_VOID(pipeline);
1252         auto theme = pipeline->GetTheme<TextFieldTheme>(host->GetThemeScopeId());
1253         CHECK_NULL_VOID(theme);
1254         iconColor_ = theme->GetTextColorDisable();
1255     } else if (textFieldLayoutProperty->HasIconColor()) {
1256         iconColor_ = textFieldLayoutProperty->GetIconColorValue();
1257     }
1258 }
1259 
CreateImageSourceInfo()1260 ImageSourceInfo CleanNodeResponseArea::CreateImageSourceInfo()
1261 {
1262     ImageSourceInfo info;
1263     info.SetBundleName(bundleName_);
1264     info.SetModuleName(moduleName_);
1265     if (iconSrc_.empty()) {
1266         info.SetResourceId(InternalResource::ResourceId::CLOSE_SVG);
1267     } else {
1268         info.SetSrc(iconSrc_);
1269     }
1270     auto pattern = hostPattern_.Upgrade();
1271     CHECK_NULL_RETURN(pattern, info);
1272     auto textFieldLayoutProperty = pattern->GetLayoutProperty<TextFieldLayoutProperty>();
1273     CHECK_NULL_RETURN(textFieldLayoutProperty, info);
1274     if (info.IsSvg() && textFieldLayoutProperty->HasIconColor()) {
1275         info.SetFillColor(iconColor_);
1276         CHECK_NULL_RETURN(cleanNode_, info);
1277         auto imageNode = cleanNode_->GetFirstChild();
1278         CHECK_NULL_RETURN(imageNode, info);
1279         auto imageFrameNode = AceType::DynamicCast<FrameNode>(imageNode);
1280         CHECK_NULL_RETURN(imageFrameNode, info);
1281         auto imageRenderProperty = imageFrameNode->GetPaintProperty<ImageRenderProperty>();
1282         CHECK_NULL_RETURN(imageRenderProperty, info);
1283         imageRenderProperty->UpdateSvgFillColor(iconColor_);
1284     }
1285     return info;
1286 }
1287 
OnThemeScopeUpdate(const RefPtr<TextFieldTheme> & theme)1288 void CleanNodeResponseArea::OnThemeScopeUpdate(const RefPtr<TextFieldTheme>& theme)
1289 {
1290     if (IsShowSymbol() && SystemProperties::IsNeedSymbol()) {
1291         UpdateSymbolSource();
1292     }
1293 }
1294 } // namespace OHOS::Ace::NG