From 00cba5aa3b4691e44502187f1c9f491c3392d61f Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Mon, 14 Jan 2013 21:46:32 +0000 Subject: more substantive reworkings of TimeAxisView::name_(entry|label) and name editing. better, but i can still (somehow) trigger occasional misbehaviour git-svn-id: svn://localhost/ardour2/branches/3.0@13840 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/arval | 2 +- gtk2_ardour/automation_time_axis.cc | 11 +- gtk2_ardour/route_time_axis.cc | 16 +-- gtk2_ardour/time_axis_view.cc | 203 ++++++++++++++++++++---------------- gtk2_ardour/time_axis_view.h | 83 +++++++-------- 5 files changed, 163 insertions(+), 152 deletions(-) (limited to 'gtk2_ardour') diff --git a/gtk2_ardour/arval b/gtk2_ardour/arval index c67bb0ac03..6503bc1ede 100755 --- a/gtk2_ardour/arval +++ b/gtk2_ardour/arval @@ -1,7 +1,7 @@ #!/bin/sh VALGRIND_OPTIONS="$VALGRIND_OPTIONS --num-callers=50" VALGRIND_OPTIONS="$VALGRIND_OPTIONS --error-limit=no" -VALGRIND_OPTIONS="$VALGRIND_OPTIONS --leak-check=full --leak-resolution=high" +#VALGRIND_OPTIONS="$VALGRIND_OPTIONS --leak-check=full --leak-resolution=high" #VALGRIND_OPTIONS="$VALGRIND_OPTIONS --log-file=/tmp/ardour-%p.log" #VALGRIND_OPTIONS="$VALGRIND_OPTIONS --gen-suppressions=all" diff --git a/gtk2_ardour/automation_time_axis.cc b/gtk2_ardour/automation_time_axis.cc index 618344fcbc..bfc0ce4440 100644 --- a/gtk2_ardour/automation_time_axis.cc +++ b/gtk2_ardour/automation_time_axis.cc @@ -153,11 +153,6 @@ AutomationTimeAxisView::AutomationTimeAxisView ( set_height (preset_height (HeightNormal)); } - /* for automation tracks, the label does not swap with an entry box. remove all that stuff */ - if (name_label.get_parent()) { - hide_name_label (); - } - name_label.set_text (_name); name_label.set_alignment (Gtk::ALIGN_CENTER, Gtk::ALIGN_CENTER); name_label.set_name (X_("TrackParameterName")); @@ -175,6 +170,8 @@ AutomationTimeAxisView::AutomationTimeAxisView ( controls_table.attach (name_label, 0, 6, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); controls_table.attach (auto_button, 6, 8, 1, 2, Gtk::FILL|Gtk::EXPAND, Gtk::FILL|Gtk::EXPAND); + name_label.show (); + if (_controller) { _controller.get()->set_size_request(-1, 24); /* add bar controller */ @@ -422,15 +419,11 @@ AutomationTimeAxisView::set_height (uint32_t h) first_call_to_set_height = false; if (h >= preset_height (HeightNormal)) { - show_name_label (); - hide_name_entry (); auto_button.show(); hide_button.show_all(); } else if (h >= preset_height (HeightSmall)) { controls_table.hide_all (); - hide_name_entry (); - hide_name_label (); auto_button.hide(); } } diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc index 5d091375b4..4f2164f3aa 100644 --- a/gtk2_ardour/route_time_axis.cc +++ b/gtk2_ardour/route_time_axis.cc @@ -111,6 +111,8 @@ void 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(); @@ -321,15 +323,15 @@ RouteTimeAxisView::label_view () { string x = _route->name(); - if (x != name_entry.get_text()) { - name_entry.set_text (x); + 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); } - ARDOUR_UI::instance()->set_tip (name_entry, Glib::Markup::escape_text(x)); } void @@ -1288,7 +1290,7 @@ RouteTimeAxisView::name_entry_changed () { TimeAxisView::name_entry_changed (); - string x = name_entry.get_text (); + string x = name_entry->get_text (); if (x == _route->name()) { return; @@ -1297,18 +1299,18 @@ RouteTimeAxisView::name_entry_changed () strip_whitespace_edges (x); if (x.length() == 0) { - name_entry.set_text (_route->name()); + name_entry->set_text (_route->name()); return; } if (_session->route_name_internal (x)) { ARDOUR_UI::instance()->popup_error (string_compose (_("You cannot create a track with that name as it is reserved for %1"), PROGRAM_NAME)); - name_entry.grab_focus (); + name_entry->grab_focus (); } else if (RouteUI::verify_new_route_name (x)) { _route->set_name (x); } else { - name_entry.grab_focus (); + name_entry->grab_focus (); } } diff --git a/gtk2_ardour/time_axis_view.cc b/gtk2_ardour/time_axis_view.cc index 06ff659fab..f49e06b026 100644 --- a/gtk2_ardour/time_axis_view.cc +++ b/gtk2_ardour/time_axis_view.cc @@ -70,18 +70,19 @@ 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) - , last_name_entry_key_press_event (0) , display_menu (0) , parent (rent) , selection_group (0) , _hidden (false) , in_destructor (false) - , name_packing (NamePackingBits (0)) , _size_menu (0) , _canvas_display (0) , _y_position (0) , _editor (ed) + , last_name_entry_key_press_event (0) , control_parent (0) , _order (0) , _effective_height (0) @@ -89,6 +90,7 @@ TimeAxisView::TimeAxisView (ARDOUR::Session* sess, PublicEditor& ed, TimeAxisVie , _preresize_cursor (0) , _have_preresize_cursor (false) , _ghost_group (0) + , _ebox_release_can_act (true) { if (extra_height == 0) { compute_heights (); @@ -106,24 +108,10 @@ TimeAxisView::TimeAxisView (ARDOUR::Session* sess, PublicEditor& ed, TimeAxisVie _ghost_group->lower_to_bottom(); _ghost_group->show(); - /* - 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.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_label.set_name ("TrackLabel"); 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. @@ -358,28 +346,24 @@ TimeAxisView::controls_ebox_scroll (GdkEventScroll* ev) bool TimeAxisView::controls_ebox_button_press (GdkEventButton* event) { - if (event->button == 1) { - if (event->type == GDK_2BUTTON_PRESS) { - /* see if it is inside the name label */ - if (name_label.is_ancestor (controls_ebox)) { - int nlx; - int nly; - 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()) { - hide_name_label (); - show_name_entry (); - if (can_edit_name()) { - name_entry.grab_focus (); - name_entry.start_editing ((GdkEvent*) event); - } - return true; - } + if ((event->button == 1 && event->type == GDK_2BUTTON_PRESS) || Keyboard::is_edit_event (event)) { + /* see if it is inside the name label */ + if (name_label.is_ancestor (controls_ebox)) { + int nlx; + int nly; + 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); + _ebox_release_can_act = false; + return true; } } + } + _ebox_release_can_act = true; + if (maybe_set_cursor (event->y) > 0) { _resize_drag_start = event->y_root; } @@ -473,6 +457,10 @@ TimeAxisView::controls_ebox_button_release (GdkEventButton* ev) _resize_drag_start = -1; } + if (!_ebox_release_can_act) { + return true; + } + switch (ev->button) { case 1: selection_click (ev); @@ -555,8 +543,6 @@ TimeAxisView::set_height (uint32_t h) /* resize the selection rect */ show_selection (_editor.get_selection().time); } - - show_name_label (); } bool @@ -566,9 +552,11 @@ TimeAxisView::name_entry_key_release (GdkEventKey* ev) switch (ev->keyval) { case GDK_Escape: - name_entry.select_region (0,0); + // 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_entry_changed (); return true; /* Shift+Tab Keys Pressed. Note that for Shift+Tab, GDK actually @@ -578,12 +566,12 @@ TimeAxisView::name_entry_key_release (GdkEventKey* ev) case GDK_ISO_Left_Tab: case GDK_Tab: { - name_entry_changed (); 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; @@ -624,16 +612,21 @@ TimeAxisView::name_entry_key_release (GdkEventKey* ev) } } + /* moving the focus will trigger everything else that is needed */ + if ((i != allviews.end()) && (*i != this) && !(*i)->hidden()) { - (*i)->name_entry.grab_focus(); _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: - name_entry_changed (); + controls_ebox.grab_focus (); return true; default: @@ -661,55 +654,82 @@ TimeAxisView::name_entry_key_release (GdkEventKey* ev) name_entry_key_timeout = Glib::signal_timeout().connect (sigc::mem_fun (*this, &TimeAxisView::name_entry_key_timed_out), name_entry_timeout); #endif + return false; } -bool -TimeAxisView::name_entry_focus_in (GdkEventFocus*) +void +TimeAxisView::begin_name_edit (GdkEvent* event) { - name_entry.select_region (0, -1); - name_entry.set_state (STATE_SELECTED); - return false; + if (_name_editing) { + return; + } + + 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); + } } -bool -TimeAxisView::name_entry_focus_out (GdkEventFocus*) +void +TimeAxisView::end_name_edit (bool push_focus) { - cerr << "NEFO\n"; + if (!_name_editing) { + return; + } - /* clean up */ + if (can_edit_name()) { - last_name_entry_key_press_event = 0; - name_entry_key_timeout.disconnect (); - name_entry.select_region (0,0); - name_entry.set_state (STATE_NORMAL); + _name_editing = false; - /* do the real stuff */ + last_name_entry_key_press_event = 0; + name_entry_key_timeout.disconnect (); + + if (push_focus) { + controls_ebox.grab_focus (); + } + + show_name_label (); + name_entry_changed (); + } +} - name_entry_changed (); +void +TimeAxisView::name_entry_changed () +{ +} +bool +TimeAxisView::name_entry_focus_in (GdkEventFocus* ev) +{ + begin_name_edit ((GdkEvent*) ev); return false; } bool -TimeAxisView::name_entry_key_timed_out () +TimeAxisView::name_entry_focus_out (GdkEventFocus*) { - name_entry_activated(); + end_name_edit (false); return false; } -void -TimeAxisView::name_entry_activated () +bool +TimeAxisView::name_entry_key_timed_out () { - controls_ebox.grab_focus(); + name_entry_activated(); + return false; } void -TimeAxisView::name_entry_changed () +TimeAxisView::name_entry_activated () { - cerr << "swithcing back to name labnel\n"; - hide_name_entry (); - show_name_label (); + end_name_edit (true); } bool @@ -1160,9 +1180,12 @@ TimeAxisView::compute_heights () void TimeAxisView::show_name_label () { - if (!(name_packing & NameLabelPacked) && name_label.get_parent() == 0) { + 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_packing = NamePackingBits (name_packing | NameLabelPacked); name_hbox.show (); name_label.show (); } @@ -1171,29 +1194,35 @@ TimeAxisView::show_name_label () void TimeAxisView::show_name_entry () { - if (!(name_packing & NameEntryPacked)) { - name_hbox.pack_start (name_entry, true, true); - name_packing = NamePackingBits (name_packing | NameEntryPacked); - name_hbox.show (); - name_entry.show (); + 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()); } -} -void -TimeAxisView::hide_name_label () -{ - if (name_packing & NameLabelPacked) { + if (name_label.is_ancestor (name_hbox)) { name_hbox.remove (name_label); - name_packing = NamePackingBits (name_packing & ~NameLabelPacked); } -} -void -TimeAxisView::hide_name_entry () -{ - if (name_packing & NameEntryPacked) { - name_hbox.remove (name_entry); - name_packing = NamePackingBits (name_packing & ~NameEntryPacked); + 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 (); } } diff --git a/gtk2_ardour/time_axis_view.h b/gtk2_ardour/time_axis_view.h index 958b0b55dd..c366d26640 100644 --- a/gtk2_ardour/time_axis_view.h +++ b/gtk2_ardour/time_axis_view.h @@ -116,8 +116,6 @@ class TimeAxisView : public virtual AxisView void idle_resize (uint32_t); - void hide_name_label (); - void hide_name_entry (); void show_name_label (); void show_name_entry (); @@ -200,19 +198,30 @@ class TimeAxisView : public virtual AxisView protected: /* The Standard LHS Controls */ - Gtk::HBox controls_hbox; - Gtk::Table controls_table; - Gtk::EventBox controls_ebox; - Gtk::VBox controls_vbox; - Gtk::VBox time_axis_vbox; - Gtk::HBox name_hbox; - Gtk::Frame name_frame; - Gtkmm2ext::FocusEntry name_entry; - - uint32_t height; /* in canvas units */ - - std::string controls_base_unselected_name; - std::string controls_base_selected_name; + Gtk::HBox controls_hbox; + Gtk::Table controls_table; + Gtk::EventBox controls_ebox; + 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 */ + std::string controls_base_unselected_name; + std::string controls_base_selected_name; + Gtk::Menu* display_menu; /* The standard LHS Track control popup-menus */ + TimeAxisView* parent; + ArdourCanvas::Group* selection_group; + std::list ghosts; + std::list free_selection_rects; + std::list used_selection_rects; + bool _hidden; + bool in_destructor; + Gtk::Menu* _size_menu; + ArdourCanvas::Group* _canvas_display; + double _y_position; + PublicEditor& _editor; virtual bool can_edit_name() const; @@ -224,6 +233,9 @@ class TimeAxisView : public virtual AxisView bool name_entry_key_timed_out (); guint32 last_name_entry_key_press_event; + void begin_name_edit (GdkEvent*); + void end_name_edit (bool push_focus); + /* derived classes can override these */ virtual void name_entry_changed (); @@ -255,14 +267,6 @@ class TimeAxisView : public virtual AxisView */ virtual bool handle_display_menu_map_event (GdkEventAny * /*ev*/) { return false; } - /* The standard LHS Track control popup-menus */ - - Gtk::Menu *display_menu; - - Gtk::Label name_label; - - TimeAxisView* parent; - Children children; bool is_child (TimeAxisView*); @@ -271,47 +275,30 @@ class TimeAxisView : public virtual AxisView /* selection display */ - ArdourCanvas::Group *selection_group; - - std::list ghosts; - - std::list free_selection_rects; - std::list used_selection_rects; - virtual void selection_click (GdkEventButton*); - bool _hidden; - bool in_destructor; - NamePackingBits name_packing; - void color_handler (); void conditionally_add_to_selection (); void build_size_menu (); - Gtk::Menu* _size_menu; - - ArdourCanvas::Group* _canvas_display; - double _y_position; - PublicEditor& _editor; private: - ArdourCanvas::Group* _canvas_background; - Gtk::VBox* control_parent; - int _order; - uint32_t _effective_height; - double _resize_drag_start; - GdkCursor* _preresize_cursor; - bool _have_preresize_cursor; + Gtk::VBox* control_parent; + int _order; + uint32_t _effective_height; + double _resize_drag_start; + GdkCursor* _preresize_cursor; + bool _have_preresize_cursor; ArdourCanvas::Group* _ghost_group; + bool _ebox_release_can_act; - void compute_heights (); static uint32_t button_height; static uint32_t extra_height; - static int const _max_order; + void compute_heights (); bool maybe_set_cursor (int y); }; /* class TimeAxisView */ -- cgit v1.2.3