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