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