Release0170 (#2165)

* blog post

* blog post

* options list

* snapshot

* words

* fix flicker
This commit is contained in:
Will McGugan
2023-03-29 16:29:28 +01:00
committed by GitHub
parent 0be094cf4a
commit 2cd8295325
11 changed files with 993 additions and 558 deletions

View File

@@ -5,7 +5,7 @@ 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
## [0.17.0] - 2023-03-29
### Fixed
@@ -33,6 +33,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Screens with alpha in their background color will now blend with the background. https://github.com/Textualize/textual/pull/2139
- Added "thick" border style. https://github.com/Textualize/textual/pull/2139
- message_pump.app will now set the active app if it is not already set.
- DataTable now has max height set to 100vh
### Added

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 134 KiB

View File

@@ -0,0 +1,96 @@
---
draft: false
date: 2023-03-29
categories:
- Release
title: "Textual 0.17.0 adds translucent screens and Option List"
authors:
- willmcgugan
---
# Textual 0.17.0 adds translucent screens and Option List
This is a surprisingly large release, given it has been just 7 days since the last version (and we were down a developer for most of that time).
What's new in this release?
<!-- more -->
There are two new notable features I want to cover. The first is a compositor effect.
## Translucent screens
Textual has a concept of "screens" which you can think of as independent UI modes, each with their own user interface and logic.
The App class keeps a stack of these screens so you can switch to a new screen and later return to the previous screen.
!!! tip inline end "Screens"
See the [guide](../../guide/screens.md) to learn more about the screens API.
<a href="/guide/screens">
<div class="excalidraw">
--8<-- "docs/images/screens/pop_screen.excalidraw.svg"
</div>
</a>
Screens can be used to build modal dialogs by *pushing* a screen with controls / buttons, and *popping* the screen when the user has finished with it.
The problem with this approach is that there was nothing to indicate to the user that the original screen was still there, and could be returned to.
In this release we have added alpha support to the Screen's background color which allows the screen underneath to show through, typically blended with a little color.
Applying this to a screen makes it clear than the user can return to the previous screen when they have finished interacting with the modal.
Here's how you can enable this effect with CSS:
```sass hl_lines="3"
DialogScreen {
align: center middle;
background: $primary 30%;
}
```
Setting the background to `$primary` will make the background blue (with the default theme).
The addition of `30%` sets the alpha so that it will be blended with the background.
Here's the kind of effect this creates:
<div>
--8<-- "docs/blog/images/transparent_background.svg"
</div>
There are 4 screens in the above screenshot, one for the base screen and one for each of the three dialogs.
Note how each screen modifies the color of the screen below, but leaves everything visible.
See the [docs on screen opacity](../../guide/screens.md#screen-opacity) if you want to add this to your apps.
## Option list
Textual has had a [ListView](../../widgets/list_view.md) widget for a while, which is an excellent way of navigating a list of items (actually other widgets). In this release we've added an [OptionList](../../widgets/option_list.md) which is similar in appearance, but uses the [line api](../../guide/widgets.md#line-api) under the hood. The Line API makes it more efficient when you approach thousands of items.
```{.textual path="docs/examples/widgets/option_list_strings.py"}
```
The Options List accepts [Rich](https://github.com/Textualize/rich/) *renderable*, which means that anything Rich can render may be displayed in a list. Here's an Option List of tables:
```{.textual path="docs/examples/widgets/option_list_tables.py" columns="100" lines="32"}
```
We plan to build on the `OptionList` widget to implement drop-downs, menus, check lists, etc.
But it is still very useful as it is, and you can add it to apps now.
## What else?
There are a number of fixes regarding refreshing in this release. If you had issues with parts of the screen not updating, the new version should resolve it.
There's also a new logging handler, and a "thick" border type.
See [release notes](https://github.com/Textualize/textual/releases/tag/v0.17.0) for the full details.
## Next week
Next week we plan to take a break from building Textual to *building apps* with Textual.
We do this now and again to give us an opportunity to step back and understand things from the perspective of a developer using Textual.
We will hopefully have something interesting to show from the exercise, and new Open Source apps to share.
## Join us
If you want to talk about this update or anything else Textual related, join us on our [Discord server](https://discord.gg/Enf6Z3qhVr).

View File

@@ -1,6 +1,6 @@
[tool.poetry]
name = "textual"
version = "0.16.0"
version = "0.17.0"
homepage = "https://github.com/Textualize/textual"
description = "Modern Text User Interface framework"
authors = ["Will McGugan <will@textualize.io>"]

View File

@@ -849,6 +849,7 @@ class Compositor:
"""
screen_region = self.size.region
update_regions = self._dirty_regions.copy()
self._dirty_regions.clear()
if update_regions:
# Create a crop region that surrounds all updates.
crop = Region.from_union(update_regions).intersection(screen_region)

View File

@@ -1599,6 +1599,7 @@ class App(Generic[ReturnType], DOMNode):
try:
await self._dispatch_message(events.Compose())
await self._dispatch_message(events.Mount())
self.check_idle()
finally:
self._mounted_event.set()

View File

@@ -437,6 +437,7 @@ class MessagePump(metaclass=MessagePumpMeta):
try:
await self._dispatch_message(events.Compose())
await self._dispatch_message(events.Mount())
self.check_idle()
self._post_mount()
except Exception as error:
self.app._handle_exception(error)

View File

@@ -382,7 +382,6 @@ class Screen(Widget):
self._repaint_required = False
if self._dirty_widgets:
self._on_timer_update()
self.update_timer.resume()
# The Screen is idle - a good opportunity to invoke the scheduled callbacks

View File

@@ -247,6 +247,7 @@ class DataTable(ScrollView, Generic[CellType], can_focus=True):
background: $surface ;
color: $text;
height: auto;
max-height: 100vh
}
DataTable > .datatable--header {
text-style: bold;

View File

@@ -176,7 +176,7 @@ class OptionList(ScrollView, can_focus=True):
}
OptionList > .option-list--separator {
color: $text-muted;
color: $foreground 15%;
}
OptionList > .option-list--option-highlighted {

File diff suppressed because one or more lines are too long