MainWindow skeleton

This commit is contained in:
2022-04-03 09:22:24 +02:00
parent 7ff3898bd9
commit b6b8a7b3f8
28 changed files with 432 additions and 105 deletions

View File

@@ -132,6 +132,9 @@
<converters:GetFileExtensionConverter x:Key="GetFileExtensionConverter"/>
<converters:FormatSizeConverter x:Key="FormatSizeConverter"/>
<converters:DateTimeConverter x:Key="DateTimeConverter"/>
<converters:SplitStringConverter x:Key="SplitStringConverter" />
<converters:CompareConverter x:Key="EqualityConverter"/>
<converters:CompareConverter x:Key="NotEqualsConverter" ComparisonCondition="{x:Static converters:ComparisonCondition.NotEqual}"/>
</ResourceDictionary>
</Application.Resources>

View File

@@ -7,6 +7,7 @@
<TrimMode>copyused</TrimMode>
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
<ApplicationIcon>filetime.ico</ApplicationIcon>
<Version>0.0.1</Version>
</PropertyGroup>
<ItemGroup>
<Content Include="filetime.ico" />

View File

@@ -0,0 +1,3 @@
<svg style="width:24px;height:24px" viewBox="0 0 24 24">
<path fill="white" d="M12,4V2A10,10 0 0,0 2,12H4A8,8 0 0,1 12,4Z" />
</svg>

After

Width:  |  Height:  |  Size: 136 B

View File

@@ -0,0 +1,54 @@
using System.Globalization;
using Avalonia.Data.Converters;
namespace FileTime.GuiApp.Converters
{
public enum ComparisonCondition
{
Equal,
GreaterThan,
LessThan,
LessThanOrEqual,
NotEqual,
GreaterThanOrEqual
}
public class CompareConverter : IValueConverter
{
public ComparisonCondition ComparisonCondition { get; set; } = ComparisonCondition.Equal;
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
return Compare(value, parameter);
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
private bool Compare(object? value, object? parameter)
{
if (ComparisonCondition == ComparisonCondition.GreaterThan)
{
if (value is int valueInt && (parameter is int parameterInt || int.TryParse(parameter?.ToString(), out parameterInt))) return valueInt > parameterInt;
else if (value is double valueDouble && (parameter is double parameterDouble || double.TryParse(parameter?.ToString(), out parameterDouble))) return valueDouble > parameterDouble;
else throw new NotSupportedException();
}
else if (ComparisonCondition == ComparisonCondition.NotEqual)
{
if (value is int valueInt && (parameter is int parameterInt || int.TryParse(parameter?.ToString(), out parameterInt))) return valueInt != parameterInt;
else if (value is double valueDouble && (parameter is double parameterDouble || double.TryParse(parameter?.ToString(), out parameterDouble))) return valueDouble != parameterDouble;
return value != parameter;
}
else if (ComparisonCondition == ComparisonCondition.Equal)
{
if (value is int valueInt && (parameter is int parameterInt || int.TryParse(parameter?.ToString(), out parameterInt))) return valueInt == parameterInt;
else if (value is double valueDouble && (parameter is double parameterDouble || double.TryParse(parameter?.ToString(), out parameterDouble))) return valueDouble == parameterDouble;
else if (value?.GetType().IsEnum ?? false && Enum.TryParse(value.GetType(), parameter?.ToString(), out var _)) return value.ToString() == parameter?.ToString();
}
return value == parameter;
}
}
}

View File

@@ -0,0 +1,27 @@
using System.Globalization;
using Avalonia.Data.Converters;
namespace FileTime.GuiApp.Converters
{
public class SplitStringConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is string path && parameter is string separator)
{
return path.Split(separator);
}
else if (value is string path2 && parameter is char separator2)
{
return path2.Split(separator2);
}
return value;
}
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View File

@@ -13,16 +13,6 @@
<ItemGroup>
<AvaloniaResource Include="Assets\**" />
</ItemGroup>
<ItemGroup>
<AvaloniaXaml Update="Views\MainWindow.axaml">
<Generator>MSBuild:Compile</Generator>
</AvaloniaXaml>
</ItemGroup>
<ItemGroup>
<Compile Update="Views\MainWindow.axaml.cs">
<DependentUpon>MainWindow.axaml</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia" Version="0.10.13" />
@@ -30,6 +20,7 @@
<!--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.13" />
<PackageReference Include="Avalonia.ReactiveUI" Version="0.10.13" />
<PackageReference Include="Avalonia.Svg.Skia" Version="0.10.12" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="6.0.0" />
<PackageReference Include="MvvmGen" Version="1.1.5" />

View File

@@ -1,4 +1,5 @@
using System;
using System.Reflection;
using Avalonia.Input;
using FileTime.App.Core;
using FileTime.App.Core.ViewModels;
@@ -6,6 +7,7 @@ using FileTime.Core.Models;
using FileTime.Core.Services;
using FileTime.Providers.Local;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using MvvmGen;
namespace FileTime.GuiApp.ViewModels
@@ -14,17 +16,34 @@ namespace FileTime.GuiApp.ViewModels
[Inject(typeof(IAppState), "_appState")]
[Inject(typeof(ILocalContentProvider), "_localContentProvider")]
[Inject(typeof(IServiceProvider), PropertyName = "_serviceProvider")]
[Inject(typeof(ILogger<MainWindowViewModel>), PropertyName = "_logger")]
public partial class MainWindowViewModel : IMainWindowViewModelBase
{
public bool Loading => false;
public IAppState AppState => _appState;
public string Title { get; private set; }
partial void OnInitialize()
{
_logger?.LogInformation($"Starting {nameof(MainWindowViewModel)} initialization...");
var version = Assembly.GetEntryAssembly()!.GetName().Version;
var versionString = "Unknwon version";
if (version != null)
{
versionString = $"{version.Major}.{version.Minor}.{version.Build}";
if (version.Revision != 0)
{
versionString += $" ({version.Revision})";
}
}
Title = "FileTime " + versionString;
//TODO: refactor
if (AppState.Tabs.Count == 0)
{
var tab = _serviceProvider.GetInitableResolver<IContainer>(_localContentProvider).GetRequiredService<ITab>();
var tabViewModel = _serviceProvider.GetInitableResolver(tab).GetRequiredService<ITabViewModel>();
var tabViewModel = _serviceProvider.GetInitableResolver(tab, 1).GetRequiredService<ITabViewModel>();
_appState.AddTab(tabViewModel);
}

View File

@@ -23,22 +23,116 @@
<Grid Background="{DynamicResource AppBackgroundBrush}">
<Grid IsVisible="{Binding Loading, Converter={x:Static BoolConverters.Not}}">
<Grid ColumnDefinitions="250,*" RowDefinitions="Auto,*">
<ListBox
Grid.Row="1"
x:Name="CurrentItems"
x:CompileBindings="False"
AutoScrollToSelectedItem="True"
IsTabStop="True"
Items="{Binding AppState.SelectedTab.CurrentItems^}"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
ScrollViewer.VerticalScrollBarVisibility="Visible"
Classes="ContentListView">
<ListBox.ItemTemplate>
<DataTemplate x:DataType="corevm:IItemViewModel">
<local:ItemView HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Grid PointerPressed="HeaderPointerPressed">
<Rectangle Fill="#01000000"/>
<TextBlock Margin="15,10" Text="{Binding Title}"/>
</Grid>
<Grid Grid.Column="1" PointerPressed="HeaderPointerPressed">
<Rectangle Fill="#01000000"/>
<StackPanel Margin="20,10" Orientation="Horizontal">
<!--local:PathPresenter DataContext="{Binding AppState.SelectedTab.CurrentLocation^.FullName.Path,Converter={StaticResource PathPreformatter}}"/-->
<TextBlock
Text="{Binding AppState.SelectedTab.CurrentSelectedItem^.DisplayNameText}" Foreground="{StaticResource AccentBrush}" />
</StackPanel>
</Grid>
<Grid Grid.Column="1" Grid.Row="1" RowDefinitions="Auto,40,*,Auto">
<ItemsControl
Grid.Row="1"
Items="{Binding AppState.Tabs}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid RowDefinitions="Auto,1">
<StackPanel Orientation="Horizontal" Margin="20,0,20,0">
<TextBlock
VerticalAlignment="Center" Text="{Binding TabNumber,StringFormat=({0})}" />
<TextBlock
VerticalAlignment="Center" Margin="5,0,0,0" Text="{Binding CurrentLocation^.Name}" />
</StackPanel>
<Rectangle Fill="{DynamicResource ForegroundBrush}" Grid.Row="1" IsVisible="{Binding IsSelected^}"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Grid
Grid.Row="2"
Margin="20,0,0,0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="15*" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="40*" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="45*" />
</Grid.ColumnDefinitions>
<Rectangle
Grid.Column="1"
Width="1"
Margin="0,10,0,10"
HorizontalAlignment="Center"
VerticalAlignment="Stretch"
Fill="{DynamicResource ContentSeparatorBrush}" />
<Grid Grid.Column="2" RowDefinitions="Auto,*">
<Grid IsVisible="{Binding AppState.SelectedTab.CurrentLocation^.IsLoading^}">
<Image Width="40" Height="40" Source="{SvgImage /Assets/loading.svg}" Classes="LoadingAnimation"/>
</Grid>
<ListBox
Grid.Row="1"
x:Name="CurrentItems"
x:CompileBindings="False"
AutoScrollToSelectedItem="True"
IsTabStop="True"
Items="{Binding AppState.SelectedTab.CurrentItems^}"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
ScrollViewer.VerticalScrollBarVisibility="Visible"
Classes="ContentListView">
<ListBox.ItemTemplate>
<DataTemplate x:DataType="corevm:IItemViewModel">
<local:ItemView HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBlock
Grid.Row="1"
x:CompileBindings="False"
x:Name="CurrentEmpty"
Margin="10"
HorizontalAlignment="Center"
FontWeight="Bold"
Foreground="{DynamicResource ErrorBrush}"
IsVisible="{Binding AppState.SelectedTab.CurrentLocation^.Items^.Count, Converter={StaticResource EqualityConverter}, ConverterParameter=0}">
Empty
</TextBlock>
</Grid>
<Rectangle
Grid.Column="3"
Width="1"
Margin="0,10,0,10"
HorizontalAlignment="Center"
VerticalAlignment="Stretch"
Fill="{DynamicResource ContentSeparatorBrush}" />
</Grid>
</Grid>
</Grid>
</Grid>
<!--Borders-->

View File

@@ -49,5 +49,24 @@ namespace FileTime.GuiApp.Views
ViewModel?.ProcessKeyDown(e.Key, e.KeyModifiers, h => e.Handled = h);
}
}
private void HeaderPointerPressed(object sender, PointerPressedEventArgs e)
{
if (e.ClickCount == 2)
{
if (WindowState == WindowState.Maximized)
{
WindowState = WindowState.Normal;
}
else
{
WindowState = WindowState.Maximized;
}
}
else
{
BeginMoveDrag(e);
}
}
}
}