Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Area.py
diff options
context:
space:
mode:
authorManusheel <manusheel@localhost.localdomain>2007-07-18 20:04:08 (GMT)
committer Manusheel <manusheel@localhost.localdomain>2007-07-18 20:04:08 (GMT)
commit9c0b7121410f4d013d2cc67e5b7490c593abdb74 (patch)
treeafea4805a043a93aed56d7999bdf93a16b9c2553 /Area.py
parent56264eb6a6e1ddef6148b78de6b52afd9e1bb745 (diff)
New SVG Icon, name of project changed to paint and bugs fixed
Diffstat (limited to 'Area.py')
-rw-r--r--Area.py491
1 files changed, 491 insertions, 0 deletions
diff --git a/Area.py b/Area.py
new file mode 100644
index 0000000..2d858b3
--- /dev/null
+++ b/Area.py
@@ -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()
+
+