-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
21 changed files
with
743 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
.idea | ||
*.tff | ||
*.ttf | ||
*.iml | ||
/cm-unicode-0.7.0 | ||
/out |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package com.kieferlam.maths | ||
|
||
import com.kieferlam.maths.fx.Launcher | ||
import javafx.application.Application | ||
|
||
fun main(args: Array<String>) { | ||
Application.launch(Launcher::class.java) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package com.kieferlam.maths.fx | ||
|
||
import com.kieferlam.maths.fx.style.MenubarStyle | ||
import com.kieferlam.maths.fx.view.RootView | ||
import javafx.stage.Stage | ||
import tornadofx.* | ||
|
||
class Launcher : App(RootView::class){ | ||
|
||
init{ | ||
reloadStylesheetsOnFocus() | ||
} | ||
|
||
override fun start(stage: Stage) { | ||
stage.width = 1280.0 | ||
stage.height = 720.0 | ||
stage.title = "Maths" | ||
super.start(stage) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package com.kieferlam.maths.fx.style | ||
|
||
import tornadofx.* | ||
|
||
class MenubarStyle : Stylesheet(){ | ||
init{ | ||
menuBar{ | ||
padding = box(0.0.px) | ||
} | ||
menu{ | ||
padding = box(5.0.px, 8.0.px) | ||
} | ||
menuItem{ | ||
padding = box(100.0.px) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package com.kieferlam.maths.fx.view | ||
|
||
import com.kieferlam.maths.fx.view.maths.MathsInputPane | ||
import com.kieferlam.maths.fx.view.menu.GlobalMenuBar | ||
import javafx.scene.Parent | ||
import javafx.scene.layout.BorderPane | ||
import tornadofx.* | ||
|
||
class RootView : View(){ | ||
override val root = BorderPane() | ||
|
||
init{ | ||
root.top = GlobalMenuBar() | ||
root.center = MathsInputPane() | ||
} | ||
|
||
} |
117 changes: 117 additions & 0 deletions
117
src/com/kieferlam/maths/fx/view/maths/MathsInputPane.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
package com.kieferlam.maths.fx.view.maths | ||
|
||
import com.kieferlam.maths.fx.view.render.MathsRenderer | ||
import com.kieferlam.maths.fx.view.render.measureString | ||
import com.kieferlam.maths.fx.view.render.operator.OperatorRenderer | ||
import com.kieferlam.postfix.exception.InvalidSyntaxException | ||
import com.kieferlam.postfix.syntax.ExpressionEntity | ||
import com.kieferlam.postfix.syntax.Postfix | ||
import javafx.application.Platform | ||
import javafx.event.EventHandler | ||
import javafx.scene.canvas.Canvas | ||
import javafx.scene.image.Image | ||
import javafx.scene.layout.Pane | ||
import javafx.scene.paint.Color | ||
import tornadofx.add | ||
import java.util.* | ||
|
||
class MathsInputPane : Pane() { | ||
|
||
private val canvas = Canvas() | ||
private val context by lazy { canvas.graphicsContext2D } | ||
|
||
private var inputString = "" | ||
private var postfix = ArrayList<ExpressionEntity>() | ||
private var resultString = "NaN" | ||
private var mathsRender = Stack<Image>() | ||
|
||
private var isDrawing = false | ||
private val drawThread = Thread({ | ||
isDrawing = true | ||
while (isDrawing) { | ||
if (!this.scene.window.isShowing) isDrawing = false | ||
draw() | ||
Thread.sleep(1000L) | ||
} | ||
}) | ||
|
||
init { | ||
canvas.widthProperty().bind(widthProperty()) | ||
canvas.heightProperty().bind(heightProperty()) | ||
canvas.widthProperty().addListener { _, _, _ -> | ||
draw() | ||
} | ||
canvas.heightProperty().addListener { _, _, _ -> | ||
draw() | ||
} | ||
|
||
add(canvas) | ||
onMousePressed = EventHandler { | ||
this.requestFocus() | ||
} | ||
|
||
onKeyTyped = EventHandler { | ||
when (it.character) { | ||
"\b" -> { | ||
if (inputString.isNotEmpty()) inputString = inputString.substring(0, inputString.length - 1) | ||
} | ||
"\u000D" -> { | ||
} | ||
else -> inputString += it.character | ||
} | ||
|
||
try { | ||
postfix = Postfix.from(inputString) | ||
resultString = Postfix.evaluate(postfix).value.toDouble().toString() | ||
Platform.runLater { | ||
mathsRender = MathsRenderer.render(postfix) | ||
} | ||
} catch (syntax: InvalidSyntaxException) { | ||
"Syntax Error" | ||
} catch (e: Exception) { | ||
e.message!! | ||
} | ||
|
||
draw() | ||
} | ||
|
||
Platform.runLater { | ||
drawThread.start() | ||
} | ||
} | ||
|
||
fun draw() { | ||
with(context) { | ||
clearRect(0.0, 0.0, width, height) | ||
|
||
fill = Color.BLACK | ||
font = OperatorRenderer.FONT | ||
|
||
val displayString = inputString + " = " + resultString | ||
val textSize = measureString(displayString, font) | ||
val xScale = Math.min(width / textSize.width, 1.0) | ||
val yScale = Math.min(height / (textSize.height + (mathsRender.maxBy { it.height }?.height ?: 0.0)), 1.0) | ||
val scale = Math.min(xScale, yScale) | ||
|
||
save() | ||
translate(width * 0.5, height * 0.5) | ||
scale(scale * 0.8, scale * 0.8) | ||
|
||
fillText(displayString, -textSize.width * 0.5, -textSize.height) | ||
|
||
fill = Color.LIGHTGRAY | ||
strokeLine(-canvas.width, -100.0, canvas.width, -100.0) | ||
fill = Color.BLACK | ||
|
||
var x = 0.0 | ||
mathsRender.forEach { | ||
drawImage(it, x - 500, -(it.height * 0.5) + 200.0) | ||
x += it.width | ||
} | ||
|
||
restore() | ||
|
||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package com.kieferlam.maths.fx.view.menu | ||
|
||
import javafx.scene.control.Menu | ||
import javafx.scene.control.MenuItem | ||
|
||
class FileMenu : Menu("File") { | ||
init { | ||
items.addAll( | ||
New(), | ||
Open() | ||
) | ||
} | ||
} | ||
|
||
private class New : MenuItem("New") { | ||
init{ | ||
setOnAction { | ||
|
||
} | ||
} | ||
} | ||
|
||
private class Open : MenuItem("Open") { | ||
init{ | ||
setOnAction { | ||
|
||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package com.kieferlam.maths.fx.view.menu | ||
|
||
import com.kieferlam.maths.fx.style.MenubarStyle | ||
import javafx.scene.control.Menu | ||
import javafx.scene.control.MenuBar | ||
import javafx.scene.control.MenuItem | ||
import tornadofx.* | ||
|
||
class GlobalMenuBar : MenuBar(){ | ||
init{ | ||
menus.addAll( | ||
FileMenu() | ||
) | ||
} | ||
|
||
override fun getUserAgentStylesheet(): String = MenubarStyle().base64URL.toExternalForm() | ||
} |
3 changes: 3 additions & 0 deletions
3
src/com/kieferlam/maths/fx/view/render/MathsRenderException.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package com.kieferlam.maths.fx.view.render | ||
|
||
class MathsRenderException(msg: String = "") : Exception("Unable to render maths expression: $msg") |
16 changes: 16 additions & 0 deletions
16
src/com/kieferlam/maths/fx/view/render/MathsRenderUtils.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.kieferlam.maths.fx.view.render | ||
|
||
import javafx.scene.Group | ||
import javafx.scene.Scene | ||
import javafx.scene.text.Font | ||
import javafx.scene.text.Text | ||
import tornadofx.* | ||
|
||
fun measureString(string: String, font: Font): Size { | ||
var text = Text(string) | ||
text.font = font | ||
Scene(Group(text)) | ||
return Size(text.layoutBounds.width, text.layoutBounds.height) | ||
} | ||
|
||
data class Size(val width: Double, val height: Double) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package com.kieferlam.maths.fx.view.render | ||
|
||
import com.kieferlam.maths.fx.view.render.operator.OperandRenderer | ||
import com.kieferlam.maths.fx.view.render.operator.OperatorRenderer | ||
import com.kieferlam.postfix.syntax.ExpressionEntity | ||
import com.kieferlam.postfix.syntax.Operand | ||
import com.kieferlam.postfix.syntax.Operator | ||
import com.kieferlam.postfix.syntax.operator.function.FunctionOperator | ||
import javafx.scene.SnapshotParameters | ||
import javafx.scene.canvas.Canvas | ||
import javafx.scene.image.Image | ||
import javafx.scene.image.WritableImage | ||
import java.util.* | ||
import kotlin.collections.ArrayList | ||
|
||
object MathsRenderer { | ||
|
||
fun render(expression: ArrayList<ExpressionEntity>): Stack<Image> { | ||
var stack = Stack<Image>() | ||
for (e in expression) { | ||
if (e.isOperator) { | ||
val numOfOperands = (e as Operator).numberOfParameters | ||
if (stack.size < numOfOperands) throw MathsRenderException("Not enough operands (operator requires $numOfOperands operands).") | ||
val operandImgs = ArrayList<Image>() | ||
for (i in 0 until numOfOperands) { | ||
operandImgs.add(stack.pop()) | ||
} | ||
stack.push(OperatorRenderer.getRenderer(e).render(e, *operandImgs.toTypedArray().reversedArray())) | ||
} else { | ||
stack.push(OperandRenderer.render(e as Operand)) | ||
} | ||
} | ||
return stack | ||
} | ||
|
||
} |
53 changes: 53 additions & 0 deletions
53
src/com/kieferlam/maths/fx/view/render/operator/DefaultFunctionRenderer.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package com.kieferlam.maths.fx.view.render.operator | ||
|
||
import com.kieferlam.maths.fx.view.render.MathsRenderException | ||
import com.kieferlam.maths.fx.view.render.Size | ||
import com.kieferlam.maths.fx.view.render.measureString | ||
import com.kieferlam.postfix.syntax.Operator | ||
import com.kieferlam.postfix.syntax.operator.function.FunctionOperator | ||
import javafx.geometry.VPos | ||
import javafx.scene.SnapshotParameters | ||
import javafx.scene.canvas.Canvas | ||
import javafx.scene.image.Image | ||
import javafx.scene.paint.Color | ||
|
||
class DefaultFunctionRenderer : OperatorRenderer(FunctionOperator.ABSOLUTE) { | ||
|
||
override fun render(operator: Operator?, vararg operands: Image): Image { | ||
if (operator == null) throw MathsRenderException("Operator is null.") | ||
if(operands.size < operator.numberOfParameters) throw MathsRenderException("Not enough parameters.") | ||
val canvas = Canvas() | ||
val g = canvas.graphicsContext2D | ||
val snapshot = SnapshotParameters() | ||
snapshot.fill = Color.TRANSPARENT | ||
// snapshot.fill = Color.rgb((Math.random() * 255).toInt(), (Math.random() * 255).toInt(), (Math.random() * 255).toInt()) | ||
|
||
val operatorSize = measureString(operator.symbol + "()", FONT) | ||
|
||
val operandSize = Size(operands.sumBy { it.width.toInt() }.toDouble() , operands.maxBy { it.height.toInt() }!!.height) | ||
|
||
canvas.width = operatorSize.width + operandSize.width | ||
canvas.height = operandSize.height | ||
|
||
var operandIndex = 0 | ||
var drawX = 0.0 | ||
|
||
with(g) { | ||
font = OperatorRenderer.FONT | ||
fill = Color.BLACK | ||
textBaseline = VPos.TOP | ||
if(operator.numberOfParameters > 1){ | ||
drawImage(operands[operandIndex], drawX, (canvas.height - operands[operandIndex].height)*0.5) | ||
drawX += operands[operandIndex].width | ||
operandIndex++ | ||
} | ||
fillText(operator.symbol, drawX, ((canvas.height - operatorSize.height) * 0.5) - 15.0) | ||
drawX += operatorSize.width | ||
drawImage(operands[operandIndex], drawX, (canvas.height - operands[operandIndex].height)*0.5) | ||
operandIndex++ | ||
} | ||
|
||
return canvas.snapshot(snapshot, null) | ||
} | ||
|
||
} |
Oops, something went wrong.