changed the way texture are loaded
This commit is contained in:
parent
fd2ffa7856
commit
e961f7e348
18 changed files with 101 additions and 62 deletions
|
@ -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")
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
||||
|
|
20
source/gui/texture/type/Animation.py
Normal file
20
source/gui/texture/type/Animation.py
Normal 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
|
||||
)
|
13
source/gui/texture/type/Texture.py
Normal file
13
source/gui/texture/type/Texture.py
Normal 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)
|
2
source/gui/texture/type/__init__.py
Normal file
2
source/gui/texture/type/__init__.py
Normal file
|
@ -0,0 +1,2 @@
|
|||
from .Texture import Texture
|
||||
from .Animation import Animation
|
20
source/gui/texture/type/abc/TextureType.py
Normal file
20
source/gui/texture/type/abc/TextureType.py
Normal 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
|
1
source/gui/texture/type/abc/__init__.py
Normal file
1
source/gui/texture/type/abc/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
from .TextureType import TextureType
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in a new issue