diff options
-rw-r--r-- | Area.py | 71 | ||||
-rw-r--r-- | icons/invert-colors.svg | 387 | ||||
-rw-r--r-- | toolbox.py | 23 |
3 files changed, 459 insertions, 22 deletions
@@ -69,10 +69,12 @@ import os import tempfile import math import pango +import numpy from fill import * from Desenho import Desenho from urlparse import urlparse + ##Tools and events manipulation are handle with this class. TARGET_URI = 0 @@ -80,7 +82,6 @@ TARGET_URI = 0 class Area(gtk.DrawingArea): - __gsignals__ = { 'undo': (gobject.SIGNAL_ACTION, gobject.TYPE_NONE, ([])), 'redo': (gobject.SIGNAL_ACTION, gobject.TYPE_NONE, ([])), @@ -227,7 +228,7 @@ class Area(gtk.DrawingArea): self.gc = win.new_gc() self.gc_eraser = win.new_gc() colormap = self.get_colormap() - self.white = colormap.alloc_color('#ffffff', True, True) # white + self.white = colormap.alloc_color('#ffffff', True, True) # white self.black = colormap.alloc_color('#000000', True, True) # black self.gc_eraser.set_foreground(self.white) @@ -555,7 +556,7 @@ class Area(gtk.DrawingArea): self.selmove = True self.sel_get_out = False self.emit('select') - elif self.sel_get_out: #get out of the func selection + elif self.sel_get_out: # get out of the func selection self.getout() try: del(self.d.pixbuf_resize) @@ -648,7 +649,7 @@ class Area(gtk.DrawingArea): if self.undo_times > 0: self.undo_times -= 1 self.redo_times += 1 - try: #to not try paint someting wrong + try: # to not try paint someting wrong self.pixmap.draw_drawable(self.gc, self.undo_list[self.undo_times], 0, 0, 0, 0, width, height) except: @@ -663,7 +664,7 @@ class Area(gtk.DrawingArea): #special case for func polygon if self.tool['name'] == 'freeform': - self.polygon_start = True #start the polygon again + self.polygon_start = True # start the polygon again self.emit('undo') @@ -680,7 +681,7 @@ class Area(gtk.DrawingArea): self.redo_times -= 1 self.undo_times += 1 - try: #to not try paint someting wrong + try: # to not try paint someting wrong self.pixmap.draw_drawable(self.gc, self.undo_list[self.undo_times], 0, 0, 0, 0, width, height) @@ -705,11 +706,11 @@ class Area(gtk.DrawingArea): if self.undo_surf: self.undo_times += 1 - self.undo_list.append(None)#alloc memory + self.undo_list.append(None) # alloc memory self.undo_list[self.undo_times] = gtk.gdk.Pixmap(widget.window, - width, height, -1) #define type + 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 + 0, 0, 0, 0, width, height) # copy workarea self.undo_times += 1 self.redo_times = 0 self.first_undo = True @@ -915,6 +916,56 @@ class Area(gtk.DrawingArea): if not self.selmove: self.enableUndo(widget) + def invert_colors(self, widget): + """Apply invert effect. + + @param self -- the Area object (GtkDrawingArea) + @param widget -- the Area object (GtkDrawingArea) + + """ + + width, height = self.window.get_size() + + 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) + + pix_manip2 = pix.get_pixels_array() + pix_manip = numpy.ones(pix_manip2.shape, dtype=numpy.uint8) * 255 + pix_manip2 = pix_manip - pix_manip2 + pix = gtk.gdk.pixbuf_new_from_array(pix_manip2, gtk.gdk.COLORSPACE_RGB, + 8) + + 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() + if not self.selmove: + self.enableUndo(widget) + def _pixbuf2Image(self, pb): """change a pixbuf to RGB image @@ -1274,7 +1325,7 @@ class Area(gtk.DrawingArea): self.orig_x = 0 self.orig_y = 0 self.pixmap_temp.draw_rectangle(self.gc_selection, False, - 0, 0, width-1, height-1) + 0, 0, width - 1, height - 1) self.selmove = True self.sel_get_out = False self.emit('select') diff --git a/icons/invert-colors.svg b/icons/invert-colors.svg new file mode 100644 index 0000000..373ca70 --- /dev/null +++ b/icons/invert-colors.svg @@ -0,0 +1,387 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:osb="http://www.openswatchbook.org/uri/2009/osb" + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + enable-background="new 0 0 55 55" + height="55px" + version="1.1" + viewBox="0 0 55 55" + width="55px" + x="0px" + xml:space="preserve" + y="0px" + id="svg2" + inkscape:version="0.48.0 r9654" + sodipodi:docname="invert-colors.svg"><metadata + id="metadata50"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs + id="defs48"><inkscape:path-effect + effect="skeletal" + id="path-effect5822" + is_visible="true" + pattern="M 0,0 0,10 10,5 z" + copytype="single_stretched" + prop_scale="1" + scale_y_rel="false" + spacing="0" + normal_offset="0" + tang_offset="0" + prop_units="false" + vertical_pattern="false" + fuse_tolerance="0" /><inkscape:path-effect + effect="skeletal" + id="path-effect5818" + is_visible="true" + pattern="M 0,0 0,10 10,5 z" + copytype="single_stretched" + prop_scale="1" + scale_y_rel="false" + spacing="0" + normal_offset="0" + tang_offset="0" + prop_units="false" + vertical_pattern="false" + fuse_tolerance="0" /><linearGradient + id="linearGradient5788" + osb:paint="solid"><stop + style="stop-color:#000000;stop-opacity:1;" + offset="0" + id="stop5790" /></linearGradient><linearGradient + gradientTransform="matrix(-4.371139e-8,1,-1,-4.371139e-8,55,-4.882812e-4)" + gradientUnits="userSpaceOnUse" + id="SVGID_1_-0" + x1="8.4995003" + x2="46.5" + y1="27.5" + y2="27.5"><stop + offset="0" + style="stop-color:#FF0000" + id="stop6-4" /><stop + offset="0.0044" + style="stop-color:#FF0500" + id="stop8-8" /><stop + offset="0.0489" + style="stop-color:#FF3000" + id="stop10-7" /><stop + offset="0.092" + style="stop-color:#FF5200" + id="stop12-1" /><stop + offset="0.1326" + style="stop-color:#FF6B00" + id="stop14-7" /><stop + offset="0.1699" + style="stop-color:#FF7A00" + id="stop16-2" /><stop + offset="0.2006" + style="stop-color:#FF7F00" + id="stop18-7" /><stop + offset="0.2506" + style="stop-color:#FF9200" + id="stop20-2" /><stop + offset="0.3497" + style="stop-color:#FFB300" + id="stop22-2" /><stop + offset="0.4042" + style="stop-color:#FFBF00" + id="stop24-6" /><stop + offset="0.4385" + style="stop-color:#E3CA03" + id="stop26-1" /><stop + offset="0.5423" + style="stop-color:#93EB0C" + id="stop28-0" /><stop + offset="0.5898" + style="stop-color:#73F80F" + id="stop30-6" /><stop + offset="0.6159" + style="stop-color:#6AF11D" + id="stop32-1" /><stop + offset="0.6649" + style="stop-color:#54E041" + id="stop34-5" /><stop + offset="0.7315" + style="stop-color:#2FC47B" + id="stop36-9" /><stop + offset="0.8084" + style="stop-color:#00A0C6" + id="stop38-4" /><stop + offset="0.8916" + style="stop-color:#1C64CB" + id="stop40-9" /><stop + offset="1" + style="stop-color:#4210D2" + id="stop42-0" /></linearGradient><linearGradient + gradientTransform="matrix(-4.371139e-8,1,-1,-4.371139e-8,55,-4.882812e-4)" + gradientUnits="userSpaceOnUse" + id="SVGID_1_-0-1" + x1="8.4995003" + x2="46.5" + y1="27.5" + y2="27.5"><stop + offset="0" + style="stop-color:#FF0000" + id="stop6-4-7" /><stop + offset="0.0044" + style="stop-color:#FF0500" + id="stop8-8-5" /><stop + offset="0.0489" + style="stop-color:#FF3000" + id="stop10-7-9" /><stop + offset="0.092" + style="stop-color:#FF5200" + id="stop12-1-6" /><stop + offset="0.1326" + style="stop-color:#FF6B00" + id="stop14-7-2" /><stop + offset="0.1699" + style="stop-color:#FF7A00" + id="stop16-2-1" /><stop + offset="0.2006" + style="stop-color:#FF7F00" + id="stop18-7-7" /><stop + offset="0.2506" + style="stop-color:#FF9200" + id="stop20-2-8" /><stop + offset="0.3497" + style="stop-color:#FFB300" + id="stop22-2-5" /><stop + offset="0.4042" + style="stop-color:#FFBF00" + id="stop24-6-7" /><stop + offset="0.4385" + style="stop-color:#E3CA03" + id="stop26-1-4" /><stop + offset="0.5423" + style="stop-color:#93EB0C" + id="stop28-0-1" /><stop + offset="0.5898" + style="stop-color:#73F80F" + id="stop30-6-8" /><stop + offset="0.6159" + style="stop-color:#6AF11D" + id="stop32-1-5" /><stop + offset="0.6649" + style="stop-color:#54E041" + id="stop34-5-9" /><stop + offset="0.7315" + style="stop-color:#2FC47B" + id="stop36-9-7" /><stop + offset="0.8084" + style="stop-color:#00A0C6" + id="stop38-4-5" /><stop + offset="0.8916" + style="stop-color:#1C64CB" + id="stop40-9-3" /><stop + offset="1" + style="stop-color:#4210D2" + id="stop42-0-8" /></linearGradient><linearGradient + y2="27.5" + x2="46.5" + y1="27.5" + x1="8.4995003" + gradientTransform="matrix(-4.371139e-8,1,-1,-4.371139e-8,55,-4.882812e-4)" + gradientUnits="userSpaceOnUse" + id="linearGradient3454" + xlink:href="#SVGID_1_-0-1" + inkscape:collect="always" /><filter + id="filter3547" + inkscape:label="Invert" + x="0" + y="0" + width="1" + height="1" + inkscape:menu="Color" + inkscape:menu-tooltip="Invert colors" + color-interpolation-filters="sRGB"><feColorMatrix + id="feColorMatrix3549" + type="saturate" + values="1" + result="fbSourceGraphic" /><feColorMatrix + id="feColorMatrix3551" + in="fbSourceGraphic" + values="-1 0 0 0 1 0 -1 0 0 1 0 0 -1 0 1 0 0 0 1 0 " /></filter></defs><sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1280" + inkscape:window-height="751" + id="namedview46" + showgrid="false" + inkscape:zoom="9.7454545" + inkscape:cx="8.7733208" + inkscape:cy="27.5" + inkscape:window-x="0" + inkscape:window-y="24" + inkscape:window-maximized="1" + inkscape:current-layer="svg2" /><g + transform="matrix(0.3848602,0,0,0.3848602,7.5641324,7.5767221)" + style="display:block" + display="block" + id="effect-rainbow-9"><linearGradient + gradientTransform="matrix(-4.371139e-8,1,-1,-4.371139e-8,55,-4.882812e-4)" + gradientUnits="userSpaceOnUse" + id="linearGradient3183" + x1="8.4995003" + x2="46.5" + y1="27.5" + y2="27.5"><stop + offset="0" + style="stop-color:#FF0000" + id="stop3185" /><stop + offset="0.0044" + style="stop-color:#FF0500" + id="stop3187" /><stop + offset="0.0489" + style="stop-color:#FF3000" + id="stop3189" /><stop + offset="0.092" + style="stop-color:#FF5200" + id="stop3191" /><stop + offset="0.1326" + style="stop-color:#FF6B00" + id="stop3193" /><stop + offset="0.1699" + style="stop-color:#FF7A00" + id="stop3195" /><stop + offset="0.2006" + style="stop-color:#FF7F00" + id="stop3197" /><stop + offset="0.2506" + style="stop-color:#FF9200" + id="stop3199" /><stop + offset="0.3497" + style="stop-color:#FFB300" + id="stop3201" /><stop + offset="0.4042" + style="stop-color:#FFBF00" + id="stop3203" /><stop + offset="0.4385" + style="stop-color:#E3CA03" + id="stop3205" /><stop + offset="0.5423" + style="stop-color:#93EB0C" + id="stop3207" /><stop + offset="0.5898" + style="stop-color:#73F80F" + id="stop3209" /><stop + offset="0.6159" + style="stop-color:#6AF11D" + id="stop3211" /><stop + offset="0.6649" + style="stop-color:#54E041" + id="stop3213" /><stop + offset="0.7315" + style="stop-color:#2FC47B" + id="stop3215" /><stop + offset="0.8084" + style="stop-color:#00A0C6" + id="stop3217" /><stop + offset="0.8916" + style="stop-color:#1C64CB" + id="stop3219" /><stop + offset="1" + style="stop-color:#4210D2" + id="stop3221" /></linearGradient><rect + style="fill:url(#SVGID_1_-0);stroke:#ffffff;stroke-width:3.5" + height="38" + width="38" + x="8.5" + y="8.5" + id="rect44-1" /></g><g + transform="matrix(0.3848602,0,0,0.3848602,26.242514,26.259729)" + style="display:block;filter:url(#filter3547)" + display="block" + id="effect-rainbow-9-8"><linearGradient + gradientTransform="matrix(-4.371139e-8,1,-1,-4.371139e-8,55,-4.882812e-4)" + gradientUnits="userSpaceOnUse" + id="linearGradient3183-3" + x1="8.4995003" + x2="46.5" + y1="27.5" + y2="27.5"><stop + offset="0" + style="stop-color:#FF0000" + id="stop3185-1" /><stop + offset="0.0044" + style="stop-color:#FF0500" + id="stop3187-8" /><stop + offset="0.0489" + style="stop-color:#FF3000" + id="stop3189-9" /><stop + offset="0.092" + style="stop-color:#FF5200" + id="stop3191-6" /><stop + offset="0.1326" + style="stop-color:#FF6B00" + id="stop3193-4" /><stop + offset="0.1699" + style="stop-color:#FF7A00" + id="stop3195-3" /><stop + offset="0.2006" + style="stop-color:#FF7F00" + id="stop3197-3" /><stop + offset="0.2506" + style="stop-color:#FF9200" + id="stop3199-3" /><stop + offset="0.3497" + style="stop-color:#FFB300" + id="stop3201-8" /><stop + offset="0.4042" + style="stop-color:#FFBF00" + id="stop3203-6" /><stop + offset="0.4385" + style="stop-color:#E3CA03" + id="stop3205-0" /><stop + offset="0.5423" + style="stop-color:#93EB0C" + id="stop3207-4" /><stop + offset="0.5898" + style="stop-color:#73F80F" + id="stop3209-8" /><stop + offset="0.6159" + style="stop-color:#6AF11D" + id="stop3211-8" /><stop + offset="0.6649" + style="stop-color:#54E041" + id="stop3213-8" /><stop + offset="0.7315" + style="stop-color:#2FC47B" + id="stop3215-9" /><stop + offset="0.8084" + style="stop-color:#00A0C6" + id="stop3217-7" /><stop + offset="0.8916" + style="stop-color:#1C64CB" + id="stop3219-7" /><stop + offset="1" + style="stop-color:#4210D2" + id="stop3221-6" /></linearGradient><rect + style="fill:url(#linearGradient3454);stroke:#ffffff;stroke-width:3.5" + height="38" + width="38" + x="8.5" + y="8.5" + id="rect44-1-4" /></g><path + style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:2.011;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:5.30000019;stroke-opacity:1;stroke-dasharray:none" + d="m 29.660555,15.426382 9.395759,0 0,8.300232 0.538129,0 -0.783268,1.678014 -0.856517,-1.67529 0.553319,-0.01848 -0.108147,-7.746052 -8.70531,0 z" + id="path5850" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cccccccccc" /><path + style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:2.011;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" + d="m 25.355629,39.092534 -9.395759,0 0,-8.300232 -0.538129,0 0.783268,-1.678013 0.856517,1.675289 -0.553319,0.01848 0.108147,7.746052 8.70531,0 z" + id="path5850-9" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cccccccccc" /></svg>
\ No newline at end of file @@ -430,7 +430,6 @@ class ToolsToolbar(gtk.Toolbar): except: logging.debug('Could not create palette for tool selection area') - # New connect method # Using dictionnaries to control tool's properties self._tool_pencil.connect('clicked', self.set_tool, self._TOOL_PENCIL) @@ -564,8 +563,6 @@ class ToolsToolbar(gtk.Toolbar): #setting cursor: Moved to Area - - # def _on_fill_checkbutton_map(self, checkbutton, data=None): # """ # Update checkbutton condition to agree with Area.Area object; @@ -809,7 +806,6 @@ class ShapesToolbar(gtk.Toolbar): except: logging.debug('Could not create palette for Shape Triangle') - self._shape_arrow.connect('clicked', self.set_tool, self._SHAPE_ARROW) self._shape_ellipse.connect('clicked', self.set_tool, self._SHAPE_ELLIPSE) @@ -1031,7 +1027,6 @@ class TextToolbar(gtk.Toolbar): separator.set_draw(True) self.insert(separator, -1) - """ #FIXME: this button is not connected to the right callback self._bold = ToggleToolButton('format-text-bold') @@ -1249,6 +1244,7 @@ class ImageToolbar(gtk.Toolbar): class EffectsToolbar(gtk.Toolbar): _EFFECT_GRAYSCALE = 'grayscale' + _INVERT_COLOR = 'invert-colors' # Rainbow acts as a tool in Area, and it has to be described as a dict _EFFECT_RAINBOW = {'name': 'rainbow', 'line size': 10, @@ -1272,6 +1268,11 @@ class EffectsToolbar(gtk.Toolbar): self.insert(self._effect_rainbow, -1) self._configure_palette(self._effect_rainbow, self._EFFECT_RAINBOW) + self._invert_colors = ToolButton('invert-colors') + self.insert(self._invert_colors, -1) + self._invert_colors.show() + self._invert_colors.set_tooltip(_('Invert Colors')) + separator = gtk.SeparatorToolItem() self.insert(separator, -1) @@ -1284,16 +1285,11 @@ class EffectsToolbar(gtk.Toolbar): 'effect-black-and-white') self._black_and_white.set_tooltip(_('Black and White')) - self._invert_colors = ToolButton('invert_colors') - self.insert(self._invert_colors, -1) - self._invert_colors.show() - self._invert_colors.connect('clicked', test_connect, activity, - 'invert-colors') - self._invert_colors.set_tooltip(_('Invert Colors')) - """ + self._effect_grayscale.connect('clicked', self.grayscale) self._effect_rainbow.connect('clicked', self.rainbow) + self._invert_colors.connect('clicked', self.invert_colors) ##Make the colors be in grayscale def grayscale(self, widget): @@ -1303,6 +1299,9 @@ class EffectsToolbar(gtk.Toolbar): def rainbow(self, widget): self._activity.area.set_tool(self._EFFECT_RAINBOW) + def invert_colors(self, widget): + self._activity.area.invert_colors(widget) + # setting cursor: moved to Area def _configure_palette(self, button, tool=None): |