Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Schampijer <simon@schampijer.de>2012-06-28 13:50:23 (GMT)
committer Simon Schampijer <simon@schampijer.de>2012-06-28 13:55:16 (GMT)
commit47e33b91d1cf9eca23504df959a9ad3fb6f7a19a (patch)
tree593540abfa9031f6e6907610b9d70306119e464a
parenta4ff9a55ef655d9d7f0caf7267b7c820df93cafe (diff)
SugarEventIcon: Add a hippo-free implementation of the CanvasIconHEADmaster
The icon consists of an GtkEventBox and an IconBuffer. The GtkEventBox is a subclass of GtkBin which has its own window and therefor is used to catch events for our IconBuffer which does not have it's own window. The EventIcon uses the CursorInvoker that has been introduced in the GTK+ 3 toolkit to invoke a palette the same way as the CanvasIcon did. We keep the same API as with the CanvasIcon, only the 'size' property is changed to be called 'pixel_size' in order to make clearer which values it expects to be passed. We don't expect a GtkIconSize to be passed here. Another option would have been to put a SugarIcon inside a a GtkEventBox and make the properties available through an icon property but the API would have not been as nice and logically it seems to make more sense to have the IconBuffer being the base for both the SugarIcon and the SugarEventIcon. This patch is highly based on the work from Walter Bender, Daniel Drake and Raul Gutierrez Segales. Signed-off-by: Simon Schampijer <simon@laptop.org> [1] http://developer.gnome.org/gtk/2.24/GtkEventBox.html [2] http://developer.gnome.org/gtk/2.24/gtk-Themeable-Stock-Images.html#GtkIconSize
-rw-r--r--src/sugar/graphics/icon.py197
-rw-r--r--src/sugar/graphics/palettewindow.py62
2 files changed, 259 insertions, 0 deletions
diff --git a/src/sugar/graphics/icon.py b/src/sugar/graphics/icon.py
index 3f540d7..7634ef2 100644
--- a/src/sugar/graphics/icon.py
+++ b/src/sugar/graphics/icon.py
@@ -30,6 +30,7 @@ import gtk
import hippo
import cairo
+from sugar.graphics import style
from sugar.graphics.xocolor import XoColor
from sugar.util import LRU
@@ -985,6 +986,202 @@ class CanvasIcon(hippo.CanvasBox, hippo.CanvasItem):
self.set_palette(Palette(text))
+class EventIcon(gtk.EventBox):
+
+ __gtype_name__ = 'SugarEventIcon'
+
+ def __init__(self, **kwargs):
+ from sugar.graphics.palettewindow import CursorInvoker
+
+ self._buffer = _IconBuffer()
+ self._alpha = 1.0
+
+ gtk.EventBox.__init__(self)
+ for key, value in kwargs.iteritems():
+ self.set_property(key, value)
+
+ self._palette_invoker = CursorInvoker()
+ self._palette_invoker.attach(self)
+
+ # HACK to supress the grey background around the icon
+ # won't be needed in GTK3
+ self.modify_bg(gtk.STATE_NORMAL, style.COLOR_WHITE.get_gdk_color())
+
+ self.connect('destroy', self.__destroy_cb)
+
+ def do_expose_event(self, event):
+ surface = self._buffer.get_surface()
+ if surface:
+ allocation = self.get_allocation()
+
+ x = (allocation.width - surface.get_width()) / 2
+ y = (allocation.height - surface.get_height()) / 2
+
+ cr = self.window.cairo_create()
+ cr.set_source_surface(surface, x, y)
+ if self._alpha == 1.0:
+ cr.paint()
+ else:
+ cr.paint_with_alpha(self._alpha)
+
+ def do_size_request(self, req):
+ surface = self._buffer.get_surface()
+ if surface:
+ req.width = surface.get_width()
+ req.height = surface.get_height()
+ elif self._buffer.width:
+ req.width = self._buffer.width
+ req.height = self._buffer.height
+ else:
+ req.width = 0
+ req.height = 0
+
+ def __destroy_cb(self, icon):
+ if self._palette_invoker is not None:
+ self._palette_invoker.detach()
+
+ def set_file_name(self, value):
+ if self._buffer.file_name != value:
+ self._buffer.file_name = value
+ self.queue_draw()
+
+ def get_file_name(self):
+ return self._buffer.file_name
+
+ file_name = gobject.property(
+ type=object, getter=get_file_name, setter=set_file_name)
+
+ def set_icon_name(self, value):
+ if self._buffer.icon_name != value:
+ self._buffer.icon_name = value
+ self.queue_draw()
+
+ def get_icon_name(self):
+ return self._buffer.icon_name
+
+ icon_name = gobject.property(
+ type=object, getter=get_icon_name, setter=set_icon_name)
+
+ def set_xo_color(self, value):
+ if self._buffer.xo_color != value:
+ self._buffer.xo_color = value
+ self.queue_draw()
+
+ xo_color = gobject.property(
+ type=object, getter=None, setter=set_xo_color)
+
+ def set_fill_color(self, value):
+ if self._buffer.fill_color != value:
+ self._buffer.fill_color = value
+ self.queue_draw()
+
+ def get_fill_color(self):
+ return self._buffer.fill_color
+
+ fill_color = gobject.property(
+ type=object, getter=get_fill_color, setter=set_fill_color)
+
+ def set_stroke_color(self, value):
+ if self._buffer.stroke_color != value:
+ self._buffer.stroke_color = value
+ self.queue_draw()
+
+ def get_stroke_color(self):
+ return self._buffer.stroke_color
+
+ stroke_color = gobject.property(
+ type=object, getter=get_stroke_color, setter=set_stroke_color)
+
+ def set_background_color(self, value):
+ if self._buffer.background_color != value:
+ self._buffer.background_color = value
+ self.queue_draw()
+
+ def get_background_color(self):
+ return self._buffer.background_color
+
+ background_color = gobject.property(
+ type=object, getter=get_background_color, setter=set_background_color)
+
+ def set_size(self, value):
+ if self._buffer.width != value:
+ self._buffer.width = value
+ self._buffer.height = value
+ self.queue_resize()
+
+ def get_size(self):
+ return self._buffer.width
+
+ pixel_size = gobject.property(
+ type=object, getter=get_size, setter=set_size)
+
+ def set_scale(self, value):
+ if self._buffer.scale != value:
+ self._buffer.scale = value
+ self.queue_resize()
+
+ def get_scale(self):
+ return self._buffer.scale
+
+ scale = gobject.property(
+ type=float, getter=get_scale, setter=set_scale)
+
+ def set_alpha(self, alpha):
+ if self._alpha != alpha:
+ self._alpha = alpha
+ self.queue_draw()
+
+ alpha = gobject.property(
+ type=float, setter=set_alpha)
+
+ def set_cache(self, value):
+ self._buffer.cache = value
+
+ def get_cache(self):
+ return self._buffer.cache
+
+ cache = gobject.property(
+ type=bool, default=False, getter=get_cache, setter=set_cache)
+
+ def set_badge_name(self, value):
+ if self._buffer.badge_name != value:
+ self._buffer.badge_name = value
+ self.queue_draw()
+
+ def get_badge_name(self):
+ return self._buffer.badge_name
+
+ badge_name = gobject.property(
+ type=object, getter=get_badge_name, setter=set_badge_name)
+
+ def create_palette(self):
+ return None
+
+ def get_palette(self):
+ return self._palette_invoker.palette
+
+ def set_palette(self, palette):
+ self._palette_invoker.palette = palette
+
+ palette = gobject.property(
+ type=object, setter=set_palette, getter=get_palette)
+
+ def get_palette_invoker(self):
+ return self._palette_invoker
+
+ def set_palette_invoker(self, palette_invoker):
+ self._palette_invoker.detach()
+ self._palette_invoker = palette_invoker
+
+ palette_invoker = gobject.property(
+ type=object, setter=set_palette_invoker, getter=get_palette_invoker)
+
+ def set_tooltip(self, text):
+ from sugar.graphics.palette import Palette
+
+ self.set_palette(Palette(text))
+
+
class CellRendererIcon(gtk.GenericCellRenderer):
__gtype_name__ = 'SugarCellRendererIcon'
diff --git a/src/sugar/graphics/palettewindow.py b/src/sugar/graphics/palettewindow.py
index 5281e54..4603c16 100644
--- a/src/sugar/graphics/palettewindow.py
+++ b/src/sugar/graphics/palettewindow.py
@@ -845,6 +845,68 @@ class CanvasInvoker(Invoker):
return hippo.get_canvas_for_item(self._item).get_toplevel()
+class CursorInvoker(Invoker):
+
+ def __init__(self, parent=None):
+ Invoker.__init__(self)
+
+ self._position_hint = self.AT_CURSOR
+ self._enter_hid = None
+ self._leave_hid = None
+ self._release_hid = None
+ self._item = None
+
+ if parent:
+ self.attach(parent)
+
+ def attach(self, parent):
+ Invoker.attach(self, parent)
+
+ self._item = parent
+ self._enter_hid = self._item.connect('enter-notify-event',
+ self.__enter_notify_event_cb)
+ self._leave_hid = self._item.connect('leave-notify-event',
+ self.__leave_notify_event_cb)
+ self._release_hid = self._item.connect('button-release-event',
+ self.__button_release_event_cb)
+
+ def detach(self):
+ Invoker.detach(self)
+ self._item.disconnect(self._enter_hid)
+ self._item.disconnect(self._leave_hid)
+ self._item.disconnect(self._release_hid)
+
+ def get_default_position(self):
+ return self.AT_CURSOR
+
+ def get_rect(self):
+ window = self._item.get_window()
+ allocation = self._item.get_allocation()
+ rect = Gdk.Rectangle()
+ rect.x, rect.y = window.get_root_coords(allocation.x, allocation.y)
+ rect.width = allocation.width
+ rect.height = allocation.height
+ return rect
+
+ def __enter_notify_event_cb(self, button, event):
+ self.notify_mouse_enter()
+ return False
+
+ def __leave_notify_event_cb(self, button, event):
+ self.notify_mouse_leave()
+ return False
+
+ def __button_release_event_cb(self, button, event):
+ if event.button == 3:
+ self.notify_right_click()
+ return True
+ else:
+ return False
+
+ def get_toplevel(self):
+ return self._item.get_toplevel()
+
+
class ToolInvoker(WidgetInvoker):
def __init__(self, parent=None):