X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Ftime_info_box.cc;h=d5d77acee8af1d729edc4fe49278d6d1790cd689;hb=14c390ed027b3ba1c48084502677d1a1287bfc05;hp=aeb361686ab67d73de885c646cacc562c521b078;hpb=57ce855053b26b5a8fdf7875c60d2dc23df5093e;p=ardour.git diff --git a/gtk2_ardour/time_info_box.cc b/gtk2_ardour/time_info_box.cc index aeb361686a..d5d77acee8 100644 --- a/gtk2_ardour/time_info_box.cc +++ b/gtk2_ardour/time_info_box.cc @@ -20,128 +20,119 @@ #include #include "pbd/compose.h" -#include "gtkmm2ext/cairocell.h" #include "gtkmm2ext/gui_thread.h" #include "gtkmm2ext/utils.h" -#include "gtkmm2ext/stateful_button.h" #include "gtkmm2ext/actions.h" #include "ardour/location.h" +#include "ardour/profile.h" #include "ardour/session.h" -#include "time_info_box.h" #include "audio_clock.h" -#include "editor.h" -#include "control_point.h" #include "automation_line.h" +#include "control_point.h" +#include "editor.h" +#include "region_view.h" +#include "time_info_box.h" -#include "i18n.h" +#include "pbd/i18n.h" using namespace Gtk; using namespace ARDOUR; using std::min; using std::max; -TimeInfoBox::TimeInfoBox () - : left (2, 4) - , right (2, 4) +TimeInfoBox::TimeInfoBox (std::string state_node_name, bool with_punch) + : table (3, 3) + , punch_start (0) + , punch_end (0) , syncing_selection (false) , syncing_punch (false) + , with_punch_clock (with_punch) { set_name (X_("TimeInfoBox")); - selection_start = new AudioClock ("selection-start", false, "selection", false, false, false, false); - selection_end = new AudioClock ("selection-end", false, "selection", false, false, false, false); - selection_length = new AudioClock ("selection-length", false, "selection", false, false, true, false); - - punch_start = new AudioClock ("punch-start", false, "punch", false, false, false, false); - punch_end = new AudioClock ("punch-end", false, "punch", false, false, false, false); - - selection_start->set_draw_background (false); - selection_end->set_draw_background (false); - selection_length->set_draw_background (false); - punch_start->set_draw_background (false); - punch_end->set_draw_background (false); + selection_start = new AudioClock ( + string_compose ("%1-selection-start", state_node_name), + false, "selection", false, false, false, false); + selection_end = new AudioClock ( + string_compose ("%1-selection-end", state_node_name), + false, "selection", false, false, false, false); + selection_length = new AudioClock ( + string_compose ("%1-selection-length", state_node_name), + false, "selection", false, false, true, false); selection_title.set_text (_("Selection")); - punch_title.set_text (_("Punch")); set_homogeneous (false); - set_spacing (6); + set_spacing (0); set_border_width (2); - pack_start (left, true, true); - pack_start (right, true, true); - - left.set_homogeneous (false); - left.set_spacings (0); - left.set_border_width (2); - left.set_col_spacings (2); + pack_start (table, false, false); - right.set_homogeneous (false); - right.set_spacings (0); - right.set_border_width (2); - right.set_col_spacings (2); + table.set_homogeneous (false); + table.set_spacings (0); + table.set_border_width (2); + table.set_col_spacings (2); Gtk::Label* l; selection_title.set_name ("TimeInfoSelectionTitle"); - left.attach (selection_title, 0, 2, 0, 1); + if (with_punch_clock) { + table.attach (selection_title, 1, 2, 0, 1); + } l = manage (new Label); l->set_text (_("Start")); l->set_alignment (1.0, 0.5); l->set_name (X_("TimeInfoSelectionLabel")); - left.attach (*l, 0, 1, 1, 2, FILL); - left.attach (*selection_start, 1, 2, 1, 2); + table.attach (*l, 0, 1, 1, 2, FILL); + table.attach (*selection_start, 1, 2, 1, 2); l = manage (new Label); l->set_text (_("End")); l->set_alignment (1.0, 0.5); l->set_name (X_("TimeInfoSelectionLabel")); - left.attach (*l, 0, 1, 2, 3, FILL); - left.attach (*selection_end, 1, 2, 2, 3); + table.attach (*l, 0, 1, 2, 3, FILL); + table.attach (*selection_end, 1, 2, 2, 3); l = manage (new Label); l->set_text (_("Length")); l->set_alignment (1.0, 0.5); l->set_name (X_("TimeInfoSelectionLabel")); - left.attach (*l, 0, 1, 3, 4, FILL); - left.attach (*selection_length, 1, 2, 3, 4); - - punch_in_button.set_name ("punch button"); - punch_out_button.set_name ("punch button"); - punch_in_button.set_text (_("In")); - punch_out_button.set_text (_("Out")); - - Glib::RefPtr act = ActionManager::get_action ("Transport", "TogglePunchIn"); - punch_in_button.set_related_action (act); - act = ActionManager::get_action ("Transport", "TogglePunchOut"); - punch_out_button.set_related_action (act); - - Gtkmm2ext::UI::instance()->set_tip (punch_in_button, _("Start recording at auto-punch start")); - Gtkmm2ext::UI::instance()->set_tip (punch_out_button, _("Stop recording at auto-punch end")); - - punch_title.set_name ("TimeInfoSelectionTitle"); - right.attach (punch_title, 2, 4, 0, 1); - right.attach (punch_in_button, 2, 3, 1, 2, FILL, SHRINK); - right.attach (*punch_start, 3, 4, 1, 2); - right.attach (punch_out_button, 2, 3, 2, 3, FILL, SHRINK); - right.attach (*punch_end, 3, 4, 2, 3); + table.attach (*l, 0, 1, 3, 4, FILL); + table.attach (*selection_length, 1, 2, 3, 4); + + if (with_punch_clock) { + punch_start = new AudioClock ( + string_compose ("%1-punch-start", state_node_name), + false, "punch", false, false, false, false); + punch_end = new AudioClock ( + string_compose ("%1-punch-end", state_node_name), + false, "punch", false, false, false, false); + punch_title.set_text (_("Punch")); + + punch_title.set_name ("TimeInfoSelectionTitle"); + table.attach (punch_title, 2, 3, 0, 1); + table.attach (*punch_start, 2, 3, 1, 2); + table.attach (*punch_end, 2, 3, 2, 3); + } - show_all (); + show_all (); selection_start->mode_changed.connect (sigc::bind (sigc::mem_fun (*this, &TimeInfoBox::sync_selection_mode), selection_start)); selection_end->mode_changed.connect (sigc::bind (sigc::mem_fun (*this, &TimeInfoBox::sync_selection_mode), selection_end)); selection_length->mode_changed.connect (sigc::bind (sigc::mem_fun (*this, &TimeInfoBox::sync_selection_mode), selection_length)); - punch_start->mode_changed.connect (sigc::bind (sigc::mem_fun (*this, &TimeInfoBox::sync_punch_mode), punch_start)); - punch_end->mode_changed.connect (sigc::bind (sigc::mem_fun (*this, &TimeInfoBox::sync_punch_mode), punch_end)); - selection_start->signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &TimeInfoBox::clock_button_release_event), selection_start), true); selection_end->signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &TimeInfoBox::clock_button_release_event), selection_end), true); - punch_start->signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &TimeInfoBox::clock_button_release_event), punch_start), true); - punch_end->signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &TimeInfoBox::clock_button_release_event), punch_end), true); + if (with_punch_clock) { + punch_start->mode_changed.connect (sigc::bind (sigc::mem_fun (*this, &TimeInfoBox::sync_punch_mode), punch_start)); + punch_end->mode_changed.connect (sigc::bind (sigc::mem_fun (*this, &TimeInfoBox::sync_punch_mode), punch_end)); + + punch_start->signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &TimeInfoBox::clock_button_release_event), punch_start), true); + punch_end->signal_button_release_event().connect (sigc::bind (sigc::mem_fun (*this, &TimeInfoBox::clock_button_release_event), punch_end), true); + } Editor::instance().get_selection().TimeChanged.connect (sigc::mem_fun (*this, &TimeInfoBox::selection_changed)); Editor::instance().get_selection().RegionsChanged.connect (sigc::mem_fun (*this, &TimeInfoBox::selection_changed)); @@ -151,12 +142,12 @@ TimeInfoBox::TimeInfoBox () TimeInfoBox::~TimeInfoBox () { - delete selection_length; - delete selection_end; - delete selection_start; - - delete punch_start; - delete punch_end; + delete selection_length; + delete selection_end; + delete selection_start; + + delete punch_start; + delete punch_end; } void @@ -197,6 +188,9 @@ TimeInfoBox::sync_selection_mode (AudioClock* src) void TimeInfoBox::sync_punch_mode (AudioClock* src) { + if (!with_punch_clock) { + return; + } if (!syncing_punch) { syncing_punch = true; punch_start->set_mode (src->mode()); @@ -204,7 +198,7 @@ TimeInfoBox::sync_punch_mode (AudioClock* src) syncing_punch = false; } } - + void TimeInfoBox::set_session (Session* s) @@ -215,83 +209,107 @@ TimeInfoBox::set_session (Session* s) selection_end->set_session (s); selection_length->set_session (s); + if (!with_punch_clock) { + return; + } + punch_start->set_session (s); punch_end->set_session (s); if (s) { Location* punch = s->locations()->auto_punch_location (); - + if (punch) { watch_punch (punch); } - + punch_changed (punch); - _session->auto_punch_location_changed.connect (_session_connections, MISSING_INVALIDATOR, - boost::bind (&TimeInfoBox::punch_location_changed, this, _1), gui_context()); + _session->auto_punch_location_changed.connect (_session_connections, MISSING_INVALIDATOR, + boost::bind (&TimeInfoBox::punch_location_changed, this, _1), gui_context()); } } +void +TimeInfoBox::region_selection_changed () +{ + samplepos_t s, e; + Selection& selection (Editor::instance().get_selection()); + s = selection.regions.start(); + e = selection.regions.end_sample(); + selection_start->set_off (false); + selection_end->set_off (false); + selection_length->set_off (false); + selection_start->set (s); + selection_end->set (e); + selection_length->set (e, false, s); +} + void TimeInfoBox::selection_changed () { - framepos_t s, e; + samplepos_t s, e; Selection& selection (Editor::instance().get_selection()); + region_property_connections.drop_connections(); + switch (Editor::instance().current_mouse_mode()) { + case Editing::MouseContent: + /* displaying MIDI note selection is tricky */ + selection_start->set_off (true); + selection_end->set_off (true); + selection_length->set_off (true); + break; + case Editing::MouseObject: - if (Editor::instance().internal_editing()) { - /* displaying MIDI note selection is tricky */ - - selection_start->set_off (true); - selection_end->set_off (true); - selection_length->set_off (true); + if (selection.regions.empty()) { + if (selection.points.empty()) { + Glib::RefPtr act = ActionManager::get_action ("MouseMode", "set-mouse-mode-object-range"); + Glib::RefPtr tact = Glib::RefPtr::cast_dynamic (act); - } else { - if (selection.regions.empty()) { - if (selection.points.empty()) { - Glib::RefPtr act = ActionManager::get_action ("MouseMode", "set-mouse-mode-object-range"); - Glib::RefPtr tact = Glib::RefPtr::cast_dynamic (act); - - if (tact && tact->get_active() && !selection.time.empty()) { - /* show selected range */ - selection_start->set_off (false); - selection_end->set_off (false); - selection_length->set_off (false); - selection_start->set (selection.time.start()); - selection_end->set (selection.time.end_frame()); - selection_length->set (selection.time.length()); - } else { - selection_start->set_off (true); - selection_end->set_off (true); - selection_length->set_off (true); - } - } else { - s = max_framepos; - e = 0; - for (PointSelection::iterator i = selection.points.begin(); i != selection.points.end(); ++i) { - framepos_t const p = (*i)->line().session_position ((*i)->model ()); - s = min (s, p); - e = max (e, p); - } + if (tact && tact->get_active() && !selection.time.empty()) { + /* show selected range */ selection_start->set_off (false); selection_end->set_off (false); selection_length->set_off (false); - selection_start->set (s); - selection_end->set (e); - selection_length->set (e - s + 1); + selection_start->set (selection.time.start()); + selection_end->set (selection.time.end_sample()); + selection_length->set (selection.time.end_sample(), false, selection.time.start()); + } else { + selection_start->set_off (true); + selection_end->set_off (true); + selection_length->set_off (true); } } else { - s = selection.regions.start(); - e = selection.regions.end_frame(); + s = max_samplepos; + e = 0; + for (PointSelection::iterator i = selection.points.begin(); i != selection.points.end(); ++i) { + samplepos_t const p = (*i)->line().session_position ((*i)->model ()); + s = min (s, p); + e = max (e, p); + } selection_start->set_off (false); selection_end->set_off (false); selection_length->set_off (false); selection_start->set (s); selection_end->set (e); - selection_length->set (e - s + 1); + selection_length->set (e, false, s); + } + } else { + /* this is more efficient than tracking changes per region in large selections */ + std::set > playlists; + for (RegionSelection::iterator s = selection.regions.begin(); s != selection.regions.end(); ++s) { + boost::shared_ptr pl = (*s)->region()->playlist(); + if (pl) { + playlists.insert (pl); + } + } + for (std::set >::iterator ps = playlists.begin(); ps != playlists.end(); ++ps) { + (*ps)->ContentsChanged.connect (region_property_connections, invalidator (*this), + boost::bind (&TimeInfoBox::region_selection_changed, this), gui_context()); } + region_selection_changed (); } break; @@ -300,16 +318,16 @@ TimeInfoBox::selection_changed () Glib::RefPtr act = ActionManager::get_action ("MouseMode", "set-mouse-mode-object-range"); Glib::RefPtr tact = Glib::RefPtr::cast_dynamic (act); - if (tact && tact->get_active() && !selection.regions.empty()) { + if (tact && tact->get_active() && !selection.regions.empty()) { /* show selected regions */ s = selection.regions.start(); - e = selection.regions.end_frame(); + e = selection.regions.end_sample(); selection_start->set_off (false); selection_end->set_off (false); selection_length->set_off (false); selection_start->set (s); selection_end->set (e); - selection_length->set (e - s + 1); + selection_length->set (e, false, s); } else { selection_start->set_off (true); selection_end->set_off (true); @@ -320,15 +338,15 @@ TimeInfoBox::selection_changed () selection_end->set_off (false); selection_length->set_off (false); selection_start->set (selection.time.start()); - selection_end->set (selection.time.end_frame()); - selection_length->set (selection.time.length()); + selection_end->set (selection.time.end_sample()); + selection_length->set (selection.time.end_sample(), false, selection.time.start()); } break; default: selection_start->set_off (true); selection_end->set_off (true); - selection_length->set_off (true); + selection_length->set_off (true); break; } } @@ -336,14 +354,15 @@ TimeInfoBox::selection_changed () void TimeInfoBox::punch_location_changed (Location* loc) { - if (loc) { + if (loc && with_punch_clock) { watch_punch (loc); - } + } } void TimeInfoBox::watch_punch (Location* punch) { + assert (with_punch_clock); punch_connections.drop_connections (); punch->start_changed.connect (punch_connections, MISSING_INVALIDATOR, boost::bind (&TimeInfoBox::punch_changed, this, _1), gui_context()); @@ -355,6 +374,7 @@ TimeInfoBox::watch_punch (Location* punch) void TimeInfoBox::punch_changed (Location* loc) { + assert (with_punch_clock); if (!loc) { punch_start->set_off (true); punch_end->set_off (true); @@ -366,5 +386,4 @@ TimeInfoBox::punch_changed (Location* loc) punch_start->set (loc->start()); punch_end->set (loc->end()); -} - +}