def on_mouse(self, event):
        '''handle mouse events'''
        state = self.state
        pos = event.GetPosition()
        if event.Leaving():
            self.mouse_pos = None
        else:
            self.mouse_pos = pos
        self.update_position()

        if hasattr(event, 'ButtonIsDown'):
            any_button_down = event.ButtonIsDown(wx.MOUSE_BTN_ANY)
            left_button_down = event.ButtonIsDown(wx.MOUSE_BTN_LEFT)
            right_button_down = event.ButtonIsDown(wx.MOUSE_BTN_RIGHT)
        else:
            left_button_down = event.leftIsDown
            right_button_down = event.rightIsDown
            any_button_down = left_button_down or right_button_down

        if any_button_down or event.ButtonUp():
            # send any event with a mouse button to the parent
            latlon = self.coordinates(pos.x, pos.y)
            selected = self.selected_objects(pos)
            state.event_queue.put(SlipMouseEvent(latlon, event, selected))
            if event.RightDown():
                state.popup_object = None
                state.popup_latlon = None
                if len(selected) > 0:
                    obj = state.layers[selected[0].layer][selected[0].objkey]
                    if obj.popup_menu is not None:
                        state.popup_object = obj
                        state.popup_latlon = latlon
                        self.show_popup(obj, pos)
                        state.popup_started = True
                if not state.popup_started and state.default_popup is not None:
                    state.popup_latlon = latlon
                    self.show_default_popup(pos)
                    state.popup_started = True

        if not right_button_down:
            state.popup_started = False

        if event.LeftDown() or event.RightDown():
            self.mouse_down = pos
            self.last_click_pos = self.click_pos
            self.click_pos = self.coordinates(pos.x, pos.y)

        if event.Dragging() and left_button_down:
            # drag map to new position
            newpos = pos
            if self.mouse_down and newpos:
                dx = (self.mouse_down.x - newpos.x)
                dy = -(self.mouse_down.y - newpos.y)
                pdist = math.sqrt(dx**2 + dy**2)
                if pdist > state.drag_step:
                    bearing = math.degrees(math.atan2(dx, dy))
                    distance = (state.ground_width/float(state.width)) * pdist
                    newlatlon = mp_util.gps_newpos(state.lat, state.lon, bearing, distance)
                    (state.lat, state.lon) = newlatlon
                    self.mouse_down = newpos
                    self.redraw_map()