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
)
41 add_events (Gdk::BUTTON_PRESS_MASK
|Gdk::BUTTON_RELEASE_MASK
|Gdk::POINTER_MOTION_MASK
|Gdk::SCROLL_MASK
);
43 adj
.signal_value_changed().connect (mem_fun (*this, &PixScroller::adjustment_changed
));
44 default_value
= adj
.get_value();
46 sliderrect
.set_width(slider
->get_width());
47 sliderrect
.set_height(slider
->get_height());
48 railrect
.set_width(rail
->get_width());
49 railrect
.set_height(rail
->get_height());
51 railrect
.set_y(sliderrect
.get_height() / 2);
54 overall_height
= railrect
.get_height() + sliderrect
.get_height();
56 sliderrect
.set_y((int) rint ((overall_height
- sliderrect
.get_height()) * (adj
.get_upper() - adj
.get_value())));
57 railrect
.set_x((sliderrect
.get_width() / 2) - 2);
61 PixScroller::on_size_request (GtkRequisition
* requisition
)
63 requisition
->width
= sliderrect
.get_width();
64 requisition
->height
= overall_height
;
68 PixScroller::on_expose_event (GdkEventExpose
* ev
)
70 GdkRectangle intersect
;
71 Glib::RefPtr
<Gdk::Window
> win (get_window());
73 win
->draw_rectangle (get_style()->get_bg_gc(get_state()), TRUE
,
79 if (gdk_rectangle_intersect (railrect
.gobj(), &ev
->area
, &intersect
)) {
80 Glib::RefPtr
<Gdk::GC
> gc(get_style()->get_bg_gc(get_state()));
81 win
->draw_pixbuf (gc
, rail
,
82 intersect
.x
- railrect
.get_x(),
83 intersect
.y
- railrect
.get_y(),
88 Gdk::RGB_DITHER_NONE
, 0, 0);
91 if (gdk_rectangle_intersect (sliderrect
.gobj(), &ev
->area
, &intersect
)) {
92 Glib::RefPtr
<Gdk::GC
> gc(get_style()->get_fg_gc(get_state()));
93 // Glib::RefPtr<Gdk::Bitmap> mask (slider_mask);
96 gdk_gc_get_values(gc
->gobj(), &values
);
97 gc
->set_clip_origin (sliderrect
.get_x(), sliderrect
.get_y());
98 // gc->set_clip_mask (mask);
99 win
->draw_pixbuf (gc
, slider
,
100 intersect
.x
- sliderrect
.get_x(),
101 intersect
.y
- sliderrect
.get_y(),
106 Gdk::RGB_DITHER_NONE
, 0, 0);
107 gc
->set_clip_origin (values
.clip_x_origin
, values
.clip_y_origin
);
108 // gdk_gc_set_clip_mask (gc->gobj(), values.clip_mask);
116 PixScroller::on_button_press_event (GdkEventButton
* ev
)
118 switch (ev
->button
) {
120 if (!(ev
->state
& Keyboard::TertiaryModifier
)) {
124 grab_window
= ev
->window
;
137 PixScroller::on_button_release_event (GdkEventButton
* ev
)
141 if (ev
->state
& Keyboard::PrimaryModifier
) {
142 if (ev
->state
& Keyboard::SecondaryModifier
) {
151 switch (ev
->button
) {
157 if (ev
->y
== grab_start
) {
158 /* no motion - just a click */
161 if (ev
->y
< sliderrect
.get_height()/2) {
165 fract
= 1.0 - (ev
->y
- sliderrect
.get_height()/2) / railrect
.get_height();
168 fract
= min (1.0, fract
);
169 fract
= max (0.0, fract
);
171 adj
.set_value (scale
* fract
* (adj
.get_upper() - adj
.get_lower()));
174 if (ev
->state
& Keyboard::TertiaryModifier
) {
175 adj
.set_value (default_value
);
176 cerr
<< "default value = " << default_value
<< endl
;
187 PixScroller::on_scroll_event (GdkEventScroll
* ev
)
191 if (ev
->state
& Keyboard::PrimaryModifier
) {
192 if (ev
->state
& Keyboard::SecondaryModifier
) {
201 switch (ev
->direction
) {
205 adj
.set_value (adj
.get_value() + (adj
.get_page_increment() * scale
));
207 case GDK_SCROLL_DOWN
:
209 adj
.set_value (adj
.get_value() - (adj
.get_page_increment() * scale
));
218 PixScroller::on_motion_notify_event (GdkEventMotion
* ev
)
225 if (ev
->window
!= grab_window
) {
227 grab_window
= ev
->window
;
231 if (ev
->state
& Keyboard::PrimaryModifier
) {
232 if (ev
->state
& Keyboard::SecondaryModifier
) {
241 delta
= ev
->y
- grab_y
;
244 fract
= (delta
/ railrect
.get_height());
246 fract
= min (1.0, fract
);
247 fract
= max (-1.0, fract
);
251 adj
.set_value (adj
.get_value() + scale
* fract
* (adj
.get_upper() - adj
.get_lower()));
258 PixScroller::adjustment_changed ()
260 int y
= (int) rint ((overall_height
- sliderrect
.get_height()) * (adj
.get_upper() - adj
.get_value()));
262 if (y
!= sliderrect
.get_y()) {