1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include "flow.hxx" 29 30 #include <sal/macros.h> 31 32 namespace layoutimpl 33 { 34 35 using namespace css; 36 37 bool Flow::ChildData::isVisible() 38 { 39 return xChild.is(); 40 } 41 42 Flow::Flow() 43 : Container() 44 , mnSpacing( 0 ) 45 , mbHomogeneous( false ) 46 { 47 addProp( RTL_CONSTASCII_USTRINGPARAM( "Homogeneous" ), 48 ::getCppuType( static_cast< const sal_Bool* >( NULL ) ), 49 &mbHomogeneous ); 50 addProp( RTL_CONSTASCII_USTRINGPARAM( "Spacing" ), 51 ::getCppuType( static_cast< const sal_Int32* >( NULL ) ), 52 &mnSpacing ); 53 } 54 55 bool 56 Flow::emptyVisible () 57 { 58 return true; 59 } 60 61 void SAL_CALL 62 Flow::addChild( const uno::Reference< awt::XLayoutConstrains >& xChild ) 63 throw (uno::RuntimeException, css::awt::MaxChildrenException) 64 { 65 if ( xChild.is() ) 66 { 67 ChildData *pData = new ChildData(); 68 pData->xChild = xChild; 69 maChildren.push_back( pData ); 70 71 setChildParent( xChild ); 72 queueResize(); 73 } 74 } 75 76 void SAL_CALL 77 Flow::removeChild( const css::uno::Reference< css::awt::XLayoutConstrains >& xChild ) 78 throw (css::uno::RuntimeException) 79 { 80 for ( std::list< ChildData * >::iterator it = maChildren.begin(); 81 it != maChildren.end(); it++ ) 82 { 83 if ( (*it)->xChild == xChild ) 84 { 85 delete *it; 86 maChildren.erase( it ); 87 88 unsetChildParent( xChild ); 89 queueResize(); 90 break; 91 } 92 } 93 } 94 95 css::uno::Sequence< css::uno::Reference < css::awt::XLayoutConstrains > > SAL_CALL 96 Flow::getChildren() 97 throw (css::uno::RuntimeException) 98 { 99 uno::Sequence< uno::Reference< awt::XLayoutConstrains > > children( maChildren.size() ); 100 unsigned int i = 0; 101 for ( std::list< ChildData * >::iterator it = maChildren.begin(); 102 it != maChildren.end(); it++, i++ ) 103 children[i] = (*it)->xChild; 104 105 return children; 106 } 107 108 uno::Reference< beans::XPropertySet > SAL_CALL 109 Flow::getChildProperties( const uno::Reference< awt::XLayoutConstrains >& /*xChild*/ ) 110 throw (uno::RuntimeException) 111 { 112 return uno::Reference< beans::XPropertySet >(); 113 } 114 115 css::awt::Size 116 Flow::calculateSize( long nMaxWidth ) 117 { 118 long nNeedHeight = 0; 119 120 std::list<ChildData *>::const_iterator it; 121 mnEachWidth = 0; 122 // first pass, for homogeneous property 123 for (it = maChildren.begin(); it != maChildren.end(); it++) 124 { 125 if ( !(*it)->isVisible() ) 126 continue; 127 (*it)->aRequisition = (*it)->xChild->getMinimumSize(); 128 if ( mbHomogeneous ) 129 mnEachWidth = SAL_MAX( mnEachWidth, (*it)->aRequisition.Width ); 130 } 131 132 long nRowWidth = 0, nRowHeight = 0; 133 for (it = maChildren.begin(); it != maChildren.end(); it++) 134 { 135 if ( !(*it)->isVisible() ) 136 continue; 137 138 awt::Size aChildSize = (*it)->aRequisition; 139 if ( mbHomogeneous ) 140 aChildSize.Width = mnEachWidth; 141 142 if ( nMaxWidth && nRowWidth > 0 && nRowWidth + aChildSize.Width > nMaxWidth ) 143 { 144 nRowWidth = 0; 145 nNeedHeight += nRowHeight; 146 nRowHeight = 0; 147 } 148 nRowHeight = SAL_MAX( nRowHeight, aChildSize.Height ); 149 nRowWidth += aChildSize.Width; 150 } 151 nNeedHeight += nRowHeight; 152 153 return awt::Size( nRowWidth, nNeedHeight ); 154 } 155 156 awt::Size SAL_CALL 157 Flow::getMinimumSize() throw(uno::RuntimeException) 158 { 159 return maRequisition = calculateSize( 0 ); 160 } 161 162 sal_Bool SAL_CALL 163 Flow::hasHeightForWidth() 164 throw(css::uno::RuntimeException) 165 { 166 return true; 167 } 168 169 sal_Int32 SAL_CALL 170 Flow::getHeightForWidth( sal_Int32 nWidth ) 171 throw(css::uno::RuntimeException) 172 { 173 return calculateSize( nWidth ).Height; 174 } 175 176 void SAL_CALL 177 Flow::allocateArea( const css::awt::Rectangle &rArea ) 178 throw (css::uno::RuntimeException) 179 { 180 maAllocation = rArea; 181 182 std::list<ChildData *>::const_iterator it; 183 long nX = 0, nY = 0, nRowHeight = 0; 184 for (it = maChildren.begin(); it != maChildren.end(); it++) 185 { 186 ChildData *child = *it; 187 if ( !child->isVisible() ) 188 continue; 189 190 awt::Size aChildSize( child->aRequisition ); 191 if ( mbHomogeneous ) 192 aChildSize.Width = mnEachWidth; 193 194 if ( nX > 0 && nX + aChildSize.Width > rArea.Width ) 195 { 196 nX = 0; 197 nY += nRowHeight; 198 nRowHeight = 0; 199 } 200 nRowHeight = SAL_MAX( nRowHeight, aChildSize.Height ); 201 202 allocateChildAt( child->xChild, 203 awt::Rectangle( rArea.X + nX, rArea.Y + nY, aChildSize.Width, aChildSize.Height ) ); 204 205 nX += aChildSize.Width; 206 } 207 } 208 209 } // namespace layoutimpl 210