1 /**********************************************************************
2 
3   Audacity: A Digital Audio Editor
4 
5   ZoomInfo.h
6 
7   Paul Licameli split from ViewInfo.h
8 
9 **********************************************************************/
10 
11 #ifndef __AUDACITY_ZOOM_INFO__
12 #define __AUDACITY_ZOOM_INFO__
13 
14 #include "ClientData.h" // to inherit
15 #include "Prefs.h" // to inherit
16 
17 #ifdef __GNUC__
18 #define CONST
19 #else
20 #define CONST const
21 #endif
22 
23 class AudacityProject;
24 
25 // See big pictorial comment in TrackPanel.cpp for explanation of these numbers
26 enum : int {
27    // Constants related to x coordinates in the track panel
28    kBorderThickness = 1,
29    kShadowThickness = 1,
30 
31    kLeftInset = 4,
32    kRightInset = kLeftInset,
33    kLeftMargin = kLeftInset + kBorderThickness,
34    kRightMargin = kRightInset + kShadowThickness + kBorderThickness,
35 
36    kTrackInfoWidth = 100 - kLeftMargin,
37 };
38 
39 // The subset of ViewInfo information (other than selection)
40 // that is sufficient for purposes of TrackArtist,
41 // and for computing conversions between track times and pixel positions.
42 class SCREEN_GEOMETRY_API ZoomInfo /* not final */
43    // Note that ViewInfo inherits from ZoomInfo but there are no virtual functions.
44    // That's okay if we pass always by reference and never copy, suffering "slicing."
45    : public ClientData::Base
46    , protected PrefsListener
47 {
48 public:
49    ZoomInfo(double start, double pixelsPerSecond);
50    ~ZoomInfo();
51 
52    // Be sure we don't slice
53    ZoomInfo(const ZoomInfo&) PROHIBITED;
54    ZoomInfo& operator= (const ZoomInfo&) PROHIBITED;
55 
56    void UpdatePrefs() override;
57 
58    int vpos;                    // vertical scroll pos
59 
60    double h;                    // h pos in secs
61 
62 protected:
63    double zoom;                 // pixels per second
64 
65 public:
66    float dBr;                   // decibel scale range
67 
68    // do NOT use this once to convert a pixel width to a duration!
69    // Instead, call twice to convert start and end times,
70    // and take the difference.
71    // origin specifies the pixel corresponding to time h
72    double PositionToTime(wxInt64 position,
73       wxInt64 origin = 0
74       , bool ignoreFisheye = false
75    ) const;
76 
77    // do NOT use this once to convert a duration to a pixel width!
78    // Instead, call twice to convert start and end positions,
79    // and take the difference.
80    // origin specifies the pixel corresponding to time h
81    wxInt64 TimeToPosition(double time,
82       wxInt64 origin = 0
83       , bool ignoreFisheye = false
84    ) const;
85 
86    // This always ignores the fisheye.  Use with caution!
87    // You should prefer to call TimeToPosition twice, for endpoints, and take the difference!
88    double TimeRangeToPixelWidth(double timeRange) const;
89 
90    double OffsetTimeByPixels(double time, wxInt64 offset, bool ignoreFisheye = false) const
91    {
92       return PositionToTime(offset + TimeToPosition(time, ignoreFisheye), ignoreFisheye);
93    }
94 
GetWidth()95    int GetWidth() const { return mWidth; }
SetWidth(int width)96    void SetWidth( int width ) { mWidth = width; }
97 
GetVRulerWidth()98    int GetVRulerWidth() const { return mVRulerWidth; }
SetVRulerWidth(int width)99    void SetVRulerWidth( int width ) { mVRulerWidth = width; }
GetVRulerOffset()100    int GetVRulerOffset() const { return kTrackInfoWidth + kLeftMargin; }
101 
102    // The x-coordinate of the start of the displayed track data
GetLeftOffset()103    int GetLeftOffset() const
104       { return GetVRulerOffset() + GetVRulerWidth() + 1; }
105    // The number of pixel columns for display of track data
GetTracksUsableWidth()106    int GetTracksUsableWidth() const
107    {
108       return
109          std::max( 0, GetWidth() - ( GetLeftOffset() + kRightMargin ) );
110    }
111 
112    // Returns the time corresponding to the pixel column one past the track area
113    // (ignoring any fisheye)
GetScreenEndTime()114    double GetScreenEndTime() const
115    {
116       auto width = GetTracksUsableWidth();
117       return PositionToTime(width, 0, true);
118    }
119 
120    bool ZoomInAvailable() const;
121    bool ZoomOutAvailable() const;
122 
GetDefaultZoom()123    static double GetDefaultZoom()
124    { return 44100.0 / 512.0; }
125 
126 
127    // Limits zoom to certain bounds
128    void SetZoom(double pixelsPerSecond);
129 
130    // This function should not be used to convert positions to times and back
131    // Use TimeToPosition and PositionToTime and OffsetTimeByPixels instead
132    double GetZoom() const;
133 
134    static double GetMaxZoom( );
135    static double GetMinZoom( );
136 
137    // Limits zoom to certain bounds
138    // multipliers above 1.0 zoom in, below out
139    void ZoomBy(double multiplier);
140 
141    struct Interval {
142       CONST wxInt64 position; CONST double averageZoom; CONST bool inFisheye;
IntervalInterval143       Interval(wxInt64 p, double z, bool i)
144          : position(p), averageZoom(z), inFisheye(i) {}
145    };
146    typedef std::vector<Interval> Intervals;
147 
148    // Find an increasing sequence of pixel positions.  Each is the start
149    // of an interval, or is the end position.
150    // Each of the disjoint intervals should be drawn
151    // separately.
152    // It is guaranteed that there is at least one entry and the position of the
153    // first entry equals origin.
154    // @param origin specifies the pixel position corresponding to time ViewInfo::h.
155    void FindIntervals
156       (double rate, Intervals &results, wxInt64 width, wxInt64 origin = 0) const;
157 
158    enum FisheyeState {
159       HIDDEN,
160       PINNED,
161 
162       NUM_STATES,
163    };
GetFisheyeState()164    FisheyeState GetFisheyeState() const
165    { return HIDDEN; } // stub
166 
167    // Return true if the mouse position is anywhere in the fisheye
168    // origin specifies the pixel corresponding to time h
169    bool InFisheye(wxInt64 /*position*/, wxInt64 WXUNUSED(origin = 0)) const
170    {return false;} // stub
171 
172    // These accessors ignore the fisheye hiding state.
173    // Inclusive:
174    wxInt64 GetFisheyeLeftBoundary(wxInt64 WXUNUSED(origin = 0)) const
175    {return 0;} // stub
176    // Exclusive:
177    wxInt64 GetFisheyeRightBoundary(wxInt64 WXUNUSED(origin = 0)) const
178    {return 0;} // stub
179 
180    int mWidth{ 0 };
181    int mVRulerWidth{ 36 };
182 };
183 
184 #endif
185