Changing active-state needs no color lookup
[ardour.git] / libs / widgets / barcontroller.cc
1 /*
2  * Copyright (C) 2004 Paul Davis <paul@linuxaudiosystems.com>
3  * Copyright (C) 2017 Robin Gareus <robin@gareus.org>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19
20 #include <string>
21 #include <sstream>
22 #include <climits>
23 #include <cstdio>
24 #include <cmath>
25 #include <algorithm>
26
27 #include <pbd/controllable.h>
28
29 #include "gtkmm2ext/gtk_ui.h"
30 #include "gtkmm2ext/utils.h"
31 #include "gtkmm2ext/keyboard.h"
32 #include "gtkmm2ext/cairo_widget.h"
33
34 #include "widgets/barcontroller.h"
35
36 #include "pbd/i18n.h"
37
38 using namespace std;
39 using namespace Gtk;
40 using namespace Gtkmm2ext;
41 using namespace ArdourWidgets;
42
43 BarController::BarController (Gtk::Adjustment& adj,
44                 boost::shared_ptr<PBD::Controllable> mc)
45         : _slider (&adj, mc, 60, 16)
46         , _switching (false)
47         , _switch_on_release (false)
48 {
49
50         add_events (Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK);
51         set (.5, .5, 1.0, 1.0);
52         set_border_width (0);
53         _slider.set_tweaks (ArdourFader::NoShowUnityLine);
54
55         _slider.StartGesture.connect (sigc::mem_fun(*this, &BarController::passtrhu_gesture_start));
56         _slider.StopGesture.connect (sigc::mem_fun(*this, &BarController::passtrhu_gesture_stop));
57         _slider.OnExpose.connect (sigc::mem_fun(*this, &BarController::before_expose));
58         _slider.set_name (get_name());
59
60         Gtk::SpinButton& spinner = _slider.get_spin_button();
61         spinner.signal_activate().connect (mem_fun (*this, &BarController::entry_activated));
62         spinner.signal_focus_out_event().connect (mem_fun (*this, &BarController::entry_focus_out));
63         spinner.set_digits (4);
64         spinner.set_numeric (true);
65         spinner.set_name ("BarControlSpinner");
66         add (_slider);
67         show_all ();
68 }
69
70 BarController::~BarController ()
71 {
72 }
73
74 bool
75 BarController::on_button_press_event (GdkEventButton* ev)
76 {
77         if (get_child() != &_slider) {
78                 return false;
79         }
80         if (ev->button == 1 && ev->type == GDK_2BUTTON_PRESS) {
81                 _switch_on_release = true;
82                 return true;
83         } else {
84                 _switch_on_release = false;
85         }
86         return false;
87 }
88
89 bool
90 BarController::on_button_release_event (GdkEventButton* ev)
91 {
92         if (get_child() != &_slider) {
93                 return false;
94         }
95         if (ev->button == 1 && _switch_on_release) {
96                 Glib::signal_idle().connect (mem_fun (*this, &BarController::switch_to_spinner));
97                 return true;
98         }
99         return false;
100 }
101
102 void
103 BarController::on_style_changed (const Glib::RefPtr<Gtk::Style>&)
104 {
105         _slider.set_name (get_name());
106 }
107
108 gint
109 BarController::switch_to_bar ()
110 {
111         if (_switching || get_child() == &_slider) {
112                 return FALSE;
113         }
114         _switching = true;
115         remove ();
116         add (_slider);
117         _slider.show ();
118         _slider.queue_draw ();
119         _switching = false;
120         SpinnerActive (false); /* EMIT SIGNAL */
121         return FALSE;
122 }
123
124 gint
125 BarController::switch_to_spinner ()
126 {
127         if (_switching || get_child() != &_slider) {
128                 return FALSE;
129         }
130
131         _switching = true;
132         Gtk::SpinButton& spinner = _slider.get_spin_button();
133         if (spinner.get_parent()) {
134                 spinner.get_parent()->remove(spinner);
135         }
136         remove ();
137         add (spinner);
138         spinner.show ();
139         spinner.select_region (0, spinner.get_text_length());
140         spinner.grab_focus ();
141         _switching = false;
142         SpinnerActive (true); /* EMIT SIGNAL */
143         return FALSE;
144 }
145
146 void
147 BarController::entry_activated ()
148 {
149         switch_to_bar ();
150 }
151
152 bool
153 BarController::entry_focus_out (GdkEventFocus* /*ev*/)
154 {
155         entry_activated ();
156         return true;
157 }
158
159 void
160 BarController::before_expose ()
161 {
162         double xpos = -1;
163         _slider.set_text (get_label (xpos), false, false);
164 }
165
166 void
167 BarController::set_sensitive (bool yn)
168 {
169         Alignment::set_sensitive (yn);
170         _slider.set_sensitive (yn);
171 }