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