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