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