mirror of
https://github.com/1j01/textual-paint.git
synced 2024-12-22 22:31:43 +03:00
ASCII-ize scrollbar in --ascii-only mode
This commit is contained in:
parent
e2c53e48a0
commit
7c4947df12
@ -28,6 +28,7 @@ from textual.containers import Container, Vertical, Horizontal
|
|||||||
from textual.geometry import Offset, Region, Size
|
from textual.geometry import Offset, Region, Size
|
||||||
from textual.css._style_properties import BorderDefinition
|
from textual.css._style_properties import BorderDefinition
|
||||||
from textual.reactive import var, reactive
|
from textual.reactive import var, reactive
|
||||||
|
from textual.scrollbar import ScrollBar, ScrollBarRender
|
||||||
from textual.strip import Strip
|
from textual.strip import Strip
|
||||||
from textual.dom import DOMNode
|
from textual.dom import DOMNode
|
||||||
from textual.widget import Widget
|
from textual.widget import Widget
|
||||||
@ -51,6 +52,7 @@ from .graphics_primitives import (
|
|||||||
)
|
)
|
||||||
from .menus import MenuBar, Menu, MenuItem, Separator
|
from .menus import MenuBar, Menu, MenuItem, Separator
|
||||||
from .windows import Window, DialogWindow, CharacterSelectorDialogWindow, MessageBox, get_warning_icon, get_question_icon, get_paint_icon
|
from .windows import Window, DialogWindow, CharacterSelectorDialogWindow, MessageBox, get_warning_icon, get_question_icon, get_paint_icon
|
||||||
|
from .scrollbars import ASCIIScrollBarRender
|
||||||
from .file_dialogs import SaveAsDialogWindow, OpenDialogWindow
|
from .file_dialogs import SaveAsDialogWindow, OpenDialogWindow
|
||||||
from .edit_colors import EditColorsDialogWindow
|
from .edit_colors import EditColorsDialogWindow
|
||||||
from .localization.i18n import get as _, load_language, remove_hotkey
|
from .localization.i18n import get as _, load_language, remove_hotkey
|
||||||
@ -5253,6 +5255,9 @@ if args.ascii_only:
|
|||||||
RadioButton.BUTTON_LEFT = "["
|
RadioButton.BUTTON_LEFT = "["
|
||||||
RadioButton.BUTTON_RIGHT = "]"
|
RadioButton.BUTTON_RIGHT = "]"
|
||||||
|
|
||||||
|
ScrollBar.renderer = ASCIIScrollBarRender
|
||||||
|
|
||||||
|
|
||||||
# header_icon_markup = "[on white][blue]\\\\[/][red]|[/][yellow]/[/][/]"
|
# header_icon_markup = "[on white][blue]\\\\[/][red]|[/][yellow]/[/][/]"
|
||||||
# header_icon_markup = "[black]..,[/]\n[blue]\\\\[/][on white][red]|[/][yellow]/[/][/]\n[black on rgb(192,192,192)]\\[_][/]"
|
# header_icon_markup = "[black]..,[/]\n[blue]\\\\[/][on white][red]|[/][yellow]/[/][/]\n[black on rgb(192,192,192)]\\[_][/]"
|
||||||
# trying different geometries for the page going behind the cup of brushes:
|
# trying different geometries for the page going behind the cup of brushes:
|
||||||
|
95
src/textual_paint/scrollbars.py
Normal file
95
src/textual_paint/scrollbars.py
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
|
||||||
|
from math import ceil
|
||||||
|
from rich.color import Color
|
||||||
|
from rich.segment import Segment, Segments
|
||||||
|
from rich.style import Style
|
||||||
|
from textual.scrollbar import ScrollBarRender
|
||||||
|
|
||||||
|
|
||||||
|
class ASCIIScrollBarRender(ScrollBarRender):
|
||||||
|
"""A scrollbar renderer that uses ASCII characters."""
|
||||||
|
@classmethod
|
||||||
|
def render_bar(
|
||||||
|
cls,
|
||||||
|
size: int = 25,
|
||||||
|
virtual_size: float = 50,
|
||||||
|
window_size: float = 20,
|
||||||
|
position: float = 0,
|
||||||
|
thickness: int = 1,
|
||||||
|
vertical: bool = True,
|
||||||
|
back_color: Color = Color.parse("#555555"),
|
||||||
|
bar_color: Color = Color.parse("bright_magenta"),
|
||||||
|
) -> Segments:
|
||||||
|
if vertical:
|
||||||
|
# bars = ["▁", "▂", "▃", "▄", "▅", "▆", "▇", " "]
|
||||||
|
# bars = ["_", "=", "#", " "]
|
||||||
|
bars = [" "]
|
||||||
|
else:
|
||||||
|
# bars = ["▉", "▊", "▋", "▌", "▍", "▎", "▏", " "]
|
||||||
|
# bars = ["#", " "]
|
||||||
|
bars = [" "]
|
||||||
|
|
||||||
|
back = back_color
|
||||||
|
bar = bar_color
|
||||||
|
|
||||||
|
len_bars = len(bars)
|
||||||
|
|
||||||
|
width_thickness = thickness if vertical else 1
|
||||||
|
|
||||||
|
_Segment = Segment
|
||||||
|
_Style = Style
|
||||||
|
blank = " " * width_thickness
|
||||||
|
|
||||||
|
foreground_meta = {"@mouse.up": "release", "@mouse.down": "grab"}
|
||||||
|
if window_size and size and virtual_size and size != virtual_size:
|
||||||
|
bar_ratio = virtual_size / size
|
||||||
|
thumb_size = max(1, window_size / bar_ratio)
|
||||||
|
|
||||||
|
position_ratio = position / (virtual_size - window_size)
|
||||||
|
position = (size - thumb_size) * position_ratio
|
||||||
|
|
||||||
|
start = int(position * len_bars)
|
||||||
|
end = start + ceil(thumb_size * len_bars)
|
||||||
|
|
||||||
|
start_index, start_bar = divmod(max(0, start), len_bars)
|
||||||
|
end_index, end_bar = divmod(max(0, end), len_bars)
|
||||||
|
|
||||||
|
upper = {"@mouse.up": "scroll_up"}
|
||||||
|
lower = {"@mouse.up": "scroll_down"}
|
||||||
|
|
||||||
|
upper_back_segment = Segment(blank, _Style(bgcolor=back, meta=upper))
|
||||||
|
lower_back_segment = Segment(blank, _Style(bgcolor=back, meta=lower))
|
||||||
|
|
||||||
|
segments = [upper_back_segment] * int(size)
|
||||||
|
segments[end_index:] = [lower_back_segment] * (size - end_index)
|
||||||
|
|
||||||
|
segments[start_index:end_index] = [
|
||||||
|
_Segment(blank, _Style(bgcolor=bar, meta=foreground_meta))
|
||||||
|
] * (end_index - start_index)
|
||||||
|
|
||||||
|
# Apply the smaller bar characters to head and tail of scrollbar for more "granularity"
|
||||||
|
if start_index < len(segments):
|
||||||
|
bar_character = bars[len_bars - 1 - start_bar]
|
||||||
|
if bar_character != " ":
|
||||||
|
segments[start_index] = _Segment(
|
||||||
|
bar_character * width_thickness,
|
||||||
|
_Style(bgcolor=back, color=bar, meta=foreground_meta)
|
||||||
|
if vertical
|
||||||
|
else _Style(bgcolor=bar, color=back, meta=foreground_meta),
|
||||||
|
)
|
||||||
|
if end_index < len(segments):
|
||||||
|
bar_character = bars[len_bars - 1 - end_bar]
|
||||||
|
if bar_character != " ":
|
||||||
|
segments[end_index] = _Segment(
|
||||||
|
bar_character * width_thickness,
|
||||||
|
_Style(bgcolor=bar, color=back, meta=foreground_meta)
|
||||||
|
if vertical
|
||||||
|
else _Style(bgcolor=back, color=bar, meta=foreground_meta),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
style = _Style(bgcolor=back)
|
||||||
|
segments = [_Segment(blank, style=style)] * int(size)
|
||||||
|
if vertical:
|
||||||
|
return Segments(segments, new_lines=True)
|
||||||
|
else:
|
||||||
|
return Segments((segments + [_Segment.line()]) * thickness, new_lines=False)
|
Loading…
Reference in New Issue
Block a user