void UIListView::collectOverTopChild() { float scroll_top = _topBoundary; ccArray* arrayChildren = _children->data; int times = arrayChildren->num; for (int i = 0; i < times; ++i) { UIWidget* child = dynamic_cast<UIWidget*>(arrayChildren->arr[i]); float child_bottom = child->getBottomInParent(); if (child_bottom >= scroll_top) { _overTopArray->addObject(child); } } }
void UIListView::setLoopPosition() { switch (_direction) { case LISTVIEW_DIR_VERTICAL: // vertical switch (_moveDirection) { case LISTVIEW_MOVE_DIR_UP: // up { ccArray* arrayChildren = _children->data; unsigned int childrenCount = arrayChildren->num; if (_overTopArray->count() == childrenCount) { unsigned int count = childrenCount; for (unsigned int i = 0; i < count; ++i) { UIWidget* child = dynamic_cast<UIWidget*>(_overTopArray->getObjectAtIndex(i)); if (i == 0) { float height = child->getSize().height; float offset = (child->getWidgetType() == WidgetTypeWidget) ? height / 2 : height; float y = _topBoundary - _disBoundaryToChild_0 - offset; child->setPosition(Point(child->getPosition().x, y)); } else { UIWidget* prev_child = dynamic_cast<UIWidget*>(_overTopArray->getObjectAtIndex(i - 1)); child->setPosition(Point(child->getPosition().x, prev_child->getPosition().y - _disBetweenChild)); } } } else { float scroll_top = _topBoundary; ccArray* arrayChildren = _children->data; int count = arrayChildren->num; for (int i = 0; i < count; ++i) { UIWidget* child = dynamic_cast<UIWidget*>(arrayChildren->arr[i]); float child_bottom = child->getBottomInParent(); if (child_bottom >= scroll_top) { int index = (i == 0) ? (count - 1) : (i - 1); UIWidget* prev_child = dynamic_cast<UIWidget*>(arrayChildren->arr[index]); child->setPosition(Point(child->getPosition().x, prev_child->getPosition().y - _disBetweenChild)); } } } } break; case LISTVIEW_MOVE_DIR_DOWN: // down { ccArray* arrayChildren = _children->data; unsigned int childrenCount = arrayChildren->num; if (_overBottomArray->count() == childrenCount) { unsigned int count = childrenCount; for (unsigned int i = 0; i < count; ++i) { UIWidget* child = dynamic_cast<UIWidget*>(_overBottomArray->getObjectAtIndex(i)); if (i == 0) { float y = _bottomBoundary + _disBoundaryToChild_0 - _disBetweenChild; child->setPosition(Point(child->getPosition().x, y)); } else { UIWidget* prev_child = dynamic_cast<UIWidget*>(_overBottomArray->getObjectAtIndex(i - 1)); child->setPosition(Point(child->getPosition().x, prev_child->getPosition().y + _disBetweenChild)); } } } else { float scroll_bottom = _bottomBoundary; ccArray* arrayChildren = _children->data; int count = arrayChildren->num; for (int i = count - 1; i >= 0; --i) { UIWidget* child = dynamic_cast<UIWidget*>(arrayChildren->arr[i]); float child_top = child->getTopInParent(); if (child_top <= scroll_bottom) { int index = (i == count - 1) ? 0 : (i + 1); UIWidget* next_child = dynamic_cast<UIWidget*>(arrayChildren->arr[index]); child->setPosition(Point(child->getPosition().x, next_child->getPosition().y + _disBetweenChild)); } } } } break; default: break; } break; case LISTVIEW_DIR_HORIZONTAL: // horizontal switch (_moveDirection) { case LISTVIEW_MOVE_DIR_LEFT: // left { ccArray* arrayChildren = _children->data; unsigned int childrenCount = arrayChildren->num; if (_overLeftArray->count() == childrenCount) { unsigned int count = childrenCount; for (unsigned int i = 0; i < count; ++i) { UIWidget* child = dynamic_cast<UIWidget*>(_overLeftArray->getObjectAtIndex(i)); if (i == 0) { float width = child->getSize().width; float offset = (child->getWidgetType() == WidgetTypeWidget) ? (width / 2) : 0; float x = _leftBoundary + _disBoundaryToChild_0 + width + offset; child->setPosition(Point(x, child->getPosition().y)); } else { UIWidget* prev_child = dynamic_cast<UIWidget*>(_overLeftArray->getObjectAtIndex(i - 1)); child->setPosition(Point(prev_child->getPosition().x + _disBetweenChild, child->getPosition().y)); } } } else { float scroll_left = _leftBoundary; ccArray* arrayChildren = _children->data; int count = arrayChildren->num; for (int i = 0; i < count; ++i) { UIWidget* child = dynamic_cast<UIWidget*>(arrayChildren->arr[i]); float child_right = child->getRightInParent(); if (child_right <= scroll_left) { int index = (i == 0) ? (count - 1) : (i - 1); UIWidget* prev_child = dynamic_cast<UIWidget*>(arrayChildren->arr[index]); child->setPosition(Point(prev_child->getPosition().x + _disBetweenChild, child->getPosition().y)); } } } } break; case LISTVIEW_MOVE_DIR_RIGHT: // right { ccArray* arrayChildren = _children->data; unsigned int childrenCount = arrayChildren->num; if (_overRightArray->count() == childrenCount) { unsigned int count = childrenCount; for (unsigned int i = 0; i < count; ++i) { UIWidget* child = dynamic_cast<UIWidget*>(_overRightArray->getObjectAtIndex(i)); if (i == 0) { float x = _rightBoundary - _disBoundaryToChild_0 + _disBetweenChild; child->setPosition(Point(x, child->getPosition().y)); } else { UIWidget* prev_child = dynamic_cast<UIWidget*>(_overRightArray->getObjectAtIndex(i - 1)); child->setPosition(Point(prev_child->getPosition().x - _disBetweenChild, child->getPosition().y)); } } } else { float scroll_right = _rightBoundary; ccArray* arrayChildren = _children->data; int count = arrayChildren->num; for (int i = count - 1; i >= 0; --i) { UIWidget* child = dynamic_cast<UIWidget*>(arrayChildren->arr[i]); float child_left = child->getLeftInParent(); if (child_left >= scroll_right) { int index = (i == count - 1) ? 0 : (i + 1); UIWidget* next_child = dynamic_cast<UIWidget*>(arrayChildren->arr[index]); child->setPosition(Point(next_child->getPosition().x - _disBetweenChild, child->getPosition().y)); } } } } break; default: break; } break; default: break; } }
void UILayout::doLayout() { switch (m_eLayoutType) { case LAYOUT_ABSOLUTE: break; case LAYOUT_LINEAR_VERTICAL: { ccArray* layoutChildrenArray = getChildren()->data; int length = layoutChildrenArray->num; CCSize layoutSize = getSize(); float topBoundary = layoutSize.height; for (int i=0; i<length; ++i) { UIWidget* child = dynamic_cast<UIWidget*>(layoutChildrenArray->arr[i]); UILinearLayoutParameter* layoutParameter = dynamic_cast<UILinearLayoutParameter*>(child->getLayoutParameter(LAYOUT_PARAMETER_LINEAR)); if (layoutParameter) { UILinearGravity childGravity = layoutParameter->getGravity(); CCPoint ap = child->getAnchorPoint(); CCSize cs = child->getSize(); float finalPosX = ap.x * cs.width; float finalPosY = topBoundary - ((1.0f-ap.y) * cs.height); switch (childGravity) { case LINEAR_GRAVITY_NONE: case LINEAR_GRAVITY_LEFT: break; case LINEAR_GRAVITY_RIGHT: finalPosX = layoutSize.width - ((1.0f - ap.x) * cs.width); break; case LINEAR_GRAVITY_CENTER_HORIZONTAL: finalPosX = layoutSize.width / 2.0f - cs.width * (0.5f-ap.x); break; default: break; } UIMargin mg = layoutParameter->getMargin(); finalPosX += mg.left; finalPosY -= mg.top; child->setPosition(ccp(finalPosX, finalPosY)); topBoundary = child->getBottomInParent() - mg.bottom; } } break; } case LAYOUT_LINEAR_HORIZONTAL: { ccArray* layoutChildrenArray = getChildren()->data; int length = layoutChildrenArray->num; CCSize layoutSize = getSize(); float leftBoundary = 0.0f; for (int i=0; i<length; ++i) { UIWidget* child = dynamic_cast<UIWidget*>(layoutChildrenArray->arr[i]); UILinearLayoutParameter* layoutParameter = dynamic_cast<UILinearLayoutParameter*>(child->getLayoutParameter(LAYOUT_PARAMETER_LINEAR)); if (layoutParameter) { UILinearGravity childGravity = layoutParameter->getGravity(); CCPoint ap = child->getAnchorPoint(); CCSize cs = child->getSize(); float finalPosX = leftBoundary + (ap.x * cs.width); float finalPosY = layoutSize.height - (1.0f - ap.y) * cs.height; switch (childGravity) { case LINEAR_GRAVITY_NONE: case LINEAR_GRAVITY_TOP: break; case LINEAR_GRAVITY_BOTTOM: finalPosY = ap.y * cs.height; break; case LINEAR_GRAVITY_CENTER_VERTICAL: finalPosY = layoutSize.height / 2.0f - cs.height * (0.5f - ap.y); break; default: break; } UIMargin mg = layoutParameter->getMargin(); finalPosX += mg.left; finalPosY -= mg.top; child->setPosition(ccp(finalPosX, finalPosY)); leftBoundary = child->getRightInParent() + mg.right; } } break; } case LAYOUT_RELATIVE: { ccArray* layoutChildrenArray = getChildren()->data; int length = layoutChildrenArray->num; int unlayoutChildCount = length; CCSize layoutSize = getSize(); for (int i=0; i<length; i++) { UIWidget* child = dynamic_cast<UIWidget*>(layoutChildrenArray->arr[i]); UIRelativeLayoutParameter* layoutParameter = dynamic_cast<UIRelativeLayoutParameter*>(child->getLayoutParameter(LAYOUT_PARAMETER_RELATIVE)); layoutParameter->m_bPut = false; } while (unlayoutChildCount > 0) { for (int i=0; i<length; i++) { UIWidget* child = dynamic_cast<UIWidget*>(layoutChildrenArray->arr[i]); UIRelativeLayoutParameter* layoutParameter = dynamic_cast<UIRelativeLayoutParameter*>(child->getLayoutParameter(LAYOUT_PARAMETER_RELATIVE)); if (layoutParameter) { if (layoutParameter->m_bPut) { continue; } CCPoint ap = child->getAnchorPoint(); CCSize cs = child->getSize(); UIRelativeAlign align = layoutParameter->getAlign(); const char* relativeName = layoutParameter->getRelativeToWidgetName(); UIWidget* relativeWidget = NULL; UIRelativeLayoutParameter* relativeWidgetLP = NULL; float finalPosX = 0.0f; float finalPosY = 0.0f; if (relativeName && strcmp(relativeName, "")) { relativeWidget = CCUIHELPER->seekWidgetByRelativeName(this, relativeName); if (relativeWidget) { relativeWidgetLP = dynamic_cast<UIRelativeLayoutParameter*>(relativeWidget->getLayoutParameter(LAYOUT_PARAMETER_RELATIVE)); } } switch (align) { case RELATIVE_ALIGN_NONE: case RELATIVE_ALIGN_PARENT_TOP_LEFT: finalPosX = ap.x * cs.width; finalPosY = layoutSize.height - ((1.0f - ap.y) * cs.height); break; case RELATIVE_ALIGN_PARENT_TOP_CENTER_HORIZONTAL: finalPosX = layoutSize.width * 0.5f - cs.width * (0.5f - ap.x); finalPosY = layoutSize.height - ((1.0f - ap.y) * cs.height); break; case RELATIVE_ALIGN_PARENT_TOP_RIGHT: finalPosX = layoutSize.width - ((1.0f - ap.x) * cs.width); finalPosY = layoutSize.height - ((1.0f - ap.y) * cs.height); break; case RELATIVE_ALIGN_PARENT_LEFT_CENTER_VERTICAL: finalPosX = ap.x * cs.width; finalPosY = layoutSize.height * 0.5f - cs.height * (0.5f - ap.y); break; case RELATIVE_CENTER_IN_PARENT: finalPosX = layoutSize.width * 0.5f - cs.width * (0.5f - ap.x); finalPosY = layoutSize.height * 0.5f - cs.height * (0.5f - ap.y); break; case RELATIVE_ALIGN_PARENT_RIGHT_CENTER_VERTICAL: finalPosX = layoutSize.width - ((1.0f - ap.x) * cs.width); finalPosY = layoutSize.height * 0.5f - cs.height * (0.5f - ap.y); break; case RELATIVE_ALIGN_PARENT_LEFT_BOTTOM: finalPosX = ap.x * cs.width; finalPosY = ap.y * cs.height; break; case RELATIVE_ALIGN_PARENT_BOTTOM_CENTER_HORIZONTAL: finalPosX = layoutSize.width * 0.5f - cs.width * (0.5f - ap.x); finalPosY = ap.y * cs.height; break; case RELATIVE_ALIGN_PARENT_RIGHT_BOTTOM: finalPosX = layoutSize.width - ((1.0f - ap.x) * cs.width); finalPosY = ap.y * cs.height; break; case RELATIVE_LOCATION_ABOVE_LEFTALIGN: if (relativeWidget) { if (relativeWidgetLP && !relativeWidgetLP->m_bPut) { continue; } float locationBottom = relativeWidget->getTopInParent(); float locationLeft = relativeWidget->getLeftInParent(); finalPosY = locationBottom + ap.y * cs.height; finalPosX = locationLeft + ap.x * cs.width; } break; case RELATIVE_LOCATION_ABOVE_CENTER: if (relativeWidget) { if (relativeWidgetLP && !relativeWidgetLP->m_bPut) { continue; } CCSize rbs = relativeWidget->getSize(); float locationBottom = relativeWidget->getTopInParent(); finalPosY = locationBottom + ap.y * cs.height; finalPosX = relativeWidget->getLeftInParent() + rbs.width * 0.5f + ap.x * cs.width - cs.width * 0.5f; } break; case RELATIVE_LOCATION_ABOVE_RIGHTALIGN: if (relativeWidget) { if (relativeWidgetLP && !relativeWidgetLP->m_bPut) { continue; } float locationBottom = relativeWidget->getTopInParent(); float locationRight = relativeWidget->getRightInParent(); finalPosY = locationBottom + ap.y * cs.height; finalPosX = locationRight - (1.0f - ap.x) * cs.width; } break; case RELATIVE_LOCATION_LEFT_OF_TOPALIGN: if (relativeWidget) { if (relativeWidgetLP && !relativeWidgetLP->m_bPut) { continue; } float locationTop = relativeWidget->getTopInParent(); float locationRight = relativeWidget->getLeftInParent(); finalPosY = locationTop - (1.0f - ap.y) * cs.height; finalPosX = locationRight - (1.0f - ap.x) * cs.width; } break; case RELATIVE_LOCATION_LEFT_OF_CENTER: if (relativeWidget) { if (relativeWidgetLP && !relativeWidgetLP->m_bPut) { continue; } CCSize rbs = relativeWidget->getSize(); float locationRight = relativeWidget->getLeftInParent(); finalPosX = locationRight - (1.0f - ap.x) * cs.width; finalPosY = relativeWidget->getBottomInParent() + rbs.height * 0.5f + ap.y * cs.height - cs.height * 0.5f; } break; case RELATIVE_LOCATION_LEFT_OF_BOTTOMALIGN: if (relativeWidget) { if (relativeWidgetLP && !relativeWidgetLP->m_bPut) { continue; } float locationBottom = relativeWidget->getBottomInParent(); float locationRight = relativeWidget->getLeftInParent(); finalPosY = locationBottom + ap.y * cs.height; finalPosX = locationRight - (1.0f - ap.x) * cs.width; } break; case RELATIVE_LOCATION_RIGHT_OF_TOPALIGN: if (relativeWidget) { if (relativeWidgetLP && !relativeWidgetLP->m_bPut) { continue; } float locationTop = relativeWidget->getTopInParent(); float locationLeft = relativeWidget->getRightInParent(); finalPosY = locationTop - (1.0f - ap.y) * cs.height; finalPosX = locationLeft + ap.x * cs.width; } break; case RELATIVE_LOCATION_RIGHT_OF_CENTER: if (relativeWidget) { if (relativeWidgetLP && !relativeWidgetLP->m_bPut) { continue; } CCSize rbs = relativeWidget->getSize(); float locationLeft = relativeWidget->getRightInParent(); finalPosX = locationLeft + ap.x * cs.width; finalPosY = relativeWidget->getBottomInParent() + rbs.height * 0.5f + ap.y * cs.height - cs.height * 0.5f; } break; case RELATIVE_LOCATION_RIGHT_OF_BOTTOMALIGN: if (relativeWidget) { if (relativeWidgetLP && !relativeWidgetLP->m_bPut) { continue; } float locationBottom = relativeWidget->getBottomInParent(); float locationLeft = relativeWidget->getRightInParent(); finalPosY = locationBottom + ap.y * cs.height; finalPosX = locationLeft + ap.x * cs.width; } break; case RELATIVE_LOCATION_BELOW_LEFTALIGN: if (relativeWidget) { if (relativeWidgetLP && !relativeWidgetLP->m_bPut) { continue; } float locationTop = relativeWidget->getBottomInParent(); float locationLeft = relativeWidget->getLeftInParent(); finalPosY = locationTop - (1.0f - ap.y) * cs.height; finalPosX = locationLeft + ap.x * cs.width; } break; case RELATIVE_LOCATION_BELOW_CENTER: if (relativeWidget) { if (relativeWidgetLP && !relativeWidgetLP->m_bPut) { continue; } CCSize rbs = relativeWidget->getSize(); float locationTop = relativeWidget->getBottomInParent(); finalPosY = locationTop - (1.0f - ap.y) * cs.height; finalPosX = relativeWidget->getLeftInParent() + rbs.width * 0.5f + ap.x * cs.width - cs.width * 0.5f; } break; case RELATIVE_LOCATION_BELOW_RIGHTALIGN: if (relativeWidget) { if (relativeWidgetLP && !relativeWidgetLP->m_bPut) { continue; } float locationTop = relativeWidget->getBottomInParent(); float locationRight = relativeWidget->getRightInParent(); finalPosY = locationTop - (1.0f - ap.y) * cs.height; finalPosX = locationRight - (1.0f - ap.x) * cs.width; } break; default: break; } UIMargin relativeWidgetMargin; UIMargin mg = layoutParameter->getMargin(); if (relativeWidget) { relativeWidgetMargin = relativeWidget->getLayoutParameter(LAYOUT_PARAMETER_RELATIVE)->getMargin(); } //handle margin switch (align) { case RELATIVE_ALIGN_NONE: case RELATIVE_ALIGN_PARENT_TOP_LEFT: finalPosX += mg.left; finalPosY -= mg.top; break; case RELATIVE_ALIGN_PARENT_TOP_CENTER_HORIZONTAL: finalPosY -= mg.top; break; case RELATIVE_ALIGN_PARENT_TOP_RIGHT: finalPosX -= mg.right; finalPosY -= mg.top; break; case RELATIVE_ALIGN_PARENT_LEFT_CENTER_VERTICAL: finalPosX += mg.left; break; case RELATIVE_CENTER_IN_PARENT: break; case RELATIVE_ALIGN_PARENT_RIGHT_CENTER_VERTICAL: finalPosX -= mg.right; break; case RELATIVE_ALIGN_PARENT_LEFT_BOTTOM: finalPosX += mg.left; finalPosY += mg.bottom; break; case RELATIVE_ALIGN_PARENT_BOTTOM_CENTER_HORIZONTAL: finalPosY += mg.bottom; break; case RELATIVE_ALIGN_PARENT_RIGHT_BOTTOM: finalPosX -= mg.right; finalPosY += mg.bottom; break; case RELATIVE_LOCATION_ABOVE_LEFTALIGN: case RELATIVE_LOCATION_ABOVE_CENTER: case RELATIVE_LOCATION_ABOVE_RIGHTALIGN: finalPosY += mg.bottom; finalPosY += relativeWidgetMargin.top; break; case RELATIVE_LOCATION_LEFT_OF_TOPALIGN: case RELATIVE_LOCATION_LEFT_OF_CENTER: case RELATIVE_LOCATION_LEFT_OF_BOTTOMALIGN: finalPosX -= mg.right; finalPosX -= relativeWidgetMargin.left; break; case RELATIVE_LOCATION_RIGHT_OF_TOPALIGN: case RELATIVE_LOCATION_RIGHT_OF_CENTER: case RELATIVE_LOCATION_RIGHT_OF_BOTTOMALIGN: finalPosX += mg.left; finalPosX += relativeWidgetMargin.right; break; case RELATIVE_LOCATION_BELOW_LEFTALIGN: case RELATIVE_LOCATION_BELOW_CENTER: case RELATIVE_LOCATION_BELOW_RIGHTALIGN: finalPosY -= mg.top; finalPosY -= relativeWidgetMargin.bottom; break; default: break; } child->setPosition(ccp(finalPosX, finalPosY)); layoutParameter->m_bPut = true; unlayoutChildCount--; } } } break; } default: break; } }