How to know if mouse is moving to the left or right?

Hi,

I’m trying to navigate on my panel. The user keeps the middle click button pressed and moves the mouse, and the panel should be navigated to the left or right, in the mouse movement direction.

I save the original x and y mouse positions in 2 variables:

        self.panel.Bind(wx.EVT_MIDDLE_DOWN, self.onMouseMiddleDown)
        self.panel.Bind(wx.EVT_MOTION, self.onMotion)
    def onMouseMiddleDown(self, evt):
        self.org_x = evt.GetX()
        self.org_y = evt.GetY()

Then the user moves the mouse while middle button is pressed, and I calculate the delta x

    def onMotion(self, evt):
        x_pos = evt.GetX()
        y_pos = evt.GetY()
        middle_is_down = evt.MiddleIsDown()
        if middle_is_down:
            delta_x = x_pos - self.org_x
            self.panel.navigate_with_middle_click(delta_x)
            return

However, after the user moves to left and without releasing the middle button, he starts to move mouse to right, the panel is still navigated to left, because delta x is still positive.

Delta x will be always positive, until the cursor moves to the right of the original x pos (self.org_x). But I want the panel to be navigated in the direction of mouse movement, regardless of the cursor being on the left or right of the original x pos.

Do you have any suggestions?

Thanks
Best Regards

You’ll have to re-set self.org_x at appropriate (more) times or else it’ll go stale …

Karsten

1 Like

Hi,

Original x should be reset when the mouse motion changes direction (for example, left to right), but how do I know if the mouse is moving to the left or to the right?

:thinking:

# freely adapted from 'titlebar.pyw' somewhere in the archives
import wx

class Gui(wx.Frame):

    def __init__(self, parent):
        super().__init__(parent, title='move wx.Frame')

        self.Bind(wx.EVT_LEFT_DOWN, self.evt_left_down)
        self.Bind(wx.EVT_MOTION, self.evt_motion)

        self.Centre()
        self.Show()

    def evt_left_down(self, evt):
        x, y = self.ClientToScreen(evt.GetPosition())
        originx, originy = self.GetPosition()
        self.delta = ((x - originx, y - originy))

    def evt_motion(self, evt):
        if evt.Dragging() and evt.LeftIsDown():
            x, y = self.ClientToScreen(evt.GetPosition())
            self.Move((x - self.delta[0], y - self.delta[1]))

app = wx.App()
Gui(None)
app.MainLoop()
1 Like

Karsten indicated that to get the relative motion:

    def evt_left_down(self, evt):
        self._org = evt.GetPosition()
        
    def evt_motion(self, evt):
        if evt.Dragging() and evt.LeftIsDown():
            pos = evt.GetPosition()
            delta = pos - self._org
            self._org = pos
            print("delta =", delta)

:wink:

1 Like

Just for fun and cobbling together what others have already pointed out.

import wx

class Gui(wx.Frame):

    def __init__(self, parent):
        super().__init__(parent, title='move wx.Frame')

        self.Bind(wx.EVT_LEFT_DOWN, self.evt_left_down)
        self.Bind(wx.EVT_LEFT_UP, self.evt_left_up)
        self.Bind(wx.EVT_MOTION, self.evt_motion)

        self.Centre()
        self.Show()

    def evt_left_down(self, event):
        x, y = self.ClientToScreen(event.GetPosition())
        self.origin = self.GetPosition()
        originx, originy = self.origin
        self.delta = ((x - originx, y - originy))
        self.latest_delta = self.delta

    def evt_left_up(self, event):
        self.Move((self.origin))
        print("Moved to Home positiom")

    def evt_motion(self, event):
        if event.Dragging() and event.LeftIsDown():
            latest_delta = self.ClientToScreen(event.GetPosition())
            x, y = latest_delta
            x1, y1 = self.latest_delta
            if x < x1:
                print("Moving Left")
            elif x > x1:
                print("Moving Right")
            if y < y1:
                print("Moving Up")
            elif y > y1:
                print("Moving Down")
            self.latest_delta = latest_delta
            self.Move((x - self.delta[0], y - self.delta[1]))

app = wx.App()
Gui(None)
app.MainLoop()
1 Like