From 3a1303ab5fa37d2a9881682af29fa4e177ea67ec Mon Sep 17 00:00:00 2001 From: erick Date: Wed, 02 Dec 2009 15:02:41 +0000 Subject: Changed the DragWrapper behavior to use drag-begin, drag-end and the icon change to implement a move on the overlayer. However, on the regular overlayer, drag-end signal is never emitted --- (limited to 'tutorius/actions.py') diff --git a/tutorius/actions.py b/tutorius/actions.py index 75c9c9b..b24d14e 100644 --- a/tutorius/actions.py +++ b/tutorius/actions.py @@ -17,7 +17,7 @@ This module defines Actions that can be done and undone on a state """ import gtk - +import logging from gettext import gettext as _ from sugar.graphics import icon @@ -25,9 +25,16 @@ from sugar.graphics import icon from . import addon from .services import ObjectStore from .properties import * +from .constants import * + class DragWrapper(object): """Wrapper to allow gtk widgets to be dragged around""" + + fromImage = [ ( WIDGET_ID, 0, TARGET_TYPE_WIDGET ) ] + + LOGGER = logging.getLogger("sugar.tutorius.actions.DragWrapper") + def __init__(self, widget, position, draggable=False): """ Creates a wrapper to allow gtk widgets to be mouse dragged, if the @@ -41,47 +48,50 @@ class DragWrapper(object): self._drag_on = False # whether dragging is enabled self._rel_pos = (0,0) # mouse pos relative to widget self._handles = [] # event handlers - self._dragging = False # whether a drag is in progress self.position = position # position of the widget self.moved = False self.draggable = draggable - def _pressed_cb(self, widget, evt): - """Callback for start of drag event""" - self._eventbox.grab_add() - self._dragging = True - self._rel_pos = evt.get_coords() - - def _moved_cb(self, widget, evt): - """Callback for mouse drag events""" - if not self._dragging: - return - - # Focus on a widget before dragging another would - # create addititonal move event, making the widget jump unexpectedly. - # Solution found was to process those focus events before dragging. - if gtk.events_pending(): - return - + def _drag_begin(self, widget, drag_context, *args): + """Callback for initialisation of drag and drop""" + # Setup the drag icon to what the widget is rendering + self.LOGGER.debug("%s drag-begin"%(str(widget))) + width = self._widget.allocation.width + height = self._widget.allocation.height + x = self._widget.allocation.x + y = self._widget.allocation.y + depth = 24 # Should be set dynamically + + pxbuf = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, True, 8, width, height) + pxbuf.fill(0xFFFFFFFF) + + px = gtk.gdk.Pixmap(None, width, height, depth) # source, size, colors + px.set_colormap(gtk.gdk.colormap_get_system()) + ctxt = px.cairo_create() + ctxt.set_source_pixbuf(pxbuf,0,0) + ctxt.paint() + + # Compensate when drawing the icon for the context + # translation done to the position occupied by the widget + ctxt.translate(-x, -y) + self._widget.draw_with_context(ctxt) + + pxbuf.get_from_drawable(px,gtk.gdk.colormap_get_system(), 0, 0, 0, 0, -1, -1) + drag_context.set_icon_pixbuf(pxbuf,0,0) + + def _drag_end(self, widget, context, *args): + """Callback for end of drag (stolen focus).""" xrel, yrel = self._rel_pos - xparent, yparent = evt.get_coords() - xparent, yparent = widget.translate_coordinates(widget.parent, - xparent, yparent) - self.position = (xparent-xrel, yparent-yrel) - self.moved = True + rootwin = widget.get_screen().get_root_window() + xparent,yparent,mods = rootwin.get_pointer() + + self.position = (int(xparent-xrel), int(yparent-yrel)) + self.LOGGER.debug("%s drag-end pos: (%s,%s)"%(str(widget),self.position)) self._widget.parent.move(self._eventbox, *self.position) self._widget.parent.move(self._widget, *self.position) self._widget.parent.queue_draw() - def _released_cb(self, *args): - """Callback for end of drag (mouse release).""" - self._eventbox.grab_remove() - self._dragging = False - - def _drag_end(self, *args): - """Callback for end of drag (stolen focus).""" - self._dragging = False def set_draggable(self, value): """Setter for the draggable property""" @@ -93,14 +103,15 @@ class DragWrapper(object): size = self._widget.size_request() self._eventbox.set_size_request(*size) self._widget.parent.put(self._eventbox, *self.position) + + # Prepare the widget for drag and drop + self._eventbox.drag_source_set(gtk.gdk.BUTTON1_MASK, + self.fromImage, + gtk.gdk.ACTION_MOVE) self._handles.append(self._eventbox.connect( - "button-press-event", self._pressed_cb)) - self._handles.append(self._eventbox.connect( - "button-release-event", self._released_cb)) - self._handles.append(self._eventbox.connect( - "motion-notify-event", self._moved_cb)) + "drag-begin", self._drag_begin)) self._handles.append(self._eventbox.connect( - "grab-broken-event", self._drag_end)) + "drag-end", self._drag_end)) else: while len(self._handles): handle = self._handles.pop() -- cgit v0.9.1