From: NeilBrown Date: Sat, 21 Apr 2012 10:51:57 +0000 (+1000) Subject: Add fingerscroll.py X-Git-Url: http://git.neil.brown.name/?a=commitdiff_plain;h=b1151274c6ae3e9535ebec309d31538300be854c;p=plato.git Add fingerscroll.py Fingerscroll is a python/gtk module to display text and allow it to be scrolled easily with a finger. No throwing, just dragging. Signed-off-by: NeilBrown --- diff --git a/lib/fingerscroll.py b/lib/fingerscroll.py new file mode 100644 index 0000000..685aa8e --- /dev/null +++ b/lib/fingerscroll.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python + +# Copyright (C) 2011-2012 Neil Brown +# +# This program 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 2 of the License, or +# (at your option) any later version. +# +# This program 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 this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# FingerScroll is a simple widget to wrap around TextView +# so that the TextBuffer can be scrolled with finger-wipes. +# Each wipe is either horizontal or vertical, not both. + +import gtk + +class FingerScroll(gtk.TextView): + def __init__(self, wrap=gtk.WRAP_NONE): + gtk.TextView.__init__(self) + self.hadj = gtk.Adjustment() + self.vadj = gtk.Adjustment() + self.set_size_request(1,1) + self.set_wrap_mode(wrap) + self.set_scroll_adjustments(self.hadj, self.vadj) + + self.add_events(gtk.gdk.POINTER_MOTION_MASK + | gtk.gdk.POINTER_MOTION_HINT_MASK + | gtk.gdk.BUTTON_PRESS_MASK + | gtk.gdk.BUTTON_RELEASE_MASK) + self.connect("button_press_event", self.press) + self.connect("button_release_event", self.release) + self.connect("motion_notify_event", self.motion) + self.drag_start = None + + def press(self, w, ev): + w.stop_emission("button_press_event") + + self.drag_start = int(ev.x), int(ev.y) + self.xstart = self.hadj.value + self.ystart = self.vadj.value + + def release(self, w, ev): + self.drag_start = None + w.stop_emission("button_release_event") + + def motion(self, w, ev): + if self.drag_start == None: + return + + if ev.is_hint: + x, y, state = ev.window.get_pointer() + else: + x = ev.x + y = ev.y + x = int(x) + y = int(y) + dx = x - self.drag_start[0] + dy = y - self.drag_start[1] + newx, newy = self.xstart, self.ystart + if abs(dx) > abs(dy): + newx = newx - dx + else: + newy = newy - dy + + if newx >= self.hadj.upper - self.hadj.page_size: + newx = self.hadj.upper - self.hadj.page_size + if newx <= self.hadj.lower: newx = self.hadj.lower + if newy >= self.vadj.upper - self.vadj.page_size: + newy = self.vadj.upper - self.vadj.page_size + if newy <= self.vadj.lower: newy = self.vadj.lower + self.hadj.value = newx + self.vadj.value = newy + w.stop_emission("motion_notify_event") + +if __name__ == "__main__": + # test app for FingerScroll + import sys + w = gtk.Window(gtk.WINDOW_TOPLEVEL) + w.connect("destroy", lambda w: gtk.main_quit()) + w.set_title("FingerScroll test") + w.show() + w.set_default_size(200,200) + + sw = FingerScroll(); sw.show() + w.add(sw) + + b = sw.get_buffer() + + f = open(sys.argv[-1], "r") + l = f.readline() + while len(l): + b.insert(b.get_end_iter(), l) + l = f.readline() + + gtk.main() + +