2346 lines
62 KiB
Java
2346 lines
62 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.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&&x<TX2&&y>TY1&&y<TY2;
|
|
}
|
|
|
|
public void setTracked(final boolean flag) {
|
|
Tracked=flag;
|
|
}
|
|
|
|
public void setSelected(final boolean flag) {
|
|
Selected=flag;
|
|
StrongSelected=false;
|
|
}
|
|
|
|
public void setStrongSelected(final boolean flag) {
|
|
StrongSelected=flag;
|
|
}
|
|
|
|
public boolean isStrongSelected() {
|
|
return StrongSelected;
|
|
}
|
|
|
|
public boolean selected() {
|
|
return Selected||StrongSelected;
|
|
}
|
|
|
|
public boolean tracked() {
|
|
return Tracked;
|
|
}
|
|
|
|
public void setLabelSelected(final boolean flag) {
|
|
LabelSelected=flag;
|
|
}
|
|
|
|
public boolean isSelectable() {
|
|
return valid()&&!JobTarget&&Selectable;
|
|
}
|
|
|
|
public void validate() {
|
|
Valid=true;
|
|
}
|
|
|
|
public boolean valid() {
|
|
return Valid;
|
|
}
|
|
|
|
public boolean displays(final ZirkelCanvas zc) {
|
|
if (SuperHidden) {
|
|
return false;
|
|
}
|
|
if (!zc.showHidden()
|
|
&&(testConditional("hidden")||testConditional("superhidden"))) {
|
|
return false;
|
|
}
|
|
return Valid&&!BreakHide&&(!Hidden||zc.showHidden());
|
|
}
|
|
|
|
public boolean indicated() {
|
|
return Indicated;
|
|
}
|
|
|
|
public void setIndicated(final boolean f) {
|
|
Indicated=f;
|
|
}
|
|
|
|
public void setIndicated(final boolean f, final boolean showname) {
|
|
Indicated=f;
|
|
ShowIndicatedName=showname;
|
|
}
|
|
|
|
/**
|
|
* @return The change of the last validation for points bound to lines,
|
|
* which are defined later.
|
|
*/
|
|
public double changedBy() {
|
|
return 0.0;
|
|
}
|
|
|
|
/**
|
|
* Routines to parse descriptive text in various languages.
|
|
*/
|
|
static public String text1(final String format, final String s1) {
|
|
final StringTokenizer t=tokenize(format);
|
|
String s="Illegal Format";
|
|
try {
|
|
s=t.nextToken()+s1;
|
|
s=s+t.nextToken();
|
|
} catch (final Exception e) {
|
|
}
|
|
return s.trim();
|
|
}
|
|
|
|
static public String text2(final String format, final String s1,
|
|
final String s2) {
|
|
final StringTokenizer t=tokenize(format);
|
|
String s="Illegal Format";
|
|
try {
|
|
s=t.nextToken()+s1+t.nextToken()+s2;
|
|
s=s+t.nextToken();
|
|
} catch (final Exception e) {
|
|
}
|
|
return s.trim();
|
|
}
|
|
|
|
static public String text3(final String format, final String s1,
|
|
final String s2, final String s3) {
|
|
final StringTokenizer t=tokenize(format);
|
|
String s="Illegal Format";
|
|
try {
|
|
s=t.nextToken()+s1+t.nextToken()+s2+t.nextToken()+s3;
|
|
s=s+t.nextToken();
|
|
} catch (final Exception e) {
|
|
}
|
|
return s.trim();
|
|
}
|
|
|
|
static public String text4(final String format, final String s1,
|
|
final String s2, final String s3, final String s4) {
|
|
final StringTokenizer t=tokenize(format);
|
|
String s="Illegal Format";
|
|
try {
|
|
s=t.nextToken()+s1+t.nextToken()+s2+t.nextToken()+s3
|
|
+t.nextToken()+s4;
|
|
s=s+t.nextToken();
|
|
} catch (final Exception e) {
|
|
}
|
|
return s;
|
|
}
|
|
|
|
static public String textAny(final String format, final String ss[]) {
|
|
final StringTokenizer t=tokenize(format);
|
|
String s="Illegal Format";
|
|
try {
|
|
s=t.nextToken();
|
|
for (int i=0; i<ss.length; i++) {
|
|
s=s+ss[i];
|
|
if (i<ss.length-1) {
|
|
s=s+", ";
|
|
}
|
|
}
|
|
s=s+t.nextToken();
|
|
} catch (final Exception e) {
|
|
}
|
|
//return s;
|
|
return s.trim();
|
|
}
|
|
|
|
static private StringTokenizer tokenize(String format) {
|
|
if (format.startsWith("%")) {
|
|
format=" "+format;
|
|
}
|
|
if (format.endsWith("%")) {
|
|
format=format+" ";
|
|
}
|
|
return new StringTokenizer(format, "%");
|
|
}
|
|
|
|
public void setText(final String s, final boolean user) {
|
|
if (!user&&Text.endsWith(" ")) {
|
|
return;
|
|
}
|
|
Text=s;
|
|
}
|
|
|
|
public void setText(final String s) {
|
|
setText(s, false);
|
|
}
|
|
|
|
public String getText() {
|
|
return Text;
|
|
}
|
|
|
|
public boolean labelSelected() {
|
|
return LabelSelected;
|
|
}
|
|
|
|
// public void setColor(Color c){
|
|
// C=c;
|
|
// }
|
|
/**
|
|
* Set the object color by index.
|
|
*/
|
|
public void setColor(final int index) {
|
|
SpecialColor=null;
|
|
if (index<0) {
|
|
C=Color.pink;
|
|
} else {
|
|
if (ColorType==THIN) {
|
|
C=ZirkelFrame.LightColors[index];
|
|
} else {
|
|
C=ZirkelFrame.Colors[index];
|
|
}
|
|
ColorIndex=index;
|
|
}
|
|
}
|
|
|
|
public String getRed() {
|
|
if (SpecialColor==null) {
|
|
return "";
|
|
} else {
|
|
return SpecialColor.getRedExpression();
|
|
}
|
|
}
|
|
|
|
public String getGreen() {
|
|
if (SpecialColor==null) {
|
|
return "";
|
|
} else {
|
|
return SpecialColor.getGreenExpression();
|
|
}
|
|
}
|
|
|
|
public String getBlue() {
|
|
if (SpecialColor==null) {
|
|
return "";
|
|
} else {
|
|
return SpecialColor.getBlueExpression();
|
|
}
|
|
}
|
|
|
|
public void setRed(String col) throws ConstructionException {
|
|
Expression red=new Expression(col, getConstruction(), this);
|
|
if (red.isValid()) {
|
|
if (SpecialColor==null) {
|
|
SpecialColor=new ExpressionColor(Cn, this);
|
|
}
|
|
SpecialColor.setRed(col);
|
|
} else {
|
|
throw new ConstructionException(red.getErrorText());
|
|
}
|
|
}
|
|
|
|
public void setGreen(String col) throws ConstructionException {
|
|
Expression green=new Expression(col, getConstruction(), this);
|
|
if (green.isValid()) {
|
|
if (SpecialColor==null) {
|
|
SpecialColor=new ExpressionColor(Cn, this);
|
|
}
|
|
SpecialColor.setGreen(col);
|
|
} else {
|
|
throw new ConstructionException(green.getErrorText());
|
|
}
|
|
}
|
|
|
|
public void setBlue(String col) throws ConstructionException {
|
|
Expression blue=new Expression(col, getConstruction(), this);
|
|
if (blue.isValid()) {
|
|
if (SpecialColor==null) {
|
|
SpecialColor=new ExpressionColor(Cn, this);
|
|
}
|
|
SpecialColor.setBlue(col);
|
|
} else {
|
|
throw new ConstructionException(blue.getErrorText());
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Set the object color by index.
|
|
*
|
|
* @param index
|
|
* @param col
|
|
*/
|
|
public void setColor(final int index, final ExpressionColor col) {
|
|
|
|
if (col==null) {
|
|
if (ColorType==THIN) {
|
|
C=ZirkelFrame.LightColors[index];
|
|
} else {
|
|
C=ZirkelFrame.Colors[index];
|
|
}
|
|
ColorIndex=index;
|
|
SpecialColor=null;
|
|
} else {
|
|
SpecialColor=col;
|
|
C=SpecialColor.getColor();
|
|
}
|
|
}
|
|
|
|
public void setColor(final int index, final Color col) {
|
|
if (col==null) {
|
|
if (ColorType==THIN) {
|
|
C=ZirkelFrame.LightColors[index];
|
|
} else {
|
|
C=ZirkelFrame.Colors[index];
|
|
}
|
|
ColorIndex=index;
|
|
SpecialColor=null;
|
|
} else {
|
|
SpecialColor=new ExpressionColor(Cn, this);
|
|
SpecialColor.setColor(col);
|
|
C=SpecialColor.getColor();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the current color index. If there is a conditional for the color,
|
|
* test it and use it.
|
|
*/
|
|
public int getColorIndex(final boolean original) {
|
|
if (!original&&haveConditionals()) {
|
|
for (int i=0; i<ZirkelFrame.ColorStrings.length; i++) {
|
|
if (testConditional(ZirkelFrame.ColorStrings[i])) {
|
|
return i;
|
|
}
|
|
}
|
|
}
|
|
return ColorIndex;
|
|
}
|
|
|
|
public int getConditionalColor() {
|
|
if (haveConditionals()) {
|
|
for (int i=0; i<ZirkelFrame.ColorStrings.length; i++) {
|
|
if (testConditional(ZirkelFrame.ColorStrings[i])) {
|
|
return i;
|
|
}
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
public synchronized Color getSpecialColor() {
|
|
if (SpecialColor==null) {
|
|
return null;
|
|
}
|
|
return SpecialColor.getColor();
|
|
}
|
|
|
|
public synchronized void setSpecialColor(final Color c) {
|
|
if (c!=null) {
|
|
SpecialColor=null;
|
|
SpecialColor=new ExpressionColor(Cn, this);
|
|
SpecialColor.setColor(c);
|
|
}
|
|
}
|
|
|
|
public void setSpecialColor(String red, String green, String blue) {
|
|
SpecialColor=null;
|
|
SpecialColor=new ExpressionColor(Cn, this);
|
|
SpecialColor.setColor(red, green, blue);
|
|
}
|
|
|
|
public int getColorIndex() {
|
|
return getColorIndex(false);
|
|
}
|
|
|
|
public Color getColor() {
|
|
Color Col, LightCol, BrighterCol, BrighterLightCol;
|
|
// it's a personnal color :
|
|
if (SpecialColor!=null) {
|
|
final int i=getConditionalColor();
|
|
if (i!=-1) {
|
|
Col=ZirkelFrame.Colors[i];
|
|
LightCol=ZirkelFrame.LightColors[i];
|
|
BrighterCol=ZirkelFrame.BrighterColors[i];
|
|
BrighterLightCol=ZirkelFrame.BrighterLightColors[i];
|
|
} else {
|
|
final double lambda=0.4;
|
|
Col=SpecialColor.getColor();
|
|
final int r=(int) (255*(1-lambda)+Col.getRed()*lambda);
|
|
final int g=(int) (255*(1-lambda)+Col.getGreen()
|
|
*lambda);
|
|
final int b=(int) (255*(1-lambda)+Col.getBlue()
|
|
*lambda);
|
|
LightCol=new Color(r, g, b);
|
|
BrighterCol=Col.brighter();
|
|
BrighterLightCol=LightCol.brighter();
|
|
}
|
|
} else {
|
|
final int i=getColorIndex();
|
|
Col=ZirkelFrame.Colors[i];
|
|
LightCol=ZirkelFrame.LightColors[i];
|
|
BrighterCol=ZirkelFrame.BrighterColors[i];
|
|
BrighterLightCol=ZirkelFrame.BrighterLightColors[i];
|
|
}
|
|
if (isJobTarget()) {
|
|
return ZirkelFrame.TargetColor;
|
|
} else if (selected()) {
|
|
return ZirkelFrame.SelectColor;
|
|
} else if (getColorType()==ConstructionObject.THIN) {
|
|
if (isHidden()) {
|
|
return BrighterLightCol;
|
|
} else {
|
|
return LightCol;
|
|
}
|
|
} else {
|
|
if (isHidden()) {
|
|
return BrighterCol;
|
|
} else {
|
|
return Col;
|
|
}
|
|
}
|
|
}
|
|
|
|
public boolean mustHide(final ZirkelCanvas zc) {
|
|
if (!Valid) {
|
|
return true;
|
|
}
|
|
if (ColorIndex>0&&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.Value<Value) {
|
|
return 1;
|
|
} else if (ob.Value==Value) {
|
|
return 0;
|
|
} else {
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
public void setSelectable(final boolean flag) {
|
|
Selectable=flag;
|
|
}
|
|
|
|
public void snap(final ZirkelCanvas zc) {
|
|
}
|
|
|
|
public String getUnit() {
|
|
return Unit;
|
|
}
|
|
|
|
public void setUnit(final String s) {
|
|
Unit=s;
|
|
}
|
|
|
|
public boolean hasUnit() {
|
|
return true;
|
|
}
|
|
|
|
public boolean isBreakHide() {
|
|
return BreakHide;
|
|
}
|
|
|
|
public void setBreakHide(final boolean flag) {
|
|
BreakHide=flag;
|
|
}
|
|
|
|
public String getEquation() {
|
|
return getDisplayValue();
|
|
}
|
|
|
|
public String helpDisplayValue(final boolean start, double x,
|
|
final String tag) {
|
|
String s="";
|
|
if (Math.abs(x)<1e-10) {
|
|
return s;
|
|
}
|
|
if (x<0) {
|
|
s="-";
|
|
} else if (!start) {
|
|
s="+";
|
|
}
|
|
x=Math.abs(x);
|
|
if (Math.abs(x-1)>1e-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<Conditionals.size(); i++) {
|
|
final Conditional c=(Conditional) Conditionals.get(i);
|
|
if (c.getTag().equals(tag)) {
|
|
Conditionals.remove(i);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|