• 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/overlay/keyboard_base_pattern.h"
17 
18 #include "base/log/dump_log.h"
19 #include "core/pipeline_ng/pipeline_context.h"
20 
21 namespace OHOS::Ace::NG {
BeforeCreateLayoutWrapper()22 void KeyboardPattern::BeforeCreateLayoutWrapper()
23 {
24     auto host = GetHost();
25     CHECK_NULL_VOID(host);
26     auto child = host->GetChildAtIndex(0);
27     while (child) {
28         // find first framenode, filter SyntaxItem
29         auto childFrameNode = AceType::DynamicCast<FrameNode>(child);
30         if (childFrameNode) {
31             auto layoutProperty = childFrameNode->GetLayoutProperty();
32             if (!layoutProperty) {
33                 break;
34             }
35             // set custom keyboard view width match parent
36             std::optional<CalcLength> height = std::nullopt;
37             auto&& layoutConstraint = layoutProperty->GetCalcLayoutConstraint();
38             if (layoutConstraint != nullptr && layoutConstraint->selfIdealSize) {
39                 height = layoutConstraint->selfIdealSize->Height();
40             }
41             auto dimension = Dimension(1.0f, DimensionUnit::PERCENT);
42             layoutProperty->UpdateUserDefinedIdealSize(CalcSize(CalcLength(dimension), height));
43             if (CheckChildPosition(childFrameNode)) {
44                 host->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_PARENT);
45             }
46             break;
47         }
48         child = child->GetChildAtIndex(0);
49     }
50 }
51 
CheckChildPosition(const RefPtr<FrameNode> & frameNode)52 bool KeyboardPattern::CheckChildPosition(const RefPtr<FrameNode>& frameNode)
53 {
54     CHECK_NULL_RETURN(frameNode, false);
55     auto childRender = frameNode->GetRenderContext();
56     CHECK_NULL_RETURN(childRender, false);
57     return childRender->HasPosition();
58 }
59 
DumpInfo()60 void KeyboardPattern::DumpInfo()
61 {
62     DumpLog::GetInstance().AddDesc(std::string("TargetId: ")
63                                         .append(std::to_string(targetId_)));
64 }
65 
OnModifyDone()66 void KeyboardPattern::OnModifyDone()
67 {
68     auto context = OHOS::Ace::NG::PipelineContext::GetCurrentContext();
69     CHECK_NULL_VOID(context);
70     context->AddOnAreaChangeNode(GetHost()->GetId());
71 }
72 
OnAreaChangedInner()73 void KeyboardPattern::OnAreaChangedInner()
74 {
75     auto host = GetHost();
76     CHECK_NULL_VOID(host);
77     auto customHeight = GetKeyboardHeight();
78     if (NearEqual(customHeight, keyboardHeight_)) {
79         return;
80     }
81     auto boundaryHeight = 0.0f;
82     // Check that the effective height of the keyboard is captured
83     auto pipeline = host->GetContext();
84     CHECK_NULL_VOID(pipeline);
85     if (std::abs(customHeight) > boundaryHeight && supportAvoidance_) {
86         Rect keyboardRect = Rect(0.0f, 0.0f, 0.0f, customHeight);
87         auto safeAreaManager = pipeline->GetSafeAreaManager();
88         if (safeAreaManager) {
89             safeAreaManager->SetKeyboardInfo(customHeight);
90         }
91         TAG_LOGI(ACE_KEYBOARD, "customKeyboardHeight Change to %{public}f, safeHeight: %{public}f",
92             customHeight, safeHeight_);
93         pipeline->OnVirtualKeyboardAreaChange(keyboardRect, nullptr, safeHeight_, supportAvoidance_, true);
94     }
95     keyboardHeight_ = customHeight;
96     auto overlayManager = pipeline->GetOverlayManager();
97     CHECK_NULL_VOID(overlayManager);
98     overlayManager->UpdateCustomKeyboardPosition();
99 }
100 
SetKeyboardAreaChange(bool keyboardAvoidance)101 void KeyboardPattern::SetKeyboardAreaChange(bool keyboardAvoidance)
102 {
103     if (keyboardAvoidance) {
104         auto host = GetHost();
105         CHECK_NULL_VOID(host);
106         auto keyboardHeight = GetKeyboardHeight();
107         auto pipeline = host->GetContext();
108         CHECK_NULL_VOID(pipeline);
109         auto safeAreaManager = pipeline->GetSafeAreaManager();
110         if (safeAreaManager) {
111             safeAreaManager->SetKeyboardInfo(keyboardHeight);
112         }
113         Rect keyboardRect = Rect(0.0f, 0.0f, 0.0f, keyboardHeight);
114         TAG_LOGI(ACE_KEYBOARD, "customKeyboardHeight Change to %{public}f, safeHeight: %{public}f",
115             keyboardHeight, safeHeight_);
116         pipeline->OnVirtualKeyboardAreaChange(keyboardRect, nullptr, safeHeight_, supportAvoidance_, true);
117     }
118 }
119 
GetKeyboardHeight()120 float KeyboardPattern::GetKeyboardHeight()
121 {
122     auto host = GetHost();
123     CHECK_NULL_RETURN(host, 0.0f);
124     auto child = host->GetChildAtIndex(0);
125     while (child) {
126         auto childFrameNode = AceType::DynamicCast<FrameNode>(child);
127         if (!childFrameNode) {
128             child = child->GetChildAtIndex(0);
129             continue;
130         }
131         auto hostRect = host->GetTransformRectRelativeToWindow();
132         if (!CheckChildPosition(childFrameNode)) {
133             return hostRect.Height();
134         }
135         auto childRender = childFrameNode->GetRenderContext();
136         CHECK_NULL_RETURN(childRender, false);
137         auto positionY = childRender->GetPositionValue({}).GetY().ConvertToPx();
138         return hostRect.Height() - positionY > 0.0f ? hostRect.Height() - positionY : 0.0f;
139     }
140     return 0.0f;
141 }
142 
OnDetachFromFrameNode(FrameNode * node)143 void KeyboardPattern::OnDetachFromFrameNode(FrameNode* node)
144 {
145     auto pipeline = PipelineContext::GetCurrentContext();
146     CHECK_NULL_VOID(pipeline);
147     pipeline->RemoveOnAreaChangeNode(node->GetId());
148 }
149 
DumpInfo(std::unique_ptr<JsonValue> & json)150 void KeyboardPattern::DumpInfo(std::unique_ptr<JsonValue>& json)
151 {
152     json->Put("TargetId", targetId_);
153 }
154 } // namespace OHOS::Ace::NG