pytermgui.widgets.interactive.button

This module contains the Button class.

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

Handle a mouse event

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

Handles a keypress

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

Get object lines