Was ein verfickter Krampf, Grid nun da, Farben passen noch nicht

This commit is contained in:
OliverT87 2025-05-06 16:38:30 +02:00
parent 3c9c8f0f7e
commit 9d75411aa7
10 changed files with 137 additions and 146 deletions

View File

@ -1,9 +1,7 @@
<Application xmlns="https://github.com/avaloniaui" <Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Project_Periodensystem.View.App" x:Class="Project_Periodensystem.View.App"
RequestedThemeVariant="Default"> RequestedThemeVariant="Light">
<!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. -->
<Application.Styles> <Application.Styles>
<FluentTheme /> <FluentTheme />
</Application.Styles> </Application.Styles>

View File

@ -2,22 +2,19 @@ using Avalonia;
using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml; using Avalonia.Markup.Xaml;
namespace Project_Periodensystem.View; namespace Project_Periodensystem.View
public partial class App : Application
{ {
public override void Initialize() public partial class App : Application
{ {
AvaloniaXamlLoader.Load(this); public override void Initialize()
} => AvaloniaXamlLoader.Load(this);
public override void OnFrameworkInitializationCompleted() public override void OnFrameworkInitializationCompleted()
{ {
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
desktop.MainWindow = new MainWindow(); desktop.MainWindow = new MainWindow();
}
base.OnFrameworkInitializationCompleted(); base.OnFrameworkInitializationCompleted();
} }
}
} }

View File

@ -1,43 +1,42 @@
<UserControl xmlns="https://github.com/avaloniaui" <UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="clr-namespace:Project_Periodensystem.View.Converters" xmlns:conv="clr-namespace:Project_Periodensystem.View.Converters"
x:Class="Project_Periodensystem.View.Components.ElementTile" x:Class="Project_Periodensystem.View.Components.ElementTile"
Width="100" Height="120"> Width="80" Height="80"
RenderTransformOrigin="0.5,0.5">
<UserControl.Resources> <!-- 1) Converter registrieren -->
<converters:SeriesToColorConverter x:Key="SeriesToColor" /> <UserControl.Resources>
<converters:BoolToScaleXConverter x:Key="BoolToScaleXConverter" /> <conv:BoolToScaleXConverter x:Key="FlipConverter"/>
</UserControl.Resources> <conv:SeriesToColorConverter x:Key="SeriesToColorConverter"/>
</UserControl.Resources>
<!-- (optional) Flip-Transform beibehalten -->
<UserControl.RenderTransform>
<ScaleTransform
ScaleX="{Binding IsFlipped, Converter={StaticResource FlipConverter}}"
ScaleY="1"/>
</UserControl.RenderTransform>
<Border RenderTransformOrigin="0.5,0.5" <!-- 2) Border.Background an die Series binden -->
BorderBrush="Black" BorderThickness="1" CornerRadius="6" Margin="4" Background="{Binding Series, Converter={StaticResource SeriesToColor}}"> <Border CornerRadius="4" Padding="4"
Background="{Binding Series, Converter={StaticResource SeriesToColorConverter}}">
<Border.RenderTransform>
<ScaleTransform ScaleX="{Binding IsFlipped, RelativeSource={RelativeSource AncestorType=UserControl}, Converter={StaticResource BoolToScaleXConverter}}" />
</Border.RenderTransform>
<Grid> <Grid>
<Grid Name="Front" IsVisible="{Binding !IsFlipped, RelativeSource={RelativeSource AncestorType=UserControl}}"> <StackPanel>
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Spacing="4"> <TextBlock Text="{Binding AtomicNumber}"
<TextBlock Text="{Binding AtomicNumber}" FontSize="12" /> FontSize="10"
<TextBlock Text="{Binding Symbol}" FontSize="24" FontWeight="Bold" /> Foreground="White"
<TextBlock Text="{Binding ElementName}" FontSize="12" /> HorizontalAlignment="Right"/>
<TextBlock Text="{Binding Symbol}"
FontSize="24"
FontWeight="Bold"
Foreground="White"
HorizontalAlignment="Center"/>
<TextBlock Text="{Binding ElementName}"
FontSize="10"
Foreground="White"
HorizontalAlignment="Center"/>
</StackPanel> </StackPanel>
</Grid> </Grid>
</Border>
<Grid Name="Back" IsVisible="{Binding IsFlipped, RelativeSource={RelativeSource AncestorType=UserControl}}">
<StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Spacing="4">
<TextBlock Text="Masse: " FontSize="10"/>
<TextBlock Text="{Binding AtomicWeight}" FontSize="10" />
<TextBlock Text="EN: " FontSize="10"/>
<TextBlock Text="{Binding Electronegativity}" FontSize="10" />
<TextBlock Text="Dichte:" FontSize="10"/>
<TextBlock Text="{Binding Density}" FontSize="10" />
</StackPanel>
</Grid>
</Grid>
</Border>
</UserControl> </UserControl>

View File

@ -1,7 +1,8 @@
using Avalonia; using Avalonia;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Media; using Avalonia.Markup.Xaml;
using Avalonia.Styling;
namespace Project_Periodensystem.View.Components namespace Project_Periodensystem.View.Components
{ {
@ -19,9 +20,10 @@ namespace Project_Periodensystem.View.Components
public ElementTile() public ElementTile()
{ {
InitializeComponent(); InitializeComponent();
// Optional: Klick per Code registrieren
this.PointerPressed += (_, __) => IsFlipped = !IsFlipped; this.PointerPressed += (_, __) => IsFlipped = !IsFlipped;
} }
private void InitializeComponent()
=> AvaloniaXamlLoader.Load(this);
} }
} }

View File

@ -7,14 +7,8 @@ namespace Project_Periodensystem.View.Converters
public class BoolToScaleXConverter : IValueConverter public class BoolToScaleXConverter : IValueConverter
{ {
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{ => (value is bool b && b) ? -1 : 1;
bool flipped = value is bool b && b;
return flipped ? -1 : 1;
}
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{ => throw new NotSupportedException();
throw new NotSupportedException();
}
} }
} }

View File

@ -7,32 +7,18 @@ namespace Project_Periodensystem.View.Converters
public class RowToYConverter : IValueConverter public class RowToYConverter : IValueConverter
{ {
private const double TileHeight = 80; private const double TileHeight = 80;
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{ => (value is int r) ? r * TileHeight : 0;
if (value is int row) public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
return row * TileHeight; => throw new NotImplementedException();
return 0;
}
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) =>
throw new NotImplementedException();
} }
public class ColumnToXConverter : IValueConverter public class ColumnToXConverter : IValueConverter
{ {
private const double TileWidth = 80; private const double TileWidth = 80;
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture) public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{ => (value is int c) ? c * TileWidth : 0;
if (value is int column) public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
return column * TileWidth; => throw new NotImplementedException();
return 0;
}
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) =>
throw new NotImplementedException();
} }
} }

View File

@ -10,19 +10,20 @@ 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 is not string series)
return Brushes.Gray; return new SolidColorBrush(Color.Parse("#222222")); // nocategory
return series switch return series switch
{ {
"Nichtmetall" => Brushes.Green, "Nichtmetall" => new SolidColorBrush(Color.Parse("#3e6418")), // nonmetal
"Metall" => Brushes.DarkRed, "Metall" => new SolidColorBrush(Color.Parse("#711019")), // transition
"Halbmetall" => Brushes.Orange, "Halbmetall" => new SolidColorBrush(Color.Parse("#015146")), // metalloid
"Edelgas" => Brushes.MediumPurple, "Edelgas" => new SolidColorBrush(Color.Parse("#3a2151")), // noble
"Halogen" => Brushes.DeepPink, "Halogen" => new SolidColorBrush(Color.Parse("#846011")), // alkaline (kein halogen-stil da)
"Lanthanoid" => Brushes.Blue, "Lanthanoid" => new SolidColorBrush(Color.Parse("#402c17")),
"Actinoid" => Brushes.DarkBlue, "Actinoid" => new SolidColorBrush(Color.Parse("#732e4c")),
"Unbekannt" => Brushes.DimGray, "Alkalimetall" => new SolidColorBrush(Color.Parse("#6c3b01")), // alkali
_ => Brushes.Black "Erdalkalimetall" => new SolidColorBrush(Color.Parse("#846011")), // alkaline
_ => new SolidColorBrush(Color.Parse("#222222")), // fallback: nocategory
}; };
} }

View File

@ -1,25 +1,22 @@
<Window xmlns="https://github.com/avaloniaui" <Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Project_Periodensystem.View" xmlns:vm="clr-namespace:Project_Periodensystem.Controller;assembly=Project_Periodensystem.Controller"
xmlns:components="clr-namespace:Project_Periodensystem.View.Components" xmlns:components="clr-namespace:Project_Periodensystem.View.Components;assembly=Project_Periodensystem.View"
x:Class="Project_Periodensystem.View.MainWindow" x:Class="Project_Periodensystem.View.MainWindow"
Width="1600" Height="900" Background="White"> Title="Periodensystem"
Width="900" Height="650"
CanResize="True">
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"> <!-- DataContext auf den Controller setzen -->
<ItemsControl Items="{Binding Elements}"> <Window.DataContext>
<ItemsControl.ItemsPanel> <vm:PeriodensystemController />
<ItemsPanelTemplate> </Window.DataContext>
<Canvas Width="1800" Height="1000"/>
</ItemsPanelTemplate> <ScrollViewer HorizontalScrollBarVisibility="Auto"
</ItemsControl.ItemsPanel> VerticalScrollBarVisibility="Auto">
<ItemsControl.ItemTemplate> <!-- Canvas mit fester Größe: 18 Spalten × 80px = 1440px, 10 Zeilen × 80px = 800px -->
<DataTemplate> <Canvas x:Name="PeriodicCanvas"
<components:ElementTile Width="1440"
Canvas.Left="{Binding Column, Converter={StaticResource ColumnToXConverter}}" Height="800" />
Canvas.Top="{Binding Row, Converter={StaticResource RowToYConverter}}"
DataContext="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer> </ScrollViewer>
</Window> </Window>

View File

@ -1,26 +1,46 @@
// Importiert die Avalonia Controls, also Basisfunktionen wie Window, Button etc.
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Markup.Xaml;
// Importiert deinen eigenen Controller, der die Daten und Logik bereitstellt
using Project_Periodensystem.Controller; using Project_Periodensystem.Controller;
using Project_Periodensystem.View.Components;
namespace Project_Periodensystem.View // Namespace entspricht deinem Projektordner „View“ namespace Project_Periodensystem.View
{ {
// Diese Klasse ist die Code-Behind-Datei für MainWindow.xaml
// Sie erweitert Avalonia's Window-Klasse
public partial class MainWindow : Window public partial class MainWindow : Window
{ {
// Der Controller verwaltet die Daten und steuert das Verhalten (MVCP-Prinzip!) private readonly PeriodensystemController _controller;
private readonly PeriodensystemController? _controller;
// Konstruktor wird aufgerufen, wenn das Fenster erstellt wird
public MainWindow() public MainWindow()
{ {
InitializeComponent(); // Initialisiert die grafischen Komponenten aus XAML InitializeComponent();
_controller = new PeriodensystemController(); _controller = new PeriodensystemController();
DataContext = _controller; // <-- wichtig! DataContext = _controller;
// Das Fenster (und alles darin) bekommt den Controller als Datenquelle (Binding-Kontext) PopulateCanvas();
// Dadurch funktionieren z.B. Bindings wie {Binding Elements} in der XAML }
private void InitializeComponent()
=> AvaloniaXamlLoader.Load(this);
private void PopulateCanvas()
{
// Holt den Canvas aus dem XAML (muss existieren!)
var canvas = this.FindControl<Canvas>("PeriodicCanvas");
if (canvas == null)
return;
foreach (var element in _controller.Elements)
{
// Neues Tile für jedes Element
var tile = new ElementTile
{
DataContext = element
};
// Position setzen: Column × 80px, Row × 80px
Canvas.SetLeft(tile, element.Column * 80);
Canvas.SetTop(tile, element.Row * 80);
canvas.Children.Add(tile);
}
} }
} }
} }

View File

@ -1,21 +1,18 @@
using Avalonia; using System;
using System; using Avalonia;
namespace Project_Periodensystem.View; namespace Project_Periodensystem.View
class Program
{ {
// Initialization code. Don't use any Avalonia, third-party APIs or any class Program
// SynchronizationContext-reliant code before AppMain is called: things aren't initialized {
// yet and stuff might break.
[STAThread] [STAThread]
public static void Main(string[] args) => BuildAvaloniaApp() public static void Main(string[] args)
=> BuildAvaloniaApp()
.StartWithClassicDesktopLifetime(args); .StartWithClassicDesktopLifetime(args);
// Avalonia configuration, don't remove; also used by visual designer.
public static AppBuilder BuildAvaloniaApp() public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>() => AppBuilder.Configure<App>()
.UsePlatformDetect() .UsePlatformDetect()
.WithInterFont()
.LogToTrace(); .LogToTrace();
}
} }