rendered paste body#!/usr/bin/python# vim: set expandtab tabstop=4 shiftwidth=4:import gtkimport mathimport timeimport cairoimport gobjectclass ClickDrag(object): def __init__(self, winsize, areasize): self.areasize = areasize window = gtk.Window() window.set_title('Testing Click-and-Drag') window.set_size_request(winsize, winsize) vbox = gtk.VBox() window.add(vbox) label = gtk.Label('Click and drag, yo.') label.set_padding(0, 10) vbox.pack_start(label, False, False) scroll = gtk.ScrolledWindow() vbox.add(scroll) vport = gtk.Viewport() scroll.add(vport) self.hadj = scroll.get_hadjustment() self.vadj = scroll.get_vadjustment() self.area = gtk.DrawingArea() vport.add(self.area) self.area.set_size_request(self.areasize, self.areasize) self.area.set_events(gtk.gdk.POINTER_MOTION_MASK | gtk.gdk.BUTTON_PRESS_MASK | gtk.gdk.BUTTON_RELEASE_MASK) self.area.connect('realize', self.draw) window.connect('delete-event', gtk.main_quit) self.dragging = False self.window = window def draw(self, widget=None): # Pixmap for the DrawingArea self.pixmap = gtk.gdk.Pixmap(self.area.window, self.areasize, self.areasize) ctx = self.pixmap.cairo_create() ctx.set_source_rgba(0, 0, 0, 1) ctx.paint() # Populate with a gradient center = self.areasize/2 grad = cairo.RadialGradient(center, center, 0, center, center, math.sqrt((center**2)*2)) grad.add_color_stop_rgb(0, 0, 0, 0) grad.add_color_stop_rgb(.25, 1, 0, 0) grad.add_color_stop_rgb(.50, 0, 1, 0) grad.add_color_stop_rgb(.75, 0, 0, 1) grad.add_color_stop_rgb(1, 1, 1, 1) ctx.set_source(grad) ctx.paint() # Now initialize self.style = self.area.get_style().fg_gc[gtk.STATE_NORMAL] self.area.connect('expose-event', self.on_expose) self.area.connect('button-press-event', self.on_button_press) self.area.connect('button-release-event', self.on_button_release) self.area.connect('motion-notify-event', self.on_motion_notify) self.area.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.FLEUR)) self.on_expose() print 'Horizontal upper: %d' % (self.hadj.get_upper()) print 'Vertical upper: %d' % (self.vadj.get_upper()) # Clean up return False def on_expose(self, widget=None, event=None): self.area.window.draw_drawable(self.style, self.pixmap, 0, 0, 0, 0, self.areasize, self.areasize) def on_button_press(self, widget, event): self.dragging = True self.hold_x = event.x_root self.hold_y = event.y_root self.area.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.DOT)) def on_button_release(self, widget, event): self.dragging = False self.area.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.FLEUR)) def on_motion_notify(self, widget, event): if self.dragging: diff_x = self.hold_x - event.x_root diff_y = self.hold_y - event.y_root if diff_x != 0: newval = self.hadj.get_value() + diff_x if newval < self.hadj.lower: newval = self.hadj.lower elif newval > self.hadj.upper-self.hadj.page_size: newval = self.hadj.upper-self.hadj.page_size self.hadj.set_value(newval) if diff_y != 0: newval = self.vadj.get_value() + diff_y if newval < self.vadj.lower: newval = self.vadj.lower elif newval > self.vadj.upper-self.vadj.page_size: newval = self.vadj.upper-self.vadj.page_size self.vadj.set_value(newval) self.hold_x = event.x_root self.hold_y = event.y_root def run(self): self.window.show_all() gtk.main()if __name__ == '__main__': foo = ClickDrag(700, 3000) foo.run()