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