tuikit/container.py
author Radek Brich <radek.brich@devl.cz>
Mon, 10 Oct 2011 22:20:59 +0200
changeset 25 f69a1f0382ce
parent 23 4e72fd2a0e14
child 32 088b92ffb119
permissions -rw-r--r--
Partial DriverPygame.putch() implementation. Add patch for PyGame implementing font.render_glyph(). Add test for PyGame font module. Add special key definitions to DriverPygame.

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

import logging

from tuikit.widget import Widget
from tuikit.common import Borders


class Container(Widget):
    
    '''Container widget. Base for any widget which can contain other widgets.'''
    
    def __init__(self, width = 10, height = 10):
        '''Create container of requested size.'''
        Widget.__init__(self, width, height)

        #: List of child widgets.
        self.children = []
        
        self.mousechild = None

        #: Width of borders (left, top, right, bottom).
        #: Child widgets are placed within borders.
        self.borders = Borders()
        
        self._layout = None
        
        self.widthrequest = (None, None)
        self.heightrequest = (None, None)

        self.colorprefix = None

        self.trapfocus = False  # if True, tab cycles inside container


    def add(self, widget, **kw):
        '''Add widget into this container.'''
        self.children.append(widget)
        widget.parent = self
        widget.settop(self.top)
        widget.hints.update(kw)


    def layout(self, layout):
        '''Set layout manager for placing child widgets.'''
        self._layout = layout
        layout.container = self
        self.connect('resize', layout.resize)


    def settop(self, top):
        '''Set top widget.'''
        self.top = top
        for child in self.children:
            child.settop(top)


    def focusnext(self):
        i = self.children.index(self.top.focuswidget)
        while True:
            i += 1
            if i >= len(self.children):
                i = 0
            if self.children[i].canfocus():
                self.children[i].setfocus()
                break
        log = logging.getLogger('tuikit')
        log.debug(str(self.top.focuswidget.__class__))


    def keypress(self, keyname, char):
        if keyname == 'tab':
            self.focusnext()
            return
        Widget.keypress(self, keyname, char)


    def resize(self):
        Widget.resize(self)
        for child in self.children:
            child.emit('resize')


    def draw(self, driver, x=0, y=0):
        if self.hidden:
            return

        driver.clipstack.push(x, y, self.width, self.height)
        if self.colorprefix:
            driver.pushcolorprefix(self.colorprefix)

        Widget.draw(self, driver, x, y)

        for child in [x for x in self.children if not x.allowlayout]:
            child.draw(driver, x + child.x, y + child.y)

        l, t, r, b = self.borders
        driver.clipstack.push(x+l, y+t, self.width-l-r, self.height-t-b)

        for child in [x for x in self.children if x.allowlayout]:
            child.draw(driver, x + child.x, y + child.y)

        driver.clipstack.pop()

        if self.colorprefix:
            driver.popcolorprefix()
        driver.clipstack.pop()


    def mousedown(self, ev):
        handled = False
        for child in reversed(self.children):
            if child.enclose(ev.wx, ev.wy):
                childev = ev.childevent(child)
                child.mousedown(childev)
                self.mousechild = child
                handled = True
                break
        if not handled:
            self.setfocus()
            self.handle('mousedown', ev)


    def mouseup(self, ev):
        if self.mousechild:
            childev = ev.childevent(self.mousechild)
            self.mousechild.mouseup(childev)
            self.mousechild = None
        else:
            self.handle('mouseup', ev)
        #handled = False
        #for child in self.children:
            #if child.enclose(ev.wx, ev.wy):
                #childev = ev.childevent(child)
                #child.mouseup(childev)
                #self.mousechild = child
                #handled = True
        #if not handled:
            #self.handle('mouseup', ev)


    def mousemove(self, ev):
        if self.mousechild:
            childev = ev.childevent(self.mousechild)
            self.mousechild.mousemove(childev)
        else:
            self.handle('mousemove', ev)


    def mousewheel(self, ev):
        handled = False
        for child in reversed(self.children):
            if child.enclose(ev.wx, ev.wy):
                childev = ev.childevent(child)
                child.mousewheel(childev)
                handled = True
                break
        if not handled:
            self.handle('mousewheel', ev)