skyscraper8/GUIs/skyscraper8.UI.ImGui/Forms/ConfigureGpsWindow.cs
2025-06-30 22:57:40 +02:00

219 lines
6.1 KiB
C#

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using ImGuiNET;
using skyscraper5.Skyscraper;
using skyscraper5.Skyscraper.Gps;
using skyscraper5.Skyscraper.Scraper.Storage;
using static SDL2Demo.Forms.ConfigureDataStorageWindow;
namespace SDL2Demo.Forms
{
internal class ConfigureGpsWindow : IRenderable
{
public Ini Ini { get; }
public bool IsOpen;
public bool RequireRestart { get; private set; }
private int selectedGpsReceiver;
private List<Setting> settings;
private ReadOnlyDictionary<int, IGpsReceiverFactory> gpsReceivers;
private bool HasChanges;
public ConfigureGpsWindow(Ini ini)
{
Ini = ini;
IsOpen = true;
selectedGpsReceiver = ini.ReadValue("startup", "gps", 0);
settings = new List<Setting>();
gpsReceivers = GpsManager.GetGpsTunerFactories();
foreach (KeyValuePair<int, IGpsReceiverFactory> keyValuePair in gpsReceivers)
{
PropertyInfo[] propertyInfos = keyValuePair.Value.GetType().GetProperties();
foreach (PropertyInfo propertyInfo in propertyInfos)
{
Setting s = new Setting();
s.IniKey = keyValuePair.Key;
s.SettingName = propertyInfo.Name;
s.SettingControlUuid = Guid.NewGuid().ToString();
switch (propertyInfo.PropertyType.Name)
{
case nameof(String):
s.SettingMode = 1;
s.StringValue = ini.ReadValue(String.Format("gps{0}", s.IniKey), s.SettingName, "");
break;
case nameof(Boolean):
s.SettingMode = 2;
s.BooleanValue = ini.ReadValue(String.Format("gps{0}", s.IniKey), s.SettingName, false);
break;
case nameof(UInt16):
s.SettingMode = 3;
s.UshortValue = (ushort)ini.ReadValue(String.Format("gps{0}", s.IniKey), s.SettingName, ushort.MinValue);
break;
case nameof(Single):
s.SettingMode = 4;
s.FloatValue = (float)ini.ReadValue(String.Format("gps{0}", s.IniKey), s.SettingName, 0.0f);
break;
case nameof(Int32):
s.SettingMode = 5;
s.IntegerValue = (int)ini.ReadValue(String.Format("gps{0}", s.IniKey), s.SettingName, 0);
break;
default:
throw new NotImplementedException(propertyInfo.PropertyType.Name);
}
settings.Add(s);
}
}
}
private void Save()
{
Ini.WriteValue("startup", "gps", selectedGpsReceiver);
foreach (Setting setting in settings)
{
switch (setting.SettingMode)
{
case 1:
Ini.WriteValue(String.Format("gps{0}", setting.IniKey), setting.SettingName, setting.StringValue);
break;
case 2:
Ini.WriteValue(String.Format("gps{0}", setting.IniKey), setting.SettingName, setting.BooleanValue);
break;
case 3:
Ini.WriteValue(String.Format("gps{0}", setting.IniKey), setting.SettingName, setting.UshortValue);
break;
case 4:
Ini.WriteValue(String.Format("gps{0}", setting.IniKey), setting.SettingName, setting.FloatValue);
break;
case 5:
Ini.WriteValue(String.Format("gps{0}", setting.IniKey), setting.SettingName, setting.IntegerValue);
break;
default:
throw new NotImplementedException(String.Format("Setting mode {0}", setting.SettingMode));
}
}
Ini.Export(new FileInfo("skyscraper5.ini"));
if (HasChanges)
RequireRestart = true;
HasChanges = false;
}
private Dictionary<long, string> keyUuids;
public void Render()
{
float itemWidth = 100.0f;
ImGuiWindowFlags flags = ImGuiWindowFlags.None;
if (HasChanges)
flags |= ImGuiWindowFlags.UnsavedDocument;
ImGui.Begin("Configure GPS Receiver", ref IsOpen, flags);
foreach (KeyValuePair<int, IGpsReceiverFactory> keyValuePair in gpsReceivers)
{
if (ImGui.RadioButton(keyValuePair.Value.GetType().Name, ref selectedGpsReceiver, keyValuePair.Key))
{
HasChanges = true;
}
if (keyUuids == null)
keyUuids = new Dictionary<long, string>();
if (!keyUuids.ContainsKey(keyValuePair.Key))
keyUuids.Add(keyValuePair.Key, Guid.NewGuid().ToString());
ImGui.BeginTable(keyUuids[keyValuePair.Key], 2);
foreach (Setting setting in settings.Where(x => x.IniKey == keyValuePair.Key))
{
ImGui.TableNextRow();
ImGui.TableSetColumnIndex(0);
ImGui.Text(setting.SettingName);
ImGui.TableSetColumnIndex(1);
ImGui.PushID(setting.SettingControlUuid);
switch (setting.SettingMode)
{
case 1:
ImGui.SetNextItemWidth(itemWidth);
if (ImGui.InputText("", ref setting.StringValue, 255))
HasChanges = true;
break;
case 2:
if (ImGui.Checkbox("", ref setting.BooleanValue))
HasChanges = true;
break;
case 3:
if (setting.UshortValue < ushort.MinValue)
setting.UshortValue = ushort.MinValue;
if (setting.UshortValue > ushort.MaxValue)
setting.UshortValue = ushort.MaxValue;
ImGui.SetNextItemWidth(itemWidth);
if (ImGui.InputInt("", ref setting.UshortValue))
HasChanges = true;
break;
case 4:
ImGui.SetNextItemWidth(itemWidth);
if (ImGui.InputFloat("", ref setting.FloatValue, 0.01f, 0.1f))
HasChanges = true;
break;
case 5:
ImGui.SetNextItemWidth(itemWidth);
if (ImGui.InputInt("", ref setting.IntegerValue, 1, 10))
HasChanges = true;
break;
default:
throw new NotImplementedException(String.Format("Setting mode {0}", setting.SettingMode));
}
}
ImGui.PopID();
ImGui.EndTable();
}
bool canApply = CanApply();
ImGui.BeginDisabled(!canApply);
if (ImGui.Button("OK"))
{
Save();
IsOpen = false;
}
ImGui.EndDisabled();
ImGui.SameLine();
if (ImGui.Button("Cancel"))
{
IsOpen = false;
}
ImGui.SameLine();
ImGui.BeginDisabled(!canApply);
if (ImGui.Button("Apply"))
{
Save();
}
ImGui.EndDisabled();
ImGui.End();
}
private bool CanApply()
{
foreach (Setting setting in settings.Where(x => x.IniKey == selectedGpsReceiver))
{
if (!setting.Validate())
{
return false;
}
}
return true;
}
}
}