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