Skip to content

Commit 7e2c0e8

Browse files
committed
Add initial PTZControl2 Avalonia GUI
1 parent 50b5ca4 commit 7e2c0e8

11 files changed

Lines changed: 434 additions & 8 deletions

File tree

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
using System.Runtime.Versioning;
77
using PTZControl.Uvc;
88

9-
namespace PTZControlConsole;
9+
namespace PTZControl.Core;
1010

11-
internal interface ICameraBackend
11+
public interface ICameraBackend
1212
{
1313
IReadOnlyList<CameraInfo> Enumerate();
1414
string GetDirectShowCameraName(string devicePath);
@@ -23,7 +23,7 @@ internal interface ICameraBackend
2323
void RestorePreset(string camera, int presetNumber);
2424
}
2525

26-
internal static class CameraBackendFactory
26+
public static class CameraBackendFactory
2727
{
2828
public static ICameraBackend Create()
2929
{
@@ -41,7 +41,7 @@ public static ICameraBackend Create()
4141
}
4242

4343
[SupportedOSPlatform("windows")]
44-
internal sealed class WindowsUvcCameraBackend : ICameraBackend
44+
public sealed class WindowsUvcCameraBackend : ICameraBackend
4545
{
4646
public IReadOnlyList<CameraInfo> Enumerate() => UvcCamera.Enumerate();
4747

@@ -110,7 +110,7 @@ public void RestorePreset(string camera, int presetNumber) =>
110110
UvcCamera.RestorePreset(camera, presetNumber);
111111
}
112112

113-
internal sealed class LinuxPreviewCameraBackend : ICameraBackend
113+
public sealed class LinuxPreviewCameraBackend : ICameraBackend
114114
{
115115
private const int OReadWrite = 2;
116116
private const uint V4L2CtrlFlagDisabled = 0x0001;
@@ -324,7 +324,7 @@ private unsafe struct V4L2QueryControl
324324
}
325325
}
326326

327-
internal sealed class UnsupportedCameraBackend(string message) : ICameraBackend
327+
public sealed class UnsupportedCameraBackend(string message) : ICameraBackend
328328
{
329329
public IReadOnlyList<CameraInfo> Enumerate() => throw new NotSupportedException(message);
330330

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<TargetFramework>net8.0</TargetFramework>
4+
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
5+
<ImplicitUsings>enable</ImplicitUsings>
6+
<Nullable>enable</Nullable>
7+
<PackageLicenseExpression>GPL-3.0-only</PackageLicenseExpression>
8+
<Copyright>PTZControl contributors</Copyright>
9+
</PropertyGroup>
10+
<ItemGroup>
11+
<ProjectReference Include="..\PTZControl.Uvc\PTZControl.Uvc.csproj" />
12+
</ItemGroup>
13+
</Project>

PTZControl.sln

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,88 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio Version 18
4-
VisualStudioVersion = 18.6.11819.183 stable
4+
VisualStudioVersion = 18.6.11819.183
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PTZControl", "PTZControl\PTZControl.vcxproj", "{2E2437DA-35E2-4D0D-B1DF-26E1DFEE1FB9}"
77
EndProject
88
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PTZControl.Uvc", "PTZControl.Uvc\PTZControl.Uvc.csproj", "{5F3D4F83-6E39-4F17-8C2E-1F0B4D14B4C2}"
99
EndProject
1010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PTZControlConsole", "PTZControlConsole\PTZControlConsole.csproj", "{9B3E3F5E-62A0-4A8D-9C42-9F6A1A21E3B1}"
1111
EndProject
12+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PTZControl.Core", "PTZControl.Core\PTZControl.Core.csproj", "{C541C70D-B081-4B91-9E3E-4DEA1D865992}"
13+
EndProject
14+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PTZControl2", "PTZControl2\PTZControl2.csproj", "{0B51F122-F977-4A65-B857-53AE93B81FEC}"
15+
EndProject
1216
Global
1317
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1418
Debug|Any CPU = Debug|Any CPU
1519
Debug|x86 = Debug|x86
20+
Debug|x64 = Debug|x64
1621
Release|Any CPU = Release|Any CPU
1722
Release|x86 = Release|x86
23+
Release|x64 = Release|x64
1824
EndGlobalSection
1925
GlobalSection(ProjectConfigurationPlatforms) = postSolution
2026
{2E2437DA-35E2-4D0D-B1DF-26E1DFEE1FB9}.Debug|Any CPU.ActiveCfg = Debug|x64
2127
{2E2437DA-35E2-4D0D-B1DF-26E1DFEE1FB9}.Debug|Any CPU.Build.0 = Debug|x64
2228
{2E2437DA-35E2-4D0D-B1DF-26E1DFEE1FB9}.Debug|x86.ActiveCfg = Debug|Win32
2329
{2E2437DA-35E2-4D0D-B1DF-26E1DFEE1FB9}.Debug|x86.Build.0 = Debug|Win32
30+
{2E2437DA-35E2-4D0D-B1DF-26E1DFEE1FB9}.Debug|x64.ActiveCfg = Debug|x64
31+
{2E2437DA-35E2-4D0D-B1DF-26E1DFEE1FB9}.Debug|x64.Build.0 = Debug|x64
2432
{2E2437DA-35E2-4D0D-B1DF-26E1DFEE1FB9}.Release|Any CPU.ActiveCfg = Release|x64
2533
{2E2437DA-35E2-4D0D-B1DF-26E1DFEE1FB9}.Release|Any CPU.Build.0 = Release|x64
2634
{2E2437DA-35E2-4D0D-B1DF-26E1DFEE1FB9}.Release|x86.ActiveCfg = Release|Win32
2735
{2E2437DA-35E2-4D0D-B1DF-26E1DFEE1FB9}.Release|x86.Build.0 = Release|Win32
36+
{2E2437DA-35E2-4D0D-B1DF-26E1DFEE1FB9}.Release|x64.ActiveCfg = Release|x64
37+
{2E2437DA-35E2-4D0D-B1DF-26E1DFEE1FB9}.Release|x64.Build.0 = Release|x64
2838
{5F3D4F83-6E39-4F17-8C2E-1F0B4D14B4C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
2939
{5F3D4F83-6E39-4F17-8C2E-1F0B4D14B4C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
3040
{5F3D4F83-6E39-4F17-8C2E-1F0B4D14B4C2}.Debug|x86.ActiveCfg = Debug|Any CPU
3141
{5F3D4F83-6E39-4F17-8C2E-1F0B4D14B4C2}.Debug|x86.Build.0 = Debug|Any CPU
42+
{5F3D4F83-6E39-4F17-8C2E-1F0B4D14B4C2}.Debug|x64.ActiveCfg = Debug|Any CPU
43+
{5F3D4F83-6E39-4F17-8C2E-1F0B4D14B4C2}.Debug|x64.Build.0 = Debug|Any CPU
3244
{5F3D4F83-6E39-4F17-8C2E-1F0B4D14B4C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
3345
{5F3D4F83-6E39-4F17-8C2E-1F0B4D14B4C2}.Release|Any CPU.Build.0 = Release|Any CPU
3446
{5F3D4F83-6E39-4F17-8C2E-1F0B4D14B4C2}.Release|x86.ActiveCfg = Release|Any CPU
3547
{5F3D4F83-6E39-4F17-8C2E-1F0B4D14B4C2}.Release|x86.Build.0 = Release|Any CPU
48+
{5F3D4F83-6E39-4F17-8C2E-1F0B4D14B4C2}.Release|x64.ActiveCfg = Release|Any CPU
49+
{5F3D4F83-6E39-4F17-8C2E-1F0B4D14B4C2}.Release|x64.Build.0 = Release|Any CPU
3650
{9B3E3F5E-62A0-4A8D-9C42-9F6A1A21E3B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
3751
{9B3E3F5E-62A0-4A8D-9C42-9F6A1A21E3B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
3852
{9B3E3F5E-62A0-4A8D-9C42-9F6A1A21E3B1}.Debug|x86.ActiveCfg = Debug|Any CPU
3953
{9B3E3F5E-62A0-4A8D-9C42-9F6A1A21E3B1}.Debug|x86.Build.0 = Debug|Any CPU
54+
{9B3E3F5E-62A0-4A8D-9C42-9F6A1A21E3B1}.Debug|x64.ActiveCfg = Debug|Any CPU
55+
{9B3E3F5E-62A0-4A8D-9C42-9F6A1A21E3B1}.Debug|x64.Build.0 = Debug|Any CPU
4056
{9B3E3F5E-62A0-4A8D-9C42-9F6A1A21E3B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
4157
{9B3E3F5E-62A0-4A8D-9C42-9F6A1A21E3B1}.Release|Any CPU.Build.0 = Release|Any CPU
4258
{9B3E3F5E-62A0-4A8D-9C42-9F6A1A21E3B1}.Release|x86.ActiveCfg = Release|Any CPU
4359
{9B3E3F5E-62A0-4A8D-9C42-9F6A1A21E3B1}.Release|x86.Build.0 = Release|Any CPU
60+
{9B3E3F5E-62A0-4A8D-9C42-9F6A1A21E3B1}.Release|x64.ActiveCfg = Release|Any CPU
61+
{9B3E3F5E-62A0-4A8D-9C42-9F6A1A21E3B1}.Release|x64.Build.0 = Release|Any CPU
62+
{C541C70D-B081-4B91-9E3E-4DEA1D865992}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
63+
{C541C70D-B081-4B91-9E3E-4DEA1D865992}.Debug|Any CPU.Build.0 = Debug|Any CPU
64+
{C541C70D-B081-4B91-9E3E-4DEA1D865992}.Debug|x86.ActiveCfg = Debug|Any CPU
65+
{C541C70D-B081-4B91-9E3E-4DEA1D865992}.Debug|x86.Build.0 = Debug|Any CPU
66+
{C541C70D-B081-4B91-9E3E-4DEA1D865992}.Debug|x64.ActiveCfg = Debug|Any CPU
67+
{C541C70D-B081-4B91-9E3E-4DEA1D865992}.Debug|x64.Build.0 = Debug|Any CPU
68+
{C541C70D-B081-4B91-9E3E-4DEA1D865992}.Release|Any CPU.ActiveCfg = Release|Any CPU
69+
{C541C70D-B081-4B91-9E3E-4DEA1D865992}.Release|Any CPU.Build.0 = Release|Any CPU
70+
{C541C70D-B081-4B91-9E3E-4DEA1D865992}.Release|x86.ActiveCfg = Release|Any CPU
71+
{C541C70D-B081-4B91-9E3E-4DEA1D865992}.Release|x86.Build.0 = Release|Any CPU
72+
{C541C70D-B081-4B91-9E3E-4DEA1D865992}.Release|x64.ActiveCfg = Release|Any CPU
73+
{C541C70D-B081-4B91-9E3E-4DEA1D865992}.Release|x64.Build.0 = Release|Any CPU
74+
{0B51F122-F977-4A65-B857-53AE93B81FEC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
75+
{0B51F122-F977-4A65-B857-53AE93B81FEC}.Debug|Any CPU.Build.0 = Debug|Any CPU
76+
{0B51F122-F977-4A65-B857-53AE93B81FEC}.Debug|x86.ActiveCfg = Debug|Any CPU
77+
{0B51F122-F977-4A65-B857-53AE93B81FEC}.Debug|x86.Build.0 = Debug|Any CPU
78+
{0B51F122-F977-4A65-B857-53AE93B81FEC}.Debug|x64.ActiveCfg = Debug|Any CPU
79+
{0B51F122-F977-4A65-B857-53AE93B81FEC}.Debug|x64.Build.0 = Debug|Any CPU
80+
{0B51F122-F977-4A65-B857-53AE93B81FEC}.Release|Any CPU.ActiveCfg = Release|Any CPU
81+
{0B51F122-F977-4A65-B857-53AE93B81FEC}.Release|Any CPU.Build.0 = Release|Any CPU
82+
{0B51F122-F977-4A65-B857-53AE93B81FEC}.Release|x86.ActiveCfg = Release|Any CPU
83+
{0B51F122-F977-4A65-B857-53AE93B81FEC}.Release|x86.Build.0 = Release|Any CPU
84+
{0B51F122-F977-4A65-B857-53AE93B81FEC}.Release|x64.ActiveCfg = Release|Any CPU
85+
{0B51F122-F977-4A65-B857-53AE93B81FEC}.Release|x64.Build.0 = Release|Any CPU
4486
EndGlobalSection
4587
GlobalSection(SolutionProperties) = preSolution
4688
HideSolutionNode = FALSE

PTZControl2/App.axaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<Application xmlns="https://github.com/avaloniaui"
2+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
3+
x:Class="PTZControl2.App">
4+
<Application.Styles>
5+
<FluentTheme />
6+
</Application.Styles>
7+
</Application>

PTZControl2/App.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using Avalonia;
2+
using Avalonia.Controls.ApplicationLifetimes;
3+
using Avalonia.Markup.Xaml;
4+
5+
namespace PTZControl2;
6+
7+
public sealed class App : Application
8+
{
9+
public override void Initialize()
10+
{
11+
AvaloniaXamlLoader.Load(this);
12+
}
13+
14+
public override void OnFrameworkInitializationCompleted()
15+
{
16+
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
17+
desktop.MainWindow = new MainWindow();
18+
19+
base.OnFrameworkInitializationCompleted();
20+
}
21+
}

PTZControl2/MainWindow.axaml

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<Window xmlns="https://github.com/avaloniaui"
2+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
3+
x:Class="PTZControl2.MainWindow"
4+
Title="PTZControl2"
5+
Width="880"
6+
Height="620"
7+
MinWidth="640"
8+
MinHeight="460"
9+
WindowStartupLocation="CenterScreen">
10+
<Grid Margin="16" RowDefinitions="Auto,*,Auto" RowSpacing="14">
11+
<Grid ColumnDefinitions="Auto,*,Auto" ColumnSpacing="10">
12+
<TextBlock Text="Camera"
13+
VerticalAlignment="Center"
14+
FontWeight="SemiBold" />
15+
<ComboBox x:Name="CameraSelector"
16+
Grid.Column="1"
17+
MinWidth="280"
18+
VerticalAlignment="Center" />
19+
<Button Grid.Column="2"
20+
Content="Refresh"
21+
Padding="18,8"
22+
Click="RefreshButton_Click" />
23+
</Grid>
24+
25+
<Grid Grid.Row="1" ColumnDefinitions="1.25*,*" ColumnSpacing="16">
26+
<StackPanel Spacing="16">
27+
<StackPanel Spacing="8">
28+
<TextBlock Text="Presets"
29+
FontSize="18"
30+
FontWeight="SemiBold" />
31+
<UniformGrid Columns="4" Rows="2">
32+
<Button Content="Preset 1" Tag="1" MinHeight="54" Margin="4" Click="PresetButton_Click" />
33+
<Button Content="Preset 2" Tag="2" MinHeight="54" Margin="4" Click="PresetButton_Click" />
34+
<Button Content="Preset 3" Tag="3" MinHeight="54" Margin="4" Click="PresetButton_Click" />
35+
<Button Content="Preset 4" Tag="4" MinHeight="54" Margin="4" Click="PresetButton_Click" />
36+
<Button Content="Preset 5" Tag="5" MinHeight="54" Margin="4" Click="PresetButton_Click" />
37+
<Button Content="Preset 6" Tag="6" MinHeight="54" Margin="4" Click="PresetButton_Click" />
38+
<Button Content="Preset 7" Tag="7" MinHeight="54" Margin="4" Click="PresetButton_Click" />
39+
<Button Content="Preset 8" Tag="8" MinHeight="54" Margin="4" Click="PresetButton_Click" />
40+
</UniformGrid>
41+
</StackPanel>
42+
43+
<StackPanel Spacing="8">
44+
<TextBlock Text="Pan / Tilt"
45+
FontSize="18"
46+
FontWeight="SemiBold" />
47+
<Grid ColumnDefinitions="*,*,*" RowDefinitions="Auto,Auto,Auto" ColumnSpacing="8" RowSpacing="8">
48+
<Button Grid.Column="1" Grid.Row="0" Content="Tilt up" MinHeight="58" Click="TiltUpButton_Click" />
49+
<Button Grid.Column="0" Grid.Row="1" Content="Pan left" MinHeight="58" Click="PanLeftButton_Click" />
50+
<Button Grid.Column="1" Grid.Row="1" Content="Home" MinHeight="58" Click="HomeButton_Click" />
51+
<Button Grid.Column="2" Grid.Row="1" Content="Pan right" MinHeight="58" Click="PanRightButton_Click" />
52+
<Button Grid.Column="1" Grid.Row="2" Content="Tilt down" MinHeight="58" Click="TiltDownButton_Click" />
53+
</Grid>
54+
</StackPanel>
55+
56+
<StackPanel Spacing="8">
57+
<TextBlock Text="Zoom"
58+
FontSize="18"
59+
FontWeight="SemiBold" />
60+
<Grid ColumnDefinitions="*,*" ColumnSpacing="8">
61+
<Button Content="Zoom out" MinHeight="52" Click="ZoomOutButton_Click" />
62+
<Button Grid.Column="1" Content="Zoom in" MinHeight="52" Click="ZoomInButton_Click" />
63+
</Grid>
64+
<Slider x:Name="ZoomSlider"
65+
Minimum="0"
66+
Maximum="100"
67+
TickFrequency="10"
68+
IsSnapToTickEnabled="False"
69+
Value="0" />
70+
<Button Content="Set zoom" MinHeight="44" Click="SetZoomButton_Click" />
71+
</StackPanel>
72+
73+
<Grid ColumnDefinitions="*,*" ColumnSpacing="8">
74+
<Button Content="Default move" MinHeight="48" Click="DefaultMoveButton_Click" />
75+
<Button Grid.Column="1" Content="Default all" MinHeight="48" Click="DefaultAllButton_Click" />
76+
</Grid>
77+
</StackPanel>
78+
79+
<Grid Grid.Column="1" RowDefinitions="Auto,*" RowSpacing="8">
80+
<Button Content="Show camera info" MinHeight="44" Click="ShowCameraInfoButton_Click" />
81+
<TextBox x:Name="DetailsText"
82+
Grid.Row="1"
83+
IsReadOnly="True"
84+
AcceptsReturn="True"
85+
TextWrapping="Wrap"
86+
Text="Select a camera and use Refresh or Show camera info." />
87+
</Grid>
88+
</Grid>
89+
90+
<TextBlock x:Name="StatusText"
91+
Grid.Row="2"
92+
Text="Ready."
93+
TextWrapping="Wrap" />
94+
</Grid>
95+
</Window>

0 commit comments

Comments
 (0)