mirror of
https://github.com/Anuken/Mindustry.git
synced 2026-10-02 11:10:50 +03:00
Improve sound selector UI
This commit is contained in:
@@ -2,6 +2,7 @@ package mindustry.logic;
|
||||
|
||||
import arc.*;
|
||||
import arc.audio.*;
|
||||
import arc.files.*;
|
||||
import arc.func.*;
|
||||
import arc.graphics.*;
|
||||
import arc.scene.style.*;
|
||||
@@ -2367,6 +2368,20 @@ public class LStatements{
|
||||
|
||||
@RegisterStatement("playsound")
|
||||
public static class PlaySoundStatement extends LStatement{
|
||||
private static @Nullable Sound lastPreview;
|
||||
|
||||
private static class SoundChoice{
|
||||
final String category;
|
||||
final String name;
|
||||
final Sound sound;
|
||||
|
||||
SoundChoice(String category, String name, Sound sound){
|
||||
this.category = category;
|
||||
this.name = name;
|
||||
this.sound = sound;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean positional;
|
||||
public String id = "@sfx-shoot", volume = "1", pitch = "1", pan = "0", x = "@thisx", y = "@thisy", limit = "true";
|
||||
|
||||
@@ -2385,21 +2400,7 @@ public class LStatements{
|
||||
|
||||
table.button(b -> {
|
||||
b.image(Icon.pencilSmall);
|
||||
|
||||
Seq<String> soundNames = new Seq<>();
|
||||
|
||||
for(var entry : Core.assets.getAllEntries(Sound.class, new Seq<>())){
|
||||
if(entry.value != Sounds.none && entry.value.file != null){
|
||||
soundNames.add(Strings.getFileNameWithoutExtension(entry.key));
|
||||
}
|
||||
}
|
||||
soundNames.sort();
|
||||
|
||||
String soundName = id.startsWith("@sfx-") ? id.substring(5) : id;
|
||||
b.clicked(() -> showSelect(b, soundNames.toArray(String.class), soundName, t -> {
|
||||
id = "@sfx-" + t;
|
||||
build(table);
|
||||
}, 3, cell -> cell.size(170, 50)));
|
||||
b.clicked(() -> showSoundSelect(b, table));
|
||||
}, Styles.logict, () -> {}).size(40).color(table.color).left().padLeft(-1);
|
||||
|
||||
row(table);
|
||||
@@ -2436,6 +2437,122 @@ public class LStatements{
|
||||
public LCategory category(){
|
||||
return LCategory.world;
|
||||
}
|
||||
|
||||
private void showSoundSelect(Button button, Table table){
|
||||
Seq<SoundChoice> choices = new Seq<>();
|
||||
ObjectMap<String, Seq<SoundChoice>> categories = new ObjectMap<>();
|
||||
|
||||
for(var entry : Core.assets.getAllEntries(Sound.class, new Seq<>())){
|
||||
Sound sound = entry.value;
|
||||
if(sound == Sounds.none || sound.file == null) continue;
|
||||
|
||||
String name = sound.file.nameWithoutExtension();
|
||||
Fi parent = sound.file.parent();
|
||||
String category = parent == null ? "other" : parent.name();
|
||||
|
||||
SoundChoice choice = new SoundChoice(category, name, sound);
|
||||
choices.add(choice);
|
||||
categories.get(category, Seq::new).add(choice);
|
||||
}
|
||||
|
||||
if(choices.isEmpty()) return;
|
||||
|
||||
choices.sort((a, b) -> {
|
||||
int cmp = a.category.compareTo(b.category);
|
||||
return cmp == 0 ? a.name.compareTo(b.name) : cmp;
|
||||
});
|
||||
|
||||
Seq<String> categoryNames = categories.keys().toSeq().sort();
|
||||
categoryNames.insert(0, "all");
|
||||
|
||||
for(var seq : categories.values()){
|
||||
seq.sort((a, b) -> a.name.compareTo(b.name));
|
||||
}
|
||||
|
||||
String current = id.startsWith("@sfx-") ? id.substring(5) : id;
|
||||
String currentCategory = "all";
|
||||
for(var choice : choices){
|
||||
if(choice.name.equals(current)){
|
||||
currentCategory = choice.category;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
final String selectedCurrentCategory = currentCategory;
|
||||
|
||||
showSelectTable(button, (root, hide) -> {
|
||||
root.left().top();
|
||||
|
||||
String[] selectedCategory = {categories.containsKey(selectedCurrentCategory) ? selectedCurrentCategory : "all"};
|
||||
Table soundList = new Table();
|
||||
ButtonGroup<Button> tabGroup = new ButtonGroup<>();
|
||||
|
||||
Runnable rebuild = () -> {
|
||||
soundList.clearChildren();
|
||||
soundList.defaults().left().pad(2f);
|
||||
soundList.top();
|
||||
|
||||
Seq<SoundChoice> visible = new Seq<>();
|
||||
if("all".equals(selectedCategory[0])){
|
||||
visible.addAll(choices);
|
||||
}else{
|
||||
visible.addAll(categories.get(selectedCategory[0], Seq::new));
|
||||
}
|
||||
|
||||
if(visible.isEmpty()){
|
||||
soundList.add("[lightgray]No sounds in this category.").pad(8f);
|
||||
return;
|
||||
}
|
||||
|
||||
for(var choice : visible){
|
||||
soundList.table(row -> {
|
||||
row.left().top();
|
||||
row.defaults().left();
|
||||
|
||||
row.button(Icon.play, Styles.cleari, 28f, () -> previewSound(choice.sound)).size(40f).padRight(6f);
|
||||
|
||||
String label = "all".equals(selectedCategory[0]) ? choice.category + "/" + choice.name : choice.name;
|
||||
row.button(label, Styles.logicTogglet, () -> {
|
||||
id = "@sfx-" + choice.name;
|
||||
build(table);
|
||||
hide.run();
|
||||
}).growX().left().checked(choice.name.equals(current)).padRight(4f).minWidth(540f);
|
||||
}).growX().padBottom(3f).minWidth(620f).row();
|
||||
}
|
||||
};
|
||||
|
||||
root.table(tabs -> {
|
||||
tabs.left().top();
|
||||
tabs.defaults().size(140f, 34f).left();
|
||||
|
||||
for(String category : categoryNames){
|
||||
String label = "all".equals(category) ? "all" : Strings.capitalize(category);
|
||||
tabs.button(label, Styles.logicTogglet, () -> {
|
||||
selectedCategory[0] = category;
|
||||
rebuild.run();
|
||||
}).checked(selectedCategory[0].equals(category)).group(tabGroup).growX().row();
|
||||
}
|
||||
}).top().left().width(160f).padRight(10f);
|
||||
|
||||
root.add(soundList).top().width(720f);
|
||||
rebuild.run();
|
||||
});
|
||||
}
|
||||
|
||||
private static void previewSound(Sound sound){
|
||||
if(sound == null || sound == Sounds.none) return;
|
||||
|
||||
if(lastPreview != null && lastPreview.countPlaying() > 0){
|
||||
lastPreview.stop();
|
||||
}
|
||||
|
||||
lastPreview = sound;
|
||||
|
||||
var bus = sound.bus;
|
||||
sound.bus = control.sound.uiBus;
|
||||
sound.play();
|
||||
sound.bus = bus;
|
||||
}
|
||||
}
|
||||
|
||||
@RegisterStatement("playmusic")
|
||||
|
||||
Reference in New Issue
Block a user