Skip to content

Commit

Permalink
Move settings to Avalonia project
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-lerch committed Oct 14, 2024
1 parent 333a406 commit 451db25
Show file tree
Hide file tree
Showing 18 changed files with 295 additions and 71 deletions.
4 changes: 2 additions & 2 deletions src/Vocup.WinForms/Forms/PracticeDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public PracticeDialog(VocabularyBook book, List<VocabularyWordPractice> practice

private void Form_Load(object sender, EventArgs e)
{
Size size = Program.Settings.PracticeDialogSize;
Size size = Program.Settings.PracticeDialogSize.ToSystemDrawingSize();
if (size.Width >= MinimumSize.Width && size.Height >= MinimumSize.Height)
{
Size = size;
Expand Down Expand Up @@ -418,7 +418,7 @@ private void TextBox_Enter(object sender, EventArgs e)

private void Form_FormClosing(object sender, FormClosingEventArgs e)
{
Program.Settings.PracticeDialogSize = Size;
Program.Settings.PracticeDialogSize = Size.ToAvaloniaSize();
}

private void Form_FormClosed(object sender, FormClosedEventArgs e)
Expand Down
16 changes: 10 additions & 6 deletions src/Vocup.WinForms/MainForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,9 @@ private void StoreSettings()

Rectangle logicalBounds = new(bounds.Location, bounds.Size.Multiply(96f / DeviceDpi).Round());

Program.Settings.MainFormBounds = logicalBounds;
Program.Settings.MainFormBounds = logicalBounds.ToAvaloniaRect();

Program.Settings.MainFormWindowState = WindowState;
Program.Settings.MainFormWindowState = WindowState.ToAvaloniaWindowState();

Program.Settings.MainFormSplitterDistance = SplitContainer.SplitterDistance;
}
Expand All @@ -162,11 +162,13 @@ protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
/// </summary>
private void RestoreSettings()
{
Rectangle mainFormBounds = Program.Settings.MainFormBounds.ToSystemDrawingRect();

// check if stored form bound is visible on any screen
bool isVisible = false;
foreach (Screen screen in Screen.AllScreens)
{
if (screen.Bounds.IntersectsWith(Program.Settings.MainFormBounds))
if (screen.Bounds.IntersectsWith(mainFormBounds))
{
isVisible = true;
break;
Expand All @@ -181,12 +183,14 @@ private void RestoreSettings()
if (isVisible && Program.Settings.MainFormBounds != default)
{
// visible => restore the bounds of the main form
Bounds = Program.Settings.MainFormBounds;
Bounds = mainFormBounds;

FormWindowState windowState = Program.Settings.MainFormWindowState.ToFormWindowState();

// Do not restore the window state when the form was minimzed
if (Program.Settings.MainFormWindowState != FormWindowState.Minimized)
if (windowState != FormWindowState.Minimized)
{
WindowState = Program.Settings.MainFormWindowState;
WindowState = windowState;
}
}
else
Expand Down
2 changes: 1 addition & 1 deletion src/Vocup.WinForms/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ private static void SwitchFocus()

public static IAsyncDisposable InitializeServices()
{
var loader = new VocupSettingsLoader();
var loader = new WindowsSettingsLoader();
var settings = loader.LoadAsync().AsTask().GetAwaiter().GetResult();
Settings = settings.Value;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
using System.Text.Json;
using System.Threading.Tasks;
using Vocup.Settings.Core;
using Vocup.Util;
using OldSettings = Vocup.Properties.Settings;

namespace Vocup.Settings;

public class VocupSettingsLoader : SettingsLoaderBase<VocupSettings>
public class WindowsSettingsLoader : SettingsLoaderBase<VocupSettings>
{
public VocupSettingsLoader()
public WindowsSettingsLoader()
: base(
new DirectoryInfo(
Path.Combine(
Expand Down Expand Up @@ -70,11 +71,11 @@ private async ValueTask<bool> MigrateJsonSettings1(SettingsContext<VocupSettings
settings.Value.EvaluateToleratePunctuationMark = oldSettings.EvaluateToleratePunctuationMark;
settings.Value.EvaluateTolerateSpecialChar = oldSettings.EvaluateTolerateSpecialChar;
settings.Value.EvaluateTolerateArticle = oldSettings.EvaluateTolerateArticle;
settings.Value.MainFormBounds = oldSettings.MainFormBounds;
settings.Value.MainFormWindowState = oldSettings.MainFormWindowState;
settings.Value.MainFormBounds = oldSettings.MainFormBounds.ToAvaloniaRect();
settings.Value.MainFormWindowState = oldSettings.MainFormWindowState.ToAvaloniaWindowState();
settings.Value.MainFormSplitterDistance = oldSettings.MainFormSplitterDistance;
settings.Value.SpecialCharTab = oldSettings.SpecialCharTab;
settings.Value.PracticeDialogSize = oldSettings.PracticeDialogSize;
settings.Value.PracticeDialogSize = oldSettings.PracticeDialogSize.ToAvaloniaSize();
settings.Value.Version = oldSettings.Version;
return true;
}
Expand Down Expand Up @@ -134,8 +135,8 @@ private static void MigrateFromAppConfig(SettingsContext<VocupSettings> settings
settings.Value.EvaluateToleratePunctuationMark = OldSettings.Default.EvaluateToleratePunctuationMark;
settings.Value.EvaluateTolerateSpecialChar = OldSettings.Default.EvaluateTolerateSpecialChar;
settings.Value.EvaluateTolerateArticle = OldSettings.Default.EvaluateTolerateArticle;
settings.Value.MainFormBounds = OldSettings.Default.MainFormBounds;
settings.Value.MainFormWindowState = OldSettings.Default.MainFormWindowState;
settings.Value.MainFormBounds = OldSettings.Default.MainFormBounds.ToAvaloniaRect();
settings.Value.MainFormWindowState = OldSettings.Default.MainFormWindowState.ToAvaloniaWindowState();
settings.Value.MainFormSplitterDistance = OldSettings.Default.MainFormSplitterDistance;
settings.Value.SpecialCharTab = OldSettings.Default.SpecialCharTab;
if (Version.TryParse(OldSettings.Default.Version, out Version? version)) settings.Value.Version = version;
Expand Down
47 changes: 47 additions & 0 deletions src/Vocup.WinForms/Util/Extensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace Vocup.Util;

Expand Down Expand Up @@ -81,3 +82,49 @@ public static int NextIndexOf<T>(this IList<T> collection, Predicate<T> predicat
return -1;
}
}

public static class AvaloniaWinFormsExtensions
{
public static Avalonia.Size ToAvaloniaSize(this System.Drawing.Size size)
{
return new(size.Width, size.Height);
}

public static System.Drawing.Size ToSystemDrawingSize(this Avalonia.Size size)
{
return new((int)size.Width, (int)size.Height);
}

public static Avalonia.Rect ToAvaloniaRect(this System.Drawing.Rectangle rect)
{
return new(rect.X, rect.Y, rect.Width, rect.Height);
}

public static System.Drawing.Rectangle ToSystemDrawingRect(this Avalonia.Rect rect)
{
return new((int)rect.X, (int)rect.Y, (int)rect.Width, (int)rect.Height);
}

public static Avalonia.Controls.WindowState ToAvaloniaWindowState(this FormWindowState state)
{
return state switch
{
FormWindowState.Normal => Avalonia.Controls.WindowState.Normal,
FormWindowState.Minimized => Avalonia.Controls.WindowState.Minimized,
FormWindowState.Maximized => Avalonia.Controls.WindowState.Maximized,
_ => throw new ArgumentOutOfRangeException(nameof(state), state, null)
};
}

public static FormWindowState ToFormWindowState(this Avalonia.Controls.WindowState state)
{
return state switch
{
Avalonia.Controls.WindowState.Normal => FormWindowState.Normal,
Avalonia.Controls.WindowState.Minimized => FormWindowState.Minimized,
Avalonia.Controls.WindowState.Maximized => FormWindowState.Maximized,
Avalonia.Controls.WindowState.FullScreen => FormWindowState.Maximized,
_ => throw new ArgumentOutOfRangeException(nameof(state), state, null)
};
}
}
5 changes: 3 additions & 2 deletions src/Vocup.WinForms/Util/RecentFilesService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.IO;
using System.Linq;
using Vocup.Settings;
using Vocup.Settings.Model;

namespace Vocup.Util;

Expand All @@ -29,13 +30,13 @@ public void InteractedWith(string fileName)
}
}

public bool TryGetMostRecent([NotNullWhen(true)] out VocupSettings.RecentFile? recentFile)
public bool TryGetMostRecent([NotNullWhen(true)] out RecentFile? recentFile)
{
recentFile = settings.RecentFiles.OrderByDescending(x => x.LastAccess).Where(Exists).FirstOrDefault();
return recentFile != null;
}

private static bool Exists(VocupSettings.RecentFile recentFile)
private static bool Exists(RecentFile recentFile)
{
bool exists = File.Exists(recentFile.FileName);
if (exists)
Expand Down
1 change: 0 additions & 1 deletion src/Vocup.WinForms/Vocup.WinForms.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
<PackageReference Include="Avalonia.Desktop" Version="$(AvaloniaVersion)" />
<PackageReference Include="Avalonia.Win32.Interoperability" Version="$(AvaloniaVersion)" />
<PackageReference Include="CsvHelper" Version="31.0.3" />
<PackageReference Include="LostTech.App.Settings" Version="0.5.0" />
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.49-beta">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ public class JsonSerializerFactory : ISerializerFactory, IDeserializerFactory
public JsonSerializerFactory()
{
options = new JsonSerializerOptions { WriteIndented = true };
options.Converters.Add(new RectJsonConverter());
options.Converters.Add(new SizeJsonConverter());
}

public Func<Stream, T, Task> MakeSerializer<T>() => Serialize;
Expand Down
75 changes: 75 additions & 0 deletions src/Vocup/Settings/Core/RectJsonConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using Avalonia;
using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Vocup.Settings.Core;

public class RectJsonConverter : JsonConverter<Rect>
{
public override Rect Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartObject)
throw new JsonException();

double x = 0, y = 0, width = 0, height = 0;

while (reader.Read())
{
if (reader.TokenType == JsonTokenType.PropertyName)
{
var propertyName = reader.GetString();

if (propertyName == "X")
{
reader.Read();
x = reader.GetDouble();
}
else if (propertyName == "Y")
{
reader.Read();
y = reader.GetDouble();
}
else if (propertyName == "Width")
{
reader.Read();
width = reader.GetDouble();
}
else if (propertyName == "Height")
{
reader.Read();
height = reader.GetDouble();
}
else
{
reader.Skip();
}
}
else if (reader.TokenType == JsonTokenType.EndObject)
{
return new Rect(x, y, width, height);
}
}

throw new JsonException();
}

public override void Write(Utf8JsonWriter writer, Rect value, JsonSerializerOptions options)
{
writer.WriteStartObject();

writer.WritePropertyName("X");
writer.WriteNumberValue(value.X);

writer.WritePropertyName("Y");
writer.WriteNumberValue(value.Y);

writer.WritePropertyName("Width");
writer.WriteNumberValue(value.Width);

writer.WritePropertyName("Height");
writer.WriteNumberValue(value.Height);

writer.WriteEndObject();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ protected T RaiseAndSetIfChanged<T>(
T newValue,
[CallerMemberName] string? propertyName = null)
{
if (propertyName is null)
{
throw new ArgumentNullException(nameof(propertyName));
}
ArgumentNullException.ThrowIfNull(propertyName, nameof(propertyName));

if (EqualityComparer<T>.Default.Equals(backingField, newValue))
{
Expand Down
File renamed without changes.
56 changes: 56 additions & 0 deletions src/Vocup/Settings/Core/SizeJsonConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using Avalonia;
using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Vocup.Settings.Core;

public class SizeJsonConverter : JsonConverter<Size>
{
public override Size Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartObject)
throw new JsonException();

double width = 0, height = 0;

while (reader.Read())
{
if (reader.TokenType == JsonTokenType.PropertyName)
{
var propertyName = reader.GetString();

if (propertyName == "Width")
{
reader.Read();
width = reader.GetDouble();
}
else if (propertyName == "Height")
{
reader.Read();
height = reader.GetDouble();
}
else
{
reader.Skip();
}
}
else if (reader.TokenType == JsonTokenType.EndObject)
{
return new Size(width, height);
}
}

throw new JsonException();
}

public override void Write(Utf8JsonWriter writer, Size value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WritePropertyName("Width");
writer.WriteNumberValue(value.Width);
writer.WritePropertyName("Height");
writer.WriteNumberValue(value.Height);
writer.WriteEndObject();
}
}
33 changes: 33 additions & 0 deletions src/Vocup/Settings/Model/RecentFile.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;
using Vocup.Settings.Core;

namespace Vocup.Settings.Model;

public class RecentFile : SettingsBase
{
public RecentFile(string fileName, DateTime lastAccess, DateTime lastAvailable)
{
FileName = fileName;
LastAccess = lastAccess;
LastAvalailable = lastAvailable;
}

public string FileName { get; }

private DateTime _lastAccess;
public DateTime LastAccess
{
get => _lastAccess;
set => RaiseAndSetIfChanged(ref _lastAccess, value);
}

private DateTime _lastAvailable;
/// <summary>
/// Gets or sets the last time the file was available on the file system.
/// </summary>
public DateTime LastAvalailable
{
get => _lastAvailable;
set => RaiseAndSetIfChanged(ref _lastAvailable, value);
}
}
Loading

0 comments on commit 451db25

Please sign in to comment.