diff options
author | Manusheel <manusheel@localhost.localdomain> | 2007-07-18 20:04:08 (GMT) |
---|---|---|
committer | Manusheel <manusheel@localhost.localdomain> | 2007-07-18 20:04:08 (GMT) |
commit | 9c0b7121410f4d013d2cc67e5b7490c593abdb74 (patch) | |
tree | afea4805a043a93aed56d7999bdf93a16b9c2553 /Area.py | |
parent | 56264eb6a6e1ddef6148b78de6b52afd9e1bb745 (diff) |
New SVG Icon, name of project changed to paint and bugs fixed
Diffstat (limited to 'Area.py')
-rw-r--r-- | Area.py | 491 |
1 files changed, 491 insertions, 0 deletions
@@ -0,0 +1,491 @@ +# -*- coding: utf-8 -*- +import pygtk
+pygtk.require('2.0')
+import gtk
+import sys, gobject, socket
+from gtk import gdk
+import math
+import pango
+
+from Desenho import Desenho
+
+WIDTH = 800
+HEIGHT = 600
+
+class Area(gtk.DrawingArea):
+ def __init__(self, janela): + """ Initialize the object from class Area which is derived from gtk.DrawingArea. + + Keyword arguments: + self -- the Area object (GtkDrawingArea) + janela -- the parent window + + """
+ gtk.DrawingArea.__init__(self)
+ self.set_size_request(WIDTH, HEIGHT)
+ self.set_events(gtk.gdk.POINTER_MOTION_MASK |
+ gtk.gdk.POINTER_MOTION_HINT_MASK |
+ gtk.gdk.BUTTON_PRESS_MASK |
+ gtk.gdk.BUTTON_RELEASE_MASK|
+ gtk.gdk.EXPOSURE_MASK)
+
+ self.connect("expose_event",self.expose)
+ self.connect("motion_notify_event", self.mousemove)
+ self.connect("button_press_event", self.mousedown)
+ self.connect("button_release_event", self.mouseup)
+
+ self.set_extension_events(gtk.gdk.EXTENSION_EVENTS_CURSOR)
+
+ self.tool = None
+ self.desenha = False
+ self.move = False
+ 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.busy = False
+ self.gc = None
+ self.gc_line = None
+ self.gc_eraser = None + self.gc_brush = None
+ self.gc_selection = None + self.pixmap = None
+ self.pixmap_temp = None
+ self.desenho = []
+ self.textos = []
+ self.color_ = 0
+ self.color_line = 0
+ self.estadoTexto = 0
+ self.janela = janela
+ self.d = Desenho(self) + self.line_size = 2 + self.brush_shape = 'circle' +
+ colormap = self.get_colormap()
+
+ self.cores = [ + colormap.alloc_color('#000000', True, True), # black
+ colormap.alloc_color('#ee33ee', True, True), # purple
+ colormap.alloc_color('#f4ee56', True, True), # yellow
+ colormap.alloc_color('#45a5dc', True, True), # blue
+ colormap.alloc_color('#44aa44', True, True), # green
+ colormap.alloc_color('#dd5555', True, True), # red
+ colormap.alloc_color('#ffaa11', True, True), # orange
+ colormap.alloc_color('#ffffff', True, True), # white
+ colormap.alloc_color('#00aa00', True, True) # green - selection
+ ]
+ self.font = pango.FontDescription('Sans 9')
+ #self.mensagem = Mensagens(self)
+ #self.mensagem.criaConexao() + + #start of UNDO and REDO + self.first_undo = True + self.undo_times = 0 + self.redo_times = 0 + self.undo_list=[]#pixmaps list to Undo func
+
+ # Create a new backing pixmap of the appropriate size
+ def configure_event(self, widget, event): + """Configure the Area object. + + Keyword arguments: + self -- the Area object (GtkDrawingArea) + widget -- the Area object (GtkDrawingArea) + event -- GdkEvent + + """
+ win = widget.window
+ width = win.get_geometry()[2]
+ height = win.get_geometry()[3]
+
+ self.pixmap = gtk.gdk.Pixmap(win, width, height, -1)
+ self.pixmap.draw_rectangle(widget.get_style().white_gc, True, 0, 0, width, height)
+ self.pixmap_temp = gtk.gdk.Pixmap(win, width, height, -1)
+ self.pixmap_temp.draw_rectangle(widget.get_style().white_gc, True, 0, 0, width, height)
+
+ self.gc = widget.window.new_gc()
+ self.gc_eraser = widget.window.new_gc()
+ self.gc_eraser.set_foreground(self.cores[7]) + + self.gc_brush = widget.window.new_gc()
+ self.gc_brush.set_foreground(self.cores[0])
+
+ self.gc_line = widget.window.new_gc() + + self.gc_selection = widget.window.new_gc()
+ self.gc_selection.set_line_attributes(1, gtk.gdk.LINE_ON_OFF_DASH, gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND)
+ self.gc_selection.set_foreground(self.cores[8])
+ + print 'configure event' +
+ return True + + # set the new line size + def configure_line(self, size): + """Configure the line's size. + + Keyword arguments: + self -- the Area object (GtkDrawingArea) + size -- + + """ + self.line_size = size + self.gc_line.set_line_attributes(size, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND)
+
+ def expose(self, widget, event): + """Show up the Area object (GtkDrawingArea). + + Keyword arguments: + self -- the Area object (GtkDrawingArea) + widget -- the Area object (GtkDrawingArea) + event -- GdkEvent + + """
+ area = event.area
+ if self.desenha:
+ widget.window.draw_drawable(self.gc, self.pixmap_temp, area[0], area[1], area[0], area[1], area[2], area[3])
+ else:
+ widget.window.draw_drawable(self.gc, self.pixmap, area[0], area[1], area[0], area[1], area[2], area[3])
+ return False
+
+ def mousedown(self,widget,event): + """Make the Area object (GtkDrawingArea) recognize that the mouse button was pressed. + + Keyword arguments: + self -- the Area object (GtkDrawingArea) + widget -- the Area object (GtkDrawingArea) + event -- GdkEvent + + """
+ # text + if self.busy == False:
+ if self.tool == 4:
+ self.d.text(widget,event)
+ if not self.move or self.tool != 26:
+ self.oldx = int(event.x)
+ self.oldy = int(event.y)
+
+ self.desenha = True
+
+ def mousemove(self,widget,event): + """Make the Area object (GtkDrawingArea) recognize that the mouse is moving. + + Keyword arguments: + self -- the Area object (GtkDrawingArea) + widget -- the Area object (GtkDrawingArea) + event -- GdkEvent + + """ + if self.busy == False:
+ x , y, state = event.window.get_pointer()
+ coords = int(x), int(y)
+
+ if state & gtk.gdk.BUTTON1_MASK and self.pixmap != None:
+ if self.tool == 3:
+ self.d.eraser(widget, coords) + #brush + elif self.tool == 29: + self.d.brush(widget, coords, self.line_size, self.brush_shape)
+ if self.desenha:
+ # line
+ if self.tool == 1:
+ print self.oldx + self.configure_line(self.line_size)
+ self.d.line(widget, coords)
+ # pencil
+ elif self.tool == 2: + self.configure_line(self.line_size)
+ self.d.pencil(widget, coords)
+ # circle
+ elif self.tool == 5: + self.configure_line(self.line_size)
+ self.d.circle(widget,coords)
+ # square
+ elif self.tool == 6: + self.configure_line(self.line_size)
+ self.d.square(widget,coords)
+ # selection
+ elif self.tool == 26 and not self.move:
+ self.d.selection(widget,coords)
+ # selection
+ elif self.tool == 26 and self.move:
+ self.d.moveSelection(widget, coords) + #polygon + elif self.tool == 27: + self.configure_line(self.line_size) + self.d.polygon(widget, coords) + #triangle + elif self.tool == 30: + self.configure_line(self.line_size) + self.d.triangle(widget,coords) + #trapezoid
+ elif self.tool == 31: + self.configure_line(self.line_size) + self.d.trapezoid(widget,coords) +
+ def mouseup(self,widget,event):
+ """Make the Area object (GtkDrawingArea) recognize that the mouse was released. + + Keyword arguments: + self -- the Area object (GtkDrawingArea) + widget -- the Area object (GtkDrawingArea) + event -- GdkEvent + + """ + if self.busy == False:
+ if self.desenha == True:
+ # line
+ if self.tool == 1:
+ self.pixmap.draw_line(self.gc_line,self.oldx,self.oldy, int (event.x), int(event.y))
+ widget.queue_draw() + self.enableUndo(widget)
+ # circle
+ elif self.tool == 5:
+ 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)
+ # square
+ elif self.tool == 6:
+ 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 == 26:
+ if self.move == False:
+ self.pixmap_temp.draw_drawable(self.gc,self.pixmap, 0 , 0 ,0,0, WIDTH, HEIGHT)
+ self.move = True
+ self.sx = int (event.x)
+ self.sy = int(event.y)
+ self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.FLEUR))
+ elif self.move == True:
+ self.pixmap.draw_drawable(self.gc, self.pixmap_temp, 0,0,0,0, WIDTH, HEIGHT)
+ # FIXME: Adicionar cursor formato selecao + self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.CROSSHAIR))
+ self.move = False + self.enableUndo(widget)
+ # polygon
+ elif self.tool == 27:
+ if self.polygon_start: + self.enableUndo(widget) + self.pixmap.draw_line(self.gc_line,self.oldx,self.oldy, int (event.x), int( event.y )) + self.lastx = event.x + self.lasty = event.y + self.firstx = self.oldx + self.firsty = self.oldy + self.polygon_start = False + else: + self.dx = math.fabs(event.x - self.firstx) + self.dy = math.fabs(event.y - self.firsty) + if (self.dx < 20) & (self.dy < 20): + self.pixmap.draw_line(self.gc_line,int (self.firstx), int (self.firsty), int (self.lastx), int (self.lasty)) + self.polygon_start = True + self.undo_times -= 1#destroy the undo screen of polygon start + self.enableUndo(widget) + else: + self.pixmap.draw_line(self.gc_line,int (self.lastx),int (self.lasty), int (event.x), int( event.y )) + self.lastx = event.x + self.lasty = event.y + widget.queue_draw() + + elif self.tool == 2:# or 4 check this for desire tool + widget.queue_draw() + self.enableUndo(widget) + + #bucket + elif self.tool == 28: + # New algorithm. See Desenho.py + width, height = self.window.get_size() + self.busy = True + image = self.pixmap.get_image(0,0, width, height) + fill_image = self.d.fill(image, int(event.x), int(event.y), self.color_dec) + + self.pixmap.draw_image(self.gc, fill_image,0,0,0,0, width, height) + self.pixmap_temp.draw_image(self.gc, fill_image,0,0,0,0, width, height) + + del image + del fill_image + + widget.queue_draw() + self.busy = False + self.enableUndo(widget) + + elif self.tool == 30: + self.pixmap.draw_polygon(self.gc, True, self.d.points)
+ self.pixmap.draw_polygon(self.gc_line, False, self.d.points) + widget.queue_draw() + self.enableUndo(widget) + + elif self.tool == 31: + self.pixmap.draw_polygon(self.gc, True, self.d.points)
+ self.pixmap.draw_polygon(self.gc_line, False, self.d.points) + widget.queue_draw() + self.enableUndo(widget) + if self.tool == 29 or self.tool == 3: + widget.queue_draw() + self.enableUndo(widget) + if self.tool == 4: + widget.queue_draw() + self.enableUndo(widget) + self.desenha = False
+
+ + #this func make a basic Undo + def undo(self): + """Undo the last drawing change. + + Keyword arguments: + self -- the Area object (GtkDrawingArea) + + """ + self.polygon_start = True + if self.first_undo:#if is the first time you click on UNDO + self.undo_times -= 1 + self.redo_times = 1 + + elif (self.first_redo) and (self.undo_times!=0): + self.undo_times += 1 + + print "Undo no.%d" %(self.undo_times) + if self.undo_times >0 : + self.undo_times -= 1 + self.redo_times += 1 + try: #to not try paint someting wrong + #print "Drawing undo[%d]" %(self.undo_times) + self.pixmap.draw_drawable(self.gc, self.undo_list[self.undo_times], 0,0,0,0, WIDTH, HEIGHT) + except: + print "Can't draw" + pass + self.queue_draw() + self.first_redo=False + else: + self.undo_times = 0 + #self.redo_times = 1 + self.first_redo = True + self.d.clear()#Undo the last action, so clear-all + self.first_undo=False + + + #special case of func polygon + if self.tool == 27: + self.polygon_start = True #start the polygon again + + + def redo(self): + """Redo the last undo operation. + + Keyword arguments: + self -- the Area object (GtkDrawingArea) + + """ + #print "REDO no.%d" %(self.redo_times) + + if (self.redo_times>0): + self.redo_times -= 1 + self.undo_times += 1 + + + if self.first_redo: + self.undo_times -=1 + self.redo_times +=1 + self.first_redo=False + try: #to not try paint someting wrong + #print "Drawing undo[%d]" %(self.undo_times) + self.pixmap.draw_drawable(self.gc, self.undo_list[self.undo_times], 0,0,0,0, WIDTH, HEIGHT) + except: + print "Can't draw" + self.undo_times-=1 + self.queue_draw() + + + def enableUndo(self,widget): + """Keep the last change in a list for Undo/Redo commands. + + Keyword arguments: + self -- the Area object (GtkDrawingArea) + widget -- the Area object (GtkDrawingArea) + + """ + if not self.first_undo and not self.first_redo: + self.undo_times += 1 + + self.undo_list.append(None)#alloc memory + self.undo_list[self.undo_times] = gtk.gdk.Pixmap(widget.window, WIDTH, HEIGHT, -1) #define type
+ self.undo_list[self.undo_times].draw_drawable(self.gc,self.pixmap,0,0,0,0, WIDTH, HEIGHT) #copy workarea + self.undo_times += 1 + self.redo_times = 0 + self.first_undo = True + + #this is the part where we can limit the steps of undo/redo + #if self.undo_times>=2: + # self.undo_list.pop(0) + # self.undo_times-=1 + # print "estourou" + + def _set_fill_color(self, color): + """Set fill color. + + Keyword arguments: + self -- the Area object (GtkDrawingArea) + color -- integer "enum" + + """ + self.color_ = color
+ self.gc.set_foreground(self.cores[color]) +
+
+ def _set_stroke_color(self, color): + """Set stroke color. + + Keyword arguments: + self -- the Area object (GtkDrawingArea) + color -- integer "enum" + + """ + self.color_line = color
+ self.gc_line.set_foreground(self.cores[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(self.cores[color]) + self.color_dec = self.cores[color].pixel + + def _set_grayscale(self,widget): + """Apply grayscale effect. + + Keyword arguments: + self -- the Area object (GtkDrawingArea) + + """ + 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_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) + + def _rotate_left(self): + """Rotate the image. + + Keyword arguments: + self -- the Area object (GtkDrawingArea) + + """ + 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, -1, -1) + pix_ = pix.rotate_simple(gtk.gdk.PIXBUF_ROTATE_COUNTERCLOCKWISE) + self.pixmap.draw_pixbuf(self.gc, pix_, 0, 0, 0, 0, width=-1, height=-1, dither=gtk.gdk.RGB_DITHER_NORMAL, x_dither=0, y_dither=0) + self.queue_draw() + + |