2 Copyright (C) 2004 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.
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.
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.
26 #include <pbd/controllable.h>
28 #include <gtkmm2ext/gtk_ui.h>
29 #include <gtkmm2ext/utils.h>
30 #include <gtkmm2ext/barcontroller.h>
36 using namespace Gtkmm2ext
;
38 BarController::BarController (Gtk::Adjustment
& adj
,
39 PBD::Controllable
& mc
,
40 sigc::slot
<void,char*,unsigned int> lc
)
51 switch_on_release
= false;
55 layout
= darea
.create_pango_layout("");
57 set_shadow_type (SHADOW_NONE
);
59 initial_value
= adjustment
.get_value ();
61 adjustment
.signal_value_changed().connect (mem_fun (*this, &Gtk::Widget::queue_draw
));
62 adjustment
.signal_changed().connect (mem_fun (*this, &Gtk::Widget::queue_draw
));
64 darea
.add_events (Gdk::BUTTON_RELEASE_MASK
|
65 Gdk::BUTTON_PRESS_MASK
|
66 Gdk::POINTER_MOTION_MASK
|
67 Gdk::ENTER_NOTIFY_MASK
|
68 Gdk::LEAVE_NOTIFY_MASK
|
71 darea
.signal_expose_event().connect (mem_fun (*this, &BarController::expose
));
72 darea
.signal_motion_notify_event().connect (mem_fun (*this, &BarController::motion
));
73 darea
.signal_button_press_event().connect (mem_fun (*this, &BarController::button_press
), false);
74 darea
.signal_button_release_event().connect (mem_fun (*this, &BarController::button_release
), false);
75 darea
.signal_scroll_event().connect (mem_fun (*this, &BarController::scroll
));
77 spinner
.signal_activate().connect (mem_fun (*this, &BarController::entry_activated
));
78 spinner
.signal_focus_out_event().connect (mem_fun (*this, &BarController::entry_focus_out
));
79 spinner
.set_digits (3);
86 BarController::drop_grab ()
90 darea
.remove_modal_grab();
96 BarController::button_press (GdkEventButton
* ev
)
100 if (binding_proxy
.button_press_handler (ev
)) {
104 switch (ev
->button
) {
106 if (ev
->type
== GDK_2BUTTON_PRESS
) {
107 switch_on_release
= true;
110 switch_on_release
= false;
111 darea
.add_modal_grab();
114 grab_window
= ev
->window
;
121 fract
= ev
->x
/ (darea
.get_width() - 2.0);
122 adjustment
.set_value (adjustment
.get_lower() + fract
* (adjustment
.get_upper() - adjustment
.get_lower()));
136 BarController::button_release (GdkEventButton
* ev
)
140 switch (ev
->button
) {
142 if (switch_on_release
) {
143 Glib::signal_idle().connect (mem_fun (*this, &BarController::switch_to_spinner
));
147 if ((ev
->state
& (GDK_SHIFT_MASK
|GDK_CONTROL_MASK
)) == GDK_SHIFT_MASK
) {
148 adjustment
.set_value (initial_value
);
152 if ((ev
->state
& (GDK_CONTROL_MASK
|GDK_SHIFT_MASK
)) == (GDK_CONTROL_MASK
|GDK_SHIFT_MASK
)) {
154 } else if (ev
->state
& GDK_CONTROL_MASK
) {
160 mouse_control (ev
->x
, ev
->window
, scale
);
178 BarController::scroll (GdkEventScroll
* ev
)
182 if ((ev
->state
& (GDK_CONTROL_MASK
|GDK_SHIFT_MASK
)) == (GDK_CONTROL_MASK
|GDK_SHIFT_MASK
)) {
184 } else if (ev
->state
& GDK_CONTROL_MASK
) {
190 switch (ev
->direction
) {
192 case GDK_SCROLL_RIGHT
:
193 adjustment
.set_value (adjustment
.get_value() + (scale
* adjustment
.get_step_increment()));
196 case GDK_SCROLL_DOWN
:
197 case GDK_SCROLL_LEFT
:
198 adjustment
.set_value (adjustment
.get_value() - (scale
* adjustment
.get_step_increment()));
206 BarController::motion (GdkEventMotion
* ev
)
214 if ((ev
->state
& (GDK_SHIFT_MASK
|GDK_CONTROL_MASK
)) == GDK_SHIFT_MASK
) {
218 if ((ev
->state
& (GDK_CONTROL_MASK
|GDK_SHIFT_MASK
)) == (GDK_CONTROL_MASK
|GDK_SHIFT_MASK
)) {
220 } else if (ev
->state
& GDK_CONTROL_MASK
) {
226 return mouse_control (ev
->x
, ev
->window
, scale
);
230 BarController::mouse_control (double x
, GdkWindow
* window
, double scaling
)
235 if (window
!= grab_window
) {
237 grab_window
= window
;
247 fract
= scaling
* (delta
/ (darea
.get_width() - 2));
248 fract
= min (1.0, fract
);
249 fract
= max (-1.0, fract
);
250 adjustment
.set_value (adjustment
.get_value() + fract
* (adjustment
.get_upper() - adjustment
.get_lower()));
262 BarController::expose (GdkEventExpose
* event
)
264 Glib::RefPtr
<Gdk::Window
> win (darea
.get_window());
266 gint x1
=0, x2
=0, y1
=0, y2
=0;
270 fract
= ((adjustment
.get_value() - adjustment
.get_lower()) /
271 (adjustment
.get_upper() - adjustment
.get_lower()));
275 w
= darea
.get_width() - 1;
276 h
= darea
.get_height();
277 x1
= (gint
) floor (w
* fract
);
283 parent
= get_parent();
286 win
->draw_rectangle (parent
->get_style()->get_fg_gc (parent
->get_state()),
288 0, 0, darea
.get_width(), darea
.get_height());
293 win
->draw_rectangle (get_style()->get_bg_gc (get_state()),
295 0, 0, darea
.get_width() - ((darea
.get_width()+1) % 2), darea
.get_height());
298 win
->draw_line (get_style()->get_fg_gc (get_state()), x1
, 0, x1
, h
);
306 w
= darea
.get_width() - 2;
307 h
= darea
.get_height() - 2;
310 x2
= (gint
) floor (w
* fract
);
314 win
->draw_rectangle (get_style()->get_bg_gc (get_state()),
316 0, 0, darea
.get_width() - 1, darea
.get_height() - 1);
318 /* draw active box */
320 win
->draw_rectangle (get_style()->get_fg_gc (get_state()),
327 /* draw inactive box */
329 win
->draw_rectangle (get_style()->get_fg_gc (STATE_INSENSITIVE
),
352 label_callback (buf
, 64);
354 if (buf
[0] != '\0') {
356 layout
->set_text (buf
);
359 layout
->get_pixel_size (width
, height
);
363 xpos
= max (3, 1 + (x2
- (width
/2)));
364 xpos
= min (darea
.get_width() - width
- 3, xpos
);
366 win
->draw_layout (get_style()->get_text_gc (get_state()),
368 (darea
.get_height()/2) - (height
/2),
377 BarController::set_with_text (bool yn
)
379 if (with_text
!= yn
) {
386 BarController::set_style (Style s
)
393 BarController::switch_to_bar ()
401 if (get_child() == &darea
) {
414 BarController::switch_to_spinner ()
422 if (get_child() == &spinner
) {
429 spinner
.select_region (0, spinner
.get_text_length());
430 spinner
.grab_focus ();
437 BarController::entry_activated ()
439 string text
= spinner
.get_text ();
442 if (sscanf (text
.c_str(), "%f", &val
) == 1) {
443 adjustment
.set_value (val
);
450 BarController::entry_focus_out (GdkEventFocus
* ev
)
457 BarController::set_use_parent (bool yn
)
464 BarController::set_sensitive (bool yn
)
466 Frame::set_sensitive (yn
);
467 darea
.set_sensitive (yn
);