Manche Räume sind unregelmäßig bestückt (z.B. eine Klasse mit 3 Reihen, in zwei davon fehlt ein Einzeltisch) - das feste Rows x Columns-Raster kennt aber keine per-Reihe abweichende Spaltenzahl. Neues Feld SeatingPlan.HiddenSeats für Plätze ohne physischen Tisch. Ein ausgeblendeter Platz bleibt Teil des Rasters (für die Spalten-/Reihenausrichtung von SeatingPlanPanel), wird im Ansichtsmodus aber nicht gerendert; im Bearbeitungsmodus bleibt er sichtbar (abgeblendet) mit einem Umschalt-Button direkt auf dem Platz. Nur leere Plätze lassen sich ausblenden; Zuweisen/ Verschieben eines Schülers auf einen ausgeblendeten Platz wird sowohl im ViewModel als auch im Drag&Drop-Ziel-Check verhindert. SeatingPlanRepository.Save filtert HiddenSeats zusätzlich auf das gültige Raster und blendet einen Platz automatisch wieder ein, falls er trotzdem belegt wird. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
220 lines
13 KiB
XML
220 lines
13 KiB
XML
<UserControl xmlns="https://github.com/avaloniaui"
|
||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||
xmlns:vm="clr-namespace:LehrerApp.Desktop.ViewModels.Groups"
|
||
xmlns:groups="clr-namespace:LehrerApp.Desktop.Views.Groups"
|
||
x:Class="LehrerApp.Desktop.Views.Groups.SeatingPlanTabView"
|
||
x:DataType="vm:SeatingPlanTabViewModel">
|
||
<UserControl.Styles>
|
||
<Style Selector="Border.seat">
|
||
<Setter Property="Background" Value="{DynamicResource SystemControlBackgroundAltHighBrush}"/>
|
||
<Setter Property="BorderBrush" Value="{DynamicResource SystemControlForegroundBaseLowBrush}"/>
|
||
<Setter Property="BorderThickness" Value="1"/>
|
||
</Style>
|
||
<Style Selector="Border.seat.occupied">
|
||
<Setter Property="BorderBrush" Value="{DynamicResource SystemAccentColor}"/>
|
||
</Style>
|
||
<Style Selector="Border.seat.droptarget">
|
||
<Setter Property="Background" Value="{DynamicResource SystemAccentColorLight2}"/>
|
||
<Setter Property="BorderBrush" Value="{DynamicResource SystemAccentColor}"/>
|
||
<Setter Property="BorderThickness" Value="2"/>
|
||
</Style>
|
||
<Style Selector="Border.seat.hidden">
|
||
<Setter Property="BorderBrush" Value="{DynamicResource SystemControlForegroundBaseLowBrush}"/>
|
||
<Setter Property="BorderThickness" Value="1"/>
|
||
<Setter Property="Background" Value="Transparent"/>
|
||
</Style>
|
||
</UserControl.Styles>
|
||
<Grid ColumnDefinitions="260,*">
|
||
<Border Grid.Column="0" BorderBrush="{DynamicResource SystemControlForegroundBaseLowBrush}"
|
||
BorderThickness="0,0,1,0" Padding="16">
|
||
<Grid RowDefinitions="Auto,*,Auto">
|
||
<StackPanel Grid.Row="0" Spacing="4" Margin="0,0,0,12">
|
||
<TextBlock Text="Sitzpläne" FontSize="18" FontWeight="SemiBold"/>
|
||
<TextBlock Text="Mehrere Pläne, z. B. für verschiedene Räume" FontSize="12"
|
||
Opacity="0.6" TextWrapping="Wrap"/>
|
||
</StackPanel>
|
||
<ListBox Grid.Row="1" ItemsSource="{Binding Plans}" SelectedItem="{Binding SelectedPlan}">
|
||
<ListBox.ItemTemplate>
|
||
<DataTemplate x:DataType="vm:SeatingPlanSummary">
|
||
<StackPanel Margin="4,6" Spacing="2">
|
||
<TextBlock Text="{Binding Name}" FontWeight="SemiBold"/>
|
||
<TextBlock Text="{Binding RoomDisplay}" FontSize="12" Opacity="0.6"/>
|
||
</StackPanel>
|
||
</DataTemplate>
|
||
</ListBox.ItemTemplate>
|
||
</ListBox>
|
||
<StackPanel Grid.Row="2" Spacing="8" Margin="0,12,0,0" IsVisible="{Binding IsEditMode}">
|
||
<Button Content="+ Sitzplan" Command="{Binding AddPlanCommand}" HorizontalAlignment="Stretch"/>
|
||
<Grid ColumnDefinitions="*,8,*" IsVisible="{Binding HasSelectedPlan}">
|
||
<Button Grid.Column="0" Content="Bearbeiten" Command="{Binding EditPlanCommand}"
|
||
HorizontalAlignment="Stretch"/>
|
||
<Button Grid.Column="2" Content="Löschen" Command="{Binding DeletePlanCommand}"
|
||
HorizontalAlignment="Stretch"/>
|
||
</Grid>
|
||
</StackPanel>
|
||
</Grid>
|
||
</Border>
|
||
|
||
<Grid Grid.Column="1">
|
||
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Spacing="10"
|
||
IsVisible="{Binding HasPlans, Converter={x:Static BoolConverters.Not}}">
|
||
<TextBlock Text="Noch kein Sitzplan" FontSize="20" FontWeight="SemiBold"
|
||
HorizontalAlignment="Center"/>
|
||
<TextBlock Text="Lege einen Plan an und ordne die Schüler den Plätzen zu."
|
||
Opacity="0.6" TextAlignment="Center"/>
|
||
<Button Content="Ersten Sitzplan anlegen" Command="{Binding AddPlanCommand}"
|
||
HorizontalAlignment="Center"/>
|
||
</StackPanel>
|
||
|
||
<Grid RowDefinitions="Auto,*" ColumnDefinitions="*,Auto" IsVisible="{Binding HasSelectedPlan}" Margin="24">
|
||
<Grid Grid.Row="0" Grid.ColumnSpan="2" ColumnDefinitions="*,Auto" Margin="0,0,0,18">
|
||
<StackPanel Spacing="3">
|
||
<TextBlock Text="{Binding PlanTitle}" FontSize="22" FontWeight="SemiBold"/>
|
||
<TextBlock Text="{Binding PlanSubtitle}" Opacity="0.65"/>
|
||
<StackPanel Orientation="Horizontal" Spacing="8" Margin="0,6,0,0"
|
||
IsVisible="{Binding IsEditMode, Converter={x:Static BoolConverters.Not}}">
|
||
<TextBlock Text="Unterricht:" VerticalAlignment="Center" FontSize="12" Opacity="0.65"/>
|
||
<ComboBox ItemsSource="{Binding TodaySessions}" SelectedItem="{Binding SelectedSession}"
|
||
DisplayMemberBinding="{Binding DisplayName}" MinWidth="210"/>
|
||
</StackPanel>
|
||
</StackPanel>
|
||
<StackPanel Grid.Column="1" VerticalAlignment="Bottom" Spacing="4">
|
||
<ToggleSwitch Content="Bearbeitungsmodus" IsChecked="{Binding IsEditMode}"
|
||
IsVisible="{Binding IsEditable}" HorizontalAlignment="Right"/>
|
||
<TextBlock Text="{Binding AssignmentSummary}" HorizontalAlignment="Right" FontSize="12" Opacity="0.6"/>
|
||
<TextBlock Text="Ziehen: Platz ändern · Klicken: bewerten" HorizontalAlignment="Right"
|
||
FontSize="11" Opacity="0.5" IsVisible="{Binding IsEditMode}"/>
|
||
<TextBlock Text="Klicken: bewerten" HorizontalAlignment="Right"
|
||
FontSize="11" Opacity="0.5" IsVisible="{Binding IsEditMode, Converter={x:Static BoolConverters.Not}}"/>
|
||
</StackPanel>
|
||
</Grid>
|
||
|
||
<ScrollViewer x:Name="RoomScrollViewer" Grid.Row="1" Grid.Column="0"
|
||
Margin="0,0,16,0"
|
||
HorizontalScrollBarVisibility="Auto"
|
||
VerticalScrollBarVisibility="Auto"
|
||
DragDrop.AllowDrop="True"
|
||
DragDrop.DragOver="OnRoomDragOver"
|
||
DragDrop.DragLeave="OnRoomDragLeave">
|
||
<StackPanel Spacing="14" HorizontalAlignment="Center">
|
||
<Border Background="{DynamicResource SystemControlBackgroundChromeMediumLowBrush}"
|
||
CornerRadius="6" Padding="36,8" HorizontalAlignment="Center"
|
||
IsVisible="{Binding IsBoardAtTop}">
|
||
<TextBlock Text="Tafel / Vorderseite" FontWeight="SemiBold" Opacity="0.75"/>
|
||
</Border>
|
||
<ItemsControl ItemsSource="{Binding Seats}" HorizontalAlignment="Center">
|
||
<ItemsControl.ItemsPanel>
|
||
<ItemsPanelTemplate>
|
||
<groups:SeatingPlanPanel Columns="{Binding PlanColumns}"
|
||
ColumnGapWidths="{Binding ColumnGapWidths}"/>
|
||
</ItemsPanelTemplate>
|
||
</ItemsControl.ItemsPanel>
|
||
<ItemsControl.ItemTemplate>
|
||
<DataTemplate x:DataType="vm:SeatCellViewModel">
|
||
<Border Classes="seat" Classes.occupied="{Binding IsOccupied}"
|
||
Classes.droptarget="{Binding IsDropTarget}"
|
||
Classes.hidden="{Binding IsHidden}"
|
||
IsVisible="{Binding ShowSeat}"
|
||
Width="190" MinHeight="76" Margin="5" Padding="10"
|
||
CornerRadius="7"
|
||
DragDrop.AllowDrop="True"
|
||
DragDrop.DragEnter="OnSeatDragEnter"
|
||
DragDrop.DragLeave="OnSeatDragLeave"
|
||
DragDrop.DragOver="OnSeatDragOver"
|
||
DragDrop.Drop="OnSeatDrop"
|
||
PointerPressed="OnDragSourcePressed"
|
||
PointerMoved="OnDragSourceMoved"
|
||
PointerReleased="OnDragSourceReleased"
|
||
Tapped="OnSeatTapped" Opacity="{Binding DisplayOpacity}">
|
||
<StackPanel Spacing="5">
|
||
<Grid ColumnDefinitions="*,Auto">
|
||
<TextBlock Text="{Binding PositionLabel}" FontSize="10" Opacity="0.5"/>
|
||
<TextBlock Grid.Column="1" Text="⠿" Opacity="0.45" IsVisible="{Binding CanEdit}"/>
|
||
</Grid>
|
||
<TextBlock Text="{Binding StudentName}" FontWeight="SemiBold" FontSize="13"
|
||
HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||
<Button Content="{Binding HiddenToggleLabel}"
|
||
Command="{Binding ToggleHiddenCommand}" FontSize="9" Padding="6,2"
|
||
HorizontalAlignment="Center" IsVisible="{Binding CanToggleHidden}"/>
|
||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Spacing="5"
|
||
IsVisible="{Binding ShowLessonOverview}">
|
||
<Border Background="#1976D2" CornerRadius="8" Padding="6,1"
|
||
IsVisible="{Binding HasAttendanceBadge}">
|
||
<TextBlock Text="{Binding AttendanceBadge}" Foreground="White" FontSize="10"
|
||
ToolTip.Tip="Anwesenheit"/>
|
||
</Border>
|
||
<Border Background="#FB8C00" CornerRadius="8" Padding="6,1"
|
||
IsVisible="{Binding HasHomeworkBadge}">
|
||
<TextBlock Text="{Binding HomeworkBadge}" Foreground="White" FontSize="10"
|
||
ToolTip.Tip="Hausaufgabe"/>
|
||
</Border>
|
||
</StackPanel>
|
||
<Expander Header="+ Situation" FontSize="10"
|
||
IsVisible="{Binding CanRecordLesson}">
|
||
<ItemsControl ItemsSource="{Binding SituationTags}" Margin="0,4,0,0">
|
||
<ItemsControl.ItemsPanel>
|
||
<ItemsPanelTemplate><WrapPanel ItemSpacing="3" LineSpacing="3"/></ItemsPanelTemplate>
|
||
</ItemsControl.ItemsPanel>
|
||
<ItemsControl.ItemTemplate>
|
||
<DataTemplate DataType="vm:SituationTagChoice">
|
||
<ToggleButton Content="{Binding Text}" IsChecked="{Binding IsSelected, Mode=OneWay}"
|
||
Command="{Binding ToggleCommand}" FontSize="9" Padding="5,2"/>
|
||
</DataTemplate>
|
||
</ItemsControl.ItemTemplate>
|
||
</ItemsControl>
|
||
</Expander>
|
||
</StackPanel>
|
||
</Border>
|
||
</DataTemplate>
|
||
</ItemsControl.ItemTemplate>
|
||
</ItemsControl>
|
||
<Border Background="{DynamicResource SystemControlBackgroundChromeMediumLowBrush}"
|
||
CornerRadius="6" Padding="36,8" HorizontalAlignment="Center"
|
||
IsVisible="{Binding IsBoardAtBottom}">
|
||
<TextBlock Text="Tafel / Vorderseite" FontWeight="SemiBold" Opacity="0.75"/>
|
||
</Border>
|
||
</StackPanel>
|
||
</ScrollViewer>
|
||
|
||
<!-- Die Schülerliste hat einen eigenen Scrollbereich und bleibt dadurch auch bei
|
||
großen Räumen neben den aktuell sichtbaren Sitzplätzen erreichbar. -->
|
||
<Border Grid.Row="1" Grid.Column="1"
|
||
Width="220" IsVisible="{Binding IsEditMode}"
|
||
DragDrop.AllowDrop="True" DragDrop.DragOver="OnUnassignedDragOver"
|
||
DragDrop.Drop="OnUnassignedDrop"
|
||
BorderBrush="{DynamicResource SystemControlForegroundBaseLowBrush}"
|
||
BorderThickness="1" CornerRadius="7" Padding="12">
|
||
<Grid RowDefinitions="Auto,Auto,*">
|
||
<TextBlock Grid.Row="0" Text="NICHT ZUGEORDNET" FontSize="10"
|
||
FontWeight="Bold" Opacity="0.5"/>
|
||
<TextBlock Grid.Row="1" Margin="0,5,0,10"
|
||
Text="Schüler auf einen Platz ziehen. Belegte Plätze hierher ziehen, um sie zu leeren."
|
||
TextWrapping="Wrap" FontSize="11" Opacity="0.5"/>
|
||
<ScrollViewer Grid.Row="2" VerticalScrollBarVisibility="Auto"
|
||
HorizontalScrollBarVisibility="Disabled">
|
||
<StackPanel Spacing="6">
|
||
<ItemsControl ItemsSource="{Binding UnassignedStudents}">
|
||
<ItemsControl.ItemTemplate>
|
||
<DataTemplate x:DataType="vm:StudentSeatOption">
|
||
<Border Background="{DynamicResource SystemAccentColorLight2}" CornerRadius="5"
|
||
Padding="9,7"
|
||
PointerPressed="OnDragSourcePressed"
|
||
PointerMoved="OnDragSourceMoved"
|
||
PointerReleased="OnDragSourceReleased">
|
||
<TextBlock Text="{Binding DisplayName}" FontSize="12" TextTrimming="CharacterEllipsis"/>
|
||
</Border>
|
||
</DataTemplate>
|
||
</ItemsControl.ItemTemplate>
|
||
</ItemsControl>
|
||
<TextBlock Text="Alle Schüler sind zugeordnet." Classes="emptyhint"
|
||
TextWrapping="Wrap"
|
||
IsVisible="{Binding !UnassignedStudents.Count}"/>
|
||
</StackPanel>
|
||
</ScrollViewer>
|
||
</Grid>
|
||
</Border>
|
||
</Grid>
|
||
</Grid>
|
||
</Grid>
|
||
</UserControl>
|