it all works - some output problems
This commit is contained in:
6
.idea/cssdialects.xml
generated
Normal file
6
.idea/cssdialects.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CssDialectMappings">
|
||||
<file url="file://$PROJECT_DIR$/ide/src/main/resources/befide/ide/style.css" dialect="CLASSIC" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -46,5 +46,14 @@
|
||||
<orderEntry type="library" scope="TEST" name="Maven: org.jetbrains.kotlin:kotlin-test-common:1.3.0" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jetbrains.kotlin:kotlin-stdlib:1.3.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jetbrains.kotlin:kotlin-stdlib-common:1.3.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jetbrains:annotations:13.0" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: org.jetbrains.kotlin:kotlin-test-junit:1.3.0" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: org.jetbrains.kotlin:kotlin-test-annotations-common:1.3.0" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: org.jetbrains.kotlin:kotlin-test:1.3.0" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: org.jetbrains.kotlin:kotlin-test-common:1.3.0" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -10,4 +10,5 @@ data class Vec(val x: Int, val y: Int) {
|
||||
operator fun times(c: Int) = Vec(x * c, y * c)
|
||||
|
||||
infix fun mod(other: Vec) = Vec(x mod other.x, y mod other.y)
|
||||
operator fun unaryMinus() = Vec(-x, -y)
|
||||
}
|
||||
15
ide/ide.iml
15
ide/ide.iml
@@ -47,6 +47,21 @@
|
||||
<orderEntry type="library" scope="TEST" name="Maven: org.jetbrains.kotlin:kotlin-test-common:1.3.0" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
|
||||
<orderEntry type="library" name="Maven: no.tornado:tornadofx:1.7.17" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.glassfish:javax.json:1.1.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: javax.json:javax.json-api:1.1.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.2.60" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.2.60" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jetbrains.kotlin:kotlin-reflect:1.2.60" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jetbrains.kotlin:kotlin-stdlib:1.3.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jetbrains.kotlin:kotlin-stdlib-common:1.3.0" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.jetbrains:annotations:13.0" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: org.jetbrains.kotlin:kotlin-test-junit:1.3.0" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: org.jetbrains.kotlin:kotlin-test-annotations-common:1.3.0" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: org.jetbrains.kotlin:kotlin-test:1.3.0" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: org.jetbrains.kotlin:kotlin-test-common:1.3.0" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
|
||||
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
|
||||
<orderEntry type="module" module-name="befunge" />
|
||||
<orderEntry type="library" name="Maven: no.tornado:tornadofx:1.7.17" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.glassfish:javax.json:1.1.2" level="project" />
|
||||
|
||||
@@ -6,7 +6,7 @@ import javafx.animation.Timeline
|
||||
import javafx.util.Duration
|
||||
import tornadofx.*
|
||||
|
||||
class ActionView(val interp: Interpreter, val ioView: IOView) : View() {
|
||||
class ActionView(val interp: Interpreter, val codeView: CodeView, val ioView: IOView) : View() {
|
||||
var runTimeline: Timeline = timeline(false) {
|
||||
keyframe(Duration.seconds(0.0)) {
|
||||
setOnFinished {
|
||||
@@ -21,25 +21,36 @@ class ActionView(val interp: Interpreter, val ioView: IOView) : View() {
|
||||
|
||||
override val root = hbox {
|
||||
button("step") {
|
||||
setOnAction { interp.step() }
|
||||
setOnAction {
|
||||
interp.funge.setString(codeView.src)
|
||||
interp.step()
|
||||
}
|
||||
}
|
||||
|
||||
button("reset") {
|
||||
enableWhen(codeView.lockedProperty)
|
||||
|
||||
setOnAction {
|
||||
interp.reset()
|
||||
ioView.reset()
|
||||
codeView.src = interp.funge.toString()
|
||||
codeView.locked = false
|
||||
}
|
||||
}
|
||||
|
||||
button("run") {
|
||||
setOnAction {
|
||||
runTimeline.rate = 10000000.0
|
||||
interp.funge.setString(codeView.src)
|
||||
codeView.locked = true
|
||||
runTimeline.rate = 10000.0
|
||||
runTimeline.playFromStart()
|
||||
}
|
||||
}
|
||||
|
||||
button("walk") {
|
||||
setOnAction {
|
||||
interp.funge.setString(codeView.src)
|
||||
codeView.locked = true
|
||||
runTimeline.rate = 50.0
|
||||
runTimeline.playFromStart()
|
||||
}
|
||||
@@ -47,6 +58,8 @@ class ActionView(val interp: Interpreter, val ioView: IOView) : View() {
|
||||
|
||||
button("crawl") {
|
||||
setOnAction {
|
||||
interp.funge.setString(codeView.src)
|
||||
codeView.locked = true
|
||||
runTimeline.rate = 4.0
|
||||
runTimeline.playFromStart()
|
||||
}
|
||||
|
||||
37
ide/src/main/kotlin/befide/ide/CodeLabel.kt
Normal file
37
ide/src/main/kotlin/befide/ide/CodeLabel.kt
Normal file
@@ -0,0 +1,37 @@
|
||||
package befide.ide
|
||||
|
||||
import befide.befunge.core.Interpreter
|
||||
import befide.befunge.state.Vec
|
||||
import javafx.beans.property.ObjectProperty
|
||||
import javafx.beans.property.SimpleObjectProperty
|
||||
import javafx.scene.control.Label
|
||||
import tornadofx.*
|
||||
|
||||
class CodeLabel(val pos: Vec, val cursorPos: ObjectProperty<Vec>, val interp: Interpreter) : Label() {
|
||||
val charProperty = SimpleObjectProperty<Char>('\u0000')
|
||||
var char: Char by charProperty
|
||||
|
||||
fun restyle() {
|
||||
styleClass.setAll("code")
|
||||
|
||||
if (char in "0123456789") styleClass.add("code-num")
|
||||
if (char in "gp") styleClass.add("code-funge")
|
||||
if (char in "<>^v?#") styleClass.add("code-dir")
|
||||
|
||||
if (pos == cursorPos.value) styleClass.add("code-cursor")
|
||||
if (pos == interp.ip.pos) styleClass.add("code-cursor-ip")
|
||||
if (char == '\u2022') styleClass.add("unknown")
|
||||
}
|
||||
|
||||
init {
|
||||
textProperty().bind(charProperty.stringBinding { it?.toString() ?: " " })
|
||||
|
||||
setOnMouseClicked {
|
||||
cursorPos.value = pos
|
||||
}
|
||||
|
||||
charProperty.addListener { _, _, _ -> restyle() }
|
||||
|
||||
char = ' '
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,131 @@
|
||||
package befide.ide
|
||||
|
||||
import befide.befunge.core.Interpreter
|
||||
import javafx.beans.property.SimpleStringProperty
|
||||
import befide.befunge.state.Vec
|
||||
import javafx.beans.property.ObjectProperty
|
||||
import javafx.beans.property.SimpleBooleanProperty
|
||||
import javafx.beans.property.SimpleObjectProperty
|
||||
import javafx.scene.input.KeyCode
|
||||
import tornadofx.*
|
||||
import tornadofx.getValue
|
||||
import tornadofx.setValue
|
||||
|
||||
operator fun <T> List<List<T>>.get(v: Vec): T = this[v.y][v.x]
|
||||
|
||||
class CodeView(val interp: Interpreter) : View() {
|
||||
val srcProperty = SimpleStringProperty("")
|
||||
var src by srcProperty
|
||||
val cursorPosProperty: ObjectProperty<Vec> = SimpleObjectProperty<Vec>(Vec(0, 0))
|
||||
var cursorPos by cursorPosProperty
|
||||
|
||||
val cursorDeltaProperty = SimpleObjectProperty<Vec>(Vec(1, 0))
|
||||
var cursorDelta by cursorDeltaProperty
|
||||
|
||||
val lockedProperty = SimpleBooleanProperty(false)
|
||||
var locked by lockedProperty
|
||||
|
||||
var labels: List<List<CodeLabel>> = List(25) { y -> List(80) { x -> CodeLabel(Vec(x, y), cursorPosProperty, interp) } }
|
||||
|
||||
init {
|
||||
interp.fungeChanged += { src = interp.funge.toString() }
|
||||
srcProperty.addListener { _, _, newValue -> interp.funge.setString(newValue) }
|
||||
cursorPosProperty.addListener { _, old, new ->
|
||||
labels[old].restyle()
|
||||
labels[new].restyle()
|
||||
}
|
||||
|
||||
interp.ipChanged += {
|
||||
labels[it.from.pos].restyle()
|
||||
labels[it.to.pos].restyle()
|
||||
}
|
||||
|
||||
interp.fungeChanged += {
|
||||
for (change in it.changes) {
|
||||
labels[change.vec].char = change.to.asChar ?: '\u2022'
|
||||
labels[change.vec].restyle()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override val root = textarea(srcProperty) {
|
||||
prefRowCount = 25
|
||||
prefColumnCount = 80
|
||||
fun move(delta: Vec? = null) {
|
||||
cursorPos = interp.funge.nextVec(cursorPos, delta ?: cursorDelta)
|
||||
}
|
||||
|
||||
var src: String
|
||||
get() = labels.joinToString("\n") { row ->
|
||||
row.dropLastWhile { lbl ->
|
||||
lbl.char.isWhitespace()
|
||||
}.joinToString("") { lbl ->
|
||||
lbl.char.toString()
|
||||
}
|
||||
}
|
||||
set(value) {
|
||||
val lines = value.lines()
|
||||
|
||||
for (row in labels) {
|
||||
for (lbl in row) {
|
||||
lbl.char = lines.getOrNull(lbl.pos.y)?.getOrNull(lbl.pos.x) ?: ' '
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override val root = hbox {
|
||||
isFocusTraversable = true
|
||||
|
||||
addClass("code-view")
|
||||
|
||||
vbox {
|
||||
children.setAll(labels.map { row -> hbox { children.setAll(row) } })
|
||||
}
|
||||
|
||||
setOnMouseClicked {
|
||||
requestFocus()
|
||||
}
|
||||
|
||||
setOnKeyPressed {
|
||||
when (it.code) {
|
||||
KeyCode.RIGHT -> move(Vec(1, 0))
|
||||
KeyCode.LEFT -> move(Vec(-1, 0))
|
||||
KeyCode.DOWN -> move(Vec(0, 1))
|
||||
KeyCode.UP -> move(Vec(0, -1))
|
||||
else -> return@setOnKeyPressed
|
||||
}
|
||||
if (it.isAltDown) when (it.code) {
|
||||
KeyCode.RIGHT -> cursorDelta = Vec(1, 0)
|
||||
KeyCode.LEFT -> cursorDelta = Vec(-1, 0)
|
||||
KeyCode.DOWN -> cursorDelta = Vec(0, 1)
|
||||
KeyCode.UP -> cursorDelta = Vec(0, -1)
|
||||
else -> Unit
|
||||
}
|
||||
it.consume()
|
||||
}
|
||||
|
||||
setOnKeyTyped {
|
||||
if (locked) return@setOnKeyTyped
|
||||
|
||||
for (ch in it.character) {
|
||||
when {
|
||||
!ch.isISOControl() -> {
|
||||
cursorDelta = when (ch) {
|
||||
'>' -> Vec(1, 0)
|
||||
'<' -> Vec(-1, 0)
|
||||
'v' -> Vec(0, 1)
|
||||
'^' -> Vec(0, -1)
|
||||
else -> cursorDelta
|
||||
}
|
||||
|
||||
labels[cursorPos].char = ch
|
||||
|
||||
move()
|
||||
}
|
||||
|
||||
ch == '\u0008' -> { // backspace
|
||||
move(-cursorDelta)
|
||||
|
||||
labels[cursorPos].char = ' '
|
||||
}
|
||||
|
||||
else -> {
|
||||
println("'$ch' (${ch.toInt()})")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,18 +10,14 @@ class EditorView : View("Befide") {
|
||||
private val codeView = CodeView(interp)
|
||||
private val stackView = StackView(interp)
|
||||
private val ioView = IOView(interp)
|
||||
private val actionView = ActionView(interp, ioView)
|
||||
private val actionView = ActionView(interp, codeView, ioView)
|
||||
|
||||
override val root = borderpane {
|
||||
top { add(actionView) }
|
||||
|
||||
center {
|
||||
add(codeView)
|
||||
}
|
||||
center { add(codeView) }
|
||||
|
||||
right {
|
||||
add(stackView)
|
||||
}
|
||||
right { add(stackView) }
|
||||
|
||||
bottom { add(ioView) }
|
||||
}
|
||||
@@ -31,31 +27,13 @@ class EditorView : View("Befide") {
|
||||
^ 0 v +1\ _^#-+*< >22g02g*"_@"*-!1- #v_v>
|
||||
>:>::3g: ,\188 ^^ -1\g21\g22<p3\"_":<
|
||||
________________________________@_________________________________^ p3\"@":<"""
|
||||
// codeView.src = """--------------------------------------------------------------------------------
|
||||
// |-
|
||||
// |-
|
||||
// |-
|
||||
// |-
|
||||
// |-
|
||||
// |-
|
||||
// |-
|
||||
// |-
|
||||
// |-
|
||||
// |-
|
||||
// |-
|
||||
// |-
|
||||
// |-
|
||||
// |-
|
||||
// |-
|
||||
// |-
|
||||
// |-
|
||||
// |-
|
||||
// |-
|
||||
// |-
|
||||
// |-
|
||||
// |-
|
||||
// |-
|
||||
// |-
|
||||
// """.trimMargin()
|
||||
|
||||
// codeView.src = """"hello world",,,,,,,,,,@"""
|
||||
}
|
||||
|
||||
override fun onDock() {
|
||||
super.onDock()
|
||||
|
||||
codeView.root.requestFocus()
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,45 @@
|
||||
-fx-font-fill: black;
|
||||
}
|
||||
|
||||
.text-area {
|
||||
-fx-font-family: monospace;
|
||||
.code, .text-area {
|
||||
-fx-font-family: Consolas, monospace;
|
||||
-fx-text-fill: black;
|
||||
}
|
||||
|
||||
.code-view, .text-area {
|
||||
-fx-border-color: #aaa;
|
||||
-fx-border-radius: 2px;
|
||||
-fx-border-width: 1px;
|
||||
-fx-background-color: #fff;
|
||||
-fx-graphic: none;
|
||||
}
|
||||
|
||||
.code-num {
|
||||
-fx-text-fill: #2d6a9c;
|
||||
}
|
||||
|
||||
.code-funge {
|
||||
-fx-text-fill: #258135;
|
||||
-fx-font-style: italic;
|
||||
-fx-font-weight: bold;
|
||||
}
|
||||
|
||||
.code-dir {
|
||||
-fx-text-fill: #b82893;
|
||||
}
|
||||
|
||||
.code-str {
|
||||
-fx-text-fill: #0a5158;
|
||||
}
|
||||
|
||||
.code-cursor-ip {
|
||||
-fx-background-color: rgba(39, 186, 235, 0.51);
|
||||
}
|
||||
|
||||
.code-unknown {
|
||||
-fx-background-color: rgba(216, 194, 155, 0.56);
|
||||
}
|
||||
|
||||
.code-cursor {
|
||||
-fx-background-color: rgba(0, 0, 0, 0.16);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user