mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-12 11:34:05 +09:00
mouse latch class
This commit is contained in:
@@ -16,6 +16,7 @@ import net.torvald.terrarum.gameworld.fmod
|
|||||||
import net.torvald.terrarum.modulebasegame.MusicContainer
|
import net.torvald.terrarum.modulebasegame.MusicContainer
|
||||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||||
import net.torvald.terrarum.ui.BasicDebugInfoWindow
|
import net.torvald.terrarum.ui.BasicDebugInfoWindow
|
||||||
|
import net.torvald.terrarum.ui.MouseLatch
|
||||||
import net.torvald.terrarum.ui.Toolkit
|
import net.torvald.terrarum.ui.Toolkit
|
||||||
import net.torvald.terrarum.ui.UICanvas
|
import net.torvald.terrarum.ui.UICanvas
|
||||||
import net.torvald.terrarum.utils.JsonFetcher
|
import net.torvald.terrarum.utils.JsonFetcher
|
||||||
@@ -178,6 +179,8 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
// printdbg(this, "setMusicName $str; strLen = $nameLengthOld -> $nameLength; overflown=$nameOverflown; transitionTime=$TRANSITION_LENGTH")
|
// printdbg(this, "setMusicName $str; strLen = $nameLengthOld -> $nameLength; overflown=$nameOverflown; transitionTime=$TRANSITION_LENGTH")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val mouseLatch = MouseLatch()
|
||||||
|
|
||||||
private var mouseOnButton: Int? = null
|
private var mouseOnButton: Int? = null
|
||||||
private var mouseOnList: Int? = null
|
private var mouseOnList: Int? = null
|
||||||
|
|
||||||
@@ -311,151 +314,152 @@ class MusicPlayer(private val ingame: TerrarumIngame) : UICanvas() {
|
|||||||
|
|
||||||
|
|
||||||
// make button work
|
// make button work
|
||||||
if (!playControlButtonLatched && mouseOnButton != null && Terrarum.mouseDown) {
|
mouseLatch.latch {
|
||||||
playControlButtonLatched = true
|
if (mouseOnButton != null) {
|
||||||
when (mouseOnButton) {
|
when (mouseOnButton) {
|
||||||
0 -> { // album
|
0 -> { // album
|
||||||
albumsListCacheIsStale = true // clicking the button will refresh the album list, even if the current view is the album list
|
albumsListCacheIsStale =
|
||||||
|
true // clicking the button will refresh the album list, even if the current view is the album list
|
||||||
|
|
||||||
if (mode < MODE_SHOW_LIST) {
|
if (mode < MODE_SHOW_LIST) {
|
||||||
if (!transitionOngoing) {
|
if (!transitionOngoing) {
|
||||||
transitionRequest = MODE_SHOW_LIST
|
transitionRequest = MODE_SHOW_LIST
|
||||||
currentListMode = 0 // no list transition anim is needed this time, just set the variable
|
currentListMode =
|
||||||
resetAlbumlistScroll()
|
0 // no list transition anim is needed this time, just set the variable
|
||||||
|
resetAlbumlistScroll()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (currentListMode != 0) {
|
||||||
|
if (!listModeTransitionOngoing)
|
||||||
|
currentListTransitionRequest = 0
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!transitionOngoing)
|
||||||
|
transitionRequest = AudioMixer.musicTrack.isPlaying.toInt() * MODE_MOUSE_UP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (currentListMode != 0) {
|
|
||||||
if (!listModeTransitionOngoing)
|
1 -> { // prev
|
||||||
currentListTransitionRequest = 0
|
// prev song
|
||||||
|
if (mode < MODE_SHOW_LIST) {
|
||||||
|
getPrevSongFromPlaylist()?.let { ingame.musicGovernor.unshiftPlaylist(it) }
|
||||||
|
AudioMixer.requestFadeOut(AudioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f) {
|
||||||
|
ingame.musicGovernor.startMusic() // required for "intermittent" mode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// prev page in the playlist
|
||||||
|
else if (listViewPanelScroll == 1f) {
|
||||||
|
val scrollMax = ((currentlySelectedAlbum?.length
|
||||||
|
?: 0).toFloat() / PLAYLIST_LINES).ceilToInt() * PLAYLIST_LINES
|
||||||
|
playlistScroll = (playlistScroll - PLAYLIST_LINES) fmod scrollMax
|
||||||
|
}
|
||||||
|
// prev page in the albumlist
|
||||||
|
else if (listViewPanelScroll == 0f) {
|
||||||
|
val scrollMax = (albumsList.size.toFloat() / PLAYLIST_LINES).ceilToInt() * PLAYLIST_LINES
|
||||||
|
albumlistScroll = (albumlistScroll - PLAYLIST_LINES) fmod scrollMax
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
if (!transitionOngoing)
|
2 -> { // stop
|
||||||
transitionRequest = AudioMixer.musicTrack.isPlaying.toInt() * MODE_MOUSE_UP
|
if (mode < MODE_SHOW_LIST) { // disable stop button entirely on MODE_SHOW_LIST
|
||||||
|
if (AudioMixer.musicTrack.isPlaying) {
|
||||||
|
val thisMusic = AudioMixer.musicTrack.currentTrack
|
||||||
|
AudioMixer.requestFadeOut(AudioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f)
|
||||||
|
AudioMixer.musicTrack.nextTrack = null
|
||||||
|
ingame.musicGovernor.stopMusic()
|
||||||
|
thisMusic?.let { ingame.musicGovernor.queueMusicToPlayNext(it) }
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ingame.musicGovernor.startMusic()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
3 -> { // next
|
||||||
|
// next song
|
||||||
|
if (mode < MODE_SHOW_LIST) {
|
||||||
|
AudioMixer.requestFadeOut(AudioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f) {
|
||||||
|
ingame.musicGovernor.startMusic() // required for "intermittent" mode, does seemingly nothing on "continuous" mode
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// next page in the playlist
|
||||||
|
else if (listViewPanelScroll == 1f) {
|
||||||
|
val scrollMax = ((currentlySelectedAlbum?.length
|
||||||
|
?: 0).toFloat() / PLAYLIST_LINES).ceilToInt() * PLAYLIST_LINES
|
||||||
|
playlistScroll = (playlistScroll + PLAYLIST_LINES) fmod scrollMax
|
||||||
|
}
|
||||||
|
// next page in the albumlist
|
||||||
|
else if (listViewPanelScroll == 0f) {
|
||||||
|
val scrollMax = (albumsList.size.toFloat() / PLAYLIST_LINES).ceilToInt() * PLAYLIST_LINES
|
||||||
|
albumlistScroll = (albumlistScroll + PLAYLIST_LINES) fmod scrollMax
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
4 -> { // playlist
|
||||||
|
if (mode < MODE_SHOW_LIST) {
|
||||||
|
if (!transitionOngoing) {
|
||||||
|
transitionRequest = MODE_SHOW_LIST
|
||||||
|
currentListMode =
|
||||||
|
1 // no list transition anim is needed this time, just set the variable
|
||||||
|
resetPlaylistScroll()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (currentListMode != 1) {
|
||||||
|
if (!listModeTransitionOngoing)
|
||||||
|
currentListTransitionRequest = 1
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!transitionOngoing)
|
||||||
|
transitionRequest = AudioMixer.musicTrack.isPlaying.toInt() * MODE_MOUSE_UP
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
1 -> { // prev
|
}
|
||||||
// prev song
|
// make playlist clicking work
|
||||||
if (mode < MODE_SHOW_LIST) {
|
else if (listViewPanelScroll == 1f && mouseOnList != null) {
|
||||||
getPrevSongFromPlaylist()?.let { ingame.musicGovernor.unshiftPlaylist(it) }
|
val index = playlistScroll + mouseOnList!!
|
||||||
|
val list = songsInGovernor
|
||||||
|
if (index < list.size) {
|
||||||
|
// if selected song != currently playing
|
||||||
|
if (AudioMixer.musicTrack.currentTrack == null || list[index] != AudioMixer.musicTrack.currentTrack) {
|
||||||
|
// rebuild playlist
|
||||||
|
ingame.musicGovernor.queueIndexFromPlaylist(index)
|
||||||
|
|
||||||
|
// fade out
|
||||||
AudioMixer.requestFadeOut(AudioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f) {
|
AudioMixer.requestFadeOut(AudioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f) {
|
||||||
ingame.musicGovernor.startMusic() // required for "intermittent" mode
|
ingame.musicGovernor.startMusic() // required for "intermittent" mode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// prev page in the playlist
|
|
||||||
else if (listViewPanelScroll == 1f) {
|
|
||||||
val scrollMax = ((currentlySelectedAlbum?.length ?: 0).toFloat() / PLAYLIST_LINES).ceilToInt() * PLAYLIST_LINES
|
|
||||||
playlistScroll = (playlistScroll - PLAYLIST_LINES) fmod scrollMax
|
|
||||||
}
|
|
||||||
// prev page in the albumlist
|
|
||||||
else if (listViewPanelScroll == 0f) {
|
|
||||||
val scrollMax = (albumsList.size.toFloat() / PLAYLIST_LINES).ceilToInt() * PLAYLIST_LINES
|
|
||||||
albumlistScroll = (albumlistScroll - PLAYLIST_LINES) fmod scrollMax
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
2 -> { // stop
|
}
|
||||||
if (mode < MODE_SHOW_LIST) { // disable stop button entirely on MODE_SHOW_LIST
|
// make album list clicking work
|
||||||
if (AudioMixer.musicTrack.isPlaying) {
|
else if (listViewPanelScroll == 0f && mouseOnList != null) {
|
||||||
val thisMusic = AudioMixer.musicTrack.currentTrack
|
val index = albumlistScroll + mouseOnList!!
|
||||||
AudioMixer.requestFadeOut(AudioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f)
|
val list = albumsList//.map { albumPropCache[it] }
|
||||||
AudioMixer.musicTrack.nextTrack = null
|
|
||||||
ingame.musicGovernor.stopMusic()
|
if (index < list.size) {
|
||||||
thisMusic?.let { ingame.musicGovernor.queueMusicToPlayNext(it) }
|
// if selected album is not the same album currently playing, queue that album immediately
|
||||||
}
|
// (navigating into the selected album involves too much complication :p)
|
||||||
else {
|
if (ingame.musicGovernor.playlistSource != albumsList[index].canonicalPath) {
|
||||||
ingame.musicGovernor.startMusic()
|
// fade out
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
3 -> { // next
|
|
||||||
// next song
|
|
||||||
if (mode < MODE_SHOW_LIST) {
|
|
||||||
AudioMixer.requestFadeOut(AudioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f) {
|
AudioMixer.requestFadeOut(AudioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f) {
|
||||||
ingame.musicGovernor.startMusic() // required for "intermittent" mode, does seemingly nothing on "continuous" mode
|
loadNewAlbum(albumsList[index])
|
||||||
|
ingame.musicGovernor.startMusic() // required for "intermittent" mode
|
||||||
|
resetPlaylistScroll(AudioMixer.musicTrack.nextTrack)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// next page in the playlist
|
|
||||||
else if (listViewPanelScroll == 1f) {
|
|
||||||
val scrollMax = ((currentlySelectedAlbum?.length ?: 0).toFloat() / PLAYLIST_LINES).ceilToInt() * PLAYLIST_LINES
|
|
||||||
playlistScroll = (playlistScroll + PLAYLIST_LINES) fmod scrollMax
|
|
||||||
}
|
|
||||||
// next page in the albumlist
|
|
||||||
else if (listViewPanelScroll == 0f) {
|
|
||||||
val scrollMax = (albumsList.size.toFloat() / PLAYLIST_LINES).ceilToInt() * PLAYLIST_LINES
|
|
||||||
albumlistScroll = (albumlistScroll + PLAYLIST_LINES) fmod scrollMax
|
|
||||||
}
|
|
||||||
}
|
|
||||||
4 -> { // playlist
|
|
||||||
if (mode < MODE_SHOW_LIST) {
|
|
||||||
if (!transitionOngoing) {
|
|
||||||
transitionRequest = MODE_SHOW_LIST
|
|
||||||
currentListMode = 1 // no list transition anim is needed this time, just set the variable
|
|
||||||
resetPlaylistScroll()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (currentListMode != 1) {
|
|
||||||
if (!listModeTransitionOngoing)
|
|
||||||
currentListTransitionRequest = 1
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (!transitionOngoing)
|
|
||||||
transitionRequest = AudioMixer.musicTrack.isPlaying.toInt() * MODE_MOUSE_UP
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
// click on the music title to return to MODE_MOUSE_UP
|
||||||
// make playlist clicking work
|
else if (mouseUp && relativeMouseY.toFloat() in _posY + height - capsuleHeight.._posY + height && !transitionOngoing && mode > MODE_MOUSE_UP) {
|
||||||
else if (listViewPanelScroll == 1f && !playControlButtonLatched && mouseOnList != null && Terrarum.mouseDown) {
|
transitionRequest = MODE_MOUSE_UP
|
||||||
playControlButtonLatched = true
|
|
||||||
val index = playlistScroll + mouseOnList!!
|
|
||||||
val list = songsInGovernor
|
|
||||||
if (index < list.size) {
|
|
||||||
// if selected song != currently playing
|
|
||||||
if (AudioMixer.musicTrack.currentTrack == null || list[index] != AudioMixer.musicTrack.currentTrack) {
|
|
||||||
// rebuild playlist
|
|
||||||
ingame.musicGovernor.queueIndexFromPlaylist(index)
|
|
||||||
|
|
||||||
// fade out
|
|
||||||
AudioMixer.requestFadeOut(AudioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f) {
|
|
||||||
ingame.musicGovernor.startMusic() // required for "intermittent" mode
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// make album list clicking work
|
|
||||||
else if (listViewPanelScroll == 0f && !playControlButtonLatched && mouseOnList != null && Terrarum.mouseDown) {
|
|
||||||
playControlButtonLatched = true
|
|
||||||
val index = albumlistScroll + mouseOnList!!
|
|
||||||
val list = albumsList//.map { albumPropCache[it] }
|
|
||||||
|
|
||||||
if (index < list.size) {
|
|
||||||
// if selected album is not the same album currently playing, queue that album immediately
|
|
||||||
// (navigating into the selected album involves too much complication :p)
|
|
||||||
if (ingame.musicGovernor.playlistSource != albumsList[index].canonicalPath) {
|
|
||||||
// fade out
|
|
||||||
AudioMixer.requestFadeOut(AudioMixer.musicTrack, AudioMixer.DEFAULT_FADEOUT_LEN / 3f) {
|
|
||||||
loadNewAlbum(albumsList[index])
|
|
||||||
ingame.musicGovernor.startMusic() // required for "intermittent" mode
|
|
||||||
resetPlaylistScroll(AudioMixer.musicTrack.nextTrack)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// click on the music title to return to MODE_MOUSE_UP
|
|
||||||
else if (mouseUp && relativeMouseY.toFloat() in _posY + height - capsuleHeight .. _posY + height && Terrarum.mouseDown && !transitionOngoing && mode > MODE_MOUSE_UP) {
|
|
||||||
playControlButtonLatched = true
|
|
||||||
transitionRequest = MODE_MOUSE_UP
|
|
||||||
}
|
|
||||||
// unlatch the click latch
|
|
||||||
else if (!Terrarum.mouseDown) {
|
|
||||||
playControlButtonLatched = false
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// printdbg(this, "mode = $mode; req = $transitionRequest")
|
// printdbg(this, "mode = $mode; req = $transitionRequest")
|
||||||
}
|
}
|
||||||
|
|
||||||
private var playControlButtonLatched = false
|
|
||||||
|
|
||||||
private fun resetAlbumlistScroll() {
|
private fun resetAlbumlistScroll() {
|
||||||
val currentlyPlaying = albumsList.indexOfFirst { it.canonicalPath.replace('\\', '/') == ingame.musicGovernor.playlistSource }
|
val currentlyPlaying = albumsList.indexOfFirst { it.canonicalPath.replace('\\', '/') == ingame.musicGovernor.playlistSource }
|
||||||
if (currentlyPlaying >= 0) {
|
if (currentlyPlaying >= 0) {
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ object DefaultConfig {
|
|||||||
"screenheight" to TerrarumScreenSize.defaultH,
|
"screenheight" to TerrarumScreenSize.defaultH,
|
||||||
"fullscreen" to false,
|
"fullscreen" to false,
|
||||||
"atlastexsize" to 2048,
|
"atlastexsize" to 2048,
|
||||||
"savegamecomp" to "zstd",
|
"savegamecomp" to "snappy",
|
||||||
|
|
||||||
"audio_buffer_size" to 512,
|
"audio_buffer_size" to 512,
|
||||||
"audio_dynamic_source_max" to 128,
|
"audio_dynamic_source_max" to 128,
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
package net.torvald.terrarum
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by minjaesong on 2024-01-10.
|
|
||||||
*/
|
|
||||||
class MouseLatch {
|
|
||||||
}
|
|
||||||
56
src/net/torvald/terrarum/ui/MouseLatch.kt
Normal file
56
src/net/torvald/terrarum/ui/MouseLatch.kt
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package net.torvald.terrarum.ui
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx
|
||||||
|
import net.torvald.terrarum.App
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by minjaesong on 2024-01-10.
|
||||||
|
*/
|
||||||
|
class MouseLatch(val button: List<Int> = listOf(App.getConfigInt("config_mouseprimary"))) {
|
||||||
|
|
||||||
|
private val status = AtomicBoolean()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the `action` when the mouse-latch is unlatched and any of the specified buttons are down. After the `action` has run, the unlatch check will be done immediately.
|
||||||
|
*
|
||||||
|
* @param action what to do when the mouse is clicked. The latch will be latched right before the action runs.
|
||||||
|
* Return `false` to unlatch the mouse-latch. Returning null WILL latch it.
|
||||||
|
*/
|
||||||
|
fun latchSelectively(action: () -> Boolean?) {
|
||||||
|
if (isNotLatched() && button.any { Gdx.input.isButtonPressed(it) }) {
|
||||||
|
status.set(true)
|
||||||
|
status.set(action() ?: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isLatched() && button.none { Gdx.input.isButtonPressed(it) }) {
|
||||||
|
status.set(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs the `action` when the mouse-latch is unlatched and any of the specified buttons are down. After the `action` has run, the unlatch check will be done immediately.
|
||||||
|
*
|
||||||
|
* @param action what to do when the mouse is clicked. The mouse-latch will be latched right before the action runs
|
||||||
|
*/
|
||||||
|
fun latch(action: () -> Unit) {
|
||||||
|
if (isNotLatched() && button.any { Gdx.input.isButtonPressed(it) }) {
|
||||||
|
status.set(true)
|
||||||
|
action()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isLatched() && button.none { Gdx.input.isButtonPressed(it) }) {
|
||||||
|
status.set(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun unlatch() {
|
||||||
|
if (button.none { Gdx.input.isButtonPressed(it) }) {
|
||||||
|
status.set(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isLatched() = status.get()
|
||||||
|
fun isNotLatched() = !status.get()
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user