[Editor] Generalize Code model with CodeType enum

This commit is contained in:
2021-02-23 09:04:57 +01:00
parent 5fec390ad8
commit f0ebb5d0b9
8 changed files with 41 additions and 12 deletions

View File

@@ -1,8 +1,8 @@
package com.bartlomiejpluta.base.editor.code.component package com.bartlomiejpluta.base.editor.code.component
import com.bartlomiejpluta.base.editor.code.highlighting.JavaSyntaxHighlighter import com.bartlomiejpluta.base.editor.code.highlighting.SyntaxHighlighter
import com.bartlomiejpluta.base.editor.code.stylesheet.HighlightingStylesheet
import javafx.beans.property.Property import javafx.beans.property.Property
import javafx.beans.value.ObservableValue
import javafx.concurrent.Task import javafx.concurrent.Task
import javafx.scene.layout.StackPane import javafx.scene.layout.StackPane
import org.fxmisc.flowless.VirtualizedScrollPane import org.fxmisc.flowless.VirtualizedScrollPane
@@ -14,17 +14,17 @@ import java.util.*
import java.util.concurrent.Executors import java.util.concurrent.Executors
class CodeEditor(val codeProperty: Property<String>) : StackPane() { class CodeEditor(private val highlighter: ObservableValue<out SyntaxHighlighter>, codeProperty: Property<String>) :
StackPane() {
private val editor = CodeArea() private val editor = CodeArea()
private val executor = Executors.newSingleThreadExecutor() private val executor = Executors.newSingleThreadExecutor()
private val cleanupWhenDone = editor.multiPlainChanges() private val cleanupWhenDone = editor.multiPlainChanges()
private val highlighting = JavaSyntaxHighlighter()
init { init {
editor.paragraphGraphicFactory = LineNumberFactory.get(editor)
editor.replaceText(0, 0, codeProperty.value) editor.replaceText(0, 0, codeProperty.value)
applyHighlighting(highlighting.highlight(editor.text)) codeProperty.bind(editor.textProperty())
editor.paragraphGraphicFactory = LineNumberFactory.get(editor)
applyHighlighting(highlighter.value.highlight(editor.text))
cleanupWhenDone cleanupWhenDone
.successionEnds(Duration.ofMillis(500)) .successionEnds(Duration.ofMillis(500))
@@ -46,7 +46,7 @@ class CodeEditor(val codeProperty: Property<String>) : StackPane() {
val code = editor.text val code = editor.text
val task = object : Task<StyleSpans<Collection<String>>>() { val task = object : Task<StyleSpans<Collection<String>>>() {
override fun call() = highlighting.highlight(code) override fun call() = highlighter.value.highlight(code)
} }
executor.execute(task) executor.execute(task)
@@ -57,5 +57,5 @@ class CodeEditor(val codeProperty: Property<String>) : StackPane() {
editor.setStyleSpans(0, highlighting) editor.setStyleSpans(0, highlighting)
} }
override fun getUserAgentStylesheet() = HighlightingStylesheet().base64URL.toExternalForm() override fun getUserAgentStylesheet(): String = highlighter.value.stylesheet.base64URL.toExternalForm()
} }

View File

@@ -1,8 +1,11 @@
package com.bartlomiejpluta.base.editor.code.highlighting package com.bartlomiejpluta.base.editor.code.highlighting
import com.bartlomiejpluta.base.editor.code.stylesheet.JavaSyntaxHighlightingStylesheet
import org.fxmisc.richtext.model.StyleSpans import org.fxmisc.richtext.model.StyleSpans
import org.fxmisc.richtext.model.StyleSpansBuilder import org.fxmisc.richtext.model.StyleSpansBuilder
import org.springframework.stereotype.Component
@Component
class JavaSyntaxHighlighter : SyntaxHighlighter { class JavaSyntaxHighlighter : SyntaxHighlighter {
override fun highlight(code: String): StyleSpans<Collection<String>> = StyleSpansBuilder<Collection<String>>().let { override fun highlight(code: String): StyleSpans<Collection<String>> = StyleSpansBuilder<Collection<String>>().let {
val lastKeywordEnd = PATTERN.findAll(code).fold(0) { lastKeywordEnd, result -> val lastKeywordEnd = PATTERN.findAll(code).fold(0) { lastKeywordEnd, result ->
@@ -28,6 +31,8 @@ class JavaSyntaxHighlighter : SyntaxHighlighter {
it.create() it.create()
} }
override val stylesheet = JavaSyntaxHighlightingStylesheet()
companion object { companion object {
private val KEYWORDS = arrayOf( private val KEYWORDS = arrayOf(
"abstract", "assert", "boolean", "break", "byte", "abstract", "assert", "boolean", "break", "byte",

View File

@@ -1,7 +1,9 @@
package com.bartlomiejpluta.base.editor.code.highlighting package com.bartlomiejpluta.base.editor.code.highlighting
import org.fxmisc.richtext.model.StyleSpans import org.fxmisc.richtext.model.StyleSpans
import tornadofx.Stylesheet
interface SyntaxHighlighter { interface SyntaxHighlighter {
fun highlight(code: String): StyleSpans<Collection<String>> fun highlight(code: String): StyleSpans<Collection<String>>
val stylesheet: Stylesheet
} }

View File

@@ -4,7 +4,10 @@ import tornadofx.getValue
import tornadofx.setValue import tornadofx.setValue
import tornadofx.toProperty import tornadofx.toProperty
class Code(code: String) { class Code(codeType: CodeType, code: String) {
val typeProperty = codeType.toProperty()
var type by typeProperty
val codeProperty = code.toProperty() val codeProperty = code.toProperty()
var code by codeProperty var code by codeProperty
} }

View File

@@ -0,0 +1,5 @@
package com.bartlomiejpluta.base.editor.code.model
enum class CodeType {
JAVA
}

View File

@@ -3,7 +3,7 @@ package com.bartlomiejpluta.base.editor.code.stylesheet
import javafx.scene.text.FontWeight import javafx.scene.text.FontWeight
import tornadofx.* import tornadofx.*
class HighlightingStylesheet : Stylesheet() { class JavaSyntaxHighlightingStylesheet : Stylesheet() {
companion object { companion object {
val keyword by cssclass() val keyword by cssclass()
val semicolon by cssclass() val semicolon by cssclass()

View File

@@ -1,13 +1,24 @@
package com.bartlomiejpluta.base.editor.code.view package com.bartlomiejpluta.base.editor.code.view
import com.bartlomiejpluta.base.editor.code.component.CodeEditor import com.bartlomiejpluta.base.editor.code.component.CodeEditor
import com.bartlomiejpluta.base.editor.code.highlighting.JavaSyntaxHighlighter
import com.bartlomiejpluta.base.editor.code.model.CodeType
import com.bartlomiejpluta.base.editor.code.viewmodel.CodeVM import com.bartlomiejpluta.base.editor.code.viewmodel.CodeVM
import javafx.beans.binding.Bindings
import tornadofx.View import tornadofx.View
import tornadofx.borderpane import tornadofx.borderpane
class CodeEditorView : View() { class CodeEditorView : View() {
private val javaSyntaxHighlighter: JavaSyntaxHighlighter by di()
private val codeVM = find<CodeVM>() private val codeVM = find<CodeVM>()
private val editor = CodeEditor(codeVM.codeProperty)
private val highlighter = Bindings.createObjectBinding({
when (codeVM.type!!) {
CodeType.JAVA -> javaSyntaxHighlighter
}
}, codeVM.typeProperty)
private val editor = CodeEditor(highlighter, codeVM.codeProperty)
override val root = borderpane { override val root = borderpane {
center = editor center = editor

View File

@@ -6,6 +6,9 @@ import tornadofx.getValue
import tornadofx.setValue import tornadofx.setValue
class CodeVM(code: Code) : ItemViewModel<Code>(code) { class CodeVM(code: Code) : ItemViewModel<Code>(code) {
val typeProperty = bind(Code::typeProperty)
var type by typeProperty
val codeProperty = bind(Code::codeProperty) val codeProperty = bind(Code::codeProperty)
var code by codeProperty var code by codeProperty
} }