Audacity 3.2.0
AButton.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 AButton.cpp
6
7 Dominic Mazzoni
8
9*******************************************************************//*******************************************************************/
23
24
25#include "AButton.h"
26
27#include "AColor.h"
28#include "TrackArt.h"
29
30#include <wx/setup.h> // for wxUSE_* macros
31
32#include <wx/app.h>
33#include <wx/dcbuffer.h>
34#include <wx/eventfilter.h>
35#include <wx/image.h>
36#include <wx/timer.h>
37
38//This is needed for tooltips
39#include "Project.h"
40#include "ProjectStatus.h"
41#include "../ProjectWindowBase.h"
42#include <wx/tooltip.h>
43
44
45
46BEGIN_EVENT_TABLE(AButton, wxWindow)
47 EVT_MOUSE_EVENTS(AButton::OnMouseEvent)
48 EVT_MOUSE_CAPTURE_LOST(AButton::OnCaptureLost)
49 EVT_KEY_DOWN(AButton::OnKeyDown)
50 EVT_CHAR_HOOK(AButton::OnCharHook)
51 EVT_SET_FOCUS(AButton::OnSetFocus)
52 EVT_KILL_FOCUS(AButton::OnKillFocus)
53 EVT_PAINT(AButton::OnPaint)
54 EVT_SIZE(AButton::OnSize)
55 EVT_ERASE_BACKGROUND(AButton::OnErase)
57
58// LL: An alternative to this might be to just use the wxEVT_KILL_FOCUS
59// or wxEVT_ACTIVATE events.
60class AButton::Listener final
61 : public wxEventFilter
62{
63public:
64 Listener (AButton *button);
65 ~Listener();
66
67 int FilterEvent(wxEvent &event) override;
68
69 void OnEvent();
70
71private:
73};
74
76: mButton(button)
77{
78 wxEvtHandler::AddFilter(this);
79}
80
82{
83 wxEvtHandler::RemoveFilter(this);
84}
85
87{
88 if (!mButton->IsDown())
89 {
90 int idx = 0;
91 // Ignore the event, consult key states. One modifier key might
92 // have gone up but another remained down.
93 // Note that CMD (or CTRL) takes precedence over Shift if both are down
94 // and alternates are defined for both
95 // see also AButton::OnMouseEvent()
96 if (wxGetKeyState(WXK_CONTROL) && mButton->HasAlternateImages(2))
97 idx = 2;
98 else if (wxGetKeyState(WXK_SHIFT) && mButton->HasAlternateImages(1))
99 idx = 1;
100
101 // Turn e.g. the "Play" button into a "Loop" button
102 // or "Cut Preview" button
103 mButton->SetAlternateIdx(idx);
104 }
105}
106
108{
109 if (event.GetEventType() == wxEVT_KEY_DOWN ||
110 event.GetEventType() == wxEVT_KEY_UP)
111 OnEvent();
112 else if (event.GetEventType() == wxEVT_SET_FOCUS)
113 // A modal dialog might have eaten the modifier key-up with its own
114 // filter before we saw it; this is adequate to fix the button image
115 // when the dialog disappears.
116 OnEvent();
117 return Event_Skip;
118}
119
120AButton::AButton(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, bool toggle)
121{
122 Init(parent, id, pos, size, toggle);
123}
124
125AButton::AButton(wxWindow * parent,
126 wxWindowID id,
127 const wxPoint & pos,
128 const wxSize & size,
129 const wxImage& up,
130 const wxImage& over,
131 const wxImage& down,
132 const wxImage& overDown,
133 const wxImage& dis,
134 bool toggle)
135{
136 Init(parent, id, pos, size, toggle);
137
138 SetAlternateImages(0, up, over, down, overDown, dis);
139
140 SetMinSize(mImages[0][AButtonUp].GetSize());
141 SetMaxSize(mImages[0][AButtonUp].GetSize());
142}
143
145{
146 if(HasCapture())
147 ReleaseMouse();
148}
149
151{
152 if(mType != type)
153 {
154 mType = type;
155 InvalidateBestSize();
156 Refresh(false);
157 PostSizeEventToParent();
158 }
159}
160
161
162void AButton::Init(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, bool toggle)
163{
164 SetBackgroundStyle(wxBG_STYLE_PAINT);
165
166 // Bug in wxWidgets 2.8.12: by default pressing Enter on an AButton is interpreted as
167 // a navigation event - move to next control. As a workaround, the style wxWANTS_CHARS
168 // results in all characters being available in the OnKeyDown function below. Note
169 // that OnKeyDown now has to handle navigation.
170 Create(parent, id, pos, size, wxWANTS_CHARS);
171
172 mToggle = toggle;
173
174 mFocusRect = GetClientRect().Deflate( 3, 3 );
175
176#if wxUSE_ACCESSIBILITY
177 SetName( wxT("") );
178 SetAccessible(safenew AButtonAx(this));
179#endif
180}
181
183{
185}
186
188{
189 wxWindow::SetToolTip( toolTip.Stripped().Translation() );
190}
191
193{
194 wxWindow::SetLabel( toolTip.Stripped().Translation() );
195 if(mType == FrameButton)
196 InvalidateBestSize();
197}
198
199// This compensates for a but in wxWidgets 3.0.2 for mac:
200// Couldn't set focus from keyboard when AcceptsFocus returns false;
201// this bypasses that limitation
203{
204 auto temp = TemporarilyAllowFocus();
205 SetFocus();
206}
207
208void AButton::SetImages(const wxImage& up, const wxImage& over, const wxImage& down, const wxImage& overDown, const wxImage& dis)
209{
210 SetAlternateImages(0, up, over, down, overDown, dis);
211}
212
214 const wxImage& up,
215 const wxImage& over,
216 const wxImage& down,
217 const wxImage& overDown,
218 const wxImage& dis)
219{
220 if (1 + idx > mImages.size())
221 mImages.resize(1 + idx);
222 mImages[idx][AButtonUp] = up;
223 mImages[idx][AButtonOver] = over;
224 mImages[idx][AButtonDown] = down;
225 mImages[idx][AButtonOverDown] = overDown;
226 mImages[idx][AButtonDis] = dis;
227}
228
229void AButton::SetIcon(const wxImage& icon)
230{
231 mIcon = icon;
232 Refresh(false);
233}
234
235void AButton::SetAlternateIdx(unsigned idx)
236{
237 // If alternate-image-state is already correct then
238 // nothing to do (saves repainting button).
239 if( mAlternateIdx == idx )
240 return;
241 mAlternateIdx = idx;
242 Refresh(false);
243 PostSizeEventToParent();
244}
245
247{
248 if(!mListener)
249 mListener = std::make_unique<Listener>(this);
250}
251
252void AButton::SetFocusRect(const wxRect & r)
253{
254 mFocusRect = r;
255 mForceFocusRect = true;
256}
257
259{
260 AButtonState state;
261
262 if (!mEnabled && (!mToggle || !mButtonIsDown))
263 return AButtonDis;
264
265 if (mCursorIsInWindow) {
266 if (mToggle) {
267 if (mIsClicking) {
271 }
272 }
273 else {
277 }
278 }
279 }
280 else {
281 if (mIsClicking) {
283 }
284 else {
286 }
287 }
288 }
289 else {
291 }
292
293 return state;
294}
295
296void AButton::OnPaint(wxPaintEvent & WXUNUSED(event))
297{
298 wxBufferedPaintDC dc(this);
299
300 dc.SetPen(*wxTRANSPARENT_PEN);
301 dc.SetBrush(GetBackgroundColour());
302 dc.Clear();
303
304 const auto buttonRect = GetClientRect();
306 {
307 AButtonState buttonState = GetState();
308 if(mType == ImageButton)
309 dc.DrawBitmap(mImages[mAlternateIdx][buttonState], buttonRect.GetTopLeft());
310 else if(mType == FrameButton)
311 {
312 wxBitmap bitmap = mImages[mAlternateIdx][buttonState];
313 AColor::DrawFrame(dc, buttonRect, bitmap);
314
315 const auto border = bitmap.GetSize() / 4;
316
317 if(!GetLabel().IsEmpty())
318 {
319 dc.SetFont(GetFont());
320 auto textRect = buttonRect;
321 if(mIcon.IsOk())
322 {
323 auto fontMetrics = dc.GetFontMetrics();
324 auto sumHeight = fontMetrics.height + mIcon.GetHeight() + border.y;
325 dc.DrawBitmap(mIcon,
326 buttonRect.x + (buttonRect.width - mIcon.GetWidth()) / 2,
327 buttonRect.y + (buttonRect.height - sumHeight) / 2);
328 textRect = wxRect(
329 buttonRect.x,
330 buttonRect.y + buttonRect.height / 2 + sumHeight / 2 - fontMetrics.height,
331 buttonRect.width,
332 fontMetrics.height);
333 }
334 dc.SetPen(GetForegroundColour());
335 dc.DrawLabel(GetLabel(), textRect, wxALIGN_CENTER);
336 }
337 else if(mIcon.IsOk())
338 {
339 dc.DrawBitmap(mIcon,
340 buttonRect.x + (buttonRect.width - mIcon.GetWidth()) / 2,
341 buttonRect.y + (buttonRect.height - mIcon.GetHeight()) / 2);
342 }
343 }
344 else
345 {
346 wxBitmap bitmap = mImages[mAlternateIdx][buttonState];
347 AColor::DrawHStretch(dc, GetClientRect(), bitmap);
348 if(!GetLabel().IsEmpty())
349 {
350 dc.SetFont(GetFont());
351 const auto text = TrackArt::TruncateText(dc, GetLabel(), GetClientSize().GetWidth() - 6);
352 if(!text.IsEmpty())
353 {
354 dc.SetPen(GetForegroundColour());
355 dc.DrawLabel(text, GetClientRect(), wxALIGN_CENTER);
356 }
357 }
358 }
359 }
360
361 if(HasFocus())
363}
364
365void AButton::OnErase(wxEraseEvent & WXUNUSED(event))
366{
367 // Ignore it to prevent flashing
368}
369
370void AButton::OnSize(wxSizeEvent & WXUNUSED(event))
371{
372 if (!mForceFocusRect)
373 {
374 mFocusRect = GetClientRect().Deflate( 3, 3 );
375 }
376 Refresh(false);
377}
378
379bool AButton::s_AcceptsFocus{ false };
380
381bool AButton::HasAlternateImages(unsigned idx) const
382{
383 if (mImages.size() <= idx)
384 return false;
385
386 const auto &arr = mImages[idx];
387 return (arr[0].Ok() &&
388 arr[1].Ok() &&
389 arr[2].Ok() &&
390 arr[3].Ok() &&
391 arr[4].Ok());
392}
393
394void AButton::OnMouseEvent(wxMouseEvent & event)
395{
396 wxSize clientSize = GetClientSize();
397 AButtonState prevState = GetState();
398
399 if (event.Entering()) {
400 // Bug 1201: On Mac, unsetting and re-setting the tooltip may be needed
401 // to make it pop up when we want it.
402 auto text = GetToolTipText();
403 UnsetToolTip();
404 wxWindow::SetToolTip(text);
405 mCursorIsInWindow = true;
406 }
407 else if (event.Leaving())
408 mCursorIsInWindow = false;
409 else
411 (event.m_x >= 0 && event.m_y >= 0 &&
412 event.m_x < clientSize.x && event.m_y < clientSize.y);
413
414 if (mEnabled && event.IsButton()) {
415 if (event.ButtonIsDown(wxMOUSE_BTN_LEFT)) {
416 mIsClicking = true;
417 if (event.ButtonDClick())
418 mIsDoubleClicked = true;
419 if( !HasCapture() )
420 CaptureMouse();
421 }
422 else if (mIsClicking) {
423 mIsClicking = false;
424
425 if (HasCapture())
426 ReleaseMouse();
427
429 if (mToggle)
431
432 mWasShiftDown = event.ShiftDown();
433 mWasControlDown = event.ControlDown();
434
435 Click();
436 }
437 }
438 }
439
440 // Only redraw and change tooltips if the state has changed.
441 AButtonState newState = GetState();
442
443 if (newState != prevState) {
444 Refresh(false);
445
447 UpdateStatus();
448 else {
449 auto pProject = FindProjectFromWindow( this );
450 if (pProject)
451 ProjectStatus::Get( *pProject ).Set({});
452 }
453 }
454 else
455 event.Skip();
456}
457
459{
460 if (mCursorIsInWindow) {
461#if wxUSE_TOOLTIPS // Not available in wxX11
462 // Display the tooltip in the status bar
463 wxToolTip * pTip = this->GetToolTip();
464 if( pTip ) {
465 auto tipText = Verbatim( pTip->GetTip() );
466 if (!mEnabled)
467 tipText.Join( XO("(disabled)"), " " );
468 auto pProject = FindProjectFromWindow( this );
469 if (pProject)
470 ProjectStatus::Get( *pProject ).Set( tipText );
471 }
472#endif
473 }
474}
475
476void AButton::OnCaptureLost(wxMouseCaptureLostEvent & WXUNUSED(event))
477{
478 wxMouseEvent e(wxEVT_LEFT_UP);
479 e.m_x = -1;
480 e.m_y = -1;
481 OnMouseEvent(e);
482}
483
484// Note that OnKeyDown has to handle navigation because wxWANTS_CHARS
485// flag was set - see above.
486void AButton::OnKeyDown(wxKeyEvent & event)
487{
488 switch( event.GetKeyCode() )
489 {
490 case WXK_RIGHT:
491 case WXK_DOWN:
492 Navigate(wxNavigationKeyEvent::IsForward);
493 break;
494 case WXK_LEFT:
495 case WXK_UP:
496 Navigate(wxNavigationKeyEvent::IsBackward);
497 break;
498 case WXK_TAB:
499 Navigate(wxNavigationKeyEvent::FromTab | (event.ShiftDown()
500 ? wxNavigationKeyEvent::IsBackward
501 : wxNavigationKeyEvent::IsForward));
502 break;
503 default:
504 event.Skip();
505 }
506}
507
508void AButton::OnCharHook(wxKeyEvent& event)
509{
510 switch(event.GetKeyCode())
511 {
512 case WXK_RETURN:
513 case WXK_NUMPAD_ENTER:
514 if( !mEnabled )
515 break;
516 mWasShiftDown = event.ShiftDown();
517 mWasControlDown = event.ControlDown();
518 if(mToggle)
519 {
521 Refresh(false);
522#if wxUSE_ACCESSIBILITY
523 GetAccessible()->NotifyEvent(wxACC_EVENT_OBJECT_NAMECHANGE,
524 this, wxOBJID_CLIENT, wxACC_SELF);
525#endif
526 }
527 Click();
528 break;
529 default:
530 event.Skip();
531 }
532}
533
534void AButton::OnSetFocus(wxFocusEvent & WXUNUSED(event))
535{
536 Refresh( false );
537}
538
539void AButton::OnKillFocus(wxFocusEvent & WXUNUSED(event))
540{
541 Refresh( false );
542}
543
545{
546 return mWasShiftDown;
547}
548
550{
551 return mWasControlDown;
552}
553
555{
556 bool changed = wxWindow::Enable(true);
557 if ( !mEnabled ) {
558 mEnabled = true;
559 Refresh(false);
560 }
561}
562
564{
565 // Bug 1565: Tooltips not showing on disabled buttons.
566 // The fix is to NOT tell windows that the button is disabled.
567 // The button's appearance will still change to show it is disabled
568 // since we control that rather than windows.
569#ifndef __WXMSW__
570 wxWindow::Enable(false);
571#endif
572 if (GetCapture()==this)
573 ReleaseMouse();
574 if ( mEnabled ) {
575 mEnabled = false;
576 Refresh(false);
577 }
578}
579
581{
582 if (!mButtonIsDown) {
583 mButtonIsDown = true;
584 this->Refresh(false);
585 }
586}
587
589{
590 if (mButtonIsDown) {
591 mButtonIsDown = false;
592
593 this->Refresh(false);
594 }
595
596 if (GetCapture()==this)
597 ReleaseMouse();
598}
599
601{
602 wxCommandEvent event(wxEVT_COMMAND_BUTTON_CLICKED, GetId());
603 event.SetEventObject(this);
604 // Be sure to use SafelyProcessEvent so that exceptions do not propagate
605 // out of DoDefaultAction
606 GetEventHandler()->SafelyProcessEvent(event);
607}
608
609void AButton::SetShift(bool shift)
610{
611 mWasShiftDown = shift;
612}
613
614void AButton::SetControl(bool control)
615{
616 mWasControlDown = control;
617}
618
620{
622 {
623 const auto& image = mImages[mAlternateIdx][AButtonUp];
624 switch(mType)
625 {
626 case FrameButton:
627 {
628 if(!GetLabel().IsEmpty())
629 {
630 const auto border = image.GetSize() / 4;
631
632 wxMemoryDC dc;
633 dc.SetFont(GetFont());
634 auto bestSize = dc.GetTextExtent(GetLabel());
635 if(mIcon.IsOk())
636 {
637 bestSize.x = std::max(bestSize.x, mIcon.GetWidth());
638 bestSize.y = bestSize.y > 0
639 ? bestSize.y + border.y + mIcon.GetHeight()
640 : mIcon.GetHeight();
641 }
642 if(bestSize.x > 0)
643 bestSize.x += border.x * 2;
644 if(bestSize.y > 0)
645 bestSize.y += border.y * 2;
646 return bestSize;
647 }
648 if(mIcon.Ok())
649 return mIcon.GetSize();
650 return image.GetSize();
651 }
652 case TextButton:
653 return {-1, image.GetHeight() };
654 default:
655 return image.GetSize();
656 }
657 }
658 return wxWindow::DoGetBestClientSize();
659}
660
662 s_AcceptsFocus = true;
664}
665
666#if wxUSE_ACCESSIBILITY
667
668AButtonAx::AButtonAx( wxWindow *window ):
669 WindowAccessible( window )
670{
671}
672
673AButtonAx::~AButtonAx()
674{
675}
676
677// Performs the default action. childId is 0 (the action for this object)
678// or > 0 (the action for a child).
679// Return wxACC_NOT_SUPPORTED if there is no default action for this
680// window (e.g. an edit control).
681wxAccStatus AButtonAx::DoDefaultAction(int WXUNUSED(childId))
682{
683 AButton *ab = wxDynamicCast( GetWindow(), AButton );
684
685 if(ab && ab->IsEnabled()) {
686 ab->mWasShiftDown = false;
687 ab->mWasControlDown = false;
688 if(ab->mToggle)
689 {
690 ab->mButtonIsDown = !ab->mButtonIsDown;
691 ab->Refresh(false);
692 }
693 ab->Click();
694 }
695
696 return wxACC_OK;
697}
698
699// Retrieves the address of an IDispatch interface for the specified child.
700// All objects must support this property.
701wxAccStatus AButtonAx::GetChild( int childId, wxAccessible** child )
702{
703 if( childId == wxACC_SELF )
704 {
705 *child = this;
706 }
707 else
708 {
709 *child = NULL;
710 }
711
712 return wxACC_OK;
713}
714
715// Gets the number of children.
716wxAccStatus AButtonAx::GetChildCount(int* childCount)
717{
718 *childCount = 0;
719
720 return wxACC_OK;
721}
722
723// Gets the default action for this object (0) or > 0 (the action for
724// a child). Return wxACC_OK even if there is no action. actionName
725// is the action, or the empty string if there is no action. The
726// retrieved string describes the action that is performed on an
727// object, not what the object does as a result. For example, a
728// toolbar button that prints a document has a default action of
729// "Press" rather than "Prints the current document."
730wxAccStatus AButtonAx::GetDefaultAction(int WXUNUSED(childId), wxString* actionName)
731{
732 *actionName = _( "Press" );
733
734 return wxACC_OK;
735}
736
737// Returns the description for this object or a child.
738wxAccStatus AButtonAx::GetDescription( int WXUNUSED(childId), wxString *description )
739{
740 description->clear();
741
742 return wxACC_OK;
743}
744
745// Gets the window with the keyboard focus.
746// If childId is 0 and child is NULL, no object in
747// this subhierarchy has the focus.
748// If this object has the focus, child should be 'this'.
749wxAccStatus AButtonAx::GetFocus(int* childId, wxAccessible** child)
750{
751 *childId = 0;
752 *child = this;
753
754 return wxACC_OK;
755}
756
757// Returns help text for this object or a child, similar to tooltip text.
758wxAccStatus AButtonAx::GetHelpText( int WXUNUSED(childId), wxString *helpText )
759{
760#if wxUSE_TOOLTIPS // Not available in wxX11
761 AButton *ab = wxDynamicCast( GetWindow(), AButton );
762
763 wxToolTip *pTip = ab->GetToolTip();
764 if( pTip )
765 {
766 *helpText = pTip->GetTip();
767 }
768
769 return wxACC_OK;
770#else
771 helpText->clear();
772
773 return wxACC_NOT_SUPPORTED;
774#endif
775}
776
777// Returns the keyboard shortcut for this object or child.
778// Return e.g. ALT+K
779wxAccStatus AButtonAx::GetKeyboardShortcut( int WXUNUSED(childId), wxString *shortcut )
780{
781 shortcut->clear();
782
783 return wxACC_OK;
784}
785
786// Returns the rectangle for this object (id = 0) or a child element (id > 0).
787// rect is in screen coordinates.
788wxAccStatus AButtonAx::GetLocation( wxRect& rect, int WXUNUSED(elementId) )
789{
790 AButton *ab = wxDynamicCast( GetWindow(), AButton );
791
792 rect = ab->GetRect();
793 rect.SetPosition( ab->GetParent()->ClientToScreen( rect.GetPosition() ) );
794
795 return wxACC_OK;
796}
797
798// Gets the name of the specified object.
799wxAccStatus AButtonAx::GetName(int WXUNUSED(childId), wxString* name)
800{
801 AButton *ab = wxDynamicCast( GetWindow(), AButton );
802
803 *name = ab->GetName();
804 if( name->empty() )
805 {
806 *name = ab->GetLabel();
807 }
808
809 if( name->empty() )
810 {
811 *name = _("Button");
812 }
813
814 /* In the MSAA frame work, there isn't such a thing as a toggle button.
815 In particular, narrator does not read the wxACC_STATE_SYSTEM_PRESSED state at all.
816 So to imitate a toggle button, include the role and the state in the name, and
817 create a name change event when the state changes. */
818 if (ab->mToggle) {
819 *name += wxT(" ") +
820 _("Button")
821 + wxT(" ") +
822 /* i18n-hint: whether a button is pressed or not pressed */
823 (ab->IsDown() ? _("pressed") : _("not pressed"));
824 }
825
826 return wxACC_OK;
827}
828
829// Returns a role constant.
830wxAccStatus AButtonAx::GetRole(int WXUNUSED(childId), wxAccRole* role)
831{
832 AButton* ab = wxDynamicCast(GetWindow(), AButton);
833
834 // For a toggle button, the role is included in the name, so read nothing
835 *role = ab->mToggle ? wxROLE_SYSTEM_STATICTEXT : wxROLE_SYSTEM_PUSHBUTTON;
836
837 return wxACC_OK;
838}
839
840// Gets a variant representing the selected children
841// of this object.
842// Acceptable values:
843// - a null variant (IsNull() returns TRUE)
844// - a list variant (GetType() == wxT("list"))
845// - an integer representing the selected child element,
846// or 0 if this object is selected (GetType() == wxT("long"))
847// - a "void*" pointer to a wxAccessible child object
848wxAccStatus AButtonAx::GetSelections( wxVariant * WXUNUSED(selections) )
849{
850 return wxACC_NOT_IMPLEMENTED;
851}
852
853// Returns a state constant.
854wxAccStatus AButtonAx::GetState(int WXUNUSED(childId), long* state)
855{
856 AButton *ab = wxDynamicCast( GetWindow(), AButton );
857 *state = 0;
858 if(!ab->IsEnabled())
859 *state = wxACC_STATE_SYSTEM_UNAVAILABLE;
860 else
861 {
862 // For a toggle button, the state is included in the name
863 if(ab->mButtonIsDown && !ab->mToggle)
864 *state |= wxACC_STATE_SYSTEM_PRESSED;
865
866 if(ab->mCursorIsInWindow)
867 *state |= wxACC_STATE_SYSTEM_HOTTRACKED;
868
869 *state |= wxACC_STATE_SYSTEM_FOCUSABLE;
870 if(ab->HasFocus())
871 *state |= wxACC_STATE_SYSTEM_FOCUSED;
872 }
873 return wxACC_OK;
874}
875
876// Returns a localized string representing the value for the object
877// or child.
878wxAccStatus AButtonAx::GetValue(int WXUNUSED(childId), wxString* WXUNUSED(strValue))
879{
880 return wxACC_NOT_SUPPORTED;
881}
882
883#endif
wxEVT_COMMAND_BUTTON_CLICKED
wxImage(22, 22)
wxT("CloseDown"))
END_EVENT_TABLE()
const TranslatableString name
Definition: Distortion.cpp:82
#define XO(s)
Definition: Internat.h:31
#define _(s)
Definition: Internat.h:75
#define safenew
Definition: MemoryX.h:10
AudacityProject * FindProjectFromWindow(wxWindow *pWindow)
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
static std::once_flag flag
AButton * mButton
Definition: AButton.cpp:72
Listener(AButton *button)
Definition: AButton.cpp:75
int FilterEvent(wxEvent &event) override
Definition: AButton.cpp:107
A wxButton with mouse-over behaviour.
Definition: AButton.h:104
wxRect mFocusRect
Definition: AButton.h:275
bool mUseDisabledAsDownHiliteImage
Definition: AButton.h:269
void SetShift(bool shift)
Definition: AButton.cpp:609
bool mButtonIsDown
Definition: AButton.h:266
void SetButtonType(Type type)
Definition: AButton.cpp:150
bool mCursorIsInWindow
Definition: AButton.h:265
void SetControl(bool control)
Definition: AButton.cpp:614
void SetImages(const wxImage &up, const wxImage &over, const wxImage &down, const wxImage &overDown, const wxImage &dis)
Definition: AButton.cpp:208
void UseDisabledAsDownHiliteImage(bool flag)
Definition: AButton.cpp:182
AButtonState
Definition: AButton.h:226
@ AButtonUp
Definition: AButton.h:227
@ AButtonDis
Definition: AButton.h:231
@ AButtonOver
Definition: AButton.h:228
@ AButtonDown
Definition: AButton.h:229
@ AButtonOverDown
Definition: AButton.h:230
void PushDown()
Definition: AButton.cpp:580
std::unique_ptr< bool, Resetter > TempAllowFocus
Definition: AButton.h:243
bool mIsClicking
Definition: AButton.h:267
bool HasAlternateImages(unsigned idx) const
Definition: AButton.cpp:381
bool mWasShiftDown
Definition: AButton.h:262
bool IsDown()
Definition: AButton.h:208
void Click()
Definition: AButton.cpp:600
void OnSize(wxSizeEvent &event)
Definition: AButton.cpp:370
void OnSetFocus(wxFocusEvent &event)
Definition: AButton.cpp:534
void OnKillFocus(wxFocusEvent &event)
Definition: AButton.cpp:539
void UpdateStatus()
Definition: AButton.cpp:458
void SetToolTip(const TranslatableString &toolTip)
Definition: AButton.cpp:187
static TempAllowFocus TemporarilyAllowFocus()
Definition: AButton.cpp:661
static bool s_AcceptsFocus
Definition: AButton.h:241
void SetAlternateIdx(unsigned idx)
Definition: AButton.cpp:235
void OnPaint(wxPaintEvent &event)
Definition: AButton.cpp:296
Type mType
Definition: AButton.h:280
void SetFocusRect(const wxRect &r)
Definition: AButton.cpp:252
bool WasControlDown()
Definition: AButton.cpp:549
void OnErase(wxEraseEvent &event)
Definition: AButton.cpp:365
wxSize DoGetBestClientSize() const override
Definition: AButton.cpp:619
void SetFocusFromKbd() override
Definition: AButton.cpp:202
std::unique_ptr< Listener > mListener
Definition: AButton.h:278
void Disable()
Definition: AButton.cpp:563
friend class AButtonAx
Definition: AButton.h:105
bool mIsDoubleClicked
Definition: AButton.h:270
void OnMouseEvent(wxMouseEvent &event)
Definition: AButton.cpp:394
void Enable()
Definition: AButton.cpp:554
void PopUp()
Definition: AButton.cpp:588
bool IsEnabled() const
Definition: AButton.h:179
@ TextButton
Definition: AButton.h:112
@ FrameButton
Definition: AButton.h:114
@ ImageButton
Definition: AButton.h:113
wxImage mIcon
Definition: AButton.h:272
bool mEnabled
Definition: AButton.h:268
void SetAlternateImages(unsigned idx, const wxImage &up, const wxImage &over, const wxImage &down, const wxImage &overDown, const wxImage &dis)
Definition: AButton.cpp:213
bool WasShiftDown()
Definition: AButton.cpp:544
AButtonState GetState()
Definition: AButton.cpp:258
AButton(wxWindow *parent=nullptr, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, bool toggle=false)
Definition: AButton.cpp:120
void OnKeyDown(wxKeyEvent &event)
Definition: AButton.cpp:486
bool mToggle
Definition: AButton.h:255
unsigned mAlternateIdx
Definition: AButton.h:254
std::vector< std::array< wxImage, AButtonStateCount > > mImages
Definition: AButton.h:273
void OnCharHook(wxKeyEvent &event)
Definition: AButton.cpp:508
virtual ~AButton()
Definition: AButton.cpp:144
bool mWasControlDown
Definition: AButton.h:263
void SetIcon(const wxImage &icon)
Definition: AButton.cpp:229
void FollowModifierKeys()
Definition: AButton.cpp:246
void Init(wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, bool toggle)
Definition: AButton.cpp:162
void OnCaptureLost(wxMouseCaptureLostEvent &event)
Definition: AButton.cpp:476
void SetLabel(const TranslatableString &label)
Definition: AButton.cpp:192
bool mForceFocusRect
Definition: AButton.h:276
static void DrawHStretch(wxDC &dc, const wxRect &rect, wxBitmap &bitmap)
Definition: AColor.cpp:308
static void DrawFrame(wxDC &dc, const wxRect &r, wxBitmap &bitmap)
Definition: AColor.cpp:325
static void DrawFocus(wxDC &dc, wxRect &r)
Definition: AColor.cpp:235
static ProjectStatus & Get(AudacityProject &project)
void Set(const TranslatableString &msg, StatusBarField field=mainStatusBarField)
Holds a msgid for the translation catalog; may also bind format arguments.
wxString Translation() const
TranslatableString Stripped(unsigned options=MenuCodes) const
non-mutating, constructs another TranslatableString object
An alternative to using wxWindowAccessible, which in wxWidgets 3.1.1 contained GetParent() which was ...
AUDACITY_DLL_API wxString TruncateText(wxDC &dc, const wxString &text, const int maxWidth)
Definition: TrackArt.cpp:156