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 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_svtools.hxx" 26 27 #define _TASKBAR_CXX 28 29 #include <tools/list.hxx> 30 #include <tools/debug.hxx> 31 #include <vcl/help.hxx> 32 #include <svtools/taskbar.hxx> 33 34 // ======================================================================= 35 36 TaskButtonBar::TaskButtonBar( Window* pParent, WinBits nWinStyle ) : 37 ToolBox( pParent, nWinStyle | WB_3DLOOK ) 38 { 39 SetAlign( WINDOWALIGN_BOTTOM ); 40 SetButtonType( BUTTON_SYMBOLTEXT ); 41 } 42 43 // ----------------------------------------------------------------------- 44 45 TaskButtonBar::~TaskButtonBar() 46 { 47 } 48 49 // ----------------------------------------------------------------------- 50 51 void TaskButtonBar::RequestHelp( const HelpEvent& rHEvt ) 52 { 53 ToolBox::RequestHelp( rHEvt ); 54 } 55 56 // ======================================================================= 57 58 WindowArrange::WindowArrange() 59 { 60 mpWinList = new List; 61 } 62 63 // ----------------------------------------------------------------------- 64 65 WindowArrange::~WindowArrange() 66 { 67 delete mpWinList; 68 } 69 70 // ----------------------------------------------------------------------- 71 72 static sal_uInt16 ImplCeilSqareRoot( sal_uInt16 nVal ) 73 { 74 sal_uInt16 i; 75 76 // Ueberlauf verhindern 77 if ( nVal > 0xFE * 0xFE ) 78 return 0xFE; 79 80 for ( i=0; i*i < nVal; i++ ) 81 {} 82 83 return i; 84 } 85 86 // ----------------------------------------------------------------------- 87 88 static void ImplPosSizeWindow( Window* pWindow, 89 long nX, long nY, long nWidth, long nHeight ) 90 { 91 if ( nWidth < 32 ) 92 nWidth = 32; 93 if ( nHeight < 24 ) 94 nHeight = 24; 95 pWindow->SetPosSizePixel( nX, nY, nWidth, nHeight ); 96 } 97 98 // ----------------------------------------------------------------------- 99 100 void WindowArrange::ImplTile( const Rectangle& rRect ) 101 { 102 sal_uInt16 nCount = (sal_uInt16)mpWinList->Count(); 103 if ( nCount < 3 ) 104 { 105 ImplVert( rRect ); 106 return; 107 } 108 109 sal_uInt16 i; 110 sal_uInt16 j; 111 sal_uInt16 nCols; 112 sal_uInt16 nRows; 113 sal_uInt16 nActRows; 114 sal_uInt16 nOffset; 115 long nOverWidth; 116 long nOverHeight; 117 Window* pWindow; 118 long nX = rRect.Left(); 119 long nY = rRect.Top(); 120 long nWidth = rRect.GetWidth(); 121 long nHeight = rRect.GetHeight(); 122 long nRectY = nY; 123 long nRectWidth = nWidth; 124 long nRectHeight = nHeight; 125 long nTempWidth; 126 long nTempHeight; 127 128 nCols = ImplCeilSqareRoot( nCount ); 129 nOffset = (nCols*nCols) - nCount; 130 if ( nOffset >= nCols ) 131 { 132 nRows = nCols -1; 133 nOffset = nOffset - nCols; 134 } 135 else 136 nRows = nCols; 137 138 nWidth /= nCols; 139 if ( nWidth < 1 ) 140 nWidth = 1; 141 nOverWidth = nRectWidth-(nWidth*nCols); 142 143 pWindow = (Window*)mpWinList->First(); 144 for ( i = 0; i < nCols; i++ ) 145 { 146 if ( i < nOffset ) 147 nActRows = nRows - 1; 148 else 149 nActRows = nRows; 150 151 nTempWidth = nWidth; 152 if ( nOverWidth > 0 ) 153 { 154 nTempWidth++; 155 nOverWidth--; 156 } 157 158 nHeight = nRectHeight / nActRows; 159 if ( nHeight < 1 ) 160 nHeight = 1; 161 nOverHeight = nRectHeight-(nHeight*nActRows); 162 for ( j = 0; j < nActRows; j++ ) 163 { 164 // Ueberhang verteilen 165 nTempHeight = nHeight; 166 if ( nOverHeight > 0 ) 167 { 168 nTempHeight++; 169 nOverHeight--; 170 } 171 ImplPosSizeWindow( pWindow, nX, nY, nTempWidth, nTempHeight ); 172 nY += nTempHeight; 173 174 pWindow = (Window*)mpWinList->Next(); 175 if ( !pWindow ) 176 break; 177 } 178 179 nX += nWidth; 180 nY = nRectY; 181 182 if ( !pWindow ) 183 break; 184 } 185 } 186 187 // ----------------------------------------------------------------------- 188 189 void WindowArrange::ImplHorz( const Rectangle& rRect ) 190 { 191 long nCount = (long)mpWinList->Count(); 192 long nX = rRect.Left(); 193 long nY = rRect.Top(); 194 long nWidth = rRect.GetWidth(); 195 long nHeight = rRect.GetHeight(); 196 long nRectHeight = nHeight; 197 long nOver; 198 long nTempHeight; 199 Window* pWindow; 200 201 nHeight /= nCount; 202 if ( nHeight < 1 ) 203 nHeight = 1; 204 nOver = nRectHeight - (nCount*nHeight); 205 pWindow = (Window*)mpWinList->First(); 206 while ( pWindow ) 207 { 208 nTempHeight = nHeight; 209 if ( nOver > 0 ) 210 { 211 nTempHeight++; 212 nOver--; 213 } 214 ImplPosSizeWindow( pWindow, nX, nY, nWidth, nTempHeight ); 215 nY += nTempHeight; 216 217 pWindow = (Window*)mpWinList->Next(); 218 } 219 } 220 221 // ----------------------------------------------------------------------- 222 223 void WindowArrange::ImplVert( const Rectangle& rRect ) 224 { 225 long nCount = (long)mpWinList->Count(); 226 long nX = rRect.Left(); 227 long nY = rRect.Top(); 228 long nWidth = rRect.GetWidth(); 229 long nHeight = rRect.GetHeight(); 230 long nRectWidth = nWidth; 231 long nOver; 232 long nTempWidth; 233 Window* pWindow; 234 235 nWidth /= nCount; 236 if ( nWidth < 1 ) 237 nWidth = 1; 238 nOver = nRectWidth - (nCount*nWidth); 239 pWindow = (Window*)mpWinList->First(); 240 while ( pWindow ) 241 { 242 nTempWidth = nWidth; 243 if ( nOver > 0 ) 244 { 245 nTempWidth++; 246 nOver--; 247 } 248 ImplPosSizeWindow( pWindow, nX, nY, nTempWidth, nHeight ); 249 nX += nTempWidth; 250 251 pWindow = (Window*)mpWinList->Next(); 252 } 253 } 254 255 // ----------------------------------------------------------------------- 256 257 void WindowArrange::ImplCascade( const Rectangle& rRect ) 258 { 259 long nX = rRect.Left(); 260 long nY = rRect.Top(); 261 long nWidth = rRect.GetWidth(); 262 long nHeight = rRect.GetHeight(); 263 long nRectWidth = nWidth; 264 long nRectHeight = nHeight; 265 long nOff; 266 long nCascadeWins; 267 sal_Int32 nLeftBorder; 268 sal_Int32 nTopBorder; 269 sal_Int32 nRightBorder; 270 sal_Int32 nBottomBorder; 271 long nStartOverWidth; 272 long nStartOverHeight; 273 long nOverWidth = 0; 274 long nOverHeight = 0; 275 long nTempX; 276 long nTempY; 277 long nTempWidth; 278 long nTempHeight; 279 long i; 280 Window* pWindow; 281 Window* pTempWindow; 282 283 // Border-Fenster suchen um den Versatz zu ermitteln 284 pTempWindow = (Window*)mpWinList->First(); 285 pTempWindow->GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder ); 286 while ( !nTopBorder ) 287 { 288 Window* pBrdWin = pTempWindow->GetWindow( WINDOW_REALPARENT ); 289 if ( !pBrdWin || (pBrdWin->GetWindow( WINDOW_CLIENT ) != pTempWindow) ) 290 break; 291 pTempWindow = pBrdWin; 292 pTempWindow->GetBorder( nLeftBorder, nTopBorder, nRightBorder, nBottomBorder ); 293 } 294 if ( !nTopBorder ) 295 nTopBorder = 22; 296 nOff = nTopBorder; 297 298 nCascadeWins = nRectHeight / 3 / nOff; 299 if ( !nCascadeWins ) 300 nCascadeWins = 1; 301 nWidth -= nCascadeWins*nOff; 302 nHeight -= nCascadeWins*nOff; 303 if ( nWidth < 1 ) 304 nWidth = 1; 305 if ( nHeight < 1 ) 306 nHeight = 1; 307 308 nStartOverWidth = nRectWidth-(nWidth+(nCascadeWins*nOff)); 309 nStartOverHeight = nRectHeight-(nHeight+(nCascadeWins*nOff)); 310 311 i = 0; 312 pWindow = (Window*)mpWinList->First(); 313 while ( pWindow ) 314 { 315 if ( !i ) 316 { 317 nOverWidth = nStartOverWidth; 318 nOverHeight = nStartOverHeight; 319 } 320 321 // Position 322 nTempX = nX + (i*nOff); 323 nTempY = nY + (i*nOff); 324 325 // Ueberhang verteilen 326 nTempWidth = nWidth; 327 if ( nOverWidth > 0 ) 328 { 329 nTempWidth++; 330 nOverWidth--; 331 } 332 nTempHeight = nHeight; 333 if ( nOverHeight > 0 ) 334 { 335 nTempHeight++; 336 nOverHeight--; 337 } 338 339 ImplPosSizeWindow( pWindow, nTempX, nTempY, nTempWidth, nTempHeight ); 340 341 if ( i < nCascadeWins ) 342 i++; 343 else 344 i = 0; 345 346 pWindow = (Window*)mpWinList->Next(); 347 } 348 } 349 350 // ----------------------------------------------------------------------- 351 352 void WindowArrange::Arrange( sal_uInt16 nType, const Rectangle& rRect ) 353 { 354 if ( !mpWinList->Count() ) 355 return; 356 357 switch ( nType ) 358 { 359 case WINDOWARRANGE_TILE: 360 ImplTile( rRect ); 361 break; 362 case WINDOWARRANGE_HORZ: 363 ImplHorz( rRect ); 364 break; 365 case WINDOWARRANGE_VERT: 366 ImplVert( rRect ); 367 break; 368 case WINDOWARRANGE_CASCADE: 369 ImplCascade( rRect ); 370 break; 371 } 372 } 373 374