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 
191 DrawTextFlags Button::ImplGetTextStyle( WinBits nWinStyle, SystemTextColorFlags nSystemTextColorFlags ) const
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.Contains( 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.Contains(GetPointerPosPixel()))
991  nState |= ControlState::ROLLOVER;
992 
993  if ( IsMouseOver() && aInRect.Contains(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.Contains(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 
1369  std::optional<StyleSettings> oOrigDevStyleSettings;
1370 
1371  if ( nFlags & SystemTextColorFlags::Mono )
1372  {
1373  pDev->SetTextColor( COL_BLACK );
1374  }
1375  else
1376  {
1377  pDev->SetTextColor( GetTextColor() );
1378  // DecoView uses the FaceColor...
1379  AllSettings aSettings = pDev->GetSettings();
1380  StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1381  oOrigDevStyleSettings = aStyleSettings;
1382  if ( IsControlBackground() )
1383  aStyleSettings.SetFaceColor( GetControlBackground() );
1384  else
1385  aStyleSettings.SetFaceColor( GetSettings().GetStyleSettings().GetFaceColor() );
1386  aSettings.SetStyleSettings( aStyleSettings );
1387  pDev->OutputDevice::SetSettings( aSettings );
1388  }
1389  pDev->SetTextFillColor();
1390 
1391  DecorationView aDecoView( pDev );
1392  DrawButtonFlags nButtonStyle = DrawButtonFlags::NONE;
1393  if ( nFlags & SystemTextColorFlags::Mono )
1394  nButtonStyle |= DrawButtonFlags::Mono;
1395  if ( IsChecked() )
1396  nButtonStyle |= DrawButtonFlags::Checked;
1397  aRect = aDecoView.DrawButton( aRect, nButtonStyle );
1398 
1399  ImplDrawPushButtonContent( pDev, nFlags, aRect, true, nButtonStyle );
1400 
1401  // restore original settings (which are not affected by Push/Pop) after
1402  // finished drawing
1403  if (oOrigDevStyleSettings)
1404  {
1405  AllSettings aSettings = pDev->GetSettings();
1406  aSettings.SetStyleSettings(*oOrigDevStyleSettings);
1407  pDev->OutputDevice::SetSettings( aSettings );
1408  }
1409 
1410  pDev->Pop();
1411 }
1412 
1414 {
1415  Control::Resize();
1416  Invalidate();
1417 }
1418 
1420 {
1423  Button::GetFocus();
1424 }
1425 
1427 {
1428  EndSelection();
1429  HideFocus();
1431 }
1432 
1434 {
1435  Button::StateChanged( nType );
1436 
1437  if ( (nType == StateChangedType::Enable) ||
1438  (nType == StateChangedType::Text) ||
1439  (nType == StateChangedType::Data) ||
1440  (nType == StateChangedType::State) ||
1441  (nType == StateChangedType::UpdateMode) )
1442  {
1443  if ( IsReallyVisible() && IsUpdateMode() )
1444  Invalidate();
1445  }
1446  else if ( nType == StateChangedType::Style )
1447  {
1449 
1450  bool bIsDefButton = ( GetStyle() & WB_DEFBUTTON ) != 0;
1451  bool bWasDefButton = ( GetPrevStyle() & WB_DEFBUTTON ) != 0;
1452  if ( bIsDefButton != bWasDefButton )
1453  ImplSetDefButton( bIsDefButton );
1454 
1455  if ( IsReallyVisible() && IsUpdateMode() )
1456  {
1457  if ( (GetPrevStyle() & PUSHBUTTON_VIEW_STYLE) !=
1459  Invalidate();
1460  }
1461  }
1462  else if ( (nType == StateChangedType::Zoom) ||
1463  (nType == StateChangedType::ControlFont) )
1464  {
1465  ImplInitSettings( false );
1466  Invalidate();
1467  }
1468  else if ( nType == StateChangedType::ControlForeground )
1469  {
1470  ImplInitSettings( false );
1471  Invalidate();
1472  }
1473  else if ( nType == StateChangedType::ControlBackground )
1474  {
1475  ImplInitSettings( true );
1476  Invalidate();
1477  }
1478 }
1479 
1481 {
1482  Button::DataChanged( rDCEvt );
1483 
1484  if ( (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
1486  ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
1487  (rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
1488  {
1489  ImplInitSettings( true );
1490  Invalidate();
1491  }
1492 }
1493 
1495 {
1496  if( rNEvt.GetType() == MouseNotifyEvent::MOUSEMOVE )
1497  {
1498  const MouseEvent* pMouseEvt = rNEvt.GetMouseEvent();
1499  if( pMouseEvt && (pMouseEvt->IsEnterWindow() || pMouseEvt->IsLeaveWindow()) )
1500  {
1501  // trigger redraw as mouse over state has changed
1502 
1503  // TODO: move this to Window class or make it a member !!!
1504  ControlType aCtrlType = ControlType::Generic;
1505  switch( GetParent()->GetType() )
1506  {
1507  case WindowType::LISTBOX:
1508  case WindowType::MULTILISTBOX:
1509  case WindowType::TREELISTBOX:
1510  aCtrlType = ControlType::Listbox;
1511  break;
1512 
1513  case WindowType::COMBOBOX:
1514  case WindowType::PATTERNBOX:
1515  case WindowType::NUMERICBOX:
1516  case WindowType::METRICBOX:
1517  case WindowType::CURRENCYBOX:
1518  case WindowType::DATEBOX:
1519  case WindowType::TIMEBOX:
1520  case WindowType::LONGCURRENCYBOX:
1521  aCtrlType = ControlType::Combobox;
1522  break;
1523  default:
1524  break;
1525  }
1526 
1527  bool bDropDown = ( IsSymbol() && (GetSymbol()==SymbolType::SPIN_DOWN) && GetText().isEmpty() );
1528 
1529  if( bDropDown && GetParent()->IsNativeControlSupported( aCtrlType, ControlPart::Entire) &&
1531  {
1533  if(aCtrlType == ControlType::Combobox)
1534  {
1535  // only paint the button part to avoid flickering of the combobox text
1536  tools::Rectangle aClipRect( Point(), GetOutputSizePixel() );
1537  aClipRect.SetPos(pBorder->ScreenToOutputPixel(OutputToScreenPixel(aClipRect.TopLeft())));
1538  pBorder->Invalidate( aClipRect );
1539  }
1540  else
1541  {
1543  }
1544  }
1545  else if( (GetStyle() & WB_FLATBUTTON) ||
1547  {
1548  Invalidate();
1549  }
1550  }
1551  }
1552 
1553  return Button::PreNotify(rNEvt);
1554 }
1555 
1557 {
1559 }
1560 
1562 {
1563  if ( meSymbol != eSymbol )
1564  {
1565  meSymbol = eSymbol;
1567  }
1568 }
1569 
1571 {
1572  ImplSetSymbolAlign( eAlign );
1573 }
1574 
1576 {
1577  if ( mnDDStyle != nStyle )
1578  {
1579  mnDDStyle = nStyle;
1581  }
1582 }
1583 
1585 {
1586  if ( meState == eState )
1587  return;
1588 
1589  meState = eState;
1590  if ( meState == TRISTATE_FALSE )
1592  else if ( meState == TRISTATE_TRUE )
1593  {
1594  GetButtonState() &= ~DrawButtonFlags::DontKnow;
1596  }
1597  else // TRISTATE_INDET
1598  {
1599  GetButtonState() &= ~DrawButtonFlags::Checked;
1601  }
1602 
1604  Toggle();
1605 }
1606 
1607 void PushButton::statusChanged(const css::frame::FeatureStateEvent& rEvent)
1608 {
1609  Button::statusChanged(rEvent);
1610  if (rEvent.State.has<bool>())
1611  SetPressed(rEvent.State.get<bool>());
1612 }
1613 
1614 void PushButton::SetPressed( bool bPressed )
1615 {
1616  if ( mbPressed != bPressed )
1617  {
1618  mbPressed = bPressed;
1620  }
1621 }
1622 
1624 {
1626  if ( !isDisposed() &&
1628  {
1630  if ( !mbPressed )
1631  Invalidate();
1632  }
1633 }
1634 
1636 {
1637  Size aSize;
1638 
1639  if ( IsSymbol() )
1640  {
1641  if ( IsSmallSymbol ())
1642  aSize = Size( 16, 12 );
1643  else
1644  aSize = Size( 26, 24 );
1645  }
1646  else if ( Button::HasImage() )
1647  aSize = GetModeImage().GetSizePixel();
1650  {
1651  tools::Long nSymbolSize = GetTextHeight() / 2 + 1;
1652  aSize.AdjustWidth(2*nSymbolSize );
1653  }
1654  if (!PushButton::GetText().isEmpty())
1655  {
1656  Size textSize = GetTextRect( tools::Rectangle( Point(), Size( 0x7fffffff, 0x7fffffff ) ),
1658 
1659  tools::Long nTextHeight = textSize.Height() * 1.15;
1660 
1661  ImageAlign eImageAlign = GetImageAlign();
1662  // tdf#142337 only considering the simple top/bottom/left/right possibilities
1663  if (eImageAlign == ImageAlign::Top || eImageAlign == ImageAlign::Bottom)
1664  {
1665  aSize.AdjustHeight(nTextHeight);
1666  aSize.setWidth(std::max(aSize.Width(), textSize.Width()));
1667  }
1668  else
1669  {
1670  aSize.AdjustWidth(textSize.Width());
1671  aSize.setHeight(std::max(aSize.Height(), nTextHeight));
1672  }
1673  }
1674 
1675  // cf. ImplDrawPushButton ...
1676  if( (GetStyle() & WB_SMALLSTYLE) == 0 )
1677  {
1678  aSize.AdjustWidth(24 );
1679  aSize.AdjustHeight(12 );
1680  }
1681 
1682  return CalcWindowSize( aSize );
1683 }
1684 
1686 {
1687  return CalcMinimumSize();
1688 }
1689 
1690 bool PushButton::set_property(const OString &rKey, const OUString &rValue)
1691 {
1692  if (rKey == "has-default")
1693  {
1694  WinBits nBits = GetStyle();
1695  nBits &= ~WB_DEFBUTTON;
1696  if (toBool(rValue))
1697  nBits |= WB_DEFBUTTON;
1698  SetStyle(nBits);
1699  }
1700  else
1701  return Button::set_property(rKey, rValue);
1702  return true;
1703 }
1704 
1706 {
1708  {
1709  PushButtonValue aControlValue;
1710  aControlValue.mbIsAction = isAction();
1713  ControlState::FOCUSED, aControlValue, OUString());
1714  }
1715  Button::ShowFocus(rRect);
1716 }
1717 
1718 void OKButton::ImplInit( vcl::Window* pParent, WinBits nStyle )
1719 {
1720  set_id("ok");
1721  PushButton::ImplInit( pParent, nStyle );
1722 
1723  SetText( GetStandardText( StandardButtonType::OK ) );
1724 }
1725 
1728 {
1729  ImplInit( pParent, nStyle );
1730 }
1731 
1733 {
1734  // close parent if no link set
1735  if ( !GetClickHdl() )
1736  {
1737  vcl::Window* pParent = getNonLayoutParent(this);
1738  if ( pParent->IsSystemWindow() )
1739  {
1740  if ( pParent->IsDialog() )
1741  {
1742  VclPtr<Dialog> xParent( static_cast<Dialog*>(pParent) );
1743  if ( xParent->IsInExecute() )
1744  xParent->EndDialog( RET_OK );
1745  // prevent recursive calls
1746  else if ( !xParent->IsInClose() )
1747  {
1748  if ( pParent->GetStyle() & WB_CLOSEABLE )
1749  xParent->Close();
1750  }
1751  }
1752  else
1753  {
1754  if ( pParent->GetStyle() & WB_CLOSEABLE )
1755  static_cast<SystemWindow*>(pParent)->Close();
1756  }
1757  }
1758  }
1759  else
1760  {
1762  }
1763 }
1764 
1766 {
1767  set_id("cancel");
1768  PushButton::ImplInit( pParent, nStyle );
1769 
1770  SetText( GetStandardText( StandardButtonType::Cancel ) );
1771 }
1772 
1775 {
1776  ImplInit( pParent, nStyle );
1777 }
1778 
1780 {
1781  // close parent if link not set
1782  if ( !GetClickHdl() )
1783  {
1784  vcl::Window* pParent = getNonLayoutParent(this);
1785  if ( pParent->IsSystemWindow() )
1786  {
1787  if ( pParent->IsDialog() )
1788  {
1789  if ( static_cast<Dialog*>(pParent)->IsInExecute() )
1790  static_cast<Dialog*>(pParent)->EndDialog();
1791  // prevent recursive calls
1792  else if ( !static_cast<Dialog*>(pParent)->IsInClose() )
1793  {
1794  if ( pParent->GetStyle() & WB_CLOSEABLE )
1795  static_cast<Dialog*>(pParent)->Close();
1796  }
1797  }
1798  else
1799  {
1800  if ( pParent->GetStyle() & WB_CLOSEABLE )
1801  static_cast<SystemWindow*>(pParent)->Close();
1802  }
1803  }
1804  }
1805  else
1806  {
1808  }
1809 }
1810 
1812  : CancelButton(pParent, 0)
1813 {
1814  SetText( GetStandardText( StandardButtonType::Close ) );
1815 }
1816 
1817 void HelpButton::ImplInit( vcl::Window* pParent, WinBits nStyle )
1818 {
1819  set_id("help");
1820  PushButton::ImplInit( pParent, nStyle | WB_NOPOINTERFOCUS );
1821 
1822  SetText( GetStandardText( StandardButtonType::Help ) );
1823 }
1824 
1827 {
1828  ImplInit( pParent, nStyle );
1829 }
1830 
1832 {
1833  // trigger help if no link set
1834  if ( !GetClickHdl() )
1835  {
1837  if ( !pFocusWin || comphelper::LibreOfficeKit::isActive() )
1838  pFocusWin = this;
1839 
1840  HelpEvent aEvt( pFocusWin->GetPointerPosPixel(), HelpEventMode::CONTEXT );
1841  pFocusWin->RequestHelp( aEvt );
1842  }
1844 }
1845 
1847 {
1848  // Hide when we have no help URL.
1850  officecfg::Office::Common::Help::HelpRootURL::get().isEmpty())
1851  Hide();
1852  else
1853  PushButton::StateChanged(nStateChange);
1854 }
1855 
1857 {
1858  mbChecked = false;
1859  mbRadioCheck = true;
1860  mbStateChanged = false;
1861 }
1862 
1864 {
1865  nStyle = ImplInitStyle(getPreviousSibling(pParent), nStyle);
1866  Button::ImplInit( pParent, nStyle, nullptr );
1867 
1868  ImplInitSettings( true );
1869 }
1870 
1871 WinBits RadioButton::ImplInitStyle( const vcl::Window* pPrevWindow, WinBits nStyle ) const
1872 {
1873  if ( !(nStyle & WB_NOGROUP) &&
1874  (!pPrevWindow || (pPrevWindow->GetType() != WindowType::RADIOBUTTON)) )
1875  nStyle |= WB_GROUP;
1876  if ( !(nStyle & WB_NOTABSTOP) )
1877  {
1878  if ( IsChecked() )
1879  nStyle |= WB_TABSTOP;
1880  else
1881  nStyle &= ~WB_TABSTOP;
1882  }
1883 
1884  return nStyle;
1885 }
1886 
1888 {
1889  return _rStyle.GetRadioCheckFont();
1890 }
1891 
1893 {
1894  return _rStyle.GetRadioCheckTextColor();
1895 }
1896 
1897 void RadioButton::ImplInitSettings( bool bBackground )
1898 {
1900 
1901  if ( !bBackground )
1902  return;
1903 
1904  vcl::Window* pParent = GetParent();
1905  if ( !IsControlBackground() &&
1907  {
1910  SetPaintTransparent( true );
1911  SetBackground();
1913  mpWindowImpl->mbUseNativeFocus = ImplGetSVData()->maNWFData.mbNoFocusRects;
1914  }
1915  else
1916  {
1917  EnableChildTransparentMode( false );
1919  SetPaintTransparent( false );
1920 
1921  if ( IsControlBackground() )
1923  else
1924  SetBackground( pParent->GetBackground() );
1925  }
1926 }
1927 
1929 {
1930  bool bNativeOK = false;
1931 
1932  // no native drawing for image radio buttons
1934  {
1938 
1940  nState |= ControlState::PRESSED;
1941  if (HasFocus())
1942  nState |= ControlState::FOCUSED;
1944  nState |= ControlState::DEFAULT;
1945  if (IsEnabled())
1946  nState |= ControlState::ENABLED;
1947 
1949  nState |= ControlState::ROLLOVER;
1950 
1951  bNativeOK = rRenderContext.DrawNativeControl(ControlType::Radiobutton, ControlPart::Entire, aCtrlRect,
1952  nState, aControlValue, OUString());
1953  }
1954 
1955  if (bNativeOK)
1956  return;
1957 
1958  if (!maImage)
1959  {
1960  DrawButtonFlags nStyle = GetButtonState();
1961  if (!IsEnabled())
1962  nStyle |= DrawButtonFlags::Disabled;
1963  if (mbChecked)
1964  nStyle |= DrawButtonFlags::Checked;
1965  Image aImage = GetRadioImage(rRenderContext.GetSettings(), nStyle);
1966  if (IsZoom())
1967  rRenderContext.DrawImage(maStateRect.TopLeft(), maStateRect.GetSize(), aImage);
1968  else
1969  rRenderContext.DrawImage(maStateRect.TopLeft(), aImage);
1970  }
1971  else
1972  {
1973  HideFocus();
1974 
1975  DecorationView aDecoView(&rRenderContext);
1976  const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
1977  tools::Rectangle aImageRect = maStateRect;
1978  Size aImageSize = maImage.GetSizePixel();
1979  bool bEnabled = IsEnabled();
1980 
1981  aImageSize.setWidth( CalcZoom(aImageSize.Width()) );
1982  aImageSize.setHeight( CalcZoom(aImageSize.Height()) );
1983 
1984  aImageRect.AdjustLeft( 1 );
1985  aImageRect.AdjustTop( 1 );
1986  aImageRect.AdjustRight( -1 );
1987  aImageRect.AdjustBottom( -1 );
1988 
1989  // display border and selection status
1990  aImageRect = aDecoView.DrawFrame(aImageRect, DrawFrameStyle::DoubleIn);
1991  if ((GetButtonState() & DrawButtonFlags::Pressed) || !bEnabled)
1992  rRenderContext.SetFillColor( rStyleSettings.GetFaceColor());
1993  else
1994  rRenderContext.SetFillColor(rStyleSettings.GetFieldColor());
1995  rRenderContext.SetLineColor();
1996  rRenderContext.DrawRect(aImageRect);
1997 
1998  // display image
1999  DrawImageFlags nImageStyle = DrawImageFlags::NONE;
2000  if (!bEnabled)
2001  nImageStyle |= DrawImageFlags::Disable;
2002 
2003  Image* pImage = &maImage;
2004 
2005  Point aImagePos(aImageRect.TopLeft());
2006  aImagePos.AdjustX((aImageRect.GetWidth() - aImageSize.Width()) / 2 );
2007  aImagePos.AdjustY((aImageRect.GetHeight() - aImageSize.Height()) / 2 );
2008  if (IsZoom())
2009  rRenderContext.DrawImage(aImagePos, aImageSize, *pImage, nImageStyle);
2010  else
2011  rRenderContext.DrawImage(aImagePos, *pImage, nImageStyle);
2012 
2013  aImageRect.AdjustLeft( 1 );
2014  aImageRect.AdjustTop( 1 );
2015  aImageRect.AdjustRight( -1 );
2016  aImageRect.AdjustBottom( -1 );
2017 
2018  ImplSetFocusRect(aImageRect);
2019 
2020  if (mbChecked)
2021  {
2022  rRenderContext.SetLineColor(rStyleSettings.GetHighlightColor());
2023  rRenderContext.SetFillColor();
2024  if ((aImageSize.Width() >= 20) || (aImageSize.Height() >= 20))
2025  {
2026  aImageRect.AdjustLeft( 1 );
2027  aImageRect.AdjustTop( 1 );
2028  aImageRect.AdjustRight( -1 );
2029  aImageRect.AdjustBottom( -1 );
2030  }
2031  rRenderContext.DrawRect(aImageRect);
2032  aImageRect.AdjustLeft( 1 );
2033  aImageRect.AdjustTop( 1 );
2034  aImageRect.AdjustRight( -1 );
2035  aImageRect.AdjustBottom( -1 );
2036  rRenderContext.DrawRect(aImageRect);
2037  }
2038 
2039  if (HasFocus())
2041  }
2042 }
2043 
2044 // for drawing RadioButton or CheckButton that has Text and/or Image
2045 void Button::ImplDrawRadioCheck(OutputDevice* pDev, WinBits nWinStyle, SystemTextColorFlags nSystemTextColorFlags,
2046  const Point& rPos, const Size& rSize,
2047  const Size& rImageSize, tools::Rectangle& rStateRect,
2048  tools::Rectangle& rMouseRect)
2049 {
2050  DrawTextFlags nTextStyle = Button::ImplGetTextStyle( nWinStyle, nSystemTextColorFlags );
2051 
2052  const tools::Long nImageSep = GetDrawPixel( pDev, ImplGetImageToTextDistance() );
2053  Size aSize( rSize );
2054  Point aPos( rPos );
2055  aPos.AdjustX(rImageSize.Width() + nImageSep );
2056 
2057  // tdf#141761 Old (convenience?) adjustment of width may lead to empty
2058  // or negative(!) Size, that needs to be avoided. The coordinate context
2059  // is pixel-oriented (all Paints of Controls are, historically), so
2060  // the minimum width should be '1' Pixel.
2061  // Hint: nImageSep is based on Zoom (using Window::CalcZoom) and
2062  // MapModes (using Window::GetDrawPixel) - so potentially a wide range
2063  // of unpredictable values is possible
2064  const tools::Long nWidthAdjust(rImageSize.Width() + nImageSep);
2065  aSize.setWidth(std::max(static_cast<tools::Long>(1), aSize.getWidth() - nWidthAdjust));
2066 
2067  // if the text rect height is smaller than the height of the image
2068  // then for single lines the default should be centered text
2069  if( (nWinStyle & (WB_TOP|WB_VCENTER|WB_BOTTOM)) == 0 &&
2070  (rImageSize.Height() > rSize.Height() || ! (nWinStyle & WB_WORDBREAK) ) )
2071  {
2073  nTextStyle |= DrawTextFlags::VCenter;
2074  aSize.setHeight( rImageSize.Height() );
2075  }
2076 
2077  ImplDrawAlignedImage( pDev, aPos, aSize, 1, nTextStyle );
2078 
2079  rMouseRect = tools::Rectangle( aPos, aSize );
2080  rMouseRect.SetLeft( rPos.X() );
2081 
2082  rStateRect.SetLeft( rPos.X() );
2083  rStateRect.SetTop( rMouseRect.Top() );
2084 
2085  if ( aSize.Height() > rImageSize.Height() )
2086  rStateRect.AdjustTop(( aSize.Height() - rImageSize.Height() ) / 2 );
2087  else
2088  {
2089  rStateRect.AdjustTop( -(( rImageSize.Height() - aSize.Height() ) / 2) );
2090  if( rStateRect.Top() < 0 )
2091  rStateRect.SetTop( 0 );
2092  }
2093 
2094  rStateRect.SetRight( rStateRect.Left()+rImageSize.Width()-1 );
2095  rStateRect.SetBottom( rStateRect.Top()+rImageSize.Height()-1 );
2096 
2097  if ( rStateRect.Bottom() > rMouseRect.Bottom() )
2098  rMouseRect.SetBottom( rStateRect.Bottom() );
2099 }
2100 
2101 void RadioButton::ImplDraw( OutputDevice* pDev, SystemTextColorFlags nSystemTextColorFlags,
2102  const Point& rPos, const Size& rSize,
2103  const Size& rImageSize, tools::Rectangle& rStateRect,
2104  tools::Rectangle& rMouseRect )
2105 {
2106  WinBits nWinStyle = GetStyle();
2107  OUString aText( GetText() );
2108 
2110  pDev->IntersectClipRegion( tools::Rectangle( rPos, rSize ) );
2111 
2112  // no image radio button
2113  if ( !maImage )
2114  {
2115  if (!aText.isEmpty() || HasImage())
2116  {
2117  Button::ImplDrawRadioCheck(pDev, nWinStyle, nSystemTextColorFlags,
2118  rPos, rSize, rImageSize,
2119  rStateRect, rMouseRect);
2120  }
2121  else
2122  {
2123  rStateRect.SetLeft( rPos.X() );
2124  if ( nWinStyle & WB_VCENTER )
2125  rStateRect.SetTop( rPos.Y()+((rSize.Height()-rImageSize.Height())/2) );
2126  else if ( nWinStyle & WB_BOTTOM )
2127  rStateRect.SetTop( rPos.Y()+rSize.Height()-rImageSize.Height() ); //-1;
2128  else
2129  rStateRect.SetTop( rPos.Y() );
2130  rStateRect.SetRight( rStateRect.Left()+rImageSize.Width()-1 );
2131  rStateRect.SetBottom( rStateRect.Top()+rImageSize.Height()-1 );
2132  rMouseRect = rStateRect;
2133 
2134  ImplSetFocusRect( rStateRect );
2135  }
2136  }
2137  else
2138  {
2139  bool bTopImage = (nWinStyle & WB_TOP) != 0;
2140  Size aImageSize = maImage.GetSizePixel();
2141  tools::Rectangle aImageRect( rPos, rSize );
2142  tools::Long nTextHeight = pDev->GetTextHeight();
2143  tools::Long nTextWidth = pDev->GetCtrlTextWidth( aText );
2144 
2145  // calculate position and sizes
2146  if (!aText.isEmpty())
2147  {
2148  Size aTmpSize( (aImageSize.Width()+8), (aImageSize.Height()+8) );
2149  if ( bTopImage )
2150  {
2151  aImageRect.SetLeft( (rSize.Width()-aTmpSize.Width())/2 );
2152  aImageRect.SetTop( (rSize.Height()-(aTmpSize.Height()+nTextHeight+6))/2 );
2153  }
2154  else
2155  aImageRect.SetTop( (rSize.Height()-aTmpSize.Height())/2 );
2156 
2157  aImageRect.SetRight( aImageRect.Left()+aTmpSize.Width() );
2158  aImageRect.SetBottom( aImageRect.Top()+aTmpSize.Height() );
2159 
2160  // display text
2161  Point aTxtPos = rPos;
2162  if ( bTopImage )
2163  {
2164  aTxtPos.AdjustX((rSize.Width()-nTextWidth)/2 );
2165  aTxtPos.AdjustY(aImageRect.Bottom()+6 );
2166  }
2167  else
2168  {
2169  aTxtPos.AdjustX(aImageRect.Right()+8 );
2170  aTxtPos.AdjustY((rSize.Height()-nTextHeight)/2 );
2171  }
2172  pDev->DrawCtrlText( aTxtPos, aText, 0, aText.getLength() );
2173  }
2174 
2175  rMouseRect = aImageRect;
2176  rStateRect = aImageRect;
2177  }
2178 
2179  pDev->Pop();
2180 }
2181 
2183 {
2184  HideFocus();
2185 
2186  Size aImageSize;
2187  if (!maImage)
2188  aImageSize = ImplGetRadioImageSize();
2189  else
2190  aImageSize = maImage.GetSizePixel();
2191 
2192  aImageSize.setWidth( CalcZoom(aImageSize.Width()) );
2193  aImageSize.setHeight( CalcZoom(aImageSize.Height()) );
2194 
2195  // Draw control text
2197  aImageSize, maStateRect, maMouseRect);
2198 
2199  if (!maImage && HasFocus())
2201 
2202  ImplDrawRadioButtonState(rRenderContext);
2203 }
2204 
2206 {
2207  if (&rOther == this)
2208  return;
2209 
2210  if (!m_xGroup)
2211  {
2212  m_xGroup = std::make_shared<std::vector<VclPtr<RadioButton> >>();
2213  m_xGroup->push_back(this);
2214  }
2215 
2216  auto aFind = std::find(m_xGroup->begin(), m_xGroup->end(), VclPtr<RadioButton>(&rOther));
2217  if (aFind == m_xGroup->end())
2218  {
2219  m_xGroup->push_back(&rOther);
2220 
2221  if (rOther.m_xGroup)
2222  {
2223  std::vector< VclPtr<RadioButton> > aOthers(rOther.GetRadioButtonGroup(false));
2224  //make all members of the group share the same button group
2225  for (auto const& elem : aOthers)
2226  {
2227  aFind = std::find(m_xGroup->begin(), m_xGroup->end(), elem);
2228  if (aFind == m_xGroup->end())
2229  m_xGroup->push_back(elem);
2230  }
2231  }
2232 
2233  //make all members of the group share the same button group
2234  for (VclPtr<RadioButton> const & pButton : *m_xGroup)
2235  {
2236  pButton->m_xGroup = m_xGroup;
2237  }
2238  }
2239 
2240  //if this one is checked, uncheck all the others
2241  if (mbChecked)
2243 }
2244 
2245 std::vector< VclPtr<RadioButton> > RadioButton::GetRadioButtonGroup(bool bIncludeThis) const
2246 {
2247  if (m_xGroup)
2248  {
2249  if (bIncludeThis)
2250  return *m_xGroup;
2251  std::vector< VclPtr<RadioButton> > aGroup;
2252  for (VclPtr<RadioButton> const & pRadioButton : *m_xGroup)
2253  {
2254  if (pRadioButton == this)
2255  continue;
2256  aGroup.push_back(pRadioButton);
2257  }
2258  return aGroup;
2259  }
2260 
2261  std::vector<VclPtr<RadioButton>> aGroup;
2262  if (mbUsesExplicitGroup)
2263  return aGroup;
2264 
2265  //old-school
2266 
2267  // go back to first in group;
2268  vcl::Window* pFirst = const_cast<RadioButton*>(this);
2269  while( ( pFirst->GetStyle() & WB_GROUP ) == 0 )
2270  {
2271  vcl::Window* pWindow = pFirst->GetWindow( GetWindowType::Prev );
2272  if( pWindow )
2273  pFirst = pWindow;
2274  else
2275  break;
2276  }
2277  // insert radiobuttons up to next group
2278  do
2279  {
2280  if( pFirst->GetType() == WindowType::RADIOBUTTON )
2281  {
2282  if( pFirst != this || bIncludeThis )
2283  aGroup.emplace_back(static_cast<RadioButton*>(pFirst) );
2284  }
2285  pFirst = pFirst->GetWindow( GetWindowType::Next );
2286  } while( pFirst && ( ( pFirst->GetStyle() & WB_GROUP ) == 0 ) );
2287 
2288  return aGroup;
2289 }
2290 
2292 {
2293  mpWindowImpl->mnStyle |= WB_TABSTOP;
2294 
2295  std::vector<VclPtr<RadioButton> > aGroup(GetRadioButtonGroup(false));
2296  // iterate over radio button group and checked buttons
2297  for (VclPtr<RadioButton>& pWindow : aGroup)
2298  {
2299  if ( pWindow->IsChecked() )
2300  {
2301  pWindow->SetState( false );
2302  if ( pWindow->isDisposed() )
2303  return;
2304  }
2305 
2306  // not inside if clause to always remove wrongly set WB_TABSTOPS
2307  pWindow->mpWindowImpl->mnStyle &= ~WB_TABSTOP;
2308  }
2309 }
2310 
2311 void RadioButton::ImplCallClick( bool bGrabFocus, GetFocusFlags nFocusFlags )
2312 {
2314  mbChecked = true;
2315  mpWindowImpl->mnStyle |= WB_TABSTOP;
2316  Invalidate();
2317  VclPtr<vcl::Window> xWindow = this;
2318  if ( mbRadioCheck )
2320  if ( xWindow->isDisposed() )
2321  return;
2322  if ( bGrabFocus )
2323  ImplGrabFocus( nFocusFlags );
2324  if ( xWindow->isDisposed() )
2325  return;
2326  if ( mbStateChanged )
2327  Toggle();
2328  if ( xWindow->isDisposed() )
2329  return;
2330  Click();
2331  if ( xWindow->isDisposed() )
2332  return;
2333  mbStateChanged = false;
2334 }
2335 
2336 RadioButton::RadioButton(vcl::Window* pParent, bool bUsesExplicitGroup, WinBits nStyle)
2338  , mbUsesExplicitGroup(bUsesExplicitGroup)
2339 {
2341  ImplInit( pParent, nStyle );
2342 }
2343 
2345 {
2346  disposeOnce();
2347 }
2348 
2350 {
2351  if (m_xGroup)
2352  {
2353  m_xGroup->erase(std::remove(m_xGroup->begin(), m_xGroup->end(), VclPtr<RadioButton>(this)),
2354  m_xGroup->end());
2355  m_xGroup.reset();
2356  }
2357  Button::dispose();
2358 }
2359 
2361 {
2362  if ( rMEvt.IsLeft() && maMouseRect.Contains( rMEvt.GetPosPixel() ) )
2363  {
2365  Invalidate();
2366  StartTracking();
2367  return;
2368  }
2369 
2370  Button::MouseButtonDown( rMEvt );
2371 }
2372 
2374 {
2375  if ( rTEvt.IsTrackingEnded() )
2376  {
2378  {
2379  if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() )
2380  GrabFocus();
2381 
2383 
2384  // do not call click handler if aborted
2385  if ( !rTEvt.IsTrackingCanceled() )
2386  ImplCallClick();
2387  else
2388  {
2389  Invalidate();
2390  }
2391  }
2392  }
2393  else
2394  {
2395  if ( maMouseRect.Contains( rTEvt.GetMouseEvent().GetPosPixel() ) )
2396  {
2398  {
2400  Invalidate();
2401  }
2402  }
2403  else
2404  {
2406  {
2408  Invalidate();
2409  }
2410  }
2411  }
2412 }
2413 
2414 void RadioButton::KeyInput( const KeyEvent& rKEvt )
2415 {
2416  vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
2417 
2418  if ( !aKeyCode.GetModifier() && (aKeyCode.GetCode() == KEY_SPACE) )
2419  {
2421  {
2423  Invalidate();
2424  }
2425  }
2426  else if ( (GetButtonState() & DrawButtonFlags::Pressed) && (aKeyCode.GetCode() == KEY_ESCAPE) )
2427  {
2429  Invalidate();
2430  }
2431  else
2432  Button::KeyInput( rKEvt );
2433 }
2434 
2435 void RadioButton::KeyUp( const KeyEvent& rKEvt )
2436 {
2437  vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
2438 
2439  if ( (GetButtonState() & DrawButtonFlags::Pressed) && (aKeyCode.GetCode() == KEY_SPACE) )
2440  {
2442  ImplCallClick();
2443  }
2444  else
2445  Button::KeyUp( rKEvt );
2446 }
2447 
2449 {
2450  mxLayoutData.emplace();
2451  const_cast<RadioButton*>(this)->Invalidate();
2452 }
2453 
2455 {
2456  ImplDrawRadioButton(rRenderContext);
2457 }
2458 
2459 void RadioButton::Draw( OutputDevice* pDev, const Point& rPos,
2460  SystemTextColorFlags nFlags )
2461 {
2462  if ( !maImage )
2463  {
2464  MapMode aResMapMode( MapUnit::Map100thMM );
2465  Point aPos = pDev->LogicToPixel( rPos );
2466  Size aSize = GetSizePixel();
2467  Size aImageSize = pDev->LogicToPixel( Size( 300, 300 ), aResMapMode );
2468  Size aBrd1Size = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode );
2469  Size aBrd2Size = pDev->LogicToPixel( Size( 60, 60 ), aResMapMode );
2470  vcl::Font aFont = GetDrawPixelFont( pDev );
2471  tools::Rectangle aStateRect;
2472  tools::Rectangle aMouseRect;
2473 
2474  aImageSize.setWidth( CalcZoom( aImageSize.Width() ) );
2475  aImageSize.setHeight( CalcZoom( aImageSize.Height() ) );
2476  aBrd1Size.setWidth( CalcZoom( aBrd1Size.Width() ) );
2477  aBrd1Size.setHeight( CalcZoom( aBrd1Size.Height() ) );
2478  aBrd2Size.setWidth( CalcZoom( aBrd2Size.Width() ) );
2479  aBrd2Size.setHeight( CalcZoom( aBrd2Size.Height() ) );
2480 
2481  if ( !aBrd1Size.Width() )
2482  aBrd1Size.setWidth( 1 );
2483  if ( !aBrd1Size.Height() )
2484  aBrd1Size.setHeight( 1 );
2485  if ( !aBrd2Size.Width() )
2486  aBrd2Size.setWidth( 1 );
2487  if ( !aBrd2Size.Height() )
2488  aBrd2Size.setHeight( 1 );
2489 
2490  pDev->Push();
2491  pDev->SetMapMode();
2492  pDev->SetFont( aFont );
2493  if ( nFlags & SystemTextColorFlags::Mono )
2494  pDev->SetTextColor( COL_BLACK );
2495  else
2496  pDev->SetTextColor( GetTextColor() );
2497  pDev->SetTextFillColor();
2498 
2499  ImplDraw( pDev, nFlags, aPos, aSize,
2500  aImageSize, aStateRect, aMouseRect );
2501 
2502  Point aCenterPos = aStateRect.Center();
2503  tools::Long nRadX = aImageSize.Width()/2;
2504  tools::Long nRadY = aImageSize.Height()/2;
2505 
2506  pDev->SetLineColor();
2507  pDev->SetFillColor( COL_BLACK );
2508  pDev->DrawPolygon( tools::Polygon( aCenterPos, nRadX, nRadY ) );
2509  nRadX -= aBrd1Size.Width();
2510  nRadY -= aBrd1Size.Height();
2511  pDev->SetFillColor( COL_WHITE );
2512  pDev->DrawPolygon( tools::Polygon( aCenterPos, nRadX, nRadY ) );
2513  if ( mbChecked )
2514  {
2515  nRadX -= aBrd1Size.Width();
2516  nRadY -= aBrd1Size.Height();
2517  if ( !nRadX )
2518  nRadX = 1;
2519  if ( !nRadY )
2520  nRadY = 1;
2521  pDev->SetFillColor( COL_BLACK );
2522  pDev->DrawPolygon( tools::Polygon( aCenterPos, nRadX, nRadY ) );
2523  }
2524 
2525  pDev->Pop();
2526  }
2527  else
2528  {
2529  OSL_FAIL( "RadioButton::Draw() - not implemented for RadioButton with Image" );
2530  }
2531 }
2532 
2534 {
2535  Control::Resize();
2536  Invalidate();
2537 }
2538 
2540 {
2543  Button::GetFocus();
2544 }
2545 
2547 {
2549  {
2551  Invalidate();
2552  }
2553 
2554  HideFocus();
2556 }
2557 
2559 {
2560  Button::StateChanged( nType );
2561 
2562  if ( nType == StateChangedType::State )
2563  {
2564  if ( IsReallyVisible() && IsUpdateMode() )
2566  }
2567  else if ( (nType == StateChangedType::Enable) ||
2568  (nType == StateChangedType::Text) ||
2569  (nType == StateChangedType::Data) ||
2570  (nType == StateChangedType::UpdateMode) )
2571  {
2572  if ( IsUpdateMode() )
2573  Invalidate();
2574  }
2575  else if ( nType == StateChangedType::Style )
2576  {
2578 
2579  if ( (GetPrevStyle() & RADIOBUTTON_VIEW_STYLE) !=
2581  {
2582  if ( IsUpdateMode() )
2583  Invalidate();
2584  }
2585  }
2586  else if ( (nType == StateChangedType::Zoom) ||
2587  (nType == StateChangedType::ControlFont) )
2588  {
2589  ImplInitSettings( false );
2590  Invalidate();
2591  }
2592  else if ( nType == StateChangedType::ControlForeground )
2593  {
2594  ImplInitSettings( false );
2595  Invalidate();
2596  }
2597  else if ( nType == StateChangedType::ControlBackground )
2598  {
2599  ImplInitSettings( true );
2600  Invalidate();
2601  }
2602 }
2603 
2605 {
2606  Button::DataChanged( rDCEvt );
2607 
2608  if ( (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
2610  ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
2611  (rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
2612  {
2613  ImplInitSettings( true );
2614  Invalidate();
2615  }
2616 }
2617 
2619 {
2620  if( rNEvt.GetType() == MouseNotifyEvent::MOUSEMOVE )
2621  {
2622  const MouseEvent* pMouseEvt = rNEvt.GetMouseEvent();
2623  if( pMouseEvt && !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() )
2624  {
2625  // trigger redraw if mouse over state has changed
2627  {
2629  pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow())
2630  {
2632  }
2633  }
2634  }
2635  }
2636 
2637  return Button::PreNotify(rNEvt);
2638 }
2639 
2641 {
2643 }
2644 
2646 {
2647  if ( rImage != maImage )
2648  {
2649  maImage = rImage;
2651  queue_resize();
2652  }
2653 }
2654 
2655 
2656 void RadioButton::SetState( bool bCheck )
2657 {
2658  // carry the TabStop flag along correctly
2659  if ( bCheck )
2660  mpWindowImpl->mnStyle |= WB_TABSTOP;
2661  else
2662  mpWindowImpl->mnStyle &= ~WB_TABSTOP;
2663 
2664  if ( mbChecked != bCheck )
2665  {
2666  mbChecked = bCheck;
2668  Toggle();
2669  }
2670 }
2671 
2672 bool RadioButton::set_property(const OString &rKey, const OUString &rValue)
2673 {
2674  if (rKey == "active")
2675  SetState(toBool(rValue));
2676  else if (rKey == "image-position")
2677  {
2678  WinBits nBits = GetStyle();
2679  if (rValue == "left")
2680  {
2681  nBits &= ~(WB_CENTER | WB_RIGHT);
2682  nBits |= WB_LEFT;
2683  }
2684  else if (rValue == "right")
2685  {
2686  nBits &= ~(WB_CENTER | WB_LEFT);
2687  nBits |= WB_RIGHT;
2688  }
2689  else if (rValue == "top")
2690  {
2691  nBits &= ~(WB_VCENTER | WB_BOTTOM);
2692  nBits |= WB_TOP;
2693  }
2694  else if (rValue == "bottom")
2695  {
2696  nBits &= ~(WB_VCENTER | WB_TOP);
2697  nBits |= WB_BOTTOM;
2698  }
2699  //It's rather mad to have to set these bits when there is the other
2700  //image align. Looks like e.g. the radiobuttons etc weren't converted
2701  //over to image align fully.
2702  SetStyle(nBits);
2703  //Deliberate to set the sane ImageAlign property
2704  return Button::set_property(rKey, rValue);
2705  }
2706  else
2707  return Button::set_property(rKey, rValue);
2708  return true;
2709 }
2710 
2711 void RadioButton::Check( bool bCheck )
2712 {
2713  // TabStop-Flag richtig mitfuehren
2714  if ( bCheck )
2715  mpWindowImpl->mnStyle |= WB_TABSTOP;
2716  else
2717  mpWindowImpl->mnStyle &= ~WB_TABSTOP;
2718 
2719  if ( mbChecked == bCheck )
2720  return;
2721 
2722  mbChecked = bCheck;
2723  VclPtr<vcl::Window> xWindow = this;
2725  if ( xWindow->isDisposed() )
2726  return;
2727  if ( bCheck && mbRadioCheck )
2729  if ( xWindow->isDisposed() )
2730  return;
2731  Toggle();
2732 }
2733 
2735 {
2736  // 4 pixels, but take zoom into account, so the text doesn't "jump" relative to surrounding elements,
2737  // which might have been aligned with the text of the check box
2738  return CalcZoom( 4 );
2739 }
2740 
2742 {
2743  Size aSize;
2744  bool bDefaultSize = true;
2746  {
2747  ImplControlValue aControlValue;
2748  tools::Rectangle aCtrlRegion( Point( 0, 0 ), GetSizePixel() );
2749  tools::Rectangle aBoundingRgn, aContentRgn;
2750 
2751  // get native size of a radio button
2754  aControlValue,
2755  aBoundingRgn, aContentRgn ) )
2756  {
2757  aSize = aContentRgn.GetSize();
2758  bDefaultSize = false;
2759  }
2760  }
2761  if( bDefaultSize )
2763  return aSize;
2764 }
2765 
2766 static void LoadThemedImageList(const StyleSettings &rStyleSettings,
2767  std::vector<Image>& rList, const std::vector<OUString> &rResources)
2768 {
2769  Color aColorAry1[6];
2770  Color aColorAry2[6];
2771  aColorAry1[0] = Color( 0xC0, 0xC0, 0xC0 );
2772  aColorAry1[1] = Color( 0xFF, 0xFF, 0x00 );
2773  aColorAry1[2] = Color( 0xFF, 0xFF, 0xFF );
2774  aColorAry1[3] = Color( 0x80, 0x80, 0x80 );
2775  aColorAry1[4] = Color( 0x00, 0x00, 0x00 );
2776  aColorAry1[5] = Color( 0x00, 0xFF, 0x00 );
2777  aColorAry2[0] = rStyleSettings.GetFaceColor();
2778  aColorAry2[1] = rStyleSettings.GetWindowColor();
2779  aColorAry2[2] = rStyleSettings.GetLightColor();
2780  aColorAry2[3] = rStyleSettings.GetShadowColor();
2781  aColorAry2[4] = rStyleSettings.GetDarkShadowColor();
2782  aColorAry2[5] = rStyleSettings.GetWindowTextColor();
2783 
2784  static_assert( sizeof(aColorAry1) == sizeof(aColorAry2), "aColorAry1 must match aColorAry2" );
2785 
2786  for (const auto &a : rResources)
2787  {
2788  BitmapEx aBmpEx(a);
2789  aBmpEx.Replace(aColorAry1, aColorAry2, SAL_N_ELEMENTS(aColorAry1));
2790  rList.emplace_back(aBmpEx);
2791  }
2792 }
2793 
2795 {
2796  ImplSVData* pSVData = ImplGetSVData();
2797  const StyleSettings& rStyleSettings = rSettings.GetStyleSettings();
2798  sal_uInt16 nStyle = 0;
2799 
2800  if ( rStyleSettings.GetOptions() & StyleSettingsOptions::Mono )
2801  nStyle = STYLE_RADIOBUTTON_MONO;
2802 
2803  if ( pSVData->maCtrlData.maRadioImgList.empty() ||
2804  (pSVData->maCtrlData.mnRadioStyle != nStyle) ||
2805  (pSVData->maCtrlData.mnLastRadioFColor != rStyleSettings.GetFaceColor()) ||
2806  (pSVData->maCtrlData.mnLastRadioWColor != rStyleSettings.GetWindowColor()) ||
2807  (pSVData->maCtrlData.mnLastRadioLColor != rStyleSettings.GetLightColor()) )
2808  {
2809  pSVData->maCtrlData.maRadioImgList.clear();
2810 
2811  pSVData->maCtrlData.mnLastRadioFColor = rStyleSettings.GetFaceColor();
2812  pSVData->maCtrlData.mnLastRadioWColor = rStyleSettings.GetWindowColor();
2813  pSVData->maCtrlData.mnLastRadioLColor = rStyleSettings.GetLightColor();
2814 
2815  std::vector<OUString> aResources;
2816  if (nStyle)
2817  {
2818  aResources.emplace_back(SV_RESID_BITMAP_RADIOMONO1);
2819  aResources.emplace_back(SV_RESID_BITMAP_RADIOMONO2);
2820  aResources.emplace_back(SV_RESID_BITMAP_RADIOMONO3);
2821  aResources.emplace_back(SV_RESID_BITMAP_RADIOMONO4);
2822  aResources.emplace_back(SV_RESID_BITMAP_RADIOMONO5);
2823  aResources.emplace_back(SV_RESID_BITMAP_RADIOMONO6);
2824  }
2825  else
2826  {
2827  aResources.emplace_back(SV_RESID_BITMAP_RADIO1);
2828  aResources.emplace_back(SV_RESID_BITMAP_RADIO2);
2829  aResources.emplace_back(SV_RESID_BITMAP_RADIO3);
2830  aResources.emplace_back(SV_RESID_BITMAP_RADIO4);
2831  aResources.emplace_back(SV_RESID_BITMAP_RADIO5);
2832  aResources.emplace_back(SV_RESID_BITMAP_RADIO6);
2833  }
2834  LoadThemedImageList( rStyleSettings, pSVData->maCtrlData.maRadioImgList, aResources);
2835  pSVData->maCtrlData.mnRadioStyle = nStyle;
2836  }
2837 
2838  sal_uInt16 nIndex;
2839  if ( nFlags & DrawButtonFlags::Disabled )
2840  {
2841  if ( nFlags & DrawButtonFlags::Checked )
2842  nIndex = 5;
2843  else
2844  nIndex = 4;
2845  }
2846  else if ( nFlags & DrawButtonFlags::Pressed )
2847  {
2848  if ( nFlags & DrawButtonFlags::Checked )
2849  nIndex = 3;
2850  else
2851  nIndex = 2;
2852  }
2853  else
2854  {
2855  if ( nFlags & DrawButtonFlags::Checked )
2856  nIndex = 1;
2857  else
2858  nIndex = 0;
2859  }
2860  return pSVData->maCtrlData.maRadioImgList[nIndex];
2861 }
2862 
2864 {
2866  SetMapMode(MapMode(MapUnit::MapPixel));
2867 
2868  ImplControlValue aControlValue;
2869  Size aCurSize( GetSizePixel() );
2870  tools::Rectangle aCtrlRegion( Point( 0, 0 ), aCurSize );
2871  tools::Rectangle aBoundingRgn, aContentRgn;
2872 
2873  // get native size of a radiobutton
2876  aBoundingRgn, aContentRgn ) )
2877  {
2878  Size aSize = aContentRgn.GetSize();
2879 
2880  if( aSize.Height() > aCurSize.Height() )
2881  {
2882  aCurSize.setHeight( aSize.Height() );
2883  SetSizePixel( aCurSize );
2884  }
2885  }
2886 
2887  GetOutDev()->Pop();
2888 }
2889 
2891 {
2892  Size aSize;
2893  if ( !maImage )
2894  aSize = ImplGetRadioImageSize();
2895  else
2896  {
2897  aSize = maImage.GetSizePixel();
2898  aSize.AdjustWidth(8);
2899  aSize.AdjustHeight(8);
2900  }
2901 
2902  if (Button::HasImage())
2903  {
2904  Size aImgSize = GetModeImage().GetSizePixel();
2905  aSize = Size(std::max(aImgSize.Width(), aSize.Width()),
2906  std::max(aImgSize.Height(), aSize.Height()));
2907  }
2908 
2909  OUString aText = GetText();
2910  if (!aText.isEmpty())
2911  {
2912  bool bTopImage = (GetStyle() & WB_TOP) != 0;
2913 
2914  Size aTextSize = GetTextRect( tools::Rectangle( Point(), Size( nMaxWidth > 0 ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ),
2916 
2917  aSize.AdjustWidth(2 ); // for focus rect
2918 
2919  if (!bTopImage)
2920  {
2922  aSize.AdjustWidth(aTextSize.Width() );
2923  if ( aSize.Height() < aTextSize.Height() )
2924  aSize.setHeight( aTextSize.Height() );
2925  }
2926  else
2927  {
2928  aSize.AdjustHeight(6 );
2929  aSize.AdjustHeight(GetTextHeight() );
2930  if ( aSize.Width() < aTextSize.Width() )
2931  aSize.setWidth( aTextSize.Width() );
2932  }
2933  }
2934 
2935  return CalcWindowSize( aSize );
2936 }
2937 
2939 {
2940  return CalcMinimumSize();
2941 }
2942 
2944 {
2946  {
2947  ImplControlValue aControlValue;
2948  tools::Rectangle aInRect(Point(0, 0), GetSizePixel());
2949 
2950  aInRect.SetLeft( rRect.Left() ); // exclude the radio element itself from the focusrect
2951 
2953  ControlState::FOCUSED, aControlValue, OUString());
2954  }
2955  Button::ShowFocus(rRect);
2956 }
2957 
2959 {
2960  Button::DumpAsPropertyTree(rJsonWriter);
2961  rJsonWriter.put("checked", IsChecked());
2962 
2963  OUString sGroupId;
2964  std::vector<VclPtr<RadioButton>> aGroup = GetRadioButtonGroup();
2965  for(const auto& pButton : aGroup)
2966  sGroupId += pButton->get_id();
2967 
2968  if (!sGroupId.isEmpty())
2969  rJsonWriter.put("group", sGroupId);
2970 
2971  if (!!maImage)
2972  {
2973  SvMemoryStream aOStm(6535, 6535);
2975  {
2976  css::uno::Sequence<sal_Int8> aSeq( static_cast<sal_Int8 const *>(aOStm.GetData()), aOStm.Tell());
2977  OUStringBuffer aBuffer("data:image/png;base64,");
2979  rJsonWriter.put("image", aBuffer.makeStringAndClear());
2980  }
2981  }
2982 }
2983 
2985 {
2987 }
2988 
2990 {
2992  mbTriState = false;
2993 }
2994 
2995 void CheckBox::ImplInit( vcl::Window* pParent, WinBits nStyle )
2996 {
2997  nStyle = ImplInitStyle(getPreviousSibling(pParent), nStyle);
2998  Button::ImplInit( pParent, nStyle, nullptr );
2999 
3000  ImplInitSettings( true );
3001 }
3002 
3004 {
3005  if ( !(nStyle & WB_NOTABSTOP) )
3006  nStyle |= WB_TABSTOP;
3007  if ( !(nStyle & WB_NOGROUP) &&
3008  (!pPrevWindow || (pPrevWindow->GetType() != WindowType::CHECKBOX)) )
3009  nStyle |= WB_GROUP;
3010  return nStyle;
3011 }
3012 
3014 {
3015  return _rStyle.GetRadioCheckFont();
3016 }
3017 
3019 {
3020  return _rStyle.GetRadioCheckTextColor();
3021 }
3022 
3023 void CheckBox::ImplInitSettings( bool bBackground )
3024 {
3026 
3027  if ( !bBackground )
3028  return;
3029 
3030  vcl::Window* pParent = GetParent();
3031  if ( !IsControlBackground() &&
3033  {
3036  SetPaintTransparent( true );
3037  SetBackground();
3040  }
3041  else
3042  {
3043  EnableChildTransparentMode( false );
3045  SetPaintTransparent( false );
3046 
3047  if ( IsControlBackground() )
3049  else
3050  SetBackground( pParent->GetBackground() );
3051  }
3052 }
3053 
3055 {
3056  bool bNativeOK = rRenderContext.IsNativeControlSupported(ControlType::Checkbox, ControlPart::Entire);
3057  if (bNativeOK)
3058  {
3060  tools::Rectangle aCtrlRegion(maStateRect);
3062 
3063  if (HasFocus())
3064  nState |= ControlState::FOCUSED;
3066  nState |= ControlState::DEFAULT;
3068  nState |= ControlState::PRESSED;
3069  if (IsEnabled())
3070  nState |= ControlState::ENABLED;
3071 
3072  if (meState == TRISTATE_TRUE)
3073  aControlValue.setTristateVal(ButtonValue::On);
3074  else if (meState == TRISTATE_INDET)
3075  aControlValue.setTristateVal(ButtonValue::Mixed);
3076 
3078  nState |= ControlState::ROLLOVER;
3079 
3080  bNativeOK = rRenderContext.DrawNativeControl(ControlType::Checkbox, ControlPart::Entire, aCtrlRegion,
3081  nState, aControlValue, OUString());
3082  }
3083 
3084  if (bNativeOK)
3085  return;
3086 
3087  DrawButtonFlags nStyle = GetButtonState();
3088  if (!IsEnabled())
3089  nStyle |= DrawButtonFlags::Disabled;
3090  if (meState == TRISTATE_INDET)
3091  nStyle |= DrawButtonFlags::DontKnow;
3092  else if (meState == TRISTATE_TRUE)
3093  nStyle |= DrawButtonFlags::Checked;
3094  Image aImage = GetCheckImage(GetSettings(), nStyle);
3095  if (IsZoom())
3096  rRenderContext.DrawImage(maStateRect.TopLeft(), maStateRect.GetSize(), aImage);
3097  else
3098  rRenderContext.DrawImage(maStateRect.TopLeft(), aImage);
3099 }
3100 
3101 void CheckBox::ImplDraw( OutputDevice* pDev, SystemTextColorFlags nSystemTextColorFlags,
3102  const Point& rPos, const Size& rSize,
3103  const Size& rImageSize, tools::Rectangle& rStateRect,
3104  tools::Rectangle& rMouseRect )
3105 {
3106  WinBits nWinStyle = GetStyle();
3107  OUString aText( GetText() );
3108 
3110  pDev->IntersectClipRegion( tools::Rectangle( rPos, rSize ) );
3111 
3112  if (!aText.isEmpty() || HasImage())
3113  {
3114  Button::ImplDrawRadioCheck(pDev, nWinStyle, nSystemTextColorFlags,
3115  rPos, rSize, rImageSize,
3116  rStateRect, rMouseRect);
3117  }
3118  else
3119  {
3120  rStateRect.SetLeft( rPos.X() );
3121  if ( nWinStyle & WB_VCENTER )
3122  rStateRect.SetTop( rPos.Y()+((rSize.Height()-rImageSize.Height())/2) );
3123  else if ( nWinStyle & WB_BOTTOM )
3124  rStateRect.SetTop( rPos.Y()+rSize.Height()-rImageSize.Height() );
3125  else
3126  rStateRect.SetTop( rPos.Y() );
3127  rStateRect.SetRight( rStateRect.Left()+rImageSize.Width()-1 );
3128  rStateRect.SetBottom( rStateRect.Top()+rImageSize.Height()-1 );
3129  // provide space for focusrect
3130  // note: this assumes that the control's size was adjusted
3131  // accordingly in Get/LoseFocus, so the onscreen position won't change
3132  if( HasFocus() )
3133  rStateRect.Move( 1, 1 );
3134  rMouseRect = rStateRect;
3135 
3136  ImplSetFocusRect( rStateRect );
3137  }
3138 
3139  pDev->Pop();
3140 }
3141 
3143 {
3144  Size aImageSize = ImplGetCheckImageSize();
3145  aImageSize.setWidth( CalcZoom( aImageSize.Width() ) );
3146  aImageSize.setHeight( CalcZoom( aImageSize.Height() ) );
3147 
3148  HideFocus();
3149 
3151  aImageSize, maStateRect, maMouseRect);
3152 
3153  ImplDrawCheckBoxState(rRenderContext);
3154  if (HasFocus())
3156 }
3157 
3159 {
3160  TriState eNewState;
3161  if ( meState == TRISTATE_FALSE )
3162  eNewState = TRISTATE_TRUE;
3163  else if ( !mbTriState )
3164  eNewState = TRISTATE_FALSE;
3165  else if ( meState == TRISTATE_TRUE )
3166  eNewState = TRISTATE_INDET;
3167  else
3168  eNewState = TRISTATE_FALSE;
3169  meState = eNewState;
3170 
3171  VclPtr<vcl::Window> xWindow = this;
3172  Invalidate();
3173  Toggle();
3174  if ( xWindow->isDisposed() )
3175  return;
3176  Click();
3177 }
3178 
3181 {
3183  ImplInit( pParent, nStyle );
3184 }
3185 
3187 {
3188  if ( rMEvt.IsLeft() && maMouseRect.Contains( rMEvt.GetPosPixel() ) )
3189  {
3191  Invalidate();
3192  StartTracking();
3193  return;
3194  }
3195 
3196  Button::MouseButtonDown( rMEvt );
3197 }
3198 
3199 void CheckBox::Tracking( const TrackingEvent& rTEvt )
3200 {
3201  if ( rTEvt.IsTrackingEnded() )
3202  {
3204  {
3205  if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() )
3206  GrabFocus();
3207 
3209 
3210  // do not call click handler if aborted
3211  if ( !rTEvt.IsTrackingCanceled() )
3212  ImplCheck();
3213  else
3214  {
3215  Invalidate();
3216  }
3217  }
3218  }
3219  else
3220  {
3221  if ( maMouseRect.Contains( rTEvt.GetMouseEvent().GetPosPixel() ) )
3222  {
3224  {
3226  Invalidate();
3227  }
3228  }
3229  else
3230  {
3232  {
3234  Invalidate();
3235  }
3236  }
3237  }
3238 }
3239 
3240 void CheckBox::KeyInput( const KeyEvent& rKEvt )
3241 {
3242  vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
3243 
3244  if ( !aKeyCode.GetModifier() && (aKeyCode.GetCode() == KEY_SPACE) )
3245  {
3247  {
3249  Invalidate();
3250  }
3251  }
3252  else if ( (GetButtonState() & DrawButtonFlags::Pressed) && (aKeyCode.GetCode() == KEY_ESCAPE) )
3253  {
3255  Invalidate();
3256  }
3257  else
3258  Button::KeyInput( rKEvt );
3259 }
3260 
3261 void CheckBox::KeyUp( const KeyEvent& rKEvt )
3262 {
3263  vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
3264 
3265  if ( (GetButtonState() & DrawButtonFlags::Pressed) && (aKeyCode.GetCode() == KEY_SPACE) )
3266  {
3268  ImplCheck();
3269  }
3270  else
3271  Button::KeyUp( rKEvt );
3272 }
3273 
3275 {
3276  mxLayoutData.emplace();
3277  const_cast<CheckBox*>(this)->Invalidate();
3278 }
3279 
3281 {
3282  ImplDrawCheckBox(rRenderContext);
3283 }
3284 
3285 void CheckBox::Draw( OutputDevice* pDev, const Point& rPos,
3286  SystemTextColorFlags nFlags )
3287 {
3288  MapMode aResMapMode( MapUnit::Map100thMM );
3289  Point aPos = pDev->LogicToPixel( rPos );
3290  Size aSize = GetSizePixel();
3291  Size aImageSize = pDev->LogicToPixel( Size( 300, 300 ), aResMapMode );
3292  Size aBrd1Size = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode );
3293  Size aBrd2Size = pDev->LogicToPixel( Size( 30, 30 ), aResMapMode );
3294  tools::Long nCheckWidth = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode ).Width();
3295  vcl::Font aFont = GetDrawPixelFont( pDev );
3296  tools::Rectangle aStateRect;
3297  tools::Rectangle aMouseRect;
3298 
3299  aImageSize.setWidth( CalcZoom( aImageSize.Width() ) );
3300  aImageSize.setHeight( CalcZoom( aImageSize.Height() ) );
3301  aBrd1Size.setWidth( CalcZoom( aBrd1Size.Width() ) );
3302  aBrd1Size.setHeight( CalcZoom( aBrd1Size.Height() ) );
3303  aBrd2Size.setWidth( CalcZoom( aBrd2Size.Width() ) );
3304  aBrd2Size.setHeight( CalcZoom( aBrd2Size.Height() ) );
3305 
3306  if ( !aBrd1Size.Width() )
3307  aBrd1Size.setWidth( 1 );
3308  if ( !aBrd1Size.Height() )
3309  aBrd1Size.setHeight( 1 );
3310  if ( !aBrd2Size.Width() )
3311  aBrd2Size.setWidth( 1 );
3312  if ( !aBrd2Size.Height() )
3313  aBrd2Size.setHeight( 1 );
3314  if ( !nCheckWidth )
3315  nCheckWidth = 1;
3316 
3317  pDev->Push();
3318  pDev->SetMapMode();
3319  pDev->SetFont( aFont );
3320  if ( nFlags & SystemTextColorFlags::Mono )
3321  pDev->SetTextColor( COL_BLACK );
3322  else
3323  pDev->SetTextColor( GetTextColor() );
3324  pDev->SetTextFillColor();
3325 
3326  ImplDraw( pDev, nFlags, aPos, aSize,
3327  aImageSize, aStateRect, aMouseRect );
3328 
3329  pDev->SetLineColor();
3330  pDev->SetFillColor( COL_BLACK );
3331  pDev->DrawRect( aStateRect );
3332  aStateRect.AdjustLeft(aBrd1Size.Width() );
3333  aStateRect.AdjustTop(aBrd1Size.Height() );
3334  aStateRect.AdjustRight( -(aBrd1Size.Width()) );
3335  aStateRect.AdjustBottom( -(aBrd1Size.Height()) );
3336  if ( meState == TRISTATE_INDET )
3337  pDev->SetFillColor( COL_LIGHTGRAY );
3338  else
3339  pDev->SetFillColor( COL_WHITE );
3340  pDev->DrawRect( aStateRect );
3341 
3342  if ( meState == TRISTATE_TRUE )
3343  {
3344  aStateRect.AdjustLeft(aBrd2Size.Width() );
3345  aStateRect.AdjustTop(aBrd2Size.Height() );
3346  aStateRect.AdjustRight( -(aBrd2Size.Width()) );
3347  aStateRect.AdjustBottom( -(aBrd2Size.Height()) );
3348  Point aPos11( aStateRect.TopLeft() );
3349  Point aPos12( aStateRect.BottomRight() );
3350  Point aPos21( aStateRect.TopRight() );
3351  Point aPos22( aStateRect.BottomLeft() );
3352  Point aTempPos11( aPos11 );
3353  Point aTempPos12( aPos12 );
3354  Point aTempPos21( aPos21 );
3355  Point aTempPos22( aPos22 );
3356  pDev->SetLineColor( COL_BLACK );
3357  tools::Long nDX = 0;
3358  for ( tools::Long i = 0; i < nCheckWidth; i++ )
3359  {
3360  if ( !(i % 2) )
3361  {
3362  aTempPos11.setX( aPos11.X()+nDX );
3363  aTempPos12.setX( aPos12.X()+nDX );
3364  aTempPos21.setX( aPos21.X()+nDX );
3365  aTempPos22.setX( aPos22.X()+nDX );
3366  }
3367  else
3368  {
3369  nDX++;
3370  aTempPos11.setX( aPos11.X()-nDX );
3371  aTempPos12.setX( aPos12.X()-nDX );
3372  aTempPos21.setX( aPos21.X()-nDX );
3373  aTempPos22.setX( aPos22.X()-nDX );
3374  }
3375  pDev->DrawLine( aTempPos11, aTempPos12 );
3376  pDev->DrawLine( aTempPos21, aTempPos22 );
3377  }
3378  }
3379 
3380  pDev->Pop();
3381 }
3382 
3384 {
3385  Control::Resize();
3386  Invalidate();
3387 }
3388 
3390 {
3391  if (GetText().isEmpty())
3392  {
3393  // increase button size to have space for focus rect
3394  // checkboxes without text will draw focusrect around the check
3395  // See CheckBox::ImplDraw()
3396  Point aPos( GetPosPixel() );
3397  Size aSize( GetSizePixel() );
3398  aPos.Move(-1,-1);
3399  aSize.AdjustHeight(2 );
3400  aSize.AdjustWidth(2 );
3401  setPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height() );
3402  Invalidate();
3403  // Trigger drawing to initialize the mouse rectangle, otherwise the mouse button down
3404  // handler would ignore the mouse event.
3405  PaintImmediately();
3406  }
3407  else
3409 
3411  Button::GetFocus();
3412 }
3413 
3415 {
3417  {
3419  Invalidate();
3420  }
3421 
3422  HideFocus();
3424 
3425  if (GetText().isEmpty())
3426  {
3427  // decrease button size again (see GetFocus())
3428  // checkboxes without text will draw focusrect around the check
3429  Point aPos( GetPosPixel() );
3430  Size aSize( GetSizePixel() );
3431  aPos.Move(1,1);
3432  aSize.AdjustHeight( -2 );
3433  aSize.AdjustWidth( -2 );
3434  setPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height() );
3435  Invalidate();
3436  }
3437 }
3438 
3440 {
3441  Button::StateChanged( nType );
3442 
3443  if ( nType == StateChangedType::State )
3444  {
3445  if ( IsReallyVisible() && IsUpdateMode() )
3447  }
3448  else if ( (nType == StateChangedType::Enable) ||
3449  (nType == StateChangedType::Text) ||
3450  (nType == StateChangedType::Data) ||
3451  (nType == StateChangedType::UpdateMode) )
3452  {
3453  if ( IsUpdateMode() )
3454  Invalidate();
3455  }
3456  else if ( nType == StateChangedType::Style )
3457  {
3459 
3460  if ( (GetPrevStyle() & CHECKBOX_VIEW_STYLE) !=
3462  {
3463  if ( IsUpdateMode() )
3464  Invalidate();
3465  }
3466  }
3467  else if ( (nType == StateChangedType::Zoom) ||
3468  (nType == StateChangedType::ControlFont) )
3469  {
3470  ImplInitSettings( false );
3471  Invalidate();
3472  }
3473  else if ( nType == StateChangedType::ControlForeground )
3474  {
3475  ImplInitSettings( false );
3476  Invalidate();
3477  }
3478  else if ( nType == StateChangedType::ControlBackground )
3479  {
3480  ImplInitSettings( true );
3481  Invalidate();
3482  }
3483 }
3484 
3486 {
3487  Button::DataChanged( rDCEvt );
3488 
3489  if ( (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
3491  ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
3492  (rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
3493  {
3494  ImplInitSettings( true );
3495  Invalidate();
3496  }
3497 }
3498 
3500 {
3501  if( rNEvt.GetType() == MouseNotifyEvent::MOUSEMOVE )
3502  {
3503  const MouseEvent* pMouseEvt = rNEvt.GetMouseEvent();
3504  if( pMouseEvt && !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() )
3505  {
3506  // trigger redraw if mouse over state has changed
3508  {
3510  pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow())
3511  {
3513  }
3514  }
3515  }
3516  }
3517 
3518  return Button::PreNotify(rNEvt);
3519 }
3520 
3522 {
3524 }
3525 
3527 {
3528  if ( !mbTriState && (eState == TRISTATE_INDET) )
3529  eState = TRISTATE_FALSE;
3530 
3531  if ( meState != eState )
3532  {
3533  meState = eState;
3535  Toggle();
3536  }
3537 }
3538 
3539 bool CheckBox::set_property(const OString &rKey, const OUString &rValue)
3540 {
3541  if (rKey == "active")
3543  else
3544  return Button::set_property(rKey, rValue);
3545  return true;
3546 }
3547 
3548 void CheckBox::EnableTriState( bool bTriState )
3549 {
3550  if ( mbTriState != bTriState )
3551  {
3552  mbTriState = bTriState;
3553 
3554  if ( !bTriState && (meState == TRISTATE_INDET) )
3556  }
3557 }
3558 
3560 {
3561  Size aSize;
3562  bool bDefaultSize = true;
3564  {
3565  ImplControlValue aControlValue;
3566  tools::Rectangle aCtrlRegion( Point( 0, 0 ), GetSizePixel() );
3567  tools::Rectangle aBoundingRgn, aContentRgn;
3568 
3569  // get native size of a check box
3572  aControlValue,
3573  aBoundingRgn, aContentRgn ) )
3574  {
3575  aSize = aContentRgn.GetSize();
3576  bDefaultSize = false;
3577  }
3578  }
3579  if( bDefaultSize )
3581  return aSize;
3582 }
3583 
3585 {
3586  ImplSVData* pSVData = ImplGetSVData();
3587  const StyleSettings& rStyleSettings = rSettings.GetStyleSettings();
3588  sal_uInt16 nStyle = 0;
3589 
3590  if ( rStyleSettings.GetOptions() & StyleSettingsOptions::Mono )
3591  nStyle = STYLE_CHECKBOX_MONO;
3592 
3593  if ( pSVData->maCtrlData.maCheckImgList.empty() ||
3594  (pSVData->maCtrlData.mnCheckStyle != nStyle) ||
3595  (pSVData->maCtrlData.mnLastCheckFColor != rStyleSettings.GetFaceColor()) ||
3596  (pSVData->maCtrlData.mnLastCheckWColor != rStyleSettings.GetWindowColor()) ||
3597  (pSVData->maCtrlData.mnLastCheckLColor != rStyleSettings.GetLightColor()) )
3598  {
3599  pSVData->maCtrlData.maCheckImgList.clear();
3600 
3601  pSVData->maCtrlData.mnLastCheckFColor = rStyleSettings.GetFaceColor();
3602  pSVData->maCtrlData.mnLastCheckWColor = rStyleSettings.GetWindowColor();
3603  pSVData->maCtrlData.mnLastCheckLColor = rStyleSettings.GetLightColor();
3604 
3605  std::vector<OUString> aResources;
3606  if (nStyle)
3607  {
3608  aResources.emplace_back(SV_RESID_BITMAP_CHECKMONO1);
3609  aResources.emplace_back(SV_RESID_BITMAP_CHECKMONO2);
3610  aResources.emplace_back(SV_RESID_BITMAP_CHECKMONO3);
3611  aResources.emplace_back(SV_RESID_BITMAP_CHECKMONO4);
3612  aResources.emplace_back(SV_RESID_BITMAP_CHECKMONO5);
3613  aResources.emplace_back(SV_RESID_BITMAP_CHECKMONO6);
3614  aResources.emplace_back(SV_RESID_BITMAP_CHECKMONO7);
3615  aResources.emplace_back(SV_RESID_BITMAP_CHECKMONO8);
3616  aResources.emplace_back(SV_RESID_BITMAP_CHECKMONO9);
3617  }
3618  else
3619  {
3620  aResources.emplace_back(SV_RESID_BITMAP_CHECK1);
3621  aResources.emplace_back(SV_RESID_BITMAP_CHECK2);
3622  aResources.emplace_back(SV_RESID_BITMAP_CHECK3);
3623  aResources.emplace_back(SV_RESID_BITMAP_CHECK4);
3624  aResources.emplace_back(SV_RESID_BITMAP_CHECK5);
3625  aResources.emplace_back(SV_RESID_BITMAP_CHECK6);
3626  aResources.emplace_back(SV_RESID_BITMAP_CHECK7);
3627  aResources.emplace_back(SV_RESID_BITMAP_CHECK8);
3628  aResources.emplace_back(SV_RESID_BITMAP_CHECK9);
3629  }
3630  LoadThemedImageList(rStyleSettings, pSVData->maCtrlData.maCheckImgList, aResources);
3631  pSVData->maCtrlData.mnCheckStyle = nStyle;
3632  }
3633 
3634  sal_uInt16 nIndex;
3635  if ( nFlags & DrawButtonFlags::Disabled )
3636  {
3637  if ( nFlags & DrawButtonFlags::DontKnow )
3638  nIndex = 8;
3639  else if ( nFlags & DrawButtonFlags::Checked )
3640  nIndex = 5;
3641  else
3642  nIndex = 4;
3643  }
3644  else if ( nFlags & DrawButtonFlags::Pressed )
3645  {
3646  if ( nFlags & DrawButtonFlags::DontKnow )
3647  nIndex = 7;
3648  else if ( nFlags & DrawButtonFlags::Checked )
3649  nIndex = 3;
3650  else
3651  nIndex = 2;
3652  }
3653  else
3654  {
3655  if ( nFlags & DrawButtonFlags::DontKnow )
3656  nIndex = 6;
3657  else if ( nFlags & DrawButtonFlags::Checked )
3658  nIndex = 1;
3659  else
3660  nIndex = 0;
3661  }
3662  return pSVData->maCtrlData.maCheckImgList[nIndex];
3663 }
3664 
3666 {
3668  SetMapMode(MapMode(MapUnit::MapPixel));
3669 
3670  ImplControlValue aControlValue;
3671  Size aCurSize( GetSizePixel() );
3672  tools::Rectangle aCtrlRegion( Point( 0, 0 ), aCurSize );
3673  tools::Rectangle aBoundingRgn, aContentRgn;
3674 
3675  // get native size of a radiobutton
3678  aBoundingRgn, aContentRgn ) )
3679  {
3680  Size aSize = aContentRgn.GetSize();
3681 
3682  if( aSize.Height() > aCurSize.Height() )
3683  {
3684  aCurSize.setHeight( aSize.Height() );
3685  SetSizePixel( aCurSize );
3686  }
3687  }
3688 
3689  GetOutDev()->Pop();
3690 }
3691 
3693 {
3694  Size aSize = ImplGetCheckImageSize();
3695  nMaxWidth -= aSize.Width();
3696 
3697  OUString aText = GetText();
3698  if (!aText.isEmpty())
3699  {
3700  // subtract what will be added later
3701  nMaxWidth-=2;
3702  nMaxWidth -= ImplGetImageToTextDistance();
3703 
3704  Size aTextSize = GetTextRect( tools::Rectangle( Point(), Size( nMaxWidth > 0 ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ),
3706  aSize.AdjustWidth(2 ); // for focus rect
3708  aSize.AdjustWidth(aTextSize.Width() );
3709  if ( aSize.Height() < aTextSize.Height() )
3710  aSize.setHeight( aTextSize.Height() );
3711  }
3712  else
3713  {
3714  // is this still correct ? since the checkbox now
3715  // shows a focus rect it should be 2 pixels wider and longer
3716 /* since otherwise the controls in the Writer hang too far up
3717  aSize.Width() += 2;
3718  aSize.Height() += 2;
3719 */
3720  }
3721 
3722  return CalcWindowSize( aSize );
3723 }
3724 
3726 {
3727  int nWidthRequest(get_width_request());
3728  return CalcMinimumSize(nWidthRequest != -1 ? nWidthRequest : 0);
3729 }
3730 
3732 {
3734  {
3735  ImplControlValue aControlValue;
3736  tools::Rectangle aInRect(Point(0, 0), GetSizePixel());
3737 
3738  aInRect.SetLeft( rRect.Left() ); // exclude the checkbox itself from the focusrect
3739 
3741  ControlState::FOCUSED, aControlValue, OUString());
3742  }
3743  Button::ShowFocus(rRect);
3744 }
3745 
3747 {
3748  Button::DumpAsPropertyTree(rJsonWriter);
3749  rJsonWriter.put("checked", IsChecked());
3750 }
3751 
3753 {
3754  return CheckBoxUIObject::create;
3755 }
3756 
3758  PushButton( pParent, nStyle )
3759 {
3760  ImplInitStyle();
3761 }
3762 
3764 {
3765  WinBits nStyle = GetStyle();
3766 
3767  if ( ! ( nStyle & ( WB_RIGHT | WB_LEFT ) ) )
3768  nStyle |= WB_CENTER;
3769 
3770  if ( ! ( nStyle & ( WB_TOP | WB_BOTTOM ) ) )
3771  nStyle |= WB_VCENTER;
3772 
3773  SetStyle( nStyle );
3774 }
3775 
3776 /* 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:2791
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:2533
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:3485
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:2734
SAL_DLLPRIVATE void ImplInitCheckBoxData()
Definition: button.cxx:2989
void Toggle()
Definition: button.cxx:3521
Color mnLastRadioLColor
Definition: svdata.hxx:288
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:1607
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:1623
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:284
virtual void StateChanged(StateChangedType nType) override
Definition: button.cxx:3439
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:3725
const Color & GetActionButtonTextColor() const
static Image GetRadioImage(const AllSettings &rSettings, DrawButtonFlags nFlags)
Definition: button.cxx:2794
tools::Long AdjustRight(tools::Long nHorzMoveDelta)
virtual bool Close() override
Definition: dialog.cxx:843
sal_uInt16 mnCheckStyle
Definition: svdata.hxx:281
SAL_DLLPRIVATE void ImplSetFocusRect(const tools::Rectangle &rFocusRect)
Definition: button.cxx:484
void SetModeRadioImage(const Image &rImage)
Definition: button.cxx:2645
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:2205
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:1732
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:3003
bool Contains(const Point &rPOINT) const
WinBits const WB_NOGROUP
void SetCommandHandler(const OUString &aCommand)
Setup handler for UNO commands so that commands like .uno:Something are handled automagically by this...
Definition: button.cxx:119
tools::Rectangle maStateRect
Definition: button.hxx:378
virtual void DataChanged(const DataChangedEvent &rDCEvt) override
Definition: button.cxx:1480
const Color & GetDefaultButtonTextColor() const
long Long
Link< CheckBox &, void > maToggleHdl
Definition: button.hxx:293
virtual void FillLayoutData() const override
Definition: button.cxx:3274
virtual void LoseFocus() override
Definition: button.cxx:2546
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
Gets the application's settings.
Definition: svapp.cxx:733
void Push(vcl::PushFlags nFlags=vcl::PushFlags::ALL)
Definition: stack.cxx:33
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:3101
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:804
SAL_DLLPRIVATE void ImplGrabFocus(GetFocusFlags nFlags)
Definition: mouse.cxx:194
ImplSVNWFData maNWFData
Definition: svdata.hxx:402
void Toggle()
Definition: button.cxx:2640
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:2402
virtual void SetSizePixel(const Size &rNewSize)
Definition: window2.cxx:1256
WinBits const WB_RIGHT
virtual void KeyUp(const KeyEvent &rKEvt) override
Definition: button.cxx:2435
SAL_DLLPRIVATE WindowImpl * ImplGetWindowImpl() const
Definition: window.hxx:527
void SetState(bool bCheck)
Definition: button.cxx:2656
SAL_DLLPRIVATE void CompatStateChanged(StateChangedType nStateChange)
Definition: window.cxx:3891
SAL_DLLPRIVATE void ImplCallClick(bool bGrabFocus=false, GetFocusFlags nFocusFlags=GetFocusFlags::NONE)
Definition: button.cxx:2311
PushButtonDropdownStyle
Definition: button.hxx:116
bool mbNoFocusRectsForFlatButtons
Definition: svdata.hxx:327
tools::Rectangle maMouseRect
Definition: button.hxx:290
void SetTextFillColor()
Definition: text.cxx:731
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: button.cxx:1690
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:1685
void IntersectClipRegion(const tools::Rectangle &rRect)
DrawButtonFlags
Definition: decoview.hxx:53
SAL_DLLPRIVATE void ImplDrawRadioButtonState(vcl::RenderContext &rRenderContext)
Definition: button.cxx:1928
#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:1863
const Color & GetControlBackground() const
Definition: window2.cxx:1076
void SetState(TriState eState)
Definition: button.cxx:3526
tools::Rectangle DrawButton(const tools::Rectangle &rRect, DrawButtonFlags nStyle)
Definition: decoview.cxx:898
constexpr sal_uInt16 KEY_SPACE
Definition: keycodes.hxx:123
virtual void ShowFocus(const tools::Rectangle &rRect) override
Definition: button.cxx:1705
virtual void Tracking(const TrackingEvent &rTEvt) override
Definition: button.cxx:1220
void PaintImmediately()
Definition: paint.cxx:1267
SAL_DLLPRIVATE Size ImplGetRadioImageSize() const
Definition: button.cxx:2741
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:594
DrawTextFlags
ImplSVCtrlData maCtrlData
Definition: svdata.hxx:400
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:1575
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:2182
bool IsTrackingRepeat() const
Definition: event.hxx:259
The invalidated area is painted with the background color/pattern.
void SetSymbolAlign(SymbolAlign eAlign)
Definition: button.cxx:1570
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:2958
virtual void KeyInput(const KeyEvent &rKEvt) override
Definition: button.cxx:3240
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:3539
SAL_DLLPRIVATE WinBits ImplInitStyle(const vcl::Window *pPrevWindow, WinBits nStyle) const
Definition: button.cxx:1871
sal_Int64 WinBits
Size CalcMinimumSize() const
Definition: button.cxx:1635
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:2433
const Color & GetDefaultButtonRolloverTextColor() const
sal_uInt16 GetButtons() const
Definition: event.hxx:147
void SetSymbol(SymbolType eSymbol)
Definition: button.cxx:1561
virtual void DumpAsPropertyTree(tools::JsonWriter &)
Dumps itself and potentially its children to a property tree, to be written easily to JSON...
Definition: window.cxx:3358
virtual void Draw(OutputDevice *pDev, const Point &rPos, SystemTextColorFlags nFlags) override
Definition: button.cxx:2459
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:3389
void ImplAdjustNWFSizes() override
Definition: button.cxx:3665
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:271
Image maImage
Definition: button.hxx:380
virtual const Color & GetCanonicalTextColor(const StyleSettings &_rStyle) const override
Definition: button.cxx:3018
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:1846
const Color & GetLightColor() const
Image maCustomContentImage
Definition: button.cxx:90
virtual void GetFocus() override
Definition: button.cxx:1419
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:92
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:2263
virtual OUString GetText() const
Definition: window.cxx:3055
static Image GetCheckImage(const AllSettings &rSettings, DrawButtonFlags nFlags)
Definition: button.cxx:3584
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:1856
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:2890
virtual void LoseFocus() override
Definition: button.cxx:1426
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:2045
TRISTATE_INDET
bool IsChildTransparentModeEnabled() const
Definition: window2.cxx:1021
SAL_DLLPRIVATE void ImplCheck()
Definition: button.cxx:3158
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:3499
constexpr bool IsEmpty() const
const Color & GetControlForeground() const
Definition: window2.cxx:1066
constexpr void SetLeft(tools::Long v)
#define SAL_N_ELEMENTS(arr)
static void LoadThemedImageList(const StyleSettings &rStyleSettings, std::vector< Image > &rList, const std::vector< OUString > &rResources)
Definition: button.cxx:2766
virtual void MouseButtonDown(const MouseEvent &rMEvt) override
Definition: button.cxx:2360
WinBits const WB_NOLIGHTBORDER
const Color & GetDarkShadowColor() const
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:75
virtual bool PreNotify(NotifyEvent &rNEvt) override
Definition: button.cxx:2618
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:1831
void SetLineColor()
Definition: line.cxx:36
virtual void ShowFocus(const tools::Rectangle &rRect) override
Definition: button.cxx:3731
virtual bool PreNotify(NotifyEvent &rNEvt)
Definition: event.cxx:52
void SetInputContext(const InputContext &rInputContext)
Definition: window.cxx:2076
void DecreaseLuminance(sal_uInt8 cLumDec)
bool IsLeaveWindow() const
Definition: event.hxx:140
const Color & GetActionButtonPressedRolloverTextColor() const
void Check(bool bCheck=true)
Definition: button.cxx:2711
int i
uno_Any a
bool IsChecked() const
Definition: button.hxx:226
virtual bool PreNotify(NotifyEvent &rNEvt) override
Definition: button.cxx:1494
SAL_DLLPRIVATE void ImplInit(vcl::Window *pParent, WinBits nStyle)
Definition: button.cxx:1765
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
Definition: button.cxx:2349
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:3199
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:1413
std::unique_ptr< ImplCommonButtonData > mpButtonData
Definition: button.hxx:43
sal_uInt16 mnRadioStyle
Definition: svdata.hxx:282
virtual FactoryFunction GetUITestFactory() const override
Definition: button.cxx:576
WinBits const WB_VCENTER
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
Definition: paint.cxx:1143
TRISTATE_FALSE
SAL_DLLPRIVATE Size ImplGetCheckImageSize() const
Definition: button.cxx:3559
void EnableTriState(bool bTriState=true)
Definition: button.cxx:3548
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:2101
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:175
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:2245
bool IsChecked() const
Definition: button.hxx:348
virtual FactoryFunction GetUITestFactory() const override
Definition: button.cxx:2984
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:713
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:1887
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:2938
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:2414
virtual void KeyUp(const KeyEvent &rKEvt) override
Definition: button.cxx:3261
MouseNotifyEvent GetType() const
Definition: event.hxx:308
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:294
void SetPaintTransparent(bool bTransparent)
Definition: paint.cxx:1025
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:1855
Button(const Button &)=delete
void DumpAsPropertyTree(tools::JsonWriter &) override
Button has additional stuff that we need to dump too.
Definition: button.cxx:3746
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:2119
virtual const Color & GetCanonicalTextColor(const StyleSettings &_rStyle) const override
Definition: button.cxx:663
Point ScreenToOutputPixel(const Point &rPos) const
Definition: window.cxx:2809
void GrabFocus()
Definition: window.cxx:2976
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:2448
WinBits const WB_LEFT
const Color & GetDefaultActionButtonPressedRolloverTextColor() const
virtual void GetFocus() override
Definition: button.cxx:2539
void Toggle()
Definition: button.cxx:1556
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:1962
void DrawSeparator(const Point &rStart, const Point &rStop, bool bVertical=true)
Definition: decoview.cxx:977
virtual void MouseButtonDown(const MouseEvent &rMEvt) override
Definition: button.cxx:3186
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:3285
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:3763
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:2558
SAL_WARN_UNUSED_RESULT Point LogicToPixel(const Point &rLogicPt) const
Definition: map.cxx:878
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:2666
virtual void KeyInput(const KeyEvent &rKEvt)
Definition: window.cxx:1805
SAL_DLLPRIVATE void ImplInit(vcl::Window *pParent, WinBits nStyle, SystemParentData *pSystemParentData)
Definition: window.cxx:938
WinBits const WB_3DLOOK
bool mbUseNativeFocus
Definition: window.h:311
SAL_DLLPRIVATE void ImplInit(vcl::Window *pParent, WinBits nStyle)
Definition: button.cxx:2995
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:1892
OKButton(const OKButton &)=delete
void set_id(const OUString &rID)
Sets an ID.
Definition: window.cxx:3923
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:2672
virtual void StateChanged(StateChangedType nType) override
Definition: button.cxx:1433
virtual const vcl::Font & GetCanonicalFont(const StyleSettings &_rStyle) const override
Definition: button.cxx:3013
const sal_uInt32 LEFT
virtual void ImplDrawCheckBoxState(vcl::RenderContext &rRenderContext)
Definition: button.cxx:3054
void ImplAdjustNWFSizes() override
Definition: button.cxx:2863
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:1614
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:276
Definition: ctrl.hxx:81
virtual void Resize() override
Definition: button.cxx:3383
bool IsSynthetic() const
Definition: event.hxx:142
virtual void GetFocus()
Definition: window.cxx:1841
tools::Rectangle & Union(const tools::Rectangle &rRect)
const Color & GetButtonTextColor() const
bool mbNoFocusRects
Definition: svdata.hxx:326
#define ERRCODE_NONE
Definition: errcode.hxx:196
constexpr tools::Long Height() const
unsigned char sal_uInt8
SAL_DLLPRIVATE DrawTextFlags ImplGetTextStyle(WinBits nWinStyle, SystemTextColorFlags nSystemTextColorFlags) const
Definition: button.cxx:191
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)
D