#region Copyright & License Information /* * Copyright 2007-2022 The OpenRA Developers (see AUTHORS) * 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 { [TranslationReference] static readonly string SettingsSaveTitle = "settings-save-title"; [TranslationReference] static readonly string SettingsSavePrompt = "settings-save-prompt"; [TranslationReference] static readonly string SettingsSaveCancel = "settings-save-cancel"; [TranslationReference] static readonly string RestartTitle = "restart-title"; [TranslationReference] static readonly string RestartPrompt = "restart-prompt"; [TranslationReference] static readonly string RestartAccept = "restart-accept"; [TranslationReference] static readonly string RestartCancel = "restart-cancel"; [TranslationReference("panel")] static readonly string ResetTitle = "reset-title"; [TranslationReference] static readonly string ResetPrompt = "reset-prompt"; [TranslationReference] static readonly string ResetAccept = "reset-accept"; [TranslationReference] static readonly string ResetCancel = "reset-cancel"; readonly Dictionary> leavePanelActions = new Dictionary>(); readonly Dictionary resetPanelActions = new Dictionary(); readonly Widget panelContainer, tabContainer; readonly ButtonWidget tabTemplate; readonly int2 buttonStride; readonly List buttons = new List(); readonly Dictionary panels = new Dictionary(); string activePanel; bool needsRestart = false; static SettingsLogic() { } [ObjectCreator.UseCtor] public SettingsLogic(Widget widget, Action onExit, WorldRenderer worldRenderer, Dictionary logicArgs, ModData modData) { panelContainer = widget.Get("PANEL_CONTAINER"); var panelTemplate = panelContainer.Get("PANEL_TEMPLATE"); panelContainer.RemoveChild(panelTemplate); tabContainer = widget.Get("SETTINGS_TAB_CONTAINER"); tabTemplate = tabContainer.Get("BUTTON_TEMPLATE"); tabContainer.RemoveChild(tabTemplate); if (logicArgs.TryGetValue("ButtonStride", out var buttonStrideNode)) buttonStride = FieldLoader.GetValue("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() as ContainerWidget; container.Id = panel.Key; panelContainer.AddChild(container); Game.LoadWidget(worldRenderer.World, panel.Key, container, new WidgetArgs() { { "registerPanel", (Action>, Func>)RegisterSettingsPanel }, { "panelID", panel.Key }, { "label", panel.Value } }); } } widget.Get("BACK_BUTTON").OnClick = () => { needsRestart |= leavePanelActions[activePanel](); var current = Game.Settings; current.Save(); Action closeAndExit = () => { Ui.CloseWindow(); onExit(); }; if (needsRestart) { Action 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), onCancel: closeAndExit, confirmText: RestartAccept, cancelText: RestartCancel); } else closeAndExit(); }; widget.Get("RESET_BUTTON").OnClick = () => { Action reset = () => { resetPanelActions[activePanel](); Game.Settings.Save(); }; ConfirmationDialogs.ButtonPrompt(modData, title: ResetTitle, titleArguments: Translation.Arguments("panel", panels[activePanel]), text: ResetPrompt, onConfirm: reset, onCancel: () => { }, confirmText: ResetAccept, cancelText: ResetCancel); }; } public void RegisterSettingsPanel(string panelID, string label, Func> init, Func reset) { var panel = panelContainer.Get(panelID); if (activePanel == null) 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() as ButtonWidget; 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; } } }