Skip to content

Commit

Permalink
Merge pull request #4543 from Textualize/multi-keys
Browse files Browse the repository at this point in the history
fix multi keys
  • Loading branch information
willmcgugan authored May 22, 2024
2 parents c3e0010 + f179f10 commit d15cfa0
Show file tree
Hide file tree
Showing 5 changed files with 191 additions and 1 deletion.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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/).

## [0.63.1] - 2024-05-22

### Fixed

- Fixed display of multiple bindings https://github.com/Textualize/textual/pull/4543

## [0.63.0] - 2024-05-22

### Fixed
Expand Down
12 changes: 11 additions & 1 deletion src/textual/widgets/_footer.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
from __future__ import annotations

from collections import defaultdict

import rich.repr
from rich.text import Text

from ..app import ComposeResult
from ..binding import Binding
from ..containers import ScrollableContainer
from ..reactive import reactive
from ..widget import Widget
Expand Down Expand Up @@ -132,8 +135,15 @@ def compose(self) -> ComposeResult:
for (_, binding, enabled) in self.screen.active_bindings.values()
if binding.show
]
self.styles.grid_size_columns = len(bindings)
action_to_bindings: defaultdict[str, list[tuple[Binding, bool]]] = defaultdict(
list
)
for binding, enabled in bindings:
action_to_bindings[binding.action].append((binding, enabled))

self.styles.grid_size_columns = len(bindings)
for multi_bindings in action_to_bindings.values():
binding, enabled = multi_bindings[0]
yield FooterKey(
binding.key,
binding.key_display or self.app.get_key_display(binding.key),
Expand Down
158 changes: 158 additions & 0 deletions tests/snapshot_tests/__snapshots__/test_snapshots.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -27047,6 +27047,164 @@

'''
# ---
# name: test_multi_keys
'''
<svg class="rich-terminal" viewBox="0 0 994 635.5999999999999" xmlns="http://www.w3.org/2000/svg">
<!-- Generated with Rich https://www.textualize.io -->
<style>

@font-face {
font-family: "Fira Code";
src: local("FiraCode-Regular"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Regular.woff2") format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Regular.woff") format("woff");
font-style: normal;
font-weight: 400;
}
@font-face {
font-family: "Fira Code";
src: local("FiraCode-Bold"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff2/FiraCode-Bold.woff2") format("woff2"),
url("https://cdnjs.cloudflare.com/ajax/libs/firacode/6.2.0/woff/FiraCode-Bold.woff") format("woff");
font-style: bold;
font-weight: 700;
}

.terminal-1053129485-matrix {
font-family: Fira Code, monospace;
font-size: 20px;
line-height: 24.4px;
font-variant-east-asian: full-width;
}

.terminal-1053129485-title {
font-size: 18px;
font-weight: bold;
font-family: arial;
}

.terminal-1053129485-r1 { fill: #e1e1e1 }
.terminal-1053129485-r2 { fill: #c5c8c6 }
.terminal-1053129485-r3 { fill: #fea62b;font-weight: bold }
.terminal-1053129485-r4 { fill: #a7a9ab }
.terminal-1053129485-r5 { fill: #e2e3e3 }
</style>

<defs>
<clipPath id="terminal-1053129485-clip-terminal">
<rect x="0" y="0" width="975.0" height="584.5999999999999" />
</clipPath>
<clipPath id="terminal-1053129485-line-0">
<rect x="0" y="1.5" width="976" height="24.65"/>
</clipPath>
<clipPath id="terminal-1053129485-line-1">
<rect x="0" y="25.9" width="976" height="24.65"/>
</clipPath>
<clipPath id="terminal-1053129485-line-2">
<rect x="0" y="50.3" width="976" height="24.65"/>
</clipPath>
<clipPath id="terminal-1053129485-line-3">
<rect x="0" y="74.7" width="976" height="24.65"/>
</clipPath>
<clipPath id="terminal-1053129485-line-4">
<rect x="0" y="99.1" width="976" height="24.65"/>
</clipPath>
<clipPath id="terminal-1053129485-line-5">
<rect x="0" y="123.5" width="976" height="24.65"/>
</clipPath>
<clipPath id="terminal-1053129485-line-6">
<rect x="0" y="147.9" width="976" height="24.65"/>
</clipPath>
<clipPath id="terminal-1053129485-line-7">
<rect x="0" y="172.3" width="976" height="24.65"/>
</clipPath>
<clipPath id="terminal-1053129485-line-8">
<rect x="0" y="196.7" width="976" height="24.65"/>
</clipPath>
<clipPath id="terminal-1053129485-line-9">
<rect x="0" y="221.1" width="976" height="24.65"/>
</clipPath>
<clipPath id="terminal-1053129485-line-10">
<rect x="0" y="245.5" width="976" height="24.65"/>
</clipPath>
<clipPath id="terminal-1053129485-line-11">
<rect x="0" y="269.9" width="976" height="24.65"/>
</clipPath>
<clipPath id="terminal-1053129485-line-12">
<rect x="0" y="294.3" width="976" height="24.65"/>
</clipPath>
<clipPath id="terminal-1053129485-line-13">
<rect x="0" y="318.7" width="976" height="24.65"/>
</clipPath>
<clipPath id="terminal-1053129485-line-14">
<rect x="0" y="343.1" width="976" height="24.65"/>
</clipPath>
<clipPath id="terminal-1053129485-line-15">
<rect x="0" y="367.5" width="976" height="24.65"/>
</clipPath>
<clipPath id="terminal-1053129485-line-16">
<rect x="0" y="391.9" width="976" height="24.65"/>
</clipPath>
<clipPath id="terminal-1053129485-line-17">
<rect x="0" y="416.3" width="976" height="24.65"/>
</clipPath>
<clipPath id="terminal-1053129485-line-18">
<rect x="0" y="440.7" width="976" height="24.65"/>
</clipPath>
<clipPath id="terminal-1053129485-line-19">
<rect x="0" y="465.1" width="976" height="24.65"/>
</clipPath>
<clipPath id="terminal-1053129485-line-20">
<rect x="0" y="489.5" width="976" height="24.65"/>
</clipPath>
<clipPath id="terminal-1053129485-line-21">
<rect x="0" y="513.9" width="976" height="24.65"/>
</clipPath>
<clipPath id="terminal-1053129485-line-22">
<rect x="0" y="538.3" width="976" height="24.65"/>
</clipPath>
</defs>

<rect fill="#292929" stroke="rgba(255,255,255,0.35)" stroke-width="1" x="1" y="1" width="992" height="633.6" rx="8"/><text class="terminal-1053129485-title" fill="#c5c8c6" text-anchor="middle" x="496" y="27">MApp</text>
<g transform="translate(26,22)">
<circle cx="0" cy="0" r="7" fill="#ff5f57"/>
<circle cx="22" cy="0" r="7" fill="#febc2e"/>
<circle cx="44" cy="0" r="7" fill="#28c840"/>
</g>

<g transform="translate(9, 41)" clip-path="url(#terminal-1053129485-clip-terminal)">
<rect fill="#1e1e1e" x="0" y="1.5" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="25.9" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="50.3" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="74.7" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="99.1" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="123.5" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="147.9" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="172.3" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="196.7" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="221.1" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="245.5" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="269.9" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="294.3" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="318.7" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="343.1" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="367.5" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="391.9" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="416.3" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="440.7" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="465.1" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="489.5" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="513.9" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#1e1e1e" x="0" y="538.3" width="976" height="24.65" shape-rendering="crispEdges"/><rect fill="#24292f" x="0" y="562.7" width="36.6" height="24.65" shape-rendering="crispEdges"/><rect fill="#24292f" x="36.6" y="562.7" width="85.4" height="24.65" shape-rendering="crispEdges"/><rect fill="#24292f" x="122" y="562.7" width="12.2" height="24.65" shape-rendering="crispEdges"/><rect fill="#24292f" x="134.2" y="562.7" width="841.8" height="24.65" shape-rendering="crispEdges"/>
<g class="terminal-1053129485-matrix">
<text class="terminal-1053129485-r2" x="976" y="20" textLength="12.2" clip-path="url(#terminal-1053129485-line-0)">
</text><text class="terminal-1053129485-r2" x="976" y="44.4" textLength="12.2" clip-path="url(#terminal-1053129485-line-1)">
</text><text class="terminal-1053129485-r2" x="976" y="68.8" textLength="12.2" clip-path="url(#terminal-1053129485-line-2)">
</text><text class="terminal-1053129485-r2" x="976" y="93.2" textLength="12.2" clip-path="url(#terminal-1053129485-line-3)">
</text><text class="terminal-1053129485-r2" x="976" y="117.6" textLength="12.2" clip-path="url(#terminal-1053129485-line-4)">
</text><text class="terminal-1053129485-r2" x="976" y="142" textLength="12.2" clip-path="url(#terminal-1053129485-line-5)">
</text><text class="terminal-1053129485-r2" x="976" y="166.4" textLength="12.2" clip-path="url(#terminal-1053129485-line-6)">
</text><text class="terminal-1053129485-r2" x="976" y="190.8" textLength="12.2" clip-path="url(#terminal-1053129485-line-7)">
</text><text class="terminal-1053129485-r2" x="976" y="215.2" textLength="12.2" clip-path="url(#terminal-1053129485-line-8)">
</text><text class="terminal-1053129485-r2" x="976" y="239.6" textLength="12.2" clip-path="url(#terminal-1053129485-line-9)">
</text><text class="terminal-1053129485-r2" x="976" y="264" textLength="12.2" clip-path="url(#terminal-1053129485-line-10)">
</text><text class="terminal-1053129485-r2" x="976" y="288.4" textLength="12.2" clip-path="url(#terminal-1053129485-line-11)">
</text><text class="terminal-1053129485-r2" x="976" y="312.8" textLength="12.2" clip-path="url(#terminal-1053129485-line-12)">
</text><text class="terminal-1053129485-r2" x="976" y="337.2" textLength="12.2" clip-path="url(#terminal-1053129485-line-13)">
</text><text class="terminal-1053129485-r2" x="976" y="361.6" textLength="12.2" clip-path="url(#terminal-1053129485-line-14)">
</text><text class="terminal-1053129485-r2" x="976" y="386" textLength="12.2" clip-path="url(#terminal-1053129485-line-15)">
</text><text class="terminal-1053129485-r2" x="976" y="410.4" textLength="12.2" clip-path="url(#terminal-1053129485-line-16)">
</text><text class="terminal-1053129485-r2" x="976" y="434.8" textLength="12.2" clip-path="url(#terminal-1053129485-line-17)">
</text><text class="terminal-1053129485-r2" x="976" y="459.2" textLength="12.2" clip-path="url(#terminal-1053129485-line-18)">
</text><text class="terminal-1053129485-r2" x="976" y="483.6" textLength="12.2" clip-path="url(#terminal-1053129485-line-19)">
</text><text class="terminal-1053129485-r2" x="976" y="508" textLength="12.2" clip-path="url(#terminal-1053129485-line-20)">
</text><text class="terminal-1053129485-r2" x="976" y="532.4" textLength="12.2" clip-path="url(#terminal-1053129485-line-21)">
</text><text class="terminal-1053129485-r2" x="976" y="556.8" textLength="12.2" clip-path="url(#terminal-1053129485-line-22)">
</text><text class="terminal-1053129485-r3" x="0" y="581.2" textLength="36.6" clip-path="url(#terminal-1053129485-line-23)">&#160;o&#160;</text><text class="terminal-1053129485-r4" x="36.6" y="581.2" textLength="85.4" clip-path="url(#terminal-1053129485-line-23)">Options</text>
</g>
</g>
</svg>

'''
# ---
# name: test_multiple_css
'''
<svg class="rich-terminal" viewBox="0 0 994 635.5999999999999" xmlns="http://www.w3.org/2000/svg">
Expand Down
11 changes: 11 additions & 0 deletions tests/snapshot_tests/snapshot_apps/multi_keys.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from textual.app import App, ComposeResult
from textual.binding import Binding
from textual.widgets import Footer

class MApp(App):
BINDINGS = [Binding("o,ctrl+o", "options", "Options")]
def compose(self) -> ComposeResult:
yield Footer()

if __name__ == "__main__":
MApp().run()
5 changes: 5 additions & 0 deletions tests/snapshot_tests/test_snapshots.py
Original file line number Diff line number Diff line change
Expand Up @@ -1264,3 +1264,8 @@ def test_dynamic_bindings(snap_compare):
def test_grid_gutter(snap_compare):
# https://github.com/Textualize/textual/issues/4522
assert snap_compare(SNAPSHOT_APPS_DIR / "grid_gutter.py")


def test_multi_keys(snap_compare):
# https://github.com/Textualize/textual/issues/4542
assert snap_compare(SNAPSHOT_APPS_DIR / "multi_keys.py")

0 comments on commit d15cfa0

Please sign in to comment.