implemented the Scroller
This commit is contained in:
parent
cac84ff171
commit
c5c81be6ce
12 changed files with 170 additions and 13 deletions
BIN
assets/image/scroller/background.png
Normal file
BIN
assets/image/scroller/background.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 166 B |
BIN
assets/image/scroller/cursor.png
Normal file
BIN
assets/image/scroller/cursor.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 144 B |
|
@ -4,7 +4,8 @@ import pyglet
|
|||
|
||||
from source.gui.scene import RoomJoin, RoomCreate, Settings
|
||||
from source.gui.scene.abc import Scene
|
||||
from source.gui.widget import Image, Text, Button, FPSDisplay
|
||||
from source.gui.widget import Image, Text, Button
|
||||
from source.gui.widget.debug import FPSDisplay
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from source.gui.window import Window
|
||||
|
@ -45,7 +46,7 @@ class MainMenu(Scene):
|
|||
texture_click=texture_button_click
|
||||
)
|
||||
|
||||
self.game_create.on_release = lambda button, modifiers: self.window.set_scene(RoomCreate)
|
||||
self.game_create.on_release = lambda *_: self.window.set_scene(RoomCreate)
|
||||
|
||||
self.game_join = self.add_widget(
|
||||
Button,
|
||||
|
@ -60,7 +61,7 @@ class MainMenu(Scene):
|
|||
texture_click=texture_button_click
|
||||
)
|
||||
|
||||
self.game_join.on_release = lambda button, modifiers: self.window.set_scene(RoomJoin)
|
||||
self.game_join.on_release = lambda *_: self.window.set_scene(RoomJoin)
|
||||
|
||||
self.settings = self.add_widget(
|
||||
Button,
|
||||
|
@ -75,7 +76,7 @@ class MainMenu(Scene):
|
|||
texture_click=texture_button_click
|
||||
)
|
||||
|
||||
self.settings.on_release = lambda button, modifiers: self.window.set_scene(Settings)
|
||||
self.settings.on_release = lambda *_: self.window.set_scene(Settings)
|
||||
|
||||
self.fps_display = self.add_widget(FPSDisplay, color=(255, 255, 255, 180))
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ class RoomCreate(Scene):
|
|||
)
|
||||
|
||||
from source.gui.scene import MainMenu
|
||||
self.back.on_release = lambda button, modifiers: self.window.set_scene(MainMenu)
|
||||
self.back.on_release = lambda *_: self.window.set_scene(MainMenu)
|
||||
|
||||
self.label_ip = self.add_widget(
|
||||
Text,
|
||||
|
|
|
@ -33,7 +33,7 @@ class RoomJoin(Scene):
|
|||
)
|
||||
|
||||
from source.gui.scene import MainMenu
|
||||
self.back.on_release = lambda button, modifiers: self.window.set_scene(MainMenu)
|
||||
self.back.on_release = lambda *_: self.window.set_scene(MainMenu)
|
||||
|
||||
self.entry_ip = self.add_widget(
|
||||
Input,
|
||||
|
|
|
@ -3,7 +3,7 @@ from typing import TYPE_CHECKING
|
|||
import pyglet
|
||||
|
||||
from source.gui.scene.abc import Scene
|
||||
from source.gui.widget import Checkbox
|
||||
from source.gui.widget import Checkbox, Scroller, Button
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from source.gui.window import Window
|
||||
|
@ -16,6 +16,27 @@ class Settings(Scene):
|
|||
texture_tick_disabled = pyglet.image.load("./assets/image/checkbox/disabled.png")
|
||||
texture_tick_enabled = pyglet.image.load("./assets/image/checkbox/enabled.png")
|
||||
|
||||
texture_scroller_background = pyglet.image.load("./assets/image/scroller/background.png")
|
||||
texture_scroller_cursor = pyglet.image.load("./assets/image/scroller/cursor.png")
|
||||
|
||||
texture_button_normal = pyglet.image.load("./assets/image/button/normal.png")
|
||||
texture_button_hover = pyglet.image.load("./assets/image/button/hovering.png")
|
||||
texture_button_click = pyglet.image.load("./assets/image/button/clicking.png")
|
||||
|
||||
self.back = self.add_widget(
|
||||
Button,
|
||||
x=20, y=20, width=0.2, height=0.1,
|
||||
|
||||
label_text="Retour",
|
||||
|
||||
texture_normal=texture_button_normal,
|
||||
texture_hover=texture_button_hover,
|
||||
texture_click=texture_button_click
|
||||
)
|
||||
|
||||
from source.gui.scene import MainMenu
|
||||
self.back.on_release = lambda *_: self.window.set_scene(MainMenu)
|
||||
|
||||
self.checkbox = self.add_widget(
|
||||
Checkbox,
|
||||
|
||||
|
@ -25,5 +46,18 @@ class Settings(Scene):
|
|||
texture_enabled=texture_tick_enabled,
|
||||
)
|
||||
|
||||
self.scroller = self.add_widget(
|
||||
Scroller,
|
||||
|
||||
x=0.3, y=0.2, width=0.3, height=0.1,
|
||||
|
||||
texture_background=texture_scroller_background,
|
||||
texture_cursor=texture_scroller_cursor,
|
||||
|
||||
text_transform=lambda value: round(value, 2),
|
||||
)
|
||||
|
||||
def on_draw(self):
|
||||
self.checkbox.draw()
|
||||
self.scroller.draw()
|
||||
self.back.draw()
|
||||
|
|
|
@ -65,7 +65,7 @@ class Checkbox(BoxWidget):
|
|||
def on_resize(self, width: int, height: int):
|
||||
self._refresh_size()
|
||||
|
||||
def on_release(self, button: int, modifiers: int):
|
||||
def on_release(self, rel_x: int, rel_y: int, button: int, modifiers: int):
|
||||
# lorsque le bouton est enclenché, inverse son état
|
||||
self.state = not self.state
|
||||
|
||||
|
|
121
source/gui/widget/Scroller.py
Normal file
121
source/gui/widget/Scroller.py
Normal file
|
@ -0,0 +1,121 @@
|
|||
from typing import TYPE_CHECKING, Callable, Any
|
||||
|
||||
import pyglet.image
|
||||
|
||||
from source.gui.sprite import Sprite
|
||||
from source.gui.widget.abc import BoxWidget
|
||||
from source.type import Distance, Percentage
|
||||
from source.utils import dict_prefix
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from source.gui.scene.abc import Scene
|
||||
|
||||
|
||||
class Scroller(BoxWidget):
|
||||
def __init__(self, scene: "Scene",
|
||||
|
||||
texture_background: pyglet.image.AbstractImage,
|
||||
texture_cursor: pyglet.image.AbstractImage,
|
||||
|
||||
x: Distance = 0,
|
||||
y: Distance = 0,
|
||||
width: Distance = None,
|
||||
height: Distance = None,
|
||||
|
||||
from_: float = 0,
|
||||
value: float = 0.5,
|
||||
to: float = 1,
|
||||
|
||||
cursor_width: Percentage = 0.1,
|
||||
text_transform: Callable[[float], Any] = lambda value: value,
|
||||
|
||||
**kwargs):
|
||||
super().__init__(scene, x, y, width, height)
|
||||
|
||||
self.cursor_width = cursor_width
|
||||
self.text_transform = text_transform
|
||||
|
||||
self.background = Sprite(
|
||||
img=texture_background,
|
||||
**dict_prefix("background_", kwargs)
|
||||
)
|
||||
self.cursor = Sprite(
|
||||
img=texture_cursor,
|
||||
**dict_prefix("cursor_", kwargs)
|
||||
)
|
||||
self.label = pyglet.text.Label(
|
||||
anchor_x="center", anchor_y="center",
|
||||
**dict_prefix("label_", kwargs)
|
||||
)
|
||||
|
||||
self._from = from_
|
||||
self._to = to
|
||||
self.value = value
|
||||
|
||||
# refresh
|
||||
|
||||
def _refresh(self):
|
||||
# background
|
||||
self.background.x, self.background.y = self.x, self.y
|
||||
self.background.width, self.background.height = self.width, self.height
|
||||
|
||||
# cursor
|
||||
self.cursor.width = self.width * self.cursor_width
|
||||
self.cursor.height = self.height
|
||||
self.cursor.y = self.y
|
||||
self.cursor.x = (
|
||||
# the base offset
|
||||
self.x
|
||||
# position the cursor relatively to the start and the end of the range
|
||||
+ (self.value - self.from_) / (self.to - self.from_) * self.background.width
|
||||
# center the cursor with its own width
|
||||
- (self.cursor.width / 2)
|
||||
)
|
||||
|
||||
# label
|
||||
self.label.x = self.x + (self.width / 2)
|
||||
self.label.y = self.y + (self.height / 2)
|
||||
self.label.text = str(self.text_transform(self.value))
|
||||
|
||||
# property
|
||||
|
||||
def on_pressed(self, rel_x: int, rel_y: int, button: int, modifiers: int):
|
||||
self.value = rel_x / self.width
|
||||
|
||||
@property
|
||||
def value(self):
|
||||
return self._value
|
||||
|
||||
@value.setter
|
||||
def value(self, value: float):
|
||||
if not self.from_ <= value <= self.to: raise ValueError(f"The value is not in range")
|
||||
self._value = value
|
||||
self._refresh()
|
||||
|
||||
@property
|
||||
def from_(self):
|
||||
return self._from
|
||||
|
||||
@from_.setter
|
||||
def from_(self, from_: float):
|
||||
self._from = from_
|
||||
self._refresh()
|
||||
|
||||
@property
|
||||
def to(self):
|
||||
return self._to
|
||||
|
||||
@to.setter
|
||||
def to(self, to: float):
|
||||
self._to = to
|
||||
self._refresh()
|
||||
|
||||
# event
|
||||
|
||||
def on_resize(self, width: int, height: int):
|
||||
self._refresh()
|
||||
|
||||
def draw(self):
|
||||
self.background.draw()
|
||||
self.cursor.draw()
|
||||
self.label.draw()
|
|
@ -1,6 +1,6 @@
|
|||
from .Text import Text
|
||||
from .FPSDisplay import FPSDisplay
|
||||
from .Button import Button
|
||||
from .Input import Input
|
||||
from .Image import Image
|
||||
from .Checkbox import Checkbox
|
||||
from .Scroller import Scroller
|
||||
|
|
|
@ -157,7 +157,7 @@ class BoxWidget(Widget, ABC):
|
|||
self.activated = True # if the click is inside the bbox, enable the activated state
|
||||
self.clicking = True # the widget is now clicked
|
||||
|
||||
self.on_pressed(button, modifiers)
|
||||
self.on_pressed(x - self.x, y - self.y, button, modifiers)
|
||||
|
||||
def on_mouse_release(self, x: int, y: int, button: int, modifiers: int):
|
||||
old_click: bool = self._clicking
|
||||
|
@ -166,14 +166,14 @@ class BoxWidget(Widget, ABC):
|
|||
if not in_bbox((x, y), self.bbox): return
|
||||
|
||||
# if this button was the one hovered when the click was pressed
|
||||
if old_click: self.on_release(button, modifiers)
|
||||
if old_click: self.on_release(x - self.x, y - self.y, button, modifiers)
|
||||
|
||||
def on_pressed(self, button: int, modifiers: int):
|
||||
def on_pressed(self, rel_x: int, rel_y: int, button: int, modifiers: int):
|
||||
"""
|
||||
This event is called when the bbox is pressed
|
||||
"""
|
||||
|
||||
def on_release(self, button: int, modifiers: int):
|
||||
def on_release(self, rel_x: int, rel_y: int, button: int, modifiers: int):
|
||||
"""
|
||||
This event is called when the bbox is released
|
||||
"""
|
1
source/gui/widget/debug/__init__.py
Normal file
1
source/gui/widget/debug/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
from .FPSDisplay import FPSDisplay
|
Loading…
Reference in a new issue