1 /*
2  * Copyright (c) 2023-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/search/search_text_field.h"
17 
18 #include "core/components_ng/pattern/search/search_event_hub.h"
19 
20 namespace OHOS::Ace::NG {
21 
22 namespace {
23 constexpr float MAX_FONT_SCALE = 2.0f;
24 } // namespace
25 
GetFocusHub() const26 RefPtr<FocusHub> SearchTextFieldPattern::GetFocusHub() const
27 {
28     auto host = GetHost();
29     CHECK_NULL_RETURN(host, TextFieldPattern::GetFocusHub());
30     auto parentFrameNode = AceType::DynamicCast<FrameNode>(host->GetParent());
31     CHECK_NULL_RETURN(parentFrameNode, TextFieldPattern::GetFocusHub());
32     return parentFrameNode->GetOrCreateFocusHub();
33 }
34 
PerformAction(TextInputAction action,bool forceCloseKeyboard)35 void SearchTextFieldPattern::PerformAction(TextInputAction action, bool forceCloseKeyboard)
36 {
37     TAG_LOGI(AceLogTag::ACE_TEXT_FIELD, "Search PerformAction %{public}d", static_cast<int32_t>(action));
38     auto host = GetHost();
39     CHECK_NULL_VOID(host);
40     auto parentFrameNode = AceType::DynamicCast<FrameNode>(host->GetParent());
41     auto eventHub = parentFrameNode->GetEventHub<SearchEventHub>();
42     CHECK_NULL_VOID(eventHub);
43     // Enter key type callback
44     TextFieldCommonEvent event;
45     eventHub->FireOnSubmit(GetTextValue(), event);
46     // If the developer wants to keep editing, editing will not stop
47     if (event.IsKeepEditable() || action == TextInputAction::NEW_LINE) {
48         return;
49     }
50     CloseKeyboard(forceCloseKeyboard);
51     FocusHub::LostFocusToViewRoot();
52 }
53 
GetDefaultTextInputAction() const54 TextInputAction SearchTextFieldPattern::GetDefaultTextInputAction() const
55 {
56     return TextInputAction::SEARCH;
57 }
58 
InitDragEvent()59 void SearchTextFieldPattern::InitDragEvent()
60 {
61     auto host = GetHost();
62     CHECK_NULL_VOID(host);
63     host->SetDraggable(true);
64     TextFieldPattern::InitDragEvent();
65 }
66 
ApplyNormalTheme()67 void SearchTextFieldPattern::ApplyNormalTheme()
68 {
69     auto host = GetHost();
70     CHECK_NULL_VOID(host);
71     auto renderContext = host->GetRenderContext();
72     CHECK_NULL_VOID(renderContext);
73     auto textFieldTheme = GetTheme();
74     CHECK_NULL_VOID(textFieldTheme);
75     if (!renderContext->HasBackgroundColor()) {
76         renderContext->UpdateBackgroundColor(textFieldTheme->GetBgColor());
77     }
78 }
79 
IsTextEditableForStylus() const80 bool SearchTextFieldPattern::IsTextEditableForStylus() const
81 {
82     auto host = GetHost();
83     CHECK_NULL_RETURN(host, false);
84     auto parentFrameNode = AceType::DynamicCast<FrameNode>(host->GetParent());
85     CHECK_NULL_RETURN(parentFrameNode, false);
86     auto focusHub = parentFrameNode->GetFocusHub();
87     CHECK_NULL_RETURN(focusHub, false);
88     if (!focusHub->IsFocusable() || !parentFrameNode->IsVisible()) {
89         return false;
90     }
91     auto renderContext = parentFrameNode->GetRenderContext();
92     CHECK_NULL_RETURN(renderContext, false);
93     auto opacity = renderContext->GetOpacity();
94     // if opacity is 0.0f, no need to hit frameNode.
95     if (NearZero(opacity.value_or(1.0f))) {
96         return false;
97     }
98     return true;
99 }
100 
ProcessSelection()101 void SearchTextFieldPattern::ProcessSelection()
102 {
103     auto textWidth = static_cast<int32_t>(contentController_->GetWideText().length());
104     if (SelectOverlayIsOn()) {
105         needToRefreshSelectOverlay_ = textWidth > 0;
106         UpdateSelection(std::clamp(selectController_->GetStartIndex(), 0, textWidth),
107             std::clamp(selectController_->GetEndIndex(), 0, textWidth));
108         SetIsSingleHandle(!IsSelected());
109         if (isTextChangedAtCreation_ && textWidth == 0) {
110             CloseSelectOverlay();
111             StartTwinkling();
112         }
113     } else if (HasFocus() && !IsSelected() && !searchRequestStopTwinkling_) {
114         StartTwinkling();
115     } else {
116         needToRefreshSelectOverlay_ = false;
117     }
118 }
119 
SearchRequestStartTwinkling()120 void SearchTextFieldPattern::SearchRequestStartTwinkling()
121 {
122     searchRequestStopTwinkling_ = false;
123     StartTwinkling();
124 }
125 
SearchRequestStopTwinkling()126 void SearchTextFieldPattern::SearchRequestStopTwinkling()
127 {
128     searchRequestStopTwinkling_ = true;
129     UpdateSelection(0);
130     StopTwinkling();
131 }
132 
ResetSearchRequestStopTwinkling()133 void SearchTextFieldPattern::ResetSearchRequestStopTwinkling()
134 {
135     searchRequestStopTwinkling_ = false;
136 }
137 
IsNeedProcessAutoFill()138 bool SearchTextFieldPattern::IsNeedProcessAutoFill()
139 {
140     return false;
141 }
142 
GetRequestKeyboardId()143 int32_t SearchTextFieldPattern::GetRequestKeyboardId()
144 {
145     auto host = GetHost();
146     CHECK_NULL_RETURN(host, -1);
147     auto searchHost = host->GetAncestorNodeOfFrame();
148     CHECK_NULL_RETURN(searchHost, -1);
149     return searchHost->GetId();
150 }
151 
FontSizeConvertToPx(const Dimension & fontSize)152 float SearchTextFieldPattern::FontSizeConvertToPx(const Dimension& fontSize)
153 {
154     if (fontSize.Unit() == DimensionUnit::FP) {
155         return fontSize.ConvertToPxDistribute(0, MAX_FONT_SCALE);
156     } else {
157         return fontSize.ConvertToPx();
158     }
159 }
160 } // namespace OHOS::Ace::NG