1 #include <cstdio> // for snprintf, grrr
3 #include <gtkmm/stock.h>
4 #include <gtkmm2ext/utils.h>
6 #include "tempo_dialog.h"
12 using namespace Gtkmm2ext;
13 using namespace ARDOUR;
16 TempoDialog::TempoDialog (TempoMap& map, nframes_t frame, const string & action)
17 : ArdourDialog ("tempo dialog"),
18 bpm_frame (_("Beats per minute")),
20 cancel_button (_("Cancel")),
21 when_bar_label (_("Bar")),
22 when_beat_label (_("Beat")),
24 when_frame (_("Location"))
27 Tempo tempo (map.tempo_at (frame));
28 map.bbt_time (frame, when);
30 init (when, tempo.beats_per_minute(), true);
33 TempoDialog::TempoDialog (TempoSection& section, const string & action)
34 : ArdourDialog ("tempo dialog"),
35 bpm_frame (_("Beats per minute")),
37 cancel_button (_("Cancel")),
38 when_bar_label (_("Bar")),
39 when_beat_label (_("Beat")),
41 when_frame (_("Location"))
43 init (section.start(), section.beats_per_minute(), section.movable());
47 TempoDialog::init (const BBT_Time& when, double bpm, bool movable)
49 snprintf (buf, sizeof (buf), "%.2f", bpm);
50 bpm_entry.set_text (buf);
51 bpm_entry.select_region (0, -1);
53 hspacer1.set_border_width (5);
54 hspacer1.pack_start (bpm_entry, false, false);
55 vspacer1.set_border_width (5);
56 vspacer1.pack_start (hspacer1, false, false);
58 bpm_frame.add (vspacer1);
61 snprintf (buf, sizeof (buf), "%" PRIu32, when.bars);
62 when_bar_entry.set_text (buf);
63 snprintf (buf, sizeof (buf), "%" PRIu32, when.beats);
64 when_beat_entry.set_text (buf);
66 when_bar_entry.set_name ("MetricEntry");
67 when_beat_entry.set_name ("MetricEntry");
69 when_bar_label.set_name ("MetricLabel");
70 when_beat_label.set_name ("MetricLabel");
72 Gtkmm2ext::set_size_request_to_display_given_text (when_bar_entry, "999g", 5, 7);
73 Gtkmm2ext::set_size_request_to_display_given_text (when_beat_entry, "999g", 5, 7);
75 when_table.set_homogeneous (true);
76 when_table.set_row_spacings (2);
77 when_table.set_col_spacings (2);
78 when_table.set_border_width (5);
80 when_table.attach (when_bar_label, 0, 1, 0, 1, Gtk::AttachOptions(0), Gtk::FILL|Gtk::EXPAND);
81 when_table.attach (when_bar_entry, 0, 1, 1, 2, Gtk::AttachOptions(0), Gtk::FILL|Gtk::EXPAND);
83 when_table.attach (when_beat_label, 1, 2, 0, 1, Gtk::AttachOptions(0), Gtk::AttachOptions(0));
84 when_table.attach (when_beat_entry, 1, 2, 1, 2, Gtk::AttachOptions(0), Gtk::AttachOptions(0));
86 when_frame.set_name ("MetricDialogFrame");
87 when_frame.add (when_table);
89 get_vbox()->pack_start (when_frame, false, false);
92 bpm_frame.set_name ("MetricDialogFrame");
93 bpm_entry.set_name ("MetricEntry");
95 get_vbox()->pack_start (bpm_frame, false, false);
97 add_button (Stock::CANCEL, RESPONSE_CANCEL);
98 add_button (Stock::APPLY, RESPONSE_ACCEPT);
99 set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
100 set_default_response (RESPONSE_ACCEPT);
102 get_vbox()->show_all();
105 set_name ("MetricDialog");
106 bpm_entry.signal_activate().connect (bind (mem_fun (*this, &TempoDialog::response), RESPONSE_ACCEPT));
107 bpm_entry.signal_key_release_event().connect (mem_fun (*this, &TempoDialog::bpm_key_release));
108 bpm_entry.signal_key_press_event().connect (mem_fun (*this, &TempoDialog::bpm_key_press), false);
112 TempoDialog::bpm_key_press (GdkEventKey* ev)
115 switch (ev->keyval) {
160 TempoDialog::bpm_key_release (GdkEventKey* ev)
162 if (bpm_entry.get_text() != "") {
163 set_response_sensitive (Gtk::RESPONSE_ACCEPT, true);
165 set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
171 TempoDialog::get_bpm ()
175 if (sscanf (bpm_entry.get_text().c_str(), "%lf", &bpm) != 1) {
183 TempoDialog::get_bbt_time (BBT_Time& requested)
185 if (sscanf (when_bar_entry.get_text().c_str(), "%" PRIu32, &requested.bars) != 1) {
189 if (sscanf (when_beat_entry.get_text().c_str(), "%" PRIu32, &requested.beats) != 1) {
197 MeterDialog::MeterDialog (TempoMap& map, nframes_t frame, const string & action)
198 : ArdourDialog ("meter dialog"),
199 note_frame (_("Meter denominator")),
200 bpb_frame (_("Beats per bar")),
202 cancel_button (_("Cancel")),
203 when_bar_label (_("Bar")),
204 when_beat_label (_("Beat")),
205 when_frame (_("Location"))
208 frame = map.round_to_bar(frame,0);
209 Meter meter (map.meter_at(frame));
211 map.bbt_time (frame, when);
212 init (when, meter.beats_per_bar(), meter.note_divisor(), true);
215 MeterDialog::MeterDialog (MeterSection& section, const string & action)
216 : ArdourDialog ("meter dialog"),
217 note_frame (_("Meter denominator")),
218 bpb_frame (_("Beats per bar")),
220 cancel_button (_("Cancel")),
221 when_bar_label (_("Bar")),
222 when_beat_label (_("Beat")),
223 when_frame (_("Location"))
225 init (section.start(), section.beats_per_bar(), section.note_divisor(), section.movable());
229 MeterDialog::init (const BBT_Time& when, double bpb, double note_type, bool movable)
231 snprintf (buf, sizeof (buf), "%.2f", bpb);
232 bpb_entry.set_text (buf);
233 bpb_entry.select_region (0, -1);
234 Gtkmm2ext::set_size_request_to_display_given_text (bpb_entry, "999999g", 5, 5);
236 strings.push_back (_("whole (1)"));
237 strings.push_back (_("second (2)"));
238 strings.push_back (_("third (3)"));
239 strings.push_back (_("quarter (4)"));
240 strings.push_back (_("eighth (8)"));
241 strings.push_back (_("sixteenth (16)"));
242 strings.push_back (_("thirty-second (32)"));
244 set_popdown_strings (note_types, strings);
247 note_types.set_active_text (_("whole (1)"));
248 else if (note_type==2.0f)
249 note_types.set_active_text (_("second (2)"));
250 else if (note_type==3.0f)
251 note_types.set_active_text (_("third (3)"));
252 else if (note_type==4.0f)
253 note_types.set_active_text (_("quarter (4)"));
254 else if (note_type==8.0f)
255 note_types.set_active_text (_("eighth (8)"));
256 else if (note_type==16.0f)
257 note_types.set_active_text (_("sixteenth (16)"));
258 else if (note_type==32.0f)
259 note_types.set_active_text (_("thirty-second (32)"));
261 note_types.set_active_text (_("quarter (4)"));
263 /* the string here needs to be the longest one to display */
264 const guint32 FUDGE = 20; // Combo's are stupid - they steal space from the entry for the button
265 Gtkmm2ext::set_size_request_to_display_given_text (note_types, "thirty-second (32)", 7+FUDGE, 7);
267 hspacer1.set_border_width (5);
268 hspacer1.pack_start (note_types, false, false);
269 vspacer1.set_border_width (5);
270 vspacer1.pack_start (hspacer1, false, false);
272 hspacer2.set_border_width (5);
273 hspacer2.pack_start (bpb_entry, false, false);
274 vspacer2.set_border_width (5);
275 vspacer2.pack_start (hspacer2, false, false);
277 note_frame.add (vspacer1);
278 bpb_frame.add (vspacer2);
281 snprintf (buf, sizeof (buf), "%" PRIu32, when.bars);
282 when_bar_entry.set_text (buf);
283 snprintf (buf, sizeof (buf), "%" PRIu32, when.beats);
284 when_beat_entry.set_text (buf);
286 when_bar_entry.set_name ("MetricEntry");
287 when_beat_entry.set_name ("MetricEntry");
289 when_bar_label.set_name ("MetricLabel");
290 when_beat_label.set_name ("MetricLabel");
292 Gtkmm2ext::set_size_request_to_display_given_text (when_bar_entry, "999g", 5, 7);
293 Gtkmm2ext::set_size_request_to_display_given_text (when_beat_entry, "999g", 5, 7);
295 when_table.set_homogeneous (true);
296 when_table.set_row_spacings (2);
297 when_table.set_col_spacings (2);
298 when_table.set_border_width (5);
300 when_table.attach (when_bar_label, 0, 1, 0, 1, Gtk::AttachOptions(0), Gtk::FILL|Gtk::EXPAND);
301 when_table.attach (when_bar_entry, 0, 1, 1, 2, Gtk::AttachOptions(0), Gtk::FILL|Gtk::EXPAND);
303 when_table.attach (when_beat_label, 1, 2, 0, 1, Gtk::AttachOptions(0), Gtk::AttachOptions(0));
304 when_table.attach (when_beat_entry, 1, 2, 1, 2, Gtk::AttachOptions(0), Gtk::AttachOptions(0));
306 when_frame.set_name ("MetricDialogFrame");
307 when_frame.add (when_table);
309 get_vbox()->pack_start (when_frame, false, false);
311 get_vbox()->pack_start (bpb_frame, false, false);
312 get_vbox()->pack_start (note_frame, false, false);
314 bpb_frame.set_name ("MetricDialogFrame");
315 note_frame.set_name ("MetricDialogFrame");
316 bpb_entry.set_name ("MetricEntry");
318 add_button (Stock::CANCEL, RESPONSE_CANCEL);
319 add_button (Stock::APPLY, RESPONSE_ACCEPT);
320 set_response_sensitive (RESPONSE_ACCEPT, false);
321 set_default_response (RESPONSE_ACCEPT);
323 get_vbox()->show_all ();
326 set_name ("MetricDialog");
327 bpb_entry.signal_activate().connect (bind (mem_fun (*this, &MeterDialog::response), RESPONSE_ACCEPT));
328 bpb_entry.signal_key_press_event().connect (mem_fun (*this, &MeterDialog::bpb_key_press), false);
329 bpb_entry.signal_key_release_event().connect (mem_fun (*this, &MeterDialog::bpb_key_release));
330 note_types.signal_changed().connect (mem_fun (*this, &MeterDialog::note_types_change));
334 MeterDialog::bpb_key_press (GdkEventKey* ev)
337 switch (ev->keyval) {
382 MeterDialog::bpb_key_release (GdkEventKey* ev)
384 if (bpb_entry.get_text() != "") {
385 set_response_sensitive (RESPONSE_ACCEPT, true);
387 set_response_sensitive (RESPONSE_ACCEPT, false);
393 MeterDialog::note_types_change ()
395 set_response_sensitive (Gtk::RESPONSE_ACCEPT, true);
399 MeterDialog::get_bpb ()
403 if (sscanf (bpb_entry.get_text().c_str(), "%lf", &bpb) != 1) {
411 MeterDialog::get_note_type ()
413 double note_type = 0;
414 vector<string>::iterator i;
415 string text = note_types.get_active_text();
417 for (i = strings.begin(); i != strings.end(); ++i) {
419 if (sscanf (text.c_str(), "%*[^0-9]%lf", ¬e_type) != 1) {
420 error << string_compose(_("garbaged note type entry (%1)"), text) << endmsg;
428 if (i == strings.end()) {
429 if (sscanf (text.c_str(), "%lf", ¬e_type) != 1) {
430 error << string_compose(_("incomprehensible note type entry (%1)"), text) << endmsg;
439 MeterDialog::get_bbt_time (BBT_Time& requested)
443 if (sscanf (when_bar_entry.get_text().c_str(), "%" PRIu32, &requested.bars) != 1) {
447 if (sscanf (when_beat_entry.get_text().c_str(), "%" PRIu32, &requested.beats) != 1) {