Skip to content

Commit

Permalink
Various things
Browse files Browse the repository at this point in the history
  • Loading branch information
kikugie committed Aug 24, 2024
1 parent 4d2e939 commit f95e6d2
Show file tree
Hide file tree
Showing 15 changed files with 93 additions and 34 deletions.
4 changes: 2 additions & 2 deletions kowoui/src/main/resources/kowoui.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
"package": "dev.kikugie.kowoui.mixin",
"compatibilityLevel": "JAVA_21",
"mixins": [
"owo.BaseParentComponentMixin",
"TextFieldWidgetMixin"
"TextFieldWidgetMixin",
"owo.BaseParentComponentMixin"
],
"injectors": {
"defaultRequire": 1
Expand Down
23 changes: 23 additions & 0 deletions src/main/java/dev/kikugie/soundboard/mixin/KeyboardMixin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package dev.kikugie.soundboard.mixin;

import dev.kikugie.soundboard.ModKeyBinds;
import net.minecraft.client.Keyboard;
import net.minecraft.client.option.KeyBinding;
import org.lwjgl.glfw.GLFW;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(Keyboard.class)
public class KeyboardMixin {
@Inject(method = "onKey", at = @At(value = "FIELD", target = "Lnet/minecraft/client/Keyboard;debugCrashStartTime:J"), cancellable = true)
private void cancelOnKeyCombo(long window, int key, int scancode, int action, int modifiers, CallbackInfo ci) {
boolean isNumrow = key >= GLFW.GLFW_KEY_0 && key <= GLFW.GLFW_KEY_9;
boolean isNumpad = key >= GLFW.GLFW_KEY_KP_0 && key <= GLFW.GLFW_KEY_KP_9;
if (!isNumrow && !isNumpad) return;

KeyBinding play = ModKeyBinds.get("play");
if (play != null && play.isPressed()) ci.cancel();
}
}
1 change: 1 addition & 0 deletions src/main/kotlin/dev/kikugie/soundboard/ModKeyBinds.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import net.minecraft.client.option.KeyBinding
object ModKeyBinds {
private val keybinds = mutableMapOf<String, KeyBuilder>()

@JvmStatic
operator fun get(name: String): KeyBinding? = keybinds[name]?.keybind
fun keybind(key: Int, name: String, action: KeyBuilder.() -> Unit) {
val bind = KeyBindingHelper.registerKeyBinding(KeyBinding("soundboard.keybinds.$name", key, "soundboard.title"))
Expand Down
8 changes: 7 additions & 1 deletion src/main/kotlin/dev/kikugie/soundboard/Soundboard.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ object Soundboard {

ModKeyBinds.keybind(GLFW.GLFW_KEY_J, "browser") {
inGame { SoundBrowser.open() }
inGui { if (this is SoundBrowser) close() }
inGui {
if (this is SoundBrowser) {
if (settings != null) closeSettings()
else close()
}
}
}
ModKeyBinds.keybind(GLFW.GLFW_KEY_U, "cancel") {
val reset = { SoundboardAccess.forEach { scheduler.reset() } }
Expand All @@ -52,6 +57,7 @@ object Soundboard {
// 0 converts to 9 because it's the last on the number row
InputUtil.isKeyPressed(handle, GLFW.GLFW_KEY_0) ||
InputUtil.isKeyPressed(handle, GLFW.GLFW_KEY_KP_0) -> 9

else -> numrow.firstNotNullOfOrNull {
if (InputUtil.isKeyPressed(handle, it)) it - GLFW.GLFW_KEY_1 else null
} ?: numpad.firstNotNullOfOrNull {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ data class AudioConfiguration(
inline fun clone(block: AudioConfiguration.() -> Unit) = clone().apply(block)
inline fun cloneOrNull(block: AudioConfiguration.() -> Unit) = clone(block).takeIf { it != DEFAULT }

fun isDefault(dest: Duration = Duration.INFINITE) =
start <= Duration.ZERO && end in dest..Duration.INFINITE && volume == 1.0

companion object {
val DEFAULT = AudioConfiguration(Duration.ZERO, Duration.INFINITE, 1.0)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import java.io.InputStream
data class SoundEntry(
val id: SoundId,
val supplier: () -> InputStream,
var settings: AudioConfiguration? = null,
val settings: AudioConfiguration? = null,
private val text: Text? = null,
) {
val group: SoundId by lazy { id.parent() }
Expand Down
6 changes: 3 additions & 3 deletions src/main/kotlin/dev/kikugie/soundboard/audio/data/SoundId.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ import kotlin.io.path.exists
@JvmInline
@Serializable
value class SoundId(val str: String) {
val namespace get() = str.substringBefore(':')
val namespace get() = str.substringBefore(':', "")
val directory get() = str.substringAfter(':').substringBeforeLast('/')
val path get() = str.substringAfter(':')
val file get() = str.substringAfterLast('/')
val file get() = str.substringAfterLast('/', "")

constructor(namespace: String, path: String) : this("$namespace:$path")
constructor(namespace: String, path: String) : this("${ if (namespace.isEmpty() || namespace == MOD_ID) "" else "$namespace:" }$path")
constructor(id: Identifier) : this(id.toString())

fun parent() = SoundId(namespace, directory.ifEmpty { "/" })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ package dev.kikugie.soundboard.audio.download
import dev.kikugie.kowoui.access.*
import dev.kikugie.kowoui.experimental.plusAssign
import dev.kikugie.kowoui.overlay
import dev.kikugie.kowoui.translation
import dev.kikugie.kowoui.util.CombinedAlignment
import dev.kikugie.soundboard.GAME_DIR
import dev.kikugie.soundboard.LOGGER
import dev.kikugie.soundboard.gui.widget.DownloadErrorWidget
import dev.kikugie.soundboard.util.client
import io.wispforest.owo.ui.container.StackLayout
import io.wispforest.owo.ui.core.Positioning
import io.wispforest.owo.ui.core.Sizing
Expand All @@ -17,8 +19,11 @@ import kotlinx.coroutines.cancel
import java.lang.ref.WeakReference
import java.net.URI
import java.nio.file.Path
import kotlin.io.path.invariantSeparatorsPathString

object Downloader {
private const val FAILURE = "soundboard.download.failure"
private const val SUCCESS = "soundboard.download.success"
private val downloads: MutableMap<Path, Pair<URI, Job>> = mutableMapOf()

fun isDownloading(path: Path) = path in downloads
Expand All @@ -27,14 +32,20 @@ object Downloader {
if (downloads[dest]?.first == url) return // Don't repeat downloads
val job = CobaltApi.download(url, dest).apply {
invokeOnCompletion {
val file = GAME_DIR.relativize(dest)
if (it !is CancellationException) downloads.remove(dest)
when (it) {
null -> LOGGER.info("Saved $url to ${GAME_DIR.relativize(dest)}")
is CancellationException -> LOGGER.info("Download cancelled for $url")
null -> {
LOGGER.info("Saved $url to $file")
client.player?.sendMessage(SUCCESS.translation(file.invariantSeparatorsPathString))
}

else -> {
LOGGER.error("Failed to download $url", it)
// TODO should open a popup if screen has been closed
ref.get()?.createWidget(it)
ref.get()?.createWidget(it) ?: client.player
?.sendMessage(FAILURE.translation(file.invariantSeparatorsPathString))
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import dev.kikugie.soundboard.audio.*
import dev.kikugie.soundboard.audio.data.SoundEntry
import dev.kikugie.soundboard.audio.data.SoundGroup
import dev.kikugie.soundboard.audio.data.SoundId
import dev.kikugie.soundboard.config.AudioConfig
import it.unimi.dsi.fastutil.objects.Object2LongMap
import it.unimi.dsi.fastutil.objects.Object2LongOpenHashMap
import net.minecraft.text.Text
Expand All @@ -27,8 +26,9 @@ object FileAudioHolder {
operator fun get(id: SoundId): SoundEntry? {
val path = runCatching { BASE_DIR.resolve(id.path.removePrefix("/") + ".$FORMAT") }
.getOrNull() ?: return null
if (cache(path)) return sounds[id.parent()][id]
update()
val props = path.withExtension("properties")
val cached = cache(path) && (props.notExists() || cache(props))
if (!cached) update()
return sounds[id.parent()][id]
}

Expand Down Expand Up @@ -62,7 +62,7 @@ object FileAudioHolder {

private fun entry(id: SoundId, path: Path, props: Path): SoundEntry {
val title = runCatching { PropertiesReader.read(props)["title"]?.text() }.getOrNull()
return SoundEntry(id, path::inputStream, AudioConfig[id], title)
return SoundEntry(id, path::inputStream, null, title)
}

private fun cache(path: Path) =
Expand Down
10 changes: 8 additions & 2 deletions src/main/kotlin/dev/kikugie/soundboard/config/AudioConfig.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,14 @@ object AudioConfig {

operator fun get(entry: SoundEntry): AudioConfiguration? = get(entry.id)
operator fun get(id: SoundId): AudioConfiguration? = configurations[id]
operator fun set(entry: SoundEntry, configuration: AudioConfiguration) {
configurations[entry.id] = configuration
operator fun set(entry: SoundEntry, configuration: AudioConfiguration) = set(entry.id, configuration)
operator fun set(id: SoundId, configuration: AudioConfiguration) {
configurations[id] = configuration
runOn(Dispatchers.IO) { save() }
}
operator fun minusAssign(entry: SoundEntry) = minusAssign(entry.id)
operator fun minusAssign(id: SoundId) {
configurations.remove(id)
runOn(Dispatchers.IO) { save() }
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import io.wispforest.owo.ui.container.StackLayout
import io.wispforest.owo.ui.core.Insets.*
import io.wispforest.owo.ui.core.OwoUIAdapter
import io.wispforest.owo.ui.core.ParentComponent
import io.wispforest.owo.ui.core.Positioning.relative
import io.wispforest.owo.ui.core.Sizing.expand
import io.wispforest.owo.ui.core.Sizing.fill
import io.wispforest.owo.ui.core.Surface
Expand Down Expand Up @@ -112,6 +113,7 @@ class SoundBrowser : BaseOwoScreen<StackLayout>() {
scrollbarThickness = 10
scrollbar = vanilla()
surface = Surface.PANEL_INSET
padding = bottom(1)
}
this += SidebarWidget(this@SoundBrowser)
}
Expand Down Expand Up @@ -174,10 +176,10 @@ class SoundBrowser : BaseOwoScreen<StackLayout>() {
private fun settings(entry: SoundEntry) {
settings = SoundSettingsWidget(entry, SoundboardAccess.delegates.first())
root + overlay(settings!!) {
sizing = fill(50)
closeOnClick = false
surface = CONFIG_PANEL
positioning = io.wispforest.owo.ui.core.Positioning.relative(50, 50)
sizing = fill(65)
positioning = relative(50, 50)
zIndex = 100
onMouseDown { _, _, _ -> true }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,27 @@ import dev.kikugie.kowoui.access.*
import dev.kikugie.kowoui.dynamic.ColoredTextComponent
import dev.kikugie.kowoui.dynamic.dynamicButton
import dev.kikugie.kowoui.dynamic.dynamicLabel
import dev.kikugie.kowoui.dynamic.fixedSpacer
import dev.kikugie.kowoui.experimental.at
import dev.kikugie.kowoui.experimental.plusAssign
import dev.kikugie.soundboard.CONFIG
import dev.kikugie.soundboard.ModKeyBinds
import dev.kikugie.soundboard.Soundboard
import dev.kikugie.soundboard.audio.data.AudioConfiguration
import dev.kikugie.soundboard.audio.data.AudioConfiguration.Companion.DEFAULT
import dev.kikugie.soundboard.audio.data.SoundEntry
import dev.kikugie.soundboard.audio.registry.SoundRegistry
import dev.kikugie.soundboard.config.AudioConfig
import dev.kikugie.soundboard.entrypoint.SoundboardEntrypoint
import dev.kikugie.soundboard.gui.screen.SoundBrowser
import dev.kikugie.soundboard.gui.component.*
import dev.kikugie.soundboard.gui.component.TimeInputComponent.Companion.asString
import dev.kikugie.soundboard.gui.screen.SoundBrowser
import dev.kikugie.soundboard.util.client
import dev.kikugie.soundboard.util.currentScreen
import dev.kikugie.soundboard.util.duration
import dev.kikugie.soundboard.util.read
import io.wispforest.owo.ui.component.ButtonComponent.Renderer
import io.wispforest.owo.ui.component.SlimSliderComponent.Axis.VERTICAL
import io.wispforest.owo.ui.container.FlowLayout
import io.wispforest.owo.ui.container.WrappingParentComponent
import io.wispforest.owo.ui.core.*
import io.wispforest.owo.ui.core.Insets.bottom
import io.wispforest.owo.ui.core.Sizing.*
Expand All @@ -35,7 +35,7 @@ import kotlin.time.Duration
class SoundSettingsWidget(
private val entry: SoundEntry,
private val access: SoundboardEntrypoint,
) : WrappingParentComponent<FlowLayout>(fill(), fill(), verticalFlow { sizing = fill() }) {
) : FlowLayout(content(), content(), Algorithm.VERTICAL) {
companion object {
private const val CLOSE = "×"
private const val CLOSE_TOOLTIP = "soundboard.browser.tooltip.close"
Expand All @@ -54,25 +54,22 @@ class SoundSettingsWidget(

private val data = entry.read(access.format)
private val duration = access.format.duration(data.size)
private val default = AudioConfiguration(Duration.ZERO, duration, 1.0)
private val settings = AudioConfig[entry] ?: default.clone()
private val settings = AudioConfig[entry] ?: entry.settings ?: DEFAULT.clone()

init {
if (settings.end == Duration.INFINITE) settings.end = duration
create()
}

fun update() {
if (settings != default) AudioConfig[entry] = settings
}

override fun draw(context: OwoUIDrawContext, mouseX: Int, mouseY: Int, partialTicks: Float, delta: Float) {
super.draw(context, mouseX, mouseY, partialTicks, delta)
child.draw(context, mouseX, mouseY, partialTicks, delta)
if (settings.isDefault(duration) || settings == entry.settings) AudioConfig -= entry
else AudioConfig[entry] = settings
}

private val Double.invert get() = 1 - this

private fun create() = with(child) {
private fun create() = with(this as FlowLayout) {
id = "settings-container"
padding = Insets.of(5)
var favourite = entry.id in Soundboard.config.favourites
var index = -1
Expand Down Expand Up @@ -131,6 +128,7 @@ class SoundSettingsWidget(
else if (index < 0) CONFIG.favourites += entry.id
else CONFIG.favourites.add(index, entry.id)

CONFIG.save()
SoundRegistry.update()
(currentScreen as? SoundBrowser)?.createFavourites()
}
Expand Down Expand Up @@ -170,7 +168,7 @@ class SoundSettingsWidget(
"${(settings.volume * 100).toInt()}%".text()
}
}
at(1, 0) += grid(1, 3) {
at(1, 0) += grid(1, 5) {
id = "duration-controls"
horizontalSizing = expand()
horizontalAlignment = HorizontalAlignment.CENTER
Expand All @@ -180,13 +178,15 @@ class SoundSettingsWidget(
validate { it <= settings.end }
onDurationChange { cutter.update() }
}
at(0, 1) += dynamicLabel{
at(0, 1) += fixedSpacer(5)
at(0, 2) += dynamicLabel{
id = "duration"
horizontalTextAlignment = HorizontalAlignment.CENTER
verticalTextAlignment = VerticalAlignment.CENTER
text { "${(settings.end - settings.start).asString}s".text() }
}
at(0, 2) += TimeInputComponent(duration, settings::end).apply {
at(0, 3) += fixedSpacer(5)
at(0, 4) += TimeInputComponent(duration, settings::end).apply {
id = "end"
validate { it >= settings.start }
onDurationChange { cutter.update() }
Expand Down
2 changes: 1 addition & 1 deletion src/main/kotlin/dev/kikugie/soundboard/util/Util.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ inline infix fun Boolean.then(action: () -> Unit): Boolean {
return this
}

fun Class<*>.accurateName(): String = simpleName.takeIf { it.isNotEmpty() } ?: run {
fun Class<*>.accurateName(): String = simpleName.ifEmpty {
val parent = if (this == Any::class.java) "Object" else superclass.accurateName()
"out $parent"
}
Expand Down
6 changes: 6 additions & 0 deletions src/main/resources/assets/soundboard/lang/en_us.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ soundboard:
You're responsible for what you download, so be mindful when using the service.
color: dark_gray
bold: false
failure:
- text: Failed to save %s. Check the game log
color: red
success:
- text: Downloaded %s
color: green
tooltip:
overwrite_path: File already exists and will be overwritten
downloading_path: File is already being downloaded and will be overwritten
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/soundboard.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"package": "dev.kikugie.soundboard.mixin",
"compatibilityLevel": "JAVA_21",
"mixins": [
"KeyboardMixin",
"owo_ui.OwODrawContextMixin",
"owo_ui.ScrollContainerAccessor"
],
Expand Down

0 comments on commit f95e6d2

Please sign in to comment.