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