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()
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
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
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()
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
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()
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()
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
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
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)
def redo(self): layer = self.doc.layer_stack.current self.before = layer.save_snapshot() layer.load_from_surface(self.surface)
def redo(self): layer = self.doc.layer_stack.current self._before = layer.save_snapshot() layer.clear()
def redo(self): layer = self.doc.layer_stack.current self.before = layer.save_snapshot() frame = self.doc.get_frame() layer.trim(frame)
def redo(self): layer = self.doc.layer self.before = layer.save_snapshot() layer.load_from_surface(self.surface)