Skip to content

Commit

Permalink
Changes for Avalonia UI version 11 and other package updates (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
Len42 authored Nov 13, 2023
1 parent 06724d8 commit 6976e85
Show file tree
Hide file tree
Showing 20 changed files with 256 additions and 105 deletions.
5 changes: 3 additions & 2 deletions software/DexyPatch/DexyPatch/App.axaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Dexy.DexyPatch"
x:Class="Dexy.DexyPatch.App">
x:Class="Dexy.DexyPatch.App"
RequestedThemeVariant="Dark">
<Application.DataTemplates>
<local:ViewLocator/>
</Application.DataTemplates>
<Application.Styles>
<FluentTheme Mode="Dark"/>
<FluentTheme/>
<StyleInclude Source="avares://DexyPatch/Icons.axaml" />
</Application.Styles>
</Application>
4 changes: 2 additions & 2 deletions software/DexyPatch/DexyPatch/Controls/ParamSlider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace Dexy.DexyPatch.Controls
/// <summary>
/// Just a subclass of Slider with different default settings
/// </summary>
public class ParamSlider : Slider, IStyleable
public class ParamSlider : Slider
{
public ParamSlider()
{
Expand All @@ -20,6 +20,6 @@ public ParamSlider()
HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Center;
}

Type IStyleable.StyleKey => typeof(Slider);
protected override Type StyleKeyOverride => typeof(Slider);
}
}
14 changes: 7 additions & 7 deletions software/DexyPatch/DexyPatch/DexyPatch.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Avalonia" Version="0.10.19" />
<PackageReference Include="Avalonia.Desktop" Version="0.10.19" />
<PackageReference Include="Avalonia" Version="11.0.5" />
<PackageReference Include="Avalonia.Desktop" Version="11.0.5" />
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="0.10.19" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.1.0" />
<PackageReference Include="MessageBox.Avalonia" Version="2.1.0" />
<PackageReference Include="Microsoft.Windows.Compatibility" Version="7.0.3" />
<PackageReference Include="XamlNameReferenceGenerator" Version="1.6.1" />
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.5" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.5" />
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
<PackageReference Include="MessageBox.Avalonia" Version="3.1.5.1" />
<PackageReference Include="Microsoft.Windows.Compatibility" Version="7.0.5" />
</ItemGroup>
</Project>
1 change: 1 addition & 0 deletions software/DexyPatch/DexyPatch/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public static void Main(string[] args)
BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
} catch(Exception ex) {
// last-ditch exception handler - log to file
ErrorLog.TraceError(ex);
ErrorLog.WriteError(ex);
throw;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,24 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using MessageBox.Avalonia;
using MessageBox.Avalonia.DTO;
using MessageBox.Avalonia.Enums;
using MessageBox.Avalonia.Models;
using MsBox.Avalonia;
using MsBox.Avalonia.Dto;
using MsBox.Avalonia.Enums;
using MsBox.Avalonia.Models;
using Dexy.DexyPatch.Utils;
using Avalonia.Platform.Storage;

namespace Dexy.DexyPatch.Services
{
/// <summary>
/// Service for displaying various message boxes and dialogs
/// </summary>
/// <remarks>
/// Uses the MessageBox.Avalonia package
/// Uses the MsBox.Avalonia package
/// </remarks>
public class MessageBoxService : IMessageBoxService
public class DialogService : IDialogService
{
public MessageBoxService() { }
public DialogService() { }

public void Terminate() { }

Expand All @@ -33,7 +34,7 @@ public async Task ShowErrorMessage(string message, Exception? ex)
if (ex != null) {
stError = $"{ex.Message} ({ex.GetType().Name})";
}
var messageBox = MessageBoxManager.GetMessageBoxStandardWindow(
var messageBox = MessageBoxManager.GetMessageBoxStandard(
new MessageBoxStandardParams {
ContentTitle = $"ERROR - {Application.Current?.Name}",
ContentHeader = message,
Expand All @@ -48,12 +49,12 @@ public async Task ShowErrorMessage(string message, Exception? ex)
if (MainWindow == null) {
throw new InvalidOperationException("No parent window for dialog");
}
await messageBox.ShowDialog(MainWindow);
await messageBox.ShowAsPopupAsync(MainWindow);
}

public async Task<ButtonResult> AskYesNo(string header, string? message)
{
var messageBox = MessageBoxManager.GetMessageBoxStandardWindow(
var messageBox = MessageBoxManager.GetMessageBoxStandard(
new MessageBoxStandardParams {
ContentTitle = Application.Current?.Name,
ContentHeader = header,
Expand All @@ -68,15 +69,15 @@ public async Task<ButtonResult> AskYesNo(string header, string? message)
if (MainWindow == null) {
throw new InvalidOperationException("No parent window for dialog");
}
return await messageBox.ShowDialog(MainWindow);
return await messageBox.ShowAsPopupAsync(MainWindow);
}

public async Task<ButtonResult> AskSaveChanges(string? name)
{
const string btnYes = "Save";
const string btnNo = "Discard Changes";
const string btnCancel = "Cancel";
var messageBox = MessageBoxManager.GetMessageBoxCustomWindow(
var messageBox = MessageBoxManager.GetMessageBoxCustom(
new MessageBoxCustomParams {
ContentTitle = Application.Current?.Name,
ContentHeader = "Save changes?",
Expand All @@ -95,7 +96,7 @@ public async Task<ButtonResult> AskSaveChanges(string? name)
if (MainWindow == null) {
throw new InvalidOperationException("No parent window for dialog");
}
string stResult = await messageBox.ShowDialog(MainWindow);
string stResult = await messageBox.ShowAsPopupAsync(MainWindow);
switch (stResult) {
case btnYes:
return ButtonResult.Yes;
Expand All @@ -114,7 +115,7 @@ public async Task<ButtonResult> AskDownloadFirmware(string pathname)
const string btnNo = "Select File";
const string btnCancel = "Cancel";
const int maxPathnameChars = 40;
var messageBox = MessageBoxManager.GetMessageBoxCustomWindow(
var messageBox = MessageBoxManager.GetMessageBoxCustom(
new MessageBoxCustomParams {
ContentTitle = Application.Current?.Name,
ContentHeader = "Download firmware file to Dexy module?",
Expand All @@ -133,7 +134,7 @@ public async Task<ButtonResult> AskDownloadFirmware(string pathname)
if (MainWindow == null) {
throw new InvalidOperationException("No parent window for dialog");
}
string stResult = await messageBox.ShowDialog(MainWindow);
string stResult = await messageBox.ShowAsPopupAsync(MainWindow);
switch (stResult) {
case btnYes:
return ButtonResult.Yes;
Expand All @@ -148,33 +149,33 @@ public async Task<ButtonResult> AskDownloadFirmware(string pathname)

public async Task<string?> OpenFileDialog(string? initPathname, string fileTypeName, string fileTypeExt)
{
var dialogBox = new OpenFileDialog() {
var storageProvider = GetStorageProvider();
var startLocation = await GetFolderLocationFromPath(initPathname);
var options = new FilePickerOpenOptions() {
Title = "Load File",
Directory = Path.GetDirectoryName(initPathname),
InitialFileName = Path.GetFileName(initPathname),
SuggestedStartLocation = startLocation,
AllowMultiple = false,
Filters = GetFileFilterList(fileTypeName, fileTypeExt)
FileTypeFilter = GetFileFilterList(fileTypeName, fileTypeExt)
};
var result = await dialogBox.ShowAsync(MainWindow!);
if (result == null) {
return null;
} else if (result.Length == 0) {
return null;
} else {
return result[0];
}
IReadOnlyList<IStorageFile> files = await storageProvider.OpenFilePickerAsync(options);
return (files.Count > 0) ? GetPathFromStorageFile(files[0]) : null;
}

public async Task<string?> SaveFileDialog(string? initPathname, string fileTypeName, string fileTypeExt)
{
var dialogBox = new SaveFileDialog() {
var storageProvider = GetStorageProvider();
var startLocation = await GetFolderLocationFromPath(initPathname);
var options = new FilePickerSaveOptions()
{
Title = "Save File",
Directory = Path.GetDirectoryName(initPathname),
InitialFileName = "New File", // not Path.GetFileName(initPathname),
DefaultExtension ="dexy",
Filters = GetFileFilterList(fileTypeName, fileTypeExt)
};
return await dialogBox.ShowAsync(MainWindow!);
SuggestedStartLocation = startLocation,
SuggestedFileName="New File",
DefaultExtension = fileTypeExt,
ShowOverwritePrompt = true,
FileTypeChoices = GetFileFilterList(fileTypeName, fileTypeExt)
};
IStorageFile? file = await storageProvider.SaveFilePickerAsync(options);
return GetPathFromStorageFile(file);
}

/// <summary>
Expand All @@ -183,12 +184,14 @@ public async Task<ButtonResult> AskDownloadFirmware(string pathname)
/// <param name="fileTypeName"></param>
/// <param name="fileTypeExt"></param>
/// <returns></returns>
private static List<FileDialogFilter> GetFileFilterList(string fileTypeName, string fileTypeExt)
private static List<FilePickerFileType> GetFileFilterList(string fileTypeName, string fileTypeExt)
{
return new() {
new () { Name = fileTypeName, Extensions = new() { fileTypeExt } },
new () { Name = "All files", Extensions = new() { "*" } }
FilePickerFileType fileType = new(fileTypeName) {
Patterns = new[] { Path.ChangeExtension("*", fileTypeExt) },
MimeTypes = new[] {"application/octet-stream"}
};
var fileTypes = new List<FilePickerFileType>{ fileType, FilePickerFileTypes.All };
return fileTypes;
}

/// <summary>
Expand All @@ -206,5 +209,45 @@ private static Window? MainWindow
}
}
}

/// <summary>
/// Get the Avalonia storage provider
/// </summary>
/// <returns></returns>
/// <exception cref="Exception"></exception>
private static IStorageProvider GetStorageProvider()
{
var storageProvider = MainWindow?.StorageProvider;
if(storageProvider is null) {
throw new Exception("Cannot get IStorageProvider");
}
return storageProvider;
}

/// <summary>
/// Get the folder containing the given file
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
private static Task<IStorageFolder?> GetFolderLocationFromPath(string? path)
{
if (path is not null) {
var stDir = Path.GetDirectoryName(path);
if (stDir is not null) {
return GetStorageProvider().TryGetFolderFromPathAsync(stDir);
}
}
return Task.FromResult<IStorageFolder?>(null);
}

/// <summary>
/// Get the file pathname corresponding to the given IStorageFile
/// </summary>
/// <param name="file"></param>
/// <returns></returns>
private static string? GetPathFromStorageFile(IStorageFile? file)
{
return (file is null) ? null : file.Path.LocalPath;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MessageBox.Avalonia.Enums;
using MsBox.Avalonia.Enums;

namespace Dexy.DexyPatch.Services
{
/// <summary>
/// Interface for displaying various message boxes and dialogs
/// </summary>
interface IMessageBoxService : IService
interface IDialogService : IService
{
/// <summary>
/// Display an error message box
Expand Down
2 changes: 1 addition & 1 deletion software/DexyPatch/DexyPatch/Services/ServiceRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public static void InitializeAll()
services.Add(Service<ISettingsManager>.Initialize<SettingsManager>());
services.Add(Service<IDexyDevice>.Initialize<DexyDevice>());
services.Add(Service<IDataManager>.Initialize<DataManager>());
services.Add(Service<IMessageBoxService>.Initialize<MessageBoxService>());
services.Add(Service<IDialogService>.Initialize<DialogService>());
services.Add(Service<ILiveUpdater>.Initialize<LiveUpdater>());
}

Expand Down
55 changes: 55 additions & 0 deletions software/DexyPatch/DexyPatch/Services/StubDialogService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
using Dexy.DexyPatch.Utils;
using MsBox.Avalonia.Enums;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Dexy.DexyPatch.Services
{
/// <summary>
/// Stub implementation of IMessageBoxService
/// </summary>
public class StubDialogService : IDialogService
{
public void Terminate() { }

public Task ShowErrorMessage(string message, Exception? ex)
{
ErrorLog.TraceError(message);
if (ex != null) {
ErrorLog.TraceError(ex);
}
return Task.CompletedTask;
}

public Task<ButtonResult> AskYesNo(string header, string? message)
{
// TODO: Need a way to return either yes or no based on a default param or something?
return Task.FromResult<ButtonResult>(ButtonResult.No);
}

public Task<ButtonResult> AskSaveChanges(string? name)
{
// TODO: Need a way to return either yes or no based on a default param or something?
return Task.FromResult<ButtonResult>(ButtonResult.No);
}

public Task<ButtonResult> AskDownloadFirmware(string pathname)
{
// TODO: Need a way to return either yes or no based on a default param or something?
return Task.FromResult<ButtonResult>(ButtonResult.No);
}

public Task<string?> OpenFileDialog(string? initPathname, string fileTypeName, string fileTypeExt)
{
return Task.FromResult<string?>(null);
}

public Task<string?> SaveFileDialog(string? initPathname, string fileTypeName, string fileTypeExt)
{
return Task.FromResult<string?>(null);
}
}
}
Loading

0 comments on commit 6976e85

Please sign in to comment.