Source code for sdl2.ext.mouse

from ctypes import c_int, byref
from collections import namedtuple
from .compat import stringify, utf8
from .err import SDLError, raise_sdl_err
from .window import _get_sdl_window
from .. import mouse
from ..events import SDL_ENABLE, SDL_DISABLE, SDL_QUERY

__all__ = [
    "show_cursor", "hide_cursor", "cursor_hidden", "mouse_coords", "mouse_delta",
    "warp_mouse", "mouse_button_state", "ButtonState",
]


[docs]class ButtonState(object): """A class representing the state of the mouse buttons. Args: buttonmask (int): The raw SDL button mask to parse. Attributes: raw (int): The raw SDL button mask representing the button state. """ def __init__(self, buttonmask): self.raw = buttonmask def __repr__(self): s = "ButtonState(l={0}, r={1}, m={2})" return s.format(self.left, self.right, self.middle) def __eq__(self, s2): return self.raw == s2.raw def __ne__(self, s2): return self.raw != s2.raw def _check_button(self, bmask): return int(bool(self.raw & bmask)) @property def any_pressed(self): """bool: True if any buttons are currently pressed, otherwise False. """ return self.raw != 0 @property def left(self): """int: The state of the left mouse button (0 = up, 1 = down). """ return self._check_button(mouse.SDL_BUTTON_LMASK) @property def right(self): """int: The state of the right mouse button (0 = up, 1 = down). """ return self._check_button(mouse.SDL_BUTTON_RMASK) @property def middle(self): """int: The state of the middle mouse button (0 = up, 1 = down). """ return self._check_button(mouse.SDL_BUTTON_MMASK) @property def x1(self): """int: The state of the first extra mouse button (0 = up, 1 = down). """ return self._check_button(mouse.SDL_BUTTON_X1MASK) @property def x2(self): """int: The state of the second extra mouse button (0 = up, 1 = down). """ return self._check_button(mouse.SDL_BUTTON_X2MASK)
[docs]def show_cursor(): """Unhides the mouse cursor if it is currently hidden. """ ret = mouse.SDL_ShowCursor(SDL_ENABLE) if ret < 0: raise_sdl_err("showing the mouse cursor")
[docs]def hide_cursor(): """Hides the mouse cursor if it is currently visible. """ ret = mouse.SDL_ShowCursor(SDL_DISABLE) if ret < 0: raise_sdl_err("hiding the mouse cursor")
[docs]def cursor_hidden(): """Checks whether the mouse cursor is currently visible. Returns: bool: True if the cursor is hidden, otherwise False. """ return mouse.SDL_ShowCursor(SDL_QUERY) == SDL_DISABLE
[docs]def mouse_coords(desktop=False): """Get the current x/y coordinates of the mouse cursor. By default, this function reports the coordinates relative to the top-left corner of the SDL window that currently has focus. To obtain the mouse coordinates relative to the top-right corner of the full desktop, this function can optionally be called with ``desktop`` argument set to True. Args: desktop (bool, optional): If True, reports the mouse coordinates relative to the full desktop instead of the currently-focused SDL window. Defaults to False. Returns: tuple: The current (x, y) coordinates of the mouse cursor. """ x, y = c_int(0), c_int(0) if desktop: mouse.SDL_GetGlobalMouseState(byref(x), byref(y)) else: mouse.SDL_GetMouseState(byref(x), byref(y)) return (int(x.value), int(y.value))
[docs]def mouse_button_state(): """Gets the current state of each button of the mouse. Mice in SDL are currently able to have up to 5 buttons: left, right, middle, and two extras (x1 and x2). You can check each of these individually, or alternatively check whether any buttons have been pressed:: bstate = mouse_button_state() if bstate.any_pressed: if bstate.left == 1: print("left button down!") if bstate.right == 1: print("right button down!") Returns: :obj:`ButtonState`: A representation of the current button state of the mouse. """ x, y = c_int(0), c_int(0) bmask = mouse.SDL_GetMouseState(byref(x), byref(y)) return ButtonState(bmask)
[docs]def mouse_delta(): """Get the relative change in cursor position since last checked. The first time this function is called, it will report the (x, y) change in cursor position since the SDL video or event system was initialized. Subsequent calls to this function report the change in position since the previous time the function was called. Returns: tuple: The (x, y) change in cursor coordinates since the function was last called. """ x, y = c_int(0), c_int(0) mouse.SDL_GetRelativeMouseState(byref(x), byref(y)) return (int(x.value), int(y.value))
[docs]def warp_mouse(x, y, window=None, desktop=False): """Warps the mouse cursor to a given location on the screen. By default, this warps the mouse cursor relative to the top-left corner of whatever SDL window currently has mouse focus. For example,:: warp_mouse(400, 300) would warp the mouse to the middle of a 800x600 SDL window. Alternatively, the cursor can be warped within a specific SDL window or relative to the full desktop. .. NOTE: For security reasons, the Wayland protocol does not allow programs to change the cursor position. However, it is possible to warp the cursor when using XWayland (the default for SDL2). Args: x (int): The new X position for the mouse cursor. y (int): The new Y position for the mouse cursor. window (:obj:`SDL_Window` or :obj:`~sdl2.ext.Window`, optional): The SDL window within which to warp the mouse cursor. If not specified (the default), the cursor will be warped within the SDL window that currently has mouse focus. desktop (bool, optional): If True, the mouse cursor will be warped relative to the full desktop instead of the current SDL window. Defaults to False. """ if desktop: ret = mouse.SDL_WarpMouseGlobal(x, y) if ret < 0: raise_sdl_err("warping the mouse cursor") else: if window is not None: window = _get_sdl_window(window) mouse.SDL_WarpMouseInWindow(window, x, y)