Refining the new internal structure. Now it works.

This commit is contained in:
XDrake99 2017-03-26 22:44:09 +02:00
parent 86438bf618
commit b86228a8d3
27 changed files with 797 additions and 423 deletions

Binary file not shown.

View File

@ -10,6 +10,7 @@ import org.warp.picalculator.gui.expression.BlockContainer;
import org.warp.picalculator.gui.expression.BlockDivision; import org.warp.picalculator.gui.expression.BlockDivision;
import org.warp.picalculator.gui.expression.Caret; import org.warp.picalculator.gui.expression.Caret;
import org.warp.picalculator.gui.expression.CaretState; import org.warp.picalculator.gui.expression.CaretState;
import org.warp.picalculator.gui.expression.containers.NormalInputContainer;
import org.warp.picalculator.gui.graphicengine.BinaryFont; import org.warp.picalculator.gui.graphicengine.BinaryFont;
import org.warp.picalculator.gui.graphicengine.Skin; import org.warp.picalculator.gui.graphicengine.Skin;
import org.warp.picalculator.gui.graphicengine.cpu.CPUEngine; import org.warp.picalculator.gui.graphicengine.cpu.CPUEngine;
@ -20,7 +21,7 @@ import org.warp.picalculator.gui.screens.MarioScreen;
import org.warp.picalculator.math.MathContext; import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.MathematicalSymbols; import org.warp.picalculator.math.MathematicalSymbols;
import org.warp.picalculator.math.functions.Expression; import org.warp.picalculator.math.functions.Expression;
import org.warp.picalculator.math.parser.InputParser; import org.warp.picalculator.math.parser.MathParser;
import java.lang.management.ManagementFactory; import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean; import java.lang.management.OperatingSystemMXBean;
@ -48,7 +49,7 @@ public class TestGPU {
private final Renderer r; private final Renderer r;
private final GraphicEngine d; private final GraphicEngine d;
private final BlockContainer c; private final NormalInputContainer c;
public Scene(GraphicEngine d) throws IOException, Error { public Scene(GraphicEngine d) throws IOException, Error {
this.d = d; this.d = d;
@ -62,22 +63,21 @@ public class TestGPU {
//New expression framework test //New expression framework test
c = new BlockContainer(false, 0, 200); c = new NormalInputContainer(false, 0, 200);
BlockDivision bd = new BlockDivision(); c.typeChar(MathematicalSymbols.DIVISION);
c.addBlock(bd); c.typeChar('5');
bd.getUpperContainer().addBlock(new BlockChar('5')); c.typeChar(MathematicalSymbols.MULTIPLICATION);
bd.getUpperContainer().addBlock(new BlockChar(MathematicalSymbols.MULTIPLICATION)); c.typeChar('2');
bd.getUpperContainer().addBlock(new BlockChar('2')); c.moveRight();
bd.getLowerContainer().addBlock(new BlockChar('2')); c.typeChar('2');
bd.recomputeDimensions(); c.moveRight();
c.addBlock(new BlockChar(MathematicalSymbols.MULTIPLICATION)); c.typeChar(MathematicalSymbols.MULTIPLICATION);
c.addBlock(new BlockChar('2')); c.typeChar('2');
c.addBlock(new BlockChar('2')); c.typeChar('2');
c.addBlock(new BlockChar('b'));
c.recomputeDimensions(); c.recomputeDimensions();
Expression expr = InputParser.parseInput(new MathContext(), c); Expression expr = MathParser.parseInput(new MathContext(), c.root);
System.out.println(expr.toString()); System.out.println("Parsed input:"+expr.toString());
d.start(this); d.start(this);
@ -119,7 +119,7 @@ public class TestGPU {
r.glFillRect(162, 2.5f, 160, 160, 0, 0, 16, 16); r.glFillRect(162, 2.5f, 160, 160, 0, 0, 16, 16);
//New expression framework test //New expression framework test
c.draw(d, r, 10, 220, new Caret(CaretState.VISIBLE_ON, 10)); c.draw(d, r, 10, 220);
} }
} }

View File

@ -25,16 +25,6 @@ import org.warp.picalculator.device.graphicengine.RAWFont;
import org.warp.picalculator.device.graphicengine.Screen; import org.warp.picalculator.device.graphicengine.Screen;
import com.pi4j.wiringpi.Gpio; import com.pi4j.wiringpi.Gpio;
/**
* STB Truetype oversampling demo.
*
* <p>
* This is a Java port of <a href=
* "https://github.com/nothings/stb/blob/master/tests/oversample/main.c">https:/
* /github
* .com/nothings/stb/blob/master/tests/oversample/main.c</a>.
* </p>
*/
public final class PIDisplay { public final class PIDisplay {
public static PIDisplay INSTANCE; public static PIDisplay INSTANCE;
private static float brightness; private static float brightness;

View File

@ -20,6 +20,10 @@ public abstract class Block implements GraphicalElement {
*/ */
public abstract void draw(GraphicEngine ge, Renderer r, int x, int y, Caret caret); public abstract void draw(GraphicEngine ge, Renderer r, int x, int y, Caret caret);
public abstract boolean putBlock(Caret caret, Block newBlock);
public abstract boolean delBlock(Caret caret);
@Override @Override
public abstract void recomputeDimensions(); public abstract void recomputeDimensions();
@ -44,4 +48,5 @@ public abstract class Block implements GraphicalElement {
public abstract void setSmall(boolean small); public abstract void setSmall(boolean small);
public abstract int getClassID();
} }

View File

@ -7,6 +7,8 @@ import org.warp.picalculator.math.parser.features.interfaces.Feature;
public class BlockChar extends Block { public class BlockChar extends Block {
public static final int CLASS_ID = 0x00000001;
private final char ch; private final char ch;
public BlockChar(char ch) { public BlockChar(char ch) {
@ -21,6 +23,16 @@ public class BlockChar extends Block {
r.glDrawCharLeft(x, y, ch); r.glDrawCharLeft(x, y, ch);
} }
@Override
public boolean putBlock(Caret caret, Block newBlock) {
return false;
}
@Override
public boolean delBlock(Caret caret) {
return false;
}
@Override @Override
public void recomputeDimensions() { public void recomputeDimensions() {
width = BlockContainer.getDefaultCharWidth(small); width = BlockContainer.getDefaultCharWidth(small);
@ -38,4 +50,9 @@ public class BlockChar extends Block {
return ch; return ch;
} }
@Override
public int getClassID() {
return CLASS_ID;
}
} }

View File

@ -11,6 +11,8 @@ import org.warp.picalculator.gui.graphicengine.gpu.GPUFont;
public class BlockContainer implements GraphicalElement { public class BlockContainer implements GraphicalElement {
private static boolean initialized = false;
private final int minWidth; private final int minWidth;
private final int minHeight; private final int minHeight;
private final ObjectArrayList<Block> content; private final ObjectArrayList<Block> content;
@ -18,32 +20,54 @@ public class BlockContainer implements GraphicalElement {
private int width; private int width;
private int height; private int height;
private int line; private int line;
public final boolean withBorder;
public BlockContainer() { public BlockContainer() {
this(false, BlockContainer.getDefaultCharWidth(true), BlockContainer.getDefaultCharHeight(true)); this(false, BlockContainer.getDefaultCharWidth(false), BlockContainer.getDefaultCharHeight(false), true);
} }
public BlockContainer(boolean small) { public BlockContainer(boolean small) {
this(small, BlockContainer.getDefaultCharWidth(true), BlockContainer.getDefaultCharHeight(true)); this(small, BlockContainer.getDefaultCharWidth(small), BlockContainer.getDefaultCharHeight(small), true);
} }
public BlockContainer(boolean small, int minWidth, int minHeight) { public BlockContainer(boolean small, boolean withBorder) {
this(small, minWidth, minHeight, new ObjectArrayList<>()); this(small, BlockContainer.getDefaultCharWidth(small), BlockContainer.getDefaultCharHeight(small), withBorder);
} }
public BlockContainer(boolean small, int minWidth, int minHeight, ObjectArrayList<Block> content) { public BlockContainer(boolean small, int minWidth, int minHeight, boolean withBorder) {
this(small, minWidth, minHeight, new ObjectArrayList<>(), withBorder);
}
public BlockContainer(boolean small, int minWidth, int minHeight, ObjectArrayList<Block> content, boolean withBorder) {
this.small = small; this.small = small;
this.minWidth = minWidth; this.minWidth = minWidth;
this.minHeight = minHeight; this.minHeight = minHeight;
this.withBorder = withBorder;
for (Block b: content) { for (Block b: content) {
if (b.isSmall() != small) {
b.setSmall(small); b.setSmall(small);
} }
}
this.content = content; this.content = content;
recomputeDimensions(); recomputeDimensions();
} }
public void addBlock(Block b) { public void addBlock(int position, Block b) {
if (b.isSmall() != small) {
b.setSmall(small); b.setSmall(small);
}
if (position >= content.size()) {
content.add(b);
} else {
content.add(position, b);
}
recomputeDimensions();
}
public void appendBlock(Block b) {
if (b.isSmall() != small) {
b.setSmall(small);
}
content.add(b); content.add(b);
recomputeDimensions(); recomputeDimensions();
} }
@ -76,25 +100,81 @@ public class BlockContainer implements GraphicalElement {
* @param caret Position of the caret. * @param caret Position of the caret.
*/ */
public void draw(GraphicEngine ge, Renderer r, int x, int y, Caret caret) { public void draw(GraphicEngine ge, Renderer r, int x, int y, Caret caret) {
int paddingX = 0; int paddingX = 1;
if (caret.getRemaining() == 0) { if (caret.getRemaining() == 0) {
if (content.size() > 0) { if (content.size() > 0) {
BlockContainer.drawCaret(ge, r, caret, x, y, content.get(0).getHeight()); BlockContainer.drawCaret(ge, r, caret, x, y+line-content.get(0).line, content.get(0).height);
} else { } else {
BlockContainer.drawCaret(ge, r, caret, x, y, height); BlockContainer.drawCaret(ge, r, caret, x, y, height);
} }
} }
if (withBorder && content.size() == 0) {
r.glDrawLine(x+paddingX, y, x+paddingX+width-1, y);
r.glDrawLine(x+paddingX, y, x+paddingX, y+height-1);
r.glDrawLine(x+paddingX+width-1, y, x+paddingX+width-1, y+height-1);
r.glDrawLine(x+paddingX, y+height-1, x+paddingX+width-1, y+height-1);
} else {
for (Block b : content) { for (Block b : content) {
caret.skip(1); caret.skip(1);
b.draw(ge, r, x+paddingX, y+line-b.getLine(), caret); b.draw(ge, r, x+paddingX, y+line-b.line, caret);
paddingX += b.getWidth(); paddingX += b.getWidth();
if (caret.getRemaining() == 0) BlockContainer.drawCaret(ge, r, caret, x + paddingX, y+line-b.getLine(), b.height); if (caret.getRemaining() == 0) BlockContainer.drawCaret(ge, r, caret, x + paddingX, y+line-b.line, b.height);
paddingX += 1;
}
} }
caret.skip(1); caret.skip(1);
} }
public boolean putBlock(Caret caret, Block newBlock) {
boolean added = false;
if (caret.getRemaining() == 0) {
this.addBlock(0, newBlock);
added = true;
}
int pos = 0;
for (Block b : content) {
caret.skip(1);
pos++;
added = added|b.putBlock(caret, newBlock);
if (caret.getRemaining() == 0) {
this.addBlock(pos, newBlock);
added = true;
}
}
caret.skip(1);
if (added) {
recomputeDimensions();
}
return added;
}
public boolean delBlock(Caret caret) {
boolean removed = false;
int pos = 0;
for (Block b : content) {
caret.skip(1);
pos++;
int deltaCaret = caret.getRemaining();
removed = removed|b.delBlock(caret);
if (caret.getRemaining() == 0 || (removed == false && deltaCaret >= 0 && caret.getRemaining() < 0)) {
this.removeAt(pos-1);
caret.setPosition(caret.getPosition()-deltaCaret);
removed = true;
}
}
caret.skip(1);
if (removed) {
recomputeDimensions();
}
return removed;
}
@Override @Override
public void recomputeDimensions() { public void recomputeDimensions() {
int l = 0; //Line int l = 0; //Line
@ -103,7 +183,7 @@ public class BlockContainer implements GraphicalElement {
int h = 0; //Height int h = 0; //Height
for (Block b : content) { for (Block b : content) {
w += b.getWidth(); w += b.getWidth() + 1;
final int bl = b.getLine(); final int bl = b.getLine();
final int bh = b.getHeight(); final int bh = b.getHeight();
final int bh2 = bh - bl; final int bh2 = bh - bl;
@ -115,6 +195,10 @@ public class BlockContainer implements GraphicalElement {
} }
} }
if (content.size() > 0) {
w -= 1;
}
h = h2 + l; h = h2 + l;
line = l; line = l;
@ -127,6 +211,7 @@ public class BlockContainer implements GraphicalElement {
height = h; height = h;
} else { } else {
height = minHeight; height = minHeight;
line = height/2;
} }
} }
@ -156,29 +241,35 @@ public class BlockContainer implements GraphicalElement {
defFontSizes[1] = big.getCharacterHeight(); defFontSizes[1] = big.getCharacterHeight();
defFontSizes[2] = small.getCharacterWidth(); defFontSizes[2] = small.getCharacterWidth();
defFontSizes[3] = small.getCharacterHeight(); defFontSizes[3] = small.getCharacterHeight();
initialized = true;
} }
public static BinaryFont getDefaultFont(boolean small) { public static BinaryFont getDefaultFont(boolean small) {
checkInitialized();
return defFonts[small?1:0]; return defFonts[small?1:0];
} }
public static int getDefaultColor() { public static int getDefaultColor() {
return defColor; return defColor;
} }
public static int getDefaultCharWidth(boolean b) { public static int getDefaultCharWidth(boolean b) {
checkInitialized();
return defFontSizes[b?2:0]; return defFontSizes[b?2:0];
} }
public static int getDefaultCharHeight(boolean b) { public static int getDefaultCharHeight(boolean b) {
checkInitialized();
return defFontSizes[b?3:1]; return defFontSizes[b?3:1];
} }
public static void drawCaret(GraphicEngine ge, Renderer r, Caret caret, int x, int y, int height) { public static void drawCaret(GraphicEngine ge, Renderer r, Caret caret, int x, int y, int height) {
if (caret.getState() == CaretState.VISIBLE_ON) {
r.glColor(getDefaultColor()); r.glColor(getDefaultColor());
r.glDrawLine(x, y, x, y-1+height); r.glDrawLine(x, y, x, y-1+height);
r.glDrawLine(x+1, y, x+1, y-1+height); r.glDrawLine(x+1, y, x+1, y-1+height);
r.glDrawLine(x+2, y, x+2, y-1+height);
}
} }
public void setSmall(boolean small) { public void setSmall(boolean small) {
@ -190,4 +281,8 @@ public class BlockContainer implements GraphicalElement {
return content.clone(); return content.clone();
} }
private static void checkInitialized() {
if (!initialized) throw new ExceptionInInitializerError("Please initialize BlockContainer by running the method BlockContainer.initialize(...) first!");
}
} }

View File

@ -9,6 +9,8 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList;
public class BlockDivision extends Block { public class BlockDivision extends Block {
public static final int CLASS_ID = 0x00000002;
private final BlockContainer containerUp; private final BlockContainer containerUp;
private final BlockContainer containerDown; private final BlockContainer containerDown;
@ -27,17 +29,39 @@ public class BlockDivision extends Block {
BlockContainer.getDefaultFont(small).use(ge); BlockContainer.getDefaultFont(small).use(ge);
r.glColor(BlockContainer.getDefaultColor()); r.glColor(BlockContainer.getDefaultColor());
containerUp.draw(ge, r, x+1+paddingLeftUpper, y, caret); containerUp.draw(ge, r, x+1+paddingLeftUpper, y, caret);
r.glDrawLine(x, y+h1+1, x+width, y+h1+1); r.glDrawLine(x, y+h1+1, x+width-1, y+h1+1);
containerDown.draw(ge, r, x+1+paddingLeftLower, y + h1+3, caret); containerDown.draw(ge, r, x+1+paddingLeftLower, y + h1+3, caret);
} }
@Override
public boolean putBlock(Caret caret, Block newBlock) {
boolean added = false;
added = added|containerUp.putBlock(caret, newBlock);
added = added|containerDown.putBlock(caret, newBlock);
if (added) {
recomputeDimensions();
}
return added;
}
@Override
public boolean delBlock(Caret caret) {
boolean removed = false;
removed = removed|containerUp.delBlock(caret);
removed = removed|containerDown.delBlock(caret);
if (removed) {
recomputeDimensions();
}
return removed;
}
@Override @Override
public void recomputeDimensions() { public void recomputeDimensions() {
final int w1 = containerUp.getWidth(); final int w1 = containerUp.getWidth();
final int w2 = containerDown.getWidth(); final int w2 = containerDown.getWidth();
final int h1 = containerUp.getHeight(); final int h1 = containerUp.getHeight();
final int h2 = containerDown.getHeight(); final int h2 = containerDown.getHeight();
width = (w1>w2?w1:w2) + 2; width = (w1>w2?w1:w2) + 4;
height = h1+3+h2; height = h1+3+h2;
line = h1+1; line = h1+1;
this.h1 = h1; this.h1 = h1;
@ -49,6 +73,9 @@ public class BlockDivision extends Block {
paddingLeftUpper = (w2 - w1) / 2; paddingLeftUpper = (w2 - w1) / 2;
paddingLeftLower = 0; paddingLeftLower = 0;
} }
} else {
paddingLeftUpper = 0;
paddingLeftLower = 0;
} }
} }
@ -67,4 +94,9 @@ public class BlockDivision extends Block {
public BlockContainer getLowerContainer() { public BlockContainer getLowerContainer() {
return containerDown; return containerDown;
} }
@Override
public int getClassID() {
return CLASS_ID;
}
} }

View File

@ -0,0 +1,87 @@
package org.warp.picalculator.gui.expression;
import org.warp.picalculator.Main;
import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.Renderer;
import org.warp.picalculator.math.parser.features.interfaces.Feature;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
public class BlockSquareRoot extends Block {
public static final int CLASS_ID = 0x00000002;
private final BlockContainer containerNumber;
private int h1;
public BlockSquareRoot() {
this.containerNumber = new BlockContainer(false);
recomputeDimensions();
}
@Override
public void draw(GraphicEngine ge, Renderer r, int x, int y, Caret caret) {
BlockContainer.getDefaultFont(small).use(ge);
r.glColor(BlockContainer.getDefaultColor());
r.glDrawLine(x, y+height-10+1, x, y+height-10+2); // /
r.glDrawLine(x+1, y+height-10, x+1, y+height-10+1); // /
r.glDrawLine(x+2, y+height-10+2, x+2, y+height-10+6); // \
r.glDrawLine(x+3, y+height-10+7, x+3, y+height-10+9); // \
r.glDrawLine(x+5, y+height-h1-1-2, x+width-1, y+height-h1-1-2); // ----
r.glDrawLine(x+5, y+height-h1-1-2, x+5, y+height-(h1-2)/3f*2f-1); // |
r.glDrawLine(x+4, y+height-(h1-2)/3f*2f-1, x+4, y+height-(h1-2)/3f-1); // |
r.glDrawLine(x+3, y+height-(h1-2)/3f-1, x+3, y+height-1); // |
containerNumber.draw(ge, r, x+7, y+3, caret);
}
@Override
public boolean putBlock(Caret caret, Block newBlock) {
boolean added = false;
added = added|containerNumber.putBlock(caret, newBlock);
if (added) {
recomputeDimensions();
}
return added;
}
@Override
public boolean delBlock(Caret caret) {
boolean removed = false;
removed = removed|containerNumber.delBlock(caret);
if (removed) {
recomputeDimensions();
}
return removed;
}
@Override
public void recomputeDimensions() {
final int w1 = containerNumber.getWidth();
h1 = containerNumber.getHeight();
final int l1 = containerNumber.getLine();
width = 8+w1+2;
height = 3+h1;
line = 3+l1;
if (height < 9) {
height = 9;
line+=(9-(3+h1));
}
}
@Override
public void setSmall(boolean small) {
this.small = small;
this.containerNumber.setSmall(small);
recomputeDimensions();
}
public BlockContainer getNumberContainer() {
return containerNumber;
}
@Override
public int getClassID() {
return CLASS_ID;
}
}

View File

@ -27,4 +27,26 @@ public class Caret {
public CaretState getState() { public CaretState getState() {
return state; return state;
} }
public void flipState() {
if (this.state == CaretState.VISIBLE_ON) {
this.state = CaretState.VISIBLE_OFF;
} else if (this.state == CaretState.VISIBLE_OFF) {
this.state = CaretState.VISIBLE_ON;
}
}
public void turnOn() {
if (this.state == CaretState.VISIBLE_OFF) {
this.state = CaretState.VISIBLE_ON;
}
}
public void setPosition(int i) {
this.pos = i;
}
public void resetRemaining() {
remaining = pos;
}
} }

View File

@ -0,0 +1,12 @@
package org.warp.picalculator.gui.expression.containers;
import org.warp.picalculator.gui.expression.Block;
import org.warp.picalculator.gui.expression.BlockChar;
import org.warp.picalculator.math.MathematicalSymbols;
public class InlineInputContainer extends InputContainer {
@Override
public Block parseChar(char c) {
return new BlockChar(MathematicalSymbols.DIVISION);
}
}

View File

@ -0,0 +1,136 @@
package org.warp.picalculator.gui.expression.containers;
import org.warp.picalculator.gui.expression.Block;
import org.warp.picalculator.gui.expression.BlockContainer;
import org.warp.picalculator.gui.expression.Caret;
import org.warp.picalculator.gui.expression.CaretState;
import org.warp.picalculator.gui.expression.GraphicalElement;
import org.warp.picalculator.gui.expression.layouts.InputLayout;
import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.Renderer;
public abstract class InputContainer implements GraphicalElement, InputLayout {
public final BlockContainer root;
private Caret caret;
private static final float CARET_DURATION = 0.5f;
private float caretTime;
public InputContainer() {
caret = new Caret(CaretState.VISIBLE_ON, 0);
root = new BlockContainer(false, false);
}
public InputContainer(boolean small) {
caret = new Caret(CaretState.VISIBLE_ON, 0);
root = new BlockContainer(small, false);
}
public InputContainer(boolean small, int minWidth, int minHeight) {
caret = new Caret(CaretState.VISIBLE_ON, 0);
root = new BlockContainer(small, false);
}
public void typeChar(char c) {
Block b = parseChar(c);
if (b != null) {
caret.resetRemaining();
if (root.putBlock(caret, b)) {
caret.setPosition(caret.getPosition()+1);
root.recomputeDimensions();
}
}
caretTime = 0;
caret.turnOn();
}
public void typeChar(String c) {
typeChar(c.charAt(0));
}
public void del() {
caret.resetRemaining();
if (root.delBlock(caret)) {
root.recomputeDimensions();
}
if (caret.getPosition() > 0) {
caret.setPosition(caret.getPosition()-1);
}
caret.turnOn();
caretTime = 0;
}
public void moveLeft() {
if (caret.getPosition() > 0) {
caret.setPosition(caret.getPosition()-1);
}
caret.turnOn();
caretTime = 0;
}
public void moveRight() {
caret.setPosition(caret.getPosition()+1);
caret.turnOn();
caretTime = 0;
}
@Override
public void recomputeDimensions() {
root.recomputeDimensions();
}
@Override
public int getWidth() {
return root.getWidth();
}
@Override
public int getHeight() {
return root.getHeight();
}
@Override
public int getLine() {
return root.getLine();
}
/**
*
* @param delta Time, in seconds
* @return true if something changed
*/
public boolean beforeRender(float delta) {
boolean somethingChanged = false;
caretTime += delta;
if (caretTime >= CARET_DURATION) {
while (caretTime >= CARET_DURATION) {
caretTime -= CARET_DURATION;
caret.flipState();
somethingChanged = true;
}
}
return somethingChanged;
}
/**
*
* @param ge Graphic Engine class.
* @param r Graphic Renderer class of <b>ge</b>.
* @param x Position relative to the window.
* @param y Position relative to the window.
*/
public void draw(GraphicEngine ge, Renderer r, int x, int y) {
caret.resetRemaining();
root.draw(ge, r, x, y, caret);
int remaining = caret.getRemaining();
if (remaining >= 0) {
caret.setPosition(caret.getPosition()-remaining-1);
}
}
public void clear() {
caret = new Caret(CaretState.VISIBLE_ON, 0);
root.clear();
recomputeDimensions();
}
}

View File

@ -0,0 +1,35 @@
package org.warp.picalculator.gui.expression.containers;
import org.warp.picalculator.gui.expression.Block;
import org.warp.picalculator.gui.expression.BlockChar;
import org.warp.picalculator.gui.expression.BlockDivision;
import org.warp.picalculator.gui.expression.BlockSquareRoot;
import org.warp.picalculator.math.MathematicalSymbols;
public class NormalInputContainer extends InputContainer {
@Override
public Block parseChar(char c) {
switch(c) {
case MathematicalSymbols.DIVISION:
return new BlockDivision();
case MathematicalSymbols.SQUARE_ROOT:
return new BlockSquareRoot();
case MathematicalSymbols.MULTIPLICATION:
case MathematicalSymbols.SUM:
case MathematicalSymbols.SUBTRACTION:
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
return new BlockChar(c);
default:
return new BlockChar(c);
}
}
}

View File

@ -0,0 +1,5 @@
package org.warp.picalculator.gui.expression.containers;
public class NormalOutputContainer extends OutputContainer {
}

View File

@ -0,0 +1,71 @@
package org.warp.picalculator.gui.expression.containers;
import org.warp.picalculator.gui.expression.Block;
import org.warp.picalculator.gui.expression.BlockContainer;
import org.warp.picalculator.gui.expression.Caret;
import org.warp.picalculator.gui.expression.CaretState;
import org.warp.picalculator.gui.expression.GraphicalElement;
import org.warp.picalculator.gui.expression.layouts.InputLayout;
import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.Renderer;
public abstract class OutputContainer implements GraphicalElement, OutputLayout {
public final BlockContainer root;
private final Caret caret = new Caret(CaretState.HIDDEN, 0);
public OutputContainer() {
root = new BlockContainer();
}
public OutputContainer(boolean small) {
root = new BlockContainer(small);
}
public OutputContainer(boolean small, int minWidth, int minHeight) {
root = new BlockContainer(small);
}
@Override
public void recomputeDimensions() {
root.recomputeDimensions();
}
@Override
public int getWidth() {
return root.getWidth();
}
@Override
public int getHeight() {
return root.getHeight();
}
@Override
public int getLine() {
return root.getLine();
}
/**
*
* @param delta Time, in seconds
*/
public void beforeRender(double delta) {
}
/**
*
* @param ge Graphic Engine class.
* @param r Graphic Renderer class of <b>ge</b>.
* @param x Position relative to the window.
* @param y Position relative to the window.
*/
public void draw(GraphicEngine ge, Renderer r, int x, int y) {
root.draw(ge, r, x, y, caret);
}
public void clear() {
root.clear();
recomputeDimensions();
}
}

View File

@ -0,0 +1,5 @@
package org.warp.picalculator.gui.expression.containers;
public interface OutputLayout {
}

View File

@ -0,0 +1,7 @@
package org.warp.picalculator.gui.expression.layouts;
import org.warp.picalculator.gui.expression.Block;
public interface InputLayout {
public Block parseChar(char c);
}

View File

@ -269,21 +269,27 @@ public class CPUEngine implements GraphicEngine {
} }
if (iy0 == iy1) { if (iy0 == iy1) {
for (int x = 0; x <= ix1 - ix0; x++) { for (int x = 0; x <= ix1 - ix0; x++) {
if ((ix0+x < size[0]) & (iy0 < size[1])) {
canvas2d[ix0 + x + iy0 * size[0]] = color; canvas2d[ix0 + x + iy0 * size[0]] = color;
} }
}
} else if (ix0 == ix1) { } else if (ix0 == ix1) {
for (int y = 0; y <= iy1 - iy0; y++) { for (int y = 0; y <= iy1 - iy0; y++) {
if ((ix0 < size[0]) & (iy0+y < size[1])) {
canvas2d[ix0 + (iy0 + y) * size[0]] = color; canvas2d[ix0 + (iy0 + y) * size[0]] = color;
} }
}
} else { } else {
final int m = (iy1 - iy0) / (ix1 - ix0); final int m = (iy1 - iy0) / (ix1 - ix0);
for (int texx = 0; texx <= ix1 - ix0; texx++) { for (int texx = 0; texx <= ix1 - ix0; texx++) {
if (ix0 + texx < size[0] && iy0 + (m * texx) < size[1]) { if (ix0 + texx < size[0] && iy0 + (m * texx) < size[1]) {
if ((ix0 + texx < size[0]) & ((iy0 + (m * texx)) < size[1])) {
canvas2d[(ix0 + texx) + (iy0 + (m * texx)) * size[0]] = color; canvas2d[(ix0 + texx) + (iy0 + (m * texx)) * size[0]] = color;
} }
} }
} }
} }
}
@Override @Override
public void glFillRect(float x, float y, float width, float height, float uvX, float uvY, float uvWidth, public void glFillRect(float x, float y, float width, float height, float uvX, float uvY, float uvWidth,

View File

@ -49,7 +49,7 @@ public class GPUEngine implements org.warp.picalculator.gui.graphicengine.Graphi
public void setDisplayMode(int ww, int wh) { public void setDisplayMode(int ww, int wh) {
this.size[0] = ww; this.size[0] = ww;
this.size[1] = wh; this.size[1] = wh;
wnd.window.setSize(ww, wh); wnd.window.setSize(Utils.debugOn?ww*2:ww, Utils.debugOn?wh*2:wh);
} }
@Override @Override

View File

@ -24,7 +24,7 @@ import com.jogamp.opengl.util.texture.TextureIO;
public class GPURenderer implements Renderer { public class GPURenderer implements Renderer {
public GL2ES1 gl; public static GL2ES1 gl;
private final DeallocationHelper deallocationHelper = new DeallocationHelper(); private final DeallocationHelper deallocationHelper = new DeallocationHelper();
FloatBuffer fbVertices; FloatBuffer fbVertices;
@ -192,10 +192,10 @@ public class GPURenderer implements Renderer {
final FileInputStream f = new FileInputStream("test.png"); final FileInputStream f = new FileInputStream("test.png");
final TextureData tx_dat = TextureIO.newTextureData(gl.getGLProfile(), f, false, TextureIO.PNG); final TextureData tx_dat = TextureIO.newTextureData(gl.getGLProfile(), f, false, TextureIO.PNG);
final Texture tex = new Texture(gl, tx_dat); final Texture tex = new Texture(gl, tx_dat);
tex.setTexParameteri(gl, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); tex.setTexParameteri(gl, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
tex.setTexParameteri(gl, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST); tex.setTexParameteri(gl, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
tex.setTexParameteri(gl, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE); // tex.setTexParameteri(gl, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE);
tex.setTexParameteri(gl, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE); // tex.setTexParameteri(gl, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE);
return tex; return tex;
} }
@ -208,7 +208,10 @@ public class GPURenderer implements Renderer {
final ByteArrayOutputStream os = new ByteArrayOutputStream(); final ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(img, "png", os); ImageIO.write(img, "png", os);
final InputStream fis = new ByteArrayInputStream(os.toByteArray()); final InputStream fis = new ByteArrayInputStream(os.toByteArray());
return TextureIO.newTexture(fis, false, TextureIO.PNG); Texture tex = TextureIO.newTexture(fis, false, TextureIO.PNG);
tex.setTexParameteri(gl, GL.GL_TEXTURE_MIN_FILTER, GL.GL_NEAREST);
tex.setTexParameteri(gl, GL.GL_TEXTURE_MAG_FILTER, GL.GL_NEAREST);
return tex;
} }
@Override @Override

View File

@ -54,6 +54,7 @@ import java.awt.event.ComponentListener;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.Collection; import java.util.Collection;
import org.warp.picalculator.Utils;
import org.warp.picalculator.device.Keyboard; import org.warp.picalculator.device.Keyboard;
import org.warp.picalculator.device.Keyboard.Key; import org.warp.picalculator.device.Keyboard.Key;
import org.warp.picalculator.gui.DisplayManager; import org.warp.picalculator.gui.DisplayManager;
@ -278,7 +279,7 @@ class NEWTWindow implements GLEventListener {
//Transparency //Transparency
gl.glEnable(GL2ES1.GL_BLEND); gl.glEnable(GL2ES1.GL_BLEND);
gl.glBlendFunc(GL2ES1.GL_SRC_ALPHA, GL2ES1.GL_ONE_MINUS_SRC_ALPHA); gl.glBlendFunc(GL2ES1.GL_SRC_ALPHA, GL2ES1.GL_ONE_MINUS_SRC_ALPHA);
gl.glShadeModel(GL2ES1.GL_SMOOTH); gl.glShadeModel(GL2ES1.GL_FLAT);
try { try {
renderer.currentTex = ((GPUSkin) disp.loadSkin("test.png")).t; renderer.currentTex = ((GPUSkin) disp.loadSkin("test.png")).t;
@ -295,8 +296,8 @@ class NEWTWindow implements GLEventListener {
@Override @Override
public void reshape(GLAutoDrawable glad, int x, int y, int width, int height) { public void reshape(GLAutoDrawable glad, int x, int y, int width, int height) {
disp.size[0] = width; disp.size[0] = Utils.debugOn?width/2:width;
disp.size[1] = height; disp.size[1] = Utils.debugOn?height/2:height;
final GL2ES1 gl = glad.getGL().getGL2ES1(); final GL2ES1 gl = glad.getGL().getGL2ES1();
float max_wh, min_wh; float max_wh, min_wh;
if (width == 0) { if (width == 0) {
@ -318,7 +319,7 @@ class NEWTWindow implements GLEventListener {
gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION); gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION);
gl.glLoadIdentity(); gl.glLoadIdentity();
gl.glOrtho(0.0, width, height, 0.0, -1, 1); gl.glOrtho(0.0, Utils.debugOn?width/2:width, Utils.debugOn?height/2:height, 0.0, -1, 1);
gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW);
gl.glLoadIdentity(); gl.glLoadIdentity();

View File

@ -1,5 +1,6 @@
package org.warp.picalculator.gui.screens; package org.warp.picalculator.gui.screens;
import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.ObjectArrayList;
@ -16,6 +17,11 @@ import org.warp.picalculator.Utils;
import org.warp.picalculator.device.Keyboard; import org.warp.picalculator.device.Keyboard;
import org.warp.picalculator.device.Keyboard.Key; import org.warp.picalculator.device.Keyboard.Key;
import org.warp.picalculator.gui.DisplayManager; import org.warp.picalculator.gui.DisplayManager;
import org.warp.picalculator.gui.expression.BlockContainer;
import org.warp.picalculator.gui.expression.containers.InputContainer;
import org.warp.picalculator.gui.expression.containers.NormalInputContainer;
import org.warp.picalculator.gui.expression.containers.NormalOutputContainer;
import org.warp.picalculator.gui.expression.containers.OutputContainer;
import org.warp.picalculator.gui.graphicengine.BinaryFont; import org.warp.picalculator.gui.graphicengine.BinaryFont;
import org.warp.picalculator.gui.graphicengine.Renderer; import org.warp.picalculator.gui.graphicengine.Renderer;
import org.warp.picalculator.math.AngleMode; import org.warp.picalculator.math.AngleMode;
@ -32,114 +38,50 @@ import org.warp.picalculator.math.functions.Number;
public class MathInputScreen extends Screen { public class MathInputScreen extends Screen {
public volatile String currentExpression = "";
public volatile String newExpression = "";
public volatile int caretPos = 0;
public volatile boolean showCaret = true;
public volatile float showCaretDelta = 0f;
public MathContext calc; public MathContext calc;
public boolean autoscroll; public InputContainer userInput;
public int scrollX = 0; public OutputContainer result;
public int errorLevel = 0; // 0 = nessuno, 1 = risultato, 2 = tutto public int errorLevel = 0; // 0 = nessuno, 1 = risultato, 2 = tutto
boolean mustRefresh = true; boolean mustRefresh = true;
boolean firstStep = true;
public MathInputScreen() { public MathInputScreen() {
super(); super();
canBeInHistory = true; canBeInHistory = true;
calc = new MathContext();
} }
@Override @Override
public void created() throws InterruptedException { public void created() throws InterruptedException {
calc = new MathContext();
try {
BlockContainer.initializeFonts(DisplayManager.engine.loadFont("ex"), DisplayManager.engine.loadFont("big"));
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
userInput = new NormalInputContainer();
result = new NormalOutputContainer();
calc.init();
} }
@Override @Override
public void init() throws InterruptedException { public void init() throws InterruptedException {
/* Fine caricamento */ /* Fine caricamento */
// Parentesi f = new
// Parentesi("(Ⓐ(2X)*3Y)/(5Z^2)+(Ⓐ(11A)*13B)/(7CZ)=19XZ");
// PARENTESI CON CALCOLI
// Funzione f = new Sottrazione(new Somma(new Parentesi("Ⓐ9/2+Ⓐ7/2",
// "").calcola(), new Termine("3.5")), new
// Parentesi("3*2√14","").calcola());
// PARENTESI CON DUE NUMERI FRAZIONALI COMPLETI CON INCOGNITE:
// Funzione f = new
// Parentesi("(Ⓐ(2X)*3Y)/(5Z^2)+(Ⓐ(11A)*13B)/(7CZ)", "");
// PARENTESI CON DUE NUMERI FRAZIONALI DISALLINEATI GRAFICAMENTE:
// Funzione f = new Parentesi("((5^2-1)/2)/5-5/(5/2)=2", "");
// TERMINE DI PROVA COMPLETO:
// Funzione f = new Termine(new NumeroAvanzato(new Rational(3, 2),
// new Rational(7, 1), new Incognite(new Incognita('X',
// Rational.ONE)), new Incognite(new Incognita('Y', Rational.ONE)),
// new Incognite(new Incognita('z', Rational.ONE))));
// PARENTESI REALISTICA CON INCOGNITE:
// Funzione f = new Equazione(new
// Parentesi("X^2+(MX-M+4)^2-4X-4(MX-M+4)^2+7", ""), new
// Termine("0"));
// POTENZA:
// Funzione f = new Parentesi("(MX-M+4)^2", "");
// NUMERO SEMPLICE LUNGO:
// Funzione f = new Parentesi("-1219999799999996934.42229", "");
// :
// Funzione f = new Parentesi("5Y+XY=2", "")
// calcola("((5^2+3√(100/0.1))+Ⓐ(7)+9/15*2√(26/2))/21");
calc.init();
// interpreta("{(5X*(15X/3X))+(25X/(5X*(15X/3X)))=15{X=5"); //TODO RIMUOVERE
// long start = System.nanoTime();
// Termine result =
// Calculator.calcolarisultato("((5Ⓑ2+3√(100/0.1))*Ⓐ7+9/15*2√(26/2))/21");
// long end = System.nanoTime();
// long timeElapsed = end-start;
// System.out.println("RESULT: " + result);
// System.out.println("DECIMAl RESULT: " +
// result.getTerm().toBigDecimal());
// System.out.println("Time elapsed: " + (double) timeElapsed /
// 1000000 + " milliseconds\n");
//
//
// start = System.nanoTime();
// RisultatoEquazione eresult =
// Calculator.calcolaequazione("((5Ⓑ2+3√(100/0.1))*Ⓐ7+9/15*2√(26/2))/21=(175*(2√7)+3*(2√13))/105");
// end = System.nanoTime();
// timeElapsed = end-start;
// System.out.println("Is an equation: " + eresult.isAnEquation);
// System.out.println("L-R: " + eresult.LR);
// System.out.println("Time elapsed: " + (double) timeElapsed /
// 1000000 + " milliseconds\n");
}
public void interpreta(boolean temporary) throws Error {
final String eqn = newExpression;
if (!temporary) {
currentExpression = eqn;
}
calc.parseInputString(eqn);
} }
@Override @Override
public void beforeRender(float dt) { public void beforeRender(float dt) {
showCaretDelta += dt;
if (showCaretDelta >= 0.5f) {
mustRefresh = true;
showCaret = !showCaret;
showCaretDelta = 0f;
}
if (caretPos > newExpression.length()) {
caretPos = newExpression.length();
}
if (DisplayManager.error == null) { if (DisplayManager.error == null) {
DisplayManager.renderer.glClearColor(0xFFc5c2af); DisplayManager.renderer.glClearColor(0xFFc5c2af);
} else { } else {
DisplayManager.renderer.glClearColor(0xFFDC3C32); DisplayManager.renderer.glClearColor(0xFFDC3C32);
} }
if (userInput.beforeRender(dt)) {
mustRefresh = true;
}
} }
private static final BinaryFont fontBig = Utils.getFont(false); private static final BinaryFont fontBig = Utils.getFont(false);
@ -165,71 +107,11 @@ public class MathInputScreen extends Screen {
final int textColor = 0xFF000000; final int textColor = 0xFF000000;
final int padding = 4; final int padding = 4;
DisplayManager.renderer.glColor(textColor); DisplayManager.renderer.glColor(textColor);
final int caretRealPos = MathematicalSymbols.getGraphicRepresentation(newExpression.substring(0, caretPos)).length() * (fontBig.getCharacterWidth() + 1);
final String inputTextWithoutCaret = MathematicalSymbols.getGraphicRepresentation(newExpression); userInput.draw(DisplayManager.engine, DisplayManager.renderer, padding, padding + 20);
final boolean tooLongI = padding + fontBig.getStringWidth(newExpression) + padding >= Main.screenSize[0];
int scrollI = 0; if (!result.root.getContent().isEmpty()) {
if (tooLongI) { result.draw(DisplayManager.engine, DisplayManager.renderer, DisplayManager.engine.getWidth() - 2, DisplayManager.engine.getHeight() - 2);
scrollI = -scrollX;
if (-scrollI >= Main.screenSize[0]) {
scrollI += Main.screenSize[0];
} else {
scrollI = 0;
}
}
DisplayManager.renderer.glDrawStringLeft(padding + scrollI, padding + 20, inputTextWithoutCaret);
if (showCaret) {
DisplayManager.renderer.glDrawStringLeft(padding + scrollI + caretRealPos, padding + 20, "|");
}
if (tooLongI) {
DisplayManager.renderer.glColor(DisplayManager.renderer.glGetClearColor());
DisplayManager.renderer.glFillColor(Main.screenSize[0] - 16 - 2, padding + 20, fontBig.getCharacterHeight(), Main.screenSize[0]);
DisplayManager.renderer.glColor(textColor);
DisplayManager.drawSkinPart(Main.screenSize[0] - 16, padding + 20 + fontBig.getCharacterHeight() / 2 - 16 / 2, 304, 0, 304 + 16, 16);
}
if (calc.f != null) {
int topSpacing = 0;
final Iterator<Function> iter = calc.f.iterator();
while (iter.hasNext()) {
final Function fnc = iter.next();
try {
final boolean tooLong = padding + fnc.getWidth() + padding >= Main.screenSize[0];
int scrollA = 0;
if (tooLong) {
scrollA = -scrollX;
if (-scrollA >= Main.screenSize[0]) {
scrollA += Main.screenSize[0];
} else {
scrollA = 0;
}
}
final int y = padding + 20 + padding + fontBig.getCharacterHeight() + 1 + topSpacing;
fnc.draw(padding + scrollA, y, null, null);
if (tooLong) {
DisplayManager.renderer.glColor(DisplayManager.renderer.glGetClearColor());
DisplayManager.renderer.glFillColor(Main.screenSize[0] - 16 - 2, y, fnc.getHeight(), Main.screenSize[0]);
DisplayManager.renderer.glColor(textColor);
DisplayManager.drawSkinPart(Main.screenSize[0] - 16, y + fnc.getHeight() / 2 - 16 / 2, 304, 0, 304 + 16, 16);
}
} catch (final NullPointerException e) {
iter.remove();
}
topSpacing += fnc.getHeight() + 2;
}
}
if (calc.f2 != null) {
int bottomSpacing = 0;
for (final Function f : calc.f2) {
bottomSpacing += f.getHeight() + 2;
f.draw(DisplayManager.engine.getWidth() - 2 - f.getWidth(), DisplayManager.engine.getHeight() - bottomSpacing, null, null);
}
if (calc.resultsCount > 1 && calc.resultsCount != calc.f2.size()) {
final String resultsCountText = calc.resultsCount + " total results".toUpperCase();
DisplayManager.renderer.glColor(0xFF9AAEA0);
Utils.getFont(true).use(DisplayManager.engine);
bottomSpacing += fontBig.getCharacterHeight() + 2;
DisplayManager.renderer.glDrawStringRight(DisplayManager.engine.getWidth() - 2, DisplayManager.engine.getHeight() - bottomSpacing, resultsCountText);
}
} }
} }
@ -247,141 +129,142 @@ public class MathInputScreen extends Screen {
public boolean keyPressed(Key k) { public boolean keyPressed(Key k) {
switch (k) { switch (k) {
case STEP: case STEP:
if (newExpression.length() > 0) { // if (newExpression.length() > 0) {
if (firstStep) { // if (firstStep) {
try { // try {
try { // try {
interpreta(true); // interpreta(true);
showVariablesDialog(() -> { // showVariablesDialog(() -> {
currentExpression = newExpression; // currentExpression = newExpression;
calc.f2 = calc.f; // calc.f2 = calc.f;
firstStep = false; // firstStep = false;
step(); // step();
}); // });
} catch (final Exception ex) { // } catch (final Exception ex) {
if (Utils.debugOn) { // if (Utils.debugOn) {
ex.printStackTrace(); // ex.printStackTrace();
} // }
throw new Error(Errors.SYNTAX_ERROR); // throw new Error(Errors.SYNTAX_ERROR);
} // }
} catch (final Error e) { // } catch (final Error e) {
final StringWriter sw = new StringWriter(); // final StringWriter sw = new StringWriter();
final PrintWriter pw = new PrintWriter(sw); // final PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw); // e.printStackTrace(pw);
d.errorStackTrace = sw.toString().toUpperCase().replace("\t", " ").replace("\r", "").split("\n"); // d.errorStackTrace = sw.toString().toUpperCase().replace("\t", " ").replace("\r", "").split("\n");
DisplayManager.error = e.id.toString(); // DisplayManager.error = e.id.toString();
System.err.println(e.id); // System.err.println(e.id);
} // }
} else { // } else {
step(); // step();
} // }
} // }
return true; // return true;
case SIMPLIFY: case SIMPLIFY:
if (DisplayManager.error != null) { // if (DisplayManager.error != null) {
Utils.debug.println("Resetting after error..."); // Utils.debug.println("Resetting after error...");
DisplayManager.error = null; // DisplayManager.error = null;
currentExpression = null; // currentExpression = null;
calc.f = null; // calc.f = null;
calc.f2 = null; // calc.f2 = null;
calc.resultsCount = 0; // calc.resultsCount = 0;
// return true;
// } else {
// try {
// try {
// if (!firstStep) {
// step();
// } else {
// if (newExpression != currentExpression && newExpression.length() > 0) {
// changeEquationScreen();
// interpreta(true);
// showVariablesDialog(() -> {
// currentExpression = newExpression;
// simplify();
// });
// }
// }
// } catch (final Exception ex) {
// if (Utils.debugOn) {
// ex.printStackTrace();
// }
// throw new Error(Errors.SYNTAX_ERROR);
// }
// } catch (final Error e) {
// final StringWriter sw = new StringWriter();
// final PrintWriter pw = new PrintWriter(sw);
// e.printStackTrace(pw);
// d.errorStackTrace = sw.toString().toUpperCase().replace("\t", " ").replace("\r", "").split("\n");
// DisplayManager.error = e.id.toString();
// System.err.println(e.id);
// }
// return true;
// }
return true; return true;
} else {
try {
try {
if (!firstStep) {
step();
} else {
if (newExpression != currentExpression && newExpression.length() > 0) {
changeEquationScreen();
interpreta(true);
showVariablesDialog(() -> {
currentExpression = newExpression;
simplify();
});
}
}
} catch (final Exception ex) {
if (Utils.debugOn) {
ex.printStackTrace();
}
throw new Error(Errors.SYNTAX_ERROR);
}
} catch (final Error e) {
final StringWriter sw = new StringWriter();
final PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
d.errorStackTrace = sw.toString().toUpperCase().replace("\t", " ").replace("\r", "").split("\n");
DisplayManager.error = e.id.toString();
System.err.println(e.id);
}
return true;
}
case NUM0: case NUM0:
typeChar("0"); typeChar('0');
return true; return true;
case NUM1: case NUM1:
typeChar("1"); typeChar('1');
return true; return true;
case NUM2: case NUM2:
typeChar("2"); typeChar('2');
return true; return true;
case NUM3: case NUM3:
typeChar("3"); typeChar('3');
return true; return true;
case NUM4: case NUM4:
typeChar("4"); typeChar('4');
return true; return true;
case NUM5: case NUM5:
typeChar("5"); typeChar('5');
return true; return true;
case NUM6: case NUM6:
typeChar("6"); typeChar('6');
return true; return true;
case NUM7: case NUM7:
typeChar("7"); typeChar('7');
return true; return true;
case NUM8: case NUM8:
typeChar("8"); typeChar('8');
return true; return true;
case NUM9: case NUM9:
typeChar("9"); typeChar('9');
return true; return true;
case PLUS: case PLUS:
typeChar("+"); typeChar('+');
return true; return true;
case MINUS: case MINUS:
typeChar("-"); typeChar('-');
return true; return true;
case PLUS_MINUS: case PLUS_MINUS:
typeChar("±"); typeChar('±');
return true; return true;
case MULTIPLY: case MULTIPLY:
typeChar("*"); typeChar('*');
return true; return true;
case DIVIDE: case DIVIDE:
typeChar("/"); typeChar('/');
return true; return true;
case PARENTHESIS_OPEN: case PARENTHESIS_OPEN:
typeChar("("); typeChar('(');
return true; return true;
case PARENTHESIS_CLOSE: case PARENTHESIS_CLOSE:
typeChar(")"); typeChar(')');
return true; return true;
case DOT: case DOT:
typeChar("."); typeChar('.');
return true; return true;
case EQUAL: case EQUAL:
typeChar("="); typeChar('=');
return true; return true;
case SQRT: case SQRT:
typeChar(""); typeChar('Ⓐ');
return true; return true;
case ROOT: case ROOT:
typeChar(""); typeChar('√');
return true; return true;
case POWER_OF_2: case POWER_OF_2:
typeChar(MathematicalSymbols.POWER + "2"); typeChar(MathematicalSymbols.POWER_OF_TWO);
return true; return true;
case POWER_OF_x: case POWER_OF_x:
typeChar(MathematicalSymbols.POWER); typeChar(MathematicalSymbols.POWER);
@ -390,10 +273,10 @@ public class MathInputScreen extends Screen {
typeChar(MathematicalSymbols.PI); typeChar(MathematicalSymbols.PI);
return true; return true;
case LETTER_X: case LETTER_X:
typeChar(MathematicalSymbols.variables()[23]); typeChar(MathematicalSymbols.variables[23]);
return true; return true;
case LETTER_Y: case LETTER_Y:
typeChar(MathematicalSymbols.variables()[24]); typeChar(MathematicalSymbols.variables[24]);
return true; return true;
case SINE: case SINE:
typeChar(MathematicalSymbols.SINE); typeChar(MathematicalSymbols.SINE);
@ -414,84 +297,56 @@ public class MathInputScreen extends Screen {
typeChar(MathematicalSymbols.ARC_TANGENT); typeChar(MathematicalSymbols.ARC_TANGENT);
return true; return true;
case DELETE: case DELETE:
if (newExpression.length() > 0) { userInput.del();
if (caretPos > 0) { mustRefresh = true;
caretPos -= 1;
newExpression = newExpression.substring(0, caretPos) + newExpression.substring(caretPos + 1, newExpression.length());
} else {
newExpression = newExpression.substring(1);
}
try {
interpreta(true);
} catch (final Error e) {}
}
firstStep = true;
return true; return true;
case LEFT: case LEFT:
if (caretPos > 0) { userInput.moveLeft();
caretPos -= 1; mustRefresh = true;
} else {
caretPos = newExpression.length();
}
scrollX = fontBig.getStringWidth(newExpression.substring(0, caretPos) + "|||");
showCaret = true;
showCaretDelta = 0L;
return true; return true;
case RIGHT: case RIGHT:
if (caretPos < newExpression.length()) { userInput.moveRight();
caretPos += 1; mustRefresh = true;
} else {
caretPos = 0;
}
scrollX = fontBig.getStringWidth(newExpression.substring(0, caretPos) + "|||");
showCaret = true;
showCaretDelta = 0L;
return true; return true;
case RESET: case RESET:
userInput.clear();
result.clear();
if (DisplayManager.error != null) { if (DisplayManager.error != null) {
Utils.debug.println("Resetting after error..."); Utils.debug.println("Resetting after error...");
DisplayManager.error = null; DisplayManager.error = null;
return true;
} else {
caretPos = 0;
newExpression = "";
firstStep = false;
if (calc.f != null) {
calc.f = new ObjectArrayList<>();
} }
return true; return true;
}
case SURD_MODE: case SURD_MODE:
calc.exactMode = !calc.exactMode; // calc.exactMode = !calc.exactMode;
if (calc.exactMode == false) { // if (calc.exactMode == false) {
calc.f2 = solveExpression(calc.f2); // calc.f2 = solveExpression(calc.f2);
} else { // } else {
currentExpression = ""; // currentExpression = "";
Keyboard.keyPressed(Key.SIMPLIFY); // Keyboard.keyPressed(Key.SIMPLIFY);
} // }
return true; return true;
case debug1: case debug1:
DisplayManager.INSTANCE.setScreen(new EmptyScreen()); DisplayManager.INSTANCE.setScreen(new EmptyScreen());
return true; return true;
case HISTORY_BACK: case HISTORY_BACK:
if (DisplayManager.INSTANCE.canGoBack()) { // if (DisplayManager.INSTANCE.canGoBack()) {
if (currentExpression != null && currentExpression.length() > 0 & DisplayManager.sessions[DisplayManager.currentSession + 1] instanceof MathInputScreen) { // if (currentExpression != null && currentExpression.length() > 0 & DisplayManager.sessions[DisplayManager.currentSession + 1] instanceof MathInputScreen) {
newExpression = currentExpression; // newExpression = currentExpression;
try { // try {
interpreta(true); // interpreta(true);
} catch (final Error e) {} // } catch (final Error e) {}
} // }
} // }
return false; return false;
case HISTORY_FORWARD: case HISTORY_FORWARD:
if (DisplayManager.INSTANCE.canGoForward()) { // if (DisplayManager.INSTANCE.canGoForward()) {
if (currentExpression != null && currentExpression.length() > 0 & DisplayManager.sessions[DisplayManager.currentSession - 1] instanceof MathInputScreen) { // if (currentExpression != null && currentExpression.length() > 0 & DisplayManager.sessions[DisplayManager.currentSession - 1] instanceof MathInputScreen) {
newExpression = currentExpression; // newExpression = currentExpression;
try { // try {
interpreta(true); // interpreta(true);
} catch (final Error e) {} // } catch (final Error e) {}
} // }
} // }
return false; return false;
case debug_DEG: case debug_DEG:
if (calc.angleMode.equals(AngleMode.DEG) == false) { if (calc.angleMode.equals(AngleMode.DEG) == false) {
@ -660,18 +515,9 @@ public class MathInputScreen extends Screen {
} }
} }
public void typeChar(String chr) { public void typeChar(char chr) {
final int len = chr.length(); userInput.typeChar(chr);
newExpression = newExpression.substring(0, caretPos) + chr + newExpression.substring(caretPos, newExpression.length()); mustRefresh = true;
caretPos += len;
scrollX = fontBig.getStringWidth(newExpression.substring(0, caretPos) + "|||");
showCaret = true;
showCaretDelta = 0L;
firstStep = true;
try {
interpreta(true);
} catch (final Error e) {}
// f.clear(); //TODO: I removed this line to prevent input blanking when pressing EQUALS button and cloning this screen, but I must see why I created this part of code.
} }
@Override @Override
@ -751,21 +597,11 @@ public class MathInputScreen extends Screen {
public MathInputScreen clone() { public MathInputScreen clone() {
final MathInputScreen es = this; final MathInputScreen es = this;
final MathInputScreen es2 = new MathInputScreen(); final MathInputScreen es2 = new MathInputScreen();
es2.scrollX = es.scrollX;
es2.newExpression = es.newExpression;
es2.currentExpression = es.currentExpression;
es2.showCaret = es.showCaret;
es2.showCaretDelta = es.showCaretDelta;
es2.caretPos = es.caretPos;
// es2.calc.f = Utils.cloner.deepClone(es.calc.f);
// es2.calc.f2 = Utils.cloner.deepClone(es.calc.f2);
// es2.calc.resultsCount = es.calc.resultsCount;
es2.autoscroll = es.autoscroll;
es2.errorLevel = es.errorLevel; es2.errorLevel = es.errorLevel;
es2.mustRefresh = es.mustRefresh; es2.mustRefresh = es.mustRefresh;
es2.firstStep = es.firstStep;
// es2.calc.variablesValues = Utils.cloner.deepClone(es.calc.variablesValues);
es2.calc = Utils.cloner.deepClone(es.calc); es2.calc = Utils.cloner.deepClone(es.calc);
es2.userInput = Utils.cloner.deepClone(es.userInput);
es2.result = Utils.cloner.deepClone(es.result);
return es2; return es2;
} }

View File

@ -102,18 +102,6 @@ public class MathContext {
} }
} }
public void parseInputString(String eqn) throws Error {
final ObjectArrayList<Function> fncs = new ObjectArrayList<>();
if (eqn.length() > 0) {
try {
fncs.add(parseString(eqn.replace("sqrt", MathematicalSymbols.SQUARE_ROOT).replace("^", MathematicalSymbols.POWER)));
} catch (final Exception ex) {
}
}
f = fncs;
}
/*public void solve(EquationScreen equationScreen, char letter) throws Error { /*public void solve(EquationScreen equationScreen, char letter) throws Error {
if (Calculator.currentSession == 0 && Calculator.sessions[0] instanceof EquationScreen) { if (Calculator.currentSession == 0 && Calculator.sessions[0] instanceof EquationScreen) {
EquationScreen es = (EquationScreen) Calculator.sessions[0]; EquationScreen es = (EquationScreen) Calculator.sessions[0];

View File

@ -16,6 +16,7 @@ public class MathematicalSymbols {
public static final char PARENTHESIS_OPEN = '('; public static final char PARENTHESIS_OPEN = '(';
public static final char PARENTHESIS_CLOSE = ')'; public static final char PARENTHESIS_CLOSE = ')';
public static final char POWER = 'Ⓑ'; public static final char POWER = 'Ⓑ';
public static final char POWER_OF_TWO = 'Ⓘ';
public static final char EQUATION = '='; public static final char EQUATION = '=';
public static final char SYSTEM = '{'; public static final char SYSTEM = '{';
public static final char SINE = 'Ⓒ'; public static final char SINE = 'Ⓒ';
@ -29,7 +30,7 @@ public class MathematicalSymbols {
public static final char[] functionsNSN = new char[] { NTH_ROOT, POWER }; public static final char[] functionsNSN = new char[] { NTH_ROOT, POWER };
public static final char[] functionsSN = new char[] { SQUARE_ROOT, MINUS, SINE, COSINE, TANGENT, ARC_SINE, ARC_COSINE, ARC_TANGENT }; public static final char[] functionsSN = new char[] { SQUARE_ROOT, POWER_OF_TWO, MINUS, SINE, COSINE, TANGENT, ARC_SINE, ARC_COSINE, ARC_TANGENT };
public static final char[] functions = concat(functionsNSN, functionsSN); public static final char[] functions = concat(functionsNSN, functionsSN);

View File

@ -96,4 +96,9 @@ public class Division extends FunctionOperator {
public FunctionOperator clone() { public FunctionOperator clone() {
return new Division(this.getMathContext(), this.getParameter1(), this.getParameter2()); return new Division(this.getMathContext(), this.getParameter1(), this.getParameter2());
} }
@Override
public String toString() {
return "("+this.getParameter1()+")/("+this.getParameter2()+")";
}
} }

View File

@ -106,10 +106,6 @@ public class Multiplication extends FunctionOperator {
@Override @Override
public String toString() { public String toString() {
if (parameter1 != null && parameter2 != null) { return "("+parameter1.toString()+")*("+parameter2.toString()+")";
return parameter1.toString()+"*"+parameter2.toString();
} else {
return super.toString();
}
} }
} }

View File

@ -7,6 +7,7 @@ import org.warp.picalculator.gui.expression.BlockChar;
import org.warp.picalculator.gui.expression.BlockContainer; import org.warp.picalculator.gui.expression.BlockContainer;
import org.warp.picalculator.gui.expression.BlockDivision; import org.warp.picalculator.gui.expression.BlockDivision;
import org.warp.picalculator.math.Function; import org.warp.picalculator.math.Function;
import org.warp.picalculator.math.FunctionOperator;
import org.warp.picalculator.math.FunctionSingle; import org.warp.picalculator.math.FunctionSingle;
import org.warp.picalculator.math.MathContext; import org.warp.picalculator.math.MathContext;
import org.warp.picalculator.math.MathematicalSymbols; import org.warp.picalculator.math.MathematicalSymbols;
@ -30,7 +31,7 @@ import com.sun.org.apache.xpath.internal.functions.Function2Args;
import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import it.unimi.dsi.fastutil.objects.ObjectListIterator; import it.unimi.dsi.fastutil.objects.ObjectListIterator;
public class InputParser { public class MathParser {
public static Expression parseInput(MathContext context, BlockContainer root) throws Error { public static Expression parseInput(MathContext context, BlockContainer root) throws Error {
Expression result; Expression result;
@ -57,14 +58,18 @@ public class InputParser {
Feature result; Feature result;
if (block instanceof BlockChar) { int blockType = block.getClassID();
switch (blockType) {
case BlockChar.CLASS_ID:
result = new FeatureChar(((BlockChar) block).getChar()); result = new FeatureChar(((BlockChar) block).getChar());
} else if (block instanceof BlockDivision) { break;
case BlockDivision.CLASS_ID:
BlockDivision bd = (BlockDivision) block; BlockDivision bd = (BlockDivision) block;
Function upper = parseContainer(context, bd.getUpperContainer()); Function upper = parseContainer(context, bd.getUpperContainer());
Function lower = parseContainer(context, bd.getLowerContainer()); Function lower = parseContainer(context, bd.getLowerContainer());
result = new FeatureDivision(upper, lower); result = new FeatureDivision(upper, lower);
} else { break;
default:
throw new Error(Errors.SYNTAX_ERROR); throw new Error(Errors.SYNTAX_ERROR);
} }
@ -108,17 +113,31 @@ public class InputParser {
} }
//Phase 2 //Phase 2
stackIterator = process.iterator(); stackIterator = process.listIterator();
while (stackIterator.hasNext()) { while (stackIterator.hasNext()) {
Function f = stackIterator.next(); Function f = stackIterator.next();
final int curIndex = stackIterator.previousIndex();
if (f instanceof Multiplication || f instanceof Division) { if (f instanceof Multiplication || f instanceof Division) {
if (curIndex-1>=0 && stackIterator.hasNext()) {
Function next = process.get(curIndex+1);
Function prev = process.get(curIndex-1);
stackIterator.set(
f.setParameter(0, prev)
.setParameter(1, next)
);
process.remove(curIndex+1);
process.remove(curIndex-1);
} else {
if (f.getParameter(0) == null || f.getParameter(1) == null) {
throw new Error(Errors.MISSING_ARGUMENTS, "There is a function at the end without any argument specified.");
}
}
} }
} }
//Phase 3 //Phase 3
stackIterator = process.iterator(); stackIterator = process.listIterator();
while (stackIterator.hasNext()) { while (stackIterator.hasNext()) {
Function f = stackIterator.next(); Function f = stackIterator.next();