def on_mouse_wheel(self, event): '''handle mouse wheel zoom changes''' state = self.state if not state.can_zoom: return mousepos = self.image_coordinates(event.GetPosition()) rotation = event.GetWheelRotation() / event.GetWheelDelta() oldzoom = self.zoom if rotation > 0: self.zoom /= 1.0 / (1.1 * rotation) elif rotation < 0: self.zoom /= 1.1 * (-rotation) if self.zoom > 10: self.zoom = 10 elif self.zoom < 0.1: self.zoom = 0.1 if oldzoom < 1 and self.zoom > 1: self.zoom = 1 if oldzoom > 1 and self.zoom < 1: self.zoom = 1 client_area = state.frame.GetClientSize() fit_window_zoom_level = min( float(client_area.x) / self.img.GetWidth(), float(client_area.y) / self.img.GetHeight()) if self.zoom < fit_window_zoom_level: self.zoom = fit_window_zoom_level self.need_redraw = True new = self.image_coordinates(event.GetPosition()) # adjust dragpos so the zoom doesn't change what pixel is under the mouse self.dragpos = wx.Point(self.dragpos.x - (new.x - mousepos.x), self.dragpos.y - (new.y - mousepos.y)) self.limit_dragpos()
def on_key_event(self, event): '''handle key events''' keycode = event.GetKeyCode() if keycode == wx.WXK_HOME: self.zoom = 1.0 self.dragpos = wx.Point(0, 0) self.need_redraw = True event.Skip()
def fit_to_window(self): '''fit image to window''' state = self.state self.dragpos = wx.Point(0, 0) client_area = state.frame.GetClientSize() self.zoom = min( float(client_area.x) / self.img.GetWidth(), float(client_area.y) / self.img.GetHeight()) self.need_redraw = True
def on_drag_event(self, event): '''handle mouse drags''' state = self.state if not state.can_drag: return newpos = self.image_coordinates(event.GetPosition()) dx = -(newpos.x - self.mouse_down.x) dy = -(newpos.y - self.mouse_down.y) self.dragpos = wx.Point(self.dragpos.x + dx, self.dragpos.y + dy) self.limit_dragpos() self.mouse_down = newpos self.need_redraw = True self.redraw()
def __init__(self, parent, state): wx.Panel.__init__(self, parent) self.frame = parent self.state = state self.img = None self.redraw_timer = wx.Timer(self) self.Bind(wx.EVT_TIMER, self.on_redraw_timer, self.redraw_timer) self.Bind(wx.EVT_SET_FOCUS, self.on_focus) self.redraw_timer.Start(100) self.mouse_down = None self.drag_step = 10 self.zoom = 1.0 self.menu = None self.popup_menu = None self.wx_popup_menu = None self.popup_pos = None self.last_size = None self.done_PIL_warning = False state.brightness = 1.0 # dragpos is the top left position in image coordinates self.dragpos = wx.Point(0, 0) self.need_redraw = True self.mainSizer = wx.BoxSizer(wx.VERTICAL) self.SetSizer(self.mainSizer) # panel for the main image with warnings.catch_warnings(): warnings.simplefilter('ignore') self.imagePanel = mp_widgets.ImagePanel( self, wx.EmptyImage(state.width, state.height)) self.mainSizer.Add(self.imagePanel, flag=wx.TOP | wx.LEFT | wx.GROW, border=0) if state.mouse_events: self.imagePanel.Bind(wx.EVT_MOUSE_EVENTS, self.on_event) else: self.imagePanel.Bind(wx.EVT_MOUSE_EVENTS, self.on_mouse_event) if state.key_events: self.imagePanel.Bind(wx.EVT_KEY_DOWN, self.on_event) else: self.imagePanel.Bind(wx.EVT_KEY_DOWN, self.on_key_event) self.imagePanel.Bind(wx.EVT_MOUSEWHEEL, self.on_mouse_wheel) self.redraw() state.frame.Fit()
def on_event(self, event): '''pass events to the parent''' state = self.state if isinstance(event, wx.MouseEvent): self.on_mouse_event(event) if isinstance(event, wx.KeyEvent): self.on_key_event(event) if isinstance(event, wx.MouseEvent): if hasattr(event, 'ButtonIsDown'): any_button_down = event.ButtonIsDown(wx.MOUSE_BTN_ANY) else: any_button_down = event.leftIsDown or event.rightIsDown if not any_button_down and event.GetWheelRotation() == 0: # don't flood the queue with mouse movement return evt = mp_util.object_container(event) pt = self.image_coordinates(wx.Point(evt.X, evt.Y)) evt.X = pt.x evt.Y = pt.y state.out_queue.put(evt)
def full_size(self): '''show image at full size''' self.dragpos = wx.Point(0, 0) self.zoom = 1.0 self.need_redraw = True
def image_coordinates(self, point): '''given a point in window coordinates, calculate image coordinates''' # the dragpos is the top left position in image coordinates ret = wx.Point(int(self.dragpos.x + point.x / self.zoom), int(self.dragpos.y + point.y / self.zoom)) return ret