Experiments with goocanvas.Item.translate



I was working on an implementation of motion grab for my project and I noticed some interesting behavior caused by goocanvas.Item.translate() routine.

I set up an event handler that intercepts clicks on the root item of my canvas. I'm printing out the location of the click using event.x and event.y properties. What I found is that if I click an item first instead of clicking the canvas directly, and the item is translated, then the event.x and event.y values get somehow translated as well.

I did not expect this behavior, because the event handler is set up for root canvas item, not for the translated items that it contains. I would naturally expect the coordinates of the click to be converted to the canvas space before I'm granted access to them. What's even more confusing, the coordinates of the click are not in the item space either - they are in some sort of "translated canvas space".

The issue is easily solved by using event.x_root and event.y_root properties instead, but the logic behind the behavior described about still eludes me. If I'm processing a click on the root canvas, shouldn't it be in the canvas space? Why should it matter what items are on top, let alone are they translated or not?

Does anybody know if this is a bug or a feature?

Here's a working example. Click across the canvas from left to right. There will be a discrepancy in the output as soon as you start clicking on the second (right) circle.



#!/usr/bin/python

try:
    import gtk
    import cairo
    import goocanvas
except ImportError:
    print "Some of the import statements failed"
    raise SystemExit


class MainApp(gtk.Window):
   
    def __init__(self):
       
        super(MainApp, self).__init__()
       
       
        # Create the main window
       
        self.set_title("translate() experiments")
        self.set_size_request(400, 200)
        self.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(0, 0, 0))
        self.set_position(gtk.WIN_POS_CENTER)
       
       
        # Add the canvas
       
        canvas = goocanvas.Canvas()
        self.add(canvas)
       
        self.root = canvas.get_root_item()
        self.root.connect("button_press_event", self.OnMousePress)
       
       
        # Add a couple items
       
        circle1 = self.MakeGoocanvasItem(canvas.get_root_item(), 100, 100)
        circle2 = self.MakeGoocanvasItem(canvas.get_root_item(), 100, 100)
       
        circle2.translate(200, 0)
       
       
        # Final steps
       
        self.connect("destroy", gtk.main_quit)
        self.show_all()


    def MakeGoocanvasItem (self, canvas_root, x, y):
       
        # Add a circle
       
        circle = goocanvas.Ellipse(parent = canvas_root, center_x = x, center_y = y, radius_x = 40, radius_y = 40, stroke_pattern = cairo.SolidPattern(0.7, 0.2, 0.0), fill_pattern = cairo.SolidPattern(1.0, 0.8, 0.9), line_width = 4.0)       
        return circle


    ## Event handlers

    def OnMousePress(self, widget, target, event):
        print "Default at %d %d, root at %d %d" % (event.x, event.y, event.x_root, event.y_root)

MainApp()
gtk.main()


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]