<commit_before>import wx
from canvasSubject import canvasSubject
from canvasObject import *

class canvas(wx.wxScrolledWindow, canvasSubject):
    def __init__(self, parent, id = -1, size = wx.wxDefaultSize):
        # parent 1 ctor
        wx.wxScrolledWindow.__init__(self, parent, id, wx.wxPoint(0, 0), size,
                                    wx.wxSUNKEN_BORDER)
        # parent 2 ctor
        canvasSubject.__init__(self)

        self._cobjects = []
        self._previousRealCoords = None
        self._mouseDelta = (0,0)
        self._potentiallyDraggedObject = None
        self._draggedObject = None

        self._observers = {'drag' : [],
                           'buttonDown' : [],
                           'buttonUp' : []}

        self.SetBackgroundColour("WHITE")

        wx.EVT_MOUSE_EVENTS(self, self.OnMouseEvent)
        wx.EVT_PAINT(self, self.OnPaint)

        self.virtualWidth = 2048
        self.virtualHeight = 2048
        
        self._buffer = None
        self._buffer = wx.wxEmptyBitmap(self.virtualWidth, self.virtualHeight)

        # we're only going to draw into the buffer, so no real client DC
        dc = wx.wxBufferedDC(None, self._buffer)
        dc.SetBackground(wx.wxBrush(self.GetBackgroundColour()))
        dc.Clear()
        self.doDrawing(dc)

        self.SetVirtualSize((self.virtualWidth, self.virtualHeight))
        self.SetScrollRate(20,20)

    def eventToRealCoords(self, ex, ey):
        """Convert window event coordinates to canvas relative coordinates.
        """
        
        # get canvas parameters
        vsx, vsy = self.GetViewStart()
        dx, dy = self.GetScrollPixelsPerUnit()

        # calculate REAL coords
        rx = ex + vsx * dx
        ry = ey + vsy * dy

        return (rx, ry)

    def getDC(self):
        """Returns DC which can be used by the outside to draw to our buffer.

        As soon as dc dies (and it will at the end of the calling function)
        the contents of self._buffer will be blitted to the screen.
        """

        cdc = wx.wxClientDC(self)
        # set device origin according to scroll position                
        self.PrepareDC(cdc)
        dc = wx.wxBufferedDC(cdc, self._buffer)
        return dc

    def OnMouseEvent(self, event):

        # this seems to work fine under windows.  If we don't do this, and the
        # mouse leaves the canvas, the rubber band remains and no selection
        # is made.
        if event.ButtonDown():
            self.CaptureMouse()
        elif event.ButtonUp():
            self.ReleaseMouse()
        
        # these coordinates are relative to the visible part of the canvas
        ex, ey = event.GetX(), event.GetY()

        rx, ry = self.eventToRealCoords(ex, ey)

        # add the "real" coords to the event structure
        event.realX = rx
        event.realY = ry

        if self._previousRealCoords:
            self._mouseDelta = (rx - self._previousRealCoords[0],
                                ry - self._previousRealCoords[1])<commit_msg>Refined canvas mouse capture logic.<commit_after>import wx
from canvasSubject import canvasSubject
from canvasObject import *

class canvas(wx.wxScrolledWindow, canvasSubject):
    def __init__(self, parent, id = -1, size = wx.wxDefaultSize):
        # parent 1 ctor
        wx.wxScrolledWindow.__init__(self, parent, id, wx.wxPoint(0, 0), size,
                                    wx.wxSUNKEN_BORDER)
        # parent 2 ctor
        canvasSubject.__init__(self)

        self._cobjects = []
        self._previousRealCoords = None
        self._mouseDelta = (0,0)
        self._potentiallyDraggedObject = None
        self._draggedObject = None

        self._observers = {'drag' : [],
                           'buttonDown' : [],
                           'buttonUp' : []}

        self.SetBackgroundColour("WHITE")

        wx.EVT_MOUSE_EVENTS(self, self.OnMouseEvent)
        wx.EVT_PAINT(self, self.OnPaint)

        self.virtualWidth = 2048
        self.virtualHeight = 2048
        
        self._buffer = None
        self._buffer = wx.wxEmptyBitmap(self.virtualWidth, self.virtualHeight)

        # we're only going to draw into the buffer, so no real client DC
        dc = wx.wxBufferedDC(None, self._buffer)
        dc.SetBackground(wx.wxBrush(self.GetBackgroundColour()))
        dc.Clear()
        self.doDrawing(dc)

        self.SetVirtualSize((self.virtualWidth, self.virtualHeight))
        self.SetScrollRate(20,20)

    def eventToRealCoords(self, ex, ey):
        """Convert window event coordinates to canvas relative coordinates.
        """
        
        # get canvas parameters
        vsx, vsy = self.GetViewStart()
        dx, dy = self.GetScrollPixelsPerUnit()

        # calculate REAL coords
        rx = ex + vsx * dx
        ry = ey + vsy * dy

        return (rx, ry)

    def getDC(self):
        """Returns DC which can be used by the outside to draw to our buffer.

        As soon as dc dies (and it will at the end of the calling function)
        the contents of self._buffer will be blitted to the screen.
        """

        cdc = wx.wxClientDC(self)
        # set device origin according to scroll position                
        self.PrepareDC(cdc)
        dc = wx.wxBufferedDC(cdc, self._buffer)
        return dc

    def OnMouseEvent(self, event):

        # this seems to work fine under windows.  If we don't do this, and the
        # mouse leaves the canvas, the rubber band remains and no selection
        # is made.
        if event.ButtonDown():
            if not self.HasCapture():
                self.CaptureMouse()
                
        elif event.ButtonUp():
            if self.HasCapture():
                self.ReleaseMouse()
        
        # these coordinates are relative to the visible part of the canvas
        ex, ey = event.GetX(), event.GetY()

        rx, ry = self.eventToRealCoords(ex, ey)

        # add the "real" coords to the event structure
        event.realX = rx
        event.realY = ry

        if self._previousRealCoords:
            self._mouseDelta = (rx - self._previousRealCoords[0],
                                ry - self._previousRealCoords[1])
{'fraction_non_alphanumeric': 0.08685104318292092, 'fraction_numerical': 0.006792819019893256, 'mean_word_length': 1.9142318567389256, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1658279', 'n_tokens_mistral': 1763, 'n_tokens_neox': 1694, 'n_words': 502}