mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
remove depreceate code
This commit is contained in:
@@ -30,7 +30,7 @@ class Edge:
|
||||
min_size: int = 1
|
||||
|
||||
|
||||
def layout_resolve(total: int, edges: Sequence[EdgeProtocol]) -> List[int]:
|
||||
def layout_resolve(total: int, edges: Sequence[EdgeProtocol]) -> list[int]:
|
||||
"""Divide total space to satisfy size, fraction, and min_size, constraints.
|
||||
|
||||
The returned list of integers should add up to total in most cases, unless it is
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
from typing import Iterable
|
||||
|
||||
from rich.cells import cell_len
|
||||
from rich.console import Console, ConsoleOptions, RenderableType, RenderResult
|
||||
from rich.control import Control
|
||||
from rich.segment import Segment
|
||||
from rich.style import Style
|
||||
|
||||
from ._loop import loop_last
|
||||
|
||||
|
||||
class LineCache:
|
||||
def __init__(self, lines: list[list[Segment]]) -> None:
|
||||
self.lines = lines
|
||||
self._dirty = [True] * len(self.lines)
|
||||
|
||||
@classmethod
|
||||
def from_renderable(
|
||||
cls,
|
||||
console: Console,
|
||||
renderable: RenderableType,
|
||||
width: int,
|
||||
height: int,
|
||||
) -> "LineCache":
|
||||
options = console.options.update_dimensions(width, height)
|
||||
lines = console.render_lines(renderable, options)
|
||||
return cls(lines)
|
||||
|
||||
@property
|
||||
def dirty(self) -> bool:
|
||||
return any(self._dirty)
|
||||
|
||||
def __rich_console__(
|
||||
self, console: Console, options: ConsoleOptions
|
||||
) -> RenderResult:
|
||||
|
||||
new_line = Segment.line()
|
||||
for line in self.lines:
|
||||
yield from line
|
||||
yield new_line
|
||||
|
||||
def render(self, x: int, y: int, width: int, height: int) -> Iterable[Segment]:
|
||||
move_to = Control.move_to
|
||||
lines = self.lines[:height]
|
||||
new_line = Segment.line()
|
||||
for last, (offset_y, (line, dirty)) in loop_last(
|
||||
enumerate(zip(lines, self._dirty), y)
|
||||
):
|
||||
if dirty:
|
||||
yield move_to(x, offset_y).segment
|
||||
yield from Segment.adjust_line_length(line, width)
|
||||
if not last:
|
||||
yield new_line
|
||||
self._dirty[:] = [False] * len(self.lines)
|
||||
|
||||
def get_style_at(self, x: int, y: int) -> Style:
|
||||
try:
|
||||
line = self.lines[y]
|
||||
except IndexError:
|
||||
return Style.null()
|
||||
end = 0
|
||||
for segment in line:
|
||||
end += cell_len(segment.text)
|
||||
if x < end:
|
||||
return segment.style or Style.null()
|
||||
return Style.null()
|
||||
@@ -108,7 +108,7 @@ class Widget(DOMNode):
|
||||
self.hscroll.position = int(new_value)
|
||||
|
||||
async def watch_scroll_y(self, new_value: float) -> None:
|
||||
self.vscroll.position = int(new_value)
|
||||
self.vertical_scrollbar.position = int(new_value)
|
||||
|
||||
def validate_scroll_x(self, value: float) -> float:
|
||||
return clamp(value, 0, self.max_scroll_x)
|
||||
@@ -131,7 +131,7 @@ class Widget(DOMNode):
|
||||
return max(0, self.virtual_size.height - self.container_size.height)
|
||||
|
||||
@property
|
||||
def vscroll(self) -> ScrollBar:
|
||||
def vertical_scrollbar(self) -> ScrollBar:
|
||||
"""Get a vertical scrollbar (create if necessary)
|
||||
|
||||
Returns:
|
||||
@@ -199,15 +199,6 @@ class Widget(DOMNode):
|
||||
self.show_horizontal_scrollbar = show_horizontal
|
||||
self.show_vertical_scrollbar = show_vertical
|
||||
|
||||
# self.log(
|
||||
# "REFRESH_SCROLLBARS",
|
||||
# widget=self,
|
||||
# virtual_size=self.virtual_size,
|
||||
# size=self.size,
|
||||
# container_size=self.container_size,
|
||||
# )
|
||||
# return changed
|
||||
|
||||
@property
|
||||
def scrollbars_enabled(self) -> tuple[bool, bool]:
|
||||
"""A tuple of booleans that indicate if scrollbars are enabled.
|
||||
@@ -350,13 +341,13 @@ class Widget(DOMNode):
|
||||
_,
|
||||
) = region.split(-1, -1)
|
||||
if vertical_scrollbar_region:
|
||||
yield self.vscroll, vertical_scrollbar_region
|
||||
yield self.vertical_scrollbar, vertical_scrollbar_region
|
||||
if horizontal_scrollbar_region:
|
||||
yield self.hscroll, horizontal_scrollbar_region
|
||||
elif show_vertical_scrollbar:
|
||||
region, scrollbar_region = region.split_vertical(-1)
|
||||
if scrollbar_region:
|
||||
yield self.vscroll, scrollbar_region
|
||||
yield self.vertical_scrollbar, scrollbar_region
|
||||
elif show_horizontal_scrollbar:
|
||||
region, scrollbar_region = region.split_horizontal(-1)
|
||||
if scrollbar_region:
|
||||
@@ -496,8 +487,8 @@ class Widget(DOMNode):
|
||||
if self.is_container:
|
||||
width, height = self.container_size
|
||||
if self.show_vertical_scrollbar:
|
||||
self.vscroll.window_virtual_size = virtual_size.height
|
||||
self.vscroll.window_size = height
|
||||
self.vertical_scrollbar.window_virtual_size = virtual_size.height
|
||||
self.vertical_scrollbar.window_size = height
|
||||
# self.vscroll.refresh()
|
||||
if self.show_horizontal_scrollbar:
|
||||
self.hscroll.window_virtual_size = virtual_size.width
|
||||
|
||||
@@ -2,7 +2,6 @@ from ._footer import Footer
|
||||
from ._header import Header
|
||||
from ._button import Button, ButtonPressed
|
||||
from ._placeholder import Placeholder
|
||||
from ._scroll_view import ScrollView
|
||||
from ._static import Static
|
||||
from ._tree_control import TreeControl, TreeClick, TreeNode, NodeID
|
||||
from ._directory_tree import DirectoryTree, FileClick
|
||||
|
||||
@@ -1,227 +0,0 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from rich.console import RenderableType
|
||||
from rich.style import StyleType
|
||||
|
||||
|
||||
from .. import events
|
||||
from ..geometry import SpacingDimensions
|
||||
from ..layouts.grid import GridLayout
|
||||
from ..message import Message
|
||||
from ..messages import CursorMove
|
||||
from ..scrollbar import ScrollTo, ScrollBar
|
||||
from ..geometry import clamp
|
||||
from ..screen import Screen
|
||||
|
||||
from ..widget import Widget
|
||||
|
||||
from ..reactive import Reactive
|
||||
|
||||
|
||||
class ScrollView(Screen):
|
||||
def __init__(
|
||||
self,
|
||||
contents: RenderableType | Widget | None = None,
|
||||
*,
|
||||
auto_width: bool = False,
|
||||
name: str | None = None,
|
||||
style: StyleType = "",
|
||||
fluid: bool = True,
|
||||
gutter: SpacingDimensions = (0, 0),
|
||||
) -> None:
|
||||
from ..views import WindowView
|
||||
|
||||
layout = GridLayout()
|
||||
super().__init__(name=name, layout=layout)
|
||||
|
||||
self.fluid = fluid
|
||||
self.vscroll = ScrollBar(vertical=True)
|
||||
self.hscroll = ScrollBar(vertical=False)
|
||||
self.window = WindowView(
|
||||
"" if contents is None else contents,
|
||||
auto_width=auto_width,
|
||||
gutter=gutter,
|
||||
)
|
||||
|
||||
layout.add_column("main")
|
||||
layout.add_column("vscroll", size=1)
|
||||
layout.add_row("main")
|
||||
layout.add_row("hscroll", size=1)
|
||||
layout.add_areas(
|
||||
content="main,main", vscroll="vscroll,main", hscroll="main,hscroll"
|
||||
)
|
||||
layout.show_row("hscroll", False)
|
||||
layout.show_column("vscroll", False)
|
||||
|
||||
x: Reactive[float] = Reactive(0, repaint=False)
|
||||
y: Reactive[float] = Reactive(0, repaint=False)
|
||||
|
||||
target_x: Reactive[float] = Reactive(0, repaint=False)
|
||||
target_y: Reactive[float] = Reactive(0, repaint=False)
|
||||
|
||||
def validate_x(self, value: float) -> float:
|
||||
return clamp(value, 0, self.max_scroll_x)
|
||||
|
||||
def validate_target_x(self, value: float) -> float:
|
||||
return clamp(value, 0, self.max_scroll_x)
|
||||
|
||||
def validate_y(self, value: float) -> float:
|
||||
return clamp(value, 0, self.max_scroll_y)
|
||||
|
||||
def validate_target_y(self, value: float) -> float:
|
||||
return clamp(value, 0, self.max_scroll_y)
|
||||
|
||||
@property
|
||||
def max_scroll_y(self) -> float:
|
||||
return max(0, self.window.virtual_size.height - self.window.size.height)
|
||||
|
||||
@property
|
||||
def max_scroll_x(self) -> float:
|
||||
return max(0, self.window.virtual_size.width - self.window.size.width)
|
||||
|
||||
async def watch_x(self, new_value: float) -> None:
|
||||
self.window.scroll_x = round(new_value)
|
||||
self.hscroll.position = round(new_value)
|
||||
|
||||
async def watch_y(self, new_value: float) -> None:
|
||||
self.window.scroll_y = round(new_value)
|
||||
self.vscroll.position = round(new_value)
|
||||
|
||||
async def update(self, renderable: RenderableType, home: bool = True) -> None:
|
||||
if home:
|
||||
self.home()
|
||||
await self.window.update(renderable)
|
||||
|
||||
async def on_mount(self, event: events.Mount) -> None:
|
||||
assert isinstance(self.layout, GridLayout)
|
||||
self.layout.place(
|
||||
content=self.window,
|
||||
vscroll=self.vscroll,
|
||||
hscroll=self.hscroll,
|
||||
)
|
||||
await self.layout.mount_all(self)
|
||||
|
||||
def home(self) -> None:
|
||||
self.x = self.y = 0
|
||||
|
||||
def scroll_up(self) -> None:
|
||||
self.target_y += 1.5
|
||||
self.animate("y", self.target_y, easing="out_cubic", speed=80)
|
||||
|
||||
def scroll_down(self) -> None:
|
||||
self.target_y -= 1.5
|
||||
self.animate("y", self.target_y, easing="out_cubic", speed=80)
|
||||
|
||||
def page_up(self) -> None:
|
||||
self.target_y -= self.size.height
|
||||
self.animate("y", self.target_y, easing="out_cubic")
|
||||
|
||||
def page_down(self) -> None:
|
||||
self.target_y += self.size.height
|
||||
self.animate("y", self.target_y, easing="out_cubic")
|
||||
|
||||
def page_left(self) -> None:
|
||||
self.target_x -= self.size.width
|
||||
self.animate("x", self.target_x, speed=120, easing="out_cubic")
|
||||
|
||||
def page_right(self) -> None:
|
||||
self.target_x += self.size.width
|
||||
self.animate("x", self.target_x, speed=120, easing="out_cubic")
|
||||
|
||||
def scroll_in_to_view(self, line: int) -> None:
|
||||
if line < self.y:
|
||||
self.y = line
|
||||
elif line >= self.y + self.size.height:
|
||||
self.y = line - self.size.height + 1
|
||||
|
||||
def scroll_to_center(self, line: int) -> None:
|
||||
self.target_y = line - self.size.height // 2
|
||||
if abs(self.target_y - self.y) > 1:
|
||||
# Animate if its more than 1
|
||||
self.animate("y", self.target_y, easing="out_cubic")
|
||||
else:
|
||||
# Jump if its just one step
|
||||
self.y = self.target_y
|
||||
|
||||
async def on_mouse_scroll_up(self, event: events.MouseScrollUp) -> None:
|
||||
self.scroll_up()
|
||||
|
||||
async def on_mouse_scroll_down(self, event: events.MouseScrollUp) -> None:
|
||||
self.scroll_down()
|
||||
|
||||
async def on_key(self, event: events.Key) -> None:
|
||||
await self.dispatch_key(event)
|
||||
|
||||
async def key_down(self) -> None:
|
||||
self.target_y += 2
|
||||
self.animate("y", self.target_y, easing="linear", speed=100)
|
||||
|
||||
async def key_up(self) -> None:
|
||||
self.target_y -= 2
|
||||
self.animate("y", self.target_y, easing="linear", speed=100)
|
||||
|
||||
async def key_pagedown(self) -> None:
|
||||
self.target_y += self.size.height
|
||||
self.animate("y", self.target_y, easing="out_cubic")
|
||||
|
||||
async def key_pageup(self) -> None:
|
||||
self.target_y -= self.size.height
|
||||
self.animate("y", self.target_y, easing="out_cubic")
|
||||
|
||||
async def key_end(self) -> None:
|
||||
self.target_x = 0
|
||||
self.target_y = self.window.virtual_size.height - self.size.height
|
||||
self.animate("x", self.target_x, duration=1, easing="out_cubic")
|
||||
self.animate("y", self.target_y, duration=1, easing="out_cubic")
|
||||
|
||||
async def key_home(self) -> None:
|
||||
self.target_x = 0
|
||||
self.target_y = 0
|
||||
self.animate("x", self.target_x, duration=1, easing="out_cubic")
|
||||
self.animate("y", self.target_y, duration=1, easing="out_cubic")
|
||||
|
||||
async def handle_scroll_up(self) -> None:
|
||||
self.page_up()
|
||||
|
||||
async def handle_scroll_down(self) -> None:
|
||||
self.page_down()
|
||||
|
||||
async def handle_scroll_left(self) -> None:
|
||||
self.page_left()
|
||||
|
||||
async def handle_scroll_right(self) -> None:
|
||||
self.page_right()
|
||||
|
||||
async def handle_scroll_to(self, message: ScrollTo) -> None:
|
||||
if message.x is not None:
|
||||
self.target_x = message.x
|
||||
if message.y is not None:
|
||||
self.target_y = message.y
|
||||
self.animate("x", self.target_x, speed=150, easing="out_cubic")
|
||||
self.animate("y", self.target_y, speed=150, easing="out_cubic")
|
||||
|
||||
async def handle_window_change(self, message: Message) -> None:
|
||||
|
||||
message.stop()
|
||||
|
||||
virtual_width, virtual_height = self.window.virtual_size
|
||||
width, height = self.size
|
||||
|
||||
self.x = self.validate_x(self.x)
|
||||
self.y = self.validate_y(self.y)
|
||||
|
||||
self.hscroll.window_virtual_size = virtual_width
|
||||
self.hscroll.window_size = width
|
||||
self.vscroll.window_virtual_size = virtual_height
|
||||
self.vscroll.window_size = height
|
||||
|
||||
assert isinstance(self.layout, GridLayout)
|
||||
|
||||
vscroll_change = self.layout.show_column("vscroll", virtual_height > height)
|
||||
hscroll_change = self.layout.show_row("hscroll", virtual_width > width)
|
||||
if hscroll_change or vscroll_change:
|
||||
self.refresh(layout=True)
|
||||
|
||||
def handle_cursor_move(self, message: CursorMove) -> None:
|
||||
self.scroll_to_center(message.line)
|
||||
message.stop()
|
||||
Reference in New Issue
Block a user