2 Copyright (C) 2005 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.
26 #include "gtkmm2ext/pixscroller.h"
27 #include "gtkmm2ext/keyboard.h"
31 using namespace Gtkmm2ext
;
33 PixScroller::PixScroller (Adjustment
& a
,
34 Glib::RefPtr
<Gdk::Pixbuf
> s
,
35 Glib::RefPtr
<Gdk::Pixbuf
> r
)
43 add_events (Gdk::BUTTON_PRESS_MASK
|Gdk::BUTTON_RELEASE_MASK
|Gdk::POINTER_MOTION_MASK
|Gdk::SCROLL_MASK
);
45 adj
.signal_value_changed().connect (mem_fun (*this, &PixScroller::adjustment_changed
));
46 default_value
= adj
.get_value();
48 sliderrect
.set_width(slider
->get_width());
49 sliderrect
.set_height(slider
->get_height());
50 railrect
.set_width(rail
->get_width());
51 railrect
.set_height(rail
->get_height());
53 railrect
.set_y(sliderrect
.get_height() / 2);
56 overall_height
= railrect
.get_height() + sliderrect
.get_height();
58 sliderrect
.set_y((int) rint ((overall_height
- sliderrect
.get_height()) * (adj
.get_upper() - adj
.get_value())));
59 railrect
.set_x((sliderrect
.get_width() / 2) - 2);
61 if (rail
->get_has_alpha()) {
62 format
= Cairo::FORMAT_ARGB32
;
64 format
= Cairo::FORMAT_RGB24
;
66 rail_surface
= Cairo::ImageSurface::create (format
, rail
->get_width(), rail
->get_height());
67 rail_context
= Cairo::Context::create (rail_surface
);
68 Gdk::Cairo::set_source_pixbuf (rail_context
, rail
, 0.0, 0.0);
69 rail_context
->paint();
71 if (slider
->get_has_alpha()) {
72 format
= Cairo::FORMAT_ARGB32
;
74 format
= Cairo::FORMAT_RGB24
;
76 slider_surface
= Cairo::ImageSurface::create (format
, slider
->get_width(), slider
->get_height());
77 slider_context
= Cairo::Context::create (slider_surface
);
78 Gdk::Cairo::set_source_pixbuf (slider_context
, slider
, 0.0, 0.0);
79 slider_context
->paint();
83 PixScroller::on_size_request (GtkRequisition
* requisition
)
85 requisition
->width
= sliderrect
.get_width();
86 requisition
->height
= overall_height
;
90 PixScroller::on_expose_event (GdkEventExpose
* ev
)
92 GdkRectangle intersect
;
93 Glib::RefPtr
<Gdk::Window
> win (get_window());
94 Cairo::RefPtr
<Cairo::Context
> context
= get_window()->create_cairo_context();
96 if (gdk_rectangle_intersect (railrect
.gobj(), &ev
->area
, &intersect
)) {
99 context
->rectangle (intersect
.x
, intersect
.y
, intersect
.width
, intersect
.height
);
101 context
->set_source (rail_surface
, intersect
.x
- railrect
.get_x(), intersect
.y
- railrect
.get_y());
102 context
->rectangle (intersect
.x
, intersect
.y
, intersect
.width
, intersect
.height
);
108 if (gdk_rectangle_intersect (sliderrect
.gobj(), &ev
->area
, &intersect
)) {
111 context
->rectangle (intersect
.x
, intersect
.y
, intersect
.width
, intersect
.height
);
113 context
->set_source (rail_surface
, intersect
.x
- sliderrect
.get_x(), intersect
.y
- sliderrect
.get_y());
114 context
->rectangle (intersect
.x
, intersect
.y
, intersect
.width
, intersect
.height
);
124 PixScroller::on_button_press_event (GdkEventButton
* ev
)
126 switch (ev
->button
) {
128 if (!(ev
->state
& Keyboard::TertiaryModifier
)) {
132 grab_window
= ev
->window
;
145 PixScroller::on_button_release_event (GdkEventButton
* ev
)
149 if (ev
->state
& Keyboard::PrimaryModifier
) {
150 if (ev
->state
& Keyboard::SecondaryModifier
) {
159 switch (ev
->button
) {
165 if (ev
->y
== grab_start
) {
166 /* no motion - just a click */
169 if (ev
->y
< sliderrect
.get_height()/2) {
173 fract
= 1.0 - (ev
->y
- sliderrect
.get_height()/2) / railrect
.get_height();
176 fract
= min (1.0, fract
);
177 fract
= max (0.0, fract
);
179 adj
.set_value (scale
* fract
* (adj
.get_upper() - adj
.get_lower()));
182 if (ev
->state
& Keyboard::TertiaryModifier
) {
183 adj
.set_value (default_value
);
184 cerr
<< "default value = " << default_value
<< endl
;
195 PixScroller::on_scroll_event (GdkEventScroll
* ev
)
199 if (ev
->state
& Keyboard::PrimaryModifier
) {
200 if (ev
->state
& Keyboard::SecondaryModifier
) {
209 switch (ev
->direction
) {
213 adj
.set_value (adj
.get_value() + (adj
.get_page_increment() * scale
));
215 case GDK_SCROLL_DOWN
:
217 adj
.set_value (adj
.get_value() - (adj
.get_page_increment() * scale
));
226 PixScroller::on_motion_notify_event (GdkEventMotion
* ev
)
233 if (ev
->window
!= grab_window
) {
235 grab_window
= ev
->window
;
239 if (ev
->state
& Keyboard::PrimaryModifier
) {
240 if (ev
->state
& Keyboard::SecondaryModifier
) {
249 delta
= ev
->y
- grab_y
;
252 fract
= (delta
/ railrect
.get_height());
254 fract
= min (1.0, fract
);
255 fract
= max (-1.0, fract
);
259 adj
.set_value (adj
.get_value() + scale
* fract
* (adj
.get_upper() - adj
.get_lower()));
266 PixScroller::adjustment_changed ()
268 int y
= (int) rint ((overall_height
- sliderrect
.get_height()) * (adj
.get_upper() - adj
.get_value()));
270 if (y
!= sliderrect
.get_y()) {