<commit_before># -*- coding: utf-8 -*-

"""Pan & zoom transform."""


#------------------------------------------------------------------------------
# Imports
#------------------------------------------------------------------------------

import math

import numpy as np


#------------------------------------------------------------------------------
# PanZoom class
#------------------------------------------------------------------------------

class PanZoom(object):
    """Pan & zoom transform.

    The panzoom transform allow to translate and scale an object in the window
    space coordinate (2D). This means that whatever point you grab on the
    screen, it should remains under the mouse pointer. Zoom is realized using
    the mouse scroll and is always centered on the mouse pointer.

    You can also control programmatically the transform using:

    * aspect: control the aspect ratio of the whole scene
    * pan   : translate the scene to the given 2D coordinates
    * zoom  : set the zoom level (centered at current pan coordinates)
    * zmin  : minimum zoom level
    * zmax  : maximum zoom level

    Interactivity
    -------------

    Pan:

    * Mouse : click and move (drag movement)
    * Keyboard : arrows

    Zoom:

    * Mouse : wheel
    * Keyboard : + and -

    Reset:

    * Keyboard : R

    """

    def __init__(self, aspect=1.0, pan=(0.0, 0.0), zoom=1.0,
                 zmin=1e-5, zmax=1e5,
                 xmin=None, xmax=None,
                 ymin=None, ymax=None,
                 ):
        """
        Initialize the transform.

        Parameters
        ----------

        aspect : float (default is None)
           Indicate what is the aspect ratio of the object displayed. This is
           necessary to convert pixel drag move in object space coordinates.

        pan : float, float (default is 0, 0)
           Initial translation

        zoom : float, float (default is 1)
           Initial zoom level

        zmin : float (default is 0.01)
           Minimum zoom level

        zmax : float (default is 1000)
           Maximum zoom level
        """

        self._aspect = aspect
        self._pan = np.array(pan)
        self._zoom = zoom
        self._zmin = zmin
        self._zmax = zmax
        self._xmin = xmin
        self._xmax = xmax
        self._ymin = ymin
        self._ymax = ymax

        self._zoom_to_pointer = True
        self._n_rows = 1

        # Canvas this transform is attached to
        self._canvas = None
        self._canvas_aspect = np.ones(2)
        self._width = 1
        self._height = 1

        # Programs using this transform
        self._u_pan = pan
        self._u_zoom = np.array([zoom, zoom])
        self._programs = []

    @property
    def zoom_to_pointer(self):
        return self._zoom_to_pointer

    @zoom_to_pointer.setter
    def zoom_to_pointer(self, value):
        self._zoom_to_pointer = value

    @property
    def n_rows(self):
        return self._n_rows

    @n_rows.setter
    def n_rows(self, value):
        self._n_rows = value

    @property
    def is_attached(self):
        """Whether transform is attached to a canvas."""
        return self._canvas is not None

    @property
    def aspect(self):
        """Aspect (width/height)."""
        return self._aspect

    @aspect.setter
    def aspect(self, value):
        """Aspect (width/height)."""
        self._aspect = value

    @property
    def pan(self):
        """Pan translation."""
        return self._pan

    @pan.setter
    def pan(self, value):
        """Pan translation."""
        self._pan = np.asarray(value)

        # Constrain bounding box.
        s = 1. / self._zoom
        if self._xmin is not None:
            self._pan[0] = max(self._pan[0], self._xmin + s)
        if self._xmax is not None:
            self._pan[0] = min(self._pan[0], self._xmax - s)

        if self._ymin is not None:
            self._pan[1] = max(self._pan[1], self._ymin + s)
        if self._ymax is not None:
            self._pan[1] = min(self._pan[1], self._ymax - s)

        self._u_pan = self._pan
        for program in self._programs:
            program["u_pan"] = self._u_pan

    @property
    def zoom(self):
        """Zoom level."""
        return self._zoom

    @zoom.setter
    def zoom(self, value):
        """Zoom level."""

        self._zoom = max(min(value, self._zmax), self._zmin)
        if not self.is_attached:
            return

        aspect = np.array([1.0, 1.0])
        if self._aspect is not None:
            aspect = self._canvas_aspect * self._aspect

        self._u_zoom = self._zoom * aspect
        for program in self._programs:
            program["u_zoom"] = self._u_zoom

    # xmin/xmax
    # -------------------------------------------------------------------------

    @property
    def xmin(self):
        return self._xmin

    @xmin.setter
    def xmin(self, value):
        if self._xmax is not None:
            self._xmin = min(value, self._xmax)
        else:
            self._xmin = value

    @property
    def xmax(self):
        return self._xmax

    @xmax.setter
    def xmax(self, value):
        if self._xmin is not None:<commit_msg>WIP: constrain bounding box in trace view.<commit_after># -*- coding: utf-8 -*-

"""Pan & zoom transform."""


#------------------------------------------------------------------------------
# Imports
#------------------------------------------------------------------------------

import math

import numpy as np


#------------------------------------------------------------------------------
# PanZoom class
#------------------------------------------------------------------------------

class PanZoom(object):
    """Pan & zoom transform.

    The panzoom transform allow to translate and scale an object in the window
    space coordinate (2D). This means that whatever point you grab on the
    screen, it should remains under the mouse pointer. Zoom is realized using
    the mouse scroll and is always centered on the mouse pointer.

    You can also control programmatically the transform using:

    * aspect: control the aspect ratio of the whole scene
    * pan   : translate the scene to the given 2D coordinates
    * zoom  : set the zoom level (centered at current pan coordinates)
    * zmin  : minimum zoom level
    * zmax  : maximum zoom level

    Interactivity
    -------------

    Pan:

    * Mouse : click and move (drag movement)
    * Keyboard : arrows

    Zoom:

    * Mouse : wheel
    * Keyboard : + and -

    Reset:

    * Keyboard : R

    """

    def __init__(self, aspect=1.0, pan=(0.0, 0.0), zoom=1.0,
                 zmin=1e-5, zmax=1e5,
                 xmin=None, xmax=None,
                 ymin=None, ymax=None,
                 ):
        """
        Initialize the transform.

        Parameters
        ----------

        aspect : float (default is None)
           Indicate what is the aspect ratio of the object displayed. This is
           necessary to convert pixel drag move in object space coordinates.

        pan : float, float (default is 0, 0)
           Initial translation

        zoom : float, float (default is 1)
           Initial zoom level

        zmin : float (default is 0.01)
           Minimum zoom level

        zmax : float (default is 1000)
           Maximum zoom level
        """

        self._aspect = aspect
        self._pan = np.array(pan)
        self._zoom = zoom
        self._zmin = zmin
        self._zmax = zmax
        self._xmin = xmin
        self._xmax = xmax
        self._ymin = ymin
        self._ymax = ymax

        self._zoom_to_pointer = True
        self._n_rows = 1

        # Canvas this transform is attached to
        self._canvas = None
        self._canvas_aspect = np.ones(2)
        self._width = 1
        self._height = 1

        # Programs using this transform
        self._u_pan = pan
        self._u_zoom = np.array([zoom, zoom])
        self._programs = []

    @property
    def zoom_to_pointer(self):
        return self._zoom_to_pointer

    @zoom_to_pointer.setter
    def zoom_to_pointer(self, value):
        self._zoom_to_pointer = value

    @property
    def n_rows(self):
        return self._n_rows

    @n_rows.setter
    def n_rows(self, value):
        self._n_rows = value

    @property
    def is_attached(self):
        """Whether transform is attached to a canvas."""
        return self._canvas is not None

    @property
    def aspect(self):
        """Aspect (width/height)."""
        return self._aspect

    @aspect.setter
    def aspect(self, value):
        """Aspect (width/height)."""
        self._aspect = value

    def _constrain_pan(self):
        """Constrain bounding box."""
        if self._xmin is not None and self._xmax is not None:
            p0 = self._xmin + 1. / self._u_zoom[0]
            p1 = self._xmax - 1. / self._u_zoom[0]
            p0, p1 = min(p0, p1), max(p0, p1)
            self._pan[0] = np.clip(self._pan[0], p0, p1)

        if self._ymin is not None and self._ymax is not None:
            p0 = self._ymin + 1. / self._u_zoom[1]
            p1 = self._ymax - 1. / self._u_zoom[1]
            p0, p1 = min(p0, p1), max(p0, p1)
            self._pan[1] = np.clip(self._pan[1], p0, p1)

    def _constrain_zoom(self):
        """Constrain bounding box."""
        if self._xmin is not None:
            self._u_zoom[0] = max(self._u_zoom[0],
                                  1. / (self._pan[0] - self._xmin))
        if self._xmax is not None:
            self._u_zoom[0] = max(self._u_zoom[0],
                                  1. / (self._xmax - self._pan[0]))

        if self._ymin is not None:
            self._u_zoom[1] = max(self._u_zoom[1],
                                  1. / (self._pan[1] - self._ymin))
        if self._ymax is not None:
            self._u_zoom[1] = max(self._u_zoom[1],
                                  1. / (self._ymax - self._pan[1]))

    @property
    def pan(self):
        """Pan translation."""
        return self._pan

    @pan.setter
    def pan(self, value):
        """Pan translation."""
        self._pan = np.asarray(value)

        self._constrain_pan()
        self._u_pan = self._pan
        for program in self._programs:
            program["u_pan"] = self._u_pan

    @property
    def zoom(self):
        """Zoom level."""
        return self._zoom

    @zoom.setter
    def zoom(self, value):
        """Zoom level."""
        self._zoom = max(min(value, self._zmax), self._zmin)
        if not self.is_attached:
            return

        aspect = np.array([1.0, 1.0])
        if self._aspect is not None:
            aspect = self._canvas_aspect * self._aspect

        self._u_zoom = self._zoom * aspect

        # Constrain bounding box.
        self._constrain_pan()
        self._constrain_zoom()

        for program in self._programs:
            program["u_pan"] = self._u_pan
        for program in self._programs:
            program["u_zoom"] = self._u_zoom

    # xmin/xmax
    # -------------------------------------------------------------------------

    @property
    def xmin(self):
        return self._xmin

    @xmin.setter
    def xmin(self, value):
        if self._xmax is not None:
            self._xmin = min(value, self._xmax)
        else:
            self._xmin = value

    @property
    def xmax(self):
        return self._xmax

    @xmax.setter
    def xmax(self, value):
        if self._xmin is not None:
{'fraction_non_alphanumeric': 0.1633310128785242, 'fraction_numerical': 0.010703097807170206, 'mean_word_length': 1.4453191489361703, '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': '769099', 'n_tokens_mistral': 3375, 'n_tokens_neox': 3217, 'n_words': 973}