1
0
Fork 0
mirror of https://github.com/oMaN-Rod/nxDumpFuse.git synced 2024-11-22 18:26:40 +00:00

Clean up code

This commit is contained in:
Omar 2021-10-22 18:45:35 -04:00
parent 846ac96c72
commit e48947c499
15 changed files with 194 additions and 189 deletions

View file

@ -0,0 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/UserDictionary/Words/=Avalonia/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>

View file

@ -3,12 +3,12 @@
xmlns:local="using:nxDumpFuse" xmlns:local="using:nxDumpFuse"
x:Class="nxDumpFuse.App"> x:Class="nxDumpFuse.App">
<Application.DataTemplates> <Application.DataTemplates>
<local:ViewLocator/> <local:ViewLocator />
</Application.DataTemplates> </Application.DataTemplates>
<Application.Styles> <Application.Styles>
<FluentTheme Mode="Dark" /> <FluentTheme Mode="Dark" />
<StyleInclude Source="/Styles/SideBar.axaml" /> <StyleInclude Source="/Styles/SideBar.axaml" />
<StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml"/> <StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml" />
</Application.Styles> </Application.Styles>
</Application> </Application>

View file

@ -1,6 +1,5 @@
using nxDumpFuse.Extensions; using nxDumpFuse.Extensions;
using nxDumpFuse.Interfaces; using nxDumpFuse.Interfaces;
using nxDumpFuse.Model;
using nxDumpFuse.Services; using nxDumpFuse.Services;
using Splat; using Splat;

View file

@ -1,6 +1,5 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia.Controls; using Avalonia.Controls;
using nxDumpFuse.ViewModels;
namespace nxDumpFuse.Interfaces namespace nxDumpFuse.Interfaces
{ {

View file

@ -0,0 +1,8 @@
namespace nxDumpFuse.Model.Enums
{
public enum FuseSimpleLogType
{
Error,
Information
}
}

View file

@ -1,11 +1,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using nxDumpFuse.Events; using nxDumpFuse.Events;
using nxDumpFuse.Model.Enums;
namespace nxDumpFuse.Model namespace nxDumpFuse.Model
{ {
@ -26,7 +26,6 @@ namespace nxDumpFuse.Model
} }
public event EventHandlers.FuseUpdateEventHandler? FuseUpdateEvent; public event EventHandlers.FuseUpdateEventHandler? FuseUpdateEvent;
public event EventHandlers.FuseSimpleLogEventHandler? FuseSimpleLogEvent; public event EventHandlers.FuseSimpleLogEventHandler? FuseSimpleLogEvent;
protected virtual void OnFuseUpdate(FuseUpdateInfo fuseUpdateInfo) protected virtual void OnFuseUpdate(FuseUpdateInfo fuseUpdateInfo)
@ -34,6 +33,17 @@ namespace nxDumpFuse.Model
FuseUpdateEvent?.Invoke(fuseUpdateInfo); FuseUpdateEvent?.Invoke(fuseUpdateInfo);
} }
private void Update(int part, int parts, double progress, double progressPart)
{
OnFuseUpdate(new FuseUpdateInfo
{
Part = part,
Parts = parts,
Progress = progress,
ProgressPart = progressPart
});
}
protected virtual void OnFuseSimpleLogEvent(FuseSimpleLog log) protected virtual void OnFuseSimpleLogEvent(FuseSimpleLog log)
{ {
FuseSimpleLogEvent?.Invoke(log); FuseSimpleLogEvent?.Invoke(log);
@ -51,92 +61,98 @@ namespace nxDumpFuse.Model
Log(FuseSimpleLogType.Error, "Input File cannot be empty"); Log(FuseSimpleLogType.Error, "Input File cannot be empty");
return; return;
} }
if (string.IsNullOrEmpty(_outputDir)) if (string.IsNullOrEmpty(_outputDir))
{ {
Log(FuseSimpleLogType.Error, "Output Directory cannot be empty"); Log(FuseSimpleLogType.Error, "Output Directory cannot be empty");
return; return;
} }
Log(FuseSimpleLogType.Information, "Fuse Started");
GetOutputFilePath(_inputFilePath, _outputDir); GetOutputFilePath();
if (string.IsNullOrEmpty(_outputFilePath)) if (string.IsNullOrEmpty(_outputFilePath))
{ {
Log(FuseSimpleLogType.Error, "Output path was null"); Log(FuseSimpleLogType.Error, "Output path was null");
return; return;
} }
var inputFiles = GetInputFiles(); var inputFiles = GetInputFiles();
if (inputFiles.Length == 0) if (inputFiles.Length == 0)
{ {
Log(FuseSimpleLogType.Error, "No input files found"); Log(FuseSimpleLogType.Error, "No input files found");
return; return;
} }
FuseFiles(inputFiles, _outputFilePath); FuseFiles(inputFiles, _outputFilePath);
} }
private void GetOutputFilePath(string inputFilePath, string outputDir) private void GetOutputFilePath()
{ {
string? fileName = Path.GetFileName(inputFilePath); var fileName = Path.GetFileName(_inputFilePath);
if (Path.HasExtension(fileName)) if (Path.HasExtension(fileName))
{ {
string ext = Path.GetExtension(fileName).Replace(".", string.Empty); var ext = Path.GetExtension(fileName).Replace(".", string.Empty);
List<string> split = fileName.Split(".").ToList(); var split = fileName.Split(".").ToList();
if (int.TryParse(ext, out _) && split.Count >= 3 && split[^2] == XciExt) // .xci.00 if (int.TryParse(ext, out _) && split.Count >= 3 && split[^2] == XciExt) // .xci.00
{ {
_outputFilePath = Path.Join(outputDir, $"{string.Join("", split.Take(split.Count - 2))}.{XciExt}"); _outputFilePath = Path.Join(_outputDir, $"{string.Join("", split.Take(split.Count - 2))}.{XciExt}");
} }
else if (int.TryParse(ext, out _) && split.Count >= 3 && split[^2] == NspExt) // .nsp.00 else if (int.TryParse(ext, out _) && split.Count >= 3 && split[^2] == NspExt) // .nsp.00
_outputFilePath = Path.Join(outputDir, $"{string.Join("", split.Take(split.Count - 2))}.{NspExt}"); _outputFilePath = Path.Join(_outputDir, $"{string.Join("", split.Take(split.Count - 2))}.{NspExt}");
else switch (ext.Substring(0, 2)) else switch (ext[..2])
{ {
// .xc0 // .xc0
case "xc" when int.TryParse(ext.Substring(ext.Length - 1, 1), out _): case "xc" when int.TryParse(ext.Substring(ext.Length - 1, 1), out _):
_outputFilePath = Path.Join(outputDir, $"{Path.GetFileNameWithoutExtension(fileName)}.{XciExt}"); _outputFilePath = Path.Join(_outputDir, $"{Path.GetFileNameWithoutExtension(fileName)}.{XciExt}");
break; break;
// .ns0 // .ns0
case "ns" when int.TryParse(ext.Substring(ext.Length - 1, 1), out _): case "ns" when int.TryParse(ext.Substring(ext.Length - 1, 1), out _):
_outputFilePath = Path.Join(outputDir, $"{Path.GetFileNameWithoutExtension(fileName)}.{NspExt}"); _outputFilePath = Path.Join(_outputDir, $"{Path.GetFileNameWithoutExtension(fileName)}.{NspExt}");
break; break;
} }
} }
else // dir/00 else // dir/00
{ {
var inputDir = new FileInfo(inputFilePath).Directory?.Name; var inputDir = new FileInfo(_inputFilePath).Directory?.Name;
if (string.IsNullOrEmpty(inputDir)) if (string.IsNullOrEmpty(inputDir))
{ {
inputDir = Path.GetPathRoot(_inputFilePath); inputDir = Path.GetPathRoot(_inputFilePath);
_outputFilePath = $"{inputDir}.{NspExt}"; _outputFilePath = $"{inputDir}.{NspExt}";
return; return;
} }
var inputDirSplit = inputDir.Split("."); var inputDirSplit = inputDir.Split(".");
_outputFilePath = Path.Join(outputDir, inputDirSplit.Length == 1 _outputFilePath = Path.Join(_outputDir, inputDirSplit.Length == 1
? $"{inputDir}.{NspExt}" ? $"{inputDir}.{NspExt}"
: $"{string.Join("", (inputDirSplit).Take(inputDirSplit.Length - 1))}.{NspExt}"); : $"{string.Join("", (inputDirSplit).Take(inputDirSplit.Length - 1))}.{NspExt}");
} }
} }
private async void FuseFiles(string[] inputFiles, string outputFilePath) private async void FuseFiles(IReadOnlyCollection<string> inputFiles, string outputFilePath)
{ {
var buffer = new byte[1024 * 1024]; var buffer = new byte[1024 * 1024];
var count = 0; var count = 0;
long totalBytes = 0; long totalBytes = 0;
var totalFileLength = GetTotalFileSize(inputFiles); var totalFileLength = GetTotalFileSize(inputFiles);
Log(FuseSimpleLogType.Information, $"Fusing {inputFiles.Length} parts to {outputFilePath}:{totalFileLength / 1000}kB");
Log(FuseSimpleLogType.Information, $"Fusing {inputFiles.Count} parts to {outputFilePath} ({ToMb(totalFileLength)}MB)");
await using var outputStream = File.Create(outputFilePath); await using var outputStream = File.Create(outputFilePath);
foreach (var inputFilePath in inputFiles) foreach (var inputFilePath in inputFiles)
{ {
if (_cts.Token.IsCancellationRequested) return; if (_cts.Token.IsCancellationRequested) return;
++count;
await using var inputStream = File.OpenRead(inputFilePath);
Log(FuseSimpleLogType.Information, $"Fusing file part {count} --> {inputFilePath}/{inputStream.Length / 1000}kB");
var fileLength = inputStream.Length;
long currentBytes = 0; long currentBytes = 0;
int currentBlockSize; int currentBlockSize;
await using var inputStream = File.OpenRead(inputFilePath);
var fileLength = inputStream.Length;
Log(FuseSimpleLogType.Information, $"Fusing file part {++count}-> {inputFilePath} ({ToMb(fileLength)}MB)");
while ((currentBlockSize = inputStream.Read(buffer, 0, buffer.Length)) > 0) while ((currentBlockSize = inputStream.Read(buffer, 0, buffer.Length)) > 0)
{ {
if (_cts.Token.IsCancellationRequested) return; if (_cts.Token.IsCancellationRequested) return;
currentBytes += currentBlockSize; currentBytes += currentBlockSize;
totalBytes += currentBlockSize; totalBytes += currentBlockSize;
@ -149,20 +165,21 @@ namespace nxDumpFuse.Model
Log(FuseSimpleLogType.Error, e.Message); Log(FuseSimpleLogType.Error, e.Message);
} }
OnFuseUpdate(new FuseUpdateInfo var progress = totalBytes * 100.0 / totalFileLength;
{ var progressPart = currentBytes * 100.0 / fileLength;
Part = count, Update(count, inputFiles.Count, progress, progressPart);
Parts = inputFiles.Length,
ProgressPart = currentBytes * 100.0 / fileLength,
Progress = totalBytes * 100.0 / totalFileLength
});
} }
} }
Log(FuseSimpleLogType.Information, "Fuse Complete"); Log(FuseSimpleLogType.Information, "Fuse Complete");
} }
private static long GetTotalFileSize(string[] inputFiles) private static long ToMb(long bytes)
{
return bytes / 1000000;
}
private static long GetTotalFileSize(IEnumerable<string> inputFiles)
{ {
long totalFileSize = 0; long totalFileSize = 0;
inputFiles.Select(f => f).ToList().ForEach(f => totalFileSize += new FileInfo(f).Length); inputFiles.Select(f => f).ToList().ForEach(f => totalFileSize += new FileInfo(f).Length);
@ -179,14 +196,9 @@ namespace nxDumpFuse.Model
public void StopFuse() public void StopFuse()
{ {
_cts.Cancel(); _cts.Cancel();
Log(FuseSimpleLogType.Information, "Fuse Stopped"); Log(FuseSimpleLogType.Information, "Fuse Stopped");
OnFuseUpdate(new FuseUpdateInfo
{
Part = 0,
Parts = 0,
ProgressPart = 0,
Progress = 0
});
if (File.Exists(_outputFilePath)) if (File.Exists(_outputFilePath))
{ {
Task.Run((() => Task.Run((() =>
@ -198,6 +210,7 @@ namespace nxDumpFuse.Model
{ {
File.Delete(_outputFilePath); File.Delete(_outputFilePath);
Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() => Log(FuseSimpleLogType.Information, $"Deleted {_outputFilePath}")); Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() => Log(FuseSimpleLogType.Information, $"Deleted {_outputFilePath}"));
Update(0, 0, 0, 0);
break; break;
} }
catch (IOException) catch (IOException)

View file

@ -1,15 +1,9 @@
using System; using System;
using System.Diagnostics;
using Avalonia.Media; using Avalonia.Media;
using nxDumpFuse.Model.Enums;
namespace nxDumpFuse.Model namespace nxDumpFuse.Model
{ {
public enum FuseSimpleLogType
{
Error,
Information
}
public class FuseSimpleLog public class FuseSimpleLog
{ {
public FuseSimpleLog(FuseSimpleLogType type, DateTime time, string message) public FuseSimpleLog(FuseSimpleLogType type, DateTime time, string message)
@ -17,8 +11,9 @@ namespace nxDumpFuse.Model
Type = type; Type = type;
Time = time; Time = time;
Message = message; Message = message;
// This is not working, seems to be an issue https://github.com/AvaloniaUI/Avalonia/issues/2482
// needs to be reviewed. Setting Foreground property directly works fine, however binding fails
Color = Type == FuseSimpleLogType.Information ? Brushes.White : Brushes.Red; Color = Type == FuseSimpleLogType.Information ? Brushes.White : Brushes.Red;
Debug.WriteLine($"Color is {Color}");
} }
public FuseSimpleLogType Type { get; } public FuseSimpleLogType Type { get; }

View file

@ -1,18 +1,18 @@
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using nxDumpFuse.Interfaces; using nxDumpFuse.Interfaces;
using nxDumpFuse.ViewModels;
namespace nxDumpFuse.Services namespace nxDumpFuse.Services
{ {
public class DialogService : IDialogService public class DialogService : IDialogService
{ {
private readonly IMainWindowProvider _mainWindowProvider; private readonly IMainWindowProvider _mainWindowProvider;
public DialogService(IMainWindowProvider mainWindowProvider) public DialogService(IMainWindowProvider mainWindowProvider)
{ {
_mainWindowProvider = mainWindowProvider; _mainWindowProvider = mainWindowProvider;
} }
public async Task<string> ShowOpenFileDialogAsync(string title, FileDialogFilter filter) public async Task<string> ShowOpenFileDialogAsync(string title, FileDialogFilter filter)
{ {
var openFileDialog = new OpenFileDialog() var openFileDialog = new OpenFileDialog()

View file

@ -9,8 +9,7 @@ namespace nxDumpFuse.ViewModels
{ {
public class AboutViewModel : ViewModelBase, IAboutViewModel public class AboutViewModel : ViewModelBase, IAboutViewModel
{ {
private string _gitHubUrl = "https://github.com/oMaN-Rod/nxDumpFuse"; private const string GitHubUrl = "https://github.com/oMaN-Rod/nxDumpFuse";
private string _explorer = "explorer.exe";
public AboutViewModel() public AboutViewModel()
{ {
@ -20,28 +19,29 @@ namespace nxDumpFuse.ViewModels
public ReactiveCommand<Unit, Unit> OpenGithubCommand { get; } public ReactiveCommand<Unit, Unit> OpenGithubCommand { get; }
public string UsageText => BuildUsageText(); public string UsageText => BuildUsageText();
public string AuthorInfo => "Made for fun by oMaN-Rod, check me out on -->"; public string AuthorInfo => "Made for fun by oMaN-Rod, check me out on -->";
private void OpenGithub() private static void OpenGithub()
{ {
try try
{ {
Process.Start(_explorer, _gitHubUrl); Process.Start("explorer.exe", GitHubUrl);
} }
catch catch
{ {
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{ {
Process.Start("xdg-open", _gitHubUrl); Process.Start("xdg-open", GitHubUrl);
} }
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{ {
Process.Start("open", _gitHubUrl); Process.Start("open", GitHubUrl);
} }
} }
} }
private string BuildUsageText() private static string BuildUsageText()
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
sb.AppendLine("To fuse files make sure all file parts are alone in a directory with no other files, i.e"); sb.AppendLine("To fuse files make sure all file parts are alone in a directory with no other files, i.e");

View file

@ -1,12 +1,11 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Reactive; using System.Reactive;
using Avalonia.Controls; using Avalonia.Controls;
using nxDumpFuse.Interfaces; using nxDumpFuse.Interfaces;
using nxDumpFuse.Model; using nxDumpFuse.Model;
using nxDumpFuse.Services; using nxDumpFuse.Model.Enums;
using ReactiveUI; using ReactiveUI;
namespace nxDumpFuse.ViewModels namespace nxDumpFuse.ViewModels

View file

@ -2,26 +2,20 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:imaging="clr-namespace:Avalonia.Media.Imaging;assembly=Avalonia.Visuals"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="nxDumpFuse.Views.AboutView" x:Class="nxDumpFuse.Views.AboutView"
xmlns:vm="clr-namespace:nxDumpFuse.ViewModels" xmlns:vm="clr-namespace:nxDumpFuse.ViewModels"
x:DataType="vm:AboutViewModel"> x:DataType="vm:AboutViewModel">
<Grid Margin="20"> <Grid Margin="20"
<Grid.RowDefinitions> RowDefinitions="Auto,Auto"
<RowDefinition Height="Auto"/> ColumnDefinitions="Auto,*">
<RowDefinition Height="Auto"/> <TextBlock Grid.Row="0" Text="{Binding UsageText}" />
</Grid.RowDefinitions> <TextBlock Grid.Row="1" Grid.Column="0" Margin="5" VerticalAlignment="Center" Text="{Binding AuthorInfo}"
<Grid.ColumnDefinitions> HorizontalAlignment="Right" />
<ColumnDefinition Width="Auto"/> <Button Grid.Row="1" Grid.Column="1" Padding="-10" Command="{Binding OpenGithubCommand}">
<ColumnDefinition/> <Panel>
</Grid.ColumnDefinitions> <Image Width="75" Height="75" Source="resm:nxDumpFuse.Assets.github_icon.png" />
<TextBlock Grid.Row="0" Text="{Binding UsageText}"/> </Panel>
<TextBlock Grid.Row="1" Margin="5" VerticalAlignment="Center" Text="{Binding AuthorInfo}" HorizontalAlignment="Right"/> </Button>
<Button Grid.Row="1" Grid.Column="1" Padding="-10" Command="{Binding OpenGithubCommand}"> </Grid>
<Panel>
<Image Width="75" Height="75" Source="resm:nxDumpFuse.Assets.github_icon.png" />
</Panel>
</Button>
</Grid>
</UserControl> </UserControl>

View file

@ -5,58 +5,53 @@
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="nxDumpFuse.Views.FuseView" x:Class="nxDumpFuse.Views.FuseView"
xmlns:vm="clr-namespace:nxDumpFuse.ViewModels" xmlns:vm="clr-namespace:nxDumpFuse.ViewModels"
x:DataType="vm:FuseViewModel" x:DataType="vm:FuseViewModel">
Name="FuseViewControl"> <DockPanel LastChildFill="True">
<DockPanel LastChildFill="True"> <Grid Margin="20" DockPanel.Dock="Top"
<Grid Margin="20" DockPanel.Dock="Top"> RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto"
<Grid.RowDefinitions> ColumnDefinitions="Auto,*">
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0" Command="{Binding SelectInputFileCommand}" Content="Input" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center"/> <Button Grid.Row="0" Grid.Column="0" Command="{Binding SelectInputFileCommand}" Content="Input"
<TextBox Grid.Row="0" Grid.Column="1" Margin="5" VerticalAlignment="Center" Text="{Binding InputFilePath}" Name="InputFileTextBox"/> HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" />
<TextBox Grid.Row="0" Grid.Column="1" Margin="5" VerticalAlignment="Center" Text="{Binding InputFilePath}"
Name="InputFileTextBox" />
<Button Grid.Row="1" Grid.Column="0" Command="{Binding SelectOutputFolderCommand}" Content="Output" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center"/> <Button Grid.Row="1" Grid.Column="0" Command="{Binding SelectOutputFolderCommand}" Content="Output"
<TextBox Grid.Row="1" Grid.Column="1" Margin="5" VerticalAlignment="Center" Text="{Binding OutputDir}"/> HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" />
<TextBox Grid.Row="1" Grid.Column="1" Margin="5" VerticalAlignment="Center" Text="{Binding OutputDir}" />
<TextBlock Grid.Row="2" Grid.Column="0" Text="{Binding ProgressPartText}" HorizontalAlignment="Right" Margin="2"/> <TextBlock Grid.Row="2" Grid.Column="0" Text="{Binding ProgressPartText}" HorizontalAlignment="Right"
<ProgressBar Grid.Row="2" Grid.Column="1" Margin="2" Height="10" Value="{Binding ProgressPart}"/> Margin="2" />
<TextBlock Grid.Row="3" Grid.Column="0" Text="Total" HorizontalAlignment="Right" Margin="2"/> <ProgressBar Grid.Row="2" Grid.Column="1" Margin="2" Height="10" Value="{Binding ProgressPart}" />
<ProgressBar Grid.Row="3" Grid.Column="1" Margin="2" Height="10" Value="{Binding Progress}"/>
<StackPanel Grid.Row="4" Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right"> <TextBlock Grid.Row="3" Grid.Column="0" Text="Total" HorizontalAlignment="Right" Margin="2" />
<Button Command="{Binding FuseCommand}" Content="Fuse" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" Margin="2"/> <ProgressBar Grid.Row="3" Grid.Column="1" Margin="2" Height="10" Value="{Binding Progress}" />
<Button Command="{Binding StopCommand}" Content="Stop" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" Margin="2"/>
</StackPanel>
<DataGrid Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="2" <StackPanel Grid.Row="4" Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right">
x:Name="FuseSimpleLog" <Button Command="{Binding FuseCommand}" Content="Fuse" HorizontalAlignment="Stretch"
Items="{Binding LogItems}" HorizontalContentAlignment="Center" Margin="2" />
CanUserSortColumns="False" <Button Command="{Binding StopCommand}" Content="Stop" HorizontalAlignment="Stretch"
CanUserResizeColumns="True" HorizontalContentAlignment="Center" Margin="2" />
CanUserReorderColumns="True" </StackPanel>
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto" <DataGrid Grid.Row="5" Grid.Column="0" Grid.ColumnSpan="2"
Width="{Binding #InputFileTextBox.Width}" x:Name="FuseSimpleLog"
VerticalAlignment="Top" Items="{Binding LogItems}"
Margin="4" CanUserSortColumns="False"
Height="350"> CanUserResizeColumns="True"
<DataGrid.Columns> CanUserReorderColumns="True"
<DataGridTextColumn Header="Type" Binding="{Binding Type}" Width="Auto" Foreground="{Binding Color}"/> VerticalScrollBarVisibility="Auto"
<DataGridTextColumn Header="Time" Binding="{Binding Time}" Width="Auto"/> HorizontalScrollBarVisibility="Auto"
<DataGridTextColumn Header="Message" Binding="{Binding Message}" Width="Auto"/> VerticalAlignment="Top"
</DataGrid.Columns> Height="300">
</DataGrid> <DataGrid.Columns>
</Grid> <DataGridTextColumn Header="Type" Binding="{Binding Type}" Width="Auto"
</DockPanel> Foreground="{Binding Color}" FontSize="12" />
<DataGridTextColumn Header="Time" Binding="{Binding Time}" Width="Auto" FontSize="12" />
<DataGridTextColumn Header="Message" Binding="{Binding Message}" Width="Auto" FontSize="12" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</DockPanel>
</UserControl> </UserControl>

View file

@ -1,6 +1,5 @@
<UserControl xmlns="https://github.com/avaloniaui" <UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:nxDumpFuse.ViewModels;assembly=nxDumpFuse"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="1350" d:DesignHeight="700" mc:Ignorable="d" d:DesignWidth="1350" d:DesignHeight="700"
@ -8,28 +7,29 @@
FontSize="14" FontSize="14"
Foreground="{StaticResource SystemBaseHighColor}" Foreground="{StaticResource SystemBaseHighColor}"
xmlns:views="clr-namespace:nxDumpFuse.Views;assembly=nxDumpFuse"> xmlns:views="clr-namespace:nxDumpFuse.Views;assembly=nxDumpFuse">
<Panel> <Panel>
<DockPanel HorizontalAlignment="Stretch"> <DockPanel HorizontalAlignment="Stretch">
<ExperimentalAcrylicBorder DockPanel.Dock="Left" Width="150"> <ExperimentalAcrylicBorder DockPanel.Dock="Left" Width="150">
<ExperimentalAcrylicBorder.Material> <ExperimentalAcrylicBorder.Material>
<ExperimentalAcrylicMaterial TintColor="Black" MaterialOpacity="0.85" TintOpacity="1" /> <ExperimentalAcrylicMaterial TintColor="Black" MaterialOpacity="0.85" TintOpacity="1" />
</ExperimentalAcrylicBorder.Material> </ExperimentalAcrylicBorder.Material>
</ExperimentalAcrylicBorder> </ExperimentalAcrylicBorder>
<ExperimentalAcrylicBorder IsHitTestVisible="False"> <ExperimentalAcrylicBorder IsHitTestVisible="False">
<ExperimentalAcrylicBorder.Material> <ExperimentalAcrylicBorder.Material>
<ExperimentalAcrylicMaterial TintColor="#222222" MaterialOpacity="0.85" TintOpacity="1" /> <ExperimentalAcrylicMaterial TintColor="#222222" MaterialOpacity="0.85" TintOpacity="1" />
</ExperimentalAcrylicBorder.Material> </ExperimentalAcrylicBorder.Material>
<TextBlock Text="{Binding #TabControl.SelectedItem.Header}" Margin="40 20" FontSize="32" FontWeight="Light" /> <TextBlock Text="{Binding #TabControl.SelectedItem.Header}" Margin="40 20" FontSize="32"
</ExperimentalAcrylicBorder> FontWeight="Light" />
</DockPanel> </ExperimentalAcrylicBorder>
</DockPanel>
<TabControl x:Name="TabControl" Classes="sidebar" Margin="0 40 0 20"> <TabControl x:Name="TabControl" Classes="sidebar" Margin="0 40 0 20">
<TabItem Header="Fuse"> <TabItem Header="Fuse">
<views:FuseView DataContext="{Binding FuseViewModel}"/> <views:FuseView DataContext="{Binding FuseViewModel}" />
</TabItem> </TabItem>
<TabItem Header="About"> <TabItem Header="About">
<views:AboutView DataContext="{Binding AboutViewModel}"/> <views:AboutView DataContext="{Binding AboutViewModel}" />
</TabItem> </TabItem>
</TabControl> </TabControl>
</Panel> </Panel>
</UserControl> </UserControl>

View file

@ -1,29 +1,29 @@
<nxDumpFuse:FluentWindow xmlns="https://github.com/avaloniaui" <nxDumpFuse:FluentWindow xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:nxDumpFuse.ViewModels;assembly=nxDumpFuse" xmlns:vm="clr-namespace:nxDumpFuse.ViewModels;assembly=nxDumpFuse"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="nxDumpFuse.Views.MainWindow" x:Class="nxDumpFuse.Views.MainWindow"
x:Name="MainWindow" x:Name="MainWindow"
xmlns:local="clr-namespace:nxDumpFuse.Views" xmlns:local="clr-namespace:nxDumpFuse.Views"
xmlns:nxDumpFuse="clr-namespace:nxDumpFuse" xmlns:nxDumpFuse="clr-namespace:nxDumpFuse"
Icon="{x:Null}" Icon="{x:Null}"
Title="nxDumpFuse" Title="nxDumpFuse"
WindowStartupLocation="CenterScreen" WindowStartupLocation="CenterScreen"
Background="{x:Null}" Background="{x:Null}"
Width="1280" Height="720"> Width="1280" Height="720">
<nxDumpFuse:FluentWindow.Styles> <nxDumpFuse:FluentWindow.Styles>
<Style Selector="TitleBar:fullscreen"> <Style Selector="TitleBar:fullscreen">
<Setter Property="Background" Value="#7f000000" /> <Setter Property="Background" Value="#7f000000" />
</Style> </Style>
</nxDumpFuse:FluentWindow.Styles> </nxDumpFuse:FluentWindow.Styles>
<Design.DataContext> <Design.DataContext>
<vm:MainWindowViewModel/> <vm:MainWindowViewModel />
</Design.DataContext> </Design.DataContext>
<Panel Margin="{Binding #MainWindow.OffScreenMargin}"> <Panel Margin="{Binding #MainWindow.OffScreenMargin}">
<local:MainView DataContext="{Binding MainViewModel}"/> <local:MainView DataContext="{Binding MainViewModel}" />
</Panel> </Panel>
</nxDumpFuse:FluentWindow> </nxDumpFuse:FluentWindow>

View file

@ -5,8 +5,9 @@
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<SelfContained>true</SelfContained> <SelfContained>true</SelfContained>
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract> <IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
<!--<RuntimeIdentifier>win10-x64</RuntimeIdentifier>--> <RuntimeIdentifier>win10-x64</RuntimeIdentifier>
<RuntimeIdentifier>osx-x64</RuntimeIdentifier> <!--<RuntimeIdentifier>linux-x64</RuntimeIdentifier>-->
<!--<RuntimeIdentifier>osx-x64</RuntimeIdentifier>-->
<PublishSingleFile>true</PublishSingleFile> <PublishSingleFile>true</PublishSingleFile>
<ApplicationIcon>nxDumpFuse.ico</ApplicationIcon> <ApplicationIcon>nxDumpFuse.ico</ApplicationIcon>
</PropertyGroup> </PropertyGroup>