This commit is contained in:
@@ -48,12 +48,14 @@ public partial class DesignerViewModel : ObservableObject
|
||||
[ObservableProperty] private string _overlayPageUnit = "mm";
|
||||
[ObservableProperty] private string _selectedPageTemplate = "first";
|
||||
[ObservableProperty] private DesignerPreviewPage? _selectedPreviewPage;
|
||||
[ObservableProperty] private SpecialContentItem? _selectedSpecialContent;
|
||||
|
||||
public IReadOnlyList<string> Units { get; } = ["mm", "cm", "pt", "in"];
|
||||
public IReadOnlyList<PlaceholderType> PlaceholderTypes { get; } = Enum.GetValues<PlaceholderType>();
|
||||
public IReadOnlyList<string> ElementTypes { get; } =
|
||||
["TEXT", "TEXTBOX", "FLOWBOX", "DRAWBOX", "FLOWDRAWBOX", "IMG", "TABLE", "CHART"];
|
||||
public IReadOnlyList<string> ElementScopes { get; } = ["Seitenvorlage (fest)", "Content-Flow"];
|
||||
public IReadOnlyList<SpecialContentItem> SpecialContents { get; } = SpecialContentCatalog.Items;
|
||||
public ObservableCollection<DesignerPlaceholder> Placeholders { get; } =
|
||||
[
|
||||
new("Datum", PlaceholderType.Date, true, DateTime.Today.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture)),
|
||||
@@ -78,7 +80,11 @@ public partial class DesignerViewModel : ObservableObject
|
||||
public bool HasSelectedPlaceholder => SelectedPlaceholder is not null;
|
||||
public bool HasNoSelectedPlaceholder => SelectedPlaceholder is null;
|
||||
|
||||
public DesignerViewModel() => SelectedPlaceholder = Placeholders.FirstOrDefault();
|
||||
public DesignerViewModel()
|
||||
{
|
||||
SelectedPlaceholder = Placeholders.FirstOrDefault();
|
||||
SelectedSpecialContent = SpecialContents.FirstOrDefault();
|
||||
}
|
||||
|
||||
partial void OnSelectedPlaceholderChanged(DesignerPlaceholder? value)
|
||||
{
|
||||
@@ -198,6 +204,32 @@ public partial class DesignerViewModel : ObservableObject
|
||||
return placeholder;
|
||||
}
|
||||
|
||||
/// <summary>Übernimmt einen lesbar benannten LehrerApp-Sonderinhalt in das normale
|
||||
/// Elementformular und legt seine Drawing-Deklaration an, falls sie noch fehlt.</summary>
|
||||
public void PrepareSelectedSpecialContent()
|
||||
{
|
||||
if (SelectedSpecialContent is not { } special)
|
||||
throw new InvalidOperationException("Bitte zuerst einen Sonderinhalt auswählen.");
|
||||
var placeholder = Placeholders.FirstOrDefault(p => p.Name == special.PlaceholderName);
|
||||
if (placeholder is not null && placeholder.Type != PlaceholderType.Drawing)
|
||||
throw new InvalidDataException(
|
||||
$"Der vorhandene Platzhalter „{special.PlaceholderName}“ hat nicht den Typ Drawing.");
|
||||
if (placeholder is null)
|
||||
{
|
||||
placeholder = new DesignerPlaceholder(special.PlaceholderName, PlaceholderType.Drawing,
|
||||
false, special.Description);
|
||||
Placeholders.Add(placeholder);
|
||||
}
|
||||
SelectedPlaceholder = placeholder;
|
||||
NewElementType = special.RecommendedElementType;
|
||||
NewContent = "$" + special.PlaceholderName;
|
||||
NewWidth = special.RecommendedWidth;
|
||||
NewHeight = special.RecommendedHeight;
|
||||
NewAttributes = "";
|
||||
CanExport = false;
|
||||
SetStatus($"„{special.DisplayName}“ vorbereitet. Position und Größe prüfen, dann ins Layout übernehmen.", false);
|
||||
}
|
||||
|
||||
public void RemoveSelectedPlaceholder()
|
||||
{
|
||||
if (SelectedPlaceholder is not { } selected) return;
|
||||
@@ -703,6 +735,48 @@ public sealed record DesignerPreviewPage(int Number, Bitmap Image)
|
||||
public string Display => $"Dokumentseite {Number}";
|
||||
}
|
||||
|
||||
public sealed record SpecialContentItem(string DisplayName, string PlaceholderName, string Description,
|
||||
string RecommendedElementType, string RecommendedWidth, string RecommendedHeight);
|
||||
|
||||
public static class SpecialContentCatalog
|
||||
{
|
||||
public static IReadOnlyList<SpecialContentItem> Items { get; } =
|
||||
[
|
||||
new("Anwesenheitskalender", "Student.AttendanceCalendar",
|
||||
"Monatskalender mit farbigen Anwesenheitsmarkern; Zeitraum und Größe werden beim Erstellen des Briefs gewählt.",
|
||||
"DRAWBOX", "170", "90"),
|
||||
new("Fehltage nach Datum", "Student.AbsenceDays",
|
||||
"Chronologische Liste mit Datum, Fehlzeit oder ganzem Fehltag sowie Entschuldigungsstatus.",
|
||||
"FLOWDRAWBOX", "170", "140"),
|
||||
];
|
||||
|
||||
public static DrawingValue SampleDrawing(string placeholderName) => placeholderName switch
|
||||
{
|
||||
"Student.AttendanceCalendar" => new DrawingValue(
|
||||
[
|
||||
new DrawString(2, 2, "Anwesenheit · Erika Beispiel", 10, "#1F2937", Bold: true),
|
||||
new DrawRectangle(2, 14, 22, 12, "#D1D5DB", .4f, "#FFFFFF"),
|
||||
new DrawString(9, 16, "12", 7, "#374151"),
|
||||
new DrawRectangle(26, 14, 22, 12, "#C62828", .4f, "#C62828"),
|
||||
new DrawString(34, 16, "U", 7, "#FFFFFF", Bold: true),
|
||||
new DrawRectangle(50, 14, 22, 12, "#2E7D32", .4f, "#2E7D32"),
|
||||
new DrawString(58, 16, "E", 7, "#FFFFFF", Bold: true),
|
||||
], 28),
|
||||
"Student.AbsenceDays" => new DrawingValue(
|
||||
[
|
||||
new DrawString(2, 2, "Fehltage · Erika Beispiel", 10, "#1F2937", Bold: true),
|
||||
new DrawRectangle(2, 14, 166, 11, "#CBD5E1", .4f, "#F3F4F6"),
|
||||
new DrawString(4, 15, "Datum", 7, "#374151", Bold: true),
|
||||
new DrawString(42, 15, "Umfang", 7, "#374151", Bold: true),
|
||||
new DrawString(116, 15, "Status", 7, "#374151", Bold: true),
|
||||
new DrawString(4, 27, "03.09.2026", 7, "#374151"),
|
||||
new DrawString(42, 27, "Ganzer Fehltag", 7, "#374151"),
|
||||
new DrawString(116, 27, "Entschuldigt", 7, "#2E7D32"),
|
||||
], 38),
|
||||
_ => DesignerPlaceholder.GenericSampleDrawing(),
|
||||
};
|
||||
}
|
||||
|
||||
public partial class DesignerAsset(string name, int pixelWidth, int pixelHeight, long byteCount) : ObservableObject
|
||||
{
|
||||
[ObservableProperty] private int _usageCount;
|
||||
@@ -757,7 +831,7 @@ public partial class DesignerPlaceholder : ObservableObject
|
||||
PlaceholderType.Image => new ImageValue([], "image/png"),
|
||||
PlaceholderType.Table => ParseTable(Sample),
|
||||
PlaceholderType.Chart => ParseChart(Sample),
|
||||
PlaceholderType.Drawing => SampleDrawing(),
|
||||
PlaceholderType.Drawing => SpecialContentCatalog.SampleDrawing(Name),
|
||||
_ => new TextValue(Sample),
|
||||
};
|
||||
public static string SampleFor(PlaceholderType type) => type switch
|
||||
@@ -772,7 +846,7 @@ public partial class DesignerPlaceholder : ObservableObject
|
||||
}
|
||||
private static ChartValue ParseChart(string value) => new([new("Werte", value.Split(';', StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select((x, i) => { var parts = x.Split(':', 2); return new ChartPoint(parts[0], parts.Length == 2 && decimal.TryParse(parts[1], CultureInfo.InvariantCulture, out var y) ? y : i + 1); }).ToList())]);
|
||||
private static DrawingValue SampleDrawing() => new DrawingValue(
|
||||
internal static DrawingValue GenericSampleDrawing() => new DrawingValue(
|
||||
[new DrawRectangle(0, 0, 80, 24, "#2563EB", 0.8f, "#EFF6FF"),
|
||||
new DrawString(4, 4, "Dynamischer Inhalt", 10, "#1E3A8A", Bold: true),
|
||||
new MoveTo(4, 19), new LineTo(76, 19, "#93C5FD", 0.6f)], 24);
|
||||
|
||||
@@ -213,6 +213,21 @@
|
||||
<ScrollViewer Padding="8">
|
||||
<StackPanel Spacing="12">
|
||||
<TextBlock Text="Element hinzufügen" Classes="section"/>
|
||||
<Border BorderBrush="#93C5FD" BorderThickness="1" Background="#EFF6FF"
|
||||
CornerRadius="6" Padding="12">
|
||||
<StackPanel Spacing="7">
|
||||
<TextBlock Text="LehrerApp-Sonderinhalte" FontWeight="SemiBold" Foreground="#1E3A8A"/>
|
||||
<TextBlock Text="Kein technischer Platzhaltername nötig: Inhalt auswählen und übernehmen."
|
||||
FontSize="11" Foreground="#475569" TextWrapping="Wrap"/>
|
||||
<ComboBox ItemsSource="{Binding SpecialContents}"
|
||||
SelectedItem="{Binding SelectedSpecialContent, Mode=TwoWay}"
|
||||
DisplayMemberBinding="{Binding DisplayName}"/>
|
||||
<TextBlock Text="{Binding SelectedSpecialContent.Description}" FontSize="11"
|
||||
Foreground="#475569" TextWrapping="Wrap"/>
|
||||
<Button Content="Für Layout vorbereiten" HorizontalAlignment="Left"
|
||||
Click="OnPrepareSpecialContent"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<StackPanel><TextBlock Text="Einfügen in" Classes="label"/>
|
||||
<ComboBox ItemsSource="{Binding ElementScopes}" SelectedItem="{Binding NewElementScope}"/></StackPanel>
|
||||
<Grid ColumnDefinitions="*,8,*">
|
||||
|
||||
@@ -58,6 +58,8 @@ public partial class MainWindow : Window
|
||||
}
|
||||
private void OnAddElement(object? sender, RoutedEventArgs e)
|
||||
{ try { _viewModel.AddElement(); } catch (Exception ex) { _viewModel.SetStatus(ex.Message, true); } }
|
||||
private void OnPrepareSpecialContent(object? sender, RoutedEventArgs e)
|
||||
{ try { _viewModel.PrepareSelectedSpecialContent(); } catch (Exception ex) { _viewModel.SetStatus(ex.Message, true); } }
|
||||
private void OnAddPageTemplate(object? sender, RoutedEventArgs e)
|
||||
{ try { _viewModel.AddPageTemplate(); } catch (Exception ex) { _viewModel.SetStatus(ex.Message, true); } }
|
||||
private void OnAddContentFlow(object? sender, RoutedEventArgs e)
|
||||
|
||||
Reference in New Issue
Block a user