mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
@@ -58,7 +58,7 @@ class FileSearchApp(App):
|
||||
self.mount(file_table_wrapper=Widget(self.file_table))
|
||||
self.mount(search_bar=self.search_bar)
|
||||
|
||||
def on_text_widget_base_changed(self, event: TextWidgetBase.Changed) -> None:
|
||||
def on_text_input_changed(self, event: TextInput.Changed) -> None:
|
||||
self.file_table.filter = event.value
|
||||
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ class InputApp(App[str]):
|
||||
)
|
||||
self.mount(text_area=TextArea())
|
||||
|
||||
def on_text_widget_base_changed(self, event: TextWidgetBase.Changed) -> None:
|
||||
def on_text_input_changed_changed(self, event: TextInput.Changed) -> None:
|
||||
try:
|
||||
value = float(event.value)
|
||||
except ValueError:
|
||||
|
||||
@@ -13,8 +13,7 @@
|
||||
}
|
||||
|
||||
App > Screen {
|
||||
|
||||
background: $background;
|
||||
|
||||
color: $text;
|
||||
layers: base sidebar;
|
||||
layout: vertical;
|
||||
@@ -22,10 +21,11 @@ App > Screen {
|
||||
}
|
||||
|
||||
#tree-container {
|
||||
background: $panel;
|
||||
overflow-y: auto;
|
||||
height: 20;
|
||||
margin: 1 2;
|
||||
background: $surface;
|
||||
|
||||
padding: 1 2;
|
||||
}
|
||||
|
||||
@@ -36,13 +36,18 @@ DirectoryTree {
|
||||
}
|
||||
|
||||
|
||||
|
||||
#table-container {
|
||||
background: $panel;
|
||||
height: auto;
|
||||
margin: 1 2;
|
||||
}
|
||||
|
||||
DataTable {
|
||||
/*border:heavy red;*/
|
||||
/* tint: 10% green; */
|
||||
/* text-opacity: 50%; */
|
||||
padding: 1;
|
||||
background: $surface;
|
||||
padding: 1 2;
|
||||
margin: 1 2;
|
||||
height: 24;
|
||||
}
|
||||
@@ -101,7 +106,7 @@ Tweet {
|
||||
/* border: outer $primary; */
|
||||
padding: 1;
|
||||
border: wide $panel;
|
||||
overflow: auto;
|
||||
|
||||
/* scrollbar-gutter: stable; */
|
||||
align-horizontal: center;
|
||||
box-sizing: border-box;
|
||||
@@ -138,8 +143,14 @@ TweetBody {
|
||||
padding: 0 1 0 0;
|
||||
}
|
||||
|
||||
Tweet.scroll-horizontal {
|
||||
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
Tweet.scroll-horizontal TweetBody {
|
||||
width: 350;
|
||||
|
||||
}
|
||||
|
||||
.button {
|
||||
@@ -182,7 +193,7 @@ Tweet.scroll-horizontal TweetBody {
|
||||
|
||||
|
||||
#sidebar .content {
|
||||
layout: vertical
|
||||
layout: vertical;
|
||||
}
|
||||
|
||||
OptionItem {
|
||||
|
||||
@@ -7,7 +7,7 @@ from textual.app import App, ComposeResult
|
||||
from textual.reactive import Reactive
|
||||
from textual.widget import Widget
|
||||
from textual.widgets import Static, DataTable, DirectoryTree, Header, Footer
|
||||
from textual.layout import Container
|
||||
from textual.layout import Container, Vertical
|
||||
|
||||
CODE = '''
|
||||
from __future__ import annotations
|
||||
@@ -68,38 +68,38 @@ lorem_short_text = Text.from_markup(lorem_short)
|
||||
lorem_long_text = Text.from_markup(lorem * 2)
|
||||
|
||||
|
||||
class TweetHeader(Widget):
|
||||
class TweetHeader(Static):
|
||||
def render(self) -> RenderableType:
|
||||
return Text("Lorem Impsum", justify="center")
|
||||
|
||||
|
||||
class TweetBody(Widget):
|
||||
class TweetBody(Static):
|
||||
short_lorem = Reactive(False)
|
||||
|
||||
def render(self) -> Text:
|
||||
return lorem_short_text if self.short_lorem else lorem_long_text
|
||||
|
||||
|
||||
class Tweet(Widget):
|
||||
class Tweet(Vertical):
|
||||
pass
|
||||
|
||||
|
||||
class OptionItem(Widget):
|
||||
class OptionItem(Static):
|
||||
def render(self) -> Text:
|
||||
return Text("Option")
|
||||
|
||||
|
||||
class Error(Widget):
|
||||
class Error(Static):
|
||||
def render(self) -> Text:
|
||||
return Text("This is an error message", justify="center")
|
||||
|
||||
|
||||
class Warning(Widget):
|
||||
class Warning(Static):
|
||||
def render(self) -> Text:
|
||||
return Text("This is a warning message", justify="center")
|
||||
|
||||
|
||||
class Success(Widget):
|
||||
class Success(Static):
|
||||
def render(self) -> Text:
|
||||
return Text("This is a success message", justify="center")
|
||||
|
||||
@@ -120,17 +120,22 @@ class BasicApp(App, css_path="basic.css"):
|
||||
table = DataTable()
|
||||
self.scroll_to_target = Tweet(TweetBody())
|
||||
|
||||
yield Container(
|
||||
yield Vertical(
|
||||
Tweet(TweetBody()),
|
||||
Widget(
|
||||
Container(
|
||||
Static(
|
||||
Syntax(CODE, "python", line_numbers=True, indent_guides=True),
|
||||
Syntax(
|
||||
CODE,
|
||||
"python",
|
||||
line_numbers=True,
|
||||
indent_guides=True,
|
||||
),
|
||||
classes="code",
|
||||
),
|
||||
classes="scrollable",
|
||||
),
|
||||
table,
|
||||
Widget(DirectoryTree("~/"), id="tree-container"),
|
||||
Container(table, id="table-container"),
|
||||
Container(DirectoryTree("~/"), id="tree-container"),
|
||||
Error(),
|
||||
Tweet(TweetBody(), classes="scrollbar-size-custom"),
|
||||
Warning(),
|
||||
@@ -143,12 +148,12 @@ class BasicApp(App, css_path="basic.css"):
|
||||
Tweet(TweetBody(), classes="scroll-horizontal"),
|
||||
)
|
||||
yield Widget(
|
||||
Widget(classes="title"),
|
||||
Widget(classes="user"),
|
||||
Static("Title", classes="title"),
|
||||
Static("Content", classes="user"),
|
||||
OptionItem(),
|
||||
OptionItem(),
|
||||
OptionItem(),
|
||||
Widget(classes="content"),
|
||||
Static(classes="content"),
|
||||
id="sidebar",
|
||||
)
|
||||
yield Footer()
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
from textual import layout, events
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.widgets import Button
|
||||
|
||||
|
||||
class ButtonsApp(App[str]):
|
||||
def compose(self) -> ComposeResult:
|
||||
yield layout.Vertical(
|
||||
Button("default", id="foo"),
|
||||
Button("Where there is a Will"),
|
||||
Button("There is a Way"),
|
||||
Button("There can be only one"),
|
||||
Button.success("success", id="bar"),
|
||||
layout.Horizontal(
|
||||
Button("Where there is a Will"),
|
||||
Button("There is a Way"),
|
||||
Button("There can be only one"),
|
||||
Button.warning("warning", id="baz"),
|
||||
Button("Where there is a Will"),
|
||||
Button("There is a Way"),
|
||||
Button("There can be only one"),
|
||||
id="scroll",
|
||||
),
|
||||
Button.error("error", id="baz"),
|
||||
Button("Where there is a Will"),
|
||||
Button("There is a Way"),
|
||||
Button("There can be only one"),
|
||||
)
|
||||
|
||||
def on_button_pressed(self, event: Button.Pressed) -> None:
|
||||
self.app.bell()
|
||||
|
||||
async def on_key(self, event: events.Key) -> None:
|
||||
await self.dispatch_key(event)
|
||||
|
||||
def key_d(self):
|
||||
self.dark = not self.dark
|
||||
|
||||
|
||||
app = ButtonsApp(log_path="textual.log", css_path="buttons.css", watch_css=True)
|
||||
|
||||
if __name__ == "__main__":
|
||||
result = app.run()
|
||||
print(repr(result))
|
||||
32
sandbox/will/scrolly.py
Normal file
32
sandbox/will/scrolly.py
Normal file
@@ -0,0 +1,32 @@
|
||||
from rich.text import Text
|
||||
from textual.app import App, ComposeResult
|
||||
from textual.widgets import Static
|
||||
|
||||
text = "\n".join("FOO BAR bazz etc sdfsdf " * 20 for n in range(1000))
|
||||
|
||||
|
||||
class Content(Static):
|
||||
DEFAULT_CSS = """
|
||||
Content {
|
||||
width: auto;
|
||||
}
|
||||
"""
|
||||
|
||||
def render(self):
|
||||
return Text(text, no_wrap=False)
|
||||
|
||||
|
||||
class ScrollApp(App):
|
||||
CSS = """
|
||||
Screen {
|
||||
overflow: auto;
|
||||
}
|
||||
"""
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
yield Content()
|
||||
|
||||
|
||||
app = ScrollApp()
|
||||
if __name__ == "__main__":
|
||||
app.run()
|
||||
Reference in New Issue
Block a user