From b66d0f4fa4230fea32dbee8aedfeb213f75c1cf6 Mon Sep 17 00:00:00 2001 From: Manuel QuiƱones Date: Wed, 20 Apr 2011 20:40:40 +0000 Subject: Brush button shows stamp --- diff --git a/Area.py b/Area.py index 18984eb..9081fa7 100644 --- a/Area.py +++ b/Area.py @@ -630,7 +630,7 @@ class Area(gtk.DrawingArea): self.d.heart(widget, coords, False, self.tool['fill']) self.enableUndo(widget) - if self.tool['name'] in ['brush', 'eraser', 'rainbow', 'pencil']: + if self.tool['name'] in ['brush', 'eraser', 'stamp', 'rainbow', 'pencil']: self.last = [] widget.queue_draw() self.enableUndo(widget) @@ -651,6 +651,44 @@ class Area(gtk.DrawingArea): widget.queue_draw_area(self.x_cursor - size, self.y_cursor - size, size * 2, size * 2) + def setupStamp(self): + """Prepare for stamping from the selected area. + + @param self -- the Area object (GtkDrawingArea) + """ + logging.debug('Area.setupStamp(self)') + + if self.is_selected(): + # Change stamp, get it from selection: + width, height = self.pixmap_sel.get_size() + self.pixbuf_stamp = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, + 8, width, height) + self.pixbuf_stamp.get_from_drawable(self.pixmap_sel, + gtk.gdk.colormap_get_system(), 0, 0, 0, 0, width, height) + self.stamp_size = 0 + + self.resizeStamp(self.tool['line size']) + return self.pixbuf_stamp + + def resizeStamp(self, size): + """Change stamping pixbuffer from the given size. + + @param self -- the Area object (GtkDrawingArea) + """ + try: + self.pixbuf_stamp + except: + logging.error('Area.resizeStamp(self) needs Area.setupStamp called first.') + return + + # Resize stamp to fit brush size as the width: + if self.stamp_size != size: + self.stamp_size = size + w = self.pixbuf_stamp.get_width() + h = self.pixbuf_stamp.get_height() + wr, hr = size, int(size * h * 1.0 / w) + self.resized_stamp = self.pixbuf_stamp.scale_simple(wr, hr, gtk.gdk.INTERP_HYPER) + def undo(self): """Undo the last drawing change. @@ -1256,7 +1294,8 @@ class Area(gtk.DrawingArea): cursors = {'pencil': 'pencil', 'brush': 'paintbrush', 'eraser': 'eraser', - 'bucket': 'paint-bucket'} + 'bucket': 'paint-bucket', + 'stamp': 'pencil'} display = gtk.gdk.display_get_default() if self.tool['name'] in cursors: diff --git a/Desenho.py b/Desenho.py index 1c04e6f..a530316 100644 --- a/Desenho.py +++ b/Desenho.py @@ -139,7 +139,7 @@ class Desenho: """ widget.desenha = False - self._trace(widget, widget.gc_brush, coords, last, size, 'stamp') + self._trace(widget, widget.gc_brush, coords, last, size, stamping=True) def rainbow(self, widget, coords, last, color, size=5, shape='circle'): """Paint with rainbow. @@ -173,61 +173,43 @@ class Desenho: widget.desenha = False self._trace(widget, widget.gc_rainbow, coords, last, size, shape) - def _trace(self, widget, gc, coords, last, size, shape): - if shape == 'circle': - widget.pixmap.draw_arc(gc, True, - coords[0] - size / 2, coords[1] - size / 2, - size, size, 0, 360 * 64) - if last: - gc.set_line_attributes(size, gtk.gdk.LINE_SOLID, - gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND) - widget.pixmap.draw_line(gc, - last[0], last[1], coords[0], coords[1]) - gc.set_line_attributes(0, gtk.gdk.LINE_SOLID, - gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND) + def _trace(self, widget, gc, coords, last, size, shape='circle', stamping=False): - elif shape == 'square': - widget.pixmap.draw_rectangle(gc, True, - coords[0] - size / 2, coords[1] - size / 2, size, size) - if last: - points = [(last[0] - size / 2, last[1] - size / 2), - (coords[0] - size / 2, coords[1] - size / 2), - (coords[0] + size / 2, coords[1] + size / 2), - (last[0] + size / 2, last[1] + size / 2)] - widget.pixmap.draw_polygon(gc, True, points) - points = [(last[0] + size / 2, last[1] - size / 2), - (coords[0] + size / 2, coords[1] - size / 2), - (coords[0] - size / 2, coords[1] + size / 2), - (last[0] - size / 2, last[1] + size / 2)] - widget.pixmap.draw_polygon(gc, True, points) - - elif shape == 'stamp': - if widget.is_selected(): - # Change stamp, get it from selection: - width, height = widget.pixmap_sel.get_size() - self.pixbuf_stamp = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, - 8, width, height) - self.pixbuf_stamp.get_from_drawable(widget.pixmap_sel, - gtk.gdk.colormap_get_system(), 0, 0, 0, 0, width, height) - self.stamp_size = 0 + if stamping: + # TODO call this as a signal when size changes + widget.resizeStamp(size) - try: - self.pixbuf_stamp - except: - pass - else: - if self.stamp_size != size: - # Resize stamp to fit brush size as the width: - self.stamp_size = size - w = self.pixbuf_stamp.get_width() - h = self.pixbuf_stamp.get_height() - wr, hr = size, int(size * h * 1.0 / w) - self.resized_stamp = self.pixbuf_stamp.scale_simple(wr, hr, gtk.gdk.INTERP_HYPER) - - width = self.resized_stamp.get_width() - height = self.resized_stamp.get_height() - widget.pixmap.draw_pixbuf(gc, self.resized_stamp, - 0, 0, coords[0] - width / 2, coords[1] - height / 2, width, height) + width = widget.resized_stamp.get_width() + height = widget.resized_stamp.get_height() + widget.pixmap.draw_pixbuf(gc, widget.resized_stamp, + 0, 0, coords[0] - width / 2, coords[1] - height / 2, width, height) + else: + if shape == 'circle': + widget.pixmap.draw_arc(gc, True, + coords[0] - size / 2, coords[1] - size / 2, + size, size, 0, 360 * 64) + if last: + gc.set_line_attributes(size, gtk.gdk.LINE_SOLID, + gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND) + widget.pixmap.draw_line(gc, + last[0], last[1], coords[0], coords[1]) + gc.set_line_attributes(0, gtk.gdk.LINE_SOLID, + gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_ROUND) + + elif shape == 'square': + widget.pixmap.draw_rectangle(gc, True, + coords[0] - size / 2, coords[1] - size / 2, size, size) + if last: + points = [(last[0] - size / 2, last[1] - size / 2), + (coords[0] - size / 2, coords[1] - size / 2), + (coords[0] + size / 2, coords[1] + size / 2), + (last[0] + size / 2, last[1] + size / 2)] + widget.pixmap.draw_polygon(gc, True, points) + points = [(last[0] + size / 2, last[1] - size / 2), + (coords[0] + size / 2, coords[1] - size / 2), + (coords[0] - size / 2, coords[1] + size / 2), + (last[0] - size / 2, last[1] + size / 2)] + widget.pixmap.draw_polygon(gc, True, points) if last: x = min(coords[0], last[0]) diff --git a/toolbox.py b/toolbox.py index c4903e9..d1a4607 100644 --- a/toolbox.py +++ b/toolbox.py @@ -272,7 +272,6 @@ class ToolsToolbarBuilder(): self._tool_stamp = DrawToolButton('tool-bucket', activity.tool_group, _('Stamp')) toolbar.insert(self._tool_stamp, -1) - toolbar._tool_stamp = self._tool_stamp is_selected = self._activity.area.is_selected() self._tool_stamp.set_sensitive(is_selected) @@ -301,7 +300,7 @@ class ToolsToolbarBuilder(): self._TOOL_STAMP_NAME) self._tool_marquee_rectangular.connect('clicked', self.set_tool, self._TOOL_MARQUEE_RECT_NAME) - + def set_tool(self, widget, tool_name): """ Set tool to the Area object. Configures tool's color and size. @@ -311,6 +310,14 @@ class ToolsToolbarBuilder(): necessary in case this method is used in a connect() @param tool_name --The name of the selected tool """ + if tool_name == 'stamp': + pixbuf = self._activity.area.setupStamp() + # Put stamp in ButtonStrokeColor widget: + # TODO use signals? + self._stroke_color.color_button._pixbuf_stamp = pixbuf + self._stroke_color.color_button.set_stamping(True) + else: + self._stroke_color.color_button.set_stamping(False) self.properties['name'] = tool_name self._activity.area.set_tool(self.properties) diff --git a/widgets.py b/widgets.py index 832649b..32734fa 100644 --- a/widgets.py +++ b/widgets.py @@ -29,6 +29,8 @@ class BrushButton(_ColorButton): self._accept_drag = True self._brush_size = 2 self._brush_shape = 'circle' + self._stamping = False + self._pixbuf_stamp = None self._preview = gtk.DrawingArea() self._preview.set_size_request(style.STANDARD_ICON_SIZE, style.STANDARD_ICON_SIZE) @@ -82,7 +84,12 @@ class BrushButton(_ColorButton): # receive gtk.gdk.Color self._color = color self._preview.queue_draw() - + + def set_stamping(self, stamping): + # receive True or False + self._stamping = stamping + self._preview.queue_draw() + def expose(self, widget, event): if self._gc is None: self._setup() @@ -92,18 +99,32 @@ class BrushButton(_ColorButton): self.pixmap.draw_rectangle(self._preview.get_style().white_gc, True, 0, 0, style.STANDARD_ICON_SIZE, style.STANDARD_ICON_SIZE) self._gc.set_foreground(self._color) - - if(self._brush_shape == 'circle'): - self.pixmap.draw_arc(self._gc, True, - center - self._brush_size / 2, - center - self._brush_size / 2, - self._brush_size, self._brush_size, 0, 360 * 64) - if(self._brush_shape == 'square'): - self.pixmap.draw_rectangle(self._gc, True, - center - self._brush_size / 2, - center - self._brush_size / 2, - self._brush_size, self._brush_size) - + + if self._stamping: + size = self._brush_size + w = self._pixbuf_stamp.get_width() + h = self._pixbuf_stamp.get_height() + wr, hr = size, int(size * h * 1.0 / w) + resized_stamp = self._pixbuf_stamp.scale_simple(wr, hr, gtk.gdk.INTERP_HYPER) + + width = resized_stamp.get_width() + height = resized_stamp.get_height() + self.pixmap.draw_pixbuf(self._gc, resized_stamp, + 0, 0, center - width / 2, center - height / 2, width, height) + + else: + if self._brush_shape == 'circle': + self.pixmap.draw_arc(self._gc, True, + center - self._brush_size / 2, + center - self._brush_size / 2, + self._brush_size, self._brush_size, 0, 360 * 64) + + elif self._brush_shape == 'square': + self.pixmap.draw_rectangle(self._gc, True, + center - self._brush_size / 2, + center - self._brush_size / 2, + self._brush_size, self._brush_size) + area = event.area widget.window.draw_drawable(self._gc, self.pixmap, area[0], area[1], area[0], area[1], area[2], area[3]) -- cgit v0.9.1