tuikit/window.py
author Radek Brich <radek.brich@devl.cz>
Fri, 18 Jan 2013 22:36:50 +0100
changeset 62 2f61931520c9
parent 45 43b2279b06e1
child 71 cfd3445107b4
permissions -rw-r--r--
Rework layouts: Layout is now normal Container which places its children upon resize event. Drop TopWindow, top is now any subclass of Container. Add floater concept: floaters are widgets drawn over normal widgets, not clipped by parent. Add HScrollbar and Scrollbar abstract base class.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     1
# -*- coding: utf-8 -*-
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     2
18
e6c3a5ee91aa Eliminate relative imports.
Radek Brich <radek.brich@devl.cz>
parents: 13
diff changeset
     3
from tuikit.container import Container
e6c3a5ee91aa Eliminate relative imports.
Radek Brich <radek.brich@devl.cz>
parents: 13
diff changeset
     4
from tuikit.button import Button
62
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
     5
from tuikit.layout import AnchorLayout
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
     6
from tuikit.common import Borders
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     7
62
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
     8
import logging
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
     9
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    10
class Window(AnchorLayout):
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 24
diff changeset
    11
13
19ebde2fd594 Add more generated documentation.
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
    12
    '''Window widget.
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 24
diff changeset
    13
13
19ebde2fd594 Add more generated documentation.
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
    14
    It represents part of screen with border, close button and contents.
19ebde2fd594 Add more generated documentation.
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
    15
    Window can be moved, resized or closed by user.'''
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 24
diff changeset
    16
62
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    17
    def __init__(self, inner_layout=AnchorLayout):
13
19ebde2fd594 Add more generated documentation.
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
    18
        '''Create window of requested size.'''
62
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    19
        AnchorLayout.__init__(self)
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    20
        self.sizemin.update(8, 3)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    21
13
19ebde2fd594 Add more generated documentation.
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
    22
        #: Window title.
2
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    23
        self.title = ''
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 24
diff changeset
    24
13
19ebde2fd594 Add more generated documentation.
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
    25
        #: Allow user to resize window.
2
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    26
        self.resizable = True
62
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    27
        self._resizing = False
13
19ebde2fd594 Add more generated documentation.
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
    28
        #: Allow user to move window.
2
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    29
        self.movable = True
62
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    30
        self._moving = False
2
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    31
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    32
        self.closebtn = Button('x')
62
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    33
        self.closebtn.sizereq.w = 3
45
43b2279b06e1 Clean up Emitter class, simplify event handling. Fix Container.focusnext() method. Add events test (handler auto-registration, order).
Radek Brich <radek.brich@devl.cz>
parents: 41
diff changeset
    34
        self.closebtn.add_handler('click', self.on_closebtn_click)
9
7175ed629a76 Added ComboBox, HorizontalLayout, TreeNode, TreeModel, TreeView. Widget is now descendant of EventSource. Improved color management (color prefixes).
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
    35
        self.closebtn.bg = 'controls'
7175ed629a76 Added ComboBox, HorizontalLayout, TreeNode, TreeModel, TreeView. Widget is now descendant of EventSource. Improved color management (color prefixes).
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
    36
        self.closebtn.bghi = 'controls-active'
62
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    37
        Container.add(self, self.closebtn, halign='right', margin=Borders(r=1))
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    38
        self._closebutton = True
7
d4a291b31cbb New color management - named colors.
Radek Brich <radek.brich@devl.cz>
parents: 5
diff changeset
    39
9
7175ed629a76 Added ComboBox, HorizontalLayout, TreeNode, TreeModel, TreeView. Widget is now descendant of EventSource. Improved color management (color prefixes).
Radek Brich <radek.brich@devl.cz>
parents: 7
diff changeset
    40
        self.colorprefix = 'window:'
2
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    41
62
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    42
        self._inner = inner_layout()
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    43
        Container.add(self, self._inner, halign='fill', valign='fill', margin=Borders(1,1,1,1))
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    44
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    45
    def add(self, widget, **kwargs):
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    46
        self._inner.add(widget, **kwargs)
2
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    47
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    48
    @property
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    49
    def closebutton(self):
13
19ebde2fd594 Add more generated documentation.
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
    50
        '''Show/hide close button.'''
2
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    51
        return self._closebutton
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    52
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    53
    @closebutton.setter
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    54
    def closebutton(self, value):
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    55
        self._closebutton = value
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    56
        self.closebtn.hidden = not value
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    57
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    58
45
43b2279b06e1 Clean up Emitter class, simplify event handling. Fix Container.focusnext() method. Add events test (handler auto-registration, order).
Radek Brich <radek.brich@devl.cz>
parents: 41
diff changeset
    59
    def on_draw(self, ev):
41
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 40
diff changeset
    60
        ev.driver.pushcolor('normal')
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 40
diff changeset
    61
        ev.driver.frame(ev.x, ev.y, self.width, self.height)
2
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    62
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    63
        if self.resizable:
62
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    64
            if self._resizing:
41
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 40
diff changeset
    65
                ev.driver.pushcolor('controls-active')
2
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    66
            else:
41
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 40
diff changeset
    67
                ev.driver.pushcolor('controls')
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 40
diff changeset
    68
            ev.driver.puts(ev.x + self.width - 2, ev.y + self.height - 1, '─┘') # '━┛'
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 40
diff changeset
    69
            ev.driver.popcolor()
2
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    70
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    71
        if self.title:
62
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    72
            title = ' ' + self.title + ' '
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    73
            left = max(1, (self.width - len(title))//2)
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    74
            right = self.width - len(title) - left
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    75
            maxlen = self.width - 5
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    76
            if left > 1 and right < 4:
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    77
                # move space from left to right to make space for close button
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    78
                left -= 1
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    79
            if len(title) > maxlen:
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    80
                title = title[:maxlen]
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    81
                title = title[:-1] + ' '
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    82
            ev.driver.puts(ev.x + left, ev.y, title)
2
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    83
41
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 40
diff changeset
    84
        ev.driver.fill(ev.x+1, ev.y+1, self.width-2, self.height-2)
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 40
diff changeset
    85
        ev.driver.popcolor()
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    86
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    87
45
43b2279b06e1 Clean up Emitter class, simplify event handling. Fix Container.focusnext() method. Add events test (handler auto-registration, order).
Radek Brich <radek.brich@devl.cz>
parents: 41
diff changeset
    88
    def after_mousedown(self, ev):
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    89
        self.dragstart = (ev.wx, ev.wy)
2
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    90
        if self.resizable and ev.wx >= self.width - 1 and ev.wy >= self.height - 1:
62
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    91
            self._resizing = True
2
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    92
        elif self.movable:
62
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    93
            self._moving = True
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    94
        self.origsize = (self.width, self.height)
2
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    95
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    96
        self.redraw(True)
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    97
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    98
45
43b2279b06e1 Clean up Emitter class, simplify event handling. Fix Container.focusnext() method. Add events test (handler auto-registration, order).
Radek Brich <radek.brich@devl.cz>
parents: 41
diff changeset
    99
    def after_mouseup(self, ev):
62
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
   100
        if self._resizing:
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
   101
            self.resize(self.origsize[0] + ev.wx - self.dragstart[0],
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
   102
                        self.origsize[1] + ev.wy - self.dragstart[1])
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
   103
            self._resizing = False
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
   104
        elif self._moving:
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
   105
            self.move(ev.px - self.dragstart[0],
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
   106
                      ev.py - self.dragstart[1])
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
   107
            self._moving = False
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   108
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   109
        self.redraw(True)
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   110
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   111
45
43b2279b06e1 Clean up Emitter class, simplify event handling. Fix Container.focusnext() method. Add events test (handler auto-registration, order).
Radek Brich <radek.brich@devl.cz>
parents: 41
diff changeset
   112
    def after_mousemove(self, ev):
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   113
        if ev.px == self.x + self.dragstart[0] \
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   114
        and ev.py == self.y + self.dragstart[1]:
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   115
            return
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   116
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   117
        #if x > self.parent.width-self.width:
24
b248ef500557 Add DriverPygame (incomplete). Move unicode graphics constants to UnicodeGraphics class. Move shared parts of drivers to Driver base class.
Radek Brich <radek.brich@devl.cz>
parents: 18
diff changeset
   118
        #    return
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   119
62
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
   120
        if self._resizing:
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
   121
            self.resize(self.origsize[0] + ev.wx - self.dragstart[0],
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
   122
                        self.origsize[1] + ev.wy - self.dragstart[1])
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
   123
        elif self._moving:
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
   124
            self.move(ev.px - self.dragstart[0],
2f61931520c9 Rework layouts: Layout is now normal Container which places its children upon resize event.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
   125
                      ev.py - self.dragstart[1])
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   126
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   127
        self.redraw(True)
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   128
2
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   129
41
37b7dfc3eae6 Update Emitter: All event handlers now have exactly one argument: object inherited from Event class, which carries any data.
Radek Brich <radek.brich@devl.cz>
parents: 40
diff changeset
   130
    def on_closebtn_click(self, ev):
2
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   131
        self.hide()
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
   132