package org.geogebra.common.kernel.scripting; import org.geogebra.common.kernel.Kernel; import org.geogebra.common.kernel.arithmetic.Command; import org.geogebra.common.kernel.commands.CmdScripting; import org.geogebra.common.kernel.geos.AbsoluteScreenLocateable; import org.geogebra.common.kernel.geos.GeoElement; import org.geogebra.common.kernel.geos.GeoLine; import org.geogebra.common.kernel.geos.GeoTurtle; import org.geogebra.common.kernel.kernelND.GeoPointND; import org.geogebra.common.kernel.kernelND.GeoVectorND; import org.geogebra.common.main.MyError; /** * SetCoords */ public class CmdSetCoords extends CmdScripting { /** * Create new command processor * * @param kernel * kernel */ public CmdSetCoords(Kernel kernel) { super(kernel); } @Override protected final GeoElement[] perform(Command c) throws MyError { int n = c.getArgumentNumber(); switch (n) { case 3: GeoElement[] arg = resArgs(c); // we don't want to change coords unless the point is free or // Point[path/region] double x = getDouble(arg[1], c); double y = getDouble(arg[2], c); if (!setCoords(arg[0], x, y)) { throw argErr(app, c, arg[0]); } return arg; case 4: arg = resArgs(c); // we don't want to change coords unless the point is free or // Point[path/region] x = getDouble(arg[1], c); y = getDouble(arg[2], c); double z = getDouble(arg[3], c); if (!setCoords(arg[0], x, y, z)) { throw argErr(app, c, arg[0]); } return arg; default: throw argNumErr(app, c, n); } } private double getDouble(GeoElement geo, Command c) { if (!geo.isNumberValue()) { throw argErr(app, c, geo); } return geo.evaluateDouble(); } /** * @param geo * element * @param x * x-coord * @param y * y-coord * @return whether it was successful */ public static boolean setCoords(GeoElement geo, double x, double y) { if (geo.isMoveable()) { if (geo.isGeoPoint()) { ((GeoPointND) geo).setCoords(x, y, 1); geo.updateRepaint(); return true; } else if (geo.isGeoVector()) { ((GeoVectorND) geo).setCoords(x, y, 0); geo.updateRepaint(); return true; } // don't return false, need to fall through } if (geo.isGeoTurtle()) { ((GeoTurtle) geo).setCoords(x, y); return true; } if (geo instanceof AbsoluteScreenLocateable) { AbsoluteScreenLocateable asl = (AbsoluteScreenLocateable) geo; if (asl.isAbsoluteScreenLocActive()) { asl.setAbsoluteScreenLoc((int) x, (int) y); } else { asl.setRealWorldLoc(x, y); } asl.updateRepaint(); return true; } return false; } /** * @param geo * element * @param x * x coordinate * @param y * y coordinate * @param z * z coordinate * @return true when successful */ public static boolean setCoords(GeoElement geo, double x, double y, double z) { if (geo.isMoveable() && geo instanceof GeoPointND) { ((GeoPointND) geo).setCoords(x, y, z, 1); geo.updateRepaint(); return true; } if (geo.isMoveable() && geo instanceof GeoVectorND) { ((GeoVectorND) geo).setCoords(x, y, z, 0); geo.updateRepaint(); return true; } if (geo.isMoveable() && geo instanceof GeoLine) { ((GeoLine) geo).setCoords(x, y, z); geo.updateRepaint(); return true; } // ignore z-coord otherwise return setCoords(geo, x, y); } }