bbt markers: all the basics of dragging, editing, removing

This commit is contained in:
Paul Davis 2022-08-17 16:27:53 -06:00
parent 025dfa6062
commit fc6ad8ebd9
9 changed files with 198 additions and 41 deletions

View file

@ -33,11 +33,27 @@ BBTMarkerDialog::BBTMarkerDialog (timepos_t const & pos)
: ArdourDialog (_("New Music Time")) : ArdourDialog (_("New Music Time"))
, _point (0) , _point (0)
, _position (pos) , _position (pos)
, entry_label (_("Position")) , entry_label (_("BBT"))
, name_label (_("Name")) , 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); bar_entry.set_range (1, 9999);
beat_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_label);
name_box.pack_start (name_entry); 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)); name_entry.signal_activate().connect (sigc::bind (sigc::mem_fun (*this, &BBTMarkerDialog::response), Gtk::RESPONSE_OK));
get_vbox()->pack_start (name_box); get_vbox()->pack_start (name_box);
@ -63,7 +83,12 @@ BBTMarkerDialog::BBTMarkerDialog (timepos_t const & pos)
name_box.show_all (); name_box.show_all ();
add_button (Stock::CANCEL, RESPONSE_CANCEL); 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_border_width (12);
get_vbox()->set_spacing (12); get_vbox()->set_spacing (12);

View file

@ -33,15 +33,15 @@
class BBTMarkerDialog : public ArdourDialog class BBTMarkerDialog : public ArdourDialog
{ {
public: public:
BBTMarkerDialog (Temporal::timepos_t const & ); BBTMarkerDialog (Temporal::timepos_t const &);
BBTMarkerDialog (Temporal::MusicTimePoint&, const std::string & action); BBTMarkerDialog (Temporal::MusicTimePoint&);
Temporal::timepos_t position() const; Temporal::timepos_t position() const;
Temporal::BBT_Time bbt_value () const; Temporal::BBT_Time bbt_value () const;
std::string name() const; std::string name() const;
private: private:
void init (); void init (bool add);
Temporal::MusicTimePoint* _point; Temporal::MusicTimePoint* _point;
Temporal::timepos_t _position; Temporal::timepos_t _position;

View file

@ -399,6 +399,7 @@ Editor::Editor ()
, time_line_group (0) , time_line_group (0)
, tempo_marker_menu (0) , tempo_marker_menu (0)
, meter_marker_menu (0) , meter_marker_menu (0)
, bbt_marker_menu (0)
, marker_menu (0) , marker_menu (0)
, range_marker_menu (0) , range_marker_menu (0)
, new_transport_marker_menu (0) , new_transport_marker_menu (0)

View file

@ -598,6 +598,7 @@ public:
void mouse_add_new_meter_event (Temporal::timepos_t where); void mouse_add_new_meter_event (Temporal::timepos_t where);
void edit_tempo_section (Temporal::TempoPoint&); void edit_tempo_section (Temporal::TempoPoint&);
void edit_meter_section (Temporal::MeterPoint&); void edit_meter_section (Temporal::MeterPoint&);
void edit_bbt (Temporal::MusicTimePoint&);
bool should_ripple () const; bool should_ripple () const;
bool should_ripple_all () const; /* RippleAll will ripple all similar regions and the timeline markers */ 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_tempo_marker (ArdourCanvas::Item*);
void remove_meter_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_tempo_marker (Temporal::TempoPoint const *);
gint real_remove_meter_marker (Temporal::MeterPoint const *); gint real_remove_meter_marker (Temporal::MeterPoint const *);
gint real_remove_bbt_marker (Temporal::MusicTimePoint const *);
void edit_tempo_marker (TempoMarker&); void edit_tempo_marker (TempoMarker&);
void edit_meter_marker (MeterMarker&); void edit_meter_marker (MeterMarker&);
void edit_bbt_marker (BBTMarker&);
void edit_control_point (ArdourCanvas::Item*); void edit_control_point (ArdourCanvas::Item*);
void edit_notes (MidiRegionView*); void edit_notes (MidiRegionView*);
void edit_region (RegionView*); void edit_region (RegionView*);
@ -1839,18 +1843,20 @@ private:
void update_punch_range_view (); void update_punch_range_view ();
void new_transport_marker_menu_popdown (); void new_transport_marker_menu_popdown ();
void marker_context_menu (GdkEventButton*, ArdourCanvas::Item*); 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 new_transport_marker_context_menu (GdkEventButton*, ArdourCanvas::Item*);
void build_range_marker_menu (ARDOUR::Location*, bool, bool); void build_range_marker_menu (ARDOUR::Location*, bool, bool);
void build_marker_menu (ARDOUR::Location*); void build_marker_menu (ARDOUR::Location*);
void build_tempo_marker_menu (TempoMarker*, bool); void build_tempo_marker_menu (TempoMarker*, bool);
void build_meter_marker_menu (MeterMarker*, bool); void build_meter_marker_menu (MeterMarker*, bool);
void build_bbt_marker_menu (BBTMarker*);
void build_new_transport_marker_menu (); 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* tempo_marker_menu;
Gtk::Menu* meter_marker_menu; Gtk::Menu* meter_marker_menu;
Gtk::Menu* bbt_marker_menu;
Gtk::Menu* marker_menu; Gtk::Menu* marker_menu;
Gtk::Menu* range_marker_menu; Gtk::Menu* range_marker_menu;
Gtk::Menu* new_transport_marker_menu; Gtk::Menu* new_transport_marker_menu;

View file

@ -3372,7 +3372,7 @@ TempoMarkerDrag::aborted (bool moved)
// _point->end_float (); // _point->end_float ();
_marker->set_position (timepos_t (_marker->tempo().beats())); _marker->set_position (timepos_t (_marker->tempo().beats()));
if (moved) { if (moved) {
// delete the dummy (hidden) marker we used for events while moving. // delete the dummy (hidden) marker we used for events while moving.
delete _marker; delete _marker;
} }
@ -3420,11 +3420,10 @@ BBTMarkerDrag::motion (GdkEvent* event, bool first_move)
} }
timepos_t pos = adjusted_current_time (event); timepos_t pos = adjusted_current_time (event);
/* XXX move marker position */
_marker->set_position (pos);
/* XXXX update verbose cursor somehow */ /* 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 (); _editor->abort_tempo_map_edit ();
if (was_double_click()) { if (was_double_click()) {
// XXX need edit_bbt_marker() _editor->edit_bbt_marker (*_marker);
// _editor->edit_tempo_marker (*_marker);
} }
return; return;
@ -3448,10 +3446,13 @@ BBTMarkerDrag::finished (GdkEvent* event, bool movement_occurred)
/* push the current state of our writable map copy */ /* push the current state of our writable map copy */
map->remove_bartime (*_point); BBT_Time bbt (_point->bbt());
// map->set_bartime (); 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(); XMLNode &after = map->get_state();
_editor->session()->add_command (new Temporal::TempoCommand (_("move BBT point"), _before_state, &after)); _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 void
BBTMarkerDrag::aborted (bool moved) BBTMarkerDrag::aborted (bool moved)
{ {
/* reset the per-thread tempo map ptr back to the current if (moved) {
* official version /* reset the marker back to the point's position
*/ */
_editor->abort_tempo_map_edit (); _marker->set_position (_marker->mt_point().time());
}
// _point->end_float ();
_marker->set_position (timepos_t::from_superclock (_marker->mt_point().sclock()));
} }
BBTRulerDrag::BBTRulerDrag (Editor* e, ArdourCanvas::Item* i) BBTRulerDrag::BBTRulerDrag (Editor* e, ArdourCanvas::Item* i)

View file

@ -946,13 +946,15 @@ Editor::location_gone (Location *location)
} }
void 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; marker_menu_item = item;
MeterMarker* mm; MeterMarker* mm;
TempoMarker* tm; 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; 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(); can_remove = !tm->tempo().map().is_initial(tm->tempo()) && !tm->tempo().locked_to_meter();
build_tempo_marker_menu (tm, can_remove); build_tempo_marker_menu (tm, can_remove);
tempo_marker_menu->popup (1, ev->time); tempo_marker_menu->popup (1, ev->time);
} else if (bm) {
build_bbt_marker_menu (bm);
bbt_marker_menu->popup (1, ev->time);
} else { } else {
return; return;
} }
@ -1198,6 +1203,21 @@ Editor::build_meter_marker_menu (MeterMarker* loc, bool can_remove)
items.back().set_sensitive (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 void
Editor::build_new_transport_marker_menu () Editor::build_new_transport_marker_menu ()
{ {
@ -1564,7 +1584,7 @@ Editor::marker_menu_zoom_to_range ()
} }
void 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<ArdourMarker*> (p); ArdourMarker* marker = reinterpret_cast<ArdourMarker*> (p);
if (!marker) { if (!marker) {
@ -1574,6 +1594,7 @@ Editor::dynamic_cast_marker_object (void* p, MeterMarker** m, TempoMarker** t) c
*m = dynamic_cast<MeterMarker*> (marker); *m = dynamic_cast<MeterMarker*> (marker);
*t = dynamic_cast<TempoMarker*> (marker); *t = dynamic_cast<TempoMarker*> (marker);
*b = dynamic_cast<BBTMarker*> (marker);
} }
void void
@ -1581,12 +1602,15 @@ Editor::marker_menu_edit ()
{ {
MeterMarker* mm; MeterMarker* mm;
TempoMarker* tm; 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) { if (mm) {
edit_meter_section (const_cast<Temporal::MeterPoint&>(mm->meter())); edit_meter_section (const_cast<Temporal::MeterPoint&>(mm->meter()));
} else if (tm) { } else if (tm) {
edit_tempo_section (const_cast<Temporal::TempoPoint&>(tm->tempo())); edit_tempo_section (const_cast<Temporal::TempoPoint&>(tm->tempo()));
} else if (bm) {
edit_bbt (const_cast<Temporal::MusicTimePoint&>(bm->mt_point()));
} }
} }
@ -1595,14 +1619,15 @@ Editor::marker_menu_remove ()
{ {
MeterMarker* mm; MeterMarker* mm;
TempoMarker* tm; 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) { if (mm) {
remove_meter_marker (marker_menu_item); remove_meter_marker (marker_menu_item);
} else if (tm) { } else if (tm) {
remove_tempo_marker (marker_menu_item); remove_tempo_marker (marker_menu_item);
} else { } else {
remove_marker (*marker_menu_item); remove_bbt_marker (marker_menu_item);
} }
} }
@ -1612,7 +1637,8 @@ Editor::toggle_tempo_type ()
{ {
TempoMarker* tm; TempoMarker* tm;
MeterMarker* mm; 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) { if (tm) {
@ -1640,7 +1666,8 @@ Editor::toggle_tempo_continues ()
{ {
TempoMarker* tm; TempoMarker* tm;
MeterMarker* mm; 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) { if (!tm) {
return; return;
@ -1672,7 +1699,8 @@ Editor::ramp_to_next_tempo ()
TempoMarker* tm; TempoMarker* tm;
MeterMarker* mm; 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) { if (!tm) {
return; return;

View file

@ -786,7 +786,6 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
return true; return true;
case TempoMarkerItem: case TempoMarkerItem:
{
if (ArdourKeyboard::indicates_constraint (event->button.state)) { if (ArdourKeyboard::indicates_constraint (event->button.state)) {
_drags->set (new TempoEndDrag (this, item), event); _drags->set (new TempoEndDrag (this, item), event);
} else { } else {
@ -794,10 +793,12 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
} }
return true; return true;
}
case BBTMarkerItem:
_drags->set (new BBTMarkerDrag (this, item), event);
return true;
case MeterMarkerItem: case MeterMarkerItem:
{
_drags->set ( _drags->set (
new MeterMarkerDrag ( new MeterMarkerDrag (
this, this,
@ -807,7 +808,6 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT
event event
); );
return true; return true;
}
case VideoBarItem: case VideoBarItem:
_drags->set (new VideoTimeLineDrag (this, item), event); _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); edit_tempo_marker (*tempo_marker);
break; break;
} }
case BBTMarkerItem: {
ArdourMarker* marker;
BBTMarker* bbt_marker;
if ((marker = reinterpret_cast<ArdourMarker *> (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<BBTMarker*> (marker)) == 0) {
fatal << _("programming error: marker for bbt is not a bbt marker!") << endmsg;
abort(); /*NOTREACHED*/
}
edit_bbt_marker (*bbt_marker);
break;
}
case MeterMarkerItem: { case MeterMarkerItem: {
ArdourMarker* marker; ArdourMarker* marker;
@ -1672,11 +1689,9 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
break; break;
case TempoMarkerItem: case TempoMarkerItem:
tempo_or_meter_marker_context_menu (&event->button, item);
break;
case MeterMarkerItem: case MeterMarkerItem:
tempo_or_meter_marker_context_menu (&event->button, item); case BBTMarkerItem:
tempo_map_marker_context_menu (&event->button, item);
break; break;
case CrossfadeViewItem: case CrossfadeViewItem:
@ -1712,6 +1727,10 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT
remove_tempo_marker (item); remove_tempo_marker (item);
break; break;
case BBTMarkerItem:
remove_bbt_marker (item);
break;
case MeterMarkerItem: case MeterMarkerItem:
remove_meter_marker (item); remove_meter_marker (item);
break; break;

View file

@ -50,6 +50,7 @@
#include "canvas/item.h" #include "canvas/item.h"
#include "canvas/line_set.h" #include "canvas/line_set.h"
#include "bbt_marker_dialog.h"
#include "editor.h" #include "editor.h"
#include "marker.h" #include "marker.h"
#include "tempo_dialog.h" #include "tempo_dialog.h"
@ -539,6 +540,25 @@ Editor::mouse_add_new_meter_event (timepos_t pos)
//map.dump (cerr); //map.dump (cerr);
} }
void
Editor::remove_bbt_marker (ArdourCanvas::Item* item)
{
ArdourMarker* marker;
BBTMarker* bbt_marker;
if ((marker = reinterpret_cast<ArdourMarker *> (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<BBTMarker*> (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 void
Editor::remove_tempo_marker (ArdourCanvas::Item* item) Editor::remove_tempo_marker (ArdourCanvas::Item* item)
{ {
@ -597,6 +617,42 @@ Editor::edit_meter_section (Temporal::MeterPoint& section)
TempoMap::update (tmap); 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 void
Editor::edit_tempo_section (TempoPoint& section) Editor::edit_tempo_section (TempoPoint& section)
{ {
@ -646,6 +702,28 @@ Editor::edit_meter_marker (MeterMarker& mm)
edit_meter_section (const_cast<Temporal::MeterPoint&>(mm.meter())); edit_meter_section (const_cast<Temporal::MeterPoint&>(mm.meter()));
} }
void
Editor::edit_bbt_marker (BBTMarker& bm)
{
edit_bbt (const_cast<Temporal::MusicTimePoint&>(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 gint
Editor::real_remove_tempo_marker (TempoPoint const * section) Editor::real_remove_tempo_marker (TempoPoint const * section)
{ {

View file

@ -158,6 +158,7 @@ setup_gtk_ardour_enums ()
REGISTER_ENUM (MeterMarkerItem); REGISTER_ENUM (MeterMarkerItem);
REGISTER_ENUM (TempoCurveItem); REGISTER_ENUM (TempoCurveItem);
REGISTER_ENUM (TempoMarkerItem); REGISTER_ENUM (TempoMarkerItem);
REGISTER_ENUM (BBTMarkerItem);
REGISTER_ENUM (MeterBarItem); REGISTER_ENUM (MeterBarItem);
REGISTER_ENUM (TempoBarItem); REGISTER_ENUM (TempoBarItem);
REGISTER_ENUM (RegionViewNameHighlight); REGISTER_ENUM (RegionViewNameHighlight);