diff --git a/extras/rhubarb-for-spine/src/main/kotlin/com/rhubarb_lip_sync/rhubarb_for_spine/AnimationFileModel.kt b/extras/rhubarb-for-spine/src/main/kotlin/com/rhubarb_lip_sync/rhubarb_for_spine/AnimationFileModel.kt index 7b2cc63..630b055 100644 --- a/extras/rhubarb-for-spine/src/main/kotlin/com/rhubarb_lip_sync/rhubarb_for_spine/AnimationFileModel.kt +++ b/extras/rhubarb-for-spine/src/main/kotlin/com/rhubarb_lip_sync/rhubarb_for_spine/AnimationFileModel.kt @@ -12,7 +12,7 @@ import tornadofx.observable import tornadofx.setValue import java.util.concurrent.ExecutorService -class AnimationFileModel(animationFilePath: Path, private val executor: ExecutorService) { +class AnimationFileModel(val parentModel: MainModel, animationFilePath: Path, private val executor: ExecutorService) { val spineJson = SpineJson(animationFilePath) val slotsProperty = SimpleObjectProperty>() @@ -55,7 +55,11 @@ class AnimationFileModel(animationFilePath: Path, private val executor: Executor val audioFileModelsProperty = SimpleListProperty( spineJson.audioEvents .map { event -> - AudioFileModel(event, this, executor, { result -> saveAnimation(result, event.name) }) + var audioFileModel: AudioFileModel? = null + val reportResult: (List) -> Unit = + { result -> saveAnimation(audioFileModel!!.animationName, event.name, result) } + audioFileModel = AudioFileModel(event, this, executor, reportResult) + return@map audioFileModel } .observable() ) @@ -88,14 +92,11 @@ class AnimationFileModel(animationFilePath: Path, private val executor: Executor } val valid by validProperty - private fun saveAnimation(mouthCues: List, audioEventName: String) { - val animationName = getAnimationName(audioEventName) + private fun saveAnimation(animationName: String, audioEventName: String, mouthCues: List) { spineJson.createOrUpdateAnimation(mouthCues, audioEventName, animationName, mouthSlot, mouthNaming) spineJson.save() } - private fun getAnimationName(audioEventName: String): String = "say_$audioEventName" - init { slots = spineJson.slots.observable() mouthSlot = spineJson.guessMouthSlot() diff --git a/extras/rhubarb-for-spine/src/main/kotlin/com/rhubarb_lip_sync/rhubarb_for_spine/AudioFileModel.kt b/extras/rhubarb-for-spine/src/main/kotlin/com/rhubarb_lip_sync/rhubarb_for_spine/AudioFileModel.kt index 9220f08..11b81c2 100644 --- a/extras/rhubarb-for-spine/src/main/kotlin/com/rhubarb_lip_sync/rhubarb_for_spine/AudioFileModel.kt +++ b/extras/rhubarb-for-spine/src/main/kotlin/com/rhubarb_lip_sync/rhubarb_for_spine/AudioFileModel.kt @@ -29,6 +29,23 @@ class AudioFileModel( val displayFilePathProperty = SimpleStringProperty(audioEvent.relativeAudioFilePath) val displayFilePath by displayFilePathProperty + val animationNameProperty = SimpleStringProperty().apply { + val mainModel = parentModel.parentModel + bind(object : ObjectBinding() { + init { + super.bind( + mainModel.animationPrefixProperty, + eventNameProperty, + mainModel.animationSuffixProperty + ) + } + override fun computeValue(): String { + return mainModel.animationPrefix + eventName + mainModel.animationSuffix + } + }) + } + val animationName by animationNameProperty + val dialogProperty = SimpleStringProperty(audioEvent.dialog) val dialog: String? by dialogProperty @@ -36,8 +53,17 @@ class AudioFileModel( var animationProgress by animationProgressProperty private set - private val animatedPreviouslyProperty = SimpleBooleanProperty(false) // TODO: Initial value - private var animatedPreviously by animatedPreviouslyProperty + private val animatedProperty = SimpleBooleanProperty().apply { + bind(object : ObjectBinding() { + init { + super.bind(animationNameProperty, parentModel.spineJson.animationNames) + } + override fun computeValue(): Boolean { + return parentModel.spineJson.animationNames.contains(animationName) + } + }) + } + private var animated by animatedProperty private val futureProperty = SimpleObjectProperty?>() private var future by futureProperty @@ -45,7 +71,7 @@ class AudioFileModel( private val audioFileStateProperty = SimpleObjectProperty().apply { bind(object : ObjectBinding() { init { - super.bind(animatedPreviouslyProperty, futureProperty, animationProgressProperty) + super.bind(animatedProperty, futureProperty, animationProgressProperty) } override fun computeValue(): AudioFileState { return if (future != null) { @@ -57,7 +83,7 @@ class AudioFileModel( else AudioFileState(AudioFileStatus.Pending) } else { - if (animatedPreviously) + if (animated) AudioFileState(AudioFileStatus.Done) else AudioFileState(AudioFileStatus.NotAnimated) @@ -133,7 +159,6 @@ class AudioFileModel( val result = rhubarbTask.call() runAndWait { reportResult(result) - animatedPreviously = true } } finally { runAndWait { diff --git a/extras/rhubarb-for-spine/src/main/kotlin/com/rhubarb_lip_sync/rhubarb_for_spine/MainModel.kt b/extras/rhubarb-for-spine/src/main/kotlin/com/rhubarb_lip_sync/rhubarb_for_spine/MainModel.kt index f860a44..ffe55e9 100644 --- a/extras/rhubarb-for-spine/src/main/kotlin/com/rhubarb_lip_sync/rhubarb_for_spine/MainModel.kt +++ b/extras/rhubarb-for-spine/src/main/kotlin/com/rhubarb_lip_sync/rhubarb_for_spine/MainModel.kt @@ -29,7 +29,7 @@ class MainModel(private val executor: ExecutorService) { throw Exception("File does not exist.") } - animationFileModel = AnimationFileModel(path, executor) + animationFileModel = AnimationFileModel(this, path, executor) } } var filePathString by filePathStringProperty @@ -42,5 +42,11 @@ class MainModel(private val executor: ExecutorService) { var animationFileModel by animationFileModelProperty private set + val animationPrefixProperty = SimpleStringProperty("say_") + var animationPrefix by animationPrefixProperty + + val animationSuffixProperty = SimpleStringProperty("") + var animationSuffix by animationSuffixProperty + private fun getDefaultPathString() = FX.application.parameters.raw.firstOrNull() } \ No newline at end of file diff --git a/extras/rhubarb-for-spine/src/main/kotlin/com/rhubarb_lip_sync/rhubarb_for_spine/MainView.kt b/extras/rhubarb-for-spine/src/main/kotlin/com/rhubarb_lip_sync/rhubarb_for_spine/MainView.kt index 1ca39e8..cc4ab47 100644 --- a/extras/rhubarb-for-spine/src/main/kotlin/com/rhubarb_lip_sync/rhubarb_for_spine/MainView.kt +++ b/extras/rhubarb-for-spine/src/main/kotlin/com/rhubarb_lip_sync/rhubarb_for_spine/MainView.kt @@ -71,6 +71,17 @@ class MainView : View() { errorProperty().bind(fileModelProperty.select { it!!.mouthShapesErrorProperty }) } } + field("Animation naming") { + textfield { + maxWidth = 100.0 + textProperty().bindBidirectional(mainModel.animationPrefixProperty) + } + label("