diff options
| author | jpbruyere <jp.bruyere@hotmail.com> | 2016-08-08 19:22:52 +0200 |
|---|---|---|
| committer | jpbruyere <jp.bruyere@hotmail.com> | 2016-08-08 19:22:52 +0200 |
| commit | cc4c62ab5d809ff451ca475a7949adc4fdfd806b (patch) | |
| tree | 3b39b3eeffbadbc930941e37c1ef3b5026339da3 /src/GraphicObjects | |
| parent | 4d4a9116ea5c68b27f0b7c43db9682ab57738ae7 (diff) | |
IMLInstantiator implementation
Diffstat (limited to 'src/GraphicObjects')
| -rw-r--r-- | src/GraphicObjects/Container.cs | 6 | ||||
| -rw-r--r-- | src/GraphicObjects/GraphicObject.cs | 359 | ||||
| -rw-r--r-- | src/GraphicObjects/Grid.cs | 5 | ||||
| -rw-r--r-- | src/GraphicObjects/Group.cs | 11 | ||||
| -rw-r--r-- | src/GraphicObjects/IBindable.cs | 32 | ||||
| -rw-r--r-- | src/GraphicObjects/ListBox.cs | 4 | ||||
| -rw-r--r-- | src/GraphicObjects/PrivateContainer.cs | 5 | ||||
| -rw-r--r-- | src/GraphicObjects/Scroller.cs | 4 | ||||
| -rw-r--r-- | src/GraphicObjects/TabView.cs | 4 |
9 files changed, 165 insertions, 265 deletions
diff --git a/src/GraphicObjects/Container.cs b/src/GraphicObjects/Container.cs index 69e3a3b4..9acbf03a 100644 --- a/src/GraphicObjects/Container.cs +++ b/src/GraphicObjects/Container.cs @@ -4,6 +4,7 @@ using System.Reflection; using System.ComponentModel; using System.Linq; using System.Threading; +using System.Diagnostics; namespace Crow { @@ -25,9 +26,10 @@ namespace Crow get { return child; } set { child = value; } } - public virtual T SetChild<T> (T _child) + public virtual void SetChild(GraphicObject _child) { - return base.SetChild (_child); + Debug.WriteLine ("container setChild"); + base.SetChild (_child); } #region IXmlSerializable diff --git a/src/GraphicObjects/GraphicObject.cs b/src/GraphicObjects/GraphicObject.cs index 8966acf6..fb9f592d 100644 --- a/src/GraphicObjects/GraphicObject.cs +++ b/src/GraphicObjects/GraphicObject.cs @@ -12,16 +12,8 @@ using System.IO; namespace Crow { - public class GraphicObject : IXmlSerializable, ILayoutable, IValueChange, ICloneable, IBindable + public class GraphicObject : IXmlSerializable, ILayoutable, IValueChange, ICloneable { - #region IBindable implementation - List<Binding> bindings = new List<Binding> (); - public List<Binding> Bindings { - get { return bindings; } - } - - #endregion - internal static ulong currentUid = 0; internal ulong uid = 0; @@ -513,7 +505,7 @@ namespace Crow #endregion /// <summary> Loads the default values from XML attributes default </summary> - protected virtual void loadDefaultValues() + public void loadDefaultValues() { #if DEBUG_LOAD Debug.WriteLine ("LoadDefValues for " + this.ToString ()); @@ -581,151 +573,70 @@ namespace Crow typeof(void),new Type[] {typeof(object)},thisType,true); il = dm.GetILGenerator(256); - + il.DeclareLocal(typeof(GraphicObject)); il.Emit(OpCodes.Nop); + //set local GraphicObject to root object passed as 1st argument + il.Emit (OpCodes.Ldarg_0); + il.Emit (OpCodes.Stloc_0); - foreach (PropertyInfo pi in thisType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { - string name = ""; - object defaultValue = null; - - #region retrieve custom attributes + foreach (PropertyInfo pi in thisType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { if (pi.GetSetMethod () == null) continue; - - XmlIgnoreAttribute xia = (XmlIgnoreAttribute)pi.GetCustomAttribute (typeof(XmlIgnoreAttribute)); - if (xia != null) - continue; - XmlAttributeAttribute xaa = (XmlAttributeAttribute)pi.GetCustomAttribute (typeof(XmlAttributeAttribute)); - if (xaa != null) { - if (string.IsNullOrEmpty (xaa.AttributeName)) - name = pi.Name; - else - name = xaa.AttributeName; - } - - int styleIndex = -1; - if (styling.Count > 0){ - for (int i = 0; i < styling.Count; i++) { - if (styling[i].ContainsKey (name)){ - styleIndex = i; - break; - } - } - } - if (styleIndex >= 0){ - if (pi.PropertyType.IsEnum)//maybe should be in parser.. - defaultValue = Enum.Parse(pi.PropertyType, (string)styling[styleIndex] [name], true); - else - defaultValue = styling[styleIndex] [name]; - }else { - DefaultValueAttribute dv = (DefaultValueAttribute)pi.GetCustomAttribute (typeof (DefaultValueAttribute)); - if (dv == null) - continue; - defaultValue = dv.Value; - } - #endregion - - il.Emit (OpCodes.Ldarg_0); - - if (defaultValue == null) { - il.Emit (OpCodes.Ldnull); - il.Emit (OpCodes.Callvirt, pi.GetSetMethod ()); + object defaultValue; + if (!getDefaultValue (pi, styling, out defaultValue)) continue; - } - Type dvType = defaultValue.GetType (); - if (dvType.IsValueType) { - if (pi.PropertyType.IsValueType) { - if (pi.PropertyType.IsEnum) { - if (pi.PropertyType != dvType) - throw new Exception ("Enum mismatch in default values: " + pi.PropertyType.FullName); - il.Emit (OpCodes.Ldc_I4, Convert.ToInt32 (defaultValue)); - } else { - switch (Type.GetTypeCode (dvType)) { - case TypeCode.Boolean: - if ((bool)defaultValue == true) - il.Emit (OpCodes.Ldc_I4_1); - else - il.Emit (OpCodes.Ldc_I4_0); - break; -// case TypeCode.Empty: -// break; -// case TypeCode.Object: -// break; -// case TypeCode.DBNull: -// break; -// case TypeCode.SByte: -// break; -// case TypeCode.Decimal: -// break; -// case TypeCode.DateTime: -// break; - case TypeCode.Char: - il.Emit (OpCodes.Ldc_I4, Convert.ToChar (defaultValue)); - break; - case TypeCode.Byte: - case TypeCode.Int16: - case TypeCode.Int32: - il.Emit (OpCodes.Ldc_I4, Convert.ToInt32 (defaultValue)); - break; - case TypeCode.UInt16: - case TypeCode.UInt32: - il.Emit (OpCodes.Ldc_I4, Convert.ToUInt32 (defaultValue)); - break; - case TypeCode.Int64: - il.Emit (OpCodes.Ldc_I8, Convert.ToInt64 (defaultValue)); - break; - case TypeCode.UInt64: - il.Emit (OpCodes.Ldc_I8, Convert.ToUInt64 (defaultValue)); - break; - case TypeCode.Single: - il.Emit (OpCodes.Ldc_R4, Convert.ToSingle (defaultValue)); - break; - case TypeCode.Double: - il.Emit (OpCodes.Ldc_R8, Convert.ToDouble (defaultValue)); - break; - case TypeCode.String: - il.Emit (OpCodes.Ldstr, Convert.ToString (defaultValue)); - break; - default: - il.Emit (OpCodes.Pop); - continue; - } - } - } else - throw new Exception ("Expecting valuetype in default values for: " + pi.Name); - }else{ - //surely a class or struct - if (dvType != typeof(string)) - throw new Exception ("Expecting String in default values for: " + pi.Name); - if (pi.PropertyType == typeof (string)) - il.Emit (OpCodes.Ldstr, Convert.ToString (defaultValue)); - else { - MethodInfo miParse = pi.PropertyType.GetMethod - ("Parse", BindingFlags.Static | BindingFlags.Public, - Type.DefaultBinder, new Type [] {typeof (string)},null); - if (miParse == null) - throw new Exception ("no Parse method found for: " + pi.PropertyType.FullName); - - il.Emit (OpCodes.Ldstr, Convert.ToString (defaultValue)); - il.Emit (OpCodes.Callvirt, miParse); - - if (miParse.ReturnType != pi.PropertyType) - il.Emit (OpCodes.Unbox_Any, pi.PropertyType); - } - } - il.Emit (OpCodes.Callvirt, pi.GetSetMethod ()); + CompilerServices.EmitSetValue (il, pi, defaultValue); } il.Emit(OpCodes.Ret); #endregion try { - Interface.DefaultValuesLoader[styleKey] = (Interface.loadDefaultInvoker)dm.CreateDelegate(typeof(Interface.loadDefaultInvoker)); + Interface.DefaultValuesLoader[styleKey] = (Interface.LoaderInvoker)dm.CreateDelegate(typeof(Interface.LoaderInvoker)); Interface.DefaultValuesLoader[styleKey] (this); } catch (Exception ex) { throw new Exception ("Error applying style <" + styleKey + ">:", ex); } } + bool getDefaultValue(PropertyInfo pi, List<Dictionary<string, object>> styling, + out object defaultValue){ + defaultValue = null; + string name = ""; + + XmlIgnoreAttribute xia = (XmlIgnoreAttribute)pi.GetCustomAttribute (typeof(XmlIgnoreAttribute)); + if (xia != null) + return false; + XmlAttributeAttribute xaa = (XmlAttributeAttribute)pi.GetCustomAttribute (typeof(XmlAttributeAttribute)); + if (xaa != null) { + if (string.IsNullOrEmpty (xaa.AttributeName)) + name = pi.Name; + else + name = xaa.AttributeName; + } + + int styleIndex = -1; + if (styling.Count > 0){ + for (int i = 0; i < styling.Count; i++) { + if (styling[i].ContainsKey (name)){ + styleIndex = i; + break; + } + } + } + if (styleIndex >= 0){ + if (pi.PropertyType.IsEnum)//maybe should be in parser.. + defaultValue = Enum.Parse(pi.PropertyType, (string)styling[styleIndex] [name], true); + else + defaultValue = styling[styleIndex] [name]; + }else { + DefaultValueAttribute dv = (DefaultValueAttribute)pi.GetCustomAttribute (typeof (DefaultValueAttribute)); + if (dv == null) + return false; + defaultValue = dv.Value; + } + return true; + } + public virtual GraphicObject FindByName(string nameToFind){ return string.Equals(nameToFind, _name, StringComparison.Ordinal) ? this : null; @@ -747,7 +658,7 @@ namespace Crow if (Width == Measure.Fit || Height == Measure.Fit) RegisterForLayouting (LayoutingType.Sizing); else if (RegisteredLayoutings == LayoutingType.None) - Interface.CurrentInterface.EnqueueForRepaint (this); + CurrentInterface.EnqueueForRepaint (this); } /// <summary> query an update of the content, a redraw </summary> [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -755,8 +666,20 @@ namespace Crow { bmp = null; if (RegisteredLayoutings == LayoutingType.None) - Interface.CurrentInterface.EnqueueForRepaint (this); + CurrentInterface.EnqueueForRepaint (this); } + public Interface CurrentInterface { + get { + ILayoutable tmp = this.Parent; + while (tmp != null) { + if (tmp is Interface) + return tmp as Interface; + tmp = tmp.Parent; + } + return null; + } + } + #region Layouting #if DEBUG_LAYOUTING @@ -1200,18 +1123,15 @@ namespace Crow } #region Binding - public void BindMember(string _member, string _expression){ - Bindings.Add(new Binding (this, _member, _expression)); - } public virtual void ResolveBindings() { - if (Bindings.Count == 0) - return; - #if DEBUG_BINDING - Debug.WriteLine ("Resolve Bindings => " + this.ToString ()); - #endif - - CompilerServices.ResolveBindings (Bindings); +// if (Bindings.Count == 0) +// return; +// #if DEBUG_BINDING +// Debug.WriteLine ("Resolve Bindings => " + this.ToString ()); +// #endif +// +// CompilerServices.ResolveBindings (Bindings); } /// <summary> @@ -1220,53 +1140,53 @@ namespace Crow /// </summary> public virtual void ClearBinding(){ //dont clear binding if dataSource is not null, - foreach (Binding b in Bindings) { - try { - if (!b.Resolved) - continue; - //cancel compiled events - if (b.Target == null){ - continue; - #if DEBUG_BINDING - Debug.WriteLine("Clear binding canceled for => " + b.ToString()); - #endif - } - if (b.Target.Instance != DataSource){ - #if DEBUG_BINDING - Debug.WriteLine("Clear binding canceled for => " + b.ToString()); - #endif - continue; - } - #if DEBUG_BINDING - Debug.WriteLine("ClearBinding => " + b.ToString()); - #endif - if (string.IsNullOrEmpty (b.DynMethodId)) { - b.Resolved = false; - if (b.Source.Member.MemberType == MemberTypes.Event) - removeEventHandler (b); - //TODO:check if full reset is necessary - continue; - } - MemberReference mr = null; - if (b.Target == null) - mr = b.Source; - else - mr = b.Target; - Type dataSourceType = mr.Instance.GetType(); - EventInfo evtInfo = dataSourceType.GetEvent ("ValueChanged"); - FieldInfo evtFi = CompilerServices.GetEventHandlerField (dataSourceType, "ValueChanged"); - MulticastDelegate multicastDelegate = evtFi.GetValue (mr.Instance) as MulticastDelegate; - if (multicastDelegate != null) { - foreach (Delegate d in multicastDelegate.GetInvocationList()) { - if (d.Method.Name == b.DynMethodId) - evtInfo.RemoveEventHandler (mr.Instance, d); - } - } - b.Reset (); - } catch (Exception ex) { - Debug.WriteLine("\t Error: " + ex.ToString()); - } - } +// foreach (Binding b in Bindings) { +// try { +// if (!b.Resolved) +// continue; +// //cancel compiled events +// if (b.Target == null){ +// continue; +// #if DEBUG_BINDING +// Debug.WriteLine("Clear binding canceled for => " + b.ToString()); +// #endif +// } +// if (b.Target.Instance != DataSource){ +// #if DEBUG_BINDING +// Debug.WriteLine("Clear binding canceled for => " + b.ToString()); +// #endif +// continue; +// } +// #if DEBUG_BINDING +// Debug.WriteLine("ClearBinding => " + b.ToString()); +// #endif +// if (string.IsNullOrEmpty (b.DynMethodId)) { +// b.Resolved = false; +// if (b.Source.Member.MemberType == MemberTypes.Event) +// removeEventHandler (b); +// //TODO:check if full reset is necessary +// continue; +// } +// MemberReference mr = null; +// if (b.Target == null) +// mr = b.Source; +// else +// mr = b.Target; +// Type dataSourceType = mr.Instance.GetType(); +// EventInfo evtInfo = dataSourceType.GetEvent ("ValueChanged"); +// FieldInfo evtFi = CompilerServices.GetEventHandlerField (dataSourceType, "ValueChanged"); +// MulticastDelegate multicastDelegate = evtFi.GetValue (mr.Instance) as MulticastDelegate; +// if (multicastDelegate != null) { +// foreach (Delegate d in multicastDelegate.GetInvocationList()) { +// if (d.Method.Name == b.DynMethodId) +// evtInfo.RemoveEventHandler (mr.Instance, d); +// } +// } +// b.Reset (); +// } catch (Exception ex) { +// Debug.WriteLine("\t Error: " + ex.ToString()); +// } +// } } void removeEventHandler(Binding b){ FieldInfo fiEvt = CompilerServices.GetEventHandlerField (b.Source.Instance.GetType(), b.Source.Member.Name); @@ -1297,7 +1217,7 @@ namespace Crow return; } if (mi.MemberType == MemberTypes.Event) { - this.Bindings.Add (new Binding (new MemberReference(this, mi), value)); + Interface.RegisterBinding (new Binding (new MemberReference(this, mi), value)); return; } if (mi.MemberType == MemberTypes.Property) { @@ -1318,7 +1238,7 @@ namespace Crow if (!value.EndsWith("}", StringComparison.Ordinal)) throw new Exception (string.Format("XML:Malformed binding: {0}", value)); - this.Bindings.Add (new Binding (new MemberReference(this, pi), value.Substring (1, value.Length - 2))); + Interface.RegisterBinding (new Binding (new MemberReference(this, pi), value.Substring (1, value.Length - 2))); return; } if (pi.GetCustomAttribute (typeof(XmlIgnoreAttribute)) != null) @@ -1341,21 +1261,34 @@ namespace Crow } public virtual void ReadXml (System.Xml.XmlReader reader) { - if (reader.HasAttributes) { - - style = reader.GetAttribute ("Style"); + IMLInstantiatorBuilder ir = reader as IMLInstantiatorBuilder; + Type thisType = this.GetType (); - loadDefaultValues (); + if (ir.HasAttributes) { + style = ir.GetAttribute ("Style"); + if (!string.IsNullOrEmpty (style)) { + PropertyInfo pi = thisType.GetProperty ("Style"); + CompilerServices.EmitSetValue (ir.il, pi, style); + } + } + if (ir.HasAttributes) { + ir.il.Emit (OpCodes.Ldarg_0); + ir.il.Emit (OpCodes.Callvirt, typeof(GraphicObject).GetMethod ("loadDefaultValues")); - while (reader.MoveToNextAttribute ()) { - if (reader.Name == "Style") + while (ir.MoveToNextAttribute ()) { + if (ir.Name == "Style") continue; - affectMember (reader.Name, reader.Value); + PropertyInfo pi = thisType.GetProperty (ir.Name); + + if (pi == null) + throw new Exception ("Member '" + ir.Name + "' not found in " + thisType.Name); + + CompilerServices.EmitSetValue (ir.il, pi, ir.Value); + } - reader.MoveToElement (); - }else - loadDefaultValues (); + ir.MoveToElement (); + } } public virtual void WriteXml (System.Xml.XmlWriter writer) { @@ -1445,6 +1378,8 @@ namespace Crow } #endregion + + #region ICloneable implementation public object Clone () { @@ -1470,8 +1405,8 @@ namespace Crow /// </summary> public virtual GraphicObject DeepClone(){ GraphicObject tmp = Clone () as GraphicObject; - foreach (Binding b in this.bindings) - tmp.Bindings.Add (new Binding (new MemberReference (tmp, b.Source.Member), b.Expression)); +// foreach (Binding b in this.bindings) +// tmp.Bindings.Add (new Binding (new MemberReference (tmp, b.Source.Member), b.Expression)); return tmp; } } diff --git a/src/GraphicObjects/Grid.cs b/src/GraphicObjects/Grid.cs index 525827e0..ed0cd986 100644 --- a/src/GraphicObjects/Grid.cs +++ b/src/GraphicObjects/Grid.cs @@ -29,11 +29,10 @@ namespace Crow int _rowCount; #endregion - public override T AddChild<T> (T child) + public override void AddChild (GraphicObject child) { - T tmp = base.AddChild (child); + base.AddChild (child); this.RegisterForLayouting (LayoutingType.ArrangeChildren); - return tmp; } public override void RemoveChild (GraphicObject child) { diff --git a/src/GraphicObjects/Group.cs b/src/GraphicObjects/Group.cs index a6ca5758..4c8d0537 100644 --- a/src/GraphicObjects/Group.cs +++ b/src/GraphicObjects/Group.cs @@ -38,19 +38,14 @@ namespace Crow get { return _multiSelect; } set { _multiSelect = value; } } - - - public virtual T AddChild<T>(T child) - { - GraphicObject g = child as GraphicObject; + public virtual void AddChild(GraphicObject g){ Children.Add(g); - g.Parent = this as GraphicObject; + g.Parent = this; g.ResolveBindings (); g.RegisteredLayoutings = LayoutingType.None; g.RegisterForLayouting (LayoutingType.Sizing | LayoutingType.ArrangeChildren); g.LayoutChanged += OnChildLayoutChanges; - return (T)child; - } + } public virtual void RemoveChild(GraphicObject child) { child.LayoutChanged -= OnChildLayoutChanges; diff --git a/src/GraphicObjects/IBindable.cs b/src/GraphicObjects/IBindable.cs deleted file mode 100644 index 45ff5864..00000000 --- a/src/GraphicObjects/IBindable.cs +++ /dev/null @@ -1,32 +0,0 @@ -// -// IValueChange.cs -// -// Author: -// Jean-Philippe Bruyère <jp.bruyere@hotmail.com> -// -// Copyright (c) 2015 jp -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -using System; -using System.Collections.Generic; - -namespace Crow -{ - public interface IBindable - { - List<Binding> Bindings { get; } - object DataSource { get; set; } - } -} - diff --git a/src/GraphicObjects/ListBox.cs b/src/GraphicObjects/ListBox.cs index 58d41e0b..397ef53d 100644 --- a/src/GraphicObjects/ListBox.cs +++ b/src/GraphicObjects/ListBox.cs @@ -151,10 +151,10 @@ namespace Crow //because _list total size is forced to approx size if (_gsList.Orientation == Orientation.Horizontal) { page.Width = Measure.Fit; - page.BindMember ("Height", "../HeightPolicy"); + Interface.Bindings.Add(new Binding (this, "Height", "../HeightPolicy")); } else { page.Height = Measure.Fit; - page.BindMember ("Width", "../WidthPolicy"); + Interface.Bindings.Add(new Binding (this, "Width", "../WidthPolicy")); } for (int i = (pageNum - 1) * itemPerPage; i < pageNum * itemPerPage; i++) { diff --git a/src/GraphicObjects/PrivateContainer.cs b/src/GraphicObjects/PrivateContainer.cs index 8793ba45..51d76604 100644 --- a/src/GraphicObjects/PrivateContainer.cs +++ b/src/GraphicObjects/PrivateContainer.cs @@ -22,6 +22,7 @@ using System; using System.Xml.Serialization; using System.ComponentModel; using Cairo; +using System.Diagnostics; namespace Crow { @@ -47,7 +48,7 @@ namespace Crow protected GraphicObject child; - protected virtual T SetChild<T>(T _child) + internal virtual void SetChild(GraphicObject _child) { if (child != null) { @@ -67,8 +68,8 @@ namespace Crow child.RegisteredLayoutings = LayoutingType.None; child.RegisterForLayouting (LayoutingType.Sizing); } + Debug.WriteLine ("privateContainer setChild"); - return (T)_child; } #region GraphicObject Overrides diff --git a/src/GraphicObjects/Scroller.cs b/src/GraphicObjects/Scroller.cs index 3eaff5f4..c248595d 100644 --- a/src/GraphicObjects/Scroller.cs +++ b/src/GraphicObjects/Scroller.cs @@ -148,7 +148,7 @@ namespace Crow ScrollY = 0; ScrollX = 0; } - public override T SetChild<T> (T _child) + public override void SetChild (GraphicObject _child) { GraphicObject c = child as GraphicObject; Group g = child as Group; @@ -164,7 +164,7 @@ namespace Crow if (g != null) g.ChildrenCleared += onChildListCleared; } - return base.SetChild (_child); + base.SetChild (_child); } #endregion diff --git a/src/GraphicObjects/TabView.cs b/src/GraphicObjects/TabView.cs index d616ffc6..015f5f4f 100644 --- a/src/GraphicObjects/TabView.cs +++ b/src/GraphicObjects/TabView.cs @@ -100,7 +100,7 @@ namespace Crow set { } } - public override T AddChild<T> (T child) + public override void AddChild (GraphicObject child) { TabItem ti = child as TabItem; if (ti == null) @@ -113,7 +113,7 @@ namespace Crow SelectedTab = 0; } - return base.AddChild (child); + base.AddChild (child); } public override void RemoveChild (GraphicObject child) { |