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_vcl.hxx" 30 31 #include <tools/debug.hxx> 32 #include <tools/poly.hxx> 33 #include <tools/rc.h> 34 35 #include <vcl/image.hxx> 36 #include <vcl/bitmap.hxx> 37 #include <vcl/bitmapex.hxx> 38 #include <vcl/decoview.hxx> 39 #include <vcl/event.hxx> 40 #include <vcl/svapp.hxx> 41 #include <vcl/dialog.hxx> 42 #include <vcl/fixed.hxx> 43 #include <vcl/button.hxx> 44 #include <vcl/salnativewidgets.hxx> 45 #include <vcl/edit.hxx> 46 47 #include <svids.hrc> 48 #include <svdata.hxx> 49 #include <window.h> 50 #include <controldata.hxx> 51 52 // ======================================================================= 53 54 #define PUSHBUTTON_VIEW_STYLE (WB_3DLOOK | \ 55 WB_LEFT | WB_CENTER | WB_RIGHT | \ 56 WB_TOP | WB_VCENTER | WB_BOTTOM | \ 57 WB_WORDBREAK | WB_NOLABEL | \ 58 WB_DEFBUTTON | WB_NOLIGHTBORDER | \ 59 WB_RECTSTYLE | WB_SMALLSTYLE | \ 60 WB_TOGGLE ) 61 #define RADIOBUTTON_VIEW_STYLE (WB_3DLOOK | \ 62 WB_LEFT | WB_CENTER | WB_RIGHT | \ 63 WB_TOP | WB_VCENTER | WB_BOTTOM | \ 64 WB_WORDBREAK | WB_NOLABEL) 65 #define CHECKBOX_VIEW_STYLE (WB_3DLOOK | \ 66 WB_LEFT | WB_CENTER | WB_RIGHT | \ 67 WB_TOP | WB_VCENTER | WB_BOTTOM | \ 68 WB_WORDBREAK | WB_NOLABEL) 69 70 // ======================================================================= 71 72 class ImplCommonButtonData 73 { 74 public: 75 Rectangle maFocusRect; 76 Rectangle maSymbolRect; 77 sal_uInt16 mnButtonState; 78 sal_Bool mbSmallSymbol; 79 80 Image maImage; 81 Image maImageHC; 82 BitmapEx* mpBitmapEx; 83 BitmapEx* mpBitmapExHC; 84 ImageAlign meImageAlign; 85 SymbolAlign meSymbolAlign; 86 87 public: 88 ImplCommonButtonData(); 89 ~ImplCommonButtonData(); 90 }; 91 92 // ----------------------------------------------------------------------- 93 ImplCommonButtonData::ImplCommonButtonData() 94 { 95 mnButtonState = 0; 96 mbSmallSymbol = sal_False; 97 98 mpBitmapEx = NULL; 99 mpBitmapExHC = NULL; 100 meImageAlign = IMAGEALIGN_TOP; 101 meSymbolAlign = SYMBOLALIGN_LEFT; 102 } 103 104 // ----------------------------------------------------------------------- 105 ImplCommonButtonData::~ImplCommonButtonData() 106 { 107 delete mpBitmapEx; 108 delete mpBitmapExHC; 109 } 110 111 // ======================================================================= 112 113 Button::Button( WindowType nType ) : 114 Control( nType ) 115 { 116 mpButtonData = new ImplCommonButtonData; 117 } 118 119 // ----------------------------------------------------------------------- 120 121 Button::Button( Window* pParent, WinBits nStyle ) : 122 Control( WINDOW_BUTTON ) 123 { 124 mpButtonData = new ImplCommonButtonData; 125 ImplInit( pParent, nStyle, NULL ); 126 } 127 128 // ----------------------------------------------------------------------- 129 130 Button::Button( Window* pParent, const ResId& rResId ) : 131 Control( WINDOW_BUTTON ) 132 { 133 rResId.SetRT( RSC_BUTTON ); 134 mpButtonData = new ImplCommonButtonData; 135 WinBits nStyle = ImplInitRes( rResId ); 136 ImplInit( pParent, nStyle, NULL ); 137 ImplLoadRes( rResId ); 138 139 if ( !(nStyle & WB_HIDE) ) 140 Show(); 141 } 142 143 // ----------------------------------------------------------------------- 144 145 Button::~Button() 146 { 147 delete mpButtonData; 148 } 149 150 // ----------------------------------------------------------------------- 151 152 void Button::Click() 153 { 154 ImplCallEventListenersAndHandler( VCLEVENT_BUTTON_CLICK, maClickHdl, this ); 155 } 156 157 // ----------------------------------------------------------------------- 158 159 XubString Button::GetStandardText( StandardButtonType eButton ) 160 { 161 static struct 162 { 163 sal_uInt32 nResId; 164 const char* pDefText; 165 } aResIdAry[BUTTON_COUNT] = 166 { 167 { SV_BUTTONTEXT_OK, "~OK" }, 168 { SV_BUTTONTEXT_CANCEL, "~Cancel" }, 169 { SV_BUTTONTEXT_YES, "~Yes" }, 170 { SV_BUTTONTEXT_NO, "~No" }, 171 { SV_BUTTONTEXT_RETRY, "~Retry" }, 172 { SV_BUTTONTEXT_HELP, "~Help" }, 173 { SV_BUTTONTEXT_CLOSE, "~Close" }, 174 { SV_BUTTONTEXT_MORE, "~More" }, 175 { SV_BUTTONTEXT_IGNORE, "~Ignore" }, 176 { SV_BUTTONTEXT_ABORT, "~Abort" }, 177 { SV_BUTTONTEXT_LESS, "~Less" } 178 }; 179 180 String aText; 181 ResMgr* pResMgr = ImplGetResMgr(); 182 if( pResMgr ) 183 { 184 ResId aResId( aResIdAry[(sal_uInt16)eButton].nResId, *pResMgr ); 185 aText = String( aResId ); 186 } 187 else 188 { 189 ByteString aT( aResIdAry[(sal_uInt16)eButton].pDefText ); 190 aText = String( aT, RTL_TEXTENCODING_ASCII_US ); 191 } 192 return aText; 193 } 194 195 // ----------------------------------------------------------------------- 196 197 XubString Button::GetStandardHelpText( StandardButtonType /* eButton */ ) 198 { 199 XubString aHelpText; 200 return aHelpText; 201 } 202 // ----------------------------------------------------------------------- 203 sal_Bool Button::SetModeImage( const Image& rImage, BmpColorMode eMode ) 204 { 205 if( eMode == BMP_COLOR_NORMAL ) 206 { 207 if ( rImage != mpButtonData->maImage ) 208 { 209 delete mpButtonData->mpBitmapEx; 210 211 mpButtonData->mpBitmapEx = NULL; 212 mpButtonData->maImage = rImage; 213 214 StateChanged( STATE_CHANGE_DATA ); 215 } 216 } 217 else if( eMode == BMP_COLOR_HIGHCONTRAST ) 218 { 219 if( rImage != mpButtonData->maImageHC ) 220 { 221 delete mpButtonData->mpBitmapExHC; 222 223 mpButtonData->mpBitmapExHC = NULL; 224 mpButtonData->maImageHC = rImage; 225 226 StateChanged( STATE_CHANGE_DATA ); 227 } 228 } 229 else 230 return sal_False; 231 232 return sal_True; 233 } 234 235 // ----------------------------------------------------------------------- 236 const Image Button::GetModeImage( BmpColorMode eMode ) const 237 { 238 if( eMode == BMP_COLOR_NORMAL ) 239 { 240 return mpButtonData->maImage; 241 } 242 else if( eMode == BMP_COLOR_HIGHCONTRAST ) 243 { 244 return mpButtonData->maImageHC; 245 } 246 else 247 return Image(); 248 } 249 250 // ----------------------------------------------------------------------- 251 sal_Bool Button::HasImage() const 252 { 253 return !!(mpButtonData->maImage); 254 } 255 256 // ----------------------------------------------------------------------- 257 void Button::SetImageAlign( ImageAlign eAlign ) 258 { 259 if ( mpButtonData->meImageAlign != eAlign ) 260 { 261 mpButtonData->meImageAlign = eAlign; 262 StateChanged( STATE_CHANGE_DATA ); 263 } 264 } 265 266 // ----------------------------------------------------------------------- 267 ImageAlign Button::GetImageAlign() const 268 { 269 return mpButtonData->meImageAlign; 270 } 271 272 // ----------------------------------------------------------------------- 273 sal_Bool Button::SetModeBitmap( const BitmapEx& rBitmap, BmpColorMode eMode ) 274 { 275 if ( SetModeImage( rBitmap, eMode ) ) 276 { 277 if( eMode == BMP_COLOR_NORMAL ) 278 { 279 if ( !mpButtonData->mpBitmapEx ) 280 mpButtonData->mpBitmapEx = new BitmapEx( rBitmap ); 281 } 282 else if ( eMode == BMP_COLOR_HIGHCONTRAST ) 283 { 284 if ( !mpButtonData->mpBitmapExHC ) 285 mpButtonData->mpBitmapExHC = new BitmapEx( rBitmap ); 286 } 287 else 288 return sal_False; 289 290 return sal_True; 291 } 292 return sal_False; 293 } 294 295 // ----------------------------------------------------------------------- 296 BitmapEx Button::GetModeBitmap( BmpColorMode eMode ) const 297 { 298 BitmapEx aBmp; 299 300 if ( eMode == BMP_COLOR_NORMAL ) 301 { 302 if ( mpButtonData->mpBitmapEx ) 303 aBmp = *( mpButtonData->mpBitmapEx ); 304 } 305 else if ( eMode == BMP_COLOR_HIGHCONTRAST ) 306 { 307 if ( mpButtonData->mpBitmapExHC ) 308 aBmp = *( mpButtonData->mpBitmapExHC ); 309 } 310 311 return aBmp; 312 } 313 314 // ----------------------------------------------------------------------- 315 void Button::SetFocusRect( const Rectangle& rFocusRect ) 316 { 317 ImplSetFocusRect( rFocusRect ); 318 } 319 320 // ----------------------------------------------------------------------- 321 const Rectangle& Button::GetFocusRect() const 322 { 323 return ImplGetFocusRect(); 324 } 325 326 // ----------------------------------------------------------------------- 327 328 const Rectangle& Button::ImplGetSymbolRect() const 329 { 330 return mpButtonData->maSymbolRect; 331 } 332 333 void Button::ImplSetSymbolRect( const Rectangle& i_rRect ) 334 { 335 mpButtonData->maSymbolRect = i_rRect; 336 } 337 338 // ----------------------------------------------------------------------- 339 340 sal_uInt16 Button::ImplGetTextStyle( XubString& rText, WinBits nWinStyle, 341 sal_uLong nDrawFlags ) 342 { 343 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 344 sal_uInt16 nTextStyle = FixedText::ImplGetTextStyle( nWinStyle & ~WB_DEFBUTTON ); 345 346 if ( nDrawFlags & WINDOW_DRAW_NOMNEMONIC ) 347 { 348 if ( nTextStyle & TEXT_DRAW_MNEMONIC ) 349 { 350 rText = GetNonMnemonicString( rText ); 351 nTextStyle &= ~TEXT_DRAW_MNEMONIC; 352 } 353 } 354 355 if ( !(nDrawFlags & WINDOW_DRAW_NODISABLE) ) 356 { 357 if ( !IsEnabled() ) 358 nTextStyle |= TEXT_DRAW_DISABLE; 359 } 360 361 if ( (nDrawFlags & WINDOW_DRAW_MONO) || 362 (rStyleSettings.GetOptions() & STYLE_OPTION_MONO) ) 363 nTextStyle |= TEXT_DRAW_MONO; 364 365 return nTextStyle; 366 } 367 368 // ----------------------------------------------------------------------- 369 370 void Button::ImplDrawAlignedImage( OutputDevice* pDev, Point& rPos, 371 Size& rSize, sal_Bool bLayout, 372 sal_uLong nImageSep, sal_uLong nDrawFlags, 373 sal_uInt16 nTextStyle, Rectangle *pSymbolRect, 374 bool bAddImageSep ) 375 { 376 XubString aText( GetText() ); 377 sal_Bool bDrawImage = HasImage() && ! ( ImplGetButtonState() & BUTTON_DRAW_NOIMAGE ); 378 sal_Bool bDrawText = aText.Len() && ! ( ImplGetButtonState() & BUTTON_DRAW_NOTEXT ); 379 sal_Bool bHasSymbol = pSymbolRect ? sal_True : sal_False; 380 381 // No text and no image => nothing to do => return 382 if ( !bDrawImage && !bDrawText && !bHasSymbol ) 383 return; 384 385 WinBits nWinStyle = GetStyle(); 386 Rectangle aOutRect( rPos, rSize ); 387 MetricVector *pVector = bLayout ? &mpControlData->mpLayoutData->m_aUnicodeBoundRects : NULL; 388 String *pDisplayText = bLayout ? &mpControlData->mpLayoutData->m_aDisplayText : NULL; 389 ImageAlign eImageAlign = mpButtonData->meImageAlign; 390 Size aImageSize = mpButtonData->maImage.GetSizePixel(); 391 392 if ( ( nDrawFlags & WINDOW_DRAW_NOMNEMONIC ) && 393 ( nTextStyle & TEXT_DRAW_MNEMONIC ) ) 394 { 395 aText = GetNonMnemonicString( aText ); 396 nTextStyle &= ~TEXT_DRAW_MNEMONIC; 397 } 398 399 aImageSize.Width() = CalcZoom( aImageSize.Width() ); 400 aImageSize.Height() = CalcZoom( aImageSize.Height() ); 401 402 // Drawing text or symbol only is simple, use style and output rectangle 403 if ( bHasSymbol && !bDrawImage && !bDrawText ) 404 { 405 *pSymbolRect = aOutRect; 406 return; 407 } 408 else if ( bDrawText && !bDrawImage && !bHasSymbol ) 409 { 410 DrawControlText( *pDev, aOutRect, aText, nTextStyle, pVector, pDisplayText ); 411 412 ImplSetFocusRect( aOutRect ); 413 rSize = aOutRect.GetSize(); 414 rPos = aOutRect.TopLeft(); 415 416 return; 417 } 418 419 // check for HC mode ( image only! ) 420 Image *pImage = &(mpButtonData->maImage); 421 BitmapEx *pBitmapEx = mpButtonData->mpBitmapEx; 422 423 if( !!(mpButtonData->maImageHC) ) 424 { 425 if( GetSettings().GetStyleSettings().GetHighContrastMode() ) 426 { 427 pImage = &(mpButtonData->maImageHC); 428 pBitmapEx = mpButtonData->mpBitmapExHC; 429 } 430 } 431 432 if ( pBitmapEx && ( pDev->GetOutDevType() == OUTDEV_PRINTER ) ) 433 { 434 // Die Groesse richtet sich nach dem Bildschirm, soll auf 435 // dem Drucker genau so aussehen... 436 MapMode aMap100thMM( MAP_100TH_MM ); 437 aImageSize = PixelToLogic( aImageSize, aMap100thMM ); 438 aImageSize = pDev->LogicToPixel( aImageSize, aMap100thMM ); 439 } 440 441 Size aTextSize; 442 Size aSymbolSize; 443 Size aMax; 444 Point aImagePos = rPos; 445 Point aTextPos = rPos; 446 Rectangle aUnion = Rectangle( aImagePos, aImageSize ); 447 Rectangle aSymbol; 448 long nSymbolHeight = 0; 449 450 if ( bDrawText || bHasSymbol ) 451 { 452 // Get the size of the text output area ( the symbol will be drawn in 453 // this area as well, so the symbol rectangle will be calculated here, too ) 454 455 Rectangle aRect = Rectangle( Point(), rSize ); 456 Size aTSSize; 457 458 if ( bHasSymbol ) 459 { 460 if ( bDrawText ) 461 { 462 nSymbolHeight = pDev->GetTextHeight(); 463 if ( mpButtonData->mbSmallSymbol ) 464 nSymbolHeight = nSymbolHeight * 3 / 4; 465 466 aSymbol = Rectangle( Point(), Size( nSymbolHeight, nSymbolHeight ) ); 467 ImplCalcSymbolRect( aSymbol ); 468 aRect.Left() += 3 * nSymbolHeight / 2; 469 aTSSize.Width() = 3 * nSymbolHeight / 2; 470 } 471 else 472 { 473 aSymbol = Rectangle( Point(), rSize ); 474 ImplCalcSymbolRect( aSymbol ); 475 aTSSize.Width() = aSymbol.GetWidth(); 476 } 477 aTSSize.Height() = aSymbol.GetHeight(); 478 aSymbolSize = aSymbol.GetSize(); 479 } 480 481 if ( bDrawText ) 482 { 483 if ( ( eImageAlign == IMAGEALIGN_LEFT_TOP ) || 484 ( eImageAlign == IMAGEALIGN_LEFT ) || 485 ( eImageAlign == IMAGEALIGN_LEFT_BOTTOM ) || 486 ( eImageAlign == IMAGEALIGN_RIGHT_TOP ) || 487 ( eImageAlign == IMAGEALIGN_RIGHT ) || 488 ( eImageAlign == IMAGEALIGN_RIGHT_BOTTOM ) ) 489 { 490 aRect.Right() -= ( aImageSize.Width() + nImageSep ); 491 } 492 else if ( ( eImageAlign == IMAGEALIGN_TOP_LEFT ) || 493 ( eImageAlign == IMAGEALIGN_TOP ) || 494 ( eImageAlign == IMAGEALIGN_TOP_RIGHT ) || 495 ( eImageAlign == IMAGEALIGN_BOTTOM_LEFT ) || 496 ( eImageAlign == IMAGEALIGN_BOTTOM ) || 497 ( eImageAlign == IMAGEALIGN_BOTTOM_RIGHT ) ) 498 { 499 aRect.Bottom() -= ( aImageSize.Height() + nImageSep ); 500 } 501 502 aRect = pDev->GetTextRect( aRect, aText, nTextStyle ); 503 aTextSize = aRect.GetSize(); 504 505 aTSSize.Width() += aTextSize.Width(); 506 507 if ( aTSSize.Height() < aTextSize.Height() ) 508 aTSSize.Height() = aTextSize.Height(); 509 510 if( bAddImageSep && bDrawImage ) 511 { 512 long nDiff = (aImageSize.Height() - aTextSize.Height()) / 3; 513 if( nDiff > 0 ) 514 nImageSep += nDiff; 515 } 516 } 517 518 aMax.Width() = aTSSize.Width() > aImageSize.Width() ? aTSSize.Width() : aImageSize.Width(); 519 aMax.Height() = aTSSize.Height() > aImageSize.Height() ? aTSSize.Height() : aImageSize.Height(); 520 521 // Now calculate the output area for the image and the text acording to the image align flags 522 523 if ( ( eImageAlign == IMAGEALIGN_LEFT ) || 524 ( eImageAlign == IMAGEALIGN_RIGHT ) ) 525 { 526 aImagePos.Y() = rPos.Y() + ( aMax.Height() - aImageSize.Height() ) / 2; 527 aTextPos.Y() = rPos.Y() + ( aMax.Height() - aTSSize.Height() ) / 2; 528 } 529 else if ( ( eImageAlign == IMAGEALIGN_LEFT_BOTTOM ) || 530 ( eImageAlign == IMAGEALIGN_RIGHT_BOTTOM ) ) 531 { 532 aImagePos.Y() = rPos.Y() + aMax.Height() - aImageSize.Height(); 533 aTextPos.Y() = rPos.Y() + aMax.Height() - aTSSize.Height(); 534 } 535 else if ( ( eImageAlign == IMAGEALIGN_TOP ) || 536 ( eImageAlign == IMAGEALIGN_BOTTOM ) ) 537 { 538 aImagePos.X() = rPos.X() + ( aMax.Width() - aImageSize.Width() ) / 2; 539 aTextPos.X() = rPos.X() + ( aMax.Width() - aTSSize.Width() ) / 2; 540 } 541 else if ( ( eImageAlign == IMAGEALIGN_TOP_RIGHT ) || 542 ( eImageAlign == IMAGEALIGN_BOTTOM_RIGHT ) ) 543 { 544 aImagePos.X() = rPos.X() + aMax.Width() - aImageSize.Width(); 545 aTextPos.X() = rPos.X() + aMax.Width() - aTSSize.Width(); 546 } 547 548 if ( ( eImageAlign == IMAGEALIGN_LEFT_TOP ) || 549 ( eImageAlign == IMAGEALIGN_LEFT ) || 550 ( eImageAlign == IMAGEALIGN_LEFT_BOTTOM ) ) 551 { 552 aTextPos.X() = rPos.X() + aImageSize.Width() + nImageSep; 553 } 554 else if ( ( eImageAlign == IMAGEALIGN_RIGHT_TOP ) || 555 ( eImageAlign == IMAGEALIGN_RIGHT ) || 556 ( eImageAlign == IMAGEALIGN_RIGHT_BOTTOM ) ) 557 { 558 aImagePos.X() = rPos.X() + aTSSize.Width() + nImageSep; 559 } 560 else if ( ( eImageAlign == IMAGEALIGN_TOP_LEFT ) || 561 ( eImageAlign == IMAGEALIGN_TOP ) || 562 ( eImageAlign == IMAGEALIGN_TOP_RIGHT ) ) 563 { 564 aTextPos.Y() = rPos.Y() + aImageSize.Height() + nImageSep; 565 } 566 else if ( ( eImageAlign == IMAGEALIGN_BOTTOM_LEFT ) || 567 ( eImageAlign == IMAGEALIGN_BOTTOM ) || 568 ( eImageAlign == IMAGEALIGN_BOTTOM_RIGHT ) ) 569 { 570 aImagePos.Y() = rPos.Y() + aTSSize.Height() + nImageSep; 571 } 572 else if ( eImageAlign == IMAGEALIGN_CENTER ) 573 { 574 aImagePos.X() = rPos.X() + ( aMax.Width() - aImageSize.Width() ) / 2; 575 aImagePos.Y() = rPos.Y() + ( aMax.Height() - aImageSize.Height() ) / 2; 576 aTextPos.X() = rPos.X() + ( aMax.Width() - aTSSize.Width() ) / 2; 577 aTextPos.Y() = rPos.Y() + ( aMax.Height() - aTSSize.Height() ) / 2; 578 } 579 aUnion = Rectangle( aImagePos, aImageSize ); 580 aUnion.Union( Rectangle( aTextPos, aTSSize ) ); 581 } 582 583 // Now place the combination of text and image in the output area of the button 584 // according to the window style (WinBits) 585 long nXOffset = 0; 586 long nYOffset = 0; 587 588 if ( nWinStyle & WB_CENTER ) 589 { 590 nXOffset = ( rSize.Width() - aUnion.GetWidth() ) / 2; 591 } 592 else if ( nWinStyle & WB_RIGHT ) 593 { 594 nXOffset = rSize.Width() - aUnion.GetWidth(); 595 } 596 597 if ( nWinStyle & WB_VCENTER ) 598 { 599 nYOffset = ( rSize.Height() - aUnion.GetHeight() ) / 2; 600 } 601 else if ( nWinStyle & WB_BOTTOM ) 602 { 603 nYOffset = rSize.Height() - aUnion.GetHeight(); 604 } 605 606 // the top left corner should always be visible, so we don't allow negative offsets 607 if ( nXOffset < 0 ) nXOffset = 0; 608 if ( nYOffset < 0 ) nYOffset = 0; 609 610 aImagePos.X() += nXOffset; 611 aImagePos.Y() += nYOffset; 612 aTextPos.X() += nXOffset; 613 aTextPos.Y() += nYOffset; 614 615 // set rPos and rSize to the union 616 rSize = aUnion.GetSize(); 617 rPos.X() += nXOffset; 618 rPos.Y() += nYOffset; 619 620 if ( bHasSymbol ) 621 { 622 if ( mpButtonData->meSymbolAlign == SYMBOLALIGN_RIGHT ) 623 { 624 Point aRightPos = Point( aTextPos.X() + aTextSize.Width() + aSymbolSize.Width()/2, aTextPos.Y() ); 625 *pSymbolRect = Rectangle( aRightPos, aSymbolSize ); 626 } 627 else 628 { 629 *pSymbolRect = Rectangle( aTextPos, aSymbolSize ); 630 aTextPos.X() += ( 3 * nSymbolHeight / 2 ); 631 } 632 if ( mpButtonData->mbSmallSymbol ) 633 { 634 nYOffset = (aUnion.GetHeight() - aSymbolSize.Height())/2; 635 pSymbolRect->setY( aTextPos.Y() + nYOffset ); 636 } 637 } 638 639 sal_uInt16 nStyle = 0; 640 641 if ( ! ( nDrawFlags & WINDOW_DRAW_NODISABLE ) && 642 ! IsEnabled() ) 643 nStyle |= IMAGE_DRAW_DISABLE; 644 645 if ( pBitmapEx && ( pDev->GetOutDevType() == OUTDEV_PRINTER ) ) 646 { 647 // Fuer die BitmapEx ueberlegt sich KA noch, wie man die disablete 648 // Darstellung hinbekommt... 649 pBitmapEx->Draw( pDev, aImagePos, aImageSize /*, nStyle*/ ); 650 } 651 else 652 { 653 if ( IsZoom() ) 654 pDev->DrawImage( aImagePos, aImageSize, *pImage, nStyle ); 655 else 656 pDev->DrawImage( aImagePos, *pImage, nStyle ); 657 } 658 659 if ( bDrawText ) 660 { 661 ImplSetFocusRect( Rectangle( aTextPos, aTextSize ) ); 662 pDev->DrawText( Rectangle( aTextPos, aTextSize ), aText, nTextStyle, pVector, pDisplayText ); 663 } 664 else 665 { 666 ImplSetFocusRect( Rectangle( aImagePos, aImageSize ) ); 667 } 668 } 669 670 // ----------------------------------------------------------------------- 671 void Button::ImplSetFocusRect( const Rectangle &rFocusRect ) 672 { 673 Rectangle aFocusRect = rFocusRect; 674 Rectangle aOutputRect = Rectangle( Point(), GetOutputSizePixel() ); 675 676 if ( ! aFocusRect.IsEmpty() ) 677 { 678 aFocusRect.Left()--; 679 aFocusRect.Top()--; 680 aFocusRect.Right()++; 681 aFocusRect.Bottom()++; 682 } 683 684 if ( aFocusRect.Left() < aOutputRect.Left() ) aFocusRect.Left() = aOutputRect.Left(); 685 if ( aFocusRect.Top() < aOutputRect.Top() ) aFocusRect.Top() = aOutputRect.Top(); 686 if ( aFocusRect.Right() > aOutputRect.Right() ) aFocusRect.Right() = aOutputRect.Right(); 687 if ( aFocusRect.Bottom() > aOutputRect.Bottom() ) aFocusRect.Bottom() = aOutputRect.Bottom(); 688 689 mpButtonData->maFocusRect = aFocusRect; 690 } 691 692 // ----------------------------------------------------------------------- 693 const Rectangle& Button::ImplGetFocusRect() const 694 { 695 return mpButtonData->maFocusRect; 696 } 697 698 // ----------------------------------------------------------------------- 699 sal_uInt16& Button::ImplGetButtonState() 700 { 701 return mpButtonData->mnButtonState; 702 } 703 704 // ----------------------------------------------------------------------- 705 sal_uInt16 Button::ImplGetButtonState() const 706 { 707 return mpButtonData->mnButtonState; 708 } 709 710 // ----------------------------------------------------------------------- 711 void Button::ImplSetSymbolAlign( SymbolAlign eAlign ) 712 { 713 if ( mpButtonData->meSymbolAlign != eAlign ) 714 { 715 mpButtonData->meSymbolAlign = eAlign; 716 StateChanged( STATE_CHANGE_DATA ); 717 } 718 } 719 720 // ----------------------------------------------------------------------- 721 SymbolAlign Button::ImplGetSymbolAlign() const 722 { 723 return mpButtonData->meSymbolAlign; 724 } 725 // ----------------------------------------------------------------------- 726 void Button::ImplSetSmallSymbol( sal_Bool bSmall ) 727 { 728 mpButtonData->mbSmallSymbol = bSmall; 729 } 730 731 // ----------------------------------------------------------------------- 732 void Button::EnableImageDisplay( sal_Bool bEnable ) 733 { 734 if( bEnable ) 735 mpButtonData->mnButtonState &= ~BUTTON_DRAW_NOIMAGE; 736 else 737 mpButtonData->mnButtonState |= BUTTON_DRAW_NOIMAGE; 738 } 739 740 // ----------------------------------------------------------------------- 741 sal_Bool Button::IsImageDisplayEnabled() 742 { 743 return (mpButtonData->mnButtonState & BUTTON_DRAW_NOIMAGE) == 0; 744 } 745 746 // ----------------------------------------------------------------------- 747 void Button::EnableTextDisplay( sal_Bool bEnable ) 748 { 749 if( bEnable ) 750 mpButtonData->mnButtonState &= ~BUTTON_DRAW_NOTEXT; 751 else 752 mpButtonData->mnButtonState |= BUTTON_DRAW_NOTEXT; 753 } 754 755 // ----------------------------------------------------------------------- 756 sal_Bool Button::IsTextDisplayEnabled() 757 { 758 return (mpButtonData->mnButtonState & BUTTON_DRAW_NOTEXT) == 0; 759 } 760 761 // ----------------------------------------------------------------------- 762 void Button::SetSmallSymbol (bool small) 763 { 764 ImplSetSmallSymbol (small); 765 } 766 767 bool Button::IsSmallSymbol () const 768 { 769 return mpButtonData->mbSmallSymbol; 770 } 771 772 // ======================================================================= 773 774 void PushButton::ImplInitPushButtonData() 775 { 776 mpWindowImpl->mbPushButton = sal_True; 777 778 meSymbol = SYMBOL_NOSYMBOL; 779 meState = STATE_NOCHECK; 780 meSaveValue = STATE_NOCHECK; 781 mnDDStyle = 0; 782 mbPressed = sal_False; 783 mbInUserDraw = sal_False; 784 } 785 786 // ----------------------------------------------------------------------- 787 788 void PushButton::ImplInit( Window* pParent, WinBits nStyle ) 789 { 790 nStyle = ImplInitStyle( pParent->GetWindow( WINDOW_LASTCHILD ), nStyle ); 791 Button::ImplInit( pParent, nStyle, NULL ); 792 793 if ( nStyle & WB_NOLIGHTBORDER ) 794 ImplGetButtonState() |= BUTTON_DRAW_NOLIGHTBORDER; 795 796 ImplInitSettings( sal_True, sal_True, sal_True ); 797 } 798 799 // ----------------------------------------------------------------------- 800 801 WinBits PushButton::ImplInitStyle( const Window* pPrevWindow, WinBits nStyle ) 802 { 803 if ( !(nStyle & WB_NOTABSTOP) ) 804 nStyle |= WB_TABSTOP; 805 806 // if no alignment is given, default to "vertically centered". This is because since 807 // #i26046#, we respect the vertical alignment flags (previously we didn't completely), 808 // but we of course want to look as before when no vertical alignment is specified 809 if ( ( nStyle & ( WB_TOP | WB_VCENTER | WB_BOTTOM ) ) == 0 ) 810 nStyle |= WB_VCENTER; 811 812 if ( !(nStyle & WB_NOGROUP) && 813 (!pPrevWindow || 814 ((pPrevWindow->GetType() != WINDOW_PUSHBUTTON) && 815 (pPrevWindow->GetType() != WINDOW_OKBUTTON) && 816 (pPrevWindow->GetType() != WINDOW_CANCELBUTTON) && 817 (pPrevWindow->GetType() != WINDOW_HELPBUTTON)) ) ) 818 nStyle |= WB_GROUP; 819 return nStyle; 820 } 821 822 // ----------------------------------------------------------------- 823 824 const Font& PushButton::GetCanonicalFont( const StyleSettings& _rStyle ) const 825 { 826 return _rStyle.GetPushButtonFont(); 827 } 828 829 // ----------------------------------------------------------------- 830 const Color& PushButton::GetCanonicalTextColor( const StyleSettings& _rStyle ) const 831 { 832 return _rStyle.GetButtonTextColor(); 833 } 834 835 // ----------------------------------------------------------------------- 836 837 void PushButton::ImplInitSettings( sal_Bool bFont, 838 sal_Bool bForeground, sal_Bool bBackground ) 839 { 840 Button::ImplInitSettings( bFont, bForeground ); 841 842 if ( bBackground ) 843 { 844 SetBackground(); 845 // #i38498#: do not check for GetParent()->IsChildTransparentModeEnabled() 846 // otherwise the formcontrol button will be overdrawn due to PARENTCLIPMODE_NOCLIP 847 // for radio and checkbox this is ok as they shoud appear transparent in documents 848 if ( IsNativeControlSupported( CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL ) || 849 (GetStyle() & WB_FLATBUTTON) != 0 ) 850 { 851 EnableChildTransparentMode( sal_True ); 852 SetParentClipMode( PARENTCLIPMODE_NOCLIP ); 853 SetPaintTransparent( sal_True ); 854 mpWindowImpl->mbUseNativeFocus = (GetStyle() & WB_FLATBUTTON) 855 ? false 856 : ImplGetSVData()->maNWFData.mbNoFocusRects; 857 } 858 else 859 { 860 EnableChildTransparentMode( sal_False ); 861 SetParentClipMode( 0 ); 862 SetPaintTransparent( sal_False ); 863 } 864 } 865 } 866 867 // ----------------------------------------------------------------------- 868 869 void PushButton::ImplDrawPushButtonFrame( Window* pDev, 870 Rectangle& rRect, sal_uInt16 nStyle ) 871 { 872 if ( !(pDev->GetStyle() & (WB_RECTSTYLE | WB_SMALLSTYLE)) ) 873 { 874 StyleSettings aStyleSettings = pDev->GetSettings().GetStyleSettings(); 875 if ( pDev->IsControlBackground() ) 876 aStyleSettings.Set3DColors( pDev->GetControlBackground() ); 877 } 878 879 DecorationView aDecoView( pDev ); 880 if ( pDev->IsControlBackground() ) 881 { 882 AllSettings aSettings = pDev->GetSettings(); 883 AllSettings aOldSettings = aSettings; 884 StyleSettings aStyleSettings = aSettings.GetStyleSettings(); 885 aStyleSettings.Set3DColors( pDev->GetControlBackground() ); 886 aSettings.SetStyleSettings( aStyleSettings ); 887 pDev->OutputDevice::SetSettings( aSettings ); 888 rRect = aDecoView.DrawButton( rRect, nStyle ); 889 pDev->OutputDevice::SetSettings( aOldSettings ); 890 } 891 else 892 rRect = aDecoView.DrawButton( rRect, nStyle ); 893 } 894 895 // ----------------------------------------------------------------------- 896 897 sal_Bool PushButton::ImplHitTestPushButton( Window* pDev, 898 const Point& rPos ) 899 { 900 Point aTempPoint; 901 Rectangle aTestRect( aTempPoint, pDev->GetOutputSizePixel() ); 902 903 return aTestRect.IsInside( rPos ); 904 } 905 906 // ----------------------------------------------------------------------- 907 908 sal_uInt16 PushButton::ImplGetTextStyle( sal_uLong nDrawFlags ) const 909 { 910 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 911 912 sal_uInt16 nTextStyle = TEXT_DRAW_MNEMONIC | TEXT_DRAW_MULTILINE | TEXT_DRAW_ENDELLIPSIS; 913 914 if ( ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO ) || 915 ( nDrawFlags & WINDOW_DRAW_MONO ) ) 916 nTextStyle |= TEXT_DRAW_MONO; 917 918 if ( GetStyle() & WB_WORDBREAK ) 919 nTextStyle |= TEXT_DRAW_WORDBREAK; 920 if ( GetStyle() & WB_NOLABEL ) 921 nTextStyle &= ~TEXT_DRAW_MNEMONIC; 922 923 if ( GetStyle() & WB_LEFT ) 924 nTextStyle |= TEXT_DRAW_LEFT; 925 else if ( GetStyle() & WB_RIGHT ) 926 nTextStyle |= TEXT_DRAW_RIGHT; 927 else 928 nTextStyle |= TEXT_DRAW_CENTER; 929 930 if ( GetStyle() & WB_TOP ) 931 nTextStyle |= TEXT_DRAW_TOP; 932 else if ( GetStyle() & WB_BOTTOM ) 933 nTextStyle |= TEXT_DRAW_BOTTOM; 934 else 935 nTextStyle |= TEXT_DRAW_VCENTER; 936 937 if ( ! ( (nDrawFlags & WINDOW_DRAW_NODISABLE) || IsEnabled() ) ) 938 nTextStyle |= TEXT_DRAW_DISABLE; 939 940 return nTextStyle; 941 } 942 943 // ----------------------------------------------------------------------- 944 945 static void ImplDrawBtnDropDownArrow( OutputDevice* pDev, 946 long nX, long nY, 947 Color& rColor, sal_Bool bBlack ) 948 { 949 Color aOldLineColor = pDev->GetLineColor(); 950 Color aOldFillColor = pDev->GetFillColor(); 951 952 pDev->SetLineColor(); 953 if ( bBlack ) 954 pDev->SetFillColor( Color( COL_BLACK ) ); 955 else 956 pDev->SetFillColor( rColor ); 957 pDev->DrawRect( Rectangle( nX+0, nY+0, nX+6, nY+0 ) ); 958 pDev->DrawRect( Rectangle( nX+1, nY+1, nX+5, nY+1 ) ); 959 pDev->DrawRect( Rectangle( nX+2, nY+2, nX+4, nY+2 ) ); 960 pDev->DrawRect( Rectangle( nX+3, nY+3, nX+3, nY+3 ) ); 961 if ( bBlack ) 962 { 963 pDev->SetFillColor( rColor ); 964 pDev->DrawRect( Rectangle( nX+2, nY+1, nX+4, nY+1 ) ); 965 pDev->DrawRect( Rectangle( nX+3, nY+2, nX+3, nY+2 ) ); 966 } 967 pDev->SetLineColor( aOldLineColor ); 968 pDev->SetFillColor( aOldFillColor ); 969 } 970 971 // ----------------------------------------------------------------------- 972 973 void PushButton::ImplDrawPushButtonContent( OutputDevice* pDev, sal_uLong nDrawFlags, 974 const Rectangle& rRect, 975 bool bLayout, 976 bool bMenuBtnSep 977 ) 978 { 979 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 980 Rectangle aInRect = rRect; 981 Color aColor; 982 XubString aText = PushButton::GetText(); // PushButton:: wegen MoreButton 983 sal_uInt16 nTextStyle = ImplGetTextStyle( nDrawFlags ); 984 sal_uInt16 nStyle; 985 986 if( aInRect.nRight < aInRect.nLeft || aInRect.nBottom < aInRect.nTop ) 987 aInRect.SetEmpty(); 988 989 pDev->Push( PUSH_CLIPREGION ); 990 pDev->IntersectClipRegion( aInRect ); 991 992 if ( nDrawFlags & WINDOW_DRAW_MONO ) 993 aColor = Color( COL_BLACK ); 994 else if ( IsControlForeground() ) 995 aColor = GetControlForeground(); 996 else if( nDrawFlags & WINDOW_DRAW_ROLLOVER ) 997 aColor = rStyleSettings.GetButtonRolloverTextColor(); 998 else 999 aColor = rStyleSettings.GetButtonTextColor(); 1000 1001 pDev->SetTextColor( aColor ); 1002 1003 if ( IsEnabled() || (nDrawFlags & WINDOW_DRAW_NODISABLE) ) 1004 nStyle = 0; 1005 else 1006 nStyle = SYMBOL_DRAW_DISABLE; 1007 1008 Size aSize = rRect.GetSize(); 1009 Point aPos = rRect.TopLeft(); 1010 1011 sal_uLong nImageSep = 1 + (pDev->GetTextHeight()-10)/2; 1012 if( nImageSep < 1 ) 1013 nImageSep = 1; 1014 if ( mnDDStyle == PUSHBUTTON_DROPDOWN_MENUBUTTON ) 1015 { 1016 if ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) ) 1017 { 1018 // calc Symbol- and Textrect 1019 long nSymbolSize = pDev->GetTextHeight() / 2 + 1; 1020 aInRect.Right() -= 5; 1021 aInRect.Left() = aInRect.Right() - nSymbolSize; 1022 aSize.Width() -= ( 5 + nSymbolSize ); 1023 1024 ImplDrawAlignedImage( pDev, aPos, aSize, bLayout, nImageSep, 1025 nDrawFlags, nTextStyle, NULL, true ); 1026 } 1027 else 1028 ImplCalcSymbolRect( aInRect ); 1029 1030 if( ! bLayout ) 1031 { 1032 long nDistance = (aInRect.GetHeight() > 10) ? 2 : 1; 1033 DecorationView aDecoView( pDev ); 1034 if( bMenuBtnSep ) 1035 { 1036 long nX = aInRect.Left() - 2*nDistance;; 1037 Point aStartPt( nX, aInRect.Top()+nDistance ); 1038 Point aEndPt( nX, aInRect.Bottom()-nDistance ); 1039 aDecoView.DrawSeparator( aStartPt, aEndPt ); 1040 } 1041 aDecoView.DrawSymbol( aInRect, SYMBOL_SPIN_DOWN, aColor, nStyle ); 1042 aInRect.Left() -= 2*nDistance; 1043 ImplSetSymbolRect( aInRect ); 1044 } 1045 } 1046 else 1047 { 1048 Rectangle aSymbolRect; 1049 // FIXME: (GetStyle() & WB_FLATBUTTON) != 0 is preliminary 1050 // in the next major this should be replaced by "true" 1051 ImplDrawAlignedImage( pDev, aPos, aSize, bLayout, nImageSep, nDrawFlags, 1052 nTextStyle, IsSymbol() ? &aSymbolRect : NULL, true ); 1053 1054 if ( IsSymbol() && ! bLayout ) 1055 { 1056 DecorationView aDecoView( pDev ); 1057 aDecoView.DrawSymbol( aSymbolRect, meSymbol, aColor, nStyle ); 1058 ImplSetSymbolRect( aSymbolRect ); 1059 } 1060 1061 if ( mnDDStyle == PUSHBUTTON_DROPDOWN_TOOLBOX && !bLayout ) 1062 { 1063 sal_Bool bBlack = sal_False; 1064 Color aArrowColor( COL_BLACK ); 1065 1066 if ( !(nDrawFlags & WINDOW_DRAW_MONO) ) 1067 { 1068 if ( !IsEnabled() ) 1069 aArrowColor = rStyleSettings.GetShadowColor(); 1070 else 1071 { 1072 aArrowColor = Color( COL_LIGHTGREEN ); 1073 bBlack = sal_True; 1074 } 1075 } 1076 1077 ImplDrawBtnDropDownArrow( pDev, aInRect.Right()-6, aInRect.Top()+1, 1078 aArrowColor, bBlack ); 1079 } 1080 } 1081 1082 UserDrawEvent aUDEvt( this, aInRect, 0 ); 1083 UserDraw( aUDEvt ); 1084 1085 pDev->Pop(); // restore clipregion 1086 } 1087 1088 // ----------------------------------------------------------------------- 1089 1090 void PushButton::UserDraw( const UserDrawEvent& ) 1091 { 1092 } 1093 1094 // ----------------------------------------------------------------------- 1095 1096 void PushButton::ImplDrawPushButton( bool bLayout ) 1097 { 1098 if( !bLayout ) 1099 HideFocus(); 1100 1101 sal_uInt16 nButtonStyle = ImplGetButtonState(); 1102 Point aPoint; 1103 Size aOutSz( GetOutputSizePixel() ); 1104 Rectangle aRect( aPoint, aOutSz ); 1105 Rectangle aInRect = aRect; 1106 Rectangle aTextRect; 1107 sal_Bool bNativeOK = sal_False; 1108 1109 // adjust style if button should be rendered 'pressed' 1110 if ( mbPressed ) 1111 nButtonStyle |= BUTTON_DRAW_PRESSED; 1112 1113 // TODO: move this to Window class or make it a member !!! 1114 ControlType aCtrlType = 0; 1115 switch( GetParent()->GetType() ) 1116 { 1117 case WINDOW_LISTBOX: 1118 case WINDOW_MULTILISTBOX: 1119 case WINDOW_TREELISTBOX: 1120 aCtrlType = CTRL_LISTBOX; 1121 break; 1122 1123 case WINDOW_COMBOBOX: 1124 case WINDOW_PATTERNBOX: 1125 case WINDOW_NUMERICBOX: 1126 case WINDOW_METRICBOX: 1127 case WINDOW_CURRENCYBOX: 1128 case WINDOW_DATEBOX: 1129 case WINDOW_TIMEBOX: 1130 case WINDOW_LONGCURRENCYBOX: 1131 aCtrlType = CTRL_COMBOBOX; 1132 break; 1133 default: 1134 break; 1135 } 1136 1137 sal_Bool bDropDown = ( IsSymbol() && (GetSymbol()==SYMBOL_SPIN_DOWN) && !GetText().Len() ); 1138 1139 if( bDropDown && (aCtrlType == CTRL_COMBOBOX || aCtrlType == CTRL_LISTBOX ) ) 1140 { 1141 if( GetParent()->IsNativeControlSupported( aCtrlType, PART_ENTIRE_CONTROL) ) 1142 { 1143 // skip painting if the button was already drawn by the theme 1144 if( aCtrlType == CTRL_COMBOBOX ) 1145 { 1146 Edit* pEdit = static_cast<Edit*>(GetParent()); 1147 if( pEdit->ImplUseNativeBorder( pEdit->GetStyle() ) ) 1148 bNativeOK = sal_True; 1149 } 1150 else if( GetParent()->IsNativeControlSupported( aCtrlType, HAS_BACKGROUND_TEXTURE) ) 1151 { 1152 bNativeOK = sal_True; 1153 } 1154 if( !bNativeOK && GetParent()->IsNativeControlSupported( aCtrlType, PART_BUTTON_DOWN ) ) 1155 { 1156 // let the theme draw it, note we then need support 1157 // for CTRL_LISTBOX/PART_BUTTON_DOWN and CTRL_COMBOBOX/PART_BUTTON_DOWN 1158 1159 ImplControlValue aControlValue; 1160 ControlState nState = 0; 1161 1162 if ( mbPressed ) nState |= CTRL_STATE_PRESSED; 1163 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) nState |= CTRL_STATE_PRESSED; 1164 if ( HasFocus() ) nState |= CTRL_STATE_FOCUSED; 1165 if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT ) nState |= CTRL_STATE_DEFAULT; 1166 if ( Window::IsEnabled() ) nState |= CTRL_STATE_ENABLED; 1167 1168 if ( IsMouseOver() && aInRect.IsInside( GetPointerPosPixel() ) ) 1169 nState |= CTRL_STATE_ROLLOVER; 1170 1171 bNativeOK = DrawNativeControl( aCtrlType, PART_BUTTON_DOWN, aInRect, nState, 1172 aControlValue, rtl::OUString() ); 1173 } 1174 } 1175 } 1176 1177 if( bNativeOK ) 1178 return; 1179 1180 bool bRollOver = (IsMouseOver() && aInRect.IsInside( GetPointerPosPixel() )); 1181 bool bDrawMenuSep = true; 1182 if( (GetStyle() & WB_FLATBUTTON) ) 1183 { 1184 if( ! bRollOver && ! HasFocus() ) 1185 bDrawMenuSep = false; 1186 } 1187 if ( (bNativeOK=IsNativeControlSupported(CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL)) == sal_True ) 1188 { 1189 PushButtonValue aControlValue; 1190 Rectangle aCtrlRegion( aInRect ); 1191 ControlState nState = 0; 1192 1193 if ( mbPressed || IsChecked() ) nState |= CTRL_STATE_PRESSED; 1194 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) nState |= CTRL_STATE_PRESSED; 1195 if ( HasFocus() ) nState |= CTRL_STATE_FOCUSED; 1196 if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT ) nState |= CTRL_STATE_DEFAULT; 1197 if ( Window::IsEnabled() ) nState |= CTRL_STATE_ENABLED; 1198 1199 if ( bRollOver ) 1200 nState |= CTRL_STATE_ROLLOVER; 1201 1202 if( GetStyle() & WB_BEVELBUTTON ) 1203 aControlValue.mbBevelButton = true; 1204 1205 // draw frame into invisible window to have aInRect modified correctly 1206 // but do not shift the inner rect for pressed buttons (ie remove BUTTON_DRAW_PRESSED) 1207 // this assumes the theme has enough visual cues to signalize the button was pressed 1208 //Window aWin( this ); 1209 //ImplDrawPushButtonFrame( &aWin, aInRect, nButtonStyle & ~BUTTON_DRAW_PRESSED ); 1210 1211 // looks better this way as symbols were displaced slightly using the above approach 1212 aInRect.Top()+=4; 1213 aInRect.Bottom()-=4; 1214 aInRect.Left()+=4; 1215 aInRect.Right()-=4; 1216 1217 // prepare single line hint (needed on mac to decide between normal push button and 1218 // rectangular bevel button look) 1219 Size aFontSize( Application::GetSettings().GetStyleSettings().GetPushButtonFont().GetSize() ); 1220 aFontSize = LogicToPixel( aFontSize, MapMode( MAP_POINT ) ); 1221 Size aInRectSize( LogicToPixel( Size( aInRect.GetWidth(), aInRect.GetHeight() ) ) ); 1222 aControlValue.mbSingleLine = (aInRectSize.Height() < 2 * aFontSize.Height() ); 1223 1224 if( ((nState & CTRL_STATE_ROLLOVER)) || ! (GetStyle() & WB_FLATBUTTON) ) 1225 { 1226 bNativeOK = DrawNativeControl( CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion, nState, 1227 aControlValue, rtl::OUString()/*PushButton::GetText()*/ ); 1228 } 1229 else 1230 { 1231 bNativeOK = true; 1232 } 1233 1234 // draw content using the same aInRect as non-native VCL would do 1235 ImplDrawPushButtonContent( this, 1236 (nState&CTRL_STATE_ROLLOVER) ? WINDOW_DRAW_ROLLOVER : 0, 1237 aInRect, bLayout, bDrawMenuSep ); 1238 1239 if ( HasFocus() ) 1240 ShowFocus( ImplGetFocusRect() ); 1241 } 1242 1243 if ( bNativeOK == sal_False ) 1244 { 1245 // draw PushButtonFrame, aInRect has content size afterwards 1246 if( (GetStyle() & WB_FLATBUTTON) ) 1247 { 1248 Rectangle aTempRect( aInRect ); 1249 if( ! bLayout && bRollOver ) 1250 ImplDrawPushButtonFrame( this, aTempRect, nButtonStyle ); 1251 aInRect.Left() += 2; 1252 aInRect.Top() += 2; 1253 aInRect.Right() -= 2; 1254 aInRect.Bottom() -= 2; 1255 } 1256 else 1257 { 1258 if( ! bLayout ) 1259 ImplDrawPushButtonFrame( this, aInRect, nButtonStyle ); 1260 } 1261 1262 // draw content 1263 ImplDrawPushButtonContent( this, 0, aInRect, bLayout, bDrawMenuSep ); 1264 1265 if( ! bLayout && HasFocus() ) 1266 { 1267 ShowFocus( ImplGetFocusRect() ); 1268 } 1269 } 1270 } 1271 1272 // ----------------------------------------------------------------------- 1273 1274 void PushButton::ImplSetDefButton( sal_Bool bSet ) 1275 { 1276 Size aSize( GetSizePixel() ); 1277 Point aPos( GetPosPixel() ); 1278 int dLeft(0), dRight(0), dTop(0), dBottom(0); 1279 sal_Bool bSetPos = sal_False; 1280 1281 if ( (IsNativeControlSupported(CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL)) == sal_True ) 1282 { 1283 Rectangle aBound, aCont; 1284 Rectangle aCtrlRect( 0, 0, 80, 20 ); // use a constant size to avoid accumulating 1285 // will not work if the theme has dynamic adornment sizes 1286 ImplControlValue aControlValue; 1287 Rectangle aCtrlRegion( aCtrlRect ); 1288 ControlState nState = CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED; 1289 1290 // get native size of a 'default' button 1291 // and adjust the VCL button if more space for adornment is required 1292 if( GetNativeControlRegion( CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion, 1293 nState, aControlValue, rtl::OUString(), 1294 aBound, aCont ) ) 1295 { 1296 dLeft = aCont.Left() - aBound.Left(); 1297 dTop = aCont.Top() - aBound.Top(); 1298 dRight = aBound.Right() - aCont.Right(); 1299 dBottom = aBound.Bottom() - aCont.Bottom(); 1300 bSetPos = dLeft || dTop || dRight || dBottom; 1301 } 1302 } 1303 1304 if ( bSet ) 1305 { 1306 if( !(ImplGetButtonState() & BUTTON_DRAW_DEFAULT) && bSetPos ) 1307 { 1308 // adjust pos/size when toggling from non-default to default 1309 aPos.Move(-dLeft, -dTop); 1310 aSize.Width() += dLeft + dRight; 1311 aSize.Height() += dTop + dBottom; 1312 } 1313 ImplGetButtonState() |= BUTTON_DRAW_DEFAULT; 1314 } 1315 else 1316 { 1317 if( (ImplGetButtonState() & BUTTON_DRAW_DEFAULT) && bSetPos ) 1318 { 1319 // adjust pos/size when toggling from default to non-default 1320 aPos.Move(dLeft, dTop); 1321 aSize.Width() -= dLeft + dRight; 1322 aSize.Height() -= dTop + dBottom; 1323 } 1324 ImplGetButtonState() &= ~BUTTON_DRAW_DEFAULT; 1325 } 1326 if( bSetPos ) 1327 SetPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height(), WINDOW_POSSIZE_ALL ); 1328 1329 Invalidate(); 1330 } 1331 1332 // ----------------------------------------------------------------------- 1333 1334 sal_Bool PushButton::ImplIsDefButton() const 1335 { 1336 return (ImplGetButtonState() & BUTTON_DRAW_DEFAULT) != 0; 1337 } 1338 1339 // ----------------------------------------------------------------------- 1340 1341 PushButton::PushButton( WindowType nType ) : 1342 Button( nType ) 1343 { 1344 ImplInitPushButtonData(); 1345 } 1346 1347 // ----------------------------------------------------------------------- 1348 1349 PushButton::PushButton( Window* pParent, WinBits nStyle ) : 1350 Button( WINDOW_PUSHBUTTON ) 1351 { 1352 ImplInitPushButtonData(); 1353 ImplInit( pParent, nStyle ); 1354 } 1355 1356 // ----------------------------------------------------------------------- 1357 1358 PushButton::PushButton( Window* pParent, const ResId& rResId ) : 1359 Button( WINDOW_PUSHBUTTON ) 1360 { 1361 ImplInitPushButtonData(); 1362 rResId.SetRT( RSC_PUSHBUTTON ); 1363 WinBits nStyle = ImplInitRes( rResId ); 1364 ImplInit( pParent, nStyle ); 1365 ImplLoadRes( rResId ); 1366 1367 if ( !(nStyle & WB_HIDE) ) 1368 Show(); 1369 } 1370 1371 // ----------------------------------------------------------------------- 1372 1373 PushButton::~PushButton() 1374 { 1375 } 1376 1377 // ----------------------------------------------------------------------- 1378 1379 void PushButton::MouseButtonDown( const MouseEvent& rMEvt ) 1380 { 1381 if ( rMEvt.IsLeft() && 1382 ImplHitTestPushButton( this, rMEvt.GetPosPixel() ) ) 1383 { 1384 sal_uInt16 nTrackFlags = 0; 1385 1386 if ( ( GetStyle() & WB_REPEAT ) && 1387 ! ( GetStyle() & WB_TOGGLE ) ) 1388 nTrackFlags |= STARTTRACK_BUTTONREPEAT; 1389 1390 ImplGetButtonState() |= BUTTON_DRAW_PRESSED; 1391 ImplDrawPushButton(); 1392 StartTracking( nTrackFlags ); 1393 1394 if ( nTrackFlags & STARTTRACK_BUTTONREPEAT ) 1395 Click(); 1396 } 1397 } 1398 1399 // ----------------------------------------------------------------------- 1400 1401 void PushButton::Tracking( const TrackingEvent& rTEvt ) 1402 { 1403 if ( rTEvt.IsTrackingEnded() ) 1404 { 1405 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) 1406 { 1407 if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() ) 1408 GrabFocus(); 1409 1410 if ( GetStyle() & WB_TOGGLE ) 1411 { 1412 // Don't toggle, when aborted 1413 if ( !rTEvt.IsTrackingCanceled() ) 1414 { 1415 if ( IsChecked() ) 1416 { 1417 Check( sal_False ); 1418 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 1419 } 1420 else 1421 Check( sal_True ); 1422 } 1423 } 1424 else 1425 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 1426 1427 ImplDrawPushButton(); 1428 1429 // Bei Abbruch kein Click-Handler rufen 1430 if ( !rTEvt.IsTrackingCanceled() ) 1431 { 1432 if ( ! ( ( GetStyle() & WB_REPEAT ) && 1433 ! ( GetStyle() & WB_TOGGLE ) ) ) 1434 Click(); 1435 } 1436 } 1437 } 1438 else 1439 { 1440 if ( ImplHitTestPushButton( this, rTEvt.GetMouseEvent().GetPosPixel() ) ) 1441 { 1442 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) 1443 { 1444 if ( rTEvt.IsTrackingRepeat() && (GetStyle() & WB_REPEAT) && 1445 ! ( GetStyle() & WB_TOGGLE ) ) 1446 Click(); 1447 } 1448 else 1449 { 1450 ImplGetButtonState() |= BUTTON_DRAW_PRESSED; 1451 ImplDrawPushButton(); 1452 } 1453 } 1454 else 1455 { 1456 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) 1457 { 1458 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 1459 ImplDrawPushButton(); 1460 } 1461 } 1462 } 1463 } 1464 1465 // ----------------------------------------------------------------------- 1466 1467 void PushButton::KeyInput( const KeyEvent& rKEvt ) 1468 { 1469 KeyCode aKeyCode = rKEvt.GetKeyCode(); 1470 1471 if ( !aKeyCode.GetModifier() && 1472 ((aKeyCode.GetCode() == KEY_RETURN) || (aKeyCode.GetCode() == KEY_SPACE)) ) 1473 { 1474 if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) ) 1475 { 1476 ImplGetButtonState() |= BUTTON_DRAW_PRESSED; 1477 ImplDrawPushButton(); 1478 } 1479 1480 if ( ( GetStyle() & WB_REPEAT ) && 1481 ! ( GetStyle() & WB_TOGGLE ) ) 1482 Click(); 1483 } 1484 else if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_ESCAPE) ) 1485 { 1486 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 1487 ImplDrawPushButton(); 1488 } 1489 else 1490 Button::KeyInput( rKEvt ); 1491 } 1492 1493 // ----------------------------------------------------------------------- 1494 1495 void PushButton::KeyUp( const KeyEvent& rKEvt ) 1496 { 1497 KeyCode aKeyCode = rKEvt.GetKeyCode(); 1498 1499 if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && 1500 ((aKeyCode.GetCode() == KEY_RETURN) || (aKeyCode.GetCode() == KEY_SPACE)) ) 1501 { 1502 if ( GetStyle() & WB_TOGGLE ) 1503 { 1504 if ( IsChecked() ) 1505 { 1506 Check( sal_False ); 1507 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 1508 } 1509 else 1510 Check( sal_True ); 1511 1512 Toggle(); 1513 } 1514 else 1515 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 1516 1517 ImplDrawPushButton(); 1518 1519 if ( !( ( GetStyle() & WB_REPEAT ) && 1520 ! ( GetStyle() & WB_TOGGLE ) ) ) 1521 Click(); 1522 } 1523 else 1524 Button::KeyUp( rKEvt ); 1525 } 1526 1527 // ----------------------------------------------------------------------- 1528 1529 void PushButton::FillLayoutData() const 1530 { 1531 mpControlData->mpLayoutData = new vcl::ControlLayoutData(); 1532 const_cast<PushButton*>(this)->ImplDrawPushButton( true ); 1533 } 1534 1535 // ----------------------------------------------------------------------- 1536 1537 void PushButton::Paint( const Rectangle& ) 1538 { 1539 ImplDrawPushButton(); 1540 } 1541 1542 // ----------------------------------------------------------------------- 1543 1544 void PushButton::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, 1545 sal_uLong nFlags ) 1546 { 1547 Point aPos = pDev->LogicToPixel( rPos ); 1548 Size aSize = pDev->LogicToPixel( rSize ); 1549 Rectangle aRect( aPos, aSize ); 1550 Rectangle aTextRect; 1551 Font aFont = GetDrawPixelFont( pDev ); 1552 1553 pDev->Push(); 1554 pDev->SetMapMode(); 1555 pDev->SetFont( aFont ); 1556 if ( nFlags & WINDOW_DRAW_MONO ) 1557 { 1558 pDev->SetTextColor( Color( COL_BLACK ) ); 1559 } 1560 else 1561 { 1562 pDev->SetTextColor( GetTextColor() ); 1563 1564 // DecoView uses the FaceColor... 1565 AllSettings aSettings = pDev->GetSettings(); 1566 StyleSettings aStyleSettings = aSettings.GetStyleSettings(); 1567 if ( IsControlBackground() ) 1568 aStyleSettings.SetFaceColor( GetControlBackground() ); 1569 else 1570 aStyleSettings.SetFaceColor( GetSettings().GetStyleSettings().GetFaceColor() ); 1571 aSettings.SetStyleSettings( aStyleSettings ); 1572 pDev->SetSettings( aSettings ); 1573 } 1574 pDev->SetTextFillColor(); 1575 1576 DecorationView aDecoView( pDev ); 1577 sal_uInt16 nButtonStyle = 0; 1578 if ( nFlags & WINDOW_DRAW_MONO ) 1579 nButtonStyle |= BUTTON_DRAW_MONO; 1580 if ( IsChecked() ) 1581 nButtonStyle |= BUTTON_DRAW_CHECKED; 1582 aRect = aDecoView.DrawButton( aRect, nButtonStyle ); 1583 1584 ImplDrawPushButtonContent( pDev, nFlags, aRect, false, true ); 1585 pDev->Pop(); 1586 } 1587 1588 // ----------------------------------------------------------------------- 1589 1590 void PushButton::Resize() 1591 { 1592 Control::Resize(); 1593 Invalidate(); 1594 } 1595 1596 // ----------------------------------------------------------------------- 1597 1598 void PushButton::GetFocus() 1599 { 1600 ShowFocus( ImplGetFocusRect() ); 1601 SetInputContext( InputContext( GetFont() ) ); 1602 Button::GetFocus(); 1603 } 1604 1605 // ----------------------------------------------------------------------- 1606 1607 void PushButton::LoseFocus() 1608 { 1609 EndSelection(); 1610 HideFocus(); 1611 Button::LoseFocus(); 1612 } 1613 1614 // ----------------------------------------------------------------------- 1615 1616 void PushButton::StateChanged( StateChangedType nType ) 1617 { 1618 Button::StateChanged( nType ); 1619 1620 if ( (nType == STATE_CHANGE_ENABLE) || 1621 (nType == STATE_CHANGE_TEXT) || 1622 (nType == STATE_CHANGE_IMAGE) || 1623 (nType == STATE_CHANGE_DATA) || 1624 (nType == STATE_CHANGE_STATE) || 1625 (nType == STATE_CHANGE_UPDATEMODE) ) 1626 { 1627 if ( IsReallyVisible() && IsUpdateMode() ) 1628 Invalidate(); 1629 } 1630 else if ( nType == STATE_CHANGE_STYLE ) 1631 { 1632 SetStyle( ImplInitStyle( GetWindow( WINDOW_PREV ), GetStyle() ) ); 1633 1634 bool bIsDefButton = ( GetStyle() & WB_DEFBUTTON ) != 0; 1635 bool bWasDefButton = ( GetPrevStyle() & WB_DEFBUTTON ) != 0; 1636 if ( bIsDefButton != bWasDefButton ) 1637 ImplSetDefButton( bIsDefButton ); 1638 1639 if ( IsReallyVisible() && IsUpdateMode() ) 1640 { 1641 if ( (GetPrevStyle() & PUSHBUTTON_VIEW_STYLE) != 1642 (GetStyle() & PUSHBUTTON_VIEW_STYLE) ) 1643 Invalidate(); 1644 } 1645 } 1646 else if ( (nType == STATE_CHANGE_ZOOM) || 1647 (nType == STATE_CHANGE_CONTROLFONT) ) 1648 { 1649 ImplInitSettings( sal_True, sal_False, sal_False ); 1650 Invalidate(); 1651 } 1652 else if ( nType == STATE_CHANGE_CONTROLFOREGROUND ) 1653 { 1654 ImplInitSettings( sal_False, sal_True, sal_False ); 1655 Invalidate(); 1656 } 1657 else if ( nType == STATE_CHANGE_CONTROLBACKGROUND ) 1658 { 1659 ImplInitSettings( sal_False, sal_False, sal_True ); 1660 Invalidate(); 1661 } 1662 } 1663 1664 // ----------------------------------------------------------------------- 1665 1666 void PushButton::DataChanged( const DataChangedEvent& rDCEvt ) 1667 { 1668 Button::DataChanged( rDCEvt ); 1669 1670 if ( (rDCEvt.GetType() == DATACHANGED_FONTS) || 1671 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) || 1672 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) && 1673 (rDCEvt.GetFlags() & SETTINGS_STYLE)) ) 1674 { 1675 ImplInitSettings( sal_True, sal_True, sal_True ); 1676 Invalidate(); 1677 } 1678 } 1679 1680 // ----------------------------------------------------------------------- 1681 1682 long PushButton::PreNotify( NotifyEvent& rNEvt ) 1683 { 1684 long nDone = 0; 1685 const MouseEvent* pMouseEvt = NULL; 1686 1687 if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL ) 1688 { 1689 if( pMouseEvt->IsEnterWindow() || pMouseEvt->IsLeaveWindow() ) 1690 { 1691 // trigger redraw as mouse over state has changed 1692 1693 // TODO: move this to Window class or make it a member !!! 1694 ControlType aCtrlType = 0; 1695 switch( GetParent()->GetType() ) 1696 { 1697 case WINDOW_LISTBOX: 1698 case WINDOW_MULTILISTBOX: 1699 case WINDOW_TREELISTBOX: 1700 aCtrlType = CTRL_LISTBOX; 1701 break; 1702 1703 case WINDOW_COMBOBOX: 1704 case WINDOW_PATTERNBOX: 1705 case WINDOW_NUMERICBOX: 1706 case WINDOW_METRICBOX: 1707 case WINDOW_CURRENCYBOX: 1708 case WINDOW_DATEBOX: 1709 case WINDOW_TIMEBOX: 1710 case WINDOW_LONGCURRENCYBOX: 1711 aCtrlType = CTRL_COMBOBOX; 1712 break; 1713 default: 1714 break; 1715 } 1716 1717 sal_Bool bDropDown = ( IsSymbol() && (GetSymbol()==SYMBOL_SPIN_DOWN) && !GetText().Len() ); 1718 1719 if( bDropDown && GetParent()->IsNativeControlSupported( aCtrlType, PART_ENTIRE_CONTROL) && 1720 !GetParent()->IsNativeControlSupported( aCtrlType, PART_BUTTON_DOWN) ) 1721 { 1722 Window *pBorder = GetParent()->GetWindow( WINDOW_BORDER ); 1723 if(aCtrlType == CTRL_COMBOBOX) 1724 { 1725 // only paint the button part to avoid flickering of the combobox text 1726 Point aPt; 1727 Rectangle aClipRect( aPt, GetOutputSizePixel() ); 1728 aClipRect.SetPos(pBorder->ScreenToOutputPixel(OutputToScreenPixel(aClipRect.TopLeft()))); 1729 pBorder->Invalidate( aClipRect ); 1730 } 1731 else 1732 { 1733 pBorder->Invalidate( INVALIDATE_NOERASE ); 1734 pBorder->Update(); 1735 } 1736 } 1737 else if( (GetStyle() & WB_FLATBUTTON) || 1738 IsNativeControlSupported(CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL) ) 1739 { 1740 Invalidate(); 1741 } 1742 } 1743 } 1744 1745 return nDone ? nDone : Button::PreNotify(rNEvt); 1746 } 1747 1748 // ----------------------------------------------------------------------- 1749 1750 void PushButton::Toggle() 1751 { 1752 ImplCallEventListenersAndHandler( VCLEVENT_PUSHBUTTON_TOGGLE, maToggleHdl, this ); 1753 } 1754 1755 // ----------------------------------------------------------------------- 1756 1757 void PushButton::SetSymbol( SymbolType eSymbol ) 1758 { 1759 if ( meSymbol != eSymbol ) 1760 { 1761 meSymbol = eSymbol; 1762 StateChanged( STATE_CHANGE_DATA ); 1763 } 1764 } 1765 1766 // ----------------------------------------------------------------------- 1767 void PushButton::SetSymbolAlign( SymbolAlign eAlign ) 1768 { 1769 ImplSetSymbolAlign( eAlign ); 1770 } 1771 1772 // ----------------------------------------------------------------------- 1773 SymbolAlign PushButton::GetSymbolAlign() const 1774 { 1775 return ImplGetSymbolAlign(); 1776 } 1777 1778 // ----------------------------------------------------------------------- 1779 1780 void PushButton::SetDropDown( sal_uInt16 nStyle ) 1781 { 1782 if ( mnDDStyle != nStyle ) 1783 { 1784 mnDDStyle = nStyle; 1785 StateChanged( STATE_CHANGE_DATA ); 1786 } 1787 } 1788 1789 // ----------------------------------------------------------------------- 1790 1791 void PushButton::SetState( TriState eState ) 1792 { 1793 if ( meState != eState ) 1794 { 1795 meState = eState; 1796 if ( meState == STATE_NOCHECK ) 1797 ImplGetButtonState() &= ~(BUTTON_DRAW_CHECKED | BUTTON_DRAW_DONTKNOW); 1798 else if ( meState == STATE_CHECK ) 1799 { 1800 ImplGetButtonState() &= ~BUTTON_DRAW_DONTKNOW; 1801 ImplGetButtonState() |= BUTTON_DRAW_CHECKED; 1802 } 1803 else // STATE_DONTKNOW 1804 { 1805 ImplGetButtonState() &= ~BUTTON_DRAW_CHECKED; 1806 ImplGetButtonState() |= BUTTON_DRAW_DONTKNOW; 1807 } 1808 1809 StateChanged( STATE_CHANGE_STATE ); 1810 Toggle(); 1811 } 1812 } 1813 1814 // ----------------------------------------------------------------------- 1815 1816 void PushButton::SetPressed( sal_Bool bPressed ) 1817 { 1818 if ( mbPressed != bPressed ) 1819 { 1820 mbPressed = bPressed; 1821 StateChanged( STATE_CHANGE_DATA ); 1822 } 1823 } 1824 1825 // ----------------------------------------------------------------------- 1826 1827 void PushButton::EndSelection() 1828 { 1829 EndTracking( ENDTRACK_CANCEL ); 1830 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) 1831 { 1832 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 1833 if ( !mbPressed ) 1834 ImplDrawPushButton(); 1835 } 1836 } 1837 1838 // ----------------------------------------------------------------------- 1839 1840 Size PushButton::CalcMinimumSize( long nMaxWidth ) const 1841 { 1842 Size aSize; 1843 1844 if ( IsSymbol() ) 1845 { 1846 if ( IsSmallSymbol ()) 1847 aSize = Size( 16, 12 ); 1848 else 1849 aSize = Size( 26, 24 ); 1850 if( mnDDStyle == PUSHBUTTON_DROPDOWN_MENUBUTTON ) 1851 aSize.Width() += 4; 1852 } 1853 else if ( IsImage() && ! (ImplGetButtonState() & BUTTON_DRAW_NOIMAGE) ) 1854 aSize = GetModeImage().GetSizePixel(); 1855 if ( PushButton::GetText().Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) ) 1856 { 1857 sal_uLong nDrawFlags = 0; 1858 Size textSize = GetTextRect( Rectangle( Point(), Size( nMaxWidth ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ), 1859 PushButton::GetText(), ImplGetTextStyle( nDrawFlags ) ).GetSize(); 1860 aSize.Width() += int( textSize.Width () * 1.15 ); 1861 aSize.Height() = std::max( aSize.Height(), long( textSize.Height() * 1.15 ) ); 1862 } 1863 1864 // cf. ImplDrawPushButton ... 1865 if( (GetStyle() & WB_SMALLSTYLE) == 0 ) 1866 { 1867 aSize.Width() += 8; 1868 aSize.Height() += 8; 1869 } 1870 1871 return CalcWindowSize( aSize ); 1872 } 1873 1874 Size PushButton::GetOptimalSize(WindowSizeType eType) const 1875 { 1876 switch (eType) { 1877 case WINDOWSIZE_MINIMUM: { 1878 return CalcMinimumSize(); 1879 } 1880 default: 1881 return Button::GetOptimalSize( eType ); 1882 } 1883 } 1884 1885 // ======================================================================= 1886 1887 void OKButton::ImplInit( Window* pParent, WinBits nStyle ) 1888 { 1889 PushButton::ImplInit( pParent, nStyle ); 1890 1891 SetText( Button::GetStandardText( BUTTON_OK ) ); 1892 SetHelpText( Button::GetStandardHelpText( BUTTON_OK ) ); 1893 } 1894 1895 // ----------------------------------------------------------------------- 1896 1897 OKButton::OKButton( Window* pParent, WinBits nStyle ) : 1898 PushButton( WINDOW_OKBUTTON ) 1899 { 1900 ImplInit( pParent, nStyle ); 1901 } 1902 1903 // ----------------------------------------------------------------------- 1904 1905 OKButton::OKButton( Window* pParent, const ResId& rResId ) : 1906 PushButton( WINDOW_OKBUTTON ) 1907 { 1908 rResId.SetRT( RSC_OKBUTTON ); 1909 WinBits nStyle = ImplInitRes( rResId ); 1910 ImplInit( pParent, nStyle ); 1911 ImplLoadRes( rResId ); 1912 1913 if ( !(nStyle & WB_HIDE) ) 1914 Show(); 1915 } 1916 1917 // ----------------------------------------------------------------------- 1918 1919 void OKButton::Click() 1920 { 1921 // Ist kein Link gesetzt, dann schliesse Parent 1922 if ( !GetClickHdl() ) 1923 { 1924 Window* pParent = GetParent(); 1925 if ( pParent->IsSystemWindow() ) 1926 { 1927 if ( pParent->IsDialog() ) 1928 { 1929 if ( ((Dialog*)pParent)->IsInExecute() ) 1930 ((Dialog*)pParent)->EndDialog( sal_True ); 1931 // gegen rekursive Aufrufe schuetzen 1932 else if ( !((Dialog*)pParent)->IsInClose() ) 1933 { 1934 if ( pParent->GetStyle() & WB_CLOSEABLE ) 1935 ((Dialog*)pParent)->Close(); 1936 } 1937 } 1938 else 1939 { 1940 if ( pParent->GetStyle() & WB_CLOSEABLE ) 1941 ((SystemWindow*)pParent)->Close(); 1942 } 1943 } 1944 } 1945 else 1946 { 1947 PushButton::Click(); 1948 } 1949 } 1950 1951 // ======================================================================= 1952 1953 void CancelButton::ImplInit( Window* pParent, WinBits nStyle ) 1954 { 1955 PushButton::ImplInit( pParent, nStyle ); 1956 1957 SetText( Button::GetStandardText( BUTTON_CANCEL ) ); 1958 SetHelpText( Button::GetStandardHelpText( BUTTON_CANCEL ) ); 1959 } 1960 1961 // ----------------------------------------------------------------------- 1962 1963 CancelButton::CancelButton( Window* pParent, WinBits nStyle ) : 1964 PushButton( WINDOW_CANCELBUTTON ) 1965 { 1966 ImplInit( pParent, nStyle ); 1967 } 1968 1969 // ----------------------------------------------------------------------- 1970 1971 CancelButton::CancelButton( Window* pParent, const ResId& rResId ) : 1972 PushButton( WINDOW_CANCELBUTTON ) 1973 { 1974 rResId.SetRT( RSC_CANCELBUTTON ); 1975 WinBits nStyle = ImplInitRes( rResId ); 1976 ImplInit( pParent, nStyle ); 1977 ImplLoadRes( rResId ); 1978 1979 if ( !(nStyle & WB_HIDE) ) 1980 Show(); 1981 } 1982 1983 // ----------------------------------------------------------------------- 1984 1985 void CancelButton::Click() 1986 { 1987 // Ist kein Link gesetzt, dann schliesse Parent 1988 if ( !GetClickHdl() ) 1989 { 1990 Window* pParent = GetParent(); 1991 if ( pParent->IsSystemWindow() ) 1992 { 1993 if ( pParent->IsDialog() ) 1994 { 1995 if ( ((Dialog*)pParent)->IsInExecute() ) 1996 ((Dialog*)pParent)->EndDialog( sal_False ); 1997 // gegen rekursive Aufrufe schuetzen 1998 else if ( !((Dialog*)pParent)->IsInClose() ) 1999 { 2000 if ( pParent->GetStyle() & WB_CLOSEABLE ) 2001 ((Dialog*)pParent)->Close(); 2002 } 2003 } 2004 else 2005 { 2006 if ( pParent->GetStyle() & WB_CLOSEABLE ) 2007 ((SystemWindow*)pParent)->Close(); 2008 } 2009 } 2010 } 2011 else 2012 { 2013 PushButton::Click(); 2014 } 2015 } 2016 2017 // ======================================================================= 2018 2019 void HelpButton::ImplInit( Window* pParent, WinBits nStyle ) 2020 { 2021 PushButton::ImplInit( pParent, nStyle | WB_NOPOINTERFOCUS ); 2022 2023 SetText( Button::GetStandardText( BUTTON_HELP ) ); 2024 SetHelpText( Button::GetStandardHelpText( BUTTON_HELP ) ); 2025 } 2026 2027 // ----------------------------------------------------------------------- 2028 2029 HelpButton::HelpButton( Window* pParent, WinBits nStyle ) : 2030 PushButton( WINDOW_HELPBUTTON ) 2031 { 2032 ImplInit( pParent, nStyle ); 2033 } 2034 2035 // ----------------------------------------------------------------------- 2036 2037 HelpButton::HelpButton( Window* pParent, const ResId& rResId ) : 2038 PushButton( WINDOW_HELPBUTTON ) 2039 { 2040 rResId.SetRT( RSC_HELPBUTTON ); 2041 WinBits nStyle = ImplInitRes( rResId ); 2042 ImplInit( pParent, nStyle ); 2043 ImplLoadRes( rResId ); 2044 2045 if ( !(nStyle & WB_HIDE) ) 2046 Show(); 2047 } 2048 2049 // ----------------------------------------------------------------------- 2050 2051 void HelpButton::Click() 2052 { 2053 // Ist kein Link gesetzt, loese Hilfe aus 2054 if ( !GetClickHdl() ) 2055 { 2056 Window* pFocusWin = Application::GetFocusWindow(); 2057 if ( !pFocusWin ) 2058 pFocusWin = this; 2059 2060 HelpEvent aEvt( pFocusWin->GetPointerPosPixel(), HELPMODE_CONTEXT ); 2061 pFocusWin->RequestHelp( aEvt ); 2062 } 2063 PushButton::Click(); 2064 } 2065 2066 // ======================================================================= 2067 2068 void RadioButton::ImplInitRadioButtonData() 2069 { 2070 mbChecked = sal_False; 2071 mbSaveValue = sal_False; 2072 mbRadioCheck = sal_True; 2073 mbStateChanged = sal_False; 2074 } 2075 2076 // ----------------------------------------------------------------------- 2077 2078 void RadioButton::ImplInit( Window* pParent, WinBits nStyle ) 2079 { 2080 nStyle = ImplInitStyle( pParent->GetWindow( WINDOW_LASTCHILD ), nStyle ); 2081 Button::ImplInit( pParent, nStyle, NULL ); 2082 2083 ImplInitSettings( sal_True, sal_True, sal_True ); 2084 } 2085 2086 // ----------------------------------------------------------------------- 2087 2088 WinBits RadioButton::ImplInitStyle( const Window* pPrevWindow, WinBits nStyle ) 2089 { 2090 if ( !(nStyle & WB_NOGROUP) && 2091 (!pPrevWindow || (pPrevWindow->GetType() != WINDOW_RADIOBUTTON)) ) 2092 nStyle |= WB_GROUP; 2093 if ( !(nStyle & WB_NOTABSTOP) ) 2094 { 2095 if ( IsChecked() ) 2096 nStyle |= WB_TABSTOP; 2097 else 2098 nStyle &= ~WB_TABSTOP; 2099 } 2100 return nStyle; 2101 } 2102 2103 // ----------------------------------------------------------------- 2104 2105 const Font& RadioButton::GetCanonicalFont( const StyleSettings& _rStyle ) const 2106 { 2107 return _rStyle.GetRadioCheckFont(); 2108 } 2109 2110 // ----------------------------------------------------------------- 2111 const Color& RadioButton::GetCanonicalTextColor( const StyleSettings& _rStyle ) const 2112 { 2113 return _rStyle.GetRadioCheckTextColor(); 2114 } 2115 2116 // ----------------------------------------------------------------------- 2117 2118 void RadioButton::ImplInitSettings( sal_Bool bFont, 2119 sal_Bool bForeground, sal_Bool bBackground ) 2120 { 2121 Button::ImplInitSettings( bFont, bForeground ); 2122 2123 if ( bBackground ) 2124 { 2125 Window* pParent = GetParent(); 2126 if ( !IsControlBackground() && 2127 (pParent->IsChildTransparentModeEnabled() || IsNativeControlSupported( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL ) ) ) 2128 { 2129 EnableChildTransparentMode( sal_True ); 2130 SetParentClipMode( PARENTCLIPMODE_NOCLIP ); 2131 SetPaintTransparent( sal_True ); 2132 SetBackground(); 2133 if( IsNativeControlSupported( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL ) ) 2134 mpWindowImpl->mbUseNativeFocus = ImplGetSVData()->maNWFData.mbNoFocusRects; 2135 } 2136 else 2137 { 2138 EnableChildTransparentMode( sal_False ); 2139 SetParentClipMode( 0 ); 2140 SetPaintTransparent( sal_False ); 2141 2142 if ( IsControlBackground() ) 2143 SetBackground( GetControlBackground() ); 2144 else 2145 SetBackground( pParent->GetBackground() ); 2146 } 2147 } 2148 } 2149 2150 //--------------------------------------------------------------------- 2151 //--- 12.03.2003 18:46:14 --------------------------------------------- 2152 2153 void RadioButton::DrawRadioButtonState( ) 2154 { 2155 ImplDrawRadioButtonState( ); 2156 } 2157 2158 // ----------------------------------------------------------------------- 2159 2160 void RadioButton::ImplInvalidateOrDrawRadioButtonState() 2161 { 2162 if( ImplGetSVData()->maNWFData.mbCheckBoxNeedsErase ) 2163 { 2164 if ( IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL) ) 2165 { 2166 Invalidate(); 2167 Update(); 2168 return; 2169 } 2170 } 2171 ImplDrawRadioButtonState(); 2172 } 2173 2174 void RadioButton::ImplDrawRadioButtonState() 2175 { 2176 sal_uInt16 nButtonStyle = 0; 2177 sal_Bool bNativeOK = sal_False; 2178 2179 // no native drawing for image radio buttons 2180 if ( !maImage && (bNativeOK=IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL)) == sal_True ) 2181 { 2182 ImplControlValue aControlValue( mbChecked ? BUTTONVALUE_ON : BUTTONVALUE_OFF ); 2183 Rectangle aCtrlRect( maStateRect.TopLeft(), maStateRect.GetSize() ); 2184 ControlState nState = 0; 2185 2186 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) nState |= CTRL_STATE_PRESSED; 2187 if ( HasFocus() ) nState |= CTRL_STATE_FOCUSED; 2188 if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT ) nState |= CTRL_STATE_DEFAULT; 2189 if ( IsEnabled() ) nState |= CTRL_STATE_ENABLED; 2190 2191 if ( IsMouseOver() && maMouseRect.IsInside( GetPointerPosPixel() ) ) 2192 nState |= CTRL_STATE_ROLLOVER; 2193 2194 bNativeOK = DrawNativeControl( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL, aCtrlRect, nState, 2195 aControlValue,rtl::OUString() ); 2196 2197 } 2198 2199 if ( bNativeOK == sal_False ) 2200 { 2201 // kein Image-RadioButton 2202 if ( !maImage ) 2203 { 2204 sal_uInt16 nStyle = ImplGetButtonState(); 2205 if ( !IsEnabled() ) 2206 nStyle |= BUTTON_DRAW_DISABLED; 2207 if ( mbChecked ) 2208 nStyle |= BUTTON_DRAW_CHECKED; 2209 Image aImage = GetRadioImage( GetSettings(), nStyle ); 2210 if ( IsZoom() ) 2211 DrawImage( maStateRect.TopLeft(), maStateRect.GetSize(), aImage ); 2212 else 2213 DrawImage( maStateRect.TopLeft(), aImage ); 2214 } 2215 else 2216 { 2217 HideFocus(); 2218 2219 DecorationView aDecoView( this ); 2220 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 2221 Rectangle aImageRect = maStateRect; 2222 Size aImageSize = maImage.GetSizePixel(); 2223 sal_Bool bEnabled = IsEnabled(); 2224 2225 aImageSize.Width() = CalcZoom( aImageSize.Width() ); 2226 aImageSize.Height() = CalcZoom( aImageSize.Height() ); 2227 2228 // Border und Selektionsstatus ausgeben 2229 nButtonStyle = FRAME_DRAW_DOUBLEIN; 2230 aImageRect = aDecoView.DrawFrame( aImageRect, nButtonStyle ); 2231 if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) || !bEnabled ) 2232 SetFillColor( rStyleSettings.GetFaceColor() ); 2233 else 2234 SetFillColor( rStyleSettings.GetFieldColor() ); 2235 SetLineColor(); 2236 DrawRect( aImageRect ); 2237 2238 // Image ausgeben 2239 nButtonStyle = 0; 2240 if ( !bEnabled ) 2241 nButtonStyle |= IMAGE_DRAW_DISABLE; 2242 2243 // check for HC mode 2244 Image *pImage = &maImage; 2245 if( !!maImageHC ) 2246 { 2247 if( rStyleSettings.GetHighContrastMode() ) 2248 pImage = &maImageHC; 2249 } 2250 2251 Point aImagePos( aImageRect.TopLeft() ); 2252 aImagePos.X() += (aImageRect.GetWidth()-aImageSize.Width())/2; 2253 aImagePos.Y() += (aImageRect.GetHeight()-aImageSize.Height())/2; 2254 if ( IsZoom() ) 2255 DrawImage( aImagePos, aImageSize, *pImage, nButtonStyle ); 2256 else 2257 DrawImage( aImagePos, *pImage, nButtonStyle ); 2258 2259 aImageRect.Left()++; 2260 aImageRect.Top()++; 2261 aImageRect.Right()--; 2262 aImageRect.Bottom()--; 2263 2264 ImplSetFocusRect( aImageRect ); 2265 2266 if ( mbChecked ) 2267 { 2268 SetLineColor( rStyleSettings.GetHighlightColor() ); 2269 SetFillColor(); 2270 if ( (aImageSize.Width() >= 20) || (aImageSize.Height() >= 20) ) 2271 { 2272 aImageRect.Left()++; 2273 aImageRect.Top()++; 2274 aImageRect.Right()--; 2275 aImageRect.Bottom()--; 2276 } 2277 DrawRect( aImageRect ); 2278 aImageRect.Left()++; 2279 aImageRect.Top()++; 2280 aImageRect.Right()--; 2281 aImageRect.Bottom()--; 2282 DrawRect( aImageRect ); 2283 } 2284 2285 if ( HasFocus() ) 2286 ShowFocus( ImplGetFocusRect() ); 2287 } 2288 } 2289 } 2290 2291 // ----------------------------------------------------------------------- 2292 2293 void RadioButton::ImplDraw( OutputDevice* pDev, sal_uLong nDrawFlags, 2294 const Point& rPos, const Size& rSize, 2295 const Size& rImageSize, Rectangle& rStateRect, 2296 Rectangle& rMouseRect, bool bLayout ) 2297 { 2298 WinBits nWinStyle = GetStyle(); 2299 XubString aText( GetText() ); 2300 Rectangle aRect( rPos, rSize ); 2301 MetricVector* pVector = bLayout ? &mpControlData->mpLayoutData->m_aUnicodeBoundRects : NULL; 2302 String* pDisplayText = bLayout ? &mpControlData->mpLayoutData->m_aDisplayText : NULL; 2303 2304 pDev->Push( PUSH_CLIPREGION ); 2305 pDev->IntersectClipRegion( Rectangle( rPos, rSize ) ); 2306 2307 // kein Image-RadioButton 2308 if ( !maImage ) 2309 { 2310 if ( ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) ) || 2311 ( HasImage() && ! (ImplGetButtonState() & BUTTON_DRAW_NOIMAGE) ) ) 2312 { 2313 sal_uInt16 nTextStyle = Button::ImplGetTextStyle( aText, nWinStyle, nDrawFlags ); 2314 2315 const long nImageSep = GetDrawPixel( pDev, ImplGetImageToTextDistance() ); 2316 Size aSize( rSize ); 2317 Point aPos( rPos ); 2318 aPos.X() += rImageSize.Width() + nImageSep; 2319 aSize.Width() -= rImageSize.Width() + nImageSep; 2320 2321 // if the text rect height is smaller than the height of the image 2322 // then for single lines the default should be centered text 2323 if( (nWinStyle & (WB_TOP|WB_VCENTER|WB_BOTTOM)) == 0 && 2324 (rImageSize.Height() > rSize.Height() || ! (nWinStyle & WB_WORDBREAK) ) ) 2325 { 2326 nTextStyle &= ~(TEXT_DRAW_TOP|TEXT_DRAW_BOTTOM); 2327 nTextStyle |= TEXT_DRAW_VCENTER; 2328 aSize.Height() = rImageSize.Height(); 2329 } 2330 2331 ImplDrawAlignedImage( pDev, aPos, aSize, bLayout, 1, 2332 nDrawFlags, nTextStyle, NULL ); 2333 2334 rMouseRect = Rectangle( aPos, aSize ); 2335 rMouseRect.Left() = rPos.X(); 2336 2337 rStateRect.Left() = rPos.X(); 2338 rStateRect.Top() = rMouseRect.Top(); 2339 2340 if ( aSize.Height() > rImageSize.Height() ) 2341 rStateRect.Top() += ( aSize.Height() - rImageSize.Height() ) / 2; 2342 else 2343 { 2344 rStateRect.Top() -= ( rImageSize.Height() - aSize.Height() ) / 2; 2345 if( rStateRect.Top() < 0 ) 2346 rStateRect.Top() = 0; 2347 } 2348 2349 rStateRect.Right() = rStateRect.Left() + rImageSize.Width()-1; 2350 rStateRect.Bottom() = rStateRect.Top() + rImageSize.Height()-1; 2351 2352 if ( rStateRect.Bottom() > rMouseRect.Bottom() ) 2353 rMouseRect.Bottom() = rStateRect.Bottom(); 2354 } 2355 else 2356 { 2357 if ( nWinStyle & WB_CENTER ) 2358 rStateRect.Left() = rPos.X()+((rSize.Width()-rImageSize.Width())/2); 2359 else if ( nWinStyle & WB_RIGHT ) 2360 rStateRect.Left() = rPos.X()+rSize.Width()-rImageSize.Width(); //-1; 2361 else 2362 rStateRect.Left() = rPos.X(); //+1; 2363 if ( nWinStyle & WB_VCENTER ) 2364 rStateRect.Top() = rPos.Y()+((rSize.Height()-rImageSize.Height())/2); 2365 else if ( nWinStyle & WB_BOTTOM ) 2366 rStateRect.Top() = rPos.Y()+rSize.Height()-rImageSize.Height(); //-1; 2367 else 2368 rStateRect.Top() = rPos.Y(); //+1; 2369 rStateRect.Right() = rStateRect.Left()+rImageSize.Width()-1; 2370 rStateRect.Bottom() = rStateRect.Top()+rImageSize.Height()-1; 2371 rMouseRect = rStateRect; 2372 2373 ImplSetFocusRect( rStateRect ); 2374 2375 /* und oben -1, da CalcSize() auch Focus-Rechteck nicht mit einrechnet, 2376 da im Writer ansonsten die Images noch weiter oben haengen 2377 rFocusRect = rStateRect; 2378 rFocusRect.Left()--; 2379 rFocusRect.Top()--; 2380 rFocusRect.Right()++; 2381 rFocusRect.Bottom()++; 2382 */ 2383 } 2384 } 2385 else 2386 { 2387 sal_Bool bTopImage = (nWinStyle & WB_TOP) != 0; 2388 Size aImageSize = maImage.GetSizePixel(); 2389 Rectangle aImageRect( rPos, rSize ); 2390 long nTextHeight = pDev->GetTextHeight(); 2391 long nTextWidth = pDev->GetCtrlTextWidth( aText ); 2392 2393 // Positionen und Groessen berechnen 2394 if ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) ) 2395 { 2396 Size aTmpSize( (aImageSize.Width()+8), (aImageSize.Height()+8) ); 2397 if ( bTopImage ) 2398 { 2399 aImageRect.Left() = (rSize.Width()-aTmpSize.Width())/2; 2400 aImageRect.Top() = (rSize.Height()-(aTmpSize.Height()+nTextHeight+6))/2; 2401 } 2402 else 2403 aImageRect.Top() = (rSize.Height()-aTmpSize.Height())/2; 2404 2405 aImageRect.Right() = aImageRect.Left()+aTmpSize.Width(); 2406 aImageRect.Bottom() = aImageRect.Top()+aTmpSize.Height(); 2407 2408 // Text ausgeben 2409 Point aTxtPos = rPos; 2410 if ( bTopImage ) 2411 { 2412 aTxtPos.X() += (rSize.Width()-nTextWidth)/2; 2413 aTxtPos.Y() += aImageRect.Bottom()+6; 2414 } 2415 else 2416 { 2417 aTxtPos.X() += aImageRect.Right()+8; 2418 aTxtPos.Y() += (rSize.Height()-nTextHeight)/2; 2419 } 2420 pDev->DrawCtrlText( aTxtPos, aText, 0, STRING_LEN, TEXT_DRAW_MNEMONIC, pVector, pDisplayText ); 2421 } 2422 2423 rMouseRect = aImageRect; 2424 rStateRect = aImageRect; 2425 } 2426 2427 pDev->Pop(); 2428 } 2429 2430 // ----------------------------------------------------------------------- 2431 2432 void RadioButton::ImplDrawRadioButton( bool bLayout ) 2433 { 2434 if( !bLayout ) 2435 HideFocus(); 2436 2437 Size aImageSize; 2438 if ( !maImage ) 2439 aImageSize = ImplGetRadioImageSize(); 2440 else 2441 aImageSize = maImage.GetSizePixel(); 2442 aImageSize.Width() = CalcZoom( aImageSize.Width() ); 2443 aImageSize.Height() = CalcZoom( aImageSize.Height() ); 2444 2445 // Draw control text 2446 ImplDraw( this, 0, Point(), GetOutputSizePixel(), 2447 aImageSize, maStateRect, maMouseRect, bLayout ); 2448 2449 if( !bLayout || (IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL)==sal_True) ) 2450 { 2451 if ( !maImage && HasFocus() ) 2452 ShowFocus( ImplGetFocusRect() ); 2453 2454 ImplDrawRadioButtonState(); 2455 } 2456 } 2457 2458 // ----------------------------------------------------------------------- 2459 2460 void RadioButton::GetRadioButtonGroup( std::vector< RadioButton* >& io_rGroup, bool bIncludeThis ) const 2461 { 2462 // empty the list 2463 io_rGroup.clear(); 2464 2465 // go back to first in group; 2466 Window* pFirst = const_cast<RadioButton*>(this); 2467 while( ( pFirst->GetStyle() & WB_GROUP ) == 0 ) 2468 { 2469 Window* pWindow = pFirst->GetWindow( WINDOW_PREV ); 2470 if( pWindow ) 2471 pFirst = pWindow; 2472 else 2473 break; 2474 } 2475 // insert radiobuttons up to next group 2476 do 2477 { 2478 if( pFirst->GetType() == WINDOW_RADIOBUTTON ) 2479 { 2480 if( pFirst != this || bIncludeThis ) 2481 io_rGroup.push_back( static_cast<RadioButton*>(pFirst) ); 2482 } 2483 pFirst = pFirst->GetWindow( WINDOW_NEXT ); 2484 } while( pFirst && ( ( pFirst->GetStyle() & WB_GROUP ) == 0 ) ); 2485 } 2486 2487 // ----------------------------------------------------------------------- 2488 2489 void RadioButton::ImplUncheckAllOther() 2490 { 2491 mpWindowImpl->mnStyle |= WB_TABSTOP; 2492 2493 // Gruppe mit RadioButtons durchgehen und die gecheckten Buttons 2494 Window* pWindow; 2495 WinBits nStyle; 2496 if ( !(GetStyle() & WB_GROUP) ) 2497 { 2498 pWindow = GetWindow( WINDOW_PREV ); 2499 while ( pWindow ) 2500 { 2501 nStyle = pWindow->GetStyle(); 2502 2503 if ( pWindow->GetType() == WINDOW_RADIOBUTTON ) 2504 { 2505 if ( ((RadioButton*)pWindow)->IsChecked() ) 2506 { 2507 ImplDelData aDelData; 2508 pWindow->ImplAddDel( &aDelData ); 2509 ((RadioButton*)pWindow)->SetState( sal_False ); 2510 if ( aDelData.IsDelete() ) 2511 return; 2512 pWindow->ImplRemoveDel( &aDelData ); 2513 } 2514 // Um falsch gesetzt WB_TABSTOPS immer zu entfernen, nicht 2515 // innerhalb der if-Abfrage 2516 pWindow->mpWindowImpl->mnStyle &= ~WB_TABSTOP; 2517 } 2518 2519 if ( nStyle & WB_GROUP ) 2520 break; 2521 2522 pWindow = pWindow->GetWindow( WINDOW_PREV ); 2523 } 2524 } 2525 2526 pWindow = GetWindow( WINDOW_NEXT ); 2527 while ( pWindow ) 2528 { 2529 nStyle = pWindow->GetStyle(); 2530 2531 if ( nStyle & WB_GROUP ) 2532 break; 2533 2534 if ( pWindow->GetType() == WINDOW_RADIOBUTTON ) 2535 { 2536 if ( ((RadioButton*)pWindow)->IsChecked() ) 2537 { 2538 ImplDelData aDelData; 2539 pWindow->ImplAddDel( &aDelData ); 2540 ((RadioButton*)pWindow)->SetState( sal_False ); 2541 if ( aDelData.IsDelete() ) 2542 return; 2543 pWindow->ImplRemoveDel( &aDelData ); 2544 } 2545 // Um falsch gesetzt WB_TABSTOPS immer zu entfernen, nicht 2546 // innerhalb der if-Abfrage 2547 pWindow->mpWindowImpl->mnStyle &= ~WB_TABSTOP; 2548 } 2549 2550 pWindow = pWindow->GetWindow( WINDOW_NEXT ); 2551 } 2552 } 2553 2554 // ----------------------------------------------------------------------- 2555 2556 void RadioButton::ImplCallClick( sal_Bool bGrabFocus, sal_uInt16 nFocusFlags ) 2557 { 2558 mbStateChanged = !mbChecked; 2559 mbChecked = sal_True; 2560 mpWindowImpl->mnStyle |= WB_TABSTOP; 2561 ImplInvalidateOrDrawRadioButtonState(); 2562 ImplDelData aDelData; 2563 ImplAddDel( &aDelData ); 2564 if ( mbRadioCheck ) 2565 ImplUncheckAllOther(); 2566 if ( aDelData.IsDelete() ) 2567 return; 2568 if ( bGrabFocus ) 2569 ImplGrabFocus( nFocusFlags ); 2570 if ( aDelData.IsDelete() ) 2571 return; 2572 if ( mbStateChanged ) 2573 Toggle(); 2574 if ( aDelData.IsDelete() ) 2575 return; 2576 Click(); 2577 if ( aDelData.IsDelete() ) 2578 return; 2579 ImplRemoveDel( &aDelData ); 2580 mbStateChanged = sal_False; 2581 } 2582 2583 // ----------------------------------------------------------------------- 2584 2585 RadioButton::RadioButton( Window* pParent, WinBits nStyle ) : 2586 Button( WINDOW_RADIOBUTTON ) 2587 { 2588 ImplInitRadioButtonData(); 2589 ImplInit( pParent, nStyle ); 2590 } 2591 2592 // ----------------------------------------------------------------------- 2593 2594 RadioButton::RadioButton( Window* pParent, const ResId& rResId ) : 2595 Button( WINDOW_RADIOBUTTON ) 2596 { 2597 ImplInitRadioButtonData(); 2598 rResId.SetRT( RSC_RADIOBUTTON ); 2599 WinBits nStyle = ImplInitRes( rResId ); 2600 ImplInit( pParent, nStyle ); 2601 ImplLoadRes( rResId ); 2602 2603 if ( !(nStyle & WB_HIDE) ) 2604 Show(); 2605 } 2606 2607 // ----------------------------------------------------------------------- 2608 2609 void RadioButton::ImplLoadRes( const ResId& rResId ) 2610 { 2611 Button::ImplLoadRes( rResId ); 2612 2613 //anderer Wert als Default ? 2614 sal_uInt16 nChecked = ReadShortRes(); 2615 if ( nChecked ) 2616 SetState( sal_True ); 2617 } 2618 2619 // ----------------------------------------------------------------------- 2620 2621 RadioButton::~RadioButton() 2622 { 2623 } 2624 2625 // ----------------------------------------------------------------------- 2626 2627 void RadioButton::MouseButtonDown( const MouseEvent& rMEvt ) 2628 { 2629 if ( rMEvt.IsLeft() && maMouseRect.IsInside( rMEvt.GetPosPixel() ) ) 2630 { 2631 ImplGetButtonState() |= BUTTON_DRAW_PRESSED; 2632 ImplInvalidateOrDrawRadioButtonState(); 2633 StartTracking(); 2634 return; 2635 } 2636 2637 Button::MouseButtonDown( rMEvt ); 2638 } 2639 2640 // ----------------------------------------------------------------------- 2641 2642 void RadioButton::Tracking( const TrackingEvent& rTEvt ) 2643 { 2644 if ( rTEvt.IsTrackingEnded() ) 2645 { 2646 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) 2647 { 2648 if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() ) 2649 GrabFocus(); 2650 2651 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 2652 2653 // Bei Abbruch kein Click-Handler rufen 2654 if ( !rTEvt.IsTrackingCanceled() ) 2655 ImplCallClick(); 2656 else 2657 ImplInvalidateOrDrawRadioButtonState(); 2658 } 2659 } 2660 else 2661 { 2662 if ( maMouseRect.IsInside( rTEvt.GetMouseEvent().GetPosPixel() ) ) 2663 { 2664 if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) ) 2665 { 2666 ImplGetButtonState() |= BUTTON_DRAW_PRESSED; 2667 ImplInvalidateOrDrawRadioButtonState(); 2668 } 2669 } 2670 else 2671 { 2672 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) 2673 { 2674 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 2675 ImplInvalidateOrDrawRadioButtonState(); 2676 } 2677 } 2678 } 2679 } 2680 2681 // ----------------------------------------------------------------------- 2682 2683 void RadioButton::KeyInput( const KeyEvent& rKEvt ) 2684 { 2685 KeyCode aKeyCode = rKEvt.GetKeyCode(); 2686 2687 if ( !aKeyCode.GetModifier() && (aKeyCode.GetCode() == KEY_SPACE) ) 2688 { 2689 if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) ) 2690 { 2691 ImplGetButtonState() |= BUTTON_DRAW_PRESSED; 2692 ImplInvalidateOrDrawRadioButtonState(); 2693 } 2694 } 2695 else if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_ESCAPE) ) 2696 { 2697 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 2698 ImplInvalidateOrDrawRadioButtonState(); 2699 } 2700 else 2701 Button::KeyInput( rKEvt ); 2702 } 2703 2704 // ----------------------------------------------------------------------- 2705 2706 void RadioButton::KeyUp( const KeyEvent& rKEvt ) 2707 { 2708 KeyCode aKeyCode = rKEvt.GetKeyCode(); 2709 2710 if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_SPACE) ) 2711 { 2712 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 2713 ImplCallClick(); 2714 } 2715 else 2716 Button::KeyUp( rKEvt ); 2717 } 2718 2719 // ----------------------------------------------------------------------- 2720 2721 void RadioButton::FillLayoutData() const 2722 { 2723 mpControlData->mpLayoutData = new vcl::ControlLayoutData(); 2724 const_cast<RadioButton*>(this)->ImplDrawRadioButton( true ); 2725 } 2726 2727 // ----------------------------------------------------------------------- 2728 2729 void RadioButton::Paint( const Rectangle& ) 2730 { 2731 ImplDrawRadioButton(); 2732 } 2733 2734 // ----------------------------------------------------------------------- 2735 2736 void RadioButton::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, 2737 sal_uLong nFlags ) 2738 { 2739 if ( !maImage ) 2740 { 2741 MapMode aResMapMode( MAP_100TH_MM ); 2742 Point aPos = pDev->LogicToPixel( rPos ); 2743 Size aSize = pDev->LogicToPixel( rSize ); 2744 Size aImageSize = pDev->LogicToPixel( Size( 300, 300 ), aResMapMode ); 2745 Size aBrd1Size = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode ); 2746 Size aBrd2Size = pDev->LogicToPixel( Size( 60, 60 ), aResMapMode ); 2747 Font aFont = GetDrawPixelFont( pDev ); 2748 Rectangle aStateRect; 2749 Rectangle aMouseRect; 2750 Rectangle aFocusRect; 2751 2752 aImageSize.Width() = CalcZoom( aImageSize.Width() ); 2753 aImageSize.Height() = CalcZoom( aImageSize.Height() ); 2754 aBrd1Size.Width() = CalcZoom( aBrd1Size.Width() ); 2755 aBrd1Size.Height() = CalcZoom( aBrd1Size.Height() ); 2756 aBrd2Size.Width() = CalcZoom( aBrd2Size.Width() ); 2757 aBrd2Size.Height() = CalcZoom( aBrd2Size.Height() ); 2758 2759 if ( !aBrd1Size.Width() ) 2760 aBrd1Size.Width() = 1; 2761 if ( !aBrd1Size.Height() ) 2762 aBrd1Size.Height() = 1; 2763 if ( !aBrd2Size.Width() ) 2764 aBrd2Size.Width() = 1; 2765 if ( !aBrd2Size.Height() ) 2766 aBrd2Size.Height() = 1; 2767 2768 pDev->Push(); 2769 pDev->SetMapMode(); 2770 pDev->SetFont( aFont ); 2771 if ( nFlags & WINDOW_DRAW_MONO ) 2772 pDev->SetTextColor( Color( COL_BLACK ) ); 2773 else 2774 pDev->SetTextColor( GetTextColor() ); 2775 pDev->SetTextFillColor(); 2776 2777 ImplDraw( pDev, nFlags, aPos, aSize, 2778 aImageSize, aStateRect, aMouseRect ); 2779 2780 Point aCenterPos = aStateRect.Center(); 2781 long nRadX = aImageSize.Width()/2; 2782 long nRadY = aImageSize.Height()/2; 2783 2784 pDev->SetLineColor(); 2785 pDev->SetFillColor( Color( COL_BLACK ) ); 2786 pDev->DrawPolygon( Polygon( aCenterPos, nRadX, nRadY ) ); 2787 nRadX -= aBrd1Size.Width(); 2788 nRadY -= aBrd1Size.Height(); 2789 pDev->SetFillColor( Color( COL_WHITE ) ); 2790 pDev->DrawPolygon( Polygon( aCenterPos, nRadX, nRadY ) ); 2791 if ( mbChecked ) 2792 { 2793 nRadX -= aBrd1Size.Width(); 2794 nRadY -= aBrd1Size.Height(); 2795 if ( !nRadX ) 2796 nRadX = 1; 2797 if ( !nRadY ) 2798 nRadY = 1; 2799 pDev->SetFillColor( Color( COL_BLACK ) ); 2800 pDev->DrawPolygon( Polygon( aCenterPos, nRadX, nRadY ) ); 2801 } 2802 2803 pDev->Pop(); 2804 } 2805 else 2806 { 2807 DBG_ERROR( "RadioButton::Draw() - not implemented for RadioButton with Image" ); 2808 } 2809 } 2810 2811 // ----------------------------------------------------------------------- 2812 2813 void RadioButton::Resize() 2814 { 2815 Control::Resize(); 2816 Invalidate(); 2817 } 2818 2819 // ----------------------------------------------------------------------- 2820 2821 void RadioButton::GetFocus() 2822 { 2823 ShowFocus( ImplGetFocusRect() ); 2824 SetInputContext( InputContext( GetFont() ) ); 2825 Button::GetFocus(); 2826 } 2827 2828 // ----------------------------------------------------------------------- 2829 2830 void RadioButton::LoseFocus() 2831 { 2832 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) 2833 { 2834 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 2835 ImplInvalidateOrDrawRadioButtonState(); 2836 } 2837 2838 HideFocus(); 2839 Button::LoseFocus(); 2840 } 2841 2842 // ----------------------------------------------------------------------- 2843 2844 void RadioButton::StateChanged( StateChangedType nType ) 2845 { 2846 Button::StateChanged( nType ); 2847 2848 if ( nType == STATE_CHANGE_STATE ) 2849 { 2850 if ( IsReallyVisible() && IsUpdateMode() ) 2851 Invalidate( maStateRect ); 2852 } 2853 else if ( (nType == STATE_CHANGE_ENABLE) || 2854 (nType == STATE_CHANGE_TEXT) || 2855 (nType == STATE_CHANGE_IMAGE) || 2856 (nType == STATE_CHANGE_DATA) || 2857 (nType == STATE_CHANGE_UPDATEMODE) ) 2858 { 2859 if ( IsUpdateMode() ) 2860 Invalidate(); 2861 } 2862 else if ( nType == STATE_CHANGE_STYLE ) 2863 { 2864 SetStyle( ImplInitStyle( GetWindow( WINDOW_PREV ), GetStyle() ) ); 2865 2866 if ( (GetPrevStyle() & RADIOBUTTON_VIEW_STYLE) != 2867 (GetStyle() & RADIOBUTTON_VIEW_STYLE) ) 2868 { 2869 if ( IsUpdateMode() ) 2870 Invalidate(); 2871 } 2872 } 2873 else if ( (nType == STATE_CHANGE_ZOOM) || 2874 (nType == STATE_CHANGE_CONTROLFONT) ) 2875 { 2876 ImplInitSettings( sal_True, sal_False, sal_False ); 2877 Invalidate(); 2878 } 2879 else if ( nType == STATE_CHANGE_CONTROLFOREGROUND ) 2880 { 2881 ImplInitSettings( sal_False, sal_True, sal_False ); 2882 Invalidate(); 2883 } 2884 else if ( nType == STATE_CHANGE_CONTROLBACKGROUND ) 2885 { 2886 ImplInitSettings( sal_False, sal_False, sal_True ); 2887 Invalidate(); 2888 } 2889 } 2890 2891 // ----------------------------------------------------------------------- 2892 2893 void RadioButton::DataChanged( const DataChangedEvent& rDCEvt ) 2894 { 2895 Button::DataChanged( rDCEvt ); 2896 2897 if ( (rDCEvt.GetType() == DATACHANGED_FONTS) || 2898 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) || 2899 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) && 2900 (rDCEvt.GetFlags() & SETTINGS_STYLE)) ) 2901 { 2902 ImplInitSettings( sal_True, sal_True, sal_True ); 2903 Invalidate(); 2904 } 2905 } 2906 2907 // ----------------------------------------------------------------------- 2908 2909 long RadioButton::PreNotify( NotifyEvent& rNEvt ) 2910 { 2911 long nDone = 0; 2912 const MouseEvent* pMouseEvt = NULL; 2913 2914 if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL ) 2915 { 2916 if( !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() ) 2917 { 2918 // trigger redraw if mouse over state has changed 2919 if( IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL) ) 2920 { 2921 if( ( maMouseRect.IsInside( GetPointerPosPixel()) && 2922 !maMouseRect.IsInside( GetLastPointerPosPixel()) ) || 2923 ( maMouseRect.IsInside( GetLastPointerPosPixel()) && 2924 !maMouseRect.IsInside( GetPointerPosPixel()) ) || 2925 pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow() ) 2926 { 2927 Invalidate( maStateRect ); 2928 } 2929 } 2930 } 2931 } 2932 2933 return nDone ? nDone : Button::PreNotify(rNEvt); 2934 } 2935 2936 // ----------------------------------------------------------------------- 2937 2938 void RadioButton::Toggle() 2939 { 2940 ImplCallEventListenersAndHandler( VCLEVENT_RADIOBUTTON_TOGGLE, maToggleHdl, this ); 2941 } 2942 2943 // ----------------------------------------------------------------------- 2944 2945 sal_Bool RadioButton::SetModeRadioImage( const Image& rImage, BmpColorMode eMode ) 2946 { 2947 if( eMode == BMP_COLOR_NORMAL ) 2948 { 2949 if ( rImage != maImage ) 2950 { 2951 maImage = rImage; 2952 StateChanged( STATE_CHANGE_DATA ); 2953 } 2954 } 2955 else if( eMode == BMP_COLOR_HIGHCONTRAST ) 2956 { 2957 if( maImageHC != rImage ) 2958 { 2959 maImageHC = rImage; 2960 StateChanged( STATE_CHANGE_DATA ); 2961 } 2962 } 2963 else 2964 return sal_False; 2965 2966 return sal_True; 2967 } 2968 2969 // ----------------------------------------------------------------------- 2970 2971 const Image& RadioButton::GetModeRadioImage( BmpColorMode eMode ) const 2972 { 2973 if( eMode == BMP_COLOR_HIGHCONTRAST ) 2974 return maImageHC; 2975 else 2976 return maImage; 2977 } 2978 2979 // ----------------------------------------------------------------------- 2980 2981 void RadioButton::SetState( sal_Bool bCheck ) 2982 { 2983 // TabStop-Flag richtig mitfuehren 2984 if ( bCheck ) 2985 mpWindowImpl->mnStyle |= WB_TABSTOP; 2986 else 2987 mpWindowImpl->mnStyle &= ~WB_TABSTOP; 2988 2989 if ( mbChecked != bCheck ) 2990 { 2991 mbChecked = bCheck; 2992 StateChanged( STATE_CHANGE_STATE ); 2993 Toggle(); 2994 } 2995 } 2996 2997 // ----------------------------------------------------------------------- 2998 2999 void RadioButton::Check( sal_Bool bCheck ) 3000 { 3001 // TabStop-Flag richtig mitfuehren 3002 if ( bCheck ) 3003 mpWindowImpl->mnStyle |= WB_TABSTOP; 3004 else 3005 mpWindowImpl->mnStyle &= ~WB_TABSTOP; 3006 3007 if ( mbChecked != bCheck ) 3008 { 3009 mbChecked = bCheck; 3010 ImplDelData aDelData; 3011 ImplAddDel( &aDelData ); 3012 StateChanged( STATE_CHANGE_STATE ); 3013 if ( aDelData.IsDelete() ) 3014 return; 3015 if ( bCheck && mbRadioCheck ) 3016 ImplUncheckAllOther(); 3017 if ( aDelData.IsDelete() ) 3018 return; 3019 Toggle(); 3020 ImplRemoveDel( &aDelData ); 3021 } 3022 } 3023 3024 // ----------------------------------------------------------------------- 3025 3026 long RadioButton::ImplGetImageToTextDistance() const 3027 { 3028 // 4 pixels, but take zoom into account, so the text doesn't "jump" relative to surrounding elements, 3029 // which might have been aligned with the text of the check box 3030 return CalcZoom( 4 ); 3031 } 3032 3033 // ----------------------------------------------------------------------- 3034 3035 Size RadioButton::ImplGetRadioImageSize() const 3036 { 3037 Size aSize; 3038 // why are IsNativeControlSupported and GetNativeControlRegion not const ? 3039 RadioButton* pThis = const_cast<RadioButton*>(this); 3040 bool bDefaultSize = true; 3041 if( pThis->IsNativeControlSupported( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL ) ) 3042 { 3043 ImplControlValue aControlValue; 3044 // #i45896# workaround gcc3.3 temporary problem 3045 Rectangle aCtrlRegion( Point( 0, 0 ), GetSizePixel() ); 3046 ControlState nState = CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED; 3047 Rectangle aBoundingRgn, aContentRgn; 3048 3049 // get native size of a radio button 3050 if( pThis->GetNativeControlRegion( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion, 3051 nState, aControlValue, rtl::OUString(), 3052 aBoundingRgn, aContentRgn ) ) 3053 { 3054 aSize = aContentRgn.GetSize(); 3055 bDefaultSize = false; 3056 } 3057 } 3058 if( bDefaultSize ) 3059 aSize = GetRadioImage( GetSettings(), 0 ).GetSizePixel(); 3060 return aSize; 3061 } 3062 3063 static void LoadThemedImageList (const StyleSettings &rStyleSettings, 3064 ImageList *pList, const ResId &rResId, 3065 sal_uInt16 nImages) 3066 { 3067 Color aColorAry1[6]; 3068 Color aColorAry2[6]; 3069 aColorAry1[0] = Color( 0xC0, 0xC0, 0xC0 ); 3070 aColorAry1[1] = Color( 0xFF, 0xFF, 0x00 ); 3071 aColorAry1[2] = Color( 0xFF, 0xFF, 0xFF ); 3072 aColorAry1[3] = Color( 0x80, 0x80, 0x80 ); 3073 aColorAry1[4] = Color( 0x00, 0x00, 0x00 ); 3074 aColorAry1[5] = Color( 0x00, 0xFF, 0x00 ); 3075 aColorAry2[0] = rStyleSettings.GetFaceColor(); 3076 aColorAry2[1] = rStyleSettings.GetWindowColor(); 3077 aColorAry2[2] = rStyleSettings.GetLightColor(); 3078 aColorAry2[3] = rStyleSettings.GetShadowColor(); 3079 aColorAry2[4] = rStyleSettings.GetDarkShadowColor(); 3080 aColorAry2[5] = rStyleSettings.GetWindowTextColor(); 3081 3082 Color aMaskColor(0x00, 0x00, 0xFF ); 3083 DBG_ASSERT( sizeof(aColorAry1) == sizeof(aColorAry2), "aColorAry1 must match aColorAry2" ); 3084 // FIXME: do we want the mask for the checkbox ? 3085 pList->InsertFromHorizontalBitmap (rResId, nImages, &aMaskColor, 3086 aColorAry1, aColorAry2, sizeof(aColorAry1) / sizeof(Color)); 3087 } 3088 3089 Image RadioButton::GetRadioImage( const AllSettings& rSettings, sal_uInt16 nFlags ) 3090 { 3091 ImplSVData* pSVData = ImplGetSVData(); 3092 const StyleSettings& rStyleSettings = rSettings.GetStyleSettings(); 3093 sal_uInt16 nStyle = 0; 3094 3095 if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO ) 3096 nStyle = STYLE_RADIOBUTTON_MONO; 3097 3098 if ( !pSVData->maCtrlData.mpRadioImgList || 3099 (pSVData->maCtrlData.mnRadioStyle != nStyle) || 3100 (pSVData->maCtrlData.mnLastRadioFColor != rStyleSettings.GetFaceColor().GetColor()) || 3101 (pSVData->maCtrlData.mnLastRadioWColor != rStyleSettings.GetWindowColor().GetColor()) || 3102 (pSVData->maCtrlData.mnLastRadioLColor != rStyleSettings.GetLightColor().GetColor()) ) 3103 { 3104 if ( pSVData->maCtrlData.mpRadioImgList ) 3105 delete pSVData->maCtrlData.mpRadioImgList; 3106 3107 pSVData->maCtrlData.mnLastRadioFColor = rStyleSettings.GetFaceColor().GetColor(); 3108 pSVData->maCtrlData.mnLastRadioWColor = rStyleSettings.GetWindowColor().GetColor(); 3109 pSVData->maCtrlData.mnLastRadioLColor = rStyleSettings.GetLightColor().GetColor(); 3110 3111 Color pColorAry1[6]; 3112 Color pColorAry2[6]; 3113 pColorAry1[0] = Color( 0xC0, 0xC0, 0xC0 ); 3114 pColorAry1[1] = Color( 0xFF, 0xFF, 0x00 ); 3115 pColorAry1[2] = Color( 0xFF, 0xFF, 0xFF ); 3116 pColorAry1[3] = Color( 0x80, 0x80, 0x80 ); 3117 pColorAry1[4] = Color( 0x00, 0x00, 0x00 ); 3118 pColorAry1[5] = Color( 0x00, 0xFF, 0x00 ); 3119 pColorAry2[0] = rStyleSettings.GetFaceColor(); 3120 pColorAry2[1] = rStyleSettings.GetWindowColor(); 3121 pColorAry2[2] = rStyleSettings.GetLightColor(); 3122 pColorAry2[3] = rStyleSettings.GetShadowColor(); 3123 pColorAry2[4] = rStyleSettings.GetDarkShadowColor(); 3124 pColorAry2[5] = rStyleSettings.GetWindowTextColor(); 3125 3126 ResMgr* pResMgr = ImplGetResMgr(); 3127 pSVData->maCtrlData.mpRadioImgList = new ImageList(); 3128 if( pResMgr ) 3129 LoadThemedImageList( rStyleSettings, 3130 pSVData->maCtrlData.mpRadioImgList, 3131 ResId( SV_RESID_BITMAP_RADIO+nStyle, *pResMgr ), 6 ); 3132 pSVData->maCtrlData.mnRadioStyle = nStyle; 3133 } 3134 3135 sal_uInt16 nId; 3136 if ( nFlags & BUTTON_DRAW_DISABLED ) 3137 { 3138 if ( nFlags & BUTTON_DRAW_CHECKED ) 3139 nId = 6; 3140 else 3141 nId = 5; 3142 } 3143 else if ( nFlags & BUTTON_DRAW_PRESSED ) 3144 { 3145 if ( nFlags & BUTTON_DRAW_CHECKED ) 3146 nId = 4; 3147 else 3148 nId = 3; 3149 } 3150 else 3151 { 3152 if ( nFlags & BUTTON_DRAW_CHECKED ) 3153 nId = 2; 3154 else 3155 nId = 1; 3156 } 3157 return pSVData->maCtrlData.mpRadioImgList->GetImage( nId ); 3158 } 3159 3160 // ----------------------------------------------------------------------- 3161 3162 void RadioButton::ImplSetMinimumNWFSize() 3163 { 3164 Push( PUSH_MAPMODE ); 3165 SetMapMode( MAP_PIXEL ); 3166 3167 ImplControlValue aControlValue; 3168 Size aCurSize( GetSizePixel() ); 3169 Rectangle aCtrlRegion( Point( 0, 0 ), aCurSize ); 3170 Rectangle aBoundingRgn, aContentRgn; 3171 3172 // get native size of a radiobutton 3173 if( GetNativeControlRegion( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion, 3174 CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED, aControlValue, rtl::OUString(), 3175 aBoundingRgn, aContentRgn ) ) 3176 { 3177 Size aSize = aContentRgn.GetSize(); 3178 3179 if( aSize.Height() > aCurSize.Height() ) 3180 { 3181 aCurSize.Height() = aSize.Height(); 3182 SetSizePixel( aCurSize ); 3183 } 3184 } 3185 3186 Pop(); 3187 } 3188 3189 // ----------------------------------------------------------------------- 3190 3191 Size RadioButton::CalcMinimumSize( long nMaxWidth ) const 3192 { 3193 Size aSize; 3194 if ( !maImage ) 3195 aSize = ImplGetRadioImageSize(); 3196 else 3197 aSize = maImage.GetSizePixel(); 3198 3199 nMaxWidth -= aSize.Width(); 3200 3201 XubString aText = GetText(); 3202 if ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) ) 3203 { 3204 // subtract what will be added later 3205 nMaxWidth-=2; 3206 nMaxWidth -= ImplGetImageToTextDistance(); 3207 3208 Size aTextSize = GetTextRect( Rectangle( Point(), Size( nMaxWidth > 0 ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ), 3209 aText, FixedText::ImplGetTextStyle( GetStyle() ) ).GetSize(); 3210 aSize.Width()+=2; // for focus rect 3211 aSize.Width() += ImplGetImageToTextDistance(); 3212 aSize.Width() += aTextSize.Width(); 3213 if ( aSize.Height() < aTextSize.Height() ) 3214 aSize.Height() = aTextSize.Height(); 3215 } 3216 else if ( !maImage ) 3217 { 3218 /* da ansonsten im Writer die Control zu weit oben haengen 3219 aSize.Width() += 2; 3220 aSize.Height() += 2; 3221 */ 3222 } 3223 3224 return CalcWindowSize( aSize ); 3225 } 3226 3227 // ----------------------------------------------------------------------- 3228 3229 Size RadioButton::GetOptimalSize(WindowSizeType eType) const 3230 { 3231 switch (eType) { 3232 case WINDOWSIZE_MINIMUM: 3233 return CalcMinimumSize(); 3234 default: 3235 return Button::GetOptimalSize( eType ); 3236 } 3237 } 3238 3239 // ======================================================================= 3240 3241 void CheckBox::ImplInitCheckBoxData() 3242 { 3243 meState = STATE_NOCHECK; 3244 meSaveValue = STATE_NOCHECK; 3245 mbTriState = sal_False; 3246 } 3247 3248 // ----------------------------------------------------------------------- 3249 3250 void CheckBox::ImplInit( Window* pParent, WinBits nStyle ) 3251 { 3252 nStyle = ImplInitStyle( pParent->GetWindow( WINDOW_LASTCHILD ), nStyle ); 3253 Button::ImplInit( pParent, nStyle, NULL ); 3254 3255 ImplInitSettings( sal_True, sal_True, sal_True ); 3256 } 3257 3258 // ----------------------------------------------------------------------- 3259 3260 WinBits CheckBox::ImplInitStyle( const Window* pPrevWindow, WinBits nStyle ) 3261 { 3262 if ( !(nStyle & WB_NOTABSTOP) ) 3263 nStyle |= WB_TABSTOP; 3264 if ( !(nStyle & WB_NOGROUP) && 3265 (!pPrevWindow || (pPrevWindow->GetType() != WINDOW_CHECKBOX)) ) 3266 nStyle |= WB_GROUP; 3267 return nStyle; 3268 } 3269 3270 // ----------------------------------------------------------------- 3271 3272 const Font& CheckBox::GetCanonicalFont( const StyleSettings& _rStyle ) const 3273 { 3274 return _rStyle.GetRadioCheckFont(); 3275 } 3276 3277 // ----------------------------------------------------------------- 3278 const Color& CheckBox::GetCanonicalTextColor( const StyleSettings& _rStyle ) const 3279 { 3280 return _rStyle.GetRadioCheckTextColor(); 3281 } 3282 3283 // ----------------------------------------------------------------------- 3284 3285 void CheckBox::ImplInitSettings( sal_Bool bFont, 3286 sal_Bool bForeground, sal_Bool bBackground ) 3287 { 3288 Button::ImplInitSettings( bFont, bForeground ); 3289 3290 if ( bBackground ) 3291 { 3292 Window* pParent = GetParent(); 3293 if ( !IsControlBackground() && 3294 (pParent->IsChildTransparentModeEnabled() || IsNativeControlSupported( CTRL_CHECKBOX, PART_ENTIRE_CONTROL ) ) ) 3295 { 3296 EnableChildTransparentMode( sal_True ); 3297 SetParentClipMode( PARENTCLIPMODE_NOCLIP ); 3298 SetPaintTransparent( sal_True ); 3299 SetBackground(); 3300 if( IsNativeControlSupported( CTRL_CHECKBOX, PART_ENTIRE_CONTROL ) ) 3301 ImplGetWindowImpl()->mbUseNativeFocus = ImplGetSVData()->maNWFData.mbNoFocusRects; 3302 } 3303 else 3304 { 3305 EnableChildTransparentMode( sal_False ); 3306 SetParentClipMode( 0 ); 3307 SetPaintTransparent( sal_False ); 3308 3309 if ( IsControlBackground() ) 3310 SetBackground( GetControlBackground() ); 3311 else 3312 SetBackground( pParent->GetBackground() ); 3313 } 3314 } 3315 } 3316 3317 // ----------------------------------------------------------------------- 3318 3319 void CheckBox::ImplLoadRes( const ResId& rResId ) 3320 { 3321 Button::ImplLoadRes( rResId ); 3322 3323 if ( rResId.GetRT() != RSC_TRISTATEBOX ) 3324 { 3325 sal_uInt16 nChecked = ReadShortRes(); 3326 //anderer Wert als Default ? 3327 if( nChecked ) 3328 Check( sal_True ); 3329 } 3330 } 3331 3332 // ----------------------------------------------------------------------- 3333 3334 void CheckBox::ImplInvalidateOrDrawCheckBoxState() 3335 { 3336 if( ImplGetSVData()->maNWFData.mbCheckBoxNeedsErase ) 3337 { 3338 if ( IsNativeControlSupported(CTRL_CHECKBOX, PART_ENTIRE_CONTROL) ) 3339 { 3340 Invalidate(); 3341 Update(); 3342 return; 3343 } 3344 } 3345 ImplDrawCheckBoxState(); 3346 } 3347 3348 void CheckBox::ImplDrawCheckBoxState() 3349 { 3350 bool bNativeOK = sal_True; 3351 3352 if ( (bNativeOK=IsNativeControlSupported(CTRL_CHECKBOX, PART_ENTIRE_CONTROL)) == sal_True ) 3353 { 3354 ImplControlValue aControlValue( meState == STATE_CHECK ? BUTTONVALUE_ON : BUTTONVALUE_OFF ); 3355 Rectangle aCtrlRegion( maStateRect ); 3356 ControlState nState = 0; 3357 3358 if ( HasFocus() ) nState |= CTRL_STATE_FOCUSED; 3359 if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT ) nState |= CTRL_STATE_DEFAULT; 3360 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) nState |= CTRL_STATE_PRESSED; 3361 if ( IsEnabled() ) nState |= CTRL_STATE_ENABLED; 3362 3363 if ( meState == STATE_CHECK ) 3364 aControlValue.setTristateVal( BUTTONVALUE_ON ); 3365 else if ( meState == STATE_DONTKNOW ) 3366 aControlValue.setTristateVal( BUTTONVALUE_MIXED ); 3367 3368 if ( IsMouseOver() && maMouseRect.IsInside( GetPointerPosPixel() ) ) 3369 nState |= CTRL_STATE_ROLLOVER; 3370 3371 bNativeOK = DrawNativeControl( CTRL_CHECKBOX, PART_ENTIRE_CONTROL, aCtrlRegion, nState, 3372 aControlValue, rtl::OUString() ); 3373 } 3374 3375 if ( bNativeOK == sal_False ) 3376 { 3377 sal_uInt16 nStyle = ImplGetButtonState(); 3378 if ( !IsEnabled() ) 3379 nStyle |= BUTTON_DRAW_DISABLED; 3380 if ( meState == STATE_DONTKNOW ) 3381 nStyle |= BUTTON_DRAW_DONTKNOW; 3382 else if ( meState == STATE_CHECK ) 3383 nStyle |= BUTTON_DRAW_CHECKED; 3384 Image aImage = GetCheckImage( GetSettings(), nStyle ); 3385 if ( IsZoom() ) 3386 DrawImage( maStateRect.TopLeft(), maStateRect.GetSize(), aImage ); 3387 else 3388 DrawImage( maStateRect.TopLeft(), aImage ); 3389 } 3390 } 3391 3392 // ----------------------------------------------------------------------- 3393 3394 void CheckBox::ImplDraw( OutputDevice* pDev, sal_uLong nDrawFlags, 3395 const Point& rPos, const Size& rSize, 3396 const Size& rImageSize, Rectangle& rStateRect, 3397 Rectangle& rMouseRect, bool bLayout ) 3398 { 3399 WinBits nWinStyle = GetStyle(); 3400 XubString aText( GetText() ); 3401 3402 pDev->Push( PUSH_CLIPREGION | PUSH_LINECOLOR ); 3403 pDev->IntersectClipRegion( Rectangle( rPos, rSize ) ); 3404 3405 long nLineY = rPos.Y() + (rSize.Height()-1)/2; 3406 if ( ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) ) || 3407 ( HasImage() && ! (ImplGetButtonState() & BUTTON_DRAW_NOIMAGE) ) ) 3408 { 3409 sal_uInt16 nTextStyle = Button::ImplGetTextStyle( aText, nWinStyle, nDrawFlags ); 3410 3411 const long nImageSep = GetDrawPixel( pDev, ImplGetImageToTextDistance() ); 3412 Size aSize( rSize ); 3413 Point aPos( rPos ); 3414 aPos.X() += rImageSize.Width() + nImageSep; 3415 aSize.Width() -= rImageSize.Width() + nImageSep; 3416 3417 // if the text rect height is smaller than the height of the image 3418 // then for single lines the default should be centered text 3419 if( (nWinStyle & (WB_TOP|WB_VCENTER|WB_BOTTOM)) == 0 && 3420 (rImageSize.Height() > rSize.Height() || ! (nWinStyle & WB_WORDBREAK) ) ) 3421 { 3422 nTextStyle &= ~(TEXT_DRAW_TOP|TEXT_DRAW_BOTTOM); 3423 nTextStyle |= TEXT_DRAW_VCENTER; 3424 aSize.Height() = rImageSize.Height(); 3425 } 3426 3427 ImplDrawAlignedImage( pDev, aPos, aSize, bLayout, 1, 3428 nDrawFlags, nTextStyle, NULL ); 3429 nLineY = aPos.Y() + aSize.Height()/2; 3430 3431 rMouseRect = Rectangle( aPos, aSize ); 3432 rMouseRect.Left() = rPos.X(); 3433 rStateRect.Left() = rPos.X(); 3434 rStateRect.Top() = rMouseRect.Top(); 3435 3436 if ( aSize.Height() > rImageSize.Height() ) 3437 rStateRect.Top() += ( aSize.Height() - rImageSize.Height() ) / 2; 3438 else 3439 { 3440 rStateRect.Top() -= ( rImageSize.Height() - aSize.Height() ) / 2; 3441 if( rStateRect.Top() < 0 ) 3442 rStateRect.Top() = 0; 3443 } 3444 3445 rStateRect.Right() = rStateRect.Left()+rImageSize.Width()-1; 3446 rStateRect.Bottom() = rStateRect.Top()+rImageSize.Height()-1; 3447 if ( rStateRect.Bottom() > rMouseRect.Bottom() ) 3448 rMouseRect.Bottom() = rStateRect.Bottom(); 3449 } 3450 else 3451 { 3452 if ( nWinStyle & WB_CENTER ) 3453 rStateRect.Left() = rPos.X()+((rSize.Width()-rImageSize.Width())/2); 3454 else if ( nWinStyle & WB_RIGHT ) 3455 rStateRect.Left() = rPos.X()+rSize.Width()-rImageSize.Width(); 3456 else 3457 rStateRect.Left() = rPos.X(); 3458 if ( nWinStyle & WB_VCENTER ) 3459 rStateRect.Top() = rPos.Y()+((rSize.Height()-rImageSize.Height())/2); 3460 else if ( nWinStyle & WB_BOTTOM ) 3461 rStateRect.Top() = rPos.Y()+rSize.Height()-rImageSize.Height(); 3462 else 3463 rStateRect.Top() = rPos.Y(); 3464 rStateRect.Right() = rStateRect.Left()+rImageSize.Width()-1; 3465 rStateRect.Bottom() = rStateRect.Top()+rImageSize.Height()-1; 3466 // provide space for focusrect 3467 // note: this assumes that the control's size was adjusted 3468 // accordingly in Get/LoseFocus, so the onscreen position won't change 3469 if( HasFocus() ) 3470 rStateRect.Move( 1, 1 ); 3471 rMouseRect = rStateRect; 3472 3473 ImplSetFocusRect( rStateRect ); 3474 } 3475 3476 const int nLineSpace = 4; 3477 if( (GetStyle() & WB_CBLINESTYLE) != 0 && 3478 rMouseRect.Right()-1-nLineSpace < rPos.X()+rSize.Width() ) 3479 { 3480 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 3481 if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO ) 3482 SetLineColor( Color( COL_BLACK ) ); 3483 else 3484 SetLineColor( rStyleSettings.GetShadowColor() ); 3485 long nLineX = rMouseRect.Right()+nLineSpace; 3486 DrawLine( Point( nLineX, nLineY ), Point( rPos.X() + rSize.Width()-1, nLineY ) ); 3487 if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) ) 3488 { 3489 SetLineColor( rStyleSettings.GetLightColor() ); 3490 DrawLine( Point( nLineX, nLineY+1 ), Point( rPos.X() + rSize.Width()-1, nLineY+1 ) ); 3491 } 3492 } 3493 3494 pDev->Pop(); 3495 } 3496 3497 // ----------------------------------------------------------------------- 3498 3499 void CheckBox::ImplDrawCheckBox( bool bLayout ) 3500 { 3501 Size aImageSize = ImplGetCheckImageSize(); 3502 aImageSize.Width() = CalcZoom( aImageSize.Width() ); 3503 aImageSize.Height() = CalcZoom( aImageSize.Height() ); 3504 3505 if( !bLayout ) 3506 HideFocus(); 3507 3508 ImplDraw( this, 0, Point(), GetOutputSizePixel(), aImageSize, 3509 maStateRect, maMouseRect, bLayout ); 3510 3511 if( !bLayout ) 3512 { 3513 ImplDrawCheckBoxState(); 3514 if ( HasFocus() ) 3515 ShowFocus( ImplGetFocusRect() ); 3516 } 3517 } 3518 3519 // ----------------------------------------------------------------------- 3520 3521 void CheckBox::ImplCheck() 3522 { 3523 TriState eNewState; 3524 if ( meState == STATE_NOCHECK ) 3525 eNewState = STATE_CHECK; 3526 else if ( !mbTriState ) 3527 eNewState = STATE_NOCHECK; 3528 else if ( meState == STATE_CHECK ) 3529 eNewState = STATE_DONTKNOW; 3530 else 3531 eNewState = STATE_NOCHECK; 3532 meState = eNewState; 3533 3534 ImplDelData aDelData; 3535 ImplAddDel( &aDelData ); 3536 if( (GetStyle() & WB_EARLYTOGGLE) ) 3537 Toggle(); 3538 ImplInvalidateOrDrawCheckBoxState(); 3539 if( ! (GetStyle() & WB_EARLYTOGGLE) ) 3540 Toggle(); 3541 if ( aDelData.IsDelete() ) 3542 return; 3543 ImplRemoveDel( &aDelData ); 3544 Click(); 3545 } 3546 3547 // ----------------------------------------------------------------------- 3548 3549 CheckBox::CheckBox( Window* pParent, WinBits nStyle ) : 3550 Button( WINDOW_CHECKBOX ) 3551 { 3552 ImplInitCheckBoxData(); 3553 ImplInit( pParent, nStyle ); 3554 } 3555 3556 // ----------------------------------------------------------------------- 3557 3558 CheckBox::CheckBox( Window* pParent, const ResId& rResId ) : 3559 Button( WINDOW_CHECKBOX ) 3560 { 3561 ImplInitCheckBoxData(); 3562 rResId.SetRT( RSC_CHECKBOX ); 3563 WinBits nStyle = ImplInitRes( rResId ); 3564 ImplInit( pParent, nStyle ); 3565 ImplLoadRes( rResId ); 3566 3567 if ( !(nStyle & WB_HIDE) ) 3568 Show(); 3569 } 3570 3571 // ----------------------------------------------------------------------- 3572 3573 void CheckBox::MouseButtonDown( const MouseEvent& rMEvt ) 3574 { 3575 if ( rMEvt.IsLeft() && maMouseRect.IsInside( rMEvt.GetPosPixel() ) ) 3576 { 3577 ImplGetButtonState() |= BUTTON_DRAW_PRESSED; 3578 ImplInvalidateOrDrawCheckBoxState(); 3579 StartTracking(); 3580 return; 3581 } 3582 3583 Button::MouseButtonDown( rMEvt ); 3584 } 3585 3586 // ----------------------------------------------------------------------- 3587 3588 void CheckBox::Tracking( const TrackingEvent& rTEvt ) 3589 { 3590 if ( rTEvt.IsTrackingEnded() ) 3591 { 3592 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) 3593 { 3594 if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() ) 3595 GrabFocus(); 3596 3597 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 3598 3599 // Bei Abbruch kein Click-Handler rufen 3600 if ( !rTEvt.IsTrackingCanceled() ) 3601 ImplCheck(); 3602 else 3603 ImplInvalidateOrDrawCheckBoxState(); 3604 } 3605 } 3606 else 3607 { 3608 if ( maMouseRect.IsInside( rTEvt.GetMouseEvent().GetPosPixel() ) ) 3609 { 3610 if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) ) 3611 { 3612 ImplGetButtonState() |= BUTTON_DRAW_PRESSED; 3613 ImplInvalidateOrDrawCheckBoxState(); 3614 } 3615 } 3616 else 3617 { 3618 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) 3619 { 3620 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 3621 ImplInvalidateOrDrawCheckBoxState(); 3622 } 3623 } 3624 } 3625 } 3626 3627 // ----------------------------------------------------------------------- 3628 3629 void CheckBox::KeyInput( const KeyEvent& rKEvt ) 3630 { 3631 KeyCode aKeyCode = rKEvt.GetKeyCode(); 3632 3633 if ( !aKeyCode.GetModifier() && (aKeyCode.GetCode() == KEY_SPACE) ) 3634 { 3635 if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) ) 3636 { 3637 ImplGetButtonState() |= BUTTON_DRAW_PRESSED; 3638 ImplInvalidateOrDrawCheckBoxState(); 3639 } 3640 } 3641 else if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_ESCAPE) ) 3642 { 3643 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 3644 ImplInvalidateOrDrawCheckBoxState(); 3645 } 3646 else 3647 Button::KeyInput( rKEvt ); 3648 } 3649 3650 // ----------------------------------------------------------------------- 3651 3652 void CheckBox::KeyUp( const KeyEvent& rKEvt ) 3653 { 3654 KeyCode aKeyCode = rKEvt.GetKeyCode(); 3655 3656 if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_SPACE) ) 3657 { 3658 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 3659 ImplCheck(); 3660 } 3661 else 3662 Button::KeyUp( rKEvt ); 3663 } 3664 3665 // ----------------------------------------------------------------------- 3666 3667 void CheckBox::FillLayoutData() const 3668 { 3669 mpControlData->mpLayoutData = new vcl::ControlLayoutData(); 3670 const_cast<CheckBox*>(this)->ImplDrawCheckBox( true ); 3671 } 3672 3673 // ----------------------------------------------------------------------- 3674 3675 void CheckBox::Paint( const Rectangle& ) 3676 { 3677 ImplDrawCheckBox(); 3678 } 3679 3680 // ----------------------------------------------------------------------- 3681 3682 void CheckBox::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, 3683 sal_uLong nFlags ) 3684 { 3685 MapMode aResMapMode( MAP_100TH_MM ); 3686 Point aPos = pDev->LogicToPixel( rPos ); 3687 Size aSize = pDev->LogicToPixel( rSize ); 3688 Size aImageSize = pDev->LogicToPixel( Size( 300, 300 ), aResMapMode ); 3689 Size aBrd1Size = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode ); 3690 Size aBrd2Size = pDev->LogicToPixel( Size( 30, 30 ), aResMapMode ); 3691 long nCheckWidth = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode ).Width(); 3692 Font aFont = GetDrawPixelFont( pDev ); 3693 Rectangle aStateRect; 3694 Rectangle aMouseRect; 3695 3696 aImageSize.Width() = CalcZoom( aImageSize.Width() ); 3697 aImageSize.Height() = CalcZoom( aImageSize.Height() ); 3698 aBrd1Size.Width() = CalcZoom( aBrd1Size.Width() ); 3699 aBrd1Size.Height() = CalcZoom( aBrd1Size.Height() ); 3700 aBrd2Size.Width() = CalcZoom( aBrd2Size.Width() ); 3701 aBrd2Size.Height() = CalcZoom( aBrd2Size.Height() ); 3702 3703 if ( !aBrd1Size.Width() ) 3704 aBrd1Size.Width() = 1; 3705 if ( !aBrd1Size.Height() ) 3706 aBrd1Size.Height() = 1; 3707 if ( !aBrd2Size.Width() ) 3708 aBrd2Size.Width() = 1; 3709 if ( !aBrd2Size.Height() ) 3710 aBrd2Size.Height() = 1; 3711 if ( !nCheckWidth ) 3712 nCheckWidth = 1; 3713 3714 pDev->Push(); 3715 pDev->SetMapMode(); 3716 pDev->SetFont( aFont ); 3717 if ( nFlags & WINDOW_DRAW_MONO ) 3718 pDev->SetTextColor( Color( COL_BLACK ) ); 3719 else 3720 pDev->SetTextColor( GetTextColor() ); 3721 pDev->SetTextFillColor(); 3722 3723 ImplDraw( pDev, nFlags, aPos, aSize, 3724 aImageSize, aStateRect, aMouseRect, false ); 3725 3726 pDev->SetLineColor(); 3727 pDev->SetFillColor( Color( COL_BLACK ) ); 3728 pDev->DrawRect( aStateRect ); 3729 aStateRect.Left() += aBrd1Size.Width(); 3730 aStateRect.Top() += aBrd1Size.Height(); 3731 aStateRect.Right() -= aBrd1Size.Width(); 3732 aStateRect.Bottom() -= aBrd1Size.Height(); 3733 if ( meState == STATE_DONTKNOW ) 3734 pDev->SetFillColor( Color( COL_LIGHTGRAY ) ); 3735 else 3736 pDev->SetFillColor( Color( COL_WHITE ) ); 3737 pDev->DrawRect( aStateRect ); 3738 3739 if ( meState == STATE_CHECK ) 3740 { 3741 aStateRect.Left() += aBrd2Size.Width(); 3742 aStateRect.Top() += aBrd2Size.Height(); 3743 aStateRect.Right() -= aBrd2Size.Width(); 3744 aStateRect.Bottom() -= aBrd2Size.Height(); 3745 Point aPos11( aStateRect.TopLeft() ); 3746 Point aPos12( aStateRect.BottomRight() ); 3747 Point aPos21( aStateRect.TopRight() ); 3748 Point aPos22( aStateRect.BottomLeft() ); 3749 Point aTempPos11( aPos11 ); 3750 Point aTempPos12( aPos12 ); 3751 Point aTempPos21( aPos21 ); 3752 Point aTempPos22( aPos22 ); 3753 pDev->SetLineColor( Color( COL_BLACK ) ); 3754 long nDX = 0; 3755 for ( long i = 0; i < nCheckWidth; i++ ) 3756 { 3757 if ( !(i % 2) ) 3758 { 3759 aTempPos11.X() = aPos11.X()+nDX; 3760 aTempPos12.X() = aPos12.X()+nDX; 3761 aTempPos21.X() = aPos21.X()+nDX; 3762 aTempPos22.X() = aPos22.X()+nDX; 3763 } 3764 else 3765 { 3766 nDX++; 3767 aTempPos11.X() = aPos11.X()-nDX; 3768 aTempPos12.X() = aPos12.X()-nDX; 3769 aTempPos21.X() = aPos21.X()-nDX; 3770 aTempPos22.X() = aPos22.X()-nDX; 3771 } 3772 pDev->DrawLine( aTempPos11, aTempPos12 ); 3773 pDev->DrawLine( aTempPos21, aTempPos22 ); 3774 } 3775 } 3776 3777 pDev->Pop(); 3778 } 3779 3780 // ----------------------------------------------------------------------- 3781 3782 void CheckBox::Resize() 3783 { 3784 Control::Resize(); 3785 Invalidate(); 3786 } 3787 3788 // ----------------------------------------------------------------------- 3789 3790 void CheckBox::GetFocus() 3791 { 3792 if ( !GetText().Len() || (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) ) 3793 { 3794 // increase button size to have space for focus rect 3795 // checkboxes without text will draw focusrect around the check 3796 // See CheckBox::ImplDraw() 3797 Point aPos( GetPosPixel() ); 3798 Size aSize( GetSizePixel() ); 3799 aPos.Move(-1,-1); 3800 aSize.Height() += 2; 3801 aSize.Width() += 2; 3802 SetPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height(), WINDOW_POSSIZE_ALL ); 3803 ImplDrawCheckBox(); 3804 } 3805 else 3806 ShowFocus( ImplGetFocusRect() ); 3807 3808 SetInputContext( InputContext( GetFont() ) ); 3809 Button::GetFocus(); 3810 } 3811 3812 // ----------------------------------------------------------------------- 3813 3814 void CheckBox::LoseFocus() 3815 { 3816 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) 3817 { 3818 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 3819 ImplInvalidateOrDrawCheckBoxState(); 3820 } 3821 3822 HideFocus(); 3823 Button::LoseFocus(); 3824 3825 if ( !GetText().Len() || (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) ) 3826 { 3827 // decrease button size again (see GetFocus()) 3828 // checkboxes without text will draw focusrect around the check 3829 Point aPos( GetPosPixel() ); 3830 Size aSize( GetSizePixel() ); 3831 aPos.Move(1,1); 3832 aSize.Height() -= 2; 3833 aSize.Width() -= 2; 3834 SetPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height(), WINDOW_POSSIZE_ALL ); 3835 ImplDrawCheckBox(); 3836 } 3837 } 3838 3839 // ----------------------------------------------------------------------- 3840 3841 void CheckBox::StateChanged( StateChangedType nType ) 3842 { 3843 Button::StateChanged( nType ); 3844 3845 if ( nType == STATE_CHANGE_STATE ) 3846 { 3847 if ( IsReallyVisible() && IsUpdateMode() ) 3848 Invalidate( maStateRect ); 3849 } 3850 else if ( (nType == STATE_CHANGE_ENABLE) || 3851 (nType == STATE_CHANGE_TEXT) || 3852 (nType == STATE_CHANGE_IMAGE) || 3853 (nType == STATE_CHANGE_DATA) || 3854 (nType == STATE_CHANGE_UPDATEMODE) ) 3855 { 3856 if ( IsUpdateMode() ) 3857 Invalidate(); 3858 } 3859 else if ( nType == STATE_CHANGE_STYLE ) 3860 { 3861 SetStyle( ImplInitStyle( GetWindow( WINDOW_PREV ), GetStyle() ) ); 3862 3863 if ( (GetPrevStyle() & CHECKBOX_VIEW_STYLE) != 3864 (GetStyle() & CHECKBOX_VIEW_STYLE) ) 3865 { 3866 if ( IsUpdateMode() ) 3867 Invalidate(); 3868 } 3869 } 3870 else if ( (nType == STATE_CHANGE_ZOOM) || 3871 (nType == STATE_CHANGE_CONTROLFONT) ) 3872 { 3873 ImplInitSettings( sal_True, sal_False, sal_False ); 3874 Invalidate(); 3875 } 3876 else if ( nType == STATE_CHANGE_CONTROLFOREGROUND ) 3877 { 3878 ImplInitSettings( sal_False, sal_True, sal_False ); 3879 Invalidate(); 3880 } 3881 else if ( nType == STATE_CHANGE_CONTROLBACKGROUND ) 3882 { 3883 ImplInitSettings( sal_False, sal_False, sal_True ); 3884 Invalidate(); 3885 } 3886 } 3887 3888 // ----------------------------------------------------------------------- 3889 3890 void CheckBox::DataChanged( const DataChangedEvent& rDCEvt ) 3891 { 3892 Button::DataChanged( rDCEvt ); 3893 3894 if ( (rDCEvt.GetType() == DATACHANGED_FONTS) || 3895 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) || 3896 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) && 3897 (rDCEvt.GetFlags() & SETTINGS_STYLE)) ) 3898 { 3899 ImplInitSettings( sal_True, sal_True, sal_True ); 3900 Invalidate(); 3901 } 3902 } 3903 3904 // ----------------------------------------------------------------------- 3905 3906 long CheckBox::PreNotify( NotifyEvent& rNEvt ) 3907 { 3908 long nDone = 0; 3909 const MouseEvent* pMouseEvt = NULL; 3910 3911 if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL ) 3912 { 3913 if( !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() ) 3914 { 3915 // trigger redraw if mouse over state has changed 3916 if( IsNativeControlSupported(CTRL_CHECKBOX, PART_ENTIRE_CONTROL) ) 3917 { 3918 if( ( maMouseRect.IsInside( GetPointerPosPixel()) && 3919 !maMouseRect.IsInside( GetLastPointerPosPixel()) ) || 3920 ( maMouseRect.IsInside( GetLastPointerPosPixel()) && 3921 !maMouseRect.IsInside( GetPointerPosPixel()) ) || 3922 pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow() ) 3923 { 3924 Invalidate( maStateRect ); 3925 } 3926 } 3927 } 3928 } 3929 3930 return nDone ? nDone : Button::PreNotify(rNEvt); 3931 } 3932 3933 // ----------------------------------------------------------------------- 3934 3935 void CheckBox::Toggle() 3936 { 3937 ImplCallEventListenersAndHandler( VCLEVENT_CHECKBOX_TOGGLE, maToggleHdl, this ); 3938 } 3939 3940 // ----------------------------------------------------------------------- 3941 3942 void CheckBox::SetState( TriState eState ) 3943 { 3944 if ( !mbTriState && (eState == STATE_DONTKNOW) ) 3945 eState = STATE_NOCHECK; 3946 3947 if ( meState != eState ) 3948 { 3949 meState = eState; 3950 StateChanged( STATE_CHANGE_STATE ); 3951 Toggle(); 3952 } 3953 } 3954 3955 // ----------------------------------------------------------------------- 3956 3957 void CheckBox::EnableTriState( sal_Bool bTriState ) 3958 { 3959 if ( mbTriState != bTriState ) 3960 { 3961 mbTriState = bTriState; 3962 3963 if ( !bTriState && (meState == STATE_DONTKNOW) ) 3964 SetState( STATE_NOCHECK ); 3965 } 3966 } 3967 3968 // ----------------------------------------------------------------------- 3969 3970 long CheckBox::ImplGetImageToTextDistance() const 3971 { 3972 // 4 pixels, but take zoom into account, so the text doesn't "jump" relative to surrounding elements, 3973 // which might have been aligned with the text of the check box 3974 return CalcZoom( 4 ); 3975 } 3976 3977 // ----------------------------------------------------------------------- 3978 3979 Size CheckBox::ImplGetCheckImageSize() const 3980 { 3981 Size aSize; 3982 // why are IsNativeControlSupported and GetNativeControlRegion not const ? 3983 CheckBox* pThis = const_cast<CheckBox*>(this); 3984 bool bDefaultSize = true; 3985 if( pThis->IsNativeControlSupported( CTRL_CHECKBOX, PART_ENTIRE_CONTROL ) ) 3986 { 3987 ImplControlValue aControlValue; 3988 // #i45896# workaround gcc3.3 temporary problem 3989 Rectangle aCtrlRegion( Point( 0, 0 ), GetSizePixel() ); 3990 ControlState nState = CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED; 3991 Rectangle aBoundingRgn, aContentRgn; 3992 3993 // get native size of a check box 3994 if( pThis->GetNativeControlRegion( CTRL_CHECKBOX, PART_ENTIRE_CONTROL, aCtrlRegion, 3995 nState, aControlValue, rtl::OUString(), 3996 aBoundingRgn, aContentRgn ) ) 3997 { 3998 aSize = aContentRgn.GetSize(); 3999 bDefaultSize = false; 4000 } 4001 } 4002 if( bDefaultSize ) 4003 aSize = GetCheckImage( GetSettings(), 0 ).GetSizePixel(); 4004 return aSize; 4005 } 4006 4007 Image CheckBox::GetCheckImage( const AllSettings& rSettings, sal_uInt16 nFlags ) 4008 { 4009 ImplSVData* pSVData = ImplGetSVData(); 4010 const StyleSettings& rStyleSettings = rSettings.GetStyleSettings(); 4011 sal_uInt16 nStyle = 0; 4012 4013 if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO ) 4014 nStyle = STYLE_CHECKBOX_MONO; 4015 4016 if ( !pSVData->maCtrlData.mpCheckImgList || 4017 (pSVData->maCtrlData.mnCheckStyle != nStyle) || 4018 (pSVData->maCtrlData.mnLastCheckFColor != rStyleSettings.GetFaceColor().GetColor()) || 4019 (pSVData->maCtrlData.mnLastCheckWColor != rStyleSettings.GetWindowColor().GetColor()) || 4020 (pSVData->maCtrlData.mnLastCheckLColor != rStyleSettings.GetLightColor().GetColor()) ) 4021 { 4022 if ( pSVData->maCtrlData.mpCheckImgList ) 4023 delete pSVData->maCtrlData.mpCheckImgList; 4024 4025 pSVData->maCtrlData.mnLastCheckFColor = rStyleSettings.GetFaceColor().GetColor(); 4026 pSVData->maCtrlData.mnLastCheckWColor = rStyleSettings.GetWindowColor().GetColor(); 4027 pSVData->maCtrlData.mnLastCheckLColor = rStyleSettings.GetLightColor().GetColor(); 4028 4029 ResMgr* pResMgr = ImplGetResMgr(); 4030 pSVData->maCtrlData.mpCheckImgList = new ImageList(); 4031 if( pResMgr ) 4032 LoadThemedImageList( rStyleSettings, 4033 pSVData->maCtrlData.mpCheckImgList, 4034 ResId( SV_RESID_BITMAP_CHECK+nStyle, *pResMgr ), 9 ); 4035 pSVData->maCtrlData.mnCheckStyle = nStyle; 4036 } 4037 4038 sal_uInt16 nId; 4039 if ( nFlags & BUTTON_DRAW_DISABLED ) 4040 { 4041 if ( nFlags & BUTTON_DRAW_DONTKNOW ) 4042 nId = 9; 4043 else if ( nFlags & BUTTON_DRAW_CHECKED ) 4044 nId = 6; 4045 else 4046 nId = 5; 4047 } 4048 else if ( nFlags & BUTTON_DRAW_PRESSED ) 4049 { 4050 if ( nFlags & BUTTON_DRAW_DONTKNOW ) 4051 nId = 8; 4052 else if ( nFlags & BUTTON_DRAW_CHECKED ) 4053 nId = 4; 4054 else 4055 nId = 3; 4056 } 4057 else 4058 { 4059 if ( nFlags & BUTTON_DRAW_DONTKNOW ) 4060 nId = 7; 4061 else if ( nFlags & BUTTON_DRAW_CHECKED ) 4062 nId = 2; 4063 else 4064 nId = 1; 4065 } 4066 return pSVData->maCtrlData.mpCheckImgList->GetImage( nId ); 4067 } 4068 4069 // ----------------------------------------------------------------------- 4070 4071 void CheckBox::ImplSetMinimumNWFSize() 4072 { 4073 Push( PUSH_MAPMODE ); 4074 SetMapMode( MAP_PIXEL ); 4075 4076 ImplControlValue aControlValue; 4077 Size aCurSize( GetSizePixel() ); 4078 Rectangle aCtrlRegion( Point( 0, 0 ), aCurSize ); 4079 Rectangle aBoundingRgn, aContentRgn; 4080 4081 // get native size of a radiobutton 4082 if( GetNativeControlRegion( CTRL_CHECKBOX, PART_ENTIRE_CONTROL, aCtrlRegion, 4083 CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED, aControlValue, rtl::OUString(), 4084 aBoundingRgn, aContentRgn ) ) 4085 { 4086 Size aSize = aContentRgn.GetSize(); 4087 4088 if( aSize.Height() > aCurSize.Height() ) 4089 { 4090 aCurSize.Height() = aSize.Height(); 4091 SetSizePixel( aCurSize ); 4092 } 4093 } 4094 4095 Pop(); 4096 } 4097 4098 // ----------------------------------------------------------------------- 4099 4100 Size CheckBox::CalcMinimumSize( long nMaxWidth ) const 4101 { 4102 Size aSize = ImplGetCheckImageSize(); 4103 nMaxWidth -= aSize.Width(); 4104 4105 XubString aText = GetText(); 4106 if ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) ) 4107 { 4108 // subtract what will be added later 4109 nMaxWidth-=2; 4110 nMaxWidth -= ImplGetImageToTextDistance(); 4111 4112 Size aTextSize = GetTextRect( Rectangle( Point(), Size( nMaxWidth > 0 ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ), 4113 aText, FixedText::ImplGetTextStyle( GetStyle() ) ).GetSize(); 4114 aSize.Width()+=2; // for focus rect 4115 aSize.Width() += ImplGetImageToTextDistance(); 4116 aSize.Width() += aTextSize.Width(); 4117 if ( aSize.Height() < aTextSize.Height() ) 4118 aSize.Height() = aTextSize.Height(); 4119 } 4120 else 4121 { 4122 // is this still correct ? since the checkbox now 4123 // shows a focus rect it should be 2 pixels wider and longer 4124 /* da ansonsten im Writer die Control zu weit oben haengen 4125 aSize.Width() += 2; 4126 aSize.Height() += 2; 4127 */ 4128 } 4129 4130 return CalcWindowSize( aSize ); 4131 } 4132 4133 // ----------------------------------------------------------------------- 4134 4135 Size CheckBox::GetOptimalSize(WindowSizeType eType) const 4136 { 4137 switch (eType) { 4138 case WINDOWSIZE_MINIMUM: 4139 return CalcMinimumSize(); 4140 default: 4141 return Button::GetOptimalSize( eType ); 4142 } 4143 } 4144 4145 // ======================================================================= 4146 4147 ImageButton::ImageButton( WindowType nType ) : 4148 PushButton( nType ) 4149 { 4150 ImplInitStyle(); 4151 } 4152 4153 // ----------------------------------------------------------------------- 4154 4155 ImageButton::ImageButton( Window* pParent, WinBits nStyle ) : 4156 PushButton( pParent, nStyle ) 4157 { 4158 ImplInitStyle(); 4159 } 4160 4161 // ----------------------------------------------------------------------- 4162 4163 ImageButton::ImageButton( Window* pParent, const ResId& rResId ) : 4164 PushButton( pParent, rResId.SetRT( RSC_IMAGEBUTTON ) ) 4165 { 4166 sal_uLong nObjMask = ReadLongRes(); 4167 4168 if ( RSC_IMAGEBUTTON_IMAGE & nObjMask ) 4169 { 4170 SetModeImage( Image( ResId( (RSHEADER_TYPE*)GetClassRes(), *rResId.GetResMgr() ) ) ); 4171 IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) ); 4172 } 4173 4174 if ( RSC_IMAGEBUTTON_SYMBOL & nObjMask ) 4175 SetSymbol( (SymbolType)ReadLongRes() ); 4176 4177 if ( RSC_IMAGEBUTTON_STATE & nObjMask ) 4178 SetState( (TriState)ReadLongRes() ); 4179 4180 ImplInitStyle(); 4181 } 4182 4183 // ----------------------------------------------------------------------- 4184 4185 ImageButton::~ImageButton() 4186 { 4187 } 4188 4189 // ----------------------------------------------------------------------- 4190 void ImageButton::ImplInitStyle() 4191 { 4192 WinBits nStyle = GetStyle(); 4193 4194 if ( ! ( nStyle & ( WB_RIGHT | WB_LEFT ) ) ) 4195 nStyle |= WB_CENTER; 4196 4197 if ( ! ( nStyle & ( WB_TOP | WB_BOTTOM ) ) ) 4198 nStyle |= WB_VCENTER; 4199 4200 SetStyle( nStyle ); 4201 } 4202 4203 // ======================================================================= 4204 4205 ImageRadioButton::ImageRadioButton( Window* pParent, WinBits nStyle ) : 4206 RadioButton( pParent, nStyle ) 4207 { 4208 } 4209 4210 // ----------------------------------------------------------------------- 4211 4212 ImageRadioButton::ImageRadioButton( Window* pParent, const ResId& rResId ) : 4213 RadioButton( pParent, rResId.SetRT( RSC_IMAGERADIOBUTTON ) ) 4214 { 4215 sal_uLong nObjMask = ReadLongRes(); 4216 4217 if ( RSC_IMAGERADIOBUTTON_IMAGE & nObjMask ) 4218 { 4219 SetModeRadioImage( Image( ResId( (RSHEADER_TYPE*)GetClassRes(), *rResId.GetResMgr() ) ) ); 4220 IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) ); 4221 } 4222 } 4223 4224 // ----------------------------------------------------------------------- 4225 4226 ImageRadioButton::~ImageRadioButton() 4227 { 4228 } 4229 4230 // ======================================================================= 4231 4232 TriStateBox::TriStateBox( Window* pParent, WinBits nStyle ) : 4233 CheckBox( pParent, nStyle ) 4234 { 4235 EnableTriState( sal_True ); 4236 } 4237 4238 // ----------------------------------------------------------------------- 4239 4240 TriStateBox::TriStateBox( Window* pParent, const ResId& rResId ) : 4241 CheckBox( pParent, rResId.SetRT( RSC_TRISTATEBOX ) ) 4242 { 4243 EnableTriState( sal_True ); 4244 4245 sal_uLong nTriState = ReadLongRes(); 4246 sal_uInt16 bDisableTriState = ReadShortRes(); 4247 //anderer Wert als Default ? 4248 if ( (TriState)nTriState != STATE_NOCHECK ) 4249 SetState( (TriState)nTriState ); 4250 if ( bDisableTriState ) 4251 EnableTriState( sal_False ); 4252 } 4253 4254 // ----------------------------------------------------------------------- 4255 4256 TriStateBox::~TriStateBox() 4257 { 4258 } 4259 4260 // ======================================================================= 4261 4262 DisclosureButton::DisclosureButton( Window* pParent, WinBits ) : 4263 CheckBox( pParent, WB_NOBORDER ) 4264 { 4265 } 4266 4267 // ----------------------------------------------------------------------- 4268 4269 DisclosureButton::DisclosureButton( Window* pParent, const ResId& rResId ) : 4270 CheckBox( pParent, rResId.SetRT( RSC_CHECKBOX ) ) 4271 { 4272 } 4273 4274 // ----------------------------------------------------------------------- 4275 4276 void DisclosureButton::ImplDrawCheckBoxState() 4277 { 4278 /* HACK: DisclosureButton is currently assuming, that the disclosure sign 4279 will fit into the rectangle occupied by a normal checkbox on all themes. 4280 If this does not hold true for some theme, ImplGetCheckImageSize 4281 would have to be overloaded for DisclosureButton; also GetNativeControlRegion 4282 for CTRL_LISTNODE would have to be implemented and taken into account 4283 */ 4284 4285 Rectangle aStateRect( GetStateRect() ); 4286 4287 ImplControlValue aControlValue( GetState() == STATE_CHECK ? BUTTONVALUE_ON : BUTTONVALUE_OFF ); 4288 Rectangle aCtrlRegion( aStateRect ); 4289 ControlState nState = 0; 4290 4291 if ( HasFocus() ) nState |= CTRL_STATE_FOCUSED; 4292 if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT ) nState |= CTRL_STATE_DEFAULT; 4293 if ( Window::IsEnabled() ) nState |= CTRL_STATE_ENABLED; 4294 if ( IsMouseOver() && GetMouseRect().IsInside( GetPointerPosPixel() ) ) 4295 nState |= CTRL_STATE_ROLLOVER; 4296 4297 if( ! DrawNativeControl( CTRL_LISTNODE, PART_ENTIRE_CONTROL, aCtrlRegion, nState, 4298 aControlValue, rtl::OUString() ) ) 4299 { 4300 ImplSVCtrlData& rCtrlData( ImplGetSVData()->maCtrlData ); 4301 if( ! rCtrlData.mpDisclosurePlus ) 4302 rCtrlData.mpDisclosurePlus = new Image( BitmapEx( VclResId( SV_DISCLOSURE_PLUS ) ) ); 4303 if( ! rCtrlData.mpDisclosurePlusHC ) 4304 rCtrlData.mpDisclosurePlusHC = new Image( BitmapEx( VclResId( SV_DISCLOSURE_PLUS_HC ) ) ); 4305 if( ! rCtrlData.mpDisclosureMinus ) 4306 rCtrlData.mpDisclosureMinus = new Image( BitmapEx( VclResId( SV_DISCLOSURE_MINUS ) ) ); 4307 if( ! rCtrlData.mpDisclosureMinusHC ) 4308 rCtrlData.mpDisclosureMinusHC = new Image( BitmapEx( VclResId( SV_DISCLOSURE_MINUS_HC ) ) ); 4309 4310 Image* pImg = NULL; 4311 if( GetSettings().GetStyleSettings().GetHighContrastMode() ) 4312 pImg = IsChecked() ? rCtrlData.mpDisclosureMinusHC : rCtrlData.mpDisclosurePlusHC; 4313 else 4314 pImg = IsChecked() ? rCtrlData.mpDisclosureMinus : rCtrlData.mpDisclosurePlus; 4315 4316 DBG_ASSERT( pImg, "no disclosure image" ); 4317 if( ! pImg ) 4318 return; 4319 4320 sal_uInt16 nStyle = 0; 4321 if( ! IsEnabled() ) 4322 nStyle |= IMAGE_DRAW_DISABLE; 4323 4324 Size aSize( aStateRect.GetSize() ); 4325 Size aImgSize( pImg->GetSizePixel() ); 4326 Point aOff( (aSize.Width() - aImgSize.Width())/2, 4327 (aSize.Height() - aImgSize.Height())/2 ); 4328 aOff += aStateRect.TopLeft(); 4329 DrawImage( aOff, *pImg, nStyle ); 4330 } 4331 } 4332 4333 // ----------------------------------------------------------------------- 4334 4335 void DisclosureButton::KeyInput( const KeyEvent& rKEvt ) 4336 { 4337 KeyCode aKeyCode = rKEvt.GetKeyCode(); 4338 4339 if( !aKeyCode.GetModifier() && 4340 ( ( aKeyCode.GetCode() == KEY_ADD ) || 4341 ( aKeyCode.GetCode() == KEY_SUBTRACT ) ) 4342 ) 4343 { 4344 Check( aKeyCode.GetCode() == KEY_ADD ); 4345 } 4346 else 4347 Button::KeyInput( rKEvt ); 4348 } 4349 4350 4351