Back to index

wims  3.65+svn20090927
ExpressionObject.java
Go to the documentation of this file.
00001 package rene.zirkel.objects;
00002 
00003 // file: PointObject.java
00004 
00005 import java.awt.*;
00006 import java.awt.event.*;
00007 import java.util.*;
00008 
00009 import rene.gui.*;
00010 
00011 import rene.util.xml.*;
00012 import rene.zirkel.*;
00013 import rene.zirkel.construction.*;
00014 import rene.zirkel.dialogs.*;
00015 import rene.zirkel.expression.*;
00016 import rene.zirkel.graphics.*;
00017 import rene.dialogs.*;
00018 
00019 class ExpressionEditDialog extends ObjectEditDialog
00020 {      TextFieldAction X,Y;
00021        TextField Expression,Prompt,Min,Max;
00022        Checkbox Fixed,Slider;
00023        ZirkelCanvas ZC;
00024        // jm.evers
00025        public String xaxis_variable;                                                                                                      
00026         public String yaxis_variable;
00027        //jm.evers
00028        
00029        public ExpressionEditDialog (Frame f, ZirkelCanvas zc, ExpressionObject o)
00030        {      super(f,Zirkel.name("edit.expression.title"),o,"expression"); 
00031               ZC=zc;
00032        }
00033        
00034        public void focusGained (FocusEvent e)
00035        {      Expression.requestFocus();
00036        }
00037        
00038        public void addFirst (Panel P)
00039        {      
00040            // jm.evers                                                                                                                    
00041                 xaxis_variable=ZirkelApplet.xaxis_variable;                                                                                
00042                 yaxis_variable=ZirkelApplet.yaxis_variable;
00043            // 
00044               ExpressionObject p=(ExpressionObject)O;
00045               X=new TextFieldAction(this,xaxis_variable,""+p.round(p.getX()));
00046               P.add(new MyLabel(""+xaxis_variable+"")); P.add(X);
00047               Y=new TextFieldAction(this,yaxis_variable,""+p.round(p.getY()));
00048               P.add(new MyLabel(""+yaxis_variable+"")); P.add(Y);
00049 /*
00050               ExpressionObject p=(ExpressionObject)O;
00051               X=new TextFieldAction(this,"X",""+p.round(p.getX()));
00052               P.add(new MyLabel(Zirkel.name("edit.point.x"))); P.add(X);
00053               Y=new TextFieldAction(this,"Y",""+p.round(p.getY()));
00054               P.add(new MyLabel(Zirkel.name("edit.point.y"))); P.add(Y);
00055 */
00056               
00057               Fixed=new Checkbox("");
00058               Fixed.setState(p.fixed());
00059               P.add(new MyLabel(Zirkel.name("edit.fixed")));
00060               P.add(Fixed);
00061               if (p.fixed())
00062               {      X.setText(p.getEX());
00063                      Y.setText(p.getEY());
00064               }
00065 
00066               Panel px=new MyPanel();
00067               px.setLayout(new GridLayout(1,0));
00068               Slider=new Checkbox("");
00069               Slider.setState(p.isSlider());
00070               P.add(new MyLabel(Zirkel.name("edit.expression.slider")));
00071               px.add(Slider);
00072               Min=new TextFieldAction(this,"Min",""+p.getMin());
00073               Max=new TextFieldAction(this,"Max",""+p.getMax());
00074               px.add(Min); px.add(Max);
00075               P.add(px);
00076               
00077               
00078               Prompt=new MyTextField(p.getPrompt());
00079               P.add(new MyLabel(Zirkel.name("edit.expression.prompt")));
00080               P.add(Prompt); 
00081               Expression=new TextFieldAction(this,"OK",p.getExpression(),30); 
00082               P.add(new MyLabel(Zirkel.name("edit.expression"))); 
00083               P.add(Expression);
00084               
00085        }
00086        
00087        public void doAction (String o)
00088        {      if (o.equals("OK"))
00089               {      if (Fixed!=null && X.isChanged() || Y.isChanged())
00090                             Fixed.setState(true);
00091               }
00092               super.doAction(o);
00093        }
00094        
00095        public void setAction ()
00096        {      ExpressionObject p=(ExpressionObject)O;   
00097               if (Slider.getState())
00098               {      p.setSlider(Min.getText(),Max.getText());
00099                      if (Expression.getText().equals(""))
00100                             Expression.setText(Min.getText());
00101               }
00102               else
00103               {      p.setSlider(false);
00104               }
00105               try
00106               {      double x=new Double(X.getText()).doubleValue();
00107                      double y=new Double(Y.getText()).doubleValue();
00108                      p.move(x,y);
00109               }
00110               catch (Exception e) {}
00111               try
00112               {      p.setExpression(Expression.getText(),ZC.getConstruction());
00113               }
00114               catch (Exception e) { }
00115               if (Fixed.getState()==true) p.setFixed(X.getText(),Y.getText());
00116               else
00117               {      try
00118                      {      double x=new Expression(X.getText(),
00119                                    p.getConstruction(),p).getValue();
00120                             double y=new Expression(Y.getText(),
00121                                    p.getConstruction(),p).getValue();
00122                             p.move(x,y);
00123                             p.setFixed(false);
00124                      }
00125                      catch (Exception e) {}
00126               }
00127               p.setPrompt(Prompt.getText());
00128        }
00129 }
00130 
00131 public class ExpressionObject extends ConstructionObject
00132        implements MoveableObject, SimulationObject
00133 {      protected double X,Y;
00134        private static Count N=new Count();
00135        Expression E;
00136        protected Expression EX,EY;
00137        protected boolean Fixed;
00138        String Prompt=Zirkel.name("expression.value");
00139        protected double CurrentValue=0;
00140        protected boolean CurrentValueValid=true;
00141        protected boolean Slider=false;
00142        protected Expression SMin,SMax;
00143        
00144        public ExpressionObject (Construction c, double x, double y)
00145        {      super(c);
00146               X=x; Y=y;
00147               setColor(ColorIndex);
00148               updateText();
00149        }
00150        
00151        public String getTag () { return "Expression"; }
00152        public int getN () { return N.next(); }
00153        
00154        public void updateText ()
00155        {      if (E!=null) 
00156                      setText(text3(Zirkel.name("text.expression"),
00157                             E.toString(),""+roundDisplay(X),""+roundDisplay(Y)));
00158               else 
00159                      setText(text3(Zirkel.name("text.expression"),
00160                             "",""+roundDisplay(X),""+roundDisplay(Y)));
00161        }
00162 
00163        public double C,R,W,H; // for the expression position
00164        public double SC,SR,SW,SH; // for the slider position in screen coord.
00165        public double SX,SY,SD; // for the slider scale in x,y-coordinates
00166 
00172        public void paint (MyGraphics g, ZirkelCanvas zc)
00173        {      DisplaysText=false;
00174               if (!Valid || mustHide(zc)) return;
00175               C=zc.col(X); R=zc.row(Y);
00176               setFont(g);
00177               FontMetrics fm=g.getFontMetrics();
00178               if (isStrongSelected() && g instanceof MyGraphics)
00179               {      ((MyGraphics13)g).drawMarkerRect(C-5,R-5,10,10);
00180               }
00181               g.setColor(this);
00182               String s="";
00183               if (showName()) // shows the tag with or without = ...
00184               {      s=Prompt;
00185                      if (showValue()) // =, if value shows and % is not surpressed
00186                      {      if (s.endsWith("_") && s.length()>1)
00187                                    s=s.substring(0,s.length()-1);
00188                             else
00189                                    s=s+" = ";
00190                      }
00191                      else s=Prompt;
00192               }
00193               if (showValue()) // show the value
00194               {      try
00195                      {      E.getValue();
00196                             double x=round(CurrentValue);
00197                             if (Slider) x=round(CurrentValue,100);
00198                             if (Math.abs(x-Math.round(x))<1e-10) s=s+(int)x;
00199                             else s=s+x;
00200                      }
00201                      catch (Exception e) { s=s+"???"; }
00202               }
00203               s=s+Unit; // add optional unit
00204               s=AngleObject.translateToUnicode(s); // translate \a etc.
00205               W=fm.stringWidth("---"); 
00206               if (s.equals(""))  // nothing to show 
00207               {      if (!Slider) s="-";
00208               }
00209               if (!s.equals(""))
00210               {      setFont(g);
00211                      R-=fm.getAscent();
00212                      H=g.drawStringExtended(s,C,R);
00213               }
00214               if (Slider) // we draw an additional slider
00215               {      int coffset=(int)(4*zc.pointSize());
00216                      R+=H;
00217                      g.drawLine(C,R+coffset/2,C+10*coffset,R+coffset/2);
00218                      double d=getSliderPosition();
00219                      int size=coffset/4;
00220                      double rslider=C+d*10*coffset;
00221                      if (getColorType()==THICK)
00222                             g.fillOval(rslider-size,R+coffset/2-size,2*size,2*size,true,false,this);
00223                      else
00224                             g.drawOval(rslider-size,R+coffset/2-size,2*size,2*size);
00225                      // remember position
00226                      SC=rslider-size;
00227                      SR=R+coffset/2-size;
00228                      SW=SH=2*size;
00229                      SX=zc.x((int)C);
00230                      SY=zc.y((int)R+coffset/2-size);
00231                      SD=zc.x((int)C+10*coffset)-SX;
00232                      R-=H;
00233               }
00234        }
00235        
00241        public double getSliderPosition ()
00242        {      try
00243               {      double min=SMin.getValue();
00244                      double max=SMax.getValue();
00245                      double x=CurrentValue;
00246                      if (min>=max)
00247                      {      Valid=false;
00248                             return 0;
00249                      }
00250                      if (x<min) x=min;
00251                      if (x>max) x=max;
00252                      return (x-min)/(max-min);
00253               }
00254               catch (Exception e)
00255               {      Valid=false;
00256                      return 0;
00257               }
00258        }
00259        
00265        public void setSliderPosition (double d)
00266        {      try
00267               {      double min=SMin.getValue();
00268                      double max=SMax.getValue();
00269                      if (min>=max)
00270                      {      Valid=false;
00271                             return;
00272                      }
00273                      double value=min+d*(max-min);
00274                      if (value<min) value=min;
00275                      if (value>max) value=max;
00276                      E.setValue(value); // kills expression and makes it a constant
00277               }
00278               catch (Exception e)
00279               {      Valid=false;
00280               }
00281        }
00282        
00283        public boolean nearto (int x, int y, ZirkelCanvas zc)
00284        {      DragSlider=false;
00285               if (Valid && !displays(zc)) return false;
00286               if (C<=x && x<=C+W && R<=y && y<=R+H) return true;
00287               if (SC<=x && SR<=y && SC+SW>=x && SR+SH>=y)
00288               {      DragSlider=true;
00289                      return true;
00290               }
00291               return false;
00292        }
00293        
00294        public double getX () { return X; }
00295        public double getY () { return Y; }
00296 
00297        public void move (double x, double y)
00298        {      X=x; Y=y;
00299        }
00300        
00301        public void snap (ZirkelCanvas zc)
00302        {      double d=zc.getGridSize()/2;
00303               X=Math.round(X/d)*d;
00304               Y=Math.round(Y/d)*d;
00305        }
00306 
00307        public void round ()
00308        {      move(round(X,ZirkelCanvas.LengthsFactor),
00309                      round(Y,ZirkelCanvas.LengthsFactor));
00310        }
00311 
00312        public void edit (ZirkelCanvas zc)
00313        {      ObjectEditDialog d=new ExpressionEditDialog(zc.getFrame(),zc,this);
00314               d.setVisible(true);
00315               zc.repaint();
00316               if (E!=null && !E.isValid())
00317               {      Frame F=zc.getFrame();
00318                      Warning w=new Warning(F,E.getErrorText(),
00319                             Zirkel.name("warning"),true);
00320                      w.center(F);
00321                      w.setVisible(true);
00322               }
00323               if ((EX!=null && !EX.isValid()))
00324               {      Frame F=zc.getFrame();
00325                      Warning w=new Warning(F,EX.getErrorText(),
00326                             Zirkel.name("warning"),true);
00327                      w.center(F);
00328                      w.setVisible(true);
00329               }
00330               else if ((EY!=null && !EY.isValid()))
00331               {      Frame F=zc.getFrame();
00332                      Warning w=new Warning(F,EY.getErrorText(),
00333                             Zirkel.name("warning"),true);
00334                      w.center(F);
00335                      w.setVisible(true);
00336               }
00337               validate();
00338               if (d.wantsMore())
00339               {      new EditConditionals(zc.getFrame(),this);
00340                      validate();
00341               }
00342        }
00343 
00344        public void printArgs (XmlWriter xml)
00345        {      if (Fixed && EX!=null && EX.isValid()) xml.printArg("x",EX.toString());
00346               else xml.printArg("x",""+X);
00347               if (Fixed && EY!=null && EY.isValid()) xml.printArg("y",EY.toString());
00348               else xml.printArg("y",""+Y);
00349               if (E!=null) xml.printArg("value",E.toString());
00350               else xml.printArg("value","");
00351               xml.printArg("prompt",Prompt);
00352               if (Fixed) xml.printArg("fixed","true");
00353               if (Slider)
00354               {      xml.printArg("slider","true");
00355                      xml.printArg("min",SMin.toString());
00356                      xml.printArg("max",SMax.toString());
00357               }
00358        }
00359        
00360        public boolean equals (ConstructionObject o)
00361        {      return false;
00362        }
00363        
00364        public void setExpression (String expr, Construction c)
00365               throws ConstructionException
00366        {      E=new Expression(expr,c,this);
00367               updateText();
00368        }
00369        
00370        public void setFixed (String expr)
00371        {      E=new Expression(expr,getConstruction(),this);
00372               updateText();
00373        }
00374        
00375        public String getExpression ()
00376        {      if (E!=null) return E.toString();
00377               else return "";
00378        }
00379        
00380        public Enumeration depending ()
00381        {      DL.reset();
00382               if (E!=null)
00383               {      Enumeration e=E.getDepList().elements();
00384                      while (e.hasMoreElements())
00385                      {      DL.add((ConstructionObject)e.nextElement());
00386                      }
00387               }
00388               if (Fixed)
00389               {      Enumeration e;
00390                      if (EX!=null)
00391                      {      e=EX.getDepList().elements();
00392                             while (e.hasMoreElements())
00393                             {      DL.add((ConstructionObject)e.nextElement());
00394                             }
00395                      }
00396                      if (EY!=null)
00397                      {      e=EY.getDepList().elements();
00398                             while (e.hasMoreElements())
00399                             {      DL.add((ConstructionObject)e.nextElement());
00400                             }
00401                      }
00402               }
00403               return DL.elements();
00404        }
00405        
00406        public double getValue ()
00407               throws ConstructionException
00408        {      if (!CurrentValueValid)
00409                      throw new InvalidException("");
00410               return CurrentValue;
00411        }
00412        
00413        public String getPrompt () { return Prompt; }
00414        public void setPrompt (String prompt) { Prompt=prompt; }
00415        
00416        public void translate ()
00417        {      E.translate();
00418               if (Fixed)
00419               {      try
00420                      {      setFixed(EX.toString(),EY.toString());
00421                             EX.translate(); EY.translate();
00422                      }
00423                      catch (Exception e) {}
00424               }
00425               updateText();
00426        }
00427 
00428        public void validate ()     
00429        {      try
00430               {      CurrentValue=E.getValue();
00431                      CurrentValueValid=true;
00432               }
00433               catch (Exception e)
00434               {      CurrentValueValid=false;
00435               }
00436               Valid=true;
00437               if (Fixed && EX!=null && EX.isValid())
00438               {      try
00439                      {      X=EX.getValue();
00440                      }
00441                      catch (Exception e) { Valid=false; return; }
00442               }
00443               if (Fixed && EY!=null && EY.isValid())
00444               {      try
00445                      {      Y=EY.getValue();
00446                      }
00447                      catch (Exception e) { Valid=false; return; }
00448               }
00449        }
00450        
00451        public void setFixed (boolean flag)
00452        {      Fixed=flag; 
00453               if (!Fixed) EX=EY=null;
00454               updateText();
00455        }
00456        
00457        public void setFixed (String x, String y)
00458        {      Fixed=true;
00459               EX=new Expression(x,getConstruction(),this);
00460               EY=new Expression(y,getConstruction(),this);
00461               updateText();
00462        }
00463        
00464        public ConstructionObject copy ()
00465        {      try
00466               {      ExpressionObject o=(ExpressionObject)clone();
00467                      setTranslation(o);
00468                      o.setExpression(E.toString(),getConstruction());
00469                      o.translateConditionals();
00470                      o.translate();
00471                      o.setName();
00472                      o.updateText();
00473                      o.setBreak(false);
00474                      o.setTarget(false);
00475                      return o;
00476               }
00477               catch (Exception e)
00478               {      return null; 
00479               }
00480        }
00481 
00482        public void setDefaults ()
00483        {      super.setDefaults();
00484               setShowValue(true);
00485        }      
00486        
00487        public boolean moveable ()
00488        {      if (Slider) return true;
00489               return EX==null && EY==null;
00490        }
00491        
00492        public void reset ()
00493        {      if (E!=null) E.reset();
00494        }
00495 
00496        public boolean fixed () { return Fixed; }
00497 
00498        public String getEX ()
00499        {      if (EX!=null) return EX.toString();
00500               else return ""+round(X);
00501        }
00502 
00503        public String getEY ()
00504        {      if (EY!=null) return EY.toString();
00505               else return ""+round(Y);
00506        }
00507 
00508        public void setCurrentValue (double x)
00509        {      CurrentValue=x; CurrentValueValid=true;
00510        }
00511        
00512        // For the simulate function:
00513        
00514        private double OldE;
00515        
00519        public void setSimulationValue (double x) 
00520        {      OldE=CurrentValue;
00521               CurrentValue=x;
00522        }
00523        
00527        public void resetSimulationValue () 
00528        {      CurrentValue=OldE;
00529        }
00530 
00537        public void setSlider (String smin, String smax)
00538        {      Slider=true;
00539               SMin=new Expression(smin,getConstruction(),this);
00540               SMax=new Expression(smax,getConstruction(),this);
00541        }
00542        
00547        public void setSlider (boolean flag)
00548        {      Slider=flag;
00549        }
00550 
00551        double oldx,oldy,startx,starty;
00552        boolean DragSlider;
00553        
00554        public void startDrag (double x, double y) 
00555        {      oldx=X; oldy=Y;
00556               startx=x; starty=y;
00557        }
00558 
00559        public void dragTo (double x, double y) 
00560        {      if (DragSlider)
00561               {      setSliderPosition((x-SX)/SD);
00562               }
00563               else
00564                      move(oldx+(x-startx),oldy+(y-starty));
00565        }
00566 
00567        public boolean isSlider ()
00568        {      return Slider;
00569        }
00570        
00571        public String getMin ()
00572        {      if (Slider) return SMin.toString();
00573               else return ("-5"); 
00574        }
00575 
00576        public String getMax ()
00577        {      if (Slider) return SMax.toString();
00578               else return ("5"); 
00579        }
00580 
00581        public String getDisplayValue ()
00582        {      String s="";
00583               try
00584               {      E.getValue();
00585                      double x=round(CurrentValue);
00586                      if (Slider) x=round(CurrentValue,100);
00587                      if (Math.abs(x-Math.round(x))<1e-10) s=s+(int)x;
00588                      else s=s+x;
00589               }
00590               catch (Exception e) { s=s+"???"; }
00591               s=s+Unit; // add optional unit
00592               return s;
00593        }
00594 
00595        public String getEquation ()
00596        {      if (E==null) return "???";
00597               else return E.toString();
00598        }
00599 }