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 settings; private ReadOnlyDictionary gpsReceivers; private bool HasChanges; public ConfigureGpsWindow(Ini ini) { Ini = ini; IsOpen = true; selectedGpsReceiver = ini.ReadValue("startup", "gps", 0); settings = new List(); gpsReceivers = GpsManager.GetGpsTunerFactories(); foreach (KeyValuePair 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 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 keyValuePair in gpsReceivers) { if (ImGui.RadioButton(keyValuePair.Value.GetType().Name, ref selectedGpsReceiver, keyValuePair.Key)) { HasChanges = true; } if (keyUuids == null) keyUuids = new Dictionary(); 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; } } }