diff --git a/src/CamBooth/CamBooth.App/Core/BaseDialogOverlay.xaml b/src/CamBooth/CamBooth.App/Core/BaseDialogOverlay.xaml
new file mode 100644
index 0000000..568a0ad
--- /dev/null
+++ b/src/CamBooth/CamBooth.App/Core/BaseDialogOverlay.xaml
@@ -0,0 +1,58 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/CamBooth/CamBooth.App/Core/BaseDialogOverlay.xaml.cs b/src/CamBooth/CamBooth.App/Core/BaseDialogOverlay.xaml.cs
new file mode 100644
index 0000000..affd4f6
--- /dev/null
+++ b/src/CamBooth/CamBooth.App/Core/BaseDialogOverlay.xaml.cs
@@ -0,0 +1,136 @@
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+
+namespace CamBooth.App.Core;
+
+[System.Windows.Markup.ContentProperty(nameof(DialogContent))]
+public partial class BaseDialogOverlay : UserControl
+{
+ public static readonly DependencyProperty DialogTitleProperty =
+ DependencyProperty.Register(nameof(DialogTitle), typeof(string), typeof(BaseDialogOverlay),
+ new PropertyMetadata(null, OnDialogTitleChanged));
+
+ public static readonly DependencyProperty DialogContentProperty =
+ DependencyProperty.Register(nameof(DialogContent), typeof(object), typeof(BaseDialogOverlay),
+ new PropertyMetadata(null, OnDialogContentChanged));
+
+ public static readonly DependencyProperty CloseButtonTextProperty =
+ DependencyProperty.Register(nameof(CloseButtonText), typeof(string), typeof(BaseDialogOverlay),
+ new PropertyMetadata("Schließen", OnCloseButtonTextChanged));
+
+ public static readonly DependencyProperty PrimaryButtonTextProperty =
+ DependencyProperty.Register(nameof(PrimaryButtonText), typeof(string), typeof(BaseDialogOverlay),
+ new PropertyMetadata(null, OnPrimaryButtonTextChanged));
+
+
+ public string? DialogTitle
+ {
+ get => (string?)GetValue(DialogTitleProperty);
+ set => SetValue(DialogTitleProperty, value);
+ }
+
+ public object? DialogContent
+ {
+ get => GetValue(DialogContentProperty);
+ set => SetValue(DialogContentProperty, value);
+ }
+
+ public string CloseButtonText
+ {
+ get => (string)GetValue(CloseButtonTextProperty);
+ set => SetValue(CloseButtonTextProperty, value);
+ }
+
+ public string? PrimaryButtonText
+ {
+ get => (string?)GetValue(PrimaryButtonTextProperty);
+ set => SetValue(PrimaryButtonTextProperty, value);
+ }
+
+ public event EventHandler? Closed;
+ public event EventHandler? PrimaryButtonClicked;
+
+ private TaskCompletionSource? _tcs;
+
+
+ public BaseDialogOverlay()
+ {
+ InitializeComponent();
+ // Apply defaults after controls are created, since DP callbacks don't fire for default values
+ CloseActionButton.Content = CloseButtonText;
+ CloseActionButton.Foreground = new SolidColorBrush(Color.FromRgb(0x1F, 0x1A, 0x00));
+ PrimaryActionButton.Foreground = new SolidColorBrush(Color.FromRgb(0x1F, 0x1A, 0x00));
+ }
+
+
+ public void Show()
+ {
+ Visibility = Visibility.Visible;
+ }
+
+ public Task ShowAsync()
+ {
+ _tcs = new TaskCompletionSource();
+ Visibility = Visibility.Visible;
+ return _tcs.Task;
+ }
+
+ public void Hide()
+ {
+ Visibility = Visibility.Collapsed;
+ _tcs?.TrySetResult(false);
+ _tcs = null;
+ Closed?.Invoke(this, EventArgs.Empty);
+ }
+
+
+ private void CloseButton_Click(object sender, RoutedEventArgs e)
+ {
+ Visibility = Visibility.Collapsed;
+ _tcs?.TrySetResult(false);
+ _tcs = null;
+ Closed?.Invoke(this, EventArgs.Empty);
+ }
+
+ private void PrimaryButton_Click(object sender, RoutedEventArgs e)
+ {
+ Visibility = Visibility.Collapsed;
+ _tcs?.TrySetResult(true);
+ _tcs = null;
+ PrimaryButtonClicked?.Invoke(this, EventArgs.Empty);
+ }
+
+
+ private static void OnDialogContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ var overlay = (BaseDialogOverlay)d;
+ if (overlay.InnerContentPresenter != null)
+ overlay.InnerContentPresenter.Content = e.NewValue;
+ }
+
+ private static void OnDialogTitleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ var overlay = (BaseDialogOverlay)d;
+ var title = (string?)e.NewValue;
+ overlay.TitleTextBlock.Text = title;
+ overlay.TitleTextBlock.Visibility = string.IsNullOrEmpty(title)
+ ? Visibility.Collapsed
+ : Visibility.Visible;
+ }
+
+ private static void OnCloseButtonTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ ((BaseDialogOverlay)d).CloseActionButton.Content = (string)e.NewValue;
+ }
+
+ private static void OnPrimaryButtonTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
+ {
+ var overlay = (BaseDialogOverlay)d;
+ var text = (string?)e.NewValue;
+ overlay.PrimaryActionButton.Content = text;
+ overlay.PrimaryActionButton.Visibility = string.IsNullOrEmpty(text)
+ ? Visibility.Collapsed
+ : Visibility.Visible;
+ }
+}
diff --git a/src/CamBooth/CamBooth.App/Features/Camera/CameraService.cs b/src/CamBooth/CamBooth.App/Features/Camera/CameraService.cs
index fc83eb5..8b6369a 100644
--- a/src/CamBooth/CamBooth.App/Features/Camera/CameraService.cs
+++ b/src/CamBooth/CamBooth.App/Features/Camera/CameraService.cs
@@ -1,12 +1,10 @@
using System.IO;
using System.Threading.Tasks;
using System.Windows;
-
using CamBooth.App.Core.AppSettings;
using CamBooth.App.Core.Logging;
using CamBooth.App.Features.PhotoPrismUpload;
using CamBooth.App.Features.PictureGallery;
-
using EOSDigital.API;
using EOSDigital.SDK;
@@ -14,284 +12,287 @@ namespace CamBooth.App.Features.Camera;
public class CameraService : IDisposable
{
-private readonly AppSettingsService _appSettings;
-private readonly Logger _logger;
-private readonly PictureGalleryService _pictureGalleryService;
-private readonly PhotoPrismUploadQueueService _photoPrismUploadQueueService;
-private readonly ICanonAPI _canonApi;
+ private readonly AppSettingsService _appSettings;
+ private readonly Logger _logger;
+ private readonly PictureGalleryService _pictureGalleryService;
+ private readonly PhotoPrismUploadQueueService _photoPrismUploadQueueService;
+ private readonly ICanonAPI _canonApi;
-private ICamera? _mainCamera;
-private List? _camList;
-private bool _isConnected;
+ private ICamera? _mainCamera;
+ private List? _camList;
+ private bool _isConnected;
-/// Fires whenever the camera delivers a new live-view frame.
-public event Action? LiveViewUpdated;
+ /// Fires whenever the camera delivers a new live-view frame.
+ public event Action? LiveViewUpdated;
-public bool IsConnected => _isConnected && _mainCamera?.SessionOpen == true;
+ public bool IsConnected => _isConnected && _mainCamera?.SessionOpen == true;
-public CameraService(
-Logger logger,
-AppSettingsService appSettings,
-PictureGalleryService pictureGalleryService,
-PhotoPrismUploadQueueService photoPrismUploadQueueService,
-ICanonAPI canonApi)
-{
-_logger = logger;
-_appSettings = appSettings;
-_pictureGalleryService = pictureGalleryService;
-_photoPrismUploadQueueService = photoPrismUploadQueueService;
-_canonApi = canonApi;
-}
+ public CameraService(
+ Logger logger,
+ AppSettingsService appSettings,
+ PictureGalleryService pictureGalleryService,
+ PhotoPrismUploadQueueService photoPrismUploadQueueService,
+ ICanonAPI canonApi)
+ {
+ _logger = logger;
+ _appSettings = appSettings;
+ _pictureGalleryService = pictureGalleryService;
+ _photoPrismUploadQueueService = photoPrismUploadQueueService;
+ _canonApi = canonApi;
+ }
-public void Dispose()
-{
-CloseSession();
-_canonApi.Dispose();
-_mainCamera?.Dispose();
-}
+ public void Dispose()
+ {
+ CloseSession();
+ _canonApi.Dispose();
+ _mainCamera?.Dispose();
+ }
-public void ConnectCamera()
-{
-ErrorHandler.SevereErrorHappened += ErrorHandler_SevereErrorHappened;
-ErrorHandler.NonSevereErrorHappened += ErrorHandler_NonSevereErrorHappened;
+ public void ConnectCamera()
+ {
+ ErrorHandler.SevereErrorHappened += ErrorHandler_SevereErrorHappened;
+ ErrorHandler.NonSevereErrorHappened += ErrorHandler_NonSevereErrorHappened;
-try
-{
-RefreshCameraList();
+ try
+ {
+ RefreshCameraList();
-const int maxRetries = 3;
-const int retryDelayMs = 750;
+ const int maxRetries = 3;
+ const int retryDelayMs = 750;
-for (int attempt = 0; attempt < maxRetries; attempt++)
-{
-if (_camList?.Any() == true) break;
+ for (int attempt = 0; attempt < maxRetries; attempt++)
+ {
+ if (_camList?.Any() == true) break;
-if (attempt < maxRetries - 1)
-{
-System.Threading.Thread.Sleep(retryDelayMs);
-RefreshCameraList();
-}
-}
+ if (attempt < maxRetries - 1)
+ {
+ System.Threading.Thread.Sleep(retryDelayMs);
+ RefreshCameraList();
+ }
+ }
-if (_camList?.Any() != true)
-throw new InvalidOperationException("No cameras found after multiple attempts.");
+ if (_camList?.Any() != true)
+ throw new InvalidOperationException("No cameras found after multiple attempts.");
-_mainCamera = _camList[0];
-_logger.Info($"Camera found: {_mainCamera.DeviceName}");
+ _mainCamera = _camList[0];
+ _logger.Info($"Camera found: {_mainCamera.DeviceName}");
-OpenSession();
-SetSaveToComputer();
-StartLiveView();
-_isConnected = true;
-}
-catch (Exception ex)
-{
-_logger.Error($"Error connecting camera: {ex.Message}");
-throw;
-}
-}
+ OpenSession();
+ SetSaveToComputer();
+ StartLiveView();
+ _isConnected = true;
+ }
+ catch (Exception ex)
+ {
+ _logger.Error($"Error connecting camera: {ex.Message}");
+ throw;
+ }
+ }
-public void CloseSession()
-{
-try
-{
-if (_mainCamera?.SessionOpen == true)
-{
-_mainCamera.CloseSession();
-_logger.Info("Camera session closed");
-}
-}
-catch (Exception ex)
-{
-_logger.Error($"Error closing camera session: {ex.Message}");
-}
+ public void CloseSession()
+ {
+ try
+ {
+ if (_mainCamera?.SessionOpen == true)
+ {
+ _mainCamera.CloseSession();
+ _logger.Info("Camera session closed");
+ }
+ }
+ catch (Exception ex)
+ {
+ _logger.Error($"Error closing camera session: {ex.Message}");
+ }
-_isConnected = false;
-}
+ _isConnected = false;
+ }
-public void TakePhoto()
-{
-if (_mainCamera == null) throw new InvalidOperationException("Camera not connected.");
-_mainCamera.TakePhoto();
-}
+ public void TakePhoto()
+ {
+ if (_mainCamera == null) throw new InvalidOperationException("Camera not connected.");
+ _mainCamera.TakePhoto();
+ }
-public async Task PrepareFocusAsync(int focusTimeoutMs = 1500)
-{
-if (_mainCamera is not EOSDigital.API.Camera sdkCamera)
-{
-await Task.Delay(200);
-return;
-}
+ public async Task PrepareFocusAsync(int focusTimeoutMs = 1500)
+ {
+ if (_mainCamera is not EOSDigital.API.Camera sdkCamera)
+ {
+ await Task.Delay(200);
+ return;
+ }
-var focusCompleted = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
+ var focusCompleted = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
-void FocusStateChanged(EOSDigital.API.Camera sender, StateEventID eventId, int parameter)
-{
-if (eventId == StateEventID.AfResult)
-focusCompleted.TrySetResult(true);
-}
+ void FocusStateChanged(EOSDigital.API.Camera sender, StateEventID eventId, int parameter)
+ {
+ if (eventId == StateEventID.AfResult)
+ focusCompleted.TrySetResult(true);
+ }
-sdkCamera.StateChanged += FocusStateChanged;
+ sdkCamera.StateChanged += FocusStateChanged;
-try
-{
-await Task.Run(() => sdkCamera.SendCommand(CameraCommand.PressShutterButton, (int)ShutterButton.Halfway));
-var completed = await Task.WhenAny(focusCompleted.Task, Task.Delay(focusTimeoutMs));
-if (completed != focusCompleted.Task)
-_logger.Info("Autofocus timeout reached, continuing.");
-}
-catch (Exception ex)
-{
-_logger.Error(ex.Message);
-}
-finally
-{
-try
-{
-await Task.Run(() => sdkCamera.SendCommand(CameraCommand.PressShutterButton, (int)ShutterButton.OFF));
-}
-catch (Exception ex) { _logger.Error(ex.Message); }
+ try
+ {
+ await Task.Run(() => sdkCamera.SendCommand(CameraCommand.PressShutterButton, (int)ShutterButton.Halfway));
+ var completed = await Task.WhenAny(focusCompleted.Task, Task.Delay(focusTimeoutMs));
+ if (completed != focusCompleted.Task)
+ _logger.Info("Autofocus timeout reached, continuing.");
+ }
+ catch (Exception ex)
+ {
+ _logger.Error(ex.Message);
+ }
+ finally
+ {
+ try
+ {
+ await Task.Run(() => sdkCamera.SendCommand(CameraCommand.PressShutterButton, (int)ShutterButton.OFF));
+ }
+ catch (Exception ex)
+ {
+ _logger.Error(ex.Message);
+ }
-sdkCamera.StateChanged -= FocusStateChanged;
-}
-}
+ sdkCamera.StateChanged -= FocusStateChanged;
+ }
+ }
-private void RefreshCameraList() => _camList = _canonApi.GetCameraList();
+ private void RefreshCameraList() => _camList = _canonApi.GetCameraList();
-private void OpenSession()
-{
-if (_mainCamera == null)
-throw new InvalidOperationException("Camera reference is null.");
+ private void OpenSession()
+ {
+ if (_mainCamera == null)
+ throw new InvalidOperationException("Camera reference is null.");
-if (_mainCamera.SessionOpen)
-{
-_logger.Info($"Session already open for {_mainCamera.DeviceName}");
-return;
-}
+ if (_mainCamera.SessionOpen)
+ {
+ _logger.Info($"Session already open for {_mainCamera.DeviceName}");
+ return;
+ }
-_logger.Info($"Opening session for: {_mainCamera.DeviceName}");
+ _logger.Info($"Opening session for: {_mainCamera.DeviceName}");
-const int maxRetries = 3;
-const int retryDelayMs = 1000;
+ const int maxRetries = 3;
+ const int retryDelayMs = 1000;
-for (int attempt = 0; attempt < maxRetries; attempt++)
-{
-try
-{
-_mainCamera.OpenSession();
-break;
-}
-catch (Exception ex) when (attempt < maxRetries - 1 && IsSessionNotOpenError(ex))
-{
-_logger.Warning($"OpenSession attempt {attempt + 1}/{maxRetries} failed, retrying...");
-System.Threading.Thread.Sleep(retryDelayMs);
-RefreshCameraList();
-if (_camList?.Any() == true)
-_mainCamera = _camList[0];
-}
-catch (Exception ex)
-{
-_logger.Error($"Failed to open session: {ex.Message}");
-throw;
-}
-}
+ for (int attempt = 0; attempt < maxRetries; attempt++)
+ {
+ try
+ {
+ _mainCamera.OpenSession();
+ break;
+ }
+ catch (Exception ex) when (attempt < maxRetries - 1 && IsSessionNotOpenError(ex))
+ {
+ _logger.Warning($"OpenSession attempt {attempt + 1}/{maxRetries} failed, retrying...");
+ System.Threading.Thread.Sleep(retryDelayMs);
+ RefreshCameraList();
+ if (_camList?.Any() == true)
+ _mainCamera = _camList[0];
+ }
+ catch (Exception ex)
+ {
+ _logger.Error($"Failed to open session: {ex.Message}");
+ throw;
+ }
+ }
-_logger.Info("Session opened successfully");
-_mainCamera.StateChanged += MainCamera_StateChanged;
-_mainCamera.DownloadReady += MainCamera_DownloadReady;
-_mainCamera.LiveViewUpdated += MainCamera_LiveViewUpdated;
-}
+ _logger.Info("Session opened successfully");
+ _mainCamera.StateChanged += MainCamera_StateChanged;
+ _mainCamera.DownloadReady += MainCamera_DownloadReady;
+ _mainCamera.LiveViewUpdated += MainCamera_LiveViewUpdated;
+ }
-private void SetSaveToComputer()
-{
-_mainCamera!.SetSetting(PropertyID.SaveTo, (int)SaveTo.Host);
-_mainCamera.SetCapacity(4096, int.MaxValue);
-}
+ private void SetSaveToComputer()
+ {
+ _mainCamera!.SetSetting(PropertyID.SaveTo, (int)SaveTo.Host);
+ _mainCamera.SetCapacity(4096, int.MaxValue);
+ }
-private void StartLiveView()
-{
-try
-{
-if (!_mainCamera!.IsLiveViewOn)
-_mainCamera.StartLiveView();
-else
-_mainCamera.StopLiveView();
-}
-catch (Exception ex)
-{
-_logger.Error(ex.Message);
-}
-}
+ private void StartLiveView()
+ {
+ try
+ {
+ if (!_mainCamera!.IsLiveViewOn)
+ _mainCamera.StartLiveView();
+ else
+ _mainCamera.StopLiveView();
+ }
+ catch (Exception ex)
+ {
+ _logger.Error(ex.Message);
+ }
+ }
-private static bool IsSessionNotOpenError(Exception ex)
-{
-const string errorName = "SESSION_NOT_OPEN";
-return ex.Message.Contains(errorName) || (ex.InnerException?.Message?.Contains(errorName) ?? false);
-}
+ private static bool IsSessionNotOpenError(Exception ex)
+ {
+ const string errorName = "SESSION_NOT_OPEN";
+ return ex.Message.Contains(errorName) || (ex.InnerException?.Message?.Contains(errorName) ?? false);
+ }
-#region Camera event handlers
+ #region Camera event handlers
-private void MainCamera_LiveViewUpdated(ICamera sender, Stream img) =>
-LiveViewUpdated?.Invoke(img);
+ private void MainCamera_LiveViewUpdated(ICamera sender, Stream img) =>
+ LiveViewUpdated?.Invoke(img);
-private void MainCamera_StateChanged(EOSDigital.API.Camera sender, StateEventID eventID, int parameter)
-{
-try
-{
-if (eventID == StateEventID.Shutdown && _isConnected)
-Application.Current.Dispatcher.Invoke(CloseSession);
-}
-catch (Exception ex)
-{
-_logger.Error(ex.Message);
-}
-}
+ private void MainCamera_StateChanged(EOSDigital.API.Camera sender, StateEventID eventID, int parameter)
+ {
+ try
+ {
+ if (eventID == StateEventID.Shutdown && _isConnected)
+ Application.Current.Dispatcher.Invoke(CloseSession);
+ }
+ catch (Exception ex)
+ {
+ _logger.Error(ex.Message);
+ }
+ }
-private void MainCamera_DownloadReady(ICamera sender, IDownloadInfo info)
-{
-_logger.Info("Download ready");
-try
-{
-info.FileName = $"img_{Guid.NewGuid()}.jpg";
-sender.DownloadFile(info, _appSettings.PictureLocation);
-var savedPath = Path.Combine(_appSettings.PictureLocation!, info.FileName);
-_logger.Info($"Download complete: {savedPath}");
+ private void MainCamera_DownloadReady(ICamera sender, IDownloadInfo info)
+ {
+ _logger.Info("Download ready");
+ try
+ {
+ info.FileName = $"img_{Guid.NewGuid()}.jpg";
+ sender.DownloadFile(info, _appSettings.PictureLocation);
+ var savedPath = Path.Combine(_appSettings.PictureLocation!, info.FileName);
+ _logger.Info($"Download complete: {savedPath}");
-Application.Current.Dispatcher.Invoke(() =>
-{
-_pictureGalleryService.IncrementNewPhotoCount();
-_pictureGalleryService.LoadThumbnailsToCache();
-});
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ _pictureGalleryService.IncrementNewPhotoCount();
+ _pictureGalleryService.LoadThumbnailsToCache();
+ });
-_photoPrismUploadQueueService.QueueNewPhoto(savedPath);
-}
-catch (Exception ex)
-{
-_logger.Error(ex.Message);
-}
-}
+ _photoPrismUploadQueueService.QueueNewPhoto(savedPath);
+ }
+ catch (Exception ex)
+ {
+ _logger.Error(ex.Message);
+ }
+ }
-private void ErrorHandler_NonSevereErrorHappened(object sender, ErrorCode ex) =>
-_logger.Error($"SDK Error: {ex} (0x{(int)ex:X})");
+ private void ErrorHandler_NonSevereErrorHappened(object sender, ErrorCode ex) =>
+ _logger.Error($"SDK Error: {ex} (0x{(int)ex:X})");
-private void ErrorHandler_SevereErrorHappened(object sender, Exception ex) =>
-_logger.Error(ex.Message);
+ private void ErrorHandler_SevereErrorHappened(object sender, Exception ex) =>
+ _logger.Error(ex.Message);
-#endregion
-}
+ #endregion
+}
\ No newline at end of file
diff --git a/src/CamBooth/CamBooth.App/Features/PhotoPrismUpload/PhotoPrismQRCodeDisplayWindow.xaml b/src/CamBooth/CamBooth.App/Features/PhotoPrismUpload/PhotoPrismQRCodeDisplayWindow.xaml
deleted file mode 100644
index e3938d6..0000000
--- a/src/CamBooth/CamBooth.App/Features/PhotoPrismUpload/PhotoPrismQRCodeDisplayWindow.xaml
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/CamBooth/CamBooth.App/Features/PhotoPrismUpload/PhotoPrismQRCodeDisplayWindow.xaml.cs b/src/CamBooth/CamBooth.App/Features/PhotoPrismUpload/PhotoPrismQRCodeDisplayWindow.xaml.cs
deleted file mode 100644
index ae901b2..0000000
--- a/src/CamBooth/CamBooth.App/Features/PhotoPrismUpload/PhotoPrismQRCodeDisplayWindow.xaml.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System.Windows;
-using System.Windows.Media.Imaging;
-
-namespace CamBooth.App.Features.PhotoPrismUpload;
-
-public partial class PhotoPrismQRCodeDisplayWindow : Window
-{
- public PhotoPrismQRCodeDisplayWindow()
- {
- InitializeComponent();
- }
-
- ///
- /// Setzt den QR-Code für die Anzeige
- ///
- public void SetQRCode(BitmapImage qrCodeImage)
- {
- if (qrCodeImage != null)
- {
- QRCodeImage.Source = qrCodeImage;
- }
- }
-
- private void CloseButton_Click(object sender, RoutedEventArgs e)
- {
- this.Close();
- }
-}
diff --git a/src/CamBooth/CamBooth.App/Features/PictureGallery/PictureGalleryPage.xaml b/src/CamBooth/CamBooth.App/Features/PictureGallery/PictureGalleryPage.xaml
index 1817be5..1d12401 100644
--- a/src/CamBooth/CamBooth.App/Features/PictureGallery/PictureGalleryPage.xaml
+++ b/src/CamBooth/CamBooth.App/Features/PictureGallery/PictureGalleryPage.xaml
@@ -3,7 +3,7 @@
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:ui="http://schemas.lepo.co/wpfui/2022/xaml"
+ xmlns:core="clr-namespace:CamBooth.App.Core"
mc:Ignorable="d"
Title="PictureGalleryPage" Width="1600" Height="900"
Background="Black">
@@ -85,5 +85,10 @@
+
+
+
\ No newline at end of file
diff --git a/src/CamBooth/CamBooth.App/Features/PictureGallery/PictureGalleryPage.xaml.cs b/src/CamBooth/CamBooth.App/Features/PictureGallery/PictureGalleryPage.xaml.cs
index fb10a6f..9df0c98 100644
--- a/src/CamBooth/CamBooth.App/Features/PictureGallery/PictureGalleryPage.xaml.cs
+++ b/src/CamBooth/CamBooth.App/Features/PictureGallery/PictureGalleryPage.xaml.cs
@@ -2,19 +2,12 @@
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
-using System.Windows.Media.Effects;
using System.Windows.Media.Imaging;
using CamBooth.App.Core.AppSettings;
using CamBooth.App.Core.Logging;
using CamBooth.App.Features.PhotoPrismUpload;
-using Wpf.Ui.Controls;
-
-using Image = Wpf.Ui.Controls.Image;
-using MessageBox = System.Windows.MessageBox;
-using TextBlock = Wpf.Ui.Controls.TextBlock;
-
namespace CamBooth.App.Features.PictureGallery;
public partial class PictureGalleryPage : Page
@@ -27,8 +20,6 @@ public partial class PictureGalleryPage : Page
private readonly PhotoPrismUploadService _photoPrismUploadService;
- private ContentDialog? _openContentDialog;
-
private int _currentPage = 1;
private int _itemsPerPage = 11;
private int _totalPages = 1;
@@ -117,15 +108,6 @@ public partial class PictureGalleryPage : Page
}
- private void ContentDialog_OnButtonClicked(ContentDialog sender, ContentDialogButtonClickEventArgs args)
- {
- if (args.Button == ContentDialogButton.Primary)
- {
- MessageBox.Show($"Print the shit baby {sender.Tag}");
- }
- }
-
-
private void LoadPictures(int startIndex, int count)
{
this.Dispatcher.Invoke(
@@ -170,82 +152,25 @@ public partial class PictureGalleryPage : Page
public void CloseOpenDialog()
{
- void CloseDialog()
- {
- if (this._openContentDialog is null)
- {
- return;
- }
-
- this._openContentDialog.ButtonClicked -= this.ContentDialog_OnButtonClicked;
- this._openContentDialog.GetType().GetMethod("Hide", Type.EmptyTypes)?.Invoke(this._openContentDialog, null);
- this.RootContentDialogPresenter.Content = null;
- this._openContentDialog = null;
- }
-
- if (this.Dispatcher.CheckAccess())
- {
- CloseDialog();
- return;
- }
-
- this.Dispatcher.Invoke(CloseDialog);
+ if (Dispatcher.CheckAccess())
+ PhotoDialogOverlay.Hide();
+ else
+ Dispatcher.Invoke(() => PhotoDialogOverlay.Hide());
}
public async Task ShowPhotoDialogAsync(string picturePath)
{
- await Application.Current.Dispatcher.InvokeAsync(
- async () =>
- {
- this.CloseOpenDialog();
- ContentDialog contentDialog = new(this.RootContentDialogPresenter);
- this._openContentDialog = contentDialog;
- Image imageToShow = new()
- {
- MaxHeight = 570,
- Background = new SolidColorBrush(Colors.White),
- VerticalAlignment = VerticalAlignment.Center,
- Source = PictureGalleryService.CreateThumbnail(picturePath, 450, 300)
- };
+ var imageToShow = new System.Windows.Controls.Image
+ {
+ MaxHeight = 570,
+ MaxWidth = 800,
+ Stretch = System.Windows.Media.Stretch.Uniform,
+ HorizontalAlignment = HorizontalAlignment.Center,
+ Source = PictureGalleryService.CreateThumbnail(picturePath, 900, 600)
+ };
- contentDialog.VerticalAlignment = VerticalAlignment.Top;
- contentDialog.PrimaryButtonAppearance = ControlAppearance.Primary;
- contentDialog.CloseButtonAppearance = ControlAppearance.Light;
- contentDialog.Background = new SolidColorBrush(Colors.White);
- contentDialog.Foreground = new SolidColorBrush(Colors.White);
- contentDialog.SetCurrentValue(ContentControl.ContentProperty, imageToShow);
- contentDialog.SetCurrentValue(ContentDialog.CloseButtonTextProperty, "Schließen");
- contentDialog.SetCurrentValue(ContentDialog.PrimaryButtonTextProperty, "Drucken");
-
- // Apply gold color to Primary button (Drucken)
- contentDialog.Loaded += (s, args) =>
- {
- // Find the Primary button and apply gold styling
- if (contentDialog.Template?.FindName("PrimaryButton", contentDialog) is System.Windows.Controls.Button primaryButton)
- {
- primaryButton.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#D4AF37"));
- primaryButton.Foreground = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#1F1A00"));
- primaryButton.BorderBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#F6E7A1"));
- primaryButton.BorderThickness = new Thickness(2);
- }
- };
-
- contentDialog.Tag = picturePath;
- contentDialog.ButtonClicked += this.ContentDialog_OnButtonClicked;
-
- try
- {
- await contentDialog.ShowAsync();
- }
- finally
- {
- contentDialog.ButtonClicked -= this.ContentDialog_OnButtonClicked;
- if (ReferenceEquals(this._openContentDialog, contentDialog))
- {
- this._openContentDialog = null;
- }
- }
- });
+ PhotoDialogOverlay.DialogContent = imageToShow;
+ await PhotoDialogOverlay.ShowAsync();
}
private void Hyperlink_OnClick(object sender, RoutedEventArgs e)
diff --git a/src/CamBooth/CamBooth.App/MainWindow.xaml b/src/CamBooth/CamBooth.App/MainWindow.xaml
index 319e379..0b79fbb 100644
--- a/src/CamBooth/CamBooth.App/MainWindow.xaml
+++ b/src/CamBooth/CamBooth.App/MainWindow.xaml
@@ -6,6 +6,7 @@
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:local="clr-namespace:CamBooth.App"
xmlns:liveView="clr-namespace:CamBooth.App.Features.LiveView"
+ xmlns:core="clr-namespace:CamBooth.App.Core"
mc:Ignorable="d"
Title="MainWindow"
Background="Black"
@@ -339,50 +340,50 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
diff --git a/src/CamBooth/CamBooth.App/MainWindow.xaml.cs b/src/CamBooth/CamBooth.App/MainWindow.xaml.cs
index b8eb928..989213a 100644
--- a/src/CamBooth/CamBooth.App/MainWindow.xaml.cs
+++ b/src/CamBooth/CamBooth.App/MainWindow.xaml.cs
@@ -1,6 +1,7 @@
using System.ComponentModel;
using System.Diagnostics;
using System.Windows;
+using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
@@ -11,7 +12,6 @@ using CamBooth.App.Features.DebugConsole;
using CamBooth.App.Features.LiveView;
using CamBooth.App.Features.PhotoPrismUpload;
using CamBooth.App.Features.PictureGallery;
-using Wpf.Ui.Controls;
namespace CamBooth.App;
@@ -134,7 +134,7 @@ public partial class MainWindow : Window
WelcomeOverlay.Visibility = Visibility.Collapsed;
ButtonPanel.Visibility = Visibility.Visible;
ActionButtonsContainer.Visibility = Visibility.Visible;
- ShutdownDock.Visibility = Visibility.Visible;
+ //ShutdownDock.Visibility = Visibility.Visible;
}
private void StartTakePhotoProcess(object sender, RoutedEventArgs e)
@@ -163,64 +163,52 @@ public partial class MainWindow : Window
SetVisibilityDebugConsole(_isDebugConsoleVisible);
}
- private void ToggleShutdownSlider(object sender, RoutedEventArgs e)
- {
- _isShutdownSliderOpen = !_isShutdownSliderOpen;
- ShutdownToggleButton.Content = _isShutdownSliderOpen ? ShutdownGlyphOpen : ShutdownGlyphClosed;
- var animation = new DoubleAnimation
- {
- To = _isShutdownSliderOpen ? 0 : ShutdownSliderOffset,
- Duration = TimeSpan.FromMilliseconds(250),
- EasingFunction = new QuadraticEase()
- };
- ShutdownSliderTransform.BeginAnimation(TranslateTransform.XProperty, animation);
- }
+ // private void ToggleShutdownSlider(object sender, RoutedEventArgs e)
+ // {
+ // _isShutdownSliderOpen = !_isShutdownSliderOpen;
+ // ShutdownToggleButton.Content = _isShutdownSliderOpen ? ShutdownGlyphOpen : ShutdownGlyphClosed;
+ // var animation = new DoubleAnimation
+ // {
+ // To = _isShutdownSliderOpen ? 0 : ShutdownSliderOffset,
+ // Duration = TimeSpan.FromMilliseconds(250),
+ // EasingFunction = new QuadraticEase()
+ // };
+ // ShutdownSliderTransform.BeginAnimation(TranslateTransform.XProperty, animation);
+ // }
- private async void ShutdownWindows(object sender, RoutedEventArgs e)
- {
- var confirmDialog = new ContentDialog(DialogPresenter)
- {
- Title = "Sicherheitsabfrage",
- Content = "Möchtest du die Fotobox wirklich ausschalten?",
- PrimaryButtonText = "Ja, ausschalten",
- CloseButtonText = "Abbrechen",
- DefaultButton = ContentDialogButton.Close,
- PrimaryButtonAppearance = ControlAppearance.Danger,
- CloseButtonAppearance = ControlAppearance.Secondary,
- Background = new SolidColorBrush(Colors.White),
- Foreground = new SolidColorBrush(Colors.Black)
- };
-
- if (await confirmDialog.ShowAsync() != ContentDialogResult.Primary) return;
-
- try
- {
- _cameraService.CloseSession();
- }
- catch
- {
- }
-
- var (args, errorMsg) = _appSettings.IsShutdownEnabled
- ? ("/s /t 0", "Windows konnte nicht heruntergefahren werden.")
- : ("/l", "Abmeldung fehlgeschlagen.");
-
- try
- {
- Process.Start(new ProcessStartInfo
- {
- FileName = "shutdown",
- Arguments = args,
- CreateNoWindow = true,
- UseShellExecute = false
- });
- }
- catch (Exception ex)
- {
- _logger.Error(ex.Message);
- System.Windows.MessageBox.Show(errorMsg);
- }
- }
+ // private async void ShutdownWindows(object sender, RoutedEventArgs e)
+ // {
+ // bool confirmed = await ShutdownConfirmOverlay.ShowAsync();
+ // if (!confirmed) return;
+ //
+ // try
+ // {
+ // _cameraService.CloseSession();
+ // }
+ // catch
+ // {
+ // }
+ //
+ // var (args, errorMsg) = _appSettings.IsShutdownEnabled
+ // ? ("/s /t 0", "Windows konnte nicht heruntergefahren werden.")
+ // : ("/l", "Abmeldung fehlgeschlagen.");
+ //
+ // try
+ // {
+ // Process.Start(new ProcessStartInfo
+ // {
+ // FileName = "shutdown",
+ // Arguments = args,
+ // CreateNoWindow = true,
+ // UseShellExecute = false
+ // });
+ // }
+ // catch (Exception ex)
+ // {
+ // _logger.Error(ex.Message);
+ // System.Windows.MessageBox.Show(errorMsg);
+ // }
+ // }
private void ShowQRCode(object sender, MouseButtonEventArgs e)
{
@@ -235,9 +223,24 @@ public partial class MainWindow : Window
return;
}
- var qrWindow = new PhotoPrismQRCodeDisplayWindow();
- qrWindow.SetQRCode(qrCodeImage);
- qrWindow.ShowDialog();
+ var content = new StackPanel { HorizontalAlignment = HorizontalAlignment.Center };
+ content.Children.Add(new System.Windows.Controls.Image
+ {
+ Source = qrCodeImage,
+ Width = 400,
+ Height = 400,
+ Margin = new Thickness(0, 0, 0, 20)
+ });
+ content.Children.Add(new System.Windows.Controls.TextBlock
+ {
+ Text = "Mit einem QR-Code-Scanner scannen",
+ Foreground = Brushes.White,
+ FontSize = 16,
+ TextAlignment = TextAlignment.Center
+ });
+
+ QRCodeOverlay.DialogContent = content;
+ QRCodeOverlay.Show();
}
catch (Exception ex)
{
@@ -299,14 +302,14 @@ public partial class MainWindow : Window
_pictureGalleryService.ResetNewPhotoCount();
ButtonPanel.Visibility = Visibility.Hidden;
ActionButtonsContainer.Visibility = Visibility.Hidden;
- ShutdownDock.Visibility = Visibility.Hidden;
+ //ShutdownDock.Visibility = Visibility.Hidden;
}
else
{
PicturePanel.ClearValue(ContentProperty);
ButtonPanel.Visibility = Visibility.Visible;
ActionButtonsContainer.Visibility = Visibility.Visible;
- ShutdownDock.Visibility = Visibility.Visible;
+ //ShutdownDock.Visibility = Visibility.Visible;
}
_isPicturePanelVisible = visible;