mirror of
https://gitee.com/openharmony/arkui_ace_engine
synced 2024-11-23 07:01:24 +00:00
new framework
Signed-off-by: wangzezhen <wangzezhen@huawei.com> Change-Id: I25253be71a5b63dfc64c4201c2e5bddcd4d1e35e
This commit is contained in:
parent
e48b6ccef3
commit
5510cc38da
@ -20,6 +20,17 @@
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_interactable_view.h"
|
||||
#include "frameworks/bridge/declarative_frontend/view_stack_processor.h"
|
||||
#include "frameworks/core/components/gesture_listener/gesture_component.h"
|
||||
|
||||
#include "frameworks/core/components_ng/gestures/recognizers/exclusive_recognizer.h"
|
||||
#include "frameworks/core/components_ng/gestures/gesture_group.h"
|
||||
#include "frameworks/core/components_ng/gestures/long_press_gesture.h"
|
||||
#include "frameworks/core/components_ng/gestures/pan_gesture.h"
|
||||
#include "frameworks/core/components_ng/gestures/recognizers/parallel_recognizer.h"
|
||||
#include "frameworks/core/components_ng/gestures/pinch_gesture.h"
|
||||
#include "frameworks/core/components_ng/gestures/rotation_gesture.h"
|
||||
#include "frameworks/core/components_ng/gestures/swipe_gesture.h"
|
||||
#include "frameworks/core/components_ng/gestures/tap_gesture.h"
|
||||
|
||||
#include "frameworks/core/gestures/exclusive_recognizer.h"
|
||||
#include "frameworks/core/gestures/gesture_group.h"
|
||||
#include "frameworks/core/gestures/long_press_gesture.h"
|
||||
@ -61,6 +72,13 @@ constexpr char ROTATION_ANGLE[] = "angle";
|
||||
void JSGesture::Create(const JSCallbackInfo& info)
|
||||
{
|
||||
LOGD("JS gesture create");
|
||||
RefPtr<GestureProcessor> gestureProcessor;
|
||||
if (Container::IsCurrentUseNewPipeline()) {
|
||||
gestureProcessor = NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
|
||||
} else {
|
||||
gestureProcessor = ViewStackProcessor::GetInstance()->GetGestureComponent();
|
||||
}
|
||||
|
||||
GesturePriority priority = GesturePriority::Low;
|
||||
if (info.Length() > 0 && info[0]->IsNumber()) {
|
||||
int32_t priorityNum = info[0]->ToNumber<int32_t>();
|
||||
@ -69,14 +87,6 @@ void JSGesture::Create(const JSCallbackInfo& info)
|
||||
priority = static_cast<GesturePriority>(priorityNum);
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<GestureProcessor> gestureProcessor;
|
||||
if (Container::IsCurrentUseNewPipeline()) {
|
||||
gestureProcessor = NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
|
||||
} else {
|
||||
gestureProcessor = ViewStackProcessor::GetInstance()->GetGestureComponent();
|
||||
}
|
||||
|
||||
gestureProcessor->SetPriority(priority);
|
||||
|
||||
GestureMask gestureMask = GestureMask::Normal;
|
||||
@ -97,17 +107,14 @@ void JSGesture::Finish()
|
||||
if (Container::IsCurrentUseNewPipeline()) {
|
||||
gestureProcessor = NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
|
||||
NG::ViewStackProcessor::GetInstance()->ResetGestureProcessor();
|
||||
} else {
|
||||
gestureProcessor = ViewStackProcessor::GetInstance()->GetGestureComponent();
|
||||
};
|
||||
auto gesture = gestureProcessor->FinishGesture();
|
||||
if (!gesture) {
|
||||
LOGE("gesture is not exist when component finish");
|
||||
return;
|
||||
}
|
||||
gesture->SetGestureMask(gestureProcessor->GetGestureMask());
|
||||
gesture->SetPriority(gestureProcessor->GetPriority());
|
||||
if (Container::IsCurrentUseNewPipeline()) {
|
||||
|
||||
auto gesture = gestureProcessor->FinishGestureNG();
|
||||
if (!gesture) {
|
||||
LOGE("gesture is not exist when component finish");
|
||||
return;
|
||||
}
|
||||
gesture->SetGestureMask(gestureProcessor->GetGestureMask());
|
||||
gesture->SetPriority(gestureProcessor->GetPriority());
|
||||
auto gestureEventHub = NG::ViewStackProcessor::GetInstance()->GetMainFrameNodeGestureEventHub();
|
||||
if (gestureEventHub) {
|
||||
gestureEventHub->AddGesture(gesture);
|
||||
@ -115,6 +122,14 @@ void JSGesture::Finish()
|
||||
return;
|
||||
}
|
||||
|
||||
gestureProcessor = ViewStackProcessor::GetInstance()->GetGestureComponent();
|
||||
auto gesture = gestureProcessor->FinishGesture();
|
||||
if (!gesture) {
|
||||
LOGE("gesture is not exist when component finish");
|
||||
return;
|
||||
}
|
||||
gesture->SetGestureMask(gestureProcessor->GetGestureMask());
|
||||
gesture->SetPriority(gestureProcessor->GetPriority());
|
||||
auto boxComponent = ViewStackProcessor::GetInstance()->GetBoxComponent();
|
||||
boxComponent->AddGesture(gestureProcessor->GetPriority(), gesture);
|
||||
}
|
||||
@ -125,14 +140,16 @@ void JSGesture::Pop()
|
||||
RefPtr<GestureProcessor> gestureProcessor;
|
||||
if (Container::IsCurrentUseNewPipeline()) {
|
||||
gestureProcessor = NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
|
||||
gestureProcessor->PopGestureNG();
|
||||
} else {
|
||||
gestureProcessor = ViewStackProcessor::GetInstance()->GetGestureComponent();
|
||||
gestureProcessor->PopGesture();
|
||||
};
|
||||
gestureProcessor->PopGesture();
|
||||
}
|
||||
|
||||
void JSTapGesture::Create(const JSCallbackInfo& args)
|
||||
{
|
||||
LOGD("JSTapGesture Create");
|
||||
int32_t countNum = DEFAULT_TAP_COUNT;
|
||||
int32_t fingersNum = DEFAULT_TAP_FINGER;
|
||||
if (args.Length() > 0 && args[0]->IsObject()) {
|
||||
@ -144,7 +161,6 @@ void JSTapGesture::Create(const JSCallbackInfo& args)
|
||||
int32_t countNumber = count->ToNumber<int32_t>();
|
||||
countNum = countNumber <= DEFAULT_TAP_COUNT ? DEFAULT_TAP_COUNT : countNumber;
|
||||
}
|
||||
|
||||
if (fingers->IsNumber()) {
|
||||
int32_t fingersNumber = fingers->ToNumber<int32_t>();
|
||||
fingersNum = fingersNumber <= DEFAULT_TAP_FINGER ? DEFAULT_TAP_FINGER : fingersNumber;
|
||||
@ -155,17 +171,18 @@ void JSTapGesture::Create(const JSCallbackInfo& args)
|
||||
RefPtr<GestureProcessor> gestureProcessor;
|
||||
if (Container::IsCurrentUseNewPipeline()) {
|
||||
gestureProcessor = NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
|
||||
auto gesture = AceType::MakeRefPtr<NG::TapGesture>(countNum, fingersNum);
|
||||
gestureProcessor->PushGestureNG(gesture);
|
||||
} else {
|
||||
gestureProcessor = ViewStackProcessor::GetInstance()->GetGestureComponent();
|
||||
auto gesture = AceType::MakeRefPtr<TapGesture>(countNum, fingersNum);
|
||||
gestureProcessor->PushGesture(gesture);
|
||||
}
|
||||
auto gesture = AceType::MakeRefPtr<OHOS::Ace::TapGesture>(countNum, fingersNum);
|
||||
gestureProcessor->PushGesture(gesture);
|
||||
}
|
||||
|
||||
void JSLongPressGesture::Create(const JSCallbackInfo& args)
|
||||
{
|
||||
LOGD("JSLongPressGesture Create");
|
||||
|
||||
int32_t fingersNum = DEFAULT_LONG_PRESS_FINGER;
|
||||
bool repeatResult = false;
|
||||
int32_t durationNum = DEFAULT_LONG_PRESS_DURATION;
|
||||
@ -179,11 +196,9 @@ void JSLongPressGesture::Create(const JSCallbackInfo& args)
|
||||
int32_t fingersNumber = fingers->ToNumber<int32_t>();
|
||||
fingersNum = fingersNumber <= DEFAULT_LONG_PRESS_FINGER ? DEFAULT_LONG_PRESS_FINGER : fingersNumber;
|
||||
}
|
||||
|
||||
if (repeat->IsBoolean()) {
|
||||
repeatResult = repeat->ToBoolean();
|
||||
}
|
||||
|
||||
if (duration->IsNumber()) {
|
||||
int32_t durationNumber = duration->ToNumber<int32_t>();
|
||||
durationNum = durationNumber <= 0 ? DEFAULT_LONG_PRESS_DURATION : durationNumber;
|
||||
@ -193,38 +208,53 @@ void JSLongPressGesture::Create(const JSCallbackInfo& args)
|
||||
RefPtr<GestureProcessor> gestureProcessor;
|
||||
if (Container::IsCurrentUseNewPipeline()) {
|
||||
gestureProcessor = NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
|
||||
auto gesture = AceType::MakeRefPtr<NG::LongPressGesture>(fingersNum, repeatResult, durationNum);
|
||||
gestureProcessor->PushGestureNG(gesture);
|
||||
} else {
|
||||
gestureProcessor = ViewStackProcessor::GetInstance()->GetGestureComponent();
|
||||
auto gesture = AceType::MakeRefPtr<LongPressGesture>(fingersNum, repeatResult, durationNum);
|
||||
gestureProcessor->PushGesture(gesture);
|
||||
}
|
||||
auto gesture = AceType::MakeRefPtr<OHOS::Ace::LongPressGesture>(fingersNum, repeatResult, durationNum);
|
||||
gestureProcessor->PushGesture(gesture);
|
||||
}
|
||||
|
||||
void JSPanGesture::Create(const JSCallbackInfo& args)
|
||||
{
|
||||
LOGD("JSPanGesture Create");
|
||||
|
||||
int32_t fingersNum = DEFAULT_PAN_FINGER;
|
||||
double distanceNum = DEFAULT_PAN_DISTANCE;
|
||||
PanDirection panDirection;
|
||||
RefPtr<GestureProcessor> gestureProcessor;
|
||||
if (Container::IsCurrentUseNewPipeline()) {
|
||||
gestureProcessor = NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
|
||||
if (args.Length() <= 0 || !args[0]->IsObject()) {
|
||||
auto gesture = AceType::MakeRefPtr<NG::PanGesture>(fingersNum, panDirection, distanceNum);
|
||||
gestureProcessor->PushGestureNG(gesture);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
gestureProcessor = ViewStackProcessor::GetInstance()->GetGestureComponent();
|
||||
}
|
||||
if (args.Length() <= 0 || !args[0]->IsObject()) {
|
||||
auto gesture = AceType::MakeRefPtr<OHOS::Ace::PanGesture>(fingersNum, panDirection, distanceNum);
|
||||
gestureProcessor->PushGesture(gesture);
|
||||
return;
|
||||
if (args.Length() <= 0 || !args[0]->IsObject()) {
|
||||
auto gesture = AceType::MakeRefPtr<PanGesture>(fingersNum, panDirection, distanceNum);
|
||||
gestureProcessor->PushGesture(gesture);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
|
||||
JSPanGestureOption* panGestureOption = obj->Unwrap<JSPanGestureOption>();
|
||||
if (panGestureOption != nullptr) {
|
||||
auto gesture = AceType::MakeRefPtr<OHOS::Ace::PanGesture>(panGestureOption->GetPanGestureOption());
|
||||
gestureProcessor->PushGesture(gesture);
|
||||
return;
|
||||
|
||||
if (Container::IsCurrentUseNewPipeline()) {
|
||||
if (panGestureOption != nullptr) {
|
||||
auto gesture = AceType::MakeRefPtr<NG::PanGesture>(panGestureOption->GetPanGestureOption());
|
||||
gestureProcessor->PushGestureNG(gesture);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (panGestureOption != nullptr) {
|
||||
auto gesture = AceType::MakeRefPtr<PanGesture>(panGestureOption->GetPanGestureOption());
|
||||
gestureProcessor->PushGesture(gesture);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
JSRef<JSVal> fingers = obj->GetProperty(GESTURE_FINGERS);
|
||||
@ -235,12 +265,10 @@ void JSPanGesture::Create(const JSCallbackInfo& args)
|
||||
int32_t fingersNumber = fingers->ToNumber<int32_t>();
|
||||
fingersNum = fingersNumber <= DEFAULT_PAN_FINGER ? DEFAULT_PAN_FINGER : fingersNumber;
|
||||
}
|
||||
|
||||
if (distance->IsNumber()) {
|
||||
double distanceNumber = distance->ToNumber<double>();
|
||||
distanceNum = LessNotEqual(distanceNumber, 0.0) ? DEFAULT_PAN_DISTANCE : distanceNumber;
|
||||
}
|
||||
|
||||
if (directionNum->IsNumber()) {
|
||||
uint32_t directNum = directionNum->ToNumber<uint32_t>();
|
||||
if (directNum >= static_cast<uint32_t>(PanDirection::NONE) &&
|
||||
@ -248,29 +276,40 @@ void JSPanGesture::Create(const JSCallbackInfo& args)
|
||||
panDirection.type = directNum;
|
||||
}
|
||||
}
|
||||
auto gesture = AceType::MakeRefPtr<OHOS::Ace::PanGesture>(fingersNum, panDirection, distanceNum);
|
||||
gestureProcessor->PushGesture(gesture);
|
||||
|
||||
if (Container::IsCurrentUseNewPipeline()) {
|
||||
auto gesture = AceType::MakeRefPtr<NG::PanGesture>(fingersNum, panDirection, distanceNum);
|
||||
gestureProcessor->PushGestureNG(gesture);
|
||||
} else {
|
||||
auto gesture = AceType::MakeRefPtr<PanGesture>(fingersNum, panDirection, distanceNum);
|
||||
gestureProcessor->PushGesture(gesture);
|
||||
}
|
||||
}
|
||||
|
||||
void JSSwipeGesture::Create(const JSCallbackInfo& args)
|
||||
{
|
||||
LOGD("JSSwipeGesture Create");
|
||||
int32_t fingersNum = DEFAULT_SLIDE_FINGER;
|
||||
double speedNum = DEFAULT_SLIDE_SPEED;
|
||||
SwipeDirection slideDirection;
|
||||
RefPtr<GestureProcessor> gestureProcessor;
|
||||
if (Container::IsCurrentUseNewPipeline()) {
|
||||
gestureProcessor = NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
|
||||
if (args.Length() <= 0 || !args[0]->IsObject()) {
|
||||
auto gesture = AceType::MakeRefPtr<NG::SwipeGesture>(fingersNum, slideDirection, speedNum);
|
||||
gestureProcessor->PushGestureNG(gesture);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
gestureProcessor = ViewStackProcessor::GetInstance()->GetGestureComponent();
|
||||
if (args.Length() <= 0 || !args[0]->IsObject()) {
|
||||
auto gesture = AceType::MakeRefPtr<SwipeGesture>(fingersNum, slideDirection, speedNum);
|
||||
gestureProcessor->PushGesture(gesture);
|
||||
return;
|
||||
}
|
||||
};
|
||||
if (args.Length() <= 0 || !args[0]->IsObject()) {
|
||||
auto gesture = AceType::MakeRefPtr<SwipeGesture>(fingersNum, slideDirection, speedNum);
|
||||
gestureProcessor->PushGesture(gesture);
|
||||
return;
|
||||
}
|
||||
|
||||
JSRef<JSObject> obj = JSRef<JSObject>::Cast(args[0]);
|
||||
|
||||
JSRef<JSVal> fingers = obj->GetProperty(GESTURE_FINGERS);
|
||||
JSRef<JSVal> speed = obj->GetProperty(GESTURE_SPEED);
|
||||
JSRef<JSVal> directionNum = obj->GetProperty(SWIPE_DIRECTION);
|
||||
@ -279,12 +318,10 @@ void JSSwipeGesture::Create(const JSCallbackInfo& args)
|
||||
int32_t fingersNumber = fingers->ToNumber<int32_t>();
|
||||
fingersNum = fingersNumber <= DEFAULT_PAN_FINGER ? DEFAULT_PAN_FINGER : fingersNumber;
|
||||
}
|
||||
|
||||
if (speed->IsNumber()) {
|
||||
double speedNumber = speed->ToNumber<double>();
|
||||
speedNum = LessNotEqual(speedNumber, 0.0) ? DEFAULT_SLIDE_SPEED : speedNumber;
|
||||
}
|
||||
|
||||
if (directionNum->IsNumber()) {
|
||||
uint32_t directNum = directionNum->ToNumber<uint32_t>();
|
||||
if (directNum >= static_cast<uint32_t>(SwipeDirection::NONE) &&
|
||||
@ -292,14 +329,19 @@ void JSSwipeGesture::Create(const JSCallbackInfo& args)
|
||||
slideDirection.type = directNum;
|
||||
}
|
||||
}
|
||||
auto gesture = AceType::MakeRefPtr<SwipeGesture>(fingersNum, slideDirection, speedNum);
|
||||
gestureProcessor->PushGesture(gesture);
|
||||
|
||||
if (Container::IsCurrentUseNewPipeline()) {
|
||||
auto gesture = AceType::MakeRefPtr<NG::SwipeGesture>(fingersNum, slideDirection, speedNum);
|
||||
gestureProcessor->PushGestureNG(gesture);
|
||||
} else {
|
||||
auto gesture = AceType::MakeRefPtr<SwipeGesture>(fingersNum, slideDirection, speedNum);
|
||||
gestureProcessor->PushGesture(gesture);
|
||||
}
|
||||
}
|
||||
|
||||
void JSPinchGesture::Create(const JSCallbackInfo& args)
|
||||
{
|
||||
LOGD("JSPinchGesture Create");
|
||||
|
||||
int32_t fingersNum = DEFAULT_PINCH_FINGER;
|
||||
double distanceNum = DEFAULT_PINCH_DISTANCE;
|
||||
if (args.Length() > 0 && args[0]->IsObject()) {
|
||||
@ -320,17 +362,18 @@ void JSPinchGesture::Create(const JSCallbackInfo& args)
|
||||
RefPtr<GestureProcessor> gestureProcessor;
|
||||
if (Container::IsCurrentUseNewPipeline()) {
|
||||
gestureProcessor = NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
|
||||
auto gesture = AceType::MakeRefPtr<NG::PinchGesture>(fingersNum, distanceNum);
|
||||
gestureProcessor->PushGestureNG(gesture);
|
||||
} else {
|
||||
gestureProcessor = ViewStackProcessor::GetInstance()->GetGestureComponent();
|
||||
auto gesture = AceType::MakeRefPtr<PinchGesture>(fingersNum, distanceNum);
|
||||
gestureProcessor->PushGesture(gesture);
|
||||
};
|
||||
auto gesture = AceType::MakeRefPtr<OHOS::Ace::PinchGesture>(fingersNum, distanceNum);
|
||||
gestureProcessor->PushGesture(gesture);
|
||||
}
|
||||
|
||||
void JSRotationGesture::Create(const JSCallbackInfo& args)
|
||||
{
|
||||
LOGD("JSRotationGesture Create");
|
||||
|
||||
double angleNum = DEFAULT_ROTATION_ANGLE;
|
||||
int32_t fingersNum = DEFAULT_ROTATION_FINGER;
|
||||
if (args.Length() > 0 && args[0]->IsObject()) {
|
||||
@ -342,7 +385,6 @@ void JSRotationGesture::Create(const JSCallbackInfo& args)
|
||||
int32_t fingersNumber = fingers->ToNumber<int32_t>();
|
||||
fingersNum = fingersNumber <= DEFAULT_ROTATION_FINGER ? DEFAULT_ROTATION_FINGER : fingersNumber;
|
||||
}
|
||||
|
||||
if (angle->IsNumber()) {
|
||||
double angleNumber = angle->ToNumber<double>();
|
||||
angleNum = LessNotEqual(angleNumber, 0.0) ? DEFAULT_ROTATION_ANGLE : angleNumber;
|
||||
@ -352,17 +394,18 @@ void JSRotationGesture::Create(const JSCallbackInfo& args)
|
||||
RefPtr<GestureProcessor> gestureProcessor;
|
||||
if (Container::IsCurrentUseNewPipeline()) {
|
||||
gestureProcessor = NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
|
||||
auto gesture = AceType::MakeRefPtr<NG::RotationGesture>(fingersNum, angleNum);
|
||||
gestureProcessor->PushGestureNG(gesture);
|
||||
} else {
|
||||
gestureProcessor = ViewStackProcessor::GetInstance()->GetGestureComponent();
|
||||
auto gesture = AceType::MakeRefPtr<RotationGesture>(fingersNum, angleNum);
|
||||
gestureProcessor->PushGesture(gesture);
|
||||
};
|
||||
auto gesture = AceType::MakeRefPtr<OHOS::Ace::RotationGesture>(fingersNum, angleNum);
|
||||
gestureProcessor->PushGesture(gesture);
|
||||
}
|
||||
|
||||
void JSGestureGroup::Create(const JSCallbackInfo& args)
|
||||
{
|
||||
int32_t gestureMode = 0;
|
||||
|
||||
if (args.Length() > 0 && args[0]->IsNumber()) {
|
||||
gestureMode = args[0]->ToNumber<int32_t>();
|
||||
}
|
||||
@ -371,11 +414,14 @@ void JSGestureGroup::Create(const JSCallbackInfo& args)
|
||||
RefPtr<GestureProcessor> gestureProcessor;
|
||||
if (Container::IsCurrentUseNewPipeline()) {
|
||||
gestureProcessor = NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
|
||||
auto gesture = AceType::MakeRefPtr<NG::GestureGroup>(static_cast<GestureMode>(gestureMode));
|
||||
gestureProcessor->PushGestureNG(gesture);
|
||||
} else {
|
||||
gestureProcessor = ViewStackProcessor::GetInstance()->GetGestureComponent();
|
||||
auto gesture = AceType::MakeRefPtr<GestureGroup>(static_cast<GestureMode>(gestureMode));
|
||||
gestureProcessor->PushGesture(gesture);
|
||||
};
|
||||
auto gesture = AceType::MakeRefPtr<OHOS::Ace::GestureGroup>(static_cast<GestureMode>(gestureMode));
|
||||
gestureProcessor->PushGesture(gesture);
|
||||
|
||||
}
|
||||
|
||||
void JSGesture::JsHandlerOnGestureEvent(JSGestureEvent action, const JSCallbackInfo& args)
|
||||
@ -388,27 +434,65 @@ void JSGesture::JsHandlerOnGestureEvent(JSGestureEvent action, const JSCallbackI
|
||||
RefPtr<GestureProcessor> gestureProcessor;
|
||||
if (Container::IsCurrentUseNewPipeline()) {
|
||||
gestureProcessor = NG::ViewStackProcessor::GetInstance()->GetOrCreateGestureProcessor();
|
||||
} else {
|
||||
gestureProcessor = ViewStackProcessor::GetInstance()->GetGestureComponent();
|
||||
};
|
||||
auto gesture = gestureProcessor->TopGestureNG();
|
||||
if (!gesture) {
|
||||
LOGE("top gesture is illegal");
|
||||
return;
|
||||
}
|
||||
RefPtr<JsGestureFunction> handlerFunc = AceType::MakeRefPtr<JsGestureFunction>(JSRef<JSFunc>::Cast(args[0]));
|
||||
|
||||
if (action == JSGestureEvent::CANCEL) {
|
||||
auto onActionCancelFunc = [execCtx = args.GetExecutionContext(), func = std::move(handlerFunc)]() {
|
||||
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
|
||||
auto info = GestureEvent();
|
||||
ACE_SCORING_EVENT("Gesture.onCancel");
|
||||
func->Execute(info);
|
||||
};
|
||||
gesture->SetOnActionCancelId(onActionCancelFunc);
|
||||
return;
|
||||
}
|
||||
|
||||
auto onActionFunc = [execCtx = args.GetExecutionContext(), func = std::move(handlerFunc)](
|
||||
GestureEvent& info) {
|
||||
JAVASCRIPT_EXECUTION_SCOPE_WITH_CHECK(execCtx);
|
||||
ACE_SCORING_EVENT("Gesture.onActionCancel");
|
||||
func->Execute(info);
|
||||
};
|
||||
|
||||
switch (action) {
|
||||
case JSGestureEvent::ACTION:
|
||||
gesture->SetOnActionId(onActionFunc);
|
||||
break;
|
||||
case JSGestureEvent::START:
|
||||
gesture->SetOnActionStartId(onActionFunc);
|
||||
break;
|
||||
case JSGestureEvent::UPDATE:
|
||||
gesture->SetOnActionUpdateId(onActionFunc);
|
||||
break;
|
||||
case JSGestureEvent::END:
|
||||
gesture->SetOnActionEndId(onActionFunc);
|
||||
break;
|
||||
default:
|
||||
LOGW("Unknown gesture action %{public}d", action);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
gestureProcessor = ViewStackProcessor::GetInstance()->GetGestureComponent();
|
||||
auto gesture = gestureProcessor->TopGesture();
|
||||
if (!gesture) {
|
||||
LOGE("top gesture is illegal");
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<JsGestureFunction> handlerFunc = AceType::MakeRefPtr<JsGestureFunction>(JSRef<JSFunc>::Cast(args[0]));
|
||||
|
||||
RefPtr<V2::InspectorFunctionImpl> impl;
|
||||
|
||||
if (!Container::IsCurrentUseNewPipeline()) {
|
||||
auto inspector = ViewStackProcessor::GetInstance()->GetInspectorComposedComponent();
|
||||
if (!inspector) {
|
||||
LOGE("fail to get inspector for on handle event");
|
||||
return;
|
||||
}
|
||||
impl = inspector->GetInspectorFunctionImpl();
|
||||
auto inspector = ViewStackProcessor::GetInstance()->GetInspectorComposedComponent();
|
||||
if (!inspector) {
|
||||
LOGE("fail to get inspector for on handle event");
|
||||
return;
|
||||
}
|
||||
impl = inspector->GetInspectorFunctionImpl();
|
||||
|
||||
if (action == JSGestureEvent::CANCEL) {
|
||||
auto onActionCancelFunc = [execCtx = args.GetExecutionContext(), func = std::move(handlerFunc), impl]() {
|
||||
@ -534,12 +618,10 @@ void JSPanGestureOption::Constructor(const JSCallbackInfo& args)
|
||||
int32_t fingersNumber = fingers->ToNumber<int32_t>();
|
||||
fingersNum = fingersNumber <= DEFAULT_PAN_FINGER ? DEFAULT_PAN_FINGER : fingersNumber;
|
||||
}
|
||||
|
||||
if (distance->IsNumber()) {
|
||||
double distanceNumber = distance->ToNumber<double>();
|
||||
distanceNum = LessNotEqual(distanceNumber, 0.0) ? DEFAULT_PAN_DISTANCE : distanceNumber;
|
||||
}
|
||||
|
||||
if (directionNum->IsNumber()) {
|
||||
uint32_t directNum = directionNum->ToNumber<uint32_t>();
|
||||
if (directNum >= static_cast<uint32_t>(PanDirection::NONE) &&
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_pan_handler.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_touch_handler.h"
|
||||
#include "frameworks/bridge/declarative_frontend/jsview/js_view_abstract.h"
|
||||
#include "frameworks/core/components_ng/gestures/tap_gesture.h"
|
||||
#include "frameworks/core/gestures/tap_gesture.h"
|
||||
#include "frameworks/core/pipeline/base/component.h"
|
||||
|
||||
|
@ -345,6 +345,7 @@ template("ace_core_source_set") {
|
||||
deps += [
|
||||
"$ace_root/frameworks/core/components_ng/base:ace_core_components_base_ng_$platform",
|
||||
"$ace_root/frameworks/core/components_ng/event:ace_core_components_event_ng_$platform",
|
||||
"$ace_root/frameworks/core/components_ng/gestures:ace_core_components_gestures_ng_$platform",
|
||||
"$ace_root/frameworks/core/components_ng/image_provider:ace_core_components_image_provider_ng_$platform",
|
||||
"$ace_root/frameworks/core/components_ng/layout:ace_core_components_layout_ng_$platform",
|
||||
"$ace_root/frameworks/core/components_ng/manager:ace_core_components_manager_ng_$platform",
|
||||
@ -641,6 +642,7 @@ template("ace_core_ng_source_set") {
|
||||
deps += [
|
||||
"$ace_root/frameworks/core/components_ng/base:ace_core_components_base_ng_$platform",
|
||||
"$ace_root/frameworks/core/components_ng/event:ace_core_components_event_ng_$platform",
|
||||
"$ace_root/frameworks/core/components_ng/gestures:ace_core_components_gestures_ng_$platform",
|
||||
"$ace_root/frameworks/core/components_ng/image_provider:ace_core_components_image_provider_ng_$platform",
|
||||
"$ace_root/frameworks/core/components_ng/layout:ace_core_components_layout_ng_$platform",
|
||||
"$ace_root/frameworks/core/components_ng/manager:ace_core_components_manager_ng_$platform",
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include "base/geometry/ng/point_t.h"
|
||||
#include "base/log/ace_trace.h"
|
||||
#include "base/memory/ace_type.h"
|
||||
#include "base/utils/utils.h"
|
||||
#include "core/components_ng/base/frame_node.h"
|
||||
#include "core/event/key_event.h"
|
||||
@ -68,7 +69,7 @@ void EventManager::TouchTest(const TouchEvent& touchPoint, const RefPtr<NG::Fram
|
||||
return;
|
||||
}
|
||||
// first clean.
|
||||
referee_->CleanGestureScope(touchPoint.id);
|
||||
refereeNG_->CleanGestureScope(touchPoint.id);
|
||||
// collect
|
||||
TouchTestResult hitTestResult;
|
||||
const NG::PointF point { touchPoint.x, touchPoint.y };
|
||||
@ -220,6 +221,7 @@ bool EventManager::DispatchTouchEvent(const TouchEvent& point)
|
||||
|
||||
if (point.type == TouchType::UP || point.type == TouchType::CANCEL) {
|
||||
referee_->CleanGestureScope(point.id);
|
||||
refereeNG_->CleanGestureScope(point.id);
|
||||
touchTestResults_.erase(point.id);
|
||||
}
|
||||
|
||||
@ -539,6 +541,7 @@ EventManager::EventManager()
|
||||
{
|
||||
LOGI("EventManger Constructor.");
|
||||
referee_ = AceType::MakeRefPtr<GestureReferee>();
|
||||
refereeNG_ = AceType::MakeRefPtr<NG::GestureReferee>();
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "base/memory/ace_type.h"
|
||||
#include "base/memory/referenced.h"
|
||||
#include "core/components_ng/gestures/gesture_referee.h"
|
||||
#include "core/event/axis_event.h"
|
||||
#include "core/event/key_event.h"
|
||||
#include "core/event/mouse_event.h"
|
||||
@ -129,6 +130,11 @@ public:
|
||||
return referee_;
|
||||
}
|
||||
|
||||
RefPtr<NG::GestureReferee> GetGestureRefereeNG()
|
||||
{
|
||||
return refereeNG_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_map<size_t, TouchTestResult> touchTestResults_;
|
||||
std::unordered_map<size_t, MouseTestResult> mouseTestResults_;
|
||||
@ -146,6 +152,7 @@ private:
|
||||
int32_t instanceId_ = 0;
|
||||
bool inSelectedRect_ = false;
|
||||
RefPtr<GestureReferee> referee_;
|
||||
RefPtr<NG::GestureReferee> refereeNG_;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
@ -538,7 +538,7 @@ HitTestResult FrameNode::TouchTest(const PointF& globalPoint, const PointF& pare
|
||||
const TouchRestrict& touchRestrict, TouchTestResult& result)
|
||||
{
|
||||
const auto& rect = geometryNode_->GetFrame().GetRect();
|
||||
LOGI("TouchTest: type is %{public}s, the region is %{public}s", GetTag().c_str(), rect.ToString().c_str());
|
||||
LOGD("TouchTest: type is %{public}s, the region is %{public}s", GetTag().c_str(), rect.ToString().c_str());
|
||||
|
||||
if (!rect.IsInRegion(parentLocalPoint)) {
|
||||
return HitTestResult::OUT_OF_REGION;
|
||||
@ -577,6 +577,11 @@ HitTestResult FrameNode::TouchTest(const PointF& globalPoint, const PointF& pare
|
||||
}
|
||||
}
|
||||
result.splice(result.end(), std::move(newComingTargets));
|
||||
auto gestureHub = eventHub_->GetGestureEventHub();
|
||||
if (gestureHub) {
|
||||
gestureHub->CombineIntoExclusiveRecognizer(globalPoint, localPoint, result);
|
||||
}
|
||||
|
||||
if (preventBubbling) {
|
||||
return HitTestResult::STOP_BUBBLING;
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include "base/utils/utils.h"
|
||||
#include "core/components_ng/base/frame_node.h"
|
||||
#include "core/components_ng/event/gesture_event_hub.h"
|
||||
#include "core/gestures/click_recognizer.h"
|
||||
#include "core/components_ng/gestures/recognizers/click_recognizer.h"
|
||||
#include "core/pipeline_ng/pipeline_context.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
@ -38,7 +38,7 @@ void ClickEventActuator::OnCollectTouchTarget(const OffsetF& coordinateOffset, c
|
||||
auto frameNode = gestureHub->GetFrameNode();
|
||||
CHECK_NULL_VOID(frameNode);
|
||||
|
||||
auto clickRecognizer = MakeRefPtr<ClickRecognizer>(frameNode->GetContext());
|
||||
auto clickRecognizer = MakeRefPtr<ClickRecognizer>();
|
||||
auto callback = [weak = WeakClaim(this)](GestureEvent& info) {
|
||||
auto actuator = weak.Upgrade();
|
||||
CHECK_NULL_VOID(actuator);
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include "core/components_ng/base/geometry_node.h"
|
||||
#include "core/components_ng/event/gesture_event_hub.h"
|
||||
#include "core/event/ace_event_handler.h"
|
||||
#include "core/gestures/click_recognizer.h"
|
||||
#include "core/pipeline_ng/pipeline_context.h"
|
||||
#include "core/pipeline_ng/ui_task_scheduler.h"
|
||||
|
||||
|
@ -18,12 +18,12 @@
|
||||
|
||||
#include "core/components_ng/base/geometry_node.h"
|
||||
#include "core/event/key_event.h"
|
||||
#include "core/gestures/gesture_info.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
class FrameNode;
|
||||
class FocusHub;
|
||||
class ClickInfo;
|
||||
class EventHub;
|
||||
|
||||
using TabIndexNodeList = std::list<std::pair<int32_t, WeakPtr<FocusHub>>>;
|
||||
|
@ -15,10 +15,11 @@
|
||||
|
||||
#include "core/components_ng/event/gesture_event_hub.h"
|
||||
|
||||
#include "base/memory/ace_type.h"
|
||||
#include "core/components_ng/base/frame_node.h"
|
||||
#include "core/components_ng/event/event_hub.h"
|
||||
#include "core/gestures/exclusive_recognizer.h"
|
||||
#include "core/gestures/parallel_recognizer.h"
|
||||
#include "core/components_ng/gestures/recognizers/exclusive_recognizer.h"
|
||||
#include "core/components_ng/gestures/recognizers/parallel_recognizer.h"
|
||||
#include "core/pipeline_ng/pipeline_context.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
@ -34,28 +35,7 @@ RefPtr<FrameNode> GestureEventHub::GetFrameNode() const
|
||||
bool GestureEventHub::ProcessTouchTestHit(const OffsetF& coordinateOffset, const TouchRestrict& touchRestrict,
|
||||
TouchTestResult& innerTargets, TouchTestResult& finalResult)
|
||||
{
|
||||
auto eventHub = eventHub_.Upgrade();
|
||||
auto getEventTargetImpl = eventHub ? eventHub->CreateGetEventTargetImpl() : nullptr;
|
||||
|
||||
if (scrollableActuator_) {
|
||||
// TODO: need to change scrollable to be gesture recognizer to make gesture referee works.
|
||||
scrollableActuator_->OnCollectTouchTarget(coordinateOffset, touchRestrict, getEventTargetImpl, innerTargets);
|
||||
}
|
||||
|
||||
if (touchEventActuator_) {
|
||||
touchEventActuator_->OnCollectTouchTarget(coordinateOffset, touchRestrict, getEventTargetImpl, innerTargets);
|
||||
}
|
||||
|
||||
if (clickEventActuator_) {
|
||||
clickEventActuator_->OnCollectTouchTarget(coordinateOffset, touchRestrict, getEventTargetImpl, innerTargets);
|
||||
}
|
||||
|
||||
if (panEventActuator_) {
|
||||
panEventActuator_->OnCollectTouchTarget(coordinateOffset, touchRestrict, getEventTargetImpl, innerTargets);
|
||||
}
|
||||
|
||||
std::list<RefPtr<GestureRecognizer>> innerRecognizers;
|
||||
|
||||
for (auto const& eventTarget : innerTargets) {
|
||||
auto recognizer = AceType::DynamicCast<GestureRecognizer>(eventTarget);
|
||||
if (recognizer) {
|
||||
@ -64,9 +44,24 @@ bool GestureEventHub::ProcessTouchTestHit(const OffsetF& coordinateOffset, const
|
||||
finalResult.push_back(eventTarget);
|
||||
}
|
||||
}
|
||||
|
||||
ProcessTouchTestHierarchy(coordinateOffset, touchRestrict, innerRecognizers, finalResult);
|
||||
|
||||
auto eventHub = eventHub_.Upgrade();
|
||||
auto getEventTargetImpl = eventHub ? eventHub->CreateGetEventTargetImpl() : nullptr;
|
||||
if (scrollableActuator_) {
|
||||
// TODO: need to change scrollable to be gesture recognizer to make gesture referee works.
|
||||
scrollableActuator_->OnCollectTouchTarget(coordinateOffset, touchRestrict, getEventTargetImpl, finalResult);
|
||||
}
|
||||
if (touchEventActuator_) {
|
||||
touchEventActuator_->OnCollectTouchTarget(coordinateOffset, touchRestrict, getEventTargetImpl, finalResult);
|
||||
}
|
||||
if (clickEventActuator_) {
|
||||
clickEventActuator_->OnCollectTouchTarget(coordinateOffset, touchRestrict, getEventTargetImpl, finalResult);
|
||||
}
|
||||
if (panEventActuator_) {
|
||||
panEventActuator_->OnCollectTouchTarget(coordinateOffset, touchRestrict, getEventTargetImpl, finalResult);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -89,8 +84,11 @@ void GestureEventHub::ProcessTouchTestHierarchy(const OffsetF& coordinateOffset,
|
||||
if (innerRecognizers.size() == 1) {
|
||||
current = *innerRecognizers.begin();
|
||||
} else if (innerRecognizers.size() > 1) {
|
||||
current = AceType::MakeRefPtr<ExclusiveRecognizer>(std::move(innerRecognizers));
|
||||
current->SetCoordinateOffset(offset);
|
||||
if (!innerExclusiveRecognizer_) {
|
||||
innerExclusiveRecognizer_ = AceType::MakeRefPtr<ExclusiveRecognizer>(std::move(innerRecognizers));
|
||||
innerExclusiveRecognizer_->SetCoordinateOffset(offset);
|
||||
}
|
||||
current = innerExclusiveRecognizer_;
|
||||
}
|
||||
|
||||
if (recreateGesture_) {
|
||||
@ -118,8 +116,11 @@ void GestureEventHub::ProcessTouchTestHierarchy(const OffsetF& coordinateOffset,
|
||||
}
|
||||
|
||||
if (recognizers.size() > 1) {
|
||||
current = AceType::MakeRefPtr<ParallelRecognizer>(std::move(recognizers));
|
||||
current->SetCoordinateOffset(offset);
|
||||
if (!externalParallelRecognizer_ || recreateGesture_) {
|
||||
externalParallelRecognizer_ = AceType::MakeRefPtr<ParallelRecognizer>(std::move(recognizers));
|
||||
externalParallelRecognizer_->SetCoordinateOffset(offset);
|
||||
}
|
||||
current = externalParallelRecognizer_;
|
||||
} else if (recognizers.size() == 1) {
|
||||
current = *recognizers.begin();
|
||||
}
|
||||
@ -133,8 +134,11 @@ void GestureEventHub::ProcessTouchTestHierarchy(const OffsetF& coordinateOffset,
|
||||
}
|
||||
|
||||
if (recognizers.size() > 1) {
|
||||
current = AceType::MakeRefPtr<ExclusiveRecognizer>(std::move(recognizers));
|
||||
current->SetCoordinateOffset(offset);
|
||||
if (!externalExclusiveRecognizer_ || recreateGesture_) {
|
||||
externalExclusiveRecognizer_ = AceType::MakeRefPtr<ExclusiveRecognizer>(std::move(recognizers));
|
||||
externalExclusiveRecognizer_->SetCoordinateOffset(offset);
|
||||
}
|
||||
current = externalExclusiveRecognizer_;
|
||||
} else if (recognizers.size() == 1) {
|
||||
current = *recognizers.begin();
|
||||
}
|
||||
@ -154,7 +158,7 @@ void GestureEventHub::UpdateGestureHierarchy()
|
||||
auto iter = gestures_.begin();
|
||||
auto recognizerIter = gestureHierarchy_.begin();
|
||||
for (; iter != gestures_.end(); iter++, recognizerIter++) {
|
||||
auto newRecognizer = (*iter)->CreateRecognizer(host->GetContext());
|
||||
auto newRecognizer = (*iter)->CreateRecognizer();
|
||||
success = success && (*recognizerIter)->ReconcileFrom(newRecognizer);
|
||||
if (!success) {
|
||||
break;
|
||||
@ -172,7 +176,7 @@ void GestureEventHub::UpdateGestureHierarchy()
|
||||
if (!gesture) {
|
||||
continue;
|
||||
}
|
||||
auto recognizer = gesture->CreateRecognizer(host->GetContext());
|
||||
auto recognizer = gesture->CreateRecognizer();
|
||||
if (!recognizer) {
|
||||
continue;
|
||||
}
|
||||
@ -185,4 +189,37 @@ void GestureEventHub::UpdateGestureHierarchy()
|
||||
gestures_.clear();
|
||||
}
|
||||
|
||||
void GestureEventHub::CombineIntoExclusiveRecognizer(const PointF& globalPoint, const PointF& localPoint,
|
||||
TouchTestResult& result)
|
||||
{
|
||||
TouchTestResult finalResult;
|
||||
std::list<RefPtr<GestureRecognizer>> recognizers;
|
||||
const auto coordinateOffset = globalPoint - localPoint;
|
||||
auto offset = Offset(coordinateOffset.GetX(), coordinateOffset.GetY());
|
||||
for (auto const& eventTarget : result) {
|
||||
auto recognizer = AceType::DynamicCast<GestureRecognizer>(eventTarget);
|
||||
if (recognizer) {
|
||||
recognizers.push_back(std::move(recognizer));
|
||||
} else {
|
||||
finalResult.push_back(eventTarget);
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<GestureRecognizer> current;
|
||||
if (recognizers.size() == 1) {
|
||||
current = *recognizers.begin();
|
||||
} else if (recognizers.size() > 1) {
|
||||
if (!nodeExclusiveRecognizer_) {
|
||||
nodeExclusiveRecognizer_ = AceType::MakeRefPtr<ExclusiveRecognizer>(std::move(recognizers));
|
||||
nodeExclusiveRecognizer_->SetCoordinateOffset(offset);
|
||||
}
|
||||
current = nodeExclusiveRecognizer_;
|
||||
}
|
||||
|
||||
if (current) {
|
||||
finalResult.emplace_back(std::move(current));
|
||||
}
|
||||
result.swap(finalResult);
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
@ -18,12 +18,15 @@
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "base/geometry/ng/point_t.h"
|
||||
#include "base/memory/referenced.h"
|
||||
#include "core/components/common/layout/constants.h"
|
||||
#include "core/components_ng/event/click_event.h"
|
||||
#include "core/components_ng/event/pan_event.h"
|
||||
#include "core/components_ng/event/scrollable_event.h"
|
||||
#include "core/components_ng/event/touch_event.h"
|
||||
#include "core/components_ng/gestures/recognizers/exclusive_recognizer.h"
|
||||
#include "core/components_ng/gestures/recognizers/parallel_recognizer.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
@ -70,7 +73,7 @@ public:
|
||||
explicit GestureEventHub(const WeakPtr<EventHub>& eventHub);
|
||||
~GestureEventHub() override = default;
|
||||
|
||||
void AddGesture(const RefPtr<Gesture>& gesture)
|
||||
void AddGesture(const RefPtr<NG::Gesture>& gesture)
|
||||
{
|
||||
if (!recreateGesture_) {
|
||||
gestures_.clear();
|
||||
@ -188,6 +191,9 @@ public:
|
||||
hitTestMode_ = hitTestMode;
|
||||
}
|
||||
|
||||
void CombineIntoExclusiveRecognizer(const PointF& globalPoint, const PointF& localPoint,
|
||||
TouchTestResult& result);
|
||||
|
||||
private:
|
||||
void ProcessTouchTestHierarchy(const OffsetF& coordinateOffset, const TouchRestrict& touchRestrict,
|
||||
std::list<RefPtr<GestureRecognizer>>& innerRecognizers, TouchTestResult& finalResult);
|
||||
@ -199,9 +205,13 @@ private:
|
||||
RefPtr<TouchEventActuator> touchEventActuator_;
|
||||
RefPtr<ClickEventActuator> clickEventActuator_;
|
||||
RefPtr<PanEventActuator> panEventActuator_;
|
||||
RefPtr<ExclusiveRecognizer> innerExclusiveRecognizer_;
|
||||
RefPtr<ExclusiveRecognizer> externalExclusiveRecognizer_;
|
||||
RefPtr<ExclusiveRecognizer> nodeExclusiveRecognizer_;
|
||||
RefPtr<ParallelRecognizer> externalParallelRecognizer_;
|
||||
|
||||
// Set by use gesture, priorityGesture and parallelGesture attribute function.
|
||||
std::list<RefPtr<Gesture>> gestures_;
|
||||
std::list<RefPtr<NG::Gesture>> gestures_;
|
||||
std::list<RefPtr<GestureRecognizer>> gestureHierarchy_;
|
||||
HitTestMode hitTestMode_ = HitTestMode::DEFAULT;
|
||||
bool recreateGesture_ = true;
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "base/utils/utils.h"
|
||||
#include "core/components_ng/base/frame_node.h"
|
||||
#include "core/components_ng/event/gesture_event_hub.h"
|
||||
#include "core/components_ng/gestures/recognizers/pan_recognizer.h"
|
||||
#include "core/pipeline_ng/pipeline_context.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
@ -38,7 +39,7 @@ PanEventActuator::PanEventActuator(const WeakPtr<GestureEventHub>& gestureEventH
|
||||
CHECK_NULL_VOID(gestureHub);
|
||||
auto frameNode = gestureHub->GetFrameNode();
|
||||
CHECK_NULL_VOID(frameNode);
|
||||
panRecognizer_ = MakeRefPtr<PanRecognizer>(frameNode->GetContext(), fingers_, direction_, distance_);
|
||||
panRecognizer_ = MakeRefPtr<PanRecognizer>(fingers_, direction_, distance_);
|
||||
}
|
||||
|
||||
void PanEventActuator::OnCollectTouchTarget(const OffsetF& coordinateOffset, const TouchRestrict& touchRestrict,
|
||||
|
@ -21,12 +21,12 @@
|
||||
|
||||
#include "base/memory/referenced.h"
|
||||
#include "core/components_ng/event/gesture_event_actuator.h"
|
||||
#include "core/gestures/gesture_info.h"
|
||||
#include "core/gestures/pan_recognizer.h"
|
||||
#include "core/components_ng/gestures/gesture_info.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
class GestureEventHub;
|
||||
class PanRecognizer;
|
||||
|
||||
class PanEvent : public Referenced {
|
||||
public:
|
||||
|
42
frameworks/core/components_ng/gestures/BUILD.gn
Normal file
42
frameworks/core/components_ng/gestures/BUILD.gn
Normal file
@ -0,0 +1,42 @@
|
||||
# Copyright (c) 2022 Huawei Device Co., Ltd.
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import(
|
||||
"//foundation/arkui/ace_engine/frameworks/core/components_ng/components.gni")
|
||||
|
||||
build_component_ng("gestures_ng") {
|
||||
sources = [
|
||||
# gestures
|
||||
"//foundation/arkui/ace_engine/frameworks/core/components_ng/gestures/gesture_group.cpp",
|
||||
"//foundation/arkui/ace_engine/frameworks/core/components_ng/gestures/gesture_referee.cpp",
|
||||
"//foundation/arkui/ace_engine/frameworks/core/components_ng/gestures/long_press_gesture.cpp",
|
||||
"//foundation/arkui/ace_engine/frameworks/core/components_ng/gestures/pan_gesture.cpp",
|
||||
"//foundation/arkui/ace_engine/frameworks/core/components_ng/gestures/pinch_gesture.cpp",
|
||||
"//foundation/arkui/ace_engine/frameworks/core/components_ng/gestures/rotation_gesture.cpp",
|
||||
"//foundation/arkui/ace_engine/frameworks/core/components_ng/gestures/swipe_gesture.cpp",
|
||||
"//foundation/arkui/ace_engine/frameworks/core/components_ng/gestures/tap_gesture.cpp",
|
||||
|
||||
# recognizers
|
||||
"recognizers/click_recognizer.cpp",
|
||||
"recognizers/exclusive_recognizer.cpp",
|
||||
"recognizers/gesture_recognizer.cpp",
|
||||
"recognizers/long_press_recognizer.cpp",
|
||||
"recognizers/multi_fingers_recognizer.cpp",
|
||||
"recognizers/pan_recognizer.cpp",
|
||||
"recognizers/parallel_recognizer.cpp",
|
||||
"recognizers/pinch_recognizer.cpp",
|
||||
"recognizers/rotation_recognizer.cpp",
|
||||
"recognizers/sequenced_recognizer.cpp",
|
||||
"recognizers/swipe_recognizer.cpp",
|
||||
]
|
||||
}
|
59
frameworks/core/components_ng/gestures/gesture_group.cpp
Normal file
59
frameworks/core/components_ng/gestures/gesture_group.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "core/components_ng/gestures/gesture_group.h"
|
||||
|
||||
#include "core/components_ng/gestures/recognizers/exclusive_recognizer.h"
|
||||
#include "core/components_ng/gestures/recognizers/parallel_recognizer.h"
|
||||
#include "core/components_ng/gestures/recognizers/sequenced_recognizer.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
RefPtr<GestureRecognizer> GestureGroup::CreateRecognizer()
|
||||
{
|
||||
LOGD("create gesture group, sub size %{public}zu, mode %{public}d", gestures_.size(), mode_);
|
||||
std::vector<RefPtr<GestureRecognizer>> recognizers;
|
||||
for (auto& subGesture : gestures_) {
|
||||
auto recognizer = subGesture->CreateRecognizer();
|
||||
if (recognizer) {
|
||||
recognizers.emplace_back(recognizer);
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<GestureRecognizer> groupRecognizer;
|
||||
switch (mode_) {
|
||||
case GestureMode::Sequence:
|
||||
groupRecognizer = AceType::MakeRefPtr<SequencedRecognizer>(recognizers);
|
||||
if (onActionCancelId_) {
|
||||
groupRecognizer->SetOnActionCancel(*onActionCancelId_);
|
||||
}
|
||||
break;
|
||||
case GestureMode::Parallel:
|
||||
groupRecognizer = AceType::MakeRefPtr<ParallelRecognizer>(recognizers);
|
||||
break;
|
||||
case GestureMode::Exclusive:
|
||||
groupRecognizer = AceType::MakeRefPtr<ExclusiveRecognizer>(recognizers);
|
||||
break;
|
||||
default:
|
||||
LOGE("unknown gesture mode %{public}d when create gesture group recognizer", mode_);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
groupRecognizer->SetPriority(priority_);
|
||||
groupRecognizer->SetPriorityMask(gestureMask_);
|
||||
return groupRecognizer;
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
52
frameworks/core/components_ng/gestures/gesture_group.h
Normal file
52
frameworks/core/components_ng/gestures/gesture_group.h
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_GESTURE_GROUP_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_GESTURE_GROUP_H
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/geometry/offset.h"
|
||||
#include "base/memory/ace_type.h"
|
||||
#include "base/utils/macros.h"
|
||||
#include "core/components_ng/gestures/gesture_info.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
class ACE_EXPORT GestureGroup : public Gesture {
|
||||
DECLARE_ACE_TYPE(GestureGroup, Gesture);
|
||||
|
||||
public:
|
||||
GestureGroup(GestureMode mode, const std::vector<RefPtr<Gesture>>& gestures) : mode_(mode), gestures_(gestures) {}
|
||||
explicit GestureGroup(GestureMode mode) : mode_(mode) {}
|
||||
~GestureGroup() override = default;
|
||||
|
||||
void AddGesture(RefPtr<Gesture> gesture)
|
||||
{
|
||||
gestures_.emplace_back(gesture);
|
||||
}
|
||||
|
||||
protected:
|
||||
RefPtr<GestureRecognizer> CreateRecognizer() override;
|
||||
|
||||
private:
|
||||
GestureMode mode_;
|
||||
std::vector<RefPtr<Gesture>> gestures_;
|
||||
};
|
||||
} // namespace OHOS::Ace::NG
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_GESTURE_GROUP_H
|
102
frameworks/core/components_ng/gestures/gesture_info.h
Normal file
102
frameworks/core/components_ng/gestures/gesture_info.h
Normal file
@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_GESTURE_INFO_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_GESTURE_INFO_H
|
||||
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "base/geometry/offset.h"
|
||||
#include "base/geometry/point.h"
|
||||
#include "base/image/pixel_map.h"
|
||||
#include "base/memory/ace_type.h"
|
||||
#include "base/utils/event_callback.h"
|
||||
#include "base/utils/macros.h"
|
||||
#include "base/utils/type_definition.h"
|
||||
#include "core/event/ace_events.h"
|
||||
#include "core/gestures/gesture_info.h"
|
||||
#include "core/gestures/velocity.h"
|
||||
#include "core/gestures/velocity_tracker.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
class GestureRecognizer;
|
||||
|
||||
class ACE_EXPORT Gesture : public virtual AceType {
|
||||
DECLARE_ACE_TYPE(Gesture, AceType);
|
||||
|
||||
public:
|
||||
Gesture() = default;
|
||||
explicit Gesture(int32_t fingers) : fingers_(fingers) {}
|
||||
~Gesture() override = default;
|
||||
|
||||
void SetOnActionId(const GestureEventFunc& onActionId)
|
||||
{
|
||||
onActionId_ = std::make_unique<GestureEventFunc>(onActionId);
|
||||
}
|
||||
void SetOnActionStartId(const GestureEventFunc& onActionStartId)
|
||||
{
|
||||
onActionStartId_ = std::make_unique<GestureEventFunc>(onActionStartId);
|
||||
}
|
||||
void SetOnActionUpdateId(const GestureEventFunc& onActionUpdateId)
|
||||
{
|
||||
onActionUpdateId_ = std::make_unique<GestureEventFunc>(onActionUpdateId);
|
||||
}
|
||||
void SetOnActionEndId(const GestureEventFunc& onActionEndId)
|
||||
{
|
||||
onActionEndId_ = std::make_unique<GestureEventFunc>(onActionEndId);
|
||||
}
|
||||
void SetOnActionCancelId(const GestureEventNoParameter& onActionCancelId)
|
||||
{
|
||||
onActionCancelId_ = std::make_unique<GestureEventNoParameter>(onActionCancelId);
|
||||
}
|
||||
void SetPriority(GesturePriority priority)
|
||||
{
|
||||
priority_ = priority;
|
||||
}
|
||||
void SetGestureMask(GestureMask gestureMask)
|
||||
{
|
||||
gestureMask_ = gestureMask;
|
||||
}
|
||||
|
||||
GesturePriority GetPriority() const
|
||||
{
|
||||
return priority_;
|
||||
}
|
||||
|
||||
GestureMask GetGestureMask() const
|
||||
{
|
||||
return gestureMask_;
|
||||
}
|
||||
|
||||
virtual RefPtr<GestureRecognizer> CreateRecognizer() = 0;
|
||||
|
||||
protected:
|
||||
int32_t fingers_ = 1;
|
||||
GesturePriority priority_ = GesturePriority::Low;
|
||||
GestureMask gestureMask_ = GestureMask::Normal;
|
||||
std::unique_ptr<GestureEventFunc> onActionId_;
|
||||
std::unique_ptr<GestureEventFunc> onActionStartId_;
|
||||
std::unique_ptr<GestureEventFunc> onActionUpdateId_;
|
||||
std::unique_ptr<GestureEventFunc> onActionEndId_;
|
||||
std::unique_ptr<GestureEventNoParameter> onActionCancelId_;
|
||||
};
|
||||
} // namespace OHOS::Ace::NG
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_GESTURE_INFO_H
|
422
frameworks/core/components_ng/gestures/gesture_referee.cpp
Normal file
422
frameworks/core/components_ng/gestures/gesture_referee.cpp
Normal file
@ -0,0 +1,422 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "core/components_ng/gestures/gesture_referee.h"
|
||||
|
||||
#include "core/components_ng/gestures/recognizers/gesture_recognizer.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
void GestureScope::AddMember(const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
if (!recognizer) {
|
||||
LOGE("gesture recognizer is null, AddMember failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (Existed(recognizer)) {
|
||||
LOGE("gesture recognizer has already been added.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
recognizer->SetRefereeState(RefereeState::DETECTING);
|
||||
|
||||
switch (recognizer->GetPriority()) {
|
||||
case GesturePriority::Parallel:
|
||||
parallelRecognizers_.emplace_back(recognizer);
|
||||
break;
|
||||
case GesturePriority::High:
|
||||
highRecognizers_.emplace_back(recognizer);
|
||||
break;
|
||||
case GesturePriority::Low:
|
||||
lowRecognizers_.emplace_back(recognizer);
|
||||
break;
|
||||
default:
|
||||
LOGW("Add unknown type member %{public}d to referee", recognizer->GetPriority());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GestureScope::DelMember(const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
if (!recognizer) {
|
||||
LOGI("gesture recognizer is null, DelMember finish.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Existed(recognizer)) {
|
||||
LOGI("gesture recognizer is not existed when deleted.");
|
||||
return;
|
||||
}
|
||||
|
||||
LOGD("gesture referee ready to delete member of %{public}s", AceType::TypeName(recognizer));
|
||||
RefereeState prevState = recognizer->GetRefereeState();
|
||||
recognizer->SetRefereeState(RefereeState::DETECTING);
|
||||
|
||||
if (recognizer->GetPriority() == GesturePriority::Parallel) {
|
||||
parallelRecognizers_.remove(recognizer);
|
||||
return;
|
||||
}
|
||||
|
||||
RemoveAndUnBlockGesture(prevState == RefereeState::PENDING, recognizer);
|
||||
}
|
||||
|
||||
void GestureScope::HandleGestureDisposal(const RefPtr<GestureRecognizer>& recognizer, const GestureDisposal disposal)
|
||||
{
|
||||
if (!Existed(recognizer)) {
|
||||
LOGE("can not find the recognizer");
|
||||
return;
|
||||
}
|
||||
|
||||
GesturePriority priority = recognizer->GetPriority();
|
||||
if (priority == GesturePriority::Parallel) {
|
||||
HandleParallelDisposal(recognizer, disposal);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (disposal) {
|
||||
case GestureDisposal::ACCEPT:
|
||||
HandleAcceptDisposal(recognizer);
|
||||
break;
|
||||
case GestureDisposal::PENDING:
|
||||
HandlePendingDisposal(recognizer);
|
||||
break;
|
||||
case GestureDisposal::REJECT:
|
||||
HandleRejectDisposal(recognizer);
|
||||
break;
|
||||
default:
|
||||
LOGW("handle known gesture disposal %{public}d", disposal);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GestureScope::HandleParallelDisposal(const RefPtr<GestureRecognizer>& recognizer, GestureDisposal disposal)
|
||||
{
|
||||
if (disposal == GestureDisposal::REJECT) {
|
||||
parallelRecognizers_.remove(recognizer);
|
||||
recognizer->SetRefereeState(RefereeState::FAIL);
|
||||
recognizer->OnRejected(touchId_);
|
||||
} else if (disposal == GestureDisposal::ACCEPT) {
|
||||
parallelRecognizers_.remove(recognizer);
|
||||
recognizer->SetRefereeState(RefereeState::SUCCEED);
|
||||
recognizer->OnAccepted(touchId_);
|
||||
}
|
||||
}
|
||||
|
||||
void GestureScope::HandleAcceptDisposal(const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
if (CheckNeedBlocked(recognizer)) {
|
||||
LOGI("gesture referee ready to notify block for %{public}s", AceType::TypeName(recognizer));
|
||||
recognizer->SetRefereeState(RefereeState::BLOCKED);
|
||||
return;
|
||||
}
|
||||
|
||||
LOGI("gesture referee accept %{public}s of id %{public}zu", AceType::TypeName(recognizer), touchId_);
|
||||
AcceptGesture(recognizer);
|
||||
}
|
||||
|
||||
void GestureScope::HandlePendingDisposal(const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
if (CheckNeedBlocked(recognizer)) {
|
||||
LOGI("gesture referee ready to notify block for %{public}s", AceType::TypeName(recognizer));
|
||||
recognizer->SetRefereeState(RefereeState::BLOCKED);
|
||||
return;
|
||||
}
|
||||
|
||||
LOGI("gesture referee ready to notify pending for %{public}s", AceType::TypeName(recognizer));
|
||||
recognizer->SetRefereeState(RefereeState::PENDING);
|
||||
recognizer->OnPending(touchId_);
|
||||
}
|
||||
|
||||
void GestureScope::HandleRejectDisposal(const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
LOGI("gesture referee ready to notify reject for %{public}s", AceType::TypeName(recognizer));
|
||||
RefereeState prevState = recognizer->GetRefereeState();
|
||||
recognizer->SetRefereeState(RefereeState::FAIL);
|
||||
recognizer->OnRejected(touchId_);
|
||||
RemoveAndUnBlockGesture(prevState == RefereeState::PENDING, recognizer);
|
||||
}
|
||||
|
||||
void GestureScope::RemoveAndUnBlockGesture(bool isPrevPending, const WeakPtr<GestureRecognizer>& weakRecognizer)
|
||||
{
|
||||
auto recognizer = weakRecognizer.Upgrade();
|
||||
if (!recognizer) {
|
||||
return;
|
||||
}
|
||||
if (recognizer->GetPriority() == GesturePriority::High) {
|
||||
highRecognizers_.remove(recognizer);
|
||||
if (highRecognizers_.empty()) {
|
||||
UnBlockGesture(lowRecognizers_);
|
||||
return;
|
||||
}
|
||||
|
||||
if (isPrevPending) {
|
||||
UnBlockGesture(highRecognizers_);
|
||||
}
|
||||
} else {
|
||||
lowRecognizers_.remove(recognizer);
|
||||
if (isPrevPending) {
|
||||
UnBlockGesture(lowRecognizers_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool GestureScope::Existed(const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
if (!recognizer) {
|
||||
LOGE("recognizer is null, AddGestureRecognizer failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::list<WeakPtr<GestureRecognizer>> members = GetMembersByRecognizer(recognizer);
|
||||
if (members.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto result = std::find(members.cbegin(), members.cend(), recognizer);
|
||||
return result != members.cend();
|
||||
}
|
||||
|
||||
const std::list<WeakPtr<GestureRecognizer>>& GestureScope::GetMembersByRecognizer(
|
||||
const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
switch (recognizer->GetPriority()) {
|
||||
case GesturePriority::Low:
|
||||
return lowRecognizers_;
|
||||
case GesturePriority::High:
|
||||
return highRecognizers_;
|
||||
case GesturePriority::Parallel:
|
||||
return parallelRecognizers_;
|
||||
default:
|
||||
return lowRecognizers_;
|
||||
}
|
||||
}
|
||||
|
||||
bool GestureScope::CheckNeedBlocked(const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
if (recognizer->GetPriority() == GesturePriority::Low && !highRecognizers_.empty()) {
|
||||
LOGD("self is low priority, high recognizers are not processed");
|
||||
return true;
|
||||
}
|
||||
|
||||
std::list<WeakPtr<GestureRecognizer>> members = GetMembersByRecognizer(recognizer);
|
||||
for (const auto& member : members) {
|
||||
if (member == recognizer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (member.Upgrade() && member.Upgrade()->GetRefereeState() == RefereeState::PENDING) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void GestureScope::AcceptGesture(const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
if (recognizer->GetPriority() == GesturePriority::Low) {
|
||||
for (const auto& rejectedItem : lowRecognizers_) {
|
||||
if (rejectedItem == recognizer) {
|
||||
continue;
|
||||
}
|
||||
auto strongItem = rejectedItem.Upgrade();
|
||||
if (strongItem) {
|
||||
strongItem->OnRejected(touchId_);
|
||||
strongItem->SetRefereeState(RefereeState::FAIL);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (const auto& rejectedItem : highRecognizers_) {
|
||||
if (rejectedItem == recognizer) {
|
||||
continue;
|
||||
}
|
||||
auto strongItem = rejectedItem.Upgrade();
|
||||
if (strongItem) {
|
||||
strongItem->OnRejected(touchId_);
|
||||
strongItem->SetRefereeState(RefereeState::FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& rejectedItem : lowRecognizers_) {
|
||||
if (rejectedItem == recognizer) {
|
||||
continue;
|
||||
}
|
||||
auto strongItem = rejectedItem.Upgrade();
|
||||
if (strongItem) {
|
||||
strongItem->OnRejected(touchId_);
|
||||
strongItem->SetRefereeState(RefereeState::FAIL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
recognizer->SetRefereeState(RefereeState::SUCCEED);
|
||||
recognizer->OnAccepted(touchId_);
|
||||
if (recognizer->GetPriority() == GesturePriority::Low) {
|
||||
lowRecognizers_.clear();
|
||||
} else {
|
||||
highRecognizers_.clear();
|
||||
lowRecognizers_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void GestureScope::UnBlockGesture(std::list<WeakPtr<GestureRecognizer>>& members)
|
||||
{
|
||||
auto weakBlockedMember =
|
||||
std::find_if(std::begin(members), std::end(members), [](const WeakPtr<GestureRecognizer>& member) {
|
||||
return member.Upgrade() && member.Upgrade()->GetRefereeState() == RefereeState::BLOCKED;
|
||||
});
|
||||
if (weakBlockedMember == members.end()) {
|
||||
LOGD("no blocked gesture in recognizers");
|
||||
return;
|
||||
}
|
||||
auto blockedMember = (*weakBlockedMember).Upgrade();
|
||||
if (!blockedMember) {
|
||||
LOGW("BlockedMember not exists.");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((blockedMember)->GetDetectState() == DetectState::DETECTED) {
|
||||
LOGD("unblock and accept this gesture");
|
||||
AcceptGesture(blockedMember);
|
||||
return;
|
||||
}
|
||||
|
||||
LOGD("set the gesture %{public}s to be pending", AceType::TypeName((*blockedMember)));
|
||||
(blockedMember)->SetRefereeState(RefereeState::PENDING);
|
||||
(blockedMember)->OnPending(touchId_);
|
||||
}
|
||||
|
||||
void GestureScope::ForceClose()
|
||||
{
|
||||
LOGD("force close gesture scope of id %{public}zu", touchId_);
|
||||
for (const auto& weakRejectedItem : lowRecognizers_) {
|
||||
auto rejectedItem = weakRejectedItem.Upgrade();
|
||||
if (rejectedItem) {
|
||||
rejectedItem->OnRejected(touchId_);
|
||||
}
|
||||
}
|
||||
lowRecognizers_.clear();
|
||||
|
||||
for (const auto& weakRejectedItem : highRecognizers_) {
|
||||
auto rejectedItem = weakRejectedItem.Upgrade();
|
||||
if (rejectedItem) {
|
||||
rejectedItem->OnRejected(touchId_);
|
||||
}
|
||||
}
|
||||
highRecognizers_.clear();
|
||||
|
||||
for (const auto& weakRejectedItem : parallelRecognizers_) {
|
||||
auto rejectedItem = weakRejectedItem.Upgrade();
|
||||
if (rejectedItem) {
|
||||
rejectedItem->OnRejected(touchId_);
|
||||
}
|
||||
}
|
||||
parallelRecognizers_.clear();
|
||||
}
|
||||
|
||||
bool GestureScope::IsPending() const
|
||||
{
|
||||
auto pendingMember = std::find_if(
|
||||
std::begin(lowRecognizers_), std::end(lowRecognizers_), [](const WeakPtr<GestureRecognizer>& member) {
|
||||
return member.Upgrade() && member.Upgrade()->GetRefereeState() == RefereeState::PENDING;
|
||||
});
|
||||
if (pendingMember != lowRecognizers_.end()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
pendingMember = std::find_if(
|
||||
std::begin(highRecognizers_), std::end(highRecognizers_), [](const WeakPtr<GestureRecognizer>& member) {
|
||||
return member.Upgrade() && member.Upgrade()->GetRefereeState() == RefereeState::PENDING;
|
||||
});
|
||||
if (pendingMember != highRecognizers_.end()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
pendingMember = std::find_if(
|
||||
std::begin(parallelRecognizers_), std::end(parallelRecognizers_), [](const WeakPtr<GestureRecognizer>& member) {
|
||||
return member.Upgrade() && member.Upgrade()->GetRefereeState() == RefereeState::PENDING;
|
||||
});
|
||||
return pendingMember != parallelRecognizers_.end();
|
||||
}
|
||||
|
||||
void GestureReferee::AddGestureRecognizer(size_t touchId, const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
if (!recognizer) {
|
||||
LOGE("recognizer is null, AddGestureRecognizer failed.");
|
||||
return;
|
||||
}
|
||||
LOGD("add gesture recognizer %{public}s into scope %{public}zu,", AceType::TypeName(recognizer), touchId);
|
||||
const auto iter = gestureScopes_.find(touchId);
|
||||
if (iter != gestureScopes_.end()) {
|
||||
iter->second.AddMember(recognizer);
|
||||
} else {
|
||||
GestureScope gestureScope(touchId);
|
||||
gestureScope.AddMember(recognizer);
|
||||
gestureScopes_.try_emplace(touchId, std::move(gestureScope));
|
||||
}
|
||||
}
|
||||
|
||||
void GestureReferee::DelGestureRecognizer(size_t touchId, const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
if (!recognizer) {
|
||||
LOGE("recognizer is null, DelGestureRecognizer failed.");
|
||||
return;
|
||||
}
|
||||
LOGD("delete gesture recognizer %{public}s from scope %{public}zu ", AceType::TypeName(recognizer), touchId);
|
||||
const auto iter = gestureScopes_.find(touchId);
|
||||
if (iter == gestureScopes_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
iter->second.DelMember(recognizer);
|
||||
}
|
||||
|
||||
void GestureReferee::CleanGestureScope(size_t touchId)
|
||||
{
|
||||
const auto iter = gestureScopes_.find(touchId);
|
||||
if (iter != gestureScopes_.end()) {
|
||||
if (iter->second.IsPending()) {
|
||||
LOGE("gesture scope of touch id %{public}zu is pending, do not clean this.", touchId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!iter->second.IsEmpty()) {
|
||||
iter->second.ForceClose();
|
||||
}
|
||||
gestureScopes_.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
void GestureReferee::Adjudicate(size_t touchId, const RefPtr<GestureRecognizer>& recognizer, GestureDisposal disposal)
|
||||
{
|
||||
if (!recognizer) {
|
||||
LOGE("recognizer is null, Adjudicate failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
const auto iter = gestureScopes_.find(touchId);
|
||||
if (iter != gestureScopes_.end()) {
|
||||
iter->second.HandleGestureDisposal(recognizer, disposal);
|
||||
if (iter->second.IsEmpty()) {
|
||||
LOGD("clean the gesture referee of %{public}zu", touchId);
|
||||
gestureScopes_.erase(iter);
|
||||
}
|
||||
} else {
|
||||
LOGE("fail to find the gesture scope for %{public}zu session id", touchId);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
101
frameworks/core/components_ng/gestures/gesture_referee.h
Normal file
101
frameworks/core/components_ng/gestures/gesture_referee.h
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_GESTURE_REFEREE_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_GESTURE_REFEREE_H
|
||||
|
||||
#include <list>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "base/memory/ace_type.h"
|
||||
#include "base/utils/singleton.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
class GestureRecognizer;
|
||||
|
||||
enum class GestureDisposal {
|
||||
ACCEPT = 0,
|
||||
REJECT,
|
||||
PENDING,
|
||||
};
|
||||
|
||||
class GestureScope {
|
||||
public:
|
||||
explicit GestureScope(size_t touchId) : touchId_(touchId) {}
|
||||
~GestureScope() = default;
|
||||
|
||||
void AddMember(const RefPtr<GestureRecognizer>& recognizer);
|
||||
void DelMember(const RefPtr<GestureRecognizer>& recognizer);
|
||||
|
||||
void ForceClose();
|
||||
|
||||
void HandleGestureDisposal(const RefPtr<GestureRecognizer>& recognizer, GestureDisposal disposal);
|
||||
|
||||
bool IsEmpty() const
|
||||
{
|
||||
return highRecognizers_.empty() && lowRecognizers_.empty() && parallelRecognizers_.empty();
|
||||
}
|
||||
|
||||
bool IsPending() const;
|
||||
|
||||
private:
|
||||
bool Existed(const RefPtr<GestureRecognizer>& recognizer);
|
||||
const std::list<WeakPtr<GestureRecognizer>>& GetMembersByRecognizer(const RefPtr<GestureRecognizer>& recognizer);
|
||||
bool CheckNeedBlocked(const RefPtr<GestureRecognizer>& recognizer);
|
||||
void AcceptGesture(const RefPtr<GestureRecognizer>& recognizer);
|
||||
void UnBlockGesture(std::list<WeakPtr<GestureRecognizer>>& members);
|
||||
void HandleParallelDisposal(const RefPtr<GestureRecognizer>& recognizer, GestureDisposal disposal);
|
||||
void HandleAcceptDisposal(const RefPtr<GestureRecognizer>& recognizer);
|
||||
void HandlePendingDisposal(const RefPtr<GestureRecognizer>& recognizer);
|
||||
void HandleRejectDisposal(const RefPtr<GestureRecognizer>& recognizer);
|
||||
void RemoveAndUnBlockGesture(bool isPrevPending, const WeakPtr<GestureRecognizer>& recognizer);
|
||||
|
||||
size_t touchId_ = 0;
|
||||
|
||||
std::list<WeakPtr<GestureRecognizer>> highRecognizers_;
|
||||
std::list<WeakPtr<GestureRecognizer>> lowRecognizers_;
|
||||
std::list<WeakPtr<GestureRecognizer>> parallelRecognizers_;
|
||||
};
|
||||
|
||||
class GestureReferee : public virtual AceType {
|
||||
DECLARE_ACE_TYPE(GestureRefereeNG, AceType);
|
||||
public:
|
||||
GestureReferee() = default;
|
||||
~GestureReferee() = default;
|
||||
|
||||
// Each gesture recognizer should add itself to the gesture scope at the beginning of the gesture sequence
|
||||
// (touch down event) for gesture adjudicating.
|
||||
void AddGestureRecognizer(size_t touchId, const RefPtr<GestureRecognizer>& recognizer);
|
||||
|
||||
// In multi finger recognizers, touch up one finger does not result to the whole gesture failed. Recognizer should
|
||||
// remove the recognizer out of the referee.
|
||||
void DelGestureRecognizer(size_t touchId, const RefPtr<GestureRecognizer>& recognizer);
|
||||
|
||||
// Try to clean gesture scope when receive cancel event.
|
||||
void CleanGestureScope(size_t touchId);
|
||||
|
||||
// Called by the gesture recognizer when the gesture recognizer has completed the recognition of the gesture (accept
|
||||
// or reject)
|
||||
void Adjudicate(size_t touchId, const RefPtr<GestureRecognizer>& recognizer, GestureDisposal disposal);
|
||||
|
||||
private:
|
||||
// Stores gesture recognizer collection according to Id.
|
||||
std::unordered_map<size_t, GestureScope> gestureScopes_;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_GESTURE_REFEREE_H
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "core/components_ng/gestures/long_press_gesture.h"
|
||||
|
||||
#include "core/components_ng/gestures/recognizers/long_press_recognizer.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
RefPtr<GestureRecognizer> LongPressGesture::CreateRecognizer()
|
||||
{
|
||||
LOGD("create long press gesture, fingers %{public}d, duration %{public}d, isRepeat %{public}d", fingers_, duration_,
|
||||
repeat_);
|
||||
auto longPressRecognizer = AceType::MakeRefPtr<LongPressRecognizer>(
|
||||
duration_, fingers_, repeat_, isForDrag_, isDisableMouseLeft_);
|
||||
longPressRecognizer->SetPriority(priority_);
|
||||
longPressRecognizer->SetPriorityMask(gestureMask_);
|
||||
if (onActionId_) {
|
||||
longPressRecognizer->SetOnAction(*onActionId_);
|
||||
}
|
||||
|
||||
if (onActionEndId_) {
|
||||
longPressRecognizer->SetOnActionEnd(*onActionEndId_);
|
||||
}
|
||||
|
||||
if (onActionCancelId_) {
|
||||
longPressRecognizer->SetOnActionCancel(*onActionCancelId_);
|
||||
}
|
||||
|
||||
return longPressRecognizer;
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
53
frameworks/core/components_ng/gestures/long_press_gesture.h
Normal file
53
frameworks/core/components_ng/gestures/long_press_gesture.h
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_LONG_PRESS_GESTURE_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_LONG_PRESS_GESTURE_H
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/geometry/offset.h"
|
||||
#include "base/memory/ace_type.h"
|
||||
#include "base/utils/macros.h"
|
||||
#include "core/components_ng/gestures/gesture_info.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
class ACE_EXPORT LongPressGesture : public Gesture {
|
||||
DECLARE_ACE_TYPE(LongPressGesture, Gesture);
|
||||
|
||||
public:
|
||||
LongPressGesture(
|
||||
int32_t fingers, bool repeat, int32_t duration, bool isForDrag = false, bool isDisableMouseLeft = false)
|
||||
: Gesture(fingers), repeat_(repeat), duration_(duration), isForDrag_(isForDrag),
|
||||
isDisableMouseLeft_(isDisableMouseLeft)
|
||||
{}
|
||||
~LongPressGesture() override = default;
|
||||
|
||||
protected:
|
||||
RefPtr<GestureRecognizer> CreateRecognizer() override;
|
||||
|
||||
private:
|
||||
bool repeat_ = false;
|
||||
int32_t duration_ = 500;
|
||||
bool isForDrag_ = false;
|
||||
bool isDisableMouseLeft_ = false;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_LONG_PRESS_GESTURE_H
|
59
frameworks/core/components_ng/gestures/pan_gesture.cpp
Normal file
59
frameworks/core/components_ng/gestures/pan_gesture.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "core/components_ng/gestures/pan_gesture.h"
|
||||
|
||||
#include "base/geometry/dimension.h"
|
||||
#include "core/components_ng/gestures/recognizers/pan_recognizer.h"
|
||||
#include "core/pipeline_ng/pipeline_context.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
RefPtr<GestureRecognizer> PanGesture::CreateRecognizer()
|
||||
{
|
||||
auto context = PipelineContext::GetCurrentContext();
|
||||
CHECK_NULL_RETURN(context, nullptr);
|
||||
|
||||
double distance = context->NormalizeToPx(Dimension(distance_, DimensionUnit::VP));
|
||||
RefPtr<PanRecognizer> panRecognizer;
|
||||
if (panGestureOption_) {
|
||||
LOGD("AceType::MakeRefPtr<OHOS::Ace::PanRecognizer>(panGestureOption_)");
|
||||
panRecognizer = AceType::MakeRefPtr<PanRecognizer>(panGestureOption_);
|
||||
} else {
|
||||
LOGD("AceType::MakeRefPtr<OHOS::Ace::PanRecognizer>(fingers_, direction_, distance)");
|
||||
panRecognizer = AceType::MakeRefPtr<PanRecognizer>(fingers_, direction_, distance);
|
||||
}
|
||||
if (onActionStartId_) {
|
||||
panRecognizer->SetOnActionStart(*onActionStartId_);
|
||||
}
|
||||
|
||||
if (onActionUpdateId_) {
|
||||
panRecognizer->SetOnActionUpdate(*onActionUpdateId_);
|
||||
}
|
||||
|
||||
if (onActionEndId_) {
|
||||
panRecognizer->SetOnActionEnd(*onActionEndId_);
|
||||
}
|
||||
|
||||
if (onActionCancelId_) {
|
||||
panRecognizer->SetOnActionCancel(*onActionCancelId_);
|
||||
}
|
||||
|
||||
panRecognizer->SetPriority(priority_);
|
||||
panRecognizer->SetPriorityMask(gestureMask_);
|
||||
return panRecognizer;
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
57
frameworks/core/components_ng/gestures/pan_gesture.h
Normal file
57
frameworks/core/components_ng/gestures/pan_gesture.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_PAN_GESTURE_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_PAN_GESTURE_H
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/geometry/offset.h"
|
||||
#include "base/memory/ace_type.h"
|
||||
#include "base/utils/macros.h"
|
||||
#include "core/components_ng/gestures/gesture_info.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
class ACE_EXPORT PanGesture : public Gesture {
|
||||
DECLARE_ACE_TYPE(PanGesture, Gesture);
|
||||
|
||||
public:
|
||||
PanGesture(int32_t fingers, const PanDirection& direction, double distance)
|
||||
{
|
||||
fingers_ = fingers;
|
||||
direction_ = direction;
|
||||
distance_ = distance;
|
||||
};
|
||||
explicit PanGesture(RefPtr<PanGestureOption> panGestureOption)
|
||||
{
|
||||
panGestureOption_ = panGestureOption;
|
||||
};
|
||||
~PanGesture() override = default;
|
||||
|
||||
protected:
|
||||
RefPtr<GestureRecognizer> CreateRecognizer() override;
|
||||
|
||||
private:
|
||||
PanDirection direction_;
|
||||
double distance_ = 0.0;
|
||||
RefPtr<PanGestureOption> panGestureOption_;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_PAN_GESTURE_H
|
55
frameworks/core/components_ng/gestures/pinch_gesture.cpp
Normal file
55
frameworks/core/components_ng/gestures/pinch_gesture.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "core/components_ng/gestures/pinch_gesture.h"
|
||||
|
||||
#include "base/geometry/dimension.h"
|
||||
#include "base/utils/utils.h"
|
||||
#include "core/components_ng/base/ui_node.h"
|
||||
#include "core/components_ng/gestures/recognizers/pinch_recognizer.h"
|
||||
#include "core/pipeline_ng/pipeline_context.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
RefPtr<GestureRecognizer> PinchGesture::CreateRecognizer()
|
||||
{
|
||||
auto context = PipelineContext::GetCurrentContext();
|
||||
CHECK_NULL_RETURN(context, nullptr);
|
||||
|
||||
double distance = context->NormalizeToPx(Dimension(distance_, DimensionUnit::VP));
|
||||
auto pinchRecognizer = AceType::MakeRefPtr<PinchRecognizer>(fingers_, distance);
|
||||
if (onActionStartId_) {
|
||||
pinchRecognizer->SetOnActionStart(*onActionStartId_);
|
||||
}
|
||||
|
||||
if (onActionUpdateId_) {
|
||||
pinchRecognizer->SetOnActionUpdate(*onActionUpdateId_);
|
||||
}
|
||||
|
||||
if (onActionEndId_) {
|
||||
pinchRecognizer->SetOnActionEnd(*onActionEndId_);
|
||||
}
|
||||
|
||||
if (onActionCancelId_) {
|
||||
pinchRecognizer->SetOnActionCancel(*onActionCancelId_);
|
||||
}
|
||||
|
||||
pinchRecognizer->SetPriority(priority_);
|
||||
pinchRecognizer->SetPriorityMask(gestureMask_);
|
||||
|
||||
return pinchRecognizer;
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
46
frameworks/core/components_ng/gestures/pinch_gesture.h
Normal file
46
frameworks/core/components_ng/gestures/pinch_gesture.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_PINCH_GESTURE_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_PINCH_GESTURE_H
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/geometry/offset.h"
|
||||
#include "base/memory/ace_type.h"
|
||||
#include "base/utils/macros.h"
|
||||
#include "core/components_ng/gestures/gesture_info.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
class ACE_EXPORT PinchGesture : public Gesture {
|
||||
DECLARE_ACE_TYPE(PinchGesture, Gesture);
|
||||
|
||||
public:
|
||||
PinchGesture(int32_t fingers, double distance) : Gesture(fingers), distance_(distance) {}
|
||||
~PinchGesture() override = default;
|
||||
|
||||
protected:
|
||||
RefPtr<GestureRecognizer> CreateRecognizer() override;
|
||||
|
||||
private:
|
||||
double distance_ = 0.0;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_PINCH_GESTURE_H
|
@ -0,0 +1,328 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "core/components_ng/gestures/recognizers/click_recognizer.h"
|
||||
|
||||
|
||||
#include "base/geometry/offset.h"
|
||||
#include "base/log/log.h"
|
||||
#include "base/ressched/ressched_report.h"
|
||||
#include "base/utils/utils.h"
|
||||
#include "core/pipeline_ng/pipeline_context.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
namespace {
|
||||
|
||||
int32_t MULTI_FINGER_TIMEOUT = 300;
|
||||
constexpr int32_t MULTI_FINGER_TIMEOUT_TOUCH = 300;
|
||||
constexpr int32_t MULTI_FINGER_TIMEOUT_MOUSE = 300;
|
||||
int32_t MULTI_TAP_TIMEOUT = 300;
|
||||
constexpr int32_t MULTI_TAP_TIMEOUT_TOUCH = 300;
|
||||
constexpr int32_t MULTI_TAP_TIMEOUT_MOUSE = 500;
|
||||
int32_t MULTI_TAP_SLOP = 100;
|
||||
constexpr int32_t MULTI_TAP_SLOP_TOUCH = 100;
|
||||
constexpr int32_t MULTI_TAP_SLOP_MOUSE = 15;
|
||||
#ifndef WEARABLE_PRODUCT
|
||||
double MAX_THRESHOLD = 20.0;
|
||||
constexpr double MAX_THRESHOLD_TOUCH = 20.0;
|
||||
#else
|
||||
constexpr double MAX_THRESHOLD = 12.0;
|
||||
constexpr double MAX_THRESHOLD_TOUCH = 12.0;
|
||||
#endif
|
||||
constexpr int32_t MAX_THRESHOLD_MOUSE = 15;
|
||||
constexpr int32_t MAX_TAP_FINGERS = 10;
|
||||
|
||||
} // namespace
|
||||
|
||||
void ClickRecognizer::InitGlobalValue(SourceType sourceType)
|
||||
{
|
||||
switch (sourceType) {
|
||||
case SourceType::TOUCH:
|
||||
MULTI_FINGER_TIMEOUT = MULTI_FINGER_TIMEOUT_TOUCH;
|
||||
MULTI_TAP_TIMEOUT = MULTI_TAP_TIMEOUT_TOUCH;
|
||||
MULTI_TAP_SLOP = MULTI_TAP_SLOP_TOUCH;
|
||||
MAX_THRESHOLD = MAX_THRESHOLD_TOUCH;
|
||||
break;
|
||||
case SourceType::MOUSE:
|
||||
case SourceType::TOUCH_PAD:
|
||||
MULTI_FINGER_TIMEOUT = MULTI_FINGER_TIMEOUT_MOUSE;
|
||||
MULTI_TAP_TIMEOUT = MULTI_TAP_TIMEOUT_MOUSE;
|
||||
MULTI_TAP_SLOP = MULTI_TAP_SLOP_MOUSE;
|
||||
MAX_THRESHOLD = MAX_THRESHOLD_MOUSE;
|
||||
break;
|
||||
default:
|
||||
LOGI("Unrecognized input source type: %{public}d", sourceType);
|
||||
}
|
||||
}
|
||||
|
||||
void ClickRecognizer::OnAccepted()
|
||||
{
|
||||
LOGI("Click gesture has been accepted!");
|
||||
ResSchedReport::GetInstance().ResSchedDataReport("click");
|
||||
if (onClick_) {
|
||||
TouchEvent touchPoint = {};
|
||||
if (!touchPoints_.empty()) {
|
||||
touchPoint = touchPoints_.begin()->second;
|
||||
}
|
||||
|
||||
ClickInfo info(touchPoint.id);
|
||||
info.SetTimeStamp(touchPoint.time);
|
||||
info.SetGlobalLocation(touchPoint.GetOffset()).SetLocalLocation(touchPoint.GetOffset() - coordinateOffset_);
|
||||
info.SetSourceDevice(deviceType_);
|
||||
info.SetDeviceId(deviceId_);
|
||||
onClick_(info);
|
||||
}
|
||||
|
||||
if (remoteMessage_) {
|
||||
TouchEvent touchPoint = {};
|
||||
if (!touchPoints_.empty()) {
|
||||
touchPoint = touchPoints_.begin()->second;
|
||||
}
|
||||
|
||||
ClickInfo info(touchPoint.id);
|
||||
info.SetTimeStamp(touchPoint.time);
|
||||
info.SetGlobalLocation(touchPoint.GetOffset()).SetLocalLocation(touchPoint.GetOffset() - coordinateOffset_);
|
||||
remoteMessage_(info);
|
||||
}
|
||||
SetFingerList(touchPoints_, coordinateOffset_, fingerList_);
|
||||
SendCallbackMsg(onAction_);
|
||||
Reset();
|
||||
}
|
||||
|
||||
void ClickRecognizer::OnRejected()
|
||||
{
|
||||
LOGD("click gesture has been rejected!");
|
||||
Reset();
|
||||
}
|
||||
|
||||
void ClickRecognizer::HandleTouchDownEvent(const TouchEvent& event)
|
||||
{
|
||||
InitGlobalValue(event.sourceType);
|
||||
LOGD("click recognizer receives touch down event, begin to detect click event");
|
||||
if (fingers_ > MAX_TAP_FINGERS) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If number of fingers which put on the screen more than fingers_,
|
||||
// the gesture will be rejected when one of them touch up.
|
||||
if (pointsCount_ == fingers_) {
|
||||
pointsCount_++;
|
||||
LOGE("number of fingers put on the screen more than %{public}d, current fingers is %{public}d",
|
||||
fingers_, pointsCount_);
|
||||
return;
|
||||
}
|
||||
|
||||
if (state_ == DetectState::READY) {
|
||||
if (tappedCount_ > 0 && pointsCount_ == 0) {
|
||||
tapDeadlineTimer_.Cancel();
|
||||
}
|
||||
AddToReferee(event.id, AceType::Claim(this));
|
||||
touchPoints_[event.id] = event;
|
||||
pointsCount_++;
|
||||
if (fingers_ > 1 && pointsCount_ == 1) {
|
||||
// waiting for multi-finger press
|
||||
DeadlineTimer(fingerDeadlineTimer_, MULTI_FINGER_TIMEOUT);
|
||||
}
|
||||
} else {
|
||||
LOGE("the state of click recognizer is not ready to receive touch down event, "
|
||||
"state is %{public}d, id is %{public}d",
|
||||
state_, event.id);
|
||||
}
|
||||
|
||||
if (pointsCount_ == fingers_) {
|
||||
// Turn off the multi-finger press deadline timer
|
||||
fingerDeadlineTimer_.Cancel();
|
||||
state_ = DetectState::DETECTING;
|
||||
equalsToFingers_ = true;
|
||||
if (ExceedSlop()) {
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ClickRecognizer::HandleTouchUpEvent(const TouchEvent& event)
|
||||
{
|
||||
InitGlobalValue(event.sourceType);
|
||||
LOGD("click recognizer receives touch up event");
|
||||
if (pointsCount_ > fingers_) {
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
return;
|
||||
}
|
||||
|
||||
auto itr = touchPoints_.find(event.id);
|
||||
if (itr == touchPoints_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state_ == DetectState::READY) {
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (state_ == DetectState::DETECTED) {
|
||||
return;
|
||||
}
|
||||
|
||||
touchPoints_[event.id] = event;
|
||||
pointsCount_--;
|
||||
|
||||
// Check whether multi-finger taps are completed in count_ times
|
||||
if (pointsCount_ == 0 && equalsToFingers_) {
|
||||
// Turn off the multi-finger lift deadline timer
|
||||
fingerDeadlineTimer_.Cancel();
|
||||
focusPoint_ = ComputeFocusPoint();
|
||||
tappedCount_++;
|
||||
|
||||
if (tappedCount_ == count_) {
|
||||
LOGI("this gesture is click, try to accept it");
|
||||
time_ = event.time;
|
||||
state_ = DetectState::DETECTED;
|
||||
if (useCatchMode_) {
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::ACCEPT);
|
||||
} else {
|
||||
OnAccepted();
|
||||
}
|
||||
return;
|
||||
}
|
||||
equalsToFingers_ = false;
|
||||
state_ = DetectState::READY;
|
||||
// waiting for multi-finger lift
|
||||
DeadlineTimer(tapDeadlineTimer_, MULTI_TAP_TIMEOUT);
|
||||
}
|
||||
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::PENDING);
|
||||
if (pointsCount_ < fingers_ && equalsToFingers_) {
|
||||
DeadlineTimer(fingerDeadlineTimer_, MULTI_FINGER_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
void ClickRecognizer::HandleTouchMoveEvent(const TouchEvent& event)
|
||||
{
|
||||
InitGlobalValue(event.sourceType);
|
||||
LOGD("click recognizer receives touch move event");
|
||||
auto itr = touchPoints_.find(event.id);
|
||||
if (itr == touchPoints_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Offset offset = event.GetOffset() - touchPoints_[event.id].GetOffset();
|
||||
if (offset.GetDistance() > MAX_THRESHOLD) {
|
||||
LOGD("this gesture is not click, try to reject it");
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
}
|
||||
}
|
||||
|
||||
void ClickRecognizer::HandleTouchCancelEvent(const TouchEvent& event)
|
||||
{
|
||||
InitGlobalValue(event.sourceType);
|
||||
LOGD("click recognizer receives touch cancel event");
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
}
|
||||
|
||||
void ClickRecognizer::HandleOverdueDeadline()
|
||||
{
|
||||
if (pointsCount_ < fingers_ || tappedCount_ < count_) {
|
||||
LOGD("the state is not detecting for accept multi-finger tap gesture");
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
}
|
||||
}
|
||||
|
||||
void ClickRecognizer::DeadlineTimer(CancelableCallback<void()>& deadlineTimer, int32_t time)
|
||||
{
|
||||
auto context = PipelineContext::GetCurrentContext();
|
||||
CHECK_NULL_VOID(context);
|
||||
|
||||
auto&& callback = [weakPtr = AceType::WeakClaim(this)]() {
|
||||
auto refPtr = weakPtr.Upgrade();
|
||||
if (refPtr) {
|
||||
refPtr->HandleOverdueDeadline();
|
||||
} else {
|
||||
LOGE("fail to handle overdue deadline due to context is nullptr");
|
||||
}
|
||||
};
|
||||
|
||||
deadlineTimer.Reset(callback);
|
||||
auto taskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
|
||||
taskExecutor.PostDelayedTask(deadlineTimer, time);
|
||||
}
|
||||
|
||||
void ClickRecognizer::Reset()
|
||||
{
|
||||
touchPoints_.clear();
|
||||
fingerList_.clear();
|
||||
pointsCount_ = 0;
|
||||
equalsToFingers_ = false;
|
||||
tappedCount_ = 0;
|
||||
state_ = DetectState::READY;
|
||||
}
|
||||
|
||||
Offset ClickRecognizer::ComputeFocusPoint()
|
||||
{
|
||||
Offset sumOfPoints;
|
||||
for (auto& element : touchPoints_) {
|
||||
sumOfPoints = sumOfPoints + element.second.GetOffset();
|
||||
}
|
||||
Offset focusPoint = sumOfPoints / touchPoints_.size();
|
||||
return focusPoint;
|
||||
}
|
||||
|
||||
bool ClickRecognizer::ExceedSlop()
|
||||
{
|
||||
if (tappedCount_ > 0 && tappedCount_ < count_) {
|
||||
Offset currentFocusPoint = ComputeFocusPoint();
|
||||
Offset slop = currentFocusPoint - focusPoint_;
|
||||
if (GreatOrEqual(slop.GetDistance(), MULTI_TAP_SLOP)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ClickRecognizer::SendCallbackMsg(const std::unique_ptr<GestureEventFunc>& onAction)
|
||||
{
|
||||
if (onAction && *onAction) {
|
||||
GestureEvent info;
|
||||
info.SetTimeStamp(time_);
|
||||
info.SetFingerList(fingerList_);
|
||||
TouchEvent touchPoint = {};
|
||||
if (!touchPoints_.empty()) {
|
||||
touchPoint = touchPoints_.begin()->second;
|
||||
}
|
||||
info.SetGlobalLocation(touchPoint.GetOffset()).SetLocalLocation(touchPoint.GetOffset() - coordinateOffset_);
|
||||
info.SetSourceDevice(deviceType_);
|
||||
info.SetDeviceId(deviceId_);
|
||||
(*onAction)(info);
|
||||
}
|
||||
}
|
||||
|
||||
bool ClickRecognizer::ReconcileFrom(const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
RefPtr<ClickRecognizer> curr = AceType::DynamicCast<ClickRecognizer>(recognizer);
|
||||
if (!curr) {
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (curr->count_ != count_ || curr->fingers_ != fingers_ || curr->priorityMask_ != priorityMask_) {
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
onAction_ = std::move(curr->onAction_);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_CLICK_RECOGNIZER_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_CLICK_RECOGNIZER_H
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "base/thread/cancelable_callback.h"
|
||||
#include "core/components_ng/gestures/gesture_info.h"
|
||||
#include "core/components_ng/gestures/recognizers/multi_fingers_recognizer.h"
|
||||
#include "core/focus/focus_node.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
class ClickRecognizer : public MultiFingersRecognizer {
|
||||
DECLARE_ACE_TYPE(ClickRecognizer, MultiFingersRecognizer);
|
||||
|
||||
public:
|
||||
ClickRecognizer() = default;
|
||||
ClickRecognizer(int32_t fingers, int32_t count) : count_(count)
|
||||
{
|
||||
fingers_ = fingers;
|
||||
}
|
||||
~ClickRecognizer() override = default;
|
||||
|
||||
void OnAccepted() override;
|
||||
void OnRejected() override;
|
||||
|
||||
void SetOnClick(const ClickCallback& onClick)
|
||||
{
|
||||
onClick_ = onClick;
|
||||
}
|
||||
|
||||
void SetRemoteMessage(const ClickCallback& remoteMessage)
|
||||
{
|
||||
remoteMessage_ = remoteMessage;
|
||||
}
|
||||
|
||||
void SetUseCatchMode(bool useCatchMode)
|
||||
{
|
||||
useCatchMode_ = useCatchMode;
|
||||
}
|
||||
|
||||
private:
|
||||
void HandleTouchDownEvent(const TouchEvent& event) override;
|
||||
void HandleTouchUpEvent(const TouchEvent& event) override;
|
||||
void HandleTouchMoveEvent(const TouchEvent& event) override;
|
||||
void HandleTouchCancelEvent(const TouchEvent& event) override;
|
||||
bool ReconcileFrom(const RefPtr<GestureRecognizer>& recognizer) override;
|
||||
void HandleOverdueDeadline();
|
||||
void DeadlineTimer(CancelableCallback<void()>& deadlineTimer, int32_t time);
|
||||
Offset ComputeFocusPoint();
|
||||
void Reset();
|
||||
void SendCallbackMsg(const std::unique_ptr<GestureEventFunc>& callback);
|
||||
bool ExceedSlop();
|
||||
void InitGlobalValue(SourceType deviceId);
|
||||
|
||||
int32_t count_ = 1;
|
||||
// number of fingers which put on the screen
|
||||
int32_t pointsCount_ = 0;
|
||||
int32_t tappedCount_ = 0;
|
||||
// Check whether the pointsCount_ has reached the configured value
|
||||
bool equalsToFingers_ = false;
|
||||
// the time when gesture recognition is successful
|
||||
TimeStamp time_;
|
||||
Offset focusPoint_;
|
||||
ClickCallback onClick_;
|
||||
ClickCallback remoteMessage_;
|
||||
bool useCatchMode_ = true;
|
||||
CancelableCallback<void()> fingerDeadlineTimer_;
|
||||
CancelableCallback<void()> tapDeadlineTimer_;
|
||||
std::map<int32_t, TouchEvent> touchPoints_;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_CLICK_RECOGNIZER_H
|
@ -0,0 +1,268 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "core/components_ng/gestures/recognizers/exclusive_recognizer.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "base/geometry/offset.h"
|
||||
#include "base/log/log.h"
|
||||
#include "base/memory/ace_type.h"
|
||||
#include "core/components_ng/gestures/gesture_referee.h"
|
||||
#include "core/components_ng/gestures/recognizers/click_recognizer.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
void ExclusiveRecognizer::OnAccepted(size_t touchId)
|
||||
{
|
||||
LOGD("the exclusive gesture recognizer has been accepted, touch id %{public}zu", touchId);
|
||||
if (refereePointers_.find(touchId) == refereePointers_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
refereePointers_.erase(touchId);
|
||||
|
||||
if (!activeRecognizer_) {
|
||||
return;
|
||||
}
|
||||
|
||||
activeRecognizer_->SetCoordinateOffset(coordinateOffset_);
|
||||
activeRecognizer_->OnAccepted(touchId);
|
||||
activeRecognizer_->SetRefereeState(RefereeState::SUCCEED);
|
||||
|
||||
for (auto& recognizer : recognizers_) {
|
||||
if (recognizer != activeRecognizer_) {
|
||||
LOGD("the sub gesture %{public}s is rejected because one is accepted", AceType::TypeName(recognizer));
|
||||
recognizer->OnRejected(touchId);
|
||||
recognizer->SetRefereeState(RefereeState::FAIL);
|
||||
}
|
||||
}
|
||||
|
||||
if (AceType::InstanceOf<ClickRecognizer>(activeRecognizer_)) {
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
||||
void ExclusiveRecognizer::OnRejected(size_t touchId)
|
||||
{
|
||||
if (refereePointers_.find(touchId) == refereePointers_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
refereePointers_.erase(touchId);
|
||||
|
||||
LOGD("the exclusive gesture recognizer has been rejected! the touch id is %{public}zu", touchId);
|
||||
for (auto& recognizer : recognizers_) {
|
||||
if (recognizer->GetRefereeState() == RefereeState::FAIL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
recognizer->OnRejected(touchId);
|
||||
if (recognizer->GetDetectState() == DetectState::READY) {
|
||||
recognizer->SetRefereeState(RefereeState::FAIL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ExclusiveRecognizer::OnPending(size_t touchId)
|
||||
{
|
||||
if (refereePointers_.find(touchId) == refereePointers_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOGD("the exclusive gesture recognizer is pending! the touch id is %{public}zu", touchId);
|
||||
for (auto& recognizer : recognizers_) {
|
||||
if (recognizer->GetRefereeState() == RefereeState::PENDING) {
|
||||
recognizer->OnPending(touchId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ExclusiveRecognizer::HandleEvent(const TouchEvent& point)
|
||||
{
|
||||
switch (point.type) {
|
||||
case TouchType::MOVE:
|
||||
case TouchType::DOWN:
|
||||
case TouchType::UP:
|
||||
case TouchType::CANCEL:
|
||||
if (activeRecognizer_) {
|
||||
activeRecognizer_->HandleEvent(point);
|
||||
} else {
|
||||
for (auto& recognizer : recognizers_) {
|
||||
recognizer->HandleEvent(point);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOGW("exclusive recognizer received unknown touch type");
|
||||
break;
|
||||
}
|
||||
|
||||
if (activeRecognizer_ && activeRecognizer_->GetDetectState() != DetectState::DETECTED) {
|
||||
LOGD("sub detected gesture has finished, change the exclusive recognizer to be ready");
|
||||
Reset();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ExclusiveRecognizer::OnFlushTouchEventsBegin()
|
||||
{
|
||||
for (auto& recognizer : recognizers_) {
|
||||
recognizer->OnFlushTouchEventsBegin();
|
||||
}
|
||||
}
|
||||
|
||||
void ExclusiveRecognizer::OnFlushTouchEventsEnd()
|
||||
{
|
||||
for (auto& recognizer : recognizers_) {
|
||||
recognizer->OnFlushTouchEventsEnd();
|
||||
}
|
||||
}
|
||||
|
||||
void ExclusiveRecognizer::BatchAdjudicate(
|
||||
const std::set<size_t>& touchIds, const RefPtr<GestureRecognizer>& recognizer, GestureDisposal disposal)
|
||||
{
|
||||
// any sub recognizer accept itself will drive to detected state
|
||||
if (state_ == DetectState::DETECTED) {
|
||||
LOGD("exclusive gesture recognizer is in detected state, do not process disposal");
|
||||
return;
|
||||
}
|
||||
|
||||
if (disposal == GestureDisposal::ACCEPT) {
|
||||
AcceptSubGesture(recognizer);
|
||||
return;
|
||||
}
|
||||
|
||||
if (disposal == GestureDisposal::PENDING) {
|
||||
if (CheckNeedBlocked(recognizer)) {
|
||||
recognizer->SetRefereeState(RefereeState::BLOCKED);
|
||||
} else {
|
||||
recognizer->SetRefereeState(RefereeState::PENDING);
|
||||
MultiFingersRecognizer::Adjudicate(AceType::Claim(this), GestureDisposal::PENDING);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// process reject disposal
|
||||
LOGD("sub gesture recognizer %{public}s ask for reject", AceType::TypeName(recognizer));
|
||||
RefereeState prevState = recognizer->GetRefereeState();
|
||||
for (auto touchId : touchIds) {
|
||||
recognizer->OnRejected(touchId);
|
||||
}
|
||||
recognizer->SetRefereeState(RefereeState::FAIL);
|
||||
|
||||
if (prevState == RefereeState::PENDING) {
|
||||
for (auto& tmpRecognizer : recognizers_) {
|
||||
if (tmpRecognizer->GetRefereeState() == RefereeState::BLOCKED &&
|
||||
tmpRecognizer->GetDetectState() == DetectState::DETECTED) {
|
||||
activeRecognizer_ = tmpRecognizer;
|
||||
state_ = DetectState::DETECTED;
|
||||
MultiFingersRecognizer::Adjudicate(AceType::Claim(this), GestureDisposal::ACCEPT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (CheckAllFailed()) {
|
||||
LOGD("all gesture recognizers are rejected, adjudicate reject");
|
||||
MultiFingersRecognizer::Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
||||
void ExclusiveRecognizer::AddToReferee(size_t touchId, const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
recognizer->SetRefereeState(RefereeState::DETECTING);
|
||||
|
||||
if (state_ == DetectState::READY) {
|
||||
state_ = DetectState::DETECTING;
|
||||
}
|
||||
|
||||
if (state_ == DetectState::DETECTING) {
|
||||
MultiFingersRecognizer::AddToReferee(touchId, AceType::Claim(this));
|
||||
}
|
||||
}
|
||||
|
||||
bool ExclusiveRecognizer::CheckNeedBlocked(const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
auto pendingMember = std::find_if(
|
||||
std::begin(recognizers_), std::end(recognizers_), [recognizer](const RefPtr<GestureRecognizer>& member) {
|
||||
return (member != recognizer) && (member->GetRefereeState() == RefereeState::PENDING);
|
||||
});
|
||||
if (pendingMember != recognizers_.end()) {
|
||||
LOGD("exclusive gesture recognizer detected pending gesture in members");
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ExclusiveRecognizer::AcceptSubGesture(const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
LOGD("sub gesture recognizer %{public}s ask for accept", AceType::TypeName(recognizer));
|
||||
if (CheckNeedBlocked(recognizer)) {
|
||||
recognizer->SetRefereeState(RefereeState::BLOCKED);
|
||||
return;
|
||||
}
|
||||
|
||||
activeRecognizer_ = recognizer;
|
||||
state_ = DetectState::DETECTED;
|
||||
MultiFingersRecognizer::Adjudicate(AceType::Claim(this), GestureDisposal::ACCEPT);
|
||||
}
|
||||
|
||||
bool ExclusiveRecognizer::CheckAllFailed()
|
||||
{
|
||||
auto notFailMember = std::find_if(std::begin(recognizers_), std::end(recognizers_),
|
||||
[](const RefPtr<GestureRecognizer>& member) { return member->GetRefereeState() != RefereeState::FAIL; });
|
||||
|
||||
return notFailMember == recognizers_.end();
|
||||
}
|
||||
|
||||
void ExclusiveRecognizer::Reset()
|
||||
{
|
||||
state_ = DetectState::READY;
|
||||
activeRecognizer_ = nullptr;
|
||||
for (auto& recognizer : recognizers_) {
|
||||
recognizer->SetRefereeState(RefereeState::DETECTING);
|
||||
}
|
||||
}
|
||||
|
||||
bool ExclusiveRecognizer::ReconcileFrom(const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
RefPtr<ExclusiveRecognizer> curr = AceType::DynamicCast<ExclusiveRecognizer>(recognizer);
|
||||
if (!curr) {
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (recognizers_.size() != curr->recognizers_.size() || curr->priorityMask_ != priorityMask_) {
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
auto currIter = curr->recognizers_.begin();
|
||||
|
||||
for (auto iter = recognizers_.begin(); iter != recognizers_.end(); iter++, currIter++) {
|
||||
if (!(*iter)->ReconcileFrom(*currIter)) {
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_EXCLUSIVE_RECOGNIZER_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_EXCLUSIVE_RECOGNIZER_H
|
||||
|
||||
#include <functional>
|
||||
#include <set>
|
||||
|
||||
#include "core/components_ng/gestures/gesture_info.h"
|
||||
#include "core/components_ng/gestures/recognizers/multi_fingers_recognizer.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
// ExclusiveRecognizer identifies gesture exclusive.
|
||||
class ACE_EXPORT ExclusiveRecognizer : public MultiFingersRecognizer {
|
||||
DECLARE_ACE_TYPE(ExclusiveRecognizer, MultiFingersRecognizer);
|
||||
|
||||
public:
|
||||
explicit ExclusiveRecognizer(const std::vector<RefPtr<GestureRecognizer>>& recognizers)
|
||||
{
|
||||
for (auto& recognizer : recognizers) {
|
||||
recognizer->SetGestureGroup(AceType::WeakClaim(this));
|
||||
recognizers_.emplace_back(recognizer);
|
||||
}
|
||||
}
|
||||
|
||||
explicit ExclusiveRecognizer(std::list<RefPtr<GestureRecognizer>>&& recognizers)
|
||||
{
|
||||
recognizers_.swap(recognizers);
|
||||
for (auto& recognizer : recognizers_) {
|
||||
recognizer->SetGestureGroup(AceType::WeakClaim(this));
|
||||
}
|
||||
}
|
||||
|
||||
~ExclusiveRecognizer() override = default;
|
||||
void OnAccepted(size_t touchId) override;
|
||||
void OnRejected(size_t touchId) override;
|
||||
void OnPending(size_t touchId) override;
|
||||
bool HandleEvent(const TouchEvent& point) override;
|
||||
void OnFlushTouchEventsBegin() override;
|
||||
void OnFlushTouchEventsEnd() override;
|
||||
|
||||
private:
|
||||
void HandleTouchDownEvent(const TouchEvent& event) override {};
|
||||
void HandleTouchUpEvent(const TouchEvent& event) override {};
|
||||
void HandleTouchMoveEvent(const TouchEvent& event) override {};
|
||||
void HandleTouchCancelEvent(const TouchEvent& event) override {};
|
||||
void BatchAdjudicate(const std::set<size_t>& touchIds, const RefPtr<GestureRecognizer>& recognizer,
|
||||
GestureDisposal disposal) override;
|
||||
void AddToReferee(size_t touchId, const RefPtr<GestureRecognizer>& recognizer) override;
|
||||
bool ReconcileFrom(const RefPtr<GestureRecognizer>& recognizer) override;
|
||||
bool CheckNeedBlocked(const RefPtr<GestureRecognizer>& recognizer);
|
||||
void AcceptSubGesture(const RefPtr<GestureRecognizer>& recognizer);
|
||||
bool CheckAllFailed();
|
||||
void Reset();
|
||||
|
||||
std::list<RefPtr<GestureRecognizer>> recognizers_;
|
||||
RefPtr<GestureRecognizer> activeRecognizer_;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_EXCLUSIVE_RECOGNIZER_H
|
@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "core/components_ng/gestures/recognizers/gesture_recognizer.h"
|
||||
|
||||
#include "base/log/log.h"
|
||||
#include "core/common/container.h"
|
||||
#include "core/event/axis_event.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
namespace {
|
||||
|
||||
RefPtr<GestureReferee> GetCurrentGestureReferee()
|
||||
{
|
||||
auto context = PipelineContext::GetCurrentContext();
|
||||
CHECK_NULL_RETURN(context, nullptr);
|
||||
|
||||
auto eventManager = context->GetEventManager();
|
||||
if (!eventManager) {
|
||||
return nullptr;
|
||||
}
|
||||
return eventManager->GetGestureRefereeNG();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool GestureRecognizer::HandleEvent(const TouchEvent& point)
|
||||
{
|
||||
switch (point.type) {
|
||||
case TouchType::MOVE:
|
||||
HandleTouchMoveEvent(point);
|
||||
break;
|
||||
case TouchType::DOWN:
|
||||
deviceId_ = point.deviceId;
|
||||
deviceType_ = point.sourceType;
|
||||
HandleTouchDownEvent(point);
|
||||
break;
|
||||
case TouchType::UP:
|
||||
HandleTouchUpEvent(point);
|
||||
break;
|
||||
case TouchType::CANCEL:
|
||||
HandleTouchCancelEvent(point);
|
||||
break;
|
||||
default:
|
||||
LOGW("unknown touch type");
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GestureRecognizer::HandleEvent(const AxisEvent& event)
|
||||
{
|
||||
switch (event.action) {
|
||||
case AxisAction::BEGIN:
|
||||
deviceId_ = event.deviceId;
|
||||
deviceType_ = event.sourceType;
|
||||
HandleTouchDownEvent(event);
|
||||
case AxisAction::UPDATE:
|
||||
HandleTouchMoveEvent(event);
|
||||
break;
|
||||
case AxisAction::END:
|
||||
HandleTouchUpEvent(event);
|
||||
break;
|
||||
default:
|
||||
HandleTouchCancelEvent(event);
|
||||
LOGW("unknown touch type");
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void GestureRecognizer::AddToReferee(size_t touchId, const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
auto gestureGroup = gestureGroup_.Upgrade();
|
||||
if (gestureGroup) {
|
||||
gestureGroup->AddToReferee(touchId, recognizer);
|
||||
return;
|
||||
}
|
||||
auto referee = GetCurrentGestureReferee();
|
||||
if (referee) {
|
||||
referee->AddGestureRecognizer(touchId, recognizer);
|
||||
}
|
||||
}
|
||||
|
||||
void GestureRecognizer::DelFromReferee(size_t touchId, const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
auto gestureGroup = gestureGroup_.Upgrade();
|
||||
if (gestureGroup) {
|
||||
gestureGroup->DelFromReferee(touchId, recognizer);
|
||||
return;
|
||||
}
|
||||
auto referee = GetCurrentGestureReferee();
|
||||
if (referee) {
|
||||
referee->DelGestureRecognizer(touchId, recognizer);
|
||||
}
|
||||
}
|
||||
|
||||
void GestureRecognizer::BatchAdjudicate(
|
||||
const std::set<size_t>& touchIds, const RefPtr<GestureRecognizer>& recognizer, GestureDisposal disposal)
|
||||
{
|
||||
auto gestureGroup = gestureGroup_.Upgrade();
|
||||
if (gestureGroup) {
|
||||
gestureGroup->BatchAdjudicate(touchIds, recognizer, disposal);
|
||||
return;
|
||||
}
|
||||
|
||||
std::set<size_t> copyIds = touchIds;
|
||||
auto referee = GetCurrentGestureReferee();
|
||||
if (!referee) {
|
||||
LOGW("No GestureReferee in GestureRecoginer.");
|
||||
return;
|
||||
}
|
||||
for (auto pointerId : copyIds) {
|
||||
LOGD("Adjudicate gesture recognizer, touch id %{public}zu, disposal %{public}d", pointerId, disposal);
|
||||
referee->Adjudicate(pointerId, recognizer, disposal);
|
||||
}
|
||||
}
|
||||
} // namespace OHOS::Ace::NG
|
@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_GESTURE_RECOGNIZER_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_GESTURE_RECOGNIZER_H
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
|
||||
#include "core/components_ng/gestures/gesture_info.h"
|
||||
#include "core/components_ng/gestures/gesture_referee.h"
|
||||
#include "core/event/axis_event.h"
|
||||
#include "core/event/touch_event.h"
|
||||
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
enum class DetectState { READY, DETECTING, DETECTED };
|
||||
|
||||
enum class RefereeState { DETECTING, PENDING, BLOCKED, SUCCEED, FAIL };
|
||||
|
||||
class ACE_EXPORT GestureRecognizer : public TouchEventTarget {
|
||||
DECLARE_ACE_TYPE(GestureRecognizer, TouchEventTarget)
|
||||
|
||||
public:
|
||||
// Called when request of handling gesture sequence is accepted by gesture referee.
|
||||
virtual void OnAccepted(size_t touchId) = 0;
|
||||
|
||||
// Called when request of handling gesture sequence is rejected by gesture referee.
|
||||
virtual void OnRejected(size_t touchId) = 0;
|
||||
|
||||
// Called when request of handling gesture sequence is rejected by gesture referee.
|
||||
virtual void OnPending(size_t touchId) {}
|
||||
|
||||
// Reconiciles the state from the given recognizer into this. The
|
||||
// implementation must check that the given recognizer type matches the
|
||||
// current one. The return value should be false if the reconciliation fails
|
||||
// and true if it succeeds
|
||||
virtual bool ReconcileFrom(const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DispatchEvent(const TouchEvent& point) override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool HandleEvent(const TouchEvent& point) override;
|
||||
bool HandleEvent(const AxisEvent& event) override;
|
||||
|
||||
GesturePriority GetPriority() const
|
||||
{
|
||||
return priority_;
|
||||
}
|
||||
|
||||
void SetPriority(GesturePriority priority)
|
||||
{
|
||||
priority_ = priority;
|
||||
}
|
||||
|
||||
GestureMask GetPriorityMask() const
|
||||
{
|
||||
return priorityMask_;
|
||||
}
|
||||
|
||||
void SetPriorityMask(GestureMask priorityMask)
|
||||
{
|
||||
priorityMask_ = priorityMask;
|
||||
}
|
||||
|
||||
RefereeState GetRefereeState() const
|
||||
{
|
||||
return refereeState_;
|
||||
}
|
||||
|
||||
void SetRefereeState(RefereeState refereeState)
|
||||
{
|
||||
refereeState_ = refereeState;
|
||||
}
|
||||
|
||||
DetectState GetDetectState() const
|
||||
{
|
||||
return state_;
|
||||
}
|
||||
|
||||
void SetGestureGroup(const WeakPtr<GestureRecognizer>& gestureGroup)
|
||||
{
|
||||
gestureGroup_ = gestureGroup;
|
||||
}
|
||||
|
||||
void SetOnAction(const GestureEventFunc& onAction)
|
||||
{
|
||||
onAction_ = std::make_unique<GestureEventFunc>(onAction);
|
||||
}
|
||||
|
||||
void SetOnActionStart(const GestureEventFunc& onActionStart)
|
||||
{
|
||||
onActionStart_ = std::make_unique<GestureEventFunc>(onActionStart);
|
||||
}
|
||||
|
||||
void SetOnActionUpdate(const GestureEventFunc& onActionUpdate)
|
||||
{
|
||||
onActionUpdate_ = std::make_unique<GestureEventFunc>(onActionUpdate);
|
||||
}
|
||||
|
||||
void SetOnActionEnd(const GestureEventFunc& onActionEnd)
|
||||
{
|
||||
onActionEnd_ = std::make_unique<GestureEventFunc>(onActionEnd);
|
||||
}
|
||||
|
||||
void SetOnActionCancel(const GestureEventNoParameter& onActionCancel)
|
||||
{
|
||||
onActionCancel_ = std::make_unique<GestureEventNoParameter>(onActionCancel);
|
||||
}
|
||||
|
||||
inline void SendCancelMsg()
|
||||
{
|
||||
if (onActionCancel_ && *onActionCancel_) {
|
||||
(*onActionCancel_)();
|
||||
}
|
||||
}
|
||||
|
||||
void SetIsExternalGesture(bool isExternalGesture)
|
||||
{
|
||||
isExternalGesture_ = isExternalGesture;
|
||||
}
|
||||
|
||||
bool GetIsExternalGesture() const
|
||||
{
|
||||
return isExternalGesture_;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void HandleTouchDownEvent(const TouchEvent& event) = 0;
|
||||
virtual void HandleTouchUpEvent(const TouchEvent& event) = 0;
|
||||
virtual void HandleTouchMoveEvent(const TouchEvent& event) = 0;
|
||||
virtual void HandleTouchCancelEvent(const TouchEvent& event) = 0;
|
||||
virtual void HandleTouchDownEvent(const AxisEvent& event) {}
|
||||
virtual void HandleTouchUpEvent(const AxisEvent& event) {}
|
||||
virtual void HandleTouchMoveEvent(const AxisEvent& event) {}
|
||||
virtual void HandleTouchCancelEvent(const AxisEvent& event) {}
|
||||
|
||||
virtual void AddToReferee(size_t touchId, const RefPtr<GestureRecognizer>& recognizer);
|
||||
virtual void DelFromReferee(size_t touchId, const RefPtr<GestureRecognizer>& recognizer);
|
||||
virtual void BatchAdjudicate(
|
||||
const std::set<size_t>& touchIds, const RefPtr<GestureRecognizer>& recognizer, GestureDisposal disposal);
|
||||
|
||||
DetectState state_ { DetectState::READY };
|
||||
RefereeState refereeState_ { RefereeState::DETECTING };
|
||||
GesturePriority priority_ = GesturePriority::Low;
|
||||
GestureMask priorityMask_ = GestureMask::Normal;
|
||||
|
||||
int32_t fingers_ = 1;
|
||||
std::list<FingerInfo> fingerList_;
|
||||
bool isExternalGesture_ = false;
|
||||
|
||||
std::unique_ptr<GestureEventFunc> onAction_;
|
||||
std::unique_ptr<GestureEventFunc> onActionStart_;
|
||||
std::unique_ptr<GestureEventFunc> onActionUpdate_;
|
||||
std::unique_ptr<GestureEventFunc> onActionEnd_;
|
||||
std::unique_ptr<GestureEventNoParameter> onActionCancel_;
|
||||
|
||||
int64_t deviceId_ = 0;
|
||||
SourceType deviceType_ = SourceType::NONE;
|
||||
|
||||
private:
|
||||
WeakPtr<GestureRecognizer> gestureGroup_;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_GESTURE_RECOGNIZER_H
|
@ -0,0 +1,288 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "core/components_ng/gestures/recognizers/long_press_recognizer.h"
|
||||
|
||||
#include "base/utils/utils.h"
|
||||
#include "core/components_ng/gestures/gesture_referee.h"
|
||||
#include "core/event/ace_events.h"
|
||||
#include "core/pipeline_ng/pipeline_context.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
namespace {
|
||||
|
||||
constexpr double MAX_THRESHOLD = 15.0;
|
||||
constexpr int32_t MAX_FINGERS = 10;
|
||||
} // namespace
|
||||
|
||||
void LongPressRecognizer::OnAccepted()
|
||||
{
|
||||
LOGI("long press gesture has been accepted!");
|
||||
|
||||
if (onLongPress_ && !touchMap_.empty()) {
|
||||
TouchEvent trackPoint = touchMap_.begin()->second;
|
||||
LongPressInfo info(trackPoint.id);
|
||||
info.SetTimeStamp(time_);
|
||||
info.SetScreenLocation(trackPoint.GetScreenOffset());
|
||||
info.SetGlobalLocation(trackPoint.GetOffset()).SetLocalLocation(trackPoint.GetOffset() - coordinateOffset_);
|
||||
info.SetTarget(GetEventTarget().value_or(EventTarget()));
|
||||
onLongPress_(info);
|
||||
}
|
||||
|
||||
SetFingerList(touchMap_, coordinateOffset_, fingerList_);
|
||||
SendCallbackMsg(onActionUpdate_, false);
|
||||
SendCallbackMsg(onAction_, false);
|
||||
if (repeat_) {
|
||||
StartRepeatTimer();
|
||||
}
|
||||
|
||||
if (pendingEnd_) {
|
||||
SendCallbackMsg(onActionEnd_, false);
|
||||
Reset();
|
||||
} else if (pendingCancel_) {
|
||||
SendCancelMsg();
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
||||
void LongPressRecognizer::OnRejected()
|
||||
{
|
||||
LOGI("long press gesture has been rejected!");
|
||||
Reset();
|
||||
}
|
||||
|
||||
void LongPressRecognizer::HandleTouchDownEvent(const TouchEvent& event)
|
||||
{
|
||||
if (isDisableMouseLeft_ && event.sourceType == SourceType::MOUSE) {
|
||||
LOGI("mouse left button is disabled for long press recognizer.");
|
||||
return;
|
||||
}
|
||||
if (fingers_ > MAX_FINGERS) {
|
||||
return;
|
||||
}
|
||||
LOGD("long press recognizer receives touch down event, begin to detect long press event");
|
||||
int32_t curDuration = duration_;
|
||||
if (isForDrag_ && event.sourceType == SourceType::MOUSE) {
|
||||
curDuration = 0;
|
||||
}
|
||||
if ((touchRestrict_.forbiddenType & TouchRestrict::LONG_PRESS) == TouchRestrict::LONG_PRESS) {
|
||||
LOGI("the long press is forbidden");
|
||||
return;
|
||||
}
|
||||
globalPoint_ = Point(event.x, event.y);
|
||||
if (state_ == DetectState::READY) {
|
||||
touchMap_[event.id] = event;
|
||||
pointsCount_++;
|
||||
AddToReferee(event.id, AceType::Claim(this));
|
||||
if (pointsCount_ == fingers_) {
|
||||
state_ = DetectState::DETECTING;
|
||||
|
||||
if (useCatchMode_) {
|
||||
DeadlineTimer(curDuration, false);
|
||||
} else {
|
||||
DeadlineTimer(curDuration, true);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LOGW("the state is not ready for detecting long press gesture, state id %{public}d, id is %{public}d",
|
||||
state_, event.id);
|
||||
}
|
||||
}
|
||||
|
||||
void LongPressRecognizer::HandleTouchUpEvent(const TouchEvent& event)
|
||||
{
|
||||
LOGD("long press recognizer receives touch up event");
|
||||
auto it = touchMap_.find(event.id);
|
||||
if (it == touchMap_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state_ != DetectState::DETECTED) {
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (refereeState_ == RefereeState::SUCCEED) {
|
||||
SendCallbackMsg(onActionUpdate_, false);
|
||||
SendCallbackMsg(onActionEnd_, false);
|
||||
Reset();
|
||||
} else {
|
||||
pendingEnd_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void LongPressRecognizer::HandleTouchMoveEvent(const TouchEvent& event)
|
||||
{
|
||||
LOGD("long press recognizer receives touch move event");
|
||||
auto it = touchMap_.find(event.id);
|
||||
if (it == touchMap_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Offset offset = event.GetOffset() - touchMap_[event.id].GetOffset();
|
||||
if (offset.GetDistance() > MAX_THRESHOLD) {
|
||||
if (state_ == DetectState::DETECTED && refereeState_ == RefereeState::SUCCEED) {
|
||||
SendCallbackMsg(onActionEnd_, false);
|
||||
Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
LOGD("this gesture is not long press, try to reject it");
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
return;
|
||||
}
|
||||
|
||||
time_ = event.time;
|
||||
}
|
||||
|
||||
void LongPressRecognizer::HandleTouchCancelEvent(const TouchEvent& event)
|
||||
{
|
||||
LOGD("long press recognizer receives touch cancel event");
|
||||
if (state_ == DetectState::READY || state_ == DetectState::DETECTING) {
|
||||
LOGD("cancel long press gesture detect, try to reject it");
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
SendCancelMsg();
|
||||
return;
|
||||
}
|
||||
|
||||
if (refereeState_ == RefereeState::SUCCEED) {
|
||||
SendCancelMsg();
|
||||
Reset();
|
||||
} else {
|
||||
pendingCancel_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void LongPressRecognizer::HandleOverdueDeadline()
|
||||
{
|
||||
if (state_ == DetectState::DETECTING) {
|
||||
LOGI("this gesture is long press, try to accept it");
|
||||
state_ = DetectState::DETECTED;
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::ACCEPT);
|
||||
SendCallbackMsg(onActionUpdate_, false);
|
||||
} else {
|
||||
LOGW("the state is not detecting for accept long press gesture");
|
||||
}
|
||||
}
|
||||
|
||||
void LongPressRecognizer::DeadlineTimer(int32_t time, bool isAccept)
|
||||
{
|
||||
auto context = PipelineContext::GetCurrentContext();
|
||||
CHECK_NULL_VOID(context);
|
||||
|
||||
auto&& callback = [weakPtr = AceType::WeakClaim(this), isAccept]() {
|
||||
auto refPtr = weakPtr.Upgrade();
|
||||
if (refPtr) {
|
||||
if (!isAccept) {
|
||||
refPtr->HandleOverdueDeadline();
|
||||
} else {
|
||||
refPtr->OnAccepted();
|
||||
}
|
||||
} else {
|
||||
LOGI("fail to handle overdue deadline due to context is nullptr");
|
||||
}
|
||||
};
|
||||
deadlineTimer_.Reset(callback);
|
||||
auto taskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
|
||||
taskExecutor.PostDelayedTask(deadlineTimer_, time);
|
||||
}
|
||||
|
||||
void LongPressRecognizer::DoRepeat()
|
||||
{
|
||||
SendCallbackMsg(onAction_, true);
|
||||
StartRepeatTimer();
|
||||
}
|
||||
|
||||
void LongPressRecognizer::StartRepeatTimer()
|
||||
{
|
||||
auto context = PipelineContext::GetCurrentContext();
|
||||
CHECK_NULL_VOID(context);
|
||||
|
||||
auto&& callback = [weakPtr = AceType::WeakClaim(this)]() {
|
||||
auto refPtr = weakPtr.Upgrade();
|
||||
if (refPtr) {
|
||||
refPtr->DoRepeat();
|
||||
} else {
|
||||
LOGW("fail to handle overdue deadline due to context is nullptr");
|
||||
}
|
||||
};
|
||||
timer_.Reset(callback);
|
||||
auto taskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
|
||||
taskExecutor.PostDelayedTask(timer_, duration_);
|
||||
}
|
||||
|
||||
double LongPressRecognizer::ConvertPxToVp(double offset) const
|
||||
{
|
||||
auto context = PipelineContext::GetCurrentContext();
|
||||
CHECK_NULL_RETURN(context, offset);
|
||||
|
||||
double vpOffset = context->ConvertPxToVp(Dimension(offset, DimensionUnit::PX));
|
||||
return vpOffset;
|
||||
}
|
||||
|
||||
void LongPressRecognizer::SendCallbackMsg(const std::unique_ptr<GestureEventFunc>& callback, bool isRepeat)
|
||||
{
|
||||
if (callback && *callback) {
|
||||
GestureEvent info;
|
||||
info.SetTimeStamp(time_);
|
||||
info.SetRepeat(isRepeat);
|
||||
info.SetFingerList(fingerList_);
|
||||
TouchEvent trackPoint = {};
|
||||
if (!touchMap_.empty()) {
|
||||
trackPoint = touchMap_.begin()->second;
|
||||
}
|
||||
info.SetSourceDevice(deviceType_);
|
||||
info.SetDeviceId(deviceId_);
|
||||
info.SetGlobalPoint(globalPoint_);
|
||||
info.SetScreenLocation(trackPoint.GetScreenOffset());
|
||||
info.SetGlobalLocation(trackPoint.GetOffset()).SetLocalLocation(trackPoint.GetOffset() - coordinateOffset_);
|
||||
info.SetTarget(GetEventTarget().value_or(EventTarget()));
|
||||
(*callback)(info);
|
||||
}
|
||||
}
|
||||
|
||||
void LongPressRecognizer::Reset()
|
||||
{
|
||||
touchMap_.clear();
|
||||
fingerList_.clear();
|
||||
pointsCount_ = 0;
|
||||
timer_.Cancel();
|
||||
deadlineTimer_.Cancel();
|
||||
state_ = DetectState::READY;
|
||||
pendingEnd_ = false;
|
||||
pendingCancel_ = false;
|
||||
}
|
||||
|
||||
bool LongPressRecognizer::ReconcileFrom(const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
RefPtr<LongPressRecognizer> curr = AceType::DynamicCast<LongPressRecognizer>(recognizer);
|
||||
if (!curr) {
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (curr->duration_ != duration_ || curr->fingers_ != fingers_ || curr->repeat_ != repeat_ ||
|
||||
curr->priorityMask_ != priorityMask_) {
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
onAction_ = std::move(curr->onAction_);
|
||||
onActionEnd_ = std::move(curr->onActionEnd_);
|
||||
onActionCancel_ = std::move(curr->onActionCancel_);
|
||||
|
||||
return true;
|
||||
}
|
||||
} // namespace OHOS::Ace::NG
|
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_LONG_PRESS_RECOGNIZER_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_LONG_PRESS_RECOGNIZER_H
|
||||
|
||||
#include "base/thread/cancelable_callback.h"
|
||||
#include "core/components_ng/gestures/recognizers/multi_fingers_recognizer.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
class LongPressInfo : public BaseEventInfo, public TouchLocationInfo {
|
||||
DECLARE_RELATIONSHIP_OF_CLASSES(LongPressInfo, BaseEventInfo, TouchLocationInfo);
|
||||
|
||||
public:
|
||||
explicit LongPressInfo(int32_t fingerId) : BaseEventInfo("onLongPress"), TouchLocationInfo(fingerId) {}
|
||||
~LongPressInfo() override = default;
|
||||
};
|
||||
|
||||
using OnLongPress = std::function<void(const LongPressInfo&)>;
|
||||
using LongPressCallback = std::function<void(const GestureEvent&)>;
|
||||
using LongPressNoParamCallback = std::function<void()>;
|
||||
|
||||
class LongPressRecognizer : public MultiFingersRecognizer {
|
||||
DECLARE_ACE_TYPE(LongPressRecognizer, MultiFingersRecognizer);
|
||||
|
||||
public:
|
||||
explicit LongPressRecognizer() {}
|
||||
LongPressRecognizer(int32_t duration, int32_t fingers, bool repeat,
|
||||
bool isForDrag = false, bool isDisableMouseLeft = false)
|
||||
: duration_(duration), repeat_(repeat), isForDrag_(isForDrag),
|
||||
isDisableMouseLeft_(isDisableMouseLeft)
|
||||
{
|
||||
fingers_ = fingers;
|
||||
}
|
||||
~LongPressRecognizer() override = default;
|
||||
|
||||
void OnAccepted() override;
|
||||
void OnRejected() override;
|
||||
|
||||
void SetOnLongPress(const OnLongPress& onLongPress)
|
||||
{
|
||||
onLongPress_ = onLongPress;
|
||||
}
|
||||
|
||||
void SetUseCatchMode(bool useCatchMode)
|
||||
{
|
||||
useCatchMode_ = useCatchMode;
|
||||
}
|
||||
|
||||
private:
|
||||
void HandleTouchDownEvent(const TouchEvent& event) override;
|
||||
void HandleTouchUpEvent(const TouchEvent& event) override;
|
||||
void HandleTouchMoveEvent(const TouchEvent& event) override;
|
||||
void HandleTouchCancelEvent(const TouchEvent& event) override;
|
||||
bool ReconcileFrom(const RefPtr<GestureRecognizer>& recognizer) override;
|
||||
void HandleOverdueDeadline();
|
||||
void DeadlineTimer(int32_t time, bool isAccept);
|
||||
void DoRepeat();
|
||||
void StartRepeatTimer();
|
||||
void SendCallbackMsg(const std::unique_ptr<GestureEventFunc>& callback, bool isRepeat);
|
||||
void Reset();
|
||||
double ConvertPxToVp(double offset) const;
|
||||
|
||||
OnLongPress onLongPress_;
|
||||
CancelableCallback<void()> deadlineTimer_;
|
||||
CancelableCallback<void()> timer_;
|
||||
int32_t duration_ = 500;
|
||||
int32_t fingers_ = 1;
|
||||
bool repeat_ = false;
|
||||
std::map<int32_t, TouchEvent> touchMap_;
|
||||
int32_t pointsCount_ = 0;
|
||||
TimeStamp time_;
|
||||
bool pendingEnd_ = false;
|
||||
bool pendingCancel_ = false;
|
||||
bool useCatchMode_ = true;
|
||||
bool isForDrag_ = false;
|
||||
bool isDisableMouseLeft_ = false;
|
||||
Point globalPoint_;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_LONG_PRESS_RECOGNIZER_H
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "core/components_ng/gestures/recognizers/multi_fingers_recognizer.h"
|
||||
#include "base/memory/ace_type.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
void MultiFingersRecognizer::OnAccepted(size_t touchId)
|
||||
{
|
||||
if (!IsInReferee(touchId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
acceptedCount_++;
|
||||
|
||||
if (refereePointers_.size() == acceptedCount_) {
|
||||
OnAccepted();
|
||||
refereePointers_.clear();
|
||||
acceptedCount_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void MultiFingersRecognizer::OnRejected(size_t touchId)
|
||||
{
|
||||
if (!IsInReferee(touchId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
OnRejected();
|
||||
refereePointers_.clear();
|
||||
acceptedCount_ = 0;
|
||||
}
|
||||
|
||||
void MultiFingersRecognizer::Adjudicate(const RefPtr<GestureRecognizer>& recognizer, GestureDisposal disposal)
|
||||
{
|
||||
if (refereePointers_.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::set<size_t> copyIds = refereePointers_;
|
||||
GestureRecognizer::BatchAdjudicate(copyIds, recognizer, disposal);
|
||||
}
|
||||
|
||||
void MultiFingersRecognizer::AddToReferee(size_t touchId, const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
auto result = refereePointers_.emplace(touchId);
|
||||
if (result.second) {
|
||||
GestureRecognizer::AddToReferee(touchId, recognizer);
|
||||
}
|
||||
}
|
||||
|
||||
void MultiFingersRecognizer::DelFromReferee(size_t touchId, const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
refereePointers_.erase(touchId);
|
||||
GestureRecognizer::DelFromReferee(touchId, recognizer);
|
||||
}
|
||||
|
||||
bool MultiFingersRecognizer::IsInReferee(size_t touchId)
|
||||
{
|
||||
return refereePointers_.find(touchId) != refereePointers_.end();
|
||||
}
|
||||
|
||||
void MultiFingersRecognizer::SetFingerList(const std::map<int32_t, TouchEvent> touchPoints,
|
||||
const Offset& coordinateOffset, std::list<FingerInfo>& fingerList)
|
||||
{
|
||||
for (auto& point : touchPoints) {
|
||||
Offset localLocation = point.second.GetOffset() - coordinateOffset;
|
||||
FingerInfo fingerInfo = {point.first, point.second.GetOffset(), localLocation};
|
||||
fingerList.emplace_back(fingerInfo);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_MULTI_FINGERS_RECOGNIZER_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_MULTI_FINGERS_RECOGNIZER_H
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
|
||||
#include "core/components_ng/gestures/recognizers/gesture_recognizer.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
// ClickRecognizer identifies only single click events.
|
||||
// For long press and double click, see: LongPressRecognizer and DoubleClickRecognizer.
|
||||
class MultiFingersRecognizer : public GestureRecognizer {
|
||||
DECLARE_ACE_TYPE(MultiFingersRecognizer, GestureRecognizer);
|
||||
|
||||
public:
|
||||
MultiFingersRecognizer() = default;
|
||||
~MultiFingersRecognizer() override = default;
|
||||
|
||||
void OnAccepted(size_t touchId) override;
|
||||
void OnRejected(size_t touchId) override;
|
||||
void AddToReferee(size_t touchId, const RefPtr<GestureRecognizer>& recognizer) override;
|
||||
void DelFromReferee(size_t touchId, const RefPtr<GestureRecognizer>& recognizer) override;
|
||||
bool IsInReferee(size_t touchId);
|
||||
|
||||
void Adjudicate(const RefPtr<GestureRecognizer>& recognizer, GestureDisposal disposal);
|
||||
|
||||
virtual void OnAccepted() {}
|
||||
virtual void OnRejected() {}
|
||||
|
||||
void SetRefereePointer(size_t touchId)
|
||||
{
|
||||
refereePointers_.emplace(touchId);
|
||||
}
|
||||
|
||||
std::set<size_t> refereePointers_;
|
||||
|
||||
void SetFingerList(const std::map<int32_t, TouchEvent> touchPoints, const Offset& coordinateOffset,
|
||||
std::list<FingerInfo>& fingerList);
|
||||
|
||||
private:
|
||||
size_t acceptedCount_ = 0;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_MULTI_FINGERS_RECOGNIZER_H
|
@ -0,0 +1,442 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "core/components_ng/gestures/recognizers/pan_recognizer.h"
|
||||
|
||||
#include "base/geometry/offset.h"
|
||||
#include "base/log/log.h"
|
||||
#include "core/components_ng/gestures/gesture_referee.h"
|
||||
#include "core/event/axis_event.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr int32_t MAX_PAN_FINGERS = 10;
|
||||
constexpr double DISTANCE_PER_MOUSE_DEGREE = DP_PER_LINE_DESKTOP * LINE_NUMBER_DESKTOP / MOUSE_WHEEL_DEGREES;
|
||||
constexpr int32_t AXIS_PAN_FINGERS = 1;
|
||||
|
||||
} // namespace
|
||||
|
||||
void PanRecognizer::OnAccepted()
|
||||
{
|
||||
SendCallbackMsg(onActionStart_);
|
||||
SendCallbackMsg(onActionUpdate_);
|
||||
|
||||
if (pendingEnd_) {
|
||||
LOGD("pan gesture recognizer has pending end event when waiting to be accepted");
|
||||
SendCallbackMsg(onActionEnd_);
|
||||
Reset();
|
||||
} else if (pendingCancel_) {
|
||||
SendCancelMsg();
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
||||
void PanRecognizer::OnRejected()
|
||||
{
|
||||
LOGD("pan gesture has been rejected!");
|
||||
Reset();
|
||||
}
|
||||
|
||||
void PanRecognizer::HandleTouchDownEvent(const TouchEvent& event)
|
||||
{
|
||||
LOGD("pan recognizer receives touch down event, begin to detect pan event");
|
||||
fingers_ = newFingers_;
|
||||
distance_ = newDistance_;
|
||||
direction_ = newDirection_;
|
||||
|
||||
if (fingers_ > MAX_PAN_FINGERS) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (direction_.type == PanDirection::NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
deviceId_ = event.deviceId;
|
||||
deviceType_ = event.sourceType;
|
||||
touchPoints_[event.id] = event;
|
||||
|
||||
if (state_ == DetectState::READY) {
|
||||
AddToReferee(event.id, AceType::Claim(this));
|
||||
if (static_cast<int32_t>(refereePointers_.size()) == fingers_) {
|
||||
velocityTracker_.Reset();
|
||||
velocityTracker_.UpdateTouchPoint(event);
|
||||
state_ = DetectState::DETECTING;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PanRecognizer::HandleTouchDownEvent(const AxisEvent& event)
|
||||
{
|
||||
LOGD("pan recognizer receives axis start event, begin to detect pan event");
|
||||
if (fingers_ != AXIS_PAN_FINGERS) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (direction_.type == PanDirection::NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
deviceId_ = event.deviceId;
|
||||
deviceType_ = event.sourceType;
|
||||
lastAxisEvent_ = event;
|
||||
|
||||
if (state_ == DetectState::READY) {
|
||||
state_ = DetectState::DETECTING;
|
||||
}
|
||||
}
|
||||
|
||||
void PanRecognizer::HandleTouchUpEvent(const TouchEvent& event)
|
||||
{
|
||||
LOGD("pan recognizer receives touch up event");
|
||||
auto itr = touchPoints_.find(event.id);
|
||||
if (itr == touchPoints_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
globalPoint_ = Point(event.x, event.y);
|
||||
touchPoints_.erase(itr);
|
||||
velocityTracker_.UpdateTouchPoint(event, true);
|
||||
|
||||
if (state_ == DetectState::READY) {
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (state_ == DetectState::DETECTING) {
|
||||
size_t inRefereeNum = refereePointers_.size();
|
||||
bool inReferee = IsInReferee(static_cast<size_t>(event.id));
|
||||
if (inReferee) {
|
||||
inRefereeNum--;
|
||||
}
|
||||
|
||||
if (static_cast<int32_t>(touchPoints_.size()) < fingers_ || inRefereeNum < 1) {
|
||||
LOGD("this gesture is not pan, try to reject it");
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (inReferee) {
|
||||
DelFromReferee(event.id, AceType::Claim(this));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (static_cast<int32_t>(touchPoints_.size()) < fingers_) {
|
||||
if (refereeState_ == RefereeState::SUCCEED) {
|
||||
SendCallbackMsg(onActionEnd_);
|
||||
Reset();
|
||||
} else {
|
||||
pendingEnd_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PanRecognizer::HandleTouchUpEvent(const AxisEvent& event)
|
||||
{
|
||||
LOGD("pan recognizer receives axis end event");
|
||||
if (fingers_ != AXIS_PAN_FINGERS) {
|
||||
return;
|
||||
}
|
||||
globalPoint_ = Point(event.x, event.y);
|
||||
|
||||
if (state_ != DetectState::DETECTED) {
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
state_ = DetectState::READY;
|
||||
return;
|
||||
}
|
||||
|
||||
SendCallbackMsg(onActionEnd_, false);
|
||||
Reset();
|
||||
}
|
||||
|
||||
void PanRecognizer::HandleTouchMoveEvent(const TouchEvent& event)
|
||||
{
|
||||
LOGD("pan recognizer receives touch move event");
|
||||
auto itr = touchPoints_.find(event.id);
|
||||
if (itr == touchPoints_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
globalPoint_ = Point(event.x, event.y);
|
||||
if (state_ == DetectState::READY) {
|
||||
touchPoints_[event.id] = event;
|
||||
return;
|
||||
}
|
||||
|
||||
delta_ = (event.GetOffset() - touchPoints_[event.id].GetOffset()) / touchPoints_.size();
|
||||
mainDelta_ = GetMainAxisDelta();
|
||||
velocityTracker_.UpdateTouchPoint(event);
|
||||
averageDistance_ += delta_;
|
||||
touchPoints_[event.id] = event;
|
||||
time_ = event.time;
|
||||
|
||||
if (state_ == DetectState::DETECTING) {
|
||||
auto result = IsPanGestureAccept();
|
||||
if (result == GestureAcceptResult::ACCEPT) {
|
||||
state_ = DetectState::DETECTED;
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::ACCEPT);
|
||||
} else if (result == GestureAcceptResult::REJECT) {
|
||||
LOGW("pan recognizer reject");
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
}
|
||||
} else if (state_ == DetectState::DETECTED && refereeState_ == RefereeState::SUCCEED) {
|
||||
if ((direction_.type & PanDirection::VERTICAL) == 0) {
|
||||
averageDistance_.SetY(0.0);
|
||||
} else if ((direction_.type & PanDirection::HORIZONTAL) == 0) {
|
||||
averageDistance_.SetX(0.0);
|
||||
}
|
||||
|
||||
LOGD("pan recognizer detected successful");
|
||||
if (isFlushTouchEventsEnd_) {
|
||||
SendCallbackMsg(onActionUpdate_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PanRecognizer::OnFlushTouchEventsBegin()
|
||||
{
|
||||
isFlushTouchEventsEnd_ = false;
|
||||
}
|
||||
|
||||
void PanRecognizer::OnFlushTouchEventsEnd()
|
||||
{
|
||||
isFlushTouchEventsEnd_ = true;
|
||||
}
|
||||
|
||||
void PanRecognizer::HandleTouchMoveEvent(const AxisEvent& event)
|
||||
{
|
||||
LOGD("pan recognizer receives axis update event");
|
||||
if (fingers_ != AXIS_PAN_FINGERS) {
|
||||
return;
|
||||
}
|
||||
globalPoint_ = Point(event.x, event.y);
|
||||
if (state_ == DetectState::READY) {
|
||||
lastAxisEvent_ = event;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((direction_.type & PanDirection::HORIZONTAL) == 0) {
|
||||
// PanRecognizer Direction: Vertical
|
||||
delta_ = Offset(-event.horizontalAxis * DISTANCE_PER_MOUSE_DEGREE,
|
||||
-event.verticalAxis * DISTANCE_PER_MOUSE_DEGREE);
|
||||
} else if ((direction_.type & PanDirection::VERTICAL) == 0) {
|
||||
// PanRecognizer Direction: Horizontal
|
||||
if (NearZero(event.horizontalAxis)) {
|
||||
delta_ = Offset(-event.verticalAxis * DISTANCE_PER_MOUSE_DEGREE, 0);
|
||||
} else {
|
||||
delta_ = Offset(-event.horizontalAxis * DISTANCE_PER_MOUSE_DEGREE,
|
||||
-event.verticalAxis * DISTANCE_PER_MOUSE_DEGREE);
|
||||
}
|
||||
}
|
||||
|
||||
mainDelta_ = GetMainAxisDelta();
|
||||
averageDistance_ += delta_;
|
||||
lastAxisEvent_ = event;
|
||||
time_ = event.time;
|
||||
|
||||
if (state_ == DetectState::DETECTING) {
|
||||
auto result = IsPanGestureAccept();
|
||||
if (result == GestureAcceptResult::ACCEPT) {
|
||||
state_ = DetectState::DETECTED;
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::ACCEPT);
|
||||
} else if (result == GestureAcceptResult::REJECT) {
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
}
|
||||
}
|
||||
if (state_ == DetectState::DETECTED) {
|
||||
if ((direction_.type & PanDirection::VERTICAL) == 0) {
|
||||
averageDistance_.SetY(0.0);
|
||||
} else if ((direction_.type & PanDirection::HORIZONTAL) == 0) {
|
||||
averageDistance_.SetX(0.0);
|
||||
}
|
||||
|
||||
SendCallbackMsg(onActionUpdate_, false);
|
||||
}
|
||||
}
|
||||
|
||||
void PanRecognizer::HandleTouchCancelEvent(const TouchEvent& event)
|
||||
{
|
||||
LOGD("pan recognizer receives touch cancel event");
|
||||
if (state_ == DetectState::READY || state_ == DetectState::DETECTING) {
|
||||
LOGD("cancel pan gesture detect, try to reject it");
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (refereeState_ == RefereeState::SUCCEED) {
|
||||
SendCancelMsg();
|
||||
Reset();
|
||||
} else {
|
||||
pendingCancel_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void PanRecognizer::HandleTouchCancelEvent(const AxisEvent& event)
|
||||
{
|
||||
if (fingers_ != AXIS_PAN_FINGERS) {
|
||||
return;
|
||||
}
|
||||
return HandleTouchCancelEvent(TouchEvent {});
|
||||
}
|
||||
|
||||
PanRecognizer::GestureAcceptResult PanRecognizer::IsPanGestureAccept() const
|
||||
{
|
||||
if ((direction_.type & PanDirection::ALL) == PanDirection::ALL) {
|
||||
double offset = averageDistance_.GetDistance();
|
||||
if (fabs(offset) < distance_) {
|
||||
return GestureAcceptResult::DETECTING;
|
||||
}
|
||||
return GestureAcceptResult::ACCEPT;
|
||||
}
|
||||
|
||||
if (fabs(averageDistance_.GetX()) > fabs(averageDistance_.GetY())) {
|
||||
if ((direction_.type & PanDirection::HORIZONTAL) != 0) {
|
||||
double offset = averageDistance_.GetX();
|
||||
if (fabs(offset) < distance_) {
|
||||
return GestureAcceptResult::DETECTING;
|
||||
}
|
||||
if ((direction_.type & PanDirection::LEFT) == 0 && offset < 0) {
|
||||
return GestureAcceptResult::REJECT;
|
||||
}
|
||||
if ((direction_.type & PanDirection::RIGHT) == 0 && offset > 0) {
|
||||
return GestureAcceptResult::REJECT;
|
||||
}
|
||||
return GestureAcceptResult::ACCEPT;
|
||||
}
|
||||
return GestureAcceptResult::DETECTING;
|
||||
} else {
|
||||
if ((direction_.type & PanDirection::VERTICAL) != 0) {
|
||||
double offset = averageDistance_.GetY();
|
||||
if (fabs(offset) < distance_) {
|
||||
return GestureAcceptResult::DETECTING;
|
||||
}
|
||||
if ((direction_.type & PanDirection::UP) == 0 && offset < 0) {
|
||||
return GestureAcceptResult::REJECT;
|
||||
}
|
||||
if ((direction_.type & PanDirection::DOWN) == 0 && offset > 0) {
|
||||
return GestureAcceptResult::REJECT;
|
||||
}
|
||||
return GestureAcceptResult::ACCEPT;
|
||||
}
|
||||
return GestureAcceptResult::DETECTING;
|
||||
}
|
||||
}
|
||||
|
||||
void PanRecognizer::Reset()
|
||||
{
|
||||
touchPoints_.clear();
|
||||
averageDistance_.Reset();
|
||||
state_ = DetectState::READY;
|
||||
pendingEnd_ = false;
|
||||
pendingCancel_ = false;
|
||||
}
|
||||
|
||||
void PanRecognizer::SendCallbackMsg(const std::unique_ptr<GestureEventFunc>& callback, bool isTouchEvent)
|
||||
{
|
||||
if (callback && *callback) {
|
||||
GestureEvent info;
|
||||
info.SetTimeStamp(time_);
|
||||
info.SetOffsetX(averageDistance_.GetX());
|
||||
info.SetOffsetY(averageDistance_.GetY());
|
||||
TouchEvent touchPoint = {};
|
||||
if (!touchPoints_.empty()) {
|
||||
touchPoint = touchPoints_.begin()->second;
|
||||
}
|
||||
info.SetGlobalPoint(globalPoint_).SetLocalLocation(touchPoint.GetOffset() - coordinateOffset_);
|
||||
info.SetDeviceId(deviceId_);
|
||||
info.SetSourceDevice(deviceType_);
|
||||
info.SetDelta(delta_);
|
||||
info.SetMainDelta(mainDelta_);
|
||||
if (isTouchEvent) {
|
||||
info.SetVelocity(velocityTracker_.GetVelocity());
|
||||
info.SetMainVelocity(velocityTracker_.GetMainAxisVelocity());
|
||||
} else {
|
||||
info.SetVelocity(Velocity());
|
||||
info.SetMainVelocity(0.0);
|
||||
}
|
||||
info.SetTarget(GetEventTarget().value_or(EventTarget()));
|
||||
(*callback)(info);
|
||||
}
|
||||
}
|
||||
|
||||
bool PanRecognizer::ReconcileFrom(const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
RefPtr<PanRecognizer> curr = AceType::DynamicCast<PanRecognizer>(recognizer);
|
||||
if (!curr) {
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (curr->fingers_ != fingers_ || curr->priorityMask_ != priorityMask_) {
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
direction_.type = curr->direction_.type;
|
||||
newDirection_.type = curr->newDirection_.type;
|
||||
distance_ = curr->distance_;
|
||||
newDistance_ = curr->newDistance_;
|
||||
|
||||
onActionStart_ = std::move(curr->onActionStart_);
|
||||
onActionUpdate_ = std::move(curr->onActionUpdate_);
|
||||
onActionEnd_ = std::move(curr->onActionEnd_);
|
||||
onActionCancel_ = std::move(curr->onActionCancel_);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PanRecognizer::ChangeFingers(int32_t fingers)
|
||||
{
|
||||
if (fingers_ != fingers) {
|
||||
newFingers_ = fingers;
|
||||
}
|
||||
}
|
||||
|
||||
void PanRecognizer::ChangeDirection(const PanDirection& direction)
|
||||
{
|
||||
if (direction_.type != direction.type) {
|
||||
direction_.type = direction.type;
|
||||
newDirection_.type = direction.type;
|
||||
}
|
||||
}
|
||||
|
||||
void PanRecognizer::ChangeDistance(double distance)
|
||||
{
|
||||
if (distance_ != distance) {
|
||||
if (state_ == DetectState::READY || state_ == DetectState::DETECTING) {
|
||||
distance_ = distance;
|
||||
}
|
||||
newDistance_ = distance;
|
||||
}
|
||||
}
|
||||
|
||||
double PanRecognizer::GetMainAxisDelta()
|
||||
{
|
||||
switch (direction_.type) {
|
||||
case PanDirection::ALL:
|
||||
return delta_.GetDistance();
|
||||
case PanDirection::HORIZONTAL:
|
||||
return delta_.GetX();
|
||||
case PanDirection::VERTICAL:
|
||||
return delta_.GetY();
|
||||
default:
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_PAN_RECOGNIZER_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_PAN_RECOGNIZER_H
|
||||
|
||||
#include <cmath>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
|
||||
#include "core/components_ng/gestures/recognizers/multi_fingers_recognizer.h"
|
||||
#include "core/pipeline_ng/pipeline_context.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
class PanRecognizer : public MultiFingersRecognizer {
|
||||
DECLARE_ACE_TYPE(PanRecognizer, MultiFingersRecognizer);
|
||||
|
||||
public:
|
||||
PanRecognizer(int32_t fingers, const PanDirection& direction, double distance)
|
||||
: direction_(direction), distance_(distance)
|
||||
{
|
||||
fingers_ = fingers;
|
||||
newFingers_ = fingers_;
|
||||
newDistance_ = distance_;
|
||||
newDirection_ = direction_;
|
||||
if ((direction_.type & PanDirection::VERTICAL) == 0) {
|
||||
velocityTracker_ = VelocityTracker(Axis::HORIZONTAL);
|
||||
} else if ((direction_.type & PanDirection::HORIZONTAL) == 0) {
|
||||
velocityTracker_ = VelocityTracker(Axis::VERTICAL);
|
||||
}
|
||||
}
|
||||
PanRecognizer(RefPtr<PanGestureOption> panGestureOption) : panGestureOption_(panGestureOption)
|
||||
{
|
||||
auto context = PipelineContext::GetCurrentContext();
|
||||
CHECK_NULL_VOID(context);
|
||||
uint32_t directNum = panGestureOption->GetDirection().type;
|
||||
double distanceNumber = panGestureOption->GetDistance();
|
||||
int32_t fingersNumber = panGestureOption->GetFingers();
|
||||
|
||||
double distance = LessNotEqual(distanceNumber, 0.0) ? DEFAULT_PAN_DISTANCE : distanceNumber;
|
||||
distance_ = context->NormalizeToPx(Dimension(distance, DimensionUnit::VP));
|
||||
fingers_ = fingersNumber <= DEFAULT_PAN_FINGER ? DEFAULT_PAN_FINGER : fingersNumber;
|
||||
|
||||
if (directNum >= PanDirection::NONE && directNum <= PanDirection::ALL) {
|
||||
direction_.type = directNum;
|
||||
}
|
||||
|
||||
newFingers_ = fingers_;
|
||||
newDistance_ = distance_;
|
||||
newDirection_ = direction_;
|
||||
|
||||
PanFingersFuncType changeFingers = [weak = AceType::WeakClaim(this)](int32_t fingers) {
|
||||
auto panRecognizer = weak.Upgrade();
|
||||
if (!panRecognizer) {
|
||||
return;
|
||||
}
|
||||
panRecognizer->ChangeFingers(fingers);
|
||||
};
|
||||
onChangeFingers_ = OnPanFingersFunc(changeFingers);
|
||||
panGestureOption_->SetOnPanFingersId(onChangeFingers_);
|
||||
|
||||
PanDirectionFuncType changeDirection = [weak = AceType::WeakClaim(this)](const PanDirection& direction) {
|
||||
auto panRecognizer = weak.Upgrade();
|
||||
if (!panRecognizer) {
|
||||
return;
|
||||
}
|
||||
panRecognizer->ChangeDirection(direction);
|
||||
};
|
||||
onChangeDirection_ = OnPanDirectionFunc(changeDirection);
|
||||
panGestureOption_->SetOnPanDirectionId(onChangeDirection_);
|
||||
|
||||
PanDistanceFuncType changeDistance = [weak = AceType::WeakClaim(this)](double distance) {
|
||||
auto panRecognizer = weak.Upgrade();
|
||||
if (!panRecognizer) {
|
||||
return;
|
||||
}
|
||||
panRecognizer->ChangeDistance(distance);
|
||||
};
|
||||
onChangeDistance_ = OnPanDistanceFunc(changeDistance);
|
||||
panGestureOption_->SetOnPanDistanceId(onChangeDistance_);
|
||||
}
|
||||
~PanRecognizer() override
|
||||
{
|
||||
if (panGestureOption_ == nullptr) {
|
||||
return;
|
||||
}
|
||||
panGestureOption_->GetOnPanFingersIds().erase(onChangeFingers_.GetId());
|
||||
panGestureOption_->GetOnPanDirectionIds().erase(onChangeDirection_.GetId());
|
||||
panGestureOption_->GetOnPanDistanceIds().erase(onChangeDistance_.GetId());
|
||||
}
|
||||
|
||||
void OnAccepted() override;
|
||||
void OnRejected() override;
|
||||
void OnFlushTouchEventsBegin() override;
|
||||
void OnFlushTouchEventsEnd() override;
|
||||
|
||||
private:
|
||||
enum class GestureAcceptResult {
|
||||
ACCEPT,
|
||||
REJECT,
|
||||
DETECTING,
|
||||
};
|
||||
void HandleTouchDownEvent(const TouchEvent& event) override;
|
||||
void HandleTouchUpEvent(const TouchEvent& event) override;
|
||||
void HandleTouchMoveEvent(const TouchEvent& event) override;
|
||||
void HandleTouchCancelEvent(const TouchEvent& event) override;
|
||||
void HandleTouchDownEvent(const AxisEvent& event) override;
|
||||
void HandleTouchUpEvent(const AxisEvent& event) override;
|
||||
void HandleTouchMoveEvent(const AxisEvent& event) override;
|
||||
void HandleTouchCancelEvent(const AxisEvent& event) override;
|
||||
bool ReconcileFrom(const RefPtr<GestureRecognizer>& recognizer) override;
|
||||
GestureAcceptResult IsPanGestureAccept() const;
|
||||
void Reset();
|
||||
void SendCallbackMsg(const std::unique_ptr<GestureEventFunc>& callback, bool isTouchEvent = true);
|
||||
void ChangeFingers(int32_t fingers);
|
||||
void ChangeDirection(const PanDirection& direction);
|
||||
void ChangeDistance(double distance);
|
||||
double GetMainAxisDelta();
|
||||
|
||||
const TouchRestrict& GetTouchRestrict() const
|
||||
{
|
||||
return touchRestrict_;
|
||||
}
|
||||
|
||||
PanDirection direction_;
|
||||
double distance_ = 0.0;
|
||||
std::map<int32_t, TouchEvent> touchPoints_;
|
||||
AxisEvent lastAxisEvent_;
|
||||
Offset averageDistance_;
|
||||
Offset delta_;
|
||||
double mainDelta_ = 0.0;
|
||||
VelocityTracker velocityTracker_;
|
||||
TimeStamp time_;
|
||||
bool pendingEnd_ = false;
|
||||
bool pendingCancel_ = false;
|
||||
Point globalPoint_;
|
||||
RefPtr<PanGestureOption> panGestureOption_;
|
||||
OnPanFingersFunc onChangeFingers_;
|
||||
OnPanDirectionFunc onChangeDirection_;
|
||||
OnPanDistanceFunc onChangeDistance_;
|
||||
int32_t newFingers_ = 1;
|
||||
double newDistance_ = 0.0;
|
||||
PanDirection newDirection_;
|
||||
bool isFlushTouchEventsEnd_ = false;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_PAN_RECOGNIZER_H
|
@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "core/components_ng/gestures/recognizers/parallel_recognizer.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "base/geometry/offset.h"
|
||||
#include "base/log/log.h"
|
||||
#include "core/components_ng/gestures/gesture_referee.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
void ParallelRecognizer::OnAccepted(size_t touchId)
|
||||
{
|
||||
if (refereePointers_.find(touchId) == refereePointers_.end()) {
|
||||
return;
|
||||
}
|
||||
refereePointers_.erase(touchId);
|
||||
|
||||
LOGD("the parallel gesture recognizer has been accepted, touch id %{public}zu", touchId);
|
||||
for (auto& recognizer : recognizers_) {
|
||||
if (recognizer->GetDetectState() == DetectState::DETECTED) {
|
||||
recognizer->SetCoordinateOffset(coordinateOffset_);
|
||||
recognizer->OnAccepted(touchId);
|
||||
recognizer->SetRefereeState(RefereeState::SUCCEED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ParallelRecognizer::OnRejected(size_t touchId)
|
||||
{
|
||||
if (refereePointers_.find(touchId) == refereePointers_.end()) {
|
||||
return;
|
||||
}
|
||||
refereePointers_.erase(touchId);
|
||||
|
||||
LOGD("the parallel gesture recognizer has been rejected! the touch id is %{public}zu", touchId);
|
||||
for (auto& recognizer : recognizers_) {
|
||||
recognizer->OnRejected(touchId);
|
||||
if (recognizer->GetDetectState() == DetectState::READY) {
|
||||
recognizer->SetRefereeState(RefereeState::FAIL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ParallelRecognizer::OnPending(size_t touchId)
|
||||
{
|
||||
if (refereePointers_.find(touchId) == refereePointers_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOGD("the parallel gesture recognizer is pending! the touch id is %{public}zu", touchId);
|
||||
for (auto& recognizer : recognizers_) {
|
||||
if (recognizer->GetRefereeState() == RefereeState::PENDING) {
|
||||
recognizer->OnPending(touchId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool ParallelRecognizer::HandleEvent(const TouchEvent& point)
|
||||
{
|
||||
if (point.type == TouchType::UNKNOWN) {
|
||||
LOGW("unknown touch type");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (point.type == TouchType::DOWN) {
|
||||
bool allRecognizeEnd = true;
|
||||
for (auto& recognizer : recognizers_) {
|
||||
if (!IsRecognizeEnd(recognizer)) {
|
||||
allRecognizeEnd = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (allRecognizeEnd) {
|
||||
LOGD("all sub gestures recognize finish, change the parallel state to be ready");
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& recognizer : recognizers_) {
|
||||
if (recognizer->GetRefereeState() != RefereeState::FAIL) {
|
||||
recognizer->HandleEvent(point);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ParallelRecognizer::OnFlushTouchEventsBegin()
|
||||
{
|
||||
for (auto& recognizer : recognizers_) {
|
||||
recognizer->OnFlushTouchEventsBegin();
|
||||
}
|
||||
}
|
||||
|
||||
void ParallelRecognizer::OnFlushTouchEventsEnd()
|
||||
{
|
||||
for (auto& recognizer : recognizers_) {
|
||||
recognizer->OnFlushTouchEventsEnd();
|
||||
}
|
||||
}
|
||||
|
||||
bool ParallelRecognizer::IsRecognizeEnd(const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
DetectState currState = recognizer->GetDetectState();
|
||||
RefereeState refereeState = recognizer->GetRefereeState();
|
||||
return (refereeState == RefereeState::SUCCEED && currState != DetectState::DETECTED) ||
|
||||
(refereeState == RefereeState::FAIL);
|
||||
}
|
||||
|
||||
void ParallelRecognizer::BatchAdjudicate(
|
||||
const std::set<size_t>& touchIds, const RefPtr<GestureRecognizer>& recognizer, GestureDisposal disposal)
|
||||
{
|
||||
if (disposal == GestureDisposal::ACCEPT) {
|
||||
if (state_ == DetectState::DETECTING) {
|
||||
LOGD("the sub gesture recognizer %{public}s ask for accept", AceType::TypeName(recognizer));
|
||||
state_ = DetectState::DETECTED;
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::ACCEPT);
|
||||
} else if (refereeState_ == RefereeState::SUCCEED) {
|
||||
LOGD("the sub gesture recognizer %{public}s is accepted because referee succeed",
|
||||
AceType::TypeName(recognizer));
|
||||
for (auto touchId : touchIds) {
|
||||
recognizer->OnAccepted(touchId);
|
||||
}
|
||||
recognizer->SetRefereeState(RefereeState::SUCCEED);
|
||||
}
|
||||
} else if (disposal == GestureDisposal::REJECT) {
|
||||
for (auto touchId : touchIds) {
|
||||
recognizer->OnRejected(touchId);
|
||||
}
|
||||
recognizer->SetRefereeState(RefereeState::FAIL);
|
||||
|
||||
LOGD("the sub gesture recognizer %{public}s ask for reject", AceType::TypeName(recognizer));
|
||||
bool needReject = true;
|
||||
for (auto& tmpRecognizer : recognizers_) {
|
||||
if (tmpRecognizer->GetRefereeState() != RefereeState::FAIL) {
|
||||
needReject = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (needReject) {
|
||||
LOGD("all gesture recognizers are rejected, adjudicate reject");
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
}
|
||||
} else {
|
||||
if (state_ == DetectState::DETECTING) {
|
||||
recognizer->SetRefereeState(RefereeState::PENDING);
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::PENDING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ParallelRecognizer::AddToReferee(size_t touchId, const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
recognizer->SetRefereeState(RefereeState::DETECTING);
|
||||
if (state_ == DetectState::READY) {
|
||||
state_ = DetectState::DETECTING;
|
||||
}
|
||||
|
||||
if (state_ == DetectState::DETECTING) {
|
||||
MultiFingersRecognizer::AddToReferee(touchId, AceType::Claim(this));
|
||||
}
|
||||
}
|
||||
|
||||
void ParallelRecognizer::Reset()
|
||||
{
|
||||
state_ = DetectState::READY;
|
||||
for (auto& recognizer : recognizers_) {
|
||||
recognizer->SetRefereeState(RefereeState::DETECTING);
|
||||
}
|
||||
}
|
||||
|
||||
bool ParallelRecognizer::ReconcileFrom(const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
RefPtr<ParallelRecognizer> curr = AceType::DynamicCast<ParallelRecognizer>(recognizer);
|
||||
if (!curr) {
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (recognizers_.size() != curr->recognizers_.size() || curr->priorityMask_ != priorityMask_) {
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
auto currIter = curr->recognizers_.begin();
|
||||
|
||||
for (auto iter = recognizers_.begin(); iter != recognizers_.end(); iter++, currIter++) {
|
||||
if (!(*iter)->ReconcileFrom(*currIter)) {
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_PARALLEL_RECOGNIZER_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_PARALLEL_RECOGNIZER_H
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "core/components_ng/gestures/gesture_info.h"
|
||||
#include "core/components_ng/gestures/recognizers/multi_fingers_recognizer.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
// ParallelRecognizer identifies events in parallel recognizers.
|
||||
// For long press and double click, see: LongPressRecognizer and DoubleClickRecognizer.
|
||||
class ACE_EXPORT ParallelRecognizer : public MultiFingersRecognizer {
|
||||
DECLARE_ACE_TYPE(ParallelRecognizer, MultiFingersRecognizer);
|
||||
|
||||
public:
|
||||
explicit ParallelRecognizer(const std::vector<RefPtr<GestureRecognizer>>& recognizers)
|
||||
{
|
||||
for (const auto& recognizer : recognizers) {
|
||||
recognizer->SetGestureGroup(AceType::WeakClaim(this));
|
||||
recognizers_.emplace_back(recognizer);
|
||||
}
|
||||
}
|
||||
|
||||
explicit ParallelRecognizer(std::list<RefPtr<GestureRecognizer>>&& recognizers)
|
||||
{
|
||||
recognizers_ = std::move(recognizers);
|
||||
for (const auto& recognizer : recognizers_) {
|
||||
recognizer->SetGestureGroup(AceType::WeakClaim(this));
|
||||
}
|
||||
}
|
||||
|
||||
~ParallelRecognizer() override = default;
|
||||
void OnAccepted(size_t touchId) override;
|
||||
void OnRejected(size_t touchId) override;
|
||||
void OnPending(size_t touchId) override;
|
||||
bool HandleEvent(const TouchEvent& point) override;
|
||||
void OnFlushTouchEventsBegin() override;
|
||||
void OnFlushTouchEventsEnd() override;
|
||||
|
||||
private:
|
||||
void HandleTouchDownEvent(const TouchEvent& event) override {};
|
||||
void HandleTouchUpEvent(const TouchEvent& event) override {};
|
||||
void HandleTouchMoveEvent(const TouchEvent& event) override {};
|
||||
void HandleTouchCancelEvent(const TouchEvent& event) override {};
|
||||
void BatchAdjudicate(const std::set<size_t>& touchIds, const RefPtr<GestureRecognizer>& recognizer,
|
||||
GestureDisposal disposal) override;
|
||||
void AddToReferee(size_t touchId, const RefPtr<GestureRecognizer>& recognizer) override;
|
||||
bool ReconcileFrom(const RefPtr<GestureRecognizer>& recognizer) override;
|
||||
void Reset();
|
||||
void DelFromReferee(size_t touchId, const RefPtr<GestureRecognizer>& recognizer) override {}
|
||||
bool IsRecognizeEnd(const RefPtr<GestureRecognizer>& recognizer);
|
||||
|
||||
std::list<RefPtr<GestureRecognizer>> recognizers_;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_PARALLEL_RECOGNIZER_H
|
@ -0,0 +1,295 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "core/components_ng/gestures/recognizers/pinch_recognizer.h"
|
||||
|
||||
#include "base/geometry/offset.h"
|
||||
#include "base/log/log.h"
|
||||
#include "base/ressched/ressched_report.h"
|
||||
#include "core/components_ng/gestures/gesture_referee.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr int32_t MAX_PINCH_FINGERS = 5;
|
||||
constexpr int32_t AXIS_PINCH_FINGERS = 2;
|
||||
|
||||
} // namespace
|
||||
|
||||
void PinchRecognizer::OnAccepted()
|
||||
{
|
||||
ResSchedReport::GetInstance().ResSchedDataReport("click");
|
||||
SendCallbackMsg(onActionStart_);
|
||||
|
||||
if (pendingEnd_) {
|
||||
SendCallbackMsg(onActionEnd_);
|
||||
Reset();
|
||||
} else if (pendingCancel_) {
|
||||
SendCancelMsg();
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
||||
void PinchRecognizer::OnRejected()
|
||||
{
|
||||
LOGD("pinch gesture has been rejected!");
|
||||
Reset();
|
||||
}
|
||||
|
||||
void PinchRecognizer::HandleTouchDownEvent(const TouchEvent& event)
|
||||
{
|
||||
LOGD("pinch recognizer receives touch down event, begin to detect pinch event");
|
||||
if (fingers_ > MAX_PINCH_FINGERS) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state_ == DetectState::READY) {
|
||||
AddToReferee(event.id, AceType::Claim(this));
|
||||
touchPoints_[event.id] = event;
|
||||
if (static_cast<int32_t>(touchPoints_.size()) == fingers_) {
|
||||
initialDev_ = ComputeAverageDeviation();
|
||||
pinchCenter_ = ComputePinchCenter();
|
||||
state_ = DetectState::DETECTING;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PinchRecognizer::HandleTouchDownEvent(const AxisEvent& event)
|
||||
{
|
||||
LOGD("pinch recognizer receives touch down event, begin to detect pinch event");
|
||||
if (fingers_ != AXIS_PINCH_FINGERS) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state_ == DetectState::READY) {
|
||||
pinchCenter_ = Offset(event.x, event.y);
|
||||
state_ = DetectState::DETECTING;
|
||||
}
|
||||
}
|
||||
|
||||
void PinchRecognizer::HandleTouchUpEvent(const TouchEvent& event)
|
||||
{
|
||||
LOGD("pinch recognizer receives touch up event");
|
||||
auto itr = touchPoints_.find(event.id);
|
||||
if (itr == touchPoints_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
touchPoints_.erase(itr);
|
||||
|
||||
if (state_ != DetectState::DETECTED) {
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (refereeState_ == RefereeState::SUCCEED) {
|
||||
SendCallbackMsg(onActionEnd_);
|
||||
Reset();
|
||||
} else {
|
||||
pendingEnd_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void PinchRecognizer::HandleTouchUpEvent(const AxisEvent& event)
|
||||
{
|
||||
LOGD("pinch recognizer receives touch up event");
|
||||
if (fingers_ != AXIS_PINCH_FINGERS) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state_ != DetectState::DETECTED) {
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
return;
|
||||
}
|
||||
|
||||
SendCallbackMsg(onActionEnd_);
|
||||
Reset();
|
||||
}
|
||||
|
||||
void PinchRecognizer::HandleTouchMoveEvent(const TouchEvent& event)
|
||||
{
|
||||
LOGD("pinch recognizer receives touch move event");
|
||||
auto itr = touchPoints_.find(event.id);
|
||||
if (itr == touchPoints_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state_ == DetectState::READY) {
|
||||
touchPoints_[event.id] = event;
|
||||
return;
|
||||
}
|
||||
|
||||
touchPoints_[event.id] = event;
|
||||
currentDev_ = ComputeAverageDeviation();
|
||||
time_ = event.time;
|
||||
|
||||
if (state_ == DetectState::DETECTING) {
|
||||
if (GreatOrEqual(fabs(currentDev_ - initialDev_), distance_)) {
|
||||
scale_ = currentDev_ / initialDev_;
|
||||
state_ = DetectState::DETECTED;
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::ACCEPT);
|
||||
}
|
||||
} else if (state_ == DetectState::DETECTED && refereeState_ == RefereeState::SUCCEED) {
|
||||
scale_ = currentDev_ / initialDev_;
|
||||
if (isFlushTouchEventsEnd_) {
|
||||
SendCallbackMsg(onActionUpdate_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PinchRecognizer::OnFlushTouchEventsBegin()
|
||||
{
|
||||
isFlushTouchEventsEnd_ = false;
|
||||
}
|
||||
|
||||
void PinchRecognizer::OnFlushTouchEventsEnd()
|
||||
{
|
||||
isFlushTouchEventsEnd_ = true;
|
||||
}
|
||||
|
||||
void PinchRecognizer::HandleTouchMoveEvent(const AxisEvent& event)
|
||||
{
|
||||
LOGD("pinch recognizer receives touch move event");
|
||||
if (fingers_ != AXIS_PINCH_FINGERS) {
|
||||
return;
|
||||
}
|
||||
if (state_ == DetectState::READY) {
|
||||
return;
|
||||
}
|
||||
|
||||
time_ = event.time;
|
||||
if (state_ == DetectState::DETECTING) {
|
||||
scale_ = event.pinchAxisScale;
|
||||
state_ = DetectState::DETECTED;
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::ACCEPT);
|
||||
}
|
||||
if (state_ == DetectState::DETECTED) {
|
||||
scale_ = event.pinchAxisScale;
|
||||
SendCallbackMsg(onActionUpdate_);
|
||||
}
|
||||
}
|
||||
|
||||
void PinchRecognizer::HandleTouchCancelEvent(const TouchEvent& event)
|
||||
{
|
||||
LOGD("pinch recognizer receives touch cancel event");
|
||||
if (state_ == DetectState::READY || state_ == DetectState::DETECTING) {
|
||||
LOGD("cancel pinch gesture detect, try to reject it");
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (refereeState_ == RefereeState::SUCCEED) {
|
||||
SendCancelMsg();
|
||||
Reset();
|
||||
} else {
|
||||
pendingCancel_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void PinchRecognizer::HandleTouchCancelEvent(const AxisEvent& event)
|
||||
{
|
||||
SendCancelMsg();
|
||||
Reset();
|
||||
}
|
||||
|
||||
double PinchRecognizer::ComputeAverageDeviation()
|
||||
{
|
||||
// compute the coordinate of focal point
|
||||
double sumOfX = 0.0;
|
||||
double sumOfY = 0.0;
|
||||
for (auto& element : touchPoints_) {
|
||||
sumOfX = sumOfX + element.second.x;
|
||||
sumOfY = sumOfY + element.second.y;
|
||||
}
|
||||
double focalX = sumOfX / touchPoints_.size();
|
||||
double focalY = sumOfY / touchPoints_.size();
|
||||
|
||||
// compute average deviation
|
||||
double devX = 0.0;
|
||||
double devY = 0.0;
|
||||
for (auto& element : touchPoints_) {
|
||||
devX = devX + fabs(element.second.x - focalX);
|
||||
devY = devY + fabs(element.second.y - focalY);
|
||||
}
|
||||
double aveDevX = devX / touchPoints_.size();
|
||||
double aveDevY = devY / touchPoints_.size();
|
||||
|
||||
// compute zoom distance
|
||||
double zoomDistance = sqrt(pow(aveDevX, 2) + pow(aveDevY, 2));
|
||||
|
||||
return zoomDistance;
|
||||
}
|
||||
|
||||
Offset PinchRecognizer::ComputePinchCenter()
|
||||
{
|
||||
double sumOfX = 0.0;
|
||||
double sumOfY = 0.0;
|
||||
for (auto& element : touchPoints_) {
|
||||
sumOfX = sumOfX + element.second.x;
|
||||
sumOfY = sumOfY + element.second.y;
|
||||
}
|
||||
double focalX = sumOfX / touchPoints_.size();
|
||||
double focalY = sumOfY / touchPoints_.size();
|
||||
|
||||
Offset pinchCenter = Offset(focalX, focalY);
|
||||
|
||||
return pinchCenter;
|
||||
}
|
||||
|
||||
void PinchRecognizer::Reset()
|
||||
{
|
||||
touchPoints_.clear();
|
||||
state_ = DetectState::READY;
|
||||
pendingEnd_ = false;
|
||||
pendingCancel_ = false;
|
||||
}
|
||||
|
||||
void PinchRecognizer::SendCallbackMsg(const std::unique_ptr<GestureEventFunc>& callback)
|
||||
{
|
||||
if (callback && *callback) {
|
||||
GestureEvent info;
|
||||
info.SetTimeStamp(time_);
|
||||
info.SetScale(scale_);
|
||||
info.SetPinchCenter(pinchCenter_);
|
||||
info.SetDeviceId(deviceId_);
|
||||
info.SetSourceDevice(deviceType_);
|
||||
info.SetTarget(GetEventTarget().value_or(EventTarget()));
|
||||
(*callback)(info);
|
||||
}
|
||||
}
|
||||
|
||||
bool PinchRecognizer::ReconcileFrom(const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
RefPtr<PinchRecognizer> curr = AceType::DynamicCast<PinchRecognizer>(recognizer);
|
||||
if (!curr) {
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (curr->fingers_ != fingers_ || curr->distance_ != distance_ || curr->priorityMask_ != priorityMask_) {
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
onActionStart_ = std::move(curr->onActionStart_);
|
||||
onActionUpdate_ = std::move(curr->onActionUpdate_);
|
||||
onActionEnd_ = std::move(curr->onActionEnd_);
|
||||
onActionCancel_ = std::move(curr->onActionCancel_);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_PINCH_RECOGNIZER_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_PINCH_RECOGNIZER_H
|
||||
|
||||
#include <cmath>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
|
||||
#include "core/components_ng/gestures/recognizers/multi_fingers_recognizer.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
class PinchRecognizer : public MultiFingersRecognizer {
|
||||
DECLARE_ACE_TYPE(PinchRecognizer, MultiFingersRecognizer);
|
||||
|
||||
public:
|
||||
PinchRecognizer(int32_t fingers, double distance) : distance_(distance)
|
||||
{
|
||||
fingers_ = fingers;
|
||||
}
|
||||
~PinchRecognizer() override = default;
|
||||
|
||||
void OnAccepted() override;
|
||||
void OnRejected() override;
|
||||
|
||||
private:
|
||||
void HandleTouchDownEvent(const TouchEvent& event) override;
|
||||
void HandleTouchUpEvent(const TouchEvent& event) override;
|
||||
void HandleTouchMoveEvent(const TouchEvent& event) override;
|
||||
void HandleTouchCancelEvent(const TouchEvent& event) override;
|
||||
void HandleTouchDownEvent(const AxisEvent& event) override;
|
||||
void HandleTouchUpEvent(const AxisEvent& event) override;
|
||||
void HandleTouchMoveEvent(const AxisEvent& event) override;
|
||||
void HandleTouchCancelEvent(const AxisEvent& event) override;
|
||||
bool ReconcileFrom(const RefPtr<GestureRecognizer>& recognizer) override;
|
||||
double ComputeAverageDeviation();
|
||||
void Reset();
|
||||
void SendCallbackMsg(const std::unique_ptr<GestureEventFunc>& callback);
|
||||
Offset ComputePinchCenter();
|
||||
void OnFlushTouchEventsBegin() override;
|
||||
void OnFlushTouchEventsEnd() override;
|
||||
|
||||
double distance_ = 0.0;
|
||||
double initialDev_ = 0.0;
|
||||
double currentDev_ = 0.0;
|
||||
double scale_ = 1.0;
|
||||
Offset pinchCenter_;
|
||||
TimeStamp time_;
|
||||
std::map<int32_t, TouchEvent> touchPoints_;
|
||||
bool pendingEnd_ = false;
|
||||
bool pendingCancel_ = false;
|
||||
bool isFlushTouchEventsEnd_ = false;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_PINCH_RECOGNIZER_H
|
@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "core/components_ng/gestures/recognizers/rotation_recognizer.h"
|
||||
|
||||
#include "base/geometry/offset.h"
|
||||
#include "base/log/log.h"
|
||||
#include "core/components_ng/gestures/gesture_referee.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr int32_t MAX_ROTATION_FINGERS = 5;
|
||||
|
||||
} // namespace
|
||||
|
||||
void RotationRecognizer::OnAccepted()
|
||||
{
|
||||
SendCallbackMsg(onActionStart_);
|
||||
|
||||
if (pendingEnd_) {
|
||||
SendCallbackMsg(onActionEnd_);
|
||||
Reset();
|
||||
} else if (pendingCancel_) {
|
||||
SendCancelMsg();
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
||||
void RotationRecognizer::OnRejected()
|
||||
{
|
||||
LOGD("rotation gesture has been rejected!");
|
||||
Reset();
|
||||
}
|
||||
|
||||
void RotationRecognizer::HandleTouchDownEvent(const TouchEvent& event)
|
||||
{
|
||||
LOGD("rotation recognizer receives touch down event, begin to detect rotation event");
|
||||
if (fingers_ > MAX_ROTATION_FINGERS) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state_ == DetectState::READY) {
|
||||
AddToReferee(event.id, AceType::Claim(this));
|
||||
touchPoints_[event.id] = event;
|
||||
if (static_cast<int32_t>(touchPoints_.size()) == fingers_) {
|
||||
initialAngle_ = ComputeAngle();
|
||||
state_ = DetectState::DETECTING;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RotationRecognizer::HandleTouchUpEvent(const TouchEvent& event)
|
||||
{
|
||||
LOGD("rotation recognizer receives touch up event");
|
||||
auto itr = touchPoints_.find(event.id);
|
||||
if (itr == touchPoints_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
touchPoints_.erase(itr);
|
||||
|
||||
if (state_ != DetectState::DETECTED) {
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
return;
|
||||
}
|
||||
|
||||
GestureEvent info;
|
||||
info.SetTimeStamp(time_);
|
||||
info.SetAngle(resultAngle_);
|
||||
if (refereeState_ == RefereeState::SUCCEED) {
|
||||
SendCallbackMsg(onActionEnd_);
|
||||
Reset();
|
||||
} else {
|
||||
pendingEnd_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void RotationRecognizer::HandleTouchMoveEvent(const TouchEvent& event)
|
||||
{
|
||||
LOGD("rotation recognizer receives touch move event");
|
||||
auto itr = touchPoints_.find(event.id);
|
||||
if (itr == touchPoints_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state_ == DetectState::READY) {
|
||||
touchPoints_[event.id] = event;
|
||||
return;
|
||||
}
|
||||
|
||||
touchPoints_[event.id] = event;
|
||||
currentAngle_ = ComputeAngle();
|
||||
time_ = event.time;
|
||||
|
||||
if (state_ == DetectState::DETECTING) {
|
||||
double diffAngle = fabs((currentAngle_ - initialAngle_));
|
||||
if (GreatOrEqual(diffAngle, angle_)) {
|
||||
resultAngle_ = ChangeValueRange(currentAngle_ - initialAngle_);
|
||||
state_ = DetectState::DETECTED;
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::ACCEPT);
|
||||
}
|
||||
} else if (state_ == DetectState::DETECTED && refereeState_ == RefereeState::SUCCEED) {
|
||||
resultAngle_ = ChangeValueRange(currentAngle_ - initialAngle_);
|
||||
SendCallbackMsg(onActionUpdate_);
|
||||
}
|
||||
}
|
||||
|
||||
void RotationRecognizer::HandleTouchCancelEvent(const TouchEvent& event)
|
||||
{
|
||||
LOGD("rotation recognizer receives touch cancel event");
|
||||
if (state_ == DetectState::READY || state_ == DetectState::DETECTING) {
|
||||
LOGD("cancel rotation gesture detect, try to reject it");
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (refereeState_ == RefereeState::SUCCEED) {
|
||||
SendCancelMsg();
|
||||
Reset();
|
||||
} else {
|
||||
pendingCancel_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
double RotationRecognizer::ComputeAngle()
|
||||
{
|
||||
double fx = touchPoints_[0].x;
|
||||
double fy = touchPoints_[0].y;
|
||||
double sx = touchPoints_[1].x;
|
||||
double sy = touchPoints_[1].y;
|
||||
double angle = atan2(fy - sy, fx - sx) * 180.0 / M_PI;
|
||||
return angle;
|
||||
}
|
||||
|
||||
// Map the value range to -180 to 180
|
||||
double RotationRecognizer::ChangeValueRange(double value)
|
||||
{
|
||||
double result = 0.0;
|
||||
if (LessOrEqual(value, -180.0)) {
|
||||
result = value + 360.0;
|
||||
} else if (GreatNotEqual(value, 180.0)) {
|
||||
result = value - 360.0;
|
||||
} else {
|
||||
result = value;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void RotationRecognizer::Reset()
|
||||
{
|
||||
touchPoints_.clear();
|
||||
state_ = DetectState::READY;
|
||||
pendingEnd_ = false;
|
||||
pendingCancel_ = false;
|
||||
}
|
||||
|
||||
void RotationRecognizer::SendCallbackMsg(const std::unique_ptr<GestureEventFunc>& callback)
|
||||
{
|
||||
if (callback && *callback) {
|
||||
GestureEvent info;
|
||||
info.SetTimeStamp(time_);
|
||||
info.SetAngle(resultAngle_);
|
||||
info.SetDeviceId(deviceId_);
|
||||
info.SetSourceDevice(deviceType_);
|
||||
info.SetTarget(GetEventTarget().value_or(EventTarget()));
|
||||
(*callback)(info);
|
||||
}
|
||||
}
|
||||
|
||||
bool RotationRecognizer::ReconcileFrom(const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
RefPtr<RotationRecognizer> curr = AceType::DynamicCast<RotationRecognizer>(recognizer);
|
||||
if (!curr) {
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (curr->fingers_ != fingers_ || !NearEqual(curr->angle_, angle_) || curr->priorityMask_ != priorityMask_) {
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
onActionStart_ = std::move(curr->onActionStart_);
|
||||
onActionUpdate_ = std::move(curr->onActionUpdate_);
|
||||
onActionEnd_ = std::move(curr->onActionEnd_);
|
||||
onActionCancel_ = std::move(curr->onActionCancel_);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_ROTATION_RECOGNIZER_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_ROTATION_RECOGNIZER_H
|
||||
|
||||
#include <cmath>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
|
||||
#include "core/components_ng/gestures/recognizers/multi_fingers_recognizer.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
class RotationRecognizer : public MultiFingersRecognizer {
|
||||
DECLARE_ACE_TYPE(RotationRecognizer, MultiFingersRecognizer);
|
||||
|
||||
public:
|
||||
RotationRecognizer(int32_t fingers, double angle) : angle_(angle)
|
||||
{
|
||||
fingers_ = fingers;
|
||||
}
|
||||
~RotationRecognizer() override = default;
|
||||
|
||||
void OnAccepted() override;
|
||||
void OnRejected() override;
|
||||
|
||||
private:
|
||||
void HandleTouchDownEvent(const TouchEvent& event) override;
|
||||
void HandleTouchUpEvent(const TouchEvent& event) override;
|
||||
void HandleTouchMoveEvent(const TouchEvent& event) override;
|
||||
void HandleTouchCancelEvent(const TouchEvent& event) override;
|
||||
bool ReconcileFrom(const RefPtr<GestureRecognizer>& recognizer) override;
|
||||
double ComputeAngle();
|
||||
void Reset();
|
||||
void SendCallbackMsg(const std::unique_ptr<GestureEventFunc>& callback);
|
||||
static double ChangeValueRange(double value);
|
||||
|
||||
double angle_ = 0.0;
|
||||
double initialAngle_ = 0.0;
|
||||
double currentAngle_ = 0.0;
|
||||
double resultAngle_ = 0.0;
|
||||
TimeStamp time_;
|
||||
std::map<int32_t, TouchEvent> touchPoints_;
|
||||
bool pendingEnd_ = false;
|
||||
bool pendingCancel_ = false;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_ROTATION_RECOGNIZER_H
|
@ -0,0 +1,238 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "core/components_ng/gestures/recognizers/sequenced_recognizer.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "base/thread/task_executor.h"
|
||||
#include "base/utils/utils.h"
|
||||
#include "core/pipeline_ng/pipeline_context.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
namespace {
|
||||
constexpr int32_t SEQUENCE_GESTURE_TIMEOUT = 300;
|
||||
}
|
||||
|
||||
void SequencedRecognizer::OnAccepted()
|
||||
{
|
||||
LOGD("the sequenced gesture recognizer has been accepted.");
|
||||
if (activeIndex >= recognizers_.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t touchId : refereePointers_) {
|
||||
recognizers_[activeIndex]->SetCoordinateOffset(coordinateOffset_);
|
||||
recognizers_[activeIndex]->OnAccepted(touchId);
|
||||
}
|
||||
recognizers_[activeIndex]->SetRefereeState(RefereeState::SUCCEED);
|
||||
}
|
||||
|
||||
void SequencedRecognizer::OnRejected()
|
||||
{
|
||||
LOGD("the sequenced gesture recognizer has been rejected!");
|
||||
if (activeIndex >= recognizers_.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t touchId : refereePointers_) {
|
||||
auto recognizer = AceType::DynamicCast<MultiFingersRecognizer>(recognizers_[activeIndex]);
|
||||
if (recognizer && recognizer->GetRefereeState() == RefereeState::SUCCEED) {
|
||||
recognizer->SetRefereePointer(touchId);
|
||||
}
|
||||
recognizers_[activeIndex]->OnRejected(touchId);
|
||||
}
|
||||
recognizers_[activeIndex]->SetRefereeState(RefereeState::FAIL);
|
||||
|
||||
if (activeIndex != 0) {
|
||||
SendCancelMsg();
|
||||
}
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
void SequencedRecognizer::OnPending(size_t touchId)
|
||||
{
|
||||
LOGD("the sequenced gesture recognizer is in pending! the touch id is %{public}zu", touchId);
|
||||
if (activeIndex >= recognizers_.size()) {
|
||||
return;
|
||||
}
|
||||
if (recognizers_[activeIndex]->GetDetectState() == DetectState::DETECTED) {
|
||||
recognizers_[activeIndex]->OnAccepted(touchId);
|
||||
recognizers_[activeIndex]->SetRefereeState(RefereeState::SUCCEED);
|
||||
} else {
|
||||
recognizers_[activeIndex]->OnPending(touchId);
|
||||
}
|
||||
}
|
||||
|
||||
bool SequencedRecognizer::HandleEvent(const TouchEvent& point)
|
||||
{
|
||||
RefPtr<GestureRecognizer> curRecognizer = recognizers_[activeIndex];
|
||||
LOGD("dispatch to the %{public}zu gesture recognizer, event type is %{public}zu", activeIndex, point.type);
|
||||
switch (point.type) {
|
||||
case TouchType::MOVE:
|
||||
curPoints_[point.id] = point;
|
||||
curRecognizer->HandleEvent(point);
|
||||
break;
|
||||
case TouchType::DOWN:
|
||||
if (curPoints_.empty()) {
|
||||
deadlineTimer_.Cancel();
|
||||
}
|
||||
curPoints_[point.id] = point;
|
||||
curRecognizer->HandleEvent(point);
|
||||
break;
|
||||
case TouchType::UP:
|
||||
curPoints_.erase(point.id);
|
||||
curRecognizer->HandleEvent(point);
|
||||
break;
|
||||
case TouchType::CANCEL:
|
||||
curPoints_.erase(point.id);
|
||||
curRecognizer->HandleEvent(point);
|
||||
break;
|
||||
default:
|
||||
LOGW("unknown touch type");
|
||||
break;
|
||||
}
|
||||
|
||||
DetectState currState = curRecognizer->GetDetectState();
|
||||
if (curRecognizer->GetRefereeState() == RefereeState::SUCCEED && currState != DetectState::DETECTED) {
|
||||
// The current recognizer has already been detected, but the touch event destroy the state.
|
||||
// Should pass the touch point to the next recognizer.
|
||||
activeIndex++;
|
||||
if (activeIndex >= recognizers_.size()) {
|
||||
LOGD("gesture reset to the initial state ");
|
||||
Reset();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (curPoints_.empty()) {
|
||||
DeadlineTimer();
|
||||
} else {
|
||||
auto iter = curPoints_.begin();
|
||||
while (iter != curPoints_.end()) {
|
||||
iter->second.type = TouchType::DOWN;
|
||||
recognizers_[activeIndex]->HandleEvent(iter->second);
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void SequencedRecognizer::OnFlushTouchEventsBegin()
|
||||
{
|
||||
for (auto& recognizer : recognizers_) {
|
||||
recognizer->OnFlushTouchEventsBegin();
|
||||
}
|
||||
}
|
||||
|
||||
void SequencedRecognizer::OnFlushTouchEventsEnd()
|
||||
{
|
||||
for (auto& recognizer : recognizers_) {
|
||||
recognizer->OnFlushTouchEventsEnd();
|
||||
}
|
||||
}
|
||||
|
||||
void SequencedRecognizer::BatchAdjudicate(
|
||||
const std::set<size_t>& touchIds, const RefPtr<GestureRecognizer>& recognizer, GestureDisposal disposal)
|
||||
{
|
||||
if (disposal == GestureDisposal::ACCEPT) {
|
||||
LOGD("the sub recognizer %{public}s ask for accept", AceType::TypeName(recognizer));
|
||||
if (activeIndex == (recognizers_.size() - 1)) {
|
||||
state_ = DetectState::DETECTED;
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::ACCEPT);
|
||||
} else {
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::PENDING);
|
||||
}
|
||||
} else if (disposal == GestureDisposal::REJECT) {
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
} else {
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::PENDING);
|
||||
}
|
||||
}
|
||||
|
||||
void SequencedRecognizer::AddToReferee(size_t touchId, const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
if (state_ == DetectState::READY) {
|
||||
state_ = DetectState::DETECTING;
|
||||
}
|
||||
|
||||
recognizer->SetRefereeState(RefereeState::DETECTING);
|
||||
MultiFingersRecognizer::AddToReferee(touchId, AceType::Claim(this));
|
||||
}
|
||||
|
||||
void SequencedRecognizer::Reset()
|
||||
{
|
||||
activeIndex = 0;
|
||||
state_ = DetectState::READY;
|
||||
|
||||
for (auto& recognizer : recognizers_) {
|
||||
recognizer->SetRefereeState(RefereeState::DETECTING);
|
||||
}
|
||||
curPoints_.clear();
|
||||
}
|
||||
|
||||
void SequencedRecognizer::DeadlineTimer()
|
||||
{
|
||||
auto context = PipelineContext::GetCurrentContext();
|
||||
CHECK_NULL_VOID(context);
|
||||
|
||||
auto&& callback = [weakPtr = AceType::WeakClaim(this)]() {
|
||||
auto refPtr = weakPtr.Upgrade();
|
||||
if (refPtr) {
|
||||
refPtr->HandleOverdueDeadline();
|
||||
} else {
|
||||
LOGE("fail to handle overdue deadline due to context is nullptr");
|
||||
}
|
||||
};
|
||||
|
||||
deadlineTimer_.Reset(callback);
|
||||
auto taskExecutor = SingleTaskExecutor::Make(context->GetTaskExecutor(), TaskExecutor::TaskType::UI);
|
||||
taskExecutor.PostDelayedTask(deadlineTimer_, SEQUENCE_GESTURE_TIMEOUT);
|
||||
}
|
||||
|
||||
void SequencedRecognizer::HandleOverdueDeadline()
|
||||
{
|
||||
LOGI("sequence gesture recognizer does not receive touch down in time");
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
}
|
||||
|
||||
bool SequencedRecognizer::ReconcileFrom(const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
RefPtr<SequencedRecognizer> curr = AceType::DynamicCast<SequencedRecognizer>(recognizer);
|
||||
if (!curr) {
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (recognizers_.size() != curr->recognizers_.size() || priorityMask_ != curr->priorityMask_) {
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < recognizers_.size(); i++) {
|
||||
if (!recognizers_[i]->ReconcileFrom(curr->recognizers_[i])) {
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
onActionCancel_ = std::move(curr->onActionCancel_);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_SEQUENCED_RECOGNIZER_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_SEQUENCED_RECOGNIZER_H
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "base/thread/cancelable_callback.h"
|
||||
#include "core/components_ng/gestures/recognizers/multi_fingers_recognizer.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
// SequencedRecognizer identifies only single click events.
|
||||
// For long press and double click, see: LongPressRecognizer and DoubleClickRecognizer.
|
||||
class ACE_EXPORT SequencedRecognizer : public MultiFingersRecognizer {
|
||||
DECLARE_ACE_TYPE(SequencedRecognizer, MultiFingersRecognizer);
|
||||
|
||||
public:
|
||||
SequencedRecognizer(const std::vector<RefPtr<GestureRecognizer>>& recognizers)
|
||||
{
|
||||
for (auto& recognizer : recognizers) {
|
||||
recognizer->SetGestureGroup(AceType::WeakClaim(this));
|
||||
}
|
||||
recognizers_ = recognizers;
|
||||
}
|
||||
~SequencedRecognizer() override = default;
|
||||
void OnAccepted() override;
|
||||
void OnRejected() override;
|
||||
bool HandleEvent(const TouchEvent& point) override;
|
||||
void OnPending(size_t touchId) override;
|
||||
void OnFlushTouchEventsBegin() override;
|
||||
void OnFlushTouchEventsEnd() override;
|
||||
|
||||
private:
|
||||
void HandleTouchDownEvent(const TouchEvent& event) override {};
|
||||
void HandleTouchUpEvent(const TouchEvent& event) override {};
|
||||
void HandleTouchMoveEvent(const TouchEvent& event) override {};
|
||||
void HandleTouchCancelEvent(const TouchEvent& event) override {};
|
||||
void BatchAdjudicate(const std::set<size_t>& touchIds, const RefPtr<GestureRecognizer>& recognizer,
|
||||
GestureDisposal disposal) override;
|
||||
void AddToReferee(size_t touchId, const RefPtr<GestureRecognizer>& recognizer) override;
|
||||
bool ReconcileFrom(const RefPtr<GestureRecognizer>& recognizer) override;
|
||||
void Reset();
|
||||
void DeadlineTimer();
|
||||
void HandleOverdueDeadline();
|
||||
|
||||
std::vector<RefPtr<GestureRecognizer>> recognizers_;
|
||||
std::map<int32_t, TouchEvent> curPoints_;
|
||||
size_t activeIndex = 0;
|
||||
CancelableCallback<void()> deadlineTimer_;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_SEQUENCED_RECOGNIZER_H
|
@ -0,0 +1,483 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "core/components_ng/gestures/recognizers/swipe_recognizer.h"
|
||||
|
||||
#include "base/geometry/offset.h"
|
||||
#include "base/log/log.h"
|
||||
#include "core/components_ng/gestures/gesture_referee.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr int32_t MAX_SWIPE_FINGERS = 10;
|
||||
constexpr int32_t AXIS_SWIPE_FINGERS = 1;
|
||||
constexpr int32_t RATIO_MS_TO_S = 1000;
|
||||
constexpr int32_t RATIO_US_TO_MS = 1000;
|
||||
constexpr double ANGLE_SUM_OF_TRIANGLE = 180.0;
|
||||
|
||||
double ChangeValueRange(double value)
|
||||
{
|
||||
double result = 0.0;
|
||||
if (LessOrEqual(value, -180.0)) {
|
||||
result = value + 360.0;
|
||||
} else if (GreatNotEqual(value, 180.0)) {
|
||||
result = value - 360.0;
|
||||
} else {
|
||||
result = value;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void SwipeRecognizer::OnAccepted()
|
||||
{
|
||||
if (slidingEnd_) {
|
||||
LOGD("swipe gesture recognizer has sliding end event when waiting to be accepted");
|
||||
Reset();
|
||||
} else if (slidingCancel_) {
|
||||
SendCancelMsg();
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
||||
void SwipeRecognizer::OnRejected()
|
||||
{
|
||||
LOGD("swipe gesture has been rejected!");
|
||||
Reset();
|
||||
}
|
||||
|
||||
void SwipeRecognizer::HandleTouchDownEvent(const TouchEvent& event)
|
||||
{
|
||||
LOGD("swipe recognizer receives touch down event, begin to detect swipe event");
|
||||
fingers_ = newFingers_;
|
||||
speed_ = newSpeed_;
|
||||
direction_ = newDirection_;
|
||||
|
||||
if (fingers_ > MAX_SWIPE_FINGERS) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (direction_.type == SwipeDirection::NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
touchPoints_[event.id] = event;
|
||||
fingersDistance_[event.id] = Offset();
|
||||
touchDownTime_ = event.time;
|
||||
|
||||
if (state_ == DetectState::READY) {
|
||||
AddToReferee(event.id, AceType::Claim(this));
|
||||
if (static_cast<int32_t>(refereePointers_.size()) == fingers_) {
|
||||
initialAngle_ = ComputeAngle();
|
||||
state_ = DetectState::DETECTING;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SwipeRecognizer::HandleTouchDownEvent(const AxisEvent& event)
|
||||
{
|
||||
LOGD("swipe recognizer receives touch down event, begin to detect swipe event");
|
||||
fingers_ = newFingers_;
|
||||
speed_ = newSpeed_;
|
||||
direction_ = newDirection_;
|
||||
|
||||
if (fingers_ != AXIS_SWIPE_FINGERS) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (direction_.type == SwipeDirection::NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
axisEventStart_ = event;
|
||||
axisVerticalTotal_ = 0.0;
|
||||
axisHorizontalTotal_ = 0.0;
|
||||
touchDownTime_ = event.time;
|
||||
|
||||
if (state_ == DetectState::READY) {
|
||||
initialAngle_ = ComputeAngle(event);
|
||||
state_ = DetectState::DETECTING;
|
||||
}
|
||||
}
|
||||
|
||||
void SwipeRecognizer::HandleTouchUpEvent(const TouchEvent& event)
|
||||
{
|
||||
LOGD("swipe recognizer receives touch up event");
|
||||
auto itr = touchPoints_.find(event.id);
|
||||
if (itr == touchPoints_.end()) {
|
||||
return;
|
||||
}
|
||||
auto itf = fingersDistance_.find(event.id);
|
||||
if (itf == fingersDistance_.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
globalPoint_ = Point(event.x, event.y);
|
||||
touchPoints_.erase(itr);
|
||||
auto distanceData = fingersDistance_;
|
||||
fingersDistance_.erase(itf);
|
||||
if (state_ == DetectState::READY) {
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (state_ == DetectState::DETECTING) {
|
||||
size_t inRefereeNum = refereePointers_.size();
|
||||
bool inReferee = IsInReferee(static_cast<size_t>(event.id));
|
||||
if (inReferee) {
|
||||
inRefereeNum--;
|
||||
}
|
||||
|
||||
if (static_cast<int32_t>(touchPoints_.size()) < fingers_ || inRefereeNum < 1) {
|
||||
LOGD("this gesture is not swipe, try to reject it");
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (inReferee) {
|
||||
DelFromReferee(event.id, AceType::Claim(this));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (static_cast<int32_t>(touchPoints_.size()) <= fingers_) {
|
||||
if (refereeState_ == RefereeState::SUCCEED) {
|
||||
double averageSpeed = 0.0;
|
||||
bool isAvailable = true;
|
||||
for (const auto& element : distanceData) {
|
||||
Offset offset = element.second;
|
||||
double distance = 0.0;
|
||||
if ((direction_.type & SwipeDirection::ALL) == SwipeDirection::ALL) {
|
||||
distance = offset.GetDistance();
|
||||
} else {
|
||||
if ((direction_.type & SwipeDirection::HORIZONTAL) != 0) {
|
||||
distance = std::abs(offset.GetX());
|
||||
} else if ((direction_.type & SwipeDirection::VERTICAL) != 0) {
|
||||
distance = std::abs(offset.GetY());
|
||||
}
|
||||
}
|
||||
auto slidingTime = event.time - touchDownTime_;
|
||||
auto duration_ms =
|
||||
std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1, 1000>>>(slidingTime);
|
||||
double slidingSpeed = (distance / duration_ms.count()) * 1000;
|
||||
if (speed_ >= slidingSpeed) {
|
||||
isAvailable = false;
|
||||
break;
|
||||
}
|
||||
averageSpeed += slidingSpeed;
|
||||
}
|
||||
if (isAvailable) {
|
||||
resultSpeed_ = averageSpeed / distanceData.size();
|
||||
SendCallbackMsg(onAction_);
|
||||
}
|
||||
Reset();
|
||||
} else {
|
||||
slidingEnd_ = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SwipeRecognizer::HandleTouchUpEvent(const AxisEvent& event)
|
||||
{
|
||||
LOGD("swipe recognizer receives touch up event");
|
||||
if (fingers_ != AXIS_SWIPE_FINGERS) {
|
||||
return;
|
||||
}
|
||||
globalPoint_ = Point(event.x, event.y);
|
||||
if (state_ == DetectState::READY) {
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (state_ == DetectState::DETECTING) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto slidingTime = event.time - touchDownTime_;
|
||||
auto duration_ms =
|
||||
std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1, RATIO_US_TO_MS>>>(slidingTime);
|
||||
double verticalMoveTotal = axisVerticalTotal_ * DP_PER_LINE_DESKTOP * LINE_NUMBER_DESKTOP / MOUSE_WHEEL_DEGREES;
|
||||
double horizontalMoveTotal = axisHorizontalTotal_ * DP_PER_LINE_DESKTOP * LINE_NUMBER_DESKTOP / MOUSE_WHEEL_DEGREES;
|
||||
resultSpeed_ = Offset(horizontalMoveTotal, verticalMoveTotal).GetDistance() / duration_ms.count() * RATIO_MS_TO_S;
|
||||
if (resultSpeed_ > speed_) {
|
||||
SendCallbackMsg(onAction_);
|
||||
}
|
||||
Reset();
|
||||
}
|
||||
|
||||
void SwipeRecognizer::HandleTouchMoveEvent(const TouchEvent& event)
|
||||
{
|
||||
LOGD("swipe recognizer receives touch move event");
|
||||
auto itr = touchPoints_.find(event.id);
|
||||
if (itr == touchPoints_.end()) {
|
||||
return;
|
||||
}
|
||||
auto itf = fingersDistance_.find(event.id);
|
||||
if (itf == fingersDistance_.end()) {
|
||||
return;
|
||||
}
|
||||
globalPoint_ = Point(event.x, event.y);
|
||||
if (state_ == DetectState::READY) {
|
||||
touchPoints_[event.id] = event;
|
||||
return;
|
||||
}
|
||||
|
||||
Offset moveDistance = event.GetOffset() - touchPoints_[event.id].GetOffset();
|
||||
fingersDistance_[event.id] = itf->second + moveDistance;
|
||||
touchPoints_[event.id] = event;
|
||||
currentAngle_ = ComputeAngle();
|
||||
time_ = event.time;
|
||||
|
||||
if (state_ == DetectState::DETECTING) {
|
||||
double diffAngle = fabs((currentAngle_ - initialAngle_));
|
||||
if (GreatOrEqual(diffAngle, angle_)) {
|
||||
resultAngle_ = ChangeValueRange(currentAngle_ - initialAngle_);
|
||||
}
|
||||
auto result = ParseFingersOffset();
|
||||
if (result == GestureAcceptResult::ACCEPT) {
|
||||
state_ = DetectState::DETECTED;
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::ACCEPT);
|
||||
} else if (result == GestureAcceptResult::REJECT) {
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
}
|
||||
} else if (state_ == DetectState::DETECTED && refereeState_ == RefereeState::SUCCEED) {
|
||||
resultAngle_ = ChangeValueRange(currentAngle_ - initialAngle_);
|
||||
}
|
||||
}
|
||||
|
||||
void SwipeRecognizer::HandleTouchMoveEvent(const AxisEvent& event)
|
||||
{
|
||||
LOGD("swipe recognizer receives touch move event");
|
||||
if (fingers_ != AXIS_SWIPE_FINGERS) {
|
||||
return;
|
||||
}
|
||||
globalPoint_ = Point(event.x, event.y);
|
||||
if (state_ == DetectState::READY) {
|
||||
axisEventStart_ = event;
|
||||
return;
|
||||
}
|
||||
|
||||
axisVerticalTotal_ += fabs(event.verticalAxis);
|
||||
axisHorizontalTotal_ += fabs(event.horizontalAxis);
|
||||
currentAngle_ = ComputeAngle(event);
|
||||
time_ = event.time;
|
||||
|
||||
if (state_ == DetectState::DETECTING) {
|
||||
if (GreatOrEqual(fabs(currentAngle_), angle_)) {
|
||||
resultAngle_ = ChangeValueRange(currentAngle_);
|
||||
}
|
||||
auto result = ParseAxisOffset();
|
||||
if (result == GestureAcceptResult::ACCEPT) {
|
||||
state_ = DetectState::DETECTED;
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::ACCEPT);
|
||||
} else if (result == GestureAcceptResult::REJECT) {
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
}
|
||||
} else if (state_ == DetectState::DETECTED) {
|
||||
resultAngle_ = ChangeValueRange(currentAngle_);
|
||||
}
|
||||
}
|
||||
|
||||
void SwipeRecognizer::HandleTouchCancelEvent(const TouchEvent& event)
|
||||
{
|
||||
LOGD("swipe recognizer receives touch cancel event");
|
||||
if (state_ == DetectState::READY || state_ == DetectState::DETECTING) {
|
||||
LOGD("cancel swipe gesture detect, try to reject it");
|
||||
Adjudicate(AceType::Claim(this), GestureDisposal::REJECT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (refereeState_ == RefereeState::SUCCEED) {
|
||||
SendCancelMsg();
|
||||
Reset();
|
||||
} else {
|
||||
slidingCancel_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void SwipeRecognizer::HandleTouchCancelEvent(const AxisEvent& event)
|
||||
{
|
||||
SendCancelMsg();
|
||||
Reset();
|
||||
}
|
||||
|
||||
SwipeRecognizer::GestureAcceptResult SwipeRecognizer::ParseFingersOffset() const
|
||||
{
|
||||
if ((direction_.type & SwipeDirection::ALL) == SwipeDirection::ALL) {
|
||||
for (const auto& element : fingersDistance_) {
|
||||
Offset offset = element.second;
|
||||
double distance = offset.GetDistance();
|
||||
if (fabs(distance) < DEFAULT_SLIDE_DISTANCE) {
|
||||
return GestureAcceptResult::DETECTING;
|
||||
}
|
||||
}
|
||||
return GestureAcceptResult::ACCEPT;
|
||||
}
|
||||
|
||||
for (const auto& element : fingersDistance_) {
|
||||
Offset offset = element.second;
|
||||
if (fabs(offset.GetX()) > fabs(offset.GetY())) {
|
||||
if ((direction_.type & SwipeDirection::HORIZONTAL) != 0) {
|
||||
double offsetX = offset.GetX();
|
||||
if (fabs(offsetX) < DEFAULT_SLIDE_DISTANCE) {
|
||||
return GestureAcceptResult::DETECTING;
|
||||
}
|
||||
} else {
|
||||
return GestureAcceptResult::REJECT;
|
||||
}
|
||||
} else {
|
||||
if ((direction_.type & SwipeDirection::VERTICAL) != 0) {
|
||||
double offsetY = offset.GetY();
|
||||
if (fabs(offsetY) < DEFAULT_SLIDE_DISTANCE) {
|
||||
return GestureAcceptResult::DETECTING;
|
||||
}
|
||||
} else {
|
||||
return GestureAcceptResult::REJECT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return GestureAcceptResult::ACCEPT;
|
||||
}
|
||||
|
||||
SwipeRecognizer::GestureAcceptResult SwipeRecognizer::ParseAxisOffset() const
|
||||
{
|
||||
if ((direction_.type & SwipeDirection::ALL) == SwipeDirection::ALL) {
|
||||
double distance = Offset(axisHorizontalTotal_, axisVerticalTotal_).GetDistance();
|
||||
if (fabs(distance) < DEFAULT_SLIDE_DISTANCE) {
|
||||
return GestureAcceptResult::DETECTING;
|
||||
}
|
||||
return GestureAcceptResult::ACCEPT;
|
||||
}
|
||||
|
||||
if (axisHorizontalTotal_ > axisVerticalTotal_) {
|
||||
if ((direction_.type & SwipeDirection::HORIZONTAL) != 0) {
|
||||
if (axisHorizontalTotal_ < DEFAULT_SLIDE_DISTANCE) {
|
||||
return GestureAcceptResult::DETECTING;
|
||||
}
|
||||
} else {
|
||||
return GestureAcceptResult::REJECT;
|
||||
}
|
||||
} else {
|
||||
if ((direction_.type & SwipeDirection::VERTICAL) != 0) {
|
||||
if (axisVerticalTotal_ < DEFAULT_SLIDE_DISTANCE) {
|
||||
return GestureAcceptResult::DETECTING;
|
||||
}
|
||||
} else {
|
||||
return GestureAcceptResult::REJECT;
|
||||
}
|
||||
}
|
||||
|
||||
return GestureAcceptResult::ACCEPT;
|
||||
}
|
||||
|
||||
void SwipeRecognizer::Reset()
|
||||
{
|
||||
axisHorizontalTotal_ = 0.0;
|
||||
axisVerticalTotal_ = 0.0;
|
||||
touchPoints_.clear();
|
||||
fingersDistance_.clear();
|
||||
resultSpeed_ = 0.0;
|
||||
state_ = DetectState::READY;
|
||||
slidingEnd_ = false;
|
||||
slidingCancel_ = false;
|
||||
}
|
||||
|
||||
void SwipeRecognizer::SendCallbackMsg(const std::unique_ptr<GestureEventFunc>& callback)
|
||||
{
|
||||
if (callback && *callback) {
|
||||
GestureEvent info;
|
||||
info.SetTimeStamp(time_);
|
||||
info.SetGlobalPoint(globalPoint_);
|
||||
info.SetAngle(resultAngle_);
|
||||
if (deviceType_ == SourceType::MOUSE) {
|
||||
info.SetSpeed(0.0);
|
||||
} else {
|
||||
info.SetSpeed(resultSpeed_);
|
||||
}
|
||||
info.SetSourceDevice(deviceType_);
|
||||
info.SetDeviceId(deviceId_);
|
||||
info.SetTarget(GetEventTarget().value_or(EventTarget()));
|
||||
(*callback)(info);
|
||||
}
|
||||
}
|
||||
|
||||
bool SwipeRecognizer::ReconcileFrom(const RefPtr<GestureRecognizer>& recognizer)
|
||||
{
|
||||
RefPtr<SwipeRecognizer> curr = AceType::DynamicCast<SwipeRecognizer>(recognizer);
|
||||
if (!curr) {
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (curr->fingers_ != fingers_ || !NearEqual(curr->angle_, angle_) || curr->priorityMask_ != priorityMask_) {
|
||||
Reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
direction_.type = curr->direction_.type;
|
||||
newDirection_.type = curr->newDirection_.type;
|
||||
speed_ = curr->speed_;
|
||||
newSpeed_ = curr->newSpeed_;
|
||||
|
||||
onAction_ = std::move(curr->onAction_);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void SwipeRecognizer::ChangeFingers(int32_t fingers)
|
||||
{
|
||||
if (fingers_ != fingers) {
|
||||
newFingers_ = fingers;
|
||||
}
|
||||
}
|
||||
|
||||
void SwipeRecognizer::ChangeDirection(const SwipeDirection& direction)
|
||||
{
|
||||
if (direction_.type != direction.type) {
|
||||
direction_.type = direction.type;
|
||||
newDirection_.type = direction.type;
|
||||
}
|
||||
}
|
||||
|
||||
void SwipeRecognizer::ChangeSpeed(double speed)
|
||||
{
|
||||
if (speed_ != speed) {
|
||||
if (state_ == DetectState::READY || state_ == DetectState::DETECTING) {
|
||||
speed_ = speed;
|
||||
}
|
||||
newSpeed_ = speed;
|
||||
}
|
||||
}
|
||||
|
||||
double SwipeRecognizer::ComputeAngle()
|
||||
{
|
||||
double fx = touchPoints_[0].x;
|
||||
double fy = touchPoints_[0].y;
|
||||
double sx = touchPoints_[1].x;
|
||||
double sy = touchPoints_[1].y;
|
||||
return atan2(fy - sy, fx - sx) * ANGLE_SUM_OF_TRIANGLE / M_PI;
|
||||
}
|
||||
|
||||
double SwipeRecognizer::ComputeAngle(AxisEvent event)
|
||||
{
|
||||
return atan2(event.verticalAxis, event.horizontalAxis) * ANGLE_SUM_OF_TRIANGLE / M_PI;
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_SLIDE_RECOGNIZER_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_SLIDE_RECOGNIZER_H
|
||||
|
||||
#include <cmath>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
|
||||
#include "core/components_ng/gestures/recognizers/multi_fingers_recognizer.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
class SwipeRecognizer : public MultiFingersRecognizer {
|
||||
DECLARE_ACE_TYPE(SwipeRecognizer, MultiFingersRecognizer);
|
||||
|
||||
public:
|
||||
SwipeRecognizer(int32_t fingers, const SwipeDirection& direction, double speed)
|
||||
: direction_(direction), speed_(speed)
|
||||
{
|
||||
fingers_ = fingers;
|
||||
newSpeed_ = speed_;
|
||||
newFingers_ = fingers_;
|
||||
newDirection_ = direction_;
|
||||
}
|
||||
|
||||
void OnAccepted() override;
|
||||
void OnRejected() override;
|
||||
~SwipeRecognizer() override {}
|
||||
|
||||
private:
|
||||
enum class GestureAcceptResult {
|
||||
ACCEPT,
|
||||
REJECT,
|
||||
DETECTING,
|
||||
};
|
||||
void HandleTouchDownEvent(const TouchEvent& event) override;
|
||||
void HandleTouchUpEvent(const TouchEvent& event) override;
|
||||
void HandleTouchMoveEvent(const TouchEvent& event) override;
|
||||
void HandleTouchCancelEvent(const TouchEvent& event) override;
|
||||
void HandleTouchDownEvent(const AxisEvent& event) override;
|
||||
void HandleTouchUpEvent(const AxisEvent& event) override;
|
||||
void HandleTouchMoveEvent(const AxisEvent& event) override;
|
||||
void HandleTouchCancelEvent(const AxisEvent& event) override;
|
||||
bool ReconcileFrom(const RefPtr<GestureRecognizer>& recognizer) override;
|
||||
GestureAcceptResult ParseFingersOffset() const;
|
||||
GestureAcceptResult ParseAxisOffset() const;
|
||||
void Reset();
|
||||
void SendCallbackMsg(const std::unique_ptr<GestureEventFunc>& callback);
|
||||
void ChangeFingers(int32_t fingers);
|
||||
void ChangeDirection(const SwipeDirection& direction);
|
||||
void ChangeSpeed(double speed);
|
||||
double ComputeAngle();
|
||||
double ComputeAngle(AxisEvent event);
|
||||
|
||||
const TouchRestrict& GetTouchRestrict() const
|
||||
{
|
||||
return touchRestrict_;
|
||||
}
|
||||
|
||||
SwipeDirection direction_;
|
||||
double speed_ = 0.0;
|
||||
WeakPtr<PipelineBase> context_;
|
||||
std::map<int32_t, TouchEvent> touchPoints_;
|
||||
std::map<int32_t, Offset> fingersDistance_;
|
||||
AxisEvent axisEventStart_;
|
||||
double axisVerticalTotal_ = 0.0;
|
||||
double axisHorizontalTotal_ = 0.0;
|
||||
TimeStamp time_;
|
||||
TimeStamp touchDownTime_;
|
||||
bool slidingEnd_ = false;
|
||||
bool slidingCancel_ = false;
|
||||
Point globalPoint_;
|
||||
OnSwipeFingersFunc onChangeFingers_;
|
||||
OnSwipeDirectionFunc onChangeDirection_;
|
||||
OnSwipeSpeedFunc onChangeSpeed_;
|
||||
int32_t newFingers_ = 1;
|
||||
|
||||
double angle_ = 0.0;
|
||||
double initialAngle_ = 0.0;
|
||||
double currentAngle_ = 0.0;
|
||||
double resultAngle_ = 0.0;
|
||||
double resultSpeed_ = 0.0;
|
||||
|
||||
double newSpeed_ = 0.0;
|
||||
SwipeDirection newDirection_;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_RECOGNIZERS_SLIDE_RECOGNIZER_H
|
46
frameworks/core/components_ng/gestures/rotation_gesture.cpp
Normal file
46
frameworks/core/components_ng/gestures/rotation_gesture.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "core/components_ng/gestures/rotation_gesture.h"
|
||||
|
||||
#include "core/components_ng/gestures/recognizers/rotation_recognizer.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
RefPtr<GestureRecognizer> RotationGesture::CreateRecognizer()
|
||||
{
|
||||
auto rotationRecognizer = AceType::MakeRefPtr<RotationRecognizer>(fingers_, angle_);
|
||||
if (onActionStartId_) {
|
||||
rotationRecognizer->SetOnActionStart(*onActionStartId_);
|
||||
}
|
||||
|
||||
if (onActionUpdateId_) {
|
||||
rotationRecognizer->SetOnActionUpdate(*onActionUpdateId_);
|
||||
}
|
||||
|
||||
if (onActionEndId_) {
|
||||
rotationRecognizer->SetOnActionEnd(*onActionEndId_);
|
||||
}
|
||||
|
||||
if (onActionCancelId_) {
|
||||
rotationRecognizer->SetOnActionCancel(*onActionCancelId_);
|
||||
}
|
||||
|
||||
rotationRecognizer->SetPriority(priority_);
|
||||
rotationRecognizer->SetPriorityMask(gestureMask_);
|
||||
return rotationRecognizer;
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
47
frameworks/core/components_ng/gestures/rotation_gesture.h
Normal file
47
frameworks/core/components_ng/gestures/rotation_gesture.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_ROTATION_GESTURE_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_ROTATION_GESTURE_H
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/geometry/offset.h"
|
||||
#include "base/memory/ace_type.h"
|
||||
#include "base/utils/macros.h"
|
||||
#include "core/components_ng/gestures/gesture_info.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
class ACE_EXPORT RotationGesture : public Gesture {
|
||||
DECLARE_ACE_TYPE(RotationGesture, Gesture);
|
||||
|
||||
public:
|
||||
RotationGesture() = default;
|
||||
RotationGesture(int32_t fingers, double angle) : Gesture(fingers), angle_(angle) {}
|
||||
~RotationGesture() override = default;
|
||||
|
||||
protected:
|
||||
RefPtr<GestureRecognizer> CreateRecognizer() override;
|
||||
|
||||
private:
|
||||
double angle_ = 1.0;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_ROTATION_GESTURE_H
|
42
frameworks/core/components_ng/gestures/swipe_gesture.cpp
Normal file
42
frameworks/core/components_ng/gestures/swipe_gesture.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "core/components_ng/gestures/swipe_gesture.h"
|
||||
|
||||
#include "base/geometry/dimension.h"
|
||||
#include "core/components_ng/gestures/recognizers/swipe_recognizer.h"
|
||||
#include "core/pipeline_ng/pipeline_context.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
RefPtr<GestureRecognizer> SwipeGesture::CreateRecognizer()
|
||||
{
|
||||
auto context = PipelineContext::GetCurrentContext();
|
||||
CHECK_NULL_RETURN(context, nullptr);
|
||||
|
||||
double speed = context->NormalizeToPx(Dimension(speed_, DimensionUnit::VP));
|
||||
RefPtr<SwipeRecognizer> swipeRecognizer;
|
||||
LOGD("AceType::MakeRefPtr<SwipeRecognizer>(fingers_, direction_, speed)");
|
||||
swipeRecognizer = AceType::MakeRefPtr<SwipeRecognizer>(fingers_, direction_, speed);
|
||||
if (onActionId_) {
|
||||
swipeRecognizer->SetOnAction(*onActionId_);
|
||||
}
|
||||
|
||||
swipeRecognizer->SetPriority(priority_);
|
||||
swipeRecognizer->SetPriorityMask(gestureMask_);
|
||||
return swipeRecognizer;
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
49
frameworks/core/components_ng/gestures/swipe_gesture.h
Normal file
49
frameworks/core/components_ng/gestures/swipe_gesture.h
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_SLIDE_GESTURE_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_SLIDE_GESTURE_H
|
||||
|
||||
#include "base/geometry/offset.h"
|
||||
#include "base/memory/ace_type.h"
|
||||
#include "base/utils/macros.h"
|
||||
#include "core/components_ng/gestures/gesture_info.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
class ACE_EXPORT SwipeGesture : public Gesture {
|
||||
DECLARE_ACE_TYPE(SwipeGesture, Gesture);
|
||||
|
||||
public:
|
||||
SwipeGesture(int32_t fingers, const SwipeDirection& direction, double speed)
|
||||
{
|
||||
fingers_ = fingers;
|
||||
direction_ = direction;
|
||||
speed_ = speed;
|
||||
};
|
||||
|
||||
~SwipeGesture() override = default;
|
||||
|
||||
protected:
|
||||
RefPtr<GestureRecognizer> CreateRecognizer() override;
|
||||
|
||||
private:
|
||||
SwipeDirection direction_;
|
||||
double speed_ = 0.0;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_SLIDE_GESTURE_H
|
34
frameworks/core/components_ng/gestures/tap_gesture.cpp
Normal file
34
frameworks/core/components_ng/gestures/tap_gesture.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "core/components_ng/gestures/tap_gesture.h"
|
||||
|
||||
#include "core/components_ng/gestures/recognizers/click_recognizer.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
RefPtr<GestureRecognizer> TapGesture::CreateRecognizer()
|
||||
{
|
||||
auto clickRecognizer = AceType::MakeRefPtr<ClickRecognizer>(fingers_, count_);
|
||||
if (onActionId_) {
|
||||
clickRecognizer->SetOnAction(*onActionId_);
|
||||
}
|
||||
|
||||
clickRecognizer->SetPriority(priority_);
|
||||
clickRecognizer->SetPriorityMask(gestureMask_);
|
||||
return clickRecognizer;
|
||||
}
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
47
frameworks/core/components_ng/gestures/tap_gesture.h
Normal file
47
frameworks/core/components_ng/gestures/tap_gesture.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_TAP_GESTURE_H
|
||||
#define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_TAP_GESTURE_H
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "base/geometry/offset.h"
|
||||
#include "base/memory/ace_type.h"
|
||||
#include "base/utils/macros.h"
|
||||
#include "core/components_ng/gestures/gesture_info.h"
|
||||
|
||||
namespace OHOS::Ace::NG {
|
||||
|
||||
class ACE_EXPORT TapGesture : public Gesture {
|
||||
DECLARE_ACE_TYPE(TapGesture, Gesture);
|
||||
|
||||
public:
|
||||
TapGesture() = default;
|
||||
TapGesture(int32_t count, int32_t fingers) : Gesture(fingers), count_(count) {}
|
||||
~TapGesture() override = default;
|
||||
|
||||
protected:
|
||||
RefPtr<GestureRecognizer> CreateRecognizer() override;
|
||||
|
||||
private:
|
||||
int32_t count_ = 1;
|
||||
};
|
||||
|
||||
} // namespace OHOS::Ace::NG
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_GESTURES_TAP_GESTURE_H
|
@ -20,20 +20,11 @@
|
||||
|
||||
#include "base/thread/cancelable_callback.h"
|
||||
#include "core/gestures/multi_fingers_recognizer.h"
|
||||
#include "core/gestures/gesture_info.h"
|
||||
#include "core/pipeline/pipeline_base.h"
|
||||
|
||||
namespace OHOS::Ace {
|
||||
|
||||
class ClickInfo : public BaseEventInfo, public TouchLocationInfo {
|
||||
DECLARE_RELATIONSHIP_OF_CLASSES(ClickInfo, BaseEventInfo, TouchLocationInfo);
|
||||
|
||||
public:
|
||||
explicit ClickInfo(int32_t fingerId) : BaseEventInfo("onClick"), TouchLocationInfo(fingerId) {}
|
||||
~ClickInfo() override = default;
|
||||
};
|
||||
|
||||
using ClickCallback = std::function<void(const ClickInfo&)>;
|
||||
|
||||
class ClickRecognizer : public MultiFingersRecognizer {
|
||||
DECLARE_ACE_TYPE(ClickRecognizer, MultiFingersRecognizer);
|
||||
|
||||
|
@ -600,6 +600,16 @@ protected:
|
||||
std::unique_ptr<GestureEventFunc> onActionEndId_;
|
||||
std::unique_ptr<GestureEventNoParameter> onActionCancelId_;
|
||||
};
|
||||
|
||||
class ClickInfo : public BaseEventInfo, public TouchLocationInfo {
|
||||
DECLARE_RELATIONSHIP_OF_CLASSES(ClickInfo, BaseEventInfo, TouchLocationInfo);
|
||||
|
||||
public:
|
||||
explicit ClickInfo(int32_t fingerId) : BaseEventInfo("onClick"), TouchLocationInfo(fingerId) {}
|
||||
~ClickInfo() override = default;
|
||||
};
|
||||
using ClickCallback = std::function<void(const ClickInfo&)>;
|
||||
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
#endif // FOUNDATION_ACE_FRAMEWORKS_CORE_GESTURES_GESTURE_INFO_H
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <stack>
|
||||
|
||||
#include "base/memory/ace_type.h"
|
||||
#include "core/components_ng/gestures/gesture_group.h"
|
||||
#include "core/gestures/gesture_group.h"
|
||||
#include "core/gestures/single_child_gesture.h"
|
||||
|
||||
@ -95,10 +96,51 @@ public:
|
||||
return gesture;
|
||||
}
|
||||
|
||||
void PushGestureNG(const RefPtr<NG::Gesture>& gesture)
|
||||
{
|
||||
gestureStackNG_.push(gesture);
|
||||
}
|
||||
|
||||
void PopGestureNG()
|
||||
{
|
||||
if (gestureStackNG_.size() <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto gesture = gestureStackNG_.top();
|
||||
gestureStackNG_.pop();
|
||||
|
||||
auto gestureGroup = AceType::DynamicCast<NG::GestureGroup>(gestureStackNG_.top());
|
||||
if (gestureGroup) {
|
||||
gestureGroup->AddGesture(gesture);
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<NG::Gesture> TopGestureNG()
|
||||
{
|
||||
if (gestureStackNG_.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
return gestureStackNG_.top();
|
||||
}
|
||||
|
||||
RefPtr<NG::Gesture> FinishGestureNG()
|
||||
{
|
||||
if (gestureStackNG_.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto gesture = gestureStackNG_.top();
|
||||
gestureStackNG_.pop();
|
||||
|
||||
return gesture;
|
||||
}
|
||||
|
||||
private:
|
||||
GesturePriority priority_ = GesturePriority::Low;
|
||||
GestureMask gestureMask_ = GestureMask::Normal;
|
||||
std::stack<RefPtr<Gesture>> gestureStack_;
|
||||
std::stack<RefPtr<NG::Gesture>> gestureStackNG_;
|
||||
};
|
||||
} // namespace OHOS::Ace
|
||||
|
||||
|
@ -116,6 +116,7 @@ ohos_unittest("PipelineContextTest") {
|
||||
"//foundation/arkui/ace_engine/frameworks/core/components/theme/theme_constants.cpp",
|
||||
"//foundation/arkui/ace_engine/frameworks/core/components/theme/theme_manager.cpp",
|
||||
"//foundation/arkui/ace_engine/frameworks/core/components/theme/theme_utils.cpp",
|
||||
"//foundation/arkui/ace_engine/frameworks/core/components_ng/gestures/gesture_referee.cpp",
|
||||
"//foundation/arkui/ace_engine/frameworks/core/event/back_end_event_manager.cpp",
|
||||
"//foundation/arkui/ace_engine/frameworks/core/event/multimodal/multimodal_manager.cpp",
|
||||
"//foundation/arkui/ace_engine/frameworks/core/event/multimodal/multimodal_scene.cpp",
|
||||
|
@ -372,7 +372,6 @@ void PipelineContext::OnTouchEvent(const TouchEvent& point, bool isSubPipe)
|
||||
eventManager_->DispatchTouchEvent(lastMoveEvent.value());
|
||||
}
|
||||
}
|
||||
|
||||
eventManager_->DispatchTouchEvent(scalePoint);
|
||||
hasIdleTasks_ = true;
|
||||
window_->RequestFrame();
|
||||
@ -440,7 +439,6 @@ void PipelineContext::FlushTouchEvents()
|
||||
touchPoints.emplace_front(scalePoint);
|
||||
}
|
||||
}
|
||||
|
||||
auto maxSize = touchPoints.size();
|
||||
for (auto iter = touchPoints.rbegin(); iter != touchPoints.rend(); ++iter) {
|
||||
maxSize--;
|
||||
|
Loading…
Reference in New Issue
Block a user