Skip to content

Commit f0318f5

Browse files
committed
Add a parameter to mouse.get_pressed() to pick between 3 and 5 button mice. For backwards compatibility it defaults to 3.
1 parent e2ca1bc commit f0318f5

File tree

5 files changed

+51
-15
lines changed

5 files changed

+51
-15
lines changed

buildconfig/pygame-stubs/mouse.pyi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import Tuple, Union, List, overload, Sequence
22

3-
def get_pressed() -> Tuple[bool, bool, bool, bool, bool]: ...
3+
def get_pressed(num_buttons: int) -> Union[Tuple[bool, bool, bool], Tuple[bool, bool, bool, bool, bool]]: ...
44
def get_pos() -> Tuple[int, int]: ...
55
def get_rel() -> Tuple[int, int]: ...
66
@overload

docs/reST/ref/mouse.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ to access data about the mouse scroll, such as ``which`` (it will tell you what
7373
.. function:: get_pressed
7474

7575
| :sl:`get the state of the mouse buttons`
76-
| :sg:`get_pressed() -> (button1, button2, button3, button4, button5)`
76+
| :sg:`get_pressed(num_buttons=3) -> (button1, button2, button3) or (button1, button2, button3, button4, button5)`
7777
7878
Returns a sequence of booleans representing the state of all the mouse
7979
buttons. A true value means the mouse is currently being pressed at the time
@@ -94,7 +94,8 @@ to access data about the mouse scroll, such as ``which`` (it will tell you what
9494
Note, remember to call ``pygame.event.get()`` before this function.
9595
Otherwise it will not work.
9696

97-
``button4`` & ``button5`` were added to the returned tuple for pygame 2.
97+
To support five button mice, an optional parameter ``num_buttons`` has been added in pygame 2. When this is set to 5
98+
``button4`` & ``button5`` are added to the returned tuple. Only 3 and 5 are valid values for this parameter.
9899
.. versionadded:: 2.0.0
99100

100101
.. ## pygame.mouse.get_pressed ##

src_c/doc/mouse_doc.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* Auto generated file: with makeref.py . Docs go in docs/reST/ref/ . */
22
#define DOC_PYGAMEMOUSE "pygame module to work with the mouse"
3-
#define DOC_PYGAMEMOUSEGETPRESSED "get_pressed() -> (button1, button2, button3, button4, button5)\nget the state of the mouse buttons"
3+
#define DOC_PYGAMEMOUSEGETPRESSED "get_pressed(num_buttons=3) -> (button1, button2, button3) or (button1, button2, button3, button4, button5)\nget the state of the mouse buttons."
44
#define DOC_PYGAMEMOUSEGETPOS "get_pos() -> (x, y)\nget the mouse cursor position"
55
#define DOC_PYGAMEMOUSEGETREL "get_rel() -> (x, y)\nget the amount of mouse movement"
66
#define DOC_PYGAMEMOUSESETPOS "set_pos([x, y]) -> None\nset the mouse cursor position"
@@ -59,4 +59,4 @@ pygame.mouse.get_cursor
5959
get_cursor() -> (size, hotspot, xormasks, andmasks)
6060
get the image of the mouse cursor
6161
62-
*/
62+
*/

src_c/mouse.c

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -134,22 +134,35 @@ mouse_get_rel(PyObject *self)
134134
}
135135

136136
static PyObject *
137-
mouse_get_pressed(PyObject *self)
137+
mouse_get_pressed(PyObject *self, PyObject *args, PyObject *kwargs)
138138
{
139139
PyObject *tuple;
140140
int state;
141+
int num_buttons = 3;
141142

143+
static char *kwids[] = {
144+
"num_buttons",
145+
NULL
146+
};
147+
148+
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwids,
149+
&num_buttons))
150+
return NULL;
142151
VIDEO_INIT_CHECK();
143152

153+
if (num_buttons != 3 && num_buttons != 5)
154+
return RAISE(PyExc_ValueError, "Number of buttons needs to be 3 or 5.");
155+
144156
state = SDL_GetMouseState(NULL, NULL);
145-
if (!(tuple = PyTuple_New(5)))
157+
if (!(tuple = PyTuple_New(num_buttons)))
146158
return NULL;
147159

148-
PyTuple_SET_ITEM(tuple, 0, PyBool_FromLong((state & SDL_BUTTON_LMASK) != 0));
149-
PyTuple_SET_ITEM(tuple, 1, PyBool_FromLong((state & SDL_BUTTON_MMASK) != 0));
150-
PyTuple_SET_ITEM(tuple, 2, PyBool_FromLong((state & SDL_BUTTON_RMASK) != 0));
151-
PyTuple_SET_ITEM(tuple, 3, PyBool_FromLong((state & SDL_BUTTON_X1MASK) != 0));
152-
PyTuple_SET_ITEM(tuple, 4, PyBool_FromLong((state & SDL_BUTTON_X2MASK) != 0));
160+
PyTuple_SET_ITEM(tuple, 0, PyBool_FromLong((state & SDL_BUTTON_LMASK) != 0));
161+
PyTuple_SET_ITEM(tuple, 1, PyBool_FromLong((state & SDL_BUTTON_MMASK) != 0));
162+
PyTuple_SET_ITEM(tuple, 2, PyBool_FromLong((state & SDL_BUTTON_RMASK) != 0));
163+
if (num_buttons == 5)
164+
PyTuple_SET_ITEM(tuple, 3, PyBool_FromLong((state & SDL_BUTTON_X1MASK) != 0));
165+
PyTuple_SET_ITEM(tuple, 4, PyBool_FromLong((state & SDL_BUTTON_X2MASK) != 0));
153166

154167
return tuple;
155168
}
@@ -355,8 +368,8 @@ static PyMethodDef _mouse_methods[] = {
355368
DOC_PYGAMEMOUSEGETPOS},
356369
{"get_rel", (PyCFunction)mouse_get_rel, METH_VARARGS,
357370
DOC_PYGAMEMOUSEGETREL},
358-
{"get_pressed", (PyCFunction)mouse_get_pressed, METH_VARARGS,
359-
DOC_PYGAMEMOUSEGETPRESSED},
371+
{"get_pressed", (PyCFunction)mouse_get_pressed,
372+
METH_VARARGS | METH_KEYWORDS, DOC_PYGAMEMOUSEGETPRESSED},
360373
{"set_visible", mouse_set_visible, METH_VARARGS,
361374
DOC_PYGAMEMOUSESETVISIBLE},
362375
{"get_visible", mouse_get_visible, METH_NOARGS, DOC_PYGAMEMOUSEGETVISIBLE},

test/mouse_test.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,15 +257,37 @@ def test_get_focused(self):
257257

258258
def test_get_pressed(self):
259259
"""Ensures get_pressed returns the correct types."""
260+
expected_length = 3
261+
buttons_pressed = pygame.mouse.get_pressed()
262+
self.assertIsInstance(buttons_pressed, tuple)
263+
self.assertEqual(len(buttons_pressed), expected_length)
264+
for value in buttons_pressed:
265+
self.assertIsInstance(value, bool)
266+
260267
expected_length = 5
268+
buttons_pressed = pygame.mouse.get_pressed(num_buttons=5)
269+
self.assertIsInstance(buttons_pressed, tuple)
270+
self.assertEqual(len(buttons_pressed), expected_length)
271+
for value in buttons_pressed:
272+
self.assertIsInstance(value, bool)
261273

262-
buttons_pressed = pygame.mouse.get_pressed()
274+
expected_length = 3
275+
buttons_pressed = pygame.mouse.get_pressed(3)
276+
self.assertIsInstance(buttons_pressed, tuple)
277+
self.assertEqual(len(buttons_pressed), expected_length)
278+
for value in buttons_pressed:
279+
self.assertIsInstance(value, bool)
263280

281+
expected_length = 5
282+
buttons_pressed = pygame.mouse.get_pressed(5)
264283
self.assertIsInstance(buttons_pressed, tuple)
265284
self.assertEqual(len(buttons_pressed), expected_length)
266285
for value in buttons_pressed:
267286
self.assertIsInstance(value, bool)
268287

288+
with self.assertRaises(ValueError):
289+
pygame.mouse.get_pressed(4)
290+
269291
def test_get_pos(self):
270292
"""Ensures get_pos returns the correct types."""
271293
expected_length = 2

0 commit comments

Comments
 (0)