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 (_("edit tempo")),
18 bpm_adjustment (60.0, 1.0, 999.9, 0.1, 1.0, 1.0),
19 bpm_spinner (bpm_adjustment),
20 bpm_frame (_("Beats per minute")),
22 cancel_button (_("Cancel")),
23 when_bar_label (_("Bar")),
24 when_beat_label (_("Beat")),
26 when_frame (_("Location"))
29 Tempo tempo (map.tempo_at (frame));
30 map.bbt_time (frame, when);
32 init (when, tempo.beats_per_minute(), true);
35 TempoDialog::TempoDialog (TempoSection& section, const string & action)
36 : ArdourDialog ("tempo dialog"),
37 bpm_adjustment (60.0, 1.0, 999.9, 0.1, 1.0, 1.0),
38 bpm_spinner (bpm_adjustment),
39 bpm_frame (_("Beats per minute")),
41 cancel_button (_("Cancel")),
42 when_bar_label (_("Bar")),
43 when_beat_label (_("Beat")),
45 when_frame (_("Location"))
47 init (section.start(), section.beats_per_minute(), section.movable());
51 TempoDialog::init (const BBT_Time& when, double bpm, bool movable)
53 bpm_spinner.set_numeric (true);
54 bpm_spinner.set_digits (1);
55 bpm_spinner.set_wrap (true);
56 bpm_spinner.set_value (bpm);
58 hspacer1.set_border_width (5);
59 hspacer1.pack_start (bpm_spinner, false, false);
60 vspacer1.set_border_width (5);
61 vspacer1.pack_start (hspacer1, false, false);
63 bpm_frame.add (vspacer1);
66 snprintf (buf, sizeof (buf), "%" PRIu32, when.bars);
67 when_bar_entry.set_text (buf);
68 snprintf (buf, sizeof (buf), "%" PRIu32, when.beats);
69 when_beat_entry.set_text (buf);
71 when_bar_entry.set_name ("MetricEntry");
72 when_beat_entry.set_name ("MetricEntry");
74 when_bar_label.set_name ("MetricLabel");
75 when_beat_label.set_name ("MetricLabel");
77 Gtkmm2ext::set_size_request_to_display_given_text (when_bar_entry, "999g", 5, 7);
78 Gtkmm2ext::set_size_request_to_display_given_text (when_beat_entry, "999g", 5, 7);
80 when_table.set_homogeneous (true);
81 when_table.set_row_spacings (2);
82 when_table.set_col_spacings (2);
83 when_table.set_border_width (5);
85 when_table.attach (when_bar_label, 0, 1, 0, 1, Gtk::AttachOptions(0), Gtk::FILL|Gtk::EXPAND);
86 when_table.attach (when_bar_entry, 0, 1, 1, 2, Gtk::AttachOptions(0), Gtk::FILL|Gtk::EXPAND);
88 when_table.attach (when_beat_label, 1, 2, 0, 1, Gtk::AttachOptions(0), Gtk::AttachOptions(0));
89 when_table.attach (when_beat_entry, 1, 2, 1, 2, Gtk::AttachOptions(0), Gtk::AttachOptions(0));
91 when_frame.set_name ("MetricDialogFrame");
92 when_frame.add (when_table);
94 get_vbox()->pack_start (when_frame, false, false);
97 bpm_frame.set_name ("MetricDialogFrame");
98 bpm_spinner.set_name ("MetricEntry");
100 get_vbox()->pack_start (bpm_frame, false, false);
102 add_button (Stock::CANCEL, RESPONSE_CANCEL);
103 add_button (Stock::APPLY, RESPONSE_ACCEPT);
104 set_response_sensitive (Gtk::RESPONSE_ACCEPT, false);
105 set_default_response (RESPONSE_ACCEPT);
107 get_vbox()->show_all();
110 set_name ("MetricDialog");
112 bpm_spinner.signal_activate().connect (bind (mem_fun (*this, &TempoDialog::response), RESPONSE_ACCEPT));
113 bpm_spinner.signal_button_press_event().connect (mem_fun (*this, &TempoDialog::bpm_button_press), false);
114 bpm_spinner.signal_button_release_event().connect (mem_fun (*this, &TempoDialog::bpm_button_release), false);
118 TempoDialog::bpm_button_press (GdkEventButton* ev)
124 TempoDialog::bpm_button_release (GdkEventButton* ev)
126 /* the value has been modified, accept should work now */
128 set_response_sensitive (Gtk::RESPONSE_ACCEPT, true);
133 TempoDialog::get_bpm ()
135 return bpm_spinner.get_value ();
139 TempoDialog::get_bbt_time (BBT_Time& requested)
141 if (sscanf (when_bar_entry.get_text().c_str(), "%" PRIu32, &requested.bars) != 1) {
145 if (sscanf (when_beat_entry.get_text().c_str(), "%" PRIu32, &requested.beats) != 1) {
153 MeterDialog::MeterDialog (TempoMap& map, nframes_t frame, const string & action)
154 : ArdourDialog ("meter dialog"),
155 note_frame (_("Meter denominator")),
156 bpb_frame (_("Beats per bar")),
158 cancel_button (_("Cancel")),
159 when_bar_label (_("Bar")),
160 when_beat_label (_("Beat")),
161 when_frame (_("Location"))
164 frame = map.round_to_bar(frame,0);
165 Meter meter (map.meter_at(frame));
167 map.bbt_time (frame, when);
168 init (when, meter.beats_per_bar(), meter.note_divisor(), true);
171 MeterDialog::MeterDialog (MeterSection& section, const string & action)
172 : ArdourDialog ("meter dialog"),
173 note_frame (_("Meter denominator")),
174 bpb_frame (_("Beats per bar")),
176 cancel_button (_("Cancel")),
177 when_bar_label (_("Bar")),
178 when_beat_label (_("Beat")),
179 when_frame (_("Location"))
181 init (section.start(), section.beats_per_bar(), section.note_divisor(), section.movable());
185 MeterDialog::init (const BBT_Time& when, double bpb, double note_type, bool movable)
187 snprintf (buf, sizeof (buf), "%.2f", bpb);
188 bpb_entry.set_text (buf);
189 bpb_entry.select_region (0, -1);
190 Gtkmm2ext::set_size_request_to_display_given_text (bpb_entry, "999999g", 5, 5);
192 strings.push_back (_("whole (1)"));
193 strings.push_back (_("second (2)"));
194 strings.push_back (_("third (3)"));
195 strings.push_back (_("quarter (4)"));
196 strings.push_back (_("eighth (8)"));
197 strings.push_back (_("sixteenth (16)"));
198 strings.push_back (_("thirty-second (32)"));
200 set_popdown_strings (note_types, strings);
203 note_types.set_active_text (_("whole (1)"));
204 else if (note_type==2.0f)
205 note_types.set_active_text (_("second (2)"));
206 else if (note_type==3.0f)
207 note_types.set_active_text (_("third (3)"));
208 else if (note_type==4.0f)
209 note_types.set_active_text (_("quarter (4)"));
210 else if (note_type==8.0f)
211 note_types.set_active_text (_("eighth (8)"));
212 else if (note_type==16.0f)
213 note_types.set_active_text (_("sixteenth (16)"));
214 else if (note_type==32.0f)
215 note_types.set_active_text (_("thirty-second (32)"));
217 note_types.set_active_text (_("quarter (4)"));
219 /* the string here needs to be the longest one to display */
220 const guint32 FUDGE = 20; // Combo's are stupid - they steal space from the entry for the button
221 Gtkmm2ext::set_size_request_to_display_given_text (note_types, "thirty-second (32)", 7+FUDGE, 7);
223 hspacer1.set_border_width (5);
224 hspacer1.pack_start (note_types, false, false);
225 vspacer1.set_border_width (5);
226 vspacer1.pack_start (hspacer1, false, false);
228 hspacer2.set_border_width (5);
229 hspacer2.pack_start (bpb_entry, false, false);
230 vspacer2.set_border_width (5);
231 vspacer2.pack_start (hspacer2, false, false);
233 note_frame.add (vspacer1);
234 bpb_frame.add (vspacer2);
237 snprintf (buf, sizeof (buf), "%" PRIu32, when.bars);
238 when_bar_entry.set_text (buf);
239 snprintf (buf, sizeof (buf), "%" PRIu32, when.beats);
240 when_beat_entry.set_text (buf);
242 when_bar_entry.set_name ("MetricEntry");
243 when_beat_entry.set_name ("MetricEntry");
245 when_bar_label.set_name ("MetricLabel");
246 when_beat_label.set_name ("MetricLabel");
248 Gtkmm2ext::set_size_request_to_display_given_text (when_bar_entry, "999g", 5, 7);
249 Gtkmm2ext::set_size_request_to_display_given_text (when_beat_entry, "999g", 5, 7);
251 when_table.set_homogeneous (true);
252 when_table.set_row_spacings (2);
253 when_table.set_col_spacings (2);
254 when_table.set_border_width (5);
256 when_table.attach (when_bar_label, 0, 1, 0, 1, Gtk::AttachOptions(0), Gtk::FILL|Gtk::EXPAND);
257 when_table.attach (when_bar_entry, 0, 1, 1, 2, Gtk::AttachOptions(0), Gtk::FILL|Gtk::EXPAND);
259 when_table.attach (when_beat_label, 1, 2, 0, 1, Gtk::AttachOptions(0), Gtk::AttachOptions(0));
260 when_table.attach (when_beat_entry, 1, 2, 1, 2, Gtk::AttachOptions(0), Gtk::AttachOptions(0));
262 when_frame.set_name ("MetricDialogFrame");
263 when_frame.add (when_table);
265 get_vbox()->pack_start (when_frame, false, false);
267 get_vbox()->pack_start (bpb_frame, false, false);
268 get_vbox()->pack_start (note_frame, false, false);
270 bpb_frame.set_name ("MetricDialogFrame");
271 note_frame.set_name ("MetricDialogFrame");
272 bpb_entry.set_name ("MetricEntry");
274 add_button (Stock::CANCEL, RESPONSE_CANCEL);
275 add_button (Stock::APPLY, RESPONSE_ACCEPT);
276 set_response_sensitive (RESPONSE_ACCEPT, false);
277 set_default_response (RESPONSE_ACCEPT);
279 get_vbox()->show_all ();
282 set_name ("MetricDialog");
283 bpb_entry.signal_activate().connect (bind (mem_fun (*this, &MeterDialog::response), RESPONSE_ACCEPT));
284 bpb_entry.signal_key_press_event().connect (mem_fun (*this, &MeterDialog::bpb_key_press), false);
285 bpb_entry.signal_key_release_event().connect (mem_fun (*this, &MeterDialog::bpb_key_release));
286 note_types.signal_changed().connect (mem_fun (*this, &MeterDialog::note_types_change));
290 MeterDialog::bpb_key_press (GdkEventKey* ev)
293 switch (ev->keyval) {
338 MeterDialog::bpb_key_release (GdkEventKey* ev)
340 if (bpb_entry.get_text() != "") {
341 set_response_sensitive (RESPONSE_ACCEPT, true);
343 set_response_sensitive (RESPONSE_ACCEPT, false);
349 MeterDialog::note_types_change ()
351 set_response_sensitive (Gtk::RESPONSE_ACCEPT, true);
355 MeterDialog::get_bpb ()
359 if (sscanf (bpb_entry.get_text().c_str(), "%lf", &bpb) != 1) {
367 MeterDialog::get_note_type ()
369 double note_type = 0;
370 vector<string>::iterator i;
371 string text = note_types.get_active_text();
373 for (i = strings.begin(); i != strings.end(); ++i) {
375 if (sscanf (text.c_str(), "%*[^0-9]%lf", ¬e_type) != 1) {
376 error << string_compose(_("garbaged note type entry (%1)"), text) << endmsg;
384 if (i == strings.end()) {
385 if (sscanf (text.c_str(), "%lf", ¬e_type) != 1) {
386 error << string_compose(_("incomprehensible note type entry (%1)"), text) << endmsg;
395 MeterDialog::get_bbt_time (BBT_Time& requested)
399 if (sscanf (when_bar_entry.get_text().c_str(), "%" PRIu32, &requested.bars) != 1) {
403 if (sscanf (when_beat_entry.get_text().c_str(), "%" PRIu32, &requested.beats) != 1) {