X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Ftime_info_box.cc;h=d0d6871cbb0c07a3626e035b12e3e9b4f986c89e;hb=cf52d6e4b40111eb04b244ec054055a4ec15dbe0;hp=ae3d3b65d4ced7414efc8a154f43467f2d145ce7;hpb=7e2b86dc835bd061786bffd0d503dfb3e8c74912;p=ardour.git diff --git a/gtk2_ardour/time_info_box.cc b/gtk2_ardour/time_info_box.cc index ae3d3b65d4..d0d6871cbb 100644 --- a/gtk2_ardour/time_info_box.cc +++ b/gtk2_ardour/time_info_box.cc @@ -17,110 +17,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 "i18n.h" +#include "pbd/i18n.h" using namespace Gtk; using namespace ARDOUR; +using std::min; +using std::max; TimeInfoBox::TimeInfoBox () - : Table (4, 4) + : left (2, 4) + , right (2, 4) , syncing_selection (false) , syncing_punch (false) { - selection_start = new AudioClock ("selection-start", false, "SelectionClockDisplay", false, false, false, false); - selection_end = new AudioClock ("selection-end", false, "SelectionClockDisplay", false, false, false, false); - selection_length = new AudioClock ("selection-length", false, "SelectionClockDisplay", false, false, true, false); - - punch_start = new AudioClock ("punch-start", false, "PunchClockDisplay", false, false, false, false); - punch_end = new AudioClock ("punch-end", false, "PunchClockDisplay", false, false, false, false); - - bool bg = true; - - CairoEditableText& ss (selection_start->main_display()); - ss.set_ypad (1); - ss.set_xpad (1); - ss.set_corner_radius (0); - ss.set_draw_background (bg); - - CairoEditableText& se (selection_end->main_display()); - se.set_ypad (1); - se.set_xpad (1); - se.set_corner_radius (0); - se.set_draw_background (bg); - - CairoEditableText& sl (selection_length->main_display()); - sl.set_ypad (1); - sl.set_xpad (2); - sl.set_corner_radius (0); - sl.set_draw_background (bg); - - CairoEditableText& ps (punch_start->main_display()); - ps.set_ypad (1); - ps.set_xpad (2); - ps.set_corner_radius (0); - ps.set_draw_background (bg); - - CairoEditableText& pe (punch_end->main_display()); - pe.set_ypad (1); - pe.set_xpad (2); - pe.set_corner_radius (0); - pe.set_draw_background (bg); - - selection_title.set_markup (string_compose ("%1", _("Selection"))); - punch_title.set_markup (string_compose ("%1", _("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_title.set_text (_("Selection")); + punch_title.set_text (_("Punch")); set_homogeneous (false); - set_spacings (0); + set_spacing (0); set_border_width (2); - set_col_spacings (2); - /* a bit more spacing between the two "sides" */ - set_col_spacing (1, 10); + pack_start (left, true, true); + if (!ARDOUR::Profile->get_trx()) { + pack_start (right, true, true); + } + + left.set_homogeneous (false); + left.set_spacings (0); + left.set_border_width (2); + left.set_col_spacings (2); + + right.set_homogeneous (false); + right.set_spacings (0); + right.set_border_width (2); + right.set_col_spacings (2); Gtk::Label* l; - attach (selection_title, 0, 2, 0, 1); - l = manage (new Label); - l->set_markup (string_compose ("%1", _("Start"))); - attach (*l, 0, 1, 1, 2); - attach (*selection_start, 1, 2, 1, 2); + selection_title.set_name ("TimeInfoSelectionTitle"); + left.attach (selection_title, 1, 2, 0, 1); l = manage (new Label); - l->set_markup (string_compose ("%1", _("End"))); - attach (*l, 0, 1, 2, 3); - attach (*selection_end, 1, 2, 2, 3); - l = manage (new Label); - l->set_markup (string_compose ("%1", _("Length"))); - attach (*l, 0, 1, 3, 4); - attach (*selection_length, 1, 2, 3, 4); + 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); - attach (punch_title, 2, 4, 0, 1); l = manage (new Label); - l->set_markup (string_compose ("%1", _("Start"))); - attach (*l, 2, 3, 1, 2); - attach (*punch_start, 3, 4, 1, 2); + 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); + l = manage (new Label); - l->set_markup (string_compose ("%1", _("End"))); - attach (*l, 2, 3, 2, 3); - attach (*punch_end, 3, 4, 2, 3); + 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, 3, 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); 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_start)); - selection_length->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)); @@ -132,6 +141,10 @@ TimeInfoBox::TimeInfoBox () 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)); + + Region::RegionPropertyChanged.connect (region_property_connections, invalidator (*this), boost::bind (&TimeInfoBox::region_property_change, this, _1, _2), gui_context()); + Editor::instance().MouseModeChanged.connect (editor_connections, invalidator(*this), boost::bind (&TimeInfoBox::track_mouse_mode, this), gui_context()); } TimeInfoBox::~TimeInfoBox () @@ -139,11 +152,44 @@ TimeInfoBox::~TimeInfoBox () delete selection_length; delete selection_end; delete selection_start; - + delete punch_start; delete punch_end; } +void +TimeInfoBox::track_mouse_mode () +{ + selection_changed (); +} + +void +TimeInfoBox::region_property_change (boost::shared_ptr /* r */, const PBD::PropertyChange& what_changed) +{ + Selection& selection (Editor::instance().get_selection()); + + if (selection.regions.empty()) { + return; + } + + PBD::PropertyChange our_interests; + + our_interests.add (ARDOUR::Properties::position); + our_interests.add (ARDOUR::Properties::length); + our_interests.add (ARDOUR::Properties::start); + + if (!what_changed.contains (our_interests)) { + return; + } + + /* TODO: check if RegionSelection includes the given region. + * This is not straight foward because RegionSelection is done by + * RegionView (not Region itself). + */ + + //selection_changed (); +} + bool TimeInfoBox::clock_button_release_event (GdkEventButton* ev, AudioClock* src) { @@ -152,7 +198,9 @@ TimeInfoBox::clock_button_release_event (GdkEventButton* ev, AudioClock* src) } if (ev->button == 1) { - _session->request_locate (src->current_time ()); + if (!src->off()) { + _session->request_locate (src->current_time ()); + } return true; } @@ -181,7 +229,7 @@ TimeInfoBox::sync_punch_mode (AudioClock* src) syncing_punch = false; } } - + void TimeInfoBox::set_session (Session* s) @@ -197,12 +245,14 @@ TimeInfoBox::set_session (Session* s) if (s) { Location* punch = s->locations()->auto_punch_location (); - + if (punch) { watch_punch (punch); } - - _session->auto_punch_location_changed.connect (_session_connections, MISSING_INVALIDATOR, + + punch_changed (punch); + + _session->auto_punch_location_changed.connect (_session_connections, MISSING_INVALIDATOR, boost::bind (&TimeInfoBox::punch_location_changed, this, _1), gui_context()); } } @@ -210,9 +260,100 @@ TimeInfoBox::set_session (Session* s) void TimeInfoBox::selection_changed () { - selection_start->set (Editor::instance().get_selection().time.start()); - selection_end->set (Editor::instance().get_selection().time.end_frame()); - selection_length->set (Editor::instance().get_selection().time.length()); + framepos_t s, e; + Selection& selection (Editor::instance().get_selection()); + + 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 (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); + } + 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); + } + } else { + s = selection.regions.start(); + e = selection.regions.end_frame(); + 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); + } + break; + + case Editing::MouseRange: + if (selection.time.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.regions.empty()) { + /* show selected regions */ + s = selection.regions.start(); + e = selection.regions.end_frame(); + 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); + } else { + selection_start->set_off (true); + selection_end->set_off (true); + selection_length->set_off (true); + } + } else { + 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()); + } + break; + + default: + selection_start->set_off (true); + selection_end->set_off (true); + selection_length->set_off (true); + break; + } } void @@ -220,7 +361,7 @@ TimeInfoBox::punch_location_changed (Location* loc) { if (loc) { watch_punch (loc); - } + } } void @@ -238,40 +379,15 @@ void TimeInfoBox::punch_changed (Location* loc) { if (!loc) { - punch_start->set (99999999); - punch_end->set (999999999); + punch_start->set_off (true); + punch_end->set_off (true); return; } + punch_start->set_off (false); + punch_end->set_off (false); + punch_start->set (loc->start()); punch_end->set (loc->end()); -} - -bool -TimeInfoBox::on_expose_event (GdkEventExpose* ev) -{ - { - int x, y; - Gtk::Widget* window_parent; - Glib::RefPtr win = Gtkmm2ext::window_to_draw_on (*this, &window_parent); - - if (win) { - - Cairo::RefPtr context = win->create_cairo_context(); - -#if 0 - translate_coordinates (*window_parent, ev->area.x, ev->area.y, x, y); - context->rectangle (x, y, ev->area.width, ev->area.height); - context->clip (); -#endif - translate_coordinates (*window_parent, 0, 0, x, y); - context->set_source_rgba (0.149, 0.149, 0.149, 1.0); - Gtkmm2ext::rounded_rectangle (context, x, y, get_allocation().get_width(), get_allocation().get_height(), 5); - context->fill (); - } - } - - Table::on_expose_event (ev); - - return false; } +