Skip to content

Commit

Permalink
Added en localization support.
Browse files Browse the repository at this point in the history
  • Loading branch information
ST-Apps committed Jul 7, 2018
1 parent 312f2ba commit 0a104e3
Show file tree
Hide file tree
Showing 12 changed files with 387 additions and 21 deletions.
101 changes: 101 additions & 0 deletions ParallelRoadTool/Extensions/LocaleManagerExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
using ColossalFramework.Globalization;
using ParallelRoadTool;
using ParallelRoadTool.Extensions.LocaleModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;

namespace ParallelRoadTool.Extensions
{
/// <summary>
/// <see cref="https://github.com/markusmitbrille/cities-skylines-custom-namelists/blob/master/CSLCNL/CSLCNL/LocaleManagerExtensions.cs"/>
/// </summary>
static class LocaleManagerExtensions
{
const string localeFieldName = "m_Locale";
const string localizedStringsFieldName = "m_LocalizedStrings";
const string localizedStringsCountFieldName = "m_LocalizedStringsCount";

static FieldInfo localeField = typeof(LocaleManager).GetField(localeFieldName, BindingFlags.Instance | BindingFlags.NonPublic);
static FieldInfo localizedStringsField = typeof(Locale).GetField(localizedStringsFieldName, BindingFlags.Instance | BindingFlags.NonPublic);
static FieldInfo localizedStringsCountField = typeof(Locale).GetField(localizedStringsCountFieldName, BindingFlags.Instance | BindingFlags.NonPublic);

public static Locale GetLocale(this LocaleManager localeManager)
{
return (Locale)localeField.GetValue(localeManager);
}

public static Dictionary<Locale.Key, string> GetLocalizedStrings(this Locale locale)
{
return (Dictionary<Locale.Key, string>)localizedStringsField.GetValue(locale);
}

public static Dictionary<Locale.Key, int> GetLocalizedStringsCount(this Locale locale)
{
return (Dictionary<Locale.Key, int>)localizedStringsCountField.GetValue(locale);
}

public static void RemoveRange(this LocaleManager localeManager, Locale.Key id)
{
Locale locale = localeManager.GetLocale();

// Set index to 0 so we can check for the string count
id.m_Index = 0;

if (!locale.Exists(id))
{
DebugUtils.Log($"Could not remove locale range {id}; localized string {id} does not exist!");
return;
}

Dictionary<Locale.Key, string> localizedStrings = locale.GetLocalizedStrings();
Dictionary<Locale.Key, int> localizedStringsCount = locale.GetLocalizedStringsCount();

for (int index = 0, lastIndex = locale.CountUnchecked(id); index <= lastIndex; index++, id.m_Index = index)
{
localizedStrings.Remove(id);
localizedStringsCount.Remove(id);
}

DebugUtils.Log($"Removed locale range {id.m_Identifier}[{id.m_Key}].");
}

public static void AddString(this LocaleManager localeManager, LocalizedString localizedString)
{
Locale locale = localeManager.GetLocale();

// Construct 0-index id for the localized string from argument
Locale.Key id;
id.m_Identifier = localizedString.Identifier;
id.m_Key = localizedString.Key;
id.m_Index = 0;

// Check if the id already exists; if so find next index
if (locale.Exists(id))
{
// Log message lags game on large namelists
// Log($"Localized string {localizedString.Identifier}[{localizedString.Key}] already exists, adding it with next available index.");
id.m_Index = locale.CountUnchecked(id);
}

// Add the localized string
locale.AddLocalizedString(id, localizedString.Value);

// Set the string counts accordingly
Dictionary<Locale.Key, int> localizedStringCounts = locale.GetLocalizedStringsCount();

// The count at the exact index appears to always be 0
localizedStringCounts[id] = 0;

// index = 0 appears to be a special case and indicates the count of localized strings with the same identifier and key
Locale.Key zeroIndexID = id;
zeroIndexID.m_Index = 0;
localizedStringCounts[zeroIndexID] = id.m_Index + 1;

// Log message lags game on large namelists
// Log($"Added localized string {id} = '{localizedString.Value}', count = {localizedStringCounts[zeroIndexID]}.");
}
}
}
21 changes: 21 additions & 0 deletions ParallelRoadTool/Extensions/LocaleModels/LocalizedString.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;

namespace ParallelRoadTool.Extensions.LocaleModels
{
/// <summary>
/// <see cref="https://github.com/markusmitbrille/cities-skylines-custom-namelists/blob/master/CSLCNL/CSLCNL/LocalizedString.cs"/>
/// </summary>
public struct LocalizedString
{
[XmlAttribute(AttributeName = "identifier")]
public string Identifier;
[XmlAttribute(AttributeName = "key")]
public string Key;
[XmlText]
public string Value;
}
}
19 changes: 19 additions & 0 deletions ParallelRoadTool/Extensions/LocaleModels/LocalizedStringKey.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;

namespace ParallelRoadTool.Extensions.LocaleModels
{
/// <summary>
/// <see cref="https://github.com/markusmitbrille/cities-skylines-custom-namelists/blob/master/CSLCNL/CSLCNL/LocalizedStringKey.cs"/>
/// </summary>
public struct LocalizedStringKey
{
[XmlAttribute(AttributeName = "identifier")]
public string Identifier;
[XmlAttribute(AttributeName = "key")]
public string Key;
}
}
32 changes: 32 additions & 0 deletions ParallelRoadTool/Extensions/LocaleModels/NameList.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using ColossalFramework;
using ColossalFramework.Globalization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;

namespace ParallelRoadTool.Extensions.LocaleModels
{
/// <summary>
/// <see cref="https://github.com/markusmitbrille/cities-skylines-custom-namelists/blob/master/CSLCNL/CSLCNL/NameList.cs"/>
/// </summary>
public class NameList
{
[XmlAttribute(AttributeName = "name")]
public string Name;
[XmlArray(ElementName = "strings")]
public LocalizedString[] LocalizedStrings;

public void Apply()
{
LocaleManager localeManager = SingletonLite<LocaleManager>.instance;
foreach (LocalizedString localizedString in LocalizedStrings)
{
localeManager.AddString(localizedString);
}

DebugUtils.Log($"Namelist {Name} applied.");
}
}
}
19 changes: 19 additions & 0 deletions ParallelRoadTool/Localization/en.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<NameList
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
name="PRT_en">
<strings>
<LocalizedString identifier="PRT_TOOLTIPS" key="SnappingToggleButton">Toggle snapping for existing nodes</LocalizedString>
<LocalizedString identifier="PRT_TOOLTIPS" key="ToolToggleButton">Toggle Parallel Road Tool</LocalizedString>
<LocalizedString identifier="PRT_TOOLTIPS" key="ReverseToggleButton">Toggle reverse direction for this road</LocalizedString>
<LocalizedString identifier="PRT_TOOLTIPS" key="RemoveNetworkButton">Remove network</LocalizedString>
<LocalizedString identifier="PRT_TOOLTIPS" key="AddNetworkButton">Add network</LocalizedString>

<LocalizedString identifier="PRT_TEXTS" key="SameAsSelectedLabel">Same as selected</LocalizedString>
<LocalizedString identifier="PRT_TEXTS" key="DecreaseHorizontalOffsetOption">Decrease horizontal offset of parallel networks</LocalizedString>
<LocalizedString identifier="PRT_TEXTS" key="IncreaseHorizontalOffsetOption">Increase horizontal offset of parallel networks</LocalizedString>
<LocalizedString identifier="PRT_TEXTS" key="DecreaseVerticalOffsetOption">Decrease vertical offset of parallel networks</LocalizedString>
<LocalizedString identifier="PRT_TEXTS" key="IncreaseVerticalOffsetOption">Increase vertical offset of parallel networks</LocalizedString>
</strings>
</NameList>
6 changes: 3 additions & 3 deletions ParallelRoadTool/OptionsKeymapping.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ public class OptionsKeymapping : UICustomControl

private void Awake()
{
AddKeymapping("Toggle Parallel Roads", toggleParallelRoads);
AddKeymapping("Decrease HorizontalOffset of Parallel Roads", decreaseOffset);
AddKeymapping("Increase HorizontalOffset of Parallel Roads", increaseOffset);
AddKeymapping(Locale.Get("PRT_TOOLTIPS", "ToolToggleButton"), toggleParallelRoads);
AddKeymapping(Locale.Get("PRT_TEXTS", "DecreaseHorizontalOffsetOption"), decreaseOffset);
AddKeymapping(Locale.Get("PRT_TEXTS", "IncreaseHorizontalOffsetOption"), increaseOffset);
}

private void AddKeymapping(string label, SavedInputKey savedInputKey)
Expand Down
56 changes: 56 additions & 0 deletions ParallelRoadTool/ParallelRoadTool.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Xml;
using System.Xml.Serialization;
using ColossalFramework;
using ColossalFramework.Globalization;
using ColossalFramework.Plugins;
using ColossalFramework.UI;
using ICities;
using ParallelRoadTool.Detours;
using ParallelRoadTool.Extensions.LocaleModels;
using ParallelRoadTool.UI;
using UnityEngine;

Expand Down Expand Up @@ -221,6 +229,54 @@ public override void OnCreated(ILoading loading)
{
ParallelRoadTool.Instance = new GameObject("ParallelRoadTool").AddComponent<ParallelRoadTool>();
}*/

// Add post locale change event handlers
LocaleManager.eventLocaleChanged += OnLocaleChanged;

DebugUtils.Log("Added locale change event handlers.");

// Reload the current locale once to effect changes
LocaleManager.ForceReload();
}

public override void OnReleased()
{
// Remove post locale change event handlers
LocaleManager.eventLocaleChanged -= OnLocaleChanged;

DebugUtils.Log("Removed locale change event handlers.");

// Reload the current locale once to effect changes
LocaleManager.ForceReload();
}

private void OnLocaleChanged()
{
DebugUtils.Log("Locale changed callback started.");

XmlSerializer serializer = new XmlSerializer(typeof(NameList));

var assembly = Assembly.GetExecutingAssembly();
var resourceName = $"ParallelRoadTool.Localization.{LocaleManager.cultureInfo.TwoLetterISOLanguageName}.xml";

DebugUtils.Log($"Trying to read {resourceName} localization file...");

using (Stream stream = assembly.GetManifestResourceStream(resourceName))
using (StreamReader reader = new StreamReader(stream))
{
using (XmlReader xmlStream = XmlReader.Create(reader))
{
if (serializer.CanDeserialize(xmlStream))
{
NameList nameList = (NameList)serializer.Deserialize(xmlStream);
nameList.Apply();
}
}
}

DebugUtils.Log($"Namelists {resourceName} applied.");

DebugUtils.Log("Locale changed callback finished.");
}

public override void OnLevelLoaded(LoadMode mode)
Expand Down
9 changes: 8 additions & 1 deletion ParallelRoadTool/ParallelRoadTool.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@
<Compile Include="Detours\NetToolDetour.cs" />
<Compile Include="EventArgs\NetworksConfigurationChangedEventArgs.cs" />
<Compile Include="EventArgs\ParallelToolToggledEventArgs.cs" />
<Compile Include="Extensions\LocaleManagerExtensions.cs" />
<Compile Include="Extensions\LocaleModels\LocalizedString.cs" />
<Compile Include="Extensions\LocaleModels\LocalizedStringKey.cs" />
<Compile Include="Extensions\LocaleModels\NameList.cs" />
<Compile Include="Extensions\NetInfoExtensions.cs" />
<Compile Include="Extensions\Vector3Extensions.cs" />
<Compile Include="NetTypeItem.cs" />
Expand All @@ -69,7 +73,8 @@
<Compile Include="Redirection\RedirectReverseAttribute.cs" />
<Compile Include="Redirection\TargetTypeAttribute.cs" />
<Compile Include="Redirection\Tuple.cs" />
<Compile Include="ResourceLoader.cs" />
<Compile Include="ResourceLoader.cs" />
<Compile Include="UI\UITipsWindow.cs" />
<Compile Include="Wrappers\RoadAIWrapper.cs" />
<Compile Include="UI\Base\UIRightDragHandle.cs" />
<Compile Include="UI\UIMainWindow.cs" />
Expand All @@ -93,6 +98,7 @@
<EmbeddedResource Include="Icons\BendingPressed.png" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Localization\en.xml" />
<EmbeddedResource Include="Icons\Reverse.png" />
<EmbeddedResource Include="Icons\ReverseDisabled.png" />
<EmbeddedResource Include="Icons\ReverseFocused.png" />
Expand All @@ -115,6 +121,7 @@
<EmbeddedResource Include="Icons\AddPressed.png" />
<Content Include="Icons\DragCursor.png" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>mkdir "%25LOCALAPPDATA%25\Colossal Order\Cities_Skylines\Addons\Mods\$(SolutionName)"
Expand Down
12 changes: 6 additions & 6 deletions ParallelRoadTool/UI/UIMainWindow.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using ColossalFramework;
using ColossalFramework.Globalization;
using ColossalFramework.UI;
using ParallelRoadTool.UI.Base;
using UnityEngine;
Expand All @@ -22,10 +23,11 @@ public class UIMainWindow : UIPanel

private UIOptionsPanel _mainPanel;
private UINetList _netList;
private NetInfo _netToolSelection;
private NetInfo _netToolSelection;
private UIRightDragHandle _buttonDragHandle;

private UICheckBox _toolToggleButton;
private UICheckBox _snappingToggleButton;
private UIRightDragHandle _buttonDragHandle;

// We use this to prevent clicks while user is dragging the button
private bool _isDragging;
Expand All @@ -39,7 +41,6 @@ public class UIMainWindow : UIPanel
private void UnsubscribeToUIEvents()
{
_toolToggleButton.eventCheckChanged -= ToolToggleButtonOnEventCheckChanged;
_mainPanel.OnToolToggled -= ToolToggleButtonOnEventCheckChanged;
_snappingToggleButton.eventCheckChanged -= SnappingToggleButtonOnEventCheckChanged;
_buttonDragHandle.eventDragStart -= ButtonDragHandleOnEventDragStart;
_buttonDragHandle.eventDragEnd -= ButtonDragHandleOnEventDragEnd;
Expand All @@ -48,7 +49,6 @@ private void UnsubscribeToUIEvents()
private void SubscribeToUIEvents()
{
_toolToggleButton.eventCheckChanged += ToolToggleButtonOnEventCheckChanged;
_mainPanel.OnToolToggled += ToolToggleButtonOnEventCheckChanged;
_snappingToggleButton.eventCheckChanged += SnappingToggleButtonOnEventCheckChanged;
_buttonDragHandle.eventDragStart += ButtonDragHandleOnEventDragStart;
_buttonDragHandle.eventDragEnd += ButtonDragHandleOnEventDragEnd;
Expand Down Expand Up @@ -151,7 +151,7 @@ public override void Start()
space.size = new Vector2(1, 1);

// Add options
_snappingToggleButton = UIUtil.CreateCheckBox(_mainPanel, "Snapping", "Toggle snapping for all nodes", false);
_snappingToggleButton = UIUtil.CreateCheckBox(_mainPanel, "Snapping", Locale.Get("PRT_TOOLTIPS", "SnappingToggleButton"), false);
_snappingToggleButton.relativePosition = new Vector3(166, 38);
_snappingToggleButton.BringToFront();

Expand All @@ -168,7 +168,7 @@ public override void Start()
if (button != null)
Destroy(button);

_toolToggleButton = UIUtil.CreateCheckBox(tsBar, "Parallel", "Parallel Road Tool", false);
_toolToggleButton = UIUtil.CreateCheckBox(tsBar, "Parallel", Locale.Get("PRT_TOOLTIPS", "ToolToggleButton"), false);
if (SavedToggleX.value != -1000 && SavedToggleY.value != -1000)
{
_toolToggleButton.absolutePosition = new Vector3(SavedToggleX.value, SavedToggleY.value);
Expand Down
Loading

0 comments on commit 0a104e3

Please sign in to comment.