204 lines
16 KiB
XML

<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:m="clr-namespace:XSDVisualiser.Models;assembly=XSDVisualiser.Core"
xmlns:conv="clr-namespace:XSDVisualiser.Desktop.Converters"
x:Class="XSDVisualiser.Desktop.MainWindow"
x:CompileBindings="False"
Title="XSD Visualiser" Width="1200" Height="800">
<Window.Resources>
<conv:CardinalityToLabelConverter x:Key="CardinalityToLabel"/>
<conv:OptionalToBorderBrushConverter x:Key="OptionalToBrush"/>
<conv:OptionalToThicknessConverter x:Key="OptionalToThickness"/>
<conv:CollectionHasItemsConverter x:Key="HasItems"/>
</Window.Resources>
<Grid RowDefinitions="Auto,*" Margin="12">
<!-- Header -->
<DockPanel LastChildFill="False">
<TextBlock Text="XSD Visualiser" FontSize="20" FontWeight="SemiBold" Margin="0,0,12,0" DockPanel.Dock="Left"/>
<Button Content="Open XSD and parse" x:Name="OpenBtn" Width="220"/>
</DockPanel>
<!-- Body: left tree | splitter | right details -->
<Grid Grid.Row="1" ColumnDefinitions="2*,Auto,*" RowDefinitions="*">
<!-- Left: Tree -->
<Border Background="{DynamicResource PanelBackgroundBrush}"
BorderBrush="{DynamicResource PanelBorderBrush}"
BorderThickness="1" CornerRadius="6" Margin="0,8,8,0">
<ScrollViewer>
<TreeView x:Name="SchemaTree" ItemsSource="{Binding RootElements}">
<TreeView.DataTemplates>
<TreeDataTemplate DataType="{x:Type m:SchemaNode}" ItemsSource="{Binding Children}">
<StackPanel>
<!-- Connector line from parent to this node (hidden for roots where ContentModel is null) -->
<Grid Margin="0,8,8,2" IsVisible="{Binding ContentModel, Converter={x:Static ObjectConverters.IsNotNull}}"
ColumnDefinitions="16,*">
<!-- leading small elbow -->
<Rectangle Grid.Column="0" Width="16" Height="2" Fill="{DynamicResource SeparatorBrush}" VerticalAlignment="Center"/>
<Grid Grid.Column="1">
<Rectangle Height="2" Fill="{DynamicResource SeparatorBrush}" VerticalAlignment="Center"/>
<TextBlock Text="{Binding Cardinality, Converter={StaticResource CardinalityToLabel}}"
Background="{DynamicResource BadgeBackgroundBrush}" Padding="6,0"
Foreground="{DynamicResource SubtleTextBrush}"
HorizontalAlignment="Center"/>
</Grid>
</Grid>
<!-- Node content -->
<Border CornerRadius="4"
BorderBrush="{Binding Cardinality, Converter={StaticResource OptionalToBrush}}"
BorderThickness="{Binding Cardinality, Converter={StaticResource OptionalToThickness}}"
Padding="8" Margin="0,0,8,6" Background="{DynamicResource PanelBackgroundBrush}">
<StackPanel Orientation="Vertical" Spacing="2">
<!-- Name on its own line, prominent -->
<TextBlock Text="{Binding Name}" FontWeight="SemiBold"/>
<!-- Path/Namespace on its own line -->
<TextBlock Text="{Binding Namespace, StringFormat=Namespace: {0}}"
Foreground="{DynamicResource SubtleTextBrush}"/>
<!-- Type info on its own line (TypeName with fallback to BuiltInType) -->
<StackPanel Orientation="Horizontal" Spacing="6">
<TextBlock Text="Type:" FontWeight="Medium"/>
<TextBlock Text="{Binding TypeName}"/>
<TextBlock Text="{Binding BuiltInType, StringFormat=({0})}"
Foreground="{DynamicResource MutedTextBrush}"/>
</StackPanel>
<!-- Optional: show content model as a subtle hint -->
<TextBlock Text="{Binding ContentModel, StringFormat=Model: {0}}"
Foreground="{DynamicResource SubtleTextBrush}" FontWeight="SemiBold"/>
</StackPanel>
</Border>
</StackPanel>
</TreeDataTemplate>
</TreeView.DataTemplates>
</TreeView>
</ScrollViewer>
</Border>
<!-- Splitter -->
<GridSplitter Grid.Column="1" Width="6" Margin="4,8" Background="{DynamicResource PanelBorderBrush}" ShowsPreview="True"/>
<!-- Right: Details -->
<Border Grid.Column="2" Background="{DynamicResource PanelBackgroundBrush}"
BorderBrush="{DynamicResource PanelBorderBrush}"
BorderThickness="1" CornerRadius="6" Margin="8,8,0,0">
<ScrollViewer>
<ContentControl Content="{Binding #SchemaTree.SelectedItem}">
<ContentControl.DataTemplates>
<DataTemplate DataType="{x:Type m:SchemaNode}">
<StackPanel Margin="12" Spacing="12">
<TextBlock Text="Details" FontSize="16" FontWeight="SemiBold"/>
<!-- General info -->
<Border BorderBrush="{DynamicResource PanelBorderBrush}" BorderThickness="1" CornerRadius="4" Padding="10">
<Grid ColumnDefinitions="Auto,*" RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,*">
<TextBlock Grid.Row="0" Grid.Column="0" Text="Name:" FontWeight="Bold"/>
<TextBlock Grid.Row="0" Grid.Column="1" Margin="8,0,0,0" Text="{Binding Name}"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="Built-in:" FontWeight="Bold"/>
<TextBlock Grid.Row="1" Grid.Column="1" Margin="8,0,0,0" Text="{Binding BuiltInType}" FontWeight="Bold"/>
<TextBlock Grid.Row="2" Grid.Column="0" Text="Model:" FontWeight="Bold"/>
<TextBlock Grid.Row="2" Grid.Column="1" Margin="8,0,0,0" Text="{Binding ContentModel}"/>
<TextBlock Grid.Row="3" Grid.Column="0" Text="Namespace:" FontWeight="Bold"/>
<TextBlock Grid.Row="3" Grid.Column="1" Margin="8,0,0,0" Text="{Binding Namespace}"/>
<TextBlock Grid.Row="4" Grid.Column="0" Text="Cardinality:" FontWeight="Bold"/>
<TextBlock Grid.Row="4" Grid.Column="1" Margin="8,0,0,0" Text="{Binding Cardinality, Converter={StaticResource CardinalityToLabel}}"/>
<TextBlock Grid.Row="5" Grid.Column="0" Text="Nillable:" FontWeight="Bold"/>
<TextBlock Grid.Row="5" Grid.Column="1" Margin="8,0,0,0" Text="{Binding IsNillable}"/>
<TextBlock Grid.Row="6" Grid.Column="0" Text="Type:" FontWeight="Bold"/>
<TextBlock Grid.Row="6" Grid.Column="1" Margin="8,0,0,0" Text="{Binding TypeName}"/>
</Grid>
</Border>
<!-- Constraints -->
<StackPanel>
<TextBlock Text="Constraints" FontWeight="SemiBold"/>
<ContentControl Content="{Binding Constraints}">
<ContentControl.DataTemplates>
<DataTemplate x:DataType="m:ConstraintSet">
<StackPanel Spacing="8">
<TextBlock Text="Base Type:" FontWeight="Bold"/>
<TextBlock Text="{Binding BaseTypeName}"/>
<StackPanel>
<TextBlock Text="Enumerations" FontWeight="SemiBold"/>
<ItemsControl ItemsSource="{Binding Enumerations}" IsVisible="{Binding Enumerations, Converter={StaticResource HasItems}}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="x:String">
<TextBlock Text="{Binding ., StringFormat=• {0}}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
<StackPanel>
<TextBlock Text="Patterns" FontWeight="SemiBold"/>
<ItemsControl ItemsSource="{Binding Patterns}" IsVisible="{Binding Patterns, Converter={StaticResource HasItems}}">
<ItemsControl.ItemTemplate>
<DataTemplate x:DataType="x:String">
<TextBlock Text="{Binding ., StringFormat=• {0}}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
<!-- Numeric bounds -->
<StackPanel IsVisible="{Binding Numeric, Converter={x:Static ObjectConverters.IsNotNull}}">
<TextBlock Text="Numeric bounds" FontWeight="SemiBold"/>
<StackPanel Orientation="Horizontal" IsVisible="{Binding Numeric.MinInclusive, Converter={x:Static ObjectConverters.IsNotNull}}">
<TextBlock Text="Min inclusive:" FontWeight="Bold"/>
<TextBlock Margin="8,0,0,0" Text="{Binding Numeric.MinInclusive}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" IsVisible="{Binding Numeric.MaxInclusive, Converter={x:Static ObjectConverters.IsNotNull}}">
<TextBlock Text="Max inclusive:" FontWeight="Bold"/>
<TextBlock Margin="8,0,0,0" Text="{Binding Numeric.MaxInclusive}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" IsVisible="{Binding Numeric.MinExclusive, Converter={x:Static ObjectConverters.IsNotNull}}">
<TextBlock Text="Min exclusive:" FontWeight="Bold"/>
<TextBlock Margin="8,0,0,0" Text="{Binding Numeric.MinExclusive}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" IsVisible="{Binding Numeric.MaxExclusive, Converter={x:Static ObjectConverters.IsNotNull}}">
<TextBlock Text="Max exclusive:" FontWeight="Bold"/>
<TextBlock Margin="8,0,0,0" Text="{Binding Numeric.MaxExclusive}"/>
</StackPanel>
</StackPanel>
<!-- Length bounds -->
<StackPanel IsVisible="{Binding Length, Converter={x:Static ObjectConverters.IsNotNull}}">
<TextBlock Text="Length bounds" FontWeight="SemiBold"/>
<StackPanel Orientation="Horizontal" IsVisible="{Binding Length.LengthSpecified}">
<TextBlock Text="Length:" FontWeight="Bold"/>
<TextBlock Margin="8,0,0,0" Text="{Binding Length.Length}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" IsVisible="{Binding Length.MinLengthSpecified}">
<TextBlock Text="Min length:" FontWeight="Bold"/>
<TextBlock Margin="8,0,0,0" Text="{Binding Length.MinLength}"/>
</StackPanel>
<StackPanel Orientation="Horizontal" IsVisible="{Binding Length.MaxLengthSpecified}">
<TextBlock Text="Max length:" FontWeight="Bold"/>
<TextBlock Margin="8,0,0,0" Text="{Binding Length.MaxLength}"/>
</StackPanel>
</StackPanel>
</StackPanel>
</DataTemplate>
</ContentControl.DataTemplates>
</ContentControl>
</StackPanel>
</StackPanel>
</DataTemplate>
</ContentControl.DataTemplates>
</ContentControl>
</ScrollViewer>
</Border>
</Grid>
</Grid>
</Window>