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