-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
186 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
87 changes: 87 additions & 0 deletions
87
src/main/java/com/github/creme332/controller/canvas/transform/AbstractTransformer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
package com.github.creme332.controller.canvas.transform; | ||
|
||
import java.awt.event.MouseAdapter; | ||
import java.awt.event.MouseEvent; | ||
import java.awt.geom.Point2D; | ||
import java.util.List; | ||
|
||
import com.github.creme332.model.AppState; | ||
import com.github.creme332.model.CanvasModel; | ||
import com.github.creme332.model.Mode; | ||
import com.github.creme332.model.ShapeWrapper; | ||
import com.github.creme332.view.Canvas; | ||
|
||
public abstract class AbstractTransformer { | ||
protected Canvas canvas; | ||
protected CanvasModel canvasModel; | ||
private AppState app; | ||
|
||
protected AbstractTransformer(AppState app, Canvas canvas) { | ||
this.app = app; | ||
this.canvas = canvas; | ||
this.canvasModel = app.getCanvasModel(); | ||
|
||
canvas.addMouseListener(new MouseAdapter() { | ||
@Override | ||
public void mousePressed(MouseEvent e) { | ||
if (!shouldDraw()) | ||
return; | ||
Point2D polyspaceMousePosition = canvasModel.toPolySpace(e.getPoint()); | ||
int selectedShapeIndex = getSelectedShapeIndex(polyspaceMousePosition); | ||
if (selectedShapeIndex < 0) | ||
return; | ||
handleShapeSelection(selectedShapeIndex); | ||
} | ||
}); | ||
} | ||
|
||
/** | ||
* | ||
* @param polyspaceMousePosition Coordinate of point lying inside shape | ||
* @return Index of first shape that contains polyspaceMousePosition. -1 if no | ||
* such shape found. | ||
*/ | ||
private int getSelectedShapeIndex(Point2D polyspaceMousePosition) { | ||
List<ShapeWrapper> shapes = canvasModel.getShapeManager().getShapes(); | ||
for (int i = 0; i < shapes.size(); i++) { | ||
ShapeWrapper wrapper = shapes.get(i); | ||
if (wrapper.getShape().contains(polyspaceMousePosition)) { | ||
return i; | ||
} | ||
} | ||
return -1; | ||
} | ||
|
||
/** | ||
* | ||
* @return Current canvas mode | ||
*/ | ||
public Mode getCanvasMode() { | ||
return app.getMode(); | ||
} | ||
|
||
/** | ||
* This method only gets called when shouldDraw() returns true and mouse | ||
* clicked. | ||
* | ||
* @param shapeIndex A valid index representing selected shape | ||
*/ | ||
public abstract void handleShapeSelection(int shapeIndex); | ||
|
||
/** | ||
* Determines whether current controller should be allowed to handle event or | ||
* not. | ||
* | ||
* @return | ||
*/ | ||
public abstract boolean shouldDraw(); | ||
|
||
/** | ||
* Reset current controller to its initial state. For example, this method will | ||
* be invoked when mode changes while drawing was ongoing. | ||
*/ | ||
public void disposePreview() { | ||
// delete any preview shape | ||
canvasModel.getShapeManager().setShapePreview(null); | ||
} | ||
} |
95 changes: 95 additions & 0 deletions
95
src/main/java/com/github/creme332/controller/canvas/transform/Translator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package com.github.creme332.controller.canvas.transform; | ||
|
||
import java.awt.Shape; | ||
import java.awt.geom.AffineTransform; | ||
import java.awt.geom.Point2D; | ||
import java.util.List; | ||
|
||
import javax.swing.JLabel; | ||
import javax.swing.JOptionPane; | ||
import javax.swing.JPanel; | ||
import javax.swing.JTextField; | ||
|
||
import com.github.creme332.model.AppState; | ||
import com.github.creme332.model.Mode; | ||
import com.github.creme332.model.ShapeWrapper; | ||
import com.github.creme332.view.Canvas; | ||
|
||
public class Translator extends AbstractTransformer { | ||
|
||
public Translator(AppState app, Canvas canvas) { | ||
super(app, canvas); | ||
} | ||
|
||
@Override | ||
public void handleShapeSelection(int shapeIndex) { | ||
/** | ||
* A copy of the shape selected | ||
*/ | ||
final ShapeWrapper selectedWrapperCopy = canvasModel.getShapeManager().getShapes().get(shapeIndex); | ||
|
||
// request user for translation vector | ||
final Point2D translationVector = requestTranslationVector(); | ||
|
||
// apply transformation on shape | ||
final AffineTransform transform = new AffineTransform(); | ||
transform.translate(translationVector.getX(), translationVector.getY()); | ||
final Shape transformedShape = transform.createTransformedShape(selectedWrapperCopy.getShape()); | ||
|
||
// save transformed shape | ||
selectedWrapperCopy.setShape(transformedShape); | ||
canvasModel.getShapeManager().editShape(shapeIndex, selectedWrapperCopy); | ||
|
||
// translate plotted points | ||
final List<Point2D> originalPlottedPoints = selectedWrapperCopy.getPlottedPoints(); | ||
for (int i = 0; i < originalPlottedPoints.size(); i++) { | ||
Point2D oldPoint = originalPlottedPoints.get(i); | ||
originalPlottedPoints.set(i, | ||
new Point2D.Double(oldPoint.getX() + translationVector.getX(), | ||
oldPoint.getY() + translationVector.getY())); | ||
} | ||
|
||
// repaint canvas | ||
canvas.repaint(); | ||
} | ||
|
||
@Override | ||
public boolean shouldDraw() { | ||
return getCanvasMode() == Mode.TRANSLATION; | ||
} | ||
|
||
/** | ||
* Asks user to enter the radii for the ellipse. If input values are invalid | ||
* or if the operation is cancelled, null is returned. | ||
* | ||
* @return array with radii [rx, ry] | ||
*/ | ||
private Point2D requestTranslationVector() { | ||
final Point2D zeroVector = new Point2D.Double(0, 0); | ||
|
||
JTextField rxField = new JTextField(5); | ||
JTextField ryField = new JTextField(5); | ||
JPanel panel = new JPanel(); | ||
panel.add(new JLabel("X:")); | ||
panel.add(rxField); | ||
panel.add(new JLabel("Y:")); | ||
panel.add(ryField); | ||
|
||
int result = JOptionPane.showConfirmDialog(null, panel, "Enter translation vector", | ||
JOptionPane.OK_CANCEL_OPTION, | ||
JOptionPane.PLAIN_MESSAGE); | ||
|
||
// Request focus again otherwise keyboard shortcuts will not work | ||
canvas.getTopLevelAncestor().requestFocus(); | ||
|
||
if (result == JOptionPane.OK_OPTION) { | ||
try { | ||
return new Point2D.Double(Integer.parseInt(rxField.getText()), Integer.parseInt(ryField.getText())); | ||
} catch (NumberFormatException e) { | ||
return zeroVector; | ||
} | ||
} | ||
return zeroVector; | ||
} | ||
|
||
} |