pytermgui.widgets.interactive.button

This module contains the Button class.

View Source
 0"""This module contains the `Button` class."""
 1
 2
 3from __future__ import annotations
 4
 5from typing import Any, Callable, Optional
 6
 7from ...ansi_interface import MouseAction, MouseEvent
 8from .. import styles as w_styles
 9from ...regex import real_length
10from ...parser import StyledText
11from ...input import keys
12from ..base import Widget
13
14
15class Button(Widget):
16    """A simple Widget representing a mouse-clickable button"""
17
18    styles = w_styles.StyleManager(
19        label=w_styles.CLICKABLE,
20        highlight=w_styles.CLICKED,
21    )
22
23    chars: dict[str, w_styles.CharType] = {"delimiter": ["[ ", " ]"]}
24
25    def __init__(
26        self,
27        label: str = "Button",
28        onclick: Optional[Callable[[Button], Any]] = None,
29        padding: int = 0,
30        centered: bool = False,
31        **attrs: Any,
32    ) -> None:
33        """Initialize object"""
34
35        super().__init__(**attrs)
36        self._selectables_length = 1
37
38        if not any("width" in attr for attr in attrs):
39            self.width = len(label)
40
41        self.label = label
42        self.onclick = onclick
43        self.padding = padding
44        self.centered = centered
45
46    def handle_mouse(self, event: MouseEvent) -> bool:
47        """Handle a mouse event"""
48
49        if event.action == MouseAction.LEFT_CLICK:
50            self.selected_index = 0
51            if self.onclick is not None:
52                self.onclick(self)
53
54            return True
55
56        if event.action == MouseAction.RELEASE:
57            self.selected_index = None
58            return True
59
60        return super().handle_mouse(event)
61
62    def handle_key(self, key: str) -> bool:
63        """Handles a keypress"""
64
65        if key == keys.RETURN and self.onclick is not None:
66            self.onclick(self)
67            return True
68
69        return False
70
71    def get_lines(self) -> list[str]:
72        """Get object lines"""
73
74        delimiters = self._get_char("delimiter")
75        assert isinstance(delimiters, list) and len(delimiters) == 2
76
77        left, right = delimiters
78        left = left.replace("[", r"\[")
79        delim_len = real_length(left + right)
80
81        label = self.label
82        if len(self.label) > self.width:
83            sli = max(self.width - delim_len - 3 - self.padding, 0)
84            label = self.label[:sli] + "..."
85
86        elif self.centered:
87            label = self.label.center(self.width)
88
89        if self.selected_index is None:
90            style = self.styles.label
91        else:
92            style = self.styles.highlight
93
94        line = StyledText(style(left + label + right + self.padding * " "))
95
96        return [line]
View Source
16class Button(Widget):
17    """A simple Widget representing a mouse-clickable button"""
18
19    styles = w_styles.StyleManager(
20        label=w_styles.CLICKABLE,
21        highlight=w_styles.CLICKED,
22    )
23
24    chars: dict[str, w_styles.CharType] = {"delimiter": ["[ ", " ]"]}
25
26    def __init__(
27        self,
28        label: str = "Button",
29        onclick: Optional[Callable[[Button], Any]] = None,
30        padding: int = 0,
31        centered: bool = False,
32        **attrs: Any,
33    ) -> None:
34        """Initialize object"""
35
36        super().__init__(**attrs)
37        self._selectables_length = 1
38
39        if not any("width" in attr for attr in attrs):
40            self.width = len(label)
41
42        self.label = label
43        self.onclick = onclick
44        self.padding = padding
45        self.centered = centered
46
47    def handle_mouse(self, event: MouseEvent) -> bool:
48        """Handle a mouse event"""
49
50        if event.action == MouseAction.LEFT_CLICK:
51            self.selected_index = 0
52            if self.onclick is not None:
53                self.onclick(self)
54
55            return True
56
57        if event.action == MouseAction.RELEASE:
58            self.selected_index = None
59            return True
60
61        return super().handle_mouse(event)
62
63    def handle_key(self, key: str) -> bool:
64        """Handles a keypress"""
65
66        if key == keys.RETURN and self.onclick is not None:
67            self.onclick(self)
68            return True
69
70        return False
71
72    def get_lines(self) -> list[str]:
73        """Get object lines"""
74
75        delimiters = self._get_char("delimiter")
76        assert isinstance(delimiters, list) and len(delimiters) == 2
77
78        left, right = delimiters
79        left = left.replace("[", r"\[")
80        delim_len = real_length(left + right)
81
82        label = self.label
83        if len(self.label) > self.width:
84            sli = max(self.width - delim_len - 3 - self.padding, 0)
85            label = self.label[:sli] + "..."
86
87        elif self.centered:
88            label = self.label.center(self.width)
89
90        if self.selected_index is None:
91            style = self.styles.label
92        else:
93            style = self.styles.highlight
94
95        line = StyledText(style(left + label + right + self.padding * " "))
96
97        return [line]

A simple Widget representing a mouse-clickable button

#   Button( label: str = 'Button', onclick: Optional[Callable[[pytermgui.widgets.interactive.button.Button], Any]] = None, padding: int = 0, centered: bool = False, **attrs: Any )
View Source
26    def __init__(
27        self,
28        label: str = "Button",
29        onclick: Optional[Callable[[Button], Any]] = None,
30        padding: int = 0,
31        centered: bool = False,
32        **attrs: Any,
33    ) -> None:
34        """Initialize object"""
35
36        super().__init__(**attrs)
37        self._selectables_length = 1
38
39        if not any("width" in attr for attr in attrs):
40            self.width = len(label)
41
42        self.label = label
43        self.onclick = onclick
44        self.padding = padding
45        self.centered = centered

Initialize object

#   styles = {'label': StyleCall(obj=None, method=MarkupFormatter(markup='[@238 72 bold]{item}', ensure_strip=False, _markup_cache={})), 'highlight': StyleCall(obj=None, method=MarkupFormatter(markup='[238 @72 bold]{item}', ensure_strip=False, _markup_cache={}))}

Default styles for this class

#   chars: dict[str, typing.Union[typing.List[str], str]] = {'delimiter': ['[ ', ' ]']}

Default characters for this class

#   def handle_mouse(self, event: pytermgui.ansi_interface.MouseEvent) -> bool:
View Source
47    def handle_mouse(self, event: MouseEvent) -> bool:
48        """Handle a mouse event"""
49
50        if event.action == MouseAction.LEFT_CLICK:
51            self.selected_index = 0
52            if self.onclick is not None:
53                self.onclick(self)
54
55            return True
56
57        if event.action == MouseAction.RELEASE:
58            self.selected_index = None
59            return True
60
61        return super().handle_mouse(event)

Handle a mouse event

#   def handle_key(self, key: str) -> bool:
View Source
63    def handle_key(self, key: str) -> bool:
64        """Handles a keypress"""
65
66        if key == keys.RETURN and self.onclick is not None:
67            self.onclick(self)
68            return True
69
70        return False

Handles a keypress

#   def get_lines(self) -> list[str]:
View Source
72    def get_lines(self) -> list[str]:
73        """Get object lines"""
74
75        delimiters = self._get_char("delimiter")
76        assert isinstance(delimiters, list) and len(delimiters) == 2
77
78        left, right = delimiters
79        left = left.replace("[", r"\[")
80        delim_len = real_length(left + right)
81
82        label = self.label
83        if len(self.label) > self.width:
84            sli = max(self.width - delim_len - 3 - self.padding, 0)
85            label = self.label[:sli] + "..."
86
87        elif self.centered:
88            label = self.label.center(self.width)
89
90        if self.selected_index is None:
91            style = self.styles.label
92        else:
93            style = self.styles.highlight
94
95        line = StyledText(style(left + label + right + self.padding * " "))
96
97        return [line]

Get object lines