Work on GUI (WIP)
This commit is contained in:
Родитель
fd4586d5e6
Коммит
02dd91365a
|
@ -68,7 +68,7 @@ namespace Confuser.Core {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// OBtains the relative path from the specified base path.
|
||||
/// Obtains the relative path from the specified base path.
|
||||
/// </summary>
|
||||
/// <param name="filespec">The file path.</param>
|
||||
/// <param name="folder">The base path.</param>
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
<Application x:Class="ConfuserEx.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
StartupUri="MainWindow.xaml">
|
||||
<Application x:Class="ConfuserEx.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="MainWindow.xaml">
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Utf8Output>true</Utf8Output>
|
||||
<SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir>
|
||||
<RestorePackages>true</RestorePackages>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|AnyCPU'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
|
@ -42,7 +44,22 @@
|
|||
<AssemblyOriginatorKeyFile>..\ConfuserEx.snk</AssemblyOriginatorKeyFile>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="GalaSoft.MvvmLight.Extras.WPF4">
|
||||
<HintPath>..\packages\MvvmLightLibs.4.3.31.1\lib\net40\GalaSoft.MvvmLight.Extras.WPF4.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="GalaSoft.MvvmLight.WPF4">
|
||||
<HintPath>..\packages\MvvmLightLibs.4.3.31.1\lib\net40\GalaSoft.MvvmLight.WPF4.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Practices.ServiceLocation">
|
||||
<HintPath>..\packages\CommonServiceLocator.1.2\lib\portable-windows8+net40+sl5+windowsphone8\Microsoft.Practices.ServiceLocation.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Ookii.Dialogs.Wpf">
|
||||
<HintPath>..\deps\Ookii.Dialogs.Wpf.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Windows.Interactivity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\MvvmLightLibs.4.3.31.1\lib\net40\System.Windows.Interactivity.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xaml" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Core" />
|
||||
|
@ -60,13 +77,18 @@
|
|||
<Link>Properties\GlobalAssemblyInfo.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ViewModel\AppVM.cs" />
|
||||
<Compile Include="Skin.cs" />
|
||||
<Compile Include="ViewModel\UI\AppVM.cs" />
|
||||
<Compile Include="ViewModel\IViewModel.cs" />
|
||||
<Compile Include="ViewModel\ProjectTabVM.cs" />
|
||||
<Compile Include="ViewModel\ProjectVM.cs" />
|
||||
<Compile Include="ViewModel\TabViewModel.cs" />
|
||||
<Compile Include="ViewModel\Project\ProjectModuleVM.cs" />
|
||||
<Compile Include="ViewModel\UI\ProjectTabVM.cs" />
|
||||
<Compile Include="ViewModel\Project\ProjectVM.cs" />
|
||||
<Compile Include="ViewModel\UI\TabViewModel.cs" />
|
||||
<Compile Include="ViewModel\Utils.cs" />
|
||||
<Compile Include="ViewModel\ViewModelBase.cs" />
|
||||
<Compile Include="Views\ProjectModuleView.xaml.cs">
|
||||
<DependentUpon>ProjectModuleView.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Page Include="MainWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
|
@ -87,6 +109,10 @@
|
|||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</Page>
|
||||
<Page Include="Views\ProjectModuleView.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="Views\ProjectTabView.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
|
@ -102,16 +128,11 @@
|
|||
<None Include="..\ConfuserEx.snk">
|
||||
<Link>Properties\ConfuserEx.snk</Link>
|
||||
</None>
|
||||
<None Include="app.config" />
|
||||
<None Include="packages.config" />
|
||||
<None Include="Resources\CREDITS" />
|
||||
<Resource Include="Resources\FontAwesome.otf" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Decode.png" />
|
||||
<Resource Include="Resources\New.png" />
|
||||
<Resource Include="Resources\Open.png" />
|
||||
<Resource Include="Resources\Save.png" />
|
||||
<Resource Include="Resources\Tools.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Confuser.Core\Confuser.Core.csproj">
|
||||
<Project>{BEB67A6E-4C54-4DE5-8C6B-2C12F44A7B92}</Project>
|
||||
|
@ -138,7 +159,21 @@
|
|||
<Name>dnlib</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\Decode.png" />
|
||||
<Resource Include="Resources\New.png" />
|
||||
<Resource Include="Resources\Open.png" />
|
||||
<Resource Include="Resources\Save.png" />
|
||||
<Resource Include="Resources\Tools.png" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))" />
|
||||
</Target>
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
<Window x:Class="ConfuserEx.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Title="{Binding Title}" Width="800" Height="600" Style="{StaticResource DarkWindow}"
|
||||
FontFamily="Open Sans" FontSize="12">
|
||||
Title="{Binding Title}" Width="800" Height="600" Style="{StaticResource DarkWindow}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<ToolBar Grid.Row="0" Grid.ColumnSpan="2" ToolBarTray.IsLocked="True" ToolBar.OverflowMode="Never">
|
||||
<ToolBar Grid.Row="0" Grid.ColumnSpan="2" ToolBarTray.IsLocked="True" ToolBar.OverflowMode="Never"
|
||||
KeyboardNavigation.TabNavigation="Continue">
|
||||
<Button>
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image Source="{StaticResource New}" Margin="0,0,4,0" />
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using System.Windows;
|
||||
|
||||
namespace ConfuserEx {
|
||||
public class Skin {
|
||||
public static readonly DependencyProperty EmptyPromptProperty =
|
||||
DependencyProperty.RegisterAttached("EmptyPrompt", typeof (string), typeof (Skin), new UIPropertyMetadata(null));
|
||||
|
||||
public static string GetEmptyPrompt(DependencyObject obj) {
|
||||
return (string)obj.GetValue(EmptyPromptProperty);
|
||||
}
|
||||
|
||||
public static void SetEmptyPrompt(DependencyObject obj, string value) {
|
||||
obj.SetValue(EmptyPromptProperty, value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
<ResourceDictionary
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:ConfuserEx">
|
||||
|
||||
<DrawingBrush x:Key="WindowBackground" TileMode="Tile" Viewport="0,0,10,10" ViewportUnits="Absolute">
|
||||
<DrawingBrush.Drawing>
|
||||
|
@ -64,9 +65,11 @@
|
|||
<Style x:Key="DarkWindow" TargetType="{x:Type Window}">
|
||||
<Setter Property="Background" Value="{StaticResource WindowBackground}" />
|
||||
<Setter Property="Foreground" Value="{StaticResource Foreground}" />
|
||||
<Setter Property="FontFamily" Value="Open Sans" />
|
||||
<Setter Property="FontSize" Value="12" />
|
||||
<Setter Property="UseLayoutRounding" Value="True" />
|
||||
<Setter Property="TextOptions.TextFormattingMode" Value="Display" />
|
||||
<Setter Property="TextOptions.TextRenderingMode" Value="Cleartype" />
|
||||
<Setter Property="TextOptions.TextFormattingMode" Value="Ideal" />
|
||||
<Setter Property="TextOptions.TextRenderingMode" Value="Grayscale" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="{x:Type Window}">
|
||||
|
@ -654,6 +657,11 @@
|
|||
<Grid>
|
||||
<Border x:Name="Overlay" Background="{StaticResource HighlightOverlay}" Opacity="0" />
|
||||
<ScrollViewer x:Name="PART_ContentHost" />
|
||||
<Label x:Name="Prompt" Opacity="0"
|
||||
Content="{Binding Path=(local:Skin.EmptyPrompt), RelativeSource={RelativeSource TemplatedParent}}"
|
||||
IsHitTestVisible="False"
|
||||
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
|
||||
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" />
|
||||
</Grid>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
|
@ -664,6 +672,12 @@
|
|||
<Trigger Property="IsFocused" Value="true">
|
||||
<Setter Property="Opacity" TargetName="Overlay" Value="0.5" />
|
||||
</Trigger>
|
||||
<Trigger Property="Text" Value="">
|
||||
<Setter Property="Opacity" TargetName="Prompt" Value="0.5" />
|
||||
</Trigger>
|
||||
<Trigger Property="Text" Value="{x:Null}">
|
||||
<Setter Property="Opacity" TargetName="Prompt" Value="0.5" />
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
|
@ -755,9 +769,15 @@
|
|||
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}"
|
||||
BorderThickness="{TemplateBinding BorderThickness}"
|
||||
Background="{TemplateBinding Background}" SnapsToDevicePixels="true">
|
||||
<ScrollViewer Focusable="false" Padding="{TemplateBinding Padding}">
|
||||
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
|
||||
</ScrollViewer>
|
||||
<Grid>
|
||||
<ScrollViewer Focusable="false" Padding="{TemplateBinding Padding}">
|
||||
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
|
||||
</ScrollViewer>
|
||||
<Label x:Name="Prompt" Opacity="0"
|
||||
Content="{Binding Path=(local:Skin.EmptyPrompt), RelativeSource={RelativeSource TemplatedParent}}"
|
||||
IsHitTestVisible="False" VerticalContentAlignment="Center"
|
||||
HorizontalContentAlignment="Center" />
|
||||
</Grid>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsEnabled" Value="false">
|
||||
|
@ -767,6 +787,10 @@
|
|||
<Trigger Property="IsGrouping" Value="true">
|
||||
<Setter Property="ScrollViewer.CanContentScroll" Value="false" />
|
||||
</Trigger>
|
||||
<DataTrigger Binding="{Binding Items.Count, RelativeSource={x:Static RelativeSource.Self}}"
|
||||
Value="0">
|
||||
<Setter Property="Opacity" TargetName="Prompt" Value="0.5" />
|
||||
</DataTrigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
using System;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using Confuser.Core.Project;
|
||||
|
||||
namespace ConfuserEx.ViewModel {
|
||||
public class ProjectModuleVM : ViewModelBase, IViewModel<ProjectModule> {
|
||||
private readonly ProjectModule module;
|
||||
private readonly ProjectVM parent;
|
||||
private string asmName = "Unknown";
|
||||
|
||||
public ProjectModuleVM(ProjectVM parent, ProjectModule module) {
|
||||
this.parent = parent;
|
||||
this.module = module;
|
||||
}
|
||||
|
||||
public ProjectModule Module {
|
||||
get { return module; }
|
||||
}
|
||||
|
||||
public string Path {
|
||||
get { return module.Path; }
|
||||
set {
|
||||
if (SetProperty(module.Path != value, val => module.Path = val, value, "Path")) {
|
||||
parent.IsModified = true;
|
||||
LoadAssemblyName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string AssemblyName {
|
||||
get { return asmName; }
|
||||
set { SetProperty(ref asmName, value, "AssemblyName"); }
|
||||
}
|
||||
|
||||
public string SNKeyPath {
|
||||
get { return module.SNKeyPath; }
|
||||
set {
|
||||
if (SetProperty(module.SNKeyPath != value, val => module.SNKeyPath = val, value, "SNKeyPath")) {
|
||||
parent.IsModified = true;
|
||||
LoadAssemblyName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string SNKeyPassword {
|
||||
get { return module.SNKeyPassword; }
|
||||
set {
|
||||
if (SetProperty(module.SNKeyPassword != value, val => module.SNKeyPassword = val, value, "SNKeyPassword")) {
|
||||
parent.IsModified = true;
|
||||
LoadAssemblyName();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ProjectModule IViewModel<ProjectModule>.Model {
|
||||
get { return module; }
|
||||
}
|
||||
|
||||
private void LoadAssemblyName() {
|
||||
AssemblyName = "Loading...";
|
||||
ThreadPool.QueueUserWorkItem(_ => {
|
||||
try {
|
||||
string path = System.IO.Path.Combine(parent.BaseDirectory, Path);
|
||||
AssemblyName name = System.Reflection.AssemblyName.GetAssemblyName(path);
|
||||
AssemblyName = name.FullName;
|
||||
}
|
||||
catch {
|
||||
AssemblyName = "Unknown";
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using Confuser.Core.Project;
|
||||
|
||||
namespace ConfuserEx.ViewModel {
|
||||
|
@ -8,6 +10,9 @@ namespace ConfuserEx.ViewModel {
|
|||
|
||||
public ProjectVM(ConfuserProject proj) {
|
||||
this.proj = proj;
|
||||
ObservableCollection<ProjectModuleVM> modules = Utils.Wrap(proj, module => new ProjectModuleVM(this, module));
|
||||
modules.CollectionChanged += (sender, e) => IsModified = true;
|
||||
Modules = modules;
|
||||
}
|
||||
|
||||
public ConfuserProject Project {
|
||||
|
@ -39,6 +44,8 @@ namespace ConfuserEx.ViewModel {
|
|||
set { SetProperty(proj.OutputDirectory != value, val => proj.OutputDirectory = val, value, "OutputDirectory"); }
|
||||
}
|
||||
|
||||
public IList<ProjectModuleVM> Modules { get; private set; }
|
||||
|
||||
ConfuserProject IViewModel<ConfuserProject>.Model {
|
||||
get { return proj; }
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace ConfuserEx.ViewModel {
|
||||
public class ProjectTabVM : TabViewModel {
|
||||
public ProjectTabVM(AppVM app)
|
||||
: base(app, "Project") { }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using Confuser.Core.Project;
|
||||
using ConfuserEx.Views;
|
||||
using GalaSoft.MvvmLight.Command;
|
||||
using Ookii.Dialogs.Wpf;
|
||||
|
||||
namespace ConfuserEx.ViewModel {
|
||||
public class ProjectTabVM : TabViewModel {
|
||||
private int selIndex = -1;
|
||||
|
||||
public ProjectTabVM(AppVM app)
|
||||
: base(app, "Project") { }
|
||||
|
||||
public ICommand DragOver {
|
||||
get {
|
||||
return new RelayCommand<DragEventArgs>(e => {
|
||||
e.Effects = DragDropEffects.None;
|
||||
if (e.Data.GetDataPresent(DataFormats.FileDrop))
|
||||
e.Effects = DragDropEffects.Link;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public ICommand Drop {
|
||||
get {
|
||||
return new RelayCommand<DragEventArgs>(e => {
|
||||
foreach (string file in (string[])e.Data.GetData(DataFormats.FileDrop))
|
||||
AddModule(file);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public int SelectedIndex {
|
||||
get { return selIndex; }
|
||||
set { SetProperty(ref selIndex, value, "SelectedIndex"); }
|
||||
}
|
||||
|
||||
public ICommand ChooseBaseDir {
|
||||
get {
|
||||
return new RelayCommand(() => {
|
||||
var fbd = new VistaFolderBrowserDialog();
|
||||
fbd.SelectedPath = App.Project.BaseDirectory;
|
||||
if (fbd.ShowDialog() ?? false) {
|
||||
App.Project.BaseDirectory = fbd.SelectedPath;
|
||||
App.Project.OutputDirectory = Path.Combine(App.Project.BaseDirectory, "Confused");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public ICommand ChooseOutputDir {
|
||||
get {
|
||||
return new RelayCommand(() => {
|
||||
var fbd = new VistaFolderBrowserDialog();
|
||||
fbd.SelectedPath = App.Project.OutputDirectory;
|
||||
if (fbd.ShowDialog() ?? false) {
|
||||
App.Project.OutputDirectory = fbd.SelectedPath;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public ICommand Add {
|
||||
get {
|
||||
return new RelayCommand(() => {
|
||||
var ofd = new VistaOpenFileDialog();
|
||||
ofd.Filter = ".NET assemblies (*.exe, *.dll)|*.exe;*.dll|All Files (*.*)|*.*";
|
||||
if (ofd.ShowDialog() ?? false) {
|
||||
AddModule(ofd.FileName);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public ICommand Remove {
|
||||
get {
|
||||
return new RelayCommand(() => {
|
||||
Debug.Assert(SelectedIndex != -1);
|
||||
ProjectModuleVM module = App.Project.Modules[SelectedIndex];
|
||||
string msg = string.Format("Are you sure to remove module '{0}'?\r\nAll settings specific to it would be lost!", module.Path);
|
||||
if (MessageBox.Show(msg, "ConfuserEx", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
|
||||
App.Project.Modules.RemoveAt(SelectedIndex);
|
||||
}, () => SelectedIndex != -1);
|
||||
}
|
||||
}
|
||||
|
||||
public ICommand Edit {
|
||||
get {
|
||||
return new RelayCommand(() => {
|
||||
Debug.Assert(SelectedIndex != -1);
|
||||
var dialog = new ProjectModuleView(App.Project.Modules[SelectedIndex]);
|
||||
dialog.Owner = Application.Current.MainWindow;
|
||||
dialog.ShowDialog();
|
||||
}, () => SelectedIndex != -1);
|
||||
}
|
||||
}
|
||||
|
||||
public ICommand Advanced {
|
||||
get { return new RelayCommand(() => { }); }
|
||||
}
|
||||
|
||||
private void AddModule(string file) {
|
||||
if (!File.Exists(file)) {
|
||||
MessageBox.Show(string.Format("File '{0}' does not exists!", file), "ConfuserEx", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
return;
|
||||
}
|
||||
if (string.IsNullOrEmpty(App.Project.BaseDirectory)) {
|
||||
string directory = Path.GetDirectoryName(file);
|
||||
App.Project.BaseDirectory = directory;
|
||||
App.Project.OutputDirectory = Path.Combine(directory, "Confused");
|
||||
}
|
||||
var module = new ProjectModuleVM(App.Project, new ProjectModule());
|
||||
module.Path = Confuser.Core.Utils.GetRelativePath(file, App.Project.BaseDirectory);
|
||||
App.Project.Modules.Add(module);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@
|
|||
namespace ConfuserEx.ViewModel {
|
||||
public abstract class TabViewModel : ViewModelBase {
|
||||
protected TabViewModel(AppVM app, string header) {
|
||||
App = app;
|
||||
Header = header;
|
||||
}
|
||||
|
|
@ -41,21 +41,21 @@ namespace ConfuserEx.ViewModel {
|
|||
return ret;
|
||||
}
|
||||
|
||||
public static ObservableCollection<IViewModel<T>> Wrap<T>(IList<T> list, Func<T, IViewModel<T>> transform) {
|
||||
var ret = new ObservableCollection<IViewModel<T>>(list.Select(item => transform(item)));
|
||||
public static ObservableCollection<TViewModel> Wrap<TModel, TViewModel>(IList<TModel> list, Func<TModel, TViewModel> transform) where TViewModel : IViewModel<TModel> {
|
||||
var ret = new ObservableCollection<TViewModel>(list.Select(item => transform(item)));
|
||||
|
||||
ret.CollectionChanged += (sender, e) => {
|
||||
var collection = (ObservableCollection<IViewModel<T>>)sender;
|
||||
var collection = (ObservableCollection<TViewModel>)sender;
|
||||
switch (e.Action) {
|
||||
case NotifyCollectionChangedAction.Reset:
|
||||
list.Clear();
|
||||
foreach (var item in collection)
|
||||
foreach (TViewModel item in collection)
|
||||
list.Add(item.Model);
|
||||
break;
|
||||
|
||||
case NotifyCollectionChangedAction.Add:
|
||||
for (int i = 0; i < e.NewItems.Count; i++)
|
||||
list.Insert(e.NewStartingIndex + i, ((IViewModel<T>)e.NewItems[i]).Model);
|
||||
list.Insert(e.NewStartingIndex + i, ((TViewModel)e.NewItems[i]).Model);
|
||||
break;
|
||||
|
||||
case NotifyCollectionChangedAction.Remove:
|
||||
|
@ -65,11 +65,11 @@ namespace ConfuserEx.ViewModel {
|
|||
|
||||
case NotifyCollectionChangedAction.Move:
|
||||
list.RemoveAt(e.OldStartingIndex);
|
||||
list.Insert(e.NewStartingIndex, ((IViewModel<T>)e.NewItems[0]).Model);
|
||||
list.Insert(e.NewStartingIndex, ((TViewModel)e.NewItems[0]).Model);
|
||||
break;
|
||||
|
||||
case NotifyCollectionChangedAction.Replace:
|
||||
list[e.NewStartingIndex] = ((IViewModel<T>)e.NewItems[0]).Model;
|
||||
list[e.NewStartingIndex] = ((TViewModel)e.NewItems[0]).Model;
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
<Window x:Class="ConfuserEx.Views.ProjectModuleView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
Title="{Binding Path, StringFormat=Edit module \'{0}\'...}" Style="{StaticResource DarkWindow}"
|
||||
SizeToContent="WidthAndHeight">
|
||||
<Grid Margin="5">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="36px" />
|
||||
<RowDefinition Height="36px" />
|
||||
<RowDefinition Height="36px" />
|
||||
<RowDefinition Height="36px" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="150px" />
|
||||
<ColumnDefinition Width="250px" />
|
||||
<ColumnDefinition Width="35px" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<Label Content="Assembly Path : " Grid.Row="0" Grid.Column="0" HorizontalContentAlignment="Right"
|
||||
VerticalContentAlignment="Center" />
|
||||
<TextBox Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" Margin="5" VerticalContentAlignment="Center"
|
||||
Text="{Binding Path, Mode=TwoWay}" />
|
||||
|
||||
<Label Content="SN Key Path : " Grid.Row="1" Grid.Column="0" HorizontalContentAlignment="Right"
|
||||
VerticalContentAlignment="Center" />
|
||||
<TextBox x:Name="PathBox" Grid.Row="1" Grid.Column="1" Margin="5" VerticalContentAlignment="Center"
|
||||
TextChanged="PathBox_TextChanged" Text="{Binding SNKeyPath, Mode=TwoWay}" />
|
||||
<Button Grid.Row="1" Grid.Column="2" Margin="5" VerticalAlignment="Center" Height="26" Click="ChooseSNKey">
|
||||
<TextBlock FontSize="14px" FontFamily="{DynamicResource FontAwesome}" Text="" Height="10px"
|
||||
TextOptions.TextRenderingMode="GrayScale" />
|
||||
</Button>
|
||||
|
||||
<Label Content="SN Key Password : " Grid.Row="2" Grid.Column="0" HorizontalContentAlignment="Right"
|
||||
VerticalContentAlignment="Center" />
|
||||
<TextBox x:Name="PwdBox" Grid.Row="2" Grid.Column="1" Margin="5" Grid.ColumnSpan="2"
|
||||
VerticalContentAlignment="Center" Text="{Binding SNKeyPassword, Mode=TwoWay}" />
|
||||
|
||||
<Button Grid.Row="3" Grid.ColumnSpan="3" HorizontalAlignment="Right" Content="Done"
|
||||
Width="70" Margin="5" Click="Done" />
|
||||
</Grid>
|
||||
</Window>
|
|
@ -0,0 +1,34 @@
|
|||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using ConfuserEx.ViewModel;
|
||||
using Ookii.Dialogs.Wpf;
|
||||
|
||||
namespace ConfuserEx.Views {
|
||||
public partial class ProjectModuleView : Window {
|
||||
private readonly ProjectModuleVM module;
|
||||
|
||||
public ProjectModuleView(ProjectModuleVM module) {
|
||||
InitializeComponent();
|
||||
this.module = module;
|
||||
DataContext = module;
|
||||
PwdBox.IsEnabled = !string.IsNullOrEmpty(PathBox.Text);
|
||||
}
|
||||
|
||||
private void Done(object sender, RoutedEventArgs e) {
|
||||
DialogResult = true;
|
||||
}
|
||||
|
||||
private void PathBox_TextChanged(object sender, TextChangedEventArgs e) {
|
||||
PwdBox.IsEnabled = !string.IsNullOrEmpty(PathBox.Text);
|
||||
}
|
||||
|
||||
private void ChooseSNKey(object sender, RoutedEventArgs e) {
|
||||
var ofd = new VistaOpenFileDialog();
|
||||
ofd.Filter = "Supported Key Files (*.snk, *.pfx)|*.snk;*.pfx|All Files (*.*)|*.*";
|
||||
if (ofd.ShowDialog() ?? false) {
|
||||
module.SNKeyPath = ofd.FileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,8 +1,11 @@
|
|||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vm="clr-namespace:ConfuserEx.ViewModel">
|
||||
xmlns:local="clr-namespace:ConfuserEx"
|
||||
xmlns:vm="clr-namespace:ConfuserEx.ViewModel"
|
||||
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
|
||||
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4">
|
||||
<DataTemplate DataType="{x:Type vm:ProjectTabVM}">
|
||||
<Grid>
|
||||
<Grid AllowDrop="True">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="36px" />
|
||||
<RowDefinition Height="36px" />
|
||||
|
@ -15,18 +18,31 @@
|
|||
<ColumnDefinition Width="35px" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<i:Interaction.Triggers>
|
||||
<i:EventTrigger EventName="PreviewDragOver">
|
||||
<cmd:EventToCommand PassEventArgsToCommand="True" Command="{Binding DragOver}" />
|
||||
</i:EventTrigger>
|
||||
<i:EventTrigger EventName="PreviewDrop">
|
||||
<cmd:EventToCommand PassEventArgsToCommand="True" Command="{Binding Drop}" />
|
||||
</i:EventTrigger>
|
||||
</i:Interaction.Triggers>
|
||||
|
||||
<Label Content="Base Directory : " Grid.Row="0" Grid.Column="0" HorizontalContentAlignment="Right"
|
||||
VerticalContentAlignment="Center" />
|
||||
<TextBox Grid.Row="0" Grid.Column="1" Margin="5" VerticalContentAlignment="Center" />
|
||||
<Button Grid.Row="0" Grid.Column="2" Margin="5" VerticalAlignment="Center" Height="26">
|
||||
<TextBox Grid.Row="0" Grid.Column="1" Margin="5" VerticalContentAlignment="Center"
|
||||
Text="{Binding App.Project.BaseDirectory, Mode=TwoWay}" />
|
||||
<Button Grid.Row="0" Grid.Column="2" Margin="5" VerticalAlignment="Center" Height="26"
|
||||
Command="{Binding ChooseBaseDir}">
|
||||
<TextBlock FontSize="14px" FontFamily="{DynamicResource FontAwesome}" Text="" Height="10px"
|
||||
TextOptions.TextRenderingMode="GrayScale" />
|
||||
</Button>
|
||||
|
||||
<Label Content="Output Directory : " Grid.Row="1" Grid.Column="0" HorizontalContentAlignment="Right"
|
||||
VerticalContentAlignment="Center" />
|
||||
<TextBox Grid.Row="1" Grid.Column="1" Margin="5" VerticalContentAlignment="Center" />
|
||||
<Button Grid.Row="1" Grid.Column="2" Margin="5" VerticalAlignment="Center" Height="26">
|
||||
<TextBox Grid.Row="1" Grid.Column="1" Margin="5" VerticalContentAlignment="Center"
|
||||
Text="{Binding App.Project.OutputDirectory, Mode=TwoWay}" />
|
||||
<Button Grid.Row="1" Grid.Column="2" Margin="5" VerticalAlignment="Center" Height="26"
|
||||
Command="{Binding ChooseOutputDir}">
|
||||
<TextBlock FontSize="14px" FontFamily="{DynamicResource FontAwesome}" Text="" Height="10px"
|
||||
TextOptions.TextRenderingMode="GrayScale" />
|
||||
</Button>
|
||||
|
@ -39,25 +55,51 @@
|
|||
</Grid.ColumnDefinitions>
|
||||
<Label Content="Seed : " Grid.Column="0" HorizontalContentAlignment="Right"
|
||||
VerticalContentAlignment="Center" />
|
||||
<TextBox Grid.Column="1" Margin="5" VerticalContentAlignment="Center" />
|
||||
<CheckBox Grid.Column="2" Content="Generate Debug Symbols" VerticalAlignment="Center" Margin="5" />
|
||||
<TextBox Grid.Column="1" Margin="5" VerticalContentAlignment="Center"
|
||||
Text="{Binding App.Project.Seed, Mode=TwoWay}"
|
||||
local:Skin.EmptyPrompt="Leave blank for random seed" />
|
||||
<CheckBox Grid.Column="2" Content="Generate Debug Symbols" VerticalAlignment="Center" Margin="5"
|
||||
IsChecked="{Binding App.Project.Debug, Mode=TwoWay}" />
|
||||
</Grid>
|
||||
|
||||
<ListBox Grid.Row="3" Grid.ColumnSpan="2" Margin="5" />
|
||||
<StackPanel Grid.Row="3" Grid.Column="2" Orientation="Vertical">
|
||||
<Button Grid.Row="1" Grid.Column="2" Height="26" Margin="5">
|
||||
<ListBox Grid.Row="3" Grid.ColumnSpan="2" Margin="5" local:Skin.EmptyPrompt="Drag input modules here"
|
||||
ItemsSource="{Binding App.Project.Modules}" HorizontalContentAlignment="Stretch"
|
||||
SelectedIndex="{Binding SelectedIndex}" ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
||||
Grid.IsSharedSizeScope="True">
|
||||
<ListBox.ItemTemplate>
|
||||
<DataTemplate DataType="{x:Type vm:ProjectModuleVM}">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text="{Binding AssemblyName}"
|
||||
TextAlignment="Left" Margin="0,0,5,0" TextTrimming="CharacterEllipsis" />
|
||||
<TextBlock Grid.Column="1" Text="{Binding Path}"
|
||||
TextAlignment="Right" Margin="5,0,0,0" TextTrimming="CharacterEllipsis" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListBox.ItemTemplate>
|
||||
</ListBox>
|
||||
<DockPanel Grid.Row="3" Grid.Column="2">
|
||||
<Button Height="26" Margin="5" DockPanel.Dock="Top" Command="{Binding Add}">
|
||||
<TextBlock FontSize="14px" FontFamily="{DynamicResource FontAwesome}" Text="" Height="12px"
|
||||
TextOptions.TextRenderingMode="GrayScale" />
|
||||
</Button>
|
||||
<Button Grid.Row="1" Grid.Column="2" Height="26" Margin="5">
|
||||
<Button Height="26" Margin="5" DockPanel.Dock="Top" Command="{Binding Remove}">
|
||||
<TextBlock FontSize="14px" FontFamily="{DynamicResource FontAwesome}" Text="" Height="12px"
|
||||
TextOptions.TextRenderingMode="GrayScale" />
|
||||
</Button>
|
||||
<Button Grid.Row="1" Grid.Column="2" Height="26" Margin="5">
|
||||
<TextBlock FontSize="14px" FontFamily="{DynamicResource FontAwesome}" Text="" Height="12px"
|
||||
<Button Height="26" Margin="5" DockPanel.Dock="Top" Command="{Binding Edit}">
|
||||
<TextBlock FontSize="14px" FontFamily="{DynamicResource FontAwesome}" Text="" Height="12px"
|
||||
TextOptions.TextRenderingMode="GrayScale" />
|
||||
</Button>
|
||||
</StackPanel>
|
||||
<Button Height="26" Margin="5" DockPanel.Dock="Bottom" Command="{Binding Advanced}">
|
||||
<TextBlock FontSize="14px" FontFamily="{DynamicResource FontAwesome}" Text="" Height="12px"
|
||||
TextOptions.TextRenderingMode="GrayScale" />
|
||||
</Button>
|
||||
<Border />
|
||||
</DockPanel>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ResourceDictionary>
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<configuration>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Microsoft.Practices.ServiceLocation" publicKeyToken="31BF3856AD364E35"
|
||||
culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-1.2.0.0" newVersion="1.2.0.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<packages>
|
||||
<package id="CommonServiceLocator" version="1.2" targetFramework="net40" />
|
||||
<package id="MvvmLightLibs" version="4.3.31.1" targetFramework="net40" />
|
||||
</packages>
|
Двоичный файл не отображается.
Загрузка…
Ссылка в новой задаче