<ItemGroup>
<Folder Include="src\GraphicObjects\" />
<Folder Include="src\Cairo\" />
- <Folder Include="src\win32\" />
<Folder Include="Images\" />
<Folder Include="Images\Icons\" />
<Folder Include="src\CompilerServices\" />
// THE SOFTWARE.
using System;
-using System.Xml.Serialization;
using System.ComponentModel;
using System.IO;
using System.Xml;
-using System.Diagnostics;
-using System.Linq;
-using System.Collections.Generic;
-using System.Text;
using System.Reflection;
using Cairo;
{
#if DESIGN_MODE
public bool design_inlineTemplate = false;
- public override void getIML (System.Xml.XmlDocument doc, System.Xml.XmlNode parentElem)
+ public override void getIML (XmlDocument doc, XmlNode parentElem)
{
if (this.design_isTGItem)
return;
parentElem.LastChild.AppendChild (xe);
}
#endif
+
#region CTOR
protected TemplatedControl() : base(){}
public TemplatedControl (Interface iface) : base(iface){}
/// </summary>
/// <returns>widget identified by name, or null if not found</returns>
/// <param name="nameToFind">widget's name to find</param>
- public override GraphicObject FindByName (string nameToFind)
- {
- //prevent name searching in template
- return nameToFind == this.Name ? this : null;
- }
+ public override GraphicObject FindByName (string nameToFind) => nameToFind == this.Name ? this : null;
+
/// <summary>
///onDraw is overrided to prevent default drawing of background, template top container
///may have a binding to root background or a fixed one.
#endregion
/// <summary>
- /// Loads the template.
+ /// Loads the template. Each TemplatedControl MUST provide a default template
+ /// It must be an embedded ressource with ID = fullTypeName.template
+ /// Entry assembly is search first, then the one where the type is defined
/// </summary>
/// <param name="template">Optional template instance</param>
protected virtual void loadTemplate(GraphicObject template = null)
this.ClearTemplateBinding();
if (template == null) {
- if (!IFace.DefaultTemplates.ContainsKey (this.GetType ().FullName))
- throw new Exception (string.Format ("No default template found for '{0}'", this.GetType ().FullName));
- this.SetChild (IFace.CreateInstance (IFace.DefaultTemplates[this.GetType ().FullName]));
+ int mdTok = this.GetType ().MetadataToken;
+
+ if (!IFace.DefaultTemplates.ContainsKey (mdTok)) {
+ string defTmpId = this.GetType ().FullName + ".template";
+ Stream s = Assembly.GetEntryAssembly ().GetManifestResourceStream (defTmpId);
+ if (s == null)
+ s = Assembly.GetAssembly (this.GetType ()).GetManifestResourceStream (defTmpId);
+ if (s == null)
+ throw new Exception (string.Format ("No default template found for '{0}'", this.GetType ().FullName));
+ IFace.DefaultTemplates [mdTok] = new IML.Instantiator (IFace, s, defTmpId);
+ }
+ this.SetChild (IFace.DefaultTemplates[mdTok].CreateInstance());
}else
this.SetChild (template);
}
#region Templating
//TODO: dont instantiate ItemTemplates if not used
//but then i should test if null in msil gen
- public Dictionary<string, ItemTemplate> ItemTemplates = new Dictionary<string, Crow.ItemTemplate>();
+ public Dictionary<string, ItemTemplate> ItemTemplates = new Dictionary<string, ItemTemplate>();
/// <summary>
/// Keep track of expanded subnodes and closed time to unload
/// ItemTemplate file may contains either a single template without the
/// ItemTemplate enclosing tag, or several item templates each enclosed
/// in a separate tag.
- /// </summary>
-
+ /// </summary>
public string ItemTemplate {
get { return _itemTemplate; }
set {
// THE SOFTWARE.
using System;
-using System.Threading;
using System.IO;
using System.Text;
using System.Diagnostics;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
-using Crow.IML;
namespace Crow.IML
{
using (XmlReader itr = XmlReader.Create (stream)) {
parseIML (itr);
}
- stream.Dispose ();
} catch (Exception ex) {
throw new InstantiatorException(sourcePath, ex);
} finally {
- #if DEBUG_LOAD
+ stream?.Dispose ();
+#if DEBUG_LOAD
loadingTime.Stop ();
using (StreamWriter sw = new StreamWriter ("loading.log", true)) {
sw.WriteLine ($"ITOR;{sourcePath,-50};{loadingTime.ElapsedTicks,8};{loadingTime.ElapsedMilliseconds,8}");
}
- #endif
+#endif
}
}
/// <summary>
/// <returns>the string triplet dataType, itemTmpID read as attribute of this tag</returns>
/// <param name="reader">current xml text reader</param>
/// <param name="itemTemplatePath">file containing the templates if its a dedicated one</param>
- string[] parseItemTemplateTag (XmlReader reader, string itemTemplatePath = "") {
+ string[] parseItemTemplateTag (IMLContext ctx, XmlReader reader, string itemTemplatePath = "") {
string dataType = "default", datas = "", path = "", dataTest = "TypeOf";
while (reader.MoveToNextAttribute ()) {
if (reader.Name == "DataType")
if (string.IsNullOrEmpty (path)) {
itemTmpID += Guid.NewGuid ().ToString ();
- iface.Instantiators [itemTmpID] =
+ iface.ItemTemplates [itemTmpID] =
new ItemTemplate (iface, new MemoryStream (Encoding.UTF8.GetBytes (reader.ReadInnerXml ())), dataTest, dataType, datas);
} else {
if (!reader.IsEmptyElement)
throw new Exception ("ItemTemplate with Path attribute set may not include sub nodes");
itemTmpID += path+dataType+datas;
- if (!iface.Instantiators.ContainsKey (itemTmpID))
- iface.Instantiators [itemTmpID] =
- new ItemTemplate (iface, path, dataTest, dataType, datas);
+ if (!iface.ItemTemplates.ContainsKey (itemTmpID))
+ iface.ItemTemplates [itemTmpID] =
+ new ItemTemplate (iface, path, ctx.CurrentNodeType, dataTest, dataType, datas);
}
return new string [] { dataType, itemTmpID, datas, dataTest };
}
reader.Read ();
readChildren (reader, ctx, -1);
} else if (reader.Name == "ItemTemplate")
- itemTemplateIds.Add (parseItemTemplateTag (reader));
+ itemTemplateIds.Add (parseItemTemplateTag (ctx, reader));
}
if (!inlineTemplate) {//load from path or default template
//try to load ItemTemplate(s) from ItemTemplate attribute of TemplatedGroup
if (!string.IsNullOrEmpty (itemTemplatePath)) {
//check if it is already loaded in cache as a single itemTemplate instantiator
- if (iface.Instantiators.ContainsKey (itemTemplatePath)) {
+ if (iface.ItemTemplates.ContainsKey (itemTemplatePath)) {
itemTemplateIds.Add (new string [] { "default", itemTemplatePath, "" });
} else {
using (Stream stream = iface.GetStreamFromPath (itemTemplatePath)) {
//itemtemplate files may have multiple root nodes
- if (stream == null)
- Debugger.Break ();
XmlReaderSettings itrSettings = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment };
using (XmlReader itr = XmlReader.Create (stream, itrSettings)) {
while (itr.Read ()) {
if (itr.NodeType == XmlNodeType.Element) {
if (itr.Name != "ItemTemplate") {
//the file contains a single template to use as default
- iface.Instantiators [itemTemplatePath] =
+ iface.ItemTemplates [itemTemplatePath] =
new ItemTemplate (iface, itr);
itemTemplateIds.Add (new string [] { "default", itemTemplatePath, "", "TypeOf" });
break;//we should be at the end of the file
}
- itemTemplateIds.Add (parseItemTemplateTag (itr, itemTemplatePath));
+ itemTemplateIds.Add (parseItemTemplateTag (ctx, itr, itemTemplatePath));
}
}
}
//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);
typeof (void),
CompilerServices.argsBoundValueChange, true);
- il = dm.GetILGenerator (256);
+ il = dm.GetILGenerator (32);
System.Reflection.Emit.Label endMethod = il.DefineLabel ();
typeof (void),
CompilerServices.argsBoundDSChange, true);
- il = dm.GetILGenerator (256);
+ il = dm.GetILGenerator (64);
il.DeclareLocal (typeof(object));//used for checking propery less bindings
il.DeclareLocal (typeof(MemberInfo));//used for checking propery less bindings
emitRemoveOldDataSourceHandler (il, "ValueChanged", delName, true);
if (!string.IsNullOrEmpty(bindingDef.TargetMember)){
- if (bindingDef.TwoWay){
-// System.Reflection.Emit.Label cancelRemove = il.DefineLabel ();
-// //remove handler if not null
-// il.Emit (OpCodes.Ldarg_2);//load old parent
-// il.Emit (OpCodes.Ldfld, CompilerServices.fiDSCOldDS);
-// il.Emit (OpCodes.Brfalse, cancelRemove);//old parent is null
-
- //remove handler
+ if (bindingDef.TwoWay)//remove handler
emitRemoveOldDataSourceHandler(il, "ValueChanged", delName, false);
-// il.Emit (OpCodes.Ldarg_1);//3d arg: instance bound to delegate (the source)
-// il.Emit (OpCodes.Ldstr, "ValueChanged");//2nd arg event name
-// il.Emit (OpCodes.Ldarg_2);//1st arg load old datasource
-// il.Emit (OpCodes.Ldfld, CompilerServices.fiDSCOldDS);
-// il.Emit (OpCodes.Call, CompilerServices.miRemEvtHdlByTarget);
-// il.MarkLabel(cancelRemove);
- }
il.Emit (OpCodes.Ldloc_2);
il.Emit (OpCodes.Brfalse, newDSIsNull);//new ds is null
}
System.Reflection.Emit.Label endMethod = il.DefineLabel ();
- il.DeclareLocal (typeof(object));
il.Emit (OpCodes.Nop);
//load value changed member name onto the stack
il.Emit (OpCodes.Ldarg_2);
il.Emit (OpCodes.Ldfld, CompilerServices.fiVCNewValue);
- CompilerServices.emitConvert (il, piOrig.PropertyType, piDest.PropertyType);
+ //if (piOrig.PropertyType != piDest.PropertyType)
+ CompilerServices.emitConvert (il, piOrig.PropertyType, piDest.PropertyType);
il.Emit (OpCodes.Callvirt, piDest.GetSetMethod ());
{
while (running) {
Update ();
- Thread.Sleep (20);
+ Thread.Sleep (1);
}
}
CurrentInterface = this;
//loadCursors ();
loadStyling ();
- findAvailableTemplates ();
#if MEASURE_TIME
PerfMeasures.Add (updateMeasure);
/// on the first instance creation of a IML item.
/// </summary>
public Dictionary<String, Instantiator> Instantiators = new Dictionary<string, Instantiator>();
+ /// <summary>
+ /// default templates dic by metadata token
+ /// </summary>
+ public Dictionary<int, Instantiator> DefaultTemplates = new Dictionary<int, Instantiator> ();
+ /// <summary>
+ /// Item templates stored with their index
+ /// </summary>
+ public Dictionary<String, ItemTemplate> ItemTemplates = new Dictionary<string, ItemTemplate> ();
+
public List<CrowThread> CrowThreads = new List<CrowThread>();//used to monitor thread finished
public DragDropEventArgs DragAndDropOperation = null;
#endregion
- #region Templates
- /// <summary>Store one default templates resource ID per class.
- /// Resource ID must be 'fullClassName.template' (not case sensitive)
- /// Those found in application assembly have priority to the default Crow's one
- /// </summary>
- public Dictionary<string, string> DefaultTemplates;
- /// <summary>Finds available default templates at startup</summary>
- void findAvailableTemplates(){
- DefaultTemplates = new Dictionary<string, string>();
- searchTemplatesOnDisk ("./");
- string defTemplatePath = System.IO.Path.Combine (CrowConfigRoot, "defaultTemplates");
- searchTemplatesOnDisk (defTemplatePath);
- searchTemplatesIn (Assembly.GetEntryAssembly ());
- searchTemplatesIn (Assembly.GetExecutingAssembly ());
- }
- void searchTemplatesOnDisk (string templatePath){
- if (!Directory.Exists (templatePath))
- return;
- foreach (string f in Directory.GetFiles(templatePath, "*.template",SearchOption.AllDirectories)) {
- string clsName = System.IO.Path.GetFileNameWithoutExtension(f);
- if (DefaultTemplates.ContainsKey (clsName))
- continue;
- DefaultTemplates [clsName] = f;
- }
- }
- void searchTemplatesIn(Assembly assembly){
- if (assembly == null)
- return;
- foreach (string resId in assembly
- .GetManifestResourceNames ()
- .Where (r => r.EndsWith (".template", StringComparison.OrdinalIgnoreCase))) {
- string clsName = resId.Substring (0, resId.Length - 9);
- if (DefaultTemplates.ContainsKey (clsName))
- continue;
- DefaultTemplates[clsName] = "#" + resId;
- }
- }
- #endregion
#region Load/Save
/// <summary>Open file or find a resource from path string</summary>
if (path.StartsWith ("#", StringComparison.Ordinal)) {
string resId = path.Substring (1);
//try/catch added to prevent nunit error
- try {
- stream = Assembly.GetEntryAssembly ().GetManifestResourceStream (resId);
- } catch{}
+ stream = Assembly.GetEntryAssembly ().GetManifestResourceStream (resId);
if (stream == null)//try to find ressource in Crow assembly
stream = Assembly.GetExecutingAssembly ().GetManifestResourceStream (resId);
if (stream == null)
throw new Exception("Resource not found: " + path);
-
+ Console.WriteLine(Assembly.GetEntryAssembly ().GetName ());
} else {
if (!File.Exists (path))
throw new FileNotFoundException ("File not found: ", path);
/// 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){
- if (!Instantiators.ContainsKey(path))
- Instantiators [path] = new ItemTemplate(this, path);
- return Instantiators [path] as ItemTemplate;
+ public virtual ItemTemplate GetItemTemplate(string path, Type declaringType){
+ if (!ItemTemplates.ContainsKey(path))
+ ItemTemplates [path] = new ItemTemplate(this, path, declaringType);
+ return ItemTemplates [path] as ItemTemplate;
}
#endregion
string fetchMethodName;
string dataTest;
+ static Stream getItemTemplateStream (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)
+ s = Assembly.GetAssembly (declaringType).GetManifestResourceStream (resId);
+ if (s == null)
+ throw new Exception ($"Item Template not found '{path}'");
+ } else {
+ if (!File.Exists (path))
+ throw new FileNotFoundException ("Item Template not found: ", path);
+ s = new FileStream (path, FileMode.Open, FileAccess.Read);
+ }
+ return s;
+ }
+
#region CTOR
/// <summary>
/// Initializes a new instance of the <see cref="Crow.ItemTemplate"/> class by parsing the file passed as argument.
/// <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, string _dataTest = "TypeOf", string _dataType = "default", string _fetchDataMethod = null)
- : base(_iface, path) {
+ public ItemTemplate (Interface _iface, string path, Type declaringType, string _dataTest = "TypeOf", string _dataType = "default", string _fetchDataMethod = null)
+ : base(_iface, getItemTemplateStream(path, declaringType)) {
strDataType = _dataType;
fetchMethodName = _fetchDataMethod;
dataTest = _dataTest;
}
+
/// <summary>
/// Initializes a new instance of the <see cref="Crow.ItemTemplate"/> class by parsing the IML fragment passed as arg.
/// </summary>
{
const byte XCB_COPY_FROM_PARENT = 0;
+ #region struct an enums
enum xcb_window_class_t : ushort {
COPY_FROM_PARENT = 0,
public UInt16 sequence; /**< Sequence number */
public UInt32 length; /**< Length of the response */
}
-
+ #endregion
#region pinvoke XCB
- [DllImportAttribute("xcb")]
+ [DllImportAttribute ("xcb")]
static extern IntPtr xcb_connect(string displayName, IntPtr screenNum);
[DllImportAttribute("xcb")]
static extern IntPtr xcb_get_setup(IntPtr connection);
IntPtr visual = findVisual (scr_it, scr.root_visual);
- //loadCursors ();
+ loadCursors ();
iFace.surf = new Cairo.XcbSurface (conn, win, visual, iFace.ClientRectangle.Width, iFace.ClientRectangle.Height);
}