Source code for arcade.gui.widgets.buttons

import arcade
from arcade import Texture
from arcade.experimental.uistyle import UIFlatButtonStyle_default
from arcade.gui.property import Property, bind
from arcade.gui.widgets import UIInteractiveWidget, Surface


[docs]class UITextureButton(UIInteractiveWidget): """ A button with an image for the face of the button. :param float x: x coordinate of bottom left :param float y: y coordinate of bottom left :param float width: width of widget. Defaults to texture width if not specified. :param float height: height of widget. Defaults to texture height if not specified. :param Texture texture: texture to display for the widget. :param Texture texture_hovered: different texture to display if mouse is hovering over button. :param Texture texture_pressed: different texture to display if mouse button is pressed while hovering over button. :param str text: text to add to the button. :param style: style information for the button. :param float scale: scale the button, based on the base texture size. :param size_hint: Tuple of floats (0.0-1.0), 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 """ def __init__( self, x: float = 0, y: float = 0, width: float = None, height: float = None, texture: Texture = None, texture_hovered: Texture = None, texture_pressed: Texture = None, text: str = "", scale: float = None, size_hint=None, size_hint_min=None, size_hint_max=None, style=None, **kwargs, ): if width is None and texture is not None: width = texture.width if height is None and texture is not None: height = texture.height if scale is not None and texture is not None: height = texture.height * scale width = texture.width * scale super().__init__( x, y, width, height, size_hint=size_hint, size_hint_min=size_hint_min, size_hint_max=size_hint_max, ) self._tex = texture self._tex_hovered = texture_hovered self._tex_pressed = texture_pressed self._style = style or {} self._text = text @property def text(self): return self._text @text.setter def text(self, value): self._text = value self.trigger_render() @property def texture(self): return self._tex @texture.setter def texture(self, value: Texture): self._tex = value self.trigger_render() @property def texture_hovered(self): return self._tex_hovered @texture_hovered.setter def texture_hovered(self, value: Texture): self._tex_hovered = value self.trigger_render() @property def texture_pressed(self): return self._tex_pressed @texture_pressed.setter def texture_pressed(self, value: Texture): self._tex_pressed = value self.trigger_render() def do_render(self, surface: Surface): self.prepare_render(surface) tex = self._tex if self.pressed and self._tex_pressed: tex = self._tex_pressed elif self.hovered and self._tex_hovered: tex = self._tex_hovered if tex: surface.draw_texture(0, 0, self.width, self.height, tex) if self.text: text_margin = 2 font_size = self._style.get("font_size", 15) font_color = self._style.get("font_color", arcade.color.WHITE) border_width = self._style.get("border_width", 2) # border_color = self._style.get("border_color", None) # bg_color = self._style.get("bg_color", (21, 19, 21)) start_x = self.width // 2 start_y = self.height // 2 + 4 if self.pressed: start_y -= 2 arcade.draw_text( text=self.text, start_x=start_x, start_y=start_y, font_size=font_size, color=font_color, align="center", anchor_x="center", anchor_y="center", width=self.width - 2 * border_width - 2 * text_margin, )
[docs]class UIFlatButton(UIInteractiveWidget): """ A text button, with support for background color and a border. :param float x: x coordinate of bottom left :param float y: y coordinate of bottom left :param float width: width of widget. Defaults to texture width if not specified. :param float height: height of widget. Defaults to texture height if not specified. :param str text: text to add to the button. :param style: Used to style the button """ text = Property("") def __init__( self, x: float = 0, y: float = 0, width: float = 100, height: float = 50, text="", size_hint=None, size_hint_min=None, size_hint_max=None, style=None, **kwargs, ): super().__init__( x, y, width, height, size_hint=size_hint, size_hint_min=size_hint_min, size_hint_max=size_hint_max, style=style or UIFlatButtonStyle_default, ) self.text = text bind(self, "text", self.trigger_render) def do_render(self, surface: Surface): self.prepare_render(surface) if self.disabled: state = "disabled" elif self.pressed: state = "press" elif self.hovered: state = "hover" else: state = "normal" style = self.style[state] # Render button font_name = style.get("font_name") font_size = style.get("font_size") font_color = style.get("font_color") border_width = style.get("border_width") border_color = style.get("border") bg_color = style.get("bg") if bg_color: surface.clear(bg_color) # render button border (which is not the widgets border) if border_color and border_width: arcade.draw_xywh_rectangle_outline( border_width, border_width, self.content_width - 2 * border_width, self.content_height - 2 * border_width, color=border_color, border_width=border_width, ) # render text if self.text and font_color: start_x = self.content_width // 2 start_y = self.content_height // 2 text_margin = 2 arcade.draw_text( text=self.text, start_x=start_x, start_y=start_y, font_name=font_name, # type: ignore font_size=font_size, # type: ignore color=font_color, # type: ignore align="center", anchor_x="center", anchor_y="center", width=self.content_width - 2 * (border_width or 0) - 2 * text_margin, )