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