Audacity 3.2.0
ASlider.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 ASlider.cpp
6
7 Dominic Mazzoni
8
9*******************************************************************//*******************************************************************/
30
31
32
33#include "ASlider.h"
34
35#include <math.h>
36
37#include <wx/setup.h> // for wxUSE_* macros
38#include <wx/defs.h>
39#include <wx/dcbuffer.h>
40#include <wx/frame.h>
41#include <wx/graphics.h>
42#include <wx/panel.h>
43#include <wx/tooltip.h>
44#include <wx/debug.h>
45#include <wx/textctrl.h>
46#include <wx/valtext.h>
47#include <wx/statline.h>
48#include <wx/settings.h>
49#include <wx/popupwin.h>
50#include <wx/window.h>
51
52#include "AColor.h"
53#include "ImageManipulation.h"
54#include "Project.h"
55#include "ProjectStatus.h"
56#include "../ProjectWindowBase.h"
57#include "ShuttleGui.h"
58#include "Theme.h"
59#include "valnum.h"
60
61#include "AllThemeResources.h"
62
63#if wxUSE_ACCESSIBILITY
64#include "WindowAccessible.h"
65
66class AUDACITY_DLL_API ASliderAx final : public WindowAccessible
67{
68public:
69 ASliderAx(wxWindow * window);
70
71 virtual ~ ASliderAx();
72
73 // Retrieves the address of an IDispatch interface for the specified child.
74 // All objects must support this property.
75 wxAccStatus GetChild(int childId, wxAccessible** child) override;
76
77 // Gets the number of children.
78 wxAccStatus GetChildCount(int* childCount) override;
79
80 // Gets the default action for this object (0) or > 0 (the action for a child).
81 // Return wxACC_OK even if there is no action. actionName is the action, or the empty
82 // string if there is no action.
83 // The retrieved string describes the action that is performed on an object,
84 // not what the object does as a result. For example, a toolbar button that prints
85 // a document has a default action of "Press" rather than "Prints the current document."
86 wxAccStatus GetDefaultAction(int childId, wxString *actionName) override;
87
88 // Returns the description for this object or a child.
89 wxAccStatus GetDescription(int childId, wxString *description) override;
90
91 // Gets the window with the keyboard focus.
92 // If childId is 0 and child is NULL, no object in
93 // this subhierarchy has the focus.
94 // If this object has the focus, child should be 'this'.
95 wxAccStatus GetFocus(int *childId, wxAccessible **child) override;
96
97 // Returns help text for this object or a child, similar to tooltip text.
98 wxAccStatus GetHelpText(int childId, wxString *helpText) override;
99
100 // Returns the keyboard shortcut for this object or child.
101 // Return e.g. ALT+K
102 wxAccStatus GetKeyboardShortcut(int childId, wxString *shortcut) override;
103
104 // Returns the rectangle for this object (id = 0) or a child element (id > 0).
105 // rect is in screen coordinates.
106 wxAccStatus GetLocation(wxRect& rect, int elementId) override;
107
108 // Gets the name of the specified object.
109 wxAccStatus GetName(int childId, wxString *name) override;
110
111 // Returns a role constant.
112 wxAccStatus GetRole(int childId, wxAccRole *role) override;
113
114 // Gets a variant representing the selected children
115 // of this object.
116 // Acceptable values:
117 // - a null variant (IsNull() returns TRUE)
118 // - a list variant (GetType() == wxT("list"))
119 // - an integer representing the selected child element,
120 // or 0 if this object is selected (GetType() == wxT("long"))
121 // - a "void*" pointer to a wxAccessible child object
122 wxAccStatus GetSelections(wxVariant *selections) override;
123
124 // Returns a state constant.
125 wxAccStatus GetState(int childId, long* state) override;
126
127 // Returns a localized string representing the value for the object
128 // or child.
129 wxAccStatus GetValue(int childId, wxString* strValue) override;
130
131};
132
133#endif // wxUSE_ACCESSIBILITY
134#if defined __WXMSW__
135const int sliderFontSize = 10;
136#else
137const int sliderFontSize = 12;
138#endif
139
140#ifndef EXPERIMENTAL_DA
141#define OPTIONAL_SLIDER_TICKS
142#endif
143
144//
145// TipWindow
146//
147
148class TipWindow final : public wxFrame
149{
150 public:
151 TipWindow(wxWindow *parent, const TranslatableStrings & labels);
152 virtual ~TipWindow() {}
153
154 wxSize GetSize() const;
155 void SetPos(const wxPoint & pos);
156 void SetLabel(const TranslatableString & label);
157
158private:
159 void OnPaint(wxPaintEvent & event);
160
161private:
165 wxFont mFont;
166
167 DECLARE_EVENT_TABLE()
168};
169
170BEGIN_EVENT_TABLE(TipWindow, wxFrame)
171 EVT_PAINT(TipWindow::OnPaint)
173
174TipWindow::TipWindow(wxWindow *parent, const TranslatableStrings & labels)
175: wxFrame(parent, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize,
176 wxFRAME_SHAPED | wxNO_BORDER | wxFRAME_NO_TASKBAR | wxFRAME_FLOAT_ON_PARENT )
177{
178 SetBackgroundStyle(wxBG_STYLE_PAINT);
179 SetBackgroundColour(wxTransparentColour);
180
181 mFont.SetPointSize(sliderFontSize);
182 mFont.SetFamily(wxFONTFAMILY_SWISS);
183 mFont.SetStyle(wxFONTSTYLE_NORMAL);
184 mFont.SetWeight(wxFONTWEIGHT_NORMAL);
185
186 mWidth = mHeight = 0;
187 for ( const auto &label : labels ) {
188 int width, height;
189 GetTextExtent(label.Translation(), &width, &height, NULL, NULL, &mFont);
190 mWidth = std::max( mWidth, width );
191 mHeight = std::max( mHeight, height );
192 }
193
194 // Pad to allow for curved corners
195 mWidth += 8;
196 mHeight += 8;
197
198#if defined(__WXMAC__)
199 // Use a bitmap region to set the shape since just adding an unfilled path
200 // will make the window transparent
201 wxBitmap shape(mWidth, mHeight);
202 wxMemoryDC dc(shape);
203
204 dc.SetPen(*wxBLACK_PEN);
205 dc.SetBrush(*wxBLACK_BRUSH);
206 dc.DrawRoundedRectangle(0, 0, mWidth, mHeight, 5);
207 dc.SelectObject(wxNullBitmap);
208
209 SetShape(wxRegion(shape, *wxWHITE));
210#else
211 wxGraphicsPath path = wxGraphicsRenderer::GetDefaultRenderer()->CreatePath();
212 path.AddRoundedRectangle(0, 0, mWidth, mHeight, 5);
213 SetShape(path);
214#endif
215}
216
217wxSize TipWindow::GetSize() const
218{
219 return wxSize(mWidth, mHeight);
220}
221
222void TipWindow::SetPos(const wxPoint & pos)
223{
224 SetSize(pos.x, pos.y, mWidth, mHeight);
225}
226
228{
229 mLabel = label;
230}
231
232void TipWindow::OnPaint(wxPaintEvent & WXUNUSED(event))
233{
234 wxAutoBufferedPaintDC dc(this);
235
236 dc.SetPen(*wxBLACK_PEN);
237 dc.SetBrush(AColor::tooltipBrush);
238 dc.DrawRoundedRectangle(0, 0, mWidth, mHeight, 5);
239
240 dc.SetFont(mFont);
241 dc.SetTextForeground(AColor::tooltipPen.GetColour());
242
243 int textWidth, textHeight;
244 const auto visibleLabel = mLabel.Translation();
245 dc.GetTextExtent(visibleLabel, &textWidth, &textHeight);
246 dc.DrawText(visibleLabel, (mWidth - textWidth) / 2, (mHeight - textHeight) / 2);
247}
248
249//
250// SliderDialog
251//
252
253BEGIN_EVENT_TABLE(SliderDialog, wxDialogWrapper)
254 EVT_TEXT( wxID_ANY, SliderDialog::OnTextChange )
255 EVT_SLIDER(wxID_ANY,SliderDialog::OnSlider)
257
258SliderDialog::SliderDialog(wxWindow * parent, wxWindowID id,
260 wxPoint position,
261 wxSize size,
262 int style,
263 float value,
264 float line,
265 float page,
266 LWSlider * pSource):
267 wxDialogWrapper(parent,id,title,position),
268 mStyle(style)
269{
270 SetName();
271 mpOrigin = pSource;
272 mValue = mpOrigin->Get(false);
273
274 auto prec = 2;
275 auto trailing = NumValidatorStyle::TWO_TRAILING_ZEROES;
276 if (style == DB_SLIDER)
277 {
278 prec = 1;
279 trailing = NumValidatorStyle::ONE_TRAILING_ZERO;
280 }
281
282 ShuttleGui S(this, eIsCreating);
283
284 S.StartVerticalLay();
285 {
286 if (style == PAN_SLIDER)
287 {
288 mTextCtrl = S
289 .Validator<IntegerValidator<float>>(
290 &mValue, NumValidatorStyle::DEFAULT, -100.0, 100.0)
291 .AddTextBox({}, wxEmptyString, 15);
292 }
293 else if (style == VEL_SLIDER)
294 {
295 mTextCtrl = S
296 .Validator<IntegerValidator<float>>(
297 &mValue, NumValidatorStyle::DEFAULT, -50.0, 50.0)
298 .AddTextBox({}, wxEmptyString, 15);
299 }
300 else if(style == PERCENT_SLIDER)
301 {
302 mTextCtrl = S
303 .Validator<IntegerValidator<float>>(
304 &mValue, NumValidatorStyle::DEFAULT, 0.0, 100.0)
305 .AddTextBox({}, wxEmptyString, 15);
306 }
307 else
308 {
309 mTextCtrl = S
310 .Validator<FloatingPointValidator<float>>(
311 prec, &mValue, trailing, mpOrigin->GetMinValue(), mpOrigin->GetMaxValue())
312 .AddTextBox({}, wxEmptyString, 15);
313 }
314 mSlider = safenew ASlider(S.GetParent(),
315 wxID_ANY,
316 title,
317 wxDefaultPosition,
318 size,
320 .Style( style ).Line( line ).Page( page ).Popup( false) );
321 S.Position(wxEXPAND)
322 .AddWindow(mSlider);
323 }
324 S.EndVerticalLay();
325
326 S.AddStandardButtons(eOkButton | eCancelButton);
327
328 Fit();
329
330 mSlider->Set(value);
331}
332
334{
335}
336
338{
339 float value = mSlider->Get(false);
341 ? value * 100.0
342 : value;
343 mTextCtrl->GetValidator()->TransferToWindow();
344 mTextCtrl->SetSelection(-1, -1);
345 if (mpOrigin) {
346 mpOrigin->Set(value);
347 mpOrigin->SendUpdate(value);
348 }
349
350 return true;
351}
352
354{
355 if (mTextCtrl->GetValidator()->TransferFromWindow())
356 {
357 float value = mValue;
358 if (mStyle == DB_SLIDER)
359 value = DB_TO_LINEAR(value);
360 else if (mStyle == PAN_SLIDER || mStyle == PERCENT_SLIDER)
361 value /= 100.0;
362 mSlider->Set(value);
363 if (mpOrigin) {
364 mpOrigin->Set(value);
365 mpOrigin->SendUpdate(value);
366 }
367 }
368
369 return true;
370}
371
372void SliderDialog::OnSlider(wxCommandEvent & event)
373{
375 event.Skip(false);
376}
377
378void SliderDialog::OnTextChange(wxCommandEvent & event)
379{
380 if (mTextCtrl->GetValidator()->TransferFromWindow())
381 {
383 }
384 event.Skip(false);
385}
386
388{
389 return mSlider->Get(false);
390}
391
392//
393// LWSlider
394//
395
396// Define the thumb outline
397static const wxPoint2DDouble outer[] =
398{
399 wxPoint2DDouble( 2, 0 ),
400 wxPoint2DDouble( 8, 0 ),
401 wxPoint2DDouble( 10, 2 ),
402 wxPoint2DDouble( 10, 8 ),
403 wxPoint2DDouble( 5, 13 ),
404 wxPoint2DDouble( 0, 8 ),
405 wxPoint2DDouble( 0, 2 ),
406 wxPoint2DDouble( 2, 0 )
407};
408
409// Define the left and top interior components when enabled
410static const wxPoint2DDouble enabledLeftBegin[] =
411{
412 wxPoint2DDouble( 2, 1 ),
413 wxPoint2DDouble( 1, 2 ),
414 wxPoint2DDouble( 1, 8 ),
415 wxPoint2DDouble( 4, 4 ),
416 wxPoint2DDouble( 4, 7 )
417};
418static const wxPoint2DDouble enabledLeftEnd[] =
419{
420 wxPoint2DDouble( 8, 1 ),
421 wxPoint2DDouble( 1, 8 ),
422 wxPoint2DDouble( 5, 12 ),
423 wxPoint2DDouble( 6, 4 ),
424 wxPoint2DDouble( 6, 7 )
425};
426
427// Define right and bottom interior components when enabled
428static const wxPoint2DDouble enabledRightBegin[] =
429{
430 wxPoint2DDouble( 9, 2 ),
431 wxPoint2DDouble( 9, 8 ),
432 wxPoint2DDouble( 4, 5 ),
433 wxPoint2DDouble( 4, 8 ),
434};
435static const wxPoint2DDouble enabledRightEnd[] =
436{
437 wxPoint2DDouble( 9, 8 ),
438 wxPoint2DDouble( 6, 11 ),
439 wxPoint2DDouble( 6, 5 ),
440 wxPoint2DDouble( 6, 8 )
441};
442
443// Define the interior stripes when disabled
444static const wxPoint2DDouble disabledStripesBegin[] =
445{
446 wxPoint2DDouble( 3, 2 ),
447 wxPoint2DDouble( 5, 2 ),
448 wxPoint2DDouble( 7, 2 ),
449 wxPoint2DDouble( 2, 3 ),
450 wxPoint2DDouble( 2, 5 ),
451 wxPoint2DDouble( 2, 7 ),
452};
453static const wxPoint2DDouble disabledStripesEnd[] =
454{
455 wxPoint2DDouble( 8, 7 ),
456 wxPoint2DDouble( 8, 5 ),
457 wxPoint2DDouble( 8, 3 ),
458 wxPoint2DDouble( 7, 8 ),
459 wxPoint2DDouble( 6, 9 ),
460 wxPoint2DDouble( 5, 10 ),
461};
462
463// Define the right and bottom interior components when disabled
464static const wxPoint2DDouble disabledRightBegin[] =
465{
466 wxPoint2DDouble( 9, 2 ),
467 wxPoint2DDouble( 9, 8 ),
468};
469static const wxPoint2DDouble disabledRightEnd[] =
470{
471 wxPoint2DDouble( 9, 8 ),
472 wxPoint2DDouble( 6, 11 ),
473};
474
475// Construct customizable slider
476LWSlider::LWSlider(wxWindow * parent,
478 const wxPoint &pos,
479 const wxSize &size,
480 float minValue,
481 float maxValue,
482 float stepValue,
483 bool canUseShift,
484 int style,
485 bool showlabels /* = true */,
486 bool drawticks /* = true */,
487 bool drawtrack /* = true */,
488 bool alwayshidetip /* = false */,
489 bool heavyweight /* = false */,
490 bool popup /* = true */,
491 int orientation /* = wxHORIZONTAL */) // wxHORIZONTAL or wxVERTICAL. wxVERTICAL is currently only for DB_SLIDER.
492{
493 Init(parent, name, pos, size, minValue, maxValue, stepValue,
494 canUseShift, style, showlabels, drawticks, drawtrack,
495 alwayshidetip, heavyweight, popup, 1.0, orientation);
496}
497
498// Construct predefined slider
499LWSlider::LWSlider(wxWindow *parent,
501 const wxPoint &pos,
502 const wxSize &size,
503 int style,
504 bool showlabels /* = true */,
505 bool drawticks /* = true */,
506 bool drawtrack /* = true */,
507 bool alwayshidetip /* = false */,
508 bool heavyweight /* = false */,
509 bool popup /* = true */,
510 int orientation /* = wxHORIZONTAL */) // wxHORIZONTAL or wxVERTICAL. wxVERTICAL is currently only for DB_SLIDER.
511{
512 wxString leftLabel, rightLabel;
513
514 float minValue, maxValue, stepValue;
515 float speed = 1.0;
516
517 switch(style)
518 {
519 case PAN_SLIDER:
520 minValue = -1.0f;
521 maxValue = +1.0f;
522 stepValue = 0.1f;
523 orientation = wxHORIZONTAL; //v Vertical PAN_SLIDER currently not handled, forced to horizontal.
524 break;
525 case DB_SLIDER:
526 minValue = -36.0f;
527 //if (orientation == wxHORIZONTAL)
528 maxValue = 36.0f;
529 //else
530 //maxValue = 36.0f; // for MixerBoard //v Previously was 6dB for MixerBoard, but identical for now.
531 stepValue = 1.0f;
532 speed = 0.5;
533 break;
534 case FRAC_SLIDER:
535 case PERCENT_SLIDER:
536 minValue = 0.0f;
537 maxValue = 1.0f;
538 stepValue = STEP_CONTINUOUS;
539 break;
540 case SPEED_SLIDER:
541 minValue = 0.01f;
542 maxValue = 3.0f;
543 stepValue = STEP_CONTINUOUS;
544 break;
545#ifdef EXPERIMENTAL_MIDI_OUT
546 case VEL_SLIDER:
547 minValue = VEL_MIN;
548 maxValue = VEL_MAX;
549 stepValue = 1.0f;
550 speed = 0.5;
551 break;
552#endif
553 default:
554 minValue = 0.0f;
555 maxValue = 1.0f;
556 stepValue = 0.0f;
557 wxASSERT(false); // undefined style
558 }
559
560 Init(parent, name, pos, size, minValue, maxValue, stepValue,
561 true, style, showlabels, drawticks, drawtrack, alwayshidetip,
562 heavyweight, popup, speed, orientation);
563}
564
565void LWSlider::Init(wxWindow * parent,
567 const wxPoint &pos,
568 const wxSize &size,
569 float minValue,
570 float maxValue,
571 float stepValue,
572 bool canUseShift,
573 int style,
574 bool showlabels,
575 bool drawticks,
576 bool drawtrack,
577 bool alwayshidetip,
578 bool heavyweight,
579 bool popup,
580 float speed,
581 int orientation /* = wxHORIZONTAL */) // wxHORIZONTAL or wxVERTICAL. wxVERTICAL is currently only for DB_SLIDER.
582{
583 mEnabled = true;
584 mName = name;
585 mStyle = style;
586 mOrientation = orientation;
587 mIsDragging = false;
588 mParent = parent;
589 mShowLabels = showlabels;
590 mDrawTicks = drawticks;
591 mDrawTrack = drawtrack;
592 mAlwaysHideTip = alwayshidetip;
593 mHW = heavyweight;
594 mPopup = popup;
595 mSpeed = speed;
596 mID = wxID_ANY;
597 mMinValue = minValue;
598 mMaxValue = maxValue;
599 mStepValue = stepValue;
600 mCanUseShift = canUseShift;
601 mCurrentValue = 0.0f;
602 mDefaultValue = 0.0f;
603 mDefaultShortcut = false;
604 mBitmap = nullptr;
605 mThumbBitmap = nullptr;
606 mThumbBitmapHilited = nullptr;
607 mScrollLine = 1.0f;
608 mScrollPage = 5.0f;
609
611
612 Move(pos);
613
614 CreatePopWin();
615}
616
618{
619}
620
621wxWindowID LWSlider::GetId()
622{
623 return mID;
624}
625
626void LWSlider::SetId(wxWindowID id)
627{
628 mID = id;
629}
630
632{
633 mName = name;
634 if(mTipPanel)
635 {
636 mTipPanel->Destroy();
637 mTipPanel = nullptr;
638 }
639 CreatePopWin();
640}
641
643{
644 SetDefaultShortcut(true);
645 mDefaultValue = value;
646}
647
649{
650 mDefaultShortcut = value;
651}
652
653void LWSlider::GetScroll(float & line, float & page)
654{
655 line = mScrollLine;
656 page = mScrollPage;
657}
658
659void LWSlider::SetScroll(float line, float page)
660{
661 mScrollLine = line;
662 mScrollPage = page;
663}
664
665void LWSlider::Move(const wxPoint &newpos)
666{
667 mLeft = newpos.x;
668 mTop = newpos.y;
669}
670
671void LWSlider::AdjustSize(const wxSize & sz)
672{
673 mWidth = sz.GetWidth();
674 mHeight = sz.GetHeight();
675
676 if( mBitmap ){
677 mBitmap.reset();
678 }
679 mThumbWidth = 11;
680 mThumbHeight = 20;
681
682 if (mShowLabels || mDrawTicks)
683 {
684 if (mOrientation == wxHORIZONTAL)
685 {
686 mCenterY = mHeight - 9;
687 }
688 else
689 {
690 mCenterX = mWidth - 9;
691 }
692 }
693 else
694 {
695 if (mOrientation == wxHORIZONTAL)
696 {
697 mCenterY = mHeight / 2;
698 }
699 else
700 {
701 mCenterX = mWidth / 2;
702 }
703 }
704
705 if (mOrientation == wxHORIZONTAL)
706 {
708 mRightX = mWidth - mThumbWidth/2 - 1;
710 }
711 else
712 {
713 mTopY = mThumbWidth/2;
714 mBottomY = mHeight - mThumbWidth/2 - 1;
716 }
717
718 Refresh();
719}
720
721void LWSlider::OnPaint(wxDC &dc, bool highlight)
722{
723 // The dc will be a paint DC
725 {
726 DrawToBitmap(dc);
727 }
728
729 //thumbPos should be in pixels
730 int thumbPos = ValueToPosition(mCurrentValue);
731 int thumbOrtho; // position in axis orthogonal to mOrientation
732 if (mOrientation == wxHORIZONTAL){
733 thumbOrtho = mCenterY - (mThumbHeight/2);
734 thumbPos += 1-mThumbWidth/2;
735 }
736 else{
737 thumbOrtho = mCenterX - (mThumbWidth/2);
738 thumbPos += 8-mThumbHeight/2;
739 }
740
741 // Draw the background.
742 // If we are lightweight, this has already been done for us.
743 if( mHW ){
744 dc.SetBackground( *wxTRANSPARENT_BRUSH );
745 dc.Clear();
746 }
747
748 dc.DrawBitmap(*mBitmap, mLeft, mTop, true);
749 const auto &thumbBitmap =
750 highlight ? *mThumbBitmapHilited : *mThumbBitmap;
751 if (mOrientation == wxHORIZONTAL)
752 {
753 dc.DrawBitmap(thumbBitmap, mLeft+thumbPos, mTop+thumbOrtho, true);
754 }
755 else
756 {
757 // TODO: Don't use pixel-count hack in positioning.
758 dc.DrawBitmap(thumbBitmap, mLeft+thumbOrtho-5, mTop+thumbPos, true);
759 }
760
761 if (mTipPanel)
762 {
763 mTipPanel->Update();
764 }
765}
766
767void LWSlider::OnSize( wxSizeEvent & event )
768{
769 AdjustSize(event.GetSize());
770
771 Refresh();
772}
773
774// This function only uses the paintDC to determine what kind of bitmap
775// to draw to and nothing else. It does not draw to the paintDC.
776void LWSlider::DrawToBitmap(wxDC & paintDC)
777{
778 // Get correctly oriented thumb.
779 if (mOrientation == wxVERTICAL){
780 mThumbBitmap = std::make_unique<wxBitmap>(wxBitmap( theTheme.Bitmap( bmpSliderThumbRotated )));
781 mThumbBitmapHilited = std::make_unique<wxBitmap>(wxBitmap( theTheme.Bitmap( bmpSliderThumbRotatedHilited )));
782 }
783 else {
784 mThumbBitmap = std::make_unique<wxBitmap>(wxBitmap( theTheme.Bitmap( bmpSliderThumb )));
785 mThumbBitmapHilited = std::make_unique<wxBitmap>(wxBitmap( theTheme.Bitmap( bmpSliderThumbHilited )));
786 }
787
788 // Now the background bitmap
789 mBitmap = std::make_unique<wxBitmap>();
790 mBitmap->Create(mWidth, mHeight, paintDC);
791
792#if defined(__WXMAC__)
793 mBitmap->UseAlpha();
794#endif
795
796 // Set up the memory DC
797 // We draw to it, not the paintDC.
798 wxMemoryDC dc;
799 dc.SelectObject(*mBitmap);
800
801 dc.SetBackground(wxBrush(mParent->GetBackgroundColour()));
802 dc.Clear();
803
804 // Draw the line along which the thumb moves.
805 AColor::UseThemeColour(&dc, clrSliderMain );
806
807 if (mDrawTrack)
808 {
809 if (mOrientation == wxHORIZONTAL)
810 {
813 }
814 else
815 {
818 }
819 }
820
821 if (mShowLabels)
822 {
823 // Draw +/- or L/R first. We need to draw these before the tick marks.
824 if (mStyle == PAN_SLIDER)
825 {
826 //VJ Vertical PAN_SLIDER currently not handled, forced to horizontal.
827
828 // sliderFontSize is for the tooltip.
829 // we need something smaller here...
830 wxFont labelFont(7, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
831 dc.SetFont(labelFont);
832
833 // Color
834 dc.SetTextForeground(theTheme.Colour(clrTrackPanelText));
835
836 /* i18n-hint: One-letter abbreviation for Left, in the Pan slider */
837 dc.DrawText(_("L"), mLeftX, 0);
838
839 /* i18n-hint: One-letter abbreviation for Right, in the Pan slider */
840 dc.DrawText(_("R"), mRightX - dc.GetTextExtent(_("R")).GetWidth(), 0);
841 }
842 else
843 {
844 // draw the '-' and the '+'
845 // These are drawn with lines, rather tha nwith a font.
846 AColor::UseThemeColour(&dc, clrTrackPanelText);
847
848 if (mOrientation == wxHORIZONTAL)
849 {
851 AColor::Line(dc, mRightX-5, mCenterY-10, mRightX-1, mCenterY-10);
853 }
854 else
855 {
856 // Vertical DB_SLIDER is for gain slider in MixerBoard.
857 // We use a Ruler instead of marks & ticks.
858 // Draw '+' and '-' only for other vertical sliders.
859 if (mStyle != DB_SLIDER)
860 {
862 AColor::Line(dc, mCenterX-12, mTopY+3, mCenterX-8, mTopY+3);
863 AColor::Line(dc, mCenterX-10, mTopY, mCenterX-10, mTopY+5);
864 }
865 }
866 }
867 }
868
869 // Use special colour to indicate no ticks.
870 wxColour TickColour = theTheme.Colour( clrSliderLight );
871 bool bTicks = TickColour != wxColour(60,60,60);
872
873 if( mDrawTicks && bTicks ) {
874 // tick marks
875 int divs = 10;
876 double upp;
877 if (mOrientation == wxHORIZONTAL)
878 {
879 // Bug #2446 - A bit of a hack, but it should suffice.
880 divs = (mWidth - 1) / 10;
881 upp = divs / (double)(mWidthX-1);
882 }
883 else
884 {
885 if (mStyle == DB_SLIDER)
886 divs = mMaxValue - mMinValue + 1;
887 upp = divs / (double)(mHeightY-1);
888 }
889#ifdef OPTIONAL_SLIDER_TICKS
890 double d = 0.0;
891 int int_d = -1;
892 const int kMax = (mOrientation == wxHORIZONTAL) ? mWidthX : mHeightY;
893 for(int p = 0; p <= kMax; p++)
894 {
895 if (((int)d) > int_d)
896 {
897 int_d = (int)d;
898 int tickLength = ((int_d == 0) || (int_d == divs)) ? 5: 3; // longer ticks at extremes
899 AColor::UseThemeColour(&dc, clrSliderLight );
900
901 if (mOrientation == wxHORIZONTAL)
902 {
903 AColor::Line(dc, mLeftX+p, mCenterY-tickLength, mLeftX+p, mCenterY-1); // ticks above
904 }
905 else
906 {
907 AColor::Line(dc, mCenterX-tickLength, mTopY+p, mCenterX-1, mTopY+p); // ticks at left
908 }
909
910 AColor::UseThemeColour(&dc, clrSliderDark );
911
912 if (mOrientation == wxHORIZONTAL)
913 {
914 AColor::Line(dc, mLeftX+p+1, mCenterY-tickLength+1, mLeftX+p+1, mCenterY-1); // ticks above
915 }
916 else
917 {
918 AColor::Line(dc, mCenterX-tickLength+1, mTopY+p+1, mCenterX-1, mTopY+p+1); // ticks at left
919 }
920 }
921 d += upp;
922 }
923#endif
924 }
925
926 dc.SelectObject(wxNullBitmap);
927
928 // safenew, because SetMask takes ownership
929 // We always mask. If we are HeavyWeight, the ASlider draws the
930 // background.
931 if( !mHW )
932 {
933 mBitmap->SetMask(safenew wxMask(*mBitmap, dc.GetBackground().GetColour()));
934 }
935}
936
938{
939 mTipTemplate = tip;
940}
941
942void LWSlider::ShowTip(bool show)
943{
944 if(!mTipPanel)
945 return;
946
947 if(show)
948 {
949 mTipPanel->SetLabel(GetTip(mCurrentValue));
951 mTipPanel->ShowWithoutActivating();
952 }
953 else
954 mTipPanel->Hide();
955}
956
958{
959 if(mTipPanel || mAlwaysHideTip || mParent == nullptr)
960 return;
961
963 mTipPanel->Hide();
964}
965
967{
968 if (mTipPanel)
969 {
970 wxSize sz = mTipPanel->GetSize();
971 wxPoint pt;
972
973 if (mOrientation == wxHORIZONTAL)
974 {
975 pt.x = mLeft + ((mWidth - sz.x) / 2);
976 pt.y = mTop + mHeight + 1;
977 }
978 else
979 {
980 pt.x = mLeft + mWidth + 1;
981 pt.y = mTop + ((mHeight - sz.y) / 2);
982 }
983
984 mTipPanel->SetPos(mParent->ClientToScreen(pt));
985 }
986}
987
989{
990 if (!mTipPanel)
991 {
992 return;
993 }
994
995 mTipPanel->SetLabel(GetTip(mCurrentValue));
996 mTipPanel->Refresh();
997}
998
1000{
1002
1003 if (mTipTemplate.empty())
1004 {
1006
1007 switch(mStyle)
1008 {
1009 case FRAC_SLIDER:
1010 val = Verbatim("%.2f").Format( value );
1011 break;
1012 case PERCENT_SLIDER:
1013 val = Verbatim("%.0f%%").Format(value * 100.0f);
1014 break;
1015
1016 case DB_SLIDER:
1017 /* i18n-hint dB abbreviates decibels */
1018 val = XO("%+.1f dB").Format( value );
1019 break;
1020
1021 case PAN_SLIDER:
1022 if (value == 0.0)
1023 {
1024 val = XO("Center");
1025 }
1026 else
1027 {
1028 const auto v = 100.0f * fabsf(value);
1029 if (value < 0.0)
1030 /* i18n-hint: Stereo pan setting */
1031 val = XO("%.0f%% Left").Format( v );
1032 else
1033 /* i18n-hint: Stereo pan setting */
1034 val = XO("%.0f%% Right").Format( v );
1035 }
1036 break;
1037
1038 case SPEED_SLIDER:
1039 /* i18n-hint: "x" suggests a multiplicative factor */
1040 val = XO("%.2fx").Format( value );
1041 break;
1042
1043#ifdef EXPERIMENTAL_MIDI_OUT
1044 case VEL_SLIDER:
1045 if (value > 0.0f)
1046 // Signed
1047 val = Verbatim("%+d").Format( (int) value );
1048 else
1049 // Zero, or signed negative
1050 val = Verbatim("%d").Format( (int) value );
1051 break;
1052#endif
1053 }
1054
1055 if(!mName.empty())
1056 {
1057 /* i18n-hint: An item name followed by a value, with appropriate separating punctuation */
1058 label = XO("%s: %s").Format( mName, val );
1059 }
1060 else
1061 label = val;
1062 }
1063 else
1064 {
1066 label.Format( value );
1067 }
1068
1069 return label;
1070}
1071
1073{
1074 TranslatableStrings results;
1075
1076 if (mTipTemplate.empty())
1077 {
1078 wxString val;
1079
1080 switch(mStyle)
1081 {
1082 case FRAC_SLIDER:
1083 results.push_back( GetTip( -1.99f ) );
1084 results.push_back( GetTip( +1.99f ) );
1085 break;
1086
1087 case PERCENT_SLIDER:
1088 results.push_back(GetTip(1.0f));
1089
1090 case DB_SLIDER:
1091 results.push_back( GetTip( -99.9f ) );
1092 results.push_back( GetTip( +99.9f ) );
1093 break;
1094
1095 case PAN_SLIDER:
1096 // Don't assume we know which of "Left", "Right", or "Center"
1097 // is the longest string, when localized
1098 results.push_back( GetTip( 0.f ) );
1099 results.push_back( GetTip( +1.f ) );
1100 results.push_back( GetTip( -1.f ) );
1101 break;
1102
1103 case SPEED_SLIDER:
1104 results.push_back( GetTip( 9.99f ) );
1105 break;
1106
1107#ifdef EXPERIMENTAL_MIDI_OUT
1108 case VEL_SLIDER:
1109 results.push_back( GetTip( 999.f ) );
1110 break;
1111#endif
1112 }
1113 }
1114 else
1115 {
1116 results.push_back( GetTip( floor(mMaxValue - mMinValue) + 0.999 ) );
1117 }
1118
1119 return results;
1120}
1121
1123{
1124 return DoShowDialog( mParent->ClientToScreen(wxPoint( mLeft, mTop ) ) );
1125}
1126
1127bool LWSlider::ShowDialog(wxPoint pos)
1128{
1129 return DoShowDialog( pos );
1130}
1131
1132bool LWSlider::DoShowDialog(wxPoint pos)
1133{
1134 float value = mCurrentValue;
1135 bool changed = false;
1136
1137 SliderDialog dlg( NULL,
1138 wxID_ANY,
1139 mName,
1140 pos,
1141 // Bug 2087. wxMin takes care of case where
1142 // slider is vertical (tall and narrow)
1143 wxSize( mWidth, wxMin( mWidth, mHeight) ),
1144 mStyle,
1145 Get(),
1148 this);
1149 if (pos == wxPoint(-1, -1)) {
1150 dlg.Center();
1151 }
1152
1153 changed = (dlg.ShowModal() == wxID_OK);
1154 if( changed )
1155 value = dlg.Get();
1156
1157 // We now expect the pop up dialog to be
1158 // sending updates as we go.
1159 // So this code is needed to possibly restore the old
1160 // value, on a cancel.
1161 if (mCurrentValue != value) {
1162 mCurrentValue = value;
1163 SendUpdate(value);
1164 }
1165
1166 return changed;
1167}
1168
1169void LWSlider::OnMouseEvent(wxMouseEvent & event)
1170{
1171 if (event.Entering())
1172 {
1173 // Display the tooltip in the status bar
1174 auto tip = GetTip(mCurrentValue);
1175 auto pProject = FindProjectFromWindow( mParent );
1176 if (pProject)
1177 ProjectStatus::Get( *pProject ).Set( tip );
1178 Refresh();
1179 }
1180 else if (event.Leaving())
1181 {
1182 if (!mIsDragging)
1183 {
1184 ShowTip(false);
1185 }
1186 auto pProject = FindProjectFromWindow( mParent );
1187 if (pProject)
1188 ProjectStatus::Get( *pProject ).Set({});
1189 Refresh();
1190 }
1191
1192 // Events other than mouse-overs are ignored when we are disabled
1193 if (!mEnabled)
1194 return;
1195
1196 // Windows sends a right button mouse event when you press the context menu
1197 // key, so ignore it.
1198 if ((event.RightDown() && !event.RightIsDown()) ||
1199 (event.RightUp() && event.GetPosition() == wxPoint(-1, -1)))
1200 {
1201 event.Skip(false);
1202 return;
1203 }
1204
1205 float prevValue = mCurrentValue;
1206
1207 // Figure out the thumb position
1208 wxRect r;
1209 if (mOrientation == wxHORIZONTAL)
1210 {
1212 r.y = mTop + (mCenterY - (mThumbHeight / 2));
1213 }
1214 else
1215 {
1216 r.x = mLeft + (mCenterX - (mThumbWidth / 2));
1218 }
1219 r.width = mThumbWidth;
1220 r.height = mThumbHeight;
1221
1222 wxRect tolerantThumbRect = r;
1223 tolerantThumbRect.Inflate(3, 3);
1224
1225 // Should probably use a right click instead/also
1226 if( event.ButtonDClick() && mPopup )
1227 {
1228 //On a double-click, we should pop up a dialog.
1229 DoShowDialog(mParent->ClientToScreen(wxPoint(event.m_x,event.m_y)));
1230 }
1231 else if( event.ButtonDown() )
1232 {
1233 if( mDefaultShortcut && event.ControlDown() )
1234 {
1236 }
1237
1238 if( event.RightDown() ) {
1239 mParent->SetFocus();
1240 }
1241
1242 // Thumb clicked?
1243 //
1244 // Do not change position until first drag. This helps
1245 // with unintended value changes.
1246 if( tolerantThumbRect.Contains( event.GetPosition() ) )
1247 {
1248 // Remember mouse position and current value
1249 mClickPos = (mOrientation == wxHORIZONTAL) ? event.m_x : event.m_y;
1251
1252 mIsDragging = true;
1253 }
1254 // Clicked to set location?
1255 else
1256 {
1259 (mOrientation == wxHORIZONTAL) ? event.m_x : event.m_y,
1260 event.ShiftDown());
1261 }
1262
1263 if (!mParent->HasCapture()) {
1264 mParent->CaptureMouse();
1265 }
1266
1267 ShowTip(true);
1268 }
1269 else if( event.ButtonUp() )
1270 {
1271 mIsDragging = false;
1272 if (mParent->HasCapture())
1273 mParent->ReleaseMouse();
1274
1275 ShowTip(false);
1276 }
1277 else if (event.Dragging() && mIsDragging)
1278 {
1279 if (mOrientation == wxHORIZONTAL)
1280 {
1281 if (event.m_y < (r.y - 2 * r.height) ||
1282 event.m_y > (r.y + 3 * r.height)) {
1283 // If the mouse y coordinate is relatively far from the slider,
1284 // snap back to the original position
1286 }
1287 else {
1288 // Otherwise, move the slider to the right position based
1289 // on the mouse position
1290 mCurrentValue = DragPositionToValue(event.m_x, event.ShiftDown());
1291 }
1292 }
1293 else // (mOrientation == wxVERTICAL)
1294 {
1295 if (event.m_x < (r.x - 2 * r.width) ||
1296 event.m_x > (r.x + 3 * r.width)) {
1297 // If the mouse x coordinate is relatively far from the slider,
1298 // snap back to the original position
1300 }
1301 else {
1302 // Otherwise, move the slider to the right position based
1303 // on the mouse position
1304 mCurrentValue = DragPositionToValue(event.m_y, event.ShiftDown());
1305 }
1306 }
1307 }
1308 else if( event.m_wheelRotation != 0 )
1309 {
1310 //Calculate the number of steps in a given direction this event
1311 //represents (allows for two or more clicks on a single event.)
1312 double steps = event.m_wheelRotation /
1313 (event.m_wheelDelta > 0 ? (double)event.m_wheelDelta : 120.0);
1314
1315 if( steps < 0.0 )
1316 {
1317 Decrease( (float)-steps );
1318 }
1319 else
1320 {
1321 Increase( (float)steps );
1322 }
1324 }
1325
1326 if( prevValue != mCurrentValue )
1328}
1329
1330void LWSlider::OnKeyDown(wxKeyEvent & event)
1331{
1332 if (mEnabled)
1333 {
1334 switch( event.GetKeyCode() )
1335 {
1336 case WXK_TAB:
1337 mParent->Navigate(event.ShiftDown()
1338 ? wxNavigationKeyEvent::IsBackward
1339 : wxNavigationKeyEvent::IsForward);
1340 break;
1341
1342 case WXK_RIGHT:
1343 case WXK_UP:
1346 ShowTip(true);
1347 break;
1348
1349 case WXK_LEFT:
1350 case WXK_DOWN:
1353 ShowTip(true);
1354 break;
1355
1356 case WXK_PAGEUP:
1359 ShowTip(true);
1360 break;
1361
1362 case WXK_PAGEDOWN:
1365 ShowTip(true);
1366 break;
1367
1368 case WXK_HOME:
1370 ShowTip(true);
1371 break;
1372
1373 case WXK_END:
1375 ShowTip(true);
1376 break;
1377
1378 case WXK_RETURN:
1379 case WXK_NUMPAD_ENTER:
1380 {
1381 wxTopLevelWindow *tlw = wxDynamicCast(wxGetTopLevelParent(mParent), wxTopLevelWindow);
1382 wxWindow *def = tlw->GetDefaultItem();
1383 if (def && def->IsEnabled()) {
1384 wxCommandEvent cevent(wxEVT_COMMAND_BUTTON_CLICKED,
1385 def->GetId());
1386 cevent.SetEventObject( def );
1387 mParent->GetEventHandler()->ProcessEvent(cevent);
1388 }
1389 }
1390
1391 default:
1392 // Allow it to propagate
1393 event.Skip();
1394 break;
1395 }
1396 }
1397 else
1398 {
1399 event.Skip();
1400 }
1401}
1402
1403void LWSlider::SetParent(wxWindow* parent)
1404{
1405 mParent = parent;
1406 //VS: create pop win if there is no one, don't re-parent
1407 //as it seem to be a workaround for DC drawing purposes
1408 //(see `WaveTrackControls::GainSlider`)
1409 CreatePopWin();
1410}
1411
1412void LWSlider::SendUpdate( float newValue )
1413{
1414 mCurrentValue = newValue;
1415
1416 FormatPopWin();
1417
1418 Refresh();
1419
1420 // Update the project's status bar as well
1421 if (mTipPanel) {
1422 auto tip = GetTip(mCurrentValue);
1423 auto pProject = FindProjectFromWindow( mParent );
1424 if (pProject)
1425 ProjectStatus::Get( *pProject ).Set( tip );
1426 }
1427
1428 wxCommandEvent e( wxEVT_COMMAND_SLIDER_UPDATED, mID );
1429 int intValue = (int)( ( mCurrentValue - mMinValue ) * 1000.0f /
1430 ( mMaxValue - mMinValue ) );
1431 e.SetInt( intValue );
1432 mParent->GetEventHandler()->ProcessEvent(e);
1433}
1434
1436{
1437 switch(mStyle)
1438 {
1439 case FRAC_SLIDER:
1440 return wxString::Format(wxT("%.0f"), mCurrentValue * 100);
1441 case PERCENT_SLIDER:
1442 return wxString::Format(wxT("%.0f%%"), mCurrentValue * 100.0f);
1443 case DB_SLIDER:
1444 return wxString::Format(wxT("%.0f"), mCurrentValue);
1445 case PAN_SLIDER:
1446 return wxString::Format(wxT("%.0f"), mCurrentValue * 100);
1447 case SPEED_SLIDER:
1448 return wxString::Format(wxT("%.0f"), mCurrentValue * 100 );
1449#ifdef EXPERIMENTAL_MIDI_OUT
1450 case VEL_SLIDER:
1451 return wxString::Format(wxT("%.0f"), mCurrentValue);
1452#endif
1453 default:
1454 return {};
1455 }
1456}
1457
1459{
1460 ShowTip(false);
1461}
1462
1463
1465{
1466 float fRange = mMaxValue - mMinValue;
1467 if (mOrientation == wxHORIZONTAL)
1468 return (int)rint((val - mMinValue) * mWidthX / fRange);
1469 else
1470 // low values at bottom
1471 return (int)rint((mMaxValue - val) * mHeightY / fRange);
1472}
1473
1474void LWSlider::SetSpeed(float speed)
1475{
1476 mSpeed = speed;
1477}
1478
1479// Given the mouse slider coordinate in fromPos, compute the NEW value
1480// of the slider when clicking to set a NEW position.
1481float LWSlider::ClickPositionToValue(int fromPos, bool shiftDown)
1482{
1483 int nSpan;
1484 int pos;
1485 if (mOrientation == wxHORIZONTAL)
1486 {
1487 pos = (fromPos - mLeft - (mThumbWidth / 2));
1488 nSpan = mWidthX;
1489 }
1490 else
1491 {
1492 // wxVERTICAL => Low values at bottom.
1493 pos = mBottomY - fromPos;
1494 nSpan = mHeightY;
1495 }
1496
1497 // MM: Special cases: If position is at the very left or the
1498 // very right (or top/bottom for wxVERTICAL), set minimum/maximum value without other checks
1499 if (pos <= 0)
1500 return mMinValue;
1501 if (pos >= nSpan)
1502 return mMaxValue;
1503
1504 float val = (pos / (float)nSpan)
1506
1507 if (val < mMinValue)
1508 val = mMinValue;
1509 if (val > mMaxValue)
1510 val = mMaxValue;
1511
1512 if (!(mCanUseShift && shiftDown) && mStepValue != STEP_CONTINUOUS)
1513 {
1514 // MM: If shift is not down, or we don't allow usage
1515 // of shift key at all, trim value to steps of
1516 // provided size.
1517 val = (int)(val / mStepValue + 0.5 * (val>0?1.0f:-1.0f)) * mStepValue;
1518 }
1519
1520 return val;
1521}
1522
1523// Given the mouse slider coordinate in fromPos, compute the NEW value
1524// of the slider during a drag.
1525float LWSlider::DragPositionToValue(int fromPos, bool shiftDown)
1526{
1527 int delta = (fromPos - mClickPos);
1528
1529 float speed = mSpeed;
1530 // Precision enhancement for Shift drags
1531 if (mCanUseShift && shiftDown)
1532 speed *= 0.4f;
1533
1534 // wxVERTICAL => Low values at bottom, so throw in the minus sign here with -mHeightY.
1535 float denominator = (mOrientation == wxHORIZONTAL) ? mWidthX : -mHeightY;
1536 float val = mClickValue +
1537 speed * (delta / denominator) * (mMaxValue - mMinValue);
1538
1539 if (val < mMinValue)
1540 val = mMinValue;
1541 if (val > mMaxValue)
1542 val = mMaxValue;
1543
1544 if (!(mCanUseShift && shiftDown) && mStepValue != STEP_CONTINUOUS)
1545 {
1546 // MM: If shift is not down, or we don't allow usage
1547 // of shift key at all, and the slider has not continuous values,
1548 // trim value to steps of provided size.
1549 val = (int)(val / mStepValue + 0.5 * (val>0?1.0f:-1.0f)) * mStepValue;
1550 }
1551
1552 return val;
1553}
1554
1555float LWSlider::Get( bool convert )
1556{
1557 if (mStyle == DB_SLIDER)
1558 return (convert ? DB_TO_LINEAR(mCurrentValue) : mCurrentValue);
1559 else
1560 return mCurrentValue;
1561}
1562
1563void LWSlider::Set(float value)
1564{
1565 if (mIsDragging)
1566 return;
1567 if (mStyle == DB_SLIDER)
1568 mCurrentValue = LINEAR_TO_DB(value);
1569 else
1570 mCurrentValue = value;
1571
1576
1577 Refresh();
1578}
1579
1580void LWSlider::Increase(float steps)
1581{
1582 float stepValue = mStepValue;
1583
1584 if ( stepValue == 0.0 )
1585 {
1586 stepValue = ( mMaxValue - mMinValue ) / 10.0;
1587 }
1588
1589 mCurrentValue += ( steps * stepValue );
1590
1591 if ( mCurrentValue < mMinValue )
1592 {
1594 }
1595 else if ( mCurrentValue > mMaxValue )
1596 {
1598 }
1599
1600 Refresh();
1601}
1602
1603void LWSlider::Decrease(float steps)
1604{
1605 float stepValue = mStepValue;
1606
1607 if ( stepValue == 0.0 )
1608 {
1609 stepValue = ( mMaxValue - mMinValue ) / 10.0;
1610 }
1611
1612 mCurrentValue -= ( steps * stepValue );
1613
1614 if ( mCurrentValue < mMinValue )
1615 {
1617 }
1618 else if ( mCurrentValue > mMaxValue )
1619 {
1621 }
1622
1623 Refresh();
1624}
1625
1627{
1628 if (mHW)
1629 mParent->Refresh(false);
1630}
1631
1633{
1634 mBitmap.reset();
1635 mThumbBitmap.reset();
1636 mThumbBitmapHilited.reset();
1637
1638 Refresh();
1639}
1640
1642{
1643 return mEnabled;
1644}
1645
1646void LWSlider::SetEnabled(bool enabled)
1647{
1648 mEnabled = enabled;
1649
1650 mThumbBitmap.reset();
1651 mThumbBitmapHilited.reset();
1652
1653 Refresh();
1654}
1655
1657{
1658 return mMinValue;
1659}
1660
1662{
1663 return mMaxValue;
1664}
1665
1666//
1667// ASlider
1668//
1669
1670BEGIN_EVENT_TABLE(ASlider, wxPanel)
1671 EVT_KEY_DOWN(ASlider::OnKeyDown)
1672 EVT_MOUSE_EVENTS(ASlider::OnMouseEvent)
1673 EVT_MOUSE_CAPTURE_LOST(ASlider::OnCaptureLost)
1674 EVT_PAINT(ASlider::OnPaint)
1675 EVT_SIZE(ASlider::OnSize)
1676 EVT_ERASE_BACKGROUND(ASlider::OnErase)
1677 EVT_SLIDER(wxID_ANY, ASlider::OnSlider)
1678 EVT_SET_FOCUS(ASlider::OnSetFocus)
1679 EVT_KILL_FOCUS(ASlider::OnKillFocus)
1680 EVT_TIMER(wxID_ANY, ASlider::OnTimer)
1682
1683ASlider::ASlider( wxWindow * parent,
1684 wxWindowID id,
1685 const TranslatableString &name,
1686 const wxPoint & pos,
1687 const wxSize & size,
1688 const Options &options)
1689: wxPanel( parent, id, pos, size, wxWANTS_CHARS )
1690{
1691 //wxColour Col(parent->GetBackgroundColour());
1692 //SetBackgroundColour( Col );
1693 SetBackgroundColour( theTheme.Colour( clrMedium ) );
1694 mLWSlider = std::make_unique<LWSlider>( this,
1695 name,
1696 wxPoint(0,0),
1697 size,
1698 options.style,
1699 options.showLabels,
1700 options.drawTicks,
1701 options.drawTrack,
1702 options.alwaysHideTip,
1703 true, // ASlider is always a heavyweight LWSlider
1704 options.popup,
1705 options.orientation);
1706 mLWSlider->mStepValue = options.stepValue;
1707 mLWSlider->SetId( id );
1708 SetName( name.Translation() );
1709
1710 mSliderIsFocused = false;
1711 mStyle = options.style;
1712
1713 mTimer.SetOwner(this);
1714
1715#if wxUSE_ACCESSIBILITY
1716 SetAccessible( safenew ASliderAx( this ) );
1717#endif
1718
1719 mLWSlider->SetScroll( options.line, options.page );
1720}
1721
1722
1724{
1725 if(HasCapture())
1726 ReleaseMouse();
1727}
1728
1729bool ASlider::SetBackgroundColour(const wxColour& colour)
1730{
1731 auto res = wxPanel::SetBackgroundColour(colour);
1732
1733 if (res && mLWSlider)
1734 {
1735 mLWSlider->Redraw();
1736 }
1737
1738 return res;
1739}
1740
1741void ASlider::OnSlider(wxCommandEvent &event)
1742{
1743
1744 if ( event.GetId() == mLWSlider->GetId() )
1745 {
1746#if wxUSE_ACCESSIBILITY
1747 GetAccessible()->NotifyEvent( wxACC_EVENT_OBJECT_VALUECHANGE,
1748 this,
1749 wxOBJID_CLIENT,
1750 wxACC_SELF );
1751#endif
1752 }
1753
1754 event.Skip();
1755}
1756
1757void ASlider::OnSize(wxSizeEvent &event)
1758{
1759 mLWSlider->OnSize( event );
1760}
1761
1762void ASlider::OnErase(wxEraseEvent & WXUNUSED(event))
1763{
1764 // Ignore it to prevent flashing
1765}
1766
1767void ASlider::OnPaint(wxPaintEvent & WXUNUSED(event))
1768{
1769 wxBufferedPaintDC dc(this);
1770
1771 bool highlighted =
1772 GetClientRect().Contains(
1773 ScreenToClient(
1774 ::wxGetMousePosition() ) );
1775 mLWSlider->OnPaint(dc, highlighted);
1776
1777 if ( mSliderIsFocused )
1778 {
1779 wxRect r( 0, 0, mLWSlider->mWidth, mLWSlider->mHeight );
1780
1781 r.Deflate( 1, 1 );
1782
1783 AColor::DrawFocus( dc, r );
1784 }
1785}
1786
1787void ASlider::OnMouseEvent(wxMouseEvent &event)
1788{
1789 if (event.Entering())
1790 {
1791 mTimer.StartOnce(1000);
1792 }
1793 else if (event.Leaving())
1794 {
1795 mTimer.Stop();
1796 }
1797
1798 mLWSlider->OnMouseEvent(event);
1799}
1800
1801void ASlider::OnCaptureLost(wxMouseCaptureLostEvent & WXUNUSED(event))
1802{
1803 wxMouseEvent e(wxEVT_LEFT_UP);
1804 mLWSlider->OnMouseEvent(e);
1805}
1806
1807void ASlider::OnKeyDown(wxKeyEvent &event)
1808{
1809 mLWSlider->OnKeyDown(event);
1810}
1811
1812void ASlider::OnSetFocus(wxFocusEvent & WXUNUSED(event))
1813{
1814 mSliderIsFocused = true;
1815 Refresh();
1816}
1817
1818void ASlider::OnKillFocus(wxFocusEvent & WXUNUSED(event))
1819{
1820 mLWSlider->OnKillFocus();
1821 mSliderIsFocused = false;
1822 Refresh();
1823}
1824
1825void ASlider::OnTimer(wxTimerEvent & WXUNUSED(event))
1826{
1827 mLWSlider->ShowTip(true);
1828}
1829
1830void ASlider::GetScroll(float & line, float & page)
1831{
1832 mLWSlider->GetScroll(line, page);
1833}
1834
1835void ASlider::SetScroll(float line, float page)
1836{
1837 mLWSlider->SetScroll(line, page);
1838}
1839
1841{
1842 mLWSlider->SetToolTipTemplate(tip);
1843}
1844
1845float ASlider::Get( bool convert )
1846{
1847 return mLWSlider->Get( convert );
1848}
1849
1850void ASlider::Set(float value)
1851{
1852 mLWSlider->Set(value);
1853}
1854
1855void ASlider::Increase(float steps)
1856{
1857 mLWSlider->Increase(steps);
1858}
1859
1860void ASlider::Decrease(float steps)
1861{
1862 mLWSlider->Decrease(steps);
1863}
1864
1865bool ASlider::ShowDialog(wxPoint pos)
1866{
1867 return mLWSlider->ShowDialog(pos);
1868}
1869
1870void ASlider::SetSpeed(float speed)
1871{
1872 mLWSlider->SetSpeed(speed);
1873}
1874
1875bool ASlider::Enable(bool enable)
1876{
1877 if (mLWSlider->GetEnabled() == enable)
1878 return false;
1879
1880 mLWSlider->SetEnabled(enable);
1881
1882 wxWindow::Enable(enable);
1883
1884 return true;
1885}
1886
1888{
1889 return mLWSlider->GetEnabled();
1890}
1891
1892bool ASlider::s_AcceptsFocus{ false };
1893
1895 s_AcceptsFocus = true;
1896 return TempAllowFocus{ &s_AcceptsFocus };
1897}
1898
1899// This compensates for a but in wxWidgets 3.0.2 for mac:
1900// Couldn't set focus from keyboard when AcceptsFocus returns false;
1901// this bypasses that limitation
1903{
1904 auto temp = TemporarilyAllowFocus();
1905 SetFocus();
1906}
1907
1908#if wxUSE_ACCESSIBILITY
1909
1910ASliderAx::ASliderAx( wxWindow * window ) :
1911 WindowAccessible( window )
1912{
1913}
1914
1915ASliderAx::~ASliderAx()
1916{
1917}
1918
1919// Retrieves the address of an IDispatch interface for the specified child.
1920// All objects must support this property.
1921wxAccStatus ASliderAx::GetChild( int childId, wxAccessible** child )
1922{
1923 if ( childId == wxACC_SELF )
1924 {
1925 *child = this;
1926 }
1927 else
1928 {
1929 *child = NULL;
1930 }
1931
1932 return wxACC_OK;
1933}
1934
1935// Gets the number of children.
1936wxAccStatus ASliderAx::GetChildCount(int* childCount)
1937{
1938 *childCount = 3;
1939
1940 return wxACC_OK;
1941}
1942
1943// Gets the default action for this object (0) or > 0 (the action for a child).
1944// Return wxACC_OK even if there is no action. actionName is the action, or the empty
1945// string if there is no action.
1946// The retrieved string describes the action that is performed on an object,
1947// not what the object does as a result. For example, a toolbar button that prints
1948// a document has a default action of "Press" rather than "Prints the current document."
1949wxAccStatus ASliderAx::GetDefaultAction( int WXUNUSED(childId), wxString *actionName )
1950{
1951 actionName->clear();
1952
1953 return wxACC_OK;
1954}
1955
1956// Returns the description for this object or a child.
1957wxAccStatus ASliderAx::GetDescription( int WXUNUSED(childId), wxString *description )
1958{
1959 description->clear();
1960
1961 return wxACC_OK;
1962}
1963
1964// Gets the window with the keyboard focus.
1965// If childId is 0 and child is NULL, no object in
1966// this subhierarchy has the focus.
1967// If this object has the focus, child should be 'this'.
1968wxAccStatus ASliderAx::GetFocus(int* childId, wxAccessible** child)
1969{
1970 *childId = 0;
1971 *child = this;
1972
1973 return wxACC_OK;
1974}
1975
1976// Returns help text for this object or a child, similar to tooltip text.
1977wxAccStatus ASliderAx::GetHelpText( int WXUNUSED(childId), wxString *helpText )
1978{
1979 helpText->clear();
1980
1981 return wxACC_OK;
1982}
1983
1984// Returns the keyboard shortcut for this object or child.
1985// Return e.g. ALT+K
1986wxAccStatus ASliderAx::GetKeyboardShortcut( int WXUNUSED(childId), wxString *shortcut )
1987{
1988 shortcut->clear();
1989
1990 return wxACC_OK;
1991}
1992
1993// Returns the rectangle for this object (id = 0) or a child element (id > 0).
1994// rect is in screen coordinates.
1995wxAccStatus ASliderAx::GetLocation( wxRect& rect, int WXUNUSED(elementId) )
1996{
1997 ASlider *as = wxDynamicCast( GetWindow(), ASlider );
1998
1999 rect = as->GetRect();
2000 rect.SetPosition( as->GetParent()->ClientToScreen( rect.GetPosition() ) );
2001
2002 return wxACC_OK;
2003}
2004
2005// Gets the name of the specified object.
2006wxAccStatus ASliderAx::GetName(int WXUNUSED(childId), wxString* name)
2007{
2008 ASlider *as = wxDynamicCast( GetWindow(), ASlider );
2009
2010 *name = as->GetName();
2011
2012 return wxACC_OK;
2013}
2014
2015// Returns a role constant.
2016wxAccStatus ASliderAx::GetRole(int childId, wxAccRole* role)
2017{
2018 switch( childId )
2019 {
2020 case 0:
2021 *role = wxROLE_SYSTEM_SLIDER;
2022 break;
2023
2024 case 1:
2025 case 3:
2026 *role = wxROLE_SYSTEM_PUSHBUTTON;
2027 break;
2028
2029 case 2:
2030 *role = wxROLE_SYSTEM_INDICATOR;
2031 break;
2032 }
2033
2034 return wxACC_OK;
2035}
2036
2037// Gets a variant representing the selected children
2038// of this object.
2039// Acceptable values:
2040// - a null variant (IsNull() returns TRUE)
2041// - a list variant (GetType() == wxT("list"))
2042// - an integer representing the selected child element,
2043// or 0 if this object is selected (GetType() == wxT("long"))
2044// - a "void*" pointer to a wxAccessible child object
2045wxAccStatus ASliderAx::GetSelections( wxVariant * WXUNUSED(selections) )
2046{
2047 return wxACC_NOT_IMPLEMENTED;
2048}
2049
2050// Returns a state constant.
2051wxAccStatus ASliderAx::GetState(int childId, long* state)
2052{
2053 ASlider *as = wxDynamicCast( GetWindow(), ASlider );
2054
2055 switch( childId )
2056 {
2057 case 0:
2058 *state = wxACC_STATE_SYSTEM_FOCUSABLE;
2059 break;
2060
2061 case 1:
2062 if ( as->mLWSlider->mCurrentValue == as->mLWSlider->mMinValue )
2063 {
2064 *state = wxACC_STATE_SYSTEM_INVISIBLE;
2065 }
2066 break;
2067
2068 case 3:
2069 if ( as->mLWSlider->mCurrentValue == as->mLWSlider->mMaxValue )
2070 {
2071 *state = wxACC_STATE_SYSTEM_INVISIBLE;
2072 }
2073 break;
2074 }
2075
2076 // Do not use mSliderIsFocused is not set until after this method
2077 // is called.
2078 *state |= ( as == wxWindow::FindFocus() ? wxACC_STATE_SYSTEM_FOCUSED : 0 );
2079
2080 return wxACC_OK;
2081}
2082
2083// Returns a localized string representing the value for the object
2084// or child.
2085wxAccStatus ASliderAx::GetValue(int childId, wxString* strValue)
2086{
2087 ASlider *as = wxDynamicCast( GetWindow(), ASlider );
2088
2089 if ( childId == 0 )
2090 {
2091 *strValue = as->mLWSlider->GetStringValue();
2092 return wxACC_OK;
2093 }
2094 return wxACC_NOT_SUPPORTED;
2095}
2096
2097#endif
const int sliderFontSize
Definition: ASlider.cpp:135
static const wxPoint2DDouble enabledLeftEnd[]
Definition: ASlider.cpp:418
static const wxPoint2DDouble disabledRightEnd[]
Definition: ASlider.cpp:469
static const wxPoint2DDouble enabledLeftBegin[]
Definition: ASlider.cpp:410
END_EVENT_TABLE()
static const wxPoint2DDouble disabledRightBegin[]
Definition: ASlider.cpp:464
static const wxPoint2DDouble disabledStripesBegin[]
Definition: ASlider.cpp:444
static const wxPoint2DDouble enabledRightBegin[]
Definition: ASlider.cpp:428
static const wxPoint2DDouble enabledRightEnd[]
Definition: ASlider.cpp:435
static const wxPoint2DDouble disabledStripesEnd[]
Definition: ASlider.cpp:453
static const wxPoint2DDouble outer[]
Definition: ASlider.cpp:397
#define VEL_SLIDER
Definition: ASlider.h:37
#define DB_SLIDER
Definition: ASlider.h:33
#define FRAC_SLIDER
Definition: ASlider.h:32
#define STEP_CONTINUOUS
Definition: ASlider.h:54
#define PERCENT_SLIDER
Definition: ASlider.h:39
#define SPEED_SLIDER
Definition: ASlider.h:35
#define PAN_SLIDER
Definition: ASlider.h:34
#define VEL_MAX
Definition: ASlider.h:48
#define VEL_MIN
Definition: ASlider.h:47
wxEVT_COMMAND_BUTTON_CLICKED
wxT("CloseDown"))
const TranslatableString name
Definition: Distortion.cpp:76
XO("Cut/Copy/Paste")
#define _(s)
Definition: Internat.h:73
#define safenew
Definition: MemoryX.h:10
#define LINEAR_TO_DB(x)
Definition: MemoryX.h:561
#define DB_TO_LINEAR(x)
Definition: MemoryX.h:560
static const auto title
AudacityProject * FindProjectFromWindow(wxWindow *pWindow)
@ eIsCreating
Definition: ShuttleGui.h:37
@ eOkButton
Definition: ShuttleGui.h:594
@ eCancelButton
Definition: ShuttleGui.h:595
TranslatableString label
Definition: TagsEditor.cpp:164
THEME_API Theme theTheme
Definition: Theme.cpp:82
#define S(N)
Definition: ToChars.cpp:64
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
std::vector< TranslatableString > TranslatableStrings
int id
static void Line(wxDC &dc, wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
Definition: AColor.cpp:187
static wxPen tooltipPen
Definition: AColor.h:132
static wxBrush tooltipBrush
Definition: AColor.h:133
static void UseThemeColour(wxDC *dc, int iBrush, int iPen=-1, int alpha=255)
Definition: AColor.cpp:372
static void DrawFocus(wxDC &dc, wxRect &r)
Definition: AColor.cpp:235
ASlider is a custom slider, allowing for a slicker look and feel.
Definition: ASlider.h:260
static TempAllowFocus TemporarilyAllowFocus()
Definition: ASlider.cpp:1894
void OnSetFocus(wxFocusEvent &event)
Definition: ASlider.cpp:1812
void Set(float value)
Definition: ASlider.cpp:1850
void SetFocusFromKbd() override
Definition: ASlider.cpp:1902
void SetSpeed(float speed)
Definition: ASlider.cpp:1870
void GetScroll(float &line, float &page)
Definition: ASlider.cpp:1830
bool ShowDialog(wxPoint pos=wxPoint(-1, -1))
Definition: ASlider.cpp:1865
std::unique_ptr< LWSlider > mLWSlider
Definition: ASlider.h:348
void OnKeyDown(wxKeyEvent &event)
Definition: ASlider.cpp:1807
bool IsEnabled() const
Definition: ASlider.cpp:1887
void OnTimer(wxTimerEvent &event)
Definition: ASlider.cpp:1825
std::unique_ptr< bool, Resetter > TempAllowFocus
Definition: ASlider.h:342
void OnKillFocus(wxFocusEvent &event)
Definition: ASlider.cpp:1818
void Increase(float steps)
Definition: ASlider.cpp:1855
void OnCaptureLost(wxMouseCaptureLostEvent &event)
Definition: ASlider.cpp:1801
virtual ~ASlider()
Definition: ASlider.cpp:1723
void Decrease(float steps)
Definition: ASlider.cpp:1860
void OnSlider(wxCommandEvent &event)
Definition: ASlider.cpp:1741
void SetToolTipTemplate(const TranslatableString &tip)
Definition: ASlider.cpp:1840
void OnMouseEvent(wxMouseEvent &event)
Definition: ASlider.cpp:1787
static bool s_AcceptsFocus
Definition: ASlider.h:340
bool Enable(bool enable=true) override
Definition: ASlider.cpp:1875
void OnPaint(wxPaintEvent &event)
Definition: ASlider.cpp:1767
bool mSliderIsFocused
Definition: ASlider.h:349
bool SetBackgroundColour(const wxColour &colour) override
Definition: ASlider.cpp:1729
wxTimer mTimer
Definition: ASlider.h:350
void OnErase(wxEraseEvent &event)
Definition: ASlider.cpp:1762
void SetScroll(float line, float page)
Definition: ASlider.cpp:1835
void OnSize(wxSizeEvent &event)
Definition: ASlider.cpp:1757
float Get(bool convert=true)
Definition: ASlider.cpp:1845
Lightweight version of ASlider. In other words it does not have a window permanently associated with ...
Definition: ASlider.h:64
void Set(float value)
Definition: ASlider.cpp:1563
void DrawToBitmap(wxDC &dc)
Definition: ASlider.cpp:776
void OnPaint(wxDC &dc, bool highlighted)
Definition: ASlider.cpp:721
float mCurrentValue
Definition: ASlider.h:238
int mCenterX
Definition: ASlider.h:217
float mDefaultValue
Definition: ASlider.h:241
int mLeft
Definition: ASlider.h:203
float mMinValue
Definition: ASlider.h:230
int mThumbWidth
Definition: ASlider.h:224
bool mCanUseShift
Definition: ASlider.h:243
void OnKillFocus()
Definition: ASlider.cpp:1458
float GetMinValue() const
Definition: ASlider.cpp:1656
std::unique_ptr< wxBitmap > mThumbBitmap
Definition: ASlider.h:252
float mClickValue
Definition: ASlider.h:227
void SetEnabled(bool enabled)
Definition: ASlider.cpp:1646
void Init(wxWindow *parent, const TranslatableString &name, const wxPoint &pos, const wxSize &size, float minValue, float maxValue, float stepValue, bool canUseShift, int style, bool showlabels, bool drawticks, bool drawtrack, bool alwayshidetip, bool heavyweight, bool popup, float speed, int orientation=wxHORIZONTAL)
Definition: ASlider.cpp:565
bool mPopup
Definition: ASlider.h:201
int mHeightY
Definition: ASlider.h:221
void Redraw()
Definition: ASlider.cpp:1632
bool mAlwaysHideTip
Definition: ASlider.h:198
float mMaxValue
Definition: ASlider.h:231
void ShowTip(bool show)
Definition: ASlider.cpp:942
TranslatableString mTipTemplate
Definition: ASlider.h:248
bool mShowLabels
Definition: ASlider.h:194
void Refresh()
Definition: ASlider.cpp:1626
void OnMouseEvent(wxMouseEvent &event)
Definition: ASlider.cpp:1169
void Decrease(float steps)
Definition: ASlider.cpp:1603
int mTopY
Definition: ASlider.h:219
TranslatableString mName
Definition: ASlider.h:254
void CreatePopWin()
Definition: ASlider.cpp:957
void AdjustSize(const wxSize &sz)
Definition: ASlider.cpp:671
void Increase(float steps)
Definition: ASlider.cpp:1580
float Get(bool convert=true)
Definition: ASlider.cpp:1555
void SetDefaultValue(float value)
Definition: ASlider.cpp:642
wxString GetStringValue() const
Definition: ASlider.cpp:1435
void OnKeyDown(wxKeyEvent &event)
Definition: ASlider.cpp:1330
int ValueToPosition(float val)
Definition: ASlider.cpp:1464
int mBottomY
Definition: ASlider.h:220
TranslatableStrings GetWidestTips() const
Definition: ASlider.cpp:1072
int mLeftX
Definition: ASlider.h:212
int mCenterY
Definition: ASlider.h:210
int mStyle
Definition: ASlider.h:191
int mHeight
Definition: ASlider.h:207
bool mEnabled
Definition: ASlider.h:256
wxWindow * mParent
Definition: ASlider.h:189
std::unique_ptr< wxBitmap > mBitmap
Definition: ASlider.h:252
void GetScroll(float &line, float &page)
Definition: ASlider.cpp:653
void SetSpeed(float speed)
Definition: ASlider.cpp:1474
wxWindowID mID
Definition: ASlider.h:245
wxWindowID GetId()
Definition: ASlider.cpp:621
bool mIsDragging
Definition: ASlider.h:250
bool GetEnabled() const
Definition: ASlider.cpp:1641
void SetDefaultShortcut(bool value)
Definition: ASlider.cpp:648
int mRightX
Definition: ASlider.h:213
std::unique_ptr< wxBitmap > mThumbBitmapHilited
Definition: ASlider.h:252
float GetMaxValue() const
Definition: ASlider.cpp:1661
void SendUpdate(float newValue)
Definition: ASlider.cpp:1412
int mOrientation
Definition: ASlider.h:192
int mTop
Definition: ASlider.h:204
void SetName(const TranslatableString &name)
Definition: ASlider.cpp:631
float DragPositionToValue(int fromPos, bool shiftDown)
Definition: ASlider.cpp:1525
void SetScroll(float line, float page)
Definition: ASlider.cpp:659
bool DoShowDialog(wxPoint pos)
Definition: ASlider.cpp:1132
virtual ~LWSlider()
Definition: ASlider.cpp:617
void OnSize(wxSizeEvent &event)
Definition: ASlider.cpp:767
void SetId(wxWindowID id)
Definition: ASlider.cpp:626
bool mDrawTicks
Definition: ASlider.h:195
void SetToolTipTemplate(const TranslatableString &tip)
Definition: ASlider.cpp:937
float mSpeed
Definition: ASlider.h:233
bool ShowDialog()
Definition: ASlider.cpp:1122
bool mDefaultShortcut
Definition: ASlider.h:240
float mStepValue
Definition: ASlider.h:232
float mScrollPage
Definition: ASlider.h:236
void Move(const wxPoint &newpos)
Definition: ASlider.cpp:665
float mScrollLine
Definition: ASlider.h:235
bool mHW
Definition: ASlider.h:200
int mWidth
Definition: ASlider.h:206
int mWidthX
Definition: ASlider.h:214
bool mDrawTrack
Definition: ASlider.h:196
void FormatPopWin()
Definition: ASlider.cpp:988
void SetPopWinPosition()
Definition: ASlider.cpp:966
void SetParent(wxWindow *parent)
Definition: ASlider.cpp:1403
LWSlider(wxWindow *parent, const TranslatableString &name, const wxPoint &pos, const wxSize &size, float minValue, float maxValue, float stepValue, bool canUseShift, int style, bool showlabels=true, bool drawticks=true, bool drawtrack=true, bool alwayshidetip=false, bool heavyweight=false, bool popup=true, int orientation=wxHORIZONTAL)
Definition: ASlider.cpp:476
int mThumbHeight
Definition: ASlider.h:225
float ClickPositionToValue(int fromPos, bool shiftDown)
Definition: ASlider.cpp:1481
wxWeakRef< TipWindow > mTipPanel
Definition: ASlider.h:247
int mClickPos
Definition: ASlider.h:228
TranslatableString GetTip(float value) const
Definition: ASlider.cpp:999
static ProjectStatus & Get(AudacityProject &project)
void Set(const TranslatableString &msg, StatusBarField field=mainStatusBarField)
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:625
Pop up dialog used with an LWSlider.
Definition: ASlider.h:368
bool TransferDataFromWindow() override
Definition: ASlider.cpp:353
float mValue
Definition: ASlider.h:394
LWSlider * mpOrigin
Definition: ASlider.h:393
int mStyle
Definition: ASlider.h:392
void OnSlider(wxCommandEvent &event)
Definition: ASlider.cpp:372
float Get()
Definition: ASlider.cpp:387
void OnTextChange(wxCommandEvent &event)
Definition: ASlider.cpp:378
wxTextCtrl * mTextCtrl
Definition: ASlider.h:391
ASlider * mSlider
Definition: ASlider.h:390
bool TransferDataToWindow() override
Definition: ASlider.cpp:337
wxColour & Colour(int iIndex)
wxBitmap & Bitmap(int iIndex)
A wxPopupWindow used to give the numerical value of an LWSlider or ASlider.
Definition: ASlider.cpp:149
void OnPaint(wxPaintEvent &event)
Definition: ASlider.cpp:232
int mHeight
Definition: ASlider.cpp:164
virtual ~TipWindow()
Definition: ASlider.cpp:152
TipWindow(wxWindow *parent, const TranslatableStrings &labels)
Definition: ASlider.cpp:174
wxFont mFont
Definition: ASlider.cpp:165
int mWidth
Definition: ASlider.cpp:163
void SetLabel(const TranslatableString &label)
Definition: ASlider.cpp:227
TranslatableString mLabel
Definition: ASlider.cpp:162
void SetPos(const wxPoint &pos)
Definition: ASlider.cpp:222
wxSize GetSize() const
Definition: ASlider.cpp:217
Holds a msgid for the translation catalog; may also bind format arguments.
wxString Translation() const
TranslatableString & Format(Args &&...args) &
Capture variadic format arguments (by copy) when there is no plural.
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
std::unique_ptr< WindowPlacement > FindFocus()
Find the window that is accepting keyboard input, if any.
Definition: BasicUI.h:343
Options & Style(int s)
Definition: ASlider.h:280
Options & Page(float p)
Definition: ASlider.h:292
Options & Line(float l)
Definition: ASlider.h:291
Options & Popup(bool p)
Definition: ASlider.h:287