2 cleanup patches from nickm, plus work on mixer_ui.cc so that it compiles
[ardour.git] / gtk2_ardour / tempo_dialog.cc
1 #include <cstdio> // for snprintf, grrr 
2
3 #include <gtkmm2ext/utils.h>
4
5 #include "tempo_dialog.h"
6 #include "utils.h"
7
8 #include "i18n.h"
9
10 using namespace Gtk;
11 using namespace Gtkmm2ext;
12 using namespace ARDOUR;
13
14 TempoDialog::TempoDialog (TempoMap& map, jack_nframes_t frame, string action)
15         : ArdourDialog ("tempo dialog"),
16           bpm_frame (_("Beats per minute")),
17           ok_button (action),
18           cancel_button (_("Cancel")),
19           when_bar_label (_("Bar")),
20           when_beat_label (_("Beat")),
21           when_table (2, 2),
22           when_frame (_("Location"))
23 {
24         BBT_Time when;
25         Tempo tempo (map.tempo_at (frame));
26         map.bbt_time (frame, when);
27
28         init (when, tempo.beats_per_minute(), true);
29 }
30
31 TempoDialog::TempoDialog (TempoSection& section, string action)
32         : ArdourDialog ("tempo dialog"),
33           bpm_frame (_("Beats per minute")),
34           ok_button (action),
35           cancel_button (_("Cancel")),
36           when_bar_label (_("Bar")),
37           when_beat_label (_("Beat")),
38           when_table (2, 2),
39           when_frame (_("Location"))
40 {
41         init (section.start(), section.beats_per_minute(), section.movable());
42 }
43
44 void
45 TempoDialog::init (const BBT_Time& when, double bpm, bool movable)
46 {
47         snprintf (buf, sizeof (buf), "%.2f", bpm);
48         bpm_entry.set_text (buf);
49         bpm_entry.select_region (0, -1);
50         
51         hspacer1.set_border_width (5);
52         hspacer1.pack_start (bpm_entry, false, false);
53         vspacer1.set_border_width (5);
54         vspacer1.pack_start (hspacer1, false, false);
55
56         bpm_frame.add (vspacer1);
57
58         button_box.set_border_width (10);
59         button_box.set_spacing (5);
60         button_box.set_homogeneous (true);
61         button_box.pack_start (ok_button); 
62         button_box.pack_start (cancel_button); 
63
64         vpacker.set_border_width (10);
65         vpacker.set_spacing (5);
66
67         if (movable) {
68                 snprintf (buf, sizeof (buf), "%" PRIu32, when.bars);
69                 when_bar_entry.set_text (buf);
70                 snprintf (buf, sizeof (buf), "%" PRIu32, when.beats);
71                 when_beat_entry.set_text (buf);
72                 
73                 when_bar_entry.set_name ("MetricEntry");
74                 when_beat_entry.set_name ("MetricEntry");
75                 
76                 when_bar_label.set_name ("MetricLabel");
77                 when_beat_label.set_name ("MetricLabel");
78                 
79                 Gtkmm2ext::set_size_request_to_display_given_text (when_bar_entry, "999g", 5, 7);
80                 Gtkmm2ext::set_size_request_to_display_given_text (when_beat_entry, "999g", 5, 7);
81                 
82                 when_table.set_homogeneous (true);
83                 when_table.set_row_spacings (2);
84                 when_table.set_col_spacings (2);
85                 when_table.set_border_width (5);
86                 
87                 when_table.attach (when_bar_label, 0, 1, 0, 1, Gtk::AttachOptions(0), Gtk::FILL|Gtk::EXPAND);
88                 when_table.attach (when_bar_entry, 0, 1, 1, 2, Gtk::AttachOptions(0), Gtk::FILL|Gtk::EXPAND);
89                 
90                 when_table.attach (when_beat_label, 1, 2, 0, 1, Gtk::AttachOptions(0), Gtk::AttachOptions(0));
91                 when_table.attach (when_beat_entry, 1, 2, 1, 2, Gtk::AttachOptions(0), Gtk::AttachOptions(0));
92                 
93                 when_frame.set_name ("MetricDialogFrame");
94                 when_frame.add (when_table);
95
96                 vpacker.pack_start (when_frame, false, false);
97         }
98
99         vpacker.pack_start (bpm_frame, false, false);
100         vpacker.pack_start (button_box, false, false);
101
102         bpm_frame.set_name ("MetricDialogFrame");
103         bpm_entry.set_name ("MetricEntry");
104         ok_button.set_name ("MetricButton");
105         cancel_button.set_name ("MetricButton");
106
107         add (vpacker);
108         set_name ("MetricDialog");
109
110         set_keyboard_input(true);
111 }
112
113 double 
114 TempoDialog::get_bpm ()
115 {
116         double bpm;
117         
118         if (sscanf (bpm_entry.get_text().c_str(), "%lf", &bpm) != 1) {
119                 return 0;
120         }
121
122         return bpm;
123 }       
124
125 bool
126 TempoDialog::get_bbt_time (BBT_Time& requested)
127 {
128         if (sscanf (when_bar_entry.get_text().c_str(), "%" PRIu32, &requested.bars) != 1) {
129                 return false;
130         }
131         
132         if (sscanf (when_beat_entry.get_text().c_str(), "%" PRIu32, &requested.beats) != 1) {
133                 return false;
134         }
135
136         return true;
137 }
138
139
140 MeterDialog::MeterDialog (TempoMap& map, jack_nframes_t frame, string action)
141         : ArdourDialog ("meter dialog"),
142           note_frame (_("Meter denominator")),
143           bpb_frame (_("Beats per bar")),
144           ok_button (action),
145           cancel_button (_("Cancel")),
146           when_bar_label (_("Bar")),
147           when_beat_label (_("Beat")),
148           when_frame (_("Location"))
149 {
150         BBT_Time when;
151         frame = map.round_to_bar(frame,0); 
152         Meter meter (map.meter_at(frame));
153
154         map.bbt_time (frame, when);
155         init (when, meter.beats_per_bar(), meter.note_divisor(), true);
156 }
157
158 MeterDialog::MeterDialog (MeterSection& section, string action)
159         : ArdourDialog ("meter dialog"),
160           note_frame (_("Meter denominator")),
161           bpb_frame (_("Beats per bar")),
162           ok_button (action),
163           cancel_button (_("Cancel")),
164           when_bar_label (_("Bar")),
165           when_beat_label (_("Beat")),
166           when_frame (_("Location"))
167 {
168         init (section.start(), section.beats_per_bar(), section.note_divisor(), section.movable());
169 }
170
171 void
172 MeterDialog::init (const BBT_Time& when, double bpb, double note_type, bool movable)
173 {
174         snprintf (buf, sizeof (buf), "%.2f", bpb);
175         bpb_entry.set_text (buf);
176         bpb_entry.select_region (0, -1);
177         Gtkmm2ext::set_size_request_to_display_given_text (bpb_entry, "999999g", 5, 5);
178
179         vector<string> strings;
180         
181         strings.push_back (_("whole (1)"));
182         strings.push_back (_("second (2)"));
183         strings.push_back (_("third (3)"));
184         strings.push_back (_("quarter (4)"));
185         strings.push_back (_("eighth (8)"));
186         strings.push_back (_("sixteenth (16)"));
187         strings.push_back (_("thirty-second (32)"));
188         
189         set_popdown_strings (note_types, strings);
190
191         if (note_type==1.0f)
192                 note_types.set_active_text (_("whole (1)"));
193         else if (note_type==2.0f)
194                 note_types.set_active_text (_("second (2)"));
195         else if (note_type==3.0f)
196                 note_types.set_active_text (_("third (3)"));
197         else if (note_type==4.0f)
198                 note_types.set_active_text (_("quarter (4)"));
199         else if (note_type==8.0f)
200                 note_types.set_active_text (_("eighth (8)"));
201         else if (note_type==16.0f)
202                 note_types.set_active_text (_("sixteenth (16)"));
203         else if (note_type==32.0f)
204                 note_types.set_active_text (_("thirty-second (32)"));
205         else
206                 note_types.set_active_text (_("quarter (4)"));
207                 
208         /* strings.back() just happens to be the longest one to display */
209         // GTK2FIX
210         // Gtkmm2ext::set_size_request_to_display_given_text (*(note_types.get_entry()), strings.back(), 7, 7);
211
212         hspacer1.set_border_width (5);
213         hspacer1.pack_start (note_types, false, false);
214         vspacer1.set_border_width (5);
215         vspacer1.pack_start (hspacer1, false, false);
216
217         hspacer2.set_border_width (5);
218         hspacer2.pack_start (bpb_entry, false, false);
219         vspacer2.set_border_width (5);
220         vspacer2.pack_start (hspacer2, false, false);
221
222         note_frame.add (vspacer1);
223         bpb_frame.add (vspacer2);
224
225         button_box.set_border_width (10);
226         button_box.set_spacing (5);
227         button_box.set_homogeneous (true);
228         button_box.pack_start (ok_button); 
229         button_box.pack_start (cancel_button); 
230
231         vpacker.set_border_width (10);
232         vpacker.set_spacing (5);
233         
234         if (movable) {
235                 snprintf (buf, sizeof (buf), "%" PRIu32, when.bars);
236                 when_bar_entry.set_text (buf);
237                 snprintf (buf, sizeof (buf), "%" PRIu32, when.beats);
238                 when_beat_entry.set_text (buf);
239                 
240                 when_bar_entry.set_name ("MetricEntry");
241                 when_beat_entry.set_name ("MetricEntry");
242                 
243                 when_bar_label.set_name ("MetricLabel");
244                 when_beat_label.set_name ("MetricLabel");
245                 
246                 Gtkmm2ext::set_size_request_to_display_given_text (when_bar_entry, "999g", 5, 7);
247                 Gtkmm2ext::set_size_request_to_display_given_text (when_beat_entry, "999g", 5, 7);
248                 
249                 when_table.set_homogeneous (true);
250                 when_table.set_row_spacings (2);
251                 when_table.set_col_spacings (2);
252                 when_table.set_border_width (5);
253                 
254                 when_table.attach (when_bar_label, 0, 1, 0, 1, Gtk::AttachOptions(0), Gtk::FILL|Gtk::EXPAND);
255                 when_table.attach (when_bar_entry, 0, 1, 1, 2, Gtk::AttachOptions(0), Gtk::FILL|Gtk::EXPAND);
256                 
257                 when_table.attach (when_beat_label, 1, 2, 0, 1, Gtk::AttachOptions(0), Gtk::AttachOptions(0));
258                 when_table.attach (when_beat_entry, 1, 2, 1, 2, Gtk::AttachOptions(0), Gtk::AttachOptions(0));
259                 
260                 when_frame.set_name ("MetricDialogFrame");
261                 when_frame.add (when_table);
262                 
263                 vpacker.pack_start (when_frame, false, false);
264         }
265
266         vpacker.pack_start (bpb_frame, false, false);
267         vpacker.pack_start (note_frame, false, false);
268         vpacker.pack_start (button_box, false, false);
269         
270         bpb_frame.set_name ("MetricDialogFrame");
271         note_frame.set_name ("MetricDialogFrame");
272         bpb_entry.set_name ("MetricEntry");
273         ok_button.set_name ("MetricButton");
274         cancel_button.set_name ("MetricButton");
275
276         add (vpacker);
277         set_name ("MetricDialog");
278
279         set_keyboard_input(true);
280 }
281
282 double
283 MeterDialog::get_bpb ()
284 {
285         double bpb = 0;
286         
287         if (sscanf (bpb_entry.get_text().c_str(), "%lf", &bpb) != 1) {
288                 return 0;
289         }
290
291         return bpb;
292 }
293         
294 double
295 MeterDialog::get_note_type ()
296 {
297         double note_type = 0;
298         vector<const gchar *>::iterator i;
299         string text = note_types.get_active_text();
300         
301         for (i = strings.begin(); i != strings.end(); ++i) {
302                 if (text == *i) {
303                         if (sscanf (text.c_str(), "%*[^0-9]%lf", &note_type) != 1) {
304                                 error << compose(_("garbaged note type entry (%1)"), text) << endmsg;
305                                 return 0;
306                         } else {
307                                 break;
308                         }
309                 }
310         } 
311         
312         if (i == strings.end()) {
313                 if (sscanf (text.c_str(), "%lf", &note_type) != 1) {
314                         error << compose(_("incomprehensible note type entry (%1)"), text) << endmsg;
315                         return 0;
316                 }
317         }
318
319         return note_type;
320 }
321
322 bool
323 MeterDialog::get_bbt_time (BBT_Time& requested)
324 {
325         requested.ticks = 0;
326
327         if (sscanf (when_bar_entry.get_text().c_str(), "%" PRIu32, &requested.bars) != 1) {
328                 return false;
329         }
330         
331         if (sscanf (when_beat_entry.get_text().c_str(), "%" PRIu32, &requested.beats) != 1) {
332                 return false;
333         }
334
335         return true;
336 }