Add EventIcon/CursorInvoker similar to CanvasIcon/CanvasInvoker
CanvasIcon and CanvasInvoker were removed in a previous GTK3-porting commit as they were based on hippocanvas. However, this leaves the toolkit with some missing functionality: there is no longer a trivial way to show an icon which can receive mouse events and pop up a palette. Such functionality is used in various places throughout the shell and activities. Reimplement this functionality as EventIcon and CursorInvoker. Instead of reimplementing much of the Icon class (like CanvasIcon did), EventIcon opts for a more simplistic encapsulation of an Icon object. This means trivial API changes for CanvasIcon users who must now use the 'icon' property with the Icon API. Signed-off-by: Daniel Drake <dsd@laptop.org> Acked-by: Simon Schampijer <simon@laptop.org>
This commit is contained in:
parent
5ad2fc7d6b
commit
827ab7218a
@ -29,6 +29,7 @@ from gi.repository import GObject
|
|||||||
from gi.repository import Gtk
|
from gi.repository import Gtk
|
||||||
import cairo
|
import cairo
|
||||||
|
|
||||||
|
from sugar3.graphics import style
|
||||||
from sugar3.graphics.xocolor import XoColor
|
from sugar3.graphics.xocolor import XoColor
|
||||||
from sugar3.util import LRU
|
from sugar3.util import LRU
|
||||||
|
|
||||||
@ -545,6 +546,75 @@ class Icon(Gtk.Image):
|
|||||||
type=float, setter=set_scale)
|
type=float, setter=set_scale)
|
||||||
|
|
||||||
|
|
||||||
|
class EventIcon(Gtk.EventBox):
|
||||||
|
"""
|
||||||
|
An Icon class that provides access to mouse events and that can act as a
|
||||||
|
cursor-positioned palette invoker.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__gtype_name__ = 'EventIcon'
|
||||||
|
__gsignals__ = {
|
||||||
|
'activated': (GObject.SIGNAL_RUN_LAST, GObject.TYPE_NONE, []),
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
Gtk.EventBox.__init__(self)
|
||||||
|
|
||||||
|
self._icon = Icon()
|
||||||
|
for key, value in kwargs.iteritems():
|
||||||
|
self._icon.set_property(key, value)
|
||||||
|
self.add(self._icon)
|
||||||
|
self._icon.show()
|
||||||
|
|
||||||
|
from sugar3.graphics.palette import CursorInvoker
|
||||||
|
self._palette_invoker = CursorInvoker()
|
||||||
|
self._palette_invoker.attach(self)
|
||||||
|
|
||||||
|
self.modify_bg(Gtk.StateType.NORMAL, style.COLOR_WHITE.get_gdk_color())
|
||||||
|
self.connect('destroy', self.__destroy_cb)
|
||||||
|
|
||||||
|
def __destroy_cb(self, icon):
|
||||||
|
if self._palette_invoker is not None:
|
||||||
|
self._palette_invoker.detach()
|
||||||
|
|
||||||
|
def do_button_press_event(self, event):
|
||||||
|
if event.button == 1:
|
||||||
|
self.emit('activated')
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_icon(self):
|
||||||
|
return self._icon
|
||||||
|
|
||||||
|
icon = GObject.property(
|
||||||
|
type=object, getter=get_icon)
|
||||||
|
|
||||||
|
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 sugar3.graphics.palette import Palette
|
||||||
|
|
||||||
|
self.set_palette(Palette(text))
|
||||||
|
|
||||||
|
|
||||||
class CellRendererIcon(Gtk.CellRenderer):
|
class CellRendererIcon(Gtk.CellRenderer):
|
||||||
|
|
||||||
__gtype_name__ = 'SugarCellRendererIcon'
|
__gtype_name__ = 'SugarCellRendererIcon'
|
||||||
|
@ -35,7 +35,7 @@ from gi.repository import SugarExt
|
|||||||
# DEPRECATED
|
# DEPRECATED
|
||||||
# Import these for backwards compatibility
|
# Import these for backwards compatibility
|
||||||
from sugar3.graphics.palettewindow import MouseSpeedDetector, Invoker, \
|
from sugar3.graphics.palettewindow import MouseSpeedDetector, Invoker, \
|
||||||
WidgetInvoker, CanvasInvoker, ToolInvoker, CellRendererInvoker
|
WidgetInvoker, CursorInvoker, ToolInvoker, CellRendererInvoker
|
||||||
|
|
||||||
|
|
||||||
class Palette(PaletteWindow):
|
class Palette(PaletteWindow):
|
||||||
|
@ -788,6 +788,68 @@ class WidgetInvoker(Invoker):
|
|||||||
widget = GObject.property(type=object, getter=_get_widget, setter=None)
|
widget = GObject.property(type=object, getter=_get_widget, setter=None)
|
||||||
|
|
||||||
|
|
||||||
|
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):
|
class ToolInvoker(WidgetInvoker):
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
|
Loading…
Reference in New Issue
Block a user