CCControl Button in CCScrollView should not respond to touch when is outside the view rect


#1

I have a CCScrollView in the scene and then I added some CCControlButton as the scroller’s child,when I click the button in the scroller’s view rect,it respond to the event, that’s good

but when I scroll the button outside of the view rect,I click the position(because the scroller’s view rect is cliped so you can’t see the button ,but it was still at the position ),I found the button also can recieve the event……. is this a bug?


#2

the key to resolve this is :

In the scroll view ,
A. the scroll layer should handle the touch event , when it recieve the touch event, it should detect the does the visible rect contains the touch point
B. if it contains , it shoud send the event to it’s child,
C. and if doesn’t contains ,it should make the event continue bubble……but except it’s children

So I look the source code ,I found

  1. CCScrollView have a touch priority 0 by default
  2. CCControls have a touch priority 1 by default
    that means the scrollview always handle the touch event first

bool CCScrollView::ccTouchBegan(CCTouch* touch, CCEvent* event)
{
if (!this~~>isVisible)
{
return false;
}
CCRect frame = getViewRect;
//dispatcher does not know about clipping. reject touches outside visible bounds.
if > 2 ||
m_bTouchMoved ||
!frame.containsPoint)))
{

return false;
}
if )
{
m_pTouches~~>addObject(touch);
}

if (m_pTouches~~>count 1)
{ // scrolling
m_tTouchPoint = this->convertTouchToNodeSpace(touch);
m_bTouchMoved = false;
m_bDragging = true; //dragging started
m_tScrollDistance = ccp(0.0f, 0.0f);
m_fTouchLength = 0.0f;
}
else if (m_pTouches->count() 2)
{
m_tTouchPoint = ccpMidpointm_pTouches~~>objectAtIndex(0)),
this~~>convertTouchToNodeSpacem_pTouches~~>objectAtIndex(1)));
m_fTouchLength = ccpDistance(m_pContainer~~>convertTouchToNodeSpacem_pTouches~~>objectAtIndex(0)),
m_pContainer~~>convertTouchToNodeSpacem_pTouches~~>objectAtIndex(1)));
m_bDragging = false;
}
return true;
}

and when touch is in the visible area it’s returns true to claimed the touch to perform scroll behaviour , otherwise it’s returns false.
but it’s doesn’t matter, case it register a targetDelegate with swallowTouches false,the touch event is bubble always
So if you touch a button in the scroller’s visible area, the scroll and the button both handle the touch event ,scroll first and the button second, there is no problem

but when you click the button in the scroll but in the invisible area, in the scroll’s touchBegin,the scroll will check if the touch point in the visible bounds,
if not, it will return false and doesn’t claim the touch began event and also will not perform scroll

CCRect frame = getViewRect();

//dispatcher does not know about clipping. reject touches outside visible bounds.
if (m_pTouches->count() > 2 ||
m_bTouchMoved ||
!frame.containsPoint(m_pContainer->convertToWorldSpace(m_pContainer->convertTouchToNodeSpace(touch))))
{

return false;
}

but at this time , the touch began will bubble to the button, it will respond to the touch began event……. and also respond to the tap ……… it’s wrong

And I think there are two ways to resolve this problem

  1. when the child receive touch event , there are some method to tell the visible rect of it’s self, and it will check if the touch point in the rect,yes it’s respond, no ignored

But I don’t know there is a method to do this……

  1. scroll handle the touch event , and when the touch is not in it’s visible area,it will not bubble the event to it’s children,only children.

But in the CCTouchDispatcher the m_pTargetedHandlers don’t have a inheritance structure

So, I don’t have an idea to resolve this


#3

Your post helped me resolve my issue. Thanks.

Posted here:
http://www.cocos2d-x.org/boards/6/topics/32023