语言

Menu
Sites
Language
Difference between pinch, panning and rotate

Hello,

I'm working on an app with an integrated map. I tried to implement gesturelistener for pinch panning an rotate. 
So far they are working. But why do all three listener get triggerd if i start a gesture?

E.g. I have implemented the panningesture with 2 touchpoints and if I do a panning pinch and rotate also fired.

Do I have to do something special to diff between the gestures? 

 

My implementation looks like (just some snippets ;)):

 

 



void MapviewerForm::OnPinchGestureStarted(Tizen::Ui::TouchPinchGestureDetector& gestureDetector)
{
		AppLogDebug("Pinch started.");
		ConsumeInputEvent();
}

void MapviewerForm::OnPinchGestureChanged(Tizen::Ui::TouchPinchGestureDetector& gestureDetector)
{
		Pinch(gestureDetector.GetScale());
		ConsumeInputEvent();
}

void MapviewerForm::OnPanningGestureStarted(Tizen::Ui::TouchPanningGestureDetector& gestureDetector)
{
		Point point(0, 0);
		bool twoTouchPoints = false;
		Tizen::Base::Collection::IListT<TouchEventInfo*>* pList = Tizen::Ui::TouchEventManager::GetInstance()->GetTouchInfoListN();
		if (pList != null)
		{
			int fingerCount = 2;
			TouchEventInfo *pTouchInfo = null;

			if (pList->GetCount() == fingerCount)
			{
				/*
				 * Just tracking second finger y-value
				 */
				pList->GetAt(1, pTouchInfo);
				_panningStartDistance = pTouchInfo->GetCurrentPositionF().y;
				twoTouchPoints = true;
			}

			pList->RemoveAll();
			delete pList;
		}
		if (twoTouchPoints)
		{
			_panningActive = true;
		}
		AppLogDebug("Panning started");
		ConsumeInputEvent();
	}
}


void MapviewerForm::OnRotationGestureStarted(Tizen::Ui::TouchRotationGestureDetector& gestureDetector)
{
		AppLogDebug("Rotating started");
		_lastRotatingAngle = gestureDetector.GetAngle();
		_rotatingActive = true;
		ConsumeInputEvent();
	}
}

响应

6 回复
Alex Dem

Hi,
You could look at UIGestureDetector examples, but there are all gestures are processed on different forms.
It is not problem to create pinch and panning (for example) on the same form:
 Tizen::Ui::TouchPinchGestureDetector* __pPinchGesture;
 Tizen::Ui::TouchPanningGestureDetector* __pPanningGesture;
and to add :
__pTouchArea->AddGestureDetector(__pPanningGesture);
__pTouchArea->AddGestureDetector(__pPinchGesture);
1)  It is enough 1 touch for panning and  OnPanningGestureStarted/OnPanningGestureChanged will come.
2) but after 2 points are touched OnPinchGestureStarted occurs at first and OnPanningGestureChanged/OnPinchGestureChanged both methods will be invoked.

If you need to process all 3 gestures on the same form:
1) Maybe you could disable panning inside OnPinchGestureStarted/OnRotationGestureStarted and implement panning for one touch only.
2) Also you could allow rotate if your angle has been changed (see UIGestureDetector ->Rotation) and disable pinch event in this case (until rotation   is processed) otherwise you could perform zoom in/out like for pinch.
But maybe I don't understand all details.
Alexey.

Stephan König

I need all three gestures on the map-form.

  • pinch for zoom in/out,
  • panning with two touchpoints/fingers for change perspective (something like 3D-view). With just one touchpiont it would be the same as moving the map (touchmove),
  • rotating to change the orentation of the map

The Problem now is that all 3 changelistener are called (OnPanningGestureChanged/OnPinchGestureChanged/OnRotationGestureChanged), but this causes some Problems and I dont understand why there are seperated listeners if they can't seperate the gestures? I tought they would help to not need to implement an own seperation of gestures.

Also disable panning inside of pinch makes no sense. This prevent panning all the time, cause pinch is fisrt called every time.

Can it be that these gesture detectors not working as expected ?

 

 

Stephan

Stephan König

Ok,

I think I got it :)
I've changed the order of the listeners and now I can handle them as expected. The panning now blocks the rotating. For this I have to register/add the rotating listener before the panning...
I also use a treshold-value for each gesture to just not react  immediately on changes.

This works well in the emulator, but on dev-device the gesture-handlers seems to be trigered a lot more. This causes some strange behavior. 
Panning and pinch works on device ok, but rotating seems to trigger about then times more than in emulator. 
Is this a bug or is the device just more sensitive on touch?

 

 

Stephan

Alex Dem

Hi,
I did not find good api to determine which gesture are now. I think treshold-value for each gesture is the only right way.

I could propose to use this approach (how to use all 3 listeners in your form):
Please add some member in your Form class which could be in 1 of  the 4 states (Nothing, Panning, Pinch, Rotation) currently.

Without gesture it should be in ‘Nothing’ state.

You should save first parameters of every gesture :

1. OnPinchGestureStarted  you should save first scale value (use GetScale() or GetScaleF() )
2. OnRotationGestureStarted you could do nothing, GetAngle() returns zero angle always during start.
3. For panning it is most difficult algoritm your should detect inside OnPanningGestureChanged when two fingers were pressed first time
and save coordinates GetTouchInfoListN() and distanse between fingers

After this you should analyze difference between saved and current params inside:
1) OnPinchGestureChanged - changed scale: GetScale() ,GetScaleF()
2) OnRotationGestureChanged - changed angle: GetAngle()
3) OnPanningGestureChanged - changed coordinates for both fingers (distance should be the same): GetTouchInfoListN()

When the difference for any gesture exceeds the some threshold value you should change state from 'Nothing' to 'Panning' or 'Pinch' or 'Rotation' and perform action until gesture will be finished .Another actions should be locked.
And you should return back state to 'Nothing' in:
OnPinchGestureFinished/OnRotationGestureFinished or if count of fingers is changed in OnPanningGestureChanged.

I hope it could help.
Alexey.

Stephan König

Thx for you detailed awnser Alexey :)

At the moment I do most of that, only that I alow pinch and rotate at the same time. Problem now is that OnRotationGestureChanged is called more often on dev-device than on emualtor. In emulator all gesture work as expected, but on dev-device OnRotationGestureChanged is called so often that my map just jumps in angle on rotating gesture.

 

Alex Dem

Maybe in your case you could add some conditions and rotate your map if angle change is significant.
Alexey.