#region Copyright & License Information /* * Copyright 2007-2021 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 { 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) { panelContainer = widget.Get("PANEL_CONTAINER"); var panelTemplate = panelContainer.Get("PANEL_TEMPLATE"); panelContainer.RemoveChild(panelTemplate); tabContainer = widget.Get("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 restart = () => { var external = Game.ExternalMods[ExternalMod.MakeKey(Game.ModData.Manifest)]; Game.SwitchToExternalMod(external, null, closeAndExit); }; ConfirmationDialogs.ButtonPrompt( title: "Restart Now?", text: "Some changes will not be applied until\nthe game is restarted. Restart now?", onConfirm: restart, onCancel: closeAndExit, confirmText: "Restart Now", cancelText: "Restart Later"); } else closeAndExit(); }; widget.Get("RESET_BUTTON").OnClick = () => { Action reset = () => { resetPanelActions[activePanel](); Game.Settings.Save(); }; ConfirmationDialogs.ButtonPrompt( title: "Reset \"{0}\"".F(panels[activePanel]), text: "Are you sure you want to reset\nall settings in this panel?", onConfirm: reset, onCancel: () => { }, confirmText: "Reset", cancelText: "Cancel"); }; } 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; } } }