299 lines
17 KiB
XML
299 lines
17 KiB
XML
<Window xmlns="https://github.com/avaloniaui"
|
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
|
xmlns:vm="using:GsaEditor.ViewModels"
|
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
|
xmlns:aedit="https://github.com/avaloniaui/avaloniaedit"
|
|
mc:Ignorable="d" d:DesignWidth="1100" d:DesignHeight="700"
|
|
x:Class="GsaEditor.Views.MainWindow"
|
|
x:CompileBindings="False"
|
|
Title="{Binding Title}"
|
|
Width="1100" Height="700"
|
|
MinWidth="800" MinHeight="500">
|
|
|
|
<Design.DataContext>
|
|
<vm:MainWindowViewModel/>
|
|
</Design.DataContext>
|
|
|
|
<DockPanel>
|
|
|
|
<!-- ============================================================ -->
|
|
<!-- Menu Bar -->
|
|
<!-- ============================================================ -->
|
|
<Menu DockPanel.Dock="Top">
|
|
<MenuItem Header="_File">
|
|
<MenuItem Header="_Open Archive..." Command="{Binding OpenArchiveCommand}"
|
|
InputGesture="Ctrl+O"/>
|
|
<MenuItem Header="_Save" Command="{Binding SaveCommand}"
|
|
InputGesture="Ctrl+S"
|
|
IsEnabled="{Binding HasArchive}"/>
|
|
<MenuItem Header="Save _As..." Command="{Binding SaveAsCommand}"
|
|
InputGesture="Ctrl+Shift+S"
|
|
IsEnabled="{Binding HasArchive}"/>
|
|
<Separator/>
|
|
<MenuItem Header="_Close" Command="{Binding CloseArchiveCommand}"
|
|
IsEnabled="{Binding HasArchive}"/>
|
|
<MenuItem Header="E_xit" Command="{Binding ExitCommand}"
|
|
InputGesture="Alt+F4"/>
|
|
</MenuItem>
|
|
<MenuItem Header="_Edit">
|
|
<MenuItem Header="_Add File(s)..." Command="{Binding AddFilesCommand}"
|
|
IsEnabled="{Binding HasArchive}"/>
|
|
<MenuItem Header="_Extract All..." Command="{Binding ExtractAllCommand}"
|
|
IsEnabled="{Binding HasArchive}"/>
|
|
<Separator/>
|
|
<MenuItem Header="_Repack" Command="{Binding RepackCommand}"
|
|
IsEnabled="{Binding HasArchive}"/>
|
|
</MenuItem>
|
|
<MenuItem Header="_About">
|
|
<MenuItem Header="About GsaEditor" Command="{Binding ShowAboutCommand}"/>
|
|
</MenuItem>
|
|
</Menu>
|
|
|
|
<!-- ============================================================ -->
|
|
<!-- Status Bar -->
|
|
<!-- ============================================================ -->
|
|
<Border DockPanel.Dock="Bottom" Padding="8,4"
|
|
BorderThickness="0,1,0,0" BorderBrush="#CCCCCC"
|
|
Background="#F5F5F5">
|
|
<Grid ColumnDefinitions="*,Auto,Auto">
|
|
<TextBlock Grid.Column="0" Text="{Binding StatusArchivePath}"
|
|
VerticalAlignment="Center" FontSize="12"
|
|
Foreground="#555555"/>
|
|
<TextBlock Grid.Column="1" Text="{Binding StatusEntryCount}"
|
|
VerticalAlignment="Center" FontSize="12"
|
|
Foreground="#555555" Margin="20,0,0,0"/>
|
|
<TextBlock Grid.Column="2" Text="{Binding StatusSizeInfo}"
|
|
VerticalAlignment="Center" FontSize="12"
|
|
Foreground="#555555" Margin="20,0,0,0"/>
|
|
</Grid>
|
|
</Border>
|
|
|
|
<!-- ============================================================ -->
|
|
<!-- Loading Overlay -->
|
|
<!-- ============================================================ -->
|
|
<Border IsVisible="{Binding IsLoading}" Background="#80000000"
|
|
ZIndex="100" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
|
<TextBlock Text="Loading..." FontSize="20"
|
|
Foreground="White"
|
|
HorizontalAlignment="Center"
|
|
VerticalAlignment="Center"/>
|
|
</Border>
|
|
|
|
<!-- ============================================================ -->
|
|
<!-- Main Content: Left Tree + Right Details -->
|
|
<!-- ============================================================ -->
|
|
<Grid ColumnDefinitions="300,5,*">
|
|
|
|
<!-- ======================================================== -->
|
|
<!-- Left Panel: Archive Tree -->
|
|
<!-- ======================================================== -->
|
|
<Border Grid.Column="0" BorderThickness="0,0,1,0" BorderBrush="#DDDDDD">
|
|
<DockPanel>
|
|
<TextBlock DockPanel.Dock="Top" Text="Archive Contents"
|
|
FontWeight="SemiBold" Padding="8,6" FontSize="13"
|
|
Background="#EEEEEE"/>
|
|
|
|
<!-- Search area -->
|
|
<StackPanel DockPanel.Dock="Top" Margin="6,6,6,0" Spacing="4"
|
|
IsEnabled="{Binding HasArchive}">
|
|
<TextBox Text="{Binding SearchQuery, Mode=TwoWay}"
|
|
Watermark="Search...">
|
|
<TextBox.KeyBindings>
|
|
<KeyBinding Gesture="Enter" Command="{Binding SearchCommand}"/>
|
|
</TextBox.KeyBindings>
|
|
</TextBox>
|
|
<DockPanel>
|
|
<Button DockPanel.Dock="Right" Content="Search"
|
|
Command="{Binding SearchCommand}"
|
|
FontSize="12" Padding="8,3"
|
|
IsVisible="{Binding SearchInContents}"/>
|
|
<CheckBox Content="In contents (regex)"
|
|
IsChecked="{Binding SearchInContents, Mode=TwoWay}"
|
|
FontSize="12"/>
|
|
</DockPanel>
|
|
<TextBlock Text="{Binding SearchStatus}"
|
|
FontSize="11" Foreground="#777777"
|
|
IsVisible="{Binding SearchStatus, Converter={x:Static StringConverters.IsNotNullOrEmpty}}"/>
|
|
</StackPanel>
|
|
|
|
<!-- Search results -->
|
|
<ListBox DockPanel.Dock="Top"
|
|
ItemsSource="{Binding SearchResults}"
|
|
SelectedItem="{Binding SelectedSearchResult, Mode=TwoWay}"
|
|
IsVisible="{Binding HasSearchResults}"
|
|
MaxHeight="220" Margin="6,4,6,4"
|
|
BorderThickness="1" BorderBrush="#DDDDDD">
|
|
<ListBox.ItemTemplate>
|
|
<DataTemplate>
|
|
<StackPanel Margin="0,1">
|
|
<TextBlock Text="{Binding Alias}" FontSize="12"
|
|
TextTrimming="CharacterEllipsis"/>
|
|
<TextBlock Text="{Binding Detail}" FontSize="11"
|
|
Foreground="#777777"
|
|
TextTrimming="CharacterEllipsis"
|
|
IsVisible="{Binding HasDetail}"/>
|
|
</StackPanel>
|
|
</DataTemplate>
|
|
</ListBox.ItemTemplate>
|
|
</ListBox>
|
|
|
|
<TreeView Name="ArchiveTree"
|
|
ItemsSource="{Binding TreeRoots}"
|
|
SelectionChanged="TreeView_SelectionChanged">
|
|
|
|
<TreeView.Styles>
|
|
<Style Selector="TreeViewItem">
|
|
<Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}"/>
|
|
</Style>
|
|
</TreeView.Styles>
|
|
|
|
<TreeView.ContextMenu>
|
|
<ContextMenu>
|
|
<!-- File node operations -->
|
|
<MenuItem Header="Extract" Command="{Binding ExtractEntryCommand}"
|
|
IsVisible="{Binding HasSelectedFile}"/>
|
|
<MenuItem Header="Replace" Command="{Binding ReplaceEntryCommand}"
|
|
IsVisible="{Binding HasSelectedFile}"/>
|
|
<MenuItem Header="Delete" Command="{Binding DeleteEntryCommand}"
|
|
IsVisible="{Binding HasSelectedFile}"/>
|
|
<MenuItem Header="Rename" Command="{Binding RenameEntryCommand}"
|
|
IsVisible="{Binding HasSelectedFile}"/>
|
|
<!-- Folder node operations -->
|
|
<MenuItem Header="Extract Folder" Command="{Binding ExtractFolderCommand}"
|
|
IsVisible="{Binding HasSelectedFolder}"/>
|
|
<!-- Always available -->
|
|
<Separator/>
|
|
<MenuItem Header="Add File(s)..." Command="{Binding AddFilesCommand}"
|
|
IsEnabled="{Binding HasArchive}"/>
|
|
</ContextMenu>
|
|
</TreeView.ContextMenu>
|
|
|
|
<TreeView.ItemTemplate>
|
|
<TreeDataTemplate ItemsSource="{Binding Children}">
|
|
<StackPanel Orientation="Horizontal" Spacing="5">
|
|
<TextBlock Text="📁" IsVisible="{Binding IsFolder}"/>
|
|
<TextBlock Text="📄" IsVisible="{Binding IsFile}"/>
|
|
<TextBlock Text="{Binding Name}"/>
|
|
</StackPanel>
|
|
</TreeDataTemplate>
|
|
</TreeView.ItemTemplate>
|
|
</TreeView>
|
|
</DockPanel>
|
|
</Border>
|
|
|
|
<!-- Splitter -->
|
|
<GridSplitter Grid.Column="1" ResizeDirection="Columns"
|
|
Background="#CCCCCC"/>
|
|
|
|
<!-- ======================================================== -->
|
|
<!-- Right Panel: Details & Preview -->
|
|
<!-- ======================================================== -->
|
|
<Grid Grid.Column="2" RowDefinitions="Auto,*">
|
|
|
|
<!-- ================================================== -->
|
|
<!-- Top Bar: Entry Info -->
|
|
<!-- ================================================== -->
|
|
<Border Grid.Row="0" Padding="10,8"
|
|
Background="#FAFAFA"
|
|
BorderThickness="0,0,0,1" BorderBrush="#DDDDDD"
|
|
IsVisible="{Binding HasSelectedEntry}">
|
|
<Grid RowDefinitions="Auto,Auto">
|
|
<!-- Row 0: Alias -->
|
|
<Grid Grid.Row="0" ColumnDefinitions="Auto,*" Margin="0,0,0,6">
|
|
<TextBlock Grid.Column="0" Text="Alias:"
|
|
VerticalAlignment="Center" Margin="0,0,8,0"
|
|
FontWeight="SemiBold"/>
|
|
<TextBox Grid.Column="1"
|
|
Text="{Binding SelectedEntry.Alias, Mode=TwoWay}"
|
|
Watermark="File path in archive"/>
|
|
</Grid>
|
|
|
|
<!-- Row 1: Size info + compression toggle -->
|
|
<StackPanel Grid.Row="1" Orientation="Horizontal" Spacing="20">
|
|
<StackPanel Orientation="Horizontal" Spacing="4">
|
|
<TextBlock Text="Size:" FontWeight="SemiBold" VerticalAlignment="Center"/>
|
|
<TextBlock Text="{Binding SelectedEntry.OriginalSizeText}" VerticalAlignment="Center"/>
|
|
</StackPanel>
|
|
<StackPanel Orientation="Horizontal" Spacing="4">
|
|
<TextBlock Text="Compressed:" FontWeight="SemiBold" VerticalAlignment="Center"/>
|
|
<TextBlock Text="{Binding SelectedEntry.CompressedSizeText}" VerticalAlignment="Center"/>
|
|
</StackPanel>
|
|
<StackPanel Orientation="Horizontal" Spacing="4">
|
|
<TextBlock Text="Ratio:" FontWeight="SemiBold" VerticalAlignment="Center"/>
|
|
<TextBlock Text="{Binding SelectedEntry.CompressionRatio}" VerticalAlignment="Center"/>
|
|
</StackPanel>
|
|
<CheckBox Content="Compressed"
|
|
IsChecked="{Binding SelectedEntry.IsCompressed, Mode=TwoWay}"
|
|
VerticalAlignment="Center"/>
|
|
</StackPanel>
|
|
</Grid>
|
|
</Border>
|
|
|
|
<!-- ================================================== -->
|
|
<!-- Content Area: Preview -->
|
|
<!-- ================================================== -->
|
|
<Panel Grid.Row="1">
|
|
<!-- No selection / No archive message -->
|
|
<TextBlock Text="Open a GSA archive and select a file to preview."
|
|
HorizontalAlignment="Center" VerticalAlignment="Center"
|
|
Foreground="#999999" FontSize="14"
|
|
IsVisible="{Binding !HasPreview}"/>
|
|
|
|
<!-- Text Preview -->
|
|
<DockPanel IsVisible="{Binding IsTextPreview}">
|
|
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal"
|
|
Spacing="5" Margin="10,6">
|
|
<Button Content="Edit" Command="{Binding StartEditCommand}"
|
|
IsVisible="{Binding !IsEditingText}"/>
|
|
<Button Content="Save" Command="{Binding SaveEditCommand}"
|
|
IsVisible="{Binding IsEditingText}"/>
|
|
<Button Content="Cancel" Command="{Binding CancelEditCommand}"
|
|
IsVisible="{Binding IsEditingText}"/>
|
|
</StackPanel>
|
|
<aedit:TextEditor Name="TextEditor"
|
|
IsReadOnly="{Binding !IsEditingText}"
|
|
FontFamily="Consolas, Courier New, monospace"
|
|
FontSize="13"
|
|
ShowLineNumbers="True"
|
|
Margin="10,0,10,10"/>
|
|
</DockPanel>
|
|
|
|
<!-- Image Preview -->
|
|
<ScrollViewer IsVisible="{Binding IsImagePreview}"
|
|
HorizontalScrollBarVisibility="Auto"
|
|
VerticalScrollBarVisibility="Auto">
|
|
<Image Source="{Binding PreviewImage}"
|
|
Stretch="Uniform"
|
|
MaxWidth="800" MaxHeight="600"
|
|
Margin="10"
|
|
HorizontalAlignment="Center"
|
|
VerticalAlignment="Center"/>
|
|
</ScrollViewer>
|
|
|
|
<!-- Hex Dump Preview -->
|
|
<DockPanel IsVisible="{Binding IsHexPreview}">
|
|
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal"
|
|
Spacing="5" Margin="10,6">
|
|
<Button Content="Edit as Text"
|
|
Command="{Binding OpenAsTextCommand}"
|
|
IsVisible="{Binding HasSelectedEntry}"/>
|
|
</StackPanel>
|
|
<TextBox Text="{Binding HexDumpText}"
|
|
IsReadOnly="True"
|
|
FontFamily="Consolas, Courier New, monospace"
|
|
FontSize="13"
|
|
AcceptsReturn="True"
|
|
TextWrapping="NoWrap"
|
|
Margin="10,0,10,10"/>
|
|
</DockPanel>
|
|
</Panel>
|
|
|
|
</Grid>
|
|
|
|
</Grid>
|
|
|
|
</DockPanel>
|
|
|
|
</Window>
|