implemented the Scroller

This commit is contained in:
Faraphel 2023-02-15 13:58:04 +01:00
parent cac84ff171
commit c5c81be6ce
12 changed files with 170 additions and 13 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 B

View file

@ -4,7 +4,8 @@ import pyglet
from source.gui.scene import RoomJoin, RoomCreate, Settings from source.gui.scene import RoomJoin, RoomCreate, Settings
from source.gui.scene.abc import Scene 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: if TYPE_CHECKING:
from source.gui.window import Window from source.gui.window import Window
@ -45,7 +46,7 @@ class MainMenu(Scene):
texture_click=texture_button_click 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( self.game_join = self.add_widget(
Button, Button,
@ -60,7 +61,7 @@ class MainMenu(Scene):
texture_click=texture_button_click 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( self.settings = self.add_widget(
Button, Button,
@ -75,7 +76,7 @@ class MainMenu(Scene):
texture_click=texture_button_click 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)) self.fps_display = self.add_widget(FPSDisplay, color=(255, 255, 255, 180))

View file

@ -35,7 +35,7 @@ class RoomCreate(Scene):
) )
from source.gui.scene import MainMenu 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( self.label_ip = self.add_widget(
Text, Text,

View file

@ -33,7 +33,7 @@ class RoomJoin(Scene):
) )
from source.gui.scene import MainMenu 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( self.entry_ip = self.add_widget(
Input, Input,

View file

@ -3,7 +3,7 @@ from typing import TYPE_CHECKING
import pyglet import pyglet
from source.gui.scene.abc import Scene from source.gui.scene.abc import Scene
from source.gui.widget import Checkbox from source.gui.widget import Checkbox, Scroller, Button
if TYPE_CHECKING: if TYPE_CHECKING:
from source.gui.window import Window 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_disabled = pyglet.image.load("./assets/image/checkbox/disabled.png")
texture_tick_enabled = pyglet.image.load("./assets/image/checkbox/enabled.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( self.checkbox = self.add_widget(
Checkbox, Checkbox,
@ -25,5 +46,18 @@ class Settings(Scene):
texture_enabled=texture_tick_enabled, 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): def on_draw(self):
self.checkbox.draw() self.checkbox.draw()
self.scroller.draw()
self.back.draw()

View file

@ -65,7 +65,7 @@ class Checkbox(BoxWidget):
def on_resize(self, width: int, height: int): def on_resize(self, width: int, height: int):
self._refresh_size() 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 # lorsque le bouton est enclenché, inverse son état
self.state = not self.state self.state = not self.state

View 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()

View file

@ -1,6 +1,6 @@
from .Text import Text from .Text import Text
from .FPSDisplay import FPSDisplay
from .Button import Button from .Button import Button
from .Input import Input from .Input import Input
from .Image import Image from .Image import Image
from .Checkbox import Checkbox from .Checkbox import Checkbox
from .Scroller import Scroller

View file

@ -157,7 +157,7 @@ class BoxWidget(Widget, ABC):
self.activated = True # if the click is inside the bbox, enable the activated state self.activated = True # if the click is inside the bbox, enable the activated state
self.clicking = True # the widget is now clicked 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): def on_mouse_release(self, x: int, y: int, button: int, modifiers: int):
old_click: bool = self._clicking old_click: bool = self._clicking
@ -166,14 +166,14 @@ class BoxWidget(Widget, ABC):
if not in_bbox((x, y), self.bbox): return if not in_bbox((x, y), self.bbox): return
# if this button was the one hovered when the click was pressed # 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 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 This event is called when the bbox is released
""" """

View file

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