tuikit/scrollbar.py
author Radek Brich <radek.brich@devl.cz>
Wed, 26 Dec 2012 01:00:31 +0100
changeset 40 5faa38c10b67
parent 34 e3beacd5e536
child 41 37b7dfc3eae6
permissions -rw-r--r--
Add ScrollView widget. Update Emitter, rename "on_event" methods to "_handle_event". Update VScrollbar, Layout.

# -*- coding: utf-8 -*-

from tuikit.widget import Widget


class VScrollbar(Widget):
    def __init__(self, height=10):
        Widget.__init__(self, 1, height)

        self._max = height - 3
        self._pos = 0
        self._thumbpos = 0

        self.interval = 0.1

        self.dragging = False
        self.move = None

        self.add_events('change')

    @property
    def max(self):
        """Maximum for scrolling position."""
        return self._max

    @max.setter
    def max(self, value):
        self._max = value
        self._update_thumbpos()

    @property
    def pos(self):
        """Scrolling position.

        Integer number between 0 and 'max'.

        """
        return self._pos

    @pos.setter
    def pos(self, value):
        self._pos = value
        self._update_thumbpos()
        self.emit('change')

    def _update_thumbpos(self):
        self._thumbpos = 0
        if self._max and self._pos <= self._max:
            self._thumbpos = int(round(self._pos / self._max * (self.height - 3)))
        self.redraw()

    def _handle_draw(self, screen, x, y):
        super()._handle_draw(screen, x, y)
        screen.putch(x, y, screen.unigraph.UP_ARROW)
        for i in range(y + 1, y + self.height - 1):
            screen.putch(x, i, screen.unigraph.LIGHT_SHADE)
        screen.putch(x, y + 1 + self._thumbpos, screen.unigraph.BLOCK)
        screen.putch(x, y + self.height - 1, screen.unigraph.DOWN_ARROW)

    def _handle_mousedown(self, ev):
        super()._handle_mousedown(ev)
        self.dragging = False
        self.move = None
        # arrow buttons
        if ev.wy == 0 or ev.wy == self.height - 1:
            if ev.wy == 0:
                self.move_up()
            else:
                self.move_down()
            self.top.add_timeout(self.interval * 2, self._timeout)
            return
        # thumb bar
        if ev.wy == 1 + self._thumbpos:
            self.dragging = True
            return

    def _handle_mouseup(self, ev):
        super()._handle_mouseup(ev)
        if self.dragging:
            self.drag(ev.wy)
            self.dragging = False
            return
        if self.move:
            self.top.remove_timeout(self._timeout)
            self.move = None
            return

    def _handle_mousemove(self, ev):
        super()._handle_mousemove(ev)
        if self.dragging:
            self.drag(ev.wy)

    def _timeout(self):
        if self.move == 'up':
            self.move_up()
        if self.move == 'down':
            self.move_down()
        self.top.add_timeout(self.interval, self._timeout)

    def move_up(self):
        if self._pos > 0:
            self.pos = self._pos - 1
        self.move = 'up'

    def move_down(self):
        if self._pos < self._max:
            self.pos = self._pos + 1
        self.move = 'down'

    def drag(self, wy):
        newpos = int(round((wy - 1) / (self.height - 3) * self._max))
        if newpos < 0:
            newpos = 0
        if newpos > self._max:
            newpos = self._max
        if self._pos != newpos:
            self.pos = newpos