Mitarbeits Wizzard und neue Statuslabels für Anwesenheit und Hausaufgaben
This commit is contained in:
@@ -0,0 +1,225 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Controls.Templates;
|
||||
using Avalonia.Data;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Media;
|
||||
using LehrerApp.Core.Models;
|
||||
using LehrerApp.Desktop.ViewModels.Groups;
|
||||
|
||||
namespace LehrerApp.Desktop.Views.Groups;
|
||||
|
||||
public partial class AttendanceHomeworkQuickInputDialog : Window
|
||||
{
|
||||
public AttendanceHomeworkQuickInputDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
BuildColumns();
|
||||
}
|
||||
|
||||
protected override void OnOpened(EventArgs e)
|
||||
{
|
||||
base.OnOpened(e);
|
||||
StatusGrid.Focus();
|
||||
if (ViewModel?.SelectedRow is { } row)
|
||||
StatusGrid.ScrollIntoView(row, null);
|
||||
}
|
||||
|
||||
private void BuildColumns()
|
||||
{
|
||||
StatusGrid.Columns.Add(new DataGridTextColumn
|
||||
{
|
||||
Header = "Schüler",
|
||||
Binding = new Binding(nameof(ParticipationStudentRow.Name)),
|
||||
Width = new DataGridLength(1, DataGridLengthUnitType.Star),
|
||||
});
|
||||
StatusGrid.Columns.Add(new DataGridTemplateColumn
|
||||
{
|
||||
Header = "Anwesenheit",
|
||||
Width = new DataGridLength(210, DataGridLengthUnitType.Pixel),
|
||||
CellTemplate = BuildAttendanceTemplate(),
|
||||
});
|
||||
StatusGrid.Columns.Add(new DataGridTemplateColumn
|
||||
{
|
||||
Header = "Hausaufgaben",
|
||||
Width = new DataGridLength(270, DataGridLengthUnitType.Pixel),
|
||||
CellTemplate = BuildHomeworkTemplate(),
|
||||
});
|
||||
}
|
||||
|
||||
private IDataTemplate BuildAttendanceTemplate() =>
|
||||
new FuncDataTemplate<ParticipationStudentRow>((row, _) =>
|
||||
{
|
||||
if (row is null) return new TextBlock();
|
||||
var button = StatusButton(185);
|
||||
var flyout = new MenuFlyout { Placement = PlacementMode.BottomEdgeAlignedLeft };
|
||||
AddAttendanceItem(flyout, row, "· Nicht kontrolliert", null);
|
||||
AddAttendanceItem(flyout, row, "✓ Anwesend", AttendanceStatus.Present);
|
||||
AddAttendanceItem(flyout, row, "? Entschuldigung offen", AttendanceStatus.ExcusePending);
|
||||
AddAttendanceItem(flyout, row, "⊘ Krank, entschuldigt", AttendanceStatus.Excused);
|
||||
AddAttendanceItem(flyout, row, "! Unentschuldigt", AttendanceStatus.Unexcused);
|
||||
AddAttendanceItem(flyout, row, "✕ Geschwänzt", AttendanceStatus.Truant);
|
||||
AddAttendanceItem(flyout, row, "◇ Andere Schulveranstaltung", AttendanceStatus.OtherSchoolEvent);
|
||||
button.Flyout = flyout;
|
||||
|
||||
void Refresh()
|
||||
{
|
||||
UpdateButton(button,
|
||||
string.IsNullOrEmpty(row.AttendanceLabel) ? "·" : row.AttendanceLabel,
|
||||
row.AttendanceTooltip, AttendanceDisplay.Color(row.Attendance));
|
||||
}
|
||||
Refresh();
|
||||
row.PropertyChanged += (_, args) =>
|
||||
{
|
||||
if (args.PropertyName == nameof(ParticipationStudentRow.AttendanceLabel)) Refresh();
|
||||
};
|
||||
return Center(button);
|
||||
});
|
||||
|
||||
private IDataTemplate BuildHomeworkTemplate() =>
|
||||
new FuncDataTemplate<ParticipationStudentRow>((row, _) =>
|
||||
{
|
||||
if (row is null) return new TextBlock();
|
||||
var button = StatusButton(245);
|
||||
var flyout = new MenuFlyout { Placement = PlacementMode.BottomEdgeAlignedLeft };
|
||||
AddHomeworkItem(flyout, row, "· Keine Hausaufgabe", null);
|
||||
AddHomeworkItem(flyout, row, "✓ Gemacht", HomeworkStatus.Completed);
|
||||
AddHomeworkItem(flyout, row, "◐ Teilweise, Rest offen", HomeworkStatus.PartiallyCompleted);
|
||||
AddHomeworkItem(flyout, row, "◕ Rest nachgereicht", HomeworkStatus.PartialSubmittedLate);
|
||||
AddHomeworkItem(flyout, row, "◒ Rest nicht nachgereicht", HomeworkStatus.PartialMissingOverdue);
|
||||
AddHomeworkItem(flyout, row, "! Nicht gemacht, Nachreichen offen", HomeworkStatus.MissingOpen);
|
||||
AddHomeworkItem(flyout, row, "✕ Nicht mehr nachgereicht", HomeworkStatus.MissingOverdue);
|
||||
AddHomeworkItem(flyout, row, "↺ Nachgereicht", HomeworkStatus.SubmittedLate);
|
||||
button.Flyout = flyout;
|
||||
|
||||
void Refresh() => UpdateButton(button, row.HomeworkSymbol, row.HomeworkTooltip,
|
||||
HomeworkDisplay.Color(row.Homework));
|
||||
Refresh();
|
||||
row.PropertyChanged += (_, args) =>
|
||||
{
|
||||
if (args.PropertyName == nameof(ParticipationStudentRow.HomeworkSymbol)) Refresh();
|
||||
};
|
||||
return Center(button);
|
||||
});
|
||||
|
||||
private void AddAttendanceItem(MenuFlyout flyout, ParticipationStudentRow row,
|
||||
string header, AttendanceStatus? status)
|
||||
{
|
||||
var item = new MenuItem { Header = header };
|
||||
item.Click += (_, _) => ViewModel?.ApplyAttendance(row, status);
|
||||
flyout.Items.Add(item);
|
||||
}
|
||||
|
||||
private void AddHomeworkItem(MenuFlyout flyout, ParticipationStudentRow row,
|
||||
string header, HomeworkStatus? status)
|
||||
{
|
||||
var item = new MenuItem { Header = header };
|
||||
item.Click += (_, _) => ViewModel?.ApplyHomework(row, status);
|
||||
flyout.Items.Add(item);
|
||||
}
|
||||
|
||||
private static Button StatusButton(double width) => new()
|
||||
{
|
||||
Width = width,
|
||||
Height = 29,
|
||||
Padding = new Thickness(8, 2),
|
||||
FontSize = 12,
|
||||
HorizontalContentAlignment = Avalonia.Layout.HorizontalAlignment.Center,
|
||||
};
|
||||
|
||||
private static Control Center(Control child) => new Grid
|
||||
{
|
||||
Margin = new Thickness(0, 2),
|
||||
HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Center,
|
||||
Children = { child },
|
||||
};
|
||||
|
||||
private static void UpdateButton(Button button, string symbol, string tooltip, string color)
|
||||
{
|
||||
button.Content = $"{symbol} {tooltip}";
|
||||
ToolTip.SetTip(button, tooltip + " – klicken, um Status auszuwählen");
|
||||
if (Color.TryParse(color, out var parsed))
|
||||
{
|
||||
button.Background = new SolidColorBrush(parsed);
|
||||
button.Foreground = Brushes.White;
|
||||
button.Opacity = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
button.ClearValue(Button.BackgroundProperty);
|
||||
button.ClearValue(Button.ForegroundProperty);
|
||||
button.Opacity = 0.48;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnKeyDown(KeyEventArgs e)
|
||||
{
|
||||
var vm = ViewModel;
|
||||
var row = vm?.SelectedRow;
|
||||
if (vm is null || row is null) { base.OnKeyDown(e); return; }
|
||||
|
||||
if (e.KeyModifiers.HasFlag(KeyModifiers.Alt))
|
||||
{
|
||||
var homework = e.Key switch
|
||||
{
|
||||
Key.D0 or Key.NumPad0 => (HomeworkStatus?)null,
|
||||
Key.M => HomeworkStatus.Completed,
|
||||
Key.T => HomeworkStatus.PartiallyCompleted,
|
||||
Key.R => HomeworkStatus.PartialSubmittedLate,
|
||||
Key.X => HomeworkStatus.PartialMissingOverdue,
|
||||
Key.O => HomeworkStatus.MissingOpen,
|
||||
Key.F => HomeworkStatus.MissingOverdue,
|
||||
Key.S => HomeworkStatus.SubmittedLate,
|
||||
_ => null,
|
||||
};
|
||||
var recognized = e.Key is Key.D0 or Key.NumPad0 or Key.M or Key.T or Key.R or Key.X or Key.O or Key.F or Key.S;
|
||||
if (recognized)
|
||||
{
|
||||
vm.ApplyHomework(row, homework);
|
||||
BringSelectionIntoView();
|
||||
e.Handled = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
AttendanceStatus? attendance = e.Key switch
|
||||
{
|
||||
Key.A => AttendanceStatus.Present,
|
||||
Key.K => AttendanceStatus.ExcusePending,
|
||||
Key.E => AttendanceStatus.Excused,
|
||||
Key.U => AttendanceStatus.Unexcused,
|
||||
Key.G => AttendanceStatus.Truant,
|
||||
Key.V => AttendanceStatus.OtherSchoolEvent,
|
||||
_ => null,
|
||||
};
|
||||
var attendanceRecognized = e.Key is Key.D0 or Key.NumPad0 or Key.A or Key.K or Key.E or Key.U or Key.G or Key.V;
|
||||
if (attendanceRecognized)
|
||||
{
|
||||
vm.ApplyAttendance(row, attendance);
|
||||
BringSelectionIntoView();
|
||||
e.Handled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
switch (e.Key)
|
||||
{
|
||||
case Key.Up: vm.MoveSelection(-1); BringSelectionIntoView(); e.Handled = true; break;
|
||||
case Key.Down or Key.Enter: vm.MoveSelection(1); BringSelectionIntoView(); e.Handled = true; break;
|
||||
case Key.Escape: Close(); e.Handled = true; break;
|
||||
default: base.OnKeyDown(e); break;
|
||||
}
|
||||
}
|
||||
|
||||
private AttendanceHomeworkQuickInputViewModel? ViewModel =>
|
||||
DataContext as AttendanceHomeworkQuickInputViewModel;
|
||||
|
||||
private void BringSelectionIntoView()
|
||||
{
|
||||
if (ViewModel?.SelectedRow is { } row)
|
||||
StatusGrid.ScrollIntoView(row, null);
|
||||
}
|
||||
|
||||
private void OnClose(object? sender, RoutedEventArgs e) => Close();
|
||||
}
|
||||
Reference in New Issue
Block a user