From ece37d9ca0f55c7be050464a95bba79ee19e3442 Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Tue, 16 Feb 2021 00:27:29 +0100 Subject: [PATCH] RecorderUI: Implement track renaming --- gtk2_ardour/recorder_ui.cc | 15 +++ gtk2_ardour/recorder_ui.h | 1 + gtk2_ardour/track_record_axis.cc | 165 +++++++++++++++++++++++++++++++ gtk2_ardour/track_record_axis.h | 23 ++++- 4 files changed, 203 insertions(+), 1 deletion(-) diff --git a/gtk2_ardour/recorder_ui.cc b/gtk2_ardour/recorder_ui.cc index 27855dcfd7..f1f43a8205 100644 --- a/gtk2_ardour/recorder_ui.cc +++ b/gtk2_ardour/recorder_ui.cc @@ -379,6 +379,7 @@ RecorderUI::set_session (Session* s) _session->RouteAdded.connect (_session_connections, invalidator (*this), boost::bind (&RecorderUI::add_routes, this, _1), gui_context ()); TrackRecordAxis::CatchDeletion.connect (*this, invalidator (*this), boost::bind (&RecorderUI::remove_route, this, _1), gui_context ()); + TrackRecordAxis::EditNextName.connect (*this, invalidator (*this), boost::bind (&RecorderUI::tra_name_edit, this, _1, _2), gui_context ()); _session->config.ParameterChanged.connect (_session_connections, invalidator (*this), boost::bind (&RecorderUI::parameter_changed, this, _1), gui_context ()); @@ -900,6 +901,20 @@ RecorderUI::remove_route (TrackRecordAxis* ra) update_rec_table_layout (); } +void +RecorderUI::tra_name_edit (TrackRecordAxis* tra, bool next) +{ + list::iterator i = find (_visible_recorders.begin (), _visible_recorders.end (), tra); + if (i == _visible_recorders.end ()) { + return; + } + if (next && ++i != _visible_recorders.end ()) { + (*i)->start_rename (); + } else if (!next && i != _visible_recorders.begin ()) { + (*--i)->start_rename (); + } +} + struct TrackRecordAxisSorter { bool operator() (const TrackRecordAxis* ca, const TrackRecordAxis* cb) { diff --git a/gtk2_ardour/recorder_ui.h b/gtk2_ardour/recorder_ui.h index f6e6e7e6c0..8f67a9f859 100644 --- a/gtk2_ardour/recorder_ui.h +++ b/gtk2_ardour/recorder_ui.h @@ -90,6 +90,7 @@ private: void initial_track_display (); void add_routes (ARDOUR::RouteList&); void remove_route (TrackRecordAxis*); + void tra_name_edit (TrackRecordAxis*, bool); void update_rec_table_layout (); void update_spacer_width (Gtk::Allocation&, TrackRecordAxis*); void tabbed_changed (bool); diff --git a/gtk2_ardour/track_record_axis.cc b/gtk2_ardour/track_record_axis.cc index 0ac410cd4f..e37fe995b3 100644 --- a/gtk2_ardour/track_record_axis.cc +++ b/gtk2_ardour/track_record_axis.cc @@ -42,6 +42,7 @@ #include "widgets/tooltips.h" +#include "ardour_message.h" #include "ardour_window.h" #include "context_menu_helper.h" #include "editor_cursors.h" @@ -69,6 +70,7 @@ using namespace Gtkmm2ext; using namespace std; PBD::Signal1 TrackRecordAxis::CatchDeletion; +PBD::Signal2 TrackRecordAxis::EditNextName; #define PX_SCALE(pxmin, dflt) rint (std::max ((double)pxmin, (double)dflt* UIConfiguration::instance ().get_ui_scale ())) @@ -80,8 +82,10 @@ TrackRecordAxis::TrackRecordAxis (Session* s, boost::shared_ptr r , RouteUI (s) , _clear_meters (true) , _route_ops_menu (0) + , _renaming (false) , _input_button (true) , _playlist_button (S_("RTAV|P")) + , _name_frame (ArdourWidgets::Frame::Horizontal, true) , _vseparator (1.0) , _ctrls_button_size_group (Gtk::SizeGroup::create (Gtk::SIZE_GROUP_BOTH)) , _monitor_ctrl_size_group (Gtk::SizeGroup::create (Gtk::SIZE_GROUP_BOTH)) @@ -130,8 +134,18 @@ TrackRecordAxis::TrackRecordAxis (Session* s, boost::shared_ptr r name_label.set_name (X_("TrackNameEditor")); name_label.set_alignment (0.0, 0.5); + name_label.set_padding (4, 0); name_label.set_width_chars (12); + _namebox.add (name_label); + _namebox.add_events (Gdk::BUTTON_PRESS_MASK); + _namebox.signal_button_press_event ().connect (sigc::mem_fun (*this, &TrackRecordAxis::namebox_button_press)); + + _name_frame.add (_namebox); + _name_frame.set_edge_color (0x000000ff); + _name_frame.set_border_width (0); + _name_frame.set_padding (0); + _input_button.set_sizing_text ("Capture_8888"); _input_button.set_route (rt, this); @@ -149,6 +163,7 @@ TrackRecordAxis::TrackRecordAxis (Session* s, boost::shared_ptr r _ctrls.attach (*rec_enable_button, 1, 2, 0, 1, Gtk::SHRINK, Gtk::FILL, 0, 0); _ctrls.attach (_input_button, 2, 3, 0, 1, Gtk::SHRINK, Gtk::FILL, 0, 0); _ctrls.attach (_playlist_button, 3, 4, 0, 1, Gtk::SHRINK, Gtk::FILL, 0, 0); + _ctrls.attach (_name_frame, 4, 5, 0, 1, Gtk::FILL, Gtk::FILL, 0, 0); _ctrls.attach (*monitor_input_button, 5, 6, 0, 1, Gtk::SHRINK, Gtk::FILL, 0, 0); _ctrls.attach (*monitor_disk_button, 6, 7, 0, 1, Gtk::SHRINK, Gtk::FILL, 0, 0); _ctrls.attach (*_level_meter, 7, 8, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 0, 0); @@ -179,6 +194,8 @@ TrackRecordAxis::TrackRecordAxis (Session* s, boost::shared_ptr r _level_meter->show (); _playlist_button.show(); _number_label.show (); + _name_frame.show (); + _namebox.show (); name_label.show (); _input_button.show (); _track_summary.show (); @@ -209,6 +226,17 @@ TrackRecordAxis::set_session (Session* s) s->config.ParameterChanged.connect (*this, invalidator (*this), ui_bind (&TrackRecordAxis::parameter_changed, this, _1), gui_context ()); } +void +TrackRecordAxis::route_rec_enable_changed () +{ + if (_route->rec_enable_control()->get_value()) { + /* end renaming when rec-arm engages + * (due to modal grab this can only be triggered by ctrl surfaces) */ + end_rename (true); + } + RouteUI::route_rec_enable_changed (); +} + void TrackRecordAxis::blink_rec_display (bool onoff) { @@ -316,6 +344,22 @@ TrackRecordAxis::set_name_label () _number_label.set_text (PBD::to_string (track_number)); } +bool +TrackRecordAxis::namebox_button_press (GdkEventButton* ev) +{ + if (_renaming) { + return false; + } + if ((ev->button == 1 && ev->type == GDK_2BUTTON_PRESS) || Keyboard::is_edit_event (ev)) { + if (!start_rename ()) { + ArdourMessageDialog msg (_("Inactive and record-armed tracks cannot be renamed")); + msg.run (); + } + return true; + } + return false; +} + void TrackRecordAxis::route_active_changed () { @@ -349,6 +393,10 @@ TrackRecordAxis::update_sensitivity () _input_button.set_sensitive (en); _ctrls.set_sensitive (en); + if (!en) { + end_rename (true); + } + if (!is_track() || track()->mode() != ARDOUR::Normal) { _playlist_button.set_sensitive (false); } @@ -463,6 +511,123 @@ TrackRecordAxis::build_route_ops_menu () items.back().set_sensitive (!is_track() || !track()->rec_enable_control()->get_value()); } +/* ****************************************************************************/ + +bool +TrackRecordAxis::start_rename () +{ + if (_renaming || _route->rec_enable_control()->get_value() || !_route->active ()) { + return false; + } + assert (_entry_connections.empty ()); + + GtkRequisition r (name_label.size_request ()); + _nameentry.set_size_request (r.width, -1); + _nameentry.set_text (_route->name ()); + _namebox.remove (); + _namebox.add (_nameentry); + _nameentry.show (); + _nameentry.grab_focus (); + _nameentry.add_modal_grab (); + _renaming = true; + + _entry_connections.push_back (_nameentry.signal_changed().connect (sigc::mem_fun (*this, &TrackRecordAxis::entry_changed))); + _entry_connections.push_back (_nameentry.signal_activate().connect (sigc::mem_fun (*this, &TrackRecordAxis::entry_activated))); + _entry_connections.push_back (_nameentry.signal_key_press_event().connect (sigc::mem_fun (*this, &TrackRecordAxis::entry_key_press), false)); + _entry_connections.push_back (_nameentry.signal_key_release_event().connect (sigc::mem_fun (*this, &TrackRecordAxis::entry_key_release), false)); + _entry_connections.push_back (_nameentry.signal_focus_out_event ().connect (sigc::mem_fun (*this, &TrackRecordAxis::entry_focus_out))); + return true; +} + +void +TrackRecordAxis::end_rename (bool ignore_change) +{ + if (!_renaming) { + return; + } + std::string result = _nameentry.get_text (); + disconnect_entry_signals (); + _nameentry.remove_modal_grab (); + _namebox.remove (); + _namebox.add (name_label); + name_label.show (); + _renaming = false; + + if (ignore_change) { + return; + } + + if (verify_new_route_name (result)) { + _route->set_name (result); + } +} + +void +TrackRecordAxis::entry_changed () +{ +} + +void +TrackRecordAxis::entry_activated () +{ + end_rename (false); +} + +bool +TrackRecordAxis::entry_focus_out (GdkEventFocus*) +{ + end_rename (false); + return false; +} + +bool +TrackRecordAxis::entry_key_press (GdkEventKey* ev) +{ + switch (ev->keyval) { + case GDK_Escape: + /* fallthrough */ + case GDK_ISO_Left_Tab: + /* fallthrough */ + case GDK_Tab: + /* fallthrough */ + return true; + default: + break; + } + return false; +} + +bool +TrackRecordAxis::entry_key_release (GdkEventKey* ev) +{ + switch (ev->keyval) { + case GDK_Escape: + end_rename (true); + return true; + case GDK_ISO_Left_Tab: + end_rename (false); + EditNextName (this, false); /* EMIT SIGNAL */ + return true; + case GDK_Tab: + end_rename (false); + EditNextName (this, true); /* EMIT SIGNAL */ + return true; + default: + break; + } + return false; +} + +void +TrackRecordAxis::disconnect_entry_signals () +{ + for (std::list::iterator i = _entry_connections.begin(); i != _entry_connections.end(); ++i) { + i->disconnect (); + } + _entry_connections.clear (); +} + + /* ****************************************************************************/ TrackRecordAxis::TrackSummary::TrackSummary (boost::shared_ptr r) diff --git a/gtk2_ardour/track_record_axis.h b/gtk2_ardour/track_record_axis.h index 9e4f2baa6b..424312c835 100644 --- a/gtk2_ardour/track_record_axis.h +++ b/gtk2_ardour/track_record_axis.h @@ -36,6 +36,7 @@ #include "widgets/ardour_button.h" #include "widgets/ardour_spacer.h" +#include "widgets/frame.h" #include "io_button.h" #include "level_meter.h" @@ -70,12 +71,15 @@ public: void set_session (ARDOUR::Session* s); void fast_update (); + bool start_rename (); void set_gui_extents (samplepos_t, samplepos_t); + bool rec_extent (samplepos_t&, samplepos_t&) const; int summary_xpos () const; int summary_width () const; static PBD::Signal1 CatchDeletion; + static PBD::Signal2 EditNextName; protected: void self_delete (); @@ -88,6 +92,7 @@ protected: /* route UI */ void set_button_names (); + void route_rec_enable_changed (); void blink_rec_display (bool onoff); void route_active_changed (); void map_frozen (); @@ -101,11 +106,21 @@ private: void reset_peak_display (); void reset_route_peak_display (ARDOUR::Route*); void reset_group_peak_display (ARDOUR::RouteGroup*); + bool namebox_button_press (GdkEventButton*); bool playlist_click (GdkEventButton*); bool route_ops_click (GdkEventButton*); void build_route_ops_menu (); + /* name editing */ + void end_rename (bool); + void entry_changed (); + void entry_activated (); + bool entry_focus_out (GdkEventFocus*); + bool entry_key_press (GdkEventKey*); + bool entry_key_release (GdkEventKey*); + void disconnect_entry_signals (); + /* RouteUI */ void route_property_changed (const PBD::PropertyChange&); void route_color_changed (); @@ -116,10 +131,15 @@ private: Gtk::Table _ctrls; Gtk::Menu* _route_ops_menu; + bool _renaming; + Gtk::EventBox _namebox; + Gtk::Entry _nameentry; + LevelMeterVBox* _level_meter; IOButton _input_button; ArdourWidgets::ArdourButton _number_label; ArdourWidgets::ArdourButton _playlist_button; + ArdourWidgets::Frame _name_frame; ArdourWidgets::ArdourVSpacer _vseparator; Glib::RefPtr _ctrls_button_size_group; @@ -128,7 +148,8 @@ private: static bool _size_group_initialized; static Glib::RefPtr _track_number_size_group; - PBD::ScopedConnectionList _route_connections; + PBD::ScopedConnectionList _route_connections; + std::list _entry_connections; struct RecInfo { RecInfo (samplepos_t s, samplepos_t e)