Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 15 additions & 9 deletions TLM/TLM/State/GlobalConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ namespace TrafficManager.State {
using TrafficManager.Util;
using TrafficManager.Lifecycle;

[XmlRootAttribute(
"GlobalConfig",
IsNullable = false)]
[XmlRoot("GlobalConfig", IsNullable = false)]
public class GlobalConfig : GenericObservable<GlobalConfig> {
public const string FILENAME = "TMPE_GlobalConfig.xml";
public const string BACKUP_FILENAME = FILENAME + ".bak";
Expand Down Expand Up @@ -79,17 +77,25 @@ internal static void OnLevelUnloading() { }

public ConfigData.TimedTrafficLights TimedTrafficLights = new();

[XmlElement("DefaultsForNewGame")]
public SavedGameOptions SavedGameOptions = null;

internal static void WriteConfig() {
ModifiedTime = WriteConfig(Instance);
}

/// <summary>
/// Replaces global config file with default config.
/// </summary>
/// <param name="oldConfig">if null, all is reset, otherwise old config is migrated to new config.</param>
/// <param name="modifiedTime">time of the file created</param>
/// <returns>the new default config</returns>
private static GlobalConfig WriteDefaultConfig(GlobalConfig oldConfig,
bool resetAll,
out DateTime modifiedTime) {
Log._Debug($"Writing default config...");
GlobalConfig conf = new GlobalConfig();

if (!resetAll && oldConfig != null) {
if (oldConfig != null) {
conf.Main.MainMenuButtonX = oldConfig.Main.MainMenuButtonX;
conf.Main.MainMenuButtonY = oldConfig.Main.MainMenuButtonY;

Expand Down Expand Up @@ -190,7 +196,7 @@ public static GlobalConfig Load(out DateTime modifiedTime) {
}
catch (Exception e) {
Log.Warning($"Could not load global config: {e} Generating default config.");
return WriteDefaultConfig(null, false, out modifiedTime);
return WriteDefaultConfig(null, out modifiedTime);
}
}

Expand All @@ -214,17 +220,17 @@ public static void Reload(bool checkVersion = true) {
$"Error occurred while saving backup config to '{filename}': {e.ToString()}");
}

Reset(conf);
Reset(oldConfig: conf);
} else {
Instance = conf;
ModifiedTime = WriteConfig(Instance);
}
}

public static void Reset(GlobalConfig oldConfig, bool resetAll = false) {
public static void Reset(GlobalConfig oldConfig) {
Log.Info($"Resetting global config.");
DateTime modifiedTime;
Instance = WriteDefaultConfig(oldConfig, resetAll, out modifiedTime);
Instance = WriteDefaultConfig(oldConfig, out modifiedTime);
ModifiedTime = modifiedTime;
}

Expand Down
14 changes: 12 additions & 2 deletions TLM/TLM/State/OptionsTabs/MaintenanceTab_ConfigGroup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,15 @@ public static class MaintenanceTab_ConfigGroup {
Handler = OnReloadGlobalConfigClicked,
};
public static ActionButton ResetGlobalConfig = new() {
Label = "Maintenance.Button:Reset global configuration",
Label = "Maintenance.Button:Reset all configuration",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

? This will be super confusing for users.
1, they will ask what happened to reset global config button
2. they will ash what does "all" even mean.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

global is also not accurate because we are resetting defaults for new game too.
@krzychu124 what do you suggest I do?

Copy link
Member

@krzychu124 krzychu124 Dec 5, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure why you decided to save defaults in global config?
Global settings are user regardless of state but the defaults would be used only in specific condition which suggest that is not the best place for that.
Maybe we just need something like TMPE_DefaultGameSettings.xml created automatically, and then the user could even change things by hand? This way we could easily handle multiple versions of settings, e.g.: with popup with list of configs to use, similar to MoveIt Import/Export modal (it could simply overwrite the main file with selected one). That seem to be more future proof and most likely easier to manage.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cool I create new file.

@krzychu124 but I still don't understand what should I call that button? should I split it into 2 buttons?

i mean its kind of global and currently there is no way for user to tell which settings are global except for trial and error (or read the xml files).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, maybe we need and icon or something to mark in-game specific options? I can be even ❔ button with a tooltip informing that setting is in-game only

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or maybe saved game options can have different text color in main menu.

@krzychu124 but I still don't understand what should I call that button? should I split it into 2 buttons?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leave it like it was "Global configuration" has its own meaning in the mod, wiki etc., always refers to GlobalConfig configuration file

Handler = OnResetGlobalConfigClicked,
};

public static ActionButton SetAsDefaultForNewGames = new() {
Label = "Maintenance.Button:Set as default for new games",
Handler = OnSetAsDefaultForNewGamesClicked,
};

#if DEBUG
public static ActionButton DebugSwiches = new() {
Translator = key => key,
Expand All @@ -33,6 +38,7 @@ internal static void AddUI(UIHelperBase tab) {
#if DEBUG
DebugSwiches.AddUI(group);
#endif
SetAsDefaultForNewGames.AddUI(group);
}

private static string T(string key) => Translation.Options.Get(key);
Expand All @@ -41,6 +47,10 @@ private static void OnReloadGlobalConfigClicked()
=> GlobalConfig.Reload();

private static void OnResetGlobalConfigClicked()
=> GlobalConfig.Reset(oldConfig: null, resetAll: true);
=> GlobalConfig.Reset(oldConfig: null);
private static void OnSetAsDefaultForNewGamesClicked() {
GlobalConfig.Instance.SavedGameOptions = SavedGameOptions.Instance;
GlobalConfig.WriteConfig();
}
}
}
14 changes: 11 additions & 3 deletions TLM/TLM/State/SavedGameOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ namespace TrafficManager.State;
using System;
using System.Text;
using TrafficManager.API.Traffic.Enums;
using TrafficManager.Custom.PathFinding;
using TrafficManager.Lifecycle;
using TrafficManager.Util;

public class SavedGameOptions {
Expand Down Expand Up @@ -112,10 +112,19 @@ public bool IsDynamicLaneSelectionActive() {
public static bool Available { get; set; } = false;

public static SavedGameOptions Instance { get; private set; }

/// <summary>
/// ensures SavedGameOptions exists.
/// if not then it is set to global default or built-in default (if global default does not exist).
/// </summary>
public static void Ensure() {
Log.Info("SavedGameOptions.Ensure() called");
if (Instance == null) {
Create();
if (GlobalConfig.Instance?.SavedGameOptions != null) {
Instance = GlobalConfig.Instance.SavedGameOptions;
} else {
Create();
}
}
}
private static void Create() {
Expand All @@ -142,7 +151,6 @@ public byte[] Seraialize() {
return null;
}
}

public static bool Deserialzie(byte[] data) {
try {
if (!data.IsNullOrEmpty()) {
Expand Down
15 changes: 4 additions & 11 deletions TLM/TLM/UI/Helpers/CheckboxOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,22 +112,15 @@ protected override void UpdateLabel() {
protected override void UpdateTooltip() {
if (!HasUI) return;

_ui.tooltip = IsInScope
? string.IsNullOrEmpty(_tooltip)
? string.Empty // avoid invalidating UI if already no tooltip
: Translate(_tooltip)
: Translate(INGAME_ONLY_SETTING);
_ui.tooltip = Tooltip;
}

protected override void UpdateReadOnly() {
if (!HasUI) return;
Log._Debug($"CheckboxOption.UpdateReadOnly() - `{FieldName}` is {(ReadOnly ? "read-only" : "writeable")}");

var readOnly = !IsInScope || _readOnly;

Log._Debug($"CheckboxOption.UpdateReadOnly() - `{FieldName}` is {(readOnly ? "read-only" : "writeable")}");

_ui.readOnly = readOnly;
_ui.opacity = readOnly ? 0.3f : 1f;
_ui.readOnly = ReadOnly;
_ui.opacity = ReadOnly ? 0.3f : 1f;
}

/* UI helper methods */
Expand Down
4 changes: 2 additions & 2 deletions TLM/TLM/UI/Helpers/DLCRestrictedCheckboxOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public DLCRestrictedCheckboxOption(string fieldName,
SteamHelper.DLC requiredDLC,
Scope scope = Scope.Savegame) : base(fieldName, scope) {
_requiredDLC = requiredDLC;
_readOnly = !SteamHelper.IsDLCOwned(_requiredDLC);
ReadOnly = !SteamHelper.IsDLCOwned(_requiredDLC);
}

public override CheckboxOption AddUI(UIHelperBase container) {
Expand All @@ -36,7 +36,7 @@ public override CheckboxOption AddUI(UIHelperBase container) {
innerPanel.autoFitChildrenVertically = true;
innerPanel.autoLayout = true;

if (_readOnly) {
if (ReadOnly) {
icon.tooltip = Locale.Get("CONTENT_REQUIRED", _requiredDLC.ToString());
_ui.tooltip = Translate("Checkbox:DLC is required to change this option and see effects in game");
}
Expand Down
21 changes: 7 additions & 14 deletions TLM/TLM/UI/Helpers/DropDownOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,25 +94,18 @@ protected override void UpdateLabel() {
}

protected override void UpdateTooltip() {
if (!HasUI) return;

//UIDropDown parent(UIPanel) handles tooltip
_ui.parent.tooltip = IsInScope
? $"{_tooltip}"
: Translate(INGAME_ONLY_SETTING);
if (HasUI) {
_ui.parent.tooltip = Tooltip;
}
}

protected override void UpdateReadOnly() {
if (!HasUI) return;
Log._Debug($"DropDownOption.UpdateReadOnly() - `{FieldName}` is {(ReadOnly ? "read-only" : "writeable")}");

var readOnly = !IsInScope || _readOnly;

Log._Debug($"DropDownOption.UpdateReadOnly() - `{FieldName}` is {(readOnly ? "read-only" : "writeable")}");

_ui.isInteractive = !readOnly;
_ui.opacity = readOnly ? 0.3f : 1f;
// parent is UIPanel containing text label and dropdown
_dropdownLabel.opacity = readOnly ? 0.3f : 1f;
_ui.isInteractive = !ReadOnly;
_ui.opacity = ReadOnly ? 0.3f : 1f;
_dropdownLabel.opacity = ReadOnly ? 0.3f : 1f;
}
}
}
23 changes: 5 additions & 18 deletions TLM/TLM/UI/Helpers/SerializableUIOptionBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ public OnChanged Handler {
/// </summary>
public ValidatorDelegate Validator { get; set; }

protected Scope _scope;

[CanBeNull]
private FieldInfo _fieldInfo;

Expand All @@ -52,7 +50,6 @@ public OnChanged Handler {
public SerializableUIOptionBase(string fieldName, Scope scope) {

_fieldName = fieldName;
_scope = scope;
if (scope.IsFlagSet(Scope.Savegame)) {
_fieldInfo = typeof(SavedGameOptions).GetField(fieldName);

Expand Down Expand Up @@ -98,16 +95,6 @@ public virtual TVal Value {

public string FieldName => _fieldInfo?.Name ?? _fieldName;

/// <summary>Returns <c>true</c> if setting can persist in current <see cref="_scope"/>.</summary>
/// <remarks>
/// When <c>false</c>, UI component should be <see cref="_readOnly"/>
/// and <see cref="_tooltip"/> should be set to <see cref="INGAME_ONLY_SETTING"/>.
/// </remarks>
protected bool IsInScope =>
_scope.IsFlagSet(Scope.Global) ||
(_scope.IsFlagSet(Scope.Savegame) && TMPELifecycle.AppMode != null) ||
_scope == Scope.None;

public static implicit operator TVal(SerializableUIOptionBase<TVal, TUI, TComponent> a) => a.Value;

public void DefaultOnValueChanged(TVal newVal) {
Expand All @@ -126,10 +113,10 @@ public void DefaultOnValueChanged(TVal newVal) {
public bool HasUI => _ui != null;
protected TUI _ui;

protected string _label;
protected string _tooltip;
private string _label;
private string _tooltip;

protected bool _readOnly;
private bool _readOnly;

private TranslatorDelegate _translator;
public delegate string TranslatorDelegate(string key);
Expand Down Expand Up @@ -161,7 +148,7 @@ public string Label {
}

public string Tooltip {
get => _tooltip;
get => _tooltip ?? string.Empty;
set {
_tooltip = value;
UpdateTooltip();
Expand All @@ -171,7 +158,7 @@ public string Tooltip {
public bool ReadOnly {
get => _readOnly;
set {
_readOnly = !IsInScope || value;
_readOnly = value;
UpdateReadOnly();
}
}
Expand Down
16 changes: 6 additions & 10 deletions TLM/TLM/UI/Helpers/SliderOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public override SliderOption AddUI(UIHelperBase container) {
protected override void UpdateLabel() {
if (!HasUI) return;

string tooltip = IsInScope ? $"{Value}{_tooltip}" : Translate(INGAME_ONLY_SETTING);
string tooltip = $"{Value}{Tooltip}";
string label = Translate(Label);
_sliderLabel.text = label + ": " + tooltip;
}
Expand All @@ -119,16 +119,12 @@ protected override void UpdateLabel() {

protected override void UpdateReadOnly() {
if (!HasUI) return;
Log._Debug($"SliderOption.UpdateReadOnly() - `{FieldName}` is {(ReadOnly ? "read-only" : "writeable")}");

var readOnly = !IsInScope || _readOnly;

Log._Debug($"SliderOption.UpdateReadOnly() - `{FieldName}` is {(readOnly ? "read-only" : "writeable")}");

_ui.isInteractive = !readOnly;
_ui.thumbObject.isInteractive = !readOnly;
_ui.thumbObject.opacity = readOnly ? 0.3f : 1f;
// parent is UIPanel containing text label and slider
_sliderLabel.opacity = readOnly ? 0.3f : 1f;
_ui.isInteractive = !ReadOnly;
_ui.thumbObject.isInteractive = !ReadOnly;
_ui.thumbObject.opacity = ReadOnly ? 0.3f : 1f;
_sliderLabel.opacity = ReadOnly ? 0.3f : 1f;
}
}
}
18 changes: 6 additions & 12 deletions TLM/TLM/UI/Helpers/TriStateCheckboxOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,24 +101,18 @@ protected override void UpdateLabel() {
}

protected override void UpdateTooltip() {
if (!HasUI) return;

_ui.tooltip = IsInScope
? string.IsNullOrEmpty(_tooltip)
? string.Empty // avoid invalidating UI if already no tooltip
: Translate(_tooltip)
: Translate(INGAME_ONLY_SETTING);
if (HasUI) {
_ui.tooltip = Tooltip;
}
}

protected override void UpdateReadOnly() {
if (!HasUI) return;

var readOnly = !IsInScope || _readOnly;

Log._Debug($"TriStateCheckboxOption.UpdateReadOnly() - `{FieldName}` is {(readOnly ? "read-only" : "writeable")}");
Log._Debug($"TriStateCheckboxOption.UpdateReadOnly() - `{FieldName}` is {(ReadOnly ? "read-only" : "writeable")}");

_ui.readOnly = readOnly;
_ui.opacity = readOnly ? 0.3f : 1f;
_ui.readOnly = ReadOnly;
_ui.opacity = ReadOnly ? 0.3f : 1f;
}

/* UI helper methods */
Expand Down