tuikit/widgets/button.py
author Radek Brich <radek.brich@devl.cz>
Wed, 03 Sep 2014 19:08:21 +0200
changeset 109 105b1affc3c2
parent 97 0c2e0c09ba5c
child 118 8c7970520632
permissions -rw-r--r--
Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
89
94f5baef19ac Add Theme, Button.
Radek Brich <radek.brich@devl.cz>
parents: 62
diff changeset
     1
from tuikit.core.widget import Widget
94f5baef19ac Add Theme, Button.
Radek Brich <radek.brich@devl.cz>
parents: 62
diff changeset
     2
from tuikit.core.signal import Signal
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     3
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     4
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
     5
class Button(Widget):
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 30
diff changeset
     6
89
94f5baef19ac Add Theme, Button.
Radek Brich <radek.brich@devl.cz>
parents: 62
diff changeset
     7
    """Clickable button."""
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 30
diff changeset
     8
89
94f5baef19ac Add Theme, Button.
Radek Brich <radek.brich@devl.cz>
parents: 62
diff changeset
     9
    def __init__(self, label='btn'):
94f5baef19ac Add Theme, Button.
Radek Brich <radek.brich@devl.cz>
parents: 62
diff changeset
    10
        """Create button with given label, size according to label."""
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
    11
        Widget.__init__(self)
109
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    12
        self.allow_focus = True
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    13
13
19ebde2fd594 Add more generated documentation.
Radek Brich <radek.brich@devl.cz>
parents: 9
diff changeset
    14
        #: Button label.
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
    15
        self._label = ''
30
05500124d7fb Add setup script. Add Checkbox widget + demo. Updates.
Radek Brich <radek.brich@devl.cz>
parents: 18
diff changeset
    16
        #: Text or graphics to be added before label
05500124d7fb Add setup script. Add Checkbox widget + demo. Updates.
Radek Brich <radek.brich@devl.cz>
parents: 18
diff changeset
    17
        self.prefix = '['
05500124d7fb Add setup script. Add Checkbox widget + demo. Updates.
Radek Brich <radek.brich@devl.cz>
parents: 18
diff changeset
    18
        #: Text or graphics to be added after label
05500124d7fb Add setup script. Add Checkbox widget + demo. Updates.
Radek Brich <radek.brich@devl.cz>
parents: 18
diff changeset
    19
        self.suffix = ']'
05500124d7fb Add setup script. Add Checkbox widget + demo. Updates.
Radek Brich <radek.brich@devl.cz>
parents: 18
diff changeset
    20
        #: How should label be aligned if button has excess space - center | left | right
05500124d7fb Add setup script. Add Checkbox widget + demo. Updates.
Radek Brich <radek.brich@devl.cz>
parents: 18
diff changeset
    21
        self.align = 'center'
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
    22
        #: Padding between prefix/suffix and label
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
    23
        self.padding = 1
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 30
diff changeset
    24
89
94f5baef19ac Add Theme, Button.
Radek Brich <radek.brich@devl.cz>
parents: 62
diff changeset
    25
        self.color = 'default'
109
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    26
        self.color_active = 'default on red'
2
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    27
        self.highlight = False
32
088b92ffb119 Clean up, refactoring. Rename EventSource to Emitter, begin merging emit() method with handle().
Radek Brich <radek.brich@devl.cz>
parents: 30
diff changeset
    28
89
94f5baef19ac Add Theme, Button.
Radek Brich <radek.brich@devl.cz>
parents: 62
diff changeset
    29
        self.sig_clicked = Signal()
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    30
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
    31
        self.label = label
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
    32
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
    @property
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
    34
    def label(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
    35
        """Button label."""
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
    36
        return self._label
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
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
    @label.setter
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
    39
    def label(self, value):
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
    40
        self._label = value
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
    41
        w = len(value) + len(self.prefix) + len(self.suffix) + 2 * self.padding
89
94f5baef19ac Add Theme, Button.
Radek Brich <radek.brich@devl.cz>
parents: 62
diff changeset
    42
        self.sizereq.update(w, 1)
94f5baef19ac Add Theme, Button.
Radek Brich <radek.brich@devl.cz>
parents: 62
diff changeset
    43
94f5baef19ac Add Theme, Button.
Radek Brich <radek.brich@devl.cz>
parents: 62
diff changeset
    44
    def set_theme(self, theme):
97
0c2e0c09ba5c Add TextField widget, keypress event, cursor.
Radek Brich <radek.brich@devl.cz>
parents: 95
diff changeset
    45
        Widget.set_theme(self, theme)
89
94f5baef19ac Add Theme, Button.
Radek Brich <radek.brich@devl.cz>
parents: 62
diff changeset
    46
        self.color = theme.button
109
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    47
        self.color_active = theme.button_active
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    48
89
94f5baef19ac Add Theme, Button.
Radek Brich <radek.brich@devl.cz>
parents: 62
diff changeset
    49
    def _get_color(self):
109
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    50
        if self.has_focus():
105b1affc3c2 Update keypress propagation. Allow focus change by tab key. Add log property to Widget for smart logging.
Radek Brich <radek.brich@devl.cz>
parents: 97
diff changeset
    51
            return self.color_active
89
94f5baef19ac Add Theme, Button.
Radek Brich <radek.brich@devl.cz>
parents: 62
diff changeset
    52
        return self.color
94f5baef19ac Add Theme, Button.
Radek Brich <radek.brich@devl.cz>
parents: 62
diff changeset
    53
94
e50dae408fe9 Add origin to Buffer. Use it to simplify hierarchical drawing.
Radek Brich <radek.brich@devl.cz>
parents: 89
diff changeset
    54
    def draw(self, buffer):
e50dae408fe9 Add origin to Buffer. Use it to simplify hierarchical drawing.
Radek Brich <radek.brich@devl.cz>
parents: 89
diff changeset
    55
        Widget.draw(self, buffer)
30
05500124d7fb Add setup script. Add Checkbox widget + demo. Updates.
Radek Brich <radek.brich@devl.cz>
parents: 18
diff changeset
    56
        pad = self.width - len(self.label) - len(self.prefix) - len(self.suffix)
05500124d7fb Add setup script. Add Checkbox widget + demo. Updates.
Radek Brich <radek.brich@devl.cz>
parents: 18
diff changeset
    57
        lpad, rpad = self._divide_padding(pad)
89
94f5baef19ac Add Theme, Button.
Radek Brich <radek.brich@devl.cz>
parents: 62
diff changeset
    58
        with buffer.attr(self._get_color()):
94f5baef19ac Add Theme, Button.
Radek Brich <radek.brich@devl.cz>
parents: 62
diff changeset
    59
            # prefix
95
05392e369ede Refactoring: Swap drawing operations parameters. Coords are now last and have default values.
Radek Brich <radek.brich@devl.cz>
parents: 94
diff changeset
    60
            buffer.puts(self.prefix)
89
94f5baef19ac Add Theme, Button.
Radek Brich <radek.brich@devl.cz>
parents: 62
diff changeset
    61
            pos = len(self.prefix)
94f5baef19ac Add Theme, Button.
Radek Brich <radek.brich@devl.cz>
parents: 62
diff changeset
    62
            # left pad
95
05392e369ede Refactoring: Swap drawing operations parameters. Coords are now last and have default values.
Radek Brich <radek.brich@devl.cz>
parents: 94
diff changeset
    63
            buffer.puts(' ' * lpad, pos)
89
94f5baef19ac Add Theme, Button.
Radek Brich <radek.brich@devl.cz>
parents: 62
diff changeset
    64
            pos += lpad
94f5baef19ac Add Theme, Button.
Radek Brich <radek.brich@devl.cz>
parents: 62
diff changeset
    65
            # label
95
05392e369ede Refactoring: Swap drawing operations parameters. Coords are now last and have default values.
Radek Brich <radek.brich@devl.cz>
parents: 94
diff changeset
    66
            buffer.puts(self.label, pos)
89
94f5baef19ac Add Theme, Button.
Radek Brich <radek.brich@devl.cz>
parents: 62
diff changeset
    67
            pos += len(self.label)
94f5baef19ac Add Theme, Button.
Radek Brich <radek.brich@devl.cz>
parents: 62
diff changeset
    68
            # right pad
95
05392e369ede Refactoring: Swap drawing operations parameters. Coords are now last and have default values.
Radek Brich <radek.brich@devl.cz>
parents: 94
diff changeset
    69
            buffer.puts(' ' * rpad, pos)
89
94f5baef19ac Add Theme, Button.
Radek Brich <radek.brich@devl.cz>
parents: 62
diff changeset
    70
            pos += rpad
94f5baef19ac Add Theme, Button.
Radek Brich <radek.brich@devl.cz>
parents: 62
diff changeset
    71
            # suffix
95
05392e369ede Refactoring: Swap drawing operations parameters. Coords are now last and have default values.
Radek Brich <radek.brich@devl.cz>
parents: 94
diff changeset
    72
            buffer.puts(self.suffix, pos)
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    73
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
    74
    def on_mousedown(self, ev):
2
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    75
        self.highlight = True
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    76
        self.redraw()
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    77
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
    78
    def on_mouseup(self, ev):
2
684cdc352562 Menu, Window and other improvements.
Radek Brich <radek.brich@devl.cz>
parents: 0
diff changeset
    79
        self.highlight = False
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    80
        self.redraw()
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    81
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    82
        if self.enclose(ev.px, ev.py):
34
e3beacd5e536 Update event propagation, keypress event, focusing.
Radek Brich <radek.brich@devl.cz>
parents: 32
diff changeset
    83
            self.emit('click')
0
Radek Brich <radek.brich@devl.cz>
parents:
diff changeset
    84
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
    85
    def on_keypress(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
    86
        if ev.keyname == 'enter':
34
e3beacd5e536 Update event propagation, keypress event, focusing.
Radek Brich <radek.brich@devl.cz>
parents: 32
diff changeset
    87
            self.emit('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
    88
30
05500124d7fb Add setup script. Add Checkbox widget + demo. Updates.
Radek Brich <radek.brich@devl.cz>
parents: 18
diff changeset
    89
    def _divide_padding(self, pad):
05500124d7fb Add setup script. Add Checkbox widget + demo. Updates.
Radek Brich <radek.brich@devl.cz>
parents: 18
diff changeset
    90
        # default is 'left'
05500124d7fb Add setup script. Add Checkbox widget + demo. Updates.
Radek Brich <radek.brich@devl.cz>
parents: 18
diff changeset
    91
        lpad, rpad = 0, pad
05500124d7fb Add setup script. Add Checkbox widget + demo. Updates.
Radek Brich <radek.brich@devl.cz>
parents: 18
diff changeset
    92
        if self.align == 'center':
05500124d7fb Add setup script. Add Checkbox widget + demo. Updates.
Radek Brich <radek.brich@devl.cz>
parents: 18
diff changeset
    93
            lpad = pad // 2
05500124d7fb Add setup script. Add Checkbox widget + demo. Updates.
Radek Brich <radek.brich@devl.cz>
parents: 18
diff changeset
    94
            rpad = pad - lpad
05500124d7fb Add setup script. Add Checkbox widget + demo. Updates.
Radek Brich <radek.brich@devl.cz>
parents: 18
diff changeset
    95
        elif self.align == 'right':
05500124d7fb Add setup script. Add Checkbox widget + demo. Updates.
Radek Brich <radek.brich@devl.cz>
parents: 18
diff changeset
    96
            lpad, rpad = pad, 0
05500124d7fb Add setup script. Add Checkbox widget + demo. Updates.
Radek Brich <radek.brich@devl.cz>
parents: 18
diff changeset
    97
        return lpad, rpad
05500124d7fb Add setup script. Add Checkbox widget + demo. Updates.
Radek Brich <radek.brich@devl.cz>
parents: 18
diff changeset
    98