2 Copyright (C) 2006 Paul Davis
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.
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.
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.
18 $Id: fastmeter.h 570 2006-06-07 21:21:21Z sampo $
23 #include <gtkmm2ext/pixfader.h>
25 using namespace Gtkmm2ext;
30 PixFader::PixFader (Glib::RefPtr<Pixbuf> base, Glib::RefPtr<Pixbuf> handle, Gtk::Adjustment& adj)
33 handle_pixbuf (handle)
36 default_value = adjustment.get_value();
40 pixrect.width = base_pixbuf->get_width();
41 pixrect.height = base_pixbuf->get_height();
42 pixheight = pixrect.height;
44 unity_y = (int) rint (pixrect.height - (default_value * pixrect.height));
46 add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK|Gdk::POINTER_MOTION_MASK|Gdk::SCROLL_MASK);
48 adjustment.signal_value_changed().connect (mem_fun (*this, &PixFader::adjustment_changed));
49 adjustment.signal_changed().connect (mem_fun (*this, &PixFader::adjustment_changed));
52 PixFader::~PixFader ()
57 PixFader::on_expose_event (GdkEventExpose* ev)
59 GdkRectangle intersection;
60 GdkRectangle background;
62 pixrect.height = display_height ();
66 background.width = pixrect.width;
67 background.height = pixheight - pixrect.height;
69 if (gdk_rectangle_intersect (&background, &ev->area, &intersection)) {
70 get_window()->draw_pixbuf (get_style()->get_fg_gc (get_state()), base_pixbuf,
71 intersection.x, intersection.y,
73 intersection.width, intersection.height,
74 Gdk::RGB_DITHER_NONE, 0, 0);
78 /* recompute the height of the handle area to use X Window's top->bottom coordinate
82 pixrect.y = pixheight - pixrect.height;
84 if (gdk_rectangle_intersect (&pixrect, &ev->area, &intersection)) {
85 get_window()->draw_pixbuf(get_style()->get_fg_gc(get_state()), handle_pixbuf,
86 intersection.x, intersection.y,
88 intersection.width, intersection.height,
89 Gdk::RGB_DITHER_NONE, 0, 0);
92 /* always draw the line */
94 get_window()->draw_line (get_style()->get_fg_gc(get_state()), 0, unity_y, pixrect.width, unity_y);
96 last_drawn = pixrect.height;
101 PixFader::on_size_request (GtkRequisition* req)
103 req->width = base_pixbuf->get_width();
104 req->height = base_pixbuf->get_height ();
108 PixFader::on_button_press_event (GdkEventButton* ev)
110 switch (ev->button) {
112 if (!(ev->state & Gdk::SHIFT_MASK)) {
116 grab_window = ev->window;
129 PixFader::on_button_release_event (GdkEventButton* ev)
133 if (ev->state & GDK_CONTROL_MASK) {
134 if (ev->state & GDK_MOD1_MASK) {
143 switch (ev->button) {
149 if (ev->y == grab_start) {
150 /* no motion - just a click */
153 if (ev->y < (pixheight/2)) {
157 fract = 1.0 - (ev->y - pixheight);
160 fract = min (1.0, fract);
161 fract = max (0.0, fract);
163 adjustment.set_value (scale * fract * (adjustment.get_upper() - adjustment.get_lower()));
166 if (ev->state & Gdk::SHIFT_MASK) {
167 adjustment.set_value (default_value);
178 PixFader::on_scroll_event (GdkEventScroll* ev)
182 if (ev->state & GDK_CONTROL_MASK) {
183 if (ev->state & GDK_MOD1_MASK) {
192 switch (ev->direction) {
196 adjustment.set_value (adjustment.get_value() + (adjustment.get_page_increment() * scale));
198 case GDK_SCROLL_DOWN:
200 adjustment.set_value (adjustment.get_value() - (adjustment.get_page_increment() * scale));
209 PixFader::on_motion_notify_event (GdkEventMotion* ev)
216 if (ev->window != grab_window) {
218 grab_window = ev->window;
222 if (ev->state & GDK_CONTROL_MASK) {
223 if (ev->state & GDK_MOD1_MASK) {
232 delta = ev->y - grab_y;
235 fract = (delta / pixheight);
237 fract = min (1.0, fract);
238 fract = max (-1.0, fract);
240 // X Window is top->bottom for 0..Y
244 adjustment.set_value (adjustment.get_value() + scale * fract * (adjustment.get_upper() - adjustment.get_lower()));
251 PixFader::adjustment_changed ()
253 if (display_height() != last_drawn) {