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 
581 namespace
582 {
583 
584 const char* symbolTypeName(SymbolType eSymbolType)
585 {
586  switch (eSymbolType)
587  {
588  case SymbolType::DONTKNOW: return "DONTKNOW";
589  case SymbolType::IMAGE: return "IMAGE";
590  case SymbolType::ARROW_UP: return "ARROW_UP";
591  case SymbolType::ARROW_DOWN: return "ARROW_DOWN";
592  case SymbolType::ARROW_LEFT: return "ARROW_LEFT";
593  case SymbolType::ARROW_RIGHT: return "ARROW_RIGHT";
594  case SymbolType::SPIN_UP: return "SPIN_UP";
595  case SymbolType::SPIN_DOWN: return "SPIN_DOWN";
596  case SymbolType::SPIN_LEFT: return "SPIN_LEFT";
597  case SymbolType::SPIN_RIGHT: return "SPIN_RIGHT";
598  case SymbolType::FIRST: return "FIRST";
599  case SymbolType::LAST: return "LAST";
600  case SymbolType::PREV: return "PREV";
601  case SymbolType::NEXT: return "NEXT";
602  case SymbolType::PAGEUP: return "PAGEUP";
603  case SymbolType::PAGEDOWN: return "PAGEDOWN";
604  case SymbolType::PLAY: return "PLAY";
605  case SymbolType::STOP: return "STOP";
606  case SymbolType::CLOSE: return "CLOSE";
607  case SymbolType::CHECKMARK: return "CHECKMARK";
608  case SymbolType::RADIOCHECKMARK: return "RADIOCHECKMARK";
609  case SymbolType::FLOAT: return "FLOAT";
610  case SymbolType::DOCK: return "DOCK";
611  case SymbolType::HIDE: return "HIDE";
612  case SymbolType::HELP: return "HELP";
613  case SymbolType::PLUS: return "PLUS";
614  }
615 
616  return "UNKNOWN";
617 }
618 
619 }
620 
622 {
623  Control::DumpAsPropertyTree(rJsonWriter);
624  rJsonWriter.put("text", GetText());
625  if (HasImage())
626  {
627  SvMemoryStream aOStm(6535, 6535);
629  {
630  css::uno::Sequence<sal_Int8> aSeq( static_cast<sal_Int8 const *>(aOStm.GetData()), aOStm.Tell());
631  OUStringBuffer aBuffer("data:image/png;base64,");
633  rJsonWriter.put("image", aBuffer.makeStringAndClear());
634  }
635  }
636 
637  if (GetStyle() & WB_DEFBUTTON)
638  rJsonWriter.put("has_default", true);
639 }
640 
642 {
643  Button::DumpAsPropertyTree(rJsonWriter);
645  rJsonWriter.put("symbol", symbolTypeName(GetSymbol()));
646 }
647 
648 IMPL_STATIC_LINK( Button, dispatchCommandHandler, Button*, pButton, void )
649 {
650  if (pButton == nullptr)
651  return;
652 
653  comphelper::dispatchCommand(pButton->maCommand, uno::Sequence<beans::PropertyValue>());
654 }
655 
657 {
658  mpWindowImpl->mbPushButton = true;
659 
663  mbIsActive = false;
664  mbPressed = false;
665  mbIsAction = false;
666 }
667 
668 namespace
669 {
670  vcl::Window* getPreviousSibling(vcl::Window const *pParent)
671  {
672  return pParent ? pParent->GetWindow(GetWindowType::LastChild) : nullptr;
673  }
674 }
675 
676 void PushButton::ImplInit( vcl::Window* pParent, WinBits nStyle )
677 {
678  nStyle = ImplInitStyle(getPreviousSibling(pParent), nStyle);
679  Button::ImplInit( pParent, nStyle, nullptr );
680 
681  if ( nStyle & WB_NOLIGHTBORDER )
683 
684  ImplInitSettings( true );
685 }
686 
688 {
689  if ( !(nStyle & WB_NOTABSTOP) )
690  nStyle |= WB_TABSTOP;
691 
692  // if no alignment is given, default to "vertically centered". This is because since
693  // #i26046#, we respect the vertical alignment flags (previously we didn't completely),
694  // but we of course want to look as before when no vertical alignment is specified
695  if ( ( nStyle & ( WB_TOP | WB_VCENTER | WB_BOTTOM ) ) == 0 )
696  nStyle |= WB_VCENTER;
697 
698  if ( !(nStyle & WB_NOGROUP) &&
699  (!pPrevWindow ||
700  ((pPrevWindow->GetType() != WindowType::PUSHBUTTON ) &&
701  (pPrevWindow->GetType() != WindowType::OKBUTTON ) &&
702  (pPrevWindow->GetType() != WindowType::CANCELBUTTON) &&
703  (pPrevWindow->GetType() != WindowType::HELPBUTTON )) ) )
704  nStyle |= WB_GROUP;
705  return nStyle;
706 }
707 
709 {
710  return _rStyle.GetPushButtonFont();
711 }
712 
714 {
715  return _rStyle.GetButtonTextColor();
716 }
717 
718 void PushButton::ImplInitSettings( bool bBackground )
719 {
721 
722  if ( !bBackground )
723  return;
724 
725  SetBackground();
726  // #i38498#: do not check for GetParent()->IsChildTransparentModeEnabled()
727  // otherwise the formcontrol button will be overdrawn due to ParentClipMode::NoClip
728  // for radio and checkbox this is ok as they should appear transparent in documents
730  (GetStyle() & WB_FLATBUTTON) != 0 )
731  {
734  SetPaintTransparent( true );
735 
736  if ((GetStyle() & WB_FLATBUTTON) == 0)
737  mpWindowImpl->mbUseNativeFocus = ImplGetSVData()->maNWFData.mbNoFocusRects;
738  else
740  }
741  else
742  {
745  SetPaintTransparent( false );
746  }
747 }
748 
750  tools::Rectangle& rRect, DrawButtonFlags nStyle)
751 {
752  if (!(GetStyle() & (WB_RECTSTYLE | WB_SMALLSTYLE)))
753  {
754  StyleSettings aStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
755  if (IsControlBackground())
756  aStyleSettings.Set3DColors(GetControlBackground());
757  }
758 
759  DecorationView aDecoView(&rRenderContext);
760  if (IsControlBackground())
761  {
762  AllSettings aSettings = rRenderContext.GetSettings();
763  AllSettings aOldSettings = aSettings;
764  StyleSettings aStyleSettings = aSettings.GetStyleSettings();
765  if (nStyle & DrawButtonFlags::Highlight)
766  {
767  // with the custom background, native highlight do nothing, so code below mimic
768  // native highlight by changing luminance
769  Color controlBackgroundColorHighlighted = GetControlBackground();
770  sal_uInt8 colorLuminance = controlBackgroundColorHighlighted.GetLuminance();
771  if (colorLuminance < 205)
772  controlBackgroundColorHighlighted.IncreaseLuminance(50);
773  else
774  controlBackgroundColorHighlighted.DecreaseLuminance(50);
775  aStyleSettings.Set3DColors(controlBackgroundColorHighlighted);
776  }
777  else
778  aStyleSettings.Set3DColors(GetControlBackground());
779  aSettings.SetStyleSettings(aStyleSettings);
780 
781  // Call OutputDevice::SetSettings() explicitly, as rRenderContext may
782  // be a vcl::Window in fact, and vcl::Window::SetSettings() will call
783  // Invalidate(), which is a problem, since we're in Paint().
784  rRenderContext.OutputDevice::SetSettings(aSettings);
785  rRect = aDecoView.DrawButton(rRect, nStyle);
786  rRenderContext.OutputDevice::SetSettings(aOldSettings);
787  }
788  else
789  rRect = aDecoView.DrawButton(rRect, nStyle);
790 }
791 
793  const Point& rPos )
794 {
795  tools::Rectangle aTestRect( Point(), pDev->GetOutputSizePixel() );
796 
797  return aTestRect.Contains( rPos );
798 }
799 
801 {
802  const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
803 
805 
806  if ( ( rStyleSettings.GetOptions() & StyleSettingsOptions::Mono ) ||
807  ( nSystemTextColorFlags & SystemTextColorFlags::Mono ) )
808  nTextStyle |= DrawTextFlags::Mono;
809 
810  if ( GetStyle() & WB_WORDBREAK )
811  nTextStyle |= DrawTextFlags::WordBreak;
812  if ( GetStyle() & WB_NOLABEL )
813  nTextStyle &= ~DrawTextFlags::Mnemonic;
814 
815  if ( GetStyle() & WB_LEFT )
816  nTextStyle |= DrawTextFlags::Left;
817  else if ( GetStyle() & WB_RIGHT )
818  nTextStyle |= DrawTextFlags::Right;
819  else
820  nTextStyle |= DrawTextFlags::Center;
821 
822  if ( GetStyle() & WB_TOP )
823  nTextStyle |= DrawTextFlags::Top;
824  else if ( GetStyle() & WB_BOTTOM )
825  nTextStyle |= DrawTextFlags::Bottom;
826  else
827  nTextStyle |= DrawTextFlags::VCenter;
828 
829  if ( !IsEnabled() )
830  nTextStyle |= DrawTextFlags::Disable;
831 
832  return nTextStyle;
833 }
834 
836  const tools::Rectangle &rRect, bool bMenuBtnSep,
837  DrawButtonFlags nButtonFlags)
838 {
839  const StyleSettings &rStyleSettings = GetSettings().GetStyleSettings();
840  tools::Rectangle aInRect = rRect;
841  Color aColor;
842  DrawTextFlags nTextStyle = ImplGetTextStyle(nSystemTextColorFlags);
843  DrawSymbolFlags nStyle;
844 
845  if (aInRect.Right() < aInRect.Left() || aInRect.Bottom() < aInRect.Top())
846  return;
847 
849  pDev->IntersectClipRegion(aInRect);
850 
851  if (nSystemTextColorFlags & SystemTextColorFlags::Mono)
852  aColor = COL_BLACK;
853 
854  else if (IsControlForeground())
855  aColor = GetControlForeground();
856 
857  // Button types with possibly different text coloring are flat buttons and regular buttons. Regular buttons may be action
858  // buttons and may have an additional default status. Moreover all buttons may have an additional pressed and rollover
859  // (highlight) status. Pressed buttons are always in rollover status.
860 
861  else if (GetStyle() & WB_FLATBUTTON)
862  if (nButtonFlags & DrawButtonFlags::Pressed)
863  aColor = rStyleSettings.GetFlatButtonPressedRolloverTextColor();
864  else if (nButtonFlags & DrawButtonFlags::Highlight)
865  aColor = rStyleSettings.GetFlatButtonRolloverTextColor();
866  else
867  aColor = rStyleSettings.GetFlatButtonTextColor();
868  else
869  if (isAction() && (nButtonFlags & DrawButtonFlags::Default))
870  if (nButtonFlags & DrawButtonFlags::Pressed)
871  aColor = rStyleSettings.GetDefaultActionButtonPressedRolloverTextColor();
872  else if (nButtonFlags & DrawButtonFlags::Highlight)
873  aColor = rStyleSettings.GetDefaultActionButtonRolloverTextColor();
874  else
875  aColor = rStyleSettings.GetDefaultActionButtonTextColor();
876  else if (isAction())
877  if (nButtonFlags & DrawButtonFlags::Pressed)
878  aColor = rStyleSettings.GetActionButtonPressedRolloverTextColor();
879  else if (nButtonFlags & DrawButtonFlags::Highlight)
880  aColor = rStyleSettings.GetActionButtonRolloverTextColor();
881  else
882  aColor = rStyleSettings.GetActionButtonTextColor();
883  else if (nButtonFlags & DrawButtonFlags::Default)
884  if (nButtonFlags & DrawButtonFlags::Pressed)
885  aColor = rStyleSettings.GetDefaultButtonPressedRolloverTextColor();
886  else if (nButtonFlags & DrawButtonFlags::Highlight)
887  aColor = rStyleSettings.GetDefaultButtonRolloverTextColor();
888  else
889  aColor = rStyleSettings.GetDefaultButtonTextColor();
890  else
891  if (nButtonFlags & DrawButtonFlags::Pressed)
892  aColor = rStyleSettings.GetButtonPressedRolloverTextColor();
893  else if (nButtonFlags & DrawButtonFlags::Highlight)
894  aColor = rStyleSettings.GetButtonRolloverTextColor();
895  else
896  aColor = rStyleSettings.GetButtonTextColor();
897 
898  pDev->SetTextColor(aColor);
899 
900  if ( IsEnabled() )
901  nStyle = DrawSymbolFlags::NONE;
902  else
903  nStyle = DrawSymbolFlags::Disable;
904 
905  Size aSize = rRect.GetSize();
906  Point aPos = rRect.TopLeft();
907 
908  sal_Int32 nImageSep = 1 + (pDev->GetTextHeight()-10)/2;
909  if( nImageSep < 1 )
910  nImageSep = 1;
913  {
914  tools::Long nSeparatorX = 0;
915  tools::Rectangle aSymbolRect = aInRect;
916 
917  // calculate symbol size
918  tools::Long nSymbolSize = pDev->GetTextHeight() / 2 + 1;
919  if (nSymbolSize > aSize.Width() / 2)
920  nSymbolSize = aSize.Width() / 2;
921 
922  nSeparatorX = aInRect.Right() - 2*nSymbolSize;
923 
924  // tdf#141761 Minimum width should be (1) Pixel, see comment
925  // with same task number above for more info
926  const tools::Long nWidthAdjust(2*nSymbolSize);
927  aSize.setWidth(std::max(static_cast<tools::Long>(1), aSize.getWidth() - nWidthAdjust));
928 
929  // center symbol rectangle in the separated area
930  aSymbolRect.AdjustRight( -(nSymbolSize/2) );
931  aSymbolRect.SetLeft( aSymbolRect.Right() - nSymbolSize );
932 
933  ImplDrawAlignedImage( pDev, aPos, aSize, nImageSep,
934  nTextStyle, nullptr, true );
935 
936  tools::Long nDistance = (aSymbolRect.GetHeight() > 10) ? 2 : 1;
937  DecorationView aDecoView( pDev );
938  if( bMenuBtnSep && nSeparatorX > 0 )
939  {
940  Point aStartPt( nSeparatorX, aSymbolRect.Top()+nDistance );
941  Point aEndPt( nSeparatorX, aSymbolRect.Bottom()-nDistance );
942  aDecoView.DrawSeparator( aStartPt, aEndPt );
943  }
944  ImplSetSeparatorX( nSeparatorX );
945 
946  aDecoView.DrawSymbol( aSymbolRect, SymbolType::SPIN_DOWN, aColor, nStyle );
947 
948  }
949  else
950  {
951  tools::Rectangle aSymbolRect;
952  ImplDrawAlignedImage( pDev, aPos, aSize, nImageSep,
953  nTextStyle, IsSymbol() ? &aSymbolRect : nullptr, true );
954 
955  if ( IsSymbol() )
956  {
957  DecorationView aDecoView( pDev );
958  aDecoView.DrawSymbol( aSymbolRect, meSymbol, aColor, nStyle );
959  }
960  }
961 
962  pDev->Pop(); // restore clipregion
963 }
964 
966 {
967  HideFocus();
968 
969  DrawButtonFlags nButtonStyle = GetButtonState();
970  Size aOutSz(GetOutputSizePixel());
971  tools::Rectangle aRect(Point(), aOutSz);
972  tools::Rectangle aInRect = aRect;
973  bool bNativeOK = false;
974 
975  // adjust style if button should be rendered 'pressed'
976  if (mbPressed || mbIsActive)
977  nButtonStyle |= DrawButtonFlags::Pressed;
978 
979  // TODO: move this to Window class or make it a member !!!
980  ControlType aCtrlType = ControlType::Generic;
981  switch(GetParent()->GetType())
982  {
983  case WindowType::LISTBOX:
984  case WindowType::MULTILISTBOX:
985  case WindowType::TREELISTBOX:
986  aCtrlType = ControlType::Listbox;
987  break;
988 
989  case WindowType::COMBOBOX:
990  case WindowType::PATTERNBOX:
991  case WindowType::NUMERICBOX:
992  case WindowType::METRICBOX:
993  case WindowType::CURRENCYBOX:
994  case WindowType::DATEBOX:
995  case WindowType::TIMEBOX:
996  case WindowType::LONGCURRENCYBOX:
997  aCtrlType = ControlType::Combobox;
998  break;
999  default:
1000  break;
1001  }
1002 
1003  bool bDropDown = (IsSymbol() && (GetSymbol() == SymbolType::SPIN_DOWN) && GetText().isEmpty());
1004 
1005  if( bDropDown && (aCtrlType == ControlType::Combobox || aCtrlType == ControlType::Listbox))
1006  {
1008  {
1009  // skip painting if the button was already drawn by the theme
1010  if (aCtrlType == ControlType::Combobox)
1011  {
1012  Edit* pEdit = static_cast<Edit*>(GetParent());
1013  if (pEdit->ImplUseNativeBorder(rRenderContext, pEdit->GetStyle()))
1014  bNativeOK = true;
1015  }
1017  {
1018  bNativeOK = true;
1019  }
1020 
1021  if (!bNativeOK && GetParent()->IsNativeControlSupported(aCtrlType, ControlPart::ButtonDown))
1022  {
1023  // let the theme draw it, note we then need support
1024  // for ControlType::Listbox/ControlPart::ButtonDown and ControlType::Combobox/ControlPart::ButtonDown
1025 
1026  ImplControlValue aControlValue;
1028 
1029  if (mbPressed || mbIsActive)
1030  nState |= ControlState::PRESSED;
1032  nState |= ControlState::PRESSED;
1033  if (HasFocus())
1034  nState |= ControlState::FOCUSED;
1036  nState |= ControlState::DEFAULT;
1037  if (Window::IsEnabled())
1038  nState |= ControlState::ENABLED;
1039 
1040  if (IsMouseOver() && aInRect.Contains(GetPointerPosPixel()))
1041  nState |= ControlState::ROLLOVER;
1042 
1043  if ( IsMouseOver() && aInRect.Contains(GetPointerPosPixel()) && mbIsActive)
1044  {
1045  nState |= ControlState::ROLLOVER;
1046  nButtonStyle &= ~DrawButtonFlags::Pressed;
1047  }
1048 
1049  bNativeOK = rRenderContext.DrawNativeControl(aCtrlType, ControlPart::ButtonDown, aInRect, nState,
1050  aControlValue, OUString());
1051  }
1052  }
1053  }
1054 
1055  if (bNativeOK)
1056  return;
1057 
1058  bool bRollOver = (IsMouseOver() && aInRect.Contains(GetPointerPosPixel()));
1059  if (bRollOver)
1060  nButtonStyle |= DrawButtonFlags::Highlight;
1061  bool bDrawMenuSep = mnDDStyle == PushButtonDropdownStyle::SplitMenuButton;
1062  if (GetStyle() & WB_FLATBUTTON)
1063  {
1064  if (!bRollOver && !HasFocus())
1065  bDrawMenuSep = false;
1066  }
1067  // tdf#123175 if there is a custom control bg set, draw the button without outsourcing to the NWF
1069  if (bNativeOK)
1070  {
1071  PushButtonValue aControlValue;
1072  aControlValue.mbIsAction = isAction();
1073 
1074  tools::Rectangle aCtrlRegion(aInRect);
1076 
1077  if (mbPressed || IsChecked() || mbIsActive)
1078  {
1079  nState |= ControlState::PRESSED;
1080  nButtonStyle |= DrawButtonFlags::Pressed;
1081  }
1083  nState |= ControlState::PRESSED;
1084  if (HasFocus())
1085  nState |= ControlState::FOCUSED;
1087  nState |= ControlState::DEFAULT;
1088  if (Window::IsEnabled())
1089  nState |= ControlState::ENABLED;
1090 
1091  if (bRollOver || mbIsActive)
1092  {
1093  nButtonStyle |= DrawButtonFlags::Highlight;
1094  nState |= ControlState::ROLLOVER;
1095  }
1096 
1097  if (mbIsActive && bRollOver)
1098  {
1099  nState &= ~ControlState::PRESSED;
1100  nButtonStyle &= ~DrawButtonFlags::Pressed;
1101  }
1102 
1103  if (GetStyle() & WB_FLATBUTTON)
1104  aControlValue.m_bFlatButton = true;
1105  if (GetStyle() & WB_BEVELBUTTON)
1106  aControlValue.mbBevelButton = true;
1107 
1108  // draw frame into invisible window to have aInRect modified correctly
1109  // but do not shift the inner rect for pressed buttons (ie remove DrawButtonFlags::Pressed)
1110  // this assumes the theme has enough visual cues to signalize the button was pressed
1111  //Window aWin( this );
1112  //ImplDrawPushButtonFrame( &aWin, aInRect, nButtonStyle & ~DrawButtonFlags::Pressed );
1113 
1114  // looks better this way as symbols were displaced slightly using the above approach
1115  aInRect.AdjustTop(4 );
1116  aInRect.AdjustBottom( -4 );
1117  aInRect.AdjustLeft(4 );
1118  aInRect.AdjustRight( -4 );
1119 
1120  // prepare single line hint (needed on mac to decide between normal push button and
1121  // rectangular bevel button look)
1122  Size aFontSize(Application::GetSettings().GetStyleSettings().GetPushButtonFont().GetFontSize());
1123  aFontSize = rRenderContext.LogicToPixel(aFontSize, MapMode(MapUnit::MapPoint));
1124  Size aInRectSize(rRenderContext.LogicToPixel(Size(aInRect.GetWidth(), aInRect.GetHeight())));
1125  aControlValue.mbSingleLine = (aInRectSize.Height() < 2 * aFontSize.Height());
1126 
1127  if ((nState & ControlState::ROLLOVER) || !(GetStyle() & WB_FLATBUTTON)
1128  || (HasFocus() && mpWindowImpl->mbUseNativeFocus
1130  {
1131  bNativeOK = rRenderContext.DrawNativeControl(ControlType::Pushbutton, ControlPart::Entire, aCtrlRegion, nState,
1132  aControlValue, OUString() /*PushButton::GetText()*/);
1133  }
1134  else
1135  {
1136  bNativeOK = true;
1137  }
1138 
1139  // draw content using the same aInRect as non-native VCL would do
1141  aInRect, bDrawMenuSep, nButtonStyle);
1142 
1143  if (HasFocus())
1145  }
1146 
1147  if (bNativeOK)
1148  return;
1149 
1150  // draw PushButtonFrame, aInRect has content size afterwards
1151  if (GetStyle() & WB_FLATBUTTON)
1152  {
1153  tools::Rectangle aTempRect(aInRect);
1154  if (bRollOver)
1155  ImplDrawPushButtonFrame(rRenderContext, aTempRect, nButtonStyle);
1156  aInRect.AdjustLeft(2 );
1157  aInRect.AdjustTop(2 );
1158  aInRect.AdjustRight( -2 );
1159  aInRect.AdjustBottom( -2 );
1160  }
1161  else
1162  {
1163  ImplDrawPushButtonFrame(rRenderContext, aInRect, nButtonStyle);
1164  }
1165 
1166  // draw content
1167  ImplDrawPushButtonContent(&rRenderContext, SystemTextColorFlags::NONE, aInRect, bDrawMenuSep, nButtonStyle);
1168 
1169  if (HasFocus())
1170  {
1172  }
1173 }
1174 
1176 {
1177  Size aSize( GetSizePixel() );
1178  Point aPos( GetPosPixel() );
1179  int dLeft(0), dRight(0), dTop(0), dBottom(0);
1180  bool bSetPos = false;
1181 
1183  {
1184  tools::Rectangle aBound, aCont;
1185  tools::Rectangle aCtrlRegion( 0, 0, 80, 20 ); // use a constant size to avoid accumulating
1186  // will not work if the theme has dynamic adornment sizes
1187  ImplControlValue aControlValue;
1188 
1189  // get native size of a 'default' button
1190  // and adjust the VCL button if more space for adornment is required
1193  aControlValue,
1194  aBound, aCont ) )
1195  {
1196  dLeft = aCont.Left() - aBound.Left();
1197  dTop = aCont.Top() - aBound.Top();
1198  dRight = aBound.Right() - aCont.Right();
1199  dBottom = aBound.Bottom() - aCont.Bottom();
1200  bSetPos = dLeft || dTop || dRight || dBottom;
1201  }
1202  }
1203 
1204  if ( bSet )
1205  {
1206  if( !(GetButtonState() & DrawButtonFlags::Default) && bSetPos )
1207  {
1208  // adjust pos/size when toggling from non-default to default
1209  aPos.Move(-dLeft, -dTop);
1210  aSize.AdjustWidth(dLeft + dRight );
1211  aSize.AdjustHeight(dTop + dBottom );
1212  }
1214  }
1215  else
1216  {
1217  if( (GetButtonState() & DrawButtonFlags::Default) && bSetPos )
1218  {
1219  // adjust pos/size when toggling from default to non-default
1220  aPos.Move(dLeft, dTop);
1221  aSize.AdjustWidth( -(dLeft + dRight) );
1222  aSize.AdjustHeight( -(dTop + dBottom) );
1223  }
1224  GetButtonState() &= ~DrawButtonFlags::Default;
1225  }
1226  if( bSetPos )
1227  setPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height() );
1228 
1229  Invalidate();
1230 }
1231 
1233 {
1234  return bool(GetButtonState() & DrawButtonFlags::Default);
1235 }
1236 
1238  Button( nType )
1239 {
1241 }
1242 
1245 {
1247  ImplInit( pParent, nStyle );
1248 }
1249 
1251 {
1252  if ( !(rMEvt.IsLeft() &&
1253  ImplHitTestPushButton( this, rMEvt.GetPosPixel() )) )
1254  return;
1255 
1257 
1258  if ( ( GetStyle() & WB_REPEAT ) &&
1259  ! ( GetStyle() & WB_TOGGLE ) )
1260  nTrackFlags |= StartTrackingFlags::ButtonRepeat;
1261 
1263  Invalidate();
1264  StartTracking( nTrackFlags );
1265 
1266  if ( nTrackFlags & StartTrackingFlags::ButtonRepeat )
1267  Click();
1268 }
1269 
1271 {
1272  if ( rTEvt.IsTrackingEnded() )
1273  {
1275  {
1276  if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() )
1277  GrabFocus();
1278 
1279  if ( GetStyle() & WB_TOGGLE )
1280  {
1281  // Don't toggle, when aborted
1282  if ( !rTEvt.IsTrackingCanceled() )
1283  {
1284  if ( IsChecked() )
1285  {
1286  Check( false );
1288  }
1289  else
1290  Check();
1291  }
1292  }
1293  else
1295 
1296  Invalidate();
1297 
1298  // do not call Click handler if aborted
1299  if ( !rTEvt.IsTrackingCanceled() )
1300  {
1301  if ( ! ( GetStyle() & WB_REPEAT ) || ( GetStyle() & WB_TOGGLE ) )
1302  Click();
1303  }
1304  }
1305  }
1306  else
1307  {
1308  if ( ImplHitTestPushButton( this, rTEvt.GetMouseEvent().GetPosPixel() ) )
1309  {
1311  {
1312  if ( rTEvt.IsTrackingRepeat() && (GetStyle() & WB_REPEAT) &&
1313  ! ( GetStyle() & WB_TOGGLE ) )
1314  Click();
1315  }
1316  else
1317  {
1319  Invalidate();
1320  }
1321  }
1322  else
1323  {
1325  {
1327  Invalidate();
1328  }
1329  }
1330  }
1331 }
1332 
1333 void PushButton::KeyInput( const KeyEvent& rKEvt )
1334 {
1335  vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
1336 
1337  if ( !aKeyCode.GetModifier() &&
1338  ((aKeyCode.GetCode() == KEY_RETURN) || (aKeyCode.GetCode() == KEY_SPACE)) )
1339  {
1341  {
1343  Invalidate();
1344  }
1345 
1346  if ( ( GetStyle() & WB_REPEAT ) &&
1347  ! ( GetStyle() & WB_TOGGLE ) )
1348  Click();
1349  }
1350  else if ( (GetButtonState() & DrawButtonFlags::Pressed) && (aKeyCode.GetCode() == KEY_ESCAPE) )
1351  {
1353  Invalidate();
1354  }
1355  else
1356  Button::KeyInput( rKEvt );
1357 }
1358 
1359 void PushButton::KeyUp( const KeyEvent& rKEvt )
1360 {
1361  vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
1362 
1364  ((aKeyCode.GetCode() == KEY_RETURN) || (aKeyCode.GetCode() == KEY_SPACE)) )
1365  {
1366  if ( GetStyle() & WB_TOGGLE )
1367  {
1368  if ( IsChecked() )
1369  {
1370  Check( false );
1372  }
1373  else
1374  Check();
1375 
1376  Toggle();
1377  }
1378  else
1380 
1381  Invalidate();
1382 
1383  if ( !( GetStyle() & WB_REPEAT ) || ( GetStyle() & WB_TOGGLE ) )
1384  Click();
1385  }
1386  else
1387  Button::KeyUp( rKEvt );
1388 }
1389 
1391 {
1392  mxLayoutData.emplace();
1393  const_cast<PushButton*>(this)->Invalidate();
1394 }
1395 
1397 {
1398  const Image& rCustomButtonImage = GetCustomButtonImage();
1399  if (!!rCustomButtonImage)
1400  {
1401  rRenderContext.DrawImage(Point(0, 0), rCustomButtonImage);
1402  return;
1403  }
1404  ImplDrawPushButton(rRenderContext);
1405 }
1406 
1407 void PushButton::Draw( OutputDevice* pDev, const Point& rPos,
1408  SystemTextColorFlags nFlags )
1409 {
1410  Point aPos = pDev->LogicToPixel( rPos );
1411  Size aSize = GetSizePixel();
1412  tools::Rectangle aRect( aPos, aSize );
1413  vcl::Font aFont = GetDrawPixelFont( pDev );
1414 
1415  pDev->Push();
1416  pDev->SetMapMode();
1417  pDev->SetFont( aFont );
1418 
1419  std::optional<StyleSettings> oOrigDevStyleSettings;
1420 
1421  if ( nFlags & SystemTextColorFlags::Mono )
1422  {
1423  pDev->SetTextColor( COL_BLACK );
1424  }
1425  else
1426  {
1427  pDev->SetTextColor( GetTextColor() );
1428  // DecoView uses the FaceColor...
1429  AllSettings aSettings = pDev->GetSettings();
1430  StyleSettings aStyleSettings = aSettings.GetStyleSettings();
1431  oOrigDevStyleSettings = aStyleSettings;
1432  if ( IsControlBackground() )
1433  aStyleSettings.SetFaceColor( GetControlBackground() );
1434  else
1435  aStyleSettings.SetFaceColor( GetSettings().GetStyleSettings().GetFaceColor() );
1436  aSettings.SetStyleSettings( aStyleSettings );
1437  pDev->OutputDevice::SetSettings( aSettings );
1438  }
1439  pDev->SetTextFillColor();
1440 
1441  DecorationView aDecoView( pDev );
1442  DrawButtonFlags nButtonStyle = DrawButtonFlags::NONE;
1443  if ( nFlags & SystemTextColorFlags::Mono )
1444  nButtonStyle |= DrawButtonFlags::Mono;
1445  if ( IsChecked() )
1446  nButtonStyle |= DrawButtonFlags::Checked;
1447  aRect = aDecoView.DrawButton( aRect, nButtonStyle );
1448 
1449  ImplDrawPushButtonContent( pDev, nFlags, aRect, true, nButtonStyle );
1450 
1451  // restore original settings (which are not affected by Push/Pop) after
1452  // finished drawing
1453  if (oOrigDevStyleSettings)
1454  {
1455  AllSettings aSettings = pDev->GetSettings();
1456  aSettings.SetStyleSettings(*oOrigDevStyleSettings);
1457  pDev->OutputDevice::SetSettings( aSettings );
1458  }
1459 
1460  pDev->Pop();
1461 }
1462 
1464 {
1465  Control::Resize();
1466  Invalidate();
1467 }
1468 
1470 {
1473  Button::GetFocus();
1474 }
1475 
1477 {
1478  EndSelection();
1479  HideFocus();
1481 }
1482 
1484 {
1485  Button::StateChanged( nType );
1486 
1487  if ( (nType == StateChangedType::Enable) ||
1488  (nType == StateChangedType::Text) ||
1489  (nType == StateChangedType::Data) ||
1490  (nType == StateChangedType::State) ||
1491  (nType == StateChangedType::UpdateMode) )
1492  {
1493  if ( IsReallyVisible() && IsUpdateMode() )
1494  Invalidate();
1495  }
1496  else if ( nType == StateChangedType::Style )
1497  {
1499 
1500  bool bIsDefButton = ( GetStyle() & WB_DEFBUTTON ) != 0;
1501  bool bWasDefButton = ( GetPrevStyle() & WB_DEFBUTTON ) != 0;
1502  if ( bIsDefButton != bWasDefButton )
1503  ImplSetDefButton( bIsDefButton );
1504 
1505  if ( IsReallyVisible() && IsUpdateMode() )
1506  {
1507  if ( (GetPrevStyle() & PUSHBUTTON_VIEW_STYLE) !=
1509  Invalidate();
1510  }
1511  }
1512  else if ( (nType == StateChangedType::Zoom) ||
1513  (nType == StateChangedType::ControlFont) )
1514  {
1515  ImplInitSettings( false );
1516  Invalidate();
1517  }
1518  else if ( nType == StateChangedType::ControlForeground )
1519  {
1520  ImplInitSettings( false );
1521  Invalidate();
1522  }
1523  else if ( nType == StateChangedType::ControlBackground )
1524  {
1525  ImplInitSettings( true );
1526  Invalidate();
1527  }
1528 }
1529 
1531 {
1532  Button::DataChanged( rDCEvt );
1533 
1534  if ( (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
1536  ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
1537  (rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
1538  {
1539  ImplInitSettings( true );
1540  Invalidate();
1541  }
1542 }
1543 
1545 {
1546  if( rNEvt.GetType() == MouseNotifyEvent::MOUSEMOVE )
1547  {
1548  const MouseEvent* pMouseEvt = rNEvt.GetMouseEvent();
1549  if( pMouseEvt && (pMouseEvt->IsEnterWindow() || pMouseEvt->IsLeaveWindow()) )
1550  {
1551  // trigger redraw as mouse over state has changed
1552 
1553  // TODO: move this to Window class or make it a member !!!
1554  ControlType aCtrlType = ControlType::Generic;
1555  switch( GetParent()->GetType() )
1556  {
1557  case WindowType::LISTBOX:
1558  case WindowType::MULTILISTBOX:
1559  case WindowType::TREELISTBOX:
1560  aCtrlType = ControlType::Listbox;
1561  break;
1562 
1563  case WindowType::COMBOBOX:
1564  case WindowType::PATTERNBOX:
1565  case WindowType::NUMERICBOX:
1566  case WindowType::METRICBOX:
1567  case WindowType::CURRENCYBOX:
1568  case WindowType::DATEBOX:
1569  case WindowType::TIMEBOX:
1570  case WindowType::LONGCURRENCYBOX:
1571  aCtrlType = ControlType::Combobox;
1572  break;
1573  default:
1574  break;
1575  }
1576 
1577  bool bDropDown = ( IsSymbol() && (GetSymbol()==SymbolType::SPIN_DOWN) && GetText().isEmpty() );
1578 
1579  if( bDropDown && GetParent()->IsNativeControlSupported( aCtrlType, ControlPart::Entire) &&
1581  {
1583  if(aCtrlType == ControlType::Combobox)
1584  {
1585  // only paint the button part to avoid flickering of the combobox text
1586  tools::Rectangle aClipRect( Point(), GetOutputSizePixel() );
1587  aClipRect.SetPos(pBorder->ScreenToOutputPixel(OutputToScreenPixel(aClipRect.TopLeft())));
1588  pBorder->Invalidate( aClipRect );
1589  }
1590  else
1591  {
1593  }
1594  }
1595  else if( (GetStyle() & WB_FLATBUTTON) ||
1597  {
1598  Invalidate();
1599  }
1600  }
1601  }
1602 
1603  return Button::PreNotify(rNEvt);
1604 }
1605 
1607 {
1609 }
1610 
1612 {
1613  if ( meSymbol != eSymbol )
1614  {
1615  meSymbol = eSymbol;
1617  }
1618 }
1619 
1621 {
1622  ImplSetSymbolAlign( eAlign );
1623 }
1624 
1626 {
1627  if ( mnDDStyle != nStyle )
1628  {
1629  mnDDStyle = nStyle;
1631  }
1632 }
1633 
1635 {
1636  if ( meState == eState )
1637  return;
1638 
1639  meState = eState;
1640  if ( meState == TRISTATE_FALSE )
1642  else if ( meState == TRISTATE_TRUE )
1643  {
1644  GetButtonState() &= ~DrawButtonFlags::DontKnow;
1646  }
1647  else // TRISTATE_INDET
1648  {
1649  GetButtonState() &= ~DrawButtonFlags::Checked;
1651  }
1652 
1654  Toggle();
1655 }
1656 
1657 void PushButton::statusChanged(const css::frame::FeatureStateEvent& rEvent)
1658 {
1659  Button::statusChanged(rEvent);
1660  if (rEvent.State.has<bool>())
1661  SetPressed(rEvent.State.get<bool>());
1662 }
1663 
1664 void PushButton::SetPressed( bool bPressed )
1665 {
1666  if ( mbPressed != bPressed )
1667  {
1668  mbPressed = bPressed;
1670  }
1671 }
1672 
1674 {
1676  if ( !isDisposed() &&
1678  {
1680  if ( !mbPressed )
1681  Invalidate();
1682  }
1683 }
1684 
1686 {
1687  Size aSize;
1688 
1689  if ( IsSymbol() )
1690  {
1691  if ( IsSmallSymbol ())
1692  aSize = Size( 16, 12 );
1693  else
1694  aSize = Size( 26, 24 );
1695  }
1696  else if ( Button::HasImage() )
1697  aSize = GetModeImage().GetSizePixel();
1700  {
1701  tools::Long nSymbolSize = GetTextHeight() / 2 + 1;
1702  aSize.AdjustWidth(2*nSymbolSize );
1703  }
1704  if (!PushButton::GetText().isEmpty())
1705  {
1706  Size textSize = GetTextRect( tools::Rectangle( Point(), Size( 0x7fffffff, 0x7fffffff ) ),
1708 
1709  tools::Long nTextHeight = textSize.Height() * 1.15;
1710 
1711  ImageAlign eImageAlign = GetImageAlign();
1712  // tdf#142337 only considering the simple top/bottom/left/right possibilities
1713  if (eImageAlign == ImageAlign::Top || eImageAlign == ImageAlign::Bottom)
1714  {
1715  aSize.AdjustHeight(nTextHeight);
1716  aSize.setWidth(std::max(aSize.Width(), textSize.Width()));
1717  }
1718  else
1719  {
1720  aSize.AdjustWidth(textSize.Width());
1721  aSize.setHeight(std::max(aSize.Height(), nTextHeight));
1722  }
1723  }
1724 
1725  // cf. ImplDrawPushButton ...
1726  if( (GetStyle() & WB_SMALLSTYLE) == 0 )
1727  {
1728  aSize.AdjustWidth(24 );
1729  aSize.AdjustHeight(12 );
1730  }
1731 
1732  return CalcWindowSize( aSize );
1733 }
1734 
1736 {
1737  return CalcMinimumSize();
1738 }
1739 
1740 bool PushButton::set_property(const OString &rKey, const OUString &rValue)
1741 {
1742  if (rKey == "has-default")
1743  {
1744  WinBits nBits = GetStyle();
1745  nBits &= ~WB_DEFBUTTON;
1746  if (toBool(rValue))
1747  nBits |= WB_DEFBUTTON;
1748  SetStyle(nBits);
1749  }
1750  else
1751  return Button::set_property(rKey, rValue);
1752  return true;
1753 }
1754 
1756 {
1758  {
1759  PushButtonValue aControlValue;
1760  aControlValue.mbIsAction = isAction();
1763  ControlState::FOCUSED, aControlValue, OUString());
1764  }
1765  Button::ShowFocus(rRect);
1766 }
1767 
1768 void OKButton::ImplInit( vcl::Window* pParent, WinBits nStyle )
1769 {
1770  set_id("ok");
1771  PushButton::ImplInit( pParent, nStyle );
1772 
1773  SetText( GetStandardText( StandardButtonType::OK ) );
1774 }
1775 
1778 {
1779  ImplInit( pParent, nStyle );
1780 }
1781 
1783 {
1784  // close parent if no link set
1785  if ( !GetClickHdl() )
1786  {
1787  vcl::Window* pParent = getNonLayoutParent(this);
1788  if ( pParent->IsSystemWindow() )
1789  {
1790  if ( pParent->IsDialog() )
1791  {
1792  VclPtr<Dialog> xParent( static_cast<Dialog*>(pParent) );
1793  if ( xParent->IsInExecute() )
1794  xParent->EndDialog( RET_OK );
1795  // prevent recursive calls
1796  else if ( !xParent->IsInClose() )
1797  {
1798  if ( pParent->GetStyle() & WB_CLOSEABLE )
1799  xParent->Close();
1800  }
1801  }
1802  else
1803  {
1804  if ( pParent->GetStyle() & WB_CLOSEABLE )
1805  static_cast<SystemWindow*>(pParent)->Close();
1806  }
1807  }
1808  }
1809  else
1810  {
1812  }
1813 }
1814 
1816 {
1817  set_id("cancel");
1818  PushButton::ImplInit( pParent, nStyle );
1819 
1820  SetText( GetStandardText( StandardButtonType::Cancel ) );
1821 }
1822 
1825 {
1826  ImplInit( pParent, nStyle );
1827 }
1828 
1830 {
1831  // close parent if link not set
1832  if ( !GetClickHdl() )
1833  {
1834  vcl::Window* pParent = getNonLayoutParent(this);
1835  if ( pParent->IsSystemWindow() )
1836  {
1837  if ( pParent->IsDialog() )
1838  {
1839  if ( static_cast<Dialog*>(pParent)->IsInExecute() )
1840  static_cast<Dialog*>(pParent)->EndDialog();
1841  // prevent recursive calls
1842  else if ( !static_cast<Dialog*>(pParent)->IsInClose() )
1843  {
1844  if ( pParent->GetStyle() & WB_CLOSEABLE )
1845  static_cast<Dialog*>(pParent)->Close();
1846  }
1847  }
1848  else
1849  {
1850  if ( pParent->GetStyle() & WB_CLOSEABLE )
1851  static_cast<SystemWindow*>(pParent)->Close();
1852  }
1853  }
1854  }
1855  else
1856  {
1858  }
1859 }
1860 
1862  : CancelButton(pParent, 0)
1863 {
1864  SetText( GetStandardText( StandardButtonType::Close ) );
1865 }
1866 
1867 void HelpButton::ImplInit( vcl::Window* pParent, WinBits nStyle )
1868 {
1869  set_id("help");
1870  PushButton::ImplInit( pParent, nStyle | WB_NOPOINTERFOCUS );
1871 
1872  SetText( GetStandardText( StandardButtonType::Help ) );
1873 }
1874 
1877 {
1878  ImplInit( pParent, nStyle );
1879 }
1880 
1882 {
1883  // trigger help if no link set
1884  if ( !GetClickHdl() )
1885  {
1887  if ( !pFocusWin || comphelper::LibreOfficeKit::isActive() )
1888  pFocusWin = this;
1889 
1890  HelpEvent aEvt( pFocusWin->GetPointerPosPixel(), HelpEventMode::CONTEXT );
1891  pFocusWin->RequestHelp( aEvt );
1892  }
1894 }
1895 
1897 {
1898  // Hide when we have no help URL.
1900  officecfg::Office::Common::Help::HelpRootURL::get().isEmpty())
1901  Hide();
1902  else
1903  PushButton::StateChanged(nStateChange);
1904 }
1905 
1907 {
1908  mbChecked = false;
1909  mbRadioCheck = true;
1910  mbStateChanged = false;
1911 }
1912 
1914 {
1915  nStyle = ImplInitStyle(getPreviousSibling(pParent), nStyle);
1916  Button::ImplInit( pParent, nStyle, nullptr );
1917 
1918  ImplInitSettings( true );
1919 }
1920 
1921 WinBits RadioButton::ImplInitStyle( const vcl::Window* pPrevWindow, WinBits nStyle ) const
1922 {
1923  if ( !(nStyle & WB_NOGROUP) &&
1924  (!pPrevWindow || (pPrevWindow->GetType() != WindowType::RADIOBUTTON)) )
1925  nStyle |= WB_GROUP;
1926  if ( !(nStyle & WB_NOTABSTOP) )
1927  {
1928  if ( IsChecked() )
1929  nStyle |= WB_TABSTOP;
1930  else
1931  nStyle &= ~WB_TABSTOP;
1932  }
1933 
1934  return nStyle;
1935 }
1936 
1938 {
1939  return _rStyle.GetRadioCheckFont();
1940 }
1941 
1943 {
1944  return _rStyle.GetRadioCheckTextColor();
1945 }
1946 
1947 void RadioButton::ImplInitSettings( bool bBackground )
1948 {
1950 
1951  if ( !bBackground )
1952  return;
1953 
1954  vcl::Window* pParent = GetParent();
1955  if ( !IsControlBackground() &&
1957  {
1960  SetPaintTransparent( true );
1961  SetBackground();
1963  mpWindowImpl->mbUseNativeFocus = ImplGetSVData()->maNWFData.mbNoFocusRects;
1964  }
1965  else
1966  {
1967  EnableChildTransparentMode( false );
1969  SetPaintTransparent( false );
1970 
1971  if ( IsControlBackground() )
1973  else
1974  SetBackground( pParent->GetBackground() );
1975  }
1976 }
1977 
1979 {
1980  bool bNativeOK = false;
1981 
1982  // no native drawing for image radio buttons
1984  {
1988 
1990  nState |= ControlState::PRESSED;
1991  if (HasFocus())
1992  nState |= ControlState::FOCUSED;
1994  nState |= ControlState::DEFAULT;
1995  if (IsEnabled())
1996  nState |= ControlState::ENABLED;
1997 
1999  nState |= ControlState::ROLLOVER;
2000 
2001  bNativeOK = rRenderContext.DrawNativeControl(ControlType::Radiobutton, ControlPart::Entire, aCtrlRect,
2002  nState, aControlValue, OUString());
2003  }
2004 
2005  if (bNativeOK)
2006  return;
2007 
2008  if (!maImage)
2009  {
2010  DrawButtonFlags nStyle = GetButtonState();
2011  if (!IsEnabled())
2012  nStyle |= DrawButtonFlags::Disabled;
2013  if (mbChecked)
2014  nStyle |= DrawButtonFlags::Checked;
2015  Image aImage = GetRadioImage(rRenderContext.GetSettings(), nStyle);
2016  if (IsZoom())
2017  rRenderContext.DrawImage(maStateRect.TopLeft(), maStateRect.GetSize(), aImage);
2018  else
2019  rRenderContext.DrawImage(maStateRect.TopLeft(), aImage);
2020  }
2021  else
2022  {
2023  HideFocus();
2024 
2025  DecorationView aDecoView(&rRenderContext);
2026  const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
2027  tools::Rectangle aImageRect = maStateRect;
2028  Size aImageSize = maImage.GetSizePixel();
2029  bool bEnabled = IsEnabled();
2030 
2031  aImageSize.setWidth( CalcZoom(aImageSize.Width()) );
2032  aImageSize.setHeight( CalcZoom(aImageSize.Height()) );
2033 
2034  aImageRect.AdjustLeft( 1 );
2035  aImageRect.AdjustTop( 1 );
2036  aImageRect.AdjustRight( -1 );
2037  aImageRect.AdjustBottom( -1 );
2038 
2039  // display border and selection status
2040  aImageRect = aDecoView.DrawFrame(aImageRect, DrawFrameStyle::DoubleIn);
2041  if ((GetButtonState() & DrawButtonFlags::Pressed) || !bEnabled)
2042  rRenderContext.SetFillColor( rStyleSettings.GetFaceColor());
2043  else
2044  rRenderContext.SetFillColor(rStyleSettings.GetFieldColor());
2045  rRenderContext.SetLineColor();
2046  rRenderContext.DrawRect(aImageRect);
2047 
2048  // display image
2049  DrawImageFlags nImageStyle = DrawImageFlags::NONE;
2050  if (!bEnabled)
2051  nImageStyle |= DrawImageFlags::Disable;
2052 
2053  Image* pImage = &maImage;
2054 
2055  Point aImagePos(aImageRect.TopLeft());
2056  aImagePos.AdjustX((aImageRect.GetWidth() - aImageSize.Width()) / 2 );
2057  aImagePos.AdjustY((aImageRect.GetHeight() - aImageSize.Height()) / 2 );
2058  if (IsZoom())
2059  rRenderContext.DrawImage(aImagePos, aImageSize, *pImage, nImageStyle);
2060  else
2061  rRenderContext.DrawImage(aImagePos, *pImage, nImageStyle);
2062 
2063  aImageRect.AdjustLeft( 1 );
2064  aImageRect.AdjustTop( 1 );
2065  aImageRect.AdjustRight( -1 );
2066  aImageRect.AdjustBottom( -1 );
2067 
2068  ImplSetFocusRect(aImageRect);
2069 
2070  if (mbChecked)
2071  {
2072  rRenderContext.SetLineColor(rStyleSettings.GetHighlightColor());
2073  rRenderContext.SetFillColor();
2074  if ((aImageSize.Width() >= 20) || (aImageSize.Height() >= 20))
2075  {
2076  aImageRect.AdjustLeft( 1 );
2077  aImageRect.AdjustTop( 1 );
2078  aImageRect.AdjustRight( -1 );
2079  aImageRect.AdjustBottom( -1 );
2080  }
2081  rRenderContext.DrawRect(aImageRect);
2082  aImageRect.AdjustLeft( 1 );
2083  aImageRect.AdjustTop( 1 );
2084  aImageRect.AdjustRight( -1 );
2085  aImageRect.AdjustBottom( -1 );
2086  rRenderContext.DrawRect(aImageRect);
2087  }
2088 
2089  if (HasFocus())
2091  }
2092 }
2093 
2094 // for drawing RadioButton or CheckButton that has Text and/or Image
2095 void Button::ImplDrawRadioCheck(OutputDevice* pDev, WinBits nWinStyle, SystemTextColorFlags nSystemTextColorFlags,
2096  const Point& rPos, const Size& rSize,
2097  const Size& rImageSize, tools::Rectangle& rStateRect,
2098  tools::Rectangle& rMouseRect)
2099 {
2100  DrawTextFlags nTextStyle = Button::ImplGetTextStyle( nWinStyle, nSystemTextColorFlags );
2101 
2102  const tools::Long nImageSep = GetDrawPixel( pDev, ImplGetImageToTextDistance() );
2103  Size aSize( rSize );
2104  Point aPos( rPos );
2105  aPos.AdjustX(rImageSize.Width() + nImageSep );
2106 
2107  // tdf#141761 Old (convenience?) adjustment of width may lead to empty
2108  // or negative(!) Size, that needs to be avoided. The coordinate context
2109  // is pixel-oriented (all Paints of Controls are, historically), so
2110  // the minimum width should be '1' Pixel.
2111  // Hint: nImageSep is based on Zoom (using Window::CalcZoom) and
2112  // MapModes (using Window::GetDrawPixel) - so potentially a wide range
2113  // of unpredictable values is possible
2114  const tools::Long nWidthAdjust(rImageSize.Width() + nImageSep);
2115  aSize.setWidth(std::max(static_cast<tools::Long>(1), aSize.getWidth() - nWidthAdjust));
2116 
2117  // if the text rect height is smaller than the height of the image
2118  // then for single lines the default should be centered text
2119  if( (nWinStyle & (WB_TOP|WB_VCENTER|WB_BOTTOM)) == 0 &&
2120  (rImageSize.Height() > rSize.Height() || ! (nWinStyle & WB_WORDBREAK) ) )
2121  {
2123  nTextStyle |= DrawTextFlags::VCenter;
2124  aSize.setHeight( rImageSize.Height() );
2125  }
2126 
2127  ImplDrawAlignedImage( pDev, aPos, aSize, 1, nTextStyle );
2128 
2129  rMouseRect = tools::Rectangle( aPos, aSize );
2130  rMouseRect.SetLeft( rPos.X() );
2131 
2132  rStateRect.SetLeft( rPos.X() );
2133  rStateRect.SetTop( rMouseRect.Top() );
2134 
2135  if ( aSize.Height() > rImageSize.Height() )
2136  rStateRect.AdjustTop(( aSize.Height() - rImageSize.Height() ) / 2 );
2137  else
2138  {
2139  rStateRect.AdjustTop( -(( rImageSize.Height() - aSize.Height() ) / 2) );
2140  if( rStateRect.Top() < 0 )
2141  rStateRect.SetTop( 0 );
2142  }
2143 
2144  rStateRect.SetRight( rStateRect.Left()+rImageSize.Width()-1 );
2145  rStateRect.SetBottom( rStateRect.Top()+rImageSize.Height()-1 );
2146 
2147  if ( rStateRect.Bottom() > rMouseRect.Bottom() )
2148  rMouseRect.SetBottom( rStateRect.Bottom() );
2149 }
2150 
2151 void RadioButton::ImplDraw( OutputDevice* pDev, SystemTextColorFlags nSystemTextColorFlags,
2152  const Point& rPos, const Size& rSize,
2153  const Size& rImageSize, tools::Rectangle& rStateRect,
2154  tools::Rectangle& rMouseRect )
2155 {
2156  WinBits nWinStyle = GetStyle();
2157  OUString aText( GetText() );
2158 
2160  pDev->IntersectClipRegion( tools::Rectangle( rPos, rSize ) );
2161 
2162  // no image radio button
2163  if ( !maImage )
2164  {
2165  if (!aText.isEmpty() || HasImage())
2166  {
2167  Button::ImplDrawRadioCheck(pDev, nWinStyle, nSystemTextColorFlags,
2168  rPos, rSize, rImageSize,
2169  rStateRect, rMouseRect);
2170  }
2171  else
2172  {
2173  rStateRect.SetLeft( rPos.X() );
2174  if ( nWinStyle & WB_VCENTER )
2175  rStateRect.SetTop( rPos.Y()+((rSize.Height()-rImageSize.Height())/2) );
2176  else if ( nWinStyle & WB_BOTTOM )
2177  rStateRect.SetTop( rPos.Y()+rSize.Height()-rImageSize.Height() ); //-1;
2178  else
2179  rStateRect.SetTop( rPos.Y() );
2180  rStateRect.SetRight( rStateRect.Left()+rImageSize.Width()-1 );
2181  rStateRect.SetBottom( rStateRect.Top()+rImageSize.Height()-1 );
2182  rMouseRect = rStateRect;
2183 
2184  ImplSetFocusRect( rStateRect );
2185  }
2186  }
2187  else
2188  {
2189  bool bTopImage = (nWinStyle & WB_TOP) != 0;
2190  Size aImageSize = maImage.GetSizePixel();
2191  tools::Rectangle aImageRect( rPos, rSize );
2192  tools::Long nTextHeight = pDev->GetTextHeight();
2193  tools::Long nTextWidth = pDev->GetCtrlTextWidth( aText );
2194 
2195  // calculate position and sizes
2196  if (!aText.isEmpty())
2197  {
2198  Size aTmpSize( (aImageSize.Width()+8), (aImageSize.Height()+8) );
2199  if ( bTopImage )
2200  {
2201  aImageRect.SetLeft( (rSize.Width()-aTmpSize.Width())/2 );
2202  aImageRect.SetTop( (rSize.Height()-(aTmpSize.Height()+nTextHeight+6))/2 );
2203  }
2204  else
2205  aImageRect.SetTop( (rSize.Height()-aTmpSize.Height())/2 );
2206 
2207  aImageRect.SetRight( aImageRect.Left()+aTmpSize.Width() );
2208  aImageRect.SetBottom( aImageRect.Top()+aTmpSize.Height() );
2209 
2210  // display text
2211  Point aTxtPos = rPos;
2212  if ( bTopImage )
2213  {
2214  aTxtPos.AdjustX((rSize.Width()-nTextWidth)/2 );
2215  aTxtPos.AdjustY(aImageRect.Bottom()+6 );
2216  }
2217  else
2218  {
2219  aTxtPos.AdjustX(aImageRect.Right()+8 );
2220  aTxtPos.AdjustY((rSize.Height()-nTextHeight)/2 );
2221  }
2222  pDev->DrawCtrlText( aTxtPos, aText, 0, aText.getLength() );
2223  }
2224 
2225  rMouseRect = aImageRect;
2226  rStateRect = aImageRect;
2227  }
2228 
2229  pDev->Pop();
2230 }
2231 
2233 {
2234  HideFocus();
2235 
2236  Size aImageSize;
2237  if (!maImage)
2238  aImageSize = ImplGetRadioImageSize();
2239  else
2240  aImageSize = maImage.GetSizePixel();
2241 
2242  aImageSize.setWidth( CalcZoom(aImageSize.Width()) );
2243  aImageSize.setHeight( CalcZoom(aImageSize.Height()) );
2244 
2245  // Draw control text
2247  aImageSize, maStateRect, maMouseRect);
2248 
2249  if (!maImage && HasFocus())
2251 
2252  ImplDrawRadioButtonState(rRenderContext);
2253 }
2254 
2256 {
2257  if (&rOther == this)
2258  return;
2259 
2260  if (!m_xGroup)
2261  {
2262  m_xGroup = std::make_shared<std::vector<VclPtr<RadioButton> >>();
2263  m_xGroup->push_back(this);
2264  }
2265 
2266  auto aFind = std::find(m_xGroup->begin(), m_xGroup->end(), VclPtr<RadioButton>(&rOther));
2267  if (aFind == m_xGroup->end())
2268  {
2269  m_xGroup->push_back(&rOther);
2270 
2271  if (rOther.m_xGroup)
2272  {
2273  std::vector< VclPtr<RadioButton> > aOthers(rOther.GetRadioButtonGroup(false));
2274  //make all members of the group share the same button group
2275  for (auto const& elem : aOthers)
2276  {
2277  aFind = std::find(m_xGroup->begin(), m_xGroup->end(), elem);
2278  if (aFind == m_xGroup->end())
2279  m_xGroup->push_back(elem);
2280  }
2281  }
2282 
2283  //make all members of the group share the same button group
2284  for (VclPtr<RadioButton> const & pButton : *m_xGroup)
2285  {
2286  pButton->m_xGroup = m_xGroup;
2287  }
2288  }
2289 
2290  //if this one is checked, uncheck all the others
2291  if (mbChecked)
2293 }
2294 
2295 std::vector< VclPtr<RadioButton> > RadioButton::GetRadioButtonGroup(bool bIncludeThis) const
2296 {
2297  if (m_xGroup)
2298  {
2299  if (bIncludeThis)
2300  return *m_xGroup;
2301  std::vector< VclPtr<RadioButton> > aGroup;
2302  for (VclPtr<RadioButton> const & pRadioButton : *m_xGroup)
2303  {
2304  if (pRadioButton == this)
2305  continue;
2306  aGroup.push_back(pRadioButton);
2307  }
2308  return aGroup;
2309  }
2310 
2311  std::vector<VclPtr<RadioButton>> aGroup;
2312  if (mbUsesExplicitGroup)
2313  return aGroup;
2314 
2315  //old-school
2316 
2317  // go back to first in group;
2318  vcl::Window* pFirst = const_cast<RadioButton*>(this);
2319  while( ( pFirst->GetStyle() & WB_GROUP ) == 0 )
2320  {
2321  vcl::Window* pWindow = pFirst->GetWindow( GetWindowType::Prev );
2322  if( pWindow )
2323  pFirst = pWindow;
2324  else
2325  break;
2326  }
2327  // insert radiobuttons up to next group
2328  do
2329  {
2330  if( pFirst->GetType() == WindowType::RADIOBUTTON )
2331  {
2332  if( pFirst != this || bIncludeThis )
2333  aGroup.emplace_back(static_cast<RadioButton*>(pFirst) );
2334  }
2335  pFirst = pFirst->GetWindow( GetWindowType::Next );
2336  } while( pFirst && ( ( pFirst->GetStyle() & WB_GROUP ) == 0 ) );
2337 
2338  return aGroup;
2339 }
2340 
2342 {
2343  mpWindowImpl->mnStyle |= WB_TABSTOP;
2344 
2345  std::vector<VclPtr<RadioButton> > aGroup(GetRadioButtonGroup(false));
2346  // iterate over radio button group and checked buttons
2347  for (VclPtr<RadioButton>& pWindow : aGroup)
2348  {
2349  if ( pWindow->IsChecked() )
2350  {
2351  pWindow->SetState( false );
2352  if ( pWindow->isDisposed() )
2353  return;
2354  }
2355 
2356  // not inside if clause to always remove wrongly set WB_TABSTOPS
2357  pWindow->mpWindowImpl->mnStyle &= ~WB_TABSTOP;
2358  }
2359 }
2360 
2361 void RadioButton::ImplCallClick( bool bGrabFocus, GetFocusFlags nFocusFlags )
2362 {
2364  mbChecked = true;
2365  mpWindowImpl->mnStyle |= WB_TABSTOP;
2366  Invalidate();
2367  VclPtr<vcl::Window> xWindow = this;
2368  if ( mbRadioCheck )
2370  if ( xWindow->isDisposed() )
2371  return;
2372  if ( bGrabFocus )
2373  ImplGrabFocus( nFocusFlags );
2374  if ( xWindow->isDisposed() )
2375  return;
2376  if ( mbStateChanged )
2377  Toggle();
2378  if ( xWindow->isDisposed() )
2379  return;
2380  Click();
2381  if ( xWindow->isDisposed() )
2382  return;
2383  mbStateChanged = false;
2384 }
2385 
2386 RadioButton::RadioButton(vcl::Window* pParent, bool bUsesExplicitGroup, WinBits nStyle)
2388  , mbUsesExplicitGroup(bUsesExplicitGroup)
2389 {
2391  ImplInit( pParent, nStyle );
2392 }
2393 
2395 {
2396  disposeOnce();
2397 }
2398 
2400 {
2401  if (m_xGroup)
2402  {
2403  m_xGroup->erase(std::remove(m_xGroup->begin(), m_xGroup->end(), VclPtr<RadioButton>(this)),
2404  m_xGroup->end());
2405  m_xGroup.reset();
2406  }
2407  Button::dispose();
2408 }
2409 
2411 {
2412  if ( rMEvt.IsLeft() && maMouseRect.Contains( rMEvt.GetPosPixel() ) )
2413  {
2415  Invalidate();
2416  StartTracking();
2417  return;
2418  }
2419 
2420  Button::MouseButtonDown( rMEvt );
2421 }
2422 
2424 {
2425  if ( rTEvt.IsTrackingEnded() )
2426  {
2428  {
2429  if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() )
2430  GrabFocus();
2431 
2433 
2434  // do not call click handler if aborted
2435  if ( !rTEvt.IsTrackingCanceled() )
2436  ImplCallClick();
2437  else
2438  {
2439  Invalidate();
2440  }
2441  }
2442  }
2443  else
2444  {
2445  if ( maMouseRect.Contains( rTEvt.GetMouseEvent().GetPosPixel() ) )
2446  {
2448  {
2450  Invalidate();
2451  }
2452  }
2453  else
2454  {
2456  {
2458  Invalidate();
2459  }
2460  }
2461  }
2462 }
2463 
2464 void RadioButton::KeyInput( const KeyEvent& rKEvt )
2465 {
2466  vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
2467 
2468  if ( !aKeyCode.GetModifier() && (aKeyCode.GetCode() == KEY_SPACE) )
2469  {
2471  {
2473  Invalidate();
2474  }
2475  }
2476  else if ( (GetButtonState() & DrawButtonFlags::Pressed) && (aKeyCode.GetCode() == KEY_ESCAPE) )
2477  {
2479  Invalidate();
2480  }
2481  else
2482  Button::KeyInput( rKEvt );
2483 }
2484 
2485 void RadioButton::KeyUp( const KeyEvent& rKEvt )
2486 {
2487  vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
2488 
2489  if ( (GetButtonState() & DrawButtonFlags::Pressed) && (aKeyCode.GetCode() == KEY_SPACE) )
2490  {
2492  ImplCallClick();
2493  }
2494  else
2495  Button::KeyUp( rKEvt );
2496 }
2497 
2499 {
2500  mxLayoutData.emplace();
2501  const_cast<RadioButton*>(this)->Invalidate();
2502 }
2503 
2505 {
2506  ImplDrawRadioButton(rRenderContext);
2507 }
2508 
2509 void RadioButton::Draw( OutputDevice* pDev, const Point& rPos,
2510  SystemTextColorFlags nFlags )
2511 {
2512  if ( !maImage )
2513  {
2514  MapMode aResMapMode( MapUnit::Map100thMM );
2515  Point aPos = pDev->LogicToPixel( rPos );
2516  Size aSize = GetSizePixel();
2517  Size aImageSize = pDev->LogicToPixel( Size( 300, 300 ), aResMapMode );
2518  Size aBrd1Size = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode );
2519  Size aBrd2Size = pDev->LogicToPixel( Size( 60, 60 ), aResMapMode );
2520  vcl::Font aFont = GetDrawPixelFont( pDev );
2521  tools::Rectangle aStateRect;
2522  tools::Rectangle aMouseRect;
2523 
2524  aImageSize.setWidth( CalcZoom( aImageSize.Width() ) );
2525  aImageSize.setHeight( CalcZoom( aImageSize.Height() ) );
2526  aBrd1Size.setWidth( CalcZoom( aBrd1Size.Width() ) );
2527  aBrd1Size.setHeight( CalcZoom( aBrd1Size.Height() ) );
2528  aBrd2Size.setWidth( CalcZoom( aBrd2Size.Width() ) );
2529  aBrd2Size.setHeight( CalcZoom( aBrd2Size.Height() ) );
2530 
2531  if ( !aBrd1Size.Width() )
2532  aBrd1Size.setWidth( 1 );
2533  if ( !aBrd1Size.Height() )
2534  aBrd1Size.setHeight( 1 );
2535  if ( !aBrd2Size.Width() )
2536  aBrd2Size.setWidth( 1 );
2537  if ( !aBrd2Size.Height() )
2538  aBrd2Size.setHeight( 1 );
2539 
2540  pDev->Push();
2541  pDev->SetMapMode();
2542  pDev->SetFont( aFont );
2543  if ( nFlags & SystemTextColorFlags::Mono )
2544  pDev->SetTextColor( COL_BLACK );
2545  else
2546  pDev->SetTextColor( GetTextColor() );
2547  pDev->SetTextFillColor();
2548 
2549  ImplDraw( pDev, nFlags, aPos, aSize,
2550  aImageSize, aStateRect, aMouseRect );
2551 
2552  Point aCenterPos = aStateRect.Center();
2553  tools::Long nRadX = aImageSize.Width()/2;
2554  tools::Long nRadY = aImageSize.Height()/2;
2555 
2556  pDev->SetLineColor();
2557  pDev->SetFillColor( COL_BLACK );
2558  pDev->DrawPolygon( tools::Polygon( aCenterPos, nRadX, nRadY ) );
2559  nRadX -= aBrd1Size.Width();
2560  nRadY -= aBrd1Size.Height();
2561  pDev->SetFillColor( COL_WHITE );
2562  pDev->DrawPolygon( tools::Polygon( aCenterPos, nRadX, nRadY ) );
2563  if ( mbChecked )
2564  {
2565  nRadX -= aBrd1Size.Width();
2566  nRadY -= aBrd1Size.Height();
2567  if ( !nRadX )
2568  nRadX = 1;
2569  if ( !nRadY )
2570  nRadY = 1;
2571  pDev->SetFillColor( COL_BLACK );
2572  pDev->DrawPolygon( tools::Polygon( aCenterPos, nRadX, nRadY ) );
2573  }
2574 
2575  pDev->Pop();
2576  }
2577  else
2578  {
2579  OSL_FAIL( "RadioButton::Draw() - not implemented for RadioButton with Image" );
2580  }
2581 }
2582 
2584 {
2585  Control::Resize();
2586  Invalidate();
2587 }
2588 
2590 {
2593  Button::GetFocus();
2594 }
2595 
2597 {
2599  {
2601  Invalidate();
2602  }
2603 
2604  HideFocus();
2606 }
2607 
2609 {
2610  Button::StateChanged( nType );
2611 
2612  if ( nType == StateChangedType::State )
2613  {
2614  if ( IsReallyVisible() && IsUpdateMode() )
2616  }
2617  else if ( (nType == StateChangedType::Enable) ||
2618  (nType == StateChangedType::Text) ||
2619  (nType == StateChangedType::Data) ||
2620  (nType == StateChangedType::UpdateMode) )
2621  {
2622  if ( IsUpdateMode() )
2623  Invalidate();
2624  }
2625  else if ( nType == StateChangedType::Style )
2626  {
2628 
2629  if ( (GetPrevStyle() & RADIOBUTTON_VIEW_STYLE) !=
2631  {
2632  if ( IsUpdateMode() )
2633  Invalidate();
2634  }
2635  }
2636  else if ( (nType == StateChangedType::Zoom) ||
2637  (nType == StateChangedType::ControlFont) )
2638  {
2639  ImplInitSettings( false );
2640  Invalidate();
2641  }
2642  else if ( nType == StateChangedType::ControlForeground )
2643  {
2644  ImplInitSettings( false );
2645  Invalidate();
2646  }
2647  else if ( nType == StateChangedType::ControlBackground )
2648  {
2649  ImplInitSettings( true );
2650  Invalidate();
2651  }
2652 }
2653 
2655 {
2656  Button::DataChanged( rDCEvt );
2657 
2658  if ( (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
2660  ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
2661  (rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
2662  {
2663  ImplInitSettings( true );
2664  Invalidate();
2665  }
2666 }
2667 
2669 {
2670  if( rNEvt.GetType() == MouseNotifyEvent::MOUSEMOVE )
2671  {
2672  const MouseEvent* pMouseEvt = rNEvt.GetMouseEvent();
2673  if( pMouseEvt && !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() )
2674  {
2675  // trigger redraw if mouse over state has changed
2677  {
2679  pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow())
2680  {
2682  }
2683  }
2684  }
2685  }
2686 
2687  return Button::PreNotify(rNEvt);
2688 }
2689 
2691 {
2693 }
2694 
2696 {
2697  if ( rImage != maImage )
2698  {
2699  maImage = rImage;
2701  queue_resize();
2702  }
2703 }
2704 
2705 
2706 void RadioButton::SetState( bool bCheck )
2707 {
2708  // carry the TabStop flag along correctly
2709  if ( bCheck )
2710  mpWindowImpl->mnStyle |= WB_TABSTOP;
2711  else
2712  mpWindowImpl->mnStyle &= ~WB_TABSTOP;
2713 
2714  if ( mbChecked != bCheck )
2715  {
2716  mbChecked = bCheck;
2718  Toggle();
2719  }
2720 }
2721 
2722 bool RadioButton::set_property(const OString &rKey, const OUString &rValue)
2723 {
2724  if (rKey == "active")
2725  SetState(toBool(rValue));
2726  else if (rKey == "image-position")
2727  {
2728  WinBits nBits = GetStyle();
2729  if (rValue == "left")
2730  {
2731  nBits &= ~(WB_CENTER | WB_RIGHT);
2732  nBits |= WB_LEFT;
2733  }
2734  else if (rValue == "right")
2735  {
2736  nBits &= ~(WB_CENTER | WB_LEFT);
2737  nBits |= WB_RIGHT;
2738  }
2739  else if (rValue == "top")
2740  {
2741  nBits &= ~(WB_VCENTER | WB_BOTTOM);
2742  nBits |= WB_TOP;
2743  }
2744  else if (rValue == "bottom")
2745  {
2746  nBits &= ~(WB_VCENTER | WB_TOP);
2747  nBits |= WB_BOTTOM;
2748  }
2749  //It's rather mad to have to set these bits when there is the other
2750  //image align. Looks like e.g. the radiobuttons etc weren't converted
2751  //over to image align fully.
2752  SetStyle(nBits);
2753  //Deliberate to set the sane ImageAlign property
2754  return Button::set_property(rKey, rValue);
2755  }
2756  else
2757  return Button::set_property(rKey, rValue);
2758  return true;
2759 }
2760 
2761 void RadioButton::Check( bool bCheck )
2762 {
2763  // TabStop-Flag richtig mitfuehren
2764  if ( bCheck )
2765  mpWindowImpl->mnStyle |= WB_TABSTOP;
2766  else
2767  mpWindowImpl->mnStyle &= ~WB_TABSTOP;
2768 
2769  if ( mbChecked == bCheck )
2770  return;
2771 
2772  mbChecked = bCheck;
2773  VclPtr<vcl::Window> xWindow = this;
2775  if ( xWindow->isDisposed() )
2776  return;
2777  if ( bCheck && mbRadioCheck )
2779  if ( xWindow->isDisposed() )
2780  return;
2781  Toggle();
2782 }
2783 
2785 {
2786  // 4 pixels, but take zoom into account, so the text doesn't "jump" relative to surrounding elements,
2787  // which might have been aligned with the text of the check box
2788  return CalcZoom( 4 );
2789 }
2790 
2792 {
2793  Size aSize;
2794  bool bDefaultSize = true;
2796  {
2797  ImplControlValue aControlValue;
2798  tools::Rectangle aCtrlRegion( Point( 0, 0 ), GetSizePixel() );
2799  tools::Rectangle aBoundingRgn, aContentRgn;
2800 
2801  // get native size of a radio button
2804  aControlValue,
2805  aBoundingRgn, aContentRgn ) )
2806  {
2807  aSize = aContentRgn.GetSize();
2808  bDefaultSize = false;
2809  }
2810  }
2811  if( bDefaultSize )
2813  return aSize;
2814 }
2815 
2816 static void LoadThemedImageList(const StyleSettings &rStyleSettings,
2817  std::vector<Image>& rList, const std::vector<OUString> &rResources)
2818 {
2819  Color aColorAry1[6];
2820  Color aColorAry2[6];
2821  aColorAry1[0] = Color( 0xC0, 0xC0, 0xC0 );
2822  aColorAry1[1] = Color( 0xFF, 0xFF, 0x00 );
2823  aColorAry1[2] = Color( 0xFF, 0xFF, 0xFF );
2824  aColorAry1[3] = Color( 0x80, 0x80, 0x80 );
2825  aColorAry1[4] = Color( 0x00, 0x00, 0x00 );
2826  aColorAry1[5] = Color( 0x00, 0xFF, 0x00 );
2827  aColorAry2[0] = rStyleSettings.GetFaceColor();
2828  aColorAry2[1] = rStyleSettings.GetWindowColor();
2829  aColorAry2[2] = rStyleSettings.GetLightColor();
2830  aColorAry2[3] = rStyleSettings.GetShadowColor();
2831  aColorAry2[4] = rStyleSettings.GetDarkShadowColor();
2832  aColorAry2[5] = rStyleSettings.GetWindowTextColor();
2833 
2834  static_assert( sizeof(aColorAry1) == sizeof(aColorAry2), "aColorAry1 must match aColorAry2" );
2835 
2836  for (const auto &a : rResources)
2837  {
2838  BitmapEx aBmpEx(a);
2839  aBmpEx.Replace(aColorAry1, aColorAry2, SAL_N_ELEMENTS(aColorAry1));
2840  rList.emplace_back(aBmpEx);
2841  }
2842 }
2843 
2845 {
2846  ImplSVData* pSVData = ImplGetSVData();
2847  const StyleSettings& rStyleSettings = rSettings.GetStyleSettings();
2848  sal_uInt16 nStyle = 0;
2849 
2850  if ( rStyleSettings.GetOptions() & StyleSettingsOptions::Mono )
2851  nStyle = STYLE_RADIOBUTTON_MONO;
2852 
2853  if ( pSVData->maCtrlData.maRadioImgList.empty() ||
2854  (pSVData->maCtrlData.mnRadioStyle != nStyle) ||
2855  (pSVData->maCtrlData.mnLastRadioFColor != rStyleSettings.GetFaceColor()) ||
2856  (pSVData->maCtrlData.mnLastRadioWColor != rStyleSettings.GetWindowColor()) ||
2857  (pSVData->maCtrlData.mnLastRadioLColor != rStyleSettings.GetLightColor()) )
2858  {
2859  pSVData->maCtrlData.maRadioImgList.clear();
2860 
2861  pSVData->maCtrlData.mnLastRadioFColor = rStyleSettings.GetFaceColor();
2862  pSVData->maCtrlData.mnLastRadioWColor = rStyleSettings.GetWindowColor();
2863  pSVData->maCtrlData.mnLastRadioLColor = rStyleSettings.GetLightColor();
2864 
2865  std::vector<OUString> aResources;
2866  if (nStyle)
2867  {
2868  aResources.emplace_back(SV_RESID_BITMAP_RADIOMONO1);
2869  aResources.emplace_back(SV_RESID_BITMAP_RADIOMONO2);
2870  aResources.emplace_back(SV_RESID_BITMAP_RADIOMONO3);
2871  aResources.emplace_back(SV_RESID_BITMAP_RADIOMONO4);
2872  aResources.emplace_back(SV_RESID_BITMAP_RADIOMONO5);
2873  aResources.emplace_back(SV_RESID_BITMAP_RADIOMONO6);
2874  }
2875  else
2876  {
2877  aResources.emplace_back(SV_RESID_BITMAP_RADIO1);
2878  aResources.emplace_back(SV_RESID_BITMAP_RADIO2);
2879  aResources.emplace_back(SV_RESID_BITMAP_RADIO3);
2880  aResources.emplace_back(SV_RESID_BITMAP_RADIO4);
2881  aResources.emplace_back(SV_RESID_BITMAP_RADIO5);
2882  aResources.emplace_back(SV_RESID_BITMAP_RADIO6);
2883  }
2884  LoadThemedImageList( rStyleSettings, pSVData->maCtrlData.maRadioImgList, aResources);
2885  pSVData->maCtrlData.mnRadioStyle = nStyle;
2886  }
2887 
2888  sal_uInt16 nIndex;
2889  if ( nFlags & DrawButtonFlags::Disabled )
2890  {
2891  if ( nFlags & DrawButtonFlags::Checked )
2892  nIndex = 5;
2893  else
2894  nIndex = 4;
2895  }
2896  else if ( nFlags & DrawButtonFlags::Pressed )
2897  {
2898  if ( nFlags & DrawButtonFlags::Checked )
2899  nIndex = 3;
2900  else
2901  nIndex = 2;
2902  }
2903  else
2904  {
2905  if ( nFlags & DrawButtonFlags::Checked )
2906  nIndex = 1;
2907  else
2908  nIndex = 0;
2909  }
2910  return pSVData->maCtrlData.maRadioImgList[nIndex];
2911 }
2912 
2914 {
2916  SetMapMode(MapMode(MapUnit::MapPixel));
2917 
2918  ImplControlValue aControlValue;
2919  Size aCurSize( GetSizePixel() );
2920  tools::Rectangle aCtrlRegion( Point( 0, 0 ), aCurSize );
2921  tools::Rectangle aBoundingRgn, aContentRgn;
2922 
2923  // get native size of a radiobutton
2926  aBoundingRgn, aContentRgn ) )
2927  {
2928  Size aSize = aContentRgn.GetSize();
2929 
2930  if( aSize.Height() > aCurSize.Height() )
2931  {
2932  aCurSize.setHeight( aSize.Height() );
2933  SetSizePixel( aCurSize );
2934  }
2935  }
2936 
2937  GetOutDev()->Pop();
2938 }
2939 
2941 {
2942  Size aSize;
2943  if ( !maImage )
2944  aSize = ImplGetRadioImageSize();
2945  else
2946  {
2947  aSize = maImage.GetSizePixel();
2948  aSize.AdjustWidth(8);
2949  aSize.AdjustHeight(8);
2950  }
2951 
2952  if (Button::HasImage())
2953  {
2954  Size aImgSize = GetModeImage().GetSizePixel();
2955  aSize = Size(std::max(aImgSize.Width(), aSize.Width()),
2956  std::max(aImgSize.Height(), aSize.Height()));
2957  }
2958 
2959  OUString aText = GetText();
2960  if (!aText.isEmpty())
2961  {
2962  bool bTopImage = (GetStyle() & WB_TOP) != 0;
2963 
2964  Size aTextSize = GetTextRect( tools::Rectangle( Point(), Size( nMaxWidth > 0 ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ),
2966 
2967  aSize.AdjustWidth(2 ); // for focus rect
2968 
2969  if (!bTopImage)
2970  {
2972  aSize.AdjustWidth(aTextSize.Width() );
2973  if ( aSize.Height() < aTextSize.Height() )
2974  aSize.setHeight( aTextSize.Height() );
2975  }
2976  else
2977  {
2978  aSize.AdjustHeight(6 );
2979  aSize.AdjustHeight(GetTextHeight() );
2980  if ( aSize.Width() < aTextSize.Width() )
2981  aSize.setWidth( aTextSize.Width() );
2982  }
2983  }
2984 
2985  return CalcWindowSize( aSize );
2986 }
2987 
2989 {
2990  return CalcMinimumSize();
2991 }
2992 
2994 {
2996  {
2997  ImplControlValue aControlValue;
2998  tools::Rectangle aInRect(Point(0, 0), GetSizePixel());
2999 
3000  aInRect.SetLeft( rRect.Left() ); // exclude the radio element itself from the focusrect
3001 
3003  ControlState::FOCUSED, aControlValue, OUString());
3004  }
3005  Button::ShowFocus(rRect);
3006 }
3007 
3009 {
3010  Button::DumpAsPropertyTree(rJsonWriter);
3011  rJsonWriter.put("checked", IsChecked());
3012 
3013  OUString sGroupId;
3014  std::vector<VclPtr<RadioButton>> aGroup = GetRadioButtonGroup();
3015  for(const auto& pButton : aGroup)
3016  sGroupId += pButton->get_id();
3017 
3018  if (!sGroupId.isEmpty())
3019  rJsonWriter.put("group", sGroupId);
3020 
3021  if (!!maImage)
3022  {
3023  SvMemoryStream aOStm(6535, 6535);
3025  {
3026  css::uno::Sequence<sal_Int8> aSeq( static_cast<sal_Int8 const *>(aOStm.GetData()), aOStm.Tell());
3027  OUStringBuffer aBuffer("data:image/png;base64,");
3029  rJsonWriter.put("image", aBuffer.makeStringAndClear());
3030  }
3031  }
3032 }
3033 
3035 {
3037 }
3038 
3040 {
3042  mbTriState = false;
3043 }
3044 
3045 void CheckBox::ImplInit( vcl::Window* pParent, WinBits nStyle )
3046 {
3047  nStyle = ImplInitStyle(getPreviousSibling(pParent), nStyle);
3048  Button::ImplInit( pParent, nStyle, nullptr );
3049 
3050  ImplInitSettings( true );
3051 }
3052 
3054 {
3055  if ( !(nStyle & WB_NOTABSTOP) )
3056  nStyle |= WB_TABSTOP;
3057  if ( !(nStyle & WB_NOGROUP) &&
3058  (!pPrevWindow || (pPrevWindow->GetType() != WindowType::CHECKBOX)) )
3059  nStyle |= WB_GROUP;
3060  return nStyle;
3061 }
3062 
3064 {
3065  return _rStyle.GetRadioCheckFont();
3066 }
3067 
3069 {
3070  return _rStyle.GetRadioCheckTextColor();
3071 }
3072 
3073 void CheckBox::ImplInitSettings( bool bBackground )
3074 {
3076 
3077  if ( !bBackground )
3078  return;
3079 
3080  vcl::Window* pParent = GetParent();
3081  if ( !IsControlBackground() &&
3083  {
3086  SetPaintTransparent( true );
3087  SetBackground();
3090  }
3091  else
3092  {
3093  EnableChildTransparentMode( false );
3095  SetPaintTransparent( false );
3096 
3097  if ( IsControlBackground() )
3099  else
3100  SetBackground( pParent->GetBackground() );
3101  }
3102 }
3103 
3105 {
3106  bool bNativeOK = rRenderContext.IsNativeControlSupported(ControlType::Checkbox, ControlPart::Entire);
3107  if (bNativeOK)
3108  {
3110  tools::Rectangle aCtrlRegion(maStateRect);
3112 
3113  if (HasFocus())
3114  nState |= ControlState::FOCUSED;
3116  nState |= ControlState::DEFAULT;
3118  nState |= ControlState::PRESSED;
3119  if (IsEnabled())
3120  nState |= ControlState::ENABLED;
3121 
3122  if (meState == TRISTATE_TRUE)
3123  aControlValue.setTristateVal(ButtonValue::On);
3124  else if (meState == TRISTATE_INDET)
3125  aControlValue.setTristateVal(ButtonValue::Mixed);
3126 
3128  nState |= ControlState::ROLLOVER;
3129 
3130  bNativeOK = rRenderContext.DrawNativeControl(ControlType::Checkbox, ControlPart::Entire, aCtrlRegion,
3131  nState, aControlValue, OUString());
3132  }
3133 
3134  if (bNativeOK)
3135  return;
3136 
3137  DrawButtonFlags nStyle = GetButtonState();
3138  if (!IsEnabled())
3139  nStyle |= DrawButtonFlags::Disabled;
3140  if (meState == TRISTATE_INDET)
3141  nStyle |= DrawButtonFlags::DontKnow;
3142  else if (meState == TRISTATE_TRUE)
3143  nStyle |= DrawButtonFlags::Checked;
3144  Image aImage = GetCheckImage(GetSettings(), nStyle);
3145  if (IsZoom())
3146  rRenderContext.DrawImage(maStateRect.TopLeft(), maStateRect.GetSize(), aImage);
3147  else
3148  rRenderContext.DrawImage(maStateRect.TopLeft(), aImage);
3149 }
3150 
3151 void CheckBox::ImplDraw( OutputDevice* pDev, SystemTextColorFlags nSystemTextColorFlags,
3152  const Point& rPos, const Size& rSize,
3153  const Size& rImageSize, tools::Rectangle& rStateRect,
3154  tools::Rectangle& rMouseRect )
3155 {
3156  WinBits nWinStyle = GetStyle();
3157  OUString aText( GetText() );
3158 
3160  pDev->IntersectClipRegion( tools::Rectangle( rPos, rSize ) );
3161 
3162  if (!aText.isEmpty() || HasImage())
3163  {
3164  Button::ImplDrawRadioCheck(pDev, nWinStyle, nSystemTextColorFlags,
3165  rPos, rSize, rImageSize,
3166  rStateRect, rMouseRect);
3167  }
3168  else
3169  {
3170  rStateRect.SetLeft( rPos.X() );
3171  if ( nWinStyle & WB_VCENTER )
3172  rStateRect.SetTop( rPos.Y()+((rSize.Height()-rImageSize.Height())/2) );
3173  else if ( nWinStyle & WB_BOTTOM )
3174  rStateRect.SetTop( rPos.Y()+rSize.Height()-rImageSize.Height() );
3175  else
3176  rStateRect.SetTop( rPos.Y() );
3177  rStateRect.SetRight( rStateRect.Left()+rImageSize.Width()-1 );
3178  rStateRect.SetBottom( rStateRect.Top()+rImageSize.Height()-1 );
3179  // provide space for focusrect
3180  // note: this assumes that the control's size was adjusted
3181  // accordingly in Get/LoseFocus, so the onscreen position won't change
3182  if( HasFocus() )
3183  rStateRect.Move( 1, 1 );
3184  rMouseRect = rStateRect;
3185 
3186  ImplSetFocusRect( rStateRect );
3187  }
3188 
3189  pDev->Pop();
3190 }
3191 
3193 {
3194  Size aImageSize = ImplGetCheckImageSize();
3195  aImageSize.setWidth( CalcZoom( aImageSize.Width() ) );
3196  aImageSize.setHeight( CalcZoom( aImageSize.Height() ) );
3197 
3198  HideFocus();
3199 
3201  aImageSize, maStateRect, maMouseRect);
3202 
3203  ImplDrawCheckBoxState(rRenderContext);
3204  if (HasFocus())
3206 }
3207 
3209 {
3210  TriState eNewState;
3211  if ( meState == TRISTATE_FALSE )
3212  eNewState = TRISTATE_TRUE;
3213  else if ( !mbTriState )
3214  eNewState = TRISTATE_FALSE;
3215  else if ( meState == TRISTATE_TRUE )
3216  eNewState = TRISTATE_INDET;
3217  else
3218  eNewState = TRISTATE_FALSE;
3219  meState = eNewState;
3220 
3221  VclPtr<vcl::Window> xWindow = this;
3222  Invalidate();
3223  Toggle();
3224  if ( xWindow->isDisposed() )
3225  return;
3226  Click();
3227 }
3228 
3231 {
3233  ImplInit( pParent, nStyle );
3234 }
3235 
3237 {
3238  if ( rMEvt.IsLeft() && maMouseRect.Contains( rMEvt.GetPosPixel() ) )
3239  {
3241  Invalidate();
3242  StartTracking();
3243  return;
3244  }
3245 
3246  Button::MouseButtonDown( rMEvt );
3247 }
3248 
3249 void CheckBox::Tracking( const TrackingEvent& rTEvt )
3250 {
3251  if ( rTEvt.IsTrackingEnded() )
3252  {
3254  {
3255  if ( !(GetStyle() & WB_NOPOINTERFOCUS) && !rTEvt.IsTrackingCanceled() )
3256  GrabFocus();
3257 
3259 
3260  // do not call click handler if aborted
3261  if ( !rTEvt.IsTrackingCanceled() )
3262  ImplCheck();
3263  else
3264  {
3265  Invalidate();
3266  }
3267  }
3268  }
3269  else
3270  {
3271  if ( maMouseRect.Contains( rTEvt.GetMouseEvent().GetPosPixel() ) )
3272  {
3274  {
3276  Invalidate();
3277  }
3278  }
3279  else
3280  {
3282  {
3284  Invalidate();
3285  }
3286  }
3287  }
3288 }
3289 
3290 void CheckBox::KeyInput( const KeyEvent& rKEvt )
3291 {
3292  vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
3293 
3294  if ( !aKeyCode.GetModifier() && (aKeyCode.GetCode() == KEY_SPACE) )
3295  {
3297  {
3299  Invalidate();
3300  }
3301  }
3302  else if ( (GetButtonState() & DrawButtonFlags::Pressed) && (aKeyCode.GetCode() == KEY_ESCAPE) )
3303  {
3305  Invalidate();
3306  }
3307  else
3308  Button::KeyInput( rKEvt );
3309 }
3310 
3311 void CheckBox::KeyUp( const KeyEvent& rKEvt )
3312 {
3313  vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
3314 
3315  if ( (GetButtonState() & DrawButtonFlags::Pressed) && (aKeyCode.GetCode() == KEY_SPACE) )
3316  {
3318  ImplCheck();
3319  }
3320  else
3321  Button::KeyUp( rKEvt );
3322 }
3323 
3325 {
3326  mxLayoutData.emplace();
3327  const_cast<CheckBox*>(this)->Invalidate();
3328 }
3329 
3331 {
3332  ImplDrawCheckBox(rRenderContext);
3333 }
3334 
3335 void CheckBox::Draw( OutputDevice* pDev, const Point& rPos,
3336  SystemTextColorFlags nFlags )
3337 {
3338  MapMode aResMapMode( MapUnit::Map100thMM );
3339  Point aPos = pDev->LogicToPixel( rPos );
3340  Size aSize = GetSizePixel();
3341  Size aImageSize = pDev->LogicToPixel( Size( 300, 300 ), aResMapMode );
3342  Size aBrd1Size = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode );
3343  Size aBrd2Size = pDev->LogicToPixel( Size( 30, 30 ), aResMapMode );
3344  tools::Long nCheckWidth = pDev->LogicToPixel( Size( 20, 20 ), aResMapMode ).Width();
3345  vcl::Font aFont = GetDrawPixelFont( pDev );
3346  tools::Rectangle aStateRect;
3347  tools::Rectangle aMouseRect;
3348 
3349  aImageSize.setWidth( CalcZoom( aImageSize.Width() ) );
3350  aImageSize.setHeight( CalcZoom( aImageSize.Height() ) );
3351  aBrd1Size.setWidth( CalcZoom( aBrd1Size.Width() ) );
3352  aBrd1Size.setHeight( CalcZoom( aBrd1Size.Height() ) );
3353  aBrd2Size.setWidth( CalcZoom( aBrd2Size.Width() ) );
3354  aBrd2Size.setHeight( CalcZoom( aBrd2Size.Height() ) );
3355 
3356  if ( !aBrd1Size.Width() )
3357  aBrd1Size.setWidth( 1 );
3358  if ( !aBrd1Size.Height() )
3359  aBrd1Size.setHeight( 1 );
3360  if ( !aBrd2Size.Width() )
3361  aBrd2Size.setWidth( 1 );
3362  if ( !aBrd2Size.Height() )
3363  aBrd2Size.setHeight( 1 );
3364  if ( !nCheckWidth )
3365  nCheckWidth = 1;
3366 
3367  pDev->Push();
3368  pDev->SetMapMode();
3369  pDev->SetFont( aFont );
3370  if ( nFlags & SystemTextColorFlags::Mono )
3371  pDev->SetTextColor( COL_BLACK );
3372  else
3373  pDev->SetTextColor( GetTextColor() );
3374  pDev->SetTextFillColor();
3375 
3376  ImplDraw( pDev, nFlags, aPos, aSize,
3377  aImageSize, aStateRect, aMouseRect );
3378 
3379  pDev->SetLineColor();
3380  pDev->SetFillColor( COL_BLACK );
3381  pDev->DrawRect( aStateRect );
3382  aStateRect.AdjustLeft(aBrd1Size.Width() );
3383  aStateRect.AdjustTop(aBrd1Size.Height() );
3384  aStateRect.AdjustRight( -(aBrd1Size.Width()) );
3385  aStateRect.AdjustBottom( -(aBrd1Size.Height()) );
3386  if ( meState == TRISTATE_INDET )
3387  pDev->SetFillColor( COL_LIGHTGRAY );
3388  else
3389  pDev->SetFillColor( COL_WHITE );
3390  pDev->DrawRect( aStateRect );
3391 
3392  if ( meState == TRISTATE_TRUE )
3393  {
3394  aStateRect.AdjustLeft(aBrd2Size.Width() );
3395  aStateRect.AdjustTop(aBrd2Size.Height() );
3396  aStateRect.AdjustRight( -(aBrd2Size.Width()) );
3397  aStateRect.AdjustBottom( -(aBrd2Size.Height()) );
3398  Point aPos11( aStateRect.TopLeft() );
3399  Point aPos12( aStateRect.BottomRight() );
3400  Point aPos21( aStateRect.TopRight() );
3401  Point aPos22( aStateRect.BottomLeft() );
3402  Point aTempPos11( aPos11 );
3403  Point aTempPos12( aPos12 );
3404  Point aTempPos21( aPos21 );
3405  Point aTempPos22( aPos22 );
3406  pDev->SetLineColor( COL_BLACK );
3407  tools::Long nDX = 0;
3408  for ( tools::Long i = 0; i < nCheckWidth; i++ )
3409  {
3410  if ( !(i % 2) )
3411  {
3412  aTempPos11.setX( aPos11.X()+nDX );
3413  aTempPos12.setX( aPos12.X()+nDX );
3414  aTempPos21.setX( aPos21.X()+nDX );
3415  aTempPos22.setX( aPos22.X()+nDX );
3416  }
3417  else
3418  {
3419  nDX++;
3420  aTempPos11.setX( aPos11.X()-nDX );
3421  aTempPos12.setX( aPos12.X()-nDX );
3422  aTempPos21.setX( aPos21.X()-nDX );
3423  aTempPos22.setX( aPos22.X()-nDX );
3424  }
3425  pDev->DrawLine( aTempPos11, aTempPos12 );
3426  pDev->DrawLine( aTempPos21, aTempPos22 );
3427  }
3428  }
3429 
3430  pDev->Pop();
3431 }
3432 
3434 {
3435  Control::Resize();
3436  Invalidate();
3437 }
3438 
3440 {
3441  if (GetText().isEmpty())
3442  {
3443  // increase button size to have space for focus rect
3444  // checkboxes without text will draw focusrect around the check
3445  // See CheckBox::ImplDraw()
3446  Point aPos( GetPosPixel() );
3447  Size aSize( GetSizePixel() );
3448  aPos.Move(-1,-1);
3449  aSize.AdjustHeight(2 );
3450  aSize.AdjustWidth(2 );
3451  setPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height() );
3452  Invalidate();
3453  // Trigger drawing to initialize the mouse rectangle, otherwise the mouse button down
3454  // handler would ignore the mouse event.
3455  PaintImmediately();
3456  }
3457  else
3459 
3461  Button::GetFocus();
3462 }
3463 
3465 {
3467  {
3469  Invalidate();
3470  }
3471 
3472  HideFocus();
3474 
3475  if (GetText().isEmpty())
3476  {
3477  // decrease button size again (see GetFocus())
3478  // checkboxes without text will draw focusrect around the check
3479  Point aPos( GetPosPixel() );
3480  Size aSize( GetSizePixel() );
3481  aPos.Move(1,1);
3482  aSize.AdjustHeight( -2 );
3483  aSize.AdjustWidth( -2 );
3484  setPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height() );
3485  Invalidate();
3486  }
3487 }
3488 
3490 {
3491  Button::StateChanged( nType );
3492 
3493  if ( nType == StateChangedType::State )
3494  {
3495  if ( IsReallyVisible() && IsUpdateMode() )
3497  }
3498  else if ( (nType == StateChangedType::Enable) ||
3499  (nType == StateChangedType::Text) ||
3500  (nType == StateChangedType::Data) ||
3501  (nType == StateChangedType::UpdateMode) )
3502  {
3503  if ( IsUpdateMode() )
3504  Invalidate();
3505  }
3506  else if ( nType == StateChangedType::Style )
3507  {
3509 
3510  if ( (GetPrevStyle() & CHECKBOX_VIEW_STYLE) !=
3512  {
3513  if ( IsUpdateMode() )
3514  Invalidate();
3515  }
3516  }
3517  else if ( (nType == StateChangedType::Zoom) ||
3518  (nType == StateChangedType::ControlFont) )
3519  {
3520  ImplInitSettings( false );
3521  Invalidate();
3522  }
3523  else if ( nType == StateChangedType::ControlForeground )
3524  {
3525  ImplInitSettings( false );
3526  Invalidate();
3527  }
3528  else if ( nType == StateChangedType::ControlBackground )
3529  {
3530  ImplInitSettings( true );
3531  Invalidate();
3532  }
3533 }
3534 
3536 {
3537  Button::DataChanged( rDCEvt );
3538 
3539  if ( (rDCEvt.GetType() == DataChangedEventType::FONTS) ||
3541  ((rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
3542  (rDCEvt.GetFlags() & AllSettingsFlags::STYLE)) )
3543  {
3544  ImplInitSettings( true );
3545  Invalidate();
3546  }
3547 }
3548 
3550 {
3551  if( rNEvt.GetType() == MouseNotifyEvent::MOUSEMOVE )
3552  {
3553  const MouseEvent* pMouseEvt = rNEvt.GetMouseEvent();
3554  if( pMouseEvt && !pMouseEvt->GetButtons() && !pMouseEvt->IsSynthetic() && !pMouseEvt->IsModifierChanged() )
3555  {
3556  // trigger redraw if mouse over state has changed
3558  {
3560  pMouseEvt->IsLeaveWindow() || pMouseEvt->IsEnterWindow())
3561  {
3563  }
3564  }
3565  }
3566  }
3567 
3568  return Button::PreNotify(rNEvt);
3569 }
3570 
3572 {
3574 }
3575 
3577 {
3578  if ( !mbTriState && (eState == TRISTATE_INDET) )
3579  eState = TRISTATE_FALSE;
3580 
3581  if ( meState != eState )
3582  {
3583  meState = eState;
3585  Toggle();
3586  }
3587 }
3588 
3589 bool CheckBox::set_property(const OString &rKey, const OUString &rValue)
3590 {
3591  if (rKey == "active")
3593  else
3594  return Button::set_property(rKey, rValue);
3595  return true;
3596 }
3597 
3598 void CheckBox::EnableTriState( bool bTriState )
3599 {
3600  if ( mbTriState != bTriState )
3601  {
3602  mbTriState = bTriState;
3603 
3604  if ( !bTriState && (meState == TRISTATE_INDET) )
3606  }
3607 }
3608 
3610 {
3611  Size aSize;
3612  bool bDefaultSize = true;
3614  {
3615  ImplControlValue aControlValue;
3616  tools::Rectangle aCtrlRegion( Point( 0, 0 ), GetSizePixel() );
3617  tools::Rectangle aBoundingRgn, aContentRgn;
3618 
3619  // get native size of a check box
3622  aControlValue,
3623  aBoundingRgn, aContentRgn ) )
3624  {
3625  aSize = aContentRgn.GetSize();
3626  bDefaultSize = false;
3627  }
3628  }
3629  if( bDefaultSize )
3631  return aSize;
3632 }
3633 
3635 {
3636  ImplSVData* pSVData = ImplGetSVData();
3637  const StyleSettings& rStyleSettings = rSettings.GetStyleSettings();
3638  sal_uInt16 nStyle = 0;
3639 
3640  if ( rStyleSettings.GetOptions() & StyleSettingsOptions::Mono )
3641  nStyle = STYLE_CHECKBOX_MONO;
3642 
3643  if ( pSVData->maCtrlData.maCheckImgList.empty() ||
3644  (pSVData->maCtrlData.mnCheckStyle != nStyle) ||
3645  (pSVData->maCtrlData.mnLastCheckFColor != rStyleSettings.GetFaceColor()) ||
3646  (pSVData->maCtrlData.mnLastCheckWColor != rStyleSettings.GetWindowColor()) ||
3647  (pSVData->maCtrlData.mnLastCheckLColor != rStyleSettings.GetLightColor()) )
3648  {
3649  pSVData->maCtrlData.maCheckImgList.clear();
3650 
3651  pSVData->maCtrlData.mnLastCheckFColor = rStyleSettings.GetFaceColor();
3652  pSVData->maCtrlData.mnLastCheckWColor = rStyleSettings.GetWindowColor();
3653  pSVData->maCtrlData.mnLastCheckLColor = rStyleSettings.GetLightColor();
3654 
3655  std::vector<OUString> aResources;
3656  if (nStyle)
3657  {
3658  aResources.emplace_back(SV_RESID_BITMAP_CHECKMONO1);
3659  aResources.emplace_back(SV_RESID_BITMAP_CHECKMONO2);
3660  aResources.emplace_back(SV_RESID_BITMAP_CHECKMONO3);
3661  aResources.emplace_back(SV_RESID_BITMAP_CHECKMONO4);
3662  aResources.emplace_back(SV_RESID_BITMAP_CHECKMONO5);
3663  aResources.emplace_back(SV_RESID_BITMAP_CHECKMONO6);
3664  aResources.emplace_back(SV_RESID_BITMAP_CHECKMONO7);
3665  aResources.emplace_back(SV_RESID_BITMAP_CHECKMONO8);
3666  aResources.emplace_back(SV_RESID_BITMAP_CHECKMONO9);
3667  }
3668  else
3669  {
3670  aResources.emplace_back(SV_RESID_BITMAP_CHECK1);
3671  aResources.emplace_back(SV_RESID_BITMAP_CHECK2);
3672  aResources.emplace_back(SV_RESID_BITMAP_CHECK3);
3673  aResources.emplace_back(SV_RESID_BITMAP_CHECK4);
3674  aResources.emplace_back(SV_RESID_BITMAP_CHECK5);
3675  aResources.emplace_back(SV_RESID_BITMAP_CHECK6);
3676  aResources.emplace_back(SV_RESID_BITMAP_CHECK7);
3677  aResources.emplace_back(SV_RESID_BITMAP_CHECK8);
3678  aResources.emplace_back(SV_RESID_BITMAP_CHECK9);
3679  }
3680  LoadThemedImageList(rStyleSettings, pSVData->maCtrlData.maCheckImgList, aResources);
3681  pSVData->maCtrlData.mnCheckStyle = nStyle;
3682  }
3683 
3684  sal_uInt16 nIndex;
3685  if ( nFlags & DrawButtonFlags::Disabled )
3686  {
3687  if ( nFlags & DrawButtonFlags::DontKnow )
3688  nIndex = 8;
3689  else if ( nFlags & DrawButtonFlags::Checked )
3690  nIndex = 5;
3691  else
3692  nIndex = 4;
3693  }
3694  else if ( nFlags & DrawButtonFlags::Pressed )
3695  {
3696  if ( nFlags & DrawButtonFlags::DontKnow )
3697  nIndex = 7;
3698  else if ( nFlags & DrawButtonFlags::Checked )
3699  nIndex = 3;
3700  else
3701  nIndex = 2;
3702  }
3703  else
3704  {
3705  if ( nFlags & DrawButtonFlags::DontKnow )
3706  nIndex = 6;
3707  else if ( nFlags & DrawButtonFlags::Checked )
3708  nIndex = 1;
3709  else
3710  nIndex = 0;
3711  }
3712  return pSVData->maCtrlData.maCheckImgList[nIndex];
3713 }
3714 
3716 {
3718  SetMapMode(MapMode(MapUnit::MapPixel));
3719 
3720  ImplControlValue aControlValue;
3721  Size aCurSize( GetSizePixel() );
3722  tools::Rectangle aCtrlRegion( Point( 0, 0 ), aCurSize );
3723  tools::Rectangle aBoundingRgn, aContentRgn;
3724 
3725  // get native size of a radiobutton
3728  aBoundingRgn, aContentRgn ) )
3729  {
3730  Size aSize = aContentRgn.GetSize();
3731 
3732  if( aSize.Height() > aCurSize.Height() )
3733  {
3734  aCurSize.setHeight( aSize.Height() );
3735  SetSizePixel( aCurSize );
3736  }
3737  }
3738 
3739  GetOutDev()->Pop();
3740 }
3741 
3743 {
3744  Size aSize = ImplGetCheckImageSize();
3745  nMaxWidth -= aSize.Width();
3746 
3747  OUString aText = GetText();
3748  if (!aText.isEmpty())
3749  {
3750  // subtract what will be added later
3751  nMaxWidth-=2;
3752  nMaxWidth -= ImplGetImageToTextDistance();
3753 
3754  Size aTextSize = GetTextRect( tools::Rectangle( Point(), Size( nMaxWidth > 0 ? nMaxWidth : 0x7fffffff, 0x7fffffff ) ),
3756  aSize.AdjustWidth(2 ); // for focus rect
3758  aSize.AdjustWidth(aTextSize.Width() );
3759  if ( aSize.Height() < aTextSize.Height() )
3760  aSize.setHeight( aTextSize.Height() );
3761  }
3762  else
3763  {
3764  // is this still correct ? since the checkbox now
3765  // shows a focus rect it should be 2 pixels wider and longer
3766 /* since otherwise the controls in the Writer hang too far up
3767  aSize.Width() += 2;
3768  aSize.Height() += 2;
3769 */
3770  }
3771 
3772  return CalcWindowSize( aSize );
3773 }
3774 
3776 {
3777  int nWidthRequest(get_width_request());
3778  return CalcMinimumSize(nWidthRequest != -1 ? nWidthRequest : 0);
3779 }
3780 
3782 {
3784  {
3785  ImplControlValue aControlValue;
3786  tools::Rectangle aInRect(Point(0, 0), GetSizePixel());
3787 
3788  aInRect.SetLeft( rRect.Left() ); // exclude the checkbox itself from the focusrect
3789 
3791  ControlState::FOCUSED, aControlValue, OUString());
3792  }
3793  Button::ShowFocus(rRect);
3794 }
3795 
3797 {
3798  Button::DumpAsPropertyTree(rJsonWriter);
3799  rJsonWriter.put("checked", IsChecked());
3800 }
3801 
3803 {
3804  return CheckBoxUIObject::create;
3805 }
3806 
3808  PushButton( pParent, nStyle )
3809 {
3810  ImplInitStyle();
3811 }
3812 
3814 {
3815  WinBits nStyle = GetStyle();
3816 
3817  if ( ! ( nStyle & ( WB_RIGHT | WB_LEFT ) ) )
3818  nStyle |= WB_CENTER;
3819 
3820  if ( ! ( nStyle & ( WB_TOP | WB_BOTTOM ) ) )
3821  nStyle |= WB_VCENTER;
3822 
3823  SetStyle( nStyle );
3824 }
3825 
3826 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static bool toBool(std::string_view rValue)
Definition: builder.cxx:90
virtual Point GetPosPixel() const
Definition: window.cxx:2797
BitmapEx GetBitmapEx(BitmapEx const &rBitmapEx, DrawModeFlags nDrawMode)
Definition: drawmode.cxx:224
std::shared_ptr< std::vector< VclPtr< RadioButton > > > m_xGroup
Definition: button.hxx:379
virtual void Resize() override
Definition: button.cxx:2583
bool mbIsAction
Definition: button.hxx:220
virtual const vcl::Font & GetCanonicalFont(const StyleSettings &_rStyle) const override
Definition: button.cxx:708
virtual void FillLayoutData() const override
Definition: button.cxx:1390
virtual void DataChanged(const DataChangedEvent &rDCEvt) override
Definition: button.cxx:3535
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:1110
static std::unique_ptr< UIObject > create(vcl::Window *pWindow)
SAL_DLLPRIVATE tools::Long ImplGetImageToTextDistance() const
Definition: button.cxx:2784
SAL_DLLPRIVATE void ImplInitCheckBoxData()
Definition: button.cxx:3039
void Toggle()
Definition: button.cxx:3571
Color mnLastRadioLColor
Definition: svdata.hxx:290
void SetBackground()
Definition: window3.cxx:100
TriState meState
Definition: button.hxx:218
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:1657
bool ImplCallEventListenersAndHandler(VclEventId nEvent, std::function< void()> const &callHandler)
this calls both our event listeners, and a specified handler
Definition: ctrl.cxx:301
CheckBox(const CheckBox &)=delete
Point GetPointerPosPixel()
Definition: mouse.cxx:564
void EndSelection()
Definition: button.cxx:1673
SAL_DLLPRIVATE void ImplDrawPushButtonContent(OutputDevice *pDev, SystemTextColorFlags nSystemTextColorFlags, const tools::Rectangle &rRect, bool bMenuBtnSep, DrawButtonFlags nButtonFlags)
Definition: button.cxx:835
void HideFocus()
Definition: window2.cxx:94
sal_Int32 nIndex
DrawButtonFlags mnButtonState
Definition: button.cxx:82
bool mbIsActive
Definition: button.hxx:186
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:286
virtual void StateChanged(StateChangedType nType) override
Definition: button.cxx:3489
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:3775
const Color & GetActionButtonTextColor() const
static Image GetRadioImage(const AllSettings &rSettings, DrawButtonFlags nFlags)
Definition: button.cxx:2844
tools::Long AdjustRight(tools::Long nHorzMoveDelta)
virtual bool Close() override
Definition: dialog.cxx:843
sal_uInt16 mnCheckStyle
Definition: svdata.hxx:283
SAL_DLLPRIVATE void ImplSetFocusRect(const tools::Rectangle &rFocusRect)
Definition: button.cxx:484
void SetModeRadioImage(const Image &rImage)
Definition: button.cxx:2695
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:2255
void SetClickHdl(const Link< Button *, void > &rLink)
Definition: button.hxx:79
tools::Rectangle maStateRect
Definition: button.hxx:291
ImageAlign
virtual void MouseButtonDown(const MouseEvent &rMEvt)
Definition: mouse.cxx:420
#define STYLE_RADIOBUTTON_MONO
Definition: button.cxx:72
StartTrackingFlags
Definition: window.hxx:263
virtual void KeyInput(const KeyEvent &rKEvt) override
Definition: button.cxx:1333
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:1175
tools::Long getWidth() const
void Check(bool bCheck=true)
Definition: button.hxx:223
SymbolAlign
virtual void Click() override
Definition: button.cxx:1782
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:1112
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:3053
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:380
virtual void DataChanged(const DataChangedEvent &rDCEvt) override
Definition: button.cxx:1530
const Color & GetDefaultButtonTextColor() const
long Long
Link< CheckBox &, void > maToggleHdl
Definition: button.hxx:295
virtual void FillLayoutData() const override
Definition: button.cxx:3324
virtual void LoseFocus() override
Definition: button.cxx:2596
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
Gets the application's settings.
Definition: svapp.cxx:760
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:3151
sal_uInt8 GetLuminance() const
const Color & GetFaceColor() const
const vcl::Font & GetRadioCheckFont() const
virtual void StateChanged(StateChangedType nStateChange) override
Definition: ctrl.cxx:256
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:195
ImplSVNWFData maNWFData
Definition: svdata.hxx:404
void Toggle()
Definition: button.cxx:2690
const OUString & GetQuickHelpText() const
Definition: window2.cxx:1255
void DrawPolygon(const tools::Polygon &rPoly)
Render the given polygon.
Definition: polygon.cxx:156
const Color & GetDefaultButtonPressedRolloverTextColor() const
bool mbRadioCheck
Definition: button.hxx:384
std::function< std::unique_ptr< UIObject >vcl::Window *)> FactoryFunction
virtual Size GetSizePixel() const
Definition: window.cxx:2405
virtual void SetSizePixel(const Size &rNewSize)
Definition: window2.cxx:1285
WinBits const WB_RIGHT
virtual void KeyUp(const KeyEvent &rKEvt) override
Definition: button.cxx:2485
SAL_DLLPRIVATE WindowImpl * ImplGetWindowImpl() const
Definition: window.hxx:527
void SetState(bool bCheck)
Definition: button.cxx:2706
SAL_DLLPRIVATE void CompatStateChanged(StateChangedType nStateChange)
Definition: window.cxx:3898
SAL_DLLPRIVATE void ImplCallClick(bool bGrabFocus=false, GetFocusFlags nFocusFlags=GetFocusFlags::NONE)
Definition: button.cxx:2361
PushButtonDropdownStyle
Definition: button.hxx:116
bool mbNoFocusRectsForFlatButtons
Definition: svdata.hxx:329
tools::Rectangle maMouseRect
Definition: button.hxx:292
void SetTextFillColor()
Definition: text.cxx:732
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: button.cxx:1740
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:981
DataChangedEventType GetType() const
Definition: event.hxx:362
virtual Size GetOptimalSize() const override
Definition: button.cxx:1735
void IntersectClipRegion(const tools::Rectangle &rRect)
DrawButtonFlags
Definition: decoview.hxx:53
SAL_DLLPRIVATE void ImplDrawRadioButtonState(vcl::RenderContext &rRenderContext)
Definition: button.cxx:1978
#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:428
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:1913
const Color & GetControlBackground() const
Definition: window2.cxx:1105
void SetState(TriState eState)
Definition: button.cxx:3576
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:1755
virtual void Tracking(const TrackingEvent &rTEvt) override
Definition: button.cxx:1270
void PaintImmediately()
Definition: paint.cxx:1268
SAL_DLLPRIVATE Size ImplGetRadioImageSize() const
Definition: button.cxx:2791
void SetQuickHelpText(const OUString &rHelpText)
Definition: window2.cxx:1249
TRISTATE_TRUE
void StartTracking(StartTrackingFlags nFlags=StartTrackingFlags::NONE)
Definition: window2.cxx:251
bool IsNativeControlSupported(ControlType nType, ControlPart nPart) const
Query the platform layer for control support.
void SetMapMode()
Definition: map.cxx:649
DrawTextFlags
ImplSVCtrlData maCtrlData
Definition: svdata.hxx:402
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:1625
IMPL_STATIC_LINK(Button, dispatchCommandHandler, Button *, pButton, void)
Definition: button.cxx:648
SAL_DLLPRIVATE void ImplInit(vcl::Window *pParent, WinBits nStyle)
Definition: button.cxx:676
NONE
SAL_DLLPRIVATE void ImplDrawRadioButton(vcl::RenderContext &rRenderContext)
Definition: button.cxx:2232
bool IsTrackingRepeat() const
Definition: event.hxx:259
The invalidated area is painted with the background color/pattern.
void SetSymbolAlign(SymbolAlign eAlign)
Definition: button.cxx:1620
tools::Rectangle GetControlTextRect(OutputDevice &_rTargetDevice, const tools::Rectangle &rRect, const OUString &_rStr, DrawTextFlags _nStyle, Size *o_pDeviceSize=nullptr) const
Definition: ctrl.cxx:453
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:3008
virtual void KeyInput(const KeyEvent &rKEvt) override
Definition: button.cxx:3290
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:3589
SAL_DLLPRIVATE WinBits ImplInitStyle(const vcl::Window *pPrevWindow, WinBits nStyle) const
Definition: button.cxx:1921
sal_Int64 WinBits
Size CalcMinimumSize() const
Definition: button.cxx:1685
WinBits const WB_BOTTOM
WinBits const WB_TOP
bool mbTriState
Definition: button.hxx:294
void Enable(bool bEnable=true, bool bChild=true)
Definition: window.cxx:2436
const Color & GetDefaultButtonRolloverTextColor() const
sal_uInt16 GetButtons() const
Definition: event.hxx:147
void SetSymbol(SymbolType eSymbol)
Definition: button.cxx:1611
virtual void DumpAsPropertyTree(tools::JsonWriter &)
Dumps itself and potentially its children to a property tree, to be written easily to JSON...
Definition: window.cxx:3364
virtual void Draw(OutputDevice *pDev, const Point &rPos, SystemTextColorFlags nFlags) override
Definition: button.cxx:2509
WinBits const WB_DEFBUTTON
SymbolType
Definition: vclenum.hxx:73
Link< RadioButton &, void > maToggleHdl
Definition: button.hxx:387
PushButton(vcl::Window *pParent, WinBits nStyle=0)
Definition: button.cxx:1243
virtual void GetFocus() override
Definition: button.cxx:3439
void ImplAdjustNWFSizes() override
Definition: button.cxx:3715
bool IsControlForeground() const
Definition: window2.cxx:1100
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:292
Image maImage
Definition: button.hxx:382
virtual const Color & GetCanonicalTextColor(const StyleSettings &_rStyle) const override
Definition: button.cxx:3068
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:455
AllSettingsFlags GetFlags() const
Definition: event.hxx:363
virtual void StateChanged(StateChangedType nStateChange) override
Definition: button.cxx:1896
const Color & GetLightColor() const
Image maCustomContentImage
Definition: button.cxx:90
virtual void GetFocus() override
Definition: button.cxx:1469
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:1350
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:2325
virtual OUString GetText() const
Definition: window.cxx:3061
static Image GetCheckImage(const AllSettings &rSettings, DrawButtonFlags nFlags)
Definition: button.cxx:3634
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:1906
Definition: edit.hxx:55
void IncreaseLuminance(sal_uInt8 cLumInc)
SymbolType meSymbol
Definition: button.hxx:217
Size CalcMinimumSize(tools::Long nMaxWidth=0) const
Definition: button.cxx:2940
virtual void LoseFocus() override
Definition: button.cxx:1476
PushButtonDropdownStyle mnDDStyle
Definition: button.hxx:185
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:2095
TRISTATE_INDET
bool IsChildTransparentModeEnabled() const
Definition: window2.cxx:1050
SAL_DLLPRIVATE void ImplCheck()
Definition: button.cxx:3208
void DrawRect(const tools::Rectangle &rRect)
Definition: rect.cxx:51
SAL_DLLPRIVATE DrawTextFlags ImplGetTextStyle(SystemTextColorFlags nSystemTextColorFlags) const
Definition: button.cxx:800
GetFocusFlags
Definition: window.hxx:311
virtual bool PreNotify(NotifyEvent &rNEvt) override
Definition: button.cxx:3549
constexpr bool IsEmpty() const
const Color & GetControlForeground() const
Definition: window2.cxx:1095
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:2816
virtual void MouseButtonDown(const MouseEvent &rMEvt) override
Definition: button.cxx:2410
WinBits const WB_NOLIGHTBORDER
const Color & GetDarkShadowColor() const
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:76
virtual bool PreNotify(NotifyEvent &rNEvt) override
Definition: button.cxx:2668
Size CalcWindowSize(const Size &rOutSz) const
Definition: window2.cxx:560
const Color & GetActionButtonRolloverTextColor() const
const vcl::Font & GetPushButtonFont() const
virtual void Click() override
Definition: button.cxx:1881
void SetLineColor()
Definition: line.cxx:36
virtual void ShowFocus(const tools::Rectangle &rRect) override
Definition: button.cxx:3781
virtual bool PreNotify(NotifyEvent &rNEvt)
Definition: event.cxx:52
void SetInputContext(const InputContext &rInputContext)
Definition: window.cxx:2079
void DecreaseLuminance(sal_uInt8 cLumDec)
bool IsLeaveWindow() const
Definition: event.hxx:140
const Color & GetActionButtonPressedRolloverTextColor() const
void Check(bool bCheck=true)
Definition: button.cxx:2761
int i
uno_Any a
bool IsChecked() const
Definition: button.hxx:228
virtual bool PreNotify(NotifyEvent &rNEvt) override
Definition: button.cxx:1544
SAL_DLLPRIVATE void ImplInit(vcl::Window *pParent, WinBits nStyle)
Definition: button.cxx:1815
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
Definition: button.cxx:2399
bool IsSystemWindow() const
Definition: window2.cxx:1020
constexpr auto CHECKBOX_VIEW_STYLE
Definition: button.cxx:67
virtual void Tracking(const TrackingEvent &rTEvt) override
Definition: button.cxx:3249
virtual void SetText(const OUString &rStr) override
Definition: ctrl.cxx:95
tools::Long mnSeparatorX
Definition: button.cxx:81
virtual void Resize() override
Definition: button.cxx:1463
std::unique_ptr< ImplCommonButtonData > mpButtonData
Definition: button.hxx:43
sal_uInt16 mnRadioStyle
Definition: svdata.hxx:284
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:3609
void EnableTriState(bool bTriState=true)
Definition: button.cxx:3598
CancelButton(const CancelButton &)=delete
void DumpAsPropertyTree(tools::JsonWriter &) override
Dumps itself and potentially its children to a property tree, to be written easily to JSON...
Definition: button.cxx:641
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:2151
bool IsUpdateMode() const
Definition: window2.cxx:1196
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:2295
bool IsChecked() const
Definition: button.hxx:350
virtual FactoryFunction GetUITestFactory() const override
Definition: button.cxx:3034
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:1025
void SetTextColor(const Color &rColor)
Definition: text.cxx:714
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:1937
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:2988
bool IsZoom() const
Definition: window2.cxx:1238
WinBits const WB_RECTSTYLE
constexpr tools::Long Top() const
void SetPosY(tools::Long y)
virtual void KeyInput(const KeyEvent &rKEvt) override
Definition: button.cxx:2464
virtual void KeyUp(const KeyEvent &rKEvt) override
Definition: button.cxx:3311
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:58
const AllSettings & GetSettings() const
Definition: outdev.hxx:295
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:1407
TriState meState
Definition: button.hxx:293
bool IsInExecute() const
Definition: dialog.hxx:124
virtual bool set_property(const OString &rKey, const OUString &rValue)
Definition: window2.cxx:1468
static SAL_DLLPRIVATE WinBits ImplInitStyle(const vcl::Window *pPrevWindow, WinBits nStyle)
Definition: button.cxx:687
virtual void LoseFocus()
Definition: window.cxx:1858
Button(const Button &)=delete
void DumpAsPropertyTree(tools::JsonWriter &) override
Button has additional stuff that we need to dump too.
Definition: button.cxx:3796
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:2181
virtual const Color & GetCanonicalTextColor(const StyleSettings &_rStyle) const override
Definition: button.cxx:713
Point ScreenToOutputPixel(const Point &rPos) const
Definition: window.cxx:2815
void GrabFocus()
Definition: window.cxx:2982
bool mbUsesExplicitGroup
Definition: button.hxx:386
virtual void ShowFocus(const tools::Rectangle &rRect)
Definition: window2.cxx:52
vcl::Window * GetParent() const
Definition: window2.cxx:1120
virtual void FillLayoutData() const override
Definition: button.cxx:2498
WinBits const WB_LEFT
const Color & GetDefaultActionButtonPressedRolloverTextColor() const
virtual void GetFocus() override
Definition: button.cxx:2589
void Toggle()
Definition: button.cxx:1606
SAL_DLLPRIVATE void ImplDrawPushButton(vcl::RenderContext &rRenderContext)
Definition: button.cxx:965
constexpr void SetTop(tools::Long v)
bool IsTrackingEnded() const
Definition: event.hxx:261
void SetStyle(WinBits nStyle)
Definition: window.cxx:1965
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:3236
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:3335
constexpr sal_uInt16 KEY_RETURN
Definition: keycodes.hxx:119
SAL_DLLPRIVATE void ImplInitPushButtonData()
Definition: button.cxx:656
const Color & GetButtonRolloverTextColor() const
SAL_DLLPRIVATE void ImplInitStyle()
Definition: button.cxx:3813
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:2608
SAL_WARN_UNUSED_RESULT Point LogicToPixel(const Point &rLogicPt) const
Definition: map.cxx:933
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:2669
virtual void KeyInput(const KeyEvent &rKEvt)
Definition: window.cxx:1808
SAL_DLLPRIVATE void ImplInit(vcl::Window *pParent, WinBits nStyle, SystemParentData *pSystemParentData)
Definition: window.cxx:941
WinBits const WB_3DLOOK