1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <tools/debug.hxx>
22 #include <tools/poly.hxx>
25 #include <vcl/image.hxx>
26 #include <vcl/bitmap.hxx>
27 #include <vcl/bitmapex.hxx>
28 #include <vcl/decoview.hxx>
29 #include <vcl/event.hxx>
30 #include <vcl/svapp.hxx>
31 #include <vcl/dialog.hxx>
32 #include <vcl/fixed.hxx>
33 #include <vcl/button.hxx>
34 #include <vcl/salnativewidgets.hxx>
35 #include <vcl/edit.hxx>
36 #include <vcl/layout.hxx>
41 #include <controldata.hxx>
43 // =======================================================================
45 #define PUSHBUTTON_VIEW_STYLE (WB_3DLOOK | \
46 WB_LEFT | WB_CENTER | WB_RIGHT | \
47 WB_TOP | WB_VCENTER | WB_BOTTOM | \
48 WB_WORDBREAK | WB_NOLABEL | \
49 WB_DEFBUTTON | WB_NOLIGHTBORDER | \
50 WB_RECTSTYLE | WB_SMALLSTYLE | \
52 #define RADIOBUTTON_VIEW_STYLE (WB_3DLOOK | \
53 WB_LEFT | WB_CENTER | WB_RIGHT | \
54 WB_TOP | WB_VCENTER | WB_BOTTOM | \
55 WB_WORDBREAK | WB_NOLABEL)
56 #define CHECKBOX_VIEW_STYLE (WB_3DLOOK | \
57 WB_LEFT | WB_CENTER | WB_RIGHT | \
58 WB_TOP | WB_VCENTER | WB_BOTTOM | \
59 WB_WORDBREAK | WB_NOLABEL)
61 // =======================================================================
63 class ImplCommonButtonData
66 Rectangle maFocusRect
;
68 sal_uInt16 mnButtonState
;
72 ImageAlign meImageAlign
;
73 SymbolAlign meSymbolAlign
;
76 ImplCommonButtonData();
77 ~ImplCommonButtonData();
80 // -----------------------------------------------------------------------
81 ImplCommonButtonData::ImplCommonButtonData() : maFocusRect(), mnSeparatorX(0), mnButtonState(0),
82 mbSmallSymbol(false), maImage(), meImageAlign(IMAGEALIGN_TOP
), meSymbolAlign(SYMBOLALIGN_LEFT
)
86 // -----------------------------------------------------------------------
87 ImplCommonButtonData::~ImplCommonButtonData()
91 // =======================================================================
93 Button::Button( WindowType nType
) :
96 mpButtonData
= new ImplCommonButtonData
;
99 // -----------------------------------------------------------------------
106 // -----------------------------------------------------------------------
110 ImplCallEventListenersAndHandler( VCLEVENT_BUTTON_CLICK
, maClickHdl
, this );
113 // -----------------------------------------------------------------------
115 OUString
Button::GetStandardText( StandardButtonType eButton
)
120 const char* pDefText
;
121 } aResIdAry
[BUTTON_COUNT
] =
123 { SV_BUTTONTEXT_OK
, "~OK" },
124 { SV_BUTTONTEXT_CANCEL
, "~Cancel" },
125 { SV_BUTTONTEXT_YES
, "~Yes" },
126 { SV_BUTTONTEXT_NO
, "~No" },
127 { SV_BUTTONTEXT_RETRY
, "~Retry" },
128 { SV_BUTTONTEXT_HELP
, "~Help" },
129 { SV_BUTTONTEXT_CLOSE
, "~Close" },
130 { SV_BUTTONTEXT_MORE
, "~More" },
131 { SV_BUTTONTEXT_IGNORE
, "~Ignore" },
132 { SV_BUTTONTEXT_ABORT
, "~Abort" },
133 { SV_BUTTONTEXT_LESS
, "~Less" },
134 { SV_BUTTONTEXT_RESET
, "R~eset" }
137 ResMgr
* pResMgr
= ImplGetResMgr();
141 OString
aT( aResIdAry
[(sal_uInt16
)eButton
].pDefText
);
142 return OStringToOUString(aT
, RTL_TEXTENCODING_ASCII_US
);
145 sal_uInt32 nResId
= aResIdAry
[(sal_uInt16
)eButton
].nResId
;
147 // http://lists.freedesktop.org/archives/libreoffice/2013-January/044513.html
148 // Under windows we don't want accelerators on ok/cancel but do on other
150 if (nResId
== SV_BUTTONTEXT_OK
)
151 nResId
= SV_BUTTONTEXT_OK_NOMNEMONIC
;
152 else if (nResId
== SV_BUTTONTEXT_CANCEL
)
153 nResId
= SV_BUTTONTEXT_CANCEL_NOMNEMONIC
;
155 return ResId(nResId
, *pResMgr
).toString();
158 // -----------------------------------------------------------------------
160 XubString
Button::GetStandardHelpText( StandardButtonType
/* eButton */ )
166 // -----------------------------------------------------------------------
167 sal_Bool
Button::SetModeImage( const Image
& rImage
)
169 if ( rImage
!= mpButtonData
->maImage
)
171 mpButtonData
->maImage
= rImage
;
172 StateChanged( STATE_CHANGE_DATA
);
178 // -----------------------------------------------------------------------
179 const Image
Button::GetModeImage( ) const
181 return mpButtonData
->maImage
;
184 // -----------------------------------------------------------------------
185 sal_Bool
Button::HasImage() const
187 return !!(mpButtonData
->maImage
);
190 // -----------------------------------------------------------------------
191 void Button::SetImageAlign( ImageAlign eAlign
)
193 if ( mpButtonData
->meImageAlign
!= eAlign
)
195 mpButtonData
->meImageAlign
= eAlign
;
196 StateChanged( STATE_CHANGE_DATA
);
200 // -----------------------------------------------------------------------
201 ImageAlign
Button::GetImageAlign() const
203 return mpButtonData
->meImageAlign
;
206 // -----------------------------------------------------------------------
208 void Button::SetFocusRect( const Rectangle
& rFocusRect
)
210 ImplSetFocusRect( rFocusRect
);
213 // -----------------------------------------------------------------------
215 long Button::ImplGetSeparatorX() const
217 return mpButtonData
->mnSeparatorX
;
220 void Button::ImplSetSeparatorX( long nX
)
222 mpButtonData
->mnSeparatorX
= nX
;
225 // -----------------------------------------------------------------------
227 sal_uInt16
Button::ImplGetTextStyle( OUString
& rText
, WinBits nWinStyle
,
228 sal_uLong nDrawFlags
)
230 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
231 sal_uInt16 nTextStyle
= FixedText::ImplGetTextStyle( nWinStyle
& ~WB_DEFBUTTON
);
233 if ( nDrawFlags
& WINDOW_DRAW_NOMNEMONIC
)
235 if ( nTextStyle
& TEXT_DRAW_MNEMONIC
)
237 rText
= GetNonMnemonicString( rText
);
238 nTextStyle
&= ~TEXT_DRAW_MNEMONIC
;
242 if ( !(nDrawFlags
& WINDOW_DRAW_NODISABLE
) )
245 nTextStyle
|= TEXT_DRAW_DISABLE
;
248 if ( (nDrawFlags
& WINDOW_DRAW_MONO
) ||
249 (rStyleSettings
.GetOptions() & STYLE_OPTION_MONO
) )
250 nTextStyle
|= TEXT_DRAW_MONO
;
255 // -----------------------------------------------------------------------
257 void Button::ImplDrawAlignedImage( OutputDevice
* pDev
, Point
& rPos
,
258 Size
& rSize
, sal_Bool bLayout
,
259 sal_uLong nImageSep
, sal_uLong nDrawFlags
,
260 sal_uInt16 nTextStyle
, Rectangle
*pSymbolRect
,
263 OUString
aText( GetText() );
264 bool bDrawImage
= HasImage() && ! ( ImplGetButtonState() & BUTTON_DRAW_NOIMAGE
);
265 bool bDrawText
= !aText
.isEmpty() && ! ( ImplGetButtonState() & BUTTON_DRAW_NOTEXT
);
266 bool bHasSymbol
= pSymbolRect
? true : false;
268 // No text and no image => nothing to do => return
269 if ( !bDrawImage
&& !bDrawText
&& !bHasSymbol
)
272 WinBits nWinStyle
= GetStyle();
273 Rectangle
aOutRect( rPos
, rSize
);
274 MetricVector
*pVector
= bLayout
? &mpControlData
->mpLayoutData
->m_aUnicodeBoundRects
: NULL
;
275 OUString
*pDisplayText
= bLayout
? &mpControlData
->mpLayoutData
->m_aDisplayText
: NULL
;
276 ImageAlign eImageAlign
= mpButtonData
->meImageAlign
;
277 Size aImageSize
= mpButtonData
->maImage
.GetSizePixel();
279 if ( ( nDrawFlags
& WINDOW_DRAW_NOMNEMONIC
) &&
280 ( nTextStyle
& TEXT_DRAW_MNEMONIC
) )
282 aText
= GetNonMnemonicString( aText
);
283 nTextStyle
&= ~TEXT_DRAW_MNEMONIC
;
286 aImageSize
.Width() = CalcZoom( aImageSize
.Width() );
287 aImageSize
.Height() = CalcZoom( aImageSize
.Height() );
289 // Drawing text or symbol only is simple, use style and output rectangle
290 if ( bHasSymbol
&& !bDrawImage
&& !bDrawText
)
292 *pSymbolRect
= aOutRect
;
295 else if ( bDrawText
&& !bDrawImage
&& !bHasSymbol
)
297 DrawControlText( *pDev
, aOutRect
, aText
, nTextStyle
, pVector
, pDisplayText
);
299 ImplSetFocusRect( aOutRect
);
300 rSize
= aOutRect
.GetSize();
301 rPos
= aOutRect
.TopLeft();
306 // check for HC mode ( image only! )
307 Image
*pImage
= &(mpButtonData
->maImage
);
312 Point aImagePos
= rPos
;
313 Point aTextPos
= rPos
;
314 Rectangle aUnion
= Rectangle( aImagePos
, aImageSize
);
316 long nSymbolHeight
= 0;
318 if ( bDrawText
|| bHasSymbol
)
320 // Get the size of the text output area ( the symbol will be drawn in
321 // this area as well, so the symbol rectangle will be calculated here, too )
323 Rectangle aRect
= Rectangle( Point(), rSize
);
330 nSymbolHeight
= pDev
->GetTextHeight();
331 if ( mpButtonData
->mbSmallSymbol
)
332 nSymbolHeight
= nSymbolHeight
* 3 / 4;
334 aSymbol
= Rectangle( Point(), Size( nSymbolHeight
, nSymbolHeight
) );
335 ImplCalcSymbolRect( aSymbol
);
336 aRect
.Left() += 3 * nSymbolHeight
/ 2;
337 aTSSize
.Width() = 3 * nSymbolHeight
/ 2;
341 aSymbol
= Rectangle( Point(), rSize
);
342 ImplCalcSymbolRect( aSymbol
);
343 aTSSize
.Width() = aSymbol
.GetWidth();
345 aTSSize
.Height() = aSymbol
.GetHeight();
346 aSymbolSize
= aSymbol
.GetSize();
351 if ( ( eImageAlign
== IMAGEALIGN_LEFT_TOP
) ||
352 ( eImageAlign
== IMAGEALIGN_LEFT
) ||
353 ( eImageAlign
== IMAGEALIGN_LEFT_BOTTOM
) ||
354 ( eImageAlign
== IMAGEALIGN_RIGHT_TOP
) ||
355 ( eImageAlign
== IMAGEALIGN_RIGHT
) ||
356 ( eImageAlign
== IMAGEALIGN_RIGHT_BOTTOM
) )
358 aRect
.Right() -= ( aImageSize
.Width() + nImageSep
);
360 else if ( ( eImageAlign
== IMAGEALIGN_TOP_LEFT
) ||
361 ( eImageAlign
== IMAGEALIGN_TOP
) ||
362 ( eImageAlign
== IMAGEALIGN_TOP_RIGHT
) ||
363 ( eImageAlign
== IMAGEALIGN_BOTTOM_LEFT
) ||
364 ( eImageAlign
== IMAGEALIGN_BOTTOM
) ||
365 ( eImageAlign
== IMAGEALIGN_BOTTOM_RIGHT
) )
367 aRect
.Bottom() -= ( aImageSize
.Height() + nImageSep
);
370 aRect
= pDev
->GetTextRect( aRect
, aText
, nTextStyle
);
371 aTextSize
= aRect
.GetSize();
373 aTSSize
.Width() += aTextSize
.Width();
375 if ( aTSSize
.Height() < aTextSize
.Height() )
376 aTSSize
.Height() = aTextSize
.Height();
378 if( bAddImageSep
&& bDrawImage
)
380 long nDiff
= (aImageSize
.Height() - aTextSize
.Height()) / 3;
386 aMax
.Width() = aTSSize
.Width() > aImageSize
.Width() ? aTSSize
.Width() : aImageSize
.Width();
387 aMax
.Height() = aTSSize
.Height() > aImageSize
.Height() ? aTSSize
.Height() : aImageSize
.Height();
389 // Now calculate the output area for the image and the text acording to the image align flags
391 if ( ( eImageAlign
== IMAGEALIGN_LEFT
) ||
392 ( eImageAlign
== IMAGEALIGN_RIGHT
) )
394 aImagePos
.Y() = rPos
.Y() + ( aMax
.Height() - aImageSize
.Height() ) / 2;
395 aTextPos
.Y() = rPos
.Y() + ( aMax
.Height() - aTSSize
.Height() ) / 2;
397 else if ( ( eImageAlign
== IMAGEALIGN_LEFT_BOTTOM
) ||
398 ( eImageAlign
== IMAGEALIGN_RIGHT_BOTTOM
) )
400 aImagePos
.Y() = rPos
.Y() + aMax
.Height() - aImageSize
.Height();
401 aTextPos
.Y() = rPos
.Y() + aMax
.Height() - aTSSize
.Height();
403 else if ( ( eImageAlign
== IMAGEALIGN_TOP
) ||
404 ( eImageAlign
== IMAGEALIGN_BOTTOM
) )
406 aImagePos
.X() = rPos
.X() + ( aMax
.Width() - aImageSize
.Width() ) / 2;
407 aTextPos
.X() = rPos
.X() + ( aMax
.Width() - aTSSize
.Width() ) / 2;
409 else if ( ( eImageAlign
== IMAGEALIGN_TOP_RIGHT
) ||
410 ( eImageAlign
== IMAGEALIGN_BOTTOM_RIGHT
) )
412 aImagePos
.X() = rPos
.X() + aMax
.Width() - aImageSize
.Width();
413 aTextPos
.X() = rPos
.X() + aMax
.Width() - aTSSize
.Width();
416 if ( ( eImageAlign
== IMAGEALIGN_LEFT_TOP
) ||
417 ( eImageAlign
== IMAGEALIGN_LEFT
) ||
418 ( eImageAlign
== IMAGEALIGN_LEFT_BOTTOM
) )
420 aTextPos
.X() = rPos
.X() + aImageSize
.Width() + nImageSep
;
422 else if ( ( eImageAlign
== IMAGEALIGN_RIGHT_TOP
) ||
423 ( eImageAlign
== IMAGEALIGN_RIGHT
) ||
424 ( eImageAlign
== IMAGEALIGN_RIGHT_BOTTOM
) )
426 aImagePos
.X() = rPos
.X() + aTSSize
.Width() + nImageSep
;
428 else if ( ( eImageAlign
== IMAGEALIGN_TOP_LEFT
) ||
429 ( eImageAlign
== IMAGEALIGN_TOP
) ||
430 ( eImageAlign
== IMAGEALIGN_TOP_RIGHT
) )
432 aTextPos
.Y() = rPos
.Y() + aImageSize
.Height() + nImageSep
;
434 else if ( ( eImageAlign
== IMAGEALIGN_BOTTOM_LEFT
) ||
435 ( eImageAlign
== IMAGEALIGN_BOTTOM
) ||
436 ( eImageAlign
== IMAGEALIGN_BOTTOM_RIGHT
) )
438 aImagePos
.Y() = rPos
.Y() + aTSSize
.Height() + nImageSep
;
440 else if ( eImageAlign
== IMAGEALIGN_CENTER
)
442 aImagePos
.X() = rPos
.X() + ( aMax
.Width() - aImageSize
.Width() ) / 2;
443 aImagePos
.Y() = rPos
.Y() + ( aMax
.Height() - aImageSize
.Height() ) / 2;
444 aTextPos
.X() = rPos
.X() + ( aMax
.Width() - aTSSize
.Width() ) / 2;
445 aTextPos
.Y() = rPos
.Y() + ( aMax
.Height() - aTSSize
.Height() ) / 2;
447 aUnion
= Rectangle( aImagePos
, aImageSize
);
448 aUnion
.Union( Rectangle( aTextPos
, aTSSize
) );
451 // Now place the combination of text and image in the output area of the button
452 // according to the window style (WinBits)
456 if ( nWinStyle
& WB_CENTER
)
458 nXOffset
= ( rSize
.Width() - aUnion
.GetWidth() ) / 2;
460 else if ( nWinStyle
& WB_RIGHT
)
462 nXOffset
= rSize
.Width() - aUnion
.GetWidth();
465 if ( nWinStyle
& WB_VCENTER
)
467 nYOffset
= ( rSize
.Height() - aUnion
.GetHeight() ) / 2;
469 else if ( nWinStyle
& WB_BOTTOM
)
471 nYOffset
= rSize
.Height() - aUnion
.GetHeight();
474 // the top left corner should always be visible, so we don't allow negative offsets
475 if ( nXOffset
< 0 ) nXOffset
= 0;
476 if ( nYOffset
< 0 ) nYOffset
= 0;
478 aImagePos
.X() += nXOffset
;
479 aImagePos
.Y() += nYOffset
;
480 aTextPos
.X() += nXOffset
;
481 aTextPos
.Y() += nYOffset
;
483 // set rPos and rSize to the union
484 rSize
= aUnion
.GetSize();
485 rPos
.X() += nXOffset
;
486 rPos
.Y() += nYOffset
;
490 if ( mpButtonData
->meSymbolAlign
== SYMBOLALIGN_RIGHT
)
492 Point aRightPos
= Point( aTextPos
.X() + aTextSize
.Width() + aSymbolSize
.Width()/2, aTextPos
.Y() );
493 *pSymbolRect
= Rectangle( aRightPos
, aSymbolSize
);
497 *pSymbolRect
= Rectangle( aTextPos
, aSymbolSize
);
498 aTextPos
.X() += ( 3 * nSymbolHeight
/ 2 );
500 if ( mpButtonData
->mbSmallSymbol
)
502 nYOffset
= (aUnion
.GetHeight() - aSymbolSize
.Height())/2;
503 pSymbolRect
->setY( aTextPos
.Y() + nYOffset
);
507 sal_uInt16 nStyle
= 0;
509 if ( ! ( nDrawFlags
& WINDOW_DRAW_NODISABLE
) &&
511 nStyle
|= IMAGE_DRAW_DISABLE
;
514 pDev
->DrawImage( aImagePos
, aImageSize
, *pImage
, nStyle
);
516 pDev
->DrawImage( aImagePos
, *pImage
, nStyle
);
520 ImplSetFocusRect( Rectangle( aTextPos
, aTextSize
) );
521 pDev
->DrawText( Rectangle( aTextPos
, aTextSize
), aText
, nTextStyle
, pVector
, pDisplayText
);
525 ImplSetFocusRect( Rectangle( aImagePos
, aImageSize
) );
529 // -----------------------------------------------------------------------
530 void Button::ImplSetFocusRect( const Rectangle
&rFocusRect
)
532 Rectangle aFocusRect
= rFocusRect
;
533 Rectangle aOutputRect
= Rectangle( Point(), GetOutputSizePixel() );
535 if ( ! aFocusRect
.IsEmpty() )
539 aFocusRect
.Right()++;
540 aFocusRect
.Bottom()++;
543 if ( aFocusRect
.Left() < aOutputRect
.Left() ) aFocusRect
.Left() = aOutputRect
.Left();
544 if ( aFocusRect
.Top() < aOutputRect
.Top() ) aFocusRect
.Top() = aOutputRect
.Top();
545 if ( aFocusRect
.Right() > aOutputRect
.Right() ) aFocusRect
.Right() = aOutputRect
.Right();
546 if ( aFocusRect
.Bottom() > aOutputRect
.Bottom() ) aFocusRect
.Bottom() = aOutputRect
.Bottom();
548 mpButtonData
->maFocusRect
= aFocusRect
;
551 // -----------------------------------------------------------------------
552 const Rectangle
& Button::ImplGetFocusRect() const
554 return mpButtonData
->maFocusRect
;
557 // -----------------------------------------------------------------------
558 sal_uInt16
& Button::ImplGetButtonState()
560 return mpButtonData
->mnButtonState
;
563 // -----------------------------------------------------------------------
564 sal_uInt16
Button::ImplGetButtonState() const
566 return mpButtonData
->mnButtonState
;
569 // -----------------------------------------------------------------------
570 void Button::ImplSetSymbolAlign( SymbolAlign eAlign
)
572 if ( mpButtonData
->meSymbolAlign
!= eAlign
)
574 mpButtonData
->meSymbolAlign
= eAlign
;
575 StateChanged( STATE_CHANGE_DATA
);
579 // -----------------------------------------------------------------------
580 void Button::SetSmallSymbol(bool bSmall
)
582 mpButtonData
->mbSmallSymbol
= bSmall
;
585 // -----------------------------------------------------------------------
586 void Button::EnableImageDisplay( sal_Bool bEnable
)
589 mpButtonData
->mnButtonState
&= ~BUTTON_DRAW_NOIMAGE
;
591 mpButtonData
->mnButtonState
|= BUTTON_DRAW_NOIMAGE
;
594 // -----------------------------------------------------------------------
595 void Button::EnableTextDisplay( sal_Bool bEnable
)
598 mpButtonData
->mnButtonState
&= ~BUTTON_DRAW_NOTEXT
;
600 mpButtonData
->mnButtonState
|= BUTTON_DRAW_NOTEXT
;
603 bool Button::IsSmallSymbol () const
605 return mpButtonData
->mbSmallSymbol
;
608 // =======================================================================
610 void PushButton::ImplInitPushButtonData()
612 mpWindowImpl
->mbPushButton
= sal_True
;
614 meSymbol
= SYMBOL_NOSYMBOL
;
615 meState
= STATE_NOCHECK
;
616 meSaveValue
= STATE_NOCHECK
;
618 mbPressed
= sal_False
;
619 mbInUserDraw
= sal_False
;
622 // -----------------------------------------------------------------------
624 void PushButton::ImplInit( Window
* pParent
, WinBits nStyle
)
626 nStyle
= ImplInitStyle( pParent
->GetWindow( WINDOW_LASTCHILD
), nStyle
);
627 Button::ImplInit( pParent
, nStyle
, NULL
);
629 if ( nStyle
& WB_NOLIGHTBORDER
)
630 ImplGetButtonState() |= BUTTON_DRAW_NOLIGHTBORDER
;
632 ImplInitSettings( sal_True
, sal_True
, sal_True
);
635 // -----------------------------------------------------------------------
637 WinBits
PushButton::ImplInitStyle( const Window
* pPrevWindow
, WinBits nStyle
)
639 if ( !(nStyle
& WB_NOTABSTOP
) )
640 nStyle
|= WB_TABSTOP
;
642 // if no alignment is given, default to "vertically centered". This is because since
643 // #i26046#, we respect the vertical alignment flags (previously we didn't completely),
644 // but we of course want to look as before when no vertical alignment is specified
645 if ( ( nStyle
& ( WB_TOP
| WB_VCENTER
| WB_BOTTOM
) ) == 0 )
646 nStyle
|= WB_VCENTER
;
648 if ( !(nStyle
& WB_NOGROUP
) &&
650 ((pPrevWindow
->GetType() != WINDOW_PUSHBUTTON
) &&
651 (pPrevWindow
->GetType() != WINDOW_OKBUTTON
) &&
652 (pPrevWindow
->GetType() != WINDOW_CANCELBUTTON
) &&
653 (pPrevWindow
->GetType() != WINDOW_HELPBUTTON
)) ) )
658 // -----------------------------------------------------------------
660 const Font
& PushButton::GetCanonicalFont( const StyleSettings
& _rStyle
) const
662 return _rStyle
.GetPushButtonFont();
665 // -----------------------------------------------------------------
666 const Color
& PushButton::GetCanonicalTextColor( const StyleSettings
& _rStyle
) const
668 return _rStyle
.GetButtonTextColor();
671 // -----------------------------------------------------------------------
673 void PushButton::ImplInitSettings( sal_Bool bFont
,
674 sal_Bool bForeground
, sal_Bool bBackground
)
676 Button::ImplInitSettings( bFont
, bForeground
);
681 // #i38498#: do not check for GetParent()->IsChildTransparentModeEnabled()
682 // otherwise the formcontrol button will be overdrawn due to PARENTCLIPMODE_NOCLIP
683 // for radio and checkbox this is ok as they shoud appear transparent in documents
684 if ( IsNativeControlSupported( CTRL_PUSHBUTTON
, PART_ENTIRE_CONTROL
) ||
685 (GetStyle() & WB_FLATBUTTON
) != 0 )
687 EnableChildTransparentMode( sal_True
);
688 SetParentClipMode( PARENTCLIPMODE_NOCLIP
);
689 SetPaintTransparent( sal_True
);
690 mpWindowImpl
->mbUseNativeFocus
= (GetStyle() & WB_FLATBUTTON
)
692 : ImplGetSVData()->maNWFData
.mbNoFocusRects
;
696 EnableChildTransparentMode( sal_False
);
697 SetParentClipMode( 0 );
698 SetPaintTransparent( sal_False
);
703 // -----------------------------------------------------------------------
705 void PushButton::ImplDrawPushButtonFrame( Window
* pDev
,
706 Rectangle
& rRect
, sal_uInt16 nStyle
)
708 if ( !(pDev
->GetStyle() & (WB_RECTSTYLE
| WB_SMALLSTYLE
)) )
710 StyleSettings aStyleSettings
= pDev
->GetSettings().GetStyleSettings();
711 if ( pDev
->IsControlBackground() )
712 aStyleSettings
.Set3DColors( pDev
->GetControlBackground() );
715 DecorationView
aDecoView( pDev
);
716 if ( pDev
->IsControlBackground() )
718 AllSettings aSettings
= pDev
->GetSettings();
719 AllSettings aOldSettings
= aSettings
;
720 StyleSettings aStyleSettings
= aSettings
.GetStyleSettings();
721 aStyleSettings
.Set3DColors( pDev
->GetControlBackground() );
722 aSettings
.SetStyleSettings( aStyleSettings
);
723 pDev
->OutputDevice::SetSettings( aSettings
);
724 rRect
= aDecoView
.DrawButton( rRect
, nStyle
);
725 pDev
->OutputDevice::SetSettings( aOldSettings
);
728 rRect
= aDecoView
.DrawButton( rRect
, nStyle
);
731 // -----------------------------------------------------------------------
733 sal_Bool
PushButton::ImplHitTestPushButton( Window
* pDev
,
737 Rectangle
aTestRect( aTempPoint
, pDev
->GetOutputSizePixel() );
739 return aTestRect
.IsInside( rPos
);
742 // -----------------------------------------------------------------------
744 sal_uInt16
PushButton::ImplGetTextStyle( sal_uLong nDrawFlags
) const
746 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
748 sal_uInt16 nTextStyle
= TEXT_DRAW_MNEMONIC
| TEXT_DRAW_MULTILINE
| TEXT_DRAW_ENDELLIPSIS
;
750 if ( ( rStyleSettings
.GetOptions() & STYLE_OPTION_MONO
) ||
751 ( nDrawFlags
& WINDOW_DRAW_MONO
) )
752 nTextStyle
|= TEXT_DRAW_MONO
;
754 if ( GetStyle() & WB_WORDBREAK
)
755 nTextStyle
|= TEXT_DRAW_WORDBREAK
;
756 if ( GetStyle() & WB_NOLABEL
)
757 nTextStyle
&= ~TEXT_DRAW_MNEMONIC
;
759 if ( GetStyle() & WB_LEFT
)
760 nTextStyle
|= TEXT_DRAW_LEFT
;
761 else if ( GetStyle() & WB_RIGHT
)
762 nTextStyle
|= TEXT_DRAW_RIGHT
;
764 nTextStyle
|= TEXT_DRAW_CENTER
;
766 if ( GetStyle() & WB_TOP
)
767 nTextStyle
|= TEXT_DRAW_TOP
;
768 else if ( GetStyle() & WB_BOTTOM
)
769 nTextStyle
|= TEXT_DRAW_BOTTOM
;
771 nTextStyle
|= TEXT_DRAW_VCENTER
;
773 if ( ! ( (nDrawFlags
& WINDOW_DRAW_NODISABLE
) || IsEnabled() ) )
774 nTextStyle
|= TEXT_DRAW_DISABLE
;
779 // -----------------------------------------------------------------------
781 static void ImplDrawBtnDropDownArrow( OutputDevice
* pDev
,
783 Color
& rColor
, bool bBlack
)
785 Color aOldLineColor
= pDev
->GetLineColor();
786 Color aOldFillColor
= pDev
->GetFillColor();
788 pDev
->SetLineColor();
790 pDev
->SetFillColor( Color( COL_BLACK
) );
792 pDev
->SetFillColor( rColor
);
793 pDev
->DrawRect( Rectangle( nX
+0, nY
+0, nX
+6, nY
+0 ) );
794 pDev
->DrawRect( Rectangle( nX
+1, nY
+1, nX
+5, nY
+1 ) );
795 pDev
->DrawRect( Rectangle( nX
+2, nY
+2, nX
+4, nY
+2 ) );
796 pDev
->DrawRect( Rectangle( nX
+3, nY
+3, nX
+3, nY
+3 ) );
799 pDev
->SetFillColor( rColor
);
800 pDev
->DrawRect( Rectangle( nX
+2, nY
+1, nX
+4, nY
+1 ) );
801 pDev
->DrawRect( Rectangle( nX
+3, nY
+2, nX
+3, nY
+2 ) );
803 pDev
->SetLineColor( aOldLineColor
);
804 pDev
->SetFillColor( aOldFillColor
);
807 // -----------------------------------------------------------------------
809 void PushButton::ImplDrawPushButtonContent( OutputDevice
* pDev
, sal_uLong nDrawFlags
,
810 const Rectangle
& rRect
,
815 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
816 Rectangle aInRect
= rRect
;
818 OUString aText
= PushButton::GetText(); // PushButton:: because of MoreButton
819 sal_uInt16 nTextStyle
= ImplGetTextStyle( nDrawFlags
);
822 if( aInRect
.Right() < aInRect
.Left() || aInRect
.Bottom() < aInRect
.Top() )
825 pDev
->Push( PUSH_CLIPREGION
);
826 pDev
->IntersectClipRegion( aInRect
);
828 if ( nDrawFlags
& WINDOW_DRAW_MONO
)
829 aColor
= Color( COL_BLACK
);
830 else if ( IsControlForeground() )
831 aColor
= GetControlForeground();
832 else if( nDrawFlags
& WINDOW_DRAW_ROLLOVER
)
833 aColor
= rStyleSettings
.GetButtonRolloverTextColor();
835 aColor
= rStyleSettings
.GetButtonTextColor();
837 pDev
->SetTextColor( aColor
);
839 if ( IsEnabled() || (nDrawFlags
& WINDOW_DRAW_NODISABLE
) )
842 nStyle
= SYMBOL_DRAW_DISABLE
;
844 Size aSize
= rRect
.GetSize();
845 Point aPos
= rRect
.TopLeft();
847 sal_uLong nImageSep
= 1 + (pDev
->GetTextHeight()-10)/2;
850 if ( mnDDStyle
== PUSHBUTTON_DROPDOWN_MENUBUTTON
)
852 long nSeparatorX
= 0;
853 Rectangle aSymbolRect
= aInRect
;
854 if ( !aText
.isEmpty() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT
) )
856 // calculate symbol size
857 long nSymbolSize
= pDev
->GetTextHeight() / 2 + 1;
859 nSeparatorX
= aInRect
.Right() - 2*nSymbolSize
;
860 aSize
.Width() -= 2*nSymbolSize
;
862 // center symbol rectangle in the separated area
863 aSymbolRect
.Right() -= nSymbolSize
/2;
864 aSymbolRect
.Left() = aSymbolRect
.Right() - nSymbolSize
;
866 ImplDrawAlignedImage( pDev
, aPos
, aSize
, bLayout
, nImageSep
,
867 nDrawFlags
, nTextStyle
, NULL
, true );
870 ImplCalcSymbolRect( aSymbolRect
);
874 long nDistance
= (aSymbolRect
.GetHeight() > 10) ? 2 : 1;
875 DecorationView
aDecoView( pDev
);
876 if( bMenuBtnSep
&& nSeparatorX
> 0 )
878 Point
aStartPt( nSeparatorX
, aSymbolRect
.Top()+nDistance
);
879 Point
aEndPt( nSeparatorX
, aSymbolRect
.Bottom()-nDistance
);
880 aDecoView
.DrawSeparator( aStartPt
, aEndPt
);
882 ImplSetSeparatorX( nSeparatorX
);
884 aDecoView
.DrawSymbol( aSymbolRect
, SYMBOL_SPIN_DOWN
, aColor
, nStyle
);
890 Rectangle aSymbolRect
;
891 ImplDrawAlignedImage( pDev
, aPos
, aSize
, bLayout
, nImageSep
, nDrawFlags
,
892 nTextStyle
, IsSymbol() ? &aSymbolRect
: NULL
, true );
894 if ( IsSymbol() && ! bLayout
)
896 DecorationView
aDecoView( pDev
);
897 aDecoView
.DrawSymbol( aSymbolRect
, meSymbol
, aColor
, nStyle
);
900 if ( mnDDStyle
== PUSHBUTTON_DROPDOWN_TOOLBOX
&& !bLayout
)
903 Color
aArrowColor( COL_BLACK
);
905 if ( !(nDrawFlags
& WINDOW_DRAW_MONO
) )
908 aArrowColor
= rStyleSettings
.GetShadowColor();
911 aArrowColor
= Color( COL_LIGHTGREEN
);
916 ImplDrawBtnDropDownArrow( pDev
, aInRect
.Right()-6, aInRect
.Top()+1,
917 aArrowColor
, bBlack
);
921 UserDrawEvent
aUDEvt( this, aInRect
, 0 );
924 pDev
->Pop(); // restore clipregion
927 // -----------------------------------------------------------------------
929 void PushButton::UserDraw( const UserDrawEvent
& )
933 // -----------------------------------------------------------------------
935 void PushButton::ImplDrawPushButton( bool bLayout
)
940 sal_uInt16 nButtonStyle
= ImplGetButtonState();
942 Size
aOutSz( GetOutputSizePixel() );
943 Rectangle
aRect( aPoint
, aOutSz
);
944 Rectangle aInRect
= aRect
;
945 sal_Bool bNativeOK
= sal_False
;
947 // adjust style if button should be rendered 'pressed'
949 nButtonStyle
|= BUTTON_DRAW_PRESSED
;
951 // TODO: move this to Window class or make it a member !!!
952 ControlType aCtrlType
= 0;
953 switch( GetParent()->GetType() )
956 case WINDOW_MULTILISTBOX
:
957 case WINDOW_TREELISTBOX
:
958 aCtrlType
= CTRL_LISTBOX
;
961 case WINDOW_COMBOBOX
:
962 case WINDOW_PATTERNBOX
:
963 case WINDOW_NUMERICBOX
:
964 case WINDOW_METRICBOX
:
965 case WINDOW_CURRENCYBOX
:
968 case WINDOW_LONGCURRENCYBOX
:
969 aCtrlType
= CTRL_COMBOBOX
;
975 bool bDropDown
= ( IsSymbol() && (GetSymbol()==SYMBOL_SPIN_DOWN
) && GetText().isEmpty() );
977 if( bDropDown
&& (aCtrlType
== CTRL_COMBOBOX
|| aCtrlType
== CTRL_LISTBOX
) )
979 if( GetParent()->IsNativeControlSupported( aCtrlType
, PART_ENTIRE_CONTROL
) )
981 // skip painting if the button was already drawn by the theme
982 if( aCtrlType
== CTRL_COMBOBOX
)
984 Edit
* pEdit
= static_cast<Edit
*>(GetParent());
985 if( pEdit
->ImplUseNativeBorder( pEdit
->GetStyle() ) )
986 bNativeOK
= sal_True
;
988 else if( GetParent()->IsNativeControlSupported( aCtrlType
, HAS_BACKGROUND_TEXTURE
) )
990 bNativeOK
= sal_True
;
992 if( !bNativeOK
&& GetParent()->IsNativeControlSupported( aCtrlType
, PART_BUTTON_DOWN
) )
994 // let the theme draw it, note we then need support
995 // for CTRL_LISTBOX/PART_BUTTON_DOWN and CTRL_COMBOBOX/PART_BUTTON_DOWN
997 ImplControlValue aControlValue
;
998 ControlState nState
= 0;
1000 if ( mbPressed
) nState
|= CTRL_STATE_PRESSED
;
1001 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED
) nState
|= CTRL_STATE_PRESSED
;
1002 if ( HasFocus() ) nState
|= CTRL_STATE_FOCUSED
;
1003 if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT
) nState
|= CTRL_STATE_DEFAULT
;
1004 if ( Window::IsEnabled() ) nState
|= CTRL_STATE_ENABLED
;
1006 if ( IsMouseOver() && aInRect
.IsInside( GetPointerPosPixel() ) )
1007 nState
|= CTRL_STATE_ROLLOVER
;
1009 bNativeOK
= DrawNativeControl( aCtrlType
, PART_BUTTON_DOWN
, aInRect
, nState
,
1010 aControlValue
, OUString() );
1018 bool bRollOver
= (IsMouseOver() && aInRect
.IsInside( GetPointerPosPixel() ));
1019 bool bDrawMenuSep
= true;
1020 if( (GetStyle() & WB_FLATBUTTON
) )
1022 if( ! bRollOver
&& ! HasFocus() )
1023 bDrawMenuSep
= false;
1025 if ( (bNativeOK
=IsNativeControlSupported(CTRL_PUSHBUTTON
, PART_ENTIRE_CONTROL
)) == sal_True
)
1027 PushButtonValue aControlValue
;
1028 Rectangle
aCtrlRegion( aInRect
);
1029 ControlState nState
= 0;
1031 if ( mbPressed
|| IsChecked() ) nState
|= CTRL_STATE_PRESSED
;
1032 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED
) nState
|= CTRL_STATE_PRESSED
;
1033 if ( HasFocus() ) nState
|= CTRL_STATE_FOCUSED
;
1034 if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT
) nState
|= CTRL_STATE_DEFAULT
;
1035 if ( Window::IsEnabled() ) nState
|= CTRL_STATE_ENABLED
;
1038 nState
|= CTRL_STATE_ROLLOVER
;
1040 if( GetStyle() & WB_BEVELBUTTON
)
1041 aControlValue
.mbBevelButton
= true;
1043 // draw frame into invisible window to have aInRect modified correctly
1044 // but do not shift the inner rect for pressed buttons (ie remove BUTTON_DRAW_PRESSED)
1045 // this assumes the theme has enough visual cues to signalize the button was pressed
1046 //Window aWin( this );
1047 //ImplDrawPushButtonFrame( &aWin, aInRect, nButtonStyle & ~BUTTON_DRAW_PRESSED );
1049 // looks better this way as symbols were displaced slightly using the above approach
1051 aInRect
.Bottom()-=4;
1055 // prepare single line hint (needed on mac to decide between normal push button and
1056 // rectangular bevel button look)
1057 Size
aFontSize( Application::GetSettings().GetStyleSettings().GetPushButtonFont().GetSize() );
1058 aFontSize
= LogicToPixel( aFontSize
, MapMode( MAP_POINT
) );
1059 Size
aInRectSize( LogicToPixel( Size( aInRect
.GetWidth(), aInRect
.GetHeight() ) ) );
1060 aControlValue
.mbSingleLine
= (aInRectSize
.Height() < 2 * aFontSize
.Height() );
1062 if( ((nState
& CTRL_STATE_ROLLOVER
)) || ! (GetStyle() & WB_FLATBUTTON
) )
1064 bNativeOK
= DrawNativeControl( CTRL_PUSHBUTTON
, PART_ENTIRE_CONTROL
, aCtrlRegion
, nState
,
1065 aControlValue
, OUString()/*PushButton::GetText()*/ );
1072 // draw content using the same aInRect as non-native VCL would do
1073 ImplDrawPushButtonContent( this,
1074 (nState
&CTRL_STATE_ROLLOVER
) ? WINDOW_DRAW_ROLLOVER
: 0,
1075 aInRect
, bLayout
, bDrawMenuSep
);
1078 ShowFocus( ImplGetFocusRect() );
1081 if ( bNativeOK
== sal_False
)
1083 // draw PushButtonFrame, aInRect has content size afterwards
1084 if( (GetStyle() & WB_FLATBUTTON
) )
1086 Rectangle
aTempRect( aInRect
);
1087 if( ! bLayout
&& bRollOver
)
1088 ImplDrawPushButtonFrame( this, aTempRect
, nButtonStyle
);
1089 aInRect
.Left() += 2;
1091 aInRect
.Right() -= 2;
1092 aInRect
.Bottom() -= 2;
1097 ImplDrawPushButtonFrame( this, aInRect
, nButtonStyle
);
1101 ImplDrawPushButtonContent( this, 0, aInRect
, bLayout
, bDrawMenuSep
);
1103 if( ! bLayout
&& HasFocus() )
1105 ShowFocus( ImplGetFocusRect() );
1110 // -----------------------------------------------------------------------
1112 void PushButton::ImplSetDefButton( sal_Bool bSet
)
1114 Size
aSize( GetSizePixel() );
1115 Point
aPos( GetPosPixel() );
1116 int dLeft(0), dRight(0), dTop(0), dBottom(0);
1117 bool bSetPos
= false;
1119 if ( (IsNativeControlSupported(CTRL_PUSHBUTTON
, PART_ENTIRE_CONTROL
)) == sal_True
)
1121 Rectangle aBound
, aCont
;
1122 Rectangle
aCtrlRect( 0, 0, 80, 20 ); // use a constant size to avoid accumulating
1123 // will not work if the theme has dynamic adornment sizes
1124 ImplControlValue aControlValue
;
1125 Rectangle
aCtrlRegion( aCtrlRect
);
1126 ControlState nState
= CTRL_STATE_DEFAULT
|CTRL_STATE_ENABLED
;
1128 // get native size of a 'default' button
1129 // and adjust the VCL button if more space for adornment is required
1130 if( GetNativeControlRegion( CTRL_PUSHBUTTON
, PART_ENTIRE_CONTROL
, aCtrlRegion
,
1131 nState
, aControlValue
, OUString(),
1134 dLeft
= aCont
.Left() - aBound
.Left();
1135 dTop
= aCont
.Top() - aBound
.Top();
1136 dRight
= aBound
.Right() - aCont
.Right();
1137 dBottom
= aBound
.Bottom() - aCont
.Bottom();
1138 bSetPos
= dLeft
|| dTop
|| dRight
|| dBottom
;
1144 if( !(ImplGetButtonState() & BUTTON_DRAW_DEFAULT
) && bSetPos
)
1146 // adjust pos/size when toggling from non-default to default
1147 aPos
.Move(-dLeft
, -dTop
);
1148 aSize
.Width() += dLeft
+ dRight
;
1149 aSize
.Height() += dTop
+ dBottom
;
1151 ImplGetButtonState() |= BUTTON_DRAW_DEFAULT
;
1155 if( (ImplGetButtonState() & BUTTON_DRAW_DEFAULT
) && bSetPos
)
1157 // adjust pos/size when toggling from default to non-default
1158 aPos
.Move(dLeft
, dTop
);
1159 aSize
.Width() -= dLeft
+ dRight
;
1160 aSize
.Height() -= dTop
+ dBottom
;
1162 ImplGetButtonState() &= ~BUTTON_DRAW_DEFAULT
;
1165 setPosSizePixel( aPos
.X(), aPos
.Y(), aSize
.Width(), aSize
.Height(), WINDOW_POSSIZE_ALL
);
1170 // -----------------------------------------------------------------------
1172 sal_Bool
PushButton::ImplIsDefButton() const
1174 return (ImplGetButtonState() & BUTTON_DRAW_DEFAULT
) != 0;
1177 // -----------------------------------------------------------------------
1179 PushButton::PushButton( WindowType nType
) :
1182 ImplInitPushButtonData();
1185 // -----------------------------------------------------------------------
1187 PushButton::PushButton( Window
* pParent
, WinBits nStyle
) :
1188 Button( WINDOW_PUSHBUTTON
)
1190 ImplInitPushButtonData();
1191 ImplInit( pParent
, nStyle
);
1194 // -----------------------------------------------------------------------
1196 PushButton::PushButton( Window
* pParent
, const ResId
& rResId
) :
1197 Button( WINDOW_PUSHBUTTON
)
1199 rResId
.SetRT( RSC_PUSHBUTTON
);
1200 WinBits nStyle
= ImplInitRes( rResId
);
1201 ImplInitPushButtonData();
1202 ImplInit( pParent
, nStyle
);
1203 ImplLoadRes( rResId
);
1205 if ( !(nStyle
& WB_HIDE
) )
1209 // -----------------------------------------------------------------------
1211 PushButton::~PushButton()
1215 // -----------------------------------------------------------------------
1217 void PushButton::MouseButtonDown( const MouseEvent
& rMEvt
)
1219 if ( rMEvt
.IsLeft() &&
1220 ImplHitTestPushButton( this, rMEvt
.GetPosPixel() ) )
1222 sal_uInt16 nTrackFlags
= 0;
1224 if ( ( GetStyle() & WB_REPEAT
) &&
1225 ! ( GetStyle() & WB_TOGGLE
) )
1226 nTrackFlags
|= STARTTRACK_BUTTONREPEAT
;
1228 ImplGetButtonState() |= BUTTON_DRAW_PRESSED
;
1229 ImplDrawPushButton();
1230 StartTracking( nTrackFlags
);
1232 if ( nTrackFlags
& STARTTRACK_BUTTONREPEAT
)
1237 // -----------------------------------------------------------------------
1239 void PushButton::Tracking( const TrackingEvent
& rTEvt
)
1241 if ( rTEvt
.IsTrackingEnded() )
1243 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED
)
1245 if ( !(GetStyle() & WB_NOPOINTERFOCUS
) && !rTEvt
.IsTrackingCanceled() )
1248 if ( GetStyle() & WB_TOGGLE
)
1250 // Don't toggle, when aborted
1251 if ( !rTEvt
.IsTrackingCanceled() )
1256 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED
;
1263 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED
;
1265 ImplDrawPushButton();
1267 // do not call Click handler if aborted
1268 if ( !rTEvt
.IsTrackingCanceled() )
1270 if ( ! ( ( GetStyle() & WB_REPEAT
) &&
1271 ! ( GetStyle() & WB_TOGGLE
) ) )
1278 if ( ImplHitTestPushButton( this, rTEvt
.GetMouseEvent().GetPosPixel() ) )
1280 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED
)
1282 if ( rTEvt
.IsTrackingRepeat() && (GetStyle() & WB_REPEAT
) &&
1283 ! ( GetStyle() & WB_TOGGLE
) )
1288 ImplGetButtonState() |= BUTTON_DRAW_PRESSED
;
1289 ImplDrawPushButton();
1294 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED
)
1296 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED
;
1297 ImplDrawPushButton();
1303 // -----------------------------------------------------------------------
1305 void PushButton::KeyInput( const KeyEvent
& rKEvt
)
1307 KeyCode aKeyCode
= rKEvt
.GetKeyCode();
1309 if ( !aKeyCode
.GetModifier() &&
1310 ((aKeyCode
.GetCode() == KEY_RETURN
) || (aKeyCode
.GetCode() == KEY_SPACE
)) )
1312 if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED
) )
1314 ImplGetButtonState() |= BUTTON_DRAW_PRESSED
;
1315 ImplDrawPushButton();
1318 if ( ( GetStyle() & WB_REPEAT
) &&
1319 ! ( GetStyle() & WB_TOGGLE
) )
1322 else if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED
) && (aKeyCode
.GetCode() == KEY_ESCAPE
) )
1324 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED
;
1325 ImplDrawPushButton();
1328 Button::KeyInput( rKEvt
);
1331 // -----------------------------------------------------------------------
1333 void PushButton::KeyUp( const KeyEvent
& rKEvt
)
1335 KeyCode aKeyCode
= rKEvt
.GetKeyCode();
1337 if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED
) &&
1338 ((aKeyCode
.GetCode() == KEY_RETURN
) || (aKeyCode
.GetCode() == KEY_SPACE
)) )
1340 if ( GetStyle() & WB_TOGGLE
)
1345 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED
;
1353 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED
;
1355 ImplDrawPushButton();
1357 if ( !( ( GetStyle() & WB_REPEAT
) &&
1358 ! ( GetStyle() & WB_TOGGLE
) ) )
1362 Button::KeyUp( rKEvt
);
1365 // -----------------------------------------------------------------------
1367 void PushButton::FillLayoutData() const
1369 mpControlData
->mpLayoutData
= new vcl::ControlLayoutData();
1370 const_cast<PushButton
*>(this)->ImplDrawPushButton( true );
1373 // -----------------------------------------------------------------------
1375 void PushButton::Paint( const Rectangle
& )
1377 ImplDrawPushButton();
1380 // -----------------------------------------------------------------------
1382 void PushButton::Draw( OutputDevice
* pDev
, const Point
& rPos
, const Size
& rSize
,
1385 Point aPos
= pDev
->LogicToPixel( rPos
);
1386 Size aSize
= pDev
->LogicToPixel( rSize
);
1387 Rectangle
aRect( aPos
, aSize
);
1388 Font aFont
= GetDrawPixelFont( pDev
);
1392 pDev
->SetFont( aFont
);
1393 if ( nFlags
& WINDOW_DRAW_MONO
)
1395 pDev
->SetTextColor( Color( COL_BLACK
) );
1399 pDev
->SetTextColor( GetTextColor() );
1401 // DecoView uses the FaceColor...
1402 AllSettings aSettings
= pDev
->GetSettings();
1403 StyleSettings aStyleSettings
= aSettings
.GetStyleSettings();
1404 if ( IsControlBackground() )
1405 aStyleSettings
.SetFaceColor( GetControlBackground() );
1407 aStyleSettings
.SetFaceColor( GetSettings().GetStyleSettings().GetFaceColor() );
1408 aSettings
.SetStyleSettings( aStyleSettings
);
1409 pDev
->OutputDevice::SetSettings( aSettings
);
1411 pDev
->SetTextFillColor();
1413 DecorationView
aDecoView( pDev
);
1414 sal_uInt16 nButtonStyle
= 0;
1415 if ( nFlags
& WINDOW_DRAW_MONO
)
1416 nButtonStyle
|= BUTTON_DRAW_MONO
;
1418 nButtonStyle
|= BUTTON_DRAW_CHECKED
;
1419 aRect
= aDecoView
.DrawButton( aRect
, nButtonStyle
);
1421 ImplDrawPushButtonContent( pDev
, nFlags
, aRect
, false, true );
1425 // -----------------------------------------------------------------------
1427 void PushButton::Resize()
1433 // -----------------------------------------------------------------------
1435 void PushButton::GetFocus()
1437 ShowFocus( ImplGetFocusRect() );
1438 SetInputContext( InputContext( GetFont() ) );
1442 // -----------------------------------------------------------------------
1444 void PushButton::LoseFocus()
1448 Button::LoseFocus();
1451 // -----------------------------------------------------------------------
1453 void PushButton::StateChanged( StateChangedType nType
)
1455 Button::StateChanged( nType
);
1457 if ( (nType
== STATE_CHANGE_ENABLE
) ||
1458 (nType
== STATE_CHANGE_TEXT
) ||
1459 (nType
== STATE_CHANGE_IMAGE
) ||
1460 (nType
== STATE_CHANGE_DATA
) ||
1461 (nType
== STATE_CHANGE_STATE
) ||
1462 (nType
== STATE_CHANGE_UPDATEMODE
) )
1464 if ( IsReallyVisible() && IsUpdateMode() )
1467 else if ( nType
== STATE_CHANGE_STYLE
)
1469 SetStyle( ImplInitStyle( GetWindow( WINDOW_PREV
), GetStyle() ) );
1471 bool bIsDefButton
= ( GetStyle() & WB_DEFBUTTON
) != 0;
1472 bool bWasDefButton
= ( GetPrevStyle() & WB_DEFBUTTON
) != 0;
1473 if ( bIsDefButton
!= bWasDefButton
)
1474 ImplSetDefButton( bIsDefButton
);
1476 if ( IsReallyVisible() && IsUpdateMode() )
1478 if ( (GetPrevStyle() & PUSHBUTTON_VIEW_STYLE
) !=
1479 (GetStyle() & PUSHBUTTON_VIEW_STYLE
) )
1483 else if ( (nType
== STATE_CHANGE_ZOOM
) ||
1484 (nType
== STATE_CHANGE_CONTROLFONT
) )
1486 ImplInitSettings( sal_True
, sal_False
, sal_False
);
1489 else if ( nType
== STATE_CHANGE_CONTROLFOREGROUND
)
1491 ImplInitSettings( sal_False
, sal_True
, sal_False
);
1494 else if ( nType
== STATE_CHANGE_CONTROLBACKGROUND
)
1496 ImplInitSettings( sal_False
, sal_False
, sal_True
);
1501 // -----------------------------------------------------------------------
1503 void PushButton::DataChanged( const DataChangedEvent
& rDCEvt
)
1505 Button::DataChanged( rDCEvt
);
1507 if ( (rDCEvt
.GetType() == DATACHANGED_FONTS
) ||
1508 (rDCEvt
.GetType() == DATACHANGED_FONTSUBSTITUTION
) ||
1509 ((rDCEvt
.GetType() == DATACHANGED_SETTINGS
) &&
1510 (rDCEvt
.GetFlags() & SETTINGS_STYLE
)) )
1512 ImplInitSettings( sal_True
, sal_True
, sal_True
);
1517 // -----------------------------------------------------------------------
1519 long PushButton::PreNotify( NotifyEvent
& rNEvt
)
1522 const MouseEvent
* pMouseEvt
= NULL
;
1524 if( (rNEvt
.GetType() == EVENT_MOUSEMOVE
) && (pMouseEvt
= rNEvt
.GetMouseEvent()) != NULL
)
1526 if( pMouseEvt
->IsEnterWindow() || pMouseEvt
->IsLeaveWindow() )
1528 // trigger redraw as mouse over state has changed
1530 // TODO: move this to Window class or make it a member !!!
1531 ControlType aCtrlType
= 0;
1532 switch( GetParent()->GetType() )
1534 case WINDOW_LISTBOX
:
1535 case WINDOW_MULTILISTBOX
:
1536 case WINDOW_TREELISTBOX
:
1537 aCtrlType
= CTRL_LISTBOX
;
1540 case WINDOW_COMBOBOX
:
1541 case WINDOW_PATTERNBOX
:
1542 case WINDOW_NUMERICBOX
:
1543 case WINDOW_METRICBOX
:
1544 case WINDOW_CURRENCYBOX
:
1545 case WINDOW_DATEBOX
:
1546 case WINDOW_TIMEBOX
:
1547 case WINDOW_LONGCURRENCYBOX
:
1548 aCtrlType
= CTRL_COMBOBOX
;
1554 bool bDropDown
= ( IsSymbol() && (GetSymbol()==SYMBOL_SPIN_DOWN
) && GetText().isEmpty() );
1556 if( bDropDown
&& GetParent()->IsNativeControlSupported( aCtrlType
, PART_ENTIRE_CONTROL
) &&
1557 !GetParent()->IsNativeControlSupported( aCtrlType
, PART_BUTTON_DOWN
) )
1559 Window
*pBorder
= GetParent()->GetWindow( WINDOW_BORDER
);
1560 if(aCtrlType
== CTRL_COMBOBOX
)
1562 // only paint the button part to avoid flickering of the combobox text
1564 Rectangle
aClipRect( aPt
, GetOutputSizePixel() );
1565 aClipRect
.SetPos(pBorder
->ScreenToOutputPixel(OutputToScreenPixel(aClipRect
.TopLeft())));
1566 pBorder
->Invalidate( aClipRect
);
1570 pBorder
->Invalidate( INVALIDATE_NOERASE
);
1574 else if( (GetStyle() & WB_FLATBUTTON
) ||
1575 IsNativeControlSupported(CTRL_PUSHBUTTON
, PART_ENTIRE_CONTROL
) )
1582 return nDone
? nDone
: Button::PreNotify(rNEvt
);
1585 // -----------------------------------------------------------------------
1587 void PushButton::Toggle()
1589 ImplCallEventListenersAndHandler( VCLEVENT_PUSHBUTTON_TOGGLE
, maToggleHdl
, this );
1592 // -----------------------------------------------------------------------
1594 void PushButton::SetSymbol( SymbolType eSymbol
)
1596 if ( meSymbol
!= eSymbol
)
1599 StateChanged( STATE_CHANGE_DATA
);
1603 // -----------------------------------------------------------------------
1604 void PushButton::SetSymbolAlign( SymbolAlign eAlign
)
1606 ImplSetSymbolAlign( eAlign
);
1609 // -----------------------------------------------------------------------
1611 void PushButton::SetDropDown( sal_uInt16 nStyle
)
1613 if ( mnDDStyle
!= nStyle
)
1616 StateChanged( STATE_CHANGE_DATA
);
1620 // -----------------------------------------------------------------------
1622 void PushButton::SetState( TriState eState
)
1624 if ( meState
!= eState
)
1627 if ( meState
== STATE_NOCHECK
)
1628 ImplGetButtonState() &= ~(BUTTON_DRAW_CHECKED
| BUTTON_DRAW_DONTKNOW
);
1629 else if ( meState
== STATE_CHECK
)
1631 ImplGetButtonState() &= ~BUTTON_DRAW_DONTKNOW
;
1632 ImplGetButtonState() |= BUTTON_DRAW_CHECKED
;
1634 else // STATE_DONTKNOW
1636 ImplGetButtonState() &= ~BUTTON_DRAW_CHECKED
;
1637 ImplGetButtonState() |= BUTTON_DRAW_DONTKNOW
;
1640 StateChanged( STATE_CHANGE_STATE
);
1645 // -----------------------------------------------------------------------
1647 void PushButton::SetPressed( sal_Bool bPressed
)
1649 if ( mbPressed
!= bPressed
)
1651 mbPressed
= bPressed
;
1652 StateChanged( STATE_CHANGE_DATA
);
1656 // -----------------------------------------------------------------------
1658 void PushButton::EndSelection()
1660 EndTracking( ENDTRACK_CANCEL
);
1661 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED
)
1663 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED
;
1665 ImplDrawPushButton();
1669 // -----------------------------------------------------------------------
1671 Size
PushButton::CalcMinimumSize( long nMaxWidth
) const
1677 if ( IsSmallSymbol ())
1678 aSize
= Size( 16, 12 );
1680 aSize
= Size( 26, 24 );
1681 if( mnDDStyle
== PUSHBUTTON_DROPDOWN_MENUBUTTON
)
1684 else if ( IsImage() && ! (ImplGetButtonState() & BUTTON_DRAW_NOIMAGE
) )
1685 aSize
= GetModeImage().GetSizePixel();
1686 if ( !PushButton::GetText().isEmpty() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT
) )
1688 sal_uLong nDrawFlags
= 0;
1689 Size textSize
= GetTextRect( Rectangle( Point(), Size( nMaxWidth
? nMaxWidth
: 0x7fffffff, 0x7fffffff ) ),
1690 PushButton::GetText(), ImplGetTextStyle( nDrawFlags
) ).GetSize();
1691 aSize
.Width() += int( textSize
.Width () * 1.15 );
1692 aSize
.Height() = std::max( aSize
.Height(), long( textSize
.Height() * 1.15 ) );
1695 // cf. ImplDrawPushButton ...
1696 if( (GetStyle() & WB_SMALLSTYLE
) == 0 )
1698 aSize
.Width() += 12;
1699 aSize
.Height() += 12;
1702 return CalcWindowSize( aSize
);
1705 Size
PushButton::GetOptimalSize() const
1707 return CalcMinimumSize();
1710 bool PushButton::set_property(const OString
&rKey
, const OString
&rValue
)
1712 if (rKey
== "has-default")
1714 WinBits nBits
= GetStyle();
1715 nBits
&= ~(WB_DEFBUTTON
);
1717 nBits
|= WB_DEFBUTTON
;
1721 return Control::set_property(rKey
, rValue
);
1726 // =======================================================================
1728 void OKButton::ImplInit( Window
* pParent
, WinBits nStyle
)
1730 PushButton::ImplInit( pParent
, nStyle
);
1732 SetText( Button::GetStandardText( BUTTON_OK
) );
1733 SetHelpText( Button::GetStandardHelpText( BUTTON_OK
) );
1736 // -----------------------------------------------------------------------
1738 OKButton::OKButton( Window
* pParent
, WinBits nStyle
) :
1739 PushButton( WINDOW_OKBUTTON
)
1741 ImplInit( pParent
, nStyle
);
1744 // -----------------------------------------------------------------------
1746 OKButton::OKButton( Window
* pParent
, const ResId
& rResId
) :
1747 PushButton( WINDOW_OKBUTTON
)
1749 rResId
.SetRT( RSC_OKBUTTON
);
1750 WinBits nStyle
= ImplInitRes( rResId
);
1751 ImplInit( pParent
, nStyle
);
1752 ImplLoadRes( rResId
);
1754 if ( !(nStyle
& WB_HIDE
) )
1758 // -----------------------------------------------------------------------
1760 void OKButton::Click()
1762 // close parent if no link set
1763 if ( !GetClickHdl() )
1765 Window
* pParent
= getNonLayoutParent(this);
1766 if ( pParent
->IsSystemWindow() )
1768 if ( pParent
->IsDialog() )
1770 if ( ((Dialog
*)pParent
)->IsInExecute() )
1771 ((Dialog
*)pParent
)->EndDialog( sal_True
);
1772 // prevent recursive calls
1773 else if ( !((Dialog
*)pParent
)->IsInClose() )
1775 if ( pParent
->GetStyle() & WB_CLOSEABLE
)
1776 ((Dialog
*)pParent
)->Close();
1781 if ( pParent
->GetStyle() & WB_CLOSEABLE
)
1782 ((SystemWindow
*)pParent
)->Close();
1788 PushButton::Click();
1792 // =======================================================================
1794 void CancelButton::ImplInit( Window
* pParent
, WinBits nStyle
)
1796 PushButton::ImplInit( pParent
, nStyle
);
1798 SetText( Button::GetStandardText( BUTTON_CANCEL
) );
1799 SetHelpText( Button::GetStandardHelpText( BUTTON_CANCEL
) );
1802 // -----------------------------------------------------------------------
1804 CancelButton::CancelButton( Window
* pParent
, WinBits nStyle
) :
1805 PushButton( WINDOW_CANCELBUTTON
)
1807 ImplInit( pParent
, nStyle
);
1810 // -----------------------------------------------------------------------
1812 CancelButton::CancelButton( Window
* pParent
, const ResId
& rResId
) :
1813 PushButton( WINDOW_CANCELBUTTON
)
1815 rResId
.SetRT( RSC_CANCELBUTTON
);
1816 WinBits nStyle
= ImplInitRes( rResId
);
1817 ImplInit( pParent
, nStyle
);
1818 ImplLoadRes( rResId
);
1820 if ( !(nStyle
& WB_HIDE
) )
1824 // -----------------------------------------------------------------------
1826 void CancelButton::Click()
1828 // close parent if link not set
1829 if ( !GetClickHdl() )
1831 Window
* pParent
= getNonLayoutParent(this);
1832 if ( pParent
->IsSystemWindow() )
1834 if ( pParent
->IsDialog() )
1836 if ( ((Dialog
*)pParent
)->IsInExecute() )
1837 ((Dialog
*)pParent
)->EndDialog( sal_False
);
1838 // prevent recursive calls
1839 else if ( !((Dialog
*)pParent
)->IsInClose() )
1841 if ( pParent
->GetStyle() & WB_CLOSEABLE
)
1842 ((Dialog
*)pParent
)->Close();
1847 if ( pParent
->GetStyle() & WB_CLOSEABLE
)
1848 ((SystemWindow
*)pParent
)->Close();
1854 PushButton::Click();
1858 CloseButton::CloseButton( Window
* pParent
, WinBits nStyle
)
1859 : CancelButton(pParent
, nStyle
)
1861 SetText( Button::GetStandardText( BUTTON_CLOSE
) );
1862 SetHelpText( Button::GetStandardHelpText( BUTTON_CLOSE
) );
1865 // =======================================================================
1867 void HelpButton::ImplInit( Window
* pParent
, WinBits nStyle
)
1869 PushButton::ImplInit( pParent
, nStyle
| WB_NOPOINTERFOCUS
);
1871 SetText( Button::GetStandardText( BUTTON_HELP
) );
1872 SetHelpText( Button::GetStandardHelpText( BUTTON_HELP
) );
1875 // -----------------------------------------------------------------------
1877 HelpButton::HelpButton( Window
* pParent
, WinBits nStyle
) :
1878 PushButton( WINDOW_HELPBUTTON
)
1880 ImplInit( pParent
, nStyle
);
1883 // -----------------------------------------------------------------------
1885 HelpButton::HelpButton( Window
* pParent
, const ResId
& rResId
) :
1886 PushButton( WINDOW_HELPBUTTON
)
1888 rResId
.SetRT( RSC_HELPBUTTON
);
1889 WinBits nStyle
= ImplInitRes( rResId
);
1890 ImplInit( pParent
, nStyle
);
1891 ImplLoadRes( rResId
);
1893 if ( !(nStyle
& WB_HIDE
) )
1897 // -----------------------------------------------------------------------
1899 void HelpButton::Click()
1901 // trigger help if no link set
1902 if ( !GetClickHdl() )
1904 Window
* pFocusWin
= Application::GetFocusWindow();
1908 HelpEvent
aEvt( pFocusWin
->GetPointerPosPixel(), HELPMODE_CONTEXT
);
1909 pFocusWin
->RequestHelp( aEvt
);
1911 PushButton::Click();
1914 // =======================================================================
1916 void RadioButton::ImplInitRadioButtonData()
1918 mbChecked
= sal_False
;
1919 mbSaveValue
= sal_False
;
1920 mbRadioCheck
= sal_True
;
1921 mbStateChanged
= sal_False
;
1924 // -----------------------------------------------------------------------
1926 void RadioButton::ImplInit( Window
* pParent
, WinBits nStyle
)
1928 nStyle
= ImplInitStyle( pParent
->GetWindow( WINDOW_LASTCHILD
), nStyle
);
1929 Button::ImplInit( pParent
, nStyle
, NULL
);
1931 ImplInitSettings( sal_True
, sal_True
, sal_True
);
1934 // -----------------------------------------------------------------------
1936 WinBits
RadioButton::ImplInitStyle( const Window
* pPrevWindow
, WinBits nStyle
)
1938 if ( !(nStyle
& WB_NOGROUP
) &&
1939 (!pPrevWindow
|| (pPrevWindow
->GetType() != WINDOW_RADIOBUTTON
)) )
1941 if ( !(nStyle
& WB_NOTABSTOP
) )
1944 nStyle
|= WB_TABSTOP
;
1946 nStyle
&= ~WB_TABSTOP
;
1951 // -----------------------------------------------------------------
1953 const Font
& RadioButton::GetCanonicalFont( const StyleSettings
& _rStyle
) const
1955 return _rStyle
.GetRadioCheckFont();
1958 // -----------------------------------------------------------------
1959 const Color
& RadioButton::GetCanonicalTextColor( const StyleSettings
& _rStyle
) const
1961 return _rStyle
.GetRadioCheckTextColor();
1964 // -----------------------------------------------------------------------
1966 void RadioButton::ImplInitSettings( sal_Bool bFont
,
1967 sal_Bool bForeground
, sal_Bool bBackground
)
1969 Button::ImplInitSettings( bFont
, bForeground
);
1973 Window
* pParent
= GetParent();
1974 if ( !IsControlBackground() &&
1975 (pParent
->IsChildTransparentModeEnabled() || IsNativeControlSupported( CTRL_RADIOBUTTON
, PART_ENTIRE_CONTROL
) ) )
1977 EnableChildTransparentMode( sal_True
);
1978 SetParentClipMode( PARENTCLIPMODE_NOCLIP
);
1979 SetPaintTransparent( sal_True
);
1981 if( IsNativeControlSupported( CTRL_RADIOBUTTON
, PART_ENTIRE_CONTROL
) )
1982 mpWindowImpl
->mbUseNativeFocus
= ImplGetSVData()->maNWFData
.mbNoFocusRects
;
1986 EnableChildTransparentMode( sal_False
);
1987 SetParentClipMode( 0 );
1988 SetPaintTransparent( sal_False
);
1990 if ( IsControlBackground() )
1991 SetBackground( GetControlBackground() );
1993 SetBackground( pParent
->GetBackground() );
1998 void RadioButton::DrawRadioButtonState( )
2000 ImplDrawRadioButtonState( );
2003 // -----------------------------------------------------------------------
2005 void RadioButton::ImplInvalidateOrDrawRadioButtonState()
2007 if( ImplGetSVData()->maNWFData
.mbCheckBoxNeedsErase
)
2009 if ( IsNativeControlSupported(CTRL_RADIOBUTTON
, PART_ENTIRE_CONTROL
) )
2016 ImplDrawRadioButtonState();
2019 void RadioButton::ImplDrawRadioButtonState()
2021 sal_Bool bNativeOK
= sal_False
;
2023 // no native drawing for image radio buttons
2024 if ( !maImage
&& (bNativeOK
=IsNativeControlSupported(CTRL_RADIOBUTTON
, PART_ENTIRE_CONTROL
)) == sal_True
)
2026 ImplControlValue
aControlValue( mbChecked
? BUTTONVALUE_ON
: BUTTONVALUE_OFF
);
2027 Rectangle
aCtrlRect( maStateRect
.TopLeft(), maStateRect
.GetSize() );
2028 ControlState nState
= 0;
2030 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED
) nState
|= CTRL_STATE_PRESSED
;
2031 if ( HasFocus() ) nState
|= CTRL_STATE_FOCUSED
;
2032 if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT
) nState
|= CTRL_STATE_DEFAULT
;
2033 if ( IsEnabled() ) nState
|= CTRL_STATE_ENABLED
;
2035 if ( IsMouseOver() && maMouseRect
.IsInside( GetPointerPosPixel() ) )
2036 nState
|= CTRL_STATE_ROLLOVER
;
2038 bNativeOK
= DrawNativeControl( CTRL_RADIOBUTTON
, PART_ENTIRE_CONTROL
, aCtrlRect
, nState
,
2039 aControlValue
,OUString() );
2043 if ( bNativeOK
== sal_False
)
2045 // kein Image-RadioButton
2048 sal_uInt16 nStyle
= ImplGetButtonState();
2050 nStyle
|= BUTTON_DRAW_DISABLED
;
2052 nStyle
|= BUTTON_DRAW_CHECKED
;
2053 Image aImage
= GetRadioImage( GetSettings(), nStyle
);
2055 DrawImage( maStateRect
.TopLeft(), maStateRect
.GetSize(), aImage
);
2057 DrawImage( maStateRect
.TopLeft(), aImage
);
2063 DecorationView
aDecoView( this );
2064 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
2065 Rectangle aImageRect
= maStateRect
;
2066 Size aImageSize
= maImage
.GetSizePixel();
2067 sal_Bool bEnabled
= IsEnabled();
2068 sal_uInt16 nButtonStyle
= FRAME_DRAW_DOUBLEIN
;
2070 aImageSize
.Width() = CalcZoom( aImageSize
.Width() );
2071 aImageSize
.Height() = CalcZoom( aImageSize
.Height() );
2073 // display border and selection status
2074 aImageRect
= aDecoView
.DrawFrame( aImageRect
, nButtonStyle
);
2075 if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED
) || !bEnabled
)
2076 SetFillColor( rStyleSettings
.GetFaceColor() );
2078 SetFillColor( rStyleSettings
.GetFieldColor() );
2080 DrawRect( aImageRect
);
2085 nButtonStyle
|= IMAGE_DRAW_DISABLE
;
2087 Image
*pImage
= &maImage
;
2089 Point
aImagePos( aImageRect
.TopLeft() );
2090 aImagePos
.X() += (aImageRect
.GetWidth()-aImageSize
.Width())/2;
2091 aImagePos
.Y() += (aImageRect
.GetHeight()-aImageSize
.Height())/2;
2093 DrawImage( aImagePos
, aImageSize
, *pImage
, nButtonStyle
);
2095 DrawImage( aImagePos
, *pImage
, nButtonStyle
);
2097 aImageRect
.Left()++;
2099 aImageRect
.Right()--;
2100 aImageRect
.Bottom()--;
2102 ImplSetFocusRect( aImageRect
);
2106 SetLineColor( rStyleSettings
.GetHighlightColor() );
2108 if ( (aImageSize
.Width() >= 20) || (aImageSize
.Height() >= 20) )
2110 aImageRect
.Left()++;
2112 aImageRect
.Right()--;
2113 aImageRect
.Bottom()--;
2115 DrawRect( aImageRect
);
2116 aImageRect
.Left()++;
2118 aImageRect
.Right()--;
2119 aImageRect
.Bottom()--;
2120 DrawRect( aImageRect
);
2124 ShowFocus( ImplGetFocusRect() );
2129 // -----------------------------------------------------------------------
2131 void RadioButton::ImplDraw( OutputDevice
* pDev
, sal_uLong nDrawFlags
,
2132 const Point
& rPos
, const Size
& rSize
,
2133 const Size
& rImageSize
, Rectangle
& rStateRect
,
2134 Rectangle
& rMouseRect
, bool bLayout
)
2136 WinBits nWinStyle
= GetStyle();
2137 OUString
aText( GetText() );
2138 MetricVector
* pVector
= bLayout
? &mpControlData
->mpLayoutData
->m_aUnicodeBoundRects
: NULL
;
2139 OUString
* pDisplayText
= bLayout
? &mpControlData
->mpLayoutData
->m_aDisplayText
: NULL
;
2141 pDev
->Push( PUSH_CLIPREGION
);
2142 pDev
->IntersectClipRegion( Rectangle( rPos
, rSize
) );
2144 // no image radio button
2147 if ( ( !aText
.isEmpty() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT
) ) ||
2148 ( HasImage() && ! (ImplGetButtonState() & BUTTON_DRAW_NOIMAGE
) ) )
2150 sal_uInt16 nTextStyle
= Button::ImplGetTextStyle( aText
, nWinStyle
, nDrawFlags
);
2152 const long nImageSep
= GetDrawPixel( pDev
, ImplGetImageToTextDistance() );
2153 Size
aSize( rSize
);
2155 aPos
.X() += rImageSize
.Width() + nImageSep
;
2156 aSize
.Width() -= rImageSize
.Width() + nImageSep
;
2158 // if the text rect height is smaller than the height of the image
2159 // then for single lines the default should be centered text
2160 if( (nWinStyle
& (WB_TOP
|WB_VCENTER
|WB_BOTTOM
)) == 0 &&
2161 (rImageSize
.Height() > rSize
.Height() || ! (nWinStyle
& WB_WORDBREAK
) ) )
2163 nTextStyle
&= ~(TEXT_DRAW_TOP
|TEXT_DRAW_BOTTOM
);
2164 nTextStyle
|= TEXT_DRAW_VCENTER
;
2165 aSize
.Height() = rImageSize
.Height();
2168 ImplDrawAlignedImage( pDev
, aPos
, aSize
, bLayout
, 1,
2169 nDrawFlags
, nTextStyle
, NULL
);
2171 rMouseRect
= Rectangle( aPos
, aSize
);
2172 rMouseRect
.Left() = rPos
.X();
2174 rStateRect
.Left() = rPos
.X();
2175 rStateRect
.Top() = rMouseRect
.Top();
2177 if ( aSize
.Height() > rImageSize
.Height() )
2178 rStateRect
.Top() += ( aSize
.Height() - rImageSize
.Height() ) / 2;
2181 rStateRect
.Top() -= ( rImageSize
.Height() - aSize
.Height() ) / 2;
2182 if( rStateRect
.Top() < 0 )
2183 rStateRect
.Top() = 0;
2186 rStateRect
.Right() = rStateRect
.Left() + rImageSize
.Width()-1;
2187 rStateRect
.Bottom() = rStateRect
.Top() + rImageSize
.Height()-1;
2189 if ( rStateRect
.Bottom() > rMouseRect
.Bottom() )
2190 rMouseRect
.Bottom() = rStateRect
.Bottom();
2194 if ( mbLegacyNoTextAlign
&& ( nWinStyle
& WB_CENTER
) )
2195 rStateRect
.Left() = rPos
.X()+((rSize
.Width()-rImageSize
.Width())/2);
2196 else if ( mbLegacyNoTextAlign
&& ( nWinStyle
& WB_RIGHT
) )
2197 rStateRect
.Left() = rPos
.X()+rSize
.Width()-rImageSize
.Width(); //-1;
2199 rStateRect
.Left() = rPos
.X(); //+1;
2200 if ( nWinStyle
& WB_VCENTER
)
2201 rStateRect
.Top() = rPos
.Y()+((rSize
.Height()-rImageSize
.Height())/2);
2202 else if ( nWinStyle
& WB_BOTTOM
)
2203 rStateRect
.Top() = rPos
.Y()+rSize
.Height()-rImageSize
.Height(); //-1;
2205 rStateRect
.Top() = rPos
.Y(); //+1;
2206 rStateRect
.Right() = rStateRect
.Left()+rImageSize
.Width()-1;
2207 rStateRect
.Bottom() = rStateRect
.Top()+rImageSize
.Height()-1;
2208 rMouseRect
= rStateRect
;
2210 ImplSetFocusRect( rStateRect
);
2212 /* and above -1 because CalcSize() does not include focus-rectangle since images would be even
2213 positioned higher in writer
2214 rFocusRect = rStateRect;
2215 rFocusRect.Left()--;
2217 rFocusRect.Right()++;
2218 rFocusRect.Bottom()++;
2224 bool bTopImage
= (nWinStyle
& WB_TOP
) != 0;
2225 Size aImageSize
= maImage
.GetSizePixel();
2226 Rectangle
aImageRect( rPos
, rSize
);
2227 long nTextHeight
= pDev
->GetTextHeight();
2228 long nTextWidth
= pDev
->GetCtrlTextWidth( aText
);
2230 // calculate position and sizes
2231 if ( !aText
.isEmpty() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT
) )
2233 Size
aTmpSize( (aImageSize
.Width()+8), (aImageSize
.Height()+8) );
2236 aImageRect
.Left() = (rSize
.Width()-aTmpSize
.Width())/2;
2237 aImageRect
.Top() = (rSize
.Height()-(aTmpSize
.Height()+nTextHeight
+6))/2;
2240 aImageRect
.Top() = (rSize
.Height()-aTmpSize
.Height())/2;
2242 aImageRect
.Right() = aImageRect
.Left()+aTmpSize
.Width();
2243 aImageRect
.Bottom() = aImageRect
.Top()+aTmpSize
.Height();
2246 Point aTxtPos
= rPos
;
2249 aTxtPos
.X() += (rSize
.Width()-nTextWidth
)/2;
2250 aTxtPos
.Y() += aImageRect
.Bottom()+6;
2254 aTxtPos
.X() += aImageRect
.Right()+8;
2255 aTxtPos
.Y() += (rSize
.Height()-nTextHeight
)/2;
2257 pDev
->DrawCtrlText( aTxtPos
, aText
, 0, STRING_LEN
, TEXT_DRAW_MNEMONIC
, pVector
, pDisplayText
);
2260 rMouseRect
= aImageRect
;
2261 rStateRect
= aImageRect
;
2267 // -----------------------------------------------------------------------
2269 void RadioButton::ImplDrawRadioButton( bool bLayout
)
2276 aImageSize
= ImplGetRadioImageSize();
2278 aImageSize
= maImage
.GetSizePixel();
2279 aImageSize
.Width() = CalcZoom( aImageSize
.Width() );
2280 aImageSize
.Height() = CalcZoom( aImageSize
.Height() );
2282 // Draw control text
2283 ImplDraw( this, 0, Point(), GetOutputSizePixel(),
2284 aImageSize
, maStateRect
, maMouseRect
, bLayout
);
2286 if( !bLayout
|| (IsNativeControlSupported(CTRL_RADIOBUTTON
, PART_ENTIRE_CONTROL
)==sal_True
) )
2288 if ( !maImage
&& HasFocus() )
2289 ShowFocus( ImplGetFocusRect() );
2291 ImplDrawRadioButtonState();
2295 void RadioButton::group(RadioButton
&rOther
)
2297 if (&rOther
== this)
2302 m_xGroup
.reset(new std::vector
<RadioButton
*>);
2303 m_xGroup
->push_back(this);
2306 std::vector
<RadioButton
*>::iterator aFind
= std::find(m_xGroup
->begin(), m_xGroup
->end(), &rOther
);
2307 if (aFind
== m_xGroup
->end())
2309 m_xGroup
->push_back(&rOther
);
2311 if (rOther
.m_xGroup
)
2313 std::vector
< RadioButton
* > aOthers(rOther
.GetRadioButtonGroup(false));
2314 //make all members of the group share the same button group
2315 for (std::vector
<RadioButton
*>::iterator aI
= aOthers
.begin(), aEnd
= aOthers
.end(); aI
!= aEnd
; ++aI
)
2317 aFind
= std::find(m_xGroup
->begin(), m_xGroup
->end(), *aI
);
2318 if (aFind
== m_xGroup
->end())
2319 m_xGroup
->push_back(*aI
);
2323 //make all members of the group share the same button group
2324 for (std::vector
<RadioButton
*>::iterator aI
= m_xGroup
->begin(), aEnd
= m_xGroup
->end();
2327 RadioButton
* pButton
= *aI
;
2328 pButton
->m_xGroup
= m_xGroup
;
2332 //if this one is checked, uncheck all the others
2334 ImplUncheckAllOther();
2337 // .-----------------------------------------------------------------------
2339 std::vector
< RadioButton
* > RadioButton::GetRadioButtonGroup(bool bIncludeThis
) const
2345 std::vector
< RadioButton
* > aGroup
;
2346 for (std::vector
<RadioButton
*>::iterator aI
= m_xGroup
->begin(), aEnd
= m_xGroup
->end(); aI
!= aEnd
; ++aI
)
2348 RadioButton
*pRadioButton
= *aI
;
2349 if (pRadioButton
== this)
2351 aGroup
.push_back(pRadioButton
);
2357 SAL_WARN("vcl.control", "No new-style group set on radiobutton, using old-style digging around");
2359 // go back to first in group;
2360 Window
* pFirst
= const_cast<RadioButton
*>(this);
2361 while( ( pFirst
->GetStyle() & WB_GROUP
) == 0 )
2363 Window
* pWindow
= pFirst
->GetWindow( WINDOW_PREV
);
2369 std::vector
< RadioButton
* > aGroup
;
2370 // insert radiobuttons up to next group
2373 if( pFirst
->GetType() == WINDOW_RADIOBUTTON
)
2375 if( pFirst
!= this || bIncludeThis
)
2376 aGroup
.push_back( static_cast<RadioButton
*>(pFirst
) );
2378 pFirst
= pFirst
->GetWindow( WINDOW_NEXT
);
2379 } while( pFirst
&& ( ( pFirst
->GetStyle() & WB_GROUP
) == 0 ) );
2384 // -----------------------------------------------------------------------
2386 void RadioButton::ImplUncheckAllOther()
2388 mpWindowImpl
->mnStyle
|= WB_TABSTOP
;
2390 std::vector
<RadioButton
*> aGroup(GetRadioButtonGroup(false));
2391 // iterate over radio button group and checked buttons
2392 for (std::vector
<RadioButton
*>::iterator aI
= aGroup
.begin(), aEnd
= aGroup
.end(); aI
!= aEnd
; ++aI
)
2394 RadioButton
*pWindow
= *aI
;
2395 if ( pWindow
->IsChecked() )
2397 ImplDelData aDelData
;
2398 pWindow
->ImplAddDel( &aDelData
);
2399 pWindow
->SetState( sal_False
);
2400 if ( aDelData
.IsDead() )
2402 pWindow
->ImplRemoveDel( &aDelData
);
2405 // not inside if clause to always remove wrongly set WB_TABSTOPS
2406 pWindow
->mpWindowImpl
->mnStyle
&= ~WB_TABSTOP
;
2410 // -----------------------------------------------------------------------
2412 void RadioButton::ImplCallClick( sal_Bool bGrabFocus
, sal_uInt16 nFocusFlags
)
2414 mbStateChanged
= !mbChecked
;
2415 mbChecked
= sal_True
;
2416 mpWindowImpl
->mnStyle
|= WB_TABSTOP
;
2417 ImplInvalidateOrDrawRadioButtonState();
2418 ImplDelData aDelData
;
2419 ImplAddDel( &aDelData
);
2421 ImplUncheckAllOther();
2422 if ( aDelData
.IsDead() )
2425 ImplGrabFocus( nFocusFlags
);
2426 if ( aDelData
.IsDead() )
2428 if ( mbStateChanged
)
2430 if ( aDelData
.IsDead() )
2433 if ( aDelData
.IsDead() )
2435 ImplRemoveDel( &aDelData
);
2436 mbStateChanged
= sal_False
;
2439 // -----------------------------------------------------------------------
2441 RadioButton::RadioButton( Window
* pParent
, WinBits nStyle
) :
2442 Button( WINDOW_RADIOBUTTON
), mbLegacyNoTextAlign( false )
2444 ImplInitRadioButtonData();
2445 ImplInit( pParent
, nStyle
);
2448 // -----------------------------------------------------------------------
2450 RadioButton::RadioButton( Window
* pParent
, const ResId
& rResId
) :
2451 Button( WINDOW_RADIOBUTTON
), mbLegacyNoTextAlign( false )
2453 rResId
.SetRT( RSC_RADIOBUTTON
);
2454 WinBits nStyle
= ImplInitRes( rResId
);
2455 ImplInitRadioButtonData();
2456 ImplInit( pParent
, nStyle
);
2457 ImplLoadRes( rResId
);
2459 if ( !(nStyle
& WB_HIDE
) )
2463 // -----------------------------------------------------------------------
2465 void RadioButton::ImplLoadRes( const ResId
& rResId
)
2467 Button::ImplLoadRes( rResId
);
2469 //anderer Wert als Default ?
2470 sal_uInt16 nChecked
= ReadShortRes();
2472 SetState( sal_True
);
2475 // -----------------------------------------------------------------------
2477 RadioButton::~RadioButton()
2481 m_xGroup
->erase(std::remove(m_xGroup
->begin(), m_xGroup
->end(), this),
2486 // -----------------------------------------------------------------------
2488 void RadioButton::MouseButtonDown( const MouseEvent
& rMEvt
)
2490 if ( rMEvt
.IsLeft() && maMouseRect
.IsInside( rMEvt
.GetPosPixel() ) )
2492 ImplGetButtonState() |= BUTTON_DRAW_PRESSED
;
2493 ImplInvalidateOrDrawRadioButtonState();
2498 Button::MouseButtonDown( rMEvt
);
2501 // -----------------------------------------------------------------------
2503 void RadioButton::Tracking( const TrackingEvent
& rTEvt
)
2505 if ( rTEvt
.IsTrackingEnded() )
2507 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED
)
2509 if ( !(GetStyle() & WB_NOPOINTERFOCUS
) && !rTEvt
.IsTrackingCanceled() )
2512 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED
;
2514 // do not call click handler if aborted
2515 if ( !rTEvt
.IsTrackingCanceled() )
2518 ImplInvalidateOrDrawRadioButtonState();
2523 if ( maMouseRect
.IsInside( rTEvt
.GetMouseEvent().GetPosPixel() ) )
2525 if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED
) )
2527 ImplGetButtonState() |= BUTTON_DRAW_PRESSED
;
2528 ImplInvalidateOrDrawRadioButtonState();
2533 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED
)
2535 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED
;
2536 ImplInvalidateOrDrawRadioButtonState();
2542 // -----------------------------------------------------------------------
2544 void RadioButton::KeyInput( const KeyEvent
& rKEvt
)
2546 KeyCode aKeyCode
= rKEvt
.GetKeyCode();
2548 if ( !aKeyCode
.GetModifier() && (aKeyCode
.GetCode() == KEY_SPACE
) )
2550 if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED
) )
2552 ImplGetButtonState() |= BUTTON_DRAW_PRESSED
;
2553 ImplInvalidateOrDrawRadioButtonState();
2556 else if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED
) && (aKeyCode
.GetCode() == KEY_ESCAPE
) )
2558 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED
;
2559 ImplInvalidateOrDrawRadioButtonState();
2562 Button::KeyInput( rKEvt
);
2565 // -----------------------------------------------------------------------
2567 void RadioButton::KeyUp( const KeyEvent
& rKEvt
)
2569 KeyCode aKeyCode
= rKEvt
.GetKeyCode();
2571 if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED
) && (aKeyCode
.GetCode() == KEY_SPACE
) )
2573 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED
;
2577 Button::KeyUp( rKEvt
);
2580 // -----------------------------------------------------------------------
2582 void RadioButton::FillLayoutData() const
2584 mpControlData
->mpLayoutData
= new vcl::ControlLayoutData();
2585 const_cast<RadioButton
*>(this)->ImplDrawRadioButton( true );
2588 // -----------------------------------------------------------------------
2590 void RadioButton::Paint( const Rectangle
& )
2592 ImplDrawRadioButton();
2595 // -----------------------------------------------------------------------
2597 void RadioButton::Draw( OutputDevice
* pDev
, const Point
& rPos
, const Size
& rSize
,
2602 MapMode
aResMapMode( MAP_100TH_MM
);
2603 Point aPos
= pDev
->LogicToPixel( rPos
);
2604 Size aSize
= pDev
->LogicToPixel( rSize
);
2605 Size aImageSize
= pDev
->LogicToPixel( Size( 300, 300 ), aResMapMode
);
2606 Size aBrd1Size
= pDev
->LogicToPixel( Size( 20, 20 ), aResMapMode
);
2607 Size aBrd2Size
= pDev
->LogicToPixel( Size( 60, 60 ), aResMapMode
);
2608 Font aFont
= GetDrawPixelFont( pDev
);
2609 Rectangle aStateRect
;
2610 Rectangle aMouseRect
;
2612 aImageSize
.Width() = CalcZoom( aImageSize
.Width() );
2613 aImageSize
.Height() = CalcZoom( aImageSize
.Height() );
2614 aBrd1Size
.Width() = CalcZoom( aBrd1Size
.Width() );
2615 aBrd1Size
.Height() = CalcZoom( aBrd1Size
.Height() );
2616 aBrd2Size
.Width() = CalcZoom( aBrd2Size
.Width() );
2617 aBrd2Size
.Height() = CalcZoom( aBrd2Size
.Height() );
2619 if ( !aBrd1Size
.Width() )
2620 aBrd1Size
.Width() = 1;
2621 if ( !aBrd1Size
.Height() )
2622 aBrd1Size
.Height() = 1;
2623 if ( !aBrd2Size
.Width() )
2624 aBrd2Size
.Width() = 1;
2625 if ( !aBrd2Size
.Height() )
2626 aBrd2Size
.Height() = 1;
2630 pDev
->SetFont( aFont
);
2631 if ( nFlags
& WINDOW_DRAW_MONO
)
2632 pDev
->SetTextColor( Color( COL_BLACK
) );
2634 pDev
->SetTextColor( GetTextColor() );
2635 pDev
->SetTextFillColor();
2637 ImplDraw( pDev
, nFlags
, aPos
, aSize
,
2638 aImageSize
, aStateRect
, aMouseRect
);
2640 Point aCenterPos
= aStateRect
.Center();
2641 long nRadX
= aImageSize
.Width()/2;
2642 long nRadY
= aImageSize
.Height()/2;
2644 pDev
->SetLineColor();
2645 pDev
->SetFillColor( Color( COL_BLACK
) );
2646 pDev
->DrawPolygon( Polygon( aCenterPos
, nRadX
, nRadY
) );
2647 nRadX
-= aBrd1Size
.Width();
2648 nRadY
-= aBrd1Size
.Height();
2649 pDev
->SetFillColor( Color( COL_WHITE
) );
2650 pDev
->DrawPolygon( Polygon( aCenterPos
, nRadX
, nRadY
) );
2653 nRadX
-= aBrd1Size
.Width();
2654 nRadY
-= aBrd1Size
.Height();
2659 pDev
->SetFillColor( Color( COL_BLACK
) );
2660 pDev
->DrawPolygon( Polygon( aCenterPos
, nRadX
, nRadY
) );
2667 OSL_FAIL( "RadioButton::Draw() - not implemented for RadioButton with Image" );
2671 // -----------------------------------------------------------------------
2673 void RadioButton::Resize()
2679 // -----------------------------------------------------------------------
2681 void RadioButton::GetFocus()
2683 ShowFocus( ImplGetFocusRect() );
2684 SetInputContext( InputContext( GetFont() ) );
2688 // -----------------------------------------------------------------------
2690 void RadioButton::LoseFocus()
2692 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED
)
2694 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED
;
2695 ImplInvalidateOrDrawRadioButtonState();
2699 Button::LoseFocus();
2702 // -----------------------------------------------------------------------
2704 void RadioButton::StateChanged( StateChangedType nType
)
2706 Button::StateChanged( nType
);
2708 if ( nType
== STATE_CHANGE_STATE
)
2710 if ( IsReallyVisible() && IsUpdateMode() )
2711 Invalidate( maStateRect
);
2713 else if ( (nType
== STATE_CHANGE_ENABLE
) ||
2714 (nType
== STATE_CHANGE_TEXT
) ||
2715 (nType
== STATE_CHANGE_IMAGE
) ||
2716 (nType
== STATE_CHANGE_DATA
) ||
2717 (nType
== STATE_CHANGE_UPDATEMODE
) )
2719 if ( IsUpdateMode() )
2722 else if ( nType
== STATE_CHANGE_STYLE
)
2724 SetStyle( ImplInitStyle( GetWindow( WINDOW_PREV
), GetStyle() ) );
2726 if ( (GetPrevStyle() & RADIOBUTTON_VIEW_STYLE
) !=
2727 (GetStyle() & RADIOBUTTON_VIEW_STYLE
) )
2729 if ( IsUpdateMode() )
2733 else if ( (nType
== STATE_CHANGE_ZOOM
) ||
2734 (nType
== STATE_CHANGE_CONTROLFONT
) )
2736 ImplInitSettings( sal_True
, sal_False
, sal_False
);
2739 else if ( nType
== STATE_CHANGE_CONTROLFOREGROUND
)
2741 ImplInitSettings( sal_False
, sal_True
, sal_False
);
2744 else if ( nType
== STATE_CHANGE_CONTROLBACKGROUND
)
2746 ImplInitSettings( sal_False
, sal_False
, sal_True
);
2751 // -----------------------------------------------------------------------
2753 void RadioButton::DataChanged( const DataChangedEvent
& rDCEvt
)
2755 Button::DataChanged( rDCEvt
);
2757 if ( (rDCEvt
.GetType() == DATACHANGED_FONTS
) ||
2758 (rDCEvt
.GetType() == DATACHANGED_FONTSUBSTITUTION
) ||
2759 ((rDCEvt
.GetType() == DATACHANGED_SETTINGS
) &&
2760 (rDCEvt
.GetFlags() & SETTINGS_STYLE
)) )
2762 ImplInitSettings( sal_True
, sal_True
, sal_True
);
2767 // -----------------------------------------------------------------------
2769 long RadioButton::PreNotify( NotifyEvent
& rNEvt
)
2772 const MouseEvent
* pMouseEvt
= NULL
;
2774 if( (rNEvt
.GetType() == EVENT_MOUSEMOVE
) && (pMouseEvt
= rNEvt
.GetMouseEvent()) != NULL
)
2776 if( !pMouseEvt
->GetButtons() && !pMouseEvt
->IsSynthetic() && !pMouseEvt
->IsModifierChanged() )
2778 // trigger redraw if mouse over state has changed
2779 if( IsNativeControlSupported(CTRL_RADIOBUTTON
, PART_ENTIRE_CONTROL
) )
2781 if( ( maMouseRect
.IsInside( GetPointerPosPixel()) &&
2782 !maMouseRect
.IsInside( GetLastPointerPosPixel()) ) ||
2783 ( maMouseRect
.IsInside( GetLastPointerPosPixel()) &&
2784 !maMouseRect
.IsInside( GetPointerPosPixel()) ) ||
2785 pMouseEvt
->IsLeaveWindow() || pMouseEvt
->IsEnterWindow() )
2787 Invalidate( maStateRect
);
2793 return nDone
? nDone
: Button::PreNotify(rNEvt
);
2796 // -----------------------------------------------------------------------
2798 void RadioButton::Toggle()
2800 ImplCallEventListenersAndHandler( VCLEVENT_RADIOBUTTON_TOGGLE
, maToggleHdl
, this );
2803 // -----------------------------------------------------------------------
2805 sal_Bool
RadioButton::SetModeRadioImage( const Image
& rImage
)
2807 if ( rImage
!= maImage
)
2810 StateChanged( STATE_CHANGE_DATA
);
2816 // -----------------------------------------------------------------------
2818 const Image
& RadioButton::GetModeRadioImage( ) const
2823 // -----------------------------------------------------------------------
2825 void RadioButton::SetState( sal_Bool bCheck
)
2827 // TabStop-Flag richtig mitfuehren
2829 mpWindowImpl
->mnStyle
|= WB_TABSTOP
;
2831 mpWindowImpl
->mnStyle
&= ~WB_TABSTOP
;
2833 if ( mbChecked
!= bCheck
)
2836 StateChanged( STATE_CHANGE_STATE
);
2841 bool RadioButton::set_property(const OString
&rKey
, const OString
&rValue
)
2843 if (rKey
== "active")
2844 SetState(toBool(rValue
));
2846 return Window::set_property(rKey
, rValue
);
2850 // -----------------------------------------------------------------------
2852 void RadioButton::Check( sal_Bool bCheck
)
2854 // TabStop-Flag richtig mitfuehren
2856 mpWindowImpl
->mnStyle
|= WB_TABSTOP
;
2858 mpWindowImpl
->mnStyle
&= ~WB_TABSTOP
;
2860 if ( mbChecked
!= bCheck
)
2863 ImplDelData aDelData
;
2864 ImplAddDel( &aDelData
);
2865 StateChanged( STATE_CHANGE_STATE
);
2866 if ( aDelData
.IsDead() )
2868 if ( bCheck
&& mbRadioCheck
)
2869 ImplUncheckAllOther();
2870 if ( aDelData
.IsDead() )
2873 ImplRemoveDel( &aDelData
);
2877 // -----------------------------------------------------------------------
2879 long RadioButton::ImplGetImageToTextDistance() const
2881 // 4 pixels, but take zoom into account, so the text doesn't "jump" relative to surrounding elements,
2882 // which might have been aligned with the text of the check box
2883 return CalcZoom( 4 );
2886 // -----------------------------------------------------------------------
2888 Size
RadioButton::ImplGetRadioImageSize() const
2891 // why are IsNativeControlSupported and GetNativeControlRegion not const ?
2892 RadioButton
* pThis
= const_cast<RadioButton
*>(this);
2893 bool bDefaultSize
= true;
2894 if( pThis
->IsNativeControlSupported( CTRL_RADIOBUTTON
, PART_ENTIRE_CONTROL
) )
2896 ImplControlValue aControlValue
;
2897 // #i45896# workaround gcc3.3 temporary problem
2898 Rectangle
aCtrlRegion( Point( 0, 0 ), GetSizePixel() );
2899 ControlState nState
= CTRL_STATE_DEFAULT
|CTRL_STATE_ENABLED
;
2900 Rectangle aBoundingRgn
, aContentRgn
;
2902 // get native size of a radio button
2903 if( pThis
->GetNativeControlRegion( CTRL_RADIOBUTTON
, PART_ENTIRE_CONTROL
, aCtrlRegion
,
2904 nState
, aControlValue
, OUString(),
2905 aBoundingRgn
, aContentRgn
) )
2907 aSize
= aContentRgn
.GetSize();
2908 bDefaultSize
= false;
2912 aSize
= GetRadioImage( GetSettings(), 0 ).GetSizePixel();
2916 static void LoadThemedImageList (const StyleSettings
&rStyleSettings
,
2917 ImageList
*pList
, const ResId
&rResId
,
2920 Color aColorAry1
[6];
2921 Color aColorAry2
[6];
2922 aColorAry1
[0] = Color( 0xC0, 0xC0, 0xC0 );
2923 aColorAry1
[1] = Color( 0xFF, 0xFF, 0x00 );
2924 aColorAry1
[2] = Color( 0xFF, 0xFF, 0xFF );
2925 aColorAry1
[3] = Color( 0x80, 0x80, 0x80 );
2926 aColorAry1
[4] = Color( 0x00, 0x00, 0x00 );
2927 aColorAry1
[5] = Color( 0x00, 0xFF, 0x00 );
2928 aColorAry2
[0] = rStyleSettings
.GetFaceColor();
2929 aColorAry2
[1] = rStyleSettings
.GetWindowColor();
2930 aColorAry2
[2] = rStyleSettings
.GetLightColor();
2931 aColorAry2
[3] = rStyleSettings
.GetShadowColor();
2932 aColorAry2
[4] = rStyleSettings
.GetDarkShadowColor();
2933 aColorAry2
[5] = rStyleSettings
.GetWindowTextColor();
2935 Color
aMaskColor(0x00, 0x00, 0xFF );
2936 DBG_ASSERT( sizeof(aColorAry1
) == sizeof(aColorAry2
), "aColorAry1 must match aColorAry2" );
2937 // FIXME: do we want the mask for the checkbox ?
2938 pList
->InsertFromHorizontalBitmap (rResId
, nImages
, &aMaskColor
,
2939 aColorAry1
, aColorAry2
, sizeof(aColorAry1
) / sizeof(Color
));
2942 Image
RadioButton::GetRadioImage( const AllSettings
& rSettings
, sal_uInt16 nFlags
)
2944 ImplSVData
* pSVData
= ImplGetSVData();
2945 const StyleSettings
& rStyleSettings
= rSettings
.GetStyleSettings();
2946 sal_uInt16 nStyle
= 0;
2948 if ( rStyleSettings
.GetOptions() & STYLE_OPTION_MONO
)
2949 nStyle
= STYLE_RADIOBUTTON_MONO
;
2951 if ( !pSVData
->maCtrlData
.mpRadioImgList
||
2952 (pSVData
->maCtrlData
.mnRadioStyle
!= nStyle
) ||
2953 (pSVData
->maCtrlData
.mnLastRadioFColor
!= rStyleSettings
.GetFaceColor().GetColor()) ||
2954 (pSVData
->maCtrlData
.mnLastRadioWColor
!= rStyleSettings
.GetWindowColor().GetColor()) ||
2955 (pSVData
->maCtrlData
.mnLastRadioLColor
!= rStyleSettings
.GetLightColor().GetColor()) )
2957 if ( pSVData
->maCtrlData
.mpRadioImgList
)
2958 delete pSVData
->maCtrlData
.mpRadioImgList
;
2960 pSVData
->maCtrlData
.mnLastRadioFColor
= rStyleSettings
.GetFaceColor().GetColor();
2961 pSVData
->maCtrlData
.mnLastRadioWColor
= rStyleSettings
.GetWindowColor().GetColor();
2962 pSVData
->maCtrlData
.mnLastRadioLColor
= rStyleSettings
.GetLightColor().GetColor();
2964 ResMgr
* pResMgr
= ImplGetResMgr();
2965 pSVData
->maCtrlData
.mpRadioImgList
= new ImageList();
2967 LoadThemedImageList( rStyleSettings
,
2968 pSVData
->maCtrlData
.mpRadioImgList
,
2969 ResId( SV_RESID_BITMAP_RADIO
+nStyle
, *pResMgr
), 6
2971 pSVData
->maCtrlData
.mnRadioStyle
= nStyle
;
2975 if ( nFlags
& BUTTON_DRAW_DISABLED
)
2977 if ( nFlags
& BUTTON_DRAW_CHECKED
)
2982 else if ( nFlags
& BUTTON_DRAW_PRESSED
)
2984 if ( nFlags
& BUTTON_DRAW_CHECKED
)
2991 if ( nFlags
& BUTTON_DRAW_CHECKED
)
2996 return pSVData
->maCtrlData
.mpRadioImgList
->GetImage( nId
);
2999 // -----------------------------------------------------------------------
3001 void RadioButton::ImplSetMinimumNWFSize()
3003 Push( PUSH_MAPMODE
);
3004 SetMapMode( MAP_PIXEL
);
3006 ImplControlValue aControlValue
;
3007 Size
aCurSize( GetSizePixel() );
3008 Rectangle
aCtrlRegion( Point( 0, 0 ), aCurSize
);
3009 Rectangle aBoundingRgn
, aContentRgn
;
3011 // get native size of a radiobutton
3012 if( GetNativeControlRegion( CTRL_RADIOBUTTON
, PART_ENTIRE_CONTROL
, aCtrlRegion
,
3013 CTRL_STATE_DEFAULT
|CTRL_STATE_ENABLED
, aControlValue
, OUString(),
3014 aBoundingRgn
, aContentRgn
) )
3016 Size aSize
= aContentRgn
.GetSize();
3018 if( aSize
.Height() > aCurSize
.Height() )
3020 aCurSize
.Height() = aSize
.Height();
3021 SetSizePixel( aCurSize
);
3028 // -----------------------------------------------------------------------
3030 Size
RadioButton::CalcMinimumSize( long nMaxWidth
) const
3034 aSize
= ImplGetRadioImageSize();
3036 aSize
= maImage
.GetSizePixel();
3038 nMaxWidth
-= aSize
.Width();
3040 OUString aText
= GetText();
3041 if ( !aText
.isEmpty() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT
) )
3043 // subtract what will be added later
3045 nMaxWidth
-= ImplGetImageToTextDistance();
3047 Size aTextSize
= GetTextRect( Rectangle( Point(), Size( nMaxWidth
> 0 ? nMaxWidth
: 0x7fffffff, 0x7fffffff ) ),
3048 aText
, FixedText::ImplGetTextStyle( GetStyle() ) ).GetSize();
3049 aSize
.Width()+=2; // for focus rect
3050 aSize
.Width() += ImplGetImageToTextDistance();
3051 aSize
.Width() += aTextSize
.Width();
3052 if ( aSize
.Height() < aTextSize
.Height() )
3053 aSize
.Height() = aTextSize
.Height();
3055 // else if ( !maImage )
3057 /* da ansonsten im Writer die Control zu weit oben haengen
3059 aSize.Height() += 2;
3063 return CalcWindowSize( aSize
);
3066 // -----------------------------------------------------------------------
3068 Size
RadioButton::GetOptimalSize() const
3070 return CalcMinimumSize();
3073 // =======================================================================
3075 void CheckBox::ImplInitCheckBoxData()
3077 meState
= STATE_NOCHECK
;
3078 meSaveValue
= STATE_NOCHECK
;
3079 mbTriState
= sal_False
;
3082 // -----------------------------------------------------------------------
3084 void CheckBox::ImplInit( Window
* pParent
, WinBits nStyle
)
3086 nStyle
= ImplInitStyle( pParent
->GetWindow( WINDOW_LASTCHILD
), nStyle
);
3087 Button::ImplInit( pParent
, nStyle
, NULL
);
3089 ImplInitSettings( sal_True
, sal_True
, sal_True
);
3092 // -----------------------------------------------------------------------
3094 WinBits
CheckBox::ImplInitStyle( const Window
* pPrevWindow
, WinBits nStyle
)
3096 if ( !(nStyle
& WB_NOTABSTOP
) )
3097 nStyle
|= WB_TABSTOP
;
3098 if ( !(nStyle
& WB_NOGROUP
) &&
3099 (!pPrevWindow
|| (pPrevWindow
->GetType() != WINDOW_CHECKBOX
)) )
3104 // -----------------------------------------------------------------
3106 const Font
& CheckBox::GetCanonicalFont( const StyleSettings
& _rStyle
) const
3108 return _rStyle
.GetRadioCheckFont();
3111 // -----------------------------------------------------------------
3112 const Color
& CheckBox::GetCanonicalTextColor( const StyleSettings
& _rStyle
) const
3114 return _rStyle
.GetRadioCheckTextColor();
3117 // -----------------------------------------------------------------------
3119 void CheckBox::ImplInitSettings( sal_Bool bFont
,
3120 sal_Bool bForeground
, sal_Bool bBackground
)
3122 Button::ImplInitSettings( bFont
, bForeground
);
3126 Window
* pParent
= GetParent();
3127 if ( !IsControlBackground() &&
3128 (pParent
->IsChildTransparentModeEnabled() || IsNativeControlSupported( CTRL_CHECKBOX
, PART_ENTIRE_CONTROL
) ) )
3130 EnableChildTransparentMode( sal_True
);
3131 SetParentClipMode( PARENTCLIPMODE_NOCLIP
);
3132 SetPaintTransparent( sal_True
);
3134 if( IsNativeControlSupported( CTRL_CHECKBOX
, PART_ENTIRE_CONTROL
) )
3135 ImplGetWindowImpl()->mbUseNativeFocus
= ImplGetSVData()->maNWFData
.mbNoFocusRects
;
3139 EnableChildTransparentMode( sal_False
);
3140 SetParentClipMode( 0 );
3141 SetPaintTransparent( sal_False
);
3143 if ( IsControlBackground() )
3144 SetBackground( GetControlBackground() );
3146 SetBackground( pParent
->GetBackground() );
3151 // -----------------------------------------------------------------------
3153 void CheckBox::ImplLoadRes( const ResId
& rResId
)
3155 Button::ImplLoadRes( rResId
);
3157 if ( rResId
.GetRT() != RSC_TRISTATEBOX
)
3159 sal_uInt16 nChecked
= ReadShortRes();
3160 //anderer Wert als Default ?
3166 // -----------------------------------------------------------------------
3168 void CheckBox::ImplInvalidateOrDrawCheckBoxState()
3170 if( ImplGetSVData()->maNWFData
.mbCheckBoxNeedsErase
)
3172 if ( IsNativeControlSupported(CTRL_CHECKBOX
, PART_ENTIRE_CONTROL
) )
3179 ImplDrawCheckBoxState();
3182 void CheckBox::ImplDrawCheckBoxState()
3184 bool bNativeOK
= sal_True
;
3186 if ( (bNativeOK
=IsNativeControlSupported(CTRL_CHECKBOX
, PART_ENTIRE_CONTROL
)) == sal_True
)
3188 ImplControlValue
aControlValue( meState
== STATE_CHECK
? BUTTONVALUE_ON
: BUTTONVALUE_OFF
);
3189 Rectangle
aCtrlRegion( maStateRect
);
3190 ControlState nState
= 0;
3192 if ( HasFocus() ) nState
|= CTRL_STATE_FOCUSED
;
3193 if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT
) nState
|= CTRL_STATE_DEFAULT
;
3194 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED
) nState
|= CTRL_STATE_PRESSED
;
3195 if ( IsEnabled() ) nState
|= CTRL_STATE_ENABLED
;
3197 if ( meState
== STATE_CHECK
)
3198 aControlValue
.setTristateVal( BUTTONVALUE_ON
);
3199 else if ( meState
== STATE_DONTKNOW
)
3200 aControlValue
.setTristateVal( BUTTONVALUE_MIXED
);
3202 if ( IsMouseOver() && maMouseRect
.IsInside( GetPointerPosPixel() ) )
3203 nState
|= CTRL_STATE_ROLLOVER
;
3205 bNativeOK
= DrawNativeControl( CTRL_CHECKBOX
, PART_ENTIRE_CONTROL
, aCtrlRegion
, nState
,
3206 aControlValue
, OUString() );
3209 if ( bNativeOK
== sal_False
)
3211 sal_uInt16 nStyle
= ImplGetButtonState();
3213 nStyle
|= BUTTON_DRAW_DISABLED
;
3214 if ( meState
== STATE_DONTKNOW
)
3215 nStyle
|= BUTTON_DRAW_DONTKNOW
;
3216 else if ( meState
== STATE_CHECK
)
3217 nStyle
|= BUTTON_DRAW_CHECKED
;
3218 Image aImage
= GetCheckImage( GetSettings(), nStyle
);
3220 DrawImage( maStateRect
.TopLeft(), maStateRect
.GetSize(), aImage
);
3222 DrawImage( maStateRect
.TopLeft(), aImage
);
3226 // -----------------------------------------------------------------------
3228 void CheckBox::ImplDraw( OutputDevice
* pDev
, sal_uLong nDrawFlags
,
3229 const Point
& rPos
, const Size
& rSize
,
3230 const Size
& rImageSize
, Rectangle
& rStateRect
,
3231 Rectangle
& rMouseRect
, bool bLayout
)
3233 WinBits nWinStyle
= GetStyle();
3234 OUString
aText( GetText() );
3236 pDev
->Push( PUSH_CLIPREGION
| PUSH_LINECOLOR
);
3237 pDev
->IntersectClipRegion( Rectangle( rPos
, rSize
) );
3239 long nLineY
= rPos
.Y() + (rSize
.Height()-1)/2;
3240 if ( ( !aText
.isEmpty() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT
) ) ||
3241 ( HasImage() && ! (ImplGetButtonState() & BUTTON_DRAW_NOIMAGE
) ) )
3243 sal_uInt16 nTextStyle
= Button::ImplGetTextStyle( aText
, nWinStyle
, nDrawFlags
);
3245 const long nImageSep
= GetDrawPixel( pDev
, ImplGetImageToTextDistance() );
3246 Size
aSize( rSize
);
3248 aPos
.X() += rImageSize
.Width() + nImageSep
;
3249 aSize
.Width() -= rImageSize
.Width() + nImageSep
;
3251 // if the text rect height is smaller than the height of the image
3252 // then for single lines the default should be centered text
3253 if( (nWinStyle
& (WB_TOP
|WB_VCENTER
|WB_BOTTOM
)) == 0 &&
3254 (rImageSize
.Height() > rSize
.Height() || ! (nWinStyle
& WB_WORDBREAK
) ) )
3256 nTextStyle
&= ~(TEXT_DRAW_TOP
|TEXT_DRAW_BOTTOM
);
3257 nTextStyle
|= TEXT_DRAW_VCENTER
;
3258 aSize
.Height() = rImageSize
.Height();
3261 ImplDrawAlignedImage( pDev
, aPos
, aSize
, bLayout
, 1,
3262 nDrawFlags
, nTextStyle
, NULL
);
3263 nLineY
= aPos
.Y() + aSize
.Height()/2;
3265 rMouseRect
= Rectangle( aPos
, aSize
);
3266 rMouseRect
.Left() = rPos
.X();
3267 rStateRect
.Left() = rPos
.X();
3268 rStateRect
.Top() = rMouseRect
.Top();
3270 if ( aSize
.Height() > rImageSize
.Height() )
3271 rStateRect
.Top() += ( aSize
.Height() - rImageSize
.Height() ) / 2;
3274 rStateRect
.Top() -= ( rImageSize
.Height() - aSize
.Height() ) / 2;
3275 if( rStateRect
.Top() < 0 )
3276 rStateRect
.Top() = 0;
3279 rStateRect
.Right() = rStateRect
.Left()+rImageSize
.Width()-1;
3280 rStateRect
.Bottom() = rStateRect
.Top()+rImageSize
.Height()-1;
3281 if ( rStateRect
.Bottom() > rMouseRect
.Bottom() )
3282 rMouseRect
.Bottom() = rStateRect
.Bottom();
3286 if ( mbLegacyNoTextAlign
&& ( nWinStyle
& WB_CENTER
) )
3287 rStateRect
.Left() = rPos
.X()+((rSize
.Width()-rImageSize
.Width())/2);
3288 else if ( mbLegacyNoTextAlign
&& ( nWinStyle
& WB_RIGHT
) )
3289 rStateRect
.Left() = rPos
.X()+rSize
.Width()-rImageSize
.Width();
3291 rStateRect
.Left() = rPos
.X();
3292 if ( nWinStyle
& WB_VCENTER
)
3293 rStateRect
.Top() = rPos
.Y()+((rSize
.Height()-rImageSize
.Height())/2);
3294 else if ( nWinStyle
& WB_BOTTOM
)
3295 rStateRect
.Top() = rPos
.Y()+rSize
.Height()-rImageSize
.Height();
3297 rStateRect
.Top() = rPos
.Y();
3298 rStateRect
.Right() = rStateRect
.Left()+rImageSize
.Width()-1;
3299 rStateRect
.Bottom() = rStateRect
.Top()+rImageSize
.Height()-1;
3300 // provide space for focusrect
3301 // note: this assumes that the control's size was adjusted
3302 // accordingly in Get/LoseFocus, so the onscreen position won't change
3304 rStateRect
.Move( 1, 1 );
3305 rMouseRect
= rStateRect
;
3307 ImplSetFocusRect( rStateRect
);
3310 const int nLineSpace
= 4;
3311 if( (GetStyle() & WB_CBLINESTYLE
) != 0 &&
3312 rMouseRect
.Right()-1-nLineSpace
< rPos
.X()+rSize
.Width() )
3314 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
3315 if ( rStyleSettings
.GetOptions() & STYLE_OPTION_MONO
)
3316 SetLineColor( Color( COL_BLACK
) );
3318 SetLineColor( rStyleSettings
.GetShadowColor() );
3319 long nLineX
= rMouseRect
.Right()+nLineSpace
;
3320 DrawLine( Point( nLineX
, nLineY
), Point( rPos
.X() + rSize
.Width()-1, nLineY
) );
3321 if ( !(rStyleSettings
.GetOptions() & STYLE_OPTION_MONO
) )
3323 SetLineColor( rStyleSettings
.GetLightColor() );
3324 DrawLine( Point( nLineX
, nLineY
+1 ), Point( rPos
.X() + rSize
.Width()-1, nLineY
+1 ) );
3331 // -----------------------------------------------------------------------
3333 void CheckBox::ImplDrawCheckBox( bool bLayout
)
3335 Size aImageSize
= ImplGetCheckImageSize();
3336 aImageSize
.Width() = CalcZoom( aImageSize
.Width() );
3337 aImageSize
.Height() = CalcZoom( aImageSize
.Height() );
3342 ImplDraw( this, 0, Point(), GetOutputSizePixel(), aImageSize
,
3343 maStateRect
, maMouseRect
, bLayout
);
3347 ImplDrawCheckBoxState();
3349 ShowFocus( ImplGetFocusRect() );
3353 // -----------------------------------------------------------------------
3355 void CheckBox::ImplCheck()
3358 if ( meState
== STATE_NOCHECK
)
3359 eNewState
= STATE_CHECK
;
3360 else if ( !mbTriState
)
3361 eNewState
= STATE_NOCHECK
;
3362 else if ( meState
== STATE_CHECK
)
3363 eNewState
= STATE_DONTKNOW
;
3365 eNewState
= STATE_NOCHECK
;
3366 meState
= eNewState
;
3368 ImplDelData aDelData
;
3369 ImplAddDel( &aDelData
);
3370 if( (GetStyle() & WB_EARLYTOGGLE
) )
3372 ImplInvalidateOrDrawCheckBoxState();
3373 if( ! (GetStyle() & WB_EARLYTOGGLE
) )
3375 if ( aDelData
.IsDead() )
3377 ImplRemoveDel( &aDelData
);
3381 // -----------------------------------------------------------------------
3383 CheckBox::CheckBox( Window
* pParent
, WinBits nStyle
) :
3384 Button( WINDOW_CHECKBOX
), mbLegacyNoTextAlign( false )
3386 ImplInitCheckBoxData();
3387 ImplInit( pParent
, nStyle
);
3390 // -----------------------------------------------------------------------
3392 CheckBox::CheckBox( Window
* pParent
, const ResId
& rResId
) :
3393 Button( WINDOW_CHECKBOX
), mbLegacyNoTextAlign( false )
3395 rResId
.SetRT( RSC_CHECKBOX
);
3396 WinBits nStyle
= ImplInitRes( rResId
);
3397 ImplInitCheckBoxData();
3398 ImplInit( pParent
, nStyle
);
3399 ImplLoadRes( rResId
);
3401 if ( !(nStyle
& WB_HIDE
) )
3405 // -----------------------------------------------------------------------
3407 void CheckBox::MouseButtonDown( const MouseEvent
& rMEvt
)
3409 if ( rMEvt
.IsLeft() && maMouseRect
.IsInside( rMEvt
.GetPosPixel() ) )
3411 ImplGetButtonState() |= BUTTON_DRAW_PRESSED
;
3412 ImplInvalidateOrDrawCheckBoxState();
3417 Button::MouseButtonDown( rMEvt
);
3420 // -----------------------------------------------------------------------
3422 void CheckBox::Tracking( const TrackingEvent
& rTEvt
)
3424 if ( rTEvt
.IsTrackingEnded() )
3426 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED
)
3428 if ( !(GetStyle() & WB_NOPOINTERFOCUS
) && !rTEvt
.IsTrackingCanceled() )
3431 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED
;
3433 // do not call click handler if aborted
3434 if ( !rTEvt
.IsTrackingCanceled() )
3437 ImplInvalidateOrDrawCheckBoxState();
3442 if ( maMouseRect
.IsInside( rTEvt
.GetMouseEvent().GetPosPixel() ) )
3444 if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED
) )
3446 ImplGetButtonState() |= BUTTON_DRAW_PRESSED
;
3447 ImplInvalidateOrDrawCheckBoxState();
3452 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED
)
3454 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED
;
3455 ImplInvalidateOrDrawCheckBoxState();
3461 // -----------------------------------------------------------------------
3463 void CheckBox::KeyInput( const KeyEvent
& rKEvt
)
3465 KeyCode aKeyCode
= rKEvt
.GetKeyCode();
3467 if ( !aKeyCode
.GetModifier() && (aKeyCode
.GetCode() == KEY_SPACE
) )
3469 if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED
) )
3471 ImplGetButtonState() |= BUTTON_DRAW_PRESSED
;
3472 ImplInvalidateOrDrawCheckBoxState();
3475 else if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED
) && (aKeyCode
.GetCode() == KEY_ESCAPE
) )
3477 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED
;
3478 ImplInvalidateOrDrawCheckBoxState();
3481 Button::KeyInput( rKEvt
);
3484 // -----------------------------------------------------------------------
3486 void CheckBox::KeyUp( const KeyEvent
& rKEvt
)
3488 KeyCode aKeyCode
= rKEvt
.GetKeyCode();
3490 if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED
) && (aKeyCode
.GetCode() == KEY_SPACE
) )
3492 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED
;
3496 Button::KeyUp( rKEvt
);
3499 // -----------------------------------------------------------------------
3501 void CheckBox::FillLayoutData() const
3503 mpControlData
->mpLayoutData
= new vcl::ControlLayoutData();
3504 const_cast<CheckBox
*>(this)->ImplDrawCheckBox( true );
3507 // -----------------------------------------------------------------------
3509 void CheckBox::Paint( const Rectangle
& )
3514 // -----------------------------------------------------------------------
3516 void CheckBox::Draw( OutputDevice
* pDev
, const Point
& rPos
, const Size
& rSize
,
3519 MapMode
aResMapMode( MAP_100TH_MM
);
3520 Point aPos
= pDev
->LogicToPixel( rPos
);
3521 Size aSize
= pDev
->LogicToPixel( rSize
);
3522 Size aImageSize
= pDev
->LogicToPixel( Size( 300, 300 ), aResMapMode
);
3523 Size aBrd1Size
= pDev
->LogicToPixel( Size( 20, 20 ), aResMapMode
);
3524 Size aBrd2Size
= pDev
->LogicToPixel( Size( 30, 30 ), aResMapMode
);
3525 long nCheckWidth
= pDev
->LogicToPixel( Size( 20, 20 ), aResMapMode
).Width();
3526 Font aFont
= GetDrawPixelFont( pDev
);
3527 Rectangle aStateRect
;
3528 Rectangle aMouseRect
;
3530 aImageSize
.Width() = CalcZoom( aImageSize
.Width() );
3531 aImageSize
.Height() = CalcZoom( aImageSize
.Height() );
3532 aBrd1Size
.Width() = CalcZoom( aBrd1Size
.Width() );
3533 aBrd1Size
.Height() = CalcZoom( aBrd1Size
.Height() );
3534 aBrd2Size
.Width() = CalcZoom( aBrd2Size
.Width() );
3535 aBrd2Size
.Height() = CalcZoom( aBrd2Size
.Height() );
3537 if ( !aBrd1Size
.Width() )
3538 aBrd1Size
.Width() = 1;
3539 if ( !aBrd1Size
.Height() )
3540 aBrd1Size
.Height() = 1;
3541 if ( !aBrd2Size
.Width() )
3542 aBrd2Size
.Width() = 1;
3543 if ( !aBrd2Size
.Height() )
3544 aBrd2Size
.Height() = 1;
3550 pDev
->SetFont( aFont
);
3551 if ( nFlags
& WINDOW_DRAW_MONO
)
3552 pDev
->SetTextColor( Color( COL_BLACK
) );
3554 pDev
->SetTextColor( GetTextColor() );
3555 pDev
->SetTextFillColor();
3557 ImplDraw( pDev
, nFlags
, aPos
, aSize
,
3558 aImageSize
, aStateRect
, aMouseRect
, false );
3560 pDev
->SetLineColor();
3561 pDev
->SetFillColor( Color( COL_BLACK
) );
3562 pDev
->DrawRect( aStateRect
);
3563 aStateRect
.Left() += aBrd1Size
.Width();
3564 aStateRect
.Top() += aBrd1Size
.Height();
3565 aStateRect
.Right() -= aBrd1Size
.Width();
3566 aStateRect
.Bottom() -= aBrd1Size
.Height();
3567 if ( meState
== STATE_DONTKNOW
)
3568 pDev
->SetFillColor( Color( COL_LIGHTGRAY
) );
3570 pDev
->SetFillColor( Color( COL_WHITE
) );
3571 pDev
->DrawRect( aStateRect
);
3573 if ( meState
== STATE_CHECK
)
3575 aStateRect
.Left() += aBrd2Size
.Width();
3576 aStateRect
.Top() += aBrd2Size
.Height();
3577 aStateRect
.Right() -= aBrd2Size
.Width();
3578 aStateRect
.Bottom() -= aBrd2Size
.Height();
3579 Point
aPos11( aStateRect
.TopLeft() );
3580 Point
aPos12( aStateRect
.BottomRight() );
3581 Point
aPos21( aStateRect
.TopRight() );
3582 Point
aPos22( aStateRect
.BottomLeft() );
3583 Point
aTempPos11( aPos11
);
3584 Point
aTempPos12( aPos12
);
3585 Point
aTempPos21( aPos21
);
3586 Point
aTempPos22( aPos22
);
3587 pDev
->SetLineColor( Color( COL_BLACK
) );
3589 for ( long i
= 0; i
< nCheckWidth
; i
++ )
3593 aTempPos11
.X() = aPos11
.X()+nDX
;
3594 aTempPos12
.X() = aPos12
.X()+nDX
;
3595 aTempPos21
.X() = aPos21
.X()+nDX
;
3596 aTempPos22
.X() = aPos22
.X()+nDX
;
3601 aTempPos11
.X() = aPos11
.X()-nDX
;
3602 aTempPos12
.X() = aPos12
.X()-nDX
;
3603 aTempPos21
.X() = aPos21
.X()-nDX
;
3604 aTempPos22
.X() = aPos22
.X()-nDX
;
3606 pDev
->DrawLine( aTempPos11
, aTempPos12
);
3607 pDev
->DrawLine( aTempPos21
, aTempPos22
);
3614 // -----------------------------------------------------------------------
3616 void CheckBox::Resize()
3622 // -----------------------------------------------------------------------
3624 void CheckBox::GetFocus()
3626 if ( GetText().isEmpty() || (ImplGetButtonState() & BUTTON_DRAW_NOTEXT
) )
3628 // increase button size to have space for focus rect
3629 // checkboxes without text will draw focusrect around the check
3630 // See CheckBox::ImplDraw()
3631 Point
aPos( GetPosPixel() );
3632 Size
aSize( GetSizePixel() );
3634 aSize
.Height() += 2;
3636 setPosSizePixel( aPos
.X(), aPos
.Y(), aSize
.Width(), aSize
.Height(), WINDOW_POSSIZE_ALL
);
3640 ShowFocus( ImplGetFocusRect() );
3642 SetInputContext( InputContext( GetFont() ) );
3646 // -----------------------------------------------------------------------
3648 void CheckBox::LoseFocus()
3650 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED
)
3652 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED
;
3653 ImplInvalidateOrDrawCheckBoxState();
3657 Button::LoseFocus();
3659 if ( GetText().isEmpty() || (ImplGetButtonState() & BUTTON_DRAW_NOTEXT
) )
3661 // decrease button size again (see GetFocus())
3662 // checkboxes without text will draw focusrect around the check
3663 Point
aPos( GetPosPixel() );
3664 Size
aSize( GetSizePixel() );
3666 aSize
.Height() -= 2;
3668 setPosSizePixel( aPos
.X(), aPos
.Y(), aSize
.Width(), aSize
.Height(), WINDOW_POSSIZE_ALL
);
3673 // -----------------------------------------------------------------------
3675 void CheckBox::StateChanged( StateChangedType nType
)
3677 Button::StateChanged( nType
);
3679 if ( nType
== STATE_CHANGE_STATE
)
3681 if ( IsReallyVisible() && IsUpdateMode() )
3682 Invalidate( maStateRect
);
3684 else if ( (nType
== STATE_CHANGE_ENABLE
) ||
3685 (nType
== STATE_CHANGE_TEXT
) ||
3686 (nType
== STATE_CHANGE_IMAGE
) ||
3687 (nType
== STATE_CHANGE_DATA
) ||
3688 (nType
== STATE_CHANGE_UPDATEMODE
) )
3690 if ( IsUpdateMode() )
3693 else if ( nType
== STATE_CHANGE_STYLE
)
3695 SetStyle( ImplInitStyle( GetWindow( WINDOW_PREV
), GetStyle() ) );
3697 if ( (GetPrevStyle() & CHECKBOX_VIEW_STYLE
) !=
3698 (GetStyle() & CHECKBOX_VIEW_STYLE
) )
3700 if ( IsUpdateMode() )
3704 else if ( (nType
== STATE_CHANGE_ZOOM
) ||
3705 (nType
== STATE_CHANGE_CONTROLFONT
) )
3707 ImplInitSettings( sal_True
, sal_False
, sal_False
);
3710 else if ( nType
== STATE_CHANGE_CONTROLFOREGROUND
)
3712 ImplInitSettings( sal_False
, sal_True
, sal_False
);
3715 else if ( nType
== STATE_CHANGE_CONTROLBACKGROUND
)
3717 ImplInitSettings( sal_False
, sal_False
, sal_True
);
3722 // -----------------------------------------------------------------------
3724 void CheckBox::DataChanged( const DataChangedEvent
& rDCEvt
)
3726 Button::DataChanged( rDCEvt
);
3728 if ( (rDCEvt
.GetType() == DATACHANGED_FONTS
) ||
3729 (rDCEvt
.GetType() == DATACHANGED_FONTSUBSTITUTION
) ||
3730 ((rDCEvt
.GetType() == DATACHANGED_SETTINGS
) &&
3731 (rDCEvt
.GetFlags() & SETTINGS_STYLE
)) )
3733 ImplInitSettings( sal_True
, sal_True
, sal_True
);
3738 // -----------------------------------------------------------------------
3740 long CheckBox::PreNotify( NotifyEvent
& rNEvt
)
3743 const MouseEvent
* pMouseEvt
= NULL
;
3745 if( (rNEvt
.GetType() == EVENT_MOUSEMOVE
) && (pMouseEvt
= rNEvt
.GetMouseEvent()) != NULL
)
3747 if( !pMouseEvt
->GetButtons() && !pMouseEvt
->IsSynthetic() && !pMouseEvt
->IsModifierChanged() )
3749 // trigger redraw if mouse over state has changed
3750 if( IsNativeControlSupported(CTRL_CHECKBOX
, PART_ENTIRE_CONTROL
) )
3752 if( ( maMouseRect
.IsInside( GetPointerPosPixel()) &&
3753 !maMouseRect
.IsInside( GetLastPointerPosPixel()) ) ||
3754 ( maMouseRect
.IsInside( GetLastPointerPosPixel()) &&
3755 !maMouseRect
.IsInside( GetPointerPosPixel()) ) ||
3756 pMouseEvt
->IsLeaveWindow() || pMouseEvt
->IsEnterWindow() )
3758 Invalidate( maStateRect
);
3764 return nDone
? nDone
: Button::PreNotify(rNEvt
);
3767 // -----------------------------------------------------------------------
3769 void CheckBox::Toggle()
3771 ImplCallEventListenersAndHandler( VCLEVENT_CHECKBOX_TOGGLE
, maToggleHdl
, this );
3774 // -----------------------------------------------------------------------
3776 void CheckBox::SetState( TriState eState
)
3778 if ( !mbTriState
&& (eState
== STATE_DONTKNOW
) )
3779 eState
= STATE_NOCHECK
;
3781 if ( meState
!= eState
)
3784 StateChanged( STATE_CHANGE_STATE
);
3789 bool CheckBox::set_property(const OString
&rKey
, const OString
&rValue
)
3791 if (rKey
== "active")
3792 SetState(toBool(rValue
) ? STATE_CHECK
: STATE_NOCHECK
);
3794 return Window::set_property(rKey
, rValue
);
3798 // -----------------------------------------------------------------------
3800 void CheckBox::EnableTriState( sal_Bool bTriState
)
3802 if ( mbTriState
!= bTriState
)
3804 mbTriState
= bTriState
;
3806 if ( !bTriState
&& (meState
== STATE_DONTKNOW
) )
3807 SetState( STATE_NOCHECK
);
3811 // -----------------------------------------------------------------------
3813 long CheckBox::ImplGetImageToTextDistance() const
3815 // 4 pixels, but take zoom into account, so the text doesn't "jump" relative to surrounding elements,
3816 // which might have been aligned with the text of the check box
3817 return CalcZoom( 4 );
3820 // -----------------------------------------------------------------------
3822 Size
CheckBox::ImplGetCheckImageSize() const
3825 // why are IsNativeControlSupported and GetNativeControlRegion not const ?
3826 CheckBox
* pThis
= const_cast<CheckBox
*>(this);
3827 bool bDefaultSize
= true;
3828 if( pThis
->IsNativeControlSupported( CTRL_CHECKBOX
, PART_ENTIRE_CONTROL
) )
3830 ImplControlValue aControlValue
;
3831 // #i45896# workaround gcc3.3 temporary problem
3832 Rectangle
aCtrlRegion( Point( 0, 0 ), GetSizePixel() );
3833 ControlState nState
= CTRL_STATE_DEFAULT
|CTRL_STATE_ENABLED
;
3834 Rectangle aBoundingRgn
, aContentRgn
;
3836 // get native size of a check box
3837 if( pThis
->GetNativeControlRegion( CTRL_CHECKBOX
, PART_ENTIRE_CONTROL
, aCtrlRegion
,
3838 nState
, aControlValue
, OUString(),
3839 aBoundingRgn
, aContentRgn
) )
3841 aSize
= aContentRgn
.GetSize();
3842 bDefaultSize
= false;
3846 aSize
= GetCheckImage( GetSettings(), 0 ).GetSizePixel();
3850 Image
CheckBox::GetCheckImage( const AllSettings
& rSettings
, sal_uInt16 nFlags
)
3852 ImplSVData
* pSVData
= ImplGetSVData();
3853 const StyleSettings
& rStyleSettings
= rSettings
.GetStyleSettings();
3854 sal_uInt16 nStyle
= 0;
3856 if ( rStyleSettings
.GetOptions() & STYLE_OPTION_MONO
)
3857 nStyle
= STYLE_CHECKBOX_MONO
;
3859 if ( !pSVData
->maCtrlData
.mpCheckImgList
||
3860 (pSVData
->maCtrlData
.mnCheckStyle
!= nStyle
) ||
3861 (pSVData
->maCtrlData
.mnLastCheckFColor
!= rStyleSettings
.GetFaceColor().GetColor()) ||
3862 (pSVData
->maCtrlData
.mnLastCheckWColor
!= rStyleSettings
.GetWindowColor().GetColor()) ||
3863 (pSVData
->maCtrlData
.mnLastCheckLColor
!= rStyleSettings
.GetLightColor().GetColor()) )
3865 if ( pSVData
->maCtrlData
.mpCheckImgList
)
3866 delete pSVData
->maCtrlData
.mpCheckImgList
;
3868 pSVData
->maCtrlData
.mnLastCheckFColor
= rStyleSettings
.GetFaceColor().GetColor();
3869 pSVData
->maCtrlData
.mnLastCheckWColor
= rStyleSettings
.GetWindowColor().GetColor();
3870 pSVData
->maCtrlData
.mnLastCheckLColor
= rStyleSettings
.GetLightColor().GetColor();
3872 ResMgr
* pResMgr
= ImplGetResMgr();
3873 pSVData
->maCtrlData
.mpCheckImgList
= new ImageList();
3875 LoadThemedImageList( rStyleSettings
,
3876 pSVData
->maCtrlData
.mpCheckImgList
,
3877 ResId( SV_RESID_BITMAP_CHECK
+nStyle
, *pResMgr
), 9 );
3878 pSVData
->maCtrlData
.mnCheckStyle
= nStyle
;
3882 if ( nFlags
& BUTTON_DRAW_DISABLED
)
3884 if ( nFlags
& BUTTON_DRAW_DONTKNOW
)
3886 else if ( nFlags
& BUTTON_DRAW_CHECKED
)
3891 else if ( nFlags
& BUTTON_DRAW_PRESSED
)
3893 if ( nFlags
& BUTTON_DRAW_DONTKNOW
)
3895 else if ( nFlags
& BUTTON_DRAW_CHECKED
)
3902 if ( nFlags
& BUTTON_DRAW_DONTKNOW
)
3904 else if ( nFlags
& BUTTON_DRAW_CHECKED
)
3909 return pSVData
->maCtrlData
.mpCheckImgList
->GetImage( nId
);
3912 // -----------------------------------------------------------------------
3914 void CheckBox::ImplSetMinimumNWFSize()
3916 Push( PUSH_MAPMODE
);
3917 SetMapMode( MAP_PIXEL
);
3919 ImplControlValue aControlValue
;
3920 Size
aCurSize( GetSizePixel() );
3921 Rectangle
aCtrlRegion( Point( 0, 0 ), aCurSize
);
3922 Rectangle aBoundingRgn
, aContentRgn
;
3924 // get native size of a radiobutton
3925 if( GetNativeControlRegion( CTRL_CHECKBOX
, PART_ENTIRE_CONTROL
, aCtrlRegion
,
3926 CTRL_STATE_DEFAULT
|CTRL_STATE_ENABLED
, aControlValue
, OUString(),
3927 aBoundingRgn
, aContentRgn
) )
3929 Size aSize
= aContentRgn
.GetSize();
3931 if( aSize
.Height() > aCurSize
.Height() )
3933 aCurSize
.Height() = aSize
.Height();
3934 SetSizePixel( aCurSize
);
3941 // -----------------------------------------------------------------------
3943 Size
CheckBox::CalcMinimumSize( long nMaxWidth
) const
3945 Size aSize
= ImplGetCheckImageSize();
3946 nMaxWidth
-= aSize
.Width();
3948 OUString aText
= GetText();
3949 if ( !aText
.isEmpty() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT
) )
3951 // subtract what will be added later
3953 nMaxWidth
-= ImplGetImageToTextDistance();
3955 Size aTextSize
= GetTextRect( Rectangle( Point(), Size( nMaxWidth
> 0 ? nMaxWidth
: 0x7fffffff, 0x7fffffff ) ),
3956 aText
, FixedText::ImplGetTextStyle( GetStyle() ) ).GetSize();
3957 aSize
.Width()+=2; // for focus rect
3958 aSize
.Width() += ImplGetImageToTextDistance();
3959 aSize
.Width() += aTextSize
.Width();
3960 if ( aSize
.Height() < aTextSize
.Height() )
3961 aSize
.Height() = aTextSize
.Height();
3965 // is this still correct ? since the checkbox now
3966 // shows a focus rect it should be 2 pixels wider and longer
3967 /* da ansonsten im Writer die Control zu weit oben haengen
3969 aSize.Height() += 2;
3973 return CalcWindowSize( aSize
);
3976 // -----------------------------------------------------------------------
3978 Size
CheckBox::GetOptimalSize() const
3980 return CalcMinimumSize();
3983 // =======================================================================
3985 ImageButton::ImageButton( Window
* pParent
, WinBits nStyle
) :
3986 PushButton( pParent
, nStyle
)
3991 // -----------------------------------------------------------------------
3993 ImageButton::ImageButton( Window
* pParent
, const ResId
& rResId
) :
3994 PushButton( pParent
, rResId
.SetRT( RSC_IMAGEBUTTON
) )
3996 sal_uLong nObjMask
= ReadLongRes();
3998 if ( RSC_IMAGEBUTTON_IMAGE
& nObjMask
)
4000 SetModeImage( Image( ResId( (RSHEADER_TYPE
*)GetClassRes(), *rResId
.GetResMgr() ) ) );
4001 IncrementRes( GetObjSizeRes( (RSHEADER_TYPE
*)GetClassRes() ) );
4004 if ( RSC_IMAGEBUTTON_SYMBOL
& nObjMask
)
4005 SetSymbol( (SymbolType
)ReadLongRes() );
4007 if ( RSC_IMAGEBUTTON_STATE
& nObjMask
)
4008 SetState( (TriState
)ReadLongRes() );
4013 // -----------------------------------------------------------------------
4015 ImageButton::~ImageButton()
4019 // -----------------------------------------------------------------------
4020 void ImageButton::ImplInitStyle()
4022 WinBits nStyle
= GetStyle();
4024 if ( ! ( nStyle
& ( WB_RIGHT
| WB_LEFT
) ) )
4025 nStyle
|= WB_CENTER
;
4027 if ( ! ( nStyle
& ( WB_TOP
| WB_BOTTOM
) ) )
4028 nStyle
|= WB_VCENTER
;
4033 // =======================================================================
4035 ImageRadioButton::ImageRadioButton( Window
* pParent
, WinBits nStyle
) :
4036 RadioButton( pParent
, nStyle
)
4040 // -----------------------------------------------------------------------
4042 ImageRadioButton::ImageRadioButton( Window
* pParent
, const ResId
& rResId
) :
4043 RadioButton( pParent
, rResId
.SetRT( RSC_IMAGERADIOBUTTON
) )
4045 sal_uLong nObjMask
= ReadLongRes();
4047 if ( RSC_IMAGERADIOBUTTON_IMAGE
& nObjMask
)
4049 SetModeRadioImage( Image( ResId( (RSHEADER_TYPE
*)GetClassRes(), *rResId
.GetResMgr() ) ) );
4050 IncrementRes( GetObjSizeRes( (RSHEADER_TYPE
*)GetClassRes() ) );
4054 // -----------------------------------------------------------------------
4056 ImageRadioButton::~ImageRadioButton()
4060 // =======================================================================
4062 TriStateBox::TriStateBox( Window
* pParent
, WinBits nStyle
) :
4063 CheckBox( pParent
, nStyle
)
4065 EnableTriState( sal_True
);
4068 // -----------------------------------------------------------------------
4070 TriStateBox::TriStateBox( Window
* pParent
, const ResId
& rResId
) :
4071 CheckBox( pParent
, rResId
.SetRT( RSC_TRISTATEBOX
) )
4073 EnableTriState( sal_True
);
4075 sal_uLong nTriState
= ReadLongRes();
4076 sal_uInt16 bDisableTriState
= ReadShortRes();
4077 //anderer Wert als Default ?
4078 if ( (TriState
)nTriState
!= STATE_NOCHECK
)
4079 SetState( (TriState
)nTriState
);
4080 if ( bDisableTriState
)
4081 EnableTriState( sal_False
);
4084 // -----------------------------------------------------------------------
4086 TriStateBox::~TriStateBox()
4090 // =======================================================================
4092 DisclosureButton::DisclosureButton( Window
* pParent
, WinBits nStyle
) :
4093 CheckBox( pParent
, nStyle
)
4097 DisclosureButton::DisclosureButton( Window
* pParent
, const ResId
& rResId
) :
4098 CheckBox( pParent
, rResId
.SetRT( RSC_CHECKBOX
) )
4102 // -----------------------------------------------------------------------
4104 void DisclosureButton::ImplDrawCheckBoxState()
4106 /* HACK: DisclosureButton is currently assuming, that the disclosure sign
4107 will fit into the rectangle occupied by a normal checkbox on all themes.
4108 If this does not hold true for some theme, ImplGetCheckImageSize
4109 would have to be overloaded for DisclosureButton; also GetNativeControlRegion
4110 for CTRL_LISTNODE would have to be implemented and taken into account
4113 Rectangle
aStateRect( GetStateRect() );
4115 ImplControlValue
aControlValue( GetState() == STATE_CHECK
? BUTTONVALUE_ON
: BUTTONVALUE_OFF
);
4116 Rectangle
aCtrlRegion( aStateRect
);
4117 ControlState nState
= 0;
4119 if ( HasFocus() ) nState
|= CTRL_STATE_FOCUSED
;
4120 if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT
) nState
|= CTRL_STATE_DEFAULT
;
4121 if ( Window::IsEnabled() ) nState
|= CTRL_STATE_ENABLED
;
4122 if ( IsMouseOver() && GetMouseRect().IsInside( GetPointerPosPixel() ) )
4123 nState
|= CTRL_STATE_ROLLOVER
;
4125 if( ! DrawNativeControl( CTRL_LISTNODE
, PART_ENTIRE_CONTROL
, aCtrlRegion
, nState
,
4126 aControlValue
, OUString() ) )
4128 ImplSVCtrlData
& rCtrlData( ImplGetSVData()->maCtrlData
);
4129 if( ! rCtrlData
.mpDisclosurePlus
)
4130 rCtrlData
.mpDisclosurePlus
= new Image( BitmapEx( VclResId( SV_DISCLOSURE_PLUS
) ) );
4131 if( ! rCtrlData
.mpDisclosureMinus
)
4132 rCtrlData
.mpDisclosureMinus
= new Image( BitmapEx( VclResId( SV_DISCLOSURE_MINUS
) ) );
4135 pImg
= IsChecked() ? rCtrlData
.mpDisclosureMinus
: rCtrlData
.mpDisclosurePlus
;
4137 DBG_ASSERT( pImg
, "no disclosure image" );
4141 sal_uInt16 nStyle
= 0;
4143 nStyle
|= IMAGE_DRAW_DISABLE
;
4145 Size
aSize( aStateRect
.GetSize() );
4146 Size
aImgSize( pImg
->GetSizePixel() );
4147 Point
aOff( (aSize
.Width() - aImgSize
.Width())/2,
4148 (aSize
.Height() - aImgSize
.Height())/2 );
4149 aOff
+= aStateRect
.TopLeft();
4150 DrawImage( aOff
, *pImg
, nStyle
);
4154 // -----------------------------------------------------------------------
4156 void DisclosureButton::KeyInput( const KeyEvent
& rKEvt
)
4158 KeyCode aKeyCode
= rKEvt
.GetKeyCode();
4160 if( !aKeyCode
.GetModifier() &&
4161 ( ( aKeyCode
.GetCode() == KEY_ADD
) ||
4162 ( aKeyCode
.GetCode() == KEY_SUBTRACT
) )
4165 Check( aKeyCode
.GetCode() == KEY_ADD
);
4168 CheckBox::KeyInput( rKEvt
);
4171 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */