3 Commits
Author SHA256 Message Date
copecone 369f6f9a0d Fix Warning Dialogs Hidden Behind Render Config Window 2026-10-14 20:46:02 +09:00
copeconeandClaude Sonnet 5.5 520d18846b Validate Even Render Resolution Before Starting
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 20:20:16 +09:00
copeconeandClaude Sonnet 5.5 22bd38d008 Fix Language Change And Name Collision In Presets
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 20:20:06 +09:00
5 changed files with 48 additions and 7 deletions

No files matched your search

+5 -1
View File
@@ -116,7 +116,11 @@ public static class PresetManager
return Path.Combine(root, "UserData", "ADOFAIRenderer", "Presets");
}
private static string GetSafeFileName(string name)
/// <summary>
/// File name (without extension) of the preset file for the given preset name: every character that is invalid
/// in a file name is replaced with '_'. Different preset names can map to the same file name (e.g. "a/b" and "a_b").
/// </summary>
internal static string GetSafeFileName(string name)
{
return Path.GetInvalidFileNameChars().Aggregate(name, (current, c) => current.Replace(c, '_'));
}
+1
View File
@@ -45,6 +45,7 @@
"ui.render_config.random_seed": "Random Seed (Optional)",
"ui.render_config.validation_title": "Invalid Settings",
"ui.render_config.validation_error": "Please check your input values:\n- Width and Height must be integers > 0\n- Render FPS and Video FPS must be > 0\n- Delay After End must be >= 0",
"ui.render_config.validation_even_size": "Render width and height must be even numbers (current: {0} x {1}).",
"ui.render_config.invalid_path": "Output directory path is invalid:\n{0}",
"ui.render_config.planet_colors": "Planet Colors (Optional)",
"ui.render_config.fire_planet": "Fire Planet",
+1
View File
@@ -45,6 +45,7 @@
"ui.render_config.random_seed": "랜덤 시드 (선택 사항)",
"ui.render_config.validation_title": "설정 오류",
"ui.render_config.validation_error": "입력값을 확인해 주세요:\n- 너비와 높이는 0보다 큰 정수여야 합니다.\n- 렌더 FPS와 영상 FPS는 0보다 커야 합니다.\n- 종료 후 대기 시간은 0 이상이어야 합니다.",
"ui.render_config.validation_even_size": "렌더 해상도의 가로와 세로는 짝수여야 해요. (현재: {0} x {1})",
"ui.render_config.invalid_path": "출력 디렉토리 경로가 올바르지 않습니다:\n{0}",
"ui.render_config.planet_colors": "행성 색상 설정 (선택 사항)",
"ui.render_config.fire_planet": "불 행성",
+7
View File
@@ -94,8 +94,15 @@ internal class RendererUIManager : MonoBehaviour
);
_windowManager = O5WindowManager.Create(_context, transform, "RendererMod_Canvas");
// The O5Kit canvas is created with sortingOrder 32767. It is lowered so that the dialogs of
// CommonWarningDialogUI (32766) are drawn above the windows of this manager.
var windowCanvas = transform.Find("RendererMod_Canvas")?.GetComponent<Canvas>();
if (windowCanvas != null) windowCanvas.sortingOrder = WindowCanvasSortingOrder;
}
private const int WindowCanvasSortingOrder = 32000;
private void Update() {
O5Object.TickAll();
Context.Tooltip.Tick();
+34 -6
View File
@@ -846,6 +846,14 @@ internal static class RenderConfigWindow
var config = UiConfig;
SyncUItoConfig(config);
// The encoders use 4:2:0 chroma subsampling, which needs an even width and height.
if (config.RenderWidth % 2 != 0 || config.RenderHeight % 2 != 0)
{
ShowValidationError(LocalizationManager.Get(
"ui.render_config.validation_even_size", config.RenderWidth, config.RenderHeight));
return;
}
// Sync Output Directory
if (_outputDirInput != null)
{
@@ -1023,12 +1031,16 @@ internal static class RenderConfigWindow
bool isCurrentPreset = !string.IsNullOrEmpty(_lastLoadedPresetName) &&
string.Equals(_lastLoadedPresetName, name, StringComparison.OrdinalIgnoreCase);
var existing = PresetManager.GetPresets().FirstOrDefault(p => string.Equals(p.Name, name, StringComparison.OrdinalIgnoreCase));
// A preset with another name can share the file of this name (PresetManager.GetSafeFileName), e.g. "a/b" and "a_b".
var fileName = PresetManager.GetSafeFileName(name);
var existing = PresetManager.GetPresets().FirstOrDefault(p =>
string.Equals(p.Name, name, StringComparison.OrdinalIgnoreCase) ||
string.Equals(PresetManager.GetSafeFileName(p.Name), fileName, StringComparison.OrdinalIgnoreCase));
if (existing != null && !isCurrentPreset)
{
CommonWarningDialogUI.ShowDialog(
LocalizationManager.Get("ui.render_config.preset_overwrite_title"),
LocalizationManager.Get("ui.render_config.preset_overwrite_desc", name),
LocalizationManager.Get("ui.render_config.preset_overwrite_desc", existing.Name),
new DialogButton(
LocalizationManager.Get("ui.render_config.confirm"),
() => DoSavePreset(name, config)
@@ -1190,12 +1202,28 @@ internal static class RenderConfigWindow
{
if (_configWindow == null) return;
if (_presetDropdown != null)
if (_presetDropdown == null) return;
// The preset names are not localized, the Custom label is. The list is rebuilt from the preset names
// (which drops the Custom label of the previous language), then the label is decided from the values:
// the Custom label of the new language only when the values differ from the last loaded preset.
var names = PresetManager.GetPresets().Select(p => p.Name).ToList();
if (names.Count == 0)
{
var cur = _presetDropdown.Value;
var isCustom = cur == "(Modified)" || cur == "(수정됨)" || cur == CustomPresetLabel;
ReloadPresetDropdown(isCustom ? CustomPresetLabel : cur);
_presetDropdown.SetValues(new List<string> { CustomPresetLabel });
_presetDropdown.Set(CustomPresetLabel, false);
UpdateDeleteButtonState();
return;
}
_presetDropdown.SetValues(names);
var loadedName = _lastLoadedPresetName;
if (!string.IsNullOrEmpty(loadedName) && names.Contains(loadedName))
{
_presetDropdown.Set(loadedName, false);
}
UpdatePresetLabel(UiConfig);
}
private static string GetVersionText()