From 7bd1448224dc73535d40267c2ef907a5bf2cdc44 Mon Sep 17 00:00:00 2001 From: Aspect1103 Date: Tue, 21 Jun 2022 10:12:56 +0100 Subject: [PATCH 1/4] Created UIButtonRow. --- arcade/gui/__init__.py | 2 ++ arcade/gui/widgets/layout.py | 37 +++++++++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/arcade/gui/__init__.py b/arcade/gui/__init__.py index 5c14dd5a94..358cccefda 100644 --- a/arcade/gui/__init__.py +++ b/arcade/gui/__init__.py @@ -22,6 +22,7 @@ UIAnchorLayout, UIGridLayout, UILayout, + UIButtonRow, ) from arcade.gui.widgets import UIDummy, Rect from arcade.gui.widgets import UIInteractiveWidget @@ -42,6 +43,7 @@ __all__ = [ "UIAnchorLayout", "UIBoxLayout", + "UIButtonRow", "UIGridLayout", "UIManager", "UIMessageBox", diff --git a/arcade/gui/widgets/layout.py b/arcade/gui/widgets/layout.py index 4cba0afa8e..1763be72d4 100644 --- a/arcade/gui/widgets/layout.py +++ b/arcade/gui/widgets/layout.py @@ -1,7 +1,8 @@ -from typing import Iterable, TypeVar, Tuple +from typing import Iterable, TypeVar, Tuple, Any, Callable from arcade.gui.property import bind from arcade.gui.widgets import UIWidget, UILayout +from arcade.gui.widgets.buttons import UIFlatButton W = TypeVar("W", bound="UIWidget") @@ -545,3 +546,37 @@ def do_layout(self): child.rect = new_rect start_y -= max_height_row + + +class UIButtonRow(UIBoxLayout): + """""" + def __init__( + self, + align: str = "center", + size_hint: Any = (0, 0), + size_hint_min: Any = None, + size_hint_max: Any = None, + space_between: int = 10, + style: Any = None, + button_labels: Tuple[str, ...] = (), + callback: Callable = None, + ): + super().__init__( + vertical=False, + align=align, + size_hint=size_hint, + size_hint_min=size_hint_min, + size_hint_max=size_hint_max, + space_between=space_between, + style=style + ) + self._callback = callback + + for button_text in button_labels: + button = UIFlatButton(text=button_text) + button.on_click = self.on_ok # type: ignore + self.add(button) + + def on_ok(self, event): + if self._callback: + self._callback(event.source.text) From 7f0b883377f3fafb23a6b214168fdbfc17f7ed57 Mon Sep 17 00:00:00 2001 From: Aspect1103 Date: Tue, 21 Jun 2022 21:33:47 +0100 Subject: [PATCH 2/4] Added docstring and vertical parameter to UIButtonRow. --- arcade/gui/widgets/layout.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/arcade/gui/widgets/layout.py b/arcade/gui/widgets/layout.py index 1763be72d4..51c178b6a5 100644 --- a/arcade/gui/widgets/layout.py +++ b/arcade/gui/widgets/layout.py @@ -549,9 +549,22 @@ def do_layout(self): class UIButtonRow(UIBoxLayout): - """""" + """ + Places buttons in a row. + + :param bool vertical: Whether the button row is vertical or not. + :param str align: Where to align the button row. + :param Any size_hint: Tuple of floats (0.0 - 1.0) of how much space of the parent should be requested. + :param size_hint_min: Min width and height in pixel. + :param size_hint_max: Max width and height in pixel. + :param int space_between: The space between the children. + :param Any style: Not used. + :param Tuple[str, ...] button_labels: The labels for the buttons. + :param Callable callback: The callback function which will receive the text of the clicked button. + """ def __init__( self, + vertical: bool = False, align: str = "center", size_hint: Any = (0, 0), size_hint_min: Any = None, @@ -562,7 +575,7 @@ def __init__( callback: Callable = None, ): super().__init__( - vertical=False, + vertical=vertical, align=align, size_hint=size_hint, size_hint_min=size_hint_min, From 45836c0e7b43551fcbe059cccaca31a2be9c1a6b Mon Sep 17 00:00:00 2001 From: Aspect1103 Date: Wed, 22 Jun 2022 21:09:39 +0100 Subject: [PATCH 3/4] Updated UIButtonRow as per review. --- arcade/gui/__init__.py | 2 ++ arcade/gui/events.py | 5 +++++ arcade/gui/widgets/layout.py | 27 +++++++++++++++------------ 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/arcade/gui/__init__.py b/arcade/gui/__init__.py index 358cccefda..ce97786e41 100644 --- a/arcade/gui/__init__.py +++ b/arcade/gui/__init__.py @@ -15,6 +15,7 @@ from arcade.gui.events import UITextEvent from arcade.gui.events import UITextMotionEvent from arcade.gui.events import UITextMotionSelectEvent +from arcade.gui.events import UIOnActionEvent from arcade.gui.surface import Surface from arcade.gui.ui_manager import UIManager from arcade.gui.widgets.layout import ( @@ -67,6 +68,7 @@ "UIMousePressEvent", "UIMouseReleaseEvent", "UIMouseScrollEvent", + "UIOnActionEvent", "UIOnUpdateEvent", "UIOnChangeEvent", "UIOnClickEvent", diff --git a/arcade/gui/events.py b/arcade/gui/events.py index ddb8a0a552..29c2785eb1 100644 --- a/arcade/gui/events.py +++ b/arcade/gui/events.py @@ -112,3 +112,8 @@ class UIOnChangeEvent(UIEvent): old_value: Any new_value: Any + + +@dataclass +class UIOnActionEvent(UIMouseEvent): + pass diff --git a/arcade/gui/widgets/layout.py b/arcade/gui/widgets/layout.py index 51c178b6a5..25729bf1b9 100644 --- a/arcade/gui/widgets/layout.py +++ b/arcade/gui/widgets/layout.py @@ -3,6 +3,7 @@ from arcade.gui.property import bind from arcade.gui.widgets import UIWidget, UILayout from arcade.gui.widgets.buttons import UIFlatButton +from arcade.gui.events import UIOnActionEvent, UIOnClickEvent W = TypeVar("W", bound="UIWidget") @@ -559,8 +560,6 @@ class UIButtonRow(UIBoxLayout): :param size_hint_max: Max width and height in pixel. :param int space_between: The space between the children. :param Any style: Not used. - :param Tuple[str, ...] button_labels: The labels for the buttons. - :param Callable callback: The callback function which will receive the text of the clicked button. """ def __init__( self, @@ -571,8 +570,6 @@ def __init__( size_hint_max: Any = None, space_between: int = 10, style: Any = None, - button_labels: Tuple[str, ...] = (), - callback: Callable = None, ): super().__init__( vertical=vertical, @@ -583,13 +580,19 @@ def __init__( space_between=space_between, style=style ) - self._callback = callback + self.register_event_type("on_action") - for button_text in button_labels: - button = UIFlatButton(text=button_text) - button.on_click = self.on_ok # type: ignore - self.add(button) + def add_button(self, label: str, *, on_click: Callable = None, style: Any = None) -> None: + button = UIFlatButton(text=label, style=style) + button.on_click = self._on_click # type: ignore + self.add(button) - def on_ok(self, event): - if self._callback: - self._callback(event.source.text) + if on_click: + # Add on_click callback as event handler + button.event("on_click")(on_click) + + def on_action(self, event: UIOnActionEvent) -> None: + pass + + def _on_click(self, event: UIOnClickEvent) -> None: + self.dispatch_event("on_action", UIOnActionEvent(event.source, event.source.text)) From fe7488e851ffe1a7549c25a00aa22ddba79d07d5 Mon Sep 17 00:00:00 2001 From: Aspect1103 Date: Wed, 22 Jun 2022 21:17:48 +0100 Subject: [PATCH 4/4] Fixed mypy error. --- arcade/gui/widgets/layout.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arcade/gui/widgets/layout.py b/arcade/gui/widgets/layout.py index 25729bf1b9..de997268e2 100644 --- a/arcade/gui/widgets/layout.py +++ b/arcade/gui/widgets/layout.py @@ -595,4 +595,4 @@ def on_action(self, event: UIOnActionEvent) -> None: pass def _on_click(self, event: UIOnClickEvent) -> None: - self.dispatch_event("on_action", UIOnActionEvent(event.source, event.source.text)) + self.dispatch_event("on_action", UIOnActionEvent(self, event.source, event.source.text))