Skip to content

Commit 8e7dd8b

Browse files
committed
Add mouse button/mask enums.
Continuing to replace loose constants with enums.
1 parent a7372fb commit 8e7dd8b

File tree

3 files changed

+81
-45
lines changed

3 files changed

+81
-45
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,15 @@ Changes relevant to the users of python-tcod are documented here.
44
This project adheres to [Semantic Versioning](https://semver.org/) since version `2.0.0`.
55

66
## [Unreleased]
7+
### Added
8+
- Added the enums `tcod.event.MouseButton` and `tcod.event.MouseButtonMask`.
9+
710
### Changed
811
- Using `libtcod 1.24.0`.
912

13+
### Deprecated
14+
- Mouse button and mask constants have been replaced by enums.
15+
1016
### Fixed
1117
- `WindowResized` literal annotations were in the wrong case.
1218

tcod/event.py

Lines changed: 68 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -240,46 +240,48 @@ class Modifier(enum.IntFlag):
240240
"""Alt graph."""
241241

242242

243-
# manually define names for SDL macros
244-
BUTTON_LEFT = 1
245-
BUTTON_MIDDLE = 2
246-
BUTTON_RIGHT = 3
247-
BUTTON_X1 = 4
248-
BUTTON_X2 = 5
249-
BUTTON_LMASK = 0x1
250-
BUTTON_MMASK = 0x2
251-
BUTTON_RMASK = 0x4
252-
BUTTON_X1MASK = 0x8
253-
BUTTON_X2MASK = 0x10
254-
255-
# reverse tables are used to get the tcod.event name from the value.
256-
_REVERSE_BUTTON_TABLE = {
257-
BUTTON_LEFT: "BUTTON_LEFT",
258-
BUTTON_MIDDLE: "BUTTON_MIDDLE",
259-
BUTTON_RIGHT: "BUTTON_RIGHT",
260-
BUTTON_X1: "BUTTON_X1",
261-
BUTTON_X2: "BUTTON_X2",
262-
}
243+
class MouseButton(enum.IntEnum):
244+
"""An enum for mouse buttons.
263245
264-
_REVERSE_BUTTON_MASK_TABLE = {
265-
BUTTON_LMASK: "BUTTON_LMASK",
266-
BUTTON_MMASK: "BUTTON_MMASK",
267-
BUTTON_RMASK: "BUTTON_RMASK",
268-
BUTTON_X1MASK: "BUTTON_X1MASK",
269-
BUTTON_X2MASK: "BUTTON_X2MASK",
270-
}
246+
.. versionadded:: Unreleased
247+
"""
248+
249+
LEFT = 1
250+
"""Left mouse button."""
251+
MIDDLE = 2
252+
"""Middle mouse button."""
253+
RIGHT = 3
254+
"""Right mouse button."""
255+
X1 = 4
256+
"""Back mouse button."""
257+
X2 = 5
258+
"""Forward mouse button."""
259+
260+
def __repr__(self) -> str:
261+
return f"{self.__class__.__name__}.{self.name}"
271262

272-
_REVERSE_BUTTON_TABLE_PREFIX = _ConstantsWithPrefix(_REVERSE_BUTTON_TABLE)
273-
_REVERSE_BUTTON_MASK_TABLE_PREFIX = _ConstantsWithPrefix(_REVERSE_BUTTON_MASK_TABLE)
274263

264+
class MouseButtonMask(enum.IntFlag):
265+
"""A mask enum for held mouse buttons.
275266
276-
_REVERSE_MOD_TABLE = tcod.event_constants._REVERSE_MOD_TABLE.copy()
277-
del _REVERSE_MOD_TABLE[KMOD_SHIFT]
278-
del _REVERSE_MOD_TABLE[KMOD_CTRL]
279-
del _REVERSE_MOD_TABLE[KMOD_ALT]
280-
del _REVERSE_MOD_TABLE[KMOD_GUI]
267+
.. versionadded:: Unreleased
268+
"""
281269

282-
_REVERSE_MOD_TABLE_PREFIX = _ConstantsWithPrefix(_REVERSE_MOD_TABLE)
270+
LEFT = 0x1
271+
"""Left mouse button is held."""
272+
MIDDLE = 0x2
273+
"""Middle mouse button is held."""
274+
RIGHT = 0x4
275+
"""Right mouse button is held."""
276+
X1 = 0x8
277+
"""Back mouse button is held."""
278+
X2 = 0x10
279+
"""Forward mouse button is held."""
280+
281+
def __repr__(self) -> str:
282+
if self == 0:
283+
return f"{self.__class__.__name__}(0)"
284+
return "|".join(f"{self.__class__.__name__}.{self.__class__(bit).name}" for bit in self.__class__ if bit & self)
283285

284286

285287
class Event:
@@ -361,11 +363,11 @@ def from_sdl_event(cls, sdl_event: Any) -> Any:
361363
return self
362364

363365
def __repr__(self) -> str:
364-
return "tcod.event.{}(scancode={!r}, sym={!r}, mod={}{})".format(
366+
return "tcod.event.{}(scancode={!r}, sym={!r}, mod={!r}{})".format(
365367
self.__class__.__name__,
366368
self.scancode,
367369
self.sym,
368-
_describe_bitmask(self.mod, _REVERSE_MOD_TABLE_PREFIX),
370+
self.mod,
369371
", repeat=True" if self.repeat else "",
370372
)
371373

@@ -446,15 +448,15 @@ def __repr__(self) -> str:
446448
self.__class__.__name__,
447449
tuple(self.position),
448450
tuple(self.tile),
449-
_describe_bitmask(self.state, _REVERSE_BUTTON_MASK_TABLE_PREFIX),
451+
MouseButtonMask(self.state),
450452
)
451453

452454
def __str__(self) -> str:
453455
return ("<%s, position=(x=%i, y=%i), tile=(x=%i, y=%i), state=%s>") % (
454456
super().__str__().strip("<>"),
455457
*self.position,
456458
*self.tile,
457-
_describe_bitmask(self.state, _REVERSE_BUTTON_MASK_TABLE),
459+
MouseButtonMask(self.state),
458460
)
459461

460462

@@ -552,13 +554,13 @@ def from_sdl_event(cls, sdl_event: Any) -> MouseMotion:
552554
return self
553555

554556
def __repr__(self) -> str:
555-
return ("tcod.event.{}(position={!r}, motion={!r}, tile={!r}, tile_motion={!r}, state={})").format(
557+
return ("tcod.event.{}(position={!r}, motion={!r}, tile={!r}, tile_motion={!r}, state={!r})").format(
556558
self.__class__.__name__,
557559
tuple(self.position),
558560
tuple(self.motion),
559561
tuple(self.tile),
560562
tuple(self.tile_motion),
561-
_describe_bitmask(self.state, _REVERSE_BUTTON_MASK_TABLE_PREFIX),
563+
MouseButtonMask(self.state),
562564
)
563565

564566
def __str__(self) -> str:
@@ -619,19 +621,19 @@ def from_sdl_event(cls, sdl_event: Any) -> Any:
619621
return self
620622

621623
def __repr__(self) -> str:
622-
return "tcod.event.{}(position={!r}, tile={!r}, button={})".format(
624+
return "tcod.event.{}(position={!r}, tile={!r}, button={!r})".format(
623625
self.__class__.__name__,
624626
tuple(self.position),
625627
tuple(self.tile),
626-
_REVERSE_BUTTON_TABLE_PREFIX[self.button],
628+
MouseButton(self.button),
627629
)
628630

629631
def __str__(self) -> str:
630-
return "<type=%r, position=(x=%i, y=%i), tile=(x=%i, y=%i), button=%s)" % (
632+
return "<type=%r, position=(x=%i, y=%i), tile=(x=%i, y=%i), button=%r)" % (
631633
self.type,
632634
*self.position,
633635
*self.tile,
634-
_REVERSE_BUTTON_TABLE[self.button],
636+
MouseButton(self.button),
635637
)
636638

637639

@@ -2779,6 +2781,27 @@ def __repr__(self) -> str:
27792781

27802782
def __getattr__(name: str) -> int:
27812783
"""Migrate deprecated access of event constants."""
2784+
if name.startswith("BUTTON_"):
2785+
replacement = {
2786+
"BUTTON_LEFT": MouseButton.LEFT,
2787+
"BUTTON_MIDDLE": MouseButton.MIDDLE,
2788+
"BUTTON_RIGHT": MouseButton.RIGHT,
2789+
"BUTTON_X1": MouseButton.X1,
2790+
"BUTTON_X2": MouseButton.X2,
2791+
"BUTTON_LMASK": MouseButtonMask.LEFT,
2792+
"BUTTON_MMASK": MouseButtonMask.MIDDLE,
2793+
"BUTTON_RMASK": MouseButtonMask.RIGHT,
2794+
"BUTTON_X1MASK": MouseButtonMask.X1,
2795+
"BUTTON_X2MASK": MouseButtonMask.X2,
2796+
}[name]
2797+
warnings.warn(
2798+
"Key constants have been replaced with enums.\n"
2799+
f"'tcod.event.{name}' should be replaced with 'tcod.event.{replacement!r}'",
2800+
FutureWarning,
2801+
stacklevel=2,
2802+
)
2803+
return replacement
2804+
27822805
value: int | None = getattr(tcod.event_constants, name, None)
27832806
if not value:
27842807
msg = f"module {__name__!r} has no attribute {name!r}"

tests/test_deprecated.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,13 @@ def test_deprecate_key_constants() -> None:
4242
_ = tcod.event.SCANCODE_1
4343

4444

45+
def test_deprecate_mouse_constants() -> None:
46+
with pytest.warns(FutureWarning, match=r"MouseButton.LEFT"):
47+
_ = tcod.event.BUTTON_LEFT
48+
with pytest.warns(FutureWarning, match=r"MouseButtonMask.LEFT"):
49+
_ = tcod.event.BUTTON_LMASK
50+
51+
4552
def test_line_where() -> None:
4653
with pytest.warns():
4754
where = tcod.libtcodpy.line_where(1, 0, 3, 4)

0 commit comments

Comments
 (0)