diff --git a/src/sugar3/graphics/Makefile.am b/src/sugar3/graphics/Makefile.am index a4f9629e..344cc82d 100644 --- a/src/sugar3/graphics/Makefile.am +++ b/src/sugar3/graphics/Makefile.am @@ -6,6 +6,7 @@ sugar_PYTHON = \ combobox.py \ iconentry.py \ icon.py \ + progressicon.py \ __init__.py \ menuitem.py \ notebook.py \ diff --git a/src/sugar3/graphics/progressicon.py b/src/sugar3/graphics/progressicon.py new file mode 100644 index 00000000..c0ca8a6a --- /dev/null +++ b/src/sugar3/graphics/progressicon.py @@ -0,0 +1,101 @@ +# Copyright (C) 2013, One Laptop Per Child +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +from gi.repository import Gtk +from sugar3.graphics.icon import get_surface +from sugar3.graphics import style + + +class ProgressIcon(Gtk.DrawingArea): + """Display the progress filling the icon. + + This class is compatible with the sugar3.graphics.icon.Icon class. + + Call update(progress) with the new progress to update the icon. + + The direction defaults to 'vertical', in which case the icon is + filled from bottom to top. If direction is set to 'horizontal', + it will be filled from right to left or from left to right, + depending on the system's language RTL setting. + + """ + def __init__(self, icon_name, pixel_size, stroke_color, fill_color, + direction=None): + Gtk.DrawingArea.__init__(self) + + self._icon_name = icon_name + if direction == None: + direction = 'vertical' + self._direction = direction + self._progress = 0 + + self._stroke = get_surface( + icon_name=icon_name, width=pixel_size, height=pixel_size, + stroke_color=stroke_color, + fill_color=style.COLOR_TRANSPARENT.get_svg()) + + self._fill = get_surface( + icon_name=icon_name, width=pixel_size, height=pixel_size, + stroke_color=style.COLOR_TRANSPARENT.get_svg(), + fill_color=fill_color) + + self.connect("draw", self.__draw_cb) + + def __draw_cb(self, widget, cr): + allocation = widget.get_allocation() + + # Center the graphic in the allocated space. + margin_x = (allocation.width - self._stroke.get_width()) / 2 + margin_y = (allocation.height - self._stroke.get_height()) / 2 + cr.translate(margin_x, margin_y) + + # Paint the fill, clipping it by the progress. + x_, y_ = 0, 0 + width, height = self._stroke.get_width(), self._stroke.get_height() + if self._direction == 'vertical': # vertical direction, bottom to top + y_ = self._stroke.get_height() + height *= self._progress * -1 + else: + rtl_direction = \ + Gtk.Widget.get_default_direction() == Gtk.TextDirection.RTL + if rtl_direction: # horizontal direction, right to left + x_ = self._stroke.get_width() + width *= self._progress * -1 + else: # horizontal direction, left to right + width *= self._progress + + cr.rectangle(x_, y_, width, height) + cr.clip() + cr.set_source_surface(self._fill, 0, 0) + cr.paint() + + # Paint the stroke over the fill. + cr.reset_clip() + cr.set_source_surface(self._stroke, 0, 0) + cr.paint() + + def do_get_preferred_width(self): + width = self._stroke.get_width() + return (width, width) + + def do_get_preferred_height(self): + height = self._stroke.get_height() + return (height, height) + + def update(self, progress): + self._progress = progress + self.queue_draw() diff --git a/tests/graphics/progressicon.py b/tests/graphics/progressicon.py new file mode 100644 index 00000000..3dbd4b10 --- /dev/null +++ b/tests/graphics/progressicon.py @@ -0,0 +1,66 @@ +# Copyright (C) 2013, One Laptop Per Child +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +""" +Test the sugar3.graphics.progressicon.ProgressIcon widget. +""" + + +from gi.repository import GObject + +from sugar3.graphics.progressicon import ProgressIcon +from sugar3.graphics.icon import Icon, get_surface +from sugar3.graphics import style + +import common + +test = common.Test() +test.show() + +icon = ProgressIcon( + pixel_size=style.LARGE_ICON_SIZE, + icon_name='computer-xo', + stroke_color=style.COLOR_BUTTON_GREY.get_svg(), + fill_color=style.COLOR_WHITE.get_svg()) +test.pack_start(icon, True, True, 0) +icon.show() + +icon2 = ProgressIcon( + pixel_size=style.LARGE_ICON_SIZE, + icon_name='computer-xo', + stroke_color=style.COLOR_BUTTON_GREY.get_svg(), + fill_color=style.COLOR_WHITE.get_svg(), + direction='horizontal') +test.pack_start(icon2, True, True, 0) +icon2.show() + +progress = 0 + + +def timeout_cb(): + global progress + progress += 0.05 + icon.update(progress) + icon2.update(progress) + if progress >= 1: + return False + return True + +GObject.timeout_add(50, timeout_cb) + +if __name__ == '__main__': + common.main(test)