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 "frameworks/bridge/declarative_frontend/engine/functions/js_gesture_judge_function.h"
17
18 #include "base/memory/ace_type.h"
19 #include "base/utils/utils.h"
20 #include "bridge/declarative_frontend/engine/functions/js_should_built_in_recognizer_parallel_with_function.h"
21 #include "core/components/common/layout/constants.h"
22 #include "core/components_ng/gestures/base_gesture_event.h"
23
24 namespace OHOS::Ace::Framework {
25
Execute(const RefPtr<NG::GestureInfo> & gestureInfo,const std::shared_ptr<BaseGestureEvent> & info)26 GestureJudgeResult JsGestureJudgeFunction::Execute(
27 const RefPtr<NG::GestureInfo>& gestureInfo, const std::shared_ptr<BaseGestureEvent>& info)
28 {
29 JSRef<JSObject> gestureInfoObj = JSRef<JSObject>::New();
30 CHECK_NULL_RETURN(gestureInfo, GestureJudgeResult::CONTINUE);
31 CHECK_NULL_RETURN(info, GestureJudgeResult::CONTINUE);
32 if (gestureInfo->GetTag().has_value()) {
33 gestureInfoObj->SetProperty<std::string>("tag", gestureInfo->GetTag().value());
34 }
35 gestureInfoObj->SetProperty<int32_t>("type", static_cast<int32_t>(gestureInfo->GetType()));
36 gestureInfoObj->SetProperty<bool>("isSystemGesture", gestureInfo->IsSystemGesture());
37 auto obj = CreateGestureEventObject(info, gestureInfo->GetType());
38 int32_t paramCount = 2;
39 JSRef<JSVal> params[paramCount];
40 params[0] = gestureInfoObj;
41 params[1] = obj;
42 auto jsValue = JsFunction::ExecuteJS(paramCount, params);
43 auto returnValue = GestureJudgeResult::CONTINUE;
44 if (jsValue->IsNumber()) {
45 returnValue = static_cast<GestureJudgeResult>(jsValue->ToNumber<int32_t>());
46 }
47 return returnValue;
48 }
49
Execute(const std::shared_ptr<BaseGestureEvent> & info,const RefPtr<NG::NGGestureRecognizer> & current,const std::list<RefPtr<NG::NGGestureRecognizer>> & others)50 GestureJudgeResult JsGestureJudgeFunction::Execute(const std::shared_ptr<BaseGestureEvent>& info,
51 const RefPtr<NG::NGGestureRecognizer>& current, const std::list<RefPtr<NG::NGGestureRecognizer>>& others)
52 {
53 CHECK_NULL_RETURN(info, GestureJudgeResult::CONTINUE);
54 auto gestureInfo = current->GetGestureInfo();
55 CHECK_NULL_RETURN(gestureInfo, GestureJudgeResult::CONTINUE);
56 auto obj = CreateGestureEventObject(info, gestureInfo->GetRecognizerType());
57 int32_t paramCount = 3;
58 JSRef<JSVal> params[paramCount];
59 params[0] = obj;
60 auto currentObj = JsShouldBuiltInRecognizerParallelWithFunction::CreateRecognizerObject(current);
61 params[1] = currentObj;
62 JSRef<JSArray> othersArr = JSRef<JSArray>::New();
63 uint32_t othersIdx = 0;
64 for (const auto& item : others) {
65 auto othersObj = JsShouldBuiltInRecognizerParallelWithFunction::CreateRecognizerObject(item);
66 othersArr->SetValueAt(othersIdx++, othersObj);
67 }
68 params[2] = othersArr;
69 auto jsValue = JsFunction::ExecuteJS(paramCount, params);
70 auto returnValue = GestureJudgeResult::CONTINUE;
71 if (jsValue->IsNumber()) {
72 returnValue = static_cast<GestureJudgeResult>(jsValue->ToNumber<int32_t>());
73 }
74 return returnValue;
75 }
76
CreateFingerInfo(const FingerInfo & fingerInfo)77 JSRef<JSObject> JsGestureJudgeFunction::CreateFingerInfo(const FingerInfo& fingerInfo)
78 {
79 JSRef<JSObject> fingerInfoObj = JSRef<JSObject>::New();
80 const OHOS::Ace::Offset& globalLocation = fingerInfo.globalLocation_;
81 const OHOS::Ace::Offset& localLocation = fingerInfo.localLocation_;
82 const OHOS::Ace::Offset& screenLocation = fingerInfo.screenLocation_;
83 fingerInfoObj->SetProperty<int32_t>("id", fingerInfo.fingerId_);
84 fingerInfoObj->SetProperty<double>("globalX", PipelineBase::Px2VpWithCurrentDensity(globalLocation.GetX()));
85 fingerInfoObj->SetProperty<double>("globalY", PipelineBase::Px2VpWithCurrentDensity(globalLocation.GetY()));
86 fingerInfoObj->SetProperty<double>("localX", PipelineBase::Px2VpWithCurrentDensity(localLocation.GetX()));
87 fingerInfoObj->SetProperty<double>("localY", PipelineBase::Px2VpWithCurrentDensity(localLocation.GetY()));
88 fingerInfoObj->SetProperty<double>("displayX", PipelineBase::Px2VpWithCurrentDensity(screenLocation.GetX()));
89 fingerInfoObj->SetProperty<double>("displayY", PipelineBase::Px2VpWithCurrentDensity(screenLocation.GetY()));
90 return fingerInfoObj;
91 }
92
CreateEventTargetObject(const std::shared_ptr<BaseGestureEvent> & info)93 JSRef<JSObject> JsGestureJudgeFunction::CreateEventTargetObject(const std::shared_ptr<BaseGestureEvent>& info)
94 {
95 JSRef<JSObjTemplate> objectTemplate = JSRef<JSObjTemplate>::New();
96 JSRef<JSObject> target = objectTemplate->NewInstance();
97 JSRef<JSObject> area = objectTemplate->NewInstance();
98 JSRef<JSObject> offset = objectTemplate->NewInstance();
99 JSRef<JSObject> globalOffset = objectTemplate->NewInstance();
100 const auto& localOffset = info->GetTarget().area.GetOffset();
101 const auto& origin = info->GetTarget().origin;
102 offset->SetProperty<double>("x", localOffset.GetX().ConvertToVp());
103 offset->SetProperty<double>("y", localOffset.GetY().ConvertToVp());
104 globalOffset->SetProperty<double>("x", (origin.GetX().ConvertToVp() + localOffset.GetX().ConvertToVp()));
105 globalOffset->SetProperty<double>("y", (origin.GetY().ConvertToVp() + localOffset.GetY().ConvertToVp()));
106 area->SetPropertyObject("position", offset);
107 area->SetPropertyObject("globalPosition", globalOffset);
108 area->SetProperty<double>("width", info->GetTarget().area.GetWidth().ConvertToVp());
109 area->SetProperty<double>("height", info->GetTarget().area.GetHeight().ConvertToVp());
110 target->SetPropertyObject("area", area);
111 return target;
112 }
113
SetUniqueAttributes(JSRef<JSObject> & obj,GestureTypeName typeName,const std::shared_ptr<BaseGestureEvent> & info)114 void JsGestureJudgeFunction::SetUniqueAttributes(
115 JSRef<JSObject>& obj, GestureTypeName typeName, const std::shared_ptr<BaseGestureEvent>& info)
116 {
117 switch (typeName) {
118 case OHOS::Ace::GestureTypeName::LONG_PRESS_GESTURE: {
119 auto longPressGestureEvent = TypeInfoHelper::DynamicCast<LongPressGestureEvent>(info.get());
120 if (longPressGestureEvent) {
121 obj->SetProperty<bool>("repeat", longPressGestureEvent->GetRepeat());
122 }
123 break;
124 }
125 case OHOS::Ace::GestureTypeName::PAN_GESTURE: {
126 auto panGestureEvent = TypeInfoHelper::DynamicCast<PanGestureEvent>(info.get());
127 if (panGestureEvent) {
128 obj->SetProperty<double>(
129 "offsetX", PipelineBase::Px2VpWithCurrentDensity(panGestureEvent->GetOffsetX()));
130 obj->SetProperty<double>(
131 "offsetY", PipelineBase::Px2VpWithCurrentDensity(panGestureEvent->GetOffsetY()));
132 obj->SetProperty<double>(
133 "velocityX", PipelineBase::Px2VpWithCurrentDensity(panGestureEvent->GetVelocity().GetVelocityX()));
134 obj->SetProperty<double>(
135 "velocityY", PipelineBase::Px2VpWithCurrentDensity(panGestureEvent->GetVelocity().GetVelocityY()));
136 obj->SetProperty<double>("velocity",
137 PipelineBase::Px2VpWithCurrentDensity(panGestureEvent->GetVelocity().GetVelocityValue()));
138 }
139 break;
140 }
141 case OHOS::Ace::GestureTypeName::PINCH_GESTURE: {
142 auto pinchGestureEvent = TypeInfoHelper::DynamicCast<PinchGestureEvent>(info.get());
143 if (pinchGestureEvent) {
144 obj->SetProperty<double>("scale", pinchGestureEvent->GetScale());
145 obj->SetProperty<double>(
146 "pinchCenterX", PipelineBase::Px2VpWithCurrentDensity(pinchGestureEvent->GetPinchCenter().GetX()));
147 obj->SetProperty<double>(
148 "pinchCenterY", PipelineBase::Px2VpWithCurrentDensity(pinchGestureEvent->GetPinchCenter().GetY()));
149 }
150 break;
151 }
152 case OHOS::Ace::GestureTypeName::ROTATION_GESTURE: {
153 auto rotationGestureEvent = TypeInfoHelper::DynamicCast<RotationGestureEvent>(info.get());
154 if (rotationGestureEvent) {
155 obj->SetProperty<double>("angle", rotationGestureEvent->GetAngle());
156 }
157 break;
158 }
159 case OHOS::Ace::GestureTypeName::SWIPE_GESTURE: {
160 auto swipeGestureEvent = TypeInfoHelper::DynamicCast<SwipeGestureEvent>(info.get());
161 if (swipeGestureEvent) {
162 obj->SetProperty<double>("angle", swipeGestureEvent->GetAngle());
163 obj->SetProperty<double>("speed", swipeGestureEvent->GetSpeed());
164 }
165 break;
166 }
167 default:
168 break;
169 }
170 }
171
CreateGestureEventObject(const std::shared_ptr<BaseGestureEvent> & info,GestureTypeName typeName)172 JSRef<JSObject> JsGestureJudgeFunction::CreateGestureEventObject(
173 const std::shared_ptr<BaseGestureEvent>& info, GestureTypeName typeName)
174 {
175 JSRef<JSObject> obj = JSRef<JSObject>::New();
176 SetUniqueAttributes(obj, typeName, info);
177 obj->SetProperty<double>("timestamp", info->GetTimeStamp().time_since_epoch().count());
178 obj->SetProperty<double>("source", static_cast<int32_t>(info->GetSourceDevice()));
179 obj->SetProperty<double>("pressure", info->GetForce());
180 obj->SetProperty<double>("tiltX", info->GetTiltX().value_or(0.0f));
181 obj->SetProperty<double>("tiltY", info->GetTiltY().value_or(0.0f));
182 obj->SetProperty<double>("sourceTool", static_cast<int32_t>(info->GetSourceTool()));
183 obj->SetProperty<double>("deviceId", static_cast<int32_t>(info->GetDeviceId()));
184
185 JSRef<JSArray> fingerArr = JSRef<JSArray>::New();
186 const std::list<FingerInfo>& fingerList = info->GetFingerList();
187 std::list<FingerInfo> notTouchFingerList;
188 int32_t maxFingerId = -1;
189 for (const FingerInfo& fingerInfo : fingerList) {
190 JSRef<JSObject> element = CreateFingerInfo(fingerInfo);
191 if (fingerInfo.sourceType_ == SourceType::TOUCH && fingerInfo.sourceTool_ == SourceTool::FINGER) {
192 fingerArr->SetValueAt(fingerInfo.fingerId_, element);
193 if (fingerInfo.fingerId_ > maxFingerId) {
194 maxFingerId = fingerInfo.fingerId_;
195 }
196 } else {
197 notTouchFingerList.emplace_back(fingerInfo);
198 }
199 }
200 auto idx = maxFingerId + 1;
201 for (const FingerInfo& fingerInfo : notTouchFingerList) {
202 JSRef<JSObject> element = CreateFingerInfo(fingerInfo);
203 fingerArr->SetValueAt(idx++, element);
204 }
205 obj->SetPropertyObject("fingerList", fingerArr);
206 auto target = CreateEventTargetObject(info);
207 obj->SetPropertyObject("target", target);
208 return obj;
209 }
210 } // namespace OHOS::Ace::Framework
211