Skip to content

button

This module contains the Button class.

Button

Bases: Widget

A simple Widget representing a mouse-clickable button

Source code in pytermgui/widgets/button.py
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
class Button(Widget):
    """A simple Widget representing a mouse-clickable button"""

    styles = w_styles.StyleManager(
        label="@surface dim #auto",
        highlight="@surface+1 dim #auto",
        _current=None,
    )

    chars: dict[str, w_styles.CharType] = {"delimiter": ["[ ", " ]"]}

    def __init__(
        self,
        label: str = "Button",
        onclick: Optional[Callable[[Button], Any]] = None,
        padding: int = 0,
        centered: bool = False,
        **attrs: Any,
    ) -> None:
        """Initialize object"""

        super().__init__(**attrs)
        self._selectables_length = 1

        if not any("width" in attr for attr in attrs):
            self.width = len(label)

        self.label = label
        self.onclick = onclick
        self.padding = padding
        self.centered = centered

        self.styles["_current"] = self.styles.label

    def on_hover(self, _) -> bool:
        """Sets highlight style when hovering."""

        self.styles["_current"] = self.styles.highlight
        return False

    def on_release(self, _) -> bool:
        """Sets normal style when no longer hovering."""

        self.styles["_current"] = self.styles.label
        return False

    def handle_mouse(self, event: MouseEvent) -> bool:
        """Handles a mouse event"""

        if super().handle_mouse(event):
            return True

        if event.action == MouseAction.LEFT_CLICK:
            self.selected_index = 0
            if self.onclick is not None:
                self.onclick(self)

            return True

        if event.action == MouseAction.RELEASE:
            self.selected_index = None
            return True

        return False

    def handle_key(self, key: str) -> bool:
        """Handles a keypress"""

        if key == keys.RETURN and self.onclick is not None:
            self.onclick(self)
            return True

        return False

    def get_lines(self) -> list[str]:
        """Get object lines"""

        delimiters = self._get_char("delimiter")
        assert isinstance(delimiters, list) and len(delimiters) == 2

        left, right = delimiters
        left = left.replace("[", r"\[")
        delim_len = real_length(left + right)

        label = self.label
        if len(self.label) > self.width:
            sli = max(self.width - delim_len - 3 - self.padding, 0)
            label = self.label[:sli] + "..."

        elif self.centered:
            label = self.label.center(self.width)

        if self.selected_index is None:
            style = self.styles["_current"]
        else:
            style = self.styles.highlight

        line = style(left + label + right + self.padding * " ")

        return [line]

__init__(label='Button', onclick=None, padding=0, centered=False, attrs)

Initialize object

Source code in pytermgui/widgets/button.py
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
def __init__(
    self,
    label: str = "Button",
    onclick: Optional[Callable[[Button], Any]] = None,
    padding: int = 0,
    centered: bool = False,
    **attrs: Any,
) -> None:
    """Initialize object"""

    super().__init__(**attrs)
    self._selectables_length = 1

    if not any("width" in attr for attr in attrs):
        self.width = len(label)

    self.label = label
    self.onclick = onclick
    self.padding = padding
    self.centered = centered

    self.styles["_current"] = self.styles.label

get_lines()

Get object lines

Source code in pytermgui/widgets/button.py
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
def get_lines(self) -> list[str]:
    """Get object lines"""

    delimiters = self._get_char("delimiter")
    assert isinstance(delimiters, list) and len(delimiters) == 2

    left, right = delimiters
    left = left.replace("[", r"\[")
    delim_len = real_length(left + right)

    label = self.label
    if len(self.label) > self.width:
        sli = max(self.width - delim_len - 3 - self.padding, 0)
        label = self.label[:sli] + "..."

    elif self.centered:
        label = self.label.center(self.width)

    if self.selected_index is None:
        style = self.styles["_current"]
    else:
        style = self.styles.highlight

    line = style(left + label + right + self.padding * " ")

    return [line]

handle_key(key)

Handles a keypress

Source code in pytermgui/widgets/button.py
80
81
82
83
84
85
86
87
def handle_key(self, key: str) -> bool:
    """Handles a keypress"""

    if key == keys.RETURN and self.onclick is not None:
        self.onclick(self)
        return True

    return False

handle_mouse(event)

Handles a mouse event

Source code in pytermgui/widgets/button.py
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
def handle_mouse(self, event: MouseEvent) -> bool:
    """Handles a mouse event"""

    if super().handle_mouse(event):
        return True

    if event.action == MouseAction.LEFT_CLICK:
        self.selected_index = 0
        if self.onclick is not None:
            self.onclick(self)

        return True

    if event.action == MouseAction.RELEASE:
        self.selected_index = None
        return True

    return False

on_hover(_)

Sets highlight style when hovering.

Source code in pytermgui/widgets/button.py
49
50
51
52
53
def on_hover(self, _) -> bool:
    """Sets highlight style when hovering."""

    self.styles["_current"] = self.styles.highlight
    return False

on_release(_)

Sets normal style when no longer hovering.

Source code in pytermgui/widgets/button.py
55
56
57
58
59
def on_release(self, _) -> bool:
    """Sets normal style when no longer hovering."""

    self.styles["_current"] = self.styles.label
    return False