Ejemplo n.º 1
0
class CallbackMixin(object):
    """
    A mixin that provides a utility for attaching callback
    functions to methods
    """
    def __init__(self):
        self._callbacks = CallbackContainer()

    def add_callback(self, function):
        self._callbacks.append(function)

    def remove_callback(self, function):
        self._callbacks.remove(function)

    def notify(self, *args, **kwargs):
        for func in self._callbacks:
            func(*args, **kwargs)
Ejemplo n.º 2
0
class CallbackMixin(object):

    """
    A mixin that provides a utility for attaching callback
    functions to methods
    """

    def __init__(self):
        self._callbacks = CallbackContainer()

    def add_callback(self, function):
        self._callbacks.append(function)

    def remove_callback(self, function):
        self._callbacks.remove(function)

    def notify(self, *args, **kwargs):
        for func in self._callbacks:
            func(*args, **kwargs)
Ejemplo n.º 3
0
 def __init__(self):
     self.artists = []
     self.empty_callbacks = CallbackContainer()
     self.change_callbacks = CallbackContainer()
     self._ignore_empty_callbacks = False
     self._ignore_change_callbacks = False
Ejemplo n.º 4
0
class LayerArtistContainer(object):
    """A collection of LayerArtists"""
    def __init__(self):
        self.artists = []
        self.empty_callbacks = CallbackContainer()
        self.change_callbacks = CallbackContainer()
        self._ignore_empty_callbacks = False
        self._ignore_change_callbacks = False

    def on_empty(self, func):
        """
        Register a callback function that should be invoked when
        this container is emptied
        """
        self.empty_callbacks.append(func)

    def on_changed(self, func):
        """
        Register a callback function that should be invoked when
        this container's elements change
        """
        self.change_callbacks.append(func)

    def _duplicate(self, artist):
        for a in self.artists:
            if type(a) == type(artist) and a.layer is artist.layer:
                return True
        return False

    def append(self, artist):
        """Add a LayerArtist to this collection"""
        self.artists.append(artist)
        artist.zorder = max(a.zorder for a in self.artists) + 1
        self._notify()

    def remove(self, artist):
        """Remove a LayerArtist from this collection

        :param artist: The artist to remove
        :type artist: :class:`LayerArtistBase`
        """
        if artist in self.artists:
            self.artists.remove(artist)
            artist.remove()
            self._notify()

    def clear(self):
        """
        Remove all layer artists from this collection
        """
        for artist in self.artists:
            artist.remove()
        if six.PY2:
            self.artists[:] = []
        else:
            self.artists.clear()

    def clear_callbacks(self):
        """
        Remove all callbacks
        """
        self.empty_callbacks.clear()
        self.change_callbacks.clear()

    def _notify(self):

        if not self._ignore_change_callbacks:
            for cb in self.change_callbacks:
                cb()

        if not self._ignore_empty_callbacks and len(self) == 0:
            for cb in self.empty_callbacks:
                cb()

    def pop(self, layer):
        """Remove all artists associated with a layer"""
        to_remove = [a for a in self.artists if a.layer is layer]
        for r in to_remove:
            self.remove(r)
        return to_remove

    @property
    def layers(self):
        """A list of the unique layers in the container"""
        return list(set([a.layer for a in self.artists]))

    @contextmanager
    def ignore_empty(self):
        """
        A context manager that temporarily disables calling callbacks if
        container is empty.
        """
        try:
            self._ignore_empty_callbacks = True
            yield
        finally:
            self._ignore_empty_callbacks = False

    @contextmanager
    def ignore_change(self):
        """
        A context manager that temporarily disables calling callbacks if
        container is changed.
        """
        try:
            self._ignore_change_callbacks = True
            yield
        finally:
            self._ignore_change_callbacks = False

    @contextmanager
    def ignore_callbacks(self):
        try:
            self._ignore_change_callbacks = True
            self._ignore_empty_callbacks = True
            yield
        finally:
            self._ignore_change_callbacks = False
            self._ignore_empty_callbacks = False

    def __len__(self):
        return len(self.artists)

    def __iter__(self):
        return iter(sorted(self.artists, key=lambda x: x.zorder))

    def __contains__(self, item):
        return any(item is a.layer for a in self.artists)

    def __getitem__(self, layer):
        if isinstance(layer, int):
            return self.artists[layer]
        return [a for a in self.artists if a.layer is layer]
Ejemplo n.º 5
0
 def __init__(self):
     self._callbacks = CallbackContainer()
Ejemplo n.º 6
0
 def __init__(self):
     self.artists = []
     self.empty_callbacks = CallbackContainer()
     self.change_callbacks = CallbackContainer()
     self._ignore_callbacks = False
Ejemplo n.º 7
0
class LayerArtistContainer(object):

    """A collection of LayerArtists"""

    def __init__(self):
        self.artists = []
        self.empty_callbacks = CallbackContainer()
        self.change_callbacks = CallbackContainer()
        self._ignore_callbacks = False

    def on_empty(self, func):
        """
        Register a callback function that should be invoked when
        this container is emptied
        """
        self.empty_callbacks.append(func)

    def on_changed(self, func):
        """
        Register a callback function that should be invoked when
        this container's elements change
        """
        self.change_callbacks.append(func)

    def _duplicate(self, artist):
        for a in self.artists:
            if type(a) == type(artist) and a.layer is artist.layer:
                return True
        return False

    def append(self, artist):
        """Add a LayerArtist to this collection"""
        self.artists.append(artist)
        artist.zorder = max(a.zorder for a in self.artists) + 1
        self._notify()

    def remove(self, artist):
        """Remove a LayerArtist from this collection

        :param artist: The artist to remove
        :type artist: :class:`LayerArtistBase`
        """
        if artist in self.artists:
            self.artists.remove(artist)
            artist.remove()
            self._notify()

    def clear(self):
        """
        Remove all layer artists from this collection
        """
        for artist in self.artists:
            artist.remove()
        if six.PY2:
            self.artists[:] = []
        else:
            self.artists.clear()

    def clear_callbacks(self):
        """
        Remove all callbacks
        """
        self.empty_callbacks.clear()
        self.change_callbacks.clear()

    def _notify(self):
        if self._ignore_callbacks:
            return

        for cb in self.change_callbacks:
            cb()

        if len(self) == 0:
            for cb in self.empty_callbacks:
                cb()

    def pop(self, layer):
        """Remove all artists associated with a layer"""
        to_remove = [a for a in self.artists if a.layer is layer]
        for r in to_remove:
            self.remove(r)
        return to_remove

    @property
    def layers(self):
        """A list of the unique layers in the container"""
        return list(set([a.layer for a in self.artists]))

    @contextmanager
    def ignore_empty(self):
        """A context manager that temporarily disables calling callbacks if container is emptied"""
        try:
            self._ignore_callbacks = True
            yield
        finally:
            self._ignore_callbacks = False

    def __len__(self):
        return len(self.artists)

    def __iter__(self):
        return iter(sorted(self.artists, key=lambda x: x.zorder))

    def __contains__(self, item):
        return any(item is a.layer for a in self.artists)

    def __getitem__(self, layer):
        if isinstance(layer, int):
            return self.artists[layer]
        return [a for a in self.artists if a.layer is layer]
Ejemplo n.º 8
0
 def __init__(self):
     self._callbacks = CallbackContainer()