diff --git a/CHANGELOG.md b/CHANGELOG.md index f1d794a8d7..45262df670 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## Unreleased + +### Added + +- Added `tooltip` to Binding https://github.com/Textualize/textual/pull/4859 + ## [0.76.0] ### Changed diff --git a/src/textual/binding.py b/src/textual/binding.py index 9a396478a4..3b0825d8a2 100644 --- a/src/textual/binding.py +++ b/src/textual/binding.py @@ -50,6 +50,8 @@ class Binding: """How the key should be shown in footer.""" priority: bool = False """Enable priority binding for this key.""" + tooltip: str = "" + """Optional tooltip to show in footer.""" class ActiveBinding(NamedTuple): @@ -61,6 +63,8 @@ class ActiveBinding(NamedTuple): """The binding information.""" enabled: bool """Is the binding enabled? (enabled bindings are typically rendered dim)""" + tooltip: str = "" + """Optional tooltip shown in Footer.""" @rich.repr.auto @@ -112,6 +116,7 @@ def make_bindings(bindings: Iterable[BindingType]) -> Iterable[Binding]: show=bool(binding.description and binding.show), key_display=binding.key_display, priority=binding.priority, + tooltip=binding.tooltip, ) self.key_to_bindings: dict[str, list[Binding]] = {} diff --git a/src/textual/screen.py b/src/textual/screen.py index f03bbca593..0519ee585d 100644 --- a/src/textual/screen.py +++ b/src/textual/screen.py @@ -348,10 +348,14 @@ def active_bindings(self) -> dict[str, ActiveBinding]: binding.priority and not existing_key_and_binding.binding.priority ): - bindings_map[key] = ActiveBinding(namespace, binding, enabled) + bindings_map[key] = ActiveBinding( + namespace, binding, enabled, binding.tooltip + ) else: # New binding - bindings_map[key] = ActiveBinding(namespace, binding, enabled) + bindings_map[key] = ActiveBinding( + namespace, binding, enabled, binding.tooltip + ) return bindings_map diff --git a/src/textual/widgets/_classic_footer.py b/src/textual/widgets/_classic_footer.py index d8df547300..5b1b5cffae 100644 --- a/src/textual/widgets/_classic_footer.py +++ b/src/textual/widgets/_classic_footer.py @@ -108,15 +108,15 @@ def _make_key_text(self) -> Text: description_style = self.get_component_rich_style("footer--description") bindings = [ - (binding, enabled) - for (_, binding, enabled) in self.screen.active_bindings.values() + (binding, enabled, tooltip) + for (_, binding, enabled, tooltip) in self.screen.active_bindings.values() if binding.show ] action_to_bindings: defaultdict[str, list[tuple[Binding, bool]]] = defaultdict( list ) - for binding, enabled in bindings: + for binding, enabled, _ in bindings: action_to_bindings[binding.action].append((binding, enabled)) app_focus = self.app.app_focus diff --git a/src/textual/widgets/_footer.py b/src/textual/widgets/_footer.py index 0cd93ece70..04ac4abbc3 100644 --- a/src/textual/widgets/_footer.py +++ b/src/textual/widgets/_footer.py @@ -84,6 +84,7 @@ def __init__( description: str, action: str, disabled: bool = False, + tooltip: str = "", ) -> None: self.key = key self.key_display = key_display @@ -91,6 +92,8 @@ def __init__( self.action = action self._disabled = disabled super().__init__(classes="-disabled" if disabled else "") + if tooltip: + self.tooltip = tooltip def render(self) -> Text: key_style = self.get_component_rich_style("footer-key--key") @@ -160,24 +163,25 @@ def compose(self) -> ComposeResult: if not self._bindings_ready: return bindings = [ - (binding, enabled) - for (_, binding, enabled) in self.screen.active_bindings.values() + (binding, enabled, tooltip) + for (_, binding, enabled, tooltip) in self.screen.active_bindings.values() if binding.show ] - action_to_bindings: defaultdict[str, list[tuple[Binding, bool]]] + action_to_bindings: defaultdict[str, list[tuple[Binding, bool, str]]] action_to_bindings = defaultdict(list) - for binding, enabled in bindings: - action_to_bindings[binding.action].append((binding, enabled)) + for binding, enabled, tooltip in bindings: + action_to_bindings[binding.action].append((binding, enabled, tooltip)) self.styles.grid_size_columns = len(action_to_bindings) for multi_bindings in action_to_bindings.values(): - binding, enabled = multi_bindings[0] + binding, enabled, tooltip = multi_bindings[0] yield FooterKey( binding.key, binding.key_display or self.app.get_key_display(binding.key), binding.description, binding.action, disabled=not enabled, + tooltip=tooltip, ).data_bind( Footer.upper_case_keys, Footer.ctrl_to_caret,