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 = self.root.add(
148                ColorButton(
149                    color_name=name,
150                    color=color,
151                    size_hint=(1, 1),
152                )
153            )
154            self.grid.add(button, row=i // 5, column=i % 5)
155
156            # connect event handler
157            button.on_choose_color = self.on_color_button_choose_color
158
159        # setup toasts (temporary messages)
160        self.toasts = self.root.add(UIBoxLayout(space_between=2), anchor_x="right", anchor_y="top")
161        self.toasts.with_padding(all=10)
162
163    def on_color_button_choose_color(self, event: ChooseColorEvent) -> bool:
164        """Color button click event handler, which copies the color name to the clipboard.
165
166        And shows a temporary message."""
167        self.window.set_clipboard_text(f"arcade.uicolor.{event.color_name}")
168
169        # prepare and show toast
170        toast = Toast(f"Copied {event.color_name}", width=250, size_hint=(None, 0))
171        toast.update_font(
172            font_color=arcade.uicolor.DARK_BLUE_MIDNIGHT_BLUE,
173            font_size=9,
174            bold=True,
175        )
176        toast.with_background(color=arcade.uicolor.GREEN_EMERALD)
177        toast.with_padding(all=10)
178
179        self.toasts.add(toast)
180
181        return True
182
183    def on_draw_before_ui(self):
184        # Add draw commands that should be below the UI
185        pass
186
187    def on_draw_after_ui(self):
188        # Add draw commands that should be on top of the UI (uncommon)
189        pass
190
191
192def main():
193    window = arcade.Window(title="GUI Example: Color Picker")
194    window.show_view(ColorView())
195    window.run()
196
197
198if __name__ == "__main__":
199    main()