[Editor] Generalize Code model with CodeType enum
This commit is contained in:
@@ -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()
|
||||||
}
|
}
|
||||||
@@ -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",
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package com.bartlomiejpluta.base.editor.code.model
|
||||||
|
|
||||||
|
enum class CodeType {
|
||||||
|
JAVA
|
||||||
|
}
|
||||||
@@ -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()
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user