From f4f0dd6637878ba0597157ed8ec4550dcdb2a273 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Sat, 19 Jan 2013 15:27:04 +0000 Subject: [PATCH] completely revisit how track name editing works in the editor git-svn-id: svn://localhost/ardour2/branches/3.0@13898 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/automation_time_axis.cc | 6 + gtk2_ardour/route_time_axis.cc | 7 - gtk2_ardour/time_axis_view.cc | 334 ++++++++++------------------ gtk2_ardour/time_axis_view.h | 20 +- gtk2_ardour/visual_time_axis.cc | 2 - gtk2_ardour/visual_time_axis.h | 3 - 6 files changed, 130 insertions(+), 242 deletions(-) diff --git a/gtk2_ardour/automation_time_axis.cc b/gtk2_ardour/automation_time_axis.cc index 9fa412652d..848298c8b8 100644 --- a/gtk2_ardour/automation_time_axis.cc +++ b/gtk2_ardour/automation_time_axis.cc @@ -153,6 +153,12 @@ AutomationTimeAxisView::AutomationTimeAxisView ( set_height (preset_height (HeightNormal)); } + /* repack the name label */ + + if (name_label.get_parent()) { + name_label.get_parent()->remove (name_label); + } + name_label.set_text (_name); name_label.set_alignment (Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); name_label.set_name (X_("TrackParameterName")); diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc index 4f2164f3aa..041cbb59e1 100644 --- a/gtk2_ardour/route_time_axis.cc +++ b/gtk2_ardour/route_time_axis.cc @@ -112,8 +112,6 @@ RouteTimeAxisView::set_route (boost::shared_ptr rt) { RouteUI::set_route (rt); - show_name_label (); - gm.set_controls (_route, _route->shared_peak_meter(), _route->amp()); gm.get_level_meter().set_no_show_all(); gm.get_level_meter().setup_meters(50); @@ -323,11 +321,6 @@ RouteTimeAxisView::label_view () { string x = _route->name(); - if (name_entry && x != name_entry->get_text()) { - name_entry->set_text (x); - ARDOUR_UI::instance()->set_tip (*name_entry, Glib::Markup::escape_text(x)); - } - if (x != name_label.get_text()) { name_label.set_text (x); } diff --git a/gtk2_ardour/time_axis_view.cc b/gtk2_ardour/time_axis_view.cc index f49e06b026..1cf2391d5e 100644 --- a/gtk2_ardour/time_axis_view.cc +++ b/gtk2_ardour/time_axis_view.cc @@ -30,10 +30,12 @@ #include "pbd/error.h" #include "pbd/convert.h" +#include #include #include #include "ardour_ui.h" +#include "ardour_dialog.h" #include "global_signals.h" #include "gui_thread.h" #include "public_editor.h" @@ -70,7 +72,6 @@ PBD::Signal1 TimeAxisView::CatchDeletion; TimeAxisView::TimeAxisView (ARDOUR::Session* sess, PublicEditor& ed, TimeAxisView* rent, Canvas& /*canvas*/) : AxisView (sess) , controls_table (2, 8) - , name_entry (0) , _name_editing (false) , height (0) , display_menu (0) @@ -82,7 +83,8 @@ TimeAxisView::TimeAxisView (ARDOUR::Session* sess, PublicEditor& ed, TimeAxisVie , _canvas_display (0) , _y_position (0) , _editor (ed) - , last_name_entry_key_press_event (0) + , name_editor (0) + , name_entry (0) , control_parent (0) , _order (0) , _effective_height (0) @@ -112,13 +114,10 @@ TimeAxisView::TimeAxisView (ARDOUR::Session* sess, PublicEditor& ed, TimeAxisVie name_label.set_alignment (0.0, 0.5); ARDOUR_UI::instance()->set_tip (name_label, _("Track/Bus name (double click to edit)")); - /* typically, either name_label OR name_entry are visible, - but not both. its up to derived classes to show/hide them as they - wish. - */ - + name_hbox.pack_start (name_label, true, true); name_hbox.show (); - + name_label.show (); + controls_table.set_size_request (200); controls_table.set_row_spacings (2); controls_table.set_col_spacings (2); @@ -354,7 +353,7 @@ TimeAxisView::controls_ebox_button_press (GdkEventButton* event) controls_ebox.translate_coordinates (name_label, event->x, event->y, nlx, nly); Gtk::Allocation a = name_label.get_allocation (); if (nlx > 0 && nlx < a.get_width() && nly > 0 && nly < a.get_height()) { - begin_name_edit ((GdkEvent*) event); + begin_name_edit (); _ebox_release_can_act = false; return true; } @@ -545,6 +544,20 @@ TimeAxisView::set_height (uint32_t h) } } +bool +TimeAxisView::name_entry_key_press (GdkEventKey* ev) +{ + /* steal escape, tabs from GTK */ + + switch (ev->keyval) { + case GDK_Escape: + case GDK_ISO_Left_Tab: + case GDK_Tab: + return true; + } + return false; +} + bool TimeAxisView::name_entry_key_release (GdkEventKey* ev) { @@ -552,11 +565,7 @@ TimeAxisView::name_entry_key_release (GdkEventKey* ev) switch (ev->keyval) { case GDK_Escape: - // revert back to the way it was because - // name_entry_changed() will still be called as we drop focus. - name_entry->set_text (name_label.get_text()); - // moving the focus will trigger everything else - controls_ebox.grab_focus (); + name_editor->response (RESPONSE_CANCEL); return true; /* Shift+Tab Keys Pressed. Note that for Shift+Tab, GDK actually @@ -565,138 +574,133 @@ TimeAxisView::name_entry_key_release (GdkEventKey* ev) */ case GDK_ISO_Left_Tab: case GDK_Tab: - { - TrackViewList const & allviews = _editor.get_track_views (); - TrackViewList::const_iterator i = find (allviews.begin(), allviews.end(), this); - - if (ev->keyval == GDK_Tab) { - if (i != allviews.end()) { - - do { - if (++i == allviews.end()) { - return true; - } - - RouteTimeAxisView* rtav = dynamic_cast(*i); - - if (rtav && rtav->route()->record_enabled()) { - continue; - } - - if (!(*i)->hidden()) { - break; - } - - } while (true); - } - } else { - if (i != allviews.begin()) { - do { - if (i == allviews.begin()) { - return true; - } - - --i; - - RouteTimeAxisView* rtav = dynamic_cast(*i); - - if (rtav && rtav->route()->record_enabled()) { - continue; - } - - if (!(*i)->hidden()) { - break; - } - - } while (true); - } - } - - /* moving the focus will trigger everything else that is needed */ - - if ((i != allviews.end()) && (*i != this) && !(*i)->hidden()) { - _editor.ensure_time_axis_view_is_visible (**i); - (*i)->begin_name_edit ((GdkEvent*) ev); - } else { - controls_ebox.grab_focus (); - } - - } - return true; - - case GDK_Up: - case GDK_Down: - controls_ebox.grab_focus (); + name_editor->response (RESPONSE_ACCEPT); return true; - default: break; } -#ifdef TIMEOUT_NAME_EDIT - /* adapt the timeout to reflect the user's typing speed */ - - guint32 name_entry_timeout; - - if (last_name_entry_key_press_event) { - /* timeout is 1/2 second or 5 times their current inter-char typing speed */ - name_entry_timeout = std::max (500U, (5 * (ev->time - last_name_entry_key_press_event))); - } else { - /* start with a 1 second timeout */ - name_entry_timeout = 1000; - } - - last_name_entry_key_press_event = ev->time; - - /* wait 1 seconds and if no more keys are pressed, act as if they pressed enter */ - - name_entry_key_timeout.disconnect(); - name_entry_key_timeout = Glib::signal_timeout().connect (sigc::mem_fun (*this, &TimeAxisView::name_entry_key_timed_out), name_entry_timeout); -#endif - - return false; } void -TimeAxisView::begin_name_edit (GdkEvent* event) +TimeAxisView::begin_name_edit () { - if (_name_editing) { + if (name_editor) { return; } if (can_edit_name()) { - _name_editing = true; + Gtk::Widget* w = name_label.get_toplevel(); + Gtk::Window* win = dynamic_cast(w); + + if (!win) { + return; + } + + name_editor = new ArdourDialog (*win, string_compose (_("Edit name for %1"), name()), true); + name_editor->add_button (_("Cancel"), RESPONSE_CANCEL); + name_editor->add_button (_("Save"), RESPONSE_OK); + name_editor->add_button (_("Save & Edit Next"), RESPONSE_ACCEPT); + + name_entry = manage (new Gtkmm2ext::FocusEntry); + + name_entry->set_name ("EditorTrackNameDisplay"); + name_entry->signal_key_press_event().connect (sigc::mem_fun (*this, &TimeAxisView::name_entry_key_press), false); + name_entry->signal_key_release_event().connect (sigc::mem_fun (*this, &TimeAxisView::name_entry_key_release), false); + name_entry->set_text (name_label.get_text()); + name_entry->signal_activate().connect (sigc::bind (sigc::mem_fun (*name_editor, &ArdourDialog::response), RESPONSE_OK)); + + Gtk::HBox* hbox = manage (new HBox); + Gtk::Label* label = manage (new Label (_("New name"))); + + hbox->pack_start (*label, false, false); + hbox->pack_start (*name_entry, true, true); + name_editor->get_vbox()->pack_start (*hbox, false, false); + + label->show(); + name_entry->show (); + hbox->show (); - show_name_entry (); name_entry->select_region (0, -1); name_entry->set_state (STATE_SELECTED); name_entry->grab_focus (); - name_entry->start_editing (event); + name_entry->start_editing (0); + + name_editor->signal_response().connect (sigc::mem_fun (*this, &TimeAxisView::end_name_edit)); + + name_editor->set_position (WIN_POS_MOUSE); + name_editor->present (); + + /* move it to line up with the name label, and some distance to + * the right of it + */ + + int x, y; + int wx, wy; + + name_label.translate_coordinates (_editor, 0, 0, x, y); + _editor.get_position (wx, wy); + + name_editor->move (wx + x + 250, wy + y); } } void -TimeAxisView::end_name_edit (bool push_focus) +TimeAxisView::end_name_edit (int response) { - if (!_name_editing) { + if (!name_editor) { return; } + + bool edit_next = false; - if (can_edit_name()) { + switch (response) { + case RESPONSE_CANCEL: + break; + case RESPONSE_OK: + name_entry_changed (); + break; + case RESPONSE_ACCEPT: + name_entry_changed (); + edit_next = true; + } - _name_editing = false; + delete_when_idle (name_editor); - last_name_entry_key_press_event = 0; - name_entry_key_timeout.disconnect (); + name_editor = 0; + name_entry = 0; + + if (edit_next) { + + TrackViewList const & allviews = _editor.get_track_views (); + TrackViewList::const_iterator i = find (allviews.begin(), allviews.end(), this); - if (push_focus) { - controls_ebox.grab_focus (); + if (i != allviews.end()) { + + do { + if (++i == allviews.end()) { + return; + } + + RouteTimeAxisView* rtav = dynamic_cast(*i); + + if (rtav && rtav->route()->record_enabled()) { + continue; + } + + if (!(*i)->hidden()) { + break; + } + + } while (true); } - show_name_label (); - name_entry_changed (); + if ((i != allviews.end()) && (*i != this) && !(*i)->hidden()) { + _editor.ensure_time_axis_view_is_visible (**i); + (*i)->begin_name_edit (); + } } } @@ -705,65 +709,12 @@ TimeAxisView::name_entry_changed () { } -bool -TimeAxisView::name_entry_focus_in (GdkEventFocus* ev) -{ - begin_name_edit ((GdkEvent*) ev); - return false; -} - -bool -TimeAxisView::name_entry_focus_out (GdkEventFocus*) -{ - end_name_edit (false); - return false; -} - -bool -TimeAxisView::name_entry_key_timed_out () -{ - name_entry_activated(); - return false; -} - -void -TimeAxisView::name_entry_activated () -{ - end_name_edit (true); -} - bool TimeAxisView::can_edit_name () const { return true; } -bool -TimeAxisView::name_entry_button_press (GdkEventButton *ev) -{ - if (ev->button == 3) { - return true; - } - - if (ev->button == 1) { - if (ev->type != GDK_2BUTTON_PRESS) { - conditionally_add_to_selection (); - } - } - - return true; -} - -bool -TimeAxisView::name_entry_button_release (GdkEventButton *ev) -{ - if (ev->button == 3) { - popup_display_menu (ev->time); - return true; - } - return false; -} - void TimeAxisView::conditionally_add_to_selection () { @@ -1177,55 +1128,6 @@ TimeAxisView::compute_heights () button_height = req.height; } -void -TimeAxisView::show_name_label () -{ - if (name_entry && name_entry->is_ancestor (name_hbox)) { - name_hbox.remove (*name_entry); - } - - if (!name_label.is_ancestor (name_hbox) && name_label.get_parent() == 0) { - name_hbox.pack_start (name_label, true, true); - name_hbox.show (); - name_label.show (); - } -} - -void -TimeAxisView::show_name_entry () -{ - if (!name_entry) { - /* - Create the standard LHS Controls - We create the top-level container and name add the name label here, - subclasses can add to the layout as required - */ - - name_entry = new Gtkmm2ext::FocusEntry; - - name_entry->set_name ("EditorTrackNameDisplay"); - name_entry->signal_button_release_event().connect (sigc::mem_fun (*this, &TimeAxisView::name_entry_button_release), false); - name_entry->signal_button_press_event().connect (sigc::mem_fun (*this, &TimeAxisView::name_entry_button_press), false); - name_entry->signal_key_release_event().connect (sigc::mem_fun (*this, &TimeAxisView::name_entry_key_release)); - name_entry->signal_activate().connect (sigc::mem_fun(*this, &TimeAxisView::name_entry_activated)); - name_entry->signal_focus_in_event().connect (sigc::mem_fun (*this, &TimeAxisView::name_entry_focus_in)); - name_entry->signal_focus_out_event().connect (sigc::mem_fun (*this, &TimeAxisView::name_entry_focus_out)); - Gtkmm2ext::set_size_request_to_display_given_text (*name_entry, N_("gTortnam"), 10, 10); // just represents a short name - - name_entry->set_text (name_label.get_text()); - } - - if (name_label.is_ancestor (name_hbox)) { - name_hbox.remove (name_label); - } - - if (!name_entry->is_ancestor (name_hbox) && name_label.get_parent() == 0) { - name_hbox.pack_start (*name_entry, true, true); - name_hbox.show (); - name_entry->show (); - } -} - void TimeAxisView::color_handler () { diff --git a/gtk2_ardour/time_axis_view.h b/gtk2_ardour/time_axis_view.h index c366d26640..6e659e47a7 100644 --- a/gtk2_ardour/time_axis_view.h +++ b/gtk2_ardour/time_axis_view.h @@ -68,6 +68,7 @@ class Selectable; class RegionView; class GhostRegion; class StreamView; +class ArdourDialog; /** Abstract base class for time-axis views (horizontal editor 'strips') * @@ -116,9 +117,6 @@ class TimeAxisView : public virtual AxisView void idle_resize (uint32_t); - void show_name_label (); - void show_name_entry (); - virtual guint32 show_at (double y, int& nth, Gtk::VBox *parent); virtual void hide (); @@ -204,7 +202,6 @@ class TimeAxisView : public virtual AxisView Gtk::VBox controls_vbox; Gtk::VBox time_axis_vbox; Gtk::HBox name_hbox; - Gtkmm2ext::FocusEntry* name_entry; Gtk::Label name_label; bool _name_editing; uint32_t height; /* in canvas units */ @@ -225,22 +222,17 @@ class TimeAxisView : public virtual AxisView virtual bool can_edit_name() const; - bool name_entry_button_press (GdkEventButton *ev); - bool name_entry_button_release (GdkEventButton *ev); bool name_entry_key_release (GdkEventKey *ev); - void name_entry_activated (); - sigc::connection name_entry_key_timeout; - bool name_entry_key_timed_out (); - guint32 last_name_entry_key_press_event; + bool name_entry_key_press (GdkEventKey *ev); - void begin_name_edit (GdkEvent*); - void end_name_edit (bool push_focus); + ArdourDialog* name_editor; + Gtk::Entry* name_entry; + void begin_name_edit (); + void end_name_edit (int); /* derived classes can override these */ virtual void name_entry_changed (); - virtual bool name_entry_focus_in (GdkEventFocus *ev); - virtual bool name_entry_focus_out (GdkEventFocus *ev); /** Handle mouse relaese on our LHS control name ebox. * diff --git a/gtk2_ardour/visual_time_axis.cc b/gtk2_ardour/visual_time_axis.cc index 07d2ae62aa..3961bf8be1 100644 --- a/gtk2_ardour/visual_time_axis.cc +++ b/gtk2_ardour/visual_time_axis.cc @@ -148,8 +148,6 @@ VisualTimeAxis::set_height(uint32_t h) { TimeAxisView::set_height(h); - show_name_label (); - if (h >= hNormal) { other_button_hbox.show_all() ; } else if (h >= hSmaller) { diff --git a/gtk2_ardour/visual_time_axis.h b/gtk2_ardour/visual_time_axis.h index 25ec1d8ef3..a692482b49 100644 --- a/gtk2_ardour/visual_time_axis.h +++ b/gtk2_ardour/visual_time_axis.h @@ -227,10 +227,7 @@ class VisualTimeAxis : public TimeAxisView // Handle name entry signals void name_entry_changed() ; - bool name_entry_focus_out_handler(GdkEventFocus*) ; bool name_entry_key_release_handler(GdkEventKey*) ; - bool name_entry_button_release_handler(GdkEventButton*) ; - bool name_entry_button_press_handler(GdkEventButton*) ; //---------------------------------------------------------------------------------------// // VisualTimeAxis Widgets