You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
62 lines
2.3 KiB
62 lines
2.3 KiB
import pyray as rl
|
|
from cffi import FFI
|
|
|
|
MOUSE_WHEEL_SCROLL_SPEED = 30
|
|
INERTIA_FRICTION = 0.95 # The rate at which the inertia slows down
|
|
MIN_VELOCITY = 0.1 # Minimum velocity before stopping the inertia
|
|
|
|
|
|
class GuiScrollPanel:
|
|
def __init__(self, bounds: rl.Rectangle, content: rl.Rectangle, show_vertical_scroll_bar: bool = False):
|
|
self._dragging: bool = False
|
|
self._last_mouse_y: float = 0.0
|
|
self._bounds = bounds
|
|
self._content = content
|
|
self._scroll = rl.Vector2(0, 0)
|
|
self._view = rl.Rectangle(0, 0, 0, 0)
|
|
self._show_vertical_scroll_bar: bool = show_vertical_scroll_bar
|
|
self._velocity_y = 0.0 # Velocity for inertia
|
|
|
|
def handle_scroll(self) -> rl.Vector2:
|
|
mouse_pos = rl.get_mouse_position()
|
|
|
|
# Handle dragging logic
|
|
if rl.check_collision_point_rec(mouse_pos, self._bounds) and rl.is_mouse_button_pressed(rl.MouseButton.MOUSE_BUTTON_LEFT):
|
|
if not self._dragging:
|
|
self._dragging = True
|
|
self._last_mouse_y = mouse_pos.y
|
|
self._velocity_y = 0.0 # Reset velocity when drag starts
|
|
|
|
if self._dragging:
|
|
if rl.is_mouse_button_down(rl.MouseButton.MOUSE_BUTTON_LEFT):
|
|
delta_y = mouse_pos.y - self._last_mouse_y
|
|
self._scroll.y += delta_y
|
|
self._last_mouse_y = mouse_pos.y
|
|
self._velocity_y = delta_y # Update velocity during drag
|
|
else:
|
|
self._dragging = False
|
|
|
|
# Handle mouse wheel scrolling
|
|
wheel_move = rl.get_mouse_wheel_move()
|
|
if self._show_vertical_scroll_bar:
|
|
self._scroll.y += wheel_move * (MOUSE_WHEEL_SCROLL_SPEED - 20)
|
|
rl.gui_scroll_panel(self._bounds, FFI().NULL, self._content, self._scroll, self._view)
|
|
else:
|
|
self._scroll.y += wheel_move * MOUSE_WHEEL_SCROLL_SPEED
|
|
max_scroll_y = self._content.height - self._bounds.height
|
|
self._scroll.y = max(min(self._scroll.y, 0), -max_scroll_y)
|
|
|
|
# Apply inertia (continue scrolling after mouse release)
|
|
if not self._dragging:
|
|
self._scroll.y += self._velocity_y
|
|
self._velocity_y *= INERTIA_FRICTION # Slow down velocity over time
|
|
|
|
# Stop scrolling when velocity is low
|
|
if abs(self._velocity_y) < MIN_VELOCITY:
|
|
self._velocity_y = 0.0
|
|
|
|
# Ensure scrolling doesn't go beyond bounds
|
|
max_scroll_y = max(self._content.height - self._bounds.height, 0)
|
|
self._scroll.y = max(min(self._scroll.y, 0), -max_scroll_y)
|
|
|
|
return self._scroll
|
|
|