<?xml version="1.0"?>
-<TreeView IsRoot="true" Name="treeView" Data="{./CurrentDirectory}"
+<TreeView IsRoot="true" Name="treeView" Data="{./FileSystemEntries}"
SelectedItemChanged="./onSelectedItemChanged">
<ItemTemplate DataType="System.IO.FileInfo">
<HorizontalStack Focusable="true" Height="Fit" Width="Stretched" Background="{../Background}" >
MouseLeave="{Background=Transparent}"/>
</HorizontalStack>
</ItemTemplate>
- <ItemTemplate DataType="System.IO.DirectoryInfo" Data="GetFileSystemInfos">
+ <ItemTemplate DataType="System.IO.DirectoryInfo" Data="GetFileSystemInfos">
<Expandable Caption="{Name}" >
<Template>
<VerticalStack Height="{./HeightPolicy}" Width="{./WidthPolicy}">
MouseEnter="{Background=hgradient|0:BlueCrayola|1:Transparent}"
MouseLeave="{Background=Transparent}">
<Image Margin="2" Width="12" Height="12"
- Visible="{./HasContent}"
- Path="{./Image}"
+ Path="{./Image}"
SvgSub="{./IsExpanded}"/>
<Image Margin="2" Width="14" Height="14"
Path="#Crow.Images.Icons.folder.svg"/>
<?xml version="1.0"?>
-<HorizontalStack Name="ItemsContainer" Margin="2" Background="{./Background}"
+<HorizontalStack Name="ItemsContainer" Margin="0" Background="{./Background}"
Width="{./WidthPolicy}" Height="{./HeightPolicy}"/>
Background="{./Background}">
<Label Text="{./Caption}"
Foreground="{./Foreground}"
- Margin="3" HorizontalAlignment="Left"
+ Margin="1" HorizontalAlignment="Left"
Font="{./Font}" />
</Border>
</Template>
<?xml version="1.0"?>
-<Border BorderWidth="1" Foreground="White" CornerRadius="{./CornerRadius}" Height="{./HeightPolicy}" Width="{./WidthPolicy}"
+<Border BorderWidth="1" Foreground="White" CornerRadius="{./CornerRadius}"
+ Background="{./Background}"
+ Height="{./HeightPolicy}" Width="{./WidthPolicy}"
MouseEnter="./onBorderMouseEnter"
MouseLeave="./onBorderMouseLeave">
<VerticalStack Height="{./HeightPolicy}" Width="{./WidthPolicy}" Spacing="0">
</VerticalStack>
<Splitter/>
<VerticalStack Width="33%" Margin="5">
- <Border Margin="5" Background="Onyx" Height="Fit">
+ <Border Margin="5" Height="Fit">
<Label Width="Stretched" Margin="1" Text="{../../dv.SelectedItem}"/>
</Border>
- <Border Margin="5" Background="Onyx" Height="50%">
- <DirectoryView Name="dv" Root="./" Margin="1"/>
+ <Border Margin="5" Height="50%">
+ <DirectoryView Name="dv" CurrentDirectory="./" Margin="1"/>
</Border>
<Splitter/>
- <ListBox Data="{TestList}" Background="Onyx" Margin="5"
+ <ListBox Data="{TestList}" Margin="5"
ItemTemplate="#Tests.Interfaces.colorItem.crow"
Template="#Crow.Templates.ScrollingListBox.goml"/>
</VerticalStack>
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);
MethodAttributes.Family | MethodAttributes.FamANDAssem | MethodAttributes.NewSlot,
CallingConventions.Standard,
typeof (void),
- dmValueChangedArgs,
+ argsValueChange,
target_Type, true);
il = dm.GetILGenerator (256);
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 });
}
}
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 ();
+ }
}
}
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) {
}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);
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)
public event EventHandler<SelectionChangeEventArgs> SelectedItemChanged;
#endregion
- string _root = "/";
- bool _showFiles;
+ string currentDirectory = "/";
+ bool showFiles;
object _selectedItem;
[XmlIgnore]public object SelectedItem {
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);
}
#region CTOR
public GraphicObject ()
{
+ #if DEBUG
uid = currentUid;
currentUid++;
+ #endif
}
#endregion
internal protected virtual void initialize(){
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";
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)]
/// Fit or Stretched
/// </summary>
[XmlIgnore]public virtual Measure WidthPolicy { get {
- return Width.Units == Unit.Percent || Width.IsFixed ?
- Measure.Stretched : Measure.Fit; } }
+ return Width.IsFit ? Measure.Fit : Measure.Stretched; } }
/// <summary>
/// Used for binding on dimensions, this property will never hold fixed size, but instead only
/// Fit or Stretched
/// </summary>
[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; }
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);
}
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);
#region Layouting
- #if DEBUG_LAYOUTING
- public List<LayoutingQueueItem> CurrentDrawLQIs = null;
- public List<List<LayoutingQueueItem>> LQIs = new List<List<LayoutingQueueItem>>();
- #endif
/// <summary> return size of content + margins </summary>
protected virtual int measureRawSize (LayoutingType lt) {
return lt == LayoutingType.Width ?
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);
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;
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) {
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)
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){
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
+ }
}
}
//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;
}
}
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;
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) {
public class IMLReader : XmlTextReader
{
InstanciatorInvoker loader = null;
-
- string ImlPath;
- Stream ImlStream;
-
DynamicMethod dm = null;
public ILGenerator il = null;
#region CTOR
public IMLReader (string path)
: this(Interface.GetStreamFromPath (path)){
- ImlPath = path;
}
public IMLReader (Stream stream)
: base(stream)
{
- ImlStream = stream;
createInstantiator ();
}
/// <summary>
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 });
}
}
#region Attributes reading
if (reader.HasAttributes) {
- MethodInfo miAddBinding = typeof(GraphicObject).GetMethod ("BindMember");
-
while (reader.MoveToNextAttribute ()) {
if (reader.Name == "Style")
continue;
}
#endregion
-
+ #if DEBUG_LAYOUTING
+ public List<LQIList> LQIsTries = new List<LQIList>();
+ public LQIList curLQIsTries = new LQIList();
+ public List<LQIList> LQIs = new List<LQIList>();
+ 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<LQIList> LQIs = null;//still create the var for CrowIDE
+ #endif
public void Update(){
if (mouseRepeatCount > 0) {
int mc = mouseRepeatCount;
processLayouting ();
+ #if DEBUG_LAYOUTING
+ if (curLQIsTries.Count > 0){
+ LQIsTries.Add(curLQIsTries);
+ curLQIsTries = new LQIList();
+ LQIs.Add(curLQIs);
+ curLQIs = new LQIList();
+ }
+ #endif
+
clippingRegistration ();
processDrawing ();
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;
}
g.ClearBinding ();
GraphicTree.RemoveAt (0);
}
+ #if DEBUG_LAYOUTING
+ LQIsTries = new List<LQIList>();
+ curLQIsTries = new LQIList();
+ LQIs = new List<LQIList>();
+ curLQIs = new LQIList();
+ #endif
}
public GraphicObject FindByName (string nameToFind)
{
using System.Xml;
using System.Collections.Generic;
using System.Diagnostics;
+using System.Linq;
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)
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 ();
#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);
+ }
}
}
public int LayoutingTries, DiscardCount;
#if DEBUG_LAYOUTING
- public static List<LayoutingQueueItem> processedLQIs = new List<LayoutingQueueItem>();
- 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<LayoutingQueueItem> triggeredLQIs = new List<LayoutingQueueItem>();
+ 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
Layoutable = _graphicObject;
Layoutable.RegisteredLayoutings |= LayoutType;
#if DEBUG_LAYOUTING
- if (graphicObject.CurrentDrawLQIs == null)
- graphicObject.CurrentDrawLQIs = new List<LayoutingQueueItem>();
- 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
}
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) {
#endif
}
#if DEBUG_LAYOUTING
- currentLQI = null;
LQITime.Stop();
#endif
}
#endif
}
}
+ public class LQIList : List<LayoutingQueueItem>{
+ #if DEBUG_LAYOUTING
+ public List<LayoutingQueueItem> GetRootLQIs(){
+ return this.Where (lqi => lqi.wasTriggeredBy == null).ToList ();
+ }
+ #endif
+ }
}
/// True is size is fixed in pixels, this means not proportional, stretched nor fit.
/// </summary>
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;
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);