Files
ADOFAIRenderer/UI/RenderConfigUIManager.cs
T
2026-06-12 22:29:01 +09:00

144 lines
6.1 KiB
C#

using System.Text;
using ADOFAIRenderer.Core;
using ADOFAIRenderer.Data;
using ADOFAIRenderer.Util.FFmpeg;
using MelonLoader;
using UnityEngine;
using UnityEngine.UIElements;
namespace ADOFAIRenderer.UI
{
public class RenderConfigUIManager : MonoBehaviour
{
[SerializeField]
private UIDocument uiDocument = null!;
private VisualElement _root = null!;
private IntegerInputValidator _intValidator = null!;
private DoubleInputValidator _doubleValidator = null!;
private EnumDropdownBinder<Codec> _codecBinder = null!;
private Button _goRenderButton = null!;
private Button _encodingConfigButton = null!;
private void Awake()
{
_root = uiDocument.rootVisualElement;
RenderManager.Instance.Configuration = new RenderConfig();
_intValidator = new IntegerInputValidator(_root);
_doubleValidator = new DoubleInputValidator(_root);
}
private void Start()
{
Melon<RenderMod>.Logger.Msg("[UI] Start 진입");
// Init Validators
_intValidator
.AddLimits("RenderWidth", new PositiveOnlyIntegerLimit(), new RangeIntegerLimit(1, 7680))
.AddLimits("RenderHeight", new PositiveOnlyIntegerLimit(), new RangeIntegerLimit(1, 4320));
_doubleValidator
.AddLimits("RenderFPS", new PositiveOnlyDoubleLimit(), new RangeDoubleLimit(0, 9600))
.AddLimits("VideoFPS", new PositiveOnlyDoubleLimit(), new RangeDoubleLimit(0, 4800))
.AddLimits("DelayAfterLevelEnd", new PositiveOnlyDoubleLimit(), new RangeDoubleLimit(0, 86400));
_intValidator.SetupValidation();
_doubleValidator.SetupValidation();
Melon<RenderMod>.Logger.Msg("[UI] Validator 설정 완료");
// Init Enum Binders & Event Listeners
_codecBinder = new EnumDropdownBinder<Codec>(_root, "CodecDropdown", Codec.H264);
Melon<RenderMod>.Logger.Msg("[UI] CodecBinder 생성 완료");
_codecBinder.OnValueChanged(value => RenderManager.Instance.Configuration.Codec = value);
Melon<RenderMod>.Logger.Msg("[UI] CodecBinder 콜백 등록 완료");
// Bind Data
_root.dataSource = RenderManager.Instance.Configuration;
// Attach Button Event Listener
_goRenderButton = _root.Q<Button>("GoRenderButton");
if (_goRenderButton != null)
{
Melon<RenderMod>.Logger.Msg($"[UI] GoRenderButton 발견: pickingMode={_goRenderButton.pickingMode}, enabledSelf={_goRenderButton.enabledSelf}");
_goRenderButton.RegisterCallback<ClickEvent>(_ => TryGoRender());
}
else
{
Melon<RenderMod>.Logger.Error("Button 'GoRenderButton'을(를) 찾을 수 없습니다.");
}
_encodingConfigButton = _root.Q<Button>("EncodingSettingsButton");
if (_encodingConfigButton != null)
{
Melon<RenderMod>.Logger.Msg($"[UI] EncodingSettingsButton 발견: pickingMode={_encodingConfigButton.pickingMode}, enabledSelf={_encodingConfigButton.enabledSelf}");
_encodingConfigButton.RegisterCallback<ClickEvent>(_ => OpenEncodingConfig());
}
else
{
Melon<RenderMod>.Logger.Error("Button 'EncodingSettingsButton'을(를) 찾을 수 없습니다.");
}
}
private void OpenEncodingConfig()
{
Melon<RenderMod>.Logger.Msg("[UI] OpenEncodingConfig 호출됨");
RenderManager.Instance.Configuration.EncodingConfig ??= GenerateEncodingConfig(_codecBinder.Value);
}
private void TryGoRender()
{
Melon<RenderMod>.Logger.Msg("[UI] TryGoRender 호출됨");
var widthField = _root.Q<IntegerField>("RenderWidth");
var heightField = _root.Q<IntegerField>("RenderHeight");
var randomSeedField = _root.Q<IntegerField>("RandomSeed");
var renderFpsField = _root.Q<DoubleField>("RenderFPS");
var videoFpsField = _root.Q<DoubleField>("VideoFPS");
var delayField = _root.Q<DoubleField>("DelayAfterLevelEnd");
var showJudgementText = _root.Q<Toggle>("ShowJudgementText");
var processAudio = _root.Q<Toggle>("ProcessAudioToggle");
if (string.IsNullOrEmpty(widthField.text) ||
string.IsNullOrEmpty(heightField.text) ||
string.IsNullOrEmpty(renderFpsField.text) ||
string.IsNullOrEmpty(videoFpsField.text) ||
string.IsNullOrEmpty(delayField.text))
{
Melon<RenderMod>.Logger.Error("필수 입력 값이 비어 있습니다. 모든 설정을 입력해 주세요.");
return;
}
// Copy validated values to Configuration manually
var config = RenderManager.Instance.Configuration;
config.RenderWidth = widthField.value;
config.RenderHeight = heightField.value;
config.RenderFPS = renderFpsField.value;
config.VideoFPS = videoFpsField.value;
config.DelayAfterLevelEnd = delayField.value;
config.ShowJudgementText = showJudgementText.value;
config.ProcessAudio = processAudio.value;
if (!string.IsNullOrEmpty(randomSeedField.text))
config.RandomSeed = randomSeedField.value;
RenderManager.Instance.Configuration.EncodingConfig ??= GenerateEncodingConfig(_codecBinder.Value);
RenderManager.Instance.SetupCaptureDirectory();
RenderManager.Instance.SetupGameScene();
}
private EncodingConfig GenerateEncodingConfig(Codec codec)
{
return new EncodingConfig
{
RateControlMode = RateControlMode.CBR,
Bitrate = 30000, MaxBitrate = 50000,
QP = 18
};
}
}
}