Neue Abwensenheitsmodi plus Upgrade Sitzplan
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
|
||||
namespace LehrerApp.Desktop.Views.Groups;
|
||||
|
||||
/// <summary>
|
||||
/// Ordnet Sitzplätze in einem Raster an und fügt zwischen ausgewählten Spalten zusätzliche
|
||||
/// transparente Breite ein. Anders als ein UniformGrid kann der Abstand je Spaltengrenze variieren.
|
||||
/// </summary>
|
||||
public sealed class SeatingPlanPanel : Panel
|
||||
{
|
||||
public static readonly StyledProperty<int> ColumnsProperty =
|
||||
AvaloniaProperty.Register<SeatingPlanPanel, int>(nameof(Columns), 1);
|
||||
|
||||
public static readonly StyledProperty<IReadOnlyList<double>> ColumnGapWidthsProperty =
|
||||
AvaloniaProperty.Register<SeatingPlanPanel, IReadOnlyList<double>>(
|
||||
nameof(ColumnGapWidths), Array.Empty<double>());
|
||||
|
||||
public int Columns
|
||||
{
|
||||
get => GetValue(ColumnsProperty);
|
||||
set => SetValue(ColumnsProperty, value);
|
||||
}
|
||||
|
||||
public IReadOnlyList<double> ColumnGapWidths
|
||||
{
|
||||
get => GetValue(ColumnGapWidthsProperty);
|
||||
set => SetValue(ColumnGapWidthsProperty, value);
|
||||
}
|
||||
|
||||
static SeatingPlanPanel() =>
|
||||
AffectsMeasure<SeatingPlanPanel>(ColumnsProperty, ColumnGapWidthsProperty);
|
||||
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
foreach (var child in Children)
|
||||
child.Measure(Size.Infinity);
|
||||
|
||||
if (Children.Count == 0) return default;
|
||||
var columns = Math.Max(1, Columns);
|
||||
var rows = (int)Math.Ceiling((double)Children.Count / columns);
|
||||
var cellWidth = Children.Max(child => child.DesiredSize.Width);
|
||||
var cellHeight = Children.Max(child => child.DesiredSize.Height);
|
||||
return new Size(cellWidth * columns + GapWidth(columns), cellHeight * rows);
|
||||
}
|
||||
|
||||
protected override Size ArrangeOverride(Size finalSize)
|
||||
{
|
||||
if (Children.Count == 0) return finalSize;
|
||||
var columns = Math.Max(1, Columns);
|
||||
var cellWidth = Children.Max(child => child.DesiredSize.Width);
|
||||
var cellHeight = Children.Max(child => child.DesiredSize.Height);
|
||||
|
||||
for (var index = 0; index < Children.Count; index++)
|
||||
{
|
||||
var column = index % columns;
|
||||
var row = index / columns;
|
||||
var child = Children[index];
|
||||
var x = column * cellWidth + GapWidthBefore(column);
|
||||
var childX = x + Math.Max(0, (cellWidth - child.DesiredSize.Width) / 2);
|
||||
var childY = row * cellHeight + Math.Max(0, (cellHeight - child.DesiredSize.Height) / 2);
|
||||
child.Arrange(new Rect(childX, childY, child.DesiredSize.Width, child.DesiredSize.Height));
|
||||
}
|
||||
|
||||
return finalSize;
|
||||
}
|
||||
|
||||
private double GapWidth(int columns) =>
|
||||
Enumerable.Range(0, Math.Max(0, columns - 1)).Sum(GapAt);
|
||||
|
||||
private double GapWidthBefore(int column) =>
|
||||
Enumerable.Range(0, Math.Max(0, column)).Sum(GapAt);
|
||||
|
||||
private double GapAt(int index) => index < ColumnGapWidths.Count
|
||||
? Math.Clamp(ColumnGapWidths[index], 0, 300)
|
||||
: 0;
|
||||
}
|
||||
Reference in New Issue
Block a user