diff --git a/squirrelbattle/display/creditsdisplay.py b/squirrelbattle/display/creditsdisplay.py index a97c10e..93f2f72 100644 --- a/squirrelbattle/display/creditsdisplay.py +++ b/squirrelbattle/display/creditsdisplay.py @@ -92,6 +92,6 @@ class CreditsDisplay(Display): self.addstr(self.pad, y_offset + i, x_offset + j, c, fg_color, bg_color, bold=bold) - def handle_click(self, y: int, x: int, game: Game) -> None: + def handle_click(self, y: int, x: int, attr: int, game: Game) -> None: if self.pad.inch(y - 1, x - 1) != ord(" "): self.ascii_art_displayed = True diff --git a/squirrelbattle/display/display.py b/squirrelbattle/display/display.py index 3f9e08f..17d8c29 100644 --- a/squirrelbattle/display/display.py +++ b/squirrelbattle/display/display.py @@ -190,12 +190,11 @@ class Display: """ raise NotImplementedError - def handle_click(self, y: int, x: int, game: Game) -> None: + def handle_click(self, y: int, x: int, attr: int, game: Game) -> None: """ A mouse click was performed on the coordinates (y, x) of the pad. Maybe it should do something. """ - pass @property def rows(self) -> int: diff --git a/squirrelbattle/display/display_manager.py b/squirrelbattle/display/display_manager.py index 0042615..a1d2ed9 100644 --- a/squirrelbattle/display/display_manager.py +++ b/squirrelbattle/display/display_manager.py @@ -63,7 +63,7 @@ class DisplayManager: d.pack = TexturePack.get_pack(self.game.settings.TEXTURE_PACK) d.update(self.game) - def handle_mouse_click(self, y: int, x: int) -> None: + def handle_mouse_click(self, y: int, x: int, attr: int) -> None: """ Handles the mouse clicks. """ @@ -76,7 +76,7 @@ class DisplayManager: # of that display display = d if display: - display.handle_click(y - display.y, x - display.x, self.game) + display.handle_click(y - display.y, x - display.x, attr, self.game) def refresh(self) -> List[Display]: """ diff --git a/squirrelbattle/display/menudisplay.py b/squirrelbattle/display/menudisplay.py index cc73010..6c4d991 100644 --- a/squirrelbattle/display/menudisplay.py +++ b/squirrelbattle/display/menudisplay.py @@ -50,7 +50,7 @@ class MenuDisplay(Display): self.height - 2 + self.y, self.width - 2 + self.x) - def handle_click(self, y: int, x: int, game: Game) -> None: + def handle_click(self, y: int, x: int, attr: int, game: Game) -> None: """ We can select a menu item with the mouse. """ @@ -134,13 +134,13 @@ class MainMenuDisplay(Display): def update(self, game: Game) -> None: self.menudisplay.update_menu(game.main_menu) - def handle_click(self, y: int, x: int, game: Game) -> None: + def handle_click(self, y: int, x: int, attr: int, game: Game) -> None: menuwidth = min(self.menudisplay.preferred_width, self.width) menuy, menux = len(self.title) + 8, self.width // 2 - menuwidth // 2 - 1 menuheight = min(self.menudisplay.preferred_height, self.height - menuy) if menuy <= y < menuy + menuheight and menux <= x < menux + menuwidth: - self.menudisplay.handle_click(y - menuy, x - menux, game) + self.menudisplay.handle_click(y - menuy, x - menux, attr, game) if y <= len(self.title): self.fg_color = randint(0, 1000), randint(0, 1000), randint(0, 1000) @@ -189,7 +189,7 @@ class PlayerInventoryDisplay(MenuDisplay): def trueheight(self) -> int: return 2 + super().trueheight - def handle_click(self, y: int, x: int, game: Game) -> None: + def handle_click(self, y: int, x: int, attr: int, game: Game) -> None: """ We can select a menu item with the mouse. """ @@ -232,7 +232,7 @@ class StoreInventoryDisplay(MenuDisplay): def trueheight(self) -> int: return 2 + super().trueheight - def handle_click(self, y: int, x: int, game: Game) -> None: + def handle_click(self, y: int, x: int, attr: int, game: Game) -> None: """ We can select a menu item with the mouse. """ diff --git a/squirrelbattle/game.py b/squirrelbattle/game.py index ecdfccb..ba8493f 100644 --- a/squirrelbattle/game.py +++ b/squirrelbattle/game.py @@ -94,10 +94,14 @@ class Game: screen.noutrefresh() self.display_actions(DisplayActions.REFRESH) curses.doupdate() - key = screen.getkey() + try: + key = screen.getkey() + except KeyboardInterrupt: + exit(0) + return if key == "KEY_MOUSE": - _ignored1, x, y, _ignored2, _ignored3 = curses.getmouse() - self.display_actions(DisplayActions.MOUSE, y, x) + _ignored1, x, y, _ignored2, attr = curses.getmouse() + self.display_actions(DisplayActions.MOUSE, y, x, attr) else: self.handle_key_pressed( KeyValues.translate_key(key, self.settings), key) diff --git a/squirrelbattle/settings.py b/squirrelbattle/settings.py index b5e2c14..549fc5f 100644 --- a/squirrelbattle/settings.py +++ b/squirrelbattle/settings.py @@ -73,7 +73,8 @@ class Settings: """ d = json.loads(json_str) for key in d: - setattr(self, key, d[key]) + if hasattr(self, key): + setattr(self, key, d[key]) def dumps_to_string(self) -> str: """ diff --git a/squirrelbattle/term_manager.py b/squirrelbattle/term_manager.py index 6484289..2e74fff 100644 --- a/squirrelbattle/term_manager.py +++ b/squirrelbattle/term_manager.py @@ -21,7 +21,7 @@ class TermManager: # pragma: no cover # make cursor invisible curses.curs_set(False) # Catch mouse events - curses.mousemask(True) + curses.mousemask(curses.ALL_MOUSE_EVENTS | curses.REPORT_MOUSE_POSITION) # Enable colors curses.start_color() diff --git a/squirrelbattle/tests/game_test.py b/squirrelbattle/tests/game_test.py index 0843ae8..dab0e7e 100644 --- a/squirrelbattle/tests/game_test.py +++ b/squirrelbattle/tests/game_test.py @@ -1,6 +1,6 @@ # Copyright (C) 2020 by ÿnérant, eichhornchen, nicomarg, charlse # SPDX-License-Identifier: GPL-3.0-or-later - +import curses import os import random import unittest @@ -257,10 +257,12 @@ class TestGame(unittest.TestCase): self.game.state = GameMode.MAINMENU # Change the color of the artwork - self.game.display_actions(DisplayActions.MOUSE, 0, 10) + self.game.display_actions(DisplayActions.MOUSE, 0, 10, + curses.BUTTON1_CLICKED) # Settings menu - self.game.display_actions(DisplayActions.MOUSE, 25, 21) + self.game.display_actions(DisplayActions.MOUSE, 25, 21, + curses.BUTTON1_CLICKED) self.assertEqual(self.game.main_menu.position, 4) self.assertEqual(self.game.state, GameMode.SETTINGS) @@ -272,11 +274,13 @@ class TestGame(unittest.TestCase): self.game.state = GameMode.INVENTORY # Click nowhere - self.game.display_actions(DisplayActions.MOUSE, 0, 0) + self.game.display_actions(DisplayActions.MOUSE, 0, 0, + curses.BUTTON1_CLICKED) self.assertEqual(self.game.state, GameMode.INVENTORY) # Click on the second item - self.game.display_actions(DisplayActions.MOUSE, 8, 25) + self.game.display_actions(DisplayActions.MOUSE, 8, 25, + curses.BUTTON1_CLICKED) self.assertEqual(self.game.state, GameMode.INVENTORY) self.assertEqual(self.game.inventory_menu.position, 1) @@ -572,7 +576,8 @@ class TestGame(unittest.TestCase): # Buy the second item by clicking on it item = self.game.store_menu.validate() self.assertIn(item, merchant.inventory) - self.game.display_actions(DisplayActions.MOUSE, 7, 25) + self.game.display_actions(DisplayActions.MOUSE, 7, 25, + curses.BUTTON1_CLICKED) self.assertIn(item, self.game.player.inventory) self.assertNotIn(item, merchant.inventory) @@ -747,9 +752,11 @@ class TestGame(unittest.TestCase): """ self.game.state = GameMode.MAINMENU - self.game.display_actions(DisplayActions.MOUSE, 41, 41) + self.game.display_actions(DisplayActions.MOUSE, 41, 41, + curses.BUTTON1_CLICKED) self.assertEqual(self.game.state, GameMode.CREDITS) - self.game.display_actions(DisplayActions.MOUSE, 21, 21) + self.game.display_actions(DisplayActions.MOUSE, 21, 21, + curses.BUTTON1_CLICKED) self.game.display_actions(DisplayActions.REFRESH) self.game.state = GameMode.CREDITS