unicornpaint

A web-based painting app for raspberry PI and pimoroni Unicorn Hat HD
Log | Files | Refs | README

unicorn_hat_sim.py (3748B)


      1 import sys
      2 import colorsys
      3 import pygame.gfxdraw
      4 
      5 try:
      6     import pygame
      7 except ImportError:
      8     print("To simulate a unicorn HAT on your computer, please pip install pygame")
      9 
     10 class UnicornHatSim(object):
     11     def __init__(self, width, height, rotation_offset = 0):
     12         # Compat with old library
     13         self.AUTO = None
     14         self.PHAT = None
     15             
     16         # Set some defaults
     17         self.rotation_offset = rotation_offset
     18         self.rotation(0)
     19         self.pixels = [(0, 0, 0)] * width * height
     20         self.pixel_size = 15
     21         self.width = width
     22         self.height = height
     23         self.window_width = width * self.pixel_size
     24         self.window_height = height * self.pixel_size
     25 
     26         # Init pygame and off we go
     27         pygame.init()
     28         pygame.display.set_caption("Unicorn HAT simulator")
     29         self.screen = pygame.display.set_mode([self.window_width, self.window_height])
     30         # self.clear()
     31         self.screen.fill((0, 0, 0))
     32 
     33     def set_pixel(self, x, y, r, g, b):
     34         i = (x * self.width) + y
     35         self.pixels[i] = [int(r), int(g), int(b)]
     36 
     37     def get_pixels(self):
     38         """Returns a 2d array of 3-tuple RGB values repsenting pixel colours """
     39         px = []
     40         for y in range(self.height):
     41             row = []
     42             for x in range(self.width):
     43                 i = (x * self.width) + y
     44                 row.append(self.pixels[i])
     45             px.append(row)
     46         return px
     47 
     48     def draw(self):
     49         for event in pygame.event.get(): # User did something
     50             if event.type == pygame.QUIT:
     51                 print("Exiting...")
     52                 sys.exit()
     53 
     54         for x in range(self.width):
     55             for y in range(self.height):
     56                 self.draw_led(x, y)
     57 
     58     def show(self):
     59         # self.clear()
     60         self.screen.fill((0, 0, 0))
     61         self.draw()
     62         pygame.display.flip()
     63 
     64     def draw_led(self, x, y):
     65         self.draw_gfxcircle(x,y)
     66 
     67     def draw_gfxcircle(self, x, y):
     68         p = self.pixel_size
     69         w_x = int(x * p + self.pixel_size / 2)
     70         w_y = int((self.height - 1 - y) * p + self.pixel_size / 2)
     71         r = int(self.pixel_size / 4)
     72         color = self.pixels[self.index(x, y)]
     73         pygame.gfxdraw.aacircle(self.screen, w_x, w_y, r, color)
     74         pygame.gfxdraw.filled_circle(self.screen, w_x, w_y, r, color)
     75 
     76     def get_shape(self):
     77         return (self.width, self.height)
     78 
     79     def brightness(self, *args):
     80         pass
     81 
     82     def rotation(self, r):
     83         self._rotation = int(round(r/90.0)) % 3
     84 
     85     def clear(self):
     86         # self.screen.fill((0, 0, 0))
     87         self.pixels = [(0, 0, 0)] * self.width * self.height
     88         
     89     def get_rotation(self):
     90         return self._rotation * 90
     91 
     92     def set_layout(self, *args):
     93         pass
     94 
     95     def set_pixel_hsv(self, x, y, h, s=1.0, v=1.0):
     96         r, g, b = [int(n*255) for n in colorsys.hsv_to_rgb(h, s, v)]
     97         self.set_pixel(x, y, r, g, b)
     98 
     99     def off(self):
    100         print("Closing window")
    101         pygame.quit()
    102 
    103     def index(self, x, y):
    104         # Offset to match device rotation
    105         rot = (self.get_rotation() + self.rotation_offset) % 360
    106 
    107         if rot == 0:
    108             xx = x
    109             yy = y
    110         elif rot == 90:
    111             xx = self.height - 1 - y
    112             yy = x
    113         elif rot == 180:
    114             xx = self.width - 1 - x
    115             yy = self.height - 1 - y
    116         elif rot == 270:
    117             xx = y
    118             yy = self.width - 1 - x
    119         return (xx * self.width) + yy
    120 
    121 # SD hats works as expected
    122 unicornhat = UnicornHatSim(8,8)
    123 unicornphat = UnicornHatSim(8, 4)
    124 
    125 # Unicornhat HD seems to be the other way around (not that there's anything wrong with that), so we rotate it 180 deg
    126 unicornhathd = UnicornHatSim(16, 16, 180)