A cross-platform UI framework for .NET
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

157 lines
5.9 KiB

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using OmniXaml;
using OmniXaml.ObjectAssembler;
using Avalonia.Controls;
using Avalonia.Controls.Platform;
using Avalonia.Markup.Xaml;
using Avalonia.Platform;
using Avalonia.Styling;
using Avalonia.Themes.Default;
namespace Avalonia.DesignerSupport
{
class DesignerAssist
{
class DesignerApp : Application
{
public override void Initialize()
{
Styles.Add(new DefaultTheme());
var loader = new AvaloniaXamlLoader();
var baseLight = (IStyle)loader.Load(
new Uri("resm:Avalonia.Themes.Default.Accents.BaseLight.xaml?assembly=Avalonia.Themes.Default"));
Styles.Add(baseLight);
}
}
public static DesignerApi Api { get; set; }
public static void Init(Dictionary<string, object> shared)
{
Design.IsDesignMode = true;
Api = new DesignerApi(shared) {UpdateXaml = UpdateXaml, UpdateXaml2 = UpdateXaml2, SetScalingFactor = SetScalingFactor};
var runtimeAssembly = Assembly.Load(new AssemblyName("Avalonia.DotNetFrameworkRuntime"));
var plat = (IRuntimePlatform) Activator.CreateInstance(runtimeAssembly
.DefinedTypes.First(typeof (IRuntimePlatform).GetTypeInfo().IsAssignableFrom).AsType());
TypeInfo app = null;
var asms = plat.GetLoadedAssemblies();
foreach (var asm in asms)
{
if(Equals(asm, typeof(Application).GetTypeInfo().Assembly) || Equals(asm, typeof(DesignerApp).GetTypeInfo().Assembly))
continue;
try
{
app = asm.DefinedTypes.Where(typeof (Application).GetTypeInfo().IsAssignableFrom).FirstOrDefault();
if (app != null)
break;
}
catch
{
//Ignore, Assembly.DefinedTypes threw an exception, we can't do anything about that
}
}
var builderType = runtimeAssembly.GetType("Avalonia.AppBuilder");
var builder = (dynamic)Activator.CreateInstance(builderType,
app == null ? new DesignerApp() : (Application) Activator.CreateInstance(app.AsType()));
builder
.UseWindowingSubsystem("Avalonia.Win32")
.UseRenderingSubsystem("Avalonia.Direct2D1")
.SetupWithoutStarting();
}
private static void SetScalingFactor(double factor)
{
PlatformManager.SetDesignerScalingFactor(factor);
if (s_currentWindow != null)
s_currentWindow.PlatformImpl.ClientSize = s_currentWindow.ClientSize;
}
static Window s_currentWindow;
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 control;
using (PlatformManager.DesignerMode())
{
var loader = new AvaloniaXamlLoader();
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));
}
var loaded = loader.Load(stream, null, baseUri);
var styles = loaded as Styles;
if (styles != null)
{
var substitute = Design.GetPreviewWith(styles) ??
styles.Select(Design.GetPreviewWith).FirstOrDefault(s => s != null);
if (substitute != null)
{
substitute.Styles.AddRange(styles);
control = substitute;
}
else
control = new StackPanel
{
Children =
{
new TextBlock {Text = "Styles can't be previewed without Design.PreviewWith. Add"},
new TextBlock {Text = "<Design.PreviewWith>"},
new TextBlock {Text = " <Border Padding=20><!-- YOUR CONTROL FOR PREVIEW HERE--></Border>"},
new TextBlock {Text = "<Design.PreviewWith>"},
new TextBlock {Text = "before setters in your first Style"}
}
};
}
if (loaded is Application)
control = new TextBlock {Text = "Application can't be previewed in design view"};
else
control = (Control) loaded;
window = control as Window;
if (window == null)
{
window = new Window() {Content = (Control)control};
}
if (!window.IsSet(Window.SizeToContentProperty))
window.SizeToContent = SizeToContent.WidthAndHeight;
}
s_currentWindow?.Close();
s_currentWindow = window;
window.Show();
Design.ApplyDesignerProperties(window, control);
Api.OnWindowCreated?.Invoke(window.PlatformImpl.Handle.Handle);
Api.OnResize?.Invoke();
}
}
}