LibreOffice Module vcl (master)  1
button.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <tools/poly.hxx>
21 
22 #include <vcl/builder.hxx>
23 #include <vcl/image.hxx>
24 #include <vcl/bitmapex.hxx>
25 #include <vcl/decoview.hxx>
26 #include <vcl/event.hxx>
27 #include <vcl/svapp.hxx>
28 #include <vcl/settings.hxx>
29 #include <vcl/toolkit/dialog.hxx>
30 #include <vcl/toolkit/fixed.hxx>
31 #include <vcl/toolkit/button.hxx>
32 #include <vcl/salnativewidgets.hxx>
33 #include <vcl/toolkit/edit.hxx>
34 #include <vcl/layout.hxx>
35 #include <vcl/stdtext.hxx>
36 #include <vcl/uitest/uiobject.hxx>
37 
38 #include <bitmaps.hlst>
39 #include <svdata.hxx>
40 #include <window.h>
41 #include <controldata.hxx>
42 #include <vclstatuslistener.hxx>
43 #include <osl/diagnose.h>
44 
46 #include <comphelper/lok.hxx>
47 #include <officecfg/Office/Common.hxx>
48 #include <boost/property_tree/ptree.hpp>
49 #include <tools/json_writer.hxx>
50 
51 
52 using namespace css;
53 
54 constexpr auto PUSHBUTTON_VIEW_STYLE = WB_3DLOOK |
60  WB_TOGGLE;
65 constexpr auto CHECKBOX_VIEW_STYLE = WB_3DLOOK |
69 
70 #define STYLE_RADIOBUTTON_MONO (sal_uInt16(0x0001)) // legacy
71 #define STYLE_CHECKBOX_MONO (sal_uInt16(0x0001)) // legacy
72 
74 {
75 public:
77 
83 
87 
89 
92 };
93 
94 ImplCommonButtonData::ImplCommonButtonData() : maFocusRect(), mnSeparatorX(0), mnButtonState(DrawButtonFlags::NONE),
95 mbSmallSymbol(false), mbGeneratedTooltip(false), maImage(), meImageAlign(ImageAlign::Top), meSymbolAlign(SymbolAlign::LEFT), maCustomContentImage()
96 {
97 }
98 
100  Control( nType ),
101  mpButtonData( std::make_unique<ImplCommonButtonData>() )
102 {
103 }
104 
106 {
107  disposeOnce();
108 }
109 
111 {
112  if (mpButtonData->mpStatusListener.is())
113  mpButtonData->mpStatusListener->dispose();
115 }
116 
117 void Button::SetCommandHandler(const OUString& aCommand)
118 {
119  maCommand = aCommand;
120  SetClickHdl( LINK( this, Button, dispatchCommandHandler) );
121 
122  mpButtonData->mpStatusListener = new VclStatusListener<Button>(this, aCommand);
123  mpButtonData->mpStatusListener->startListening();
124 }
125 
127 {
129 }
130 
131 void Button::SetModeImage( const Image& rImage )
132 {
133  if ( rImage != mpButtonData->maImage )
134  {
135  mpButtonData->maImage = rImage;
137  queue_resize();
138  }
139 }
140 
141 Image const & Button::GetModeImage( ) const
142 {
143  return mpButtonData->maImage;
144 }
145 
146 bool Button::HasImage() const
147 {
148  return !!(mpButtonData->maImage);
149 }
150 
152 {
153  if ( mpButtonData->meImageAlign != eAlign )
154  {
155  mpButtonData->meImageAlign = eAlign;
157  }
158 }
159 
161 {
162  return mpButtonData->meImageAlign;
163 }
164 
166 {
167  if (rImage != mpButtonData->maCustomContentImage)
168  {
169  mpButtonData->maCustomContentImage = rImage;
171  }
172 }
173 
175 {
176  return mpButtonData->maCustomContentImage;
177 }
178 
180 {
181  return mpButtonData->mnSeparatorX;
182 }
183 
185 {
186  mpButtonData->mnSeparatorX = nX;
187 }
188 
190 {
191  const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
192  DrawTextFlags nTextStyle = FixedText::ImplGetTextStyle(nWinStyle & ~WB_DEFBUTTON);
193 
194  if (!IsEnabled())
195  nTextStyle |= DrawTextFlags::Disable;
196 
197  if ((nDrawFlags & DrawFlags::Mono) ||
198  (rStyleSettings.GetOptions() & StyleSettingsOptions::Mono))
199  {
200  nTextStyle |= DrawTextFlags::Mono;
201  }
202 
203  return nTextStyle;
204 }
205 
207  Size& rSize,
208  sal_Int32 nImageSep,
209  DrawTextFlags nTextStyle, tools::Rectangle *pSymbolRect,
210  bool bAddImageSep)
211 {
212  OUString aText(GetText());
213  bool bDrawImage = HasImage();
214  bool bDrawText = !aText.isEmpty();
215  bool bHasSymbol = pSymbolRect != nullptr;
216 
217  // No text and no image => nothing to do => return
218  if (!bDrawImage && !bDrawText && !bHasSymbol)
219  return;
220 
221  WinBits nWinStyle = GetStyle();
222  tools::Rectangle aOutRect( rPos, rSize );
223  ImageAlign eImageAlign = mpButtonData->meImageAlign;
224  Size aImageSize = mpButtonData->maImage.GetSizePixel();
225 
226  aImageSize.setWidth( CalcZoom( aImageSize.Width() ) );
227  aImageSize.setHeight( CalcZoom( aImageSize.Height() ) );
228 
229  // Drawing text or symbol only is simple, use style and output rectangle
230  if (bHasSymbol && !bDrawImage && !bDrawText)
231  {
232  *pSymbolRect = aOutRect;
233  return;
234  }
235  else if (bDrawText && !bDrawImage && !bHasSymbol)
236  {
237  aOutRect = DrawControlText(*pDev, aOutRect, aText, nTextStyle, nullptr, nullptr);
238  tools::Rectangle textRect = GetTextRect(
239  tools::Rectangle(Point(), Size(0x7fffffff, 0x7fffffff)), aText, nTextStyle);
240  // If the button text doesn't fit into it, put it into a tooltip (might happen in sidebar)
241  if (GetQuickHelpText()!= aText && mpButtonData->mbGeneratedTooltip)
242  SetQuickHelpText("");
243  if (GetQuickHelpText().isEmpty() && textRect.getWidth() > rSize.getWidth())
244  {
245  SetQuickHelpText(aText);
246  mpButtonData->mbGeneratedTooltip = true;
247  }
248 
249  ImplSetFocusRect(aOutRect);
250  rSize = aOutRect.GetSize();
251  rPos = aOutRect.TopLeft();
252 
253  return;
254  }
255 
256  // check for HC mode ( image only! )
257  Image* pImage = &(mpButtonData->maImage);
258 
259  Size aTextSize;
260  Size aSymbolSize;
261  Size aDeviceTextSize;
262  Point aImagePos = rPos;
263  Point aTextPos = rPos;
264  tools::Rectangle aUnion(aImagePos, aImageSize);
265  tools::Long nSymbolHeight = 0;
266 
267  if (bDrawText || bHasSymbol)
268  {
269  // Get the size of the text output area ( the symbol will be drawn in
270  // this area as well, so the symbol rectangle will be calculated here, too )
271 
272  tools::Rectangle aRect(Point(), rSize);
273  Size aTSSize;
274 
275  if (bHasSymbol)
276  {
277  tools::Rectangle aSymbol;
278  if (bDrawText)
279  {
280  nSymbolHeight = pDev->GetTextHeight();
281  if (mpButtonData->mbSmallSymbol)
282  nSymbolHeight = nSymbolHeight * 3 / 4;
283 
284  aSymbol = tools::Rectangle(Point(), Size(nSymbolHeight, nSymbolHeight));
285  ImplCalcSymbolRect(aSymbol);
286  aRect.AdjustLeft(3 * nSymbolHeight / 2 );
287  aTSSize.setWidth( 3 * nSymbolHeight / 2 );
288  }
289  else
290  {
291  aSymbol = tools::Rectangle(Point(), rSize);
292  ImplCalcSymbolRect(aSymbol);
293  aTSSize.setWidth( aSymbol.GetWidth() );
294  }
295  aTSSize.setHeight( aSymbol.GetHeight() );
296  aSymbolSize = aSymbol.GetSize();
297  }
298 
299  if (bDrawText)
300  {
301  if ((eImageAlign == ImageAlign::LeftTop) ||
302  (eImageAlign == ImageAlign::Left ) ||
303  (eImageAlign == ImageAlign::LeftBottom) ||
304  (eImageAlign == ImageAlign::RightTop) ||
305  (eImageAlign == ImageAlign::Right) ||
306  (eImageAlign == ImageAlign::RightBottom))
307  {
308  aRect.AdjustRight( -sal_Int32(aImageSize.Width() + nImageSep) );
309  }
310  else if ((eImageAlign == ImageAlign::TopLeft) ||
311  (eImageAlign == ImageAlign::Top) ||
312  (eImageAlign == ImageAlign::TopRight) ||
313  (eImageAlign == ImageAlign::BottomLeft) ||
314  (eImageAlign == ImageAlign::Bottom) ||
315  (eImageAlign == ImageAlign::BottomRight))
316  {
317  aRect.AdjustBottom( -sal_Int32(aImageSize.Height() + nImageSep) );
318  }
319 
320  aRect = GetControlTextRect(*pDev, aRect, aText, nTextStyle, &aDeviceTextSize);
321  aTextSize = aRect.GetSize();
322 
323  aTSSize.AdjustWidth(aTextSize.Width() );
324 
325  if (aTSSize.Height() < aTextSize.Height())
326  aTSSize.setHeight( aTextSize.Height() );
327 
328  if (bAddImageSep && bDrawImage)
329  {
330  tools::Long nDiff = (aImageSize.Height() - aTextSize.Height()) / 3;
331  if (nDiff > 0)
332  nImageSep += nDiff;
333  }
334  }
335 
336  Size aMax;
337  aMax.setWidth( std::max(aTSSize.Width(), aImageSize.Width()) );
338  aMax.setHeight( std::max(aTSSize.Height(), aImageSize.Height()) );
339 
340  // Now calculate the output area for the image and the text according to the image align flags
341 
342  if ((eImageAlign == ImageAlign::Left) ||
343  (eImageAlign == ImageAlign::Right))
344  {
345  aImagePos.setY( rPos.Y() + (aMax.Height() - aImageSize.Height()) / 2 );
346  aTextPos.setY( rPos.Y() + (aMax.Height() - aTSSize.Height()) / 2 );
347  }
348  else if ((eImageAlign == ImageAlign::LeftBottom) ||
349  (eImageAlign == ImageAlign::RightBottom))
350  {
351  aImagePos.setY( rPos.Y() + aMax.Height() - aImageSize.Height() );
352  aTextPos.setY( rPos.Y() + aMax.Height() - aTSSize.Height() );
353  }
354  else if ((eImageAlign == ImageAlign::Top) ||
355  (eImageAlign == ImageAlign::Bottom))
356  {
357  aImagePos.setX( rPos.X() + (aMax.Width() - aImageSize.Width()) / 2 );
358  aTextPos.setX( rPos.X() + (aMax.Width() - aTSSize.Width()) / 2 );
359  }
360  else if ((eImageAlign == ImageAlign::TopRight) ||
361  (eImageAlign == ImageAlign::BottomRight))
362  {
363  aImagePos.setX( rPos.X() + aMax.Width() - aImageSize.Width() );
364  aTextPos.setX( rPos.X() + aMax.Width() - aTSSize.Width() );
365  }
366 
367  if ((eImageAlign == ImageAlign::LeftTop) ||
368  (eImageAlign == ImageAlign::Left) ||
369  (eImageAlign == ImageAlign::LeftBottom))
370  {
371  aTextPos.setX( rPos.X() + aImageSize.Width() + nImageSep );
372  }
373  else if ((eImageAlign == ImageAlign::RightTop) ||
374  (eImageAlign == ImageAlign::Right) ||
375  (eImageAlign == ImageAlign::RightBottom))
376  {
377  aImagePos.setX( rPos.X() + aTSSize.Width() + nImageSep );
378  }
379  else if ((eImageAlign == ImageAlign::TopLeft) ||
380  (eImageAlign == ImageAlign::Top) ||
381  (eImageAlign == ImageAlign::TopRight))
382  {
383  aTextPos.setY( rPos.Y() + aImageSize.Height() + nImageSep );
384  }
385  else if ((eImageAlign == ImageAlign::BottomLeft) ||
386  (eImageAlign == ImageAlign::Bottom) ||
387  (eImageAlign == ImageAlign::BottomRight))
388  {
389  aImagePos.setY( rPos.Y() + aTSSize.Height() + nImageSep );
390  }
391  else if (eImageAlign == ImageAlign::Center)
392  {
393  aImagePos.setX( rPos.X() + (aMax.Width() - aImageSize.Width()) / 2 );
394  aImagePos.setY( rPos.Y() + (aMax.Height() - aImageSize.Height()) / 2 );
395  aTextPos.setX( rPos.X() + (aMax.Width() - aTSSize.Width()) / 2 );
396  aTextPos.setY( rPos.Y() + (aMax.Height() - aTSSize.Height()) / 2 );
397  }
398  aUnion = tools::Rectangle(aImagePos, aImageSize);
399  aUnion.Union(tools::Rectangle(aTextPos, aTSSize));
400  }
401 
402  // Now place the combination of text and image in the output area of the button
403  // according to the window style (WinBits)
404  tools::Long nXOffset = 0;
405  tools::Long nYOffset = 0;
406 
407  if (nWinStyle & WB_CENTER)
408  {
409  nXOffset = (rSize.Width() - aUnion.GetWidth()) / 2;
410  }
411  else if (nWinStyle & WB_RIGHT)
412  {
413  nXOffset = rSize.Width() - aUnion.GetWidth();
414  }
415 
416  if (nWinStyle & WB_VCENTER)
417  {
418  nYOffset = (rSize.Height() - aUnion.GetHeight()) / 2;
419  }
420  else if (nWinStyle & WB_BOTTOM)
421  {
422  nYOffset = rSize.Height() - aUnion.GetHeight();
423  }
424 
425  // the top left corner should always be visible, so we don't allow negative offsets
426  if (nXOffset < 0) nXOffset = 0;
427  if (nYOffset < 0) nYOffset = 0;
428 
429  aImagePos.AdjustX(nXOffset );
430  aImagePos.AdjustY(nYOffset );
431  aTextPos.AdjustX(nXOffset );
432  aTextPos.AdjustY(nYOffset );
433 
434  // set rPos and rSize to the union
435  rSize = aUnion.GetSize();
436  rPos.AdjustX(nXOffset );
437  rPos.AdjustY(nYOffset );
438 
439  if (bHasSymbol)
440  {
441  if (mpButtonData->meSymbolAlign == SymbolAlign::RIGHT)
442  {
443  Point aRightPos(aTextPos.X() + aTextSize.Width() + aSymbolSize.Width() / 2, aTextPos.Y());
444  *pSymbolRect = tools::Rectangle(aRightPos, aSymbolSize);
445  }
446  else
447  {
448  *pSymbolRect = tools::Rectangle(aTextPos, aSymbolSize);
449  aTextPos.AdjustX(3 * nSymbolHeight / 2 );
450  }
451  if (mpButtonData->mbSmallSymbol)
452  {
453  nYOffset = (aUnion.GetHeight() - aSymbolSize.Height()) / 2;
454  pSymbolRect->setY(aTextPos.Y() + nYOffset);
455  }
456  }
457 
459 
460  if (!IsEnabled())
461  {
462  nStyle |= DrawImageFlags::Disable;
463  }
464 
465  if (IsZoom())
466  pDev->DrawImage(aImagePos, aImageSize, *pImage, nStyle);
467  else
468  pDev->DrawImage(aImagePos, *pImage, nStyle);
469 
470  if (bDrawText)
471  {
472  const tools::Rectangle aTOutRect(aTextPos, aTextSize);
473  ImplSetFocusRect(aTOutRect);
474  DrawControlText(*pDev, aTOutRect, aText, nTextStyle, nullptr, nullptr, &aDeviceTextSize);
475  }
476  else
477  {
478  ImplSetFocusRect(tools::Rectangle(aImagePos, aImageSize));
479  }
480 }
481 
483 {
484  tools::Rectangle aFocusRect = rFocusRect;
485  tools::Rectangle aOutputRect(Point(), GetOutputSizePixel());
486 
487  if (!aFocusRect.IsEmpty())
488  {
489  aFocusRect.AdjustLeft( -1 );
490  aFocusRect.AdjustTop( -1 );
491  aFocusRect.AdjustRight( 1 );
492  aFocusRect.AdjustBottom( 1 );
493  }
494 
495  if (aFocusRect.Left() < aOutputRect.Left())
496  aFocusRect.SetLeft( aOutputRect.Left() );
497  if (aFocusRect.Top() < aOutputRect.Top())
498  aFocusRect.SetTop( aOutputRect.Top() );
499  if (aFocusRect.Right() > aOutputRect.Right())
500  aFocusRect.SetRight( aOutputRect.Right() );
501  if (aFocusRect.Bottom() > aOutputRect.Bottom())
502  aFocusRect.SetBottom( aOutputRect.Bottom() );
503 
504  mpButtonData->maFocusRect = aFocusRect;
505 }
506 
508 {
509  return mpButtonData->maFocusRect;
510 }
511 
513 {
514  return mpButtonData->mnButtonState;
515 }
516 
518 {
519  return mpButtonData->mnButtonState;
520 }
521 
523 {
524  if ( mpButtonData->meSymbolAlign != eAlign )
525  {
526  mpButtonData->meSymbolAlign = eAlign;
528  }
529 }
530 
532 {
533  mpButtonData->mbSmallSymbol = true;
534 }
535 
537 {
538  return mpButtonData->mbSmallSymbol;
539 }
540 
541 bool Button::set_property(const OString &rKey, const OUString &rValue)
542 {
543  if (rKey == "image-position")
544  {
545  ImageAlign eAlign = ImageAlign::Left;
546  if (rValue == "left")
547  eAlign = ImageAlign::Left;
548  else if (rValue == "right")
549  eAlign = ImageAlign::Right;
550  else if (rValue == "top")
551  eAlign = ImageAlign::Top;
552  else if (rValue == "bottom")
553  eAlign = ImageAlign::Bottom;
554  SetImageAlign(eAlign);
555  }
556  else if (rKey == "focus-on-click")
557  {
558  WinBits nBits = GetStyle();
559  nBits &= ~WB_NOPOINTERFOCUS;
560  if (!toBool(rValue))
561  nBits |= WB_NOPOINTERFOCUS;
562  SetStyle(nBits);
563  }
564  else
565  return Control::set_property(rKey, rValue);
566  return true;
567 }
568 
569 void Button::statusChanged(const css::frame::FeatureStateEvent& rEvent)
570 {
571  Enable(rEvent.IsEnabled);
572 }
573 
575 {
576  return ButtonUIObject::create;
577 }
578 
580 {
581  Control::DumpAsPropertyTree(rJsonWriter);
582  rJsonWriter.put("text", GetText());
583 }
584 
585 IMPL_STATIC_LINK( Button, dispatchCommandHandler, Button*, pButton, void )
586 {
587  if (pButton == nullptr)
588  return;
589 
590  comphelper::dispatchCommand(pButton->maCommand, uno::Sequence<beans::PropertyValue>());
591 }
592 
594 {
595  mpWindowImpl->mbPushButton = true;
596 
600  mbIsActive = false;
601  mbPressed = false;
602  mbIsAction = false;
603 }
604 
605 namespace
606 {
607  vcl::Window* getPreviousSibling(vcl::Window const *pParent)
608  {
609  return pParent ? pParent->GetWindow(GetWindowType::LastChild) : nullptr;
610  }
611 }
612 
613 void PushButton::ImplInit( vcl::Window* pParent, WinBits nStyle )
614 {
615  nStyle = ImplInitStyle(getPreviousSibling(pParent), nStyle);
616  Button::ImplInit( pParent, nStyle, nullptr );
617 
618  if ( nStyle & WB_NOLIGHTBORDER )
620 
621  ImplInitSettings( true );
622 }
623 
625 {
626  if ( !(nStyle & WB_NOTABSTOP) )
627  nStyle |= WB_TABSTOP;
628 
629  // if no alignment is given, default to "vertically centered". This is because since
630  // #i26046#, we respect the vertical alignment flags (previously we didn't completely),
631  // but we of course want to look as before when no vertical alignment is specified
632  if ( ( nStyle & ( WB_TOP | WB_VCENTER | WB_BOTTOM ) ) == 0 )
633  nStyle |= WB_VCENTER;
634 
635  if ( !(nStyle & WB_NOGROUP) &&
636  (!pPrevWindow ||
637  ((pPrevWindow->GetType() != WindowType::PUSHBUTTON ) &&
638  (pPrevWindow->GetType() != WindowType::OKBUTTON ) &&
639  (pPrevWindow->GetType() != WindowType::CANCELBUTTON) &&
640  (pPrevWindow->GetType() != WindowType::HELPBUTTON )) ) )
641  nStyle |= WB_GROUP;
642  return nStyle;
643 }
644 
646 {
647  return _rStyle.GetPushButtonFont();
648 }
649 
651 {
652  return _rStyle.GetButtonTextColor();
653 }
654 
655 void PushButton::ImplInitSettings( bool bBackground )
656 {
658 
659  if ( !bBackground )
660  return;
661 
662  SetBackground();
663  // #i38498#: do not check for GetParent()->IsChildTransparentModeEnabled()
664  // otherwise the formcontrol button will be overdrawn due to ParentClipMode::NoClip
665  // for radio and checkbox this is ok as they should appear transparent in documents
667  (GetStyle() & WB_FLATBUTTON) != 0 )
668  {
671  SetPaintTransparent( true );
672 
673  if ((GetStyle() & WB_FLATBUTTON) == 0)
674  mpWindowImpl->mbUseNativeFocus = ImplGetSVData()->maNWFData.mbNoFocusRects;
675  else
677  }
678  else
679  {
682  SetPaintTransparent( false );
683  }
684 }
685 
687  tools::Rectangle& rRect, DrawButtonFlags nStyle)
688 {
689  if (!(GetStyle() & (WB_RECTSTYLE | WB_SMALLSTYLE)))
690  {
691  StyleSettings aStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
692  if (IsControlBackground())
693  aStyleSettings.Set3DColors(GetControlBackground());
694  }
695 
696  DecorationView aDecoView(&rRenderContext);
697  if (IsControlBackground())
698  {
699  AllSettings aSettings = rRenderContext.GetSettings();
700  AllSettings aOldSettings = aSettings;
701  StyleSettings aStyleSettings = aSettings.GetStyleSettings();
702  if (nStyle & DrawButtonFlags::Highlight)
703  {
704  // with the custom background, native highlight do nothing, so code below mimic
705  // native highlight by changing luminance
706  Color controlBackgroundColorHighlighted = GetControlBackground();
707  sal_uInt8 colorLuminance = controlBackgroundColorHighlighted.GetLuminance();
708  if (colorLuminance < 205)
709  controlBackgroundColorHighlighted.IncreaseLuminance(50);
710  else
711  controlBackgroundColorHighlighted.DecreaseLuminance(50);
712  aStyleSettings.Set3DColors(controlBackgroundColorHighlighted);
713  }
714  else
715  aStyleSettings.Set3DColors(GetControlBackground());
716  aSettings.SetStyleSettings(aStyleSettings);
717 
718  // Call OutputDevice::SetSettings() explicitly, as rRenderContext may
719  // be a vcl::Window in fact, and vcl::Window::SetSettings() will call
720  // Invalidate(), which is a problem, since we're in Paint().
721  rRenderContext.OutputDevice::SetSettings(aSettings);
722  rRect = aDecoView.DrawButton(rRect, nStyle);
723  rRenderContext.OutputDevice::SetSettings(aOldSettings);
724  }
725  else
726  rRect = aDecoView.DrawButton(rRect, nStyle);
727 }
728 
730  const Point& rPos )
731 {
732  tools::Rectangle aTestRect( Point(), pDev->GetOutputSizePixel() );
733 
734  return aTestRect.IsInside( rPos );
735 }
736 
738 {
739  const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
740 
742 
743  if ( ( rStyleSettings.GetOptions() & StyleSettingsOptions::Mono ) ||
744  ( nDrawFlags & DrawFlags::Mono ) )
745  nTextStyle |= DrawTextFlags::Mono;
746 
747  if ( GetStyle() & WB_WORDBREAK )
748  nTextStyle |= DrawTextFlags::WordBreak;
749  if ( GetStyle() & WB_NOLABEL )
750  nTextStyle &= ~DrawTextFlags::Mnemonic;
751 
752  if ( GetStyle() & WB_LEFT )
753  nTextStyle |= DrawTextFlags::Left;
754  else if ( GetStyle() & WB_RIGHT )
755  nTextStyle |= DrawTextFlags::Right;
756  else
757  nTextStyle |= DrawTextFlags::Center;
758 
759  if ( GetStyle() & WB_TOP )
760  nTextStyle |= DrawTextFlags::Top;
761  else if ( GetStyle() & WB_BOTTOM )
762  nTextStyle |= DrawTextFlags::Bottom;
763  else
764  nTextStyle |= DrawTextFlags::VCenter;
765 
766  if ( !IsEnabled() )
767  nTextStyle |= DrawTextFlags::Disable;
768 
769  return nTextStyle;
770 }
771 
773  const tools::Rectangle &rRect, bool bMenuBtnSep,
774  DrawButtonFlags nButtonFlags)
775 {
776  const StyleSettings &rStyleSettings = GetSettings().GetStyleSettings();
777  tools::Rectangle aInRect = rRect;
778  Color aColor;
779  DrawTextFlags nTextStyle = ImplGetTextStyle(nDrawFlags);
780  DrawSymbolFlags nStyle;
781 
782  if (aInRect.Right() < aInRect.Left() || aInRect.Bottom() < aInRect.Top())
783  return;
784 
786  pDev->IntersectClipRegion(aInRect);
787 
788  if (nDrawFlags & DrawFlags::Mono)
789  aColor = COL_BLACK;
790 
791  else if (IsControlForeground())
792  aColor = GetControlForeground();
793 
794  // Button types with possibly different text coloring are flat buttons and regular buttons. Regular buttons may be action
795  // buttons and may have an additional default status. Moreover all buttons may have an additional pressed and rollover
796  // (highlight) status. Pressed buttons are always in rollover status.
797 
798  else if (GetStyle() & WB_FLATBUTTON)
799  if (nButtonFlags & DrawButtonFlags::Pressed)
800  aColor = rStyleSettings.GetFlatButtonPressedRolloverTextColor();
801  else if (nButtonFlags & DrawButtonFlags::Highlight)
802  aColor = rStyleSettings.GetFlatButtonRolloverTextColor();
803  else
804  aColor = rStyleSettings.GetFlatButtonTextColor();
805  else
806  if (isAction() && (nButtonFlags & DrawButtonFlags::Default))
807  if (nButtonFlags & DrawButtonFlags::Pressed)
808  aColor = rStyleSettings.GetDefaultActionButtonPressedRolloverTextColor();
809  else if (nButtonFlags & DrawButtonFlags::Highlight)
810  aColor = rStyleSettings.GetDefaultActionButtonRolloverTextColor();
811  else
812  aColor = rStyleSettings.GetDefaultActionButtonTextColor();
813  else if (isAction())
814  if (nButtonFlags & DrawButtonFlags::Pressed)
815  aColor = rStyleSettings.GetActionButtonPressedRolloverTextColor();
816  else if (nButtonFlags & DrawButtonFlags::Highlight)
817  aColor = rStyleSettings.GetActionButtonRolloverTextColor();
818  else
819  aColor = rStyleSettings.GetActionButtonTextColor();
820  else if (nButtonFlags & DrawButtonFlags::Default)
821  if (nButtonFlags & DrawButtonFlags::Pressed)
822  aColor = rStyleSettings.GetDefaultButtonPressedRolloverTextColor();
823  else if (nButtonFlags & DrawButtonFlags::Highlight)
824  aColor = rStyleSettings.GetDefaultButtonRolloverTextColor();
825  else
826  aColor = rStyleSettings.GetDefaultButtonTextColor();
827  else
828  if (nButtonFlags & DrawButtonFlags::Pressed)
829  aColor = rStyleSettings.GetButtonPressedRolloverTextColor();
830  else if (nButtonFlags & DrawButtonFlags::Highlight)
831  aColor = rStyleSettings.GetButtonRolloverTextColor();
832  else
833  aColor = rStyleSettings.GetButtonTextColor();
834 
835  pDev->SetTextColor(aColor);
836 
837  if ( IsEnabled() )
838  nStyle = DrawSymbolFlags::NONE;
839  else
840  nStyle = DrawSymbolFlags::Disable;
841 
842  Size aSize = rRect.GetSize();
843  Point aPos = rRect.TopLeft();
844 
845  sal_Int32 nImageSep = 1 + (pDev->GetTextHeight()-10)/2;
846  if( nImageSep < 1 )
847  nImageSep = 1;
850  {
851  tools::Long nSeparatorX = 0;
852  tools::Rectangle aSymbolRect = aInRect;
853 
854  // calculate symbol size
855  tools::Long nSymbolSize = pDev->GetTextHeight() / 2 + 1;
856  if (nSymbolSize > aSize.Width() / 2)
857  nSymbolSize = aSize.Width() / 2;
858 
859  nSeparatorX = aInRect.Right() - 2*nSymbolSize;
860 
861  // tdf#141761 Minimum width should be (1) Pixel, see comment
862  // with same task number above for more info
863  const tools::Long nWidthAdjust(2*nSymbolSize);
864  aSize.setWidth(std::max(static_cast<tools::Long>(1), aSize.getWidth() - nWidthAdjust));
865 
866  // center symbol rectangle in the separated area
867  aSymbolRect.AdjustRight( -(nSymbolSize/2) );
868  aSymbolRect.SetLeft( aSymbolRect.Right() - nSymbolSize );
869 
870  ImplDrawAlignedImage( pDev, aPos, aSize, nImageSep,
871  nTextStyle, nullptr, true );
872 
873  tools::Long nDistance = (aSymbolRect.GetHeight() > 10) ? 2 : 1;
874  DecorationView aDecoView( pDev );
875  if( bMenuBtnSep && nSeparatorX > 0 )
876  {
877  Point aStartPt( nSeparatorX, aSymbolRect.Top()+nDistance );
878  Point aEndPt( nSeparatorX, aSymbolRect.Bottom()-nDistance );
879  aDecoView.DrawSeparator( aStartPt, aEndPt );
880  }
881  ImplSetSeparatorX( nSeparatorX );
882 
883  aDecoView.DrawSymbol( aSymbolRect, SymbolType::SPIN_DOWN, aColor, nStyle );
884 
885  }
886  else
887  {
888  tools::Rectangle aSymbolRect;
889  ImplDrawAlignedImage( pDev, aPos, aSize, nImageSep,
890  nTextStyle, IsSymbol() ? &aSymbolRect : nullptr, true );
891 
892  if ( IsSymbol() )
893  {
894  DecorationView aDecoView( pDev );
895  aDecoView.DrawSymbol( aSymbolRect, meSymbol, aColor, nStyle );
896  }
897  }
898 
899  pDev->Pop(); // restore clipregion
900 }
901 
903 {
904  HideFocus();
905 
906  DrawButtonFlags nButtonStyle = GetButtonState();
907  Size aOutSz(GetOutputSizePixel());
908  tools::Rectangle aRect(Point(), aOutSz);
909  tools::Rectangle aInRect = aRect;
910  bool bNativeOK = false;
911 
912  // adjust style if button should be rendered 'pressed'
913  if (mbPressed || mbIsActive)
914  nButtonStyle |= DrawButtonFlags::Pressed;
915 
916  // TODO: move this to Window class or make it a member !!!
917  ControlType aCtrlType = ControlType::Generic;
918  switch(GetParent()->GetType())
919  {
920  case WindowType::LISTBOX:
921  case WindowType::MULTILISTBOX:
922  case WindowType::TREELISTBOX:
923  aCtrlType = ControlType::Listbox;
924  break;
925 
926  case WindowType::COMBOBOX:
927  case WindowType::PATTERNBOX:
928  case WindowType::NUMERICBOX:
929  case WindowType::METRICBOX:
930  case WindowType::CURRENCYBOX:
931  case WindowType::DATEBOX:
932  case WindowType::TIMEBOX:
933  case WindowType::LONGCURRENCYBOX:
934  aCtrlType = ControlType::Combobox;
935  break;
936  default:
937  break;
938  }
939 
940  bool bDropDown = (IsSymbol() && (GetSymbol() == SymbolType::SPIN_DOWN) && GetText().isEmpty());
941 
942  if( bDropDown && (aCtrlType == ControlType::Combobox || aCtrlType == ControlType::Listbox))
943  {
945  {
946  // skip painting if the button was already drawn by the theme
947  if (aCtrlType == ControlType::Combobox)
948  {
949  Edit* pEdit = static_cast<Edit*>(GetParent());
950  if (pEdit->ImplUseNativeBorder(rRenderContext, pEdit->GetStyle()))
951  bNativeOK = true;
952  }
954  {
955  bNativeOK = true;
956  }
957 
958  if (!bNativeOK && GetParent()->IsNativeControlSupported(aCtrlType, ControlPart::ButtonDown))
959  {
960  // let the theme draw it, note we then need support
961  // for ControlType::Listbox/ControlPart::ButtonDown and ControlType::Combobox/ControlPart::ButtonDown
962 
963  ImplControlValue aControlValue;
965 
966  if (mbPressed || mbIsActive)
967  nState |= ControlState::PRESSED;
969  nState |= ControlState::PRESSED;
970  if (HasFocus())
971  nState |= ControlState::FOCUSED;
973  nState |= ControlState::DEFAULT;
974  if (Window::IsEnabled())
975  nState |= ControlState::ENABLED;
976 
977  if (IsMouseOver() && aInRect.IsInside(GetPointerPosPixel()))
978  nState |= ControlState::ROLLOVER;
979 
980  if ( IsMouseOver() && aInRect.IsInside(GetPointerPosPixel()) && mbIsActive)
981  {
982  nState |= ControlState::ROLLOVER;
983  nButtonStyle &= ~DrawButtonFlags::Pressed;
984  }
985 
986  bNativeOK = rRenderContext.DrawNativeControl(aCtrlType, ControlPart::ButtonDown, aInRect, nState,
987  aControlValue, OUString());
988  }
989  }
990  }
991 
992  if (bNativeOK)
993  return;
994 
995  bool bRollOver = (IsMouseOver() && aInRect.IsInside(GetPointerPosPixel()));
996  if (bRollOver)
997  nButtonStyle |= DrawButtonFlags::Highlight;
999  if (GetStyle() & WB_FLATBUTTON)
1000  {
1001  if (!bRollOver && !HasFocus())
1002  bDrawMenuSep = false;
1003  }
1004  // tdf#123175 if there is a custom control bg set, draw the button without outsourcing to the NWF
1006  if (bNativeOK)
1007  {
1008  PushButtonValue aControlValue;
1009  aControlValue.mbIsAction = isAction();
1010 
1011  tools::Rectangle aCtrlRegion(aInRect);
1013 
1014  if (mbPressed || IsChecked() || mbIsActive)
1015  {
1016  nState |= ControlState::PRESSED;
1017  nButtonStyle |= DrawButtonFlags::Pressed;
1018  }
1020  nState |= ControlState::PRESSED;
1021  if (HasFocus())
1022  nState |= ControlState::FOCUSED;
1024  nState |= ControlState::DEFAULT;
1025  if (Window::IsEnabled())
1026  nState |= ControlState::ENABLED;
1027 
1028  if (bRollOver || mbIsActive)
1029  {
1030  nButtonStyle |= DrawButtonFlags::Highlight;
1031  nState |= ControlState::ROLLOVER;
1032  }
1033 
1034  if (mbIsActive && bRollOver)
1035  {
1036  nState &= ~ControlState::PRESSED;
1037  nButtonStyle &= ~DrawButtonFlags::Pressed;
1038  }
1039 
1040  if (GetStyle() & WB_FLATBUTTON)
1041  aControlValue.m_bFlatButton = true;
1042  if (GetStyle() & WB_BEVELBUTTON)
1043  aControlValue.mbBevelButton = true;
1044 
1045  // draw frame into invisible window to have aInRect modified correctly
1046  // but do not shift the inner rect for pressed buttons (ie remove DrawButtonFlags::Pressed)
1047  // this assumes the theme has enough visual cues to signalize the button was pressed
1048  //Window aWin( this );
1049  //ImplDrawPushButtonFrame( &aWin, aInRect, nButtonStyle & ~DrawButtonFlags::Pressed );
1050 
1051  // looks better this way as symbols were displaced slightly using the above approach
1052  aInRect.AdjustTop(4 );
1053  aInRect.AdjustBottom( -4 );
1054  aInRect.AdjustLeft(4 );
1055  aInRect.AdjustRight( -4 );
1056 
1057  // prepare single line hint (needed on mac to decide between normal push button and
1058  // rectangular bevel button look)
1059  Size aFontSize(Application::GetSettings().GetStyleSettings().GetPushButtonFont().GetFontSize());
1060  aFontSize = rRenderContext.LogicToPixel(aFontSize, MapMode(MapUnit::MapPoint));
1061  Size aInRectSize(rRenderContext.LogicToPixel(Size(aInRect.GetWidth(), aInRect.GetHeight())));
1062  aControlValue.mbSingleLine = (aInRectSize.Height() < 2 * aFontSize.Height());
1063 
1064  if ((nState & ControlState::ROLLOVER) || !(GetStyle() & WB_FLATBUTTON)
1065  || (HasFocus() && mpWindowImpl->mbUseNativeFocus
1067  {
1068  bNativeOK = rRenderContext.DrawNativeControl(ControlType::Pushbutton, ControlPart::Entire, aCtrlRegion, nState,
1069  aControlValue, OUString() /*PushButton::GetText()*/);
1070  }
1071  else
1072  {
1073  bNativeOK = true;
1074  }
1075 
1076  // draw content using the same aInRect as non-native VCL would do
1077  ImplDrawPushButtonContent(&rRenderContext, DrawFlags::NONE,
1078  aInRect, bDrawMenuSep, nButtonStyle);
1079 
1080  if (HasFocus())
1082  }
1083 
1084  if (bNativeOK)
1085  return;
1086 
1087  // draw PushButtonFrame, aInRect has content size afterwards
1088  if (GetStyle() & WB_FLATBUTTON)
1089  {
1090  tools::Rectangle aTempRect(aInRect);
1091  if (bRollOver)
1092  ImplDrawPushButtonFrame(rRenderContext, aTempRect, nButtonStyle);
1093  aInRect.AdjustLeft(2 );
1094  aInRect.AdjustTop(2 );
1095  aInRect.AdjustRight( -2 );
1096  aInRect.AdjustBottom( -2 );
1097  }
1098  else
1099  {
1100  ImplDrawPushButtonFrame(rRenderContext, aInRect, nButtonStyle);
1101  }
1102 
1103  // draw content
1104  ImplDrawPushButtonContent(&rRenderContext, DrawFlags::NONE, aInRect, bDrawMenuSep, nButtonStyle);
1105 
1106  if (HasFocus())
1107  {
1109  }
1110 }
1111 
1113 {
1114  Size aSize( GetSizePixel() );
1115  Point aPos( GetPosPixel() );
1116  int dLeft(0), dRight(0), dTop(0), dBottom(0);
1117  bool bSetPos = false;
1118 
1120  {
1121  tools::Rectangle aBound, aCont;
1122  tools::Rectangle aCtrlRegion( 0, 0, 80, 20 ); // use a constant size to avoid accumulating
1123  // will not work if the theme has dynamic adornment sizes
1124  ImplControlValue aControlValue;
1125 
1126  // get native size of a 'default' button
1127  // and adjust the VCL button if more space for adornment is required
1130  aControlValue,
1131  aBound, aCont ) )
1132  {
1133  dLeft = aCont.Left() - aBound.Left();
1134  dTop = aCont.Top() - aBound.Top();
1135  dRight = aBound.Right() - aCont.Right();
1136  dBottom = aBound.Bottom() - aCont.Bottom();
1137  bSetPos = dLeft || dTop || dRight || dBottom;
1138  }
1139  }
1140 
1141  if ( bSet )
1142  {
1143  if( !(GetButtonState() & DrawButtonFlags::Default) && bSetPos )
1144  {
1145  // adjust pos/size when toggling from non-default to default
1146  aPos.Move(-dLeft, -dTop);
1147  aSize.AdjustWidth(dLeft + dRight );
1148  aSize.AdjustHeight(dTop + dBottom );
1149  }
1151  }
1152  else
1153  {
1154  if( (GetButtonState() & DrawButtonFlags::Default) && bSetPos )
1155  {
1156  // adjust pos/size when toggling from default to non-default
1157  aPos.Move(dLeft, dTop);
1158  aSize.AdjustWidth( -(dLeft + dRight) );
1159  aSize.AdjustHeight( -(dTop + dBottom) );
1160  }
1161  GetButtonState() &= ~DrawButtonFlags::Default;
1162  }
1163  if( bSetPos )
1164  setPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height() );
1165 
1166  Invalidate();
1167 }
1168 
1170 {
1171  return bool(GetButtonState() & DrawButtonFlags::Default);
1172 }
1173 
1175  Button( nType )
1176 {
1178 }
1179 
1182 {
1184  ImplInit( pParent, nStyle );
1185 }
1186 
1188 {
1189  if ( !(rMEvt.IsLeft() &&
1190  ImplHitTestPushButton( this, rMEvt.GetPosPixel() )) )
1191  return;
1192 
1194 
1195  if ( ( GetStyle() & WB_REPEAT ) &&
1196  ! ( GetStyle() & WB_TOGGLE ) )
1197  nTrackFlags |= StartTrackingFlags::ButtonRepeat;
1198 
1200  Invalidate();
1201  StartTracking( nTrackFlags );
1202 
1203  if ( nTrackFlags & StartTrackingFlags::ButtonRepeat )
1204  Click();
1205 }
1206 
1208 {
1209  if ( rTEvt.IsTrackingEnded() )
1210  {
1212  {
1213  if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() )
1214  GrabFocus();
1215 
1216  if ( GetStyle() & WB_TOGGLE )
1217  {
1218  // Don't toggle, when aborted
1219  if ( !rTEvt.IsTrackingCanceled() )
1220  {
1221  if ( IsChecked() )
1222  {
1223  Check( false );
1225  }
1226  else
1227  Check();
1228  }
1229  }
1230  else
1232 
1233  Invalidate();
1234 
1235  // do not call Click handler if aborted
1236  if ( !rTEvt.IsTrackingCanceled() )
1237  {
1238  if ( ! ( GetStyle() & WB_REPEAT ) || ( GetStyle() & WB_TOGGLE ) )
1239  Click();
1240  }
1241  }
1242  }
1243  else
1244  {
1245  if ( ImplHitTestPushButton( this, rTEvt.GetMouseEvent().GetPosPixel() ) )
1246  {
1248  {
1249  if ( rTEvt.IsTrackingRepeat() && (GetStyle() & WB_REPEAT) &&
1250  ! ( GetStyle() & WB_TOGGLE ) )
1251  Click();
1252  }
1253  else
1254  {
1256  Invalidate();
1257  }
1258  }
1259  else
1260  {
1262  {
1264  Invalidate();
1265  }
1266  }
1267  }
1268 }
1269 
1270 void PushButton::KeyInput( const KeyEvent& rKEvt )
1271 {
1272  vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
1273 
1274  if ( !aKeyCode.GetModifier() &&
1275  ((aKeyCode.GetCode() == KEY_RETURN) || (aKeyCode.GetCode() == KEY_SPACE)) )
1276  {
1278  {
1280  Invalidate();
1281  }
1282 
1283  if ( ( GetStyle() & WB_REPEAT ) &&
1284  ! ( GetStyle() & WB_TOGGLE ) )
1285  Click();
1286  }
1287  else if ( (GetButtonState() & DrawButtonFlags::Pressed) && (aKeyCode.GetCode() == KEY_ESCAPE) )
1288  {
1290  Invalidate();
1291  }
1292  else
1293  Button::KeyInput( rKEvt );
1294 }
1295 
1296 void PushButton::KeyUp( const KeyEvent& rKEvt )
1297 {
1298  vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
1299 
1301  ((aKeyCode.GetCode() == KEY_RETURN) || (aKeyCode.GetCode() == KEY_SPACE)) )
1302  {
1303  if ( GetStyle() & WB_TOGGLE )
1304  {
1305  if ( IsChecked() )
1306  {
1307  Check( false );
1309  }
1310  else
1311  Check();
1312 
1313  Toggle();
1314  }
1315  else
1317 
1318  Invalidate();
1319 
1320  if ( !( GetStyle() & WB_REPEAT ) || ( GetStyle() & WB_TOGGLE ) )
1321  Click();
1322  }
1323  else
1324  Button::KeyUp( rKEvt );
1325 }
1326 
1328 {
1329  mpControlData->mpLayoutData.reset( new vcl::ControlLayoutData );
1330  const_cast<PushButton*>(this)->Invalidate();
1331 }
1332 
1334 {
1335  const Image& rCustomButtonImage = GetCustomButtonImage();
1336  if (!!rCustomButtonImage)
1337  {
1338  rRenderContext.DrawImage(Point(0, 0), rCustomButtonImage);
1339  return;
1340  }
1341  ImplDrawPushButton(rRenderContext);
1342 }
1343 
1344 void PushButton::Draw( OutputDevice* pDev, const Point& rPos,
1345  DrawFlags nFlags )
1346 {
1347  Point aPos = pDev->LogicToPixel( rPos );
1348  Size aSize = GetSizePixel();
1349  tools::Rectangle aRect( aPos, aSize );
1350  vcl::Font aFont = GetDrawPixelFont( pDev );
1351 
1352  pDev->Push();
1353  pDev->SetMapMode();
1354  pDev->SetFont( aFont );
1355  if ( nFlags & DrawFlags::Mono )
1356  {
1357  pDev->SetTextColor( COL_BLACK );
1358  }
1359  else
1360  {
1361  pDev->SetTextColor( GetTextColor() );
1362 
1363  // DecoView uses the FaceColor...
1364  AllSettings aSettings = pDev->GetSettings();
1365  StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1366  if ( IsControlBackground() )
1367  aStyleSettings.SetFaceColor( GetControlBackground() );
1368  else
1369  aStyleSettings.SetFaceColor( GetSettings().GetStyleSettings().GetFaceColor() );
1370  aSettings.SetStyleSettings( aStyleSettings );
1371  pDev->OutputDevice::SetSettings( aSettings );
1372  }
1373  pDev->SetTextFillColor();
1374 
1375  DecorationView aDecoView( pDev );
1376  DrawButtonFlags nButtonStyle = DrawButtonFlags::NONE;
1377  if ( nFlags & DrawFlags::Mono )
1378  nButtonStyle |= DrawButtonFlags::Mono;
1379  if ( IsChecked() )
1380  nButtonStyle |= DrawButtonFlags::Checked;
1381  aRect = aDecoView.DrawButton( aRect, nButtonStyle );
1382 
1383  ImplDrawPushButtonContent( pDev, nFlags, aRect, true, nButtonStyle );
1384  pDev->Pop();
1385 }
1386 
1388 {
1389  Control::Resize();
1390  Invalidate();
1391 }
1392 
1394 {
1397  Button::GetFocus();
1398 }
1399 
1401 {
1402  EndSelection();
1403  HideFocus();
1405 }
1406 
1408 {
1409  Button::StateChanged( nType );
1410 
1411  if ( (nType == StateChangedType::Enable) ||
1412  (nType == StateChangedType::Text) ||
1413  (nType == StateChangedType::Data) ||
1414  (nType == StateChangedType::State) ||
1415  (nType == StateChangedType::UpdateMode) )
1416  {
1417  if ( IsReallyVisible() && IsUpdateMode() )
1418  Invalidate();
1419  }
1420  else if ( nType == StateChangedType::Style )
1421  {
1423 
1424  bool bIsDefButton = ( GetStyle() & WB_DEFBUTTON ) != 0;
1425  bool bWasDefButton = ( GetPrevStyle() & WB_DEFBUTTON ) != 0;
1426  if ( bIsDefButton != bWasDefButton )
1427  ImplSetDefButton( bIsDefButton );
1428 
1429  if ( IsReallyVisible() && IsUpdateMode() )
1430  {
1431  if ( (GetPrevStyle() & PUSHBUTTON_VIEW_STYLE) !=
1433  Invalidate();
1434  }
1435  }
1436  else if ( (nType == StateChangedType::Zoom) ||
1437  (nType == StateChangedType::ControlFont) )
1438  {
1439  ImplInitSettings( false );
1440  Invalidate();
1441  }
1442  else if ( nType == StateChangedType::ControlForeground )
1443  {
1444  ImplInitSettings( false );
1445  Invalidate();
1446  }
1447  else if ( nType == StateChangedType::ControlBackground )
1448  {
1449  ImplInitSettings( true );
1450  Invalidate();
1451  }
1452 }
1453 
1455 {
1456  Button::DataChanged( rDCEvt );
1457 
1458  if ( (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
1460  ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
1461  (rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
1462  {
1463  ImplInitSettings( true );
1464  Invalidate();
1465  }
1466 }
1467 
1469 {
1470  if( rNEvt.GetType() == MouseNotifyEvent::MOUSEMOVE )
1471  {
1472  const MouseEvent* pMouseEvt = rNEvt.GetMouseEvent();
1473  if( pMouseEvt && (pMouseEvt->IsEnterWindow() || pMouseEvt->IsLeaveWindow()) )
1474  {
1475  // trigger redraw as mouse over state has changed
1476 
1477  // TODO: move this to Window class or make it a member !!!
1478  ControlType aCtrlType = ControlType::Generic;
1479  switch( GetParent()->GetType() )
1480  {
1481  case WindowType::LISTBOX:
1482  case WindowType::MULTILISTBOX:
1483  case WindowType::TREELISTBOX:
1484  aCtrlType = ControlType::Listbox;
1485  break;
1486 
1487  case WindowType::COMBOBOX:
1488  case WindowType::PATTERNBOX:
1489  case WindowType::NUMERICBOX:
1490  case WindowType::METRICBOX:
1491  case WindowType::CURRENCYBOX:
1492  case WindowType::DATEBOX:
1493  case WindowType::TIMEBOX:
1494  case WindowType::LONGCURRENCYBOX:
1495  aCtrlType = ControlType::Combobox;
1496  break;
1497  default:
1498  break;
1499  }
1500 
1501  bool bDropDown = ( IsSymbol() && (GetSymbol()==SymbolType::SPIN_DOWN) && GetText().isEmpty() );
1502 
1503  if( bDropDown && GetParent()->IsNativeControlSupported( aCtrlType, ControlPart::Entire) &&
1505  {
1507  if(aCtrlType == ControlType::Combobox)
1508  {
1509  // only paint the button part to avoid flickering of the combobox text
1510  tools::Rectangle aClipRect( Point(), GetOutputSizePixel() );
1511  aClipRect.SetPos(pBorder->ScreenToOutputPixel(OutputToScreenPixel(aClipRect.TopLeft())));
1512  pBorder->Invalidate( aClipRect );
1513  }
1514  else
1515  {
1517  }
1518  }
1519  else if( (GetStyle() & WB_FLATBUTTON) ||
1521  {
1522  Invalidate();
1523  }
1524  }
1525  }
1526 
1527  return Button::PreNotify(rNEvt);
1528 }
1529 
1531 {
1533 }
1534 
1536 {
1537  if ( meSymbol != eSymbol )
1538  {
1539  meSymbol = eSymbol;
1541  }
1542 }
1543 
1545 {
1546  ImplSetSymbolAlign( eAlign );
1547 }
1548 
1550 {
1551  if ( mnDDStyle != nStyle )
1552  {
1553  mnDDStyle = nStyle;
1555  }
1556 }
1557 
1559 {
1560  if ( meState == eState )
1561  return;
1562 
1563  meState = eState;
1564  if ( meState == TRISTATE_FALSE )
1566  else if ( meState == TRISTATE_TRUE )
1567  {
1568  GetButtonState() &= ~DrawButtonFlags::DontKnow;
1570  }
1571  else // TRISTATE_INDET
1572  {
1573  GetButtonState() &= ~DrawButtonFlags::Checked;
1575  }
1576 
1578  Toggle();
1579 }
1580 
1581 void PushButton::statusChanged(const css::frame::FeatureStateEvent& rEvent)
1582 {
1583  Button::statusChanged(rEvent);
1584  if (rEvent.State.has<bool>())
1585  SetPressed(rEvent.State.get<bool>());
1586 }
1587 
1588 void PushButton::SetPressed( bool bPressed )
1589 {
1590  if ( mbPressed != bPressed )
1591  {
1592  mbPressed = bPressed;
1594  }
1595 }
1596 
1598 {
1600  if ( !isDisposed() &&
1602  {
1604  if ( !mbPressed )
1605  Invalidate();
1606  }
1607 }
1608 
1610 {
1611  Size aSize;
1612 
1613  if ( IsSymbol() )
1614  {
1615  if ( IsSmallSymbol ())
1616  aSize = Size( 16, 12 );
1617  else
1618  aSize = Size( 26, 24 );
1619  }
1620  else if ( Button::HasImage() )
1621  aSize = GetModeImage().GetSizePixel();
1624  {
1625  tools::Long nSymbolSize = GetTextHeight() / 2 + 1;
1626  aSize.AdjustWidth(2*nSymbolSize );
1627  }
1628  if (!PushButton::GetText().isEmpty())
1629  {
1630  Size textSize = GetTextRect( tools::Rectangle( Point(), Size( 0x7fffffff, 0x7fffffff ) ),
1632 
1633  tools::Long nTextHeight = textSize.Height() * 1.15;
1634 
1635  ImageAlign eImageAlign = GetImageAlign();
1636  // tdf#142337 only considering the simple top/bottom/left/right possibilities
1637  if (eImageAlign == ImageAlign::Top || eImageAlign == ImageAlign::Bottom)
1638  {
1639  aSize.AdjustHeight(nTextHeight);
1640  aSize.setWidth(std::max(aSize.Width(), textSize.Width()));
1641  }
1642  else
1643  {
1644  aSize.AdjustWidth(textSize.Width());
1645  aSize.setHeight(std::max(aSize.Height(), nTextHeight));
1646  }
1647  }
1648 
1649  // cf. ImplDrawPushButton ...
1650  if( (GetStyle() & WB_SMALLSTYLE) == 0 )
1651  {
1652  aSize.AdjustWidth(24 );
1653  aSize.AdjustHeight(12 );
1654  }
1655 
1656  return CalcWindowSize( aSize );
1657 }
1658 
1660 {
1661  return CalcMinimumSize();
1662 }
1663 
1664 bool PushButton::set_property(const OString &rKey, const OUString &rValue)
1665 {
1666  if (rKey == "has-default")
1667  {
1668  WinBits nBits = GetStyle();
1669  nBits &= ~WB_DEFBUTTON;
1670  if (toBool(rValue))
1671  nBits |= WB_DEFBUTTON;
1672  SetStyle(nBits);
1673  }
1674  else
1675  return Button::set_property(rKey, rValue);
1676  return true;
1677 }
1678 
1680 {
1682  {
1683  PushButtonValue aControlValue;
1684  aControlValue.mbIsAction = isAction();
1687  ControlState::FOCUSED, aControlValue, OUString());
1688  }
1689  Button::ShowFocus(rRect);
1690 }
1691 
1692 void OKButton::ImplInit( vcl::Window* pParent, WinBits nStyle )
1693 {
1694  set_id("ok");
1695  PushButton::ImplInit( pParent, nStyle );
1696 
1697  SetText( GetStandardText( StandardButtonType::OK ) );
1698 }
1699 
1702 {
1703  ImplInit( pParent, nStyle );
1704 }
1705 
1707 {
1708  // close parent if no link set
1709  if ( !GetClickHdl() )
1710  {
1711  vcl::Window* pParent = getNonLayoutParent(this);
1712  if ( pParent->IsSystemWindow() )
1713  {
1714  if ( pParent->IsDialog() )
1715  {
1716  VclPtr<Dialog> xParent( static_cast<Dialog*>(pParent) );
1717  if ( xParent->IsInExecute() )
1718  xParent->EndDialog( RET_OK );
1719  // prevent recursive calls
1720  else if ( !xParent->IsInClose() )
1721  {
1722  if ( pParent->GetStyle() & WB_CLOSEABLE )
1723  xParent->Close();
1724  }
1725  }
1726  else
1727  {
1728  if ( pParent->GetStyle() & WB_CLOSEABLE )
1729  static_cast<SystemWindow*>(pParent)->Close();
1730  }
1731  }
1732  }
1733  else
1734  {
1736  }
1737 }
1738 
1740 {
1741  set_id("cancel");
1742  PushButton::ImplInit( pParent, nStyle );
1743 
1744  SetText( GetStandardText( StandardButtonType::Cancel ) );
1745 }
1746 
1749 {
1750  ImplInit( pParent, nStyle );
1751 }
1752 
1754 {
1755  // close parent if link not set
1756  if ( !GetClickHdl() )
1757  {
1758  vcl::Window* pParent = getNonLayoutParent(this);
1759  if ( pParent->IsSystemWindow() )
1760  {
1761  if ( pParent->IsDialog() )
1762  {
1763  if ( static_cast<Dialog*>(pParent)->IsInExecute() )
1764  static_cast<Dialog*>(pParent)->EndDialog();
1765  // prevent recursive calls
1766  else if ( !static_cast<Dialog*>(pParent)->IsInClose() )
1767  {
1768  if ( pParent->GetStyle() & WB_CLOSEABLE )
1769  static_cast<Dialog*>(pParent)->Close();
1770  }
1771  }
1772  else
1773  {
1774  if ( pParent->GetStyle() & WB_CLOSEABLE )
1775  static_cast<SystemWindow*>(pParent)->Close();
1776  }
1777  }
1778  }
1779  else
1780  {
1782  }
1783 }
1784 
1786  : CancelButton(pParent, 0)
1787 {
1788  SetText( GetStandardText( StandardButtonType::Close ) );
1789 }
1790 
1791 void HelpButton::ImplInit( vcl::Window* pParent, WinBits nStyle )
1792 {
1793  set_id("help");
1794  PushButton::ImplInit( pParent, nStyle | WB_NOPOINTERFOCUS );
1795 
1796  SetText( GetStandardText( StandardButtonType::Help ) );
1797 }
1798 
1801 {
1802  ImplInit( pParent, nStyle );
1803 }
1804 
1806 {
1807  // trigger help if no link set
1808  if ( !GetClickHdl() )
1809  {
1811  if ( !pFocusWin || comphelper::LibreOfficeKit::isActive() )
1812  pFocusWin = this;
1813 
1814  HelpEvent aEvt( pFocusWin->GetPointerPosPixel(), HelpEventMode::CONTEXT );
1815  pFocusWin->RequestHelp( aEvt );
1816  }
1818 }
1819 
1821 {
1822  // Hide when we have no help URL.
1824  officecfg::Office::Common::Help::HelpRootURL::get().isEmpty())
1825  Hide();
1826  else
1827  PushButton::StateChanged(nStateChange);
1828 }
1829 
1831 {
1832  mbChecked = false;
1833  mbRadioCheck = true;
1834  mbStateChanged = false;
1835 }
1836 
1838 {
1839  nStyle = ImplInitStyle(getPreviousSibling(pParent), nStyle);
1840  Button::ImplInit( pParent, nStyle, nullptr );
1841 
1842  ImplInitSettings( true );
1843 }
1844 
1846 {
1847  if ( !(nStyle & WB_NOGROUP) &&
1848  (!pPrevWindow || (pPrevWindow->GetType() != WindowType::RADIOBUTTON)) )
1849  nStyle |= WB_GROUP;
1850  if ( !(nStyle & WB_NOTABSTOP) )
1851  {
1852  if ( IsChecked() )
1853  nStyle |= WB_TABSTOP;
1854  else
1855  nStyle &= ~WB_TABSTOP;
1856  }
1857 
1858  return nStyle;
1859 }
1860 
1862 {
1863  return _rStyle.GetRadioCheckFont();
1864 }
1865 
1867 {
1868  return _rStyle.GetRadioCheckTextColor();
1869 }
1870 
1871 void RadioButton::ImplInitSettings( bool bBackground )
1872 {
1874 
1875  if ( !bBackground )
1876  return;
1877 
1878  vcl::Window* pParent = GetParent();
1879  if ( !IsControlBackground() &&
1881  {
1884  SetPaintTransparent( true );
1885  SetBackground();
1887  mpWindowImpl->mbUseNativeFocus = ImplGetSVData()->maNWFData.mbNoFocusRects;
1888  }
1889  else
1890  {
1891  EnableChildTransparentMode( false );
1893  SetPaintTransparent( false );
1894 
1895  if ( IsControlBackground() )
1897  else
1898  SetBackground( pParent->GetBackground() );
1899  }
1900 }
1901 
1903 {
1904  bool bNativeOK = false;
1905 
1906  // no native drawing for image radio buttons
1908  {
1912 
1914  nState |= ControlState::PRESSED;
1915  if (HasFocus())
1916  nState |= ControlState::FOCUSED;
1918  nState |= ControlState::DEFAULT;
1919  if (IsEnabled())
1920  nState |= ControlState::ENABLED;
1921 
1923  nState |= ControlState::ROLLOVER;
1924 
1925  bNativeOK = rRenderContext.DrawNativeControl(ControlType::Radiobutton, ControlPart::Entire, aCtrlRect,
1926  nState, aControlValue, OUString());
1927  }
1928 
1929  if (bNativeOK)
1930  return;
1931 
1932  if (!maImage)
1933  {
1934  DrawButtonFlags nStyle = GetButtonState();
1935  if (!IsEnabled())
1936  nStyle |= DrawButtonFlags::Disabled;
1937  if (mbChecked)
1938  nStyle |= DrawButtonFlags::Checked;
1939  Image aImage = GetRadioImage(rRenderContext.GetSettings(), nStyle);
1940  if (IsZoom())
1941  rRenderContext.DrawImage(maStateRect.TopLeft(), maStateRect.GetSize(), aImage);
1942  else
1943  rRenderContext.DrawImage(maStateRect.TopLeft(), aImage);
1944  }
1945  else
1946  {
1947  HideFocus();
1948 
1949  DecorationView aDecoView(&rRenderContext);
1950  const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
1951  tools::Rectangle aImageRect = maStateRect;
1952  Size aImageSize = maImage.GetSizePixel();
1953  bool bEnabled = IsEnabled();
1954 
1955  aImageSize.setWidth( CalcZoom(aImageSize.Width()) );
1956  aImageSize.setHeight( CalcZoom(aImageSize.Height()) );
1957 
1958  aImageRect.AdjustLeft( 1 );
1959  aImageRect.AdjustTop( 1 );
1960  aImageRect.AdjustRight( -1 );
1961  aImageRect.AdjustBottom( -1 );
1962 
1963  // display border and selection status
1964  aImageRect = aDecoView.DrawFrame(aImageRect, DrawFrameStyle::DoubleIn);
1965  if ((GetButtonState() & DrawButtonFlags::Pressed) || !bEnabled)
1966  rRenderContext.SetFillColor( rStyleSettings.GetFaceColor());
1967  else
1968  rRenderContext.SetFillColor(rStyleSettings.GetFieldColor());
1969  rRenderContext.SetLineColor();
1970  rRenderContext.DrawRect(aImageRect);
1971 
1972  // display image
1973  DrawImageFlags nImageStyle = DrawImageFlags::NONE;
1974  if (!bEnabled)
1975  nImageStyle |= DrawImageFlags::Disable;
1976 
1977  Image* pImage = &maImage;
1978 
1979  Point aImagePos(aImageRect.TopLeft());
1980  aImagePos.AdjustX((aImageRect.GetWidth() - aImageSize.Width()) / 2 );
1981  aImagePos.AdjustY((aImageRect.GetHeight() - aImageSize.Height()) / 2 );
1982  if (IsZoom())
1983  rRenderContext.DrawImage(aImagePos, aImageSize, *pImage, nImageStyle);
1984  else
1985  rRenderContext.DrawImage(aImagePos, *pImage, nImageStyle);
1986 
1987  aImageRect.AdjustLeft( 1 );
1988  aImageRect.AdjustTop( 1 );
1989  aImageRect.AdjustRight( -1 );
1990  aImageRect.AdjustBottom( -1 );
1991 
1992  ImplSetFocusRect(aImageRect);
1993 
1994  if (mbChecked)
1995  {
1996  rRenderContext.SetLineColor(rStyleSettings.GetHighlightColor());
1997  rRenderContext.SetFillColor();
1998  if ((aImageSize.Width() >= 20) || (aImageSize.Height() >= 20))
1999  {
2000  aImageRect.AdjustLeft( 1 );
2001  aImageRect.AdjustTop( 1 );
2002  aImageRect.AdjustRight( -1 );
2003  aImageRect.AdjustBottom( -1 );
2004  }
2005  rRenderContext.DrawRect(aImageRect);
2006  aImageRect.AdjustLeft( 1 );
2007  aImageRect.AdjustTop( 1 );
2008  aImageRect.AdjustRight( -1 );
2009  aImageRect.AdjustBottom( -1 );
2010  rRenderContext.DrawRect(aImageRect);
2011  }
2012 
2013  if (HasFocus())
2015  }
2016 }
2017 
2018 // for drawing RadioButton or CheckButton that has Text and/or Image
2019 void Button::ImplDrawRadioCheck(OutputDevice* pDev, WinBits nWinStyle, DrawFlags nDrawFlags,
2020  const Point& rPos, const Size& rSize,
2021  const Size& rImageSize, tools::Rectangle& rStateRect,
2022  tools::Rectangle& rMouseRect)
2023 {
2024  DrawTextFlags nTextStyle = Button::ImplGetTextStyle( nWinStyle, nDrawFlags );
2025 
2026  const tools::Long nImageSep = GetDrawPixel( pDev, ImplGetImageToTextDistance() );
2027  Size aSize( rSize );
2028  Point aPos( rPos );
2029  aPos.AdjustX(rImageSize.Width() + nImageSep );
2030 
2031  // tdf#141761 Old (convenience?) adjustment of width may lead to empty
2032  // or negative(!) Size, that needs to be avoided. The coordinate context
2033  // is pixel-oriented (all Paints of Controls are, historically), so
2034  // the minimum width should be '1' Pixel.
2035  // Hint: nImageSep is based on Zoom (using Window::CalcZoom) and
2036  // MapModes (using Window::GetDrawPixel) - so potentially a wide range
2037  // of unpredictable values is possible
2038  const tools::Long nWidthAdjust(rImageSize.Width() + nImageSep);
2039  aSize.setWidth(std::max(static_cast<tools::Long>(1), aSize.getWidth() - nWidthAdjust));
2040 
2041  // if the text rect height is smaller than the height of the image
2042  // then for single lines the default should be centered text
2043  if( (nWinStyle & (WB_TOP|WB_VCENTER|WB_BOTTOM)) == 0 &&
2044  (rImageSize.Height() > rSize.Height() || ! (nWinStyle & WB_WORDBREAK) ) )
2045  {
2047  nTextStyle |= DrawTextFlags::VCenter;
2048  aSize.setHeight( rImageSize.Height() );
2049  }
2050 
2051  ImplDrawAlignedImage( pDev, aPos, aSize, 1, nTextStyle );
2052 
2053  rMouseRect = tools::Rectangle( aPos, aSize );
2054  rMouseRect.SetLeft( rPos.X() );
2055 
2056  rStateRect.SetLeft( rPos.X() );
2057  rStateRect.SetTop( rMouseRect.Top() );
2058 
2059  if ( aSize.Height() > rImageSize.Height() )
2060  rStateRect.AdjustTop(( aSize.Height() - rImageSize.Height() ) / 2 );
2061  else
2062  {
2063  rStateRect.AdjustTop( -(( rImageSize.Height() - aSize.Height() ) / 2) );
2064  if( rStateRect.Top() < 0 )
2065  rStateRect.SetTop( 0 );
2066  }
2067 
2068  rStateRect.SetRight( rStateRect.Left()+rImageSize.Width()-1 );
2069  rStateRect.SetBottom( rStateRect.Top()+rImageSize.Height()-1 );
2070 
2071  if ( rStateRect.Bottom() > rMouseRect.Bottom() )
2072  rMouseRect.SetBottom( rStateRect.Bottom() );
2073 }
2074 
2076  const Point& rPos, const Size& rSize,
2077  const Size& rImageSize, tools::Rectangle& rStateRect,
2078  tools::Rectangle& rMouseRect )
2079 {
2080  WinBits nWinStyle = GetStyle();
2081  OUString aText( GetText() );
2082 
2083  pDev->Push( PushFlags::CLIPREGION );
2084  pDev->IntersectClipRegion( tools::Rectangle( rPos, rSize ) );
2085 
2086  // no image radio button
2087  if ( !maImage )
2088  {
2089  if (!aText.isEmpty() || HasImage())
2090  {
2091  Button::ImplDrawRadioCheck(pDev, nWinStyle, nDrawFlags,
2092  rPos, rSize, rImageSize,
2093  rStateRect, rMouseRect);
2094  }
2095  else
2096  {
2097  rStateRect.SetLeft( rPos.X() );
2098  if ( nWinStyle & WB_VCENTER )
2099  rStateRect.SetTop( rPos.Y()+((rSize.Height()-rImageSize.Height())/2) );
2100  else if ( nWinStyle & WB_BOTTOM )
2101  rStateRect.SetTop( rPos.Y()+rSize.Height()-rImageSize.Height() ); //-1;
2102  else
2103  rStateRect.SetTop( rPos.Y() );
2104  rStateRect.SetRight( rStateRect.Left()+rImageSize.Width()-1 );
2105  rStateRect.SetBottom( rStateRect.Top()+rImageSize.Height()-1 );
2106  rMouseRect = rStateRect;
2107 
2108  ImplSetFocusRect( rStateRect );
2109  }
2110  }
2111  else
2112  {
2113  bool bTopImage = (nWinStyle & WB_TOP) != 0;
2114  Size aImageSize = maImage.GetSizePixel();
2115  tools::Rectangle aImageRect( rPos, rSize );
2116  tools::Long nTextHeight = pDev->GetTextHeight();
2117  tools::Long nTextWidth = pDev->GetCtrlTextWidth( aText );
2118 
2119  // calculate position and sizes
2120  if (!aText.isEmpty())
2121  {
2122  Size aTmpSize( (aImageSize.Width()+8), (aImageSize.Height()+8) );
2123  if ( bTopImage )
2124  {
2125  aImageRect.SetLeft( (rSize.Width()-aTmpSize.Width())/2 );
2126  aImageRect.SetTop( (rSize.Height()-(aTmpSize.Height()+nTextHeight+6))/2 );
2127  }
2128  else
2129  aImageRect.SetTop( (rSize.Height()-aTmpSize.Height())/2 );
2130 
2131  aImageRect.SetRight( aImageRect.Left()+aTmpSize.Width() );
2132  aImageRect.SetBottom( aImageRect.Top()+aTmpSize.Height() );
2133 
2134  // display text
2135  Point aTxtPos = rPos;
2136  if ( bTopImage )
2137  {
2138  aTxtPos.AdjustX((rSize.Width()-nTextWidth)/2 );
2139  aTxtPos.AdjustY(aImageRect.Bottom()+6 );
2140  }
2141  else
2142  {
2143  aTxtPos.AdjustX(aImageRect.Right()+8 );
2144  aTxtPos.AdjustY((rSize.Height()-nTextHeight)/2 );
2145  }
2146  pDev->DrawCtrlText( aTxtPos, aText, 0, aText.getLength() );
2147  }
2148 
2149  rMouseRect = aImageRect;
2150  rStateRect = aImageRect;
2151  }
2152 
2153  pDev->Pop();
2154 }
2155 
2157 {
2158  HideFocus();
2159 
2160  Size aImageSize;
2161  if (!maImage)
2162  aImageSize = ImplGetRadioImageSize();
2163  else
2164  aImageSize = maImage.GetSizePixel();
2165 
2166  aImageSize.setWidth( CalcZoom(aImageSize.Width()) );
2167  aImageSize.setHeight( CalcZoom(aImageSize.Height()) );
2168 
2169  // Draw control text
2170  ImplDraw(&rRenderContext, DrawFlags::NONE, Point(), GetOutputSizePixel(),
2171  aImageSize, maStateRect, maMouseRect);
2172 
2173  if (!maImage && HasFocus())
2175 
2176  ImplDrawRadioButtonState(rRenderContext);
2177 }
2178 
2180 {
2181  if (&rOther == this)
2182  return;
2183 
2184  if (!m_xGroup)
2185  {
2186  m_xGroup = std::make_shared<std::vector<VclPtr<RadioButton> >>();
2187  m_xGroup->push_back(this);
2188  }
2189 
2190  auto aFind = std::find(m_xGroup->begin(), m_xGroup->end(), VclPtr<RadioButton>(&rOther));
2191  if (aFind == m_xGroup->end())
2192  {
2193  m_xGroup->push_back(&rOther);
2194 
2195  if (rOther.m_xGroup)
2196  {
2197  std::vector< VclPtr<RadioButton> > aOthers(rOther.GetRadioButtonGroup(false));
2198  //make all members of the group share the same button group
2199  for (auto const& elem : aOthers)
2200  {
2201  aFind = std::find(m_xGroup->begin(), m_xGroup->end(), elem);
2202  if (aFind == m_xGroup->end())
2203  m_xGroup->push_back(elem);
2204  }
2205  }
2206 
2207  //make all members of the group share the same button group
2208  for (VclPtr<RadioButton> const & pButton : *m_xGroup)
2209  {
2210  pButton->m_xGroup = m_xGroup;
2211  }
2212  }
2213 
2214  //if this one is checked, uncheck all the others
2215  if (mbChecked)
2217 }
2218 
2219 std::vector< VclPtr<RadioButton> > RadioButton::GetRadioButtonGroup(bool bIncludeThis) const
2220 {
2221  if (m_xGroup)
2222  {
2223  if (bIncludeThis)
2224  return *m_xGroup;
2225  std::vector< VclPtr<RadioButton> > aGroup;
2226  for (VclPtr<RadioButton> const & pRadioButton : *m_xGroup)
2227  {
2228  if (pRadioButton == this)
2229  continue;
2230  aGroup.push_back(pRadioButton);
2231  }
2232  return aGroup;
2233  }
2234 
2235  std::vector<VclPtr<RadioButton>> aGroup;
2236  if (mbUsesExplicitGroup)
2237  return aGroup;
2238 
2239  //old-school
2240 
2241  // go back to first in group;
2242  vcl::Window* pFirst = const_cast<RadioButton*>(this);
2243  while( ( pFirst->GetStyle() & WB_GROUP ) == 0 )
2244  {
2245  vcl::Window* pWindow = pFirst->GetWindow( GetWindowType::Prev );
2246  if( pWindow )
2247  pFirst = pWindow;
2248  else
2249  break;
2250  }
2251  // insert radiobuttons up to next group
2252  do
2253  {
2254  if( pFirst->GetType() == WindowType::RADIOBUTTON )
2255  {
2256  if( pFirst != this || bIncludeThis )
2257  aGroup.emplace_back(static_cast<RadioButton*>(pFirst) );
2258  }
2259  pFirst = pFirst->GetWindow( GetWindowType::Next );
2260  } while( pFirst && ( ( pFirst->GetStyle() & WB_GROUP ) == 0 ) );
2261 
2262  return aGroup;
2263 }
2264 
2266 {
2267  mpWindowImpl->mnStyle |= WB_TABSTOP;
2268 
2269  std::vector<VclPtr<RadioButton> > aGroup(GetRadioButtonGroup(false));
2270  // iterate over radio button group and checked buttons
2271  for (VclPtr<RadioButton>& pWindow : aGroup)
2272  {
2273  if ( pWindow->IsChecked() )
2274  {
2275  pWindow->SetState( false );
2276  if ( pWindow->isDisposed() )
2277  return;
2278  }
2279 
2280  // not inside if clause to always remove wrongly set WB_TABSTOPS
2281  pWindow->mpWindowImpl->mnStyle &= ~WB_TABSTOP;
2282  }
2283 }
2284 
2285 void RadioButton::ImplCallClick( bool bGrabFocus, GetFocusFlags nFocusFlags )
2286 {
2288  mbChecked = true;
2289  mpWindowImpl->mnStyle |= WB_TABSTOP;
2290  Invalidate();
2291  VclPtr<vcl::Window> xWindow = this;
2292  if ( mbRadioCheck )
2294  if ( xWindow->isDisposed() )
2295  return;
2296  if ( bGrabFocus )
2297  ImplGrabFocus( nFocusFlags );
2298  if ( xWindow->isDisposed() )
2299  return;
2300  if ( mbStateChanged )
2301  Toggle();
2302  if ( xWindow->isDisposed() )
2303  return;
2304  Click();
2305  if ( xWindow->isDisposed() )
2306  return;
2307  mbStateChanged = false;
2308 }
2309 
2310 RadioButton::RadioButton(vcl::Window* pParent, bool bUsesExplicitGroup, WinBits nStyle)
2312  , mbUsesExplicitGroup(bUsesExplicitGroup)
2313 {
2315  ImplInit( pParent, nStyle );
2316 }
2317 
2319 {
2320  disposeOnce();
2321 }
2322 
2324 {
2325  if (m_xGroup)
2326  {
2327  m_xGroup->erase(std::remove(m_xGroup->begin(), m_xGroup->end(), VclPtr<RadioButton>(this)),
2328  m_xGroup->end());
2329  m_xGroup.reset();
2330  }
2331  Button::dispose();
2332 }
2333 
2335 {
2336  if ( rMEvt.IsLeft() && maMouseRect.IsInside( rMEvt.GetPosPixel() ) )
2337  {
2339  Invalidate();
2340  StartTracking();
2341  return;
2342  }
2343 
2344  Button::MouseButtonDown( rMEvt );
2345 }
2346 
2348 {
2349  if ( rTEvt.IsTrackingEnded() )
2350  {
2352  {
2353  if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() )
2354  GrabFocus();
2355 
2357 
2358  // do not call click handler if aborted
2359  if ( !rTEvt.IsTrackingCanceled() )
2360  ImplCallClick();
2361  else
2362  {
2363  Invalidate();
2364  }
2365  }
2366  }
2367  else
2368  {
2369  if ( maMouseRect.IsInside( rTEvt.GetMouseEvent().GetPosPixel() ) )
2370  {
2372  {
2374  Invalidate();
2375  }
2376  }
2377  else
2378  {
2380  {
2382  Invalidate();
2383  }
2384  }
2385  }
2386 }
2387 
2388 void RadioButton::KeyInput( const KeyEvent& rKEvt )
2389 {
2390  vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
2391 
2392  if ( !aKeyCode.GetModifier() && (aKeyCode.GetCode() == KEY_SPACE) )
2393  {
2395  {
2397  Invalidate();
2398  }
2399  }
2400  else if ( (GetButtonState() & DrawButtonFlags::Pressed) && (aKeyCode.GetCode() == KEY_ESCAPE) )
2401  {
2403  Invalidate();
2404  }
2405  else
2406  Button::KeyInput( rKEvt );
2407 }
2408 
2409 void RadioButton::KeyUp( const KeyEvent& rKEvt )
2410 {
2411  vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
2412 
2413  if ( (GetButtonState() & DrawButtonFlags::Pressed) && (aKeyCode.GetCode() == KEY_SPACE) )
2414  {
2416  ImplCallClick();
2417  }
2418  else
2419  Button::KeyUp( rKEvt );
2420 }
2421 
2423 {
2424  mpControlData->mpLayoutData.reset( new vcl::ControlLayoutData );
2425  const_cast<RadioButton*>(this)->Invalidate();
2426 }
2427 
2429 {
2430  ImplDrawRadioButton(rRenderContext);
2431 }
2432 
2433 void RadioButton::Draw( OutputDevice* pDev, const Point& rPos,
2434  DrawFlags nFlags )
2435 {
2436  if ( !maImage )
2437  {
2438  MapMode aResMapMode( MapUnit::Map100thMM );
2439  Point aPos = pDev->LogicToPixel( rPos );
2440  Size aSize = GetSizePixel();
2441  Size aImageSize = pDev->LogicToPixel( Size( 300, 300 ), aResMapMode );
2442  Size aBrd1Size = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode );
2443  Size aBrd2Size = pDev->LogicToPixel( Size( 60, 60 ), aResMapMode );
2444  vcl::Font aFont = GetDrawPixelFont( pDev );
2445  tools::Rectangle aStateRect;
2446  tools::Rectangle aMouseRect;
2447 
2448  aImageSize.setWidth( CalcZoom( aImageSize.Width() ) );
2449  aImageSize.setHeight( CalcZoom( aImageSize.Height() ) );
2450  aBrd1Size.setWidth( CalcZoom( aBrd1Size.Width() ) );
2451  aBrd1Size.setHeight( CalcZoom( aBrd1Size.Height() ) );
2452  aBrd2Size.setWidth( CalcZoom( aBrd2Size.Width() ) );
2453  aBrd2Size.setHeight( CalcZoom( aBrd2Size.Height() ) );
2454 
2455  if ( !aBrd1Size.Width() )
2456  aBrd1Size.setWidth( 1 );
2457  if ( !aBrd1Size.Height() )
2458  aBrd1Size.setHeight( 1 );
2459  if ( !aBrd2Size.Width() )
2460  aBrd2Size.setWidth( 1 );
2461  if ( !aBrd2Size.Height() )
2462  aBrd2Size.setHeight( 1 );
2463 
2464  pDev->Push();
2465  pDev->SetMapMode();
2466  pDev->SetFont( aFont );
2467  if ( nFlags & DrawFlags::Mono )
2468  pDev->SetTextColor( COL_BLACK );
2469  else
2470  pDev->SetTextColor( GetTextColor() );
2471  pDev->SetTextFillColor();
2472 
2473  ImplDraw( pDev, nFlags, aPos, aSize,
2474  aImageSize, aStateRect, aMouseRect );
2475 
2476  Point aCenterPos = aStateRect.Center();
2477  tools::Long nRadX = aImageSize.Width()/2;
2478  tools::Long nRadY = aImageSize.Height()/2;
2479 
2480  pDev->SetLineColor();
2481  pDev->SetFillColor( COL_BLACK );
2482  pDev->DrawPolygon( tools::Polygon( aCenterPos, nRadX, nRadY ) );
2483  nRadX -= aBrd1Size.Width();
2484  nRadY -= aBrd1Size.Height();
2485  pDev->SetFillColor( COL_WHITE );
2486  pDev->DrawPolygon( tools::Polygon( aCenterPos, nRadX, nRadY ) );
2487  if ( mbChecked )
2488  {
2489  nRadX -= aBrd1Size.Width();
2490  nRadY -= aBrd1Size.Height();
2491  if ( !nRadX )
2492  nRadX = 1;
2493  if ( !nRadY )
2494  nRadY = 1;
2495  pDev->SetFillColor( COL_BLACK );
2496  pDev->DrawPolygon( tools::Polygon( aCenterPos, nRadX, nRadY ) );
2497  }
2498 
2499  pDev->Pop();
2500  }
2501  else
2502  {
2503  OSL_FAIL( "RadioButton::Draw() - not implemented for RadioButton with Image" );
2504  }
2505 }
2506 
2508 {
2509  Control::Resize();
2510  Invalidate();
2511 }
2512 
2514 {
2517  Button::GetFocus();
2518 }
2519 
2521 {
2523  {
2525  Invalidate();
2526  }
2527 
2528  HideFocus();
2530 }
2531 
2533 {
2534  Button::StateChanged( nType );
2535 
2536  if ( nType == StateChangedType::State )
2537  {
2538  if ( IsReallyVisible() && IsUpdateMode() )
2540  }
2541  else if ( (nType == StateChangedType::Enable) ||
2542  (nType == StateChangedType::Text) ||
2543  (nType == StateChangedType::Data) ||
2544  (nType == StateChangedType::UpdateMode) )
2545  {
2546  if ( IsUpdateMode() )
2547  Invalidate();
2548  }
2549  else if ( nType == StateChangedType::Style )
2550  {
2552 
2553  if ( (GetPrevStyle() & RADIOBUTTON_VIEW_STYLE) !=
2555  {
2556  if ( IsUpdateMode() )
2557  Invalidate();
2558  }
2559  }
2560  else if ( (nType == StateChangedType::Zoom) ||
2561  (nType == StateChangedType::ControlFont) )
2562  {
2563  ImplInitSettings( false );
2564  Invalidate();
2565  }
2566  else if ( nType == StateChangedType::ControlForeground )
2567  {
2568  ImplInitSettings( false );
2569  Invalidate();
2570  }
2571  else if ( nType == StateChangedType::ControlBackground )
2572  {
2573  ImplInitSettings( true );
2574  Invalidate();
2575  }
2576 }
2577 
2579 {
2580  Button::DataChanged( rDCEvt );
2581 
2582  if ( (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
2584  ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
2585  (rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
2586  {
2587  ImplInitSettings( true );
2588  Invalidate();
2589  }
2590 }
2591 
2593 {
2594  if( rNEvt.GetType() == MouseNotifyEvent::MOUSEMOVE )
2595  {
2596  const MouseEvent* pMouseEvt = rNEvt.GetMouseEvent();
2597  if( pMouseEvt && !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() )
2598  {
2599  // trigger redraw if mouse over state has changed
2601  {
2603  pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow())
2604  {
2606  }
2607  }
2608  }
2609  }
2610 
2611  return Button::PreNotify(rNEvt);
2612 }
2613 
2615 {
2617 }
2618 
2620 {
2621  if ( rImage != maImage )
2622  {
2623  maImage = rImage;
2625  queue_resize();
2626  }
2627 }
2628 
2629 
2630 void RadioButton::SetState( bool bCheck )
2631 {
2632  // carry the TabStop flag along correctly
2633  if ( bCheck )
2634  mpWindowImpl->mnStyle |= WB_TABSTOP;
2635  else
2636  mpWindowImpl->mnStyle &= ~WB_TABSTOP;
2637 
2638  if ( mbChecked != bCheck )
2639  {
2640  mbChecked = bCheck;
2642  Toggle();
2643  }
2644 }
2645 
2646 bool RadioButton::set_property(const OString &rKey, const OUString &rValue)
2647 {
2648  if (rKey == "active")
2649  SetState(toBool(rValue));
2650  else if (rKey == "image-position")
2651  {
2652  WinBits nBits = GetStyle();
2653  if (rValue == "left")
2654  {
2655  nBits &= ~(WB_CENTER | WB_RIGHT);
2656  nBits |= WB_LEFT;
2657  }
2658  else if (rValue == "right")
2659  {
2660  nBits &= ~(WB_CENTER | WB_LEFT);
2661  nBits |= WB_RIGHT;
2662  }
2663  else if (rValue == "top")
2664  {
2665  nBits &= ~(WB_VCENTER | WB_BOTTOM);
2666  nBits |= WB_TOP;
2667  }
2668  else if (rValue == "bottom")
2669  {
2670  nBits &= ~(WB_VCENTER | WB_TOP);
2671  nBits |= WB_BOTTOM;
2672  }
2673  //It's rather mad to have to set these bits when there is the other
2674  //image align. Looks like e.g. the radiobuttons etc weren't converted
2675  //over to image align fully.
2676  SetStyle(nBits);
2677  //Deliberate to set the sane ImageAlign property
2678  return Button::set_property(rKey, rValue);
2679  }
2680  else
2681  return Button::set_property(rKey, rValue);
2682  return true;
2683 }
2684 
2685 void RadioButton::Check( bool bCheck )
2686 {
2687  // TabStop-Flag richtig mitfuehren
2688  if ( bCheck )
2689  mpWindowImpl->mnStyle |= WB_TABSTOP;
2690  else
2691  mpWindowImpl->mnStyle &= ~WB_TABSTOP;
2692 
2693  if ( mbChecked == bCheck )
2694  return;
2695 
2696  mbChecked = bCheck;
2697  VclPtr<vcl::Window> xWindow = this;
2699  if ( xWindow->isDisposed() )
2700  return;
2701  if ( bCheck && mbRadioCheck )
2703  if ( xWindow->isDisposed() )
2704  return;
2705  Toggle();
2706 }
2707 
2709 {
2710  // 4 pixels, but take zoom into account, so the text doesn't "jump" relative to surrounding elements,
2711  // which might have been aligned with the text of the check box
2712  return CalcZoom( 4 );
2713 }
2714 
2716 {
2717  Size aSize;
2718  bool bDefaultSize = true;
2720  {
2721  ImplControlValue aControlValue;
2722  tools::Rectangle aCtrlRegion( Point( 0, 0 ), GetSizePixel() );
2723  tools::Rectangle aBoundingRgn, aContentRgn;
2724 
2725  // get native size of a radio button
2728  aControlValue,
2729  aBoundingRgn, aContentRgn ) )
2730  {
2731  aSize = aContentRgn.GetSize();
2732  bDefaultSize = false;
2733  }
2734  }
2735  if( bDefaultSize )
2737  return aSize;
2738 }
2739 
2740 static void LoadThemedImageList(const StyleSettings &rStyleSettings,
2741  std::vector<Image>& rList, const std::vector<OUString> &rResources)
2742 {
2743  Color aColorAry1[6];
2744  Color aColorAry2[6];
2745  aColorAry1[0] = Color( 0xC0, 0xC0, 0xC0 );
2746  aColorAry1[1] = Color( 0xFF, 0xFF, 0x00 );
2747  aColorAry1[2] = Color( 0xFF, 0xFF, 0xFF );
2748  aColorAry1[3] = Color( 0x80, 0x80, 0x80 );
2749  aColorAry1[4] = Color( 0x00, 0x00, 0x00 );
2750  aColorAry1[5] = Color( 0x00, 0xFF, 0x00 );
2751  aColorAry2[0] = rStyleSettings.GetFaceColor();
2752  aColorAry2[1] = rStyleSettings.GetWindowColor();
2753  aColorAry2[2] = rStyleSettings.GetLightColor();
2754  aColorAry2[3] = rStyleSettings.GetShadowColor();
2755  aColorAry2[4] = rStyleSettings.GetDarkShadowColor();
2756  aColorAry2[5] = rStyleSettings.GetWindowTextColor();
2757 
2758  static_assert( sizeof(aColorAry1) == sizeof(aColorAry2), "aColorAry1 must match aColorAry2" );
2759 
2760  for (const auto &a : rResources)
2761  {
2762  BitmapEx aBmpEx(a);
2763  aBmpEx.Replace(aColorAry1, aColorAry2, SAL_N_ELEMENTS(aColorAry1));
2764  rList.emplace_back(aBmpEx);
2765  }
2766 }
2767 
2769 {
2770  ImplSVData* pSVData = ImplGetSVData();
2771  const StyleSettings& rStyleSettings = rSettings.GetStyleSettings();
2772  sal_uInt16 nStyle = 0;
2773 
2774  if ( rStyleSettings.GetOptions() & StyleSettingsOptions::Mono )
2775  nStyle = STYLE_RADIOBUTTON_MONO;
2776 
2777  if ( pSVData->maCtrlData.maRadioImgList.empty() ||
2778  (pSVData->maCtrlData.mnRadioStyle != nStyle) ||
2779  (pSVData->maCtrlData.mnLastRadioFColor != rStyleSettings.GetFaceColor()) ||
2780  (pSVData->maCtrlData.mnLastRadioWColor != rStyleSettings.GetWindowColor()) ||
2781  (pSVData->maCtrlData.mnLastRadioLColor != rStyleSettings.GetLightColor()) )
2782  {
2783  pSVData->maCtrlData.maRadioImgList.clear();
2784 
2785  pSVData->maCtrlData.mnLastRadioFColor = rStyleSettings.GetFaceColor();
2786  pSVData->maCtrlData.mnLastRadioWColor = rStyleSettings.GetWindowColor();
2787  pSVData->maCtrlData.mnLastRadioLColor = rStyleSettings.GetLightColor();
2788 
2789  std::vector<OUString> aResources;
2790  if (nStyle)
2791  {
2792  aResources.emplace_back(SV_RESID_BITMAP_RADIOMONO1);
2793  aResources.emplace_back(SV_RESID_BITMAP_RADIOMONO2);
2794  aResources.emplace_back(SV_RESID_BITMAP_RADIOMONO3);
2795  aResources.emplace_back(SV_RESID_BITMAP_RADIOMONO4);
2796  aResources.emplace_back(SV_RESID_BITMAP_RADIOMONO5);
2797  aResources.emplace_back(SV_RESID_BITMAP_RADIOMONO6);
2798  }
2799  else
2800  {
2801  aResources.emplace_back(SV_RESID_BITMAP_RADIO1);
2802  aResources.emplace_back(SV_RESID_BITMAP_RADIO2);
2803  aResources.emplace_back(SV_RESID_BITMAP_RADIO3);
2804  aResources.emplace_back(SV_RESID_BITMAP_RADIO4);
2805  aResources.emplace_back(SV_RESID_BITMAP_RADIO5);
2806  aResources.emplace_back(SV_RESID_BITMAP_RADIO6);
2807  }
2808  LoadThemedImageList( rStyleSettings, pSVData->maCtrlData.maRadioImgList, aResources);
2809  pSVData->maCtrlData.mnRadioStyle = nStyle;
2810  }
2811 
2812  sal_uInt16 nIndex;
2813  if ( nFlags & DrawButtonFlags::Disabled )
2814  {
2815  if ( nFlags & DrawButtonFlags::Checked )
2816  nIndex = 5;
2817  else
2818  nIndex = 4;
2819  }
2820  else if ( nFlags & DrawButtonFlags::Pressed )
2821  {
2822  if ( nFlags & DrawButtonFlags::Checked )
2823  nIndex = 3;
2824  else
2825  nIndex = 2;
2826  }
2827  else
2828  {
2829  if ( nFlags & DrawButtonFlags::Checked )
2830  nIndex = 1;
2831  else
2832  nIndex = 0;
2833  }
2834  return pSVData->maCtrlData.maRadioImgList[nIndex];
2835 }
2836 
2838 {
2840  SetMapMode(MapMode(MapUnit::MapPixel));
2841 
2842  ImplControlValue aControlValue;
2843  Size aCurSize( GetSizePixel() );
2844  tools::Rectangle aCtrlRegion( Point( 0, 0 ), aCurSize );
2845  tools::Rectangle aBoundingRgn, aContentRgn;
2846 
2847  // get native size of a radiobutton
2850  aBoundingRgn, aContentRgn ) )
2851  {
2852  Size aSize = aContentRgn.GetSize();
2853 
2854  if( aSize.Height() > aCurSize.Height() )
2855  {
2856  aCurSize.setHeight( aSize.Height() );
2857  SetSizePixel( aCurSize );
2858  }
2859  }
2860 
2861  GetOutDev()->Pop();
2862 }
2863 
2865 {
2866  Size aSize;
2867  if ( !maImage )
2868  aSize = ImplGetRadioImageSize();
2869  else
2870  {
2871  aSize = maImage.GetSizePixel();
2872  aSize.AdjustWidth(8);
2873  aSize.AdjustHeight(8);
2874  }
2875 
2876  if (Button::HasImage())
2877  {
2878  Size aImgSize = GetModeImage().GetSizePixel();
2879  aSize = Size(std::max(aImgSize.Width(), aSize.Width()),
2880  std::max(aImgSize.Height(), aSize.Height()));
2881  }
2882 
2883  OUString aText = GetText();
2884  if (!aText.isEmpty())
2885  {
2886  bool bTopImage = (GetStyle() & WB_TOP) != 0;
2887 
2888  Size aTextSize = GetTextRect( tools::Rectangle( Point(), Size( nMaxWidth > 0 ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ),
2890 
2891  aSize.AdjustWidth(2 ); // for focus rect
2892 
2893  if (!bTopImage)
2894  {
2896  aSize.AdjustWidth(aTextSize.Width() );
2897  if ( aSize.Height() < aTextSize.Height() )
2898  aSize.setHeight( aTextSize.Height() );
2899  }
2900  else
2901  {
2902  aSize.AdjustHeight(6 );
2903  aSize.AdjustHeight(GetTextHeight() );
2904  if ( aSize.Width() < aTextSize.Width() )
2905  aSize.setWidth( aTextSize.Width() );
2906  }
2907  }
2908 
2909  return CalcWindowSize( aSize );
2910 }
2911 
2913 {
2914  return CalcMinimumSize();
2915 }
2916 
2918 {
2920  {
2921  ImplControlValue aControlValue;
2922  tools::Rectangle aInRect(Point(0, 0), GetSizePixel());
2923 
2924  aInRect.SetLeft( rRect.Left() ); // exclude the radio element itself from the focusrect
2925 
2927  ControlState::FOCUSED, aControlValue, OUString());
2928  }
2929  Button::ShowFocus(rRect);
2930 }
2931 
2933 {
2934  Button::DumpAsPropertyTree(rJsonWriter);
2935  rJsonWriter.put("checked", IsChecked());
2936 
2937  OUString sGroupId;
2938  std::vector<VclPtr<RadioButton>> aGroup = GetRadioButtonGroup();
2939  for(auto& pButton : aGroup)
2940  sGroupId += pButton->get_id();
2941 
2942  if (!sGroupId.isEmpty())
2943  rJsonWriter.put("group", sGroupId);
2944 }
2945 
2947 {
2949 }
2950 
2952 {
2954  mbTriState = false;
2955 }
2956 
2957 void CheckBox::ImplInit( vcl::Window* pParent, WinBits nStyle )
2958 {
2959  nStyle = ImplInitStyle(getPreviousSibling(pParent), nStyle);
2960  Button::ImplInit( pParent, nStyle, nullptr );
2961 
2962  ImplInitSettings( true );
2963 }
2964 
2966 {
2967  if ( !(nStyle & WB_NOTABSTOP) )
2968  nStyle |= WB_TABSTOP;
2969  if ( !(nStyle & WB_NOGROUP) &&
2970  (!pPrevWindow || (pPrevWindow->GetType() != WindowType::CHECKBOX)) )
2971  nStyle |= WB_GROUP;
2972  return nStyle;
2973 }
2974 
2976 {
2977  return _rStyle.GetRadioCheckFont();
2978 }
2979 
2981 {
2982  return _rStyle.GetRadioCheckTextColor();
2983 }
2984 
2985 void CheckBox::ImplInitSettings( bool bBackground )
2986 {
2988 
2989  if ( !bBackground )
2990  return;
2991 
2992  vcl::Window* pParent = GetParent();
2993  if ( !IsControlBackground() &&
2995  {
2998  SetPaintTransparent( true );
2999  SetBackground();
3002  }
3003  else
3004  {
3005  EnableChildTransparentMode( false );
3007  SetPaintTransparent( false );
3008 
3009  if ( IsControlBackground() )
3011  else
3012  SetBackground( pParent->GetBackground() );
3013  }
3014 }
3015 
3017 {
3018  bool bNativeOK = rRenderContext.IsNativeControlSupported(ControlType::Checkbox, ControlPart::Entire);
3019  if (bNativeOK)
3020  {
3022  tools::Rectangle aCtrlRegion(maStateRect);
3024 
3025  if (HasFocus())
3026  nState |= ControlState::FOCUSED;
3028  nState |= ControlState::DEFAULT;
3030  nState |= ControlState::PRESSED;
3031  if (IsEnabled())
3032  nState |= ControlState::ENABLED;
3033 
3034  if (meState == TRISTATE_TRUE)
3035  aControlValue.setTristateVal(ButtonValue::On);
3036  else if (meState == TRISTATE_INDET)
3037  aControlValue.setTristateVal(ButtonValue::Mixed);
3038 
3040  nState |= ControlState::ROLLOVER;
3041 
3042  bNativeOK = rRenderContext.DrawNativeControl(ControlType::Checkbox, ControlPart::Entire, aCtrlRegion,
3043  nState, aControlValue, OUString());
3044  }
3045 
3046  if (bNativeOK)
3047  return;
3048 
3049  DrawButtonFlags nStyle = GetButtonState();
3050  if (!IsEnabled())
3051  nStyle |= DrawButtonFlags::Disabled;
3052  if (meState == TRISTATE_INDET)
3053  nStyle |= DrawButtonFlags::DontKnow;
3054  else if (meState == TRISTATE_TRUE)
3055  nStyle |= DrawButtonFlags::Checked;
3056  Image aImage = GetCheckImage(GetSettings(), nStyle);
3057  if (IsZoom())
3058  rRenderContext.DrawImage(maStateRect.TopLeft(), maStateRect.GetSize(), aImage);
3059  else
3060  rRenderContext.DrawImage(maStateRect.TopLeft(), aImage);
3061 }
3062 
3064  const Point& rPos, const Size& rSize,
3065  const Size& rImageSize, tools::Rectangle& rStateRect,
3066  tools::Rectangle& rMouseRect )
3067 {
3068  WinBits nWinStyle = GetStyle();
3069  OUString aText( GetText() );
3070 
3072  pDev->IntersectClipRegion( tools::Rectangle( rPos, rSize ) );
3073 
3074  if (!aText.isEmpty() || HasImage())
3075  {
3076  Button::ImplDrawRadioCheck(pDev, nWinStyle, nDrawFlags,
3077  rPos, rSize, rImageSize,
3078  rStateRect, rMouseRect);
3079  }
3080  else
3081  {
3082  rStateRect.SetLeft( rPos.X() );
3083  if ( nWinStyle & WB_VCENTER )
3084  rStateRect.SetTop( rPos.Y()+((rSize.Height()-rImageSize.Height())/2) );
3085  else if ( nWinStyle & WB_BOTTOM )
3086  rStateRect.SetTop( rPos.Y()+rSize.Height()-rImageSize.Height() );
3087  else
3088  rStateRect.SetTop( rPos.Y() );
3089  rStateRect.SetRight( rStateRect.Left()+rImageSize.Width()-1 );
3090  rStateRect.SetBottom( rStateRect.Top()+rImageSize.Height()-1 );
3091  // provide space for focusrect
3092  // note: this assumes that the control's size was adjusted
3093  // accordingly in Get/LoseFocus, so the onscreen position won't change
3094  if( HasFocus() )
3095  rStateRect.Move( 1, 1 );
3096  rMouseRect = rStateRect;
3097 
3098  ImplSetFocusRect( rStateRect );
3099  }
3100 
3101  pDev->Pop();
3102 }
3103 
3105 {
3106  Size aImageSize = ImplGetCheckImageSize();
3107  aImageSize.setWidth( CalcZoom( aImageSize.Width() ) );
3108  aImageSize.setHeight( CalcZoom( aImageSize.Height() ) );
3109 
3110  HideFocus();
3111 
3112  ImplDraw(&rRenderContext, DrawFlags::NONE, Point(), GetOutputSizePixel(),
3113  aImageSize, maStateRect, maMouseRect);
3114 
3115  ImplDrawCheckBoxState(rRenderContext);
3116  if (HasFocus())
3118 }
3119 
3121 {
3122  TriState eNewState;
3123  if ( meState == TRISTATE_FALSE )
3124  eNewState = TRISTATE_TRUE;
3125  else if ( !mbTriState )
3126  eNewState = TRISTATE_FALSE;
3127  else if ( meState == TRISTATE_TRUE )
3128  eNewState = TRISTATE_INDET;
3129  else
3130  eNewState = TRISTATE_FALSE;
3131  meState = eNewState;
3132 
3133  VclPtr<vcl::Window> xWindow = this;
3134  Invalidate();
3135  Toggle();
3136  if ( xWindow->isDisposed() )
3137  return;
3138  Click();
3139 }
3140 
3143 {
3145  ImplInit( pParent, nStyle );
3146 }
3147 
3149 {
3150  if ( rMEvt.IsLeft() && maMouseRect.IsInside( rMEvt.GetPosPixel() ) )
3151  {
3153  Invalidate();
3154  StartTracking();
3155  return;
3156  }
3157 
3158  Button::MouseButtonDown( rMEvt );
3159 }
3160 
3161 void CheckBox::Tracking( const TrackingEvent& rTEvt )
3162 {
3163  if ( rTEvt.IsTrackingEnded() )
3164  {
3166  {
3167  if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() )
3168  GrabFocus();
3169 
3171 
3172  // do not call click handler if aborted
3173  if ( !rTEvt.IsTrackingCanceled() )
3174  ImplCheck();
3175  else
3176  {
3177  Invalidate();
3178  }
3179  }
3180  }
3181  else
3182  {
3183  if ( maMouseRect.IsInside( rTEvt.GetMouseEvent().GetPosPixel() ) )
3184  {
3186  {
3188  Invalidate();
3189  }
3190  }
3191  else
3192  {
3194  {
3196  Invalidate();
3197  }
3198  }
3199  }
3200 }
3201 
3202 void CheckBox::KeyInput( const KeyEvent& rKEvt )
3203 {
3204  vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
3205 
3206  if ( !aKeyCode.GetModifier() && (aKeyCode.GetCode() == KEY_SPACE) )
3207  {
3209  {
3211  Invalidate();
3212  }
3213  }
3214  else if ( (GetButtonState() & DrawButtonFlags::Pressed) && (aKeyCode.GetCode() == KEY_ESCAPE) )
3215  {
3217  Invalidate();
3218  }
3219  else
3220  Button::KeyInput( rKEvt );
3221 }
3222 
3223 void CheckBox::KeyUp( const KeyEvent& rKEvt )
3224 {
3225  vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
3226 
3227  if ( (GetButtonState() & DrawButtonFlags::Pressed) && (aKeyCode.GetCode() == KEY_SPACE) )
3228  {
3230  ImplCheck();
3231  }
3232  else
3233  Button::KeyUp( rKEvt );
3234 }
3235 
3237 {
3238  mpControlData->mpLayoutData.reset( new vcl::ControlLayoutData );
3239  const_cast<CheckBox*>(this)->Invalidate();
3240 }
3241 
3243 {
3244  ImplDrawCheckBox(rRenderContext);
3245 }
3246 
3247 void CheckBox::Draw( OutputDevice* pDev, const Point& rPos,
3248  DrawFlags nFlags )
3249 {
3250  MapMode aResMapMode( MapUnit::Map100thMM );
3251  Point aPos = pDev->LogicToPixel( rPos );
3252  Size aSize = GetSizePixel();
3253  Size aImageSize = pDev->LogicToPixel( Size( 300, 300 ), aResMapMode );
3254  Size aBrd1Size = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode );
3255  Size aBrd2Size = pDev->LogicToPixel( Size( 30, 30 ), aResMapMode );
3256  tools::Long nCheckWidth = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode ).Width();
3257  vcl::Font aFont = GetDrawPixelFont( pDev );
3258  tools::Rectangle aStateRect;
3259  tools::Rectangle aMouseRect;
3260 
3261  aImageSize.setWidth( CalcZoom( aImageSize.Width() ) );
3262  aImageSize.setHeight( CalcZoom( aImageSize.Height() ) );
3263  aBrd1Size.setWidth( CalcZoom( aBrd1Size.Width() ) );
3264  aBrd1Size.setHeight( CalcZoom( aBrd1Size.Height() ) );
3265  aBrd2Size.setWidth( CalcZoom( aBrd2Size.Width() ) );
3266  aBrd2Size.setHeight( CalcZoom( aBrd2Size.Height() ) );
3267 
3268  if ( !aBrd1Size.Width() )
3269  aBrd1Size.setWidth( 1 );
3270  if ( !aBrd1Size.Height() )
3271  aBrd1Size.setHeight( 1 );
3272  if ( !aBrd2Size.Width() )
3273  aBrd2Size.setWidth( 1 );
3274  if ( !aBrd2Size.Height() )
3275  aBrd2Size.setHeight( 1 );
3276  if ( !nCheckWidth )
3277  nCheckWidth = 1;
3278 
3279  pDev->Push();
3280  pDev->SetMapMode();
3281  pDev->SetFont( aFont );
3282  if ( nFlags & DrawFlags::Mono )
3283  pDev->SetTextColor( COL_BLACK );
3284  else
3285  pDev->SetTextColor( GetTextColor() );
3286  pDev->SetTextFillColor();
3287 
3288  ImplDraw( pDev, nFlags, aPos, aSize,
3289  aImageSize, aStateRect, aMouseRect );
3290 
3291  pDev->SetLineColor();
3292  pDev->SetFillColor( COL_BLACK );
3293  pDev->DrawRect( aStateRect );
3294  aStateRect.AdjustLeft(aBrd1Size.Width() );
3295  aStateRect.AdjustTop(aBrd1Size.Height() );
3296  aStateRect.AdjustRight( -(aBrd1Size.Width()) );
3297  aStateRect.AdjustBottom( -(aBrd1Size.Height()) );
3298  if ( meState == TRISTATE_INDET )
3299  pDev->SetFillColor( COL_LIGHTGRAY );
3300  else
3301  pDev->SetFillColor( COL_WHITE );
3302  pDev->DrawRect( aStateRect );
3303 
3304  if ( meState == TRISTATE_TRUE )
3305  {
3306  aStateRect.AdjustLeft(aBrd2Size.Width() );
3307  aStateRect.AdjustTop(aBrd2Size.Height() );
3308  aStateRect.AdjustRight( -(aBrd2Size.Width()) );
3309  aStateRect.AdjustBottom( -(aBrd2Size.Height()) );
3310  Point aPos11( aStateRect.TopLeft() );
3311  Point aPos12( aStateRect.BottomRight() );
3312  Point aPos21( aStateRect.TopRight() );
3313  Point aPos22( aStateRect.BottomLeft() );
3314  Point aTempPos11( aPos11 );
3315  Point aTempPos12( aPos12 );
3316  Point aTempPos21( aPos21 );
3317  Point aTempPos22( aPos22 );
3318  pDev->SetLineColor( COL_BLACK );
3319  tools::Long nDX = 0;
3320  for ( tools::Long i = 0; i < nCheckWidth; i++ )
3321  {
3322  if ( !(i % 2) )
3323  {
3324  aTempPos11.setX( aPos11.X()+nDX );
3325  aTempPos12.setX( aPos12.X()+nDX );
3326  aTempPos21.setX( aPos21.X()+nDX );
3327  aTempPos22.setX( aPos22.X()+nDX );
3328  }
3329  else
3330  {
3331  nDX++;
3332  aTempPos11.setX( aPos11.X()-nDX );
3333  aTempPos12.setX( aPos12.X()-nDX );
3334  aTempPos21.setX( aPos21.X()-nDX );
3335  aTempPos22.setX( aPos22.X()-nDX );
3336  }
3337  pDev->DrawLine( aTempPos11, aTempPos12 );
3338  pDev->DrawLine( aTempPos21, aTempPos22 );
3339  }
3340  }
3341 
3342  pDev->Pop();
3343 }
3344 
3346 {
3347  Control::Resize();
3348  Invalidate();
3349 }
3350 
3352 {
3353  if (GetText().isEmpty())
3354  {
3355  // increase button size to have space for focus rect
3356  // checkboxes without text will draw focusrect around the check
3357  // See CheckBox::ImplDraw()
3358  Point aPos( GetPosPixel() );
3359  Size aSize( GetSizePixel() );
3360  aPos.Move(-1,-1);
3361  aSize.AdjustHeight(2 );
3362  aSize.AdjustWidth(2 );
3363  setPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height() );
3364  Invalidate();
3365  // Trigger drawing to initialize the mouse rectangle, otherwise the mouse button down
3366  // handler would ignore the mouse event.
3367  PaintImmediately();
3368  }
3369  else
3371 
3373  Button::GetFocus();
3374 }
3375 
3377 {
3379  {
3381  Invalidate();
3382  }
3383 
3384  HideFocus();
3386 
3387  if (GetText().isEmpty())
3388  {
3389  // decrease button size again (see GetFocus())
3390  // checkboxes without text will draw focusrect around the check
3391  Point aPos( GetPosPixel() );
3392  Size aSize( GetSizePixel() );
3393  aPos.Move(1,1);
3394  aSize.AdjustHeight( -2 );
3395  aSize.AdjustWidth( -2 );
3396  setPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height() );
3397  Invalidate();
3398  }
3399 }
3400 
3402 {
3403  Button::StateChanged( nType );
3404 
3405  if ( nType == StateChangedType::State )
3406  {
3407  if ( IsReallyVisible() && IsUpdateMode() )
3409  }
3410  else if ( (nType == StateChangedType::Enable) ||
3411  (nType == StateChangedType::Text) ||
3412  (nType == StateChangedType::Data) ||
3413  (nType == StateChangedType::UpdateMode) )
3414  {
3415  if ( IsUpdateMode() )
3416  Invalidate();
3417  }
3418  else if ( nType == StateChangedType::Style )
3419  {
3421 
3422  if ( (GetPrevStyle() & CHECKBOX_VIEW_STYLE) !=
3424  {
3425  if ( IsUpdateMode() )
3426  Invalidate();
3427  }
3428  }
3429  else if ( (nType == StateChangedType::Zoom) ||
3430  (nType == StateChangedType::ControlFont) )
3431  {
3432  ImplInitSettings( false );
3433  Invalidate();
3434  }
3435  else if ( nType == StateChangedType::ControlForeground )
3436  {
3437  ImplInitSettings( false );
3438  Invalidate();
3439  }
3440  else if ( nType == StateChangedType::ControlBackground )
3441  {
3442  ImplInitSettings( true );
3443  Invalidate();
3444  }
3445 }
3446 
3448 {
3449  Button::DataChanged( rDCEvt );
3450 
3451  if ( (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
3453  ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
3454  (rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
3455  {
3456  ImplInitSettings( true );
3457  Invalidate();
3458  }
3459 }
3460 
3462 {
3463  if( rNEvt.GetType() == MouseNotifyEvent::MOUSEMOVE )
3464  {
3465  const MouseEvent* pMouseEvt = rNEvt.GetMouseEvent();
3466  if( pMouseEvt && !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() )
3467  {
3468  // trigger redraw if mouse over state has changed
3470  {
3472  pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow())
3473  {
3475  }
3476  }
3477  }
3478  }
3479 
3480  return Button::PreNotify(rNEvt);
3481 }
3482 
3484 {
3486 }
3487 
3489 {
3490  if ( !mbTriState && (eState == TRISTATE_INDET) )
3491  eState = TRISTATE_FALSE;
3492 
3493  if ( meState != eState )
3494  {
3495  meState = eState;
3497  Toggle();
3498  }
3499 }
3500 
3501 bool CheckBox::set_property(const OString &rKey, const OUString &rValue)
3502 {
3503  if (rKey == "active")
3505  else
3506  return Button::set_property(rKey, rValue);
3507  return true;
3508 }
3509 
3510 void CheckBox::EnableTriState( bool bTriState )
3511 {
3512  if ( mbTriState != bTriState )
3513  {
3514  mbTriState = bTriState;
3515 
3516  if ( !bTriState && (meState == TRISTATE_INDET) )
3518  }
3519 }
3520 
3522 {
3523  Size aSize;
3524  bool bDefaultSize = true;
3526  {
3527  ImplControlValue aControlValue;
3528  tools::Rectangle aCtrlRegion( Point( 0, 0 ), GetSizePixel() );
3529  tools::Rectangle aBoundingRgn, aContentRgn;
3530 
3531  // get native size of a check box
3534  aControlValue,
3535  aBoundingRgn, aContentRgn ) )
3536  {
3537  aSize = aContentRgn.GetSize();
3538  bDefaultSize = false;
3539  }
3540  }
3541  if( bDefaultSize )
3543  return aSize;
3544 }
3545 
3547 {
3548  ImplSVData* pSVData = ImplGetSVData();
3549  const StyleSettings& rStyleSettings = rSettings.GetStyleSettings();
3550  sal_uInt16 nStyle = 0;
3551 
3552  if ( rStyleSettings.GetOptions() & StyleSettingsOptions::Mono )
3553  nStyle = STYLE_CHECKBOX_MONO;
3554 
3555  if ( pSVData->maCtrlData.maCheckImgList.empty() ||
3556  (pSVData->maCtrlData.mnCheckStyle != nStyle) ||
3557  (pSVData->maCtrlData.mnLastCheckFColor != rStyleSettings.GetFaceColor()) ||
3558  (pSVData->maCtrlData.mnLastCheckWColor != rStyleSettings.GetWindowColor()) ||
3559  (pSVData->maCtrlData.mnLastCheckLColor != rStyleSettings.GetLightColor()) )
3560  {
3561  pSVData->maCtrlData.maCheckImgList.clear();
3562 
3563  pSVData->maCtrlData.mnLastCheckFColor = rStyleSettings.GetFaceColor();
3564  pSVData->maCtrlData.mnLastCheckWColor = rStyleSettings.GetWindowColor();
3565  pSVData->maCtrlData.mnLastCheckLColor = rStyleSettings.GetLightColor();
3566 
3567  std::vector<OUString> aResources;
3568  if (nStyle)
3569  {
3570  aResources.emplace_back(SV_RESID_BITMAP_CHECKMONO1);
3571  aResources.emplace_back(SV_RESID_BITMAP_CHECKMONO2);
3572  aResources.emplace_back(SV_RESID_BITMAP_CHECKMONO3);
3573  aResources.emplace_back(SV_RESID_BITMAP_CHECKMONO4);
3574  aResources.emplace_back(SV_RESID_BITMAP_CHECKMONO5);
3575  aResources.emplace_back(SV_RESID_BITMAP_CHECKMONO6);
3576  aResources.emplace_back(SV_RESID_BITMAP_CHECKMONO7);
3577  aResources.emplace_back(SV_RESID_BITMAP_CHECKMONO8);
3578  aResources.emplace_back(SV_RESID_BITMAP_CHECKMONO9);
3579  }
3580  else
3581  {
3582  aResources.emplace_back(SV_RESID_BITMAP_CHECK1);
3583  aResources.emplace_back(SV_RESID_BITMAP_CHECK2);
3584  aResources.emplace_back(SV_RESID_BITMAP_CHECK3);
3585  aResources.emplace_back(SV_RESID_BITMAP_CHECK4);
3586  aResources.emplace_back(SV_RESID_BITMAP_CHECK5);
3587  aResources.emplace_back(SV_RESID_BITMAP_CHECK6);
3588  aResources.emplace_back(SV_RESID_BITMAP_CHECK7);
3589  aResources.emplace_back(SV_RESID_BITMAP_CHECK8);
3590  aResources.emplace_back(SV_RESID_BITMAP_CHECK9);
3591  }
3592  LoadThemedImageList(rStyleSettings, pSVData->maCtrlData.maCheckImgList, aResources);
3593  pSVData->maCtrlData.mnCheckStyle = nStyle;
3594  }
3595 
3596  sal_uInt16 nIndex;
3597  if ( nFlags & DrawButtonFlags::Disabled )
3598  {
3599  if ( nFlags & DrawButtonFlags::DontKnow )
3600  nIndex = 8;
3601  else if ( nFlags & DrawButtonFlags::Checked )
3602  nIndex = 5;
3603  else
3604  nIndex = 4;
3605  }
3606  else if ( nFlags & DrawButtonFlags::Pressed )
3607  {
3608  if ( nFlags & DrawButtonFlags::DontKnow )
3609  nIndex = 7;
3610  else if ( nFlags & DrawButtonFlags::Checked )
3611  nIndex = 3;
3612  else
3613  nIndex = 2;
3614  }
3615  else
3616  {
3617  if ( nFlags & DrawButtonFlags::DontKnow )
3618  nIndex = 6;
3619  else if ( nFlags & DrawButtonFlags::Checked )
3620  nIndex = 1;
3621  else
3622  nIndex = 0;
3623  }
3624  return pSVData->maCtrlData.maCheckImgList[nIndex];
3625 }
3626 
3628 {
3630  SetMapMode(MapMode(MapUnit::MapPixel));
3631 
3632  ImplControlValue aControlValue;
3633  Size aCurSize( GetSizePixel() );
3634  tools::Rectangle aCtrlRegion( Point( 0, 0 ), aCurSize );
3635  tools::Rectangle aBoundingRgn, aContentRgn;
3636 
3637  // get native size of a radiobutton
3640  aBoundingRgn, aContentRgn ) )
3641  {
3642  Size aSize = aContentRgn.GetSize();
3643 
3644  if( aSize.Height() > aCurSize.Height() )
3645  {
3646  aCurSize.setHeight( aSize.Height() );
3647  SetSizePixel( aCurSize );
3648  }
3649  }
3650 
3651  GetOutDev()->Pop();
3652 }
3653 
3655 {
3656  Size aSize = ImplGetCheckImageSize();
3657  nMaxWidth -= aSize.Width();
3658 
3659  OUString aText = GetText();
3660  if (!aText.isEmpty())
3661  {
3662  // subtract what will be added later
3663  nMaxWidth-=2;
3664  nMaxWidth -= ImplGetImageToTextDistance();
3665 
3666  Size aTextSize = GetTextRect( tools::Rectangle( Point(), Size( nMaxWidth > 0 ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ),
3668  aSize.AdjustWidth(2 ); // for focus rect
3670  aSize.AdjustWidth(aTextSize.Width() );
3671  if ( aSize.Height() < aTextSize.Height() )
3672  aSize.setHeight( aTextSize.Height() );
3673  }
3674  else
3675  {
3676  // is this still correct ? since the checkbox now
3677  // shows a focus rect it should be 2 pixels wider and longer
3678 /* since otherwise the controls in the Writer hang too far up
3679  aSize.Width() += 2;
3680  aSize.Height() += 2;
3681 */
3682  }
3683 
3684  return CalcWindowSize( aSize );
3685 }
3686 
3688 {
3689  int nWidthRequest(get_width_request());
3690  return CalcMinimumSize(nWidthRequest != -1 ? nWidthRequest : 0);
3691 }
3692 
3694 {
3696  {
3697  ImplControlValue aControlValue;
3698  tools::Rectangle aInRect(Point(0, 0), GetSizePixel());
3699 
3700  aInRect.SetLeft( rRect.Left() ); // exclude the checkbox itself from the focusrect
3701 
3703  ControlState::FOCUSED, aControlValue, OUString());
3704  }
3705  Button::ShowFocus(rRect);
3706 }
3707 
3709 {
3710  Button::DumpAsPropertyTree(rJsonWriter);
3711  rJsonWriter.put("checked", IsChecked());
3712 }
3713 
3715 {
3716  return CheckBoxUIObject::create;
3717 }
3718 
3720  PushButton( pParent, nStyle )
3721 {
3722  ImplInitStyle();
3723 }
3724 
3726 {
3727  WinBits nStyle = GetStyle();
3728 
3729  if ( ! ( nStyle & ( WB_RIGHT | WB_LEFT ) ) )
3730  nStyle |= WB_CENTER;
3731 
3732  if ( ! ( nStyle & ( WB_TOP | WB_BOTTOM ) ) )
3733  nStyle |= WB_VCENTER;
3734 
3735  SetStyle( nStyle );
3736 }
3737 
3738 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static bool toBool(std::string_view rValue)
Definition: builder.cxx:88
virtual Point GetPosPixel() const
Definition: window.cxx:2786
std::shared_ptr< std::vector< VclPtr< RadioButton > > > m_xGroup
Definition: button.hxx:377
virtual void Resize() override
Definition: button.cxx:2507
bool mbIsAction
Definition: button.hxx:218
virtual const vcl::Font & GetCanonicalFont(const StyleSettings &_rStyle) const override
Definition: button.cxx:645
virtual void FillLayoutData() const override
Definition: button.cxx:1327
virtual void DataChanged(const DataChangedEvent &rDCEvt) override
Definition: button.cxx:3447
tools::Long GetTextHeight() const
Height where any character of the current font fits; in logic coordinates.
Definition: window3.cxx:65
Image const & GetCustomButtonImage() const
Definition: button.cxx:174
Size GetSizePixel() const
Definition: Image.cxx:86
void SetPos(const Point &rPoint)
const Color & GetShadowColor() const
bool IsControlBackground() const
Definition: window2.cxx:1090
static std::unique_ptr< UIObject > create(vcl::Window *pWindow)
SAL_DLLPRIVATE tools::Long ImplGetImageToTextDistance() const
Definition: button.cxx:2708
SAL_DLLPRIVATE void ImplInitCheckBoxData()
Definition: button.cxx:2951
void Toggle()
Definition: button.cxx:3483
Color mnLastRadioLColor
Definition: svdata.hxx:283
void SetBackground()
Definition: window3.cxx:100
TriState meState
Definition: button.hxx:216
virtual void statusChanged(const css::frame::FeatureStateEvent &rEvent) override
Sets the button state according to the FeatureStateEvent emitted by a Uno state change.
Definition: button.cxx:1581
bool ImplCallEventListenersAndHandler(VclEventId nEvent, std::function< void()> const &callHandler)
this calls both our event listeners, and a specified handler
Definition: ctrl.cxx:305
CheckBox(const CheckBox &)=delete
Point GetPointerPosPixel()
Definition: mouse.cxx:555
void EndSelection()
Definition: button.cxx:1597
void HideFocus()
Definition: window2.cxx:91
sal_Int32 nIndex
DrawButtonFlags mnButtonState
Definition: button.cxx:80
bool mbIsActive
Definition: button.hxx:184
WinBits const WB_TOGGLE
virtual ~Button() override
Definition: button.cxx:105
static std::unique_ptr< UIObject > create(vcl::Window *pWindow)
Color mnLastCheckWColor
Definition: svdata.hxx:279
virtual void StateChanged(StateChangedType nType) override
Definition: button.cxx:3401
WinBits const WB_NOLABEL
void DrawImage(const Point &rPos, const Image &rImage, DrawImageFlags nStyle=DrawImageFlags::NONE)
This is an overloaded member function, provided for convenience. It differs from the above function o...
virtual Size GetOptimalSize() const override
Definition: button.cxx:3687
const Color & GetActionButtonTextColor() const
static Image GetRadioImage(const AllSettings &rSettings, DrawButtonFlags nFlags)
Definition: button.cxx:2768
tools::Long AdjustRight(tools::Long nHorzMoveDelta)
virtual bool Close() override
Definition: dialog.cxx:843
sal_uInt16 mnCheckStyle
Definition: svdata.hxx:276
SAL_DLLPRIVATE void ImplSetFocusRect(const tools::Rectangle &rFocusRect)
Definition: button.cxx:482
void SetModeRadioImage(const Image &rImage)
Definition: button.cxx:2619
void setWidth(tools::Long nWidth)
void Replace(const Color &rSearchColor, const Color &rReplaceColor)
Replace all pixel having the search color with the specified color.
Definition: BitmapEx.cxx:479
void group(RadioButton &rOther)
Definition: button.cxx:2179
void SetClickHdl(const Link< Button *, void > &rLink)
Definition: button.hxx:79
tools::Rectangle maStateRect
Definition: button.hxx:289
ImageAlign
virtual void MouseButtonDown(const MouseEvent &rMEvt)
Definition: mouse.cxx:419
#define STYLE_RADIOBUTTON_MONO
Definition: button.cxx:70
StartTrackingFlags
Definition: window.hxx:263
virtual void KeyInput(const KeyEvent &rKEvt) override
Definition: button.cxx:1270
void SetModeImage(const Image &rImage)
Definition: button.cxx:131
SAL_DLLPRIVATE void ImplSetSeparatorX(tools::Long nX)
Definition: button.cxx:184
SAL_DLLPRIVATE void ImplSetDefButton(bool bSet)
Definition: button.cxx:1112
tools::Long getWidth() const
void Check(bool bCheck=true)
Definition: button.hxx:221
SymbolAlign
virtual void Click() override
Definition: button.cxx:1706
OUString GetStandardText(StandardButtonType eButton)
Definition: stdtext.cxx:93
void EndDialog(tools::Long nResult=RET_CANCEL)
Definition: dialog.cxx:1102
void SetStyleSettings(const StyleSettings &rSet)
SymbolAlign meSymbolAlign
Definition: button.cxx:86
static SAL_DLLPRIVATE WinBits ImplInitStyle(const vcl::Window *pPrevWindow, WinBits nStyle)
Definition: button.cxx:2965
Point BottomLeft() const
WinBits const WB_NOGROUP
void SetCommandHandler(const OUString &aCommand)
Setup handler for UNO commands so that commands like .uno:Something are handled automagically by this...
Definition: button.cxx:117
tools::Rectangle maStateRect
Definition: button.hxx:378
virtual void DataChanged(const DataChangedEvent &rDCEvt) override
Definition: button.cxx:1454
const Color & GetDefaultButtonTextColor() const
long Long
Link< CheckBox &, void > maToggleHdl
Definition: button.hxx:293
virtual void FillLayoutData() const override
Definition: button.cxx:3236
virtual void LoseFocus() override
Definition: button.cxx:2520
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
Gets the application's settings.
Definition: svapp.cxx:733
sal_uInt8 GetLuminance() const
const Color & GetFaceColor() const
const vcl::Font & GetRadioCheckFont() const
virtual void StateChanged(StateChangedType nStateChange) override
Definition: ctrl.cxx:260
void DrawFrame(const tools::Rectangle &rRect, const Color &rLeftTopColor, const Color &rRightBottomColor)
Definition: decoview.cxx:824
SAL_DLLPRIVATE void ImplGrabFocus(GetFocusFlags nFlags)
Definition: mouse.cxx:194
ImplSVNWFData maNWFData
Definition: svdata.hxx:397
void Toggle()
Definition: button.cxx:2614
const OUString & GetQuickHelpText() const
Definition: window2.cxx:1235
void DrawPolygon(const tools::Polygon &rPoly)
Render the given polygon.
Definition: polygon.cxx:156
const Color & GetDefaultButtonPressedRolloverTextColor() const
bool mbRadioCheck
Definition: button.hxx:382
std::function< std::unique_ptr< UIObject >vcl::Window *)> FactoryFunction
virtual Size GetSizePixel() const
Definition: window.cxx:2397
virtual void SetSizePixel(const Size &rNewSize)
Definition: window2.cxx:1265
WinBits const WB_RIGHT
virtual void KeyUp(const KeyEvent &rKEvt) override
Definition: button.cxx:2409
SAL_DLLPRIVATE WindowImpl * ImplGetWindowImpl() const
Definition: window.hxx:540
void SetState(bool bCheck)
Definition: button.cxx:2630
void CompatStateChanged(StateChangedType nStateChange)
Definition: window.cxx:3881
SAL_DLLPRIVATE void ImplCallClick(bool bGrabFocus=false, GetFocusFlags nFocusFlags=GetFocusFlags::NONE)
Definition: button.cxx:2285
PushButtonDropdownStyle
Definition: button.hxx:116
bool mbNoFocusRectsForFlatButtons
Definition: svdata.hxx:322
tools::Rectangle maMouseRect
Definition: button.hxx:290
void SetTextFillColor()
Definition: text.cxx:697
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: button.cxx:1664
sal_uInt16 GetCode() const
Definition: keycod.hxx:51
void SetParentClipMode(ParentClipMode nMode=ParentClipMode::NONE)
RadioButton(const RadioButton &)=delete
void setTristateVal(ButtonValue nTristate)
WinBits GetPrevStyle() const
Definition: window2.cxx:961
DataChangedEventType GetType() const
Definition: event.hxx:354
virtual Size GetOptimalSize() const override
Definition: button.cxx:1659
void IntersectClipRegion(const tools::Rectangle &rRect)
DrawButtonFlags
Definition: decoview.hxx:53
SAL_DLLPRIVATE void ImplDrawRadioButtonState(vcl::RenderContext &rRenderContext)
Definition: button.cxx:1902
#define STYLE_CHECKBOX_MONO
Definition: button.cxx:71
constexpr::Color COL_LIGHTGRAY(0xC0, 0xC0, 0xC0)
tools::Rectangle DrawControlText(OutputDevice &_rTargetDevice, const tools::Rectangle &_rRect, const OUString &_rStr, DrawTextFlags _nStyle, std::vector< tools::Rectangle > *_pVector, OUString *_pDisplayText, const Size *i_pDeviceSize=nullptr) const
draws the given text onto the given device
Definition: ctrl.cxx:433
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: button.cxx:541
SAL_DLLPRIVATE void ImplInit(vcl::Window *pParent, WinBits nStyle)
Definition: button.cxx:1837
const Color & GetControlBackground() const
Definition: window2.cxx:1085
void SetState(TriState eState)
Definition: button.cxx:3488
tools::Rectangle DrawButton(const tools::Rectangle &rRect, DrawButtonFlags nStyle)
Definition: decoview.cxx:918
constexpr sal_uInt16 KEY_SPACE
Definition: keycodes.hxx:123
virtual void ShowFocus(const tools::Rectangle &rRect) override
Definition: button.cxx:1679
virtual void Tracking(const TrackingEvent &rTEvt) override
Definition: button.cxx:1207
SAL_DLLPRIVATE void ImplDrawPushButtonContent(OutputDevice *pDev, DrawFlags nDrawFlags, const tools::Rectangle &rRect, bool bMenuBtnSep, DrawButtonFlags nButtonFlags)
Definition: button.cxx:772
void PaintImmediately()
Definition: paint.cxx:1268
SAL_DLLPRIVATE Size ImplGetRadioImageSize() const
Definition: button.cxx:2715
void SetQuickHelpText(const OUString &rHelpText)
Definition: window2.cxx:1229
TRISTATE_TRUE
void StartTracking(StartTrackingFlags nFlags=StartTrackingFlags::NONE)
Definition: window2.cxx:242
bool IsNativeControlSupported(ControlType nType, ControlPart nPart) const
Query the platform layer for control support.
void SetMapMode()
Definition: map.cxx:551
DrawTextFlags
void SetRight(tools::Long v)
ImplSVCtrlData maCtrlData
Definition: svdata.hxx:395
const Color & GetHighlightColor() const
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
Definition: button.cxx:110
void SetDropDown(PushButtonDropdownStyle nStyle)
Definition: button.cxx:1549
IMPL_STATIC_LINK(Button, dispatchCommandHandler, Button *, pButton, void)
Definition: button.cxx:585
SAL_DLLPRIVATE void ImplInit(vcl::Window *pParent, WinBits nStyle)
Definition: button.cxx:613
NONE
SAL_DLLPRIVATE void ImplDrawRadioButton(vcl::RenderContext &rRenderContext)
Definition: button.cxx:2156
bool IsTrackingRepeat() const
Definition: event.hxx:259
The invalidated area is painted with the background color/pattern.
void SetSymbolAlign(SymbolAlign eAlign)
Definition: button.cxx:1544
tools::Rectangle GetControlTextRect(OutputDevice &_rTargetDevice, const tools::Rectangle &rRect, const OUString &_rStr, DrawTextFlags _nStyle, Size *o_pDeviceSize=nullptr) const
Definition: ctrl.cxx:458
StateChangedType
Definition: window.hxx:289
constexpr tools::Long Width() const
WinBits const WB_NOPOINTERFOCUS
void DumpAsPropertyTree(tools::JsonWriter &) override
Button has additional stuff that we need to dump too.
Definition: button.cxx:2932
SAL_DLLPRIVATE void ImplDraw(OutputDevice *pDev, DrawFlags nDrawFlags, const Point &rPos, const Size &rSize, const Size &rImageSize, tools::Rectangle &rStateRect, tools::Rectangle &rMouseRect)
Definition: button.cxx:2075
virtual void KeyInput(const KeyEvent &rKEvt) override
Definition: button.cxx:3202
const Color & GetRadioCheckTextColor() const
rtl::Reference< VclStatusListener< Button > > mpStatusListener
StatusListener.
Definition: button.cxx:91
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: button.cxx:3501
sal_Int64 WinBits
Size CalcMinimumSize() const
Definition: button.cxx:1609
WinBits const WB_BOTTOM
WinBits const WB_TOP
bool mbTriState
Definition: button.hxx:292
void Enable(bool bEnable=true, bool bChild=true)
Definition: window.cxx:2428
const Color & GetDefaultButtonRolloverTextColor() const
sal_uInt16 GetButtons() const
Definition: event.hxx:147
tools::Long Left() const
void SetSymbol(SymbolType eSymbol)
Definition: button.cxx:1535
virtual void DumpAsPropertyTree(tools::JsonWriter &)
Dumps itself and potentially its children to a property tree, to be written easily to JSON...
Definition: window.cxx:3353
void SetLeft(tools::Long v)
WinBits const WB_DEFBUTTON
SymbolType
Definition: vclenum.hxx:73
Link< RadioButton &, void > maToggleHdl
Definition: button.hxx:385
PushButton(vcl::Window *pParent, WinBits nStyle=0)
Definition: button.cxx:1180
virtual void GetFocus() override
Definition: button.cxx:3351
void ImplAdjustNWFSizes() override
Definition: button.cxx:3627
bool IsControlForeground() const
Definition: window2.cxx:1080
DrawImageFlags
bool IsEnterWindow() const
Definition: event.hxx:138
bool dispatchCommand(const OUString &rCommand, const uno::Reference< css::frame::XFrame > &rFrame, const css::uno::Sequence< css::beans::PropertyValue > &rArguments, const uno::Reference< css::frame::XDispatchResultListener > &rListener)
void EndTracking(TrackingEventFlags nFlags=TrackingEventFlags::NONE)
Definition: window2.cxx:270
Image maImage
Definition: button.hxx:380
virtual const Color & GetCanonicalTextColor(const StyleSettings &_rStyle) const override
Definition: button.cxx:2980
OUString maCommand
Command URL (like .uno:Save) in case the button should handle it.
Definition: button.hxx:47
Link< Button *, void > maClickHdl
Definition: button.hxx:44
ImageAlign meImageAlign
Definition: button.cxx:85
void Hide()
Definition: window.hxx:897
bool IsChecked() const
Definition: button.hxx:453
AllSettingsFlags GetFlags() const
Definition: event.hxx:355
tools::Long Bottom() const
virtual void StateChanged(StateChangedType nStateChange) override
Definition: button.cxx:1820
const Color & GetLightColor() const
Image maCustomContentImage
Definition: button.cxx:88
virtual void GetFocus() override
Definition: button.cxx:1393
virtual void Click()
Definition: button.cxx:126
constexpr tools::Long GetWidth() const
SAL_DLLPRIVATE tools::Long ImplGetSeparatorX() const
The x-coordinate of the vertical separator line, use in MenuButton subclass only. ...
Definition: button.cxx:179
virtual void queue_resize(StateChangedType eReason=StateChangedType::Layout)
Definition: window2.cxx:1330
static std::unique_ptr< UIObject > create(vcl::Window *pWindow)
void SetImageAlign(ImageAlign eAlign)
Definition: button.cxx:151
SAL_DLLPRIVATE const tools::Rectangle & ImplGetFocusRect() const
Definition: button.cxx:507
bool isAction() const
Definition: button.hxx:177
SAL_DLLPRIVATE DrawTextFlags ImplGetTextStyle(WinBits nWinStyle, DrawFlags nDrawFlags)
Definition: button.cxx:189
sal_uInt16 GetModifier() const
Definition: keycod.hxx:54
tools::Long GetCtrlTextWidth(const OUString &rStr, const SalLayoutGlyphs *pLayoutCache=nullptr) const
Definition: text.cxx:2204
virtual OUString GetText() const
Definition: window.cxx:3050
static Image GetCheckImage(const AllSettings &rSettings, DrawButtonFlags nFlags)
Definition: button.cxx:3546
static SAL_DLLPRIVATE void ImplCalcSymbolRect(tools::Rectangle &rRect)
Definition: brdwin.cxx:44
constexpr auto RADIOBUTTON_VIEW_STYLE
Definition: button.cxx:61
SAL_DLLPRIVATE void ImplInitRadioButtonData()
Definition: button.cxx:1830
Definition: edit.hxx:55
void IncreaseLuminance(sal_uInt8 cLumInc)
SymbolType meSymbol
Definition: button.hxx:215
Size CalcMinimumSize(tools::Long nMaxWidth=0) const
Definition: button.cxx:2864
virtual void LoseFocus() override
Definition: button.cxx:1400
PushButtonDropdownStyle mnDDStyle
Definition: button.hxx:183
tools::Long AdjustBottom(tools::Long nVertMoveDelta)
void DrawLine(const Point &rStartPt, const Point &rEndPt)
Definition: line.cxx:89
WinBits const WB_BEVELBUTTON
TRISTATE_INDET
bool IsChildTransparentModeEnabled() const
Definition: window2.cxx:1030
SAL_DLLPRIVATE void ImplCheck()
Definition: button.cxx:3120
void DrawRect(const tools::Rectangle &rRect)
Definition: rect.cxx:51
GetFocusFlags
Definition: window.hxx:311
virtual bool PreNotify(NotifyEvent &rNEvt) override
Definition: button.cxx:3461
constexpr bool IsEmpty() const
const Color & GetControlForeground() const
Definition: window2.cxx:1075
virtual void Draw(OutputDevice *pDev, const Point &rPos, DrawFlags nFlags) override
Definition: button.cxx:1344
#define SAL_N_ELEMENTS(arr)
SAL_DLLPRIVATE bool ImplUseNativeBorder(vcl::RenderContext const &rRenderContext, WinBits nStyle)
Definition: edit.cxx:289
static void LoadThemedImageList(const StyleSettings &rStyleSettings, std::vector< Image > &rList, const std::vector< OUString > &rResources)
Definition: button.cxx:2740
virtual void MouseButtonDown(const MouseEvent &rMEvt) override
Definition: button.cxx:2334
WinBits const WB_NOLIGHTBORDER
Point BottomRight() const
const Color & GetDarkShadowColor() const
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:75
virtual bool PreNotify(NotifyEvent &rNEvt) override
Definition: button.cxx:2592
Size CalcWindowSize(const Size &rOutSz) const
Definition: window2.cxx:535
const Color & GetActionButtonRolloverTextColor() const
const vcl::Font & GetPushButtonFont() const
virtual void Click() override
Definition: button.cxx:1805
void setY(tools::Long y)
void SetLineColor()
virtual void ShowFocus(const tools::Rectangle &rRect) override
Definition: button.cxx:3693
virtual bool PreNotify(NotifyEvent &rNEvt)
Definition: event.cxx:52
void SetInputContext(const InputContext &rInputContext)
Definition: window.cxx:2072
void DecreaseLuminance(sal_uInt8 cLumDec)
bool IsLeaveWindow() const
Definition: event.hxx:140
const Color & GetActionButtonPressedRolloverTextColor() const
void Check(bool bCheck=true)
Definition: button.cxx:2685
int i
DrawFlags
Definition: window.hxx:332
uno_Any a
bool IsChecked() const
Definition: button.hxx:226
virtual bool PreNotify(NotifyEvent &rNEvt) override
Definition: button.cxx:1468
SAL_DLLPRIVATE void ImplInit(vcl::Window *pParent, WinBits nStyle)
Definition: button.cxx:1739
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
Definition: button.cxx:2323
bool IsSystemWindow() const
Definition: window2.cxx:1000
constexpr auto CHECKBOX_VIEW_STYLE
Definition: button.cxx:65
virtual void Tracking(const TrackingEvent &rTEvt) override
Definition: button.cxx:3161
virtual void SetText(const OUString &rStr) override
Definition: ctrl.cxx:95
tools::Long mnSeparatorX
Definition: button.cxx:79
virtual void Resize() override
Definition: button.cxx:1387
std::unique_ptr< ImplCommonButtonData > mpButtonData
Definition: button.hxx:43
sal_uInt16 mnRadioStyle
Definition: svdata.hxx:277
virtual FactoryFunction GetUITestFactory() const override
Definition: button.cxx:574
WinBits const WB_VCENTER
SAL_DLLPRIVATE void ImplDrawRadioCheck(OutputDevice *pDev, WinBits nWinStyle, DrawFlags nDrawFlags, const Point &rPos, const Size &rSize, const Size &rImageSize, tools::Rectangle &rStateRect, tools::Rectangle &rMouseRect)
Definition: button.cxx:2019
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
Definition: paint.cxx:1144
TRISTATE_FALSE
SAL_DLLPRIVATE DrawTextFlags ImplGetTextStyle(DrawFlags nDrawFlags) const
Definition: button.cxx:737
SAL_DLLPRIVATE Size ImplGetCheckImageSize() const
Definition: button.cxx:3521
void EnableTriState(bool bTriState=true)
Definition: button.cxx:3510
CancelButton(const CancelButton &)=delete
bool IsUpdateMode() const
Definition: window2.cxx:1176
void SetFillColor()
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:162
const AllSettings & GetSettings() const
Definition: window3.cxx:129
const Color & GetFieldColor() const
std::vector< VclPtr< RadioButton > > GetRadioButtonGroup(bool bIncludeThis=true) const
GetRadioButtonGroup returns a list of pointers to RadioButtons in the same group. ...
Definition: button.cxx:2219
bool IsChecked() const
Definition: button.hxx:348
virtual FactoryFunction GetUITestFactory() const override
Definition: button.cxx:2946
SAL_DLLPRIVATE void ImplDrawAlignedImage(OutputDevice *pDev, Point &rPos, Size &rSize, sal_Int32 nImageSep, DrawTextFlags nTextStyle, tools::Rectangle *pSymbolRect=nullptr, bool bAddImageSep=false)
Definition: button.cxx:206
bool IsDialog() const
Definition: window2.cxx:1005
void SetTextColor(const Color &rColor)
Definition: text.cxx:662
bool GetNativeControlRegion(ControlType nType, ControlPart nPart, const tools::Rectangle &rControlRegion, ControlState nState, const ImplControlValue &aValue, tools::Rectangle &rNativeBoundingRegion, tools::Rectangle &rNativeContentRegion) const
Query the native control's actual drawing region (including adornment)
Definition: window3.cxx:79
virtual const vcl::Font & GetCanonicalFont(const StyleSettings &_rStyle) const override
Definition: button.cxx:1861
std::unique_ptr< WindowImpl > mpWindowImpl
Definition: window.hxx:496
WinBits const WB_SMALLSTYLE
DrawSymbolFlags
Definition: decoview.hxx:34
virtual Size GetOptimalSize() const override
Definition: button.cxx:2912
bool IsZoom() const
Definition: window2.cxx:1218
WinBits const WB_RECTSTYLE
virtual void KeyInput(const KeyEvent &rKEvt) override
Definition: button.cxx:2388
virtual void KeyUp(const KeyEvent &rKEvt) override
Definition: button.cxx:3223
MouseNotifyEvent GetType() const
Definition: event.hxx:300
bool IsInside(const Point &rPOINT) const
bool DrawNativeControl(ControlType nType, ControlPart nPart, const tools::Rectangle &rControlRegion, ControlState nState, const ImplControlValue &aValue, const OUString &aCaption, const Color &rBackgroundColor=COL_AUTO)
Request rendering of a particular control and/or part.
void SetTop(tools::Long v)
void SetBottom(tools::Long v)
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
Definition: ctrl.cxx:59
const AllSettings & GetSettings() const
Definition: outdev.hxx:280
void SetPaintTransparent(bool bTransparent)
Definition: paint.cxx:1026
TriState meState
Definition: button.hxx:291
bool IsInExecute() const
Definition: dialog.hxx:122
virtual bool set_property(const OString &rKey, const OUString &rValue)
Definition: window2.cxx:1448
static SAL_DLLPRIVATE WinBits ImplInitStyle(const vcl::Window *pPrevWindow, WinBits nStyle)
Definition: button.cxx:624
tools::Long Top() const
virtual void LoseFocus()
Definition: window.cxx:1851
Button(const Button &)=delete
void DumpAsPropertyTree(tools::JsonWriter &) override
Button has additional stuff that we need to dump too.
Definition: button.cxx:3708
void DrawCtrlText(const Point &rPos, const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, DrawTextFlags nStyle=DrawTextFlags::Mnemonic, std::vector< tools::Rectangle > *pVector=nullptr, OUString *pDisplayText=nullptr, const SalLayoutGlyphs *pGlyphs=nullptr)
Definition: text.cxx:2060
virtual const Color & GetCanonicalTextColor(const StyleSettings &_rStyle) const override
Definition: button.cxx:650
Point ScreenToOutputPixel(const Point &rPos) const
Definition: window.cxx:2804
void GrabFocus()
Definition: window.cxx:2971
bool mbUsesExplicitGroup
Definition: button.hxx:384
virtual void ShowFocus(const tools::Rectangle &rRect)
Definition: window2.cxx:49
vcl::Window * GetParent() const
Definition: window2.cxx:1100
virtual void FillLayoutData() const override
Definition: button.cxx:2422
WinBits const WB_LEFT
const Color & GetDefaultActionButtonPressedRolloverTextColor() const
virtual void GetFocus() override
Definition: button.cxx:2513
void Toggle()
Definition: button.cxx:1530
SAL_DLLPRIVATE void ImplDrawPushButton(vcl::RenderContext &rRenderContext)
Definition: button.cxx:902
bool IsTrackingEnded() const
Definition: event.hxx:261
void SetStyle(WinBits nStyle)
Definition: window.cxx:1958
virtual void Draw(OutputDevice *pDev, const Point &rPos, DrawFlags nFlags) override
Definition: button.cxx:3247
void DrawSeparator(const Point &rStart, const Point &rStop, bool bVertical=true)
Definition: decoview.cxx:997
virtual void Draw(OutputDevice *pDev, const Point &rPos, DrawFlags nFlags) override
Definition: button.cxx:2433
virtual void MouseButtonDown(const MouseEvent &rMEvt) override
Definition: button.cxx:3148
void put(const char *pPropName, const OUString &rPropValue)
WinBits const WB_REPEAT
constexpr sal_uInt16 KEY_RETURN
Definition: keycodes.hxx:119
SAL_DLLPRIVATE void ImplInitPushButtonData()
Definition: button.cxx:593
const Color & GetButtonRolloverTextColor() const
SAL_DLLPRIVATE void ImplInitStyle()
Definition: button.cxx:3725
const Color & GetDefaultActionButtonRolloverTextColor() const
constexpr Point TopLeft() const
StyleSettingsOptions GetOptions() const
tools::Long AdjustTop(tools::Long nVertMoveDelta)
vcl::Window * GetWindow(GetWindowType nType) const
Definition: stacking.cxx:1035
virtual void StateChanged(StateChangedType nType) override
Definition: button.cxx:2532
Point LogicToPixel(const Point &rLogicPt) const
Definition: map.cxx:835
bool HasImage() const
Definition: button.cxx:146
ControlType
These types are all based on the supported variants vcl/salnativewidgets.hxx and must be kept in-sync...
virtual void setPosSizePixel(tools::Long nX, tools::Long nY, tools::Long nWidth, tools::Long nHeight, PosSizeFlags nFlags=PosSizeFlags::All)
Definition: window.cxx:2661
virtual void KeyInput(const KeyEvent &rKEvt)
Definition: window.cxx:1801
SAL_DLLPRIVATE void ImplInit(vcl::Window *pParent, WinBits nStyle, SystemParentData *pSystemParentData)
Definition: window.cxx:935
WinBits const WB_3DLOOK
bool mbUseNativeFocus
Definition: window.h:312
SAL_DLLPRIVATE void ImplInit(vcl::Window *pParent, WinBits nStyle)
Definition: button.cxx:2957
DrawButtonFlags GetButtonState() const
Definition: button.cxx:517
bool IsModifierChanged() const
Definition: event.hxx:144
virtual const Color & GetCanonicalTextColor(const StyleSettings &_rStyle) const override
Definition: button.cxx:1866
OKButton(const OKButton &)=delete
void set_id(const OUString &rID)
Sets an ID.
Definition: window.cxx:3913
void SetCustomButtonImage(const Image &rImage)
Set an image to use as the complete render view of a custom button, instead of the usual contents of ...
Definition: button.cxx:165
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
Definition: button.cxx:1333
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: button.cxx:2646
virtual void StateChanged(StateChangedType nType) override
Definition: button.cxx:1407
virtual const vcl::Font & GetCanonicalFont(const StyleSettings &_rStyle) const override
Definition: button.cxx:2975
const sal_uInt32 LEFT
virtual void ImplDrawCheckBoxState(vcl::RenderContext &rRenderContext)
Definition: button.cxx:3016
void ImplAdjustNWFSizes() override
Definition: button.cxx:2837
const vcl::KeyCode & GetKeyCode() const
Definition: event.hxx:57
static vcl::Window * GetFocusWindow()
Get the currently focused window.
Definition: svapp.cxx:1064
SAL_DLLPRIVATE void ImplDraw(OutputDevice *pDev, DrawFlags nDrawFlags, const Point &rPos, const Size &rSize, const Size &rImageSize, tools::Rectangle &rStateRect, tools::Rectangle &rMouseRect)
Definition: button.cxx:3063
void SetSmallSymbol()
Definition: button.cxx:531
constexpr Size GetSize() const
void SetPressed(bool bPressed)
Definition: button.cxx:1588
void SetFaceColor(const Color &rColor)
static SAL_DLLPRIVATE DrawTextFlags ImplGetTextStyle(WinBits nWinBits)
Definition: fixed.cxx:104
bool IsMouseOver() const
Definition: mouse.cxx:611
virtual void Resize() override
Definition: ctrl.cxx:74
SAL_DLLPRIVATE bool ImplIsDefButton() const
Definition: button.cxx:1169
static SAL_DLLPRIVATE bool ImplHitTestPushButton(vcl::Window const *pDev, const Point &rPos)
Definition: button.cxx:729
WindowType
std::vector< Image > maCheckImgList
Definition: svdata.hxx:271
Definition: ctrl.hxx:33
virtual void Resize() override
Definition: button.cxx:3345
bool IsSynthetic() const
Definition: event.hxx:142
virtual void GetFocus()
Definition: window.cxx:1837
tools::Rectangle & Union(const tools::Rectangle &rRect)
const Color & GetButtonTextColor() const
bool mbNoFocusRects
Definition: svdata.hxx:321
constexpr tools::Long Height() const
unsigned char sal_uInt8
const Color & GetDefaultActionButtonTextColor() const
bool mbStateChanged
Definition: button.hxx:383
constexpr sal_uInt16 KEY_ESCAPE
Definition: keycodes.hxx:120
void SetFont(const vcl::Font &rNewFont)
std::vector< Image > maRadioImgList
Definition: svdata.hxx:272
const MouseEvent * GetMouseEvent() const
Definition: event.hxx:316
std::unique_ptr< vcl::ImplControlData > mpControlData
Definition: ctrl.hxx:36
SAL_DLLPRIVATE void ImplDrawCheckBox(vcl::RenderContext &rRenderContext)
Definition: button.cxx:3104
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
Definition: button.cxx:2428
const Color & GetFlatButtonRolloverTextColor() const
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_WHITE
tools::Long GetTextHeight() const
Height where any character of the current font fits; in logic coordinates.
Definition: text.cxx:891
sal_Int32 get_width_request() const
Definition: window2.cxx:1921
virtual void Tracking(const TrackingEvent &rTEvt) override
Definition: button.cxx:2347
const Color & GetFlatButtonPressedRolloverTextColor() const
constexpr Point TopRight() const
virtual void DumpAsPropertyTree(tools::JsonWriter &) override
Dumps itself and potentially its children to a property tree, to be written easily to JSON...
Definition: button.cxx:579
vcl::Font GetDrawPixelFont(::OutputDevice const *pDev) const
Definition: window2.cxx:551
::OutputDevice const * GetOutDev() const
Definition: window.cxx:565
virtual FactoryFunction GetUITestFactory() const override
Definition: button.cxx:3714
void EnableChildTransparentMode(bool bEnable=true)
Definition: window2.cxx:1025
bool IsLeft() const
Definition: event.hxx:149
virtual void DataChanged(const DataChangedEvent &rDCEvt) override
Definition: button.cxx:2578
tools::Long AdjustWidth(tools::Long n)
Definition: image.hxx:39
tools::Rectangle maFocusRect
Definition: button.cxx:78
SAL_DLLPRIVATE WinBits ImplInitStyle(const vcl::Window *pPrevWindow, WinBits nStyle)
Definition: button.cxx:1845
Color mnLastRadioFColor
Definition: svdata.hxx:281
virtual void KeyUp(const KeyEvent &rKEvt) override
Definition: button.cxx:1296
bool mbChecked
Definition: button.hxx:381
void SetState(TriState eState)
Definition: button.cxx:1558
tools::Rectangle GetTextRect(const tools::Rectangle &rRect, const OUString &rStr, DrawTextFlags nStyle=DrawTextFlags::WordBreak, TextRectInfo *pInfo=nullptr, const vcl::ITextLayout *_pTextLayout=nullptr) const
Definition: window3.cxx:201
const Color & GetTextColor() const
Definition: window3.cxx:109
virtual void ShowFocus(const tools::Rectangle &rRect) override
Definition: button.cxx:2917
tools::Long CalcZoom(tools::Long n) const
Definition: window2.cxx:395
tools::Long GetDrawPixel(::OutputDevice const *pDev, tools::Long nPixels) const
Definition: window2.cxx:561
const ::std::vector< Color > ImpSvNumber