themes eingebaut, müssen noch verfeinert werden

This commit is contained in:
OliverT87 2025-06-21 13:00:43 +02:00
parent f2646952c1
commit 53d3a39fa5
10 changed files with 281 additions and 233 deletions

View File

@ -0,0 +1,9 @@
namespace Project_Periodensystem.Model
{
public enum AppTheme
{
Dark,
Light,
Classic
}
}

View File

@ -4,14 +4,35 @@
xmlns:i="using:Avalonia.Interactivity" xmlns:i="using:Avalonia.Interactivity"
x:Class="Project_Periodensystem.View.AboutPage" x:Class="Project_Periodensystem.View.AboutPage"
Background="#5C5144"> Background="#5C5144">
<UserControl.Styles>
<Style Selector="Button">
<Setter Property="Background" Value="Black"/>
<Setter Property="Foreground" Value="White"/>
</Style>
<Style Selector="Button:pointerover /template/ ContentPresenter">
<Setter Property="Background" Value="DarkRed"/>
</Style>
<Style Selector="Button:pressed /template/ ContentPresenter">
<Setter Property="Background" Value="Red"/>
</Style>
</UserControl.Styles>
<Grid> <Grid>
<StackPanel VerticalAlignment="Center" <Grid.RowDefinitions>
HorizontalAlignment="Center"> <RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- Content -->
<StackPanel Grid.Row="0"
VerticalAlignment="Center"
HorizontalAlignment="Center">
<TextBlock Text="Author: Oliver Träger" <TextBlock Text="Author: Oliver Träger"
FontSize="20" FontSize="20"
Foreground="White" Foreground="White"
HorizontalAlignment="Center" HorizontalAlignment="Center"
Margin="0,0,0,10"/> Margin="0,0,0,10"/>
<TextBlock Text="Klasse: ITFS2" <TextBlock Text="Klasse: ITFS2"
FontSize="20" FontSize="20"
Foreground="White" Foreground="White"
@ -24,23 +45,34 @@
Margin="0,0,0,40"/> Margin="0,0,0,40"/>
</StackPanel> </StackPanel>
<Button x:Name="BackButton" <!-- Footer with Buttons -->
Click="BackButton_Click" <Grid Grid.Row="1"
HorizontalAlignment="Left" Margin="20,0,20,20">
VerticalAlignment="Top" <Grid.ColumnDefinitions>
Margin="20" <ColumnDefinition Width="Auto"/>
Padding="20,10" <ColumnDefinition Width="*"/>
Background="Black" <ColumnDefinition Width="Auto"/>
Foreground="White"> </Grid.ColumnDefinitions>
<Button.Styles>
<Style Selector="Button:pointerover /template/ ContentPresenter"> <Button Name="ThemeButton"
<Setter Property="Background" Value="DarkRed"/> Grid.Column="0"
</Style> Click="ThemeButton_Click"
<Style Selector="Button:pressed /template/ ContentPresenter"> Width="250"
<Setter Property="Background" Value="Red"/> Height="40">
</Style> <TextBlock Text="Theme wechseln"
</Button.Styles> FontSize="16"
Back HorizontalAlignment="Center"/>
</Button> </Button>
<Button x:Name="BackButton"
Grid.Column="2"
Click="BackButton_Click"
Width="200"
Height="40">
<TextBlock Text="Back"
FontSize="16"
HorizontalAlignment="Center"/>
</Button>
</Grid>
</Grid> </Grid>
</UserControl> </UserControl>

View File

@ -3,6 +3,7 @@ using Avalonia.Controls;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using Avalonia.VisualTree; using Avalonia.VisualTree;
using Project_Periodensystem.Model;
namespace Project_Periodensystem.View namespace Project_Periodensystem.View
{ {
@ -14,26 +15,30 @@ namespace Project_Periodensystem.View
} }
private void InitializeComponent() private void InitializeComponent()
=> AvaloniaXamlLoader.Load(this);
private void BackButton_Click(object sender, RoutedEventArgs e)
{ {
try AvaloniaXamlLoader.Load(this);
}
private void BackButton_Click(object? sender, RoutedEventArgs e)
{
if (this.Parent is ContentControl content && content.Parent is MainWindow mainWindow)
{ {
var mainWindow = this.FindAncestorOfType<MainWindow>(); mainWindow.ShowLandingPage();
if (mainWindow != null)
{
mainWindow.ShowLanding();
}
else
{
Console.WriteLine("MainWindow nicht gefunden!");
}
} }
catch (Exception ex) }
private void ThemeButton_Click(object? sender, RoutedEventArgs e)
{
var nextTheme = MainWindow.CurrentTheme switch
{ {
Console.WriteLine($"Fehler in BackButton_Click: {ex.Message}"); AppTheme.Dark => AppTheme.Light,
Console.WriteLine($"StackTrace: {ex.StackTrace}"); AppTheme.Light => AppTheme.Classic,
_ => AppTheme.Dark
};
if (this.Parent is ContentControl content && content.Parent is MainWindow mainWindow)
{
mainWindow.UpdateTheme(nextTheme);
} }
} }
} }

View File

@ -1,7 +1,7 @@
using System;
using System.Globalization;
using Avalonia.Data.Converters; using Avalonia.Data.Converters;
using Avalonia.Media; using Avalonia.Media;
using System;
using System.Globalization;
namespace Project_Periodensystem.View.Converters namespace Project_Periodensystem.View.Converters
{ {
@ -9,26 +9,27 @@ namespace Project_Periodensystem.View.Converters
{ {
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{ {
if (value is not string series) if (value == null) return new SolidColorBrush(Colors.Gray);
return new SolidColorBrush(Color.Parse("#222222")); // fallback
return series switch return value.ToString() switch
{ {
"Nichtmetall" => new SolidColorBrush(Color.Parse("#3e6418")), "Nichtmetall" => new SolidColorBrush(Color.Parse("#3e6418")),
"Metall" => new SolidColorBrush(Color.Parse("#711019")), // Übergangsmetall "Metall" => new SolidColorBrush(Color.Parse("#711019")),
"Post-Übergangsmetall" => new SolidColorBrush(Color.Parse("#555555")), // neu hinzugefügt "Post-Übergangsmetall" => new SolidColorBrush(Color.Parse("#555555")),
"Halbmetall" => new SolidColorBrush(Color.Parse("#015146")), "Halbmetall" => new SolidColorBrush(Color.Parse("#015146")),
"Edelgas" => new SolidColorBrush(Color.Parse("#3a2151")), "Edelgas" => new SolidColorBrush(Color.Parse("#3a2151")),
"Halogen" => new SolidColorBrush(Color.Parse("#846011")), "Halogen" => new SolidColorBrush(Color.Parse("#846011")),
"Alkalimetall" => new SolidColorBrush(Color.Parse("#6c3b01")), "Alkalimetall" => new SolidColorBrush(Color.Parse("#6c3b01")),
"Erdalkalimetall" => new SolidColorBrush(Color.Parse("#846011")), "Erdalkalimetall" => new SolidColorBrush(Color.Parse("#846011")),
"Lanthanoid" => new SolidColorBrush(Color.Parse("#402c17")), "Lanthanoid" => new SolidColorBrush(Color.Parse("#402c17")),
"Actinoid" => new SolidColorBrush(Color.Parse("#732e4c")), "Actinoid" => new SolidColorBrush(Color.Parse("#732e4c")),
_ => new SolidColorBrush(Color.Parse("#222222")), _ => new SolidColorBrush(Color.Parse("#222222"))
}; };
} }
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) => public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException(); throw new NotImplementedException();
}
} }
} }

View File

@ -2,30 +2,56 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Project_Periodensystem.View.LandingPage" x:Class="Project_Periodensystem.View.LandingPage"
Background="#5C5144"> Background="#5C5144">
<UserControl.Styles>
<Style Selector="Button">
<Setter Property="Background" Value="Black"/>
<Setter Property="Foreground" Value="White"/>
</Style>
<Style Selector="Button:pointerover /template/ ContentPresenter">
<Setter Property="Background" Value="DarkRed"/>
</Style>
<Style Selector="Button:pressed /template/ ContentPresenter">
<Setter Property="Background" Value="Red"/>
</Style>
</UserControl.Styles>
<Grid> <Grid>
<TextBlock Text="Willkommen zum Periodensystem der Elemente!" <Grid.RowDefinitions>
FontSize="36" <RowDefinition Height="*"/>
HorizontalAlignment="Center" <RowDefinition Height="Auto"/>
VerticalAlignment="Top" </Grid.RowDefinitions>
Margin="0,40,0,0"/>
<Button Name="StartButton" <!-- Hauptcontent -->
Click="StartButton_Click" <Grid Grid.Row="0">
HorizontalAlignment="Center" <StackPanel VerticalAlignment="Center"
VerticalAlignment="Center" Margin="0,-100,0,0">
Width="200" <TextBlock Text="Willkommen zum Periodensystem der Elemente!"
Height="50" FontSize="36"
Background="Black" HorizontalAlignment="Center"
Foreground="White"> Margin="0,0,0,20"/>
<Button.Styles> <Button Name="StartButton"
<Style Selector="Button:pointerover /template/ ContentPresenter"> Click="StartButton_Click"
<Setter Property="Background" Value="DarkRed"/> HorizontalAlignment="Center"
</Style> Width="200"
<Style Selector="Button:pressed /template/ ContentPresenter"> Height="50">
<Setter Property="Background" Value="Red"/> <TextBlock Text="Start"
</Style> FontSize="24"
</Button.Styles> HorizontalAlignment="Center"/>
<TextBlock Text="Start" </Button>
FontSize="24" </StackPanel>
</Grid>
<!-- Theme Button -->
<Button Name="ThemeButton"
Grid.Row="1"
Click="ThemeButton_Click"
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
Width="250"
Height="40"
Margin="20,0,0,20">
<TextBlock Text="Theme wechseln"
FontSize="16"
HorizontalAlignment="Center"/> HorizontalAlignment="Center"/>
</Button> </Button>
</Grid> </Grid>

View File

@ -2,21 +2,35 @@ using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using Avalonia.VisualTree; using Avalonia.Media;
using Project_Periodensystem.Model;
using System; using System;
using System.Collections.Generic;
namespace Project_Periodensystem.View namespace Project_Periodensystem.View
{ {
public partial class LandingPage : UserControl public partial class LandingPage : UserControl
{ {
private readonly Random random = new();
private readonly Dictionary<AppTheme, string> themeColors;
private AppTheme currentTheme;
private Button? startButton; private Button? startButton;
private DateTime lastClickTime = DateTime.MinValue; private DateTime lastClickTime = DateTime.MinValue;
private const int DEBOUNCE_MS = 500; private const int DEBOUNCE_MS = 500;
public LandingPage() public LandingPage()
{ {
Logger.Log("=== LandingPage wird initialisiert ==="); Logger.Log($"=== LandingPage wird initialisiert am {DateTime.Now:dd.MM.yyyy HH:mm:ss} ===");
InitializeComponent(); InitializeComponent();
themeColors = new Dictionary<AppTheme, string>
{
{ AppTheme.Dark, "#5C5144" },
{ AppTheme.Light, "#E8DFD8" },
{ AppTheme.Classic, "#7B8B6F" }
};
SetRandomTheme();
startButton = this.Find<Button>("StartButton"); startButton = this.Find<Button>("StartButton");
if (startButton != null) if (startButton != null)
@ -36,6 +50,25 @@ namespace Project_Periodensystem.View
AvaloniaXamlLoader.Load(this); AvaloniaXamlLoader.Load(this);
} }
private void SetRandomTheme()
{
var themes = Enum.GetValues<AppTheme>();
currentTheme = themes[random.Next(themes.Length)];
this.Background = new SolidColorBrush(Color.Parse(themeColors[currentTheme]));
Logger.Log($"Theme gewählt: {currentTheme}");
}
private void ThemeButton_Click(object? sender, RoutedEventArgs e)
{
var themes = Enum.GetValues<AppTheme>();
currentTheme = themes[(Array.IndexOf(themes, currentTheme) + 1) % themes.Length];
if (this.Parent is ContentControl content && content.Parent is MainWindow mainWindow)
{
mainWindow.UpdateTheme(currentTheme);
}
}
private void StartButton_Click(object? sender, RoutedEventArgs e) private void StartButton_Click(object? sender, RoutedEventArgs e)
{ {
// Stop event propagation // Stop event propagation
@ -54,16 +87,9 @@ namespace Project_Periodensystem.View
try try
{ {
var mainWindow = this.FindAncestorOfType<MainWindow>(); if (this.Parent is ContentControl content && content.Parent is MainWindow mainWindow)
if (mainWindow != null)
{ {
Logger.Log("MainWindow gefunden, starte Navigation...");
mainWindow.ShowPeriodicTable(); mainWindow.ShowPeriodicTable();
Logger.Log("Navigation ausgeführt");
}
else
{
Logger.Log("FEHLER: MainWindow nicht gefunden!");
} }
} }
catch (Exception ex) catch (Exception ex)

View File

@ -5,7 +5,6 @@
Width="1024" Width="1024"
Height="768"> Height="768">
<Grid> <ContentControl Name="MainContent"/>
<ContentControl Name="MainContent"/>
</Grid>
</Window> </Window>

View File

@ -1,101 +1,52 @@
using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Markup.Xaml; using Avalonia.Media;
using Project_Periodensystem.Model;
using System; using System;
using System.Collections.Generic;
namespace Project_Periodensystem.View namespace Project_Periodensystem.View
{ {
public partial class MainWindow : Window public partial class MainWindow : Window
{ {
private readonly ContentControl? mainContent; private ContentControl? mainContent;
public static AppTheme CurrentTheme { get; set; } = AppTheme.Dark;
public static Dictionary<AppTheme, string> ThemeColors { get; } = new()
{
{ AppTheme.Dark, "#5C5144" },
{ AppTheme.Light, "#E8DFD8" },
{ AppTheme.Classic, "#7B8B6F" }
};
public MainWindow() public MainWindow()
{ {
InitializeComponent(); InitializeComponent();
try mainContent = this.FindControl<ContentControl>("MainContent");
{ ShowLandingPage();
Console.WriteLine("MainWindow wird initialisiert...");
var content = this.Find<ContentControl>("MainContent");
if (content == null)
{
Console.WriteLine("FEHLER: MainContent nicht gefunden!");
throw new Exception("MainContent control not found.");
}
mainContent = content;
Console.WriteLine("Navigation zur Landing Page...");
ShowLanding();
}
catch (Exception ex)
{
Console.WriteLine($"FEHLER in MainWindow Constructor: {ex.Message}");
}
} }
public void ShowLanding() public void ShowLandingPage()
{ {
try mainContent!.Content = new LandingPage();
{
Console.WriteLine("ShowLanding wird aufgerufen...");
if (mainContent != null)
{
mainContent.Content = new LandingPage();
}
else
{
Console.WriteLine("FEHLER: mainContent ist null in ShowLanding!");
}
}
catch (Exception ex)
{
Console.WriteLine($"FEHLER in ShowLanding: {ex.Message}");
}
} }
public void ShowPeriodicTable() public void ShowPeriodicTable()
{ {
try mainContent!.Content = new PeriodicTablePage();
{
Logger.Log("ShowPeriodicTable wird aufgerufen...");
if (mainContent != null)
{
var periodicTablePage = new PeriodicTablePage();
mainContent.Content = periodicTablePage;
Logger.Log("PeriodicTablePage wurde geladen");
}
else
{
Logger.Log("FEHLER: mainContent ist null in ShowPeriodicTable!");
}
}
catch (Exception ex)
{
Logger.Log($"FEHLER in ShowPeriodicTable: {ex.Message}");
}
} }
public void ShowAbout() public void ShowAboutPage()
{ {
try mainContent!.Content = new AboutPage();
{
Console.WriteLine("ShowAbout wird aufgerufen...");
if (mainContent != null)
{
mainContent.Content = new AboutPage();
}
else
{
Console.WriteLine("FEHLER: mainContent ist null in ShowAbout!");
}
}
catch (Exception ex)
{
Console.WriteLine($"FEHLER in ShowAbout: {ex.Message}");
}
} }
private void InitializeComponent() public void UpdateTheme(AppTheme theme)
{ {
AvaloniaXamlLoader.Load(this); CurrentTheme = theme;
if (mainContent?.Content is UserControl control)
{
control.Background = new SolidColorBrush(Color.Parse(ThemeColors[theme]));
}
} }
} }
} }

View File

@ -5,6 +5,19 @@
x:Class="Project_Periodensystem.View.PeriodicTablePage" x:Class="Project_Periodensystem.View.PeriodicTablePage"
Background="#5C5144"> Background="#5C5144">
<UserControl.Styles>
<Style Selector="Button">
<Setter Property="Background" Value="Black"/>
<Setter Property="Foreground" Value="White"/>
</Style>
<Style Selector="Button:pointerover /template/ ContentPresenter">
<Setter Property="Background" Value="DarkRed"/>
</Style>
<Style Selector="Button:pressed /template/ ContentPresenter">
<Setter Property="Background" Value="Red"/>
</Style>
</UserControl.Styles>
<UserControl.Resources> <UserControl.Resources>
<conv:SeriesToColorConverter x:Key="SeriesToColor"/> <conv:SeriesToColorConverter x:Key="SeriesToColor"/>
</UserControl.Resources> </UserControl.Resources>
@ -25,7 +38,7 @@
HorizontalAlignment="Center" HorizontalAlignment="Center"
Margin="0,0,0,20"/> Margin="0,0,0,20"/>
<!-- Periodensystem Grid --> <!-- Periodic Table Grid -->
<ScrollViewer Grid.Row="1" <ScrollViewer Grid.Row="1"
HorizontalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"> VerticalScrollBarVisibility="Auto">
@ -67,24 +80,34 @@
</Grid> </Grid>
</ScrollViewer> </ScrollViewer>
<!-- Footer with About Button --> <!-- Footer with Buttons -->
<Button Grid.Row="2" <Grid Grid.Row="2"
x:Name="AboutButton" Margin="0,20,0,0">
Content="About" <Grid.ColumnDefinitions>
Click="AboutButton_Click" <ColumnDefinition Width="Auto"/>
HorizontalAlignment="Right" <ColumnDefinition Width="*"/>
Margin="0,20,0,0" <ColumnDefinition Width="Auto"/>
Padding="20,10" </Grid.ColumnDefinitions>
Background="Black"
Foreground="White"> <Button Name="ThemeButton"
<Button.Styles> Grid.Column="0"
<Style Selector="Button:pointerover /template/ ContentPresenter"> Click="ThemeButton_Click"
<Setter Property="Background" Value="DarkRed"/> Width="250"
</Style> Height="40">
<Style Selector="Button:pressed /template/ ContentPresenter"> <TextBlock Text="Theme wechseln"
<Setter Property="Background" Value="Red"/> FontSize="16"
</Style> HorizontalAlignment="Center"/>
</Button.Styles> </Button>
</Button>
<Button x:Name="AboutButton"
Grid.Column="2"
Click="AboutButton_Click"
Width="200"
Height="40">
<TextBlock Text="About"
FontSize="16"
HorizontalAlignment="Center"/>
</Button>
</Grid>
</Grid> </Grid>
</UserControl> </UserControl>

View File

@ -1,42 +1,17 @@
using System;
using System.Globalization;
using System.Linq;
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Data.Converters;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.VisualTree; using Project_Periodensystem.Model;
using Project_Periodensystem.Persistence; using Project_Periodensystem.Persistence;
using Project_Periodensystem.View.Converters; using Project_Periodensystem.View.Converters;
using System;
using System.Globalization;
using System.Linq;
namespace Project_Periodensystem.View namespace Project_Periodensystem.View
{ {
// Converter to map element series to a color
public class SeriesToColorConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null) return new SolidColorBrush(Colors.Gray);
return value.ToString() switch
{
"Nichtmetall" => new SolidColorBrush(Color.Parse("#3e6418")),
"Metall" => new SolidColorBrush(Color.Parse("#711019")),
"Post-Übergangsmetall" => new SolidColorBrush(Color.Parse("#555555")),
"Halbmetall" => new SolidColorBrush(Color.Parse("#015146")),
"Edelgas" => new SolidColorBrush(Color.Parse("#3a2151")),
"Halogen" => new SolidColorBrush(Color.Parse("#846011")),
"Alkalimetall" => new SolidColorBrush(Color.Parse("#6c3b01")),
"Erdalkalimetall" => new SolidColorBrush(Color.Parse("#846011")),
"Lanthanoid" => new SolidColorBrush(Color.Parse("#402c17")),
"Actinoid" => new SolidColorBrush(Color.Parse("#732e4c")),
_ => new SolidColorBrush(Color.Parse("#222222"))
};
}
}
public partial class PeriodicTablePage : UserControl public partial class PeriodicTablePage : UserControl
{ {
private readonly Grid? periodicGrid; private readonly Grid? periodicGrid;
@ -129,25 +104,26 @@ namespace Project_Periodensystem.View
} }
} }
private void ThemeButton_Click(object? sender, RoutedEventArgs e)
{
var nextTheme = MainWindow.CurrentTheme switch
{
AppTheme.Dark => AppTheme.Light,
AppTheme.Light => AppTheme.Classic,
_ => AppTheme.Dark
};
if (this.Parent is ContentControl content && content.Parent is MainWindow mainWindow)
{
mainWindow.UpdateTheme(nextTheme);
}
}
private void AboutButton_Click(object? sender, RoutedEventArgs e) private void AboutButton_Click(object? sender, RoutedEventArgs e)
{ {
try if (this.Parent is ContentControl content && content.Parent is MainWindow mainWindow)
{ {
Logger.Log("AboutButton wurde geklickt"); mainWindow.ShowAboutPage();
var mainWindow = this.FindAncestorOfType<MainWindow>();
if (mainWindow != null)
{
Logger.Log("Navigation zu About Page");
mainWindow.ShowAbout();
}
else
{
Logger.Log("FEHLER: MainWindow nicht gefunden");
}
}
catch (Exception ex)
{
Logger.Log($"FEHLER im AboutButton_Click: {ex.Message}");
} }
} }
} }