Skip to content

Commit e252675

Browse files
committed
Feat: implement ui
1 parent cae732a commit e252675

File tree

11 files changed

+937
-65
lines changed

11 files changed

+937
-65
lines changed

DebitExpress.VatRelief/App.xaml

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
1-
<Application x:Class="DebitExpress.VatRelief.App"
2-
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3-
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4-
xmlns:local="clr-namespace:DebitExpress.VatRelief"
5-
StartupUri="MainWindow.xaml">
1+
<Application
2+
x:Class="DebitExpress.VatRelief.App"
3+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
4+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5+
StartupUri="MainWindow.xaml">
66
<Application.Resources>
7-
7+
<ResourceDictionary>
8+
<ResourceDictionary.MergedDictionaries>
9+
<ResourceDictionary Source="pack://application:,,,/DebitExpress.Controls;component/Defaults.xaml" />
10+
<ResourceDictionary Source="pack://application:,,,/Themes/MaterialTheme.Dark.xaml" />
11+
<ResourceDictionary Source="pack://application:,,,/Themes/MaterialTheme.xaml" />
12+
</ResourceDictionary.MergedDictionaries>
13+
</ResourceDictionary>
814
</Application.Resources>
9-
</Application>
15+
</Application>

DebitExpress.VatRelief/App.xaml.cs

Lines changed: 3 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,8 @@
1-
using System;
2-
using System.Collections.Generic;
3-
using System.Configuration;
4-
using System.Data;
5-
using System.Linq;
6-
using System.Threading.Tasks;
7-
using System.Windows;
8-
using DebitExpress.VatRelief.Models;
9-
using DebitExpress.VatRelief.Utils;
10-
11-
namespace DebitExpress.VatRelief;
1+
namespace DebitExpress.VatRelief;
122

133
/// <summary>
14-
/// Interaction logic for App.xaml
4+
/// Interaction logic for App.xaml
155
/// </summary>
16-
public partial class App : Application
6+
public partial class App
177
{
18-
protected override async void OnStartup(StartupEventArgs e)
19-
{
20-
const string fileName = @"%USERPROFILE%\Desktop\vat-relief-template.xlsx";
21-
22-
var reader = new VatTemplateReader();
23-
var result = await reader.ReadAsync(Environment.ExpandEnvironmentVariables(fileName));
24-
if (result.IsFaulted)
25-
{
26-
MessageBox.Show(result.ToString());
27-
Environment.Exit(1);
28-
}
29-
30-
const string loc = @"%USERPROFILE%\Desktop";
31-
var path = Environment.ExpandEnvironmentVariables(loc);
32-
ExcelData data = result;
33-
34-
var generator = new DatFileGenerator();
35-
await generator.GenerateAsync(data, path);
36-
37-
var reconWriter = new ExcelReconWriter();
38-
reconWriter.WriteReconciliationReport(data, path);
39-
}
408
}
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
using System;
2+
using System.Globalization;
3+
using System.Windows;
4+
using System.Windows.Data;
5+
using System.Windows.Media;
6+
7+
namespace DebitExpress.VatRelief.Converters;
8+
9+
public sealed class BorderClipConverter : IMultiValueConverter
10+
{
11+
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
12+
{
13+
if (values.Length <= 1 || values[0] is not double width || values[1] is not double height)
14+
return DependencyProperty.UnsetValue;
15+
if (width < 1.0 || height < 1.0) return Geometry.Empty;
16+
17+
CornerRadius cornerRadius = default;
18+
Thickness borderThickness = default;
19+
if (values.Length > 2 && values[2] is CornerRadius radius)
20+
{
21+
cornerRadius = radius;
22+
if (values.Length > 3 && values[3] is Thickness thickness) borderThickness = thickness;
23+
}
24+
25+
var geometry = GetRoundRectangle(new Rect(0, 0, width, height), borderThickness, cornerRadius);
26+
geometry.Freeze();
27+
28+
return geometry;
29+
}
30+
31+
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) =>
32+
throw new NotImplementedException();
33+
34+
// https://wpfspark.wordpress.com/2011/06/08/clipborder-a-wpf-border-that-clips/
35+
private static Geometry GetRoundRectangle(Rect baseRect, Thickness borderThickness, CornerRadius cornerRadius)
36+
{
37+
// Normalizing the corner radius
38+
if (cornerRadius.TopLeft < double.Epsilon) cornerRadius.TopLeft = 0.0;
39+
40+
if (cornerRadius.TopRight < double.Epsilon) cornerRadius.TopRight = 0.0;
41+
42+
if (cornerRadius.BottomLeft < double.Epsilon) cornerRadius.BottomLeft = 0.0;
43+
44+
if (cornerRadius.BottomRight < double.Epsilon) cornerRadius.BottomRight = 0.0;
45+
46+
// Taking the border thickness into account
47+
var leftHalf = borderThickness.Left * 0.5;
48+
if (leftHalf < double.Epsilon) leftHalf = 0.0;
49+
50+
var topHalf = borderThickness.Top * 0.5;
51+
if (topHalf < double.Epsilon) topHalf = 0.0;
52+
53+
var rightHalf = borderThickness.Right * 0.5;
54+
if (rightHalf < double.Epsilon) rightHalf = 0.0;
55+
56+
var bottomHalf = borderThickness.Bottom * 0.5;
57+
if (bottomHalf < double.Epsilon) bottomHalf = 0.0;
58+
59+
// Create the rectangles for the corners that needs to be curved in the base rectangle
60+
// TopLeft Rectangle
61+
var topLeftRect = new Rect(
62+
baseRect.Location.X,
63+
baseRect.Location.Y,
64+
Math.Max(0.0, cornerRadius.TopLeft - leftHalf),
65+
Math.Max(0.0, cornerRadius.TopLeft - rightHalf));
66+
67+
// TopRight Rectangle
68+
var topRightRect = new Rect(
69+
baseRect.Location.X + baseRect.Width - cornerRadius.TopRight + rightHalf,
70+
baseRect.Location.Y,
71+
Math.Max(0.0, cornerRadius.TopRight - rightHalf),
72+
Math.Max(0.0, cornerRadius.TopRight - topHalf));
73+
74+
// BottomRight Rectangle
75+
var bottomRightRect = new Rect(
76+
baseRect.Location.X + baseRect.Width - cornerRadius.BottomRight + rightHalf,
77+
baseRect.Location.Y + baseRect.Height - cornerRadius.BottomRight + bottomHalf,
78+
Math.Max(0.0, cornerRadius.BottomRight - rightHalf),
79+
Math.Max(0.0, cornerRadius.BottomRight - bottomHalf));
80+
81+
// BottomLeft Rectangle
82+
var bottomLeftRect = new Rect(
83+
baseRect.Location.X,
84+
baseRect.Location.Y + baseRect.Height - cornerRadius.BottomLeft + bottomHalf,
85+
Math.Max(0.0, cornerRadius.BottomLeft - leftHalf),
86+
Math.Max(0.0, cornerRadius.BottomLeft - bottomHalf));
87+
88+
// Adjust the width of the TopLeft and TopRight rectangles so that they are proportional to the width of the baseRect
89+
if (topLeftRect.Right > topRightRect.Left)
90+
{
91+
var newWidth = topLeftRect.Width / (topLeftRect.Width + topRightRect.Width) * baseRect.Width;
92+
topLeftRect = new Rect(topLeftRect.Location.X, topLeftRect.Location.Y, newWidth, topLeftRect.Height);
93+
topRightRect = new Rect(
94+
baseRect.Left + newWidth,
95+
topRightRect.Location.Y,
96+
Math.Max(0.0, baseRect.Width - newWidth),
97+
topRightRect.Height);
98+
}
99+
100+
// Adjust the height of the TopRight and BottomRight rectangles so that they are proportional to the height of the baseRect
101+
if (topRightRect.Bottom > bottomRightRect.Top)
102+
{
103+
var newHeight = topRightRect.Height / (topRightRect.Height + bottomRightRect.Height) *
104+
baseRect.Height;
105+
topRightRect = new Rect(topRightRect.Location.X, topRightRect.Location.Y, topRightRect.Width,
106+
newHeight);
107+
bottomRightRect = new Rect(
108+
bottomRightRect.Location.X,
109+
baseRect.Top + newHeight,
110+
bottomRightRect.Width,
111+
Math.Max(0.0, baseRect.Height - newHeight));
112+
}
113+
114+
// Adjust the width of the BottomLeft and BottomRight rectangles so that they are proportional to the width of the baseRect
115+
if (bottomRightRect.Left < bottomLeftRect.Right)
116+
{
117+
var newWidth = bottomLeftRect.Width / (bottomLeftRect.Width + bottomRightRect.Width) * baseRect.Width;
118+
bottomLeftRect = new Rect(bottomLeftRect.Location.X, bottomLeftRect.Location.Y, newWidth,
119+
bottomLeftRect.Height);
120+
bottomRightRect = new Rect(
121+
baseRect.Left + newWidth,
122+
bottomRightRect.Location.Y,
123+
Math.Max(0.0, baseRect.Width - newWidth),
124+
bottomRightRect.Height);
125+
}
126+
127+
// Adjust the height of the TopLeft and BottomLeft rectangles so that they are proportional to the height of the baseRect
128+
if (bottomLeftRect.Top < topLeftRect.Bottom)
129+
{
130+
var newHeight = topLeftRect.Height / (topLeftRect.Height + bottomLeftRect.Height) * baseRect.Height;
131+
topLeftRect = new Rect(topLeftRect.Location.X, topLeftRect.Location.Y, topLeftRect.Width, newHeight);
132+
bottomLeftRect = new Rect(
133+
bottomLeftRect.Location.X,
134+
baseRect.Top + newHeight,
135+
bottomLeftRect.Width,
136+
Math.Max(0.0, baseRect.Height - newHeight));
137+
}
138+
139+
var roundedRectGeometry = new StreamGeometry();
140+
141+
using var context = roundedRectGeometry.Open();
142+
// Begin from the Bottom of the TopLeft Arc and proceed clockwise
143+
context.BeginFigure(topLeftRect.BottomLeft, true, true);
144+
145+
// TopLeft Arc
146+
context.ArcTo(topLeftRect.TopRight, topLeftRect.Size, 0, false, SweepDirection.Clockwise, true, true);
147+
148+
// Top Line
149+
context.LineTo(topRightRect.TopLeft, true, true);
150+
151+
// TopRight Arc
152+
context.ArcTo(topRightRect.BottomRight, topRightRect.Size, 0, false, SweepDirection.Clockwise, true,
153+
true);
154+
155+
// Right Line
156+
context.LineTo(bottomRightRect.TopRight, true, true);
157+
158+
// BottomRight Arc
159+
context.ArcTo(bottomRightRect.BottomLeft, bottomRightRect.Size, 0, false, SweepDirection.Clockwise,
160+
true, true);
161+
162+
// Bottom Line
163+
context.LineTo(bottomLeftRect.BottomRight, true, true);
164+
165+
// BottomLeft Arc
166+
context.ArcTo(bottomLeftRect.TopLeft, bottomLeftRect.Size, 0, false, SweepDirection.Clockwise, true,
167+
true);
168+
169+
return roundedRectGeometry;
170+
}
171+
}
Lines changed: 79 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,81 @@
1-
<Window x:Class="DebitExpress.VatRelief.MainWindow"
2-
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3-
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4-
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5-
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
6-
xmlns:local="clr-namespace:DebitExpress.VatRelief"
7-
mc:Ignorable="d"
8-
Title="MainWindow" Height="450" Width="800">
1+
<ctrl:Window
2+
x:Class="DebitExpress.VatRelief.MainWindow"
3+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
4+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
5+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
6+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
7+
xmlns:ctrl="http://debitexpress.com/winfx/xaml/controls"
8+
xmlns:attached="http://debitexpress.com/winfx/xaml/attached-properties"
9+
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
10+
xmlns:dialogs="http://debitexpress.com/winfx/xaml/dialogs"
11+
mc:Ignorable="d"
12+
ResizeMode="NoResize"
13+
Title="DebitExpress VAT Relief"
14+
WindowStartupLocation="CenterScreen"
15+
ShowTitle="True"
16+
AllowDrop="True"
17+
TextElement.FontSize="13"
18+
TextElement.FontFamily="{StaticResource MaterialDesignFont}"
19+
TextElement.Foreground="{DynamicResource MaterialDesignBody}"
20+
attached:WindowElement.ExtendContentToNonClientArea="True"
21+
attached:WindowElement.SaveWindowPosition="True"
22+
Height="500" Width="350">
23+
<ctrl:Window.TopmostContent>
24+
<ctrl:SimplePanel>
25+
<materialDesign:Snackbar
26+
x:Name="ErrorSnackBar"
27+
Background="#F03F2B"
28+
Margin="10"
29+
HorizontalAlignment="Center"
30+
ActionButtonPlacement="Inline"
31+
Foreground="{DynamicResource PrimaryHueMidForegroundBrush}"
32+
ActionButtonStyle="{StaticResource ErrorSnackBarButtonStyle}" />
33+
<materialDesign:Snackbar
34+
x:Name="SnackBar"
35+
Margin="10"
36+
HorizontalAlignment="Center"
37+
ActionButtonPlacement="Inline"
38+
ActionButtonStyle="{StaticResource SnackBarButtonStyle}" />
39+
</ctrl:SimplePanel>
40+
</ctrl:Window.TopmostContent>
941
<Grid>
10-
42+
<StackPanel
43+
x:Name="DragIndicator"
44+
Margin="0,0,0,60"
45+
VerticalAlignment="Center"
46+
HorizontalAlignment="Center">
47+
<materialDesign:PackIcon
48+
x:Name="DragIcon"
49+
Width="100"
50+
Height="100"
51+
Kind="FileExcelOutline"
52+
HorizontalAlignment="Center" />
53+
<TextBlock
54+
x:Name="FileName"
55+
FontSize="18"
56+
TextAlignment="Center"
57+
Width="150"
58+
MaxHeight="50"
59+
TextWrapping="Wrap"
60+
TextTrimming="CharacterEllipsis"
61+
Text="Drag and drop excel file here" />
62+
</StackPanel>
63+
<StackPanel VerticalAlignment="Center" Margin="0,0,0,80">
64+
<Grid
65+
x:Name="Container"
66+
Width="300"
67+
Height="350"
68+
AllowDrop="True"
69+
Background="Transparent" />
70+
<Button
71+
x:Name="GenerateButton"
72+
Height="40"
73+
Width="160"
74+
IsEnabled="False"
75+
HorizontalAlignment="Center"
76+
materialDesign:ButtonAssist.CornerRadius="20"
77+
Style="{StaticResource MaterialDesignFlatMidBgButton}"
78+
Content="Generate" />
79+
</StackPanel>
1180
</Grid>
12-
</Window>
81+
</ctrl:Window>

0 commit comments

Comments
 (0)