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