added a Widget system with a Button widget example
This commit is contained in:
parent
b902d83d90
commit
eff0218c8f
30 changed files with 409 additions and 89 deletions
BIN
assets/test_button_hover.png
Normal file
BIN
assets/test_button_hover.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 224 B |
BIN
assets/test_button_normal.png
Normal file
BIN
assets/test_button_normal.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 224 B |
|
@ -1,22 +0,0 @@
|
|||
from typing import Optional
|
||||
|
||||
import pyglet
|
||||
|
||||
from gui.scene import Scene
|
||||
from gui.window import Window
|
||||
|
||||
|
||||
class FPSCounterScene(Scene):
|
||||
"""
|
||||
This scene represent a simple FPS Counter.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.fps_display: Optional[pyglet.window.FPSDisplay] = None
|
||||
|
||||
def on_window_added(self, window: Window):
|
||||
# the fps display need to be defined here because it is the moment where the window is first accessible
|
||||
self.fps_display = pyglet.window.FPSDisplay(window=window)
|
||||
|
||||
def on_draw(self, window: Window) -> None:
|
||||
self.fps_display.draw()
|
|
@ -1,43 +0,0 @@
|
|||
import pyglet.event
|
||||
|
||||
from gui.window import Window
|
||||
|
||||
|
||||
class Scene(pyglet.event.EventDispatcher):
|
||||
"""
|
||||
This class represent a scene that can be applied to a pyglet window.
|
||||
|
||||
The scene can represent anything like the main menu, the game, the
|
||||
options' menu, the multiplayer menu, ...
|
||||
"""
|
||||
|
||||
def on_window_added(self, window: Window): pass # when the Scene is added to a window
|
||||
def on_window_removed(self, window: Window): pass # when the Scene is removed from a window
|
||||
|
||||
def on_draw(self, window: Window): pass
|
||||
def on_resize(self, window: Window, width: int, height: int): pass
|
||||
def on_hide(self, window: Window): pass
|
||||
def on_show(self, window: Window): pass
|
||||
def on_close(self, window: Window): pass
|
||||
def on_expose(self, window: Window): pass
|
||||
def on_activate(self, window: Window): pass
|
||||
def on_deactivate(self, window: Window): pass
|
||||
def on_text(self, window: Window, char: str): pass
|
||||
def on_move(self, window: Window, x: int, y: int): pass
|
||||
def on_context_lost(self, window: Window): pass
|
||||
def on_context_state_lost(self, window: Window): pass
|
||||
def on_key_press(self, window: Window, symbol: int, modifiers: int): pass
|
||||
def on_key_release(self, window: Window, symbol: int, modifiers: int): pass
|
||||
def on_key_held(self, window: Window, dt: float, symbol: int, modifiers: int): pass
|
||||
def on_mouse_enter(self, window: Window, x: int, y: int): pass
|
||||
def on_mouse_leave(self, window: Window, x: int, y: int): pass
|
||||
def on_text_motion(self, window: Window, motion: int): pass
|
||||
def on_text_motion_select(self, window: Window, motion: int): pass
|
||||
def on_mouse_motion(self, window: Window, x: int, y: int, dx: int, dy: int): pass
|
||||
def on_mouse_press(self, window: Window, x: int, y: int, button: int, modifiers: int): pass
|
||||
def on_mouse_release(self, window: Window, x: int, y: int, button: int, modifiers: int): pass
|
||||
def on_mouse_drag(self, window: Window, x: int, y: int, dx: int, dy: int, buttons: int, modifiers: int): pass
|
||||
def on_mouse_scroll(self, window: Window, x: int, y: int, scroll_x: float, scroll_y: float): pass
|
||||
|
||||
|
||||
|
23
main.pyw
23
main.pyw
|
@ -1,12 +1,29 @@
|
|||
import pyglet
|
||||
|
||||
from gui.window import Window
|
||||
from gui.scene import HelloWorldScene, FPSCounterScene
|
||||
from source.gui.widget.Button import Button
|
||||
from source.gui.window import Window
|
||||
from source.gui.scene import HelloWorldScene, FPSCounterScene
|
||||
|
||||
# Créer une fenêtre
|
||||
window = Window(resizable=True, visible=False)
|
||||
|
||||
window.add_scene(HelloWorldScene(), FPSCounterScene())
|
||||
button_normal_image = pyglet.image.load("./assets/test_button_normal.png")
|
||||
button_hover_image = pyglet.image.load("./assets/test_button_hover.png")
|
||||
|
||||
hello_world_scene = HelloWorldScene()
|
||||
|
||||
button = Button(
|
||||
50, 50, 300, 100,
|
||||
text="HELLO",
|
||||
on_release=lambda *a, **b: print(a, b),
|
||||
normal_image=button_normal_image,
|
||||
hover_image=button_hover_image,
|
||||
)
|
||||
|
||||
hello_world_scene.add_widget(button)
|
||||
fps_counter_scene = FPSCounterScene()
|
||||
|
||||
window.add_scene(hello_world_scene, fps_counter_scene)
|
||||
|
||||
# Lance la fenêtre
|
||||
window.set_visible(True)
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
from .Boat import Boat
|
||||
from .Board import Board
|
|
@ -1,8 +1,8 @@
|
|||
import numpy as np
|
||||
|
||||
from source import Boat
|
||||
from source.enums import Orientation, BombState
|
||||
from source.error import InvalidBoatPosition, PositionAlreadyShot
|
||||
from source.core import Boat
|
||||
from source.core.enums import Orientation, BombState
|
||||
from source.core.error import InvalidBoatPosition, PositionAlreadyShot
|
||||
from source.utils import copy_array_offset
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
import numpy as np
|
||||
|
||||
from source.enums import Orientation
|
||||
from source.core.enums import Orientation
|
||||
|
||||
|
||||
class Boat:
|
0
source/gui/__init__.py
Normal file
0
source/gui/__init__.py
Normal file
30
source/gui/scene/FPSCounterScene.py
Normal file
30
source/gui/scene/FPSCounterScene.py
Normal file
|
@ -0,0 +1,30 @@
|
|||
from typing import Optional, TYPE_CHECKING
|
||||
|
||||
import pyglet
|
||||
|
||||
from source.gui.scene.base import Scene
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from source.gui.window import Window
|
||||
|
||||
|
||||
class FPSCounterScene(Scene):
|
||||
"""
|
||||
This scene represent a simple FPS Counter.
|
||||
"""
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.fps_display: Optional[pyglet.window.FPSDisplay] = None
|
||||
|
||||
def on_window_added(self, window: "Window"):
|
||||
super().on_window_added(window)
|
||||
|
||||
# the fps display need to be defined here because it is the moment where the window is first accessible
|
||||
self.fps_display = pyglet.window.FPSDisplay(window=window)
|
||||
|
||||
def on_draw(self, window: "Window") -> None:
|
||||
super().on_draw(window)
|
||||
|
||||
self.fps_display.draw()
|
|
@ -2,8 +2,12 @@ from datetime import datetime, timedelta
|
|||
|
||||
import pyglet
|
||||
|
||||
from gui.scene import Scene
|
||||
from gui.window import Window
|
||||
from source.gui.scene.base import Scene
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from source.gui.window import Window
|
||||
|
||||
|
||||
class HelloWorldScene(Scene):
|
||||
|
@ -14,7 +18,9 @@ class HelloWorldScene(Scene):
|
|||
The text is centered on the screen.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.label = pyglet.text.Label(
|
||||
"Hello World !",
|
||||
anchor_x="center",
|
||||
|
@ -24,17 +30,25 @@ class HelloWorldScene(Scene):
|
|||
# remember the cooldown for the backspace button
|
||||
self._hold_backspace_last_call: datetime = datetime.now()
|
||||
|
||||
def on_draw(self, window: Window) -> None:
|
||||
def on_draw(self, window: "Window") -> None:
|
||||
super().on_draw(window)
|
||||
|
||||
self.label.draw()
|
||||
|
||||
def on_resize(self, window: Window, width: int, height: int) -> None:
|
||||
def on_resize(self, window: "Window", width: int, height: int) -> None:
|
||||
super().on_resize(window, width, height)
|
||||
|
||||
self.label.x = width // 2
|
||||
self.label.y = height // 2
|
||||
|
||||
def on_text(self, window: Window, char: str):
|
||||
def on_text(self, window: "Window", char: str):
|
||||
super().on_text(window, char)
|
||||
|
||||
self.label.text += char
|
||||
|
||||
def on_key_held(self, window: Window, dt: float, symbol: int, modifiers: int):
|
||||
def on_key_held(self, window: "Window", dt: float, symbol: int, modifiers: int):
|
||||
super().on_key_held(window, dt, symbol, modifiers)
|
||||
|
||||
if symbol == pyglet.window.key.BACKSPACE:
|
||||
|
||||
# add a cooldown of 0.1 second on the backspace key
|
18
source/gui/scene/MainMenu.py
Normal file
18
source/gui/scene/MainMenu.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
from source.gui.scene.base import Scene
|
||||
from source.gui.widget.Button import Button
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from source.gui.window import Window
|
||||
|
||||
|
||||
class MainMenuScene(Scene):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.add_widget(Button())
|
||||
|
||||
def on_draw(self, window: "Window"):
|
||||
super().on_draw(window)
|
||||
|
|
@ -1,3 +1,2 @@
|
|||
from .Scene import Scene
|
||||
from .HelloWorldScene import HelloWorldScene
|
||||
from .FPSCounterScene import FPSCounterScene
|
116
source/gui/scene/base/Scene.py
Normal file
116
source/gui/scene/base/Scene.py
Normal file
|
@ -0,0 +1,116 @@
|
|||
from pyglet.event import EventDispatcher
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from source.gui.widget.base import Widget
|
||||
from source.gui.window import Window
|
||||
|
||||
|
||||
class Scene(EventDispatcher):
|
||||
"""
|
||||
This class represent a scene that can be applied to a pyglet window.
|
||||
|
||||
The scene can represent anything like the main menu, the game, the
|
||||
options' menu, the multiplayer menu, ...
|
||||
"""
|
||||
|
||||
def __init__(self, widgets: list["Widget"] = None):
|
||||
self._widgets: list["Widget"] = []
|
||||
if widgets is not None: self.add_widget(*widgets)
|
||||
|
||||
def add_widget(self, *widgets: "Widget", priority: int = 0) -> None:
|
||||
for widget in widgets:
|
||||
self._widgets.insert(priority, widget)
|
||||
widget.on_scene_added(self)
|
||||
|
||||
def remove_widget(self, *widgets: "Widget") -> None:
|
||||
for widget in widgets:
|
||||
widget.on_scene_removed(self)
|
||||
self._widgets.remove(widget)
|
||||
|
||||
def clear_widget(self) -> None:
|
||||
for widget in self._widgets: widget.on_scene_removed(self)
|
||||
self._widgets.clear()
|
||||
|
||||
# scene event
|
||||
|
||||
def on_window_added(self, window: "Window"): # when the Scene is added to a window
|
||||
for widget in self._widgets: widget.on_window_added(window, self)
|
||||
|
||||
def on_window_removed(self, window: "Window"): # when the Scene is removed from a window
|
||||
for widget in self._widgets: widget.on_window_removed(window, self)
|
||||
|
||||
# window event
|
||||
|
||||
def on_draw(self, window: "Window"):
|
||||
for widget in self._widgets: widget.on_draw(window, self)
|
||||
|
||||
def on_resize(self, window: "Window", width: int, height: int):
|
||||
for widget in self._widgets: widget.on_resize(window, self, width, height)
|
||||
|
||||
def on_hide(self, window: "Window"):
|
||||
for widget in self._widgets: widget.on_hide(window, self)
|
||||
|
||||
def on_show(self, window: "Window"):
|
||||
for widget in self._widgets: widget.on_show(window, self)
|
||||
|
||||
def on_close(self, window: "Window"):
|
||||
for widget in self._widgets: widget.on_close(window, self)
|
||||
|
||||
def on_expose(self, window: "Window"):
|
||||
for widget in self._widgets: widget.on_expose(window, self)
|
||||
|
||||
def on_activate(self, window: "Window"):
|
||||
for widget in self._widgets: widget.on_activate(window, self)
|
||||
|
||||
def on_deactivate(self, window: "Window"):
|
||||
for widget in self._widgets: widget.on_deactivate(window, self)
|
||||
|
||||
def on_text(self, window: "Window", char: str):
|
||||
for widget in self._widgets: widget.on_text(window, self, char)
|
||||
|
||||
def on_move(self, window: "Window", x: int, y: int):
|
||||
for widget in self._widgets: widget.on_move(window, self, x, y)
|
||||
|
||||
def on_context_lost(self, window: "Window"):
|
||||
for widget in self._widgets: widget.on_context_lost(window, self)
|
||||
|
||||
def on_context_state_lost(self, window: "Window"):
|
||||
for widget in self._widgets: widget.on_context_state_lost(window, self)
|
||||
|
||||
def on_key_press(self, window: "Window", symbol: int, modifiers: int):
|
||||
for widget in self._widgets: widget.on_key_press(window, self, symbol, modifiers)
|
||||
|
||||
def on_key_release(self, window: "Window", symbol: int, modifiers: int):
|
||||
for widget in self._widgets: widget.on_key_release(window, self, symbol, modifiers)
|
||||
|
||||
def on_key_held(self, window: "Window", dt: float, symbol: int, modifiers: int):
|
||||
for widget in self._widgets: widget.on_key_held(window, self, dt, symbol, modifiers)
|
||||
|
||||
def on_mouse_enter(self, window: "Window", x: int, y: int):
|
||||
for widget in self._widgets: widget.on_mouse_enter(window, self, x, y)
|
||||
|
||||
def on_mouse_leave(self, window: "Window", x: int, y: int):
|
||||
for widget in self._widgets: widget.on_mouse_leave(window, self, x, y)
|
||||
|
||||
def on_text_motion(self, window: "Window", motion: int):
|
||||
for widget in self._widgets: widget.on_text_motion(window, self, motion)
|
||||
|
||||
def on_text_motion_select(self, window: "Window", motion: int):
|
||||
for widget in self._widgets: widget.on_text_motion_select(window, self, motion)
|
||||
|
||||
def on_mouse_motion(self, window: "Window", x: int, y: int, dx: int, dy: int):
|
||||
for widget in self._widgets: widget.on_mouse_motion(window, self, x, y, dx, dy)
|
||||
|
||||
def on_mouse_press(self, window: "Window", x: int, y: int, button: int, modifiers: int):
|
||||
for widget in self._widgets: widget.on_mouse_press(window, self, x, y, button, modifiers)
|
||||
|
||||
def on_mouse_release(self, window: "Window", x: int, y: int, button: int, modifiers: int):
|
||||
for widget in self._widgets: widget.on_mouse_release(window, self, x, y, button, modifiers)
|
||||
|
||||
def on_mouse_drag(self, window: "Window", x: int, y: int, dx: int, dy: int, buttons: int, modifiers: int):
|
||||
for widget in self._widgets: widget.on_mouse_drag(window, self, x, y, dx, dy, buttons, modifiers)
|
||||
|
||||
def on_mouse_scroll(self, window: "Window", x: int, y: int, scroll_x: float, scroll_y: float):
|
||||
for widget in self._widgets: widget.on_mouse_scroll(window, self, x, y, scroll_x, scroll_y)
|
1
source/gui/scene/base/__init__.py
Normal file
1
source/gui/scene/base/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
from .Scene import Scene
|
123
source/gui/widget/Button.py
Normal file
123
source/gui/widget/Button.py
Normal file
|
@ -0,0 +1,123 @@
|
|||
from typing import Callable, Optional, TYPE_CHECKING
|
||||
|
||||
import pyglet
|
||||
|
||||
from source.gui.widget.base import Widget
|
||||
from source.utils import in_bbox
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from source.gui.scene.base import Scene
|
||||
from source.gui.window import Window
|
||||
|
||||
|
||||
class Button(Widget):
|
||||
__slots__ = ("_x", "_y", "_width", "_height", "_text", "on_press", "on_release", "_normal_image", "_hover_image",
|
||||
"_hovering")
|
||||
|
||||
def __init__(self,
|
||||
x: int,
|
||||
y: int,
|
||||
width: int,
|
||||
height: int,
|
||||
on_press: Optional[Callable] = None,
|
||||
on_release: Optional[Callable] = None,
|
||||
normal_image: pyglet.image.AbstractImage = None,
|
||||
hover_image: pyglet.image.AbstractImage = None,
|
||||
*args, **kwargs
|
||||
):
|
||||
|
||||
# TODO: use batch
|
||||
# TODO: make the label centered in the button
|
||||
# TODO: use texture bin and animation to simplify the image handling ?
|
||||
|
||||
self.label = pyglet.text.Label(*args, **kwargs)
|
||||
|
||||
self._hovering = False
|
||||
self._normal_sprite = pyglet.sprite.Sprite(normal_image)
|
||||
self._hover_sprite = pyglet.sprite.Sprite(hover_image)
|
||||
|
||||
self.on_press: Optional[Callable[["Window", "Scene", int, int, int, int], None]] = on_press
|
||||
self.on_release: Optional[Callable[["Window", "Scene", int, int, int, int], None]] = on_release
|
||||
|
||||
self.x: int = x
|
||||
self.y: int = y
|
||||
self.width: int = width
|
||||
self.height: int = height
|
||||
|
||||
# function
|
||||
|
||||
def _update_sprite_size(self, x: int = None, y: int = None, width: int = None, height: int = None):
|
||||
for sprite in self._normal_sprite, self._hover_sprite:
|
||||
sprite.update(
|
||||
x=x,
|
||||
y=y,
|
||||
scale_x=None if width is None else width / sprite.width,
|
||||
scale_y=None if height is None else height / sprite.height,
|
||||
)
|
||||
|
||||
# button getter and setter
|
||||
|
||||
@property
|
||||
def background_sprite(self) -> Optional[pyglet.sprite.Sprite]:
|
||||
return self._hover_sprite if self._hovering else self._normal_sprite
|
||||
|
||||
@property
|
||||
def bbox(self) -> tuple[int, int, int, int]:
|
||||
return self.x, self.y, self.x + self.width, self.y + self.height
|
||||
|
||||
# label getter and setter
|
||||
|
||||
@property
|
||||
def x(self) -> int: return self._x
|
||||
|
||||
@x.setter
|
||||
def x(self, value: int):
|
||||
self._x = value
|
||||
self.label.x = value
|
||||
self._update_sprite_size(x=value)
|
||||
|
||||
@property
|
||||
def y(self) -> int: return self._y
|
||||
|
||||
@y.setter
|
||||
def y(self, value: int):
|
||||
self._y = value
|
||||
self.label.y = value
|
||||
self._update_sprite_size(y=value)
|
||||
|
||||
@property
|
||||
def width(self) -> int: return self._width
|
||||
|
||||
@width.setter
|
||||
def width(self, value: int):
|
||||
self._width = value
|
||||
self.label.width = value
|
||||
self._update_sprite_size(width=value)
|
||||
|
||||
@property
|
||||
def height(self) -> int: return self._height
|
||||
|
||||
@height.setter
|
||||
def height(self, value: int):
|
||||
self._height = value
|
||||
self.label.height = value
|
||||
self._update_sprite_size(height=value)
|
||||
|
||||
# event
|
||||
|
||||
def on_mouse_press(self, window: "Window", scene: "Scene", x: int, y: int, button: int, modifiers: int):
|
||||
if not in_bbox((x, y), self.bbox): return
|
||||
if self.on_press is not None: self.on_press(window, scene, x, y, button, modifiers)
|
||||
|
||||
def on_mouse_release(self, window: "Window", scene: "Scene", x: int, y: int, button: int, modifiers: int):
|
||||
if not in_bbox((x, y), self.bbox): return
|
||||
if self.on_release is not None: self.on_release(window, scene, x, y, button, modifiers)
|
||||
|
||||
def on_mouse_motion(self, window: "Window", scene: "Scene", x: int, y: int, dx: int, dy: int):
|
||||
self._hovering = in_bbox((x, y), self.bbox)
|
||||
|
||||
def on_draw(self, window: "Window", scene: "Scene"):
|
||||
if (bg := self.background_sprite) is not None:
|
||||
bg.draw()
|
||||
|
||||
self.label.draw()
|
0
source/gui/widget/__init__.py
Normal file
0
source/gui/widget/__init__.py
Normal file
50
source/gui/widget/base/Widget.py
Normal file
50
source/gui/widget/base/Widget.py
Normal file
|
@ -0,0 +1,50 @@
|
|||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from source.gui.scene.base import Scene
|
||||
from source.gui.window import Window
|
||||
|
||||
|
||||
class Widget:
|
||||
"""
|
||||
This class represent a widget that can be attached to a Scene.
|
||||
|
||||
It can be used to create a button, a label, ...
|
||||
"""
|
||||
|
||||
# widget event
|
||||
|
||||
def on_scene_added(self, scene: "Scene"): pass
|
||||
def on_scene_removed(self, scene: "Scene"): pass
|
||||
|
||||
# scene event
|
||||
|
||||
def on_window_added(self, window: "Window", scene: "Scene"): pass
|
||||
def on_window_removed(self, window: "Window", scene: "Scene"): pass
|
||||
|
||||
# global event
|
||||
|
||||
def on_draw(self, window: "Window", scene: "Scene"): pass
|
||||
def on_resize(self, window: "Window", scene: "Scene", width: int, height: int): pass
|
||||
def on_hide(self, window: "Window", scene: "Scene"): pass
|
||||
def on_show(self, window: "Window", scene: "Scene"): pass
|
||||
def on_close(self, window: "Window", scene: "Scene"): pass
|
||||
def on_expose(self, window: "Window", scene: "Scene"): pass
|
||||
def on_activate(self, window: "Window", scene: "Scene"): pass
|
||||
def on_deactivate(self, window: "Window", scene: "Scene"): pass
|
||||
def on_text(self, window: "Window", scene: "Scene", char: str): pass
|
||||
def on_move(self, window: "Window", scene: "Scene", x: int, y: int): pass
|
||||
def on_context_lost(self, window: "Window", scene: "Scene"): pass
|
||||
def on_context_state_lost(self, window: "Window", scene: "Scene"): pass
|
||||
def on_key_press(self, window: "Window", scene: "Scene", symbol: int, modifiers: int): pass
|
||||
def on_key_release(self, window: "Window", scene: "Scene", symbol: int, modifiers: int): pass
|
||||
def on_key_held(self, window: "Window", scene: "Scene", dt: float, symbol: int, modifiers: int): pass
|
||||
def on_mouse_enter(self, window: "Window", scene: "Scene", x: int, y: int): pass
|
||||
def on_mouse_leave(self, window: "Window", scene: "Scene", x: int, y: int): pass
|
||||
def on_text_motion(self, window: "Window", scene: "Scene", motion: int): pass
|
||||
def on_text_motion_select(self, window: "Window", scene: "Scene", motion: int): pass
|
||||
def on_mouse_motion(self, window: "Window", scene: "Scene", x: int, y: int, dx: int, dy: int): pass
|
||||
def on_mouse_press(self, window: "Window", scene: "Scene", x: int, y: int, button: int, modifiers: int): pass
|
||||
def on_mouse_release(self, window: "Window", scene: "Scene", x: int, y: int, button: int, modifiers: int): pass
|
||||
def on_mouse_drag(self, window: "Window", scene: "Scene", x: int, y: int, dx: int, dy: int, buttons: int, modifiers: int): pass
|
||||
def on_mouse_scroll(self, window: "Window", scene: "Scene", x: int, y: int, scroll_x: float, scroll_y: float): pass
|
1
source/gui/widget/base/__init__.py
Normal file
1
source/gui/widget/base/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
from .Widget import Widget
|
|
@ -1,8 +1,9 @@
|
|||
from typing import Optional, Callable
|
||||
from typing import Optional, Callable, TYPE_CHECKING
|
||||
|
||||
import pyglet.window
|
||||
|
||||
from gui.scene import Scene
|
||||
if TYPE_CHECKING:
|
||||
from source.gui.scene import Scene
|
||||
|
||||
|
||||
class Window(pyglet.window.Window): # NOQA - pycharm think pyglet window is abstract
|
||||
|
@ -14,9 +15,10 @@ class Window(pyglet.window.Window): # NOQA - pycharm think pyglet window is abs
|
|||
putting everything in the window code.
|
||||
"""
|
||||
|
||||
def __init__(self, *args, scenes: Optional[Scene] = None, **kwargs):
|
||||
def __init__(self, scenes: Optional["Scene"] = None, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self._scenes: list[Scene] = [] if scenes is None else scenes
|
||||
self._scenes: list["Scene"] = []
|
||||
if scenes is not None: self.add_scene(*scenes)
|
||||
|
||||
# add a keys handler to the window
|
||||
self.keys = pyglet.window.key.KeyStateHandler()
|
||||
|
@ -27,7 +29,7 @@ class Window(pyglet.window.Window): # NOQA - pycharm think pyglet window is abs
|
|||
|
||||
# scene methods
|
||||
|
||||
def set_scene(self, *scenes: Scene) -> None:
|
||||
def set_scene(self, *scenes: "Scene") -> None:
|
||||
"""
|
||||
Set the scene(s) of the window
|
||||
:param scenes: the scene(s) to set
|
||||
|
@ -42,7 +44,7 @@ class Window(pyglet.window.Window): # NOQA - pycharm think pyglet window is abs
|
|||
for scene in self._scenes: scene.on_window_removed(self)
|
||||
self._scenes.clear()
|
||||
|
||||
def add_scene(self, *scenes: Scene, priority: int = 0) -> None:
|
||||
def add_scene(self, *scenes: "Scene", priority: int = 0) -> None:
|
||||
"""
|
||||
Add a scene to the window
|
||||
:param scenes: the scene to add
|
||||
|
@ -52,7 +54,7 @@ class Window(pyglet.window.Window): # NOQA - pycharm think pyglet window is abs
|
|||
self._scenes.insert(priority, scene)
|
||||
scene.on_window_added(self)
|
||||
|
||||
def remove_scene(self, *scenes: Scene) -> None:
|
||||
def remove_scene(self, *scenes: "Scene") -> None:
|
||||
"""
|
||||
Remove a scene from the window
|
||||
:param scenes: the scene to remove
|
|
@ -1 +1,2 @@
|
|||
from .Window import Window
|
||||
|
|
@ -1 +1,2 @@
|
|||
from .copy_array_offset import copy_array_offset
|
||||
from .in_bbox import in_bbox
|
||||
|
|
14
source/utils/in_bbox.py
Normal file
14
source/utils/in_bbox.py
Normal file
|
@ -0,0 +1,14 @@
|
|||
def in_bbox(point: tuple[int, int], bbox: tuple[int, int, int, int]) -> bool:
|
||||
"""
|
||||
Return true if a point is inside a bounding box
|
||||
:param point: the point to check
|
||||
:param bbox: the bbox where to check the point
|
||||
:return: True if the point is inside the bbox, False otherwise
|
||||
"""
|
||||
|
||||
point_x, point_y = point
|
||||
bbox_x1, bbox_y1, bbox_x2, bbox_y2 = bbox
|
||||
|
||||
if not bbox_x1 <= point_x <= bbox_x2: return False
|
||||
if not bbox_y1 <= point_y <= bbox_y2: return False
|
||||
return True
|
Loading…
Reference in a new issue