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