Skip to content

Commit

Permalink
整理SettingsV2功能,增加快速重置按钮
Browse files Browse the repository at this point in the history
  • Loading branch information
way-zer committed Dec 22, 2024
1 parent d937d09 commit 3f7d6ca
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 132 deletions.
29 changes: 13 additions & 16 deletions src/mindustryX/features/ArcRadar.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import arc.scene.event.*;
import arc.scene.ui.layout.*;
import arc.util.*;
import kotlin.collections.*;
import mindustry.game.*;
import mindustry.gen.*;
import mindustry.graphics.*;
Expand All @@ -16,7 +17,7 @@
import mindustryX.features.SettingsV2.*;
import mindustryX.features.func.*;

import java.util.*;
import java.util.List;

import static mindustry.Vars.*;

Expand Down Expand Up @@ -46,23 +47,19 @@ public class ArcRadar{
private static boolean working = false;
private static Table t;

private static SettingsV2.SliderPref mode, size;
public static List<ISetting> settings = new ArrayList<>();
private static final SettingsV2.Data<Integer>
mode = new SliderPref(1, 30, 1, s -> switch(s){
case 0 -> "关闭";
case 30 -> "瞬间完成";
default -> "[lightgray]x[white]" + Strings.autoFixed(s * 0.2f, 1) + "倍搜索速度";
}).create("radarMode", 1),
size = new SliderPref(0, 50, 1, s -> {
if(s == 0) return "固定大小";
return "[lightgray]x[white]" + Strings.autoFixed(s * 0.1f, 1) + "倍";
}).create("radarSize", 0);
public static List<SettingsV2.Data<?>> settings = CollectionsKt.listOf(mode, size);

static{
mode = new SliderPref("radarMode", 1, 1, 30, 1);
mode.setLabelMap(s -> switch(s){
case 0 -> "关闭";
case 30 -> "瞬间完成";
default -> "[lightgray]x[white]" + Strings.autoFixed(s * 0.2f, 1) + "倍搜索速度";
});
settings.add(mode);
size = new SliderPref("radarSize", 0, 0, 50, 1);
size.setLabelMap(s -> {
if(s == 0) return "固定大小";
return "[lightgray]x[white]" + Strings.autoFixed(s * 0.1f, 1) + "倍";
});
settings.add(size);
Events.on(EventType.WorldLoadEvent.class, event -> scanTime = Math.max(Mathf.dst(world.width(), world.height()) / 20f, 7.5f));
}

Expand Down
6 changes: 3 additions & 3 deletions src/mindustryX/features/AutoFill.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ object AutoFill {
@JvmField
var enable = false
private val transferredThisTick = mutableSetOf<Building>()
val cooldown = SettingsV2.SliderPref("autoFill.cooldown", 300, 0, 3000, 100)
val minFill = SettingsV2.SliderPref("autoFill.minFill", 5, 1, 20, 1)
val fillStorageBlock = SettingsV2.CheckPref("autoFill.fillStorageBlock")
val cooldown = SettingsV2.SliderPref(0, 3000, 100).create("autoFill.cooldown", 300)
val minFill = SettingsV2.SliderPref(1, 20, 1).create("autoFill.minFill", 5)
val fillStorageBlock = SettingsV2.CheckPref.create("autoFill.fillStorageBlock")
val settings = listOf(cooldown, minFill, fillStorageBlock)
private var timer = Interval()

Expand Down
215 changes: 106 additions & 109 deletions src/mindustryX/features/SettingsV2.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package mindustryX.features

import arc.Core
import arc.input.KeyCode
import arc.scene.Element
import arc.scene.event.ClickListener
import arc.scene.event.InputEvent
import arc.scene.event.Touchable
Expand All @@ -13,6 +12,7 @@ import arc.util.Log
import arc.util.Reflect
import arc.util.Time
import mindustry.Vars
import mindustry.gen.Icon
import mindustry.ui.Styles
import mindustry.ui.dialogs.BaseDialog

Expand All @@ -21,154 +21,152 @@ import mindustry.ui.dialogs.BaseDialog
* 接口与Core.settings解耦,所有设置项将在实例化时读取
* 所有读取修改应该通过value字段进行
*/
object SettingsV2 {
val ALL = mutableMapOf<String, ISetting>()

interface ISetting {
var changed: Boolean
val name: String
fun load()
fun build(table: Table)
}
object SettingsV2 {
data class Data<T>(val name: String, val def: T, val ext: SettingExt<T>, var persistentProvider: PersistentProvider? = PersistentProvider.Arc) {
private val changedSet = mutableSetOf<String>()
var value: T = def
set(value) {
val v = ext.transformValue(value)
if (v == field) return
field = value
persistentProvider?.set(name, value)
changedSet.clear()
}

abstract class BaseSetting : ISetting {
//所有子类都有 value, def字段,因为泛型涉及到包装,此处不声明
override var changed: Boolean = true
get() {
if (!field) return false
field = false
return field
init {
if (name in ALL)
Log.warn("Settings initialized!: $name")
ALL[name] = this
persistentProvider?.run {
value = get(name, def)
}
}

@JvmOverloads
fun changed(name: String = "DEFAULT"): Boolean {
return changedSet.add(name)
}

//util
protected val title get() = Core.bundle.get("setting.${name}.name", name)
protected fun Element.addDesc() {
val desc = Core.bundle.getOrNull("setting.${name}.description") ?: return
Vars.ui.addDescTooltip(this, desc)
val title: String get() = Core.bundle.get("setting.${name}.name", name)
fun resetDefault() {
persistentProvider?.reset(name)
value = def
}

fun buildUI(table: Table) {
Table().apply {
button(Icon.undo, Styles.clearNonei) { resetDefault() }.tooltip("@settings.reset")
.fillY().disabled { value == def }
ext.build(this@Data, this)

Core.bundle.getOrNull("setting.${name}.description")?.let {
Vars.ui.addDescTooltip(this, it)
}
table.add(this).left().row()
}
}
}

data class CheckPref(override val name: String, val def: Boolean = false) : BaseSetting() {
var value = def
set(value) {
if (value == field) return
field = value
sealed interface PersistentProvider {
fun <T> get(name: String, def: T): T
fun <T> set(name: String, value: T)
fun reset(name: String)

data object Arc : PersistentProvider {
override fun <T> get(name: String, def: T): T {
@Suppress("UNCHECKED_CAST")
return Core.settings.get(name, def) as T
}

override fun <T> set(name: String, value: T) {
Core.settings.put(name, value)
changed = true
}

override fun load() {
value = Core.settings.getBool(name, def)
override fun reset(name: String) {
Core.settings.remove(name)
}
}
}

override fun build(table: Table) {
val box = CheckBox(title)
box.changed { value = box.isChecked }
box.update { box.isChecked = value }
box.addDesc()
table.add(box).left().padTop(3f).row()
}
sealed interface SettingExt<T> {
fun transformValue(value: T): T = value
fun build(s: Data<T>, table: Table)

init {
register()
}
//util
fun create(name: String, def: T) = Data(name, def, this)
fun create(name: String, def: T, persistentProvider: PersistentProvider?) = Data(name, def, this, persistentProvider)
}

data class SliderPref(override val name: String, val def: Int, val min: Int, val max: Int, val step: Int = 1) : BaseSetting() {
var value = def
set(value) {
field = value.coerceIn(min, max)
Core.settings.put(name, field)
changed = true
}
var labelMap: (Int) -> String = { it.toString() }

override fun load() {
value = Core.settings.getInt(name, def)
data object CheckPref : SettingExt<Boolean> {
override fun build(s: Data<Boolean>, table: Table) {
val box = CheckBox(s.title)
box.changed { s.value = box.isChecked }
box.update { box.isChecked = s.value }
table.add(box).left().padTop(3f)
}

override fun build(table: Table) {
fun create(name: String) = create(name, false)
}

data class SliderPref @JvmOverloads constructor(val min: Int, val max: Int, val step: Int = 1, val labelMap: (Int) -> String = { it.toString() }) : SettingExt<Int> {
override fun transformValue(value: Int): Int = value.coerceIn(min, max)
override fun build(s: Data<Int>, table: Table) {
val elem = Slider(min.toFloat(), max.toFloat(), step.toFloat(), false)
elem.changed { value = elem.value.toInt() }
elem.update { elem.value = value.toFloat() }
elem.changed { s.value = elem.value.toInt() }
elem.update { elem.value = s.value.toFloat() }

val content = Table().apply {
touchable = Touchable.disabled
add(title, Styles.outlineLabel).left().growX().wrap()
label { labelMap(value) }.style(Styles.outlineLabel).padLeft(10f).right().get()
add(s.title, Styles.outlineLabel).left().growX().wrap()
label { labelMap(s.value) }.style(Styles.outlineLabel).padLeft(10f).right().get()
}

table.stack(elem, content).minWidth(220f).growX().padTop(4f)
.also { it.get().addDesc() }.row()
}

init {
register()
}
}

data class ChoosePref(
override val name: String, val values: List<String>, val def: Int = 0,
private val impl: SliderPref = SliderPref(name, def, 0, values.size - 1).apply {
labelMap = { values[it] }
}
) : ISetting by impl

data class TextPref(override val name: String, val def: String = "", val area: Boolean = false) : BaseSetting() {
var value = def
set(value) {
field = value
Core.settings.put(name, value)
changed = true
}
val values: List<String>,
private val impl: SliderPref = SliderPref(0, values.size, labelMap = { values[it] })
) : SettingExt<Int> by impl

override fun load() {
value = Core.settings.getString(name, def)
}

override fun build(table: Table) {
if (area) {
val elem = TextArea("")
elem.setPrefRows(5f)
elem.changed { value = elem.text }
elem.update { elem.text = value }
table.add(title).left().padTop(3f).get().addDesc()
table.row().add(elem).fillX().row()
return
}
data object TextPref : SettingExt<String> {
override fun transformValue(value: String): String = value.trim()
override fun build(s: Data<String>, table: Table) {
val elem = TextField()
elem.changed { value = elem.text }
elem.update { elem.text = value }
elem.changed { s.value = elem.text }
elem.update { elem.text = s.value }

table.table().left().padTop(3f).fillX().get().apply {
add(title).padRight(8f)
add(s.title).padRight(8f)
add(elem).growX()
}.addDesc()
table.row()
}
}
}

init {
register()
data object TextAreaPref : SettingExt<String> {
override fun transformValue(value: String): String = value.trim()
override fun build(s: Data<String>, table: Table) {
val elem = TextArea("")
elem.setPrefRows(5f)
elem.changed { s.value = elem.text }
elem.update { elem.text = s.value }
table.add(s.title).left().padTop(3f)
table.row().add(elem).colspan(2).fillX()
}
}

fun ISetting.register() {
if (name in ALL)
Log.warn("Settings initialized!: $name")
ALL[name] = this
load()
}
val ALL = LinkedHashMap<String, Data<*>>()

class SettingDialog(val settings: List<ISetting>) : BaseDialog("@settings") {
class SettingDialog(val settings: Iterable<Data<*>>) : BaseDialog("@settings") {
init {
cont.add(Table().also {
settings.forEach { s -> s.build(it) }
cont.add(Table().also { t ->
settings.forEach { it.buildUI(t) }
}).fill().row()
cont.button("@settings.reset") {
settings.forEach {
Core.settings.remove(it.name)
it.load()
}
settings.forEach { it.resetDefault() }
}
addCloseButton()
closeOnBack()
Expand All @@ -177,7 +175,7 @@ object SettingsV2 {
fun showFloatPanel(x: Float, y: Float) {
val table = Table().apply {
background(Styles.black8).margin(8f)
settings.forEach { s -> s.build(this) }
settings.forEach { it.buildUI(this) }
button("@close") { this.remove() }.fillX()
}
Core.scene.add(table)
Expand All @@ -187,9 +185,8 @@ object SettingsV2 {
}
}


@JvmStatic
fun bindQuickSettings(button: Button, settings: List<ISetting>) {
fun bindQuickSettings(button: Button, settings: Iterable<Data<*>>) {
button.removeListener(button.clickListener)
Reflect.set(Button::class.java, button, "clickListener", object : ClickListener() {
private var startTime: Long = Long.MAX_VALUE
Expand Down
4 changes: 3 additions & 1 deletion src/mindustryX/features/UIExt.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public class UIExt{
public static WaveInfoDisplay waveInfoDisplay = new WaveInfoDisplay();
public static NewCoreItemsDisplay coreItems = new NewCoreItemsDisplay();

public static SettingsV2.Data<Integer> quickToolOffset = new SettingsV2.SliderPref(-250, 250, 10).create("quickToolOffset", 0);

public static void init(){
teamSelect = new TeamSelectDialog();

Expand All @@ -41,7 +43,7 @@ public static void init(){

ui.hudGroup.fill(t -> {
t.right().name = "quickTool";
t.update(() -> t.y = Core.settings.getInt("quickToolOffset"));
t.update(() -> t.y = quickToolOffset.getValue());
t.add(auxiliaryTools.wrapped()).growX().row();
t.add(hudSettingsTable.wrapped()).growX().row();
t.add(advanceToolTable.wrapped()).growX().row();
Expand Down
2 changes: 1 addition & 1 deletion src/mindustryX/features/ui/WaveInfoDisplay.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
import static mindustry.Vars.*;

public class WaveInfoDisplay extends Table{
public static SettingsV2.CheckPref enable = new CheckPref("newWaveInfoDisplay", true);
public static SettingsV2.Data<Boolean> enable = CheckPref.INSTANCE.create("newWaveInfoDisplay", true);
public static final float fontScl = 0.8f;
private int waveOffset = 0;
private final WaveInfoDialog waveInfoDialog = new WaveInfoDialog();
Expand Down
4 changes: 2 additions & 2 deletions src/mindustryX/features/ui/toolTable/HudSettingsTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,8 @@ protected void rebuild(){
checkPref("blockWeaponTargetLine");
checkPref("unitbuildplan");
sliderPref("minimapSize", 40, 400, 10, i -> i + "");
sliderPref("quickToolOffset", -250, 250, 10, i -> i + "");
WaveInfoDisplay.enable.build(this);
UIExt.quickToolOffset.buildUI(this);
WaveInfoDisplay.enable.buildUI(this);
}

private void arcQuickMsgTable(){
Expand Down

0 comments on commit 3f7d6ca

Please sign in to comment.