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