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