diff --git a/src/main/kotlin/com/marvinelsen/willow/Interactor.kt b/src/main/kotlin/com/marvinelsen/willow/Interactor.kt new file mode 100644 index 0000000..77a7ef3 --- /dev/null +++ b/src/main/kotlin/com/marvinelsen/willow/Interactor.kt @@ -0,0 +1,127 @@ +package com.marvinelsen.willow + +import com.marvinelsen.willow.domain.SearchMode +import com.marvinelsen.willow.domain.SqliteDictionary +import com.marvinelsen.willow.domain.objects.DictionaryEntry +import com.marvinelsen.willow.ui.undo.Command +import com.marvinelsen.willow.ui.util.ClipboardHelper +import kotlinx.coroutines.MainScope +import kotlinx.coroutines.launch + +@Suppress("TooManyFunctions") +class Interactor( + private val model: Model, + private val dictionary: SqliteDictionary, +) { + private val coroutineScope = MainScope() + + fun copyHeadwordOfSelectedEntry() { + model.selectedEntry?.let { ClipboardHelper.copyString(it.traditional) } + } + + fun copyPronunciationOfSelectedEntry() { + model.selectedEntry?.let { ClipboardHelper.copyString(it.pinyinWithToneMarks) } + } + + fun undoSelection() { + model.undoManager.undo() + } + + fun redoSelection() { + model.undoManager.redo() + } + + fun search(query: String, searchMode: SearchMode) { + coroutineScope.launch { + model.isSearching = true + model.searchResults.setAll(dictionary.search(query, searchMode)) + model.isSearching = false + } + } + + fun findWordsBeginning() { + coroutineScope.launch { + model.isFindingWordsBeginning = true + model.wordsBeginning.setAll( + model.selectedEntry?.let { + dictionary + .findWordsBeginningWith(it) + } + ) + model.isFindingWordsBeginning = false + model.finishedFindingWordsBeginning = true + } + } + + fun findWordsContaining() { + coroutineScope.launch { + model.isFindingWordsContaining = true + model.wordsContaining.setAll( + model.selectedEntry?.let { + dictionary + .findWordsContaining(it) + } + ) + model.isFindingWordsContaining = false + model.finishedFindingWordsContaining = true + } + } + + fun findCharacters() { + coroutineScope.launch { + model.isFindingCharacters = true + model.characters.setAll( + model.selectedEntry?.let { + dictionary + .findCharactersOf(it) + } + ) + model.isFindingCharacters = false + model.finishedFindingCharacters = true + } + } + + fun findSentences() { + coroutineScope.launch { + model.isFindingSentences = true + model.sentences.setAll( + model.selectedEntry?.let { + dictionary + .findExampleSentencesFor(it) + } + ) + model.isFindingSentences = false + model.finishedFindingSentences = true + } + } + + fun deepDive(entry: DictionaryEntry) { + model.undoManager.execute(object : Command { + private val previouslySelectedEntry = model.selectedEntry + + override fun execute() { + select(entry) + } + + override fun undo() { + if (previouslySelectedEntry == null) return + + select(previouslySelectedEntry) + } + }) + } + + fun normalSelect(entry: DictionaryEntry) { + model.undoManager.reset() + select(entry) + } + + private fun select(entry: DictionaryEntry) { + model.finishedFindingCharacters = false + model.finishedFindingWordsBeginning = false + model.finishedFindingWordsContaining = false + model.finishedFindingSentences = false + + model.selectedEntry = entry + } +} diff --git a/src/main/kotlin/com/marvinelsen/willow/Model.kt b/src/main/kotlin/com/marvinelsen/willow/Model.kt new file mode 100644 index 0000000..576293c --- /dev/null +++ b/src/main/kotlin/com/marvinelsen/willow/Model.kt @@ -0,0 +1,110 @@ +package com.marvinelsen.willow + +import com.marvinelsen.willow.domain.objects.DictionaryEntry +import com.marvinelsen.willow.domain.objects.Sentence +import com.marvinelsen.willow.ui.undo.UndoManager +import javafx.beans.property.BooleanProperty +import javafx.beans.property.ObjectProperty +import javafx.beans.property.ReadOnlyBooleanProperty +import javafx.beans.property.SimpleBooleanProperty +import javafx.beans.property.SimpleObjectProperty +import javafx.collections.FXCollections +import javafx.collections.ObservableList + +@Suppress("TooManyFunctions") +class Model( + val undoManager: UndoManager, +) { + private val _selectedEntry: ObjectProperty = SimpleObjectProperty() + + private val _isSearching: BooleanProperty = SimpleBooleanProperty(false) + private val _isFindingWordsBeginning: BooleanProperty = SimpleBooleanProperty(false) + private val _isFindingWordsContaining: BooleanProperty = SimpleBooleanProperty(false) + private val _isFindingCharacters: BooleanProperty = SimpleBooleanProperty(false) + private val _isFindingSentences: BooleanProperty = SimpleBooleanProperty(false) + + private val _finishedFindingWordsBeginning: BooleanProperty = SimpleBooleanProperty(false) + private val _finishedFindingWordsContaining: BooleanProperty = SimpleBooleanProperty(false) + private val _finishedFindingCharacters: BooleanProperty = SimpleBooleanProperty(false) + private val _finishedFindingSentences: BooleanProperty = SimpleBooleanProperty(false) + + val searchResults: ObservableList = FXCollections.observableArrayList() + val wordsBeginning: ObservableList = FXCollections.observableArrayList() + val wordsContaining: ObservableList = FXCollections.observableArrayList() + val characters: ObservableList = FXCollections.observableArrayList() + val sentences: ObservableList = FXCollections.observableArrayList() + + val canUndo: ReadOnlyBooleanProperty = undoManager.canUndoProperty + val canRedo: ReadOnlyBooleanProperty = undoManager.canRedoProperty + + var selectedEntry: DictionaryEntry? + get() = _selectedEntry.value + set(value) { + _selectedEntry.value = value + } + + var isSearching: Boolean + get() = _isSearching.value + set(value) { + _isSearching.value = value + } + + var isFindingWordsBeginning: Boolean + get() = _isFindingWordsBeginning.value + set(value) { + _isFindingWordsBeginning.value = value + } + + var isFindingWordsContaining: Boolean + get() = _isFindingWordsContaining.value + set(value) { + _isFindingWordsContaining.value = value + } + + var isFindingCharacters: Boolean + get() = _isFindingCharacters.value + set(value) { + _isFindingCharacters.value = value + } + + var isFindingSentences: Boolean + get() = _isFindingSentences.value + set(value) { + _isFindingSentences.value = value + } + + var finishedFindingWordsBeginning: Boolean + get() = _finishedFindingWordsBeginning.value + set(value) { + _finishedFindingWordsBeginning.value = value + } + + var finishedFindingWordsContaining: Boolean + get() = _finishedFindingWordsContaining.value + set(value) { + _finishedFindingWordsContaining.value = value + } + + var finishedFindingCharacters: Boolean + get() = _finishedFindingCharacters.value + set(value) { + _finishedFindingCharacters.value = value + } + + var finishedFindingSentences: Boolean + get() = _finishedFindingSentences.value + set(value) { + _finishedFindingSentences.value = value + } + + fun selectedEntryProperty(): ObjectProperty = _selectedEntry + fun isSearchingProperty(): BooleanProperty = _isSearching + fun isFindingWordsBeginningProperty(): BooleanProperty = _isFindingWordsBeginning + fun isFindingWordsContainingProperty(): BooleanProperty = _isFindingWordsContaining + fun isFindingCharactersProperty(): BooleanProperty = _isFindingCharacters + fun isFindingSentencesProperty(): BooleanProperty = _isFindingSentences + fun finishedFindingWordsBeginning(): BooleanProperty = _finishedFindingWordsBeginning + fun finishedFindingWordsContaining(): BooleanProperty = _finishedFindingWordsContaining + fun finishedFindingCharacters(): BooleanProperty = _finishedFindingCharacters + fun finishedFindingSentences(): BooleanProperty = _finishedFindingSentences +} diff --git a/src/main/kotlin/com/marvinelsen/willow/State.kt b/src/main/kotlin/com/marvinelsen/willow/State.kt deleted file mode 100644 index 5964d18..0000000 --- a/src/main/kotlin/com/marvinelsen/willow/State.kt +++ /dev/null @@ -1,174 +0,0 @@ -package com.marvinelsen.willow - -import com.marvinelsen.willow.domain.SearchMode -import com.marvinelsen.willow.domain.SqliteDictionary -import com.marvinelsen.willow.domain.entities.DictionaryEntry -import com.marvinelsen.willow.domain.entities.Sentence -import com.marvinelsen.willow.ui.undo.Command -import com.marvinelsen.willow.ui.undo.UndoManager -import com.marvinelsen.willow.ui.util.ClipboardHelper -import javafx.beans.property.BooleanProperty -import javafx.beans.property.ObjectProperty -import javafx.beans.property.ReadOnlyBooleanProperty -import javafx.beans.property.ReadOnlyObjectProperty -import javafx.beans.property.SimpleBooleanProperty -import javafx.beans.property.SimpleObjectProperty -import javafx.collections.FXCollections -import javafx.collections.ObservableList -import kotlinx.coroutines.MainScope -import kotlinx.coroutines.launch - -@Suppress("TooManyFunctions") -class State( - private val dictionary: SqliteDictionary, - private val undoManager: UndoManager, -) { - private val internalSelectedEntry: ObjectProperty = SimpleObjectProperty() - private val internalSearchResults: ObservableList = FXCollections.observableArrayList() - private val internalWordsBeginning: ObservableList = FXCollections.observableArrayList() - private val internalWordsContaining: ObservableList = FXCollections.observableArrayList() - private val internalCharacters: ObservableList = FXCollections.observableArrayList() - private val internalSentences: ObservableList = FXCollections.observableArrayList() - - private val internalIsSearching: BooleanProperty = SimpleBooleanProperty(false) - private val internalIsFindingWordsBeginning: BooleanProperty = SimpleBooleanProperty(false) - private val internalIsFindingWordsContaining: BooleanProperty = SimpleBooleanProperty(false) - private val internalIsFindingCharacters: BooleanProperty = SimpleBooleanProperty(false) - private val internalIsFindingSentences: BooleanProperty = SimpleBooleanProperty(false) - - private val internalFinishedFindingWordsBeginning: BooleanProperty = SimpleBooleanProperty(false) - private val internalFinishedFindingWordsContaining: BooleanProperty = SimpleBooleanProperty(false) - private val internalFinishedFindingCharacters: BooleanProperty = SimpleBooleanProperty(false) - private val internalFinishedFindingSentences: BooleanProperty = SimpleBooleanProperty(false) - - val canUndo: ReadOnlyBooleanProperty = undoManager.canUndoProperty - val canRedo: ReadOnlyBooleanProperty = undoManager.canRedoProperty - - val selectedEntry: ReadOnlyObjectProperty = internalSelectedEntry - - val searchResults: ObservableList = - FXCollections.unmodifiableObservableList(internalSearchResults) - val wordsBeginning: ObservableList = - FXCollections.unmodifiableObservableList(internalWordsBeginning) - val wordsContaining: ObservableList = - FXCollections.unmodifiableObservableList(internalWordsContaining) - val characters: ObservableList = - FXCollections.unmodifiableObservableList(internalCharacters) - val sentences: ObservableList = - FXCollections.unmodifiableObservableList(internalSentences) - - val isSearching: ReadOnlyBooleanProperty = internalIsSearching - val isFindingWordsBeginning: ReadOnlyBooleanProperty = internalIsFindingWordsBeginning - val isFindingWordsContaining: ReadOnlyBooleanProperty = internalIsFindingWordsContaining - val isFindingCharacters: ReadOnlyBooleanProperty = internalIsFindingCharacters - val isFindingSentences: ReadOnlyBooleanProperty = internalIsFindingSentences - - val finishedFindingWordsBeginning: ReadOnlyBooleanProperty = internalFinishedFindingWordsBeginning - val finishedFindingWordsContaining: ReadOnlyBooleanProperty = internalFinishedFindingWordsContaining - val finishedFindingCharacters: ReadOnlyBooleanProperty = internalFinishedFindingCharacters - val finishedFindingSentences: ReadOnlyBooleanProperty = internalFinishedFindingSentences - - private val coroutineScope = MainScope() - - fun copyHeadwordOfSelectedEntry() { - ClipboardHelper.copyString(internalSelectedEntry.value.traditional) - } - - fun copyPronunciationOfSelectedEntry() { - ClipboardHelper.copyString(internalSelectedEntry.value.pinyinWithToneMarks) - } - - fun undoSelection() { - undoManager.undo() - } - - fun redoSelection() { - undoManager.redo() - } - - fun search(query: String, searchMode: SearchMode) { - coroutineScope.launch { - internalIsSearching.value = true - internalSearchResults.setAll(dictionary.search(query, searchMode)) - internalIsSearching.value = false - } - } - - fun findWordsBeginning() { - coroutineScope.launch { - internalIsFindingWordsBeginning.value = true - internalWordsBeginning.setAll( - dictionary - .findWordsBeginningWith(internalSelectedEntry.value) - ) - internalIsFindingWordsBeginning.value = false - internalFinishedFindingWordsBeginning.value = true - } - } - - fun findWordsContaining() { - coroutineScope.launch { - internalIsFindingWordsContaining.value = true - internalWordsContaining.setAll( - dictionary - .findWordsContaining(internalSelectedEntry.value) - ) - internalIsFindingWordsContaining.value = false - internalFinishedFindingWordsContaining.value = true - } - } - - fun findCharacters() { - coroutineScope.launch { - internalIsFindingCharacters.value = true - internalCharacters.setAll( - dictionary - .findCharactersOf(internalSelectedEntry.value) - ) - internalIsFindingCharacters.value = false - internalFinishedFindingCharacters.value = true - } - } - - fun findSentences() { - coroutineScope.launch { - internalIsFindingSentences.value = true - internalSentences.setAll( - dictionary - .findExampleSentencesFor(internalSelectedEntry.value) - ) - internalIsFindingSentences.value = false - internalFinishedFindingSentences.value = true - } - } - - fun deepDive(entry: DictionaryEntry) { - undoManager.execute(object : Command { - private val previouslySelectedEntry = internalSelectedEntry.value - - override fun execute() { - select(entry) - } - - override fun undo() { - if (previouslySelectedEntry == null) return - - select(previouslySelectedEntry) - } - }) - } - - fun normalSelect(entry: DictionaryEntry) { - undoManager.reset() - select(entry) - } - - private fun select(entry: DictionaryEntry) { - internalFinishedFindingCharacters.value = false - internalFinishedFindingWordsBeginning.value = false - internalFinishedFindingWordsContaining.value = false - internalFinishedFindingSentences.value = false - - internalSelectedEntry.value = entry - } -} diff --git a/src/main/kotlin/com/marvinelsen/willow/WillowApplication.kt b/src/main/kotlin/com/marvinelsen/willow/WillowApplication.kt index 8880d57..93650e7 100644 --- a/src/main/kotlin/com/marvinelsen/willow/WillowApplication.kt +++ b/src/main/kotlin/com/marvinelsen/willow/WillowApplication.kt @@ -43,10 +43,8 @@ class WillowApplication : Application() { } val dictionary = SqliteDictionary(connection) val undoManager = UndoManager() - val state = State( - dictionary, - undoManager - ) + val model = Model(undoManager) + val interactor = Interactor(model, dictionary) val config = Config() config.load() @@ -56,11 +54,11 @@ class WillowApplication : Application() { fxmlLoader.resources = ResourceBundle.getBundle("i18n/willow", config.locale.value) fxmlLoader.controllerFactory = Callback { type -> when (type) { - MainController::class.java -> MainController(state) - MenuController::class.java -> MenuController(state, config) - DetailsController::class.java -> DetailsController(state, config, hostServices) - SearchController::class.java -> SearchController(state) - SearchResultsController::class.java -> SearchResultsController(state, config, hostServices) + MainController::class.java -> MainController(model) + MenuController::class.java -> MenuController(model, interactor, config) + DetailsController::class.java -> DetailsController(model, interactor, config, hostServices) + SearchController::class.java -> SearchController(model, interactor) + SearchResultsController::class.java -> SearchResultsController(model, interactor, config, hostServices) else -> error("Trying to instantiate unknown controller type $type") } } diff --git a/src/main/kotlin/com/marvinelsen/willow/domain/Dictionary.kt b/src/main/kotlin/com/marvinelsen/willow/domain/Dictionary.kt index 1ab4da1..7ace957 100644 --- a/src/main/kotlin/com/marvinelsen/willow/domain/Dictionary.kt +++ b/src/main/kotlin/com/marvinelsen/willow/domain/Dictionary.kt @@ -1,7 +1,7 @@ package com.marvinelsen.willow.domain -import com.marvinelsen.willow.domain.entities.DictionaryEntry -import com.marvinelsen.willow.domain.entities.Sentence +import com.marvinelsen.willow.domain.objects.DictionaryEntry +import com.marvinelsen.willow.domain.objects.Sentence interface Dictionary { suspend fun search(query: String, searchMode: SearchMode): List diff --git a/src/main/kotlin/com/marvinelsen/willow/domain/SqliteDictionary.kt b/src/main/kotlin/com/marvinelsen/willow/domain/SqliteDictionary.kt index c8d7b2f..e866945 100644 --- a/src/main/kotlin/com/marvinelsen/willow/domain/SqliteDictionary.kt +++ b/src/main/kotlin/com/marvinelsen/willow/domain/SqliteDictionary.kt @@ -8,8 +8,8 @@ import com.github.houbb.segment.support.segment.impl.Segments import com.github.houbb.segment.support.segment.mode.impl.SegmentModes import com.github.houbb.segment.support.segment.result.impl.SegmentResultHandlers import com.github.houbb.segment.support.tagging.pos.tag.impl.SegmentPosTaggings -import com.marvinelsen.willow.domain.entities.DictionaryEntry -import com.marvinelsen.willow.domain.entities.Sentence +import com.marvinelsen.willow.domain.objects.DictionaryEntry +import com.marvinelsen.willow.domain.objects.Sentence import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import kotlinx.serialization.json.Json diff --git a/src/main/kotlin/com/marvinelsen/willow/domain/entities/DictionaryEntry.kt b/src/main/kotlin/com/marvinelsen/willow/domain/objects/DictionaryEntry.kt similarity index 64% rename from src/main/kotlin/com/marvinelsen/willow/domain/entities/DictionaryEntry.kt rename to src/main/kotlin/com/marvinelsen/willow/domain/objects/DictionaryEntry.kt index 2d3619a..765cf6b 100644 --- a/src/main/kotlin/com/marvinelsen/willow/domain/entities/DictionaryEntry.kt +++ b/src/main/kotlin/com/marvinelsen/willow/domain/objects/DictionaryEntry.kt @@ -1,7 +1,7 @@ -package com.marvinelsen.willow.domain.entities +package com.marvinelsen.willow.domain.objects -import com.marvinelsen.willow.domain.entities.definitions.CrossStraitsDefinition -import com.marvinelsen.willow.domain.entities.definitions.MoedictDefinition +import com.marvinelsen.willow.domain.objects.definitions.CrossStraitsDefinition +import com.marvinelsen.willow.domain.objects.definitions.MoedictDefinition data class DictionaryEntry( val traditional: String, diff --git a/src/main/kotlin/com/marvinelsen/willow/domain/entities/Sentence.kt b/src/main/kotlin/com/marvinelsen/willow/domain/objects/Sentence.kt similarity index 63% rename from src/main/kotlin/com/marvinelsen/willow/domain/entities/Sentence.kt rename to src/main/kotlin/com/marvinelsen/willow/domain/objects/Sentence.kt index 232465e..bac01ab 100644 --- a/src/main/kotlin/com/marvinelsen/willow/domain/entities/Sentence.kt +++ b/src/main/kotlin/com/marvinelsen/willow/domain/objects/Sentence.kt @@ -1,4 +1,4 @@ -package com.marvinelsen.willow.domain.entities +package com.marvinelsen.willow.domain.objects data class Sentence( val traditional: String, diff --git a/src/main/kotlin/com/marvinelsen/willow/domain/entities/definitions/CrossStraitsDefinition.kt b/src/main/kotlin/com/marvinelsen/willow/domain/objects/definitions/CrossStraitsDefinition.kt similarity index 72% rename from src/main/kotlin/com/marvinelsen/willow/domain/entities/definitions/CrossStraitsDefinition.kt rename to src/main/kotlin/com/marvinelsen/willow/domain/objects/definitions/CrossStraitsDefinition.kt index ea7fa79..22e4bef 100644 --- a/src/main/kotlin/com/marvinelsen/willow/domain/entities/definitions/CrossStraitsDefinition.kt +++ b/src/main/kotlin/com/marvinelsen/willow/domain/objects/definitions/CrossStraitsDefinition.kt @@ -1,4 +1,4 @@ -package com.marvinelsen.willow.domain.entities.definitions +package com.marvinelsen.willow.domain.objects.definitions import kotlinx.serialization.Serializable diff --git a/src/main/kotlin/com/marvinelsen/willow/domain/entities/definitions/MoedictDefinition.kt b/src/main/kotlin/com/marvinelsen/willow/domain/objects/definitions/MoedictDefinition.kt similarity index 88% rename from src/main/kotlin/com/marvinelsen/willow/domain/entities/definitions/MoedictDefinition.kt rename to src/main/kotlin/com/marvinelsen/willow/domain/objects/definitions/MoedictDefinition.kt index e1fee97..869c4ab 100644 --- a/src/main/kotlin/com/marvinelsen/willow/domain/entities/definitions/MoedictDefinition.kt +++ b/src/main/kotlin/com/marvinelsen/willow/domain/objects/definitions/MoedictDefinition.kt @@ -1,4 +1,4 @@ -package com.marvinelsen.willow.domain.entities.definitions +package com.marvinelsen.willow.domain.objects.definitions import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable 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 1085064..82ee240 100644 --- a/src/main/kotlin/com/marvinelsen/willow/ui/cells/DictionaryEntryCellFactory.kt +++ b/src/main/kotlin/com/marvinelsen/willow/ui/cells/DictionaryEntryCellFactory.kt @@ -2,7 +2,7 @@ package com.marvinelsen.willow.ui.cells import com.marvinelsen.willow.config.Config import com.marvinelsen.willow.config.Pronunciation -import com.marvinelsen.willow.domain.entities.DictionaryEntry +import com.marvinelsen.willow.domain.objects.DictionaryEntry import com.marvinelsen.willow.ui.components.TextFlowWithToneColors import com.marvinelsen.willow.ui.util.createContextMenuForEntry import javafx.application.HostServices diff --git a/src/main/kotlin/com/marvinelsen/willow/ui/cells/SentenceCellFactory.kt b/src/main/kotlin/com/marvinelsen/willow/ui/cells/SentenceCellFactory.kt index c6e0d24..7a76b3e 100644 --- a/src/main/kotlin/com/marvinelsen/willow/ui/cells/SentenceCellFactory.kt +++ b/src/main/kotlin/com/marvinelsen/willow/ui/cells/SentenceCellFactory.kt @@ -2,7 +2,7 @@ package com.marvinelsen.willow.ui.cells import com.marvinelsen.willow.config.Config import com.marvinelsen.willow.config.Script -import com.marvinelsen.willow.domain.entities.Sentence +import com.marvinelsen.willow.domain.objects.Sentence import com.marvinelsen.willow.ui.util.createContextMenuForSentence import javafx.application.HostServices import javafx.beans.binding.Bindings diff --git a/src/main/kotlin/com/marvinelsen/willow/ui/components/TextFlowWithToneColors.kt b/src/main/kotlin/com/marvinelsen/willow/ui/components/TextFlowWithToneColors.kt index 2716bfb..7ea3b4b 100644 --- a/src/main/kotlin/com/marvinelsen/willow/ui/components/TextFlowWithToneColors.kt +++ b/src/main/kotlin/com/marvinelsen/willow/ui/components/TextFlowWithToneColors.kt @@ -2,7 +2,7 @@ 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 com.marvinelsen.willow.domain.objects.DictionaryEntry import javafx.beans.property.SimpleObjectProperty import javafx.scene.paint.Color import javafx.scene.text.Text diff --git a/src/main/kotlin/com/marvinelsen/willow/ui/controllers/DetailsController.kt b/src/main/kotlin/com/marvinelsen/willow/ui/controllers/DetailsController.kt index 49c1730..f64a2da 100644 --- a/src/main/kotlin/com/marvinelsen/willow/ui/controllers/DetailsController.kt +++ b/src/main/kotlin/com/marvinelsen/willow/ui/controllers/DetailsController.kt @@ -1,11 +1,12 @@ package com.marvinelsen.willow.ui.controllers -import com.marvinelsen.willow.State +import com.marvinelsen.willow.Interactor +import com.marvinelsen.willow.Model 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.domain.entities.Sentence +import com.marvinelsen.willow.domain.objects.DictionaryEntry +import com.marvinelsen.willow.domain.objects.Sentence import com.marvinelsen.willow.ui.cells.DictionaryEntryCellFactory import com.marvinelsen.willow.ui.cells.SentenceCellFactory import com.marvinelsen.willow.ui.util.createContextMenuForEntry @@ -33,7 +34,8 @@ import java.util.ResourceBundle @Suppress("UnusedPrivateMember", "TooManyFunctions") class DetailsController( - private val state: State, + private val model: Model, + private val interactor: Interactor, private val config: Config, private val hostServices: HostServices, ) { @@ -112,14 +114,13 @@ class DetailsController( textProperty().bind( Bindings.createStringBinding( { - val selectedEntry = state.selectedEntry.value when (config.script.value!!) { - Script.SIMPLIFIED -> selectedEntry?.simplified - Script.TRADITIONAL -> selectedEntry?.traditional + Script.SIMPLIFIED -> model.selectedEntry?.simplified + Script.TRADITIONAL -> model.selectedEntry?.traditional } }, config.script, - state.selectedEntry + model.selectedEntryProperty() ) ) styleProperty().bind( @@ -137,15 +138,14 @@ class DetailsController( textProperty().bind( Bindings.createStringBinding( { - val selectedEntry = state.selectedEntry.value when (config.details.pronunciation.value!!) { - Pronunciation.PINYIN_WITH_TONE_MARKS -> selectedEntry?.pinyinWithToneMarks - Pronunciation.PINYIN_WITH_TONE_NUMBERS -> selectedEntry?.pinyinWithToneNumbers - Pronunciation.ZHUYIN -> selectedEntry?.zhuyin + Pronunciation.PINYIN_WITH_TONE_MARKS -> model.selectedEntry?.pinyinWithToneMarks + Pronunciation.PINYIN_WITH_TONE_NUMBERS -> model.selectedEntry?.pinyinWithToneNumbers + Pronunciation.ZHUYIN -> model.selectedEntry?.zhuyin } }, config.details.pronunciation, - state.selectedEntry + model.selectedEntryProperty() ) ) styleProperty().bind( @@ -160,16 +160,16 @@ class DetailsController( private fun initializeTabPaneDetails() { tabPaneDetails.apply { - disableProperty().bind(Bindings.isNull(state.selectedEntry)) + disableProperty().bind(Bindings.isNull(model.selectedEntryProperty())) selectionModel.selectedItemProperty().addListener { _, _, selectedTab -> - if (state.selectedEntry.value == null) return@addListener + if (model.selectedEntry == null) return@addListener lazyUpdateTabContent(selectedTab.id) } } - state.selectedEntry.addListener { _, _, newEntry -> + model.selectedEntryProperty().addListener { _, _, newEntry -> if (newEntry == null) return@addListener tabPaneDetails.selectionModel.select(0) @@ -178,9 +178,9 @@ class DetailsController( tabCharacters.disableProperty().bind( Bindings.createBooleanBinding( { - (state.selectedEntry.value?.traditional?.length ?: 0) < 2 + (model.selectedEntry?.traditional?.length ?: 0) < 2 }, - state.selectedEntry + model.selectedEntryProperty() ) ) } @@ -188,68 +188,82 @@ class DetailsController( private fun initializeListViewSentences() { listViewSentences.apply { cellFactory = SentenceCellFactory(resources, config, hostServices) - items = state.sentences + items = model.sentences - disableProperty().bind(Bindings.or(state.isFindingSentences, Bindings.isEmpty(state.sentences))) + disableProperty().bind(Bindings.or(model.isFindingSentencesProperty(), Bindings.isEmpty(model.sentences))) } - progressIndicatorSentences.visibleProperty().bind(state.isFindingSentences) + progressIndicatorSentences.visibleProperty().bind(model.isFindingSentencesProperty()) labelNoSentencesFound .visibleProperty() - .bind(Bindings.and(Bindings.isEmpty(state.sentences), Bindings.not(state.isFindingSentences))) + .bind(Bindings.and(Bindings.isEmpty(model.sentences), Bindings.not(model.isFindingSentencesProperty()))) } private fun initializeListViewWordsContaining() { listViewWordsContaining.apply { cellFactory = DictionaryEntryCellFactory(resources, config, hostServices) - items = state.wordsContaining + items = model.wordsContaining - disableProperty().bind(Bindings.or(state.isFindingWordsContaining, Bindings.isEmpty(state.wordsContaining))) + disableProperty().bind( + Bindings.or(model.isFindingWordsContainingProperty(), Bindings.isEmpty(model.wordsContaining)) + ) selectionModel.selectedItemProperty().addListener { _, _, newEntry -> if (newEntry == null) return@addListener - state.deepDive(newEntry) + interactor.deepDive(newEntry) } } - progressIndicatorWordsContaining.visibleProperty().bind(state.isFindingWordsContaining) + progressIndicatorWordsContaining.visibleProperty().bind(model.isFindingWordsContainingProperty()) labelNoWordsContainingFound .visibleProperty() - .bind(Bindings.and(Bindings.isEmpty(state.wordsContaining), Bindings.not(state.isFindingWordsContaining))) + .bind( + Bindings.and( + Bindings.isEmpty(model.wordsContaining), + Bindings.not(model.isFindingWordsContainingProperty()) + ) + ) } private fun initializeListViewWordsBeginning() { listViewWordsBeginning.apply { cellFactory = DictionaryEntryCellFactory(resources, config, hostServices) - items = state.wordsBeginning + items = model.wordsBeginning - disableProperty().bind(Bindings.or(state.isFindingWordsBeginning, Bindings.isEmpty(state.wordsBeginning))) + disableProperty().bind( + Bindings.or(model.isFindingWordsBeginningProperty(), Bindings.isEmpty(model.wordsBeginning)) + ) selectionModel.selectedItemProperty().addListener { _, _, newEntry -> if (newEntry == null) return@addListener - state.deepDive(newEntry) + interactor.deepDive(newEntry) } } - progressIndicatorWordsBeginning.visibleProperty().bind(state.isFindingWordsBeginning) + progressIndicatorWordsBeginning.visibleProperty().bind(model.isFindingWordsBeginningProperty()) labelNoWordsBeginningFound .visibleProperty() - .bind(Bindings.and(Bindings.isEmpty(state.wordsBeginning), Bindings.not(state.isFindingWordsBeginning))) + .bind( + Bindings.and( + Bindings.isEmpty(model.wordsBeginning), + Bindings.not(model.isFindingWordsBeginningProperty()) + ) + ) } private fun initializeListViewCharacters() { listViewCharacters.apply { cellFactory = DictionaryEntryCellFactory(resources, config, hostServices) - items = state.characters + items = model.characters - disableProperty().bind(Bindings.or(state.isFindingCharacters, Bindings.isEmpty(state.characters))) + disableProperty().bind(Bindings.or(model.isFindingCharactersProperty(), Bindings.isEmpty(model.characters))) selectionModel.selectedItemProperty().addListener { _, _, newEntry -> if (newEntry == null) return@addListener - state.deepDive(newEntry) + interactor.deepDive(newEntry) } } - progressIndicatorCharacters.visibleProperty().bind(state.isFindingCharacters) + progressIndicatorCharacters.visibleProperty().bind(model.isFindingCharactersProperty()) labelNoCharactersFound .visibleProperty() - .bind(Bindings.and(Bindings.isEmpty(state.characters), Bindings.not(state.isFindingCharacters))) + .bind(Bindings.and(Bindings.isEmpty(model.characters), Bindings.not(model.isFindingCharactersProperty()))) } private fun initializeWebViewDefinition() { @@ -257,7 +271,7 @@ class DetailsController( engine.userStyleSheetLocation = this::class.java.getResource("/css/definitions.css")!!.toExternalForm() } - state.selectedEntry.addListener { _, _, newEntry -> + model.selectedEntryProperty().addListener { _, _, newEntry -> if (newEntry == null) return@addListener webViewDefinition.engine.loadContent(createDefinitionHtml(newEntry)) @@ -266,9 +280,9 @@ class DetailsController( @FXML private fun headerOnContextMenuRequested(contextMenuEvent: ContextMenuEvent) { - if (state.selectedEntry.value == null) return + if (model.selectedEntry == null) return - createContextMenuForEntry(state.selectedEntry.value, resources, hostServices).show( + createContextMenuForEntry(model.selectedEntry!!, resources, hostServices).show( flowPaneHeader.scene.window, contextMenuEvent.screenX, contextMenuEvent.screenY @@ -279,24 +293,24 @@ class DetailsController( private fun lazyUpdateTabContent(selectedTabId: String?) { when (selectedTabId) { "tabWords" -> { - if (!state.finishedFindingWordsContaining.value) { - state.findWordsContaining() + if (!model.finishedFindingWordsContaining) { + interactor.findWordsContaining() } - if (!state.finishedFindingWordsBeginning.value) { - state.findWordsBeginning() + if (!model.finishedFindingWordsBeginning) { + interactor.findWordsBeginning() } } "tabCharacters" -> { - if (state.finishedFindingCharacters.value) return + if (model.finishedFindingCharacters) return - state.findCharacters() + interactor.findCharacters() } "tabSentences" -> { - if (state.finishedFindingSentences.value) return + if (model.finishedFindingSentences) return - state.findSentences() + interactor.findSentences() } else -> {} diff --git a/src/main/kotlin/com/marvinelsen/willow/ui/controllers/MainController.kt b/src/main/kotlin/com/marvinelsen/willow/ui/controllers/MainController.kt index 9c5e4f6..99ff526 100644 --- a/src/main/kotlin/com/marvinelsen/willow/ui/controllers/MainController.kt +++ b/src/main/kotlin/com/marvinelsen/willow/ui/controllers/MainController.kt @@ -1,10 +1,10 @@ package com.marvinelsen.willow.ui.controllers -import com.marvinelsen.willow.State +import com.marvinelsen.willow.Model import javafx.fxml.FXML @Suppress("UnusedPrivateProperty", "UnusedPrivateMember") -class MainController(private val state: State) { +class MainController(private val model: Model) { @FXML private fun initialize() { // no-op diff --git a/src/main/kotlin/com/marvinelsen/willow/ui/controllers/MenuController.kt b/src/main/kotlin/com/marvinelsen/willow/ui/controllers/MenuController.kt index 4ffc031..0dd773c 100644 --- a/src/main/kotlin/com/marvinelsen/willow/ui/controllers/MenuController.kt +++ b/src/main/kotlin/com/marvinelsen/willow/ui/controllers/MenuController.kt @@ -1,6 +1,7 @@ package com.marvinelsen.willow.ui.controllers -import com.marvinelsen.willow.State +import com.marvinelsen.willow.Interactor +import com.marvinelsen.willow.Model import com.marvinelsen.willow.config.Config import com.marvinelsen.willow.ui.dialogs.PreferencesDialog import javafx.application.Platform @@ -11,7 +12,7 @@ import javafx.scene.control.MenuItem import java.util.ResourceBundle @Suppress("UnusedPrivateMember") -class MenuController(private val state: State, private val config: Config) { +class MenuController(private val model: Model, private val interactor: Interactor, private val config: Config) { @FXML private lateinit var resources: ResourceBundle @@ -26,8 +27,8 @@ class MenuController(private val state: State, private val config: Config) { @FXML private fun initialize() { - menuItemCopyPronunciation.disableProperty().bind(Bindings.isNull(state.selectedEntry)) - menuItemCopyHeadword.disableProperty().bind(Bindings.isNull(state.selectedEntry)) + menuItemCopyPronunciation.disableProperty().bind(Bindings.isNull(model.selectedEntryProperty())) + menuItemCopyHeadword.disableProperty().bind(Bindings.isNull(model.selectedEntryProperty())) } @FXML @@ -47,11 +48,11 @@ class MenuController(private val state: State, private val config: Config) { @FXML private fun onMenuItemCopyPronunciationAction() { - state.copyPronunciationOfSelectedEntry() + interactor.copyPronunciationOfSelectedEntry() } @FXML private fun onMenuItemCopyHeadwordAction() { - state.copyHeadwordOfSelectedEntry() + interactor.copyHeadwordOfSelectedEntry() } } diff --git a/src/main/kotlin/com/marvinelsen/willow/ui/controllers/SearchController.kt b/src/main/kotlin/com/marvinelsen/willow/ui/controllers/SearchController.kt index ccaf2e4..e10fcdd 100644 --- a/src/main/kotlin/com/marvinelsen/willow/ui/controllers/SearchController.kt +++ b/src/main/kotlin/com/marvinelsen/willow/ui/controllers/SearchController.kt @@ -1,13 +1,14 @@ package com.marvinelsen.willow.ui.controllers -import com.marvinelsen.willow.State +import com.marvinelsen.willow.Interactor +import com.marvinelsen.willow.Model import com.marvinelsen.willow.domain.SearchMode import javafx.fxml.FXML import javafx.scene.control.Button import javafx.scene.control.TextField import javafx.scene.control.ToggleGroup -class SearchController(private val state: State) { +class SearchController(private val model: Model, private val interactor: Interactor) { @FXML private lateinit var buttonUndo: Button @@ -26,8 +27,8 @@ class SearchController(private val state: State) { textFieldSearch.textProperty().addListener { _, _, _ -> search() } searchModeToggleGroup.selectedToggleProperty().addListener { _, _, _ -> search() } - buttonUndo.disableProperty().bind(state.canUndo.not()) - buttonRedo.disableProperty().bind(state.canRedo.not()) + buttonUndo.disableProperty().bind(model.canUndo.not()) + buttonRedo.disableProperty().bind(model.canRedo.not()) } private fun search() { @@ -38,14 +39,14 @@ class SearchController(private val state: State) { return } - state.search(searchQuery, searchMode) + interactor.search(searchQuery, searchMode) } fun onButtonRedoAction() { - state.redoSelection() + interactor.redoSelection() } fun onButtonUndoAction() { - state.undoSelection() + interactor.undoSelection() } } diff --git a/src/main/kotlin/com/marvinelsen/willow/ui/controllers/SearchResultsController.kt b/src/main/kotlin/com/marvinelsen/willow/ui/controllers/SearchResultsController.kt index e29e752..7a996cd 100644 --- a/src/main/kotlin/com/marvinelsen/willow/ui/controllers/SearchResultsController.kt +++ b/src/main/kotlin/com/marvinelsen/willow/ui/controllers/SearchResultsController.kt @@ -1,8 +1,9 @@ package com.marvinelsen.willow.ui.controllers -import com.marvinelsen.willow.State +import com.marvinelsen.willow.Interactor +import com.marvinelsen.willow.Model import com.marvinelsen.willow.config.Config -import com.marvinelsen.willow.domain.entities.DictionaryEntry +import com.marvinelsen.willow.domain.objects.DictionaryEntry import com.marvinelsen.willow.ui.cells.DictionaryEntryCellFactory import javafx.application.HostServices import javafx.beans.binding.Bindings @@ -13,7 +14,8 @@ import javafx.scene.control.ProgressIndicator import java.util.ResourceBundle class SearchResultsController( - private val state: State, + private val model: Model, + private val interactor: Interactor, private val config: Config, private val hostServices: HostServices, ) { @@ -35,21 +37,21 @@ class SearchResultsController( @Suppress("UnusedPrivateMember") private fun initialize() { listViewSearchResults.cellFactory = DictionaryEntryCellFactory(resources, config, hostServices) - listViewSearchResults.items = state.searchResults + listViewSearchResults.items = model.searchResults listViewSearchResults .disableProperty() - .bind(Bindings.or(state.isSearching, Bindings.isEmpty(state.searchResults))) + .bind(Bindings.or(model.isSearchingProperty(), Bindings.isEmpty(model.searchResults))) - progressIndicatorEntries.visibleProperty().bind(state.isSearching) + progressIndicatorEntries.visibleProperty().bind(model.isSearchingProperty()) labelNoEntriesFound .visibleProperty() - .bind(Bindings.and(Bindings.isEmpty(state.searchResults), Bindings.not(state.isSearching))) + .bind(Bindings.and(Bindings.isEmpty(model.searchResults), Bindings.not(model.isSearchingProperty()))) listViewSearchResults.selectionModel.selectedItemProperty().addListener { _, _, newValue: DictionaryEntry? -> if (newValue == null) { return@addListener } - state.normalSelect(newValue) + interactor.normalSelect(newValue) } } } diff --git a/src/main/kotlin/com/marvinelsen/willow/ui/util/ContextMenuUtils.kt b/src/main/kotlin/com/marvinelsen/willow/ui/util/ContextMenuUtils.kt index 79bb1de..cf1aab2 100644 --- a/src/main/kotlin/com/marvinelsen/willow/ui/util/ContextMenuUtils.kt +++ b/src/main/kotlin/com/marvinelsen/willow/ui/util/ContextMenuUtils.kt @@ -1,7 +1,7 @@ package com.marvinelsen.willow.ui.util -import com.marvinelsen.willow.domain.entities.DictionaryEntry -import com.marvinelsen.willow.domain.entities.Sentence +import com.marvinelsen.willow.domain.objects.DictionaryEntry +import com.marvinelsen.willow.domain.objects.Sentence import javafx.application.HostServices import javafx.event.EventHandler import javafx.scene.control.ContextMenu