Extract translation strings.

This commit is contained in:
Matthias Mailänder
2022-08-29 20:56:25 +02:00
committed by Gustas
parent dfd5a960ed
commit 0b67b5bfae
42 changed files with 1819 additions and 410 deletions

View File

@@ -83,7 +83,7 @@ namespace OpenRA.Mods.Common.LoadScreens
}
catch { }
if (ReplayUtils.PromptConfirmReplayCompatibility(replayMeta, Game.LoadShellMap))
if (ReplayUtils.PromptConfirmReplayCompatibility(replayMeta, Game.ModData, Game.LoadShellMap))
Game.JoinReplay(Launch.Replay);
if (replayMeta != null)

View File

@@ -785,14 +785,14 @@ namespace OpenRA.Mods.Common.Server
}
Log.Write("server", $"Kicking client {kickClientID}.");
server.SendLocalizedMessage(Kicked, Translation.Arguments("admin", client.Name, "client", kickClient.Name));
server.SendLocalizedMessage(Kicked, Translation.Arguments("admin", client.Name, "player", kickClient.Name));
server.SendOrderTo(kickConn, "ServerError", YouWereKicked);
server.DropClient(kickConn);
if (bool.TryParse(split[1], out var tempBan) && tempBan)
{
Log.Write("server", $"Temporarily banning client {kickClientID} ({kickClient.IPAddress}).");
server.SendLocalizedMessage(TempBan, Translation.Arguments("admin", client.Name, "client", kickClient.Name));
server.SendLocalizedMessage(TempBan, Translation.Arguments("admin", client.Name, "player", kickClient.Name));
server.TempBans.Add(kickClient.IPAddress);
}

View File

@@ -10,6 +10,7 @@
#endregion
using System;
using System.Collections.Generic;
using OpenRA.Widgets;
namespace OpenRA.Mods.Common.Widgets
@@ -17,8 +18,11 @@ namespace OpenRA.Mods.Common.Widgets
public static class ConfirmationDialogs
{
public static void ButtonPrompt(
ModData modData,
string title,
string text,
Dictionary<string, object> titleArguments = null,
Dictionary<string, object> textArguments = null,
Action onConfirm = null,
Action onCancel = null,
Action onOther = null,
@@ -32,10 +36,12 @@ namespace OpenRA.Mods.Common.Widgets
var cancelButton = prompt.GetOrNull<ButtonWidget>("CANCEL_BUTTON");
var otherButton = prompt.GetOrNull<ButtonWidget>("OTHER_BUTTON");
prompt.Get<LabelWidget>("PROMPT_TITLE").GetText = () => title;
var titleMessage = modData.Translation.GetString(title, titleArguments);
prompt.Get<LabelWidget>("PROMPT_TITLE").GetText = () => titleMessage;
var headerTemplate = prompt.Get<LabelWidget>("PROMPT_TEXT");
var headerLines = text.Replace("\\n", "\n").Split('\n');
var textMessage = modData.Translation.GetString(text, textArguments);
var headerLines = textMessage.Split('\n');
var headerHeight = 0;
foreach (var l in headerLines)
{
@@ -61,7 +67,10 @@ namespace OpenRA.Mods.Common.Widgets
};
if (!string.IsNullOrEmpty(confirmText))
confirmButton.GetText = () => confirmText;
{
var confirmTextMessage = modData.Translation.GetString(confirmText);
confirmButton.GetText = () => confirmTextMessage;
}
}
if (onCancel != null && cancelButton != null)
@@ -75,7 +84,10 @@ namespace OpenRA.Mods.Common.Widgets
};
if (!string.IsNullOrEmpty(cancelText))
cancelButton.GetText = () => cancelText;
{
var cancelTextMessage = modData.Translation.GetString(cancelText);
cancelButton.GetText = () => cancelTextMessage;
}
}
if (onOther != null && otherButton != null)
@@ -88,11 +100,14 @@ namespace OpenRA.Mods.Common.Widgets
};
if (!string.IsNullOrEmpty(otherText))
otherButton.GetText = () => otherText;
{
var otherTextMessage = modData.Translation.GetString(otherText);
otherButton.GetText = () => otherTextMessage;
}
}
}
public static void TextInputPrompt(
public static void TextInputPrompt(ModData modData,
string title, string prompt, string initialText,
Action<string> onAccept, Action onCancel = null,
string acceptText = null, string cancelText = null,
@@ -102,13 +117,12 @@ namespace OpenRA.Mods.Common.Widgets
Func<bool> doValidate = null;
ButtonWidget acceptButton = null, cancelButton = null;
// Title
panel.Get<LabelWidget>("PROMPT_TITLE").GetText = () => title;
var titleMessage = modData.Translation.GetString(title);
panel.Get<LabelWidget>("PROMPT_TITLE").GetText = () => titleMessage;
// Prompt
panel.Get<LabelWidget>("PROMPT_TEXT").GetText = () => prompt;
var promptMessage = modData.Translation.GetString(prompt);
panel.Get<LabelWidget>("PROMPT_TEXT").GetText = () => promptMessage;
// Text input
var input = panel.Get<TextFieldWidget>("INPUT_TEXT");
var isValid = false;
input.Text = initialText;
@@ -133,10 +147,12 @@ namespace OpenRA.Mods.Common.Widgets
input.CursorPosition = input.Text.Length;
input.OnTextEdited = () => doValidate();
// Buttons
acceptButton = panel.Get<ButtonWidget>("ACCEPT_BUTTON");
if (!string.IsNullOrEmpty(acceptText))
acceptButton.GetText = () => acceptText;
{
var acceptTextMessage = modData.Translation.GetString(acceptText);
acceptButton.GetText = () => acceptTextMessage;
}
acceptButton.OnClick = () =>
{
@@ -149,7 +165,10 @@ namespace OpenRA.Mods.Common.Widgets
cancelButton = panel.Get<ButtonWidget>("CANCEL_BUTTON");
if (!string.IsNullOrEmpty(cancelText))
cancelButton.GetText = () => cancelText;
{
var cancelTextMessage = modData.Translation.GetString(cancelText);
cancelButton.GetText = () => cancelTextMessage;
}
cancelButton.OnClick = () =>
{
@@ -157,7 +176,6 @@ namespace OpenRA.Mods.Common.Widgets
onCancel?.Invoke();
};
// Validation
doValidate = () =>
{
if (inputValidator == null)

View File

@@ -60,6 +60,14 @@ namespace OpenRA.Mods.Common.Widgets.Logic
float spriteScale;
float modelScale;
[TranslationReference("length")]
static readonly string LengthInSeconds = "length-in-seconds";
[TranslationReference]
static readonly string AllPackages = "all-packages";
readonly string allPackages;
[ObjectCreator.UseCtor]
public AssetBrowserLogic(Widget widget, Action onExit, ModData modData, WorldRenderer worldRenderer)
{
@@ -67,6 +75,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
this.modData = modData;
panel = widget;
allPackages = modData.Translation.GetString(AllPackages);
var colorPickerPalettes = world.WorldActor.TraitsImplementing<IProvidesAssetBrowserColorPickerPalettes>()
.SelectMany(p => p.ColorPickerPaletteNames)
.ToArray();
@@ -194,13 +204,15 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var frameText = panel.GetOrNull<LabelWidget>("FRAME_COUNT");
if (frameText != null)
{
var soundLength = new CachedTransform<int, string>(p =>
modData.Translation.GetString(LengthInSeconds, Translation.Arguments("length", p)));
frameText.GetText = () =>
{
if (isVideoLoaded)
return $"{player.Video.CurrentFrameIndex + 1} / {player.Video.FrameCount}";
if (currentSoundFormat != null)
return $"{Math.Round(currentSoundFormat.LengthInSeconds, 3)} sec";
return soundLength.Update((int)currentSoundFormat.LengthInSeconds);
return $"{currentFrame} / {currentSprites.Length - 1}";
};
@@ -607,7 +619,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
string GetSourceDisplayName(IReadOnlyPackage source)
{
if (source == null)
return "All Packages";
return allPackages;
// Packages that are explicitly mounted in the filesystem use their explicit mount name
var fs = (OpenRA.FileSystem.FileSystem)modData.DefaultFileSystem;

View File

@@ -21,6 +21,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
readonly Action onAbort;
readonly Action<string> onRetry;
[TranslationReference("endpoint")]
static readonly string ConnectingToEndpoint = "connecting-to-endpoint";
void ConnectionStateChanged(OrderManager om, string password, NetworkConnection connection)
{
if (connection.ConnectionState == ConnectionState.Connected)
@@ -51,7 +54,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
}
[ObjectCreator.UseCtor]
public ConnectionLogic(Widget widget, ConnectionTarget endpoint, Action onConnect, Action onAbort, Action<string> onRetry)
public ConnectionLogic(Widget widget, ModData modData, ConnectionTarget endpoint, Action onConnect, Action onAbort, Action<string> onRetry)
{
this.onConnect = onConnect;
this.onAbort = onAbort;
@@ -62,7 +65,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var panel = widget;
panel.Get<ButtonWidget>("ABORT_BUTTON").OnClick = () => { CloseWindow(); onAbort(); };
widget.Get<LabelWidget>("CONNECTING_DESC").GetText = () => $"Connecting to {endpoint}...";
var connectingDesc = modData.Translation.GetString(ConnectingToEndpoint, Translation.Arguments("endpoint", endpoint));
widget.Get<LabelWidget>("CONNECTING_DESC").GetText = () => connectingDesc;
}
public static void Connect(ConnectionTarget endpoint, string password, Action onConnect, Action onAbort)
@@ -85,6 +89,18 @@ namespace OpenRA.Mods.Common.Widgets.Logic
readonly PasswordFieldWidget passwordField;
bool passwordOffsetAdjusted;
[TranslationReference("target")]
static readonly string CouldNotConnectToTarget = "could-not-connect-to-target";
[TranslationReference]
static readonly string UnknownError = "unknown-error";
[TranslationReference]
static readonly string PasswordRequired = "password-required";
[TranslationReference]
static readonly string ConnectionFailed = "connection-failed";
[ObjectCreator.UseCtor]
public ConnectionFailedLogic(Widget widget, ModData modData, OrderManager orderManager, NetworkConnection connection, string password, Action onAbort, Action<string> onRetry)
{
@@ -104,13 +120,16 @@ namespace OpenRA.Mods.Common.Widgets.Logic
onRetry(pass);
};
widget.Get<LabelWidget>("CONNECTING_DESC").GetText = () => $"Could not connect to {connection.Target}";
var connectingDescText = modData.Translation.GetString(CouldNotConnectToTarget, Translation.Arguments("target", connection.Target));
widget.Get<LabelWidget>("CONNECTING_DESC").GetText = () => connectingDescText;
var connectionError = widget.Get<LabelWidget>("CONNECTION_ERROR");
connectionError.GetText = () => modData.Translation.GetString(orderManager.ServerError) ?? connection.ErrorMessage ?? "Unknown error";
var connectionErrorText = modData.Translation.GetString(orderManager.ServerError) ?? connection.ErrorMessage ?? modData.Translation.GetString(UnknownError);
connectionError.GetText = () => connectionErrorText;
var panelTitle = widget.Get<LabelWidget>("TITLE");
panelTitle.GetText = () => orderManager.AuthenticationFailed ? "Password Required" : "Connection Failed";
var panelTitleText = orderManager.AuthenticationFailed ? modData.Translation.GetString(PasswordRequired) : modData.Translation.GetString(ConnectionFailed);
panelTitle.GetText = () => panelTitleText;
passwordField = panel.GetOrNull<PasswordFieldWidget>("PASSWORD");
if (passwordField != null)
@@ -151,6 +170,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
public class ConnectionSwitchModLogic : ChromeLogic
{
[TranslationReference]
static readonly string ModSwitchFailed = "mod-switch-failed";
[ObjectCreator.UseCtor]
public ConnectionSwitchModLogic(Widget widget, OrderManager orderManager, NetworkConnection connection, Action onAbort, Action<string> onRetry)
{
@@ -167,7 +189,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var launchCommand = $"Launch.URI={new UriBuilder("tcp", connection.EndPoint.Address.ToString(), connection.EndPoint.Port)}";
Game.SwitchToExternalMod(CurrentServerSettings.ServerExternalMod, new[] { launchCommand }, () =>
{
orderManager.ServerError = "Failed to switch mod.";
orderManager.ServerError = ModSwitchFailed;
Ui.CloseWindow();
Ui.OpenWindow("CONNECTIONFAILED_PANEL", new WidgetArgs()
{

View File

@@ -71,22 +71,27 @@ namespace OpenRA.Mods.Common.Widgets.Logic
return true;
};
var none = ModData.Translation.GetString(None);
var searchResults = ModData.Translation.GetString(SearchResults);
var all = ModData.Translation.GetString(All);
var multiple = ModData.Translation.GetString(Multiple);
var categorySelector = widget.Get<DropDownButtonWidget>("CATEGORIES_DROPDOWN");
categorySelector.GetText = () =>
{
if (SelectedCategories.Count == 0)
return ModData.Translation.GetString(None);
return none;
if (!string.IsNullOrEmpty(searchFilter))
return ModData.Translation.GetString(SearchResults);
return searchResults;
if (SelectedCategories.Count == 1)
return SelectedCategories.First();
if (SelectedCategories.Count == allCategories.Length)
return ModData.Translation.GetString(All);
return all;
return ModData.Translation.GetString(Multiple);
return multiple;
};
categorySelector.OnMouseDown = _ =>

View File

@@ -42,6 +42,36 @@ namespace OpenRA.Mods.Common.Widgets.Logic
}
}
[TranslationReference]
static readonly string SaveMapFailedTitle = "save-map-failed-title";
[TranslationReference]
static readonly string SaveMapFailedPrompt = "save-map-failed-prompt";
[TranslationReference]
static readonly string SaveMapFailedAccept = "save-map-failed-accept";
[TranslationReference]
static readonly string Unpacked = "unpacked";
[TranslationReference]
static readonly string OverwriteMapFailedTitle = "overwrite-map-failed-title";
[TranslationReference]
static readonly string OverwriteMapFailedPrompt = "overwrite-map-failed-prompt";
[TranslationReference]
static readonly string SaveMapFailedConfirm = "overwrite-map-failed-confirm";
[TranslationReference]
static readonly string OverwriteMapOutsideEditTitle = "overwrite-map-outside-edit-title";
[TranslationReference]
static readonly string OverwriteMapOutsideEditPrompt = "overwrite-map-outside-edit-prompt";
[TranslationReference]
static readonly string SaveMapMapOutsideConfirm = "overwrite-map-outside-edit-confirm";
[ObjectCreator.UseCtor]
public SaveMapLogic(Widget widget, ModData modData, Action<string> onSave, Action onExit,
Map map, List<MiniYamlNode> playerDefinitions, List<MiniYamlNode> actorDefinitions)
@@ -135,7 +165,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var fileTypes = new Dictionary<MapFileType, MapFileTypeInfo>()
{
{ MapFileType.OraMap, new MapFileTypeInfo { Extension = ".oramap", UiLabel = ".oramap" } },
{ MapFileType.Unpacked, new MapFileTypeInfo { Extension = "", UiLabel = "(unpacked)" } }
{ MapFileType.Unpacked, new MapFileTypeInfo { Extension = "", UiLabel = $"({modData.Translation.GetString(Unpacked)})" } }
};
var typeDropdown = widget.Get<DropDownButtonWidget>("TYPE_DROPDOWN");
@@ -192,11 +222,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
Log.Write("debug", $"Failed to save map at {combinedPath}");
Log.Write("debug", e);
ConfirmationDialogs.ButtonPrompt(
title: "Failed to save map",
text: "See debug.log for details.",
ConfirmationDialogs.ButtonPrompt(modData,
title: SaveMapFailedTitle,
text: SaveMapFailedPrompt,
onConfirm: () => { },
confirmText: "OK");
confirmText: SaveMapFailedAccept);
}
};
@@ -213,10 +243,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
// When creating a new map or when file paths don't match
if (modData.MapCache.Any(m => m.Status == MapStatus.Available && m.Package?.Name == combinedPath))
{
ConfirmationDialogs.ButtonPrompt(
title: "Warning",
text: "By saving you will overwrite\n an already existing map.",
confirmText: "Save",
ConfirmationDialogs.ButtonPrompt(modData,
title: OverwriteMapFailedTitle,
text: OverwriteMapFailedPrompt,
confirmText: SaveMapFailedConfirm,
onConfirm: () => saveMap(combinedPath),
onCancel: () => { });
@@ -229,10 +259,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var recentUid = modData.MapCache.GetUpdatedMap(map.Uid);
if (recentUid != null && map.Uid != recentUid && modData.MapCache[recentUid].Status == MapStatus.Available)
{
ConfirmationDialogs.ButtonPrompt(
title: "Warning",
text: "The map has been edited from outside the editor.\n By saving you may overwrite progress",
confirmText: "Save",
ConfirmationDialogs.ButtonPrompt(modData,
title: OverwriteMapOutsideEditTitle,
text: OverwriteMapOutsideEditPrompt,
confirmText: SaveMapMapOutsideConfirm,
onConfirm: () => saveMap(combinedPath),
onCancel: () => { });

View File

@@ -33,6 +33,45 @@ namespace OpenRA.Mods.Common.Widgets.Logic
readonly string defaultSaveFilename;
string selectedSave;
[TranslationReference]
static readonly string RenameSaveTitle = "rename-save-title";
[TranslationReference]
static readonly string RenameSavePrompt = "rename-save-prompt";
[TranslationReference]
static readonly string RenameSaveAccept = "rename-save-accept";
[TranslationReference]
static readonly string DeleteSaveTitle = "delete-save-title";
[TranslationReference("save")]
static readonly string DeleteSavePrompt = "delete-save-prompt";
[TranslationReference]
static readonly string DeleteSaveAccept = "delete-save-accept";
[TranslationReference]
static readonly string DeleteAllSavesTitle = "delete-all-saves-title";
[TranslationReference("count")]
static readonly string DeleteAllSavesPrompt = "delete-all-saves-prompt";
[TranslationReference]
static readonly string DeleteAllSavesAccept = "delete-all-saves-accept";
[TranslationReference("savePath")]
static readonly string SaveDeletionFailed = "save-deletion-failed";
[TranslationReference]
static readonly string OverwriteSaveTitle = "overwrite-save-title";
[TranslationReference("file")]
static readonly string OverwriteSavePrompt = "overwrite-save-prompt";
[TranslationReference]
static readonly string OverwriteSaveAccpet = "overwrite-save-accept";
[ObjectCreator.UseCtor]
public GameSaveBrowserLogic(Widget widget, ModData modData, Action onExit, Action onStart, bool isSavePanel, World world)
{
@@ -100,13 +139,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var initialName = Path.GetFileNameWithoutExtension(selectedSave);
var invalidChars = Path.GetInvalidFileNameChars();
ConfirmationDialogs.TextInputPrompt(
"Rename Save",
"Enter a new file name:",
ConfirmationDialogs.TextInputPrompt(modData,
RenameSaveTitle,
RenameSavePrompt,
initialName,
onAccept: newName => Rename(initialName, newName),
onCancel: null,
acceptText: "Rename",
acceptText: RenameSaveAccept,
cancelText: null,
inputValidator: newName =>
{
@@ -130,9 +169,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
deleteButton.IsDisabled = () => selectedSave == null;
deleteButton.OnClick = () =>
{
ConfirmationDialogs.ButtonPrompt(
title: "Delete selected game save?",
text: $"Delete '{Path.GetFileNameWithoutExtension(selectedSave)}'?",
ConfirmationDialogs.ButtonPrompt(modData,
title: DeleteSaveTitle,
text: DeleteSavePrompt,
textArguments: Translation.Arguments("save", Path.GetFileNameWithoutExtension(selectedSave)),
onConfirm: () =>
{
Delete(selectedSave);
@@ -145,7 +185,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
else
SelectFirstVisible();
},
confirmText: "Delete",
confirmText: DeleteSaveAccept,
onCancel: () => { });
};
@@ -153,9 +193,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
deleteAllButton.IsDisabled = () => games.Count == 0;
deleteAllButton.OnClick = () =>
{
ConfirmationDialogs.ButtonPrompt(
title: "Delete all game saves?",
text: $"Delete {games.Count} game saves?",
ConfirmationDialogs.ButtonPrompt(modData,
title: DeleteAllSavesTitle,
text: DeleteAllSavesPrompt,
textArguments: Translation.Arguments("count", games.Count),
onConfirm: () =>
{
foreach (var s in games.ToList())
@@ -164,7 +205,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
Ui.CloseWindow();
onExit();
},
confirmText: "Delete All",
confirmText: DeleteAllSavesAccept,
onCancel: () => { });
};
@@ -251,7 +292,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
}
catch (Exception ex)
{
TextNotificationsManager.Debug("Failed to delete save file '{0}'. See the logs for details.", savePath);
TextNotificationsManager.Debug(modData.Translation.GetString(SaveDeletionFailed, Translation.Arguments("savePath", savePath)));
Log.Write("debug", ex.ToString());
return;
}
@@ -319,11 +360,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (selectedSave != null || File.Exists(testPath))
{
ConfirmationDialogs.ButtonPrompt(
title: "Overwrite save game?",
text: $"Overwrite {saveTextField.Text}?",
ConfirmationDialogs.ButtonPrompt(modData,
title: OverwriteSaveTitle,
text: OverwriteSavePrompt,
textArguments: Translation.Arguments("file", saveTextField.Text),
onConfirm: inner,
confirmText: "Overwrite",
confirmText: OverwriteSaveAccpet,
onCancel: () => { });
}
else

View File

@@ -28,6 +28,36 @@ namespace OpenRA.Mods.Common.Widgets.Logic
[TranslationReference]
static readonly string Mute = "mute";
[TranslationReference]
static readonly string Accomplished = "accomplished";
[TranslationReference]
static readonly string Failed = "failed";
[TranslationReference]
static readonly string InProgress = "in-progress";
[TranslationReference("team")]
static readonly string TeamNumber = "team-number";
[TranslationReference]
static readonly string NoTeam = "no-team";
[TranslationReference]
static readonly string Spectators = "spectators";
[TranslationReference]
static readonly string Gone = "gone";
[TranslationReference("player")]
static readonly string KickTitle = "kick-title";
[TranslationReference]
static readonly string KickPrompt = "kick-prompt";
[TranslationReference]
static readonly string KickAccept = "kick-accept";
[ObjectCreator.UseCtor]
public GameInfoStatsLogic(Widget widget, ModData modData, World world, OrderManager orderManager, WorldRenderer worldRenderer, Action<bool> hideMenu)
{
@@ -49,8 +79,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
checkbox.GetText = () => mo.Objectives.First().Description;
}
statusLabel.GetText = () => player.WinState == WinState.Won ? "Accomplished" :
player.WinState == WinState.Lost ? "Failed" : "In progress";
statusLabel.GetText = () => player.WinState == WinState.Won ? Accomplished :
player.WinState == WinState.Lost ? Failed : InProgress;
statusLabel.GetColor = () => player.WinState == WinState.Won ? Color.LimeGreen :
player.WinState == WinState.Lost ? Color.Red : Color.White;
}
@@ -86,7 +116,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (teams.Count() > 1)
{
var teamHeader = ScrollItemWidget.Setup(teamTemplate, () => true, () => { });
teamHeader.Get<LabelWidget>("TEAM").GetText = () => t.Key == 0 ? "No Team" : $"Team {t.Key}";
var team = t.Key > 0
? modData.Translation.GetString(TeamNumber, Translation.Arguments("team", t.Key))
: modData.Translation.GetString(NoTeam);
teamHeader.Get<LabelWidget>("TEAM").GetText = () => team;
var teamRating = teamHeader.Get<LabelWidget>("TEAM_SCORE");
var scoreCache = new CachedTransform<int, string>(s => s.ToString());
var teamMemberScores = t.Select(tt => tt.PlayerStatistics).Where(s => s != null).ToArray().Select(s => s.Experience);
@@ -137,7 +170,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (spectators.Count > 0)
{
var spectatorHeader = ScrollItemWidget.Setup(teamTemplate, () => true, () => { });
spectatorHeader.Get<LabelWidget>("TEAM").GetText = () => "Spectators";
var spectatorTeam = modData.Translation.GetString(Spectators);
spectatorHeader.Get<LabelWidget>("TEAM").GetText = () => spectatorTeam;
playerPanel.AddChild(spectatorHeader);
@@ -155,7 +189,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
nameLabel.GetText = () =>
{
var suffix = client.State == Session.ClientState.Disconnected ? " (Gone)" : "";
var suffix = client.State == Session.ClientState.Disconnected ? $" ({modData.Translation.GetString(Gone)})" : "";
return name.Update((client.Name, suffix));
};
@@ -164,16 +198,17 @@ namespace OpenRA.Mods.Common.Widgets.Logic
kickButton.OnClick = () =>
{
hideMenu(true);
ConfirmationDialogs.ButtonPrompt(
title: $"Kick {client.Name}?",
text: "They will not be able to rejoin this game.",
ConfirmationDialogs.ButtonPrompt(modData,
title: KickTitle,
titleArguments: Translation.Arguments("player", client.Name),
text: KickPrompt,
onConfirm: () =>
{
orderManager.IssueOrder(Order.Command($"kick {client.Index} {false}"));
hideMenu(false);
},
onCancel: () => hideMenu(false),
confirmText: "Kick");
confirmText: KickAccept);
};
var muteCheckbox = item.Get<CheckboxWidget>("MUTE");

View File

@@ -32,7 +32,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
readonly ContainerWidget chatChrome;
readonly ScrollPanelWidget chatScrollPanel;
readonly TextFieldWidget chatText;
readonly CachedTransform<int, string> chatDisabledLabel;
readonly CachedTransform<int, string> chatAvailableIn;
readonly string chatDisabled;
readonly Dictionary<TextNotificationPool, Widget> templates = new Dictionary<TextNotificationPool, Widget>();
readonly TabCompletionLogic tabCompletion = new TabCompletionLogic();
@@ -52,6 +53,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
[TranslationReference("seconds")]
static readonly string ChatAvailability = "chat-availability";
[TranslationReference]
static readonly string ChatDisabled = "chat-disabled";
[ObjectCreator.UseCtor]
public IngameChatLogic(Widget widget, OrderManager orderManager, World world, ModData modData, bool isMenuChat, Dictionary<string, MiniYaml> logicArgs)
{
@@ -69,6 +73,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var teamMessage = modData.Translation.GetString(Team);
var allMessage = modData.Translation.GetString(All);
chatDisabled = modData.Translation.GetString(ChatDisabled);
// Only execute this once, the first time this widget is loaded
if (TextNotificationsManager.MutedPlayers.Count == 0)
foreach (var c in orderManager.LobbyInfo.Clients)
@@ -188,7 +194,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
return true;
};
chatDisabledLabel = new CachedTransform<int, string>(x => modData.Translation.GetString(ChatAvailability, Translation.Arguments("seconds", x)));
chatAvailableIn = new CachedTransform<int, string>(x => modData.Translation.GetString(ChatAvailability, Translation.Arguments("seconds", x)));
if (!isMenuChat)
{
@@ -320,7 +326,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (TextNotificationsManager.ChatDisabledUntil != uint.MaxValue)
remaining = (int)(TextNotificationsManager.ChatDisabledUntil - Game.RunTime + 999) / 1000;
chatText.Text = chatDisabledLabel.Update(remaining);
chatText.Text = remaining == 0 ? chatDisabled : chatAvailableIn.Update(remaining);
}
}

View File

@@ -37,6 +37,102 @@ namespace OpenRA.Mods.Common.Widgets.Logic
bool leaving;
bool hideMenu;
[TranslationReference]
static readonly string Leave = "leave";
[TranslationReference]
static readonly string AbortMission = "abort-mission";
[TranslationReference]
static readonly string LeaveMissionTitle = "leave-mission-title";
[TranslationReference]
static readonly string LeaveMissionPrompt = "leave-mission-prompt";
[TranslationReference]
static readonly string LeaveMissionAccept = "leave-mission-accept";
[TranslationReference]
static readonly string LeaveMissionCancel = "leave-mission-cancel";
[TranslationReference]
static readonly string RestartButton = "restart-button";
[TranslationReference]
static readonly string RestartMissionTitle = "restart-mission-title";
[TranslationReference]
static readonly string RestartMissionPrompt = "restart-mission-prompt";
[TranslationReference]
static readonly string RestartMissionAccept = "restart-mission-accept";
[TranslationReference]
static readonly string RestartMissionCancel = "restart-mission-cancel";
[TranslationReference]
static readonly string SurrenderButton = "surrender-button";
[TranslationReference]
static readonly string SurrenderTitle = "surrender-title";
[TranslationReference]
static readonly string SurrenderPrompt = "surrender-prompt";
[TranslationReference]
static readonly string SurrenderAccept = "surrender-accept";
[TranslationReference]
static readonly string SurrenderCancel = "surrender-cancel";
[TranslationReference]
static readonly string LoadGameButton = "load-game-button";
[TranslationReference]
static readonly string SaveGameButton = "save-game-button";
[TranslationReference]
static readonly string MusicButton = "music-button";
[TranslationReference]
static readonly string SettingsButton = "settings-button";
[TranslationReference]
static readonly string ReturnToMap = "return-to-map";
[TranslationReference]
static readonly string Resume = "resume";
[TranslationReference]
static readonly string SaveMapButton = "save-map-button";
[TranslationReference]
static readonly string ErrorMaxPlayerTitle = "error-max-player-title";
[TranslationReference("players", "max")]
static readonly string ErrorMaxPlayerPrompt = "error-max-player-prompt";
[TranslationReference]
static readonly string ErrorMaxPlayerAccept = "error-max-player-accept";
[TranslationReference]
static readonly string ExitMapButton = "exit-map-button";
[TranslationReference]
static readonly string ExitMapEditorTitle = "exit-map-editor-title";
[TranslationReference]
static readonly string ExitMapEditorPromptUnsaved = "exit-map-editor-prompt-unsaved";
[TranslationReference]
static readonly string ExitMapEditorPromptDeleted = "exit-map-editor-prompt-deleted";
[TranslationReference]
static readonly string ExitMapEditorAnywayConfirm = "exit-map-editor-confirm-anyway";
[TranslationReference]
static readonly string ExitMapEditorConfirm = "exit-map-editor-confirm";
[ObjectCreator.UseCtor]
public IngameMenuLogic(Widget widget, ModData modData, World world, Action onExit, WorldRenderer worldRenderer,
IngameInfoPanel initialPanel, Dictionary<string, MiniYaml> logicArgs)
@@ -175,7 +271,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
button.Id = id;
button.IsDisabled = () => leaving;
button.GetText = () => text;
var translation = modData.Translation.GetString(text);
button.GetText = () => translation;
buttonContainer.AddChild(button);
buttons.Add(button);
@@ -187,19 +284,21 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (world.Type != WorldType.Regular)
return;
var button = AddButton("ABORT_MISSION", world.IsGameOver ? "Leave" : "Abort Mission");
var button = AddButton("ABORT_MISSION", world.IsGameOver
? modData.Translation.GetString(Leave)
: modData.Translation.GetString(AbortMission));
button.OnClick = () =>
{
hideMenu = true;
ConfirmationDialogs.ButtonPrompt(
title: "Leave Mission",
text: "Leave this game and return to the menu?",
ConfirmationDialogs.ButtonPrompt(modData,
title: LeaveMissionTitle,
text: LeaveMissionPrompt,
onConfirm: OnQuit,
onCancel: ShowMenu,
confirmText: "Leave",
cancelText: "Stay");
confirmText: LeaveMissionAccept,
cancelText: LeaveMissionCancel);
};
}
@@ -224,18 +323,18 @@ namespace OpenRA.Mods.Common.Widgets.Logic
Game.RunAfterDelay(exitDelay, Game.RestartGame);
};
var button = AddButton("RESTART", "Restart");
var button = AddButton("RESTART", RestartButton);
button.IsDisabled = () => hasError || leaving;
button.OnClick = () =>
{
hideMenu = true;
ConfirmationDialogs.ButtonPrompt(
title: "Restart",
text: "Are you sure you want to restart?",
ConfirmationDialogs.ButtonPrompt(modData,
title: RestartMissionTitle,
text: RestartMissionPrompt,
onConfirm: onRestart,
onCancel: ShowMenu,
confirmText: "Restart",
cancelText: "Stay");
confirmText: RestartMissionAccept,
cancelText: RestartMissionCancel);
};
}
@@ -250,18 +349,18 @@ namespace OpenRA.Mods.Common.Widgets.Logic
CloseMenu();
};
var button = AddButton("SURRENDER", "Surrender");
var button = AddButton("SURRENDER", SurrenderButton);
button.IsDisabled = () => world.LocalPlayer.WinState != WinState.Undefined || hasError || leaving;
button.OnClick = () =>
{
hideMenu = true;
ConfirmationDialogs.ButtonPrompt(
title: "Surrender",
text: "Are you sure you want to surrender?",
ConfirmationDialogs.ButtonPrompt(modData,
title: SurrenderTitle,
text: SurrenderPrompt,
onConfirm: onSurrender,
onCancel: ShowMenu,
confirmText: "Surrender",
cancelText: "Stay");
confirmText: SurrenderAccept,
cancelText: SurrenderCancel);
};
}
@@ -270,7 +369,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (world.Type != WorldType.Regular || !world.LobbyInfo.GlobalSettings.GameSavesEnabled || world.IsReplay)
return;
var button = AddButton("LOAD_GAME", "Load Game");
var button = AddButton("LOAD_GAME", LoadGameButton);
button.IsDisabled = () => leaving || !GameSaveBrowserLogic.IsLoadPanelEnabled(modData.Manifest);
button.OnClick = () =>
{
@@ -290,7 +389,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (world.Type != WorldType.Regular || !world.LobbyInfo.GlobalSettings.GameSavesEnabled || world.IsReplay)
return;
var button = AddButton("SAVE_GAME", "Save Game");
var button = AddButton("SAVE_GAME", SaveGameButton);
button.IsDisabled = () => hasError || leaving || !world.Players.Any(p => p.Playable && p.WinState == WinState.Undefined);
button.OnClick = () =>
{
@@ -307,7 +406,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
void CreateMusicButton()
{
var button = AddButton("MUSIC", "Music");
var button = AddButton("MUSIC", MusicButton);
button.OnClick = () =>
{
hideMenu = true;
@@ -321,7 +420,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
void CreateSettingsButton()
{
var button = AddButton("SETTINGS", "Settings");
var button = AddButton("SETTINGS", SettingsButton);
button.OnClick = () =>
{
hideMenu = true;
@@ -336,7 +435,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
void CreateResumeButton()
{
var button = AddButton("RESUME", world.IsGameOver ? "Return to map" : "Resume");
var button = AddButton("RESUME", world.IsGameOver ? ReturnToMap : Resume);
button.Key = modData.Hotkeys["escape"];
button.OnClick = CloseMenu;
}
@@ -346,7 +445,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (world.Type != WorldType.Editor)
return;
var button = AddButton("SAVE_MAP", "Save Map");
var button = AddButton("SAVE_MAP", SaveMapButton);
button.OnClick = () =>
{
hideMenu = true;
@@ -358,11 +457,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var playerCount = new MapPlayers(playerDefinitions).Players.Count;
if (playerCount > MapPlayers.MaximumPlayerCount)
{
ConfirmationDialogs.ButtonPrompt(
title: "Error: Max player count exceeded",
text: $"There are too many players defined ({playerCount}/{MapPlayers.MaximumPlayerCount}).",
ConfirmationDialogs.ButtonPrompt(modData,
title: ErrorMaxPlayerTitle,
text: ErrorMaxPlayerPrompt,
textArguments: Translation.Arguments("players", playerCount, "max", MapPlayers.MaximumPlayerCount),
onConfirm: ShowMenu,
confirmText: "Back");
confirmText: ErrorMaxPlayerAccept);
return;
}
@@ -384,7 +484,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
return;
var actionManager = world.WorldActor.Trait<EditorActionManager>();
var button = AddButton("EXIT_EDITOR", "Exit Map Editor");
var button = AddButton("EXIT_EDITOR", ExitMapButton);
// Show dialog only if updated since last save
button.OnClick = () =>
@@ -394,10 +494,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (actionManager.HasUnsavedItems() || deletedOrUnavailable)
{
hideMenu = true;
ConfirmationDialogs.ButtonPrompt(
title: "Warning",
text: deletedOrUnavailable ? "The map may have been deleted outside the editor" : "Exit and lose all unsaved changes?",
confirmText: deletedOrUnavailable ? "Exit anyway" : "Exit",
ConfirmationDialogs.ButtonPrompt(modData,
title: ExitMapEditorTitle,
text: deletedOrUnavailable ? ExitMapEditorPromptDeleted : ExitMapEditorPromptUnsaved,
confirmText: deletedOrUnavailable ? ExitMapEditorAnywayConfirm : ExitMapEditorConfirm,
onConfirm: OnQuit,
onCancel: ShowMenu);
}

View File

@@ -48,7 +48,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
static readonly string Players = "players";
[TranslationReference("team")]
static readonly string Team = "team-no-team";
static readonly string TeamNumber = "team-number";
[TranslationReference]
static readonly string NoTeam = "no-team";
class CameraOption
{
@@ -116,7 +119,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
foreach (var t in teams)
{
totalPlayers += t.Count();
var label = noTeams ? modData.Translation.GetString(Players) : modData.Translation.GetString(Team, Translation.Arguments("team", t.Key));
var label = noTeams ? modData.Translation.GetString(Players) : t.Key > 0
? modData.Translation.GetString(TeamNumber, Translation.Arguments("team", t.Key))
: modData.Translation.GetString(NoTeam);
groups.Add(label, t);
}

View File

@@ -82,7 +82,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
static readonly string ArmyGraph = "army-graph";
[TranslationReference("team")]
static readonly string Team = "team-no-team";
static readonly string TeamNumber = "team-number";
[TranslationReference]
static readonly string NoTeam = "no-team";
[ObjectCreator.UseCtor]
public ObserverStatsLogic(World world, ModData modData, WorldRenderer worldRenderer, Widget widget, Dictionary<string, MiniYaml> logicArgs)
@@ -91,7 +94,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
this.worldRenderer = worldRenderer;
MiniYaml yaml;
string[] keyNames = Enum.GetNames(typeof(ObserverStatsPanel));
var keyNames = Enum.GetNames(typeof(ObserverStatsPanel));
var statsHotkeys = new HotkeyReference[keyNames.Length];
for (var i = 0; i < keyNames.Length; i++)
statsHotkeys[i] = logicArgs.TryGetValue("Statistics" + keyNames[i] + "Key", out yaml) ? modData.Hotkeys[yaml.Value] : new HotkeyReference();
@@ -144,7 +147,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
title = modData.Translation.GetString(title);
return new StatsDropDownOption
{
Title = title,
Title = modData.Translation.GetString(title),
IsSelected = () => activePanel == panel,
OnClick = () =>
{
@@ -272,9 +275,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
tt.IgnoreMouseOver = true;
var teamLabel = tt.Get<LabelWidget>("TEAM");
var teamText = modData.Translation.GetString(Team, Translation.Arguments("team-no-team", team.Key));
var teamText = team.Key > 0 ? modData.Translation.GetString(TeamNumber, Translation.Arguments("team", team.Key))
: modData.Translation.GetString(NoTeam);
teamLabel.GetText = () => teamText;
tt.Bounds.Width = teamLabel.Bounds.Width = Game.Renderer.Fonts[tt.Font].Measure(tt.Get<LabelWidget>("TEAM").GetText()).X;
tt.Bounds.Width = teamLabel.Bounds.Width = Game.Renderer.Fonts[tt.Font].Measure(teamText).X;
var colorBlockWidget = tt.Get<ColorBlockWidget>("TEAM_COLOR");
var scrollBarOffset = playerStatsPanel.ScrollBar != ScrollBar.Hidden

View File

@@ -24,6 +24,41 @@ namespace OpenRA.Mods.Common.Widgets.Logic
public class DownloadPackageLogic : ChromeLogic
{
static readonly string[] SizeSuffixes = { "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
[TranslationReference("title")]
static readonly string Downloading = "downloading";
[TranslationReference]
static readonly string FetchingMirrorList = "fetching-mirror-list";
[TranslationReference]
static readonly string UnknownHost = "unknown-host";
[TranslationReference("host", "received", "suffix")]
static readonly string DownloadingFrom = "downloading-from";
[TranslationReference("host", "received", "total", "suffix", "progress")]
static readonly string DownloadingFromProgress = "downloading-from-progress";
[TranslationReference]
static readonly string VerifyingArchive = "verifying-archive";
[TranslationReference]
static readonly string ArchiveValidationFailed = "archive-validation-failed";
[TranslationReference]
static readonly string Extracting = "extracting";
[TranslationReference("entry")]
static readonly string ExtractingEntry = "extracting-entry";
[TranslationReference]
static readonly string ArchiveExtractionFailed = "archive-extraction-failed";
[TranslationReference]
static readonly string MirrorSelectionFailed = "mirror-selection-failed";
readonly ModData modData;
readonly ModContent.ModDownload download;
readonly Action onSuccess;
@@ -34,8 +69,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
string downloadHost;
[ObjectCreator.UseCtor]
public DownloadPackageLogic(Widget widget, ModContent.ModDownload download, Action onSuccess)
public DownloadPackageLogic(Widget widget, ModData modData, ModContent.ModDownload download, Action onSuccess)
{
this.modData = modData;
this.download = download;
this.onSuccess = onSuccess;
@@ -49,7 +85,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var status = new CachedTransform<string, string>(s => WidgetUtils.TruncateText(s, statusLabel.Bounds.Width, statusFont));
statusLabel.GetText = () => status.Update(getStatusText());
var text = $"Downloading {download.Title}";
var text = modData.Translation.GetString(Downloading, Translation.Arguments("title", download.Title));
panel.Get<LabelWidget>("TITLE").Text = text;
ShowDownloadDialog();
@@ -57,7 +93,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
void ShowDownloadDialog()
{
getStatusText = () => "Fetching list of mirrors...";
getStatusText = () => modData.Translation.GetString(FetchingMirrorList);
progressBar.Indeterminate = true;
var retryButton = panel.Get<ButtonWidget>("RETRY_BUTTON");
@@ -71,6 +107,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var dataTotal = 0.0f;
var mag = 0;
var dataSuffix = "";
var host = downloadHost ?? UnknownHost;
if (total < 0)
{
@@ -78,7 +115,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
dataReceived = read / (float)(1L << (mag * 10));
dataSuffix = SizeSuffixes[mag];
getStatusText = () => $"Downloading from {downloadHost ?? "unknown host"} {dataReceived:0.00} {dataSuffix}";
getStatusText = () => modData.Translation.GetString(DownloadingFrom,
Translation.Arguments("host", host, "received", $"{dataReceived:0.00}", "suffix", dataSuffix));
progressBar.Indeterminate = true;
}
else
@@ -88,7 +126,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
dataReceived = read / (float)(1L << (mag * 10));
dataSuffix = SizeSuffixes[mag];
getStatusText = () => $"Downloading from {downloadHost ?? "unknown host"} {dataReceived:0.00}/{dataTotal:0.00} {dataSuffix} ({progressPercentage}%)";
getStatusText = () => modData.Translation.GetString(DownloadingFromProgress,
Translation.Arguments("host", host, "received", $"{dataReceived:0.00}", "total", $"{dataTotal:0.00}",
"suffix", dataSuffix, "progress", progressPercentage));
progressBar.Indeterminate = false;
}
@@ -142,7 +182,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
// Validate integrity
if (!string.IsNullOrEmpty(download.SHA1))
{
getStatusText = () => "Verifying archive...";
getStatusText = () => modData.Translation.GetString(VerifyingArchive);
progressBar.Indeterminate = true;
var archiveValid = false;
@@ -164,13 +204,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (!archiveValid)
{
onError("Archive validation failed");
onError(modData.Translation.GetString(ArchiveValidationFailed));
return;
}
}
// Automatically extract
getStatusText = () => "Extracting...";
getStatusText = () => modData.Translation.GetString(Extracting);
progressBar.Indeterminate = true;
var extracted = new List<string>();
@@ -185,7 +225,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (entry == null || !entry.IsFile)
continue;
onExtractProgress("Extracting " + entry.Name);
onExtractProgress(modData.Translation.GetString(ExtractingEntry, Translation.Arguments("entry", entry.Name)));
Log.Write("install", "Extracting " + entry.Name);
var targetPath = Platform.ResolvePath(kv.Key);
Directory.CreateDirectory(Path.GetDirectoryName(targetPath));
@@ -215,7 +255,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
File.Delete(f);
}
onError("Archive extraction failed");
onError(modData.Translation.GetString(ArchiveExtractionFailed));
}
}
catch (Exception e)
@@ -248,7 +288,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
Log.Write("install", "Mirror selection failed with error:");
Log.Write("install", e.ToString());
onError("Online mirror is not available. Please install from an original disc.");
onError(modData.Translation.GetString(MirrorSelectionFailed));
}
});
}

View File

@@ -27,6 +27,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
enum Mode { Progress, Message, List }
readonly ModData modData;
readonly ModContent content;
readonly Dictionary<string, ModContent.ModSource> sources;
@@ -53,9 +54,67 @@ namespace OpenRA.Mods.Common.Widgets.Logic
Mode visible = Mode.Progress;
[TranslationReference]
static readonly string DetectingDrives = "detecting-drives";
[TranslationReference]
static readonly string CheckingDiscs = "checking-discs";
[TranslationReference("title")]
static readonly string SearchingDiscFor = "searching-disc-for";
[TranslationReference]
static readonly string ContentPackageInstallation = "content-package-installation";
[TranslationReference]
static readonly string GameDiscs = "game-discs";
[TranslationReference]
static readonly string DigitalInstalls = "digital-installs";
[TranslationReference]
static readonly string GameContentNotFound = "game-content-not-found";
[TranslationReference]
static readonly string AlternativeContentSources = "alternative-content-sources";
[TranslationReference]
static readonly string InstallingContent = "installing-content";
[TranslationReference("filename")]
static readonly string CopyingFilename = "copying-filename";
[TranslationReference("filename", "progress")]
static readonly string CopyingFilenameProgress = "copying-filename-progress";
[TranslationReference]
static readonly string InstallationFailed = "installation-failed";
[TranslationReference]
static readonly string CheckInstallLog = "check-install-log";
[TranslationReference("filename")]
static readonly string Extracing = "extracting-filename";
[TranslationReference("filename", "progress")]
static readonly string ExtracingProgress = "extracting-filename-progress";
[TranslationReference]
static readonly string Continue = "continue";
[TranslationReference]
static readonly string Cancel = "cancel";
[TranslationReference]
static readonly string Retry = "retry";
[TranslationReference]
static readonly string Back = "back";
[ObjectCreator.UseCtor]
public InstallFromDiscLogic(Widget widget, ModContent content, Dictionary<string, ModContent.ModSource> sources)
public InstallFromDiscLogic(Widget widget, ModData modData, ModContent content, Dictionary<string, ModContent.ModSource> sources)
{
this.modData = modData;
this.content = content;
this.sources = sources;
@@ -108,8 +167,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
void DetectContentDisks()
{
var message = "Detecting drives";
ShowProgressbar("Checking Discs", () => message);
var message = modData.Translation.GetString(DetectingDrives);
ShowProgressbar(modData.Translation.GetString(CheckingDiscs), () => message);
ShowBackRetry(DetectContentDisks);
new Task(() =>
@@ -132,7 +191,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
foreach (var kv in sources)
{
message = "Searching for " + kv.Value.Title;
message = modData.Translation.GetString(SearchingDiscFor, Translation.Arguments("title", kv.Value.Title));
var path = FindSourcePath(kv.Value, volumes);
if (path != null)
@@ -148,7 +207,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
Game.RunAfterTick(() =>
{
ShowList(kv.Value.Title, "The following content packages will be installed:", packages);
ShowList(kv.Value.Title, modData.Translation.GetString(ContentPackageInstallation), packages);
ShowContinueCancel(() => InstallFromDisc(path, kv.Value));
});
@@ -169,7 +228,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var options = new Dictionary<string, IEnumerable<string>>()
{
{ "Game Discs", discs },
{ modData.Translation.GetString(GameDiscs), discs },
};
if (Platform.CurrentPlatform == PlatformType.Windows)
@@ -179,12 +238,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
.Select(s => s.Title)
.Distinct();
options.Add("Digital Installs", installations);
options.Add(modData.Translation.GetString(DigitalInstalls), installations);
}
Game.RunAfterTick(() =>
{
ShowList("Game Content Not Found", "Please insert or install one of the following content sources:", options);
ShowList(modData.Translation.GetString(GameContentNotFound), modData.Translation.GetString(AlternativeContentSources), options);
ShowBackRetry(DetectContentDisks);
});
}).Start();
@@ -193,7 +252,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
void InstallFromDisc(string path, ModContent.ModSource modSource)
{
var message = "";
ShowProgressbar("Installing Content", () => message);
ShowProgressbar(modData.Translation.GetString(InstallingContent), () => message);
ShowDisabledCancel();
new Task(() =>
@@ -231,9 +290,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
Action<long> onProgress = null;
if (length < ShowPercentageThreshold)
message = "Copying " + displayFilename;
message = modData.Translation.GetString(CopyingFilename, Translation.Arguments("filename", displayFilename));
else
onProgress = b => message = $"Copying {displayFilename} ({100 * b / length}%)";
onProgress = b => message = modData.Translation.GetString(CopyingFilenameProgress, Translation.Arguments("filename", displayFilename, "progress", 100 * b / length));
CopyStream(source, target, length, onProgress);
}
@@ -244,25 +303,25 @@ namespace OpenRA.Mods.Common.Widgets.Logic
case "extract-raw":
{
ExtractFromPackage(ExtractionType.Raw, path, i.Value, extracted, m => message = m);
ExtractFromPackage(modData, ExtractionType.Raw, path, i.Value, extracted, m => message = m);
break;
}
case "extract-blast":
{
ExtractFromPackage(ExtractionType.Blast, path, i.Value, extracted, m => message = m);
ExtractFromPackage(modData, ExtractionType.Blast, path, i.Value, extracted, m => message = m);
break;
}
case "extract-mscab":
{
ExtractFromMSCab(path, i.Value, extracted, m => message = m);
ExtractFromMSCab(modData, path, i.Value, extracted, m => message = m);
break;
}
case "extract-iscab":
{
ExtractFromISCab(path, i.Value, extracted, m => message = m);
ExtractFromISCab(modData, path, i.Value, extracted, m => message = m);
break;
}
@@ -296,7 +355,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
Game.RunAfterTick(() =>
{
ShowMessage("Installation Failed", "Refer to install.log in the logs directory for details.");
ShowMessage(modData.Translation.GetString(InstallationFailed), modData.Translation.GetString(CheckInstallLog));
ShowBackRetry(() => InstallFromDisc(path, modSource));
});
}
@@ -320,7 +379,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
enum ExtractionType { Raw, Blast }
static void ExtractFromPackage(ExtractionType type, string path, MiniYaml actionYaml, List<string> extractedFiles, Action<string> updateMessage)
static void ExtractFromPackage(ModData modData, ExtractionType type, string path, MiniYaml actionYaml, List<string> extractedFiles, Action<string> updateMessage)
{
// Yaml path may be specified relative to a named directory (e.g. ^SupportDir) or the detected disc path
var sourcePath = actionYaml.Value.StartsWith("^") ? Platform.ResolvePath(actionYaml.Value) : Path.Combine(path, actionYaml.Value);
@@ -360,9 +419,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
Action<long> onProgress = null;
if (length < ShowPercentageThreshold)
updateMessage("Extracting " + displayFilename);
updateMessage(modData.Translation.GetString(Extracing, Translation.Arguments("filename", displayFilename)));
else
onProgress = b => updateMessage($"Extracting {displayFilename} ({100 * b / length}%)");
onProgress = b => updateMessage(modData.Translation.GetString(ExtracingProgress, Translation.Arguments("filename", displayFilename, "progress", 100 * b / length)));
using (var target = File.OpenWrite(targetPath))
{
@@ -376,7 +435,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
}
}
static void ExtractFromMSCab(string path, MiniYaml actionYaml, List<string> extractedFiles, Action<string> updateMessage)
static void ExtractFromMSCab(ModData modData, string path, MiniYaml actionYaml, List<string> extractedFiles, Action<string> updateMessage)
{
// Yaml path may be specified relative to a named directory (e.g. ^SupportDir) or the detected disc path
var sourcePath = actionYaml.Value.StartsWith("^") ? Platform.ResolvePath(actionYaml.Value) : Path.Combine(path, actionYaml.Value);
@@ -400,14 +459,14 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
Log.Write("install", $"Extracting {sourcePath} -> {targetPath}");
var displayFilename = Path.GetFileName(Path.GetFileName(targetPath));
Action<int> onProgress = percent => updateMessage($"Extracting {displayFilename} ({percent}%)");
Action<int> onProgress = percent => updateMessage(modData.Translation.GetString(ExtracingProgress, Translation.Arguments("filename", displayFilename, "progress", percent)));
reader.ExtractFile(node.Value.Value, target, onProgress);
}
}
}
}
static void ExtractFromISCab(string path, MiniYaml actionYaml, List<string> extractedFiles, Action<string> updateMessage)
static void ExtractFromISCab(ModData modData, string path, MiniYaml actionYaml, List<string> extractedFiles, Action<string> updateMessage)
{
// Yaml path may be specified relative to a named directory (e.g. ^SupportDir) or the detected disc path
var sourcePath = actionYaml.Value.StartsWith("^") ? Platform.ResolvePath(actionYaml.Value) : Path.Combine(path, actionYaml.Value);
@@ -449,7 +508,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
Log.Write("install", $"Extracting {sourcePath} -> {targetPath}");
var displayFilename = Path.GetFileName(Path.GetFileName(targetPath));
Action<int> onProgress = percent => updateMessage($"Extracting {displayFilename} ({percent}%)");
Action<int> onProgress = percent => updateMessage(modData.Translation.GetString(ExtracingProgress, Translation.Arguments("filename", displayFilename, "progress", percent)));
reader.ExtractFile(node.Value.Value, target, onProgress);
}
}
@@ -627,11 +686,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
void ShowContinueCancel(Action continueAction)
{
primaryButton.OnClick = continueAction;
primaryButton.Text = "Continue";
primaryButton.Text = modData.Translation.GetString(Continue);
primaryButton.Visible = true;
secondaryButton.OnClick = Ui.CloseWindow;
secondaryButton.Text = "Cancel";
secondaryButton.Text = modData.Translation.GetString(Cancel);
secondaryButton.Visible = true;
secondaryButton.Disabled = false;
Game.RunAfterTick(Ui.ResetTooltips);
@@ -640,11 +699,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
void ShowBackRetry(Action retryAction)
{
primaryButton.OnClick = retryAction;
primaryButton.Text = "Retry";
primaryButton.Text = modData.Translation.GetString(Retry);
primaryButton.Visible = true;
secondaryButton.OnClick = Ui.CloseWindow;
secondaryButton.Text = "Back";
secondaryButton.Text = modData.Translation.GetString(Back);
secondaryButton.Visible = true;
secondaryButton.Disabled = false;
Game.RunAfterTick(Ui.ResetTooltips);

View File

@@ -20,6 +20,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
public class ModContentLogic : ChromeLogic
{
readonly ModData modData;
readonly ModContent content;
readonly ScrollPanelWidget scrollPanel;
readonly Widget template;
@@ -29,9 +30,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
bool discAvailable;
[TranslationReference]
static readonly string ManualInstall = "manual-install";
[ObjectCreator.UseCtor]
public ModContentLogic(Widget widget, Manifest mod, ModContent content, Action onCancel)
public ModContentLogic(ModData modData, Widget widget, Manifest mod, ModContent content, Action onCancel)
{
this.modData = modData;
this.content = content;
var panel = widget.Get("CONTENT_PANEL");
@@ -137,7 +142,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var requiresDiscWidget = container.Get<LabelWidget>("REQUIRES_DISC");
requiresDiscWidget.IsVisible = () => !installed && !downloadEnabled;
if (!isSourceAvailable)
requiresDiscWidget.GetText = () => "Manual Install";
{
var manualInstall = modData.Translation.GetString(ManualInstall);
requiresDiscWidget.GetText = () => manualInstall;
}
scrollPanel.AddChild(container);
}

View File

@@ -23,12 +23,21 @@ namespace OpenRA.Mods.Common.Widgets.Logic
readonly ModContent content;
bool requiredContentInstalled;
[TranslationReference]
static readonly string Continue = "continue";
[TranslationReference]
static readonly string Quit = "quit";
[ObjectCreator.UseCtor]
public ModContentPromptLogic(Widget widget, Manifest mod, ModContent content, Action continueLoading)
public ModContentPromptLogic(ModData modData, Widget widget, Manifest mod, ModContent content, Action continueLoading)
{
this.content = content;
CheckRequiredContentInstalled();
var continueMessage = modData.Translation.GetString(Continue);
var quitMessage = modData.Translation.GetString(Quit);
var panel = widget.Get("CONTENT_PROMPT_PANEL");
var headerTemplate = panel.Get<LabelWidget>("HEADER_TEMPLATE");
var headerLines = !string.IsNullOrEmpty(content.InstallPromptMessage) ? content.InstallPromptMessage.Replace("\\n", "\n").Split('\n') : Array.Empty<string>();
@@ -83,7 +92,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
};
var quitButton = panel.Get<ButtonWidget>("QUIT_BUTTON");
quitButton.GetText = () => requiredContentInstalled ? "Continue" : "Quit";
quitButton.GetText = () => requiredContentInstalled ? continueMessage : quitMessage;
quitButton.Bounds.Y += headerHeight;
quitButton.OnClick = () =>
{

View File

@@ -26,6 +26,14 @@ namespace OpenRA.Mods.Common.Widgets.Logic
return Game.Settings.Game.IntroductionPromptVersion < IntroductionVersion;
}
[TranslationReference]
static readonly string Classic = "classic";
readonly string classic;
[TranslationReference]
static readonly string Modern = "modern";
readonly string modern;
[ObjectCreator.UseCtor]
public IntroductionPromptLogic(Widget widget, ModData modData, WorldRenderer worldRenderer, Action onComplete)
{
@@ -33,6 +41,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var ds = Game.Settings.Graphics;
var gs = Game.Settings.Game;
classic = modData.Translation.GetString(Classic);
modern = modData.Translation.GetString(Modern);
var escPressed = false;
var nameTextfield = widget.Get<TextFieldWidget>("PLAYERNAME");
nameTextfield.IsDisabled = () => worldRenderer.World.Type != WorldType.Shellmap;
@@ -74,8 +85,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
mouseControlDescModern.IsVisible = () => !gs.UseClassicMouseStyle;
var mouseControlDropdown = widget.Get<DropDownButtonWidget>("MOUSE_CONTROL_DROPDOWN");
mouseControlDropdown.OnMouseDown = _ => InputSettingsLogic.ShowMouseControlDropdown(mouseControlDropdown, gs);
mouseControlDropdown.GetText = () => gs.UseClassicMouseStyle ? "Classic" : "Modern";
mouseControlDropdown.OnMouseDown = _ => InputSettingsLogic.ShowMouseControlDropdown(modData, mouseControlDropdown, gs);
mouseControlDropdown.GetText = () => gs.UseClassicMouseStyle ? classic : modern;
foreach (var container in new[] { mouseControlDescClassic, mouseControlDescModern })
{
@@ -113,8 +124,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var viewportSizes = modData.Manifest.Get<WorldViewportSizes>();
var battlefieldCameraDropDown = widget.Get<DropDownButtonWidget>("BATTLEFIELD_CAMERA_DROPDOWN");
var battlefieldCameraLabel = new CachedTransform<WorldViewport, string>(vs => DisplaySettingsLogic.ViewportSizeNames[vs]);
battlefieldCameraDropDown.OnMouseDown = _ => DisplaySettingsLogic.ShowBattlefieldCameraDropdown(battlefieldCameraDropDown, viewportSizes, ds);
var battlefieldCameraLabel = new CachedTransform<WorldViewport, string>(vs => DisplaySettingsLogic.GetViewportSizeName(modData, vs));
battlefieldCameraDropDown.OnMouseDown = _ => DisplaySettingsLogic.ShowBattlefieldCameraDropdown(modData, battlefieldCameraDropDown, viewportSizes, ds);
battlefieldCameraDropDown.GetText = () => battlefieldCameraLabel.Update(ds.ViewportDistance);
var uiScaleDropdown = widget.Get<DropDownButtonWidget>("UI_SCALE_DROPDOWN");

View File

@@ -16,10 +16,14 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
class KickClientLogic : ChromeLogic
{
[TranslationReference("player")]
static readonly string KickClient = "kick-client";
[ObjectCreator.UseCtor]
public KickClientLogic(Widget widget, string clientName, Action<bool> okPressed, Action cancelPressed)
public KickClientLogic(ModData modData, Widget widget, string clientName, Action<bool> okPressed, Action cancelPressed)
{
widget.Get<LabelWidget>("TITLE").GetText = () => $"Kick {clientName}?";
var kickMessage = modData.Translation.GetString(KickClient, Translation.Arguments("player", clientName));
widget.Get<LabelWidget>("TITLE").GetText = () => kickMessage;
var tempBan = false;
var preventRejoiningCheckbox = widget.Get<CheckboxWidget>("PREVENT_REJOINING_CHECKBOX");

View File

@@ -16,10 +16,14 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
class KickSpectatorsLogic : ChromeLogic
{
[TranslationReference("count")]
static readonly string KickSpectators = "kick-spectators";
[ObjectCreator.UseCtor]
public KickSpectatorsLogic(Widget widget, int clientCount, Action okPressed, Action cancelPressed)
public KickSpectatorsLogic(ModData modData, Widget widget, int clientCount, Action okPressed, Action cancelPressed)
{
widget.Get<LabelWidget>("TEXT").GetText = () => $"Are you sure you want to kick {clientCount} spectators?";
var kickMessage = modData.Translation.GetString(KickSpectators, Translation.Arguments("count", clientCount));
widget.Get<LabelWidget>("TEXT").GetText = () => kickMessage;
widget.Get<ButtonWidget>("OK_BUTTON").OnClick = () =>
{

View File

@@ -47,7 +47,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
readonly ScrollPanelWidget lobbyChatPanel;
readonly Dictionary<TextNotificationPool, Widget> chatTemplates = new Dictionary<TextNotificationPool, Widget>();
readonly TextFieldWidget chatTextField;
readonly CachedTransform<int, string> chatDisabledLabel;
readonly CachedTransform<int, string> chatAvailableIn;
readonly string chatDisabled;
readonly ScrollPanelWidget players;
@@ -74,6 +75,42 @@ namespace OpenRA.Mods.Common.Widgets.Logic
bool MapIsPlayable => (mapStatus & Session.MapStatus.Playable) == Session.MapStatus.Playable;
[TranslationReference]
static readonly string Add = "add";
[TranslationReference]
static readonly string Remove = "remove";
[TranslationReference]
static readonly string ConfigureBots = "configure-bots";
[TranslationReference("count")]
static readonly string NumberTeams = "n-teams";
[TranslationReference]
static readonly string HumanVsBots = "humans-vs-bots";
[TranslationReference]
static readonly string FreeForAll = "free-for-all";
[TranslationReference]
static readonly string ConfigureTeams = "configure-teams";
[TranslationReference]
static readonly string Back = "back";
[TranslationReference]
static readonly string Team = "team";
[TranslationReference]
static readonly string All = "all";
[TranslationReference("seconds")]
static readonly string ChatAvailability = "chat-availability";
[TranslationReference]
static readonly string ChatDisabled = "chat-disabled";
// Listen for connection failures
void ConnectionStateChanged(OrderManager om, string password, NetworkConnection connection)
{
@@ -226,7 +263,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
new DropDownOption()
{
Title = "Add",
Title = modData.Translation.GetString(Add),
IsSelected = () => false,
OnClick = () =>
{
@@ -245,7 +282,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
botOptions.Add(new DropDownOption()
{
Title = "Remove",
Title = modData.Translation.GetString(Remove),
IsSelected = () => false,
OnClick = () =>
{
@@ -259,7 +296,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
});
}
options.Add("Configure Bots", botOptions);
options.Add(modData.Translation.GetString(ConfigureBots), botOptions);
}
var teamCount = (orderManager.LobbyInfo.Slots.Count(s => !s.Value.LockTeam && orderManager.LobbyInfo.ClientInSlot(s.Key) != null) + 1) / 2;
@@ -267,7 +304,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
var teamOptions = Enumerable.Range(2, teamCount - 1).Reverse().Select(d => new DropDownOption
{
Title = $"{d} Teams",
Title = modData.Translation.GetString(NumberTeams, Translation.Arguments("count", d)),
IsSelected = () => false,
OnClick = () => orderManager.IssueOrder(Order.Command($"assignteams {d}"))
}).ToList();
@@ -276,7 +313,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
teamOptions.Add(new DropDownOption
{
Title = "Humans vs Bots",
Title = modData.Translation.GetString(HumanVsBots),
IsSelected = () => false,
OnClick = () => orderManager.IssueOrder(Order.Command("assignteams 1"))
});
@@ -284,12 +321,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
teamOptions.Add(new DropDownOption
{
Title = "Free for all",
Title = modData.Translation.GetString(FreeForAll),
IsSelected = () => false,
OnClick = () => orderManager.IssueOrder(Order.Command("assignteams 0"))
});
options.Add("Configure Teams", teamOptions);
options.Add(modData.Translation.GetString(ConfigureTeams), teamOptions);
}
Func<DropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (option, template) =>
@@ -407,7 +444,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
disconnectButton.OnClick = () => { Ui.CloseWindow(); onExit(); };
if (skirmishMode)
disconnectButton.Text = "Back";
disconnectButton.Text = modData.Translation.GetString(Back);
if (logicArgs.TryGetValue("ChatTemplates", out var templateIds))
{
@@ -419,7 +456,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
}
var chatMode = lobby.Get<ButtonWidget>("CHAT_MODE");
chatMode.GetText = () => teamChat ? "Team" : "All";
var team = modData.Translation.GetString(Team);
var all = modData.Translation.GetString(All);
chatMode.GetText = () => teamChat ? team : all;
chatMode.OnClick = () => teamChat ^= true;
chatMode.IsDisabled = () => disableTeamChat || !chatEnabled;
@@ -459,7 +498,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
chatTextField.OnEscKey = _ => chatTextField.YieldKeyboardFocus();
chatDisabledLabel = new CachedTransform<int, string>(x => x > 0 ? $"Chat available in {x} seconds..." : "Chat Disabled");
chatAvailableIn = new CachedTransform<int, string>(x => modData.Translation.GetString(ChatAvailability, Translation.Arguments("seconds", x)));
chatDisabled = modData.Translation.GetString(ChatDisabled);
lobbyChatPanel = lobby.Get<ScrollPanelWidget>("CHAT_DISPLAY");
lobbyChatPanel.RemoveChildren();
@@ -524,7 +564,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (TextNotificationsManager.ChatDisabledUntil != uint.MaxValue)
remaining = (int)(TextNotificationsManager.ChatDisabledUntil - Game.RunTime + 999) / 1000;
chatTextField.Text = chatDisabledLabel.Update(remaining);
chatTextField.Text = remaining == 0 ? chatDisabled : chatAvailableIn.Update(remaining);
}
}
@@ -612,9 +652,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
template = emptySlotTemplate.Clone();
if (isHost)
LobbyUtils.SetupEditableSlotWidget(template, slot, client, orderManager, map);
LobbyUtils.SetupEditableSlotWidget(template, slot, client, orderManager, map, modData);
else
LobbyUtils.SetupSlotWidget(template, slot, client);
LobbyUtils.SetupSlotWidget(template, modData, slot, client);
var join = template.Get<ButtonWidget>("JOIN");
join.IsVisible = () => !slot.Closed;
@@ -631,7 +671,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
LobbyUtils.SetupLatencyWidget(template, client, orderManager);
if (client.Bot != null)
LobbyUtils.SetupEditableSlotWidget(template, slot, client, orderManager, map);
LobbyUtils.SetupEditableSlotWidget(template, slot, client, orderManager, map, modData);
else
LobbyUtils.SetupEditableNameWidget(template, client, orderManager, worldRenderer);

View File

@@ -20,6 +20,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
public class LobbyOptionsLogic : ChromeLogic
{
readonly ModData modData;
readonly ScrollPanelWidget panel;
readonly Widget optionsContainer;
readonly Widget checkboxRowTemplate;
@@ -31,9 +32,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
readonly Func<bool> configurationDisabled;
MapPreview mapPreview;
[TranslationReference]
static readonly string NotAvailable = "not-available";
[ObjectCreator.UseCtor]
internal LobbyOptionsLogic(Widget widget, OrderManager orderManager, Func<MapPreview> getMap, Func<bool> configurationDisabled)
internal LobbyOptionsLogic(ModData modData, Widget widget, OrderManager orderManager, Func<MapPreview> getMap, Func<bool> configurationDisabled)
{
this.modData = modData;
this.getMap = getMap;
this.orderManager = orderManager;
this.configurationDisabled = configurationDisabled;
@@ -131,7 +136,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var getOptionLabel = new CachedTransform<string, string>(id =>
{
if (id == null || !option.Values.TryGetValue(id, out var value))
return "Not Available";
return modData.Translation.GetString(NotAvailable);
return value;
});

View File

@@ -23,6 +23,21 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
public static class LobbyUtils
{
[TranslationReference]
static readonly string Open = "open";
[TranslationReference]
static readonly string Closed = "closed";
[TranslationReference]
static readonly string Bots = "bots";
[TranslationReference]
static readonly string BotsDisabled = "bots-disabled";
[TranslationReference]
static readonly string Slot = "slot";
class SlotDropDownOption
{
public readonly string Title;
@@ -38,15 +53,17 @@ namespace OpenRA.Mods.Common.Widgets.Logic
}
public static void ShowSlotDropDown(DropDownButtonWidget dropdown, Session.Slot slot,
Session.Client client, OrderManager orderManager, MapPreview map)
Session.Client client, OrderManager orderManager, MapPreview map, ModData modData)
{
var open = modData.Translation.GetString(Open);
var closed = modData.Translation.GetString(Closed);
var options = new Dictionary<string, IEnumerable<SlotDropDownOption>>
{
{
"Slot", new List<SlotDropDownOption>
modData.Translation.GetString(Slot), new List<SlotDropDownOption>
{
new SlotDropDownOption("Open", "slot_open " + slot.PlayerReference, () => !slot.Closed && client == null),
new SlotDropDownOption("Closed", "slot_close " + slot.PlayerReference, () => slot.Closed)
new SlotDropDownOption(open, "slot_open " + slot.PlayerReference, () => !slot.Closed && client == null),
new SlotDropDownOption(closed, "slot_close " + slot.PlayerReference, () => slot.Closed)
}
}
};
@@ -63,7 +80,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
}
}
options.Add(bots.Count > 0 ? "Bots" : "Bots Disabled", bots);
options.Add(bots.Count > 0 ? Bots : BotsDisabled, bots);
Func<SlotDropDownOption, ScrollItemWidget, ScrollItemWidget> setupItem = (o, itemTemplate) =>
{
@@ -436,7 +453,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
}
public static void SetupEditableSlotWidget(Widget parent, Session.Slot s, Session.Client c,
OrderManager orderManager, MapPreview map)
OrderManager orderManager, MapPreview map, ModData modData)
{
var slot = parent.Get<DropDownButtonWidget>("SLOT_OPTIONS");
slot.IsVisible = () => true;
@@ -446,18 +463,22 @@ namespace OpenRA.Mods.Common.Widgets.Logic
WidgetUtils.TruncateText(name, slot.Bounds.Width - slot.Bounds.Height - slot.LeftMargin - slot.RightMargin,
Game.Renderer.Fonts[slot.Font]));
slot.GetText = () => truncated.Update(c != null ? c.Name : s.Closed ? "Closed" : "Open");
slot.OnMouseDown = _ => ShowSlotDropDown(slot, s, c, orderManager, map);
var closed = modData.Translation.GetString(Closed);
var open = modData.Translation.GetString(Open);
slot.GetText = () => truncated.Update(c != null ? c.Name : s.Closed ? closed : open);
slot.OnMouseDown = _ => ShowSlotDropDown(slot, s, c, orderManager, map, modData);
// Ensure Name selector (if present) is hidden
HideChildWidget(parent, "NAME");
}
public static void SetupSlotWidget(Widget parent, Session.Slot s, Session.Client c)
public static void SetupSlotWidget(Widget parent, ModData modData, Session.Slot s, Session.Client c)
{
var name = parent.Get<LabelWidget>("NAME");
name.IsVisible = () => true;
name.GetText = () => c != null ? c.Name : s.Closed ? "Closed" : "Open";
name.GetText = () => c != null ? c.Name : s.Closed
? modData.Translation.GetString(Closed)
: modData.Translation.GetString(Open);
// Ensure Slot selector (if present) is hidden
HideChildWidget(parent, "SLOT_OPTIONS");

View File

@@ -23,6 +23,24 @@ namespace OpenRA.Mods.Common.Widgets.Logic
bool installHighlighted;
int blinkTick;
[TranslationReference]
static readonly string Connecting = "connecting";
[TranslationReference("size")]
static readonly string Downloading = "downloading-map";
[TranslationReference("size", "progress")]
static readonly string DownloadingPercentage = "downloading-map-progress";
[TranslationReference]
static readonly string RetryInstall = "retry-install";
[TranslationReference]
static readonly string RetrySearch = "retry-search";
[TranslationReference("author")]
static readonly string CreatedBy = "created-by";
[ObjectCreator.UseCtor]
internal MapPreviewLogic(Widget widget, ModData modData, OrderManager orderManager, Func<(MapPreview Map, Session.MapStatus Status)> getMap,
Action<MapPreviewWidget, MapPreview, MouseInput> onMouseDown, Func<Dictionary<int, SpawnOccupant>> getSpawnOccupants,
@@ -40,7 +58,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
return map.Status == MapStatus.Available && isPlayable;
};
SetupWidgets(available, getMap, onMouseDown, getSpawnOccupants, getDisabledSpawnPoints, showUnoccupiedSpawnpoints);
SetupWidgets(available, modData, getMap, onMouseDown, getSpawnOccupants, getDisabledSpawnPoints, showUnoccupiedSpawnpoints);
}
var invalid = widget.GetOrNull("MAP_INVALID");
@@ -52,7 +70,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
return map.Status == MapStatus.Available && (serverStatus & Session.MapStatus.Incompatible) != 0;
};
SetupWidgets(invalid, getMap, onMouseDown, getSpawnOccupants, getDisabledSpawnPoints, showUnoccupiedSpawnpoints);
SetupWidgets(invalid, modData, getMap, onMouseDown, getSpawnOccupants, getDisabledSpawnPoints, showUnoccupiedSpawnpoints);
}
var validating = widget.GetOrNull("MAP_VALIDATING");
@@ -64,7 +82,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
return map.Status == MapStatus.Available && (serverStatus & Session.MapStatus.Validating) != 0;
};
SetupWidgets(validating, getMap, onMouseDown, getSpawnOccupants, getDisabledSpawnPoints, showUnoccupiedSpawnpoints);
SetupWidgets(validating, modData, getMap, onMouseDown, getSpawnOccupants, getDisabledSpawnPoints, showUnoccupiedSpawnpoints);
}
var download = widget.GetOrNull("MAP_DOWNLOADABLE");
@@ -72,7 +90,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
download.IsVisible = () => getMap().Map.Status == MapStatus.DownloadAvailable;
SetupWidgets(download, getMap, onMouseDown, getSpawnOccupants, getDisabledSpawnPoints, showUnoccupiedSpawnpoints);
SetupWidgets(download, modData, getMap, onMouseDown, getSpawnOccupants, getDisabledSpawnPoints, showUnoccupiedSpawnpoints);
var install = download.GetOrNull<ButtonWidget>("MAP_INSTALL");
if (install != null)
@@ -99,7 +117,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
return map.Status != MapStatus.Available && map.Status != MapStatus.DownloadAvailable;
};
SetupWidgets(progress, getMap, onMouseDown, getSpawnOccupants, getDisabledSpawnPoints, showUnoccupiedSpawnpoints);
SetupWidgets(progress, modData, getMap, onMouseDown, getSpawnOccupants, getDisabledSpawnPoints, showUnoccupiedSpawnpoints);
var statusSearching = progress.GetOrNull("MAP_STATUS_SEARCHING");
if (statusSearching != null)
@@ -134,13 +152,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
var (map, _) = getMap();
if (map.DownloadBytes == 0)
return "Connecting...";
return modData.Translation.GetString(Connecting);
// Server does not provide the total file length
if (map.DownloadPercentage == 0)
return $"Downloading {map.DownloadBytes / 1024} kB";
modData.Translation.GetString(Downloading, Translation.Arguments("size", map.DownloadBytes / 1024));
return $"Downloading {map.DownloadBytes / 1024} kB ({map.DownloadPercentage}%)";
return modData.Translation.GetString(DownloadingPercentage, Translation.Arguments("size", map.DownloadBytes / 1024, "progress", map.DownloadPercentage));
};
}
@@ -168,7 +186,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
modData.MapCache.QueryRemoteMapDetails(mapRepository, new[] { map.Uid });
};
retry.GetText = () => getMap().Map.Status == MapStatus.DownloadError ? "Retry Install" : "Retry Search";
retry.GetText = () => getMap().Map.Status == MapStatus.DownloadError
? modData.Translation.GetString(RetryInstall)
: modData.Translation.GetString(RetrySearch);
}
var progressbar = progress.GetOrNull<ProgressBarWidget>("MAP_PROGRESSBAR");
@@ -190,7 +210,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
}
}
void SetupWidgets(Widget parent,
static void SetupWidgets(Widget parent, ModData modData,
Func<(MapPreview Map, Session.MapStatus Status)> getMap,
Action<MapPreviewWidget, MapPreview, MouseInput> onMouseDown,
Func<Dictionary<int, SpawnOccupant>> getSpawnOccupants,
@@ -235,7 +255,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
var font = Game.Renderer.Fonts[authorLabel.Font];
var author = new CachedTransform<MapPreview, string>(
m => WidgetUtils.TruncateText($"Created by {m.Author}", authorLabel.Bounds.Width, font));
m => WidgetUtils.TruncateText(modData.Translation.GetString(CreatedBy, Translation.Arguments("author", m.Author)), authorLabel.Bounds.Width, font));
authorLabel.GetText = () => author.Update(getMap().Map);
}
}

View File

@@ -17,8 +17,19 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
public class SpawnSelectorTooltipLogic : ChromeLogic
{
[TranslationReference]
static readonly string DisabledSpawn = "disabled-spawn";
[TranslationReference]
static readonly string AvailableSpawn = "available-spawn";
[TranslationReference("team")]
static readonly string TeamNumber = "team-number";
readonly CachedTransform<int, string> teamMessage;
[ObjectCreator.UseCtor]
public SpawnSelectorTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, MapPreviewWidget preview, bool showUnoccupiedSpawnpoints)
public SpawnSelectorTooltipLogic(Widget widget, ModData modData, TooltipContainerWidget tooltipContainer, MapPreviewWidget preview, bool showUnoccupiedSpawnpoints)
{
var showTooltip = true;
widget.IsVisible = () => preview.TooltipSpawnIndex != -1 && showTooltip;
@@ -36,6 +47,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var labelText = "";
string playerFaction = null;
var playerTeam = -1;
teamMessage = new CachedTransform<int, string>(t => modData.Translation.GetString(TeamNumber, Translation.Arguments("team", t)));
var disabledSpawn = modData.Translation.GetString(DisabledSpawn);
var availableSpawn = modData.Translation.GetString(AvailableSpawn);
tooltipContainer.BeforeRender = () =>
{
@@ -58,7 +72,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
return;
}
labelText = preview.DisabledSpawnPoints().Contains(preview.TooltipSpawnIndex) ? "Disabled spawn" : "Available spawn";
labelText = preview.DisabledSpawnPoints().Contains(preview.TooltipSpawnIndex)
? disabledSpawn
: availableSpawn;
playerFaction = null;
playerTeam = 0;
widget.Bounds.Height = singleHeight;
@@ -75,7 +92,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
flag.IsVisible = () => playerFaction != null;
flag.GetImageCollection = () => "flags";
flag.GetImageName = () => playerFaction;
team.GetText = () => $"Team {playerTeam}";
team.GetText = () => teamMessage.Update(playerTeam);
team.IsVisible = () => playerTeam > 0;
}
}

View File

@@ -31,6 +31,16 @@ namespace OpenRA.Mods.Common.Widgets.Logic
readonly ScrollPanelWidget newsPanel;
readonly Widget newsTemplate;
readonly LabelWidget newsStatus;
readonly ModData modData;
[TranslationReference]
static readonly string LoadingNews = "loading-news";
[TranslationReference("message")]
static readonly string NewsRetrivalFailed = "news-retrival-failed";
[TranslationReference("message")]
static readonly string NewsParsingFailed = "news-parsing-failed";
// Update news once per game launch
static bool fetchedNews;
@@ -52,6 +62,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
[ObjectCreator.UseCtor]
public MainMenuLogic(Widget widget, World world, ModData modData)
{
this.modData = modData;
rootMenu = widget;
rootMenu.Get<LabelWidget>("VERSION_LABEL").Text = modData.Manifest.Metadata.Version;
@@ -205,7 +217,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
newsPanel.RemoveChild(newsTemplate);
newsStatus = newsPanel.Get<LabelWidget>("NEWS_STATUS");
SetNewsStatus("Loading news");
SetNewsStatus(modData.Translation.GetString(LoadingNews));
}
Game.OnRemoteDirectConnect += OnRemoteDirectConnect;
@@ -318,7 +330,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
Game.RunAfterTick(() => // run on the main thread
{
SetNewsStatus($"Failed to retrieve news: {e.Message}");
SetNewsStatus(modData.Translation.GetString(NewsRetrivalFailed, Translation.Arguments("message", e.Message)));
});
}
});
@@ -390,7 +402,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
}
catch (Exception ex)
{
SetNewsStatus($"Failed to parse news: {ex.Message}");
SetNewsStatus(modData.Translation.GetString(NewsParsingFailed, Translation.Arguments("message", ex.Message)));
}
return null;

View File

@@ -18,6 +18,52 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
public class MapChooserLogic : ChromeLogic
{
[TranslationReference]
static readonly string AllMaps = "all-maps";
readonly string allMaps;
[TranslationReference]
static readonly string NoMatches = "no-matches";
[TranslationReference("players")]
static readonly string Players = "player-players";
[TranslationReference("author")]
static readonly string CreatedBy = "created-by";
[TranslationReference]
static readonly string MapSizeHuge = "map-size-huge";
[TranslationReference]
static readonly string MapSizeLarge = "map-size-large";
[TranslationReference]
static readonly string MapSizeMedium = "map-size-medium";
[TranslationReference]
static readonly string MapSizeSmall = "map-size-small";
[TranslationReference("map")]
static readonly string MapDeletionFailed = "map-deletion-failed";
[TranslationReference]
static readonly string DeleteMapTitle = "delete-map-title";
[TranslationReference("title")]
static readonly string DeleteMapPrompt = "delete-map-prompt";
[TranslationReference]
static readonly string DeleteMapAccept = "delete-map-accept";
[TranslationReference]
static readonly string DeleteAllMapsTitle = "delete-all-maps-title";
[TranslationReference]
static readonly string DeleteAllMapsPrompt = "delete-all-maps-prompt";
[TranslationReference]
static readonly string DeleteAllMapsAccept = "delete-all-maps-accept";
readonly Widget widget;
readonly DropDownButtonWidget gameModeDropdown;
readonly ModData modData;
@@ -43,6 +89,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
this.modData = modData;
this.onSelect = onSelect;
allMaps = modData.Translation.GetString(AllMaps);
var approving = new Action(() =>
{
Ui.CloseWindow();
@@ -192,7 +240,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
// 'all game types' extra item
categories.Insert(0, (null as string, tabMaps[tab].Length));
Func<(string Category, int Count), string> showItem = x => $"{x.Category ?? "All Maps"} ({x.Count})";
Func<(string Category, int Count), string> showItem = x => (x.Category ?? allMaps) + $" ({x.Count})";
Func<(string Category, int Count), ScrollItemWidget, ScrollItemWidget> setupItem = (ii, template) =>
{
@@ -210,7 +258,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
var item = categories.FirstOrDefault(m => m.Category == category);
if (item == default((string, int)))
item.Category = "No matches";
item.Category = modData.Translation.GetString(NoMatches);
return showItem(item);
};
@@ -269,25 +317,23 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (type != null)
details = type + " ";
details += $"({preview.PlayerCount} players)";
details += modData.Translation.GetString(Players, Translation.Arguments("players", preview.PlayerCount));
detailsWidget.GetText = () => details;
}
var authorWidget = item.GetOrNull<LabelWithTooltipWidget>("AUTHOR");
if (authorWidget != null)
{
WidgetUtils.TruncateLabelToTooltip(authorWidget, $"Created by {preview.Author}");
}
if (authorWidget != null && !string.IsNullOrEmpty(preview.Author))
WidgetUtils.TruncateLabelToTooltip(authorWidget, modData.Translation.GetString(CreatedBy, Translation.Arguments("author", preview.Author)));
var sizeWidget = item.GetOrNull<LabelWidget>("SIZE");
if (sizeWidget != null)
{
var size = preview.Bounds.Width + "x" + preview.Bounds.Height;
var numberPlayableCells = preview.Bounds.Width * preview.Bounds.Height;
if (numberPlayableCells >= 120 * 120) size += " (Huge)";
else if (numberPlayableCells >= 90 * 90) size += " (Large)";
else if (numberPlayableCells >= 60 * 60) size += " (Medium)";
else size += " (Small)";
if (numberPlayableCells >= 120 * 120) size += " " + modData.Translation.GetString(MapSizeHuge);
else if (numberPlayableCells >= 90 * 90) size += " " + modData.Translation.GetString(MapSizeLarge);
else if (numberPlayableCells >= 60 * 60) size += " " + modData.Translation.GetString(MapSizeMedium);
else size += " " + modData.Translation.GetString(MapSizeSmall);
sizeWidget.GetText = () => size;
}
@@ -315,7 +361,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
}
catch (Exception ex)
{
TextNotificationsManager.Debug("Failed to delete map '{0}'. See the debug.log file for details.", map);
TextNotificationsManager.Debug(modData.Translation.GetString(MapDeletionFailed, Translation.Arguments("map", map)));
Log.Write("debug", ex.ToString());
}
@@ -324,23 +370,24 @@ namespace OpenRA.Mods.Common.Widgets.Logic
void DeleteOneMap(string map, Action<string> after)
{
ConfirmationDialogs.ButtonPrompt(
title: "Delete map",
text: $"Delete the map '{modData.MapCache[map].Title}'?",
ConfirmationDialogs.ButtonPrompt(modData,
title: DeleteMapTitle,
text: DeleteMapPrompt,
textArguments: Translation.Arguments("title", modData.MapCache[map].Title),
onConfirm: () =>
{
var newUid = DeleteMap(map);
after?.Invoke(newUid);
},
confirmText: "Delete",
confirmText: DeleteMapAccept,
onCancel: () => { });
}
void DeleteAllMaps(string[] maps, Action<string> after)
{
ConfirmationDialogs.ButtonPrompt(
title: "Delete maps",
text: "Delete all maps on this page?",
ConfirmationDialogs.ButtonPrompt(modData,
title: DeleteAllMapsTitle,
text: DeleteAllMapsPrompt,
onConfirm: () =>
{
foreach (var map in maps)
@@ -348,7 +395,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
after?.Invoke(Game.ModData.MapCache.ChooseInitialMap(null, Game.CosmeticRandom));
},
confirmText: "Delete",
confirmText: DeleteAllMapsAccept,
onCancel: () => { });
}
}

View File

@@ -25,6 +25,24 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
enum PlayingVideo { None, Info, Briefing, GameStart }
[TranslationReference]
static readonly string NoVideoTitle = "no-video-title";
[TranslationReference]
static readonly string NoVideoText = "no-video-text";
[TranslationReference]
static readonly string NoVideoCancel = "no-video-cancel";
[TranslationReference]
static readonly string CantPlayTitle = "cant-play-title";
[TranslationReference]
static readonly string CantPlayPrompt = "cant-play-prompt";
[TranslationReference]
static readonly string CantPlayCancel = "cant-play-cancel";
readonly ModData modData;
readonly Action onStart;
readonly ScrollPanelWidget descriptionPanel;
@@ -330,10 +348,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
if (!modData.DefaultFileSystem.Exists(video))
{
ConfirmationDialogs.ButtonPrompt(
title: "Video not installed",
text: "The game videos can be installed from the\n\"Manage Content\" menu in the mod chooser.",
cancelText: "Back",
ConfirmationDialogs.ButtonPrompt(modData,
title: NoVideoTitle,
text: NoVideoText,
cancelText: NoVideoCancel,
onCancel: () => { });
}
else
@@ -347,10 +365,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
StopVideo(player);
ConfirmationDialogs.ButtonPrompt(
title: "Unable to play video",
text: "Something went wrong during video playback.",
cancelText: "Back",
ConfirmationDialogs.ButtonPrompt(modData,
title: CantPlayTitle,
text: CantPlayPrompt,
cancelText: CantPlayCancel,
onCancel: () => { });
}
else

View File

@@ -18,6 +18,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
public class MusicPlayerLogic : ChromeLogic
{
[TranslationReference]
static readonly string SoundMuted = "sound-muted";
[TranslationReference]
static readonly string NoSongPlaying = "no-song-playing";
readonly ScrollPanelWidget musicList;
readonly ScrollItemWidget itemTemplate;
@@ -25,7 +31,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
MusicInfo currentSong = null;
[ObjectCreator.UseCtor]
public MusicPlayerLogic(Widget widget, World world, Action onExit)
public MusicPlayerLogic(Widget widget, World world, ModData modData, Action onExit)
{
var panel = widget;
@@ -43,7 +49,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
panel.Get<LabelWidget>("MUTE_LABEL").GetText = () =>
{
if (Game.Settings.Sound.Mute)
return "Audio has been muted in settings.";
return modData.Translation.GetString(SoundMuted);
return "";
};
@@ -95,9 +101,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
return $"{minutes:D2}:{seconds:D2} / {totalMinutes:D2}:{totalSeconds:D2}";
};
var noSongPlaying = modData.Translation.GetString(NoSongPlaying);
var musicTitle = panel.GetOrNull<LabelWidget>("TITLE_LABEL");
if (musicTitle != null)
musicTitle.GetText = () => currentSong != null ? currentSong.Title : "No song playing";
musicTitle.GetText = () => currentSong != null ? currentSong.Title : noSongPlaying;
var musicSlider = panel.Get<SliderWidget>("MUSIC_SLIDER");
musicSlider.OnChange += x => Game.Sound.MusicVolume = x;

View File

@@ -18,9 +18,20 @@ namespace OpenRA.Mods.Common.Widgets.Logic
[ChromeLogicArgsHotkeys("MuteAudioKey")]
public class MuteHotkeyLogic : SingleHotkeyBaseLogic
{
readonly ModData modData;
[TranslationReference]
static readonly string AudioMuted = "audio-muted";
[TranslationReference]
static readonly string AudioUnmuted = "audio-unmuted";
[ObjectCreator.UseCtor]
public MuteHotkeyLogic(Widget widget, ModData modData, Dictionary<string, MiniYaml> logicArgs)
: base(widget, modData, "MuteAudioKey", "GLOBAL_KEYHANDLER", logicArgs) { }
: base(widget, modData, "MuteAudioKey", "GLOBAL_KEYHANDLER", logicArgs)
{
this.modData = modData;
}
protected override bool OnHotkeyActivated(KeyInput e)
{
@@ -29,12 +40,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (Game.Settings.Sound.Mute)
{
Game.Sound.MuteAudio();
TextNotificationsManager.AddFeedbackLine("Audio muted.");
TextNotificationsManager.AddFeedbackLine(modData.Translation.GetString(AudioMuted));
}
else
{
Game.Sound.UnmuteAudio();
TextNotificationsManager.AddFeedbackLine("Audio unmuted.");
TextNotificationsManager.AddFeedbackLine(modData.Translation.GetString(AudioUnmuted));
}
return true;

View File

@@ -131,6 +131,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
public class RegisteredProfileTooltipLogic : ChromeLogic
{
[TranslationReference]
static readonly string LoadingPlayerProfile = "loading-player-profile";
[TranslationReference]
static readonly string LoadingPlayerProfileFailed = "loading-player-profile-failed";
readonly PlayerDatabase playerDatabase;
PlayerProfile profile;
bool profileLoaded;
@@ -154,7 +160,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var profileWidth = 0;
var maxProfileWidth = widget.Bounds.Width;
var messageText = "Loading player profile...";
var messageText = modData.Translation.GetString(LoadingPlayerProfile);
var messageWidth = messageFont.Measure(messageText).X + 2 * message.Bounds.Left;
Task.Run(async () =>
@@ -243,7 +249,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
if (profile == null)
{
messageText = "Failed to load player profile.";
messageText = modData.Translation.GetString(LoadingPlayerProfileFailed);
messageWidth = messageFont.Measure(messageText).X + 2 * message.Bounds.Left;
header.Bounds.Width = widget.Bounds.Width = messageWidth;
}

View File

@@ -25,6 +25,78 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
public class ReplayBrowserLogic : ChromeLogic
{
[TranslationReference("time")]
static readonly string Duration = "duration";
[TranslationReference]
static readonly string Singleplayer = "singleplayer";
[TranslationReference]
static readonly string Multiplayer = "multiplayer";
[TranslationReference]
static readonly string Today = "today";
[TranslationReference]
static readonly string LastWeek = "last-week";
[TranslationReference]
static readonly string LastFortnight = "last-fortnight";
[TranslationReference]
static readonly string LastMonth = "last-month";
[TranslationReference]
static readonly string ReplayDurationVeryShort = "replay-duration-very-short";
[TranslationReference]
static readonly string ReplayDurationShort = "replay-duration-short";
[TranslationReference]
static readonly string ReplayDurationMedium = "replay-duration-medium";
[TranslationReference]
static readonly string ReplayDurationLong = "replay-duration-long";
[TranslationReference]
static readonly string RenameReplayTitle = "rename-replay-title";
[TranslationReference]
static readonly string RenameReplayPrompt = "rename-replay-prompt";
[TranslationReference]
static readonly string RenameReplayAccept = "rename-replay-accept";
[TranslationReference]
static readonly string DeleteReplayTitle = "delete-replay-title";
[TranslationReference("replay")]
static readonly string DeleteReplayPrompt = "delete-replay-prompt";
[TranslationReference]
static readonly string DeleteReplayAccept = "delete-replay-accept";
[TranslationReference]
static readonly string DeleteAllReplaysTitle = "delete-all-replays-title";
[TranslationReference("count")]
static readonly string DeleteAllReplaysPrompt = "delete-all-replays-prompt";
[TranslationReference]
static readonly string DeleteAllReplaysAccept = "delete-all-replays-accept";
[TranslationReference("file")]
static readonly string ReplayDeletionFailed = "replay-deletion-failed";
[TranslationReference]
static readonly string Players = "players";
[TranslationReference("team")]
static readonly string TeamNumber = "team-number";
[TranslationReference]
static readonly string NoTeam = "no-team";
static Filter filter = new Filter();
readonly Widget panel;
@@ -101,7 +173,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
});
var replayDuration = new CachedTransform<ReplayMetadata, string>(r =>
$"Duration: {WidgetUtils.FormatTimeSeconds((int)selectedReplay.GameInfo.Duration.TotalSeconds)}");
modData.Translation.GetString(Duration, Translation.Arguments("time", WidgetUtils.FormatTimeSeconds((int)selectedReplay.GameInfo.Duration.TotalSeconds))));
panel.Get<LabelWidget>("DURATION").GetText = () => replayDuration.Update(selectedReplay);
SetupFilters();
@@ -153,8 +225,8 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var options = new List<(GameType GameType, string Text)>
{
(GameType.Any, ddb.GetText()),
(GameType.Singleplayer, "Singleplayer"),
(GameType.Multiplayer, "Multiplayer")
(GameType.Singleplayer, modData.Translation.GetString(Singleplayer)),
(GameType.Multiplayer, modData.Translation.GetString(Multiplayer))
};
var lookup = options.ToDictionary(kvp => kvp.GameType, kvp => kvp.Text);
@@ -186,10 +258,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var options = new List<(DateType DateType, string Text)>
{
(DateType.Any, ddb.GetText()),
(DateType.Today, "Today"),
(DateType.LastWeek, "Last 7 days"),
(DateType.LastFortnight, "Last 14 days"),
(DateType.LastMonth, "Last 30 days")
(DateType.Today, modData.Translation.GetString(Today)),
(DateType.LastWeek, modData.Translation.GetString(LastWeek)),
(DateType.LastFortnight, modData.Translation.GetString(LastFortnight)),
(DateType.LastMonth, modData.Translation.GetString(LastMonth))
};
var lookup = options.ToDictionary(kvp => kvp.DateType, kvp => kvp.Text);
@@ -222,10 +294,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var options = new List<(DurationType DurationType, string Text)>
{
(DurationType.Any, ddb.GetText()),
(DurationType.VeryShort, "Under 5 min"),
(DurationType.Short, "Short (10 min)"),
(DurationType.Medium, "Medium (30 min)"),
(DurationType.Long, "Long (60+ min)")
(DurationType.VeryShort, modData.Translation.GetString(ReplayDurationVeryShort)),
(DurationType.Short, modData.Translation.GetString(ReplayDurationShort)),
(DurationType.Medium, modData.Translation.GetString(ReplayDurationMedium)),
(DurationType.Long, modData.Translation.GetString(ReplayDurationLong))
};
var lookup = options.ToDictionary(kvp => kvp.DurationType, kvp => kvp.Text);
@@ -393,13 +465,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var directoryName = Path.GetDirectoryName(r.FilePath);
var invalidChars = Path.GetInvalidFileNameChars();
ConfirmationDialogs.TextInputPrompt(
"Rename Replay",
"Enter a new file name:",
ConfirmationDialogs.TextInputPrompt(modData,
RenameReplayTitle,
RenameReplayPrompt,
initialName,
onAccept: newName => RenameReplay(r, newName),
onCancel: null,
acceptText: "Rename",
acceptText: RenameReplayAccept,
cancelText: null,
inputValidator: newName =>
{
@@ -421,15 +493,16 @@ namespace OpenRA.Mods.Common.Widgets.Logic
Action<ReplayMetadata, Action> onDeleteReplay = (r, after) =>
{
ConfirmationDialogs.ButtonPrompt(
title: "Delete selected replay?",
text: $"Delete replay '{Path.GetFileNameWithoutExtension(r.FilePath)}'?",
ConfirmationDialogs.ButtonPrompt(modData,
title: DeleteReplayTitle,
text: DeleteReplayPrompt,
textArguments: Translation.Arguments("replay", Path.GetFileNameWithoutExtension(r.FilePath)),
onConfirm: () =>
{
DeleteReplay(r);
after?.Invoke();
},
confirmText: "Delete",
confirmText: DeleteReplayAccept,
onCancel: () => { });
};
@@ -458,9 +531,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
return;
}
ConfirmationDialogs.ButtonPrompt(
title: "Delete all selected replays?",
text: $"Delete {list.Count} replays?",
ConfirmationDialogs.ButtonPrompt(modData,
title: DeleteAllReplaysTitle,
text: DeleteAllReplaysPrompt,
textArguments: Translation.Arguments("count", list.Count),
onConfirm: () =>
{
foreach (var replayMetadata in list)
@@ -469,7 +543,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (selectedReplay == null)
SelectFirstVisibleReplay();
},
confirmText: "Delete All",
confirmText: DeleteAllReplaysAccept,
onCancel: () => { });
};
}
@@ -500,7 +574,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
}
catch (Exception ex)
{
TextNotificationsManager.Debug("Failed to delete replay file '{0}'. See the logs for details.", replay.FilePath);
TextNotificationsManager.Debug(modData.Translation.GetString(ReplayDeletionFailed, Translation.Arguments("file", replay.FilePath)));
Log.Write("debug", ex.ToString());
return;
}
@@ -636,7 +710,10 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var noTeams = players.Count() == 1;
foreach (var p in players)
{
var label = noTeams ? "Players" : p.Key == 0 ? "No Team" : $"Team {p.Key}";
var label = noTeams ? modData.Translation.GetString(Players) : p.Key > 0
? modData.Translation.GetString(TeamNumber, Translation.Arguments("team", p.Key))
: modData.Translation.GetString(NoTeam);
teams.Add(label, p);
}
@@ -685,7 +762,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
void WatchReplay()
{
if (selectedReplay != null && ReplayUtils.PromptConfirmReplayCompatibility(selectedReplay))
if (selectedReplay != null && ReplayUtils.PromptConfirmReplayCompatibility(selectedReplay, modData))
{
cancelLoadingReplays = true;

View File

@@ -10,52 +10,72 @@
#endregion
using System;
using System.Collections.Generic;
using OpenRA.FileFormats;
namespace OpenRA.Mods.Common.Widgets.Logic
{
public static class ReplayUtils
{
[TranslationReference]
static readonly string IncompatibleReplayTitle = "incompatible-replay-title";
[TranslationReference]
static readonly string IncompatibleReplayPrompt = "incompatible-replay-prompt";
[TranslationReference("version")]
static readonly string UnknownVersion = "incompatible-replay-unknown-version";
[TranslationReference("mod")]
static readonly string UnknownMod = "incompatible-replay-unknown-mod";
[TranslationReference("mod")]
static readonly string UnvailableMod = "incompatible-replay-unavailable-mod";
[TranslationReference("version")]
static readonly string IncompatibleVersion = "incompatible-replay-incompatible-version";
[TranslationReference("map")]
static readonly string UnvailableMap = "incompatible-replay-unavailable-map";
static readonly Action DoNothing = () => { };
public static bool PromptConfirmReplayCompatibility(ReplayMetadata replayMeta, Action onCancel = null)
public static bool PromptConfirmReplayCompatibility(ReplayMetadata replayMeta, ModData modData, Action onCancel = null)
{
if (onCancel == null)
onCancel = DoNothing;
if (replayMeta == null)
{
ConfirmationDialogs.ButtonPrompt("Incompatible Replay", "Replay metadata could not be read.", onCancel: onCancel);
ConfirmationDialogs.ButtonPrompt(modData, IncompatibleReplayTitle,
IncompatibleReplayPrompt, onCancel: onCancel);
return false;
}
var version = replayMeta.GameInfo.Version;
if (version == null)
return IncompatibleReplayDialog("unknown version", version, onCancel);
return IncompatibleReplayDialog(UnknownVersion, Translation.Arguments("version", version), modData, onCancel);
var mod = replayMeta.GameInfo.Mod;
if (mod == null)
return IncompatibleReplayDialog("unknown mod", mod, onCancel);
return IncompatibleReplayDialog(UnknownMod, Translation.Arguments("mod", mod), modData, onCancel);
if (!Game.Mods.ContainsKey(mod))
return IncompatibleReplayDialog("unavailable mod", mod, onCancel);
return IncompatibleReplayDialog(UnvailableMod, Translation.Arguments("mod", mod), modData, onCancel);
if (Game.Mods[mod].Metadata.Version != version)
return IncompatibleReplayDialog("incompatible version", version, onCancel);
return IncompatibleReplayDialog(IncompatibleVersion, Translation.Arguments("version", version), modData, onCancel);
if (replayMeta.GameInfo.MapPreview.Status != MapStatus.Available)
return IncompatibleReplayDialog("unavailable map", replayMeta.GameInfo.MapUid, onCancel);
return IncompatibleReplayDialog(UnvailableMap, Translation.Arguments("map", replayMeta.GameInfo.MapUid), modData, onCancel);
return true;
}
static bool IncompatibleReplayDialog(string type, string name, Action onCancel)
static bool IncompatibleReplayDialog(string text, Dictionary<string, object> textArguments, ModData modData, Action onCancel)
{
var error = "It was recorded with an " + type;
error += string.IsNullOrEmpty(name) ? "." : $":\n{name}";
ConfirmationDialogs.ButtonPrompt("Incompatible Replay", error, onCancel: onCancel);
ConfirmationDialogs.ButtonPrompt(modData, IncompatibleReplayTitle, text, textArguments: textArguments, onCancel: onCancel);
return false;
}
}

View File

@@ -19,7 +19,41 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
public class ServerCreationLogic : ChromeLogic
{
[TranslationReference]
static readonly string InternetServerNatA = "internet-server-nat-A";
[TranslationReference]
static readonly string InternetServerNatBenabled = "internet-server-nat-B-enabled";
[TranslationReference]
static readonly string InternetServerNatBnotSupported = "internet-server-nat-B-not-supported";
[TranslationReference]
static readonly string InternetServerNatBdisabled = "internet-server-nat-B-disabled";
[TranslationReference]
static readonly string InternetServerNatC = "internet-server-nat-C";
[TranslationReference]
static readonly string LocalServer = "local-server";
[TranslationReference("port")]
static readonly string ServerCreationFailedPrompt = "server-creation-failed-prompt";
[TranslationReference]
static readonly string ServerCreationFailedPortUsed = "server-creation-failed-port-used";
[TranslationReference("message", "code")]
static readonly string ServerCreationFailedError = "server-creation-failed-error";
[TranslationReference]
static readonly string ServerCreationFailedTitle = "server-creation-failed-title";
[TranslationReference]
static readonly string ServerCreationFailedCancel = "server-creation-failed-cancel";
readonly Widget panel;
readonly ModData modData;
readonly LabelWidget noticesLabelA, noticesLabelB, noticesLabelC;
readonly Action onCreate;
readonly Action onExit;
@@ -30,6 +64,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
public ServerCreationLogic(Widget widget, ModData modData, Action onExit, Action openLobby)
{
panel = widget;
this.modData = modData;
onCreate = openLobby;
this.onExit = onExit;
@@ -154,12 +189,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (advertiseOnline)
{
noticesLabelA.Text = "Internet Server (UPnP/NAT-PMP ";
noticesLabelA.Text = modData.Translation.GetString(InternetServerNatA) + " ";
var aWidth = Game.Renderer.Fonts[noticesLabelA.Font].Measure(noticesLabelA.Text).X;
noticesLabelA.Bounds.Width = aWidth;
noticesLabelB.Text = Nat.Status == NatStatus.Enabled ? "Enabled" :
Nat.Status == NatStatus.NotSupported ? "Not Supported" : "Disabled";
noticesLabelB.Text = Nat.Status == NatStatus.Enabled ? modData.Translation.GetString(InternetServerNatBenabled) :
Nat.Status == NatStatus.NotSupported ? modData.Translation.GetString(InternetServerNatBnotSupported)
: modData.Translation.GetString(InternetServerNatBdisabled);
noticesLabelB.TextColor = Nat.Status == NatStatus.Enabled ? ChromeMetrics.Get<Color>("NoticeSuccessColor") :
Nat.Status == NatStatus.NotSupported ? ChromeMetrics.Get<Color>("NoticeErrorColor") :
@@ -170,13 +206,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
noticesLabelB.Bounds.Width = bWidth;
noticesLabelB.Visible = true;
noticesLabelC.Text = "):";
noticesLabelC.Text = modData.Translation.GetString(InternetServerNatC);
noticesLabelC.Bounds.X = noticesLabelB.Bounds.Right;
noticesLabelC.Visible = true;
}
else
{
noticesLabelA.Text = "Local Server:";
noticesLabelA.Text = modData.Translation.GetString(LocalServer);
noticesLabelB.Visible = false;
noticesLabelC.Visible = false;
}
@@ -212,15 +248,17 @@ namespace OpenRA.Mods.Common.Widgets.Logic
}
catch (System.Net.Sockets.SocketException e)
{
var message = $"Could not listen on port {Game.Settings.Server.ListenPort}.";
var message = modData.Translation.GetString(ServerCreationFailedPrompt, Translation.Arguments("port", Game.Settings.Server.ListenPort));
// AddressAlreadyInUse (WSAEADDRINUSE)
if (e.ErrorCode == 10048)
message += "\nCheck if the port is already being used.";
message += "\n" + modData.Translation.GetString(ServerCreationFailedPortUsed);
else
message += $"\nError is: \"{e.Message}\" ({e.ErrorCode})";
message += $"\n" + modData.Translation.GetString(ServerCreationFailedError,
Translation.Arguments("message", e.Message, "code", e.ErrorCode));
ConfirmationDialogs.ButtonPrompt("Server Creation Failed", message, onCancel: () => { }, cancelText: "Back");
ConfirmationDialogs.ButtonPrompt(modData, ServerCreationFailedTitle, message,
onCancel: () => { }, cancelText: ServerCreationFailedCancel);
}
}
}

View File

@@ -25,6 +25,74 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
public class ServerListLogic : ChromeLogic
{
[TranslationReference]
static readonly string SearchStatusFailed = "search-status-failed";
[TranslationReference]
static readonly string SearchStatusNoGames = "search-status-no-games";
[TranslationReference("players")]
static readonly string PlayersOnline = "players-online";
[TranslationReference]
static readonly string NoServerSelected = "no-server-selected";
readonly string noServerSelected;
[TranslationReference]
static readonly string MapStatusSearching = "map-status-searching";
readonly string mapStatusSearching;
[TranslationReference]
static readonly string MapClassificationUnknown = "map-classification-unknown";
readonly string mapClassificationUnknown;
[TranslationReference("players")]
static readonly string PlayersLabel = "players-label";
[TranslationReference("bots")]
static readonly string BotsLabel = "bots-label";
[TranslationReference("spectators")]
static readonly string SpectatorsLabel = "spectators-label";
[TranslationReference]
static readonly string Players = "players";
[TranslationReference("team")]
static readonly string TeamNumber = "team-number";
[TranslationReference]
static readonly string NoTeam = "no-team";
[TranslationReference]
static readonly string Spectators = "spectators";
[TranslationReference("players")]
static readonly string OtherPlayers = "n-other-players";
[TranslationReference]
static readonly string Playing = "playing";
readonly string playing;
[TranslationReference]
static readonly string Waiting = "waiting";
readonly string waiting;
[TranslationReference("minutes")]
static readonly string InProgress = "in-progress-for";
[TranslationReference]
static readonly string PasswordProtected = "password-protected";
[TranslationReference]
static readonly string WaitingForPlayers = "waiting-for-players";
[TranslationReference]
static readonly string ServerShuttingDown = "server-shutting-down";
[TranslationReference]
static readonly string UnknownServerState = "unknown-server-state";
readonly Color incompatibleVersionColor;
readonly Color incompatibleProtectedGameColor;
readonly Color protectedGameColor;
@@ -62,12 +130,22 @@ namespace OpenRA.Mods.Common.Widgets.Logic
bool activeQuery;
IEnumerable<BeaconLocation> lanGameLocations;
readonly CachedTransform<int, string> players;
readonly CachedTransform<int, string> bots;
readonly CachedTransform<int, string> spectators;
readonly CachedTransform<double, string> minutes;
readonly string passwordProtected;
readonly string waitingForPlayers;
readonly string serverShuttingDown;
readonly string unknownServerState;
public string ProgressLabelText()
{
switch (searchStatus)
{
case SearchStatus.Failed: return "Failed to query server list.";
case SearchStatus.NoGames: return "No games found. Try changing filters.";
case SearchStatus.Failed: return modData.Translation.GetString(SearchStatusFailed);
case SearchStatus.NoGames: return modData.Translation.GetString(SearchStatusNoGames);
default: return "";
}
}
@@ -78,6 +156,23 @@ namespace OpenRA.Mods.Common.Widgets.Logic
this.modData = modData;
this.onJoin = onJoin;
playing = modData.Translation.GetString(Playing);
waiting = modData.Translation.GetString(Waiting);
noServerSelected = modData.Translation.GetString(NoServerSelected);
mapStatusSearching = modData.Translation.GetString(MapStatusSearching);
mapClassificationUnknown = modData.Translation.GetString(MapClassificationUnknown);
players = new CachedTransform<int, string>(i => modData.Translation.GetString(PlayersLabel, Translation.Arguments("players", i)));
bots = new CachedTransform<int, string>(i => modData.Translation.GetString(BotsLabel, Translation.Arguments("bots", i)));
spectators = new CachedTransform<int, string>(i => modData.Translation.GetString(SpectatorsLabel, Translation.Arguments("spectators", i)));
minutes = new CachedTransform<double, string>(i => modData.Translation.GetString(InProgress, Translation.Arguments("minutes", i)));
passwordProtected = modData.Translation.GetString(PasswordProtected);
waitingForPlayers = modData.Translation.GetString(WaitingForPlayers);
serverShuttingDown = modData.Translation.GetString(ServerShuttingDown);
unknownServerState = modData.Translation.GetString(UnknownServerState);
services = modData.Manifest.Get<WebServices>();
incompatibleVersionColor = ChromeMetrics.Get<Color>("IncompatibleVersionColor");
@@ -222,7 +317,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var playersLabel = widget.GetOrNull<LabelWidget>("PLAYER_COUNT");
if (playersLabel != null)
{
var playersText = new CachedTransform<int, string>(c => c == 1 ? "1 Player Online" : c.ToString() + " Players Online");
var playersText = new CachedTransform<int, string>(p => modData.Translation.GetString(PlayersOnline, Translation.Arguments("players", p)));
playersLabel.IsVisible = () => playerCount != 0;
playersLabel.GetText = () => playersText.Update(playerCount);
}
@@ -250,13 +345,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
mapTitle.GetText = () =>
{
if (currentMap == null)
return "No Server Selected";
return noServerSelected;
if (currentMap.Status == MapStatus.Searching)
return "Searching...";
return mapStatusSearching;
if (currentMap.Class == MapClassification.Unknown)
return "Unknown Map";
return mapClassificationUnknown;
return title.Update(currentMap);
};
@@ -288,11 +383,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
modVersion.GetText = () => version.Update(currentServer);
}
var players = widget.GetOrNull<LabelWidget>("SELECTED_PLAYERS");
if (players != null)
var selectedPlayers = widget.GetOrNull<LabelWidget>("SELECTED_PLAYERS");
if (selectedPlayers != null)
{
players.IsVisible = () => currentServer != null && (clientContainer == null || currentServer.Clients.Length == 0);
players.GetText = () => PlayersLabel(currentServer);
selectedPlayers.IsVisible = () => currentServer != null && (clientContainer == null || currentServer.Clients.Length == 0);
selectedPlayers.GetText = () => PlayerLabel(currentServer);
}
clientContainer = widget.GetOrNull("CLIENT_LIST_CONTAINER");
@@ -320,9 +415,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
RefreshServerList();
}
static string PlayersLabel(GameServer game)
string PlayerLabel(GameServer game)
{
return $"{(game.Players > 0 ? game.Players.ToString() : "No")} Player{(game.Players != 1 ? "s" : "")}{(game.Bots > 0 ? $", {game.Bots} Bot{(game.Bots != 1 ? "s" : "")}" : "")}{(game.Spectators > 0 ? $", {game.Spectators} Spectator{(game.Spectators != 1 ? "s" : "")}" : "")}";
return players.Update(game.Players)
+ bots.Update(game.Bots)
+ spectators.Update(game.Spectators);
}
public void RefreshServerList()
@@ -474,12 +571,14 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var noTeams = players.Count() == 1;
foreach (var p in players)
{
var label = noTeams ? "Players" : p.Key == 0 ? "No Team" : $"Team {p.Key}";
var label = noTeams ? modData.Translation.GetString(Players) : p.Key > 0
? modData.Translation.GetString(TeamNumber, Translation.Arguments("team", p.Key))
: modData.Translation.GetString(NoTeam);
teams.Add(label, p);
}
if (server.Clients.Any(c => c.IsSpectator))
teams.Add("Spectators", server.Clients.Where(c => c.IsSpectator));
teams.Add(modData.Translation.GetString(Spectators), server.Clients.Where(c => c.IsSpectator));
var factionInfo = modData.DefaultRules.Actors[SystemActors.World].TraitInfos<FactionInfo>();
foreach (var kv in teams)
@@ -655,7 +754,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (game.Clients.Length > 10)
displayClients = displayClients
.Take(9)
.Append($"+ {game.Clients.Length - 9} other players");
.Append(modData.Translation.GetString(OtherPlayers, Translation.Arguments("players", game.Clients.Length - 9)));
var tooltip = displayClients.JoinWith("\n");
players.GetTooltipText = () => tooltip;
@@ -667,8 +766,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var state = item.GetOrNull<LabelWidget>("STATUS");
if (state != null)
{
var label = game.State >= (int)ServerState.GameStarted ?
"Playing" : "Waiting";
var label = game.State >= (int)ServerState.GameStarted ? playing : waiting;
state.GetText = () => label;
var color = GetStateColor(game, state, !canJoin);
@@ -695,31 +793,24 @@ namespace OpenRA.Mods.Common.Widgets.Logic
return rows;
}
static string GetStateLabel(GameServer game)
string GetStateLabel(GameServer game)
{
if (game == null)
return "";
return string.Empty;
if (game.State == (int)ServerState.GameStarted)
{
var label = "In progress";
if (game.PlayTime > 0)
{
var totalMinutes = Math.Ceiling(game.PlayTime / 60.0);
label += $" for {totalMinutes} minute{(totalMinutes > 1 ? "s" : "")}";
}
return label;
var totalMinutes = Math.Ceiling(game.PlayTime / 60.0);
return minutes.Update(totalMinutes);
}
if (game.State == (int)ServerState.WaitingPlayers)
return game.Protected ? "Password protected" : "Waiting for players";
return game.Protected ? passwordProtected : waitingForPlayers;
if (game.State == (int)ServerState.ShuttingDown)
return "Server shutting down";
return serverShuttingDown;
return "Unknown server state";
return unknownServerState;
}
Color GetStateColor(GameServer game, LabelWidget label, bool darkened = false)

View File

@@ -22,6 +22,50 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
public class DisplaySettingsLogic : ChromeLogic
{
[TranslationReference]
static readonly string Close = "close";
[TranslationReference]
static readonly string Medium = "medium";
[TranslationReference]
static readonly string Far = "far";
[TranslationReference]
static readonly string Furthest = "furthest";
[TranslationReference]
static readonly string Windowed = "windowed";
[TranslationReference]
static readonly string LegacyFullscreen = "legacy-fullscreen";
readonly string legacyFullscreen;
[TranslationReference]
static readonly string Fullscreen = "fullscreen";
readonly string fullscreen;
[TranslationReference("number")]
static readonly string Display = "display";
[TranslationReference]
static readonly string Standard = "standard";
[TranslationReference]
static readonly string ShowOnDamage = "show-on-damage";
[TranslationReference]
static readonly string AlwaysShow = "always-show";
[TranslationReference]
static readonly string Automatic = "automatic";
[TranslationReference]
static readonly string Manual = "manual";
[TranslationReference]
static readonly string Disabled = "disabled";
static readonly int OriginalVideoDisplay;
static readonly WindowMode OriginalGraphicsMode;
static readonly int2 OriginalGraphicsWindowedSize;
@@ -32,6 +76,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
readonly WorldRenderer worldRenderer;
readonly WorldViewportSizes viewportSizes;
readonly string showOnDamage;
readonly string alwaysShow;
readonly string automatic;
readonly string manual;
readonly string disabled;
static DisplaySettingsLogic()
{
var original = Game.Settings;
@@ -49,16 +100,35 @@ namespace OpenRA.Mods.Common.Widgets.Logic
this.modData = modData;
viewportSizes = modData.Manifest.Get<WorldViewportSizes>();
legacyFullscreen = modData.Translation.GetString(LegacyFullscreen);
fullscreen = modData.Translation.GetString(Fullscreen);
registerPanel(panelID, label, InitPanel, ResetPanel);
showOnDamage = modData.Translation.GetString(ShowOnDamage);
alwaysShow = modData.Translation.GetString(AlwaysShow);
automatic = modData.Translation.GetString(Automatic);
manual = modData.Translation.GetString(Manual);
disabled = modData.Translation.GetString(Disabled);
}
public static readonly Dictionary<WorldViewport, string> ViewportSizeNames = new Dictionary<WorldViewport, string>()
public static string GetViewportSizeName(ModData modData, WorldViewport worldViewport)
{
{ WorldViewport.Close, "Close" },
{ WorldViewport.Medium, "Medium" },
{ WorldViewport.Far, "Far" },
{ WorldViewport.Native, "Furthest" }
};
switch (worldViewport)
{
case WorldViewport.Close:
return modData.Translation.GetString(Close);
case WorldViewport.Medium:
return modData.Translation.GetString(Medium);
case WorldViewport.Far:
return modData.Translation.GetString(Far);
case WorldViewport.Native:
return modData.Translation.GetString(Furthest);
default:
return "";
}
}
Func<bool> InitPanel(Widget panel)
{
@@ -77,13 +147,14 @@ namespace OpenRA.Mods.Common.Widgets.Logic
SettingsUtils.BindCheckboxPref(panel, "HIDE_REPLAY_CHAT_CHECKBOX", gs, "HideReplayChat");
var windowModeDropdown = panel.Get<DropDownButtonWidget>("MODE_DROPDOWN");
windowModeDropdown.OnMouseDown = _ => ShowWindowModeDropdown(windowModeDropdown, ds, scrollPanel);
windowModeDropdown.GetText = () => ds.Mode == WindowMode.Windowed ?
"Windowed" : ds.Mode == WindowMode.Fullscreen ? "Fullscreen (Legacy)" : "Fullscreen";
windowModeDropdown.OnMouseDown = _ => ShowWindowModeDropdown(modData, windowModeDropdown, ds, scrollPanel);
windowModeDropdown.GetText = () => ds.Mode == WindowMode.Windowed
? modData.Translation.GetString(Windowed)
: ds.Mode == WindowMode.Fullscreen ? legacyFullscreen : fullscreen;
var displaySelectionDropDown = panel.Get<DropDownButtonWidget>("DISPLAY_SELECTION_DROPDOWN");
displaySelectionDropDown.OnMouseDown = _ => ShowDisplaySelectionDropdown(displaySelectionDropDown, ds);
var displaySelectionLabel = new CachedTransform<int, string>(i => $"Display {i + 1}");
var displaySelectionLabel = new CachedTransform<int, string>(i => modData.Translation.GetString(Display, Translation.Arguments("number", i + 1)));
displaySelectionDropDown.GetText = () => displaySelectionLabel.Update(ds.VideoDisplay);
displaySelectionDropDown.IsDisabled = () => Game.Renderer.DisplayCount < 2;
@@ -95,18 +166,24 @@ namespace OpenRA.Mods.Common.Widgets.Logic
glProfileDropdown.IsDisabled = () => disableProfile;
var statusBarsDropDown = panel.Get<DropDownButtonWidget>("STATUS_BAR_DROPDOWN");
statusBarsDropDown.OnMouseDown = _ => ShowStatusBarsDropdown(statusBarsDropDown, gs);
statusBarsDropDown.GetText = () => gs.StatusBars == StatusBarsType.Standard ?
"Standard" : gs.StatusBars == StatusBarsType.DamageShow ? "Show On Damage" : "Always Show";
statusBarsDropDown.OnMouseDown = _ => ShowStatusBarsDropdown(modData, statusBarsDropDown, gs);
statusBarsDropDown.GetText = () => gs.StatusBars == StatusBarsType.Standard
? modData.Translation.GetString(Standard)
: gs.StatusBars == StatusBarsType.DamageShow
? showOnDamage
: alwaysShow;
var targetLinesDropDown = panel.Get<DropDownButtonWidget>("TARGET_LINES_DROPDOWN");
targetLinesDropDown.OnMouseDown = _ => ShowTargetLinesDropdown(targetLinesDropDown, gs);
targetLinesDropDown.GetText = () => gs.TargetLines == TargetLinesType.Automatic ?
"Automatic" : gs.TargetLines == TargetLinesType.Manual ? "Manual" : "Disabled";
targetLinesDropDown.OnMouseDown = _ => ShowTargetLinesDropdown(modData, targetLinesDropDown, gs);
targetLinesDropDown.GetText = () => gs.TargetLines == TargetLinesType.Automatic
? automatic
: gs.TargetLines == TargetLinesType.Manual
? manual
: disabled;
var battlefieldCameraDropDown = panel.Get<DropDownButtonWidget>("BATTLEFIELD_CAMERA_DROPDOWN");
var battlefieldCameraLabel = new CachedTransform<WorldViewport, string>(vs => ViewportSizeNames[vs]);
battlefieldCameraDropDown.OnMouseDown = _ => ShowBattlefieldCameraDropdown(battlefieldCameraDropDown, viewportSizes, ds);
var battlefieldCameraLabel = new CachedTransform<WorldViewport, string>(vs => GetViewportSizeName(modData, vs));
battlefieldCameraDropDown.OnMouseDown = _ => ShowBattlefieldCameraDropdown(modData, battlefieldCameraDropDown, viewportSizes, ds);
battlefieldCameraDropDown.GetText = () => battlefieldCameraLabel.Update(ds.ViewportDistance);
BindTextNotificationPoolFilterSettings(panel, gs);
@@ -251,13 +328,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
};
}
static void ShowWindowModeDropdown(DropDownButtonWidget dropdown, GraphicSettings s, ScrollPanelWidget scrollPanel)
static void ShowWindowModeDropdown(ModData modData, DropDownButtonWidget dropdown, GraphicSettings s, ScrollPanelWidget scrollPanel)
{
var options = new Dictionary<string, WindowMode>()
{
{ "Fullscreen", WindowMode.PseudoFullscreen },
{ "Fullscreen (Legacy)", WindowMode.Fullscreen },
{ "Windowed", WindowMode.Windowed },
{ modData.Translation.GetString(Fullscreen), WindowMode.PseudoFullscreen },
{ modData.Translation.GetString(LegacyFullscreen), WindowMode.Fullscreen },
{ modData.Translation.GetString(Windowed), WindowMode.Windowed },
};
Func<string, ScrollItemWidget, ScrollItemWidget> setupItem = (o, itemTemplate) =>
@@ -300,13 +377,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
}
}
static void ShowStatusBarsDropdown(DropDownButtonWidget dropdown, GameSettings s)
static void ShowStatusBarsDropdown(ModData modData, DropDownButtonWidget dropdown, GameSettings s)
{
var options = new Dictionary<string, StatusBarsType>()
{
{ "Standard", StatusBarsType.Standard },
{ "Show On Damage", StatusBarsType.DamageShow },
{ "Always Show", StatusBarsType.AlwaysShow },
{ modData.Translation.GetString(Standard), StatusBarsType.Standard },
{ modData.Translation.GetString(ShowOnDamage), StatusBarsType.DamageShow },
{ modData.Translation.GetString(AlwaysShow), StatusBarsType.AlwaysShow },
};
Func<string, ScrollItemWidget, ScrollItemWidget> setupItem = (o, itemTemplate) =>
@@ -355,13 +432,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 500, profiles, setupItem);
}
static void ShowTargetLinesDropdown(DropDownButtonWidget dropdown, GameSettings s)
static void ShowTargetLinesDropdown(ModData modData, DropDownButtonWidget dropdown, GameSettings s)
{
var options = new Dictionary<string, TargetLinesType>()
{
{ "Automatic", TargetLinesType.Automatic },
{ "Manual", TargetLinesType.Manual },
{ "Disabled", TargetLinesType.Disabled },
{ modData.Translation.GetString(Automatic), TargetLinesType.Automatic },
{ modData.Translation.GetString(Manual), TargetLinesType.Manual },
{ modData.Translation.GetString(Disabled), TargetLinesType.Disabled },
};
Func<string, ScrollItemWidget, ScrollItemWidget> setupItem = (o, itemTemplate) =>
@@ -377,7 +454,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 500, options.Keys, setupItem);
}
public static void ShowBattlefieldCameraDropdown(DropDownButtonWidget dropdown, WorldViewportSizes viewportSizes, GraphicSettings gs)
public static void ShowBattlefieldCameraDropdown(ModData modData, DropDownButtonWidget dropdown, WorldViewportSizes viewportSizes, GraphicSettings gs)
{
Func<WorldViewport, ScrollItemWidget, ScrollItemWidget> setupItem = (o, itemTemplate) =>
{
@@ -385,7 +462,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
() => gs.ViewportDistance == o,
() => gs.ViewportDistance = o);
var label = ViewportSizeNames[o];
var label = GetViewportSizeName(modData, o);
item.Get<LabelWidget>("LABEL").GetText = () => label;
return item;
};

View File

@@ -17,11 +17,53 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
public class InputSettingsLogic : ChromeLogic
{
[TranslationReference]
static readonly string Classic = "classic";
readonly string classic;
[TranslationReference]
static readonly string Modern = "modern";
readonly string modern;
[TranslationReference]
static readonly string Disabled = "disabled";
[TranslationReference]
static readonly string Standard = "standard";
[TranslationReference]
static readonly string Inverted = "inverted";
[TranslationReference]
static readonly string Joystick = "joystick";
[TranslationReference]
static readonly string Alt = "alt";
[TranslationReference]
static readonly string Ctrl = "ctrl";
[TranslationReference]
static readonly string Meta = "meta";
[TranslationReference]
static readonly string Shift = "shift";
[TranslationReference]
static readonly string None = "none";
static InputSettingsLogic() { }
readonly ModData modData;
[ObjectCreator.UseCtor]
public InputSettingsLogic(Action<string, string, Func<Widget, Func<bool>>, Func<Widget, Action>> registerPanel, string panelID, string label)
public InputSettingsLogic(Action<string, string, Func<Widget, Func<bool>>, Func<Widget, Action>> registerPanel, string panelID, string label, ModData modData)
{
this.modData = modData;
classic = modData.Translation.GetString(Classic);
modern = modData.Translation.GetString(Modern);
registerPanel(panelID, label, InitPanel, ResetPanel);
}
@@ -38,11 +80,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
SettingsUtils.BindSliderPref(panel, "UI_SCROLLSPEED_SLIDER", gs, "UIScrollSpeed");
var mouseControlDropdown = panel.Get<DropDownButtonWidget>("MOUSE_CONTROL_DROPDOWN");
mouseControlDropdown.OnMouseDown = _ => ShowMouseControlDropdown(mouseControlDropdown, gs);
mouseControlDropdown.GetText = () => gs.UseClassicMouseStyle ? "Classic" : "Modern";
mouseControlDropdown.OnMouseDown = _ => ShowMouseControlDropdown(modData, mouseControlDropdown, gs);
mouseControlDropdown.GetText = () => gs.UseClassicMouseStyle ? classic : modern;
var mouseScrollDropdown = panel.Get<DropDownButtonWidget>("MOUSE_SCROLL_TYPE_DROPDOWN");
mouseScrollDropdown.OnMouseDown = _ => ShowMouseScrollDropdown(mouseScrollDropdown, gs);
mouseScrollDropdown.OnMouseDown = _ => ShowMouseScrollDropdown(modData, mouseScrollDropdown, gs);
mouseScrollDropdown.GetText = () => gs.MouseScroll.ToString();
var mouseControlDescClassic = panel.Get("MOUSE_CONTROL_DESC_CLASSIC");
@@ -87,7 +129,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
};
var zoomModifierDropdown = panel.Get<DropDownButtonWidget>("ZOOM_MODIFIER");
zoomModifierDropdown.OnMouseDown = _ => ShowZoomModifierDropdown(zoomModifierDropdown, gs);
zoomModifierDropdown.OnMouseDown = _ => ShowZoomModifierDropdown(modData, zoomModifierDropdown, gs);
zoomModifierDropdown.GetText = () => gs.ZoomModifier.ToString();
SettingsUtils.AdjustSettingsScrollPanelLayout(scrollPanel);
@@ -119,12 +161,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
};
}
public static void ShowMouseControlDropdown(DropDownButtonWidget dropdown, GameSettings s)
public static void ShowMouseControlDropdown(ModData modData, DropDownButtonWidget dropdown, GameSettings s)
{
var options = new Dictionary<string, bool>()
{
{ "Classic", true },
{ "Modern", false },
{ modData.Translation.GetString(Classic), true },
{ modData.Translation.GetString(Modern), false },
};
Func<string, ScrollItemWidget, ScrollItemWidget> setupItem = (o, itemTemplate) =>
@@ -139,14 +181,14 @@ namespace OpenRA.Mods.Common.Widgets.Logic
dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 500, options.Keys, setupItem);
}
static void ShowMouseScrollDropdown(DropDownButtonWidget dropdown, GameSettings s)
static void ShowMouseScrollDropdown(ModData modData, DropDownButtonWidget dropdown, GameSettings s)
{
var options = new Dictionary<string, MouseScrollType>()
{
{ "Disabled", MouseScrollType.Disabled },
{ "Standard", MouseScrollType.Standard },
{ "Inverted", MouseScrollType.Inverted },
{ "Joystick", MouseScrollType.Joystick },
{ modData.Translation.GetString(Disabled), MouseScrollType.Disabled },
{ modData.Translation.GetString(Standard), MouseScrollType.Standard },
{ modData.Translation.GetString(Inverted), MouseScrollType.Inverted },
{ modData.Translation.GetString(Joystick), MouseScrollType.Joystick },
};
Func<string, ScrollItemWidget, ScrollItemWidget> setupItem = (o, itemTemplate) =>
@@ -161,15 +203,15 @@ namespace OpenRA.Mods.Common.Widgets.Logic
dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 500, options.Keys, setupItem);
}
static void ShowZoomModifierDropdown(DropDownButtonWidget dropdown, GameSettings s)
static void ShowZoomModifierDropdown(ModData modData, DropDownButtonWidget dropdown, GameSettings s)
{
var options = new Dictionary<string, Modifiers>()
{
{ "Alt", Modifiers.Alt },
{ "Ctrl", Modifiers.Ctrl },
{ "Meta", Modifiers.Meta },
{ "Shift", Modifiers.Shift },
{ "None", Modifiers.None }
{ modData.Translation.GetString(Alt), Modifiers.Alt },
{ modData.Translation.GetString(Ctrl), Modifiers.Ctrl },
{ modData.Translation.GetString(Meta), Modifiers.Meta },
{ modData.Translation.GetString(Shift), Modifiers.Shift },
{ modData.Translation.GetString(None), Modifiers.None }
};
Func<string, ScrollItemWidget, ScrollItemWidget> setupItem = (o, itemTemplate) =>

View File

@@ -19,6 +19,39 @@ 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<string, Func<bool>> leavePanelActions = new Dictionary<string, Func<bool>>();
readonly Dictionary<string, Action> resetPanelActions = new Dictionary<string, Action>();
@@ -34,7 +67,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
static SettingsLogic() { }
[ObjectCreator.UseCtor]
public SettingsLogic(Widget widget, Action onExit, WorldRenderer worldRenderer, Dictionary<string, MiniYaml> logicArgs)
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");
@@ -75,11 +108,11 @@ namespace OpenRA.Mods.Common.Widgets.Logic
Action closeAndExit = () => { Ui.CloseWindow(); onExit(); };
if (needsRestart)
{
Action noRestart = () => ConfirmationDialogs.ButtonPrompt(
title: "Restart Required",
text: "Some changes will not be applied until\nthe game is restarted.",
Action noRestart = () => ConfirmationDialogs.ButtonPrompt(modData,
title: SettingsSaveTitle,
text: SettingsSavePrompt,
onCancel: closeAndExit,
cancelText: "Continue");
cancelText: SettingsSaveCancel);
if (!Game.ExternalMods.TryGetValue(ExternalMod.MakeKey(Game.ModData.Manifest), out var external))
{
@@ -87,13 +120,13 @@ namespace OpenRA.Mods.Common.Widgets.Logic
return;
}
ConfirmationDialogs.ButtonPrompt(
title: "Restart Now?",
text: "Some changes will not be applied until\nthe game is restarted. Restart now?",
ConfirmationDialogs.ButtonPrompt(modData,
title: RestartTitle,
text: RestartPrompt,
onConfirm: () => Game.SwitchToExternalMod(external, null, noRestart),
onCancel: closeAndExit,
confirmText: "Restart Now",
cancelText: "Restart Later");
confirmText: RestartAccept,
cancelText: RestartCancel);
}
else
closeAndExit();
@@ -107,13 +140,14 @@ namespace OpenRA.Mods.Common.Widgets.Logic
Game.Settings.Save();
};
ConfirmationDialogs.ButtonPrompt(
title: $"Reset \"{panels[activePanel]}\"",
text: "Are you sure you want to reset\nall settings in this panel?",
ConfirmationDialogs.ButtonPrompt(modData,
title: ResetTitle,
titleArguments: Translation.Arguments("panel", panels[activePanel]),
text: ResetPrompt,
onConfirm: reset,
onCancel: () => { },
confirmText: "Reset",
cancelText: "Cancel");
confirmText: ResetAccept,
cancelText: ResetCancel);
};
}