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_ng/event/input_event.h"
27 #include "core/components_ng/layout/layout_property.h"
28 #include "core/components_ng/pattern/image/image_pattern.h"
29 #include "core/components_ng/pattern/stack/stack_pattern.h"
30 #include "core/components_ng/pattern/text_field/text_field_layout_property.h"
31 #include "core/components_ng/pattern/text_field/text_field_pattern.h"
32 #include "core/components_ng/property/measure_property.h"
33 #include "core/components_v2/inspector/inspector_constants.h"
34 #include "core/event/mouse_event.h"
35 #include "core/pipeline/pipeline_context.h"
36 #include "core/pipeline_ng/ui_task_scheduler.h"
37
38 namespace OHOS::Ace::NG {
39 // TextInputResponseArea begin
LayoutChild(LayoutWrapper * layoutWrapper,int32_t index,float & nodeWidth)40 void TextInputResponseArea::LayoutChild(LayoutWrapper* layoutWrapper, int32_t index, float& nodeWidth)
41 {
42 auto frameNode = layoutWrapper->GetHostNode();
43 CHECK_NULL_VOID(frameNode);
44 auto children = frameNode->GetChildren();
45 CHECK_NULL_VOID(!children.empty());
46 auto pattern = frameNode->GetPattern<TextFieldPattern>();
47 CHECK_NULL_VOID(pattern);
48 auto textInputGeometryNode = layoutWrapper->GetGeometryNode();
49 CHECK_NULL_VOID(textInputGeometryNode);
50 auto contentRect = textInputGeometryNode->GetContentRect();
51 auto textInputFrameSize = textInputGeometryNode->GetFrameSize();
52 auto childWrapper = layoutWrapper->GetOrCreateChildByIndex(index);
53 CHECK_NULL_VOID(childWrapper);
54 auto childGeometryNode = childWrapper->GetGeometryNode();
55 CHECK_NULL_VOID(childGeometryNode);
56 auto childFrameSize = childGeometryNode->GetFrameSize();
57 auto childOffset = GetChildOffset(textInputFrameSize, contentRect, childFrameSize, nodeWidth);
58 childGeometryNode->SetFrameOffset(childOffset);
59 childWrapper->GetGeometryNode()->SetFrameSize(childFrameSize);
60 areaRect_.SetSize(childFrameSize);
61 areaRect_.SetOffset(childOffset);
62 childWrapper->Layout();
63 nodeWidth += childFrameSize.Width();
64 }
65
GetChildOffset(SizeF parentSize,RectF contentRect,SizeF childSize,float nodeWidth)66 OffsetF TextInputResponseArea::GetChildOffset(SizeF parentSize, RectF contentRect, SizeF childSize, float nodeWidth)
67 {
68 auto offset = Alignment::GetAlignPosition(parentSize, childSize, Alignment::CENTER);
69 auto textFieldPattern = hostPattern_.Upgrade();
70 auto layoutProperty = textFieldPattern->GetLayoutProperty<TextFieldLayoutProperty>();
71 auto isRTL = layoutProperty->GetNonAutoLayoutDirection() == TextDirection::RTL;
72 if (isRTL) {
73 return OffsetF(nodeWidth, offset.GetY());
74 } else {
75 return OffsetF(parentSize.Width() - childSize.Width() - nodeWidth, offset.GetY());
76 }
77 }
78
Measure(LayoutWrapper * layoutWrapper,int32_t index)79 SizeF TextInputResponseArea::Measure(LayoutWrapper* layoutWrapper, int32_t index)
80 {
81 auto childWrapper = layoutWrapper->GetOrCreateChildByIndex(index);
82 auto textfieldLayoutProperty = AceType::DynamicCast<TextFieldLayoutProperty>(layoutWrapper->GetLayoutProperty());
83 SizeF size(0, 0);
84 CHECK_NULL_RETURN(textfieldLayoutProperty, size);
85 auto childLayoutConstraint = textfieldLayoutProperty->CreateChildConstraint();
86 CHECK_NULL_RETURN(childWrapper, size);
87 auto childLayoutProperty = childWrapper->GetLayoutProperty();
88 childWrapper->Measure(childLayoutConstraint);
89 auto geometryNode = childWrapper->GetGeometryNode();
90 CHECK_NULL_RETURN(geometryNode, size);
91 return geometryNode->GetFrameSize();
92 }
93
GetFrameSize(bool withSafeArea)94 SizeF TextInputResponseArea::GetFrameSize(bool withSafeArea)
95 {
96 auto frameNode = GetFrameNode();
97 CHECK_NULL_RETURN(frameNode, SizeF(0, 0));
98 auto geometryNode = frameNode->GetGeometryNode();
99 CHECK_NULL_RETURN(geometryNode, SizeF(0, 0));
100 return geometryNode->GetFrameSize(withSafeArea);
101 }
102
GetStackAlignment(const TextDirection & userDirection)103 Alignment TextInputResponseArea::GetStackAlignment(const TextDirection& userDirection)
104 {
105 bool isSysRtl = AceApplicationInfo::GetInstance().IsRightToLeft();
106 if ((isSysRtl && userDirection == TextDirection::LTR) ||
107 (!isSysRtl && userDirection == TextDirection::RTL)) {
108 return Alignment::CENTER_RIGHT;
109 }
110 return Alignment::CENTER_LEFT;
111 }
112 // TextInputResponseArea end
113
114 // PasswordResponseArea begin
InitResponseArea()115 void PasswordResponseArea::InitResponseArea()
116 {
117 ClearArea();
118 auto pattern = hostPattern_.Upgrade();
119 CHECK_NULL_VOID(pattern);
120 auto host = pattern->GetHost();
121 CHECK_NULL_VOID(host);
122 if (!IsShowPasswordIcon()) {
123 return;
124 }
125 auto passwordNode = CreateNode();
126 CHECK_NULL_VOID(passwordNode);
127 passwordNode->MountToParent(host);
128 }
129
GetFrameNode()130 const RefPtr<FrameNode> PasswordResponseArea::GetFrameNode()
131 {
132 auto frameNode = passwordNode_.Upgrade();
133 CHECK_NULL_RETURN(frameNode, nullptr);
134 auto stackNode = frameNode->GetParent();
135 CHECK_NULL_RETURN(stackNode, nullptr);
136 auto ret = AceType::DynamicCast<FrameNode>(stackNode);
137 CHECK_NULL_RETURN(ret, nullptr);
138 return ret;
139 }
140
CreateNode()141 RefPtr<FrameNode> PasswordResponseArea::CreateNode()
142 {
143 auto textFieldPattern = DynamicCast<TextFieldPattern>(hostPattern_.Upgrade());
144 CHECK_NULL_RETURN(textFieldPattern, nullptr);
145 auto iconSize = GetIconSize();
146 auto rightOffset = GetIconRightOffset();
147 auto hotZoneSize = iconSize + rightOffset;
148
149 auto stackNode = FrameNode::CreateFrameNode(
150 V2::STACK_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<StackPattern>());
151 auto stackLayoutProperty = stackNode->GetLayoutProperty<LayoutProperty>();
152 CHECK_NULL_RETURN(stackLayoutProperty, nullptr);
153 stackLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(hotZoneSize), std::nullopt));
154 auto layoutProperty = textFieldPattern->GetLayoutProperty<TextFieldLayoutProperty>();
155 CHECK_NULL_RETURN(layoutProperty, nullptr);
156 stackLayoutProperty->UpdateAlignment(GetStackAlignment(layoutProperty->GetLayoutDirection()));
157 AddEvent(stackNode);
158 stackNode->MarkModifyDone();
159
160 auto imageNode = FrameNode::CreateFrameNode(
161 V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
162 imageNode->SetDraggable(false);
163 LoadImageSourceInfo();
164 auto currentImageSourceInfo = GetCurrentSourceInfo();
165 CHECK_NULL_RETURN(currentImageSourceInfo, nullptr);
166 auto imageLayoutProperty = imageNode->GetLayoutProperty<ImageLayoutProperty>();
167 imageLayoutProperty->UpdateImageSourceInfo(currentImageSourceInfo.value());
168 imageLayoutProperty->UpdateImageFit(ImageFit::FILL);
169 imageLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(iconSize), CalcLength(iconSize)));
170 auto eventHub = imageNode->GetEventHub<ImageEventHub>();
171 CHECK_NULL_RETURN(eventHub, nullptr);
172 eventHub->SetOnError([ weakNode = WeakClaim(AceType::RawPtr(imageNode)), weakArea = WeakClaim(this) ]
173 (const LoadImageFailEvent& info) {
174 auto host = weakNode.Upgrade();
175 CHECK_NULL_VOID(host);
176 auto area = weakArea.Upgrade();
177 CHECK_NULL_VOID(area);
178 auto imagePattern = host->GetPattern<ImagePattern>();
179 CHECK_NULL_VOID(imagePattern);
180 auto layoutProperty = host->GetLayoutProperty<ImageLayoutProperty>();
181 layoutProperty->UpdateImageSourceInfo(area->GetDefaultSourceInfo(area->isObscured_));
182 imagePattern->LoadImageDataIfNeed();
183 });
184 imageNode->MarkModifyDone();
185 imageNode->MountToParent(stackNode);
186 passwordNode_ = imageNode;
187 stackNode_ = stackNode;
188 return stackNode;
189 }
190
AddEvent(const RefPtr<FrameNode> & node)191 void PasswordResponseArea::AddEvent(const RefPtr<FrameNode>& node)
192 {
193 CHECK_NULL_VOID(node);
194 auto focusHub = node->GetOrCreateFocusHub();
195 CHECK_NULL_VOID(focusHub);
196 auto gesture = node->GetOrCreateGestureEventHub();
197 auto clickCallback = [weak = WeakClaim(this)](GestureEvent& info) {
198 auto button = weak.Upgrade();
199 CHECK_NULL_VOID(button);
200 button->OnPasswordIconClicked();
201 auto context = PipelineBase::GetCurrentContextSafely();
202 CHECK_NULL_VOID(context);
203 auto theme = context->GetTheme<TextFieldTheme>();
204 CHECK_NULL_VOID(theme);
205 auto node = button->GetFrameNode();
206 CHECK_NULL_VOID(node);
207 auto message = !button->IsObscured() ? theme->GetHasShowedPassword() : theme->GetHasHiddenPassword();
208 node->OnAccessibilityEvent(AccessibilityEventType::ANNOUNCE_FOR_ACCESSIBILITY, message);
209 };
210 auto mouseTask = [id = Container::CurrentId(), weak = hostPattern_](MouseInfo& info) {
211 info.SetStopPropagation(true);
212 auto pattern = weak.Upgrade();
213 CHECK_NULL_VOID(pattern);
214 auto textfield = DynamicCast<TextFieldPattern>(pattern);
215 CHECK_NULL_VOID(textfield);
216 textfield->RestoreDefaultMouseState();
217 };
218 auto touchTask = [weak = WeakClaim(this)](TouchEventInfo& info) {
219 info.SetStopPropagation(true);
220 };
221
222 auto inputHub = node->GetOrCreateInputEventHub();
223 auto mouseEvent = MakeRefPtr<InputEvent>(std::move(mouseTask));
224 inputHub->AddOnMouseEvent(mouseEvent);
225 gesture->AddClickEvent(MakeRefPtr<ClickEvent>(std::move(clickCallback)));
226 gesture->AddTouchEvent(MakeRefPtr<TouchEventImpl>(std::move(touchTask)));
227 }
228
Refresh()229 void PasswordResponseArea::Refresh()
230 {
231 auto imageNode = passwordNode_.Upgrade();
232 if (!imageNode) {
233 InitResponseArea();
234 return;
235 }
236
237 auto textFieldPattern = hostPattern_.Upgrade();
238 if (textFieldPattern && stackNode_) {
239 auto layoutProperty = textFieldPattern->GetLayoutProperty<TextFieldLayoutProperty>();
240 auto stackLayoutProperty = stackNode_->GetLayoutProperty<LayoutProperty>();
241 if (stackLayoutProperty && layoutProperty) {
242 stackLayoutProperty->UpdateAlignment(GetStackAlignment(layoutProperty->GetLayoutDirection()));
243 }
244 }
245
246 auto imageLayoutProperty = imageNode->GetLayoutProperty<ImageLayoutProperty>();
247 CHECK_NULL_VOID(imageLayoutProperty);
248 auto currentSrc = imageLayoutProperty->GetImageSourceInfoValue().GetSrc();
249 LoadImageSourceInfo();
250 auto src = isObscured_ ? hideIcon_->GetSrc() : showIcon_->GetSrc();
251 if (currentSrc != src) {
252 UpdateImageSource();
253 }
254 }
255
OnPasswordIconClicked()256 void PasswordResponseArea::OnPasswordIconClicked()
257 {
258 isObscured_ = !isObscured_;
259 ChangeObscuredState();
260 }
261
ChangeObscuredState()262 void PasswordResponseArea::ChangeObscuredState()
263 {
264 UpdateImageSource();
265 auto textFieldPattern = DynamicCast<TextFieldPattern>(hostPattern_.Upgrade());
266 CHECK_NULL_VOID(textFieldPattern);
267 textFieldPattern->OnObscuredChanged(isObscured_);
268 }
269
Measure(LayoutWrapper * layoutWrapper,int32_t index)270 SizeF PasswordResponseArea::Measure(LayoutWrapper* layoutWrapper, int32_t index)
271 {
272 if (!IsShowPasswordIcon()) {
273 return SizeF(0, 0);
274 }
275 return TextInputResponseArea::Measure(layoutWrapper, index);
276 }
277
Layout(LayoutWrapper * layoutWrapper,int32_t index,float & nodeWidth)278 void PasswordResponseArea::Layout(LayoutWrapper* layoutWrapper, int32_t index, float& nodeWidth)
279 {
280 if (!IsShowPasswordIcon()) {
281 return;
282 }
283 LayoutChild(layoutWrapper, index, nodeWidth);
284 }
285
GetIconSize()286 float PasswordResponseArea::GetIconSize()
287 {
288 auto textFieldPattern = hostPattern_.Upgrade();
289 CHECK_NULL_RETURN(textFieldPattern, 0.0f);
290 auto tmpHost = textFieldPattern->GetHost();
291 CHECK_NULL_RETURN(tmpHost, 0.0f);
292 auto pipeline = tmpHost->GetContextRefPtr();
293 CHECK_NULL_RETURN(pipeline, 0.0f);
294 auto themeManager = pipeline->GetThemeManager();
295 CHECK_NULL_RETURN(themeManager, 0.0f);
296 auto textFieldTheme = themeManager->GetTheme<TextFieldTheme>();
297 CHECK_NULL_RETURN(textFieldTheme, 0.0f);
298 return static_cast<float>(textFieldTheme->GetIconSize().ConvertToPx());
299 }
300
GetIconRightOffset()301 float PasswordResponseArea::GetIconRightOffset()
302 {
303 auto textFieldPattern = hostPattern_.Upgrade();
304 CHECK_NULL_RETURN(textFieldPattern, 0.0f);
305 auto tmpHost = textFieldPattern->GetHost();
306 auto pipeline = tmpHost->GetContextRefPtr();
307 CHECK_NULL_RETURN(pipeline, 0.0f);
308 auto themeManager = pipeline->GetThemeManager();
309 CHECK_NULL_RETURN(themeManager, 0.0f);
310 auto textFieldTheme = themeManager->GetTheme<TextFieldTheme>();
311 CHECK_NULL_RETURN(textFieldTheme, 0.0f);
312 auto themePadding = textFieldTheme->GetPadding();
313 return static_cast<float>(themePadding.Left().ConvertToPx());
314 }
315
LoadImageSourceInfo()316 void PasswordResponseArea::LoadImageSourceInfo()
317 {
318 auto textFieldPattern = hostPattern_.Upgrade();
319 CHECK_NULL_VOID(textFieldPattern);
320 auto layoutProperty = textFieldPattern->GetLayoutProperty<TextFieldLayoutProperty>();
321 CHECK_NULL_VOID(layoutProperty);
322 showIcon_ = layoutProperty->GetShowPasswordSourceInfoValue(GetDefaultSourceInfo(false));
323 hideIcon_ = layoutProperty->GetHidePasswordSourceInfoValue(GetDefaultSourceInfo(true));
324 auto tmpHost = textFieldPattern->GetHost();
325 CHECK_NULL_VOID(tmpHost);
326 auto pipeline = tmpHost->GetContextRefPtr();
327 CHECK_NULL_VOID(pipeline);
328 auto themeManager = pipeline->GetThemeManager();
329 CHECK_NULL_VOID(themeManager);
330 auto textFieldTheme = themeManager->GetTheme<TextFieldTheme>();
331 CHECK_NULL_VOID(textFieldTheme);
332 if (showIcon_->GetResourceId() == InternalResource::ResourceId::SHOW_PASSWORD_SVG) {
333 showIcon_->SetFillColor(textFieldTheme->GetTextColor());
334 }
335 if (hideIcon_->GetResourceId() == InternalResource::ResourceId::HIDE_PASSWORD_SVG) {
336 hideIcon_->SetFillColor(textFieldTheme->GetTextColor());
337 }
338 if (layoutProperty->GetIsDisabledValue(false)) {
339 auto iconTheme = pipeline->GetTheme<IconTheme>();
340 CHECK_NULL_VOID(iconTheme);
341 auto textDisableColor = textFieldTheme->GetTextColorDisable();
342 auto hideIconPath = iconTheme->GetIconPath(hideIcon_->GetResourceId());
343 hideIcon_->SetSrc(hideIconPath, textDisableColor);
344 auto showIconPath = iconTheme->GetIconPath(showIcon_->GetResourceId());
345 showIcon_->SetSrc(showIconPath, textDisableColor);
346 UpdateImageSource();
347 }
348 }
349
GetDefaultSourceInfo(bool isObscured)350 ImageSourceInfo PasswordResponseArea::GetDefaultSourceInfo(bool isObscured)
351 {
352 if (isObscured) {
353 ImageSourceInfo hideSystemSourceInfo;
354 hideSystemSourceInfo.SetResourceId(InternalResource::ResourceId::HIDE_PASSWORD_SVG);
355 return hideSystemSourceInfo;
356 }
357 ImageSourceInfo showSystemSourceInfo;
358 showSystemSourceInfo.SetResourceId(InternalResource::ResourceId::SHOW_PASSWORD_SVG);
359 return showSystemSourceInfo;
360 }
361
UpdateImageSource()362 void PasswordResponseArea::UpdateImageSource()
363 {
364 auto frameNode = passwordNode_.Upgrade();
365 CHECK_NULL_VOID(frameNode);
366 auto layoutProperty = frameNode->GetLayoutProperty<ImageLayoutProperty>();
367 CHECK_NULL_VOID(layoutProperty);
368 auto currentImageSourceInfo = GetCurrentSourceInfo();
369 CHECK_NULL_VOID(currentImageSourceInfo);
370 layoutProperty->UpdateImageSourceInfo(currentImageSourceInfo.value());
371 auto imagePattern = frameNode->GetPattern<ImagePattern>();
372 CHECK_NULL_VOID(imagePattern);
373 imagePattern->LoadImageDataIfNeed();
374 }
375
IsShowPasswordIcon()376 bool PasswordResponseArea::IsShowPasswordIcon()
377 {
378 auto textFieldPattern = AceType::DynamicCast<TextFieldPattern>(hostPattern_.Upgrade());
379 CHECK_NULL_RETURN(textFieldPattern, false);
380 return textFieldPattern->IsShowPasswordIcon();
381 } // PasswordResponseArea end
382
383 // UnitResponseArea begin
InitResponseArea()384 void UnitResponseArea::InitResponseArea()
385 {
386 auto pattern = hostPattern_.Upgrade();
387 CHECK_NULL_VOID(pattern);
388 auto host = pattern->GetHost();
389 CHECK_NULL_VOID(host);
390 if (!IsShowUnit()) {
391 return;
392 }
393 CHECK_NULL_VOID(unitNode_);
394 unitNode_->MountToParent(host);
395 }
396
GetFrameNode()397 const RefPtr<FrameNode> UnitResponseArea::GetFrameNode()
398 {
399 auto frameNode = AceType::DynamicCast<FrameNode>(unitNode_);
400 CHECK_NULL_RETURN(frameNode, nullptr);
401 return frameNode;
402 }
403
Measure(LayoutWrapper * layoutWrapper,int32_t index)404 SizeF UnitResponseArea::Measure(LayoutWrapper* layoutWrapper, int32_t index)
405 {
406 if (!IsShowUnit()) {
407 return SizeF(0, 0);
408 }
409 return TextInputResponseArea::Measure(layoutWrapper, index);
410 }
411
Layout(LayoutWrapper * layoutWrapper,int32_t index,float & nodeWidth)412 void UnitResponseArea::Layout(LayoutWrapper* layoutWrapper, int32_t index, float& nodeWidth)
413 {
414 if (!IsShowUnit()) {
415 return;
416 }
417 LayoutChild(layoutWrapper, index, nodeWidth);
418 }
419
IsShowUnit()420 bool UnitResponseArea::IsShowUnit()
421 {
422 auto pattern = hostPattern_.Upgrade();
423 CHECK_NULL_RETURN(pattern, false);
424 auto textFieldPattern = AceType::DynamicCast<TextFieldPattern>(pattern);
425 CHECK_NULL_RETURN(textFieldPattern, false);
426 return textFieldPattern->IsUnderlineMode();
427 } // UnitResponseArea end
428
InitResponseArea()429 void CleanNodeResponseArea::InitResponseArea()
430 {
431 auto pattern = hostPattern_.Upgrade();
432 CHECK_NULL_VOID(pattern);
433 auto host = pattern->GetHost();
434 CHECK_NULL_VOID(host);
435 LoadingImageProperty();
436 auto cleanNode = CreateNode();
437 CHECK_NULL_VOID(cleanNode);
438 cleanNode->MountToParent(host);
439 }
440
Measure(LayoutWrapper * layoutWrapper,int32_t index)441 SizeF CleanNodeResponseArea::Measure(LayoutWrapper* layoutWrapper, int32_t index)
442 {
443 return TextInputResponseArea::Measure(layoutWrapper, index);
444 }
445
IsShowClean()446 bool CleanNodeResponseArea::IsShowClean()
447 {
448 auto pattern = hostPattern_.Upgrade();
449 CHECK_NULL_RETURN(pattern, false);
450 auto textFieldPattern = AceType::DynamicCast<TextFieldPattern>(pattern);
451 CHECK_NULL_RETURN(textFieldPattern, false);
452 return textFieldPattern->IsShowCancelButtonMode();
453 }
454
Layout(LayoutWrapper * layoutWrapper,int32_t index,float & nodeWidth)455 void CleanNodeResponseArea::Layout(LayoutWrapper *layoutWrapper, int32_t index, float &nodeWidth)
456 {
457 if (!IsShowClean()) {
458 return;
459 }
460 LayoutChild(layoutWrapper, index, nodeWidth);
461 }
462
GetFrameNode()463 const RefPtr<FrameNode> CleanNodeResponseArea::GetFrameNode()
464 {
465 return cleanNode_;
466 }
467
CreateNode()468 RefPtr<FrameNode> CleanNodeResponseArea::CreateNode()
469 {
470 auto stackNode = FrameNode::CreateFrameNode(
471 V2::STACK_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<StackPattern>());
472 auto stackLayoutProperty = stackNode->GetLayoutProperty<LayoutProperty>();
473 CHECK_NULL_RETURN(stackLayoutProperty, nullptr);
474 stackLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(0.0f), std::nullopt));
475 stackLayoutProperty->UpdateVisibility(VisibleType::INVISIBLE);
476 auto textFieldPattern = hostPattern_.Upgrade();
477 CHECK_NULL_RETURN(textFieldPattern, nullptr);
478 auto layoutProperty = textFieldPattern->GetLayoutProperty<TextFieldLayoutProperty>();
479 CHECK_NULL_RETURN(layoutProperty, nullptr);
480 stackLayoutProperty->UpdateAlignment(GetStackAlignment(layoutProperty->GetLayoutDirection()));
481 stackNode->MarkModifyDone();
482 auto cleanNode = FrameNode::CreateFrameNode(
483 V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ImagePattern>());
484 CHECK_NULL_RETURN(cleanNode, nullptr);
485 cleanNode->SetDraggable(false);
486 cleanNode_ = stackNode;
487 auto info = CreateImageSourceInfo();
488 auto imageLayoutProperty = cleanNode->GetLayoutProperty<ImageLayoutProperty>();
489 CHECK_NULL_RETURN(imageLayoutProperty, nullptr);
490 imageLayoutProperty->UpdateImageSourceInfo(info);
491 imageLayoutProperty->UpdateImageFit(ImageFit::COVER);
492 imageLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(0.0f), CalcLength(0.0f)));
493 imageLayoutProperty->UpdateVisibility(VisibleType::INVISIBLE);
494 cleanNode->MarkModifyDone();
495 cleanNode->MountToParent(stackNode);
496 InitClickEvent(stackNode);
497 return stackNode;
498 }
499
InitClickEvent(const RefPtr<FrameNode> & frameNode)500 void CleanNodeResponseArea::InitClickEvent(const RefPtr<FrameNode>& frameNode)
501 {
502 auto focusHub = frameNode->GetOrCreateFocusHub();
503 CHECK_NULL_VOID(focusHub);
504 auto gesture = frameNode->GetOrCreateGestureEventHub();
505 auto clickCallback = [weak = WeakClaim(this)](GestureEvent& info) {
506 auto cleanNode = weak.Upgrade();
507 CHECK_NULL_VOID(cleanNode);
508 cleanNode->OnCleanNodeClicked();
509 };
510 gesture->AddClickEvent(MakeRefPtr<ClickEvent>(std::move(clickCallback)));
511 }
512
OnCleanNodeClicked()513 void CleanNodeResponseArea::OnCleanNodeClicked()
514 {
515 auto textFieldPattern = DynamicCast<TextFieldPattern>(hostPattern_.Upgrade());
516 CHECK_NULL_VOID(textFieldPattern);
517 CHECK_NULL_VOID(!textFieldPattern->IsDragging());
518 textFieldPattern->CleanNodeResponseKeyEvent();
519 auto host = textFieldPattern->GetHost();
520 CHECK_NULL_VOID(host);
521 host->OnAccessibilityEvent(AccessibilityEventType::REQUEST_FOCUS);
522 }
523
UpdateCleanNode(bool isShow)524 void CleanNodeResponseArea::UpdateCleanNode(bool isShow)
525 {
526 isShow_ = isShow;
527 auto textFieldPattern = DynamicCast<TextFieldPattern>(hostPattern_.Upgrade());
528 CHECK_NULL_VOID(textFieldPattern);
529 CHECK_NULL_VOID(cleanNode_);
530 auto stackLayoutProperty = cleanNode_->GetLayoutProperty<LayoutProperty>();
531 CHECK_NULL_VOID(stackLayoutProperty);
532 auto imageNode = cleanNode_->GetFirstChild();
533 CHECK_NULL_VOID(imageNode);
534 auto imageFrameNode = AceType::DynamicCast<FrameNode>(imageNode);
535 CHECK_NULL_VOID(imageFrameNode);
536 auto imageLayoutProperty = imageFrameNode->GetLayoutProperty<ImageLayoutProperty>();
537 CHECK_NULL_VOID(imageLayoutProperty);
538 if (isShow) {
539 auto host = textFieldPattern->GetHost();
540 CHECK_NULL_VOID(host);
541 auto pipeline = host->GetContextRefPtr();
542 CHECK_NULL_VOID(pipeline);
543 auto themeManager = pipeline->GetThemeManager();
544 CHECK_NULL_VOID(themeManager);
545 auto textFieldTheme = themeManager->GetTheme<TextFieldTheme>();
546 CHECK_NULL_VOID(textFieldTheme);
547 auto themePadding = textFieldTheme->GetPadding();
548 auto rightOffset = static_cast<float>(themePadding.Left().ConvertToPx());
549 auto geometryNode = host->GetGeometryNode();
550 CHECK_NULL_VOID(geometryNode);
551 auto frameSize = geometryNode->GetFrameSize();
552 auto iconSize = std::min(iconSize_.ConvertToPx(), static_cast<double>(frameSize.Height()));
553 if (NearZero(iconSize)) {
554 isShow_ = false;
555 }
556 auto hotZoneSize = iconSize + rightOffset;
557 stackLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(hotZoneSize), std::nullopt));
558 imageLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(iconSize), CalcLength(iconSize)));
559 stackLayoutProperty->UpdateVisibility(VisibleType::VISIBLE);
560 imageLayoutProperty->UpdateVisibility(VisibleType::VISIBLE);
561 } else {
562 stackLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(0.0f), std::nullopt));
563 imageLayoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(0.0f), CalcLength(0.0f)));
564 stackLayoutProperty->UpdateVisibility(VisibleType::INVISIBLE);
565 imageLayoutProperty->UpdateVisibility(VisibleType::INVISIBLE);
566 }
567 imageFrameNode->MarkModifyDone();
568 imageFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
569 }
570
ClearArea()571 void CleanNodeResponseArea::ClearArea()
572 {
573 auto hostPattern = hostPattern_.Upgrade();
574 CHECK_NULL_VOID(hostPattern);
575 auto host = hostPattern->GetHost();
576 CHECK_NULL_VOID(host);
577 CHECK_NULL_VOID(cleanNode_);
578 host->RemoveChildAndReturnIndex(cleanNode_);
579 cleanNode_.Reset();
580 areaRect_.Reset();
581 }
582
Refresh()583 void CleanNodeResponseArea::Refresh()
584 {
585 auto textFieldPattern = hostPattern_.Upgrade();
586 if (textFieldPattern && cleanNode_) {
587 auto layoutProperty = textFieldPattern->GetLayoutProperty<TextFieldLayoutProperty>();
588 auto stackLayoutProperty = cleanNode_->GetLayoutProperty<LayoutProperty>();
589 if (layoutProperty && stackLayoutProperty) {
590 stackLayoutProperty->UpdateAlignment(GetStackAlignment(layoutProperty->GetLayoutDirection()));
591 }
592 }
593 LoadingImageProperty();
594 auto info = CreateImageSourceInfo();
595 CHECK_NULL_VOID(cleanNode_);
596 auto imageNode = cleanNode_->GetFirstChild();
597 CHECK_NULL_VOID(imageNode);
598 auto imageFrameNode = AceType::DynamicCast<FrameNode>(imageNode);
599 CHECK_NULL_VOID(imageFrameNode);
600 auto imageLayoutProperty = imageFrameNode->GetLayoutProperty<ImageLayoutProperty>();
601 CHECK_NULL_VOID(imageLayoutProperty);
602 imageLayoutProperty->UpdateImageSourceInfo(info);
603 imageFrameNode->MarkModifyDone();
604 imageFrameNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
605 }
606
LoadingImageProperty()607 void CleanNodeResponseArea::LoadingImageProperty()
608 {
609 auto pattern = hostPattern_.Upgrade();
610 CHECK_NULL_VOID(pattern);
611 auto textFieldLayoutProperty = pattern->GetLayoutProperty<TextFieldLayoutProperty>();
612 CHECK_NULL_VOID(textFieldLayoutProperty);
613 if (textFieldLayoutProperty->HasIconSize()) {
614 iconSize_ = textFieldLayoutProperty->GetIconSizeValue();
615 }
616 if (textFieldLayoutProperty->HasIconSrc()) {
617 iconSrc_ = textFieldLayoutProperty->GetIconSrcValue();
618 }
619 LoadingCancelButtonColor();
620 if (textFieldLayoutProperty->HasBundleName()) {
621 bundleName_ = textFieldLayoutProperty->GetBundleNameValue();
622 }
623 if (textFieldLayoutProperty->HasModuleName()) {
624 moduleName_ = textFieldLayoutProperty->GetModuleNameValue();
625 }
626 }
627
LoadingCancelButtonColor()628 void CleanNodeResponseArea::LoadingCancelButtonColor()
629 {
630 auto pattern = hostPattern_.Upgrade();
631 CHECK_NULL_VOID(pattern);
632 auto textFieldLayoutProperty = pattern->GetLayoutProperty<TextFieldLayoutProperty>();
633 CHECK_NULL_VOID(textFieldLayoutProperty);
634 if (textFieldLayoutProperty->GetIsDisabledValue(false)) {
635 auto host = pattern->GetHost();
636 CHECK_NULL_VOID(host);
637 auto pipeline = host->GetContext();
638 CHECK_NULL_VOID(pipeline);
639 auto theme = pipeline->GetTheme<TextFieldTheme>();
640 CHECK_NULL_VOID(theme);
641 iconColor_ = theme->GetTextColorDisable();
642 } else if (textFieldLayoutProperty->HasIconColor()) {
643 iconColor_ = textFieldLayoutProperty->GetIconColorValue();
644 }
645 }
646
CreateImageSourceInfo()647 ImageSourceInfo CleanNodeResponseArea::CreateImageSourceInfo()
648 {
649 ImageSourceInfo info;
650 info.SetBundleName(bundleName_);
651 info.SetModuleName(moduleName_);
652 if (iconSrc_.empty()) {
653 info.SetResourceId(InternalResource::ResourceId::CLOSE_SVG);
654 } else {
655 info.SetSrc(iconSrc_);
656 }
657 auto pattern = hostPattern_.Upgrade();
658 CHECK_NULL_RETURN(pattern, info);
659 auto textFieldLayoutProperty = pattern->GetLayoutProperty<TextFieldLayoutProperty>();
660 CHECK_NULL_RETURN(textFieldLayoutProperty, info);
661 if (info.IsSvg() && textFieldLayoutProperty->HasIconColor()) {
662 info.SetFillColor(iconColor_);
663 CHECK_NULL_RETURN(cleanNode_, info);
664 auto imageNode = cleanNode_->GetFirstChild();
665 CHECK_NULL_RETURN(imageNode, info);
666 auto imageFrameNode = AceType::DynamicCast<FrameNode>(imageNode);
667 CHECK_NULL_RETURN(imageFrameNode, info);
668 auto imageRenderProperty = imageFrameNode->GetPaintProperty<ImageRenderProperty>();
669 CHECK_NULL_RETURN(imageRenderProperty, info);
670 imageRenderProperty->UpdateSvgFillColor(iconColor_);
671 }
672 return info;
673 }
674 } // namespace OHOS::Ace::NG