NAME

Gtk2::Ex::Dragger -- drag to move adjustment position

SYNOPSIS

use Gtk2::Ex::Dragger;
Gtk2::Ex::Dragger->new (widget => $widget,
                        hadjustment => $widget->get_hadjustment);

DESCRIPTION

Gtk2::Ex::Dragger implements mouse pointer dragging to move the contents of a widget horizontally, vertically, or both. It works on any windowed widget with Gtk2::Adjustment objects controlling the visible area.

The width or height of the widget corresponds to the "page" in the adjustment and Dragger scales pixel movement to the adjustment "value" accordingly. It's then up to the usual widget drawing code to follow value-changed signals from the adjustment for redraws, the same as for scrollbars etc. The effect for the user is that the contents get pulled around with the mouse.

             Adjustment
                  +--+ --upper
                  |  |
 Window           |  |
+-------------+ \ |  |
|             |  \|  |
|             |   +--+ \_ page size
|             |   |  | /
|             |   +--+ ___ value
|             |  /|  |
+-------------+ / |  |
                  |  |
                  |  |
                  +--+ --lower

If you've got scrollbars attached to the adjustments then they move with the dragging too. It can be good to have scrollbars together with draggability since the scrollbars give visual feedback but the dragging allows fine movements if the visible page is only a small part of the adjustment extents.

The "confine" option allows you to restict mouse movement to screen positions corresponding to the adjustement extents, so the user gets an obvious feedback at the limits.

The "cursor" option changes the mouse pointer cursor while dragging. This is good if it's not obvious in a given widget which button press etc activates a drag. The cursor is set through Gtk2::Ex::WidgetCursor and so cooperates with other uses of that (such as the global "busy" indication).

Dragger can work on both natively scrollable widgets and widgets put into a Gtk2::Viewport. For a viewport it's the viewport widget which should be passed to the dragger (it being the "visible" part of a larger underlying thing).

Changes to the adjustment extents or page size or to the widget window size are allowed during a drag, though currently any external changes to the "value", ie. the position, during a drag will be overridden.

FUNCTIONS

Gtk2::Ex::Dragger->new (key=>value, ...)

Create and return a new dragger. Key/value pairs set the following various parameters,

widget         the widget to drag
hadjustment    Gtk2::Adjustment
vadjustment    Gtk2::Adjustment
hinverted      boolean
vinverted      boolean
cursor         cursor name per Gtk2::Ex::WidgetCursor
confine        boolean
update_policy  string

The target widget and at least one of hadjustment or vadjustment are mandatory, the rest are options.

The hinverted or vinverted flags swap the direction the adjustments are moved. Normally the hadjustment value increases to the left and the vadjustment downwards. Inverting goes instead to the right, and upwards. This is the same sense as Gtk2::Scrollbar uses, so if you've set inverted on your scrollbar then do the same to the dragger.

cursor is any cursor name or object accepted by the WidgetCursor mechanism (see Gtk2::Ex::WidgetCursor). If unset or undef then the cursor is unchanged (and you don't need to have WidgetCursor installed in that case).

update_policy is a string option for how often to emit value-changed signals on the adjustments. "continous" means every motion event, "delayed" means after 300 milliseconds (to collapse multiple motions), or "discontinuous" means only on ending the drag. But the secret default you get without an update_policy option is designed to be a good compromise between smoothness and collapsing. It syncs with the X server to avoid hammering, folowed by a wait for idle or timeout on the client side, whichever comes first.

$dragger->start ($event)

Begin a drag. $event must be a Gtk2::Gdk::Event::Button button press object; it gives the button doing the drag (and a server timestamp).

$dragger->stop ()
$dragger->stop ($event)

Stop $dragger, if it's active. Normally a dragger stops itself when the dragging button is released, but this method can be do it sooner.

If you stop in response to a Gdk event then pass the Gtk2::Gdk::Event so its timestamp can be used. (This matters with the confine option if event processing is lagged; ensuring any later button passive grab isn't undone.)

OTHER NOTES

The update_policy option is the same sort of thing Gtk2::Scrollbar has, and is done in the same way, namely the value in the adjustment is set, but the value-changed signal emission may be deferred for a while. Choosing a policy is really a matter of how good the drawing your target widget is. You can see the difference for example with a big block of text in a Gtk2::TextView versus a viewport and Gtk2::Label. The TextView goes very close to coping with continuous update policy, but the same on the Label's naive drawing ends up flooding the server to the point of being unusable.

Dragger recognises pointer-motion-hint-mask flag in the events mask of its target widget and will do a $widget->get_pointer in each motion event processed. This means a deliberate server round-trip on each move, which has the effect of making each motion wait until the drawing etc from the previous one has finished. Give this a try if you're having trouble with excessive redrawing going to the server, though the default update policy is meant to achieve the same effect asynchronously.

Currently only a weak reference is kept to the target widget, so the fact there's a dragger feature created doesn't keep it alive forever. This means in particular it's safe to hold the dragger object in the widget instance data without creating a circular reference. But strong references are kept to the adjustment objects since they probably should stay alive as long as the widget and dragger do. But perhaps this will be changed.

SEE ALSO

Gtk2::Adjustment, Gtk2::Ex::WidgetCursor

HOME PAGE

http://www.geocities.com/user42_kevin/gtk2-ex-dragger/index.html

LICENSE

Copyright 2007, 2008 Kevin Ryde

Gtk2-Ex-Dragger is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version.

Gtk2-Ex-Dragger is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with Gtk2-Ex-Dragger. If not, see http://www.gnu.org/licenses/.