From 9528ca4b134e476ca02255f4219d139f0fe18470 Mon Sep 17 00:00:00 2001 From: Maic Siemering Date: Thu, 23 Jan 2025 20:40:58 +0100 Subject: [PATCH 1/3] sneak in experimental pixelated support for UIManager --- arcade/examples/gui/2_widgets.py | 25 +++++++++++++------------ arcade/gui/surface.py | 16 +++++++++++++--- arcade/gui/ui_manager.py | 7 ++++++- arcade/gui/widgets/text.py | 29 ++++++++++++++++++++++++++++- 4 files changed, 60 insertions(+), 17 deletions(-) diff --git a/arcade/examples/gui/2_widgets.py b/arcade/examples/gui/2_widgets.py index bbb91790d..973963f23 100644 --- a/arcade/examples/gui/2_widgets.py +++ b/arcade/examples/gui/2_widgets.py @@ -13,27 +13,27 @@ import arcade from arcade.gui import ( + NinePatchTexture, UIAnchorLayout, + UIBoxLayout, UIButtonRow, + UIDropdown, + UIDummy, UIFlatButton, + UIImage, UIInputText, UILabel, - UISpace, + UIManager, + UIMessageBox, UIOnActionEvent, - UITextArea, UIOnChangeEvent, - UITextureButton, - UITextureToggle, UISlider, - UITextureSlider, - UIBoxLayout, - UIImage, - UIDummy, + UISpace, UISpriteWidget, - NinePatchTexture, - UIDropdown, - UIMessageBox, - UIManager, + UITextArea, + UITextureButton, + UITextureSlider, + UITextureToggle, UIView, ) @@ -612,6 +612,7 @@ def _show_other_widgets(self): text_area.with_padding(left=10, right=10) text_area.with_border(color=arcade.uicolor.GRAY_CONCRETE, width=2) + def main(): window = arcade.Window(title="GUI Example: Widget Gallery") window.show_view(GalleryView()) diff --git a/arcade/gui/surface.py b/arcade/gui/surface.py index ac499d0fc..c859dd3a3 100644 --- a/arcade/gui/surface.py +++ b/arcade/gui/surface.py @@ -12,7 +12,7 @@ from arcade.color import TRANSPARENT_BLACK from arcade.gl import Framebuffer from arcade.gui.nine_patch import NinePatchTexture -from arcade.types import LBWH, RGBA255, Point, Rect +from arcade.types import LBWH, Point, RGBA255, Rect class Surface: @@ -38,6 +38,7 @@ def __init__( self._size = size self._pos = position self._pixel_ratio = pixel_ratio + self._pixelated = False self.texture = self.ctx.texture(self.size_scaled, components=4) self.fbo: Framebuffer = self.ctx.framebuffer(color_attachments=[self.texture]) @@ -142,7 +143,9 @@ def draw_texture( tex.draw_rect(rect=LBWH(0, 0, width, height)) else: - arcade.draw_texture_rect(tex, LBWH(x, y, width, height), angle=angle, alpha=alpha) + arcade.draw_texture_rect( + tex, LBWH(x, y, width, height), angle=angle, alpha=alpha, pixelated=self._pixelated + ) def draw_sprite(self, x: float, y: float, width: float, height: float, sprite: arcade.Sprite): """Draw a sprite to the surface @@ -157,7 +160,7 @@ def draw_sprite(self, x: float, y: float, width: float, height: float, sprite: a sprite.position = x + width // 2, y + height // 2 sprite.width = width sprite.height = height - arcade.draw_sprite(sprite) + arcade.draw_sprite(sprite, pixelated=self._pixelated) @contextmanager def activate(self) -> Generator[Self, None, None]: @@ -226,11 +229,18 @@ def draw( Args: area: Limit the area in the surface we're drawing (l, b, w, h) + pixelated: If True, the texture will be rendered pixelated """ # Set blend function blend_func = self.ctx.blend_func self.ctx.blend_func = self.blend_func_render + # Handle the pixelated shortcut if filter is not set + if self._pixelated: + self.texture.filter = self.ctx.NEAREST, self.ctx.NEAREST + else: + self.texture.filter = self.ctx.LINEAR, self.ctx.LINEAR + self.texture.use(0) self._program["pos"] = self._pos self._program["size"] = self._size diff --git a/arcade/gui/ui_manager.py b/arcade/gui/ui_manager.py index 4f36c6cce..9a650da8c 100644 --- a/arcade/gui/ui_manager.py +++ b/arcade/gui/ui_manager.py @@ -87,6 +87,10 @@ def on_draw(): """ _enabled = False + _pixelated = False + """Experimental feature to pixelate the UI, all textures will be rendered pixelated, + which will mostly influence scaled background images. + This property has to be set right after the UIManager is created.""" DEFAULT_LAYER = 0 OVERLAY_LAYER = 10 @@ -198,6 +202,7 @@ def _get_surface(self, layer: int) -> Surface: size=self.window.get_size(), pixel_ratio=self.window.get_pixel_ratio(), ) + self._surfaces[layer]._pixelated = self._pixelated return self._surfaces[layer] @@ -316,7 +321,7 @@ def on_update(self, time_delta): """Dispatches an update event to all widgets in the UIManager.""" return self.dispatch_ui_event(UIOnUpdateEvent(self, time_delta)) - def draw(self) -> None: + def draw(self, pixelated=False) -> None: """Will draw all widgets to the window. UIManager caches all rendered widgets into a framebuffer (something like a diff --git a/arcade/gui/widgets/text.py b/arcade/gui/widgets/text.py index be72e8788..f12e78893 100644 --- a/arcade/gui/widgets/text.py +++ b/arcade/gui/widgets/text.py @@ -25,7 +25,7 @@ from arcade.gui.widgets import UIWidget from arcade.gui.widgets.layout import UIAnchorLayout from arcade.text import FontNameOrNames -from arcade.types import LBWH, RGBA255, Color, RGBOrA255 +from arcade.types import Color, LBWH, RGBA255, RGBOrA255 class UILabel(UIWidget): @@ -194,6 +194,33 @@ def text(self, value): else: self.trigger_full_render() + @property + def font_name(self) -> FontNameOrNames: + """Font name of the label. Use :py:meth:`~arcade.gui.UILabel.update_font` to change.""" + return self._label.font_name + + @property + def font_size(self) -> float: + """Font size of the label. Use :py:meth:`~arcade.gui.UILabel.update_font` to change.""" + return self._label.font_size + + @property + def font_color(self) -> Color: + """Font color of the label. Use :py:meth:`~arcade.gui.UILabel.update_font` to change.""" + return self._label.color + + @property + def bold(self) -> bool: + """Return if the label is in bold style. + Use :py:meth:`~arcade.gui.UILabel.update_font` to change.""" + return self._label.bold + + @property + def italic(self) -> bool: + """Return if the label is in italic style. + Use :py:meth:`~arcade.gui.UILabel.update_font` to change.""" + return self._label.italic + def _update_label(self): """Update the position and size of the label. From 9e0686889e11010430982fa0ab8bd06a91d402b6 Mon Sep 17 00:00:00 2001 From: Maic Siemering Date: Thu, 23 Jan 2025 21:19:26 +0100 Subject: [PATCH 2/3] fix format --- arcade/gui/surface.py | 2 +- arcade/gui/widgets/text.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arcade/gui/surface.py b/arcade/gui/surface.py index c859dd3a3..5e7af4d86 100644 --- a/arcade/gui/surface.py +++ b/arcade/gui/surface.py @@ -12,7 +12,7 @@ from arcade.color import TRANSPARENT_BLACK from arcade.gl import Framebuffer from arcade.gui.nine_patch import NinePatchTexture -from arcade.types import LBWH, Point, RGBA255, Rect +from arcade.types import LBWH, RGBA255, Point, Rect class Surface: diff --git a/arcade/gui/widgets/text.py b/arcade/gui/widgets/text.py index f12e78893..9ab122d3f 100644 --- a/arcade/gui/widgets/text.py +++ b/arcade/gui/widgets/text.py @@ -25,7 +25,7 @@ from arcade.gui.widgets import UIWidget from arcade.gui.widgets.layout import UIAnchorLayout from arcade.text import FontNameOrNames -from arcade.types import Color, LBWH, RGBA255, RGBOrA255 +from arcade.types import LBWH, RGBA255, Color, RGBOrA255 class UILabel(UIWidget): From af8dbdb40503fcb379c4592a14d24731441981b3 Mon Sep 17 00:00:00 2001 From: Maic Siemering Date: Thu, 23 Jan 2025 21:24:26 +0100 Subject: [PATCH 3/3] fix linting --- arcade/gui/ui_manager.py | 2 +- arcade/gui/widgets/text.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arcade/gui/ui_manager.py b/arcade/gui/ui_manager.py index 9a650da8c..d793a177d 100644 --- a/arcade/gui/ui_manager.py +++ b/arcade/gui/ui_manager.py @@ -88,7 +88,7 @@ def on_draw(): _enabled = False _pixelated = False - """Experimental feature to pixelate the UI, all textures will be rendered pixelated, + """Experimental feature to pixelate the UI, all textures will be rendered pixelated, which will mostly influence scaled background images. This property has to be set right after the UIManager is created.""" diff --git a/arcade/gui/widgets/text.py b/arcade/gui/widgets/text.py index 9ab122d3f..e79b19814 100644 --- a/arcade/gui/widgets/text.py +++ b/arcade/gui/widgets/text.py @@ -210,13 +210,13 @@ def font_color(self) -> Color: return self._label.color @property - def bold(self) -> bool: + def bold(self) -> bool | str: """Return if the label is in bold style. Use :py:meth:`~arcade.gui.UILabel.update_font` to change.""" return self._label.bold @property - def italic(self) -> bool: + def italic(self) -> bool | str: """Return if the label is in italic style. Use :py:meth:`~arcade.gui.UILabel.update_font` to change.""" return self._label.italic