completely revisit how track name editing works in the editor
authorPaul Davis <paul@linuxaudiosystems.com>
Sat, 19 Jan 2013 15:27:04 +0000 (15:27 +0000)
committerPaul Davis <paul@linuxaudiosystems.com>
Sat, 19 Jan 2013 15:27:04 +0000 (15:27 +0000)
git-svn-id: svn://localhost/ardour2/branches/3.0@13898 d708f5d6-7413-0410-9779-e7cbd77b26cf

gtk2_ardour/automation_time_axis.cc
gtk2_ardour/route_time_axis.cc
gtk2_ardour/time_axis_view.cc
gtk2_ardour/time_axis_view.h
gtk2_ardour/visual_time_axis.cc
gtk2_ardour/visual_time_axis.h

index 9fa412652d83dbc9caf8d62b6fc05f0a138785ba..848298c8b805a47f7ab4f9aa0773b71910dd763d 100644 (file)
@@ -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"));
index 4f2164f3aa3949c74558d185624b483979e949b0..041cbb59e16c6c5428ae84519c7abfc90b1f7015 100644 (file)
@@ -112,8 +112,6 @@ RouteTimeAxisView::set_route (boost::shared_ptr<Route> 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);
        }
index f49e06b026672d3c04bf68f28495d5bba9d9affd..1cf2391d5e8558171f03c0736abf6f95e58e80cb 100644 (file)
 #include "pbd/error.h"
 #include "pbd/convert.h"
 
+#include <gtkmm2ext/doi.h>
 #include <gtkmm2ext/utils.h>
 #include <gtkmm2ext/selector.h>
 
 #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<void,TimeAxisView*> 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<RouteTimeAxisView*>(*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;
+               name_editor->response (RESPONSE_ACCEPT);
+               return true;
+       default:
+               break;
+       }
 
-                                       RouteTimeAxisView* rtav = dynamic_cast<RouteTimeAxisView*>(*i);
+       return false;
+}
 
-                                       if (rtav && rtav->route()->record_enabled()) {
-                                               continue;
-                                       }
+void
+TimeAxisView::begin_name_edit ()
+{
+       if (name_editor) {
+               return;
+       }
 
-                                       if (!(*i)->hidden()) {
-                                               break;
-                                       }
+       if (can_edit_name()) {
 
-                               } while (true);
-                       }
+               Gtk::Widget* w = name_label.get_toplevel();
+               Gtk::Window* win = dynamic_cast<Gtk::Window*>(w);
+               
+               if (!win) {
+                       return;
                }
 
-               /* moving the focus will trigger everything else that is needed */
+               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);
 
-               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 ();
-               }
+               name_entry = manage (new Gtkmm2ext::FocusEntry);
                
-       }
-       return true;
+               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));
 
-       case GDK_Up:
-       case GDK_Down:
-               controls_ebox.grab_focus ();
-               return true;
+               Gtk::HBox* hbox = manage (new HBox);
+               Gtk::Label* label = manage (new Label (_("New name")));
 
-       default:
-               break;
-       }
+               hbox->pack_start (*label, false, false);
+               hbox->pack_start (*name_entry, true, true);
+               name_editor->get_vbox()->pack_start (*hbox, false, false);
 
-#ifdef TIMEOUT_NAME_EDIT
-       /* adapt the timeout to reflect the user's typing speed */
+               label->show();
+               name_entry->show ();
+               hbox->show ();
 
-       guint32 name_entry_timeout;
+               name_entry->select_region (0, -1);
+               name_entry->set_state (STATE_SELECTED);
+               name_entry->grab_focus ();
+               name_entry->start_editing (0);
 
-       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;
-       }
+               name_editor->signal_response().connect (sigc::mem_fun (*this, &TimeAxisView::end_name_edit));
 
-       last_name_entry_key_press_event = ev->time;
+               name_editor->set_position (WIN_POS_MOUSE);
+               name_editor->present ();
 
-       /* wait 1 seconds and if no more keys are pressed, act as if they pressed enter */
+               /* move it to line up with the name label, and some distance to
+                * the right of it
+                */
 
-       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
+               int x, y;
+               int wx, wy;
 
+               name_label.translate_coordinates (_editor, 0, 0, x, y);
+               _editor.get_position (wx, wy);
 
-       return false;
+               name_editor->move (wx + x + 250, wy + y);
+       }
 }
 
 void
-TimeAxisView::begin_name_edit (GdkEvent* event)
+TimeAxisView::end_name_edit (int response)
 {
-       if (_name_editing) {
+       if (!name_editor) {
                return;
        }
+       
+       bool edit_next = false;
 
-       if (can_edit_name()) {
-
-               _name_editing = true;
-
-               show_name_entry ();
-               name_entry->select_region (0, -1);
-               name_entry->set_state (STATE_SELECTED);
-               name_entry->grab_focus ();
-               name_entry->start_editing (event);
+       switch (response) {
+       case RESPONSE_CANCEL:
+               break;
+       case RESPONSE_OK:
+               name_entry_changed ();
+               break;
+       case RESPONSE_ACCEPT:
+               name_entry_changed ();
+               edit_next = true;
        }
-}
 
-void
-TimeAxisView::end_name_edit (bool push_focus)
-{
-       if (!_name_editing) {
-               return;
-       }
+       delete_when_idle (name_editor);
 
-       if (can_edit_name()) {
+       name_editor = 0;
+       name_entry = 0;
 
-               _name_editing = false;
+       if (edit_next) {
 
-               last_name_entry_key_press_event = 0;
-               name_entry_key_timeout.disconnect ();
+               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<RouteTimeAxisView*>(*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 ()
 {
index c366d266400d05cd607e5e5524017173a9ddc3f3..6e659e47a73677ce8caf5ce6851c29620183c382 100644 (file)
@@ -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.
         *
index 07d2ae62aa9b7ca047d53e2e245c217dfcb93053..3961bf8be1bb8c59ff1dd4b9cb613a8f2108955c 100644 (file)
@@ -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) {
index 25ec1d8ef34fa5f254975a92bae1fd87d955f603..a692482b49af84fc5f3c734a9af87c6414b3ec1d 100644 (file)
@@ -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