From: jpbruyere Date: Tue, 13 Sep 2016 12:44:26 +0000 (+0200) Subject: Merge improvements from CrowIDE X-Git-Tag: v0.5~1 X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=2616e6ee7a1a34036cc002d28543d0d7a657fdb2;p=jp%2Fcrow.git Merge improvements from CrowIDE modifié : Templates/DirectoryView.template modifié : Templates/Menu.template modifié : Templates/MenuItem.template modifié : Templates/Window.template modifié : Tests/Interfaces/Divers/0.crow modifié : src/CompilerServices/CompilerServices.cs modifié : src/ExtensionsMethods.cs modifié : src/GraphicObjects/DirectoryView.cs modifié : src/GraphicObjects/GraphicObject.cs modifié : src/GraphicObjects/Group.cs modifié : src/GraphicObjects/TreeView.cs modifié : src/GraphicObjects/Wrapper.cs modifié : src/IMLReader.cs modifié : src/Interface.cs modifié : src/ItemTemplate.cs modifié : src/LayoutingQueueItem.cs modifié : src/Measure.cs modifié : src/Point.cs --- diff --git a/Templates/DirectoryView.template b/Templates/DirectoryView.template index 13f10f11..9b80c1e9 100755 --- a/Templates/DirectoryView.template +++ b/Templates/DirectoryView.template @@ -1,5 +1,5 @@  - @@ -10,7 +10,7 @@ MouseLeave="{Background=Transparent}"/> - + diff --git a/Templates/Window.template b/Templates/Window.template index 481c030b..6b3932c1 100755 --- a/Templates/Window.template +++ b/Templates/Window.template @@ -1,5 +1,7 @@ - diff --git a/Tests/Interfaces/Divers/0.crow b/Tests/Interfaces/Divers/0.crow index 18b06910..a7a2158a 100755 --- a/Tests/Interfaces/Divers/0.crow +++ b/Tests/Interfaces/Divers/0.crow @@ -139,14 +139,14 @@ - + - - + + - diff --git a/src/CompilerServices/CompilerServices.cs b/src/CompilerServices/CompilerServices.cs index d6f036ab..43c9d704 100644 --- a/src/CompilerServices/CompilerServices.cs +++ b/src/CompilerServices/CompilerServices.cs @@ -17,15 +17,19 @@ namespace Crow BindingFlags.NonPublic | BindingFlags.Instance); static MethodInfo stringEquals = typeof (string).GetMethod ("Equals", new Type [3] { typeof (string), typeof (string), typeof (StringComparison) }); - static FieldInfo fiNewValue = typeof (ValueChangeEventArgs).GetField ("NewValue"); - static FieldInfo fiMbName = typeof (ValueChangeEventArgs).GetField ("MemberName"); - static EventInfo eiValueChanged = typeof (IValueChange).GetEvent ("ValueChanged"); - static Type [] dmValueChangedArgs = { typeof (object), typeof (object), - eiValueChanged.EventHandlerType.GetMethod ("Invoke"). - GetParameters ()[1].ParameterType }; static MethodInfo miFindByName = typeof (GraphicObject).GetMethod ("FindByName"); + #region ValueChange Reflexion member info + static EventInfo eiValueChange = typeof (IValueChange).GetEvent ("ValueChanged"); + static MethodInfo miInvokeValueChange = eiValueChange.EventHandlerType.GetMethod ("Invoke"); + static Type [] argsValueChange = { typeof (object), typeof (object), miInvokeValueChange.GetParameters () [1].ParameterType }; + static FieldInfo fiNewValue = typeof (ValueChangeEventArgs).GetField ("NewValue"); + static FieldInfo fiMbName = typeof (ValueChangeEventArgs).GetField ("MemberName"); + static MethodInfo miValueChangeAdd = eiValueChange.GetAddMethod (); + #endregion + + public static void emitSetCurInterface(ILGenerator il){ il.Emit (OpCodes.Ldloc_0); il.Emit (OpCodes.Ldarg_1); @@ -229,7 +233,7 @@ namespace Crow MethodAttributes.Family | MethodAttributes.FamANDAssem | MethodAttributes.NewSlot, CallingConventions.Standard, typeof (void), - dmValueChangedArgs, + argsValueChange, target_Type, true); il = dm.GetILGenerator (256); @@ -377,9 +381,8 @@ namespace Crow il.Emit (OpCodes.Pop); il.Emit (OpCodes.Ret); - Delegate del = dm.CreateDelegate (eiValueChanged.EventHandlerType, Bindings [0].Source.Instance); - MethodInfo addHandler = eiValueChanged.GetAddMethod (); - addHandler.Invoke (grouped [0].Target.Instance, new object [] { del }); + Delegate del = dm.CreateDelegate (eiValueChange.EventHandlerType, Bindings [0].Source.Instance); + miValueChangeAdd.Invoke (grouped [0].Target.Instance, new object [] { del }); } } @@ -589,6 +592,17 @@ namespace Crow return query; } + + public static MethodInfo SearchExtMethod(Type t, string methodName){ + MethodInfo mi = null; + mi = GetExtensionMethods (Assembly.GetEntryAssembly(), t) + .Where (em => em.Name == methodName).FirstOrDefault (); + if (mi != null) + return mi; + + return GetExtensionMethods (Assembly.GetExecutingAssembly(), t) + .Where (em => em.Name == methodName).FirstOrDefault (); + } } } diff --git a/src/ExtensionsMethods.cs b/src/ExtensionsMethods.cs index d1b951b9..2bfc36ea 100644 --- a/src/ExtensionsMethods.cs +++ b/src/ExtensionsMethods.cs @@ -26,6 +26,7 @@ namespace Crow public static class ExtensionsMethods { #region Cairo extensions + public static void Rectangle(this Cairo.Context ctx, Rectangle r, double stroke = 0.0) { if (stroke > 0.0) { @@ -36,6 +37,59 @@ namespace Crow }else ctx.Rectangle (r.X, r.Y, r.Width, r.Height); } + public static double GetLength(this Cairo.PointD p){ + return Math.Sqrt (Math.Pow (p.X, 2) + Math.Pow (p.Y, 2)); + } + public static Cairo.PointD GetPerp(this Cairo.PointD p){ + return new Cairo.PointD(-p.Y, p.X); + } + public static Cairo.PointD GetNormalized(this Cairo.PointD p){ + double length = p.GetLength(); + p.X /= length; + p.Y /= length; + return p; + } + public static Cairo.PointD Substract(this Cairo.PointD p1, Cairo.PointD p2){ + return new Cairo.PointD(p1.X - p2.X, p1.Y - p2.Y); + } + public static Cairo.PointD Add(this Cairo.PointD p1, Cairo.PointD p2){ + return new Cairo.PointD(p1.X + p2.X, p1.Y + p2.Y); + } + public static Cairo.PointD Multiply(this Cairo.PointD p1, double v){ + return new Cairo.PointD(p1.X * v, p1.Y * v); + } + public static void DrawCote(this Cairo.Context ctx, Cairo.PointD p1, Cairo.PointD p2, double stroke = 1.0) + { + const double arrowWidth = 4.0; + const double arrowLength = 10.0; + + Cairo.PointD vDir = p2.Substract(p1); + vDir = vDir.GetNormalized (); + Cairo.PointD vPerp = vDir.GetPerp (); + + Cairo.PointD pA0 = p1.Add(vDir.Multiply(arrowLength)); + Cairo.PointD pA1 = p2.Substract(vDir.Multiply(arrowLength)); + + Cairo.PointD vA = vPerp.Multiply (arrowWidth); + + ctx.MoveTo (p1); + ctx.LineTo (pA0.Add (vA)); + ctx.LineTo (pA0.Substract (vA)); + ctx.LineTo (p1); + + ctx.MoveTo (p2); + ctx.LineTo (pA1.Add (vA)); + ctx.LineTo (pA1.Substract (vA)); + ctx.LineTo (p2); + + ctx.Fill (); + + ctx.MoveTo (p1); + ctx.LineTo (p2); + ctx.LineWidth = stroke; + ctx.Stroke (); + + } public static void SetSourceColor(this Cairo.Context ctx, Color c) { ctx.SetSourceRGBA(c.R,c.G,c.B,c.A); @@ -45,6 +99,7 @@ namespace Crow grad.AddColorStop (offset, new Cairo.Color (c.R, c.G, c.B, c.A)); } #endregion + public static void Raise(this EventHandler handler, object sender, EventArgs e) { if(handler != null) diff --git a/src/GraphicObjects/DirectoryView.cs b/src/GraphicObjects/DirectoryView.cs index 586b1b26..4e29621e 100644 --- a/src/GraphicObjects/DirectoryView.cs +++ b/src/GraphicObjects/DirectoryView.cs @@ -37,8 +37,8 @@ namespace Crow public event EventHandler SelectedItemChanged; #endregion - string _root = "/"; - bool _showFiles; + string currentDirectory = "/"; + bool showFiles; object _selectedItem; [XmlIgnore]public object SelectedItem { @@ -52,31 +52,37 @@ namespace Crow NotifyValueChanged ("SelectedItem", _selectedItem); } } - [XmlAttributeAttribute()][DefaultValue(true)] + [XmlAttributeAttribute()][DefaultValue(false)] public virtual bool ShowFiles { - get { return _showFiles; } + get { return showFiles; } set { - if (_showFiles == value) + if (showFiles == value) return; - _showFiles = value; - NotifyValueChanged ("ShowFiles", _showFiles); + showFiles = value; + NotifyValueChanged ("ShowFiles", showFiles); + NotifyValueChanged ("FileSystemEntries", FileSystemEntries); } } [XmlAttributeAttribute][DefaultValue("/")] - public virtual string Root { - get { return _root; } + public virtual string CurrentDirectory { + get { return currentDirectory; } set { - if (_root == value) + if (currentDirectory == value) return; - _root = value; - NotifyValueChanged ("Root", _root); - NotifyValueChanged ("CurrentDirectory", CurrentDirectory); + currentDirectory = value; + NotifyValueChanged ("CurrentDirectory", currentDirectory); + NotifyValueChanged ("FileSystemEntries", FileSystemEntries); } } - [XmlIgnore]public FileSystemInfo[] CurrentDirectory { - get { return new DirectoryInfo (Root).GetFileSystemInfos (); } + [XmlIgnore]public FileSystemInfo[] FileSystemEntries { + get { + return showFiles ? new DirectoryInfo (CurrentDirectory).GetFileSystemInfos (): + new DirectoryInfo(currentDirectory).GetDirectories(); + } } public void onSelectedItemChanged (object sender, SelectionChangeEventArgs e){ + if (e.NewValue == SelectedItem) + return; SelectedItem = e.NewValue; SelectedItemChanged.Raise (this, e); } diff --git a/src/GraphicObjects/GraphicObject.cs b/src/GraphicObjects/GraphicObject.cs index 6572ba52..093664d1 100644 --- a/src/GraphicObjects/GraphicObject.cs +++ b/src/GraphicObjects/GraphicObject.cs @@ -54,8 +54,10 @@ namespace Crow #region CTOR public GraphicObject () { + #if DEBUG uid = currentUid; currentUid++; + #endif } #endregion internal protected virtual void initialize(){ @@ -65,7 +67,7 @@ namespace Crow LayoutingType registeredLayoutings = LayoutingType.All; ILayoutable logicalParent; ILayoutable parent; - string name = "unamed"; + string name; Fill background = Color.Transparent; Fill foreground = Color.White; Font font = "droid, 10"; @@ -199,14 +201,20 @@ namespace Crow this.RegisterForRedraw (); } } - [XmlAttributeAttribute()][DefaultValue("unamed")] + [XmlAttributeAttribute()][DefaultValue(null)] public virtual string Name { - get { return name; } + get { + #if DEBUG + return string.IsNullOrEmpty(name) ? this.GetType().Name + uid.ToString () : name; + #else + return name; + #endif + } set { if (name == value) return; name = value; - NotifyValueChanged("Name", verticalAlignment); + NotifyValueChanged("Name", name); } } [XmlAttributeAttribute ()][DefaultValue(VerticalAlignment.Center)] @@ -333,15 +341,13 @@ namespace Crow /// Fit or Stretched /// [XmlIgnore]public virtual Measure WidthPolicy { get { - return Width.Units == Unit.Percent || Width.IsFixed ? - Measure.Stretched : Measure.Fit; } } + return Width.IsFit ? Measure.Fit : Measure.Stretched; } } /// /// Used for binding on dimensions, this property will never hold fixed size, but instead only /// Fit or Stretched /// [XmlIgnore]public virtual Measure HeightPolicy { get { - return Height.Units == Unit.Percent || Height.IsFixed ? - Measure.Stretched : Measure.Fit; } } + return Height.IsFit ? Measure.Fit : Measure.Stretched; } } [XmlAttributeAttribute()][DefaultValue(false)] public virtual bool Focusable { get { return focusable; } @@ -450,14 +456,17 @@ namespace Crow if (!isVisible && this.Contains (CurrentInterface.HoverWidget)) CurrentInterface.HoverWidget = null; - if (Parent is GraphicObject) - (Parent as GraphicObject).RegisterForLayouting (LayoutingType.Sizing); - if (Parent is GenericStack) - (Parent as GraphicObject).RegisterForLayouting (LayoutingType.ArrangeChildren); - if (isVisible) RegisterForLayouting (LayoutingType.Sizing); - CurrentInterface.EnqueueForRepaint (this); + else { + Slot.Width = 0; + LayoutChanged.Raise (this, new LayoutingEventArgs (LayoutingType.Width)); + Slot.Height = 0; + LayoutChanged.Raise (this, new LayoutingEventArgs (LayoutingType.Height)); + CurrentInterface.EnqueueForRepaint (this); + LastSlots.Width = LastSlots.Height = 0; + } + NotifyValueChanged ("Visible", isVisible); } @@ -720,7 +729,7 @@ namespace Crow public void RegisterForGraphicUpdate () { bmp = null; - if (Width == Measure.Fit || Height == Measure.Fit) + if (Width.IsFit || Height.IsFit) RegisterForLayouting (LayoutingType.Sizing); else if (RegisteredLayoutings == LayoutingType.None) CurrentInterface.EnqueueForRepaint (this); @@ -737,10 +746,6 @@ namespace Crow #region Layouting - #if DEBUG_LAYOUTING - public List CurrentDrawLQIs = null; - public List> LQIs = new List>(); - #endif /// return size of content + margins protected virtual int measureRawSize (LayoutingType lt) { return lt == LayoutingType.Width ? @@ -754,6 +759,11 @@ namespace Crow if (Parent == null) return; lock (CurrentInterface.LayoutMutex) { + //prevent queueing same LayoutingType for this + layoutType &= (~RegisteredLayoutings); + + if (layoutType == LayoutingType.None) + return; //dont set position for stretched item if (Width == Measure.Stretched) layoutType &= (~LayoutingType.X); @@ -767,8 +777,8 @@ namespace Crow if (Parent is GraphicObject) (Parent as GraphicObject).ChildrenLayoutingConstraints (ref layoutType); - //prevent queueing same LayoutingType for this - layoutType &= (~RegisteredLayoutings); +// //prevent queueing same LayoutingType for this +// layoutType &= (~RegisteredLayoutings); if (layoutType == LayoutingType.None) return; @@ -791,8 +801,8 @@ namespace Crow public virtual void OnLayoutChanges(LayoutingType layoutType) { #if DEBUG_LAYOUTING - LayoutingQueueItem.currentLQI.Slot = LastSlots; - LayoutingQueueItem.currentLQI.Slot = Slot; + CurrentInterface.currentLQI.Slot = LastSlots; + CurrentInterface.currentLQI.NewSlot = Slot; #endif switch (layoutType) { @@ -1020,12 +1030,6 @@ namespace Crow return; LastPaintedSlot = Slot; - #if DEBUG_LAYOUTING - if (CurrentDrawLQIs != null){ - LQIs.Add (CurrentDrawLQIs); - CurrentDrawLQIs = null; - } - #endif if (cacheEnabled) { if (Slot.Width > Interface.MaxCacheSize || Slot.Height > Interface.MaxCacheSize) @@ -1200,18 +1204,6 @@ namespace Crow public virtual void onDisable(object sender, EventArgs e){ Disabled.Raise (this, e); } - public override string ToString () - { - string tmp =""; - - if (Parent != null) - tmp = Parent.ToString () + tmp; - #if DEBUG_LAYOUTING - return Name == "unamed" ? tmp + "." + this.GetType ().Name + uid.ToString(): tmp + "." + Name; - #else - return Name == "unamed" ? tmp + "." + this.GetType ().Name : tmp + "." + Name; - #endif - } #region Binding public void BindMember(string _member, string _expression){ @@ -1489,5 +1481,18 @@ namespace Crow tmp.Bindings.Add (new Binding (new MemberReference (tmp, b.Source.Member), b.Expression)); return tmp; } + + public override string ToString () + { + string tmp =""; + + if (Parent != null) + tmp = Parent.ToString () + tmp; + #if DEBUG_LAYOUTING + return Name == "unamed" ? tmp + "." + this.GetType ().Name + uid.ToString(): tmp + "." + Name; + #else + return Name == "unamed" ? tmp + "." + this.GetType ().Name : tmp + "." + Name; + #endif + } } } diff --git a/src/GraphicObjects/Group.cs b/src/GraphicObjects/Group.cs index 402128b0..efe02d95 100644 --- a/src/GraphicObjects/Group.cs +++ b/src/GraphicObjects/Group.cs @@ -153,12 +153,20 @@ namespace Crow //position smaller objects in group when group size is fit switch (layoutType) { case LayoutingType.Width: - foreach (GraphicObject c in Children) - c.RegisterForLayouting (LayoutingType.X | LayoutingType.Width); + foreach (GraphicObject c in Children){ + if (c.Width.Units == Unit.Percent) + c.RegisterForLayouting (LayoutingType.Width); + else + c.RegisterForLayouting (LayoutingType.X); + } break; case LayoutingType.Height: - foreach (GraphicObject c in Children) - c.RegisterForLayouting (LayoutingType.Y | LayoutingType.Height); + foreach (GraphicObject c in Children) { + if (c.Height.Units == Unit.Percent) + c.RegisterForLayouting (LayoutingType.Height); + else + c.RegisterForLayouting (LayoutingType.Y); + } break; } } diff --git a/src/GraphicObjects/TreeView.cs b/src/GraphicObjects/TreeView.cs index b9ab20b6..4fa881b4 100644 --- a/src/GraphicObjects/TreeView.cs +++ b/src/GraphicObjects/TreeView.cs @@ -72,6 +72,8 @@ namespace Crow internal override void itemClick (object sender, MouseButtonEventArgs e) { GraphicObject tmp = sender as GraphicObject; + if (!tmp.HasFocus) + return; if (selectedItemContainer != null) { selectedItemContainer.Foreground = Color.Transparent; selectedItemContainer.Background = Color.Transparent; diff --git a/src/GraphicObjects/Wrapper.cs b/src/GraphicObjects/Wrapper.cs index 03251af9..1bfcd92a 100644 --- a/src/GraphicObjects/Wrapper.cs +++ b/src/GraphicObjects/Wrapper.cs @@ -191,8 +191,8 @@ namespace Crow public override void OnLayoutChanges (LayoutingType layoutType) { #if DEBUG_LAYOUTING - LayoutingQueueItem.currentLQI.Slot = LastSlots; - LayoutingQueueItem.currentLQI.Slot = Slot; + CurrentInterface.currentLQI.Slot = LastSlots; + CurrentInterface.currentLQI.Slot = Slot; #endif switch (layoutType) { diff --git a/src/IMLReader.cs b/src/IMLReader.cs index 0ff80652..ad4fd835 100644 --- a/src/IMLReader.cs +++ b/src/IMLReader.cs @@ -31,10 +31,6 @@ namespace Crow public class IMLReader : XmlTextReader { InstanciatorInvoker loader = null; - - string ImlPath; - Stream ImlStream; - DynamicMethod dm = null; public ILGenerator il = null; @@ -55,12 +51,10 @@ namespace Crow #region CTOR public IMLReader (string path) : this(Interface.GetStreamFromPath (path)){ - ImlPath = path; } public IMLReader (Stream stream) : base(stream) { - ImlStream = stream; createInstantiator (); } /// @@ -138,13 +132,23 @@ namespace Crow path = reader.Value; } reader.MoveToElement (); - using (IMLReader iTmp = new IMLReader (null, reader.ReadInnerXml ())) { - string uid = Guid.NewGuid ().ToString (); - Interface.Instantiators [uid] = - new ItemTemplate (iTmp.RootType, iTmp.GetLoader (), dataType, datas); - - itemTemplateIds.Add (new string[] { dataType, uid, datas }); + + string itemTmpID; + + if (string.IsNullOrEmpty (path)) { + using (IMLReader iTmp = new IMLReader (null, reader.ReadInnerXml ())) { + itemTmpID = Guid.NewGuid ().ToString (); + Interface.Instantiators [itemTmpID] = + new ItemTemplate (iTmp.RootType, iTmp.GetLoader (), dataType, datas); + } + }else{ + if (!reader.IsEmptyElement) + throw new Exception ("ItemTemplate with Path attribute may not include sub nodes"); + itemTmpID = path; + Interface.Instantiators [itemTmpID] = + new ItemTemplate (itemTmpID, dataType, datas); } + itemTemplateIds.Add (new string[] { dataType, itemTmpID, datas }); } } @@ -209,8 +213,6 @@ namespace Crow #region Attributes reading if (reader.HasAttributes) { - MethodInfo miAddBinding = typeof(GraphicObject).GetMethod ("BindMember"); - while (reader.MoveToNextAttribute ()) { if (reader.Name == "Style") continue; diff --git a/src/Interface.cs b/src/Interface.cs index d01d2e8f..1659c0ea 100644 --- a/src/Interface.cs +++ b/src/Interface.cs @@ -320,7 +320,18 @@ namespace Crow } #endregion - + #if DEBUG_LAYOUTING + public List LQIsTries = new List(); + public LQIList curLQIsTries = new LQIList(); + public List LQIs = new List(); + public LQIList curLQIs = new LQIList(); +// public static LayoutingQueueItem[] MultipleRunsLQIs { +// get { return curUpdateLQIs.Where(l=>l.LayoutingTries>2 || l.DiscardCount > 0).ToArray(); } +// } + public LayoutingQueueItem currentLQI = null; + #else + public List LQIs = null;//still create the var for CrowIDE + #endif public void Update(){ if (mouseRepeatCount > 0) { int mc = mouseRepeatCount; @@ -346,6 +357,15 @@ namespace Crow processLayouting (); + #if DEBUG_LAYOUTING + if (curLQIsTries.Count > 0){ + LQIsTries.Add(curLQIsTries); + curLQIsTries = new LQIList(); + LQIs.Add(curLQIs); + curLQIs = new LQIList(); + } + #endif + clippingRegistration (); processDrawing (); @@ -366,7 +386,14 @@ namespace Crow LayoutingQueueItem lqi = null; while (LayoutingQueue.Count > 0) { lqi = LayoutingQueue.Dequeue (); + #if DEBUG_LAYOUTING + currentLQI = lqi; + curLQIsTries.Add(currentLQI); + #endif lqi.ProcessLayouting (); + #if DEBUG_LAYOUTING + currentLQI = null; + #endif } LayoutingQueue = DiscardQueue; } @@ -496,6 +523,12 @@ namespace Crow g.ClearBinding (); GraphicTree.RemoveAt (0); } + #if DEBUG_LAYOUTING + LQIsTries = new List(); + curLQIsTries = new LQIList(); + LQIs = new List(); + curLQIs = new LQIList(); + #endif } public GraphicObject FindByName (string nameToFind) { diff --git a/src/ItemTemplate.cs b/src/ItemTemplate.cs index 310cfb0a..fe26f7a7 100644 --- a/src/ItemTemplate.cs +++ b/src/ItemTemplate.cs @@ -27,6 +27,7 @@ using System.Xml.Serialization; using System.Xml; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; namespace Crow { @@ -36,8 +37,10 @@ namespace Crow string fetchMethodName; #region CTOR - public ItemTemplate(string path) + public ItemTemplate(string path, string _dataType = null, string _fetchDataMethod = null) : base(path) { + strDataType = _dataType; + fetchMethodName = _fetchDataMethod; } public ItemTemplate (Type _root, InstanciatorInvoker _loader,string _dataType, string _fetchDataMethod) :base(_root, _loader) @@ -53,6 +56,7 @@ namespace Crow Type hostType = tmpGrpType;//not sure is the best place to put the dyn method Type evtType = typeof(EventHandler); + PropertyInfo piData = tmpGrpType.GetProperty ("Data"); MethodInfo evtInvoke = evtType.GetMethod ("Invoke"); ParameterInfo [] evtParams = evtInvoke.GetParameters (); @@ -66,37 +70,76 @@ namespace Crow #region IL generation + System.Reflection.Emit.Label gotoEnd; + System.Reflection.Emit.Label ifDataIsNull; + ILGenerator il = dm.GetILGenerator (256); il.DeclareLocal(typeof(GraphicObject)); - il.Emit (OpCodes.Ldarg_1); + gotoEnd = il.DefineLabel (); + ifDataIsNull = il.DefineLabel (); + + il.Emit (OpCodes.Ldarg_1);//load sender of expand event MethodInfo miFindByName = typeof(GraphicObject).GetMethod("FindByName"); il.Emit(OpCodes.Ldstr, "List"); il.Emit (OpCodes.Callvirt, miFindByName); il.Emit (OpCodes.Stloc_0); - FieldInfo fiTemplates = typeof(TemplatedGroup).GetField("ItemTemplates"); + //check that 'Data' of list is not already set + il.Emit (OpCodes.Ldloc_0); + il.Emit (OpCodes.Callvirt, piData.GetGetMethod ()); + il.Emit (OpCodes.Brfalse, ifDataIsNull); + il.Emit (OpCodes.Br, gotoEnd); + + il.MarkLabel(ifDataIsNull); + //copy the ref of ItemTemplates list TODO: maybe find another way to share it among the nodes? + FieldInfo fiTemplates = tmpGrpType.GetField("ItemTemplates"); il.Emit (OpCodes.Ldloc_0); il.Emit (OpCodes.Ldarg_0); il.Emit (OpCodes.Ldfld, fiTemplates); il.Emit (OpCodes.Stfld, fiTemplates); - il.Emit (OpCodes.Ldloc_0); - il.Emit (OpCodes.Ldarg_1); + //call 'fetchMethodName' from the dataSource to build the sub nodes list + il.Emit (OpCodes.Ldloc_0);//push 'List' (of sub nodes) into the stack + il.Emit (OpCodes.Ldarg_1);//get the dataSource of the sender il.Emit (OpCodes.Callvirt, typeof(GraphicObject).GetProperty("DataSource").GetGetMethod ()); - MethodInfo miGetDatas = dataType.GetMethod (fetchMethodName, new Type[] {}); - il.Emit (OpCodes.Callvirt, miGetDatas); + if (fetchMethodName != "self"){//special keyword self allows the use of recurent list<<< + emitGetSubData(il, dataType); + } - il.Emit (OpCodes.Callvirt, tmpGrpType.GetProperty("Data").GetSetMethod ()); + //set 'return' from the fetch method as 'data' of the list + il.Emit (OpCodes.Callvirt, piData.GetSetMethod ()); + il.MarkLabel(gotoEnd); il.Emit (OpCodes.Ret); #endregion Expand = (EventHandler)dm.CreateDelegate (evtType, host); } + void emitGetSubData(ILGenerator il, Type dataType){ + MethodInfo miGetDatas = dataType.GetMethod (fetchMethodName, new Type[] {}); + if (miGetDatas == null) + miGetDatas = CompilerServices.SearchExtMethod (dataType, fetchMethodName); + + if (miGetDatas == null) {//in last resort, search among properties + PropertyInfo piDatas = dataType.GetProperty (fetchMethodName); + if (piDatas == null) { + FieldInfo fiDatas = dataType.GetField (fetchMethodName); + if (fiDatas == null)//and among fields + throw new Exception ("Fetch data member not found in ItemTemplate: " + fetchMethodName); + il.Emit (OpCodes.Ldfld, fiDatas); + return; + } + miGetDatas = piDatas.GetGetMethod (); + if (miGetDatas == null) + throw new Exception ("Read only property for fetching data in ItemTemplate: " + fetchMethodName); + } + + il.Emit (OpCodes.Callvirt, miGetDatas); + } } } diff --git a/src/LayoutingQueueItem.cs b/src/LayoutingQueueItem.cs index 6de5be7b..3b19efc9 100644 --- a/src/LayoutingQueueItem.cs +++ b/src/LayoutingQueueItem.cs @@ -51,17 +51,25 @@ namespace Crow public int LayoutingTries, DiscardCount; #if DEBUG_LAYOUTING - public static List processedLQIs = new List(); - public static LayoutingQueueItem[] MultipleRunsLQIs { - get { return processedLQIs.Where(l=>l.LayoutingTries>2 || l.DiscardCount > 0).ToArray(); } - } - public static LayoutingQueueItem currentLQI = null; public Stopwatch LQITime = new Stopwatch(); - public List triggeredLQIs = new List(); + public LQIList triggeredLQIs = new LQIList(); public LayoutingQueueItem wasTriggeredBy = null; public GraphicObject graphicObject { get { return Layoutable as GraphicObject; } } + public string Name { + get { return graphicObject.Name; } + } + public string FullName { + get { return graphicObject.ToString(); } + } + public Measure Width { + get { return graphicObject.Width; } + } + public Measure Height { + get { return graphicObject.Height; } + } + public bool HasTriggeredLQIs { get { return triggeredLQIs.Count > 0; }} public Rectangle Slot, NewSlot; #endif @@ -72,12 +80,11 @@ namespace Crow Layoutable = _graphicObject; Layoutable.RegisteredLayoutings |= LayoutType; #if DEBUG_LAYOUTING - if (graphicObject.CurrentDrawLQIs == null) - graphicObject.CurrentDrawLQIs = new List(); - graphicObject.CurrentDrawLQIs.Add(this); - if (currentLQI != null){ - wasTriggeredBy = currentLQI; - currentLQI.triggeredLQIs.Add(this); + GraphicObject g = graphicObject; + g.CurrentInterface.curLQIs.Add(this); + if (g.CurrentInterface.currentLQI != null){ + wasTriggeredBy = g.CurrentInterface.currentLQI; + g.CurrentInterface.currentLQI.triggeredLQIs.Add(this); } #endif } @@ -93,13 +100,11 @@ namespace Crow return; } #if DEBUG_LAYOUTING - currentLQI = this; - processedLQIs.Add(this); LQITime.Start(); #endif + LayoutingTries++; if (!Layoutable.UpdateLayout (LayoutType)) { if (LayoutingTries < Interface.MaxLayoutingTries) { - LayoutingTries++; Layoutable.RegisteredLayoutings |= LayoutType; (Layoutable as GraphicObject).CurrentInterface.LayoutingQueue.Enqueue (this); } else if (DiscardCount < Interface.MaxDiscardCount) { @@ -114,7 +119,6 @@ namespace Crow #endif } #if DEBUG_LAYOUTING - currentLQI = null; LQITime.Stop(); #endif } @@ -138,5 +142,12 @@ namespace Crow #endif } } + public class LQIList : List{ + #if DEBUG_LAYOUTING + public List GetRootLQIs(){ + return this.Where (lqi => lqi.wasTriggeredBy == null).ToList (); + } + #endif + } } diff --git a/src/Measure.cs b/src/Measure.cs index 19e8f548..c9b08f22 100644 --- a/src/Measure.cs +++ b/src/Measure.cs @@ -62,7 +62,7 @@ namespace Crow /// True is size is fixed in pixels, this means not proportional, stretched nor fit. /// public bool IsFixed { get { return Value > 0 && Units == Unit.Pixel; }} - + public bool IsFit { get { return Value == -1 && Units == Unit.Pixel; }} #region Operators public static implicit operator int(Measure m){ return m.Value; diff --git a/src/Point.cs b/src/Point.cs index ba0103e3..2e196133 100644 --- a/src/Point.cs +++ b/src/Point.cs @@ -29,6 +29,9 @@ namespace Crow public int Length { get { return (int)Math.Sqrt (Math.Pow (_x, 2) + Math.Pow (_y, 2)); } } + public double LengthD { + get { return Math.Sqrt (Math.Pow (_x, 2) + Math.Pow (_y, 2)); } + } public static implicit operator Cairo.Point(Point p) { return new Cairo.Point(p.X, p.Y);