Fully implemented Operations UI with one example
- You can now add, remove, modify and move operations - FilterChangedAny was renamed to FilterChanged, the new event for the preview follows the same naming scheme with PreviewChanged - Operations now actually verify that they're enabled (This was originally supposed to be done in the loop in Preview(), but this way seems nicer since it also removes the error label when the operation is disabled) - The foundation has been laid to make it very easy to add more operations
This commit is contained in:
parent
c51f848a31
commit
5d8327f071
|
@ -2,6 +2,7 @@
|
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:ops="clr-namespace:BFR.Operations;assembly=BFR"
|
||||
mc:Ignorable="d" MinWidth="720" MinHeight="480"
|
||||
x:Class="BFR.MainWindow"
|
||||
Title="BFR">
|
||||
|
@ -16,13 +17,13 @@
|
|||
<!-- Filters -->
|
||||
<Grid Grid.Row="1" Grid.ColumnSpan="3" ColumnDefinitions="auto,*,auto,*,auto,auto,auto,auto" IsVisible="{Binding #FilterExpander.IsExpanded}">
|
||||
<TextBlock Grid.Column="0" Text="Extension:"/>
|
||||
<TextBox Grid.Column="1" Text="{Binding FilterExtension}" KeyUp="FilterChangedAny"/>
|
||||
<TextBox Grid.Column="1" Text="{Binding FilterExtension}" KeyUp="FilterChanged"/>
|
||||
<TextBlock Grid.Column="2" Text="Name:"/>
|
||||
<TextBox Grid.Column="3" Text="{Binding FilterPattern}" KeyUp="FilterChangedAny"/>
|
||||
<TextBox Grid.Column="3" Text="{Binding FilterPattern}" KeyUp="FilterChanged"/>
|
||||
<TextBlock Grid.Column="4" Text="Full Name:"/>
|
||||
<CheckBox Grid.Column="5" IsChecked="{Binding FilterFullName}" Click="FilterChangedAny"/>
|
||||
<CheckBox Grid.Column="5" IsChecked="{Binding FilterFullName}" Click="FilterChanged"/>
|
||||
<TextBlock Grid.Column="6" Text="Regex:"/>
|
||||
<CheckBox Grid.Column="7" IsChecked="{Binding FilterRegex}" Click="FilterChangedAny" Margin="4,4,5,4"/>
|
||||
<CheckBox Grid.Column="7" IsChecked="{Binding FilterRegex}" Click="FilterChanged" Margin="4,4,5,4"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
@ -51,16 +52,16 @@
|
|||
<!-- Middle Section (Operations, Controls) -->
|
||||
<Grid Grid.Row="2" Grid.Column="1" RowDefinitions="*,auto,auto" Classes="StyleBorders">
|
||||
<!-- Operations ListBox -->
|
||||
<ListBox Grid.Row="0"/>
|
||||
<ListBox Grid.Row="0" Items="{Binding Operations}" Name="OperationsListBox" SelectedIndex="{Binding SelectedOperation}"/>
|
||||
|
||||
<!-- Operations Controls -->
|
||||
<Border Grid.Row="1" Classes="ConnectUp">
|
||||
<Grid ColumnDefinitions="auto,*,auto,auto,auto">
|
||||
<TextBlock Grid.Column="0" Text="New:"/>
|
||||
<ComboBox Grid.Column="1"/>
|
||||
<Button Grid.Column="2" Content=" + "/>
|
||||
<Button Grid.Column="3" Content=" - "/>
|
||||
<ButtonSpinner Grid.Column="4"/>
|
||||
<ComboBox Grid.Column="1" Items="{Binding OperationTypes}" SelectedIndex="{Binding SelectedOperationType}"/>
|
||||
<Button Grid.Column="2" Content=" + " Command="{Binding AddOperation}"/>
|
||||
<Button Grid.Column="3" Content=" - " Command="{Binding RemoveOperation}"/>
|
||||
<ButtonSpinner Grid.Column="4" Spin="MoveOperation"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
|
@ -75,6 +76,7 @@
|
|||
</Grid>
|
||||
|
||||
<Window.Styles>
|
||||
<!-- General Styling-->
|
||||
<Style Selector="Grid > Expander">
|
||||
<Setter Property="Margin" Value="4"/>
|
||||
</Style>
|
||||
|
@ -120,5 +122,41 @@
|
|||
<Style Selector="Border.ConnectUp">
|
||||
<Setter Property="Margin" Value="4,-5,4,4"/>
|
||||
</Style>
|
||||
|
||||
<!-- Operation Styles -->
|
||||
<Style Selector="Expander.OperationExpander">
|
||||
<Setter Property="Header">
|
||||
<Template>
|
||||
<Grid ColumnDefinitions="auto,*,auto">
|
||||
<CheckBox Grid.Column="0" Margin="0,0,8,0" IsChecked="{Binding IsEnabled}" Command="{Binding $parent[6].DataContext.Preview}"/>
|
||||
<TextBlock Grid.Column="1" Margin="0,0,8,0" Text="{Binding Name}"/>
|
||||
<Grid Grid.Column="2" ToolTip.Tip="{Binding Error}" IsVisible="{Binding !!Error.Length}">
|
||||
<Ellipse Width="18" Height="18" Margin="0" Stroke="DarkRed" StrokeThickness="2"/>
|
||||
<TextBlock Width="18" Height="18" Margin="0" Foreground="DarkRed" Text="!" FontWeight="Black" TextAlignment="Center"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Template>
|
||||
</Setter>
|
||||
</Style>
|
||||
</Window.Styles>
|
||||
|
||||
<Window.DataTemplates>
|
||||
<!-- Operation Type (For the selector) -->
|
||||
<DataTemplate DataType="{x:Type ops:OperationType}">
|
||||
<TextBlock Text="{Binding Name}"/>
|
||||
</DataTemplate>
|
||||
|
||||
<!-- Operations -->
|
||||
<DataTemplate DataType="{x:Type ops:Overwrite}">
|
||||
<Expander Classes="OperationExpander">
|
||||
<Grid ColumnDefinitions="auto,*" RowDefinitions="*,*">
|
||||
<TextBlock Grid.Row="0" Text="Replacement:"/>
|
||||
<TextBox Grid.Row="0" Text="{Binding Replacement}" KeyUp="PreviewChanged"/>
|
||||
<TextBlock Grid.Row="1" Text="Full Name:"/>
|
||||
<CheckBox Grid.Row="1" IsChecked="{Binding FullName}" Click="PreviewChanged"/>
|
||||
</Grid>
|
||||
</Expander>
|
||||
</DataTemplate>
|
||||
</Window.DataTemplates>
|
||||
|
||||
</Window>
|
||||
|
|
|
@ -25,8 +25,8 @@ namespace BFR
|
|||
Filter();
|
||||
}
|
||||
|
||||
public void FilterChangedAny(object sender, KeyEventArgs e) => Filter();
|
||||
public void FilterChangedAny(object sender, RoutedEventArgs e) => Filter();
|
||||
public void FilterChanged(object sender, KeyEventArgs e) => Filter();
|
||||
public void FilterChanged(object sender, RoutedEventArgs e) => Filter();
|
||||
public void Filter()
|
||||
{
|
||||
// Filter all files in the directory for those satisfying the given filters
|
||||
|
@ -37,6 +37,10 @@ namespace BFR
|
|||
Preview();
|
||||
}
|
||||
|
||||
public void PreviewChanged(object sender, KeyEventArgs e) => Preview(); // TextBox.KeyUp
|
||||
public void PreviewChanged(object sender, RoutedEventArgs e) => Preview(); // CheckBox.Click
|
||||
public void PreviewChanged(object sender, SelectionChangedEventArgs e) => Preview(); // ComboBox.SelectionChanged
|
||||
public void PreviewChanged(object sender, NumericUpDownValueChangedEventArgs e) => Preview(); // NumericUpDown.ValueChanged
|
||||
public void Preview()
|
||||
{
|
||||
// Reset all files to how they currently exist
|
||||
|
@ -51,6 +55,32 @@ namespace BFR
|
|||
Files.ReplaceAll(new List<FileModel>(Files));
|
||||
}
|
||||
|
||||
public void AddOperation()
|
||||
{
|
||||
Operations.Insert(
|
||||
SelectedOperation >= 0 ? SelectedOperation + 1 : Operations.Count,
|
||||
OperationTypes[SelectedOperationType].Create());
|
||||
Preview();
|
||||
}
|
||||
|
||||
public void RemoveOperation()
|
||||
{
|
||||
if (SelectedOperation >= 0)
|
||||
Operations.RemoveAt(SelectedOperation);
|
||||
else Operations.RemoveAt(0);
|
||||
Preview();
|
||||
}
|
||||
|
||||
public void MoveOperation(object sender, SpinEventArgs e)
|
||||
{
|
||||
if (Operations.Count > 1)
|
||||
if (e.Direction == SpinDirection.Increase && SelectedOperation > 0)
|
||||
Operations.Move(SelectedOperation, SelectedOperation - 1);
|
||||
else if (e.Direction == SpinDirection.Decrease && SelectedOperation < Operations.Count - 1)
|
||||
Operations.Move(SelectedOperation, SelectedOperation + 1);
|
||||
Preview();
|
||||
}
|
||||
|
||||
public MainWindow() => InitializeComponent();
|
||||
private void InitializeComponent()
|
||||
{
|
||||
|
|
|
@ -16,6 +16,13 @@ namespace BFR
|
|||
public AvaloniaList<FileModel> AllFiles { get; } = new AvaloniaList<FileModel>();
|
||||
public AvaloniaList<FileModel> Files { get; } = new AvaloniaList<FileModel>();
|
||||
public AvaloniaList<Operation> Operations { get; } = new AvaloniaList<Operation>();
|
||||
public int SelectedOperation { get; set; }
|
||||
|
||||
public int SelectedOperationType { get; set; } = 0;
|
||||
public OperationType[] OperationTypes { get; } = new[]
|
||||
{
|
||||
OperationType.Make<Overwrite>()
|
||||
};
|
||||
|
||||
// Filters
|
||||
public string FilterExtension { get; set; } = "";
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Avalonia;
|
||||
|
||||
using BFR.DataModels;
|
||||
|
@ -24,8 +25,9 @@ namespace BFR.Operations
|
|||
var backup = files.Select(file => file.Path).ToList();
|
||||
try
|
||||
{
|
||||
ApplyToInternal(files); // Try to apply operation
|
||||
Error = ""; // If successul, remove any previous error
|
||||
if(IsEnabled)
|
||||
ApplyToInternal(files); // Try to apply operation
|
||||
Error = ""; // If successul, remove any previous error
|
||||
}
|
||||
catch (OperationException e) { Error = e.Message; } // If expected, show user a concise and descriptive message
|
||||
catch (Exception e) { Error = $"Unexpected {e}"; } // If not, hint with the exception thrown that this is unexpected behaviour
|
||||
|
|
Loading…
Reference in New Issue
Block a user