tuikit/tableview.py
author Radek Brich <radek.brich@devl.cz>
Mon, 04 Feb 2013 20:12:09 +0100
changeset 98 dcfb185ac866
parent 77 fc1989059e19
child 99 f3063f08ba81
permissions -rw-r--r--
Fix redraw of overlapping widgets inside AnchorLayout.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     1
# -*- coding: utf-8 -*-
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     2
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     3
import math
22
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
     4
import logging
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     5
43
369c8ef5070a Rename emitter module to events.
Radek Brich <radek.brich@devl.cz>
parents: 41
diff changeset
     6
from tuikit.events import Event, Emitter
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
     7
from tuikit.widget import Widget
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     8
from tuikit.common import Coords
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     9
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    10
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
    11
class TableModel(Emitter):
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    12
    def __init__(self, list_of_lists):
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
    13
        self.add_events('change', Event)
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    14
        self.data = list_of_lists
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
    15
98
dcfb185ac866 Fix redraw of overlapping widgets inside AnchorLayout.
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
    16
    def rowcount(self):
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    17
        '''Get number of rows.'''
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    18
        return len(self.data)
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
    19
98
dcfb185ac866 Fix redraw of overlapping widgets inside AnchorLayout.
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
    20
    def get_rows(self, begin, end):
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    21
        '''Get rows from begin to end, including begin, excluding end.'''
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    22
        return self.data[begin:end]
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
    23
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    24
    def update(self, row, col, val):
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    25
        self.data[row][col] = val
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    26
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    27
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    28
class Column:
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
    29
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    30
    '''Columns description.'''
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
    31
22
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
    32
    def __init__(self, title='', header=False, expand=True, sizereq=1,
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
    33
        readonly=False, maxlength=None):
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    34
        '''Create column with default values.'''
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
    35
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    36
        self.title = title
22
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
    37
        '''Title is displayed in heading before first row.'''
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
    38
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
    39
        self.header = header
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
    40
        '''Header column is highlighted, values in this column cannot be edited.'''
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
    41
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    42
        self.expand = expand
22
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
    43
        '''If true, this column will autoresize to consume any free space.'''
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
    44
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    45
        self.sizereq = sizereq
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    46
        '''Size request. Meaning depends on value of expand:
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
    47
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    48
        When false, sizereq is number of characters.
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    49
        When true, sizereq is relative size ratio.
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
    50
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    51
        '''
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
    52
22
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
    53
        self.size = None
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    54
        '''Computed size of column.'''
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
    55
22
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
    56
        self.index = None
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
    57
        '''Computed index.'''
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
    58
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    59
        self.readonly = readonly
22
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
    60
        '''If not readonly, values in this column can be changed by user.'''
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
    61
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    62
        self.maxlength = maxlength
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    63
        '''Maximum length of value (for EditField).'''
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    64
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    65
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    66
class TableView(Widget):
64
03f591f5fe5c Drop Container.offset, add special layout for that - OffsetLayout.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    67
    def __init__(self, model=None):
03f591f5fe5c Drop Container.offset, add special layout for that - OffsetLayout.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    68
        Widget.__init__(self)
03f591f5fe5c Drop Container.offset, add special layout for that - OffsetLayout.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    69
        self._default_size.update(20, 20)
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
    70
34
e3beacd5e536 Update event propagation, keypress event, focusing.
Radek Brich <radek.brich@devl.cz>
parents: 33
diff changeset
    71
        self.allow_focus = True
e3beacd5e536 Update event propagation, keypress event, focusing.
Radek Brich <radek.brich@devl.cz>
parents: 33
diff changeset
    72
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    73
        # model
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    74
        self._model = None
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    75
        self.setmodel(model)
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
    76
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    77
        self.columns = []
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    78
        self.spacing = 1
22
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
    79
        self.rowcount = 0
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
    80
        self.headsize = 1
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
    81
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    82
        self.offset = Coords()
64
03f591f5fe5c Drop Container.offset, add special layout for that - OffsetLayout.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
    83
        #: Active cell (cursor)
22
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
    84
        self.acell = Coords()
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
    85
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
    86
        self.add_events(
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
    87
            'scroll', Event,
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
    88
            'areasize', Event)
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
    89
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    90
    def getmodel(self):
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    91
        return self._model
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
    92
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    93
    def setmodel(self, value):
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    94
        if self._model:
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: 43
diff changeset
    95
            self._model.remove_handler('change', self.redraw)
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    96
        self._model = value
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    97
        if self._model:
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: 43
diff changeset
    98
            self._model.add_handler('change', self.redraw)
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
    99
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   100
    model = property(getmodel, setmodel)
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
   101
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   102
    def addcolumn(self, *args, **kwargs):
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   103
        for col in args:
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   104
            self.columns.append(col)
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   105
        if len(args) == 0:
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   106
            col = Column(**kwargs)
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   107
            self.columns.append(col)
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
   108
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   109
    def compute_column_sizes(self):
64
03f591f5fe5c Drop Container.offset, add special layout for that - OffsetLayout.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
   110
        total_space = self.width - self.spacing * len(self.columns)
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   111
        no_expand_cols = [col for col in self.columns if not col.expand]
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   112
        no_expand_size = sum([col.sizereq for col in no_expand_cols])
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   113
        expand_cols = [col for col in self.columns if col.expand]
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   114
        expand_num = len(expand_cols)
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   115
        expand_size = total_space - no_expand_size
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
   116
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   117
        # compute size of cols without expand
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   118
        for col in no_expand_cols:
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   119
            col.size = col.sizereq
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
   120
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   121
        # compute size of cols with expand
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   122
        if no_expand_size > total_space + expand_num:
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   123
            for col in expand_cols:
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   124
                col.size = 1
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   125
        else:
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   126
            total_req = sum([col.sizereq for col in expand_cols])
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   127
            remaining_space = 0.
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   128
            for col in expand_cols:
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   129
                frac, intp = math.modf(expand_size * col.sizereq / total_req)
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   130
                col.size = int(intp)
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   131
                remaining_space += frac
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   132
                if remaining_space > 0.99:
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   133
                    remaining_space -= 1.
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   134
                    col.size += 1
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
   135
22
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   136
        # compute indexes
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   137
        idx = 0
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   138
        for col in self.columns:
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   139
            if not col.header:
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   140
                col.index = idx
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   141
                idx += 1
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
   142
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   143
    def draw_head(self, screen, x, y):
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   144
        screen.pushcolor('strong')
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   145
        for col in self.columns:
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   146
            screen.puts(x, y, col.title[:col.size])
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   147
            x += col.size + self.spacing
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   148
        screen.popcolor()
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
   149
22
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   150
    def draw_row(self, screen, x, y, row, highlight):
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   151
        for col, data in zip(self.columns, row):
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   152
            if col.header:
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   153
                screen.pushcolor('strong')
22
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   154
            elif col.index in highlight:
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   155
                screen.pushcolor('active')
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   156
            else:
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   157
                screen.pushcolor('normal')
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   158
            screen.puts(x, y, data[:col.size])
22
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   159
            screen.popcolor()
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   160
            x += col.size + self.spacing
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
   161
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: 43
diff changeset
   162
    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
   163
        ev.driver.pushcolor('normal')
77
fc1989059e19 Propagate "quit" event, do not just terminate application. Resize: flag widgets to be resized, do resizes only once before draw. Draw: flag widgets to be redrawn, do not draw everything on any event.
Radek Brich <radek.brich@devl.cz>
parents: 64
diff changeset
   164
        ev.driver.fill_clip()
98
dcfb185ac866 Fix redraw of overlapping widgets inside AnchorLayout.
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   165
        self.rowcount = self.model.rowcount()
64
03f591f5fe5c Drop Container.offset, add special layout for that - OffsetLayout.
Radek Brich <radek.brich@devl.cz>
parents: 45
diff changeset
   166
        numrows = min(self.rowcount - self.offset.y, self.height - self.headsize)
98
dcfb185ac866 Fix redraw of overlapping widgets inside AnchorLayout.
Radek Brich <radek.brich@devl.cz>
parents: 77
diff changeset
   167
        rows = self.model.get_rows(self.offset.y, self.offset.y + numrows)
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   168
        self.compute_column_sizes()
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
   169
        self.draw_head(ev.driver, ev.x, ev.y)
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
   170
        y = ev.y + self.headsize
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   171
        for row in rows:
22
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   172
            highlight = []
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   173
            if self.offset.y + rows.index(row) == self.acell.y:
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   174
                highlight.append(self.acell.x)
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
   175
            self.draw_row(ev.driver, ev.x, y, row, highlight)
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   176
            y += 1
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
   177
        ev.driver.popcolor()
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   178
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: 43
diff changeset
   179
    def on_keypress(self, ev):
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: 43
diff changeset
   180
        key_map = {
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: 43
diff changeset
   181
            'up': self.move_up,
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: 43
diff changeset
   182
            'down': self.move_down,
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: 43
diff changeset
   183
            'left': self.move_left,
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: 43
diff changeset
   184
            'right': self.move_right,
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: 43
diff changeset
   185
            'pageup':  self.move_pageup,
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: 43
diff changeset
   186
            'pagedown':  self.move_pagedown}
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: 43
diff changeset
   187
        if ev.keyname in key_map:
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: 43
diff changeset
   188
            key_map[ev.keyname]()
77
fc1989059e19 Propagate "quit" event, do not just terminate application. Resize: flag widgets to be resized, do resizes only once before draw. Draw: flag widgets to be redrawn, do not draw everything on any event.
Radek Brich <radek.brich@devl.cz>
parents: 64
diff changeset
   189
            self.redraw()
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: 43
diff changeset
   190
            return True
21
8553a6bd2d82 Add TableView plus demo.
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
   191
22
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   192
    def set_yofs(self, yofs):
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   193
        if yofs > self.rowcount - (self.height - self.headsize):
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   194
            yofs = self.rowcount - (self.height - self.headsize)
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   195
        if yofs < 0:
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   196
            yofs = 0
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   197
        self.offset.y = yofs
34
e3beacd5e536 Update event propagation, keypress event, focusing.
Radek Brich <radek.brich@devl.cz>
parents: 33
diff changeset
   198
        self.emit('scroll')
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
   199
22
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   200
    def move_up(self):
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   201
        if self.acell.y > 0:
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   202
            self.acell.y -= 1
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   203
            if self.acell.y < self.offset.y:
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   204
                self.set_yofs(self.acell.y)
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   205
            return True
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   206
        return False
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 22
diff changeset
   207
22
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   208
    def move_down(self):
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   209
        log=logging.getLogger('tuikit')
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   210
        log.debug('height %d', self.height)
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   211
        if self.acell.y < self.rowcount - 1:
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   212
            self.acell.y += 1
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   213
            if self.acell.y > self.offset.y + (self.height - self.headsize - 1):
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   214
                self.set_yofs(self.acell.y - (self.height - self.headsize - 1))
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   215
            return True
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   216
        return False
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   217
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   218
    def move_pageup(self):
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   219
        if self.acell.y >= self.height - self.headsize - 1:
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   220
            self.acell.y -= self.height - self.headsize - 1
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   221
            self.set_yofs(self.offset.y - (self.height - self.headsize - 1))
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   222
        else:
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   223
            self.acell.y = 0
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   224
            self.set_yofs(0)
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   225
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   226
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   227
    def move_pagedown(self):
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   228
        if self.acell.y <= self.rowcount - (self.height - self.headsize - 1):
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   229
            self.acell.y += self.height - self.headsize - 1
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   230
            self.set_yofs(self.offset.y + (self.height - self.headsize - 1))
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   231
        else:
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   232
            self.acell.y = self.rowcount - 1
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   233
            self.set_yofs(self.acell.y)
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   234
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   235
    def move_left(self):
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   236
        if self.acell.x > 0:
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   237
            self.acell.x -= 1
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   238
            return True
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   239
        return False
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   240
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   241
    def move_right(self):
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   242
        if self.acell.x < len([col for col in self.columns if not col.header]) - 1:
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   243
            self.acell.x += 1
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   244
            return True
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   245
        return False
6ca8b2d221c3 Update TableView: cursor movement.
Radek Brich <radek.brich@devl.cz>
parents: 21
diff changeset
   246