Mercurial > hg > svcore
comparison base/ZoomLevel.h @ 1551:4de4284d0596
Merge from branch zoom
author | Chris Cannam |
---|---|
date | Wed, 10 Oct 2018 08:44:15 +0100 |
parents | 8f9e9cff141d |
children | 1ae6a19464a7 |
comparison
equal
deleted
inserted
replaced
1548:51d6551d5244 | 1551:4de4284d0596 |
---|---|
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ | |
2 | |
3 /* | |
4 Sonic Visualiser | |
5 An audio file viewer and annotation editor. | |
6 Centre for Digital Music, Queen Mary, University of London. | |
7 | |
8 This program is free software; you can redistribute it and/or | |
9 modify it under the terms of the GNU General Public License as | |
10 published by the Free Software Foundation; either version 2 of the | |
11 License, or (at your option) any later version. See the file | |
12 COPYING included with this distribution for more information. | |
13 */ | |
14 | |
15 #ifndef SV_ZOOM_LEVEL_H | |
16 #define SV_ZOOM_LEVEL_H | |
17 | |
18 #include "BaseTypes.h" | |
19 | |
20 #include <ostream> | |
21 #include <cmath> | |
22 | |
23 /** Display zoom level. Can be an integer number of samples per pixel, | |
24 * or an integer number of pixels per sample. | |
25 */ | |
26 struct ZoomLevel { | |
27 | |
28 enum Zone { | |
29 FramesPerPixel, // zoomed out (as in classic SV) | |
30 PixelsPerFrame // zoomed in beyond 1-1 (interpolating the waveform) | |
31 }; | |
32 | |
33 Zone zone; | |
34 int level; | |
35 | |
36 ZoomLevel() : zone(FramesPerPixel), level(1) { } | |
37 ZoomLevel(Zone z, int lev) : zone(z), level(lev) { } | |
38 | |
39 bool operator<(const ZoomLevel &other) const { | |
40 if (zone == FramesPerPixel) { | |
41 if (other.zone == zone) { | |
42 return level < other.level; | |
43 } else { | |
44 return false; | |
45 } | |
46 } else { | |
47 if (other.zone == zone) { | |
48 return level > other.level; | |
49 } else { | |
50 return false; | |
51 } | |
52 } | |
53 } | |
54 | |
55 bool operator==(const ZoomLevel &other) const { | |
56 return (zone == other.zone && level == other.level); | |
57 } | |
58 | |
59 ZoomLevel incremented() const { | |
60 if (zone == FramesPerPixel) { | |
61 return { zone, level + 1 }; | |
62 } else if (level == 1) { | |
63 return { FramesPerPixel, 2 }; | |
64 } else if (level == 2) { | |
65 return { FramesPerPixel, 1 }; | |
66 } else { | |
67 return { zone, level - 1 }; | |
68 } | |
69 } | |
70 | |
71 ZoomLevel decremented() const { | |
72 if (zone == PixelsPerFrame) { | |
73 return { zone, level + 1 }; | |
74 } else if (level == 1) { | |
75 return { PixelsPerFrame, 2 }; | |
76 } else { | |
77 return { zone, level - 1 }; | |
78 } | |
79 } | |
80 | |
81 /** Inexact conversion. The result is a whole number if we are | |
82 * zoomed in enough (in PixelsPerFrame zone), a fraction | |
83 * otherwise. | |
84 */ | |
85 double framesToPixels(double frames) const { | |
86 if (zone == PixelsPerFrame) { | |
87 return frames * level; | |
88 } else { | |
89 return frames / level; | |
90 } | |
91 } | |
92 | |
93 /** Inexact conversion. The result is a whole number if we are | |
94 * zoomed out enough (in FramesPerPixel zone), a fraction | |
95 * otherwise. | |
96 */ | |
97 double pixelsToFrames(double pixels) const { | |
98 if (zone == PixelsPerFrame) { | |
99 return pixels / level; | |
100 } else { | |
101 return pixels * level; | |
102 } | |
103 } | |
104 | |
105 /** Return a ZoomLevel that approximates the given ratio of pixels | |
106 * to frames. | |
107 */ | |
108 static ZoomLevel fromRatio(int pixels, sv_frame_t frames) { | |
109 if (pixels < frames) { | |
110 return { FramesPerPixel, int(round(double(frames)/pixels)) }; | |
111 } else { | |
112 int r = int(round(pixels/double(frames))); | |
113 if (r > 1) { | |
114 return { PixelsPerFrame, r }; | |
115 } else { | |
116 return { FramesPerPixel, 1 }; | |
117 } | |
118 } | |
119 } | |
120 }; | |
121 | |
122 std::ostream &operator<<(std::ostream &s, const ZoomLevel &z); | |
123 | |
124 #endif |