WarpPI/core/src/main/java/it/cavallium/warppi/gui/expression/containers/NormalInputContainer.java
2023-08-23 16:47:55 +02:00

164 lines
4.5 KiB
Java

package it.cavallium.warppi.gui.expression.containers;
import it.cavallium.warppi.gui.expression.Caret;
import it.cavallium.warppi.gui.expression.CaretState;
import it.cavallium.warppi.gui.expression.InputContext;
import it.cavallium.warppi.gui.expression.blocks.*;
import it.cavallium.warppi.math.MathematicalSymbols;
import java.util.ArrayList;
import java.util.List;
public class NormalInputContainer extends InputContainer {
@Deprecated()
/**
* Use NormalInputContainer(InputContext) instead
*/
public NormalInputContainer() {
super();
}
public NormalInputContainer(final InputContext ic) {
super(ic);
}
public NormalInputContainer(final InputContext ic, final boolean small) {
super(ic, small);
}
public NormalInputContainer(final InputContext ic, final boolean small, final int minWidth, final int minHeight) {
super(ic, small, minWidth, minHeight);
}
/**
* Copy
* @param ic
*/
public NormalInputContainer(InputContainer old, InputContext ic) {
super(old, ic);
}
@Override
public Block parseChar(final char c) {
switch (c) {
case MathematicalSymbols.DIVISION:
return new BlockDivision();
case MathematicalSymbols.SQUARE_ROOT:
return new BlockSquareRoot();
case MathematicalSymbols.PARENTHESIS_OPEN:
return new BlockParenthesis();
case MathematicalSymbols.PARENTHESIS_CLOSE:
return null;
case MathematicalSymbols.POWER:
return new BlockPower();
case MathematicalSymbols.POWER_OF_TWO:
return new BlockPower2();
case MathematicalSymbols.MULTIPLICATION:
case MathematicalSymbols.SUM:
case MathematicalSymbols.SUM_SUBTRACTION:
case MathematicalSymbols.SUBTRACTION:
return new BlockChar(c);
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '.':
return new BlockNumericChar(c);
case MathematicalSymbols.SINE:
return new BlockSine();
case MathematicalSymbols.LOGARITHM:
return new BlockLogarithm();
case MathematicalSymbols.PI:
return new BlockVariable(inputContext, c, true);
case MathematicalSymbols.EULER_NUMBER:
return new BlockVariable(inputContext, c, true);
default:
for (final char v : MathematicalSymbols.variables) {
if (c == v) {
return new BlockVariable(inputContext, c);
}
}
return new BlockChar(c);
}
}
@Override
public void typeChar(final char c) {
super.typeChar(c);
switch (c) {
case MathematicalSymbols.PARENTHESIS_CLOSE: {
final BlockReference<?> ref = getSelectedBlock();
BlockParenthesisAbstract parenthesis = findParenthesis(ref.get());
if (parenthesis == null) {
break;
} else {
moveTo(new BlockPosition(parenthesis));
}
break;
}
case MathematicalSymbols.POWER_OF_TWO:
moveTo(new BlockPosition(getSelectedBlock().get()));
break;
case MathematicalSymbols.DIVISION: {
@SuppressWarnings("unchecked")
final BlockReference<BlockDivision> ref = (BlockReference<BlockDivision>) getSelectedBlock();
@SuppressWarnings("unused")
final BlockContainer parentContainer = ref.getContainer();
BlockReference<?> currentBlock = ref;
List<Block> blocksToMove = new ArrayList<>();
boolean groupedBefore = false;
int before = 0;
while (true) {
currentBlock = currentBlock.getPreviousBlock();
if (currentBlock == null) {
break;
}
final Block b = currentBlock.get();
if (b instanceof BlockNumericChar || b instanceof BlockVariable) {
if (!groupedBefore) {
groupedBefore = true;
}
blocksToMove.add(b);
before++;
} else {
break;
}
}
if (groupedBefore) {
var div = ref.get();
var upperContainer = div.getUpperContainer();
for (int i = blocksToMove.size() - 1; i >= 0; i--) {
var b = blocksToMove.get(i);
b.getParentContainer().removeBlockUnsafe(b);
upperContainer.appendBlock(b);
}
div.recomputeDimensionsToRoot();
moveTo(new BlockPosition(div.getLowerContainer()));
}
break;
}
}
}
private BlockParenthesisAbstract findParenthesis(Block o) {
while (!(o instanceof BlockParenthesisAbstract)) {
var pc = o.getParentContainer();
if (!pc.hasParent()) {
return null;
}
o = pc.getParentBlock();
if (o == null) {
return null;
}
}
return (BlockParenthesisAbstract) o;
}
}