using Avalonia.Controls; using Avalonia.Interactivity; using Avalonia.Input; using Avalonia.Threading; using LehrerApp.Core.Models; using LehrerApp.Core.Interfaces; using LehrerApp.Desktop.ViewModels; using LehrerApp.Desktop.ViewModels.Groups; using Microsoft.Extensions.DependencyInjection; namespace LehrerApp.Desktop.Views.Groups; public partial class TeachingModeWindow : Window { private static readonly Dictionary OpenWindows = []; private readonly DispatcherTimer _clock = new() { Interval = TimeSpan.FromSeconds(1) }; private WindowState _previousState = WindowState.Maximized; public static void Open(Lesson lesson) { if (OpenWindows.TryGetValue(lesson.Id, out var existing)) { if (existing.WindowState == WindowState.Minimized) existing.WindowState = WindowState.Normal; existing.Activate(); return; } var group = App.Services.GetRequiredService().GetById(lesson.GroupId); if (group is null) return; var window = new TeachingModeWindow { DataContext = new TeachingModeViewModel(lesson, group, App.Services.GetRequiredService(), App.Services.GetRequiredService(), App.Services.GetRequiredService(), App.Services.GetRequiredService()) }; OpenWindows.Add(lesson.Id, window); window.Closed += (_, _) => OpenWindows.Remove(lesson.Id); window.Show(); } public TeachingModeWindow() { InitializeComponent(); _clock.Tick += (_, _) => (DataContext as TeachingModeViewModel)?.Timeline.Refresh(); Opened += (_, _) => _clock.Start(); Closed += (_, _) => _clock.Stop(); KeyDown += (_, e) => { if (e.Key == Key.F11) { ToggleFullScreen(); e.Handled = true; } else if (e.Key == Key.Escape && WindowState == WindowState.FullScreen) { WindowState = _previousState; e.Handled = true; } }; } private void ToggleFullScreen() { if (WindowState == WindowState.FullScreen) WindowState = _previousState; else { _previousState = WindowState; WindowState = WindowState.FullScreen; } } private void OnFullScreen(object? sender, RoutedEventArgs e) => ToggleFullScreen(); protected override void OnDataContextChanged(EventArgs e) { base.OnDataContextChanged(e); // Gleiches Muster wie LessonViewerDialog (4.5.3): Fenster schließt zuerst, dann Sprung // über die MainWindowViewModel-Singleton-Navigation in den Ziel-Tab der Gruppe. if (DataContext is TeachingModeViewModel vm) { vm.LessonInfo.OnNavigateToTab = tabIndex => { Close(); App.Services.GetRequiredService() .NavigateToGroupDetail(vm.LessonInfo.GroupId, tabIndex); }; // Nutzer-Feedback: Schnellbewertung (Mitarbeit) und Schnellanwesenheit/Hausaufgabe // direkt aus dem Unterrichtsmodus statt erst zum Mitarbeit-Tab wechseln zu müssen — // dieselben Dialoge wie in ParticipationTabView.axaml.cs, hier auf die zu dieser // Stunde gehörende Sitzung vorselektiert (siehe TeachingModeViewModel-Konstruktor). vm.Participation.OnQuickInput = ShowQuickInputDialog; vm.Participation.OnStatusQuickInput = ShowStatusQuickInputDialog; } } private async Task ShowQuickInputDialog(ParticipationTabViewModel tabVm) { if (tabVm.StudentRows.Count == 0) return; tabVm.RefreshCurrentGrid(); var quickVm = new QuickInputViewModel(tabVm.StudentRows.ToList(), tabVm.Aspects.ToList()); var dialog = new ParticipationQuickInputDialog { DataContext = quickVm }; await dialog.ShowDialog(this); (DataContext as TeachingModeViewModel)?.SeatingPlan.ReloadSeatBadgesFromRepository(); } private async Task ShowStatusQuickInputDialog(ParticipationTabViewModel tabVm) { if (tabVm.StudentRows.Count == 0 || tabVm.SelectedSession is null) return; tabVm.RefreshCurrentGrid(); var quickVm = new AttendanceHomeworkQuickInputViewModel(tabVm.StudentRows, tabVm.SelectedSessionDisplay); var dialog = new AttendanceHomeworkQuickInputDialog { DataContext = quickVm }; await dialog.ShowDialog(this); (DataContext as TeachingModeViewModel)?.SeatingPlan.ReloadSeatBadgesFromRepository(); } private void OnClose(object? sender, RoutedEventArgs e) => Close(); }