[Editor] Enable defining Java code for objects in ObjectLayer

This commit is contained in:
2021-04-02 23:10:31 +02:00
parent abc8f9ba3d
commit aae41f3b4c
4 changed files with 204 additions and 4 deletions

View File

@@ -0,0 +1,38 @@
package com.bartlomiejpluta.base.editor.code.view.editor
import com.bartlomiejpluta.base.editor.code.viewmodel.CodeVM
import tornadofx.*
class CodeSnippetFragment : Fragment("Enter code") {
private val editor = find<CodeSnippetView>()
private val codeVM = find<CodeVM>()
private var onCompleteConsumer: ((String) -> Unit)? = null
fun onComplete(consumer: (String) -> Unit) {
this.onCompleteConsumer = consumer
}
override val root = borderpane {
setPrefSize(640.0, 480.0)
center = editor.root
bottom = buttonbar {
button("Apply") {
action {
onCompleteConsumer?.let { it(codeVM.code) }
editor.shutdown()
close()
}
}
button("Cancel") {
action {
editor.shutdown()
close()
}
}
}
}
}

View File

@@ -0,0 +1,73 @@
package com.bartlomiejpluta.base.editor.code.view.editor
import com.bartlomiejpluta.base.editor.code.component.CodeEditor
import com.bartlomiejpluta.base.editor.code.highlighting.JavaSyntaxHighlighter
import com.bartlomiejpluta.base.editor.code.highlighting.SqlSyntaxHighlighter
import com.bartlomiejpluta.base.editor.code.highlighting.XmlSyntaxHighlighter
import com.bartlomiejpluta.base.editor.code.model.CodeScope
import com.bartlomiejpluta.base.editor.code.model.CodeType
import com.bartlomiejpluta.base.editor.code.viewmodel.CodeVM
import com.bartlomiejpluta.base.editor.file.model.DummyFileNode
import com.bartlomiejpluta.base.editor.file.model.FileSystemNode
import com.bartlomiejpluta.base.editor.file.model.InMemoryStringFileNode
import com.bartlomiejpluta.base.editor.file.model.ScriptAssetFileNode
import javafx.beans.binding.Bindings
import org.kordamp.ikonli.javafx.FontIcon
import tornadofx.*
class CodeSnippetView : View() {
override val scope = super.scope as CodeScope
private val javaSyntaxHighlighter: JavaSyntaxHighlighter by di()
private val xmlSyntaxHighlighter: XmlSyntaxHighlighter by di()
private val sqlSyntaxHighlighter: SqlSyntaxHighlighter by di()
private val codeVM = find<CodeVM>()
private val highlighter = Bindings.createObjectBinding({
when (codeVM.type!!) {
CodeType.JAVA -> javaSyntaxHighlighter
CodeType.XML -> xmlSyntaxHighlighter
CodeType.SQL -> sqlSyntaxHighlighter
}
}, codeVM.typeProperty)
private val editable = Bindings.createBooleanBinding(
{ codeVM.fileNode is FileSystemNode || codeVM.fileNode is ScriptAssetFileNode || codeVM.fileNode is InMemoryStringFileNode || codeVM.fileNode is DummyFileNode },
codeVM.itemProperty
)
private val editor = CodeEditor(highlighter, codeVM.codeProperty, !editable.value)
init {
scope.caretDisplacementRequestListener = { line, column ->
editor.setCaretPosition(line, column)
}
}
fun shutdown() {
editor.shutdownHighlighterThread()
codeVM.fileNode
}
override val root = borderpane {
top = toolbar {
button(graphic = FontIcon("fa-undo")) {
enableWhen(editable)
action { undo() }
}
button(graphic = FontIcon("fa-repeat")) {
enableWhen(editable)
action { redo() }
}
}
center = editor
}
fun redo() = editor.redo()
fun undo() = editor.undo()
}

View File

@@ -0,0 +1,45 @@
package com.bartlomiejpluta.base.editor.file.model
import javafx.beans.value.ObservableLongValue
import javafx.beans.value.ObservableValue
class DummyFileNode : FileNode {
override val nameProperty: ObservableValue<String>
get() = throw UnsupportedOperationException()
override val name: String
get() = throw UnsupportedOperationException()
override val extensionProperty: ObservableValue<String>
get() = throw UnsupportedOperationException()
override val extension: String
get() = throw UnsupportedOperationException()
override val nameWithoutExtensionProperty: ObservableValue<String>
get() = throw UnsupportedOperationException()
override val nameWithoutExtension: String
get() = throw UnsupportedOperationException()
override val absolutePathProperty: ObservableValue<String>
get() = throw UnsupportedOperationException()
override val absolutePath: String
get() = throw UnsupportedOperationException()
override val type: FileType
get() = throw UnsupportedOperationException()
override val parent: FileNode
get() = throw UnsupportedOperationException()
override val children: Iterable<FileNode>
get() = throw UnsupportedOperationException()
override val lastModifiedProperty: ObservableLongValue
get() = throw UnsupportedOperationException()
override val lastModified: Long
get() = throw UnsupportedOperationException()
}

View File

@@ -1,5 +1,11 @@
package com.bartlomiejpluta.base.editor.map.canvas
import com.bartlomiejpluta.base.editor.code.model.Code
import com.bartlomiejpluta.base.editor.code.model.CodeScope
import com.bartlomiejpluta.base.editor.code.model.CodeType
import com.bartlomiejpluta.base.editor.code.view.editor.CodeSnippetFragment
import com.bartlomiejpluta.base.editor.code.viewmodel.CodeVM
import com.bartlomiejpluta.base.editor.file.model.DummyFileNode
import com.bartlomiejpluta.base.editor.map.model.brush.BrushMode
import com.bartlomiejpluta.base.editor.map.model.layer.ObjectLayer
import com.bartlomiejpluta.base.editor.map.model.obj.MapObject
@@ -9,6 +15,9 @@ import com.bartlomiejpluta.base.editor.map.viewmodel.GameMapVM
import com.bartlomiejpluta.base.editor.render.input.MapMouseEvent
import javafx.collections.ObservableList
import javafx.scene.input.MouseButton
import tornadofx.find
import tornadofx.setInScope
import tornadofx.toProperty
class ObjectPaintingTrace(val map: GameMapVM, override val commandName: String) : PaintingTrace {
private lateinit var objects: ObservableList<MapObject>
@@ -37,11 +46,46 @@ class ObjectPaintingTrace(val map: GameMapVM, override val commandName: String)
}
private fun createOrUpdateObject() {
newObject = MapObject(x, y, "")
showCodeDialog(formerObject?.code ?: initialCode)?.let {
newObject = MapObject(x, y, it)
objects.remove(formerObject)
objects.add(newObject)
executed = true
}
}
private fun showCodeDialog(initialContent: String): String? {
val scope = CodeScope(1, 1)
val code = Code(DummyFileNode(), CodeType.JAVA.toProperty(), initialContent)
val vm = CodeVM(code)
setInScope(vm, scope)
var content: String? = null
find<CodeSnippetFragment>(scope).apply {
title = "Define object"
onComplete {
content = it
}
openModal(block = true)
}
return content
}
private val initialCode: String
get() = """
// In this place you can implement some logic
// that will be evaluated for selected location.
// Following references are available:
// int x - the x coordinate
// int y - the y coordinate
// Runner runner - the game runner
// Context context - the game context
// Handler handler - current map handler
""".trimIndent()
private fun moveObject(newX: Int, newY: Int) {
if (newY >= map.rows || newX >= map.columns || newY < 0 || newX < 0) {