/* 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 . */ package rene.zirkel.macro; /** * This is an ObjectConstructor, which can run a macro. */ // with addons by Dibs for 3D import eric.JSelectPopup; import eric.GUI.palette.PaletteManager; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.Enumeration; import java.util.StringTokenizer; import java.util.Vector; import rene.gui.Global; import rene.zirkel.ZirkelCanvas; import rene.zirkel.construction.Construction; import rene.zirkel.construction.ConstructionException; import rene.zirkel.construction.DepList; import rene.zirkel.construction.Selector; import rene.zirkel.constructors.ObjectConstructor; import rene.zirkel.objects.AngleObject; import rene.zirkel.objects.AreaObject; import rene.zirkel.objects.CircleObject; import rene.zirkel.objects.ConstructionObject; import rene.zirkel.objects.ExpressionObject; import rene.zirkel.objects.FixedAngleObject; import rene.zirkel.objects.FixedCircleObject; import rene.zirkel.objects.FunctionObject; import rene.zirkel.objects.JLocusTrackObject; import rene.zirkel.objects.LineObject; import rene.zirkel.objects.PointObject; import rene.zirkel.objects.PointonObject; import rene.zirkel.objects.PrimitiveCircleObject; import rene.zirkel.objects.PrimitiveLineObject; import rene.zirkel.objects.QuadricObject; import rene.zirkel.objects.RayObject; import rene.zirkel.objects.SegmentObject; import rene.zirkel.objects.TextObject; import rene.zirkel.objects.TwoPointLineObject; import rene.zirkel.objects.UserFunctionObject; import rene.zirkel.objects.VectorObject; public class MacroRunner extends ObjectConstructor implements Selector { String S[]; int Param; Macro M; ArrayList OCs=new ArrayList(); ArrayList PROMPTs=new ArrayList(); ZirkelCanvas ZC; ConstructionObject Params[]; // array of parameters. boolean NewPoint[]; // are the parameters new points? boolean Fixed[]; double LastX=0, LastY=0; boolean ShiftDown=false; static ConstructionObject previewPoint=null; static boolean keepLine=true; static boolean keepCircle=true; /** * Must be called, when this constructor is started. * * @param m * The macro to be run */ public void setMacro(final Macro m, final ZirkelCanvas zc) { S=m.getPrompts(); Param=0; M=m; Params=new ConstructionObject[S.length]; Fixed=new boolean[S.length]; NewPoint=new boolean[S.length]; for (int i=0; i=S.length) { doMacro(zc); reset(zc); } else { getFixed(zc); } } } @Override public boolean isAdmissible(final ZirkelCanvas zc, final ConstructionObject o) { final ConstructionObject p[]=M.getParams(); if (p[Param] instanceof PointObject) { return (o instanceof PointObject); } else if (p[Param] instanceof FixedAngleObject) { return (o instanceof FixedAngleObject); } else if (p[Param] instanceof RayObject) { return (o instanceof RayObject); } else if (p[Param] instanceof TwoPointLineObject) { return (o instanceof TwoPointLineObject); } else if (p[Param] instanceof SegmentObject) { return (p[Param] instanceof SegmentObject); } else if (p[Param] instanceof PrimitiveLineObject) { return (o instanceof PrimitiveLineObject); } else if (p[Param] instanceof PrimitiveCircleObject) { return (o instanceof PrimitiveCircleObject); } else if (p[Param] instanceof FunctionObject) { return (o instanceof FunctionObject); } else if (p[Param] instanceof UserFunctionObject) { return (o instanceof UserFunctionObject); } else if (p[Param] instanceof AngleObject) { return (o instanceof AngleObject); } else if (p[Param] instanceof QuadricObject) { return (o instanceof QuadricObject); } else if (p[Param] instanceof ExpressionObject) { return (o instanceof ExpressionObject||o instanceof AngleObject ||o instanceof FixedAngleObject||o instanceof AreaObject); } else if (p[Param] instanceof AreaObject) { return (o instanceof AreaObject); } else { return false; } } private void checkIfKeepLine(final ZirkelCanvas zc) { final Construction c=zc.getConstruction(); PointObject P1org=new PointObject(c, -3, 4); PointObject P2org=new PointObject(c, -1, 1); PointObject P3org=new PointObject(c, 1, -2); P1org.setSuperHidden(true); P2org.setSuperHidden(true); P3org.setSuperHidden(true); Params[Params.length-1]=P1org; c.add(P1org); runMacroPreview(zc, false); final PointObject p1=(PointObject) previewPoint; Params[Params.length-1]=P2org; c.add(P2org); runMacroPreview(zc, false); final PointObject p2=(PointObject) previewPoint; Params[Params.length-1]=P3org; c.add(P3org); runMacroPreview(zc, false); final PointObject p3=(PointObject) previewPoint; final double x1=p2.getX()-p1.getX(); final double y1=p2.getY()-p1.getY(); final double x2=p3.getX()-p1.getX(); final double y2=p3.getY()-p1.getY(); keepLine=(Math.abs(x1*y2-x2*y1)<1e-11); } private void checkIfKeepCircle(final ZirkelCanvas zc) { final Construction c=zc.getConstruction(); PointObject P0org=new PointObject(c, 1, 1); PointObject P1org=new PointObject(c, 2, -1); PointObject P2org=new PointObject(c, 3, 2); PointObject P3org=new PointObject(c, 0, 3); PointObject P4org=new PointObject(c, -1, 2); P0org.setSuperHidden(true); P1org.setSuperHidden(true); P2org.setSuperHidden(true); P3org.setSuperHidden(true); P4org.setSuperHidden(true); Params[Params.length-1]=P0org; c.add(P0org); runMacroPreview(zc, false); final PointObject p0=(PointObject) previewPoint; Params[Params.length-1]=P1org; c.add(P1org); runMacroPreview(zc, false); final PointObject p1=(PointObject) previewPoint; Params[Params.length-1]=P2org; c.add(P2org); runMacroPreview(zc, false); final PointObject p2=(PointObject) previewPoint; Params[Params.length-1]=P3org; c.add(P3org); runMacroPreview(zc, false); final PointObject p3=(PointObject) previewPoint; Params[Params.length-1]=P4org; c.add(P4org); runMacroPreview(zc, false); final PointObject p4=(PointObject) previewPoint; final double x1=Math.sqrt((p1.getX()-p0.getX()) *(p1.getX()-p0.getX())+(p1.getY()-p0.getY()) *(p1.getY()-p0.getY())); final double x2=Math.sqrt((p2.getX()-p0.getX()) *(p2.getX()-p0.getX())+(p2.getY()-p0.getY()) *(p2.getY()-p0.getY())); final double x3=Math.sqrt((p3.getX()-p0.getX()) *(p3.getX()-p0.getX())+(p3.getY()-p0.getY()) *(p3.getY()-p0.getY())); final double x4=Math.sqrt((p4.getX()-p0.getX()) *(p4.getX()-p0.getX())+(p4.getY()-p0.getY()) *(p4.getY()-p0.getY())); boolean b=Math.abs(x1-x2)<1e-11; b=b&&Math.abs(x1-x3)<1e-11; b=b&&Math.abs(x1-x4)<1e-11; keepCircle=b; } public boolean isMultipleFinalAccepted() { final ConstructionObject p[]=M.getParams(); if (Param0) { return false; } final ConstructionObject p[]=M.getParams(); return (p[Param] instanceof PointObject)&&Param==p.length-1; } @Override public void finishConstruction(final MouseEvent e, final ZirkelCanvas zc) { final ConstructionObject p[]=M.getParams(); ConstructionObject o; if (p[Param] instanceof PointObject) { o=zc.selectCreatePoint(e.getX(), e.getY(), e.isAltDown()); } else { return; } NewPoint[Param]=true; Params[Param]=o; runMacroPreview(zc, true); } public void finishConstruction(int x, int y, final MouseEvent e, final ZirkelCanvas zc) { final ConstructionObject p[]=M.getParams(); ConstructionObject o; if (p[Param] instanceof PointObject) { o=zc.selectCreatePoint(x, y, e.isAltDown()); } else { return; } NewPoint[Param]=true; Params[Param]=o; runMacroPreview(zc, true); } @Override public void reset(final ZirkelCanvas zc) { if (zc.Visual) { super.reset(zc); Param=0; if (M!=null&&M.hasFixed()) { getFixed(zc); } showStatus(zc); } else if (M!=null) // show the input pattern { final StringBuffer b=new StringBuffer(); b.append('='); final String name=M.getName(); if (name.indexOf("(")>0) { b.append("\""+M.getName()+"\""); } else { b.append(M.getName()); } b.append('('); for (int i=0; i=S.length) { doMacro(zc); reset(zc); break; } } showStatus(zc); } public void returnPressed(final ZirkelCanvas zc) { if (M==null||!zc.Visual) { return; } final String name=M.getLast(Param); if (name.equals("")) { return; } final ConstructionObject o=zc.getConstruction().find(name); if (!setNextParameter(o, zc, false)) { return; } if (Param>=S.length) { doMacro(zc); reset(zc); } else { getFixed(zc); } } public boolean setNextParameter(final ConstructionObject o, final ZirkelCanvas zc, final boolean fix) { if (!isAdmissible(zc, o)) { return false; } Params[Param]=o; o.setSelected(true); if (fix) { Fixed[Param]=true; } zc.getConstruction().addParameter(o); zc.repaint(); Param++; return true; } public void doMacro(final ZirkelCanvas zc) { final String value[]=new String[0]; runMacro(zc, value); } static DepList DL=new DepList(); @Override public void showStatus(final ZirkelCanvas zc) { if (M!=null) { final ConstructionObject p[]=M.getParams(); String type="???"; // Determine the expected type and display in status line if (p[Param] instanceof FunctionObject) { type=Global.name("name.Function"); } else if (p[Param] instanceof PointObject) { type=Global.name("name.Point"); } else if (p[Param] instanceof FixedAngleObject) { type=Global.name("name.FixedAngle"); } else if(p[Param] instanceof VectorObject) { type=Global.name("name.Vector"); } else if (p[Param] instanceof SegmentObject) { type=Global.name("name.Segment"); } else if (p[Param] instanceof LineObject) { type=Global.name("name.TwoPointLine"); } else if (p[Param] instanceof RayObject) { type=Global.name("name.Ray"); } else if (p[Param] instanceof PrimitiveLineObject) { type=Global.name("name.Line"); } else if (p[Param] instanceof PrimitiveCircleObject) { type=Global.name("name.Circle"); } else if (p[Param] instanceof ExpressionObject) { type=Global.name("name.Expression"); } else if (p[Param] instanceof AreaObject) { type=Global.name("name.Polygon"); } else if (p[Param] instanceof AngleObject) { type=Global.name("name.Angle"); } else if (p[Param] instanceof QuadricObject) { type=Global.name("name.Quadric"); } final String s=M.getLast(Param); String prompt; int inc=zc.isDP()?0:1; if (s.equals("")) { prompt=ConstructionObject.text4(Global.name("message.runmacro"), M.getName(), "" +(Param+inc), type, S[Param]); } else { prompt=ConstructionObject.text4(Global.name("message.runmacro"), M.getName(), "" +(Param+inc), type, S[Param]) +" "; } zc.showStatus(prompt); } } //Only for JSFunctions/ExecuteMacro public static ArrayList TargetsNameList = new ArrayList(); public static ArrayList TargetsIndexList = new ArrayList(); /** * Run a macro. The macro parameters have already been determined. This is a * rather complicated function. */ public void runMacro(final ZirkelCanvas zc, final Construction c, final String value[]) { TargetsNameList.clear(); TargetsIndexList.clear(); OCs.clear(); PROMPTs.clear(); M.setTranslation(c); final ConstructionObject LastBefore=c.lastButN(0); final int N=Params.length; // First clear all parameter flags. This makes it possible to // check for proper translation of secondary parameters later. // Secondary parameters without a translation will be // constructed. Enumeration e=M.elements(); while (e.hasMoreElements()) { final ConstructionObject o=(ConstructionObject) e.nextElement(); o.clearParameter(); o.setTranslation(null); } M.clearTranslations(); c.clearTranslators(); final ConstructionObject p[]=M.getParams(); // For all macro parameters, determine the translation to the // real construction, and do the same for the secondary // parameters, which belong to the parameter. The secondary // parameters are stored in the macro at its definition, as // the primary ones. Also the parameters in the macros are marked // as such to make sure and prevent construction. M.initLast(); // Macros remember the parameters for next call for (int i=0; i=value.length||value[index].equals("")) { OCs.add(oc); PROMPTs.add(M.getPromptName(o.getName())); } } } } } // Now fix the objects, which depend on later objects e=M.elements(); while (e.hasMoreElements()) { final ConstructionObject o=(ConstructionObject) e.nextElement(); if (!o.isParameter()) { o.laterTranslate(M); } } c.updateCircleDep(); c.runTranslators(M); c.dovalidate(); zc.repaint(); int fixed=0; for (final boolean element : Fixed) { if (element) { fixed++; } } if (fixed>0&&fixed