/* 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.objects; // file: ConstructionObject.java import java.awt.Color; import java.awt.Rectangle; import java.util.Enumeration; import java.util.StringTokenizer; import java.util.Vector; import rene.lister.Element; import rene.util.FileName; import rene.util.MyVector; import rene.util.sort.SortObject; import rene.util.xml.XmlWriter; import rene.gui.Global; import rene.zirkel.ZirkelCanvas; import rene.zirkel.ZirkelFrame; import rene.zirkel.construction.Construction; import rene.zirkel.construction.ConstructionException; import rene.zirkel.construction.Count; import rene.zirkel.construction.DepList; import rene.zirkel.expression.Expression; import rene.zirkel.expression.ExpressionColor; import rene.zirkel.expression.ExpressionString; import rene.zirkel.expression.NoValueException; import rene.zirkel.graphics.MyGraphics; class Conditional implements Cloneable { String Tag; Expression Expr; public Conditional(final String t, final Expression e) { Tag=t; Expr=e; } public String getTag() { return Tag; } public Expression getExpression() { return Expr; } public void setExpression(final Expression e) { Expr=e; } } public class ConstructionObject implements Cloneable, SortObject, Element { /** object color and static default color */ protected int ColorType=0; public static final int NORMAL=0, THICK=1, THIN=2, INVISIBLE=3; protected Color C=Color.black; protected ExpressionColor SpecialColor=null; protected int ColorIndex=0; protected boolean Tracked=false; protected boolean Selected=false; // is selected (highlight red!) protected boolean StrongSelected=false; // to highlight the object even // more protected boolean Indicated=false; // mouse is over it (highlight darker!) protected boolean ShowIndicatedName=false; // shows the name (or name and // value) protected boolean LabelSelected=false; // label is selected (highlight // red!) protected boolean Valid=true; // e.g. for intersections protected boolean Hidden=false; // not visible or lighter protected boolean SuperHidden=false; // not visible at all protected boolean BreakHide=false; // Hide due to hiding break protected boolean ShowName=false; // shows the name (or name and value) protected boolean ShowValue=false; // shows the value (or name and value) protected boolean Selectable=true; // may be selected protected String Name="Generic"; protected static int Count=1; // To generate a unique name protected String Text="???"; // Description (human readable) private int XOffset=0, YOffset=0; // Deprecated INT offset (translated // to double) protected double XcOffset=0.0, YcOffset=0.0; // Offsets for the text // display protected boolean KeepClose; // Keep the text display close to the object protected boolean DisplaysText=false; // Does this object display text? protected double TX1, TY1, TX2, TY2; // text rectangle. protected Construction Cn; // Construction that this Object belongs to protected boolean MainParameter, Parameter; // for macros and jobs protected boolean Target; // for macros and jobs protected int MacroFinalIndex=0; // only for ExecuteMacroAsBuilt public boolean Flag, RekFlag, IsDrawn, HasZ; // for various processing // purposes public int Scratch; // for various processing purposes protected boolean Keep=false; // for job parameters. protected boolean JobTarget=false; // for job targets protected ConstructionObject Translation; protected boolean Back=false; // draws in the background (first round) protected boolean Obtuse=true; // for angles and circles between two // points. protected boolean Break=false; // Break point in front of this object? protected boolean HideBreak=false; // Hide construction before this break! protected boolean Solid=false; // Not transparent? static Count N=new Count(); protected boolean inConstruction; // Is in the construction (or deleted) protected String Unit=""; // Use a unit display protected boolean Bold=false; // Use a bold font for this item protected boolean Large=false; // Use a large font for this item protected Vector Conditionals; // For conditional formatting protected int NCount=0; // Unique number protected boolean gotNCount=false; // Have already a number (from load // file) public boolean NeedsRecompute=true; protected boolean inMultipleSelection=false; final public static int NON_DP=0,DP_LINE=1,DP_SEGMENT=2,DP_CIRCLE=3; private int dp_mode=0; // 0 for non-dp objects 1 for lines, 2 for segments public void setInMultipleSelection(boolean b) { inMultipleSelection=b; } public boolean isInMultipleSelection() { return inMultipleSelection; } public void copyProperties(final ConstructionObject origin) { Tracked=origin.Tracked; Selected=origin.Selected; StrongSelected=origin.StrongSelected; Indicated=origin.Indicated; ShowIndicatedName=origin.ShowIndicatedName; LabelSelected=origin.LabelSelected; Valid=origin.Valid; Hidden=origin.Hidden; SuperHidden=origin.SuperHidden; BreakHide=origin.BreakHide; ShowName=origin.ShowName; ShowValue=origin.ShowValue; Selectable=origin.Selectable; ColorType=origin.ColorType; C=origin.C; ColorIndex=origin.ColorIndex; if (origin.Conditionals!=null) { Conditionals=(Vector) origin.Conditionals.clone(); } } public boolean isGotNCount() { return gotNCount; } public void setGotNCount(final boolean gotNCount) { this.gotNCount=gotNCount; } public ConstructionObject(final Construction c) { Cn=c; inConstruction=true; setName(); } public ConstructionObject(final Construction c, final String name) { Cn=c; inConstruction=true; setName(name); } public int getDPMode(){ return dp_mode; } public void setDPMode(int i){ dp_mode=i; } public boolean isDPObject(){ return (dp_mode>NON_DP); } public boolean isDPLineObject(){ return (dp_mode==DP_LINE); } public boolean isDPSegmentObject(){ return (dp_mode==DP_SEGMENT); } public boolean isDPCircleObject(){ return (dp_mode==DP_CIRCLE); } public boolean isDPLineOrSegmentObject(){ return ((dp_mode==DP_LINE)||(dp_mode==DP_SEGMENT)); } // tells if it's a main object which can make heavy objects to recompute : public boolean isDriverObject() { return false; } /** * Sets a unique name for the object. Should be overriden in all items. */ public void setName() { if (Cn.LongNames) { Name=Global.name("name."+getTag())+" "+getN(); } else { Name=Global.name("name.short."+getTag())+getN(); // System.out.println("nom="+Name); } } public int getN() { return N.next(); } public String getTag() { return "Generic"; } /** * This is used to define macros and run them. The items of the construction * are translated to macro items. */ public ConstructionObject getTranslation() { return Translation; } public void setTranslation(final ConstructionObject t) { Translation=t; } /** * Override in children! This translates the mother items. */ public void translate() { } public void paint(final MyGraphics g, final ZirkelCanvas zc) { } /** * Test, if this object is chosen with coordinates x,y */ public boolean nearto(final int x, final int y, final ZirkelCanvas zc) { return false; } /** * Test, if this object is chosen with coordinates x,y */ public boolean nearto(final int x, final int y, final boolean ignorefill, final ZirkelCanvas zc) { return nearto(x, y, zc); } /** * Test, if this object must be chosen with coordinates x,y, assuming it is * near to these coordinates. */ public boolean onlynearto(final int x, final int y, final ZirkelCanvas zc) { return true; } public boolean isInRect(Rectangle r, ZirkelCanvas zc) { return false; } public boolean textcontains(final int x, final int y, final ZirkelCanvas zc) { if (!DisplaysText||!Valid||(isHidden()&&!zc.showHidden())) { return false; } return x>TX1&&xTY1&&y0&&zc.getShowColor()!=0 &&zc.getShowColor()!=ColorIndex) { return true; } if (JobTarget&&Hidden) { return true; } return SuperHidden||testConditional("superhidden")||BreakHide ||zc.hides(this)||(isHidden()&&!zc.showHidden()); } public void setHidden(final boolean flag) { Hidden=flag; if (!flag) { SuperHidden=false; } } public void setSuperHidden(final boolean flag) { SuperHidden=flag; } public void toggleHidden() { Hidden=!Hidden; if (!Hidden) { SuperHidden=false; } } public boolean isHidden(final boolean original) { if (!original&&testConditional("visible")) { return false; } if (!original &&(testConditional("hidden")||testConditional("superhidden"))) { return true; } return Hidden||SuperHidden; } public boolean isHidden() { return isHidden(false); } public boolean isSuperHidden(final boolean original) { if (!original&&testConditional("superhidden")) { return true; } return SuperHidden; } public boolean isSuperHidden() { return isSuperHidden(false); } public String getName() { return Name; } public void setName(String n) { Name=""; if (Cn!=null) { ConstructionObject o=Cn.find(n); while (o!=null&&o!=this) { n=n+"*"; o=Cn.find(n); } } Name=n; } public void setNameCheck(String n) throws ConstructionException { boolean extend=false; Name=""; if (Cn!=null) { ConstructionObject o=Cn.find(n); if (o!=null&&o!=this) { n=n+"*"; o=Cn.find(n); extend=true; } } Name=n; if (extend) { throw new ConstructionException(Global.name("exception.double")); } } public void setNameWithNumber(String n) { Name=""; if (Cn!=null) { ConstructionObject o=Cn.find(n); if (o!=null) { while (o!=null&&o!=this) { setName(); n=Name; Name=""; o=Cn.find(n); } Name=n; } else { Name=n; } } else { Name=n; } } public void edit(final ZirkelCanvas zc, boolean forcevisible, boolean forcefocus) { eric.bar.JPropertiesBar.EditObject(this, forcevisible, forcefocus); } /** * Service routine to draw a string from upper left coordinates. Position is * at TX1, TX2. */ public void drawLabel(final MyGraphics g, final String s) { g.drawStringExtended(s, TX1, TY1); TX2=TX1+g.stringWidth(s); TY2=TY1+g.stringHeight(s); } public void setFont(final MyGraphics g) { g.setFont(Large, Bold); } /** * Service routine to draw a string centered at x,y */ public void drawCenteredLabel(final MyGraphics g, final String s, final ZirkelCanvas zc, final double x, final double y, final double xo, final double yo) { double ws=g.stringWidth(s), hs=g.stringHeight(s); TX1=zc.col(x+xo)-ws/2; TY1=zc.row(y+yo)-hs/2; g.drawStringExtended(s, TX1, TY1); TX2=TX1+ws; TY2=TY1+hs; } /** * Service routine to draw a string at x,y but offset into direction -vy,vx * so that it does not intersect the direction vx,vy. r=(vx,vy) is assumed * to be normalized. */ public void drawLabel(final MyGraphics g, final String s, final ZirkelCanvas zc, final double x, final double y, final double vx, final double vy, final double xo, final double yo) { double ws=g.stringWidth(s), hs= g.stringHeight(s); final double w=zc.dx(ws), h=zc.dy(hs); final double d1=Math.abs(-w*vy+h*vx); final double d2=Math.abs(w*vy+h*vx); double d=d1; if (d2>d) { d=d2; } final double dd=zc.dy(2*zc.pointSize()); TX1=zc.col(x-vy*(d+3*dd)/2+xo)-ws/2; TY1=zc.row(y+vx*(d+3*dd)/2+yo)-hs/2; g.drawStringExtended(s, TX1, TY1); TX2=TX1+ws; TY2=TY1+hs; } /** * Service routine to draw a string at x,y but offset into direction -vy,vx * so that it does not intersect the direction vx,vy. r=(vx,vy) is assumed * to be normalized. */ public void drawPointLabel(final MyGraphics g, final String s, final ZirkelCanvas zc, final double x, final double y, final double vx, final double vy, final double xo, final double yo) { double ws=g.stringWidth(s), hs=g.stringHeight(s); final double w=zc.dx(ws), h=zc.dy(hs); final double d1=Math.abs(-w*vy+h*vx); final double d2=Math.abs(w*vy+h*vx); double d=d1; if (d2>d) { d=d2; } final double dd=zc.dy(2*zc.pointSize()); if (Math.abs(d*vx)>h+2*dd) { d=Math.abs((h+2*dd)/vx); } final double xp=x-vy*d/2, yp=y+vx*d/2; TX1=zc.col(xp-vy*dd*1.5+xo)-ws/2; TY1=zc.row(yp+vx*dd*1.5+yo)-hs/2; g.drawStringExtended(s, TX1, TY1); TX2=TX1+ws; TY2=TY1+hs; } /** * Save the object in XML form. */ public void save(final XmlWriter xml) { xml.startTagStart(getTag()); xml.printArg("name", Name); if (AliasES!=null) { xml.printArg("alias", AliasES.toString()); } xml.printArg("n", ""+NCount); if (ColorIndex!=0) { xml.printArg("color", ""+ColorIndex); } if (SpecialColor!=null) { xml.printArg("scolor", SpecialColor.getRedExpression()+",," +SpecialColor.getGreenExpression()+",,"+SpecialColor.getBlueExpression()); } if (ColorType==THICK) { xml.printArg("type", "thick"); } if (ColorType==THIN) { xml.printArg("type", "thin"); } if (ColorType==INVISIBLE) { xml.printArg("type", "invisible"); } if (SuperHidden) { xml.printArg("hidden", "super"); } else if (Hidden) { xml.printArg("hidden", "true"); } if (ShowName) { xml.printArg("showname", "true"); } if (ShowValue) { xml.printArg("showvalue", "true"); } if (Back) { xml.printArg("background", "true"); } if (XcOffset!=0.0) { xml.printArg("xcoffset", ""+XcOffset); } if (YcOffset!=0.0) { xml.printArg("ycoffset", ""+YcOffset); } if (KeepClose) { xml.printArg("keepclose", "true"); } if (Parameter) { xml.printArg("parameter", "true"); } if (MainParameter) { xml.printArg("mainparameter", "true"); } if (Target) { xml.printArg("target", "true"); xml.printArg("macroFinalIndex", ""+MacroFinalIndex); } if (Tracked) { xml.printArg("tracked", "true"); } if (Break) { if (HideBreak) { xml.printArg("hidebreak", "true"); } else { xml.printArg("break", "true"); } } if (Solid&&maybeTransparent()&&isFilled()) { xml.printArg("solid", "true"); } if (!Unit.equals("")) { xml.printArg("unit", Unit); } if (Bold) { xml.printArg("bold", "true"); } if (Large) { xml.printArg("large", "true"); } if (isDPObject()) { xml.printArg("dp_mode", ""+dp_mode); } if (haveConditionals()) { int i=0; final Enumeration e=Conditionals.elements(); while (e.hasMoreElements()) { final Conditional c=(Conditional) e.nextElement(); xml.printArg("ctag"+i, c.getTag()); xml.printArg("cexpr"+i, c.getExpression().toString()); i++; } } printArgs(xml); xml.startTagEnd(); xml.print(Text); xml.endTag(getTag()); xml.println(); } public void printArgs(final XmlWriter xml) { } public void updateText() { } public void setConstruction(final Construction c) { Cn=c; inConstruction=true; setNameWithNumber(Name); // make sure the name is not double } public boolean showName(final boolean original) { if (!original&&testConditional("showname")) { return true; } return ShowName||(Indicated&&ShowIndicatedName); } public boolean showName() { return showName(false); } public void setShowName(final boolean f) { ShowName=f; } public boolean showValue(final boolean original) { if (!original&&testConditional("showvalue")) { return true; } return ShowValue; } public boolean showValue() { return showValue(false); } public void setShowValue(final boolean f) { ShowValue=f; } /** * Determine the string to be displayed onscreen. * * @return "", if there should be no display. */ static String findIndice(final String s) { return ""; } public Boolean is2DObject() { return false; } public Boolean isTellsSon() { //William Tell's son has an arrow over him //Only a Vector is supposed to have an arrow over him... return false; } public String getDisplayText() { // If the name of the object starts with simple letters only // and ends with a number, then place this number in subscript // and use the $-character around to send the string to HotEqn String name=Name.replaceAll("^([a-zA-Z]+)([0-9]+)$", "$1_{$2}"); if (AliasES!=null) { name=AliasES.evaluate(); } else if (name.indexOf("~")>0) { name=name.substring(0, name.indexOf("~")); } if(!name.startsWith("$")) { name="$"+name; } if (showName()) { if (showValue()) { final String value=getDisplayValue(); if (value.equals("")) { return name+"$"; } if (name.endsWith("$") && name.length()!=1) { name=name.substring(0, name.length()-1); } if (name.endsWith("_")&&name.length()>1) { name=name.substring(0, name.length()-1); //} else if (!this.is2DObject()) { // name=name+" = "; } else if (this.isTellsSon() && AliasES==null && name.length()!=1){ name="$\\overrightarrow{"+name.substring(1,name.length())+"}"; } if (Unit.equals("")) { return name+value+"$"; } else { return name+value+Unit+"$"; } } else { if (name.indexOf("~")>0&&AliasES==null) { name=name.substring(0, name.indexOf("~")); } if (this.isTellsSon() && AliasES==null && name.length()!=1) { //System.out.println(name.length()); name="$\\overrightarrow{"+name.substring(1,name.length())+"}"; } return name+"$"; } } else if (showValue()) { if (Unit.equals("")) { return "$"+getDisplayValue()+"$"; } else { return "$"+getDisplayValue()+Unit+"$"; } } return ""; } /** * Replace the expression in %...% by their values * * @param s * @param zc * may be null (no direct search of object) * @return */ public String replaceExpressions(String s) { // System.out.println(s); final boolean latex=s.startsWith("$"); int searchpos=0; while (s.indexOf("%", searchpos)>=0) { final int h1=s.indexOf("%", searchpos); final String s1=s.substring(h1+1); final int h2=s1.indexOf("%"); if (h2==0) { s=s.substring(0, h1)+"%"+s1.substring(1); searchpos+=1; } else if (h2>=0) { String var=s1.substring(0, h2); boolean showeq=false, forceplus=false; if (var.startsWith("~")) // show equation { var=var.substring(1); showeq=true; } else if (var.startsWith("+")) // force + { var=var.substring(1); forceplus=true; } final ConstructionObject o=getConstruction().find(var); // System.out.println(o+" "+var); String repl=""; if (o!=null) { DL.add(o); } try { if (showeq) { repl=o.getEquation(); } else { if (o!=null) { final double x=round(o.getValue()); if (forceplus&&x>=0) { repl="+"; } if (x==Math.floor(x+0.1)) { repl=repl+(int) (x); } else { repl=repl+x; } } else { final Expression ex=new Expression(var, getConstruction(), this); if (ex.isValid()) { final Enumeration e=ex.getDepList().elements(); while (e.hasMoreElements()) { DL.add((ConstructionObject) e.nextElement()); } } final double x=round(ex.getValue()); if (forceplus&&x>=0) { repl="+"; } if (x==Math.floor(x+0.1)) { repl=repl+(int) (x); } else { repl=repl+x; } } } } catch (final Exception ex) { if (latex) { repl="\\circ"; } else { repl="???"; // ex.printStackTrace(); } } s=s.substring(0, h1)+repl+s1.substring(h2+1); searchpos=h1+repl.length(); } else { break; } } return s; } /** * Add the dependencies in expressions in %...% in the string. * * @param s * @param zc * may be null (no direct search of object) * @return */ public void addDepInExpressions(final String s) { replaceExpressions(s); } /** * Replace the expression in %...% by their translated epressions. * * @param s * @param zc * may be null (no direct search of object) * @return */ public String translateExpressions(String s) { // System.out.println(s); s.startsWith("$"); int searchpos=0; while (s.indexOf("%", searchpos)>=0) { // System.out.println(searchpos); final int h1=s.indexOf("%", searchpos); final String s1=s.substring(h1+1); final int h2=s1.indexOf("%"); if (h2==0) { s=s.substring(0, h1)+"%"+s1.substring(1); searchpos+=1; } else if (h2>=0) { String var=s1.substring(0, h2); boolean showeq=false; String repl=""; if (var.startsWith("~")) // show equation { var=var.substring(1); showeq=true; repl="+"; } else if (var.startsWith("+")) // force + { var=var.substring(1); repl="~"; } ConstructionObject o=getConstruction().find(var); if (o!=null) { o=o.getTranslation(); // System.out.println(o+" "+var); } if (showeq) { repl=repl+o.getName(); } else { if (o!=null) { repl=repl+o.getName(); } else { final Expression ex=new Expression(var, getConstruction(), this); if (ex.isValid()) { ex.translate(); repl=repl+ex.toString(); } else { return s; } } } // System.out.println(repl); s=s.substring(0, h1)+"%"+repl+"%" +s1.substring(h2+1); searchpos=h1+repl.length()+2; // System.out.println(s); } else { break; } } return s; } /** * To be overridden by the objects. * * @return The string to display the value (length, coordinates) of the * object. */ public String getDisplayValue() { return ""; } public String getCDPDisplayValue() { return getDisplayValue(); } // Only for Construction Display Panel : public String getCDPSizeDisplay() { return getCDPDisplayValue()+getUnit(); } /** * Service function to round a value. */ public double round(final double x) { return round(x, ZirkelCanvas.EditFactor); } public double roundDisplay(final double x) { return round(x, ZirkelCanvas.LengthsFactor); } public double round(final double x, final double Rounder) { return Math.round(x*Rounder)/Rounder; } // The following procedures are for label offset public void setcOffset(final double x, final double y) { XcOffset=x; YcOffset=y; } public double xcOffset() { return XcOffset; } public double ycOffset() { return YcOffset; } public void setOffset(final int x, final int y) // deprecated { XOffset=x; YOffset=y; } public boolean isKeepClose() { return KeepClose; } public void setKeepClose(final double x, final double y) // Override! { KeepClose=true; XcOffset=x; YcOffset=y; } public void setKeepClose(final boolean flag) { if (KeepClose&&!flag) { XcOffset=0; YcOffset=0; } KeepClose=flag; } public boolean canKeepClose() // Override! { return false; } public void translateOffset(final ZirkelCanvas zc) { if (XOffset!=0||YOffset!=0) { XcOffset=zc.dx(XOffset); YcOffset=zc.dy(-YOffset); XOffset=YOffset=0; } } public int getColorType(final boolean original) { if (!original&&testConditional("thin")) { return THIN; } if (!original&&testConditional("thick")) { return THICK; } if (!original&&testConditional("normal")) { return NORMAL; } return ColorType; } public int getColorType() { return getColorType(false); } public void setColorType(final int type) { ColorType=type; setColor(ColorIndex, SpecialColor); } public boolean isParameter() { return Parameter||MainParameter; } public boolean isMainParameter() { return MainParameter; } public void clearParameter() { Parameter=false; MainParameter=false; } public void setMainParameter(boolean b) { final Enumeration e=secondaryParams(); while (e.hasMoreElements()) { final ConstructionObject o=(ConstructionObject) e.nextElement(); o.setParameter(b); } MainParameter=b; } public void setParameter(boolean b) { Parameter=b; } public static DepList DL=new DepList(); /** * Return an enumeration of objects, that this object depends on. This * should usually called from children via super. */ public Enumeration depending() { DL.reset(); if (haveConditionals()) { final Enumeration e=Conditionals.elements(); while (e.hasMoreElements()) { final Conditional c=(Conditional) e.nextElement(); final Enumeration ex=c.getExpression().getDepList().elements(); while (ex.hasMoreElements()) { DL.add((ConstructionObject) ex.nextElement()); } } } if (AliasES!=null) { AliasES.addDep(this); } return DL.elements(); } /** * Test, if the object directly depends on another object. */ public boolean dependsOn(final ConstructionObject o) { final Enumeration e=depending(); while (e.hasMoreElements()) { final ConstructionObject o1=(ConstructionObject) e.nextElement(); if (o1==o) { return true; } } return false; } /** * Return an enumeration of objects, which can be set as secondary * parameters, whenever this object is selected as main parameter. */ public Enumeration secondaryParams() { DL.reset(); return DL.elements(); } public ConstructionObject[] getDepArray() { depending(); return DL.getArray(); } public Enumeration depset(final ConstructionObject o1) { DL.add(o1); return DL.elements(); } public Enumeration depset(final ConstructionObject o1, final ConstructionObject o2) { DL.add(o1); DL.add(o2); return DL.elements(); } public Enumeration depset(final ConstructionObject o1, final ConstructionObject o2, final ConstructionObject o3) { DL.add(o1); DL.add(o2); DL.add(o3); return DL.elements(); } public void setFlag(final boolean flag) { Flag=flag; } public boolean isFlag() { return Flag; } public void setRekFlag(final boolean flag) { RekFlag=flag; } public boolean isRekFlag() { return RekFlag; } public void setTarget(final boolean flag) { Target=flag; } public void setMacroFinalIndex(final int u) { MacroFinalIndex=u; } public boolean isTarget() { return Target; } public int getMacroFinalIndex() { return MacroFinalIndex; } public void setKeep(final boolean flag) { Keep=flag; } public boolean isOwnedByControl() { return false; } public void setOwnedByControl(boolean b) { } public boolean isKeep() { return Keep; } public boolean equalsTo(final ConstructionObject o) { return super.equals(o); } public boolean equals(final ConstructionObject o) { return false; } public boolean equals(final double x, final double y) { return Math.abs(x-y)<1e-8; } int OldColorIndex; public void setJobTarget(final boolean flag) { if (flag) { OldColorIndex=ColorIndex; setColor(-1); } else if (JobTarget) { setColor(OldColorIndex, SpecialColor); } JobTarget=flag; } public boolean isJobTarget() { return JobTarget; } public void updateCircleDep() { } public void clearCircleDep() { } /** * This clones the object for macro construction. NOTE: This must be * overriden in all items to translate the mother objects. */ public ConstructionObject copy(final double x, final double y) { ConstructionObject o=null; try { o=(ConstructionObject) clone(); setTranslation(o); o.translateConditionals(); o.translate(); o.setName(); o.updateText(); o.setBreak(false); Cn.getH(); // o.setTarget(false); } catch (final Exception e) { } return o; } // public ConstructionObject copy () // { ConstructionObject o=null; // try // { o=(ConstructionObject)clone(); // setTranslation(o); // o.translateConditionals(); // o.translate(); // o.setName(); // o.updateText(); // o.setBreak(false); // Cn.getH(); // // o.setTarget(false); // } // catch (Exception e) {} // return o; // } public Construction getConstruction() { return Cn; } /** * Get the value of an object or throw an exception (e.g. if invalid). Not * all objects have a value. */ public double getValue() throws ConstructionException { throw new NoValueException(Valid); } public void applyDefaults(ConstructionObject o) { ConstructionObject cpy=o.copy(0, 0); cpy.setTargetDefaults(); setShowName(cpy.showName()); setShowValue(cpy.showValue()); setColor(cpy.getColorIndex()); setColorType(cpy.getColorType()); setFilled(cpy.isFilled()); setSolid(cpy.isSolid()); setHidden(cpy.isHidden()); setObtuse(cpy.getObtuse()); setLarge(cpy.isLarge()); setBold(cpy.isBold()); setPartial(cpy.isPartial()); Cn.updateCircleDep(); } public void setDefaults() { setShowName(Cn.ShowNames); setShowValue(Cn.ShowValues); setColor(Cn.DefaultColor, SpecialColor); setColorType(Cn.DefaultColorType); setHidden(Cn.Hidden); setObtuse(Cn.Obtuse); setSolid(Cn.Solid); setLarge(Cn.LargeFont); setBold(Cn.BoldFont); } public void setTargetDefaults() { setShowName(Cn.ShowNames); setShowValue(Cn.ShowValues); setColor(Cn.DefaultColor, SpecialColor); setColorType(Cn.DefaultColorType); } public boolean contains(final PointObject p) { return false; } public boolean canFix() { return false; } public void setFixed(final String o) { } public boolean isBack(final boolean original) { if (!original&&testConditional("background")) { return true; } return Back; } public boolean isBack() { return isBack(false); } public void setBack(final boolean flag) { Back=flag; } public void setInConstruction(final boolean flag) { inConstruction=flag; } public boolean isInConstruction() { return inConstruction; } /** * This is called after the loading of a construction has been finished. * PointObject uses this to bind to a line or circle, which is defined AFTER * it. * * @param c * The construction this object is in. */ public void laterBind(final Construction c) { } /** * This is called after macro definition or execution is complete. * PrimitiveCircleObject uses it to translate the restriction points in its * copy. * * @param c * The construction this object is in. */ public void laterTranslate(final Construction c) { } public void setFilled(final boolean flag) { } public boolean isFilled() { return false; } public boolean isFilledForSelect() { return isFilled(); } public boolean getObtuse() { return Obtuse; } public void setObtuse(final boolean flag) { Obtuse=flag; } public String getDescription() { return ""; } public void round() { } public boolean isFixed() { return false; } public boolean isBreak() { return Break; } public void setBreak(final boolean flag) { Break=flag; HideBreak=false; } public boolean isHideBreak() { return HideBreak; } public void setHideBreak(final boolean flag) { HideBreak=flag; Break=flag; } public boolean isSolid(final boolean original) { if (!original&&testConditional("solid")) { return true; } return Solid; } public boolean isSolid() { return isSolid(false); } public void setSolid(final boolean solid) { Solid=solid; } public boolean maybeTransparent() { return false; } public boolean locallyLike(final ConstructionObject o) { return false; } public double Value=1000; public int compare(final SortObject o) { final ConstructionObject ob=(ConstructionObject) o; if (ob.Value1e-10) { s=s+roundDisplay(x); } if (tag.equals("")) { return s; } else if (s.equals("")||s.equals("-")) { return s+tag; } else { return s+"*"+tag; } } public String helpDisplayNumber(final boolean start, double x) { String s=""; if (Math.abs(x)<1e-10) { return s; } if (x<0) { s="-"; } else if (!start) { s="+"; } x=Math.abs(x); return s+roundDisplay(x); } public boolean visible(final ZirkelCanvas zc) { return selected()||ColorType!=INVISIBLE||zc.showHidden(); } public boolean isBold() { return Bold; } public void setBold(final boolean bold) { Bold=bold; } public boolean isLarge() { return Large; } public void setLarge(final boolean large) { Large=large; } // Routines for conditional formatting public void addConditional(final String tag, final Expression expr) { final Conditional c=new Conditional(tag, expr); if (Conditionals==null) { Conditionals=new Vector(); } Conditionals.addElement(c); } public Expression getConditional(final String tag) { if (Conditionals==null) { return null; } final Enumeration e=Conditionals.elements(); while (e.hasMoreElements()) { final Conditional c=(Conditional) e.nextElement(); if (c.getTag().equals(tag)) { return c.getExpression(); } } return null; } public boolean haveConditional(final String tag) { final Expression ex=getConditional(tag); return (ex!=null); } /** * Test if the conditional "tag" evaluates to true. * * @param tag */ public boolean testConditional(final String tag) { final Expression ex=getConditional(tag); if (ex==null) { return false; } try { if (ex.getValue()!=0) { return true; } } catch (final Exception e) { } return false; } public void clearConditionals() { Conditionals=null; } public void translateConditionals() { if (Conditionals!=null) { final Enumeration e=Conditionals.elements(); clearConditionals(); while (e.hasMoreElements()) { final Conditional c=(Conditional) e.nextElement(); final String expr=c.getExpression().toString(); final Expression enew=new Expression(expr, getConstruction(), this); enew.translate(); addConditional(c.getTag(), enew); } } if (AliasES!=null) { setAlias(AliasES.toString()); AliasES.translate(); } } public boolean haveConditionals() { return Conditionals!=null; } public void checkConditionals() throws ConstructionException { if (Conditionals==null) { return; } final Enumeration e=Conditionals.elements(); while (e.hasMoreElements()) { final Conditional c=(Conditional) e.nextElement(); if (!c.getExpression().isValid()) { throw new ConstructionException(c.getExpression().getErrorText()); } c.getExpression().getValue(); } } /** * Get the z-buffer for this object. * * @return double value z * @throws ConstructionException */ public double getZ() throws ConstructionException { final Expression e=getConditional("z"); if (e==null) { throw new ConstructionException(""); } return e.getValue(); } public boolean canDisplayName() { return true; } public int getNCount() { return NCount; } public void setNCount(final int count) { NCount=count; } ExpressionString AliasES=null; public String getAlias() { if (AliasES==null) { return null; } else { return AliasES.toString(); } } public void setAlias(final String s) { if ((s==null)||("".equals(s))) { AliasES=null; } else { AliasES=new ExpressionString(s, this); } } /** * A general workplace for rekursive validation. VRek gets the elements that * need to be updated. */ public MyVector VRek; public boolean RekValidating=false; public static final int DescriptionState=0, FormulaState=1, SizeState=2; /** * Get a display string for the Lister class. */ public String getElementString(final int state) { String s=""; switch (state) { case DescriptionState: s=getName()+" : "+FileName.chop(getText(), 80); break; case SizeState: s=getName()+" : "+FileName.chop(getCDPSizeDisplay(), 80); break; case FormulaState: s=getName()+" : "+FileName.chop(getEquation(), 80); break; } if (isSuperHidden()) { s="( "+s+" )"; } if (isHideBreak()) { s="** "+s; } else if (isBreak()) { s="* "+s; } if (!valid()) { s="? "+s; } if (this instanceof MoveableObject &&((MoveableObject) this).moveable()) { s="> "+s; } if (s.startsWith(getName())) { s=" "+s; } return s; } public String getElementString() { return getElementString(0); } /** * Get a color for the element in the display color. */ public Color getElementColor() { if (isJobTarget()) { return ZirkelFrame.TargetColor; } else if (indicated()) { return ZirkelFrame.IndicateColor; } else if (selected()) { return ZirkelFrame.SelectColor; } return getColor(); } public boolean SpecialParameter=false; public boolean isSpecialParameter() { return SpecialParameter; } public void setSpecialParameter(final boolean flag) { SpecialParameter=flag; } /** * Service function to extract a point from an expression * * @param E * @return point object or null */ static public PointObject getPointObject(final Expression E) { if (E==null) { return null; } final ConstructionObject o=E.getObject(); if (o==null||!(o instanceof PointObject)) { return null; } return (PointObject) o; } // provide a reusable array for each construction object MyVector MV; boolean MVInUse=false; /** * Get an empty MyVector. * * @return MyVector instance */ public MyVector getVector() { if (MVInUse) { return new MyVector(); } if (MV==null) { MV=new MyVector(); } MVInUse=true; return MV; } /** * MyVector no longer needed. */ public void discardMV() { MVInUse=false; MV.removeAllElements(); } public double getX() { return 0.0; } public double getY() { return 0.0; } public double getX3D() { return 0.0; } public double getY3D() { return 0.0; } public double getZ3D() { return 0.0; } public double getR() { return 0.0; } public double getR3D() { return 0.0; } public void setType(final int i) { } public int getType() { return 0; } public boolean isPartial() { return false; } public void setPartial(final boolean bool) { } public void setDisplaySize(final int i) { } public int getDisplaySize() { return 0; } public void setExpression(final String expr, final Construction c) throws ConstructionException { } public String getExpression() { return ""; } public boolean fixed() { return true; } public boolean fixed3D() { return true; } public boolean fixedCoord(){ return true; } public boolean fixedCoord3D(){ return true; } public String getEX() { return ""; } public String getEY() { return ""; } public String getEX3D() { return ""; } public String getEY3D() { return ""; } public String getEZ3D() { return ""; } public String getEXpos() { return getEX(); } public String getEYpos() { return getEY(); } public String getEX3Dpos() { return getEX3D(); } public String getEY3Dpos() { return getEY3D(); } public String getEZ3Dpos() { return getEZ3D(); } public void setFixed(final boolean bool) { } public void setFixed3D(final boolean bool) { } public void setFixed(final String x, final String y) { } public void setFixed(final boolean bool, final String r) throws ConstructionException { } public void setFixed3D(final boolean bool, final String r) throws ConstructionException { } public void setFixed(final String x3D, final String y3D, final String z3D) { } public void move(final double x, final double y) { } public void move3D(final double x, final double y, final double z) { } public String getPrompt() { return ""; } public void setPrompt(final String prompt) { } public String getMin() { return ""; } public String getMax() { return ""; } public int getDistance(final PointObject P) { return Integer.MAX_VALUE; } public void setSlider(final String smin, final String smax) { } public void setSlider(final boolean bool) { } public boolean isSlider() { return false; } public String getStringLength() { return ""; } public String getStringLength3D() { return ""; } public void setDragable(final boolean f) { } public boolean isDragable() { return false; } public String getE() { return ""; } public String getLines() { return ""; } public void setLines(final String o) { } public double getIncrement() { return 0.0; } public void setIncrement(final double inc) { } public boolean isInside() { return false; } public void setInside(final boolean flag) { } public boolean isSpecial() { return false; } public void setSpecial(final boolean f) { } public void clearConditional(final String tag) { if (haveConditional(tag)) { if (Conditionals.size()==1) { Conditionals=null; return; } for (int i=0; i