diff options
Diffstat (limited to 'toolkit/source/layout/flow.cxx')
-rw-r--r-- | toolkit/source/layout/flow.cxx | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/toolkit/source/layout/flow.cxx b/toolkit/source/layout/flow.cxx new file mode 100644 index 000000000000..c8573c82a4fa --- /dev/null +++ b/toolkit/source/layout/flow.cxx @@ -0,0 +1,176 @@ +#include "flow.hxx" + +#include <sal/macros.h> + +namespace layoutimpl +{ + +using namespace css; + +bool Flow::ChildData::isVisible() +{ + return xChild.is(); +} + +Flow::Flow() + : Container() + , mnSpacing( 0 ) + , mbHomogeneous( false ) +{ + addProp( RTL_CONSTASCII_USTRINGPARAM( "Homogeneous" ), + ::getCppuType( static_cast< const sal_Bool* >( NULL ) ), + &mbHomogeneous ); + addProp( RTL_CONSTASCII_USTRINGPARAM( "Spacing" ), + ::getCppuType( static_cast< const sal_Int32* >( NULL ) ), + &mnSpacing ); +} + +void SAL_CALL +Flow::addChild( const uno::Reference< awt::XLayoutConstrains >& xChild ) + throw (uno::RuntimeException, css::awt::MaxChildrenException) +{ + if ( xChild.is() ) + { + ChildData *pData = new ChildData(); + pData->xChild = xChild; + maChildren.push_back( pData ); + + setChildParent( xChild ); + queueResize(); + } +} + +void SAL_CALL +Flow::removeChild( const css::uno::Reference< css::awt::XLayoutConstrains >& xChild ) + throw (css::uno::RuntimeException) +{ + for( std::list< ChildData * >::iterator it = maChildren.begin(); + it != maChildren.end(); it++ ) + { + if ( (*it)->xChild == xChild ) + { + delete *it; + maChildren.erase( it ); + + unsetChildParent( xChild ); + queueResize(); + break; + } + } +} + +css::uno::Sequence< css::uno::Reference < css::awt::XLayoutConstrains > > SAL_CALL +Flow::getChildren() + throw (css::uno::RuntimeException) +{ + uno::Sequence< uno::Reference< awt::XLayoutConstrains > > children( maChildren.size() ); + unsigned int i = 0; + for( std::list< ChildData * >::iterator it = maChildren.begin(); + it != maChildren.end(); it++, i++ ) + children[i] = (*it)->xChild; + + return children; +} + +uno::Reference< beans::XPropertySet > SAL_CALL +Flow::getChildProperties( const uno::Reference< awt::XLayoutConstrains >& /*xChild*/ ) + throw (uno::RuntimeException) +{ + return uno::Reference< beans::XPropertySet >(); +} + +css::awt::Size +Flow::calculateSize( long nMaxWidth ) +{ + long nNeedHeight = 0; + + std::list<ChildData *>::const_iterator it; + mnEachWidth = 0; + // first pass, for homogeneous property + for (it = maChildren.begin(); it != maChildren.end(); it++) + { + if ( !(*it)->isVisible() ) + continue; + (*it)->aRequisition = (*it)->xChild->getMinimumSize(); + if ( mbHomogeneous ) + mnEachWidth = SAL_MAX( mnEachWidth, (*it)->aRequisition.Width ); + } + + long nRowWidth = 0, nRowHeight = 0; + for (it = maChildren.begin(); it != maChildren.end(); it++) + { + if ( !(*it)->isVisible() ) + continue; + + awt::Size aChildSize = (*it)->aRequisition; + if ( mbHomogeneous ) + aChildSize.Width = mnEachWidth; + + if ( nMaxWidth && nRowWidth > 0 && nRowWidth + aChildSize.Width > nMaxWidth ) + { + nRowWidth = 0; + nNeedHeight += nRowHeight; + nRowHeight = 0; + } + nRowHeight = SAL_MAX( nRowHeight, aChildSize.Height ); + nRowWidth += aChildSize.Width; + } + nNeedHeight += nRowHeight; + + return awt::Size( nRowWidth, nNeedHeight ); +} + +awt::Size SAL_CALL +Flow::getMinimumSize() throw(uno::RuntimeException) +{ + return maRequisition = calculateSize( 0 ); +} + +sal_Bool SAL_CALL +Flow::hasHeightForWidth() + throw(css::uno::RuntimeException) +{ + return true; +} + +sal_Int32 SAL_CALL +Flow::getHeightForWidth( sal_Int32 nWidth ) + throw(css::uno::RuntimeException) +{ + return calculateSize( nWidth ).Height; +} + +void SAL_CALL +Flow::allocateArea( const css::awt::Rectangle &rArea ) + throw (css::uno::RuntimeException) +{ + maAllocation = rArea; + + std::list<ChildData *>::const_iterator it; + long nX = 0, nY = 0, nRowHeight = 0; + for (it = maChildren.begin(); it != maChildren.end(); it++) + { + ChildData *child = *it; + if ( !child->isVisible() ) + continue; + + awt::Size aChildSize( child->aRequisition ); + if ( mbHomogeneous ) + aChildSize.Width = mnEachWidth; + + if ( nX > 0 && nX + aChildSize.Width > rArea.Width ) + { + nX = 0; + nY += nRowHeight; + nRowHeight = 0; + } + nRowHeight = SAL_MAX( nRowHeight, aChildSize.Height ); + + allocateChildAt( child->xChild, + awt::Rectangle( rArea.X + nX, rArea.Y + nY, aChildSize.Width, aChildSize.Height ) ); + + nX += aChildSize.Width; + } +} + +} // namespace layoutimpl |