mirror of
https://github.com/soarqin/DSP_Mods.git
synced 2025-12-08 21:33:28 +08:00
UXAssist: Work in progress
This commit is contained in:
86
UXAssist/UI/MyCheckbox.cs
Normal file
86
UXAssist/UI/MyCheckbox.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
using BepInEx.Configuration;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace UXAssist.UI;
|
||||
|
||||
// MyCheckBox modified from LSTM: https://github.com/hetima/DSP_LSTM/blob/main/LSTM/MyCheckBox.cs
|
||||
public class MyCheckBox : MonoBehaviour
|
||||
{
|
||||
public UIButton uiButton;
|
||||
public Image checkImage;
|
||||
public RectTransform rectTrans;
|
||||
public Text labelText;
|
||||
public event Action OnChecked;
|
||||
private bool _checked;
|
||||
private ConfigEntry<bool> _configAssigned;
|
||||
|
||||
public bool Checked
|
||||
{
|
||||
get => _checked;
|
||||
set
|
||||
{
|
||||
_checked = value;
|
||||
checkImage.enabled = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static MyCheckBox CreateCheckBox(float x, float y, RectTransform parent, ConfigEntry<bool> config, string label = "", int fontSize = 15)
|
||||
{
|
||||
var cb = CreateCheckBox(x, y, parent, config.Value, label, fontSize);
|
||||
cb._configAssigned = config;
|
||||
cb.OnChecked += () => config.Value = !config.Value;
|
||||
config.SettingChanged += (_, _) => cb.Checked = config.Value;
|
||||
return cb;
|
||||
}
|
||||
|
||||
public static MyCheckBox CreateCheckBox(float x, float y, RectTransform parent, bool check, string label = "", int fontSize = 15)
|
||||
{
|
||||
var buildMenu = UIRoot.instance.uiGame.buildMenu;
|
||||
var src = buildMenu.uxFacilityCheck;
|
||||
|
||||
var go = Instantiate(src.gameObject);
|
||||
go.name = "my-checkbox";
|
||||
var cb = go.AddComponent<MyCheckBox>();
|
||||
cb._checked = check;
|
||||
var rect = Util.NormalizeRectWithTopLeft(cb, x, y, parent);
|
||||
|
||||
cb.rectTrans = rect;
|
||||
cb.uiButton = go.GetComponent<UIButton>();
|
||||
cb.checkImage = go.transform.Find("checked")?.GetComponent<Image>();
|
||||
|
||||
var child = go.transform.Find("text");
|
||||
if (child != null)
|
||||
{
|
||||
DestroyImmediate(child.GetComponent<Localizer>());
|
||||
cb.labelText = child.GetComponent<Text>();
|
||||
cb.labelText.fontSize = fontSize;
|
||||
cb.SetLabelText(label);
|
||||
}
|
||||
|
||||
//value
|
||||
cb.uiButton.onClick += cb.OnClick;
|
||||
if (cb.checkImage != null)
|
||||
{
|
||||
cb.checkImage.enabled = check;
|
||||
}
|
||||
|
||||
return cb;
|
||||
}
|
||||
|
||||
public void SetLabelText(string val)
|
||||
{
|
||||
if (labelText != null)
|
||||
{
|
||||
labelText.text = val.Translate();
|
||||
}
|
||||
}
|
||||
|
||||
public void OnClick(int obj)
|
||||
{
|
||||
_checked = !_checked;
|
||||
checkImage.enabled = _checked;
|
||||
OnChecked?.Invoke();
|
||||
}
|
||||
}
|
||||
64
UXAssist/UI/MyConfigWindow.cs
Normal file
64
UXAssist/UI/MyConfigWindow.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UXAssist.Common;
|
||||
|
||||
namespace UXAssist.UI;
|
||||
|
||||
public class MyConfigWindow : MyWindowWithTabs
|
||||
{
|
||||
public static Action<MyConfigWindow, RectTransform> OnUICreated;
|
||||
public static Action OnUpdateUI;
|
||||
|
||||
private RectTransform _windowTrans;
|
||||
|
||||
public static MyConfigWindow CreateInstance()
|
||||
{
|
||||
return MyWindowManager.CreateWindow<MyConfigWindow>("UXAConfigWindow", "UXAssist Config");
|
||||
}
|
||||
|
||||
public override void _OnCreate()
|
||||
{
|
||||
_windowTrans = GetComponent<RectTransform>();
|
||||
_windowTrans.sizeDelta = new Vector2(680f, 420f);
|
||||
|
||||
OnUICreated?.Invoke(this, _windowTrans);
|
||||
SetCurrentTab(0);
|
||||
OnUpdateUI?.Invoke();
|
||||
}
|
||||
|
||||
public override void _OnDestroy()
|
||||
{
|
||||
}
|
||||
|
||||
public override bool _OnInit()
|
||||
{
|
||||
_windowTrans.anchoredPosition = new Vector2(0, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void _OnFree()
|
||||
{
|
||||
}
|
||||
|
||||
public override void _OnOpen()
|
||||
{
|
||||
}
|
||||
|
||||
public override void _OnClose()
|
||||
{
|
||||
}
|
||||
|
||||
public override void _OnUpdate()
|
||||
{
|
||||
base._OnUpdate();
|
||||
if (VFInput.escape && !VFInput.inputing)
|
||||
{
|
||||
VFInput.UseEscape();
|
||||
_Close();
|
||||
return;
|
||||
}
|
||||
|
||||
OnUpdateUI?.Invoke();
|
||||
}
|
||||
}
|
||||
231
UXAssist/UI/MyKeyBinder.cs
Normal file
231
UXAssist/UI/MyKeyBinder.cs
Normal file
@@ -0,0 +1,231 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using BepInEx.Configuration;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace UXAssist.UI;
|
||||
|
||||
// MyKeyBinder modified from LSTM: https://github.com/hetima/DSP_LSTM/blob/main/LSTM/MyKeyBinder.cs
|
||||
public class MyKeyBinder : MonoBehaviour
|
||||
{
|
||||
private ConfigEntry<KeyboardShortcut> _config;
|
||||
|
||||
[SerializeField]
|
||||
public Text functionText;
|
||||
|
||||
[SerializeField]
|
||||
public Text keyText;
|
||||
|
||||
[SerializeField]
|
||||
public InputField setTheKeyInput;
|
||||
|
||||
[SerializeField]
|
||||
public Toggle setTheKeyToggle;
|
||||
|
||||
[SerializeField]
|
||||
public RectTransform rectTrans;
|
||||
|
||||
[SerializeField]
|
||||
public UIButton inputUIButton;
|
||||
|
||||
[SerializeField]
|
||||
public Text conflictText;
|
||||
|
||||
[SerializeField]
|
||||
public Text waitingText;
|
||||
|
||||
[SerializeField]
|
||||
public UIButton setDefaultUIButton;
|
||||
|
||||
[SerializeField]
|
||||
public UIButton setNoneKeyUIButton;
|
||||
|
||||
private bool _nextNotOn;
|
||||
|
||||
public static RectTransform CreateKeyBinder(float x, float y, RectTransform parent, ConfigEntry<KeyboardShortcut> config, string label = "", int fontSize = 17)
|
||||
{
|
||||
var optionWindow = UIRoot.instance.optionWindow;
|
||||
var uikeyEntry = Instantiate(optionWindow.entryPrefab);
|
||||
GameObject go;
|
||||
(go = uikeyEntry.gameObject).SetActive(true);
|
||||
go.name = "my-keybinder";
|
||||
var kb = go.AddComponent<MyKeyBinder>();
|
||||
kb._config = config;
|
||||
|
||||
kb.functionText = uikeyEntry.functionText;
|
||||
kb.keyText = uikeyEntry.keyText;
|
||||
kb.setTheKeyInput = uikeyEntry.setTheKeyInput;
|
||||
kb.setTheKeyToggle = uikeyEntry.setTheKeyToggle;
|
||||
kb.rectTrans = uikeyEntry.rectTrans;
|
||||
kb.inputUIButton = uikeyEntry.inputUIButton;
|
||||
kb.conflictText = uikeyEntry.conflictText;
|
||||
kb.waitingText = uikeyEntry.waitingText;
|
||||
kb.setDefaultUIButton = uikeyEntry.setDefaultUIButton;
|
||||
kb.setNoneKeyUIButton = uikeyEntry.setNoneKeyUIButton;
|
||||
|
||||
|
||||
kb.functionText.text = label.Translate();
|
||||
kb.functionText.fontSize = 17;
|
||||
|
||||
((RectTransform)kb.keyText.transform).anchoredPosition = new Vector2(20f, -27f);
|
||||
//kb.keyText.alignment = TextAnchor.MiddleRight;
|
||||
kb.keyText.fontSize = 17;
|
||||
((RectTransform)kb.inputUIButton.transform.parent.transform).anchoredPosition = new Vector2(0f + 20f, -57f);
|
||||
((RectTransform)kb.setDefaultUIButton.transform).anchoredPosition = new Vector2(140f + 20f, -57f);
|
||||
((RectTransform)kb.setNoneKeyUIButton.transform).anchoredPosition = new Vector2(240f + 20f, -57f);
|
||||
|
||||
var rect = Util.NormalizeRectWithTopLeft(kb, x, y, parent);
|
||||
kb.rectTrans = rect;
|
||||
|
||||
//rect.sizeDelta = new Vector2(240f, 64f);
|
||||
Destroy(uikeyEntry);
|
||||
kb.setNoneKeyUIButton.gameObject.SetActive(false);
|
||||
|
||||
kb.SettingChanged();
|
||||
config.SettingChanged += (_, _) => {
|
||||
kb.SettingChanged();
|
||||
};
|
||||
kb.inputUIButton.onClick += kb.OnInputUIButtonClick;
|
||||
kb.setDefaultUIButton.onClick += kb.OnSetDefaultKeyClick;
|
||||
//kb.setNoneKeyUIButton.onClick += kb.OnSetNoneKeyClick;
|
||||
return go.transform as RectTransform;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!setTheKeyToggle.isOn && inputUIButton.highlighted)
|
||||
{
|
||||
setTheKeyToggle.isOn = true;
|
||||
}
|
||||
|
||||
if (!setTheKeyToggle.isOn) return;
|
||||
if (!inputUIButton._isPointerEnter && Input.GetKeyDown(KeyCode.Mouse0))
|
||||
{
|
||||
inputUIButton.highlighted = false;
|
||||
setTheKeyToggle.isOn = false;
|
||||
Reset();
|
||||
}
|
||||
else if (!this.inputUIButton.highlighted)
|
||||
{
|
||||
setTheKeyToggle.isOn = false;
|
||||
Reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
waitingText.gameObject.SetActive(true);
|
||||
if (!TrySetValue()) return;
|
||||
setTheKeyToggle.isOn = false;
|
||||
inputUIButton.highlighted = false;
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public bool TrySetValue()
|
||||
{
|
||||
if (Input.GetKey(KeyCode.Escape))
|
||||
{
|
||||
VFInput.UseEscape();
|
||||
return true;
|
||||
}
|
||||
if (Input.GetKey(KeyCode.Mouse0) || Input.GetKey(KeyCode.Mouse1))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
var anyKey = GetIunptKeys();
|
||||
if (anyKey || _lastKey == KeyCode.None) return false;
|
||||
var k = GetPressedKey();
|
||||
if (string.IsNullOrEmpty(k))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
_lastKey = KeyCode.None;
|
||||
|
||||
_config.Value = KeyboardShortcut.Deserialize(k);
|
||||
//keyText.text = k;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
private KeyCode _lastKey;
|
||||
private static readonly KeyCode[] ModKeys = { KeyCode.RightShift, KeyCode.LeftShift,
|
||||
KeyCode.RightControl, KeyCode.LeftControl,
|
||||
KeyCode.RightAlt, KeyCode.LeftAlt,
|
||||
KeyCode.LeftCommand, KeyCode.LeftApple, KeyCode.LeftWindows,
|
||||
KeyCode.RightCommand, KeyCode.RightApple, KeyCode.RightWindows };
|
||||
|
||||
public string GetPressedKey()
|
||||
{
|
||||
var key = _lastKey.ToString();
|
||||
if (string.IsNullOrEmpty(key))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var mod = "";
|
||||
foreach (var modKey in ModKeys)
|
||||
{
|
||||
if (Input.GetKey(modKey))
|
||||
{
|
||||
mod += "+" + modKey.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(mod))
|
||||
{
|
||||
key += mod;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
//通常キーが押されているかチェック _lastKey に保存
|
||||
public bool GetIunptKeys()
|
||||
{
|
||||
var anyKey = false;
|
||||
|
||||
foreach (KeyCode item in Enum.GetValues(typeof(KeyCode)))
|
||||
{
|
||||
if (item == KeyCode.None || ModKeys.Contains(item) || !Input.GetKey(item)) continue;
|
||||
_lastKey = item;
|
||||
anyKey = true;
|
||||
}
|
||||
return anyKey;
|
||||
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
conflictText.gameObject.SetActive(false);
|
||||
waitingText.gameObject.SetActive(false);
|
||||
setDefaultUIButton.button.Select(); // InputFieldのフォーカス外す
|
||||
_lastKey = KeyCode.None;
|
||||
}
|
||||
|
||||
public void OnInputUIButtonClick(int data)
|
||||
{
|
||||
inputUIButton.highlighted = true;
|
||||
|
||||
if (!_nextNotOn) return;
|
||||
_nextNotOn = false;
|
||||
inputUIButton.highlighted = false;
|
||||
setTheKeyToggle.isOn = false;
|
||||
waitingText.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
public void OnSetDefaultKeyClick(int data)
|
||||
{
|
||||
_config.Value = (KeyboardShortcut)_config.DefaultValue;
|
||||
keyText.text = _config.Value.Serialize();
|
||||
}
|
||||
|
||||
public void OnSetNoneKeyClick(int data)
|
||||
{
|
||||
_config.Value = (KeyboardShortcut)_config.DefaultValue;
|
||||
keyText.text = _config.Value.Serialize();
|
||||
}
|
||||
|
||||
public void SettingChanged()
|
||||
{
|
||||
keyText.text = _config.Value.Serialize();
|
||||
}
|
||||
}
|
||||
123
UXAssist/UI/MySlider.cs
Normal file
123
UXAssist/UI/MySlider.cs
Normal file
@@ -0,0 +1,123 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace UXAssist.UI;
|
||||
|
||||
// MySlider modified from LSTM: https://github.com/hetima/DSP_LSTM/blob/main/LSTM/MySlider.cs
|
||||
|
||||
public class MySlider : MonoBehaviour
|
||||
{
|
||||
public Slider slider;
|
||||
public RectTransform rectTrans;
|
||||
public Text labelText;
|
||||
public string labelFormat;
|
||||
public event Action OnValueChanged;
|
||||
private float _value;
|
||||
public float Value
|
||||
{
|
||||
get => _value;
|
||||
set
|
||||
{
|
||||
_value = value;
|
||||
OnValueSet();
|
||||
}
|
||||
}
|
||||
|
||||
public static RectTransform CreateSlider(float x, float y, RectTransform parent, float value, float minValue, float maxValue, string format = "{0}", float width = 0f)
|
||||
{
|
||||
var optionWindow = UIRoot.instance.optionWindow;
|
||||
var src = optionWindow.audioVolumeComp;
|
||||
|
||||
var go = Instantiate(src.gameObject);
|
||||
//sizeDelta = 240, 20
|
||||
go.name = "my-slider";
|
||||
go.SetActive(true);
|
||||
var sl = go.AddComponent<MySlider>();
|
||||
sl._value = value;
|
||||
var rect = Util.NormalizeRectWithTopLeft(sl, x, y, parent);
|
||||
sl.rectTrans = rect;
|
||||
if (width > 0)
|
||||
{
|
||||
rect.sizeDelta = new Vector2(width, rect.sizeDelta.y);
|
||||
}
|
||||
|
||||
sl.slider = go.GetComponent<Slider>();
|
||||
sl.slider.minValue = minValue;
|
||||
sl.slider.maxValue = maxValue;
|
||||
sl.slider.onValueChanged.RemoveAllListeners();
|
||||
sl.slider.onValueChanged.AddListener(sl.SliderChanged);
|
||||
sl.labelText = sl.slider.handleRect.Find("Text")?.GetComponent<Text>();
|
||||
if (sl.labelText != null)
|
||||
{
|
||||
sl.labelText.fontSize = 14;
|
||||
if (sl.labelText.transform is RectTransform rectTrans)
|
||||
{
|
||||
rectTrans.sizeDelta = new Vector2(22f, 22f);
|
||||
}
|
||||
}
|
||||
sl.labelFormat = format;
|
||||
|
||||
var bg = sl.slider.transform.Find("Background")?.GetComponent<Image>();
|
||||
if (bg != null)
|
||||
{
|
||||
bg.color = new Color(0.5f, 0.5f, 0.5f, 0.5f);
|
||||
}
|
||||
var fill = sl.slider.fillRect.GetComponent<Image>();
|
||||
if (fill != null)
|
||||
{
|
||||
fill.color = new Color(1f, 1f, 1f, 0.28f);
|
||||
}
|
||||
sl.OnValueSet();
|
||||
sl.UpdateLabel();
|
||||
|
||||
return sl.rectTrans;
|
||||
}
|
||||
public void OnValueSet()
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
var sliderVal = _value;
|
||||
if (_value.Equals(slider.value)) return;
|
||||
if (sliderVal > slider.maxValue)
|
||||
{
|
||||
_value = sliderVal = slider.maxValue;
|
||||
}
|
||||
else if (sliderVal < slider.minValue)
|
||||
{
|
||||
_value = sliderVal = slider.minValue;
|
||||
}
|
||||
|
||||
slider.value = sliderVal;
|
||||
UpdateLabel();
|
||||
}
|
||||
}
|
||||
public void UpdateLabel()
|
||||
{
|
||||
if (labelText != null)
|
||||
{
|
||||
labelText.text = _value.ToString(labelFormat);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetLabelText(string text)
|
||||
{
|
||||
if (labelText != null)
|
||||
{
|
||||
labelText.text = text;
|
||||
}
|
||||
}
|
||||
|
||||
public void SliderChanged(float val)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
var newVal = Mathf.Round(slider.value);
|
||||
if (_value.Equals(newVal)) return;
|
||||
_value = newVal;
|
||||
UpdateLabel();
|
||||
OnValueChanged?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
427
UXAssist/UI/MyWindow.cs
Normal file
427
UXAssist/UI/MyWindow.cs
Normal file
@@ -0,0 +1,427 @@
|
||||
using System;
|
||||
using HarmonyLib;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.UI;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace UXAssist.UI;
|
||||
|
||||
// MyWindow modified from LSTM: https://github.com/hetima/DSP_LSTM/blob/main/LSTM/MyWindowCtl.cs
|
||||
|
||||
public class MyWindow: ManualBehaviour
|
||||
{
|
||||
private readonly Dictionary<InputField, Tuple<UnityAction<string>, UnityAction<string>>> _inputFields = new();
|
||||
private readonly Dictionary<UIButton, UnityAction> _buttons = new();
|
||||
protected bool EventRegistered { get; private set; }
|
||||
|
||||
public virtual void TryClose()
|
||||
{
|
||||
_Close();
|
||||
}
|
||||
|
||||
public virtual bool IsWindowFunctional()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Open()
|
||||
{
|
||||
_Open();
|
||||
transform.SetAsLastSibling();
|
||||
}
|
||||
|
||||
public void Close() => _Close();
|
||||
|
||||
public void SetTitle(string title)
|
||||
{
|
||||
var txt = gameObject.transform.Find("panel-bg/title-text")?.gameObject.GetComponent<Text>();
|
||||
if (txt)
|
||||
{
|
||||
txt.text = title.Translate();
|
||||
}
|
||||
}
|
||||
|
||||
private static void AddElement(float x, float y, RectTransform rect, RectTransform parent = null)
|
||||
{
|
||||
if (rect != null)
|
||||
{
|
||||
Util.NormalizeRectWithTopLeft(rect, x, y, parent);
|
||||
}
|
||||
}
|
||||
|
||||
public static Text AddText(float x, float y, RectTransform parent, string label, int fontSize = 14, string objName = "label")
|
||||
{
|
||||
var src = UIRoot.instance.uiGame.assemblerWindow.stateText;
|
||||
var txt = Instantiate(src);
|
||||
txt.gameObject.name = objName;
|
||||
txt.text = label.Translate();
|
||||
txt.color = new Color(1f, 1f, 1f, 0.4f);
|
||||
txt.alignment = TextAnchor.MiddleLeft;
|
||||
txt.fontSize = fontSize;
|
||||
if (txt.transform is RectTransform rect)
|
||||
{
|
||||
rect.sizeDelta = new Vector2(txt.preferredWidth + 40f, 30f);
|
||||
}
|
||||
AddElement(x, y, txt.rectTransform, parent);
|
||||
return txt;
|
||||
}
|
||||
|
||||
public static UIButton AddTipsButton(float x, float y, RectTransform parent, string label, string tip, string content, string objName = "tips-button")
|
||||
{
|
||||
var src = UIRoot.instance.galaxySelect.sandboxToggle.gameObject.transform.parent.Find("tip-button");
|
||||
var dst = Instantiate(src);
|
||||
dst.gameObject.name = objName;
|
||||
var btn = dst.GetComponent<UIButton>();
|
||||
Util.NormalizeRectWithTopLeft(btn, x, y, parent);
|
||||
btn.tips.topLevel = true;
|
||||
btn.tips.tipTitle = label;
|
||||
btn.tips.tipText = tip;
|
||||
btn.UpdateTip();
|
||||
return btn;
|
||||
}
|
||||
|
||||
public UIButton AddButton(float x, float y, RectTransform parent, string text = "", int fontSize = 16, string objName = "button", UnityAction onClick = null)
|
||||
{
|
||||
var panel = UIRoot.instance.uiGame.statWindow.performancePanelUI;
|
||||
var btn = Instantiate(panel.cpuActiveButton);
|
||||
btn.gameObject.name = objName;
|
||||
var rect = Util.NormalizeRectWithTopLeft(btn, x, y, parent);
|
||||
rect.sizeDelta = new Vector2(150, rect.sizeDelta.y);
|
||||
var l = btn.gameObject.transform.Find("button-text").GetComponent<Localizer>();
|
||||
var t = btn.gameObject.transform.Find("button-text").GetComponent<Text>();
|
||||
if (l != null)
|
||||
{
|
||||
l.stringKey = text;
|
||||
l.translation = text.Translate();
|
||||
}
|
||||
if (t != null)
|
||||
{
|
||||
t.text = text.Translate();
|
||||
}
|
||||
t.fontSize = fontSize;
|
||||
btn.button.onClick.RemoveAllListeners();
|
||||
btn.tip = null;
|
||||
btn.tips = new UIButton.TipSettings();
|
||||
_buttons[btn] = onClick;
|
||||
if (EventRegistered)
|
||||
{
|
||||
if (onClick != null)
|
||||
btn.button.onClick.AddListener(onClick);
|
||||
}
|
||||
return btn;
|
||||
}
|
||||
|
||||
public UIButton AddFlatButton(float x, float y, RectTransform parent, string text = "", int fontSize = 12, string objName = "button", UnityAction onClick = null)
|
||||
{
|
||||
var panel = UIRoot.instance.uiGame.dysonEditor.controlPanel.hierarchy.layerPanel;
|
||||
var btn = Instantiate(panel.layerButtons[0]);
|
||||
btn.gameObject.name = objName;
|
||||
btn.highlighted = false;
|
||||
Util.NormalizeRectWithTopLeft(btn, x, y, parent);
|
||||
var t = btn.gameObject.transform.Find("Text").GetComponent<Text>();
|
||||
if (t != null)
|
||||
{
|
||||
t.text = text.Translate();
|
||||
}
|
||||
t.fontSize = fontSize;
|
||||
btn.button.onClick.RemoveAllListeners();
|
||||
_buttons[btn] = onClick;
|
||||
if (EventRegistered)
|
||||
{
|
||||
if (onClick != null)
|
||||
btn.button.onClick.AddListener(onClick);
|
||||
}
|
||||
return btn;
|
||||
}
|
||||
|
||||
protected InputField AddInputField(float x, float y, RectTransform parent, string text = "", int fontSize = 16, string objName = "input", UnityAction<string> onChanged = null, UnityAction<string> onEditEnd = null)
|
||||
{
|
||||
var stationWindow = UIRoot.instance.uiGame.stationWindow;
|
||||
//public InputField nameInput;
|
||||
var inputField = Instantiate(stationWindow.nameInput);
|
||||
inputField.gameObject.name = objName;
|
||||
Destroy(inputField.GetComponent<UIButton>());
|
||||
inputField.GetComponent<Image>().color = new Color(1f, 1f, 1f, 0.05f);
|
||||
var rect = Util.NormalizeRectWithTopLeft(inputField, x, y, parent);
|
||||
rect.sizeDelta = new Vector2(210, rect.sizeDelta.y);
|
||||
inputField.textComponent.text = text;
|
||||
inputField.textComponent.fontSize = fontSize;
|
||||
inputField.onValueChanged.RemoveAllListeners();
|
||||
inputField.onEndEdit.RemoveAllListeners();
|
||||
_inputFields[inputField] = Tuple.Create(onChanged, onEditEnd);
|
||||
if (EventRegistered)
|
||||
{
|
||||
if (onChanged != null)
|
||||
inputField.onValueChanged.AddListener(onChanged);
|
||||
if (onEditEnd != null)
|
||||
inputField.onEndEdit.AddListener(onEditEnd);
|
||||
}
|
||||
return inputField;
|
||||
}
|
||||
|
||||
public override void _OnRegEvent()
|
||||
{
|
||||
base._OnRegEvent();
|
||||
if (EventRegistered) return;
|
||||
foreach (var t in _inputFields)
|
||||
{
|
||||
var inputField = t.Key;
|
||||
if (t.Value.Item1 != null)
|
||||
inputField.onValueChanged.AddListener(t.Value.Item1);
|
||||
if (t.Value.Item2 != null)
|
||||
inputField.onEndEdit.AddListener(t.Value.Item2);
|
||||
}
|
||||
foreach (var t in _buttons)
|
||||
{
|
||||
var btn = t.Key;
|
||||
if (t.Value != null)
|
||||
btn.button.onClick.AddListener(t.Value);
|
||||
}
|
||||
EventRegistered = true;
|
||||
}
|
||||
|
||||
public override void _OnUnregEvent()
|
||||
{
|
||||
base._OnUnregEvent();
|
||||
if (!EventRegistered) return;
|
||||
EventRegistered = false;
|
||||
foreach (var t in _buttons)
|
||||
{
|
||||
var btn = t.Key;
|
||||
if (t.Value != null)
|
||||
btn.button.onClick.RemoveListener(t.Value);
|
||||
}
|
||||
foreach (var t in _inputFields)
|
||||
{
|
||||
var inputField = t.Key;
|
||||
if (t.Value.Item1 != null)
|
||||
inputField.onValueChanged.RemoveListener(t.Value.Item1);
|
||||
if (t.Value.Item2 != null)
|
||||
inputField.onEndEdit.RemoveListener(t.Value.Item2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class MyWindowWithTabs : MyWindow
|
||||
{
|
||||
private readonly List<Tuple<RectTransform, UIButton>> _tabs = new();
|
||||
private float _tabX = 36f;
|
||||
public override void TryClose()
|
||||
{
|
||||
_Close();
|
||||
}
|
||||
|
||||
public override bool IsWindowFunctional()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public RectTransform AddTab(float x, int index, RectTransform parent, string label)
|
||||
{
|
||||
var tab = new GameObject();
|
||||
var tabRect = tab.AddComponent<RectTransform>();
|
||||
Util.NormalizeRectWithMargin(tabRect, 54f + 28f, 36f, 0f, 0f, parent);
|
||||
tab.name = "tab-" + index;
|
||||
var swarmPanel = UIRoot.instance.uiGame.dysonEditor.controlPanel.hierarchy.swarmPanel;
|
||||
var src = swarmPanel.orbitButtons[0];
|
||||
var btn = Instantiate(src);
|
||||
var btnRect = Util.NormalizeRectWithTopLeft(btn, x, 54f, parent);
|
||||
btn.name = "tab-btn-" + index;
|
||||
btnRect.sizeDelta = new Vector2(100f, 24f);
|
||||
btn.transform.Find("frame").gameObject.SetActive(false);
|
||||
if (btn.transitions.Length >= 3)
|
||||
{
|
||||
btn.transitions[0].normalColor = new Color(0.1f, 0.1f, 0.1f, 0.68f);
|
||||
btn.transitions[0].highlightColorOverride = new Color(0.9906f, 0.5897f, 0.3691f, 0.4f);
|
||||
btn.transitions[1].normalColor = new Color(1f, 1f, 1f, 0.6f);
|
||||
btn.transitions[1].highlightColorOverride = new Color(0.2f, 0.1f, 0.1f, 0.9f);
|
||||
}
|
||||
|
||||
var btnText = btn.transform.Find("Text").GetComponent<Text>();
|
||||
btnText.text = label.Translate();
|
||||
btnText.fontSize = 16;
|
||||
btn.data = index;
|
||||
|
||||
_tabs.Add(Tuple.Create(tabRect, btn));
|
||||
if (EventRegistered)
|
||||
{
|
||||
btn.onClick += OnTabButtonClick;
|
||||
}
|
||||
return tabRect;
|
||||
}
|
||||
|
||||
public RectTransform AddTab(RectTransform parent, string label)
|
||||
{
|
||||
var result = AddTab(_tabX, _tabs.Count, parent, label);
|
||||
_tabX += 100f;
|
||||
return result;
|
||||
}
|
||||
|
||||
public override void _OnRegEvent()
|
||||
{
|
||||
if (!EventRegistered)
|
||||
{
|
||||
foreach (var t in _tabs)
|
||||
{
|
||||
t.Item2.onClick += OnTabButtonClick;
|
||||
}
|
||||
}
|
||||
base._OnRegEvent();
|
||||
}
|
||||
|
||||
public override void _OnUnregEvent()
|
||||
{
|
||||
if (EventRegistered)
|
||||
{
|
||||
foreach (var t in _tabs)
|
||||
{
|
||||
t.Item2.onClick -= OnTabButtonClick;
|
||||
}
|
||||
}
|
||||
base._OnUnregEvent();
|
||||
}
|
||||
|
||||
protected void SetCurrentTab(int index) => OnTabButtonClick(index);
|
||||
|
||||
private void OnTabButtonClick(int index)
|
||||
{
|
||||
foreach (var (rectTransform, btn) in _tabs)
|
||||
{
|
||||
if (btn.data != index)
|
||||
{
|
||||
btn.highlighted = false;
|
||||
rectTransform.gameObject.SetActive(false);
|
||||
continue;
|
||||
}
|
||||
btn.highlighted = true;
|
||||
rectTransform.gameObject.SetActive(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyWindowManager
|
||||
{
|
||||
private static readonly List<ManualBehaviour> Windows = new(4);
|
||||
private static bool _initialized;
|
||||
|
||||
public static T CreateWindow<T>(string name, string title = "") where T : MyWindow
|
||||
{
|
||||
var srcWin = UIRoot.instance.uiGame.tankWindow;
|
||||
var src = srcWin.gameObject;
|
||||
var go = Object.Instantiate(src, UIRoot.instance.uiGame.transform.parent);
|
||||
go.name = name;
|
||||
go.SetActive(false);
|
||||
Object.Destroy(go.GetComponent<UITankWindow>());
|
||||
var win = go.AddComponent<T>() as MyWindow;
|
||||
if (win == null)
|
||||
return null;
|
||||
|
||||
for (var i = 0; i < go.transform.childCount; i++)
|
||||
{
|
||||
var child = go.transform.GetChild(i).gameObject;
|
||||
if (child.name == "panel-bg")
|
||||
{
|
||||
var btn = child.GetComponentInChildren<Button>();
|
||||
//close-btn
|
||||
if (btn != null)
|
||||
{
|
||||
btn.onClick.AddListener(win._Close);
|
||||
}
|
||||
}
|
||||
else if (child.name != "shadow" && child.name != "panel-bg")
|
||||
{
|
||||
Object.Destroy(child);
|
||||
}
|
||||
}
|
||||
|
||||
win.SetTitle(title);
|
||||
win._Create();
|
||||
if (_initialized)
|
||||
{
|
||||
win._Init(win.data);
|
||||
}
|
||||
Windows.Add(win);
|
||||
return (T)win;
|
||||
}
|
||||
|
||||
/*
|
||||
public static void SetRect(ManualBehaviour win, RectTransform rect)
|
||||
{
|
||||
var rectTransform = win.GetComponent<RectTransform>();
|
||||
//rectTransform.position =
|
||||
//rectTransform.sizeDelta = rect;
|
||||
}
|
||||
*/
|
||||
|
||||
public static class Patch
|
||||
{
|
||||
|
||||
/*
|
||||
//_Create -> _Init
|
||||
[HarmonyPostfix, HarmonyPatch(typeof(UIGame), "_OnCreate")]
|
||||
public static void UIGame__OnCreate_Postfix()
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
[HarmonyPostfix, HarmonyPatch(typeof(UIRoot), "_OnDestroy")]
|
||||
public static void UIRoot__OnDestroy_Postfix()
|
||||
{
|
||||
foreach (var win in Windows)
|
||||
{
|
||||
win._Free();
|
||||
win._Destroy();
|
||||
}
|
||||
Windows.Clear();
|
||||
}
|
||||
|
||||
[HarmonyPostfix, HarmonyPatch(typeof(UIRoot), "_OnOpen")]
|
||||
public static void UIRoot__OnOpen_Postfix()
|
||||
{
|
||||
if (_initialized) return;
|
||||
foreach (var win in Windows)
|
||||
{
|
||||
win._Init(win.data);
|
||||
}
|
||||
_initialized = true;
|
||||
}
|
||||
|
||||
/*
|
||||
[HarmonyPostfix, HarmonyPatch(typeof(UIGame), "_OnFree")]
|
||||
public static void UIGame__OnFree_Postfix()
|
||||
{
|
||||
foreach (var win in Windows)
|
||||
{
|
||||
win._Free();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
[HarmonyPostfix, HarmonyPatch(typeof(UIRoot), "_OnUpdate")]
|
||||
public static void UIRoot__OnUpdate_Postfix()
|
||||
{
|
||||
if (GameMain.isPaused || !GameMain.isRunning)
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (var win in Windows)
|
||||
{
|
||||
win._Update();
|
||||
}
|
||||
}
|
||||
|
||||
[HarmonyPostfix, HarmonyPatch(typeof(UIGame), "ShutAllFunctionWindow")]
|
||||
public static void UIGame_ShutAllFunctionWindow_Postfix()
|
||||
{
|
||||
foreach (var win in Windows)
|
||||
{
|
||||
if (win is MyWindow theWin && theWin.IsWindowFunctional())
|
||||
{
|
||||
theWin.TryClose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
66
UXAssist/UI/Util.cs
Normal file
66
UXAssist/UI/Util.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace UXAssist.UI;
|
||||
|
||||
public static class Util
|
||||
{
|
||||
|
||||
public static RectTransform NormalizeRectWithTopLeft(Component cmp, float left, float top, Transform parent = null)
|
||||
{
|
||||
if (cmp.transform is not RectTransform rect) return null;
|
||||
if (parent != null)
|
||||
{
|
||||
rect.SetParent(parent, false);
|
||||
}
|
||||
rect.anchorMax = new Vector2(0f, 1f);
|
||||
rect.anchorMin = new Vector2(0f, 1f);
|
||||
rect.pivot = new Vector2(0f, 1f);
|
||||
rect.anchoredPosition3D = new Vector3(left, -top, 0f);
|
||||
return rect;
|
||||
}
|
||||
|
||||
public static RectTransform NormalizeRectWithBottomLeft(Component cmp, float left, float bottom, Transform parent = null)
|
||||
{
|
||||
if (cmp.transform is not RectTransform rect) return null;
|
||||
if (parent != null)
|
||||
{
|
||||
rect.SetParent(parent, false);
|
||||
}
|
||||
rect.anchorMax = new Vector2(0f, 0f);
|
||||
rect.anchorMin = new Vector2(0f, 0f);
|
||||
rect.pivot = new Vector2(0f, 0f);
|
||||
rect.anchoredPosition3D = new Vector3(left, bottom, 0f);
|
||||
return rect;
|
||||
}
|
||||
|
||||
public static RectTransform NormalizeRectWithMargin(Component cmp, float top, float left, float bottom, float right, Transform parent = null)
|
||||
{
|
||||
if (cmp.transform is not RectTransform rect) return null;
|
||||
if (parent != null)
|
||||
{
|
||||
rect.SetParent(parent, false);
|
||||
}
|
||||
rect.anchoredPosition3D = Vector3.zero;
|
||||
rect.localScale = Vector3.one;
|
||||
rect.anchorMax = Vector2.one;
|
||||
rect.anchorMin = Vector2.zero;
|
||||
rect.pivot = new Vector2(0.5f, 0.5f);
|
||||
rect.offsetMax = new Vector2(-right, -top);
|
||||
rect.offsetMin = new Vector2(left, bottom);
|
||||
return rect;
|
||||
}
|
||||
|
||||
public static RectTransform NormalizeRectCenter(GameObject go, float width = 0, float height = 0)
|
||||
{
|
||||
if (go.transform is not RectTransform rect) return null;
|
||||
rect.anchorMax = new Vector2(0.5f, 0.5f);
|
||||
rect.anchorMin = new Vector2(0.5f, 0.5f);
|
||||
rect.pivot = new Vector2(0.5f, 0.5f);
|
||||
if (width > 0 && height > 0)
|
||||
{
|
||||
rect.sizeDelta = new Vector2(width, height);
|
||||
}
|
||||
return rect;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user