Add project files.
This commit is contained in:
Generated
+13
@@ -0,0 +1,13 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Rider ignored files
|
||||
/modules.xml
|
||||
/contentModel.xml
|
||||
/projectSettingsUpdater.xml
|
||||
/.idea.TheXamlGuy.iml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding" addBOMForNewFiles="with BOM under Windows, with no BOM otherwise" />
|
||||
</project>
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="UserContentModel">
|
||||
<attachedFolders />
|
||||
<explicitIncludes />
|
||||
<explicitExcludes />
|
||||
</component>
|
||||
</project>
|
||||
@@ -0,0 +1,84 @@
|
||||
<Application
|
||||
x:Class="TheXamlGuy.App.WeddingDisplay.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:system="clr-namespace:System;assembly=mscorlib">
|
||||
<Application.Resources>
|
||||
|
||||
<FontFamily x:Key="ContentControlFontFamily">Segoe UI Variable Display</FontFamily>
|
||||
<FontFamily x:Key="AccentFontFamily">Signature Collection</FontFamily>
|
||||
<FontFamily x:Key="SemiLightContentControlFontFamily">Segoe UI Variable Display Semil</FontFamily>
|
||||
|
||||
<system:Double x:Key="CaptionTextBlockFontSize">12</system:Double>
|
||||
<system:Double x:Key="BodyTextBlockFontSize">14</system:Double>
|
||||
<system:Double x:Key="SubtitleTextBlockFontSize">20</system:Double>
|
||||
<system:Double x:Key="TitleTextBlockFontSize">28</system:Double>
|
||||
<system:Double x:Key="TitleLargeTextBlockFontSize">40</system:Double>
|
||||
<system:Double x:Key="DisplayTextBlockFontSize">68</system:Double>
|
||||
<system:Double x:Key="LargeDisplayTextBlockFontSize">120</system:Double>
|
||||
|
||||
<Style x:Key="BaseTextBlockStyle" TargetType="TextBlock">
|
||||
<Setter Property="FontFamily" Value="{StaticResource ContentControlFontFamily}" />
|
||||
<Setter Property="FontSize" Value="{StaticResource BodyTextBlockFontSize}" />
|
||||
<Setter Property="FontWeight" Value="SemiBold" />
|
||||
<Setter Property="TextTrimming" Value="CharacterEllipsis" />
|
||||
<Setter Property="TextWrapping" Value="Wrap" />
|
||||
<Setter Property="LineStackingStrategy" Value="MaxHeight" />
|
||||
</Style>
|
||||
|
||||
<Style
|
||||
x:Key="CaptionTextBlockStyle"
|
||||
BasedOn="{StaticResource BaseTextBlockStyle}"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="{StaticResource CaptionTextBlockFontSize}" />
|
||||
<Setter Property="FontWeight" Value="Normal" />
|
||||
</Style>
|
||||
|
||||
<Style
|
||||
x:Key="BodyTextBlockStyle"
|
||||
BasedOn="{StaticResource BaseTextBlockStyle}"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="FontWeight" Value="Normal" />
|
||||
</Style>
|
||||
|
||||
<Style
|
||||
x:Key="BodyStrongTextBlockStyle"
|
||||
BasedOn="{StaticResource BaseTextBlockStyle}"
|
||||
TargetType="TextBlock" />
|
||||
|
||||
<Style
|
||||
x:Key="SubtitleTextBlockStyle"
|
||||
BasedOn="{StaticResource BaseTextBlockStyle}"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="{StaticResource SubtitleTextBlockFontSize}" />
|
||||
</Style>
|
||||
|
||||
<Style
|
||||
x:Key="TitleTextBlockStyle"
|
||||
BasedOn="{StaticResource BaseTextBlockStyle}"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="{StaticResource TitleTextBlockFontSize}" />
|
||||
</Style>
|
||||
|
||||
<Style
|
||||
x:Key="TitleLargeTextBlockStyle"
|
||||
BasedOn="{StaticResource BaseTextBlockStyle}"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="{StaticResource TitleLargeTextBlockFontSize}" />
|
||||
</Style>
|
||||
|
||||
<Style
|
||||
x:Key="DisplayTextBlockStyle"
|
||||
BasedOn="{StaticResource BaseTextBlockStyle}"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="{StaticResource DisplayTextBlockFontSize}" />
|
||||
</Style>
|
||||
|
||||
<Style
|
||||
x:Key="LargeDisplayTextBlockStyle"
|
||||
BasedOn="{StaticResource BaseTextBlockStyle}"
|
||||
TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="{StaticResource LargeDisplayTextBlockFontSize}" />
|
||||
</Style>
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
@@ -0,0 +1,79 @@
|
||||
using System.Windows;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using TheXamlGuy.Framework.WPF;
|
||||
using WeddingBooth.Views;
|
||||
using System.Reflection;
|
||||
using System;
|
||||
using System.IO;
|
||||
using TheXamlGuy.Framework.Core;
|
||||
using TheXamlGuy.Framework.Microcontroller;
|
||||
using TheXamlGuy.Framework.Serial;
|
||||
using TheXamlGuy.Framework.Camera;
|
||||
using WeddingBooth.LifeCycles;
|
||||
|
||||
namespace TheXamlGuy.App.WeddingDisplay
|
||||
{
|
||||
public partial class App : Application
|
||||
{
|
||||
protected override async void OnStartup(StartupEventArgs args)
|
||||
{
|
||||
base.OnStartup(args);
|
||||
|
||||
IHost? host = new HostBuilder()
|
||||
.UseContentRoot(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "WeddingBooth"), true)
|
||||
.ConfigureAppConfiguration((context, configuration) =>
|
||||
{
|
||||
configuration.AddWritableJsonFile("Settings.json", false, true, writableConfiguration =>
|
||||
{
|
||||
writableConfiguration.AddDefaultFileStream(Assembly.GetExecutingAssembly().ExtractResource("Settings.json")!)
|
||||
.AddDefaultConfiguration<StartupConfiguration>("Startup")
|
||||
.AddDefaultConfiguration<NavigationConfiguration>("Navigation")
|
||||
.AddDefaultConfiguration<MicrocontrollerConfiguration>("Microcontroller")
|
||||
.AddDefaultConfiguration<RemoteCameraConfiguration>("RemoteCamera");
|
||||
});
|
||||
})
|
||||
.ConfigureMicrocontrollers((context, builder) =>
|
||||
{
|
||||
builder.Add<MicrocontrollerConfiguration, SerialLineReader, string, MicrocontrollerModuleJsonDeserializer>(context.Configuration.GetSection("Microcontroller"))
|
||||
.AddModule<CapactiveSensor>();
|
||||
})
|
||||
.ConfigureEvents(configuration =>
|
||||
{
|
||||
configuration.Add<SerialResponse<string>>().WithHandler(args => args);
|
||||
configuration.Add<Navigated<NavigationView, NavigationViewModel>>().WithHandler(args => args);
|
||||
configuration.Add<Captured>().WithHandler(args => args);
|
||||
})
|
||||
.ConfigureTemplates(configuration =>
|
||||
{
|
||||
configuration.Add<NavigationViewModel, NavigationView>("Navigation");
|
||||
configuration.Add<WelcomeViewModel, WelcomeView>("Welcome");
|
||||
configuration.Add<SeatingChartViewModel, SeatingChartView>("Seatings");
|
||||
configuration.Add<CameraViewModel, CameraView>("Camera");
|
||||
configuration.Add<GalleryViewModel, GalleryView>("Gallery");
|
||||
})
|
||||
.ConfigureCamera((context, builder) =>
|
||||
{
|
||||
builder.Add<RemoteCameraConfiguration>(context.Configuration.GetSection("RemoteCamera"));
|
||||
})
|
||||
.ConfigureServices(ConfigureServices)
|
||||
.Build();
|
||||
|
||||
await host.RunAsync();
|
||||
}
|
||||
|
||||
private void ConfigureServices(HostBuilderContext context, IServiceCollection services)
|
||||
{
|
||||
services.AddReqiredCore()
|
||||
.AddRequiredWpf()
|
||||
.AddHostedService<AppServices>()
|
||||
.AddSingleton<MainWindow>()
|
||||
.AddSingleton<MainWindowViewModel>()
|
||||
.AddConfiguration<StartupConfiguration>(context.Configuration.GetSection("Startup"))
|
||||
.AddConfiguration<NavigationConfiguration>(context.Configuration.GetSection("Navigation"))
|
||||
.AddConfiguration<MicrocontrollerConfiguration>(context.Configuration.GetSection("Microcontroller"))
|
||||
.AddConfiguration<RemoteCameraConfiguration>(context.Configuration.GetSection("RemoteCamera"))
|
||||
.RegisterHandlers();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using TheXamlGuy.Framework.Camera;
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace WeddingBooth.LifeCycles
|
||||
{
|
||||
public class CapturedHandler : IMediatorHandler<Captured>
|
||||
{
|
||||
private readonly IHostEnvironment hostEnvironment;
|
||||
|
||||
public CapturedHandler(IHostEnvironment hostEnvironment)
|
||||
{
|
||||
this.hostEnvironment = hostEnvironment;
|
||||
}
|
||||
|
||||
public void Handle(Captured request)
|
||||
{
|
||||
if (request.Photo is Bitmap bitmap)
|
||||
{
|
||||
using Bitmap writableBitmap = new(bitmap);
|
||||
string directory = Path.Combine(hostEnvironment.ContentRootPath, "Photos");
|
||||
Directory.CreateDirectory(directory);
|
||||
|
||||
ImageCodecInfo encoder = ImageCodecInfo.GetImageEncoders().First(x => x.FormatID == ImageFormat.Jpeg.Guid);
|
||||
EncoderParameters encoderParameters = new() { Param = new[] { new EncoderParameter(Encoder.Quality, 100L) } };
|
||||
writableBitmap.Save($"{directory}\\{DateTime.Now:MMddyyyy-HHmmss}.jpg", encoder, encoderParameters);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace WeddingBooth.LifeCycles
|
||||
{
|
||||
public class NavigationConfiguration : List<string>
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using TheXamlGuy.Framework.Core;
|
||||
using TheXamlGuy.Framework.WPF;
|
||||
using WeddingBooth.Views;
|
||||
|
||||
namespace WeddingBooth.LifeCycles
|
||||
{
|
||||
|
||||
public class NavigationNavigatedHandler : IMediatorHandler<Navigated<NavigationView, NavigationViewModel>>
|
||||
{
|
||||
private readonly NavigationConfiguration configuration;
|
||||
|
||||
public NavigationNavigatedHandler(NavigationConfiguration configuration)
|
||||
{
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
public void Handle(Navigated<NavigationView, NavigationViewModel> request)
|
||||
{
|
||||
foreach (string navigation in configuration)
|
||||
{
|
||||
switch (navigation)
|
||||
{
|
||||
case "Welcome":
|
||||
request.DataContext?.Add<WelcomeViewModel>();
|
||||
break;
|
||||
case "SeatingChart":
|
||||
request.DataContext?.Add<SeatingChartViewModel>();
|
||||
break;
|
||||
case "Camera":
|
||||
request.DataContext?.Add<CameraViewModel>();
|
||||
break;
|
||||
case "Gallery":
|
||||
request.DataContext?.Add<GalleryViewModel>();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using System.Linq;
|
||||
using System.Windows;
|
||||
using TheXamlGuy.Framework.Core;
|
||||
using WeddingBooth.Views;
|
||||
using WpfScreenHelper;
|
||||
|
||||
namespace WeddingBooth.LifeCycles
|
||||
{
|
||||
public class StartedHandler : IMediatorHandler<Started>
|
||||
{
|
||||
private readonly StartupConfiguration configuration;
|
||||
private readonly MainWindow window;
|
||||
private readonly MainWindowViewModel viewModel;
|
||||
|
||||
public StartedHandler(StartupConfiguration configuration,
|
||||
MainWindow window,
|
||||
MainWindowViewModel viewModel)
|
||||
{
|
||||
this.configuration = configuration;
|
||||
this.window = window;
|
||||
this.viewModel = viewModel;
|
||||
}
|
||||
|
||||
public void Handle(Started request)
|
||||
{
|
||||
window.DataContext = viewModel;
|
||||
window.Show();
|
||||
|
||||
if (configuration.Display is string display)
|
||||
{
|
||||
Screen? screen = Screen.AllScreens.FirstOrDefault(x => x.DeviceName.Contains(display, System.StringComparison.InvariantCultureIgnoreCase)) ?? Screen.AllScreens.FirstOrDefault();
|
||||
if (screen is not null)
|
||||
{
|
||||
window.Left = screen.Bounds.Left;
|
||||
window.Top = screen.Bounds.Top;
|
||||
window.Width = screen.Bounds.Width;
|
||||
window.Height = screen.Bounds.Height;
|
||||
}
|
||||
|
||||
if (configuration.FullScreen)
|
||||
{
|
||||
window.WindowState = WindowState.Maximized;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace WeddingBooth.LifeCycles
|
||||
{
|
||||
public class StartupConfiguration
|
||||
{
|
||||
public bool FullScreen { get; set; }
|
||||
|
||||
public string? Display { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace WeddingBooth.LifeCycles
|
||||
{
|
||||
public class Table
|
||||
{
|
||||
public string? Name { get; set; }
|
||||
|
||||
public List<string> Guests { get; set; } = new List<string>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Globalization;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Media.Imaging;
|
||||
using TheXamlGuy.Framework.Camera;
|
||||
using TheXamlGuy.UI.WPF;
|
||||
|
||||
namespace WeddingBooth.Markups
|
||||
{
|
||||
public class CapturedConverter : ValueConverter<Captured, BitmapSource>
|
||||
{
|
||||
[DllImport("gdi32.dll")]
|
||||
private static extern bool DeleteObject(IntPtr hObject);
|
||||
|
||||
protected override BitmapSource? ConvertTo(Captured value, Type? targetType, object? parameter, CultureInfo? culture)
|
||||
{
|
||||
if (value.Photo is Bitmap bitmap)
|
||||
{
|
||||
IntPtr handle = bitmap.GetHbitmap();
|
||||
BitmapSource image = Imaging.CreateBitmapSourceFromHBitmap(handle, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromWidthAndHeight(value.Width, value.Height));
|
||||
|
||||
DeleteObject(handle);
|
||||
return image;
|
||||
}
|
||||
|
||||
return default;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
using System.Windows;
|
||||
|
||||
[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]
|
||||
@@ -0,0 +1,140 @@
|
||||
{
|
||||
"Startup": {
|
||||
"Display": "DISPLAY2",
|
||||
"FullScreen": true
|
||||
},
|
||||
"Navigation": [
|
||||
"Welcome",
|
||||
"Camera"
|
||||
],
|
||||
"Microcontroller": {
|
||||
"PortName": "COM7",
|
||||
"BaudRate": 9600
|
||||
},
|
||||
"RemoteCamera": {
|
||||
"Name": "Test"
|
||||
},
|
||||
"SeatingChart": [
|
||||
{
|
||||
"Name": "one",
|
||||
"Guests": [
|
||||
"Lynne Lamb",
|
||||
"Peter Lamb",
|
||||
"Liam Lamb",
|
||||
"Ryan Lamb",
|
||||
"Mabel Lamb",
|
||||
"Hayley Lamb",
|
||||
"Nikki Rushton",
|
||||
"John Clark",
|
||||
"Rebecca Days"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "two",
|
||||
"Guests": [
|
||||
"Pauline Clough",
|
||||
"John Clough",
|
||||
"Ava Lamb-Clark",
|
||||
"Nathan Clark",
|
||||
"Emma Cunnington",
|
||||
"George Clough",
|
||||
"Vera Clough",
|
||||
"Margaret Clayton"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "three",
|
||||
"Guests": [
|
||||
"Alex Clark",
|
||||
"Anita Chan",
|
||||
"Trevor Million",
|
||||
"Lisa Iveson",
|
||||
"Brian Clark",
|
||||
"Brian Clark",
|
||||
"Emma Lee",
|
||||
"Lisa Clark",
|
||||
"Siân Laura Davies"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "four",
|
||||
"Guests": [
|
||||
"Michael Lamb",
|
||||
"Lesley Lamb",
|
||||
"Ken Clough",
|
||||
"Kathryn Dodds",
|
||||
"Patricia Clough",
|
||||
"Ann Peck",
|
||||
"Greg Peck"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "five",
|
||||
"Guests": [
|
||||
"Olive Shorten",
|
||||
"Lynne Shorten",
|
||||
"Joyce Clark",
|
||||
"Alison Clarke",
|
||||
"Jim Clarke",
|
||||
"Scott Thirlaway",
|
||||
"Kevin McVittie",
|
||||
"Katharyn Church",
|
||||
"Eve Clark",
|
||||
"Grace Clark"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "six",
|
||||
"Guests": [
|
||||
"Tom Parker",
|
||||
"Amy Parker",
|
||||
"Stephen Coates",
|
||||
"Ashley Coates",
|
||||
"Callie Coates",
|
||||
"Ellie Coates",
|
||||
"Colin Armstrong",
|
||||
"Kelly Shearsmith",
|
||||
"Jay Evans"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "seven",
|
||||
"Guests": [
|
||||
"Kelly Taylor",
|
||||
"Phillip Taylor",
|
||||
"Lucas Taylor",
|
||||
"Lana Taylor",
|
||||
"Christopher Lamb",
|
||||
"Emma Hunter",
|
||||
"Tommy",
|
||||
"Livinya"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "eight",
|
||||
"Guests": [
|
||||
"Harry Clough",
|
||||
"Jack Clough",
|
||||
"Corey Derbyshire",
|
||||
"Shauna Gallon",
|
||||
"Lora Johnstone",
|
||||
"Steven Clark",
|
||||
"Michael Clarke",
|
||||
"Nicole Wright"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Name": "nine",
|
||||
"Guests": [
|
||||
"Vikki Finnigan",
|
||||
"Logan Finnigan",
|
||||
"Gemma Carr",
|
||||
"Alysha Carr",
|
||||
"Ross Finnigan",
|
||||
"Jemma Clark",
|
||||
"Lily-Rose Goddard",
|
||||
"David Ford"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
<UserControl
|
||||
x:Class="WeddingBooth.Views.CameraView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:camera="clr-namespace:TheXamlGuy.Framework.Camera;assembly=Camera"
|
||||
xmlns:markup="clr-namespace:WeddingBooth.Markups"
|
||||
x:Name="Camera"
|
||||
VisualStateExtension.IsStateTriggersAttached="True">
|
||||
<UserControl.Resources>
|
||||
<BindingProxy x:Key="BindingProxy" DataContext="{Binding}" />
|
||||
<BindingProxy x:Key="CountdownProxy" DataContext="{Binding ElementName=Countdown}" />
|
||||
<BindingProxy x:Key="CameraProxy" DataContext="{Binding ElementName=Camera}" />
|
||||
<BindingProxy x:Key="ImageProxy" DataContext="{Binding ElementName=Image}" />
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<CameraPreview x:Name="CameraPreview">
|
||||
<CameraPreview.LayoutTransform>
|
||||
<RotateTransform Angle="90" />
|
||||
</CameraPreview.LayoutTransform>
|
||||
</CameraPreview>
|
||||
<ProgressRing
|
||||
x:Name="ProgressRing"
|
||||
Width="500"
|
||||
Height="500"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
IsActive="True"
|
||||
IsIndeterminate="True"
|
||||
Opacity="0"
|
||||
Thickness="12" />
|
||||
<Countdown
|
||||
x:Name="Countdown"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Completed="{Composite {State {Binding Source={StaticResource CameraProxy}, Path=DataContext},
|
||||
Completed},
|
||||
{ChangeProperty {Binding},
|
||||
CanCapture,
|
||||
false},
|
||||
{Invoke Capture}}"
|
||||
CountdownIdentifier="FiveSecond"
|
||||
FontFamily="{StaticResource ContentControlFontFamily}"
|
||||
FontSize="300"
|
||||
Foreground="White"
|
||||
TextBlock.FontWeight="Thin" />
|
||||
<Image
|
||||
x:Name="Image"
|
||||
Opacity="0"
|
||||
Stretch="Fill">
|
||||
<Image.LayoutTransform>
|
||||
<RotateTransform Angle="90" />
|
||||
</Image.LayoutTransform>
|
||||
</Image>
|
||||
<Border
|
||||
x:Name="FlashOverlay"
|
||||
Background="White"
|
||||
Opacity="0"
|
||||
RenderTransformOrigin="0.5,0.5">
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
FontFamily="{StaticResource AccentFontFamily}"
|
||||
FontSize="288"
|
||||
Text="Smile!" />
|
||||
<Border.RenderTransform>
|
||||
<ScaleTransform x:Name="ScaleTransform" />
|
||||
</Border.RenderTransform>
|
||||
</Border>
|
||||
</Grid>
|
||||
<Interaction.XamlEventAggregator>
|
||||
<XamlEventAggregator EventAggregator="{Binding Source={StaticResource BindingProxy}, Path=DataContext.EventAggregator}">
|
||||
<EventSubscriber Invoked="{Composite {ChangeProperty {Binding Source={StaticResource ImageProxy}, Path=DataContext}, Source, {EventParameter Invoked, {markup:CapturedConverter}}}, {State {Binding Source={StaticResource CameraProxy}, Path=DataContext}, Captured}, {ChangeProperty {Binding}, CanCapture, true}}" Type="{x:Type camera:Captured}" />
|
||||
</XamlEventAggregator>
|
||||
</Interaction.XamlEventAggregator>
|
||||
<Interaction.InteractiveFrame>
|
||||
<InteractiveFrame EventAggregator="{Binding Source={StaticResource BindingProxy}, Path=DataContext.EventAggregator}">
|
||||
<InteractiveFrameButton Invoked="{Composite {Condition {Binding CanCapture}, {Invoke Start, BindingTarget={Binding Source={StaticResource CountdownProxy}, Path=DataContext}}, {State {Binding Source={StaticResource CameraProxy}, Path=DataContext}, Started}}}" Placement="Top" />
|
||||
</InteractiveFrame>
|
||||
</Interaction.InteractiveFrame>
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="PhotoStates">
|
||||
<VisualState x:Name="Started">
|
||||
<Storyboard>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ProgressRing" Storyboard.TargetProperty="(UIElement.Opacity)">
|
||||
<DiscreteDoubleKeyFrame KeyTime="00:00:00" Value="1" />
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Completed">
|
||||
<Storyboard>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ScaleTransform" Storyboard.TargetProperty="ScaleX">
|
||||
<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="2.05" />
|
||||
<SplineDoubleKeyFrame
|
||||
KeySpline="0,0,0,1"
|
||||
KeyTime="00:00:00.250"
|
||||
Value="1.0" />
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ScaleTransform" Storyboard.TargetProperty="ScaleY">
|
||||
<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="2.05" />
|
||||
<SplineDoubleKeyFrame
|
||||
KeySpline="0,0,0,1"
|
||||
KeyTime="00:00:00.250"
|
||||
Value="1.0" />
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="FlashOverlay" Storyboard.TargetProperty="(UIElement.Opacity)">
|
||||
<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="0.0" />
|
||||
<LinearDoubleKeyFrame KeyTime="00:00:00.167" Value="1.0" />
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ProgressRing" Storyboard.TargetProperty="(UIElement.Opacity)">
|
||||
<DiscreteDoubleKeyFrame KeyTime="00:00:00" Value="0" />
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
<VisualState x:Name="Captured">
|
||||
<Storyboard>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="Image" Storyboard.TargetProperty="(UIElement.Opacity)">
|
||||
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="1" />
|
||||
<SplineDoubleKeyFrame KeyTime="00:00:04" Value="1" />
|
||||
<SplineDoubleKeyFrame KeyTime="00:00:04.168" Value="0" />
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ScaleTransform" Storyboard.TargetProperty="ScaleX">
|
||||
<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="1.0" />
|
||||
<SplineDoubleKeyFrame
|
||||
KeySpline="0,0,0,1"
|
||||
KeyTime="00:00:00.167"
|
||||
Value="1.05" />
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="ScaleTransform" Storyboard.TargetProperty="ScaleY">
|
||||
<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="1.0" />
|
||||
<SplineDoubleKeyFrame
|
||||
KeySpline="0,0,0,1"
|
||||
KeyTime="00:00:00.167"
|
||||
Value="1.05" />
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="FlashOverlay" Storyboard.TargetProperty="(UIElement.Opacity)">
|
||||
<DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="1.0" />
|
||||
<LinearDoubleKeyFrame KeyTime="00:00:00.083" Value="0.0" />
|
||||
</DoubleAnimationUsingKeyFrames>
|
||||
</Storyboard>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,16 @@
|
||||
|
||||
namespace WeddingBooth.Views;
|
||||
|
||||
public partial class CameraView
|
||||
{
|
||||
public CameraView()
|
||||
{
|
||||
InitializeComponent();
|
||||
Loaded += CameraView_Loaded;
|
||||
}
|
||||
|
||||
private void CameraView_Loaded(object sender, System.Windows.RoutedEventArgs e)
|
||||
{
|
||||
CameraPreview.StartAsync();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
using TheXamlGuy.Framework.Camera;
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace WeddingBooth.Views;
|
||||
|
||||
public class CameraViewModel : ObservableViewModel
|
||||
{
|
||||
public CameraViewModel(IPropertyBuilder propertyBuilder,
|
||||
IEventAggregator eventAggregator,
|
||||
IServiceFactory serviceFactory,
|
||||
IDisposer disposer) : base(propertyBuilder, eventAggregator, serviceFactory, disposer)
|
||||
{
|
||||
}
|
||||
|
||||
public bool CanCapture { get; set; } = true;
|
||||
|
||||
public void Capture()
|
||||
{
|
||||
EventAggregator.Publish<Capture>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<UserControl x:Class="WeddingBooth.Views.GalleryView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:local="clr-namespace:WeddingBooth.Views"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
FontSize="100"
|
||||
Text="GALLERY VIEW" />
|
||||
</UserControl>
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace WeddingBooth.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for GalleryView.xaml
|
||||
/// </summary>
|
||||
public partial class GalleryView : UserControl
|
||||
{
|
||||
public GalleryView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace WeddingBooth.Views;
|
||||
|
||||
public class GalleryViewModel : ObservableViewModel
|
||||
{
|
||||
public GalleryViewModel(IPropertyBuilder propertyBuilder,
|
||||
IEventAggregator eventAggregator,
|
||||
IServiceFactory serviceFactory,
|
||||
IDisposer disposer) : base(propertyBuilder, eventAggregator, serviceFactory, disposer)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace WeddingBooth.Views;
|
||||
|
||||
public class GuestViewModel : ObservableViewModel
|
||||
{
|
||||
public GuestViewModel(IPropertyBuilder propertyBuilder,
|
||||
IEventAggregator eventAggregator,
|
||||
IServiceFactory serviceFactory,
|
||||
IDisposer disposer,
|
||||
string name) : base(propertyBuilder, eventAggregator, serviceFactory, disposer)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<Window
|
||||
x:Class="WeddingBooth.Views.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Content="{Route {Binding Route},
|
||||
Root}"
|
||||
Loaded="{Navigate {Binding EventAggregator},
|
||||
Root,
|
||||
Navigation}"
|
||||
WindowStyle="None" />
|
||||
@@ -0,0 +1,23 @@
|
||||
using System.Linq;
|
||||
|
||||
namespace WeddingBooth.Views;
|
||||
|
||||
public partial class MainWindow
|
||||
{
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
//var DeviceManager = new CameraDeviceManager();
|
||||
//DeviceManager.ConnectToCamera();
|
||||
|
||||
//DeviceManager.AddDevice(d[3].Connect("192.168.1.1"));
|
||||
|
||||
//DeviceManager.CameraConnected += DeviceManager_CameraConnected;
|
||||
|
||||
//DeviceManager.SelectedCameraDevice.PhotoCaptured += SelectedCameraDevice_PhotoCaptured;
|
||||
|
||||
//DeviceManager.SelectedCameraDevice.CapturePhoto();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using TheXamlGuy.Framework.Core;
|
||||
using TheXamlGuy.Framework.WPF;
|
||||
|
||||
namespace WeddingBooth.Views;
|
||||
|
||||
public class MainWindowViewModel : ObservableViewModel
|
||||
{
|
||||
public MainWindowViewModel(IPropertyBuilder propertyBuilder,
|
||||
IEventAggregator eventAggregator,
|
||||
IServiceFactory serviceFactory,
|
||||
IDisposer disposer,
|
||||
IRoute route) : base(propertyBuilder, eventAggregator, serviceFactory, disposer)
|
||||
{
|
||||
Route = route;
|
||||
}
|
||||
|
||||
public IRoute Route { get; }
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<UserControl
|
||||
x:Class="WeddingBooth.Views.NavigationView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<UserControl.Resources>
|
||||
<BindingProxy x:Key="BindingProxy" DataContext="{Binding}" />
|
||||
<BindingProxy x:Key="FlipViewProxy" DataContext="{Binding ElementName=FlipView}" />
|
||||
</UserControl.Resources>
|
||||
<FlipView
|
||||
x:Name="FlipView"
|
||||
ItemContainerTemplateSelector="{Binding TemplateSelector}"
|
||||
ItemsSource="{Binding}"
|
||||
UsesItemContainerTemplateSelector="True" />
|
||||
<Interaction.InteractiveFrame>
|
||||
<InteractiveFrame EventAggregator="{Binding Source={StaticResource BindingProxy}, Path=DataContext.EventAggregator}">
|
||||
<InteractiveFrameButton Invoked="{Invoke Previous, BindingTarget={Binding Source={StaticResource FlipViewProxy}, Path=DataContext}}" Placement="Left" />
|
||||
<InteractiveFrameButton Invoked="{Invoke Next, BindingTarget={Binding Source={StaticResource FlipViewProxy}, Path=DataContext}}" Placement="Right" />
|
||||
</InteractiveFrame>
|
||||
</Interaction.InteractiveFrame>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace WeddingBooth.Views;
|
||||
|
||||
public partial class NavigationView
|
||||
{
|
||||
public NavigationView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace WeddingBooth.Views;
|
||||
|
||||
public class NavigationViewModel : ObservableViewModelCollection<IObservableViewModel>
|
||||
{
|
||||
public NavigationViewModel(IPropertyBuilder propertyBuilder,
|
||||
IEventAggregator eventAggregator,
|
||||
IServiceFactory serviceFactory,
|
||||
IDisposer disposer,
|
||||
ITemplateSelector templateSelector) : base(propertyBuilder, eventAggregator, serviceFactory, disposer)
|
||||
{
|
||||
TemplateSelector = templateSelector;
|
||||
}
|
||||
|
||||
public ITemplateSelector TemplateSelector { get; }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace WeddingBooth.LifeCycles
|
||||
{
|
||||
public class SeatingChartConfiguration : List<Table>
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using TheXamlGuy.Framework.Core;
|
||||
using TheXamlGuy.Framework.WPF;
|
||||
using WeddingBooth.Views;
|
||||
|
||||
namespace WeddingBooth.LifeCycles
|
||||
{
|
||||
public class SeatingChartNavigatedHandler : IMediatorHandler<Navigated<SeatingChartView, SeatingChartViewModel>>
|
||||
{
|
||||
private readonly SeatingChartConfiguration configuration;
|
||||
|
||||
public SeatingChartNavigatedHandler(SeatingChartConfiguration configuration)
|
||||
{
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
public void Handle(Navigated<SeatingChartView, SeatingChartViewModel> request)
|
||||
{
|
||||
foreach (Table table in configuration)
|
||||
{
|
||||
if(request.DataContext?.Add(table.Name) is TableViewModel tableViewModel)
|
||||
{
|
||||
foreach (string guest in table.Guests)
|
||||
{
|
||||
tableViewModel.Add(guest);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<UserControl
|
||||
x:Class="WeddingBooth.Views.SeatingChartView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Margin="40,40,16,16">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="18" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
HorizontalAlignment="Center"
|
||||
FontFamily="{StaticResource AccentFontFamily}"
|
||||
FontWeight="Normal"
|
||||
Style="{StaticResource LargeDisplayTextBlockStyle}"
|
||||
Text="find your seat" />
|
||||
<ItemsControl
|
||||
Grid.Row="2"
|
||||
ItemTemplateSelector="{Binding TemplateSelector}"
|
||||
ItemsSource="{Binding}">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<UniformGrid Columns="3" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
</ItemsControl>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,11 @@
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace WeddingBooth.Views;
|
||||
|
||||
public partial class SeatingChartView : UserControl
|
||||
{
|
||||
public SeatingChartView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace WeddingBooth.Views;
|
||||
|
||||
public class SeatingChartViewModel : ObservableViewModelCollection<TableViewModel>
|
||||
{
|
||||
public SeatingChartViewModel(IPropertyBuilder propertyBuilder,
|
||||
IEventAggregator eventAggregator,
|
||||
IServiceFactory serviceFactory,
|
||||
IDisposer disposer,
|
||||
ITemplateSelector templateSelector) : base(propertyBuilder, eventAggregator, serviceFactory, disposer)
|
||||
{
|
||||
TemplateSelector = templateSelector;
|
||||
}
|
||||
|
||||
public ITemplateSelector TemplateSelector { get; }
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<UserControl
|
||||
x:Class="WeddingBooth.Views.TableView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<UserControl.Resources>
|
||||
<SolidColorBrush x:Key="BorderBrush" Color="#FF8C8C8C" />
|
||||
</UserControl.Resources>
|
||||
<Border
|
||||
Margin="0,0,24,24"
|
||||
BorderBrush="{StaticResource BorderBrush}"
|
||||
BorderThickness="1">
|
||||
<Grid Margin="24">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock
|
||||
Grid.Row="0"
|
||||
HorizontalAlignment="Center"
|
||||
FontFamily="{StaticResource AccentFontFamily}"
|
||||
FontWeight="Normal"
|
||||
FontSize="92"
|
||||
Margin="0 0 0 -28"
|
||||
Text="{Binding Name}" />
|
||||
<ItemsControl
|
||||
Grid.Row="2"
|
||||
HorizontalAlignment="Center"
|
||||
ItemsSource="{Binding}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock
|
||||
Margin="0,0,0,2"
|
||||
FontWeight="Thin"
|
||||
Style="{StaticResource SubtitleTextBlockStyle}"
|
||||
Text="{Binding Name}"
|
||||
TextAlignment="Center" />
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</Grid>
|
||||
</Border>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,9 @@
|
||||
namespace WeddingBooth.Views;
|
||||
|
||||
public partial class TableView
|
||||
{
|
||||
public TableView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace WeddingBooth.Views;
|
||||
|
||||
public class TableViewModel : ObservableViewModelCollection<GuestViewModel>
|
||||
{
|
||||
public TableViewModel(IPropertyBuilder propertyBuilder,
|
||||
IEventAggregator eventAggregator,
|
||||
IServiceFactory serviceFactory,
|
||||
IDisposer disposer,
|
||||
string name) : base(propertyBuilder, eventAggregator, serviceFactory, disposer)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<UserControl
|
||||
x:Class="WeddingBooth.Views.WelcomeView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<TextBlock
|
||||
Margin="0,-0,0,-60"
|
||||
HorizontalAlignment="Center"
|
||||
FontFamily="{StaticResource AccentFontFamily}"
|
||||
FontSize="288"
|
||||
FontWeight="Light"
|
||||
Text="Welcome" />
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
FontStretch="ExtraExpanded"
|
||||
FontWeight="Thin"
|
||||
Style="{StaticResource TitleTextBlockStyle}"
|
||||
Text="TO OUR WEDDING" />
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
FontStretch="ExtraExpanded"
|
||||
FontWeight="Thin"
|
||||
Style="{StaticResource DisplayTextBlockStyle}"
|
||||
Text="LAURA & DANIEL" />
|
||||
<TextBlock
|
||||
Margin="0,0,0,12"
|
||||
HorizontalAlignment="Center"
|
||||
FontStretch="ExtraExpanded"
|
||||
FontWeight="Thin"
|
||||
Style="{StaticResource TitleTextBlockStyle}"
|
||||
Text="OCTOBER 6ᵗʰ, 2022" />
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
FontStretch="ExtraExpanded"
|
||||
FontWeight="Thin"
|
||||
Style="{StaticResource TitleTextBlockStyle}"
|
||||
Text="LET US MAKE MEMORIES OF OUR SPECIAL EVENING"
|
||||
TextAlignment="Center" />
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace WeddingBooth.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for WelcomeView.xaml
|
||||
/// </summary>
|
||||
public partial class WelcomeView : UserControl
|
||||
{
|
||||
public WelcomeView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace WeddingBooth.Views;
|
||||
|
||||
public class WelcomeViewModel : ObservableViewModel
|
||||
{
|
||||
public WelcomeViewModel(IPropertyBuilder propertyBuilder,
|
||||
IEventAggregator eventAggregator,
|
||||
IServiceFactory serviceFactory,
|
||||
IDisposer disposer) : base(propertyBuilder, eventAggregator, serviceFactory, disposer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net6.0-windows10.0.18362.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<UseWPF>true</UseWPF>
|
||||
<Platforms>AnyCPU;x64</Platforms>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="Settings.json" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Settings.json" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.0-rc.2.22472.3" />
|
||||
<PackageReference Include="WpfScreenHelper" Version="2.1.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Framework\Camera\Camera.csproj" />
|
||||
<ProjectReference Include="..\..\Framework\Core\Core.csproj" />
|
||||
<ProjectReference Include="..\..\Framework\Microcontroller\Microcontroller.csproj" />
|
||||
<ProjectReference Include="..\..\Framework\Serial\Serial.csproj" />
|
||||
<ProjectReference Include="..\..\Framework\WPF\WPF.csproj" />
|
||||
<ProjectReference Include="..\..\Media\Capture\Capture.csproj" />
|
||||
<ProjectReference Include="..\..\UI\WPF.Controls\WPF.Controls.csproj" />
|
||||
<ProjectReference Include="..\..\UI\WPF\WPF.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,454 @@
|
||||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# Tye
|
||||
.tye/
|
||||
|
||||
# ASP.NET Scaffolding
|
||||
ScaffoldingReadMe.txt
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Coverlet is a free, cross platform Code Coverage Tool
|
||||
coverage*.json
|
||||
coverage*.xml
|
||||
coverage*.info
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
|
||||
##
|
||||
## Visual studio for Mac
|
||||
##
|
||||
|
||||
|
||||
# globs
|
||||
Makefile.in
|
||||
*.userprefs
|
||||
*.usertasks
|
||||
config.make
|
||||
config.status
|
||||
aclocal.m4
|
||||
install-sh
|
||||
autom4te.cache/
|
||||
*.tar.gz
|
||||
tarballs/
|
||||
test-results/
|
||||
|
||||
# Mac bundle stuff
|
||||
*.dmg
|
||||
*.app
|
||||
|
||||
# content below from: https://github.com/github/gitignore/blob/master/Global/macOS.gitignore
|
||||
# General
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
|
||||
# Icon must end with two \r
|
||||
Icon
|
||||
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear in the root of a volume
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
|
||||
# Directories potentially created on remote AFP share
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
|
||||
# content below from: https://github.com/github/gitignore/blob/master/Global/Windows.gitignore
|
||||
# Windows thumbnail cache files
|
||||
Thumbs.db
|
||||
ehthumbs.db
|
||||
ehthumbs_vista.db
|
||||
|
||||
# Dump file
|
||||
*.stackdump
|
||||
|
||||
# Folder config file
|
||||
[Dd]esktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
# JetBrains Rider
|
||||
.idea/
|
||||
*.sln.iml
|
||||
|
||||
##
|
||||
## Visual Studio Code
|
||||
##
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
@@ -0,0 +1,75 @@
|
||||
<Application
|
||||
x:Class="Builder.App"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:style="using:FluentAvalonia.Styling">
|
||||
<Application.Styles>
|
||||
<style:FluentAvaloniaTheme />
|
||||
<Style Selector="Button.Icon">
|
||||
<Setter Property="FontSize" Value="16" />
|
||||
<Setter Property="FontFamily" Value="{StaticResource SymbolThemeFontFamily}" />
|
||||
<Setter Property="MinHeight" Value="{StaticResource PaneToggleButtonHeight}" />
|
||||
<Setter Property="MinWidth" Value="{StaticResource PaneToggleButtonWidth}" />
|
||||
<Setter Property="Padding" Value="4,2" />
|
||||
<Setter Property="HorizontalAlignment" Value="Center" />
|
||||
<Setter Property="VerticalAlignment" Value="Top" />
|
||||
<Setter Property="HorizontalContentAlignment" Value="Center" />
|
||||
<Setter Property="VerticalContentAlignment" Value="Center" />
|
||||
<Setter Property="Background" Value="{DynamicResource NavigationViewItemBackground}" />
|
||||
<Setter Property="Foreground" Value="{DynamicResource NavigationViewItemForeground}" />
|
||||
<Setter Property="BorderThickness" Value="{DynamicResource NavigationViewToggleBorderThickness}" />
|
||||
<Setter Property="Template">
|
||||
<ControlTemplate>
|
||||
<Border
|
||||
Name="LayoutRoot"
|
||||
Height="{TemplateBinding MinHeight}"
|
||||
Margin="{TemplateBinding Padding}"
|
||||
HorizontalAlignment="Stretch"
|
||||
Background="{TemplateBinding Background}"
|
||||
CornerRadius="{DynamicResource ControlCornerRadius}">
|
||||
<Grid Name="ContentRoot" ColumnDefinitions="Auto,*">
|
||||
<Border Width="{TemplateBinding MinWidth}">
|
||||
<Viewbox
|
||||
Name="IconHost"
|
||||
Width="16"
|
||||
Height="16"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
|
||||
<ContentPresenter
|
||||
Name="ContentPresenter"
|
||||
VerticalContentAlignment="Center"
|
||||
Content="{TemplateBinding Content}"
|
||||
FontSize="{TemplateBinding FontSize}" />
|
||||
</Viewbox>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter>
|
||||
<Style Selector="^:pointerover">
|
||||
<Style Selector="^ /template/ Border#LayoutRoot">
|
||||
<Setter Property="Background" Value="{DynamicResource NavigationViewButtonBackgroundPointerOver}" />
|
||||
</Style>
|
||||
<Style Selector="^ /template/ ContentPresenter#ContentPresenter">
|
||||
<Setter Property="Foreground" Value="{DynamicResource NavigationViewButtonForegroundPointerOver}" />
|
||||
</Style>
|
||||
</Style>
|
||||
<Style Selector="^:pressed">
|
||||
<Style Selector="^ /template/ Border#LayoutRoot">
|
||||
<Setter Property="Background" Value="{DynamicResource NavigationViewButtonBackgroundPressed}" />
|
||||
</Style>
|
||||
<Style Selector="^ /template/ ContentPresenter#ContentPresenter">
|
||||
<Setter Property="Foreground" Value="{DynamicResource NavigationViewButtonForegroundPressed}" />
|
||||
</Style>
|
||||
</Style>
|
||||
<Style Selector="^:disabled">
|
||||
<Style Selector="^ /template/ Border#LayoutRoot">
|
||||
<Setter Property="Background" Value="{DynamicResource NavigationViewButtonBackgroundDisabled}" />
|
||||
</Style>
|
||||
<Style Selector="^ /template/ ContentPresenter#ContentPresenter">
|
||||
<Setter Property="Foreground" Value="{DynamicResource NavigationViewButtonForegroundDisabled}" />
|
||||
</Style>
|
||||
</Style>
|
||||
</Style>
|
||||
</Application.Styles>
|
||||
</Application>
|
||||
@@ -0,0 +1,53 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using PropertyChanged;
|
||||
using System;
|
||||
using System.IO;
|
||||
using TheXamlGuy.Framework.Avalonia;
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace Builder
|
||||
{
|
||||
[DoNotNotify]
|
||||
public partial class App : Application
|
||||
{
|
||||
public override void Initialize()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
}
|
||||
|
||||
public override async void OnFrameworkInitializationCompleted()
|
||||
{
|
||||
IHost? host = new HostBuilder()
|
||||
.UseContentRoot(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData), "Builder"), true)
|
||||
.ConfigureTemplates(configuration =>
|
||||
{
|
||||
configuration.Add<MainWindowViewModel, MainWindow>();
|
||||
configuration.Add<MainViewModel, MainView>("Main");
|
||||
configuration.Add<ProjectConfigurationViewModel, ProjectConfigurationView>("ProjectConfiguration");
|
||||
configuration.Add<StartProjectConfigurationViewModel, StartProjectConfigurationView>("StartProjectConfiguration");
|
||||
configuration.Add<CreateProjectConfigurationViewModel, CreateProjectConfigurationView>("CreateProjectConfiguration");
|
||||
configuration.Add<ExistingProjectConfigurationViewModel, ExistingProjectConfigurationView>("ExistingProjectConfiguration");
|
||||
configuration.Add<ProjectViewModel, ProjectView>("Project");
|
||||
configuration.Add<PageDesignerViewModel, PageDesignerView>("PageDesigner");
|
||||
configuration.Add<PageCollectionViewModel, PageCollectionView>("Pages");
|
||||
configuration.Add<AddPageViewModel, AddPageView>("AddPage");
|
||||
})
|
||||
.ConfigureServices(ConfigureServices)
|
||||
.Build();
|
||||
|
||||
await host.RunAsync();
|
||||
base.OnFrameworkInitializationCompleted();
|
||||
}
|
||||
|
||||
private void ConfigureServices(HostBuilderContext context, IServiceCollection services)
|
||||
{
|
||||
services.AddReqiredCore()
|
||||
.AddRequiredAvalonia()
|
||||
.AddHostedService<AppServices>()
|
||||
.RegisterHandlers();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<TrimMode>copyused</TrimMode>
|
||||
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Remove=".gitignore" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<TrimmableAssembly Include="Avalonia.Themes.Fluent" />
|
||||
<TrimmableAssembly Include="Avalonia.Themes.Default" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia" Version="11.0.0-preview3" />
|
||||
<PackageReference Include="Avalonia.Desktop" Version="11.0.0-preview3" />
|
||||
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="Avalonia.Diagnostics" Version="11.0.0-preview3" />
|
||||
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.0.0-preview3" />
|
||||
<PackageReference Include="PropertyChanged.Fody" Version="4.0.5" />
|
||||
<PackageReference Include="XamlNameReferenceGenerator" Version="1.3.4" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Framework\Avalonia\Avalonia.csproj" />
|
||||
<ProjectReference Include="..\..\UI\Avalonia.Controls\Avalonia.Controls.csproj" />
|
||||
<ProjectReference Include="..\..\UI\Avalonia\Avalonia.csproj" />
|
||||
<ProjectReference Include="..\..\UI\UI\UI.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="FluentAvalonia">
|
||||
<HintPath>..\..\Framework\Avalonia\References\FluentAvalonia.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Update="Views\StartProjectConfigurationView.axaml.cs">
|
||||
<DependentUpon>StartProjectConfigurationView.axaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Views\ProjectView.axaml.cs">
|
||||
<DependentUpon>ProjectView.axaml</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,3 @@
|
||||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
|
||||
<PropertyChanged />
|
||||
</Weavers>
|
||||
@@ -0,0 +1,3 @@
|
||||
namespace Builder.LifeCycles;
|
||||
|
||||
public record AddPage(string Name);
|
||||
@@ -0,0 +1,18 @@
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace Builder.LifeCycles;
|
||||
|
||||
public class AddPageHandler : IMediatorHandler<AddPage>
|
||||
{
|
||||
private readonly IProjectContext context;
|
||||
|
||||
public AddPageHandler(IProjectContext context)
|
||||
{
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public void Handle(AddPage request)
|
||||
{
|
||||
context.Pages.Add(new Page(request.Name));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Builder.LifeCycles
|
||||
{
|
||||
public interface IProjectContext
|
||||
{
|
||||
ICollection<Page> Pages { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
namespace Builder.LifeCycles
|
||||
{
|
||||
public record Page(string Name);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Builder.LifeCycles
|
||||
{
|
||||
public class ProjectConfiguration
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Builder.LifeCycles
|
||||
{
|
||||
public class ProjectContext : IProjectContext
|
||||
{
|
||||
public ICollection<Page> Pages => new List<Page>();
|
||||
}
|
||||
|
||||
public interface IProjectScope
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace Builder;
|
||||
|
||||
public class StartedHandler : IMediatorHandler<Started>
|
||||
{
|
||||
private readonly MainWindow window;
|
||||
private readonly MainWindowViewModel viewModel;
|
||||
|
||||
public StartedHandler(MainWindow window,
|
||||
MainWindowViewModel viewModel)
|
||||
{
|
||||
this.window = window;
|
||||
this.viewModel = viewModel;
|
||||
}
|
||||
|
||||
public void Handle(Started request)
|
||||
{
|
||||
window.DataContext = viewModel;
|
||||
if (Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||
{
|
||||
desktop.MainWindow = window;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
using Avalonia;
|
||||
using System;
|
||||
|
||||
namespace Builder;
|
||||
|
||||
internal class Program
|
||||
{
|
||||
[STAThread]
|
||||
public static void Main(string[] args) => BuildAvaloniaApp()
|
||||
.StartWithClassicDesktopLifetime(args);
|
||||
|
||||
public static AppBuilder BuildAvaloniaApp()
|
||||
=> AppBuilder.Configure<App>()
|
||||
.UsePlatformDetect()
|
||||
.With(new Win32PlatformOptions
|
||||
{
|
||||
UseCompositor = false
|
||||
})
|
||||
.LogToTrace();
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
using Avalonia.Metadata;
|
||||
|
||||
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "FluentAvalonia.UI.Controls")]
|
||||
@@ -0,0 +1,16 @@
|
||||
<fluent:ContentDialog
|
||||
x:Class="Builder.AddPageView"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:fluent="using:FluentAvalonia.UI.Controls"
|
||||
xmlns:ui="clr-namespace:TheXamlGuy.UI.Avalonia;assembly=TheXamlGuy.UI.Avalonia"
|
||||
Title="Add Page"
|
||||
CloseButtonText="Cancel"
|
||||
DefaultButton="Primary"
|
||||
PrimaryButtonClick="{ui:Invoke Add}"
|
||||
PrimaryButtonText="Add">
|
||||
<TextBox
|
||||
Width="500"
|
||||
Text="{Binding Name}"
|
||||
Watermark="Enter page name" />
|
||||
</fluent:ContentDialog>
|
||||
@@ -0,0 +1,17 @@
|
||||
using Avalonia.Styling;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using PropertyChanged;
|
||||
using System;
|
||||
|
||||
namespace Builder;
|
||||
|
||||
[DoNotNotify]
|
||||
public partial class AddPageView : ContentDialog, IStyleable
|
||||
{
|
||||
public AddPageView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
Type IStyleable.StyleKey => typeof(ContentDialog);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using Builder.LifeCycles;
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace Builder;
|
||||
|
||||
public class AddPageViewModel : ObservableViewModel
|
||||
{
|
||||
public AddPageViewModel(IPropertyBuilder propertyBuilder,
|
||||
IEventAggregator eventAggregator,
|
||||
IServiceFactory serviceFactory,
|
||||
IDisposer disposer) : base(propertyBuilder, eventAggregator, serviceFactory, disposer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public string? Name { get; set; }
|
||||
|
||||
public void Add()
|
||||
{
|
||||
EventAggregator.Publish(new AddPage(Name));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<UserControl
|
||||
x:Class="Builder.CreateProjectConfigurationView"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:controls="clr-namespace:TheXamlGuy.UI.Avalonia.Controls;assembly=TheXamlGuy.UI.Avalonia.Controls"
|
||||
xmlns:fluent="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
xmlns:views="using:Builder"
|
||||
Loaded="{Composite {ChangeProperty {Binding $parent[fluent:ContentDialog]},
|
||||
Classes,
|
||||
Create}}">
|
||||
<Grid>
|
||||
<controls:FilePicker x:Name="FilePicker" />
|
||||
<StackPanel Spacing="18">
|
||||
<TextBox Watermark="Project name" />
|
||||
<Grid ColumnDefinitions="*, 4, Auto">
|
||||
<TextBox Grid.Column="0" Watermark="Project location" />
|
||||
<Button
|
||||
Grid.Column="2"
|
||||
Click="{Invoke {Binding #FilePicker.Open}}"
|
||||
Content="..." />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,14 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Platform.Storage;
|
||||
using PropertyChanged;
|
||||
|
||||
namespace Builder;
|
||||
|
||||
[DoNotNotify]
|
||||
public partial class CreateProjectConfigurationView : UserControl
|
||||
{
|
||||
public CreateProjectConfigurationView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace Builder;
|
||||
|
||||
public class CreateProjectConfigurationViewModel : ObservableViewModel
|
||||
{
|
||||
public CreateProjectConfigurationViewModel(IPropertyBuilder propertyBuilder,
|
||||
IEventAggregator eventAggregator,
|
||||
IServiceFactory serviceFactory,
|
||||
IDisposer disposer) : base(propertyBuilder, eventAggregator, serviceFactory, disposer)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<UserControl
|
||||
x:Class="Builder.ExistingProjectConfigurationView"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:fluent="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
Loaded="{Composite {ChangeProperty {Binding $parent[fluent:ContentDialog]},
|
||||
Classes,
|
||||
Open}}" />
|
||||
@@ -0,0 +1,15 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Data;
|
||||
using PropertyChanged;
|
||||
|
||||
namespace Builder;
|
||||
|
||||
[DoNotNotify]
|
||||
public partial class ExistingProjectConfigurationView : UserControl
|
||||
{
|
||||
public ExistingProjectConfigurationView()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace Builder;
|
||||
|
||||
public class ExistingProjectConfigurationViewModel : ObservableViewModel
|
||||
{
|
||||
public ExistingProjectConfigurationViewModel(IPropertyBuilder propertyBuilder,
|
||||
IEventAggregator eventAggregator,
|
||||
IServiceFactory serviceFactory,
|
||||
IDisposer disposer) : base(propertyBuilder, eventAggregator, serviceFactory, disposer)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<UserControl
|
||||
x:Class="Builder.MainView"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Content="{Route {Binding Route},
|
||||
Main}"
|
||||
Loaded="{Navigate {Binding EventAggregator},
|
||||
Project,
|
||||
Route=Main}" />
|
||||
@@ -0,0 +1,14 @@
|
||||
using Avalonia.Controls;
|
||||
using PropertyChanged;
|
||||
|
||||
namespace Builder
|
||||
{
|
||||
[DoNotNotify]
|
||||
public partial class MainView : UserControl
|
||||
{
|
||||
public MainView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using TheXamlGuy.Framework.Avalonia;
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace Builder;
|
||||
|
||||
public class MainViewModel : ObservableViewModel
|
||||
{
|
||||
public MainViewModel(IPropertyBuilder propertyBuilder,
|
||||
IEventAggregator eventAggregator,
|
||||
IServiceFactory serviceFactory,
|
||||
IDisposer disposer,
|
||||
IRouter route) : base(propertyBuilder, eventAggregator, serviceFactory, disposer)
|
||||
{
|
||||
Route = route;
|
||||
}
|
||||
|
||||
public IRouter Route { get; }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<Window
|
||||
x:Class="Builder.MainWindow"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Content="{Route {Binding Route},
|
||||
Window}"
|
||||
Loaded="{Navigate {Binding EventAggregator},
|
||||
Main,
|
||||
Route=Window}" />
|
||||
@@ -0,0 +1,75 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.Media.Immutable;
|
||||
using FluentAvalonia.Styling;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using FluentAvalonia.UI.Media;
|
||||
using PropertyChanged;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Builder;
|
||||
|
||||
[DoNotNotify]
|
||||
public partial class MainWindow : CoreWindow
|
||||
{
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnOpened(EventArgs args)
|
||||
{
|
||||
if (AvaloniaLocator.Current.GetService<FluentAvaloniaTheme>() is FluentAvaloniaTheme theme)
|
||||
{
|
||||
theme.RequestedThemeChanged += OnRequestedThemeChanged;
|
||||
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
if (IsWindows11 && theme.RequestedTheme != FluentAvaloniaTheme.HighContrastModeString)
|
||||
{
|
||||
TransparencyBackgroundFallback = Brushes.Transparent;
|
||||
TransparencyLevelHint = WindowTransparencyLevel.Mica;
|
||||
|
||||
TryEnableMicaEffect(theme);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
base.OnOpened(args);
|
||||
}
|
||||
|
||||
private void OnRequestedThemeChanged(FluentAvaloniaTheme sender, RequestedThemeChangedEventArgs args)
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
if (IsWindows11 && args.NewTheme != FluentAvaloniaTheme.HighContrastModeString)
|
||||
{
|
||||
TryEnableMicaEffect(sender);
|
||||
}
|
||||
else if (args.NewTheme == FluentAvaloniaTheme.HighContrastModeString)
|
||||
{
|
||||
SetValue(BackgroundProperty, AvaloniaProperty.UnsetValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void TryEnableMicaEffect(FluentAvaloniaTheme theme)
|
||||
{
|
||||
if (theme.RequestedTheme == FluentAvaloniaTheme.DarkModeString)
|
||||
{
|
||||
Color2 color = this.TryFindResource("SolidBackgroundFillColorBase", out object? value) ? (Color2)(Color)value! : new Color2(32, 32, 32);
|
||||
color = color.LightenPercent(-0.5f);
|
||||
|
||||
Background = new ImmutableSolidColorBrush(color, 0.78);
|
||||
}
|
||||
else if (theme.RequestedTheme == FluentAvaloniaTheme.LightModeString)
|
||||
{
|
||||
Color2 color = this.TryFindResource("SolidBackgroundFillColorBase", out object? value) ? (Color2)(Color)value! : new Color2(243, 243, 243);
|
||||
color = color.LightenPercent(0.5f);
|
||||
|
||||
Background = new ImmutableSolidColorBrush(color, 0.9);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using TheXamlGuy.Framework.Avalonia;
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace Builder;
|
||||
|
||||
public class MainWindowViewModel : ObservableViewModel
|
||||
{
|
||||
public MainWindowViewModel(IPropertyBuilder propertyBuilder,
|
||||
IEventAggregator eventAggregator,
|
||||
IServiceFactory serviceFactory,
|
||||
IDisposer disposer,
|
||||
IRouter route) : base(propertyBuilder, eventAggregator, serviceFactory, disposer)
|
||||
{
|
||||
Route = route;
|
||||
}
|
||||
|
||||
public IRouter Route { get; }
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<UserControl
|
||||
x:Class="Builder.PageCollectionView"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:fluent="using:FluentAvalonia.UI.Controls"
|
||||
xmlns:view="clr-namespace:Builder;assembly=Builder">
|
||||
<fluent:NavigationView
|
||||
IsPaneToggleButtonVisible="False"
|
||||
IsSettingsVisible="False"
|
||||
MenuItems="{Binding}">
|
||||
<fluent:NavigationView.PaneHeader>
|
||||
<Button
|
||||
HorizontalAlignment="Left"
|
||||
Classes="Icon"
|
||||
Click="{Navigate {Binding EventAggregator},
|
||||
AddPage}"
|
||||
Content="">
|
||||
<fluent:FAPathIcon Data="F1 M 10.52 4.559999 C 10.519999 4.346666 10.446666 4.166668 10.3 4.02 C 10.153333 3.873333 9.973333 3.799999 9.76 3.799999 C 9.546666 3.799999 9.366666 3.873333 9.22 4.02 C 9.073333 4.166668 9 4.346666 9 4.559999 L 9 10.799999 L 2.76 10.799999 C 2.546667 10.799999 2.366667 10.873333 2.22 11.02 C 2.073333 11.166667 2 11.346666 2 11.559999 C 2 11.773333 2.073333 11.953333 2.22 12.099999 C 2.366667 12.246667 2.546667 12.32 2.76 12.32 L 9 12.32 L 9 18.559999 C 9 18.773333 9.073333 18.953333 9.22 19.099998 C 9.366666 19.246666 9.546666 19.313332 9.76 19.299999 C 9.973333 19.286667 10.153333 19.213333 10.3 19.08 C 10.446666 18.946667 10.519999 18.773333 10.52 18.559999 L 10.52 12.28 L 16.76 12.28 C 16.973333 12.306667 17.153332 12.246667 17.299999 12.099999 C 17.446667 11.953333 17.513332 11.773333 17.5 11.559999 C 17.486666 11.346666 17.413332 11.166667 17.279999 11.02 C 17.146666 10.873333 16.973333 10.799999 16.76 10.799999 L 10.52 10.799999 Z " />
|
||||
</Button>
|
||||
</fluent:NavigationView.PaneHeader>
|
||||
<fluent:NavigationView.MenuItemTemplate>
|
||||
<DataTemplate x:DataType="view:PageItemViewModel">
|
||||
<fluent:NavigationViewItem Content="{Binding Name}">
|
||||
<fluent:NavigationViewItem.Icon>
|
||||
<fluent:FAPathIcon Data="F1 M 7.08 11.24 C 7.053333 11.373333 7.08 11.5 7.16 11.62 C 7.24 11.74 7.346666 11.806666 7.48 11.82 C 7.613333 11.833333 7.739999 11.799999 7.86 11.719999 C 7.98 11.639999 8.053333 11.533333 8.08 11.4 L 8.16 10.799999 L 9.4 10.799999 L 9.32 11.24 C 9.293333 11.373333 9.32 11.5 9.4 11.62 C 9.48 11.74 9.593332 11.806666 9.74 11.82 C 9.886666 11.833333 10.013333 11.799999 10.12 11.719999 C 10.226665 11.639999 10.293333 11.533333 10.32 11.4 L 10.4 10.799999 L 11 10.799999 C 11.133333 10.799999 11.253333 10.753333 11.36 10.66 C 11.466666 10.566667 11.52 10.446667 11.52 10.299999 C 11.52 10.153334 11.466666 10.033333 11.36 9.94 C 11.253333 9.846666 11.133333 9.799999 11 9.799999 L 10.559999 9.799999 L 10.76 8.32 L 11.52 8.32 C 11.653333 8.32 11.766666 8.266666 11.86 8.16 C 11.953333 8.053333 12 7.933333 12 7.799999 C 12 7.666666 11.953333 7.553333 11.86 7.459999 C 11.766666 7.366667 11.653333 7.32 11.52 7.32 L 10.92 7.32 L 11.04 6.36 C 11.066667 6.226667 11.04 6.106668 10.96 6 C 10.88 5.893333 10.766666 5.826666 10.62 5.799999 C 10.473332 5.773335 10.346666 5.806667 10.24 5.9 C 10.133333 5.993334 10.066666 6.106668 10.04 6.24 L 9.92 7.32 L 8.679999 7.32 L 8.8 6.36 C 8.826666 6.226667 8.793333 6.106668 8.7 6 C 8.606667 5.893333 8.493333 5.826666 8.36 5.799999 C 8.226666 5.773335 8.106667 5.806667 8 5.9 C 7.893332 5.993334 7.826666 6.106668 7.8 6.24 L 7.64 7.32 L 7 7.32 C 6.866666 7.32 6.746666 7.366667 6.64 7.459999 C 6.533333 7.553333 6.486667 7.666666 6.5 7.799999 C 6.513333 7.933333 6.566667 8.053333 6.66 8.16 C 6.753333 8.266666 6.866666 8.32 7 8.32 L 7.52 8.32 L 7.28 9.799999 L 6.52 9.799999 C 6.36 9.799999 6.233333 9.846666 6.14 9.94 C 6.046666 10.033333 6 10.153334 6 10.299999 C 6 10.446667 6.046666 10.566667 6.14 10.66 C 6.233333 10.753333 6.346666 10.799999 6.48 10.799999 L 7.12 10.799999 Z M 9.76 8.32 L 9.52 9.799999 L 8.28 9.799999 L 8.52 8.32 Z M 6 3.799999 C 5.44 3.799999 4.966666 3.993334 4.58 4.379999 C 4.193333 4.766666 4 5.24 4 5.799999 L 4 17.799999 C 4 18.360001 4.193333 18.833332 4.58 19.219999 C 4.966666 19.606667 5.44 19.799999 6 19.799999 L 14 19.799999 C 14.559999 19.799999 15.033333 19.606667 15.42 19.219999 C 15.806666 18.833332 16 18.360001 16 17.799999 L 16 5.799999 C 16 5.24 15.806666 4.766666 15.42 4.379999 C 15.033333 3.993334 14.559999 3.799999 14 3.799999 Z M 6 4.799999 L 14 4.799999 C 14.266666 4.799999 14.5 4.9 14.7 5.1 C 14.9 5.299999 14.999999 5.533333 15 5.799999 L 15 17.799999 C 14.999999 18.066666 14.9 18.299999 14.7 18.5 C 14.5 18.699999 14.266666 18.799999 14 18.799999 L 6 18.799999 C 5.733333 18.799999 5.5 18.699999 5.3 18.5 C 5.099999 18.299999 5 18.066666 5 17.799999 L 5 5.799999 C 5 5.533333 5.099999 5.299999 5.3 5.1 C 5.5 4.9 5.733333 4.799999 6 4.799999 Z " />
|
||||
</fluent:NavigationViewItem.Icon>
|
||||
</fluent:NavigationViewItem>
|
||||
</DataTemplate>
|
||||
</fluent:NavigationView.MenuItemTemplate>
|
||||
</fluent:NavigationView>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,13 @@
|
||||
using Avalonia.Controls;
|
||||
using PropertyChanged;
|
||||
|
||||
namespace Builder;
|
||||
|
||||
[DoNotNotify]
|
||||
public partial class PageCollectionView : UserControl
|
||||
{
|
||||
public PageCollectionView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using TheXamlGuy.Framework.Avalonia;
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace Builder;
|
||||
|
||||
public class PageCollectionViewModel : ObservableViewModelCollection<PageItemViewModel>
|
||||
{
|
||||
public PageCollectionViewModel(IPropertyBuilder propertyBuilder,
|
||||
IEventAggregator eventAggregator,
|
||||
IServiceFactory serviceFactory,
|
||||
IDisposer disposer,
|
||||
ITemplateSelector templateSelector,
|
||||
IRouter route) : base(propertyBuilder, eventAggregator, serviceFactory, disposer)
|
||||
{
|
||||
TemplateSelector = templateSelector;
|
||||
Route = route;
|
||||
}
|
||||
|
||||
public ITemplateSelector TemplateSelector { get; }
|
||||
|
||||
public IRouter Route { get; }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<UserControl
|
||||
x:Class="Builder.PageDesignerView"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
<SplitView
|
||||
IsPaneOpen="True"
|
||||
PaneBackground="Red"
|
||||
PanePlacement="Right" />
|
||||
</UserControl>
|
||||
@@ -0,0 +1,13 @@
|
||||
using Avalonia.Controls;
|
||||
using PropertyChanged;
|
||||
|
||||
namespace Builder;
|
||||
|
||||
[DoNotNotify]
|
||||
public partial class PageDesignerView : UserControl
|
||||
{
|
||||
public PageDesignerView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using TheXamlGuy.Framework.Avalonia;
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace Builder;
|
||||
|
||||
public class PageDesignerViewModel : ObservableViewModel
|
||||
{
|
||||
public PageDesignerViewModel(IPropertyBuilder propertyBuilder,
|
||||
IEventAggregator eventAggregator,
|
||||
IServiceFactory serviceFactory,
|
||||
IDisposer disposer,
|
||||
IRouter route) : base(propertyBuilder, eventAggregator, serviceFactory, disposer)
|
||||
{
|
||||
Route = route;
|
||||
}
|
||||
|
||||
public IRouter Route { get; }
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using TheXamlGuy.Framework.Avalonia;
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace Builder;
|
||||
|
||||
public class PageItemViewModel : ObservableViewModel
|
||||
{
|
||||
public PageItemViewModel(IPropertyBuilder propertyBuilder,
|
||||
IEventAggregator eventAggregator,
|
||||
IServiceFactory serviceFactory,
|
||||
IDisposer disposer,
|
||||
IRouter route,
|
||||
string name) : base(propertyBuilder, eventAggregator, serviceFactory, disposer)
|
||||
{
|
||||
Route = route;
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public IRouter Route { get; }
|
||||
|
||||
public string Name { get; }
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
<fluent:ContentDialog
|
||||
x:Class="Builder.ProjectConfigurationView"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:fluent="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
CloseButtonText="Cancel">
|
||||
<fluent:ContentDialog.Title>
|
||||
<Grid Height="40" ColumnDefinitions="Auto, *">
|
||||
<Button
|
||||
x:Name="BackButton"
|
||||
Grid.Column="0"
|
||||
Classes="Icon"
|
||||
Click="{Invoke {Binding #Frame.GoBack}}">
|
||||
<fluent:FAPathIcon Data="F1 M 12.28 17.599998 C 12.119999 17.733334 11.939999 17.799999 11.74 17.799999 C 11.539999 17.799999 11.36 17.719999 11.2 17.559999 L 6.2 12.32 C 6.066667 12.186666 6 12.02 6 11.82 C 6 11.62 6.066667 11.440001 6.2 11.28 L 11.2 6.04 C 11.413333 5.826667 11.66 5.753334 11.94 5.82 C 12.219999 5.886666 12.399999 6.059999 12.48 6.339999 C 12.559999 6.62 12.493332 6.866667 12.28 7.08 L 7.8 11.799999 L 12.28 16.52 C 12.439999 16.68 12.513332 16.860001 12.5 17.059999 C 12.486666 17.259998 12.413332 17.439999 12.28 17.599998 Z " />
|
||||
</Button>
|
||||
<TextBlock
|
||||
x:Name="Title"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center" />
|
||||
</Grid>
|
||||
</fluent:ContentDialog.Title>
|
||||
<fluent:Frame
|
||||
x:Name="Frame"
|
||||
Width="500"
|
||||
Height="350"
|
||||
Content="{Route {Binding Route},
|
||||
ProjectConfiguration}"
|
||||
Loaded="{Navigate {Binding EventAggregator},
|
||||
StartProjectConfiguration,
|
||||
Route=ProjectConfiguration}" />
|
||||
<fluent:ContentDialog.Styles>
|
||||
<Style Selector="fluent|ContentDialog.Project">
|
||||
<Style Selector="^fluent|ContentDialog.Project /template/ Button#PrimaryButton">
|
||||
<Setter Property="IsVisible" Value="False" />
|
||||
</Style>
|
||||
<Style Selector="^fluent|ContentDialog.Project Button#BackButton">
|
||||
<Setter Property="IsVisible" Value="False" />
|
||||
</Style>
|
||||
<Style Selector="^fluent|ContentDialog.Project TextBlock#Title">
|
||||
<Setter Property="Text" Value="Let's get started" />
|
||||
</Style>
|
||||
</Style>
|
||||
<Style Selector="fluent|ContentDialog.Create">
|
||||
<Style Selector="^fluent|ContentDialog.Create /template/ Button#PrimaryButton">
|
||||
<Setter Property="Content" Value="Create" />
|
||||
<Setter Property="IsVisible" Value="True" />
|
||||
<Setter Property="Grid.Column" Value="0" />
|
||||
<Setter Property="Grid.ColumnSpan" Value="2" />
|
||||
<Setter Property="Margin" Value="0 0 4 0" />
|
||||
</Style>
|
||||
<Style Selector="^fluent|ContentDialog.Create Button#BackButton">
|
||||
<Setter Property="IsVisible" Value="True" />
|
||||
</Style>
|
||||
<Style Selector="^fluent|ContentDialog.Create TextBlock#Title">
|
||||
<Setter Property="Text" Value="Create a new project" />
|
||||
</Style>
|
||||
</Style>
|
||||
<Style Selector="fluent|ContentDialog.Open">
|
||||
<Style Selector="^fluent|ContentDialog.Open /template/ Button#PrimaryButton">
|
||||
<Setter Property="IsVisible" Value="False" />
|
||||
</Style>
|
||||
<Style Selector="^fluent|ContentDialog.Open Button#BackButton">
|
||||
<Setter Property="IsVisible" Value="True" />
|
||||
</Style>
|
||||
<Style Selector="^fluent|ContentDialog.Open TextBlock#Title">
|
||||
<Setter Property="Text" Value="Open a project" />
|
||||
</Style>
|
||||
</Style>
|
||||
</fluent:ContentDialog.Styles>
|
||||
</fluent:ContentDialog>
|
||||
@@ -0,0 +1,17 @@
|
||||
using Avalonia.Styling;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using PropertyChanged;
|
||||
using System;
|
||||
|
||||
namespace Builder;
|
||||
|
||||
[DoNotNotify]
|
||||
public partial class ProjectConfigurationView : ContentDialog, IStyleable
|
||||
{
|
||||
public ProjectConfigurationView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
Type IStyleable.StyleKey => typeof(ContentDialog);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using TheXamlGuy.Framework.Avalonia;
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace Builder;
|
||||
|
||||
public class ProjectConfigurationViewModel : ObservableViewModel
|
||||
{
|
||||
public ProjectConfigurationViewModel(IPropertyBuilder propertyBuilder,
|
||||
IEventAggregator eventAggregator,
|
||||
IServiceFactory serviceFactory,
|
||||
IDisposer disposer,
|
||||
IRouter route) : base(propertyBuilder, eventAggregator, serviceFactory, disposer)
|
||||
{
|
||||
Route = route;
|
||||
}
|
||||
|
||||
public IRouter Route { get; }
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<UserControl
|
||||
x:Class="Builder.ProjectView"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:fluent="using:FluentAvalonia.UI.Controls"
|
||||
Loaded="{Navigate {Binding EventAggregator},
|
||||
ProjectConfiguration}">
|
||||
<Grid RowDefinitions="Auto,*">
|
||||
<Button
|
||||
Grid.Row="0"
|
||||
Margin="6,6,12,6"
|
||||
HorizontalAlignment="Right"
|
||||
Classes="accent"
|
||||
Content="New project" />
|
||||
<fluent:Frame
|
||||
Grid.Row="1"
|
||||
Content="{Route {Binding Route},
|
||||
Navigation}"
|
||||
Loaded="{Navigate {Binding EventAggregator},
|
||||
Pages,
|
||||
Route=Navigation}" />
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,13 @@
|
||||
using Avalonia.Controls;
|
||||
using PropertyChanged;
|
||||
|
||||
namespace Builder;
|
||||
|
||||
[DoNotNotify]
|
||||
public partial class ProjectView : UserControl
|
||||
{
|
||||
public ProjectView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using TheXamlGuy.Framework.Avalonia;
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace Builder;
|
||||
|
||||
public class ProjectViewModel : ObservableViewModel
|
||||
{
|
||||
public ProjectViewModel(IPropertyBuilder propertyBuilder,
|
||||
IEventAggregator eventAggregator,
|
||||
IServiceFactory serviceFactory,
|
||||
IDisposer disposer,
|
||||
IRouter route) : base(propertyBuilder, eventAggregator, serviceFactory, disposer)
|
||||
{
|
||||
Route = route;
|
||||
}
|
||||
|
||||
public IRouter Route { get; }
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<UserControl
|
||||
x:Class="Builder.StartProjectConfigurationView"
|
||||
xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:fluent="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
|
||||
Loaded="{Composite {ChangeProperty {Binding $parent[fluent:ContentDialog]},
|
||||
Classes,
|
||||
Project}}">
|
||||
<StackPanel Spacing="4">
|
||||
<fluent:SettingsExpander
|
||||
Click="{Navigate {Binding EventAggregator},
|
||||
CreateProjectConfiguration,
|
||||
Route=ProjectConfiguration}"
|
||||
Description="Let's started with a new blank builder proejct"
|
||||
Header="Create a new project"
|
||||
IsClickEnabled="True">
|
||||
<fluent:SettingsExpander.IconSource>
|
||||
<fluent:PathIconSource Data="F1 M 3.056641 18.75 C 2.646484 18.75 2.255859 18.666992 1.884766 18.500977 C 1.513672 18.334961 1.189779 18.113607 0.913086 17.836914 C 0.636393 17.560221 0.415039 17.236328 0.249023 16.865234 C 0.083008 16.494141 0 16.103516 0 15.693359 L 0 4.306641 C 0 3.896484 0.083008 3.505859 0.249023 3.134766 C 0.415039 2.763672 0.636393 2.439779 0.913086 2.163086 C 1.189779 1.886395 1.513672 1.665039 1.884766 1.499023 C 2.255859 1.333008 2.646484 1.25 3.056641 1.25 L 6.875 1.25 C 7.324219 1.25 7.709961 1.319988 8.032227 1.459961 C 8.354492 1.599936 8.644205 1.785482 8.901367 2.016602 C 9.158528 2.247723 9.397786 2.513021 9.619141 2.8125 C 9.840494 3.11198 10.071614 3.42448 10.3125 3.75 L 16.943359 3.75 C 17.353516 3.75 17.744141 3.833008 18.115234 3.999023 C 18.486328 4.165039 18.810221 4.386394 19.086914 4.663086 C 19.363605 4.939779 19.584961 5.263672 19.750977 5.634766 C 19.916992 6.005859 20 6.396484 20 6.806641 L 20 9.902344 C 19.817707 9.674479 19.622395 9.456381 19.414062 9.248047 C 19.205729 9.039714 18.984375 8.847656 18.75 8.671875 L 18.75 6.875 C 18.75 6.621095 18.701172 6.380209 18.603516 6.152344 C 18.505859 5.924479 18.370768 5.724284 18.198242 5.551758 C 18.025715 5.379232 17.82552 5.244142 17.597656 5.146484 C 17.369791 5.048829 17.128906 5.000001 16.875 5 L 10.185547 5 C 9.957682 5.156251 9.736328 5.309246 9.521484 5.458984 C 9.306641 5.608725 9.088541 5.742188 8.867188 5.859375 C 8.645833 5.976562 8.413086 6.070964 8.168945 6.142578 C 7.924805 6.214193 7.65625 6.25 7.363281 6.25 L 1.25 6.25 L 1.25 15.625 C 1.25 15.878906 1.298828 16.119791 1.396484 16.347656 C 1.494141 16.575521 1.629232 16.775717 1.801758 16.948242 C 1.974284 17.120768 2.174479 17.255859 2.402344 17.353516 C 2.630208 17.451172 2.871094 17.5 3.125 17.5 L 7.900391 17.5 C 8.011067 17.721354 8.129883 17.936197 8.256836 18.144531 C 8.383789 18.352865 8.522135 18.554688 8.671875 18.75 Z M 7.363281 5 C 7.539062 5.000001 7.70345 4.977215 7.856445 4.931641 C 8.009439 4.886068 8.154297 4.825847 8.291016 4.750977 C 8.427734 4.676107 8.562825 4.5931 8.696289 4.501953 C 8.829752 4.410808 8.964844 4.316406 9.101562 4.21875 C 8.951822 4.016928 8.805338 3.813477 8.662109 3.608398 C 8.51888 3.40332 8.36263 3.219402 8.193359 3.056641 C 8.024088 2.893881 7.833658 2.760418 7.62207 2.65625 C 7.410481 2.552084 7.161458 2.5 6.875 2.5 L 3.125 2.5 C 2.871094 2.5 2.630208 2.548828 2.402344 2.646484 C 2.174479 2.744141 1.974284 2.879232 1.801758 3.051758 C 1.629232 3.224285 1.494141 3.42448 1.396484 3.652344 C 1.298828 3.880209 1.25 4.121094 1.25 4.375 L 1.25 5 Z M 8.75 14.375 C 8.75 13.600261 8.898111 12.871094 9.194336 12.1875 C 9.49056 11.503906 9.892578 10.908203 10.400391 10.400391 C 10.908203 9.892578 11.503906 9.490561 12.1875 9.194336 C 12.871093 8.898112 13.60026 8.75 14.375 8.75 C 14.889322 8.75 15.385741 8.816732 15.864258 8.950195 C 16.342773 9.083659 16.790363 9.272461 17.207031 9.516602 C 17.623697 9.760742 18.004557 10.055339 18.349609 10.400391 C 18.69466 10.745443 18.989258 11.126303 19.233398 11.542969 C 19.477539 11.959636 19.66634 12.407227 19.799805 12.885742 C 19.933268 13.364258 20 13.860678 20 14.375 C 20 15.14974 19.851887 15.878906 19.555664 16.5625 C 19.259439 17.246094 18.857422 17.841797 18.349609 18.349609 C 17.841797 18.857422 17.246094 19.259439 16.5625 19.555664 C 15.878906 19.851889 15.149739 20 14.375 20 C 13.59375 20 12.861328 19.853516 12.177734 19.560547 C 11.494141 19.267578 10.898438 18.867188 10.390625 18.359375 C 9.882812 17.851562 9.482422 17.255859 9.189453 16.572266 C 8.896484 15.888672 8.75 15.15625 8.75 14.375 Z M 15 15 L 16.875 15 C 17.04427 15 17.190754 14.938151 17.314453 14.814453 C 17.43815 14.690756 17.5 14.544271 17.5 14.375 C 17.5 14.205729 17.43815 14.059245 17.314453 13.935547 C 17.190754 13.81185 17.04427 13.75 16.875 13.75 L 15 13.75 L 15 11.875 C 14.999999 11.705729 14.93815 11.559245 14.814453 11.435547 C 14.690755 11.31185 14.544271 11.25 14.375 11.25 C 14.205729 11.25 14.059244 11.31185 13.935547 11.435547 C 13.811849 11.559245 13.75 11.705729 13.75 11.875 L 13.75 13.75 L 11.875 13.75 C 11.705729 13.75 11.559244 13.81185 11.435547 13.935547 C 11.311849 14.059245 11.25 14.205729 11.25 14.375 C 11.25 14.544271 11.311849 14.690756 11.435547 14.814453 C 11.559244 14.938151 11.705729 15 11.875 15 L 13.75 15 L 13.75 16.875 C 13.75 17.044271 13.811849 17.190756 13.935547 17.314453 C 14.059244 17.43815 14.205729 17.5 14.375 17.5 C 14.544271 17.5 14.690755 17.43815 14.814453 17.314453 C 14.93815 17.190756 14.999999 17.044271 15 16.875 Z " />
|
||||
</fluent:SettingsExpander.IconSource>
|
||||
<fluent:SettingsExpander.ActionIconSource>
|
||||
<fluent:PathIconSource Data="F1 M 6.25 16.875 C 6.25 16.705729 6.311849 16.559244 6.435547 16.435547 L 12.861328 10 L 6.435547 3.564453 C 6.311849 3.440756 6.25 3.294271 6.25 3.125 C 6.25 2.95573 6.311849 2.809246 6.435547 2.685547 C 6.559244 2.56185 6.705729 2.5 6.875 2.5 C 7.044271 2.5 7.190755 2.56185 7.314453 2.685547 L 14.189453 9.560547 C 14.31315 9.684245 14.375 9.830729 14.375 10 C 14.375 10.169271 14.31315 10.315756 14.189453 10.439453 L 7.314453 17.314453 C 7.190755 17.43815 7.044271 17.5 6.875 17.5 C 6.705729 17.5 6.559244 17.43815 6.435547 17.314453 C 6.311849 17.190756 6.25 17.044271 6.25 16.875 Z " />
|
||||
</fluent:SettingsExpander.ActionIconSource>
|
||||
</fluent:SettingsExpander>
|
||||
<fluent:SettingsExpander
|
||||
Click="{Navigate {Binding EventAggregator},
|
||||
ExistingProjectConfiguration,
|
||||
Route=ProjectConfiguration}"
|
||||
Description="Open an existing builder project"
|
||||
Header="Open a project"
|
||||
IsClickEnabled="True">
|
||||
<fluent:SettingsExpander.IconSource>
|
||||
<fluent:PathIconSource Data="F1 M 3.056641 18.75 C 2.646484 18.75 2.255859 18.666992 1.884766 18.500977 C 1.513672 18.334961 1.189779 18.113607 0.913086 17.836914 C 0.636393 17.560221 0.415039 17.236328 0.249023 16.865234 C 0.083008 16.494141 0 16.103516 0 15.693359 L 0 4.306641 C 0 3.896484 0.083008 3.505859 0.249023 3.134766 C 0.415039 2.763672 0.636393 2.439779 0.913086 2.163086 C 1.189779 1.886395 1.513672 1.665039 1.884766 1.499023 C 2.255859 1.333008 2.646484 1.25 3.056641 1.25 L 6.875 1.25 C 7.324219 1.25 7.709961 1.319988 8.032227 1.459961 C 8.354492 1.599936 8.644205 1.785482 8.901367 2.016602 C 9.158528 2.247723 9.397786 2.513021 9.619141 2.8125 C 9.840494 3.11198 10.071614 3.42448 10.3125 3.75 L 16.943359 3.75 C 17.353516 3.75 17.744141 3.833008 18.115234 3.999023 C 18.486328 4.165039 18.810221 4.386394 19.086914 4.663086 C 19.363605 4.939779 19.584961 5.263672 19.750977 5.634766 C 19.916992 6.005859 20 6.396484 20 6.806641 L 20 9.902344 C 19.817707 9.674479 19.622395 9.456381 19.414062 9.248047 C 19.205729 9.039714 18.984375 8.847656 18.75 8.671875 L 18.75 6.875 C 18.75 6.621095 18.701172 6.380209 18.603516 6.152344 C 18.505859 5.924479 18.370768 5.724284 18.198242 5.551758 C 18.025715 5.379232 17.82552 5.244142 17.597656 5.146484 C 17.369791 5.048829 17.128906 5.000001 16.875 5 L 10.185547 5 C 9.957682 5.156251 9.736328 5.309246 9.521484 5.458984 C 9.306641 5.608725 9.088541 5.742188 8.867188 5.859375 C 8.645833 5.976562 8.413086 6.070964 8.168945 6.142578 C 7.924805 6.214193 7.65625 6.25 7.363281 6.25 L 1.25 6.25 L 1.25 15.625 C 1.25 15.878906 1.298828 16.119791 1.396484 16.347656 C 1.494141 16.575521 1.629232 16.775717 1.801758 16.948242 C 1.974284 17.120768 2.174479 17.255859 2.402344 17.353516 C 2.630208 17.451172 2.871094 17.5 3.125 17.5 L 7.900391 17.5 C 8.011067 17.721354 8.129883 17.936197 8.256836 18.144531 C 8.383789 18.352865 8.522135 18.554688 8.671875 18.75 Z M 7.363281 5 C 7.539062 5.000001 7.70345 4.977215 7.856445 4.931641 C 8.009439 4.886068 8.154297 4.825847 8.291016 4.750977 C 8.427734 4.676107 8.562825 4.5931 8.696289 4.501953 C 8.829752 4.410808 8.964844 4.316406 9.101562 4.21875 C 8.951822 4.016928 8.805338 3.813477 8.662109 3.608398 C 8.51888 3.40332 8.36263 3.219402 8.193359 3.056641 C 8.024088 2.893881 7.833658 2.760418 7.62207 2.65625 C 7.410481 2.552084 7.161458 2.5 6.875 2.5 L 3.125 2.5 C 2.871094 2.5 2.630208 2.548828 2.402344 2.646484 C 2.174479 2.744141 1.974284 2.879232 1.801758 3.051758 C 1.629232 3.224285 1.494141 3.42448 1.396484 3.652344 C 1.298828 3.880209 1.25 4.121094 1.25 4.375 L 1.25 5 Z M 8.75 14.375 C 8.75 13.600261 8.898111 12.871094 9.194336 12.1875 C 9.49056 11.503906 9.892578 10.908203 10.400391 10.400391 C 10.908203 9.892578 11.503906 9.490561 12.1875 9.194336 C 12.871093 8.898112 13.60026 8.75 14.375 8.75 C 14.889322 8.75 15.385741 8.816732 15.864258 8.950195 C 16.342773 9.083659 16.790363 9.272461 17.207031 9.516602 C 17.623697 9.760742 18.004557 10.055339 18.349609 10.400391 C 18.69466 10.745443 18.989258 11.126303 19.233398 11.542969 C 19.477539 11.959636 19.66634 12.407227 19.799805 12.885742 C 19.933268 13.364258 20 13.860678 20 14.375 C 20 15.14974 19.851887 15.878906 19.555664 16.5625 C 19.259439 17.246094 18.857422 17.841797 18.349609 18.349609 C 17.841797 18.857422 17.246094 19.259439 16.5625 19.555664 C 15.878906 19.851889 15.149739 20 14.375 20 C 13.59375 20 12.861328 19.853516 12.177734 19.560547 C 11.494141 19.267578 10.898438 18.867188 10.390625 18.359375 C 9.882812 17.851562 9.482422 17.255859 9.189453 16.572266 C 8.896484 15.888672 8.75 15.15625 8.75 14.375 Z M 12.5 16.923828 C 12.688802 16.923828 12.848307 16.858725 12.978516 16.728516 L 16.25 13.457031 L 16.25 15.625 C 16.25 15.794271 16.311848 15.940756 16.435547 16.064453 C 16.559244 16.188152 16.705729 16.25 16.875 16.25 C 17.04427 16.25 17.190754 16.188152 17.314453 16.064453 C 17.43815 15.940756 17.5 15.794271 17.5 15.625 L 17.5 11.875 C 17.5 11.705729 17.43815 11.559245 17.314453 11.435547 C 17.190754 11.31185 17.04427 11.25 16.875 11.25 L 13.125 11.25 C 12.955729 11.25 12.809244 11.31185 12.685547 11.435547 C 12.561849 11.559245 12.5 11.705729 12.5 11.875 C 12.5 12.044271 12.561849 12.190756 12.685547 12.314453 C 12.809244 12.438151 12.955729 12.5 13.125 12.5 L 15.292969 12.5 L 12.021484 15.771484 C 11.891275 15.901693 11.826172 16.061197 11.826172 16.25 C 11.826172 16.438803 11.891275 16.598307 12.021484 16.728516 C 12.151691 16.858725 12.311197 16.923828 12.5 16.923828 Z " />
|
||||
</fluent:SettingsExpander.IconSource>
|
||||
<fluent:SettingsExpander.ActionIconSource>
|
||||
<fluent:PathIconSource Data="F1 M 6.25 16.875 C 6.25 16.705729 6.311849 16.559244 6.435547 16.435547 L 12.861328 10 L 6.435547 3.564453 C 6.311849 3.440756 6.25 3.294271 6.25 3.125 C 6.25 2.95573 6.311849 2.809246 6.435547 2.685547 C 6.559244 2.56185 6.705729 2.5 6.875 2.5 C 7.044271 2.5 7.190755 2.56185 7.314453 2.685547 L 14.189453 9.560547 C 14.31315 9.684245 14.375 9.830729 14.375 10 C 14.375 10.169271 14.31315 10.315756 14.189453 10.439453 L 7.314453 17.314453 C 7.190755 17.43815 7.044271 17.5 6.875 17.5 C 6.705729 17.5 6.559244 17.43815 6.435547 17.314453 C 6.311849 17.190756 6.25 17.044271 6.25 16.875 Z " />
|
||||
</fluent:SettingsExpander.ActionIconSource>
|
||||
</fluent:SettingsExpander>
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
@@ -0,0 +1,13 @@
|
||||
using Avalonia.Controls;
|
||||
using PropertyChanged;
|
||||
|
||||
namespace Builder;
|
||||
|
||||
[DoNotNotify]
|
||||
public partial class StartProjectConfigurationView : UserControl
|
||||
{
|
||||
public StartProjectConfigurationView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace Builder;
|
||||
|
||||
public class StartProjectConfigurationViewModel : ObservableViewModel
|
||||
{
|
||||
public StartProjectConfigurationViewModel(IPropertyBuilder propertyBuilder,
|
||||
IEventAggregator eventAggregator,
|
||||
IServiceFactory serviceFactory,
|
||||
IDisposer disposer) : base(propertyBuilder, eventAggregator, serviceFactory, disposer)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,27 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>TheXamlGuy.Framework.Avalonia</RootNamespace>
|
||||
<AssemblyName>TheXamlGuy.Framework.Avalonia</AssemblyName>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia" Version="11.0.0-preview3" />
|
||||
<PackageReference Include="MicroCom.Runtime" Version="0.10.5" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\UI\Avalonia\Avalonia.csproj" />
|
||||
<ProjectReference Include="..\Core\Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Reference Include="FluentAvalonia">
|
||||
<HintPath>References\FluentAvalonia.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,34 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace TheXamlGuy.Framework.Avalonia;
|
||||
|
||||
public static class IHostBuilderExtensions
|
||||
{
|
||||
public static IHostBuilder ConfigureTemplates(this IHostBuilder hostBuilder, Action<ITemplateBuilder> builderDelegate)
|
||||
{
|
||||
hostBuilder.ConfigureServices((hostBuilderContext, serviceCollection) =>
|
||||
{
|
||||
TemplateBuilder? builder = new();
|
||||
builderDelegate?.Invoke(builder);
|
||||
|
||||
serviceCollection
|
||||
.AddSingleton(builder.Descriptors)
|
||||
.AddSingleton<ITemplateDescriptorProvider, TemplateDescriptorProvider>()
|
||||
.AddSingleton<ITemplateFactory, TemplateFactory>()
|
||||
.AddSingleton<INamedTemplateFactory, NamedTemplateFactory>()
|
||||
.AddSingleton<ITypedDataTemplateFactory, TypedDataTemplateFactory>()
|
||||
.AddSingleton<INamedDataTemplateFactory, NamedDataTemplateFactory>()
|
||||
.AddSingleton<ITemplateSelector, TemplateSelector>();
|
||||
|
||||
foreach (ITemplateDescriptor? descriptor in builder.Descriptors)
|
||||
{
|
||||
serviceCollection.Add(new ServiceDescriptor(descriptor.TemplateType, descriptor.TemplateType, descriptor.Lifetime));
|
||||
serviceCollection.Add(new ServiceDescriptor(descriptor.DataType, descriptor.DataType, descriptor.Lifetime));
|
||||
}
|
||||
});
|
||||
|
||||
return hostBuilder;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace TheXamlGuy.Framework.Avalonia;
|
||||
|
||||
public static class IServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddRequiredAvalonia(this IServiceCollection serviceCollection)
|
||||
{
|
||||
return serviceCollection
|
||||
.AddSingleton<IRouter, Router>()
|
||||
.AddSingleton<IRouteDescriptorCollection, RouteDescriptorCollection>()
|
||||
.AddSingleton<IRouterContext, RouterContext>()
|
||||
.AddTransient<IMediatorHandler<Navigate>, NavigateHandler>()
|
||||
.RegisterHandlers();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,453 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia;
|
||||
using Avalonia.Data;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using TheXamlGuy.Framework.Core;
|
||||
using TheXamlGuy.UI.Avalonia;
|
||||
|
||||
namespace TheXamlGuy.Framework.Avalonia;
|
||||
|
||||
public class NavigateExtension : TriggerExtension
|
||||
{
|
||||
private static readonly AttachedProperty<IEventAggregator> EventAggregatorProperty =
|
||||
AvaloniaProperty.RegisterAttached<NavigateExtension, Control, IEventAggregator>("EventAggregator");
|
||||
|
||||
private static readonly AttachedProperty<object> ParameterProperty =
|
||||
AvaloniaProperty.RegisterAttached<NavigateExtension, Control, object>("Parameter");
|
||||
|
||||
private static readonly AvaloniaProperty RouteProperty =
|
||||
AvaloniaProperty.RegisterAttached<NavigateExtension, Control, object>("Route");
|
||||
|
||||
private static readonly AvaloniaProperty ToProperty =
|
||||
AvaloniaProperty.RegisterAttached<NavigateExtension, Control, object>("To");
|
||||
|
||||
private readonly Binding eventAggregatorBinding;
|
||||
private readonly List<object> parameters = new();
|
||||
private readonly Binding toBinding;
|
||||
private object? route;
|
||||
private Binding? routeBinding;
|
||||
|
||||
public NavigateExtension(object eventAggregator,
|
||||
object to)
|
||||
{
|
||||
eventAggregatorBinding = eventAggregator.ToBinding();
|
||||
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
|
||||
}
|
||||
|
||||
public NavigateExtension(object eventAggregator,
|
||||
object to,
|
||||
object args1)
|
||||
{
|
||||
eventAggregatorBinding = eventAggregator.ToBinding();
|
||||
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
|
||||
|
||||
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
|
||||
}
|
||||
|
||||
public NavigateExtension(object eventAggregator,
|
||||
object to,
|
||||
object args1,
|
||||
object args2)
|
||||
{
|
||||
eventAggregatorBinding = eventAggregator.ToBinding();
|
||||
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
|
||||
|
||||
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
|
||||
parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding());
|
||||
}
|
||||
|
||||
public NavigateExtension(object eventAggregator,
|
||||
object to,
|
||||
object args1,
|
||||
object args2,
|
||||
object args3)
|
||||
{
|
||||
eventAggregatorBinding = eventAggregator.ToBinding();
|
||||
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
|
||||
|
||||
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
|
||||
parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding());
|
||||
parameters.Add(args3 is MarkupExtension ? args3 : args3.ToBinding());
|
||||
}
|
||||
|
||||
public NavigateExtension(object eventAggregator,
|
||||
object to,
|
||||
object args1,
|
||||
object args2,
|
||||
object args3,
|
||||
object args4)
|
||||
{
|
||||
eventAggregatorBinding = eventAggregator.ToBinding();
|
||||
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
|
||||
|
||||
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
|
||||
parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding());
|
||||
parameters.Add(args3 is MarkupExtension ? args3 : args3.ToBinding());
|
||||
parameters.Add(args4 is MarkupExtension ? args4 : args4.ToBinding());
|
||||
}
|
||||
|
||||
public NavigateExtension(object eventAggregator,
|
||||
object to,
|
||||
object args1,
|
||||
object args2,
|
||||
object args3,
|
||||
object args4,
|
||||
object args5)
|
||||
{
|
||||
eventAggregatorBinding = eventAggregator.ToBinding();
|
||||
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
|
||||
|
||||
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
|
||||
parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding());
|
||||
parameters.Add(args3 is MarkupExtension ? args3 : args3.ToBinding());
|
||||
parameters.Add(args4 is MarkupExtension ? args4 : args4.ToBinding());
|
||||
parameters.Add(args5 is MarkupExtension ? args5 : args5.ToBinding());
|
||||
}
|
||||
|
||||
public NavigateExtension(object eventAggregator,
|
||||
object to,
|
||||
object args1,
|
||||
object args2,
|
||||
object args3,
|
||||
object args4,
|
||||
object args5,
|
||||
object args6)
|
||||
{
|
||||
eventAggregatorBinding = eventAggregator.ToBinding();
|
||||
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
|
||||
|
||||
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
|
||||
parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding());
|
||||
parameters.Add(args3 is MarkupExtension ? args3 : args3.ToBinding());
|
||||
parameters.Add(args4 is MarkupExtension ? args4 : args4.ToBinding());
|
||||
parameters.Add(args5 is MarkupExtension ? args5 : args5.ToBinding());
|
||||
parameters.Add(args6 is MarkupExtension ? args6 : args6.ToBinding());
|
||||
}
|
||||
|
||||
public NavigateExtension(object eventAggregator,
|
||||
object to,
|
||||
object args1,
|
||||
object args2,
|
||||
object args3,
|
||||
object args4,
|
||||
object args5,
|
||||
object args6,
|
||||
object args7)
|
||||
{
|
||||
eventAggregatorBinding = eventAggregator.ToBinding();
|
||||
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
|
||||
|
||||
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
|
||||
parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding());
|
||||
parameters.Add(args3 is MarkupExtension ? args3 : args3.ToBinding());
|
||||
parameters.Add(args4 is MarkupExtension ? args4 : args4.ToBinding());
|
||||
parameters.Add(args5 is MarkupExtension ? args5 : args5.ToBinding());
|
||||
parameters.Add(args6 is MarkupExtension ? args6 : args6.ToBinding());
|
||||
parameters.Add(args7 is MarkupExtension ? args7 : args7.ToBinding());
|
||||
}
|
||||
|
||||
public NavigateExtension(object eventAggregator,
|
||||
object to,
|
||||
object args1,
|
||||
object args2,
|
||||
object args3,
|
||||
object args4,
|
||||
object args5,
|
||||
object args6,
|
||||
object args7,
|
||||
object args8)
|
||||
{
|
||||
eventAggregatorBinding = eventAggregator.ToBinding();
|
||||
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
|
||||
|
||||
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
|
||||
parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding());
|
||||
parameters.Add(args3 is MarkupExtension ? args3 : args3.ToBinding());
|
||||
parameters.Add(args4 is MarkupExtension ? args4 : args4.ToBinding());
|
||||
parameters.Add(args5 is MarkupExtension ? args5 : args5.ToBinding());
|
||||
parameters.Add(args6 is MarkupExtension ? args6 : args6.ToBinding());
|
||||
parameters.Add(args7 is MarkupExtension ? args7 : args7.ToBinding());
|
||||
parameters.Add(args8 is MarkupExtension ? args8 : args8.ToBinding());
|
||||
}
|
||||
|
||||
public NavigateExtension(object eventAggregator,
|
||||
object to,
|
||||
object args1,
|
||||
object args2,
|
||||
object args3,
|
||||
object args4,
|
||||
object args5,
|
||||
object args6,
|
||||
object args7,
|
||||
object args8,
|
||||
object args9)
|
||||
{
|
||||
eventAggregatorBinding = eventAggregator.ToBinding();
|
||||
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
|
||||
|
||||
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
|
||||
parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding());
|
||||
parameters.Add(args3 is MarkupExtension ? args3 : args3.ToBinding());
|
||||
parameters.Add(args4 is MarkupExtension ? args4 : args4.ToBinding());
|
||||
parameters.Add(args5 is MarkupExtension ? args5 : args5.ToBinding());
|
||||
parameters.Add(args6 is MarkupExtension ? args6 : args6.ToBinding());
|
||||
parameters.Add(args7 is MarkupExtension ? args7 : args7.ToBinding());
|
||||
parameters.Add(args8 is MarkupExtension ? args8 : args8.ToBinding());
|
||||
parameters.Add(args9 is MarkupExtension ? args9 : args9.ToBinding());
|
||||
}
|
||||
|
||||
public NavigateExtension(object eventAggregator,
|
||||
object to,
|
||||
object args1,
|
||||
object args2,
|
||||
object args3,
|
||||
object args4,
|
||||
object args5,
|
||||
object args6,
|
||||
object args7,
|
||||
object args8,
|
||||
object args9,
|
||||
object args10)
|
||||
{
|
||||
eventAggregatorBinding = eventAggregator.ToBinding();
|
||||
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
|
||||
|
||||
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
|
||||
parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding());
|
||||
parameters.Add(args3 is MarkupExtension ? args3 : args3.ToBinding());
|
||||
parameters.Add(args4 is MarkupExtension ? args4 : args4.ToBinding());
|
||||
parameters.Add(args5 is MarkupExtension ? args5 : args5.ToBinding());
|
||||
parameters.Add(args6 is MarkupExtension ? args6 : args6.ToBinding());
|
||||
parameters.Add(args7 is MarkupExtension ? args7 : args7.ToBinding());
|
||||
parameters.Add(args8 is MarkupExtension ? args8 : args8.ToBinding());
|
||||
parameters.Add(args9 is MarkupExtension ? args9 : args9.ToBinding());
|
||||
parameters.Add(args10 is MarkupExtension ? args10 : args10.ToBinding());
|
||||
}
|
||||
|
||||
public NavigateExtension(object eventAggregator,
|
||||
object to,
|
||||
object args1,
|
||||
object args2,
|
||||
object args3,
|
||||
object args4,
|
||||
object args5,
|
||||
object args6,
|
||||
object args7,
|
||||
object args8,
|
||||
object args9,
|
||||
object args10,
|
||||
object args11)
|
||||
{
|
||||
eventAggregatorBinding = eventAggregator.ToBinding();
|
||||
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
|
||||
|
||||
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
|
||||
parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding());
|
||||
parameters.Add(args3 is MarkupExtension ? args3 : args3.ToBinding());
|
||||
parameters.Add(args4 is MarkupExtension ? args4 : args4.ToBinding());
|
||||
parameters.Add(args5 is MarkupExtension ? args5 : args5.ToBinding());
|
||||
parameters.Add(args6 is MarkupExtension ? args6 : args6.ToBinding());
|
||||
parameters.Add(args7 is MarkupExtension ? args7 : args7.ToBinding());
|
||||
parameters.Add(args8 is MarkupExtension ? args8 : args8.ToBinding());
|
||||
parameters.Add(args9 is MarkupExtension ? args9 : args9.ToBinding());
|
||||
parameters.Add(args10 is MarkupExtension ? args10 : args10.ToBinding());
|
||||
parameters.Add(args11 is MarkupExtension ? args11 : args11.ToBinding());
|
||||
}
|
||||
|
||||
public NavigateExtension(object eventAggregator,
|
||||
object to,
|
||||
object args1,
|
||||
object args2,
|
||||
object args3,
|
||||
object args4,
|
||||
object args5,
|
||||
object args6,
|
||||
object args7,
|
||||
object args8,
|
||||
object args9,
|
||||
object args10,
|
||||
object args11,
|
||||
object args12)
|
||||
{
|
||||
eventAggregatorBinding = eventAggregator.ToBinding();
|
||||
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
|
||||
|
||||
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
|
||||
parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding());
|
||||
parameters.Add(args3 is MarkupExtension ? args3 : args3.ToBinding());
|
||||
parameters.Add(args4 is MarkupExtension ? args4 : args4.ToBinding());
|
||||
parameters.Add(args5 is MarkupExtension ? args5 : args5.ToBinding());
|
||||
parameters.Add(args6 is MarkupExtension ? args6 : args6.ToBinding());
|
||||
parameters.Add(args7 is MarkupExtension ? args7 : args7.ToBinding());
|
||||
parameters.Add(args8 is MarkupExtension ? args8 : args8.ToBinding());
|
||||
parameters.Add(args9 is MarkupExtension ? args9 : args9.ToBinding());
|
||||
parameters.Add(args10 is MarkupExtension ? args10 : args10.ToBinding());
|
||||
parameters.Add(args11 is MarkupExtension ? args11 : args11.ToBinding());
|
||||
parameters.Add(args12 is MarkupExtension ? args12 : args12.ToBinding());
|
||||
}
|
||||
|
||||
public NavigateExtension(object eventAggregator,
|
||||
object to,
|
||||
object args1,
|
||||
object args2,
|
||||
object args3,
|
||||
object args4,
|
||||
object args5,
|
||||
object args6,
|
||||
object args7,
|
||||
object args8,
|
||||
object args9,
|
||||
object args10,
|
||||
object args11,
|
||||
object args12,
|
||||
object args13)
|
||||
{
|
||||
eventAggregatorBinding = eventAggregator.ToBinding();
|
||||
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
|
||||
|
||||
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
|
||||
parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding());
|
||||
parameters.Add(args3 is MarkupExtension ? args3 : args3.ToBinding());
|
||||
parameters.Add(args4 is MarkupExtension ? args4 : args4.ToBinding());
|
||||
parameters.Add(args5 is MarkupExtension ? args5 : args5.ToBinding());
|
||||
parameters.Add(args6 is MarkupExtension ? args6 : args6.ToBinding());
|
||||
parameters.Add(args7 is MarkupExtension ? args7 : args7.ToBinding());
|
||||
parameters.Add(args8 is MarkupExtension ? args8 : args8.ToBinding());
|
||||
parameters.Add(args9 is MarkupExtension ? args9 : args9.ToBinding());
|
||||
parameters.Add(args10 is MarkupExtension ? args10 : args10.ToBinding());
|
||||
parameters.Add(args11 is MarkupExtension ? args11 : args11.ToBinding());
|
||||
parameters.Add(args12 is MarkupExtension ? args12 : args12.ToBinding());
|
||||
parameters.Add(args13 is MarkupExtension ? args13 : args13.ToBinding());
|
||||
}
|
||||
|
||||
public NavigateExtension(object eventAggregator,
|
||||
object to,
|
||||
object args1,
|
||||
object args2,
|
||||
object args3,
|
||||
object args4,
|
||||
object args5,
|
||||
object args6,
|
||||
object args7,
|
||||
object args8,
|
||||
object args9,
|
||||
object args10,
|
||||
object args11,
|
||||
object args12,
|
||||
object args13,
|
||||
object args14)
|
||||
{
|
||||
eventAggregatorBinding = eventAggregator.ToBinding();
|
||||
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
|
||||
|
||||
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
|
||||
parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding());
|
||||
parameters.Add(args3 is MarkupExtension ? args3 : args3.ToBinding());
|
||||
parameters.Add(args4 is MarkupExtension ? args4 : args4.ToBinding());
|
||||
parameters.Add(args5 is MarkupExtension ? args5 : args5.ToBinding());
|
||||
parameters.Add(args6 is MarkupExtension ? args6 : args6.ToBinding());
|
||||
parameters.Add(args7 is MarkupExtension ? args7 : args7.ToBinding());
|
||||
parameters.Add(args8 is MarkupExtension ? args8 : args8.ToBinding());
|
||||
parameters.Add(args9 is MarkupExtension ? args9 : args9.ToBinding());
|
||||
parameters.Add(args10 is MarkupExtension ? args10 : args10.ToBinding());
|
||||
parameters.Add(args11 is MarkupExtension ? args11 : args11.ToBinding());
|
||||
parameters.Add(args12 is MarkupExtension ? args12 : args12.ToBinding());
|
||||
parameters.Add(args13 is MarkupExtension ? args13 : args13.ToBinding());
|
||||
parameters.Add(args14 is MarkupExtension ? args14 : args14.ToBinding());
|
||||
}
|
||||
|
||||
public NavigateExtension(object eventAggregator,
|
||||
object to,
|
||||
object args1,
|
||||
object args2,
|
||||
object args3,
|
||||
object args4,
|
||||
object args5,
|
||||
object args6,
|
||||
object args7,
|
||||
object args8,
|
||||
object args9,
|
||||
object args10,
|
||||
object args11,
|
||||
object args12,
|
||||
object args13,
|
||||
object args14,
|
||||
object args15)
|
||||
{
|
||||
eventAggregatorBinding = eventAggregator.ToBinding();
|
||||
this.toBinding = to is Binding toBinding ? toBinding : to.ToBinding();
|
||||
|
||||
parameters.Add(args1 is MarkupExtension ? args1 : args1.ToBinding());
|
||||
parameters.Add(args2 is MarkupExtension ? args2 : args2.ToBinding());
|
||||
parameters.Add(args3 is MarkupExtension ? args3 : args3.ToBinding());
|
||||
parameters.Add(args4 is MarkupExtension ? args4 : args4.ToBinding());
|
||||
parameters.Add(args5 is MarkupExtension ? args5 : args5.ToBinding());
|
||||
parameters.Add(args6 is MarkupExtension ? args6 : args6.ToBinding());
|
||||
parameters.Add(args7 is MarkupExtension ? args7 : args7.ToBinding());
|
||||
parameters.Add(args8 is MarkupExtension ? args8 : args8.ToBinding());
|
||||
parameters.Add(args9 is MarkupExtension ? args9 : args9.ToBinding());
|
||||
parameters.Add(args10 is MarkupExtension ? args10 : args10.ToBinding());
|
||||
parameters.Add(args11 is MarkupExtension ? args11 : args11.ToBinding());
|
||||
parameters.Add(args12 is MarkupExtension ? args12 : args12.ToBinding());
|
||||
parameters.Add(args13 is MarkupExtension ? args13 : args13.ToBinding());
|
||||
parameters.Add(args14 is MarkupExtension ? args14 : args14.ToBinding());
|
||||
parameters.Add(args15 is MarkupExtension ? args15 : args15.ToBinding());
|
||||
}
|
||||
|
||||
public object? Route
|
||||
{
|
||||
get
|
||||
{
|
||||
return route;
|
||||
}
|
||||
set
|
||||
{
|
||||
route = value;
|
||||
if (route is not null)
|
||||
{
|
||||
routeBinding = route.ToBinding();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected override void OnInvoked(object sender, EventArgs args)
|
||||
{
|
||||
if (TargetObject is not null)
|
||||
{
|
||||
TargetObject.Bind(EventAggregatorProperty, eventAggregatorBinding);
|
||||
if (TargetObject.GetValue(EventAggregatorProperty) is IEventAggregator eventAggregator)
|
||||
{
|
||||
TargetObject.Bind(ToProperty, toBinding);
|
||||
if (TargetObject.GetValue(ToProperty) is { } to)
|
||||
{
|
||||
object? route = null;
|
||||
if (routeBinding is not null)
|
||||
{
|
||||
TargetObject.Bind(RouteProperty, routeBinding);
|
||||
route = TargetObject.GetValue(RouteProperty);
|
||||
}
|
||||
|
||||
if (to is string name)
|
||||
{
|
||||
if (toBinding?.StringFormat is string format)
|
||||
{
|
||||
name = string.Format(format, name);
|
||||
}
|
||||
|
||||
eventAggregator.Publish(new Navigate(name, parameters.ToArray()) { Route = route });
|
||||
}
|
||||
|
||||
if (to is Type type)
|
||||
{
|
||||
eventAggregator.Publish(new Navigate(type, parameters.ToArray()) { Route = route });
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
base.OnInvoked(sender, args);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Data;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using TheXamlGuy.UI.Avalonia;
|
||||
|
||||
namespace TheXamlGuy.Framework.Avalonia;
|
||||
|
||||
public class RouteExtension : MarkupExtension
|
||||
{
|
||||
private static readonly AttachedProperty<object> RouteProperty =
|
||||
AvaloniaProperty.RegisterAttached<RouteExtension, Control, object>("Route");
|
||||
|
||||
private readonly string name;
|
||||
private readonly Binding routeBinding;
|
||||
|
||||
public RouteExtension(object route, string name)
|
||||
{
|
||||
routeBinding = route.ToBinding();
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
private bool TryGetBinding(AvaloniaObject sender, out object? binding)
|
||||
{
|
||||
binding = sender.GetValue(StyledElement.DataContextProperty);
|
||||
return binding is not null;
|
||||
}
|
||||
|
||||
public override object? ProvideValue(IServiceProvider serviceProvider)
|
||||
{
|
||||
if (serviceProvider.GetService(typeof(IProvideValueTarget)) is IProvideValueTarget target)
|
||||
{
|
||||
if (target.TargetObject is TemplatedControl control)
|
||||
{
|
||||
if (!TryGetBinding(control, out object? binding))
|
||||
{
|
||||
void HandleDataContextChanged(object? sender, EventArgs args)
|
||||
{
|
||||
if (TryGetBinding(control, out binding))
|
||||
{
|
||||
control.Loaded -= HandleLoaded;
|
||||
control.Bind(RouteProperty, routeBinding);
|
||||
|
||||
if (control?.GetValue(RouteProperty) is IRouter route)
|
||||
{
|
||||
route.Add(name, control);
|
||||
control.ClearValue(RouteProperty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
control.DataContextChanged += HandleDataContextChanged;
|
||||
|
||||
void HandleLoaded(object? sender, RoutedEventArgs args)
|
||||
{
|
||||
control.Loaded -= HandleLoaded;
|
||||
if (TryGetBinding(control, out binding))
|
||||
{
|
||||
control.Bind(RouteProperty, routeBinding);
|
||||
if (control?.GetValue(RouteProperty) is IRouter route)
|
||||
{
|
||||
route.Add(name, control);
|
||||
control.ClearValue(RouteProperty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
control.Loaded += HandleLoaded;
|
||||
}
|
||||
else
|
||||
{
|
||||
control.Bind(RouteProperty, routeBinding);
|
||||
if (control?.GetValue(RouteProperty) is IRouter route)
|
||||
{
|
||||
route.Add(name, control);
|
||||
control.ClearValue(RouteProperty);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
using Avalonia.Metadata;
|
||||
|
||||
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "TheXamlGuy.Framework.Avalonia")]
|
||||
Binary file not shown.
@@ -0,0 +1,30 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
|
||||
namespace TheXamlGuy.Framework.Avalonia;
|
||||
|
||||
public class ContentDialogRouteHandler : RouteHandler<ContentDialog>
|
||||
{
|
||||
public override async void Handle(Route<ContentDialog> request)
|
||||
{
|
||||
if (request.Template is ContentDialog contentDialog)
|
||||
{
|
||||
contentDialog.DataContext = request.Data;
|
||||
await contentDialog.ShowAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class ContentControlRouteHandler : RouteHandler<ContentControl>
|
||||
{
|
||||
public override void Handle(Route<ContentControl> request)
|
||||
{
|
||||
if (request.Template is TemplatedControl control)
|
||||
{
|
||||
control.DataContext = request.Data;
|
||||
request.Target.Content = control;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using Avalonia.Controls.Primitives;
|
||||
using FluentAvalonia.UI.Controls;
|
||||
using FluentAvalonia.UI.Navigation;
|
||||
|
||||
namespace TheXamlGuy.Framework.Avalonia;
|
||||
|
||||
public class FrameRouteHandler : RouteHandler<Frame>
|
||||
{
|
||||
public override void Handle(Route<Frame> request)
|
||||
{
|
||||
if (request.Template is Type type)
|
||||
{
|
||||
void HandleNavigated(object sender, NavigationEventArgs args)
|
||||
{
|
||||
request.Target.Navigated -= HandleNavigated;
|
||||
if (request.Target.Content is TemplatedControl control)
|
||||
{
|
||||
control.DataContext = request.Data;
|
||||
}
|
||||
}
|
||||
|
||||
request.Target.Navigated += HandleNavigated;
|
||||
request.Target.Navigate(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace TheXamlGuy.Framework.Avalonia;
|
||||
|
||||
public interface IRouteDescriptor
|
||||
{
|
||||
object Route { get; }
|
||||
|
||||
string? Name { get; }
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace TheXamlGuy.Framework.Avalonia;
|
||||
|
||||
public interface IRouteDescriptorCollection : IList<IRouteDescriptor>
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace TheXamlGuy.Framework.Avalonia;
|
||||
|
||||
public interface IRouter
|
||||
{
|
||||
void Add(string name, object route);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using TheXamlGuy.Framework.Core;
|
||||
|
||||
namespace TheXamlGuy.Framework.Avalonia
|
||||
{
|
||||
public class NavigateHandler : IMediatorHandler<Navigate>
|
||||
{
|
||||
private readonly IEventAggregator eventAggregator;
|
||||
|
||||
public NavigateHandler(IEventAggregator eventAggregator)
|
||||
{
|
||||
this.eventAggregator = eventAggregator;
|
||||
}
|
||||
|
||||
public void Handle(Navigate request)
|
||||
{
|
||||
eventAggregator.Publish(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
namespace TheXamlGuy.Framework.Avalonia;
|
||||
|
||||
public class Navigated<TContent, TDataContext> where TContent : class where TDataContext : class
|
||||
{
|
||||
public Navigated()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public Navigated(TContent content, TDataContext dataContext, IDictionary<string, object>? parameters = null)
|
||||
{
|
||||
Content = content;
|
||||
DataContext = dataContext;
|
||||
Parameters = parameters;
|
||||
}
|
||||
|
||||
public TContent? Content { get; }
|
||||
|
||||
public TDataContext? DataContext { get; }
|
||||
|
||||
public IDictionary<string, object>? Parameters { get; }
|
||||
}
|
||||
|
||||
public class Navigated
|
||||
{
|
||||
public static Navigated<TContent, TDataTemplate> Create<TContent, TDataTemplate>(TContent content, TDataTemplate dataContext, IDictionary<string, object>? parameters = null) where TContent : class where TDataTemplate : class
|
||||
{
|
||||
return new Navigated<TContent, TDataTemplate>(content, dataContext, parameters);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
using Avalonia.Controls.Primitives;
|
||||
|
||||
namespace TheXamlGuy.Framework.Avalonia;
|
||||
|
||||
public record Route<TTarget>(TTarget Target, object? Data, object? Template) where TTarget : TemplatedControl;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user