mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-17 08:55:05 -04:00
copy is now implemented using the common ctrl-c and ctrl-v.
It is possible to copy from one window to an other.
This commit is contained in:
parent
d468a8d576
commit
8471ff84f3
@ -19,6 +19,9 @@ import de.neemann.gui.ToolTipAction;
|
|||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.awt.datatransfer.Clipboard;
|
||||||
|
import java.awt.datatransfer.DataFlavor;
|
||||||
|
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.MouseAdapter;
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
@ -27,6 +30,7 @@ import java.awt.geom.AffineTransform;
|
|||||||
import java.awt.geom.NoninvertibleTransformException;
|
import java.awt.geom.NoninvertibleTransformException;
|
||||||
import java.awt.geom.Point2D;
|
import java.awt.geom.Point2D;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@ -42,7 +46,6 @@ public class CircuitComponent extends JComponent {
|
|||||||
private static final String DEL_ACTION = "myDelAction";
|
private static final String DEL_ACTION = "myDelAction";
|
||||||
|
|
||||||
private final ElementLibrary library;
|
private final ElementLibrary library;
|
||||||
private final ShapeFactory shapeFactory;
|
|
||||||
private final SavedListener parentsSavedListener;
|
private final SavedListener parentsSavedListener;
|
||||||
private final HashSet<Drawable> highLighted;
|
private final HashSet<Drawable> highLighted;
|
||||||
private final ToolTipAction deleteAction;
|
private final ToolTipAction deleteAction;
|
||||||
@ -53,14 +56,15 @@ public class CircuitComponent extends JComponent {
|
|||||||
private final MouseControllerWire mouseWire;
|
private final MouseControllerWire mouseWire;
|
||||||
private final MouseControllerSelect mouseSelect;
|
private final MouseControllerSelect mouseSelect;
|
||||||
private final MouseControllerMoveSelected mouseMoveSelected;
|
private final MouseControllerMoveSelected mouseMoveSelected;
|
||||||
private final MouseControllerCopySelected mouseCopySelected;
|
|
||||||
private final MouseController mouseRun;
|
private final MouseController mouseRun;
|
||||||
|
private final MouseControllerInsertCopied mouseInsertList;
|
||||||
private final Cursor moveCursor;
|
private final Cursor moveCursor;
|
||||||
|
|
||||||
private Circuit circuit;
|
private Circuit circuit;
|
||||||
private MouseController activeMouseController;
|
private MouseController activeMouseController;
|
||||||
private AffineTransform transform = new AffineTransform();
|
private AffineTransform transform = new AffineTransform();
|
||||||
private Observer manualChangeObserver;
|
private Observer manualChangeObserver;
|
||||||
|
private Vector lastMousePos;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance
|
* Creates a new instance
|
||||||
@ -70,10 +74,42 @@ public class CircuitComponent extends JComponent {
|
|||||||
*/
|
*/
|
||||||
public CircuitComponent(ElementLibrary library, ShapeFactory shapeFactory, SavedListener parentsSavedListener) {
|
public CircuitComponent(ElementLibrary library, ShapeFactory shapeFactory, SavedListener parentsSavedListener) {
|
||||||
this.library = library;
|
this.library = library;
|
||||||
this.shapeFactory = shapeFactory;
|
|
||||||
this.parentsSavedListener = parentsSavedListener;
|
this.parentsSavedListener = parentsSavedListener;
|
||||||
highLighted = new HashSet<>();
|
highLighted = new HashSet<>();
|
||||||
|
|
||||||
|
AbstractAction copyAction = new AbstractAction("Copy") {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
if (activeMouseController instanceof MouseControllerSelect) {
|
||||||
|
MouseControllerSelect mcs = ((MouseControllerSelect) activeMouseController);
|
||||||
|
ArrayList<Moveable> elements = circuit.getElementsToCopy(Vector.min(mcs.corner1, mcs.corner2), Vector.max(mcs.corner1, mcs.corner2), shapeFactory);
|
||||||
|
Clipboard clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||||
|
clpbrd.setContents(new CircuitTransferable(elements), null);
|
||||||
|
removeHighLighted();
|
||||||
|
mouseNormal.activate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
AbstractAction pasteAction = new AbstractAction("Paste") {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
Clipboard clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||||
|
try {
|
||||||
|
Object data = clpbrd.getData(DataFlavor.stringFlavor);
|
||||||
|
if (data instanceof String) {
|
||||||
|
Vector posVector = getPosVector(lastMousePos.x, lastMousePos.y);
|
||||||
|
ArrayList<Moveable> elements = CircuitTransferable.createList(data, shapeFactory, posVector);
|
||||||
|
if (elements != null) {
|
||||||
|
mouseInsertList.activate(elements, posVector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (UnsupportedFlavorException | IOException e1) {
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
deleteAction = new ToolTipAction(Lang.get("menu_delete"), ICON_DELETE) {
|
deleteAction = new ToolTipAction(Lang.get("menu_delete"), ICON_DELETE) {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
@ -81,9 +117,13 @@ public class CircuitComponent extends JComponent {
|
|||||||
}
|
}
|
||||||
}.setToolTip(Lang.get("menu_delete_tt"));
|
}.setToolTip(Lang.get("menu_delete_tt"));
|
||||||
|
|
||||||
KeyStroke delKey = KeyStroke.getKeyStroke("DELETE");
|
getInputMap().put(KeyStroke.getKeyStroke("DELETE"), DEL_ACTION);
|
||||||
getInputMap().put(delKey, DEL_ACTION);
|
|
||||||
getActionMap().put(DEL_ACTION, deleteAction);
|
getActionMap().put(DEL_ACTION, deleteAction);
|
||||||
|
getInputMap().put(KeyStroke.getKeyStroke("control C"), "myCopy");
|
||||||
|
getActionMap().put("myCopy", copyAction);
|
||||||
|
getInputMap().put(KeyStroke.getKeyStroke("control V"), "myPaste");
|
||||||
|
getActionMap().put("myPaste", pasteAction);
|
||||||
|
|
||||||
|
|
||||||
setFocusable(true);
|
setFocusable(true);
|
||||||
|
|
||||||
@ -100,11 +140,11 @@ public class CircuitComponent extends JComponent {
|
|||||||
moveCursor = new Cursor(Cursor.MOVE_CURSOR);
|
moveCursor = new Cursor(Cursor.MOVE_CURSOR);
|
||||||
mouseNormal = new MouseControllerNormal(normalCursor);
|
mouseNormal = new MouseControllerNormal(normalCursor);
|
||||||
mouseInsertElement = new MouseControllerInsertElement(normalCursor);
|
mouseInsertElement = new MouseControllerInsertElement(normalCursor);
|
||||||
|
mouseInsertList = new MouseControllerInsertCopied(normalCursor);
|
||||||
mouseMoveElement = new MouseControllerMoveElement(normalCursor);
|
mouseMoveElement = new MouseControllerMoveElement(normalCursor);
|
||||||
mouseWire = new MouseControllerWire(normalCursor);
|
mouseWire = new MouseControllerWire(normalCursor);
|
||||||
mouseSelect = new MouseControllerSelect(new Cursor(Cursor.CROSSHAIR_CURSOR));
|
mouseSelect = new MouseControllerSelect(new Cursor(Cursor.CROSSHAIR_CURSOR));
|
||||||
mouseMoveSelected = new MouseControllerMoveSelected(moveCursor);
|
mouseMoveSelected = new MouseControllerMoveSelected(moveCursor);
|
||||||
mouseCopySelected = new MouseControllerCopySelected(moveCursor);
|
|
||||||
mouseRun = new MouseControllerRun(normalCursor);
|
mouseRun = new MouseControllerRun(normalCursor);
|
||||||
|
|
||||||
setCircuit(new Circuit());
|
setCircuit(new Circuit());
|
||||||
@ -256,7 +296,13 @@ public class CircuitComponent extends JComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Vector raster(Vector pos) {
|
/**
|
||||||
|
* rounds the given vector to the raster
|
||||||
|
*
|
||||||
|
* @param pos the vector
|
||||||
|
* @return pos round to raster
|
||||||
|
*/
|
||||||
|
public static Vector raster(Vector pos) {
|
||||||
return new Vector((int) Math.round((double) pos.x / SIZE) * SIZE,
|
return new Vector((int) Math.round((double) pos.x / SIZE) * SIZE,
|
||||||
(int) Math.round((double) pos.y / SIZE) * SIZE);
|
(int) Math.round((double) pos.y / SIZE) * SIZE);
|
||||||
}
|
}
|
||||||
@ -370,6 +416,7 @@ public class CircuitComponent extends JComponent {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseMoved(MouseEvent e) {
|
public void mouseMoved(MouseEvent e) {
|
||||||
|
lastMousePos = new Vector(e.getX(), e.getY());
|
||||||
activeMouseController.moved(e);
|
activeMouseController.moved(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -641,13 +688,8 @@ public class CircuitComponent extends JComponent {
|
|||||||
@Override
|
@Override
|
||||||
boolean dragged(MouseEvent e) {
|
boolean dragged(MouseEvent e) {
|
||||||
if (wasReleased) {
|
if (wasReleased) {
|
||||||
if (downButton == MouseEvent.BUTTON1) {
|
removeHighLighted();
|
||||||
removeHighLighted();
|
mouseMoveSelected.activate(corner1, corner2, getPosVector(e));
|
||||||
mouseMoveSelected.activate(corner1, corner2, getPosVector(e));
|
|
||||||
} else if (downButton == MouseEvent.BUTTON3) {
|
|
||||||
removeHighLighted();
|
|
||||||
mouseCopySelected.activate(corner1, corner2, getPosVector(e));
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
corner2 = getPosVector(e);
|
corner2 = getPosVector(e);
|
||||||
ArrayList<Drawable> elements = circuit.getElementsToHighlight(Vector.min(corner1, corner2), Vector.max(corner1, corner2));
|
ArrayList<Drawable> elements = circuit.getElementsToHighlight(Vector.min(corner1, corner2), Vector.max(corner1, corner2));
|
||||||
@ -719,25 +761,23 @@ public class CircuitComponent extends JComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class MouseControllerCopySelected extends MouseController {
|
private final class MouseControllerInsertCopied extends MouseController {
|
||||||
private ArrayList<Moveable> elements;
|
private ArrayList<Moveable> elements;
|
||||||
private Vector lastPos;
|
private Vector lastPos;
|
||||||
private Vector movement;
|
|
||||||
|
|
||||||
private MouseControllerCopySelected(Cursor cursor) {
|
private MouseControllerInsertCopied(Cursor cursor) {
|
||||||
super(cursor);
|
super(cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void activate(Vector corner1, Vector corner2, Vector pos) {
|
private void activate(ArrayList<Moveable> elements, Vector pos) {
|
||||||
super.activate();
|
super.activate();
|
||||||
|
this.elements = elements;
|
||||||
lastPos = pos;
|
lastPos = pos;
|
||||||
movement = new Vector(0, 0);
|
|
||||||
deleteAction.setActive(true);
|
deleteAction.setActive(true);
|
||||||
elements = circuit.getElementsToCopy(Vector.min(corner1, corner2), Vector.max(corner1, corner2), shapeFactory);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
boolean dragged(MouseEvent e) {
|
void moved(MouseEvent e) {
|
||||||
if (elements != null) {
|
if (elements != null) {
|
||||||
Vector pos = getPosVector(e);
|
Vector pos = getPosVector(e);
|
||||||
Vector delta = raster(pos.sub(lastPos));
|
Vector delta = raster(pos.sub(lastPos));
|
||||||
@ -746,13 +786,10 @@ public class CircuitComponent extends JComponent {
|
|||||||
for (Moveable m : elements)
|
for (Moveable m : elements)
|
||||||
m.move(delta);
|
m.move(delta);
|
||||||
|
|
||||||
movement = movement.add(delta);
|
|
||||||
|
|
||||||
repaint();
|
repaint();
|
||||||
lastPos = lastPos.add(delta);
|
lastPos = lastPos.add(delta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -769,8 +806,8 @@ public class CircuitComponent extends JComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
void released(MouseEvent e) {
|
void clicked(MouseEvent e) {
|
||||||
if (elements != null && !movement.isZero()) {
|
if (elements != null) {
|
||||||
for (Moveable m : elements) {
|
for (Moveable m : elements) {
|
||||||
if (m instanceof Wire)
|
if (m instanceof Wire)
|
||||||
circuit.add((Wire) m);
|
circuit.add((Wire) m);
|
||||||
@ -782,6 +819,7 @@ public class CircuitComponent extends JComponent {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private interface Actor {
|
private interface Actor {
|
||||||
boolean interact(CircuitComponent cc, Point p);
|
boolean interact(CircuitComponent cc, Point p);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,100 @@
|
|||||||
|
package de.neemann.digital.gui.components;
|
||||||
|
|
||||||
|
import com.thoughtworks.xstream.XStream;
|
||||||
|
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
|
||||||
|
import de.neemann.digital.draw.elements.Circuit;
|
||||||
|
import de.neemann.digital.draw.elements.Moveable;
|
||||||
|
import de.neemann.digital.draw.elements.VisualElement;
|
||||||
|
import de.neemann.digital.draw.graphics.GraphicMinMax;
|
||||||
|
import de.neemann.digital.draw.graphics.Vector;
|
||||||
|
import de.neemann.digital.draw.shapes.ShapeFactory;
|
||||||
|
|
||||||
|
import java.awt.datatransfer.DataFlavor;
|
||||||
|
import java.awt.datatransfer.Transferable;
|
||||||
|
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author hneemann
|
||||||
|
*/
|
||||||
|
public class CircuitTransferable implements Transferable {
|
||||||
|
|
||||||
|
private String data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance
|
||||||
|
*
|
||||||
|
* @param data the data to copy
|
||||||
|
*/
|
||||||
|
public CircuitTransferable(ArrayList<Moveable> data) {
|
||||||
|
XStream xStream = Circuit.getxStream();
|
||||||
|
try (StringWriter out = new StringWriter()) {
|
||||||
|
out.write("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
|
||||||
|
xStream.marshal(data, new PrettyPrintWriter(out));
|
||||||
|
this.data = out.toString();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DataFlavor[] getTransferDataFlavors() {
|
||||||
|
return new DataFlavor[]{DataFlavor.stringFlavor};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDataFlavorSupported(DataFlavor flavor) {
|
||||||
|
return flavor == DataFlavor.stringFlavor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
|
||||||
|
if (!isDataFlavorSupported(flavor))
|
||||||
|
throw new UnsupportedFlavorException(flavor);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a list of objects from inserted data
|
||||||
|
*
|
||||||
|
* @param data the inserted data
|
||||||
|
* @param shapeFactory the shapeFactory to set to the elements
|
||||||
|
* @param lastMousePos the actual mouse position
|
||||||
|
* @return the elements or null
|
||||||
|
*/
|
||||||
|
public static ArrayList<Moveable> createList(Object data, ShapeFactory shapeFactory, Vector lastMousePos) {
|
||||||
|
if (!(data instanceof String))
|
||||||
|
return null;
|
||||||
|
|
||||||
|
XStream xStream = Circuit.getxStream();
|
||||||
|
Vector max = null;
|
||||||
|
try (Reader in = new StringReader(data.toString())) {
|
||||||
|
ArrayList<Moveable> elements = (ArrayList<Moveable>) xStream.fromXML(in);
|
||||||
|
for (Moveable m : elements)
|
||||||
|
if (m instanceof VisualElement) {
|
||||||
|
((VisualElement) m).setShapeFactory(shapeFactory);
|
||||||
|
GraphicMinMax mm = ((VisualElement) m).getMinMax();
|
||||||
|
if (max == null)
|
||||||
|
max = mm.getMax();
|
||||||
|
else
|
||||||
|
max = Vector.max(max, mm.getMax());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max != null) {
|
||||||
|
Vector delta = CircuitComponent.raster(lastMousePos.sub(max));
|
||||||
|
for (Moveable m : elements)
|
||||||
|
m.move(delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
return elements;
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user