def __init__(self, config): super(DanceSurface, self).__init__() # Create the floor communication object self._init_comms(config) # Create the layout object and calculate floor size self.layout = DisplayLayout(config["modules"]) (self.width, self.height) = self.layout.calculate_floor_size() self.total_pixels = self.width * self.height # Initialise all the pixels to black self.pixels = [ 0 for n in range(0, 3*self.total_pixels) ] self.text_writer = TextWriter()
def get_text_size(self, text): # Returns the text size as a (width, height) tuple for reference, # but doesn't actually draw anything because it doesn't pass a surface through return TextWriter.draw_text(None, text, (0, 0, 0), 0, 0)
def draw_text(self, text, colour, x_pos, y_pos, custom_text=None): # Returns the text size as a (width, height) tuple for reference text_size = TextWriter.draw_text(self, text, colour, x_pos, y_pos, custom_text) return text_size
class DanceSurface(object): """ The class representing the drawable dance floor. This is a wrapper around an internal representation of the dance floor, so that plugins need only write images using (x,y) coordinates and don't have to worry about the configuration of dance floor tiles. The dance surface is passed to the display plugins, and reacts to any changes made by sending the the appropriate updates to the dance floor through the serial port. """ def __init__(self, config): super(DanceSurface, self).__init__() # Create the floor communication object self._init_comms(config) # Create the layout object and calculate floor size self.layout = DisplayLayout(config["modules"]) (self.width, self.height) = self.layout.calculate_floor_size() self.total_pixels = self.width * self.height # Initialise all the pixels to black self.pixels = [ 0 for n in range(0, 3*self.total_pixels) ] self.text_writer = TextWriter() def _init_comms(self, config): """ Initialise the comms to the floor or simulator """ self.comms = ComboComms(config) def blit(self): """ Draw the updated floor to the serial port """ i = 0 sanitised_pixels = [] while i < len(self.pixels): p = self.pixels[i] if p < 0: logging.error("DanceSurface: Tried to send a pixel component with a negative value") sanitised_pixels.append(0) elif p > 255: logging.error("DanceSurface: Tried to send a pixel component with a value > 255") sanitised_pixels.append(255) else: sanitised_pixels.append(p) i += 1 self.pixels = sanitised_pixels self.comms.send_data(self.pixels) def clear_hex(self, colour): """ Clear the surface to a single colour """ # Make sure we never send a 1 by mistake and screw up the frames (r,g,b) = [ v if not v == 1 else 0 for v in ColourUtils.hexToTuple(colour) ] for x in range(0,self.total_pixels): self.pixels[x*3:(x+1)*3] = [r,g,b] def clear_tuple(self, colour): """ Clear the surface to a single colour """ # Make sure we never send a 1 by mistake and screw up the frames (r,g,b) = [ v if not v == 1 else 0 for v in colour ] for x in range(0,self.total_pixels): self.pixels[x*3:(x+1)*3] = [r,g,b] def draw_hex_pixel(self, x, y, colour): """ Set the value of the pixel at (x,y) to colour(#RRGGBB") """ # Make sure we never send a 1 by mistake and screw up the frames (r,g,b) = [ v if not v == 1 else 0 for v in ColourUtils.hexToTuple(colour) ] pos = self.layout.get_position(x,y) if pos is not None: mapped_pixel = 3 * pos self.pixels[mapped_pixel:mapped_pixel+3] = [r,g,b] def draw_tuple_pixel(self, x, y, colour): """ Set the value of the pixel at (x,y) to colour((r,g,b)) """ # Make sure we never send a 1 by mistake and screw up the frames (r,g,b) = [ v if not v == 1 else 0 for v in colour ] pos = self.layout.get_position(x,y) if pos is not None: mapped_pixel = 3 * pos self.pixels[mapped_pixel:mapped_pixel+3] = [r,g,b] def draw_float_tuple_pixel(self, x, y, colour): """ Set the value of the pixel at (x,y) to colour((r,g,b)) where r g and b are floats """ (floatR, floatG, floatB) = colour intR = int(floatR*255) intG = int(floatG*255) intB = int(floatB*255) self.draw_tuple_pixel(x, y, (intR, intG, intB)) def draw_tuple_box(self, top_left, bottom_right, colour): """ Fill the box from top left to bottom right with the given colour """ (tlx,tly) = top_left (brx,bry) = bottom_right if tlx <= brx and tly <= bry: y = tly while y <= bry: x = tlx while x <= brx: self.draw_tuple_pixel(x, y, colour) x += 1 y += 1 def draw_text(self, text, colour, x_pos, y_pos): if (self.text_writer == None): return (0,0) # Returns the text size as a (width, height) tuple for reference text_size = self.text_writer.draw_text(self, text, colour, x_pos, y_pos) return text_size def get_text_size(self, text): if (self.text_writer == None): return (0,0) # Returns the text size as a (width, height) tuple for reference, # but doesn't actually draw anything because it doesn't pass a surface through return self.text_writer.draw_text(None, text, (0,0,0), 0, 0)