repropagate button press event outside of FloatingTextEntry so that the click is...
[ardour.git] / gtk2_ardour / floating_text_entry.cc
1 /*
2     Copyright (C) 2014 Paul Davis
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include "pbd/stacktrace.h"
21
22 #include "floating_text_entry.h"
23 #include "gtkmm2ext/doi.h"
24 #include "gtkmm2ext/utils.h"
25
26 #include "i18n.h"
27
28 FloatingTextEntry::FloatingTextEntry ()
29         : ArdourWindow ("")
30         , entry_changed (false)
31 {
32         set_name (X_("FloatingTextEntry"));
33         set_position (Gtk::WIN_POS_MOUSE);
34         set_border_width (0);
35         
36         entry.show ();
37         entry.signal_changed().connect (sigc::mem_fun (*this, &FloatingTextEntry::changed));
38         entry.signal_activate().connect (sigc::mem_fun (*this, &FloatingTextEntry::activated));
39         entry.signal_key_press_event().connect (sigc::mem_fun (*this, &FloatingTextEntry::key_press));
40         entry.signal_button_press_event().connect (sigc::mem_fun (*this, &FloatingTextEntry::button_press));
41
42         add (entry);
43 }
44
45 void
46 FloatingTextEntry::changed ()
47 {
48         entry_changed = true;
49 }
50
51 void
52 FloatingTextEntry::on_realize ()
53 {
54         ArdourWindow::on_realize ();
55         get_window()->set_decorations (Gdk::WMDecoration (0));
56         entry.add_modal_grab ();
57 }
58
59 bool
60 FloatingTextEntry::button_press (GdkEventButton* ev)
61 {
62         if (Gtkmm2ext::event_inside_widget_window (*this, (GdkEvent*) ev)) {
63                 return true;
64         }
65
66         /* Clicked outside widget window - edit is done */
67
68         entry.remove_modal_grab ();
69
70         /* arrange re-propagation of the event once we go idle */
71
72         Glib::signal_idle().connect (sigc::bind_return (sigc::bind (sigc::ptr_fun (gtk_main_do_event), gdk_event_copy ((GdkEvent*) ev)), false));
73
74         if (entry_changed) {
75                 use_text (entry.get_text ());
76         }
77         
78         delete_when_idle ( this);
79
80         return false;
81 }
82
83 void
84 FloatingTextEntry::activated ()
85 {
86         use_text (entry.get_text()); // EMIT SIGNAL
87         delete_when_idle (this);
88 }
89
90 bool
91 FloatingTextEntry::key_press (GdkEventKey* ev)
92 {
93         switch (ev->keyval) {
94         case GDK_Escape:
95                 delete_when_idle (this);
96                 return true;
97                 break;
98         default:
99                 break;
100         }
101         return false;
102 }
103
104 void
105 FloatingTextEntry::on_hide ()
106 {
107         entry.remove_modal_grab ();
108
109         /* No hide button is shown (no decoration on the window), 
110            so being hidden is equivalent to the Escape key or any other 
111            method of cancelling the edit.
112         */
113
114         delete_when_idle (this);
115         ArdourWindow::on_hide ();
116 }