<?xml version="1.0"?>
<Border BorderWidth="1" Foreground="Grey" CornerRadius="{./CornerRadius}"
- Background="{./Background}"
- >
+ Background="{./Background}">
<VerticalStack Spacing="0">
<HorizontalStack Background="{./TitleBarBackground}"
Name="hs" Margin="0" Spacing="0" Height="Fit">
</Border>
<Widget Width="5"/>
</HorizontalStack>
- <Container Name="Content" MinimumSize="0,0" Margin="4"/>
+ <Container Name="Content" MinimumSize="0,0" />
</VerticalStack>
</Border>
Dimensions = sp.Dims;
return;
}
- using (Stream stream = Interface.StaticGetStreamFromPath (Path)) {
+ using (Stream stream = Interface.GetStreamFromPath (Path)) {
#if STB_SHARP
StbImageSharp.ImageResult stbi = StbImageSharp.ImageResult.FromStream (stream, StbImageSharp.ColorComponents.RedGreenBlueAlpha);
image = new byte [stbi.Data.Length];
Dimensions = sp.Dims;
return;
}
- using (Stream stream = Interface.StaticGetStreamFromPath (Path)) {
+ using (Stream stream = Interface.GetStreamFromPath (Path)) {
using (MemoryStream ms = new MemoryStream ()) {
stream.CopyTo (ms);
internal static MethodInfo miGetDataSource = typeof(Widget).GetProperty("DataSource").GetGetMethod ();
internal static EventInfo eiLogicalParentChanged = typeof(Widget).GetEvent("LogicalParentChanged");
- internal static MethodInfo miIFaceLoad = typeof(Interface).GetMethod ("CreateInstance", BindingFlags.Instance | BindingFlags.Public);
- internal static MethodInfo miIFaceCreateTemplateInst = typeof (Interface).GetMethod ("CreateTemplateInstance", BindingFlags.Instance | BindingFlags.Public);
+ internal static MethodInfo miIFaceCreateInstance = typeof(Interface).GetMethod ("CreateInstance", BindingFlags.Instance | BindingFlags.Public);
internal static MethodInfo miGetITemp = typeof(Interface).GetMethod ("GetItemTemplate", BindingFlags.Instance | BindingFlags.Public);
internal static MethodInfo miAddITemp = typeof(Dictionary<string, ItemTemplate>).GetMethod ("set_Item", new Type[] { typeof(string), typeof(ItemTemplate) });
/// <summary>
/// Initializes a new instance of the Instantiator class.
/// </summary>
- public Instantiator (Interface _iface, string path) : this (_iface, _iface.GetStreamFromPath(path), path) {
+ public Instantiator (Interface _iface, string path) : this (_iface, Interface.GetStreamFromPath(path), path) {
}
/// <summary>
itemTmpID += path+dataType+datas;
if (!iface.ItemTemplates.ContainsKey (itemTmpID))
iface.ItemTemplates [itemTmpID] =
- new ItemTemplate (iface, path, ctx.CurrentNodeType, dataTest, dataType, datas);
+ new ItemTemplate (iface, path, dataTest, dataType, datas);
}
return new string [] { dataType, itemTmpID, datas, dataTest };
}
if (!string.IsNullOrEmpty (templatePath)) {
ctx.il.Emit (OpCodes.Ldloc_0);//Load current templatedControl ref
- // ctx.il.Emit (OpCodes.Ldnull);//default template loading
- //} else {
ctx.il.Emit (OpCodes.Ldarg_1);//load currentInterface
ctx.il.Emit (OpCodes.Ldstr, templatePath); //Load template path string
- //get declaring type for search fallback assembly
- ctx.il.Emit (OpCodes.Ldloc_0);
- ctx.il.Emit (OpCodes.Call, CompilerServices.miGetType);
- ctx.il.Emit (OpCodes.Callvirt, CompilerServices.miIFaceCreateTemplateInst);
+ ctx.il.Emit (OpCodes.Callvirt, CompilerServices.miIFaceCreateInstance);
ctx.il.Emit (OpCodes.Callvirt, CompilerServices.miLoadTmp);//load template
}
}
if (iface.ItemTemplates.ContainsKey (itemTemplatePath)) {
itemTemplateIds.Add (new string [] { "default", itemTemplatePath, "" });
} else {
- using (Stream stream = iface.GetTemplateStreamFromPath (itemTemplatePath, ctx.CurrentNodeType)) {
+ using (Stream stream = Interface.GetStreamFromPath (itemTemplatePath)) {
//itemtemplate files may have multiple root nodes
XmlReaderSettings itrSettings = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment };
using (XmlReader itr = XmlReader.Create (stream, itrSettings)) {
//load itemTemplate
ctx.il.Emit (OpCodes.Ldarg_1);//load currentInterface
ctx.il.Emit (OpCodes.Ldstr, iTempId [1]);//load path
- //second arg is Type, to find assembly where to search if not in entry
- ctx.il.Emit (OpCodes.Ldloc_0);//load TempControl ref
- ctx.il.Emit (OpCodes.Call, CompilerServices.miGetType);
ctx.il.Emit (OpCodes.Callvirt, CompilerServices.miGetITemp);
ctx.il.Emit (OpCodes.Callvirt, CompilerServices.miAddITemp);
/// Than in any IML expresion, in style or xml, constant may be used as a replacement string with ${CONSTANTID}.
/// If a constant is not resolved in iml while creating the instantiator, an error is thrown.
/// </remarks>
- public readonly Dictionary<string, string> StylingConstants = new Dictionary<string, string> ();
+ public Dictionary<string, string> StylingConstants;
/// <summary> parse all styling data's during application startup and build global Styling Dictionary </summary>
protected virtual void loadStyling() {
+ StylingConstants = new Dictionary<string, string> ();
Styling = new Dictionary<string, Style> ();
//fetch styling info in this order, if member styling is alreadey referenced in previous
//assembly, it's ignored.
- loadStylingFromAssembly (Assembly.GetEntryAssembly ());
- loadStylingFromAssembly (Assembly.GetExecutingAssembly ());
+ loadStylingFromAssembly (Assembly.GetExecutingAssembly ());
foreach (Assembly a in crowAssemblies) {
loadStylingFromAssembly (a);
}
+ loadStylingFromAssembly (Assembly.GetEntryAssembly ());
}
/// <summary> Search for .style resources in assembly </summary>
protected void loadStylingFromAssembly (Assembly assembly) {
.GetManifestResourceNames ()
.Where (r => r.EndsWith (".style", StringComparison.OrdinalIgnoreCase))) {
using (StyleReader sr = new StyleReader (assembly.GetManifestResourceStream (s)))
- sr.Parse (this, s);
+ sr.Parse (this.StylingConstants, this.Styling, s);
}
}
#endregion
#region Load/Save
- /// <summary>get template stream from path providing the declaring type for which
- /// this template is loaded. If not found in entry assembly, the assembly where the type is defined
- /// will be searched
- /// </summary>
- /// <returns>The template stream</returns>
- public virtual Stream GetTemplateStreamFromPath (string path, Type declaringType)
- {
- Stream s = null;
- if (path.StartsWith ("#", StringComparison.Ordinal)) {
- string resId = path.Substring (1);
- s = Assembly.GetEntryAssembly ()?.GetManifestResourceStream (resId);
- if (s != null)
- return s;
- string assemblyName = resId.Split ('.')[0];
- Assembly a = AppDomain.CurrentDomain.GetAssemblies ().FirstOrDefault (aa => aa.GetName ().Name == assemblyName);
- s = a?.GetManifestResourceStream (resId);
- if (s != null)
- return s;
- s = Assembly.GetAssembly (declaringType).GetManifestResourceStream (resId);
- if (s == null)
- throw new Exception ($"Template ressource not found '{path}'");
- } else {
- if (!File.Exists (path))
- throw new FileNotFoundException ($"Template not found: {path}", path);
- s = new FileStream (path, FileMode.Open, FileAccess.Read);
- }
- return s;
+ static bool tryGetResource (Assembly a, string resId, out Stream stream) {
+ stream = null;
+ if (a == null)
+ return false;
+ stream = a.GetManifestResourceStream (resId);
+ return stream != null;
}
- /// <summary>Open file or find a resource from path string</summary>
- /// <returns>A file or resource stream</returns>
- /// <param name="path">This could be a normal file path, or an embedded ressource ID
- /// Resource ID's must be prefixed with '#' character</param>
- public virtual Stream GetStreamFromPath (string path)
- {
- Stream stream = null;
- if (path.StartsWith ("#", StringComparison.Ordinal)) {
- string resId = path.Substring (1);
- stream = Assembly.GetEntryAssembly ()?.GetManifestResourceStream (resId);
- if (stream != null)
- return stream;
- string assemblyName = resId.Split ('.') [0];
- Assembly a = AppDomain.CurrentDomain.GetAssemblies ().FirstOrDefault (aa => aa.GetName ().Name == assemblyName);
- if (a == null)
- throw new Exception ($"Assembly '{assemblyName}' not found for ressource '{path}'.");
- stream = a.GetManifestResourceStream (resId);
- if (stream == null)
- throw new Exception ("Resource not found: " + path);
- } else {
- if (!File.Exists (path))
- throw new FileNotFoundException ($"File not found: {path}", path);
- stream = new FileStream (path, FileMode.Open, FileAccess.Read);
- }
- return stream;
- }
- public static Stream StaticGetStreamFromPath (string path)
+ public static Stream GetStreamFromPath (string path)
{
- Stream stream = null;
-
if (path.StartsWith ("#", StringComparison.Ordinal)) {
+ Stream stream = null;
string resId = path.Substring (1);
- stream = Assembly.GetEntryAssembly ()?.GetManifestResourceStream (resId);
- if (stream != null)
+ if (tryGetResource (Assembly.GetEntryAssembly (), resId, out stream))
return stream;
- string assemblyName = resId.Split ('.') [0];
- Assembly a = AppDomain.CurrentDomain.GetAssemblies ().FirstOrDefault (aa => aa.GetName ().Name == assemblyName);
- if (a == null)
- throw new Exception ($"Assembly '{assemblyName}' not found for ressource '{path}'.");
- stream = a.GetManifestResourceStream (resId);
- /*foreach (var s in a.GetManifestResourceNames()) {
- System.Diagnostics.Debug.WriteLine (s);
- }*/
- if (stream == null)
- throw new Exception ("Resource not found: " + path);
- } else {
- if (!File.Exists (path))
- throw new FileNotFoundException ($"File not found: {path}", path);
- stream = new FileStream (path, FileMode.Open, FileAccess.Read);
- }
- return stream;
+ string[] assemblyNames = resId.Split ('.');
+ if (tryGetResource (AppDomain.CurrentDomain.GetAssemblies ()
+ .FirstOrDefault (aa => aa.GetName ().Name == assemblyNames[0]), resId, out stream))
+ return stream;
+ if (assemblyNames.Length > 3)
+ if (tryGetResource (AppDomain.CurrentDomain.GetAssemblies ()
+ .FirstOrDefault (aa => aa.GetName ().Name == $"{assemblyNames[0]}.{assemblyNames[1]}"), resId, out stream))
+ return stream;
+ foreach (Assembly ca in crowAssemblies)
+ if (tryGetResource (ca, resId, out stream))
+ return stream;
+ throw new Exception ("Resource not found: " + path);
+ }
+ if (!File.Exists (path))
+ throw new FileNotFoundException ($"File not found: {path}", path);
+ return new FileStream (path, FileMode.Open, FileAccess.Read);
}
/// <summary>
/// Add the content of the IML fragment to the graphic tree of this interface
/// <returns>new instance of graphic object created</returns>
/// <param name="path">path of the iml file to load</param>
public virtual Widget CreateInstance (string path)
- {
- //try {
- return GetInstantiator (path).CreateInstance ();
- //} catch (Exception ex) {
- // throw new Exception ("Error loading <" + path + ">:", ex);
- //}
- }
- /// <summary>
- /// Create an instance of a GraphicObject linked to this interface but not added to the GraphicTree
- /// </summary>
- /// <returns>new instance of graphic object created</returns>
- /// <param name="path">path of the iml file to load</param>
- public virtual Widget CreateTemplateInstance (string path, Type declaringType)
- {
-// try {
- if (!Templates.ContainsKey (path))
- Templates [path] = new Instantiator (this, GetTemplateStreamFromPath(path, declaringType), path);
- return Templates [path].CreateInstance ();
- //} catch (Exception ex) {
- // throw new Exception ("Error loading Template <" + path + ">:", ex);
- //}
- }
+ => GetInstantiator (path).CreateInstance ();
/// <summary>
/// Fetch instantiator from cache or create it.
/// </summary>
/// try to fetch the requested one in the cache or create it.
/// They have additional properties for recursivity and
/// custom display per item type</summary>
- public virtual ItemTemplate GetItemTemplate(string path, Type declaringType){
+ public virtual ItemTemplate GetItemTemplate(string path){
if (!ItemTemplates.ContainsKey(path))
- ItemTemplates [path] = new ItemTemplate(this, path, declaringType);
+ ItemTemplates [path] = new ItemTemplate(this, path);
return ItemTemplates [path] as ItemTemplate;
}
#endregion
/// <param name="path">IML file to parse</param>
/// <param name="_dataType">type this item will be choosen for, or member of the data item</param>
/// <param name="_fetchDataMethod">for hierarchical data, method to call for children fetching</param>
- public ItemTemplate (Interface _iface, string path, Type declaringType, string _dataTest = "TypeOf", string _dataType = "default", string _fetchDataMethod = null)
- : base(_iface, _iface.GetTemplateStreamFromPath (path, declaringType)) {
+ public ItemTemplate (Interface _iface, string path, string _dataTest = "TypeOf", string _dataType = "default", string _fetchDataMethod = null)
+ : base(_iface, Interface.GetStreamFromPath (path)) {
strDataType = _dataType;
fetchMethodName = _fetchDataMethod;
dataTest = _dataTest;
if (string.IsNullOrEmpty(_template))
loadTemplate ();
else
- loadTemplate (IFace.CreateTemplateInstance (_template, this.GetType()));
+ loadTemplate (IFace.CreateInstance (_template));
}
}
/// <summary>
public static XCursorFile Load(string path)
{
- return loadFromStream (Interface.StaticGetStreamFromPath (path));
+ return loadFromStream (Interface.GetStreamFromPath (path));
}
static XCursor imageLoad (BinaryReader sr)
/// Parse the full style stream and load the result in 'Styling' and 'StylingConstant'
/// fields of the interface passed as argument.
/// </summary>
- /// <param name="iFace">the Interface to load the style for</param>
- public void Parse (Interface iFace, string resId)
+ public void Parse (Dictionary<string, string> StylingConstants, Dictionary<string, Style> Styling, string resId)
{
column = 1;
line = 1;
break;
constantId += c;
}
- if (string.IsNullOrEmpty (constantId) || !iFace.StylingConstants.ContainsKey (constantId))
+ if (string.IsNullOrEmpty (constantId) || !StylingConstants.ContainsKey (constantId))
throw new ParserException (line, column, "Empty constant id in styling", resId);
- token += iFace.StylingConstants [constantId];
+ token += StylingConstants [constantId];
continue;
}
} else if (c == '\"') {
ReadChar ();
if (targetsClasses.Count == 0) {
//style constants
- iFace.StylingConstants[currentProperty] = token;
+ StylingConstants[currentProperty] = token;
curState = States.classNames;
} else {
foreach (string tc in targetsClasses) {
- if (!iFace.Styling.ContainsKey (tc))
- iFace.Styling [tc] = new Style ();
- iFace.Styling [tc] [currentProperty] = token;
+ if (!Styling.ContainsKey (tc))
+ Styling [tc] = new Style ();
+ Styling [tc] [currentProperty] = token;
#if DESIGN_MODE
- iFace.Styling [tc].Locations[currentProperty] = new FileLocation(resId, line, column - token.Length - 1, token.Length);
+ Styling [tc].Locations[currentProperty] = new FileLocation(resId, line, column - token.Length - 1, token.Length);
#endif
}
curState = States.members;
namespace ShowCase
{
- class Showcase : Interface
+ class Showcase : SampleBase
{
-
static void Main ()
{
#if NETCOREAPP3_1
public Container crowContainer;
+ public string CurrentDir {
+ get { return Configuration.Global.Get<string> ("CurrentDir"); }
+ set {
+ if (CurrentDir == value)
+ return;
+ Configuration.Global.Set ("CurrentDir", value);
+ NotifyValueChanged ("CurrentDir",CurrentDir);
+ }
+ }
+
protected override void OnInitialized ()
{
+ if (string.IsNullOrEmpty (CurrentDir))
+ CurrentDir = Path.Combine (Directory.GetCurrentDirectory (), "Interfaces");
Widget g = Load ("#ShowCase.showcase.crow");
g.DataSource = this;
crowContainer = g.FindByName ("CrowContainer") as Container;
#endif
}
- public Showcase ()
- : base (1024, 800)
- {
- }
-
-
void Dv_SelectedItemChanged (object sender, SelectionChangeEventArgs e)
{
FileSystemInfo fi = e.NewValue as FileSystemInfo;
return;
if (fi is DirectoryInfo)
return;
- hideError ();
- lock (UpdateMutex) {
- try {
- Widget g = CreateInstance (fi.FullName);
- crowContainer.SetChild (g);
- g.DataSource = this;
- } catch (Exception ex) {
- Console.WriteLine (ex.ToString ());
- showError (ex);
- }
- }
string source = "";
using (Stream s = new FileStream (fi.FullName, FileMode.Open)) {
- using (StreamReader sr = new StreamReader (s)) {
+ using (StreamReader sr = new StreamReader (s))
source = sr.ReadToEnd ();
- }
}
NotifyValueChanged ("source", source);
}
crowContainer.SetChild (g);
g.DataSource = this;
}
+ } catch (InstantiatorException itorex) {
+ Console.WriteLine (itorex.ToString ());
+ showError (itorex.InnerException);
} catch (Exception ex) {
- Console.WriteLine (ex.ToString ());
- showError ((Exception)ex);
+ Console.WriteLine (ex);
+ showError (ex);
}
}
</Menu>
<HorizontalStack Height="Fit">
<Label Text="Hover:" Width="50" Foreground="Grey"/>
- <Label Text="{HoverWidget}"/>
+ <Label Text="{HoverWidget}" Font="mono, 8"/>
</HorizontalStack>
<HorizontalStack Height="Fit">
<Label Text="Focus:" Width="50" Foreground="Grey"/>
- <Label Text="{FocusedWidget}"/>
+ <Label Text="{FocusedWidget}" Font="mono, 8"/>
</HorizontalStack>
<HorizontalStack Height="Fit">
<Label Text="Active:" Width="50" Foreground="Grey"/>
- <Label Text="{ActiveWidget}"/>
+ <Label Text="{ActiveWidget}" Font="mono, 8"/>
</HorizontalStack>
<Container Fit="true" Margin="50" Background="SlateGrey">
<Label Text="MouseEvents" Margin="3" Focusable="true" Fit="true"