From fd19c1fd6960faf9b7131a4dfade4bba95abcf81 Mon Sep 17 00:00:00 2001 From: jpbruyere Date: Mon, 18 May 2015 18:13:48 +0200 Subject: [PATCH] Simple bindings demonstration in testFps --- GOLib.csproj | 27 ++++-- GOLib.sln | 12 +-- Images/Icons/updown.svg | 46 ++++++++++ Tests/GOLIBTest_1.cs | 2 +- Tests/GOLIBTest_4.cs | 6 +- Tests/GOLIBTest_fps.cs | 54 ++++++++--- Tests/IValueChange.cs | 23 +++++ Tests/Interfaces/fps.goml | 6 +- Tests/Interfaces/log.xml | 21 +++++ Tests/Tests.csproj | 7 +- src/CompilerServices/CompilerServices.cs | 112 ++++++++++++++++++++++- src/{EventSource.cs => DynAttribute.cs} | 6 +- src/GraphicObjects/Checkbox.cs | 6 +- src/GraphicObjects/GraphicObject.cs | 20 +++- src/GraphicObjects/Group.cs | 5 +- src/GraphicObjects/IValueChange.cs | 30 ++++++ src/GraphicObjects/Image.cs | 1 - src/GraphicObjects/NumericControl.cs | 46 +++++----- src/GraphicObjects/Spinner.cs | 43 +++++++++ src/GraphicObjects/TextBox.cs | 31 +------ src/Interface.cs | 50 ++++++---- src/TextChangeEventArgs.cs | 9 +- 22 files changed, 439 insertions(+), 124 deletions(-) create mode 100644 Images/Icons/updown.svg create mode 100644 Tests/IValueChange.cs create mode 100755 Tests/Interfaces/log.xml rename src/{EventSource.cs => DynAttribute.cs} (60%) create mode 100644 src/GraphicObjects/IValueChange.cs create mode 100644 src/GraphicObjects/Spinner.cs diff --git a/GOLib.csproj b/GOLib.csproj index 567b61c5..3cc7e7e2 100644 --- a/GOLib.csproj +++ b/GOLib.csproj @@ -38,6 +38,9 @@ None 4194304 + + __linux__ + - - - - @@ -239,6 +238,18 @@ + + + + + + + + + + + + @@ -294,16 +305,12 @@ - - - - - - go.image.icons.question_mark + + diff --git a/GOLib.sln b/GOLib.sln index 7b897639..98b5962c 100644 --- a/GOLib.sln +++ b/GOLib.sln @@ -24,16 +24,15 @@ Global {232716B4-D19D-4FD7-B310-94A98FD926F0}.Documentation|Any CPU.Build.0 = Debug|Any CPU {232716B4-D19D-4FD7-B310-94A98FD926F0}.Nsis|Any CPU.ActiveCfg = Debug|Any CPU {232716B4-D19D-4FD7-B310-94A98FD926F0}.Nsis|Any CPU.Build.0 = Debug|Any CPU - {232716B4-D19D-4FD7-B310-94A98FD926F0}.Release|Linux_x86.ActiveCfg = Release|Linux_x86 - {232716B4-D19D-4FD7-B310-94A98FD926F0}.Release|Linux_x86.Build.0 = Release|Linux_x86 + {232716B4-D19D-4FD7-B310-94A98FD926F0}.Release|Linux_x86.ActiveCfg = Debug|Any CPU {74289092-9F70-4941-AFCB-DFD7BE2140B6}.Debug|Linux_x86.ActiveCfg = Debug|Any CPU {74289092-9F70-4941-AFCB-DFD7BE2140B6}.Debug|Linux_x86.Build.0 = Debug|Any CPU {74289092-9F70-4941-AFCB-DFD7BE2140B6}.Documentation|Any CPU.ActiveCfg = Debug|Any CPU {74289092-9F70-4941-AFCB-DFD7BE2140B6}.Documentation|Any CPU.Build.0 = Debug|Any CPU {74289092-9F70-4941-AFCB-DFD7BE2140B6}.Nsis|Any CPU.ActiveCfg = Debug|Any CPU {74289092-9F70-4941-AFCB-DFD7BE2140B6}.Nsis|Any CPU.Build.0 = Debug|Any CPU - {74289092-9F70-4941-AFCB-DFD7BE2140B6}.Release|Linux_x86.ActiveCfg = Release|Linux_x86 - {74289092-9F70-4941-AFCB-DFD7BE2140B6}.Release|Linux_x86.Build.0 = Release|Linux_x86 + {74289092-9F70-4941-AFCB-DFD7BE2140B6}.Release|Linux_x86.ActiveCfg = Release|Any CPU + {74289092-9F70-4941-AFCB-DFD7BE2140B6}.Release|Linux_x86.Build.0 = Release|Any CPU {A37A7E14-0000-0000-0000-000000000000}.Debug|Linux_x86.ActiveCfg = Release|Any CPU {A37A7E14-0000-0000-0000-000000000000}.Debug|Linux_x86.Build.0 = Release|Any CPU {A37A7E14-0000-0000-0000-000000000000}.Documentation|Any CPU.ActiveCfg = Documentation|Any CPU @@ -48,14 +47,13 @@ Global {C2980F9B-4798-4C05-99E2-E174810F7C7B}.Documentation|Any CPU.Build.0 = Debug|Any CPU {C2980F9B-4798-4C05-99E2-E174810F7C7B}.Nsis|Any CPU.ActiveCfg = Debug|Any CPU {C2980F9B-4798-4C05-99E2-E174810F7C7B}.Nsis|Any CPU.Build.0 = Debug|Any CPU - {C2980F9B-4798-4C05-99E2-E174810F7C7B}.Release|Linux_x86.ActiveCfg = Release|Linux_x86 - {C2980F9B-4798-4C05-99E2-E174810F7C7B}.Release|Linux_x86.Build.0 = Release|Linux_x86 + {C2980F9B-4798-4C05-99E2-E174810F7C7B}.Release|Linux_x86.ActiveCfg = Release|Any CPU + {C2980F9B-4798-4C05-99E2-E174810F7C7B}.Release|Linux_x86.Build.0 = Release|Any CPU {E9E14DB5-3C67-4E01-B5C3-4D90D7E31A2E}.Debug|Linux_x86.ActiveCfg = Debug|Any CPU {E9E14DB5-3C67-4E01-B5C3-4D90D7E31A2E}.Documentation|Any CPU.ActiveCfg = Debug|Any CPU {E9E14DB5-3C67-4E01-B5C3-4D90D7E31A2E}.Documentation|Any CPU.Build.0 = Debug|Any CPU {E9E14DB5-3C67-4E01-B5C3-4D90D7E31A2E}.Nsis|Any CPU.ActiveCfg = Debug|Any CPU {E9E14DB5-3C67-4E01-B5C3-4D90D7E31A2E}.Nsis|Any CPU.Build.0 = Debug|Any CPU {E9E14DB5-3C67-4E01-B5C3-4D90D7E31A2E}.Release|Linux_x86.ActiveCfg = Release|Any CPU - {E9E14DB5-3C67-4E01-B5C3-4D90D7E31A2E}.Release|Linux_x86.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/Images/Icons/updown.svg b/Images/Icons/updown.svg new file mode 100644 index 00000000..df22a28b --- /dev/null +++ b/Images/Icons/updown.svg @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + diff --git a/Tests/GOLIBTest_1.cs b/Tests/GOLIBTest_1.cs index f92cd16c..1f376047 100644 --- a/Tests/GOLIBTest_1.cs +++ b/Tests/GOLIBTest_1.cs @@ -27,7 +27,7 @@ namespace test protected override void OnLoad (EventArgs e) { base.OnLoad (e); - LoadInterface("Interfaces/test1.goml", out g); + LoadInterface("Interfaces/log.xml", out g); } protected override void OnRenderFrame (FrameEventArgs e) diff --git a/Tests/GOLIBTest_4.cs b/Tests/GOLIBTest_4.cs index 5ee286b6..1f244e16 100644 --- a/Tests/GOLIBTest_4.cs +++ b/Tests/GOLIBTest_4.cs @@ -82,9 +82,9 @@ namespace test c.MouseMove += pFps_mousemove; - slTest.ValueChanged += (object sender, ValueChangeEventArgs vce) => { - labV.Text = vce.NewValue.ToString ("00.00"); - }; +// slTest.ValueChanged += (object sender, ValueChangeEventArgs vce) => { +// labV.Text = vce.NewValue.ToString ("00.00"); +// }; int i = 0; diff --git a/Tests/GOLIBTest_fps.cs b/Tests/GOLIBTest_fps.cs index 946eb5e1..aaf5631e 100644 --- a/Tests/GOLIBTest_fps.cs +++ b/Tests/GOLIBTest_fps.cs @@ -16,27 +16,49 @@ using System.Threading; namespace test { - class GOLIBTest_fps : OpenTKGameWindow + class GOLIBTest_fps : OpenTKGameWindow , IValueChange { #region FPS - static int _fps = 0; + int _fps = 0; - public static int fps { + public int fps { get { return _fps; } set { + if (_fps == value) + return; + + int oldVal = _fps; _fps = value; - if (_fps > fpsMax) + + if (_fps > fpsMax) { fpsMax = _fps; - else if (_fps < fpsMin) + ValueChanged(this, new ValueChangeEventArgs ("fpsMax", fpsMax, _fps)); + } else if (_fps < fpsMin) { + ValueChanged(this, new ValueChangeEventArgs ("fpsMin", fpsMin, _fps)); fpsMin = _fps; + } + + if (ValueChanged != null) + ValueChanged(this, new ValueChangeEventArgs ("fps", oldVal, _fps)); + + //ValueChanged.Raise (this, new ValueChangeEventArgs ("fps", oldVal, _fps)); } + } + string name = "testName"; + public string Name { + get { + return name; + } + set { + name = value; + } } - public static int fpsMin = int.MaxValue; - public static int fpsMax = 0; + public int fpsMin = int.MaxValue; + public int fpsMax = 0; - static void resetFps () + void resetFps () { fpsMin = int.MaxValue; fpsMax = 0; @@ -61,6 +83,9 @@ namespace test labFpsMax = g.FindByName ("labFpsMax") as Label; labUpdate = g.FindByName ("labUpdate") as Label; + //ValueChanged += (object sender, ValueChangeEventArgs vce) => labFps.Text = vce.NewValue.ToString (); + + } protected override void OnRenderFrame (FrameEventArgs e) { @@ -76,11 +101,12 @@ namespace test fps = (int)RenderFrequency; - labFps.Text = fps.ToString(); + //labFps.Text = fps.ToString(); labUpdate.Text = this.updateTime.ElapsedMilliseconds.ToString() + " ms"; + if (frameCpt > 200) { - labFpsMin.Text = fpsMin.ToString(); - labFpsMax.Text = fpsMax.ToString(); +// labFpsMin.Text = fpsMin.ToString(); +// labFpsMax.Text = fpsMax.ToString(); resetFps (); frameCpt = 0; @@ -88,6 +114,12 @@ namespace test frameCpt++; } + #region IValueChange implementation + + public event EventHandler ValueChanged; + + #endregion + [STAThread] static void Main () { diff --git a/Tests/IValueChange.cs b/Tests/IValueChange.cs new file mode 100644 index 00000000..94499138 --- /dev/null +++ b/Tests/IValueChange.cs @@ -0,0 +1,23 @@ +#define MONO_CAIRO_DEBUG_DISPOSE + + +using System; +using System.Runtime.InteropServices; +using OpenTK; +using OpenTK.Graphics.OpenGL; +using OpenTK.Input; + +using System.Diagnostics; + +//using GGL; +using go; +using System.Threading; + + +namespace test +{ + interface IValueChange + { + } + +} \ No newline at end of file diff --git a/Tests/Interfaces/fps.goml b/Tests/Interfaces/fps.goml index 85b60afd..7c18d4ce 100755 --- a/Tests/Interfaces/fps.goml +++ b/Tests/Interfaces/fps.goml @@ -10,17 +10,17 @@ diff --git a/Tests/Interfaces/log.xml b/Tests/Interfaces/log.xml new file mode 100755 index 00000000..1039f7be --- /dev/null +++ b/Tests/Interfaces/log.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index 02a19005..d80400f0 100644 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -8,7 +8,7 @@ Exe Tests Tests - test.GOLIBTest_4 + test.GOLIBTest_fps v4.5 ..\bin\$(configuration) obj\$(configuration) @@ -142,6 +142,11 @@ PreserveNewest + + + + PreserveNewest + diff --git a/src/CompilerServices/CompilerServices.cs b/src/CompilerServices/CompilerServices.cs index 034180d1..36c88030 100644 --- a/src/CompilerServices/CompilerServices.cs +++ b/src/CompilerServices/CompilerServices.cs @@ -1,6 +1,10 @@ using System; using System.Reflection.Emit; using System.Reflection; +using System.Collections; +using System.Diagnostics; +using System.Linq; + namespace go { @@ -33,12 +37,12 @@ namespace go } static int dynHandleCpt = 0; - public static void CompileEventSource(EventSource es) + public static void CompileEventSource(DynAttribute es) { Type srcType = es.Source.GetType (); #region Retrieve EventHandler parameter type - EventInfo ei = srcType.GetEvent (es.EventName); + EventInfo ei = srcType.GetEvent (es.MemberName); MethodInfo invoke = ei.EventHandlerType.GetMethod ("Invoke"); ParameterInfo[] pars = invoke.GetParameters (); @@ -54,10 +58,10 @@ namespace go #region IL generation ILGenerator il = dm.GetILGenerator(256); - string src = es.Handler.Trim(); + string src = es.Value.Trim(); if (! (src.StartsWith("{") || src.EndsWith ("}"))) - throw new Exception (string.Format("GOML:Malformed {0} Event handler: {1}", es.EventName, es.Handler)); + throw new Exception (string.Format("GOML:Malformed {0} Event handler: {1}", es.MemberName, es.Value)); src = src.Substring (1, src.Length - 2); string[] srcLines = src.Split (new char[] { ';' }); @@ -145,11 +149,109 @@ namespace go #endregion - FieldInfo evtFi = getEventHandlerField (srcType, es.EventName); + FieldInfo evtFi = getEventHandlerField (srcType, es.MemberName); Delegate del = dm.CreateDelegate(evtFi.FieldType); evtFi.SetValue(es.Source, del); } + public static void CreateBinding(DynAttribute binding, object _source) + { + + Type srcType = _source.GetType (); + Type dstType = binding.Source.GetType (); + + MemberInfo miSrc = srcType.GetMember (binding.Value).FirstOrDefault(); + Type srcValueType = null; + if (miSrc.MemberType == MemberTypes.Property) + srcValueType = (miSrc as PropertyInfo).PropertyType; + else if (miSrc.MemberType == MemberTypes.Field) + srcValueType = (miSrc as FieldInfo).FieldType; + else + throw new Exception("unandled source type for binding"); + + #region Retrieve EventHandler parameter type + EventInfo ei = srcType.GetEvent ("ValueChanged"); + MethodInfo evtInvoke = ei.EventHandlerType.GetMethod ("Invoke"); + ParameterInfo[] evtParams = evtInvoke.GetParameters (); + + Type handlerArgsType = evtParams [1].ParameterType; + #endregion + + Type[] args = {typeof(object), handlerArgsType}; + DynamicMethod dm = new DynamicMethod("dynHandle_" + dynHandleCpt, + typeof(void), + args, + srcType.Module, true); + + //register target object reference + int dstIdx = Interface.References.IndexOf(binding.Source); + + if (dstIdx < 0) { + dstIdx = Interface.References.Count; + Interface.References.Add (binding.Source); + } + + + + #region IL generation + ILGenerator il = dm.GetILGenerator(256); + + System.Reflection.Emit.Label labFailed = il.DefineLabel(); + System.Reflection.Emit.Label labContinue = il.DefineLabel(); + + #region test if valueChange event is the correct one + il.Emit (OpCodes.Ldstr, binding.Value); + //push name from arg + il.Emit(OpCodes.Ldarg_1); + FieldInfo fiMbName = typeof(ValueChangeEventArgs).GetField("MemberName"); + il.Emit(OpCodes.Ldfld, fiMbName); + MethodInfo miStrEqu = typeof(string).GetMethod("op_Inequality", new Type[] {typeof(string),typeof(string)}); + il.Emit(OpCodes.Call, miStrEqu); + il.Emit(OpCodes.Brfalse_S, labContinue); + il.Emit(OpCodes.Br_S, labFailed); + il.MarkLabel(labContinue); + #endregion + + string[] srcLines = binding.Value.Trim().Split (new char[] { ';' }); + foreach (string srcLine in srcLines) { + MethodInfo infoWriteLine = typeof(System.Diagnostics.Debug).GetMethod("WriteLine", new Type[] { typeof(string) }); + + string statement = srcLine.Trim (); + + //load target ref onto the stack + FieldInfo fiRefs = typeof(Interface).GetField("References"); + il.Emit(OpCodes.Ldsfld, fiRefs); + il.Emit(OpCodes.Ldc_I4, dstIdx); + + MethodInfo miGetRef = Interface.References.GetType().GetMethod("get_Item"); + il.Emit(OpCodes.Callvirt, miGetRef); + il.Emit(OpCodes.Isinst, dstType); + + //push new value + il.Emit(OpCodes.Ldarg_1); + FieldInfo fiNewValue = typeof(ValueChangeEventArgs).GetField("NewValue"); + il.Emit(OpCodes.Ldfld, fiNewValue); + + PropertyInfo piTarget = dstType.GetProperty(binding.MemberName); + MethodInfo miToStr = typeof(object).GetMethod("ToString",Type.EmptyTypes); + + if (!srcValueType.IsValueType) + il.Emit(OpCodes.Castclass, srcValueType); + il.Emit(OpCodes.Callvirt, miToStr); + il.Emit(OpCodes.Callvirt, piTarget.GetSetMethod()); + } + il.MarkLabel(labFailed); + il.Emit(OpCodes.Ret); + + #endregion + + Delegate del = dm.CreateDelegate(ei.EventHandlerType); + MethodInfo addHandler = ei.GetAddMethod (); + //Delegate del = dm.CreateDelegate(typeof(System.EventHandler)); + addHandler.Invoke(_source, new object[] {del}); + } + + public static FieldInfo getEventHandlerField(Type type, string eventName) { FieldInfo fi; diff --git a/src/EventSource.cs b/src/DynAttribute.cs similarity index 60% rename from src/EventSource.cs rename to src/DynAttribute.cs index d8065cd1..db2be2b0 100755 --- a/src/EventSource.cs +++ b/src/DynAttribute.cs @@ -5,10 +5,10 @@ using System.Text; namespace go { - public class EventSource + public class DynAttribute { public GraphicObject Source; - public string EventName; - public String Handler; + public string MemberName; + public String Value; } } diff --git a/src/GraphicObjects/Checkbox.cs b/src/GraphicObjects/Checkbox.cs index 3c25c741..586855d9 100644 --- a/src/GraphicObjects/Checkbox.cs +++ b/src/GraphicObjects/Checkbox.cs @@ -242,11 +242,11 @@ namespace go public override void ReadXml(System.Xml.XmlReader reader) { string handler = reader.GetAttribute("OnClick"); - Interface.EventsToResolve.Add(new EventSource + Interface.EventsToResolve.Add(new DynAttribute { Source = this, - Handler = handler, - EventName = "OnClick" + Value = handler, + MemberName = "OnClick" }); //Container c = this as Container; diff --git a/src/GraphicObjects/GraphicObject.cs b/src/GraphicObjects/GraphicObject.cs index a7b9e93e..683e88f3 100644 --- a/src/GraphicObjects/GraphicObject.cs +++ b/src/GraphicObjects/GraphicObject.cs @@ -108,6 +108,7 @@ namespace go public event EventHandler KeyUp; public event EventHandler Focused; public event EventHandler Unfocused; + #endregion #region public properties @@ -641,11 +642,11 @@ namespace go if (string.IsNullOrEmpty (handler)) continue; - Interface.EventsToResolve.Add(new EventSource + Interface.EventsToResolve.Add(new DynAttribute { Source = this, - Handler = handler, - EventName = ei.Name + Value = handler, + MemberName = ei.Name }); } foreach (PropertyInfo pi in this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) { @@ -713,6 +714,19 @@ namespace go else pi.SetValue (this, defaultValue, null); } else { + if (v.StartsWith("{")) { + //binding + if (!v.EndsWith("}")) + throw new Exception (string.Format("GOML:Malformed binding: {0}", v)); + + string strBinding = v.Substring (1, v.Length - 2); + Interface.Bindings.Add (new DynAttribute () { + Source = this, + MemberName = name, + Value = strBinding + }); + } + if (pi.PropertyType == typeof(string)) { pi.SetValue (this, v, null); continue; diff --git a/src/GraphicObjects/Group.cs b/src/GraphicObjects/Group.cs index 7b63156f..a2a04e0b 100644 --- a/src/GraphicObjects/Group.cs +++ b/src/GraphicObjects/Group.cs @@ -120,7 +120,10 @@ namespace go return tmp; } - + public override void RegisterForLayouting (int layoutType) + { + base.RegisterForLayouting (layoutType); + } public override Rectangle ContextCoordinates(Rectangle r){ return r + ClientRectangle.Position; diff --git a/src/GraphicObjects/IValueChange.cs b/src/GraphicObjects/IValueChange.cs new file mode 100644 index 00000000..4dc886b0 --- /dev/null +++ b/src/GraphicObjects/IValueChange.cs @@ -0,0 +1,30 @@ +// +// IValueChange.cs +// +// Author: +// Jean-Philippe Bruyère +// +// 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 . +using System; + +namespace go +{ + public interface IValueChange + { + event EventHandler ValueChanged; + } +} + diff --git a/src/GraphicObjects/Image.cs b/src/GraphicObjects/Image.cs index aa3ea56d..3858aebc 100755 --- a/src/GraphicObjects/Image.cs +++ b/src/GraphicObjects/Image.cs @@ -71,7 +71,6 @@ namespace go hSVG = new Rsvg.Handle (ms.ToArray ()); imgSize = new Size (hSVG.Dimensions.Width, hSVG.Dimensions.Height); _imgPath = resId; - //loadImage (@"Images/Icons/question_mark.svg"); } } //load image via System.Drawing.Bitmap, cairo load png only diff --git a/src/GraphicObjects/NumericControl.cs b/src/GraphicObjects/NumericControl.cs index 93aadc84..2eb54bca 100644 --- a/src/GraphicObjects/NumericControl.cs +++ b/src/GraphicObjects/NumericControl.cs @@ -13,10 +13,10 @@ namespace go public NumericControl(double minimum, double maximum, double step) : base() { - _minValue = minimum; - _maxValue = maximum; - _smallStep = step; - _bigStep = step * 5; + minValue = minimum; + maxValue = maximum; + smallStep = step; + bigStep = step * 5; } #endregion @@ -30,54 +30,54 @@ namespace go #endregion #region private fields - double _actualValue, _minValue, _maxValue, _smallStep, _bigStep; + double _actualValue, minValue, maxValue, smallStep, bigStep; #endregion #region public properties [XmlAttributeAttribute()][DefaultValue(0)] public virtual double Minimum { - get { return _minValue; } + get { return minValue; } set { - if (_minValue == value) + if (minValue == value) return; - _minValue = value; + minValue = value; } } [XmlAttributeAttribute()][DefaultValue(10.0)] public virtual double Maximum { - get { return _maxValue; } + get { return maxValue; } set { - if (_maxValue == value) + if (maxValue == value) return; - _maxValue = value; + maxValue = value; } } [XmlAttributeAttribute()][DefaultValue(0.5)] public virtual double SmallIncrement { - get { return _smallStep; } + get { return smallStep; } set { - if (_smallStep == value) + if (smallStep == value) return; - _smallStep = value; + smallStep = value; } } [XmlAttributeAttribute()][DefaultValue(2.0)] public virtual double LargeIncrement { - get { return _bigStep; } + get { return bigStep; } set { - if (_bigStep == value) + if (bigStep == value) return; - _bigStep = value; + bigStep = value; } } @@ -90,16 +90,16 @@ namespace go if (value == _actualValue) return; - Decimal oldV = (Decimal)_actualValue; + int oldV = Convert.ToInt32(_actualValue); - if (value < _minValue) - _actualValue = _minValue; - else if (value > _maxValue) - _actualValue = _maxValue; + if (value < minValue) + _actualValue = minValue; + else if (value > maxValue) + _actualValue = maxValue; else _actualValue = value; - onValueChanged(this,new ValueChangeEventArgs(oldV,(Decimal)_actualValue)); + onValueChanged(this,new ValueChangeEventArgs("Value", oldV, Convert.ToInt32( _actualValue))); registerForGraphicUpdate(); } } diff --git a/src/GraphicObjects/Spinner.cs b/src/GraphicObjects/Spinner.cs new file mode 100644 index 00000000..dcf0d3d4 --- /dev/null +++ b/src/GraphicObjects/Spinner.cs @@ -0,0 +1,43 @@ +// +// Spinner.cs +// +// Author: +// Jean-Philippe Bruyère +// +// 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 . +using System; + +namespace go +{ + public class Spinner : NumericControl + { + public Spinner (double minimum, double maximum, double step) : + base (minimum, maximum, step) + { + butUp = new Button (); + butUp.setChild (new Image ("go.Image.Icons.updown.svg")); + } + public Spinner () : base() + { + } + + Button butUp; + Button butDown; + Label labCpt; + + } +} + diff --git a/src/GraphicObjects/TextBox.cs b/src/GraphicObjects/TextBox.cs index 20403789..28e7c74c 100644 --- a/src/GraphicObjects/TextBox.cs +++ b/src/GraphicObjects/TextBox.cs @@ -15,7 +15,7 @@ namespace go public class TextBoxWidget : Label { #region CTOR - public TextBoxWidget(string _initialValue, GOEvent _onTextChanged = null) + public TextBoxWidget(string _initialValue) : base(_initialValue) { @@ -25,19 +25,6 @@ namespace go { } #endregion - static bool _capitalOn = false; //???????????????? - [XmlIgnore]public static bool capitalOn - { - get - { - return _capitalOn; - //Keyboard[Key.ShiftLeft] || Keyboard[Key.ShiftRight] ? - //!_capitalOn : _capitalOn; - } - set { _capitalOn = value; } - } - - #region GraphicObject overrides [XmlIgnore]public override bool HasFocus //trigger update when lost focus to errase text beam { @@ -71,23 +58,7 @@ namespace go protected override void onDraw (Context gr) { base.onDraw (gr); - // gr.FontOptions.Antialias = Antialias.Subpixel; - // gr.FontOptions.HintMetrics = HintMetrics.On; -// gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight); -// gr.SetFontSize (Font.Size); - FontExtents fe = gr.FontExtents; - - - -// gr.MoveTo(rText.X, rText.Y + fe.Ascent); -// #if _WIN32 || _WIN64 -// gr.ShowText(txt); -// #elif __linux__ -// gr.ShowText(Text); -// #endif -// gr.Fill(); - } #endregion diff --git a/src/Interface.cs b/src/Interface.cs index 8684d851..776dd9a6 100644 --- a/src/Interface.cs +++ b/src/Interface.cs @@ -25,6 +25,7 @@ using System.Reflection; using System.Diagnostics; using System.Collections.Generic; using System.Xml; +using System.Linq; namespace go { @@ -35,11 +36,17 @@ namespace go public static bool ReplaceTabsWithSpace = false; public static bool DesignerMode = false; + /// + /// Graphic objects References use in dynamic delegates for binding + /// + public static List References = new List(); + public static LayoutingQueue LayoutingQueue = new LayoutingQueue(); #region Load/Save - internal static List EventsToResolve; + internal static List EventsToResolve; + internal static List Bindings; public static void Save(string file, T graphicObject) { @@ -68,12 +75,13 @@ namespace go } } Type t = Type.GetType("go." + root); - var go = Activator.CreateInstance(t); + //var go = Activator.CreateInstance(t); return Load(path, t); } public static void Load(string file, out T result, object ClassContainingHandlers = null) { - EventsToResolve = new List(); + EventsToResolve = new List(); + Bindings = new List (); XmlSerializerNamespaces xn = new XmlSerializerNamespaces(); xn.Add("", ""); @@ -87,32 +95,42 @@ namespace go if (ClassContainingHandlers == null) return; - foreach (EventSource es in EventsToResolve) + foreach (DynAttribute es in EventsToResolve) { - if (string.IsNullOrEmpty(es.Handler)) + if (string.IsNullOrEmpty(es.Value)) continue; - if (es.Handler.StartsWith ("{")) { + if (es.Value.StartsWith ("{")) { CompilerServices.CompileEventSource (es); } else { - MethodInfo mi = ClassContainingHandlers.GetType ().GetMethod (es.Handler, BindingFlags.NonPublic | BindingFlags.Public + MethodInfo mi = ClassContainingHandlers.GetType ().GetMethod (es.Value, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); if (mi == null) { - Debug.WriteLine ("Handler Method not found: " + es.Handler); + Debug.WriteLine ("Handler Method not found: " + es.Value); continue; } - FieldInfo fi = CompilerServices.getEventHandlerField (es.Source.GetType (), es.EventName); + FieldInfo fi = CompilerServices.getEventHandlerField (es.Source.GetType (), es.MemberName); Delegate del = Delegate.CreateDelegate(fi.FieldType, ClassContainingHandlers, mi); fi.SetValue(es.Source, del); } } + + foreach (DynAttribute binding in Bindings) { +// Type tSource = binding.Source.GetType (); +// if (!tSource.GetInterfaces ().Any (i => i.Name == "IValueChange")){ +// Debug.WriteLine ("Binding source does not implement IValueChange."); +// continue; +// } + //MemberInfo mi = binding.Source.GetType ().GetMember (binding.MemberName); + CompilerServices.CreateBinding (binding, ClassContainingHandlers); + } } public static GraphicObject Load(string file, Type type, object ClassContainingHandlers = null) { GraphicObject result; - EventsToResolve = new List(); + EventsToResolve = new List(); XmlSerializerNamespaces xn = new XmlSerializerNamespaces(); xn.Add("", ""); @@ -126,23 +144,23 @@ namespace go if (ClassContainingHandlers == null) return result; - foreach (EventSource es in EventsToResolve) + foreach (DynAttribute es in EventsToResolve) { - if (string.IsNullOrEmpty(es.Handler)) + if (string.IsNullOrEmpty(es.Value)) continue; - if (es.Handler.StartsWith ("{")) { + if (es.Value.StartsWith ("{")) { CompilerServices.CompileEventSource (es); } else { - MethodInfo mi = ClassContainingHandlers.GetType ().GetMethod (es.Handler, BindingFlags.NonPublic | BindingFlags.Public + MethodInfo mi = ClassContainingHandlers.GetType ().GetMethod (es.Value, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance); if (mi == null) { - Debug.WriteLine ("Handler Method not found: " + es.Handler); + Debug.WriteLine ("Handler Method not found: " + es.Value); continue; } - FieldInfo fi = CompilerServices.getEventHandlerField (es.Source.GetType (), es.EventName); + FieldInfo fi = CompilerServices.getEventHandlerField (es.Source.GetType (), es.MemberName); Delegate del = Delegate.CreateDelegate(fi.FieldType, ClassContainingHandlers, mi); fi.SetValue(es.Source, del); } diff --git a/src/TextChangeEventArgs.cs b/src/TextChangeEventArgs.cs index b826fe4a..726c9ae9 100644 --- a/src/TextChangeEventArgs.cs +++ b/src/TextChangeEventArgs.cs @@ -4,11 +4,14 @@ namespace go { public class ValueChangeEventArgs: EventArgs { - public Decimal OldValue; - public Decimal NewValue; + public string MemberName; + public object OldValue; + public object NewValue; - public ValueChangeEventArgs (Decimal _oldValue, Decimal _newValue) : base() + + public ValueChangeEventArgs (string _memberName, object _oldValue, object _newValue) : base() { + MemberName = _memberName; OldValue = _oldValue; NewValue = _newValue; } -- 2.47.3