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