summaryrefslogtreecommitdiff
path: root/gtk2_ardour
diff options
context:
space:
mode:
authorPaul Davis <paul@linuxaudiosystems.com>2016-05-21 19:17:11 -0400
committerPaul Davis <paul@linuxaudiosystems.com>2016-05-31 15:30:44 -0400
commit428ed8ae1b9df42b91d932242ed51d30d0255c03 (patch)
treef96502be2cd2c6ca7ed0d0963935cbe90699b569 /gtk2_ardour
parent30d0b2a3546e50d359e712f239a16e08f37d38c7 (diff)
stop playing silly games with widget packing when editing a route name in the edito
Use a FloatingTextEntry instead. All clever functionality from previous implementation has been retained.
Diffstat (limited to 'gtk2_ardour')
-rw-r--r--gtk2_ardour/clearlooks.rc.in21
-rw-r--r--gtk2_ardour/floating_text_entry.cc57
-rw-r--r--gtk2_ardour/floating_text_entry.h14
-rw-r--r--gtk2_ardour/route_time_axis.cc33
-rw-r--r--gtk2_ardour/route_time_axis.h2
-rw-r--r--gtk2_ardour/time_axis_view.cc162
-rw-r--r--gtk2_ardour/time_axis_view.h12
-rw-r--r--gtk2_ardour/vca_master_strip.cc2
-rw-r--r--gtk2_ardour/vca_master_strip.h2
9 files changed, 115 insertions, 190 deletions
diff --git a/gtk2_ardour/clearlooks.rc.in b/gtk2_ardour/clearlooks.rc.in
index 4c6c6d988c..74df60b422 100644
--- a/gtk2_ardour/clearlooks.rc.in
+++ b/gtk2_ardour/clearlooks.rc.in
@@ -798,25 +798,10 @@ style "audio_bus_metrics_inactive" = "track_controls_inactive"
font_name = ""
}
-style "track_name_display" = "medium_text"
+style "track_name_editor" = "medium_text"
{
xthickness = 0
ythickness = 0
- fg[NORMAL] = @foreground
- fg[ACTIVE] = @foreground
- fg[SELECTED] = @foreground
-
- text[NORMAL] = @foreground
- text[ACTIVE] = @foreground
- text[SELECTED] = @foreground
-
- base[NORMAL] = @bases
- base[ACTIVE] = @bg_selected
- base[SELECTED] = @bg_selected
-
- bg[NORMAL] = lighter(@bases)
- bg[ACTIVE] = lighter(@bases)
- bg[SELECTED] = lighter(@bases)
}
style "track_separator"
@@ -1106,8 +1091,8 @@ widget "*AudioBusFader" style:highest "audio_bus_fader"
widget "*BusControlsBaseUnselected" style:highest "audio_bus_base"
widget "*TrackSeparator" style:highest "track_separator"
-widget "*EditorTrackNameDisplay" style:highest "track_name_display"
-widget "*EditorTrackNameDisplay*" style:highest "track_name_display"
+widget "*TrackNameEditor" style:highest "track_name_editor"
+widget "*TrackNameEditor*" style:highest "track_name_editor"
widget "*CrossfadeEditAuditionButton" style:highest "bright_when_active"
widget "*CrossfadeEditAuditionButton*" style:highest "bright_when_active"
widget "*CrossfadeEditCurveButton" style:highest "bright_when_active"
diff --git a/gtk2_ardour/floating_text_entry.cc b/gtk2_ardour/floating_text_entry.cc
index 60f10e571b..955de8d2b1 100644
--- a/gtk2_ardour/floating_text_entry.cc
+++ b/gtk2_ardour/floating_text_entry.cc
@@ -30,6 +30,7 @@
FloatingTextEntry::FloatingTextEntry (Gtk::Window* parent, const std::string& initial_contents)
: Gtk::Window (Gtk::WINDOW_POPUP)
, entry_changed (false)
+ , by_popup_menu (false)
{
set_name (X_("FloatingTextEntry"));
set_position (Gtk::WIN_POS_MOUSE);
@@ -42,8 +43,13 @@ FloatingTextEntry::FloatingTextEntry (Gtk::Window* parent, const std::string& in
entry.show ();
entry.signal_changed().connect (sigc::mem_fun (*this, &FloatingTextEntry::changed));
entry.signal_activate().connect (sigc::mem_fun (*this, &FloatingTextEntry::activated));
- entry.signal_key_press_event().connect (sigc::mem_fun (*this, &FloatingTextEntry::key_press));
+ entry.signal_key_press_event().connect (sigc::mem_fun (*this, &FloatingTextEntry::key_press), false);
+ entry.signal_key_release_event().connect (sigc::mem_fun (*this, &FloatingTextEntry::key_release), false);
entry.signal_button_press_event().connect (sigc::mem_fun (*this, &FloatingTextEntry::button_press));
+ entry.signal_populate_popup().connect (sigc::mem_fun (*this, &FloatingTextEntry::populate_popup));
+
+ entry.select_region (0, -1);
+ entry.set_state (Gtk::STATE_SELECTED);
if (parent) {
parent->signal_focus_out_event().connect (sigc::mem_fun (*this, &FloatingTextEntry::entry_focus_out));
@@ -53,6 +59,12 @@ FloatingTextEntry::FloatingTextEntry (Gtk::Window* parent, const std::string& in
}
void
+FloatingTextEntry::populate_popup (Gtk::Menu *)
+{
+ by_popup_menu = true;
+}
+
+void
FloatingTextEntry::changed ()
{
entry_changed = true;
@@ -69,9 +81,14 @@ FloatingTextEntry::on_realize ()
bool
FloatingTextEntry::entry_focus_out (GdkEventFocus* ev)
{
+ if (by_popup_menu) {
+ by_popup_menu = false;
+ return false;
+ }
+
entry.remove_modal_grab ();
if (entry_changed) {
- use_text (entry.get_text ());
+ use_text (entry.get_text (), 0);
}
delete_when_idle ( this);
@@ -92,7 +109,7 @@ FloatingTextEntry::button_press (GdkEventButton* ev)
Glib::signal_idle().connect (sigc::bind_return (sigc::bind (sigc::ptr_fun (gtk_main_do_event), gdk_event_copy ((GdkEvent*) ev)), false));
if (entry_changed) {
- use_text (entry.get_text ());
+ use_text (entry.get_text (), 0);
}
delete_when_idle ( this);
@@ -103,24 +120,54 @@ FloatingTextEntry::button_press (GdkEventButton* ev)
void
FloatingTextEntry::activated ()
{
- use_text (entry.get_text()); // EMIT SIGNAL
+ use_text (entry.get_text(), 0); // EMIT SIGNAL
delete_when_idle (this);
}
bool
FloatingTextEntry::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
+FloatingTextEntry::key_release (GdkEventKey* ev)
+{
switch (ev->keyval) {
case GDK_Escape:
+ /* cancel edit */
+ delete_when_idle (this);
+ return true;
+
+ case GDK_ISO_Left_Tab:
+ /* Shift+Tab Keys Pressed. Note that for Shift+Tab, GDK actually
+ * generates a different ev->keyval, rather than setting
+ * ev->state.
+ */
+ use_text (entry.get_text(), -1); // EMIT SIGNAL, move to prev
+ delete_when_idle (this);
+ return true;
+
+ case GDK_Tab:
+ use_text (entry.get_text(), 1); // EMIT SIGNAL, move to next
delete_when_idle (this);
return true;
- break;
default:
break;
}
+
return false;
}
+
void
FloatingTextEntry::on_hide ()
{
diff --git a/gtk2_ardour/floating_text_entry.h b/gtk2_ardour/floating_text_entry.h
index 116ba34651..596914c317 100644
--- a/gtk2_ardour/floating_text_entry.h
+++ b/gtk2_ardour/floating_text_entry.h
@@ -28,18 +28,27 @@ class FloatingTextEntry : public Gtk::Window
public:
FloatingTextEntry (Gtk::Window* parent, const std::string& initial_contents);
- sigc::signal1<void,std::string> use_text;
+ /* 1st argument to handler is the new text
+ * 2nd argument is 0, 1 or -1 to indicate:
+ * - do not move to next editable field
+ * - move to next editable field
+ * - move to previous editable field.
+ */
+ sigc::signal2<void,std::string,int> use_text;
private:
Gtk::Entry entry;
bool entry_changed;
+ bool by_popup_menu;
/* handlers for Entry events */
- bool entry_focus_out (GdkEventFocus*);
+ bool entry_focus_out (GdkEventFocus*);
bool key_press (GdkEventKey*);
+ bool key_release (GdkEventKey*);
void activated ();
bool button_press (GdkEventButton*);
void changed ();
+ void populate_popup (Gtk::Menu*);
/* handlers for window events */
@@ -48,4 +57,3 @@ class FloatingTextEntry : public Gtk::Window
};
#endif // __ardour_window_h__
-
diff --git a/gtk2_ardour/route_time_axis.cc b/gtk2_ardour/route_time_axis.cc
index f291af5dc5..13cd68b858 100644
--- a/gtk2_ardour/route_time_axis.cc
+++ b/gtk2_ardour/route_time_axis.cc
@@ -171,7 +171,7 @@ RouteTimeAxisView::set_route (boost::shared_ptr<Route> rt)
playlist_button.set_name ("route button");
automation_button.set_name ("route button");
- route_group_button.signal_button_release_event().connect (sigc::mem_fun(*this, &RouteTimeAxisView::route_group_click), false);
+ route_group_button.signal_button_release_event().connect (sigc::mem_fun(*this, &RouteTimeAxisView::route_group_click), false);
playlist_button.signal_clicked.connect (sigc::mem_fun(*this, &RouteTimeAxisView::playlist_click));
automation_button.signal_clicked.connect (sigc::mem_fun(*this, &RouteTimeAxisView::automation_click));
@@ -470,7 +470,7 @@ RouteTimeAxisView::take_name_changed (void *src)
void
RouteTimeAxisView::playlist_click ()
{
- build_playlist_menu ();
+ build_playlist_menu ();
conditionally_add_to_selection ();
playlist_action_menu->popup (1, gtk_get_current_event_time());
}
@@ -1428,33 +1428,30 @@ RouteTimeAxisView::playlist () const
}
}
-void
-RouteTimeAxisView::name_entry_changed ()
+bool
+RouteTimeAxisView::name_entry_changed (string const& str)
{
- TimeAxisView::name_entry_changed ();
-
- string x = name_entry->get_text ();
-
- if (x == _route->name()) {
- return;
+ if (str == _route->name()) {
+ return true;
}
+ string x = str;
+
strip_whitespace_edges (x);
- if (x.length() == 0) {
- name_entry->set_text (_route->name());
- return;
+ if (x.empty()) {
+ return false;
}
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 ();
+ ARDOUR_UI::instance()->popup_error (string_compose (_("The name \"%1\" is reserved for %2"), x, PROGRAM_NAME));
+ return false;
} else if (RouteUI::verify_new_route_name (x)) {
_route->set_name (x);
- } else {
- name_entry->grab_focus ();
+ return true;
}
+
+ return false;
}
boost::shared_ptr<Region>
diff --git a/gtk2_ardour/route_time_axis.h b/gtk2_ardour/route_time_axis.h
index 57b2bbb960..5e123f2fa7 100644
--- a/gtk2_ardour/route_time_axis.h
+++ b/gtk2_ardour/route_time_axis.h
@@ -207,7 +207,7 @@ protected:
void take_name_changed (void *src);
void route_property_changed (const PBD::PropertyChange&);
- void name_entry_changed ();
+ bool name_entry_changed (std::string const&);
void blink_rec_display (bool onoff);
diff --git a/gtk2_ardour/time_axis_view.cc b/gtk2_ardour/time_axis_view.cc
index f61bad80e1..97bd1ec4af 100644
--- a/gtk2_ardour/time_axis_view.cc
+++ b/gtk2_ardour/time_axis_view.cc
@@ -42,6 +42,7 @@
#include "ardour/profile.h"
#include "ardour_dialog.h"
+#include "floating_text_entry.h"
#include "gui_thread.h"
#include "public_editor.h"
#include "time_axis_view.h"
@@ -102,9 +103,6 @@ TimeAxisView::TimeAxisView (ARDOUR::Session* sess, PublicEditor& ed, TimeAxisVie
, _canvas_display (0)
, _y_position (0)
, _editor (ed)
- , name_entry (0)
- , ending_name_edit (false)
- , by_popup_menu (false)
, control_parent (0)
, _order (0)
, _effective_height (0)
@@ -610,148 +608,42 @@ TimeAxisView::set_height (uint32_t h, TrackHeightMode m)
_editor.override_visible_track_count ();
}
-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)
-{
- TrackViewList::iterator i;
-
- switch (ev->keyval) {
- case GDK_Escape:
- end_name_edit (RESPONSE_CANCEL);
- return true;
-
- case GDK_ISO_Left_Tab:
- /* Shift+Tab Keys Pressed. Note that for Shift+Tab, GDK actually
- * generates a different ev->keyval, rather than setting
- * ev->state.
- */
- end_name_edit (RESPONSE_APPLY);
- return true;
-
- case GDK_Tab:
- end_name_edit (RESPONSE_ACCEPT);
- return true;
- default:
- break;
- }
-
- return false;
-}
-
-bool
-TimeAxisView::name_entry_focus_out (GdkEventFocus*)
-{
- if (by_popup_menu) {
- by_popup_menu = false;
- return false;
- }
- end_name_edit (RESPONSE_OK);
- return false;
-}
-
-void
-TimeAxisView::name_entry_populate_popup (Gtk::Menu *)
-{
- by_popup_menu = true;
-}
-
void
TimeAxisView::begin_name_edit ()
{
- if (name_entry) {
+ if (!can_edit_name()) {
return;
}
- if (can_edit_name()) {
-
- name_entry = manage (new Gtkmm2ext::FocusEntry);
+ Gtk::Window* toplevel = (Gtk::Window*) control_parent->get_toplevel();
+ FloatingTextEntry* fte = new FloatingTextEntry (toplevel, name_label.get_text ());
- name_entry->set_width_chars(8); // min width, entry expands
+ fte->set_name ("TrackNameEditor");
+ fte->use_text.connect (sigc::mem_fun (*this, &TimeAxisView::end_name_edit));
- 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->signal_focus_out_event().connect (sigc::mem_fun (*this, &TimeAxisView::name_entry_focus_out));
- name_entry->set_text (name_label.get_text());
- name_entry->signal_activate().connect (sigc::bind (sigc::mem_fun (*this, &TimeAxisView::end_name_edit), RESPONSE_OK));
- name_entry->signal_populate_popup().connect (sigc::mem_fun (*this, &TimeAxisView::name_entry_populate_popup));
+ /* We want to new toplevel window to overlay the name label, so
+ * translate the coordinates of the upper left corner of the name label
+ * into the coordinate space of the top level window.
+ */
- if (name_label.is_ancestor (name_hbox)) {
- name_hbox.remove (name_label);
- }
+ int x, y;
+ int wx, wy;
- name_hbox.pack_end (*name_entry, true, true);
- name_entry->show ();
+ name_label.translate_coordinates (*toplevel, 0, 0, x, y);
+ toplevel->get_window()->get_origin (wx, wy);
- name_entry->select_region (0, -1);
- name_entry->set_state (STATE_SELECTED);
- name_entry->grab_focus ();
- name_entry->start_editing (0);
- }
+ fte->move (wx + x, wy + y);
+ fte->present ();
}
void
-TimeAxisView::end_name_edit (int response)
+TimeAxisView::end_name_edit (std::string str, int next_dir)
{
- if (!name_entry) {
- return;
+ if (!name_entry_changed (str)) {
+ next_dir = 0;
}
- if (ending_name_edit) {
- /* already doing this, and focus out or other event has caused
- us to re-enter this code.
- */
- return;
- }
-
- PBD::Unwinder<bool> uw (ending_name_edit, true);
-
- bool edit_next = false;
- bool edit_prev = false;
-
- switch (response) {
- case RESPONSE_CANCEL:
- break;
- case RESPONSE_OK:
- name_entry_changed ();
- break;
- case RESPONSE_ACCEPT:
- name_entry_changed ();
- edit_next = true;
- case RESPONSE_APPLY:
- name_entry_changed ();
- edit_prev = true;
- }
-
- /* this will delete the name_entry. but it will also drop focus, which
- * will cause another callback to this function, so set name_entry = 0
- * first to ensure we don't double-remove etc. etc.
- */
-
- Gtk::Entry* tmp = name_entry;
- name_entry = 0;
- name_hbox.remove (*tmp);
-
- /* put the name label back */
-
- name_hbox.pack_end (name_label);
- name_label.show ();
-
- if (edit_next) {
+ if (next_dir > 0) {
TrackViewList const & allviews = _editor.get_track_views ();
TrackViewList::const_iterator i = find (allviews.begin(), allviews.end(), this);
@@ -781,7 +673,7 @@ TimeAxisView::end_name_edit (int response)
(*i)->begin_name_edit ();
}
- } else if (edit_prev) {
+ } else if (next_dir < 0) {
TrackViewList const & allviews = _editor.get_track_views ();
TrackViewList::const_iterator i = find (allviews.begin(), allviews.end(), this);
@@ -814,9 +706,10 @@ TimeAxisView::end_name_edit (int response)
}
}
-void
-TimeAxisView::name_entry_changed ()
+bool
+TimeAxisView::name_entry_changed (string const&)
{
+ return true;
}
bool
@@ -851,9 +744,12 @@ TimeAxisView::popup_display_menu (guint32 when)
void
TimeAxisView::set_selected (bool yn)
{
- if (can_edit_name() && name_entry && name_entry->get_visible()) {
- end_name_edit (RESPONSE_CANCEL);
+#if 0
+ /* end any name edit in progress */
+ if (can_edit_name()) {
+ end_name_edit (string(), 0);
}
+#endif
if (yn == _selected) {
return;
diff --git a/gtk2_ardour/time_axis_view.h b/gtk2_ardour/time_axis_view.h
index ad9add4484..13ade6a2fe 100644
--- a/gtk2_ardour/time_axis_view.h
+++ b/gtk2_ardour/time_axis_view.h
@@ -255,20 +255,12 @@ class TimeAxisView : public virtual AxisView
virtual bool can_edit_name() const;
- bool name_entry_key_release (GdkEventKey *ev);
- bool name_entry_key_press (GdkEventKey *ev);
- bool name_entry_focus_out (GdkEventFocus *ev);
- void name_entry_populate_popup (Gtk::Menu *);
-
- Gtk::Entry* name_entry;
- bool ending_name_edit;
- bool by_popup_menu;
void begin_name_edit ();
- void end_name_edit (int);
+ void end_name_edit (std::string, int);
/* derived classes can override these */
- virtual void name_entry_changed ();
+ virtual bool name_entry_changed (std::string const&);
/** Handle mouse relaese on our LHS control name ebox.
*
diff --git a/gtk2_ardour/vca_master_strip.cc b/gtk2_ardour/vca_master_strip.cc
index 7cfa48c091..d2e6523f52 100644
--- a/gtk2_ardour/vca_master_strip.cc
+++ b/gtk2_ardour/vca_master_strip.cc
@@ -468,7 +468,7 @@ VCAMasterStrip::start_name_edit ()
}
void
-VCAMasterStrip::finish_name_edit (std::string str)
+VCAMasterStrip::finish_name_edit (std::string str, int)
{
_vca->set_name (str);
}
diff --git a/gtk2_ardour/vca_master_strip.h b/gtk2_ardour/vca_master_strip.h
index 8c31f2b1c7..dc223d237a 100644
--- a/gtk2_ardour/vca_master_strip.h
+++ b/gtk2_ardour/vca_master_strip.h
@@ -86,7 +86,7 @@ class VCAMasterStrip : public AxisView, public Gtk::EventBox
bool vca_button_release (GdkEventButton*);
void update_vca_display ();
void start_name_edit ();
- void finish_name_edit (std::string);
+ void finish_name_edit (std::string, int);
bool vertical_button_press (GdkEventButton*);
void vca_property_changed (PBD::PropertyChange const & what_changed);
void update_vca_name ();