├── .gitignore └── src ├── Plugins ├── BitnessCheck │ ├── BitnessCheck.csproj │ ├── MainUserControl.xaml │ ├── MainUserControl.xaml.cs │ ├── Plugin.cs │ └── Properties │ │ └── AssemblyInfo.cs ├── Plugins.sln ├── SolarSystem │ ├── App.xaml │ ├── App.xaml.cs │ ├── Images │ │ ├── SolarSurface.JPG │ │ ├── earth.jpg │ │ ├── off.design │ │ ├── off.png │ │ ├── on.design │ │ └── on.png │ ├── MainUserControl.xaml │ ├── MainUserControl.xaml.cs │ ├── MainWindow.xaml │ ├── MainWindow.xaml.cs │ ├── OrbitsCalculator.cs │ ├── Plugin.cs │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ ├── Settings.Designer.cs │ │ └── Settings.settings │ └── SolarSystem.csproj ├── Surfaces │ ├── 3DTools │ │ ├── Trackball.cs │ │ ├── TrackballDecorator.cs │ │ ├── Viewport3DDecorator.cs │ │ └── license.txt │ ├── Circle.cs │ ├── Properties │ │ ├── AssemblyInfo.cs │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ ├── Settings.Designer.cs │ │ └── Settings.settings │ ├── PropertyHolder.cs │ ├── Sphere.cs │ ├── Surface.cs │ └── Surfaces.csproj ├── TestExceptions │ ├── MainUserControl.xaml │ ├── MainUserControl.xaml.cs │ ├── MyException.cs │ ├── Plugin.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── TestExceptions.csproj ├── UseLogService │ ├── LogLevel.cs │ ├── MainUserControl.xaml │ ├── MainUserControl.xaml.cs │ ├── Plugin.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── UseLogService.csproj └── license.txt └── WpfHost ├── PluginHosting ├── AssemblyResolver.cs ├── ExceptionUtil.cs ├── IPluginLoader.cs ├── IRemotePlugin.cs ├── IpcServices.cs ├── Log │ ├── ConsoleAppender.cs │ ├── ILogAppender.cs │ ├── LocalLog.cs │ ├── LogLevel.cs │ ├── TempFileAppender.cs │ └── TraceAppender.cs ├── NativeHandleContractInsulator.cs ├── PluginCreator.cs ├── PluginHosting.csproj ├── PluginLoader.cs ├── PluginLoaderBootstrapper.cs ├── ProcessMonitor.cs ├── Properties │ └── AssemblyInfo.cs └── RemotePlugin.cs ├── PluginProcess ├── App.config ├── PluginProcess.csproj ├── Program.cs └── Properties │ └── AssemblyInfo.cs ├── PluginProcess64 ├── PluginProcess64.csproj └── Properties │ └── AssemblyInfo.cs ├── WpfHost.Interfaces ├── ILog.cs ├── IPlugin.cs ├── IUnsavedData.cs ├── IWpfHost.cs ├── PluginBase.cs ├── PluginStartupInfo.cs ├── Properties │ └── AssemblyInfo.cs ├── ServiceProviderUtil.cs └── WpfHost.Interfaces.csproj ├── WpfHost.sln ├── WpfHost ├── App.config ├── App.xaml ├── App.xaml.cs ├── Catalogs │ ├── IPluginCatalog.cs │ └── XmlPluginCatalog.cs ├── CloseButton.xaml ├── ErrorHandlingService.cs ├── MainViewModel.cs ├── MainWindow.xaml ├── MainWindow.xaml.cs ├── Mvvm │ ├── DelegateCommand.cs │ ├── TrivialConverter.cs │ └── ViewModelBase.cs ├── Plugin.cs ├── PluginCatalogEntry.cs ├── PluginController.cs ├── PluginErrorEventArgs.cs ├── PluginException.cs ├── PluginProcessProxy.cs ├── PluginViewOfHost.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── WpfHost.csproj ├── packages.config └── plugins.xml └── packages ├── Unity.3.0.1304.0 ├── Unity.3.0.1304.0.nupkg ├── UnityConfiguration30.xsd ├── lib │ ├── Net45 │ │ ├── Microsoft.Practices.Unity.Configuration.dll │ │ ├── Microsoft.Practices.Unity.Configuration.xml │ │ ├── Microsoft.Practices.Unity.dll │ │ └── Microsoft.Practices.Unity.xml │ └── NetCore45 │ │ ├── Microsoft.Practices.Unity.NetCore.dll │ │ ├── Microsoft.Practices.Unity.NetCore.pri │ │ └── Microsoft.Practices.Unity.NetCore.xml └── tools │ └── install.ps1 └── repositories.config /.gitignore: -------------------------------------------------------------------------------- 1 | #OS junk files 2 | [Tt]humbs.db 3 | *.DS_Store 4 | 5 | #Visual Studio files 6 | *.[Oo]bj 7 | *.user 8 | *.aps 9 | *.pch 10 | *.vspscc 11 | *.vssscc 12 | *_i.c 13 | *_p.c 14 | *.ncb 15 | *.suo 16 | *.tlb 17 | *.tlh 18 | *.bak 19 | *.[Cc]ache 20 | *.ilk 21 | *.log 22 | *.lib 23 | *.sbr 24 | *.sdf 25 | *.opensdf 26 | *.unsuccessfulbuild 27 | ipch/ 28 | obj/ 29 | [Bb]in 30 | [Dd]ebug*/ 31 | [Rr]elease*/ 32 | 33 | #Tooling 34 | _ReSharper*/ 35 | *.resharper 36 | [Tt]est[Rr]esult* 37 | 38 | #Project files 39 | [Bb]uild/ 40 | 41 | #Subversion files 42 | .svn 43 | 44 | # Office Temp Files 45 | ~$* 46 | 47 | #NuGet 48 | packages/ 49 | 50 | # visual studio database projects 51 | *.dbmdl -------------------------------------------------------------------------------- /src/Plugins/BitnessCheck/BitnessCheck.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {BD283195-C479-4A52-95A9-536F83908AEC} 8 | Library 9 | Properties 10 | BitnessCheck 11 | BitnessCheck 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | ..\..\WpfHost\bin\Release\WpfHost.Interfaces.dll 46 | False 47 | 48 | 49 | 50 | 51 | MainUserControl.xaml 52 | 53 | 54 | 55 | 56 | 57 | 58 | MSBuild:Compile 59 | Designer 60 | 61 | 62 | 63 | 70 | -------------------------------------------------------------------------------- /src/Plugins/BitnessCheck/MainUserControl.xaml: -------------------------------------------------------------------------------- 1 |  6 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/Plugins/BitnessCheck/MainUserControl.xaml.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Windows; 10 | using System.Windows.Controls; 11 | 12 | namespace BitnessCheck 13 | { 14 | /// 15 | /// Interaction logic for BitnessCheck.xaml 16 | /// 17 | public partial class MainUserControl : UserControl 18 | { 19 | int _physicalMemory; 20 | int _virtualMemory; 21 | List _memory = new List(); 22 | 23 | public MainUserControl() 24 | { 25 | InitializeComponent(); 26 | BitnessText.Text = "Running at " + IntPtr.Size*8 + " bit"; 27 | UpdateMemoryText(); 28 | } 29 | 30 | private void UpdateMemoryText() 31 | { 32 | PhysicalMemoryText.Text = _physicalMemory + " G"; 33 | VirtualMemoryText.Text = _virtualMemory + " G"; 34 | } 35 | 36 | private void Reserve_Click(object sender, RoutedEventArgs e) 37 | { 38 | Allocate(Reserve); 39 | } 40 | 41 | private void Commit_Click(object sender, RoutedEventArgs e) 42 | { 43 | Allocate(Commit); 44 | } 45 | 46 | /* To outstmart .NET optimization and virtual memory mechanism we need to keep in mind these facts 47 | * 48 | * 1. It is not possible to allocate more than 2G of memory at a time, even when running as 64 bit 49 | * 50 | * 2. If we allocate memory in several independent arrays, they might be immediately garbage collected. 51 | * We must reference all arrays from a single data structure, so it can only be garbage collected as a whole. 52 | * 53 | * 3. To have virtual address space actually reserved, we must access at least one byte of the memory allocated. 54 | * 32-bit process cannot have 3G of virtual address space reserved and exception will be thrown at this point. 55 | * 56 | * 4. If we want pages of physical memory allocated, and not just virtual address space reserved, we must explicitly 57 | * access each page, which happens to be 4096 bytes on Intel systems. This is what Commit() method does. 58 | */ 59 | private void Allocate(Action commitAction) 60 | { 61 | try 62 | { 63 | const long oneG = 1024L * 1024 * 1024; 64 | byte[] memory = new byte[oneG]; 65 | commitAction(memory); 66 | _memory.Add(memory); 67 | } 68 | catch (Exception ex) 69 | { 70 | MessageBox.Show(ex.ToString(), "Failure"); 71 | } 72 | 73 | UpdateMemoryText(); 74 | } 75 | 76 | private void Reserve(byte[] b) 77 | { 78 | b[0] = 42; 79 | ++_virtualMemory; 80 | } 81 | 82 | 83 | private void Commit(byte[] b) 84 | { 85 | const int PageSize = 4096; 86 | 87 | // index can be int, as currently array size cannot exceed 2G 88 | for (int index=0; index 6 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/Plugins/SolarSystem/App.xaml.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System.Windows; 8 | 9 | namespace SolarSystem 10 | { 11 | /// 12 | /// Interaction logic for App.xaml 13 | /// 14 | public partial class App : Application 15 | { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Plugins/SolarSystem/Images/SolarSurface.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikriv/BaktunShell/086ff5ea1393497e477b0818a26d9edf76607ee4/src/Plugins/SolarSystem/Images/SolarSurface.JPG -------------------------------------------------------------------------------- /src/Plugins/SolarSystem/Images/earth.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikriv/BaktunShell/086ff5ea1393497e477b0818a26d9edf76607ee4/src/Plugins/SolarSystem/Images/earth.jpg -------------------------------------------------------------------------------- /src/Plugins/SolarSystem/Images/off.design: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikriv/BaktunShell/086ff5ea1393497e477b0818a26d9edf76607ee4/src/Plugins/SolarSystem/Images/off.design -------------------------------------------------------------------------------- /src/Plugins/SolarSystem/Images/off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikriv/BaktunShell/086ff5ea1393497e477b0818a26d9edf76607ee4/src/Plugins/SolarSystem/Images/off.png -------------------------------------------------------------------------------- /src/Plugins/SolarSystem/Images/on.design: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikriv/BaktunShell/086ff5ea1393497e477b0818a26d9edf76607ee4/src/Plugins/SolarSystem/Images/on.design -------------------------------------------------------------------------------- /src/Plugins/SolarSystem/Images/on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ikriv/BaktunShell/086ff5ea1393497e477b0818a26d9edf76607ee4/src/Plugins/SolarSystem/Images/on.png -------------------------------------------------------------------------------- /src/Plugins/SolarSystem/MainUserControl.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Windows; 2 | using System.Windows.Controls; 3 | 4 | namespace SolarSystem 5 | { 6 | /// 7 | /// Interaction logic for Window1.xaml 8 | /// 9 | public partial class MainUserControl : UserControl 10 | { 11 | OrbitsCalculator _data = new OrbitsCalculator(); 12 | public MainUserControl() 13 | { 14 | DataContext = _data; 15 | InitializeComponent(); 16 | } 17 | 18 | private void MainWindow_Loaded(object sender, RoutedEventArgs e) 19 | { 20 | _data.StartTimer(); 21 | } 22 | 23 | private void Pause_Checked(object sender, RoutedEventArgs e) 24 | { 25 | _data.Pause(true); 26 | } 27 | 28 | private void Pause_Unchecked(object sender, RoutedEventArgs e) 29 | { 30 | _data.Pause(false); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Plugins/SolarSystem/MainWindow.xaml: -------------------------------------------------------------------------------- 1 |  6 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/Plugins/SolarSystem/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System.Windows; 8 | 9 | namespace SolarSystem 10 | { 11 | /// 12 | /// Interaction logic for MainWindow.xaml 13 | /// 14 | public partial class MainWindow : Window 15 | { 16 | public MainWindow() 17 | { 18 | InitializeComponent(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Plugins/SolarSystem/OrbitsCalculator.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2009 Ivan Krivyakov 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | using System; 16 | using System.ComponentModel; 17 | using System.Windows.Threading; 18 | 19 | namespace SolarSystem 20 | { 21 | class OrbitsCalculator : INotifyPropertyChanged 22 | { 23 | private DateTime _startTime; 24 | private double _startDays; 25 | private DispatcherTimer _timer; 26 | 27 | const double EarthYear = 365.25; 28 | const double EarthRotationPeriod = 1.0; 29 | const double SunRotationPeriod = 25.0; 30 | const double TwoPi = Math.PI * 2; 31 | 32 | private double _daysPerSecond = 2; 33 | public double DaysPerSecond 34 | { 35 | get { return _daysPerSecond; } 36 | set { _daysPerSecond = value; Update("DaysPerSecond"); } 37 | } 38 | 39 | public double EarthOrbitRadius { get { return 40; } set { } } 40 | public double Days { get; set; } 41 | public double EarthRotationAngle { get; set; } 42 | public double SunRotationAngle { get; set; } 43 | public double EarthOrbitPositionX { get; set; } 44 | public double EarthOrbitPositionY { get; set; } 45 | public double EarthOrbitPositionZ { get; set; } 46 | public bool ReverseTime { get; set; } 47 | public bool Paused { get; set; } 48 | 49 | public OrbitsCalculator() 50 | { 51 | EarthOrbitPositionX = EarthOrbitRadius; 52 | DaysPerSecond = 2; 53 | } 54 | 55 | public void StartTimer() 56 | { 57 | _startTime = DateTime.Now; 58 | _timer = new DispatcherTimer(); 59 | _timer.Interval = TimeSpan.FromMilliseconds(100); 60 | _timer.Tick += new EventHandler(OnTimerTick); 61 | _timer.Start(); 62 | } 63 | 64 | private void StopTimer() 65 | { 66 | _timer.Stop(); 67 | _timer.Tick -= OnTimerTick; 68 | _timer = null; 69 | } 70 | 71 | public void Pause(bool doPause) 72 | { 73 | if (doPause) 74 | { 75 | StopTimer(); 76 | } 77 | else 78 | { 79 | StartTimer(); 80 | } 81 | } 82 | 83 | void OnTimerTick(object sender, EventArgs e) 84 | { 85 | var now = DateTime.Now; 86 | Days += (now-_startTime).TotalMilliseconds * DaysPerSecond / 1000.0 * (ReverseTime?-1:1); 87 | _startTime = now; 88 | Update("Days"); 89 | OnTimeChanged(); 90 | } 91 | 92 | private void OnTimeChanged() 93 | { 94 | EarthPosition(); 95 | EarthRotation(); 96 | SunRotation(); 97 | } 98 | 99 | private void EarthPosition() 100 | { 101 | double angle = 2 * Math.PI * Days / EarthYear; 102 | EarthOrbitPositionX = EarthOrbitRadius * Math.Cos(angle); 103 | EarthOrbitPositionY = EarthOrbitRadius * Math.Sin(angle); 104 | Update("EarthOrbitPositionX"); 105 | Update("EarthOrbitPositionY"); 106 | } 107 | 108 | private void EarthRotation() 109 | { 110 | EarthRotationAngle = 360 * Days / EarthRotationPeriod; 111 | Update("EarthRotationAngle"); 112 | } 113 | 114 | private void SunRotation() 115 | { 116 | SunRotationAngle = 360 * Days / SunRotationPeriod; 117 | Update("SunRotationAngle"); 118 | } 119 | 120 | private void Update(string propertyName) 121 | { 122 | if (PropertyChanged != null) 123 | { 124 | var args = new PropertyChangedEventArgs(propertyName); 125 | PropertyChanged(this, args); 126 | } 127 | } 128 | 129 | public event PropertyChangedEventHandler PropertyChanged; 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /src/Plugins/SolarSystem/Plugin.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System.Windows; 8 | using IKriv.WpfHost.Interfaces; 9 | 10 | namespace SolarSystem 11 | { 12 | public class Plugin : PluginBase 13 | { 14 | public override FrameworkElement CreateControl() 15 | { 16 | return new MainUserControl(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Plugins/SolarSystem/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2009 Ivan Krivyakov 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | using System.Reflection; 16 | using System.Resources; 17 | using System.Runtime.CompilerServices; 18 | using System.Runtime.InteropServices; 19 | using System.Windows; 20 | 21 | // General Information about an assembly is controlled through the following 22 | // set of attributes. Change these attribute values to modify the information 23 | // associated with an assembly. 24 | [assembly: AssemblyTitle("SolarSystem")] 25 | [assembly: AssemblyDescription("")] 26 | [assembly: AssemblyConfiguration("")] 27 | [assembly: AssemblyCompany("ikriv.com")] 28 | [assembly: AssemblyProduct("SolarSystem")] 29 | [assembly: AssemblyCopyright("Copyright © 2009 Ivan Krivyakov")] 30 | [assembly: AssemblyTrademark("")] 31 | [assembly: AssemblyCulture("")] 32 | 33 | // Setting ComVisible to false makes the types in this assembly not visible 34 | // to COM components. If you need to access a type in this assembly from 35 | // COM, set the ComVisible attribute to true on that type. 36 | [assembly: ComVisible(false)] 37 | 38 | //In order to begin building localizable applications, set 39 | //CultureYouAreCodingWith in your .csproj file 40 | //inside a . For example, if you are using US english 41 | //in your source files, set the to en-US. Then uncomment 42 | //the NeutralResourceLanguage attribute below. Update the "en-US" in 43 | //the line below to match the UICulture setting in the project file. 44 | 45 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] 46 | 47 | 48 | [assembly: ThemeInfo( 49 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 50 | //(used if a resource is not found in the page, 51 | // or application resource dictionaries) 52 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 53 | //(used if a resource is not found in the page, 54 | // app, or any theme specific resource dictionaries) 55 | )] 56 | 57 | 58 | // Version information for an assembly consists of the following four values: 59 | // 60 | // Major Version 61 | // Minor Version 62 | // Build Number 63 | // Revision 64 | // 65 | // You can specify all the values or you can default the Build and Revision Numbers 66 | // by using the '*' as shown below: 67 | // [assembly: AssemblyVersion("1.0.*")] 68 | [assembly: AssemblyVersion("1.0.0.0")] 69 | [assembly: AssemblyFileVersion("1.0.0.0")] 70 | -------------------------------------------------------------------------------- /src/Plugins/SolarSystem/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18052 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace SolarSystem.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SolarSystem.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/Plugins/SolarSystem/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /src/Plugins/SolarSystem/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18052 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace SolarSystem.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Plugins/SolarSystem/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/Plugins/Surfaces/3DTools/license.txt: -------------------------------------------------------------------------------- 1 | http://3dtools.codeplex.com/license 2 | Note: this license applies only to the code in the 3DTools folder. 3 | 4 | Microsoft Limited Permissive License (Ms-LPL) 5 | 6 | This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. 7 | 8 | 1. Definitions 9 | The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. 10 | A "contribution" is the original software, or any additions or changes to the software. 11 | A "contributor" is any person that distributes its contribution under this license. 12 | "Licensed patents" are a contributor's patent claims that read directly on its contribution. 13 | 14 | 2. Grant of Rights 15 | (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. 16 | (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. 17 | 18 | 3. Conditions and Limitations 19 | (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. 20 | (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. 21 | (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. 22 | (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. 23 | (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. 24 | (F) Platform Limitation- The licenses granted in sections 2(A) & 2(B) extend only to the software or derivative works that you create that run on a Microsoft Windows operating system product. -------------------------------------------------------------------------------- /src/Plugins/Surfaces/Circle.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2009 Ivan Krivyakov 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | using System; 16 | using System.Windows.Media.Media3D; 17 | 18 | namespace Ikriv.Surfaces 19 | { 20 | public sealed class Circle : Surface 21 | { 22 | private static PropertyHolder RadiusProperty = 23 | new PropertyHolder("Radius", 1.0, OnGeometryChanged); 24 | 25 | public double Radius 26 | { 27 | get { return RadiusProperty.Get(this); } 28 | set { RadiusProperty.Set(this, value); } 29 | } 30 | 31 | private static PropertyHolder PositionProperty = 32 | new PropertyHolder("Position", new Point3D(0, 0, 0), OnGeometryChanged); 33 | 34 | public Point3D Position 35 | { 36 | get { return PositionProperty.Get(this); } 37 | set { PositionProperty.Set(this, value); } 38 | } 39 | 40 | private double _radius; 41 | private Point3D _position; 42 | 43 | private Point3D PointForAngle(double angle) 44 | { 45 | return new Point3D( _position.X + _radius*Math.Cos(angle), _position.Y + _radius*Math.Sin(angle), _position.Z); 46 | } 47 | 48 | protected override Geometry3D CreateMesh() 49 | { 50 | _radius = Radius; 51 | _position = Position; 52 | 53 | MeshGeometry3D mesh = new MeshGeometry3D(); 54 | Point3D prevPoint = PointForAngle(0); 55 | Vector3D normal = new Vector3D(0,0,1); 56 | 57 | const int div = 180; 58 | for (int i = 1; i <= div; ++i) 59 | { 60 | double angle = 2 * Math.PI / div * i; 61 | Point3D newPoint = PointForAngle(angle); 62 | mesh.Positions.Add(prevPoint); 63 | mesh.Positions.Add(_position); 64 | mesh.Positions.Add(newPoint); 65 | mesh.Normals.Add(normal); 66 | mesh.Normals.Add(normal); 67 | mesh.Normals.Add(normal); 68 | prevPoint = newPoint; 69 | } 70 | 71 | mesh.Freeze(); 72 | return mesh; 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/Plugins/Surfaces/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2009 Ivan Krivyakov 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | using System.Reflection; 16 | using System.Resources; 17 | using System.Runtime.CompilerServices; 18 | using System.Runtime.InteropServices; 19 | using System.Windows; 20 | 21 | // General Information about an assembly is controlled through the following 22 | // set of attributes. Change these attribute values to modify the information 23 | // associated with an assembly. 24 | [assembly: AssemblyTitle("Surfaces")] 25 | [assembly: AssemblyDescription("")] 26 | [assembly: AssemblyConfiguration("")] 27 | [assembly: AssemblyCompany("ikriv.com")] 28 | [assembly: AssemblyProduct("Surfaces")] 29 | [assembly: AssemblyCopyright("Copyright © 2009 Ivan Krivyakov")] 30 | [assembly: AssemblyTrademark("")] 31 | [assembly: AssemblyCulture("")] 32 | 33 | // Setting ComVisible to false makes the types in this assembly not visible 34 | // to COM components. If you need to access a type in this assembly from 35 | // COM, set the ComVisible attribute to true on that type. 36 | [assembly: ComVisible(false)] 37 | 38 | //In order to begin building localizable applications, set 39 | //CultureYouAreCodingWith in your .csproj file 40 | //inside a . For example, if you are using US english 41 | //in your source files, set the to en-US. Then uncomment 42 | //the NeutralResourceLanguage attribute below. Update the "en-US" in 43 | //the line below to match the UICulture setting in the project file. 44 | 45 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] 46 | 47 | 48 | [assembly: ThemeInfo( 49 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 50 | //(used if a resource is not found in the page, 51 | // or application resource dictionaries) 52 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 53 | //(used if a resource is not found in the page, 54 | // app, or any theme specific resource dictionaries) 55 | )] 56 | 57 | 58 | // Version information for an assembly consists of the following four values: 59 | // 60 | // Major Version 61 | // Minor Version 62 | // Build Number 63 | // Revision 64 | // 65 | // You can specify all the values or you can default the Build and Revision Numbers 66 | // by using the '*' as shown below: 67 | // [assembly: AssemblyVersion("1.0.*")] 68 | [assembly: AssemblyVersion("1.0.0.0")] 69 | [assembly: AssemblyFileVersion("1.0.0.0")] 70 | -------------------------------------------------------------------------------- /src/Plugins/Surfaces/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18052 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Surfaces.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Surfaces.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/Plugins/Surfaces/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /src/Plugins/Surfaces/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18052 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace Surfaces.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Plugins/Surfaces/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/Plugins/Surfaces/PropertyHolder.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2009 Ivan Krivyakov 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | using System.Windows; 16 | 17 | namespace Ikriv.Surfaces 18 | { 19 | public class PropertyHolder where HoldingType:DependencyObject 20 | { 21 | DependencyProperty _property; 22 | 23 | public PropertyHolder(string name, PropertyType defaultValue, PropertyChangedCallback propertyChangedCallback) 24 | { 25 | _property = 26 | DependencyProperty.Register( 27 | name, 28 | typeof(PropertyType), 29 | typeof(HoldingType), 30 | new PropertyMetadata(defaultValue, propertyChangedCallback)); 31 | } 32 | 33 | public DependencyProperty Property 34 | { 35 | get { return _property; } 36 | } 37 | 38 | public PropertyType Get(HoldingType obj) 39 | { 40 | return (PropertyType)obj.GetValue(_property); 41 | } 42 | 43 | public void Set(HoldingType obj, PropertyType value) 44 | { 45 | obj.SetValue(_property, value); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Plugins/Surfaces/Sphere.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2009 Ivan Krivyakov 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | using System; 16 | using System.Windows; 17 | using System.Windows.Media; 18 | using System.Windows.Media.Media3D; 19 | 20 | namespace Ikriv.Surfaces 21 | { 22 | public sealed class Sphere : Surface 23 | { 24 | private static PropertyHolder RadiusProperty = 25 | new PropertyHolder("Radius", 1.0, OnGeometryChanged); 26 | 27 | public double Radius 28 | { 29 | get { return RadiusProperty.Get(this); } 30 | set { RadiusProperty.Set(this, value); } 31 | } 32 | 33 | private static PropertyHolder PositionProperty = 34 | new PropertyHolder("Position", new Point3D(0,0,0), OnGeometryChanged); 35 | 36 | public Point3D Position 37 | { 38 | get { return PositionProperty.Get(this); } 39 | set { PositionProperty.Set(this, value); } 40 | } 41 | 42 | private double _radius; 43 | private Point3D _position; 44 | 45 | private Point3D GetPosition(double angle, double y) 46 | { 47 | double r = _radius * Math.Sqrt(1 - y * y); 48 | double x = r * Math.Cos(angle); 49 | double z = r * Math.Sin(angle); 50 | 51 | return new Point3D(_position.X + x, _position.Y + _radius*y, _position.Z + z); 52 | } 53 | 54 | private Vector3D GetNormal(double angle, double y) 55 | { 56 | return (Vector3D) GetPosition(angle, y); 57 | } 58 | 59 | private Point GetTextureCoordinate(double angle, double y) 60 | { 61 | Matrix map = new Matrix(); 62 | map.Scale(1 / (2 * Math.PI), -0.5); 63 | 64 | Point p = new Point(angle, y); 65 | p = p * map; 66 | 67 | return p; 68 | } 69 | 70 | protected override Geometry3D CreateMesh() 71 | { 72 | _radius = Radius; 73 | _position = Position; 74 | 75 | const int angleSteps = 32; 76 | const double minAngle = 0; 77 | const double maxAngle = 2 * Math.PI; 78 | const double dAngle = (maxAngle-minAngle) / angleSteps; 79 | 80 | const int ySteps = 32; 81 | const double minY = -1.0; 82 | const double maxY = 1.0; 83 | const double dy = (maxY - minY) / ySteps; 84 | 85 | MeshGeometry3D mesh = new MeshGeometry3D(); 86 | 87 | for (int yi = 0; yi <= ySteps; yi++) 88 | { 89 | double y = minY + yi * dy; 90 | 91 | for (int ai = 0; ai <= angleSteps; ai++) 92 | { 93 | double angle = ai * dAngle; 94 | 95 | mesh.Positions.Add(GetPosition(angle, y)); 96 | mesh.Normals.Add(GetNormal(angle, y)); 97 | mesh.TextureCoordinates.Add(GetTextureCoordinate(angle, y)); 98 | } 99 | } 100 | 101 | for (int yi = 0; yi < ySteps; yi++) 102 | { 103 | for (int ai = 0; ai < angleSteps; ai++) 104 | { 105 | int a1 = ai; 106 | int a2 = (ai + 1); 107 | int y1 = yi * (angleSteps + 1); 108 | int y2 = (yi + 1) * (angleSteps + 1); 109 | 110 | mesh.TriangleIndices.Add(y1 + a1); 111 | mesh.TriangleIndices.Add(y2 + a1); 112 | mesh.TriangleIndices.Add(y1 + a2); 113 | 114 | mesh.TriangleIndices.Add(y1 + a2); 115 | mesh.TriangleIndices.Add(y2 + a1); 116 | mesh.TriangleIndices.Add(y2 + a2); 117 | } 118 | } 119 | 120 | mesh.Freeze(); 121 | return mesh; 122 | } 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/Plugins/Surfaces/Surface.cs: -------------------------------------------------------------------------------- 1 | /* Copyright 2009 Ivan Krivyakov 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | */ 15 | using System; 16 | using System.Windows; 17 | using System.Windows.Media; 18 | using System.Windows.Media.Media3D; 19 | 20 | namespace Ikriv.Surfaces 21 | { 22 | public abstract class Surface : ModelVisual3D 23 | { 24 | public Surface() 25 | { 26 | Content = _content; 27 | _content.Geometry = CreateMesh(); 28 | } 29 | 30 | public static PropertyHolder MaterialProperty = 31 | new PropertyHolder("Material", null, OnMaterialChanged); 32 | 33 | public static PropertyHolder BackMaterialProperty = 34 | new PropertyHolder("BackMaterial", null, OnBackMaterialChanged); 35 | 36 | public static PropertyHolder VisibleProperty = 37 | new PropertyHolder("Visible", true, OnVisibleChanged); 38 | 39 | public Material Material 40 | { 41 | get { return MaterialProperty.Get(this); } 42 | set { MaterialProperty.Set(this, value); } 43 | } 44 | 45 | public Material BackMaterial 46 | { 47 | get { return BackMaterialProperty.Get(this); } 48 | set { BackMaterialProperty.Set(this, value); } 49 | } 50 | 51 | public bool Visible 52 | { 53 | get { return VisibleProperty.Get(this); } 54 | set { VisibleProperty.Set(this, value); } 55 | } 56 | 57 | private static void OnMaterialChanged(Object sender, DependencyPropertyChangedEventArgs e) 58 | { 59 | ((Surface)sender).OnMaterialChanged(); 60 | } 61 | 62 | private static void OnBackMaterialChanged(Object sender, DependencyPropertyChangedEventArgs e) 63 | { 64 | ((Surface)sender).OnBackMaterialChanged(); 65 | } 66 | 67 | private static void OnVisibleChanged(Object sender, DependencyPropertyChangedEventArgs e) 68 | { 69 | ((Surface)sender).OnVisibleChanged(); 70 | } 71 | 72 | protected static void OnGeometryChanged(Object sender, DependencyPropertyChangedEventArgs e) 73 | { 74 | ((Surface)sender).OnGeometryChanged(); 75 | } 76 | 77 | private void OnMaterialChanged() 78 | { 79 | SetContentMaterial(); 80 | } 81 | 82 | private void OnBackMaterialChanged() 83 | { 84 | SetContentBackMaterial(); 85 | } 86 | 87 | private void OnVisibleChanged() 88 | { 89 | SetContentMaterial(); 90 | SetContentBackMaterial(); 91 | } 92 | 93 | private void SetContentMaterial() 94 | { 95 | _content.Material = Visible ? Material : null; 96 | } 97 | 98 | private void SetContentBackMaterial() 99 | { 100 | _content.BackMaterial = Visible ? BackMaterial : null; 101 | } 102 | 103 | private void OnGeometryChanged() 104 | { 105 | _content.Geometry = CreateMesh(); 106 | } 107 | 108 | protected abstract Geometry3D CreateMesh(); 109 | 110 | private readonly GeometryModel3D _content = new GeometryModel3D(); 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /src/Plugins/Surfaces/Surfaces.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.30729 7 | 2.0 8 | {80EE383C-DB1B-4D2D-BF14-4A97FFF0A823} 9 | library 10 | Properties 11 | Surfaces 12 | Surfaces 13 | v3.5 14 | 512 15 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 16 | 4 17 | 18 | 19 | 20 | 21 | 3.5 22 | publish\ 23 | true 24 | Disk 25 | false 26 | Foreground 27 | 7 28 | Days 29 | false 30 | false 31 | true 32 | 0 33 | 1.0.0.%2a 34 | false 35 | false 36 | true 37 | 38 | 39 | true 40 | full 41 | false 42 | bin\Debug\ 43 | DEBUG;TRACE 44 | prompt 45 | 4 46 | 47 | 48 | pdbonly 49 | true 50 | bin\Release\ 51 | TRACE 52 | prompt 53 | 4 54 | 55 | 56 | 57 | 58 | 3.5 59 | 60 | 61 | 3.5 62 | 63 | 64 | 3.5 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | Code 81 | 82 | 83 | True 84 | True 85 | Resources.resx 86 | 87 | 88 | True 89 | Settings.settings 90 | True 91 | 92 | 93 | 94 | ResXFileCodeGenerator 95 | Resources.Designer.cs 96 | 97 | 98 | SettingsSingleFileGenerator 99 | Settings.Designer.cs 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | False 109 | .NET Framework 3.5 SP1 Client Profile 110 | false 111 | 112 | 113 | False 114 | .NET Framework 3.5 SP1 115 | true 116 | 117 | 118 | 119 | 126 | -------------------------------------------------------------------------------- /src/Plugins/TestExceptions/MainUserControl.xaml: -------------------------------------------------------------------------------- 1 |  6 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | Test Exceptions Plugin 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/Plugins/TestExceptions/MainUserControl.xaml.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System.Threading; 8 | using System.Windows; 9 | using System.Windows.Controls; 10 | 11 | namespace TestExceptions 12 | { 13 | /// 14 | /// Interaction logic for MainUserControl.xaml 15 | /// 16 | public partial class MainUserControl : UserControl 17 | { 18 | public MainUserControl() 19 | { 20 | InitializeComponent(); 21 | } 22 | 23 | private void UiThreadException_Click(object sender, RoutedEventArgs e) 24 | { 25 | throw new MyException("Test exception"); 26 | } 27 | 28 | private void WorkerThreadException_Click(object sender, RoutedEventArgs e) 29 | { 30 | var thread = new Thread(() => { throw new MyException("Test exception"); }); 31 | thread.Start(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Plugins/TestExceptions/MyException.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System; 8 | 9 | namespace TestExceptions 10 | { 11 | class MyException : Exception 12 | { 13 | public MyException(string message) 14 | : 15 | base(message) 16 | { 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Plugins/TestExceptions/Plugin.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System.Windows; 8 | using IKriv.WpfHost.Interfaces; 9 | 10 | namespace TestExceptions 11 | { 12 | public class Plugin : PluginBase 13 | { 14 | public override FrameworkElement CreateControl() 15 | { 16 | return new MainUserControl(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Plugins/TestExceptions/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("TestExceptions")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("TestExceptions")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("ee292d05-9be7-4824-931f-fa9acc64f022")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/Plugins/TestExceptions/TestExceptions.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {0D686CE2-80AF-4F1C-B024-845E933B55F9} 8 | Library 9 | Properties 10 | TestExceptions 11 | TestExceptions 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | ..\..\WpfHost\bin\Release\WpfHost.Interfaces.dll 45 | False 46 | 47 | 48 | 49 | 50 | MainUserControl.xaml 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | Designer 59 | MSBuild:Compile 60 | 61 | 62 | 63 | 70 | -------------------------------------------------------------------------------- /src/Plugins/UseLogService/LogLevel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | namespace UseLogService 8 | { 9 | enum LogLevel 10 | { 11 | Debug, 12 | Info, 13 | Warning, 14 | Error 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Plugins/UseLogService/MainUserControl.xaml: -------------------------------------------------------------------------------- 1 |  6 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | Message: 28 | 29 | 30 | Log level: 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/Plugins/UseLogService/MainUserControl.xaml.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System; 8 | using System.Windows; 9 | using System.Windows.Controls; 10 | using System.Windows.Input; 11 | using IKriv.WpfHost.Interfaces; 12 | 13 | namespace UseLogService 14 | { 15 | /// 16 | /// Interaction logic for MainUserControl.xaml 17 | /// 18 | public partial class MainUserControl : UserControl, IUnsavedData 19 | { 20 | private bool _textLogged = true; 21 | 22 | public MainUserControl() 23 | { 24 | InitializeComponent(); 25 | Level.ItemsSource = Enum.GetValues(typeof(LogLevel)); 26 | Level.SelectedItem = LogLevel.Debug; 27 | Message.TextChanged += Message_TextChanged; 28 | } 29 | 30 | void Message_TextChanged(object sender, TextChangedEventArgs e) 31 | { 32 | _textLogged = false; 33 | Logged.Visibility = Visibility.Hidden; 34 | } 35 | 36 | public ILog Log { get; set; } 37 | 38 | public string[] GetNamesOfUnsavedItems() 39 | { 40 | if (!_textLogged) return new[] {"Log message text"}; 41 | return null; 42 | } 43 | 44 | private void LogIt_Click(object sender, RoutedEventArgs e) 45 | { 46 | LogIt(); 47 | } 48 | 49 | private void Message_KeyDown(object sender, KeyEventArgs e) 50 | { 51 | if (e.Key == Key.Enter) LogIt(); 52 | } 53 | 54 | private void LogIt() 55 | { 56 | var message = "From UseLogService: " + Message.Text; 57 | switch ((LogLevel)Level.SelectedItem) 58 | { 59 | case LogLevel.Debug: Log.Debug(message); break; 60 | case LogLevel.Info: Log.Info(message); break; 61 | case LogLevel.Warning: Log.Warn(message); break; 62 | case LogLevel.Error: Log.Error(message); break; 63 | } 64 | _textLogged = true; 65 | Logged.Visibility = Visibility.Visible; 66 | } 67 | 68 | private void UserControl_GotFocus(object sender, RoutedEventArgs e) 69 | { 70 | Message.Focus(); 71 | } 72 | 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/Plugins/UseLogService/Plugin.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System; 8 | using System.Windows; 9 | using IKriv.WpfHost.Interfaces; 10 | 11 | namespace UseLogService 12 | { 13 | class Plugin : PluginBase, IUnsavedData 14 | { 15 | private readonly ILog _log; 16 | private readonly string _parameter; 17 | private MainUserControl _control; 18 | 19 | public Plugin(IWpfHost host) 20 | { 21 | _log = host.GetService(); 22 | var startupInfo = host.GetService(); 23 | if (startupInfo != null) _parameter = startupInfo.Parameters; 24 | } 25 | 26 | public override FrameworkElement CreateControl() 27 | { 28 | _control = new MainUserControl { Log = _log }; 29 | _control.Message.Text = _parameter; 30 | return _control; 31 | } 32 | 33 | public string[] GetNamesOfUnsavedItems() 34 | { 35 | if (_control == null) return null; 36 | return _control.GetNamesOfUnsavedItems(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Plugins/UseLogService/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("UseShellServices")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("UseShellServices")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("3e276708-ef9c-4b3e-8c5d-8bc575af9fc7")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/Plugins/UseLogService/UseLogService.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {6DE97A2B-7D1F-4A22-A45A-02C8765C9529} 8 | Library 9 | Properties 10 | UseLogService 11 | UseLogService 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | ..\..\WpfHost\bin\Release\WpfHost.Interfaces.dll 46 | False 47 | 48 | 49 | 50 | 51 | 52 | MainUserControl.xaml 53 | 54 | 55 | 56 | 57 | 58 | 59 | Designer 60 | MSBuild:Compile 61 | 62 | 63 | 64 | 71 | -------------------------------------------------------------------------------- /src/Plugins/license.txt: -------------------------------------------------------------------------------- 1 | Earth.jpg and SolarSystem.jpg are images from public domain. 2 | 3 | Files in Surfaces\3DTools folder are Copyright (C) Microsoft Corporation, 4 | and are distributed under Microsoft licence specified in 3DTools\license.txt. 5 | 6 | All other files are 7 | Copyright 2009 Ivan Krivyakov 8 | 9 | Licensed under the Apache License, Version 2.0 (the "License"); 10 | you may not use this file except in compliance with the License. 11 | You may obtain a copy of the License at 12 | 13 | http://www.apache.org/licenses/LICENSE-2.0 14 | 15 | Unless required by applicable law or agreed to in writing, software 16 | distributed under the License is distributed on an "AS IS" BASIS, 17 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | See the License for the specific language governing permissions and 19 | limitations under the License. 20 | 21 | -------------------------------------------------------------------------------- /src/WpfHost/PluginHosting/AssemblyResolver.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System; 8 | using System.Reflection; 9 | using IKriv.WpfHost.Interfaces; 10 | 11 | namespace IKriv.PluginHosting 12 | { 13 | class AssemblyResolver 14 | { 15 | private string _thisAssemblyName; 16 | private string _interfacesAssemblyName; 17 | public void Setup() 18 | { 19 | AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve; 20 | _thisAssemblyName = GetType().Assembly.GetName().Name; 21 | _interfacesAssemblyName = typeof(IWpfHost).Assembly.GetName().Name; 22 | 23 | } 24 | 25 | private Assembly OnAssemblyResolve(object sender, ResolveEventArgs args) 26 | { 27 | var name = new AssemblyName(args.Name); 28 | 29 | if (name.Name == _thisAssemblyName) return GetType().Assembly; 30 | if (name.Name == _interfacesAssemblyName) return typeof(IWpfHost).Assembly; 31 | 32 | return null; 33 | } 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/WpfHost/PluginHosting/ExceptionUtil.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Linq; 10 | 11 | namespace IKriv.PluginHosting 12 | { 13 | public class ExceptionUtil 14 | { 15 | public static string GetUserMessage(Exception ex) 16 | { 17 | return String.Join("\r\n", 18 | GetInnerExceptions(ex).Select( 19 | e => String.Format("{0}: {1}", e.GetType().Name, e.Message)).ToArray()); 20 | } 21 | 22 | private static IEnumerable GetInnerExceptions(Exception ex) 23 | { 24 | for (var exception = ex; exception != null; exception = exception.InnerException) 25 | { 26 | yield return exception; 27 | } 28 | } 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/WpfHost/PluginHosting/IPluginLoader.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System; 8 | using IKriv.WpfHost.Interfaces; 9 | 10 | namespace IKriv.PluginHosting 11 | { 12 | public interface IPluginLoader : IDisposable 13 | { 14 | IRemotePlugin LoadPlugin(IWpfHost host, PluginStartupInfo startupInfo); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/WpfHost/PluginHosting/IRemotePlugin.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System; 8 | using System.AddIn.Contract; 9 | 10 | namespace IKriv.PluginHosting 11 | { 12 | public interface IRemotePlugin : IServiceProvider, IDisposable 13 | { 14 | INativeHandleContract Contract { get; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/WpfHost/PluginHosting/IpcServices.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System.Collections; 8 | using System.Runtime.Remoting.Channels; 9 | using System.Runtime.Remoting.Channels.Ipc; 10 | using System.Runtime.Serialization.Formatters; 11 | 12 | namespace IKriv.PluginHosting 13 | { 14 | public class IpcServices 15 | { 16 | public static bool Registered; 17 | public static object Mutex = new object(); 18 | 19 | public static void RegisterChannel(string portName) 20 | { 21 | lock (Mutex) 22 | { 23 | if (Registered) return; 24 | 25 | var serverProvider = new BinaryServerFormatterSinkProvider { TypeFilterLevel = TypeFilterLevel.Full }; 26 | var clientProvider = new BinaryClientFormatterSinkProvider(); 27 | var properties = new Hashtable(); 28 | properties["portName"] = portName; 29 | 30 | var channel = new IpcChannel(properties, clientProvider, serverProvider); 31 | ChannelServices.RegisterChannel(channel, false); 32 | Registered = true; 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/WpfHost/PluginHosting/Log/ConsoleAppender.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace IKriv.PluginHosting.Log 4 | { 5 | class ConsoleAppender : ILogAppender 6 | { 7 | public void Write(string message) 8 | { 9 | Console.WriteLine(message); 10 | } 11 | 12 | public void Dispose() 13 | { 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/WpfHost/PluginHosting/Log/ILogAppender.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace IKriv.PluginHosting.Log 4 | { 5 | public interface ILogAppender : IDisposable 6 | { 7 | void Write(string message); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/WpfHost/PluginHosting/Log/LocalLog.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using IKriv.WpfHost.Interfaces; 4 | 5 | namespace IKriv.PluginHosting.Log 6 | { 7 | public class LocalLog : MarshalByRefObject, ILog, IDisposable 8 | { 9 | private struct AppenderInfo 10 | { 11 | public AppenderInfo(ILogAppender appender, LogLevel level) 12 | { 13 | Appender = appender; 14 | Level = level; 15 | } 16 | 17 | public ILogAppender Appender; 18 | public LogLevel Level; 19 | } 20 | 21 | private readonly List _appenders = new List(); 22 | 23 | public LocalLog Console(LogLevel level) 24 | { 25 | return AddAppender(new ConsoleAppender(), level); 26 | } 27 | 28 | public LocalLog Trace(string name, LogLevel level) 29 | { 30 | return AddAppender(new TraceAppender(name), level); 31 | } 32 | 33 | public LocalLog File(string name, LogLevel level) 34 | { 35 | return AddAppender(new TempFileAppender(name), level); 36 | } 37 | 38 | public LocalLog AddAppender(ILogAppender appender, LogLevel level) 39 | { 40 | if (level != LogLevel.None) _appenders.Add(new AppenderInfo(appender, level)); 41 | return this; 42 | } 43 | 44 | public void Debug(string message) 45 | { 46 | Message(LogLevel.Debug, message); 47 | } 48 | 49 | public void Info(string message) 50 | { 51 | Message(LogLevel.Info, message); 52 | } 53 | 54 | public void Warn(string message) 55 | { 56 | Message(LogLevel.Warning, message); 57 | } 58 | 59 | public void Warn(string message, Exception ex) 60 | { 61 | Message(LogLevel.Warning, message + ". " + ex); 62 | } 63 | 64 | public void Error(string message) 65 | { 66 | Message(LogLevel.Error, message); 67 | } 68 | 69 | public void Error(string message, Exception ex) 70 | { 71 | Message(LogLevel.Error, message + ". " + ex); 72 | } 73 | 74 | public void Dispose() 75 | { 76 | foreach (var appender in _appenders) 77 | { 78 | appender.Appender.Dispose(); 79 | } 80 | } 81 | 82 | public override object InitializeLifetimeService() 83 | { 84 | return null; // live forever 85 | } 86 | 87 | private void Message(LogLevel level, string message) 88 | { 89 | foreach (var appender in _appenders) 90 | { 91 | if (appender.Level <= level) appender.Appender.Write(level.ToString().ToUpper() + " " + message); 92 | } 93 | } 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/WpfHost/PluginHosting/Log/LogLevel.cs: -------------------------------------------------------------------------------- 1 | namespace IKriv.PluginHosting.Log 2 | { 3 | public enum LogLevel 4 | { 5 | Debug, 6 | Info, 7 | Warning, 8 | Error, 9 | None 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/WpfHost/PluginHosting/Log/TempFileAppender.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace IKriv.PluginHosting.Log 5 | { 6 | class TempFileAppender : ILogAppender 7 | { 8 | private readonly string _path; 9 | private StreamWriter _output; 10 | private bool _failed; 11 | 12 | public TempFileAppender(string name) 13 | { 14 | var tempFolder = Path.GetTempPath(); 15 | var logFolder = Path.Combine(tempFolder, "WpfHost"); 16 | _path = Path.Combine(logFolder, name + ".log"); 17 | } 18 | 19 | public void Write(string message) 20 | { 21 | try 22 | { 23 | lock (this) 24 | { 25 | if (_output == null && !_failed) 26 | { 27 | var folder = Path.GetDirectoryName(_path); 28 | Directory.CreateDirectory(folder); 29 | _output = new StreamWriter(_path, true); 30 | } 31 | } 32 | 33 | if (_output != null) 34 | { 35 | _output.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " " + message); 36 | } 37 | } 38 | catch (Exception ex) 39 | { 40 | System.Diagnostics.Trace.WriteLine("Could not write to log file. " + ex); 41 | _failed = true; 42 | } 43 | } 44 | 45 | public void Dispose() 46 | { 47 | try 48 | { 49 | if (_output != null) _output.Close(); 50 | } 51 | catch (Exception ex) 52 | { 53 | System.Diagnostics.Trace.WriteLine("Error closing log. " + ex); 54 | } 55 | finally 56 | { 57 | _output = null; 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/WpfHost/PluginHosting/Log/TraceAppender.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace IKriv.PluginHosting.Log 4 | { 5 | class TraceAppender : ILogAppender 6 | { 7 | private readonly string _prefix; 8 | 9 | public TraceAppender(string name) 10 | { 11 | _prefix = String.IsNullOrEmpty(name) ? "" : name + ": "; 12 | } 13 | 14 | public void Write(string message) 15 | { 16 | System.Diagnostics.Trace.WriteLine(_prefix + message); 17 | } 18 | 19 | public void Dispose() 20 | { 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/WpfHost/PluginHosting/NativeHandleContractInsulator.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System; 8 | using System.AddIn.Contract; 9 | 10 | namespace IKriv.PluginHosting 11 | { 12 | internal class NativeHandleContractInsulator : MarshalByRefObject, INativeHandleContract 13 | { 14 | private readonly INativeHandleContract _source; 15 | 16 | public NativeHandleContractInsulator(INativeHandleContract source) 17 | { 18 | _source = source; 19 | } 20 | 21 | public IntPtr GetHandle() 22 | { 23 | return _source.GetHandle(); 24 | } 25 | 26 | public int AcquireLifetimeToken() 27 | { 28 | return _source.AcquireLifetimeToken(); 29 | } 30 | 31 | public int GetRemoteHashCode() 32 | { 33 | return _source.GetRemoteHashCode(); 34 | } 35 | 36 | public IContract QueryContract(string contractIdentifier) 37 | { 38 | return _source.QueryContract(contractIdentifier); 39 | } 40 | 41 | public bool RemoteEquals(IContract contract) 42 | { 43 | return _source.RemoteEquals(contract); 44 | } 45 | 46 | public string RemoteToString() 47 | { 48 | return _source.RemoteToString(); 49 | } 50 | 51 | public void RevokeLifetimeToken(int token) 52 | { 53 | _source.RevokeLifetimeToken(token); 54 | } 55 | 56 | public override object InitializeLifetimeService() 57 | { 58 | return null; // live forever 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/WpfHost/PluginHosting/PluginCreator.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System; 8 | using System.Reflection; 9 | using System.Windows; 10 | using IKriv.WpfHost.Interfaces; 11 | 12 | namespace IKriv.PluginHosting 13 | { 14 | internal static class PluginCreator 15 | { 16 | public static object CreatePlugin(string assemblyName, string typeName, IWpfHost host) 17 | { 18 | var assembly = Assembly.Load(assemblyName); 19 | var type = assembly.GetType(typeName); 20 | 21 | if (type == null) throw new InvalidOperationException("Could not find type " + typeName + " in assembly " + assemblyName); 22 | 23 | SetupWpfApplication(assembly); 24 | var hostConstructor = type.GetConstructor(new[] {typeof(IWpfHost)}); 25 | if (hostConstructor != null) 26 | { 27 | return hostConstructor.Invoke(new object[]{host}); 28 | } 29 | 30 | var defaultConstructor = type.GetConstructor(new Type[0]); 31 | if (defaultConstructor == null) 32 | { 33 | var message = String.Format("Cannot create an instance of {0}. Either a public default constructor, or a public constructor taking IWpfHost must be defined", typeName); 34 | throw new InvalidOperationException(message); 35 | } 36 | 37 | return defaultConstructor.Invoke(null); 38 | } 39 | 40 | private static void SetupWpfApplication(Assembly assembly) 41 | { 42 | var application = new Application { ShutdownMode = ShutdownMode.OnExplicitShutdown }; 43 | Application.ResourceAssembly = assembly; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/WpfHost/PluginHosting/PluginHosting.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {FF410DCC-13C6-490A-8C83-70E0C1588120} 8 | Library 9 | Properties 10 | IKriv.PluginHosting 11 | PluginHosting 12 | v3.5 13 | 512 14 | Client 15 | 16 | 17 | true 18 | full 19 | false 20 | ..\bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | ..\bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | {933746a8-f169-4606-a04a-113e57cbc185} 67 | WpfHost.Interfaces 68 | 69 | 70 | 71 | 78 | -------------------------------------------------------------------------------- /src/WpfHost/PluginHosting/PluginLoaderBootstrapper.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System; 8 | 9 | namespace IKriv.PluginHosting 10 | { 11 | /// 12 | /// Starts hosting logic 13 | /// 14 | /// We need this class, because otherwise PluginLoader registration with remoting 15 | /// does not work. See 16 | /// http://stackoverflow.com/questions/18445813/remotingservices-marshal-does-not-work-when-invoked-from-another-appdomain 17 | /// 18 | public class PluginLoaderBootstrapper : MarshalByRefObject 19 | { 20 | public void Run(string name) 21 | { 22 | new PluginLoader().Run(name); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/WpfHost/PluginHosting/ProcessMonitor.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System; 8 | using System.Diagnostics; 9 | 10 | namespace IKriv.PluginHosting 11 | { 12 | public class ProcessMonitor 13 | { 14 | private readonly Action _onProcessExit; 15 | private bool _fired; 16 | 17 | public ProcessMonitor(Action onProcessExit) 18 | { 19 | if (onProcessExit == null) throw new ArgumentNullException("onProcessExit"); 20 | _onProcessExit = onProcessExit; 21 | } 22 | 23 | public void Start(int processId) 24 | { 25 | Start(Process.GetProcessById(processId)); 26 | } 27 | 28 | public void Start(Process process) 29 | { 30 | if (process == null) 31 | { 32 | FireOnce(); 33 | return; 34 | } 35 | 36 | process.Exited += (sender, args) => FireOnce(); 37 | process.EnableRaisingEvents = true; 38 | 39 | if (process.HasExited) FireOnce(); 40 | } 41 | 42 | private void FireOnce() 43 | { 44 | lock (this) 45 | { 46 | if (_fired) return; 47 | _fired = true; 48 | } 49 | 50 | _onProcessExit(); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/WpfHost/PluginHosting/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("PluginHosting")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("PluginHosting")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("96baa445-f2e6-47f0-b9ba-4335de5fef2a")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/WpfHost/PluginHosting/RemotePlugin.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System; 8 | using System.AddIn.Contract; 9 | using System.AddIn.Pipeline; 10 | using IKriv.WpfHost.Interfaces; 11 | 12 | namespace IKriv.PluginHosting 13 | { 14 | internal class RemotePlugin : MarshalByRefObject, IRemotePlugin 15 | { 16 | private readonly IPlugin _plugin; 17 | 18 | public RemotePlugin(IPlugin plugin) 19 | { 20 | _plugin = plugin; 21 | var control = plugin.CreateControl(); 22 | var localContract = FrameworkElementAdapters.ViewToContractAdapter(control); 23 | Contract = new NativeHandleContractInsulator(localContract); 24 | } 25 | 26 | public INativeHandleContract Contract { get; private set; } 27 | 28 | public object GetService(Type serviceType) 29 | { 30 | return _plugin.GetService(serviceType); 31 | } 32 | 33 | public void Dispose() 34 | { 35 | _plugin.Dispose(); 36 | } 37 | 38 | public override object InitializeLifetimeService() 39 | { 40 | return null; // live forever 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/WpfHost/PluginProcess/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/WpfHost/PluginProcess/PluginProcess.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {EC0806D2-BFE5-4D83-A849-7AE10A403F48} 8 | Exe 9 | Properties 10 | IKriv.PluginProcess 11 | PluginProcess 12 | v4.5 13 | 512 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | ..\bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | ..\bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | bin\Release64\ 36 | TRACE 37 | true 38 | pdbonly 39 | AnyCPU 40 | prompt 41 | MinimumRecommendedRules.ruleset 42 | true 43 | 44 | 45 | true 46 | bin\x64\Debug\ 47 | DEBUG;TRACE 48 | full 49 | x64 50 | prompt 51 | MinimumRecommendedRules.ruleset 52 | true 53 | 54 | 55 | bin\x64\Release\ 56 | TRACE 57 | true 58 | pdbonly 59 | x64 60 | prompt 61 | MinimumRecommendedRules.ruleset 62 | true 63 | 64 | 65 | bin\x64\Release64\ 66 | TRACE 67 | true 68 | pdbonly 69 | x64 70 | prompt 71 | MinimumRecommendedRules.ruleset 72 | true 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | {ff410dcc-13c6-490a-8c83-70e0c1588120} 93 | PluginHosting 94 | 95 | 96 | {933746a8-f169-4606-a04a-113e57cbc185} 97 | WpfHost.Interfaces 98 | 99 | 100 | 101 | 108 | -------------------------------------------------------------------------------- /src/WpfHost/PluginProcess/Program.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System; 8 | using System.Configuration; 9 | using System.IO; 10 | using IKriv.PluginHosting; 11 | 12 | namespace IKriv.PluginProcess 13 | { 14 | class Program 15 | { 16 | [STAThread] 17 | [LoaderOptimization(LoaderOptimization.MultiDomainHost)] 18 | static void Main(string[] args) 19 | { 20 | bool breakIntoDebugger = bool.Parse(ConfigurationManager.AppSettings["BreakIntoDebugger"]); 21 | if (breakIntoDebugger) System.Diagnostics.Debugger.Break(); 22 | 23 | bool pauseOnError = bool.Parse(ConfigurationManager.AppSettings["PauseOnError"]); 24 | 25 | if (args.Length != 2) 26 | { 27 | Console.Error.WriteLine("Usage: PluginProcess name assemblyPath"); 28 | if (pauseOnError) Console.ReadLine(); 29 | return; 30 | } 31 | 32 | try 33 | { 34 | var name = args[0]; 35 | int bits = IntPtr.Size * 8; 36 | Console.WriteLine("Starting PluginProcess {0}, {1} bit", name, bits); 37 | 38 | var assemblyPath = args[1]; 39 | Console.WriteLine("Plugin assembly: {0}", assemblyPath); 40 | 41 | CheckFileExists(assemblyPath); 42 | var configFile = GetConfigFile(assemblyPath); 43 | 44 | var appBase = Path.GetDirectoryName(assemblyPath); 45 | 46 | var appDomain = CreateAppDomain(appBase, configFile); 47 | var bootstrapper = CreateInstanceFrom(appDomain); 48 | bootstrapper.Run(name); 49 | } 50 | catch (Exception ex) 51 | { 52 | Console.Error.WriteLine(ex); 53 | if (pauseOnError) 54 | { 55 | Console.Error.WriteLine("Pausing on error, press any key to exit..."); 56 | Console.ReadLine(); 57 | } 58 | } 59 | } 60 | 61 | private static T CreateInstanceFrom(AppDomain appDomain) 62 | { 63 | return (T)appDomain.CreateInstanceFromAndUnwrap(typeof(T).Assembly.Location, typeof(T).FullName); 64 | } 65 | 66 | private static void CheckFileExists(string path) 67 | { 68 | if (!File.Exists(path)) throw new InvalidOperationException("File '" + path + "' does not exist"); 69 | } 70 | 71 | private static string GetConfigFile(string assemblyPath) 72 | { 73 | var name = assemblyPath + ".config"; 74 | return File.Exists(name) ? name : null; 75 | } 76 | 77 | private static AppDomain CreateAppDomain(string appBase, string config) 78 | { 79 | var setup = new AppDomainSetup 80 | { 81 | ApplicationBase = appBase, 82 | ConfigurationFile = String.IsNullOrEmpty(config)? null : config 83 | }; 84 | 85 | return AppDomain.CreateDomain("PluginDomain", null, setup); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/WpfHost/PluginProcess/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("PluginProcess")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("PluginProcess")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("e58f1a31-e583-47fb-9984-8cc21f3cb7ce")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/WpfHost/PluginProcess64/PluginProcess64.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {29CF9091-2A69-4E5D-BA44-B94BB23861C3} 8 | Exe 9 | Properties 10 | PluginProcess64 11 | PluginProcess64 12 | v4.5 13 | 512 14 | 15 | 16 | x64 17 | true 18 | full 19 | false 20 | ..\bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | x64 27 | pdbonly 28 | true 29 | ..\bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | Program.cs 46 | 47 | 48 | 49 | 50 | 51 | {ff410dcc-13c6-490a-8c83-70e0c1588120} 52 | PluginHosting 53 | 54 | 55 | {933746a8-f169-4606-a04a-113e57cbc185} 56 | WpfHost.Interfaces 57 | 58 | 59 | 60 | 61 | App.config 62 | 63 | 64 | 65 | 72 | -------------------------------------------------------------------------------- /src/WpfHost/PluginProcess64/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("PluginProcess64")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("PluginProcess64")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("51db28f9-844f-4a0a-9d10-c463d5cf46d2")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/WpfHost/WpfHost.Interfaces/ILog.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System; 8 | 9 | namespace IKriv.WpfHost.Interfaces 10 | { 11 | /// 12 | /// Intefrace for the general logging service 13 | /// 14 | public interface ILog 15 | { 16 | void Debug(string message); 17 | void Info(string message); 18 | void Warn(string message); 19 | void Warn(string message, Exception ex); 20 | void Error(string message); 21 | void Error(string message, Exception ex); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/WpfHost/WpfHost.Interfaces/IPlugin.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System; 8 | using System.Windows; 9 | 10 | namespace IKriv.WpfHost.Interfaces 11 | { 12 | /// 13 | /// Interface for user-defined plugin 14 | /// 15 | public interface IPlugin : IServiceProvider, IDisposable 16 | { 17 | /// 18 | /// Creates plugin's visual element; called only ones in plugin's lifetime 19 | /// 20 | /// WPF framework element of the plugin 21 | FrameworkElement CreateControl(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/WpfHost/WpfHost.Interfaces/IUnsavedData.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | namespace IKriv.WpfHost.Interfaces 8 | { 9 | /// 10 | /// Interface for plugins that may have unsaved data 11 | /// 12 | public interface IUnsavedData 13 | { 14 | /// 15 | /// Get list of currently unsaved data items 16 | /// 17 | /// Array of unsaved data item names 18 | string[] GetNamesOfUnsavedItems(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/WpfHost/WpfHost.Interfaces/IWpfHost.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System; 8 | 9 | namespace IKriv.WpfHost.Interfaces 10 | { 11 | /// 12 | /// Plugins' view of host 13 | /// 14 | public interface IWpfHost : IServiceProvider 15 | { 16 | /// 17 | /// Reports fatal plugin error to the host; the plugin will be closed 18 | /// 19 | /// Message explaining the nature of the error 20 | /// Exception call stack as string 21 | void ReportFatalError(string userMessage, string fullExceptionText); 22 | 23 | /// 24 | /// ID of the host process 25 | /// 26 | int HostProcessId { get; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/WpfHost/WpfHost.Interfaces/PluginBase.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System; 8 | using System.Windows; 9 | 10 | namespace IKriv.WpfHost.Interfaces 11 | { 12 | /// 13 | /// Recommended (but not requried) base class for user-defined plugins 14 | /// 15 | public abstract class PluginBase : MarshalByRefObject, IPlugin 16 | { 17 | public abstract FrameworkElement CreateControl(); 18 | 19 | public virtual object GetService(Type serviceType) 20 | { 21 | if (serviceType.IsAssignableFrom(GetType())) return this; 22 | return null; 23 | } 24 | 25 | public virtual void Dispose() 26 | { 27 | } 28 | 29 | public override object InitializeLifetimeService() 30 | { 31 | return null; // live forever 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/WpfHost/WpfHost.Interfaces/PluginStartupInfo.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System; 8 | 9 | namespace IKriv.WpfHost.Interfaces 10 | { 11 | [Serializable] 12 | public class PluginStartupInfo 13 | { 14 | public string FullAssemblyPath { get; set; } 15 | public string AssemblyName { get; set; } 16 | public int Bits { get; set; } 17 | public string MainClass { get; set; } 18 | public string Name { get; set; } 19 | public string Parameters { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/WpfHost/WpfHost.Interfaces/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("WpfHost.Interfaces.v1")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("WpfHost.Interfaces.v1")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("0ba38539-23c2-4b25-9bb3-f7e7a493f6ce")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/WpfHost/WpfHost.Interfaces/ServiceProviderUtil.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System; 8 | 9 | namespace IKriv.WpfHost.Interfaces 10 | { 11 | public static class ServiceProviderUtil 12 | { 13 | public static T GetService(this IServiceProvider provider) where T : class 14 | { 15 | return (T)provider.GetService(typeof(T)); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/WpfHost/WpfHost.Interfaces/WpfHost.Interfaces.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {933746A8-F169-4606-A04A-113E57CBC185} 8 | Library 9 | Properties 10 | IKriv.WpfHost.Interfaces 11 | WpfHost.Interfaces 12 | v3.5 13 | 512 14 | Client 15 | 16 | 17 | true 18 | full 19 | false 20 | ..\bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | ..\bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 58 | -------------------------------------------------------------------------------- /src/WpfHost/WpfHost.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfHost", "WpfHost\WpfHost.csproj", "{78F065D6-98E5-43D9-91D9-2E8823ABBDA5}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginHosting", "PluginHosting\PluginHosting.csproj", "{FF410DCC-13C6-490A-8C83-70E0C1588120}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginProcess", "PluginProcess\PluginProcess.csproj", "{EC0806D2-BFE5-4D83-A849-7AE10A403F48}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginProcess64", "PluginProcess64\PluginProcess64.csproj", "{29CF9091-2A69-4E5D-BA44-B94BB23861C3}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WpfHost.Interfaces", "WpfHost.Interfaces\WpfHost.Interfaces.csproj", "{933746A8-F169-4606-A04A-113E57CBC185}" 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|Any CPU = Debug|Any CPU 17 | Release|Any CPU = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {78F065D6-98E5-43D9-91D9-2E8823ABBDA5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {78F065D6-98E5-43D9-91D9-2E8823ABBDA5}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {78F065D6-98E5-43D9-91D9-2E8823ABBDA5}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {78F065D6-98E5-43D9-91D9-2E8823ABBDA5}.Release|Any CPU.Build.0 = Release|Any CPU 24 | {FF410DCC-13C6-490A-8C83-70E0C1588120}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {FF410DCC-13C6-490A-8C83-70E0C1588120}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {FF410DCC-13C6-490A-8C83-70E0C1588120}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {FF410DCC-13C6-490A-8C83-70E0C1588120}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {EC0806D2-BFE5-4D83-A849-7AE10A403F48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {EC0806D2-BFE5-4D83-A849-7AE10A403F48}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {EC0806D2-BFE5-4D83-A849-7AE10A403F48}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {EC0806D2-BFE5-4D83-A849-7AE10A403F48}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {29CF9091-2A69-4E5D-BA44-B94BB23861C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {29CF9091-2A69-4E5D-BA44-B94BB23861C3}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {29CF9091-2A69-4E5D-BA44-B94BB23861C3}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {29CF9091-2A69-4E5D-BA44-B94BB23861C3}.Release|Any CPU.Build.0 = Release|Any CPU 36 | {933746A8-F169-4606-A04A-113E57CBC185}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 37 | {933746A8-F169-4606-A04A-113E57CBC185}.Debug|Any CPU.Build.0 = Debug|Any CPU 38 | {933746A8-F169-4606-A04A-113E57CBC185}.Release|Any CPU.ActiveCfg = Release|Any CPU 39 | {933746A8-F169-4606-A04A-113E57CBC185}.Release|Any CPU.Build.0 = Release|Any CPU 40 | EndGlobalSection 41 | GlobalSection(SolutionProperties) = preSolution 42 | HideSolutionNode = FALSE 43 | EndGlobalSection 44 | EndGlobal 45 | -------------------------------------------------------------------------------- /src/WpfHost/WpfHost/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/WpfHost/WpfHost/App.xaml: -------------------------------------------------------------------------------- 1 |  6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/WpfHost/WpfHost/App.xaml.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System.Windows; 8 | using IKriv.PluginHosting.Log; 9 | using IKriv.WpfHost.Interfaces; 10 | using Microsoft.Practices.Unity; 11 | 12 | namespace IKriv.WpfHost 13 | { 14 | /// 15 | /// Interaction logic for App.xaml 16 | /// 17 | public partial class App : Application 18 | { 19 | private IUnityContainer _container; 20 | 21 | protected override void OnStartup(StartupEventArgs e) 22 | { 23 | _container = new UnityContainer(); 24 | ConfigureContainer(); 25 | _container.Resolve().Info("WpfHost starting"); 26 | 27 | var mainWindow = _container.Resolve(); 28 | var viewModel = _container.Resolve(); 29 | mainWindow.DataContext = viewModel; 30 | mainWindow.Show(); 31 | } 32 | 33 | protected override void OnExit(ExitEventArgs e) 34 | { 35 | _container.Resolve().Info("WpfHost shutting down"); 36 | _container.Dispose(); 37 | base.OnExit(e); 38 | } 39 | 40 | private void ConfigureContainer() 41 | { 42 | _container.RegisterType(Singleton()); 43 | _container.RegisterInstance(new LocalLog().File("WpfHost", LogLevel.Debug), Singleton()); 44 | } 45 | 46 | private static ContainerControlledLifetimeManager Singleton() 47 | { 48 | return new ContainerControlledLifetimeManager(); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/WpfHost/WpfHost/Catalogs/IPluginCatalog.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System.Collections.Generic; 8 | 9 | namespace IKriv.WpfHost.Catalogs 10 | { 11 | public interface IPluginCatalog 12 | { 13 | IEnumerable GetPluginList(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/WpfHost/WpfHost/Catalogs/XmlPluginCatalog.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System.Collections.Generic; 8 | using System.IO; 9 | using System.Xml.Serialization; 10 | 11 | namespace IKriv.WpfHost.Catalogs 12 | { 13 | public class XmlPluginCatalog : IPluginCatalog 14 | { 15 | [XmlRoot(ElementName="PluginCatalog", Namespace="http://www.ikriv.com/wpfHosting/plugins")] 16 | public class XmlPluginData 17 | { 18 | [XmlArrayItem(ElementName = "Plugin")] 19 | public PluginCatalogEntry[] Plugins { get; set; } 20 | } 21 | 22 | public XmlPluginCatalog() 23 | { 24 | } 25 | 26 | public XmlPluginCatalog(string fileName) 27 | { 28 | FileName = fileName; 29 | } 30 | 31 | public string FileName { get; set; } 32 | 33 | public IEnumerable GetPluginList() 34 | { 35 | using (var reader = new StreamReader(FileName)) 36 | { 37 | var serializer = new XmlSerializer(typeof(XmlPluginData)); 38 | var data = (XmlPluginData)serializer.Deserialize(reader); 39 | return data.Plugins; 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/WpfHost/WpfHost/CloseButton.xaml: -------------------------------------------------------------------------------- 1 |  6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 59 | 60 | 68 | 69 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /src/WpfHost/WpfHost/ErrorHandlingService.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System; 8 | using System.Windows; 9 | using IKriv.PluginHosting; 10 | using IKriv.WpfHost.Interfaces; 11 | 12 | namespace IKriv.WpfHost 13 | { 14 | class ErrorHandlingService 15 | { 16 | private readonly ILog _log; 17 | 18 | public ErrorHandlingService(ILog log) 19 | { 20 | _log = log; 21 | } 22 | 23 | public void ShowError(string message, Exception ex) 24 | { 25 | _log.Error(message, ex); 26 | 27 | var text = (ex==null)? message : message + GetSeparator(message) + ExceptionUtil.GetUserMessage(ex); 28 | 29 | var mainWindow = GetMainWindow(); 30 | if (mainWindow == null) 31 | { 32 | MessageBox.Show(text, "Error", MessageBoxButton.OK, MessageBoxImage.Error); 33 | } 34 | else 35 | { 36 | MessageBox.Show(mainWindow, text, "Error", MessageBoxButton.OK, MessageBoxImage.Error); 37 | } 38 | } 39 | 40 | public void LogError(string message, Exception ex) 41 | { 42 | _log.Error(message, ex); 43 | } 44 | 45 | public bool Confirm(string message) 46 | { 47 | return MessageBox.Show(message, "Please confirm", MessageBoxButton.OKCancel, MessageBoxImage.Question) == MessageBoxResult.OK; 48 | } 49 | 50 | private static Window GetMainWindow() 51 | { 52 | if (Application.Current == null) return null; 53 | return Application.Current.MainWindow; 54 | } 55 | 56 | private static string GetSeparator(string message) 57 | { 58 | if (message.EndsWith(".")) return " "; 59 | if (message.EndsWith("\n")) return ""; 60 | return ". "; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/WpfHost/WpfHost/MainViewModel.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2013 Ivan Krivyakov 2 | // Licensed under the Apache License, Version 2.0 (the "License"); 3 | // you may not use this file except in compliance with the License. 4 | // You may obtain a copy of the License at 5 | // http://www.apache.org/licenses/LICENSE-2.0 6 | // 7 | using System; 8 | using System.Collections.Generic; 9 | using System.Collections.ObjectModel; 10 | using System.Text; 11 | using System.Threading.Tasks; 12 | using System.Windows.Input; 13 | using IKriv.WpfHost.Mvvm; 14 | 15 | namespace IKriv.WpfHost 16 | { 17 | class MainViewModel : ViewModelBase, IDisposable 18 | { 19 | private readonly PluginController _pluginController; 20 | private readonly ErrorHandlingService _errorHandlingService; 21 | 22 | public MainViewModel(ErrorHandlingService errorHandlingService, PluginController pluginController) 23 | { 24 | _errorHandlingService = errorHandlingService; 25 | _pluginController = pluginController; 26 | LoadPluginCommand = new DelegateCommand(LoadPlugin); 27 | CloseTabCommand = new DelegateCommand(CloseTab); 28 | 29 | _pluginController.LoadCatalogAcync() 30 | .ContinueWith( 31 | unusedTask =>{ AvailablePlugins = _pluginController.AvailablePlugins; }); 32 | } 33 | 34 | private IEnumerable _availablePlugins; 35 | public IEnumerable AvailablePlugins 36 | { 37 | get { return _availablePlugins; } 38 | set { _availablePlugins = value; RaisePropertyChanged("AvailablePlugins"); } 39 | } 40 | 41 | public ObservableCollection LoadedPlugins { get { return _pluginController.LoadedPlugins; } } 42 | 43 | private Plugin _selectedPlugin; 44 | public Plugin SelectedPlugin 45 | { 46 | get { return _selectedPlugin; } 47 | set { _selectedPlugin = value; RaisePropertyChanged("SelectedPlugin"); } 48 | } 49 | 50 | public ICommand LoadPluginCommand { get; private set; } 51 | public ICommand CloseTabCommand { get; private set; } 52 | 53 | public void Dispose() 54 | { 55 | _pluginController.Dispose(); 56 | } 57 | 58 | public bool CanClose() 59 | { 60 | var unsavedItems = _pluginController.GetUnsavedItems(); 61 | if (unsavedItems.Count == 0) return true; 62 | 63 | var sb = new StringBuilder(); 64 | 65 | sb.AppendLine("The following items are not saved:"); 66 | foreach (var data in unsavedItems) 67 | { 68 | sb.AppendLine("\t" + data.Key.Title + ":"); 69 | foreach (var item in data.Value) 70 | { 71 | sb.AppendLine("\t\t" + item); 72 | } 73 | } 74 | 75 | sb.AppendLine(); 76 | sb.Append("Are you sure you want to close the application and lose this data?"); 77 | return _errorHandlingService.Confirm(sb.ToString()); 78 | } 79 | 80 | #if CSHARP_45 81 | private async void LoadPlugin(PluginCatalogEntry catalogEntry) 82 | { 83 | try 84 | { 85 | var plugin = await _pluginController.LoadPluginAsync(catalogEntry); 86 | SelectedPlugin = plugin; 87 | } 88 | catch (Exception ex) 89 | { 90 | _errorHandlingService.ShowError("Error loading plugin", ex); 91 | } 92 | } 93 | #else 94 | private void LoadPlugin(PluginCatalogEntry catalogEntry) 95 | { 96 | 97 | var task = _pluginController.LoadPluginAsync(catalogEntry); 98 | var scheduler = TaskScheduler.FromCurrentSynchronizationContext(); 99 | task.ContinueWith(t => 100 | { 101 | try 102 | { 103 | SelectedPlugin = t.Result; 104 | } 105 | catch (Exception ex) 106 | { 107 | _errorHandlingService.ShowError("Error loading plugin", ex); 108 | } 109 | }, scheduler); 110 | } 111 | #endif 112 | 113 | private void CloseTab(Plugin plugin) 114 | { 115 | if (!CanClose(plugin)) return; 116 | 117 | bool changeSelection = (plugin == SelectedPlugin); 118 | int selectedIndex = LoadedPlugins.IndexOf(plugin); 119 | 120 | _pluginController.RemovePlugin(plugin); 121 | 122 | if (changeSelection) 123 | { 124 | int count = LoadedPlugins.Count; 125 | 126 | if (count == 0) 127 | { 128 | SelectedPlugin = null; 129 | } 130 | else 131 | { 132 | if (selectedIndex >= count) selectedIndex = count - 1; 133 | SelectedPlugin = LoadedPlugins[selectedIndex]; 134 | } 135 | } 136 | } 137 | 138 | private bool CanClose(Plugin plugin) 139 | { 140 | var unsavedItems = _pluginController.GetUnsavedItems(plugin); 141 | if (unsavedItems == null || unsavedItems.Length == 0) return true; 142 | 143 | var message = "The following items are not saved:\r\n" + 144 | String.Join("\r\n", unsavedItems) + "\r\n\r\n" + 145 | "Are you sure you want to close " + plugin.Title + "?"; 146 | 147 | return _errorHandlingService.Confirm(message); 148 | } 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /src/WpfHost/WpfHost/MainWindow.xaml: -------------------------------------------------------------------------------- 1 |  6 | 14 | 15 | 19 | 20 | 21 | 22 | 23 |