changed the way texture are loaded

This commit is contained in:
Faraphel 2023-02-27 15:18:12 +01:00
parent fd2ffa7856
commit e961f7e348
18 changed files with 101 additions and 62 deletions

View file

@ -1,10 +1,10 @@
from . import path
from .abc import Style
from source.gui.texture.type import Texture
path = path / "background"
class Background(Style):
main = path / "main.png"
game = path / "game.png"
main = Texture(path / "main.png")
game = Texture(path / "game.png")

View file

@ -1,11 +1,12 @@
from . import path
from .abc import Style
from source.gui.texture.type import Texture
path = path / "button"
class Button:
class Style1(Style):
normal = path / "normal.png"
click = path / "clicking.png"
hover = path / "hovering.png"
normal = Texture(path / "normal.png")
click = Texture(path / "clicking.png")
hover = Texture(path / "hovering.png")

View file

@ -1,10 +1,11 @@
from . import path
from .abc import Style
from .type import Texture
path = path / "checkbox"
class Checkbox:
class Style1(Style):
disabled = path / "disabled.png"
enabled = path / "enabled.png"
disabled = Texture(path / "disabled.png")
enabled = Texture(path / "enabled.png")

View file

@ -1,5 +1,6 @@
from . import path
from .abc import Style
from .type import Texture, Animation
path = path / "grid"
path_boat = path / "boat"
@ -8,13 +9,13 @@ path_bomb = path / "bomb"
class Grid:
class Style1(Style):
background = path / "background.png"
background = Texture(path / "background.png")
class Boat:
class Style1(Style):
body = path_boat / "body.png"
edge = path_boat / "edge.png"
solo = path_boat / "solo.png"
body = Texture(path_boat / "body.png")
edge = Texture(path_boat / "edge.png")
solo = Texture(path_boat / "solo.png")
class Bomb:
class Style1(Style):
@ -23,5 +24,5 @@ class Grid:
key=lambda path: int(path.stem)
)
missed = [*_animation, path_bomb / "missed.png"], 0.03, False
touched = [*_animation, path_bomb / "touched.png"], 0.03, False
missed = Animation([*_animation, path_bomb / "missed.png"], 0.03, False)
touched = Animation([*_animation, path_bomb / "touched.png"], 0.03, False)

View file

@ -1,11 +1,12 @@
from . import path
from .abc import Style
from .type import Texture
path = path / "input"
class Input:
class Style1(Style):
normal = path / "normal.png"
active = path / "active.png"
error = path / "error.png"
normal = Texture(path / "normal.png")
active = Texture(path / "active.png")
error = Texture(path / "error.png")

View file

@ -1,10 +1,11 @@
from . import path
from .abc import Style
from .type import Animation
path = path / "result"
class Result:
class Style1(Style):
victory = (path / "victory").iterdir(), 0.04, False
defeat = (path / "defeat").iterdir(), 0.04, False
victory = Animation((path / "victory").iterdir(), 0.04, False)
defeat = Animation((path / "defeat").iterdir(), 0.04, False)

View file

@ -1,10 +1,11 @@
from . import path
from .abc import Style
from .type import Texture
path = path / "scroller"
class Scroller:
class Style1(Style):
background = path / "background.png"
cursor = path / "cursor.png"
background = Texture(path / "background.png")
cursor = Texture(path / "cursor.png")

View file

@ -8,33 +8,12 @@ import pyglet
class Style(ABC):
"""
This class represent a style that can be attached to a widget.
All property of the class will be loaded into a pyglet image.
If the property is associated to only a Path, a simple image will be loaded.
If the property is associated to a list of Path, an animation will be loaded.
"""
def __init_subclass__(cls, **kwargs):
for name, args in cls.__dict__.items():
if name.startswith("_"): continue
if isinstance(args, Path): # if this is a normal path for a normal image
path = args
texture = pyglet.image.load(path)
elif isinstance(args, tuple) and len(args) == 3: # if this is a tuple for an animation
paths, duration, loop = args
textures = map(pyglet.image.load, paths)
texture = pyglet.image.Animation.from_image_sequence(textures, duration, loop)
else:
raise ValueError(f"Invalid type : {type(args)}")
setattr(cls, name, texture)
@classmethod
def __getattr__(cls, item):
return None # by default, an object will be None if not found.
@classmethod
def get(cls, item: str, default: Any = None) -> Optional[pyglet.image.AbstractImage]:
def get(cls, item, default=None):
return getattr(cls, item, default)
def __class_getitem__(cls, item: str) -> Optional[pyglet.image.AbstractImage]:
return cls.get(item)

View file

@ -0,0 +1,20 @@
from pathlib import Path
from typing import Iterable
import pyglet
from source.gui.texture.type.abc import TextureType
class Animation(TextureType):
def __init__(self, paths: Iterable[Path], frame_duration: float, loop: bool = True):
self.paths = paths
self.frame_duration = frame_duration
self.loop = loop
def __get__(self, instance, owner) -> pyglet.image.Animation:
return pyglet.image.Animation.from_image_sequence(
sequence=map(self.get_texture, self.paths),
duration=self.frame_duration,
loop=self.loop
)

View file

@ -0,0 +1,13 @@
from pathlib import Path
import pyglet
from source.gui.texture.type.abc import TextureType
class Texture(TextureType):
def __init__(self, path: Path):
self.path = path
def __get__(self, instance, owner) -> pyglet.image.AbstractImage:
return self.get_texture(self.path)

View file

@ -0,0 +1,2 @@
from .Texture import Texture
from .Animation import Animation

View file

@ -0,0 +1,20 @@
from abc import ABC, abstractmethod
from pathlib import Path
import pyglet
class TextureType(ABC):
loaded_image: dict[Path, pyglet.image.AbstractImage] = {}
@classmethod
def get_texture(cls, path: Path) -> pyglet.image.AbstractImage:
if (texture := cls.loaded_image.get(path)) is None:
texture = pyglet.image.load(path)
cls.loaded_image[path] = texture
return texture
@abstractmethod
def __get__(self, instance, owner) -> pyglet.image.AbstractImage:
pass

View file

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

View file

@ -1,4 +1,4 @@
from typing import TYPE_CHECKING, Optional, Type
from typing import TYPE_CHECKING, Type
import pyglet
@ -33,7 +33,7 @@ class Button(BoxWidget):
self.style = style
self.background = Sprite(
img=self.style.get("normal"),
img=self.style.normal,
**dict_filter_prefix("background_", kwargs)
)
@ -60,9 +60,9 @@ class Button(BoxWidget):
"""
return (
texture if self.clicking and (texture := self.style.get("click")) is not None else # NOQA
texture if self.hovering and (texture := self.style.get("hover")) is not None else
self.style.get("normal")
texture if self.clicking and (texture := self.style.click) is not None else # NOQA
texture if self.hovering and (texture := self.style.hover) is not None else
self.style.normal
)
# refresh

View file

@ -1,7 +1,5 @@
from typing import TYPE_CHECKING, Type
import pyglet.image
from source.gui.sprite import Sprite
from source.gui.texture.abc import Style
from source.gui.widget.abc import BoxWidget
@ -33,7 +31,7 @@ class Checkbox(BoxWidget):
self.style = style
self.tick = Sprite(img=self.style.get("disabled"), **kwargs)
self.tick = Sprite(img=self.style.disabled, **kwargs)
self.state = state

View file

@ -61,7 +61,7 @@ class GameGrid(BoxWidget):
self.bomb_style = bomb_style
self.background = Sprite(
img=grid_style.get("background"),
img=grid_style.background,
**dict_filter_prefix("background_", kwargs)
)
@ -224,7 +224,7 @@ class GameGrid(BoxWidget):
def place_bomb(self, cell: Point2D, touched: bool):
self.cell_sprites[cell] = Sprite(
img=self.bomb_style.get("touched" if touched else "missed"),
img=self.bomb_style.touched if touched else self.bomb_style.missed,
**self._bomb_kwargs
)

View file

@ -39,7 +39,7 @@ class Input(BoxWidget):
self.regex = re.compile(regex) if isinstance(regex, str) else regex
self.background = Sprite(
img=self.style.get("normal"),
img=self.style.normal,
**dict_filter_prefix("background_", kwargs)
)
@ -65,9 +65,9 @@ class Input(BoxWidget):
"""
return (
texture if self.activated and (texture := self.style.get("active")) is not None else # NOQA
texture if self.invalid and (texture := self.style.get("signal")) is not None else
self.style.get("normal")
texture if self.activated and (texture := self.style.active) is not None else # NOQA
texture if self.invalid and (texture := self.style.signal) is not None else
self.style.normal
)
# refresh

View file

@ -43,12 +43,12 @@ class Scroller(BoxWidget):
self.text_transform = text_transform
self.background = Sprite(
img=self.style.get("background"),
img=self.style.background,
**dict_filter_prefix("background_", kwargs)
)
self.cursor = Sprite(
img=self.style.get("cursor"),
img=self.style.cursor,
**dict_filter_prefix("cursor_", kwargs)
)