Merge branch 'master' into cairocanvas
[ardour.git] / libs / gtkmm2ext / binding_proxy.cc
1 /*
2     Copyright (C) 2006 Paul Davis
3     This program is free software; you can redistribute it and/or modify
4     it under the terms of the GNU General Public License as published by
5     the Free Software Foundation; either version 2 of the License, or
6     (at your option) any later version.
7
8     This program is distributed in the hope that it will be useful,
9     but WITHOUT ANY WARRANTY; without even the implied warranty of
10     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11     GNU General Public License for more details.
12
13     You should have received a copy of the GNU General Public License
14     along with this program; if not, write to the Free Software
15     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16
17     $Id$
18 */
19
20 #include <string>
21 #include <climits>
22 #include <iostream>
23
24 #include <pbd/controllable.h>
25
26 #include <gtkmm2ext/binding_proxy.h>
27
28 #include "i18n.h"
29
30 using namespace Gtkmm2ext;
31 using namespace std;
32 using namespace PBD;
33
34 BindingProxy::BindingProxy (boost::shared_ptr<Controllable> c)
35         : prompter (0),
36           controllable (c),
37           bind_button (2),
38           bind_statemask (Gdk::CONTROL_MASK)
39
40 {                         
41 }
42
43 BindingProxy::BindingProxy ()
44         : prompter (0),
45           bind_button (2),
46           bind_statemask (Gdk::CONTROL_MASK)
47
48 {                         
49 }
50
51 BindingProxy::~BindingProxy ()
52 {
53         if (prompter) {
54                 delete prompter;
55         }
56 }
57
58 void
59 BindingProxy::set_controllable (boost::shared_ptr<Controllable> c)
60 {
61         learning_finished ();
62         controllable = c;
63 }
64
65 void
66 BindingProxy::set_bind_button_state (guint button, guint statemask)
67 {
68         bind_button = button;
69         bind_statemask = statemask;
70 }
71
72 void
73 BindingProxy::get_bind_button_state (guint &button, guint &statemask)
74 {
75         button = bind_button;
76         statemask = bind_statemask;
77 }
78
79 bool
80 BindingProxy::button_press_handler (GdkEventButton *ev)
81 {
82         if (controllable && (ev->state & bind_statemask) && ev->button == bind_button) { 
83                 if (Controllable::StartLearning (controllable.get())) {
84                         string prompt = _("operate controller now");
85                         if (prompter == 0) {
86                                 prompter = new PopUp (Gtk::WIN_POS_MOUSE, 30000, false);
87                                 prompter->signal_unmap_event().connect (mem_fun (*this, &BindingProxy::prompter_hiding));
88                         }
89                         prompter->set_text (prompt);
90                         prompter->touch (); // shows popup
91                         controllable->LearningFinished.connect_same_thread (learning_connection, boost::bind (&BindingProxy::learning_finished, this));
92                 }
93                 return true;
94         }
95         
96         return false;
97 }
98
99 void
100 BindingProxy::learning_finished ()
101 {
102         learning_connection.disconnect ();
103         if (prompter) {
104                 prompter->touch (); // hides popup
105         }
106 }
107
108
109 bool
110 BindingProxy::prompter_hiding (GdkEventAny* /*ev*/)
111 {
112         learning_connection.disconnect ();
113         if (controllable) {
114                 Controllable::StopLearning (controllable.get());
115         }
116         return false;
117 }
118