On 08/06/2012 03:53 PM, Benjamin Berg wrote:
On Mon, 2012-08-06 at 15:49 +0200, Sascha Silbe wrote:
Benjamin Berg <ben...@sugarlabs.org> writes:
+        # 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())

Not really too bad, but I am pretty sure that
gtk.EventBox.set_visible_window(False) should work fine here.

Doesn't look that way to me:

Oh, thanks for the screenshot. That is kinda obvious. One needs to add
allocation.x and allocation.y to the coordinates if you don't have a
visible window.

So:

+    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)


Also change the x/y calculation to add allocation.x and allocation.y
respectively. Then things should work fine.

Benjamin


diff --git a/src/jarabe/view/eventicon.py b/src/jarabe/view/eventicon.py
index 4166798..0432c34 100644
--- a/src/jarabe/view/eventicon.py
+++ b/src/jarabe/view/eventicon.py
@@ -94,16 +94,13 @@ class EventIcon(gtk.EventBox):
         self._alpha = 1.0

         gtk.EventBox.__init__(self)
+        self.set_visible_window(False)
         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):
@@ -111,8 +108,8 @@ class EventIcon(gtk.EventBox):
         if surface:
             allocation = self.get_allocation()

-            x = (allocation.width - surface.get_width()) / 2
-            y = (allocation.height - surface.get_height()) / 2
+            x = allocation.x + (allocation.width - surface.get_width()) / 2
+ y = allocation.y + (allocation.height - surface.get_height()) / 2

             cr = self.window.cairo_create()
             cr.set_source_surface(surface, x, y)


This will work now. As Benjamin stated the one needs to add allocation.x/y in expose, the current code works fine if the event box has a visible window, because then allocation.x and allocation.y are 0 by definition. Attached is the updated patch as well.

Regards,
   Simon



>From f1e4ccbee809d099f1af1d70694d32d2790033e9 Mon Sep 17 00:00:00 2001
From: Simon Schampijer <si...@schampijer.de>
Date: Wed, 25 Jul 2012 00:23:46 +0200
Subject: [PATCH sugar 1/5] SugarEventIcon: Add a hippo-free implementation of
 the CanvasIcon

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 <si...@laptop.org>
[moved from sugar-toolkit to sugar]
Signed-off-by: Sascha Silbe <si...@activitycentral.com>

[1] http://developer.gnome.org/gtk/2.24/GtkEventBox.html
[2] http://developer.gnome.org/gtk/2.24/gtk-Themeable-Stock-Images.html#GtkIconSize
---
 src/jarabe/view/Makefile.am  |   1 +
 src/jarabe/view/eventicon.py | 274 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 275 insertions(+)
 create mode 100644 src/jarabe/view/eventicon.py

diff --git a/src/jarabe/view/Makefile.am b/src/jarabe/view/Makefile.am
index 630f184..31ccfa4 100644
--- a/src/jarabe/view/Makefile.am
+++ b/src/jarabe/view/Makefile.am
@@ -4,6 +4,7 @@ sugar_PYTHON =				\
 	buddyicon.py			\
 	buddymenu.py			\
 	customizebundle.py		\
+	eventicon.py			\
 	keyhandler.py			\
 	launcher.py			\
 	palettes.py			\
diff --git a/src/jarabe/view/eventicon.py b/src/jarabe/view/eventicon.py
new file mode 100644
index 0000000..0432c34
--- /dev/null
+++ b/src/jarabe/view/eventicon.py
@@ -0,0 +1,274 @@
+# Copyright (C) 2012, 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.
+import gobject
+import gtk
+
+from sugar.graphics import style
+from sugar.graphics.icon import _IconBuffer
+from sugar.graphics.palette import Palette
+from sugar.graphics.palettewindow import Invoker
+
+
+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 EventIcon(gtk.EventBox):
+
+    __gtype_name__ = 'SugarEventIcon'
+
+    def __init__(self, **kwargs):
+        self._buffer = _IconBuffer()
+        self._alpha = 1.0
+
+        gtk.EventBox.__init__(self)
+        self.set_visible_window(False)
+        for key, value in kwargs.iteritems():
+            self.set_property(key, value)
+
+        self._palette_invoker = CursorInvoker()
+        self._palette_invoker.attach(self)
+
+        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.x + (allocation.width - surface.get_width()) / 2
+            y = allocation.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):
+        self.set_palette(Palette(text))
-- 
1.7.11.2

_______________________________________________
Sugar-devel mailing list
Sugar-devel@lists.sugarlabs.org
http://lists.sugarlabs.org/listinfo/sugar-devel

Reply via email to