diff options
author | SoniEx2 <endermoneymod@gmail.com> | 2025-03-21 23:19:14 -0300 |
---|---|---|
committer | SoniEx2 <endermoneymod@gmail.com> | 2025-03-21 23:19:14 -0300 |
commit | 8f4da9a630ee4cb549c75a85b7e6ac842ef874f1 (patch) | |
tree | 0f93e56e26eacbe97f6dd0be6f89f2f3947e3763 | |
parent | 32f4966e8d3e824619fabbd225ee8e74b62be7c7 (diff) |
Improve GUI accessibility
-rw-r--r-- | gradle.properties | 2 | ||||
-rw-r--r-- | gui/radio-receiver.c | 83 | ||||
-rw-r--r-- | src/client/kotlin/space/autistic/radio/client/gui/FmReceiverScreen.kt | 157 |
3 files changed, 161 insertions, 81 deletions
diff --git a/gradle.properties b/gradle.properties index 080b6d9..6b1ab26 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,7 +10,7 @@ loader_version=0.16.10 fabric_kotlin_version=1.13.1+kotlin.2.1.10 # Mod Properties -mod_version=1.0.4 +mod_version=1.0.5 maven_group=space.autistic.radio archives_base_name=pirate-radio diff --git a/gui/radio-receiver.c b/gui/radio-receiver.c index defd419..de879a2 100644 --- a/gui/radio-receiver.c +++ b/gui/radio-receiver.c @@ -51,20 +51,12 @@ extern int screen_get_width(); [[clang::import_module("screen")]] [[clang::import_name("get-height")]] extern int screen_get_height(); -[[clang::import_module("volume-plus-widget")]] [[clang::import_name("set-dimensions")]] -extern void vp_set_dimensions(int x, int y, int width, int height); -[[clang::import_module("volume-minus-widget")]] [[clang::import_name("set-dimensions")]] -extern void vm_set_dimensions(int x, int y, int width, int height); -[[clang::import_module("frequency-plus-widget")]] [[clang::import_name("set-dimensions")]] -extern void fp_set_dimensions(int x, int y, int width, int height); -[[clang::import_module("frequency-minus-widget")]] [[clang::import_name("set-dimensions")]] -extern void fm_set_dimensions(int x, int y, int width, int height); -[[clang::import_module("toggle-widget")]] [[clang::import_name("set-dimensions")]] -extern void mode_set_dimensions(int x, int y, int width, int height); -[[clang::import_module("audio-device-widget")]] [[clang::import_name("set-dimensions")]] -extern void audio_device_set_dimensions(int x, int y, int width, int height); +[[clang::import_module("buttons")]] [[clang::import_name("set-dimensions")]] +extern int buttons_set_dimensions(int button, int x, int y, int width, int height); +[[clang::import_module("buttons")]] [[clang::import_name("set-base-layout")]] +extern void buttons_set_base_layout(int layout); -#define BACKGROUND_WIDTH 200 +#define BACKGROUND_WIDTH 320 #define BACKGROUND_HEIGHT 100 void init() { @@ -72,70 +64,17 @@ void init() { logger_log_message("placeholder radio skin."); set_background_size(BACKGROUND_WIDTH, BACKGROUND_HEIGHT); + buttons_set_base_layout(1); + int width = screen_get_width(); int height = screen_get_height(); int base_x = (width - BACKGROUND_WIDTH) / 2; int base_y = (height - BACKGROUND_HEIGHT) / 2; - fp_set_dimensions(base_x + 100 - 40, base_y, 20, 20); - fm_set_dimensions(base_x + 120 - 40, base_y, 20, 20); - vp_set_dimensions(base_x + 100 - 40, base_y + 20, 20, 20); - vm_set_dimensions(base_x + 120 - 40, base_y + 20, 20, 20); - mode_set_dimensions(base_x + 100 - 100, base_y + 40, 100, 20); - audio_device_set_dimensions(base_x, base_y + 60, 200, 20); + buttons_set_dimensions(0, base_x, base_y + 0, 320, 20); + buttons_set_dimensions(1, base_x, base_y + 20, 320, 20); + buttons_set_dimensions(2, base_x, base_y + 40, 320, 20); + buttons_set_dimensions(3, base_x, base_y + 60, 320, 20); } void render(int mouseX, int mouseY, float delta) { - int width = screen_get_width(); - int height = screen_get_height(); - int base_x = (width - BACKGROUND_WIDTH) / 2 + 100; - int base_y = (height - BACKGROUND_HEIGHT) / 2 + (20 - 9) / 2; - int t1; - switch (simulator_get_mode()) { - case SIMULATOR_FAST: - { - t1 = text_translatable("pirate-radio.mode.fast"); - break; - } - case SIMULATOR_DEAF: - { - t1 = text_translatable("pirate-radio.mode.deaf"); - break; - } - default: - { - t1 = text_translatable("pirate-radio.mode.full"); - } - } - int t2 = text_arguments("pirate-radio.mode.selected", 1, &t1); - render_text_object(t2, base_x, base_y + 40, -1, true); - text_free(t1); - text_free(t2); - - int volume = simulator_get_volume(); - if (volume == 0) { - t1 = text_translatable("pirate-radio.volume.off"); - } else { - char volume_text[30]; - sprintf(volume_text, "%d", volume); - t1 = text_literal(volume_text); - } - t2 = text_arguments("pirate-radio.volume.selected", 1, &t1); - render_text_object(t2, base_x, base_y + 20, -1, true); - text_free(t1); - text_free(t2); - - int frequency = simulator_get_frequency(); - int freq_mhz = frequency/10; - int freq_step = frequency%10; - char freq_text[30]; - sprintf(freq_text, "%d", freq_mhz); - t1 = text_literal(freq_text); - sprintf(freq_text, "%d", freq_step); - t2 = text_literal(freq_text); - int freq_args[2] = {t1, t2}; - int t3 = text_arguments("pirate-radio.frequency.selected", 2, freq_args); - render_text_object(t3, base_x, base_y + 0, -1, true); - text_free(t1); - text_free(t2); - text_free(t3); } diff --git a/src/client/kotlin/space/autistic/radio/client/gui/FmReceiverScreen.kt b/src/client/kotlin/space/autistic/radio/client/gui/FmReceiverScreen.kt index e4ea8ea..8886498 100644 --- a/src/client/kotlin/space/autistic/radio/client/gui/FmReceiverScreen.kt +++ b/src/client/kotlin/space/autistic/radio/client/gui/FmReceiverScreen.kt @@ -15,12 +15,15 @@ import net.minecraft.client.gui.screen.Screen import net.minecraft.client.gui.widget.ButtonWidget import net.minecraft.client.gui.widget.ClickableWidget import net.minecraft.client.gui.widget.CyclingButtonWidget +import net.minecraft.client.gui.widget.SliderWidget import net.minecraft.client.render.GameRenderer import net.minecraft.client.util.InputUtil +import net.minecraft.screen.ScreenTexts import net.minecraft.text.StringVisitable import net.minecraft.text.Text import net.minecraft.util.Colors import net.minecraft.util.Identifier +import net.minecraft.util.math.MathHelper import org.lwjgl.glfw.GLFW import org.slf4j.LoggerFactory import org.slf4j.event.Level @@ -33,7 +36,6 @@ import java.lang.invoke.MethodHandles import java.util.* import javax.sound.sampled.AudioSystem import javax.sound.sampled.Mixer -import kotlin.collections.ArrayList import kotlin.math.max import kotlin.reflect.jvm.javaMethod @@ -94,12 +96,106 @@ class FmReceiverScreen : Screen(Text.translatable("pirate-radio.fm-receiver")) { }.dimensions(20, 20, 20, 20) .narrationSupplier { ButtonWidget.getNarrationMessage(Text.translatable("pirate-radio.volume.minus.narrated")) } .build() + private var frequencySlider = makeFrequencySlider(0, 0, 320, 20) + private fun makeFrequencySlider(x: Int, y: Int, width: Int, height: Int) = object : SliderWidget( + x, y, width, height, ScreenTexts.EMPTY, (PirateRadioClient.frequency - 768).toDouble() / (1080.0 - 768.0) + ) { + init { + updateMessage() + } + + override fun updateMessage() { + message = Text.translatable( + "pirate-radio.frequency.selected", PirateRadioClient.frequency / 10, PirateRadioClient.frequency % 10 + ) + } + + override fun applyValue() { + PirateRadioClient.frequency = MathHelper.clampedLerp(768.0, 1080.0, value).toInt() + } + + override fun keyPressed(keyCode: Int, scanCode: Int, modifiers: Int): Boolean { + val oldValue = this.value + val oldFrequency = PirateRadioClient.frequency + val changed = super.keyPressed(keyCode, scanCode, modifiers) + val bl = keyCode == GLFW.GLFW_KEY_LEFT + if (bl || keyCode == GLFW.GLFW_KEY_RIGHT) { + if (changed) { + val delta = if (bl) -1 else 1 + val newValue = (oldFrequency + delta - 768).toDouble() / (1080.0 - 768.0) + this.value = MathHelper.clamp(newValue, 0.0, 1.0) + if (oldValue != this.value) { + this.applyValue() + } + + this.updateMessage() + } + } + return changed + } + } + + private var volumeSlider = makeVolumeSlider(0, 20, 320, 20) + private fun makeVolumeSlider(x: Int, y: Int, width: Int, height: Int) = object : SliderWidget( + x, y, width, height, ScreenTexts.EMPTY, PirateRadioClient.volume.toDouble() / 10.0 + ) { + init { + updateMessage() + } + + override fun updateMessage() { + message = if (PirateRadioClient.volume == 0) { + Text.translatable("pirate-radio.volume.selected", Text.translatable("pirate-radio.volume.off")) + } else { + Text.translatable("pirate-radio.volume.selected", PirateRadioClient.volume) + } + } + + override fun applyValue() { + PirateRadioClient.volume = MathHelper.clampedLerp(0.0, 10.0, value).toInt() + } + + + override fun keyPressed(keyCode: Int, scanCode: Int, modifiers: Int): Boolean { + val oldValue = this.value + val oldVolume = PirateRadioClient.volume + val changed = super.keyPressed(keyCode, scanCode, modifiers) + val bl = keyCode == GLFW.GLFW_KEY_LEFT + if (bl || keyCode == GLFW.GLFW_KEY_RIGHT) { + if (changed) { + val delta = if (bl) -1 else 1 + val newValue = (oldVolume + delta).toDouble() / 10.0 + this.value = MathHelper.clamp(newValue, 0.0, 1.0) + if (oldValue != this.value) { + this.applyValue() + } + + this.updateMessage() + } + } + return changed + } + } + private val toggleModes = ButtonWidget.builder(Text.translatable("pirate-radio.mode")) { PirateRadioClient.mode = when (PirateRadioClient.mode) { FmSimulatorMode.FULL -> FmSimulatorMode.FAST else -> FmSimulatorMode.FULL } }.position(0, 40).build() + private val cycleModes = CyclingButtonWidget.builder { info: FmSimulatorMode -> + when (info) { + FmSimulatorMode.FAST -> Text.translatable("pirate-radio.mode.fast") + FmSimulatorMode.FULL -> Text.translatable("pirate-radio.mode.full") + FmSimulatorMode.DEAF -> Text.translatable("pirate-radio.mode.deaf") + } + }.values( + listOf( + FmSimulatorMode.FULL, FmSimulatorMode.FAST + ) + ).initially(PirateRadioClient.mode).build(0, 40, 320, 20, Text.translatable("pirate-radio.mode")) { _, it -> + PirateRadioClient.mode = it + } private val audioDevice = CyclingButtonWidget.builder { info: Mixer.Info -> when (info) { PirateRadioClient.minecraftAudioDevice -> Text.translatable("pirate-radio.device.system-matching-minecraft") @@ -119,7 +215,7 @@ class FmReceiverScreen : Screen(Text.translatable("pirate-radio.fm-receiver")) { PirateRadioClient.audioDevice = it } - private val buttons = arrayOf( + private val buttons = arrayListOf<ClickableWidget>( frequencyPlusWidget, frequencyMinusWidget, volumePlusWidget, volumeMinusWidget, toggleModes, audioDevice ) @@ -134,13 +230,8 @@ class FmReceiverScreen : Screen(Text.translatable("pirate-radio.fm-receiver")) { } if (failure == null) { try { + setBaseLayout(0) instance!!.export("init").apply() - addDrawableChild(frequencyPlusWidget) - addDrawableChild(frequencyMinusWidget) - addDrawableChild(volumePlusWidget) - addDrawableChild(volumeMinusWidget) - addDrawableChild(toggleModes) - addDrawableChild(audioDevice) } catch (e: ChicoryException) { failure = WasmScreenException("Skin failed to initialize", e) logger.error("Failed to initialize.", failure) @@ -342,6 +433,51 @@ class FmReceiverScreen : Screen(Text.translatable("pirate-radio.fm-receiver")) { private fun getHeight(): Int = height + private fun setBaseLayout(layout: Int) { + when (layout) { + 0 -> { + clearChildren() + addDrawableChild(frequencyPlusWidget) + addDrawableChild(frequencyMinusWidget) + addDrawableChild(volumePlusWidget) + addDrawableChild(volumeMinusWidget) + addDrawableChild(toggleModes) + addDrawableChild(audioDevice) + buttons.clear() + buttons.addAll( + listOf( + frequencyPlusWidget, + frequencyMinusWidget, + volumePlusWidget, + volumeMinusWidget, + toggleModes, + audioDevice + ) + ) + } + + 1 -> { + clearChildren() + frequencySlider = makeFrequencySlider( + frequencySlider.x, + frequencySlider.y, + frequencySlider.width, + frequencySlider.height + ) + volumeSlider = makeVolumeSlider(volumeSlider.x, volumeSlider.y, volumeSlider.width, volumeSlider.height) + addDrawableChild(frequencySlider) + addDrawableChild(volumeSlider) + addDrawableChild(cycleModes) + addDrawableChild(audioDevice) + cycleModes.value = PirateRadioClient.mode + buttons.clear() + buttons.addAll(listOf(frequencySlider, volumeSlider, cycleModes, audioDevice)) + } + + else -> throw WasmScreenException("Invalid base layout: $layout", null) + } + } + // useful for drawing the stereo pilot, not that it's implemented private fun drawImage( red: Float, green: Float, blue: Float, alpha: Float, x: Int, y: Int, u: Float, v: Float, w: Int, h: Int @@ -478,6 +614,11 @@ class FmReceiverScreen : Screen(Text.translatable("pirate-radio.fm-receiver")) { ) importValues.addFunction( bindFunc( + "buttons", "set-base-layout", lookup, this::setBaseLayout.javaMethod!!, this + ) + ) + importValues.addFunction( + bindFunc( "simulator", "get-frequency", lookup, this::getFrequency.javaMethod!!, this ) ) |