From fc6ad8ebd955560b742c149993dcf16bf6251cf2 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Wed, 17 Aug 2022 16:27:53 -0600 Subject: [PATCH] bbt markers: all the basics of dragging, editing, removing --- gtk2_ardour/bbt_marker_dialog.cc | 31 ++++++++++-- gtk2_ardour/bbt_marker_dialog.h | 6 +-- gtk2_ardour/editor.cc | 1 + gtk2_ardour/editor.h | 10 +++- gtk2_ardour/editor_drag.cc | 31 ++++++------ gtk2_ardour/editor_markers.cc | 46 ++++++++++++++---- gtk2_ardour/editor_mouse.cc | 35 +++++++++++--- gtk2_ardour/editor_tempodisplay.cc | 78 ++++++++++++++++++++++++++++++ gtk2_ardour/enums.cc | 1 + 9 files changed, 198 insertions(+), 41 deletions(-) diff --git a/gtk2_ardour/bbt_marker_dialog.cc b/gtk2_ardour/bbt_marker_dialog.cc index 34d531652e..d7df7d572e 100644 --- a/gtk2_ardour/bbt_marker_dialog.cc +++ b/gtk2_ardour/bbt_marker_dialog.cc @@ -33,11 +33,27 @@ BBTMarkerDialog::BBTMarkerDialog (timepos_t const & pos) : ArdourDialog (_("New Music Time")) , _point (0) , _position (pos) - , entry_label (_("Position")) + , entry_label (_("BBT")) , name_label (_("Name")) { - BBT_Time bbt = TempoMap::use()->bbt_at (pos).round_to_beat (); + init (true); +} + +BBTMarkerDialog::BBTMarkerDialog (MusicTimePoint& p) + : ArdourDialog (_("Edit Music Time")) + , _point (&p) + , _position (timepos_t::from_superclock (p.sclock())) + , entry_label (_("BBT")) + , name_label (_("Name")) +{ + init (false); +} + +void +BBTMarkerDialog::init (bool add) +{ + BBT_Time bbt = TempoMap::use()->bbt_at (_position).round_to_beat (); bar_entry.set_range (1, 9999); beat_entry.set_range (1, 9999); @@ -54,6 +70,10 @@ BBTMarkerDialog::BBTMarkerDialog (timepos_t const & pos) name_box.pack_start (name_label); name_box.pack_start (name_entry); + if (_point) { + name_entry.set_text (_point->name()); + } + name_entry.signal_activate().connect (sigc::bind (sigc::mem_fun (*this, &BBTMarkerDialog::response), Gtk::RESPONSE_OK)); get_vbox()->pack_start (name_box); @@ -63,7 +83,12 @@ BBTMarkerDialog::BBTMarkerDialog (timepos_t const & pos) name_box.show_all (); add_button (Stock::CANCEL, RESPONSE_CANCEL); - add_button (_("Add Marker"), RESPONSE_OK); + + if (add) { + add_button (_("Add Marker"), RESPONSE_OK); + } else { + add_button (_("Save Changes"), RESPONSE_OK); + } get_vbox()->set_border_width (12); get_vbox()->set_spacing (12); diff --git a/gtk2_ardour/bbt_marker_dialog.h b/gtk2_ardour/bbt_marker_dialog.h index 1c4b78ea43..805587b474 100644 --- a/gtk2_ardour/bbt_marker_dialog.h +++ b/gtk2_ardour/bbt_marker_dialog.h @@ -33,15 +33,15 @@ class BBTMarkerDialog : public ArdourDialog { public: - BBTMarkerDialog (Temporal::timepos_t const & ); - BBTMarkerDialog (Temporal::MusicTimePoint&, const std::string & action); + BBTMarkerDialog (Temporal::timepos_t const &); + BBTMarkerDialog (Temporal::MusicTimePoint&); Temporal::timepos_t position() const; Temporal::BBT_Time bbt_value () const; std::string name() const; private: - void init (); + void init (bool add); Temporal::MusicTimePoint* _point; Temporal::timepos_t _position; diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index 477430ad8d..90e134b18f 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -399,6 +399,7 @@ Editor::Editor () , time_line_group (0) , tempo_marker_menu (0) , meter_marker_menu (0) + , bbt_marker_menu (0) , marker_menu (0) , range_marker_menu (0) , new_transport_marker_menu (0) diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 7564631f88..7b85928603 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -598,6 +598,7 @@ public: void mouse_add_new_meter_event (Temporal::timepos_t where); void edit_tempo_section (Temporal::TempoPoint&); void edit_meter_section (Temporal::MeterPoint&); + void edit_bbt (Temporal::MusicTimePoint&); bool should_ripple () const; bool should_ripple_all () const; /* RippleAll will ripple all similar regions and the timeline markers */ @@ -1798,11 +1799,14 @@ private: void remove_tempo_marker (ArdourCanvas::Item*); void remove_meter_marker (ArdourCanvas::Item*); + void remove_bbt_marker (ArdourCanvas::Item*); gint real_remove_tempo_marker (Temporal::TempoPoint const *); gint real_remove_meter_marker (Temporal::MeterPoint const *); + gint real_remove_bbt_marker (Temporal::MusicTimePoint const *); void edit_tempo_marker (TempoMarker&); void edit_meter_marker (MeterMarker&); + void edit_bbt_marker (BBTMarker&); void edit_control_point (ArdourCanvas::Item*); void edit_notes (MidiRegionView*); void edit_region (RegionView*); @@ -1839,18 +1843,20 @@ private: void update_punch_range_view (); void new_transport_marker_menu_popdown (); void marker_context_menu (GdkEventButton*, ArdourCanvas::Item*); - void tempo_or_meter_marker_context_menu (GdkEventButton*, ArdourCanvas::Item*); + void tempo_map_marker_context_menu (GdkEventButton*, ArdourCanvas::Item*); void new_transport_marker_context_menu (GdkEventButton*, ArdourCanvas::Item*); void build_range_marker_menu (ARDOUR::Location*, bool, bool); void build_marker_menu (ARDOUR::Location*); void build_tempo_marker_menu (TempoMarker*, bool); void build_meter_marker_menu (MeterMarker*, bool); + void build_bbt_marker_menu (BBTMarker*); void build_new_transport_marker_menu (); - void dynamic_cast_marker_object (void*, MeterMarker**, TempoMarker**) const; + void dynamic_cast_marker_object (void*, MeterMarker**, TempoMarker**, BBTMarker**) const; Gtk::Menu* tempo_marker_menu; Gtk::Menu* meter_marker_menu; + Gtk::Menu* bbt_marker_menu; Gtk::Menu* marker_menu; Gtk::Menu* range_marker_menu; Gtk::Menu* new_transport_marker_menu; diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index dad57ea26f..5d94e5d1e5 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -3372,7 +3372,7 @@ TempoMarkerDrag::aborted (bool moved) // _point->end_float (); _marker->set_position (timepos_t (_marker->tempo().beats())); - if (moved) { + if (moved) { // delete the dummy (hidden) marker we used for events while moving. delete _marker; } @@ -3420,11 +3420,10 @@ BBTMarkerDrag::motion (GdkEvent* event, bool first_move) } timepos_t pos = adjusted_current_time (event); - /* XXX move marker position */ + + _marker->set_position (pos); /* XXXX update verbose cursor somehow */ - - _editor->mid_tempo_change (Editor::TempoChanged); } @@ -3439,8 +3438,7 @@ BBTMarkerDrag::finished (GdkEvent* event, bool movement_occurred) _editor->abort_tempo_map_edit (); if (was_double_click()) { - // XXX need edit_bbt_marker() - // _editor->edit_tempo_marker (*_marker); + _editor->edit_bbt_marker (*_marker); } return; @@ -3448,10 +3446,13 @@ BBTMarkerDrag::finished (GdkEvent* event, bool movement_occurred) /* push the current state of our writable map copy */ - map->remove_bartime (*_point); - // map->set_bartime (); + BBT_Time bbt (_point->bbt()); + string name (_point->name()); - _editor->commit_tempo_map_edit (map); + map->remove_bartime (*_point); + map->set_bartime (bbt, _marker->position(), name); + + _editor->commit_tempo_map_edit (map, true); XMLNode &after = map->get_state(); _editor->session()->add_command (new Temporal::TempoCommand (_("move BBT point"), _before_state, &after)); @@ -3461,14 +3462,12 @@ BBTMarkerDrag::finished (GdkEvent* event, bool movement_occurred) void BBTMarkerDrag::aborted (bool moved) { - /* reset the per-thread tempo map ptr back to the current - * official version - */ + if (moved) { + /* reset the marker back to the point's position + */ - _editor->abort_tempo_map_edit (); - - // _point->end_float (); - _marker->set_position (timepos_t::from_superclock (_marker->mt_point().sclock())); + _marker->set_position (_marker->mt_point().time()); + } } BBTRulerDrag::BBTRulerDrag (Editor* e, ArdourCanvas::Item* i) diff --git a/gtk2_ardour/editor_markers.cc b/gtk2_ardour/editor_markers.cc index 5cdd2f33cd..00ae562b90 100644 --- a/gtk2_ardour/editor_markers.cc +++ b/gtk2_ardour/editor_markers.cc @@ -946,13 +946,15 @@ Editor::location_gone (Location *location) } void -Editor::tempo_or_meter_marker_context_menu (GdkEventButton* ev, ArdourCanvas::Item* item) +Editor::tempo_map_marker_context_menu (GdkEventButton* ev, ArdourCanvas::Item* item) { marker_menu_item = item; MeterMarker* mm; TempoMarker* tm; - dynamic_cast_marker_object (marker_menu_item->get_data ("marker"), &mm, &tm); + BBTMarker* bm; + + dynamic_cast_marker_object (marker_menu_item->get_data ("marker"), &mm, &tm, &bm); bool can_remove = false; @@ -967,6 +969,9 @@ Editor::tempo_or_meter_marker_context_menu (GdkEventButton* ev, ArdourCanvas::It can_remove = !tm->tempo().map().is_initial(tm->tempo()) && !tm->tempo().locked_to_meter(); build_tempo_marker_menu (tm, can_remove); tempo_marker_menu->popup (1, ev->time); + } else if (bm) { + build_bbt_marker_menu (bm); + bbt_marker_menu->popup (1, ev->time); } else { return; } @@ -1198,6 +1203,21 @@ Editor::build_meter_marker_menu (MeterMarker* loc, bool can_remove) items.back().set_sensitive (can_remove); } +void +Editor::build_bbt_marker_menu (BBTMarker* loc) +{ + using namespace Menu_Helpers; + + delete meter_marker_menu; + bbt_marker_menu = new Menu; + + MenuList& items = bbt_marker_menu->items(); + bbt_marker_menu->set_name ("ArdourContextMenu"); + + items.push_back (MenuElem (_("Edit..."), sigc::mem_fun(*this, &Editor::marker_menu_edit))); + items.push_back (MenuElem (_("Remove"), sigc::mem_fun(*this, &Editor::marker_menu_remove))); +} + void Editor::build_new_transport_marker_menu () { @@ -1564,7 +1584,7 @@ Editor::marker_menu_zoom_to_range () } void -Editor::dynamic_cast_marker_object (void* p, MeterMarker** m, TempoMarker** t) const +Editor::dynamic_cast_marker_object (void* p, MeterMarker** m, TempoMarker** t, BBTMarker** b) const { ArdourMarker* marker = reinterpret_cast (p); if (!marker) { @@ -1574,6 +1594,7 @@ Editor::dynamic_cast_marker_object (void* p, MeterMarker** m, TempoMarker** t) c *m = dynamic_cast (marker); *t = dynamic_cast (marker); + *b = dynamic_cast (marker); } void @@ -1581,12 +1602,15 @@ Editor::marker_menu_edit () { MeterMarker* mm; TempoMarker* tm; - dynamic_cast_marker_object (marker_menu_item->get_data ("marker"), &mm, &tm); + BBTMarker* bm; + dynamic_cast_marker_object (marker_menu_item->get_data ("marker"), &mm, &tm, &bm); if (mm) { edit_meter_section (const_cast(mm->meter())); } else if (tm) { edit_tempo_section (const_cast(tm->tempo())); + } else if (bm) { + edit_bbt (const_cast(bm->mt_point())); } } @@ -1595,14 +1619,15 @@ Editor::marker_menu_remove () { MeterMarker* mm; TempoMarker* tm; - dynamic_cast_marker_object (marker_menu_item->get_data ("marker"), &mm, &tm); + BBTMarker* bm; + dynamic_cast_marker_object (marker_menu_item->get_data ("marker"), &mm, &tm, &bm); if (mm) { remove_meter_marker (marker_menu_item); } else if (tm) { remove_tempo_marker (marker_menu_item); } else { - remove_marker (*marker_menu_item); + remove_bbt_marker (marker_menu_item); } } @@ -1612,7 +1637,8 @@ Editor::toggle_tempo_type () { TempoMarker* tm; MeterMarker* mm; - dynamic_cast_marker_object (marker_menu_item->get_data ("marker"), &mm, &tm); + BBTMarker* bm; + dynamic_cast_marker_object (marker_menu_item->get_data ("marker"), &mm, &tm, &bm); if (tm) { @@ -1640,7 +1666,8 @@ Editor::toggle_tempo_continues () { TempoMarker* tm; MeterMarker* mm; - dynamic_cast_marker_object (marker_menu_item->get_data ("marker"), &mm, &tm); + BBTMarker* bm; + dynamic_cast_marker_object (marker_menu_item->get_data ("marker"), &mm, &tm, &bm); if (!tm) { return; @@ -1672,7 +1699,8 @@ Editor::ramp_to_next_tempo () TempoMarker* tm; MeterMarker* mm; - dynamic_cast_marker_object (marker_menu_item->get_data ("marker"), &mm, &tm); + BBTMarker* bm; + dynamic_cast_marker_object (marker_menu_item->get_data ("marker"), &mm, &tm, &bm); if (!tm) { return; diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index a82ef5651d..c172430e23 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -786,7 +786,6 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT return true; case TempoMarkerItem: - { if (ArdourKeyboard::indicates_constraint (event->button.state)) { _drags->set (new TempoEndDrag (this, item), event); } else { @@ -794,10 +793,12 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT } return true; - } + + case BBTMarkerItem: + _drags->set (new BBTMarkerDrag (this, item), event); + return true; case MeterMarkerItem: - { _drags->set ( new MeterMarkerDrag ( this, @@ -807,7 +808,6 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT event ); return true; - } case VideoBarItem: _drags->set (new VideoTimeLineDrag (this, item), event); @@ -1564,6 +1564,23 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT edit_tempo_marker (*tempo_marker); break; } + case BBTMarkerItem: { + ArdourMarker* marker; + BBTMarker* bbt_marker; + + if ((marker = reinterpret_cast (item->get_data ("marker"))) == 0) { + fatal << _("programming error: bbt marker canvas item has no marker object pointer!") << endmsg; + abort(); /*NOTREACHED*/ + } + + if ((bbt_marker = dynamic_cast (marker)) == 0) { + fatal << _("programming error: marker for bbt is not a bbt marker!") << endmsg; + abort(); /*NOTREACHED*/ + } + + edit_bbt_marker (*bbt_marker); + break; + } case MeterMarkerItem: { ArdourMarker* marker; @@ -1672,11 +1689,9 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT break; case TempoMarkerItem: - tempo_or_meter_marker_context_menu (&event->button, item); - break; - case MeterMarkerItem: - tempo_or_meter_marker_context_menu (&event->button, item); + case BBTMarkerItem: + tempo_map_marker_context_menu (&event->button, item); break; case CrossfadeViewItem: @@ -1712,6 +1727,10 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT remove_tempo_marker (item); break; + case BBTMarkerItem: + remove_bbt_marker (item); + break; + case MeterMarkerItem: remove_meter_marker (item); break; diff --git a/gtk2_ardour/editor_tempodisplay.cc b/gtk2_ardour/editor_tempodisplay.cc index 72b654a1c3..2d4ad9d58e 100644 --- a/gtk2_ardour/editor_tempodisplay.cc +++ b/gtk2_ardour/editor_tempodisplay.cc @@ -50,6 +50,7 @@ #include "canvas/item.h" #include "canvas/line_set.h" +#include "bbt_marker_dialog.h" #include "editor.h" #include "marker.h" #include "tempo_dialog.h" @@ -539,6 +540,25 @@ Editor::mouse_add_new_meter_event (timepos_t pos) //map.dump (cerr); } +void +Editor::remove_bbt_marker (ArdourCanvas::Item* item) +{ + ArdourMarker* marker; + BBTMarker* bbt_marker; + + if ((marker = reinterpret_cast (item->get_data ("marker"))) == 0) { + fatal << _("programming error: bbt marker canvas item has no marker object pointer!") << endmsg; + abort(); /*NOTREACHED*/ + } + + if ((bbt_marker = dynamic_cast (marker)) == 0) { + fatal << _("programming error: marker for bbt is not a bbt marker!") << endmsg; + abort(); /*NOTREACHED*/ + } + + Glib::signal_idle().connect (sigc::bind (sigc::mem_fun(*this, &Editor::real_remove_bbt_marker), &bbt_marker->mt_point())); +} + void Editor::remove_tempo_marker (ArdourCanvas::Item* item) { @@ -597,6 +617,42 @@ Editor::edit_meter_section (Temporal::MeterPoint& section) TempoMap::update (tmap); } +void +Editor::edit_bbt (MusicTimePoint& point) +{ + BBTMarkerDialog dialog (point); + + switch (dialog.run ()) { + case RESPONSE_OK: + case RESPONSE_ACCEPT: + break; + default: + return; + } + + if (dialog.bbt_value() == point.bbt()) { + /* just a name change, no need to modify the map */ + point.set_name (dialog.name()); + /* XXX need to update marker label */ + return; + } + + TempoMap::WritableSharedPtr tmap (TempoMap::write_copy()); + reassociate_metric_markers (tmap); + + begin_reversible_command (_("Edit Tempo")); + XMLNode &before = tmap->get_state(); + + tmap->remove_bartime (point); + tmap->set_bartime (dialog.bbt_value(), dialog.position(), dialog.name()); + + XMLNode &after = tmap->get_state(); + _session->add_command (new Temporal::TempoCommand (_("edit tempo"), &before, &after)); + commit_reversible_command (); + + TempoMap::update (tmap); +} + void Editor::edit_tempo_section (TempoPoint& section) { @@ -646,6 +702,28 @@ Editor::edit_meter_marker (MeterMarker& mm) edit_meter_section (const_cast(mm.meter())); } +void +Editor::edit_bbt_marker (BBTMarker& bm) +{ + edit_bbt (const_cast(bm.mt_point())); +} + +gint +Editor::real_remove_bbt_marker (MusicTimePoint const * point) +{ + begin_reversible_command (_("remove BBT marker")); + TempoMap::WritableSharedPtr tmap (TempoMap::write_copy()); + XMLNode &before = tmap->get_state(); + tmap->remove_bartime (*point); + XMLNode &after = tmap->get_state(); + _session->add_command (new Temporal::TempoCommand (_("remove BBT marker"), &before, &after)); + commit_reversible_command (); + + TempoMap::update (tmap); + + return FALSE; +} + gint Editor::real_remove_tempo_marker (TempoPoint const * section) { diff --git a/gtk2_ardour/enums.cc b/gtk2_ardour/enums.cc index 25120a218d..761268cde7 100644 --- a/gtk2_ardour/enums.cc +++ b/gtk2_ardour/enums.cc @@ -158,6 +158,7 @@ setup_gtk_ardour_enums () REGISTER_ENUM (MeterMarkerItem); REGISTER_ENUM (TempoCurveItem); REGISTER_ENUM (TempoMarkerItem); + REGISTER_ENUM (BBTMarkerItem); REGISTER_ENUM (MeterBarItem); REGISTER_ENUM (TempoBarItem); REGISTER_ENUM (RegionViewNameHighlight);