diff options
-rw-r--r-- | Area.py | 40 | ||||
-rw-r--r-- | Desenho.py | 16 | ||||
-rw-r--r-- | activity/activity.info | 2 | ||||
-rw-r--r-- | fontcombobox.py | 65 | ||||
-rw-r--r-- | icons/tool-picker.svg | 48 | ||||
-rw-r--r-- | toolbox.py | 51 |
6 files changed, 171 insertions, 51 deletions
@@ -98,12 +98,12 @@ class Area(gtk.DrawingArea): 'select': (gobject.SIGNAL_ACTION, gobject.TYPE_NONE, ([])), } - def __init__(self, janela): + def __init__(self, activity): """ Initialize the object from class Area which is derived from gtk.DrawingArea. @param self -- the Area object (GtkDrawingArea) - @param janela -- the parent window + @param activity -- the parent window """ gtk.DrawingArea.__init__(self) @@ -175,7 +175,7 @@ class Area(gtk.DrawingArea): self.desenho = [] self.textos = [] self.text_in_progress = False - self.janela = janela + self.activity = activity self.d = Desenho(self) self.last = [] self.rainbow_counter = 0 @@ -336,17 +336,17 @@ class Area(gtk.DrawingArea): elif self.text_in_progress: try: # This works for a gtk.Entry - text = self.janela.textview.get_text() + text = self.activity.textview.get_text() except AttributeError: # This works for a gtk.TextView - buf = self.janela.textview.get_buffer() + buf = self.activity.textview.get_buffer() start, end = buf.get_bounds() text = buf.get_text(start, end) if text is not None: self.d.text(widget, event) self.text_in_progress = False - self.janela.textview.hide() + self.activity.textview.hide() self.oldx, self.oldy = coords @@ -355,6 +355,9 @@ class Area(gtk.DrawingArea): x, y, state = event.window.get_pointer() + if self.tool['name'] == 'picker': + self.pick_color(x, y) + if state & gtk.gdk.BUTTON3_MASK: #Handle with the right button click event. if self.tool['name'] == 'marquee-rectangular': @@ -706,6 +709,22 @@ class Area(gtk.DrawingArea): self.queue_draw() self.window.set_cursor(None) + def pick_color(self, x, y): + gdk_image = self.pixmap.get_image(x, y, 1, 1) + pixel = gdk_image.get_pixel(0, 0) + cmap = gdk_image.get_colormap() + gdk_color = cmap.query_color(pixel) + + # set in the area + pixmap_cmap = self.pixmap.get_colormap() + stroke_color = pixmap_cmap.alloc_color(gdk_color) + self.tool['stroke color'] = stroke_color + self.set_stroke_color(self.tool['stroke color']) + + # update the stroke color button + self.activity.get_toolbar_box().brush_button.set_color(stroke_color) + self.activity.get_toolbar_box().brush_button.stop_stamping() + def mouseleave(self, widget, event): if self.tool['name'] in ['pencil', 'eraser', 'brush', 'rainbow', 'stamp']: @@ -777,7 +796,7 @@ class Area(gtk.DrawingArea): if self.text_in_progress: self.d.text(self, None) - self.janela.textview.hide() + self.activity.textview.hide() if self._undo_index > 0: self._undo_index -= 1 @@ -803,7 +822,7 @@ class Area(gtk.DrawingArea): if self.selmove: self.getout() - if self._undo_index < len(self._undo_list)-1: + if self._undo_index < len(self._undo_list) - 1: self._undo_index += 1 undo_pix = self._undo_list[self._undo_index] @@ -987,7 +1006,7 @@ class Area(gtk.DrawingArea): 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(color) - self.janela.textview.modify_text(gtk.STATE_NORMAL, color) + self.activity.textview.modify_text(gtk.STATE_NORMAL, color) def grayscale(self, widget): """Apply grayscale effect. @@ -1101,7 +1120,6 @@ class Area(gtk.DrawingArea): self.enableUndo(widget) self.set_tool_cursor() - def drain_events(self, block=gtk.FALSE): while gtk.events_pending(): gtk.mainiteration(block) @@ -1217,7 +1235,7 @@ class Area(gtk.DrawingArea): height, width, dither=gtk.gdk.RGB_DITHER_NORMAL, x_dither=0, y_dither=0) - self.janela.center_area() + self.activity.center_area() del temp_pix @@ -595,32 +595,32 @@ class Desenho: widget.text_in_progress = True x, y = int(event.x), int(event.y) - widget.janela.move_textview(x, y) - widget.janela.textview.show() - widget.janela.textview.grab_focus() + widget.activity.move_textview(x, y) + widget.activity.textview.show() + widget.activity.textview.grab_focus() else: widget.text_in_progress = False try: # This works for a gtk.Entry - text = widget.janela.textview.get_text() + text = widget.activity.textview.get_text() except AttributeError: # This works for a gtk.TextView - buf = widget.janela.textview.get_buffer() + buf = widget.activity.textview.get_buffer() start, end = buf.get_bounds() text = buf.get_text(start, end) - layout = widget.janela.textview.create_pango_layout(text) + layout = widget.activity.textview.create_pango_layout(text) widget.pixmap.draw_layout(widget.gc_brush, widget.oldx, widget.oldy, layout) widget.pixmap_temp.draw_layout(widget.gc, widget.oldx, widget.oldy, layout) - widget.janela.textview.hide() + widget.activity.textview.hide() try: - widget.janela.textview.set_text('') + widget.activity.textview.set_text('') except AttributeError: buf.set_text('') diff --git a/activity/activity.info b/activity/activity.info index f706c91..82751fb 100644 --- a/activity/activity.info +++ b/activity/activity.info @@ -1,6 +1,6 @@ [Activity] name = Paint -activity_version = 41 +activity_version = 42 bundle_id = org.laptop.Oficina exec = sugar-activity OficinaActivity.OficinaActivity icon = activity-paint diff --git a/fontcombobox.py b/fontcombobox.py new file mode 100644 index 0000000..58f9140 --- /dev/null +++ b/fontcombobox.py @@ -0,0 +1,65 @@ +# Copyright (C) 2012 Gonzalo Odiard <gonzalo@laptop.org> +# Based in code form Flavio Danesse <fdanesse@activitycentral.com> +# and Ariel Calzada <ariel.calzada@gmail.com> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +import gtk + +FONT_BLACKLIST = ['cmex10', 'cmmi10', 'cmr10', 'cmsy10', 'esint10', 'eufm10', + 'msam10', 'msbm10', 'rsfs10', 'wasy10'] + + +class FontComboBox(gtk.ComboBox): + + def __init__(self): + gtk.ComboBox.__init__(self) + font_renderer = gtk.CellRendererText() + self.pack_start(font_renderer) + self.add_attribute(font_renderer, 'text', 0) + self.add_attribute(font_renderer, 'font', 0) + font_model = gtk.ListStore(str) + + context = self.get_pango_context() + font_index = 0 + self.faces = {} + + for family in context.list_families(): + name = family.get_name() + if name not in FONT_BLACKLIST: + font_model.append([name]) + font_faces = [] + for face in family.list_faces(): + face_name = face.get_face_name() + font_faces.append(face_name) + self.faces[name] = font_faces + + sorter = gtk.TreeModelSort(font_model) + sorter.set_sort_column_id(0, gtk.SORT_ASCENDING) + self.set_model(sorter) + self.show() + + def set_font_name(self, font_name): + count = 0 + tree_iter = self.get_model().get_iter_first() + while tree_iter is not None: + value = self.get_model().get_value(tree_iter, 0) + if value == font_name: + self.set_active(count) + count = count + 1 + tree_iter = self.get_model().iter_next(tree_iter) + + def get_font_name(self): + tree_iter = self.get_active_iter() + return self.get_model().get_value(tree_iter, 0) diff --git a/icons/tool-picker.svg b/icons/tool-picker.svg new file mode 100644 index 0000000..57033ce --- /dev/null +++ b/icons/tool-picker.svg @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [ + <!ENTITY fill_color "#FFFFFF"> + <!ENTITY stroke_color "#010101"> +]> +<svg + xmlns="http://www.w3.org/2000/svg" + version="1.1" + width="55" + height="55" + viewBox="0 0 55 55" + id="svg2" + xml:space="preserve"><g + transform="translate(0,1.6628777)" + id="g3805"><g + transform="matrix(0.70710678,0.70710678,-0.70710678,0.70710678,26.449785,-15.294557)" + id="g3799"><rect + width="4.6261501" + height="27.981865" + ry="0" + x="29.37398" + y="13.271664" + id="rect2992" + style="color:#000000;fill:none;stroke:&fill_color;;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /><rect + width="13.011048" + height="3.9033144" + ry="1.0051752" + x="25.181532" + y="13.813988" + id="rect2994" + style="color:#000000;fill:&fill_color;;fill-opacity:1;stroke:&fill_color;;stroke-width:1.48247087;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /><rect + width="9.2666368" + height="6.5055242" + ry="2.9628069" + x="27.053738" + y="7.1639123" + id="rect2996" + style="color:#000000;fill:&fill_color;;fill-opacity:1;stroke:&fill_color;;stroke-width:1.7131356;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /><rect + width="4.6261501" + height="7.4034247" + ry="0" + x="29.37398" + y="33.850105" + id="rect3766" + style="color:#000000;fill:&fill_color;;stroke:&fill_color;;stroke-width:1.02874565;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /></g><path + d="m 21.3837,45.810463 c 0,1.235339 -0.585979,2.236779 -1.30882,2.236779 -0.722842,0 -1.308821,-1.00144 -1.308821,-2.236779 0,-1.235337 1.193562,-3.688251 1.308821,-7.316933 0.115259,3.628682 1.30882,6.081596 1.30882,7.316933 z" + id="path3774" + style="color:#000000;fill:&fill_color;;fill-opacity:1;stroke:&fill_color;;stroke-width:1.31233227;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /></g></svg>
\ No newline at end of file @@ -82,6 +82,8 @@ from sugar.activity.widgets import ActivityToolbarButton from sugar.graphics.toolbarbox import ToolbarButton, ToolbarBox from sugar.activity.widgets import StopButton +from fontcombobox import FontComboBox + class DrawToolbarBox(ToolbarBox): """Create toolbars for the activity""" @@ -123,23 +125,18 @@ class DrawToolbarBox(ToolbarBox): image_button.props.label = _('Image') self.toolbar.insert(image_button, -1) - separator = gtk.SeparatorToolItem() - separator.props.draw = False - separator.set_expand(True) - separator.show() - self.toolbar.insert(separator, -1) - stop = StopButton(self._activity) self.toolbar.insert(stop, -1) # TODO: workaround # the BrushButton does not starts - brush_button = tools_builder._stroke_color.color_button - brush_button.set_brush_shape(self._activity.area.tool['line shape']) - brush_button.set_brush_size(self._activity.area.tool['line size']) - brush_button.set_stamp_size(self._activity.area.tool['stamp size']) + self.brush_button = tools_builder._stroke_color.color_button + area = self._activity.area + self.brush_button.set_brush_shape(area.tool['line shape']) + self.brush_button.set_brush_size(area.tool['line size']) + self.brush_button.set_stamp_size(area.tool['stamp size']) if self._activity.area.tool['stroke color'] is not None: - brush_button.set_color(self._activity.area.tool['stroke color']) + self.brush_button.set_color(area.tool['stroke color']) ##Make the Edit Toolbar @@ -230,6 +227,7 @@ class ToolsToolbarBuilder(): _TOOL_BRUSH_NAME = 'brush' _TOOL_ERASER_NAME = 'eraser' _TOOL_BUCKET_NAME = 'bucket' + _TOOL_PICKER_NAME = 'picker' _TOOL_STAMP_NAME = 'stamp' _TOOL_MARQUEE_RECT_NAME = 'marquee-rectangular' @@ -251,12 +249,6 @@ class ToolsToolbarBuilder(): separator.set_draw(True) toolbar.insert(separator, -1) - """ - self._tool_pencil = DrawToolButton('tool-pencil', - activity.tool_group, _('Pencil')) - toolbar.insert(self._tool_pencil, -1) - """ - self._tool_brush = DrawToolButton('tool-brush', activity.tool_group, _('Brush')) activity.tool_group = self._tool_brush @@ -270,6 +262,10 @@ class ToolsToolbarBuilder(): activity.tool_group, _('Bucket')) toolbar.insert(self._tool_bucket, -1) + self._tool_picker = DrawToolButton('tool-picker', + activity.tool_group, _('Picker')) + toolbar.insert(self._tool_picker, -1) + self._tool_stamp = DrawToolButton('tool-stamp', activity.tool_group, _('Stamp')) toolbar.insert(self._tool_stamp, -1) @@ -301,6 +297,8 @@ class ToolsToolbarBuilder(): self._TOOL_ERASER_NAME) self._tool_bucket.connect('clicked', self.set_tool, self._TOOL_BUCKET_NAME) + self._tool_picker.connect('clicked', self.set_tool, + self._TOOL_PICKER_NAME) self._tool_stamp.connect('clicked', self.set_tool, self._TOOL_STAMP_NAME) self._tool_marquee_rectangular.connect('clicked', self.set_tool, @@ -604,20 +602,11 @@ class TextToolbar(gtk.Toolbar): tool_item = ToolComboBox(self._font_size_combo) self.insert(tool_item, -1) - self._fonts = [] - pango_context = self.get_pango_context() - pango_context.set_language(pango.Language("en")) - for family in pango_context.list_families(): - self._fonts.append(family.get_name()) - self._fonts.sort() - - self._font_combo = gtk.combo_box_new_text() + self._font_combo = FontComboBox() self._fonts_changed_id = self._font_combo.connect('changed', self.__font_changed_cb) - for i, f in enumerate(self._fonts): - self._font_combo.append_text(f) - if f == activity.area.font_description.get_family(): - self._font_combo.set_active(i) + font_name = activity.area.font_description.get_family() + self._font_combo.set_font_name(font_name) tool_item = ToolComboBox(self._font_combo) self.insert(tool_item, -1) self.show_all() @@ -646,8 +635,8 @@ class TextToolbar(gtk.Toolbar): def __font_changed_cb(self, combo): activity = self._activity - value = self.get_active_text(combo) - activity.area.font_description.set_family(value) + font_name = combo.get_font_name() + activity.area.font_description.set_family(font_name) activity.textview.modify_font(activity.area.font_description) def get_active_text(self, combobox): |