1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #include "flow.hxx" 25 26 #include <sal/macros.h> 27 28 namespace layoutimpl 29 { 30 31 using namespace css; 32 33 bool Flow::ChildData::isVisible() 34 { 35 return xChild.is(); 36 } 37 38 Flow::Flow() 39 : Container() 40 , mnSpacing( 0 ) 41 , mbHomogeneous( false ) 42 { 43 addProp( RTL_CONSTASCII_USTRINGPARAM( "Homogeneous" ), 44 ::getCppuType( static_cast< const sal_Bool* >( NULL ) ), 45 &mbHomogeneous ); 46 addProp( RTL_CONSTASCII_USTRINGPARAM( "Spacing" ), 47 ::getCppuType( static_cast< const sal_Int32* >( NULL ) ), 48 &mnSpacing ); 49 } 50 51 bool 52 Flow::emptyVisible () 53 { 54 return true; 55 } 56 57 void SAL_CALL 58 Flow::addChild( const uno::Reference< awt::XLayoutConstrains >& xChild ) 59 throw (uno::RuntimeException, css::awt::MaxChildrenException) 60 { 61 if ( xChild.is() ) 62 { 63 ChildData *pData = new ChildData(); 64 pData->xChild = xChild; 65 maChildren.push_back( pData ); 66 67 setChildParent( xChild ); 68 queueResize(); 69 } 70 } 71 72 void SAL_CALL 73 Flow::removeChild( const css::uno::Reference< css::awt::XLayoutConstrains >& xChild ) 74 throw (css::uno::RuntimeException) 75 { 76 for ( std::list< ChildData * >::iterator it = maChildren.begin(); 77 it != maChildren.end(); it++ ) 78 { 79 if ( (*it)->xChild == xChild ) 80 { 81 delete *it; 82 maChildren.erase( it ); 83 84 unsetChildParent( xChild ); 85 queueResize(); 86 break; 87 } 88 } 89 } 90 91 css::uno::Sequence< css::uno::Reference < css::awt::XLayoutConstrains > > SAL_CALL 92 Flow::getChildren() 93 throw (css::uno::RuntimeException) 94 { 95 uno::Sequence< uno::Reference< awt::XLayoutConstrains > > children( maChildren.size() ); 96 unsigned int i = 0; 97 for ( std::list< ChildData * >::iterator it = maChildren.begin(); 98 it != maChildren.end(); it++, i++ ) 99 children[i] = (*it)->xChild; 100 101 return children; 102 } 103 104 uno::Reference< beans::XPropertySet > SAL_CALL 105 Flow::getChildProperties( const uno::Reference< awt::XLayoutConstrains >& /*xChild*/ ) 106 throw (uno::RuntimeException) 107 { 108 return uno::Reference< beans::XPropertySet >(); 109 } 110 111 css::awt::Size 112 Flow::calculateSize( long nMaxWidth ) 113 { 114 long nNeedHeight = 0; 115 116 std::list<ChildData *>::const_iterator it; 117 mnEachWidth = 0; 118 // first pass, for homogeneous property 119 for (it = maChildren.begin(); it != maChildren.end(); it++) 120 { 121 if ( !(*it)->isVisible() ) 122 continue; 123 (*it)->aRequisition = (*it)->xChild->getMinimumSize(); 124 if ( mbHomogeneous ) 125 mnEachWidth = SAL_MAX( mnEachWidth, (*it)->aRequisition.Width ); 126 } 127 128 long nRowWidth = 0, nRowHeight = 0; 129 for (it = maChildren.begin(); it != maChildren.end(); it++) 130 { 131 if ( !(*it)->isVisible() ) 132 continue; 133 134 awt::Size aChildSize = (*it)->aRequisition; 135 if ( mbHomogeneous ) 136 aChildSize.Width = mnEachWidth; 137 138 if ( nMaxWidth && nRowWidth > 0 && nRowWidth + aChildSize.Width > nMaxWidth ) 139 { 140 nRowWidth = 0; 141 nNeedHeight += nRowHeight; 142 nRowHeight = 0; 143 } 144 nRowHeight = SAL_MAX( nRowHeight, aChildSize.Height ); 145 nRowWidth += aChildSize.Width; 146 } 147 nNeedHeight += nRowHeight; 148 149 return awt::Size( nRowWidth, nNeedHeight ); 150 } 151 152 awt::Size SAL_CALL 153 Flow::getMinimumSize() throw(uno::RuntimeException) 154 { 155 return maRequisition = calculateSize( 0 ); 156 } 157 158 sal_Bool SAL_CALL 159 Flow::hasHeightForWidth() 160 throw(css::uno::RuntimeException) 161 { 162 return true; 163 } 164 165 sal_Int32 SAL_CALL 166 Flow::getHeightForWidth( sal_Int32 nWidth ) 167 throw(css::uno::RuntimeException) 168 { 169 return calculateSize( nWidth ).Height; 170 } 171 172 void SAL_CALL 173 Flow::allocateArea( const css::awt::Rectangle &rArea ) 174 throw (css::uno::RuntimeException) 175 { 176 maAllocation = rArea; 177 178 std::list<ChildData *>::const_iterator it; 179 long nX = 0, nY = 0, nRowHeight = 0; 180 for (it = maChildren.begin(); it != maChildren.end(); it++) 181 { 182 ChildData *child = *it; 183 if ( !child->isVisible() ) 184 continue; 185 186 awt::Size aChildSize( child->aRequisition ); 187 if ( mbHomogeneous ) 188 aChildSize.Width = mnEachWidth; 189 190 if ( nX > 0 && nX + aChildSize.Width > rArea.Width ) 191 { 192 nX = 0; 193 nY += nRowHeight; 194 nRowHeight = 0; 195 } 196 nRowHeight = SAL_MAX( nRowHeight, aChildSize.Height ); 197 198 allocateChildAt( child->xChild, 199 awt::Rectangle( rArea.X + nX, rArea.Y + nY, aChildSize.Width, aChildSize.Height ) ); 200 201 nX += aChildSize.Width; 202 } 203 } 204 205 } // namespace layoutimpl 206