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