Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development

Reply
New Developer
Posts: 13
Registered: ‎12-28-2012
My Device: BB10 Dev Alpha
My Carrier: Simyo
Accepted Solution

Capture touches inside a ScrollView

I have a control that when I receive a touch, I track the touch() signal when the user is moving up and down, to change the value it has inside. Like in this video https://www.youtube.com/watch?v=aK0Mqxg89xc , but in a vertical direction.

 

If I put the control inside a ScrollView, the control doesn't work anymore, since I receive a Cancel TouchEvent.

I tried to change all the view ancestors  touchPropagationMode to TouchPropagationMode::smileytongue:assThrough on the touch down event, and restore them in the touch up / touch cancel event  (so the ScrollView should stop handling the events for scrolling, when this control has captured the touch event) ,  but it doesn't work , and I still receive the Cancel event. 

 

I've also had a look at this thread http://supportforums.blackberry.com/t5/Cascades-Development/block-scroll-view/td-p/2029435 , that it says that is doing the trick of the events, but I understand not from a control inside the view, but from outside. 

 

Any hint of how to capture the touch events, and prevent the parent ScrollView from scrolling when my control is capturing the touch event !? 

 

 

New Developer
Posts: 13
Registered: ‎12-28-2012
My Device: BB10 Dev Alpha
My Carrier: Simyo

Re: Capture touches inside a ScrollView

Finally found the way to solve this. Sorry for the 'spam' in the forum :/ 

 

The way is the same used in the post that I've referenced in my first post.

 

 

 

I've put a signal handler for my touch event.
QObject::connect( counterLabel, SIGNAL(	touch(bb::cascades::TouchEvent*) ),
			          this, SLOT( onTouchEvent( bb::cascades::TouchEvent* )));
So when I receive a touch down in my counterLabel, I call the hijackTouchEvents :
void TouchCounter::onTouchEvent( bb::cascades::TouchEvent* touchEvent )
{
	TouchType::Type eType = touchEvent->touchType();

	if( eType == TouchType::Down ){
		counterUpdateTimer->start();
		initialY = touchEvent->windowY();
		counterUpdateIncrement = 0;
		timerIntervalAccum = 0;
		hijackTouchEvents();
		touchEvent->accept();
	}
}
and I go up the 'older ancestor' to install a touchCapture handler, and to block all the touch events to its immediate child (saving the mode to restore it later).
void TouchCounter::hijackTouchEvents()
{
	blockedNode = NULL;
	capturingTouchesNode = this;
	VisualNode* next;
	while( (next = qobject_cast(capturingTouchesNode->parent() ) ) != 0){
		blockedNode = capturingTouchesNode;
		capturingTouchesNode = next;
	}
	QObject::connect( capturingTouchesNode, SIGNAL(	touchCapture(bb::cascades::TouchEvent*) ),
	 					  this, SLOT( onTouchCaptureEvent( bb::cascades::TouchEvent* )));
	if( blockedNode != NULL ){
		blockedNodeOriginalPropagationMode = blockedNode->touchPropagationMode();
		blockedNode->setTouchPropagationMode( TouchPropagationMode::None);
	}
}
I also have the function to disconnect from the touchCapture:
 
void TouchCounter::freeTouchEvents()
{
	QObject::disconnect( capturingTouchesNode, SIGNAL(	touchCapture(bb::cascades::TouchEvent*) ),
		 					  this, SLOT( onTouchCaptureEvent( bb::cascades::TouchEvent* )));
	capturingTouchesNode = 0;

	if( blockedNode != NULL){
		blockedNode->setTouchPropagationMode( blockedNodeOriginalPropagationMode );
		blockedNode = NULL;
	}
}
And I would call the freeTouchEvents function in the onTouchCaptureEvent, when I receive a touch up , or touch cancel event.

void TouchCounter::onTouchCaptureEvent( bb::cascades::TouchEvent* touchEvent )
{
	TouchType::Type eType = touchEvent->touchType();
	VisualNode* tgt = touchEvent->target();
	touchEvent->propagationPhase();
	if( eType == TouchType::Move && capturingTouchesNode != 0 ){
		float a = touchEvent->windowY();
		float diff = a - initialY;
		counterUpdateIncrement = getUpdateRateMilliseconds( diff  );
		if( diff > 10.0f ){
			valueDirection = -1;
		}else if( diff < 10.0f ){
			valueDirection = 1;
		}else{
			valueDirection = 0;
		}
		touchEvent->accept();
	}else if( eType== TouchType::Up || eType == TouchType::Cancel ){
		initialY = 0;
		counterUpdateTimer->stop();
		touchEvent->accept();
		freeTouchEvents();
	}
}
Hope this is helps someone! :smileyhappy: