color docs

This commit is contained in:
Will McGugan
2022-09-11 10:25:51 +01:00
parent b6341ddb50
commit 32079fc8f7
3 changed files with 48 additions and 12 deletions

View File

@@ -1,30 +1,52 @@
# Styles
Textual provides a large number of *styles* you can use to customize how your app looks and feels. In this chapter will will look at how you can edit styles in your applications.
In this chapter will explore how you can apply styles to your application to create beautiful user interfaces.
## Styles object
Every widget class in Textual provides a `styles` object which contains a number of writable attributes. You can write to any of these attributes and Textual will update the screen accordingly.
Every Textual widget class provides a `styles` object which contains a number of attributes. These attributes tell Textual how the widget should be displayed, and how it should be positioned on the screen relative to other widgets.
Let's look at a simple example which sets the styles on the `screen` (a special widget that represents the screen).
!!! note
These docs use the term *screen* to describe the contents of the terminal, which will typically be a window on your desktop.
If you write to any styles attribute the screen will update accordingly.
Let's look at a simple example which sets the styles on `screen` (a special widget that represents the screen).
```python title="screen.py" hl_lines="6-7"
--8<-- "docs/examples/guide/styles/screen.py"
```
The first line sets [background](../styles/background.md) to `"darkblue"` which will change the background color to dark blue. There are a few other ways of setting color which we will explore later.
The first line sets the [background](../styles/background.md) style to `"darkblue"` which will change the background color to dark blue. There are a few other ways of setting color which we will explore later.
The second line sets [border](../styles/border.md) to a tuple of `("heavy", "white")` which tells Textual to draw a white border with a style of `"heavy"`. Running this code will show the following:
```{.textual path="docs/examples/guide/styles/screen.py"}
```
## Styling widgets
## Colors
The [color](../styles/color.md) property set the color of text on a widget. The [background](..styles/background/md) property sets the color of the background (under the text).
There are a number of style attribute which accept colors. The most commonly used arel be [color](../styles/color.md) which sets the default color of text on a widget, and [background](..styles/background/md) which sets the background color (under the text).
You can set a color value to one of a number of pre-defined color constants, such as "crimson", "lime", and "palegreen". You can find a full list in the [Color reference](../reference/color.md#textual.color--named-colors).
Here's how you would set the screen background to lime:
```python
self.screen.background = "lime"
```
In addition to color names, there are other ways you can specify a color in Textual (which give you access to all 16.7 million colors a typical monitor can display).
- RGB hex colors starts with a `#` followed by three pairs of one or two hex digits; one for the red, green, and blue color components. For example, `#f00` is an intense red color, and `#9932CC` is *dark orchid*.
- RGB decimal color start with `rgb` followed by a tuple of three numbers in the range 0 to 255. For example `rgb(255,0,0)` is intense red, and `rgb(153,50,204)` is *dark orchid*.
- HSL colors start with `hsl` followed by a tuple of three colors in the range 0 to 255, representing the Hue Saturation and Lightness. For example `hsl(0,100%,50%)` is intense red and `hsl(280,60%,49%)` is *dark orchid*

1
docs/reference/screen.md Normal file
View File

@@ -0,0 +1 @@
::: textual.screen

View File

@@ -10,16 +10,19 @@ The following named colors are used by the [parse][textual.color.Color.parse] me
```{.rich title="colors"}
from textual._color_constants import COLOR_NAME_TO_RGB
from textual.color import Color
from rich.table import Table
from rich.text import Text
table = Table("Name", "RGB", "Color", expand=True, highlight=True)
table = Table("Name", "hex", "RGB", "Color", expand=True, highlight=True)
for name, triplet in sorted(COLOR_NAME_TO_RGB.items()):
if len(triplet) != 3:
continue
color = Color(*triplet)
r, g, b = triplet
table.add_row(
f'"{name}"',
f"{color.hex}",
f"rgb({r}, {g}, {b})",
Text(" ", style=f"on rgb({r},{g},{b})")
)
@@ -64,6 +67,16 @@ class HLS(NamedTuple):
s: float
"""Saturation"""
@property
def css(self) -> str:
"""HLS in css format."""
h, l, s = self
def as_str(number: float) -> str:
return f"{number:.1f}".rstrip("0").rstrip(".")
return f"hsl({as_str(h*360)},{as_str(s*100)}%,{as_str(l*100)}%)"
class HSV(NamedTuple):
"""A color in HSV format."""
@@ -99,11 +112,11 @@ hsla{OPEN_BRACE}({DECIMAL}{COMMA}{PERCENT}{COMMA}{PERCENT}{COMMA}{DECIMAL}){CLOS
)
# Fast way to split a string of 6 characters in to 3 pairs of 2 characters
split_pairs3: Callable[[str], tuple[str, str, str]] = itemgetter(
_split_pairs3: Callable[[str], tuple[str, str, str]] = itemgetter(
slice(0, 2), slice(2, 4), slice(4, 6)
)
# Fast way to split a string of 8 characters in to 4 pairs of 2 characters
split_pairs4: Callable[[str], tuple[str, str, str, str]] = itemgetter(
_split_pairs4: Callable[[str], tuple[str, str, str, str]] = itemgetter(
slice(0, 2), slice(2, 4), slice(4, 6), slice(6, 8)
)
@@ -237,7 +250,7 @@ class Color(NamedTuple):
"""Get the color as HLS.
Returns:
HLS:
HLS: Color in HLS format.
"""
r, g, b = self.normalized
return HLS(*rgb_to_hls(r, g, b))
@@ -350,7 +363,7 @@ class Color(NamedTuple):
- `rgb(RED,GREEN,BLUE)`
- `rgba(RED,GREEN,BLUE,ALPHA)`
- `hsl(RED,GREEN,BLUE)`
- `hsl(RED,GREEN,BLUE,ALPHA)`
- `hsla(RED,GREEN,BLUE,ALPHA)`
All other text will raise a `ColorParseError`.
@@ -402,10 +415,10 @@ class Color(NamedTuple):
int(f"{a}{a}", 16) / 255.0,
)
elif rgb_hex is not None:
r, g, b = [int(pair, 16) for pair in split_pairs3(rgb_hex)]
r, g, b = [int(pair, 16) for pair in _split_pairs3(rgb_hex)]
color = cls(r, g, b, 1.0)
elif rgba_hex is not None:
r, g, b, a = [int(pair, 16) for pair in split_pairs4(rgba_hex)]
r, g, b, a = [int(pair, 16) for pair in _split_pairs4(rgba_hex)]
color = cls(r, g, b, a / 255.0)
elif rgb is not None:
r, g, b = [clamp(int(float(value)), 0, 255) for value in rgb.split(",")]