Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions arcade/gui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
from arcade.gui.widgets import UIDummy, Rect
from arcade.gui.widgets import UIInteractiveWidget
from arcade.gui.widgets.text import UILabel, UIInputText, UITextArea
from arcade.gui.widgets.toggle import UITextureToggle
from arcade.gui.widgets import UISpace
from arcade.gui.widgets.dropdown import UIDropdown
from arcade.gui.widgets import UISpriteWidget
Expand Down Expand Up @@ -78,6 +79,7 @@
"UITextMotionEvent",
"UITextMotionSelectEvent",
"UITextureButton",
"UITextureToggle",
"UIWidget",
"UIWidgetParent",
"Surface",
Expand Down
12 changes: 6 additions & 6 deletions arcade/gui/constructs.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ def on_action(event: UIOnActionEvent):
"""

def __init__(
self,
*,
width: float,
height: float,
message_text: str,
buttons=("Ok",),
self,
*,
width: float,
height: float,
message_text: str,
buttons=("Ok",),
):
super().__init__(size_hint=(1, 1))
self.register_event_type("on_action")
Expand Down
39 changes: 39 additions & 0 deletions arcade/gui/examples/toggle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
from arcade.gui.events import UIOnChangeEvent

from arcade import View, load_texture, Window
from arcade.gui import UIManager, UIAnchorLayout
from arcade.gui.widgets.toggle import UITextureToggle


class MyView(View):
def __init__(self):
super().__init__()

self.mng = UIManager()

on_texture = load_texture(":resources:gui_basic_assets/toggle/switch_green.png")
off_texture = load_texture(":resources:gui_basic_assets/toggle/switch_red.png")
self.toggle = UITextureToggle(on_texture=on_texture, off_texture=off_texture)

# Add toggle to UIManager, use UIAnchorLayout to center on screen
self.mng.add(UIAnchorLayout(children=[self.toggle]))

# Listen for value changes
@self.toggle.event("on_change")
def print_oon_change(event: UIOnChangeEvent):
print(f"New value {event.new_value}")

def on_show_view(self):
self.mng.enable()

def on_hide_view(self):
self.mng.disable()

def on_draw(self):
self.mng.draw()


if __name__ == "__main__":
window = Window()
window.show_view(MyView())
window.run()
129 changes: 65 additions & 64 deletions arcade/gui/widgets/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,18 +211,18 @@ class UIWidget(EventDispatcher, ABC):

# TODO add padding, bg, border to constructor
def __init__(
self,
x: float = 0,
y: float = 0,
width: float = 100,
height: float = 100,
children: Iterable["UIWidget"] = tuple(),
# Properties which might be used by layouts
size_hint=None, # in percentage
size_hint_min=None, # in pixel
size_hint_max=None, # in pixel
style=None,
**kwargs,
self,
x: float = 0,
y: float = 0,
width: float = 100,
height: float = 100,
children: Iterable["UIWidget"] = tuple(),
# Properties which might be used by layouts
size_hint=None, # in percentage
size_hint_min=None, # in pixel
size_hint_max=None, # in pixel
style=None,
**kwargs,
):
self.style = style or {}

Expand Down Expand Up @@ -503,7 +503,7 @@ def with_border(self, width=2, color=(0, 0, 0)) -> "UIWidget":
return self

def with_padding(
self, top=..., right=..., bottom=..., left=..., all=...
self, top=..., right=..., bottom=..., left=..., all=...
) -> "UIWidget":
"""
Changes the padding to the given values if set. Returns itself
Expand All @@ -521,13 +521,14 @@ def with_padding(
self._padding_left = left
return self

def with_background(self,
*,
color=...,
texture=...,
start: Tuple[int, int] = None,
end: Tuple[int, int] = None
) -> "UIWidget":
def with_background(
self,
*,
color=...,
texture=...,
start: Tuple[int, int] = None,
end: Tuple[int, int] = None,
) -> "UIWidget":

"""
Set widgets background.
Expand Down Expand Up @@ -555,7 +556,7 @@ def with_background(self,
size=self.size,
start=start,
end=end,
texture=texture
texture=texture,
)

return self
Expand Down Expand Up @@ -646,16 +647,16 @@ class UIInteractiveWidget(UIWidget):
disabled = Property(False)

def __init__(
self,
x=0,
y=0,
width=100,
height=100,
size_hint=None,
size_hint_min=None,
size_hint_max=None,
style=None,
**kwargs,
self,
x=0,
y=0,
width=100,
height=100,
size_hint=None,
size_hint_min=None,
size_hint_max=None,
style=None,
**kwargs,
):
super().__init__(
x,
Expand All @@ -678,7 +679,7 @@ def on_event(self, event: UIEvent) -> Optional[bool]:
self.hovered = self.rect.collide_with_point(event.x, event.y)

if isinstance(event, UIMousePressEvent) and self.rect.collide_with_point(
event.x, event.y
event.x, event.y
):
self.pressed = True
return EVENT_HANDLED
Expand Down Expand Up @@ -720,15 +721,15 @@ class UIDummy(UIInteractiveWidget):
"""

def __init__(
self,
x=0,
y=0,
width=100,
height=100,
size_hint=None,
size_hint_min=None,
size_hint_max=None,
**kwargs,
self,
x=0,
y=0,
width=100,
height=100,
size_hint=None,
size_hint_min=None,
size_hint_max=None,
**kwargs,
):
super().__init__(
x,
Expand Down Expand Up @@ -786,18 +787,18 @@ class UISpriteWidget(UIWidget):
"""

def __init__(
self,
*,
x=0,
y=0,
width=100,
height=100,
sprite: Sprite = None,
size_hint=None,
size_hint_min=None,
size_hint_max=None,
style=None,
**kwargs,
self,
*,
x=0,
y=0,
width=100,
height=100,
sprite: Sprite = None,
size_hint=None,
size_hint_min=None,
size_hint_max=None,
style=None,
**kwargs,
):
super().__init__(
x,
Expand Down Expand Up @@ -870,17 +871,17 @@ class UISpace(UIWidget):
"""

def __init__(
self,
x=0,
y=0,
width=100,
height=100,
color=(0, 0, 0, 0),
size_hint=None,
size_hint_min=None,
size_hint_max=None,
style=None,
**kwargs,
self,
x=0,
y=0,
width=100,
height=100,
color=(0, 0, 0, 0),
size_hint=None,
size_hint_min=None,
size_hint_max=None,
style=None,
**kwargs,
):
super().__init__(
x,
Expand Down
12 changes: 8 additions & 4 deletions arcade/gui/widgets/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -489,8 +489,10 @@ def _update_size_hints(self):

max_height_per_row[row_num][col_num] = (child.height, row_span)

for row in child_sorted_row_wise[row_num: row_num + row_span]:
row[col_num: col_num + col_span] = [child] * col_span
for row in child_sorted_row_wise[
row_num : row_num + row_span # noqa: E203
]:
row[col_num : col_num + col_span] = [child] * col_span # noqa: E203

principal_width_ratio_list = []
principal_height_ratio_list = []
Expand Down Expand Up @@ -579,8 +581,10 @@ def do_layout(self):

max_height_per_row[row_num][col_num] = (child.height, row_span)

for row in child_sorted_row_wise[row_num: row_num + row_span]:
row[col_num: col_num + col_span] = [child] * col_span
for row in child_sorted_row_wise[
row_num : row_num + row_span # noqa: E203
]:
row[col_num : col_num + col_span] = [child] * col_span # noqa: E203

# making max_height_per_row and max_width_per_column uniform
for row in max_height_per_row:
Expand Down
96 changes: 96 additions & 0 deletions arcade/gui/widgets/toggle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
from PIL import ImageEnhance
from arcade.gui.surface import Surface

from arcade.gui.events import UIOnClickEvent, UIOnChangeEvent

from arcade import Texture
from arcade.gui.property import Property, bind

from arcade.gui.widgets import UIInteractiveWidget


class UITextureToggle(UIInteractiveWidget):
"""
A toggel button switching between on (True) and off (False) state.

on_texture and off_texture are required.
"""

# Experimental ui class
value: bool = Property(False) # type: ignore

def __init__(
self,
x: float = 0,
y: float = 0,
width: float = 100,
height: float = 50,
on_texture: Texture = None,
off_texture: Texture = None,
value=False,
size_hint=None,
size_hint_min=None,
size_hint_max=None,
style=None,
**kwargs
):
# Generate hover and pressed texture by changing the brightness
if on_texture is None:
raise ValueError("You have to provide a `on_texture`")
self.normal_on_tex = on_texture
enhancer = ImageEnhance.Brightness(self.normal_on_tex.image)
self.hover_on_tex = Texture(
name=self.normal_on_tex.name + "_brighter", image=enhancer.enhance(1.5)
)
self.pressed_on_tex = Texture(
name=self.normal_on_tex.name + "_darker", image=enhancer.enhance(0.5)
)

if off_texture is None:
raise ValueError("You have to provide a `off_texture`")
self.normal_off_tex = off_texture
enhancer = ImageEnhance.Brightness(self.normal_off_tex.image)
self.hover_off_tex = Texture(
name=self.normal_off_tex.name + "_brighter", image=enhancer.enhance(1.5)
)
self.pressed_off_tex = Texture(
name=self.normal_off_tex.name + "_darker", image=enhancer.enhance(0.5)
)

self.value = value
self.register_event_type("on_change")

bind(self, "value", self.trigger_render)
bind(self, "value", self._dispatch_on_change_event)

super().__init__(
x=x,
y=y,
width=width,
height=height,
size_hint=size_hint,
size_hint_min=size_hint_min,
size_hint_max=size_hint_max,
style=style,
**kwargs
)

def _dispatch_on_change_event(self):
self.dispatch_event(
"on_change", UIOnChangeEvent(self, not self.value, self.value)
)

def on_click(self, event: UIOnClickEvent):
self.value = not self.value

def do_render(self, surface: Surface):
self.prepare_render(surface)
tex = self.normal_on_tex if self.value else self.normal_off_tex
if self.pressed:
tex = self.pressed_on_tex if self.value else self.pressed_off_tex
elif self.hovered:
tex = self.hover_on_tex if self.value else self.hover_off_tex
surface.draw_texture(0, 0, self.width, self.height, tex)

def on_change(self, event: UIOnChangeEvent):
pass
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading