update dev300-m58
[ooovba.git] / vcl / source / control / button.cxx
blob43234700915358d8120a3a2c579d54d8c15e185f
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: button.cxx,v $
10 * $Revision: 1.63 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
34 #include <tools/debug.hxx>
36 #ifndef _SV_SVIDS_HRC
37 #include <vcl/svids.hrc>
38 #endif
39 #include <vcl/svdata.hxx>
40 #ifndef _SV_IAMGE_HXX
41 #include <vcl/image.hxx>
42 #endif
43 #include <vcl/bitmap.hxx>
44 #include <vcl/bitmapex.hxx>
45 #include <vcl/decoview.hxx>
46 #include <vcl/event.hxx>
47 #include <vcl/svapp.hxx>
48 #include <vcl/dialog.hxx>
49 #include <vcl/fixed.hxx>
50 #include <tools/poly.hxx>
51 #include <vcl/button.hxx>
52 #include <vcl/window.h>
53 #include <vcl/controllayout.hxx>
54 #ifndef _SV_NATIVEWIDGET_HXX
55 #include <vcl/salnativewidgets.hxx>
56 #endif
57 #include <vcl/edit.hxx>
59 #ifndef _SV_RC_H
60 #include <tools/rc.h>
61 #endif
65 // =======================================================================
67 #define PUSHBUTTON_VIEW_STYLE (WB_3DLOOK | \
68 WB_LEFT | WB_CENTER | WB_RIGHT | \
69 WB_TOP | WB_VCENTER | WB_BOTTOM | \
70 WB_WORDBREAK | WB_NOLABEL | \
71 WB_DEFBUTTON | WB_NOLIGHTBORDER | \
72 WB_RECTSTYLE | WB_SMALLSTYLE | \
73 WB_TOGGLE )
74 #define RADIOBUTTON_VIEW_STYLE (WB_3DLOOK | \
75 WB_LEFT | WB_CENTER | WB_RIGHT | \
76 WB_TOP | WB_VCENTER | WB_BOTTOM | \
77 WB_WORDBREAK | WB_NOLABEL)
78 #define CHECKBOX_VIEW_STYLE (WB_3DLOOK | \
79 WB_LEFT | WB_CENTER | WB_RIGHT | \
80 WB_TOP | WB_VCENTER | WB_BOTTOM | \
81 WB_WORDBREAK | WB_NOLABEL)
83 // =======================================================================
85 class ImplCommonButtonData
87 public:
88 Rectangle maFocusRect;
89 USHORT mnButtonState;
90 BOOL mbSmallSymbol;
92 Image maImage;
93 Image maImageHC;
94 BitmapEx* mpBitmapEx;
95 BitmapEx* mpBitmapExHC;
96 ImageAlign meImageAlign;
97 SymbolAlign meSymbolAlign;
99 public:
100 ImplCommonButtonData();
101 ~ImplCommonButtonData();
104 // -----------------------------------------------------------------------
105 ImplCommonButtonData::ImplCommonButtonData()
107 mnButtonState = 0;
108 mbSmallSymbol = FALSE;
110 mpBitmapEx = NULL;
111 mpBitmapExHC = NULL;
112 meImageAlign = IMAGEALIGN_TOP;
113 meSymbolAlign = SYMBOLALIGN_LEFT;
116 // -----------------------------------------------------------------------
117 ImplCommonButtonData::~ImplCommonButtonData()
119 delete mpBitmapEx;
120 delete mpBitmapExHC;
123 // =======================================================================
125 Button::Button( WindowType nType ) :
126 Control( nType )
128 mpButtonData = new ImplCommonButtonData;
131 // -----------------------------------------------------------------------
133 Button::Button( Window* pParent, WinBits nStyle ) :
134 Control( WINDOW_BUTTON )
136 mpButtonData = new ImplCommonButtonData;
137 ImplInit( pParent, nStyle, NULL );
140 // -----------------------------------------------------------------------
142 Button::Button( Window* pParent, const ResId& rResId ) :
143 Control( WINDOW_BUTTON )
145 rResId.SetRT( RSC_BUTTON );
146 mpButtonData = new ImplCommonButtonData;
147 WinBits nStyle = ImplInitRes( rResId );
148 ImplInit( pParent, nStyle, NULL );
149 ImplLoadRes( rResId );
151 if ( !(nStyle & WB_HIDE) )
152 Show();
155 // -----------------------------------------------------------------------
157 Button::~Button()
159 delete mpButtonData;
162 // -----------------------------------------------------------------------
164 void Button::Click()
166 ImplCallEventListenersAndHandler( VCLEVENT_BUTTON_CLICK, maClickHdl, this );
169 // -----------------------------------------------------------------------
171 XubString Button::GetStandardText( StandardButtonType eButton )
173 static struct
175 sal_uInt32 nResId;
176 const char* pDefText;
177 } aResIdAry[BUTTON_COUNT] =
179 { SV_BUTTONTEXT_OK, "~OK" },
180 { SV_BUTTONTEXT_CANCEL, "~Cancel" },
181 { SV_BUTTONTEXT_YES, "~Yes" },
182 { SV_BUTTONTEXT_NO, "~No" },
183 { SV_BUTTONTEXT_RETRY, "~Retry" },
184 { SV_BUTTONTEXT_HELP, "~Help" },
185 { SV_BUTTONTEXT_CLOSE, "~Close" },
186 { SV_BUTTONTEXT_MORE, "~More" },
187 { SV_BUTTONTEXT_IGNORE, "~Ignore" },
188 { SV_BUTTONTEXT_ABORT, "~Abort" },
189 { SV_BUTTONTEXT_LESS, "~Less" }
192 String aText;
193 ResMgr* pResMgr = ImplGetResMgr();
194 if( pResMgr )
196 ResId aResId( aResIdAry[(USHORT)eButton].nResId, *pResMgr );
197 aText = String( aResId );
199 else
201 ByteString aT( aResIdAry[(USHORT)eButton].pDefText );
202 aText = String( aT, RTL_TEXTENCODING_ASCII_US );
204 return aText;
207 // -----------------------------------------------------------------------
209 XubString Button::GetStandardHelpText( StandardButtonType /* eButton */ )
211 XubString aHelpText;
212 return aHelpText;
214 // -----------------------------------------------------------------------
215 BOOL Button::SetModeImage( const Image& rImage, BmpColorMode eMode )
217 if( eMode == BMP_COLOR_NORMAL )
219 if ( rImage != mpButtonData->maImage )
221 delete mpButtonData->mpBitmapEx;
223 mpButtonData->mpBitmapEx = NULL;
224 mpButtonData->maImage = rImage;
226 StateChanged( STATE_CHANGE_DATA );
229 else if( eMode == BMP_COLOR_HIGHCONTRAST )
231 if( rImage != mpButtonData->maImageHC )
233 delete mpButtonData->mpBitmapExHC;
235 mpButtonData->mpBitmapExHC = NULL;
236 mpButtonData->maImageHC = rImage;
238 StateChanged( STATE_CHANGE_DATA );
241 else
242 return FALSE;
244 return TRUE;
247 // -----------------------------------------------------------------------
248 const Image Button::GetModeImage( BmpColorMode eMode ) const
250 if( eMode == BMP_COLOR_NORMAL )
252 return mpButtonData->maImage;
254 else if( eMode == BMP_COLOR_HIGHCONTRAST )
256 return mpButtonData->maImageHC;
258 else
259 return Image();
262 // -----------------------------------------------------------------------
263 BOOL Button::HasImage() const
265 return !!(mpButtonData->maImage);
268 // -----------------------------------------------------------------------
269 void Button::SetImageAlign( ImageAlign eAlign )
271 if ( mpButtonData->meImageAlign != eAlign )
273 mpButtonData->meImageAlign = eAlign;
274 StateChanged( STATE_CHANGE_DATA );
278 // -----------------------------------------------------------------------
279 ImageAlign Button::GetImageAlign() const
281 return mpButtonData->meImageAlign;
284 // -----------------------------------------------------------------------
285 BOOL Button::SetModeBitmap( const BitmapEx& rBitmap, BmpColorMode eMode )
287 if ( SetModeImage( rBitmap, eMode ) )
289 if( eMode == BMP_COLOR_NORMAL )
291 if ( !mpButtonData->mpBitmapEx )
292 mpButtonData->mpBitmapEx = new BitmapEx( rBitmap );
294 else if ( eMode == BMP_COLOR_HIGHCONTRAST )
296 if ( !mpButtonData->mpBitmapExHC )
297 mpButtonData->mpBitmapExHC = new BitmapEx( rBitmap );
299 else
300 return FALSE;
302 return TRUE;
304 return FALSE;
307 // -----------------------------------------------------------------------
308 BitmapEx Button::GetModeBitmap( BmpColorMode eMode ) const
310 BitmapEx aBmp;
312 if ( eMode == BMP_COLOR_NORMAL )
314 if ( mpButtonData->mpBitmapEx )
315 aBmp = *( mpButtonData->mpBitmapEx );
317 else if ( eMode == BMP_COLOR_HIGHCONTRAST )
319 if ( mpButtonData->mpBitmapExHC )
320 aBmp = *( mpButtonData->mpBitmapExHC );
323 return aBmp;
326 // -----------------------------------------------------------------------
327 void Button::SetFocusRect( const Rectangle& rFocusRect )
329 ImplSetFocusRect( rFocusRect );
332 // -----------------------------------------------------------------------
333 const Rectangle& Button::GetFocusRect() const
335 return ImplGetFocusRect();
338 // -----------------------------------------------------------------------
340 USHORT Button::ImplGetTextStyle( XubString& rText, WinBits nWinStyle,
341 ULONG nDrawFlags )
343 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
344 USHORT nTextStyle = FixedText::ImplGetTextStyle( nWinStyle & ~WB_DEFBUTTON );
346 if ( nDrawFlags & WINDOW_DRAW_NOMNEMONIC )
348 if ( nTextStyle & TEXT_DRAW_MNEMONIC )
350 rText = GetNonMnemonicString( rText );
351 nTextStyle &= ~TEXT_DRAW_MNEMONIC;
355 if ( !(nDrawFlags & WINDOW_DRAW_NODISABLE) )
357 if ( !IsEnabled() )
358 nTextStyle |= TEXT_DRAW_DISABLE;
361 if ( (nDrawFlags & WINDOW_DRAW_MONO) ||
362 (rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
363 nTextStyle |= TEXT_DRAW_MONO;
365 return nTextStyle;
368 // -----------------------------------------------------------------------
370 void Button::ImplDrawAlignedImage( OutputDevice* pDev, Point& rPos,
371 Size& rSize, BOOL bLayout,
372 ULONG nImageSep, ULONG nDrawFlags,
373 USHORT nTextStyle, Rectangle *pSymbolRect )
375 XubString aText( GetText() );
376 BOOL bDrawImage = HasImage() && ! ( ImplGetButtonState() & BUTTON_DRAW_NOIMAGE );
377 BOOL bDrawText = aText.Len() && ! ( ImplGetButtonState() & BUTTON_DRAW_NOTEXT );
378 BOOL bHasSymbol = pSymbolRect ? TRUE : FALSE;
380 // No text and no image => nothing to do => return
381 if ( !bDrawImage && !bDrawText && !bHasSymbol )
382 return;
384 WinBits nWinStyle = GetStyle();
385 Rectangle aOutRect( rPos, rSize );
386 MetricVector *pVector = bLayout ? &mpLayoutData->m_aUnicodeBoundRects : NULL;
387 String *pDisplayText = bLayout ? &mpLayoutData->m_aDisplayText : NULL;
388 ImageAlign eImageAlign = mpButtonData->meImageAlign;
389 Size aImageSize = mpButtonData->maImage.GetSizePixel();
391 if ( ( nDrawFlags & WINDOW_DRAW_NOMNEMONIC ) &&
392 ( nTextStyle & TEXT_DRAW_MNEMONIC ) )
394 aText = GetNonMnemonicString( aText );
395 nTextStyle &= ~TEXT_DRAW_MNEMONIC;
398 aImageSize.Width() = CalcZoom( aImageSize.Width() );
399 aImageSize.Height() = CalcZoom( aImageSize.Height() );
401 // Drawing text or symbol only is simple, use style and output rectangle
402 if ( bHasSymbol && !bDrawImage && !bDrawText )
404 *pSymbolRect = aOutRect;
405 return;
407 else if ( bDrawText && !bDrawImage && !bHasSymbol )
409 Rectangle aDrawRect = aOutRect;
411 aOutRect = pDev->GetTextRect( aOutRect, aText, nTextStyle );
412 rSize = aOutRect.GetSize();
413 rPos = aOutRect.TopLeft();
415 ImplSetFocusRect( aOutRect );
417 pDev->DrawText( aDrawRect, aText, nTextStyle, pVector, pDisplayText );
418 return;
421 // check for HC mode ( image only! )
422 Image *pImage = &(mpButtonData->maImage);
423 BitmapEx *pBitmapEx = mpButtonData->mpBitmapEx;
425 Color aBackCol;
426 if( !!(mpButtonData->maImageHC) && ImplGetCurrentBackgroundColor( aBackCol ) )
428 if( aBackCol.IsDark() )
430 pImage = &(mpButtonData->maImageHC);
431 pBitmapEx = mpButtonData->mpBitmapExHC;
435 if ( pBitmapEx && ( pDev->GetOutDevType() == OUTDEV_PRINTER ) )
437 // Die Groesse richtet sich nach dem Bildschirm, soll auf
438 // dem Drucker genau so aussehen...
439 MapMode aMap100thMM( MAP_100TH_MM );
440 aImageSize = PixelToLogic( aImageSize, aMap100thMM );
441 aImageSize = pDev->LogicToPixel( aImageSize, aMap100thMM );
444 Size aTextSize;
445 Size aSymbolSize;
446 Size aMax;
447 Point aImagePos = rPos;
448 Point aTextPos = rPos;
449 Rectangle aUnion = Rectangle( aImagePos, aImageSize );
450 Rectangle aSymbol;
451 long nSymbolHeight = 0;
453 if ( bDrawText || bHasSymbol )
455 // Get the size of the text output area ( the symbol will be drawn in
456 // this area as well, so the symbol rectangle will be calculated here, too )
458 Rectangle aRect = Rectangle( Point(), rSize );
459 Size aTSSize;
461 if ( bHasSymbol )
463 if ( bDrawText )
465 nSymbolHeight = pDev->GetTextHeight();
466 if ( mpButtonData->mbSmallSymbol )
467 nSymbolHeight = nSymbolHeight * 3 / 4;
469 aSymbol = Rectangle( Point(), Size( nSymbolHeight, nSymbolHeight ) );
470 ImplCalcSymbolRect( aSymbol );
471 aRect.Left() += 3 * nSymbolHeight / 2;
472 aTSSize.Width() = 3 * nSymbolHeight / 2;
474 else
476 aSymbol = Rectangle( Point(), rSize );
477 ImplCalcSymbolRect( aSymbol );
478 aTSSize.Width() = aSymbol.GetWidth();
480 aTSSize.Height() = aSymbol.GetHeight();
481 aSymbolSize = aSymbol.GetSize();
484 if ( bDrawText )
486 if ( ( eImageAlign == IMAGEALIGN_LEFT_TOP ) ||
487 ( eImageAlign == IMAGEALIGN_LEFT ) ||
488 ( eImageAlign == IMAGEALIGN_LEFT_BOTTOM ) ||
489 ( eImageAlign == IMAGEALIGN_RIGHT_TOP ) ||
490 ( eImageAlign == IMAGEALIGN_RIGHT ) ||
491 ( eImageAlign == IMAGEALIGN_RIGHT_BOTTOM ) )
493 aRect.Right() -= ( aImageSize.Width() + nImageSep );
495 else if ( ( eImageAlign == IMAGEALIGN_TOP_LEFT ) ||
496 ( eImageAlign == IMAGEALIGN_TOP ) ||
497 ( eImageAlign == IMAGEALIGN_TOP_RIGHT ) ||
498 ( eImageAlign == IMAGEALIGN_BOTTOM_LEFT ) ||
499 ( eImageAlign == IMAGEALIGN_BOTTOM ) ||
500 ( eImageAlign == IMAGEALIGN_BOTTOM_RIGHT ) )
502 aRect.Bottom() -= ( aImageSize.Height() + nImageSep );
505 aRect = pDev->GetTextRect( aRect, aText, nTextStyle );
506 aTextSize = aRect.GetSize();
508 aTSSize.Width() += aTextSize.Width();
510 if ( aTSSize.Height() < aTextSize.Height() )
511 aTSSize.Height() = aTextSize.Height();
514 aMax.Width() = aTSSize.Width() > aImageSize.Width() ? aTSSize.Width() : aImageSize.Width();
515 aMax.Height() = aTSSize.Height() > aImageSize.Height() ? aTSSize.Height() : aImageSize.Height();
517 // Now calculate the output area for the image and the text acording to the image align flags
519 if ( ( eImageAlign == IMAGEALIGN_LEFT ) ||
520 ( eImageAlign == IMAGEALIGN_RIGHT ) )
522 aImagePos.Y() = rPos.Y() + ( aMax.Height() - aImageSize.Height() ) / 2;
523 aTextPos.Y() = rPos.Y() + ( aMax.Height() - aTSSize.Height() ) / 2;
525 else if ( ( eImageAlign == IMAGEALIGN_LEFT_BOTTOM ) ||
526 ( eImageAlign == IMAGEALIGN_RIGHT_BOTTOM ) )
528 aImagePos.Y() = rPos.Y() + aMax.Height() - aImageSize.Height();
529 aTextPos.Y() = rPos.Y() + aMax.Height() - aTSSize.Height();
531 else if ( ( eImageAlign == IMAGEALIGN_TOP ) ||
532 ( eImageAlign == IMAGEALIGN_BOTTOM ) )
534 aImagePos.X() = rPos.X() + ( aMax.Width() - aImageSize.Width() ) / 2;
535 aTextPos.X() = rPos.X() + ( aMax.Width() - aTSSize.Width() ) / 2;
537 else if ( ( eImageAlign == IMAGEALIGN_TOP_RIGHT ) ||
538 ( eImageAlign == IMAGEALIGN_BOTTOM_RIGHT ) )
540 aImagePos.X() = rPos.X() + aMax.Width() - aImageSize.Width();
541 aTextPos.X() = rPos.X() + aMax.Width() - aTSSize.Width();
544 if ( ( eImageAlign == IMAGEALIGN_LEFT_TOP ) ||
545 ( eImageAlign == IMAGEALIGN_LEFT ) ||
546 ( eImageAlign == IMAGEALIGN_LEFT_BOTTOM ) )
548 aTextPos.X() = rPos.X() + aImageSize.Width() + nImageSep;
550 else if ( ( eImageAlign == IMAGEALIGN_RIGHT_TOP ) ||
551 ( eImageAlign == IMAGEALIGN_RIGHT ) ||
552 ( eImageAlign == IMAGEALIGN_RIGHT_BOTTOM ) )
554 aImagePos.X() = rPos.X() + aTSSize.Width() + nImageSep;
556 else if ( ( eImageAlign == IMAGEALIGN_TOP_LEFT ) ||
557 ( eImageAlign == IMAGEALIGN_TOP ) ||
558 ( eImageAlign == IMAGEALIGN_TOP_RIGHT ) )
560 aTextPos.Y() = rPos.Y() + aImageSize.Height() + nImageSep;
562 else if ( ( eImageAlign == IMAGEALIGN_BOTTOM_LEFT ) ||
563 ( eImageAlign == IMAGEALIGN_BOTTOM ) ||
564 ( eImageAlign == IMAGEALIGN_BOTTOM_RIGHT ) )
566 aImagePos.Y() = rPos.Y() + aTSSize.Height() + nImageSep;
568 else if ( eImageAlign == IMAGEALIGN_CENTER )
570 aImagePos.X() = rPos.X() + ( aMax.Width() - aImageSize.Width() ) / 2;
571 aImagePos.Y() = rPos.Y() + ( aMax.Height() - aImageSize.Height() ) / 2;
572 aTextPos.X() = rPos.X() + ( aMax.Width() - aTSSize.Width() ) / 2;
573 aTextPos.Y() = rPos.Y() + ( aMax.Height() - aTSSize.Height() ) / 2;
575 aUnion = Rectangle( aImagePos, aImageSize );
576 aUnion.Union( Rectangle( aTextPos, aTSSize ) );
579 // Now place the combination of text and image in the output area of the button
580 // according to the window style (WinBits)
581 long nXOffset = 0;
582 long nYOffset = 0;
584 if ( nWinStyle & WB_CENTER )
586 nXOffset = ( rSize.Width() - aUnion.GetWidth() ) / 2;
588 else if ( nWinStyle & WB_RIGHT )
590 nXOffset = rSize.Width() - aUnion.GetWidth();
593 if ( nWinStyle & WB_VCENTER )
595 nYOffset = ( rSize.Height() - aUnion.GetHeight() ) / 2;
597 else if ( nWinStyle & WB_BOTTOM )
599 nYOffset = rSize.Height() - aUnion.GetHeight();
602 // the top left corner should always be visible, so we don't allow negative offsets
603 if ( nXOffset < 0 ) nXOffset = 0;
604 if ( nYOffset < 0 ) nYOffset = 0;
606 aImagePos.X() += nXOffset;
607 aImagePos.Y() += nYOffset;
608 aTextPos.X() += nXOffset;
609 aTextPos.Y() += nYOffset;
611 // set rPos and rSize to the union
612 rSize = aUnion.GetSize();
613 rPos.X() += nXOffset;
614 rPos.Y() += nYOffset;
616 if ( bHasSymbol )
618 if ( mpButtonData->meSymbolAlign == SYMBOLALIGN_RIGHT )
620 Point aRightPos = Point( aTextPos.X() + aTextSize.Width() + aSymbolSize.Width()/2, aTextPos.Y() );
621 *pSymbolRect = Rectangle( aRightPos, aSymbolSize );
623 else
625 *pSymbolRect = Rectangle( aTextPos, aSymbolSize );
626 aTextPos.X() += ( 3 * nSymbolHeight / 2 );
628 if ( mpButtonData->mbSmallSymbol )
630 nYOffset = (aUnion.GetHeight() - aSymbolSize.Height())/2;
631 pSymbolRect->setY( aTextPos.Y() + nYOffset );
635 USHORT nStyle = 0;
637 if ( ! ( nDrawFlags & WINDOW_DRAW_NODISABLE ) &&
638 ! IsEnabled() )
639 nStyle |= IMAGE_DRAW_DISABLE;
641 if ( pBitmapEx && ( pDev->GetOutDevType() == OUTDEV_PRINTER ) )
643 // Fuer die BitmapEx ueberlegt sich KA noch, wie man die disablete
644 // Darstellung hinbekommt...
645 pBitmapEx->Draw( pDev, aImagePos, aImageSize /*, nStyle*/ );
647 else
649 if ( IsZoom() )
650 pDev->DrawImage( aImagePos, aImageSize, *pImage, nStyle );
651 else
652 pDev->DrawImage( aImagePos, *pImage, nStyle );
655 if ( bDrawText )
657 ImplSetFocusRect( Rectangle( aTextPos, aTextSize ) );
658 pDev->DrawText( Rectangle( aTextPos, aTextSize ), aText, nTextStyle, pVector, pDisplayText );
660 else
662 ImplSetFocusRect( Rectangle( aImagePos, aImageSize ) );
666 // -----------------------------------------------------------------------
667 void Button::ImplSetFocusRect( const Rectangle &rFocusRect )
669 Rectangle aFocusRect = rFocusRect;
670 Rectangle aOutputRect = Rectangle( Point(), GetOutputSizePixel() );
672 if ( ! aFocusRect.IsEmpty() )
674 aFocusRect.Left()--;
675 aFocusRect.Top()--;
676 aFocusRect.Right()++;
677 aFocusRect.Bottom()++;
680 if ( aFocusRect.Left() < aOutputRect.Left() ) aFocusRect.Left() = aOutputRect.Left();
681 if ( aFocusRect.Top() < aOutputRect.Top() ) aFocusRect.Top() = aOutputRect.Top();
682 if ( aFocusRect.Right() > aOutputRect.Right() ) aFocusRect.Right() = aOutputRect.Right();
683 if ( aFocusRect.Bottom() > aOutputRect.Bottom() ) aFocusRect.Bottom() = aOutputRect.Bottom();
685 mpButtonData->maFocusRect = aFocusRect;
688 // -----------------------------------------------------------------------
689 const Rectangle& Button::ImplGetFocusRect() const
691 return mpButtonData->maFocusRect;
694 // -----------------------------------------------------------------------
695 USHORT& Button::ImplGetButtonState()
697 return mpButtonData->mnButtonState;
700 // -----------------------------------------------------------------------
701 USHORT Button::ImplGetButtonState() const
703 return mpButtonData->mnButtonState;
706 // -----------------------------------------------------------------------
707 void Button::ImplSetSymbolAlign( SymbolAlign eAlign )
709 if ( mpButtonData->meSymbolAlign != eAlign )
711 mpButtonData->meSymbolAlign = eAlign;
712 StateChanged( STATE_CHANGE_DATA );
716 // -----------------------------------------------------------------------
717 SymbolAlign Button::ImplGetSymbolAlign() const
719 return mpButtonData->meSymbolAlign;
721 // -----------------------------------------------------------------------
722 void Button::ImplSetSmallSymbol( BOOL bSmall )
724 mpButtonData->mbSmallSymbol = bSmall;
727 // -----------------------------------------------------------------------
728 void Button::EnableImageDisplay( BOOL bEnable )
730 if( bEnable )
731 mpButtonData->mnButtonState &= ~BUTTON_DRAW_NOIMAGE;
732 else
733 mpButtonData->mnButtonState |= BUTTON_DRAW_NOIMAGE;
736 // -----------------------------------------------------------------------
737 BOOL Button::IsImageDisplayEnabled()
739 return (mpButtonData->mnButtonState & BUTTON_DRAW_NOIMAGE) == 0;
742 // -----------------------------------------------------------------------
743 void Button::EnableTextDisplay( BOOL bEnable )
745 if( bEnable )
746 mpButtonData->mnButtonState &= ~BUTTON_DRAW_NOTEXT;
747 else
748 mpButtonData->mnButtonState |= BUTTON_DRAW_NOTEXT;
751 // -----------------------------------------------------------------------
752 BOOL Button::IsTextDisplayEnabled()
754 return (mpButtonData->mnButtonState & BUTTON_DRAW_NOTEXT) == 0;
757 // -----------------------------------------------------------------------
758 void Button::DataChanged( const DataChangedEvent& rDCEvt )
760 Control::DataChanged( rDCEvt );
762 // The flag SETTINGS_IN_UPDATE_SETTINGS is set when the settings changed due to a
763 // Application::SettingsChanged event. In this scenario we want to keep the style settings
764 // of our radio buttons and our check boxes.
765 if ( ( rDCEvt.GetType() == DATACHANGED_SETTINGS ) &&
766 ( rDCEvt.GetFlags() & SETTINGS_IN_UPDATE_SETTINGS ) )
769 const AllSettings* pOldSettings = rDCEvt.GetOldSettings();
770 if ( pOldSettings )
772 BOOL bResetStyleSettings = FALSE;
773 AllSettings aAllSettings = GetSettings();
774 StyleSettings aStyleSetting = aAllSettings.GetStyleSettings();
776 USHORT nCheckBoxStyle = aStyleSetting.GetCheckBoxStyle();
777 if ( nCheckBoxStyle != pOldSettings->GetStyleSettings().GetCheckBoxStyle() )
779 aStyleSetting.SetCheckBoxStyle( pOldSettings->GetStyleSettings().GetCheckBoxStyle() );
780 bResetStyleSettings = TRUE;
783 USHORT nRadioButtonStyle = aStyleSetting.GetRadioButtonStyle();
784 if ( nRadioButtonStyle != pOldSettings->GetStyleSettings().GetRadioButtonStyle() )
786 aStyleSetting.SetRadioButtonStyle( pOldSettings->GetStyleSettings().GetRadioButtonStyle() );
787 bResetStyleSettings = TRUE;
790 if ( bResetStyleSettings )
792 aAllSettings.SetStyleSettings( pOldSettings->GetStyleSettings() );
793 SetSettings( aAllSettings );
799 void Button::SetSmallSymbol (bool small)
801 ImplSetSmallSymbol (small);
804 bool Button::IsSmallSymbol () const
806 return mpButtonData->mbSmallSymbol;
809 // =======================================================================
811 void PushButton::ImplInitPushButtonData()
813 mpWindowImpl->mbPushButton = TRUE;
815 meSymbol = SYMBOL_NOSYMBOL;
816 meState = STATE_NOCHECK;
817 meSaveValue = STATE_NOCHECK;
818 mnDDStyle = 0;
819 mbPressed = FALSE;
820 mbInUserDraw = FALSE;
823 // -----------------------------------------------------------------------
825 void PushButton::ImplInit( Window* pParent, WinBits nStyle )
827 nStyle = ImplInitStyle( pParent->GetWindow( WINDOW_LASTCHILD ), nStyle );
828 Button::ImplInit( pParent, nStyle, NULL );
830 if ( nStyle & WB_NOLIGHTBORDER )
831 ImplGetButtonState() |= BUTTON_DRAW_NOLIGHTBORDER;
833 ImplInitSettings( TRUE, TRUE, TRUE );
836 // -----------------------------------------------------------------------
838 WinBits PushButton::ImplInitStyle( const Window* pPrevWindow, WinBits nStyle )
840 if ( !(nStyle & WB_NOTABSTOP) )
841 nStyle |= WB_TABSTOP;
843 // if no alignment is given, default to "vertically centered". This is because since
844 // #i26046#, we respect the vertical alignment flags (previously we didn't completely),
845 // but we of course want to look as before when no vertical alignment is specified
846 if ( ( nStyle & ( WB_TOP | WB_VCENTER | WB_BOTTOM ) ) == 0 )
847 nStyle |= WB_VCENTER;
849 if ( !(nStyle & WB_NOGROUP) &&
850 (!pPrevWindow ||
851 ((pPrevWindow->GetType() != WINDOW_PUSHBUTTON) &&
852 (pPrevWindow->GetType() != WINDOW_OKBUTTON) &&
853 (pPrevWindow->GetType() != WINDOW_CANCELBUTTON) &&
854 (pPrevWindow->GetType() != WINDOW_HELPBUTTON)) ) )
855 nStyle |= WB_GROUP;
856 return nStyle;
859 // -----------------------------------------------------------------------
861 void PushButton::ImplInitSettings( BOOL bFont,
862 BOOL bForeground, BOOL bBackground )
864 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
866 if ( bFont )
868 Font aFont = rStyleSettings.GetPushButtonFont();
869 if ( IsControlFont() )
870 aFont.Merge( GetControlFont() );
871 SetZoomedPointFont( aFont );
874 if ( bForeground || bFont )
876 Color aColor;
877 if ( IsControlForeground() )
878 aColor = GetControlForeground();
879 else
880 aColor = rStyleSettings.GetButtonTextColor();
881 SetTextColor( aColor );
882 SetTextFillColor();
885 if ( bBackground )
887 SetBackground();
888 // #i38498#: do not check for GetParent()->IsChildTransparentModeEnabled()
889 // otherwise the formcontrol button will be overdrawn due to PARENTCLIPMODE_NOCLIP
890 // for radio and checkbox this is ok as they shoud appear transparent in documents
891 if ( IsNativeControlSupported( CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL ) )
893 EnableChildTransparentMode( TRUE );
894 SetParentClipMode( PARENTCLIPMODE_NOCLIP );
895 SetPaintTransparent( TRUE );
896 mpWindowImpl->mbUseNativeFocus = ImplGetSVData()->maNWFData.mbNoFocusRects;
898 else
900 EnableChildTransparentMode( FALSE );
901 SetParentClipMode( 0 );
902 SetPaintTransparent( FALSE );
907 // -----------------------------------------------------------------------
909 void PushButton::ImplDrawPushButtonFrame( Window* pDev,
910 Rectangle& rRect, USHORT nStyle )
912 if ( !(pDev->GetStyle() & (WB_RECTSTYLE | WB_SMALLSTYLE)) )
914 StyleSettings aStyleSettings = pDev->GetSettings().GetStyleSettings();
915 if ( pDev->IsControlBackground() )
916 aStyleSettings.Set3DColors( pDev->GetControlBackground() );
918 USHORT nPushButtonSysStyle = aStyleSettings.GetPushButtonStyle() & STYLE_PUSHBUTTON_STYLE;
919 if ( nPushButtonSysStyle == STYLE_PUSHBUTTON_MAC )
921 pDev->SetLineColor();
922 pDev->SetFillColor( aStyleSettings.GetFaceColor() );
923 pDev->DrawRect( rRect );
925 if ( (aStyleSettings.GetOptions() & STYLE_OPTION_MONO) ||
926 (pDev->GetOutDevType() == OUTDEV_PRINTER) )
927 nStyle |= BUTTON_DRAW_MONO;
929 if ( nStyle & BUTTON_DRAW_DEFAULT )
931 if ( nStyle & BUTTON_DRAW_MONO )
932 pDev->SetLineColor( Color( COL_BLACK ) );
933 else
934 pDev->SetLineColor( aStyleSettings.GetDarkShadowColor() );
936 pDev->DrawLine( Point( rRect.Left()+3, rRect.Top() ),
937 Point( rRect.Right()-3, rRect.Top() ) );
938 pDev->DrawLine( Point( rRect.Left()+3, rRect.Bottom() ),
939 Point( rRect.Right()-3, rRect.Bottom() ) );
940 pDev->DrawLine( Point( rRect.Left(), rRect.Top()+3 ),
941 Point( rRect.Left(), rRect.Bottom()-3 ) );
942 pDev->DrawLine( Point( rRect.Right(), rRect.Top()+3 ),
943 Point( rRect.Right(), rRect.Bottom()-3 ) );
944 pDev->DrawPixel( Point( rRect.Left()+2, rRect.Top()+1 ) );
945 pDev->DrawPixel( Point( rRect.Left()+1, rRect.Top()+2 ) );
946 pDev->DrawPixel( Point( rRect.Right()-2, rRect.Top()+1 ) );
947 pDev->DrawPixel( Point( rRect.Right()-1, rRect.Top()+2 ) );
948 pDev->DrawPixel( Point( rRect.Left()+2, rRect.Bottom()-1 ) );
949 pDev->DrawPixel( Point( rRect.Left()+1, rRect.Bottom()-2 ) );
950 pDev->DrawPixel( Point( rRect.Right()-2, rRect.Bottom()-1 ) );
951 pDev->DrawPixel( Point( rRect.Right()-1, rRect.Bottom()-2 ) );
953 if ( nStyle & BUTTON_DRAW_MONO )
954 pDev->SetLineColor( Color( COL_BLACK ) );
955 else
956 pDev->SetLineColor( aStyleSettings.GetShadowColor() );
957 pDev->DrawLine( Point( rRect.Left()+3, rRect.Bottom()-1 ),
958 Point( rRect.Right()-3, rRect.Bottom()-1 ) );
959 pDev->DrawLine( Point( rRect.Right()-1, rRect.Top()+3 ),
960 Point( rRect.Right()-1, rRect.Bottom()-3 ) );
961 pDev->DrawPixel( Point( rRect.Right()-3, rRect.Bottom()-2 ) );
962 pDev->DrawPixel( Point( rRect.Right()-2, rRect.Bottom()-2 ) );
963 pDev->DrawPixel( Point( rRect.Right()-2, rRect.Bottom()-3 ) );
966 rRect.Left() += 2;
967 rRect.Top() += 2;
968 rRect.Right() -= 2;
969 rRect.Bottom() -= 2;
971 if ( nStyle & BUTTON_DRAW_MONO )
972 pDev->SetLineColor( Color( COL_BLACK ) );
973 else
974 pDev->SetLineColor( aStyleSettings.GetDarkShadowColor() );
976 pDev->DrawLine( Point( rRect.Left()+2, rRect.Top() ),
977 Point( rRect.Right()-2, rRect.Top() ) );
978 pDev->DrawLine( Point( rRect.Left()+2, rRect.Bottom() ),
979 Point( rRect.Right()-2, rRect.Bottom() ) );
980 pDev->DrawLine( Point( rRect.Left(), rRect.Top()+2 ),
981 Point( rRect.Left(), rRect.Bottom()-2 ) );
982 pDev->DrawLine( Point( rRect.Right(), rRect.Top()+2 ),
983 Point( rRect.Right(), rRect.Bottom()-2 ) );
984 pDev->DrawPixel( Point( rRect.Left()+1, rRect.Top()+1 ) );
985 pDev->DrawPixel( Point( rRect.Right()-1, rRect.Top()+1 ) );
986 pDev->DrawPixel( Point( rRect.Left()+1, rRect.Bottom()-1 ) );
987 pDev->DrawPixel( Point( rRect.Right()-1, rRect.Bottom()-1 ) );
989 pDev->SetLineColor();
990 if ( nStyle & BUTTON_DRAW_CHECKED )
991 pDev->SetFillColor( aStyleSettings.GetCheckedColor() );
992 else
993 pDev->SetFillColor( aStyleSettings.GetFaceColor() );
994 pDev->DrawRect( Rectangle( rRect.Left()+2, rRect.Top()+2, rRect.Right()-2, rRect.Bottom()-2 ) );
996 if ( !(nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED)) )
998 if ( nStyle & BUTTON_DRAW_MONO )
999 pDev->SetLineColor( Color( COL_BLACK ) );
1000 else
1001 pDev->SetLineColor( aStyleSettings.GetShadowColor() );
1002 pDev->DrawLine( Point( rRect.Left()+2, rRect.Bottom()-1 ),
1003 Point( rRect.Right()-2, rRect.Bottom()-1 ) );
1004 pDev->DrawLine( Point( rRect.Right()-1, rRect.Top()+2 ),
1005 Point( rRect.Right()-1, rRect.Bottom()-2 ) );
1006 pDev->DrawPixel( Point( rRect.Right()-2, rRect.Bottom()-2 ) );
1007 pDev->SetLineColor( aStyleSettings.GetLightColor() );
1009 else
1010 pDev->SetLineColor( aStyleSettings.GetShadowColor() );
1012 if ( !(nStyle & BUTTON_DRAW_MONO) )
1014 pDev->DrawLine( Point( rRect.Left()+2, rRect.Top()+1 ),
1015 Point( rRect.Right()-2, rRect.Top()+1 ) );
1016 pDev->DrawLine( Point( rRect.Left()+1, rRect.Top()+2 ),
1017 Point( rRect.Left()+1, rRect.Bottom()-2 ) );
1018 pDev->DrawPixel( Point( rRect.Top()+2, rRect.Right()+2 ) );
1021 rRect.Left() += 2;
1022 rRect.Top() += 2;
1023 rRect.Right() -= 2;
1024 rRect.Bottom() -= 2;
1026 if ( nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED) )
1028 rRect.Left()++;
1029 rRect.Top()++;
1030 rRect.Right()++;
1031 rRect.Bottom()++;
1034 return;
1038 DecorationView aDecoView( pDev );
1039 if ( pDev->IsControlBackground() )
1041 AllSettings aSettings = pDev->GetSettings();
1042 AllSettings aOldSettings = aSettings;
1043 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1044 aStyleSettings.Set3DColors( pDev->GetControlBackground() );
1045 aSettings.SetStyleSettings( aStyleSettings );
1046 pDev->OutputDevice::SetSettings( aSettings );
1047 rRect = aDecoView.DrawButton( rRect, nStyle );
1048 pDev->OutputDevice::SetSettings( aOldSettings );
1050 else
1051 rRect = aDecoView.DrawButton( rRect, nStyle );
1054 // -----------------------------------------------------------------------
1056 BOOL PushButton::ImplHitTestPushButton( Window* pDev,
1057 const Point& rPos )
1059 Point aTempPoint;
1060 Rectangle aTestRect( aTempPoint, pDev->GetOutputSizePixel() );
1062 if ( !(pDev->GetStyle() & (WB_RECTSTYLE | WB_SMALLSTYLE)) )
1064 const StyleSettings& rStyleSettings = pDev->GetSettings().GetStyleSettings();
1066 USHORT nPushButtonSysStyle = rStyleSettings.GetPushButtonStyle() & STYLE_PUSHBUTTON_STYLE;
1067 if ( nPushButtonSysStyle == STYLE_PUSHBUTTON_MAC )
1069 aTestRect.Left() += 2;
1070 aTestRect.Top() += 2;
1071 aTestRect.Right() -= 2;
1072 aTestRect.Bottom() -= 2;
1076 return aTestRect.IsInside( rPos );
1079 // -----------------------------------------------------------------------
1081 USHORT PushButton::ImplGetTextStyle( ULONG nDrawFlags ) const
1083 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1085 USHORT nTextStyle = TEXT_DRAW_MNEMONIC | TEXT_DRAW_MULTILINE | TEXT_DRAW_ENDELLIPSIS;
1087 if ( ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO ) ||
1088 ( nDrawFlags & WINDOW_DRAW_MONO ) )
1089 nTextStyle |= TEXT_DRAW_MONO;
1091 if ( GetStyle() & WB_WORDBREAK )
1092 nTextStyle |= TEXT_DRAW_WORDBREAK;
1093 if ( GetStyle() & WB_NOLABEL )
1094 nTextStyle &= ~TEXT_DRAW_MNEMONIC;
1096 if ( GetStyle() & WB_LEFT )
1097 nTextStyle |= TEXT_DRAW_LEFT;
1098 else if ( GetStyle() & WB_RIGHT )
1099 nTextStyle |= TEXT_DRAW_RIGHT;
1100 else
1101 nTextStyle |= TEXT_DRAW_CENTER;
1103 if ( GetStyle() & WB_TOP )
1104 nTextStyle |= TEXT_DRAW_TOP;
1105 else if ( GetStyle() & WB_BOTTOM )
1106 nTextStyle |= TEXT_DRAW_BOTTOM;
1107 else
1108 nTextStyle |= TEXT_DRAW_VCENTER;
1110 if ( ! ( (nDrawFlags & WINDOW_DRAW_NODISABLE) || IsEnabled() ) )
1111 nTextStyle |= TEXT_DRAW_DISABLE;
1113 return nTextStyle;
1116 // -----------------------------------------------------------------------
1118 static void ImplDrawBtnDropDownArrow( OutputDevice* pDev,
1119 long nX, long nY,
1120 Color& rColor, BOOL bBlack )
1122 Color aOldLineColor = pDev->GetLineColor();
1123 Color aOldFillColor = pDev->GetFillColor();
1125 pDev->SetLineColor();
1126 if ( bBlack )
1127 pDev->SetFillColor( Color( COL_BLACK ) );
1128 else
1129 pDev->SetFillColor( rColor );
1130 pDev->DrawRect( Rectangle( nX+0, nY+0, nX+6, nY+0 ) );
1131 pDev->DrawRect( Rectangle( nX+1, nY+1, nX+5, nY+1 ) );
1132 pDev->DrawRect( Rectangle( nX+2, nY+2, nX+4, nY+2 ) );
1133 pDev->DrawRect( Rectangle( nX+3, nY+3, nX+3, nY+3 ) );
1134 if ( bBlack )
1136 pDev->SetFillColor( rColor );
1137 pDev->DrawRect( Rectangle( nX+2, nY+1, nX+4, nY+1 ) );
1138 pDev->DrawRect( Rectangle( nX+3, nY+2, nX+3, nY+2 ) );
1140 pDev->SetLineColor( aOldLineColor );
1141 pDev->SetFillColor( aOldFillColor );
1144 // -----------------------------------------------------------------------
1146 void PushButton::ImplDrawPushButtonContent( OutputDevice* pDev, ULONG nDrawFlags,
1147 const Rectangle& rRect,
1148 bool bLayout )
1150 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1151 Rectangle aInRect = rRect;
1152 Color aColor;
1153 XubString aText = PushButton::GetText(); // PushButton:: wegen MoreButton
1154 USHORT nTextStyle = ImplGetTextStyle( nDrawFlags );
1155 USHORT nStyle;
1157 if( aInRect.nRight < aInRect.nLeft || aInRect.nBottom < aInRect.nTop )
1158 aInRect.SetEmpty();
1160 pDev->Push( PUSH_CLIPREGION );
1161 pDev->IntersectClipRegion( aInRect );
1163 if ( nDrawFlags & WINDOW_DRAW_MONO )
1164 aColor = Color( COL_BLACK );
1165 else if ( IsControlForeground() )
1166 aColor = GetControlForeground();
1167 else if( nDrawFlags & WINDOW_DRAW_ROLLOVER )
1168 aColor = rStyleSettings.GetButtonRolloverTextColor();
1169 else
1170 aColor = rStyleSettings.GetButtonTextColor();
1172 pDev->SetTextColor( aColor );
1174 if ( IsEnabled() || (nDrawFlags & WINDOW_DRAW_NODISABLE) )
1175 nStyle = 0;
1176 else
1177 nStyle = SYMBOL_DRAW_DISABLE;
1179 Size aSize = rRect.GetSize();
1180 Point aPos = rRect.TopLeft();
1182 if ( mnDDStyle == PUSHBUTTON_DROPDOWN_MENUBUTTON )
1184 if ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
1186 // calc Symbol- and Textrect
1187 long nSymbolSize = pDev->GetTextHeight() / 2 + 1;
1188 aInRect.Right() -= 5;
1189 aInRect.Left() = aInRect.Right() - nSymbolSize;
1190 aSize.Width() -= ( 5 + nSymbolSize );
1192 ImplDrawAlignedImage( pDev, aPos, aSize, bLayout,
1193 1, nDrawFlags, nTextStyle );
1195 else
1196 ImplCalcSymbolRect( aInRect );
1198 if( ! bLayout )
1200 DecorationView aDecoView( pDev );
1201 aDecoView.DrawSymbol( aInRect, SYMBOL_SPIN_DOWN, aColor, nStyle );
1204 else
1206 Rectangle aSymbolRect;
1207 ImplDrawAlignedImage( pDev, aPos, aSize, bLayout, 1, nDrawFlags,
1208 nTextStyle, IsSymbol() ? &aSymbolRect : NULL );
1210 if ( IsSymbol() && ! bLayout )
1212 DecorationView aDecoView( pDev );
1213 aDecoView.DrawSymbol( aSymbolRect, meSymbol, aColor, nStyle );
1216 if ( mnDDStyle == PUSHBUTTON_DROPDOWN_TOOLBOX && !bLayout )
1218 BOOL bBlack = FALSE;
1219 Color aArrowColor( COL_BLACK );
1221 if ( !(nDrawFlags & WINDOW_DRAW_MONO) )
1223 if ( !IsEnabled() )
1224 aArrowColor = rStyleSettings.GetShadowColor();
1225 else
1227 aArrowColor = Color( COL_LIGHTGREEN );
1228 bBlack = TRUE;
1232 ImplDrawBtnDropDownArrow( pDev, aInRect.Right()-6, aInRect.Top()+1,
1233 aArrowColor, bBlack );
1237 UserDrawEvent aUDEvt( this, aInRect, 0 );
1238 UserDraw( aUDEvt );
1240 pDev->Pop(); // restore clipregion
1243 // -----------------------------------------------------------------------
1245 void PushButton::UserDraw( const UserDrawEvent& )
1249 // -----------------------------------------------------------------------
1251 void PushButton::ImplDrawPushButton( bool bLayout )
1253 if( !bLayout )
1254 HideFocus();
1256 USHORT nButtonStyle = ImplGetButtonState();
1257 Point aPoint;
1258 Size aOutSz( GetOutputSizePixel() );
1259 Rectangle aRect( aPoint, aOutSz );
1260 Rectangle aInRect = aRect;
1261 Rectangle aTextRect;
1262 BOOL bNativeOK = FALSE;
1264 // adjust style if button should be rendered 'pressed'
1265 if ( mbPressed )
1266 nButtonStyle |= BUTTON_DRAW_PRESSED;
1268 // TODO: move this to Window class or make it a member !!!
1269 ControlType aCtrlType = 0;
1270 switch( GetParent()->GetType() )
1272 case WINDOW_LISTBOX:
1273 case WINDOW_MULTILISTBOX:
1274 case WINDOW_TREELISTBOX:
1275 aCtrlType = CTRL_LISTBOX;
1276 break;
1278 case WINDOW_COMBOBOX:
1279 case WINDOW_PATTERNBOX:
1280 case WINDOW_NUMERICBOX:
1281 case WINDOW_METRICBOX:
1282 case WINDOW_CURRENCYBOX:
1283 case WINDOW_DATEBOX:
1284 case WINDOW_TIMEBOX:
1285 case WINDOW_LONGCURRENCYBOX:
1286 aCtrlType = CTRL_COMBOBOX;
1287 break;
1288 default:
1289 break;
1292 BOOL bDropDown = ( IsSymbol() && (GetSymbol()==SYMBOL_SPIN_DOWN) && !GetText().Len() );
1294 if( bDropDown && (aCtrlType == CTRL_COMBOBOX || aCtrlType == CTRL_LISTBOX ) )
1296 if( GetParent()->IsNativeControlSupported( aCtrlType, PART_ENTIRE_CONTROL) )
1298 // skip painting if the button was already drawn by the theme
1299 if( aCtrlType == CTRL_COMBOBOX )
1301 Edit* pEdit = static_cast<Edit*>(GetParent());
1302 if( pEdit->ImplUseNativeBorder( pEdit->GetStyle() ) )
1303 bNativeOK = TRUE;
1305 else if( GetParent()->IsNativeControlSupported( aCtrlType, HAS_BACKGROUND_TEXTURE) )
1307 bNativeOK = TRUE;
1309 if( !bNativeOK && GetParent()->IsNativeControlSupported( aCtrlType, PART_BUTTON_DOWN ) )
1311 // let the theme draw it, note we then need support
1312 // for CTRL_LISTBOX/PART_BUTTON_DOWN and CTRL_COMBOBOX/PART_BUTTON_DOWN
1314 ImplControlValue aControlValue;
1315 Region aCtrlRegion( aInRect );
1316 ControlState nState = 0;
1318 if ( mbPressed ) nState |= CTRL_STATE_PRESSED;
1319 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) nState |= CTRL_STATE_PRESSED;
1320 if ( HasFocus() ) nState |= CTRL_STATE_FOCUSED;
1321 if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT ) nState |= CTRL_STATE_DEFAULT;
1322 if ( Window::IsEnabled() ) nState |= CTRL_STATE_ENABLED;
1324 if ( IsMouseOver() && aInRect.IsInside( GetPointerPosPixel() ) )
1325 nState |= CTRL_STATE_ROLLOVER;
1327 bNativeOK = DrawNativeControl( aCtrlType, PART_BUTTON_DOWN, aCtrlRegion, nState,
1328 aControlValue, rtl::OUString() );
1333 if( bNativeOK )
1334 return;
1336 if ( (bNativeOK=IsNativeControlSupported(CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL)) == TRUE )
1338 PushButtonValue aPBVal;
1339 ImplControlValue aControlValue;
1340 aControlValue.setOptionalVal( &aPBVal );
1341 Region aCtrlRegion( aInRect );
1342 ControlState nState = 0;
1344 if ( mbPressed || IsChecked() ) nState |= CTRL_STATE_PRESSED;
1345 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) nState |= CTRL_STATE_PRESSED;
1346 if ( HasFocus() ) nState |= CTRL_STATE_FOCUSED;
1347 if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT ) nState |= CTRL_STATE_DEFAULT;
1348 if ( Window::IsEnabled() ) nState |= CTRL_STATE_ENABLED;
1350 if ( IsMouseOver() && aInRect.IsInside( GetPointerPosPixel() ) )
1351 nState |= CTRL_STATE_ROLLOVER;
1353 if( GetStyle() & WB_BEVELBUTTON )
1354 aPBVal.mbBevelButton = true;
1356 // draw frame into invisible window to have aInRect modified correctly
1357 // but do not shift the inner rect for pressed buttons (ie remove BUTTON_DRAW_PRESSED)
1358 // this assumes the theme has enough visual cues to signalize the button was pressed
1359 //Window aWin( this );
1360 //ImplDrawPushButtonFrame( &aWin, aInRect, nButtonStyle & ~BUTTON_DRAW_PRESSED );
1362 // looks better this way as symbols were displaced slightly using the above approach
1363 aInRect.Top()+=4;
1364 aInRect.Bottom()-=4;
1365 aInRect.Left()+=4;
1366 aInRect.Right()-=4;
1368 // prepare single line hint (needed on mac to decide between normal push button and
1369 // rectangular bevel button look)
1370 Size aFontSize( Application::GetSettings().GetStyleSettings().GetPushButtonFont().GetSize() );
1371 aFontSize = LogicToPixel( aFontSize, MapMode( MAP_POINT ) );
1372 Size aInRectSize( LogicToPixel( Size( aInRect.GetWidth(), aInRect.GetHeight() ) ) );
1373 aPBVal.mbSingleLine = (aInRectSize.Height() < 2 * aFontSize.Height() );
1375 bNativeOK = DrawNativeControl( CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion, nState,
1376 aControlValue, rtl::OUString()/*PushButton::GetText()*/ );
1378 // draw content using the same aInRect as non-native VCL would do
1379 ImplDrawPushButtonContent( this,
1380 (nState&CTRL_STATE_ROLLOVER) ? WINDOW_DRAW_ROLLOVER : 0,
1381 aInRect, bLayout );
1383 if ( HasFocus() )
1384 ShowFocus( ImplGetFocusRect() );
1387 if ( bNativeOK == FALSE )
1389 // draw PushButtonFrame, aInRect has content size afterwards
1390 if( ! bLayout )
1391 ImplDrawPushButtonFrame( this, aInRect, nButtonStyle );
1393 // draw content
1394 ImplDrawPushButtonContent( this, 0, aInRect, bLayout );
1396 if( ! bLayout && HasFocus() )
1398 ShowFocus( ImplGetFocusRect() );
1403 // -----------------------------------------------------------------------
1405 void PushButton::ImplSetDefButton( BOOL bSet )
1407 Size aSize( GetSizePixel() );
1408 Point aPos( GetPosPixel() );
1409 int dLeft(0), dRight(0), dTop(0), dBottom(0);
1410 BOOL bSetPos = FALSE;
1412 if ( (IsNativeControlSupported(CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL)) == TRUE )
1414 Region aBoundingRgn, aContentRgn;
1415 Rectangle aCtrlRect( 0, 0, 80, 20 ); // use a constant size to avoid accumulating
1416 // will not work if the theme has dynamic adornment sizes
1417 ImplControlValue aControlValue;
1418 Region aCtrlRegion( aCtrlRect );
1419 ControlState nState = CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED;
1421 // get native size of a 'default' button
1422 // and adjust the VCL button if more space for adornment is required
1423 if( GetNativeControlRegion( CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion,
1424 nState, aControlValue, rtl::OUString(),
1425 aBoundingRgn, aContentRgn ) )
1427 Rectangle aCont(aContentRgn.GetBoundRect());
1428 Rectangle aBound(aBoundingRgn.GetBoundRect());
1430 dLeft = aCont.Left() - aBound.Left();
1431 dTop = aCont.Top() - aBound.Top();
1432 dRight = aBound.Right() - aCont.Right();
1433 dBottom = aBound.Bottom() - aCont.Bottom();
1434 bSetPos = dLeft || dTop || dRight || dBottom;
1438 if ( bSet )
1440 if( !(ImplGetButtonState() & BUTTON_DRAW_DEFAULT) && bSetPos )
1442 // adjust pos/size when toggling from non-default to default
1443 aPos.Move(-dLeft, -dTop);
1444 aSize.Width() += dLeft + dRight;
1445 aSize.Height() += dTop + dBottom;
1447 ImplGetButtonState() |= BUTTON_DRAW_DEFAULT;
1449 else
1451 if( (ImplGetButtonState() & BUTTON_DRAW_DEFAULT) && bSetPos )
1453 // adjust pos/size when toggling from default to non-default
1454 aPos.Move(dLeft, dTop);
1455 aSize.Width() -= dLeft + dRight;
1456 aSize.Height() -= dTop + dBottom;
1458 ImplGetButtonState() &= ~BUTTON_DRAW_DEFAULT;
1460 if( bSetPos )
1461 SetPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height(), WINDOW_POSSIZE_ALL );
1463 Invalidate();
1466 // -----------------------------------------------------------------------
1468 BOOL PushButton::ImplIsDefButton() const
1470 return (ImplGetButtonState() & BUTTON_DRAW_DEFAULT) != 0;
1473 // -----------------------------------------------------------------------
1475 PushButton::PushButton( WindowType nType ) :
1476 Button( nType )
1478 ImplInitPushButtonData();
1481 // -----------------------------------------------------------------------
1483 PushButton::PushButton( Window* pParent, WinBits nStyle ) :
1484 Button( WINDOW_PUSHBUTTON )
1486 ImplInitPushButtonData();
1487 ImplInit( pParent, nStyle );
1490 // -----------------------------------------------------------------------
1492 PushButton::PushButton( Window* pParent, const ResId& rResId ) :
1493 Button( WINDOW_PUSHBUTTON )
1495 ImplInitPushButtonData();
1496 rResId.SetRT( RSC_PUSHBUTTON );
1497 WinBits nStyle = ImplInitRes( rResId );
1498 ImplInit( pParent, nStyle );
1499 ImplLoadRes( rResId );
1501 if ( !(nStyle & WB_HIDE) )
1502 Show();
1505 // -----------------------------------------------------------------------
1507 PushButton::~PushButton()
1511 // -----------------------------------------------------------------------
1513 void PushButton::MouseButtonDown( const MouseEvent& rMEvt )
1515 if ( rMEvt.IsLeft() &&
1516 ImplHitTestPushButton( this, rMEvt.GetPosPixel() ) )
1518 USHORT nTrackFlags = 0;
1520 if ( ( GetStyle() & WB_REPEAT ) &&
1521 ! ( GetStyle() & WB_TOGGLE ) )
1522 nTrackFlags |= STARTTRACK_BUTTONREPEAT;
1524 ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
1525 ImplDrawPushButton();
1526 StartTracking( nTrackFlags );
1528 if ( nTrackFlags & STARTTRACK_BUTTONREPEAT )
1529 Click();
1533 // -----------------------------------------------------------------------
1535 void PushButton::Tracking( const TrackingEvent& rTEvt )
1537 if ( rTEvt.IsTrackingEnded() )
1539 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
1541 if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() )
1542 GrabFocus();
1544 if ( GetStyle() & WB_TOGGLE )
1546 // Don't toggle, when aborted
1547 if ( !rTEvt.IsTrackingCanceled() )
1549 if ( IsChecked() )
1551 Check( FALSE );
1552 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
1554 else
1555 Check( TRUE );
1558 else
1559 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
1561 ImplDrawPushButton();
1563 // Bei Abbruch kein Click-Handler rufen
1564 if ( !rTEvt.IsTrackingCanceled() )
1566 if ( ! ( ( GetStyle() & WB_REPEAT ) &&
1567 ! ( GetStyle() & WB_TOGGLE ) ) )
1568 Click();
1572 else
1574 if ( ImplHitTestPushButton( this, rTEvt.GetMouseEvent().GetPosPixel() ) )
1576 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
1578 if ( rTEvt.IsTrackingRepeat() && (GetStyle() & WB_REPEAT) &&
1579 ! ( GetStyle() & WB_TOGGLE ) )
1580 Click();
1582 else
1584 ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
1585 ImplDrawPushButton();
1588 else
1590 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
1592 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
1593 ImplDrawPushButton();
1599 // -----------------------------------------------------------------------
1601 void PushButton::KeyInput( const KeyEvent& rKEvt )
1603 KeyCode aKeyCode = rKEvt.GetKeyCode();
1605 if ( !aKeyCode.GetModifier() &&
1606 ((aKeyCode.GetCode() == KEY_RETURN) || (aKeyCode.GetCode() == KEY_SPACE)) )
1608 if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) )
1610 ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
1611 ImplDrawPushButton();
1614 if ( ( GetStyle() & WB_REPEAT ) &&
1615 ! ( GetStyle() & WB_TOGGLE ) )
1616 Click();
1618 else if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_ESCAPE) )
1620 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
1621 ImplDrawPushButton();
1623 else
1624 Button::KeyInput( rKEvt );
1627 // -----------------------------------------------------------------------
1629 void PushButton::KeyUp( const KeyEvent& rKEvt )
1631 KeyCode aKeyCode = rKEvt.GetKeyCode();
1633 if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) &&
1634 ((aKeyCode.GetCode() == KEY_RETURN) || (aKeyCode.GetCode() == KEY_SPACE)) )
1636 if ( GetStyle() & WB_TOGGLE )
1638 if ( IsChecked() )
1640 Check( FALSE );
1641 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
1643 else
1644 Check( TRUE );
1646 Toggle();
1648 else
1649 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
1651 ImplDrawPushButton();
1653 if ( !( ( GetStyle() & WB_REPEAT ) &&
1654 ! ( GetStyle() & WB_TOGGLE ) ) )
1655 Click();
1657 else
1658 Button::KeyUp( rKEvt );
1661 // -----------------------------------------------------------------------
1663 void PushButton::FillLayoutData() const
1665 mpLayoutData = new vcl::ControlLayoutData();
1666 const_cast<PushButton*>(this)->ImplDrawPushButton( true );
1669 // -----------------------------------------------------------------------
1671 void PushButton::Paint( const Rectangle& )
1673 ImplDrawPushButton();
1676 // -----------------------------------------------------------------------
1678 void PushButton::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
1679 ULONG nFlags )
1681 Point aPos = pDev->LogicToPixel( rPos );
1682 Size aSize = pDev->LogicToPixel( rSize );
1683 Rectangle aRect( aPos, aSize );
1684 Rectangle aTextRect;
1685 Font aFont = GetDrawPixelFont( pDev );
1687 pDev->Push();
1688 pDev->SetMapMode();
1689 pDev->SetFont( aFont );
1690 if ( nFlags & WINDOW_DRAW_MONO )
1692 pDev->SetTextColor( Color( COL_BLACK ) );
1694 else
1696 pDev->SetTextColor( GetTextColor() );
1698 // DecoView uses the FaceColor...
1699 AllSettings aSettings = pDev->GetSettings();
1700 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1701 if ( IsControlBackground() )
1702 aStyleSettings.SetFaceColor( GetControlBackground() );
1703 else
1704 aStyleSettings.SetFaceColor( GetSettings().GetStyleSettings().GetFaceColor() );
1705 aSettings.SetStyleSettings( aStyleSettings );
1706 pDev->SetSettings( aSettings );
1708 pDev->SetTextFillColor();
1710 DecorationView aDecoView( pDev );
1711 USHORT nButtonStyle = 0;
1712 if ( nFlags & WINDOW_DRAW_MONO )
1713 nButtonStyle |= BUTTON_DRAW_MONO;
1714 if ( IsChecked() )
1715 nButtonStyle |= BUTTON_DRAW_CHECKED;
1716 aRect = aDecoView.DrawButton( aRect, nButtonStyle );
1718 ImplDrawPushButtonContent( pDev, nFlags, aRect, false );
1719 pDev->Pop();
1722 // -----------------------------------------------------------------------
1724 void PushButton::Resize()
1726 Control::Resize();
1727 Invalidate();
1730 // -----------------------------------------------------------------------
1732 void PushButton::GetFocus()
1734 ShowFocus( ImplGetFocusRect() );
1735 SetInputContext( InputContext( GetFont() ) );
1736 Button::GetFocus();
1739 // -----------------------------------------------------------------------
1741 void PushButton::LoseFocus()
1743 EndSelection();
1744 HideFocus();
1745 Button::LoseFocus();
1748 // -----------------------------------------------------------------------
1750 void PushButton::StateChanged( StateChangedType nType )
1752 Button::StateChanged( nType );
1754 if ( (nType == STATE_CHANGE_ENABLE) ||
1755 (nType == STATE_CHANGE_TEXT) ||
1756 (nType == STATE_CHANGE_IMAGE) ||
1757 (nType == STATE_CHANGE_DATA) ||
1758 (nType == STATE_CHANGE_STATE) ||
1759 (nType == STATE_CHANGE_UPDATEMODE) )
1761 if ( IsReallyVisible() && IsUpdateMode() )
1762 Invalidate();
1764 else if ( nType == STATE_CHANGE_STYLE )
1766 SetStyle( ImplInitStyle( GetWindow( WINDOW_PREV ), GetStyle() ) );
1768 bool bIsDefButton = ( GetStyle() & WB_DEFBUTTON ) != 0;
1769 bool bWasDefButton = ( GetPrevStyle() & WB_DEFBUTTON ) != 0;
1770 if ( bIsDefButton != bWasDefButton )
1771 ImplSetDefButton( bIsDefButton );
1773 if ( IsReallyVisible() && IsUpdateMode() )
1775 if ( (GetPrevStyle() & PUSHBUTTON_VIEW_STYLE) !=
1776 (GetStyle() & PUSHBUTTON_VIEW_STYLE) )
1777 Invalidate();
1780 else if ( (nType == STATE_CHANGE_ZOOM) ||
1781 (nType == STATE_CHANGE_CONTROLFONT) )
1783 ImplInitSettings( TRUE, FALSE, FALSE );
1784 Invalidate();
1786 else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
1788 ImplInitSettings( FALSE, TRUE, FALSE );
1789 Invalidate();
1791 else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
1793 ImplInitSettings( FALSE, FALSE, TRUE );
1794 Invalidate();
1798 // -----------------------------------------------------------------------
1800 void PushButton::DataChanged( const DataChangedEvent& rDCEvt )
1802 Button::DataChanged( rDCEvt );
1804 if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
1805 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
1806 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
1807 (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
1809 ImplInitSettings( TRUE, TRUE, TRUE );
1810 Invalidate();
1814 // -----------------------------------------------------------------------
1816 long PushButton::PreNotify( NotifyEvent& rNEvt )
1818 long nDone = 0;
1819 const MouseEvent* pMouseEvt = NULL;
1821 if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL )
1823 if( pMouseEvt->IsEnterWindow() || pMouseEvt->IsLeaveWindow() )
1825 // trigger redraw as mouse over state has changed
1827 // TODO: move this to Window class or make it a member !!!
1828 ControlType aCtrlType = 0;
1829 switch( GetParent()->GetType() )
1831 case WINDOW_LISTBOX:
1832 case WINDOW_MULTILISTBOX:
1833 case WINDOW_TREELISTBOX:
1834 aCtrlType = CTRL_LISTBOX;
1835 break;
1837 case WINDOW_COMBOBOX:
1838 case WINDOW_PATTERNBOX:
1839 case WINDOW_NUMERICBOX:
1840 case WINDOW_METRICBOX:
1841 case WINDOW_CURRENCYBOX:
1842 case WINDOW_DATEBOX:
1843 case WINDOW_TIMEBOX:
1844 case WINDOW_LONGCURRENCYBOX:
1845 aCtrlType = CTRL_COMBOBOX;
1846 break;
1847 default:
1848 break;
1851 BOOL bDropDown = ( IsSymbol() && (GetSymbol()==SYMBOL_SPIN_DOWN) && !GetText().Len() );
1853 if( bDropDown && GetParent()->IsNativeControlSupported( aCtrlType, PART_ENTIRE_CONTROL) &&
1854 !GetParent()->IsNativeControlSupported( aCtrlType, PART_BUTTON_DOWN) )
1856 Window *pBorder = GetParent()->GetWindow( WINDOW_BORDER );
1857 if(aCtrlType == CTRL_COMBOBOX)
1859 // only paint the button part to avoid flickering of the combobox text
1860 Point aPt;
1861 Rectangle aClipRect( aPt, GetOutputSizePixel() );
1862 aClipRect.SetPos(pBorder->ScreenToOutputPixel(OutputToScreenPixel(aClipRect.TopLeft())));
1863 pBorder->Invalidate( aClipRect );
1865 else
1867 pBorder->Invalidate( INVALIDATE_NOERASE );
1868 pBorder->Update();
1871 else if( IsNativeControlSupported(CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL) )
1873 Invalidate();
1878 return nDone ? nDone : Button::PreNotify(rNEvt);
1881 // -----------------------------------------------------------------------
1883 void PushButton::Toggle()
1885 ImplCallEventListenersAndHandler( VCLEVENT_PUSHBUTTON_TOGGLE, maToggleHdl, this );
1888 // -----------------------------------------------------------------------
1890 void PushButton::SetSymbol( SymbolType eSymbol )
1892 if ( meSymbol != eSymbol )
1894 meSymbol = eSymbol;
1895 StateChanged( STATE_CHANGE_DATA );
1899 // -----------------------------------------------------------------------
1900 void PushButton::SetSymbolAlign( SymbolAlign eAlign )
1902 ImplSetSymbolAlign( eAlign );
1905 // -----------------------------------------------------------------------
1906 SymbolAlign PushButton::GetSymbolAlign() const
1908 return ImplGetSymbolAlign();
1911 // -----------------------------------------------------------------------
1913 void PushButton::SetDropDown( USHORT nStyle )
1915 if ( mnDDStyle != nStyle )
1917 mnDDStyle = nStyle;
1918 StateChanged( STATE_CHANGE_DATA );
1922 // -----------------------------------------------------------------------
1924 void PushButton::SetState( TriState eState )
1926 if ( meState != eState )
1928 meState = eState;
1929 if ( meState == STATE_NOCHECK )
1930 ImplGetButtonState() &= ~(BUTTON_DRAW_CHECKED | BUTTON_DRAW_DONTKNOW);
1931 else if ( meState == STATE_CHECK )
1933 ImplGetButtonState() &= ~BUTTON_DRAW_DONTKNOW;
1934 ImplGetButtonState() |= BUTTON_DRAW_CHECKED;
1936 else // STATE_DONTKNOW
1938 ImplGetButtonState() &= ~BUTTON_DRAW_CHECKED;
1939 ImplGetButtonState() |= BUTTON_DRAW_DONTKNOW;
1942 StateChanged( STATE_CHANGE_STATE );
1943 Toggle();
1947 // -----------------------------------------------------------------------
1949 void PushButton::SetPressed( BOOL bPressed )
1951 if ( mbPressed != bPressed )
1953 mbPressed = bPressed;
1954 StateChanged( STATE_CHANGE_DATA );
1958 // -----------------------------------------------------------------------
1960 void PushButton::EndSelection()
1962 EndTracking( ENDTRACK_CANCEL );
1963 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
1965 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
1966 if ( !mbPressed )
1967 ImplDrawPushButton();
1971 // -----------------------------------------------------------------------
1973 Size PushButton::CalcMinimumSize( long nMaxWidth ) const
1975 Size aSize;
1977 if ( IsSymbol() )
1979 if ( IsSmallSymbol ())
1980 aSize = Size( 16, 12 );
1981 else
1982 aSize = Size( 26, 24 );
1984 else if ( IsImage() && ! (ImplGetButtonState() & BUTTON_DRAW_NOIMAGE) )
1985 aSize = GetModeImage().GetSizePixel();
1986 if ( PushButton::GetText().Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
1988 ULONG nDrawFlags = 0;
1989 Size textSize = GetTextRect( Rectangle( Point(), Size( nMaxWidth ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ),
1990 PushButton::GetText(), ImplGetTextStyle( nDrawFlags ) ).GetSize();
1991 aSize.Width() += int( textSize.Width () * 1.15 );
1992 aSize.Height() = std::max( aSize.Height(), long( textSize.Height() * 1.15 ) );
1995 // cf. ImplDrawPushButton ...
1996 aSize.Width() += 8;
1997 aSize.Height() += 8;
1999 return CalcWindowSize( aSize );
2002 Size PushButton::GetOptimalSize(WindowSizeType eType) const
2004 switch (eType) {
2005 case WINDOWSIZE_MINIMUM: {
2006 return CalcMinimumSize();
2008 default:
2009 return Button::GetOptimalSize( eType );
2013 // =======================================================================
2015 void OKButton::ImplInit( Window* pParent, WinBits nStyle )
2017 PushButton::ImplInit( pParent, nStyle );
2019 SetText( Button::GetStandardText( BUTTON_OK ) );
2020 SetHelpText( Button::GetStandardHelpText( BUTTON_OK ) );
2023 // -----------------------------------------------------------------------
2025 OKButton::OKButton( Window* pParent, WinBits nStyle ) :
2026 PushButton( WINDOW_OKBUTTON )
2028 ImplInit( pParent, nStyle );
2031 // -----------------------------------------------------------------------
2033 OKButton::OKButton( Window* pParent, const ResId& rResId ) :
2034 PushButton( WINDOW_OKBUTTON )
2036 rResId.SetRT( RSC_OKBUTTON );
2037 WinBits nStyle = ImplInitRes( rResId );
2038 ImplInit( pParent, nStyle );
2039 ImplLoadRes( rResId );
2041 if ( !(nStyle & WB_HIDE) )
2042 Show();
2045 // -----------------------------------------------------------------------
2047 void OKButton::Click()
2049 // Ist kein Link gesetzt, dann schliesse Parent
2050 if ( !GetClickHdl() )
2052 Window* pParent = GetParent();
2053 if ( pParent->IsSystemWindow() )
2055 if ( pParent->IsDialog() )
2057 if ( ((Dialog*)pParent)->IsInExecute() )
2058 ((Dialog*)pParent)->EndDialog( TRUE );
2059 // gegen rekursive Aufrufe schuetzen
2060 else if ( !((Dialog*)pParent)->IsInClose() )
2062 if ( pParent->GetStyle() & WB_CLOSEABLE )
2063 ((Dialog*)pParent)->Close();
2066 else
2068 if ( pParent->GetStyle() & WB_CLOSEABLE )
2069 ((SystemWindow*)pParent)->Close();
2073 else
2075 PushButton::Click();
2079 // =======================================================================
2081 void CancelButton::ImplInit( Window* pParent, WinBits nStyle )
2083 PushButton::ImplInit( pParent, nStyle );
2085 SetText( Button::GetStandardText( BUTTON_CANCEL ) );
2086 SetHelpText( Button::GetStandardHelpText( BUTTON_CANCEL ) );
2089 // -----------------------------------------------------------------------
2091 CancelButton::CancelButton( Window* pParent, WinBits nStyle ) :
2092 PushButton( WINDOW_CANCELBUTTON )
2094 ImplInit( pParent, nStyle );
2097 // -----------------------------------------------------------------------
2099 CancelButton::CancelButton( Window* pParent, const ResId& rResId ) :
2100 PushButton( WINDOW_CANCELBUTTON )
2102 rResId.SetRT( RSC_CANCELBUTTON );
2103 WinBits nStyle = ImplInitRes( rResId );
2104 ImplInit( pParent, nStyle );
2105 ImplLoadRes( rResId );
2107 if ( !(nStyle & WB_HIDE) )
2108 Show();
2111 // -----------------------------------------------------------------------
2113 void CancelButton::Click()
2115 // Ist kein Link gesetzt, dann schliesse Parent
2116 if ( !GetClickHdl() )
2118 Window* pParent = GetParent();
2119 if ( pParent->IsSystemWindow() )
2121 if ( pParent->IsDialog() )
2123 if ( ((Dialog*)pParent)->IsInExecute() )
2124 ((Dialog*)pParent)->EndDialog( FALSE );
2125 // gegen rekursive Aufrufe schuetzen
2126 else if ( !((Dialog*)pParent)->IsInClose() )
2128 if ( pParent->GetStyle() & WB_CLOSEABLE )
2129 ((Dialog*)pParent)->Close();
2132 else
2134 if ( pParent->GetStyle() & WB_CLOSEABLE )
2135 ((SystemWindow*)pParent)->Close();
2139 else
2141 PushButton::Click();
2145 // =======================================================================
2147 void HelpButton::ImplInit( Window* pParent, WinBits nStyle )
2149 PushButton::ImplInit( pParent, nStyle | WB_NOPOINTERFOCUS );
2151 SetText( Button::GetStandardText( BUTTON_HELP ) );
2152 SetHelpText( Button::GetStandardHelpText( BUTTON_HELP ) );
2155 // -----------------------------------------------------------------------
2157 HelpButton::HelpButton( Window* pParent, WinBits nStyle ) :
2158 PushButton( WINDOW_HELPBUTTON )
2160 ImplInit( pParent, nStyle );
2163 // -----------------------------------------------------------------------
2165 HelpButton::HelpButton( Window* pParent, const ResId& rResId ) :
2166 PushButton( WINDOW_HELPBUTTON )
2168 rResId.SetRT( RSC_HELPBUTTON );
2169 WinBits nStyle = ImplInitRes( rResId );
2170 ImplInit( pParent, nStyle );
2171 ImplLoadRes( rResId );
2173 if ( !(nStyle & WB_HIDE) )
2174 Show();
2177 // -----------------------------------------------------------------------
2179 void HelpButton::Click()
2181 // Ist kein Link gesetzt, loese Hilfe aus
2182 if ( !GetClickHdl() )
2184 Window* pFocusWin = Application::GetFocusWindow();
2185 if ( !pFocusWin )
2186 pFocusWin = this;
2188 HelpEvent aEvt( pFocusWin->GetPointerPosPixel(), HELPMODE_CONTEXT );
2189 pFocusWin->RequestHelp( aEvt );
2191 PushButton::Click();
2194 // =======================================================================
2196 void RadioButton::ImplInitRadioButtonData()
2198 mbChecked = FALSE;
2199 mbSaveValue = FALSE;
2200 mbRadioCheck = TRUE;
2201 mbStateChanged = FALSE;
2204 // -----------------------------------------------------------------------
2206 void RadioButton::ImplInit( Window* pParent, WinBits nStyle )
2208 nStyle = ImplInitStyle( pParent->GetWindow( WINDOW_LASTCHILD ), nStyle );
2209 Button::ImplInit( pParent, nStyle, NULL );
2211 ImplInitSettings( TRUE, TRUE, TRUE );
2214 // -----------------------------------------------------------------------
2216 WinBits RadioButton::ImplInitStyle( const Window* pPrevWindow, WinBits nStyle )
2218 if ( !(nStyle & WB_NOGROUP) &&
2219 (!pPrevWindow || (pPrevWindow->GetType() != WINDOW_RADIOBUTTON)) )
2220 nStyle |= WB_GROUP;
2221 if ( !(nStyle & WB_NOTABSTOP) )
2223 if ( IsChecked() )
2224 nStyle |= WB_TABSTOP;
2225 else
2226 nStyle &= ~WB_TABSTOP;
2228 return nStyle;
2231 // -----------------------------------------------------------------------
2233 void RadioButton::ImplInitSettings( BOOL bFont,
2234 BOOL bForeground, BOOL bBackground )
2236 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
2238 if ( bFont )
2240 Font aFont = rStyleSettings.GetRadioCheckFont();
2241 if ( IsControlFont() )
2242 aFont.Merge( GetControlFont() );
2243 SetZoomedPointFont( aFont );
2246 if ( bForeground || bFont )
2248 Color aColor;
2249 if ( IsControlForeground() )
2250 aColor = GetControlForeground();
2251 else
2252 aColor = rStyleSettings.GetRadioCheckTextColor();
2253 SetTextColor( aColor );
2254 SetTextFillColor();
2257 if ( bBackground )
2259 Window* pParent = GetParent();
2260 if ( !IsControlBackground() &&
2261 (pParent->IsChildTransparentModeEnabled() || IsNativeControlSupported( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL ) ) )
2263 EnableChildTransparentMode( TRUE );
2264 SetParentClipMode( PARENTCLIPMODE_NOCLIP );
2265 SetPaintTransparent( TRUE );
2266 SetBackground();
2267 if( IsNativeControlSupported( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL ) )
2268 mpWindowImpl->mbUseNativeFocus = ImplGetSVData()->maNWFData.mbNoFocusRects;
2270 else
2272 EnableChildTransparentMode( FALSE );
2273 SetParentClipMode( 0 );
2274 SetPaintTransparent( FALSE );
2276 if ( IsControlBackground() )
2277 SetBackground( GetControlBackground() );
2278 else
2279 SetBackground( pParent->GetBackground() );
2284 //---------------------------------------------------------------------
2285 //--- 12.03.2003 18:46:14 ---------------------------------------------
2287 void RadioButton::DrawRadioButtonState( )
2289 ImplDrawRadioButtonState( );
2292 // -----------------------------------------------------------------------
2294 void RadioButton::ImplInvalidateOrDrawRadioButtonState()
2296 if( ImplGetSVData()->maNWFData.mbCheckBoxNeedsErase )
2298 if ( IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL) )
2300 Invalidate();
2301 Update();
2302 return;
2305 ImplDrawRadioButtonState();
2308 void RadioButton::ImplDrawRadioButtonState()
2310 USHORT nButtonStyle = 0;
2311 BOOL bNativeOK = FALSE;
2313 // no native drawing for image radio buttons
2314 if ( !maImage && (bNativeOK=IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL)) == TRUE )
2316 ImplControlValue aControlValue( mbChecked ? BUTTONVALUE_ON : BUTTONVALUE_OFF, rtl::OUString(), 0 );
2317 Rectangle aCtrlRect( maStateRect.TopLeft(), maStateRect.GetSize() );
2318 Region aCtrlRegion( aCtrlRect );
2319 ControlState nState = 0;
2321 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) nState |= CTRL_STATE_PRESSED;
2322 if ( HasFocus() ) nState |= CTRL_STATE_FOCUSED;
2323 if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT ) nState |= CTRL_STATE_DEFAULT;
2324 if ( IsEnabled() ) nState |= CTRL_STATE_ENABLED;
2326 if ( IsMouseOver() && maMouseRect.IsInside( GetPointerPosPixel() ) )
2327 nState |= CTRL_STATE_ROLLOVER;
2329 bNativeOK = DrawNativeControl( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion, nState,
2330 aControlValue,rtl::OUString() );
2334 if ( bNativeOK == FALSE )
2336 // kein Image-RadioButton
2337 if ( !maImage )
2339 USHORT nStyle = ImplGetButtonState();
2340 if ( !IsEnabled() )
2341 nStyle |= BUTTON_DRAW_DISABLED;
2342 if ( mbChecked )
2343 nStyle |= BUTTON_DRAW_CHECKED;
2344 Image aImage = GetRadioImage( GetSettings(), nStyle );
2345 if ( IsZoom() )
2346 DrawImage( maStateRect.TopLeft(), maStateRect.GetSize(), aImage );
2347 else
2348 DrawImage( maStateRect.TopLeft(), aImage );
2350 else
2352 HideFocus();
2354 DecorationView aDecoView( this );
2355 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
2356 Rectangle aImageRect = maStateRect;
2357 Size aImageSize = maImage.GetSizePixel();
2358 BOOL bEnabled = IsEnabled();
2360 aImageSize.Width() = CalcZoom( aImageSize.Width() );
2361 aImageSize.Height() = CalcZoom( aImageSize.Height() );
2363 // Border und Selektionsstatus ausgeben
2364 nButtonStyle = FRAME_DRAW_DOUBLEIN;
2365 aImageRect = aDecoView.DrawFrame( aImageRect, nButtonStyle );
2366 if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) || !bEnabled )
2367 SetFillColor( rStyleSettings.GetFaceColor() );
2368 else
2369 SetFillColor( rStyleSettings.GetFieldColor() );
2370 SetLineColor();
2371 DrawRect( aImageRect );
2373 // Image ausgeben
2374 nButtonStyle = 0;
2375 if ( !bEnabled )
2376 nButtonStyle |= IMAGE_DRAW_DISABLE;
2378 // check for HC mode
2379 Image *pImage = &maImage;
2380 Color aBackCol;
2381 if( !!maImageHC && ImplGetCurrentBackgroundColor( aBackCol ) )
2383 if( aBackCol.IsDark() )
2384 pImage = &maImageHC;
2385 // #99902 no col transform required
2386 //if( aBackCol.IsBright() )
2387 // nStyle |= IMAGE_DRAW_COLORTRANSFORM;
2390 Point aImagePos( aImageRect.TopLeft() );
2391 aImagePos.X() += (aImageRect.GetWidth()-aImageSize.Width())/2;
2392 aImagePos.Y() += (aImageRect.GetHeight()-aImageSize.Height())/2;
2393 if ( IsZoom() )
2394 DrawImage( aImagePos, aImageSize, *pImage, nButtonStyle );
2395 else
2396 DrawImage( aImagePos, *pImage, nButtonStyle );
2398 aImageRect.Left()++;
2399 aImageRect.Top()++;
2400 aImageRect.Right()--;
2401 aImageRect.Bottom()--;
2403 ImplSetFocusRect( aImageRect );
2405 if ( mbChecked )
2407 SetLineColor( rStyleSettings.GetHighlightColor() );
2408 SetFillColor();
2409 if ( (aImageSize.Width() >= 20) || (aImageSize.Height() >= 20) )
2411 aImageRect.Left()++;
2412 aImageRect.Top()++;
2413 aImageRect.Right()--;
2414 aImageRect.Bottom()--;
2416 DrawRect( aImageRect );
2417 aImageRect.Left()++;
2418 aImageRect.Top()++;
2419 aImageRect.Right()--;
2420 aImageRect.Bottom()--;
2421 DrawRect( aImageRect );
2424 if ( HasFocus() )
2425 ShowFocus( ImplGetFocusRect() );
2430 // -----------------------------------------------------------------------
2432 void RadioButton::ImplDraw( OutputDevice* pDev, ULONG nDrawFlags,
2433 const Point& rPos, const Size& rSize,
2434 const Size& rImageSize, long nImageSep,
2435 Rectangle& rStateRect,
2436 Rectangle& rMouseRect,
2437 bool bLayout )
2439 WinBits nWinStyle = GetStyle();
2440 XubString aText( GetText() );
2441 Rectangle aRect( rPos, rSize );
2442 MetricVector* pVector = bLayout ? &mpLayoutData->m_aUnicodeBoundRects : NULL;
2443 String* pDisplayText = bLayout ? &mpLayoutData->m_aDisplayText : NULL;
2445 pDev->Push( PUSH_CLIPREGION );
2446 pDev->IntersectClipRegion( Rectangle( rPos, rSize ) );
2448 // kein Image-RadioButton
2449 if ( !maImage )
2451 if ( ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) ) ||
2452 ( HasImage() && ! (ImplGetButtonState() & BUTTON_DRAW_NOIMAGE) ) )
2454 USHORT nTextStyle = Button::ImplGetTextStyle( aText, nWinStyle, nDrawFlags );
2456 Size aSize( rSize );
2457 Point aPos( rPos );
2459 aPos.X() += rImageSize.Width() + nImageSep;
2460 aSize.Width() -= rImageSize.Width() + nImageSep;
2462 // if the text rect height is smaller than the height of the image
2463 // then for single lines the default should be centered text
2464 if( (nWinStyle & (WB_TOP|WB_VCENTER|WB_BOTTOM)) == 0 &&
2465 (rImageSize.Height() > rSize.Height() || ! (nWinStyle & WB_WORDBREAK) ) )
2467 nTextStyle &= ~(TEXT_DRAW_TOP|TEXT_DRAW_BOTTOM);
2468 nTextStyle |= TEXT_DRAW_VCENTER;
2469 aSize.Height() = rImageSize.Height();
2472 ImplDrawAlignedImage( pDev, aPos, aSize, bLayout, 1,
2473 nDrawFlags, nTextStyle, NULL );
2475 rMouseRect = Rectangle( aPos, aSize );
2476 rMouseRect.Left() = rPos.X();
2478 rStateRect.Left() = rPos.X();
2479 rStateRect.Top() = rMouseRect.Top();
2481 if ( aSize.Height() > rImageSize.Height() )
2482 rStateRect.Top() += ( aSize.Height() - rImageSize.Height() ) / 2;
2483 else
2485 rStateRect.Top() -= ( rImageSize.Height() - aSize.Height() ) / 2;
2486 if( rStateRect.Top() < 0 )
2487 rStateRect.Top() = 0;
2490 rStateRect.Right() = rStateRect.Left() + rImageSize.Width()-1;
2491 rStateRect.Bottom() = rStateRect.Top() + rImageSize.Height()-1;
2493 if ( rStateRect.Bottom() > rMouseRect.Bottom() )
2494 rMouseRect.Bottom() = rStateRect.Bottom();
2496 else
2498 if ( nWinStyle & WB_CENTER )
2499 rStateRect.Left() = rPos.X()+((rSize.Width()-rImageSize.Width())/2);
2500 else if ( nWinStyle & WB_RIGHT )
2501 rStateRect.Left() = rPos.X()+rSize.Width()-rImageSize.Width(); //-1;
2502 else
2503 rStateRect.Left() = rPos.X(); //+1;
2504 if ( nWinStyle & WB_VCENTER )
2505 rStateRect.Top() = rPos.Y()+((rSize.Height()-rImageSize.Height())/2);
2506 else if ( nWinStyle & WB_BOTTOM )
2507 rStateRect.Top() = rPos.Y()+rSize.Height()-rImageSize.Height(); //-1;
2508 else
2509 rStateRect.Top() = rPos.Y(); //+1;
2510 rStateRect.Right() = rStateRect.Left()+rImageSize.Width()-1;
2511 rStateRect.Bottom() = rStateRect.Top()+rImageSize.Height()-1;
2512 rMouseRect = rStateRect;
2514 ImplSetFocusRect( rStateRect );
2516 /* und oben -1, da CalcSize() auch Focus-Rechteck nicht mit einrechnet,
2517 da im Writer ansonsten die Images noch weiter oben haengen
2518 rFocusRect = rStateRect;
2519 rFocusRect.Left()--;
2520 rFocusRect.Top()--;
2521 rFocusRect.Right()++;
2522 rFocusRect.Bottom()++;
2526 else
2528 BOOL bTopImage = (nWinStyle & WB_TOP) != 0;
2529 Size aImageSize = maImage.GetSizePixel();
2530 Rectangle aImageRect( rPos, rSize );
2531 long nTextHeight = pDev->GetTextHeight();
2532 long nTextWidth = pDev->GetCtrlTextWidth( aText );
2534 // Positionen und Groessen berechnen
2535 if ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
2537 Size aTmpSize( (aImageSize.Width()+8), (aImageSize.Height()+8) );
2538 if ( bTopImage )
2540 aImageRect.Left() = (rSize.Width()-aTmpSize.Width())/2;
2541 aImageRect.Top() = (rSize.Height()-(aTmpSize.Height()+nTextHeight+6))/2;
2543 else
2544 aImageRect.Top() = (rSize.Height()-aTmpSize.Height())/2;
2546 aImageRect.Right() = aImageRect.Left()+aTmpSize.Width();
2547 aImageRect.Bottom() = aImageRect.Top()+aTmpSize.Height();
2549 // Text ausgeben
2550 Point aTxtPos = rPos;
2551 if ( bTopImage )
2553 aTxtPos.X() += (rSize.Width()-nTextWidth)/2;
2554 aTxtPos.Y() += aImageRect.Bottom()+6;
2556 else
2558 aTxtPos.X() += aImageRect.Right()+8;
2559 aTxtPos.Y() += (rSize.Height()-nTextHeight)/2;
2561 pDev->DrawCtrlText( aTxtPos, aText, 0, STRING_LEN, TEXT_DRAW_MNEMONIC, pVector, pDisplayText );
2564 rMouseRect = aImageRect;
2565 rStateRect = aImageRect;
2568 pDev->Pop();
2571 // -----------------------------------------------------------------------
2573 void RadioButton::ImplDrawRadioButton( bool bLayout )
2575 if( !bLayout )
2576 HideFocus();
2578 Size aImageSize;
2579 if ( !maImage )
2580 aImageSize = ImplGetRadioImageSize();
2581 else
2582 aImageSize = maImage.GetSizePixel();
2583 aImageSize.Width() = CalcZoom( aImageSize.Width() );
2584 aImageSize.Height() = CalcZoom( aImageSize.Height() );
2586 // Draw control text
2587 ImplDraw( this, 0, Point(), GetOutputSizePixel(),
2588 aImageSize, IMPL_SEP_BUTTON_IMAGE, maStateRect, maMouseRect, bLayout );
2590 if( !bLayout || (IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL)==TRUE) )
2592 if ( !maImage && HasFocus() )
2593 ShowFocus( ImplGetFocusRect() );
2595 ImplDrawRadioButtonState();
2599 // -----------------------------------------------------------------------
2601 void RadioButton::GetRadioButtonGroup( std::vector< RadioButton* >& io_rGroup, bool bIncludeThis ) const
2603 // empty the list
2604 io_rGroup.clear();
2606 // go back to first in group;
2607 Window* pFirst = const_cast<RadioButton*>(this);
2608 while( ( pFirst->GetStyle() & WB_GROUP ) == 0 )
2610 Window* pWindow = pFirst->GetWindow( WINDOW_PREV );
2611 if( pWindow )
2612 pFirst = pWindow;
2613 else
2614 break;
2616 // insert radiobuttons up to next group
2619 if( pFirst->GetType() == WINDOW_RADIOBUTTON )
2621 if( pFirst != this || bIncludeThis )
2622 io_rGroup.push_back( static_cast<RadioButton*>(pFirst) );
2624 pFirst = pFirst->GetWindow( WINDOW_NEXT );
2625 } while( pFirst && ( ( pFirst->GetStyle() & WB_GROUP ) == 0 ) );
2628 // -----------------------------------------------------------------------
2630 void RadioButton::ImplUncheckAllOther()
2632 mpWindowImpl->mnStyle |= WB_TABSTOP;
2634 // Gruppe mit RadioButtons durchgehen und die gecheckten Buttons
2635 Window* pWindow;
2636 WinBits nStyle;
2637 if ( !(GetStyle() & WB_GROUP) )
2639 pWindow = GetWindow( WINDOW_PREV );
2640 while ( pWindow )
2642 nStyle = pWindow->GetStyle();
2644 if ( pWindow->GetType() == WINDOW_RADIOBUTTON )
2646 if ( ((RadioButton*)pWindow)->IsChecked() )
2648 ImplDelData aDelData;
2649 pWindow->ImplAddDel( &aDelData );
2650 ((RadioButton*)pWindow)->SetState( FALSE );
2651 if ( aDelData.IsDelete() )
2652 return;
2653 pWindow->ImplRemoveDel( &aDelData );
2655 // Um falsch gesetzt WB_TABSTOPS immer zu entfernen, nicht
2656 // innerhalb der if-Abfrage
2657 pWindow->mpWindowImpl->mnStyle &= ~WB_TABSTOP;
2660 if ( nStyle & WB_GROUP )
2661 break;
2663 pWindow = pWindow->GetWindow( WINDOW_PREV );
2667 pWindow = GetWindow( WINDOW_NEXT );
2668 while ( pWindow )
2670 nStyle = pWindow->GetStyle();
2672 if ( nStyle & WB_GROUP )
2673 break;
2675 if ( pWindow->GetType() == WINDOW_RADIOBUTTON )
2677 if ( ((RadioButton*)pWindow)->IsChecked() )
2679 ImplDelData aDelData;
2680 pWindow->ImplAddDel( &aDelData );
2681 ((RadioButton*)pWindow)->SetState( FALSE );
2682 if ( aDelData.IsDelete() )
2683 return;
2684 pWindow->ImplRemoveDel( &aDelData );
2686 // Um falsch gesetzt WB_TABSTOPS immer zu entfernen, nicht
2687 // innerhalb der if-Abfrage
2688 pWindow->mpWindowImpl->mnStyle &= ~WB_TABSTOP;
2691 pWindow = pWindow->GetWindow( WINDOW_NEXT );
2695 // -----------------------------------------------------------------------
2697 void RadioButton::ImplCallClick( BOOL bGrabFocus, USHORT nFocusFlags )
2699 mbStateChanged = !mbChecked;
2700 mbChecked = TRUE;
2701 mpWindowImpl->mnStyle |= WB_TABSTOP;
2702 ImplInvalidateOrDrawRadioButtonState();
2703 ImplDelData aDelData;
2704 ImplAddDel( &aDelData );
2705 if ( mbRadioCheck )
2706 ImplUncheckAllOther();
2707 if ( aDelData.IsDelete() )
2708 return;
2709 if ( bGrabFocus )
2710 ImplGrabFocus( nFocusFlags );
2711 if ( aDelData.IsDelete() )
2712 return;
2713 if ( mbStateChanged )
2714 Toggle();
2715 if ( aDelData.IsDelete() )
2716 return;
2717 Click();
2718 if ( aDelData.IsDelete() )
2719 return;
2720 ImplRemoveDel( &aDelData );
2721 mbStateChanged = FALSE;
2724 // -----------------------------------------------------------------------
2726 RadioButton::RadioButton( Window* pParent, WinBits nStyle ) :
2727 Button( WINDOW_RADIOBUTTON )
2729 ImplInitRadioButtonData();
2730 ImplInit( pParent, nStyle );
2733 // -----------------------------------------------------------------------
2735 RadioButton::RadioButton( Window* pParent, const ResId& rResId ) :
2736 Button( WINDOW_RADIOBUTTON )
2738 ImplInitRadioButtonData();
2739 rResId.SetRT( RSC_RADIOBUTTON );
2740 WinBits nStyle = ImplInitRes( rResId );
2741 ImplInit( pParent, nStyle );
2742 ImplLoadRes( rResId );
2744 if ( !(nStyle & WB_HIDE) )
2745 Show();
2748 // -----------------------------------------------------------------------
2750 void RadioButton::ImplLoadRes( const ResId& rResId )
2752 Button::ImplLoadRes( rResId );
2754 //anderer Wert als Default ?
2755 USHORT nChecked = ReadShortRes();
2756 if ( nChecked )
2757 SetState( TRUE );
2760 // -----------------------------------------------------------------------
2762 RadioButton::~RadioButton()
2766 // -----------------------------------------------------------------------
2768 void RadioButton::MouseButtonDown( const MouseEvent& rMEvt )
2770 if ( rMEvt.IsLeft() && maMouseRect.IsInside( rMEvt.GetPosPixel() ) )
2772 ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
2773 ImplInvalidateOrDrawRadioButtonState();
2774 StartTracking();
2775 return;
2778 Button::MouseButtonDown( rMEvt );
2781 // -----------------------------------------------------------------------
2783 void RadioButton::Tracking( const TrackingEvent& rTEvt )
2785 if ( rTEvt.IsTrackingEnded() )
2787 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
2789 if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() )
2790 GrabFocus();
2792 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
2794 // Bei Abbruch kein Click-Handler rufen
2795 if ( !rTEvt.IsTrackingCanceled() )
2796 ImplCallClick();
2797 else
2798 ImplInvalidateOrDrawRadioButtonState();
2801 else
2803 if ( maMouseRect.IsInside( rTEvt.GetMouseEvent().GetPosPixel() ) )
2805 if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) )
2807 ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
2808 ImplInvalidateOrDrawRadioButtonState();
2811 else
2813 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
2815 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
2816 ImplInvalidateOrDrawRadioButtonState();
2822 // -----------------------------------------------------------------------
2824 void RadioButton::KeyInput( const KeyEvent& rKEvt )
2826 KeyCode aKeyCode = rKEvt.GetKeyCode();
2828 if ( !aKeyCode.GetModifier() && (aKeyCode.GetCode() == KEY_SPACE) )
2830 if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) )
2832 ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
2833 ImplInvalidateOrDrawRadioButtonState();
2836 else if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_ESCAPE) )
2838 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
2839 ImplInvalidateOrDrawRadioButtonState();
2841 else
2842 Button::KeyInput( rKEvt );
2845 // -----------------------------------------------------------------------
2847 void RadioButton::KeyUp( const KeyEvent& rKEvt )
2849 KeyCode aKeyCode = rKEvt.GetKeyCode();
2851 if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_SPACE) )
2853 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
2854 ImplCallClick();
2856 else
2857 Button::KeyUp( rKEvt );
2860 // -----------------------------------------------------------------------
2862 void RadioButton::FillLayoutData() const
2864 mpLayoutData = new vcl::ControlLayoutData();
2865 const_cast<RadioButton*>(this)->ImplDrawRadioButton( true );
2868 // -----------------------------------------------------------------------
2870 void RadioButton::Paint( const Rectangle& )
2872 ImplDrawRadioButton();
2875 // -----------------------------------------------------------------------
2877 void RadioButton::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
2878 ULONG nFlags )
2880 if ( !maImage )
2882 MapMode aResMapMode( MAP_100TH_MM );
2883 Point aPos = pDev->LogicToPixel( rPos );
2884 Size aSize = pDev->LogicToPixel( rSize );
2885 Size aImageSize = pDev->LogicToPixel( Size( 300, 300 ), aResMapMode );
2886 Size aBrd1Size = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode );
2887 Size aBrd2Size = pDev->LogicToPixel( Size( 60, 60 ), aResMapMode );
2888 Font aFont = GetDrawPixelFont( pDev );
2889 Rectangle aStateRect;
2890 Rectangle aMouseRect;
2891 Rectangle aFocusRect;
2893 aImageSize.Width() = CalcZoom( aImageSize.Width() );
2894 aImageSize.Height() = CalcZoom( aImageSize.Height() );
2895 aBrd1Size.Width() = CalcZoom( aBrd1Size.Width() );
2896 aBrd1Size.Height() = CalcZoom( aBrd1Size.Height() );
2897 aBrd2Size.Width() = CalcZoom( aBrd2Size.Width() );
2898 aBrd2Size.Height() = CalcZoom( aBrd2Size.Height() );
2900 if ( !aBrd1Size.Width() )
2901 aBrd1Size.Width() = 1;
2902 if ( !aBrd1Size.Height() )
2903 aBrd1Size.Height() = 1;
2904 if ( !aBrd2Size.Width() )
2905 aBrd2Size.Width() = 1;
2906 if ( !aBrd2Size.Height() )
2907 aBrd2Size.Height() = 1;
2909 pDev->Push();
2910 pDev->SetMapMode();
2911 pDev->SetFont( aFont );
2912 if ( nFlags & WINDOW_DRAW_MONO )
2913 pDev->SetTextColor( Color( COL_BLACK ) );
2914 else
2915 pDev->SetTextColor( GetTextColor() );
2916 pDev->SetTextFillColor();
2918 ImplDraw( pDev, nFlags, aPos, aSize,
2919 aImageSize, GetDrawPixel( pDev, IMPL_SEP_BUTTON_IMAGE ),
2920 aStateRect, aMouseRect );
2922 Point aCenterPos = aStateRect.Center();
2923 long nRadX = aImageSize.Width()/2;
2924 long nRadY = aImageSize.Height()/2;
2926 pDev->SetLineColor();
2927 pDev->SetFillColor( Color( COL_BLACK ) );
2928 pDev->DrawPolygon( Polygon( aCenterPos, nRadX, nRadY ) );
2929 nRadX -= aBrd1Size.Width();
2930 nRadY -= aBrd1Size.Height();
2931 pDev->SetFillColor( Color( COL_WHITE ) );
2932 pDev->DrawPolygon( Polygon( aCenterPos, nRadX, nRadY ) );
2933 if ( mbChecked )
2935 nRadX -= aBrd1Size.Width();
2936 nRadY -= aBrd1Size.Height();
2937 if ( !nRadX )
2938 nRadX = 1;
2939 if ( !nRadY )
2940 nRadY = 1;
2941 pDev->SetFillColor( Color( COL_BLACK ) );
2942 pDev->DrawPolygon( Polygon( aCenterPos, nRadX, nRadY ) );
2945 pDev->Pop();
2947 else
2949 DBG_ERROR( "RadioButton::Draw() - not implemented for RadioButton with Image" );
2953 // -----------------------------------------------------------------------
2955 void RadioButton::Resize()
2957 Control::Resize();
2958 Invalidate();
2961 // -----------------------------------------------------------------------
2963 void RadioButton::GetFocus()
2965 ShowFocus( ImplGetFocusRect() );
2966 SetInputContext( InputContext( GetFont() ) );
2967 Button::GetFocus();
2970 // -----------------------------------------------------------------------
2972 void RadioButton::LoseFocus()
2974 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
2976 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
2977 ImplInvalidateOrDrawRadioButtonState();
2980 HideFocus();
2981 Button::LoseFocus();
2984 // -----------------------------------------------------------------------
2986 void RadioButton::StateChanged( StateChangedType nType )
2988 Button::StateChanged( nType );
2990 if ( nType == STATE_CHANGE_STATE )
2992 if ( IsReallyVisible() && IsUpdateMode() )
2993 Invalidate( maStateRect );
2995 else if ( (nType == STATE_CHANGE_ENABLE) ||
2996 (nType == STATE_CHANGE_TEXT) ||
2997 (nType == STATE_CHANGE_IMAGE) ||
2998 (nType == STATE_CHANGE_DATA) ||
2999 (nType == STATE_CHANGE_UPDATEMODE) )
3001 if ( IsUpdateMode() )
3002 Invalidate();
3004 else if ( nType == STATE_CHANGE_STYLE )
3006 SetStyle( ImplInitStyle( GetWindow( WINDOW_PREV ), GetStyle() ) );
3008 if ( (GetPrevStyle() & RADIOBUTTON_VIEW_STYLE) !=
3009 (GetStyle() & RADIOBUTTON_VIEW_STYLE) )
3011 if ( IsUpdateMode() )
3012 Invalidate();
3015 else if ( (nType == STATE_CHANGE_ZOOM) ||
3016 (nType == STATE_CHANGE_CONTROLFONT) )
3018 ImplInitSettings( TRUE, FALSE, FALSE );
3019 Invalidate();
3021 else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
3023 ImplInitSettings( FALSE, TRUE, FALSE );
3024 Invalidate();
3026 else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
3028 ImplInitSettings( FALSE, FALSE, TRUE );
3029 Invalidate();
3033 // -----------------------------------------------------------------------
3035 void RadioButton::DataChanged( const DataChangedEvent& rDCEvt )
3037 Button::DataChanged( rDCEvt );
3039 if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
3040 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
3041 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
3042 (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
3044 ImplInitSettings( TRUE, TRUE, TRUE );
3045 Invalidate();
3049 // -----------------------------------------------------------------------
3051 long RadioButton::PreNotify( NotifyEvent& rNEvt )
3053 long nDone = 0;
3054 const MouseEvent* pMouseEvt = NULL;
3056 if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL )
3058 if( !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() )
3060 // trigger redraw if mouse over state has changed
3061 if( IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL) )
3063 if( ( maMouseRect.IsInside( GetPointerPosPixel()) &&
3064 !maMouseRect.IsInside( GetLastPointerPosPixel()) ) ||
3065 ( maMouseRect.IsInside( GetLastPointerPosPixel()) &&
3066 !maMouseRect.IsInside( GetPointerPosPixel()) ) ||
3067 pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow() )
3069 Invalidate( maStateRect );
3075 return nDone ? nDone : Button::PreNotify(rNEvt);
3078 // -----------------------------------------------------------------------
3080 void RadioButton::Toggle()
3082 ImplCallEventListenersAndHandler( VCLEVENT_RADIOBUTTON_TOGGLE, maToggleHdl, this );
3085 // -----------------------------------------------------------------------
3087 BOOL RadioButton::SetModeRadioImage( const Image& rImage, BmpColorMode eMode )
3089 if( eMode == BMP_COLOR_NORMAL )
3091 if ( rImage != maImage )
3093 maImage = rImage;
3094 StateChanged( STATE_CHANGE_DATA );
3097 else if( eMode == BMP_COLOR_HIGHCONTRAST )
3099 if( maImageHC != rImage )
3101 maImageHC = rImage;
3102 StateChanged( STATE_CHANGE_DATA );
3105 else
3106 return FALSE;
3108 return TRUE;
3111 // -----------------------------------------------------------------------
3113 const Image& RadioButton::GetModeRadioImage( BmpColorMode eMode ) const
3115 if( eMode == BMP_COLOR_HIGHCONTRAST )
3116 return maImageHC;
3117 else
3118 return maImage;
3121 // -----------------------------------------------------------------------
3123 void RadioButton::SetState( BOOL bCheck )
3125 // TabStop-Flag richtig mitfuehren
3126 if ( bCheck )
3127 mpWindowImpl->mnStyle |= WB_TABSTOP;
3128 else
3129 mpWindowImpl->mnStyle &= ~WB_TABSTOP;
3131 if ( mbChecked != bCheck )
3133 mbChecked = bCheck;
3134 StateChanged( STATE_CHANGE_STATE );
3135 Toggle();
3139 // -----------------------------------------------------------------------
3141 void RadioButton::Check( BOOL bCheck )
3143 // TabStop-Flag richtig mitfuehren
3144 if ( bCheck )
3145 mpWindowImpl->mnStyle |= WB_TABSTOP;
3146 else
3147 mpWindowImpl->mnStyle &= ~WB_TABSTOP;
3149 if ( mbChecked != bCheck )
3151 mbChecked = bCheck;
3152 ImplDelData aDelData;
3153 ImplAddDel( &aDelData );
3154 StateChanged( STATE_CHANGE_STATE );
3155 if ( aDelData.IsDelete() )
3156 return;
3157 if ( bCheck && mbRadioCheck )
3158 ImplUncheckAllOther();
3159 if ( aDelData.IsDelete() )
3160 return;
3161 Toggle();
3162 ImplRemoveDel( &aDelData );
3166 // -----------------------------------------------------------------------
3168 Size RadioButton::ImplGetRadioImageSize() const
3170 Size aSize;
3171 // why are IsNativeControlSupported and GetNativeControlRegion not const ?
3172 RadioButton* pThis = const_cast<RadioButton*>(this);
3173 bool bDefaultSize = true;
3174 if( pThis->IsNativeControlSupported( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL ) )
3176 ImplControlValue aControlValue;
3177 // #i45896# workaround gcc3.3 temporary problem
3178 Region aCtrlRegion = Region( Rectangle( Point( 0, 0 ), GetSizePixel() ) );
3179 ControlState nState = CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED;
3180 Region aBoundingRgn, aContentRgn;
3182 // get native size of a radio button
3183 if( pThis->GetNativeControlRegion( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion,
3184 nState, aControlValue, rtl::OUString(),
3185 aBoundingRgn, aContentRgn ) )
3187 Rectangle aCont(aContentRgn.GetBoundRect());
3188 aSize = aCont.GetSize();
3189 bDefaultSize = false;
3192 if( bDefaultSize )
3193 aSize = GetRadioImage( GetSettings(), 0 ).GetSizePixel();
3194 return aSize;
3197 static void LoadThemedImageList (const StyleSettings &rStyleSettings,
3198 ImageList *pList, const ResId &rResId,
3199 USHORT nImages)
3201 Color aColorAry1[6];
3202 Color aColorAry2[6];
3203 aColorAry1[0] = Color( 0xC0, 0xC0, 0xC0 );
3204 aColorAry1[1] = Color( 0xFF, 0xFF, 0x00 );
3205 aColorAry1[2] = Color( 0xFF, 0xFF, 0xFF );
3206 aColorAry1[3] = Color( 0x80, 0x80, 0x80 );
3207 aColorAry1[4] = Color( 0x00, 0x00, 0x00 );
3208 aColorAry1[5] = Color( 0x00, 0xFF, 0x00 );
3209 aColorAry2[0] = rStyleSettings.GetFaceColor();
3210 aColorAry2[1] = rStyleSettings.GetWindowColor();
3211 aColorAry2[2] = rStyleSettings.GetLightColor();
3212 aColorAry2[3] = rStyleSettings.GetShadowColor();
3213 aColorAry2[4] = rStyleSettings.GetDarkShadowColor();
3214 aColorAry2[5] = rStyleSettings.GetWindowTextColor();
3216 Color aMaskColor(0x00, 0x00, 0xFF );
3217 DBG_ASSERT( sizeof(aColorAry1) == sizeof(aColorAry2), "aColorAry1 must match aColorAry2" );
3218 // FIXME: do we want the mask for the checkbox ?
3219 pList->InsertFromHorizontalBitmap (rResId, nImages, &aMaskColor,
3220 aColorAry1, aColorAry2, sizeof(aColorAry1) / sizeof(Color));
3223 Image RadioButton::GetRadioImage( const AllSettings& rSettings, USHORT nFlags )
3225 ImplSVData* pSVData = ImplGetSVData();
3226 const StyleSettings& rStyleSettings = rSettings.GetStyleSettings();
3227 USHORT nStyle = rStyleSettings.GetRadioButtonStyle() & STYLE_RADIOBUTTON_STYLE;
3229 if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO )
3230 nStyle = STYLE_RADIOBUTTON_MONO;
3232 if ( !pSVData->maCtrlData.mpRadioImgList ||
3233 (pSVData->maCtrlData.mnRadioStyle != nStyle) ||
3234 (pSVData->maCtrlData.mnLastRadioFColor != rStyleSettings.GetFaceColor().GetColor()) ||
3235 (pSVData->maCtrlData.mnLastRadioWColor != rStyleSettings.GetWindowColor().GetColor()) ||
3236 (pSVData->maCtrlData.mnLastRadioLColor != rStyleSettings.GetLightColor().GetColor()) )
3238 if ( pSVData->maCtrlData.mpRadioImgList )
3239 delete pSVData->maCtrlData.mpRadioImgList;
3241 pSVData->maCtrlData.mnLastRadioFColor = rStyleSettings.GetFaceColor().GetColor();
3242 pSVData->maCtrlData.mnLastRadioWColor = rStyleSettings.GetWindowColor().GetColor();
3243 pSVData->maCtrlData.mnLastRadioLColor = rStyleSettings.GetLightColor().GetColor();
3245 Color pColorAry1[6];
3246 Color pColorAry2[6];
3247 pColorAry1[0] = Color( 0xC0, 0xC0, 0xC0 );
3248 pColorAry1[1] = Color( 0xFF, 0xFF, 0x00 );
3249 pColorAry1[2] = Color( 0xFF, 0xFF, 0xFF );
3250 pColorAry1[3] = Color( 0x80, 0x80, 0x80 );
3251 pColorAry1[4] = Color( 0x00, 0x00, 0x00 );
3252 pColorAry1[5] = Color( 0x00, 0xFF, 0x00 );
3253 pColorAry2[0] = rStyleSettings.GetFaceColor();
3254 pColorAry2[1] = rStyleSettings.GetWindowColor();
3255 pColorAry2[2] = rStyleSettings.GetLightColor();
3256 pColorAry2[3] = rStyleSettings.GetShadowColor();
3257 pColorAry2[4] = rStyleSettings.GetDarkShadowColor();
3258 pColorAry2[5] = rStyleSettings.GetWindowTextColor();
3260 ResMgr* pResMgr = ImplGetResMgr();
3261 pSVData->maCtrlData.mpRadioImgList = new ImageList();
3262 if( pResMgr )
3263 LoadThemedImageList( rStyleSettings,
3264 pSVData->maCtrlData.mpRadioImgList,
3265 ResId( SV_RESID_BITMAP_RADIO+nStyle, *pResMgr ), 6 );
3266 pSVData->maCtrlData.mnRadioStyle = nStyle;
3269 USHORT nId;
3270 if ( nFlags & BUTTON_DRAW_DISABLED )
3272 if ( nFlags & BUTTON_DRAW_CHECKED )
3273 nId = 6;
3274 else
3275 nId = 5;
3277 else if ( nFlags & BUTTON_DRAW_PRESSED )
3279 if ( nFlags & BUTTON_DRAW_CHECKED )
3280 nId = 4;
3281 else
3282 nId = 3;
3284 else
3286 if ( nFlags & BUTTON_DRAW_CHECKED )
3287 nId = 2;
3288 else
3289 nId = 1;
3291 return pSVData->maCtrlData.mpRadioImgList->GetImage( nId );
3294 // -----------------------------------------------------------------------
3296 void RadioButton::ImplSetMinimumNWFSize()
3298 Push( PUSH_MAPMODE );
3299 SetMapMode( MAP_PIXEL );
3301 ImplControlValue aControlValue;
3302 Size aCurSize( GetSizePixel() );
3303 Region aCtrlRegion = Region( Rectangle( Point( 0, 0 ), aCurSize ) );
3304 Region aBoundingRgn, aContentRgn;
3306 // get native size of a radiobutton
3307 if( GetNativeControlRegion( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion,
3308 CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED, aControlValue, rtl::OUString(),
3309 aBoundingRgn, aContentRgn ) )
3311 Rectangle aCont(aContentRgn.GetBoundRect());
3312 Size aSize = aCont.GetSize();
3314 if( aSize.Height() > aCurSize.Height() )
3316 aCurSize.Height() = aSize.Height();
3317 SetSizePixel( aCurSize );
3321 Pop();
3324 // -----------------------------------------------------------------------
3326 Size RadioButton::CalcMinimumSize( long nMaxWidth ) const
3328 Size aSize;
3329 if ( !maImage )
3330 aSize = ImplGetRadioImageSize();
3331 else
3332 aSize = maImage.GetSizePixel();
3334 nMaxWidth -= aSize.Width();
3336 XubString aText = GetText();
3337 if ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
3339 // subtract what will be added later
3340 nMaxWidth-=2;
3341 nMaxWidth -= IMPL_SEP_BUTTON_IMAGE;
3343 Size aTextSize = GetTextRect( Rectangle( Point(), Size( nMaxWidth > 0 ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ),
3344 aText, FixedText::ImplGetTextStyle( GetStyle() ) ).GetSize();
3345 aSize.Width()+=2; // for focus rect
3346 aSize.Width() += IMPL_SEP_BUTTON_IMAGE;
3347 aSize.Width() += aTextSize.Width();
3348 if ( aSize.Height() < aTextSize.Height() )
3349 aSize.Height() = aTextSize.Height();
3351 else if ( !maImage )
3353 /* da ansonsten im Writer die Control zu weit oben haengen
3354 aSize.Width() += 2;
3355 aSize.Height() += 2;
3359 return CalcWindowSize( aSize );
3362 // -----------------------------------------------------------------------
3364 Size RadioButton::GetOptimalSize(WindowSizeType eType) const
3366 switch (eType) {
3367 case WINDOWSIZE_MINIMUM:
3368 return CalcMinimumSize();
3369 default:
3370 return Button::GetOptimalSize( eType );
3374 // =======================================================================
3376 void CheckBox::ImplInitCheckBoxData()
3378 meState = STATE_NOCHECK;
3379 meSaveValue = STATE_NOCHECK;
3380 mbTriState = FALSE;
3383 // -----------------------------------------------------------------------
3385 void CheckBox::ImplInit( Window* pParent, WinBits nStyle )
3387 nStyle = ImplInitStyle( pParent->GetWindow( WINDOW_LASTCHILD ), nStyle );
3388 Button::ImplInit( pParent, nStyle, NULL );
3390 ImplInitSettings( TRUE, TRUE, TRUE );
3393 // -----------------------------------------------------------------------
3395 WinBits CheckBox::ImplInitStyle( const Window* pPrevWindow, WinBits nStyle )
3397 if ( !(nStyle & WB_NOTABSTOP) )
3398 nStyle |= WB_TABSTOP;
3399 if ( !(nStyle & WB_NOGROUP) &&
3400 (!pPrevWindow || (pPrevWindow->GetType() != WINDOW_CHECKBOX)) )
3401 nStyle |= WB_GROUP;
3402 return nStyle;
3405 // -----------------------------------------------------------------------
3407 void CheckBox::ImplInitSettings( BOOL bFont,
3408 BOOL bForeground, BOOL bBackground )
3410 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
3412 if ( bFont )
3414 Font aFont = rStyleSettings.GetRadioCheckFont();
3415 if ( IsControlFont() )
3416 aFont.Merge( GetControlFont() );
3417 SetZoomedPointFont( aFont );
3420 if ( bForeground || bFont )
3422 Color aColor;
3423 if ( IsControlForeground() )
3424 aColor = GetControlForeground();
3425 else
3426 aColor = rStyleSettings.GetRadioCheckTextColor();
3427 SetTextColor( aColor );
3428 SetTextFillColor();
3431 if ( bBackground )
3433 Window* pParent = GetParent();
3434 if ( !IsControlBackground() &&
3435 (pParent->IsChildTransparentModeEnabled() || IsNativeControlSupported( CTRL_CHECKBOX, PART_ENTIRE_CONTROL ) ) )
3437 EnableChildTransparentMode( TRUE );
3438 SetParentClipMode( PARENTCLIPMODE_NOCLIP );
3439 SetPaintTransparent( TRUE );
3440 SetBackground();
3441 if( IsNativeControlSupported( CTRL_CHECKBOX, PART_ENTIRE_CONTROL ) )
3442 ImplGetWindowImpl()->mbUseNativeFocus = ImplGetSVData()->maNWFData.mbNoFocusRects;
3444 else
3446 EnableChildTransparentMode( FALSE );
3447 SetParentClipMode( 0 );
3448 SetPaintTransparent( FALSE );
3450 if ( IsControlBackground() )
3451 SetBackground( GetControlBackground() );
3452 else
3453 SetBackground( pParent->GetBackground() );
3458 // -----------------------------------------------------------------------
3460 void CheckBox::ImplLoadRes( const ResId& rResId )
3462 Button::ImplLoadRes( rResId );
3464 if ( rResId.GetRT() != RSC_TRISTATEBOX )
3466 USHORT nChecked = ReadShortRes();
3467 //anderer Wert als Default ?
3468 if( nChecked )
3469 Check( TRUE );
3473 // -----------------------------------------------------------------------
3475 void CheckBox::ImplInvalidateOrDrawCheckBoxState()
3477 if( ImplGetSVData()->maNWFData.mbCheckBoxNeedsErase )
3479 if ( IsNativeControlSupported(CTRL_CHECKBOX, PART_ENTIRE_CONTROL) )
3481 Invalidate();
3482 Update();
3483 return;
3486 ImplDrawCheckBoxState();
3489 void CheckBox::ImplDrawCheckBoxState()
3491 bool bNativeOK = TRUE;
3493 if ( (bNativeOK=IsNativeControlSupported(CTRL_CHECKBOX, PART_ENTIRE_CONTROL)) == TRUE )
3495 ImplControlValue aControlValue( meState == STATE_CHECK ? BUTTONVALUE_ON : BUTTONVALUE_OFF, rtl::OUString(), 0 );
3496 Region aCtrlRegion( maStateRect );
3497 ControlState nState = 0;
3499 if ( HasFocus() ) nState |= CTRL_STATE_FOCUSED;
3500 if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT ) nState |= CTRL_STATE_DEFAULT;
3501 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) nState |= CTRL_STATE_PRESSED;
3502 if ( IsEnabled() ) nState |= CTRL_STATE_ENABLED;
3504 if ( meState == STATE_CHECK )
3505 aControlValue.setTristateVal( BUTTONVALUE_ON );
3506 else if ( meState == STATE_DONTKNOW )
3507 aControlValue.setTristateVal( BUTTONVALUE_MIXED );
3509 if ( IsMouseOver() && maMouseRect.IsInside( GetPointerPosPixel() ) )
3510 nState |= CTRL_STATE_ROLLOVER;
3512 bNativeOK = DrawNativeControl( CTRL_CHECKBOX, PART_ENTIRE_CONTROL, aCtrlRegion, nState,
3513 aControlValue, rtl::OUString() );
3516 if ( bNativeOK == FALSE )
3518 USHORT nStyle = ImplGetButtonState();
3519 if ( !IsEnabled() )
3520 nStyle |= BUTTON_DRAW_DISABLED;
3521 if ( meState == STATE_DONTKNOW )
3522 nStyle |= BUTTON_DRAW_DONTKNOW;
3523 else if ( meState == STATE_CHECK )
3524 nStyle |= BUTTON_DRAW_CHECKED;
3525 Image aImage = GetCheckImage( GetSettings(), nStyle );
3526 if ( IsZoom() )
3527 DrawImage( maStateRect.TopLeft(), maStateRect.GetSize(), aImage );
3528 else
3529 DrawImage( maStateRect.TopLeft(), aImage );
3533 // -----------------------------------------------------------------------
3535 void CheckBox::ImplDraw( OutputDevice* pDev, ULONG nDrawFlags,
3536 const Point& rPos, const Size& rSize,
3537 const Size& rImageSize, long nImageSep,
3538 Rectangle& rStateRect, Rectangle& rMouseRect,
3539 bool bLayout )
3541 WinBits nWinStyle = GetStyle();
3542 XubString aText( GetText() );
3544 pDev->Push( PUSH_CLIPREGION | PUSH_LINECOLOR );
3545 pDev->IntersectClipRegion( Rectangle( rPos, rSize ) );
3547 long nLineY = rPos.Y() + (rSize.Height()-1)/2;
3548 if ( ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) ) ||
3549 ( HasImage() && ! (ImplGetButtonState() & BUTTON_DRAW_NOIMAGE) ) )
3551 USHORT nTextStyle = Button::ImplGetTextStyle( aText, nWinStyle, nDrawFlags );
3553 Size aSize( rSize );
3554 Point aPos( rPos );
3555 aPos.X() += rImageSize.Width() + nImageSep;
3556 aSize.Width() -= rImageSize.Width() + nImageSep;
3558 // if the text rect height is smaller than the height of the image
3559 // then for single lines the default should be centered text
3560 if( (nWinStyle & (WB_TOP|WB_VCENTER|WB_BOTTOM)) == 0 &&
3561 (rImageSize.Height() > rSize.Height() || ! (nWinStyle & WB_WORDBREAK) ) )
3563 nTextStyle &= ~(TEXT_DRAW_TOP|TEXT_DRAW_BOTTOM);
3564 nTextStyle |= TEXT_DRAW_VCENTER;
3565 aSize.Height() = rImageSize.Height();
3568 ImplDrawAlignedImage( pDev, aPos, aSize, bLayout, 1,
3569 nDrawFlags, nTextStyle, NULL );
3570 nLineY = aPos.Y() + aSize.Height()/2;
3572 rMouseRect = Rectangle( aPos, aSize );
3573 rMouseRect.Left() = rPos.X();
3574 rStateRect.Left() = rPos.X();
3575 rStateRect.Top() = rMouseRect.Top();
3577 if ( aSize.Height() > rImageSize.Height() )
3578 rStateRect.Top() += ( aSize.Height() - rImageSize.Height() ) / 2;
3579 else
3581 rStateRect.Top() -= ( rImageSize.Height() - aSize.Height() ) / 2;
3582 if( rStateRect.Top() < 0 )
3583 rStateRect.Top() = 0;
3586 rStateRect.Right() = rStateRect.Left()+rImageSize.Width()-1;
3587 rStateRect.Bottom() = rStateRect.Top()+rImageSize.Height()-1;
3588 if ( rStateRect.Bottom() > rMouseRect.Bottom() )
3589 rMouseRect.Bottom() = rStateRect.Bottom();
3591 else
3593 if ( nWinStyle & WB_CENTER )
3594 rStateRect.Left() = rPos.X()+((rSize.Width()-rImageSize.Width())/2);
3595 else if ( nWinStyle & WB_RIGHT )
3596 rStateRect.Left() = rPos.X()+rSize.Width()-rImageSize.Width();
3597 else
3598 rStateRect.Left() = rPos.X();
3599 if ( nWinStyle & WB_VCENTER )
3600 rStateRect.Top() = rPos.Y()+((rSize.Height()-rImageSize.Height())/2);
3601 else if ( nWinStyle & WB_BOTTOM )
3602 rStateRect.Top() = rPos.Y()+rSize.Height()-rImageSize.Height();
3603 else
3604 rStateRect.Top() = rPos.Y();
3605 rStateRect.Right() = rStateRect.Left()+rImageSize.Width()-1;
3606 rStateRect.Bottom() = rStateRect.Top()+rImageSize.Height()-1;
3607 // provide space for focusrect
3608 // note: this assumes that the control's size was adjusted
3609 // accordingly in Get/LoseFocus, so the onscreen position won't change
3610 if( HasFocus() )
3611 rStateRect.Move( 1, 1 );
3612 rMouseRect = rStateRect;
3614 ImplSetFocusRect( rStateRect );
3617 const int nLineSpace = 4;
3618 if( (GetStyle() & WB_CBLINESTYLE) != 0 &&
3619 rMouseRect.Right()-1-nLineSpace < rPos.X()+rSize.Width() )
3621 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
3622 if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO )
3623 SetLineColor( Color( COL_BLACK ) );
3624 else
3625 SetLineColor( rStyleSettings.GetShadowColor() );
3626 long nLineX = rMouseRect.Right()+nLineSpace;
3627 DrawLine( Point( nLineX, nLineY ), Point( rPos.X() + rSize.Width()-1, nLineY ) );
3628 if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
3630 SetLineColor( rStyleSettings.GetLightColor() );
3631 DrawLine( Point( nLineX, nLineY+1 ), Point( rPos.X() + rSize.Width()-1, nLineY+1 ) );
3635 pDev->Pop();
3638 // -----------------------------------------------------------------------
3640 void CheckBox::ImplDrawCheckBox( bool bLayout )
3642 Size aImageSize = ImplGetCheckImageSize();
3643 aImageSize.Width() = CalcZoom( aImageSize.Width() );
3644 aImageSize.Height() = CalcZoom( aImageSize.Height() );
3646 if( !bLayout )
3647 HideFocus();
3649 ImplDraw( this, 0, Point(), GetOutputSizePixel(), aImageSize,
3650 IMPL_SEP_BUTTON_IMAGE, maStateRect, maMouseRect, bLayout );
3652 if( !bLayout )
3654 ImplDrawCheckBoxState();
3655 if ( HasFocus() )
3656 ShowFocus( ImplGetFocusRect() );
3660 // -----------------------------------------------------------------------
3662 void CheckBox::ImplCheck()
3664 TriState eNewState;
3665 if ( meState == STATE_NOCHECK )
3666 eNewState = STATE_CHECK;
3667 else if ( !mbTriState )
3668 eNewState = STATE_NOCHECK;
3669 else if ( meState == STATE_CHECK )
3670 eNewState = STATE_DONTKNOW;
3671 else
3672 eNewState = STATE_NOCHECK;
3673 meState = eNewState;
3674 ImplInvalidateOrDrawCheckBoxState();
3676 ImplDelData aDelData;
3677 ImplAddDel( &aDelData );
3678 Toggle();
3679 if ( aDelData.IsDelete() )
3680 return;
3681 ImplRemoveDel( &aDelData );
3682 Click();
3685 // -----------------------------------------------------------------------
3687 CheckBox::CheckBox( Window* pParent, WinBits nStyle ) :
3688 Button( WINDOW_CHECKBOX )
3690 ImplInitCheckBoxData();
3691 ImplInit( pParent, nStyle );
3694 // -----------------------------------------------------------------------
3696 CheckBox::CheckBox( Window* pParent, const ResId& rResId ) :
3697 Button( WINDOW_CHECKBOX )
3699 ImplInitCheckBoxData();
3700 rResId.SetRT( RSC_CHECKBOX );
3701 WinBits nStyle = ImplInitRes( rResId );
3702 ImplInit( pParent, nStyle );
3703 ImplLoadRes( rResId );
3705 if ( !(nStyle & WB_HIDE) )
3706 Show();
3709 // -----------------------------------------------------------------------
3711 void CheckBox::MouseButtonDown( const MouseEvent& rMEvt )
3713 if ( rMEvt.IsLeft() && maMouseRect.IsInside( rMEvt.GetPosPixel() ) )
3715 ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
3716 ImplInvalidateOrDrawCheckBoxState();
3717 StartTracking();
3718 return;
3721 Button::MouseButtonDown( rMEvt );
3724 // -----------------------------------------------------------------------
3726 void CheckBox::Tracking( const TrackingEvent& rTEvt )
3728 if ( rTEvt.IsTrackingEnded() )
3730 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
3732 if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() )
3733 GrabFocus();
3735 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
3737 // Bei Abbruch kein Click-Handler rufen
3738 if ( !rTEvt.IsTrackingCanceled() )
3739 ImplCheck();
3740 else
3741 ImplInvalidateOrDrawCheckBoxState();
3744 else
3746 if ( maMouseRect.IsInside( rTEvt.GetMouseEvent().GetPosPixel() ) )
3748 if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) )
3750 ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
3751 ImplInvalidateOrDrawCheckBoxState();
3754 else
3756 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
3758 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
3759 ImplInvalidateOrDrawCheckBoxState();
3765 // -----------------------------------------------------------------------
3767 void CheckBox::KeyInput( const KeyEvent& rKEvt )
3769 KeyCode aKeyCode = rKEvt.GetKeyCode();
3771 if ( !aKeyCode.GetModifier() && (aKeyCode.GetCode() == KEY_SPACE) )
3773 if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) )
3775 ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
3776 ImplInvalidateOrDrawCheckBoxState();
3779 else if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_ESCAPE) )
3781 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
3782 ImplInvalidateOrDrawCheckBoxState();
3784 else
3785 Button::KeyInput( rKEvt );
3788 // -----------------------------------------------------------------------
3790 void CheckBox::KeyUp( const KeyEvent& rKEvt )
3792 KeyCode aKeyCode = rKEvt.GetKeyCode();
3794 if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_SPACE) )
3796 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
3797 ImplCheck();
3799 else
3800 Button::KeyUp( rKEvt );
3803 // -----------------------------------------------------------------------
3805 void CheckBox::FillLayoutData() const
3807 mpLayoutData = new vcl::ControlLayoutData();
3808 const_cast<CheckBox*>(this)->ImplDrawCheckBox( true );
3811 // -----------------------------------------------------------------------
3813 void CheckBox::Paint( const Rectangle& )
3815 ImplDrawCheckBox();
3818 // -----------------------------------------------------------------------
3820 void CheckBox::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
3821 ULONG nFlags )
3823 MapMode aResMapMode( MAP_100TH_MM );
3824 Point aPos = pDev->LogicToPixel( rPos );
3825 Size aSize = pDev->LogicToPixel( rSize );
3826 Size aImageSize = pDev->LogicToPixel( Size( 300, 300 ), aResMapMode );
3827 Size aBrd1Size = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode );
3828 Size aBrd2Size = pDev->LogicToPixel( Size( 30, 30 ), aResMapMode );
3829 long nCheckWidth = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode ).Width();
3830 Font aFont = GetDrawPixelFont( pDev );
3831 Rectangle aStateRect;
3832 Rectangle aMouseRect;
3834 aImageSize.Width() = CalcZoom( aImageSize.Width() );
3835 aImageSize.Height() = CalcZoom( aImageSize.Height() );
3836 aBrd1Size.Width() = CalcZoom( aBrd1Size.Width() );
3837 aBrd1Size.Height() = CalcZoom( aBrd1Size.Height() );
3838 aBrd2Size.Width() = CalcZoom( aBrd2Size.Width() );
3839 aBrd2Size.Height() = CalcZoom( aBrd2Size.Height() );
3841 if ( !aBrd1Size.Width() )
3842 aBrd1Size.Width() = 1;
3843 if ( !aBrd1Size.Height() )
3844 aBrd1Size.Height() = 1;
3845 if ( !aBrd2Size.Width() )
3846 aBrd2Size.Width() = 1;
3847 if ( !aBrd2Size.Height() )
3848 aBrd2Size.Height() = 1;
3849 if ( !nCheckWidth )
3850 nCheckWidth = 1;
3852 pDev->Push();
3853 pDev->SetMapMode();
3854 pDev->SetFont( aFont );
3855 if ( nFlags & WINDOW_DRAW_MONO )
3856 pDev->SetTextColor( Color( COL_BLACK ) );
3857 else
3858 pDev->SetTextColor( GetTextColor() );
3859 pDev->SetTextFillColor();
3861 ImplDraw( pDev, nFlags, aPos, aSize,
3862 aImageSize, GetDrawPixel( pDev, IMPL_SEP_BUTTON_IMAGE ),
3863 aStateRect, aMouseRect, false );
3865 pDev->SetLineColor();
3866 pDev->SetFillColor( Color( COL_BLACK ) );
3867 pDev->DrawRect( aStateRect );
3868 aStateRect.Left() += aBrd1Size.Width();
3869 aStateRect.Top() += aBrd1Size.Height();
3870 aStateRect.Right() -= aBrd1Size.Width();
3871 aStateRect.Bottom() -= aBrd1Size.Height();
3872 if ( meState == STATE_DONTKNOW )
3873 pDev->SetFillColor( Color( COL_LIGHTGRAY ) );
3874 else
3875 pDev->SetFillColor( Color( COL_WHITE ) );
3876 pDev->DrawRect( aStateRect );
3878 if ( meState == STATE_CHECK )
3880 aStateRect.Left() += aBrd2Size.Width();
3881 aStateRect.Top() += aBrd2Size.Height();
3882 aStateRect.Right() -= aBrd2Size.Width();
3883 aStateRect.Bottom() -= aBrd2Size.Height();
3884 Point aPos11( aStateRect.TopLeft() );
3885 Point aPos12( aStateRect.BottomRight() );
3886 Point aPos21( aStateRect.TopRight() );
3887 Point aPos22( aStateRect.BottomLeft() );
3888 Point aTempPos11( aPos11 );
3889 Point aTempPos12( aPos12 );
3890 Point aTempPos21( aPos21 );
3891 Point aTempPos22( aPos22 );
3892 pDev->SetLineColor( Color( COL_BLACK ) );
3893 long nDX = 0;
3894 for ( long i = 0; i < nCheckWidth; i++ )
3896 if ( !(i % 2) )
3898 aTempPos11.X() = aPos11.X()+nDX;
3899 aTempPos12.X() = aPos12.X()+nDX;
3900 aTempPos21.X() = aPos21.X()+nDX;
3901 aTempPos22.X() = aPos22.X()+nDX;
3903 else
3905 nDX++;
3906 aTempPos11.X() = aPos11.X()-nDX;
3907 aTempPos12.X() = aPos12.X()-nDX;
3908 aTempPos21.X() = aPos21.X()-nDX;
3909 aTempPos22.X() = aPos22.X()-nDX;
3911 pDev->DrawLine( aTempPos11, aTempPos12 );
3912 pDev->DrawLine( aTempPos21, aTempPos22 );
3916 pDev->Pop();
3919 // -----------------------------------------------------------------------
3921 void CheckBox::Resize()
3923 Control::Resize();
3924 Invalidate();
3927 // -----------------------------------------------------------------------
3929 void CheckBox::GetFocus()
3931 if ( !GetText().Len() || (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
3933 // increase button size to have space for focus rect
3934 // checkboxes without text will draw focusrect around the check
3935 // See CheckBox::ImplDraw()
3936 Point aPos( GetPosPixel() );
3937 Size aSize( GetSizePixel() );
3938 aPos.Move(-1,-1);
3939 aSize.Height() += 2;
3940 aSize.Width() += 2;
3941 SetPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height(), WINDOW_POSSIZE_ALL );
3942 ImplDrawCheckBox();
3944 else
3945 ShowFocus( ImplGetFocusRect() );
3947 SetInputContext( InputContext( GetFont() ) );
3948 Button::GetFocus();
3951 // -----------------------------------------------------------------------
3953 void CheckBox::LoseFocus()
3955 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
3957 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
3958 ImplInvalidateOrDrawCheckBoxState();
3961 HideFocus();
3962 Button::LoseFocus();
3964 if ( !GetText().Len() || (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
3966 // decrease button size again (see GetFocus())
3967 // checkboxes without text will draw focusrect around the check
3968 Point aPos( GetPosPixel() );
3969 Size aSize( GetSizePixel() );
3970 aPos.Move(1,1);
3971 aSize.Height() -= 2;
3972 aSize.Width() -= 2;
3973 SetPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height(), WINDOW_POSSIZE_ALL );
3974 ImplDrawCheckBox();
3978 // -----------------------------------------------------------------------
3980 void CheckBox::StateChanged( StateChangedType nType )
3982 Button::StateChanged( nType );
3984 if ( nType == STATE_CHANGE_STATE )
3986 if ( IsReallyVisible() && IsUpdateMode() )
3987 Invalidate( maStateRect );
3989 else if ( (nType == STATE_CHANGE_ENABLE) ||
3990 (nType == STATE_CHANGE_TEXT) ||
3991 (nType == STATE_CHANGE_IMAGE) ||
3992 (nType == STATE_CHANGE_DATA) ||
3993 (nType == STATE_CHANGE_UPDATEMODE) )
3995 if ( IsUpdateMode() )
3996 Invalidate();
3998 else if ( nType == STATE_CHANGE_STYLE )
4000 SetStyle( ImplInitStyle( GetWindow( WINDOW_PREV ), GetStyle() ) );
4002 if ( (GetPrevStyle() & CHECKBOX_VIEW_STYLE) !=
4003 (GetStyle() & CHECKBOX_VIEW_STYLE) )
4005 if ( IsUpdateMode() )
4006 Invalidate();
4009 else if ( (nType == STATE_CHANGE_ZOOM) ||
4010 (nType == STATE_CHANGE_CONTROLFONT) )
4012 ImplInitSettings( TRUE, FALSE, FALSE );
4013 Invalidate();
4015 else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
4017 ImplInitSettings( FALSE, TRUE, FALSE );
4018 Invalidate();
4020 else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
4022 ImplInitSettings( FALSE, FALSE, TRUE );
4023 Invalidate();
4027 // -----------------------------------------------------------------------
4029 void CheckBox::DataChanged( const DataChangedEvent& rDCEvt )
4031 Button::DataChanged( rDCEvt );
4033 if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
4034 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
4035 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
4036 (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
4038 ImplInitSettings( TRUE, TRUE, TRUE );
4039 Invalidate();
4043 // -----------------------------------------------------------------------
4045 long CheckBox::PreNotify( NotifyEvent& rNEvt )
4047 long nDone = 0;
4048 const MouseEvent* pMouseEvt = NULL;
4050 if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL )
4052 if( !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() )
4054 // trigger redraw if mouse over state has changed
4055 if( IsNativeControlSupported(CTRL_CHECKBOX, PART_ENTIRE_CONTROL) )
4057 if( ( maMouseRect.IsInside( GetPointerPosPixel()) &&
4058 !maMouseRect.IsInside( GetLastPointerPosPixel()) ) ||
4059 ( maMouseRect.IsInside( GetLastPointerPosPixel()) &&
4060 !maMouseRect.IsInside( GetPointerPosPixel()) ) ||
4061 pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow() )
4063 Invalidate( maStateRect );
4069 return nDone ? nDone : Button::PreNotify(rNEvt);
4072 // -----------------------------------------------------------------------
4074 void CheckBox::Toggle()
4076 ImplCallEventListenersAndHandler( VCLEVENT_CHECKBOX_TOGGLE, maToggleHdl, this );
4079 // -----------------------------------------------------------------------
4081 void CheckBox::SetState( TriState eState )
4083 if ( !mbTriState && (eState == STATE_DONTKNOW) )
4084 eState = STATE_NOCHECK;
4086 if ( meState != eState )
4088 meState = eState;
4089 StateChanged( STATE_CHANGE_STATE );
4090 Toggle();
4094 // -----------------------------------------------------------------------
4096 void CheckBox::EnableTriState( BOOL bTriState )
4098 if ( mbTriState != bTriState )
4100 mbTriState = bTriState;
4102 if ( !bTriState && (meState == STATE_DONTKNOW) )
4103 SetState( STATE_NOCHECK );
4107 // -----------------------------------------------------------------------
4109 Size CheckBox::ImplGetCheckImageSize() const
4111 Size aSize;
4112 // why are IsNativeControlSupported and GetNativeControlRegion not const ?
4113 CheckBox* pThis = const_cast<CheckBox*>(this);
4114 bool bDefaultSize = true;
4115 if( pThis->IsNativeControlSupported( CTRL_CHECKBOX, PART_ENTIRE_CONTROL ) )
4117 ImplControlValue aControlValue;
4118 // #i45896# workaround gcc3.3 temporary problem
4119 Region aCtrlRegion = Region( Rectangle( Point( 0, 0 ), GetSizePixel() ) );
4120 ControlState nState = CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED;
4121 Region aBoundingRgn, aContentRgn;
4123 // get native size of a check box
4124 if( pThis->GetNativeControlRegion( CTRL_CHECKBOX, PART_ENTIRE_CONTROL, aCtrlRegion,
4125 nState, aControlValue, rtl::OUString(),
4126 aBoundingRgn, aContentRgn ) )
4128 Rectangle aCont(aContentRgn.GetBoundRect());
4129 aSize = aCont.GetSize();
4130 bDefaultSize = false;
4133 if( bDefaultSize )
4134 aSize = GetCheckImage( GetSettings(), 0 ).GetSizePixel();
4135 return aSize;
4138 Image CheckBox::GetCheckImage( const AllSettings& rSettings, USHORT nFlags )
4140 ImplSVData* pSVData = ImplGetSVData();
4141 const StyleSettings& rStyleSettings = rSettings.GetStyleSettings();
4142 USHORT nStyle = rStyleSettings.GetCheckBoxStyle() & STYLE_CHECKBOX_STYLE;
4144 if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO )
4145 nStyle = STYLE_CHECKBOX_MONO;
4147 if ( !pSVData->maCtrlData.mpCheckImgList ||
4148 (pSVData->maCtrlData.mnCheckStyle != nStyle) ||
4149 (pSVData->maCtrlData.mnLastCheckFColor != rStyleSettings.GetFaceColor().GetColor()) ||
4150 (pSVData->maCtrlData.mnLastCheckWColor != rStyleSettings.GetWindowColor().GetColor()) ||
4151 (pSVData->maCtrlData.mnLastCheckLColor != rStyleSettings.GetLightColor().GetColor()) )
4153 if ( pSVData->maCtrlData.mpCheckImgList )
4154 delete pSVData->maCtrlData.mpCheckImgList;
4156 pSVData->maCtrlData.mnLastCheckFColor = rStyleSettings.GetFaceColor().GetColor();
4157 pSVData->maCtrlData.mnLastCheckWColor = rStyleSettings.GetWindowColor().GetColor();
4158 pSVData->maCtrlData.mnLastCheckLColor = rStyleSettings.GetLightColor().GetColor();
4160 ResMgr* pResMgr = ImplGetResMgr();
4161 pSVData->maCtrlData.mpCheckImgList = new ImageList();
4162 if( pResMgr )
4163 LoadThemedImageList( rStyleSettings,
4164 pSVData->maCtrlData.mpCheckImgList,
4165 ResId( SV_RESID_BITMAP_CHECK+nStyle, *pResMgr ), 9 );
4166 pSVData->maCtrlData.mnCheckStyle = nStyle;
4169 USHORT nId;
4170 if ( nFlags & BUTTON_DRAW_DISABLED )
4172 if ( nFlags & BUTTON_DRAW_DONTKNOW )
4173 nId = 9;
4174 else if ( nFlags & BUTTON_DRAW_CHECKED )
4175 nId = 6;
4176 else
4177 nId = 5;
4179 else if ( nFlags & BUTTON_DRAW_PRESSED )
4181 if ( nFlags & BUTTON_DRAW_DONTKNOW )
4182 nId = 8;
4183 else if ( nFlags & BUTTON_DRAW_CHECKED )
4184 nId = 4;
4185 else
4186 nId = 3;
4188 else
4190 if ( nFlags & BUTTON_DRAW_DONTKNOW )
4191 nId = 7;
4192 else if ( nFlags & BUTTON_DRAW_CHECKED )
4193 nId = 2;
4194 else
4195 nId = 1;
4197 return pSVData->maCtrlData.mpCheckImgList->GetImage( nId );
4200 // -----------------------------------------------------------------------
4202 void CheckBox::ImplSetMinimumNWFSize()
4204 Push( PUSH_MAPMODE );
4205 SetMapMode( MAP_PIXEL );
4207 ImplControlValue aControlValue;
4208 Size aCurSize( GetSizePixel() );
4209 Region aCtrlRegion = Region( Rectangle( Point( 0, 0 ), aCurSize ) );
4210 Region aBoundingRgn, aContentRgn;
4212 // get native size of a radiobutton
4213 if( GetNativeControlRegion( CTRL_CHECKBOX, PART_ENTIRE_CONTROL, aCtrlRegion,
4214 CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED, aControlValue, rtl::OUString(),
4215 aBoundingRgn, aContentRgn ) )
4217 Rectangle aCont(aContentRgn.GetBoundRect());
4218 Size aSize = aCont.GetSize();
4220 if( aSize.Height() > aCurSize.Height() )
4222 aCurSize.Height() = aSize.Height();
4223 SetSizePixel( aCurSize );
4227 Pop();
4230 // -----------------------------------------------------------------------
4232 Size CheckBox::CalcMinimumSize( long nMaxWidth ) const
4234 Size aSize = ImplGetCheckImageSize();
4235 nMaxWidth -= aSize.Width();
4237 XubString aText = GetText();
4238 if ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
4240 // subtract what will be added later
4241 nMaxWidth-=2;
4242 nMaxWidth -= IMPL_SEP_BUTTON_IMAGE;
4244 Size aTextSize = GetTextRect( Rectangle( Point(), Size( nMaxWidth > 0 ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ),
4245 aText, FixedText::ImplGetTextStyle( GetStyle() ) ).GetSize();
4246 aSize.Width()+=2; // for focus rect
4247 aSize.Width() += IMPL_SEP_BUTTON_IMAGE;
4248 aSize.Width() += aTextSize.Width();
4249 if ( aSize.Height() < aTextSize.Height() )
4250 aSize.Height() = aTextSize.Height();
4252 else
4254 // is this still correct ? since the checkbox now
4255 // shows a focus rect it should be 2 pixels wider and longer
4256 /* da ansonsten im Writer die Control zu weit oben haengen
4257 aSize.Width() += 2;
4258 aSize.Height() += 2;
4262 return CalcWindowSize( aSize );
4265 // -----------------------------------------------------------------------
4267 Size CheckBox::GetOptimalSize(WindowSizeType eType) const
4269 switch (eType) {
4270 case WINDOWSIZE_MINIMUM:
4271 return CalcMinimumSize();
4272 default:
4273 return Button::GetOptimalSize( eType );
4277 // =======================================================================
4279 ImageButton::ImageButton( WindowType nType ) :
4280 PushButton( nType )
4282 ImplInitStyle();
4285 // -----------------------------------------------------------------------
4287 ImageButton::ImageButton( Window* pParent, WinBits nStyle ) :
4288 PushButton( pParent, nStyle )
4290 ImplInitStyle();
4293 // -----------------------------------------------------------------------
4295 ImageButton::ImageButton( Window* pParent, const ResId& rResId ) :
4296 PushButton( pParent, rResId.SetRT( RSC_IMAGEBUTTON ) )
4298 ULONG nObjMask = ReadLongRes();
4300 if ( RSC_IMAGEBUTTON_IMAGE & nObjMask )
4302 SetModeImage( Image( ResId( (RSHEADER_TYPE*)GetClassRes(), *rResId.GetResMgr() ) ) );
4303 IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
4306 if ( RSC_IMAGEBUTTON_SYMBOL & nObjMask )
4307 SetSymbol( (SymbolType)ReadLongRes() );
4309 if ( RSC_IMAGEBUTTON_STATE & nObjMask )
4310 SetState( (TriState)ReadLongRes() );
4312 ImplInitStyle();
4315 // -----------------------------------------------------------------------
4317 ImageButton::~ImageButton()
4321 // -----------------------------------------------------------------------
4322 void ImageButton::ImplInitStyle()
4324 WinBits nStyle = GetStyle();
4326 if ( ! ( nStyle & ( WB_RIGHT | WB_LEFT ) ) )
4327 nStyle |= WB_CENTER;
4329 if ( ! ( nStyle & ( WB_TOP | WB_BOTTOM ) ) )
4330 nStyle |= WB_VCENTER;
4332 SetStyle( nStyle );
4335 // =======================================================================
4337 ImageRadioButton::ImageRadioButton( Window* pParent, WinBits nStyle ) :
4338 RadioButton( pParent, nStyle )
4342 // -----------------------------------------------------------------------
4344 ImageRadioButton::ImageRadioButton( Window* pParent, const ResId& rResId ) :
4345 RadioButton( pParent, rResId.SetRT( RSC_IMAGERADIOBUTTON ) )
4347 ULONG nObjMask = ReadLongRes();
4349 if ( RSC_IMAGERADIOBUTTON_IMAGE & nObjMask )
4351 SetModeRadioImage( Image( ResId( (RSHEADER_TYPE*)GetClassRes(), *rResId.GetResMgr() ) ) );
4352 IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
4356 // -----------------------------------------------------------------------
4358 ImageRadioButton::~ImageRadioButton()
4362 // =======================================================================
4364 TriStateBox::TriStateBox( Window* pParent, WinBits nStyle ) :
4365 CheckBox( pParent, nStyle )
4367 EnableTriState( TRUE );
4370 // -----------------------------------------------------------------------
4372 TriStateBox::TriStateBox( Window* pParent, const ResId& rResId ) :
4373 CheckBox( pParent, rResId.SetRT( RSC_TRISTATEBOX ) )
4375 EnableTriState( TRUE );
4377 ULONG nTriState = ReadLongRes();
4378 USHORT bDisableTriState = ReadShortRes();
4379 //anderer Wert als Default ?
4380 if ( (TriState)nTriState != STATE_NOCHECK )
4381 SetState( (TriState)nTriState );
4382 if ( bDisableTriState )
4383 EnableTriState( FALSE );
4386 // -----------------------------------------------------------------------
4388 TriStateBox::~TriStateBox()