package gve.calc.formula;

import awt.*;
import java.awt.*; 
import awt.Button;
import java.awt.event.*;

Binary boolean operators
public class OperatorBoolean extends InfixBinaryOp { private byte kind; public static final byte AND = 0; public static final byte XOR = 1; public static final byte OR = 2; public static final byte IMPLIES = 3; public static final byte EQUIV = 4; private static String [] names = { "&","xor","or","=>","<=>" }; private static int [] pri = { 1200,1100,1000,900,900 }; public OperatorBoolean(String name,Part l,Part r) { super(l,r); for (int i = names.length-1; i>=0; i--) { if (names[i].equals(name)) { kind = (byte)i; break; } } } public OperatorBoolean(byte kind,Part l,Part r) { super(l,r); this.kind = kind; } public String getName() { return names[kind]; } public int getPri() { return pri[kind]; } public int getLeftPri() { return pri[kind] - 10; } public int getRightPri() { return pri[kind] + 10; } public byte getKind() { return kind; } public Part evaluate(Evaluator ev) { // PENDING: shortcut L->R evaluatie bij sommige operatoren Object evalL = left.evaluate(ev); Object evalR = right.evaluate(ev); if (evalL instanceof Boolean && evalR instanceof Boolean) { boolean l = ((Boolean)evalL).getBooleanValue(); boolean r = ((Boolean)evalR).getBooleanValue(); switch(kind) { case AND: return new Boolean(l & r); case XOR: return new Boolean(l != r); case OR: return new Boolean(l | r); case IMPLIES: return new Boolean(!l | r); case EQUIV: return new Boolean(l == r); } } return new OperatorBoolean(kind,(Part)evalL,(Part)evalR); } public boolean same(Object o) { o = Brackets.unbracket(o); if (!(o instanceof OperatorBoolean)) return false; OperatorBoolean b = (OperatorBoolean)o; return b.left.same(left) && b.right.same(right) && b.kind==kind; } public void write(java.io.Writer w) throws java.io.IOException { super.write(w); w.write(kind+"\n"); } public static Part read(java.io.BufferedReader r) throws java.io.IOException, ClassNotFoundException,NoSuchMethodException, java.lang.reflect.InvocationTargetException,IllegalAccessException{ Part left = Part.read(r); Part right = Part.read(r); String line = r.readLine(); byte kind = (byte)Integer.parseInt(line); return new OperatorBoolean(kind,left,right); } public Component createView(FormulaView view) { return new OperatorBooleanView(this,view,new OperatorBooleanSymbolView(kind,getName())); } public void saveOperatorLatex(java.io.BufferedWriter w) throws java.io.IOException { switch (kind) { case AND: w.write("\\&"); break; case XOR: w.write("\\oplus"); break; case OR: w.write("\\vee"); break; case IMPLIES: w.write("\\Rightarrow"); break; case EQUIV: w.write("\\Leftrightarrow"); break; } } } class OperatorBooleanSymbolView extends TextSymbolView { private byte kind; public OperatorBooleanSymbolView(byte kind,String str) { super(str); this.kind = kind; } public Dimension getSymbolSize() { FontMetrics metrics = getFontMetrics(getFont()); int w = 0; switch (kind) { case OperatorBoolean.AND: w = metrics.charWidth('&'); break; case OperatorBoolean.XOR: w = metrics.charWidth('O'); break; case OperatorBoolean.OR: w = metrics.charWidth('v'); break; case OperatorBoolean.IMPLIES: case OperatorBoolean.EQUIV: w = metrics.stringWidth("=="); break; } return new Dimension(w,metrics.getHeight()); } public void paintSymbol(Graphics g) { FontMetrics metrics = getFontMetrics(getFont()); int spatwidth = metrics.charWidth(' '); int ascent = metrics.getAscent(); switch (kind) { case OperatorBoolean.AND: g.drawString("&",0,ascent); return; case OperatorBoolean.XOR: paintXor(g,0,0,metrics.charWidth('O'),ascent); break; case OperatorBoolean.OR: paintOr(g,0,ascent/3,metrics.charWidth('v'),ascent*2/3); break; case OperatorBoolean.IMPLIES: paintImplies(g,1,0,metrics.stringWidth("==")-2,ascent); break; case OperatorBoolean.EQUIV: paintEquiv(g,1,0,metrics.stringWidth("==")-2,ascent); break; } } private void paintXor(Graphics g,int x,int y,int w,int h) { g.drawOval(x,y,w,h); w--; h--; g.drawLine(x+w/2,y,x+w/2,y+h); g.drawLine(x,y+h/2,x+w,y+h/2); } private void paintOr(Graphics g,int x,int y,int w,int h) { w--; h--; g.drawLine(x,y,x+w/2,y+h); g.drawLine(x+w/2,y+h,x+w,y); } private void paintImplies(Graphics g,int x,int y,int w,int h) { w--; h--; // right arrow g.drawLine(x+w*3/4,y,x+w,y+h/2); g.drawLine(x+w,y+h/2,x+w*3/4,y+h); // two horizontal lines g.drawLine(x,y+(h+2)/4,x+w*7/8,y+(h+2)/4); g.drawLine(x,y+h*3/4,x+w*7/8,y+h*3/4); } private void paintEquiv(Graphics g,int x,int y,int w,int h) { w--; h--; // right arrow g.drawLine(x+w*3/4,y,x+w,y+h/2); g.drawLine(x+w,y+h/2,x+w*3/4,y+h); // two horizontal lines g.drawLine(x+w/8,y+(h+2)/4,x+w*7/8,y+(h+2)/4); g.drawLine(x+w/8,y+h*3/4,x+w*7/8,y+h*3/4); // left arrow g.drawLine(x+w/4,y,x,y+h/2); g.drawLine(x,y+h/2,x+w/4,y+h); } }