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