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