Browse Source

Merge pull request #1725 from icsharpcode/avalondock

Basic AvalonDock support without multiple tabs
pull/1726/head
Christoph Wille 6 years ago committed by GitHub
parent
commit
49dfc5a6af
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      ILSpy/Analyzers/AnalyzerTreeView.cs
  2. 2
      ILSpy/Analyzers/RemoveAnalyzeContextMenuEntry.cs
  3. 52
      ILSpy/Commands/DecompileInNewViewCommand.cs
  4. 14
      ILSpy/ContextMenuEntry.cs
  5. 76
      ILSpy/Controls/DockedPane.cs
  6. 2
      ILSpy/DebugSteps.xaml.cs
  7. 32
      ILSpy/Docking/DockingHelper.cs
  8. 9
      ILSpy/Docking/PanePosition.cs
  9. 5
      ILSpy/ILSpy.csproj
  10. 143
      ILSpy/MainWindow.xaml
  11. 143
      ILSpy/MainWindow.xaml.cs
  12. 9
      ILSpy/Properties/Resources.Designer.cs
  13. 3
      ILSpy/Properties/Resources.resx
  14. 2
      ILSpy/Search/SearchPane.cs
  15. 91
      ILSpy/themes/generic.xaml

2
ILSpy/Analyzers/AnalyzerTreeView.cs

@ -73,7 +73,7 @@ namespace ICSharpCode.ILSpy.Analyzers @@ -73,7 +73,7 @@ namespace ICSharpCode.ILSpy.Analyzers
public void Show()
{
if (!IsVisible)
MainWindow.Instance.ShowInBottomPane("Analyzer", this);
MainWindow.Instance.ShowInNewPane("Analyzer", this, PanePosition.Bottom);
}
public void Show(AnalyzerTreeNode node)

2
ILSpy/Analyzers/RemoveAnalyzeContextMenuEntry.cs

@ -20,7 +20,7 @@ using System.Linq; @@ -20,7 +20,7 @@ using System.Linq;
namespace ICSharpCode.ILSpy.Analyzers
{
[ExportContextMenuEntry(Header = "Remove", Icon = "images/Delete.png", Category = "Analyze", Order = 200)]
[ExportContextMenuEntry(Header = "Remove", Icon = "images/Delete", Category = "Analyze", Order = 200)]
internal sealed class RemoveAnalyzeContextMenuEntry : IContextMenuEntry
{
public bool IsVisible(TextViewContext context)

52
ILSpy/Commands/DecompileInNewViewCommand.cs

@ -0,0 +1,52 @@ @@ -0,0 +1,52 @@
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System.Linq;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.TreeNodes;
namespace ICSharpCode.ILSpy.Commands
{
// [ExportContextMenuEntry(Header = nameof(Resources.DecompileToNewPanel), Icon = "images/Search", Category = nameof(Resources.Analyze), Order = 90)]
internal sealed class DecompileInNewViewCommand : IContextMenuEntry
{
public bool IsVisible(TextViewContext context)
{
if (context.SelectedTreeNodes == null)
return false;
return true;
}
public bool IsEnabled(TextViewContext context)
{
if (context.SelectedTreeNodes == null)
return false;
return true;
}
public async void Execute(TextViewContext context)
{
var dtv = new DecompilerTextView();
var nodes = context.SelectedTreeNodes.Cast<ILSpyTreeNode>().ToArray();
var title = string.Join(", ", nodes.Select(x => x.ToString()));
MainWindow.Instance.ShowInNewPane(title, dtv, PanePosition.Document);
await dtv.DecompileAsync(MainWindow.Instance.CurrentLanguage, nodes, new DecompilationOptions());
}
}
}

14
ILSpy/ContextMenuEntry.cs

@ -222,15 +222,11 @@ namespace ICSharpCode.ILSpy @@ -222,15 +222,11 @@ namespace ICSharpCode.ILSpy
menuItem.Header = MainWindow.GetResourceString( entryPair.Metadata.Header);
menuItem.InputGestureText = entryPair.Metadata.InputGestureText;
if (!string.IsNullOrEmpty(entryPair.Metadata.Icon)) {
object image = Images.Load(entryPair.Value, entryPair.Metadata.Icon);
if (!(image is Viewbox)) {
image = new Image {
Width = 16,
Height = 16,
Source = (ImageSource)image
};
}
menuItem.Icon = image;
menuItem.Icon = new Image {
Width = 16,
Height = 16,
Source = Images.Load(entryPair.Value, entryPair.Metadata.Icon)
};
}
if (entryPair.Value.IsEnabled(context)) {
menuItem.Click += delegate { entry.Execute(context); };

76
ILSpy/Controls/DockedPane.cs

@ -1,76 +0,0 @@ @@ -1,76 +0,0 @@
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace ICSharpCode.ILSpy.Controls
{
class DockedPane : Control
{
static DockedPane()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(DockedPane), new FrameworkPropertyMetadata(typeof(DockedPane)));
}
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title", typeof(string), typeof(DockedPane));
public string Title {
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
public static readonly DependencyProperty ContentProperty =
DependencyProperty.Register("Content", typeof(object), typeof(DockedPane));
public object Content {
get { return GetValue(ContentProperty); }
set { SetValue(ContentProperty, value); }
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
Button closeButton = (Button)this.Template.FindName("PART_Close", this);
if (closeButton != null) {
closeButton.Click += closeButton_Click;
}
}
void closeButton_Click(object sender, RoutedEventArgs e)
{
if (CloseButtonClicked != null)
CloseButtonClicked(this, e);
}
public event EventHandler CloseButtonClicked;
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (e.Key == Key.F4 && e.KeyboardDevice.Modifiers == ModifierKeys.Control || e.Key == Key.Escape) {
if (CloseButtonClicked != null)
CloseButtonClicked(this, e);
e.Handled = true;
}
}
}
}

2
ILSpy/DebugSteps.xaml.cs

@ -79,7 +79,7 @@ namespace ICSharpCode.ILSpy @@ -79,7 +79,7 @@ namespace ICSharpCode.ILSpy
public static void Show()
{
MainWindow.Instance.ShowInTopPane(Properties.Resources.DebugSteps, new DebugSteps());
MainWindow.Instance.ShowInNewPane(Properties.Resources.DebugSteps, new DebugSteps(), PanePosition.Top);
}
void IPane.Closed()

32
ILSpy/Docking/DockingHelper.cs

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
using System.Windows;
using System.Windows.Controls;
using Xceed.Wpf.AvalonDock.Layout;
namespace ICSharpCode.ILSpy.Docking
{
public static class DockingHelper
{
public static void DockHorizontal(LayoutContent layoutContent, ILayoutElement paneRelativeTo, GridLength dockHeight, bool dockBefore = false)
{
if (paneRelativeTo is ILayoutDocumentPane parentDocumentPane) {
var parentDocumentGroup = paneRelativeTo.FindParent<LayoutDocumentPaneGroup>();
if (parentDocumentGroup == null) {
var grandParent = parentDocumentPane.Parent as ILayoutContainer;
parentDocumentGroup = new LayoutDocumentPaneGroup() { Orientation = System.Windows.Controls.Orientation.Vertical };
grandParent.ReplaceChild(paneRelativeTo, parentDocumentGroup);
parentDocumentGroup.Children.Add(parentDocumentPane);
}
parentDocumentGroup.Orientation = System.Windows.Controls.Orientation.Vertical;
int indexOfParentPane = parentDocumentGroup.IndexOfChild(parentDocumentPane);
var layoutDocumentPane = new LayoutDocumentPane(layoutContent) { DockHeight = dockHeight };
parentDocumentGroup.InsertChildAt(dockBefore ? indexOfParentPane : indexOfParentPane + 1, layoutDocumentPane);
layoutContent.IsActive = true;
layoutContent.Root.CollectGarbage();
Application.Current.MainWindow.Dispatcher.Invoke(() => {
layoutDocumentPane.DockHeight = dockHeight;
}, System.Windows.Threading.DispatcherPriority.Loaded);
}
}
}
}

9
ILSpy/Docking/PanePosition.cs

@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
namespace ICSharpCode.ILSpy
{
public enum PanePosition
{
Top,
Bottom,
Document
}
}

5
ILSpy/ILSpy.csproj

@ -49,6 +49,7 @@ @@ -49,6 +49,7 @@
<ItemGroup>
<PackageReference Include="AvalonEdit" Version="6.0.0" />
<PackageReference Include="Dirkster.AvalonDock" Version="3.5.12" />
<PackageReference Include="Microsoft.VisualStudio.Composition" Version="15.5.23" />
<PackageReference Include="Mono.Cecil" Version="0.10.3" />
<PackageReference Include="OSVersionHelper" Version="1.0.11" />
@ -99,6 +100,7 @@ @@ -99,6 +100,7 @@
<Compile Include="AssemblyListManager.cs" />
<Compile Include="AvalonEdit\ITextMarker.cs" />
<Compile Include="AvalonEdit\TextMarkerService.cs" />
<Compile Include="Commands\DecompileInNewViewCommand.cs" />
<Compile Include="Commands\CheckForUpdatesCommand.cs" />
<Compile Include="Commands\BrowseBackCommand.cs" />
<Compile Include="Commands\BrowseForwardCommand.cs" />
@ -122,7 +124,6 @@ @@ -122,7 +124,6 @@
<Compile Include="Controls\ResourceObjectTable.xaml.cs">
<DependentUpon>ResourceObjectTable.xaml</DependentUpon>
</Compile>
<Compile Include="Controls\DockedPane.cs" />
<Compile Include="Commands\DecompileAllCommand.cs" />
<Compile Include="Commands\ExportCommandAttribute.cs" />
<Compile Include="Controls\ExtensionMethods.cs" />
@ -136,6 +137,7 @@ @@ -136,6 +137,7 @@
<Compile Include="DebugSteps.xaml.cs">
<DependentUpon>DebugSteps.xaml</DependentUpon>
</Compile>
<Compile Include="Docking\DockingHelper.cs" />
<Compile Include="ILSpyTraceListener.cs" />
<Compile Include="DecompilationOptions.cs" />
<Compile Include="ExtensionMethods.cs" />
@ -162,6 +164,7 @@ @@ -162,6 +164,7 @@
<Compile Include="Languages\Language.cs" />
<Compile Include="Languages\Languages.cs" />
<Compile Include="Options\DecompilerSettingsPanel.xaml.cs" />
<Compile Include="Docking\PanePosition.cs" />
<Compile Include="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>

143
ILSpy/MainWindow.xaml

@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
x:ClassModifier="public"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:tv="clr-namespace:ICSharpCode.TreeView;assembly=ICSharpCode.TreeView"
xmlns:local="clr-namespace:ICSharpCode.ILSpy"
xmlns:textView="clr-namespace:ICSharpCode.ILSpy.TextView"
xmlns:avalondock="http://schemas.xceed.com/wpf/xaml/avalondock"
xmlns:controls="clr-namespace:ICSharpCode.ILSpy.Controls"
xmlns:properties="clr-namespace:ICSharpCode.ILSpy.Properties"
Title="ILSpy"
@ -51,7 +51,8 @@ @@ -51,7 +51,8 @@
<DockPanel>
<!-- Main menu -->
<Menu DockPanel.Dock="Top" Name="mainMenu" Height="23" KeyboardNavigation.TabNavigation="None">
<MenuItem Header="{x:Static properties:Resources._File}" /> <!-- contents of file menu are added using MEF -->
<MenuItem Header="{x:Static properties:Resources._File}" />
<!-- contents of file menu are added using MEF -->
<MenuItem Header="{x:Static properties:Resources._View}">
<MenuItem Header="{x:Static properties:Resources.Show_publiconlyTypesMembers}" IsCheckable="True" IsChecked="{Binding FilterSettings.ApiVisPublicOnly}" />
<MenuItem Header="{x:Static properties:Resources.Show_internalTypesMembers}" IsCheckable="True" IsChecked="{Binding FilterSettings.ApiVisPublicAndInternal}" />
@ -96,6 +97,15 @@ @@ -96,6 +97,15 @@
ItemsSource="{Binding SelectedItem.LanguageVersions, ElementName=languageComboBox, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding FilterSettings.LanguageVersion, UpdateSourceTrigger=PropertyChanged}"/>
</ToolBar>
<Border DockPanel.Dock="Top" BorderBrush="Black" BorderThickness="1" Name="updatePanel" Visibility="Collapsed">
<DockPanel KeyboardNavigation.TabNavigation="Contained">
<Button DockPanel.Dock="Right" Click="updatePanelCloseButtonClick" MinWidth="0">X</Button>
<StackPanel Orientation="Horizontal">
<TextBlock Name="updatePanelMessage" Margin="4,0" VerticalAlignment="Center" Text="{x:Static properties:Resources.ILSpyVersionAvailable}" />
<Button Name="downloadOrCheckUpdateButton" Click="downloadOrCheckUpdateButtonClick" Content="{x:Static properties:Resources.Download}"/>
</StackPanel>
</DockPanel>
</Border>
<!-- Status bar -->
<StatusBar x:Name="statusBar" DockPanel.Dock="Bottom" Height="26" Visibility="Collapsed">
<StatusBarItem DockPanel.Dock="Right">
@ -107,99 +117,40 @@ @@ -107,99 +117,40 @@
</StatusBarItem>
</StatusBar>
<!-- Main grid separating left pane (treeView) from main pane (textEditor) -->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition
Name="leftColumn"
MinWidth="100"
Width="0.4*" />
<ColumnDefinition
Width="3" />
<ColumnDefinition
Name="rightColumn"
MinWidth="100"
Width="0.6*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition
Height="*" />
</Grid.RowDefinitions>
<!-- Left pane: Tree View of assemblies and classes -->
<tv:SharpTreeView
Name="treeView"
AutomationProperties.Name="Assemblies and Classes"
SelectionChanged="TreeView_SelectionChanged"
ShowRoot="False"
AllowDropOrder="True"
AllowDrop="True"
BorderThickness="0,1,1,1" Visibility="Visible" />
<GridSplitter
Grid.ZIndex="1"
Grid.Column="1"
Margin="-5,0"
BorderThickness="5,0"
HorizontalAlignment="Center"
VerticalAlignment="Stretch"
Focusable="False"
BorderBrush="Transparent" />
<!-- Right pane: Text Editor -->
<Grid Grid.Column="2">
<Grid.ColumnDefinitions>
<ColumnDefinition
Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="0" Name="topPaneRow" />
<RowDefinition Height="0" />
<RowDefinition Height="0.7*" MinHeight="100" Name="textViewRow" />
<RowDefinition Height="0" />
<RowDefinition Height="0" Name="bottomPaneRow" />
</Grid.RowDefinitions>
<Border BorderBrush="Black" BorderThickness="1" Name="updatePanel" Visibility="Collapsed">
<DockPanel KeyboardNavigation.TabNavigation="Contained">
<Button DockPanel.Dock="Right" Click="updatePanelCloseButtonClick" MinWidth="0">X</Button>
<StackPanel Orientation="Horizontal">
<TextBlock Name="updatePanelMessage" Margin="4,0" VerticalAlignment="Center" Text="{x:Static properties:Resources.ILSpyVersionAvailable}" />
<Button Name="downloadOrCheckUpdateButton" Click="downloadOrCheckUpdateButtonClick" Content="{x:Static properties:Resources.Download}"/>
</StackPanel>
</DockPanel>
</Border>
<controls:DockedPane x:Name="topPane" Grid.Row="1" Title="Top" Visibility="Collapsed"
AutomationProperties.Name="Close top pane"
CloseButtonClicked="TopPane_CloseButtonClicked" Margin="0,0,0,3"
BorderThickness="1,1,0,1" />
<GridSplitter
Grid.ZIndex="1"
Grid.Row="2"
Margin="0,-2,0,-5"
BorderThickness="0,2,0,5"
BorderBrush="Transparent"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Focusable="False"
Visibility="{Binding Visibility, ElementName=topPane}" />
<!-- decompilerTextView is into the mainPane by code -->
<ContentPresenter Name="mainPane" Grid.Row="3"/>
<GridSplitter
Grid.ZIndex="1"
Grid.Row="4"
Margin="0,-2,0,-5"
BorderThickness="0,2,0,5"
BorderBrush="Transparent"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Focusable="False"
Visibility="{Binding Visibility, ElementName=bottomPane}" />
<controls:DockedPane x:Name="bottomPane" Grid.Row="5" Title="Bottom" Visibility="Collapsed"
AutomationProperties.Name="Close"
CloseButtonClicked="BottomPane_CloseButtonClicked" Margin="0,3,0,0" BorderThickness="1,1,0,1"/>
</Grid>
</Grid>
<avalondock:DockingManager x:Name="DockManager"
AllowMixedOrientation="True" Grid.ColumnSpan="2">
<avalondock:LayoutRoot x:Name="LayoutRoot" >
<avalondock:LayoutPanel Orientation="Vertical">
<avalondock:LayoutPanel Orientation="Horizontal">
<avalondock:LayoutAnchorablePaneGroup DockWidth="200" Orientation="Vertical">
<avalondock:LayoutAnchorablePane DockHeight="*">
<avalondock:LayoutAnchorable x:Name="Tree" Title="Project Explorer" CanHide="False" CanClose="False">
<!-- Left pane: Tree View of assemblies and classes -->
<tv:SharpTreeView
Name="treeView"
AutomationProperties.Name="Assemblies and Classes"
SelectionChanged="TreeView_SelectionChanged"
ShowRoot="False"
AllowDropOrder="True"
AllowDrop="True"
BorderThickness="0,1,1,1" Visibility="Visible" />
</avalondock:LayoutAnchorable>
</avalondock:LayoutAnchorablePane>
</avalondock:LayoutAnchorablePaneGroup>
<avalondock:LayoutDocumentPaneGroup DockWidth="*">
<avalondock:LayoutDocumentPane x:Name="adDocumentPane">
<avalondock:LayoutDocument Title="MAIN" CanClose="False">
<!-- decompilerTextView is into the mainPane by code -->
<ContentPresenter Name="mainPane" />
</avalondock:LayoutDocument>
</avalondock:LayoutDocumentPane>
</avalondock:LayoutDocumentPaneGroup>
</avalondock:LayoutPanel>
</avalondock:LayoutPanel>
</avalondock:LayoutRoot>
</avalondock:DockingManager>
</DockPanel>
</Window>

143
ILSpy/MainWindow.xaml.cs

@ -44,6 +44,7 @@ using ICSharpCode.ILSpy.TreeNodes; @@ -44,6 +44,7 @@ using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.TreeView;
using Microsoft.Win32;
using OSVersionHelper;
using Xceed.Wpf.AvalonDock.Layout;
namespace ICSharpCode.ILSpy
{
@ -90,10 +91,11 @@ namespace ICSharpCode.ILSpy @@ -90,10 +91,11 @@ namespace ICSharpCode.ILSpy
decompilerTextView = App.ExportProvider.GetExportedValue<DecompilerTextView>();
mainPane.Content = decompilerTextView;
if (sessionSettings.SplitterPosition > 0 && sessionSettings.SplitterPosition < 1) {
leftColumn.Width = new GridLength(sessionSettings.SplitterPosition, GridUnitType.Star);
rightColumn.Width = new GridLength(1 - sessionSettings.SplitterPosition, GridUnitType.Star);
}
//todo
//if (sessionSettings.SplitterPosition > 0 && sessionSettings.SplitterPosition < 1) {
// leftColumn.Width = new GridLength(sessionSettings.SplitterPosition, GridUnitType.Star);
// rightColumn.Width = new GridLength(1 - sessionSettings.SplitterPosition, GridUnitType.Star);
//}
sessionSettings.FilterSettings.PropertyChanged += filterSettings_PropertyChanged;
InitMainMenu();
@ -140,19 +142,15 @@ namespace ICSharpCode.ILSpy @@ -140,19 +142,15 @@ namespace ICSharpCode.ILSpy
Button MakeToolbarItem(Lazy<ICommand, IToolbarCommandMetadata> command)
{
object image = Images.Load(command.Value, command.Metadata.ToolbarIcon);
if (!(image is Viewbox)) {
image = new Image {
Width = 16,
Height = 16,
Source = (ImageSource)image
};
}
return new Button {
Command = CommandWrapper.Unwrap(command.Value),
ToolTip = Properties.Resources.ResourceManager.GetString(command.Metadata.ToolTip),
Tag = command.Metadata.Tag,
Content = image
Content = new Image {
Width = 16,
Height = 16,
Source = Images.Load(command.Value, command.Metadata.ToolbarIcon)
}
};
}
#endregion
@ -178,15 +176,11 @@ namespace ICSharpCode.ILSpy @@ -178,15 +176,11 @@ namespace ICSharpCode.ILSpy
if (!string.IsNullOrEmpty(GetResourceString(entry.Metadata.Header)))
menuItem.Header = GetResourceString(entry.Metadata.Header);
if (!string.IsNullOrEmpty(entry.Metadata.MenuIcon)) {
object image = Images.Load(entry.Value, entry.Metadata.MenuIcon);
if (!(image is Viewbox)) {
image = new Image {
Width = 16,
Height = 16,
Source = (ImageSource)image
};
}
menuItem.Icon = image;
menuItem.Icon = new Image {
Width = 16,
Height = 16,
Source = Images.Load(entry.Value, entry.Metadata.MenuIcon)
};
}
menuItem.IsEnabled = entry.Metadata.IsEnabled;
@ -1022,11 +1016,12 @@ namespace ICSharpCode.ILSpy @@ -1022,11 +1016,12 @@ namespace ICSharpCode.ILSpy
sessionSettings.ActiveTreeViewPath = GetPathForNode(treeView.SelectedItem as SharpTreeNode);
sessionSettings.ActiveAutoLoadedAssembly = GetAutoLoadedAssemblyNode(treeView.SelectedItem as SharpTreeNode);
sessionSettings.WindowBounds = this.RestoreBounds;
sessionSettings.SplitterPosition = leftColumn.Width.Value / (leftColumn.Width.Value + rightColumn.Width.Value);
if (topPane.Visibility == Visibility.Visible)
sessionSettings.TopPaneSplitterPosition = topPaneRow.Height.Value / (topPaneRow.Height.Value + textViewRow.Height.Value);
if (bottomPane.Visibility == Visibility.Visible)
sessionSettings.BottomPaneSplitterPosition = bottomPaneRow.Height.Value / (bottomPaneRow.Height.Value + textViewRow.Height.Value);
//todo
//sessionSettings.SplitterPosition = leftColumn.Width.Value / (leftColumn.Width.Value + rightColumn.Width.Value);
//if (topPane.Visibility == Visibility.Visible)
// sessionSettings.TopPaneSplitterPosition = topPaneRow.Height.Value / (topPaneRow.Height.Value + textViewRow.Height.Value);
//if (bottomPane.Visibility == Visibility.Visible)
// sessionSettings.BottomPaneSplitterPosition = bottomPaneRow.Height.Value / (bottomPaneRow.Height.Value + textViewRow.Height.Value);
sessionSettings.Save();
}
@ -1048,95 +1043,19 @@ namespace ICSharpCode.ILSpy @@ -1048,95 +1043,19 @@ namespace ICSharpCode.ILSpy
#region Top/Bottom Pane management
/// <summary>
/// When grid is resized using splitter, row height value could become greater than 1.
/// As result, when a new pane is shown, both textView and pane could become very small.
/// This method normalizes two rows and ensures that height is less then 1.
/// </summary>
void NormalizePaneRowHeightValues(RowDefinition pane1Row, RowDefinition pane2Row)
{
var pane1Height = pane1Row.Height;
var pane2Height = pane2Row.Height;
//only star height values are normalized.
if (!pane1Height.IsStar || !pane2Height.IsStar) {
return;
}
var totalHeight = pane1Height.Value + pane2Height.Value;
if (totalHeight == 0) {
return;
}
pane1Row.Height = new GridLength(pane1Height.Value / totalHeight, GridUnitType.Star);
pane2Row.Height = new GridLength(pane2Height.Value / totalHeight, GridUnitType.Star);
}
public void ShowInTopPane(string title, object content)
{
topPaneRow.MinHeight = 100;
if (sessionSettings.TopPaneSplitterPosition > 0 && sessionSettings.TopPaneSplitterPosition < 1) {
//Ensure all 3 blocks are in fair conditions
NormalizePaneRowHeightValues(bottomPaneRow, textViewRow);
textViewRow.Height = new GridLength(1 - sessionSettings.TopPaneSplitterPosition, GridUnitType.Star);
topPaneRow.Height = new GridLength(sessionSettings.TopPaneSplitterPosition, GridUnitType.Star);
}
topPane.Title = title;
if (topPane.Content != content) {
IPane pane = topPane.Content as IPane;
if (pane != null)
pane.Closed();
topPane.Content = content;
}
topPane.Visibility = Visibility.Visible;
}
void TopPane_CloseButtonClicked(object sender, EventArgs e)
{
sessionSettings.TopPaneSplitterPosition = topPaneRow.Height.Value / (topPaneRow.Height.Value + textViewRow.Height.Value);
topPaneRow.MinHeight = 0;
topPaneRow.Height = new GridLength(0);
topPane.Visibility = Visibility.Collapsed;
IPane pane = topPane.Content as IPane;
topPane.Content = null;
if (pane != null)
pane.Closed();
}
public void ShowInBottomPane(string title, object content)
public void ShowInNewPane(string title, object content, PanePosition panePosition, string toolTip = null)
{
bottomPaneRow.MinHeight = 100;
if (sessionSettings.BottomPaneSplitterPosition > 0 && sessionSettings.BottomPaneSplitterPosition < 1) {
//Ensure all 3 blocks are in fair conditions
NormalizePaneRowHeightValues(topPaneRow, textViewRow);
textViewRow.Height = new GridLength(1 - sessionSettings.BottomPaneSplitterPosition, GridUnitType.Star);
bottomPaneRow.Height = new GridLength(sessionSettings.BottomPaneSplitterPosition, GridUnitType.Star);
}
bottomPane.Title = title;
if (bottomPane.Content != content) {
IPane pane = bottomPane.Content as IPane;
if (pane != null)
pane.Closed();
bottomPane.Content = content;
if (panePosition == PanePosition.Document) {
var layoutDocument = new LayoutDocument() { Title = title, Content = content, ToolTip = toolTip, CanClose = true };
var documentPane = this.DockManager.Layout.Descendents().OfType<LayoutDocumentPane>().FirstOrDefault();
documentPane.Children.Add(layoutDocument);
} else {
var layoutAnchorable = new LayoutAnchorable() { Title = title, Content = content, ToolTip = toolTip, CanClose = true, CanHide = true };
var documentPane = this.DockManager.Layout.Descendents().OfType<LayoutDocumentPane>().FirstOrDefault();
Docking.DockingHelper.DockHorizontal(layoutAnchorable, documentPane, new GridLength(200), panePosition == PanePosition.Top);
}
bottomPane.Visibility = Visibility.Visible;
}
void BottomPane_CloseButtonClicked(object sender, EventArgs e)
{
sessionSettings.BottomPaneSplitterPosition = bottomPaneRow.Height.Value / (bottomPaneRow.Height.Value + textViewRow.Height.Value);
bottomPaneRow.MinHeight = 0;
bottomPaneRow.Height = new GridLength(0);
bottomPane.Visibility = Visibility.Collapsed;
IPane pane = bottomPane.Content as IPane;
bottomPane.Content = null;
if (pane != null)
pane.Closed();
}
#endregion
public void UnselectAll()

9
ILSpy/Properties/Resources.Designer.cs generated

@ -1008,6 +1008,15 @@ namespace ICSharpCode.ILSpy.Properties { @@ -1008,6 +1008,15 @@ namespace ICSharpCode.ILSpy.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Decompile to new tab.
/// </summary>
public static string DecompileToNewPanel {
get {
return ResourceManager.GetString("DecompileToNewPanel", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Decompiling....
/// </summary>

3
ILSpy/Properties/Resources.resx

@ -766,4 +766,7 @@ Are you sure you want to continue?</value> @@ -766,4 +766,7 @@ Are you sure you want to continue?</value>
<data name="Assembly" xml:space="preserve">
<value>Assembly</value>
</data>
<data name="DecompileToNewPanel" xml:space="preserve">
<value>Decompile to new tab</value>
</data>
</root>

2
ILSpy/Search/SearchPane.cs

@ -112,7 +112,7 @@ namespace ICSharpCode.ILSpy @@ -112,7 +112,7 @@ namespace ICSharpCode.ILSpy
public void Show()
{
if (!IsVisible) {
MainWindow.Instance.ShowInTopPane(Properties.Resources.SearchPane_Search, this);
MainWindow.Instance.ShowInNewPane(Properties.Resources.SearchPane_Search, this, PanePosition.Top);
if (runSearchOnNextShow) {
runSearchOnNextShow = false;
StartSearch(this.SearchTerm);

91
ILSpy/themes/generic.xaml

@ -10,7 +10,7 @@ @@ -10,7 +10,7 @@
Displays an up arrow or down arrow in the column header when the grid is sorted using that column.
-->
<controls:ColumnSortDirectionToVisibilityConverter x:Key="ColumnSortDirectionToVisibilityConverter"/>
<DataTemplate x:Key="{ComponentResourceKey {x:Type controls:SortableGridViewColumn}, ColumnHeaderTemplate}">
<StackPanel Orientation="Horizontal">
<TextBlock HorizontalAlignment="Center" Text="{Binding}"/>
@ -26,93 +26,4 @@ @@ -26,93 +26,4 @@
Data = "M 5,5 L 10,10 L 15,5 L 5,5"/>
</StackPanel>
</DataTemplate>
<SolidColorBrush x:Key="paneBorder" Color="#828790" />
<!-- DockedPane -->
<Style TargetType="{x:Type controls:DockedPane}">
<Style.Resources>
<Style x:Key="CloseButtonStyle" TargetType="{x:Type Button}">
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="{controls:ControlColor 243}" Offset="0"/>
<GradientStop Color="{controls:ControlColor 235}" Offset="0.5"/>
<GradientStop Color="{controls:ControlColor 221}" Offset="0.5"/>
<GradientStop Color="{controls:ControlColor 205}" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush">
<Setter.Value>
<SolidColorBrush Color="{controls:ControlColor 150}"/>
</Setter.Value>
</Setter>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Padding" Value="4"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Border SnapsToDevicePixels="true" x:Name="buttonBorder" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2" />
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" TargetName="buttonBorder">
<Setter.Value>
<LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="{controls:ControlColor 250, Highlight=0.3}" Offset="0"/>
<GradientStop Color="{controls:ControlColor 224, Highlight=0.4}" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" TargetName="buttonBorder">
<Setter.Value>
<LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="{controls:ControlColor 224}" Offset="0"/>
<GradientStop Color="{controls:ControlColor 248}" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Style.Resources>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type controls:DockedPane}">
<Border BorderThickness="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=BorderThickness}" BorderBrush="{StaticResource paneBorder}">
<DockPanel>
<Border BorderThickness="0,0,0,0" BorderBrush="{StaticResource paneBorder}"
Background="{DynamicResource {x:Static SystemColors.InactiveCaptionBrushKey}}" DockPanel.Dock="Top">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Text="{TemplateBinding Title}" Margin="3,0"
Foreground="{DynamicResource {x:Static SystemColors.InactiveCaptionTextBrushKey}}" VerticalAlignment="Center"/>
<Button x:Name="PART_Close" Grid.Column="2" VerticalAlignment="Center" Width="16" Height="16" DockPanel.Dock="Right" Style="{DynamicResource CloseButtonStyle}" ToolTip="Close" Margin="1">
<Path x:Name="Path" Stretch="Fill" StrokeThickness="0.5" Stroke="#FF333333" Fill="#FF969696" Data="F1 M 0,1.3333L 1.33333,0L 4,2.6666L 6.6666,0 8,1.3333L 5.3333,4L 8,6.6666L 6.6666,8L 4,5.3333L 1.3333,8L 0,6.6666L 2.6666,4L 0,1.3333 Z " HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</Button>
</Grid>
</Border>
<ContentPresenter Content="{TemplateBinding Content}" />
</DockPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Control.BorderBrush" Value="{StaticResource paneBorder}" />
</Style>
</ResourceDictionary>
Loading…
Cancel
Save