GUI UIColor Picker

Arcade provides constants for colors, which work great for GUI widgets. They are based on FlatUI colors.

This example provides an interactive color picker, widgets can be used as a util to find the right color for your GUI widgets.

Screen shot of advanced button usage
5_uicolor_picker.py
  1"""Show all arcade.uicolors in a grid.
  2
  3Click on a color to select
  4it and copy the Arcade reference to the clipboard.
  5
  6If Arcade and Python are properly installed, you can run this example with:
  7python -m arcade.examples.gui.5_uicolor_picker
  8
  9"""
 10
 11from dataclasses import dataclass
 12
 13import arcade
 14from arcade.gui import (
 15    UIAnchorLayout,
 16    UIBoxLayout,
 17    UIEvent,
 18    UIGridLayout,
 19    UIInteractiveWidget,
 20    UILabel,
 21    UITextWidget,
 22    UIView,
 23)
 24
 25
 26@dataclass
 27class ChooseColorEvent(UIEvent):
 28    """Custom event, which is dispatched when a color button is clicked."""
 29
 30    color_name: str
 31    color: arcade.color.Color
 32
 33
 34class Toast(UILabel):
 35    """Label which disappears after a certain time."""
 36
 37    def __init__(self, text: str, duration: float = 2.0, **kwargs):
 38        super().__init__(**kwargs)
 39        self.text = text
 40        self.duration = duration
 41        self.time = 0
 42
 43    def on_update(self, dt):
 44        self.time += dt
 45
 46        if self.time > self.duration:
 47            self.parent.remove(self)
 48
 49
 50class ColorButton(UITextWidget, UIInteractiveWidget):
 51    """Button which shows a color and color name and
 52    emits a ChooseColorEvent event when clicked."""
 53
 54    def __init__(
 55        self,
 56        color_name: str,
 57        color: arcade.color.Color,
 58        **kwargs,
 59    ):
 60        super().__init__(text=color_name, **kwargs)
 61        # set color and place text on the bottom
 62        self.with_background(color=color)
 63        self.place_text(anchor_y="bottom")
 64
 65        # set font color based on background color
 66        f = 2 if color_name.startswith("DARK") else 0.5
 67        self.ui_label.update_font(
 68            font_color=arcade.color.Color(int(color[0] * f), int(color[1] * f), int(color[2] * f))
 69        )
 70
 71        # store color name and color for later reference
 72        self._color_name = color_name
 73        self._color = color
 74
 75        # register custom event
 76        self.register_event_type("on_choose_color")
 77
 78    def on_update(self, dt):
 79        """Update the button state.
 80
 81        UIInteractiveWidget provides properties like hovered and pressed,
 82        which can be used to highlight the button."""
 83        if self.pressed:
 84            self.with_border(color=arcade.uicolor.WHITE_CLOUDS, width=3)
 85        elif self.hovered:
 86            self.with_border(color=arcade.uicolor.WHITE_CLOUDS, width=2)
 87        else:
 88            self.with_border(color=arcade.color.BLACK, width=1)
 89
 90    def on_click(self, event) -> bool:
 91        """Emit a ChooseColorEvent event when clicked."""
 92        self.dispatch_event(
 93            "on_choose_color", ChooseColorEvent(self, self._color_name, self._color)
 94        )
 95        return True
 96
 97    def on_choose_color(self, event: ChooseColorEvent):
 98        """ChooseColorEvent event handler, which can be overridden."""
 99        pass
100
101
102class ColorView(UIView):
103    """Uses the arcade.gui.UIView which takes care about the UIManager setup."""
104
105    def __init__(self):
106        super().__init__()
107        # Create an anchor layout, which can be used to position widgets on screen
108        self.root = self.add_widget(UIAnchorLayout())
109
110        # Define colors in grid order
111        self.colors = {
112            # row 0
113            "GREEN_TURQUOISE": arcade.uicolor.GREEN_TURQUOISE,
114            "GREEN_EMERALD": arcade.uicolor.GREEN_EMERALD,
115            "BLUE_PETER_RIVER": arcade.uicolor.BLUE_PETER_RIVER,
116            "PURPLE_AMETHYST": arcade.uicolor.PURPLE_AMETHYST,
117            "DARK_BLUE_WET_ASPHALT": arcade.uicolor.DARK_BLUE_WET_ASPHALT,
118            # row 1
119            "GREEN_GREEN_SEA": arcade.uicolor.GREEN_GREEN_SEA,
120            "GREEN_NEPHRITIS": arcade.uicolor.GREEN_NEPHRITIS,
121            "BLUE_BELIZE_HOLE": arcade.uicolor.BLUE_BELIZE_HOLE,
122            "PURPLE_WISTERIA": arcade.uicolor.PURPLE_WISTERIA,
123            "DARK_BLUE_MIDNIGHT_BLUE": arcade.uicolor.DARK_BLUE_MIDNIGHT_BLUE,
124            # row 2
125            "YELLOW_SUN_FLOWER": arcade.uicolor.YELLOW_SUN_FLOWER,
126            "ORANGE_CARROT": arcade.uicolor.ORANGE_CARROT,
127            "RED_ALIZARIN": arcade.uicolor.RED_ALIZARIN,
128            "WHITE_CLOUDS": arcade.uicolor.WHITE_CLOUDS,
129            "GRAY_CONCRETE": arcade.uicolor.GRAY_CONCRETE,
130            # row 3
131            "YELLOW_ORANGE": arcade.uicolor.YELLOW_ORANGE,
132            "ORANGE_PUMPKIN": arcade.uicolor.ORANGE_PUMPKIN,
133            "RED_POMEGRANATE": arcade.uicolor.RED_POMEGRANATE,
134            "WHITE_SILVER": arcade.uicolor.WHITE_SILVER,
135            "GRAY_ASBESTOS": arcade.uicolor.GRAY_ASBESTOS,
136        }
137
138        # setup grid with colors
139        self.grid = self.root.add(
140            UIGridLayout(
141                column_count=5,
142                row_count=4,
143                size_hint=(1, 1),
144            )
145        )
146        for i, (name, color) in enumerate(self.colors.items()):
147            button = ColorButton(
148                color_name=name,
149                color=color,
150                size_hint=(1, 1),
151            )
152            self.grid.add(button, row=i // 5, column=i % 5)
153
154            # connect event handler
155            button.on_choose_color = self.on_color_button_choose_color
156
157        # setup toasts (temporary messages)
158        self.toasts = self.root.add(UIBoxLayout(space_between=2), anchor_x="right", anchor_y="top")
159        self.toasts.with_padding(all=10)
160
161    def on_color_button_choose_color(self, event: ChooseColorEvent) -> bool:
162        """Color button click event handler, which copies the color name to the clipboard.
163
164        And shows a temporary message."""
165        self.window.set_clipboard_text(f"arcade.uicolor.{event.color_name}")
166
167        # prepare and show toast
168        toast = Toast(f"Copied {event.color_name}", width=250, size_hint=(None, 0))
169        toast.update_font(
170            font_color=arcade.uicolor.DARK_BLUE_MIDNIGHT_BLUE,
171            font_size=9,
172            bold=True,
173        )
174        toast.with_background(color=arcade.uicolor.GREEN_EMERALD)
175        toast.with_padding(all=10)
176
177        self.toasts.add(toast)
178
179        return True
180
181    def on_draw_before_ui(self):
182        # Add draw commands that should be below the UI
183        pass
184
185    def on_draw_after_ui(self):
186        # Add draw commands that should be on top of the UI (uncommon)
187        pass
188
189
190def main():
191    window = arcade.Window(title="GUI Example: Color Picker")
192    window.show_view(ColorView())
193    window.run()
194
195
196if __name__ == "__main__":
197    main()