From 6ab73a35e3a1873f0c64f66ea236c572faaf9666 Mon Sep 17 00:00:00 2001 From: Alexandre Antonino Gonçalves Martinazzo Date: Mon, 20 Aug 2007 20:13:52 +0000 Subject: New Paint (oficina) version: 5 User can choose side number for regular polygons Fixed bug that denied user to choose shapes for brush and eraser Added rainbow effect (by andremossinato) --- diff --git a/Area.py b/Area.py index d78eabb..b14ab76 100644 --- a/Area.py +++ b/Area.py @@ -61,8 +61,8 @@ import gtk, gobject, logging, os import math import pango from fill import * -import Image -import StringIO +# import Image +# import StringIO from Desenho import Desenho WIDTH = 800 @@ -74,7 +74,7 @@ class Area(gtk.DrawingArea): 'undo' : (gobject.SIGNAL_ACTION, gobject.TYPE_NONE, ([])), 'redo' : (gobject.SIGNAL_ACTION, gobject.TYPE_NONE, ([])), 'action-saved' : (gobject.SIGNAL_ACTION, gobject.TYPE_NONE, ([])), - #TODO: these signals still not used. + #TODO: this signal still not used. # 'copy' : (gobject.SIGNAL_ACTION, gobject.TYPE_NONE, ([])), 'selected' : (gobject.SIGNAL_ACTION, gobject.TYPE_NONE, ([])), } @@ -111,14 +111,10 @@ class Area(gtk.DrawingArea): self.connect("configure_event", self.configure_event) self.oldx = 0 self.oldy = 0 - self.newx = 0 - self.newy = 0 - self.newx_ = 0 - self.newy_ = 0 - self.color_dec = 0 self.polygon_start = True self.points = [] self.gc = None + self.gc_rainbow = None self.gc_line = None self.gc_eraser = None self.gc_brush = None @@ -135,6 +131,8 @@ class Area(gtk.DrawingArea): self.line_size = 2 self.brush_shape = 'circle' self.eraser_shape = 'circle' + self.last = -1, -1 + self.rainbow_counter = 0 self.font = pango.FontDescription('Sans 9') @@ -145,6 +143,8 @@ class Area(gtk.DrawingArea): self.redo_times = 0 self.undo_list=[]#pixmaps list to Undo func + # Number of sides for regular polygon + self.polygon_sides = 5 # Create a new backing pixmap of the appropriate size def configure_event(self, widget, event): @@ -176,6 +176,7 @@ class Area(gtk.DrawingArea): colormap = self.get_colormap() white = colormap.alloc_color('#ffffff', True, True) # white self.gc_eraser.set_foreground(white) + self.gc_rainbow = widget.window.new_gc() self.gc_brush = widget.window.new_gc() self.gc_brush.set_foreground(white) @@ -244,22 +245,36 @@ class Area(gtk.DrawingArea): event -- GdkEvent """ + width, height = self.window.get_size() # text + coords = int(event.x), int(event.y) if self.tool == 'text': self.d.text(widget,event) if not self.selmove or self.tool != 'marquee-rectangular': self.oldx = int(event.x) self.oldy = int(event.y) if self.selmove and self.tool != 'marquee-rectangular': #get out of the func selection - self.pixmap.draw_drawable(self.gc, self.pixmap_temp, 0,0,0,0, WIDTH, HEIGHT) + self.pixmap.draw_drawable(self.gc, self.pixmap_temp, 0,0,0,0, width, height) self.selmove = False self.enableUndo(widget) + if self.tool == 'eraser': + self.last = -1, -1 + self.d.eraser(widget, coords, self.last, self.line_size, self.eraser_shape) + self.last = coords + if self.tool == 'brush': + self.last = -1, -1 + self.d.brush(widget, coords, self.last, self.line_size, self.brush_shape) + self.last = coords + if self.tool == 'rainbow': + self.last = -1, -1 + self.d.rainbow(widget, coords, self.last, self.rainbow_counter,self.line_size, self.brush_shape) + self.last = coords x , y, state = event.window.get_pointer() if state & gtk.gdk.BUTTON3_MASK: self.sel_get_out = True - self.pixmap_sel.draw_drawable(self.gc, self.pixmap_temp, 0,0,0,0, WIDTH, HEIGHT) + self.pixmap_sel.draw_drawable(self.gc, self.pixmap_temp, 0,0,0,0, width, height) if state & gtk.gdk.BUTTON1_MASK: - self.pixmap_temp.draw_drawable(self.gc, self.pixmap, 0,0,0,0, WIDTH, HEIGHT) + self.pixmap_temp.draw_drawable(self.gc, self.pixmap, 0,0,0,0, width, height) widget.queue_draw() self.desenha = True @@ -279,10 +294,18 @@ class Area(gtk.DrawingArea): if state & gtk.gdk.BUTTON1_MASK and self.pixmap != None: #eraser if self.tool == 'eraser': - self.d.eraser(widget, coords, self.line_size, self.eraser_shape) + self.d.eraser(widget, coords, self.last, self.line_size, self.eraser_shape) + self.last = coords #brush elif self.tool == 'brush': - self.d.brush(widget, coords, self.line_size, self.brush_shape) + self.d.brush(widget, coords, self.last, self.line_size, self.brush_shape) + self.last = coords + elif self.tool == 'rainbow': + self.d.rainbow(widget, coords, self.last, self.rainbow_counter,self.line_size, self.brush_shape) + self.rainbow_counter += 1 + if self.rainbow_counter > 11: + self.rainbow_counter = 0 + self.last = coords if self.desenha: # line if self.tool == 'line': @@ -334,8 +357,8 @@ class Area(gtk.DrawingArea): #polygon regular elif self.tool == 'polygon_regular': self.configure_line(self.line_size) - n = 7 - self.d.polygon_regular(widget,coords,n,True,True) + #n = 7 + self.d.polygon_regular(widget,coords,self.polygon_sides,True,True) #Heart elif self.tool == 'heart': self.configure_line(self.line_size) @@ -362,16 +385,10 @@ class Area(gtk.DrawingArea): # ellipse elif self.tool == 'ellipse': self.d.circle(widget,coords,False,True) - #self.pixmap.draw_arc(self.gc, True, self.newx, self.newy, self.newx_, self.newy_, 0, 360*64) - #self.pixmap.draw_arc(self.gc_line, False, self.newx, self.newy, self.newx_, self.newy_, 0, 360*64) - #widget.queue_draw() self.enableUndo(widget) # rectangle elif self.tool == 'rectangle': self.d.square(widget,coords,False,True) - #self.pixmap.draw_rectangle(self.gc, True, self.newx,self.newy, self.newx_,self.newy_) - #self.pixmap.draw_rectangle(self.gc_line, False, self.newx,self.newy, self.newx_,self.newy_) - #widget.queue_draw() self.enableUndo(widget) # selection elif self.tool == 'marquee-rectangular': @@ -402,7 +419,7 @@ class Area(gtk.DrawingArea): #bucket elif self.tool == 'bucket': width, height = self.window.get_size() - fill(self.pixmap, self.gc, int(event.x), int(event.y), width, height, self.color_dec) + fill(self.pixmap, self.gc, coords[0], coords[1], width, height, self.gc_line.foreground.pixel) widget.queue_draw() self.enableUndo(widget) #triangle @@ -427,15 +444,16 @@ class Area(gtk.DrawingArea): self.enableUndo(widget) #polygon regular elif self.tool == 'polygon_regular': - n = 7 - self.d.polygon_regular(widget,coords,n,False,True) + #n = 7 + self.d.polygon_regular(widget,coords,self.polygon_sides,False,True) self.enableUndo(widget) - #Heart + #heart elif self.tool == 'heart': self.d.heart(widget,coords,False,True) self.enableUndo(widget) - if self.tool == 'brush' or self.tool == 'eraser': + if self.tool == 'brush' or self.tool == 'eraser' or self.tool == 'rainbow': + self.last = -1, -1 widget.queue_draw() self.enableUndo(widget) self.desenha = False @@ -664,7 +682,6 @@ class Area(gtk.DrawingArea): self.gc_line.set_foreground(color) self.gc_line.set_line_attributes(1, gtk.gdk.LINE_ON_OFF_DASH, gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND) self.gc_brush.set_foreground(color) - self.color_dec = color.pixel def _set_grayscale(self,widget): """Apply grayscale effect. @@ -674,15 +691,16 @@ class Area(gtk.DrawingArea): """ logging.debug('Area._set_grayscale(self,widget)') + width, height = self.window.get_size() - pix = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, WIDTH, HEIGHT) - pix_ = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, WIDTH, HEIGHT) - pix.get_from_drawable(self.pixmap, gtk.gdk.colormap_get_system(), 0, 0, 0, 0, WIDTH, HEIGHT) + pix = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, width, height) + pix_ = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, width, height) + pix.get_from_drawable(self.pixmap, gtk.gdk.colormap_get_system(), 0, 0, 0, 0, width, height) pix.saturate_and_pixelate(pix_, 0 ,0) - self.pixmap.draw_pixbuf(self.gc, pix_, 0, 0, 0, 0, WIDTH, HEIGHT, dither=gtk.gdk.RGB_DITHER_NORMAL, x_dither=0, y_dither=0) + self.pixmap.draw_pixbuf(self.gc, pix_, 0, 0, 0, 0, width, height, dither=gtk.gdk.RGB_DITHER_NORMAL, x_dither=0, y_dither=0) - self.pixmap_temp.draw_pixbuf(self.gc, pix_, 0, 0, 0, 0, WIDTH, HEIGHT, dither=gtk.gdk.RGB_DITHER_NORMAL, x_dither=0, y_dither=0) + self.pixmap_temp.draw_pixbuf(self.gc, pix_, 0, 0, 0, 0, width, height, dither=gtk.gdk.RGB_DITHER_NORMAL, x_dither=0, y_dither=0) self.queue_draw() self.enableUndo(widget) @@ -758,4 +776,35 @@ class Area(gtk.DrawingArea): def get_selection_bounds(self): return self._selection_corners[0], self._selection_corners[1], self._selection_corners[2], self._selection_corners[3] + + def loadImage(self, name, widget, load_selected): + """Load an image. + + Keyword arguments: + self -- Area.area instance + name -- string (image file path) + + """ + pixbuf = gtk.gdk.pixbuf_new_from_file(name) + size = (int)(pixbuf.get_width()), (int)(pixbuf.get_height()) + + self.pixmap.draw_pixbuf(self.gc, pixbuf, 0, 0, 0, 0, size[0], size[1], dither=gtk.gdk.RGB_DITHER_NORMAL, x_dither=0, y_dither=0) + self.pixmap_temp.draw_pixbuf(self.gc, pixbuf, 0, 0, 0, 0, size[0], size[1], dither=gtk.gdk.RGB_DITHER_NORMAL, x_dither=0, y_dither=0) + self.pixmap_sel.draw_pixbuf(self.gc, pixbuf, 0, 0, 0, 0, size[0], size[1], dither=gtk.gdk.RGB_DITHER_NORMAL, x_dither=0, y_dither=0) + + + + if not load_selected : + self.enableUndo(widget) + else : + self.oldx, self.oldy = 0,0 + self.d.selection(self, size, True, False) + #self.pixmap_temp.draw_rectangle(self.gc_selection, True ,0,0,size[0],size[1]) + self.sx, self.sy = size + self.tool = 'marquee-rectangular' + self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.FLEUR)) + self.selmove = True + self.desenha = True + + self.queue_draw() diff --git a/Desenho.py b/Desenho.py index e8691d2..413b016 100644 --- a/Desenho.py +++ b/Desenho.py @@ -85,13 +85,14 @@ class Desenho: coords -- Two value tuple """ - self.d.pixmap_temp.draw_drawable(self.d.gc,self.d.pixmap, 0 , 0 ,0,0, WIDTH, HEIGHT) + width, height = self.window.get_size() + self.d.pixmap_temp.draw_drawable(self.d.gc,self.d.pixmap, 0 , 0 ,0,0, width, height) self.d.pixmap_temp.draw_line(self.d.gc_line,self.d.oldx,self.d.oldy,coords[0],coords[1]) #self.d.newx = coords[0] #self.d.newy = coords[1] widget.queue_draw() - def eraser(self, widget, coords, size = 30, shape = 'circle'): + def eraser(self, widget, coords, last, size = 30, shape = 'circle'): """Erase part of the drawing. Keyword arguments: @@ -105,15 +106,20 @@ class Desenho: self.d.desenha = False if(shape == 'circle'): self.d.pixmap.draw_arc(self.d.gc_eraser, True, coords[0], coords[1], size, size, 0, 360*64) - self.d.pixmap_temp.draw_arc(self.d.gc_eraser, True, coords[0], coords[1], size, size, 0, 360*64) + if last[0] != -1: + self.d.gc_eraser.set_line_attributes(size, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND) + self.d.pixmap.draw_line(self.d.gc_eraser,last[0]+size/2,last[1]+size/2,coords[0]+size/2,coords[1]+size/2) + self.d.gc_eraser.set_line_attributes(0, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND) if(shape == 'square'): self.d.pixmap.draw_rectangle(self.d.gc_eraser, True, coords[0], coords[1], size, size) - self.d.pixmap_temp.draw_rectangle(self.d.gc_eraser, True, coords[0], coords[1], size, size) - self.d.oldx = coords[0] - self.d.oldy = coords[1] + if last[0] != -1: + points = [coords, last, (last[0]+size,last[1]+size), (coords[0]+size,coords[1]+size)] + self.d.pixmap.draw_polygon(self.d.gc_eraser,True,points) + points = [(last[0]+size,last[1]), (coords[0]+size,coords[1]), (coords[0],coords[1]+size), (last[0],last[1]+size)] + self.d.pixmap.draw_polygon(self.d.gc_eraser,True,points) widget.queue_draw() - def brush(self, widget, coords, size = 5, shape = 'circle'): + def brush(self, widget, coords, last, size = 5, shape = 'circle'): """Paint with brush. Keyword arguments: @@ -127,56 +133,72 @@ class Desenho: self.d.desenha = False if(shape == 'circle'): self.d.pixmap.draw_arc(self.d.gc_brush, True, coords[0], coords[1], size, size, 0, 360*64) - self.d.pixmap_temp.draw_arc(self.d.gc_brush, True, coords[0], coords[1], size, size, 0, 360*64) + if last[0] != -1: + self.d.gc_brush.set_line_attributes(size, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND) + self.d.pixmap.draw_line(self.d.gc_brush,last[0]+size/2,last[1]+size/2,coords[0]+size/2,coords[1]+size/2) + self.d.gc_brush.set_line_attributes(0, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND) if(shape == 'square'): self.d.pixmap.draw_rectangle(self.d.gc_brush, True, coords[0], coords[1], size, size) - self.d.pixmap_temp.draw_rectangle(self.d.gc_brush, True, coords[0], coords[1], size, size) - self.d.oldx = coords[0] - self.d.oldy = coords[1] + if last[0] != -1: + points = [coords, last, (last[0]+size,last[1]+size), (coords[0]+size,coords[1]+size)] + self.d.pixmap.draw_polygon(self.d.gc_brush,True,points) + points = [(last[0]+size,last[1]), (coords[0]+size,coords[1]), (coords[0],coords[1]+size), (last[0],last[1]+size)] + self.d.pixmap.draw_polygon(self.d.gc_brush,True,points) widget.queue_draw() - - def square(self, widget, coords, temp, fill): - """Draw a square. + + def rainbow(self, widget, coords, last, color, size = 5, shape = 'circle'): + """Paint with rainbow. Keyword arguments: self -- Desenho.Desenho instance widget -- Area object (GtkDrawingArea) coords -- Two value tuple + size -- integer (default 30) + shape -- string (default 'circle') - - if coords[0] > WIDTH: - coords0 = WIDTH - else: - coords0 = coords[0] - - if coords [1] > HEIGHT: - coords1 = HEIGHT - else: - coords1 = coords[1] - - self.d.newx_ = coords0 - self.d.oldx - self.d.newy_ = coords1 - self.d.oldy + """ + colormap = self.d.get_colormap() + rainbow_colors = [ + colormap.alloc_color('#ff0000', True, True), # vermelho + colormap.alloc_color('#ff8000', True, True), # laranja + colormap.alloc_color('#ffff00', True, True), # amarelo + colormap.alloc_color('#80ff00', True, True), # verde lima + colormap.alloc_color('#00ff00', True, True), # verde + colormap.alloc_color('#00ff80', True, True), # verde agua + colormap.alloc_color('#00ffff', True, True), # azul claro + colormap.alloc_color('#007fff', True, True), # quase azul + colormap.alloc_color('#0000ff', True, True), # azul + colormap.alloc_color('#8000ff', True, True), # anil + colormap.alloc_color('#ff00ff', True, True), # rosa violeta + colormap.alloc_color('#ff0080', True, True), # violeta + ] + + self.d.gc_rainbow.set_foreground(rainbow_colors[color]) + self.d.desenha = False + if(shape == 'circle'): + self.d.pixmap.draw_arc(self.d.gc_rainbow, True, coords[0], coords[1], size, size, 0, 360*64) + if last[0] != -1: + self.d.gc_rainbow.set_line_attributes(size, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND) + self.d.pixmap.draw_line(self.d.gc_rainbow,last[0]+size/2,last[1]+size/2,coords[0]+size/2,coords[1]+size/2) + self.d.gc_rainbow.set_line_attributes(0, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND) + if(shape == 'square'): + if last[0] != -1: + self.d.pixmap.draw_rectangle(self.d.gc_rainbow, True, last[0], last[1], size, size) + points = [coords, last, (last[0]+size,last[1]+size), (coords[0]+size,coords[1]+size)] + self.d.pixmap.draw_polygon(self.d.gc_rainbow,True,points) + points = [(last[0]+size,last[1]), (coords[0]+size,coords[1]), (coords[0],coords[1]+size), (last[0],last[1]+size)] + self.d.pixmap.draw_polygon(self.d.gc_rainbow,True,points) + self.d.pixmap.draw_rectangle(self.d.gc_rainbow, True, coords[0], coords[1], size, size) + widget.queue_draw() - if self.d.newx_ >= 0: - self.d.newx = self.d.oldx - else: - if coords0 > 0: - self.d.newx = coords0 - self.d.newx_ = - self.d.newx_ - else: - self.d.newx = 0 - self.d.newx_ = self.d.oldx - - if self.d.newy_ >= 0: - self.d.newy = self.d.oldy - else: - if coords1 > 0: - self.d.newy_ = - self.d.newy_ - self.d.newy = coords1 - else: - self.d.newy = 0 - self.d.newy_ = self.d.oldy + + def square(self, widget, coords, temp, fill): + """Draw a square. + Keyword arguments: + self -- Desenho.Desenho instance + widget -- Area object (GtkDrawingArea) + coords -- Two value tuple """ if temp == True: pixmap = self.d.pixmap_temp @@ -430,39 +452,6 @@ class Desenho: widget -- Area object (GtkDrawingArea) coords -- Two value tuple - if coords[0] > WIDTH: - coords0 = WIDTH - else: - coords0 = coords[0] - - if coords [1] > HEIGHT: - coords1 = HEIGHT - else: - coords1 = coords[1] - - self.d.newx_ = coords0 - self.d.oldx - self.d.newy_ = coords1 - self.d.oldy - - if self.d.newx_ >= 0: - self.d.newx = self.d.oldx - else: - if coords0 > 0: - self.d.newx = coords0 - self.d.newx_ = - self.d.newx_ - else: - self.d.newx = 0 - self.d.newx_ = self.d.oldx - - if self.d.newy_ >= 0: - self.d.newy = self.d.oldy - else: - if coords1 > 0: - self.d.newy_ = - self.d.newy_ - self.d.newy = coords1 - else: - self.d.newy = 0 - self.d.newy_ = self.d.oldy - """ if temp == True: @@ -499,7 +488,8 @@ class Desenho: coords -- Two value tuple """ - self.d.pixmap_temp.draw_drawable(self.d.gc,self.d.pixmap, 0 , 0 ,0,0, WIDTH, HEIGHT) + width, height = self.d.window.get_size() + self.d.pixmap_temp.draw_drawable(self.d.gc,self.d.pixmap, 0 , 0 ,0,0, width, height) self.d.pixmap.draw_line(self.d.gc_line,self.d.oldx,self.d.oldy,coords[0],coords[1]) self.d.oldx = coords[0] self.d.oldy = coords[1] @@ -512,10 +502,11 @@ class Desenho: self -- Desenho.Desenho instance """ + width, height = self.d.window.get_size() self.d.desenho = [] self.d.textos = [] - self.d.pixmap.draw_rectangle(self.d.get_style().white_gc, True,0, 0, WIDTH, HEIGHT) - self.d.pixmap_temp.draw_rectangle(self.d.get_style().white_gc, True,0, 0, WIDTH, HEIGHT) + self.d.pixmap.draw_rectangle(self.d.get_style().white_gc, True,0, 0, width, height) + self.d.pixmap_temp.draw_rectangle(self.d.get_style().white_gc, True,0, 0, width, height) self.d.queue_draw() def text(self,widget,event): @@ -531,6 +522,8 @@ class Desenho: self.d.estadoTexto = 1 print event.x self.d.janela._fixed.move(self.d.janela._textview, int(event.x)+200, int(event.y)+100) + # Area size has changed... + #self.d.janela._fixed.move(self.d.janela._textview, int(event.x), int(event.y)) self.d.janela._textview.show() else: self.d.estadoTexto = 0 @@ -546,21 +539,6 @@ class Desenho: widget.queue_draw() - def loadImage(self, name, widget): - """Load an image. - - Keyword arguments: - self -- Desenho.Desenho instance - name -- string (image file path) - - """ - pixbuf = gtk.gdk.pixbuf_new_from_file(name) - self.d.pixmap.draw_pixbuf(self.d.gc, pixbuf, 0, 0, 0, 0, width=-1, height=-1, dither=gtk.gdk.RGB_DITHER_NORMAL, x_dither=0, y_dither=0) - self.d.pixmap_temp.draw_pixbuf(self.d.gc, pixbuf, 0, 0, 0, 0, width=-1, height=-1, dither=gtk.gdk.RGB_DITHER_NORMAL, x_dither=0, y_dither=0) - - self.d.enableUndo(widget) - - self.d.queue_draw() def selection(self, widget, coords, temp, fill): """Make a selection. @@ -569,47 +547,6 @@ class Desenho: self -- Desenho.Desenho instance widget -- Area object (GtkDrawingArea) coords -- Two value tuple - - - widget.queue_draw() - - if coords[0] > WIDTH: - coords0 = WIDTH - else: - coords0 = coords[0] - - if coords [1] > HEIGHT: - coords1 = HEIGHT - else: - coords1 = coords[1] - - self.d.newx_ = coords0 - self.d.oldx - self.d.newy_ = coords1 - self.d.oldy - - if self.d.newx_ >= 0: - self.d.newx = self.d.oldx - else: - if coords0 > 0: - self.d.newx = coords0 - self.d.newx_ = - self.d.newx_ - else: - self.d.newx = 0 - self.d.newx_ = self.d.oldx - - if self.d.newy_ >= 0: - self.d.newy = self.d.oldy - else: - if coords1 > 0: - self.d.newy_ = - self.d.newy_ - self.d.newy = coords1 - else: - self.d.newy = 0 - self.d.newy_ = self.d.oldy - - self.d.pixmap_temp.draw_drawable(self.d.gc,self.d.pixmap, 0 , 0 ,0,0, WIDTH, HEIGHT) - self.d.pixmap_temp.draw_rectangle(self.d.gc_selection, False ,self.d.newx,self.d.newy,self.d.newx_,self.d.newy_) - self.d.pixmap_temp.draw_rectangle(self.d.gc_selection1, False, \ - self.d.newx-1,self.d.newy-1,self.d.newx_+2,self.d.newy_+2) """ if temp == True: @@ -633,7 +570,7 @@ class Desenho: pixmap.draw_drawable(self.d.gc,self.d.pixmap,0,0,0,0,width,height) if fill == True: pixmap.draw_rectangle(self.d.gc,True,x,y,dx,dy) - pixmap.draw_rectangle(self.d.gc_line,False,x,y,dx,dy) + pixmap.draw_rectangle(self.d.gc_selection,False,x,y,dx,dy) widget.queue_draw() return self.d.oldx, self.d.oldy, coords[0], coords[1] @@ -646,11 +583,10 @@ class Desenho: coords -- Two value tuple """ - self.d.pixmap_temp.draw_rectangle(self.d.get_style().white_gc, True,0, 0, WIDTH, HEIGHT) - self.d.pixmap_temp.draw_drawable(self.d.gc,self.d.pixmap, 0 , 0 ,0,0, WIDTH, HEIGHT) + width, height = self.d.window.get_size() + self.d.pixmap_temp.draw_drawable(self.d.gc,self.d.pixmap, 0 , 0 ,0,0, width, height) - self.d.pixmap_sel.draw_rectangle(self.d.get_style().white_gc, True,0, 0, WIDTH, HEIGHT) - self.d.pixmap_sel.draw_drawable(self.d.gc,self.d.pixmap, 0 , 0 ,0,0, WIDTH, HEIGHT) + self.d.pixmap_sel.draw_drawable(self.d.gc,self.d.pixmap, 0 , 0 ,0,0, width, height) if self.d.sx > self.d.oldx: x0 = self.d.oldx @@ -706,65 +642,31 @@ class Desenho: else: pixmap.draw_line(self.d.gc_line,self.d.oldx,self.d.oldy, coords[0], coords[1]) self.d.enableUndo(widget) - self.d.lastx = coords[0] - self.d.lasty = coords[1] - self.d.firstx = self.d.oldx - self.d.firsty = self.d.oldy + self.d.last = coords + self.d.first = self.d.oldx, self.d.oldy self.d.polygon_start = False - self.d.points = [(self.d.oldx,self.d.oldy), (coords[0],coords[1])] + self.d.points = [self.d.first, coords] else: if temp == True: - pixmap.draw_line(self.d.gc_line,self.d.lastx,self.d.lasty,coords[0],coords[1]) + pixmap.draw_line(self.d.gc_line,self.d.last[0],self.d.last[1],coords[0],coords[1]) else: - x = coords[0] - self.d.firstx - y = coords[1] - self.d.firsty + x = coords[0] - self.d.first[0] + y = coords[1] - self.d.first[1] d = math.hypot(x,y) if d > 20: # close the polygon ? - pixmap.draw_line(self.d.gc_line,self.d.lastx,self.d.lasty,coords[0],coords[1]) - self.d.lastx = coords[0] - self.d.lasty = coords[1] - self.d.points.append((coords[0],coords[1])) + pixmap.draw_line(self.d.gc_line,self.d.last[0],self.d.last[1],coords[0],coords[1]) + self.d.last = coords + self.d.points.append(coords) else: tp = tuple(self.d.points) if fill == True: pixmap.draw_polygon(self.d.gc, True, tp) pixmap.draw_polygon(self.d.gc_line, False, tp) + self.d.last = -1, -1 self.d.polygon_start = True self.d.undo_times -= 1#destroy the undo screen of polygon start self.d.enableUndo(widget) widget.queue_draw() - def fill(self, image, x, y, color): - '''Fills a region with a given color. - self -- - image -- a gtk.gdk.Image - x,y -- pixel coordinates - color -- a color to fill (decimal) - - ''' - - start_color = image.get_pixel(x,y) - width, height = self.d.window.get_size() - - if x < 0 or x > width or y < 0 or y > height \ - or image.get_pixel(x,y) == color: -# print 'leaving...' - return - - edge = [(x, y)] - image.put_pixel(x, y, color) - while edge: -# print edge - newedge = [] - while gtk.events_pending ():gtk.main_iteration() - for (x, y) in edge: - for (s, t) in ((x+1, y), (x-1, y), (x, y+1), (x, y-1)): - if (s >= 0 and s < width) and (t >= 0 and t < height) \ - and image.get_pixel(s, t) == start_color: - image.put_pixel(s, t, color) - newedge.append((s, t)) - edge = newedge - - return image diff --git a/MANIFEST b/MANIFEST index 3ca6173..5f76976 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1,12 +1,10 @@ Area.py COPYING Desenho.py -MANIFEST NEWS OficinaActivity.py activity/activity-rgbpaint.svg activity/activity.info -fill.so fill_src/Makefile fill_src/eggfill.c fill_src/eggfill.h @@ -75,22 +73,25 @@ images/trapezoid.png images/triangle.png locale/de/LC_MESSAGES/de.mo locale/de/LC_MESSAGES/de.po -locale/de/LC_MESSAGES/drawing.mo -locale/es/LC_MESSAGES/drawing.mo +locale/de/activity.linfo locale/es/LC_MESSAGES/es.mo locale/es/LC_MESSAGES/es.po +locale/es/activity.linfo locale/fr/LC_MESSAGES/fr.mo locale/fr/LC_MESSAGES/fr.po -locale/ko_KO/LC_MESSAGES/drawing.mo +locale/fr/activity.linfo locale/ko_KO/LC_MESSAGES/ko_KO.mo locale/ko_KO/LC_MESSAGES/ko_KO.po +locale/ko_KO/activity.linfo locale/paint.pot -locale/pt_BR/LC_MESSAGES/drawing.mo locale/pt_BR/LC_MESSAGES/pt_BR.mo locale/pt_BR/LC_MESSAGES/pt_BR.po +locale/pt_BR/activity.linfo locale/zh_CN/LC_MESSAGES/zh_CN.mo locale/zh_CN/LC_MESSAGES/zh_CN.po +locale/zh_CN/activity.linfo locale/zh_TW/LC_MESSAGES/zh_TW.mo locale/zh_TW/LC_MESSAGES/zh_TW.po +locale/zh_TW/activity.linfo setup.py toolbox.py diff --git a/NEWS b/NEWS index 33bba72..7569ef7 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,9 @@ +5 +=== +Added rainbow effect (andremossinato) +Side number for regular polygon can be choosen (alexandre) +New shape available: Heart (andremossinato) + 4 === Now paste and copy are integrated to Sugar (pekayatt) diff --git a/OficinaActivity.py b/OficinaActivity.py index cf8b56e..fdc62d7 100644 --- a/OficinaActivity.py +++ b/OficinaActivity.py @@ -105,7 +105,9 @@ class OficinaActivity(activity.Activity): self._textview = gtk.Entry() self._area.tool = 2 self._fixed.put(self._area, 200 , 100) - + # Area size increased + #self._fixed.put(self._area, 0 , 0) + sw.add_with_viewport(self._fixed) self._area.show() self._fixed.show() @@ -129,7 +131,7 @@ class OficinaActivity(activity.Activity): logging.debug('reading file %s', file_path) # logging.debug(file_path) - self._area.d.loadImage(file_path, self._area) + self._area.loadImage(file_path, self._area, False) # Does this work? # self._area.undo_times = 1 diff --git a/activity/activity.info b/activity/activity.info index 98824fc..0d73cf1 100644 --- a/activity/activity.info +++ b/activity/activity.info @@ -1,6 +1,6 @@ [Activity] name = Paint -activity_version = 4 +activity_version = 5 service_name = org.laptop.Oficina icon = activity-rgbpaint class = OficinaActivity.OficinaActivity diff --git a/setup.py b/setup.py index 876cd3f..c273089 100755 --- a/setup.py +++ b/setup.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/env python # Copyright (C) 2006, Red Hat, Inc. # @@ -18,5 +18,5 @@ from sugar.activity import bundlebuilder -bundlebuilder.start() +bundlebuilder.start('oficina') diff --git a/toolbox.py b/toolbox.py index 2b7bef3..7b8f901 100644 --- a/toolbox.py +++ b/toolbox.py @@ -207,7 +207,7 @@ class ToolsToolbar(gtk.Toolbar): self._tool_brush.show() self._tool_brush.set_tooltip(_('Brush')) try: - self.set_palette(self._tool_brush, self._TOOL_BRUSH) + self._configure_palette(self._tool_brush, self._TOOL_BRUSH) except: logging.debug('Could not create palette for tool Brush') @@ -216,7 +216,7 @@ class ToolsToolbar(gtk.Toolbar): self._tool_eraser.show() self._tool_eraser.set_tooltip(_('Eraser')) try: - self.set_palette(self._tool_eraser, self._TOOL_ERASER) + self._configure_palette(self._tool_eraser, self._TOOL_ERASER) except: logging.debug('Could not create palette for tool Eraser') @@ -267,45 +267,27 @@ class ToolsToolbar(gtk.Toolbar): self._tool_marquee_rectangular.connect('clicked', self.set_tool, self._TOOL_MARQUEE_RECTANGULAR) #self._tool_marquee_smart.connect('clicked', self.set_tool, self._TOOL_MARQUEE_SMART) - def create_palette(self, tool=None): - # Deprecated: Palette module has changed. - #TODO: create palettes for other tools. - if tool == None: - return None - elif (tool == 'Brush') or (tool == 'Eraser'): - palette = Palette(_(tool)) - item_1 = gtk.MenuItem(_('Square')) - item_2 = gtk.MenuItem(_('Circle')) - - palette.append_menu_item(item_1) - palette.append_menu_item(item_2) - item_1.show() - item_2.show() - item_1.connect('activate', self.set_shape, tool, 'square') - item_2.connect('activate', self.set_shape, tool,'circle') - - return palette - - def set_palette(self, widget, tool=None): - '''Set palette for a tool''' + def _configure_palette(self, widget, tool=None): + '''Set palette for a tool + widget - the widget which Palette will be set + tool - the reference tool for Palette creation. Its values are + restricted to ToolsToolbar Class constants + ''' logging.debug('setting a palette for %s', tool) - #FIXME: this does not work; MenuItem widgets are not displayed. This way, it is not possible to choose shapes for Brush and Eraser. palette = widget.get_palette() - #print palette, tool - if tool == None: + + if tool is None: return - elif (tool == self._TOOL_BRUSH) or (tool == self._TOOL_ERASER): - palette = Palette(_(tool)) + elif (tool is self._TOOL_BRUSH) or (tool is self._TOOL_ERASER): + item_1 = MenuItem(_('Square')) item_2 = MenuItem(_('Circle')) logging.debug('Menu Items created') - #print palette.menu.get_children() for menu_item in palette.menu.get_children(): - #print menu_item palette.menu.remove(menu_item) palette.menu.append(item_1) @@ -624,12 +606,6 @@ class ShapesToolbar(gtk.Toolbar): self._icon_fill.show() self._icon_fill.set_tooltip(_('Fill Color')) - # Changing widget: using toolbox.ButtonFillColor instead of toolbox.ComboFillColors - ''' - self._fill_color = ComboFillColors(activity) - self.insert(self._fill_color, -1) - self._fill_color.show() - ''' self._fill_color = ButtonFillColor(activity) self._fill_color.show() item = gtk.ToolItem() @@ -642,12 +618,7 @@ class ShapesToolbar(gtk.Toolbar): self._icon_stroke.show() self._icon_stroke.set_tooltip(_('Stroke Color')) - # Changing widget: using toolbox.ButtonStrokeColor instead of toolbox.ComboStrokeColors - ''' - self._stroke_color = ComboStrokeColors(activity) - self.insert(self._stroke_color, -1) - self._stroke_color.show() - ''' + self._stroke_color = ButtonStrokeColor(activity) self._stroke_color.show() item = gtk.ToolItem() @@ -684,6 +655,10 @@ class ShapesToolbar(gtk.Toolbar): self.insert(self._tool_shape_polygon, -1) self._tool_shape_polygon.show() self._tool_shape_polygon.set_tooltip(_('Polygon')) +# try: + self._configure_palette(self._tool_shape_polygon, self._TOOL_SHAPE_POLYGON) +# except: +# logging.debug('Could not create palette for Regular Polygon') """ @@ -770,7 +745,49 @@ class ShapesToolbar(gtk.Toolbar): def _on_icon_fill_clicked(self, widget, data=None): self._fill_color.clicked() - + + def _configure_palette(self, widget, tool=None): + '''Configure palette for a given tool + widget - the widget which Palette will be set + tool - the reference tool for Palette creation. Its values are + restricted to ToolsToolbar Class constants + ''' + + logging.debug('setting a palette for %s', tool) + + palette = widget.get_palette() + + if tool is None: + logging.debug('Trying to configure Palette, but there is no tool!') + raise TypeError + + elif tool is self._TOOL_SHAPE_POLYGON: + spin = gtk.SpinButton() + spin.show() + + black = gtk.gdk.Color(0,0,0) + white = gtk.gdk.Color(255,255,255) + + spin.modify_base(gtk.STATE_NORMAL, black) + spin.modify_base(gtk.STATE_ACTIVE, white) + + # This is where we set restrictions for Regular Polygon: + # Initial value, minimum value, maximum value, step + try: + initial = self._activity._area.polygon_sides + except: + initial = 5 + adj = gtk.Adjustment(float(initial), 3.0, 50.0, 1.0) + spin.set_adjustment(adj) + + spin.set_numeric(True) + palette.set_content(spin) + + spin.connect('value-changed', self._on_value_changed) + + def _on_value_changed(self, spinbutton, data=None): + self._activity._area.polygon_sides = spinbutton.get_value_as_int() + class TextToolbar(gtk.Toolbar): _ACTION_TEXT = 'text' @@ -915,7 +932,7 @@ class ImageToolbar(gtk.Toolbar): logging.debug(file_path) #file_path = decode_path((file_path,))[0] #open(activity, file_path) - activity._area.d.loadImage(file_path,widget) + activity._area.loadImage(file_path,widget,True) elif response == gtk.RESPONSE_CANCEL: logging.debug('Closed, no files selected') @@ -925,7 +942,8 @@ class ImageToolbar(gtk.Toolbar): class EffectsToolbar(gtk.Toolbar): - _ACTION_GRAYSCALE = 'grayscale' + _EFFECT_GRAYSCALE = 'grayscale' + _EFFECT_RAINBOW = 'rainbow' def __init__(self, activity): gtk.Toolbar.__init__(self) @@ -938,6 +956,11 @@ class EffectsToolbar(gtk.Toolbar): self.insert(self._effect_grayscale, -1) self._effect_grayscale.show() self._effect_grayscale.set_tooltip(_('Grayscale')) + + self._effect_rainbow = ToolButton('effect-raindow') + self.insert(self._effect_rainbow, -1) + self._effect_rainbow.show() + self._effect_rainbow.set_tooltip(_('Rainbow')) """ #FIXME: Must be implemented @@ -955,10 +978,16 @@ class EffectsToolbar(gtk.Toolbar): """ self._effect_grayscale.connect('clicked', self.grayscale, activity) + self._effect_rainbow.connect('clicked', self.rainbow, activity) def grayscale(self, widget, activity): activity._area._set_grayscale(widget) + def rainbow(self, widget, activity): + activity._area.tool = self._EFFECT_RAINBOW + #FIXME: this should NOT be like this. I want user to choose rainbow size! + activity._area.configure_line(10) + class ViewToolbar(gtk.Toolbar): -- cgit v0.9.1