def __init__( self, screen_width, screen_height, window_title, debug=False ): super( PixelEditor, self ).__init__( screen_width, screen_height, debug ) pygame.init() self.color_palette = [ Pixels.red, Pixels.blue, Pixels.green, Pixels.white, Pixels.black ] self.current_color = list( Pixels.blue ) self.clock = pygame.time.Clock() self.screen = pygame.display.set_mode( [screen_width, screen_height], pygame.RESIZABLE ) self.font = pygame.font.SysFont( "monospace", 15 ) self.window_title = window_title pygame.display.set_caption( self.window_title ) # Draw grid overlay self.draw_grid = False # Drawing area and pixels for testing self.scale_multiplier = 32 # How big to draw each pixel on screen self.pan_amount = [0,0] self.drawing_area = DrawingArea( 110, 47, screen_width, screen_height, resize_mode='DYNAMIC', margin=(17, 15), color=Pixels.black, spritesize=16 , pixel_scaling=self.scale_multiplier, pan_amount=self.pan_amount ) self.drawing_area.connect( "click", self.drawing_area.useCurrentTool, data={'position':True} ) self.drawing_area.connect( "drag", self.drawing_area.useCurrentTool, data={'position':True} ) self.append( self.drawing_area ) # Hbox buttons self.save_button = Button( w=50, h=30, text="Save" ) self.save_button.connect( "click", self.drawing_area.saveImage ) self.open_button = Button( w=50, h=30, text="Open" ) self.open_button.connect( "click", self.open ) self.new_column_button = Button( w=100, h=30, text="New Column") self.new_column_button.connect( "click", self.drawing_area.newSheetColumn ) self.new_row_button = Button( w=100, h=30, text="New Row") self.new_row_button.connect( "click", self.drawing_area.newSheetRow ) # Hbox self.hbox = Container( 0, 0, screen_width, 30, 'WIDTH', axis="H" ) self.hbox.append( self.save_button ) self.hbox.append( self.open_button ) self.hbox.append( self.new_column_button ) self.hbox.append( self.new_row_button ) self.append( self.hbox ) # Vbox self.vbox = Container( 0, 31, 93, screen_height, 'HEIGHT', axis="V", multi_obj=True ) # Vbox buttons. One for each color in the palette for value in self.color_palette: self.color_button = Button( w=30, h=30, color=value ) self.color_button.connect( "mouse_down", self.drawing_area.setCurrentColor, data={'color':self.color_button.color}) self.vbox.append( self.color_button ) self.paint_tool_button = Button( w=92, h=30, text="Paint" ) self.paint_tool_button.connect( "click", self.drawing_area.setCurrentTool, data={'tool':self.drawing_area.changePixel}) self.vbox.append( self.paint_tool_button ) self.append( self.vbox ) self.run()
class PixelEditor( Wrapper ): def __init__( self, screen_width, screen_height, window_title, debug=False ): super( PixelEditor, self ).__init__( screen_width, screen_height, debug ) pygame.init() self.color_palette = [ Pixels.red, Pixels.blue, Pixels.green, Pixels.white, Pixels.black ] self.current_color = list( Pixels.blue ) self.clock = pygame.time.Clock() self.screen = pygame.display.set_mode( [screen_width, screen_height], pygame.RESIZABLE ) self.font = pygame.font.SysFont( "monospace", 15 ) self.window_title = window_title pygame.display.set_caption( self.window_title ) # Draw grid overlay self.draw_grid = False # Drawing area and pixels for testing self.scale_multiplier = 32 # How big to draw each pixel on screen self.pan_amount = [0,0] self.drawing_area = DrawingArea( 110, 47, screen_width, screen_height, resize_mode='DYNAMIC', margin=(17, 15), color=Pixels.black, spritesize=16 , pixel_scaling=self.scale_multiplier, pan_amount=self.pan_amount ) self.drawing_area.connect( "click", self.drawing_area.useCurrentTool, data={'position':True} ) self.drawing_area.connect( "drag", self.drawing_area.useCurrentTool, data={'position':True} ) self.append( self.drawing_area ) # Hbox buttons self.save_button = Button( w=50, h=30, text="Save" ) self.save_button.connect( "click", self.drawing_area.saveImage ) self.open_button = Button( w=50, h=30, text="Open" ) self.open_button.connect( "click", self.open ) self.new_column_button = Button( w=100, h=30, text="New Column") self.new_column_button.connect( "click", self.drawing_area.newSheetColumn ) self.new_row_button = Button( w=100, h=30, text="New Row") self.new_row_button.connect( "click", self.drawing_area.newSheetRow ) # Hbox self.hbox = Container( 0, 0, screen_width, 30, 'WIDTH', axis="H" ) self.hbox.append( self.save_button ) self.hbox.append( self.open_button ) self.hbox.append( self.new_column_button ) self.hbox.append( self.new_row_button ) self.append( self.hbox ) # Vbox self.vbox = Container( 0, 31, 93, screen_height, 'HEIGHT', axis="V", multi_obj=True ) # Vbox buttons. One for each color in the palette for value in self.color_palette: self.color_button = Button( w=30, h=30, color=value ) self.color_button.connect( "mouse_down", self.drawing_area.setCurrentColor, data={'color':self.color_button.color}) self.vbox.append( self.color_button ) self.paint_tool_button = Button( w=92, h=30, text="Paint" ) self.paint_tool_button.connect( "click", self.drawing_area.setCurrentTool, data={'tool':self.drawing_area.changePixel}) self.vbox.append( self.paint_tool_button ) self.append( self.vbox ) self.run() def run( self ): self.middle_down = False self.running = True self.fps = 60 while self.running: self.keys_down = pygame.key.get_pressed() self.clock.tick( self.fps ) for pyevent in pygame.event.get(): if pyevent.type == pygame.QUIT: self.running = False if pyevent.type == pygame.KEYDOWN: # Toggle grid if pyevent.key == pygame.K_g: self.draw_grid = not self.draw_grid if pyevent.key == pygame.K_RIGHT: self.pan_amount[0] -= 10 if pyevent.key == pygame.K_LEFT: self.pan_amount[0] += 10 if pyevent.key == pygame.K_DOWN: self.pan_amount[1] -= 10 if pyevent.key == pygame.K_UP: self.pan_amount[1] += 10 elif pyevent.type == pygame.MOUSEBUTTONDOWN: if pyevent.button == 1: self.mouseDown( pygame.mouse.get_pos() ) elif pyevent.button == 2: self.middle_down = True elif pyevent.button == 4: if self.keys_down[pygame.K_LCTRL]: self.scale_multiplier += 4 if self.scale_multiplier > 64: self.scale_multiplier = 64 self.drawing_area.pixel_scaling = self.scale_multiplier elif pyevent.button == 5: if self.keys_down[pygame.K_LCTRL]: self.scale_multiplier -= 4 if self.scale_multiplier < 1: self.scale_multiplier = 1 self.drawing_area.pixel_scaling = self.scale_multiplier elif pyevent.type == pygame.MOUSEBUTTONUP: if pyevent.button == 1: self.mouseUp( pygame.mouse.get_pos() ) if pyevent.button == 2: self.middle_down = False elif pyevent.type == pygame.MOUSEMOTION: self.mouseMove( pygame.mouse.get_pos() ) elif pyevent.type == pygame.VIDEORESIZE: self.screen = pygame.display.set_mode( (pyevent.w, pyevent.h), pygame.RESIZABLE) self.resizeArea( (pyevent.w, pyevent.h) ) # Move the spritsheet by using panning if self.middle_down: self.move_amount = pygame.mouse.get_rel() self.pan_amount[0] -= self.move_amount[0] self.pan_amount[1] -= self.move_amount[1] else: #Effectively pops the last mouse position pygame.mouse.get_rel() # Display the FPS of the window in the title if self.debug == True: pygame.display.set_caption( self.window_title + "\t\t - FPS: " + str(int(self.clock.get_fps())) ) self.render() pygame.quit() def render( self ): self.screen.fill( Pixels.white ) if len( self ) > 0: for item in self: if item.getType() == 'Button': pygame.draw.rect( self.screen, Pixels.silver, item.getRect() ) elif item.getType() == 'DrawingArea': # Background of the drawing area pygame.draw.rect( self.screen, item.color, item.getRect() ) # ------------------------------------------------------------------- # TODO Precalculate what part of the surface will be displayed on screen, # then scale that. Max will be around item.w, item.h and never much more # Raw surface of pixels self.surface = pygame.surfarray.make_surface( self.drawing_area.getPixels() ).convert() # Surface is scaled/zoomed in by the scale_multiplier # if self.scale_multiplier > 64: self.scale_multiplier = 64 self.surface = pygame.transform.scale( self.surface, (self.surface.get_width() * self.scale_multiplier, self.surface.get_height() * self.scale_multiplier)) if self.debug==True: print self.surface.get_rect(), "scaletexture" self.rect_drawarea = self.surface.get_rect() self.rect_drawarea.x = self.pan_amount[0] - self.drawing_area.x_offset self.rect_drawarea.y = self.pan_amount[1] - self.drawing_area.y_offset self.rect_drawarea.w = item.w self.rect_drawarea.h = item.h if self.debug==True: print self.rect_drawarea # Draw grid if it is enabled if self.draw_grid == True: s = self.drawing_area.spritesize w = self.drawing_area.sheetsize[0] * s h = self.drawing_area.sheetsize[1] * s p = self.scale_multiplier xo = self.drawing_area.x_offset yo = self.drawing_area.y_offset j = s * p lines = [] lines.append([0,0]) lines.append([w*p, 0]) for y in range(0, h*p, j): for x in range(0, w*p, j): lines.append([x - xo, y - yo]) lines.append([x - xo, y - yo +j]) lines.append([x - xo +j, y - yo +j]) lines.append([w*p, 0]) try: pygame.draw.lines(self.surface, Pixels.darksilver, False, lines, 3 ) except Exception as e: "Error drawing lines, e: ", e self.draw_position = (item.x, item.y) self.screen.blit( self.surface, self.draw_position, area=self.rect_drawarea ) elif item.getType() == 'Container': pygame.draw.rect( self.screen, Pixels.darksilver, item.getRect() ) for i in item.items: if i.color is not None: pygame.draw.rect( self.screen, i.color, i.getRect() ) else: pygame.draw.rect( self.screen, Pixels.silver, i.getRect() ) if i.text is not None: self.label_font = self.font.render(i.text, 1, Pixels.black) self.screen.blit( self.label_font, ( i.getCenterPoint()[0] - self.label_font.get_width()/2, i.getCenterPoint()[1] - self.label_font.get_height()/2 ) ) pygame.display.flip() def save( self ): print "file is being saved" def open( self ): print "file is being opened"