1 /********************************************************************** 2 3 Audacity: A Digital Audio Editor 4 5 ASlider.h 6 7 Dominic Mazzoni 8 9 This class is a custom slider. 10 11 **********************************************************************/ 12 13 #ifndef __AUDACITY_SLIDER__ 14 #define __AUDACITY_SLIDER__ 15 16 #include <wx/setup.h> // for wxUSE_* macros 17 #include <wx/defs.h> 18 #include <wx/timer.h> // member variable 19 #include "wxPanelWrapper.h" // to inherit 20 21 class wxBitmap; 22 class wxSize; 23 class wxPoint; 24 class wxTextCtrl; 25 26 class Ruler; 27 class TipWindow; 28 29 // 30 // Predefined slider types (mStyle) 31 // 32 #define FRAC_SLIDER 1 // 0.0...1.0 33 #define DB_SLIDER 2 // -36...36 dB 34 #define PAN_SLIDER 3 // -1.0...1.0 35 #define SPEED_SLIDER 4 // 0.01 ..3.0 36 37 #define VEL_SLIDER 5 // -50..50 38 39 #define DB_MIN -36.0f 40 #define DB_MAX 36.0f 41 #define FRAC_MIN 0.0f 42 #define FRAC_MAX 1.0f 43 #define SPEED_MIN 0.01f 44 #define SPEED_MAX 3.0f 45 #define VEL_MIN -50.0f 46 #define VEL_MAX 50.0f 47 48 // Customizable slider only: If stepValue is STEP_CONTINUOUS, 49 // every value on the slider between minValue and maxValue 50 // will be possible 51 // 52 #define STEP_CONTINUOUS 0.0f 53 54 // 55 // Lightweight slider - i.e. a slider that doesn't appear in 56 // its own window, but rather draws itself inside an existing 57 // window (used inside Track Labels). The ASlider class, 58 // which uses this class, is below. 59 // 60 61 class AUDACITY_DLL_API LWSlider 62 { 63 friend class ASlider; 64 friend class ASliderAx; 65 66 public: 67 68 // MM: Construct customizable slider 69 LWSlider(wxWindow * parent, 70 const TranslatableString &name, 71 const wxPoint &pos, 72 const wxSize &size, 73 float minValue, 74 float maxValue, 75 float stepValue, 76 bool canUseShift, 77 int style, 78 bool heavyweight=false, 79 bool popup=true, 80 int orientation = wxHORIZONTAL); // wxHORIZONTAL or wxVERTICAL. wxVERTICAL is currently only for DB_SLIDER. 81 82 // Construct predefined slider 83 LWSlider(wxWindow * parent, 84 const TranslatableString &name, 85 const wxPoint &pos, 86 const wxSize &size, 87 int style, 88 bool heavyweight=false, 89 bool popup=true, 90 int orientation = wxHORIZONTAL); // wxHORIZONTAL or wxVERTICAL. wxVERTICAL is currently only for DB_SLIDER. 91 92 void Init(wxWindow * parent, 93 const TranslatableString &name, 94 const wxPoint &pos, 95 const wxSize &size, 96 float minValue, 97 float maxValue, 98 float stepValue, 99 bool canUseShift, 100 int style, 101 bool heavyweight, 102 bool popup, 103 float speed, 104 int orientation = wxHORIZONTAL); // wxHORIZONTAL or wxVERTICAL. wxVERTICAL is currently only for DB_SLIDER. 105 106 virtual ~LWSlider(); 107 108 wxWindowID GetId(); 109 void SetId(wxWindowID id); 110 111 void SetDefaultValue(float value); 112 void SetDefaultShortcut(bool value); 113 114 void GetScroll(float & line, float & page); 115 void SetScroll(float line, float page); 116 117 void ShowTip(bool show); 118 void SetToolTipTemplate(const TranslatableString & tip); 119 120 float Get(bool convert = true); 121 void Set(float value); 122 123 void Increase(float steps); 124 void Decrease(float steps); 125 126 // If set to less than 1.0, moving the mouse one pixel will move 127 // the slider by less than 1 unit 128 void SetSpeed(float speed); 129 130 void Move(const wxPoint &newpos); 131 132 void AdjustSize(const wxSize & sz); 133 134 void OnPaint(wxDC &dc, bool highlighted); 135 void OnSize(wxSizeEvent & event); 136 void OnMouseEvent(wxMouseEvent & event); 137 void OnKeyDown(wxKeyEvent & event); 138 void Refresh(); 139 void Redraw(); 140 141 bool ShowDialog(); 142 bool ShowDialog(wxPoint pos); 143 144 void SetEnabled(bool enabled); 145 bool GetEnabled() const; 146 147 float GetMinValue() const; 148 float GetMaxValue() const; 149 SetParent(wxWindow * parent)150 void SetParent(wxWindow *parent) { mParent = parent; } 151 void SendUpdate(float newValue); 152 153 private: 154 155 TranslatableString GetTip(float value) const; 156 TranslatableStrings GetWidestTips() const; 157 void FormatPopWin(); 158 void SetPopWinPosition(); 159 void CreatePopWin(); 160 void DrawToBitmap(wxDC & dc); 161 162 bool DoShowDialog(wxPoint pos); 163 164 165 int ValueToPosition(float val); 166 float DragPositionToValue(int fromPos, bool shiftDown); 167 float ClickPositionToValue(int fromPos, bool shiftDown); 168 169 wxWindow *mParent; 170 171 int mStyle; 172 int mOrientation; // wxHORIZONTAL or wxVERTICAL. wxVERTICAL is currently only for DB_SLIDER. 173 174 bool mHW; // is it really heavyweight (in a window) 175 bool mPopup; // should display dialog on double click 176 177 int mLeft; 178 int mTop; 179 180 int mWidth; //In pixels 181 int mHeight; //In pixels 182 183 // for (mOrientation == wxHORIZONTAL) 184 int mCenterY; 185 186 int mLeftX; 187 int mRightX; 188 int mWidthX; 189 190 // for (mOrientation == wxVERTICAL) //v Vertical PAN_SLIDER currently not handled, forced to horizontal. 191 int mCenterX; 192 193 int mTopY; 194 int mBottomY; // low values at bottom 195 int mHeightY; 196 197 198 int mThumbWidth; //In pixels 199 int mThumbHeight; //In pixels 200 201 float mClickValue; 202 int mClickPos; // position in x if (mOrientation == wxHORIZONTAL), else in y 203 204 float mMinValue; 205 float mMaxValue; 206 float mStepValue; 207 float mSpeed; 208 209 float mScrollLine; 210 float mScrollPage; 211 212 float mCurrentValue; 213 214 bool mDefaultShortcut; 215 float mDefaultValue; 216 217 bool mCanUseShift; 218 219 wxWindowID mID; 220 221 std::unique_ptr<TipWindow> mTipPanel; 222 TranslatableString mTipTemplate; 223 224 bool mIsDragging; 225 226 std::unique_ptr<wxBitmap> mBitmap, mThumbBitmap, mThumbBitmapHilited; 227 228 TranslatableString mName; 229 230 bool mEnabled; 231 }; 232 233 class AUDACITY_DLL_API ASlider /* not final */ : public wxPanel 234 { 235 friend class ASliderAx; 236 237 public: 238 struct Options { OptionsOptions239 Options() {} 240 241 int style{ FRAC_SLIDER }; 242 wxOrientation orientation{ wxHORIZONTAL }; 243 bool popup{ true }; 244 bool canUseShift{ true }; 245 float stepValue{ STEP_CONTINUOUS }; 246 247 float line{ 1.0 }; 248 float page{ 5.0 }; 249 StyleOptions250 Options& Style( int s ) { style = s; return *this; } OrientationOptions251 Options& Orientation( wxOrientation o ) 252 { orientation = o; return *this; } PopupOptions253 Options& Popup( bool p ) { popup = p; return *this; } CanUseShiftOptions254 Options& CanUseShift( bool c ) { canUseShift = c; return *this; } StepValueOptions255 Options& StepValue( float v ) { stepValue = v; return *this; } 256 LineOptions257 Options& Line( float l ) { line = l; return *this; } PageOptions258 Options& Page( float p ) { page = p; return *this; } 259 }; 260 261 ASlider( wxWindow * parent, 262 wxWindowID id, 263 const TranslatableString &name, 264 const wxPoint & pos, 265 const wxSize & size, 266 const Options &options = Options{}); 267 virtual ~ASlider(); 268 AcceptsFocus()269 bool AcceptsFocus() const override { return s_AcceptsFocus; } AcceptsFocusFromKeyboard()270 bool AcceptsFocusFromKeyboard() const override { return true; } 271 272 void SetFocusFromKbd() override; 273 274 bool SetBackgroundColour(const wxColour& colour) override; 275 276 void GetScroll(float & line, float & page); 277 void SetScroll(float line, float page); 278 279 void SetToolTipTemplate(const TranslatableString & tip); 280 281 float Get( bool convert = true ); 282 void Set(float value); 283 284 void Increase(float steps); 285 void Decrease(float steps); 286 bool ShowDialog(wxPoint pos = wxPoint(-1, -1)); 287 288 void SetSpeed(float speed); 289 290 void OnErase(wxEraseEvent & event); 291 void OnPaint(wxPaintEvent & event); 292 void OnSize(wxSizeEvent & event); 293 void OnMouseEvent(wxMouseEvent & event); 294 void OnCaptureLost(wxMouseCaptureLostEvent & event); 295 void OnKeyDown(wxKeyEvent &event); 296 void OnSlider(wxCommandEvent &event); 297 void OnSetFocus(wxFocusEvent & event); 298 void OnKillFocus(wxFocusEvent & event); 299 void OnTimer(wxTimerEvent & event); 300 301 // Overrides of the wxWindow functions with the same semantics 302 bool Enable(bool enable = true) override; 303 bool IsEnabled() const; 304 305 private: 306 static bool s_AcceptsFocus; operatorResetter307 struct Resetter { void operator () (bool *p) const { if(p) *p = false; } }; 308 using TempAllowFocus = std::unique_ptr<bool, Resetter>; 309 310 public: 311 static TempAllowFocus TemporarilyAllowFocus(); 312 313 private: 314 std::unique_ptr<LWSlider> mLWSlider; 315 bool mSliderIsFocused; 316 wxTimer mTimer; 317 318 protected: 319 int mStyle; 320 321 public: 322 DECLARE_EVENT_TABLE() 323 }; 324 325 326 327 #define SLIDER_DIALOG_TEXTCTRL 100 328 329 330 // This is a modal dialog that contains an ASlider 331 // and a text-entry box which can be used to set the 332 // value of a slider. 333 class SliderDialog final : public wxDialogWrapper 334 { 335 public: 336 SliderDialog(wxWindow * parent, wxWindowID id, 337 const TranslatableString & title, 338 wxPoint position, 339 wxSize size, 340 int style, 341 float value, 342 float line, 343 float page, 344 LWSlider * pSlider=nullptr); 345 ~SliderDialog(); 346 347 float Get(); 348 349 private: 350 bool TransferDataToWindow() override; 351 bool TransferDataFromWindow() override; 352 353 void OnSlider(wxCommandEvent &event); 354 void OnTextChange(wxCommandEvent &event); 355 356 ASlider * mSlider; 357 wxTextCtrl * mTextCtrl; 358 int mStyle; 359 LWSlider * mpOrigin; 360 float mValue; 361 362 public: 363 DECLARE_EVENT_TABLE() 364 }; 365 366 #endif 367