restructured some part of the code, implemented Label and Button

This commit is contained in:
Faraphel 2023-01-17 22:24:03 +01:00
parent 7cc837b68e
commit 920914ad8c
27 changed files with 446 additions and 179 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

View file

@ -1,13 +1,15 @@
import pyglet import pyglet
from source.gui.scene.debug import FPSScene from source.gui.scene.debug import FPSAbstractScene
from source.gui.scene.test import HelloWorldScene from source.gui.scene.test import TestButtonScene, TestLabelScene
from source.gui.window import Window from source.gui.window import Window
# Create a new window # Create a new window
window = Window(resizable=True, vsync=False) window = Window(resizable=True, vsync=False)
window.add_scene(HelloWorldScene(), FPSScene()) window.add_scene(TestButtonScene())
# window.add_scene(TestLabelScene())
window.add_scene(FPSAbstractScene())
# Start the event loop # Start the event loop
pyglet.app.run(interval=0) pyglet.app.run(interval=0)

8
source/gui/README.md Normal file
View file

@ -0,0 +1,8 @@
Ce module est une "surcouche" pour le module pyglet afin d'implémenter quelques éléments qui
ne sont pas déjà disponible nativement dans cette librairie, tel que :
- Les scènes (attachable à une fenêtre afin de changer rapidement de menu / d'interface)
- Les widgets (attachable à des scènes afin de rajouter des boutons, des textes, ...)
Ces éléments permettent de plus facilement gérer le redimentionnement de la fenêtre tout en
restant suffisament rapide pour ne pas causer de problème de ralentissement.

View file

@ -1,27 +1,29 @@
from abc import ABC
from typing import TYPE_CHECKING, Optional from typing import TYPE_CHECKING, Optional
if TYPE_CHECKING: if TYPE_CHECKING:
from source.gui.window import Window from source.gui.window import Window
from source.gui.widget.base import BaseWidget from source.gui.widget.abc import AbstractWidget
class BaseScene: class AbstractScene(ABC):
""" """
A scene that can be attached to a window An abstract scene that can be attached to a window.
Can be used to create a menu, an overlay, ...
""" """
def __init__(self): def __init__(self):
self._widgets: list["BaseWidget"] = [] self._widgets: list["AbstractWidget"] = [] # the lists of the widgets in the scene
self._window: Optional["Window"] = None self._window: Optional["Window"] = None # the window where the scene is attached
# widget # widget
def add_widget(self, *widgets: "BaseWidget", priority: int = 0) -> None: def add_widget(self, *widgets: "AbstractWidget", priority: int = 0) -> None:
for widget in widgets: for widget in widgets:
self._widgets.insert(priority, widget) self._widgets.insert(priority, widget)
widget.on_scene_added(self) widget.on_scene_added(self)
def remove_widget(self, *widgets: "BaseWidget") -> None: def remove_widget(self, *widgets: "AbstractWidget") -> None:
for widget in widgets: for widget in widgets:
widget.on_scene_removed(self) widget.on_scene_removed(self)
self._widgets.remove(widget) self._widgets.remove(widget)
@ -44,12 +46,12 @@ class BaseScene:
return self._window return self._window
@window.setter @window.setter
def window(self, window: "Window"): def window(self, window: "Window"): # trying to change the window will trigger the event
if self._window is not None: self.on_window_removed(self._window) if self._window is not None: self.on_window_removed(self._window)
self._window = window self._window = window
if self._window is not None: self.on_window_added(self._window) if self._window is not None: self.on_window_added(self._window)
# event # all the events of the window are directly available here or in the widgets
def on_draw(self, window: "Window"): def on_draw(self, window: "Window"):
for widget in self._widgets: widget.on_draw(window, self) for widget in self._widgets: widget.on_draw(window, self)

View file

@ -0,0 +1 @@
from .AbstractScene import AbstractScene

View file

@ -1 +0,0 @@
from .BaseScene import BaseScene

View file

@ -1,17 +1,21 @@
from typing import TYPE_CHECKING from typing import TYPE_CHECKING, Optional
import pyglet.window import pyglet.window
from source.gui.scene.base import BaseScene from source.gui.scene.abc import AbstractScene
if TYPE_CHECKING: if TYPE_CHECKING:
from source.gui.window import Window from source.gui.window import Window
class FPSScene(BaseScene): class FPSAbstractScene(AbstractScene):
"""
A base scene that can be used as an overlay to display the FPS
"""
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self._fps_display = None self._fps_display: Optional[pyglet.window.FPSDisplay] = None
def on_window_added(self, window: "Window"): def on_window_added(self, window: "Window"):
self._fps_display = pyglet.window.FPSDisplay(window) self._fps_display = pyglet.window.FPSDisplay(window)

View file

@ -1 +1 @@
from .FPSScene import FPSScene from .FPSScene import FPSAbstractScene

View file

@ -2,19 +2,23 @@ from typing import TYPE_CHECKING
import pyglet import pyglet
from source.gui.scene.base import BaseScene from source.gui.scene.abc import AbstractScene
from source.gui.widget.Button import Button from source.gui.widget import Button
if TYPE_CHECKING: if TYPE_CHECKING:
from source.gui.window import Window from source.gui.window import Window
class HelloWorldScene(BaseScene): class TestButtonScene(AbstractScene):
"""
A scene used to test the Button widget
"""
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.button_atlas = None self.button_atlas = None
self.sprite_batch = None self.background_batch = None
self.label_batch = None self.label_batch = None
def on_window_added(self, window: "Window") -> None: def on_window_added(self, window: "Window") -> None:
@ -27,7 +31,7 @@ class HelloWorldScene(BaseScene):
hover_region = self.button_atlas.add(hover_texture) hover_region = self.button_atlas.add(hover_texture)
click_region = self.button_atlas.add(click_texture) click_region = self.button_atlas.add(click_texture)
self.sprite_batch = pyglet.graphics.Batch() self.background_batch = pyglet.graphics.Batch()
self.label_batch = pyglet.graphics.Batch() self.label_batch = pyglet.graphics.Batch()
for x in range(10): for x in range(10):
@ -43,7 +47,7 @@ class HelloWorldScene(BaseScene):
label_multiline=True, label_multiline=True,
label_batch=self.label_batch, label_batch=self.label_batch,
sprite_batch=self.sprite_batch, background_batch=self.background_batch,
)) ))
super().on_window_added(window) super().on_window_added(window)
@ -51,5 +55,5 @@ class HelloWorldScene(BaseScene):
def on_draw(self, window: "Window"): def on_draw(self, window: "Window"):
super().on_draw(window) super().on_draw(window)
self.sprite_batch.draw() self.background_batch.draw()
self.label_batch.draw() self.label_batch.draw()

View file

@ -0,0 +1,40 @@
from typing import TYPE_CHECKING
import pyglet
from source.gui.scene.abc import AbstractScene
from source.gui.widget import Label
if TYPE_CHECKING:
from source.gui.window import Window
class TestLabelScene(AbstractScene):
"""
A scene used to test the Label widget
"""
def __init__(self):
super().__init__()
self.label_batch = None
def on_window_added(self, window: "Window") -> None:
self.label_batch = pyglet.graphics.Batch()
for x in range(10):
for y in range(10):
self.add_widget(Label(
x=x*0.1, y=y*0.1, width=0.1, height=0.1,
text=f"{x}.{y}",
label_batch=self.label_batch,
))
super().on_window_added(window)
def on_draw(self, window: "Window"):
super().on_draw(window)
self.label_batch.draw()

View file

@ -1 +1,3 @@
from .HelloWorldScene import HelloWorldScene from .TestButtonScene import TestButtonScene
from .TestLabelScene import TestLabelScene

View file

@ -1 +0,0 @@
from .Sprite import Sprite

View file

@ -1,18 +1,18 @@
from typing import TYPE_CHECKING, Callable from typing import TYPE_CHECKING, Callable, Optional
import pyglet.image import pyglet.image
from source.gui.sprite import Sprite from source.gui.widget.base import Sprite, Label
from source.gui.widget.base import BaseAdaptativeWidget from source.gui.widget.abc import AbstractResizableWidget
from source.type import Percentage from source.type import Percentage
from source.utils import in_bbox from source.utils import in_bbox
if TYPE_CHECKING: if TYPE_CHECKING:
from source.gui.window import Window from source.gui.window import Window
from source.gui.scene.base import BaseScene from source.gui.scene.abc import AbstractScene
class Button(BaseAdaptativeWidget): class Button(AbstractResizableWidget):
def __init__(self, def __init__(self,
# position # position
@ -45,11 +45,11 @@ class Button(BaseAdaptativeWidget):
# batch # batch
label_batch: pyglet.graphics.Batch = None, label_batch: pyglet.graphics.Batch = None,
sprite_batch: pyglet.graphics.Batch = None, background_batch: pyglet.graphics.Batch = None,
# group # group
label_group: pyglet.graphics.Group = None, label_group: pyglet.graphics.Group = None,
sprite_group: pyglet.graphics.Group = None, background_group: pyglet.graphics.Group = None,
): ):
super().__init__(x, y, width, height) super().__init__(x, y, width, height)
@ -61,7 +61,7 @@ class Button(BaseAdaptativeWidget):
self.on_press = on_press self.on_press = on_press
self.on_release = on_release self.on_release = on_release
self._label = None self._label: Optional[Label] = None
self._label_kwargs = { self._label_kwargs = {
"text": label_text, "text": label_text,
"font_name": label_font_name, "font_name": label_font_name,
@ -79,15 +79,32 @@ class Button(BaseAdaptativeWidget):
"group": label_group, "group": label_group,
} }
self._sprite = None self._background: Optional[Sprite] = None
self._sprite_kwargs = { self._background_kwargs = {
"batch": sprite_batch, "batch": background_batch,
"group": sprite_group, "group": background_group,
} }
self._hover = False self._hover = False
self._click = False self._click = False
def on_window_added(self, window: "Window", scene: "AbstractScene"):
super().on_window_added(window, scene)
self._label = Label(
x=self.x + self.width / 2, y=self.y + self.height / 2, width=self.width,
anchor_x="center", anchor_y="center",
**self._label_kwargs
)
self._background = Sprite(
self._normal_texture,
x=self.x, y=self.y, width=self.width, height=self.height,
**self._background_kwargs
)
# button update # button update
@property @property
@ -97,7 +114,7 @@ class Button(BaseAdaptativeWidget):
@hover.setter @hover.setter
def hover(self, hover: bool) -> None: def hover(self, hover: bool) -> None:
self._hover = hover self._hover = hover
self._update_sprite() self.update_sprite()
@property @property
def click(self) -> bool: def click(self) -> bool:
@ -106,7 +123,7 @@ class Button(BaseAdaptativeWidget):
@click.setter @click.setter
def click(self, click: bool) -> None: def click(self, click: bool) -> None:
self._click = click self._click = click
self._update_sprite() self.update_sprite()
@property @property
def background_texture(self) -> pyglet.image.AbstractImage: def background_texture(self) -> pyglet.image.AbstractImage:
@ -116,47 +133,19 @@ class Button(BaseAdaptativeWidget):
self._normal_texture self._normal_texture
) )
def _update_sprite(self): def update_sprite(self):
self._sprite.image = self.background_texture self._background.image = self.background_texture
def update_size(self): def update_size(self):
self._sprite.x = self.x self._background.update_size(self.x, self.y, self.width, self.height)
self._sprite.y = self.y self._label.update_size(self.x + self.width // 2, self.y + self.height // 2, self.width)
self._sprite.width = self.width
self._sprite.height = self.height
self._label.x = self.x + self.width / 2
self._label.y = self.y + self.height / 2
self._label.width = self.width
# event # event
def on_window_added(self, window: "Window", scene: "BaseScene"): def on_mouse_motion(self, window: "Window", scene: "AbstractScene", x: int, y: int, dx: int, dy: int):
super().on_window_added(window, scene)
self._label = pyglet.text.Label(
x=self.x + self.width / 2,
y=self.y + self.height / 2,
width=self.width,
anchor_x="center", anchor_y="center",
**self._label_kwargs
)
self._sprite = Sprite(
self._normal_texture,
x=self.x, y=self.y,
width=self.width, height=self.height,
**self._sprite_kwargs
)
def on_mouse_motion(self, window: "Window", scene: "BaseScene", x: int, y: int, dx: int, dy: int):
self.hover = in_bbox((x, y), self.bbox) self.hover = in_bbox((x, y), self.bbox)
def on_mouse_press(self, window: "Window", scene: "BaseScene", x: int, y: int, button: int, modifiers: int): def on_mouse_press(self, window: "Window", scene: "AbstractScene", x: int, y: int, button: int, modifiers: int):
if not in_bbox((x, y), self.bbox): return if not in_bbox((x, y), self.bbox): return
self.click = True self.click = True
@ -164,7 +153,7 @@ class Button(BaseAdaptativeWidget):
if self.on_press is not None: if self.on_press is not None:
self.on_press(self, window, scene, x, y, button, modifiers) self.on_press(self, window, scene, x, y, button, modifiers)
def on_mouse_release(self, window: "Window", scene: "BaseScene", x: int, y: int, button: int, modifiers: int): def on_mouse_release(self, window: "Window", scene: "AbstractScene", x: int, y: int, button: int, modifiers: int):
old_click = self.click old_click = self.click
self.click = False self.click = False

View file

@ -0,0 +1,5 @@
from source.gui.widget.abc import AbstractResizableWidget
class Image(AbstractResizableWidget):
...

View file

@ -0,0 +1,74 @@
from typing import TYPE_CHECKING
import pyglet.text
from source.gui.widget.abc import AbstractResizableWidget
from source.type import Percentage
if TYPE_CHECKING:
from source.gui.window import Window
from source.gui.scene.abc import AbstractScene
class Input(AbstractResizableWidget):
def __init__(self,
# position
x: int | Percentage,
y: int | Percentage,
width: int | Percentage,
height: int | Percentage,
# background
texture: pyglet.image.AbstractImage,
# label
label_text: str = "",
label_font_name: str = None,
label_font_size: int = None,
label_bold: bool = False,
label_italic: bool = False,
label_stretch: bool = False,
label_color: tuple[int, int, int, int] = (255, 255, 255, 255),
label_align: str = "center",
label_multiline: bool = False,
label_dpi: int = None,
label_rotation: int = 0,
# batch
label_batch: pyglet.graphics.Batch = None,
background_batch: pyglet.graphics.Batch = None,
# group
label_group: pyglet.graphics.Group = None,
background_group: pyglet.graphics.Group = None,
):
super().__init__(x, y, width, height)
self._label = None
self._label_kwargs = {
"text": label_text,
"font_name": label_font_name,
"font_size": label_font_size,
"bold": label_bold,
"italic": label_italic,
"stretch": label_stretch,
"color": label_color,
"align": label_align,
"multiline": label_multiline,
"dpi": label_dpi,
"rotation": label_rotation,
"batch": label_batch,
"group": label_group,
}
self._background_kwargs = {
"img": texture,
"batch": background_batch,
"group": background_group,
}
def on_window_added(self, window: "Window", scene: "AbstractScene"):
...

102
source/gui/widget/Label.py Normal file
View file

@ -0,0 +1,102 @@
from typing import TYPE_CHECKING
import pyglet.text
from source.gui.widget.base import Sprite
from source.gui.widget.abc import AbstractResizableWidget
from source.type import Percentage
if TYPE_CHECKING:
from source.gui.window import Window
from source.gui.scene.abc import AbstractScene
class Label(AbstractResizableWidget):
def __init__(self,
# position
x: int | Percentage,
y: int | Percentage,
width: int | Percentage = None,
height: int | Percentage = None,
# label
text: str = "",
font_name: str = None,
font_size: int = None,
bold: bool = False,
italic: bool = False,
stretch: bool = False,
color: tuple[int, int, int, int] = (255, 255, 255, 255),
align: str = "center",
multiline: bool = False,
dpi: int = None,
rotation: int = 0,
# background
texture: pyglet.image.AbstractImage = None,
# batch
label_batch: pyglet.graphics.Batch = None,
background_batch: pyglet.graphics.Batch = None,
# group
label_group: pyglet.graphics.Group = None,
background_group: pyglet.graphics.Group = None
):
super().__init__(x, y, width, height)
self._label = None
self._label_kwargs = {
"text": text,
"font_name": font_name,
"font_size": font_size,
"bold": bold,
"italic": italic,
"stretch": stretch,
"color": color,
"align": align,
"multiline": multiline,
"dpi": dpi,
"rotation": rotation,
"batch": label_batch,
"group": label_group,
}
if texture is not None and width is None or height is None:
raise ValueError("You need to set a width and a height to create a Label with a background !")
self._background = None
self._background_kwargs = {
"img": texture,
"batch": background_batch,
"group": background_group,
} if texture is not None else None
def on_window_added(self, window: "Window", scene: "AbstractScene"):
super().on_window_added(window, scene)
self._label = pyglet.text.Label(
x=self.x, y=self.y, width=self.width, height=self.height,
**self._label_kwargs
)
if self._background_kwargs is not None:
self._background = Sprite(
x=self.x, y=self.y, width=self.width, height=self.height,
**self._background_kwargs
)
def update_size(self):
self._label.x = self.x
self._label.y = self.y
self._label.width = self.width
self._label.height = self.height
if self._background is not None:
self._background.x = self.x
self._background.y = self.y
self._background.width = self.width
self._background.height = self.height

View file

@ -0,0 +1,4 @@
from .Label import Label
from .Input import Input
from .Button import Button
from .Image import Image

View file

@ -1,8 +1,10 @@
from source.gui.widget.base import BaseWidget from abc import ABC
from source.gui.widget.abc import AbstractWidget
from source.type import BBox from source.type import BBox
class BaseBoxWidget(BaseWidget): class AbstractBoxWidget(AbstractWidget, ABC):
def __init__(self, x: int, y: int, width: int, height: int): def __init__(self, x: int, y: int, width: int, height: int):
self._x = x self._x = x
self._y = y self._y = y

View file

@ -0,0 +1,50 @@
from abc import ABC
from typing import Optional, TYPE_CHECKING
from source.gui.widget.abc import AbstractBoxWidget
from source.type import Percentage
if TYPE_CHECKING:
from source.gui.window import Window
from source.gui.scene.abc import AbstractScene
class AbstractResizableWidget(AbstractBoxWidget, ABC):
def __init__(self, x: int | Percentage, y: int | Percentage, width: int | Percentage, height: int | Percentage):
super().__init__(x, y, width, height)
self._window_width: Optional[int] = None
self._window_height: Optional[int] = None
# getter / setter
def on_window_added(self, window: "Window", scene: "AbstractScene"):
self._window_width = window.width
self._window_height = window.height
@property
def x(self) -> int:
return self._x * self._window_width if isinstance(self._x, Percentage) else self._x
@property
def y(self) -> int:
return self._y * self._window_height if isinstance(self._y, Percentage) else self._y
@property
def width(self) -> int:
return self._width * self._window_width if isinstance(self._width, Percentage) else self._width
@property
def height(self) -> int:
return self._height * self._window_height if isinstance(self._height, Percentage) else self._height
# event
def update_size(self): pass
def on_resize(self, window: "Window", scene: "AbstractScene", width: int, height: int):
self._window_width = width
self._window_height = height
self.update_size()

View file

@ -0,0 +1,51 @@
from abc import ABC
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from source.gui.scene.abc import AbstractScene
from source.gui.window import Window
class AbstractWidget(ABC):
"""
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: "AbstractScene"): pass
def on_scene_removed(self, scene: "AbstractScene"): pass
# scene event
def on_window_added(self, window: "Window", scene: "AbstractScene"): pass
def on_window_removed(self, window: "Window", scene: "AbstractScene"): pass
# global event
def on_draw(self, window: "Window", scene: "AbstractScene"): pass
def on_resize(self, window: "Window", scene: "AbstractScene", width: int, height: int): pass
def on_hide(self, window: "Window", scene: "AbstractScene"): pass
def on_show(self, window: "Window", scene: "AbstractScene"): pass
def on_close(self, window: "Window", scene: "AbstractScene"): pass
def on_expose(self, window: "Window", scene: "AbstractScene"): pass
def on_activate(self, window: "Window", scene: "AbstractScene"): pass
def on_deactivate(self, window: "Window", scene: "AbstractScene"): pass
def on_text(self, window: "Window", scene: "AbstractScene", char: str): pass
def on_move(self, window: "Window", scene: "AbstractScene", x: int, y: int): pass
def on_context_lost(self, window: "Window", scene: "AbstractScene"): pass
def on_context_state_lost(self, window: "Window", scene: "AbstractScene"): pass
def on_key_press(self, window: "Window", scene: "AbstractScene", symbol: int, modifiers: int): pass
def on_key_release(self, window: "Window", scene: "AbstractScene", symbol: int, modifiers: int): pass
def on_key_held(self, window: "Window", scene: "AbstractScene", dt: float, symbol: int, modifiers: int): pass
def on_mouse_enter(self, window: "Window", scene: "AbstractScene", x: int, y: int): pass
def on_mouse_leave(self, window: "Window", scene: "AbstractScene", x: int, y: int): pass
def on_text_motion(self, window: "Window", scene: "AbstractScene", motion: int): pass
def on_text_motion_select(self, window: "Window", scene: "AbstractScene", motion: int): pass
def on_mouse_motion(self, window: "Window", scene: "AbstractScene", x: int, y: int, dx: int, dy: int): pass
def on_mouse_press(self, window: "Window", scene: "AbstractScene", x: int, y: int, button: int, modifiers: int): pass
def on_mouse_release(self, window: "Window", scene: "AbstractScene", x: int, y: int, button: int, modifiers: int): pass
def on_mouse_drag(self, window: "Window", scene: "AbstractScene", x: int, y: int, dx: int, dy: int, buttons: int, modifiers: int): pass
def on_mouse_scroll(self, window: "Window", scene: "AbstractScene", x: int, y: int, scroll_x: float, scroll_y: float): pass

View file

@ -0,0 +1,3 @@
from .AbstractWidget import AbstractWidget
from .AbstractBoxWidget import AbstractBoxWidget
from .AbstractResizableWidget import AbstractResizableWidget

View file

@ -1,44 +0,0 @@
from typing import Optional
from source.gui.widget.base import BaseBoxWidget
from source.type import Percentage
class BaseAdaptativeWidget(BaseBoxWidget):
def __init__(self, x: int | Percentage, y: int | Percentage, width: int | Percentage, height: int | Percentage):
super().__init__(x, y, width, height)
self._window_width: Optional[int] = None
self._window_height: Optional[int] = None
# getter / setter
def on_window_added(self, window: "Window", scene: "BaseScene"):
self._window_width = window.width
self._window_height = window.height
@property
def x(self) -> int:
return self._x if isinstance(self._x, int) else self._x * self._window_width
@property
def y(self) -> int:
return self._y if isinstance(self._y, int) else self._y * self._window_height
@property
def width(self) -> int:
return self._width if isinstance(self._width, int) else self._width * self._window_width
@property
def height(self) -> int:
return self._height if isinstance(self._height, int) else self._height * self._window_height
# event
def update_size(self): pass
def on_resize(self, window: "Window", scene: "BaseScene", width: int, height: int):
self._window_width = width
self._window_height = height
self.update_size()

View file

@ -1,50 +0,0 @@
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from source.gui.scene.base import BaseScene
from source.gui.window import Window
class BaseWidget:
"""
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: "BaseScene"): pass
def on_scene_removed(self, scene: "BaseScene"): pass
# scene event
def on_window_added(self, window: "Window", scene: "BaseScene"): pass
def on_window_removed(self, window: "Window", scene: "BaseScene"): pass
# global event
def on_draw(self, window: "Window", scene: "BaseScene"): pass
def on_resize(self, window: "Window", scene: "BaseScene", width: int, height: int): pass
def on_hide(self, window: "Window", scene: "BaseScene"): pass
def on_show(self, window: "Window", scene: "BaseScene"): pass
def on_close(self, window: "Window", scene: "BaseScene"): pass
def on_expose(self, window: "Window", scene: "BaseScene"): pass
def on_activate(self, window: "Window", scene: "BaseScene"): pass
def on_deactivate(self, window: "Window", scene: "BaseScene"): pass
def on_text(self, window: "Window", scene: "BaseScene", char: str): pass
def on_move(self, window: "Window", scene: "BaseScene", x: int, y: int): pass
def on_context_lost(self, window: "Window", scene: "BaseScene"): pass
def on_context_state_lost(self, window: "Window", scene: "BaseScene"): pass
def on_key_press(self, window: "Window", scene: "BaseScene", symbol: int, modifiers: int): pass
def on_key_release(self, window: "Window", scene: "BaseScene", symbol: int, modifiers: int): pass
def on_key_held(self, window: "Window", scene: "BaseScene", dt: float, symbol: int, modifiers: int): pass
def on_mouse_enter(self, window: "Window", scene: "BaseScene", x: int, y: int): pass
def on_mouse_leave(self, window: "Window", scene: "BaseScene", x: int, y: int): pass
def on_text_motion(self, window: "Window", scene: "BaseScene", motion: int): pass
def on_text_motion_select(self, window: "Window", scene: "BaseScene", motion: int): pass
def on_mouse_motion(self, window: "Window", scene: "BaseScene", x: int, y: int, dx: int, dy: int): pass
def on_mouse_press(self, window: "Window", scene: "BaseScene", x: int, y: int, button: int, modifiers: int): pass
def on_mouse_release(self, window: "Window", scene: "BaseScene", x: int, y: int, button: int, modifiers: int): pass
def on_mouse_drag(self, window: "Window", scene: "BaseScene", x: int, y: int, dx: int, dy: int, buttons: int, modifiers: int): pass
def on_mouse_scroll(self, window: "Window", scene: "BaseScene", x: int, y: int, scroll_x: float, scroll_y: float): pass

View file

@ -0,0 +1,11 @@
from typing import Optional
import pyglet.text
class Label(pyglet.text.Label):
def update_size(self, x: int, y: int, width: Optional[int] = None, height: Optional[int] = None):
self.x = x
self.y = y
self.width = width
self.height = height

View file

@ -11,6 +11,8 @@ class Sprite(pyglet.sprite.Sprite):
if width is not None: self.width = width if width is not None: self.width = width
if height is not None: self.height = height if height is not None: self.height = height
# property
@pyglet.sprite.Sprite.width.setter @pyglet.sprite.Sprite.width.setter
def width(self, width: int): def width(self, width: int):
self.scale_x = width / self._orig_width self.scale_x = width / self._orig_width
@ -18,3 +20,11 @@ class Sprite(pyglet.sprite.Sprite):
@pyglet.sprite.Sprite.height.setter @pyglet.sprite.Sprite.height.setter
def height(self, height: int): def height(self, height: int):
self.scale_y = height / self._orig_height self.scale_y = height / self._orig_height
# other event
def update_size(self, x: int, y: int, width: int, height: int):
self.x = x
self.y = y
self.width = width
self.height = height

View file

@ -1,3 +1,2 @@
from .BaseWidget import BaseWidget from .Label import Label
from .BaseBoxWidget import BaseBoxWidget from .Sprite import Sprite
from .BaseAdaptativeWidget import BaseAdaptativeWidget

View file

@ -3,7 +3,7 @@ from typing import TYPE_CHECKING, Callable
import pyglet.window import pyglet.window
if TYPE_CHECKING: if TYPE_CHECKING:
from source.gui.scene import BaseScene from source.gui.scene.abc import AbstractScene
class Window(pyglet.window.Window): # NOQA class Window(pyglet.window.Window): # NOQA
@ -26,16 +26,16 @@ class Window(pyglet.window.Window): # NOQA
# scene system # scene system
def set_scene(self, *scenes: "BaseScene"): def set_scene(self, *scenes: "AbstractScene"):
self.clear() self.clear()
self.add_scene(*scenes) self.add_scene(*scenes)
def add_scene(self, *scenes: "BaseScene", priority: int = 0): def add_scene(self, *scenes: "AbstractScene", priority: int = 0):
for scene in scenes: for scene in scenes:
self._scenes.insert(priority, scene) self._scenes.insert(priority, scene)
scene.on_window_added(self) scene.on_window_added(self)
def remove_scene(self, *scenes: "BaseScene"): def remove_scene(self, *scenes: "AbstractScene"):
for scene in scenes: for scene in scenes:
scene.on_window_removed(self) scene.on_window_removed(self)
self._scenes.remove(scene) self._scenes.remove(scene)