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 #pragma once
21
22 #if !defined(VCL_DLLIMPLEMENTATION) && !defined(TOOLKIT_DLLIMPLEMENTATION) && !defined(VCL_INTERNALS)
23 #error "don't use this in new code"
24 #endif
25
26 #include <vcl/dllapi.h>
27 #include <vcl/image.hxx>
28 #include <vcl/ctrl.hxx>
29 #include <vcl/vclenum.hxx>
30 #include <memory>
31 #include <vector>
32
33 namespace com::sun::star::frame { struct FeatureStateEvent; }
34 template <class T> class VclPtr;
35
36 class Color;
37 class ImplCommonButtonData;
38 enum class DrawButtonFlags;
39
40 class VCL_DLLPUBLIC Button : public Control
41 {
42 private:
43 std::unique_ptr<ImplCommonButtonData> mpButtonData;
44 Link<Button*,void> maClickHdl;
45
46 /// Command URL (like .uno:Save) in case the button should handle it.
47 OUString maCommand;
48
49 Button (const Button &) = delete;
50 Button & operator= (const Button &) = delete;
51 public:
52 SAL_DLLPRIVATE DrawTextFlags ImplGetTextStyle( WinBits nWinStyle, DrawFlags nDrawFlags );
53 SAL_DLLPRIVATE void ImplDrawAlignedImage(OutputDevice* pDev, Point& rPos, Size& rSize,
54 sal_Int32 nImageSep,
55 DrawTextFlags nTextStyle, tools::Rectangle *pSymbolRect=nullptr, bool bAddImageSep = false );
56 SAL_DLLPRIVATE void ImplSetFocusRect( const tools::Rectangle &rFocusRect );
57 SAL_DLLPRIVATE const tools::Rectangle& ImplGetFocusRect() const;
58 SAL_DLLPRIVATE void ImplSetSymbolAlign( SymbolAlign eAlign );
59 /// The x-coordinate of the vertical separator line, use in MenuButton subclass only.
60 SAL_DLLPRIVATE tools::Long ImplGetSeparatorX() const;
61 SAL_DLLPRIVATE void ImplSetSeparatorX( tools::Long nX );
62
63 protected:
64 explicit Button( WindowType nType );
65
66 // for drawing RadioButton or CheckButton that has Text and/or Image
67 SAL_DLLPRIVATE void ImplDrawRadioCheck(OutputDevice* pDev, WinBits nWinStyle, DrawFlags nDrawFlags,
68 const Point& rPos, const Size& rSize,
69 const Size& rImageSize, tools::Rectangle& rStateRect,
70 tools::Rectangle& rMouseRect);
71 SAL_DLLPRIVATE tools::Long ImplGetImageToTextDistance() const;
72
73 public:
74 virtual ~Button() override;
75 virtual void dispose() override;
76
77 virtual void Click();
78
SetClickHdl(const Link<Button *,void> & rLink)79 void SetClickHdl( const Link<Button*,void>& rLink ) { maClickHdl = rLink; }
GetClickHdl() const80 const Link<Button*,void>& GetClickHdl() const { return maClickHdl; }
81
82 /// Setup handler for UNO commands so that commands like .uno:Something are handled automagically by this button.
83 void SetCommandHandler(const OUString& aCommand);
GetCommand() const84 OUString const & GetCommand() const { return maCommand; }
85
86 void SetModeImage( const Image& rImage );
87 Image const & GetModeImage( ) const;
88 bool HasImage() const;
89 void SetImageAlign( ImageAlign eAlign );
90 ImageAlign GetImageAlign() const;
91 DrawButtonFlags GetButtonState() const;
92 DrawButtonFlags& GetButtonState();
93
94 /// Set an image to use as the complete render view of a custom button,
95 /// instead of the usual contents of a button
96 void SetCustomButtonImage( const Image& rImage );
97 Image const & GetCustomButtonImage() const;
98
99 bool IsSmallSymbol() const;
100 void SetSmallSymbol();
101 virtual bool set_property(const OString &rKey, const OUString &rValue) override;
102
103 /// Sets the button state according to the FeatureStateEvent emitted by a Uno state change.
104 virtual void statusChanged(const css::frame::FeatureStateEvent& rEvent);
105
106 virtual FactoryFunction GetUITestFactory() const override;
107
108 virtual void DumpAsPropertyTree(tools::JsonWriter&) override;
109
110 protected:
111
112 /// Handler for click, in case we want the button to handle uno commands (.uno:Something).
113 DECL_STATIC_LINK(Button, dispatchCommandHandler, Button*, void);
114 };
115
116 enum class PushButtonDropdownStyle
117 {
118 NONE = 0x0000,
119 MenuButton = 0x0002, //visual down arrow
120 SplitMenuButton = 0x0003, //visual down arrow and separator line
121 };
122
123 class VCL_DLLPUBLIC PushButton : public Button
124 {
125 public:
126 SAL_DLLPRIVATE void ImplSetDefButton( bool bSet );
127 SAL_DLLPRIVATE void ImplDrawPushButtonFrame(vcl::RenderContext& rRenderContext, tools::Rectangle& rRect, DrawButtonFlags nStyle);
128 SAL_DLLPRIVATE static bool ImplHitTestPushButton(vcl::Window const * pDev, const Point& rPos);
129 SAL_DLLPRIVATE bool ImplIsDefButton() const;
130
131 explicit PushButton( vcl::Window* pParent, WinBits nStyle = 0 );
132
133 virtual void MouseButtonDown( const MouseEvent& rMEvt ) override;
134 virtual void Tracking( const TrackingEvent& rTEvt ) override;
135 virtual void KeyInput( const KeyEvent& rKEvt ) override;
136 virtual void KeyUp( const KeyEvent& rKEvt ) override;
137 virtual void Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) override;
138 virtual void Draw( OutputDevice* pDev, const Point& rPos, DrawFlags nFlags ) override;
139 virtual void Resize() override;
140 virtual void GetFocus() override;
141 virtual void LoseFocus() override;
142 virtual void StateChanged( StateChangedType nType ) override;
143 virtual void DataChanged( const DataChangedEvent& rDCEvt ) override;
144 virtual bool PreNotify( NotifyEvent& rNEvt ) override;
145
146 void Toggle();
147
148 void SetSymbol( SymbolType eSymbol );
GetSymbol() const149 SymbolType GetSymbol() const { return meSymbol; }
150 void SetSymbolAlign( SymbolAlign eAlign );
151
152 void SetDropDown( PushButtonDropdownStyle nStyle );
153
154 void SetState( TriState eState );
GetState() const155 TriState GetState() const { return meState; }
156 virtual void statusChanged(const css::frame::FeatureStateEvent& rEvent) override;
157
158 void Check( bool bCheck = true );
159 bool IsChecked() const;
160
161 void SetPressed( bool bPressed );
IsPressed() const162 bool IsPressed() const { return mbPressed; }
163
164 void EndSelection();
165
166 Size CalcMinimumSize() const;
167 virtual Size GetOptimalSize() const override;
168
169 virtual bool set_property(const OString &rKey, const OUString &rValue) override;
170 virtual void ShowFocus(const tools::Rectangle& rRect) override;
171
setAction(bool bIsAction)172 void setAction(bool bIsAction)
173 {
174 mbIsAction = bIsAction;
175 }
176
isAction() const177 bool isAction() const
178 {
179 return mbIsAction;
180 }
181
182 protected:
183 PushButtonDropdownStyle mnDDStyle;
184 bool mbIsActive;
185
186 SAL_DLLPRIVATE void ImplInitPushButtonData();
187 SAL_DLLPRIVATE static WinBits ImplInitStyle( const vcl::Window* pPrevWindow, WinBits nStyle );
188 SAL_DLLPRIVATE void ImplInitSettings( bool bBackground );
189 SAL_DLLPRIVATE void ImplDrawPushButtonContent(OutputDevice* pDev, DrawFlags nDrawFlags,
190 const tools::Rectangle& rRect, bool bMenuBtnSep,
191 DrawButtonFlags nButtonFlags);
192 SAL_DLLPRIVATE void ImplDrawPushButton(vcl::RenderContext& rRenderContext);
193 using Button::ImplGetTextStyle;
194 SAL_DLLPRIVATE DrawTextFlags ImplGetTextStyle( DrawFlags nDrawFlags ) const;
IsSymbol() const195 SAL_DLLPRIVATE bool IsSymbol() const { return ( (meSymbol != SymbolType::DONTKNOW) && (meSymbol != SymbolType::IMAGE) ); }
196
197 PushButton( const PushButton & ) = delete;
198 PushButton& operator=( const PushButton & )
199 = delete;
200
201 SAL_DLLPRIVATE void ImplInit( vcl::Window* pParent, WinBits nStyle );
202
203 using Control::ImplInitSettings;
204 using Window::ImplInit;
205
206 explicit PushButton( WindowType nType );
207
208 virtual void FillLayoutData() const override;
209 virtual const vcl::Font&
210 GetCanonicalFont( const StyleSettings& _rStyle ) const override;
211 virtual const Color&
212 GetCanonicalTextColor( const StyleSettings& _rStyle ) const override;
213
214 private:
215 SymbolType meSymbol;
216 TriState meState;
217 bool mbPressed;
218 bool mbIsAction;
219 };
220
Check(bool bCheck)221 inline void PushButton::Check( bool bCheck )
222 {
223 SetState( bCheck ? TRISTATE_TRUE : TRISTATE_FALSE );
224 }
225
IsChecked() const226 inline bool PushButton::IsChecked() const
227 {
228 return (GetState() == TRISTATE_TRUE);
229 }
230
231 class VCL_DLLPUBLIC OKButton final : public PushButton
232 {
233 private:
234 using PushButton::ImplInit;
235
236 SAL_DLLPRIVATE void ImplInit( vcl::Window* pParent, WinBits nStyle );
237
238 OKButton (const OKButton &) = delete;
239 OKButton & operator= (const OKButton &) = delete;
240
241 public:
242 explicit OKButton( vcl::Window* pParent, WinBits nStyle = WB_DEFBUTTON );
243
244 virtual void Click() override;
245 };
246
247 class VCL_DLLPUBLIC CancelButton : public PushButton
248 {
249 protected:
250 using PushButton::ImplInit;
251 private:
252 SAL_DLLPRIVATE void ImplInit( vcl::Window* pParent, WinBits nStyle );
253
254 CancelButton (const CancelButton &) = delete;
255 CancelButton & operator= (const CancelButton &) = delete;
256
257 public:
258 explicit CancelButton( vcl::Window* pParent, WinBits nStyle = 0 );
259
260 virtual void Click() override;
261 };
262
263 class CloseButton final : public CancelButton
264 {
265 public:
266 explicit CloseButton(vcl::Window* pParent);
267 };
268
269 class VCL_DLLPUBLIC HelpButton final : public PushButton
270 {
271 private:
272 using PushButton::ImplInit;
273 SAL_DLLPRIVATE void ImplInit( vcl::Window* pParent, WinBits nStyle );
274
275 HelpButton( const HelpButton & ) = delete;
276 HelpButton & operator= ( const HelpButton & ) = delete;
277
278 virtual void StateChanged( StateChangedType nStateChange ) override;
279
280 public:
281 explicit HelpButton( vcl::Window* pParent, WinBits nStyle = 0 );
282
283 virtual void Click() override;
284 };
285
286 class VCL_DLLPUBLIC CheckBox : public Button
287 {
288 private:
289 tools::Rectangle maStateRect;
290 tools::Rectangle maMouseRect;
291 TriState meState;
292 bool mbTriState;
293 Link<CheckBox&,void> maToggleHdl;
294 SAL_DLLPRIVATE void ImplInitCheckBoxData();
295 SAL_DLLPRIVATE static WinBits ImplInitStyle( const vcl::Window* pPrevWindow, WinBits nStyle );
296 SAL_DLLPRIVATE void ImplInitSettings( bool bBackground );
297 SAL_DLLPRIVATE void ImplDraw( OutputDevice* pDev, DrawFlags nDrawFlags,
298 const Point& rPos, const Size& rSize,
299 const Size& rImageSize, tools::Rectangle& rStateRect,
300 tools::Rectangle& rMouseRect );
301 SAL_DLLPRIVATE void ImplDrawCheckBox(vcl::RenderContext& rRenderContext );
302 SAL_DLLPRIVATE Size ImplGetCheckImageSize() const;
303
304 CheckBox(const CheckBox &) = delete;
305 CheckBox& operator= (const CheckBox &) = delete;
306
307 protected:
308 using Control::ImplInitSettings;
309 using Window::ImplInit;
310 SAL_DLLPRIVATE void ImplInit( vcl::Window* pParent, WinBits nStyle );
311 virtual void FillLayoutData() const override;
312 virtual const vcl::Font& GetCanonicalFont( const StyleSettings& _rStyle ) const override;
313 virtual const Color& GetCanonicalTextColor( const StyleSettings& _rStyle ) const override;
314 void ImplAdjustNWFSizes() override;
315
316 virtual void ImplDrawCheckBoxState(vcl::RenderContext& rRenderContext);
GetStateRect() const317 SAL_DLLPRIVATE const tools::Rectangle& GetStateRect() const { return maStateRect; }
GetMouseRect() const318 SAL_DLLPRIVATE const tools::Rectangle& GetMouseRect() const { return maMouseRect; }
319
320 public:
321 SAL_DLLPRIVATE void ImplCheck();
322 public:
323 explicit CheckBox( vcl::Window* pParent, WinBits nStyle = 0 );
324
325 virtual void MouseButtonDown( const MouseEvent& rMEvt ) override;
326 virtual void Tracking( const TrackingEvent& rTEvt ) override;
327 virtual void KeyInput( const KeyEvent& rKEvt ) override;
328 virtual void KeyUp( const KeyEvent& rKEvt ) override;
329 virtual void Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) override;
330 virtual void Draw( OutputDevice* pDev, const Point& rPos, DrawFlags nFlags ) override;
331 virtual void Resize() override;
332 virtual void GetFocus() override;
333 virtual void LoseFocus() override;
334 virtual void StateChanged( StateChangedType nType ) override;
335 virtual void DataChanged( const DataChangedEvent& rDCEvt ) override;
336 virtual bool PreNotify( NotifyEvent& rNEvt ) override;
337
338 void Toggle();
339
340 void SetState( TriState eState );
GetState() const341 TriState GetState() const { return meState; }
342
Check(bool bCheck=true)343 void Check( bool bCheck = true )
344 {
345 SetState( bCheck ? TRISTATE_TRUE : TRISTATE_FALSE );
346 }
347
IsChecked() const348 bool IsChecked() const
349 {
350 return (GetState() == TRISTATE_TRUE);
351 }
352
353 void EnableTriState( bool bTriState = true );
IsTriStateEnabled() const354 bool IsTriStateEnabled() const { return mbTriState; }
355
356 static Image GetCheckImage( const AllSettings& rSettings, DrawButtonFlags nFlags );
357
358 Size CalcMinimumSize( tools::Long nMaxWidth = 0 ) const;
359 virtual Size GetOptimalSize() const override;
360
SetToggleHdl(const Link<CheckBox &,void> & rLink)361 void SetToggleHdl( const Link<CheckBox&,void>& rLink ) { maToggleHdl = rLink; }
362
363 virtual bool set_property(const OString &rKey, const OUString &rValue) override;
364 virtual void ShowFocus(const tools::Rectangle& rRect) override;
365
366 /// Button has additional stuff that we need to dump too.
367 void DumpAsPropertyTree(tools::JsonWriter&) override;
368
369 virtual FactoryFunction GetUITestFactory() const override;
370 };
371
372 class VCL_DLLPUBLIC RadioButton : public Button
373 {
374 private:
375 friend class VclBuilder;
376
377 std::shared_ptr< std::vector< VclPtr< RadioButton > > > m_xGroup;
378 tools::Rectangle maStateRect;
379 tools::Rectangle maMouseRect;
380 Image maImage;
381 bool mbChecked;
382 bool mbRadioCheck;
383 bool mbStateChanged;
384 bool mbUsesExplicitGroup;
385 Link<RadioButton&,void> maToggleHdl;
386 SAL_DLLPRIVATE void ImplInitRadioButtonData();
387 SAL_DLLPRIVATE WinBits ImplInitStyle( const vcl::Window* pPrevWindow, WinBits nStyle );
388 SAL_DLLPRIVATE void ImplInitSettings( bool bBackground );
389 SAL_DLLPRIVATE void ImplDrawRadioButtonState(vcl::RenderContext& rRenderContext);
390 SAL_DLLPRIVATE void ImplDraw( OutputDevice* pDev, DrawFlags nDrawFlags,
391 const Point& rPos, const Size& rSize,
392 const Size& rImageSize, tools::Rectangle& rStateRect,
393 tools::Rectangle& rMouseRect );
394 SAL_DLLPRIVATE void ImplDrawRadioButton(vcl::RenderContext& rRenderContext );
395 SAL_DLLPRIVATE void ImplUncheckAllOther();
396 SAL_DLLPRIVATE Size ImplGetRadioImageSize() const;
397
398 RadioButton(const RadioButton &) = delete;
399 RadioButton& operator= (const RadioButton &) = delete;
400
401 protected:
402 using Control::ImplInitSettings;
403 using Window::ImplInit;
404 SAL_DLLPRIVATE void ImplInit( vcl::Window* pParent, WinBits nStyle );
405
406 public:
407 SAL_DLLPRIVATE void ImplCallClick( bool bGrabFocus = false, GetFocusFlags nFocusFlags = GetFocusFlags::NONE );
408
409 protected:
410 virtual void FillLayoutData() const override;
411 virtual const vcl::Font&
412 GetCanonicalFont( const StyleSettings& _rStyle ) const override;
413 virtual const Color&
414 GetCanonicalTextColor( const StyleSettings& _rStyle ) const override;
415 void ImplAdjustNWFSizes() override;
416
417 public:
418 /*
419 bUsesExplicitGroup of true means that group() is used to set what radiobuttons are part of a group
420 while false means that contiguous radiobuttons are considered part of a group where WB_GROUP designates
421 the start of the group and all contiguous radiobuttons without WB_GROUP set form the rest of the group.
422
423 true is fairly straightforward, false leads to trick situations and is the legacy case
424 */
425 explicit RadioButton(vcl::Window* pParent, bool bUsesExplicitGroup, WinBits nWinStyle);
426 virtual ~RadioButton() override;
427 virtual void dispose() override;
428
429 virtual void MouseButtonDown( const MouseEvent& rMEvt ) override;
430 virtual void Tracking( const TrackingEvent& rTEvt ) override;
431 virtual void KeyInput( const KeyEvent& rKEvt ) override;
432 virtual void KeyUp( const KeyEvent& rKEvt ) override;
433 virtual void Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) override;
434 virtual void Draw( OutputDevice* pDev, const Point& rPos, DrawFlags nFlags ) override;
435 virtual void Resize() override;
436 virtual void GetFocus() override;
437 virtual void LoseFocus() override;
438 virtual void StateChanged( StateChangedType nType ) override;
439 virtual void DataChanged( const DataChangedEvent& rDCEvt ) override;
440 virtual bool PreNotify( NotifyEvent& rNEvt ) override;
441
442 void Toggle();
443
IsStateChanged() const444 bool IsStateChanged() const { return mbStateChanged; }
445
EnableRadioCheck(bool bRadioCheck)446 void EnableRadioCheck( bool bRadioCheck ) { mbRadioCheck = bRadioCheck; }
IsRadioCheckEnabled() const447 bool IsRadioCheckEnabled() const { return mbRadioCheck; }
448
449 void SetModeRadioImage( const Image& rImage );
450
451 void SetState( bool bCheck );
452 void Check( bool bCheck = true );
IsChecked() const453 bool IsChecked() const { return mbChecked; }
454
455 static Image GetRadioImage( const AllSettings& rSettings, DrawButtonFlags nFlags );
456
457 Size CalcMinimumSize( tools::Long nMaxWidth = 0 ) const;
458 virtual Size GetOptimalSize() const override;
459
SetToggleHdl(const Link<RadioButton &,void> & rLink)460 void SetToggleHdl( const Link<RadioButton&,void>& rLink ) { maToggleHdl = rLink; }
461
462 /** GetRadioButtonGroup returns a list of pointers to <code>RadioButton</code>s in the same group.
463
464 The pointers in the returned list are valid at the time call returns. However rescheduling
465 or giving up the SolarMutex may mean events get executed that lead to the pointers getting
466 invalid.
467
468 @param bIncludeThis
469 defines whether <code>this</code> is contained in the returned list
470
471 @return
472 on return contains the <code>RadioButton</code>s
473 in the same group as this <code>RadioButton</code>.
474 */
475 std::vector<VclPtr<RadioButton> > GetRadioButtonGroup(bool bIncludeThis = true) const;
476
477 virtual bool set_property(const OString &rKey, const OUString &rValue) override;
478
479 /*
480 * Group this RadioButton with another
481 */
482 void group(RadioButton &rOther);
483 virtual void ShowFocus(const tools::Rectangle& rRect) override;
484
485 /// Button has additional stuff that we need to dump too.
486 void DumpAsPropertyTree(tools::JsonWriter&) override;
487
488 virtual FactoryFunction GetUITestFactory() const override;
489 };
490
491 class VCL_DLLPUBLIC ImageButton final : public PushButton
492 {
493 private:
494 using PushButton::ImplInitStyle;
495
496 SAL_DLLPRIVATE void ImplInitStyle();
497
498 ImageButton( const ImageButton & ) = delete;
499 ImageButton & operator= ( const ImageButton & ) = delete;
500
501 public:
502 ImageButton( vcl::Window* pParent, WinBits nStyle = 0 );
503 };
504
505 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
506