186 lines
3.8 KiB
Python
186 lines
3.8 KiB
Python
|
from textual.app import App
|
||
|
from textual.containers import Container, Horizontal, ScrollableContainer, Vertical
|
||
|
from textual.screen import Screen
|
||
|
from textual.widgets import Header, Label
|
||
|
from textual_fastdatatable import ArrowBackend, DataTable
|
||
|
|
||
|
|
||
|
class LabeledBox(Container):
|
||
|
DEFAULT_CSS = """
|
||
|
LabeledBox {
|
||
|
layers: base_ top_;
|
||
|
width: 100%;
|
||
|
height: 100%;
|
||
|
}
|
||
|
|
||
|
LabeledBox > Container {
|
||
|
layer: base_;
|
||
|
border: round $primary;
|
||
|
width: 100%;
|
||
|
height: 100%;
|
||
|
layout: vertical;
|
||
|
}
|
||
|
|
||
|
LabeledBox > Label {
|
||
|
layer: top_;
|
||
|
offset-x: 2;
|
||
|
}
|
||
|
"""
|
||
|
|
||
|
def __init__(self, title, *args, **kwargs):
|
||
|
self.__label = Label(title)
|
||
|
|
||
|
super().__init__(self.__label, Container(*args, **kwargs))
|
||
|
|
||
|
@property
|
||
|
def label(self):
|
||
|
return self.__label
|
||
|
|
||
|
|
||
|
class StatusTable(DataTable):
|
||
|
def __init__(self) -> None:
|
||
|
backend = ArrowBackend.from_pydict(
|
||
|
{
|
||
|
"Foo": ["ABCDEFGH"] * 50,
|
||
|
"Bar": ["0123456789"] * 50,
|
||
|
"Baz": ["IJKLMNOPQRSTUVWXYZ"] * 50,
|
||
|
}
|
||
|
)
|
||
|
super().__init__(backend=backend)
|
||
|
|
||
|
self.cursor_type = "row"
|
||
|
self.show_cursor = False
|
||
|
|
||
|
|
||
|
class Status(LabeledBox):
|
||
|
DEFAULT_CSS = """
|
||
|
Status {
|
||
|
width: auto;
|
||
|
}
|
||
|
|
||
|
Status Container {
|
||
|
width: auto;
|
||
|
}
|
||
|
|
||
|
Status StatusTable {
|
||
|
width: auto;
|
||
|
height: 100%;
|
||
|
margin-top: 1;
|
||
|
scrollbar-gutter: stable;
|
||
|
overflow-x: hidden;
|
||
|
}
|
||
|
"""
|
||
|
|
||
|
def __init__(self, name: str):
|
||
|
self.__name = name
|
||
|
self.__table = StatusTable()
|
||
|
|
||
|
super().__init__(f" {self.__name} ", self.__table)
|
||
|
|
||
|
@property
|
||
|
def name(self) -> str:
|
||
|
return self.__name
|
||
|
|
||
|
@property
|
||
|
def table(self) -> StatusTable:
|
||
|
return self.__table
|
||
|
|
||
|
|
||
|
class Rendering(LabeledBox):
|
||
|
DEFAULT_CSS = """
|
||
|
#issue-info {
|
||
|
height: auto;
|
||
|
border-bottom: dashed #632CA6;
|
||
|
}
|
||
|
|
||
|
#statuses-box {
|
||
|
height: 1fr;
|
||
|
width: auto;
|
||
|
}
|
||
|
"""
|
||
|
|
||
|
def __init__(self):
|
||
|
self.__info = Label("test")
|
||
|
|
||
|
super().__init__(
|
||
|
"",
|
||
|
ScrollableContainer(
|
||
|
Horizontal(self.__info, id="issue-info"),
|
||
|
Horizontal(*[Status(str(i)) for i in range(4)], id="statuses-box"),
|
||
|
id="issues-box",
|
||
|
),
|
||
|
)
|
||
|
|
||
|
@property
|
||
|
def info(self) -> Label:
|
||
|
return self.__info
|
||
|
|
||
|
|
||
|
class Sidebar(LabeledBox):
|
||
|
DEFAULT_CSS = """
|
||
|
#sidebar-status {
|
||
|
height: auto;
|
||
|
border-bottom: dashed #632CA6;
|
||
|
}
|
||
|
|
||
|
#sidebar-options {
|
||
|
height: 1fr;
|
||
|
}
|
||
|
"""
|
||
|
|
||
|
def __init__(self):
|
||
|
self.__status = Label("ok")
|
||
|
self.__options = Vertical()
|
||
|
|
||
|
super().__init__(
|
||
|
"",
|
||
|
Container(self.__status, id="sidebar-status"),
|
||
|
Container(self.__options, id="sidebar-options"),
|
||
|
)
|
||
|
|
||
|
@property
|
||
|
def status(self) -> Label:
|
||
|
return self.__status
|
||
|
|
||
|
@property
|
||
|
def options(self) -> Vertical:
|
||
|
return self.__options
|
||
|
|
||
|
|
||
|
class MyScreen(Screen):
|
||
|
DEFAULT_CSS = """
|
||
|
#main-content {
|
||
|
layout: grid;
|
||
|
grid-size: 2;
|
||
|
grid-columns: 1fr 5fr;
|
||
|
grid-rows: 1fr;
|
||
|
}
|
||
|
|
||
|
#main-content-sidebar {
|
||
|
height: 100%;
|
||
|
}
|
||
|
|
||
|
#main-content-rendering {
|
||
|
height: 100%;
|
||
|
}
|
||
|
"""
|
||
|
|
||
|
def compose(self):
|
||
|
yield Header()
|
||
|
yield Container(
|
||
|
Container(Sidebar(), id="main-content-sidebar"),
|
||
|
Container(Rendering(), id="main-content-rendering"),
|
||
|
id="main-content",
|
||
|
)
|
||
|
|
||
|
|
||
|
class MyApp(App):
|
||
|
async def on_mount(self):
|
||
|
self.install_screen(MyScreen(), "myscreen")
|
||
|
await self.push_screen("myscreen")
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
app = MyApp()
|
||
|
app.run()
|