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