Fixing vertical layout

This commit is contained in:
Darren Burns
2022-01-25 15:20:14 +00:00
parent cea331ef4d
commit 19d0a2b097
7 changed files with 16 additions and 82 deletions

View File

@@ -1,8 +1,8 @@
/* CSS file for dev_sandbox.py */
App > View {
docks: side=left/1;
text: on #20639b;
layout: vertical;
text: on #6e06c2;
}
Widget:hover {

View File

@@ -7,7 +7,7 @@ from textual.widget import Widget
class PanelWidget(Widget):
def render(self) -> RenderableType:
return Panel("hello world!", title="Title")
return Panel("hello world!", title="Title", height=4)
class BasicApp(App):
@@ -21,12 +21,8 @@ class BasicApp(App):
def on_mount(self):
"""Build layout here."""
self.mount(
header=Widget(),
content=PanelWidget(),
footer=Widget(),
sidebar=Widget(),
)
self.mount(header=PanelWidget(), content=PanelWidget(), footer=PanelWidget())
self.view.refresh_layout()
BasicApp.run(css_file="test_app.css", watch_css=True, log="textual.log")
BasicApp.run(log="textual.log")

View File

@@ -254,7 +254,6 @@ class App(DOMNode):
Args:
widget (Widget): [description]
"""
log("set_focus", widget)
if widget == self.focused:
# Widget is already focused
return
@@ -380,7 +379,7 @@ class App(DOMNode):
if self.log_file is not None:
self.log_file.close()
def _register(self, parent: DOMNode, child: DOMNode) -> bool:
def _register_child(self, parent: DOMNode, child: DOMNode) -> bool:
if child not in self.registry:
parent.children._append(child)
self.registry.add(child)
@@ -409,7 +408,7 @@ class App(DOMNode):
if widget not in self.registry:
if widget_id is not None:
widget.id = widget_id
self._register(parent, widget)
self._register_child(parent, child=widget)
apply_stylesheet(widget)
for _widget_id, widget in name_widgets:
@@ -432,7 +431,7 @@ class App(DOMNode):
driver.disable_input()
await self.close_messages()
def refresh(self, repaint: bool = True, layout: bool = False) -> None:
def refresh(self) -> None:
sync_available = os.environ.get("TERM_PROGRAM", "") != "Apple_Terminal"
if not self._closed:
console = self.console
@@ -627,51 +626,3 @@ class App(DOMNode):
self.reset_styles()
self.stylesheet.update(self)
self.view.refresh(layout=True)
if __name__ == "__main__":
import asyncio
from .widgets import Header
from .widgets import Footer
from .widgets import Placeholder
# from .widgets.scroll_view import ScrollView
import os
class MyApp(App):
"""Just a test app."""
async def on_load(self, event: events.Load) -> None:
await self.bind("ctrl+c", "quit", show=False)
await self.bind("q", "quit", "Quit")
await self.bind("x", "bang", "Test error handling")
await self.bind("b", "toggle_sidebar", "Toggle sidebar")
show_bar: Reactive[bool] = Reactive(False)
async def watch_show_bar(self, show_bar: bool) -> None:
self.animator.animate(self.bar, "layout_offset_x", 0 if show_bar else -40)
async def action_toggle_sidebar(self) -> None:
self.show_bar = not self.show_bar
async def on_mount(self, event: events.Mount) -> None:
view = await self.push_view(DockView())
header = Header()
footer = Footer()
self.bar = Placeholder(name="left")
await view.dock(header, edge="top")
await view.dock(footer, edge="bottom")
await view.dock(self.bar, edge="left", size=40, z=1)
self.bar.layout_offset_x = -40
sub_view = DockView()
await sub_view.dock(Placeholder(), Placeholder(), edge="top")
await view.dock(sub_view, edge="left")
MyApp.run(log="textual.log")

View File

@@ -159,9 +159,9 @@ class Layout(ABC):
"""Generate a layout map that defines where on the screen the widgets will be drawn.
Args:
console (Console): Console instance.
size (Dimensions): Size of container.
viewport (Region): Screen relative viewport.
view (View): The View instance.
size (Size): Size of container.
scroll (Offset): Offset to apply to the Widget placements.
Returns:
Iterable[WidgetPlacement]: An iterable of widget location

View File

@@ -22,25 +22,15 @@ class VerticalLayout(Layout):
self.auto_width = auto_width
self.z = z
self.gutter = Spacing.unpack(gutter)
self._widgets: list[Widget] = []
self._max_widget_width = 0
super().__init__()
def add(self, widget: Widget) -> None:
self._widgets.append(widget)
self._max_widget_width = max(widget.app.measure(widget), self._max_widget_width)
def clear(self) -> None:
del self._widgets[:]
self._max_widget_width = 0
def get_widgets(self) -> Iterable[Widget]:
return self._widgets
def get_widgets(self, view: View) -> Iterable[Widget]:
return view.children
def arrange(
self, view: View, size: Size, scroll: Offset
) -> Iterable[WidgetPlacement]:
index = 0
width, _height = size
gutter = self.gutter
x, y = self.gutter.top_left
@@ -51,10 +41,9 @@ class VerticalLayout(Layout):
)
total_width = render_width
gutter_height = max(gutter.top, gutter.bottom)
for last, widget in loop_last(self._widgets):
for last, widget in loop_last(view.children):
if (
not widget.render_cache
or widget.render_cache.size.width != render_width
@@ -63,7 +52,7 @@ class VerticalLayout(Layout):
assert widget.render_cache is not None
render_height = widget.render_cache.size.height
region = Region(x, y, render_width, render_height)
yield WidgetPlacement(region, widget, (self.z, index))
yield WidgetPlacement(region, widget, self.z)
y += render_height + (gutter.bottom if last else gutter_height)
yield WidgetPlacement(Region(0, 0, total_width + gutter.width, y))

View File

@@ -13,7 +13,6 @@ from typing import (
TYPE_CHECKING,
)
from . import log
from . import events
from ._callback import count_parameters, invoke

View File

@@ -22,7 +22,6 @@ class View(Widget):
def __init__(self, name: str | None = None, id: str | None = None) -> None:
self.mouse_over: Widget | None = None
self.widgets: set[Widget] = set()
self._mouse_style: Style = Style()
self._mouse_widget: Widget | None = None