Size GridLayout::layout(Component::Ptr component, const std::list<Component::Ptr>& children, const Size& innerSize) { unsigned int actualRows = rows; unsigned int actualColumns = columns; if (actualRows < 1 && actualColumns < 1) { actualRows = actualColumns = (unsigned int) ceil(sqrt(children.size())); } else if (actualRows < 1) { actualRows = (unsigned int) ceil((float) children.size() / (float) actualColumns); } else if (actualColumns < 1) { actualColumns = (unsigned int) ceil((float) children.size() / (float) actualRows); } Size childSize = innerSize.resize(-(actualColumns - 1) * hPadding, -(actualRows - 1) * vPadding).scale(1.0 / actualColumns, 1.0 / actualRows); unsigned int row = 0; unsigned int column = 0; for (std::list<Component::Ptr>::const_iterator child = children.begin(); child != children.end(); ++child) { Component::Ptr childComp = *child; childComp->setSize(Size::min(childSize, childComp->getMaximumSize())); Point position(column * (childSize.width + hPadding), row * (childSize.height + vPadding)); switch (defaultHAlignment) { default: case Component::ALIGN_LEFT: position = position.move(0, 0); break; case Component::ALIGN_CENTER: position = position.move((childSize.width - childComp->getWidth()) / 2, 0); break; case Component::ALIGN_RIGHT: position = position.move(childSize.width - childComp->getWidth(), 0); break; } switch (defaultVAlignment) { default: case Component::ALIGN_TOP: position = position.move(0, 0); break; case Component::ALIGN_CENTER: position = position.move(0, (childSize.height - childComp->getHeight()) / 2); break; case Component::ALIGN_BOTTOM: position = position.move(0, childSize.height - childComp->getHeight()); break; } childComp->setPosition(position); if (order == LEFT_TO_RIGHT) { column += 1; if (column >= actualColumns) { column = 0; row += 1; } } else { row += 1; if (row >= actualRows) { row = 0; column += 1; } } } Size preferredChildSize = Size::ZERO; for (std::list<Component::Ptr>::const_iterator child = children.begin(); child != children.end(); ++child) { preferredChildSize = Size::max(preferredChildSize, (*child)->getPreferredSize()); } return preferredChildSize.scale(actualColumns, actualRows).resize((actualColumns - 1) * hPadding, (actualRows - 1) * vPadding).grow( component->getInsets()); }
Size BorderLayout::layout(Component::Ptr component, const std::list<Component::Ptr>& children, const Size& innerSize) { Component::Ptr top; Component::Ptr bottom; Component::Ptr left; Component::Ptr right; Component::Ptr center; for (std::list<Component::Ptr>::const_iterator child = children.begin(); child != children.end(); ++child) { Component::Alignment alignment = (*child)->getAlignment(); switch (alignment) { case Component::ALIGN_LEFT: if (left) { throw Exception("BorderLayout supports only one component with ALIGN_LEFT"); } left = (*child); break; case Component::ALIGN_TOP: if (top) { throw Exception("BorderLayout supports only one component with ALIGN_TOP"); } top = (*child); break; case Component::ALIGN_RIGHT: if (right) { throw Exception("BorderLayout supports only one component with ALIGN_RIGHT"); } right = (*child); break; case Component::ALIGN_BOTTOM: if (bottom) { throw Exception("BorderLayout supports only one component with ALIGN_BOTTOM"); } bottom = (*child); break; default: case Component::ALIGN_DEFAULT: case Component::ALIGN_CENTER: if (center) { throw Exception("BorderLayout supports only one component with ALIGN_CENTER/ALIGN_DEFAULT"); } center = (*child); break; } } Insets centerInsets; if (top) { top->setWidth(innerSize.width); top->setHeight(top->getPreferredSize().height); top->setPosition(Point(0, 0)); centerInsets.top += top->getHeight(); } if (bottom) { bottom->setWidth(innerSize.width); bottom->setHeight(bottom->getPreferredSize().height); bottom->setPosition(Point(0, innerSize.height - bottom->getHeight())); centerInsets.bottom += bottom->getHeight(); } if (left) { left->setHeight(innerSize.shrink(centerInsets).height); left->setWidth(left->getPreferredSize().width); left->setPosition(Point(0, centerInsets.top)); centerInsets.left += left->getWidth(); } if (right) { right->setHeight(innerSize.shrink(centerInsets).height); right->setWidth(right->getPreferredSize().width); right->setPosition(Point(innerSize.width - right->getWidth(), centerInsets.top)); centerInsets.right += right->getWidth(); } if (center) { center->setSize(innerSize.shrink(centerInsets)); center->setPosition(centerInsets.getTopLeft()); } Size preferred; if (left) { const Size& size = left->getPreferredSize(); preferred.width += size.width; preferred.height = std::max(preferred.height, size.height); } if (center) { const Size& size = center->getPreferredSize(); preferred.width += size.width; preferred.height = std::max(preferred.height, size.height); } if (right) { const Size& size = right->getPreferredSize(); preferred.width += size.width; preferred.height = std::max(preferred.height, size.height); } if (top) { const Size& size = top->getPreferredSize(); preferred.width = std::max(preferred.width, size.width); preferred.height += size.height; } if (bottom) { const Size& size = bottom->getPreferredSize(); preferred.width = std::max(preferred.width, size.width); preferred.height += size.height; } return preferred.grow(component->getInsets()); }