316 lines
7.7 KiB
Java
316 lines
7.7 KiB
Java
/*
|
|
|
|
Copyright 2006 Rene Grothmann, modified by Eric Hakenholz
|
|
|
|
This file is part of C.a.R. software.
|
|
|
|
C.a.R. is a free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, version 3 of the License.
|
|
|
|
C.a.R. is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
package rene.zirkel.tools;
|
|
|
|
// file: Tracker.java
|
|
|
|
import java.awt.event.MouseEvent;
|
|
import java.util.Enumeration;
|
|
import java.util.Vector;
|
|
|
|
import rene.util.xml.XmlWriter;
|
|
import rene.gui.Global;
|
|
import rene.zirkel.ZirkelCanvas;
|
|
import rene.zirkel.constructors.ObjectConstructor;
|
|
import rene.zirkel.graphics.MyGraphics;
|
|
import rene.zirkel.graphics.TrackPainter;
|
|
import rene.zirkel.objects.ConstructionObject;
|
|
import rene.zirkel.objects.MoveableObject;
|
|
import rene.zirkel.objects.PointObject;
|
|
import rene.zirkel.objects.PrimitiveLineObject;
|
|
import rene.zirkel.structures.Coordinates;
|
|
|
|
public class Tracker extends ObjectConstructor implements TrackPainter {
|
|
ConstructionObject PM;
|
|
int PMax = 8, PN;
|
|
ConstructionObject P;
|
|
ConstructionObject PO[] = new ConstructionObject[PMax];
|
|
Vector V = new Vector();
|
|
Vector VO[] = new Vector[PMax];
|
|
double X, Y, DX, DY;
|
|
double XO[] = new double[PMax], YO[] = new double[PMax],
|
|
DXO[] = new double[PMax], DYO[] = new double[PMax];
|
|
boolean Started;
|
|
boolean StartedO[] = new boolean[PMax];
|
|
boolean Other;
|
|
|
|
public Tracker(final ConstructionObject p, final ConstructionObject po[]) {
|
|
super();
|
|
P = p;
|
|
PN = 0;
|
|
for (int i = 0; i < po.length; i++) {
|
|
if (i >= PMax || po[i] == null)
|
|
break;
|
|
PO[PN] = po[i];
|
|
VO[i] = new Vector();
|
|
PN++;
|
|
}
|
|
}
|
|
|
|
public Tracker() {
|
|
super();
|
|
}
|
|
|
|
@Override
|
|
public void mousePressed(final MouseEvent e, final ZirkelCanvas zc) {
|
|
|
|
final double x = zc.x(e.getX()), y = zc.y(e.getY());
|
|
if (P == null) {
|
|
P = zc.selectPoint(e.getX(), e.getY());
|
|
if (P == null)
|
|
P = zc.selectLine(e.getX(), e.getY());
|
|
if (P == null)
|
|
return;
|
|
P.setSelected(true);
|
|
zc.repaint();
|
|
if (e.isShiftDown())
|
|
Other = true;
|
|
else
|
|
Other = false;
|
|
showStatus(zc);
|
|
} else if (Other) {
|
|
ConstructionObject P = zc.selectPoint(e.getX(), e.getY());
|
|
if (P == null)
|
|
P = zc.selectLine(e.getX(), e.getY());
|
|
if (P != null) {
|
|
P.setSelected(true);
|
|
zc.repaint();
|
|
PO[PN] = P;
|
|
VO[PN] = new Vector();
|
|
PN++;
|
|
}
|
|
if (!e.isShiftDown() || PN >= PMax)
|
|
Other = false;
|
|
showStatus(zc);
|
|
} else {
|
|
final ConstructionObject pm = zc.selectMoveableObject(e.getX(), e
|
|
.getY());
|
|
PM = pm;
|
|
if (PM != null) {
|
|
zc.clearSelected();
|
|
PM.setSelected(true);
|
|
((MoveableObject) PM).startDrag(x, y);
|
|
zc.repaint();
|
|
showStatus(zc);
|
|
}
|
|
Started = false;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void mouseMoved(final MouseEvent e, final ZirkelCanvas zc,
|
|
final boolean simple) {
|
|
if (P == null || Other)
|
|
zc.indicatePointsOrLines(e.getX(), e.getY());
|
|
else if (PM == null)
|
|
zc.indicateMoveableObjects(e.getX(), e.getY());
|
|
else
|
|
zc.clearIndicated();
|
|
}
|
|
|
|
@Override
|
|
public void mouseDragged(final MouseEvent e, final ZirkelCanvas zc) {
|
|
if (PM == null)
|
|
return;
|
|
((MoveableObject) PM).dragTo(zc.x(e.getX()), zc.y(e.getY()));
|
|
zc.validate();
|
|
track(zc);
|
|
zc.repaint();
|
|
}
|
|
|
|
@Override
|
|
public void mouseReleased(final MouseEvent e, final ZirkelCanvas zc) {
|
|
if (PM == null)
|
|
return;
|
|
PM.setSelected(false);
|
|
PM = null;
|
|
zc.repaint();
|
|
showStatus(zc);
|
|
}
|
|
|
|
@Override
|
|
public void reset(final ZirkelCanvas zc) {
|
|
zc.clearSelected();
|
|
P = PM = null;
|
|
PN = 0;
|
|
V = new Vector();
|
|
showStatus(zc);
|
|
zc.repaint();
|
|
}
|
|
|
|
@Override
|
|
public void showStatus(final ZirkelCanvas zc) {
|
|
if (P == null || Other)
|
|
zc.showStatus(Global.name("message.tracker.select"));
|
|
else if (PM == null)
|
|
zc.showStatus(Global.name("message.tracker.selectpoint"));
|
|
else
|
|
zc.showStatus(Global.name("message.tracker.move"));
|
|
}
|
|
|
|
public void track(final ZirkelCanvas zc) {
|
|
if (P == null)
|
|
return;
|
|
if (P instanceof PointObject) {
|
|
final PointObject p = (PointObject) P;
|
|
if (p.valid())
|
|
V.addElement(new Coordinates(p.getX(), p.getY()));
|
|
} else if (P instanceof PrimitiveLineObject) {
|
|
final PrimitiveLineObject L = (PrimitiveLineObject) P;
|
|
if (L.valid()) {
|
|
if (!Started) {
|
|
X = L.getX();
|
|
Y = L.getY();
|
|
DX = L.getDX();
|
|
DY = L.getDY();
|
|
Started = true;
|
|
} else {
|
|
double x, y, dx, dy;
|
|
x = L.getX();
|
|
y = L.getY();
|
|
dx = L.getDX();
|
|
dy = L.getDY();
|
|
final double det = dx * DY - dy * DX;
|
|
if (Math.sqrt(Math.abs(det)) > 1e-9) {
|
|
final double a = (-(X - x) * DY + DX * (Y - y))
|
|
/ (-det);
|
|
V.addElement(new Coordinates(x + a * dx, y + a * dy));
|
|
}
|
|
X = x;
|
|
Y = y;
|
|
DX = dx;
|
|
DY = dy;
|
|
}
|
|
}
|
|
}
|
|
for (int i = 0; i < PN; i++) {
|
|
if (PO[i] == null || !PO[i].valid())
|
|
continue;
|
|
if (PO[i] instanceof PointObject) {
|
|
final PointObject p = (PointObject) PO[i];
|
|
VO[i].addElement(new Coordinates(p.getX(), p.getY()));
|
|
} else if (PO[i] instanceof PrimitiveLineObject) {
|
|
final PrimitiveLineObject L = (PrimitiveLineObject) PO[i];
|
|
if (!StartedO[i]) {
|
|
XO[i] = L.getX();
|
|
YO[i] = L.getY();
|
|
DXO[i] = L.getDX();
|
|
DYO[i] = L.getDY();
|
|
StartedO[i] = true;
|
|
} else {
|
|
double x, y, dx, dy;
|
|
x = L.getX();
|
|
y = L.getY();
|
|
dx = L.getDX();
|
|
dy = L.getDY();
|
|
final double det = dx * DYO[i] - dy * DXO[i];
|
|
if (Math.sqrt(Math.abs(det)) > 1e-9) {
|
|
final double a = (-(XO[i] - x) * DYO[i] + DXO[i]
|
|
* (YO[i] - y))
|
|
/ (-det);
|
|
VO[i]
|
|
.addElement(new Coordinates(x + a * dx, y + a
|
|
* dy));
|
|
}
|
|
XO[i] = x;
|
|
YO[i] = y;
|
|
DXO[i] = dx;
|
|
DYO[i] = dy;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public Enumeration elements() {
|
|
return V.elements();
|
|
}
|
|
|
|
public void paint(final MyGraphics g, final ZirkelCanvas zc) {
|
|
if (P == null)
|
|
return;
|
|
Coordinates C;
|
|
Enumeration e = V.elements();
|
|
g.setColor(P);
|
|
double c0, r0, c, r;
|
|
final int maxd = zc.width() / 20;
|
|
if (e.hasMoreElements()) {
|
|
C = (Coordinates) e.nextElement();
|
|
c0 = zc.col(C.X);
|
|
r0 = zc.row(C.Y);
|
|
while (e.hasMoreElements()) {
|
|
C = (Coordinates) e.nextElement();
|
|
c = zc.col(C.X);
|
|
r = zc.row(C.Y);
|
|
if (Math.abs(c0 - c) < maxd && Math.abs(r0 - r) < maxd)
|
|
g.drawLine(c0, r0, c, r, P);
|
|
else
|
|
g.drawLine(c0, r0, c0, r0, P);
|
|
c0 = c;
|
|
r0 = r;
|
|
}
|
|
}
|
|
for (int i = 0; i < PN; i++) {
|
|
if (PO[i] == null)
|
|
continue;
|
|
g.setColor(PO[i]);
|
|
e = VO[i].elements();
|
|
if (e.hasMoreElements()) {
|
|
C = (Coordinates) e.nextElement();
|
|
c0 = zc.col(C.X);
|
|
r0 = zc.row(C.Y);
|
|
while (e.hasMoreElements()) {
|
|
C = (Coordinates) e.nextElement();
|
|
c = zc.col(C.X);
|
|
r = zc.row(C.Y);
|
|
if (Math.abs(c0 - c) < maxd && Math.abs(r0 - r) < maxd)
|
|
g.drawLine(c0, r0, c, r, PO[i]);
|
|
else
|
|
g.drawLine(c0, r0, c0, r0, PO[i]);
|
|
c0 = c;
|
|
r0 = r;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void validate(final ZirkelCanvas zc) {
|
|
}
|
|
|
|
public void save(final XmlWriter xml) {
|
|
if (P == null)
|
|
return;
|
|
xml.startTagStart("Track");
|
|
xml.printArg("track", P.getName());
|
|
for (int i = 0; i < PN; i++) {
|
|
xml.printArg("track" + i, PO[i].getName());
|
|
}
|
|
if (PM != null)
|
|
xml.printArg("move", PM.getName());
|
|
xml.finishTagNewLine();
|
|
}
|
|
|
|
@Override
|
|
public boolean useSmartBoard() {
|
|
return false;
|
|
}
|
|
}
|