Use the covariant return type feature of C# 9 to allow method overrides to be more specific about their return type. By exposing this information, e.g. for Widget.Clone(), callers will have more information. This allows various casts to be removed as the information is now available within the type system.
195 lines
5.5 KiB
C#
195 lines
5.5 KiB
C#
#region Copyright & License Information
|
|
/*
|
|
* Copyright (c) The OpenRA Developers and Contributors
|
|
* This file is part of OpenRA, which is free software. It is made
|
|
* available to you under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation, either version 3 of
|
|
* the License, or (at your option) any later version. For more
|
|
* information, see COPYING.
|
|
*/
|
|
#endregion
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using OpenRA.Graphics;
|
|
using OpenRA.Widgets;
|
|
|
|
namespace OpenRA.Mods.Common.Widgets.Logic
|
|
{
|
|
public class SettingsLogic : ChromeLogic
|
|
{
|
|
[FluentReference]
|
|
const string SettingsSaveTitle = "dialog-settings-save.title";
|
|
|
|
[FluentReference]
|
|
const string SettingsSavePrompt = "dialog-settings-save.prompt";
|
|
|
|
[FluentReference]
|
|
const string SettingsSaveCancel = "dialog-settings-save.cancel";
|
|
|
|
[FluentReference]
|
|
const string RestartTitle = "dialog-settings-restart.title";
|
|
|
|
[FluentReference]
|
|
const string RestartPrompt = "dialog-settings-restart.prompt";
|
|
|
|
[FluentReference]
|
|
const string RestartAccept = "dialog-settings-restart.confirm";
|
|
|
|
[FluentReference]
|
|
const string RestartCancel = "dialog-settings-restart.cancel";
|
|
|
|
[FluentReference("panel")]
|
|
const string ResetTitle = "dialog-settings-reset.title";
|
|
|
|
[FluentReference]
|
|
const string ResetPrompt = "dialog-settings-reset.prompt";
|
|
|
|
[FluentReference]
|
|
const string ResetAccept = "dialog-settings-reset.confirm";
|
|
|
|
[FluentReference]
|
|
const string ResetCancel = "dialog-settings-reset.cancel";
|
|
|
|
readonly Dictionary<string, Func<bool>> leavePanelActions = new();
|
|
readonly Dictionary<string, Action> resetPanelActions = new();
|
|
|
|
readonly Widget panelContainer, tabContainer;
|
|
readonly ButtonWidget tabTemplate;
|
|
readonly int2 buttonStride;
|
|
readonly List<ButtonWidget> buttons = new();
|
|
readonly Dictionary<string, string> panels = new();
|
|
string activePanel;
|
|
|
|
bool needsRestart = false;
|
|
|
|
static SettingsLogic() { }
|
|
|
|
[ObjectCreator.UseCtor]
|
|
public SettingsLogic(Widget widget, Action onExit, WorldRenderer worldRenderer, Dictionary<string, MiniYaml> logicArgs, ModData modData)
|
|
{
|
|
panelContainer = widget.Get("PANEL_CONTAINER");
|
|
var panelTemplate = panelContainer.Get<ContainerWidget>("PANEL_TEMPLATE");
|
|
panelContainer.RemoveChild(panelTemplate);
|
|
|
|
tabContainer = widget.Get("SETTINGS_TAB_CONTAINER");
|
|
tabTemplate = tabContainer.Get<ButtonWidget>("BUTTON_TEMPLATE");
|
|
tabContainer.RemoveChild(tabTemplate);
|
|
|
|
if (logicArgs.TryGetValue("ButtonStride", out var buttonStrideNode))
|
|
buttonStride = FieldLoader.GetValue<int2>("ButtonStride", buttonStrideNode.Value);
|
|
|
|
if (logicArgs.TryGetValue("Panels", out var settingsPanels))
|
|
{
|
|
panels = settingsPanels.ToDictionary(kv => kv.Value);
|
|
|
|
foreach (var panel in panels)
|
|
{
|
|
var container = panelTemplate.Clone();
|
|
container.Id = panel.Key;
|
|
panelContainer.AddChild(container);
|
|
|
|
Game.LoadWidget(worldRenderer.World, panel.Key, container, new WidgetArgs()
|
|
{
|
|
{ "registerPanel", (Action<string, string, Func<Widget, Func<bool>>, Func<Widget, Action>>)RegisterSettingsPanel },
|
|
{ "panelID", panel.Key },
|
|
{ "label", panel.Value }
|
|
});
|
|
}
|
|
}
|
|
|
|
widget.Get<ButtonWidget>("BACK_BUTTON").OnClick = () =>
|
|
{
|
|
needsRestart |= leavePanelActions[activePanel]();
|
|
var current = Game.Settings;
|
|
current.Save();
|
|
|
|
void CloseAndExit() { Ui.CloseWindow(); onExit(); }
|
|
if (needsRestart)
|
|
{
|
|
void NoRestart() => ConfirmationDialogs.ButtonPrompt(modData,
|
|
title: SettingsSaveTitle,
|
|
text: SettingsSavePrompt,
|
|
onCancel: CloseAndExit,
|
|
cancelText: SettingsSaveCancel);
|
|
|
|
if (!Game.ExternalMods.TryGetValue(ExternalMod.MakeKey(Game.ModData.Manifest), out var external))
|
|
{
|
|
NoRestart();
|
|
return;
|
|
}
|
|
|
|
ConfirmationDialogs.ButtonPrompt(modData,
|
|
title: RestartTitle,
|
|
text: RestartPrompt,
|
|
onConfirm: () => Game.SwitchToExternalMod(external, null, NoRestart),
|
|
confirmText: RestartAccept,
|
|
onCancel: CloseAndExit,
|
|
cancelText: RestartCancel);
|
|
}
|
|
else
|
|
CloseAndExit();
|
|
};
|
|
|
|
widget.Get<ButtonWidget>("RESET_BUTTON").OnClick = () =>
|
|
{
|
|
void Reset()
|
|
{
|
|
resetPanelActions[activePanel]();
|
|
Game.Settings.Save();
|
|
}
|
|
|
|
ConfirmationDialogs.ButtonPrompt(modData,
|
|
title: ResetTitle,
|
|
text: ResetPrompt,
|
|
titleArguments: new object[] { "panel", panels[activePanel] },
|
|
onConfirm: Reset,
|
|
confirmText: ResetAccept,
|
|
onCancel: () => { },
|
|
cancelText: ResetCancel);
|
|
};
|
|
}
|
|
|
|
public void RegisterSettingsPanel(string panelID, string label, Func<Widget, Func<bool>> init, Func<Widget, Action> reset)
|
|
{
|
|
var panel = panelContainer.Get(panelID);
|
|
|
|
activePanel ??= panelID;
|
|
|
|
panel.IsVisible = () => activePanel == panelID;
|
|
|
|
leavePanelActions.Add(panelID, init(panel));
|
|
resetPanelActions.Add(panelID, reset(panel));
|
|
|
|
AddSettingsTab(panelID, label);
|
|
}
|
|
|
|
ButtonWidget AddSettingsTab(string id, string label)
|
|
{
|
|
var tab = tabTemplate.Clone();
|
|
var lastButton = buttons.LastOrDefault();
|
|
if (lastButton != null)
|
|
{
|
|
tab.Bounds.X = lastButton.Bounds.X + buttonStride.X;
|
|
tab.Bounds.Y = lastButton.Bounds.Y + buttonStride.Y;
|
|
}
|
|
|
|
tab.Id = id;
|
|
tab.GetText = () => label;
|
|
tab.IsHighlighted = () => activePanel == id;
|
|
tab.OnClick = () =>
|
|
{
|
|
needsRestart |= leavePanelActions[activePanel]();
|
|
Game.Settings.Save();
|
|
activePanel = id;
|
|
};
|
|
|
|
tabContainer.AddChild(tab);
|
|
buttons.Add(tab);
|
|
|
|
return tab;
|
|
}
|
|
}
|
|
}
|