GUI: Populate TreeView with CheckBox'd namespaces

This commit is contained in:
Katy Coe
2020-02-09 09:43:29 +01:00
parent 4aad710451
commit c039b77a80
2 changed files with 59 additions and 9 deletions

View File

@@ -3,9 +3,10 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Il2CppInspectorGUI"
xmlns:gif="https://github.com/XamlAnimatedGif/XamlAnimatedGif" xmlns:gif="https://github.com/XamlAnimatedGif/XamlAnimatedGif"
mc:Ignorable="d" mc:Ignorable="d"
Title="Il2CppInspector" Height="570" Width="900" Background="White"> Title="Il2CppInspector" Height="590" Width="970" Background="White">
<Window.Resources> <Window.Resources>
<!-- Our favourite colours --> <!-- Our favourite colours -->
<SolidColorBrush x:Key="MicrosoftBlue" Color="#00A2ED"/> <SolidColorBrush x:Key="MicrosoftBlue" Color="#00A2ED"/>
@@ -82,6 +83,11 @@
</TextBlock.Text> </TextBlock.Text>
</TextBlock> </TextBlock>
</DataTemplate> </DataTemplate>
<!-- Namespace checkbox tree items -->
<HierarchicalDataTemplate x:Key="NamespaceTreeItemTemplate" DataType="{x:Type local:CheckboxNode}" ItemsSource="{Binding Children}">
<CheckBox Focusable="False" IsChecked="{Binding IsChecked}" VerticalAlignment="Center" Content="{Binding Name}"/>
</HierarchicalDataTemplate>
</Window.Resources> </Window.Resources>
<!-- Window content --> <!-- Window content -->
@@ -101,7 +107,7 @@
<!-- List of images in the binary file --> <!-- List of images in the binary file -->
<Label DockPanel.Dock="Top" Foreground="{StaticResource WindowsBlue}" FontSize="18">Select image</Label> <Label DockPanel.Dock="Top" Foreground="{StaticResource WindowsBlue}" FontSize="18">Select image</Label>
<ListBox DockPanel.Dock="Top" Name="lstImages" ItemTemplate="{StaticResource ImageListTemplate}" Height="80"/> <ListBox DockPanel.Dock="Top" Name="lstImages" ItemTemplate="{StaticResource ImageListTemplate}" Height="80" SelectionChanged="LstImages_OnSelectionChanged"/>
<!-- Image details view --> <!-- Image details view -->
<Label DockPanel.Dock="Top" Foreground="{StaticResource WindowsBlue}" FontSize="18">Image information</Label> <Label DockPanel.Dock="Top" Foreground="{StaticResource WindowsBlue}" FontSize="18">Image information</Label>
@@ -182,10 +188,10 @@
<DockPanel DockPanel.Dock="Top"> <DockPanel DockPanel.Dock="Top">
<!-- List of namespaces to export --> <!-- List of namespaces to export -->
<StackPanel DockPanel.Dock="Right"> <DockPanel DockPanel.Dock="Right">
<Label Foreground="{StaticResource WindowsBlue}" FontSize="18">Namespaces</Label> <Label DockPanel.Dock="Top" Foreground="{StaticResource WindowsBlue}" FontSize="18">Namespaces</Label>
<TreeView DockPanel.Dock="Right" Width="200" Margin="5" MinHeight="60"></TreeView> <TreeView DockPanel.Dock="Bottom" Name="trvNamespaces" ItemTemplate="{StaticResource NamespaceTreeItemTemplate}" Width="220" Margin="5"></TreeView>
</StackPanel> </DockPanel>
<!-- Settings --> <!-- Settings -->
<StackPanel DockPanel.Dock="Left"> <StackPanel DockPanel.Dock="Left">
@@ -209,7 +215,7 @@
</StackPanel> </StackPanel>
</GroupBox> </GroupBox>
<CheckBox Margin="2">Suppress pointer, offset and index metadata comments</CheckBox> <CheckBox Margin="2">Suppress pointer, offset and index metadata comments</CheckBox>
<CheckBox Margin="2">Attempt to generate output that compiles</CheckBox> <CheckBox Margin="2">Attempt to generate code that compiles</CheckBox>
<CheckBox IsChecked="True" Margin="2">Place assembly-level attributes in separate files</CheckBox> <CheckBox IsChecked="True" Margin="2">Place assembly-level attributes in separate files</CheckBox>
<Separator Margin="5"/> <Separator Margin="5"/>
<RadioButton GroupName="grpOutputType" VerticalContentAlignment="Center" FontSize="18" Foreground="{StaticResource MicrosoftGreen}">Visual Studio solution</RadioButton> <RadioButton GroupName="grpOutputType" VerticalContentAlignment="Center" FontSize="18" Foreground="{StaticResource MicrosoftGreen}">Visual Studio solution</RadioButton>
@@ -226,6 +232,7 @@
</DockPanel> </DockPanel>
<Separator Margin="5"/> <Separator Margin="5"/>
<RadioButton GroupName="grpOutputType" VerticalContentAlignment="Center" FontSize="18" Foreground="{StaticResource MicrosoftGreen}">IDAPython script</RadioButton> <RadioButton GroupName="grpOutputType" VerticalContentAlignment="Center" FontSize="18" Foreground="{StaticResource MicrosoftGreen}">IDAPython script</RadioButton>
<TextBlock TextWrapping="WrapWithOverflow">No configuration required for IDA script output</TextBlock>
</StackPanel> </StackPanel>
</DockPanel> </DockPanel>
</DockPanel> </DockPanel>

View File

@@ -16,6 +16,7 @@ using System.Windows.Navigation;
using System.Windows.Shapes; using System.Windows.Shapes;
using Microsoft.Win32; using Microsoft.Win32;
using Il2CppInspector; using Il2CppInspector;
using Il2CppInspector.Reflection;
namespace Il2CppInspectorGUI namespace Il2CppInspectorGUI
{ {
@@ -86,6 +87,7 @@ namespace Il2CppInspectorGUI
rectModalLightBoxBackground.Visibility = Visibility.Hidden; rectModalLightBoxBackground.Visibility = Visibility.Hidden;
lstImages.ItemsSource = app.Il2CppModels; lstImages.ItemsSource = app.Il2CppModels;
lstImages.SelectedIndex = 0;
} }
else { else {
areaBusyIndicator.Visibility = Visibility.Hidden; areaBusyIndicator.Visibility = Visibility.Hidden;
@@ -98,13 +100,54 @@ namespace Il2CppInspectorGUI
/// <summary> /// <summary>
/// Reset binary and metadata files and start again /// Reset binary and metadata files and start again
/// </summary> /// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BtnBack_OnClick(object sender, RoutedEventArgs e) { private void BtnBack_OnClick(object sender, RoutedEventArgs e) {
rectModalLightBoxBackground.Visibility = Visibility.Visible; rectModalLightBoxBackground.Visibility = Visibility.Visible;
lstImages.ItemsSource = null; lstImages.ItemsSource = null;
btnSelectBinaryFile.Visibility = Visibility.Hidden; btnSelectBinaryFile.Visibility = Visibility.Hidden;
btnSelectMetadataFile.Visibility = Visibility.Visible; btnSelectMetadataFile.Visibility = Visibility.Visible;
} }
/// <summary>
/// User has selected an image
/// </summary>
private void LstImages_OnSelectionChanged(object sender, SelectionChangedEventArgs e) {
// Selection has been removed?
if (((ListBox) sender).SelectedItem == null) {
trvNamespaces.ItemsSource = null;
return;
}
// Get selected image
var model = (Il2CppModel) ((ListBox) sender).SelectedItem;
// Get namespaces
var namespaces = model.Assemblies.SelectMany(x => x.DefinedTypes).GroupBy(t => t.Namespace).Select(n => n.Key);
// Break namespaces down into a tree
var namespaceTree = deconstructNamespaces(namespaces);
// Populate TreeView with namespace hierarchy
trvNamespaces.ItemsSource = namespaceTree;
}
private IEnumerable<CheckboxNode> deconstructNamespaces(IEnumerable<string> input) {
if (!input.Any())
return null;
var rootAndChildren = input.Select(s => string.IsNullOrEmpty(s)? "<global namespace>" : s)
.GroupBy(n => n.IndexOf(".") != -1 ? n.Substring(0, n.IndexOf(".")) : n).OrderBy(g => g.Key);
return rootAndChildren.Select(i => new CheckboxNode {Name = i.Key, IsChecked = true, Children = deconstructNamespaces(
i.Where(s => s.IndexOf(".") != -1).Select(s => s.Substring(s.IndexOf(".") + 1))
)}).ToList();
}
}
// Replacement for TreeViewItem that includes checkbox state
internal class CheckboxNode
{
public string Name { get; set; }
public bool IsChecked { get; set; }
public IEnumerable<CheckboxNode> Children { get; set; }
} }
} }