Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/widgets.py
diff options
context:
space:
mode:
authorGonzalo Odiard <godiard@gmail.com>2011-05-03 18:29:08 (GMT)
committer Gonzalo Odiard <godiard@gmail.com>2011-05-03 18:29:08 (GMT)
commit44ce7d95c33fc76078d88fc43e9c4453ca6522e9 (patch)
tree0974e2d8fe36e5c992e94f0e4fad4621fdf1e9a3 /widgets.py
parent149d8ceb9bfd288c2ccdcff5f787305dc7332275 (diff)
Implementation of Stamp functionality
The user can select a part of the image to use it like a stamp. When the stamp is selected, can change the size, and use it to draw. Signed-of: manuel quiƱones <manuel.por.aca@gmail.com> Reviewed-by: Gonzalo Odiard <gonzalo@laptop.org>
Diffstat (limited to 'widgets.py')
-rw-r--r--widgets.py123
1 files changed, 98 insertions, 25 deletions
diff --git a/widgets.py b/widgets.py
index 832649b..7c23683 100644
--- a/widgets.py
+++ b/widgets.py
@@ -28,7 +28,9 @@ class BrushButton(_ColorButton):
self._palette = None
self._accept_drag = True
self._brush_size = 2
+ self._stamp_size = 20
self._brush_shape = 'circle'
+ self._resized_stamp = None
self._preview = gtk.DrawingArea()
self._preview.set_size_request(style.STANDARD_ICON_SIZE,
style.STANDARD_ICON_SIZE)
@@ -83,6 +85,26 @@ class BrushButton(_ColorButton):
self._color = color
self._preview.queue_draw()
+ def get_stamp_size(self):
+ return self._stamp_size
+
+ def set_stamp_size(self, stamp_size):
+ self._stamp_size = stamp_size
+ self._preview.queue_draw()
+
+ stamp_size = gobject.property(type=int, getter=get_stamp_size,
+ setter=set_stamp_size)
+
+ def set_resized_stamp(self, resized_stamp):
+ self._resized_stamp = resized_stamp
+
+ def stop_stamping(self):
+ self._resized_stamp = None
+ self._preview.queue_draw()
+
+ def is_stamping(self):
+ return self._resized_stamp != None
+
def expose(self, widget, event):
if self._gc is None:
self._setup()
@@ -93,16 +115,26 @@ class BrushButton(_ColorButton):
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.is_stamping():
+ width = self._resized_stamp.get_width()
+ height = self._resized_stamp.get_height()
+ dx = center - width / 2
+ dy = center - height / 2
+ self.pixmap.draw_pixbuf(self._gc, self._resized_stamp,
+ 0, 0, dx, dy, 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,
@@ -157,6 +189,7 @@ class ButtonStrokeColor(gtk.ToolItem):
self.add(self.color_button)
self.color_button.set_brush_size(2)
self.color_button.set_brush_shape('circle')
+ self.color_button.set_stamp_size(20)
# The following is so that the behaviour on the toolbar is correct.
self.color_button.set_relief(gtk.RELIEF_NONE)
@@ -171,6 +204,8 @@ class ButtonStrokeColor(gtk.ToolItem):
self.color_button.connect('can-activate-accel',
self.__button_can_activate_accel_cb)
+ self.create_palette()
+
def __button_can_activate_accel_cb(self, button, signal_id):
# Accept activation via accelerators regardless of this widget's state
return True
@@ -193,20 +228,22 @@ class ButtonStrokeColor(gtk.ToolItem):
color_palette_hbox = self._palette._picker_hbox
content_box = gtk.VBox()
- size_spinbutton = gtk.SpinButton()
+ self.size_spinbutton = gtk.SpinButton()
# This is where we set restrictions for size:
# Initial value, minimum value, maximum value, step
adj = gtk.Adjustment(self.properties['line size'], 1.0, 100.0, 1.0)
- size_spinbutton.set_adjustment(adj)
- size_spinbutton.set_numeric(True)
+ self.size_spinbutton.set_adjustment(adj)
+ self.size_spinbutton.set_numeric(True)
label = gtk.Label(_('Size: '))
- hbox = gtk.HBox()
- content_box.pack_start(hbox)
+ hbox_size = gtk.HBox()
+ self.vbox_brush_options = gtk.VBox()
+ content_box.pack_start(hbox_size)
+ content_box.pack_start(self.vbox_brush_options)
- hbox.pack_start(label)
- hbox.pack_start(size_spinbutton)
- size_spinbutton.connect('value-changed', self._on_value_changed)
+ hbox_size.pack_start(label)
+ hbox_size.pack_start(self.size_spinbutton)
+ self.size_spinbutton.connect('value-changed', self._on_value_changed)
# User is able to choose Shapes for 'Brush' and 'Eraser'
item1 = gtk.RadioButton(None, _('Circle'))
@@ -233,37 +270,73 @@ class ButtonStrokeColor(gtk.ToolItem):
label = gtk.Label(_('Shape'))
- content_box.pack_start(label)
- content_box.pack_start(item1)
- content_box.pack_start(item2)
+ self.vbox_brush_options.pack_start(label)
+ self.vbox_brush_options.pack_start(item1)
+ self.vbox_brush_options.pack_start(item2)
keep_aspect_checkbutton = gtk.CheckButton(_('Keep aspect'))
ratio = self._activity.area.keep_aspect_ratio
keep_aspect_checkbutton.set_active(ratio)
keep_aspect_checkbutton.connect('toggled',
self._keep_aspect_checkbutton_toggled)
- content_box.pack_start(keep_aspect_checkbutton)
+ self.vbox_brush_options.pack_start(keep_aspect_checkbutton)
color_palette_hbox.pack_start(gtk.VSeparator(),
padding=style.DEFAULT_SPACING)
color_palette_hbox.pack_start(content_box)
color_palette_hbox.show_all()
+ self._update_palette()
return self._palette
def _keep_aspect_checkbutton_toggled(self, checkbutton):
self._activity.area.keep_aspect_ratio = checkbutton.get_active()
+ def _update_palette(self):
+ palette_children = self._palette._picker_hbox.get_children()
+ if self.color_button.is_stamping():
+ # Hide palette color widgets:
+ for ch in palette_children[:4]:
+ ch.hide_all()
+ # Hide brush options:
+ self.vbox_brush_options.hide_all()
+ # Change title:
+ self.set_title(_('Stamp properties'))
+ else:
+ # Show palette color widgets:
+ for ch in palette_children[:4]:
+ ch.show_all()
+ # Show brush options:
+ self.vbox_brush_options.show_all()
+ # Change title:
+ self.set_title(_('Brush properties'))
+
+ self._palette._picker_hbox.resize_children()
+ self._palette._picker_hbox.queue_draw()
+
+ def update_stamping(self):
+ if self.color_button.is_stamping():
+ self.size_spinbutton.set_value(self.color_button.stamp_size)
+ else:
+ self.size_spinbutton.set_value(self.color_button.brush_size)
+ self._update_palette()
+
def _on_value_changed(self, spinbutton):
size = spinbutton.get_value_as_int()
- self.properties['line size'] = size
+ if self.color_button.is_stamping():
+ self.properties['stamp size'] = size
+ resized_stamp = self._activity.area.resize_stamp(size)
+ self.color_button.set_resized_stamp(resized_stamp)
+ self.color_button.set_stamp_size(self.properties['stamp size'])
+ else:
+ self.properties['line size'] = size
+ self.color_button.set_brush_size(self.properties['line size'])
self._activity.area.set_tool(self.properties)
- self.color_button.set_brush_size(self.properties['line size'])
def _on_toggled(self, radiobutton, tool, shape):
if radiobutton.get_active():
self.properties['line shape'] = shape
self.color_button.set_brush_shape(shape)
- self.color_button.set_brush_size(self.properties['line size'])
+ self.color_button.set_brush_size(self.properties['line size'])
def get_palette_invoker(self):
return self._palette_invoker