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