pytermgui.widgets.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 ..input import keys 10from ..regex import real_length 11from . import styles as w_styles 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 _current=None, 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 self.styles["_current"] = self.styles.label 48 49 def on_hover(self, _) -> bool: 50 """Sets highlight style when hovering.""" 51 52 self.styles["_current"] = self.styles.highlight 53 return False 54 55 def on_release(self, _) -> bool: 56 """Sets normal style when no longer hovering.""" 57 58 self.styles["_current"] = self.styles.label 59 return False 60 61 def handle_mouse(self, event: MouseEvent) -> bool: 62 """Handles a mouse event""" 63 64 if super().handle_mouse(event): 65 return True 66 67 if event.action == MouseAction.LEFT_CLICK: 68 self.selected_index = 0 69 if self.onclick is not None: 70 self.onclick(self) 71 72 return True 73 74 if event.action == MouseAction.RELEASE: 75 self.selected_index = None 76 return True 77 78 return False 79 80 def handle_key(self, key: str) -> bool: 81 """Handles a keypress""" 82 83 if key == keys.RETURN and self.onclick is not None: 84 self.onclick(self) 85 return True 86 87 return False 88 89 def get_lines(self) -> list[str]: 90 """Get object lines""" 91 92 delimiters = self._get_char("delimiter") 93 assert isinstance(delimiters, list) and len(delimiters) == 2 94 95 left, right = delimiters 96 left = left.replace("[", r"\[") 97 delim_len = real_length(left + right) 98 99 label = self.label 100 if len(self.label) > self.width: 101 sli = max(self.width - delim_len - 3 - self.padding, 0) 102 label = self.label[:sli] + "..." 103 104 elif self.centered: 105 label = self.label.center(self.width) 106 107 if self.selected_index is None: 108 style = self.styles["_current"] 109 else: 110 style = self.styles.highlight 111 112 line = style(left + label + right + self.padding * " ") 113 114 return [line]
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 _current=None, 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 self.styles["_current"] = self.styles.label 49 50 def on_hover(self, _) -> bool: 51 """Sets highlight style when hovering.""" 52 53 self.styles["_current"] = self.styles.highlight 54 return False 55 56 def on_release(self, _) -> bool: 57 """Sets normal style when no longer hovering.""" 58 59 self.styles["_current"] = self.styles.label 60 return False 61 62 def handle_mouse(self, event: MouseEvent) -> bool: 63 """Handles a mouse event""" 64 65 if super().handle_mouse(event): 66 return True 67 68 if event.action == MouseAction.LEFT_CLICK: 69 self.selected_index = 0 70 if self.onclick is not None: 71 self.onclick(self) 72 73 return True 74 75 if event.action == MouseAction.RELEASE: 76 self.selected_index = None 77 return True 78 79 return False 80 81 def handle_key(self, key: str) -> bool: 82 """Handles a keypress""" 83 84 if key == keys.RETURN and self.onclick is not None: 85 self.onclick(self) 86 return True 87 88 return False 89 90 def get_lines(self) -> list[str]: 91 """Get object lines""" 92 93 delimiters = self._get_char("delimiter") 94 assert isinstance(delimiters, list) and len(delimiters) == 2 95 96 left, right = delimiters 97 left = left.replace("[", r"\[") 98 delim_len = real_length(left + right) 99 100 label = self.label 101 if len(self.label) > self.width: 102 sli = max(self.width - delim_len - 3 - self.padding, 0) 103 label = self.label[:sli] + "..." 104 105 elif self.centered: 106 label = self.label.center(self.width) 107 108 if self.selected_index is None: 109 style = self.styles["_current"] 110 else: 111 style = self.styles.highlight 112 113 line = style(left + label + right + self.padding * " ") 114 115 return [line]
A simple Widget representing a mouse-clickable button
Button( label: str = 'Button', onclick: Optional[Callable[[pytermgui.widgets.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 47 48 self.styles["_current"] = self.styles.label
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={})), '_current': StyleCall(obj=None, method=None)}
Default styles for this class
chars: dict[str, typing.Union[typing.List[str], str]] = {'delimiter': ['[ ', ' ]']}
Default characters for this class
def
on_hover(self, _) -> bool:
50 def on_hover(self, _) -> bool: 51 """Sets highlight style when hovering.""" 52 53 self.styles["_current"] = self.styles.highlight 54 return False
Sets highlight style when hovering.
def
on_release(self, _) -> bool:
56 def on_release(self, _) -> bool: 57 """Sets normal style when no longer hovering.""" 58 59 self.styles["_current"] = self.styles.label 60 return False
Sets normal style when no longer hovering.
62 def handle_mouse(self, event: MouseEvent) -> bool: 63 """Handles a mouse event""" 64 65 if super().handle_mouse(event): 66 return True 67 68 if event.action == MouseAction.LEFT_CLICK: 69 self.selected_index = 0 70 if self.onclick is not None: 71 self.onclick(self) 72 73 return True 74 75 if event.action == MouseAction.RELEASE: 76 self.selected_index = None 77 return True 78 79 return False
Handles a mouse event
def
handle_key(self, key: str) -> bool:
81 def handle_key(self, key: str) -> bool: 82 """Handles a keypress""" 83 84 if key == keys.RETURN and self.onclick is not None: 85 self.onclick(self) 86 return True 87 88 return False
Handles a keypress
def
get_lines(self) -> list[str]:
90 def get_lines(self) -> list[str]: 91 """Get object lines""" 92 93 delimiters = self._get_char("delimiter") 94 assert isinstance(delimiters, list) and len(delimiters) == 2 95 96 left, right = delimiters 97 left = left.replace("[", r"\[") 98 delim_len = real_length(left + right) 99 100 label = self.label 101 if len(self.label) > self.width: 102 sli = max(self.width - delim_len - 3 - self.padding, 0) 103 label = self.label[:sli] + "..." 104 105 elif self.centered: 106 label = self.label.center(self.width) 107 108 if self.selected_index is None: 109 style = self.styles["_current"] 110 else: 111 style = self.styles.highlight 112 113 line = style(left + label + right + self.padding * " ") 114 115 return [line]
Get object lines