Audacity 3.2.0
TimeFormat.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 TimeFormat.cpp
6
7 Dominic Mazzoni
8 Michael Papadopoulos split from Ruler.h
9
10**********************************************************************/
11
12#include "TimeFormat.h"
13#include "RealFormat.h"
14
16{
17 static TimeFormat instance;
18 return instance;
19}
20
22 double units, double& major, double& minor, double& minorMinor,
23 int& mDigits
24) const
25{
26 if (units > 0.5) {
27 if (units < 1.0) { // 1 sec
28 minor = 1.0;
29 major = 5.0;
30 return;
31 }
32 if (units < 5.0) { // 5 sec
33 minor = 5.0;
34 major = 15.0;
35 return;
36 }
37 if (units < 10.0) {
38 minor = 10.0;
39 major = 30.0;
40 return;
41 }
42 if (units < 15.0) {
43 minor = 15.0;
44 major = 60.0;
45 return;
46 }
47 if (units < 30.0) {
48 minor = 30.0;
49 major = 60.0;
50 return;
51 }
52 if (units < 60.0) { // 1 min
53 minor = 60.0;
54 major = 300.0;
55 return;
56 }
57 if (units < 300.0) { // 5 min
58 minor = 300.0;
59 major = 900.0;
60 return;
61 }
62 if (units < 600.0) { // 10 min
63 minor = 600.0;
64 major = 1800.0;
65 return;
66 }
67 if (units < 900.0) { // 15 min
68 minor = 900.0;
69 major = 3600.0;
70 return;
71 }
72 if (units < 1800.0) { // 30 min
73 minor = 1800.0;
74 major = 3600.0;
75 return;
76 }
77 if (units < 3600.0) { // 1 hr
78 minor = 3600.0;
79 major = 6 * 3600.0;
80 return;
81 }
82 if (units < 6 * 3600.0) { // 6 hrs
83 minor = 6 * 3600.0;
84 major = 24 * 3600.0;
85 return;
86 }
87 if (units < 24 * 3600.0) { // 1 day
88 minor = 24 * 3600.0;
89 major = 7 * 24 * 3600.0;
90 return;
91 }
92
93 minor = 24.0 * 7.0 * 3600.0; // 1 week
94 major = 24.0 * 7.0 * 3600.0;
95 return;
96 }
97
98 // Otherwise fall through to RealFormat
99 // (fractions of a second should be dealt with
100 // the same way as for RealFormat)
102 units, major, minor, minorMinor, mDigits);
103}
104
106 wxString& s, double d, double, double minor, int mDigits, TickType tickType
107) const
108{
109 // Replace -0 with 0
110 if (d < 0.0 && (d + minor > 0.0))
111 d = 0.0;
112
113 if (tickType == RulerFormat::t_major) {
114 if (d < 0) {
115 return;
116 }
117
118#if ALWAYS_HH_MM_SS
119 int secs = (int)(d + 0.5);
120 if (mMinor >= 1.0) {
121 s.Printf(wxT("%d:%02d:%02d"), secs / 3600, (secs / 60) % 60, secs % 60);
122 }
123 else {
124 wxString t1, t2, format;
125 t1.Printf(wxT("%d:%02d:"), secs / 3600, (secs / 60) % 60);
126 format.Printf(wxT("%%0%d.%dlf"), mDigits + 3, mDigits);
127 t2.Printf(format, fmod(d, 60.0));
128 s += t1 + t2;
129 }
130 break;
131#endif
132
133 if (minor >= 3600.0) {
134 int hrs = (int)(d / 3600.0 + 0.5);
135 wxString h;
136 h.Printf(wxT("%d:00:00"), hrs);
137 s += h;
138 }
139 else if (minor >= 60.0) {
140 int minutes = (int)(d / 60.0 + 0.5);
141 wxString m;
142 if (minutes >= 60)
143 m.Printf(wxT("%d:%02d:00"), minutes / 60, minutes % 60);
144 else
145 m.Printf(wxT("%d:00"), minutes);
146 s += m;
147 }
148 else if (minor >= 1.0) {
149 int secs = (int)(d + 0.5);
150 wxString t;
151 if (secs >= 3600)
152 t.Printf(wxT("%d:%02d:%02d"), secs / 3600, (secs / 60) % 60, secs % 60);
153 else if (secs >= 60)
154 t.Printf(wxT("%d:%02d"), secs / 60, secs % 60);
155 else
156 t.Printf(wxT("%d"), secs);
157 s += t;
158 }
159 else {
160 // Commented out old and incorrect code for avoiding the 40mins and 60 seconds problem
161 // It was causing Bug 463 - Incorrect Timeline numbering (where at high zoom and long tracks,
162 // numbers did not change.
163#if 0
164 // The casting to float is working around an issue where 59 seconds
165 // would show up as 60 when using g++ (Ubuntu 4.3.3-5ubuntu4) 4.3.3.
166 int secs = (int)(float)(d);
167 wxString t1, t2, format;
168
169 if (secs >= 3600)
170 t1.Printf(wxT("%d:%02d:"), secs / 3600, (secs / 60) % 60);
171 else if (secs >= 60)
172 t1.Printf(wxT("%d:"), secs / 60);
173
174 if (secs >= 60)
175 format.Printf(wxT("%%0%d.%dlf"), mDigits + 3, mDigits);
176 else
177 format.Printf(wxT("%%%d.%dlf"), mDigits + 3, mDigits);
178 // The casting to float is working around an issue where 59 seconds
179 // would show up as 60 when using g++ (Ubuntu 4.3.3-5ubuntu4) 4.3.3.
180 t2.Printf(format, fmod((float)d, (float)60.0));
181#else
182 // For d in the range of hours, d is just very slightly below the value it should
183 // have, because of using a double, which in turn yields values like 59:59:999999
184 // mins:secs:nanosecs when we want 1:00:00:000000
185 // so adjust by less than a nano second per hour to get nicer number formatting.
186 double dd = d * 1.000000000000001;
187 int secs = (int)(dd);
188 wxString t1, t2, format;
189
190 if (secs >= 3600)
191 t1.Printf(wxT("%d:%02d:"), secs / 3600, (secs / 60) % 60);
192 else if (secs >= 60)
193 t1.Printf(wxT("%d:"), secs / 60);
194
195 if (secs >= 60)
196 format.Printf(wxT("%%0%d.%dlf"), mDigits + 3, mDigits);
197 else
198 format.Printf(wxT("%%%d.%dlf"), mDigits + 3, mDigits);
199 // dd will be reduced to just the seconds and fractional part.
200 dd = dd - secs + (secs % 60);
201 // truncate to appropriate number of digits, so that the print formatting
202 // doesn't round up 59.9999999 to 60.
203 double multiplier = pow(10, mDigits);
204 dd = ((int)(dd * multiplier)) / multiplier;
205 t2.Printf(format, dd);
206#endif
207 s += t1 + t2;
208 }
209 }
210}
211
212TimeFormat::~TimeFormat() = default;
wxT("CloseDown"))
void SetTickSizes(double units, double &major, double &minor, double &minorMinor, int &mDigits) const override
Definition: RealFormat.cpp:26
static const RealFormat & LinearInstance()
Definition: RealFormat.cpp:14
~TimeFormat() override
void SetLabelString(wxString &s, double d, double units, double minor, int mDigits, TickType tickType) const override
Definition: TimeFormat.cpp:105
static const TimeFormat & Instance()
Definition: TimeFormat.cpp:15
void SetTickSizes(double units, double &major, double &minor, double &minorMinor, int &mDigits) const override
Definition: TimeFormat.cpp:21