The scissor code should now properly cut all controls from going past the parent.
634 lines
22 KiB
C#
634 lines
22 KiB
C#
using System.CodeDom.Compiler;
|
|
using System.ComponentModel;
|
|
using System.Reflection;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using System.Text.Json.Serialization.Metadata;
|
|
using GraphicsManager;
|
|
using GraphicsManager.Enums;
|
|
using GraphicsManager.Interfaces;
|
|
using GraphicsManager.Objects;
|
|
using GraphicsManager.Objects.Core;
|
|
using Luski.Classes;
|
|
using Luski.Classes.ThemeSub;
|
|
using Luski.GUI;
|
|
using Luski.GUI.MainScreen.UI.LuskiControls;
|
|
using Luski.net;
|
|
using Luski.net.Enums;
|
|
using Luski.net.Interfaces;
|
|
using Luski.net.Structures.Public;
|
|
using Luski.Shared.PublicServers.V1.Enums;
|
|
using OpenTK.Graphics.OpenGL4;
|
|
using OpenTK.Mathematics;
|
|
using OpenTK.Windowing.Common.Input;
|
|
using OpenTK.Windowing.Desktop;
|
|
|
|
namespace Luski;
|
|
|
|
public static class Globals
|
|
{
|
|
#pragma warning disable CS8618
|
|
public static List<Task<bool>> ServersLoading = new();
|
|
public static ServerList ServerList;
|
|
public static Dictionary<Window, List<IRenderObject>> AllowedBehindObjects = new();
|
|
|
|
public static ThemeStart Theme
|
|
{
|
|
get
|
|
{
|
|
return LuskiThemes.LuskiThemeList.Where(s => s.Name == Settings.Theme).First();
|
|
}
|
|
}
|
|
|
|
public static ServerThemeProperties GetTheme(this PublicServer ser)
|
|
{
|
|
IEnumerable<ServerTheme> l = Theme.ServerOverrides.Where(s => s.Address == ser.Domain);
|
|
ServerTheme[] serverThemes = l as ServerTheme[] ?? l.ToArray();
|
|
if (serverThemes.Any()) return serverThemes[0].Properties;
|
|
return Theme.GlobalServerTemplate;
|
|
}
|
|
|
|
private static List<ExperimentInfo> AddedExperiments = new();
|
|
private static List<ExperimentInfo> EnabledExperiments = new();
|
|
public static List<ExperimentJson> MissingExperiments = new();
|
|
private static Dictionary<ExperimentSelectorInfo, ExperimentInfo> ExperimentSelectorInfos = new();
|
|
public static IReadOnlyList<ExperimentInfo> Experiments => AddedExperiments.AsReadOnly();
|
|
|
|
private static int LastExpCount = 0;
|
|
|
|
public static Color4 DodgerBlue = new Color4(30, 144, 255, 255);
|
|
private static bool msc = true;
|
|
private static double mscale = -1;
|
|
|
|
public static double GetScale()
|
|
{
|
|
if (Settings.Scale is not null) return Settings.Scale.Value;
|
|
if (msc)
|
|
{
|
|
msc = false;
|
|
mscale = Monitors.GetMonitorFromWindow(ms).HorizontalScale;
|
|
}
|
|
return mscale;
|
|
}
|
|
public static int ScaleInt(this int i)
|
|
{
|
|
return (int)(GetScale() * i);
|
|
}
|
|
public static int ScaleInt(this double i)
|
|
{
|
|
return (int)(GetScale() * i);
|
|
}
|
|
public static double ScaleDouble(this int i)
|
|
{
|
|
return (GetScale() * i);
|
|
}
|
|
public static double ScaleDouble(this double i)
|
|
{
|
|
return (GetScale() * i);
|
|
}
|
|
public static uint ScaleFont(this uint i)
|
|
{
|
|
if (Globals.Settings.ScaleFonts) return (uint)(GetScale() * i);
|
|
return i;
|
|
}
|
|
|
|
public static void PrintParent(IParent par)
|
|
{
|
|
void PrintP(int index, IParent p, Vector3i l)
|
|
{
|
|
string sp = "";
|
|
for (int i = 0; i < index; i++)
|
|
{
|
|
sp += " ";
|
|
}
|
|
|
|
for (int i = 0; i < p.Controls.Length; i++)
|
|
{
|
|
if (p.Controls[i].IgnoreHover) continue;
|
|
Console.WriteLine(sp + p.Controls[i] + ": " + p.Controls[i].Location + " " + (p.Controls[i].Location + l) + " "+ p.Controls[i].Size);
|
|
if (p.Controls[i] is IParent pp) PrintP(index + 1, pp, l + pp.Position);
|
|
}
|
|
}
|
|
Console.WriteLine(par + ": " + par.Position + par.Size);
|
|
PrintP(1,par, par.Position);
|
|
}
|
|
|
|
public static void RegisterExperiment(ExperimentInfo exp)
|
|
{
|
|
IEnumerable<ExperimentJson> found = MissingExperiments.Where(e => e.Name == exp.Name);
|
|
ExperimentJson[] experimentInfos = found as ExperimentJson[] ?? found.ToArray();
|
|
if (experimentInfos.Length > 0)
|
|
{
|
|
MissingExperiments.Remove(experimentInfos[0]);
|
|
EnabledExperiments.Add(exp);
|
|
}
|
|
AddedExperiments.Add(exp);
|
|
foreach (ExperimentSelectorInfo esi in exp.Options)
|
|
{
|
|
ExperimentSelectorInfos.Add(esi, exp);
|
|
}
|
|
}
|
|
|
|
public static void Toggle(this ExperimentSelectorInfo exp)
|
|
{
|
|
if (!ExperimentSelectorInfos.TryGetValue(exp, out ExperimentInfo EI)) return;
|
|
if (Settings.Experiments.Any(e => e.Name == EI.Name))
|
|
{
|
|
ExperimentJson ej = Settings.Experiments.Where(e => e.Name == EI.Name).First();
|
|
if (EI.Selected == EI.Options.IndexOf(exp))
|
|
{
|
|
Settings.Experiments.Remove(ej);
|
|
EnabledExperiments.Remove(EI);
|
|
EI.Selected = null;
|
|
LastExpCount--;
|
|
exp.SendTog(false);
|
|
}
|
|
else
|
|
{
|
|
EI.Options[EI.Selected!.Value].SendTog(false);
|
|
ej.Selected = EI.Options.IndexOf(exp);
|
|
EI.Selected = ej.Selected;
|
|
exp.SendTog(true);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LastExpCount++;
|
|
ExperimentJson ej = new()
|
|
{
|
|
Name = EI.Name,
|
|
Selected = EI.Options.IndexOf(exp)
|
|
};
|
|
Settings.Experiments.Add(ej);
|
|
EI.Selected = ej.Selected;
|
|
if (!EnabledExperiments.Contains(EI)) EnabledExperiments.Add(EI);
|
|
exp.SendTog(true);
|
|
}
|
|
Settings.SaveSettings(Path.Combine(Globals.LuskiPath, "Settings.json"), SettingsContext.Default.Settings);
|
|
}
|
|
|
|
public static bool IsEnabled(this ExperimentSelectorInfo exp)
|
|
{
|
|
if (!ExperimentSelectorInfos.TryGetValue(exp, out ExperimentInfo EI)) return false;
|
|
if (LastExpCount != Settings.Experiments.Count)
|
|
{
|
|
//rescan
|
|
foreach (ExperimentJson experiment in Settings.Experiments)
|
|
{
|
|
IEnumerable<ExperimentInfo> found = AddedExperiments.Where(e => e.Name == experiment.Name);
|
|
ExperimentInfo[] experimentInfos = found as ExperimentInfo[] ?? found.ToArray();
|
|
if (experimentInfos.Count() > 0)
|
|
{
|
|
if (!EnabledExperiments.Contains(experimentInfos[0])) EnabledExperiments.Add(experimentInfos[0]);
|
|
experimentInfos[0].Selected = experiment.Selected;
|
|
}
|
|
else
|
|
{
|
|
MissingExperiments.Add(experiment);
|
|
}
|
|
}
|
|
|
|
LastExpCount = Settings.Experiments.Count;
|
|
}
|
|
|
|
//detect
|
|
return EnabledExperiments.Contains(EI) && EI.Selected.HasValue && EI.Options.Count > EI.Selected &&
|
|
EI.Options[EI.Selected.Value] == exp;
|
|
}
|
|
|
|
private static Dictionary<TextureManager, Dictionary<string, Texture>> TextureResources = new();
|
|
|
|
public static Texture GetTextureResource(this TextureManager tm, string File)
|
|
{
|
|
try
|
|
{
|
|
if (!TextureResources.ContainsKey(tm)) TextureResources.Add(tm, new());
|
|
if (TextureResources[tm].TryGetValue(File, out Texture? t)) return t;
|
|
t = tm.AddTexture(GetResource($"Textures.{File}"));
|
|
TextureResources[tm].Add(File,t);
|
|
return t;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Console.WriteLine(e);
|
|
throw;
|
|
}
|
|
}
|
|
|
|
public static Stream GetResource(string File)
|
|
{
|
|
return Tools.GetResourceStream(Assembly.GetExecutingAssembly(),
|
|
$"Luski.Resources.{File}");
|
|
}
|
|
|
|
public static void AddBehindObject(this Window w, IRenderObject obj)
|
|
{
|
|
if (!AllowedBehindObjects.ContainsKey(w)) AllowedBehindObjects.Add(w, new());
|
|
if (AllowedBehindObjects[w].Count > 0)
|
|
{
|
|
obj.AllowHoverFromBehind = AllowedBehindObjects[w][0].AllowHoverFromBehind;
|
|
}
|
|
w.Controls.Add(obj);
|
|
AllowedBehindObjects[w].Add(obj);
|
|
}
|
|
|
|
public static void ToggleBehindObjects(this Window w)
|
|
{
|
|
if (!AllowedBehindObjects.ContainsKey(w)) AllowedBehindObjects.Add(w, new());
|
|
if (AllowedBehindObjects[w].Count > 0)
|
|
{
|
|
bool new_val = !AllowedBehindObjects[w][0].AllowHoverFromBehind;
|
|
foreach (IRenderObject v in AllowedBehindObjects[w])
|
|
{
|
|
v.AllowHoverFromBehind = new_val;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void RemoveBehindObject(this Window w, IRenderObject obj, bool purge = true)
|
|
{
|
|
if (!AllowedBehindObjects.ContainsKey(w)) AllowedBehindObjects.Add(w, new());
|
|
AllowedBehindObjects[w].Remove(obj);
|
|
w.Controls.Remove(obj, purge);
|
|
obj.Clean();
|
|
obj = null!;
|
|
}
|
|
|
|
|
|
public static bool Download { get; set; } = false;
|
|
public static API Luski { get; } = new();
|
|
public static MainScreenWindow ms;
|
|
|
|
public static UserControl AddBool(IParent parent, string Name, string description, bool s, Action<bool> a, List<Label>? List = null)
|
|
{
|
|
ToggleSwitch ts = new()
|
|
{
|
|
Value = s,
|
|
Anchor = ObjectAnchor.Top | ObjectAnchor.Right
|
|
};
|
|
UserControl tc = new()
|
|
{
|
|
BackgroundColor = new(0,0,0,0)
|
|
};
|
|
Label l, ll;
|
|
int space = 5.ScaleInt();
|
|
tc.Controls.Add(ll =new Label(Globals.DefaultFont)
|
|
{
|
|
Location = new(0, space + space, 0),
|
|
Text = Name
|
|
});
|
|
tc.Controls.Add(l =new Label(Globals.DefaultFont)
|
|
{
|
|
Location = new(ll.Location.X, ll.Size.Y + space, 0),
|
|
Color = Color4.Gray,
|
|
MaxSize = parent.Size,
|
|
Text = description
|
|
});
|
|
if (List is not null) List.Add(l);
|
|
tc.Size = l.Size;
|
|
tc.Controls.Add(ts);
|
|
ts.Location = new(parent.Size.X - ts.Size.X - 5.ScaleInt(), ll.Location.Y, 0);
|
|
|
|
Rectangle TempLine = new()
|
|
{
|
|
Location = new(0, l.Location.Y + l.Size.Y + space, 0),
|
|
BackgroundColor = Color4.White,
|
|
Anchor = ObjectAnchor.Left | ObjectAnchor.Right | ObjectAnchor.Top
|
|
};
|
|
l.Tag = TempLine;
|
|
TempLine.Size = new(parent.Size.X - space - space, 2.ScaleInt());
|
|
tc.SetSize(parent.Size.X, TempLine.Location.Y + TempLine.Size.Y);
|
|
TempLine.ForceDistanceUpdate(tc);
|
|
tc.Controls.Add(TempLine);
|
|
//ts.ForceDistanceUpdate(tc);
|
|
ts.ValueChanged += @switch =>
|
|
{
|
|
a.Invoke(@switch.Value);
|
|
return Task.CompletedTask;
|
|
};
|
|
tc.ForceDistanceUpdate(parent);
|
|
parent.Controls.Add(tc);
|
|
return tc;
|
|
}
|
|
|
|
public static void AddBool<TEnum>(IParent parent, Type t, TEnum e, bool s, Action<bool> a, List<Label>? List = null) where TEnum : Enum
|
|
{
|
|
MemberInfo? enumValueMemberInfo = GetMemberInfo(t, e);
|
|
object[] valueAttributes =
|
|
enumValueMemberInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
|
|
if (valueAttributes.Length == 0) return;
|
|
string description = ((DescriptionAttribute)valueAttributes[0]).Description;
|
|
object[] namevalueAttributes =
|
|
enumValueMemberInfo.GetCustomAttributes(typeof(Luski.Shared.GlobalAttributes.DisplayNameAttribute), false);
|
|
if (namevalueAttributes.Length == 0) return;
|
|
string Name = ((Luski.Shared.GlobalAttributes.DisplayNameAttribute)namevalueAttributes[0]).DisplayName;
|
|
AddBool(parent, Name, description,s,a,List);
|
|
}
|
|
|
|
public static void AddBool(IParent parent, PropertyInfo t, bool s, Action<bool> a, List<Label>? List = null)
|
|
{
|
|
object[] valueAttributes =
|
|
t.GetCustomAttributes(typeof(DescriptionAttribute), false);
|
|
if (valueAttributes.Length == 0) return;
|
|
string description = ((DescriptionAttribute)valueAttributes[0]).Description;
|
|
object[] namevalueAttributes =
|
|
t.GetCustomAttributes(typeof(Luski.Shared.GlobalAttributes.DisplayNameAttribute), false);
|
|
if (namevalueAttributes.Length == 0) return;
|
|
string Name = ((Luski.Shared.GlobalAttributes.DisplayNameAttribute)namevalueAttributes[0]).DisplayName;
|
|
AddBool(parent, Name, description,s,a,List);
|
|
}
|
|
|
|
public static TAttribute GetAttribute<TAttribute, TEnum>(Type t, TEnum e) where TAttribute : Attribute where TEnum : Enum
|
|
{
|
|
MemberInfo? enumValueMemberInfo = GetMemberInfo(t, e);
|
|
object[] valueAttributes =
|
|
enumValueMemberInfo!.GetCustomAttributes(typeof(TAttribute), false);
|
|
return (TAttribute)valueAttributes[0];
|
|
}
|
|
|
|
public static TAttribute GetAttribute<TAttribute, TEnum>(MemberInfo enumValueMemberInfo, TEnum e) where TAttribute : Attribute where TEnum : Enum
|
|
{
|
|
object[] valueAttributes =
|
|
enumValueMemberInfo.GetCustomAttributes(typeof(TAttribute), false);
|
|
return (TAttribute)valueAttributes[0];
|
|
}
|
|
|
|
public static MemberInfo? GetMemberInfo<TEnum>(Type t, TEnum e) where TEnum : Enum
|
|
{
|
|
MemberInfo[] memberInfos =
|
|
t.GetMember(e.ToString());
|
|
MemberInfo? enumValueMemberInfo = memberInfos.FirstOrDefault(m =>
|
|
m.DeclaringType == t);
|
|
return enumValueMemberInfo;
|
|
}
|
|
|
|
|
|
public static Color4 ToColor4(this Color col)
|
|
{
|
|
return new(col.R, col.G, col.B, col.A);
|
|
}
|
|
|
|
public static Color4[] ToColor4Array(this Color[] col)
|
|
{
|
|
List<Color4> cols = new();
|
|
foreach (Color c in col)
|
|
{
|
|
cols.Add(new(c.R, c.G, c.B, c.A));
|
|
}
|
|
return cols.ToArray();
|
|
}
|
|
|
|
public static string ToDB(this Color[] col)
|
|
{
|
|
StringBuilder sb = new();
|
|
foreach (Color c in col)
|
|
{
|
|
sb.Append(Convert.ToHexString(new byte[] { c.R, c.G, c.B, c.A }));
|
|
}
|
|
return sb.ToString();
|
|
}
|
|
public static string ToDB(this Color4[] col)
|
|
{
|
|
StringBuilder sb = new();
|
|
foreach (Color4 c in col)
|
|
{
|
|
sb.Append(Convert.ToHexString(new byte[] { (byte)(c.R * byte.MaxValue), (byte)(c.G * byte.MaxValue), (byte)(c.B * byte.MaxValue), (byte)(c.A * byte.MaxValue) }));
|
|
}
|
|
return sb.ToString();
|
|
}
|
|
|
|
public static Color4 ToColor4(this Color? col)
|
|
{
|
|
return new(col!.Value.R, col.Value.G, col.Value.B, col.Value.A);
|
|
}
|
|
|
|
public static Color ToColor(this Color4 col)
|
|
{
|
|
return new((byte)(col.R*byte.MaxValue), (byte)(col.G*byte.MaxValue), (byte)(col.B*byte.MaxValue), (byte)(col.A*byte.MaxValue));
|
|
}
|
|
|
|
public static Texture GetAlphaCircle(this TextureManager tm)
|
|
{
|
|
return tm.GetTextureResource("Status.png");
|
|
}
|
|
|
|
public static Dictionary<long, Texture> UserTextureMap = new();
|
|
public static Dictionary<long, Texture> ProfileTextureMap = new();
|
|
public static readonly Dictionary<IGLFWGraphicsContext, Shader> GradientShader = new Dictionary<IGLFWGraphicsContext, Shader>();
|
|
|
|
public static ServerProfile? ServerProfile = null;
|
|
|
|
public static async Task<IRenderObject> MakeRct<TUser>(this ServerProfile Profile, TUser User, Vector2i Size) where TUser : SocketUser
|
|
{
|
|
Texture t = ms.TextureManager.GetTextureResource("Status.png");
|
|
if (Profile.PictureType == PictureType.none)
|
|
{
|
|
UserControl r = new(t);
|
|
r.Size = Size;
|
|
r.Shader = Rectangle.DefaultAlphaShader[ms.Context];
|
|
ColorType ct = await User.GetColorType();
|
|
Color[] c = await User.GetColors();
|
|
ColorType? cct = await Profile.GetColorType();
|
|
Color[]? cc = await Profile.GetColors();
|
|
if (cc is not null)
|
|
{
|
|
c = cc;
|
|
ct = cct!.Value;
|
|
}
|
|
r.BackgroundColor = new(25, 25, 25, 255);
|
|
if (ct == ColorType.Full)
|
|
{
|
|
Label l = new(DefaultFont)
|
|
{
|
|
Color = c[0].ToColor4()
|
|
};
|
|
l.Text = Profile.DisplayName[0].ToString();
|
|
Vector2i y = l.GetSizeOfChar(0),
|
|
yy = l.GetBearingOfChar(0);
|
|
l.Location = new((r.Size.X - l.Size.X)/2,
|
|
(int)(r.Size.Y - l.Font.PixelHeight + yy.Y - (r.Size.Y / 2) - (y.Y/2)),
|
|
0);
|
|
r.Controls.Add(l);
|
|
}
|
|
else
|
|
{
|
|
AdvancedGradientLabel l = new(DefaultFont)
|
|
{
|
|
Colors = c.ToColor4Array()
|
|
};
|
|
l.Text = Profile.DisplayName[0].ToString();
|
|
Vector2i y = l.GetSizeOfChar(0),
|
|
yy = l.GetBearingOfChar(0);
|
|
l.Location = new((r.Size.X - l.Size.X)/2,
|
|
(int)(r.Size.Y - l.Font.PixelHeight + yy.Y - (r.Size.Y / 2) - (y.Y/2)),
|
|
0);
|
|
r.Controls.Add(l);
|
|
}
|
|
return r;
|
|
}
|
|
else
|
|
{
|
|
Rectangle r = new(t);
|
|
r.Size = Size;
|
|
r.Shader = Rectangle.DefaultAlphaTextureShader[ms.Context];
|
|
r.Textures.Add(await Profile.GetIcon());
|
|
return r;
|
|
}
|
|
}
|
|
|
|
public static async Task<IRenderObject> MakeRct(this PublicServer Server, Vector2i Size)
|
|
{
|
|
Texture t = ms.TextureManager.GetTextureResource("rc.png");
|
|
if (Server.PictureType == PictureType.none)
|
|
{
|
|
UserControl r = new(t);
|
|
r.Size = Size;
|
|
r.Shader = Rectangle.DefaultAlphaShader[ms.Context];
|
|
r.BackgroundColor = new(25, 25, 25, 255);
|
|
Label l = new(DefaultFont)
|
|
{
|
|
Color = new(255,255,255,255),
|
|
IgnoreHover = true,
|
|
Text = Server.Name[0].ToString()
|
|
};
|
|
Vector2i y = l.GetSizeOfChar(0),
|
|
yy = l.GetBearingOfChar(0);
|
|
l.Location = new((r.Size.X - l.Size.X)/2,
|
|
(int)(r.Size.Y - l.Font.PixelHeight + yy.Y - (r.Size.Y / 2) - (y.Y/2)),
|
|
0);
|
|
r.Controls.Add(l);
|
|
return r;
|
|
}
|
|
else
|
|
{
|
|
Rectangle r = new(t);
|
|
r.Size = Size;
|
|
r.Shader = Rectangle.DefaultAlphaTextureShader[ms.Context];
|
|
r.Textures.Add(await Server.GetIcon());
|
|
return r;
|
|
}
|
|
}
|
|
|
|
private static async Task<Texture> GetIcon<TServer>(this TServer Server) where TServer : Server
|
|
{
|
|
Stream UserStream = await Server.GetAvatar(CancellationToken.None);
|
|
Texture t = Globals.ms.TextureManager.AddTexture(UserStream);
|
|
UserStream.Dispose();
|
|
t.Unit = TextureUnit.Texture1;
|
|
return t;
|
|
}
|
|
|
|
private static async Task<Texture> GetIcon(this ServerProfile User)
|
|
{
|
|
if (ProfileTextureMap.TryGetValue(User.ID, out Texture? t)) return t;
|
|
Stream UserStream = await User.GetAvatar(CancellationToken.None);
|
|
t = Globals.ms.TextureManager.AddTexture(UserStream);
|
|
ProfileTextureMap.Add(User.ID, t);
|
|
UserStream.Dispose();
|
|
t.Unit = TextureUnit.Texture1;
|
|
return t;
|
|
}
|
|
|
|
public static Settings Settings { get; set; }
|
|
|
|
public static FontFamily DefaultFontFamly { get; set; }
|
|
public static FontInteraction DefaultFont { get; set; }
|
|
public static FontInteraction ServerRoleFont { get; set; }
|
|
public static FontInteraction TopTimeFont { get; set; }
|
|
public static FontInteraction MessageFont { get; set; }
|
|
public static FontInteraction SmallTimeFont { get; set; }
|
|
|
|
public static PublicServer? GetCurentPublicServer()
|
|
{
|
|
if (Luski.LoadedServers.Count > 0)
|
|
return Luski.LoadedServers[0];
|
|
else
|
|
return null;
|
|
}
|
|
|
|
public static UpdaterSettings UpdaterSettings { get; set; }
|
|
|
|
public static Texture LuskiTexture;
|
|
|
|
public static TResult GetSettings<TResult>(string path, JsonTypeInfo<TResult> TypeInfo) where TResult : new()
|
|
{
|
|
TResult? @out;
|
|
if (!File.Exists(path))
|
|
{
|
|
@out = new();
|
|
File.WriteAllText(path, JsonSerializer.Serialize(@out, TypeInfo));
|
|
}
|
|
|
|
try
|
|
{
|
|
@out = JsonSerializer.Deserialize(File.ReadAllText(path), TypeInfo);
|
|
if (@out is null)
|
|
{
|
|
@out = new();
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
@out = new();
|
|
}
|
|
File.WriteAllText(path, JsonSerializer.Serialize(@out, TypeInfo));
|
|
return @out;
|
|
}
|
|
|
|
public static TResult GetSettings<TResult>(Stream data, JsonTypeInfo<TResult> TypeInfo) where TResult : new()
|
|
{
|
|
TResult? @out;
|
|
|
|
try
|
|
{
|
|
@out = JsonSerializer.Deserialize(data, TypeInfo);
|
|
if (@out is null)
|
|
{
|
|
@out = new();
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
@out = new();
|
|
}
|
|
return @out;
|
|
}
|
|
|
|
public static void SaveSettings<TResult>(this TResult json, string path, JsonTypeInfo<TResult> TypeInfo) where TResult : new()
|
|
{
|
|
File.WriteAllText(path, JsonSerializer.Serialize(json, TypeInfo));
|
|
}
|
|
|
|
public static string JT
|
|
{
|
|
get
|
|
{
|
|
string tmp = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "JacobTech");
|
|
if (OperatingSystem.IsLinux())
|
|
{
|
|
tmp = Path.Combine(Environment.GetEnvironmentVariable("HOME")!, ".config/");
|
|
tmp += "JacobTech";
|
|
}
|
|
|
|
if (!Directory.Exists(tmp)) Directory.CreateDirectory(tmp);
|
|
if (!Directory.Exists(Path.Combine(tmp, "Luski"))) Directory.CreateDirectory(Path.Combine(tmp, "Luski"));
|
|
return tmp;
|
|
}
|
|
}
|
|
public static WindowIcon Icon { get; set; }
|
|
|
|
public static string LuskiPath
|
|
{
|
|
get
|
|
{
|
|
return Path.Combine(JT, "Luski");
|
|
}
|
|
}
|
|
|
|
public static bool Empty(string? str)
|
|
{
|
|
return (string.IsNullOrEmpty(str) || string.IsNullOrWhiteSpace(str));
|
|
}
|
|
}
|
|
#pragma warning restore CS8618 |