1 /*
2  * Copyright (c) 2022 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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_FIELD_TEXT_FIELD_MANAGER_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_FIELD_TEXT_FIELD_MANAGER_H
18 
19 #include "base/geometry/offset.h"
20 #include "base/memory/ace_type.h"
21 #include "base/utils/macros.h"
22 #include "core/common/ime/text_input_type.h"
23 #include "core/common/manager_interface.h"
24 #include "core/components_ng/pattern/pattern.h"
25 #include "core/components_ng/pattern/text_field/text_content_type.h"
26 #include "core/components_ng/property/safe_area_insets.h"
27 
28 namespace OHOS::Ace::NG {
29 
30 struct TextFieldInfo {
31     int32_t nodeId = -1;
32     TextInputType inputType;
33     TextContentType contentType;
34     int32_t autoFillContainerNodeId = -1;
35     bool enableAutoFill = true;
36 };
37 
38 class ACE_EXPORT TextFieldManagerNG : public ManagerInterface {
39     DECLARE_ACE_TYPE(TextFieldManagerNG, ManagerInterface);
40 
41 public:
42     TextFieldManagerNG() = default;
43     ~TextFieldManagerNG() override;
44 
45     void SetClickPosition(const Offset& position) override;
46 
GetClickPosition()47     const Offset& GetClickPosition() override
48     {
49         return position_;
50     }
51 
GetOptionalClickPosition()52     const std::optional<Offset>& GetOptionalClickPosition()
53     {
54         return optionalPosition_;
55     }
56 
ResetOptionalClickPosition()57     void ResetOptionalClickPosition() {
58         optionalPosition_ = std::nullopt;
59     }
60 
61     RectF GetFocusedNodeCaretRect();
62 
63     void TriggerAvoidOnCaretChange();
64 
65     void AvoidKeyboardInSheet(const RefPtr<FrameNode>& textField);
66 
MovePage(int32_t pageId,const Offset & rootRect,double offsetHeight)67     void MovePage(int32_t pageId, const Offset& rootRect, double offsetHeight) override {}
RemovePageId(int32_t pageId)68     void RemovePageId(int32_t pageId) override {}
69 
GetOnFocusTextField()70     WeakPtr<Pattern>& GetOnFocusTextField()
71     {
72         return onFocusTextField_;
73     }
74 
SetOnFocusTextField(const WeakPtr<Pattern> & onFocusTextField)75     void SetOnFocusTextField(const WeakPtr<Pattern>& onFocusTextField)
76     {
77         const auto& pattern = onFocusTextField.Upgrade();
78         if (pattern && pattern->GetHost()) {
79             onFocusTextFieldId = pattern->GetHost()->GetId();
80         }
81         if (onFocusTextField_ != onFocusTextField) {
82             SetImeAttached(false);
83             GetOnFocusTextFieldInfo(onFocusTextField);
84         }
85         onFocusTextField_ = onFocusTextField;
86     }
87 
88     void GetOnFocusTextFieldInfo(const WeakPtr<Pattern>& onFocusTextField);
89 
IsScrollableChild()90     bool IsScrollableChild()
91     {
92         return isScrollableChild_;
93     }
94 
95     bool ScrollTextFieldToSafeArea();
96 
97     void ClearOnFocusTextField();
98 
99     void ClearOnFocusTextField(int32_t id);
100 
101     bool ResetSlidingPanelParentHeight();
102 
103     bool UpdatePanelForVirtualKeyboard(double offsetY, double fullHeight);
104     void SetHeight(float height);
105 
GetHeight()106     float GetHeight() const
107     {
108         return height_;
109     }
110 
111     bool OnBackPressed();
112 
113     void UpdateScrollableParentViewPort(const RefPtr<FrameNode>& node);
114 
GetImeShow()115     bool GetImeShow() const override
116     {
117         if (!imeShow_ && imeAttachCalled_) {
118             TAG_LOGI(ACE_KEYBOARD, "imeNotShown but attach called, still consider that as shown");
119         }
120         return imeShow_ || imeAttachCalled_;
121     }
122 
SetImeShow(bool imeShow)123     void SetImeShow(bool imeShow)
124     {
125         imeShow_ = imeShow;
126         imeAttachCalled_ = false;
127     }
128 
SetImeAttached(bool imeAttached)129     void SetImeAttached(bool imeAttached)
130     {
131         imeAttachCalled_ = imeAttached;
132     }
133 
UsingCustomKeyboardAvoid()134     bool UsingCustomKeyboardAvoid() {
135         return usingCustomKeyboardAvoid_;
136     }
137 
138     void TriggerCustomKeyboardAvoid();
139 
SetUsingCustomKeyboardAvoid(bool usingCustomKeyboardAvoid)140     void SetUsingCustomKeyboardAvoid(bool usingCustomKeyboardAvoid) {
141         usingCustomKeyboardAvoid_ = usingCustomKeyboardAvoid;
142     }
143 
SetUIExtensionImeShow(bool imeShow)144     void SetUIExtensionImeShow(bool imeShow) override
145     {
146         uiExtensionImeShow_ = imeShow;
147     }
148 
PrevHasTextFieldPattern()149     bool PrevHasTextFieldPattern() const
150     {
151         return prevHasTextFieldPattern_;
152     }
153 
UpdatePrevHasTextFieldPattern()154     void UpdatePrevHasTextFieldPattern()
155     {
156         if (onFocusTextField_.Upgrade()) {
157             prevHasTextFieldPattern_ = true;
158         } else {
159             prevHasTextFieldPattern_ = false;
160         }
161     }
162 
163     void AvoidKeyBoardInNavigation();
164 
165     void SetNavContentAvoidKeyboardOffset(RefPtr<FrameNode> navNode, float avoidKeyboardOffset);
166 
SetNeedToRequestKeyboard(bool val)167     void SetNeedToRequestKeyboard(bool val) override
168     {
169         needToRequestKeyboard_ = val;
170     }
171 
GetNeedToRequestKeyboard()172     bool GetNeedToRequestKeyboard() override
173     {
174         return needToRequestKeyboard_;
175     }
176 
GetIfFocusTextFieldIsInline()177     bool GetIfFocusTextFieldIsInline() {
178         return focusFieldIsInline;
179     }
180 
SetIfFocusTextFieldIsInline(bool isinline)181     void SetIfFocusTextFieldIsInline(bool isinline) {
182         focusFieldIsInline = isinline;
183     }
184 
GetInlineTextFieldAvoidPositionYAndHeight(double & positionY,double & height)185     void GetInlineTextFieldAvoidPositionYAndHeight(double& positionY, double& height) {
186         positionY = inlinePositionY_;
187         height = inlineHeight_;
188     }
189 
SetInlineTextFieldAvoidPositionYAndHeight(double positionY,double height)190     void SetInlineTextFieldAvoidPositionYAndHeight(double positionY, double height) {
191         inlinePositionY_ = positionY;
192         inlineHeight_ = height;
193     }
194 
SetLastAvoidFieldId(int32_t lastAvoidFieldId)195     void SetLastAvoidFieldId(int32_t lastAvoidFieldId) {
196         lastAvoidFieldId_ = lastAvoidFieldId;
197     }
198 
GetLastAvoidFieldId()199     int32_t GetLastAvoidFieldId() {
200         return lastAvoidFieldId_;
201     }
202 
GetOnFocusTextFieldId()203     int32_t GetOnFocusTextFieldId() {
204         return onFocusTextFieldId;
205     }
206 
GetLaterAvoid()207     bool GetLaterAvoid() const
208     {
209         return laterAvoid_;
210     }
211 
SetLaterAvoid(bool laterAvoid)212     void SetLaterAvoid(bool laterAvoid)
213     {
214         laterAvoid_ = laterAvoid;
215     }
216 
SetLaterAvoidArgs(Rect keyboardArea,double positionY,double height,int32_t orientation)217     void SetLaterAvoidArgs(Rect keyboardArea, double positionY, double height, int32_t orientation)
218     {
219         laterAvoid_ = true;
220         laterAvoidKeyboardArea_ = keyboardArea;
221         laterAvoidPositionY_ = positionY;
222         laterAvoidHeight_ = height;
223         laterOrientation_ = orientation;
224     }
225 
GetLaterAvoidKeyboardRect()226     Rect GetLaterAvoidKeyboardRect()
227     {
228         return laterAvoidKeyboardArea_;
229     }
230 
GetLaterAvoidPositionY()231     double GetLaterAvoidPositionY()
232     {
233         return laterAvoidPositionY_;
234     }
235 
GetLaterAvoidHeight()236     double GetLaterAvoidHeight()
237     {
238         return laterAvoidHeight_;
239     }
240 
GetLaterOrientation()241     int32_t GetLaterOrientation()
242     {
243         return laterOrientation_;
244     }
245 
SetLastRequestKeyboardId(int32_t lastRequestKeyboardId)246     void SetLastRequestKeyboardId(int32_t lastRequestKeyboardId) {
247         lastRequestKeyboardId_ = lastRequestKeyboardId;
248     }
249 
GetLastRequestKeyboardId()250     int32_t GetLastRequestKeyboardId() {
251         return lastRequestKeyboardId_;
252     }
253 
SetClickPositionOffset(float clickPositionOffset)254     void SetClickPositionOffset(float clickPositionOffset)
255     {
256         clickPositionOffset_ = clickPositionOffset;
257     }
258 
GetClickPositionOffset()259     float GetClickPositionOffset()
260     {
261         return clickPositionOffset_;
262     }
263 
264     RefPtr<FrameNode> FindScrollableOfFocusedTextField(const RefPtr<FrameNode>& textField);
265     void AddTextFieldInfo(const TextFieldInfo& textFieldInfo);
266     void RemoveTextFieldInfo(const int32_t& autoFillContainerNodeId, const int32_t& nodeId);
267     void UpdateTextFieldInfo(const TextFieldInfo& textFieldInfo);
268     bool HasAutoFillPasswordNodeInContainer(const int32_t& autoFillContainerNodeId, const int32_t& nodeId);
269 
SetIsImeAttached(bool isImeAttached)270     void SetIsImeAttached(bool isImeAttached)
271     {
272         isImeAttached_ = isImeAttached;
273     }
274 
GetIsImeAttached()275     bool GetIsImeAttached() const override
276     {
277         return isImeAttached_;
278     }
279 
280 private:
281     bool ScrollToSafeAreaHelper(const SafeAreaInsets::Inset& bottomInset, bool isShowKeyboard);
282     RefPtr<FrameNode> FindNavNode(const RefPtr<FrameNode>& textField);
283     bool IsAutoFillPasswordType(const TextFieldInfo& textFieldInfo);
284 
285     bool focusFieldIsInline = false;
286     double inlinePositionY_ = 0.0f;
287     double inlineHeight_ = 0.0f;
288     bool hasMove_ = false;
289     bool imeShow_ = false;
290     bool usingCustomKeyboardAvoid_ = false;
291     bool uiExtensionImeShow_ = false;
292     bool prevHasTextFieldPattern_ = true;
293     Offset position_;
294     float clickPositionOffset_ = 0.0f;
295     std::optional<Offset> optionalPosition_;
296     float height_ = 0.0f;
297     WeakPtr<Pattern> onFocusTextField_;
298     WeakPtr<FrameNode> weakNavNode_;
299     int32_t onFocusTextFieldId = -1;
300     int32_t lastAvoidFieldId_ = -1;
301     int32_t lastRequestKeyboardId_ = -1;
302     bool imeAttachCalled_ = false;
303     bool needToRequestKeyboard_ = true;
304     std::unordered_map<int32_t, std::unordered_map<int32_t, TextFieldInfo>> textFieldInfoMap_;
305     bool laterAvoid_ = false;
306     Rect laterAvoidKeyboardArea_;
307     double laterAvoidPositionY_ = 0.0;
308     double laterAvoidHeight_ = 0.0;
309     int32_t laterOrientation_ = -1;
310     bool isImeAttached_ = false;
311     bool isScrollableChild_ = false;
312     float lastKeyboardOffset_ = 0.0f;
313 };
314 
315 } // namespace OHOS::Ace::NG
316 
317 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_TEXT_FIELD_TEXT_FIELD_MANAGER_H
318