402 lines
13 KiB
C#
402 lines
13 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using Avalonia;
|
|
using Avalonia.Controls;
|
|
using Avalonia.Interactivity;
|
|
using Avalonia.Media;
|
|
using Project_Periodensystem.Controller;
|
|
using Project_Periodensystem.Model;
|
|
using Project_Periodensystem.Persistence;
|
|
using Project_Periodensystem.View.Converters;
|
|
|
|
namespace Project_Periodensystem.View
|
|
{
|
|
/// <summary>
|
|
/// Code-Behind für das Periodensystem - nur UI-Logik, keine Geschäftslogik
|
|
/// </summary>
|
|
public partial class PeriodicTablePage : UserControl
|
|
{
|
|
private readonly Grid? periodicGrid;
|
|
private PeriodensystemController? _controller;
|
|
|
|
// Für Highlighting-Funktionalität
|
|
private string? _currentHighlightedSeries;
|
|
private readonly List<Button> _elementButtons = new List<Button>();
|
|
private readonly List<Button> _legendButtons = new List<Button>();
|
|
|
|
/// <summary>
|
|
/// Konstruktor - initialisiert UI (Controller wird per SetController gesetzt)
|
|
/// </summary>
|
|
public PeriodicTablePage()
|
|
{
|
|
InitializeComponent();
|
|
|
|
// Grid-Referenz für Element-Buttons
|
|
periodicGrid = this.FindControl<Grid>("PeriodicGrid");
|
|
}
|
|
|
|
public void SetController(PeriodensystemController controller)
|
|
{
|
|
_controller = controller ?? throw new ArgumentNullException(nameof(controller));
|
|
Logger.Log("PeriodicTablePage: Controller gesetzt (MVC-Pattern)");
|
|
LoadAndDisplayElements();
|
|
}
|
|
|
|
private void LoadAndDisplayElements()
|
|
{
|
|
try
|
|
{
|
|
if (_controller == null)
|
|
{
|
|
Logger.LogError("Controller nicht gesetzt - kann Elemente nicht laden");
|
|
return;
|
|
}
|
|
|
|
var elements = _controller.GetAllElements();
|
|
|
|
if (!elements.Any())
|
|
{
|
|
Logger.Log("Keine Elemente vom Controller erhalten");
|
|
return;
|
|
}
|
|
|
|
if (!_controller.ValidateData())
|
|
{
|
|
Logger.Log("Datenvalidierung fehlgeschlagen");
|
|
return;
|
|
}
|
|
|
|
Logger.Log($"Lade {elements.Count} Elemente in das Grid");
|
|
|
|
int successCount = 0;
|
|
foreach (var element in elements)
|
|
{
|
|
if (_controller.ValidateElementPosition(element))
|
|
{
|
|
CreateElementButton(element);
|
|
successCount++;
|
|
}
|
|
else
|
|
{
|
|
Logger.Log($"Element {element?.Symbol ?? "NULL"} übersprungen - ungültige Position");
|
|
}
|
|
}
|
|
|
|
Logger.Log($"{successCount} von {elements.Count} Elementen erfolgreich geladen");
|
|
CollectLegendButtons();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Log($"EXCEPTION in LoadAndDisplayElements: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
private void CreateElementButton(Element element)
|
|
{
|
|
if (element == null)
|
|
{
|
|
Logger.Log("Null-Element kann nicht angezeigt werden");
|
|
return;
|
|
}
|
|
|
|
var button = new Button { Classes = { "ElementTile" } };
|
|
var panel = new StackPanel();
|
|
|
|
button.Tag = element;
|
|
_elementButtons.Add(button);
|
|
|
|
var backgroundColor = new SeriesToColorConverter()
|
|
.Convert(element.Series, typeof(Brush), null, CultureInfo.InvariantCulture) as Brush;
|
|
|
|
if (backgroundColor != null)
|
|
{
|
|
button.Background = backgroundColor;
|
|
}
|
|
|
|
var symbolText = new TextBlock
|
|
{
|
|
Text = element.Symbol,
|
|
Classes = { "Symbol" },
|
|
Foreground = new SolidColorBrush(Colors.White),
|
|
HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Center
|
|
};
|
|
|
|
var numberText = new TextBlock
|
|
{
|
|
Text = element.AtomicNumber.ToString(),
|
|
Classes = { "Number" },
|
|
Foreground = new SolidColorBrush(Colors.White),
|
|
HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Center
|
|
};
|
|
|
|
panel.Children.Add(numberText);
|
|
panel.Children.Add(symbolText);
|
|
button.Content = panel;
|
|
|
|
int gridRow = element.Row;
|
|
int gridColumn = element.Column;
|
|
|
|
Logger.Log($"Element {element.Symbol}: Grid({gridRow},{gridColumn})");
|
|
|
|
Grid.SetRow(button, gridRow);
|
|
Grid.SetColumn(button, gridColumn);
|
|
|
|
if (periodicGrid != null)
|
|
{
|
|
periodicGrid.Children.Add(button);
|
|
}
|
|
else
|
|
{
|
|
Logger.Log("PeriodicGrid ist null - Button kann nicht hinzugefügt werden");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Event-Handler für Theme-Button - SAUBERES MVC
|
|
/// </summary>
|
|
private void ThemeButton_Click(object? sender, RoutedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
if (_controller != null)
|
|
{
|
|
// Controller übernimmt Theme-Logik
|
|
_controller.HandleToggleTheme();
|
|
}
|
|
else
|
|
{
|
|
Logger.LogError("Controller nicht gesetzt - kann Theme nicht wechseln");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.LogException(ex, "ThemeButton_Click");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Event-Handler für About-Button - SAUBERES MVC
|
|
/// </summary>
|
|
private void AboutButton_Click(object? sender, RoutedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
if (_controller != null)
|
|
{
|
|
// Controller übernimmt Navigation
|
|
_controller.HandleNavigateToAbout();
|
|
}
|
|
else
|
|
{
|
|
Logger.LogError("Controller nicht gesetzt - kann nicht navigieren");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.LogException(ex, "AboutButton_Click");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Event-Handler für Zurück-Button - SAUBERES MVC
|
|
/// </summary>
|
|
private void BackButton_Click(object? sender, RoutedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
if (_controller != null)
|
|
{
|
|
// Controller übernimmt Navigation
|
|
_controller.HandleNavigateToLanding();
|
|
}
|
|
else
|
|
{
|
|
Logger.LogError("Controller nicht gesetzt - kann nicht navigieren");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.LogException(ex, "BackButton_Click");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Export-Button für Element-Daten - SAUBERES MVC
|
|
/// </summary>
|
|
private void ExportButton_Click(object? sender, RoutedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
if (_controller != null)
|
|
{
|
|
// Controller übernimmt Export-Logik
|
|
_controller.HandleExportData();
|
|
}
|
|
else
|
|
{
|
|
Logger.LogError("Controller nicht gesetzt - kann nicht exportieren");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.LogException(ex, "ExportButton_Click");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Event-Handler für Legende-Buttons - Highlighting-Funktionalität
|
|
/// </summary>
|
|
private void LegendButton_Click(object? sender, RoutedEventArgs e)
|
|
{
|
|
try
|
|
{
|
|
if (sender is not Button legendButton || legendButton.Tag?.ToString() is not string series)
|
|
{
|
|
Logger.LogError("LegendButton_Click: Ungültiger Button oder Tag");
|
|
return;
|
|
}
|
|
|
|
// Prüfen ob diese Serie bereits highlighted ist
|
|
if (_currentHighlightedSeries == series)
|
|
{
|
|
// Highlighting entfernen
|
|
ClearHighlighting();
|
|
Logger.Log($"Highlighting für {series} entfernt");
|
|
}
|
|
else
|
|
{
|
|
// Neue Serie highlighten
|
|
HighlightSeries(series);
|
|
Logger.Log($"Serie {series} wird highlighted");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.LogException(ex, "LegendButton_Click");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Hebt eine bestimmte Elementserie hervor
|
|
/// </summary>
|
|
private void HighlightSeries(string series)
|
|
{
|
|
try
|
|
{
|
|
// Zuerst alle Highlights entfernen
|
|
ClearHighlighting();
|
|
|
|
// Neue Serie als aktuell highlighted setzen
|
|
_currentHighlightedSeries = series;
|
|
|
|
// Element-Buttons highlighten, die zur Serie gehören
|
|
foreach (var button in _elementButtons)
|
|
{
|
|
if (button.Tag is Element element && element.Series == series)
|
|
{
|
|
button.Classes.Add("Highlighted");
|
|
}
|
|
}
|
|
|
|
// Legend-Button highlighten
|
|
var legendButton = GetLegendButtonForSeries(series);
|
|
if (legendButton != null)
|
|
{
|
|
legendButton.Classes.Add("Highlighted");
|
|
}
|
|
|
|
Logger.Log($"Highlighting für Serie '{series}' angewendet");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.LogException(ex, "HighlightSeries");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Entfernt alle Highlighting-Effekte
|
|
/// </summary>
|
|
private void ClearHighlighting()
|
|
{
|
|
try
|
|
{
|
|
_currentHighlightedSeries = null;
|
|
|
|
// Highlighting von allen Element-Buttons entfernen
|
|
foreach (var button in _elementButtons)
|
|
{
|
|
button.Classes.Remove("Highlighted");
|
|
}
|
|
|
|
// Highlighting von allen Legend-Buttons entfernen
|
|
foreach (var button in _legendButtons)
|
|
{
|
|
button.Classes.Remove("Highlighted");
|
|
}
|
|
|
|
Logger.Log("Alle Highlighting-Effekte entfernt");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.LogException(ex, "ClearHighlighting");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Findet den Legend-Button für eine bestimmte Serie
|
|
/// </summary>
|
|
private Button? GetLegendButtonForSeries(string series)
|
|
{
|
|
try
|
|
{
|
|
// Durchsuche alle Legend-Buttons
|
|
foreach (var button in _legendButtons)
|
|
{
|
|
if (button.Tag?.ToString() == series)
|
|
{
|
|
return button;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.LogException(ex, "GetLegendButtonForSeries");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sammelt alle Legend-Button-Referenzen nach dem Laden der UI
|
|
/// </summary>
|
|
private void CollectLegendButtons()
|
|
{
|
|
try
|
|
{
|
|
_legendButtons.Clear();
|
|
|
|
// Finde alle Buttons mit der Klasse "LegendButton"
|
|
var legendPanel = this.FindControl<WrapPanel>("LegendPanel");
|
|
if (legendPanel != null)
|
|
{
|
|
foreach (var child in legendPanel.Children)
|
|
{
|
|
if (child is Button button && button.Classes.Contains("LegendButton"))
|
|
{
|
|
_legendButtons.Add(button);
|
|
}
|
|
}
|
|
}
|
|
|
|
Logger.Log($"{_legendButtons.Count} Legend-Buttons gefunden");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.LogException(ex, "CollectLegendButtons");
|
|
}
|
|
}
|
|
}
|
|
}
|