xref: /aoo42x/main/vcl/source/control/button.cxx (revision 86e1cf34)
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 // -----------------------------------------------------------------------
ImplCommonButtonData()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 // -----------------------------------------------------------------------
~ImplCommonButtonData()101 ImplCommonButtonData::~ImplCommonButtonData()
102 {
103     delete mpBitmapEx;
104     delete mpBitmapExHC;
105 }
106 
107 // =======================================================================
108 
Button(WindowType nType)109 Button::Button( WindowType nType ) :
110     Control( nType )
111 {
112     mpButtonData = new ImplCommonButtonData;
113 }
114 
115 // -----------------------------------------------------------------------
116 
Button(Window * pParent,WinBits nStyle)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 
Button(Window * pParent,const ResId & rResId)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 
~Button()141 Button::~Button()
142 {
143     delete mpButtonData;
144 }
145 
146 // -----------------------------------------------------------------------
147 
Click()148 void Button::Click()
149 {
150     ImplCallEventListenersAndHandler( VCLEVENT_BUTTON_CLICK, maClickHdl, this );
151 }
152 
153 // -----------------------------------------------------------------------
154 
GetStandardText(StandardButtonType eButton)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 
GetStandardHelpText(StandardButtonType)193 XubString Button::GetStandardHelpText( StandardButtonType /* eButton */ )
194 {
195     XubString aHelpText;
196     return aHelpText;
197 }
198 // -----------------------------------------------------------------------
SetModeImage(const Image & rImage,BmpColorMode eMode)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 // -----------------------------------------------------------------------
GetModeImage(BmpColorMode eMode) const232 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 // -----------------------------------------------------------------------
HasImage() const247 sal_Bool Button::HasImage() const
248 {
249     return !!(mpButtonData->maImage);
250 }
251 
252 // -----------------------------------------------------------------------
SetImageAlign(ImageAlign eAlign)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 // -----------------------------------------------------------------------
GetImageAlign() const263 ImageAlign Button::GetImageAlign() const
264 {
265     return mpButtonData->meImageAlign;
266 }
267 
268 // -----------------------------------------------------------------------
SetModeBitmap(const BitmapEx & rBitmap,BmpColorMode eMode)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 // -----------------------------------------------------------------------
GetModeBitmap(BmpColorMode eMode) const292 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 // -----------------------------------------------------------------------
SetFocusRect(const Rectangle & rFocusRect)311 void Button::SetFocusRect( const Rectangle& rFocusRect )
312 {
313     ImplSetFocusRect( rFocusRect );
314 }
315 
316 // -----------------------------------------------------------------------
GetFocusRect() const317 const Rectangle& Button::GetFocusRect() const
318 {
319     return ImplGetFocusRect();
320 }
321 
322 // -----------------------------------------------------------------------
323 
ImplGetSymbolRect() const324 const Rectangle& Button::ImplGetSymbolRect() const
325 {
326     return mpButtonData->maSymbolRect;
327 }
328 
ImplSetSymbolRect(const Rectangle & i_rRect)329 void Button::ImplSetSymbolRect( const Rectangle& i_rRect )
330 {
331     mpButtonData->maSymbolRect = i_rRect;
332 }
333 
334 // -----------------------------------------------------------------------
335 
ImplGetTextStyle(XubString & rText,WinBits nWinStyle,sal_uLong nDrawFlags)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 
ImplDrawAlignedImage(OutputDevice * pDev,Point & rPos,Size & rSize,sal_Bool bLayout,sal_uLong nImageSep,sal_uLong nDrawFlags,sal_uInt16 nTextStyle,Rectangle * pSymbolRect,bool bAddImageSep)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 according 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 // -----------------------------------------------------------------------
ImplSetFocusRect(const Rectangle & rFocusRect)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 // -----------------------------------------------------------------------
ImplGetFocusRect() const689 const Rectangle& Button::ImplGetFocusRect() const
690 {
691     return mpButtonData->maFocusRect;
692 }
693 
694 // -----------------------------------------------------------------------
ImplGetButtonState()695 sal_uInt16& Button::ImplGetButtonState()
696 {
697     return mpButtonData->mnButtonState;
698 }
699 
700 // -----------------------------------------------------------------------
ImplGetButtonState() const701 sal_uInt16 Button::ImplGetButtonState() const
702 {
703     return mpButtonData->mnButtonState;
704 }
705 
706 // -----------------------------------------------------------------------
ImplSetSymbolAlign(SymbolAlign eAlign)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 // -----------------------------------------------------------------------
ImplGetSymbolAlign() const717 SymbolAlign Button::ImplGetSymbolAlign() const
718 {
719     return mpButtonData->meSymbolAlign;
720 }
721 // -----------------------------------------------------------------------
ImplSetSmallSymbol(sal_Bool bSmall)722 void Button::ImplSetSmallSymbol( sal_Bool bSmall )
723 {
724     mpButtonData->mbSmallSymbol = bSmall;
725 }
726 
727 // -----------------------------------------------------------------------
EnableImageDisplay(sal_Bool bEnable)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 // -----------------------------------------------------------------------
IsImageDisplayEnabled()737 sal_Bool Button::IsImageDisplayEnabled()
738 {
739     return (mpButtonData->mnButtonState & BUTTON_DRAW_NOIMAGE) == 0;
740 }
741 
742 // -----------------------------------------------------------------------
EnableTextDisplay(sal_Bool bEnable)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 // -----------------------------------------------------------------------
IsTextDisplayEnabled()752 sal_Bool Button::IsTextDisplayEnabled()
753 {
754     return (mpButtonData->mnButtonState & BUTTON_DRAW_NOTEXT) == 0;
755 }
756 
757 // -----------------------------------------------------------------------
SetSmallSymbol(bool small)758 void Button::SetSmallSymbol (bool small)
759 {
760     ImplSetSmallSymbol (small);
761 }
762 
IsSmallSymbol() const763 bool Button::IsSmallSymbol () const
764 {
765     return mpButtonData->mbSmallSymbol;
766 }
767 
768 // =======================================================================
769 
ImplInitPushButtonData()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 
ImplInit(Window * pParent,WinBits nStyle)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 
ImplInitStyle(const Window * pPrevWindow,WinBits nStyle)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 
GetCanonicalFont(const StyleSettings & _rStyle) const820 const Font& PushButton::GetCanonicalFont( const StyleSettings& _rStyle ) const
821 {
822     return _rStyle.GetPushButtonFont();
823 }
824 
825 // -----------------------------------------------------------------
GetCanonicalTextColor(const StyleSettings & _rStyle) const826 const Color& PushButton::GetCanonicalTextColor( const StyleSettings& _rStyle ) const
827 {
828     return _rStyle.GetButtonTextColor();
829 }
830 
831 // -----------------------------------------------------------------------
832 
ImplInitSettings(sal_Bool bFont,sal_Bool bForeground,sal_Bool bBackground)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 
ImplDrawPushButtonFrame(Window * pDev,Rectangle & rRect,sal_uInt16 nStyle)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 
ImplHitTestPushButton(Window * pDev,const Point & rPos)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 
ImplGetTextStyle(sal_uLong nDrawFlags) const904 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 
ImplDrawBtnDropDownArrow(OutputDevice * pDev,long nX,long nY,Color & rColor,sal_Bool bBlack)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 
ImplDrawPushButtonContent(OutputDevice * pDev,sal_uLong nDrawFlags,const Rectangle & rRect,bool bLayout,bool bMenuBtnSep)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 
UserDraw(const UserDrawEvent &)1086 void PushButton::UserDraw( const UserDrawEvent& )
1087 {
1088 }
1089 
1090 // -----------------------------------------------------------------------
1091 
ImplDrawPushButton(bool bLayout)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 
1135     if( bDropDown && (aCtrlType == CTRL_COMBOBOX || aCtrlType == CTRL_LISTBOX ) )
1136     {
1137         if( GetParent()->IsNativeControlSupported( aCtrlType, PART_ENTIRE_CONTROL) )
1138         {
1139             // skip painting if the button was already drawn by the theme
1140             if( aCtrlType == CTRL_COMBOBOX )
1141             {
1142                 Edit* pEdit = static_cast<Edit*>(GetParent());
1143                 if( pEdit->ImplUseNativeBorder( pEdit->GetStyle() ) )
1144                     bNativeOK = sal_True;
1145             }
1146             else if( GetParent()->IsNativeControlSupported( aCtrlType, HAS_BACKGROUND_TEXTURE) )
1147             {
1148                 bNativeOK = sal_True;
1149             }
1150             if( !bNativeOK && GetParent()->IsNativeControlSupported( aCtrlType, PART_BUTTON_DOWN ) )
1151             {
1152                 // let the theme draw it, note we then need support
1153                 // for CTRL_LISTBOX/PART_BUTTON_DOWN and CTRL_COMBOBOX/PART_BUTTON_DOWN
1154 
1155                 ImplControlValue    aControlValue;
1156                 ControlState        nState = 0;
1157 
1158                 if ( mbPressed ) 						nState |= CTRL_STATE_PRESSED;
1159                 if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )	nState |= CTRL_STATE_PRESSED;
1160                 if ( HasFocus() )						nState |= CTRL_STATE_FOCUSED;
1161                 if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT )	nState |= CTRL_STATE_DEFAULT;
1162                 if ( Window::IsEnabled() ) 				nState |= CTRL_STATE_ENABLED;
1163 
1164                 if ( IsMouseOver() && aInRect.IsInside( GetPointerPosPixel() ) )
1165                     nState |= CTRL_STATE_ROLLOVER;
1166 
1167                 bNativeOK = DrawNativeControl( aCtrlType, PART_BUTTON_DOWN, aInRect, nState,
1168                                                 aControlValue, rtl::OUString() );
1169             }
1170         }
1171     }
1172 
1173     if( bNativeOK )
1174         return;
1175 
1176     bool bRollOver = (IsMouseOver() && aInRect.IsInside( GetPointerPosPixel() ));
1177     bool bDrawMenuSep = true;
1178     if( (GetStyle() & WB_FLATBUTTON) )
1179     {
1180         if( ! bRollOver && ! HasFocus() )
1181             bDrawMenuSep = false;
1182     }
1183     if ( (bNativeOK=IsNativeControlSupported(CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL)) == sal_True )
1184     {
1185         PushButtonValue aControlValue;
1186         Rectangle		 aCtrlRegion( aInRect );
1187         ControlState	 nState = 0;
1188 
1189         if ( mbPressed || IsChecked() )                   nState |= CTRL_STATE_PRESSED;
1190         if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED ) nState |= CTRL_STATE_PRESSED;
1191         if ( HasFocus() )						nState |= CTRL_STATE_FOCUSED;
1192         if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT )	nState |= CTRL_STATE_DEFAULT;
1193         if ( Window::IsEnabled() ) 				nState |= CTRL_STATE_ENABLED;
1194 
1195         if ( bRollOver )
1196             nState |= CTRL_STATE_ROLLOVER;
1197 
1198         if( GetStyle() & WB_BEVELBUTTON )
1199             aControlValue.mbBevelButton = true;
1200 
1201         // draw frame into invisible window to have aInRect modified correctly
1202         // but do not shift the inner rect for pressed buttons (ie remove BUTTON_DRAW_PRESSED)
1203         // this assumes the theme has enough visual cues to signalize the button was pressed
1204         //Window aWin( this );
1205         //ImplDrawPushButtonFrame( &aWin, aInRect, nButtonStyle & ~BUTTON_DRAW_PRESSED );
1206 
1207         // looks better this way as symbols were displaced slightly using the above approach
1208         aInRect.Top()+=4;
1209         aInRect.Bottom()-=4;
1210         aInRect.Left()+=4;
1211         aInRect.Right()-=4;
1212 
1213         // prepare single line hint (needed on mac to decide between normal push button and
1214         // rectangular bevel button look)
1215         Size aFontSize( Application::GetSettings().GetStyleSettings().GetPushButtonFont().GetSize() );
1216         aFontSize = LogicToPixel( aFontSize, MapMode( MAP_POINT ) );
1217         Size aInRectSize( LogicToPixel( Size( aInRect.GetWidth(), aInRect.GetHeight() ) ) );
1218         aControlValue.mbSingleLine = (aInRectSize.Height() < 2 * aFontSize.Height() );
1219 
1220         if( ((nState & CTRL_STATE_ROLLOVER)) || ! (GetStyle() & WB_FLATBUTTON) )
1221         {
1222             bNativeOK = DrawNativeControl( CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion, nState,
1223                             aControlValue, rtl::OUString()/*PushButton::GetText()*/ );
1224         }
1225         else
1226         {
1227             bNativeOK = true;
1228         }
1229 
1230         // draw content using the same aInRect as non-native VCL would do
1231         ImplDrawPushButtonContent( this,
1232                                    (nState&CTRL_STATE_ROLLOVER) ? WINDOW_DRAW_ROLLOVER : 0,
1233                                    aInRect, bLayout, bDrawMenuSep );
1234 
1235         if ( HasFocus() )
1236             ShowFocus( ImplGetFocusRect() );
1237     }
1238 
1239     if ( bNativeOK == sal_False )
1240     {
1241         // draw PushButtonFrame, aInRect has content size afterwards
1242         if( (GetStyle() & WB_FLATBUTTON) )
1243         {
1244             Rectangle aTempRect( aInRect );
1245             if( ! bLayout && bRollOver )
1246                 ImplDrawPushButtonFrame( this, aTempRect, nButtonStyle );
1247             aInRect.Left()   += 2;
1248             aInRect.Top()    += 2;
1249             aInRect.Right()  -= 2;
1250             aInRect.Bottom() -= 2;
1251         }
1252         else
1253         {
1254             if( ! bLayout )
1255                 ImplDrawPushButtonFrame( this, aInRect, nButtonStyle );
1256         }
1257 
1258         // draw content
1259         ImplDrawPushButtonContent( this, 0, aInRect, bLayout, bDrawMenuSep );
1260 
1261         if( ! bLayout && HasFocus() )
1262         {
1263             ShowFocus( ImplGetFocusRect() );
1264         }
1265     }
1266 }
1267 
1268 // -----------------------------------------------------------------------
1269 
ImplSetDefButton(sal_Bool bSet)1270 void PushButton::ImplSetDefButton( sal_Bool bSet )
1271 {
1272     Size aSize( GetSizePixel() );
1273     Point aPos( GetPosPixel() );
1274     int dLeft(0), dRight(0), dTop(0), dBottom(0);
1275     sal_Bool bSetPos = sal_False;
1276 
1277     if ( (IsNativeControlSupported(CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL)) == sal_True )
1278     {
1279         Rectangle aBound, aCont;
1280         Rectangle aCtrlRect( 0, 0, 80, 20 ); // use a constant size to avoid accumulating
1281                                              // will not work if the theme has dynamic adornment sizes
1282         ImplControlValue aControlValue;
1283         Rectangle		 aCtrlRegion( aCtrlRect );
1284         ControlState	 nState = CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED;
1285 
1286         // get native size of a 'default' button
1287         // and adjust the VCL button if more space for adornment is required
1288         if( GetNativeControlRegion( CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion,
1289                                 nState, aControlValue, rtl::OUString(),
1290 								aBound, aCont ) )
1291         {
1292             dLeft = aCont.Left() - aBound.Left();
1293             dTop = aCont.Top() - aBound.Top();
1294             dRight = aBound.Right() - aCont.Right();
1295             dBottom = aBound.Bottom() - aCont.Bottom();
1296             bSetPos = dLeft || dTop || dRight || dBottom;
1297         }
1298     }
1299 
1300     if ( bSet )
1301     {
1302         if( !(ImplGetButtonState() & BUTTON_DRAW_DEFAULT) && bSetPos )
1303         {
1304             // adjust pos/size when toggling from non-default to default
1305             aPos.Move(-dLeft, -dTop);
1306             aSize.Width() += dLeft + dRight;
1307             aSize.Height() += dTop + dBottom;
1308         }
1309         ImplGetButtonState() |= BUTTON_DRAW_DEFAULT;
1310     }
1311     else
1312     {
1313         if( (ImplGetButtonState() & BUTTON_DRAW_DEFAULT) && bSetPos )
1314         {
1315             // adjust pos/size when toggling from default to non-default
1316             aPos.Move(dLeft, dTop);
1317             aSize.Width() -= dLeft + dRight;
1318             aSize.Height() -= dTop + dBottom;
1319         }
1320         ImplGetButtonState() &= ~BUTTON_DRAW_DEFAULT;
1321     }
1322     if( bSetPos )
1323         SetPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height(), WINDOW_POSSIZE_ALL );
1324 
1325     Invalidate();
1326 }
1327 
1328 // -----------------------------------------------------------------------
1329 
ImplIsDefButton() const1330 sal_Bool PushButton::ImplIsDefButton() const
1331 {
1332     return (ImplGetButtonState() & BUTTON_DRAW_DEFAULT) != 0;
1333 }
1334 
1335 // -----------------------------------------------------------------------
1336 
PushButton(WindowType nType)1337 PushButton::PushButton( WindowType nType ) :
1338     Button( nType )
1339 {
1340     ImplInitPushButtonData();
1341 }
1342 
1343 // -----------------------------------------------------------------------
1344 
PushButton(Window * pParent,WinBits nStyle)1345 PushButton::PushButton( Window* pParent, WinBits nStyle ) :
1346     Button( WINDOW_PUSHBUTTON )
1347 {
1348     ImplInitPushButtonData();
1349     ImplInit( pParent, nStyle );
1350 }
1351 
1352 // -----------------------------------------------------------------------
1353 
PushButton(Window * pParent,const ResId & rResId)1354 PushButton::PushButton( Window* pParent, const ResId& rResId ) :
1355     Button( WINDOW_PUSHBUTTON )
1356 {
1357     ImplInitPushButtonData();
1358     rResId.SetRT( RSC_PUSHBUTTON );
1359     WinBits nStyle = ImplInitRes( rResId );
1360     ImplInit( pParent, nStyle );
1361     ImplLoadRes( rResId );
1362 
1363     if ( !(nStyle & WB_HIDE) )
1364         Show();
1365 }
1366 
1367 // -----------------------------------------------------------------------
1368 
~PushButton()1369 PushButton::~PushButton()
1370 {
1371 }
1372 
1373 // -----------------------------------------------------------------------
1374 
MouseButtonDown(const MouseEvent & rMEvt)1375 void PushButton::MouseButtonDown( const MouseEvent& rMEvt )
1376 {
1377     if ( rMEvt.IsLeft() &&
1378          ImplHitTestPushButton( this, rMEvt.GetPosPixel() ) )
1379     {
1380         sal_uInt16 nTrackFlags = 0;
1381 
1382         if ( ( GetStyle() & WB_REPEAT ) &&
1383              ! ( GetStyle() & WB_TOGGLE ) )
1384             nTrackFlags |= STARTTRACK_BUTTONREPEAT;
1385 
1386         ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
1387         ImplDrawPushButton();
1388         StartTracking( nTrackFlags );
1389 
1390         if ( nTrackFlags & STARTTRACK_BUTTONREPEAT )
1391             Click();
1392     }
1393 }
1394 
1395 // -----------------------------------------------------------------------
1396 
Tracking(const TrackingEvent & rTEvt)1397 void PushButton::Tracking( const TrackingEvent& rTEvt )
1398 {
1399     if ( rTEvt.IsTrackingEnded() )
1400     {
1401         if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
1402         {
1403             if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() )
1404                 GrabFocus();
1405 
1406             if ( GetStyle() & WB_TOGGLE )
1407             {
1408                 // Don't toggle, when aborted
1409                 if ( !rTEvt.IsTrackingCanceled() )
1410                 {
1411                     if ( IsChecked() )
1412                     {
1413                         Check( sal_False );
1414                         ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
1415                     }
1416                     else
1417                         Check( sal_True );
1418                 }
1419             }
1420             else
1421                 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
1422 
1423             ImplDrawPushButton();
1424 
1425             // Bei Abbruch kein Click-Handler rufen
1426             if ( !rTEvt.IsTrackingCanceled() )
1427             {
1428                 if ( ! ( ( GetStyle() & WB_REPEAT ) &&
1429                          ! ( GetStyle() & WB_TOGGLE ) ) )
1430                     Click();
1431             }
1432         }
1433     }
1434     else
1435     {
1436         if ( ImplHitTestPushButton( this, rTEvt.GetMouseEvent().GetPosPixel() ) )
1437         {
1438             if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
1439             {
1440                 if ( rTEvt.IsTrackingRepeat() && (GetStyle() & WB_REPEAT) &&
1441                      ! ( GetStyle() & WB_TOGGLE ) )
1442                     Click();
1443             }
1444             else
1445             {
1446                 ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
1447                 ImplDrawPushButton();
1448             }
1449         }
1450         else
1451         {
1452             if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
1453             {
1454                 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
1455                 ImplDrawPushButton();
1456             }
1457         }
1458     }
1459 }
1460 
1461 // -----------------------------------------------------------------------
1462 
KeyInput(const KeyEvent & rKEvt)1463 void PushButton::KeyInput( const KeyEvent& rKEvt )
1464 {
1465     KeyCode aKeyCode = rKEvt.GetKeyCode();
1466 
1467     if ( !aKeyCode.GetModifier() &&
1468          ((aKeyCode.GetCode() == KEY_RETURN) || (aKeyCode.GetCode() == KEY_SPACE)) )
1469     {
1470         if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) )
1471         {
1472             ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
1473             ImplDrawPushButton();
1474         }
1475 
1476         if ( ( GetStyle() & WB_REPEAT ) &&
1477              ! ( GetStyle() & WB_TOGGLE ) )
1478             Click();
1479     }
1480     else if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_ESCAPE) )
1481     {
1482         ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
1483         ImplDrawPushButton();
1484     }
1485     else
1486         Button::KeyInput( rKEvt );
1487 }
1488 
1489 // -----------------------------------------------------------------------
1490 
KeyUp(const KeyEvent & rKEvt)1491 void PushButton::KeyUp( const KeyEvent& rKEvt )
1492 {
1493     KeyCode aKeyCode = rKEvt.GetKeyCode();
1494 
1495     if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) &&
1496          ((aKeyCode.GetCode() == KEY_RETURN) || (aKeyCode.GetCode() == KEY_SPACE)) )
1497     {
1498         if ( GetStyle() & WB_TOGGLE )
1499         {
1500             if ( IsChecked() )
1501             {
1502                 Check( sal_False );
1503                 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
1504             }
1505             else
1506                 Check( sal_True );
1507 
1508             Toggle();
1509         }
1510         else
1511             ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
1512 
1513         ImplDrawPushButton();
1514 
1515         if ( !( ( GetStyle() & WB_REPEAT )  &&
1516                 ! ( GetStyle() & WB_TOGGLE ) ) )
1517             Click();
1518     }
1519     else
1520         Button::KeyUp( rKEvt );
1521 }
1522 
1523 // -----------------------------------------------------------------------
1524 
FillLayoutData() const1525 void PushButton::FillLayoutData() const
1526 {
1527     mpControlData->mpLayoutData = new vcl::ControlLayoutData();
1528     const_cast<PushButton*>(this)->ImplDrawPushButton( true );
1529 }
1530 
1531 // -----------------------------------------------------------------------
1532 
Paint(const Rectangle &)1533 void PushButton::Paint( const Rectangle& )
1534 {
1535     ImplDrawPushButton();
1536 }
1537 
1538 // -----------------------------------------------------------------------
1539 
Draw(OutputDevice * pDev,const Point & rPos,const Size & rSize,sal_uLong nFlags)1540 void PushButton::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
1541                        sal_uLong nFlags )
1542 {
1543     Point       aPos  = pDev->LogicToPixel( rPos );
1544     Size        aSize = pDev->LogicToPixel( rSize );
1545     Rectangle   aRect( aPos, aSize );
1546     Rectangle   aTextRect;
1547     Font        aFont = GetDrawPixelFont( pDev );
1548 
1549     pDev->Push();
1550     pDev->SetMapMode();
1551     pDev->SetFont( aFont );
1552     if ( nFlags & WINDOW_DRAW_MONO )
1553 	{
1554         pDev->SetTextColor( Color( COL_BLACK ) );
1555 	}
1556     else
1557 	{
1558         pDev->SetTextColor( GetTextColor() );
1559 
1560 		// DecoView uses the FaceColor...
1561 		AllSettings aSettings = pDev->GetSettings();
1562 		StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1563 		if ( IsControlBackground() )
1564 			aStyleSettings.SetFaceColor( GetControlBackground() );
1565 		else
1566 			aStyleSettings.SetFaceColor( GetSettings().GetStyleSettings().GetFaceColor() );
1567 		aSettings.SetStyleSettings( aStyleSettings );
1568 		pDev->SetSettings( aSettings );
1569 	}
1570     pDev->SetTextFillColor();
1571 
1572     DecorationView aDecoView( pDev );
1573     sal_uInt16 nButtonStyle = 0;
1574     if ( nFlags & WINDOW_DRAW_MONO )
1575         nButtonStyle |= BUTTON_DRAW_MONO;
1576     if ( IsChecked() )
1577         nButtonStyle |= BUTTON_DRAW_CHECKED;
1578     aRect = aDecoView.DrawButton( aRect, nButtonStyle );
1579 
1580     ImplDrawPushButtonContent( pDev, nFlags, aRect, false, true );
1581     pDev->Pop();
1582 }
1583 
1584 // -----------------------------------------------------------------------
1585 
Resize()1586 void PushButton::Resize()
1587 {
1588     Control::Resize();
1589     Invalidate();
1590 }
1591 
1592 // -----------------------------------------------------------------------
1593 
GetFocus()1594 void PushButton::GetFocus()
1595 {
1596     ShowFocus( ImplGetFocusRect() );
1597     SetInputContext( InputContext( GetFont() ) );
1598     Button::GetFocus();
1599 }
1600 
1601 // -----------------------------------------------------------------------
1602 
LoseFocus()1603 void PushButton::LoseFocus()
1604 {
1605     EndSelection();
1606     HideFocus();
1607     Button::LoseFocus();
1608 }
1609 
1610 // -----------------------------------------------------------------------
1611 
StateChanged(StateChangedType nType)1612 void PushButton::StateChanged( StateChangedType nType )
1613 {
1614     Button::StateChanged( nType );
1615 
1616     if ( (nType == STATE_CHANGE_ENABLE) ||
1617          (nType == STATE_CHANGE_TEXT) ||
1618          (nType == STATE_CHANGE_IMAGE) ||
1619          (nType == STATE_CHANGE_DATA) ||
1620          (nType == STATE_CHANGE_STATE) ||
1621          (nType == STATE_CHANGE_UPDATEMODE) )
1622     {
1623         if ( IsReallyVisible() && IsUpdateMode() )
1624             Invalidate();
1625     }
1626     else if ( nType == STATE_CHANGE_STYLE )
1627     {
1628         SetStyle( ImplInitStyle( GetWindow( WINDOW_PREV ), GetStyle() ) );
1629 
1630         bool bIsDefButton = ( GetStyle() & WB_DEFBUTTON ) != 0;
1631         bool bWasDefButton = ( GetPrevStyle() & WB_DEFBUTTON ) != 0;
1632         if ( bIsDefButton != bWasDefButton )
1633             ImplSetDefButton( bIsDefButton );
1634 
1635         if ( IsReallyVisible() && IsUpdateMode() )
1636         {
1637             if ( (GetPrevStyle() & PUSHBUTTON_VIEW_STYLE) !=
1638                  (GetStyle() & PUSHBUTTON_VIEW_STYLE) )
1639                 Invalidate();
1640         }
1641     }
1642     else if ( (nType == STATE_CHANGE_ZOOM) ||
1643               (nType == STATE_CHANGE_CONTROLFONT) )
1644     {
1645         ImplInitSettings( sal_True, sal_False, sal_False );
1646         Invalidate();
1647     }
1648     else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
1649     {
1650         ImplInitSettings( sal_False, sal_True, sal_False );
1651         Invalidate();
1652     }
1653     else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
1654     {
1655         ImplInitSettings( sal_False, sal_False, sal_True );
1656         Invalidate();
1657     }
1658 }
1659 
1660 // -----------------------------------------------------------------------
1661 
DataChanged(const DataChangedEvent & rDCEvt)1662 void PushButton::DataChanged( const DataChangedEvent& rDCEvt )
1663 {
1664     Button::DataChanged( rDCEvt );
1665 
1666     if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
1667          (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
1668          ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
1669           (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
1670     {
1671         ImplInitSettings( sal_True, sal_True, sal_True );
1672         Invalidate();
1673     }
1674 }
1675 
1676 // -----------------------------------------------------------------------
1677 
PreNotify(NotifyEvent & rNEvt)1678 long PushButton::PreNotify( NotifyEvent& rNEvt )
1679 {
1680     long nDone = 0;
1681     const MouseEvent* pMouseEvt = NULL;
1682 
1683     if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL )
1684     {
1685         if( pMouseEvt->IsEnterWindow() || pMouseEvt->IsLeaveWindow() )
1686         {
1687             // trigger redraw as mouse over state has changed
1688 
1689             // TODO: move this to Window class or make it a member !!!
1690             ControlType aCtrlType = 0;
1691             switch( GetParent()->GetType() )
1692             {
1693                 case WINDOW_LISTBOX:
1694                 case WINDOW_MULTILISTBOX:
1695                 case WINDOW_TREELISTBOX:
1696                     aCtrlType = CTRL_LISTBOX;
1697                     break;
1698 
1699                 case WINDOW_COMBOBOX:
1700                 case WINDOW_PATTERNBOX:
1701                 case WINDOW_NUMERICBOX:
1702                 case WINDOW_METRICBOX:
1703                 case WINDOW_CURRENCYBOX:
1704                 case WINDOW_DATEBOX:
1705                 case WINDOW_TIMEBOX:
1706                 case WINDOW_LONGCURRENCYBOX:
1707                     aCtrlType = CTRL_COMBOBOX;
1708                     break;
1709                 default:
1710                     break;
1711             }
1712 
1713             sal_Bool bDropDown = ( IsSymbol() && (GetSymbol()==SYMBOL_SPIN_DOWN) && !GetText().Len() );
1714 
1715             if( bDropDown && GetParent()->IsNativeControlSupported( aCtrlType, PART_ENTIRE_CONTROL) &&
1716                    !GetParent()->IsNativeControlSupported( aCtrlType, PART_BUTTON_DOWN) )
1717             {
1718                 Window *pBorder = GetParent()->GetWindow( WINDOW_BORDER );
1719                 if(aCtrlType == CTRL_COMBOBOX)
1720                 {
1721                     // only paint the button part to avoid flickering of the combobox text
1722                     Point aPt;
1723                     Rectangle aClipRect( aPt, GetOutputSizePixel() );
1724                     aClipRect.SetPos(pBorder->ScreenToOutputPixel(OutputToScreenPixel(aClipRect.TopLeft())));
1725                     pBorder->Invalidate( aClipRect );
1726                 }
1727                 else
1728                 {
1729                     pBorder->Invalidate( INVALIDATE_NOERASE );
1730                     pBorder->Update();
1731                 }
1732             }
1733             else if( (GetStyle() & WB_FLATBUTTON) ||
1734                      IsNativeControlSupported(CTRL_PUSHBUTTON, PART_ENTIRE_CONTROL) )
1735             {
1736                 Invalidate();
1737             }
1738         }
1739     }
1740 
1741     return nDone ? nDone : Button::PreNotify(rNEvt);
1742 }
1743 
1744 // -----------------------------------------------------------------------
1745 
Toggle()1746 void PushButton::Toggle()
1747 {
1748     ImplCallEventListenersAndHandler( VCLEVENT_PUSHBUTTON_TOGGLE, maToggleHdl, this );
1749 }
1750 
1751 // -----------------------------------------------------------------------
1752 
SetSymbol(SymbolType eSymbol)1753 void PushButton::SetSymbol( SymbolType eSymbol )
1754 {
1755     if ( meSymbol != eSymbol )
1756     {
1757         meSymbol = eSymbol;
1758         StateChanged( STATE_CHANGE_DATA );
1759     }
1760 }
1761 
1762 // -----------------------------------------------------------------------
SetSymbolAlign(SymbolAlign eAlign)1763 void PushButton::SetSymbolAlign( SymbolAlign eAlign )
1764 {
1765     ImplSetSymbolAlign( eAlign );
1766 }
1767 
1768 // -----------------------------------------------------------------------
GetSymbolAlign() const1769 SymbolAlign PushButton::GetSymbolAlign() const
1770 {
1771     return ImplGetSymbolAlign();
1772 }
1773 
1774 // -----------------------------------------------------------------------
1775 
SetDropDown(sal_uInt16 nStyle)1776 void PushButton::SetDropDown( sal_uInt16 nStyle )
1777 {
1778     if ( mnDDStyle != nStyle )
1779     {
1780         mnDDStyle = nStyle;
1781         StateChanged( STATE_CHANGE_DATA );
1782     }
1783 }
1784 
1785 // -----------------------------------------------------------------------
1786 
SetState(TriState eState)1787 void PushButton::SetState( TriState eState )
1788 {
1789     if ( meState != eState )
1790     {
1791         meState = eState;
1792         if ( meState == STATE_NOCHECK )
1793             ImplGetButtonState() &= ~(BUTTON_DRAW_CHECKED | BUTTON_DRAW_DONTKNOW);
1794         else if ( meState == STATE_CHECK )
1795         {
1796             ImplGetButtonState() &= ~BUTTON_DRAW_DONTKNOW;
1797             ImplGetButtonState() |= BUTTON_DRAW_CHECKED;
1798         }
1799         else // STATE_DONTKNOW
1800         {
1801             ImplGetButtonState() &= ~BUTTON_DRAW_CHECKED;
1802             ImplGetButtonState() |= BUTTON_DRAW_DONTKNOW;
1803         }
1804 
1805         StateChanged( STATE_CHANGE_STATE );
1806         Toggle();
1807     }
1808 }
1809 
1810 // -----------------------------------------------------------------------
1811 
SetPressed(sal_Bool bPressed)1812 void PushButton::SetPressed( sal_Bool bPressed )
1813 {
1814     if ( mbPressed != bPressed )
1815     {
1816         mbPressed = bPressed;
1817         StateChanged( STATE_CHANGE_DATA );
1818     }
1819 }
1820 
1821 // -----------------------------------------------------------------------
1822 
EndSelection()1823 void PushButton::EndSelection()
1824 {
1825     EndTracking( ENDTRACK_CANCEL );
1826     if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
1827     {
1828         ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
1829         if ( !mbPressed )
1830             ImplDrawPushButton();
1831     }
1832 }
1833 
1834 // -----------------------------------------------------------------------
1835 
CalcMinimumSize(long nMaxWidth) const1836 Size PushButton::CalcMinimumSize( long nMaxWidth ) const
1837 {
1838 	Size aSize;
1839 
1840 	if ( IsSymbol() )
1841     {
1842         if ( IsSmallSymbol ())
1843             aSize = Size( 16, 12 );
1844         else
1845             aSize = Size( 26, 24 );
1846         if( mnDDStyle == PUSHBUTTON_DROPDOWN_MENUBUTTON )
1847             aSize.Width() += 4;
1848     }
1849 	else if ( IsImage() && ! (ImplGetButtonState() & BUTTON_DRAW_NOIMAGE) )
1850 		aSize = GetModeImage().GetSizePixel();
1851 	if ( PushButton::GetText().Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
1852 	{
1853 		sal_uLong nDrawFlags = 0;
1854 		Size textSize = GetTextRect( Rectangle( Point(), Size( nMaxWidth ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ),
1855 									 PushButton::GetText(), ImplGetTextStyle( nDrawFlags ) ).GetSize();
1856 	   aSize.Width() += int( textSize.Width () * 1.15 );
1857 	   aSize.Height() = std::max( aSize.Height(), long( textSize.Height() * 1.15 ) );
1858 	}
1859 
1860 	// cf. ImplDrawPushButton ...
1861     if( (GetStyle() & WB_SMALLSTYLE) == 0 )
1862     {
1863         aSize.Width() += 8;
1864         aSize.Height() += 8;
1865     }
1866 
1867     return CalcWindowSize( aSize );
1868 }
1869 
GetOptimalSize(WindowSizeType eType) const1870 Size PushButton::GetOptimalSize(WindowSizeType eType) const
1871 {
1872     switch (eType) {
1873     case WINDOWSIZE_MINIMUM: {
1874         return CalcMinimumSize();
1875     }
1876     default:
1877         return Button::GetOptimalSize( eType );
1878     }
1879 }
1880 
1881 // =======================================================================
1882 
ImplInit(Window * pParent,WinBits nStyle)1883 void OKButton::ImplInit( Window* pParent, WinBits nStyle )
1884 {
1885     PushButton::ImplInit( pParent, nStyle );
1886 
1887     SetText( Button::GetStandardText( BUTTON_OK ) );
1888     SetHelpText( Button::GetStandardHelpText( BUTTON_OK ) );
1889 }
1890 
1891 // -----------------------------------------------------------------------
1892 
OKButton(Window * pParent,WinBits nStyle)1893 OKButton::OKButton( Window* pParent, WinBits nStyle ) :
1894     PushButton( WINDOW_OKBUTTON )
1895 {
1896     ImplInit( pParent, nStyle );
1897 }
1898 
1899 // -----------------------------------------------------------------------
1900 
OKButton(Window * pParent,const ResId & rResId)1901 OKButton::OKButton( Window* pParent, const ResId& rResId ) :
1902     PushButton( WINDOW_OKBUTTON )
1903 {
1904     rResId.SetRT( RSC_OKBUTTON );
1905     WinBits nStyle = ImplInitRes( rResId );
1906     ImplInit( pParent, nStyle );
1907     ImplLoadRes( rResId );
1908 
1909     if ( !(nStyle & WB_HIDE) )
1910         Show();
1911 }
1912 
1913 // -----------------------------------------------------------------------
1914 
Click()1915 void OKButton::Click()
1916 {
1917     // Ist kein Link gesetzt, dann schliesse Parent
1918     if ( !GetClickHdl() )
1919     {
1920         Window* pParent = GetParent();
1921         if ( pParent->IsSystemWindow() )
1922         {
1923             if ( pParent->IsDialog() )
1924             {
1925                 if ( ((Dialog*)pParent)->IsInExecute() )
1926                     ((Dialog*)pParent)->EndDialog( sal_True );
1927                 // gegen rekursive Aufrufe schuetzen
1928                 else if ( !((Dialog*)pParent)->IsInClose() )
1929                 {
1930                     if ( pParent->GetStyle() & WB_CLOSEABLE )
1931                         ((Dialog*)pParent)->Close();
1932                 }
1933             }
1934             else
1935             {
1936                 if ( pParent->GetStyle() & WB_CLOSEABLE )
1937                     ((SystemWindow*)pParent)->Close();
1938             }
1939         }
1940     }
1941     else
1942     {
1943         PushButton::Click();
1944     }
1945 }
1946 
1947 // =======================================================================
1948 
ImplInit(Window * pParent,WinBits nStyle)1949 void CancelButton::ImplInit( Window* pParent, WinBits nStyle )
1950 {
1951     PushButton::ImplInit( pParent, nStyle );
1952 
1953     SetText( Button::GetStandardText( BUTTON_CANCEL ) );
1954     SetHelpText( Button::GetStandardHelpText( BUTTON_CANCEL ) );
1955 }
1956 
1957 // -----------------------------------------------------------------------
1958 
CancelButton(Window * pParent,WinBits nStyle)1959 CancelButton::CancelButton( Window* pParent, WinBits nStyle ) :
1960     PushButton( WINDOW_CANCELBUTTON )
1961 {
1962     ImplInit( pParent, nStyle );
1963 }
1964 
1965 // -----------------------------------------------------------------------
1966 
CancelButton(Window * pParent,const ResId & rResId)1967 CancelButton::CancelButton( Window* pParent, const ResId& rResId ) :
1968     PushButton( WINDOW_CANCELBUTTON )
1969 {
1970     rResId.SetRT( RSC_CANCELBUTTON );
1971     WinBits nStyle = ImplInitRes( rResId );
1972     ImplInit( pParent, nStyle );
1973     ImplLoadRes( rResId );
1974 
1975     if ( !(nStyle & WB_HIDE) )
1976         Show();
1977 }
1978 
1979 // -----------------------------------------------------------------------
1980 
Click()1981 void CancelButton::Click()
1982 {
1983     // Ist kein Link gesetzt, dann schliesse Parent
1984     if ( !GetClickHdl() )
1985     {
1986         Window* pParent = GetParent();
1987         if ( pParent->IsSystemWindow() )
1988         {
1989             if ( pParent->IsDialog() )
1990             {
1991                 if ( ((Dialog*)pParent)->IsInExecute() )
1992                     ((Dialog*)pParent)->EndDialog( sal_False );
1993                 // gegen rekursive Aufrufe schuetzen
1994                 else if ( !((Dialog*)pParent)->IsInClose() )
1995                 {
1996                     if ( pParent->GetStyle() & WB_CLOSEABLE )
1997                         ((Dialog*)pParent)->Close();
1998                 }
1999             }
2000             else
2001             {
2002                 if ( pParent->GetStyle() & WB_CLOSEABLE )
2003                     ((SystemWindow*)pParent)->Close();
2004             }
2005         }
2006     }
2007     else
2008     {
2009         PushButton::Click();
2010     }
2011 }
2012 
2013 // =======================================================================
2014 
ImplInit(Window * pParent,WinBits nStyle)2015 void HelpButton::ImplInit( Window* pParent, WinBits nStyle )
2016 {
2017     PushButton::ImplInit( pParent, nStyle | WB_NOPOINTERFOCUS );
2018 
2019     SetText( Button::GetStandardText( BUTTON_HELP ) );
2020     SetHelpText( Button::GetStandardHelpText( BUTTON_HELP ) );
2021 }
2022 
2023 // -----------------------------------------------------------------------
2024 
HelpButton(Window * pParent,WinBits nStyle)2025 HelpButton::HelpButton( Window* pParent, WinBits nStyle ) :
2026     PushButton( WINDOW_HELPBUTTON )
2027 {
2028     ImplInit( pParent, nStyle );
2029 }
2030 
2031 // -----------------------------------------------------------------------
2032 
HelpButton(Window * pParent,const ResId & rResId)2033 HelpButton::HelpButton( Window* pParent, const ResId& rResId ) :
2034     PushButton( WINDOW_HELPBUTTON )
2035 {
2036     rResId.SetRT( RSC_HELPBUTTON );
2037     WinBits nStyle = ImplInitRes( rResId );
2038     ImplInit( pParent, nStyle );
2039     ImplLoadRes( rResId );
2040 
2041     if ( !(nStyle & WB_HIDE) )
2042         Show();
2043 }
2044 
2045 // -----------------------------------------------------------------------
2046 
Click()2047 void HelpButton::Click()
2048 {
2049     // Ist kein Link gesetzt, loese Hilfe aus
2050     if ( !GetClickHdl() )
2051     {
2052         Window* pFocusWin = Application::GetFocusWindow();
2053         if ( !pFocusWin )
2054             pFocusWin = this;
2055 
2056         HelpEvent aEvt( pFocusWin->GetPointerPosPixel(), HELPMODE_CONTEXT );
2057         pFocusWin->RequestHelp( aEvt );
2058     }
2059     PushButton::Click();
2060 }
2061 
2062 // =======================================================================
2063 
ImplInitRadioButtonData()2064 void RadioButton::ImplInitRadioButtonData()
2065 {
2066     mbChecked       = sal_False;
2067     mbSaveValue     = sal_False;
2068     mbRadioCheck    = sal_True;
2069     mbStateChanged  = sal_False;
2070 }
2071 
2072 // -----------------------------------------------------------------------
2073 
ImplInit(Window * pParent,WinBits nStyle)2074 void RadioButton::ImplInit( Window* pParent, WinBits nStyle )
2075 {
2076     nStyle = ImplInitStyle( pParent->GetWindow( WINDOW_LASTCHILD ), nStyle );
2077     Button::ImplInit( pParent, nStyle, NULL );
2078 
2079     ImplInitSettings( sal_True, sal_True, sal_True );
2080 }
2081 
2082 // -----------------------------------------------------------------------
2083 
ImplInitStyle(const Window * pPrevWindow,WinBits nStyle)2084 WinBits RadioButton::ImplInitStyle( const Window* pPrevWindow, WinBits nStyle )
2085 {
2086     if ( !(nStyle & WB_NOGROUP) &&
2087          (!pPrevWindow || (pPrevWindow->GetType() != WINDOW_RADIOBUTTON)) )
2088         nStyle |= WB_GROUP;
2089     if ( !(nStyle & WB_NOTABSTOP) )
2090     {
2091         if ( IsChecked() )
2092             nStyle |= WB_TABSTOP;
2093         else
2094             nStyle &= ~WB_TABSTOP;
2095     }
2096     return nStyle;
2097 }
2098 
2099 // -----------------------------------------------------------------
2100 
GetCanonicalFont(const StyleSettings & _rStyle) const2101 const Font& RadioButton::GetCanonicalFont( const StyleSettings& _rStyle ) const
2102 {
2103     return _rStyle.GetRadioCheckFont();
2104 }
2105 
2106 // -----------------------------------------------------------------
GetCanonicalTextColor(const StyleSettings & _rStyle) const2107 const Color& RadioButton::GetCanonicalTextColor( const StyleSettings& _rStyle ) const
2108 {
2109     return _rStyle.GetRadioCheckTextColor();
2110 }
2111 
2112 // -----------------------------------------------------------------------
2113 
ImplInitSettings(sal_Bool bFont,sal_Bool bForeground,sal_Bool bBackground)2114 void RadioButton::ImplInitSettings( sal_Bool bFont,
2115                                     sal_Bool bForeground, sal_Bool bBackground )
2116 {
2117     Button::ImplInitSettings( bFont, bForeground );
2118 
2119     if ( bBackground )
2120     {
2121         Window* pParent = GetParent();
2122         if ( !IsControlBackground() &&
2123             (pParent->IsChildTransparentModeEnabled() || IsNativeControlSupported( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL ) ) )
2124         {
2125             EnableChildTransparentMode( sal_True );
2126             SetParentClipMode( PARENTCLIPMODE_NOCLIP );
2127             SetPaintTransparent( sal_True );
2128             SetBackground();
2129             if( IsNativeControlSupported( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL ) )
2130                 mpWindowImpl->mbUseNativeFocus = ImplGetSVData()->maNWFData.mbNoFocusRects;
2131         }
2132         else
2133         {
2134             EnableChildTransparentMode( sal_False );
2135             SetParentClipMode( 0 );
2136             SetPaintTransparent( sal_False );
2137 
2138             if ( IsControlBackground() )
2139                 SetBackground( GetControlBackground() );
2140             else
2141                 SetBackground( pParent->GetBackground() );
2142         }
2143     }
2144 }
2145 
2146 //---------------------------------------------------------------------
2147 //--- 12.03.2003 18:46:14 ---------------------------------------------
2148 
DrawRadioButtonState()2149 void RadioButton::DrawRadioButtonState( )
2150 {
2151 	ImplDrawRadioButtonState( );
2152 }
2153 
2154 // -----------------------------------------------------------------------
2155 
ImplInvalidateOrDrawRadioButtonState()2156 void RadioButton::ImplInvalidateOrDrawRadioButtonState()
2157 {
2158     if( ImplGetSVData()->maNWFData.mbCheckBoxNeedsErase )
2159     {
2160         if ( IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL) )
2161         {
2162             Invalidate();
2163             Update();
2164             return;
2165         }
2166     }
2167     ImplDrawRadioButtonState();
2168 }
2169 
ImplDrawRadioButtonState()2170 void RadioButton::ImplDrawRadioButtonState()
2171 {
2172     sal_uInt16 nButtonStyle = 0;
2173     sal_Bool   bNativeOK = sal_False;
2174 
2175     // no native drawing for image radio buttons
2176     if ( !maImage && (bNativeOK=IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL)) == sal_True )
2177     {
2178         ImplControlValue		    aControlValue( mbChecked ? BUTTONVALUE_ON : BUTTONVALUE_OFF );
2179         Rectangle					aCtrlRect( maStateRect.TopLeft(), maStateRect.GetSize() );
2180         ControlState				nState = 0;
2181 
2182         if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )	nState |= CTRL_STATE_PRESSED;
2183         if ( HasFocus() ) 						nState |= CTRL_STATE_FOCUSED;
2184         if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT )	nState |= CTRL_STATE_DEFAULT;
2185         if ( IsEnabled() )						nState |= CTRL_STATE_ENABLED;
2186 
2187         if ( IsMouseOver() && maMouseRect.IsInside( GetPointerPosPixel() ) )
2188             nState |= CTRL_STATE_ROLLOVER;
2189 
2190         bNativeOK = DrawNativeControl( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL, aCtrlRect, nState,
2191                     aControlValue,rtl::OUString() );
2192 
2193     }
2194 
2195 if ( bNativeOK == sal_False )
2196 {
2197     // kein Image-RadioButton
2198     if ( !maImage )
2199     {
2200         sal_uInt16 nStyle = ImplGetButtonState();
2201         if ( !IsEnabled() )
2202             nStyle |= BUTTON_DRAW_DISABLED;
2203         if ( mbChecked )
2204             nStyle |= BUTTON_DRAW_CHECKED;
2205         Image aImage = GetRadioImage( GetSettings(), nStyle );
2206         if ( IsZoom() )
2207             DrawImage( maStateRect.TopLeft(), maStateRect.GetSize(), aImage );
2208         else
2209             DrawImage( maStateRect.TopLeft(), aImage );
2210     }
2211     else
2212     {
2213         HideFocus();
2214 
2215         DecorationView          aDecoView( this );
2216         const StyleSettings&    rStyleSettings = GetSettings().GetStyleSettings();
2217         Rectangle               aImageRect  = maStateRect;
2218         Size                    aImageSize  = maImage.GetSizePixel();
2219         sal_Bool                    bEnabled    = IsEnabled();
2220 
2221         aImageSize.Width()  = CalcZoom( aImageSize.Width() );
2222         aImageSize.Height() = CalcZoom( aImageSize.Height() );
2223 
2224         // Border und Selektionsstatus ausgeben
2225         nButtonStyle = FRAME_DRAW_DOUBLEIN;
2226         aImageRect = aDecoView.DrawFrame( aImageRect, nButtonStyle );
2227         if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) || !bEnabled )
2228             SetFillColor( rStyleSettings.GetFaceColor() );
2229         else
2230             SetFillColor( rStyleSettings.GetFieldColor() );
2231         SetLineColor();
2232         DrawRect( aImageRect );
2233 
2234         // Image ausgeben
2235         nButtonStyle = 0;
2236         if ( !bEnabled )
2237             nButtonStyle |= IMAGE_DRAW_DISABLE;
2238 
2239 		// check for HC mode
2240 		Image *pImage = &maImage;
2241 		if( !!maImageHC )
2242 		{
2243 			if( rStyleSettings.GetHighContrastMode() )
2244 				pImage = &maImageHC;
2245 		}
2246 
2247         Point aImagePos( aImageRect.TopLeft() );
2248         aImagePos.X() += (aImageRect.GetWidth()-aImageSize.Width())/2;
2249         aImagePos.Y() += (aImageRect.GetHeight()-aImageSize.Height())/2;
2250         if ( IsZoom() )
2251             DrawImage( aImagePos, aImageSize, *pImage, nButtonStyle );
2252         else
2253             DrawImage( aImagePos, *pImage, nButtonStyle );
2254 
2255         aImageRect.Left()++;
2256         aImageRect.Top()++;
2257         aImageRect.Right()--;
2258         aImageRect.Bottom()--;
2259 
2260         ImplSetFocusRect( aImageRect );
2261 
2262         if ( mbChecked )
2263         {
2264             SetLineColor( rStyleSettings.GetHighlightColor() );
2265             SetFillColor();
2266             if ( (aImageSize.Width() >= 20) || (aImageSize.Height() >= 20) )
2267             {
2268                 aImageRect.Left()++;
2269                 aImageRect.Top()++;
2270                 aImageRect.Right()--;
2271                 aImageRect.Bottom()--;
2272             }
2273             DrawRect( aImageRect );
2274             aImageRect.Left()++;
2275             aImageRect.Top()++;
2276             aImageRect.Right()--;
2277             aImageRect.Bottom()--;
2278             DrawRect( aImageRect );
2279         }
2280 
2281         if ( HasFocus() )
2282             ShowFocus( ImplGetFocusRect() );
2283     }
2284 }
2285 }
2286 
2287 // -----------------------------------------------------------------------
2288 
ImplDraw(OutputDevice * pDev,sal_uLong nDrawFlags,const Point & rPos,const Size & rSize,const Size & rImageSize,Rectangle & rStateRect,Rectangle & rMouseRect,bool bLayout)2289 void RadioButton::ImplDraw( OutputDevice* pDev, sal_uLong nDrawFlags,
2290                             const Point& rPos, const Size& rSize,
2291                             const Size& rImageSize, Rectangle& rStateRect,
2292                             Rectangle& rMouseRect, bool bLayout )
2293 {
2294     WinBits                 nWinStyle = GetStyle();
2295     XubString               aText( GetText() );
2296     Rectangle               aRect( rPos, rSize );
2297     MetricVector*			pVector = bLayout ? &mpControlData->mpLayoutData->m_aUnicodeBoundRects : NULL;
2298     String*					pDisplayText = bLayout ? &mpControlData->mpLayoutData->m_aDisplayText : NULL;
2299 
2300     pDev->Push( PUSH_CLIPREGION );
2301     pDev->IntersectClipRegion( Rectangle( rPos, rSize ) );
2302 
2303     // kein Image-RadioButton
2304     if ( !maImage )
2305     {
2306         if ( ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) ) ||
2307              ( HasImage() &&  ! (ImplGetButtonState() & BUTTON_DRAW_NOIMAGE) ) )
2308         {
2309             sal_uInt16 nTextStyle = Button::ImplGetTextStyle( aText, nWinStyle, nDrawFlags );
2310 
2311             const long nImageSep = GetDrawPixel( pDev, ImplGetImageToTextDistance() );
2312             Size aSize( rSize );
2313             Point aPos( rPos );
2314             aPos.X() += rImageSize.Width() + nImageSep;
2315             aSize.Width() -= rImageSize.Width() + nImageSep;
2316 
2317             // if the text rect height is smaller than the height of the image
2318             // then for single lines the default should be centered text
2319             if( (nWinStyle & (WB_TOP|WB_VCENTER|WB_BOTTOM)) == 0 &&
2320                 (rImageSize.Height() > rSize.Height() || ! (nWinStyle & WB_WORDBREAK)  ) )
2321             {
2322                 nTextStyle &= ~(TEXT_DRAW_TOP|TEXT_DRAW_BOTTOM);
2323                 nTextStyle |= TEXT_DRAW_VCENTER;
2324                 aSize.Height() = rImageSize.Height();
2325             }
2326 
2327             ImplDrawAlignedImage( pDev, aPos, aSize, bLayout, 1,
2328                                   nDrawFlags, nTextStyle, NULL );
2329 
2330             rMouseRect          = Rectangle( aPos, aSize );
2331             rMouseRect.Left()   = rPos.X();
2332 
2333             rStateRect.Left()   = rPos.X();
2334             rStateRect.Top()    = rMouseRect.Top();
2335 
2336             if ( aSize.Height() > rImageSize.Height() )
2337                 rStateRect.Top() += ( aSize.Height() - rImageSize.Height() ) / 2;
2338             else
2339             {
2340                 rStateRect.Top() -= ( rImageSize.Height() - aSize.Height() ) / 2;
2341                 if( rStateRect.Top() < 0 )
2342                     rStateRect.Top() = 0;
2343             }
2344 
2345             rStateRect.Right()  = rStateRect.Left() + rImageSize.Width()-1;
2346             rStateRect.Bottom() = rStateRect.Top() + rImageSize.Height()-1;
2347 
2348             if ( rStateRect.Bottom() > rMouseRect.Bottom() )
2349                 rMouseRect.Bottom() = rStateRect.Bottom();
2350         }
2351         else
2352         {
2353             if ( nWinStyle & WB_CENTER )
2354                 rStateRect.Left() = rPos.X()+((rSize.Width()-rImageSize.Width())/2);
2355             else if ( nWinStyle & WB_RIGHT )
2356                 rStateRect.Left() = rPos.X()+rSize.Width()-rImageSize.Width(); //-1;
2357             else
2358                 rStateRect.Left() = rPos.X(); //+1;
2359             if ( nWinStyle & WB_VCENTER )
2360                 rStateRect.Top() = rPos.Y()+((rSize.Height()-rImageSize.Height())/2);
2361             else if ( nWinStyle & WB_BOTTOM )
2362                 rStateRect.Top() = rPos.Y()+rSize.Height()-rImageSize.Height(); //-1;
2363             else
2364                 rStateRect.Top() = rPos.Y(); //+1;
2365             rStateRect.Right()  = rStateRect.Left()+rImageSize.Width()-1;
2366             rStateRect.Bottom() = rStateRect.Top()+rImageSize.Height()-1;
2367             rMouseRect          = rStateRect;
2368 
2369             ImplSetFocusRect( rStateRect );
2370 
2371 /*  und oben -1, da CalcSize() auch Focus-Rechteck nicht mit einrechnet,
2372 da im Writer ansonsten die Images noch weiter oben haengen
2373             rFocusRect          = rStateRect;
2374             rFocusRect.Left()--;
2375             rFocusRect.Top()--;
2376             rFocusRect.Right()++;
2377             rFocusRect.Bottom()++;
2378 */
2379         }
2380     }
2381     else
2382     {
2383         sal_Bool        bTopImage   = (nWinStyle & WB_TOP) != 0;
2384         Size        aImageSize  = maImage.GetSizePixel();
2385         Rectangle   aImageRect( rPos, rSize );
2386         long        nTextHeight = pDev->GetTextHeight();
2387         long        nTextWidth  = pDev->GetCtrlTextWidth( aText );
2388 
2389         // Positionen und Groessen berechnen
2390         if ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
2391         {
2392             Size aTmpSize( (aImageSize.Width()+8), (aImageSize.Height()+8) );
2393             if ( bTopImage )
2394             {
2395                 aImageRect.Left() = (rSize.Width()-aTmpSize.Width())/2;
2396                 aImageRect.Top()  = (rSize.Height()-(aTmpSize.Height()+nTextHeight+6))/2;
2397             }
2398             else
2399                 aImageRect.Top()  = (rSize.Height()-aTmpSize.Height())/2;
2400 
2401             aImageRect.Right()  = aImageRect.Left()+aTmpSize.Width();
2402             aImageRect.Bottom() = aImageRect.Top()+aTmpSize.Height();
2403 
2404             // Text ausgeben
2405             Point aTxtPos = rPos;
2406             if ( bTopImage )
2407             {
2408                 aTxtPos.X() += (rSize.Width()-nTextWidth)/2;
2409                 aTxtPos.Y() += aImageRect.Bottom()+6;
2410             }
2411             else
2412             {
2413                 aTxtPos.X() += aImageRect.Right()+8;
2414                 aTxtPos.Y() += (rSize.Height()-nTextHeight)/2;
2415             }
2416             pDev->DrawCtrlText( aTxtPos, aText, 0, STRING_LEN, TEXT_DRAW_MNEMONIC, pVector, pDisplayText );
2417         }
2418 
2419         rMouseRect = aImageRect;
2420         rStateRect = aImageRect;
2421     }
2422 
2423     pDev->Pop();
2424 }
2425 
2426 // -----------------------------------------------------------------------
2427 
ImplDrawRadioButton(bool bLayout)2428 void RadioButton::ImplDrawRadioButton( bool bLayout )
2429 {
2430     if( !bLayout )
2431         HideFocus();
2432 
2433     Size aImageSize;
2434     if ( !maImage )
2435         aImageSize = ImplGetRadioImageSize();
2436     else
2437         aImageSize  = maImage.GetSizePixel();
2438     aImageSize.Width()  = CalcZoom( aImageSize.Width() );
2439     aImageSize.Height() = CalcZoom( aImageSize.Height() );
2440 
2441     // Draw control text
2442     ImplDraw( this, 0, Point(), GetOutputSizePixel(),
2443               aImageSize, maStateRect, maMouseRect, bLayout );
2444 
2445     if( !bLayout || (IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL)==sal_True) )
2446     {
2447         if ( !maImage && HasFocus() )
2448             ShowFocus( ImplGetFocusRect() );
2449 
2450         ImplDrawRadioButtonState();
2451     }
2452 }
2453 
2454 // -----------------------------------------------------------------------
2455 
GetRadioButtonGroup(std::vector<RadioButton * > & io_rGroup,bool bIncludeThis) const2456 void RadioButton::GetRadioButtonGroup( std::vector< RadioButton* >& io_rGroup, bool bIncludeThis ) const
2457 {
2458     // empty the list
2459     io_rGroup.clear();
2460 
2461     // go back to first in group;
2462     Window* pFirst = const_cast<RadioButton*>(this);
2463     while( ( pFirst->GetStyle() & WB_GROUP ) == 0 )
2464     {
2465         Window* pWindow = pFirst->GetWindow( WINDOW_PREV );
2466         if( pWindow )
2467             pFirst = pWindow;
2468         else
2469             break;
2470     }
2471     // insert radiobuttons up to next group
2472     do
2473     {
2474         if( pFirst->GetType() == WINDOW_RADIOBUTTON )
2475         {
2476             if( pFirst != this || bIncludeThis )
2477                 io_rGroup.push_back( static_cast<RadioButton*>(pFirst) );
2478         }
2479         pFirst = pFirst->GetWindow( WINDOW_NEXT );
2480     } while( pFirst && ( ( pFirst->GetStyle() & WB_GROUP ) == 0 ) );
2481 }
2482 
2483 // -----------------------------------------------------------------------
2484 
ImplUncheckAllOther()2485 void RadioButton::ImplUncheckAllOther()
2486 {
2487     mpWindowImpl->mnStyle |= WB_TABSTOP;
2488 
2489     // Gruppe mit RadioButtons durchgehen und die gecheckten Buttons
2490     Window* pWindow;
2491     WinBits nStyle;
2492     if ( !(GetStyle() & WB_GROUP) )
2493     {
2494         pWindow = GetWindow( WINDOW_PREV );
2495         while ( pWindow )
2496         {
2497             nStyle = pWindow->GetStyle();
2498 
2499             if ( pWindow->GetType() == WINDOW_RADIOBUTTON )
2500             {
2501                 if ( ((RadioButton*)pWindow)->IsChecked() )
2502                 {
2503                     ImplDelData aDelData;
2504                     pWindow->ImplAddDel( &aDelData );
2505                     ((RadioButton*)pWindow)->SetState( sal_False );
2506                     if ( aDelData.IsDelete() )
2507                         return;
2508                     pWindow->ImplRemoveDel( &aDelData );
2509                 }
2510                 // Um falsch gesetzt WB_TABSTOPS immer zu entfernen, nicht
2511                 // innerhalb der if-Abfrage
2512                 pWindow->mpWindowImpl->mnStyle &= ~WB_TABSTOP;
2513             }
2514 
2515             if ( nStyle & WB_GROUP )
2516                 break;
2517 
2518             pWindow = pWindow->GetWindow( WINDOW_PREV );
2519         }
2520     }
2521 
2522     pWindow = GetWindow( WINDOW_NEXT );
2523     while ( pWindow )
2524     {
2525         nStyle = pWindow->GetStyle();
2526 
2527         if ( nStyle & WB_GROUP )
2528             break;
2529 
2530         if ( pWindow->GetType() == WINDOW_RADIOBUTTON )
2531         {
2532             if ( ((RadioButton*)pWindow)->IsChecked() )
2533             {
2534                 ImplDelData aDelData;
2535                 pWindow->ImplAddDel( &aDelData );
2536                 ((RadioButton*)pWindow)->SetState( sal_False );
2537                 if ( aDelData.IsDelete() )
2538                     return;
2539                 pWindow->ImplRemoveDel( &aDelData );
2540             }
2541             // Um falsch gesetzt WB_TABSTOPS immer zu entfernen, nicht
2542             // innerhalb der if-Abfrage
2543             pWindow->mpWindowImpl->mnStyle &= ~WB_TABSTOP;
2544         }
2545 
2546         pWindow = pWindow->GetWindow( WINDOW_NEXT );
2547     }
2548 }
2549 
2550 // -----------------------------------------------------------------------
2551 
ImplCallClick(sal_Bool bGrabFocus,sal_uInt16 nFocusFlags)2552 void RadioButton::ImplCallClick( sal_Bool bGrabFocus, sal_uInt16 nFocusFlags )
2553 {
2554     mbStateChanged = !mbChecked;
2555     mbChecked = sal_True;
2556     mpWindowImpl->mnStyle |= WB_TABSTOP;
2557     ImplInvalidateOrDrawRadioButtonState();
2558     ImplDelData aDelData;
2559     ImplAddDel( &aDelData );
2560     if ( mbRadioCheck )
2561         ImplUncheckAllOther();
2562     if ( aDelData.IsDelete() )
2563         return;
2564     if ( bGrabFocus )
2565         ImplGrabFocus( nFocusFlags );
2566     if ( aDelData.IsDelete() )
2567         return;
2568     if ( mbStateChanged )
2569         Toggle();
2570     if ( aDelData.IsDelete() )
2571         return;
2572     Click();
2573     if ( aDelData.IsDelete() )
2574         return;
2575     ImplRemoveDel( &aDelData );
2576     mbStateChanged = sal_False;
2577 }
2578 
2579 // -----------------------------------------------------------------------
2580 
RadioButton(Window * pParent,WinBits nStyle)2581 RadioButton::RadioButton( Window* pParent, WinBits nStyle ) :
2582     Button( WINDOW_RADIOBUTTON )
2583 {
2584     ImplInitRadioButtonData();
2585     ImplInit( pParent, nStyle );
2586 }
2587 
2588 // -----------------------------------------------------------------------
2589 
RadioButton(Window * pParent,const ResId & rResId)2590 RadioButton::RadioButton( Window* pParent, const ResId& rResId ) :
2591     Button( WINDOW_RADIOBUTTON )
2592 {
2593     ImplInitRadioButtonData();
2594     rResId.SetRT( RSC_RADIOBUTTON );
2595     WinBits nStyle = ImplInitRes( rResId );
2596     ImplInit( pParent, nStyle );
2597     ImplLoadRes( rResId );
2598 
2599     if ( !(nStyle & WB_HIDE) )
2600         Show();
2601 }
2602 
2603 // -----------------------------------------------------------------------
2604 
ImplLoadRes(const ResId & rResId)2605 void RadioButton::ImplLoadRes( const ResId& rResId )
2606 {
2607     Button::ImplLoadRes( rResId );
2608 
2609     //anderer Wert als Default ?
2610     sal_uInt16 nChecked = ReadShortRes();
2611     if ( nChecked )
2612         SetState( sal_True );
2613 }
2614 
2615 // -----------------------------------------------------------------------
2616 
~RadioButton()2617 RadioButton::~RadioButton()
2618 {
2619 }
2620 
2621 // -----------------------------------------------------------------------
2622 
MouseButtonDown(const MouseEvent & rMEvt)2623 void RadioButton::MouseButtonDown( const MouseEvent& rMEvt )
2624 {
2625     if ( rMEvt.IsLeft() && maMouseRect.IsInside( rMEvt.GetPosPixel() ) )
2626     {
2627         ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
2628         ImplInvalidateOrDrawRadioButtonState();
2629         StartTracking();
2630         return;
2631     }
2632 
2633     Button::MouseButtonDown( rMEvt );
2634 }
2635 
2636 // -----------------------------------------------------------------------
2637 
Tracking(const TrackingEvent & rTEvt)2638 void RadioButton::Tracking( const TrackingEvent& rTEvt )
2639 {
2640     if ( rTEvt.IsTrackingEnded() )
2641     {
2642         if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
2643         {
2644             if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() )
2645                 GrabFocus();
2646 
2647             ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
2648 
2649             // Bei Abbruch kein Click-Handler rufen
2650             if ( !rTEvt.IsTrackingCanceled() )
2651                 ImplCallClick();
2652             else
2653                 ImplInvalidateOrDrawRadioButtonState();
2654         }
2655     }
2656     else
2657     {
2658         if ( maMouseRect.IsInside( rTEvt.GetMouseEvent().GetPosPixel() ) )
2659         {
2660             if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) )
2661             {
2662                 ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
2663                 ImplInvalidateOrDrawRadioButtonState();
2664             }
2665         }
2666         else
2667         {
2668             if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
2669             {
2670                 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
2671                 ImplInvalidateOrDrawRadioButtonState();
2672             }
2673         }
2674     }
2675 }
2676 
2677 // -----------------------------------------------------------------------
2678 
KeyInput(const KeyEvent & rKEvt)2679 void RadioButton::KeyInput( const KeyEvent& rKEvt )
2680 {
2681     KeyCode aKeyCode = rKEvt.GetKeyCode();
2682 
2683     if ( !aKeyCode.GetModifier() && (aKeyCode.GetCode() == KEY_SPACE) )
2684     {
2685         if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) )
2686         {
2687             ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
2688             ImplInvalidateOrDrawRadioButtonState();
2689         }
2690     }
2691     else if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_ESCAPE) )
2692     {
2693         ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
2694         ImplInvalidateOrDrawRadioButtonState();
2695     }
2696     else
2697         Button::KeyInput( rKEvt );
2698 }
2699 
2700 // -----------------------------------------------------------------------
2701 
KeyUp(const KeyEvent & rKEvt)2702 void RadioButton::KeyUp( const KeyEvent& rKEvt )
2703 {
2704     KeyCode aKeyCode = rKEvt.GetKeyCode();
2705 
2706     if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_SPACE) )
2707     {
2708         ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
2709         ImplCallClick();
2710     }
2711     else
2712         Button::KeyUp( rKEvt );
2713 }
2714 
2715 // -----------------------------------------------------------------------
2716 
FillLayoutData() const2717 void RadioButton::FillLayoutData() const
2718 {
2719     mpControlData->mpLayoutData = new vcl::ControlLayoutData();
2720     const_cast<RadioButton*>(this)->ImplDrawRadioButton( true );
2721 }
2722 
2723 // -----------------------------------------------------------------------
2724 
Paint(const Rectangle &)2725 void RadioButton::Paint( const Rectangle& )
2726 {
2727     ImplDrawRadioButton();
2728 }
2729 
2730 // -----------------------------------------------------------------------
2731 
Draw(OutputDevice * pDev,const Point & rPos,const Size & rSize,sal_uLong nFlags)2732 void RadioButton::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
2733                         sal_uLong nFlags )
2734 {
2735     if ( !maImage )
2736     {
2737         MapMode     aResMapMode( MAP_100TH_MM );
2738         Point       aPos  = pDev->LogicToPixel( rPos );
2739         Size        aSize = pDev->LogicToPixel( rSize );
2740         Size        aImageSize = pDev->LogicToPixel( Size( 300, 300 ), aResMapMode );
2741         Size        aBrd1Size = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode );
2742         Size        aBrd2Size = pDev->LogicToPixel( Size( 60, 60 ), aResMapMode );
2743         Font        aFont = GetDrawPixelFont( pDev );
2744         Rectangle   aStateRect;
2745         Rectangle   aMouseRect;
2746         Rectangle   aFocusRect;
2747 
2748         aImageSize.Width()  = CalcZoom( aImageSize.Width() );
2749         aImageSize.Height() = CalcZoom( aImageSize.Height() );
2750         aBrd1Size.Width()   = CalcZoom( aBrd1Size.Width() );
2751         aBrd1Size.Height()  = CalcZoom( aBrd1Size.Height() );
2752         aBrd2Size.Width()   = CalcZoom( aBrd2Size.Width() );
2753         aBrd2Size.Height()  = CalcZoom( aBrd2Size.Height() );
2754 
2755         if ( !aBrd1Size.Width() )
2756             aBrd1Size.Width() = 1;
2757         if ( !aBrd1Size.Height() )
2758             aBrd1Size.Height() = 1;
2759         if ( !aBrd2Size.Width() )
2760             aBrd2Size.Width() = 1;
2761         if ( !aBrd2Size.Height() )
2762             aBrd2Size.Height() = 1;
2763 
2764         pDev->Push();
2765         pDev->SetMapMode();
2766         pDev->SetFont( aFont );
2767         if ( nFlags & WINDOW_DRAW_MONO )
2768             pDev->SetTextColor( Color( COL_BLACK ) );
2769         else
2770             pDev->SetTextColor( GetTextColor() );
2771         pDev->SetTextFillColor();
2772 
2773         ImplDraw( pDev, nFlags, aPos, aSize,
2774                   aImageSize, aStateRect, aMouseRect );
2775 
2776         Point   aCenterPos = aStateRect.Center();
2777         long    nRadX = aImageSize.Width()/2;
2778         long    nRadY = aImageSize.Height()/2;
2779 
2780         pDev->SetLineColor();
2781         pDev->SetFillColor( Color( COL_BLACK ) );
2782         pDev->DrawPolygon( Polygon( aCenterPos, nRadX, nRadY ) );
2783         nRadX -= aBrd1Size.Width();
2784         nRadY -= aBrd1Size.Height();
2785         pDev->SetFillColor( Color( COL_WHITE ) );
2786         pDev->DrawPolygon( Polygon( aCenterPos, nRadX, nRadY ) );
2787         if ( mbChecked )
2788         {
2789             nRadX -= aBrd1Size.Width();
2790             nRadY -= aBrd1Size.Height();
2791             if ( !nRadX )
2792                 nRadX = 1;
2793             if ( !nRadY )
2794                 nRadY = 1;
2795             pDev->SetFillColor( Color( COL_BLACK ) );
2796             pDev->DrawPolygon( Polygon( aCenterPos, nRadX, nRadY ) );
2797         }
2798 
2799         pDev->Pop();
2800     }
2801     else
2802     {
2803         DBG_ERROR( "RadioButton::Draw() - not implemented for RadioButton with Image" );
2804     }
2805 }
2806 
2807 // -----------------------------------------------------------------------
2808 
Resize()2809 void RadioButton::Resize()
2810 {
2811     Control::Resize();
2812     Invalidate();
2813 }
2814 
2815 // -----------------------------------------------------------------------
2816 
GetFocus()2817 void RadioButton::GetFocus()
2818 {
2819     ShowFocus( ImplGetFocusRect() );
2820     SetInputContext( InputContext( GetFont() ) );
2821     Button::GetFocus();
2822 }
2823 
2824 // -----------------------------------------------------------------------
2825 
LoseFocus()2826 void RadioButton::LoseFocus()
2827 {
2828     if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
2829     {
2830         ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
2831         ImplInvalidateOrDrawRadioButtonState();
2832     }
2833 
2834     HideFocus();
2835     Button::LoseFocus();
2836 }
2837 
2838 // -----------------------------------------------------------------------
2839 
StateChanged(StateChangedType nType)2840 void RadioButton::StateChanged( StateChangedType nType )
2841 {
2842     Button::StateChanged( nType );
2843 
2844     if ( nType == STATE_CHANGE_STATE )
2845     {
2846         if ( IsReallyVisible() && IsUpdateMode() )
2847             Invalidate( maStateRect );
2848     }
2849     else if ( (nType == STATE_CHANGE_ENABLE) ||
2850               (nType == STATE_CHANGE_TEXT) ||
2851               (nType == STATE_CHANGE_IMAGE) ||
2852               (nType == STATE_CHANGE_DATA) ||
2853               (nType == STATE_CHANGE_UPDATEMODE) )
2854     {
2855         if ( IsUpdateMode() )
2856             Invalidate();
2857     }
2858     else if ( nType == STATE_CHANGE_STYLE )
2859     {
2860         SetStyle( ImplInitStyle( GetWindow( WINDOW_PREV ), GetStyle() ) );
2861 
2862         if ( (GetPrevStyle() & RADIOBUTTON_VIEW_STYLE) !=
2863              (GetStyle() & RADIOBUTTON_VIEW_STYLE) )
2864         {
2865             if ( IsUpdateMode() )
2866                 Invalidate();
2867         }
2868     }
2869     else if ( (nType == STATE_CHANGE_ZOOM) ||
2870               (nType == STATE_CHANGE_CONTROLFONT) )
2871     {
2872         ImplInitSettings( sal_True, sal_False, sal_False );
2873         Invalidate();
2874     }
2875     else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
2876     {
2877         ImplInitSettings( sal_False, sal_True, sal_False );
2878         Invalidate();
2879     }
2880     else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
2881     {
2882         ImplInitSettings( sal_False, sal_False, sal_True );
2883         Invalidate();
2884     }
2885 }
2886 
2887 // -----------------------------------------------------------------------
2888 
DataChanged(const DataChangedEvent & rDCEvt)2889 void RadioButton::DataChanged( const DataChangedEvent& rDCEvt )
2890 {
2891     Button::DataChanged( rDCEvt );
2892 
2893     if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
2894          (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
2895          ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
2896           (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
2897     {
2898         ImplInitSettings( sal_True, sal_True, sal_True );
2899         Invalidate();
2900     }
2901 }
2902 
2903 // -----------------------------------------------------------------------
2904 
PreNotify(NotifyEvent & rNEvt)2905 long RadioButton::PreNotify( NotifyEvent& rNEvt )
2906 {
2907     long nDone = 0;
2908     const MouseEvent* pMouseEvt = NULL;
2909 
2910     if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL )
2911     {
2912         if( !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() )
2913         {
2914             // trigger redraw if mouse over state has changed
2915             if( IsNativeControlSupported(CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL) )
2916             {
2917                 if( ( maMouseRect.IsInside( GetPointerPosPixel()) &&
2918                      !maMouseRect.IsInside( GetLastPointerPosPixel()) ) ||
2919                     ( maMouseRect.IsInside( GetLastPointerPosPixel()) &&
2920                      !maMouseRect.IsInside( GetPointerPosPixel()) ) ||
2921                      pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow() )
2922                 {
2923                     Invalidate( maStateRect );
2924                 }
2925             }
2926         }
2927     }
2928 
2929     return nDone ? nDone : Button::PreNotify(rNEvt);
2930 }
2931 
2932 // -----------------------------------------------------------------------
2933 
Toggle()2934 void RadioButton::Toggle()
2935 {
2936     ImplCallEventListenersAndHandler( VCLEVENT_RADIOBUTTON_TOGGLE, maToggleHdl, this );
2937 }
2938 
2939 // -----------------------------------------------------------------------
2940 
SetModeRadioImage(const Image & rImage,BmpColorMode eMode)2941 sal_Bool RadioButton::SetModeRadioImage( const Image& rImage, BmpColorMode eMode )
2942 {
2943     if( eMode == BMP_COLOR_NORMAL )
2944 {
2945     if ( rImage != maImage )
2946     {
2947         maImage = rImage;
2948         StateChanged( STATE_CHANGE_DATA );
2949     }
2950 }
2951     else if( eMode == BMP_COLOR_HIGHCONTRAST )
2952     {
2953 		if( maImageHC != rImage )
2954 		{
2955 			maImageHC = rImage;
2956 			StateChanged( STATE_CHANGE_DATA );
2957 		}
2958     }
2959     else
2960         return sal_False;
2961 
2962     return sal_True;
2963 }
2964 
2965 // -----------------------------------------------------------------------
2966 
GetModeRadioImage(BmpColorMode eMode) const2967 const Image& RadioButton::GetModeRadioImage( BmpColorMode eMode ) const
2968 {
2969     if( eMode == BMP_COLOR_HIGHCONTRAST )
2970         return maImageHC;
2971     else
2972         return maImage;
2973 }
2974 
2975 // -----------------------------------------------------------------------
2976 
SetState(sal_Bool bCheck)2977 void RadioButton::SetState( sal_Bool bCheck )
2978 {
2979     // TabStop-Flag richtig mitfuehren
2980     if ( bCheck )
2981         mpWindowImpl->mnStyle |= WB_TABSTOP;
2982     else
2983         mpWindowImpl->mnStyle &= ~WB_TABSTOP;
2984 
2985     if ( mbChecked != bCheck )
2986     {
2987         mbChecked = bCheck;
2988         StateChanged( STATE_CHANGE_STATE );
2989         Toggle();
2990     }
2991 }
2992 
2993 // -----------------------------------------------------------------------
2994 
Check(sal_Bool bCheck)2995 void RadioButton::Check( sal_Bool bCheck )
2996 {
2997     // TabStop-Flag richtig mitfuehren
2998     if ( bCheck )
2999         mpWindowImpl->mnStyle |= WB_TABSTOP;
3000     else
3001         mpWindowImpl->mnStyle &= ~WB_TABSTOP;
3002 
3003     if ( mbChecked != bCheck )
3004     {
3005         mbChecked = bCheck;
3006         ImplDelData aDelData;
3007         ImplAddDel( &aDelData );
3008         StateChanged( STATE_CHANGE_STATE );
3009         if ( aDelData.IsDelete() )
3010             return;
3011         if ( bCheck && mbRadioCheck )
3012             ImplUncheckAllOther();
3013         if ( aDelData.IsDelete() )
3014             return;
3015         Toggle();
3016         ImplRemoveDel( &aDelData );
3017     }
3018 }
3019 
3020 // -----------------------------------------------------------------------
3021 
ImplGetImageToTextDistance() const3022 long RadioButton::ImplGetImageToTextDistance() const
3023 {
3024     // 4 pixels, but take zoom into account, so the text doesn't "jump" relative to surrounding elements,
3025     // which might have been aligned with the text of the check box
3026     return CalcZoom( 4 );
3027 }
3028 
3029 // -----------------------------------------------------------------------
3030 
ImplGetRadioImageSize() const3031 Size RadioButton::ImplGetRadioImageSize() const
3032 {
3033     Size aSize;
3034     // why are IsNativeControlSupported and GetNativeControlRegion not const ?
3035     RadioButton* pThis = const_cast<RadioButton*>(this);
3036     bool bDefaultSize = true;
3037     if( pThis->IsNativeControlSupported( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL ) )
3038     {
3039         ImplControlValue aControlValue;
3040         // #i45896# workaround gcc3.3 temporary problem
3041         Rectangle		 aCtrlRegion( Point( 0, 0 ), GetSizePixel() );
3042         ControlState	 nState = CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED;
3043         Rectangle aBoundingRgn, aContentRgn;
3044 
3045         // get native size of a radio button
3046         if( pThis->GetNativeControlRegion( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion,
3047                                            nState, aControlValue, rtl::OUString(),
3048                                            aBoundingRgn, aContentRgn ) )
3049         {
3050             aSize = aContentRgn.GetSize();
3051             bDefaultSize = false;
3052         }
3053     }
3054     if( bDefaultSize )
3055         aSize = GetRadioImage( GetSettings(), 0 ).GetSizePixel();
3056     return aSize;
3057 }
3058 
LoadThemedImageList(const StyleSettings & rStyleSettings,ImageList * pList,const ResId & rResId,sal_uInt16 nImages)3059 static void LoadThemedImageList (const StyleSettings &rStyleSettings,
3060 								 ImageList *pList, const ResId &rResId,
3061                                  sal_uInt16 nImages)
3062 {
3063 	Color aColorAry1[6];
3064 	Color aColorAry2[6];
3065 	aColorAry1[0] = Color( 0xC0, 0xC0, 0xC0 );
3066 	aColorAry1[1] = Color( 0xFF, 0xFF, 0x00 );
3067 	aColorAry1[2] = Color( 0xFF, 0xFF, 0xFF );
3068 	aColorAry1[3] = Color( 0x80, 0x80, 0x80 );
3069 	aColorAry1[4] = Color( 0x00, 0x00, 0x00 );
3070 	aColorAry1[5] = Color( 0x00, 0xFF, 0x00 );
3071 	aColorAry2[0] = rStyleSettings.GetFaceColor();
3072 	aColorAry2[1] = rStyleSettings.GetWindowColor();
3073 	aColorAry2[2] = rStyleSettings.GetLightColor();
3074 	aColorAry2[3] = rStyleSettings.GetShadowColor();
3075 	aColorAry2[4] = rStyleSettings.GetDarkShadowColor();
3076 	aColorAry2[5] = rStyleSettings.GetWindowTextColor();
3077 
3078 	Color aMaskColor(0x00, 0x00, 0xFF );
3079         DBG_ASSERT( sizeof(aColorAry1) == sizeof(aColorAry2), "aColorAry1 must match aColorAry2" );
3080 	// FIXME: do we want the mask for the checkbox ?
3081 	pList->InsertFromHorizontalBitmap (rResId, nImages, &aMaskColor,
3082         aColorAry1, aColorAry2, sizeof(aColorAry1) / sizeof(Color));
3083 }
3084 
GetRadioImage(const AllSettings & rSettings,sal_uInt16 nFlags)3085 Image RadioButton::GetRadioImage( const AllSettings& rSettings, sal_uInt16 nFlags )
3086 {
3087     ImplSVData*             pSVData = ImplGetSVData();
3088     const StyleSettings&    rStyleSettings = rSettings.GetStyleSettings();
3089     sal_uInt16              nStyle = 0;
3090 
3091     if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO )
3092         nStyle = STYLE_RADIOBUTTON_MONO;
3093 
3094     if ( !pSVData->maCtrlData.mpRadioImgList ||
3095          (pSVData->maCtrlData.mnRadioStyle != nStyle) ||
3096          (pSVData->maCtrlData.mnLastRadioFColor != rStyleSettings.GetFaceColor().GetColor()) ||
3097          (pSVData->maCtrlData.mnLastRadioWColor != rStyleSettings.GetWindowColor().GetColor()) ||
3098          (pSVData->maCtrlData.mnLastRadioLColor != rStyleSettings.GetLightColor().GetColor()) )
3099     {
3100         if ( pSVData->maCtrlData.mpRadioImgList )
3101             delete pSVData->maCtrlData.mpRadioImgList;
3102 
3103         pSVData->maCtrlData.mnLastRadioFColor = rStyleSettings.GetFaceColor().GetColor();
3104         pSVData->maCtrlData.mnLastRadioWColor = rStyleSettings.GetWindowColor().GetColor();
3105         pSVData->maCtrlData.mnLastRadioLColor = rStyleSettings.GetLightColor().GetColor();
3106 
3107         Color pColorAry1[6];
3108         Color pColorAry2[6];
3109         pColorAry1[0] = Color( 0xC0, 0xC0, 0xC0 );
3110         pColorAry1[1] = Color( 0xFF, 0xFF, 0x00 );
3111         pColorAry1[2] = Color( 0xFF, 0xFF, 0xFF );
3112         pColorAry1[3] = Color( 0x80, 0x80, 0x80 );
3113         pColorAry1[4] = Color( 0x00, 0x00, 0x00 );
3114         pColorAry1[5] = Color( 0x00, 0xFF, 0x00 );
3115         pColorAry2[0] = rStyleSettings.GetFaceColor();
3116         pColorAry2[1] = rStyleSettings.GetWindowColor();
3117         pColorAry2[2] = rStyleSettings.GetLightColor();
3118         pColorAry2[3] = rStyleSettings.GetShadowColor();
3119         pColorAry2[4] = rStyleSettings.GetDarkShadowColor();
3120         pColorAry2[5] = rStyleSettings.GetWindowTextColor();
3121 
3122         ResMgr* pResMgr = ImplGetResMgr();
3123         pSVData->maCtrlData.mpRadioImgList = new ImageList();
3124         if( pResMgr )
3125 	    LoadThemedImageList( rStyleSettings,
3126 				 pSVData->maCtrlData.mpRadioImgList,
3127 				 ResId( SV_RESID_BITMAP_RADIO+nStyle, *pResMgr ), 6 );
3128 	pSVData->maCtrlData.mnRadioStyle = nStyle;
3129     }
3130 
3131     sal_uInt16 nId;
3132     if ( nFlags & BUTTON_DRAW_DISABLED )
3133     {
3134         if ( nFlags & BUTTON_DRAW_CHECKED )
3135             nId = 6;
3136         else
3137             nId = 5;
3138     }
3139     else if ( nFlags & BUTTON_DRAW_PRESSED )
3140     {
3141         if ( nFlags & BUTTON_DRAW_CHECKED )
3142             nId = 4;
3143         else
3144             nId = 3;
3145     }
3146     else
3147     {
3148         if ( nFlags & BUTTON_DRAW_CHECKED )
3149             nId = 2;
3150         else
3151             nId = 1;
3152     }
3153     return pSVData->maCtrlData.mpRadioImgList->GetImage( nId );
3154 }
3155 
3156 // -----------------------------------------------------------------------
3157 
ImplSetMinimumNWFSize()3158 void RadioButton::ImplSetMinimumNWFSize()
3159 {
3160     Push( PUSH_MAPMODE );
3161     SetMapMode( MAP_PIXEL );
3162 
3163     ImplControlValue aControlValue;
3164     Size aCurSize( GetSizePixel() );
3165     Rectangle aCtrlRegion( Point( 0, 0 ), aCurSize );
3166     Rectangle aBoundingRgn, aContentRgn;
3167 
3168     // get native size of a radiobutton
3169     if( GetNativeControlRegion( CTRL_RADIOBUTTON, PART_ENTIRE_CONTROL, aCtrlRegion,
3170                                 CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED, aControlValue, rtl::OUString(),
3171                                 aBoundingRgn, aContentRgn ) )
3172     {
3173         Size aSize = aContentRgn.GetSize();
3174 
3175         if( aSize.Height() > aCurSize.Height() )
3176         {
3177             aCurSize.Height() = aSize.Height();
3178             SetSizePixel( aCurSize );
3179         }
3180     }
3181 
3182     Pop();
3183 }
3184 
3185 // -----------------------------------------------------------------------
3186 
CalcMinimumSize(long nMaxWidth) const3187 Size RadioButton::CalcMinimumSize( long nMaxWidth ) const
3188 {
3189     Size aSize;
3190     if ( !maImage )
3191         aSize = ImplGetRadioImageSize();
3192     else
3193         aSize = maImage.GetSizePixel();
3194 
3195     nMaxWidth -= aSize.Width();
3196 
3197     XubString aText = GetText();
3198     if ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
3199     {
3200         // subtract what will be added later
3201         nMaxWidth-=2;
3202         nMaxWidth -= ImplGetImageToTextDistance();
3203 
3204         Size aTextSize = GetTextRect( Rectangle( Point(), Size( nMaxWidth > 0 ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ),
3205                                       aText, FixedText::ImplGetTextStyle( GetStyle() ) ).GetSize();
3206         aSize.Width()+=2;   // for focus rect
3207         aSize.Width() += ImplGetImageToTextDistance();
3208         aSize.Width() += aTextSize.Width();
3209         if ( aSize.Height() < aTextSize.Height() )
3210             aSize.Height() = aTextSize.Height();
3211     }
3212     else if ( !maImage )
3213     {
3214 /* da ansonsten im Writer die Control zu weit oben haengen
3215         aSize.Width() += 2;
3216         aSize.Height() += 2;
3217 */
3218     }
3219 
3220     return CalcWindowSize( aSize );
3221 }
3222 
3223 // -----------------------------------------------------------------------
3224 
GetOptimalSize(WindowSizeType eType) const3225 Size RadioButton::GetOptimalSize(WindowSizeType eType) const
3226 {
3227     switch (eType) {
3228     case WINDOWSIZE_MINIMUM:
3229         return CalcMinimumSize();
3230     default:
3231         return Button::GetOptimalSize( eType );
3232     }
3233 }
3234 
3235 // =======================================================================
3236 
ImplInitCheckBoxData()3237 void CheckBox::ImplInitCheckBoxData()
3238 {
3239     meState         = STATE_NOCHECK;
3240     meSaveValue     = STATE_NOCHECK;
3241     mbTriState      = sal_False;
3242 }
3243 
3244 // -----------------------------------------------------------------------
3245 
ImplInit(Window * pParent,WinBits nStyle)3246 void CheckBox::ImplInit( Window* pParent, WinBits nStyle )
3247 {
3248     nStyle = ImplInitStyle( pParent->GetWindow( WINDOW_LASTCHILD ), nStyle );
3249     Button::ImplInit( pParent, nStyle, NULL );
3250 
3251     ImplInitSettings( sal_True, sal_True, sal_True );
3252 }
3253 
3254 // -----------------------------------------------------------------------
3255 
ImplInitStyle(const Window * pPrevWindow,WinBits nStyle)3256 WinBits CheckBox::ImplInitStyle( const Window* pPrevWindow, WinBits nStyle )
3257 {
3258     if ( !(nStyle & WB_NOTABSTOP) )
3259         nStyle |= WB_TABSTOP;
3260     if ( !(nStyle & WB_NOGROUP) &&
3261          (!pPrevWindow || (pPrevWindow->GetType() != WINDOW_CHECKBOX)) )
3262         nStyle |= WB_GROUP;
3263     return nStyle;
3264 }
3265 
3266 // -----------------------------------------------------------------
3267 
GetCanonicalFont(const StyleSettings & _rStyle) const3268 const Font& CheckBox::GetCanonicalFont( const StyleSettings& _rStyle ) const
3269 {
3270     return _rStyle.GetRadioCheckFont();
3271 }
3272 
3273 // -----------------------------------------------------------------
GetCanonicalTextColor(const StyleSettings & _rStyle) const3274 const Color& CheckBox::GetCanonicalTextColor( const StyleSettings& _rStyle ) const
3275 {
3276     return _rStyle.GetRadioCheckTextColor();
3277 }
3278 
3279 // -----------------------------------------------------------------------
3280 
ImplInitSettings(sal_Bool bFont,sal_Bool bForeground,sal_Bool bBackground)3281 void CheckBox::ImplInitSettings( sal_Bool bFont,
3282                                  sal_Bool bForeground, sal_Bool bBackground )
3283 {
3284     Button::ImplInitSettings( bFont, bForeground );
3285 
3286     if ( bBackground )
3287     {
3288         Window* pParent = GetParent();
3289         if ( !IsControlBackground() &&
3290             (pParent->IsChildTransparentModeEnabled() || IsNativeControlSupported( CTRL_CHECKBOX, PART_ENTIRE_CONTROL ) ) )
3291         {
3292             EnableChildTransparentMode( sal_True );
3293             SetParentClipMode( PARENTCLIPMODE_NOCLIP );
3294             SetPaintTransparent( sal_True );
3295             SetBackground();
3296             if( IsNativeControlSupported( CTRL_CHECKBOX, PART_ENTIRE_CONTROL ) )
3297                 ImplGetWindowImpl()->mbUseNativeFocus = ImplGetSVData()->maNWFData.mbNoFocusRects;
3298         }
3299         else
3300         {
3301             EnableChildTransparentMode( sal_False );
3302             SetParentClipMode( 0 );
3303             SetPaintTransparent( sal_False );
3304 
3305             if ( IsControlBackground() )
3306                 SetBackground( GetControlBackground() );
3307             else
3308                 SetBackground( pParent->GetBackground() );
3309         }
3310     }
3311 }
3312 
3313 // -----------------------------------------------------------------------
3314 
ImplLoadRes(const ResId & rResId)3315 void CheckBox::ImplLoadRes( const ResId& rResId )
3316 {
3317     Button::ImplLoadRes( rResId );
3318 
3319     if ( rResId.GetRT() != RSC_TRISTATEBOX )
3320     {
3321         sal_uInt16 nChecked = ReadShortRes();
3322         //anderer Wert als Default ?
3323         if( nChecked )
3324             Check( sal_True );
3325     }
3326 }
3327 
3328 // -----------------------------------------------------------------------
3329 
ImplInvalidateOrDrawCheckBoxState()3330 void CheckBox::ImplInvalidateOrDrawCheckBoxState()
3331 {
3332     if( ImplGetSVData()->maNWFData.mbCheckBoxNeedsErase )
3333     {
3334         if ( IsNativeControlSupported(CTRL_CHECKBOX, PART_ENTIRE_CONTROL) )
3335         {
3336             Invalidate();
3337             Update();
3338             return;
3339         }
3340     }
3341     ImplDrawCheckBoxState();
3342 }
3343 
ImplDrawCheckBoxState()3344 void CheckBox::ImplDrawCheckBoxState()
3345 {
3346     bool	bNativeOK = sal_True;
3347 
3348     if ( (bNativeOK=IsNativeControlSupported(CTRL_CHECKBOX, PART_ENTIRE_CONTROL)) == sal_True )
3349     {
3350         ImplControlValue    aControlValue( meState == STATE_CHECK ? BUTTONVALUE_ON : BUTTONVALUE_OFF );
3351         Rectangle           aCtrlRegion( maStateRect );
3352         ControlState        nState = 0;
3353 
3354         if ( HasFocus() ) 						nState |= CTRL_STATE_FOCUSED;
3355         if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT )	nState |= CTRL_STATE_DEFAULT;
3356         if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )	nState |= CTRL_STATE_PRESSED;
3357         if ( IsEnabled() )						nState |= CTRL_STATE_ENABLED;
3358 
3359         if ( meState == STATE_CHECK )
3360             aControlValue.setTristateVal( BUTTONVALUE_ON );
3361         else if ( meState == STATE_DONTKNOW )
3362             aControlValue.setTristateVal( BUTTONVALUE_MIXED );
3363 
3364         if ( IsMouseOver() && maMouseRect.IsInside( GetPointerPosPixel() ) )
3365             nState |= CTRL_STATE_ROLLOVER;
3366 
3367         bNativeOK = DrawNativeControl( CTRL_CHECKBOX, PART_ENTIRE_CONTROL, aCtrlRegion, nState,
3368 	     						aControlValue, rtl::OUString() );
3369     }
3370 
3371     if ( bNativeOK == sal_False )
3372     {
3373         sal_uInt16 nStyle = ImplGetButtonState();
3374         if ( !IsEnabled() )
3375             nStyle |= BUTTON_DRAW_DISABLED;
3376         if ( meState == STATE_DONTKNOW )
3377             nStyle |= BUTTON_DRAW_DONTKNOW;
3378         else if ( meState == STATE_CHECK )
3379             nStyle |= BUTTON_DRAW_CHECKED;
3380         Image aImage = GetCheckImage( GetSettings(), nStyle );
3381         if ( IsZoom() )
3382             DrawImage( maStateRect.TopLeft(), maStateRect.GetSize(), aImage );
3383         else
3384             DrawImage( maStateRect.TopLeft(), aImage );
3385     }
3386 }
3387 
3388 // -----------------------------------------------------------------------
3389 
ImplDraw(OutputDevice * pDev,sal_uLong nDrawFlags,const Point & rPos,const Size & rSize,const Size & rImageSize,Rectangle & rStateRect,Rectangle & rMouseRect,bool bLayout)3390 void CheckBox::ImplDraw( OutputDevice* pDev, sal_uLong nDrawFlags,
3391                          const Point& rPos, const Size& rSize,
3392                          const Size& rImageSize, Rectangle& rStateRect,
3393                          Rectangle& rMouseRect, bool bLayout )
3394 {
3395     WinBits                 nWinStyle = GetStyle();
3396     XubString               aText( GetText() );
3397 
3398     pDev->Push( PUSH_CLIPREGION | PUSH_LINECOLOR );
3399     pDev->IntersectClipRegion( Rectangle( rPos, rSize ) );
3400 
3401     long nLineY = rPos.Y() + (rSize.Height()-1)/2;
3402     if ( ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) ) ||
3403          ( HasImage() && !  (ImplGetButtonState() & BUTTON_DRAW_NOIMAGE) ) )
3404     {
3405         sal_uInt16 nTextStyle = Button::ImplGetTextStyle( aText, nWinStyle, nDrawFlags );
3406 
3407         const long nImageSep = GetDrawPixel( pDev, ImplGetImageToTextDistance() );
3408         Size aSize( rSize );
3409         Point aPos( rPos );
3410         aPos.X() += rImageSize.Width() + nImageSep;
3411         aSize.Width() -= rImageSize.Width() + nImageSep;
3412 
3413         // if the text rect height is smaller than the height of the image
3414         // then for single lines the default should be centered text
3415         if( (nWinStyle & (WB_TOP|WB_VCENTER|WB_BOTTOM)) == 0 &&
3416             (rImageSize.Height() > rSize.Height() || ! (nWinStyle & WB_WORDBREAK) ) )
3417         {
3418             nTextStyle &= ~(TEXT_DRAW_TOP|TEXT_DRAW_BOTTOM);
3419             nTextStyle |= TEXT_DRAW_VCENTER;
3420             aSize.Height() = rImageSize.Height();
3421         }
3422 
3423         ImplDrawAlignedImage( pDev, aPos, aSize, bLayout, 1,
3424                               nDrawFlags, nTextStyle, NULL );
3425         nLineY = aPos.Y() + aSize.Height()/2;
3426 
3427         rMouseRect          = Rectangle( aPos, aSize );
3428         rMouseRect.Left()   = rPos.X();
3429         rStateRect.Left()   = rPos.X();
3430         rStateRect.Top()    = rMouseRect.Top();
3431 
3432         if ( aSize.Height() > rImageSize.Height() )
3433             rStateRect.Top() += ( aSize.Height() - rImageSize.Height() ) / 2;
3434         else
3435         {
3436             rStateRect.Top() -= ( rImageSize.Height() - aSize.Height() ) / 2;
3437             if( rStateRect.Top() < 0 )
3438                 rStateRect.Top() = 0;
3439         }
3440 
3441         rStateRect.Right()  = rStateRect.Left()+rImageSize.Width()-1;
3442         rStateRect.Bottom() = rStateRect.Top()+rImageSize.Height()-1;
3443         if ( rStateRect.Bottom() > rMouseRect.Bottom() )
3444             rMouseRect.Bottom() = rStateRect.Bottom();
3445     }
3446     else
3447     {
3448         if ( nWinStyle & WB_CENTER )
3449             rStateRect.Left() = rPos.X()+((rSize.Width()-rImageSize.Width())/2);
3450         else if ( nWinStyle & WB_RIGHT )
3451             rStateRect.Left() = rPos.X()+rSize.Width()-rImageSize.Width();
3452         else
3453             rStateRect.Left() = rPos.X();
3454         if ( nWinStyle & WB_VCENTER )
3455             rStateRect.Top() = rPos.Y()+((rSize.Height()-rImageSize.Height())/2);
3456         else if ( nWinStyle & WB_BOTTOM )
3457             rStateRect.Top() = rPos.Y()+rSize.Height()-rImageSize.Height();
3458         else
3459             rStateRect.Top() = rPos.Y();
3460         rStateRect.Right()  = rStateRect.Left()+rImageSize.Width()-1;
3461         rStateRect.Bottom() = rStateRect.Top()+rImageSize.Height()-1;
3462         // provide space for focusrect
3463         // note: this assumes that the control's size was adjusted
3464         // accordingly in Get/LoseFocus, so the onscreen position won't change
3465         if( HasFocus() )
3466             rStateRect.Move( 1, 1 );
3467         rMouseRect          = rStateRect;
3468 
3469         ImplSetFocusRect( rStateRect );
3470     }
3471 
3472     const int nLineSpace = 4;
3473     if( (GetStyle() & WB_CBLINESTYLE) != 0 &&
3474         rMouseRect.Right()-1-nLineSpace < rPos.X()+rSize.Width() )
3475     {
3476         const StyleSettings&	rStyleSettings = GetSettings().GetStyleSettings();
3477         if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO )
3478             SetLineColor( Color( COL_BLACK ) );
3479         else
3480             SetLineColor( rStyleSettings.GetShadowColor() );
3481         long nLineX = rMouseRect.Right()+nLineSpace;
3482         DrawLine( Point( nLineX, nLineY ), Point( rPos.X() + rSize.Width()-1, nLineY ) );
3483         if ( !(rStyleSettings.GetOptions() & STYLE_OPTION_MONO) )
3484         {
3485             SetLineColor( rStyleSettings.GetLightColor() );
3486             DrawLine( Point( nLineX, nLineY+1 ), Point( rPos.X() + rSize.Width()-1, nLineY+1 ) );
3487         }
3488     }
3489 
3490     pDev->Pop();
3491 }
3492 
3493 // -----------------------------------------------------------------------
3494 
ImplDrawCheckBox(bool bLayout)3495 void CheckBox::ImplDrawCheckBox( bool bLayout )
3496 {
3497     Size aImageSize = ImplGetCheckImageSize();
3498     aImageSize.Width()  = CalcZoom( aImageSize.Width() );
3499     aImageSize.Height() = CalcZoom( aImageSize.Height() );
3500 
3501     if( !bLayout )
3502         HideFocus();
3503 
3504     ImplDraw( this, 0, Point(), GetOutputSizePixel(), aImageSize,
3505               maStateRect, maMouseRect, bLayout );
3506 
3507     if( !bLayout )
3508     {
3509         ImplDrawCheckBoxState();
3510         if ( HasFocus() )
3511             ShowFocus( ImplGetFocusRect() );
3512     }
3513 }
3514 
3515 // -----------------------------------------------------------------------
3516 
ImplCheck()3517 void CheckBox::ImplCheck()
3518 {
3519     TriState eNewState;
3520     if ( meState == STATE_NOCHECK )
3521         eNewState = STATE_CHECK;
3522     else if ( !mbTriState )
3523         eNewState = STATE_NOCHECK;
3524     else if ( meState == STATE_CHECK )
3525         eNewState = STATE_DONTKNOW;
3526     else
3527         eNewState = STATE_NOCHECK;
3528     meState = eNewState;
3529 
3530     ImplDelData aDelData;
3531     ImplAddDel( &aDelData );
3532     if( (GetStyle() & WB_EARLYTOGGLE) )
3533         Toggle();
3534     ImplInvalidateOrDrawCheckBoxState();
3535     if( ! (GetStyle() & WB_EARLYTOGGLE) )
3536         Toggle();
3537     if ( aDelData.IsDelete() )
3538         return;
3539     ImplRemoveDel( &aDelData );
3540     Click();
3541 }
3542 
3543 // -----------------------------------------------------------------------
3544 
CheckBox(Window * pParent,WinBits nStyle)3545 CheckBox::CheckBox( Window* pParent, WinBits nStyle ) :
3546     Button( WINDOW_CHECKBOX )
3547 {
3548     ImplInitCheckBoxData();
3549     ImplInit( pParent, nStyle );
3550 }
3551 
3552 // -----------------------------------------------------------------------
3553 
CheckBox(Window * pParent,const ResId & rResId)3554 CheckBox::CheckBox( Window* pParent, const ResId& rResId ) :
3555     Button( WINDOW_CHECKBOX )
3556 {
3557     ImplInitCheckBoxData();
3558     rResId.SetRT( RSC_CHECKBOX );
3559     WinBits nStyle = ImplInitRes( rResId );
3560     ImplInit( pParent, nStyle );
3561     ImplLoadRes( rResId );
3562 
3563     if ( !(nStyle & WB_HIDE) )
3564         Show();
3565 }
3566 
3567 // -----------------------------------------------------------------------
3568 
MouseButtonDown(const MouseEvent & rMEvt)3569 void CheckBox::MouseButtonDown( const MouseEvent& rMEvt )
3570 {
3571     if ( rMEvt.IsLeft() && maMouseRect.IsInside( rMEvt.GetPosPixel() ) )
3572     {
3573         ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
3574         ImplInvalidateOrDrawCheckBoxState();
3575         StartTracking();
3576         return;
3577     }
3578 
3579     Button::MouseButtonDown( rMEvt );
3580 }
3581 
3582 // -----------------------------------------------------------------------
3583 
Tracking(const TrackingEvent & rTEvt)3584 void CheckBox::Tracking( const TrackingEvent& rTEvt )
3585 {
3586     if ( rTEvt.IsTrackingEnded() )
3587     {
3588         if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
3589         {
3590             if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() )
3591                 GrabFocus();
3592 
3593             ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
3594 
3595             // Bei Abbruch kein Click-Handler rufen
3596             if ( !rTEvt.IsTrackingCanceled() )
3597                 ImplCheck();
3598             else
3599                 ImplInvalidateOrDrawCheckBoxState();
3600         }
3601     }
3602     else
3603     {
3604         if ( maMouseRect.IsInside( rTEvt.GetMouseEvent().GetPosPixel() ) )
3605         {
3606             if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) )
3607             {
3608                 ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
3609                 ImplInvalidateOrDrawCheckBoxState();
3610             }
3611         }
3612         else
3613         {
3614             if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
3615             {
3616                 ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
3617                 ImplInvalidateOrDrawCheckBoxState();
3618             }
3619         }
3620     }
3621 }
3622 
3623 // -----------------------------------------------------------------------
3624 
KeyInput(const KeyEvent & rKEvt)3625 void CheckBox::KeyInput( const KeyEvent& rKEvt )
3626 {
3627     KeyCode aKeyCode = rKEvt.GetKeyCode();
3628 
3629     if ( !aKeyCode.GetModifier() && (aKeyCode.GetCode() == KEY_SPACE) )
3630     {
3631         if ( !(ImplGetButtonState() & BUTTON_DRAW_PRESSED) )
3632         {
3633             ImplGetButtonState() |= BUTTON_DRAW_PRESSED;
3634             ImplInvalidateOrDrawCheckBoxState();
3635         }
3636     }
3637     else if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_ESCAPE) )
3638     {
3639         ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
3640         ImplInvalidateOrDrawCheckBoxState();
3641     }
3642     else
3643         Button::KeyInput( rKEvt );
3644 }
3645 
3646 // -----------------------------------------------------------------------
3647 
KeyUp(const KeyEvent & rKEvt)3648 void CheckBox::KeyUp( const KeyEvent& rKEvt )
3649 {
3650     KeyCode aKeyCode = rKEvt.GetKeyCode();
3651 
3652     if ( (ImplGetButtonState() & BUTTON_DRAW_PRESSED) && (aKeyCode.GetCode() == KEY_SPACE) )
3653     {
3654         ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
3655         ImplCheck();
3656     }
3657     else
3658         Button::KeyUp( rKEvt );
3659 }
3660 
3661 // -----------------------------------------------------------------------
3662 
FillLayoutData() const3663 void CheckBox::FillLayoutData() const
3664 {
3665     mpControlData->mpLayoutData = new vcl::ControlLayoutData();
3666     const_cast<CheckBox*>(this)->ImplDrawCheckBox( true );
3667 }
3668 
3669 // -----------------------------------------------------------------------
3670 
Paint(const Rectangle &)3671 void CheckBox::Paint( const Rectangle& )
3672 {
3673     ImplDrawCheckBox();
3674 }
3675 
3676 // -----------------------------------------------------------------------
3677 
Draw(OutputDevice * pDev,const Point & rPos,const Size & rSize,sal_uLong nFlags)3678 void CheckBox::Draw( OutputDevice* pDev, const Point& rPos, const Size& rSize,
3679                      sal_uLong nFlags )
3680 {
3681     MapMode     aResMapMode( MAP_100TH_MM );
3682     Point       aPos  = pDev->LogicToPixel( rPos );
3683     Size        aSize = pDev->LogicToPixel( rSize );
3684     Size        aImageSize = pDev->LogicToPixel( Size( 300, 300 ), aResMapMode );
3685     Size        aBrd1Size = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode );
3686     Size        aBrd2Size = pDev->LogicToPixel( Size( 30, 30 ), aResMapMode );
3687     long        nCheckWidth = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode ).Width();
3688     Font        aFont = GetDrawPixelFont( pDev );
3689     Rectangle   aStateRect;
3690     Rectangle   aMouseRect;
3691 
3692     aImageSize.Width()  = CalcZoom( aImageSize.Width() );
3693     aImageSize.Height() = CalcZoom( aImageSize.Height() );
3694     aBrd1Size.Width()   = CalcZoom( aBrd1Size.Width() );
3695     aBrd1Size.Height()  = CalcZoom( aBrd1Size.Height() );
3696     aBrd2Size.Width()   = CalcZoom( aBrd2Size.Width() );
3697     aBrd2Size.Height()  = CalcZoom( aBrd2Size.Height() );
3698 
3699     if ( !aBrd1Size.Width() )
3700         aBrd1Size.Width() = 1;
3701     if ( !aBrd1Size.Height() )
3702         aBrd1Size.Height() = 1;
3703     if ( !aBrd2Size.Width() )
3704         aBrd2Size.Width() = 1;
3705     if ( !aBrd2Size.Height() )
3706         aBrd2Size.Height() = 1;
3707     if ( !nCheckWidth )
3708         nCheckWidth = 1;
3709 
3710     pDev->Push();
3711     pDev->SetMapMode();
3712     pDev->SetFont( aFont );
3713     if ( nFlags & WINDOW_DRAW_MONO )
3714         pDev->SetTextColor( Color( COL_BLACK ) );
3715     else
3716         pDev->SetTextColor( GetTextColor() );
3717     pDev->SetTextFillColor();
3718 
3719     ImplDraw( pDev, nFlags, aPos, aSize,
3720               aImageSize, aStateRect, aMouseRect, false );
3721 
3722     pDev->SetLineColor();
3723     pDev->SetFillColor( Color( COL_BLACK ) );
3724     pDev->DrawRect( aStateRect );
3725     aStateRect.Left()   += aBrd1Size.Width();
3726     aStateRect.Top()    += aBrd1Size.Height();
3727     aStateRect.Right()  -= aBrd1Size.Width();
3728     aStateRect.Bottom() -= aBrd1Size.Height();
3729     if ( meState == STATE_DONTKNOW )
3730         pDev->SetFillColor( Color( COL_LIGHTGRAY ) );
3731     else
3732         pDev->SetFillColor( Color( COL_WHITE ) );
3733     pDev->DrawRect( aStateRect );
3734 
3735     if ( meState == STATE_CHECK )
3736     {
3737         aStateRect.Left()   += aBrd2Size.Width();
3738         aStateRect.Top()    += aBrd2Size.Height();
3739         aStateRect.Right()  -= aBrd2Size.Width();
3740         aStateRect.Bottom() -= aBrd2Size.Height();
3741         Point   aPos11( aStateRect.TopLeft() );
3742         Point   aPos12( aStateRect.BottomRight() );
3743         Point   aPos21( aStateRect.TopRight() );
3744         Point   aPos22( aStateRect.BottomLeft() );
3745         Point   aTempPos11( aPos11 );
3746         Point   aTempPos12( aPos12 );
3747         Point   aTempPos21( aPos21 );
3748         Point   aTempPos22( aPos22 );
3749         pDev->SetLineColor( Color( COL_BLACK ) );
3750         long nDX = 0;
3751         for ( long i = 0; i < nCheckWidth; i++ )
3752         {
3753             if ( !(i % 2) )
3754             {
3755                 aTempPos11.X() = aPos11.X()+nDX;
3756                 aTempPos12.X() = aPos12.X()+nDX;
3757                 aTempPos21.X() = aPos21.X()+nDX;
3758                 aTempPos22.X() = aPos22.X()+nDX;
3759             }
3760             else
3761             {
3762                 nDX++;
3763                 aTempPos11.X() = aPos11.X()-nDX;
3764                 aTempPos12.X() = aPos12.X()-nDX;
3765                 aTempPos21.X() = aPos21.X()-nDX;
3766                 aTempPos22.X() = aPos22.X()-nDX;
3767             }
3768             pDev->DrawLine( aTempPos11, aTempPos12 );
3769             pDev->DrawLine( aTempPos21, aTempPos22 );
3770         }
3771     }
3772 
3773     pDev->Pop();
3774 }
3775 
3776 // -----------------------------------------------------------------------
3777 
Resize()3778 void CheckBox::Resize()
3779 {
3780     Control::Resize();
3781     Invalidate();
3782 }
3783 
3784 // -----------------------------------------------------------------------
3785 
GetFocus()3786 void CheckBox::GetFocus()
3787 {
3788     if ( !GetText().Len() || (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
3789     {
3790         // increase button size to have space for focus rect
3791         // checkboxes without text will draw focusrect around the check
3792         // See CheckBox::ImplDraw()
3793         Point aPos( GetPosPixel() );
3794         Size aSize( GetSizePixel() );
3795         aPos.Move(-1,-1);
3796         aSize.Height() += 2;
3797         aSize.Width() += 2;
3798         SetPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height(), WINDOW_POSSIZE_ALL );
3799         ImplDrawCheckBox();
3800     }
3801     else
3802         ShowFocus( ImplGetFocusRect() );
3803 
3804     SetInputContext( InputContext( GetFont() ) );
3805     Button::GetFocus();
3806 }
3807 
3808 // -----------------------------------------------------------------------
3809 
LoseFocus()3810 void CheckBox::LoseFocus()
3811 {
3812     if ( ImplGetButtonState() & BUTTON_DRAW_PRESSED )
3813     {
3814         ImplGetButtonState() &= ~BUTTON_DRAW_PRESSED;
3815         ImplInvalidateOrDrawCheckBoxState();
3816     }
3817 
3818     HideFocus();
3819     Button::LoseFocus();
3820 
3821     if ( !GetText().Len() || (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
3822     {
3823         // decrease button size again (see GetFocus())
3824         // checkboxes without text will draw focusrect around the check
3825         Point aPos( GetPosPixel() );
3826         Size aSize( GetSizePixel() );
3827         aPos.Move(1,1);
3828         aSize.Height() -= 2;
3829         aSize.Width() -= 2;
3830         SetPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height(), WINDOW_POSSIZE_ALL );
3831         ImplDrawCheckBox();
3832     }
3833 }
3834 
3835 // -----------------------------------------------------------------------
3836 
StateChanged(StateChangedType nType)3837 void CheckBox::StateChanged( StateChangedType nType )
3838 {
3839     Button::StateChanged( nType );
3840 
3841     if ( nType == STATE_CHANGE_STATE )
3842     {
3843         if ( IsReallyVisible() && IsUpdateMode() )
3844             Invalidate( maStateRect );
3845     }
3846     else if ( (nType == STATE_CHANGE_ENABLE) ||
3847               (nType == STATE_CHANGE_TEXT) ||
3848               (nType == STATE_CHANGE_IMAGE) ||
3849               (nType == STATE_CHANGE_DATA) ||
3850               (nType == STATE_CHANGE_UPDATEMODE) )
3851     {
3852         if ( IsUpdateMode() )
3853             Invalidate();
3854     }
3855     else if ( nType == STATE_CHANGE_STYLE )
3856     {
3857         SetStyle( ImplInitStyle( GetWindow( WINDOW_PREV ), GetStyle() ) );
3858 
3859         if ( (GetPrevStyle() & CHECKBOX_VIEW_STYLE) !=
3860              (GetStyle() & CHECKBOX_VIEW_STYLE) )
3861         {
3862             if ( IsUpdateMode() )
3863                 Invalidate();
3864         }
3865     }
3866     else if ( (nType == STATE_CHANGE_ZOOM) ||
3867               (nType == STATE_CHANGE_CONTROLFONT) )
3868     {
3869         ImplInitSettings( sal_True, sal_False, sal_False );
3870         Invalidate();
3871     }
3872     else if ( nType == STATE_CHANGE_CONTROLFOREGROUND )
3873     {
3874         ImplInitSettings( sal_False, sal_True, sal_False );
3875         Invalidate();
3876     }
3877     else if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
3878     {
3879         ImplInitSettings( sal_False, sal_False, sal_True );
3880         Invalidate();
3881     }
3882 }
3883 
3884 // -----------------------------------------------------------------------
3885 
DataChanged(const DataChangedEvent & rDCEvt)3886 void CheckBox::DataChanged( const DataChangedEvent& rDCEvt )
3887 {
3888     Button::DataChanged( rDCEvt );
3889 
3890     if ( (rDCEvt.GetType() == DATACHANGED_FONTS) ||
3891          (rDCEvt.GetType() == DATACHANGED_FONTSUBSTITUTION) ||
3892          ((rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
3893           (rDCEvt.GetFlags() & SETTINGS_STYLE)) )
3894     {
3895         ImplInitSettings( sal_True, sal_True, sal_True );
3896         Invalidate();
3897     }
3898 }
3899 
3900 // -----------------------------------------------------------------------
3901 
PreNotify(NotifyEvent & rNEvt)3902 long CheckBox::PreNotify( NotifyEvent& rNEvt )
3903 {
3904     long nDone = 0;
3905     const MouseEvent* pMouseEvt = NULL;
3906 
3907     if( (rNEvt.GetType() == EVENT_MOUSEMOVE) && (pMouseEvt = rNEvt.GetMouseEvent()) != NULL )
3908     {
3909         if( !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() )
3910         {
3911             // trigger redraw if mouse over state has changed
3912             if( IsNativeControlSupported(CTRL_CHECKBOX, PART_ENTIRE_CONTROL) )
3913             {
3914                 if( ( maMouseRect.IsInside( GetPointerPosPixel()) &&
3915                      !maMouseRect.IsInside( GetLastPointerPosPixel()) ) ||
3916                     ( maMouseRect.IsInside( GetLastPointerPosPixel()) &&
3917                      !maMouseRect.IsInside( GetPointerPosPixel()) ) ||
3918                     pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow() )
3919                 {
3920                     Invalidate( maStateRect );
3921                 }
3922             }
3923         }
3924     }
3925 
3926     return nDone ? nDone : Button::PreNotify(rNEvt);
3927 }
3928 
3929 // -----------------------------------------------------------------------
3930 
Toggle()3931 void CheckBox::Toggle()
3932 {
3933     ImplCallEventListenersAndHandler( VCLEVENT_CHECKBOX_TOGGLE, maToggleHdl, this );
3934 }
3935 
3936 // -----------------------------------------------------------------------
3937 
SetState(TriState eState)3938 void CheckBox::SetState( TriState eState )
3939 {
3940     if ( !mbTriState && (eState == STATE_DONTKNOW) )
3941         eState = STATE_NOCHECK;
3942 
3943     if ( meState != eState )
3944     {
3945         meState = eState;
3946         StateChanged( STATE_CHANGE_STATE );
3947         Toggle();
3948     }
3949 }
3950 
3951 // -----------------------------------------------------------------------
3952 
EnableTriState(sal_Bool bTriState)3953 void CheckBox::EnableTriState( sal_Bool bTriState )
3954 {
3955     if ( mbTriState != bTriState )
3956     {
3957         mbTriState = bTriState;
3958 
3959         if ( !bTriState && (meState == STATE_DONTKNOW) )
3960             SetState( STATE_NOCHECK );
3961     }
3962 }
3963 
3964 // -----------------------------------------------------------------------
3965 
ImplGetImageToTextDistance() const3966 long CheckBox::ImplGetImageToTextDistance() const
3967 {
3968     // 4 pixels, but take zoom into account, so the text doesn't "jump" relative to surrounding elements,
3969     // which might have been aligned with the text of the check box
3970     return CalcZoom( 4 );
3971 }
3972 
3973 // -----------------------------------------------------------------------
3974 
ImplGetCheckImageSize() const3975 Size CheckBox::ImplGetCheckImageSize() const
3976 {
3977     Size aSize;
3978     // why are IsNativeControlSupported and GetNativeControlRegion not const ?
3979     CheckBox* pThis = const_cast<CheckBox*>(this);
3980     bool bDefaultSize = true;
3981     if( pThis->IsNativeControlSupported( CTRL_CHECKBOX, PART_ENTIRE_CONTROL ) )
3982     {
3983         ImplControlValue aControlValue;
3984         // #i45896# workaround gcc3.3 temporary problem
3985         Rectangle		 aCtrlRegion( Point( 0, 0 ), GetSizePixel() );
3986         ControlState	 nState = CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED;
3987         Rectangle aBoundingRgn, aContentRgn;
3988 
3989         // get native size of a check box
3990         if( pThis->GetNativeControlRegion( CTRL_CHECKBOX, PART_ENTIRE_CONTROL, aCtrlRegion,
3991                                            nState, aControlValue, rtl::OUString(),
3992                                            aBoundingRgn, aContentRgn ) )
3993         {
3994             aSize = aContentRgn.GetSize();
3995             bDefaultSize = false;
3996         }
3997     }
3998     if( bDefaultSize )
3999         aSize = GetCheckImage( GetSettings(), 0 ).GetSizePixel();
4000     return aSize;
4001 }
4002 
GetCheckImage(const AllSettings & rSettings,sal_uInt16 nFlags)4003 Image CheckBox::GetCheckImage( const AllSettings& rSettings, sal_uInt16 nFlags )
4004 {
4005     ImplSVData*             pSVData = ImplGetSVData();
4006     const StyleSettings&    rStyleSettings = rSettings.GetStyleSettings();
4007     sal_uInt16              nStyle = 0;
4008 
4009     if ( rStyleSettings.GetOptions() & STYLE_OPTION_MONO )
4010         nStyle = STYLE_CHECKBOX_MONO;
4011 
4012     if ( !pSVData->maCtrlData.mpCheckImgList ||
4013          (pSVData->maCtrlData.mnCheckStyle != nStyle) ||
4014          (pSVData->maCtrlData.mnLastCheckFColor != rStyleSettings.GetFaceColor().GetColor()) ||
4015          (pSVData->maCtrlData.mnLastCheckWColor != rStyleSettings.GetWindowColor().GetColor()) ||
4016          (pSVData->maCtrlData.mnLastCheckLColor != rStyleSettings.GetLightColor().GetColor()) )
4017     {
4018         if ( pSVData->maCtrlData.mpCheckImgList )
4019             delete pSVData->maCtrlData.mpCheckImgList;
4020 
4021         pSVData->maCtrlData.mnLastCheckFColor = rStyleSettings.GetFaceColor().GetColor();
4022         pSVData->maCtrlData.mnLastCheckWColor = rStyleSettings.GetWindowColor().GetColor();
4023         pSVData->maCtrlData.mnLastCheckLColor = rStyleSettings.GetLightColor().GetColor();
4024 
4025         ResMgr* pResMgr = ImplGetResMgr();
4026         pSVData->maCtrlData.mpCheckImgList = new ImageList();
4027         if( pResMgr )
4028 	    LoadThemedImageList( rStyleSettings,
4029 				 pSVData->maCtrlData.mpCheckImgList,
4030 				 ResId( SV_RESID_BITMAP_CHECK+nStyle, *pResMgr ), 9 );
4031         pSVData->maCtrlData.mnCheckStyle = nStyle;
4032     }
4033 
4034     sal_uInt16 nId;
4035     if ( nFlags & BUTTON_DRAW_DISABLED )
4036     {
4037         if ( nFlags & BUTTON_DRAW_DONTKNOW )
4038             nId = 9;
4039         else if ( nFlags & BUTTON_DRAW_CHECKED )
4040             nId = 6;
4041         else
4042             nId = 5;
4043     }
4044     else if ( nFlags & BUTTON_DRAW_PRESSED )
4045     {
4046         if ( nFlags & BUTTON_DRAW_DONTKNOW )
4047             nId = 8;
4048         else if ( nFlags & BUTTON_DRAW_CHECKED )
4049             nId = 4;
4050         else
4051             nId = 3;
4052     }
4053     else
4054     {
4055         if ( nFlags & BUTTON_DRAW_DONTKNOW )
4056             nId = 7;
4057         else if ( nFlags & BUTTON_DRAW_CHECKED )
4058             nId = 2;
4059         else
4060             nId = 1;
4061     }
4062     return pSVData->maCtrlData.mpCheckImgList->GetImage( nId );
4063 }
4064 
4065 // -----------------------------------------------------------------------
4066 
ImplSetMinimumNWFSize()4067 void CheckBox::ImplSetMinimumNWFSize()
4068 {
4069     Push( PUSH_MAPMODE );
4070     SetMapMode( MAP_PIXEL );
4071 
4072     ImplControlValue aControlValue;
4073     Size aCurSize( GetSizePixel() );
4074     Rectangle aCtrlRegion( Point( 0, 0 ), aCurSize );
4075     Rectangle aBoundingRgn, aContentRgn;
4076 
4077     // get native size of a radiobutton
4078     if( GetNativeControlRegion( CTRL_CHECKBOX, PART_ENTIRE_CONTROL, aCtrlRegion,
4079                                 CTRL_STATE_DEFAULT|CTRL_STATE_ENABLED, aControlValue, rtl::OUString(),
4080                                 aBoundingRgn, aContentRgn ) )
4081     {
4082         Size aSize = aContentRgn.GetSize();
4083 
4084         if( aSize.Height() > aCurSize.Height() )
4085         {
4086             aCurSize.Height() = aSize.Height();
4087             SetSizePixel( aCurSize );
4088         }
4089     }
4090 
4091     Pop();
4092 }
4093 
4094 // -----------------------------------------------------------------------
4095 
CalcMinimumSize(long nMaxWidth) const4096 Size CheckBox::CalcMinimumSize( long nMaxWidth ) const
4097 {
4098     Size aSize = ImplGetCheckImageSize();
4099     nMaxWidth -= aSize.Width();
4100 
4101     XubString aText = GetText();
4102     if ( aText.Len() && ! (ImplGetButtonState() & BUTTON_DRAW_NOTEXT) )
4103     {
4104         // subtract what will be added later
4105         nMaxWidth-=2;
4106         nMaxWidth -= ImplGetImageToTextDistance();
4107 
4108         Size aTextSize = GetTextRect( Rectangle( Point(), Size( nMaxWidth > 0 ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ),
4109                                       aText, FixedText::ImplGetTextStyle( GetStyle() ) ).GetSize();
4110         aSize.Width()+=2;    // for focus rect
4111         aSize.Width() += ImplGetImageToTextDistance();
4112         aSize.Width() += aTextSize.Width();
4113         if ( aSize.Height() < aTextSize.Height() )
4114             aSize.Height() = aTextSize.Height();
4115     }
4116     else
4117     {
4118         // is this still correct ? since the checkbox now
4119         // shows a focus rect it should be 2 pixels wider and longer
4120 /* da ansonsten im Writer die Control zu weit oben haengen
4121         aSize.Width() += 2;
4122         aSize.Height() += 2;
4123 */
4124     }
4125 
4126     return CalcWindowSize( aSize );
4127 }
4128 
4129 // -----------------------------------------------------------------------
4130 
GetOptimalSize(WindowSizeType eType) const4131 Size CheckBox::GetOptimalSize(WindowSizeType eType) const
4132 {
4133     switch (eType) {
4134     case WINDOWSIZE_MINIMUM:
4135         return CalcMinimumSize();
4136     default:
4137         return Button::GetOptimalSize( eType );
4138     }
4139 }
4140 
4141 // =======================================================================
4142 
ImageButton(WindowType nType)4143 ImageButton::ImageButton( WindowType nType ) :
4144     PushButton( nType )
4145 {
4146     ImplInitStyle();
4147 }
4148 
4149 // -----------------------------------------------------------------------
4150 
ImageButton(Window * pParent,WinBits nStyle)4151 ImageButton::ImageButton( Window* pParent, WinBits nStyle ) :
4152     PushButton( pParent, nStyle )
4153 {
4154     ImplInitStyle();
4155 }
4156 
4157 // -----------------------------------------------------------------------
4158 
ImageButton(Window * pParent,const ResId & rResId)4159 ImageButton::ImageButton( Window* pParent, const ResId& rResId ) :
4160     PushButton( pParent, rResId.SetRT( RSC_IMAGEBUTTON ) )
4161 {
4162     sal_uLong nObjMask = ReadLongRes();
4163 
4164     if ( RSC_IMAGEBUTTON_IMAGE & nObjMask )
4165     {
4166         SetModeImage( Image( ResId( (RSHEADER_TYPE*)GetClassRes(), *rResId.GetResMgr() ) ) );
4167         IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
4168     }
4169 
4170     if ( RSC_IMAGEBUTTON_SYMBOL & nObjMask )
4171         SetSymbol( (SymbolType)ReadLongRes() );
4172 
4173     if ( RSC_IMAGEBUTTON_STATE & nObjMask )
4174         SetState( (TriState)ReadLongRes() );
4175 
4176     ImplInitStyle();
4177 }
4178 
4179 // -----------------------------------------------------------------------
4180 
~ImageButton()4181 ImageButton::~ImageButton()
4182 {
4183 }
4184 
4185 // -----------------------------------------------------------------------
ImplInitStyle()4186 void ImageButton::ImplInitStyle()
4187 {
4188     WinBits nStyle = GetStyle();
4189 
4190     if ( ! ( nStyle & ( WB_RIGHT | WB_LEFT ) ) )
4191         nStyle |= WB_CENTER;
4192 
4193     if ( ! ( nStyle & ( WB_TOP | WB_BOTTOM ) ) )
4194         nStyle |= WB_VCENTER;
4195 
4196     SetStyle( nStyle );
4197 }
4198 
4199 // =======================================================================
4200 
ImageRadioButton(Window * pParent,WinBits nStyle)4201 ImageRadioButton::ImageRadioButton( Window* pParent, WinBits nStyle ) :
4202     RadioButton( pParent, nStyle )
4203 {
4204 }
4205 
4206 // -----------------------------------------------------------------------
4207 
ImageRadioButton(Window * pParent,const ResId & rResId)4208 ImageRadioButton::ImageRadioButton( Window* pParent, const ResId& rResId ) :
4209     RadioButton( pParent, rResId.SetRT( RSC_IMAGERADIOBUTTON ) )
4210 {
4211     sal_uLong nObjMask = ReadLongRes();
4212 
4213     if ( RSC_IMAGERADIOBUTTON_IMAGE & nObjMask )
4214     {
4215         SetModeRadioImage( Image( ResId( (RSHEADER_TYPE*)GetClassRes(), *rResId.GetResMgr() ) ) );
4216         IncrementRes( GetObjSizeRes( (RSHEADER_TYPE*)GetClassRes() ) );
4217     }
4218 }
4219 
4220 // -----------------------------------------------------------------------
4221 
~ImageRadioButton()4222 ImageRadioButton::~ImageRadioButton()
4223 {
4224 }
4225 
4226 // =======================================================================
4227 
TriStateBox(Window * pParent,WinBits nStyle)4228 TriStateBox::TriStateBox( Window* pParent, WinBits nStyle ) :
4229     CheckBox( pParent, nStyle )
4230 {
4231     EnableTriState( sal_True );
4232 }
4233 
4234 // -----------------------------------------------------------------------
4235 
TriStateBox(Window * pParent,const ResId & rResId)4236 TriStateBox::TriStateBox( Window* pParent, const ResId& rResId ) :
4237     CheckBox( pParent, rResId.SetRT( RSC_TRISTATEBOX ) )
4238 {
4239     EnableTriState( sal_True );
4240 
4241     sal_uLong  nTriState        = ReadLongRes();
4242     sal_uInt16 bDisableTriState = ReadShortRes();
4243     //anderer Wert als Default ?
4244     if ( (TriState)nTriState != STATE_NOCHECK )
4245         SetState( (TriState)nTriState );
4246     if ( bDisableTriState )
4247         EnableTriState( sal_False );
4248 }
4249 
4250 // -----------------------------------------------------------------------
4251 
~TriStateBox()4252 TriStateBox::~TriStateBox()
4253 {
4254 }
4255 
4256 // =======================================================================
4257 
DisclosureButton(Window * pParent,WinBits)4258 DisclosureButton::DisclosureButton( Window* pParent, WinBits ) :
4259     CheckBox( pParent, WB_NOBORDER )
4260 {
4261 }
4262 
4263 // -----------------------------------------------------------------------
4264 
DisclosureButton(Window * pParent,const ResId & rResId)4265 DisclosureButton::DisclosureButton( Window* pParent, const ResId& rResId ) :
4266     CheckBox( pParent, rResId.SetRT( RSC_CHECKBOX ) )
4267 {
4268 }
4269 
4270 // -----------------------------------------------------------------------
4271 
ImplDrawCheckBoxState()4272 void DisclosureButton::ImplDrawCheckBoxState()
4273 {
4274     /* HACK: DisclosureButton is currently assuming, that the disclosure sign
4275        will fit into the rectangle occupied by a normal checkbox on all themes.
4276        If this does not hold true for some theme, ImplGetCheckImageSize
4277        would have to be overloaded for DisclosureButton; also GetNativeControlRegion
4278        for CTRL_LISTNODE would have to be implemented and taken into account
4279     */
4280 
4281     Rectangle aStateRect( GetStateRect() );
4282 
4283     ImplControlValue    aControlValue( GetState() == STATE_CHECK ? BUTTONVALUE_ON : BUTTONVALUE_OFF );
4284     Rectangle           aCtrlRegion( aStateRect );
4285     ControlState        nState = 0;
4286 
4287     if ( HasFocus() )						nState |= CTRL_STATE_FOCUSED;
4288     if ( ImplGetButtonState() & BUTTON_DRAW_DEFAULT )	nState |= CTRL_STATE_DEFAULT;
4289     if ( Window::IsEnabled() ) 				nState |= CTRL_STATE_ENABLED;
4290     if ( IsMouseOver() && GetMouseRect().IsInside( GetPointerPosPixel() ) )
4291         nState |= CTRL_STATE_ROLLOVER;
4292 
4293     if( ! DrawNativeControl( CTRL_LISTNODE, PART_ENTIRE_CONTROL, aCtrlRegion, nState,
4294                            aControlValue, rtl::OUString() ) )
4295     {
4296         ImplSVCtrlData& rCtrlData( ImplGetSVData()->maCtrlData );
4297         if( ! rCtrlData.mpDisclosurePlus )
4298             rCtrlData.mpDisclosurePlus = new Image( BitmapEx( VclResId( SV_DISCLOSURE_PLUS ) ) );
4299         if( ! rCtrlData.mpDisclosurePlusHC )
4300             rCtrlData.mpDisclosurePlusHC = new Image( BitmapEx( VclResId( SV_DISCLOSURE_PLUS_HC ) ) );
4301         if( ! rCtrlData.mpDisclosureMinus )
4302             rCtrlData.mpDisclosureMinus = new Image( BitmapEx( VclResId( SV_DISCLOSURE_MINUS ) ) );
4303         if( ! rCtrlData.mpDisclosureMinusHC )
4304             rCtrlData.mpDisclosureMinusHC = new Image( BitmapEx( VclResId( SV_DISCLOSURE_MINUS_HC ) ) );
4305 
4306         Image* pImg = NULL;
4307         if( GetSettings().GetStyleSettings().GetHighContrastMode() )
4308             pImg = IsChecked() ? rCtrlData.mpDisclosureMinusHC : rCtrlData.mpDisclosurePlusHC;
4309         else
4310             pImg = IsChecked() ? rCtrlData.mpDisclosureMinus : rCtrlData.mpDisclosurePlus;
4311 
4312         DBG_ASSERT( pImg, "no disclosure image" );
4313         if( ! pImg )
4314             return;
4315 
4316         sal_uInt16 nStyle = 0;
4317         if( ! IsEnabled() )
4318             nStyle |= IMAGE_DRAW_DISABLE;
4319 
4320         Size aSize( aStateRect.GetSize() );
4321         Size aImgSize( pImg->GetSizePixel() );
4322         Point aOff( (aSize.Width() - aImgSize.Width())/2,
4323                     (aSize.Height() - aImgSize.Height())/2 );
4324         aOff += aStateRect.TopLeft();
4325         DrawImage( aOff, *pImg, nStyle );
4326     }
4327 }
4328 
4329 // -----------------------------------------------------------------------
4330 
KeyInput(const KeyEvent & rKEvt)4331 void DisclosureButton::KeyInput( const KeyEvent& rKEvt )
4332 {
4333     KeyCode aKeyCode = rKEvt.GetKeyCode();
4334 
4335     if( !aKeyCode.GetModifier()  &&
4336         ( ( aKeyCode.GetCode() == KEY_ADD ) ||
4337           ( aKeyCode.GetCode() == KEY_SUBTRACT ) )
4338         )
4339     {
4340         Check( aKeyCode.GetCode() == KEY_ADD );
4341     }
4342     else
4343         Button::KeyInput( rKEvt );
4344 }
4345 
4346 
4347