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 . import path
from .abc import Style from .abc import Style
from source.gui.texture.type import Texture
path = path / "background" path = path / "background"
class Background(Style): class Background(Style):
main = path / "main.png" main = Texture(path / "main.png")
game = path / "game.png" game = Texture(path / "game.png")

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -8,33 +8,12 @@ import pyglet
class Style(ABC): class Style(ABC):
""" """
This class represent a style that can be attached to a widget. 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): @classmethod
for name, args in cls.__dict__.items(): def __getattr__(cls, item):
if name.startswith("_"): continue return None # by default, an object will be None if not found.
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 @classmethod
def get(cls, item: str, default: Any = None) -> Optional[pyglet.image.AbstractImage]: def get(cls, item, default=None):
return getattr(cls, item, default) 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 import pyglet
@ -33,7 +33,7 @@ class Button(BoxWidget):
self.style = style self.style = style
self.background = Sprite( self.background = Sprite(
img=self.style.get("normal"), img=self.style.normal,
**dict_filter_prefix("background_", kwargs) **dict_filter_prefix("background_", kwargs)
) )
@ -60,9 +60,9 @@ class Button(BoxWidget):
""" """
return ( return (
texture if self.clicking and (texture := self.style.get("click")) is not None else # NOQA texture if self.clicking and (texture := self.style.click) is not None else # NOQA
texture if self.hovering and (texture := self.style.get("hover")) is not None else texture if self.hovering and (texture := self.style.hover) is not None else
self.style.get("normal") self.style.normal
) )
# refresh # refresh

View file

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

View file

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

View file

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

View file

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