Shofel2_T124_python/venv/lib/python3.10/site-packages/asciimatics/widgets/scrollbar.py

96 lines
3.5 KiB
Python
Raw Normal View History

2024-05-25 16:45:07 +00:00
# -*- coding: utf-8 -*-
"""This module implements a scroll bar capability for widgets"""
from __future__ import division
from __future__ import absolute_import
from __future__ import print_function
from __future__ import unicode_literals
from builtins import range
from builtins import object
class _ScrollBar(object):
"""
Internal object to provide vertical scroll bars for widgets.
"""
def __init__(self, canvas, palette, x, y, height, get_pos, set_pos, absolute=False):
"""
:param canvas: The canvas on which to draw the scroll bar.
:param palette: The palette of the parent Frame.
:param x: The x location of the top of the scroll bar.
:param y: The y location of the top of the scroll bar.
:param height: The height of the scroll bar.
:param get_pos: A function to return the current position of the scroll bar.
:param set_pos: A function to set the current position of the scroll bar.
:param absolute: Whether the scroll bar should use absolute co-ordinates when handling mouse
events.
The current position for the scroll bar is defined to be 0.0 at the top and 1.0 at the
bottom. The scroll bar will call `get_pos` to find the current position when drawing and
uses `set_pos` to update this position on a mouse click.
The widget using the scroll bar is responsible for maintaining its own state of where the
current view is scrolled (e.g. which is the top line in a text box) and for providing
these two functions to translate that internal state into a form the scroll bar can use.
"""
self._canvas = canvas
self.palette = palette
self.max_height = 0
self._x = x
self._y = y
self._height = height
self._absolute = absolute
self._get_pos = get_pos
self._set_pos = set_pos
def update(self):
"""
Draw the scroll bar.
"""
# Sort out chars
cursor = u"" if self._canvas.unicode_aware else "O"
back = u"" if self._canvas.unicode_aware else "|"
# Now draw...
try:
sb_pos = self._get_pos()
sb_pos = min(1, max(0, sb_pos))
sb_pos = max(int(self._height * sb_pos) - 1, 0)
except ZeroDivisionError:
sb_pos = 0
(colour, attr, bg) = self.palette["scroll"]
y = self._canvas.start_line if self._absolute else 0
for dy in range(self._height):
self._canvas.print_at(cursor if dy == sb_pos else back,
self._x, y + self._y + dy,
colour, attr, bg)
def is_mouse_over(self, event):
"""
Check whether a MouseEvent is over thus scroll bar.
:param event: The MouseEvent to check.
:returns: True if the mouse event is over the scroll bar.
"""
return event.x == self._x and self._y <= event.y < self._y + self._height
def process_event(self, event):
"""
Handle input on the scroll bar.
:param event: the event to be processed.
:returns: True if the scroll bar handled the event.
"""
# Convert into absolute coordinates if needed.
new_event = event
if self._absolute:
new_event.y -= self._canvas.start_line
# Process event if needed.
if self.is_mouse_over(new_event) and event.buttons != 0:
self._set_pos((new_event.y - self._y) / (self._height - 1))
return True
return False