Exemplo n.º 1
0
 def redo(self):
     layer = self.doc.layer_stack.deepget(self._layer_path)
     if not self._before:
         self._before = layer.save_snapshot()
     if self._after:
         layer.load_snapshot(self._after)
     else:
         layer.load_from_external_edit_tempfile(self._tmpfile)
         self._after = layer.save_snapshot()
Exemplo n.º 2
0
 def redo(self):
     layer = self.doc.layer_stack.deepget(self._layer_path)
     if not self._before:
         self._before = layer.save_snapshot()
     if self._after:
         layer.load_snapshot(self._after)
     else:
         layer.load_from_external_edit_tempfile(self._tmpfile)
         self._after = layer.save_snapshot()
Exemplo n.º 3
0
    def _check_recording_started(self):
        """Ensure command is in the recording phase"""
        assert not self._recording_finished
        if self._recording_started:
            return
        # Cache the layer being painted to. This is accessed frequently
        # during the painting phase.
        model = self.doc
        layer = model.layer_stack.deepget(self._layer_path)
        assert layer is not None, \
            "Layer with path %r not available" % (self._layer_path,)
        if not layer.get_paintable():
            logger.warning(
                "Brushwork: skipped non-paintable layer %r",
                layer,
            )
            return
        self._stroke_target_layer = layer

        assert self._sshot_before is None
        assert self._time_before is None
        assert self._stroke_seq is None
        self._sshot_before = layer.save_snapshot()
        self._time_before = model.unsaved_painting_time
        self._stroke_seq = lib.stroke.Stroke()
        self._stroke_seq.start_recording(model.brush)
        assert self._sshot_after is None
        self._recording_started = True
Exemplo n.º 4
0
    def _check_recording_started(self):
        """Ensure command is in the recording phase"""
        assert not self._recording_finished
        if self._recording_started:
            return
        # Cache the layer being painted to. This is accessed frequently
        # during the painting phase.
        model = self.doc
        layer = model.layer_stack.deepget(self._layer_path)
        assert layer is not None, \
            "Layer with path %r not available" % (self._layer_path,)
        if not layer.get_paintable():
            logger.warning(
                "Brushwork: skipped non-paintable layer %r",
                layer,
            )
            return
        self._stroke_target_layer = layer

        assert self._sshot_before is None
        assert self._time_before is None
        assert self._stroke_seq is None
        self._sshot_before = layer.save_snapshot()
        self._time_before = model.unsaved_painting_time
        self._stroke_seq = lib.stroke.Stroke()
        self._stroke_seq.start_recording(model.brush)
        assert self._sshot_after is None
        self._recording_started = True
Exemplo n.º 5
0
    def stop_recording(self, revert=False):
        """Ends the recording phase

        :param bool revert: revert any changes to the model
        :rtype: bool
        :returns: whether any changes were made

        When called with default arguments,
        this method makes the command ready to add to the command stack
        using the document model's do() method.
        If no changes were made, you can (and should)
        just discard the command instead.

        If `revert` is true,
        all changes made to the layer during recording
        will be rolled back,
        so that the layer has its original appearance and state.
        Reverted commands should be discarded.

        After this method is called,
        the `stroke_to()` method must not be called again.

        """
        self._check_recording_started()
        layer = self._stroke_target_layer
        self._stroke_target_layer = None  # prevent potential leak
        self._recording_finished = True
        if self._stroke_seq is None:
            # Unclear circumstances, but I've seen it happen
            # (unpaintable layers and visibility state toggling).
            # Perhaps _recording_started should be made synonymous with this?
            logger.warning(
                "No recorded stroke, but recording was started? "
                "Please report this glitch if you can reliably reproduce it."
            )
            return False  # nothing recorded, so nothing changed
        self._stroke_seq.stop_recording()
        if layer is None:
            return False  # wasn't suitable for painting, thus nothing changed
        if revert:
            assert self._sshot_before is not None
            logger.debug(
                "Brushwork: stop_recording: rollback %0.3fs",
                self._stroke_seq.total_painting_time,
            )
            layer.load_snapshot(self._sshot_before)
            return False  # nothing changed
        t0 = self._time_before
        self._time_after = t0 + self._stroke_seq.total_painting_time
        layer.add_stroke_shape(self._stroke_seq, self._sshot_before)
        self._sshot_after = layer.save_snapshot()
        self._sshot_after_applied = True  # changes happened before redo()
        tiles_changed = (not self._stroke_seq.empty)
        logger.debug(
            "Brushwork: stop_recording: %0.3fs, tiles_changed=%r",
            self._stroke_seq.total_painting_time,
            tiles_changed,
        )
        return tiles_changed
Exemplo n.º 6
0
 def update(self, brushinfo):
     """Retrace the last stroke with a new brush"""
     layer = self.doc.layer_stack.deepget(self._layer_path)
     layer.load_snapshot(self._sshot_before)
     stroke = self._stroke_seq.copy_using_different_brush(brushinfo)
     layer.render_stroke(stroke)
     self._stroke_seq = stroke
     layer.add_stroke_shape(stroke, self._sshot_before)
     self._sshot_after = layer.save_snapshot()
Exemplo n.º 7
0
    def stop_recording(self, revert=False):
        """Ends the recording phase

        :param bool revert: revert any changes to the model
        :rtype: bool
        :returns: whether any changes were made

        When called with default arguments,
        this method makes the command ready to add to the command stack
        using the document model's do() method.
        If no changes were made, you can (and should)
        just discard the command instead.

        If `revert` is true,
        all changes made to the layer during recording
        will be rolled back,
        so that the layer has its original appearance and state.
        Reverted commands should be discarded.

        After this method is called,
        the `stroke_to()` method must not be called again.

        """
        self._check_recording_started()
        layer = self._stroke_target_layer
        self._stroke_target_layer = None  # prevent potential leak
        self._recording_finished = True
        if self._stroke_seq is None:
            # Unclear circumstances, but I've seen it happen
            # (unpaintable layers and visibility state toggling).
            # Perhaps _recording_started should be made synonymous with this?
            logger.warning(
                "No recorded stroke, but recording was started? "
                "Please report this glitch if you can reliably reproduce it."
            )
            return False  # nothing recorded, so nothing changed
        self._stroke_seq.stop_recording()
        if layer is None:
            return False  # wasn't suitable for painting, thus nothing changed
        if revert:
            assert self._sshot_before is not None
            layer.load_snapshot(self._sshot_before)
            logger.debug("Reverted %r: tiles_changed=%r", self, False)
            return False  # nothing changed
        t0 = self._time_before
        self._time_after = t0 + self._stroke_seq.total_painting_time
        layer.add_stroke_shape(self._stroke_seq, self._sshot_before)
        self._sshot_after = layer.save_snapshot()
        self._sshot_after_applied = True  # changes happened before redo()
        tiles_changed = (not self._stroke_seq.empty)
        logger.debug(
            "Stopped recording %r: tiles_changed=%r",
            self, tiles_changed,
        )
        return tiles_changed
Exemplo n.º 8
0
 def update(self, brushinfo):
     """Retrace the last stroke with a new brush"""
     model = self.doc
     layer = model.layer_stack.deepget(self._layer_path)
     assert self._recording_finished, "Call stop_recording() first"
     assert self._sshot_after_applied, "command.Brushwork must be applied before being updated"
     layer.load_snapshot(self._sshot_before)
     stroke = self._stroke_seq.copy_using_different_brush(brushinfo)
     layer.render_stroke(stroke)
     self._stroke_seq = stroke
     layer.add_stroke_shape(stroke, self._sshot_before)
     self._sshot_after = layer.save_snapshot()
Exemplo n.º 9
0
 def update(self, brushinfo):
     """Retrace the last stroke with a new brush"""
     model = self.doc
     layer = model.layer_stack.deepget(self._layer_path)
     assert self._recording_finished, "Call stop_recording() first"
     assert self._sshot_after_applied, \
         "command.Brushwork must be applied before being updated"
     layer.load_snapshot(self._sshot_before)
     stroke = self._stroke_seq.copy_using_different_brush(brushinfo)
     layer.render_stroke(stroke)
     self._stroke_seq = stroke
     layer.add_stroke_shape(stroke, self._sshot_before)
     self._sshot_after = layer.save_snapshot()
Exemplo n.º 10
0
    def stop_recording(self, revert=False):
        """Ends the recording phase

        :param bool revert: revert any changes to the model
        :rtype: bool
        :returns: whether any changes were made

        When called with default arguments,
        this method makes the command ready to add to the command stack
        using the document model's do() method.
        If no changes were made, you can (and should)
        just discard the command instead.

        If `revert` is true,
        all changes made to the layer during recording
        will be rolled back,
        so that the layer has its original appearance and state.
        Reverted commands should be discarded.

        After this method is called,
        the `stroke_to()` method must not be called again.

        """
        self._check_recording_started()
        layer = self._stroke_target_layer
        self._stroke_target_layer = None  # prevent potential leak
        self._recording_finished = True
        self._stroke_seq.stop_recording()
        if layer is None:
            return False  # wasn't suitable for painting, thus nothing changed
        if revert:
            assert self._sshot_before is not None
            logger.debug(
                "Brushwork: stop_recording: rollback %0.3fs",
                self._stroke_seq.total_painting_time,
            )
            layer.load_snapshot(self._sshot_before)
            return False  # nothing changed
        t0 = self._time_before
        self._time_after = t0 + self._stroke_seq.total_painting_time
        layer.add_stroke_shape(self._stroke_seq, self._sshot_before)
        self._sshot_after = layer.save_snapshot()
        self._sshot_after_applied = True  # changes happened before redo()
        tiles_changed = (not self._stroke_seq.empty)
        logger.debug(
            "Brushwork: stop_recording: %0.3fs, tiles_changed=%r",
            self._stroke_seq.total_painting_time,
            tiles_changed,
        )
        return tiles_changed
Exemplo n.º 11
0
 def redo(self):
     """Performs, or re-performs after undo"""
     model = self.doc
     layer = model.layer_stack.deepget(self._layer_path)
     if self._stroke_seq is None:
         return
     assert self._stroke_seq.finished, "Call stop_recording() first"
     if self._sshot_after is None:
         t0 = self._time_before
         self._time_after = t0 + self._stroke_seq.total_painting_time
         layer.add_stroke_shape(self._stroke_seq, self._sshot_before)
         self._sshot_after = layer.save_snapshot()
     else:
         layer.load_snapshot(self._sshot_after)
     # Update painting time
     assert self._time_after is not None
     self.doc.unsaved_painting_time = self._time_after
Exemplo n.º 12
0
    def stroke_to(self, dtime, x, y, pressure, xtilt, ytilt):
        """Painting: forward a stroke position update to the model

        :param float dtime: Seconds since the last call to this method
        :param float x: Document X position update
        :param float y: Document Y position update
        :param float pressure: Pressure, ranging from 0.0 to 1.0
        :param float xtilt: X-axis tilt, ranging from -1.0 to 1.0
        :param float ytilt: Y-axis tilt, ranging from -1.0 to 1.0

        Stroke data is recorded at this level, but strokes are not
        autosplit here because that would involve the creation of a new
        Brushwork command on the CommandStack. Instead, callers should
        check `split_due` and split appropriately.

        An example of a GUI mode which does just this can be found in
        the complete MyPaint distribution in gui/.
        """
        # Model and layer being painted on. Called frequently during the
        # painting phase, so use a cache to avoid excessive layers tree
        # climbing.
        model = self.doc
        if self._layer_ref is None:
            layer = model.layer_stack.deepget(self._layer_path)
            if not layer.get_paintable():
                logger.debug("Skipped non-paintable layer %r", layer)
                return
            self._layer_ref = weakref.ref(layer)
        else:
            layer = self._layer_ref()
            if layer is None:
                logger.error("Layer was deleted while painting was in "
                             "progress: undo stack is probably broken now")
                self.split_due = True
                return
        if not self._stroke_seq:
            self._stroke_seq = lib.stroke.Stroke()
            self._time_before = model.unsaved_painting_time
            self._sshot_before = layer.save_snapshot()
            self._stroke_seq.start_recording(model.brush)
        brush = model.brush
        self._stroke_seq.record_event(dtime, x, y, pressure,
                                      xtilt, ytilt)
        self.split_due = layer.stroke_to(brush, x, y, pressure,
                                         xtilt, ytilt, dtime)
        self._last_pos = (x, y, xtilt, ytilt)
Exemplo n.º 13
0
 def redo(self):
     layer = self.doc.layer_stack.current
     self.before = layer.save_snapshot()
     layer.load_from_surface(self.surface)
Exemplo n.º 14
0
 def redo(self):
     layer = self.doc.layer_stack.current
     self._before = layer.save_snapshot()
     layer.clear()
Exemplo n.º 15
0
 def redo(self):
     layer = self.doc.layer_stack.current
     self.before = layer.save_snapshot()
     frame = self.doc.get_frame()
     layer.trim(frame)
Exemplo n.º 16
0
 def redo(self):
     layer = self.doc.layer_stack.current
     self.before = layer.save_snapshot()
     frame = self.doc.get_frame()
     layer.trim(frame)
Exemplo n.º 17
0
 def redo(self):
     layer = self.doc.layer_stack.current
     self._before = layer.save_snapshot()
     layer.clear()
Exemplo n.º 18
0
 def redo(self):
     layer = self.doc.layer
     self.before = layer.save_snapshot()
     layer.load_from_surface(self.surface)