Merge pull request #2279 from sjchao/master

fixed #2030: Fixing a display bug when a scrollView nested in another scrollView. The parent's scissor rect need to be considered, when setting the scissor rect in the subScrollView.
This commit is contained in:
James Chen 2013-04-07 23:55:55 -07:00
commit d3eed7fd1f
4 changed files with 66 additions and 17 deletions

View File

@ -154,17 +154,33 @@ void CCEGLViewProtocol::setScissorInPoints(float x , float y , float w , float h
(GLsizei)(h * m_fScaleY));
}
void CCEGLViewProtocol::setViewName(const char* pszViewName)
{
if (pszViewName != NULL && strlen(pszViewName) > 0)
{
strncpy(m_szViewName, pszViewName, sizeof(m_szViewName));
}
}
const char* CCEGLViewProtocol::getViewName()
{
return m_szViewName;
bool CCEGLViewProtocol::isScissorEnabled()
{
return glIsEnabled(GL_SCISSOR_TEST);
}
CCRect CCEGLViewProtocol::getScissorRect()
{
GLfloat params[4];
glGetFloatv(GL_SCISSOR_BOX, params);
float x = (params[0] - m_obViewPortRect.origin.x) / m_fScaleX;
float y = (params[1] - m_obViewPortRect.origin.y) / m_fScaleY;
float w = params[2] / m_fScaleX;
float h = params[3] / m_fScaleY;
return CCRectMake(x, y, w, h);
}
void CCEGLViewProtocol::setViewName(const char* pszViewName)
{
if (pszViewName != NULL && strlen(pszViewName) > 0)
{
strncpy(m_szViewName, pszViewName, sizeof(m_szViewName));
}
}
const char* CCEGLViewProtocol::getViewName()
{
return m_szViewName;
}
void CCEGLViewProtocol::handleTouchesBegin(int num, int ids[], float xs[], float ys[])

View File

@ -98,6 +98,16 @@ public:
*/
virtual void setScissorInPoints(float x , float y , float w , float h);
/**
* Get whether GL_SCISSOR_TEST is enable
*/
virtual bool isScissorEnabled();
/**
* Get the current scissor rectangle
*/
virtual CCRect getScissorRect();
virtual void setViewName(const char* pszViewName);
const char* getViewName();

View File

@ -492,11 +492,24 @@ void CCScrollView::beforeDraw()
{
if (m_bClippingToBounds)
{
CCRect frame = getViewRect();
glEnable(GL_SCISSOR_TEST);
CCEGLView::sharedOpenGLView()->setScissorInPoints(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
m_bScissorRestored = false;
CCRect frame = getViewRect();
if (CCEGLView::sharedOpenGLView()->isScissorEnabled()) {
m_bScissorRestored = true;
m_tParentScissorRect = CCEGLView::sharedOpenGLView()->getScissorRect();
//set the intersection of m_tParentScissorRect and frame as the new scissor rect
if (frame.intersectsRect(m_tParentScissorRect)) {
float x = MAX(frame.origin.x, m_tParentScissorRect.origin.x);
float y = MAX(frame.origin.y, m_tParentScissorRect.origin.y);
float xx = MIN(frame.origin.x+frame.size.width, m_tParentScissorRect.origin.x+m_tParentScissorRect.size.width);
float yy = MIN(frame.origin.y+frame.size.height, m_tParentScissorRect.origin.y+m_tParentScissorRect.size.height);
CCEGLView::sharedOpenGLView()->setScissorInPoints(x, y, xx-x, yy-y);
}
}
else {
glEnable(GL_SCISSOR_TEST);
CCEGLView::sharedOpenGLView()->setScissorInPoints(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height);
}
}
}
@ -508,7 +521,12 @@ void CCScrollView::afterDraw()
{
if (m_bClippingToBounds)
{
glDisable(GL_SCISSOR_TEST);
if (m_bScissorRestored) {//restore the parent's scissor rect
CCEGLView::sharedOpenGLView()->setScissorInPoints(m_tParentScissorRect.origin.x, m_tParentScissorRect.origin.y, m_tParentScissorRect.size.width, m_tParentScissorRect.size.height);
}
else {
glDisable(GL_SCISSOR_TEST);
}
}
}

View File

@ -317,6 +317,11 @@ protected:
* max and min scale
*/
float m_fMinScale, m_fMaxScale;
/**
* scissor rect for parent, just for restoring GL_SCISSOR_BOX
*/
CCRect m_tParentScissorRect;
bool m_bScissorRestored;
};
// end of GUI group