diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b27bc934b..f1485e47d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,14 +7,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased -### Added - -- Added support for A-F to Digits widget https://github.com/Textualize/textual/pull/5094 ### Changed +- `Screen.ALLOW_IN_MAXIMIZED_VIEW` will now default to `App.ALLOW_IN_MAXIMIZED_VIEW` https://github.com/Textualize/textual/pull/5088 +- Widgets matching `.-textual-system` will now be included in the maximize view by default https://github.com/Textualize/textual/pull/5088 - Digits are now thin by default, style with text-style: bold to get bold digits https://github.com/Textualize/textual/pull/5094 +### Added + +- Added support for A-F to Digits widget https://github.com/Textualize/textual/pull/5094 + ## [0.82.0] - 2024-10-03 ### Fixed diff --git a/src/textual/app.py b/src/textual/app.py index abc06bda32..b49cca30d8 100644 --- a/src/textual/app.py +++ b/src/textual/app.py @@ -461,6 +461,9 @@ class MyApp(App[None]): COMMAND_PALETTE_DISPLAY: ClassVar[str | None] = None """How the command palette key should be displayed in the footer (or `None` for default).""" + ALLOW_IN_MAXIMIZED_VIEW: ClassVar[str] = "Footer" + """The default value of [Screen.ALLOW_IN_MAXIMIZED_VIEW][textual.screen.Screen.ALLOW_IN_MAXIMIZED_VIEW].""" + BINDINGS: ClassVar[list[BindingType]] = [ Binding("ctrl+c", "quit", "Quit", show=False, priority=True) ] diff --git a/src/textual/screen.py b/src/textual/screen.py index 36c4de658b..55999c7ccd 100644 --- a/src/textual/screen.py +++ b/src/textual/screen.py @@ -204,8 +204,9 @@ class Screen(Generic[ScreenResultType], Widget): Should be a set of [`command.Provider`][textual.command.Provider] classes. """ - ALLOW_IN_MAXIMIZED_VIEW: ClassVar[str] = ".-textual-system,Footer" - """A selector for the widgets (direct children of Screen) that are allowed in the maximized view (in addition to maximized widget).""" + ALLOW_IN_MAXIMIZED_VIEW: ClassVar[str | None] = None + """A selector for the widgets (direct children of Screen) that are allowed in the maximized view (in addition to maximized widget). Or + `None` to default to [App.ALLOW_IN_MAXIMIZED_VIEW][textual.app.App.ALLOW_IN_MAXIMIZED_VIEW]""" ESCAPE_TO_MINIMIZE: ClassVar[bool | None] = None """Use escape key to minimize (potentially overriding bindings) or `None` to defer to [`App.ESCAPE_TO_MINIMIZE`][textual.app.App.ESCAPE_TO_MINIMIZE].""" @@ -434,10 +435,36 @@ def _arrange(self, size: Size) -> DockArrangeResult: if cached_result is not None: return cached_result + allow_in_maximized_view = ( + self.app.ALLOW_IN_MAXIMIZED_VIEW + if self.ALLOW_IN_MAXIMIZED_VIEW is None + else self.ALLOW_IN_MAXIMIZED_VIEW + ) + + def get_maximize_widgets(maximized: Widget) -> list[Widget]: + """Get widgets to display in maximized view. + + Returns: + A list of widgets. + + """ + # De-duplicate with a set + widgets = { + maximized, + *self.query_children(allow_in_maximized_view), + *self.query_children(".-textual-system"), + } + # Restore order of widgets. + maximize_widgets = [widget for widget in self.children if widget in widgets] + # Add the maximized widget, if its not already included + if maximized not in maximize_widgets: + maximize_widgets.insert(0, maximized) + return maximize_widgets + arrangement = self._arrangement_cache[cache_key] = arrange( self, ( - [self.maximized, *self.query_children(self.ALLOW_IN_MAXIMIZED_VIEW)] + get_maximize_widgets(self.maximized) if self.maximized is not None else self._nodes ), diff --git a/tests/snapshot_tests/__snapshots__/test_snapshots/test_maximize_allow.svg b/tests/snapshot_tests/__snapshots__/test_snapshots/test_maximize_allow.svg new file mode 100644 index 0000000000..2da68397b1 --- /dev/null +++ b/tests/snapshot_tests/__snapshots__/test_snapshots/test_maximize_allow.svg @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MaximizeApp + + + + + + + + + + MaximizeApp +╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱Above╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ Hello ╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱Below╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ +╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱╱ + + + diff --git a/tests/snapshot_tests/test_snapshots.py b/tests/snapshot_tests/test_snapshots.py index a0b290cc93..e35b3e9393 100644 --- a/tests/snapshot_tests/test_snapshots.py +++ b/tests/snapshot_tests/test_snapshots.py @@ -2266,3 +2266,29 @@ def render(self) -> LinearGradient: app = TransparentApp() snap_compare(app) + + +def test_maximize_allow(snap_compare): + """Check that App.ALLOW_IN_MAXIMIZED_VIEW is the default. + + If working this should show a header, some text, a focused button, and more text. + + """ + + class MaximizeApp(App): + ALLOW_IN_MAXIMIZED_VIEW = "Header" + BINDINGS = [("m", "screen.maximize", "maximize focused widget")] + + def compose(self) -> ComposeResult: + yield Label( + "Above", classes="-textual-system" + ) # Allowed in maximize view because it has class -textual-system + yield Header() # Allowed because it matches ALLOW_IN_MAXIMIZED_VIEW + yield Button("Hello") # Allowed because it is the maximized widget + yield Label( + "Below", classes="-textual-system" + ) # Allowed because it has class -textual-system + yield Button("World") # Not allowed + yield Footer() # Not allowed + + assert snap_compare(MaximizeApp(), press=["m"])