From b900e216169904ecc18190069f206a283997ceb2 Mon Sep 17 00:00:00 2001 From: Alexandre Antonino Gonçalves Martinazzo Date: Fri, 19 Oct 2007 18:41:25 +0000 Subject: Merging repositories Using Sugar's Object Chooser to "Import Image" dialog box; user imports images from Journal. Palettes' layout changed (see ticket #4231). Image Toolbar buttons active only when there is a selection. Clear button now works with selected areas. From SVN: r116 | barbolo | 2007-10-16 15:57:10 -0200 (Ter, 16 Out 2007) | 14 lines Freeform polygon tool. Eben has suggested a new way of drawing freeform polygon and it's been implemented in this version. Now, it's possible to draw polygons with freeform lines. Modified functions: Desenho.polygon All the new algorithm has been written. Area.mousedown Area.mousemove Area.mouseup It's changed the way of calling Desenho.polygon function. ------------------------------------------------------------------------ r115 | andremossinato | 2007-10-09 14:38:51 -0300 (Ter, 09 Out 2007) | 4 lines now effects can be used in selection fixed bug in "insert image" added rotate --- diff --git a/Area.py b/Area.py index 031d7c7..b44081d 100644 --- a/Area.py +++ b/Area.py @@ -69,7 +69,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, ([])), - 'selected' : (gobject.SIGNAL_ACTION, gobject.TYPE_NONE, ([])), + 'select' : (gobject.SIGNAL_ACTION, gobject.TYPE_NONE, ([])), } def __init__(self, janela): @@ -84,6 +84,7 @@ class Area(gtk.DrawingArea): gtk.DrawingArea.__init__(self) #self.set_size_request(800, 600) self.set_size_request(1185, 770) + self.set_events(gtk.gdk.POINTER_MOTION_MASK | gtk.gdk.POINTER_MOTION_HINT_MASK | gtk.gdk.BUTTON_PRESS_MASK | @@ -132,7 +133,6 @@ class Area(gtk.DrawingArea): self.pixmap = None self.pixmap_temp = None self.pixmap_sel = None - self.pixbuf_sel = None self.desenho = [] self.textos = [] self.estadoTexto = 0 @@ -140,7 +140,7 @@ class Area(gtk.DrawingArea): self.d = Desenho(self) self.line_size = 2 self.line_shape = 'circle' - self.last = -1, -1 + self.last = [] self.rainbow_counter = 0 self.font = pango.FontDescription('Sans 9') @@ -185,8 +185,8 @@ class Area(gtk.DrawingArea): self.pixmap_temp.draw_rectangle(widget.get_style().white_gc, True, 0, 0, width, height) ##When something is selected this pixmap draw and rectangular box out of the selection - self.pixmap_sel = gtk.gdk.Pixmap(win, width, height, -1) - self.pixmap_sel.draw_rectangle(widget.get_style().white_gc, True, 0, 0, width, height) + #self.pixmap_sel = gtk.gdk.Pixmap(win, width, height, -1) + #self.pixmap_sel.draw_rectangle(widget.get_style().white_gc, True, 0, 0, width, height) self.gc = win.new_gc() self.gc_eraser = win.new_gc() @@ -242,13 +242,10 @@ class Area(gtk.DrawingArea): #logging.debug('Area.expose(self, widget, event)') area = event.area - if self.desenha: - if self.selmove : - widget.window.draw_drawable(self.gc, self.pixmap_sel, area[0], area[1], area[0], area[1], area[2], area[3]) - else: - widget.window.draw_drawable(self.gc, self.pixmap_temp, area[0], area[1], area[0], area[1], area[2], area[3]) + if self.desenha or self.selmove: + 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]) + 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): @@ -282,38 +279,38 @@ class Area(gtk.DrawingArea): self.estadoTexto = 0 self.janela.textview.hide() - if not self.selmove or self.tool['name'] != 'marquee-rectangular': - self.oldx, self.oldy = coords + self.oldx, self.oldy = coords if self.selmove and self.tool['name'] != 'marquee-rectangular': #get out of the func selection - self.pixmap.draw_drawable(self.gc, self.pixmap_temp, 0,0,0,0, width, height) + self.getout() self.selmove = False - self.pixbuf_sel = None - self.enableUndo(widget) if self.tool['name'] == 'eraser': - self.last = -1, -1 + self.last = [] self.d.eraser(widget, coords, self.last, self.line_size, self.tool['line shape']) self.last = coords elif self.tool['name'] == 'brush': - self.last = -1, -1 + self.last = [] self.d.brush(widget, coords, self.last, self.line_size, self.tool['line shape']) self.last = coords elif self.tool['name'] == 'rainbow': - self.last = -1, -1 + self.last = [] self.d.rainbow(widget, coords, self.last, self.rainbow_counter,self.line_size, self.tool['line shape']) self.last = coords elif self.tool['name'] == 'polygon': self.configure_line(self.line_size) x , y, state = event.window.get_pointer() - x0, y0, x1, y1 = self.get_selection_bounds() if (state & gtk.gdk.BUTTON3_MASK):#Handle with the right button click event. self.sel_get_out = True - self.pixmap_sel.draw_drawable(self.gc, self.pixmap_temp, 0,0,0,0, width, height) - elif state & gtk.gdk.BUTTON1_MASK:#Handle with the left button click event. - if not (x0 xf) or (coords[1] < yi) or (coords[1] > yf): + self.sel_get_out = True else: self.pixmap_temp.draw_drawable(self.gc, self.pixmap, 0,0,0,0, width, height) widget.queue_draw() @@ -362,18 +359,15 @@ class Area(gtk.DrawingArea): self.d.square(widget,coords,True,self.tool['fill']) elif self.tool['name'] == 'marquee-rectangular' and not self.selmove: - x1, y1, x2, y2 = self.d.selection(widget,coords,True,False) - self._set_selection_bounds(x1, y1, x2, y2) + self.d.selection(widget,coords) # selected elif self.tool['name'] == 'marquee-rectangular' and self.selmove: - if self.pixbuf_sel!=None: - self.d.moveSelection(widget,coords,True,self.pixbuf_sel) - else: + if not self.sel_get_out: self.d.moveSelection(widget,coords) elif self.tool['name'] == 'polygon': self.configure_line(self.line_size) - self.d.polygon(widget,coords,True,self.tool['fill']) + self.d.polygon(widget,coords,True,self.tool['fill'],"motion") elif self.tool['name'] == 'triangle': self.configure_line(self.line_size) @@ -402,7 +396,22 @@ class Area(gtk.DrawingArea): elif self.tool['name'] == 'heart': self.configure_line(self.line_size) self.d.heart(widget,coords,True,self.tool['fill']) + else: + if self.tool['name'] == 'marquee-rectangular' and self.selmove: + size = self.pixmap_sel.get_size() + xi = self.orig_x + yi = self.orig_y + xf = xi + size[0] + yf = yi + size[1] + if (coords[0] < xi) or (coords[0] > xf) or (coords[1] < yi) or (coords[1] > yf): + self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.TCROSS)) + else: + self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.FLEUR)) + elif self.tool['name'] == 'polygon': + self.desenha = True + self.configure_line(self.line_size) + self.d.polygon(widget,coords,True,self.tool['fill'],"moving") def mouseup(self,widget,event): """Make the Area object (GtkDrawingArea) recognize that the mouse was released. @@ -427,27 +436,29 @@ class Area(gtk.DrawingArea): elif self.tool['name'] == 'rectangle': self.d.square(widget,coords,False,self.tool['fill']) self.enableUndo(widget) - + elif self.tool['name'] == 'marquee-rectangular': if self.selmove == False: - self.pixmap_temp.draw_drawable(self.gc,self.pixmap, 0,0,0,0, width, height) - self.pixmap_sel.draw_drawable(self.gc,self.pixmap, 0,0,0,0, width, height) - self.sx, self.sy = coords + self.d.selection(widget,coords,False) self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.FLEUR)) self.selmove = True self.sel_get_out = False - self.emit('selected') + self.emit('select') elif self.sel_get_out: #get out of the func selection - self.pixmap.draw_drawable(self.gc, self.pixmap_temp, 0,0,0,0, width, height) - self.selmove = False - self.pixbuf_sel = None + self.getout() + try: + del(self.d.pixbuf_resize) + except: pass self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.TCROSS)) - self.oldx, self.oldy = coords + widget.queue_draw() self.enableUndo(widget) - self.emit('selected') + elif self.selmove: + self.orig_x = self.orig_x + coords[0] - self.oldx + self.orig_y = self.orig_y + coords[1] - self.oldy + self.emit('select') elif self.tool['name'] == 'polygon': - self.d.polygon(widget, coords, False, self.tool['fill']) + self.d.polygon(widget, coords, False, self.tool['fill'],"release") elif self.tool['name'] == 'bucket': width, height = self.window.get_size() @@ -484,7 +495,7 @@ class Area(gtk.DrawingArea): self.enableUndo(widget) if self.tool['name'] == 'brush' or self.tool['name'] == 'eraser' or self.tool['name'] == 'rainbow' or self.tool['name'] == 'pencil' : - self.last = -1, -1 + self.last = [] widget.queue_draw() self.enableUndo(widget) self.desenha = False @@ -507,7 +518,6 @@ class Area(gtk.DrawingArea): 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: logging.debug('Cant draw') @@ -542,7 +552,6 @@ class Area(gtk.DrawingArea): self.undo_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: logging.debug('Cant draw') @@ -558,7 +567,8 @@ class Area(gtk.DrawingArea): @param widget -- the Area object (GtkDrawingArea) """ - logging.debug('Area.enableUndo(self,widget)') + #logging.debug('Area.enableUndo(self,widget)') + width, height = self.window.get_size() if self.undo_surf: @@ -578,8 +588,7 @@ class Area(gtk.DrawingArea): self.undo_times-=1 self.emit('action-saved') - - + def copy(self): """ Copy Image. When the tool selection is working make the change the copy of selectioned area @@ -591,23 +600,9 @@ class Area(gtk.DrawingArea): tempPath = os.path.abspath(tempPath) if self.selmove: - - if self.sx > self.oldx: - x = self.oldx - else: - x = self.sx - - if self.sy > self.oldy: - y = self.oldy - else: - y = self.sy - - w = math.fabs(self.sx - self.oldx) - h = math.fabs(self.sy - self.oldy) - - pixbuf_copy = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, w, h) - pixbuf_copy.get_from_drawable(self.pixmap, gtk.gdk.colormap_get_system(), x, y, 0, 0, w, h) - + size = self.pixmap_sel.get_size() + pixbuf_copy = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB,True,8,size[0],size[1]) + pixbuf_copy.get_from_drawable(self.pixmap_sel, gtk.gdk.colormap_get_system(),0,0,0,0,size[0],size[1]) pixbuf_copy.save(tempPath,'png') #with this func we can send the image to the clipboard with right MIME type, but we cannot past the image! #gtk.Clipboard().set_with_data( [('text/uri-list', 0, 0)], self._copyGetFunc, self._copyClearFunc, tempPath ) this make the icon seens right, but with none data @@ -639,7 +634,7 @@ class Area(gtk.DrawingArea): os.remove( data ) data = None - def past(self): + def past(self,widget): """ Past image. Past image that is in pixmap @@ -653,20 +648,25 @@ class Area(gtk.DrawingArea): clipBoard = gtk.Clipboard() if clipBoard.wait_is_image_available(): - self.pixbuf_sel = clipBoard.wait_for_image() - size = (int)(self.pixbuf_sel.get_width()), (int)(self.pixbuf_sel.get_height()) - self.pixmap_sel.draw_pixbuf(self.gc, self.pixbuf_sel, 0, 0, 0, 0, size[0], size[1], dither=gtk.gdk.RGB_DITHER_NORMAL, x_dither=0, y_dither=0) + self.getout(True,widget) + pixbuf_sel = clipBoard.wait_for_image() + size = (int)(pixbuf_sel.get_width()),(int)(pixbuf_sel.get_height()) + self.pixmap_sel = gtk.gdk.Pixmap(self.window,size[0],size[1],-1) + self.pixmap_sel.draw_pixbuf(self.gc,pixbuf_sel,0,0,0,0,size[0],size[1],dither=gtk.gdk.RGB_DITHER_NORMAL,x_dither=0,y_dither=0) + self.selmove = True self.desenha = True self.sel_get_out = False - self.oldx, self.oldy = 0,0 - x1, y1, x2, y2 = self.d.selection(self, size, True, False) - self._set_selection_bounds(x1, y1, x2, y2) - self.pixmap_sel.draw_rectangle(self.gc_selection, False ,0,0,size[0],size[1]) - self.sx, self.sy = size + self.orig_x, self.orig_y = 0,0 + + self.pixmap_temp.draw_drawable(self.gc,self.pixmap,0,0,0,0,width,height) + self.pixmap_temp.draw_drawable(self.gc,self.pixmap_sel,0,0,0,0,size[0],size[1]) + self.pixmap_temp.draw_rectangle(self.gc_selection,False,0,0,size[0],size[1]) + self.pixmap_temp.draw_rectangle(self.gc_selection1,False,-1,-1,size[0]+2,size[1]+2) + self.tool['name'] = 'marquee-rectangular' self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.FLEUR)) - self.emit('selected') + self.emit('select') else: self.loadImage(tempPath, self, True) logging.debug('Area.past(self): Load from clipboard fails, loading from tempPatch') @@ -705,19 +705,38 @@ class Area(gtk.DrawingArea): @param widget -- the Area object (GtkDrawingArea) """ + 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.saturate_and_pixelate(pix_, 0 ,0) + + if self.selmove: + size = self.pixmap_sel.get_size() + pix = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB,False,8,size[0],size[1]) + pix.get_from_drawable(self.pixmap_sel,gtk.gdk.colormap_get_system(),0,0,0,0,size[0],size[1]) + else: + 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) - 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) + pix.saturate_and_pixelate(pix,0,0) + + try: + self.d.pixbuf_resize.saturate_and_pixelate(self.d.pixbuf_resize,0,0) + except: pass - 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) + if self.selmove: + self.pixmap_sel.draw_pixbuf(self.gc,pix,0,0,0,0,size[0],size[1],dither=gtk.gdk.RGB_DITHER_NORMAL,x_dither=0,y_dither=0) + + self.pixmap_temp.draw_drawable(self.gc,self.pixmap,0,0,0,0,width,height) + self.pixmap_temp.draw_drawable(self.gc,self.pixmap_sel,0,0,self.orig_x,self.orig_y,size[0],size[1]) + self.pixmap_temp.draw_rectangle(self.gc_selection,False,self.orig_x,self.orig_y,size[0],size[1]) + self.pixmap_temp.draw_rectangle(self.gc_selection1,False,self.orig_x-1,self.orig_y-1,size[0]+2,size[1]+2) + + else: + 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.queue_draw() - self.enableUndo(widget) + if not self.selmove: + self.enableUndo(widget) def _pixbuf2Image(self, pb): """change a pixbuf to RGB image @@ -759,28 +778,61 @@ class Area(gtk.DrawingArea): """ logging.debug('Area._rotate_left(self)') - - x1, y1, x2, y2 = self.get_selection_bounds() - #x1, y1, x2, y2 = 0, 0, 100, 200 if self.selmove: - pix = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, x2 - x1, y2 - y1) - pix_ = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, x2 - x1, y2 - y1) - pix.get_from_drawable(self.pixmap, gtk.gdk.colormap_get_system(), x1, y1, 0, 0, x2 - x1, y2 - y1) - - im = self._pixbuf2Image(pix) - #pix_ = pix.rotate_simple(gtk.gdk.PIXBUF_ROTATE_CLOCKWISE) + width, height = self.window.get_size() + size = self.pixmap_sel.get_size() + pix = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False,8,size[0],size[1]) + pix.get_from_drawable(self.pixmap_sel, gtk.gdk.colormap_get_system(),0,0,0,0,size[0],size[1]) + pix = pix.rotate_simple(90) + try: + self.d.pixbuf_resize = self.d.pixbuf_resize.rotate_simple(90) + except: pass + try: + del(self.pixmap_sel) + except: pass + self.pixmap_sel = gtk.gdk.Pixmap(widget.window,size[1],size[0],-1) + self.pixmap_sel.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.pixmap_temp.draw_drawable(self.gc,self.pixmap,0,0,0,0,width,height) + self.pixmap_temp.draw_drawable(self.gc,self.pixmap_sel,0,0,self.orig_x,self.orig_y,size[1],size[0]) + self.pixmap_temp.draw_rectangle(self.gc_selection,False,self.orig_x,self.orig_y,size[1],size[0]) + self.pixmap_temp.draw_rectangle(self.gc_selection1,False,self.orig_x-1,self.orig_y-1,size[1]+2,size[0]+2) + self.queue_draw() + + else : + logging.debug('Please select some area first') - im_ = im.rotate(90) + def _rotate_right(self, widget): + """Rotate the image. - pix_ = self._image2pixbuf(im_) + @param self -- the Area object (GtkDrawingArea) + @param widget -- the Area object (GtkDrawingArea) + - self.pixmap.draw_pixbuf(self.gc, pix_, 0, 0, x1, y1, width=-1, height=-1, dither=gtk.gdk.RGB_DITHER_NORMAL, x_dither=0, y_dither=0) + """ + logging.debug('Area._rotate_right(self)') + if self.selmove: + width, height = self.window.get_size() + size = self.pixmap_sel.get_size() + pix = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False,8,size[0],size[1]) + pix.get_from_drawable(self.pixmap_sel, gtk.gdk.colormap_get_system(),0,0,0,0,size[0],size[1]) + pix = pix.rotate_simple(270) + try: + self.d.pixbuf_resize = self.d.pixbuf_resize.rotate_simple(270) + except: pass + try: + del(self.pixmap_sel) + except: pass + self.pixmap_sel = gtk.gdk.Pixmap(widget.window,size[1],size[0],-1) + self.pixmap_sel.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.pixmap_temp.draw_drawable(self.gc,self.pixmap,0,0,0,0,width,height) + self.pixmap_temp.draw_drawable(self.gc,self.pixmap_sel,0,0,self.orig_x,self.orig_y,size[1],size[0]) + self.pixmap_temp.draw_rectangle(self.gc_selection,False,self.orig_x,self.orig_y,size[1],size[0]) + self.pixmap_temp.draw_rectangle(self.gc_selection1,False,self.orig_x-1,self.orig_y-1,size[1]+2,size[0]+2) self.queue_draw() - self.enableUndo(widget) else : logging.debug('Please select some area first') - + def can_undo(self): """ Indicate if is there some action to undo @@ -807,7 +859,7 @@ class Area(gtk.DrawingArea): @param self -- the Area object (GtkDrawingArea) """ - logging.debug('Area.can_redo(self)') + #logging.debug('Area.can_redo(self)') if self.redo_times < 1: return False @@ -822,7 +874,7 @@ class Area(gtk.DrawingArea): """ - logging.debug('Area.is_selected(self)') + #logging.debug('Area.is_selected(self)') if self.selmove: return True @@ -849,13 +901,13 @@ class Area(gtk.DrawingArea): """ return self._selection_corners[0], self._selection_corners[1], self._selection_corners[2], self._selection_corners[3] - def loadImage(self, name, widget, load_selected=True): + def loadImage(self, name, widget=None, load_selected=True): """Load an image. @param self -- Area instance @param name -- string (image file path) @param widget -- GtkDrawingArea - @param load_selected -- False if this func is called by Journal + @param load_selected -- False if loading file from Journal """ logging.debug('Area.loadImage') @@ -863,39 +915,36 @@ class Area(gtk.DrawingArea): logging.debug('From Journal? %s', not load_selected) if not load_selected : - pixbuf = gtk.gdk.pixbuf_new_from_file(name) - + 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.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.undo_times -= 1 self.enableUndo(widget) - - else : - self.pixbuf_sel = gtk.gdk.pixbuf_new_from_file(name) - size = (int)(self.pixbuf_sel.get_width()), (int)(self.pixbuf_sel.get_height()) - width, height = self.window.get_size() - - self.pixmap_sel.draw_drawable(self.gc,self.pixmap,0,0,0,0, width, height) - self.pixmap_sel.draw_pixbuf(self.gc, self.pixbuf_sel, 0, 0, 0, 0, size[0], size[1], dither=gtk.gdk.RGB_DITHER_NORMAL, x_dither=0, y_dither=0) - + pixbuf = gtk.gdk.pixbuf_new_from_file(name) + size = (int)(pixbuf.get_width()), (int)(pixbuf.get_height()) + #self.getout(True,widget) + self.getout(True) + #self.pixmap_sel = gtk.gdk.Pixmap(widget.window,size[0],size[1],-1) + self.pixmap_sel = gtk.gdk.Pixmap(self.window,size[0],size[1],-1) + 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) + self.sel_get_out = False self.selmove = True self.desenha = True - self.oldx, self.oldy = 0,0 + self.orig_x, self.orig_y = 0,0 + #width, height = widget.window.get_size() + width, height = self.window.get_size() - x0, y0, x1, y1 = self.d.selection(self, size, True, False) - self._set_selection_bounds(x0, y0, x1, y1) + self.pixmap_temp.draw_drawable(self.gc,self.pixmap,0,0,0,0,width,height) + self.pixmap_temp.draw_drawable(self.gc,self.pixmap_sel,0,0,0,0,size[0],size[1]) + self.pixmap_temp.draw_rectangle(self.gc_selection,False,0,0,size[0],size[1]) + self.pixmap_temp.draw_rectangle(self.gc_selection1,False,-1,-1,size[0]+2,size[1]+2) - self.pixmap_sel.draw_rectangle(self.gc_selection, False ,0,0,size[0],size[1]) - self.sx, self.sy = size self.tool['name'] = 'marquee-rectangular' self.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.FLEUR)) - self.emit('selected') - + self.emit('select') + #widget.queue_draw() self.queue_draw() def clear(self): @@ -904,7 +953,11 @@ class Area(gtk.DrawingArea): """ logging.debug('Area.clear') self.d.clear(self) - self.enableUndo(self) + + # If something is selected, the action will be saved + # after it is unselected + if not self.is_selected(): + self.enableUndo(self) # Changing to public methods def _set_fill_color(self, color): @@ -975,4 +1028,25 @@ class Area(gtk.DrawingArea): self.window.set_cursor(cursor) + def getout(self,undo=False,widget=None): + logging.debug('Area.getout') + try: + self.pixmap_sel + size = self.pixmap_sel.get_size() + self.pixmap.draw_drawable(self.gc,self.pixmap_sel,0,0,self.orig_x,self.orig_y,size[0],size[1]) + self.selmove = False + if undo: + if widget is not None: + self.enableUndo(widget) + else: + self.enableUndo(self) + + del(self.pixmap_sel) + del(self.pixbuf_resize) + + except NameError, message: + logging.debug(message) + except Exception, message: + logging.debug('Unexpected error: %s', message) + diff --git a/Desenho.py b/Desenho.py index e7ad7e1..cbaca21 100644 --- a/Desenho.py +++ b/Desenho.py @@ -56,15 +56,13 @@ Roseli de Deus Lopes (roseli@lsi.usp.br) import pygtk pygtk.require('2.0') import gtk -import sys, gobject, socket +import sys, gobject, logging from gtk import gdk import math import pango import gc -WIDTH = 1195 -HEIGHT = 800 ##Pixmap manipulation class Desenho: def __init__(self, widget): @@ -105,13 +103,13 @@ class Desenho: widget.desenha = False if(shape == 'circle'): widget.pixmap.draw_arc(widget.gc_eraser, True, coords[0], coords[1], size, size, 0, 360*64) - if last[0] != -1: + if last: widget.gc_eraser.set_line_attributes(size, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND) widget.pixmap.draw_line(widget.gc_eraser,last[0]+size/2,last[1]+size/2,coords[0]+size/2,coords[1]+size/2) widget.gc_eraser.set_line_attributes(0, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND) if(shape == 'square'): widget.pixmap.draw_rectangle(widget.gc_eraser, True, coords[0], coords[1], size, size) - if last[0] != -1: + if last: points = [coords, last, (last[0]+size,last[1]+size), (coords[0]+size,coords[1]+size)] widget.pixmap.draw_polygon(widget.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)] @@ -132,13 +130,13 @@ class Desenho: widget.desenha = False if(shape == 'circle'): widget.pixmap.draw_arc(widget.gc_brush, True, coords[0], coords[1], size, size, 0, 360*64) - if last[0] != -1: + if last: widget.gc_brush.set_line_attributes(size, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND) widget.pixmap.draw_line(widget.gc_brush,last[0]+size/2,last[1]+size/2,coords[0]+size/2,coords[1]+size/2) widget.gc_brush.set_line_attributes(0, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND) if(shape == 'square'): widget.pixmap.draw_rectangle(widget.gc_brush, True, coords[0], coords[1], size, size) - if last[0] != -1: + if last: points = [coords, last, (last[0]+size,last[1]+size), (coords[0]+size,coords[1]+size)] widget.pixmap.draw_polygon(widget.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)] @@ -177,12 +175,12 @@ class Desenho: widget.desenha = False if(shape == 'circle'): widget.pixmap.draw_arc(widget.gc_rainbow, True, coords[0], coords[1], size, size, 0, 360*64) - if last[0] != -1: + if last: widget.gc_rainbow.set_line_attributes(size, gtk.gdk.LINE_SOLID, gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND) widget.pixmap.draw_line(widget.gc_rainbow,last[0]+size/2,last[1]+size/2,coords[0]+size/2,coords[1]+size/2) widget.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: + if last: widget.pixmap.draw_rectangle(widget.gc_rainbow, True, last[0], last[1], size, size) points = [coords, last, (last[0]+size,last[1]+size), (coords[0]+size,coords[1]+size)] widget.pixmap.draw_polygon(widget.gc_rainbow,True,points) @@ -207,17 +205,7 @@ class Desenho: pixmap = widget.pixmap width, height = widget.window.get_size() - dx = math.fabs(coords[0] - widget.oldx) - dy = math.fabs(coords[1] - widget.oldy) - - if coords[0] < widget.oldx: - x = coords[0] - else: - x = widget.oldx - if coords[1] < widget.oldy: - y = coords[1] - else: - y = widget.oldy + x, y, dx, dy, = self.adjust(widget,coords) pixmap.draw_drawable(widget.gc,widget.pixmap,0,0,0,0,width,height) if fill == True: @@ -466,17 +454,7 @@ class Desenho: pixmap = widget.pixmap width, height = widget.window.get_size() - if coords[0] < widget.oldx: - x = coords[0] - else: - x = widget.oldx - if coords[1] < widget.oldy: - y = coords[1] - else: - y = widget.oldy - - dx = math.fabs(coords[0] - widget.oldx) - dy = math.fabs(coords[1] - widget.oldy) + x, y, dx, dy = self.adjust(widget,coords) pixmap.draw_drawable(widget.gc,widget.pixmap,0,0,0,0,width,height) if fill == True: @@ -506,11 +484,32 @@ class Desenho: @param self -- Desenho.Desenho instance @param widget -- Area object (GtkDrawingArea) """ - width, height = widget.window.get_size() + logging.debug('Desenho.clear') + widget.desenho = [] - widget.textos = [] - widget.pixmap.draw_rectangle(widget.get_style().white_gc, True,0, 0, width, height) - widget.pixmap_temp.draw_rectangle(widget.get_style().white_gc, True,0, 0, width, height) + widget.textos = [] + + # try to clear a selected area first + if widget.is_selected(): + try: + width, height = widget.pixmap_sel.get_size() + + # Clear the selected area + widget.pixmap_sel.draw_rectangle(widget.get_style().white_gc, True,0, 0, width, height) + # Draw the selected area in the displayed pixmap + widget.pixmap_temp.draw_drawable(widget.gc,widget.pixmap_sel,0,0,widget.orig_x,widget.orig_y, width, height) + # Draw the selection rectangle + widget.pixmap_temp.draw_rectangle(widget.gc_selection, False, widget.orig_x,widget.orig_y, width, height) + widget.pixmap_temp.draw_rectangle(widget.gc_selection1,False, widget.orig_x-1,widget.orig_y-1, width+2, height+2) + + except NameError, message: + logging.debug(message) + except Exception, message: + logging.debug('Unexpected error: %s', message) + else: + width, height = widget.window.get_size() + widget.pixmap.draw_rectangle(widget.get_style().white_gc, True,0, 0, width, height) + widget.pixmap_temp.draw_rectangle(widget.get_style().white_gc, True,0, 0, width, height) widget.queue_draw() def text(self,widget,event): @@ -560,7 +559,7 @@ class Desenho: widget.queue_draw() - def selection(self, widget, coords, temp, fill): + def selection(self, widget, coords, temp=True): """Make a selection. @param self -- Desenho.Desenho instance @@ -571,38 +570,30 @@ class Desenho: @return (x0,y0,x1,y1) -- coords of corners """ - - if temp == True: - pixmap = widget.pixmap_temp - else: - pixmap = widget.pixmap + width, height = widget.window.get_size() - - dx = int(math.fabs(coords[0] - widget.oldx)) - dy = int(math.fabs(coords[1] - widget.oldy)) - - if coords[0] < widget.oldx: - x = int(coords[0]) - else: - x = widget.oldx - if coords[1] < widget.oldy: - y = int(coords[1]) + + x, y, dx, dy = self.adjust(widget,coords,True) + + widget.pixmap_temp.draw_drawable(widget.gc,widget.pixmap,0,0,0,0,width,height) + if temp: + widget.pixmap_temp.draw_rectangle(widget.gc_selection,False,x,y,dx,dy) + widget.pixmap_temp.draw_rectangle(widget.gc_selection1,False,x-1,y-1,dx+2,dy+2) else: - y = widget.oldy + try: + del (widget.pixmap_sel) + except: pass + widget.pixmap_sel = gtk.gdk.Pixmap(widget.window,dx,dy,-1) + widget.pixmap_sel.draw_drawable(widget.gc,widget.pixmap,x,y,0,0,dx,dy) + widget.pixmap.draw_rectangle(widget.get_style().white_gc,True,x,y,dx,dy) + widget.orig_x = x + widget.orig_y = y + widget.pixmap_temp.draw_rectangle(widget.gc_selection,False,x,y,dx,dy) + widget.pixmap_temp.draw_rectangle(widget.gc_selection1,False,x-1,y-1,dx+2,dy+2) - self.coords = (x,y) - - pixmap.draw_drawable(widget.gc,widget.pixmap,0,0,0,0,width,height) - if fill: - pixmap.draw_rectangle(widget.gc,True,x,y,dx,dy) - - pixmap.draw_rectangle(widget.gc_selection,False,x,y,dx,dy) - pixmap.draw_rectangle(widget.gc_selection1,False,x-1,y-1,dx+2,dy+2) widget.queue_draw() - return x,y,x+dx,y+dy - - def moveSelection(self, widget, coords, mvcopy=False, pixbuf_copy=None): + def moveSelection(self, widget, coords): """Move the selection. @param self -- Desenho.Desenho instance @@ -611,47 +602,22 @@ class Desenho: @param mvcopy -- Copy or Move @param pixbuf_copy -- For import image - """ - + """ + width, height = widget.window.get_size() - widget.pixmap_sel.draw_drawable(widget.gc,widget.pixmap,0,0,0,0, width, height) - - if widget.sx > widget.oldx: - x0 = int(widget.oldx) - else: - x0 = int(widget.sx) - - if widget.sy > widget.oldy: - y0 = int(widget.oldy) - else: - y0 = int(widget.sy) - - w = int(math.fabs(widget.sx - widget.oldx)) - h = int(math.fabs(widget.sy - widget.oldy)) + widget.pixmap_temp.draw_drawable(widget.gc,widget.pixmap,0,0,0,0, width, height) + + dx = int(coords[0]-widget.oldx) + dy = int(coords[1]-widget.oldy) - self.coords = (coords[0] -w/2,coords[1]-h/2) + size = widget.pixmap_sel.get_size() - widget._set_selection_bounds(coords[0]-w/2, coords[1]-h/2, coords[0]+w/2, coords[1]+h/2) - if not mvcopy: - widget.pixmap_sel.draw_rectangle(widget.get_style().white_gc, True, x0, y0, w, h) - - try: # test if resizing has been done - w, h = self.resized.get_width(), self.resized.get_height() - widget.pixmap_sel.draw_pixbuf(widget.gc,self.resized,0,0,coords[0] - w/2, coords[1] - h/2, w, h) - widget.pixmap_temp.draw_pixbuf(widget.gc,self.resized,0,0,coords[0] - w/2, coords[1] - h/2, w, h) - except: - if pixbuf_copy!=None: #to import or paste image - widget.pixmap_sel.draw_pixbuf(widget.gc, pixbuf_copy, 0, 0, coords[0] - w/2, coords[1]- h/2, w, h, dither=gtk.gdk.RGB_DITHER_NORMAL, x_dither=0, y_dither=0) - widget.pixmap_temp.draw_pixbuf(widget.gc, pixbuf_copy, 0, 0, coords[0] - w/2, coords[1]- h/2, w, h, dither=gtk.gdk.RGB_DITHER_NORMAL, x_dither=0, y_dither=0) - else: - widget.pixmap_sel.draw_drawable(widget.gc, widget.pixmap, x0, y0, coords[0] - w/2, coords[1]- h/2, w, h) - - widget.pixmap_temp.draw_drawable(widget.gc, widget.pixmap_sel,0,0,0,0, width, height) + widget.pixmap_temp.draw_drawable(widget.gc,widget.pixmap_sel,0,0,widget.orig_x+dx,widget.orig_y+dy, size[0], size[1]) - #to draw the selection black and white line rectangle - widget.pixmap_sel.draw_rectangle(widget.gc_selection, False ,coords[0] - w/2, coords[1]- h/2, w, h) - widget.pixmap_sel.draw_rectangle(widget.gc_selection1, False ,coords[0] - w/2-1, coords[1]- h/2-1, w+2, h+2) + widget.pixmap_temp.draw_rectangle(widget.gc_selection, False ,widget.orig_x+dx,widget.orig_y+dy, size[0], size[1]) + widget.pixmap_temp.draw_rectangle(widget.gc_selection1,False,widget.orig_x+dx-1,widget.orig_y+dy-1,size[0]+2,size[1]+2) + widget.queue_draw() def resizeSelection(self, widget, width_percent, height_percent): @@ -662,54 +628,43 @@ class Desenho: @param height_percent -- Percent of y scale """ + width, height = widget.window.get_size() widget.desenha = True widget.selmove = True - - width, height = widget.window.get_size() - widget.pixmap_sel.draw_drawable(widget.gc,widget.pixmap_temp,0,0,0,0, width, height) - if widget.sx > widget.oldx: - x0 = int(widget.oldx) - else: - x0 = int(widget.sx) - - if widget.sy > widget.oldy: - y0 = int(widget.oldy) - else: - y0 = int(widget.sy) - - w = int(math.fabs(widget.sx - widget.oldx)) - h = int(math.fabs(widget.sy - widget.oldy)) - delta_x = int( w*(width_percent-1)/2 ) - delta_y = int( h*(height_percent-1)/2 ) gc.collect() - - try: self.resize_pixbuf + #Create the pixbuf for future resizes + try: + self.pixbuf_resize except: - self.resize_pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, w, h) - self.resize_pixbuf.get_from_drawable(widget.pixmap, gtk.gdk.colormap_get_system(), x0, y0, 0, 0, int(w), int(h)) + size = widget.pixmap_sel.get_size() + self.pixbuf_resize = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB,False,8,size[0],size[1]) + self.pixbuf_resize.get_from_drawable(widget.pixmap_sel,gtk.gdk.colormap_get_system(),0,0,0,0,size[0],size[1]) - x0,y0 = self.coords + w = self.pixbuf_resize.get_width() + h = self.pixbuf_resize.get_height() + wr = int(w*width_percent) + hr = int(h*height_percent) + resized = self.pixbuf_resize.scale_simple(wr,hr,gtk.gdk.INTERP_HYPER) + + #Copy the resized picture to pixmap_sel try: - del(self.resized) + del (widget.pixmap_sel) except: pass - - self.resized = self.resize_pixbuf.scale_simple(int(w*width_percent), int(h*height_percent), gtk.gdk.INTERP_HYPER) - - widget.pixmap_sel.draw_rectangle(widget.get_style().white_gc, True, x0 - delta_x, y0 - delta_y, int(w*width_percent), int(h*height_percent)) - widget.pixmap_sel.draw_pixbuf(widget.get_style().white_gc,self.resized,0,0,x0 - delta_x, y0 - delta_y,int(w*width_percent), int(h*height_percent)) + widget.pixmap_sel = gtk.gdk.Pixmap(widget.window,wr,hr,-1) + widget.pixmap_sel.draw_pixbuf(widget.get_style().white_gc,resized,0,0,0,0,wr,hr) - widget.pixmap_temp.draw_drawable(widget.gc, widget.pixmap_sel,0,0,0,0, width, height) + #Draw the new pixmap_sel + widget.pixmap_temp.draw_drawable(widget.gc,widget.pixmap,0,0,0,0,width,height) + widget.pixmap_temp.draw_drawable(widget.gc,widget.pixmap_sel,0,0,widget.orig_x,widget.orig_y,wr,hr) + widget.pixmap_temp.draw_rectangle(widget.gc_selection,False,widget.orig_x,widget.orig_y,wr,hr) + widget.pixmap_temp.draw_rectangle(widget.gc_selection1,False,widget.orig_x-1,widget.orig_y-1,wr+2,hr+2) - #to draw the selection black and white line rectangle - widget.pixmap_sel.draw_rectangle(widget.gc_selection, False ,x0- delta_x -1, y0- delta_y-1,int(width_percent*w+1), int(height_percent*h+1)) - widget.pixmap_sel.draw_rectangle(widget.gc_selection1, False ,x0- delta_x -2, y0- delta_y-2,int(width_percent*w +1), int(height_percent*h +1)) - widget.queue_draw() gc.collect() - def polygon(self, widget, coords, temp, fill): + def polygon(self, widget, coords, temp, fill, param = None): """Draw polygon. @param self -- Desenho.Desenho instance @@ -727,21 +682,48 @@ class Desenho: width, height = widget.window.get_size() pixmap.draw_drawable(widget.gc, widget.pixmap, 0, 0, 0, 0, width, height) - - if widget.polygon_start == True: # Starting a new polygon ? - if temp == True: - pixmap.draw_line(widget.gc_line,widget.oldx,widget.oldy, coords[0], coords[1]) - else: - pixmap.draw_line(widget.gc_line,widget.oldx,widget.oldy, coords[0], coords[1]) + + if param == "moving": + # mouse not pressed moving + if not widget.polygon_start: + pixmap.draw_line(widget.gc_line,widget.last[0],widget.last[1], coords[0], coords[1]) + elif widget.polygon_start == True: # Starting a new polygon ? + if param == "motion": + # first press + try: + pixmap.draw_line(widget.gc_line,widget.last[0],widget.last[1], coords[0], coords[1]) + widget.pixmap.draw_line(widget.gc_line,widget.last[0],widget.last[1], coords[0], coords[1]) + widget.points.append(coords) + except: + pixmap.draw_line(widget.gc_line,widget.oldx,widget.oldy, coords[0], coords[1]) + widget.pixmap.draw_line(widget.gc_line,widget.oldx,widget.oldy, coords[0], coords[1]) + widget.first = widget.oldx, widget.oldy + widget.points = [widget.first, coords] + widget.enableUndo(widget) + widget.last = coords + else: # param == "release" + # first release + try: + widget.first + widget.points.append(coords) + widget.pixmap.draw_line(widget.gc_line,widget.last[0],widget.last[1], coords[0], coords[1]) + except: + widget.first = widget.oldx, widget.oldy + widget.points = [widget.first, coords] + widget.pixmap.draw_line(widget.gc_line,widget.oldx,widget.oldy, coords[0], coords[1]) widget.enableUndo(widget) widget.last = coords - widget.first = widget.oldx, widget.oldy widget.polygon_start = False - widget.points = [widget.first, coords] else: - if temp == True: + if param == "motion": + # print "press" pixmap.draw_line(widget.gc_line,widget.last[0],widget.last[1],coords[0],coords[1]) - else: + widget.pixmap.draw_line(widget.gc_line,widget.last[0],widget.last[1], coords[0], coords[1]) + widget.enableUndo(widget) + widget.last = coords + widget.points.append(coords) + elif param == "release": + # print "release" x = coords[0] - widget.first[0] y = coords[1] - widget.first[1] d = math.hypot(x,y) @@ -754,11 +736,40 @@ class Desenho: if fill == True: pixmap.draw_polygon(widget.gc, True, tp) pixmap.draw_polygon(widget.gc_line, False, tp) - widget.last = -1, -1 + widget.last = [] widget.polygon_start = True widget.undo_times -= 1#destroy the undo screen of polygon start widget.enableUndo(widget) widget.queue_draw() - + def adjust(self, widget, coords, locked=False): + width, height = widget.window.get_size() + if widget.oldx > int(coords[0]): + xi = int(coords[0]) + xf = widget.oldx + else: + xi = widget.oldx + xf = int(coords[0]) + + if widget.oldy > int(coords[1]): + yi = int(coords[1]) + yf = widget.oldy + else: + yi = widget.oldy + yf = int(coords[1]) + + if locked == True: + if xi < 0: + xi = 0 + if yi < 0: + yi = 0 + if xf > width: + xf = width + if yf > height: + yf = height + + dx = xf-xi + dy = yf-yi + return xi, yi, dx, dy + diff --git a/NEWS b/NEWS index 866b603..42a6721 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,8 @@ +* Journal is now used to import images - using Sugar's ObjectChooser (alexandre) * Drawing area now fits usable area (alexandre) +* Fixed bug in "Insert Image" (andre) +* Added rotate (andre) +* Now effects can be used in selection (andre) 11 diff --git a/OficinaActivity.py b/OficinaActivity.py index a77381d..bd8410a 100644 --- a/OficinaActivity.py +++ b/OficinaActivity.py @@ -65,7 +65,7 @@ from Area import Area import logging class OficinaActivity(activity.Activity): - + def __init__(self, handle): """Initialize the OficinaActivity object. @@ -144,6 +144,7 @@ class OficinaActivity(activity.Activity): logging.debug('writting file %s', file_path) width, height = self.area.window.get_size() + self.area.getout() pixbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8, width, height) pixbuf.get_from_drawable(self.area.pixmap, gtk.gdk.colormap_get_system(), 0, 0, 0, 0, -1, -1) self.metadata['mime_type'] = 'image/png' diff --git a/toolbox.py b/toolbox.py index cbe3daf..f0c66f7 100644 --- a/toolbox.py +++ b/toolbox.py @@ -63,6 +63,7 @@ from sugar.graphics.toggletoolbutton import ToggleToolButton from sugar.graphics.combobox import ComboBox from sugar.graphics.palette import Palette from sugar.graphics.menuitem import MenuItem +from sugar.graphics.objectchooser import ObjectChooser ##Create toolbars for the activity class Toolbox(ActivityToolbox): @@ -136,7 +137,7 @@ class DrawEditToolbar(EditToolbar): self._activity.area.connect('undo', self._on_signal_undo_cb) self._activity.area.connect('redo', self._on_signal_redo_cb) - self._activity.area.connect('selected', self._on_signal_copy_cb) + self._activity.area.connect('select', self._on_signal_select_cb) self._activity.area.connect('action-saved', self._on_signal_action_saved_cb) @@ -150,7 +151,7 @@ class DrawEditToolbar(EditToolbar): self._activity.area.copy() def _paste_cb(self, widget, data=None): - self._activity.area.past() + self._activity.area.past(self._activity.area) def _on_signal_undo_cb(self, widget, data=None): self._verify_sensitive_buttons() @@ -158,7 +159,7 @@ class DrawEditToolbar(EditToolbar): def _on_signal_redo_cb(self, widget, data=None): self._verify_sensitive_buttons() - def _on_signal_copy_cb(self, widget, data=None): + def _on_signal_select_cb(self, widget, data=None): self._verify_sensitive_buttons() def _on_signal_action_saved_cb(self, widget, data=None): @@ -390,6 +391,10 @@ class ToolsToolbar(gtk.Toolbar): palette = widget.get_palette() + content_box = gtk.VBox() + content_box.show() + palette.set_content(content_box) + if tool is None: raise TypeError @@ -402,9 +407,6 @@ class ToolsToolbar(gtk.Toolbar): size_spinbutton = gtk.SpinButton() size_spinbutton.show() - black = gtk.gdk.Color(0,0,0) - size_spinbutton.modify_text(gtk.STATE_NORMAL, black) - # This is where we set restrictions for size: # Initial value, minimum value, maximum value, step adj = gtk.Adjustment(tool['line size'], 1.0, 100.0, 1.0) @@ -415,8 +417,15 @@ class ToolsToolbar(gtk.Toolbar): label = gtk.Label(_('Size: ')) label.show() - palette.action_bar.pack_start(label) - palette.action_bar.pack_start(size_spinbutton) + # Palette's action_bar should pack buttons only + #palette.action_bar.pack_start(label) + #palette.action_bar.pack_start(size_spinbutton) + hbox = gtk.HBox() + hbox.show() + content_box.pack_start(hbox) + + hbox.pack_start(label) + hbox.pack_start(size_spinbutton) size_spinbutton.connect('value-changed', self._on_value_changed, tool) @@ -455,13 +464,14 @@ class ToolsToolbar(gtk.Toolbar): vbox.pack_start(item1) vbox.pack_start(item2) - palette.set_content(vbox) + #palette.set_content(vbox) + content_box.pack_start(vbox) - separator = gtk.HSeparator() - vbox.pack_end(separator) - separator.show() + #separator = gtk.HSeparator() + #vbox.pack_end(separator) + #separator.show() - # User is able to fill or not a polygon, and its fill color + # User is able to fill or not a polygon, and choose its fill color if tool['name'] is self._TOOL_POLYGON['name']: # Creating a CheckButton named "Fill". fill_checkbutton = gtk.CheckButton(_('Fill')) @@ -470,7 +480,8 @@ class ToolsToolbar(gtk.Toolbar): fill_checkbutton.connect('toggled', self._on_fill_checkbutton_toggled, widget, self._TOOL_POLYGON) - palette.set_content(fill_checkbutton) + #palette.set_content(fill_checkbutton) + palette.action_bar.pack_start(fill_checkbutton) # Creating Fill Color Button hbox = gtk.HBox() @@ -487,7 +498,7 @@ class ToolsToolbar(gtk.Toolbar): #palette.action_bar.pack_start(label) #palette.action_bar.pack_start(colorbutton) - palette.set_content(hbox) + content_box.pack_start(hbox) colorbutton.connect_after('color-set', self._on_color_set, self._TOOL_POLYGON) @@ -582,7 +593,7 @@ class ButtonFillColor(gtk.ColorButton): def set_fill_color(self, color): new_color = self.alloc_color(color) - self._activity.area._set_fill_color(new_color) + self._activity.area.set_fill_color(new_color) ##Class to manage the Stroke Color of a Button class ButtonStrokeColor(gtk.ColorButton): @@ -603,7 +614,7 @@ class ButtonStrokeColor(gtk.ColorButton): def set_stroke_color(self, color): new_color = self.alloc_color(color) - self._activity.area._set_stroke_color(new_color) + self._activity.area.set_stroke_color(new_color) ##Make the Shapes Toolbar class ShapesToolbar(gtk.Toolbar): @@ -927,9 +938,6 @@ class ShapesToolbar(gtk.Toolbar): spin = gtk.SpinButton() spin.show() - # When inserted in a Palette, a spinbutton does not display text in black - black = gtk.gdk.Color(0,0,0) - spin.modify_text(gtk.STATE_NORMAL, black) # This is where we set restrictions for sides in Regular Polygon: # Initial value, minimum value, maximum value, step @@ -945,9 +953,10 @@ class ShapesToolbar(gtk.Toolbar): hbox.pack_start(label) hbox.pack_start(spin) + # changing layout due to problems with palette's action_bar #palette.action_bar.pack_start(label) #palette.action_bar.pack_start(spin) - palette.set_content(hbox) + palette.content_box.pack_start(hbox) spin.connect('value-changed', self._on_vertices_value_changed, self._SHAPE_POLYGON) @@ -976,9 +985,6 @@ class ShapesToolbar(gtk.Toolbar): spin = gtk.SpinButton() spin.show() - # When inserted in a Palette, a spinbutton does not display text in black - black = gtk.gdk.Color(0,0,0) - spin.modify_text(gtk.STATE_NORMAL, black) # This is where we set restrictions for Star: # Initial value, minimum value, maximum value, step @@ -994,9 +1000,10 @@ class ShapesToolbar(gtk.Toolbar): hbox.pack_start(label) hbox.pack_start(spin) + # changing layout due to problems with palette's action_bar #palette.action_bar.pack_start(label) #palette.action_bar.pack_start(spin) - palette.set_content(hbox) + palette.content_box.pack_start(hbox) spin.connect('value-changed', self._on_vertices_value_changed, self._SHAPE_STAR) @@ -1026,15 +1033,12 @@ class ShapesToolbar(gtk.Toolbar): fill_checkbutton.connect('toggled', self._on_fill_checkbutton_toggled, tool) - palette.set_content(fill_checkbutton) + #palette.set_content(fill_checkbutton) + palette.action_bar.pack_start(fill_checkbutton) size_spinbutton = gtk.SpinButton() size_spinbutton.show() - # When inserted in a Palette, a spinbutton does not display text in black - black = gtk.gdk.Color(0,0,0) - size_spinbutton.modify_text(gtk.STATE_NORMAL, black) - # This is where we set restrictions for size: # Initial value, minimum value, maximum value, step adj = gtk.Adjustment(tool['line size'], 1.0, 100.0, 1.0) @@ -1045,20 +1049,23 @@ class ShapesToolbar(gtk.Toolbar): label = gtk.Label(_('Size: ')) label.show() - palette.action_bar.pack_start(label) - palette.action_bar.pack_start(size_spinbutton) + #palette.action_bar.pack_start(label) + #palette.action_bar.pack_start(size_spinbutton) + hbox = gtk.HBox() + hbox.show() + hbox.pack_start(label) + hbox.pack_start(size_spinbutton) + + # Creating a public content box + # palette's action_bar should pack only buttons; changing layout + palette.content_box = gtk.VBox() + palette.content_box.show() + palette.set_content(palette.content_box) + + palette.content_box.pack_start(hbox) size_spinbutton.connect('value-changed', self._on_line_size_value_changed, tool) -# def _on_fill_checkbutton_map(self, checkbutton, data=None): -# """ -# Update checkbutton condition to agree with Area.Area object; this prevents tools to have fill checked but be drawed not filled. -# -# @param self -- gtk.Toolbar -# @param checkbutton -# @param data -# """ -# self._activity.area.fill = checkbutton.get_active() def _configure_palette_shape_line(self): logging.debug('Creating palette to shape line') @@ -1151,6 +1158,7 @@ class ImageToolbar(gtk.Toolbar): ##The Constructor def __init__(self, activity): gtk.Toolbar.__init__(self) + self._activity = activity self._object_insert = ToolButton('object-insert') self.insert(self._object_insert, -1) @@ -1164,19 +1172,18 @@ class ImageToolbar(gtk.Toolbar): self.width_percent = 1. self.height_percent = 1. - - """ + self._object_rotate_left = ToolButton('object-rotate-left') self.insert(self._object_rotate_left, -1) self._object_rotate_left.show() self._object_rotate_left.set_tooltip(_('Rotate Left')) + self._object_rotate_left.set_sensitive( self._activity.area.is_selected() ) self._object_rotate_right = ToolButton('object-rotate-right') self.insert(self._object_rotate_right, -1) self._object_rotate_right.show() self._object_rotate_right.set_tooltip(_('Rotate Right')) - - """ + self._object_rotate_right.set_sensitive( self._activity.area.is_selected() ) self._object_height = ToolButton('object-height') self.insert(self._object_height, -1) @@ -1202,27 +1209,32 @@ class ImageToolbar(gtk.Toolbar): self.insert(item, -1) item.show() -# self._object_height.connect('clicked', self.resize, activity, 'object-height', self._OBJECT_HEIGHT) - self._object_insert.connect('clicked', self.insertImage, activity) - #self._object_rotate_left.connect('clicked', self.rotate_left, activity) - #self._object_rotate_right.connect('clicked', set_tool, activity, 'object-rotate-right', self._OBJECT_ROTATE_RIGHT) -# self._object_width.connect('clicked', self.resize, activity, 'object-width', self._OBJECT_WIDTH) + self._object_rotate_left.connect('clicked', self.rotate_left, activity) + self._object_rotate_right.connect('clicked', self.rotate_right, activity) + + self._activity.area.connect('select', self._on_signal_select_cb) def _selected(self, widget, spin, activity): if not activity.area.is_selected(): spin.set_value(100) self.width_percent = 1. self.height_percent = 1. - try: - del(activity.area.d.resize_pixbuf) - del(activity.area.d.resized) - except: pass + + # get active only if something is selected + spin.set_sensitive( self._activity.area.is_selected() ) + + #try: + #del(activity.area.d.resize_pixbuf) + #del(activity.area.d.resized) + #except: pass def rotate_left(self, widget, activity): - #activity.area._rotate_left(widget) - pass - + activity.area._rotate_left(activity.area) + + def rotate_right(self, widget, activity): + activity.area._rotate_right(activity.area) + def resize(self, spinButton, tool, activity): if activity.area.tool['name'] == 'marquee-rectangular' and activity.area.selmove: if tool == "object-height": @@ -1252,34 +1264,57 @@ class ImageToolbar(gtk.Toolbar): spin.set_adjustment(adj) spin.set_numeric(True) + spin.set_sensitive( self._activity.area.is_selected() ) + spin.connect('value-changed', self.resize, tool, activity) - activity.area.connect('selected', self._selected, spin, activity) + activity.area.connect('select', self._selected, spin, activity) return spin def insertImage(self, widget, activity): + # FIXME: this should be a ObjectChooser # TODO: add a filter to display images only. - dialog = gtk.FileChooserDialog(title=(_('Open File...')), - action=gtk.FILE_CHOOSER_ACTION_OPEN, - buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, - gtk.STOCK_OK, gtk.RESPONSE_OK)) - dialog.show_all() - - logging.debug('Importing image from file') - response = dialog.run() - - if response == gtk.RESPONSE_OK: - file_path = dialog.get_filename() - logging.debug('file selected') - logging.debug(file_path) - #file_path = decode_path((file_path,))[0] - #open(activity, file_path) - activity.area.loadImage(file_path,widget,True) - elif response == gtk.RESPONSE_CANCEL: - logging.debug('Closed, no files selected') + #dialog = gtk.FileChooserDialog(title=(_('Open File...')), + #action=gtk.FILE_CHOOSER_ACTION_OPEN, + #buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, + #gtk.STOCK_OK, gtk.RESPONSE_OK)) + #dialog.show_all() + + #logging.debug('Importing image from file') + #response = dialog.run() + + #if response == gtk.RESPONSE_OK: + #file_path = dialog.get_filename() + #logging.debug('file selected') + #logging.debug(file_path) + ##file_path = decode_path((file_path,))[0] + ##open(activity, file_path) + #activity.area.loadImage(file_path,widget,True) + #elif response == gtk.RESPONSE_CANCEL: + #logging.debug('Closed, no files selected') - dialog.destroy() - + #dialog.destroy() + + chooser = ObjectChooser(_('Choose image'), self._activity, + gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT) + try: + result = chooser.run() + if result == gtk.RESPONSE_ACCEPT: + logging.debug('ObjectChooser: %r' % chooser.get_selected_object()) + jobject = chooser.get_selected_object() + if jobject and jobject.file_path: + self._activity.area.loadImage(jobject.file_path) + finally: + chooser.destroy() + del chooser + + def _on_signal_select_cb(self, widget, data=None): + self._verify_sensitive_buttons() + + def _verify_sensitive_buttons(self): + self._object_rotate_right.set_sensitive( self._activity.area.is_selected() ) + self._object_rotate_left.set_sensitive( self._activity.area.is_selected() ) + ##Make the Effects Tools Toolbar class EffectsToolbar(gtk.Toolbar): @@ -1302,7 +1337,7 @@ class EffectsToolbar(gtk.Toolbar): gtk.Toolbar.__init__(self) self._activity = activity - + self._effect_grayscale = ToolButton('effect-grayscale') self.insert(self._effect_grayscale, -1) @@ -1314,12 +1349,12 @@ class EffectsToolbar(gtk.Toolbar): self._effect_rainbow.show() self._effect_rainbow.set_tooltip(_('Rainbow')) self._configure_palette(self._effect_rainbow, self._EFFECT_RAINBOW) - + separator = gtk.SeparatorToolItem() self.insert(separator, -1) separator.show() - """ + """ #FIXME: Must be implemented self._black_and_white = ToolButton('black_and_white') self.insert(self._black_and_white, -1) @@ -1338,7 +1373,7 @@ class EffectsToolbar(gtk.Toolbar): self._effect_rainbow.connect('clicked', self.rainbow) ##Make the colors be in grayscale - def grayscale(self, widget): + def grayscale(self, widget): self._activity.area.grayscale(widget) ##Like the brush, but change it color when painting @@ -1367,9 +1402,6 @@ class EffectsToolbar(gtk.Toolbar): size_spinbutton = gtk.SpinButton() size_spinbutton.show() - black = gtk.gdk.Color(0,0,0) - size_spinbutton.modify_text(gtk.STATE_NORMAL, black) - # This is where we set restrictions for Rainbow: # Initial value, minimum value, maximum value, step adj = gtk.Adjustment(tool['line size'], 1.0, 100.0, 1.0) -- cgit v0.9.1