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