diff --git a/gtk2_ardour/bbt_marker_dialog.cc b/gtk2_ardour/bbt_marker_dialog.cc new file mode 100644 index 0000000000..d0e23941db --- /dev/null +++ b/gtk2_ardour/bbt_marker_dialog.cc @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2021 Paul Davis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "pbd/i18n.h" + +#include + +#include "bbt_marker_dialog.h" + +using namespace std; +using namespace Gtk; +using namespace Gtkmm2ext; +using namespace ARDOUR; +using namespace PBD; +using namespace Temporal; + +BBTMarkerDialog::BBTMarkerDialog (timepos_t const & pos) + : ArdourDialog (_("New Music Time")) + , _point (0) + , _position (pos) + , entry_label (_("Position")) + +{ + BBT_Time bbt = TempoMap::use()->bbt_at (pos).round_to_beat (); + + bar_entry.set_range (1, 9999); + beat_entry.set_range (1, 9999); + bar_entry.set_digits (0); + beat_entry.set_digits (0); + + bbt_box.pack_start (entry_label); + bbt_box.pack_start (bar_entry); + bbt_box.pack_start (beat_entry); + + bar_entry.set_value (bbt.bars); + beat_entry.set_value (bbt.beats); + + get_vbox()->pack_start (bbt_box); + bbt_box.show_all (); + + add_button (Stock::CANCEL, RESPONSE_CANCEL); + add_button (_("Add Marker"), RESPONSE_OK); +} + +BBT_Time +BBTMarkerDialog::bbt_value () const +{ + int bars = bar_entry.get_value_as_int(); + int beats = beat_entry.get_value_as_int(); + + return BBT_Time (bars, beats, 0); +} + +timepos_t +BBTMarkerDialog::position() const +{ + return _position; +} diff --git a/gtk2_ardour/bbt_marker_dialog.h b/gtk2_ardour/bbt_marker_dialog.h new file mode 100644 index 0000000000..c09b6323cb --- /dev/null +++ b/gtk2_ardour/bbt_marker_dialog.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2021 Paul Davis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __ardour_gtk_bbt_marker_dialog_h__ +#define __ardour_gtk_bbt_marker_dialog_h__ + +#include +#include +#include + +#include "temporal/tempo.h" +#include "temporal/types.h" + +#include "ardour_dialog.h" +#include "audio_clock.h" + +class BBTMarkerDialog : public ArdourDialog +{ +public: + BBTMarkerDialog (Temporal::timepos_t const & ); + BBTMarkerDialog (Temporal::MusicTimePoint&, const std::string & action); + + Temporal::timepos_t position() const; + Temporal::BBT_Time bbt_value () const; + +private: + void init (); + Temporal::MusicTimePoint* _point; + Temporal::timepos_t _position; + + Gtk::HBox bbt_box; + Gtk::SpinButton bar_entry; + Gtk::SpinButton beat_entry; + Gtk::Label entry_label; +}; + +#endif /* __ardour_gtk_bbt_marker_dialog_h__ */ diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index 36a872314d..9c7b595c49 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -56,6 +56,7 @@ #include "editor.h" #include "pbd/i18n.h" +#include "bbt_marker_dialog.h" #include "keyboard.h" #include "audio_region_view.h" #include "automation_region_view.h" @@ -3747,6 +3748,7 @@ BBTRulerDrag::BBTRulerDrag (Editor* e, ArdourCanvas::Item* i) , _tempo (0) , _before_state (0) , _drag_valid (true) + , marker_dialog (0) { DEBUG_TRACE (DEBUG::Drags, "New BBTRulerDrag\n"); @@ -3755,10 +3757,10 @@ BBTRulerDrag::BBTRulerDrag (Editor* e, ArdourCanvas::Item* i) void BBTRulerDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor) { - Drag::start_grab (event, cursor); - TempoMap::fetch_writable (); + Drag::start_grab (event, cursor); + TempoMap::SharedPtr map (TempoMap::use()); _tempo = const_cast (&map->metric_at (raw_grab_time().beats()).tempo()); @@ -3838,6 +3840,51 @@ BBTRulerDrag::motion (GdkEvent* event, bool first_move) show_verbose_cursor_text (sstr.str()); } +void +BBTRulerDrag::begin_position_marker_creation (timepos_t const & pos) +{ + marker_dialog = new BBTMarkerDialog (pos); + + /* run this modally since we are finishing a drag and the drag object + * will be destroyed when we return from here + */ + + int response = marker_dialog->run (); + finish_position_marker_creation (response); +} + +void +BBTRulerDrag::finish_position_marker_creation (int result) +{ + BBT_Time bbt; + bool commit = false; + TempoMap::SharedPtr map (TempoMap::use()); + + switch (result) { + case RESPONSE_ACCEPT: + case RESPONSE_OK: + bbt = marker_dialog->bbt_value (); + map->set_bartime (bbt, marker_dialog->position()); + commit = true; + break; + default: + break; + } + + delete marker_dialog; + marker_dialog = 0; + + if (commit) { + TempoMap::update (map); + XMLNode &after = TempoMap::use()->get_state(); + + _editor->session()->add_command(new MementoCommand(new Temporal::TempoMap::MementoBinder(), _before_state, &after)); + _editor->commit_reversible_command (); + } else { + TempoMap::abort_update (); + } +} + void BBTRulerDrag::finished (GdkEvent* event, bool movement_occurred) { @@ -3851,7 +3898,9 @@ BBTRulerDrag::finished (GdkEvent* event, bool movement_occurred) if (!movement_occurred) { _editor->begin_reversible_command (_("add BBT marker")); - map->set_bartime (BBT_Time (3, 1, 0), grab_time()); + /* position markers must always be positioned using audio time */ + begin_position_marker_creation (timepos_t (grab_sample())); + return; } else { diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h index 06aa46b9c4..29d423bea1 100644 --- a/gtk2_ardour/editor_drag.h +++ b/gtk2_ardour/editor_drag.h @@ -58,6 +58,7 @@ namespace PBD { class StatefulDiffCommand; } +class BBTMarkerDialog; class PatchChange; class Editor; class EditorCursor; @@ -906,6 +907,10 @@ private: Temporal::TempoPoint* _tempo; XMLNode* _before_state; bool _drag_valid; + BBTMarkerDialog* marker_dialog; + + void begin_position_marker_creation (Temporal::timepos_t const &); + void finish_position_marker_creation (int response); }; #warning NUTEMPO may or may not need this in the new world diff --git a/gtk2_ardour/marker.cc b/gtk2_ardour/marker.cc index 523f80da17..533bf8459c 100644 --- a/gtk2_ardour/marker.cc +++ b/gtk2_ardour/marker.cc @@ -99,6 +99,7 @@ ArdourMarker::ArdourMarker (PublicEditor& ed, ArdourCanvas::Container& parent, g * * Mark: * RegionCue: + * BBTPosition * * (0,0) -> (6,0) * ^ | @@ -110,7 +111,6 @@ ArdourMarker::ArdourMarker (PublicEditor& ed, ArdourCanvas::Container& parent, g * * TempoMark: * MeterMark: - * BBTPosition * * (3,0) * / \ @@ -171,6 +171,7 @@ ArdourMarker::ArdourMarker (PublicEditor& ed, ArdourCanvas::Container& parent, g switch (type) { case Mark: case RegionCue: + case BBTPosition: points = new ArdourCanvas::Points (); points->push_back (ArdourCanvas::Duple (0.0, 0.0)); @@ -186,7 +187,6 @@ ArdourMarker::ArdourMarker (PublicEditor& ed, ArdourCanvas::Container& parent, g case Tempo: case Meter: - case BBTPosition: points = new ArdourCanvas::Points (); points->push_back (ArdourCanvas::Duple ( M3, 0.0)); points->push_back (ArdourCanvas::Duple ( M6, MH * .6)); @@ -700,7 +700,6 @@ BBTMarker::BBTMarker (PublicEditor& editor, ArdourCanvas::Item& parent, guint32 : ArdourMarker (editor, parent, rgba, text, BBTPosition, p.time(), false) , _point (p) { - cerr << "NEW BBT MARKER!\n"; group->Event.connect (sigc::bind (sigc::mem_fun (editor, &PublicEditor::canvas_bbt_marker_event), group, this)); } diff --git a/gtk2_ardour/wscript b/gtk2_ardour/wscript index 1f063b1197..df3620f985 100644 --- a/gtk2_ardour/wscript +++ b/gtk2_ardour/wscript @@ -61,6 +61,7 @@ gtk2_ardour_sources = [ 'automation_time_axis.cc', 'axis_view.cc', 'beatbox_gui.cc', + 'bbt_marker_dialog.cc', 'big_clock_window.cc', 'big_transport_window.cc', 'bundle_manager.cc',