From 9096941d589ac5652c83e8faa7dce72dd0491ad4 Mon Sep 17 00:00:00 2001 From: Marvin Elsen Date: Thu, 14 Nov 2024 19:59:55 +0100 Subject: [PATCH] Implement TextFlowWithToneColors and use it in search results --- .../ui/cells/DictionaryEntryCellFactory.kt | 22 +++----- .../ui/components/TextFlowWithToneColors.kt | 55 +++++++++++++++++++ 2 files changed, 62 insertions(+), 15 deletions(-) create mode 100644 src/main/kotlin/com/marvinelsen/willow/ui/components/TextFlowWithToneColors.kt diff --git a/src/main/kotlin/com/marvinelsen/willow/ui/cells/DictionaryEntryCellFactory.kt b/src/main/kotlin/com/marvinelsen/willow/ui/cells/DictionaryEntryCellFactory.kt index 3ed6277..1085064 100644 --- a/src/main/kotlin/com/marvinelsen/willow/ui/cells/DictionaryEntryCellFactory.kt +++ b/src/main/kotlin/com/marvinelsen/willow/ui/cells/DictionaryEntryCellFactory.kt @@ -2,8 +2,8 @@ package com.marvinelsen.willow.ui.cells import com.marvinelsen.willow.config.Config import com.marvinelsen.willow.config.Pronunciation -import com.marvinelsen.willow.config.Script import com.marvinelsen.willow.domain.entities.DictionaryEntry +import com.marvinelsen.willow.ui.components.TextFlowWithToneColors import com.marvinelsen.willow.ui.util.createContextMenuForEntry import javafx.application.HostServices import javafx.beans.binding.Bindings @@ -39,8 +39,8 @@ private class EntryCell( private val hostServices: HostServices, ) : ListCell() { - private val labelHeadword by lazy { - Label().apply { + private val textFlowHeadword by lazy { + TextFlowWithToneColors(config).apply { styleClass.add("headword") styleProperty().bind( Bindings.concat( @@ -83,7 +83,7 @@ private class EntryCell( } private val flowPane by lazy { - FlowPane(labelHeadword, labelPronunciation).apply { + FlowPane(textFlowHeadword, labelPronunciation).apply { hgap = FLOW_PANE_HGAP rowValignment = VPos.BASELINE } @@ -105,17 +105,8 @@ private class EntryCell( graphic = null contextMenu = null } else { - labelHeadword.textProperty().bind( - Bindings.createStringBinding( - { - when (config.script.value!!) { - Script.SIMPLIFIED -> entry.simplified - Script.TRADITIONAL -> entry.traditional - } - }, - config.script - ) - ) + textFlowHeadword.entry.value = entry + labelPronunciation.textProperty().bind( Bindings.createStringBinding( { @@ -144,6 +135,7 @@ private class EntryCell( else -> error("No definition for entry") } + labelDefinition.text = definition contextMenu = createContextMenuForEntry(entry, resources, hostServices) diff --git a/src/main/kotlin/com/marvinelsen/willow/ui/components/TextFlowWithToneColors.kt b/src/main/kotlin/com/marvinelsen/willow/ui/components/TextFlowWithToneColors.kt new file mode 100644 index 0000000..2716bfb --- /dev/null +++ b/src/main/kotlin/com/marvinelsen/willow/ui/components/TextFlowWithToneColors.kt @@ -0,0 +1,55 @@ +package com.marvinelsen.willow.ui.components + +import com.marvinelsen.willow.config.Config +import com.marvinelsen.willow.config.Script +import com.marvinelsen.willow.domain.entities.DictionaryEntry +import javafx.beans.property.SimpleObjectProperty +import javafx.scene.paint.Color +import javafx.scene.text.Text +import javafx.scene.text.TextFlow + +class TextFlowWithToneColors(private val config: Config) : TextFlow() { + init { + config.script.addListener { _, _, newValue -> + updateTextFlow(newValue) + } + } + + val entry = SimpleObjectProperty().apply { + addListener { _, _, _ -> + updateTextFlow(config.script.value) + } + } + + private val invalidCharacterRegex = """[a-zA-Z0-9,.·\[\]{}()+]""".toRegex() + + @Suppress("MagicNumber") + private fun updateTextFlow(script: Script) { + children.clear() + + val headword = when (script) { + Script.SIMPLIFIED -> entry.value?.simplified + Script.TRADITIONAL -> entry.value?.traditional + } ?: return + + var index = 0 + for (char in headword) { + val text = Text(char.toString()) + + val color = if (invalidCharacterRegex.matches(char.toString())) { + Color.BLACK + } else { + when (entry.value?.tones?.getOrNull(index++)) { + 1 -> Color.RED + 2 -> Color.GREEN + 3 -> Color.BLUE + 4 -> Color.PURPLE + 5 -> Color.DARKGRAY + else -> Color.BLACK + } + } + text.fill = color + children.add(text) + } + } +}