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"))
, _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);

View File

@ -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;

View File

@ -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)

View File

@ -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;

View File

@ -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)

View File

@ -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<ArdourMarker*> (p);
if (!marker) {
@ -1574,6 +1594,7 @@ Editor::dynamic_cast_marker_object (void* p, MeterMarker** m, TempoMarker** t) c
*m = dynamic_cast<MeterMarker*> (marker);
*t = dynamic_cast<TempoMarker*> (marker);
*b = dynamic_cast<BBTMarker*> (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<Temporal::MeterPoint&>(mm->meter()));
} else if (tm) {
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;
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;

View File

@ -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<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: {
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;

View File

@ -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<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
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<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
Editor::real_remove_tempo_marker (TempoPoint const * section)
{

View File

@ -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);