-
What would be the easiest way to handle support for undo/redo? I tried saving the Mantis.Config object from an existing CropViewController object and then passing it in to Mantis.setupCropViewController() on an existing CropViewController object and also to a new version in the Mantis.cropViewController init call. But this does not update the UI for the previous state. Is there a single function that will rebuild the UI based on the current state in the config object? Thanks, Rick |
Beta Was this translation helpful? Give feedback.
Replies: 17 comments 30 replies
-
Currently Mantis does not save view status into the config object, so it doesn't support undo/redo as you mentioned. |
Beta Was this translation helpful? Give feedback.
-
I have undo/redo support working for all transformations except 90 degree rotations: I took the logic from CropView.processPresetTransformation() for the .presetInfo case, and created a function for the CropViewProtocol called applyTransform() which contains this logic. Then I take a snapshot of the Transformation object before and after a transformation by calling cropView.makeTransformation(), and send both snapshots back to my delegate. I can then undo/redo the UI state by calling back in to a new cropViewController delegate which will call the applyTransform() function. It can successfully undo/redo the UI state for all transformations except a 90 degree rotation. Both undo and redo of a 90 degree rotation transform fail. It works for:
func applyTransform(byTransformInfo transformation: Transformation, isUpdateRotationControlView: Bool = true) {
Any ideas what is missing? Is it the rotation type or the rotations in the viewModel? |
Beta Was this translation helpful? Give feedback.
-
I just added the ImageRotationType state to the Transformation object. If I then set the rotationType in the viewModel from the new applyTransform() function, I can successfully undo a 90 degree rotation. Redo of a 90 degree rotation still fails. |
Beta Was this translation helpful? Give feedback.
-
func applyTransform(byTransformInfo transformation: Transformation, isUpdateRotationControlView: Bool = true) {
|
Beta Was this translation helpful? Give feedback.
-
@rickshane |
Beta Was this translation helpful? Give feedback.
-
Here is a zip file of the project. Run the xcode project from the /Examples folder and select the "Embedded" version of the cropViewController. You should see yellow "Undo" and "Redo" buttons on the left side of the toolbar. Thanks, Rick |
Beta Was this translation helpful? Give feedback.
-
It also looks like undoing an Aspect Ratio change back to "Freeform" (unlocked) will not remember the aspect ratio that was set prior to changing to the "Freeform" (unlocked) . Some additional state for that is needed somewhere to match the crop rect frame. |
Beta Was this translation helpful? Give feedback.
-
@rickshane |
Beta Was this translation helpful? Give feedback.
-
That doesn't work for redo (I get same results as before). I also tried setting "viewModel.rotationType = .none" at beginning of applyTransform() and then "viewModel.rotationType = transformation.rotationType" as the last line of applyTransform() after the two calls to "transform()". The rotationType state will still need to be restored, becase subsequent transforms sometimes look at rotationType.isRotatedByMultiple180 |
Beta Was this translation helpful? Give feedback.
-
@rickshane // The second transform is for adjusting the scale of transformInfo
let adjustScale = (viewModel.cropBoxFrame.width / viewModel.cropBoxOriginFrame.width)
/ (transformation.maskFrame.width / transformation.initialMaskFrame.width)
newTransform.scale *= adjustScale |
Beta Was this translation helpful? Give feedback.
-
I will also need to store flipOddTimes to correctly undo a flip that occurred after a rotation. I will then work on refactoring into new CropState object that stores Transformation plus all the other state needed for undo/redo. But should rotationType stay in the Transformation object along with radians? |
Beta Was this translation helpful? Give feedback.
-
I notice there is a big bug in the control that is affecting Undo/Redo logic. If I touch down just outside the crop rectangle, it causes the grid to move, even though I have not moved my finger. At a high level, this always prevents pulling the crop grid to the edge of the image. This is the biggest bug I have noticed since using this control. This affects undo/redo because if I click just outside the lower right anchor point, it causes handle to move and inside the function "imageStatusChanged" there is a check on the point, "getImageRightBottomAnchorPoint", and since this moved, this function returns true which causes a new transform record to be pushed on to the undo stack. |
Beta Was this translation helpful? Give feedback.
-
Here is the new version of the project with the Equatable struct versions of CropState and Transformation. |
Beta Was this translation helpful? Give feedback.
-
This latest version has support for undo/redo of the "Reset" button. There are now two different types of Transform records pushed on the stack - "Transform" and "ResetTransforms". It also disables/enables the undo/redo/reset buttons based on the state of the UndoManager and Transform Stack. I have also hooked up the "Undo" + "Redo" + "Revert to Original" menu commands in Catalyst using the AppDelegate.buildMenu function. |
Beta Was this translation helpful? Give feedback.
-
This version has the fix for Catalyst touchesMoved bug. I have added clockwiseRotate, and both flip buttons to tool bar for testing undo/redo. |
Beta Was this translation helpful? Give feedback.
-
I just sent a pull request for this feature. |
Beta Was this translation helpful? Give feedback.
-
I will close this as "Answered". |
Beta Was this translation helpful? Give feedback.
I will close this as "Answered".