wxpython Pan implementation issue

I'm trying to implement a panning function in a wxpython program. This
program consists of a frame containing a ScrolledWindow which holds a Bitmap
image.

Clicking and panning on the blank panel produces the expected behaviour.
Clicking and panning on the image produces "jumping" of about 10px.

If the mouse_pos member is not updated during dragging, panning is smooth on
the image but then panning on the blank panel is erroneous.

System information: wxpython 2.8.12.1, Python 2.7.3 64bit and Windows 7
64bit.

<code>
import wx
import inspect
import threading

class MyFrame(wx.Frame):
    def __init__(self, parent, mytitle):
        wx.Frame.__init__(self, parent, wx.ID_ANY, mytitle, size=(350, 350))

        self.scrollwin = wx.ScrolledWindow(self, wx.ID_ANY)
        width = 1000
        height = 1000
        self.scrollwin.SetScrollbars(20, 20, width/20, height/20)
        self.scrollwin.SetScrollRate(1, 1)
        self.scrollwin.Bind(wx.EVT_MOTION, self.on_mouse_drag)
        self.scrollwin.Bind(wx.EVT_LEFT_DOWN, self.on_left_down)
        self.SetCursor(wx.StockCursor(wx.CURSOR_HAND))

        image_file = "test.jpg"
        image = wx.Bitmap(image_file)
        sb = wx.StaticBitmap(self.scrollwin, wx.ID_ANY, image)
        sb.Bind(wx.EVT_MOTION, self.event_defer)
        sb.Bind(wx.EVT_LEFT_DOWN, self.event_defer)
        self._mouse_pos = (0, 0)
        self.sem = threading.Semaphore(0)

    @property
    def mouse_pos(self):
        return self._mouse_pos

    @mouse_pos.setter
    def mouse_pos(self, value):
        print "mouse_pos:"
        print "Calling from: ", inspect.stack()[1][3]
        print value
        self._mouse_pos = value

    def on_mouse_drag(self, event):
        if event.Dragging() and event.LeftIsDown():
            self.sem.release()
            print self.sem._Semaphore__value
            (mouse_x, mouse_y) = self.mouse_pos

            #new_pos =
self.scrollwin.CalcUnscrolledPosition(event.GetPosition()).Get()
            #new_pos =
self.scrollwin.CalcScrolledPosition(event.GetPosition()).Get()
            new_pos = event.GetPositionTuple()
            (new_x, new_y) = new_pos

            scrollpos = self.scrollwin.GetViewStart()
            (scroll_x, scroll_y) = scrollpos

            (delta_x, delta_y) = ((new_x - mouse_x), (new_y - mouse_y))

            (scroll_x, scroll_y) = ((scroll_x - delta_x), (scroll_y -
delta_y))
            print "Scroll:"
            print (scroll_x, scroll_y)
            self.scrollwin.Scroll(scroll_x, scroll_y)

            #self.mouse_pos =
self.scrollwin.CalcUnscrolledPosition(event.GetPosition()).Get()
            #self.mouse_pos =
self.scrollwin.CalcScrolledPosition(event.GetPosition()).Get()
            self.mouse_pos = new_pos # Disabling this gives smooth panning
on the image

            self.sem.acquire(False)

    def on_left_down(self, event):
        #self.mouse_pos =
self.scrollwin.CalcUnscrolledPosition(event.GetPosition()).Get()
        #self.mouse_pos =
self.scrollwin.CalcScrolledPosition(event.GetPosition()).Get()
        self.mouse_pos = event.GetPositionTuple()

    def event_defer(self, event):
        event.ResumePropagation(1)
        event.Skip()

app = wx.App()
MyFrame(None, "Test wx.ScrolledWindow()").Show()
app.MainLoop()
</code>

···

--
View this message in context: http://wxpython-users.1045709.n5.nabble.com/wxpython-Pan-implementation-issue-tp5717823.html
Sent from the wxPython-users mailing list archive at Nabble.com.

dilbert wrote:

I'm trying to implement a panning function in a wxpython program. This
program consists of a frame containing a ScrolledWindow which holds a Bitmap
image.

Clicking and panning on the blank panel produces the expected behaviour.
Clicking and panning on the image produces "jumping" of about 10px.

If the mouse_pos member is not updated during dragging, panning is smooth on
the image but then panning on the blank panel is erroneous.

System information: wxpython 2.8.12.1, Python 2.7.3 64bit and Windows 7
64bit.

If you just draw the image yourself in a scrolled window's EVT_PAINT handler instead of using the wx.StaticBitmap then you would not have to deal with translating and forwarding the mouse events from one to the other, and things would end up being a lot simpler and would probably work better too.

···

--
Robin Dunn
Software Craftsman