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