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  cevent.SetEventObject( def );
1327  mParent->GetEventHandler()->ProcessEvent(cevent);
1328  }
1329  }
1330 
1331  default:
1332  // Allow it to propagate
1333  event.Skip();
1334  break;
1335  }
1336  }
1337  else
1338  {
1339  event.Skip();
1340  }
1341 }
1342 
1343 void LWSlider::SendUpdate( float newValue )
1344 {
1345  mCurrentValue = newValue;
1346 
1347  FormatPopWin();
1348 
1349  Refresh();
1350 
1351  // Update the project's status bar as well
1352  if (mTipPanel) {
1353  auto tip = GetTip(mCurrentValue);
1354  auto pProject = FindProjectFromWindow( mParent );
1355  if (pProject)
1356  ProjectStatus::Get( *pProject ).Set( tip );
1357  }
1358 
1359  wxCommandEvent e( wxEVT_COMMAND_SLIDER_UPDATED, mID );
1360  int intValue = (int)( ( mCurrentValue - mMinValue ) * 1000.0f /
1361  ( mMaxValue - mMinValue ) );
1362  e.SetInt( intValue );
1363  mParent->GetEventHandler()->ProcessEvent(e);
1364 }
1365 
1367 {
1368  float fRange = mMaxValue - mMinValue;
1369  if (mOrientation == wxHORIZONTAL)
1370  return (int)rint((val - mMinValue) * mWidthX / fRange);
1371  else
1372  // low values at bottom
1373  return (int)rint((mMaxValue - val) * mHeightY / fRange);
1374 }
1375 
1376 void LWSlider::SetSpeed(float speed)
1377 {
1378  mSpeed = speed;
1379 }
1380 
1381 // Given the mouse slider coordinate in fromPos, compute the NEW value
1382 // of the slider when clicking to set a NEW position.
1383 float LWSlider::ClickPositionToValue(int fromPos, bool shiftDown)
1384 {
1385  int nSpan;
1386  int pos;
1387  if (mOrientation == wxHORIZONTAL)
1388  {
1389  pos = (fromPos - mLeft - (mThumbWidth / 2));
1390  nSpan = mWidthX;
1391  }
1392  else
1393  {
1394  // wxVERTICAL => Low values at bottom.
1395  pos = mBottomY - fromPos;
1396  nSpan = mHeightY;
1397  }
1398 
1399  // MM: Special cases: If position is at the very left or the
1400  // very right (or top/bottom for wxVERTICAL), set minimum/maximum value without other checks
1401  if (pos <= 0)
1402  return mMinValue;
1403  if (pos >= nSpan)
1404  return mMaxValue;
1405 
1406  float val = (pos / (float)nSpan)
1407  * (mMaxValue - mMinValue) + mMinValue;
1408 
1409  if (val < mMinValue)
1410  val = mMinValue;
1411  if (val > mMaxValue)
1412  val = mMaxValue;
1413 
1414  if (!(mCanUseShift && shiftDown) && mStepValue != STEP_CONTINUOUS)
1415  {
1416  // MM: If shift is not down, or we don't allow usage
1417  // of shift key at all, trim value to steps of
1418  // provided size.
1419  val = (int)(val / mStepValue + 0.5 * (val>0?1.0f:-1.0f)) * mStepValue;
1420  }
1421 
1422  return val;
1423 }
1424 
1425 // Given the mouse slider coordinate in fromPos, compute the NEW value
1426 // of the slider during a drag.
1427 float LWSlider::DragPositionToValue(int fromPos, bool shiftDown)
1428 {
1429  int delta = (fromPos - mClickPos);
1430 
1431  float speed = mSpeed;
1432  // Precision enhancement for Shift drags
1433  if (mCanUseShift && shiftDown)
1434  speed *= 0.4f;
1435 
1436  // wxVERTICAL => Low values at bottom, so throw in the minus sign here with -mHeightY.
1437  float denominator = (mOrientation == wxHORIZONTAL) ? mWidthX : -mHeightY;
1438  float val = mClickValue +
1439  speed * (delta / denominator) * (mMaxValue - mMinValue);
1440 
1441  if (val < mMinValue)
1442  val = mMinValue;
1443  if (val > mMaxValue)
1444  val = mMaxValue;
1445 
1446  if (!(mCanUseShift && shiftDown) && mStepValue != STEP_CONTINUOUS)
1447  {
1448  // MM: If shift is not down, or we don't allow usage
1449  // of shift key at all, and the slider has not continuous values,
1450  // trim value to steps of provided size.
1451  val = (int)(val / mStepValue + 0.5 * (val>0?1.0f:-1.0f)) * mStepValue;
1452  }
1453 
1454  return val;
1455 }
1456 
1457 float LWSlider::Get( bool convert )
1458 {
1459  if (mStyle == DB_SLIDER)
1460  return (convert ? DB_TO_LINEAR(mCurrentValue) : mCurrentValue);
1461  else
1462  return mCurrentValue;
1463 }
1464 
1465 void LWSlider::Set(float value)
1466 {
1467  if (mIsDragging)
1468  return;
1469  if (mStyle == DB_SLIDER)
1470  mCurrentValue = LINEAR_TO_DB(value);
1471  else
1472  mCurrentValue = value;
1473 
1474  if (mCurrentValue < mMinValue)
1476  if (mCurrentValue > mMaxValue)
1478 
1479  Refresh();
1480 }
1481 
1482 void LWSlider::Increase(float steps)
1483 {
1484  float stepValue = mStepValue;
1485 
1486  if ( stepValue == 0.0 )
1487  {
1488  stepValue = ( mMaxValue - mMinValue ) / 10.0;
1489  }
1490 
1491  mCurrentValue += ( steps * stepValue );
1492 
1493  if ( mCurrentValue < mMinValue )
1494  {
1496  }
1497  else if ( mCurrentValue > mMaxValue )
1498  {
1500  }
1501 
1502  Refresh();
1503 }
1504 
1505 void LWSlider::Decrease(float steps)
1506 {
1507  float stepValue = mStepValue;
1508 
1509  if ( stepValue == 0.0 )
1510  {
1511  stepValue = ( mMaxValue - mMinValue ) / 10.0;
1512  }
1513 
1514  mCurrentValue -= ( steps * stepValue );
1515 
1516  if ( mCurrentValue < mMinValue )
1517  {
1519  }
1520  else if ( mCurrentValue > mMaxValue )
1521  {
1523  }
1524 
1525  Refresh();
1526 }
1527 
1529 {
1530  if (mHW)
1531  mParent->Refresh(false);
1532 }
1533 
1535 {
1536  mBitmap.reset();
1537  mThumbBitmap.reset();
1538  mThumbBitmapHilited.reset();
1539 
1540  Refresh();
1541 }
1542 
1544 {
1545  return mEnabled;
1546 }
1547 
1548 void LWSlider::SetEnabled(bool enabled)
1549 {
1550  mEnabled = enabled;
1551 
1552  mThumbBitmap.reset();
1553  mThumbBitmapHilited.reset();
1554 
1555  Refresh();
1556 }
1557 
1559 {
1560  return mMinValue;
1561 }
1562 
1564 {
1565  return mMaxValue;
1566 }
1567 
1568 //
1569 // ASlider
1570 //
1571 
1572 BEGIN_EVENT_TABLE(ASlider, wxPanel)
1573  EVT_KEY_DOWN(ASlider::OnKeyDown)
1574  EVT_MOUSE_EVENTS(ASlider::OnMouseEvent)
1575  EVT_MOUSE_CAPTURE_LOST(ASlider::OnCaptureLost)
1576  EVT_PAINT(ASlider::OnPaint)
1577  EVT_SIZE(ASlider::OnSize)
1578  EVT_ERASE_BACKGROUND(ASlider::OnErase)
1579  EVT_SLIDER(wxID_ANY, ASlider::OnSlider)
1580  EVT_SET_FOCUS(ASlider::OnSetFocus)
1581  EVT_KILL_FOCUS(ASlider::OnKillFocus)
1582  EVT_TIMER(wxID_ANY, ASlider::OnTimer)
1584 
1585 ASlider::ASlider( wxWindow * parent,
1586  wxWindowID id,
1587  const TranslatableString &name,
1588  const wxPoint & pos,
1589  const wxSize & size,
1590  const Options &options)
1591 : wxPanel( parent, id, pos, size, wxWANTS_CHARS )
1592 {
1593  //wxColour Col(parent->GetBackgroundColour());
1594  //SetBackgroundColour( Col );
1595  SetBackgroundColour( theTheme.Colour( clrMedium ) );
1596  mLWSlider = std::make_unique<LWSlider>( this,
1597  name,
1598  wxPoint(0,0),
1599  size,
1600  options.style,
1601  true, // ASlider is always a heavyweight LWSlider
1602  options.popup,
1603  options.orientation);
1604  mLWSlider->mStepValue = options.stepValue;
1605  mLWSlider->SetId( id );
1606  SetName( name.Translation() );
1607 
1608  mSliderIsFocused = false;
1609  mStyle = options.style;
1610 
1611  mTimer.SetOwner(this);
1612 
1613 #if wxUSE_ACCESSIBILITY
1614  SetAccessible( safenew ASliderAx( this ) );
1615 #endif
1616 
1617  mLWSlider->SetScroll( options.line, options.page );
1618 }
1619 
1620 
1622 {
1623  if(HasCapture())
1624  ReleaseMouse();
1625 }
1626 
1627 bool ASlider::SetBackgroundColour(const wxColour& colour)
1628 {
1629  auto res = wxPanel::SetBackgroundColour(colour);
1630 
1631  if (res && mLWSlider)
1632  {
1633  mLWSlider->Redraw();
1634  }
1635 
1636  return res;
1637 }
1638 
1639 void ASlider::OnSlider(wxCommandEvent &event)
1640 {
1641 
1642  if ( event.GetId() == mLWSlider->GetId() )
1643  {
1644 #if wxUSE_ACCESSIBILITY
1645  GetAccessible()->NotifyEvent( wxACC_EVENT_OBJECT_VALUECHANGE,
1646  this,
1647  wxOBJID_CLIENT,
1648  wxACC_SELF );
1649 #endif
1650  }
1651 
1652  event.Skip();
1653 }
1654 
1655 void ASlider::OnSize(wxSizeEvent &event)
1656 {
1657  mLWSlider->OnSize( event );
1658 }
1659 
1660 void ASlider::OnErase(wxEraseEvent & WXUNUSED(event))
1661 {
1662  // Ignore it to prevent flashing
1663 }
1664 
1665 void ASlider::OnPaint(wxPaintEvent & WXUNUSED(event))
1666 {
1667  wxBufferedPaintDC dc(this);
1668 
1669  bool highlighted =
1670  GetClientRect().Contains(
1671  ScreenToClient(
1672  ::wxGetMousePosition() ) );
1673  mLWSlider->OnPaint(dc, highlighted);
1674 
1675  if ( mSliderIsFocused )
1676  {
1677  wxRect r( 0, 0, mLWSlider->mWidth, mLWSlider->mHeight );
1678 
1679  r.Deflate( 1, 1 );
1680 
1681  AColor::DrawFocus( dc, r );
1682  }
1683 }
1684 
1685 void ASlider::OnMouseEvent(wxMouseEvent &event)
1686 {
1687  if (event.Entering())
1688  {
1689  mTimer.StartOnce(1000);
1690  }
1691  else if (event.Leaving())
1692  {
1693  mTimer.Stop();
1694  }
1695 
1696  mLWSlider->OnMouseEvent(event);
1697 }
1698 
1699 void ASlider::OnCaptureLost(wxMouseCaptureLostEvent & WXUNUSED(event))
1700 {
1701  wxMouseEvent e(wxEVT_LEFT_UP);
1702  mLWSlider->OnMouseEvent(e);
1703 }
1704 
1705 void ASlider::OnKeyDown(wxKeyEvent &event)
1706 {
1707  mLWSlider->OnKeyDown(event);
1708 }
1709 
1710 void ASlider::OnSetFocus(wxFocusEvent & WXUNUSED(event))
1711 {
1712  mSliderIsFocused = true;
1713  Refresh();
1714 }
1715 
1716 void ASlider::OnKillFocus(wxFocusEvent & WXUNUSED(event))
1717 {
1718  mSliderIsFocused = false;
1719  Refresh();
1720 }
1721 
1722 void ASlider::OnTimer(wxTimerEvent & WXUNUSED(event))
1723 {
1724  mLWSlider->ShowTip(true);
1725 }
1726 
1727 void ASlider::GetScroll(float & line, float & page)
1728 {
1729  mLWSlider->GetScroll(line, page);
1730 }
1731 
1732 void ASlider::SetScroll(float line, float page)
1733 {
1734  mLWSlider->SetScroll(line, page);
1735 }
1736 
1738 {
1739  mLWSlider->SetToolTipTemplate(tip);
1740 }
1741 
1742 float ASlider::Get( bool convert )
1743 {
1744  return mLWSlider->Get( convert );
1745 }
1746 
1747 void ASlider::Set(float value)
1748 {
1749  mLWSlider->Set(value);
1750 }
1751 
1752 void ASlider::Increase(float steps)
1753 {
1754  mLWSlider->Increase(steps);
1755 }
1756 
1757 void ASlider::Decrease(float steps)
1758 {
1759  mLWSlider->Decrease(steps);
1760 }
1761 
1762 bool ASlider::ShowDialog(wxPoint pos)
1763 {
1764  return mLWSlider->ShowDialog(pos);
1765 }
1766 
1767 void ASlider::SetSpeed(float speed)
1768 {
1769  mLWSlider->SetSpeed(speed);
1770 }
1771 
1772 bool ASlider::Enable(bool enable)
1773 {
1774  if (mLWSlider->GetEnabled() == enable)
1775  return false;
1776 
1777  mLWSlider->SetEnabled(enable);
1778 
1779  wxWindow::Enable(enable);
1780 
1781  return true;
1782 }
1783 
1785 {
1786  return mLWSlider->GetEnabled();
1787 }
1788 
1789 bool ASlider::s_AcceptsFocus{ false };
1790 
1792  s_AcceptsFocus = true;
1793  return TempAllowFocus{ &s_AcceptsFocus };
1794 }
1795 
1796 // This compensates for a but in wxWidgets 3.0.2 for mac:
1797 // Couldn't set focus from keyboard when AcceptsFocus returns false;
1798 // this bypasses that limitation
1800 {
1801  auto temp = TemporarilyAllowFocus();
1802  SetFocus();
1803 }
1804 
1805 #if wxUSE_ACCESSIBILITY
1806 
1807 ASliderAx::ASliderAx( wxWindow * window ) :
1808  WindowAccessible( window )
1809 {
1810 }
1811 
1812 ASliderAx::~ASliderAx()
1813 {
1814 }
1815 
1816 // Retrieves the address of an IDispatch interface for the specified child.
1817 // All objects must support this property.
1818 wxAccStatus ASliderAx::GetChild( int childId, wxAccessible** child )
1819 {
1820  if ( childId == wxACC_SELF )
1821  {
1822  *child = this;
1823  }
1824  else
1825  {
1826  *child = NULL;
1827  }
1828 
1829  return wxACC_OK;
1830 }
1831 
1832 // Gets the number of children.
1833 wxAccStatus ASliderAx::GetChildCount(int* childCount)
1834 {
1835  *childCount = 3;
1836 
1837  return wxACC_OK;
1838 }
1839 
1840 // Gets the default action for this object (0) or > 0 (the action for a child).
1841 // Return wxACC_OK even if there is no action. actionName is the action, or the empty
1842 // string if there is no action.
1843 // The retrieved string describes the action that is performed on an object,
1844 // not what the object does as a result. For example, a toolbar button that prints
1845 // a document has a default action of "Press" rather than "Prints the current document."
1846 wxAccStatus ASliderAx::GetDefaultAction( int WXUNUSED(childId), wxString *actionName )
1847 {
1848  actionName->clear();
1849 
1850  return wxACC_OK;
1851 }
1852 
1853 // Returns the description for this object or a child.
1854 wxAccStatus ASliderAx::GetDescription( int WXUNUSED(childId), wxString *description )
1855 {
1856  description->clear();
1857 
1858  return wxACC_OK;
1859 }
1860 
1861 // Gets the window with the keyboard focus.
1862 // If childId is 0 and child is NULL, no object in
1863 // this subhierarchy has the focus.
1864 // If this object has the focus, child should be 'this'.
1865 wxAccStatus ASliderAx::GetFocus(int* childId, wxAccessible** child)
1866 {
1867  *childId = 0;
1868  *child = this;
1869 
1870  return wxACC_OK;
1871 }
1872 
1873 // Returns help text for this object or a child, similar to tooltip text.
1874 wxAccStatus ASliderAx::GetHelpText( int WXUNUSED(childId), wxString *helpText )
1875 {
1876  helpText->clear();
1877 
1878  return wxACC_OK;
1879 }
1880 
1881 // Returns the keyboard shortcut for this object or child.
1882 // Return e.g. ALT+K
1883 wxAccStatus ASliderAx::GetKeyboardShortcut( int WXUNUSED(childId), wxString *shortcut )
1884 {
1885  shortcut->clear();
1886 
1887  return wxACC_OK;
1888 }
1889 
1890 // Returns the rectangle for this object (id = 0) or a child element (id > 0).
1891 // rect is in screen coordinates.
1892 wxAccStatus ASliderAx::GetLocation( wxRect& rect, int WXUNUSED(elementId) )
1893 {
1894  ASlider *as = wxDynamicCast( GetWindow(), ASlider );
1895 
1896  rect = as->GetRect();
1897  rect.SetPosition( as->GetParent()->ClientToScreen( rect.GetPosition() ) );
1898 
1899  return wxACC_OK;
1900 }
1901 
1902 // Gets the name of the specified object.
1903 wxAccStatus ASliderAx::GetName(int WXUNUSED(childId), wxString* name)
1904 {
1905  ASlider *as = wxDynamicCast( GetWindow(), ASlider );
1906 
1907  *name = as->GetName();
1908 
1909  return wxACC_OK;
1910 }
1911 
1912 // Returns a role constant.
1913 wxAccStatus ASliderAx::GetRole(int childId, wxAccRole* role)
1914 {
1915  switch( childId )
1916  {
1917  case 0:
1918  *role = wxROLE_SYSTEM_SLIDER;
1919  break;
1920 
1921  case 1:
1922  case 3:
1923  *role = wxROLE_SYSTEM_PUSHBUTTON;
1924  break;
1925 
1926  case 2:
1927  *role = wxROLE_SYSTEM_INDICATOR;
1928  break;
1929  }
1930 
1931  return wxACC_OK;
1932 }
1933 
1934 // Gets a variant representing the selected children
1935 // of this object.
1936 // Acceptable values:
1937 // - a null variant (IsNull() returns TRUE)
1938 // - a list variant (GetType() == wxT("list"))
1939 // - an integer representing the selected child element,
1940 // or 0 if this object is selected (GetType() == wxT("long"))
1941 // - a "void*" pointer to a wxAccessible child object
1942 wxAccStatus ASliderAx::GetSelections( wxVariant * WXUNUSED(selections) )
1943 {
1944  return wxACC_NOT_IMPLEMENTED;
1945 }
1946 
1947 // Returns a state constant.
1948 wxAccStatus ASliderAx::GetState(int childId, long* state)
1949 {
1950  ASlider *as = wxDynamicCast( GetWindow(), ASlider );
1951 
1952  switch( childId )
1953  {
1954  case 0:
1955  *state = wxACC_STATE_SYSTEM_FOCUSABLE;
1956  break;
1957 
1958  case 1:
1959  if ( as->mLWSlider->mCurrentValue == as->mLWSlider->mMinValue )
1960  {
1961  *state = wxACC_STATE_SYSTEM_INVISIBLE;
1962  }
1963  break;
1964 
1965  case 3:
1966  if ( as->mLWSlider->mCurrentValue == as->mLWSlider->mMaxValue )
1967  {
1968  *state = wxACC_STATE_SYSTEM_INVISIBLE;
1969  }
1970  break;
1971  }
1972 
1973  // Do not use mSliderIsFocused is not set until after this method
1974  // is called.
1975  *state |= ( as == wxWindow::FindFocus() ? wxACC_STATE_SYSTEM_FOCUSED : 0 );
1976 
1977  return wxACC_OK;
1978 }
1979 
1980 // Returns a localized string representing the value for the object
1981 // or child.
1982 wxAccStatus ASliderAx::GetValue(int childId, wxString* strValue)
1983 {
1984  ASlider *as = wxDynamicCast( GetWindow(), ASlider );
1985 
1986  if ( childId == 0 )
1987  {
1988  switch( as->mLWSlider->mStyle )
1989  {
1990  case FRAC_SLIDER:
1991  strValue->Printf( wxT("%.0f"), as->mLWSlider->mCurrentValue * 100 );
1992  break;
1993 
1994  case DB_SLIDER:
1995  strValue->Printf( wxT("%.0f"), as->mLWSlider->mCurrentValue );
1996  break;
1997 
1998  case PAN_SLIDER:
1999  strValue->Printf( wxT("%.0f"), as->mLWSlider->mCurrentValue * 100 );
2000  break;
2001 
2002  case SPEED_SLIDER:
2003  strValue->Printf( wxT("%.0f"), as->mLWSlider->mCurrentValue * 100 );
2004  break;
2005 #ifdef EXPERIMENTAL_MIDI_OUT
2006  case VEL_SLIDER:
2007  strValue->Printf( wxT("%.0f"), as->mLWSlider->mCurrentValue);
2008  break;
2009 #endif
2010  }
2011  return wxACC_OK;
2012  }
2013 
2014  return wxACC_NOT_SUPPORTED;
2015 }
2016 
2017 #endif
size
size_t size
Definition: ffmpeg-2.3.6-single-header.h:412
TranslatableString
Holds a msgid for the translation catalog; may also bind format arguments.
Definition: TranslatableString.h:32
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:280
eIsCreating
@ eIsCreating
Definition: ShuttleGui.h:38
LWSlider::mThumbWidth
int mThumbWidth
Definition: ASlider.h:198
LWSlider::mOrientation
int mOrientation
Definition: ASlider.h:172
TranslatableString::empty
bool empty() const
Definition: TranslatableString.h:72
ASlider::Get
float Get(bool convert=true)
Definition: ASlider.cpp:1742
ProjectStatus.h
LWSlider::SetScroll
void SetScroll(float line, float page)
Definition: ASlider.cpp:626
ShuttleGuiBase::StartVerticalLay
void StartVerticalLay(int iProp=1)
Definition: ShuttleGui.cpp:1184
ASlider::OnMouseEvent
void OnMouseEvent(wxMouseEvent &event)
Definition: ASlider.cpp:1685
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:1639
LWSlider::ShowTip
void ShowTip(bool show)
Definition: ASlider.cpp:889
LWSlider::DragPositionToValue
float DragPositionToValue(int fromPos, bool shiftDown)
Definition: ASlider.cpp:1427
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:1727
AllThemeResources.h
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
TranslatableStrings
std::vector< TranslatableString > TranslatableStrings
Definition: TranslatableString.h:295
LWSlider::SetPopWinPosition
void SetPopWinPosition()
Definition: ASlider.cpp:923
Project.h
ASlider::Set
void Set(float value)
Definition: ASlider.cpp:1747
ASlider::SetBackgroundColour
bool SetBackgroundColour(const wxColour &colour) override
Definition: ASlider.cpp:1627
ASlider::SetScroll
void SetScroll(float line, float page)
Definition: ASlider.cpp:1732
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:109
VEL_SLIDER
#define VEL_SLIDER
Definition: ASlider.h:37
LWSlider::Set
void Set(float value)
Definition: ASlider.cpp:1465
ASlider::OnTimer
void OnTimer(wxTimerEvent &event)
Definition: ASlider.cpp:1722
LWSlider::Redraw
void Redraw()
Definition: ASlider.cpp:1534
END_EVENT_TABLE
END_EVENT_TABLE()
XO
#define XO(s)
Definition: Internat.h:31
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:1343
ASlider::SetSpeed
void SetSpeed(float speed)
Definition: ASlider.cpp:1767
LWSlider::Decrease
void Decrease(float steps)
Definition: ASlider.cpp:1505
ASlider::IsEnabled
bool IsEnabled() const
Definition: ASlider.cpp:1784
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:1699
SliderDialog
Pop up dialog used with an LWSlider.
Definition: ASlider.h:334
FindProjectFromWindow
AudacityProject * FindProjectFromWindow(wxWindow *pWindow)
Definition: ProjectWindowBase.cpp:44
ASlider::Options
Definition: ASlider.h:238
SliderDialog::~SliderDialog
~SliderDialog()
Definition: ASlider.cpp:331
ASlider::Enable
bool Enable(bool enable=true) override
Definition: ASlider.cpp:1772
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:1543
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:1558
LWSlider::SetEnabled
void SetEnabled(bool enabled)
Definition: ASlider.cpp:1548
ThemeBase::Bitmap
wxBitmap & Bitmap(int iIndex)
Definition: Theme.cpp:1209
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:1799
wxEVT_COMMAND_BUTTON_CLICKED
wxEVT_COMMAND_BUTTON_CLICKED
Definition: AdornedRulerPanel.cpp:494
LWSlider::Get
float Get(bool convert=true)
Definition: ASlider.cpp:1457
LWSlider::ValueToPosition
int ValueToPosition(float val)
Definition: ASlider.cpp:1366
LWSlider::GetTip
TranslatableString GetTip(float value) const
Definition: ASlider.cpp:956
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:77
TipWindow::SetLabel
void SetLabel(const TranslatableString &label)
Definition: ASlider.cpp:232
AColor::tooltipBrush
static wxBrush tooltipBrush
Definition: AColor.h:122
eCancelButton
@ eCancelButton
Definition: ShuttleGui.h:601
ASlider::OnKeyDown
void OnKeyDown(wxKeyEvent &event)
Definition: ASlider.cpp:1705
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:1737
label
TranslatableString label
Definition: Tags.cpp:756
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:121
ShuttleGuiBase::EndVerticalLay
void EndVerticalLay()
Definition: ShuttleGui.cpp:1203
ASlider::mSliderIsFocused
bool mSliderIsFocused
Definition: ASlider.h:315
ASlider::OnPaint
void OnPaint(wxPaintEvent &event)
Definition: ASlider.cpp:1665
enabledRightEnd
static const wxPoint2DDouble enabledRightEnd[]
Definition: ASlider.cpp:433
ASlider::~ASlider
virtual ~ASlider()
Definition: ASlider.cpp:1621
Theme.h
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:1752
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:496
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:678
DB_SLIDER
#define DB_SLIDER
Definition: ASlider.h:33
ShuttleGuiBase::AddWindow
wxWindow * AddWindow(wxWindow *pWindow, int PositionFlags=wxALIGN_CENTRE)
Definition: ShuttleGui.cpp:299
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:157
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
theTheme
THEME_API Theme theTheme
Definition: Theme.cpp:79
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:577
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:1655
WindowAccessible.h
title
static const auto title
Definition: NoUpdatesAvailableDialog.cpp:22
ASlider
ASlider is a custom slider, allowing for a slicker look and feel.
Definition: ASlider.h:234
eOkButton
@ eOkButton
Definition: ShuttleGui.h:600
LWSlider::ClickPositionToValue
float ClickPositionToValue(int fromPos, bool shiftDown)
Definition: ASlider.cpp:1383
LWSlider::mScrollLine
float mScrollLine
Definition: ASlider.h:209
ShuttleGui::Position
ShuttleGui & Position(int flags)
Definition: ShuttleGui.h:712
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:1563
_
#define _(s)
Definition: Internat.h:75
TipWindow::TipWindow
TipWindow(wxWindow *parent, const TranslatableStrings &labels)
Definition: ASlider.cpp:179
ProjectStatus::Get
static ProjectStatus & Get(AudacityProject &project)
Definition: ProjectStatus.cpp:35
LWSlider::Refresh
void Refresh()
Definition: ASlider.cpp:1528
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
ASlider::OnKillFocus
void OnKillFocus(wxFocusEvent &event)
Definition: ASlider.cpp:1716
LWSlider::SetToolTipTemplate
void SetToolTipTemplate(const TranslatableString &tip)
Definition: ASlider.cpp:884
disabledStripesBegin
static const wxPoint2DDouble disabledStripesBegin[]
Definition: ASlider.cpp:442
Verbatim
TranslatableString Verbatim(wxString str)
Require calls to the one-argument constructor to go through this distinct global function name.
Definition: TranslatableString.h:321
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:1791
ThemeBase::Colour
wxColour & Colour(int iIndex)
Definition: Theme.cpp:1189
LINEAR_TO_DB
#define LINEAR_TO_DB(x)
Definition: MemoryX.h:631
LWSlider::mLeft
int mLeft
Definition: ASlider.h:177
ShuttleGui::AddStandardButtons
void AddStandardButtons(long buttons=eOkButton|eCancelButton, wxWindow *extra=NULL)
Definition: ShuttleGui.cpp:2444
LWSlider::AdjustSize
void AdjustSize(const wxSize &sz)
Definition: ASlider.cpp:638
FRAC_SLIDER
#define FRAC_SLIDER
Definition: ASlider.h:32
SliderDialog::mpOrigin
LWSlider * mpOrigin
Definition: ASlider.h:359
TranslatableString::Translation
wxString Translation() const
Definition: TranslatableString.h:79
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:1660
TranslatableString::Format
TranslatableString & Format(Args &&...args) &
Capture variadic format arguments (by copy) when there is no plural.
Definition: TranslatableString.h:103
disabledRightEnd
static const wxPoint2DDouble disabledRightEnd[]
Definition: ASlider.cpp:467
safenew
#define safenew
Definition: MemoryX.h:10
LWSlider::DrawToBitmap
void DrawToBitmap(wxDC &dc)
Definition: ASlider.cpp:729
LWSlider::mThumbHeight
int mThumbHeight
Definition: ASlider.h:199
AColor.h
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:1757
LWSlider::Increase
void Increase(float steps)
Definition: ASlider.cpp:1482
LWSlider::mClickPos
int mClickPos
Definition: ASlider.h:202
LWSlider::mMaxValue
float mMaxValue
Definition: ASlider.h:205
ImageManipulation.h
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:1762
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:631
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:1376
LWSlider::FormatPopWin
void FormatPopWin()
Definition: ASlider.cpp:945
ASlider::OnSetFocus
void OnSetFocus(wxFocusEvent &event)
Definition: ASlider.cpp:1710