Browse Source

Added source assembly information to designer

Nikita Tsukanov 9 năm trước cách đây
mục cha
commit
2ec8ba3e12

+ 5 - 2
Avalonia.sln

@@ -1,6 +1,6 @@
 Microsoft Visual Studio Solution File, Format Version 12.00
 # Visual Studio 14
-VisualStudioVersion = 14.0.25123.0
+VisualStudioVersion = 14.0.24720.0
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Base", "src\Avalonia.Base\Avalonia.Base.csproj", "{B09B78D8-9B26-48B0-9149-D64A2F120F3F}"
 EndProject
@@ -15,6 +15,9 @@ EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Direct2D1", "src\Windows\Avalonia.Direct2D1\Avalonia.Direct2D1.csproj", "{3E908F67-5543-4879-A1DC-08EACE79B3CD}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Designer", "src\Windows\Avalonia.Designer\Avalonia.Designer.csproj", "{EC42600F-049B-43FF-AED1-8314D61B2749}"
+	ProjectSection(ProjectDependencies) = postProject
+		{2B888490-D14A-4BCA-AB4B-48676FA93C9B} = {2B888490-D14A-4BCA-AB4B-48676FA93C9B}
+	EndProjectSection
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Input", "src\Avalonia.Input\Avalonia.Input.csproj", "{62024B2D-53EB-4638-B26B-85EEAA54866E}"
 EndProject
@@ -156,7 +159,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.DesignerSupport.Te
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.DesignerSupport.TestApp", "tests\Avalonia.DesignerSupport.TestApp\Avalonia.DesignerSupport.TestApp.csproj", "{F1381F98-4D24-409A-A6C5-1C5B1E08BB08}"
 EndProject
-Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Aval+onia.RenderTests", "tests\Avalonia.RenderTests\Avalonia.RenderTests.shproj", "{48840EDD-24BF-495D-911E-2EB12AE75D3B}"
+Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Avalonia.RenderTests", "tests\Avalonia.RenderTests\Avalonia.RenderTests.shproj", "{48840EDD-24BF-495D-911E-2EB12AE75D3B}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VirtualizationTest", "samples\VirtualizationTest\VirtualizationTest.csproj", "{FBCAF3D0-2808-4934-8E96-3F607594517B}"
 EndProject

+ 44 - 8
src/Avalonia.DesignerSupport/DesignerApi.cs

@@ -7,33 +7,42 @@ using System.Threading.Tasks;
 
 namespace Avalonia.DesignerSupport
 {
-    class DesignerApi
+    class DesignerApiDictionary
     {
-        private readonly Dictionary<string, object> _inner;
+        public Dictionary<string, object> Dictionary { get; set; }
 
-        public DesignerApi(Dictionary<string, object> inner)
+        public DesignerApiDictionary(Dictionary<string, object> dictionary)
         {
-            _inner = inner;
+            Dictionary = dictionary;
         }
 
-        object Get([CallerMemberName] string name = null)
+        protected object Get([CallerMemberName] string name = null)
         {
             object rv;
-            _inner.TryGetValue(name, out rv);
+            Dictionary.TryGetValue(name, out rv);
             return rv;
         }
 
-        void Set(object value, [CallerMemberName] string name = null)
+        protected void Set(object value, [CallerMemberName] string name = null)
         {
-            _inner[name] = value;
+            Dictionary[name] = value;
         }
+    }
 
+    class DesignerApi : DesignerApiDictionary
+    {
         public Action<string> UpdateXaml
         {
             get { return (Action<string>) Get(); }
             set {Set(value); }
         }
 
+        public Action<Dictionary<string, object>> UpdateXaml2
+        {
+            get { return (Action<Dictionary<string, object>>)Get(); }
+            set { Set(value); }
+        }
+
         public Action OnResize
         {
             get { return (Action) Get(); }
@@ -52,5 +61,32 @@ namespace Avalonia.DesignerSupport
             get { return (Action<double>) Get(); }
         }
 
+        public DesignerApi(Dictionary<string, object> dictionary) : base(dictionary)
+        {
+        }
+    }
+
+    class DesignerApiXamlFileInfo : DesignerApiDictionary
+    {
+        public string Xaml
+        {
+            get { return (string)Get(); }
+            set { Set(value); }
+        }
+
+        public string AssemblyPath
+        {
+            get { return (string) Get(); }
+            set { Set(value); }
+        }
+
+        public DesignerApiXamlFileInfo(Dictionary<string, object> dictionary) : base(dictionary)
+        {
+        }
+
+        public DesignerApiXamlFileInfo(): base(new Dictionary<string, object>())
+        {
+            
+        }
     }
 }

+ 20 - 5
src/Avalonia.DesignerSupport/DesignerAssist.cs

@@ -36,7 +36,7 @@ namespace Avalonia.DesignerSupport
         public static void Init(Dictionary<string, object> shared)
         {
             Design.IsDesignMode = true;
-            Api = new DesignerApi(shared) {UpdateXaml = UpdateXaml, SetScalingFactor = SetScalingFactor};
+            Api = new DesignerApi(shared) {UpdateXaml = UpdateXaml, UpdateXaml2 = UpdateXaml2, SetScalingFactor = SetScalingFactor};
             var plat = (IPclPlatformWrapper) Activator.CreateInstance(Assembly.Load(new AssemblyName("Avalonia.Win32"))
                 .DefinedTypes.First(typeof (IPclPlatformWrapper).GetTypeInfo().IsAssignableFrom).AsType());
             
@@ -58,7 +58,6 @@ namespace Avalonia.DesignerSupport
                     //Ignore, Assembly.DefinedTypes threw an exception, we can't do anything about that
                 }
             }
-
             AppBuilder.Configure(app == null ? new DesignerApp() : (Application) Activator.CreateInstance(app.AsType()))
                 .UseWindowingSubsystem("Avalonia.Win32")
                 .UseRenderingSubsystem("Avalonia.Direct2D1")
@@ -74,17 +73,33 @@ namespace Avalonia.DesignerSupport
 
         static Window s_currentWindow;
 
-        private static void UpdateXaml(string xaml)
+        private static void UpdateXaml(string xaml) => UpdateXaml2(new DesignerApiXamlFileInfo
+        {
+            Xaml = xaml
+        }.Dictionary);
+
+        private static void UpdateXaml2(Dictionary<string, object> dic)
         {
+            var xamlInfo = new DesignerApiXamlFileInfo(dic);
             Window window;
             Control original;
 
             using (PlatformManager.DesignerMode())
             {
                 var loader = new AvaloniaXamlLoader();
-                var stream = new MemoryStream(Encoding.UTF8.GetBytes(xaml));
+                var stream = new MemoryStream(Encoding.UTF8.GetBytes(xamlInfo.Xaml));
+
+
+                
+                Uri baseUri = null;
+                if (xamlInfo.AssemblyPath != null)
+                {
+                    //Fabricate fake Uri
+                    baseUri =
+                        new Uri("resm:Fake.xaml?assembly=" + Path.GetFileNameWithoutExtension(xamlInfo.AssemblyPath));
+                }
 
-                original = (Control)loader.Load(stream);
+                original = (Control)loader.Load(stream, null, baseUri);
                 window = original as Window;
 
                 if (window == null)

+ 14 - 1
src/Windows/Avalonia.Designer/AppHost/AvaloniaAppHost.cs

@@ -21,6 +21,7 @@ namespace Avalonia.Designer.AppHost
         private readonly CommChannel _comm;
         private string _lastXaml;
         private string _currentXaml;
+        private string _currentSourceAssembly;
         private bool _initSuccess;
         private readonly HostedAppModel _appModel;
         private Control _window;
@@ -47,7 +48,10 @@ namespace Avalonia.Designer.AppHost
             }
             var updateXaml = obj as UpdateXamlMessage;
             if (updateXaml != null)
+            {
                 _currentXaml = updateXaml.Xaml;
+                _currentSourceAssembly = updateXaml.AssemblyPath;
+            }
         }
 
         void UpdateState(string state)
@@ -183,7 +187,16 @@ namespace Avalonia.Designer.AppHost
             }
             try
             {
-                Api.UpdateXaml(_currentXaml);
+                if (Api.UpdateXaml2 != null)
+                {
+                    Api.UpdateXaml2(new DesignerApiXamlFileInfo
+                    {
+                        AssemblyPath = _currentSourceAssembly,
+                        Xaml = _currentXaml
+                    }.Dictionary);
+                }
+                else
+                    Api.UpdateXaml(_currentXaml);
 
                 _appModel.SetError(null);
             }

+ 12 - 4
src/Windows/Avalonia.Designer/AvaloniaDesigner.xaml.cs

@@ -52,7 +52,15 @@ namespace Avalonia.Designer
             get { return (string) GetValue(XamlProperty); }
             set { SetValue(XamlProperty, value); }
         }
-        
+
+        public static readonly DependencyProperty SourceAssemblyProperty = DependencyProperty.Register(
+            "SourceAssembly", typeof (string), typeof (AvaloniaDesigner), new FrameworkPropertyMetadata(XamlChanged));
+
+        public string SourceAssembly
+        {
+            get { return (string) GetValue(SourceAssemblyProperty); }
+            set { SetValue(SourceAssemblyProperty, value); }
+        }
         
         private readonly ProcessHost _host = new ProcessHost();
         
@@ -117,7 +125,7 @@ namespace Avalonia.Designer
                 return;
             if(string.IsNullOrEmpty(Xaml))
                 return;
-            _host.Start(TargetExe, Xaml);
+            _host.Start(TargetExe, Xaml, SourceAssembly);
         }
 
         private void OnXamlChanged()
@@ -125,9 +133,9 @@ namespace Avalonia.Designer
             if (!CheckTargetExeOrSetError())
                 return;
             if (!_host.IsAlive)
-                _host.Start(TargetExe, Xaml);
+                _host.Start(TargetExe, Xaml, SourceAssembly);
             else
-                _host.UpdateXaml(Xaml ?? "");
+                _host.UpdateXaml(Xaml ?? "", SourceAssembly);
         }
 
     }

+ 1 - 1
src/Windows/Avalonia.Designer/Comm/InitMessage.cs

@@ -10,7 +10,7 @@ namespace Avalonia.Designer.Comm
     class InitMessage : UpdateXamlMessage
     {
         public string TargetExe { get; private set; }
-        public InitMessage(string targetExe, string xaml) : base(xaml)
+        public InitMessage(string targetExe, string xaml, string sourceAssembly) : base(xaml, sourceAssembly)
         {
             TargetExe = targetExe;
         }

+ 4 - 4
src/Windows/Avalonia.Designer/Comm/ProcessHost.cs

@@ -80,7 +80,7 @@ namespace Avalonia.Designer.Comm
             State = "Designer process crashed";
         }
 
-        public void Start(string targetExe, string initialXaml)
+        public void Start(string targetExe, string initialXaml, string sourceAssembly)
         {
             if (_proc != null)
             {
@@ -95,7 +95,7 @@ namespace Avalonia.Designer.Comm
                 State = "Restarting...";
             }
 
-            var msg = new InitMessage(Path.GetFullPath(targetExe), initialXaml);
+            var msg = new InitMessage(Path.GetFullPath(targetExe), initialXaml, sourceAssembly);
             var exe = typeof (ProcessHost).Assembly.GetModules()[0].FullyQualifiedName;
             _proc = new Process()
             {
@@ -128,9 +128,9 @@ namespace Avalonia.Designer.Comm
 
         }
 
-        public void UpdateXaml(string xaml)
+        public void UpdateXaml(string xaml, string sourceAssembly)
         {
-            _comm?.SendMessage(new UpdateXamlMessage(xaml));
+            _comm?.SendMessage(new UpdateXamlMessage(xaml, sourceAssembly));
         }
 
         private void OnMessage(object obj)

+ 3 - 1
src/Windows/Avalonia.Designer/Comm/UpdateXamlMessage.cs

@@ -9,11 +9,13 @@ namespace Avalonia.Designer.Comm
     [Serializable]
     class UpdateXamlMessage
     {
-        public UpdateXamlMessage(string xaml)
+        public UpdateXamlMessage(string xaml, string assemblyPath)
         {
             Xaml = xaml;
+            AssemblyPath = assemblyPath;
         }
 
         public string Xaml { get; private set; }
+        public string AssemblyPath { get; private set; }
     }
 }

+ 7 - 1
src/Windows/Avalonia.Designer/DemoWindow.xaml

@@ -14,10 +14,16 @@
             <Button Margin="5,0" DockPanel.Dock="Right" Click="RestartClicked">Restart</Button>
             <TextBlock x:Name="TargetExe"/>
         </DockPanel>
+        <DockPanel Dock="Bottom" LastChildFill="True" Margin="0,5">
+            <TextBlock Margin="5,0">Source Assembly:</TextBlock>
+            <Button DockPanel.Dock="Right" Click="SelectSourceClicked">Select Source Assembly</Button>
+            <TextBlock x:Name="SourceAssembly"/>
+        </DockPanel>
         <UniformGrid Columns="1" Rows="2">
             <local:AvaloniaDesigner x:Name="Designer"
                 TargetExe="{Binding ElementName=TargetExe, Path=Text, Mode=OneWay}"
-                Xaml="{Binding ElementName=Xaml, Path=Text, Mode=OneWay}"/>
+                Xaml="{Binding ElementName=Xaml, Path=Text, Mode=OneWay}"
+                                    SourceAssembly="{Binding ElementName=SourceAssembly, Path=Text, Mode=OneWay}"/>
             <TextBox x:Name="Xaml"/>
         </UniformGrid>
     </DockPanel>

+ 14 - 3
src/Windows/Avalonia.Designer/DemoWindow.xaml.cs

@@ -25,11 +25,15 @@ namespace Avalonia.Designer
             InitializeComponent();
         }
 
-        public DemoWindow(string targetExe, string targetPath) : this()
+        public DemoWindow(string targetExe, string targetPath, string sourceAssembly) : this()
         {
-            TargetExe.Text = targetExe;
-            if (targetExe != null)
+            
+            if (targetPath != null)
+            {
                 Xaml.Text = File.ReadAllText(targetPath);
+            }
+            SourceAssembly.Text = sourceAssembly ?? targetExe;
+            TargetExe.Text = targetExe;
         }
 
         static string OpenFile(string filter)
@@ -51,5 +55,12 @@ namespace Avalonia.Designer
         {
             Designer.RestartProcess();
         }
+
+        private void SelectSourceClicked(object sender, RoutedEventArgs e)
+        {
+            var exe = OpenFile("assembly|*.exe,*.dll");
+            if (exe != null)
+                SourceAssembly.Text = exe;
+        }
     }
 }

+ 4 - 2
src/Windows/Avalonia.Designer/Program.cs

@@ -58,10 +58,12 @@ namespace Avalonia.Designer
             var app =  new App();
             const string targetExe = "--exe=";
             const string xaml = "--xaml=";
-            
+            const string source = "--source=";
+
             app.Run(new DemoWindow(
                 args.Where(a => a.StartsWith(targetExe)).Select(a => a.Substring(targetExe.Length)).FirstOrDefault(),
-                args.Where(a => a.StartsWith(xaml)).Select(a => a.Substring(xaml.Length)).FirstOrDefault()));
+                args.Where(a => a.StartsWith(xaml)).Select(a => a.Substring(xaml.Length)).FirstOrDefault(),
+                args.Where(a => a.StartsWith(source)).Select(a => a.Substring(source.Length)).FirstOrDefault()));
         }
     }
 }