Browse Source

Fixed #282

pull/386/head
Nikita Tsukanov 11 years ago
parent
commit
81f1bf51a8
  1. 4
      src/Markup/Perspex.Markup.Xaml/PerspexXamlLoader.cs
  2. 56
      src/Perspex.Themes.Default/DefaultTheme.paml
  3. 103
      src/Shared/PlatformSupport/AssetLoader.cs

4
src/Markup/Perspex.Markup.Xaml/PerspexXamlLoader.cs

@ -108,8 +108,8 @@ namespace Perspex.Markup.Xaml
{
var asm = type.GetTypeInfo().Assembly.GetName().Name;
var typeName = type.FullName;
yield return new Uri("resource://application/" + asm + "/" + typeName + ".xaml");
yield return new Uri("resource://application/" + asm + "/" + typeName + ".paml");
yield return new Uri("resm:" + typeName + ".xaml?assembly=" + asm);
yield return new Uri("resm:" + typeName + ".paml?assembly=" + asm);
}
}

56
src/Perspex.Themes.Default/DefaultTheme.paml

@ -1,30 +1,30 @@
<Styles xmlns="https://github.com/perspex">
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.FocusAdorner.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.Button.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.Carousel.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.CheckBox.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.ContentControl.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.DropDown.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.GridSplitter.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.ItemsControl.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.ListBox.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.ListBoxItem.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.Menu.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.MenuItem.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.PopupRoot.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.ProgressBar.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.RadioButton.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.Separator.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.ScrollBar.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.ScrollViewer.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.TabControl.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.TabStrip.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.TabStripItem.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.TextBox.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.ToggleButton.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.Expander.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.ToolTip.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.TreeView.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.TreeViewItem.paml"/>
<StyleInclude Source="resource://application/Perspex.Themes.Default/Perspex.Themes.Default.Window.paml"/>
<StyleInclude Source="resm:Perspex.Themes.Default.FocusAdorner.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.Button.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.Carousel.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.CheckBox.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.ContentControl.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.DropDown.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.GridSplitter.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.ItemsControl.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.ListBox.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.ListBoxItem.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.Menu.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.MenuItem.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.PopupRoot.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.ProgressBar.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.RadioButton.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.Separator.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.ScrollBar.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.ScrollViewer.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.TabControl.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.TabStrip.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.TabStripItem.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.TextBox.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.ToggleButton.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.Expander.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.ToolTip.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.TreeView.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.TreeViewItem.paml?assembly=Perspex.Themes.Default"/>
<StyleInclude Source="resm:Perspex.Themes.Default.Window.paml?assembly=Perspex.Themes.Default"/>
</Styles>

103
src/Shared/PlatformSupport/AssetLoader.cs

@ -15,26 +15,93 @@ namespace Perspex.Shared.PlatformSupport
/// </summary>
public class AssetLoader : IAssetLoader
{
private static readonly Dictionary<string, Assembly> AssemblyNameCache
= new Dictionary<string, Assembly>();
class AssemblyDescriptor
{
public AssemblyDescriptor(Assembly assembly)
{
Assembly = assembly;
Resources = assembly.GetManifestResourceNames()
.ToDictionary(n => n, n => (IAssetDescriptor)new AssemblyResourceDescriptor(assembly, n));
Name = assembly.GetName().Name;
}
public Assembly Assembly { get; }
public Dictionary<string, IAssetDescriptor> Resources { get; }
public string Name { get; }
}
private readonly Assembly _defaultAssembly;
private static readonly Dictionary<string, AssemblyDescriptor> AssemblyNameCache
= new Dictionary<string, AssemblyDescriptor>();
private readonly AssemblyDescriptor _defaultAssembly;
public AssetLoader(Assembly assembly = null)
{
_defaultAssembly = assembly;
if (assembly == null)
assembly = Assembly.GetEntryAssembly();
_defaultAssembly = new AssemblyDescriptor(assembly);
}
static Assembly GetAssembly(string name)
AssemblyDescriptor GetAssembly(string name)
{
Assembly rv;
if (name == null)
return _defaultAssembly;
AssemblyDescriptor rv;
if (!AssemblyNameCache.TryGetValue(name, out rv))
AssemblyNameCache[name] = rv =
AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.GetName().Name == name)
?? Assembly.Load(name);
new AssemblyDescriptor(AppDomain.CurrentDomain.GetAssemblies()
.FirstOrDefault(a => a.GetName().Name == name)
?? Assembly.Load(name));
return rv;
}
interface IAssetDescriptor
{
Stream GetStream();
}
class AssemblyResourceDescriptor : IAssetDescriptor
{
private readonly Assembly _asm;
private readonly string _name;
public AssemblyResourceDescriptor(Assembly asm, string name)
{
_asm = asm;
_name = name;
}
public Stream GetStream()
{
return _asm.GetManifestResourceStream(_name);
}
}
IAssetDescriptor GetAsset(Uri uri)
{
if (!uri.IsAbsoluteUri || uri.Scheme == "resm")
{
var qs = uri.Query.TrimStart('?')
.Split('&')
.Select(p => p.Split('='))
.ToDictionary(p => p[0], p => p[1]);
//TODO: Replace _defaultAssembly by current one (need support from OmniXAML)
var asm = _defaultAssembly;
if (qs.ContainsKey("assembly"))
asm = GetAssembly(qs["assembly"]);
IAssetDescriptor rv;
asm.Resources.TryGetValue(uri.AbsolutePath, out rv);
return rv;
}
throw new ArgumentException($"Invalid uri, see https://github.com/Perspex/Perspex/issues/282#issuecomment-166982104", nameof(uri));
}
/// <summary>
/// Checks if an asset with the specified URI exists.
/// </summary>
@ -42,11 +109,7 @@ namespace Perspex.Shared.PlatformSupport
/// <returns>True if the asset could be found; otherwise false.</returns>
public bool Exists(Uri uri)
{
var parts = uri.AbsolutePath.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
var asm = parts.Length == 1 ? (_defaultAssembly ?? Assembly.GetEntryAssembly()) : GetAssembly(parts[0]);
var typeName = parts[parts.Length == 1 ? 0 : 1];
var rv = asm.GetManifestResourceStream(typeName);
return rv != null;
return GetAsset(uri) != null;
}
/// <summary>
@ -59,18 +122,10 @@ namespace Perspex.Shared.PlatformSupport
/// </exception>
public Stream Open(Uri uri)
{
var parts = uri.AbsolutePath.Split(new[] {'/'}, StringSplitOptions.RemoveEmptyEntries);
var asm = parts.Length == 1 ? (_defaultAssembly ?? Assembly.GetEntryAssembly()) : GetAssembly(parts[0]);
var typeName = parts[parts.Length == 1 ? 0 : 1];
var rv = asm.GetManifestResourceStream(typeName);
if (rv == null)
{
#if DEBUG
var names = asm.GetManifestResourceNames().ToList();
#endif
var asset = GetAsset(uri);
if (asset == null)
throw new FileNotFoundException($"The resource {uri} could not be found.");
}
return rv;
return asset.GetStream();
}
}
}

Loading…
Cancel
Save