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 1135 if( bDropDown && (aCtrlType == CTRL_COMBOBOX || aCtrlType == CTRL_LISTBOX ) ) 1136 { 1137 if( GetParent()->IsNativeControlSupported( aCtrlType, PART_ENTIRE_CONTROL) ) 1138 { 1139 // skip painting if the button was already drawn by the theme 1140 if( aCtrlType == CTRL_COMBOBOX ) 1141 { 1142 Edit* pEdit = static_cast<Edit*>(GetParent()); 1143 if( pEdit->ImplUseNativeBorder( pEdit->GetStyle() ) ) 1144 bNativeOK = sal_True; 1145 } 1146 else if( GetParent()->IsNativeControlSupported( aCtrlType, HAS_BACKGROUND_TEXTURE) ) 1147 { 1148 bNativeOK = sal_True; 1149 } 1150 if( !bNativeOK && GetParent()->IsNativeControlSupported( aCtrlType, PART_BUTTON_DOWN ) ) 1151 { 1152 // let the theme draw it, note we then need support 1153 // for CTRL_LISTBOX/PART_BUTTON_DOWN and CTRL_COMBOBOX/PART_BUTTON_DOWN 1154 1155 ImplControlValue aControlValue; 1156 ControlState nState = 0; 1157 1158 if ( mbPressed ) nState |= CTRL_STATE_PRESSED; 1159 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) nState |= CTRL_STATE_PRESSED; 1160 if ( HasFocus() ) nState |= CTRL_STATE_FOCUSED; 1161 if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT ) nState |= CTRL_STATE_DEFAULT; 1162 if ( Window::IsEnabled() ) nState |= CTRL_STATE_ENABLED; 1163 1164 if ( IsMouseOver() && aInRect.IsInside( GetPointerPosPixel() ) ) 1165 nState |= CTRL_STATE_ROLLOVER; 1166 1167 bNativeOK = DrawNativeControl( aCtrlType, PART_BUTTON_DOWN, aInRect, nState, 1168 aControlValue, rtl::OUString() ); 1169 } 1170 } 1171 } 1172 1173 if( bNativeOK ) 1174 return; 1175 1176 bool bRollOver = (IsMouseOver() && aInRect.IsInside( GetPointerPosPixel() )); 1177 bool bDrawMenuSep = true; 1178 if( (GetStyle() & WB_FLATBUTTON) ) 1179 { 1180 if( ! bRollOver && ! HasFocus() ) 1181 bDrawMenuSep = false; 1182 } 1183 if ( (bNativeOK=IsNativeControlSupported(CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL)) == sal_True ) 1184 { 1185 PushButtonValue aControlValue; 1186 Rectangle aCtrlRegion( aInRect ); 1187 ControlState nState = 0; 1188 1189 if ( mbPressed || IsChecked() ) nState |= CTRL_STATE_PRESSED; 1190 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) nState |= CTRL_STATE_PRESSED; 1191 if ( HasFocus() ) nState |= CTRL_STATE_FOCUSED; 1192 if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT ) nState |= CTRL_STATE_DEFAULT; 1193 if ( Window::IsEnabled() ) nState |= CTRL_STATE_ENABLED; 1194 1195 if ( bRollOver ) 1196 nState |= CTRL_STATE_ROLLOVER; 1197 1198 if( GetStyle() & WB_BEVELBUTTON ) 1199 aControlValue.mbBevelButton = true; 1200 1201 // draw frame into invisible window to have aInRect modified correctly 1202 // but do not shift the inner rect for pressed buttons (ie remove BUTTON_DRAW_PRESSED) 1203 // this assumes the theme has enough visual cues to signalize the button was pressed 1204 //Window aWin( this ); 1205 //ImplDrawPushButtonFrame( &aWin, aInRect, nButtonStyle & ~BUTTON_DRAW_PRESSED ); 1206 1207 // looks better this way as symbols were displaced slightly using the above approach 1208 aInRect.Top()+=4; 1209 aInRect.Bottom()-=4; 1210 aInRect.Left()+=4; 1211 aInRect.Right()-=4; 1212 1213 // prepare single line hint (needed on mac to decide between normal push button and 1214 // rectangular bevel button look) 1215 Size aFontSize( Application::GetSettings().GetStyleSettings().GetPushButtonFont().GetSize() ); 1216 aFontSize = LogicToPixel( aFontSize, MapMode( MAP_POINT ) ); 1217 Size aInRectSize( LogicToPixel( Size( aInRect.GetWidth(), aInRect.GetHeight() ) ) ); 1218 aControlValue.mbSingleLine = (aInRectSize.Height() < 2 * aFontSize.Height() ); 1219 1220 if( ((nState & CTRL_STATE_ROLLOVER)) || ! (GetStyle() & WB_FLATBUTTON) ) 1221 { 1222 bNativeOK = DrawNativeControl( CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion, nState, 1223 aControlValue, rtl::OUString()/*PushButton::GetText()*/ ); 1224 } 1225 else 1226 { 1227 bNativeOK = true; 1228 } 1229 1230 // draw content using the same aInRect as non-native VCL would do 1231 ImplDrawPushButtonContent( this, 1232 (nState&CTRL_STATE_ROLLOVER) ? WINDOW_DRAW_ROLLOVER : 0, 1233 aInRect, bLayout, bDrawMenuSep ); 1234 1235 if ( HasFocus() ) 1236 ShowFocus( ImplGetFocusRect() ); 1237 } 1238 1239 if ( bNativeOK == sal_False ) 1240 { 1241 // draw PushButtonFrame, aInRect has content size afterwards 1242 if( (GetStyle() & WB_FLATBUTTON) ) 1243 { 1244 Rectangle aTempRect( aInRect ); 1245 if( ! bLayout && bRollOver ) 1246 ImplDrawPushButtonFrame( this, aTempRect, nButtonStyle ); 1247 aInRect.Left() += 2; 1248 aInRect.Top() += 2; 1249 aInRect.Right() -= 2; 1250 aInRect.Bottom() -= 2; 1251 } 1252 else 1253 { 1254 if( ! bLayout ) 1255 ImplDrawPushButtonFrame( this, aInRect, nButtonStyle ); 1256 } 1257 1258 // draw content 1259 ImplDrawPushButtonContent( this, 0, aInRect, bLayout, bDrawMenuSep ); 1260 1261 if( ! bLayout && HasFocus() ) 1262 { 1263 ShowFocus( ImplGetFocusRect() ); 1264 } 1265 } 1266 } 1267 1268 // ----------------------------------------------------------------------- 1269 1270 void PushButton::ImplSetDefButton( sal_Bool bSet ) 1271 { 1272 Size aSize( GetSizePixel() ); 1273 Point aPos( GetPosPixel() ); 1274 int dLeft(0), dRight(0), dTop(0), dBottom(0); 1275 sal_Bool bSetPos = sal_False; 1276 1277 if ( (IsNativeControlSupported(CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL)) == sal_True ) 1278 { 1279 Rectangle aBound, aCont; 1280 Rectangle aCtrlRect( 0, 0, 80, 20 ); // use a constant size to avoid accumulating 1281 // will not work if the theme has dynamic adornment sizes 1282 ImplControlValue aControlValue; 1283 Rectangle aCtrlRegion( aCtrlRect ); 1284 ControlState nState = CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED; 1285 1286 // get native size of a 'default' button 1287 // and adjust the VCL button if more space for adornment is required 1288 if( GetNativeControlRegion( CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion, 1289 nState, aControlValue, rtl::OUString(), 1290 aBound, aCont ) ) 1291 { 1292 dLeft = aCont.Left() - aBound.Left(); 1293 dTop = aCont.Top() - aBound.Top(); 1294 dRight = aBound.Right() - aCont.Right(); 1295 dBottom = aBound.Bottom() - aCont.Bottom(); 1296 bSetPos = dLeft || dTop || dRight || dBottom; 1297 } 1298 } 1299 1300 if ( bSet ) 1301 { 1302 if( !(ImplGetButtonState() & BUTTON_DRAW_DEFAULT) && bSetPos ) 1303 { 1304 // adjust pos/size when toggling from non-default to default 1305 aPos.Move(-dLeft, -dTop); 1306 aSize.Width() += dLeft + dRight; 1307 aSize.Height() += dTop + dBottom; 1308 } 1309 ImplGetButtonState() |= BUTTON_DRAW_DEFAULT; 1310 } 1311 else 1312 { 1313 if( (ImplGetButtonState() & BUTTON_DRAW_DEFAULT) && bSetPos ) 1314 { 1315 // adjust pos/size when toggling from default to non-default 1316 aPos.Move(dLeft, dTop); 1317 aSize.Width() -= dLeft + dRight; 1318 aSize.Height() -= dTop + dBottom; 1319 } 1320 ImplGetButtonState() &= ~BUTTON_DRAW_DEFAULT; 1321 } 1322 if( bSetPos ) 1323 SetPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height(), WINDOW_POSSIZE_ALL ); 1324 1325 Invalidate(); 1326 } 1327 1328 // ----------------------------------------------------------------------- 1329 1330 sal_Bool PushButton::ImplIsDefButton() const 1331 { 1332 return (ImplGetButtonState() & BUTTON_DRAW_DEFAULT) != 0; 1333 } 1334 1335 // ----------------------------------------------------------------------- 1336 1337 PushButton::PushButton( WindowType nType ) : 1338 Button( nType ) 1339 { 1340 ImplInitPushButtonData(); 1341 } 1342 1343 // ----------------------------------------------------------------------- 1344 1345 PushButton::PushButton( Window* pParent, WinBits nStyle ) : 1346 Button( WINDOW_PUSHBUTTON ) 1347 { 1348 ImplInitPushButtonData(); 1349 ImplInit( pParent, nStyle ); 1350 } 1351 1352 // ----------------------------------------------------------------------- 1353 1354 PushButton::PushButton( Window* pParent, const ResId& rResId ) : 1355 Button( WINDOW_PUSHBUTTON ) 1356 { 1357 ImplInitPushButtonData(); 1358 rResId.SetRT( RSC_PUSHBUTTON ); 1359 WinBits nStyle = ImplInitRes( rResId ); 1360 ImplInit( pParent, nStyle ); 1361 ImplLoadRes( rResId ); 1362 1363 if ( !(nStyle & WB_HIDE) ) 1364 Show(); 1365 } 1366 1367 // ----------------------------------------------------------------------- 1368 1369 PushButton::~PushButton() 1370 { 1371 } 1372 1373 // ----------------------------------------------------------------------- 1374 1375 void PushButton::MouseButtonDown( const MouseEvent& rMEvt ) 1376 { 1377 if ( rMEvt.IsLeft() && 1378 ImplHitTestPushButton( this, rMEvt.GetPosPixel() ) ) 1379 { 1380 sal_uInt16 nTrackFlags = 0; 1381 1382 if ( ( GetStyle() & WB_REPEAT ) && 1383 ! ( GetStyle() & WB_TOGGLE ) ) 1384 nTrackFlags |= STARTTRACK_BUTTONREPEAT; 1385 1386 ImplGetButtonState() |= BUTTON_DRAW_PRESSED; 1387 ImplDrawPushButton(); 1388 StartTracking( nTrackFlags ); 1389 1390 if ( nTrackFlags & STARTTRACK_BUTTONREPEAT ) 1391 Click(); 1392 } 1393 } 1394 1395 // ----------------------------------------------------------------------- 1396 1397 void PushButton::Tracking( const TrackingEvent& rTEvt ) 1398 { 1399 if ( rTEvt.IsTrackingEnded() ) 1400 { 1401 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) 1402 { 1403 if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() ) 1404 GrabFocus(); 1405 1406 if ( GetStyle() & WB_TOGGLE ) 1407 { 1408 // Don't toggle, when aborted 1409 if ( !rTEvt.IsTrackingCanceled() ) 1410 { 1411 if ( IsChecked() ) 1412 { 1413 Check( sal_False ); 1414 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 1415 } 1416 else 1417 Check( sal_True ); 1418 } 1419 } 1420 else 1421 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 1422 1423 ImplDrawPushButton(); 1424 1425 // Bei Abbruch kein Click-Handler rufen 1426 if ( !rTEvt.IsTrackingCanceled() ) 1427 { 1428 if ( ! ( ( GetStyle() & WB_REPEAT ) && 1429 ! ( GetStyle() & WB_TOGGLE ) ) ) 1430 Click(); 1431 } 1432 } 1433 } 1434 else 1435 { 1436 if ( ImplHitTestPushButton( this, rTEvt.GetMouseEvent().GetPosPixel() ) ) 1437 { 1438 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) 1439 { 1440 if ( rTEvt.IsTrackingRepeat() && (GetStyle() & WB_REPEAT) && 1441 ! ( GetStyle() & WB_TOGGLE ) ) 1442 Click(); 1443 } 1444 else 1445 { 1446 ImplGetButtonState() |= BUTTON_DRAW_PRESSED; 1447 ImplDrawPushButton(); 1448 } 1449 } 1450 else 1451 { 1452 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) 1453 { 1454 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 1455 ImplDrawPushButton(); 1456 } 1457 } 1458 } 1459 } 1460 1461 // ----------------------------------------------------------------------- 1462 1463 void PushButton::KeyInput( const KeyEvent& rKEvt ) 1464 { 1465 KeyCode aKeyCode = rKEvt.GetKeyCode(); 1466 1467 if ( !aKeyCode.GetModifier() && 1468 ((aKeyCode.GetCode() == KEY_RETURN) || (aKeyCode.GetCode() == KEY_SPACE)) ) 1469 { 1470 if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) ) 1471 { 1472 ImplGetButtonState() |= BUTTON_DRAW_PRESSED; 1473 ImplDrawPushButton(); 1474 } 1475 1476 if ( ( GetStyle() & WB_REPEAT ) && 1477 ! ( GetStyle() & WB_TOGGLE ) ) 1478 Click(); 1479 } 1480 else if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_ESCAPE) ) 1481 { 1482 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 1483 ImplDrawPushButton(); 1484 } 1485 else 1486 Button::KeyInput( rKEvt ); 1487 } 1488 1489 // ----------------------------------------------------------------------- 1490 1491 void PushButton::KeyUp( const KeyEvent& rKEvt ) 1492 { 1493 KeyCode aKeyCode = rKEvt.GetKeyCode(); 1494 1495 if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && 1496 ((aKeyCode.GetCode() == KEY_RETURN) || (aKeyCode.GetCode() == KEY_SPACE)) ) 1497 { 1498 if ( GetStyle() & WB_TOGGLE ) 1499 { 1500 if ( IsChecked() ) 1501 { 1502 Check( sal_False ); 1503 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 1504 } 1505 else 1506 Check( sal_True ); 1507 1508 Toggle(); 1509 } 1510 else 1511 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 1512 1513 ImplDrawPushButton(); 1514 1515 if ( !( ( GetStyle() & WB_REPEAT ) && 1516 ! ( GetStyle() & WB_TOGGLE ) ) ) 1517 Click(); 1518 } 1519 else 1520 Button::KeyUp( rKEvt ); 1521 } 1522 1523 // ----------------------------------------------------------------------- 1524 1525 void PushButton::FillLayoutData() const 1526 { 1527 mpControlData->mpLayoutData = new vcl::ControlLayoutData(); 1528 const_cast<PushButton*>(this)->ImplDrawPushButton( true ); 1529 } 1530 1531 // ----------------------------------------------------------------------- 1532 1533 void PushButton::Paint( const Rectangle& ) 1534 { 1535 ImplDrawPushButton(); 1536 } 1537 1538 // ----------------------------------------------------------------------- 1539 1540 void PushButton::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, 1541 sal_uLong nFlags ) 1542 { 1543 Point aPos = pDev->LogicToPixel( rPos ); 1544 Size aSize = pDev->LogicToPixel( rSize ); 1545 Rectangle aRect( aPos, aSize ); 1546 Rectangle aTextRect; 1547 Font aFont = GetDrawPixelFont( pDev ); 1548 1549 pDev->Push(); 1550 pDev->SetMapMode(); 1551 pDev->SetFont( aFont ); 1552 if ( nFlags & WINDOW_DRAW_MONO ) 1553 { 1554 pDev->SetTextColor( Color( COL_BLACK ) ); 1555 } 1556 else 1557 { 1558 pDev->SetTextColor( GetTextColor() ); 1559 1560 // DecoView uses the FaceColor... 1561 AllSettings aSettings = pDev->GetSettings(); 1562 StyleSettings aStyleSettings = aSettings.GetStyleSettings(); 1563 if ( IsControlBackground() ) 1564 aStyleSettings.SetFaceColor( GetControlBackground() ); 1565 else 1566 aStyleSettings.SetFaceColor( GetSettings().GetStyleSettings().GetFaceColor() ); 1567 aSettings.SetStyleSettings( aStyleSettings ); 1568 pDev->SetSettings( aSettings ); 1569 } 1570 pDev->SetTextFillColor(); 1571 1572 DecorationView aDecoView( pDev ); 1573 sal_uInt16 nButtonStyle = 0; 1574 if ( nFlags & WINDOW_DRAW_MONO ) 1575 nButtonStyle |= BUTTON_DRAW_MONO; 1576 if ( IsChecked() ) 1577 nButtonStyle |= BUTTON_DRAW_CHECKED; 1578 aRect = aDecoView.DrawButton( aRect, nButtonStyle ); 1579 1580 ImplDrawPushButtonContent( pDev, nFlags, aRect, false, true ); 1581 pDev->Pop(); 1582 } 1583 1584 // ----------------------------------------------------------------------- 1585 1586 void PushButton::Resize() 1587 { 1588 Control::Resize(); 1589 Invalidate(); 1590 } 1591 1592 // ----------------------------------------------------------------------- 1593 1594 void PushButton::GetFocus() 1595 { 1596 ShowFocus( ImplGetFocusRect() ); 1597 SetInputContext( InputContext( GetFont() ) ); 1598 Button::GetFocus(); 1599 } 1600 1601 // ----------------------------------------------------------------------- 1602 1603 void PushButton::LoseFocus() 1604 { 1605 EndSelection(); 1606 HideFocus(); 1607 Button::LoseFocus(); 1608 } 1609 1610 // ----------------------------------------------------------------------- 1611 1612 void PushButton::StateChanged( StateChangedType nType ) 1613 { 1614 Button::StateChanged( nType ); 1615 1616 if ( (nType == STATE_CHANGE_ENABLE) || 1617 (nType == STATE_CHANGE_TEXT) || 1618 (nType == STATE_CHANGE_IMAGE) || 1619 (nType == STATE_CHANGE_DATA) || 1620 (nType == STATE_CHANGE_STATE) || 1621 (nType == STATE_CHANGE_UPDATEMODE) ) 1622 { 1623 if ( IsReallyVisible() && IsUpdateMode() ) 1624 Invalidate(); 1625 } 1626 else if ( nType == STATE_CHANGE_STYLE ) 1627 { 1628 SetStyle( ImplInitStyle( GetWindow( WINDOW_PREV ), GetStyle() ) ); 1629 1630 bool bIsDefButton = ( GetStyle() & WB_DEFBUTTON ) != 0; 1631 bool bWasDefButton = ( GetPrevStyle() & WB_DEFBUTTON ) != 0; 1632 if ( bIsDefButton != bWasDefButton ) 1633 ImplSetDefButton( bIsDefButton ); 1634 1635 if ( IsReallyVisible() && IsUpdateMode() ) 1636 { 1637 if ( (GetPrevStyle() & PUSHBUTTON_VIEW_STYLE) != 1638 (GetStyle() & PUSHBUTTON_VIEW_STYLE) ) 1639 Invalidate(); 1640 } 1641 } 1642 else if ( (nType == STATE_CHANGE_ZOOM) || 1643 (nType == STATE_CHANGE_CONTROLFONT) ) 1644 { 1645 ImplInitSettings( sal_True, sal_False, sal_False ); 1646 Invalidate(); 1647 } 1648 else if ( nType == STATE_CHANGE_CONTROLFOREGROUND ) 1649 { 1650 ImplInitSettings( sal_False, sal_True, sal_False ); 1651 Invalidate(); 1652 } 1653 else if ( nType == STATE_CHANGE_CONTROLBACKGROUND ) 1654 { 1655 ImplInitSettings( sal_False, sal_False, sal_True ); 1656 Invalidate(); 1657 } 1658 } 1659 1660 // ----------------------------------------------------------------------- 1661 1662 void PushButton::DataChanged( const DataChangedEvent& rDCEvt ) 1663 { 1664 Button::DataChanged( rDCEvt ); 1665 1666 if ( (rDCEvt.GetType() == DATACHANGED_FONTS) || 1667 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) || 1668 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) && 1669 (rDCEvt.GetFlags() & SETTINGS_STYLE)) ) 1670 { 1671 ImplInitSettings( sal_True, sal_True, sal_True ); 1672 Invalidate(); 1673 } 1674 } 1675 1676 // ----------------------------------------------------------------------- 1677 1678 long PushButton::PreNotify( NotifyEvent& rNEvt ) 1679 { 1680 long nDone = 0; 1681 const MouseEvent* pMouseEvt = NULL; 1682 1683 if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL ) 1684 { 1685 if( pMouseEvt->IsEnterWindow() || pMouseEvt->IsLeaveWindow() ) 1686 { 1687 // trigger redraw as mouse over state has changed 1688 1689 // TODO: move this to Window class or make it a member !!! 1690 ControlType aCtrlType = 0; 1691 switch( GetParent()->GetType() ) 1692 { 1693 case WINDOW_LISTBOX: 1694 case WINDOW_MULTILISTBOX: 1695 case WINDOW_TREELISTBOX: 1696 aCtrlType = CTRL_LISTBOX; 1697 break; 1698 1699 case WINDOW_COMBOBOX: 1700 case WINDOW_PATTERNBOX: 1701 case WINDOW_NUMERICBOX: 1702 case WINDOW_METRICBOX: 1703 case WINDOW_CURRENCYBOX: 1704 case WINDOW_DATEBOX: 1705 case WINDOW_TIMEBOX: 1706 case WINDOW_LONGCURRENCYBOX: 1707 aCtrlType = CTRL_COMBOBOX; 1708 break; 1709 default: 1710 break; 1711 } 1712 1713 sal_Bool bDropDown = ( IsSymbol() && (GetSymbol()==SYMBOL_SPIN_DOWN) && !GetText().Len() ); 1714 1715 if( bDropDown && GetParent()->IsNativeControlSupported( aCtrlType, PART_ENTIRE_CONTROL) && 1716 !GetParent()->IsNativeControlSupported( aCtrlType, PART_BUTTON_DOWN) ) 1717 { 1718 Window *pBorder = GetParent()->GetWindow( WINDOW_BORDER ); 1719 if(aCtrlType == CTRL_COMBOBOX) 1720 { 1721 // only paint the button part to avoid flickering of the combobox text 1722 Point aPt; 1723 Rectangle aClipRect( aPt, GetOutputSizePixel() ); 1724 aClipRect.SetPos(pBorder->ScreenToOutputPixel(OutputToScreenPixel(aClipRect.TopLeft()))); 1725 pBorder->Invalidate( aClipRect ); 1726 } 1727 else 1728 { 1729 pBorder->Invalidate( INVALIDATE_NOERASE ); 1730 pBorder->Update(); 1731 } 1732 } 1733 else if( (GetStyle() & WB_FLATBUTTON) || 1734 IsNativeControlSupported(CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL) ) 1735 { 1736 Invalidate(); 1737 } 1738 } 1739 } 1740 1741 return nDone ? nDone : Button::PreNotify(rNEvt); 1742 } 1743 1744 // ----------------------------------------------------------------------- 1745 1746 void PushButton::Toggle() 1747 { 1748 ImplCallEventListenersAndHandler( VCLEVENT_PUSHBUTTON_TOGGLE, maToggleHdl, this ); 1749 } 1750 1751 // ----------------------------------------------------------------------- 1752 1753 void PushButton::SetSymbol( SymbolType eSymbol ) 1754 { 1755 if ( meSymbol != eSymbol ) 1756 { 1757 meSymbol = eSymbol; 1758 StateChanged( STATE_CHANGE_DATA ); 1759 } 1760 } 1761 1762 // ----------------------------------------------------------------------- 1763 void PushButton::SetSymbolAlign( SymbolAlign eAlign ) 1764 { 1765 ImplSetSymbolAlign( eAlign ); 1766 } 1767 1768 // ----------------------------------------------------------------------- 1769 SymbolAlign PushButton::GetSymbolAlign() const 1770 { 1771 return ImplGetSymbolAlign(); 1772 } 1773 1774 // ----------------------------------------------------------------------- 1775 1776 void PushButton::SetDropDown( sal_uInt16 nStyle ) 1777 { 1778 if ( mnDDStyle != nStyle ) 1779 { 1780 mnDDStyle = nStyle; 1781 StateChanged( STATE_CHANGE_DATA ); 1782 } 1783 } 1784 1785 // ----------------------------------------------------------------------- 1786 1787 void PushButton::SetState( TriState eState ) 1788 { 1789 if ( meState != eState ) 1790 { 1791 meState = eState; 1792 if ( meState == STATE_NOCHECK ) 1793 ImplGetButtonState() &= ~(BUTTON_DRAW_CHECKED | BUTTON_DRAW_DONTKNOW); 1794 else if ( meState == STATE_CHECK ) 1795 { 1796 ImplGetButtonState() &= ~BUTTON_DRAW_DONTKNOW; 1797 ImplGetButtonState() |= BUTTON_DRAW_CHECKED; 1798 } 1799 else // STATE_DONTKNOW 1800 { 1801 ImplGetButtonState() &= ~BUTTON_DRAW_CHECKED; 1802 ImplGetButtonState() |= BUTTON_DRAW_DONTKNOW; 1803 } 1804 1805 StateChanged( STATE_CHANGE_STATE ); 1806 Toggle(); 1807 } 1808 } 1809 1810 // ----------------------------------------------------------------------- 1811 1812 void PushButton::SetPressed( sal_Bool bPressed ) 1813 { 1814 if ( mbPressed != bPressed ) 1815 { 1816 mbPressed = bPressed; 1817 StateChanged( STATE_CHANGE_DATA ); 1818 } 1819 } 1820 1821 // ----------------------------------------------------------------------- 1822 1823 void PushButton::EndSelection() 1824 { 1825 EndTracking( ENDTRACK_CANCEL ); 1826 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) 1827 { 1828 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 1829 if ( !mbPressed ) 1830 ImplDrawPushButton(); 1831 } 1832 } 1833 1834 // ----------------------------------------------------------------------- 1835 1836 Size PushButton::CalcMinimumSize( long nMaxWidth ) const 1837 { 1838 Size aSize; 1839 1840 if ( IsSymbol() ) 1841 { 1842 if ( IsSmallSymbol ()) 1843 aSize = Size( 16, 12 ); 1844 else 1845 aSize = Size( 26, 24 ); 1846 if( mnDDStyle == PUSHBUTTON_DROPDOWN_MENUBUTTON ) 1847 aSize.Width() += 4; 1848 } 1849 else if ( IsImage() && ! (ImplGetButtonState() & BUTTON_DRAW_NOIMAGE) ) 1850 aSize = GetModeImage().GetSizePixel(); 1851 if ( PushButton::GetText().Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) ) 1852 { 1853 sal_uLong nDrawFlags = 0; 1854 Size textSize = GetTextRect( Rectangle( Point(), Size( nMaxWidth ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ), 1855 PushButton::GetText(), ImplGetTextStyle( nDrawFlags ) ).GetSize(); 1856 aSize.Width() += int( textSize.Width () * 1.15 ); 1857 aSize.Height() = std::max( aSize.Height(), long( textSize.Height() * 1.15 ) ); 1858 } 1859 1860 // cf. ImplDrawPushButton ... 1861 if( (GetStyle() & WB_SMALLSTYLE) == 0 ) 1862 { 1863 aSize.Width() += 8; 1864 aSize.Height() += 8; 1865 } 1866 1867 return CalcWindowSize( aSize ); 1868 } 1869 1870 Size PushButton::GetOptimalSize(WindowSizeType eType) const 1871 { 1872 switch (eType) { 1873 case WINDOWSIZE_MINIMUM: { 1874 return CalcMinimumSize(); 1875 } 1876 default: 1877 return Button::GetOptimalSize( eType ); 1878 } 1879 } 1880 1881 // ======================================================================= 1882 1883 void OKButton::ImplInit( Window* pParent, WinBits nStyle ) 1884 { 1885 PushButton::ImplInit( pParent, nStyle ); 1886 1887 SetText( Button::GetStandardText( BUTTON_OK ) ); 1888 SetHelpText( Button::GetStandardHelpText( BUTTON_OK ) ); 1889 } 1890 1891 // ----------------------------------------------------------------------- 1892 1893 OKButton::OKButton( Window* pParent, WinBits nStyle ) : 1894 PushButton( WINDOW_OKBUTTON ) 1895 { 1896 ImplInit( pParent, nStyle ); 1897 } 1898 1899 // ----------------------------------------------------------------------- 1900 1901 OKButton::OKButton( Window* pParent, const ResId& rResId ) : 1902 PushButton( WINDOW_OKBUTTON ) 1903 { 1904 rResId.SetRT( RSC_OKBUTTON ); 1905 WinBits nStyle = ImplInitRes( rResId ); 1906 ImplInit( pParent, nStyle ); 1907 ImplLoadRes( rResId ); 1908 1909 if ( !(nStyle & WB_HIDE) ) 1910 Show(); 1911 } 1912 1913 // ----------------------------------------------------------------------- 1914 1915 void OKButton::Click() 1916 { 1917 // Ist kein Link gesetzt, dann schliesse Parent 1918 if ( !GetClickHdl() ) 1919 { 1920 Window* pParent = GetParent(); 1921 if ( pParent->IsSystemWindow() ) 1922 { 1923 if ( pParent->IsDialog() ) 1924 { 1925 if ( ((Dialog*)pParent)->IsInExecute() ) 1926 ((Dialog*)pParent)->EndDialog( sal_True ); 1927 // gegen rekursive Aufrufe schuetzen 1928 else if ( !((Dialog*)pParent)->IsInClose() ) 1929 { 1930 if ( pParent->GetStyle() & WB_CLOSEABLE ) 1931 ((Dialog*)pParent)->Close(); 1932 } 1933 } 1934 else 1935 { 1936 if ( pParent->GetStyle() & WB_CLOSEABLE ) 1937 ((SystemWindow*)pParent)->Close(); 1938 } 1939 } 1940 } 1941 else 1942 { 1943 PushButton::Click(); 1944 } 1945 } 1946 1947 // ======================================================================= 1948 1949 void CancelButton::ImplInit( Window* pParent, WinBits nStyle ) 1950 { 1951 PushButton::ImplInit( pParent, nStyle ); 1952 1953 SetText( Button::GetStandardText( BUTTON_CANCEL ) ); 1954 SetHelpText( Button::GetStandardHelpText( BUTTON_CANCEL ) ); 1955 } 1956 1957 // ----------------------------------------------------------------------- 1958 1959 CancelButton::CancelButton( Window* pParent, WinBits nStyle ) : 1960 PushButton( WINDOW_CANCELBUTTON ) 1961 { 1962 ImplInit( pParent, nStyle ); 1963 } 1964 1965 // ----------------------------------------------------------------------- 1966 1967 CancelButton::CancelButton( Window* pParent, const ResId& rResId ) : 1968 PushButton( WINDOW_CANCELBUTTON ) 1969 { 1970 rResId.SetRT( RSC_CANCELBUTTON ); 1971 WinBits nStyle = ImplInitRes( rResId ); 1972 ImplInit( pParent, nStyle ); 1973 ImplLoadRes( rResId ); 1974 1975 if ( !(nStyle & WB_HIDE) ) 1976 Show(); 1977 } 1978 1979 // ----------------------------------------------------------------------- 1980 1981 void CancelButton::Click() 1982 { 1983 // Ist kein Link gesetzt, dann schliesse Parent 1984 if ( !GetClickHdl() ) 1985 { 1986 Window* pParent = GetParent(); 1987 if ( pParent->IsSystemWindow() ) 1988 { 1989 if ( pParent->IsDialog() ) 1990 { 1991 if ( ((Dialog*)pParent)->IsInExecute() ) 1992 ((Dialog*)pParent)->EndDialog( sal_False ); 1993 // gegen rekursive Aufrufe schuetzen 1994 else if ( !((Dialog*)pParent)->IsInClose() ) 1995 { 1996 if ( pParent->GetStyle() & WB_CLOSEABLE ) 1997 ((Dialog*)pParent)->Close(); 1998 } 1999 } 2000 else 2001 { 2002 if ( pParent->GetStyle() & WB_CLOSEABLE ) 2003 ((SystemWindow*)pParent)->Close(); 2004 } 2005 } 2006 } 2007 else 2008 { 2009 PushButton::Click(); 2010 } 2011 } 2012 2013 // ======================================================================= 2014 2015 void HelpButton::ImplInit( Window* pParent, WinBits nStyle ) 2016 { 2017 PushButton::ImplInit( pParent, nStyle | WB_NOPOINTERFOCUS ); 2018 2019 SetText( Button::GetStandardText( BUTTON_HELP ) ); 2020 SetHelpText( Button::GetStandardHelpText( BUTTON_HELP ) ); 2021 } 2022 2023 // ----------------------------------------------------------------------- 2024 2025 HelpButton::HelpButton( Window* pParent, WinBits nStyle ) : 2026 PushButton( WINDOW_HELPBUTTON ) 2027 { 2028 ImplInit( pParent, nStyle ); 2029 } 2030 2031 // ----------------------------------------------------------------------- 2032 2033 HelpButton::HelpButton( Window* pParent, const ResId& rResId ) : 2034 PushButton( WINDOW_HELPBUTTON ) 2035 { 2036 rResId.SetRT( RSC_HELPBUTTON ); 2037 WinBits nStyle = ImplInitRes( rResId ); 2038 ImplInit( pParent, nStyle ); 2039 ImplLoadRes( rResId ); 2040 2041 if ( !(nStyle & WB_HIDE) ) 2042 Show(); 2043 } 2044 2045 // ----------------------------------------------------------------------- 2046 2047 void HelpButton::Click() 2048 { 2049 // Ist kein Link gesetzt, loese Hilfe aus 2050 if ( !GetClickHdl() ) 2051 { 2052 Window* pFocusWin = Application::GetFocusWindow(); 2053 if ( !pFocusWin ) 2054 pFocusWin = this; 2055 2056 HelpEvent aEvt( pFocusWin->GetPointerPosPixel(), HELPMODE_CONTEXT ); 2057 pFocusWin->RequestHelp( aEvt ); 2058 } 2059 PushButton::Click(); 2060 } 2061 2062 // ======================================================================= 2063 2064 void RadioButton::ImplInitRadioButtonData() 2065 { 2066 mbChecked = sal_False; 2067 mbSaveValue = sal_False; 2068 mbRadioCheck = sal_True; 2069 mbStateChanged = sal_False; 2070 } 2071 2072 // ----------------------------------------------------------------------- 2073 2074 void RadioButton::ImplInit( Window* pParent, WinBits nStyle ) 2075 { 2076 nStyle = ImplInitStyle( pParent->GetWindow( WINDOW_LASTCHILD ), nStyle ); 2077 Button::ImplInit( pParent, nStyle, NULL ); 2078 2079 ImplInitSettings( sal_True, sal_True, sal_True ); 2080 } 2081 2082 // ----------------------------------------------------------------------- 2083 2084 WinBits RadioButton::ImplInitStyle( const Window* pPrevWindow, WinBits nStyle ) 2085 { 2086 if ( !(nStyle & WB_NOGROUP) && 2087 (!pPrevWindow || (pPrevWindow->GetType() != WINDOW_RADIOBUTTON)) ) 2088 nStyle |= WB_GROUP; 2089 if ( !(nStyle & WB_NOTABSTOP) ) 2090 { 2091 if ( IsChecked() ) 2092 nStyle |= WB_TABSTOP; 2093 else 2094 nStyle &= ~WB_TABSTOP; 2095 } 2096 return nStyle; 2097 } 2098 2099 // ----------------------------------------------------------------- 2100 2101 const Font& RadioButton::GetCanonicalFont( const StyleSettings& _rStyle ) const 2102 { 2103 return _rStyle.GetRadioCheckFont(); 2104 } 2105 2106 // ----------------------------------------------------------------- 2107 const Color& RadioButton::GetCanonicalTextColor( const StyleSettings& _rStyle ) const 2108 { 2109 return _rStyle.GetRadioCheckTextColor(); 2110 } 2111 2112 // ----------------------------------------------------------------------- 2113 2114 void RadioButton::ImplInitSettings( sal_Bool bFont, 2115 sal_Bool bForeground, sal_Bool bBackground ) 2116 { 2117 Button::ImplInitSettings( bFont, bForeground ); 2118 2119 if ( bBackground ) 2120 { 2121 Window* pParent = GetParent(); 2122 if ( !IsControlBackground() && 2123 (pParent->IsChildTransparentModeEnabled() || IsNativeControlSupported( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL ) ) ) 2124 { 2125 EnableChildTransparentMode( sal_True ); 2126 SetParentClipMode( PARENTCLIPMODE_NOCLIP ); 2127 SetPaintTransparent( sal_True ); 2128 SetBackground(); 2129 if( IsNativeControlSupported( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL ) ) 2130 mpWindowImpl->mbUseNativeFocus = ImplGetSVData()->maNWFData.mbNoFocusRects; 2131 } 2132 else 2133 { 2134 EnableChildTransparentMode( sal_False ); 2135 SetParentClipMode( 0 ); 2136 SetPaintTransparent( sal_False ); 2137 2138 if ( IsControlBackground() ) 2139 SetBackground( GetControlBackground() ); 2140 else 2141 SetBackground( pParent->GetBackground() ); 2142 } 2143 } 2144 } 2145 2146 //--------------------------------------------------------------------- 2147 //--- 12.03.2003 18:46:14 --------------------------------------------- 2148 2149 void RadioButton::DrawRadioButtonState( ) 2150 { 2151 ImplDrawRadioButtonState( ); 2152 } 2153 2154 // ----------------------------------------------------------------------- 2155 2156 void RadioButton::ImplInvalidateOrDrawRadioButtonState() 2157 { 2158 if( ImplGetSVData()->maNWFData.mbCheckBoxNeedsErase ) 2159 { 2160 if ( IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL) ) 2161 { 2162 Invalidate(); 2163 Update(); 2164 return; 2165 } 2166 } 2167 ImplDrawRadioButtonState(); 2168 } 2169 2170 void RadioButton::ImplDrawRadioButtonState() 2171 { 2172 sal_uInt16 nButtonStyle = 0; 2173 sal_Bool bNativeOK = sal_False; 2174 2175 // no native drawing for image radio buttons 2176 if ( !maImage && (bNativeOK=IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL)) == sal_True ) 2177 { 2178 ImplControlValue aControlValue( mbChecked ? BUTTONVALUE_ON : BUTTONVALUE_OFF ); 2179 Rectangle aCtrlRect( maStateRect.TopLeft(), maStateRect.GetSize() ); 2180 ControlState nState = 0; 2181 2182 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) nState |= CTRL_STATE_PRESSED; 2183 if ( HasFocus() ) nState |= CTRL_STATE_FOCUSED; 2184 if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT ) nState |= CTRL_STATE_DEFAULT; 2185 if ( IsEnabled() ) nState |= CTRL_STATE_ENABLED; 2186 2187 if ( IsMouseOver() && maMouseRect.IsInside( GetPointerPosPixel() ) ) 2188 nState |= CTRL_STATE_ROLLOVER; 2189 2190 bNativeOK = DrawNativeControl( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL, aCtrlRect, nState, 2191 aControlValue,rtl::OUString() ); 2192 2193 } 2194 2195 if ( bNativeOK == sal_False ) 2196 { 2197 // kein Image-RadioButton 2198 if ( !maImage ) 2199 { 2200 sal_uInt16 nStyle = ImplGetButtonState(); 2201 if ( !IsEnabled() ) 2202 nStyle |= BUTTON_DRAW_DISABLED; 2203 if ( mbChecked ) 2204 nStyle |= BUTTON_DRAW_CHECKED; 2205 Image aImage = GetRadioImage( GetSettings(), nStyle ); 2206 if ( IsZoom() ) 2207 DrawImage( maStateRect.TopLeft(), maStateRect.GetSize(), aImage ); 2208 else 2209 DrawImage( maStateRect.TopLeft(), aImage ); 2210 } 2211 else 2212 { 2213 HideFocus(); 2214 2215 DecorationView aDecoView( this ); 2216 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 2217 Rectangle aImageRect = maStateRect; 2218 Size aImageSize = maImage.GetSizePixel(); 2219 sal_Bool bEnabled = IsEnabled(); 2220 2221 aImageSize.Width() = CalcZoom( aImageSize.Width() ); 2222 aImageSize.Height() = CalcZoom( aImageSize.Height() ); 2223 2224 // Border und Selektionsstatus ausgeben 2225 nButtonStyle = FRAME_DRAW_DOUBLEIN; 2226 aImageRect = aDecoView.DrawFrame( aImageRect, nButtonStyle ); 2227 if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) || !bEnabled ) 2228 SetFillColor( rStyleSettings.GetFaceColor() ); 2229 else 2230 SetFillColor( rStyleSettings.GetFieldColor() ); 2231 SetLineColor(); 2232 DrawRect( aImageRect ); 2233 2234 // Image ausgeben 2235 nButtonStyle = 0; 2236 if ( !bEnabled ) 2237 nButtonStyle |= IMAGE_DRAW_DISABLE; 2238 2239 // check for HC mode 2240 Image *pImage = &maImage; 2241 if( !!maImageHC ) 2242 { 2243 if( rStyleSettings.GetHighContrastMode() ) 2244 pImage = &maImageHC; 2245 } 2246 2247 Point aImagePos( aImageRect.TopLeft() ); 2248 aImagePos.X() += (aImageRect.GetWidth()-aImageSize.Width())/2; 2249 aImagePos.Y() += (aImageRect.GetHeight()-aImageSize.Height())/2; 2250 if ( IsZoom() ) 2251 DrawImage( aImagePos, aImageSize, *pImage, nButtonStyle ); 2252 else 2253 DrawImage( aImagePos, *pImage, nButtonStyle ); 2254 2255 aImageRect.Left()++; 2256 aImageRect.Top()++; 2257 aImageRect.Right()--; 2258 aImageRect.Bottom()--; 2259 2260 ImplSetFocusRect( aImageRect ); 2261 2262 if ( mbChecked ) 2263 { 2264 SetLineColor( rStyleSettings.GetHighlightColor() ); 2265 SetFillColor(); 2266 if ( (aImageSize.Width() >= 20) || (aImageSize.Height() >= 20) ) 2267 { 2268 aImageRect.Left()++; 2269 aImageRect.Top()++; 2270 aImageRect.Right()--; 2271 aImageRect.Bottom()--; 2272 } 2273 DrawRect( aImageRect ); 2274 aImageRect.Left()++; 2275 aImageRect.Top()++; 2276 aImageRect.Right()--; 2277 aImageRect.Bottom()--; 2278 DrawRect( aImageRect ); 2279 } 2280 2281 if ( HasFocus() ) 2282 ShowFocus( ImplGetFocusRect() ); 2283 } 2284 } 2285 } 2286 2287 // ----------------------------------------------------------------------- 2288 2289 void RadioButton::ImplDraw( OutputDevice* pDev, sal_uLong nDrawFlags, 2290 const Point& rPos, const Size& rSize, 2291 const Size& rImageSize, Rectangle& rStateRect, 2292 Rectangle& rMouseRect, bool bLayout ) 2293 { 2294 WinBits nWinStyle = GetStyle(); 2295 XubString aText( GetText() ); 2296 Rectangle aRect( rPos, rSize ); 2297 MetricVector* pVector = bLayout ? &mpControlData->mpLayoutData->m_aUnicodeBoundRects : NULL; 2298 String* pDisplayText = bLayout ? &mpControlData->mpLayoutData->m_aDisplayText : NULL; 2299 2300 pDev->Push( PUSH_CLIPREGION ); 2301 pDev->IntersectClipRegion( Rectangle( rPos, rSize ) ); 2302 2303 // kein Image-RadioButton 2304 if ( !maImage ) 2305 { 2306 if ( ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) ) || 2307 ( HasImage() && ! (ImplGetButtonState() & BUTTON_DRAW_NOIMAGE) ) ) 2308 { 2309 sal_uInt16 nTextStyle = Button::ImplGetTextStyle( aText, nWinStyle, nDrawFlags ); 2310 2311 const long nImageSep = GetDrawPixel( pDev, ImplGetImageToTextDistance() ); 2312 Size aSize( rSize ); 2313 Point aPos( rPos ); 2314 aPos.X() += rImageSize.Width() + nImageSep; 2315 aSize.Width() -= rImageSize.Width() + nImageSep; 2316 2317 // if the text rect height is smaller than the height of the image 2318 // then for single lines the default should be centered text 2319 if( (nWinStyle & (WB_TOP|WB_VCENTER|WB_BOTTOM)) == 0 && 2320 (rImageSize.Height() > rSize.Height() || ! (nWinStyle & WB_WORDBREAK) ) ) 2321 { 2322 nTextStyle &= ~(TEXT_DRAW_TOP|TEXT_DRAW_BOTTOM); 2323 nTextStyle |= TEXT_DRAW_VCENTER; 2324 aSize.Height() = rImageSize.Height(); 2325 } 2326 2327 ImplDrawAlignedImage( pDev, aPos, aSize, bLayout, 1, 2328 nDrawFlags, nTextStyle, NULL ); 2329 2330 rMouseRect = Rectangle( aPos, aSize ); 2331 rMouseRect.Left() = rPos.X(); 2332 2333 rStateRect.Left() = rPos.X(); 2334 rStateRect.Top() = rMouseRect.Top(); 2335 2336 if ( aSize.Height() > rImageSize.Height() ) 2337 rStateRect.Top() += ( aSize.Height() - rImageSize.Height() ) / 2; 2338 else 2339 { 2340 rStateRect.Top() -= ( rImageSize.Height() - aSize.Height() ) / 2; 2341 if( rStateRect.Top() < 0 ) 2342 rStateRect.Top() = 0; 2343 } 2344 2345 rStateRect.Right() = rStateRect.Left() + rImageSize.Width()-1; 2346 rStateRect.Bottom() = rStateRect.Top() + rImageSize.Height()-1; 2347 2348 if ( rStateRect.Bottom() > rMouseRect.Bottom() ) 2349 rMouseRect.Bottom() = rStateRect.Bottom(); 2350 } 2351 else 2352 { 2353 if ( nWinStyle & WB_CENTER ) 2354 rStateRect.Left() = rPos.X()+((rSize.Width()-rImageSize.Width())/2); 2355 else if ( nWinStyle & WB_RIGHT ) 2356 rStateRect.Left() = rPos.X()+rSize.Width()-rImageSize.Width(); //-1; 2357 else 2358 rStateRect.Left() = rPos.X(); //+1; 2359 if ( nWinStyle & WB_VCENTER ) 2360 rStateRect.Top() = rPos.Y()+((rSize.Height()-rImageSize.Height())/2); 2361 else if ( nWinStyle & WB_BOTTOM ) 2362 rStateRect.Top() = rPos.Y()+rSize.Height()-rImageSize.Height(); //-1; 2363 else 2364 rStateRect.Top() = rPos.Y(); //+1; 2365 rStateRect.Right() = rStateRect.Left()+rImageSize.Width()-1; 2366 rStateRect.Bottom() = rStateRect.Top()+rImageSize.Height()-1; 2367 rMouseRect = rStateRect; 2368 2369 ImplSetFocusRect( rStateRect ); 2370 2371 /* und oben -1, da CalcSize() auch Focus-Rechteck nicht mit einrechnet, 2372 da im Writer ansonsten die Images noch weiter oben haengen 2373 rFocusRect = rStateRect; 2374 rFocusRect.Left()--; 2375 rFocusRect.Top()--; 2376 rFocusRect.Right()++; 2377 rFocusRect.Bottom()++; 2378 */ 2379 } 2380 } 2381 else 2382 { 2383 sal_Bool bTopImage = (nWinStyle & WB_TOP) != 0; 2384 Size aImageSize = maImage.GetSizePixel(); 2385 Rectangle aImageRect( rPos, rSize ); 2386 long nTextHeight = pDev->GetTextHeight(); 2387 long nTextWidth = pDev->GetCtrlTextWidth( aText ); 2388 2389 // Positionen und Groessen berechnen 2390 if ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) ) 2391 { 2392 Size aTmpSize( (aImageSize.Width()+8), (aImageSize.Height()+8) ); 2393 if ( bTopImage ) 2394 { 2395 aImageRect.Left() = (rSize.Width()-aTmpSize.Width())/2; 2396 aImageRect.Top() = (rSize.Height()-(aTmpSize.Height()+nTextHeight+6))/2; 2397 } 2398 else 2399 aImageRect.Top() = (rSize.Height()-aTmpSize.Height())/2; 2400 2401 aImageRect.Right() = aImageRect.Left()+aTmpSize.Width(); 2402 aImageRect.Bottom() = aImageRect.Top()+aTmpSize.Height(); 2403 2404 // Text ausgeben 2405 Point aTxtPos = rPos; 2406 if ( bTopImage ) 2407 { 2408 aTxtPos.X() += (rSize.Width()-nTextWidth)/2; 2409 aTxtPos.Y() += aImageRect.Bottom()+6; 2410 } 2411 else 2412 { 2413 aTxtPos.X() += aImageRect.Right()+8; 2414 aTxtPos.Y() += (rSize.Height()-nTextHeight)/2; 2415 } 2416 pDev->DrawCtrlText( aTxtPos, aText, 0, STRING_LEN, TEXT_DRAW_MNEMONIC, pVector, pDisplayText ); 2417 } 2418 2419 rMouseRect = aImageRect; 2420 rStateRect = aImageRect; 2421 } 2422 2423 pDev->Pop(); 2424 } 2425 2426 // ----------------------------------------------------------------------- 2427 2428 void RadioButton::ImplDrawRadioButton( bool bLayout ) 2429 { 2430 if( !bLayout ) 2431 HideFocus(); 2432 2433 Size aImageSize; 2434 if ( !maImage ) 2435 aImageSize = ImplGetRadioImageSize(); 2436 else 2437 aImageSize = maImage.GetSizePixel(); 2438 aImageSize.Width() = CalcZoom( aImageSize.Width() ); 2439 aImageSize.Height() = CalcZoom( aImageSize.Height() ); 2440 2441 // Draw control text 2442 ImplDraw( this, 0, Point(), GetOutputSizePixel(), 2443 aImageSize, maStateRect, maMouseRect, bLayout ); 2444 2445 if( !bLayout || (IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL)==sal_True) ) 2446 { 2447 if ( !maImage && HasFocus() ) 2448 ShowFocus( ImplGetFocusRect() ); 2449 2450 ImplDrawRadioButtonState(); 2451 } 2452 } 2453 2454 // ----------------------------------------------------------------------- 2455 2456 void RadioButton::GetRadioButtonGroup( std::vector< RadioButton* >& io_rGroup, bool bIncludeThis ) const 2457 { 2458 // empty the list 2459 io_rGroup.clear(); 2460 2461 // go back to first in group; 2462 Window* pFirst = const_cast<RadioButton*>(this); 2463 while( ( pFirst->GetStyle() & WB_GROUP ) == 0 ) 2464 { 2465 Window* pWindow = pFirst->GetWindow( WINDOW_PREV ); 2466 if( pWindow ) 2467 pFirst = pWindow; 2468 else 2469 break; 2470 } 2471 // insert radiobuttons up to next group 2472 do 2473 { 2474 if( pFirst->GetType() == WINDOW_RADIOBUTTON ) 2475 { 2476 if( pFirst != this || bIncludeThis ) 2477 io_rGroup.push_back( static_cast<RadioButton*>(pFirst) ); 2478 } 2479 pFirst = pFirst->GetWindow( WINDOW_NEXT ); 2480 } while( pFirst && ( ( pFirst->GetStyle() & WB_GROUP ) == 0 ) ); 2481 } 2482 2483 // ----------------------------------------------------------------------- 2484 2485 void RadioButton::ImplUncheckAllOther() 2486 { 2487 mpWindowImpl->mnStyle |= WB_TABSTOP; 2488 2489 // Gruppe mit RadioButtons durchgehen und die gecheckten Buttons 2490 Window* pWindow; 2491 WinBits nStyle; 2492 if ( !(GetStyle() & WB_GROUP) ) 2493 { 2494 pWindow = GetWindow( WINDOW_PREV ); 2495 while ( pWindow ) 2496 { 2497 nStyle = pWindow->GetStyle(); 2498 2499 if ( pWindow->GetType() == WINDOW_RADIOBUTTON ) 2500 { 2501 if ( ((RadioButton*)pWindow)->IsChecked() ) 2502 { 2503 ImplDelData aDelData; 2504 pWindow->ImplAddDel( &aDelData ); 2505 ((RadioButton*)pWindow)->SetState( sal_False ); 2506 if ( aDelData.IsDelete() ) 2507 return; 2508 pWindow->ImplRemoveDel( &aDelData ); 2509 } 2510 // Um falsch gesetzt WB_TABSTOPS immer zu entfernen, nicht 2511 // innerhalb der if-Abfrage 2512 pWindow->mpWindowImpl->mnStyle &= ~WB_TABSTOP; 2513 } 2514 2515 if ( nStyle & WB_GROUP ) 2516 break; 2517 2518 pWindow = pWindow->GetWindow( WINDOW_PREV ); 2519 } 2520 } 2521 2522 pWindow = GetWindow( WINDOW_NEXT ); 2523 while ( pWindow ) 2524 { 2525 nStyle = pWindow->GetStyle(); 2526 2527 if ( nStyle & WB_GROUP ) 2528 break; 2529 2530 if ( pWindow->GetType() == WINDOW_RADIOBUTTON ) 2531 { 2532 if ( ((RadioButton*)pWindow)->IsChecked() ) 2533 { 2534 ImplDelData aDelData; 2535 pWindow->ImplAddDel( &aDelData ); 2536 ((RadioButton*)pWindow)->SetState( sal_False ); 2537 if ( aDelData.IsDelete() ) 2538 return; 2539 pWindow->ImplRemoveDel( &aDelData ); 2540 } 2541 // Um falsch gesetzt WB_TABSTOPS immer zu entfernen, nicht 2542 // innerhalb der if-Abfrage 2543 pWindow->mpWindowImpl->mnStyle &= ~WB_TABSTOP; 2544 } 2545 2546 pWindow = pWindow->GetWindow( WINDOW_NEXT ); 2547 } 2548 } 2549 2550 // ----------------------------------------------------------------------- 2551 2552 void RadioButton::ImplCallClick( sal_Bool bGrabFocus, sal_uInt16 nFocusFlags ) 2553 { 2554 mbStateChanged = !mbChecked; 2555 mbChecked = sal_True; 2556 mpWindowImpl->mnStyle |= WB_TABSTOP; 2557 ImplInvalidateOrDrawRadioButtonState(); 2558 ImplDelData aDelData; 2559 ImplAddDel( &aDelData ); 2560 if ( mbRadioCheck ) 2561 ImplUncheckAllOther(); 2562 if ( aDelData.IsDelete() ) 2563 return; 2564 if ( bGrabFocus ) 2565 ImplGrabFocus( nFocusFlags ); 2566 if ( aDelData.IsDelete() ) 2567 return; 2568 if ( mbStateChanged ) 2569 Toggle(); 2570 if ( aDelData.IsDelete() ) 2571 return; 2572 Click(); 2573 if ( aDelData.IsDelete() ) 2574 return; 2575 ImplRemoveDel( &aDelData ); 2576 mbStateChanged = sal_False; 2577 } 2578 2579 // ----------------------------------------------------------------------- 2580 2581 RadioButton::RadioButton( Window* pParent, WinBits nStyle ) : 2582 Button( WINDOW_RADIOBUTTON ) 2583 { 2584 ImplInitRadioButtonData(); 2585 ImplInit( pParent, nStyle ); 2586 } 2587 2588 // ----------------------------------------------------------------------- 2589 2590 RadioButton::RadioButton( Window* pParent, const ResId& rResId ) : 2591 Button( WINDOW_RADIOBUTTON ) 2592 { 2593 ImplInitRadioButtonData(); 2594 rResId.SetRT( RSC_RADIOBUTTON ); 2595 WinBits nStyle = ImplInitRes( rResId ); 2596 ImplInit( pParent, nStyle ); 2597 ImplLoadRes( rResId ); 2598 2599 if ( !(nStyle & WB_HIDE) ) 2600 Show(); 2601 } 2602 2603 // ----------------------------------------------------------------------- 2604 2605 void RadioButton::ImplLoadRes( const ResId& rResId ) 2606 { 2607 Button::ImplLoadRes( rResId ); 2608 2609 //anderer Wert als Default ? 2610 sal_uInt16 nChecked = ReadShortRes(); 2611 if ( nChecked ) 2612 SetState( sal_True ); 2613 } 2614 2615 // ----------------------------------------------------------------------- 2616 2617 RadioButton::~RadioButton() 2618 { 2619 } 2620 2621 // ----------------------------------------------------------------------- 2622 2623 void RadioButton::MouseButtonDown( const MouseEvent& rMEvt ) 2624 { 2625 if ( rMEvt.IsLeft() && maMouseRect.IsInside( rMEvt.GetPosPixel() ) ) 2626 { 2627 ImplGetButtonState() |= BUTTON_DRAW_PRESSED; 2628 ImplInvalidateOrDrawRadioButtonState(); 2629 StartTracking(); 2630 return; 2631 } 2632 2633 Button::MouseButtonDown( rMEvt ); 2634 } 2635 2636 // ----------------------------------------------------------------------- 2637 2638 void RadioButton::Tracking( const TrackingEvent& rTEvt ) 2639 { 2640 if ( rTEvt.IsTrackingEnded() ) 2641 { 2642 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) 2643 { 2644 if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() ) 2645 GrabFocus(); 2646 2647 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 2648 2649 // Bei Abbruch kein Click-Handler rufen 2650 if ( !rTEvt.IsTrackingCanceled() ) 2651 ImplCallClick(); 2652 else 2653 ImplInvalidateOrDrawRadioButtonState(); 2654 } 2655 } 2656 else 2657 { 2658 if ( maMouseRect.IsInside( rTEvt.GetMouseEvent().GetPosPixel() ) ) 2659 { 2660 if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) ) 2661 { 2662 ImplGetButtonState() |= BUTTON_DRAW_PRESSED; 2663 ImplInvalidateOrDrawRadioButtonState(); 2664 } 2665 } 2666 else 2667 { 2668 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) 2669 { 2670 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 2671 ImplInvalidateOrDrawRadioButtonState(); 2672 } 2673 } 2674 } 2675 } 2676 2677 // ----------------------------------------------------------------------- 2678 2679 void RadioButton::KeyInput( const KeyEvent& rKEvt ) 2680 { 2681 KeyCode aKeyCode = rKEvt.GetKeyCode(); 2682 2683 if ( !aKeyCode.GetModifier() && (aKeyCode.GetCode() == KEY_SPACE) ) 2684 { 2685 if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) ) 2686 { 2687 ImplGetButtonState() |= BUTTON_DRAW_PRESSED; 2688 ImplInvalidateOrDrawRadioButtonState(); 2689 } 2690 } 2691 else if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_ESCAPE) ) 2692 { 2693 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 2694 ImplInvalidateOrDrawRadioButtonState(); 2695 } 2696 else 2697 Button::KeyInput( rKEvt ); 2698 } 2699 2700 // ----------------------------------------------------------------------- 2701 2702 void RadioButton::KeyUp( const KeyEvent& rKEvt ) 2703 { 2704 KeyCode aKeyCode = rKEvt.GetKeyCode(); 2705 2706 if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_SPACE) ) 2707 { 2708 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 2709 ImplCallClick(); 2710 } 2711 else 2712 Button::KeyUp( rKEvt ); 2713 } 2714 2715 // ----------------------------------------------------------------------- 2716 2717 void RadioButton::FillLayoutData() const 2718 { 2719 mpControlData->mpLayoutData = new vcl::ControlLayoutData(); 2720 const_cast<RadioButton*>(this)->ImplDrawRadioButton( true ); 2721 } 2722 2723 // ----------------------------------------------------------------------- 2724 2725 void RadioButton::Paint( const Rectangle& ) 2726 { 2727 ImplDrawRadioButton(); 2728 } 2729 2730 // ----------------------------------------------------------------------- 2731 2732 void RadioButton::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, 2733 sal_uLong nFlags ) 2734 { 2735 if ( !maImage ) 2736 { 2737 MapMode aResMapMode( MAP_100TH_MM ); 2738 Point aPos = pDev->LogicToPixel( rPos ); 2739 Size aSize = pDev->LogicToPixel( rSize ); 2740 Size aImageSize = pDev->LogicToPixel( Size( 300, 300 ), aResMapMode ); 2741 Size aBrd1Size = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode ); 2742 Size aBrd2Size = pDev->LogicToPixel( Size( 60, 60 ), aResMapMode ); 2743 Font aFont = GetDrawPixelFont( pDev ); 2744 Rectangle aStateRect; 2745 Rectangle aMouseRect; 2746 Rectangle aFocusRect; 2747 2748 aImageSize.Width() = CalcZoom( aImageSize.Width() ); 2749 aImageSize.Height() = CalcZoom( aImageSize.Height() ); 2750 aBrd1Size.Width() = CalcZoom( aBrd1Size.Width() ); 2751 aBrd1Size.Height() = CalcZoom( aBrd1Size.Height() ); 2752 aBrd2Size.Width() = CalcZoom( aBrd2Size.Width() ); 2753 aBrd2Size.Height() = CalcZoom( aBrd2Size.Height() ); 2754 2755 if ( !aBrd1Size.Width() ) 2756 aBrd1Size.Width() = 1; 2757 if ( !aBrd1Size.Height() ) 2758 aBrd1Size.Height() = 1; 2759 if ( !aBrd2Size.Width() ) 2760 aBrd2Size.Width() = 1; 2761 if ( !aBrd2Size.Height() ) 2762 aBrd2Size.Height() = 1; 2763 2764 pDev->Push(); 2765 pDev->SetMapMode(); 2766 pDev->SetFont( aFont ); 2767 if ( nFlags & WINDOW_DRAW_MONO ) 2768 pDev->SetTextColor( Color( COL_BLACK ) ); 2769 else 2770 pDev->SetTextColor( GetTextColor() ); 2771 pDev->SetTextFillColor(); 2772 2773 ImplDraw( pDev, nFlags, aPos, aSize, 2774 aImageSize, aStateRect, aMouseRect ); 2775 2776 Point aCenterPos = aStateRect.Center(); 2777 long nRadX = aImageSize.Width()/2; 2778 long nRadY = aImageSize.Height()/2; 2779 2780 pDev->SetLineColor(); 2781 pDev->SetFillColor( Color( COL_BLACK ) ); 2782 pDev->DrawPolygon( Polygon( aCenterPos, nRadX, nRadY ) ); 2783 nRadX -= aBrd1Size.Width(); 2784 nRadY -= aBrd1Size.Height(); 2785 pDev->SetFillColor( Color( COL_WHITE ) ); 2786 pDev->DrawPolygon( Polygon( aCenterPos, nRadX, nRadY ) ); 2787 if ( mbChecked ) 2788 { 2789 nRadX -= aBrd1Size.Width(); 2790 nRadY -= aBrd1Size.Height(); 2791 if ( !nRadX ) 2792 nRadX = 1; 2793 if ( !nRadY ) 2794 nRadY = 1; 2795 pDev->SetFillColor( Color( COL_BLACK ) ); 2796 pDev->DrawPolygon( Polygon( aCenterPos, nRadX, nRadY ) ); 2797 } 2798 2799 pDev->Pop(); 2800 } 2801 else 2802 { 2803 DBG_ERROR( "RadioButton::Draw() - not implemented for RadioButton with Image" ); 2804 } 2805 } 2806 2807 // ----------------------------------------------------------------------- 2808 2809 void RadioButton::Resize() 2810 { 2811 Control::Resize(); 2812 Invalidate(); 2813 } 2814 2815 // ----------------------------------------------------------------------- 2816 2817 void RadioButton::GetFocus() 2818 { 2819 ShowFocus( ImplGetFocusRect() ); 2820 SetInputContext( InputContext( GetFont() ) ); 2821 Button::GetFocus(); 2822 } 2823 2824 // ----------------------------------------------------------------------- 2825 2826 void RadioButton::LoseFocus() 2827 { 2828 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) 2829 { 2830 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 2831 ImplInvalidateOrDrawRadioButtonState(); 2832 } 2833 2834 HideFocus(); 2835 Button::LoseFocus(); 2836 } 2837 2838 // ----------------------------------------------------------------------- 2839 2840 void RadioButton::StateChanged( StateChangedType nType ) 2841 { 2842 Button::StateChanged( nType ); 2843 2844 if ( nType == STATE_CHANGE_STATE ) 2845 { 2846 if ( IsReallyVisible() && IsUpdateMode() ) 2847 Invalidate( maStateRect ); 2848 } 2849 else if ( (nType == STATE_CHANGE_ENABLE) || 2850 (nType == STATE_CHANGE_TEXT) || 2851 (nType == STATE_CHANGE_IMAGE) || 2852 (nType == STATE_CHANGE_DATA) || 2853 (nType == STATE_CHANGE_UPDATEMODE) ) 2854 { 2855 if ( IsUpdateMode() ) 2856 Invalidate(); 2857 } 2858 else if ( nType == STATE_CHANGE_STYLE ) 2859 { 2860 SetStyle( ImplInitStyle( GetWindow( WINDOW_PREV ), GetStyle() ) ); 2861 2862 if ( (GetPrevStyle() & RADIOBUTTON_VIEW_STYLE) != 2863 (GetStyle() & RADIOBUTTON_VIEW_STYLE) ) 2864 { 2865 if ( IsUpdateMode() ) 2866 Invalidate(); 2867 } 2868 } 2869 else if ( (nType == STATE_CHANGE_ZOOM) || 2870 (nType == STATE_CHANGE_CONTROLFONT) ) 2871 { 2872 ImplInitSettings( sal_True, sal_False, sal_False ); 2873 Invalidate(); 2874 } 2875 else if ( nType == STATE_CHANGE_CONTROLFOREGROUND ) 2876 { 2877 ImplInitSettings( sal_False, sal_True, sal_False ); 2878 Invalidate(); 2879 } 2880 else if ( nType == STATE_CHANGE_CONTROLBACKGROUND ) 2881 { 2882 ImplInitSettings( sal_False, sal_False, sal_True ); 2883 Invalidate(); 2884 } 2885 } 2886 2887 // ----------------------------------------------------------------------- 2888 2889 void RadioButton::DataChanged( const DataChangedEvent& rDCEvt ) 2890 { 2891 Button::DataChanged( rDCEvt ); 2892 2893 if ( (rDCEvt.GetType() == DATACHANGED_FONTS) || 2894 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) || 2895 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) && 2896 (rDCEvt.GetFlags() & SETTINGS_STYLE)) ) 2897 { 2898 ImplInitSettings( sal_True, sal_True, sal_True ); 2899 Invalidate(); 2900 } 2901 } 2902 2903 // ----------------------------------------------------------------------- 2904 2905 long RadioButton::PreNotify( NotifyEvent& rNEvt ) 2906 { 2907 long nDone = 0; 2908 const MouseEvent* pMouseEvt = NULL; 2909 2910 if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL ) 2911 { 2912 if( !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() ) 2913 { 2914 // trigger redraw if mouse over state has changed 2915 if( IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL) ) 2916 { 2917 if( ( maMouseRect.IsInside( GetPointerPosPixel()) && 2918 !maMouseRect.IsInside( GetLastPointerPosPixel()) ) || 2919 ( maMouseRect.IsInside( GetLastPointerPosPixel()) && 2920 !maMouseRect.IsInside( GetPointerPosPixel()) ) || 2921 pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow() ) 2922 { 2923 Invalidate( maStateRect ); 2924 } 2925 } 2926 } 2927 } 2928 2929 return nDone ? nDone : Button::PreNotify(rNEvt); 2930 } 2931 2932 // ----------------------------------------------------------------------- 2933 2934 void RadioButton::Toggle() 2935 { 2936 ImplCallEventListenersAndHandler( VCLEVENT_RADIOBUTTON_TOGGLE, maToggleHdl, this ); 2937 } 2938 2939 // ----------------------------------------------------------------------- 2940 2941 sal_Bool RadioButton::SetModeRadioImage( const Image& rImage, BmpColorMode eMode ) 2942 { 2943 if( eMode == BMP_COLOR_NORMAL ) 2944 { 2945 if ( rImage != maImage ) 2946 { 2947 maImage = rImage; 2948 StateChanged( STATE_CHANGE_DATA ); 2949 } 2950 } 2951 else if( eMode == BMP_COLOR_HIGHCONTRAST ) 2952 { 2953 if( maImageHC != rImage ) 2954 { 2955 maImageHC = rImage; 2956 StateChanged( STATE_CHANGE_DATA ); 2957 } 2958 } 2959 else 2960 return sal_False; 2961 2962 return sal_True; 2963 } 2964 2965 // ----------------------------------------------------------------------- 2966 2967 const Image& RadioButton::GetModeRadioImage( BmpColorMode eMode ) const 2968 { 2969 if( eMode == BMP_COLOR_HIGHCONTRAST ) 2970 return maImageHC; 2971 else 2972 return maImage; 2973 } 2974 2975 // ----------------------------------------------------------------------- 2976 2977 void RadioButton::SetState( sal_Bool bCheck ) 2978 { 2979 // TabStop-Flag richtig mitfuehren 2980 if ( bCheck ) 2981 mpWindowImpl->mnStyle |= WB_TABSTOP; 2982 else 2983 mpWindowImpl->mnStyle &= ~WB_TABSTOP; 2984 2985 if ( mbChecked != bCheck ) 2986 { 2987 mbChecked = bCheck; 2988 StateChanged( STATE_CHANGE_STATE ); 2989 Toggle(); 2990 } 2991 } 2992 2993 // ----------------------------------------------------------------------- 2994 2995 void RadioButton::Check( sal_Bool bCheck ) 2996 { 2997 // TabStop-Flag richtig mitfuehren 2998 if ( bCheck ) 2999 mpWindowImpl->mnStyle |= WB_TABSTOP; 3000 else 3001 mpWindowImpl->mnStyle &= ~WB_TABSTOP; 3002 3003 if ( mbChecked != bCheck ) 3004 { 3005 mbChecked = bCheck; 3006 ImplDelData aDelData; 3007 ImplAddDel( &aDelData ); 3008 StateChanged( STATE_CHANGE_STATE ); 3009 if ( aDelData.IsDelete() ) 3010 return; 3011 if ( bCheck && mbRadioCheck ) 3012 ImplUncheckAllOther(); 3013 if ( aDelData.IsDelete() ) 3014 return; 3015 Toggle(); 3016 ImplRemoveDel( &aDelData ); 3017 } 3018 } 3019 3020 // ----------------------------------------------------------------------- 3021 3022 long RadioButton::ImplGetImageToTextDistance() const 3023 { 3024 // 4 pixels, but take zoom into account, so the text doesn't "jump" relative to surrounding elements, 3025 // which might have been aligned with the text of the check box 3026 return CalcZoom( 4 ); 3027 } 3028 3029 // ----------------------------------------------------------------------- 3030 3031 Size RadioButton::ImplGetRadioImageSize() const 3032 { 3033 Size aSize; 3034 // why are IsNativeControlSupported and GetNativeControlRegion not const ? 3035 RadioButton* pThis = const_cast<RadioButton*>(this); 3036 bool bDefaultSize = true; 3037 if( pThis->IsNativeControlSupported( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL ) ) 3038 { 3039 ImplControlValue aControlValue; 3040 // #i45896# workaround gcc3.3 temporary problem 3041 Rectangle aCtrlRegion( Point( 0, 0 ), GetSizePixel() ); 3042 ControlState nState = CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED; 3043 Rectangle aBoundingRgn, aContentRgn; 3044 3045 // get native size of a radio button 3046 if( pThis->GetNativeControlRegion( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion, 3047 nState, aControlValue, rtl::OUString(), 3048 aBoundingRgn, aContentRgn ) ) 3049 { 3050 aSize = aContentRgn.GetSize(); 3051 bDefaultSize = false; 3052 } 3053 } 3054 if( bDefaultSize ) 3055 aSize = GetRadioImage( GetSettings(), 0 ).GetSizePixel(); 3056 return aSize; 3057 } 3058 3059 static void LoadThemedImageList (const StyleSettings &rStyleSettings, 3060 ImageList *pList, const ResId &rResId, 3061 sal_uInt16 nImages) 3062 { 3063 Color aColorAry1[6]; 3064 Color aColorAry2[6]; 3065 aColorAry1[0] = Color( 0xC0, 0xC0, 0xC0 ); 3066 aColorAry1[1] = Color( 0xFF, 0xFF, 0x00 ); 3067 aColorAry1[2] = Color( 0xFF, 0xFF, 0xFF ); 3068 aColorAry1[3] = Color( 0x80, 0x80, 0x80 ); 3069 aColorAry1[4] = Color( 0x00, 0x00, 0x00 ); 3070 aColorAry1[5] = Color( 0x00, 0xFF, 0x00 ); 3071 aColorAry2[0] = rStyleSettings.GetFaceColor(); 3072 aColorAry2[1] = rStyleSettings.GetWindowColor(); 3073 aColorAry2[2] = rStyleSettings.GetLightColor(); 3074 aColorAry2[3] = rStyleSettings.GetShadowColor(); 3075 aColorAry2[4] = rStyleSettings.GetDarkShadowColor(); 3076 aColorAry2[5] = rStyleSettings.GetWindowTextColor(); 3077 3078 Color aMaskColor(0x00, 0x00, 0xFF ); 3079 DBG_ASSERT( sizeof(aColorAry1) == sizeof(aColorAry2), "aColorAry1 must match aColorAry2" ); 3080 // FIXME: do we want the mask for the checkbox ? 3081 pList->InsertFromHorizontalBitmap (rResId, nImages, &aMaskColor, 3082 aColorAry1, aColorAry2, sizeof(aColorAry1) / sizeof(Color)); 3083 } 3084 3085 Image RadioButton::GetRadioImage( const AllSettings& rSettings, sal_uInt16 nFlags ) 3086 { 3087 ImplSVData* pSVData = ImplGetSVData(); 3088 const StyleSettings& rStyleSettings = rSettings.GetStyleSettings(); 3089 sal_uInt16 nStyle = 0; 3090 3091 if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO ) 3092 nStyle = STYLE_RADIOBUTTON_MONO; 3093 3094 if ( !pSVData->maCtrlData.mpRadioImgList || 3095 (pSVData->maCtrlData.mnRadioStyle != nStyle) || 3096 (pSVData->maCtrlData.mnLastRadioFColor != rStyleSettings.GetFaceColor().GetColor()) || 3097 (pSVData->maCtrlData.mnLastRadioWColor != rStyleSettings.GetWindowColor().GetColor()) || 3098 (pSVData->maCtrlData.mnLastRadioLColor != rStyleSettings.GetLightColor().GetColor()) ) 3099 { 3100 if ( pSVData->maCtrlData.mpRadioImgList ) 3101 delete pSVData->maCtrlData.mpRadioImgList; 3102 3103 pSVData->maCtrlData.mnLastRadioFColor = rStyleSettings.GetFaceColor().GetColor(); 3104 pSVData->maCtrlData.mnLastRadioWColor = rStyleSettings.GetWindowColor().GetColor(); 3105 pSVData->maCtrlData.mnLastRadioLColor = rStyleSettings.GetLightColor().GetColor(); 3106 3107 Color pColorAry1[6]; 3108 Color pColorAry2[6]; 3109 pColorAry1[0] = Color( 0xC0, 0xC0, 0xC0 ); 3110 pColorAry1[1] = Color( 0xFF, 0xFF, 0x00 ); 3111 pColorAry1[2] = Color( 0xFF, 0xFF, 0xFF ); 3112 pColorAry1[3] = Color( 0x80, 0x80, 0x80 ); 3113 pColorAry1[4] = Color( 0x00, 0x00, 0x00 ); 3114 pColorAry1[5] = Color( 0x00, 0xFF, 0x00 ); 3115 pColorAry2[0] = rStyleSettings.GetFaceColor(); 3116 pColorAry2[1] = rStyleSettings.GetWindowColor(); 3117 pColorAry2[2] = rStyleSettings.GetLightColor(); 3118 pColorAry2[3] = rStyleSettings.GetShadowColor(); 3119 pColorAry2[4] = rStyleSettings.GetDarkShadowColor(); 3120 pColorAry2[5] = rStyleSettings.GetWindowTextColor(); 3121 3122 ResMgr* pResMgr = ImplGetResMgr(); 3123 pSVData->maCtrlData.mpRadioImgList = new ImageList(); 3124 if( pResMgr ) 3125 LoadThemedImageList( rStyleSettings, 3126 pSVData->maCtrlData.mpRadioImgList, 3127 ResId( SV_RESID_BITMAP_RADIO+nStyle, *pResMgr ), 6 ); 3128 pSVData->maCtrlData.mnRadioStyle = nStyle; 3129 } 3130 3131 sal_uInt16 nId; 3132 if ( nFlags & BUTTON_DRAW_DISABLED ) 3133 { 3134 if ( nFlags & BUTTON_DRAW_CHECKED ) 3135 nId = 6; 3136 else 3137 nId = 5; 3138 } 3139 else if ( nFlags & BUTTON_DRAW_PRESSED ) 3140 { 3141 if ( nFlags & BUTTON_DRAW_CHECKED ) 3142 nId = 4; 3143 else 3144 nId = 3; 3145 } 3146 else 3147 { 3148 if ( nFlags & BUTTON_DRAW_CHECKED ) 3149 nId = 2; 3150 else 3151 nId = 1; 3152 } 3153 return pSVData->maCtrlData.mpRadioImgList->GetImage( nId ); 3154 } 3155 3156 // ----------------------------------------------------------------------- 3157 3158 void RadioButton::ImplSetMinimumNWFSize() 3159 { 3160 Push( PUSH_MAPMODE ); 3161 SetMapMode( MAP_PIXEL ); 3162 3163 ImplControlValue aControlValue; 3164 Size aCurSize( GetSizePixel() ); 3165 Rectangle aCtrlRegion( Point( 0, 0 ), aCurSize ); 3166 Rectangle aBoundingRgn, aContentRgn; 3167 3168 // get native size of a radiobutton 3169 if( GetNativeControlRegion( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion, 3170 CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED, aControlValue, rtl::OUString(), 3171 aBoundingRgn, aContentRgn ) ) 3172 { 3173 Size aSize = aContentRgn.GetSize(); 3174 3175 if( aSize.Height() > aCurSize.Height() ) 3176 { 3177 aCurSize.Height() = aSize.Height(); 3178 SetSizePixel( aCurSize ); 3179 } 3180 } 3181 3182 Pop(); 3183 } 3184 3185 // ----------------------------------------------------------------------- 3186 3187 Size RadioButton::CalcMinimumSize( long nMaxWidth ) const 3188 { 3189 Size aSize; 3190 if ( !maImage ) 3191 aSize = ImplGetRadioImageSize(); 3192 else 3193 aSize = maImage.GetSizePixel(); 3194 3195 nMaxWidth -= aSize.Width(); 3196 3197 XubString aText = GetText(); 3198 if ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) ) 3199 { 3200 // subtract what will be added later 3201 nMaxWidth-=2; 3202 nMaxWidth -= ImplGetImageToTextDistance(); 3203 3204 Size aTextSize = GetTextRect( Rectangle( Point(), Size( nMaxWidth > 0 ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ), 3205 aText, FixedText::ImplGetTextStyle( GetStyle() ) ).GetSize(); 3206 aSize.Width()+=2; // for focus rect 3207 aSize.Width() += ImplGetImageToTextDistance(); 3208 aSize.Width() += aTextSize.Width(); 3209 if ( aSize.Height() < aTextSize.Height() ) 3210 aSize.Height() = aTextSize.Height(); 3211 } 3212 else if ( !maImage ) 3213 { 3214 /* da ansonsten im Writer die Control zu weit oben haengen 3215 aSize.Width() += 2; 3216 aSize.Height() += 2; 3217 */ 3218 } 3219 3220 return CalcWindowSize( aSize ); 3221 } 3222 3223 // ----------------------------------------------------------------------- 3224 3225 Size RadioButton::GetOptimalSize(WindowSizeType eType) const 3226 { 3227 switch (eType) { 3228 case WINDOWSIZE_MINIMUM: 3229 return CalcMinimumSize(); 3230 default: 3231 return Button::GetOptimalSize( eType ); 3232 } 3233 } 3234 3235 // ======================================================================= 3236 3237 void CheckBox::ImplInitCheckBoxData() 3238 { 3239 meState = STATE_NOCHECK; 3240 meSaveValue = STATE_NOCHECK; 3241 mbTriState = sal_False; 3242 } 3243 3244 // ----------------------------------------------------------------------- 3245 3246 void CheckBox::ImplInit( Window* pParent, WinBits nStyle ) 3247 { 3248 nStyle = ImplInitStyle( pParent->GetWindow( WINDOW_LASTCHILD ), nStyle ); 3249 Button::ImplInit( pParent, nStyle, NULL ); 3250 3251 ImplInitSettings( sal_True, sal_True, sal_True ); 3252 } 3253 3254 // ----------------------------------------------------------------------- 3255 3256 WinBits CheckBox::ImplInitStyle( const Window* pPrevWindow, WinBits nStyle ) 3257 { 3258 if ( !(nStyle & WB_NOTABSTOP) ) 3259 nStyle |= WB_TABSTOP; 3260 if ( !(nStyle & WB_NOGROUP) && 3261 (!pPrevWindow || (pPrevWindow->GetType() != WINDOW_CHECKBOX)) ) 3262 nStyle |= WB_GROUP; 3263 return nStyle; 3264 } 3265 3266 // ----------------------------------------------------------------- 3267 3268 const Font& CheckBox::GetCanonicalFont( const StyleSettings& _rStyle ) const 3269 { 3270 return _rStyle.GetRadioCheckFont(); 3271 } 3272 3273 // ----------------------------------------------------------------- 3274 const Color& CheckBox::GetCanonicalTextColor( const StyleSettings& _rStyle ) const 3275 { 3276 return _rStyle.GetRadioCheckTextColor(); 3277 } 3278 3279 // ----------------------------------------------------------------------- 3280 3281 void CheckBox::ImplInitSettings( sal_Bool bFont, 3282 sal_Bool bForeground, sal_Bool bBackground ) 3283 { 3284 Button::ImplInitSettings( bFont, bForeground ); 3285 3286 if ( bBackground ) 3287 { 3288 Window* pParent = GetParent(); 3289 if ( !IsControlBackground() && 3290 (pParent->IsChildTransparentModeEnabled() || IsNativeControlSupported( CTRL_CHECKBOX, PART_ENTIRE_CONTROL ) ) ) 3291 { 3292 EnableChildTransparentMode( sal_True ); 3293 SetParentClipMode( PARENTCLIPMODE_NOCLIP ); 3294 SetPaintTransparent( sal_True ); 3295 SetBackground(); 3296 if( IsNativeControlSupported( CTRL_CHECKBOX, PART_ENTIRE_CONTROL ) ) 3297 ImplGetWindowImpl()->mbUseNativeFocus = ImplGetSVData()->maNWFData.mbNoFocusRects; 3298 } 3299 else 3300 { 3301 EnableChildTransparentMode( sal_False ); 3302 SetParentClipMode( 0 ); 3303 SetPaintTransparent( sal_False ); 3304 3305 if ( IsControlBackground() ) 3306 SetBackground( GetControlBackground() ); 3307 else 3308 SetBackground( pParent->GetBackground() ); 3309 } 3310 } 3311 } 3312 3313 // ----------------------------------------------------------------------- 3314 3315 void CheckBox::ImplLoadRes( const ResId& rResId ) 3316 { 3317 Button::ImplLoadRes( rResId ); 3318 3319 if ( rResId.GetRT() != RSC_TRISTATEBOX ) 3320 { 3321 sal_uInt16 nChecked = ReadShortRes(); 3322 //anderer Wert als Default ? 3323 if( nChecked ) 3324 Check( sal_True ); 3325 } 3326 } 3327 3328 // ----------------------------------------------------------------------- 3329 3330 void CheckBox::ImplInvalidateOrDrawCheckBoxState() 3331 { 3332 if( ImplGetSVData()->maNWFData.mbCheckBoxNeedsErase ) 3333 { 3334 if ( IsNativeControlSupported(CTRL_CHECKBOX, PART_ENTIRE_CONTROL) ) 3335 { 3336 Invalidate(); 3337 Update(); 3338 return; 3339 } 3340 } 3341 ImplDrawCheckBoxState(); 3342 } 3343 3344 void CheckBox::ImplDrawCheckBoxState() 3345 { 3346 bool bNativeOK = sal_True; 3347 3348 if ( (bNativeOK=IsNativeControlSupported(CTRL_CHECKBOX, PART_ENTIRE_CONTROL)) == sal_True ) 3349 { 3350 ImplControlValue aControlValue( meState == STATE_CHECK ? BUTTONVALUE_ON : BUTTONVALUE_OFF ); 3351 Rectangle aCtrlRegion( maStateRect ); 3352 ControlState nState = 0; 3353 3354 if ( HasFocus() ) nState |= CTRL_STATE_FOCUSED; 3355 if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT ) nState |= CTRL_STATE_DEFAULT; 3356 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) nState |= CTRL_STATE_PRESSED; 3357 if ( IsEnabled() ) nState |= CTRL_STATE_ENABLED; 3358 3359 if ( meState == STATE_CHECK ) 3360 aControlValue.setTristateVal( BUTTONVALUE_ON ); 3361 else if ( meState == STATE_DONTKNOW ) 3362 aControlValue.setTristateVal( BUTTONVALUE_MIXED ); 3363 3364 if ( IsMouseOver() && maMouseRect.IsInside( GetPointerPosPixel() ) ) 3365 nState |= CTRL_STATE_ROLLOVER; 3366 3367 bNativeOK = DrawNativeControl( CTRL_CHECKBOX, PART_ENTIRE_CONTROL, aCtrlRegion, nState, 3368 aControlValue, rtl::OUString() ); 3369 } 3370 3371 if ( bNativeOK == sal_False ) 3372 { 3373 sal_uInt16 nStyle = ImplGetButtonState(); 3374 if ( !IsEnabled() ) 3375 nStyle |= BUTTON_DRAW_DISABLED; 3376 if ( meState == STATE_DONTKNOW ) 3377 nStyle |= BUTTON_DRAW_DONTKNOW; 3378 else if ( meState == STATE_CHECK ) 3379 nStyle |= BUTTON_DRAW_CHECKED; 3380 Image aImage = GetCheckImage( GetSettings(), nStyle ); 3381 if ( IsZoom() ) 3382 DrawImage( maStateRect.TopLeft(), maStateRect.GetSize(), aImage ); 3383 else 3384 DrawImage( maStateRect.TopLeft(), aImage ); 3385 } 3386 } 3387 3388 // ----------------------------------------------------------------------- 3389 3390 void CheckBox::ImplDraw( OutputDevice* pDev, sal_uLong nDrawFlags, 3391 const Point& rPos, const Size& rSize, 3392 const Size& rImageSize, Rectangle& rStateRect, 3393 Rectangle& rMouseRect, bool bLayout ) 3394 { 3395 WinBits nWinStyle = GetStyle(); 3396 XubString aText( GetText() ); 3397 3398 pDev->Push( PUSH_CLIPREGION | PUSH_LINECOLOR ); 3399 pDev->IntersectClipRegion( Rectangle( rPos, rSize ) ); 3400 3401 long nLineY = rPos.Y() + (rSize.Height()-1)/2; 3402 if ( ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) ) || 3403 ( HasImage() && ! (ImplGetButtonState() & BUTTON_DRAW_NOIMAGE) ) ) 3404 { 3405 sal_uInt16 nTextStyle = Button::ImplGetTextStyle( aText, nWinStyle, nDrawFlags ); 3406 3407 const long nImageSep = GetDrawPixel( pDev, ImplGetImageToTextDistance() ); 3408 Size aSize( rSize ); 3409 Point aPos( rPos ); 3410 aPos.X() += rImageSize.Width() + nImageSep; 3411 aSize.Width() -= rImageSize.Width() + nImageSep; 3412 3413 // if the text rect height is smaller than the height of the image 3414 // then for single lines the default should be centered text 3415 if( (nWinStyle & (WB_TOP|WB_VCENTER|WB_BOTTOM)) == 0 && 3416 (rImageSize.Height() > rSize.Height() || ! (nWinStyle & WB_WORDBREAK) ) ) 3417 { 3418 nTextStyle &= ~(TEXT_DRAW_TOP|TEXT_DRAW_BOTTOM); 3419 nTextStyle |= TEXT_DRAW_VCENTER; 3420 aSize.Height() = rImageSize.Height(); 3421 } 3422 3423 ImplDrawAlignedImage( pDev, aPos, aSize, bLayout, 1, 3424 nDrawFlags, nTextStyle, NULL ); 3425 nLineY = aPos.Y() + aSize.Height()/2; 3426 3427 rMouseRect = Rectangle( aPos, aSize ); 3428 rMouseRect.Left() = rPos.X(); 3429 rStateRect.Left() = rPos.X(); 3430 rStateRect.Top() = rMouseRect.Top(); 3431 3432 if ( aSize.Height() > rImageSize.Height() ) 3433 rStateRect.Top() += ( aSize.Height() - rImageSize.Height() ) / 2; 3434 else 3435 { 3436 rStateRect.Top() -= ( rImageSize.Height() - aSize.Height() ) / 2; 3437 if( rStateRect.Top() < 0 ) 3438 rStateRect.Top() = 0; 3439 } 3440 3441 rStateRect.Right() = rStateRect.Left()+rImageSize.Width()-1; 3442 rStateRect.Bottom() = rStateRect.Top()+rImageSize.Height()-1; 3443 if ( rStateRect.Bottom() > rMouseRect.Bottom() ) 3444 rMouseRect.Bottom() = rStateRect.Bottom(); 3445 } 3446 else 3447 { 3448 if ( nWinStyle & WB_CENTER ) 3449 rStateRect.Left() = rPos.X()+((rSize.Width()-rImageSize.Width())/2); 3450 else if ( nWinStyle & WB_RIGHT ) 3451 rStateRect.Left() = rPos.X()+rSize.Width()-rImageSize.Width(); 3452 else 3453 rStateRect.Left() = rPos.X(); 3454 if ( nWinStyle & WB_VCENTER ) 3455 rStateRect.Top() = rPos.Y()+((rSize.Height()-rImageSize.Height())/2); 3456 else if ( nWinStyle & WB_BOTTOM ) 3457 rStateRect.Top() = rPos.Y()+rSize.Height()-rImageSize.Height(); 3458 else 3459 rStateRect.Top() = rPos.Y(); 3460 rStateRect.Right() = rStateRect.Left()+rImageSize.Width()-1; 3461 rStateRect.Bottom() = rStateRect.Top()+rImageSize.Height()-1; 3462 // provide space for focusrect 3463 // note: this assumes that the control's size was adjusted 3464 // accordingly in Get/LoseFocus, so the onscreen position won't change 3465 if( HasFocus() ) 3466 rStateRect.Move( 1, 1 ); 3467 rMouseRect = rStateRect; 3468 3469 ImplSetFocusRect( rStateRect ); 3470 } 3471 3472 const int nLineSpace = 4; 3473 if( (GetStyle() & WB_CBLINESTYLE) != 0 && 3474 rMouseRect.Right()-1-nLineSpace < rPos.X()+rSize.Width() ) 3475 { 3476 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 3477 if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO ) 3478 SetLineColor( Color( COL_BLACK ) ); 3479 else 3480 SetLineColor( rStyleSettings.GetShadowColor() ); 3481 long nLineX = rMouseRect.Right()+nLineSpace; 3482 DrawLine( Point( nLineX, nLineY ), Point( rPos.X() + rSize.Width()-1, nLineY ) ); 3483 if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) ) 3484 { 3485 SetLineColor( rStyleSettings.GetLightColor() ); 3486 DrawLine( Point( nLineX, nLineY+1 ), Point( rPos.X() + rSize.Width()-1, nLineY+1 ) ); 3487 } 3488 } 3489 3490 pDev->Pop(); 3491 } 3492 3493 // ----------------------------------------------------------------------- 3494 3495 void CheckBox::ImplDrawCheckBox( bool bLayout ) 3496 { 3497 Size aImageSize = ImplGetCheckImageSize(); 3498 aImageSize.Width() = CalcZoom( aImageSize.Width() ); 3499 aImageSize.Height() = CalcZoom( aImageSize.Height() ); 3500 3501 if( !bLayout ) 3502 HideFocus(); 3503 3504 ImplDraw( this, 0, Point(), GetOutputSizePixel(), aImageSize, 3505 maStateRect, maMouseRect, bLayout ); 3506 3507 if( !bLayout ) 3508 { 3509 ImplDrawCheckBoxState(); 3510 if ( HasFocus() ) 3511 ShowFocus( ImplGetFocusRect() ); 3512 } 3513 } 3514 3515 // ----------------------------------------------------------------------- 3516 3517 void CheckBox::ImplCheck() 3518 { 3519 TriState eNewState; 3520 if ( meState == STATE_NOCHECK ) 3521 eNewState = STATE_CHECK; 3522 else if ( !mbTriState ) 3523 eNewState = STATE_NOCHECK; 3524 else if ( meState == STATE_CHECK ) 3525 eNewState = STATE_DONTKNOW; 3526 else 3527 eNewState = STATE_NOCHECK; 3528 meState = eNewState; 3529 3530 ImplDelData aDelData; 3531 ImplAddDel( &aDelData ); 3532 if( (GetStyle() & WB_EARLYTOGGLE) ) 3533 Toggle(); 3534 ImplInvalidateOrDrawCheckBoxState(); 3535 if( ! (GetStyle() & WB_EARLYTOGGLE) ) 3536 Toggle(); 3537 if ( aDelData.IsDelete() ) 3538 return; 3539 ImplRemoveDel( &aDelData ); 3540 Click(); 3541 } 3542 3543 // ----------------------------------------------------------------------- 3544 3545 CheckBox::CheckBox( Window* pParent, WinBits nStyle ) : 3546 Button( WINDOW_CHECKBOX ) 3547 { 3548 ImplInitCheckBoxData(); 3549 ImplInit( pParent, nStyle ); 3550 } 3551 3552 // ----------------------------------------------------------------------- 3553 3554 CheckBox::CheckBox( Window* pParent, const ResId& rResId ) : 3555 Button( WINDOW_CHECKBOX ) 3556 { 3557 ImplInitCheckBoxData(); 3558 rResId.SetRT( RSC_CHECKBOX ); 3559 WinBits nStyle = ImplInitRes( rResId ); 3560 ImplInit( pParent, nStyle ); 3561 ImplLoadRes( rResId ); 3562 3563 if ( !(nStyle & WB_HIDE) ) 3564 Show(); 3565 } 3566 3567 // ----------------------------------------------------------------------- 3568 3569 void CheckBox::MouseButtonDown( const MouseEvent& rMEvt ) 3570 { 3571 if ( rMEvt.IsLeft() && maMouseRect.IsInside( rMEvt.GetPosPixel() ) ) 3572 { 3573 ImplGetButtonState() |= BUTTON_DRAW_PRESSED; 3574 ImplInvalidateOrDrawCheckBoxState(); 3575 StartTracking(); 3576 return; 3577 } 3578 3579 Button::MouseButtonDown( rMEvt ); 3580 } 3581 3582 // ----------------------------------------------------------------------- 3583 3584 void CheckBox::Tracking( const TrackingEvent& rTEvt ) 3585 { 3586 if ( rTEvt.IsTrackingEnded() ) 3587 { 3588 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) 3589 { 3590 if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() ) 3591 GrabFocus(); 3592 3593 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 3594 3595 // Bei Abbruch kein Click-Handler rufen 3596 if ( !rTEvt.IsTrackingCanceled() ) 3597 ImplCheck(); 3598 else 3599 ImplInvalidateOrDrawCheckBoxState(); 3600 } 3601 } 3602 else 3603 { 3604 if ( maMouseRect.IsInside( rTEvt.GetMouseEvent().GetPosPixel() ) ) 3605 { 3606 if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) ) 3607 { 3608 ImplGetButtonState() |= BUTTON_DRAW_PRESSED; 3609 ImplInvalidateOrDrawCheckBoxState(); 3610 } 3611 } 3612 else 3613 { 3614 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) 3615 { 3616 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 3617 ImplInvalidateOrDrawCheckBoxState(); 3618 } 3619 } 3620 } 3621 } 3622 3623 // ----------------------------------------------------------------------- 3624 3625 void CheckBox::KeyInput( const KeyEvent& rKEvt ) 3626 { 3627 KeyCode aKeyCode = rKEvt.GetKeyCode(); 3628 3629 if ( !aKeyCode.GetModifier() && (aKeyCode.GetCode() == KEY_SPACE) ) 3630 { 3631 if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) ) 3632 { 3633 ImplGetButtonState() |= BUTTON_DRAW_PRESSED; 3634 ImplInvalidateOrDrawCheckBoxState(); 3635 } 3636 } 3637 else if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_ESCAPE) ) 3638 { 3639 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 3640 ImplInvalidateOrDrawCheckBoxState(); 3641 } 3642 else 3643 Button::KeyInput( rKEvt ); 3644 } 3645 3646 // ----------------------------------------------------------------------- 3647 3648 void CheckBox::KeyUp( const KeyEvent& rKEvt ) 3649 { 3650 KeyCode aKeyCode = rKEvt.GetKeyCode(); 3651 3652 if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_SPACE) ) 3653 { 3654 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 3655 ImplCheck(); 3656 } 3657 else 3658 Button::KeyUp( rKEvt ); 3659 } 3660 3661 // ----------------------------------------------------------------------- 3662 3663 void CheckBox::FillLayoutData() const 3664 { 3665 mpControlData->mpLayoutData = new vcl::ControlLayoutData(); 3666 const_cast<CheckBox*>(this)->ImplDrawCheckBox( true ); 3667 } 3668 3669 // ----------------------------------------------------------------------- 3670 3671 void CheckBox::Paint( const Rectangle& ) 3672 { 3673 ImplDrawCheckBox(); 3674 } 3675 3676 // ----------------------------------------------------------------------- 3677 3678 void CheckBox::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize, 3679 sal_uLong nFlags ) 3680 { 3681 MapMode aResMapMode( MAP_100TH_MM ); 3682 Point aPos = pDev->LogicToPixel( rPos ); 3683 Size aSize = pDev->LogicToPixel( rSize ); 3684 Size aImageSize = pDev->LogicToPixel( Size( 300, 300 ), aResMapMode ); 3685 Size aBrd1Size = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode ); 3686 Size aBrd2Size = pDev->LogicToPixel( Size( 30, 30 ), aResMapMode ); 3687 long nCheckWidth = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode ).Width(); 3688 Font aFont = GetDrawPixelFont( pDev ); 3689 Rectangle aStateRect; 3690 Rectangle aMouseRect; 3691 3692 aImageSize.Width() = CalcZoom( aImageSize.Width() ); 3693 aImageSize.Height() = CalcZoom( aImageSize.Height() ); 3694 aBrd1Size.Width() = CalcZoom( aBrd1Size.Width() ); 3695 aBrd1Size.Height() = CalcZoom( aBrd1Size.Height() ); 3696 aBrd2Size.Width() = CalcZoom( aBrd2Size.Width() ); 3697 aBrd2Size.Height() = CalcZoom( aBrd2Size.Height() ); 3698 3699 if ( !aBrd1Size.Width() ) 3700 aBrd1Size.Width() = 1; 3701 if ( !aBrd1Size.Height() ) 3702 aBrd1Size.Height() = 1; 3703 if ( !aBrd2Size.Width() ) 3704 aBrd2Size.Width() = 1; 3705 if ( !aBrd2Size.Height() ) 3706 aBrd2Size.Height() = 1; 3707 if ( !nCheckWidth ) 3708 nCheckWidth = 1; 3709 3710 pDev->Push(); 3711 pDev->SetMapMode(); 3712 pDev->SetFont( aFont ); 3713 if ( nFlags & WINDOW_DRAW_MONO ) 3714 pDev->SetTextColor( Color( COL_BLACK ) ); 3715 else 3716 pDev->SetTextColor( GetTextColor() ); 3717 pDev->SetTextFillColor(); 3718 3719 ImplDraw( pDev, nFlags, aPos, aSize, 3720 aImageSize, aStateRect, aMouseRect, false ); 3721 3722 pDev->SetLineColor(); 3723 pDev->SetFillColor( Color( COL_BLACK ) ); 3724 pDev->DrawRect( aStateRect ); 3725 aStateRect.Left() += aBrd1Size.Width(); 3726 aStateRect.Top() += aBrd1Size.Height(); 3727 aStateRect.Right() -= aBrd1Size.Width(); 3728 aStateRect.Bottom() -= aBrd1Size.Height(); 3729 if ( meState == STATE_DONTKNOW ) 3730 pDev->SetFillColor( Color( COL_LIGHTGRAY ) ); 3731 else 3732 pDev->SetFillColor( Color( COL_WHITE ) ); 3733 pDev->DrawRect( aStateRect ); 3734 3735 if ( meState == STATE_CHECK ) 3736 { 3737 aStateRect.Left() += aBrd2Size.Width(); 3738 aStateRect.Top() += aBrd2Size.Height(); 3739 aStateRect.Right() -= aBrd2Size.Width(); 3740 aStateRect.Bottom() -= aBrd2Size.Height(); 3741 Point aPos11( aStateRect.TopLeft() ); 3742 Point aPos12( aStateRect.BottomRight() ); 3743 Point aPos21( aStateRect.TopRight() ); 3744 Point aPos22( aStateRect.BottomLeft() ); 3745 Point aTempPos11( aPos11 ); 3746 Point aTempPos12( aPos12 ); 3747 Point aTempPos21( aPos21 ); 3748 Point aTempPos22( aPos22 ); 3749 pDev->SetLineColor( Color( COL_BLACK ) ); 3750 long nDX = 0; 3751 for ( long i = 0; i < nCheckWidth; i++ ) 3752 { 3753 if ( !(i % 2) ) 3754 { 3755 aTempPos11.X() = aPos11.X()+nDX; 3756 aTempPos12.X() = aPos12.X()+nDX; 3757 aTempPos21.X() = aPos21.X()+nDX; 3758 aTempPos22.X() = aPos22.X()+nDX; 3759 } 3760 else 3761 { 3762 nDX++; 3763 aTempPos11.X() = aPos11.X()-nDX; 3764 aTempPos12.X() = aPos12.X()-nDX; 3765 aTempPos21.X() = aPos21.X()-nDX; 3766 aTempPos22.X() = aPos22.X()-nDX; 3767 } 3768 pDev->DrawLine( aTempPos11, aTempPos12 ); 3769 pDev->DrawLine( aTempPos21, aTempPos22 ); 3770 } 3771 } 3772 3773 pDev->Pop(); 3774 } 3775 3776 // ----------------------------------------------------------------------- 3777 3778 void CheckBox::Resize() 3779 { 3780 Control::Resize(); 3781 Invalidate(); 3782 } 3783 3784 // ----------------------------------------------------------------------- 3785 3786 void CheckBox::GetFocus() 3787 { 3788 if ( !GetText().Len() || (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) ) 3789 { 3790 // increase button size to have space for focus rect 3791 // checkboxes without text will draw focusrect around the check 3792 // See CheckBox::ImplDraw() 3793 Point aPos( GetPosPixel() ); 3794 Size aSize( GetSizePixel() ); 3795 aPos.Move(-1,-1); 3796 aSize.Height() += 2; 3797 aSize.Width() += 2; 3798 SetPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height(), WINDOW_POSSIZE_ALL ); 3799 ImplDrawCheckBox(); 3800 } 3801 else 3802 ShowFocus( ImplGetFocusRect() ); 3803 3804 SetInputContext( InputContext( GetFont() ) ); 3805 Button::GetFocus(); 3806 } 3807 3808 // ----------------------------------------------------------------------- 3809 3810 void CheckBox::LoseFocus() 3811 { 3812 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) 3813 { 3814 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED; 3815 ImplInvalidateOrDrawCheckBoxState(); 3816 } 3817 3818 HideFocus(); 3819 Button::LoseFocus(); 3820 3821 if ( !GetText().Len() || (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) ) 3822 { 3823 // decrease button size again (see GetFocus()) 3824 // checkboxes without text will draw focusrect around the check 3825 Point aPos( GetPosPixel() ); 3826 Size aSize( GetSizePixel() ); 3827 aPos.Move(1,1); 3828 aSize.Height() -= 2; 3829 aSize.Width() -= 2; 3830 SetPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height(), WINDOW_POSSIZE_ALL ); 3831 ImplDrawCheckBox(); 3832 } 3833 } 3834 3835 // ----------------------------------------------------------------------- 3836 3837 void CheckBox::StateChanged( StateChangedType nType ) 3838 { 3839 Button::StateChanged( nType ); 3840 3841 if ( nType == STATE_CHANGE_STATE ) 3842 { 3843 if ( IsReallyVisible() && IsUpdateMode() ) 3844 Invalidate( maStateRect ); 3845 } 3846 else if ( (nType == STATE_CHANGE_ENABLE) || 3847 (nType == STATE_CHANGE_TEXT) || 3848 (nType == STATE_CHANGE_IMAGE) || 3849 (nType == STATE_CHANGE_DATA) || 3850 (nType == STATE_CHANGE_UPDATEMODE) ) 3851 { 3852 if ( IsUpdateMode() ) 3853 Invalidate(); 3854 } 3855 else if ( nType == STATE_CHANGE_STYLE ) 3856 { 3857 SetStyle( ImplInitStyle( GetWindow( WINDOW_PREV ), GetStyle() ) ); 3858 3859 if ( (GetPrevStyle() & CHECKBOX_VIEW_STYLE) != 3860 (GetStyle() & CHECKBOX_VIEW_STYLE) ) 3861 { 3862 if ( IsUpdateMode() ) 3863 Invalidate(); 3864 } 3865 } 3866 else if ( (nType == STATE_CHANGE_ZOOM) || 3867 (nType == STATE_CHANGE_CONTROLFONT) ) 3868 { 3869 ImplInitSettings( sal_True, sal_False, sal_False ); 3870 Invalidate(); 3871 } 3872 else if ( nType == STATE_CHANGE_CONTROLFOREGROUND ) 3873 { 3874 ImplInitSettings( sal_False, sal_True, sal_False ); 3875 Invalidate(); 3876 } 3877 else if ( nType == STATE_CHANGE_CONTROLBACKGROUND ) 3878 { 3879 ImplInitSettings( sal_False, sal_False, sal_True ); 3880 Invalidate(); 3881 } 3882 } 3883 3884 // ----------------------------------------------------------------------- 3885 3886 void CheckBox::DataChanged( const DataChangedEvent& rDCEvt ) 3887 { 3888 Button::DataChanged( rDCEvt ); 3889 3890 if ( (rDCEvt.GetType() == DATACHANGED_FONTS) || 3891 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) || 3892 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) && 3893 (rDCEvt.GetFlags() & SETTINGS_STYLE)) ) 3894 { 3895 ImplInitSettings( sal_True, sal_True, sal_True ); 3896 Invalidate(); 3897 } 3898 } 3899 3900 // ----------------------------------------------------------------------- 3901 3902 long CheckBox::PreNotify( NotifyEvent& rNEvt ) 3903 { 3904 long nDone = 0; 3905 const MouseEvent* pMouseEvt = NULL; 3906 3907 if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL ) 3908 { 3909 if( !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() ) 3910 { 3911 // trigger redraw if mouse over state has changed 3912 if( IsNativeControlSupported(CTRL_CHECKBOX, PART_ENTIRE_CONTROL) ) 3913 { 3914 if( ( maMouseRect.IsInside( GetPointerPosPixel()) && 3915 !maMouseRect.IsInside( GetLastPointerPosPixel()) ) || 3916 ( maMouseRect.IsInside( GetLastPointerPosPixel()) && 3917 !maMouseRect.IsInside( GetPointerPosPixel()) ) || 3918 pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow() ) 3919 { 3920 Invalidate( maStateRect ); 3921 } 3922 } 3923 } 3924 } 3925 3926 return nDone ? nDone : Button::PreNotify(rNEvt); 3927 } 3928 3929 // ----------------------------------------------------------------------- 3930 3931 void CheckBox::Toggle() 3932 { 3933 ImplCallEventListenersAndHandler( VCLEVENT_CHECKBOX_TOGGLE, maToggleHdl, this ); 3934 } 3935 3936 // ----------------------------------------------------------------------- 3937 3938 void CheckBox::SetState( TriState eState ) 3939 { 3940 if ( !mbTriState && (eState == STATE_DONTKNOW) ) 3941 eState = STATE_NOCHECK; 3942 3943 if ( meState != eState ) 3944 { 3945 meState = eState; 3946 StateChanged( STATE_CHANGE_STATE ); 3947 Toggle(); 3948 } 3949 } 3950 3951 // ----------------------------------------------------------------------- 3952 3953 void CheckBox::EnableTriState( sal_Bool bTriState ) 3954 { 3955 if ( mbTriState != bTriState ) 3956 { 3957 mbTriState = bTriState; 3958 3959 if ( !bTriState && (meState == STATE_DONTKNOW) ) 3960 SetState( STATE_NOCHECK ); 3961 } 3962 } 3963 3964 // ----------------------------------------------------------------------- 3965 3966 long CheckBox::ImplGetImageToTextDistance() const 3967 { 3968 // 4 pixels, but take zoom into account, so the text doesn't "jump" relative to surrounding elements, 3969 // which might have been aligned with the text of the check box 3970 return CalcZoom( 4 ); 3971 } 3972 3973 // ----------------------------------------------------------------------- 3974 3975 Size CheckBox::ImplGetCheckImageSize() const 3976 { 3977 Size aSize; 3978 // why are IsNativeControlSupported and GetNativeControlRegion not const ? 3979 CheckBox* pThis = const_cast<CheckBox*>(this); 3980 bool bDefaultSize = true; 3981 if( pThis->IsNativeControlSupported( CTRL_CHECKBOX, PART_ENTIRE_CONTROL ) ) 3982 { 3983 ImplControlValue aControlValue; 3984 // #i45896# workaround gcc3.3 temporary problem 3985 Rectangle aCtrlRegion( Point( 0, 0 ), GetSizePixel() ); 3986 ControlState nState = CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED; 3987 Rectangle aBoundingRgn, aContentRgn; 3988 3989 // get native size of a check box 3990 if( pThis->GetNativeControlRegion( CTRL_CHECKBOX, PART_ENTIRE_CONTROL, aCtrlRegion, 3991 nState, aControlValue, rtl::OUString(), 3992 aBoundingRgn, aContentRgn ) ) 3993 { 3994 aSize = aContentRgn.GetSize(); 3995 bDefaultSize = false; 3996 } 3997 } 3998 if( bDefaultSize ) 3999 aSize = GetCheckImage( GetSettings(), 0 ).GetSizePixel(); 4000 return aSize; 4001 } 4002 4003 Image CheckBox::GetCheckImage( const AllSettings& rSettings, sal_uInt16 nFlags ) 4004 { 4005 ImplSVData* pSVData = ImplGetSVData(); 4006 const StyleSettings& rStyleSettings = rSettings.GetStyleSettings(); 4007 sal_uInt16 nStyle = 0; 4008 4009 if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO ) 4010 nStyle = STYLE_CHECKBOX_MONO; 4011 4012 if ( !pSVData->maCtrlData.mpCheckImgList || 4013 (pSVData->maCtrlData.mnCheckStyle != nStyle) || 4014 (pSVData->maCtrlData.mnLastCheckFColor != rStyleSettings.GetFaceColor().GetColor()) || 4015 (pSVData->maCtrlData.mnLastCheckWColor != rStyleSettings.GetWindowColor().GetColor()) || 4016 (pSVData->maCtrlData.mnLastCheckLColor != rStyleSettings.GetLightColor().GetColor()) ) 4017 { 4018 if ( pSVData->maCtrlData.mpCheckImgList ) 4019 delete pSVData->maCtrlData.mpCheckImgList; 4020 4021 pSVData->maCtrlData.mnLastCheckFColor = rStyleSettings.GetFaceColor().GetColor(); 4022 pSVData->maCtrlData.mnLastCheckWColor = rStyleSettings.GetWindowColor().GetColor(); 4023 pSVData->maCtrlData.mnLastCheckLColor = rStyleSettings.GetLightColor().GetColor(); 4024 4025 ResMgr* pResMgr = ImplGetResMgr(); 4026 pSVData->maCtrlData.mpCheckImgList = new ImageList(); 4027 if( pResMgr ) 4028 LoadThemedImageList( rStyleSettings, 4029 pSVData->maCtrlData.mpCheckImgList, 4030 ResId( SV_RESID_BITMAP_CHECK+nStyle, *pResMgr ), 9 ); 4031 pSVData->maCtrlData.mnCheckStyle = nStyle; 4032 } 4033 4034 sal_uInt16 nId; 4035 if ( nFlags & BUTTON_DRAW_DISABLED ) 4036 { 4037 if ( nFlags & BUTTON_DRAW_DONTKNOW ) 4038 nId = 9; 4039 else if ( nFlags & BUTTON_DRAW_CHECKED ) 4040 nId = 6; 4041 else 4042 nId = 5; 4043 } 4044 else if ( nFlags & BUTTON_DRAW_PRESSED ) 4045 { 4046 if ( nFlags & BUTTON_DRAW_DONTKNOW ) 4047 nId = 8; 4048 else if ( nFlags & BUTTON_DRAW_CHECKED ) 4049 nId = 4; 4050 else 4051 nId = 3; 4052 } 4053 else 4054 { 4055 if ( nFlags & BUTTON_DRAW_DONTKNOW ) 4056 nId = 7; 4057 else if ( nFlags & BUTTON_DRAW_CHECKED ) 4058 nId = 2; 4059 else 4060 nId = 1; 4061 } 4062 return pSVData->maCtrlData.mpCheckImgList->GetImage( nId ); 4063 } 4064 4065 // ----------------------------------------------------------------------- 4066 4067 void CheckBox::ImplSetMinimumNWFSize() 4068 { 4069 Push( PUSH_MAPMODE ); 4070 SetMapMode( MAP_PIXEL ); 4071 4072 ImplControlValue aControlValue; 4073 Size aCurSize( GetSizePixel() ); 4074 Rectangle aCtrlRegion( Point( 0, 0 ), aCurSize ); 4075 Rectangle aBoundingRgn, aContentRgn; 4076 4077 // get native size of a radiobutton 4078 if( GetNativeControlRegion( CTRL_CHECKBOX, PART_ENTIRE_CONTROL, aCtrlRegion, 4079 CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED, aControlValue, rtl::OUString(), 4080 aBoundingRgn, aContentRgn ) ) 4081 { 4082 Size aSize = aContentRgn.GetSize(); 4083 4084 if( aSize.Height() > aCurSize.Height() ) 4085 { 4086 aCurSize.Height() = aSize.Height(); 4087 SetSizePixel( aCurSize ); 4088 } 4089 } 4090 4091 Pop(); 4092 } 4093 4094 // ----------------------------------------------------------------------- 4095 4096 Size CheckBox::CalcMinimumSize( long nMaxWidth ) const 4097 { 4098 Size aSize = ImplGetCheckImageSize(); 4099 nMaxWidth -= aSize.Width(); 4100 4101 XubString aText = GetText(); 4102 if ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) ) 4103 { 4104 // subtract what will be added later 4105 nMaxWidth-=2; 4106 nMaxWidth -= ImplGetImageToTextDistance(); 4107 4108 Size aTextSize = GetTextRect( Rectangle( Point(), Size( nMaxWidth > 0 ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ), 4109 aText, FixedText::ImplGetTextStyle( GetStyle() ) ).GetSize(); 4110 aSize.Width()+=2; // for focus rect 4111 aSize.Width() += ImplGetImageToTextDistance(); 4112 aSize.Width() += aTextSize.Width(); 4113 if ( aSize.Height() < aTextSize.Height() ) 4114 aSize.Height() = aTextSize.Height(); 4115 } 4116 else 4117 { 4118 // is this still correct ? since the checkbox now 4119 // shows a focus rect it should be 2 pixels wider and longer 4120 /* da ansonsten im Writer die Control zu weit oben haengen 4121 aSize.Width() += 2; 4122 aSize.Height() += 2; 4123 */ 4124 } 4125 4126 return CalcWindowSize( aSize ); 4127 } 4128 4129 // ----------------------------------------------------------------------- 4130 4131 Size CheckBox::GetOptimalSize(WindowSizeType eType) const 4132 { 4133 switch (eType) { 4134 case WINDOWSIZE_MINIMUM: 4135 return CalcMinimumSize(); 4136 default: 4137 return Button::GetOptimalSize( eType ); 4138 } 4139 } 4140 4141 // ======================================================================= 4142 4143 ImageButton::ImageButton( WindowType nType ) : 4144 PushButton( nType ) 4145 { 4146 ImplInitStyle(); 4147 } 4148 4149 // ----------------------------------------------------------------------- 4150 4151 ImageButton::ImageButton( Window* pParent, WinBits nStyle ) : 4152 PushButton( pParent, nStyle ) 4153 { 4154 ImplInitStyle(); 4155 } 4156 4157 // ----------------------------------------------------------------------- 4158 4159 ImageButton::ImageButton( Window* pParent, const ResId& rResId ) : 4160 PushButton( pParent, rResId.SetRT( RSC_IMAGEBUTTON ) ) 4161 { 4162 sal_uLong nObjMask = ReadLongRes(); 4163 4164 if ( RSC_IMAGEBUTTON_IMAGE & nObjMask ) 4165 { 4166 SetModeImage( Image( ResId( (RSHEADER_TYPE*)GetClassRes(), *rResId.GetResMgr() ) ) ); 4167 IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) ); 4168 } 4169 4170 if ( RSC_IMAGEBUTTON_SYMBOL & nObjMask ) 4171 SetSymbol( (SymbolType)ReadLongRes() ); 4172 4173 if ( RSC_IMAGEBUTTON_STATE & nObjMask ) 4174 SetState( (TriState)ReadLongRes() ); 4175 4176 ImplInitStyle(); 4177 } 4178 4179 // ----------------------------------------------------------------------- 4180 4181 ImageButton::~ImageButton() 4182 { 4183 } 4184 4185 // ----------------------------------------------------------------------- 4186 void ImageButton::ImplInitStyle() 4187 { 4188 WinBits nStyle = GetStyle(); 4189 4190 if ( ! ( nStyle & ( WB_RIGHT | WB_LEFT ) ) ) 4191 nStyle |= WB_CENTER; 4192 4193 if ( ! ( nStyle & ( WB_TOP | WB_BOTTOM ) ) ) 4194 nStyle |= WB_VCENTER; 4195 4196 SetStyle( nStyle ); 4197 } 4198 4199 // ======================================================================= 4200 4201 ImageRadioButton::ImageRadioButton( Window* pParent, WinBits nStyle ) : 4202 RadioButton( pParent, nStyle ) 4203 { 4204 } 4205 4206 // ----------------------------------------------------------------------- 4207 4208 ImageRadioButton::ImageRadioButton( Window* pParent, const ResId& rResId ) : 4209 RadioButton( pParent, rResId.SetRT( RSC_IMAGERADIOBUTTON ) ) 4210 { 4211 sal_uLong nObjMask = ReadLongRes(); 4212 4213 if ( RSC_IMAGERADIOBUTTON_IMAGE & nObjMask ) 4214 { 4215 SetModeRadioImage( Image( ResId( (RSHEADER_TYPE*)GetClassRes(), *rResId.GetResMgr() ) ) ); 4216 IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) ); 4217 } 4218 } 4219 4220 // ----------------------------------------------------------------------- 4221 4222 ImageRadioButton::~ImageRadioButton() 4223 { 4224 } 4225 4226 // ======================================================================= 4227 4228 TriStateBox::TriStateBox( Window* pParent, WinBits nStyle ) : 4229 CheckBox( pParent, nStyle ) 4230 { 4231 EnableTriState( sal_True ); 4232 } 4233 4234 // ----------------------------------------------------------------------- 4235 4236 TriStateBox::TriStateBox( Window* pParent, const ResId& rResId ) : 4237 CheckBox( pParent, rResId.SetRT( RSC_TRISTATEBOX ) ) 4238 { 4239 EnableTriState( sal_True ); 4240 4241 sal_uLong nTriState = ReadLongRes(); 4242 sal_uInt16 bDisableTriState = ReadShortRes(); 4243 //anderer Wert als Default ? 4244 if ( (TriState)nTriState != STATE_NOCHECK ) 4245 SetState( (TriState)nTriState ); 4246 if ( bDisableTriState ) 4247 EnableTriState( sal_False ); 4248 } 4249 4250 // ----------------------------------------------------------------------- 4251 4252 TriStateBox::~TriStateBox() 4253 { 4254 } 4255 4256 // ======================================================================= 4257 4258 DisclosureButton::DisclosureButton( Window* pParent, WinBits ) : 4259 CheckBox( pParent, WB_NOBORDER ) 4260 { 4261 } 4262 4263 // ----------------------------------------------------------------------- 4264 4265 DisclosureButton::DisclosureButton( Window* pParent, const ResId& rResId ) : 4266 CheckBox( pParent, rResId.SetRT( RSC_CHECKBOX ) ) 4267 { 4268 } 4269 4270 // ----------------------------------------------------------------------- 4271 4272 void DisclosureButton::ImplDrawCheckBoxState() 4273 { 4274 /* HACK: DisclosureButton is currently assuming, that the disclosure sign 4275 will fit into the rectangle occupied by a normal checkbox on all themes. 4276 If this does not hold true for some theme, ImplGetCheckImageSize 4277 would have to be overloaded for DisclosureButton; also GetNativeControlRegion 4278 for CTRL_LISTNODE would have to be implemented and taken into account 4279 */ 4280 4281 Rectangle aStateRect( GetStateRect() ); 4282 4283 ImplControlValue aControlValue( GetState() == STATE_CHECK ? BUTTONVALUE_ON : BUTTONVALUE_OFF ); 4284 Rectangle aCtrlRegion( aStateRect ); 4285 ControlState nState = 0; 4286 4287 if ( HasFocus() ) nState |= CTRL_STATE_FOCUSED; 4288 if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT ) nState |= CTRL_STATE_DEFAULT; 4289 if ( Window::IsEnabled() ) nState |= CTRL_STATE_ENABLED; 4290 if ( IsMouseOver() && GetMouseRect().IsInside( GetPointerPosPixel() ) ) 4291 nState |= CTRL_STATE_ROLLOVER; 4292 4293 if( ! DrawNativeControl( CTRL_LISTNODE, PART_ENTIRE_CONTROL, aCtrlRegion, nState, 4294 aControlValue, rtl::OUString() ) ) 4295 { 4296 ImplSVCtrlData& rCtrlData( ImplGetSVData()->maCtrlData ); 4297 if( ! rCtrlData.mpDisclosurePlus ) 4298 rCtrlData.mpDisclosurePlus = new Image( BitmapEx( VclResId( SV_DISCLOSURE_PLUS ) ) ); 4299 if( ! rCtrlData.mpDisclosurePlusHC ) 4300 rCtrlData.mpDisclosurePlusHC = new Image( BitmapEx( VclResId( SV_DISCLOSURE_PLUS_HC ) ) ); 4301 if( ! rCtrlData.mpDisclosureMinus ) 4302 rCtrlData.mpDisclosureMinus = new Image( BitmapEx( VclResId( SV_DISCLOSURE_MINUS ) ) ); 4303 if( ! rCtrlData.mpDisclosureMinusHC ) 4304 rCtrlData.mpDisclosureMinusHC = new Image( BitmapEx( VclResId( SV_DISCLOSURE_MINUS_HC ) ) ); 4305 4306 Image* pImg = NULL; 4307 if( GetSettings().GetStyleSettings().GetHighContrastMode() ) 4308 pImg = IsChecked() ? rCtrlData.mpDisclosureMinusHC : rCtrlData.mpDisclosurePlusHC; 4309 else 4310 pImg = IsChecked() ? rCtrlData.mpDisclosureMinus : rCtrlData.mpDisclosurePlus; 4311 4312 DBG_ASSERT( pImg, "no disclosure image" ); 4313 if( ! pImg ) 4314 return; 4315 4316 sal_uInt16 nStyle = 0; 4317 if( ! IsEnabled() ) 4318 nStyle |= IMAGE_DRAW_DISABLE; 4319 4320 Size aSize( aStateRect.GetSize() ); 4321 Size aImgSize( pImg->GetSizePixel() ); 4322 Point aOff( (aSize.Width() - aImgSize.Width())/2, 4323 (aSize.Height() - aImgSize.Height())/2 ); 4324 aOff += aStateRect.TopLeft(); 4325 DrawImage( aOff, *pImg, nStyle ); 4326 } 4327 } 4328 4329 // ----------------------------------------------------------------------- 4330 4331 void DisclosureButton::KeyInput( const KeyEvent& rKEvt ) 4332 { 4333 KeyCode aKeyCode = rKEvt.GetKeyCode(); 4334 4335 if( !aKeyCode.GetModifier() && 4336 ( ( aKeyCode.GetCode() == KEY_ADD ) || 4337 ( aKeyCode.GetCode() == KEY_SUBTRACT ) ) 4338 ) 4339 { 4340 Check( aKeyCode.GetCode() == KEY_ADD ); 4341 } 4342 else 4343 Button::KeyInput( rKEvt ); 4344 } 4345 4346 4347