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
 | 
						|
 |