Update ooo320-m1
[ooovba.git] / vcl / source / control / button.cxx
blob0f1b4408e80444b594816b92e2348f01fe8f2b0d
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 if( !!(mpButtonData->maImageHC) )
427 if( GetSettings().GetStyleSettings().GetHighContrastMode() )
429 pImage = &(mpButtonData->maImageHC);
430 pBitmapEx = mpButtonData->mpBitmapExHC;
434 if ( pBitmapEx && ( pDev->GetOutDevType() == OUTDEV_PRINTER ) )
436 // Die Groesse richtet sich nach dem Bildschirm, soll auf
437 // dem Drucker genau so aussehen...
438 MapMode aMap100thMM( MAP_100TH_MM );
439 aImageSize = PixelToLogic( aImageSize, aMap100thMM );
440 aImageSize = pDev->LogicToPixel( aImageSize, aMap100thMM );
443 Size aTextSize;
444 Size aSymbolSize;
445 Size aMax;
446 Point aImagePos = rPos;
447 Point aTextPos = rPos;
448 Rectangle aUnion = Rectangle( aImagePos, aImageSize );
449 Rectangle aSymbol;
450 long nSymbolHeight = 0;
452 if ( bDrawText || bHasSymbol )
454 // Get the size of the text output area ( the symbol will be drawn in
455 // this area as well, so the symbol rectangle will be calculated here, too )
457 Rectangle aRect = Rectangle( Point(), rSize );
458 Size aTSSize;
460 if ( bHasSymbol )
462 if ( bDrawText )
464 nSymbolHeight = pDev->GetTextHeight();
465 if ( mpButtonData->mbSmallSymbol )
466 nSymbolHeight = nSymbolHeight * 3 / 4;
468 aSymbol = Rectangle( Point(), Size( nSymbolHeight, nSymbolHeight ) );
469 ImplCalcSymbolRect( aSymbol );
470 aRect.Left() += 3 * nSymbolHeight / 2;
471 aTSSize.Width() = 3 * nSymbolHeight / 2;
473 else
475 aSymbol = Rectangle( Point(), rSize );
476 ImplCalcSymbolRect( aSymbol );
477 aTSSize.Width() = aSymbol.GetWidth();
479 aTSSize.Height() = aSymbol.GetHeight();
480 aSymbolSize = aSymbol.GetSize();
483 if ( bDrawText )
485 if ( ( eImageAlign == IMAGEALIGN_LEFT_TOP ) ||
486 ( eImageAlign == IMAGEALIGN_LEFT ) ||
487 ( eImageAlign == IMAGEALIGN_LEFT_BOTTOM ) ||
488 ( eImageAlign == IMAGEALIGN_RIGHT_TOP ) ||
489 ( eImageAlign == IMAGEALIGN_RIGHT ) ||
490 ( eImageAlign == IMAGEALIGN_RIGHT_BOTTOM ) )
492 aRect.Right() -= ( aImageSize.Width() + nImageSep );
494 else if ( ( eImageAlign == IMAGEALIGN_TOP_LEFT ) ||
495 ( eImageAlign == IMAGEALIGN_TOP ) ||
496 ( eImageAlign == IMAGEALIGN_TOP_RIGHT ) ||
497 ( eImageAlign == IMAGEALIGN_BOTTOM_LEFT ) ||
498 ( eImageAlign == IMAGEALIGN_BOTTOM ) ||
499 ( eImageAlign == IMAGEALIGN_BOTTOM_RIGHT ) )
501 aRect.Bottom() -= ( aImageSize.Height() + nImageSep );
504 aRect = pDev->GetTextRect( aRect, aText, nTextStyle );
505 aTextSize = aRect.GetSize();
507 aTSSize.Width() += aTextSize.Width();
509 if ( aTSSize.Height() < aTextSize.Height() )
510 aTSSize.Height() = aTextSize.Height();
513 aMax.Width() = aTSSize.Width() > aImageSize.Width() ? aTSSize.Width() : aImageSize.Width();
514 aMax.Height() = aTSSize.Height() > aImageSize.Height() ? aTSSize.Height() : aImageSize.Height();
516 // Now calculate the output area for the image and the text acording to the image align flags
518 if ( ( eImageAlign == IMAGEALIGN_LEFT ) ||
519 ( eImageAlign == IMAGEALIGN_RIGHT ) )
521 aImagePos.Y() = rPos.Y() + ( aMax.Height() - aImageSize.Height() ) / 2;
522 aTextPos.Y() = rPos.Y() + ( aMax.Height() - aTSSize.Height() ) / 2;
524 else if ( ( eImageAlign == IMAGEALIGN_LEFT_BOTTOM ) ||
525 ( eImageAlign == IMAGEALIGN_RIGHT_BOTTOM ) )
527 aImagePos.Y() = rPos.Y() + aMax.Height() - aImageSize.Height();
528 aTextPos.Y() = rPos.Y() + aMax.Height() - aTSSize.Height();
530 else if ( ( eImageAlign == IMAGEALIGN_TOP ) ||
531 ( eImageAlign == IMAGEALIGN_BOTTOM ) )
533 aImagePos.X() = rPos.X() + ( aMax.Width() - aImageSize.Width() ) / 2;
534 aTextPos.X() = rPos.X() + ( aMax.Width() - aTSSize.Width() ) / 2;
536 else if ( ( eImageAlign == IMAGEALIGN_TOP_RIGHT ) ||
537 ( eImageAlign == IMAGEALIGN_BOTTOM_RIGHT ) )
539 aImagePos.X() = rPos.X() + aMax.Width() - aImageSize.Width();
540 aTextPos.X() = rPos.X() + aMax.Width() - aTSSize.Width();
543 if ( ( eImageAlign == IMAGEALIGN_LEFT_TOP ) ||
544 ( eImageAlign == IMAGEALIGN_LEFT ) ||
545 ( eImageAlign == IMAGEALIGN_LEFT_BOTTOM ) )
547 aTextPos.X() = rPos.X() + aImageSize.Width() + nImageSep;
549 else if ( ( eImageAlign == IMAGEALIGN_RIGHT_TOP ) ||
550 ( eImageAlign == IMAGEALIGN_RIGHT ) ||
551 ( eImageAlign == IMAGEALIGN_RIGHT_BOTTOM ) )
553 aImagePos.X() = rPos.X() + aTSSize.Width() + nImageSep;
555 else if ( ( eImageAlign == IMAGEALIGN_TOP_LEFT ) ||
556 ( eImageAlign == IMAGEALIGN_TOP ) ||
557 ( eImageAlign == IMAGEALIGN_TOP_RIGHT ) )
559 aTextPos.Y() = rPos.Y() + aImageSize.Height() + nImageSep;
561 else if ( ( eImageAlign == IMAGEALIGN_BOTTOM_LEFT ) ||
562 ( eImageAlign == IMAGEALIGN_BOTTOM ) ||
563 ( eImageAlign == IMAGEALIGN_BOTTOM_RIGHT ) )
565 aImagePos.Y() = rPos.Y() + aTSSize.Height() + nImageSep;
567 else if ( eImageAlign == IMAGEALIGN_CENTER )
569 aImagePos.X() = rPos.X() + ( aMax.Width() - aImageSize.Width() ) / 2;
570 aImagePos.Y() = rPos.Y() + ( aMax.Height() - aImageSize.Height() ) / 2;
571 aTextPos.X() = rPos.X() + ( aMax.Width() - aTSSize.Width() ) / 2;
572 aTextPos.Y() = rPos.Y() + ( aMax.Height() - aTSSize.Height() ) / 2;
574 aUnion = Rectangle( aImagePos, aImageSize );
575 aUnion.Union( Rectangle( aTextPos, aTSSize ) );
578 // Now place the combination of text and image in the output area of the button
579 // according to the window style (WinBits)
580 long nXOffset = 0;
581 long nYOffset = 0;
583 if ( nWinStyle & WB_CENTER )
585 nXOffset = ( rSize.Width() - aUnion.GetWidth() ) / 2;
587 else if ( nWinStyle & WB_RIGHT )
589 nXOffset = rSize.Width() - aUnion.GetWidth();
592 if ( nWinStyle & WB_VCENTER )
594 nYOffset = ( rSize.Height() - aUnion.GetHeight() ) / 2;
596 else if ( nWinStyle & WB_BOTTOM )
598 nYOffset = rSize.Height() - aUnion.GetHeight();
601 // the top left corner should always be visible, so we don't allow negative offsets
602 if ( nXOffset < 0 ) nXOffset = 0;
603 if ( nYOffset < 0 ) nYOffset = 0;
605 aImagePos.X() += nXOffset;
606 aImagePos.Y() += nYOffset;
607 aTextPos.X() += nXOffset;
608 aTextPos.Y() += nYOffset;
610 // set rPos and rSize to the union
611 rSize = aUnion.GetSize();
612 rPos.X() += nXOffset;
613 rPos.Y() += nYOffset;
615 if ( bHasSymbol )
617 if ( mpButtonData->meSymbolAlign == SYMBOLALIGN_RIGHT )
619 Point aRightPos = Point( aTextPos.X() + aTextSize.Width() + aSymbolSize.Width()/2, aTextPos.Y() );
620 *pSymbolRect = Rectangle( aRightPos, aSymbolSize );
622 else
624 *pSymbolRect = Rectangle( aTextPos, aSymbolSize );
625 aTextPos.X() += ( 3 * nSymbolHeight / 2 );
627 if ( mpButtonData->mbSmallSymbol )
629 nYOffset = (aUnion.GetHeight() - aSymbolSize.Height())/2;
630 pSymbolRect->setY( aTextPos.Y() + nYOffset );
634 USHORT nStyle = 0;
636 if ( ! ( nDrawFlags & WINDOW_DRAW_NODISABLE ) &&
637 ! IsEnabled() )
638 nStyle |= IMAGE_DRAW_DISABLE;
640 if ( pBitmapEx && ( pDev->GetOutDevType() == OUTDEV_PRINTER ) )
642 // Fuer die BitmapEx ueberlegt sich KA noch, wie man die disablete
643 // Darstellung hinbekommt...
644 pBitmapEx->Draw( pDev, aImagePos, aImageSize /*, nStyle*/ );
646 else
648 if ( IsZoom() )
649 pDev->DrawImage( aImagePos, aImageSize, *pImage, nStyle );
650 else
651 pDev->DrawImage( aImagePos, *pImage, nStyle );
654 if ( bDrawText )
656 ImplSetFocusRect( Rectangle( aTextPos, aTextSize ) );
657 pDev->DrawText( Rectangle( aTextPos, aTextSize ), aText, nTextStyle, pVector, pDisplayText );
659 else
661 ImplSetFocusRect( Rectangle( aImagePos, aImageSize ) );
665 // -----------------------------------------------------------------------
666 void Button::ImplSetFocusRect( const Rectangle &rFocusRect )
668 Rectangle aFocusRect = rFocusRect;
669 Rectangle aOutputRect = Rectangle( Point(), GetOutputSizePixel() );
671 if ( ! aFocusRect.IsEmpty() )
673 aFocusRect.Left()--;
674 aFocusRect.Top()--;
675 aFocusRect.Right()++;
676 aFocusRect.Bottom()++;
679 if ( aFocusRect.Left() < aOutputRect.Left() ) aFocusRect.Left() = aOutputRect.Left();
680 if ( aFocusRect.Top() < aOutputRect.Top() ) aFocusRect.Top() = aOutputRect.Top();
681 if ( aFocusRect.Right() > aOutputRect.Right() ) aFocusRect.Right() = aOutputRect.Right();
682 if ( aFocusRect.Bottom() > aOutputRect.Bottom() ) aFocusRect.Bottom() = aOutputRect.Bottom();
684 mpButtonData->maFocusRect = aFocusRect;
687 // -----------------------------------------------------------------------
688 const Rectangle& Button::ImplGetFocusRect() const
690 return mpButtonData->maFocusRect;
693 // -----------------------------------------------------------------------
694 USHORT& Button::ImplGetButtonState()
696 return mpButtonData->mnButtonState;
699 // -----------------------------------------------------------------------
700 USHORT Button::ImplGetButtonState() const
702 return mpButtonData->mnButtonState;
705 // -----------------------------------------------------------------------
706 void Button::ImplSetSymbolAlign( SymbolAlign eAlign )
708 if ( mpButtonData->meSymbolAlign != eAlign )
710 mpButtonData->meSymbolAlign = eAlign;
711 StateChanged( STATE_CHANGE_DATA );
715 // -----------------------------------------------------------------------
716 SymbolAlign Button::ImplGetSymbolAlign() const
718 return mpButtonData->meSymbolAlign;
720 // -----------------------------------------------------------------------
721 void Button::ImplSetSmallSymbol( BOOL bSmall )
723 mpButtonData->mbSmallSymbol = bSmall;
726 // -----------------------------------------------------------------------
727 void Button::EnableImageDisplay( BOOL bEnable )
729 if( bEnable )
730 mpButtonData->mnButtonState &= ~BUTTON_DRAW_NOIMAGE;
731 else
732 mpButtonData->mnButtonState |= BUTTON_DRAW_NOIMAGE;
735 // -----------------------------------------------------------------------
736 BOOL Button::IsImageDisplayEnabled()
738 return (mpButtonData->mnButtonState & BUTTON_DRAW_NOIMAGE) == 0;
741 // -----------------------------------------------------------------------
742 void Button::EnableTextDisplay( BOOL bEnable )
744 if( bEnable )
745 mpButtonData->mnButtonState &= ~BUTTON_DRAW_NOTEXT;
746 else
747 mpButtonData->mnButtonState |= BUTTON_DRAW_NOTEXT;
750 // -----------------------------------------------------------------------
751 BOOL Button::IsTextDisplayEnabled()
753 return (mpButtonData->mnButtonState & BUTTON_DRAW_NOTEXT) == 0;
756 // -----------------------------------------------------------------------
757 void Button::DataChanged( const DataChangedEvent& rDCEvt )
759 Control::DataChanged( rDCEvt );
761 // The flag SETTINGS_IN_UPDATE_SETTINGS is set when the settings changed due to a
762 // Application::SettingsChanged event. In this scenario we want to keep the style settings
763 // of our radio buttons and our check boxes.
764 if ( ( rDCEvt.GetType() == DATACHANGED_SETTINGS ) &&
765 ( rDCEvt.GetFlags() & SETTINGS_IN_UPDATE_SETTINGS ) )
768 const AllSettings* pOldSettings = rDCEvt.GetOldSettings();
769 if ( pOldSettings )
771 BOOL bResetStyleSettings = FALSE;
772 AllSettings aAllSettings = GetSettings();
773 StyleSettings aStyleSetting = aAllSettings.GetStyleSettings();
775 USHORT nCheckBoxStyle = aStyleSetting.GetCheckBoxStyle();
776 if ( nCheckBoxStyle != pOldSettings->GetStyleSettings().GetCheckBoxStyle() )
778 aStyleSetting.SetCheckBoxStyle( pOldSettings->GetStyleSettings().GetCheckBoxStyle() );
779 bResetStyleSettings = TRUE;
782 USHORT nRadioButtonStyle = aStyleSetting.GetRadioButtonStyle();
783 if ( nRadioButtonStyle != pOldSettings->GetStyleSettings().GetRadioButtonStyle() )
785 aStyleSetting.SetRadioButtonStyle( pOldSettings->GetStyleSettings().GetRadioButtonStyle() );
786 bResetStyleSettings = TRUE;
789 if ( bResetStyleSettings )
791 aAllSettings.SetStyleSettings( pOldSettings->GetStyleSettings() );
792 SetSettings( aAllSettings );
798 void Button::SetSmallSymbol (bool small)
800 ImplSetSmallSymbol (small);
803 bool Button::IsSmallSymbol () const
805 return mpButtonData->mbSmallSymbol;
808 // =======================================================================
810 void PushButton::ImplInitPushButtonData()
812 mpWindowImpl->mbPushButton = TRUE;
814 meSymbol = SYMBOL_NOSYMBOL;
815 meState = STATE_NOCHECK;
816 meSaveValue = STATE_NOCHECK;
817 mnDDStyle = 0;
818 mbPressed = FALSE;
819 mbInUserDraw = FALSE;
822 // -----------------------------------------------------------------------
824 void PushButton::ImplInit( Window* pParent, WinBits nStyle )
826 nStyle = ImplInitStyle( pParent->GetWindow( WINDOW_LASTCHILD ), nStyle );
827 Button::ImplInit( pParent, nStyle, NULL );
829 if ( nStyle & WB_NOLIGHTBORDER )
830 ImplGetButtonState() |= BUTTON_DRAW_NOLIGHTBORDER;
832 ImplInitSettings( TRUE, TRUE, TRUE );
835 // -----------------------------------------------------------------------
837 WinBits PushButton::ImplInitStyle( const Window* pPrevWindow, WinBits nStyle )
839 if ( !(nStyle & WB_NOTABSTOP) )
840 nStyle |= WB_TABSTOP;
842 // if no alignment is given, default to "vertically centered". This is because since
843 // #i26046#, we respect the vertical alignment flags (previously we didn't completely),
844 // but we of course want to look as before when no vertical alignment is specified
845 if ( ( nStyle & ( WB_TOP | WB_VCENTER | WB_BOTTOM ) ) == 0 )
846 nStyle |= WB_VCENTER;
848 if ( !(nStyle & WB_NOGROUP) &&
849 (!pPrevWindow ||
850 ((pPrevWindow->GetType() != WINDOW_PUSHBUTTON) &&
851 (pPrevWindow->GetType() != WINDOW_OKBUTTON) &&
852 (pPrevWindow->GetType() != WINDOW_CANCELBUTTON) &&
853 (pPrevWindow->GetType() != WINDOW_HELPBUTTON)) ) )
854 nStyle |= WB_GROUP;
855 return nStyle;
858 // -----------------------------------------------------------------------
860 void PushButton::ImplInitSettings( BOOL bFont,
861 BOOL bForeground, BOOL bBackground )
863 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
865 if ( bFont )
867 Font aFont = rStyleSettings.GetPushButtonFont();
868 if ( IsControlFont() )
869 aFont.Merge( GetControlFont() );
870 SetZoomedPointFont( aFont );
873 if ( bForeground || bFont )
875 Color aColor;
876 if ( IsControlForeground() )
877 aColor = GetControlForeground();
878 else
879 aColor = rStyleSettings.GetButtonTextColor();
880 SetTextColor( aColor );
881 SetTextFillColor();
884 if ( bBackground )
886 SetBackground();
887 // #i38498#: do not check for GetParent()->IsChildTransparentModeEnabled()
888 // otherwise the formcontrol button will be overdrawn due to PARENTCLIPMODE_NOCLIP
889 // for radio and checkbox this is ok as they shoud appear transparent in documents
890 if ( IsNativeControlSupported( CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL ) )
892 EnableChildTransparentMode( TRUE );
893 SetParentClipMode( PARENTCLIPMODE_NOCLIP );
894 SetPaintTransparent( TRUE );
895 mpWindowImpl->mbUseNativeFocus = ImplGetSVData()->maNWFData.mbNoFocusRects;
897 else
899 EnableChildTransparentMode( FALSE );
900 SetParentClipMode( 0 );
901 SetPaintTransparent( FALSE );
906 // -----------------------------------------------------------------------
908 void PushButton::ImplDrawPushButtonFrame( Window* pDev,
909 Rectangle& rRect, USHORT nStyle )
911 if ( !(pDev->GetStyle() & (WB_RECTSTYLE | WB_SMALLSTYLE)) )
913 StyleSettings aStyleSettings = pDev->GetSettings().GetStyleSettings();
914 if ( pDev->IsControlBackground() )
915 aStyleSettings.Set3DColors( pDev->GetControlBackground() );
917 USHORT nPushButtonSysStyle = aStyleSettings.GetPushButtonStyle() & STYLE_PUSHBUTTON_STYLE;
918 if ( nPushButtonSysStyle == STYLE_PUSHBUTTON_MAC )
920 pDev->SetLineColor();
921 pDev->SetFillColor( aStyleSettings.GetFaceColor() );
922 pDev->DrawRect( rRect );
924 if ( (aStyleSettings.GetOptions() & STYLE_OPTION_MONO) ||
925 (pDev->GetOutDevType() == OUTDEV_PRINTER) )
926 nStyle |= BUTTON_DRAW_MONO;
928 if ( nStyle & BUTTON_DRAW_DEFAULT )
930 if ( nStyle & BUTTON_DRAW_MONO )
931 pDev->SetLineColor( Color( COL_BLACK ) );
932 else
933 pDev->SetLineColor( aStyleSettings.GetDarkShadowColor() );
935 pDev->DrawLine( Point( rRect.Left()+3, rRect.Top() ),
936 Point( rRect.Right()-3, rRect.Top() ) );
937 pDev->DrawLine( Point( rRect.Left()+3, rRect.Bottom() ),
938 Point( rRect.Right()-3, rRect.Bottom() ) );
939 pDev->DrawLine( Point( rRect.Left(), rRect.Top()+3 ),
940 Point( rRect.Left(), rRect.Bottom()-3 ) );
941 pDev->DrawLine( Point( rRect.Right(), rRect.Top()+3 ),
942 Point( rRect.Right(), rRect.Bottom()-3 ) );
943 pDev->DrawPixel( Point( rRect.Left()+2, rRect.Top()+1 ) );
944 pDev->DrawPixel( Point( rRect.Left()+1, rRect.Top()+2 ) );
945 pDev->DrawPixel( Point( rRect.Right()-2, rRect.Top()+1 ) );
946 pDev->DrawPixel( Point( rRect.Right()-1, rRect.Top()+2 ) );
947 pDev->DrawPixel( Point( rRect.Left()+2, rRect.Bottom()-1 ) );
948 pDev->DrawPixel( Point( rRect.Left()+1, rRect.Bottom()-2 ) );
949 pDev->DrawPixel( Point( rRect.Right()-2, rRect.Bottom()-1 ) );
950 pDev->DrawPixel( Point( rRect.Right()-1, rRect.Bottom()-2 ) );
952 if ( nStyle & BUTTON_DRAW_MONO )
953 pDev->SetLineColor( Color( COL_BLACK ) );
954 else
955 pDev->SetLineColor( aStyleSettings.GetShadowColor() );
956 pDev->DrawLine( Point( rRect.Left()+3, rRect.Bottom()-1 ),
957 Point( rRect.Right()-3, rRect.Bottom()-1 ) );
958 pDev->DrawLine( Point( rRect.Right()-1, rRect.Top()+3 ),
959 Point( rRect.Right()-1, rRect.Bottom()-3 ) );
960 pDev->DrawPixel( Point( rRect.Right()-3, rRect.Bottom()-2 ) );
961 pDev->DrawPixel( Point( rRect.Right()-2, rRect.Bottom()-2 ) );
962 pDev->DrawPixel( Point( rRect.Right()-2, rRect.Bottom()-3 ) );
965 rRect.Left() += 2;
966 rRect.Top() += 2;
967 rRect.Right() -= 2;
968 rRect.Bottom() -= 2;
970 if ( nStyle & BUTTON_DRAW_MONO )
971 pDev->SetLineColor( Color( COL_BLACK ) );
972 else
973 pDev->SetLineColor( aStyleSettings.GetDarkShadowColor() );
975 pDev->DrawLine( Point( rRect.Left()+2, rRect.Top() ),
976 Point( rRect.Right()-2, rRect.Top() ) );
977 pDev->DrawLine( Point( rRect.Left()+2, rRect.Bottom() ),
978 Point( rRect.Right()-2, rRect.Bottom() ) );
979 pDev->DrawLine( Point( rRect.Left(), rRect.Top()+2 ),
980 Point( rRect.Left(), rRect.Bottom()-2 ) );
981 pDev->DrawLine( Point( rRect.Right(), rRect.Top()+2 ),
982 Point( rRect.Right(), rRect.Bottom()-2 ) );
983 pDev->DrawPixel( Point( rRect.Left()+1, rRect.Top()+1 ) );
984 pDev->DrawPixel( Point( rRect.Right()-1, rRect.Top()+1 ) );
985 pDev->DrawPixel( Point( rRect.Left()+1, rRect.Bottom()-1 ) );
986 pDev->DrawPixel( Point( rRect.Right()-1, rRect.Bottom()-1 ) );
988 pDev->SetLineColor();
989 if ( nStyle & BUTTON_DRAW_CHECKED )
990 pDev->SetFillColor( aStyleSettings.GetCheckedColor() );
991 else
992 pDev->SetFillColor( aStyleSettings.GetFaceColor() );
993 pDev->DrawRect( Rectangle( rRect.Left()+2, rRect.Top()+2, rRect.Right()-2, rRect.Bottom()-2 ) );
995 if ( !(nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED)) )
997 if ( nStyle & BUTTON_DRAW_MONO )
998 pDev->SetLineColor( Color( COL_BLACK ) );
999 else
1000 pDev->SetLineColor( aStyleSettings.GetShadowColor() );
1001 pDev->DrawLine( Point( rRect.Left()+2, rRect.Bottom()-1 ),
1002 Point( rRect.Right()-2, rRect.Bottom()-1 ) );
1003 pDev->DrawLine( Point( rRect.Right()-1, rRect.Top()+2 ),
1004 Point( rRect.Right()-1, rRect.Bottom()-2 ) );
1005 pDev->DrawPixel( Point( rRect.Right()-2, rRect.Bottom()-2 ) );
1006 pDev->SetLineColor( aStyleSettings.GetLightColor() );
1008 else
1009 pDev->SetLineColor( aStyleSettings.GetShadowColor() );
1011 if ( !(nStyle & BUTTON_DRAW_MONO) )
1013 pDev->DrawLine( Point( rRect.Left()+2, rRect.Top()+1 ),
1014 Point( rRect.Right()-2, rRect.Top()+1 ) );
1015 pDev->DrawLine( Point( rRect.Left()+1, rRect.Top()+2 ),
1016 Point( rRect.Left()+1, rRect.Bottom()-2 ) );
1017 pDev->DrawPixel( Point( rRect.Top()+2, rRect.Right()+2 ) );
1020 rRect.Left() += 2;
1021 rRect.Top() += 2;
1022 rRect.Right() -= 2;
1023 rRect.Bottom() -= 2;
1025 if ( nStyle & (BUTTON_DRAW_PRESSED | BUTTON_DRAW_CHECKED) )
1027 rRect.Left()++;
1028 rRect.Top()++;
1029 rRect.Right()++;
1030 rRect.Bottom()++;
1033 return;
1037 DecorationView aDecoView( pDev );
1038 if ( pDev->IsControlBackground() )
1040 AllSettings aSettings = pDev->GetSettings();
1041 AllSettings aOldSettings = aSettings;
1042 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1043 aStyleSettings.Set3DColors( pDev->GetControlBackground() );
1044 aSettings.SetStyleSettings( aStyleSettings );
1045 pDev->OutputDevice::SetSettings( aSettings );
1046 rRect = aDecoView.DrawButton( rRect, nStyle );
1047 pDev->OutputDevice::SetSettings( aOldSettings );
1049 else
1050 rRect = aDecoView.DrawButton( rRect, nStyle );
1053 // -----------------------------------------------------------------------
1055 BOOL PushButton::ImplHitTestPushButton( Window* pDev,
1056 const Point& rPos )
1058 Point aTempPoint;
1059 Rectangle aTestRect( aTempPoint, pDev->GetOutputSizePixel() );
1061 if ( !(pDev->GetStyle() & (WB_RECTSTYLE | WB_SMALLSTYLE)) )
1063 const StyleSettings& rStyleSettings = pDev->GetSettings().GetStyleSettings();
1065 USHORT nPushButtonSysStyle = rStyleSettings.GetPushButtonStyle() & STYLE_PUSHBUTTON_STYLE;
1066 if ( nPushButtonSysStyle == STYLE_PUSHBUTTON_MAC )
1068 aTestRect.Left() += 2;
1069 aTestRect.Top() += 2;
1070 aTestRect.Right() -= 2;
1071 aTestRect.Bottom() -= 2;
1075 return aTestRect.IsInside( rPos );
1078 // -----------------------------------------------------------------------
1080 USHORT PushButton::ImplGetTextStyle( ULONG nDrawFlags ) const
1082 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1084 USHORT nTextStyle = TEXT_DRAW_MNEMONIC | TEXT_DRAW_MULTILINE | TEXT_DRAW_ENDELLIPSIS;
1086 if ( ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO ) ||
1087 ( nDrawFlags & WINDOW_DRAW_MONO ) )
1088 nTextStyle |= TEXT_DRAW_MONO;
1090 if ( GetStyle() & WB_WORDBREAK )
1091 nTextStyle |= TEXT_DRAW_WORDBREAK;
1092 if ( GetStyle() & WB_NOLABEL )
1093 nTextStyle &= ~TEXT_DRAW_MNEMONIC;
1095 if ( GetStyle() & WB_LEFT )
1096 nTextStyle |= TEXT_DRAW_LEFT;
1097 else if ( GetStyle() & WB_RIGHT )
1098 nTextStyle |= TEXT_DRAW_RIGHT;
1099 else
1100 nTextStyle |= TEXT_DRAW_CENTER;
1102 if ( GetStyle() & WB_TOP )
1103 nTextStyle |= TEXT_DRAW_TOP;
1104 else if ( GetStyle() & WB_BOTTOM )
1105 nTextStyle |= TEXT_DRAW_BOTTOM;
1106 else
1107 nTextStyle |= TEXT_DRAW_VCENTER;
1109 if ( ! ( (nDrawFlags & WINDOW_DRAW_NODISABLE) || IsEnabled() ) )
1110 nTextStyle |= TEXT_DRAW_DISABLE;
1112 return nTextStyle;
1115 // -----------------------------------------------------------------------
1117 static void ImplDrawBtnDropDownArrow( OutputDevice* pDev,
1118 long nX, long nY,
1119 Color& rColor, BOOL bBlack )
1121 Color aOldLineColor = pDev->GetLineColor();
1122 Color aOldFillColor = pDev->GetFillColor();
1124 pDev->SetLineColor();
1125 if ( bBlack )
1126 pDev->SetFillColor( Color( COL_BLACK ) );
1127 else
1128 pDev->SetFillColor( rColor );
1129 pDev->DrawRect( Rectangle( nX+0, nY+0, nX+6, nY+0 ) );
1130 pDev->DrawRect( Rectangle( nX+1, nY+1, nX+5, nY+1 ) );
1131 pDev->DrawRect( Rectangle( nX+2, nY+2, nX+4, nY+2 ) );
1132 pDev->DrawRect( Rectangle( nX+3, nY+3, nX+3, nY+3 ) );
1133 if ( bBlack )
1135 pDev->SetFillColor( rColor );
1136 pDev->DrawRect( Rectangle( nX+2, nY+1, nX+4, nY+1 ) );
1137 pDev->DrawRect( Rectangle( nX+3, nY+2, nX+3, nY+2 ) );
1139 pDev->SetLineColor( aOldLineColor );
1140 pDev->SetFillColor( aOldFillColor );
1143 // -----------------------------------------------------------------------
1145 void PushButton::ImplDrawPushButtonContent( OutputDevice* pDev, ULONG nDrawFlags,
1146 const Rectangle& rRect,
1147 bool bLayout )
1149 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
1150 Rectangle aInRect = rRect;
1151 Color aColor;
1152 XubString aText = PushButton::GetText(); // PushButton:: wegen MoreButton
1153 USHORT nTextStyle = ImplGetTextStyle( nDrawFlags );
1154 USHORT nStyle;
1156 if( aInRect.nRight < aInRect.nLeft || aInRect.nBottom < aInRect.nTop )
1157 aInRect.SetEmpty();
1159 pDev->Push( PUSH_CLIPREGION );
1160 pDev->IntersectClipRegion( aInRect );
1162 if ( nDrawFlags & WINDOW_DRAW_MONO )
1163 aColor = Color( COL_BLACK );
1164 else if ( IsControlForeground() )
1165 aColor = GetControlForeground();
1166 else if( nDrawFlags & WINDOW_DRAW_ROLLOVER )
1167 aColor = rStyleSettings.GetButtonRolloverTextColor();
1168 else
1169 aColor = rStyleSettings.GetButtonTextColor();
1171 pDev->SetTextColor( aColor );
1173 if ( IsEnabled() || (nDrawFlags & WINDOW_DRAW_NODISABLE) )
1174 nStyle = 0;
1175 else
1176 nStyle = SYMBOL_DRAW_DISABLE;
1178 Size aSize = rRect.GetSize();
1179 Point aPos = rRect.TopLeft();
1181 if ( mnDDStyle == PUSHBUTTON_DROPDOWN_MENUBUTTON )
1183 if ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
1185 // calc Symbol- and Textrect
1186 long nSymbolSize = pDev->GetTextHeight() / 2 + 1;
1187 aInRect.Right() -= 5;
1188 aInRect.Left() = aInRect.Right() - nSymbolSize;
1189 aSize.Width() -= ( 5 + nSymbolSize );
1191 ImplDrawAlignedImage( pDev, aPos, aSize, bLayout,
1192 1, nDrawFlags, nTextStyle );
1194 else
1195 ImplCalcSymbolRect( aInRect );
1197 if( ! bLayout )
1199 DecorationView aDecoView( pDev );
1200 aDecoView.DrawSymbol( aInRect, SYMBOL_SPIN_DOWN, aColor, nStyle );
1203 else
1205 Rectangle aSymbolRect;
1206 ImplDrawAlignedImage( pDev, aPos, aSize, bLayout, 1, nDrawFlags,
1207 nTextStyle, IsSymbol() ? &aSymbolRect : NULL );
1209 if ( IsSymbol() && ! bLayout )
1211 DecorationView aDecoView( pDev );
1212 aDecoView.DrawSymbol( aSymbolRect, meSymbol, aColor, nStyle );
1215 if ( mnDDStyle == PUSHBUTTON_DROPDOWN_TOOLBOX && !bLayout )
1217 BOOL bBlack = FALSE;
1218 Color aArrowColor( COL_BLACK );
1220 if ( !(nDrawFlags & WINDOW_DRAW_MONO) )
1222 if ( !IsEnabled() )
1223 aArrowColor = rStyleSettings.GetShadowColor();
1224 else
1226 aArrowColor = Color( COL_LIGHTGREEN );
1227 bBlack = TRUE;
1231 ImplDrawBtnDropDownArrow( pDev, aInRect.Right()-6, aInRect.Top()+1,
1232 aArrowColor, bBlack );
1236 UserDrawEvent aUDEvt( this, aInRect, 0 );
1237 UserDraw( aUDEvt );
1239 pDev->Pop(); // restore clipregion
1242 // -----------------------------------------------------------------------
1244 void PushButton::UserDraw( const UserDrawEvent& )
1248 // -----------------------------------------------------------------------
1250 void PushButton::ImplDrawPushButton( bool bLayout )
1252 if( !bLayout )
1253 HideFocus();
1255 USHORT nButtonStyle = ImplGetButtonState();
1256 Point aPoint;
1257 Size aOutSz( GetOutputSizePixel() );
1258 Rectangle aRect( aPoint, aOutSz );
1259 Rectangle aInRect = aRect;
1260 Rectangle aTextRect;
1261 BOOL bNativeOK = FALSE;
1263 // adjust style if button should be rendered 'pressed'
1264 if ( mbPressed )
1265 nButtonStyle |= BUTTON_DRAW_PRESSED;
1267 // TODO: move this to Window class or make it a member !!!
1268 ControlType aCtrlType = 0;
1269 switch( GetParent()->GetType() )
1271 case WINDOW_LISTBOX:
1272 case WINDOW_MULTILISTBOX:
1273 case WINDOW_TREELISTBOX:
1274 aCtrlType = CTRL_LISTBOX;
1275 break;
1277 case WINDOW_COMBOBOX:
1278 case WINDOW_PATTERNBOX:
1279 case WINDOW_NUMERICBOX:
1280 case WINDOW_METRICBOX:
1281 case WINDOW_CURRENCYBOX:
1282 case WINDOW_DATEBOX:
1283 case WINDOW_TIMEBOX:
1284 case WINDOW_LONGCURRENCYBOX:
1285 aCtrlType = CTRL_COMBOBOX;
1286 break;
1287 default:
1288 break;
1291 BOOL bDropDown = ( IsSymbol() && (GetSymbol()==SYMBOL_SPIN_DOWN) && !GetText().Len() );
1293 if( bDropDown && (aCtrlType == CTRL_COMBOBOX || aCtrlType == CTRL_LISTBOX ) )
1295 if( GetParent()->IsNativeControlSupported( aCtrlType, PART_ENTIRE_CONTROL) )
1297 // skip painting if the button was already drawn by the theme
1298 if( aCtrlType == CTRL_COMBOBOX )
1300 Edit* pEdit = static_cast<Edit*>(GetParent());
1301 if( pEdit->ImplUseNativeBorder( pEdit->GetStyle() ) )
1302 bNativeOK = TRUE;
1304 else if( GetParent()->IsNativeControlSupported( aCtrlType, HAS_BACKGROUND_TEXTURE) )
1306 bNativeOK = TRUE;
1308 if( !bNativeOK && GetParent()->IsNativeControlSupported( aCtrlType, PART_BUTTON_DOWN ) )
1310 // let the theme draw it, note we then need support
1311 // for CTRL_LISTBOX/PART_BUTTON_DOWN and CTRL_COMBOBOX/PART_BUTTON_DOWN
1313 ImplControlValue aControlValue;
1314 Region aCtrlRegion( aInRect );
1315 ControlState nState = 0;
1317 if ( mbPressed ) nState |= CTRL_STATE_PRESSED;
1318 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) nState |= CTRL_STATE_PRESSED;
1319 if ( HasFocus() ) nState |= CTRL_STATE_FOCUSED;
1320 if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT ) nState |= CTRL_STATE_DEFAULT;
1321 if ( Window::IsEnabled() ) nState |= CTRL_STATE_ENABLED;
1323 if ( IsMouseOver() && aInRect.IsInside( GetPointerPosPixel() ) )
1324 nState |= CTRL_STATE_ROLLOVER;
1326 bNativeOK = DrawNativeControl( aCtrlType, PART_BUTTON_DOWN, aCtrlRegion, nState,
1327 aControlValue, rtl::OUString() );
1332 if( bNativeOK )
1333 return;
1335 if ( (bNativeOK=IsNativeControlSupported(CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL)) == TRUE )
1337 PushButtonValue aPBVal;
1338 ImplControlValue aControlValue;
1339 aControlValue.setOptionalVal( &aPBVal );
1340 Region aCtrlRegion( aInRect );
1341 ControlState nState = 0;
1343 if ( mbPressed || IsChecked() ) nState |= CTRL_STATE_PRESSED;
1344 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) nState |= CTRL_STATE_PRESSED;
1345 if ( HasFocus() ) nState |= CTRL_STATE_FOCUSED;
1346 if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT ) nState |= CTRL_STATE_DEFAULT;
1347 if ( Window::IsEnabled() ) nState |= CTRL_STATE_ENABLED;
1349 if ( IsMouseOver() && aInRect.IsInside( GetPointerPosPixel() ) )
1350 nState |= CTRL_STATE_ROLLOVER;
1352 if( GetStyle() & WB_BEVELBUTTON )
1353 aPBVal.mbBevelButton = true;
1355 // draw frame into invisible window to have aInRect modified correctly
1356 // but do not shift the inner rect for pressed buttons (ie remove BUTTON_DRAW_PRESSED)
1357 // this assumes the theme has enough visual cues to signalize the button was pressed
1358 //Window aWin( this );
1359 //ImplDrawPushButtonFrame( &aWin, aInRect, nButtonStyle & ~BUTTON_DRAW_PRESSED );
1361 // looks better this way as symbols were displaced slightly using the above approach
1362 aInRect.Top()+=4;
1363 aInRect.Bottom()-=4;
1364 aInRect.Left()+=4;
1365 aInRect.Right()-=4;
1367 // prepare single line hint (needed on mac to decide between normal push button and
1368 // rectangular bevel button look)
1369 Size aFontSize( Application::GetSettings().GetStyleSettings().GetPushButtonFont().GetSize() );
1370 aFontSize = LogicToPixel( aFontSize, MapMode( MAP_POINT ) );
1371 Size aInRectSize( LogicToPixel( Size( aInRect.GetWidth(), aInRect.GetHeight() ) ) );
1372 aPBVal.mbSingleLine = (aInRectSize.Height() < 2 * aFontSize.Height() );
1374 bNativeOK = DrawNativeControl( CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion, nState,
1375 aControlValue, rtl::OUString()/*PushButton::GetText()*/ );
1377 // draw content using the same aInRect as non-native VCL would do
1378 ImplDrawPushButtonContent( this,
1379 (nState&CTRL_STATE_ROLLOVER) ? WINDOW_DRAW_ROLLOVER : 0,
1380 aInRect, bLayout );
1382 if ( HasFocus() )
1383 ShowFocus( ImplGetFocusRect() );
1386 if ( bNativeOK == FALSE )
1388 // draw PushButtonFrame, aInRect has content size afterwards
1389 if( ! bLayout )
1390 ImplDrawPushButtonFrame( this, aInRect, nButtonStyle );
1392 // draw content
1393 ImplDrawPushButtonContent( this, 0, aInRect, bLayout );
1395 if( ! bLayout && HasFocus() )
1397 ShowFocus( ImplGetFocusRect() );
1402 // -----------------------------------------------------------------------
1404 void PushButton::ImplSetDefButton( BOOL bSet )
1406 Size aSize( GetSizePixel() );
1407 Point aPos( GetPosPixel() );
1408 int dLeft(0), dRight(0), dTop(0), dBottom(0);
1409 BOOL bSetPos = FALSE;
1411 if ( (IsNativeControlSupported(CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL)) == TRUE )
1413 Region aBoundingRgn, aContentRgn;
1414 Rectangle aCtrlRect( 0, 0, 80, 20 ); // use a constant size to avoid accumulating
1415 // will not work if the theme has dynamic adornment sizes
1416 ImplControlValue aControlValue;
1417 Region aCtrlRegion( aCtrlRect );
1418 ControlState nState = CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED;
1420 // get native size of a 'default' button
1421 // and adjust the VCL button if more space for adornment is required
1422 if( GetNativeControlRegion( CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion,
1423 nState, aControlValue, rtl::OUString(),
1424 aBoundingRgn, aContentRgn ) )
1426 Rectangle aCont(aContentRgn.GetBoundRect());
1427 Rectangle aBound(aBoundingRgn.GetBoundRect());
1429 dLeft = aCont.Left() - aBound.Left();
1430 dTop = aCont.Top() - aBound.Top();
1431 dRight = aBound.Right() - aCont.Right();
1432 dBottom = aBound.Bottom() - aCont.Bottom();
1433 bSetPos = dLeft || dTop || dRight || dBottom;
1437 if ( bSet )
1439 if( !(ImplGetButtonState() & BUTTON_DRAW_DEFAULT) && bSetPos )
1441 // adjust pos/size when toggling from non-default to default
1442 aPos.Move(-dLeft, -dTop);
1443 aSize.Width() += dLeft + dRight;
1444 aSize.Height() += dTop + dBottom;
1446 ImplGetButtonState() |= BUTTON_DRAW_DEFAULT;
1448 else
1450 if( (ImplGetButtonState() & BUTTON_DRAW_DEFAULT) && bSetPos )
1452 // adjust pos/size when toggling from default to non-default
1453 aPos.Move(dLeft, dTop);
1454 aSize.Width() -= dLeft + dRight;
1455 aSize.Height() -= dTop + dBottom;
1457 ImplGetButtonState() &= ~BUTTON_DRAW_DEFAULT;
1459 if( bSetPos )
1460 SetPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height(), WINDOW_POSSIZE_ALL );
1462 Invalidate();
1465 // -----------------------------------------------------------------------
1467 BOOL PushButton::ImplIsDefButton() const
1469 return (ImplGetButtonState() & BUTTON_DRAW_DEFAULT) != 0;
1472 // -----------------------------------------------------------------------
1474 PushButton::PushButton( WindowType nType ) :
1475 Button( nType )
1477 ImplInitPushButtonData();
1480 // -----------------------------------------------------------------------
1482 PushButton::PushButton( Window* pParent, WinBits nStyle ) :
1483 Button( WINDOW_PUSHBUTTON )
1485 ImplInitPushButtonData();
1486 ImplInit( pParent, nStyle );
1489 // -----------------------------------------------------------------------
1491 PushButton::PushButton( Window* pParent, const ResId& rResId ) :
1492 Button( WINDOW_PUSHBUTTON )
1494 ImplInitPushButtonData();
1495 rResId.SetRT( RSC_PUSHBUTTON );
1496 WinBits nStyle = ImplInitRes( rResId );
1497 ImplInit( pParent, nStyle );
1498 ImplLoadRes( rResId );
1500 if ( !(nStyle & WB_HIDE) )
1501 Show();
1504 // -----------------------------------------------------------------------
1506 PushButton::~PushButton()
1510 // -----------------------------------------------------------------------
1512 void PushButton::MouseButtonDown( const MouseEvent& rMEvt )
1514 if ( rMEvt.IsLeft() &&
1515 ImplHitTestPushButton( this, rMEvt.GetPosPixel() ) )
1517 USHORT nTrackFlags = 0;
1519 if ( ( GetStyle() & WB_REPEAT ) &&
1520 ! ( GetStyle() & WB_TOGGLE ) )
1521 nTrackFlags |= STARTTRACK_BUTTONREPEAT;
1523 ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
1524 ImplDrawPushButton();
1525 StartTracking( nTrackFlags );
1527 if ( nTrackFlags & STARTTRACK_BUTTONREPEAT )
1528 Click();
1532 // -----------------------------------------------------------------------
1534 void PushButton::Tracking( const TrackingEvent& rTEvt )
1536 if ( rTEvt.IsTrackingEnded() )
1538 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
1540 if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() )
1541 GrabFocus();
1543 if ( GetStyle() & WB_TOGGLE )
1545 // Don't toggle, when aborted
1546 if ( !rTEvt.IsTrackingCanceled() )
1548 if ( IsChecked() )
1550 Check( FALSE );
1551 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
1553 else
1554 Check( TRUE );
1557 else
1558 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
1560 ImplDrawPushButton();
1562 // Bei Abbruch kein Click-Handler rufen
1563 if ( !rTEvt.IsTrackingCanceled() )
1565 if ( ! ( ( GetStyle() & WB_REPEAT ) &&
1566 ! ( GetStyle() & WB_TOGGLE ) ) )
1567 Click();
1571 else
1573 if ( ImplHitTestPushButton( this, rTEvt.GetMouseEvent().GetPosPixel() ) )
1575 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
1577 if ( rTEvt.IsTrackingRepeat() && (GetStyle() & WB_REPEAT) &&
1578 ! ( GetStyle() & WB_TOGGLE ) )
1579 Click();
1581 else
1583 ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
1584 ImplDrawPushButton();
1587 else
1589 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
1591 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
1592 ImplDrawPushButton();
1598 // -----------------------------------------------------------------------
1600 void PushButton::KeyInput( const KeyEvent& rKEvt )
1602 KeyCode aKeyCode = rKEvt.GetKeyCode();
1604 if ( !aKeyCode.GetModifier() &&
1605 ((aKeyCode.GetCode() == KEY_RETURN) || (aKeyCode.GetCode() == KEY_SPACE)) )
1607 if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) )
1609 ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
1610 ImplDrawPushButton();
1613 if ( ( GetStyle() & WB_REPEAT ) &&
1614 ! ( GetStyle() & WB_TOGGLE ) )
1615 Click();
1617 else if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_ESCAPE) )
1619 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
1620 ImplDrawPushButton();
1622 else
1623 Button::KeyInput( rKEvt );
1626 // -----------------------------------------------------------------------
1628 void PushButton::KeyUp( const KeyEvent& rKEvt )
1630 KeyCode aKeyCode = rKEvt.GetKeyCode();
1632 if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) &&
1633 ((aKeyCode.GetCode() == KEY_RETURN) || (aKeyCode.GetCode() == KEY_SPACE)) )
1635 if ( GetStyle() & WB_TOGGLE )
1637 if ( IsChecked() )
1639 Check( FALSE );
1640 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
1642 else
1643 Check( TRUE );
1645 Toggle();
1647 else
1648 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
1650 ImplDrawPushButton();
1652 if ( !( ( GetStyle() & WB_REPEAT ) &&
1653 ! ( GetStyle() & WB_TOGGLE ) ) )
1654 Click();
1656 else
1657 Button::KeyUp( rKEvt );
1660 // -----------------------------------------------------------------------
1662 void PushButton::FillLayoutData() const
1664 mpLayoutData = new vcl::ControlLayoutData();
1665 const_cast<PushButton*>(this)->ImplDrawPushButton( true );
1668 // -----------------------------------------------------------------------
1670 void PushButton::Paint( const Rectangle& )
1672 ImplDrawPushButton();
1675 // -----------------------------------------------------------------------
1677 void PushButton::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
1678 ULONG nFlags )
1680 Point aPos = pDev->LogicToPixel( rPos );
1681 Size aSize = pDev->LogicToPixel( rSize );
1682 Rectangle aRect( aPos, aSize );
1683 Rectangle aTextRect;
1684 Font aFont = GetDrawPixelFont( pDev );
1686 pDev->Push();
1687 pDev->SetMapMode();
1688 pDev->SetFont( aFont );
1689 if ( nFlags & WINDOW_DRAW_MONO )
1691 pDev->SetTextColor( Color( COL_BLACK ) );
1693 else
1695 pDev->SetTextColor( GetTextColor() );
1697 // DecoView uses the FaceColor...
1698 AllSettings aSettings = pDev->GetSettings();
1699 StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1700 if ( IsControlBackground() )
1701 aStyleSettings.SetFaceColor( GetControlBackground() );
1702 else
1703 aStyleSettings.SetFaceColor( GetSettings().GetStyleSettings().GetFaceColor() );
1704 aSettings.SetStyleSettings( aStyleSettings );
1705 pDev->SetSettings( aSettings );
1707 pDev->SetTextFillColor();
1709 DecorationView aDecoView( pDev );
1710 USHORT nButtonStyle = 0;
1711 if ( nFlags & WINDOW_DRAW_MONO )
1712 nButtonStyle |= BUTTON_DRAW_MONO;
1713 if ( IsChecked() )
1714 nButtonStyle |= BUTTON_DRAW_CHECKED;
1715 aRect = aDecoView.DrawButton( aRect, nButtonStyle );
1717 ImplDrawPushButtonContent( pDev, nFlags, aRect, false );
1718 pDev->Pop();
1721 // -----------------------------------------------------------------------
1723 void PushButton::Resize()
1725 Control::Resize();
1726 Invalidate();
1729 // -----------------------------------------------------------------------
1731 void PushButton::GetFocus()
1733 ShowFocus( ImplGetFocusRect() );
1734 SetInputContext( InputContext( GetFont() ) );
1735 Button::GetFocus();
1738 // -----------------------------------------------------------------------
1740 void PushButton::LoseFocus()
1742 EndSelection();
1743 HideFocus();
1744 Button::LoseFocus();
1747 // -----------------------------------------------------------------------
1749 void PushButton::StateChanged( StateChangedType nType )
1751 Button::StateChanged( nType );
1753 if ( (nType == STATE_CHANGE_ENABLE) ||
1754 (nType == STATE_CHANGE_TEXT) ||
1755 (nType == STATE_CHANGE_IMAGE) ||
1756 (nType == STATE_CHANGE_DATA) ||
1757 (nType == STATE_CHANGE_STATE) ||
1758 (nType == STATE_CHANGE_UPDATEMODE) )
1760 if ( IsReallyVisible() && IsUpdateMode() )
1761 Invalidate();
1763 else if ( nType == STATE_CHANGE_STYLE )
1765 SetStyle( ImplInitStyle( GetWindow( WINDOW_PREV ), GetStyle() ) );
1767 bool bIsDefButton = ( GetStyle() & WB_DEFBUTTON ) != 0;
1768 bool bWasDefButton = ( GetPrevStyle() & WB_DEFBUTTON ) != 0;
1769 if ( bIsDefButton != bWasDefButton )
1770 ImplSetDefButton( bIsDefButton );
1772 if ( IsReallyVisible() && IsUpdateMode() )
1774 if ( (GetPrevStyle() & PUSHBUTTON_VIEW_STYLE) !=
1775 (GetStyle() & PUSHBUTTON_VIEW_STYLE) )
1776 Invalidate();
1779 else if ( (nType == STATE_CHANGE_ZOOM) ||
1780 (nType == STATE_CHANGE_CONTROLFONT) )
1782 ImplInitSettings( TRUE, FALSE, FALSE );
1783 Invalidate();
1785 else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
1787 ImplInitSettings( FALSE, TRUE, FALSE );
1788 Invalidate();
1790 else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
1792 ImplInitSettings( FALSE, FALSE, TRUE );
1793 Invalidate();
1797 // -----------------------------------------------------------------------
1799 void PushButton::DataChanged( const DataChangedEvent& rDCEvt )
1801 Button::DataChanged( rDCEvt );
1803 if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
1804 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
1805 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
1806 (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
1808 ImplInitSettings( TRUE, TRUE, TRUE );
1809 Invalidate();
1813 // -----------------------------------------------------------------------
1815 long PushButton::PreNotify( NotifyEvent& rNEvt )
1817 long nDone = 0;
1818 const MouseEvent* pMouseEvt = NULL;
1820 if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL )
1822 if( pMouseEvt->IsEnterWindow() || pMouseEvt->IsLeaveWindow() )
1824 // trigger redraw as mouse over state has changed
1826 // TODO: move this to Window class or make it a member !!!
1827 ControlType aCtrlType = 0;
1828 switch( GetParent()->GetType() )
1830 case WINDOW_LISTBOX:
1831 case WINDOW_MULTILISTBOX:
1832 case WINDOW_TREELISTBOX:
1833 aCtrlType = CTRL_LISTBOX;
1834 break;
1836 case WINDOW_COMBOBOX:
1837 case WINDOW_PATTERNBOX:
1838 case WINDOW_NUMERICBOX:
1839 case WINDOW_METRICBOX:
1840 case WINDOW_CURRENCYBOX:
1841 case WINDOW_DATEBOX:
1842 case WINDOW_TIMEBOX:
1843 case WINDOW_LONGCURRENCYBOX:
1844 aCtrlType = CTRL_COMBOBOX;
1845 break;
1846 default:
1847 break;
1850 BOOL bDropDown = ( IsSymbol() && (GetSymbol()==SYMBOL_SPIN_DOWN) && !GetText().Len() );
1852 if( bDropDown && GetParent()->IsNativeControlSupported( aCtrlType, PART_ENTIRE_CONTROL) &&
1853 !GetParent()->IsNativeControlSupported( aCtrlType, PART_BUTTON_DOWN) )
1855 Window *pBorder = GetParent()->GetWindow( WINDOW_BORDER );
1856 if(aCtrlType == CTRL_COMBOBOX)
1858 // only paint the button part to avoid flickering of the combobox text
1859 Point aPt;
1860 Rectangle aClipRect( aPt, GetOutputSizePixel() );
1861 aClipRect.SetPos(pBorder->ScreenToOutputPixel(OutputToScreenPixel(aClipRect.TopLeft())));
1862 pBorder->Invalidate( aClipRect );
1864 else
1866 pBorder->Invalidate( INVALIDATE_NOERASE );
1867 pBorder->Update();
1870 else if( IsNativeControlSupported(CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL) )
1872 Invalidate();
1877 return nDone ? nDone : Button::PreNotify(rNEvt);
1880 // -----------------------------------------------------------------------
1882 void PushButton::Toggle()
1884 ImplCallEventListenersAndHandler( VCLEVENT_PUSHBUTTON_TOGGLE, maToggleHdl, this );
1887 // -----------------------------------------------------------------------
1889 void PushButton::SetSymbol( SymbolType eSymbol )
1891 if ( meSymbol != eSymbol )
1893 meSymbol = eSymbol;
1894 StateChanged( STATE_CHANGE_DATA );
1898 // -----------------------------------------------------------------------
1899 void PushButton::SetSymbolAlign( SymbolAlign eAlign )
1901 ImplSetSymbolAlign( eAlign );
1904 // -----------------------------------------------------------------------
1905 SymbolAlign PushButton::GetSymbolAlign() const
1907 return ImplGetSymbolAlign();
1910 // -----------------------------------------------------------------------
1912 void PushButton::SetDropDown( USHORT nStyle )
1914 if ( mnDDStyle != nStyle )
1916 mnDDStyle = nStyle;
1917 StateChanged( STATE_CHANGE_DATA );
1921 // -----------------------------------------------------------------------
1923 void PushButton::SetState( TriState eState )
1925 if ( meState != eState )
1927 meState = eState;
1928 if ( meState == STATE_NOCHECK )
1929 ImplGetButtonState() &= ~(BUTTON_DRAW_CHECKED | BUTTON_DRAW_DONTKNOW);
1930 else if ( meState == STATE_CHECK )
1932 ImplGetButtonState() &= ~BUTTON_DRAW_DONTKNOW;
1933 ImplGetButtonState() |= BUTTON_DRAW_CHECKED;
1935 else // STATE_DONTKNOW
1937 ImplGetButtonState() &= ~BUTTON_DRAW_CHECKED;
1938 ImplGetButtonState() |= BUTTON_DRAW_DONTKNOW;
1941 StateChanged( STATE_CHANGE_STATE );
1942 Toggle();
1946 // -----------------------------------------------------------------------
1948 void PushButton::SetPressed( BOOL bPressed )
1950 if ( mbPressed != bPressed )
1952 mbPressed = bPressed;
1953 StateChanged( STATE_CHANGE_DATA );
1957 // -----------------------------------------------------------------------
1959 void PushButton::EndSelection()
1961 EndTracking( ENDTRACK_CANCEL );
1962 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
1964 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
1965 if ( !mbPressed )
1966 ImplDrawPushButton();
1970 // -----------------------------------------------------------------------
1972 Size PushButton::CalcMinimumSize( long nMaxWidth ) const
1974 Size aSize;
1976 if ( IsSymbol() )
1978 if ( IsSmallSymbol ())
1979 aSize = Size( 16, 12 );
1980 else
1981 aSize = Size( 26, 24 );
1983 else if ( IsImage() && ! (ImplGetButtonState() & BUTTON_DRAW_NOIMAGE) )
1984 aSize = GetModeImage().GetSizePixel();
1985 if ( PushButton::GetText().Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
1987 ULONG nDrawFlags = 0;
1988 Size textSize = GetTextRect( Rectangle( Point(), Size( nMaxWidth ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ),
1989 PushButton::GetText(), ImplGetTextStyle( nDrawFlags ) ).GetSize();
1990 aSize.Width() += int( textSize.Width () * 1.15 );
1991 aSize.Height() = std::max( aSize.Height(), long( textSize.Height() * 1.15 ) );
1994 // cf. ImplDrawPushButton ...
1995 aSize.Width() += 8;
1996 aSize.Height() += 8;
1998 return CalcWindowSize( aSize );
2001 Size PushButton::GetOptimalSize(WindowSizeType eType) const
2003 switch (eType) {
2004 case WINDOWSIZE_MINIMUM: {
2005 return CalcMinimumSize();
2007 default:
2008 return Button::GetOptimalSize( eType );
2012 // =======================================================================
2014 void OKButton::ImplInit( Window* pParent, WinBits nStyle )
2016 PushButton::ImplInit( pParent, nStyle );
2018 SetText( Button::GetStandardText( BUTTON_OK ) );
2019 SetHelpText( Button::GetStandardHelpText( BUTTON_OK ) );
2022 // -----------------------------------------------------------------------
2024 OKButton::OKButton( Window* pParent, WinBits nStyle ) :
2025 PushButton( WINDOW_OKBUTTON )
2027 ImplInit( pParent, nStyle );
2030 // -----------------------------------------------------------------------
2032 OKButton::OKButton( Window* pParent, const ResId& rResId ) :
2033 PushButton( WINDOW_OKBUTTON )
2035 rResId.SetRT( RSC_OKBUTTON );
2036 WinBits nStyle = ImplInitRes( rResId );
2037 ImplInit( pParent, nStyle );
2038 ImplLoadRes( rResId );
2040 if ( !(nStyle & WB_HIDE) )
2041 Show();
2044 // -----------------------------------------------------------------------
2046 void OKButton::Click()
2048 // Ist kein Link gesetzt, dann schliesse Parent
2049 if ( !GetClickHdl() )
2051 Window* pParent = GetParent();
2052 if ( pParent->IsSystemWindow() )
2054 if ( pParent->IsDialog() )
2056 if ( ((Dialog*)pParent)->IsInExecute() )
2057 ((Dialog*)pParent)->EndDialog( TRUE );
2058 // gegen rekursive Aufrufe schuetzen
2059 else if ( !((Dialog*)pParent)->IsInClose() )
2061 if ( pParent->GetStyle() & WB_CLOSEABLE )
2062 ((Dialog*)pParent)->Close();
2065 else
2067 if ( pParent->GetStyle() & WB_CLOSEABLE )
2068 ((SystemWindow*)pParent)->Close();
2072 else
2074 PushButton::Click();
2078 // =======================================================================
2080 void CancelButton::ImplInit( Window* pParent, WinBits nStyle )
2082 PushButton::ImplInit( pParent, nStyle );
2084 SetText( Button::GetStandardText( BUTTON_CANCEL ) );
2085 SetHelpText( Button::GetStandardHelpText( BUTTON_CANCEL ) );
2088 // -----------------------------------------------------------------------
2090 CancelButton::CancelButton( Window* pParent, WinBits nStyle ) :
2091 PushButton( WINDOW_CANCELBUTTON )
2093 ImplInit( pParent, nStyle );
2096 // -----------------------------------------------------------------------
2098 CancelButton::CancelButton( Window* pParent, const ResId& rResId ) :
2099 PushButton( WINDOW_CANCELBUTTON )
2101 rResId.SetRT( RSC_CANCELBUTTON );
2102 WinBits nStyle = ImplInitRes( rResId );
2103 ImplInit( pParent, nStyle );
2104 ImplLoadRes( rResId );
2106 if ( !(nStyle & WB_HIDE) )
2107 Show();
2110 // -----------------------------------------------------------------------
2112 void CancelButton::Click()
2114 // Ist kein Link gesetzt, dann schliesse Parent
2115 if ( !GetClickHdl() )
2117 Window* pParent = GetParent();
2118 if ( pParent->IsSystemWindow() )
2120 if ( pParent->IsDialog() )
2122 if ( ((Dialog*)pParent)->IsInExecute() )
2123 ((Dialog*)pParent)->EndDialog( FALSE );
2124 // gegen rekursive Aufrufe schuetzen
2125 else if ( !((Dialog*)pParent)->IsInClose() )
2127 if ( pParent->GetStyle() & WB_CLOSEABLE )
2128 ((Dialog*)pParent)->Close();
2131 else
2133 if ( pParent->GetStyle() & WB_CLOSEABLE )
2134 ((SystemWindow*)pParent)->Close();
2138 else
2140 PushButton::Click();
2144 // =======================================================================
2146 void HelpButton::ImplInit( Window* pParent, WinBits nStyle )
2148 PushButton::ImplInit( pParent, nStyle | WB_NOPOINTERFOCUS );
2150 SetText( Button::GetStandardText( BUTTON_HELP ) );
2151 SetHelpText( Button::GetStandardHelpText( BUTTON_HELP ) );
2154 // -----------------------------------------------------------------------
2156 HelpButton::HelpButton( Window* pParent, WinBits nStyle ) :
2157 PushButton( WINDOW_HELPBUTTON )
2159 ImplInit( pParent, nStyle );
2162 // -----------------------------------------------------------------------
2164 HelpButton::HelpButton( Window* pParent, const ResId& rResId ) :
2165 PushButton( WINDOW_HELPBUTTON )
2167 rResId.SetRT( RSC_HELPBUTTON );
2168 WinBits nStyle = ImplInitRes( rResId );
2169 ImplInit( pParent, nStyle );
2170 ImplLoadRes( rResId );
2172 if ( !(nStyle & WB_HIDE) )
2173 Show();
2176 // -----------------------------------------------------------------------
2178 void HelpButton::Click()
2180 // Ist kein Link gesetzt, loese Hilfe aus
2181 if ( !GetClickHdl() )
2183 Window* pFocusWin = Application::GetFocusWindow();
2184 if ( !pFocusWin )
2185 pFocusWin = this;
2187 HelpEvent aEvt( pFocusWin->GetPointerPosPixel(), HELPMODE_CONTEXT );
2188 pFocusWin->RequestHelp( aEvt );
2190 PushButton::Click();
2193 // =======================================================================
2195 void RadioButton::ImplInitRadioButtonData()
2197 mbChecked = FALSE;
2198 mbSaveValue = FALSE;
2199 mbRadioCheck = TRUE;
2200 mbStateChanged = FALSE;
2203 // -----------------------------------------------------------------------
2205 void RadioButton::ImplInit( Window* pParent, WinBits nStyle )
2207 nStyle = ImplInitStyle( pParent->GetWindow( WINDOW_LASTCHILD ), nStyle );
2208 Button::ImplInit( pParent, nStyle, NULL );
2210 ImplInitSettings( TRUE, TRUE, TRUE );
2213 // -----------------------------------------------------------------------
2215 WinBits RadioButton::ImplInitStyle( const Window* pPrevWindow, WinBits nStyle )
2217 if ( !(nStyle & WB_NOGROUP) &&
2218 (!pPrevWindow || (pPrevWindow->GetType() != WINDOW_RADIOBUTTON)) )
2219 nStyle |= WB_GROUP;
2220 if ( !(nStyle & WB_NOTABSTOP) )
2222 if ( IsChecked() )
2223 nStyle |= WB_TABSTOP;
2224 else
2225 nStyle &= ~WB_TABSTOP;
2227 return nStyle;
2230 // -----------------------------------------------------------------------
2232 void RadioButton::ImplInitSettings( BOOL bFont,
2233 BOOL bForeground, BOOL bBackground )
2235 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
2237 if ( bFont )
2239 Font aFont = rStyleSettings.GetRadioCheckFont();
2240 if ( IsControlFont() )
2241 aFont.Merge( GetControlFont() );
2242 SetZoomedPointFont( aFont );
2245 if ( bForeground || bFont )
2247 Color aColor;
2248 if ( IsControlForeground() )
2249 aColor = GetControlForeground();
2250 else
2251 aColor = rStyleSettings.GetRadioCheckTextColor();
2252 SetTextColor( aColor );
2253 SetTextFillColor();
2256 if ( bBackground )
2258 Window* pParent = GetParent();
2259 if ( !IsControlBackground() &&
2260 (pParent->IsChildTransparentModeEnabled() || IsNativeControlSupported( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL ) ) )
2262 EnableChildTransparentMode( TRUE );
2263 SetParentClipMode( PARENTCLIPMODE_NOCLIP );
2264 SetPaintTransparent( TRUE );
2265 SetBackground();
2266 if( IsNativeControlSupported( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL ) )
2267 mpWindowImpl->mbUseNativeFocus = ImplGetSVData()->maNWFData.mbNoFocusRects;
2269 else
2271 EnableChildTransparentMode( FALSE );
2272 SetParentClipMode( 0 );
2273 SetPaintTransparent( FALSE );
2275 if ( IsControlBackground() )
2276 SetBackground( GetControlBackground() );
2277 else
2278 SetBackground( pParent->GetBackground() );
2283 //---------------------------------------------------------------------
2284 //--- 12.03.2003 18:46:14 ---------------------------------------------
2286 void RadioButton::DrawRadioButtonState( )
2288 ImplDrawRadioButtonState( );
2291 // -----------------------------------------------------------------------
2293 void RadioButton::ImplInvalidateOrDrawRadioButtonState()
2295 if( ImplGetSVData()->maNWFData.mbCheckBoxNeedsErase )
2297 if ( IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL) )
2299 Invalidate();
2300 Update();
2301 return;
2304 ImplDrawRadioButtonState();
2307 void RadioButton::ImplDrawRadioButtonState()
2309 USHORT nButtonStyle = 0;
2310 BOOL bNativeOK = FALSE;
2312 // no native drawing for image radio buttons
2313 if ( !maImage && (bNativeOK=IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL)) == TRUE )
2315 ImplControlValue aControlValue( mbChecked ? BUTTONVALUE_ON : BUTTONVALUE_OFF, rtl::OUString(), 0 );
2316 Rectangle aCtrlRect( maStateRect.TopLeft(), maStateRect.GetSize() );
2317 Region aCtrlRegion( aCtrlRect );
2318 ControlState nState = 0;
2320 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) nState |= CTRL_STATE_PRESSED;
2321 if ( HasFocus() ) nState |= CTRL_STATE_FOCUSED;
2322 if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT ) nState |= CTRL_STATE_DEFAULT;
2323 if ( IsEnabled() ) nState |= CTRL_STATE_ENABLED;
2325 if ( IsMouseOver() && maMouseRect.IsInside( GetPointerPosPixel() ) )
2326 nState |= CTRL_STATE_ROLLOVER;
2328 bNativeOK = DrawNativeControl( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion, nState,
2329 aControlValue,rtl::OUString() );
2333 if ( bNativeOK == FALSE )
2335 // kein Image-RadioButton
2336 if ( !maImage )
2338 USHORT nStyle = ImplGetButtonState();
2339 if ( !IsEnabled() )
2340 nStyle |= BUTTON_DRAW_DISABLED;
2341 if ( mbChecked )
2342 nStyle |= BUTTON_DRAW_CHECKED;
2343 Image aImage = GetRadioImage( GetSettings(), nStyle );
2344 if ( IsZoom() )
2345 DrawImage( maStateRect.TopLeft(), maStateRect.GetSize(), aImage );
2346 else
2347 DrawImage( maStateRect.TopLeft(), aImage );
2349 else
2351 HideFocus();
2353 DecorationView aDecoView( this );
2354 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
2355 Rectangle aImageRect = maStateRect;
2356 Size aImageSize = maImage.GetSizePixel();
2357 BOOL bEnabled = IsEnabled();
2359 aImageSize.Width() = CalcZoom( aImageSize.Width() );
2360 aImageSize.Height() = CalcZoom( aImageSize.Height() );
2362 // Border und Selektionsstatus ausgeben
2363 nButtonStyle = FRAME_DRAW_DOUBLEIN;
2364 aImageRect = aDecoView.DrawFrame( aImageRect, nButtonStyle );
2365 if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) || !bEnabled )
2366 SetFillColor( rStyleSettings.GetFaceColor() );
2367 else
2368 SetFillColor( rStyleSettings.GetFieldColor() );
2369 SetLineColor();
2370 DrawRect( aImageRect );
2372 // Image ausgeben
2373 nButtonStyle = 0;
2374 if ( !bEnabled )
2375 nButtonStyle |= IMAGE_DRAW_DISABLE;
2377 // check for HC mode
2378 Image *pImage = &maImage;
2379 if( !!maImageHC )
2381 if( rStyleSettings.GetHighContrastMode() )
2382 pImage = &maImageHC;
2385 Point aImagePos( aImageRect.TopLeft() );
2386 aImagePos.X() += (aImageRect.GetWidth()-aImageSize.Width())/2;
2387 aImagePos.Y() += (aImageRect.GetHeight()-aImageSize.Height())/2;
2388 if ( IsZoom() )
2389 DrawImage( aImagePos, aImageSize, *pImage, nButtonStyle );
2390 else
2391 DrawImage( aImagePos, *pImage, nButtonStyle );
2393 aImageRect.Left()++;
2394 aImageRect.Top()++;
2395 aImageRect.Right()--;
2396 aImageRect.Bottom()--;
2398 ImplSetFocusRect( aImageRect );
2400 if ( mbChecked )
2402 SetLineColor( rStyleSettings.GetHighlightColor() );
2403 SetFillColor();
2404 if ( (aImageSize.Width() >= 20) || (aImageSize.Height() >= 20) )
2406 aImageRect.Left()++;
2407 aImageRect.Top()++;
2408 aImageRect.Right()--;
2409 aImageRect.Bottom()--;
2411 DrawRect( aImageRect );
2412 aImageRect.Left()++;
2413 aImageRect.Top()++;
2414 aImageRect.Right()--;
2415 aImageRect.Bottom()--;
2416 DrawRect( aImageRect );
2419 if ( HasFocus() )
2420 ShowFocus( ImplGetFocusRect() );
2425 // -----------------------------------------------------------------------
2427 void RadioButton::ImplDraw( OutputDevice* pDev, ULONG nDrawFlags,
2428 const Point& rPos, const Size& rSize,
2429 const Size& rImageSize, long nImageSep,
2430 Rectangle& rStateRect,
2431 Rectangle& rMouseRect,
2432 bool bLayout )
2434 WinBits nWinStyle = GetStyle();
2435 XubString aText( GetText() );
2436 Rectangle aRect( rPos, rSize );
2437 MetricVector* pVector = bLayout ? &mpLayoutData->m_aUnicodeBoundRects : NULL;
2438 String* pDisplayText = bLayout ? &mpLayoutData->m_aDisplayText : NULL;
2440 pDev->Push( PUSH_CLIPREGION );
2441 pDev->IntersectClipRegion( Rectangle( rPos, rSize ) );
2443 // kein Image-RadioButton
2444 if ( !maImage )
2446 if ( ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) ) ||
2447 ( HasImage() && ! (ImplGetButtonState() & BUTTON_DRAW_NOIMAGE) ) )
2449 USHORT nTextStyle = Button::ImplGetTextStyle( aText, nWinStyle, nDrawFlags );
2451 Size aSize( rSize );
2452 Point aPos( rPos );
2454 aPos.X() += rImageSize.Width() + nImageSep;
2455 aSize.Width() -= rImageSize.Width() + nImageSep;
2457 // if the text rect height is smaller than the height of the image
2458 // then for single lines the default should be centered text
2459 if( (nWinStyle & (WB_TOP|WB_VCENTER|WB_BOTTOM)) == 0 &&
2460 (rImageSize.Height() > rSize.Height() || ! (nWinStyle & WB_WORDBREAK) ) )
2462 nTextStyle &= ~(TEXT_DRAW_TOP|TEXT_DRAW_BOTTOM);
2463 nTextStyle |= TEXT_DRAW_VCENTER;
2464 aSize.Height() = rImageSize.Height();
2467 ImplDrawAlignedImage( pDev, aPos, aSize, bLayout, 1,
2468 nDrawFlags, nTextStyle, NULL );
2470 rMouseRect = Rectangle( aPos, aSize );
2471 rMouseRect.Left() = rPos.X();
2473 rStateRect.Left() = rPos.X();
2474 rStateRect.Top() = rMouseRect.Top();
2476 if ( aSize.Height() > rImageSize.Height() )
2477 rStateRect.Top() += ( aSize.Height() - rImageSize.Height() ) / 2;
2478 else
2480 rStateRect.Top() -= ( rImageSize.Height() - aSize.Height() ) / 2;
2481 if( rStateRect.Top() < 0 )
2482 rStateRect.Top() = 0;
2485 rStateRect.Right() = rStateRect.Left() + rImageSize.Width()-1;
2486 rStateRect.Bottom() = rStateRect.Top() + rImageSize.Height()-1;
2488 if ( rStateRect.Bottom() > rMouseRect.Bottom() )
2489 rMouseRect.Bottom() = rStateRect.Bottom();
2491 else
2493 if ( nWinStyle & WB_CENTER )
2494 rStateRect.Left() = rPos.X()+((rSize.Width()-rImageSize.Width())/2);
2495 else if ( nWinStyle & WB_RIGHT )
2496 rStateRect.Left() = rPos.X()+rSize.Width()-rImageSize.Width(); //-1;
2497 else
2498 rStateRect.Left() = rPos.X(); //+1;
2499 if ( nWinStyle & WB_VCENTER )
2500 rStateRect.Top() = rPos.Y()+((rSize.Height()-rImageSize.Height())/2);
2501 else if ( nWinStyle & WB_BOTTOM )
2502 rStateRect.Top() = rPos.Y()+rSize.Height()-rImageSize.Height(); //-1;
2503 else
2504 rStateRect.Top() = rPos.Y(); //+1;
2505 rStateRect.Right() = rStateRect.Left()+rImageSize.Width()-1;
2506 rStateRect.Bottom() = rStateRect.Top()+rImageSize.Height()-1;
2507 rMouseRect = rStateRect;
2509 ImplSetFocusRect( rStateRect );
2511 /* und oben -1, da CalcSize() auch Focus-Rechteck nicht mit einrechnet,
2512 da im Writer ansonsten die Images noch weiter oben haengen
2513 rFocusRect = rStateRect;
2514 rFocusRect.Left()--;
2515 rFocusRect.Top()--;
2516 rFocusRect.Right()++;
2517 rFocusRect.Bottom()++;
2521 else
2523 BOOL bTopImage = (nWinStyle & WB_TOP) != 0;
2524 Size aImageSize = maImage.GetSizePixel();
2525 Rectangle aImageRect( rPos, rSize );
2526 long nTextHeight = pDev->GetTextHeight();
2527 long nTextWidth = pDev->GetCtrlTextWidth( aText );
2529 // Positionen und Groessen berechnen
2530 if ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
2532 Size aTmpSize( (aImageSize.Width()+8), (aImageSize.Height()+8) );
2533 if ( bTopImage )
2535 aImageRect.Left() = (rSize.Width()-aTmpSize.Width())/2;
2536 aImageRect.Top() = (rSize.Height()-(aTmpSize.Height()+nTextHeight+6))/2;
2538 else
2539 aImageRect.Top() = (rSize.Height()-aTmpSize.Height())/2;
2541 aImageRect.Right() = aImageRect.Left()+aTmpSize.Width();
2542 aImageRect.Bottom() = aImageRect.Top()+aTmpSize.Height();
2544 // Text ausgeben
2545 Point aTxtPos = rPos;
2546 if ( bTopImage )
2548 aTxtPos.X() += (rSize.Width()-nTextWidth)/2;
2549 aTxtPos.Y() += aImageRect.Bottom()+6;
2551 else
2553 aTxtPos.X() += aImageRect.Right()+8;
2554 aTxtPos.Y() += (rSize.Height()-nTextHeight)/2;
2556 pDev->DrawCtrlText( aTxtPos, aText, 0, STRING_LEN, TEXT_DRAW_MNEMONIC, pVector, pDisplayText );
2559 rMouseRect = aImageRect;
2560 rStateRect = aImageRect;
2563 pDev->Pop();
2566 // -----------------------------------------------------------------------
2568 void RadioButton::ImplDrawRadioButton( bool bLayout )
2570 if( !bLayout )
2571 HideFocus();
2573 Size aImageSize;
2574 if ( !maImage )
2575 aImageSize = ImplGetRadioImageSize();
2576 else
2577 aImageSize = maImage.GetSizePixel();
2578 aImageSize.Width() = CalcZoom( aImageSize.Width() );
2579 aImageSize.Height() = CalcZoom( aImageSize.Height() );
2581 // Draw control text
2582 ImplDraw( this, 0, Point(), GetOutputSizePixel(),
2583 aImageSize, IMPL_SEP_BUTTON_IMAGE, maStateRect, maMouseRect, bLayout );
2585 if( !bLayout || (IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL)==TRUE) )
2587 if ( !maImage && HasFocus() )
2588 ShowFocus( ImplGetFocusRect() );
2590 ImplDrawRadioButtonState();
2594 // -----------------------------------------------------------------------
2596 void RadioButton::GetRadioButtonGroup( std::vector< RadioButton* >& io_rGroup, bool bIncludeThis ) const
2598 // empty the list
2599 io_rGroup.clear();
2601 // go back to first in group;
2602 Window* pFirst = const_cast<RadioButton*>(this);
2603 while( ( pFirst->GetStyle() & WB_GROUP ) == 0 )
2605 Window* pWindow = pFirst->GetWindow( WINDOW_PREV );
2606 if( pWindow )
2607 pFirst = pWindow;
2608 else
2609 break;
2611 // insert radiobuttons up to next group
2614 if( pFirst->GetType() == WINDOW_RADIOBUTTON )
2616 if( pFirst != this || bIncludeThis )
2617 io_rGroup.push_back( static_cast<RadioButton*>(pFirst) );
2619 pFirst = pFirst->GetWindow( WINDOW_NEXT );
2620 } while( pFirst && ( ( pFirst->GetStyle() & WB_GROUP ) == 0 ) );
2623 // -----------------------------------------------------------------------
2625 void RadioButton::ImplUncheckAllOther()
2627 mpWindowImpl->mnStyle |= WB_TABSTOP;
2629 // Gruppe mit RadioButtons durchgehen und die gecheckten Buttons
2630 Window* pWindow;
2631 WinBits nStyle;
2632 if ( !(GetStyle() & WB_GROUP) )
2634 pWindow = GetWindow( WINDOW_PREV );
2635 while ( pWindow )
2637 nStyle = pWindow->GetStyle();
2639 if ( pWindow->GetType() == WINDOW_RADIOBUTTON )
2641 if ( ((RadioButton*)pWindow)->IsChecked() )
2643 ImplDelData aDelData;
2644 pWindow->ImplAddDel( &aDelData );
2645 ((RadioButton*)pWindow)->SetState( FALSE );
2646 if ( aDelData.IsDelete() )
2647 return;
2648 pWindow->ImplRemoveDel( &aDelData );
2650 // Um falsch gesetzt WB_TABSTOPS immer zu entfernen, nicht
2651 // innerhalb der if-Abfrage
2652 pWindow->mpWindowImpl->mnStyle &= ~WB_TABSTOP;
2655 if ( nStyle & WB_GROUP )
2656 break;
2658 pWindow = pWindow->GetWindow( WINDOW_PREV );
2662 pWindow = GetWindow( WINDOW_NEXT );
2663 while ( pWindow )
2665 nStyle = pWindow->GetStyle();
2667 if ( nStyle & WB_GROUP )
2668 break;
2670 if ( pWindow->GetType() == WINDOW_RADIOBUTTON )
2672 if ( ((RadioButton*)pWindow)->IsChecked() )
2674 ImplDelData aDelData;
2675 pWindow->ImplAddDel( &aDelData );
2676 ((RadioButton*)pWindow)->SetState( FALSE );
2677 if ( aDelData.IsDelete() )
2678 return;
2679 pWindow->ImplRemoveDel( &aDelData );
2681 // Um falsch gesetzt WB_TABSTOPS immer zu entfernen, nicht
2682 // innerhalb der if-Abfrage
2683 pWindow->mpWindowImpl->mnStyle &= ~WB_TABSTOP;
2686 pWindow = pWindow->GetWindow( WINDOW_NEXT );
2690 // -----------------------------------------------------------------------
2692 void RadioButton::ImplCallClick( BOOL bGrabFocus, USHORT nFocusFlags )
2694 mbStateChanged = !mbChecked;
2695 mbChecked = TRUE;
2696 mpWindowImpl->mnStyle |= WB_TABSTOP;
2697 ImplInvalidateOrDrawRadioButtonState();
2698 ImplDelData aDelData;
2699 ImplAddDel( &aDelData );
2700 if ( mbRadioCheck )
2701 ImplUncheckAllOther();
2702 if ( aDelData.IsDelete() )
2703 return;
2704 if ( bGrabFocus )
2705 ImplGrabFocus( nFocusFlags );
2706 if ( aDelData.IsDelete() )
2707 return;
2708 if ( mbStateChanged )
2709 Toggle();
2710 if ( aDelData.IsDelete() )
2711 return;
2712 Click();
2713 if ( aDelData.IsDelete() )
2714 return;
2715 ImplRemoveDel( &aDelData );
2716 mbStateChanged = FALSE;
2719 // -----------------------------------------------------------------------
2721 RadioButton::RadioButton( Window* pParent, WinBits nStyle ) :
2722 Button( WINDOW_RADIOBUTTON )
2724 ImplInitRadioButtonData();
2725 ImplInit( pParent, nStyle );
2728 // -----------------------------------------------------------------------
2730 RadioButton::RadioButton( Window* pParent, const ResId& rResId ) :
2731 Button( WINDOW_RADIOBUTTON )
2733 ImplInitRadioButtonData();
2734 rResId.SetRT( RSC_RADIOBUTTON );
2735 WinBits nStyle = ImplInitRes( rResId );
2736 ImplInit( pParent, nStyle );
2737 ImplLoadRes( rResId );
2739 if ( !(nStyle & WB_HIDE) )
2740 Show();
2743 // -----------------------------------------------------------------------
2745 void RadioButton::ImplLoadRes( const ResId& rResId )
2747 Button::ImplLoadRes( rResId );
2749 //anderer Wert als Default ?
2750 USHORT nChecked = ReadShortRes();
2751 if ( nChecked )
2752 SetState( TRUE );
2755 // -----------------------------------------------------------------------
2757 RadioButton::~RadioButton()
2761 // -----------------------------------------------------------------------
2763 void RadioButton::MouseButtonDown( const MouseEvent& rMEvt )
2765 if ( rMEvt.IsLeft() && maMouseRect.IsInside( rMEvt.GetPosPixel() ) )
2767 ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
2768 ImplInvalidateOrDrawRadioButtonState();
2769 StartTracking();
2770 return;
2773 Button::MouseButtonDown( rMEvt );
2776 // -----------------------------------------------------------------------
2778 void RadioButton::Tracking( const TrackingEvent& rTEvt )
2780 if ( rTEvt.IsTrackingEnded() )
2782 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
2784 if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() )
2785 GrabFocus();
2787 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
2789 // Bei Abbruch kein Click-Handler rufen
2790 if ( !rTEvt.IsTrackingCanceled() )
2791 ImplCallClick();
2792 else
2793 ImplInvalidateOrDrawRadioButtonState();
2796 else
2798 if ( maMouseRect.IsInside( rTEvt.GetMouseEvent().GetPosPixel() ) )
2800 if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) )
2802 ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
2803 ImplInvalidateOrDrawRadioButtonState();
2806 else
2808 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
2810 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
2811 ImplInvalidateOrDrawRadioButtonState();
2817 // -----------------------------------------------------------------------
2819 void RadioButton::KeyInput( const KeyEvent& rKEvt )
2821 KeyCode aKeyCode = rKEvt.GetKeyCode();
2823 if ( !aKeyCode.GetModifier() && (aKeyCode.GetCode() == KEY_SPACE) )
2825 if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) )
2827 ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
2828 ImplInvalidateOrDrawRadioButtonState();
2831 else if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_ESCAPE) )
2833 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
2834 ImplInvalidateOrDrawRadioButtonState();
2836 else
2837 Button::KeyInput( rKEvt );
2840 // -----------------------------------------------------------------------
2842 void RadioButton::KeyUp( const KeyEvent& rKEvt )
2844 KeyCode aKeyCode = rKEvt.GetKeyCode();
2846 if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_SPACE) )
2848 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
2849 ImplCallClick();
2851 else
2852 Button::KeyUp( rKEvt );
2855 // -----------------------------------------------------------------------
2857 void RadioButton::FillLayoutData() const
2859 mpLayoutData = new vcl::ControlLayoutData();
2860 const_cast<RadioButton*>(this)->ImplDrawRadioButton( true );
2863 // -----------------------------------------------------------------------
2865 void RadioButton::Paint( const Rectangle& )
2867 ImplDrawRadioButton();
2870 // -----------------------------------------------------------------------
2872 void RadioButton::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
2873 ULONG nFlags )
2875 if ( !maImage )
2877 MapMode aResMapMode( MAP_100TH_MM );
2878 Point aPos = pDev->LogicToPixel( rPos );
2879 Size aSize = pDev->LogicToPixel( rSize );
2880 Size aImageSize = pDev->LogicToPixel( Size( 300, 300 ), aResMapMode );
2881 Size aBrd1Size = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode );
2882 Size aBrd2Size = pDev->LogicToPixel( Size( 60, 60 ), aResMapMode );
2883 Font aFont = GetDrawPixelFont( pDev );
2884 Rectangle aStateRect;
2885 Rectangle aMouseRect;
2886 Rectangle aFocusRect;
2888 aImageSize.Width() = CalcZoom( aImageSize.Width() );
2889 aImageSize.Height() = CalcZoom( aImageSize.Height() );
2890 aBrd1Size.Width() = CalcZoom( aBrd1Size.Width() );
2891 aBrd1Size.Height() = CalcZoom( aBrd1Size.Height() );
2892 aBrd2Size.Width() = CalcZoom( aBrd2Size.Width() );
2893 aBrd2Size.Height() = CalcZoom( aBrd2Size.Height() );
2895 if ( !aBrd1Size.Width() )
2896 aBrd1Size.Width() = 1;
2897 if ( !aBrd1Size.Height() )
2898 aBrd1Size.Height() = 1;
2899 if ( !aBrd2Size.Width() )
2900 aBrd2Size.Width() = 1;
2901 if ( !aBrd2Size.Height() )
2902 aBrd2Size.Height() = 1;
2904 pDev->Push();
2905 pDev->SetMapMode();
2906 pDev->SetFont( aFont );
2907 if ( nFlags & WINDOW_DRAW_MONO )
2908 pDev->SetTextColor( Color( COL_BLACK ) );
2909 else
2910 pDev->SetTextColor( GetTextColor() );
2911 pDev->SetTextFillColor();
2913 ImplDraw( pDev, nFlags, aPos, aSize,
2914 aImageSize, GetDrawPixel( pDev, IMPL_SEP_BUTTON_IMAGE ),
2915 aStateRect, aMouseRect );
2917 Point aCenterPos = aStateRect.Center();
2918 long nRadX = aImageSize.Width()/2;
2919 long nRadY = aImageSize.Height()/2;
2921 pDev->SetLineColor();
2922 pDev->SetFillColor( Color( COL_BLACK ) );
2923 pDev->DrawPolygon( Polygon( aCenterPos, nRadX, nRadY ) );
2924 nRadX -= aBrd1Size.Width();
2925 nRadY -= aBrd1Size.Height();
2926 pDev->SetFillColor( Color( COL_WHITE ) );
2927 pDev->DrawPolygon( Polygon( aCenterPos, nRadX, nRadY ) );
2928 if ( mbChecked )
2930 nRadX -= aBrd1Size.Width();
2931 nRadY -= aBrd1Size.Height();
2932 if ( !nRadX )
2933 nRadX = 1;
2934 if ( !nRadY )
2935 nRadY = 1;
2936 pDev->SetFillColor( Color( COL_BLACK ) );
2937 pDev->DrawPolygon( Polygon( aCenterPos, nRadX, nRadY ) );
2940 pDev->Pop();
2942 else
2944 DBG_ERROR( "RadioButton::Draw() - not implemented for RadioButton with Image" );
2948 // -----------------------------------------------------------------------
2950 void RadioButton::Resize()
2952 Control::Resize();
2953 Invalidate();
2956 // -----------------------------------------------------------------------
2958 void RadioButton::GetFocus()
2960 ShowFocus( ImplGetFocusRect() );
2961 SetInputContext( InputContext( GetFont() ) );
2962 Button::GetFocus();
2965 // -----------------------------------------------------------------------
2967 void RadioButton::LoseFocus()
2969 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
2971 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
2972 ImplInvalidateOrDrawRadioButtonState();
2975 HideFocus();
2976 Button::LoseFocus();
2979 // -----------------------------------------------------------------------
2981 void RadioButton::StateChanged( StateChangedType nType )
2983 Button::StateChanged( nType );
2985 if ( nType == STATE_CHANGE_STATE )
2987 if ( IsReallyVisible() && IsUpdateMode() )
2988 Invalidate( maStateRect );
2990 else if ( (nType == STATE_CHANGE_ENABLE) ||
2991 (nType == STATE_CHANGE_TEXT) ||
2992 (nType == STATE_CHANGE_IMAGE) ||
2993 (nType == STATE_CHANGE_DATA) ||
2994 (nType == STATE_CHANGE_UPDATEMODE) )
2996 if ( IsUpdateMode() )
2997 Invalidate();
2999 else if ( nType == STATE_CHANGE_STYLE )
3001 SetStyle( ImplInitStyle( GetWindow( WINDOW_PREV ), GetStyle() ) );
3003 if ( (GetPrevStyle() & RADIOBUTTON_VIEW_STYLE) !=
3004 (GetStyle() & RADIOBUTTON_VIEW_STYLE) )
3006 if ( IsUpdateMode() )
3007 Invalidate();
3010 else if ( (nType == STATE_CHANGE_ZOOM) ||
3011 (nType == STATE_CHANGE_CONTROLFONT) )
3013 ImplInitSettings( TRUE, FALSE, FALSE );
3014 Invalidate();
3016 else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
3018 ImplInitSettings( FALSE, TRUE, FALSE );
3019 Invalidate();
3021 else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
3023 ImplInitSettings( FALSE, FALSE, TRUE );
3024 Invalidate();
3028 // -----------------------------------------------------------------------
3030 void RadioButton::DataChanged( const DataChangedEvent& rDCEvt )
3032 Button::DataChanged( rDCEvt );
3034 if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
3035 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
3036 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
3037 (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
3039 ImplInitSettings( TRUE, TRUE, TRUE );
3040 Invalidate();
3044 // -----------------------------------------------------------------------
3046 long RadioButton::PreNotify( NotifyEvent& rNEvt )
3048 long nDone = 0;
3049 const MouseEvent* pMouseEvt = NULL;
3051 if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL )
3053 if( !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() )
3055 // trigger redraw if mouse over state has changed
3056 if( IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL) )
3058 if( ( maMouseRect.IsInside( GetPointerPosPixel()) &&
3059 !maMouseRect.IsInside( GetLastPointerPosPixel()) ) ||
3060 ( maMouseRect.IsInside( GetLastPointerPosPixel()) &&
3061 !maMouseRect.IsInside( GetPointerPosPixel()) ) ||
3062 pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow() )
3064 Invalidate( maStateRect );
3070 return nDone ? nDone : Button::PreNotify(rNEvt);
3073 // -----------------------------------------------------------------------
3075 void RadioButton::Toggle()
3077 ImplCallEventListenersAndHandler( VCLEVENT_RADIOBUTTON_TOGGLE, maToggleHdl, this );
3080 // -----------------------------------------------------------------------
3082 BOOL RadioButton::SetModeRadioImage( const Image& rImage, BmpColorMode eMode )
3084 if( eMode == BMP_COLOR_NORMAL )
3086 if ( rImage != maImage )
3088 maImage = rImage;
3089 StateChanged( STATE_CHANGE_DATA );
3092 else if( eMode == BMP_COLOR_HIGHCONTRAST )
3094 if( maImageHC != rImage )
3096 maImageHC = rImage;
3097 StateChanged( STATE_CHANGE_DATA );
3100 else
3101 return FALSE;
3103 return TRUE;
3106 // -----------------------------------------------------------------------
3108 const Image& RadioButton::GetModeRadioImage( BmpColorMode eMode ) const
3110 if( eMode == BMP_COLOR_HIGHCONTRAST )
3111 return maImageHC;
3112 else
3113 return maImage;
3116 // -----------------------------------------------------------------------
3118 void RadioButton::SetState( BOOL bCheck )
3120 // TabStop-Flag richtig mitfuehren
3121 if ( bCheck )
3122 mpWindowImpl->mnStyle |= WB_TABSTOP;
3123 else
3124 mpWindowImpl->mnStyle &= ~WB_TABSTOP;
3126 if ( mbChecked != bCheck )
3128 mbChecked = bCheck;
3129 StateChanged( STATE_CHANGE_STATE );
3130 Toggle();
3134 // -----------------------------------------------------------------------
3136 void RadioButton::Check( BOOL bCheck )
3138 // TabStop-Flag richtig mitfuehren
3139 if ( bCheck )
3140 mpWindowImpl->mnStyle |= WB_TABSTOP;
3141 else
3142 mpWindowImpl->mnStyle &= ~WB_TABSTOP;
3144 if ( mbChecked != bCheck )
3146 mbChecked = bCheck;
3147 ImplDelData aDelData;
3148 ImplAddDel( &aDelData );
3149 StateChanged( STATE_CHANGE_STATE );
3150 if ( aDelData.IsDelete() )
3151 return;
3152 if ( bCheck && mbRadioCheck )
3153 ImplUncheckAllOther();
3154 if ( aDelData.IsDelete() )
3155 return;
3156 Toggle();
3157 ImplRemoveDel( &aDelData );
3161 // -----------------------------------------------------------------------
3163 Size RadioButton::ImplGetRadioImageSize() const
3165 Size aSize;
3166 // why are IsNativeControlSupported and GetNativeControlRegion not const ?
3167 RadioButton* pThis = const_cast<RadioButton*>(this);
3168 bool bDefaultSize = true;
3169 if( pThis->IsNativeControlSupported( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL ) )
3171 ImplControlValue aControlValue;
3172 // #i45896# workaround gcc3.3 temporary problem
3173 Region aCtrlRegion = Region( Rectangle( Point( 0, 0 ), GetSizePixel() ) );
3174 ControlState nState = CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED;
3175 Region aBoundingRgn, aContentRgn;
3177 // get native size of a radio button
3178 if( pThis->GetNativeControlRegion( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion,
3179 nState, aControlValue, rtl::OUString(),
3180 aBoundingRgn, aContentRgn ) )
3182 Rectangle aCont(aContentRgn.GetBoundRect());
3183 aSize = aCont.GetSize();
3184 bDefaultSize = false;
3187 if( bDefaultSize )
3188 aSize = GetRadioImage( GetSettings(), 0 ).GetSizePixel();
3189 return aSize;
3192 static void LoadThemedImageList (const StyleSettings &rStyleSettings,
3193 ImageList *pList, const ResId &rResId,
3194 USHORT nImages)
3196 Color aColorAry1[6];
3197 Color aColorAry2[6];
3198 aColorAry1[0] = Color( 0xC0, 0xC0, 0xC0 );
3199 aColorAry1[1] = Color( 0xFF, 0xFF, 0x00 );
3200 aColorAry1[2] = Color( 0xFF, 0xFF, 0xFF );
3201 aColorAry1[3] = Color( 0x80, 0x80, 0x80 );
3202 aColorAry1[4] = Color( 0x00, 0x00, 0x00 );
3203 aColorAry1[5] = Color( 0x00, 0xFF, 0x00 );
3204 aColorAry2[0] = rStyleSettings.GetFaceColor();
3205 aColorAry2[1] = rStyleSettings.GetWindowColor();
3206 aColorAry2[2] = rStyleSettings.GetLightColor();
3207 aColorAry2[3] = rStyleSettings.GetShadowColor();
3208 aColorAry2[4] = rStyleSettings.GetDarkShadowColor();
3209 aColorAry2[5] = rStyleSettings.GetWindowTextColor();
3211 Color aMaskColor(0x00, 0x00, 0xFF );
3212 DBG_ASSERT( sizeof(aColorAry1) == sizeof(aColorAry2), "aColorAry1 must match aColorAry2" );
3213 // FIXME: do we want the mask for the checkbox ?
3214 pList->InsertFromHorizontalBitmap (rResId, nImages, &aMaskColor,
3215 aColorAry1, aColorAry2, sizeof(aColorAry1) / sizeof(Color));
3218 Image RadioButton::GetRadioImage( const AllSettings& rSettings, USHORT nFlags )
3220 ImplSVData* pSVData = ImplGetSVData();
3221 const StyleSettings& rStyleSettings = rSettings.GetStyleSettings();
3222 USHORT nStyle = rStyleSettings.GetRadioButtonStyle() & STYLE_RADIOBUTTON_STYLE;
3224 if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO )
3225 nStyle = STYLE_RADIOBUTTON_MONO;
3227 if ( !pSVData->maCtrlData.mpRadioImgList ||
3228 (pSVData->maCtrlData.mnRadioStyle != nStyle) ||
3229 (pSVData->maCtrlData.mnLastRadioFColor != rStyleSettings.GetFaceColor().GetColor()) ||
3230 (pSVData->maCtrlData.mnLastRadioWColor != rStyleSettings.GetWindowColor().GetColor()) ||
3231 (pSVData->maCtrlData.mnLastRadioLColor != rStyleSettings.GetLightColor().GetColor()) )
3233 if ( pSVData->maCtrlData.mpRadioImgList )
3234 delete pSVData->maCtrlData.mpRadioImgList;
3236 pSVData->maCtrlData.mnLastRadioFColor = rStyleSettings.GetFaceColor().GetColor();
3237 pSVData->maCtrlData.mnLastRadioWColor = rStyleSettings.GetWindowColor().GetColor();
3238 pSVData->maCtrlData.mnLastRadioLColor = rStyleSettings.GetLightColor().GetColor();
3240 Color pColorAry1[6];
3241 Color pColorAry2[6];
3242 pColorAry1[0] = Color( 0xC0, 0xC0, 0xC0 );
3243 pColorAry1[1] = Color( 0xFF, 0xFF, 0x00 );
3244 pColorAry1[2] = Color( 0xFF, 0xFF, 0xFF );
3245 pColorAry1[3] = Color( 0x80, 0x80, 0x80 );
3246 pColorAry1[4] = Color( 0x00, 0x00, 0x00 );
3247 pColorAry1[5] = Color( 0x00, 0xFF, 0x00 );
3248 pColorAry2[0] = rStyleSettings.GetFaceColor();
3249 pColorAry2[1] = rStyleSettings.GetWindowColor();
3250 pColorAry2[2] = rStyleSettings.GetLightColor();
3251 pColorAry2[3] = rStyleSettings.GetShadowColor();
3252 pColorAry2[4] = rStyleSettings.GetDarkShadowColor();
3253 pColorAry2[5] = rStyleSettings.GetWindowTextColor();
3255 ResMgr* pResMgr = ImplGetResMgr();
3256 pSVData->maCtrlData.mpRadioImgList = new ImageList();
3257 if( pResMgr )
3258 LoadThemedImageList( rStyleSettings,
3259 pSVData->maCtrlData.mpRadioImgList,
3260 ResId( SV_RESID_BITMAP_RADIO+nStyle, *pResMgr ), 6 );
3261 pSVData->maCtrlData.mnRadioStyle = nStyle;
3264 USHORT nId;
3265 if ( nFlags & BUTTON_DRAW_DISABLED )
3267 if ( nFlags & BUTTON_DRAW_CHECKED )
3268 nId = 6;
3269 else
3270 nId = 5;
3272 else if ( nFlags & BUTTON_DRAW_PRESSED )
3274 if ( nFlags & BUTTON_DRAW_CHECKED )
3275 nId = 4;
3276 else
3277 nId = 3;
3279 else
3281 if ( nFlags & BUTTON_DRAW_CHECKED )
3282 nId = 2;
3283 else
3284 nId = 1;
3286 return pSVData->maCtrlData.mpRadioImgList->GetImage( nId );
3289 // -----------------------------------------------------------------------
3291 void RadioButton::ImplSetMinimumNWFSize()
3293 Push( PUSH_MAPMODE );
3294 SetMapMode( MAP_PIXEL );
3296 ImplControlValue aControlValue;
3297 Size aCurSize( GetSizePixel() );
3298 Region aCtrlRegion = Region( Rectangle( Point( 0, 0 ), aCurSize ) );
3299 Region aBoundingRgn, aContentRgn;
3301 // get native size of a radiobutton
3302 if( GetNativeControlRegion( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion,
3303 CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED, aControlValue, rtl::OUString(),
3304 aBoundingRgn, aContentRgn ) )
3306 Rectangle aCont(aContentRgn.GetBoundRect());
3307 Size aSize = aCont.GetSize();
3309 if( aSize.Height() > aCurSize.Height() )
3311 aCurSize.Height() = aSize.Height();
3312 SetSizePixel( aCurSize );
3316 Pop();
3319 // -----------------------------------------------------------------------
3321 Size RadioButton::CalcMinimumSize( long nMaxWidth ) const
3323 Size aSize;
3324 if ( !maImage )
3325 aSize = ImplGetRadioImageSize();
3326 else
3327 aSize = maImage.GetSizePixel();
3329 nMaxWidth -= aSize.Width();
3331 XubString aText = GetText();
3332 if ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
3334 // subtract what will be added later
3335 nMaxWidth-=2;
3336 nMaxWidth -= IMPL_SEP_BUTTON_IMAGE;
3338 Size aTextSize = GetTextRect( Rectangle( Point(), Size( nMaxWidth > 0 ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ),
3339 aText, FixedText::ImplGetTextStyle( GetStyle() ) ).GetSize();
3340 aSize.Width()+=2; // for focus rect
3341 aSize.Width() += IMPL_SEP_BUTTON_IMAGE;
3342 aSize.Width() += aTextSize.Width();
3343 if ( aSize.Height() < aTextSize.Height() )
3344 aSize.Height() = aTextSize.Height();
3346 else if ( !maImage )
3348 /* da ansonsten im Writer die Control zu weit oben haengen
3349 aSize.Width() += 2;
3350 aSize.Height() += 2;
3354 return CalcWindowSize( aSize );
3357 // -----------------------------------------------------------------------
3359 Size RadioButton::GetOptimalSize(WindowSizeType eType) const
3361 switch (eType) {
3362 case WINDOWSIZE_MINIMUM:
3363 return CalcMinimumSize();
3364 default:
3365 return Button::GetOptimalSize( eType );
3369 // =======================================================================
3371 void CheckBox::ImplInitCheckBoxData()
3373 meState = STATE_NOCHECK;
3374 meSaveValue = STATE_NOCHECK;
3375 mbTriState = FALSE;
3378 // -----------------------------------------------------------------------
3380 void CheckBox::ImplInit( Window* pParent, WinBits nStyle )
3382 nStyle = ImplInitStyle( pParent->GetWindow( WINDOW_LASTCHILD ), nStyle );
3383 Button::ImplInit( pParent, nStyle, NULL );
3385 ImplInitSettings( TRUE, TRUE, TRUE );
3388 // -----------------------------------------------------------------------
3390 WinBits CheckBox::ImplInitStyle( const Window* pPrevWindow, WinBits nStyle )
3392 if ( !(nStyle & WB_NOTABSTOP) )
3393 nStyle |= WB_TABSTOP;
3394 if ( !(nStyle & WB_NOGROUP) &&
3395 (!pPrevWindow || (pPrevWindow->GetType() != WINDOW_CHECKBOX)) )
3396 nStyle |= WB_GROUP;
3397 return nStyle;
3400 // -----------------------------------------------------------------------
3402 void CheckBox::ImplInitSettings( BOOL bFont,
3403 BOOL bForeground, BOOL bBackground )
3405 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
3407 if ( bFont )
3409 Font aFont = rStyleSettings.GetRadioCheckFont();
3410 if ( IsControlFont() )
3411 aFont.Merge( GetControlFont() );
3412 SetZoomedPointFont( aFont );
3415 if ( bForeground || bFont )
3417 Color aColor;
3418 if ( IsControlForeground() )
3419 aColor = GetControlForeground();
3420 else
3421 aColor = rStyleSettings.GetRadioCheckTextColor();
3422 SetTextColor( aColor );
3423 SetTextFillColor();
3426 if ( bBackground )
3428 Window* pParent = GetParent();
3429 if ( !IsControlBackground() &&
3430 (pParent->IsChildTransparentModeEnabled() || IsNativeControlSupported( CTRL_CHECKBOX, PART_ENTIRE_CONTROL ) ) )
3432 EnableChildTransparentMode( TRUE );
3433 SetParentClipMode( PARENTCLIPMODE_NOCLIP );
3434 SetPaintTransparent( TRUE );
3435 SetBackground();
3436 if( IsNativeControlSupported( CTRL_CHECKBOX, PART_ENTIRE_CONTROL ) )
3437 ImplGetWindowImpl()->mbUseNativeFocus = ImplGetSVData()->maNWFData.mbNoFocusRects;
3439 else
3441 EnableChildTransparentMode( FALSE );
3442 SetParentClipMode( 0 );
3443 SetPaintTransparent( FALSE );
3445 if ( IsControlBackground() )
3446 SetBackground( GetControlBackground() );
3447 else
3448 SetBackground( pParent->GetBackground() );
3453 // -----------------------------------------------------------------------
3455 void CheckBox::ImplLoadRes( const ResId& rResId )
3457 Button::ImplLoadRes( rResId );
3459 if ( rResId.GetRT() != RSC_TRISTATEBOX )
3461 USHORT nChecked = ReadShortRes();
3462 //anderer Wert als Default ?
3463 if( nChecked )
3464 Check( TRUE );
3468 // -----------------------------------------------------------------------
3470 void CheckBox::ImplInvalidateOrDrawCheckBoxState()
3472 if( ImplGetSVData()->maNWFData.mbCheckBoxNeedsErase )
3474 if ( IsNativeControlSupported(CTRL_CHECKBOX, PART_ENTIRE_CONTROL) )
3476 Invalidate();
3477 Update();
3478 return;
3481 ImplDrawCheckBoxState();
3484 void CheckBox::ImplDrawCheckBoxState()
3486 bool bNativeOK = TRUE;
3488 if ( (bNativeOK=IsNativeControlSupported(CTRL_CHECKBOX, PART_ENTIRE_CONTROL)) == TRUE )
3490 ImplControlValue aControlValue( meState == STATE_CHECK ? BUTTONVALUE_ON : BUTTONVALUE_OFF, rtl::OUString(), 0 );
3491 Region aCtrlRegion( maStateRect );
3492 ControlState nState = 0;
3494 if ( HasFocus() ) nState |= CTRL_STATE_FOCUSED;
3495 if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT ) nState |= CTRL_STATE_DEFAULT;
3496 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) nState |= CTRL_STATE_PRESSED;
3497 if ( IsEnabled() ) nState |= CTRL_STATE_ENABLED;
3499 if ( meState == STATE_CHECK )
3500 aControlValue.setTristateVal( BUTTONVALUE_ON );
3501 else if ( meState == STATE_DONTKNOW )
3502 aControlValue.setTristateVal( BUTTONVALUE_MIXED );
3504 if ( IsMouseOver() && maMouseRect.IsInside( GetPointerPosPixel() ) )
3505 nState |= CTRL_STATE_ROLLOVER;
3507 bNativeOK = DrawNativeControl( CTRL_CHECKBOX, PART_ENTIRE_CONTROL, aCtrlRegion, nState,
3508 aControlValue, rtl::OUString() );
3511 if ( bNativeOK == FALSE )
3513 USHORT nStyle = ImplGetButtonState();
3514 if ( !IsEnabled() )
3515 nStyle |= BUTTON_DRAW_DISABLED;
3516 if ( meState == STATE_DONTKNOW )
3517 nStyle |= BUTTON_DRAW_DONTKNOW;
3518 else if ( meState == STATE_CHECK )
3519 nStyle |= BUTTON_DRAW_CHECKED;
3520 Image aImage = GetCheckImage( GetSettings(), nStyle );
3521 if ( IsZoom() )
3522 DrawImage( maStateRect.TopLeft(), maStateRect.GetSize(), aImage );
3523 else
3524 DrawImage( maStateRect.TopLeft(), aImage );
3528 // -----------------------------------------------------------------------
3530 void CheckBox::ImplDraw( OutputDevice* pDev, ULONG nDrawFlags,
3531 const Point& rPos, const Size& rSize,
3532 const Size& rImageSize, long nImageSep,
3533 Rectangle& rStateRect, Rectangle& rMouseRect,
3534 bool bLayout )
3536 WinBits nWinStyle = GetStyle();
3537 XubString aText( GetText() );
3539 pDev->Push( PUSH_CLIPREGION | PUSH_LINECOLOR );
3540 pDev->IntersectClipRegion( Rectangle( rPos, rSize ) );
3542 long nLineY = rPos.Y() + (rSize.Height()-1)/2;
3543 if ( ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) ) ||
3544 ( HasImage() && ! (ImplGetButtonState() & BUTTON_DRAW_NOIMAGE) ) )
3546 USHORT nTextStyle = Button::ImplGetTextStyle( aText, nWinStyle, nDrawFlags );
3548 Size aSize( rSize );
3549 Point aPos( rPos );
3550 aPos.X() += rImageSize.Width() + nImageSep;
3551 aSize.Width() -= rImageSize.Width() + nImageSep;
3553 // if the text rect height is smaller than the height of the image
3554 // then for single lines the default should be centered text
3555 if( (nWinStyle & (WB_TOP|WB_VCENTER|WB_BOTTOM)) == 0 &&
3556 (rImageSize.Height() > rSize.Height() || ! (nWinStyle & WB_WORDBREAK) ) )
3558 nTextStyle &= ~(TEXT_DRAW_TOP|TEXT_DRAW_BOTTOM);
3559 nTextStyle |= TEXT_DRAW_VCENTER;
3560 aSize.Height() = rImageSize.Height();
3563 ImplDrawAlignedImage( pDev, aPos, aSize, bLayout, 1,
3564 nDrawFlags, nTextStyle, NULL );
3565 nLineY = aPos.Y() + aSize.Height()/2;
3567 rMouseRect = Rectangle( aPos, aSize );
3568 rMouseRect.Left() = rPos.X();
3569 rStateRect.Left() = rPos.X();
3570 rStateRect.Top() = rMouseRect.Top();
3572 if ( aSize.Height() > rImageSize.Height() )
3573 rStateRect.Top() += ( aSize.Height() - rImageSize.Height() ) / 2;
3574 else
3576 rStateRect.Top() -= ( rImageSize.Height() - aSize.Height() ) / 2;
3577 if( rStateRect.Top() < 0 )
3578 rStateRect.Top() = 0;
3581 rStateRect.Right() = rStateRect.Left()+rImageSize.Width()-1;
3582 rStateRect.Bottom() = rStateRect.Top()+rImageSize.Height()-1;
3583 if ( rStateRect.Bottom() > rMouseRect.Bottom() )
3584 rMouseRect.Bottom() = rStateRect.Bottom();
3586 else
3588 if ( nWinStyle & WB_CENTER )
3589 rStateRect.Left() = rPos.X()+((rSize.Width()-rImageSize.Width())/2);
3590 else if ( nWinStyle & WB_RIGHT )
3591 rStateRect.Left() = rPos.X()+rSize.Width()-rImageSize.Width();
3592 else
3593 rStateRect.Left() = rPos.X();
3594 if ( nWinStyle & WB_VCENTER )
3595 rStateRect.Top() = rPos.Y()+((rSize.Height()-rImageSize.Height())/2);
3596 else if ( nWinStyle & WB_BOTTOM )
3597 rStateRect.Top() = rPos.Y()+rSize.Height()-rImageSize.Height();
3598 else
3599 rStateRect.Top() = rPos.Y();
3600 rStateRect.Right() = rStateRect.Left()+rImageSize.Width()-1;
3601 rStateRect.Bottom() = rStateRect.Top()+rImageSize.Height()-1;
3602 // provide space for focusrect
3603 // note: this assumes that the control's size was adjusted
3604 // accordingly in Get/LoseFocus, so the onscreen position won't change
3605 if( HasFocus() )
3606 rStateRect.Move( 1, 1 );
3607 rMouseRect = rStateRect;
3609 ImplSetFocusRect( rStateRect );
3612 const int nLineSpace = 4;
3613 if( (GetStyle() & WB_CBLINESTYLE) != 0 &&
3614 rMouseRect.Right()-1-nLineSpace < rPos.X()+rSize.Width() )
3616 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
3617 if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO )
3618 SetLineColor( Color( COL_BLACK ) );
3619 else
3620 SetLineColor( rStyleSettings.GetShadowColor() );
3621 long nLineX = rMouseRect.Right()+nLineSpace;
3622 DrawLine( Point( nLineX, nLineY ), Point( rPos.X() + rSize.Width()-1, nLineY ) );
3623 if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
3625 SetLineColor( rStyleSettings.GetLightColor() );
3626 DrawLine( Point( nLineX, nLineY+1 ), Point( rPos.X() + rSize.Width()-1, nLineY+1 ) );
3630 pDev->Pop();
3633 // -----------------------------------------------------------------------
3635 void CheckBox::ImplDrawCheckBox( bool bLayout )
3637 Size aImageSize = ImplGetCheckImageSize();
3638 aImageSize.Width() = CalcZoom( aImageSize.Width() );
3639 aImageSize.Height() = CalcZoom( aImageSize.Height() );
3641 if( !bLayout )
3642 HideFocus();
3644 ImplDraw( this, 0, Point(), GetOutputSizePixel(), aImageSize,
3645 IMPL_SEP_BUTTON_IMAGE, maStateRect, maMouseRect, bLayout );
3647 if( !bLayout )
3649 ImplDrawCheckBoxState();
3650 if ( HasFocus() )
3651 ShowFocus( ImplGetFocusRect() );
3655 // -----------------------------------------------------------------------
3657 void CheckBox::ImplCheck()
3659 TriState eNewState;
3660 if ( meState == STATE_NOCHECK )
3661 eNewState = STATE_CHECK;
3662 else if ( !mbTriState )
3663 eNewState = STATE_NOCHECK;
3664 else if ( meState == STATE_CHECK )
3665 eNewState = STATE_DONTKNOW;
3666 else
3667 eNewState = STATE_NOCHECK;
3668 meState = eNewState;
3669 ImplInvalidateOrDrawCheckBoxState();
3671 ImplDelData aDelData;
3672 ImplAddDel( &aDelData );
3673 Toggle();
3674 if ( aDelData.IsDelete() )
3675 return;
3676 ImplRemoveDel( &aDelData );
3677 Click();
3680 // -----------------------------------------------------------------------
3682 CheckBox::CheckBox( Window* pParent, WinBits nStyle ) :
3683 Button( WINDOW_CHECKBOX )
3685 ImplInitCheckBoxData();
3686 ImplInit( pParent, nStyle );
3689 // -----------------------------------------------------------------------
3691 CheckBox::CheckBox( Window* pParent, const ResId& rResId ) :
3692 Button( WINDOW_CHECKBOX )
3694 ImplInitCheckBoxData();
3695 rResId.SetRT( RSC_CHECKBOX );
3696 WinBits nStyle = ImplInitRes( rResId );
3697 ImplInit( pParent, nStyle );
3698 ImplLoadRes( rResId );
3700 if ( !(nStyle & WB_HIDE) )
3701 Show();
3704 // -----------------------------------------------------------------------
3706 void CheckBox::MouseButtonDown( const MouseEvent& rMEvt )
3708 if ( rMEvt.IsLeft() && maMouseRect.IsInside( rMEvt.GetPosPixel() ) )
3710 ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
3711 ImplInvalidateOrDrawCheckBoxState();
3712 StartTracking();
3713 return;
3716 Button::MouseButtonDown( rMEvt );
3719 // -----------------------------------------------------------------------
3721 void CheckBox::Tracking( const TrackingEvent& rTEvt )
3723 if ( rTEvt.IsTrackingEnded() )
3725 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
3727 if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() )
3728 GrabFocus();
3730 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
3732 // Bei Abbruch kein Click-Handler rufen
3733 if ( !rTEvt.IsTrackingCanceled() )
3734 ImplCheck();
3735 else
3736 ImplInvalidateOrDrawCheckBoxState();
3739 else
3741 if ( maMouseRect.IsInside( rTEvt.GetMouseEvent().GetPosPixel() ) )
3743 if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) )
3745 ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
3746 ImplInvalidateOrDrawCheckBoxState();
3749 else
3751 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
3753 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
3754 ImplInvalidateOrDrawCheckBoxState();
3760 // -----------------------------------------------------------------------
3762 void CheckBox::KeyInput( const KeyEvent& rKEvt )
3764 KeyCode aKeyCode = rKEvt.GetKeyCode();
3766 if ( !aKeyCode.GetModifier() && (aKeyCode.GetCode() == KEY_SPACE) )
3768 if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) )
3770 ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
3771 ImplInvalidateOrDrawCheckBoxState();
3774 else if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_ESCAPE) )
3776 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
3777 ImplInvalidateOrDrawCheckBoxState();
3779 else
3780 Button::KeyInput( rKEvt );
3783 // -----------------------------------------------------------------------
3785 void CheckBox::KeyUp( const KeyEvent& rKEvt )
3787 KeyCode aKeyCode = rKEvt.GetKeyCode();
3789 if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_SPACE) )
3791 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
3792 ImplCheck();
3794 else
3795 Button::KeyUp( rKEvt );
3798 // -----------------------------------------------------------------------
3800 void CheckBox::FillLayoutData() const
3802 mpLayoutData = new vcl::ControlLayoutData();
3803 const_cast<CheckBox*>(this)->ImplDrawCheckBox( true );
3806 // -----------------------------------------------------------------------
3808 void CheckBox::Paint( const Rectangle& )
3810 ImplDrawCheckBox();
3813 // -----------------------------------------------------------------------
3815 void CheckBox::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
3816 ULONG nFlags )
3818 MapMode aResMapMode( MAP_100TH_MM );
3819 Point aPos = pDev->LogicToPixel( rPos );
3820 Size aSize = pDev->LogicToPixel( rSize );
3821 Size aImageSize = pDev->LogicToPixel( Size( 300, 300 ), aResMapMode );
3822 Size aBrd1Size = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode );
3823 Size aBrd2Size = pDev->LogicToPixel( Size( 30, 30 ), aResMapMode );
3824 long nCheckWidth = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode ).Width();
3825 Font aFont = GetDrawPixelFont( pDev );
3826 Rectangle aStateRect;
3827 Rectangle aMouseRect;
3829 aImageSize.Width() = CalcZoom( aImageSize.Width() );
3830 aImageSize.Height() = CalcZoom( aImageSize.Height() );
3831 aBrd1Size.Width() = CalcZoom( aBrd1Size.Width() );
3832 aBrd1Size.Height() = CalcZoom( aBrd1Size.Height() );
3833 aBrd2Size.Width() = CalcZoom( aBrd2Size.Width() );
3834 aBrd2Size.Height() = CalcZoom( aBrd2Size.Height() );
3836 if ( !aBrd1Size.Width() )
3837 aBrd1Size.Width() = 1;
3838 if ( !aBrd1Size.Height() )
3839 aBrd1Size.Height() = 1;
3840 if ( !aBrd2Size.Width() )
3841 aBrd2Size.Width() = 1;
3842 if ( !aBrd2Size.Height() )
3843 aBrd2Size.Height() = 1;
3844 if ( !nCheckWidth )
3845 nCheckWidth = 1;
3847 pDev->Push();
3848 pDev->SetMapMode();
3849 pDev->SetFont( aFont );
3850 if ( nFlags & WINDOW_DRAW_MONO )
3851 pDev->SetTextColor( Color( COL_BLACK ) );
3852 else
3853 pDev->SetTextColor( GetTextColor() );
3854 pDev->SetTextFillColor();
3856 ImplDraw( pDev, nFlags, aPos, aSize,
3857 aImageSize, GetDrawPixel( pDev, IMPL_SEP_BUTTON_IMAGE ),
3858 aStateRect, aMouseRect, false );
3860 pDev->SetLineColor();
3861 pDev->SetFillColor( Color( COL_BLACK ) );
3862 pDev->DrawRect( aStateRect );
3863 aStateRect.Left() += aBrd1Size.Width();
3864 aStateRect.Top() += aBrd1Size.Height();
3865 aStateRect.Right() -= aBrd1Size.Width();
3866 aStateRect.Bottom() -= aBrd1Size.Height();
3867 if ( meState == STATE_DONTKNOW )
3868 pDev->SetFillColor( Color( COL_LIGHTGRAY ) );
3869 else
3870 pDev->SetFillColor( Color( COL_WHITE ) );
3871 pDev->DrawRect( aStateRect );
3873 if ( meState == STATE_CHECK )
3875 aStateRect.Left() += aBrd2Size.Width();
3876 aStateRect.Top() += aBrd2Size.Height();
3877 aStateRect.Right() -= aBrd2Size.Width();
3878 aStateRect.Bottom() -= aBrd2Size.Height();
3879 Point aPos11( aStateRect.TopLeft() );
3880 Point aPos12( aStateRect.BottomRight() );
3881 Point aPos21( aStateRect.TopRight() );
3882 Point aPos22( aStateRect.BottomLeft() );
3883 Point aTempPos11( aPos11 );
3884 Point aTempPos12( aPos12 );
3885 Point aTempPos21( aPos21 );
3886 Point aTempPos22( aPos22 );
3887 pDev->SetLineColor( Color( COL_BLACK ) );
3888 long nDX = 0;
3889 for ( long i = 0; i < nCheckWidth; i++ )
3891 if ( !(i % 2) )
3893 aTempPos11.X() = aPos11.X()+nDX;
3894 aTempPos12.X() = aPos12.X()+nDX;
3895 aTempPos21.X() = aPos21.X()+nDX;
3896 aTempPos22.X() = aPos22.X()+nDX;
3898 else
3900 nDX++;
3901 aTempPos11.X() = aPos11.X()-nDX;
3902 aTempPos12.X() = aPos12.X()-nDX;
3903 aTempPos21.X() = aPos21.X()-nDX;
3904 aTempPos22.X() = aPos22.X()-nDX;
3906 pDev->DrawLine( aTempPos11, aTempPos12 );
3907 pDev->DrawLine( aTempPos21, aTempPos22 );
3911 pDev->Pop();
3914 // -----------------------------------------------------------------------
3916 void CheckBox::Resize()
3918 Control::Resize();
3919 Invalidate();
3922 // -----------------------------------------------------------------------
3924 void CheckBox::GetFocus()
3926 if ( !GetText().Len() || (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
3928 // increase button size to have space for focus rect
3929 // checkboxes without text will draw focusrect around the check
3930 // See CheckBox::ImplDraw()
3931 Point aPos( GetPosPixel() );
3932 Size aSize( GetSizePixel() );
3933 aPos.Move(-1,-1);
3934 aSize.Height() += 2;
3935 aSize.Width() += 2;
3936 SetPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height(), WINDOW_POSSIZE_ALL );
3937 ImplDrawCheckBox();
3939 else
3940 ShowFocus( ImplGetFocusRect() );
3942 SetInputContext( InputContext( GetFont() ) );
3943 Button::GetFocus();
3946 // -----------------------------------------------------------------------
3948 void CheckBox::LoseFocus()
3950 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
3952 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
3953 ImplInvalidateOrDrawCheckBoxState();
3956 HideFocus();
3957 Button::LoseFocus();
3959 if ( !GetText().Len() || (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
3961 // decrease button size again (see GetFocus())
3962 // checkboxes without text will draw focusrect around the check
3963 Point aPos( GetPosPixel() );
3964 Size aSize( GetSizePixel() );
3965 aPos.Move(1,1);
3966 aSize.Height() -= 2;
3967 aSize.Width() -= 2;
3968 SetPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height(), WINDOW_POSSIZE_ALL );
3969 ImplDrawCheckBox();
3973 // -----------------------------------------------------------------------
3975 void CheckBox::StateChanged( StateChangedType nType )
3977 Button::StateChanged( nType );
3979 if ( nType == STATE_CHANGE_STATE )
3981 if ( IsReallyVisible() && IsUpdateMode() )
3982 Invalidate( maStateRect );
3984 else if ( (nType == STATE_CHANGE_ENABLE) ||
3985 (nType == STATE_CHANGE_TEXT) ||
3986 (nType == STATE_CHANGE_IMAGE) ||
3987 (nType == STATE_CHANGE_DATA) ||
3988 (nType == STATE_CHANGE_UPDATEMODE) )
3990 if ( IsUpdateMode() )
3991 Invalidate();
3993 else if ( nType == STATE_CHANGE_STYLE )
3995 SetStyle( ImplInitStyle( GetWindow( WINDOW_PREV ), GetStyle() ) );
3997 if ( (GetPrevStyle() & CHECKBOX_VIEW_STYLE) !=
3998 (GetStyle() & CHECKBOX_VIEW_STYLE) )
4000 if ( IsUpdateMode() )
4001 Invalidate();
4004 else if ( (nType == STATE_CHANGE_ZOOM) ||
4005 (nType == STATE_CHANGE_CONTROLFONT) )
4007 ImplInitSettings( TRUE, FALSE, FALSE );
4008 Invalidate();
4010 else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
4012 ImplInitSettings( FALSE, TRUE, FALSE );
4013 Invalidate();
4015 else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
4017 ImplInitSettings( FALSE, FALSE, TRUE );
4018 Invalidate();
4022 // -----------------------------------------------------------------------
4024 void CheckBox::DataChanged( const DataChangedEvent& rDCEvt )
4026 Button::DataChanged( rDCEvt );
4028 if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
4029 (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
4030 ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
4031 (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
4033 ImplInitSettings( TRUE, TRUE, TRUE );
4034 Invalidate();
4038 // -----------------------------------------------------------------------
4040 long CheckBox::PreNotify( NotifyEvent& rNEvt )
4042 long nDone = 0;
4043 const MouseEvent* pMouseEvt = NULL;
4045 if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL )
4047 if( !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() )
4049 // trigger redraw if mouse over state has changed
4050 if( IsNativeControlSupported(CTRL_CHECKBOX, PART_ENTIRE_CONTROL) )
4052 if( ( maMouseRect.IsInside( GetPointerPosPixel()) &&
4053 !maMouseRect.IsInside( GetLastPointerPosPixel()) ) ||
4054 ( maMouseRect.IsInside( GetLastPointerPosPixel()) &&
4055 !maMouseRect.IsInside( GetPointerPosPixel()) ) ||
4056 pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow() )
4058 Invalidate( maStateRect );
4064 return nDone ? nDone : Button::PreNotify(rNEvt);
4067 // -----------------------------------------------------------------------
4069 void CheckBox::Toggle()
4071 ImplCallEventListenersAndHandler( VCLEVENT_CHECKBOX_TOGGLE, maToggleHdl, this );
4074 // -----------------------------------------------------------------------
4076 void CheckBox::SetState( TriState eState )
4078 if ( !mbTriState && (eState == STATE_DONTKNOW) )
4079 eState = STATE_NOCHECK;
4081 if ( meState != eState )
4083 meState = eState;
4084 StateChanged( STATE_CHANGE_STATE );
4085 Toggle();
4089 // -----------------------------------------------------------------------
4091 void CheckBox::EnableTriState( BOOL bTriState )
4093 if ( mbTriState != bTriState )
4095 mbTriState = bTriState;
4097 if ( !bTriState && (meState == STATE_DONTKNOW) )
4098 SetState( STATE_NOCHECK );
4102 // -----------------------------------------------------------------------
4104 Size CheckBox::ImplGetCheckImageSize() const
4106 Size aSize;
4107 // why are IsNativeControlSupported and GetNativeControlRegion not const ?
4108 CheckBox* pThis = const_cast<CheckBox*>(this);
4109 bool bDefaultSize = true;
4110 if( pThis->IsNativeControlSupported( CTRL_CHECKBOX, PART_ENTIRE_CONTROL ) )
4112 ImplControlValue aControlValue;
4113 // #i45896# workaround gcc3.3 temporary problem
4114 Region aCtrlRegion = Region( Rectangle( Point( 0, 0 ), GetSizePixel() ) );
4115 ControlState nState = CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED;
4116 Region aBoundingRgn, aContentRgn;
4118 // get native size of a check box
4119 if( pThis->GetNativeControlRegion( CTRL_CHECKBOX, PART_ENTIRE_CONTROL, aCtrlRegion,
4120 nState, aControlValue, rtl::OUString(),
4121 aBoundingRgn, aContentRgn ) )
4123 Rectangle aCont(aContentRgn.GetBoundRect());
4124 aSize = aCont.GetSize();
4125 bDefaultSize = false;
4128 if( bDefaultSize )
4129 aSize = GetCheckImage( GetSettings(), 0 ).GetSizePixel();
4130 return aSize;
4133 Image CheckBox::GetCheckImage( const AllSettings& rSettings, USHORT nFlags )
4135 ImplSVData* pSVData = ImplGetSVData();
4136 const StyleSettings& rStyleSettings = rSettings.GetStyleSettings();
4137 USHORT nStyle = rStyleSettings.GetCheckBoxStyle() & STYLE_CHECKBOX_STYLE;
4139 if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO )
4140 nStyle = STYLE_CHECKBOX_MONO;
4142 if ( !pSVData->maCtrlData.mpCheckImgList ||
4143 (pSVData->maCtrlData.mnCheckStyle != nStyle) ||
4144 (pSVData->maCtrlData.mnLastCheckFColor != rStyleSettings.GetFaceColor().GetColor()) ||
4145 (pSVData->maCtrlData.mnLastCheckWColor != rStyleSettings.GetWindowColor().GetColor()) ||
4146 (pSVData->maCtrlData.mnLastCheckLColor != rStyleSettings.GetLightColor().GetColor()) )
4148 if ( pSVData->maCtrlData.mpCheckImgList )
4149 delete pSVData->maCtrlData.mpCheckImgList;
4151 pSVData->maCtrlData.mnLastCheckFColor = rStyleSettings.GetFaceColor().GetColor();
4152 pSVData->maCtrlData.mnLastCheckWColor = rStyleSettings.GetWindowColor().GetColor();
4153 pSVData->maCtrlData.mnLastCheckLColor = rStyleSettings.GetLightColor().GetColor();
4155 ResMgr* pResMgr = ImplGetResMgr();
4156 pSVData->maCtrlData.mpCheckImgList = new ImageList();
4157 if( pResMgr )
4158 LoadThemedImageList( rStyleSettings,
4159 pSVData->maCtrlData.mpCheckImgList,
4160 ResId( SV_RESID_BITMAP_CHECK+nStyle, *pResMgr ), 9 );
4161 pSVData->maCtrlData.mnCheckStyle = nStyle;
4164 USHORT nId;
4165 if ( nFlags & BUTTON_DRAW_DISABLED )
4167 if ( nFlags & BUTTON_DRAW_DONTKNOW )
4168 nId = 9;
4169 else if ( nFlags & BUTTON_DRAW_CHECKED )
4170 nId = 6;
4171 else
4172 nId = 5;
4174 else if ( nFlags & BUTTON_DRAW_PRESSED )
4176 if ( nFlags & BUTTON_DRAW_DONTKNOW )
4177 nId = 8;
4178 else if ( nFlags & BUTTON_DRAW_CHECKED )
4179 nId = 4;
4180 else
4181 nId = 3;
4183 else
4185 if ( nFlags & BUTTON_DRAW_DONTKNOW )
4186 nId = 7;
4187 else if ( nFlags & BUTTON_DRAW_CHECKED )
4188 nId = 2;
4189 else
4190 nId = 1;
4192 return pSVData->maCtrlData.mpCheckImgList->GetImage( nId );
4195 // -----------------------------------------------------------------------
4197 void CheckBox::ImplSetMinimumNWFSize()
4199 Push( PUSH_MAPMODE );
4200 SetMapMode( MAP_PIXEL );
4202 ImplControlValue aControlValue;
4203 Size aCurSize( GetSizePixel() );
4204 Region aCtrlRegion = Region( Rectangle( Point( 0, 0 ), aCurSize ) );
4205 Region aBoundingRgn, aContentRgn;
4207 // get native size of a radiobutton
4208 if( GetNativeControlRegion( CTRL_CHECKBOX, PART_ENTIRE_CONTROL, aCtrlRegion,
4209 CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED, aControlValue, rtl::OUString(),
4210 aBoundingRgn, aContentRgn ) )
4212 Rectangle aCont(aContentRgn.GetBoundRect());
4213 Size aSize = aCont.GetSize();
4215 if( aSize.Height() > aCurSize.Height() )
4217 aCurSize.Height() = aSize.Height();
4218 SetSizePixel( aCurSize );
4222 Pop();
4225 // -----------------------------------------------------------------------
4227 Size CheckBox::CalcMinimumSize( long nMaxWidth ) const
4229 Size aSize = ImplGetCheckImageSize();
4230 nMaxWidth -= aSize.Width();
4232 XubString aText = GetText();
4233 if ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
4235 // subtract what will be added later
4236 nMaxWidth-=2;
4237 nMaxWidth -= IMPL_SEP_BUTTON_IMAGE;
4239 Size aTextSize = GetTextRect( Rectangle( Point(), Size( nMaxWidth > 0 ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ),
4240 aText, FixedText::ImplGetTextStyle( GetStyle() ) ).GetSize();
4241 aSize.Width()+=2; // for focus rect
4242 aSize.Width() += IMPL_SEP_BUTTON_IMAGE;
4243 aSize.Width() += aTextSize.Width();
4244 if ( aSize.Height() < aTextSize.Height() )
4245 aSize.Height() = aTextSize.Height();
4247 else
4249 // is this still correct ? since the checkbox now
4250 // shows a focus rect it should be 2 pixels wider and longer
4251 /* da ansonsten im Writer die Control zu weit oben haengen
4252 aSize.Width() += 2;
4253 aSize.Height() += 2;
4257 return CalcWindowSize( aSize );
4260 // -----------------------------------------------------------------------
4262 Size CheckBox::GetOptimalSize(WindowSizeType eType) const
4264 switch (eType) {
4265 case WINDOWSIZE_MINIMUM:
4266 return CalcMinimumSize();
4267 default:
4268 return Button::GetOptimalSize( eType );
4272 // =======================================================================
4274 ImageButton::ImageButton( WindowType nType ) :
4275 PushButton( nType )
4277 ImplInitStyle();
4280 // -----------------------------------------------------------------------
4282 ImageButton::ImageButton( Window* pParent, WinBits nStyle ) :
4283 PushButton( pParent, nStyle )
4285 ImplInitStyle();
4288 // -----------------------------------------------------------------------
4290 ImageButton::ImageButton( Window* pParent, const ResId& rResId ) :
4291 PushButton( pParent, rResId.SetRT( RSC_IMAGEBUTTON ) )
4293 ULONG nObjMask = ReadLongRes();
4295 if ( RSC_IMAGEBUTTON_IMAGE & nObjMask )
4297 SetModeImage( Image( ResId( (RSHEADER_TYPE*)GetClassRes(), *rResId.GetResMgr() ) ) );
4298 IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
4301 if ( RSC_IMAGEBUTTON_SYMBOL & nObjMask )
4302 SetSymbol( (SymbolType)ReadLongRes() );
4304 if ( RSC_IMAGEBUTTON_STATE & nObjMask )
4305 SetState( (TriState)ReadLongRes() );
4307 ImplInitStyle();
4310 // -----------------------------------------------------------------------
4312 ImageButton::~ImageButton()
4316 // -----------------------------------------------------------------------
4317 void ImageButton::ImplInitStyle()
4319 WinBits nStyle = GetStyle();
4321 if ( ! ( nStyle & ( WB_RIGHT | WB_LEFT ) ) )
4322 nStyle |= WB_CENTER;
4324 if ( ! ( nStyle & ( WB_TOP | WB_BOTTOM ) ) )
4325 nStyle |= WB_VCENTER;
4327 SetStyle( nStyle );
4330 // =======================================================================
4332 ImageRadioButton::ImageRadioButton( Window* pParent, WinBits nStyle ) :
4333 RadioButton( pParent, nStyle )
4337 // -----------------------------------------------------------------------
4339 ImageRadioButton::ImageRadioButton( Window* pParent, const ResId& rResId ) :
4340 RadioButton( pParent, rResId.SetRT( RSC_IMAGERADIOBUTTON ) )
4342 ULONG nObjMask = ReadLongRes();
4344 if ( RSC_IMAGERADIOBUTTON_IMAGE & nObjMask )
4346 SetModeRadioImage( Image( ResId( (RSHEADER_TYPE*)GetClassRes(), *rResId.GetResMgr() ) ) );
4347 IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
4351 // -----------------------------------------------------------------------
4353 ImageRadioButton::~ImageRadioButton()
4357 // =======================================================================
4359 TriStateBox::TriStateBox( Window* pParent, WinBits nStyle ) :
4360 CheckBox( pParent, nStyle )
4362 EnableTriState( TRUE );
4365 // -----------------------------------------------------------------------
4367 TriStateBox::TriStateBox( Window* pParent, const ResId& rResId ) :
4368 CheckBox( pParent, rResId.SetRT( RSC_TRISTATEBOX ) )
4370 EnableTriState( TRUE );
4372 ULONG nTriState = ReadLongRes();
4373 USHORT bDisableTriState = ReadShortRes();
4374 //anderer Wert als Default ?
4375 if ( (TriState)nTriState != STATE_NOCHECK )
4376 SetState( (TriState)nTriState );
4377 if ( bDisableTriState )
4378 EnableTriState( FALSE );
4381 // -----------------------------------------------------------------------
4383 TriStateBox::~TriStateBox()