package gve.calc.formula;

import java.awt.*;

Cursor positions: if ^ is visible, cursor pos >=0; if ^ is invisible with cursorpos <0, cursor is invisible, if ^ is invisible with cursorpos >=0, cursor is at the right of exponent
public class OperatorPowView extends InfixBinaryOpView { public OperatorPowView(OperatorPow model,FormulaView view) { super(model,view); setLayout(new OperatorPowLayout()); deactivate(); } public void activate() {} public void deactivate() { getComponent(1).setVisible(false); getOperatorView().setCursorPos(Somewhere_NOWHERE); invalidate(); } public void setCursorPos(int pos) { FormulaView view = FormulaView.get(this); if (pos == Somewhere_NOWHERE) { deactivate(); } else if (pos==0 || pos==1) { CursorPosLabel label = (CursorPosLabel)getComponent(1); label.setVisible(true); invalidate(); label.setCursorPos(pos); } else if (pos == Somewhere_RIGHT) { getComponent(1).setVisible(false); getOperatorView().setCursorPos(0); invalidate(); } else setCursorPos(0); } public int getCursorPos() { CursorPosLabel center = (CursorPosLabel)getComponent(1); if (center.isVisible()) return center.getCursorPos(); // 0 or 1 if (center.getCursorPos() < 0) return Somewhere_NOWHERE; return Somewhere_RIGHT; } public int getBaseline() { if (getComponent(1).isVisible()) return super.getBaseline(); Component left = getComponent(0); Component right = getComponent(2); int base; if (left instanceof HasBaseline) base = ((HasBaseline)left).getBaseline(); else base = left.getSize().height / 2; return base + right.getSize().height; } public void paint(Graphics g) { super.paint(g); CursorPosLabel center = (CursorPosLabel)getComponent(1); if (!center.isVisible() && center.getCursorPos()>=0) { FontMetrics fm = g.getFontMetrics(); int spatwidth = fm.charWidth(' '); Dimension siz = getSize(); g.setColor(Color.green); g.fillRect(siz.width-spatwidth,getBaseline()-fm.getAscent(),spatwidth,fm.getHeight()); } } public boolean keydn(int key) { int cp = getCursorPos(); FormulaView view = FormulaView.get(this); OperatorPow model = (OperatorPow)getModel(); if (key == Key_LEFT) { if (cp == Somewhere_RIGHT) { view.setCursorPart(model.right,Somewhere_RIGHT); return true; } } else if (key == Key_RIGHT) { if (cp == Somewhere_RIGHT) return false; // cannot move more to the left if (cp == Somewhere_NOWHERE && Part.isDescendantOr(view.getCursorPart(),model.right)) { // Cursor is at the right of the exponent. view.setCursorComp(this,Somewhere_RIGHT); return true; } } if (cp == Somewhere_RIGHT) { Formula f = view.getFormula(); switch (key) { case '(': // PENDING break; default: if (key == ' ') { Identifier dummy = new Identifier(""); f.replace(model,dummy); OperatorSpace spat; f.replace(dummy,spat = new OperatorSpace(model,new Identifier(""))); view.setCursorPart(spat,0); // spat.rotate(f); spat.recognizeOp(f); return true; } else if (key > 32) { Identifier dummy = new Identifier(""); f.replace(model,dummy); OperatorSpace spat; Identifier ident = new Identifier((char)key); f.replace(dummy,spat = new OperatorSpace(model,ident)); view.setCursorPart(ident,1); // spat.rotate(f); spat.recognizeOp(f); return true; } } return false; } return super.keydn(key); } } class OperatorPowLayout extends HorizontalLayoutMgr { public void OperatorPowLayout() {} public void addLayoutComponent(String name,Component comp) {} public void removeLayoutComponent(Component comp) {} public Dimension preferredLayoutSize(Container target) { CursorPosLabel center = (CursorPosLabel)target.getComponent(1); if (center.isVisible()) return super.preferredLayoutSize(target); Component left = target.getComponent(0); Component right = target.getComponent(2); Dimension l = left.getPreferredSize(); Dimension r = right.getPreferredSize(); int extra = 0; if (center.getCursorPos() >= 0) extra = target.getFontMetrics(target.getFont()).charWidth(' '); return new Dimension(l.width + r.width + extra,l.height + r.height); } public Dimension minimumLayoutSize(Container target) { return preferredLayoutSize(target); } public void layoutContainer(Container target) { CursorPosLabel center = (CursorPosLabel)target.getComponent(1); if (center.isVisible()) { super.layoutContainer(target); return; } Component left = target.getComponent(0); Component right = target.getComponent(2); left.validate(); right.validate(); Dimension l = left.getPreferredSize(); Dimension r = right.getPreferredSize(); left.setBounds(0,r.height,l.width,l.height); right.setBounds(l.width,0,r.width,r.height); } }