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 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_svtools.hxx" 30 #include <com/sun/star/accessibility/AccessibleRole.hpp> 31 32 #include <vcl/svapp.hxx> 33 34 #include <ipwin.hxx> 35 #include <hatchwindow.hxx> 36 37 /************************************************************************/ 38 /************************************************************************* 39 |* SvResizeHelper::SvResizeHelper() 40 |* 41 |* Beschreibung 42 *************************************************************************/ 43 SvResizeHelper::SvResizeHelper() 44 : aBorder( 5, 5 ) 45 , nGrab( -1 ) 46 , bResizeable( sal_True ) 47 { 48 } 49 50 /************************************************************************* 51 |* SvResizeHelper::FillHandleRects() 52 |* 53 |* Beschreibung: Die acht Handles zum vergroessern 54 *************************************************************************/ 55 void SvResizeHelper::FillHandleRectsPixel( Rectangle aRects[ 8 ] ) const 56 { 57 // nur wegen EMPTY_RECT 58 Point aBottomRight = aOuter.BottomRight(); 59 60 // Links Oben 61 aRects[ 0 ] = Rectangle( aOuter.TopLeft(), aBorder ); 62 // Oben Mitte 63 aRects[ 1 ] = Rectangle( Point( aOuter.Center().X() - aBorder.Width() / 2, 64 aOuter.Top() ), 65 aBorder ); 66 // Oben Rechts 67 aRects[ 2 ] = Rectangle( Point( aBottomRight.X() - aBorder.Width() +1, 68 aOuter.Top() ), 69 aBorder ); 70 // Mitte Rechts 71 aRects[ 3 ] = Rectangle( Point( aBottomRight.X() - aBorder.Width() +1, 72 aOuter.Center().Y() - aBorder.Height() / 2 ), 73 aBorder ); 74 // Unten Rechts 75 aRects[ 4 ] = Rectangle( Point( aBottomRight.X() - aBorder.Width() +1, 76 aBottomRight.Y() - aBorder.Height() +1 ), 77 aBorder ); 78 // Mitte Unten 79 aRects[ 5 ] = Rectangle( Point( aOuter.Center().X() - aBorder.Width() / 2, 80 aBottomRight.Y() - aBorder.Height() +1), 81 aBorder ); 82 // Links Unten 83 aRects[ 6 ] = Rectangle( Point( aOuter.Left(), 84 aBottomRight.Y() - aBorder.Height() +1), 85 aBorder ); 86 // Mitte Links 87 aRects[ 7 ] = Rectangle( Point( aOuter.Left(), 88 aOuter.Center().Y() - aBorder.Height() / 2 ), 89 aBorder ); 90 } 91 92 /************************************************************************* 93 |* SvResizeHelper::FillMoveRectsPixel() 94 |* 95 |* Beschreibung: Die vier Kanten werden berechnet 96 *************************************************************************/ 97 void SvResizeHelper::FillMoveRectsPixel( Rectangle aRects[ 4 ] ) const 98 { 99 // Oben 100 aRects[ 0 ] = aOuter; 101 aRects[ 0 ].Bottom() = aRects[ 0 ].Top() + aBorder.Height() -1; 102 // Rechts 103 aRects[ 1 ] = aOuter; 104 aRects[ 1 ].Left() = aRects[ 1 ].Right() - aBorder.Width() -1; 105 //Unten 106 aRects[ 2 ] = aOuter; 107 aRects[ 2 ].Top() = aRects[ 2 ].Bottom() - aBorder.Height() -1; 108 //Links 109 aRects[ 3 ] = aOuter; 110 aRects[ 3 ].Right() = aRects[ 3 ].Left() + aBorder.Width() -1; 111 } 112 113 /************************************************************************* 114 |* SvResizeHelper::Draw() 115 |* 116 |* Beschreibung 117 *************************************************************************/ 118 void SvResizeHelper::Draw( OutputDevice * pDev ) 119 { 120 pDev->Push(); 121 pDev->SetMapMode( MapMode() ); 122 Color aColBlack; 123 Color aFillColor( COL_LIGHTGRAY ); 124 125 pDev->SetFillColor( aFillColor ); 126 pDev->SetLineColor(); 127 128 Rectangle aMoveRects[ 4 ]; 129 FillMoveRectsPixel( aMoveRects ); 130 sal_uInt16 i; 131 for( i = 0; i < 4; i++ ) 132 pDev->DrawRect( aMoveRects[ i ] ); 133 if( bResizeable ) 134 { 135 // Handles malen 136 pDev->SetFillColor( aColBlack ); 137 Rectangle aRects[ 8 ]; 138 FillHandleRectsPixel( aRects ); 139 for( i = 0; i < 8; i++ ) 140 pDev->DrawRect( aRects[ i ] ); 141 } 142 pDev->Pop(); 143 } 144 145 /************************************************************************* 146 |* SvResizeHelper::InvalidateBorder() 147 |* 148 |* Beschreibung 149 *************************************************************************/ 150 void SvResizeHelper::InvalidateBorder( Window * pWin ) 151 { 152 Rectangle aMoveRects[ 4 ]; 153 FillMoveRectsPixel( aMoveRects ); 154 for( sal_uInt16 i = 0; i < 4; i++ ) 155 pWin->Invalidate( aMoveRects[ i ] ); 156 } 157 158 /************************************************************************* 159 |* SvResizeHelper::SelectBegin() 160 |* 161 |* Beschreibung 162 *************************************************************************/ 163 sal_Bool SvResizeHelper::SelectBegin( Window * pWin, const Point & rPos ) 164 { 165 if( -1 == nGrab ) 166 { 167 nGrab = SelectMove( pWin, rPos ); 168 if( -1 != nGrab ) 169 { 170 aSelPos = rPos; // Start-Position merken 171 pWin->CaptureMouse(); 172 return sal_True; 173 } 174 } 175 return sal_False; 176 } 177 178 /************************************************************************* 179 |* SvResizeHelper::SelectMove() 180 |* 181 |* Beschreibung 182 *************************************************************************/ 183 short SvResizeHelper::SelectMove( Window * pWin, const Point & rPos ) 184 { 185 if( -1 == nGrab ) 186 { 187 if( bResizeable ) 188 { 189 Rectangle aRects[ 8 ]; 190 FillHandleRectsPixel( aRects ); 191 for( sal_uInt16 i = 0; i < 8; i++ ) 192 if( aRects[ i ].IsInside( rPos ) ) 193 return i; 194 } 195 // Move-Rect ueberlappen Handles 196 Rectangle aMoveRects[ 4 ]; 197 FillMoveRectsPixel( aMoveRects ); 198 for( sal_uInt16 i = 0; i < 4; i++ ) 199 if( aMoveRects[ i ].IsInside( rPos ) ) 200 return 8; 201 } 202 else 203 { 204 Rectangle aRect( GetTrackRectPixel( rPos ) ); 205 aRect.SetSize( pWin->PixelToLogic( aRect.GetSize() ) ); 206 aRect.SetPos( pWin->PixelToLogic( aRect.TopLeft() ) ); 207 pWin->ShowTracking( aRect ); 208 } 209 return nGrab; 210 } 211 212 Point SvResizeHelper::GetTrackPosPixel( const Rectangle & rRect ) const 213 { 214 // wie das Rechteck zurueckkommt ist egal, es zaehlt welches Handle 215 // initial angefasst wurde 216 Point aPos; 217 Rectangle aRect( rRect ); 218 aRect.Justify(); 219 // nur wegen EMPTY_RECT 220 Point aBR = aOuter.BottomRight(); 221 Point aTR = aOuter.TopRight(); 222 Point aBL = aOuter.BottomLeft(); 223 switch( nGrab ) 224 { 225 case 0: 226 aPos = aRect.TopLeft() - aOuter.TopLeft(); 227 break; 228 case 1: 229 aPos.Y() = aRect.Top() - aOuter.Top(); 230 break; 231 case 2: 232 aPos = aRect.TopRight() - aTR; 233 break; 234 case 3: 235 aPos.X() = aRect.Right() - aTR.X(); 236 break; 237 case 4: 238 aPos = aRect.BottomRight() - aBR; 239 break; 240 case 5: 241 aPos.Y() = aRect.Bottom() - aBR.Y(); 242 break; 243 case 6: 244 aPos = aRect.BottomLeft() - aBL; 245 break; 246 case 7: 247 aPos.X() = aRect.Left() - aOuter.Left(); 248 break; 249 case 8: 250 aPos = aRect.TopLeft() - aOuter.TopLeft(); 251 break; 252 } 253 return aPos += aSelPos; 254 } 255 256 /************************************************************************* 257 |* SvResizeHelper::GetTrackRectPixel() 258 |* 259 |* Beschreibung 260 *************************************************************************/ 261 Rectangle SvResizeHelper::GetTrackRectPixel( const Point & rTrackPos ) const 262 { 263 Rectangle aTrackRect; 264 if( -1 != nGrab ) 265 { 266 Point aDiff = rTrackPos - aSelPos; 267 aTrackRect = aOuter; 268 Point aBR = aOuter.BottomRight(); 269 switch( nGrab ) 270 { 271 case 0: 272 aTrackRect.Top() += aDiff.Y(); 273 aTrackRect.Left() += aDiff.X(); 274 break; 275 case 1: 276 aTrackRect.Top() += aDiff.Y(); 277 break; 278 case 2: 279 aTrackRect.Top() += aDiff.Y(); 280 aTrackRect.Right() = aBR.X() + aDiff.X(); 281 break; 282 case 3: 283 aTrackRect.Right() = aBR.X() + aDiff.X(); 284 break; 285 case 4: 286 aTrackRect.Bottom() = aBR.Y() + aDiff.Y(); 287 aTrackRect.Right() = aBR.X() + aDiff.X(); 288 break; 289 case 5: 290 aTrackRect.Bottom() = aBR.Y() + aDiff.Y(); 291 break; 292 case 6: 293 aTrackRect.Bottom() = aBR.Y() + aDiff.Y(); 294 aTrackRect.Left() += aDiff.X(); 295 break; 296 case 7: 297 aTrackRect.Left() += aDiff.X(); 298 break; 299 case 8: 300 if( Application::GetSettings().GetLayoutRTL() ) 301 aDiff.X() = -aDiff.X(); // workaround for move in RTL mode 302 aTrackRect.SetPos( aTrackRect.TopLeft() + aDiff ); 303 break; 304 /* 305 case 0: 306 aTrackRect = Rectangle( rTrackPos, aOuter.BottomRight() ); 307 break; 308 case 1: 309 aTrackRect = Rectangle( Point( aOuter.Left(), rTrackPos.Y() ), 310 aOuter.BottomRight() ); 311 break; 312 case 2: 313 aTrackRect = Rectangle( rTrackPos, aOuter.BottomLeft() ); 314 break; 315 case 3: 316 aTrackRect = Rectangle( Point( rTrackPos.X(), aOuter.Top() ), 317 aOuter.BottomLeft() ); 318 break; 319 case 4: 320 aTrackRect = Rectangle( rTrackPos, aOuter.TopLeft() ); 321 break; 322 case 5: 323 aTrackRect = Rectangle( aOuter.TopLeft(), 324 Point( aOuter.Right(), rTrackPos.Y() ) ); 325 break; 326 case 6: 327 aTrackRect = Rectangle( aOuter.TopRight(), rTrackPos ); 328 break; 329 case 7: 330 aTrackRect = Rectangle( Point( rTrackPos.X(), aOuter.Top() ), 331 aOuter.BottomRight() ); 332 break; 333 case 8: 334 aTrackRect = Rectangle( aOuter.TopLeft() + rTrackPos - aSelPos, 335 aOuter.GetSize() ); 336 break; 337 */ 338 } 339 } 340 return aTrackRect; 341 } 342 343 void SvResizeHelper::ValidateRect( Rectangle & rValidate ) const 344 { 345 switch( nGrab ) 346 { 347 case 0: 348 if( rValidate.Top() > rValidate.Bottom() ) 349 { 350 rValidate.Top() = rValidate.Bottom(); 351 rValidate.Bottom() = RECT_EMPTY; 352 } 353 if( rValidate.Left() > rValidate.Right() ) 354 { 355 rValidate.Left() = rValidate.Right(); 356 rValidate.Right() = RECT_EMPTY; 357 } 358 break; 359 case 1: 360 if( rValidate.Top() > rValidate.Bottom() ) 361 { 362 rValidate.Top() = rValidate.Bottom(); 363 rValidate.Bottom() = RECT_EMPTY; 364 } 365 break; 366 case 2: 367 if( rValidate.Top() > rValidate.Bottom() ) 368 { 369 rValidate.Top() = rValidate.Bottom(); 370 rValidate.Bottom() = RECT_EMPTY; 371 } 372 if( rValidate.Left() > rValidate.Right() ) 373 rValidate.Right() = RECT_EMPTY; 374 break; 375 case 3: 376 if( rValidate.Left() > rValidate.Right() ) 377 rValidate.Right() = RECT_EMPTY; 378 break; 379 case 4: 380 if( rValidate.Top() > rValidate.Bottom() ) 381 rValidate.Bottom() = RECT_EMPTY; 382 if( rValidate.Left() > rValidate.Right() ) 383 rValidate.Right() = RECT_EMPTY; 384 break; 385 case 5: 386 if( rValidate.Top() > rValidate.Bottom() ) 387 rValidate.Bottom() = RECT_EMPTY; 388 break; 389 case 6: 390 if( rValidate.Top() > rValidate.Bottom() ) 391 rValidate.Bottom() = RECT_EMPTY; 392 if( rValidate.Left() > rValidate.Right() ) 393 { 394 rValidate.Left() = rValidate.Right(); 395 rValidate.Right() = RECT_EMPTY; 396 } 397 break; 398 case 7: 399 if( rValidate.Left() > rValidate.Right() ) 400 { 401 rValidate.Left() = rValidate.Right(); 402 rValidate.Right() = RECT_EMPTY; 403 } 404 break; 405 } 406 if( rValidate.Right() == RECT_EMPTY ) 407 rValidate.Right() = rValidate.Left(); 408 if( rValidate.Bottom() == RECT_EMPTY ) 409 rValidate.Bottom() = rValidate.Top(); 410 411 // Mindestgr"osse 5 x 5 412 if( rValidate.Left() + 5 > rValidate.Right() ) 413 rValidate.Right() = rValidate.Left() +5; 414 if( rValidate.Top() + 5 > rValidate.Bottom() ) 415 rValidate.Bottom() = rValidate.Top() +5; 416 } 417 418 /************************************************************************* 419 |* SvResizeHelper::SelectRelease() 420 |* 421 |* Beschreibung 422 *************************************************************************/ 423 sal_Bool SvResizeHelper::SelectRelease( Window * pWin, const Point & rPos, 424 Rectangle & rOutPosSize ) 425 { 426 if( -1 != nGrab ) 427 { 428 rOutPosSize = GetTrackRectPixel( rPos ); 429 rOutPosSize.Justify(); 430 nGrab = -1; 431 pWin->ReleaseMouse(); 432 pWin->HideTracking(); 433 return sal_True; 434 } 435 return sal_False; 436 } 437 438 /************************************************************************* 439 |* SvResizeHelper::Release() 440 |* 441 |* Beschreibung 442 *************************************************************************/ 443 void SvResizeHelper::Release( Window * pWin ) 444 { 445 if( nGrab != -1 ) 446 { 447 pWin->ReleaseMouse(); 448 pWin->HideTracking(); 449 nGrab = -1; 450 } 451 } 452 453 /************************************************************************* 454 |* SvResizeWindow::SvResizeWindow() 455 |* 456 |* Beschreibung 457 *************************************************************************/ 458 SvResizeWindow::SvResizeWindow 459 ( 460 Window * pParent, 461 VCLXHatchWindow* pWrapper 462 ) 463 : Window( pParent, WB_CLIPCHILDREN ) 464 , m_nMoveGrab( -1 ) 465 , m_bActive( sal_False ) 466 , m_pWrapper( pWrapper ) 467 { 468 OSL_ENSURE( pParent != NULL && pWrapper != NULL, "Wrong initialization of hatch window!\n" ); 469 SetBackground(); 470 SetAccessibleRole( ::com::sun::star::accessibility::AccessibleRole::EMBEDDED_OBJECT ); 471 m_aResizer.SetOuterRectPixel( Rectangle( Point(), GetOutputSizePixel() ) ); 472 } 473 474 /************************************************************************* 475 |* SvResizeWindow::SetHatchBorderPixel() 476 |* 477 |* Beschreibung 478 *************************************************************************/ 479 void SvResizeWindow::SetHatchBorderPixel( const Size & rSize ) 480 { 481 m_aResizer.SetBorderPixel( rSize ); 482 } 483 484 /************************************************************************* 485 |* SvResizeWindow::SelectMouse() 486 |* 487 |* Beschreibung 488 *************************************************************************/ 489 void SvResizeWindow::SelectMouse( const Point & rPos ) 490 { 491 short nGrab = m_aResizer.SelectMove( this, rPos ); 492 if( nGrab >= 4 ) 493 nGrab -= 4; 494 if( m_nMoveGrab != nGrab ) 495 { // Pointer hat sich geaendert 496 if( -1 == nGrab ) 497 SetPointer( m_aOldPointer ); 498 else 499 { 500 PointerStyle aStyle = POINTER_MOVE; 501 if( nGrab == 3 ) 502 aStyle = POINTER_ESIZE; 503 else if( nGrab == 2 ) 504 aStyle = POINTER_NESIZE; 505 else if( nGrab == 1 ) 506 aStyle = POINTER_SSIZE; 507 else if( nGrab == 0 ) 508 aStyle = POINTER_SESIZE; 509 if( m_nMoveGrab == -1 ) // das erste mal 510 { 511 m_aOldPointer = GetPointer(); 512 SetPointer( Pointer( aStyle ) ); 513 } 514 else 515 SetPointer( Pointer( aStyle ) ); 516 } 517 m_nMoveGrab = nGrab; 518 } 519 } 520 521 /************************************************************************* 522 |* SvResizeWindow::MouseButtonDown() 523 |* 524 |* Beschreibung 525 *************************************************************************/ 526 void SvResizeWindow::MouseButtonDown( const MouseEvent & rEvt ) 527 { 528 if( m_aResizer.SelectBegin( this, rEvt.GetPosPixel() ) ) 529 SelectMouse( rEvt.GetPosPixel() ); 530 } 531 532 /************************************************************************* 533 |* SvResizeWindow::MouseMove() 534 |* 535 |* Beschreibung 536 *************************************************************************/ 537 void SvResizeWindow::MouseMove( const MouseEvent & rEvt ) 538 { 539 if( m_aResizer.GetGrab() == -1 ) 540 SelectMouse( rEvt.GetPosPixel() ); 541 else 542 { 543 Rectangle aRect( m_aResizer.GetTrackRectPixel( rEvt.GetPosPixel() ) ); 544 Point aDiff = GetPosPixel(); 545 aRect.SetPos( aRect.TopLeft() + aDiff ); 546 m_aResizer.ValidateRect( aRect ); 547 548 m_pWrapper->QueryObjAreaPixel( aRect ); 549 aRect.SetPos( aRect.TopLeft() - aDiff ); 550 Point aPos = m_aResizer.GetTrackPosPixel( aRect ); 551 552 SelectMouse( aPos ); 553 } 554 } 555 556 /************************************************************************* 557 |* SvResizeWindow::MouseButtonUp() 558 |* 559 |* Beschreibung 560 *************************************************************************/ 561 void SvResizeWindow::MouseButtonUp( const MouseEvent & rEvt ) 562 { 563 if( m_aResizer.GetGrab() != -1 ) 564 { 565 Rectangle aRect( m_aResizer.GetTrackRectPixel( rEvt.GetPosPixel() ) ); 566 Point aDiff = GetPosPixel(); 567 aRect.SetPos( aRect.TopLeft() + aDiff ); 568 // aRect -= GetAllBorderPixel(); 569 m_aResizer.ValidateRect( aRect ); 570 571 m_pWrapper->QueryObjAreaPixel( aRect ); 572 573 Rectangle aOutRect; 574 if( m_aResizer.SelectRelease( this, rEvt.GetPosPixel(), aOutRect ) ) 575 { 576 m_nMoveGrab = -1; 577 SetPointer( m_aOldPointer ); 578 m_pWrapper->RequestObjAreaPixel( aRect ); 579 } 580 } 581 } 582 583 /************************************************************************* 584 |* SvResizeWindow::KeyEvent() 585 |* 586 |* Beschreibung 587 *************************************************************************/ 588 void SvResizeWindow::KeyInput( const KeyEvent & rEvt ) 589 { 590 if( rEvt.GetKeyCode().GetCode() == KEY_ESCAPE ) 591 { 592 m_aResizer.Release( this ); 593 m_pWrapper->InplaceDeactivate(); 594 } 595 } 596 597 /************************************************************************* 598 |* SvResizeWindow::Resize() 599 |* 600 |* Beschreibung 601 *************************************************************************/ 602 void SvResizeWindow::Resize() 603 { 604 m_aResizer.InvalidateBorder( this ); // alten Bereich 605 m_aResizer.SetOuterRectPixel( Rectangle( Point(), GetOutputSizePixel() ) ); 606 m_aResizer.InvalidateBorder( this ); // neuen Bereich 607 } 608 609 /************************************************************************* 610 |* SvResizeWindow::Paint() 611 |* 612 |* Beschreibung 613 *************************************************************************/ 614 void SvResizeWindow::Paint( const Rectangle & /*rRect*/ ) 615 { 616 m_aResizer.Draw( this ); 617 } 618 619 long SvResizeWindow::PreNotify( NotifyEvent& rEvt ) 620 { 621 if ( rEvt.GetType() == EVENT_GETFOCUS && !m_bActive ) 622 { 623 m_bActive = sal_True; 624 m_pWrapper->Activated(); 625 } 626 627 return Window::PreNotify(rEvt); 628 } 629 630 long SvResizeWindow::Notify( NotifyEvent& rEvt ) 631 { 632 if ( rEvt.GetType() == EVENT_LOSEFOCUS && m_bActive ) 633 { 634 sal_Bool bHasFocus = HasChildPathFocus(sal_True); 635 if ( !bHasFocus ) 636 { 637 m_bActive = sal_False; 638 m_pWrapper->Deactivated(); 639 } 640 } 641 642 return Window::Notify(rEvt); 643 } 644 645