-
Notifications
You must be signed in to change notification settings - Fork 826
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement border (sub)title. (#2064)
* Add Widget.border_title and border_subtitle. Related issues: #1864 * Test setting border_(sub)title. * Add border (sub)title references to StylesCache. These internal references will make it easier for the instance of 'StylesCache' to know which border (sub)title to use, if/when needed. * Add method to render border label. * Add styles to align border (sub)title. * Render border labels. * Update styles template. * Make new 'render_row' parameters optional. * Add (sub)title border snapshot tests. * Document border (sub)title and styles. * Pass (sub)title directly as arguments. Get rid of the watchers to make data flow easier to follow. Related comment: https://github.com/Textualize/textual/pull/2064/files\#r1137746697 * Tweak example. * Fix render_border_label. This was wrong because border labels can be composed of multiple segments if they contain multiple styles. Additionally, we want to render a single blank space of padding around the title. * Ensure we get no label when there's no space. * Add tests for border label rendering. * 'render_border_label' now returns iterable of segments. * Add label to render_row. * Fix calling signature in tests. * Add padding to snapshot tests. * Fix changelog. * Update snapshot tests. * Update snapshot tests. * Border labels expand if there's no corners. * Update CHANGELOG.md * Fix docs. * Remove irrelevant line. * Fix snapshot tests. * Don't share Console among tests. * Simplify example in styles guide. * Avoid expensive function call when possible. * rewording * positive branch first * remove wasteful indirection * fix changelog --------- Co-authored-by: Will McGugan <[email protected]>
- Loading branch information
1 parent
2969273
commit 2a810f8
Showing
24 changed files
with
1,370 additions
and
67 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
from textual.app import App, ComposeResult | ||
from textual.widgets import Static | ||
|
||
TEXT = """I must not fear. | ||
Fear is the mind-killer. | ||
Fear is the little-death that brings total obliteration. | ||
I will face my fear. | ||
I will permit it to pass over me and through me. | ||
And when it has gone past, I will turn the inner eye to see its path. | ||
Where the fear has gone there will be nothing. Only I will remain.""" | ||
|
||
|
||
class BorderTitleApp(App[None]): | ||
def compose(self) -> ComposeResult: | ||
self.widget = Static(TEXT) | ||
yield self.widget | ||
|
||
def on_mount(self) -> None: | ||
self.widget.styles.background = "darkblue" | ||
self.widget.styles.width = "50%" | ||
self.widget.styles.border = ("heavy", "yellow") | ||
self.widget.border_title = "Litany Against Fear" | ||
self.widget.border_subtitle = "by Frank Herbert, in “Dune”" | ||
self.widget.styles.border_title_align = "center" | ||
|
||
|
||
if __name__ == "__main__": | ||
app = BorderTitleApp() | ||
app.run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
Grid { | ||
grid-size: 3 3; | ||
align: center middle; | ||
} | ||
|
||
Container { | ||
width: 100%; | ||
height: 100%; | ||
align: center middle; | ||
} | ||
|
||
#lbl1 { /* (1)! */ | ||
border: vkey $secondary; | ||
} | ||
|
||
#lbl2 { /* (2)! */ | ||
border: round $secondary; | ||
border-title-align: right; | ||
border-subtitle-align: right; | ||
} | ||
|
||
#lbl3 { | ||
border: wide $secondary; | ||
border-title-align: center; | ||
border-subtitle-align: center; | ||
} | ||
|
||
#lbl4 { | ||
border: ascii $success; | ||
border-title-align: center; /* (3)! */ | ||
border-subtitle-align: left; | ||
} | ||
|
||
#lbl5 { /* (4)! */ | ||
/* No border = no (sub)title. */ | ||
border: none $success; | ||
border-title-align: center; | ||
border-subtitle-align: center; | ||
} | ||
|
||
#lbl6 { /* (5)! */ | ||
border-top: solid $success; | ||
border-bottom: solid $success; | ||
} | ||
|
||
#lbl7 { /* (6)! */ | ||
border-top: solid $error; | ||
border-bottom: solid $error; | ||
padding: 1 2; | ||
border-subtitle-align: left; | ||
} | ||
|
||
#lbl8 { | ||
border-top: solid $error; | ||
border-bottom: solid $error; | ||
border-title-align: center; | ||
border-subtitle-align: center; | ||
} | ||
|
||
#lbl9 { | ||
border-top: solid $error; | ||
border-bottom: solid $error; | ||
border-title-align: right; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
from textual.app import App | ||
from textual.containers import Container, Grid | ||
from textual.widgets import Label | ||
|
||
|
||
def make_label_container( # (11)! | ||
text: str, id: str, border_title: str, border_subtitle: str | ||
) -> Container: | ||
lbl = Label(text, id=id) | ||
lbl.border_title = border_title | ||
lbl.border_subtitle = border_subtitle | ||
return Container(lbl) | ||
|
||
|
||
class BorderSubTitleAlignAll(App[None]): | ||
def compose(self): | ||
with Grid(): | ||
yield make_label_container( # (1)! | ||
"This is the story of", | ||
"lbl1", | ||
"[b]Border [i]title[/i][/]", | ||
"[u][r]Border[/r] subtitle[/]", | ||
) | ||
yield make_label_container( # (2)! | ||
"a Python", | ||
"lbl2", | ||
"[b red]Left, but it's loooooooooooong", | ||
"[reverse]Center, but it's loooooooooooong", | ||
) | ||
yield make_label_container( # (3)! | ||
"developer that", | ||
"lbl3", | ||
"[b i on purple]Left[/]", | ||
"[r u white on black]@@@[/]", | ||
) | ||
yield make_label_container( | ||
"had to fill up", | ||
"lbl4", | ||
"", # (4)! | ||
"[link=https://textual.textualize.io]Left[/]", # (5)! | ||
) | ||
yield make_label_container( # (6)! | ||
"nine labels", "lbl5", "Title", "Subtitle" | ||
) | ||
yield make_label_container( # (7)! | ||
"and ended up redoing it", | ||
"lbl6", | ||
"Title", | ||
"Subtitle", | ||
) | ||
yield make_label_container( # (8)! | ||
"because the first try", | ||
"lbl7", | ||
"Title, but really loooooooooong!", | ||
"Subtitle, but really loooooooooong!", | ||
) | ||
yield make_label_container( # (9)! | ||
"had some labels", | ||
"lbl8", | ||
"Title, but really loooooooooong!", | ||
"Subtitle, but really loooooooooong!", | ||
) | ||
yield make_label_container( # (10)! | ||
"that were too long.", | ||
"lbl9", | ||
"Title, but really loooooooooong!", | ||
"Subtitle, but really loooooooooong!", | ||
) | ||
|
||
|
||
app = BorderSubTitleAlignAll(css_path="border_sub_title_align_all.css") | ||
|
||
if __name__ == "__main__": | ||
app.run() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#label1 { | ||
border: solid $secondary; | ||
border-subtitle-align: left; | ||
} | ||
|
||
#label2 { | ||
border: dashed $secondary; | ||
border-subtitle-align: center; | ||
} | ||
|
||
#label3 { | ||
border: tall $secondary; | ||
border-subtitle-align: right; | ||
} | ||
|
||
Screen > Label { | ||
width: 100%; | ||
height: 5; | ||
content-align: center middle; | ||
color: white; | ||
margin: 1; | ||
box-sizing: border-box; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
from textual.app import App | ||
from textual.widgets import Label | ||
|
||
|
||
class BorderSubtitleAlignApp(App): | ||
def compose(self): | ||
lbl = Label("My subtitle is on the left.", id="label1") | ||
lbl.border_subtitle = "< Left" | ||
yield lbl | ||
|
||
lbl = Label("My subtitle is centered", id="label2") | ||
lbl.border_subtitle = "Centered!" | ||
yield lbl | ||
|
||
lbl = Label("My subtitle is on the right", id="label3") | ||
lbl.border_subtitle = "Right >" | ||
yield lbl | ||
|
||
|
||
app = BorderSubtitleAlignApp(css_path="border_subtitle_align.css") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
#label1 { | ||
border: solid $secondary; | ||
border-title-align: left; | ||
} | ||
|
||
#label2 { | ||
border: dashed $secondary; | ||
border-title-align: center; | ||
} | ||
|
||
#label3 { | ||
border: tall $secondary; | ||
border-title-align: right; | ||
} | ||
|
||
Screen > Label { | ||
width: 100%; | ||
height: 5; | ||
content-align: center middle; | ||
color: white; | ||
margin: 1; | ||
box-sizing: border-box; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
from textual.app import App | ||
from textual.widgets import Label | ||
|
||
|
||
class BorderTitleAlignApp(App): | ||
def compose(self): | ||
lbl = Label("My title is on the left.", id="label1") | ||
lbl.border_title = "< Left" | ||
yield lbl | ||
|
||
lbl = Label("My title is centered", id="label2") | ||
lbl.border_title = "Centered!" | ||
yield lbl | ||
|
||
lbl = Label("My title is on the right", id="label3") | ||
lbl.border_title = "Right >" | ||
yield lbl | ||
|
||
|
||
app = BorderTitleAlignApp(css_path="border_title_align.css") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.