diff options
| author | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2020-02-11 10:49:09 +0100 |
|---|---|---|
| committer | j-p <jp_bruyere@hotmail.com> | 2020-05-10 00:50:02 +0200 |
| commit | 701e6c825abbfb431bda3f6692e32a5f12e7307b (patch) | |
| tree | 6cfc0e63453fd235dfe81967094c3357a692c67b | |
| parent | 2774a37e0a20412971e17571e152768b299318db (diff) | |
wip
24 files changed, 320 insertions, 294 deletions
diff --git a/Crow/Crow.csproj b/Crow/Crow.csproj index 27feb880..521683f3 100644 --- a/Crow/Crow.csproj +++ b/Crow/Crow.csproj @@ -3,7 +3,7 @@ <PropertyGroup> <TargetFramework>netstandard2.0</TargetFramework> - <ReleaseVersion>$(CrowVersion)</ReleaseVersion> + <ReleaseVersion>0.8.0</ReleaseVersion> <AssemblyVersion>$(CrowVersion)</AssemblyVersion> <Title>C# Rapid Open Widget Toolkit</Title> @@ -36,7 +36,7 @@ </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <DebugType>full</DebugType> - <DefineConstants>DEBUG;TRACE;MEASURE_TIME;_DEBUG_DISPOSE;_DEBUG_BINDING;DESIGN_MODE;_DEBUG_CLIP_RECTANGLE;_DEBUG_FOCUS;_DEBUG_DRAGNDROP;_DEBUG_LOG</DefineConstants> + <DefineConstants>DEBUG;TRACE;MEASURE_TIME;_DEBUG_DISPOSE;_DEBUG_BINDING;DESIGN_MODE;_DEBUG_CLIP_RECTANGLE;_DEBUG_FOCUS;DEBUG_DRAGNDROP;_DEBUG_LOG</DefineConstants> <CheckForOverflowUnderflow>true</CheckForOverflowUnderflow> </PropertyGroup> <ItemGroup Condition="$(TargetFramework.StartsWith('netstandard'))"> diff --git a/Crow/src/Colors.cs b/Crow/src/Colors.cs index 8cec2f4e..8af93517 100644 --- a/Crow/src/Colors.cs +++ b/Crow/src/Colors.cs @@ -1,38 +1,10 @@ -// -// Colors.cs +// Copyright (c) 2013-2020 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> // -// Author: -// Jean-Philippe Bruyère <jp.bruyere@hotmail.com> -// -// Copyright (c) 2013-2017 Jean-Philippe Bruyère -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Xml.Serialization; -using System.Reflection; -using System.Diagnostics; - - namespace Crow { diff --git a/Crow/src/ExtensionsMethods.cs b/Crow/src/ExtensionsMethods.cs index 00157371..69edfe8e 100644 --- a/Crow/src/ExtensionsMethods.cs +++ b/Crow/src/ExtensionsMethods.cs @@ -1,28 +1,6 @@ -// -// ExtensionsMethods.cs +// Copyright (c) 2013-2020 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> // -// Author: -// Jean-Philippe Bruyère <jp.bruyere@hotmail.com> -// -// Copyright (c) 2013-2017 Jean-Philippe Bruyère -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) using System; using System.Linq.Expressions; diff --git a/Crow/src/BmpPicture.cs b/Crow/src/Fill/BmpPicture.cs index a67f66f1..a67f66f1 100644 --- a/Crow/src/BmpPicture.cs +++ b/Crow/src/Fill/BmpPicture.cs diff --git a/Crow/src/Fill/Fill.cs b/Crow/src/Fill/Fill.cs index 719002d2..6ff2bb7c 100644 --- a/Crow/src/Fill/Fill.cs +++ b/Crow/src/Fill/Fill.cs @@ -31,16 +31,15 @@ namespace Crow s.EndsWith (".gif", true, System.Globalization.CultureInfo.InvariantCulture)) return Picture.Parse (s); - return (SolidColor)SolidColor.Parse (s); + return new SolidColor((Color)Color.Parse (s)); } public static implicit operator Color(Fill c){ SolidColor sc = c as SolidColor; - return sc == null ? default(Color) : sc.color; + return sc == null ? default : sc.color; } public static implicit operator Fill(Color c){ return new SolidColor (c); } - } } diff --git a/Crow/src/Picture.cs b/Crow/src/Fill/Picture.cs index 2a71d6b5..2a71d6b5 100644 --- a/Crow/src/Picture.cs +++ b/Crow/src/Fill/Picture.cs diff --git a/Crow/src/SolidColor.cs b/Crow/src/Fill/SolidColor.cs index 5c8ebb72..f3e37d2b 100644 --- a/Crow/src/SolidColor.cs +++ b/Crow/src/Fill/SolidColor.cs @@ -48,8 +48,7 @@ namespace Crow #endregion #region implemented abstract members of Fill - - public override void SetAsSource (Context ctx, Rectangle bounds = default(Rectangle)) + public override void SetAsSource (Context ctx, Rectangle bounds = default) { ctx.SetSourceRGBA (color.R, color.G, color.B, color.A); } @@ -60,32 +59,19 @@ namespace Crow #endregion #region Operators - public static implicit operator Color(SolidColor c) - { - return c.color; - } - public static implicit operator SolidColor(Color c) - { - return new SolidColor (c); - } - public static bool operator ==(SolidColor left, SolidColor right) - { - return left is SolidColor ? right is SolidColor ? true : false : - left.color == right.color ? true : false; - } - public static bool operator !=(SolidColor left, SolidColor right) - { - return left is SolidColor ? right is SolidColor ? false : true : - left.color == right.color ? false : true; + public static implicit operator Color(SolidColor c) => c.color; + public static implicit operator SolidColor(Color c) => new SolidColor (c); + + public static bool operator ==(SolidColor left, SolidColor right) => left?.color == right?.color; + public static bool operator !=(SolidColor left, SolidColor right) => left?.color != right?.color; - } public override int GetHashCode () { return color.GetHashCode(); } public override bool Equals (object obj) { - if (obj is Crow.Color) + if (obj is Color) return color == (Color)obj; if (obj is SolidColor) return color == (obj as SolidColor).color; diff --git a/Crow/src/SvgPicture.cs b/Crow/src/Fill/SvgPicture.cs index 33f68955..33f68955 100644 --- a/Crow/src/SvgPicture.cs +++ b/Crow/src/Fill/SvgPicture.cs diff --git a/Crow/src/CompilerServices/CompilerServices.cs b/Crow/src/IML/CompilerServices.cs index 86e7a7a9..6ea3c957 100644 --- a/Crow/src/CompilerServices/CompilerServices.cs +++ b/Crow/src/IML/CompilerServices.cs @@ -445,7 +445,7 @@ namespace Crow.IML } return null; } -#endregion + #endregion /// <summary> /// Emits tree parsing command to fetch dest instance starting from orig node @@ -521,7 +521,7 @@ namespace Crow.IML il.Emit (OpCodes.Pop);//remove null string from stack il.Emit (OpCodes.Ldstr, "");//replace with empty string il.MarkLabel (endConvert); - } else if ((origType.IsEnum || origType == typeof (Enum)) && destType.IsEnum) { + } else if ((origType.IsEnum || origType == typeof (Enum)) && destType.IsEnum) {//TODO:double check this (multiple IsEnum test, no check of enum underlying type il.Emit (OpCodes.Unbox_Any, destType); return; } else if (origType.IsValueType) { @@ -598,6 +598,7 @@ namespace Crow.IML } } } + internal static bool isValueType (object obj) => obj.GetType ().IsValueType; /// <summary> /// check type of current object on the stack and convert to dest type, /// use loc_0 so store it as object!!! @@ -618,7 +619,7 @@ namespace Crow.IML il.MarkLabel (convert); - if (dstType == typeof(string)) { + if (dstType == typeof (string)) { System.Reflection.Emit.Label emitNullStr = il.DefineLabel (); il.Emit (OpCodes.Dup); il.Emit (OpCodes.Brfalse, emitNullStr); @@ -628,18 +629,68 @@ namespace Crow.IML il.Emit (OpCodes.Pop);//remove null string from stack il.Emit (OpCodes.Ldstr, "");//replace with empty string } else if (dstType.IsPrimitive) { - //il.Emit (OpCodes.Unbox_Any, dstType); - MethodInfo miconv = CompilerServices.GetConvertMethod(dstType); - if (miconv.IsStatic) - il.Emit(OpCodes.Call, miconv); - else - il.Emit(OpCodes.Callvirt, miconv); - } else if (dstType.IsValueType) { + //il.Emit (OpCodes.Unbox_Any, dstType); + MethodInfo miconv = CompilerServices.GetConvertMethod (dstType); + if (miconv.IsStatic) + il.Emit (OpCodes.Call, miconv); + else + il.Emit (OpCodes.Callvirt, miconv); + }else if (dstType.IsValueType) { + System.Reflection.Emit.Label endConvert2 = il.DefineLabel (); + il.Emit (OpCodes.Dup); + il.Emit (OpCodes.Call, typeof (CompilerServices).GetMethod ("isValueType", BindingFlags.Static | BindingFlags.NonPublic)); + System.Reflection.Emit.Label convertToValueType = il.DefineLabel (); + il.Emit (OpCodes.Brfalse, convertToValueType); + + il.Emit (OpCodes.Unbox_Any, dstType); + il.Emit (OpCodes.Br, endConvert); + + il.MarkLabel (convertToValueType); + //il.EmitWriteLine ($"convertToValueType:{dstType}"); + + //check if null + il.Emit (OpCodes.Dup); + LocalBuilder lbOrig = il.DeclareLocal (typeof (object)); + LocalBuilder lbMI = il.DeclareLocal (typeof (MethodInfo)); + il.Emit (OpCodes.Stloc, lbOrig); + il.Emit (OpCodes.Ldloc, lbOrig); + + //il.Emit (OpCodes.Ldloc, lbOrig); + //il.Emit (OpCodes.Call, typeof (Console).GetMethod ("WriteLine", new Type [] { typeof (object) })); + il.Emit (OpCodes.Brfalse, endConvert2); + //il.EmitWriteLine ($"search for implOp:{dstType}"); + il.Emit (OpCodes.Ldloc, lbOrig); + il.Emit (OpCodes.Callvirt, miGetType); + il.Emit (OpCodes.Ldtoken, dstType);//push destination property type for testing + il.Emit (OpCodes.Call, CompilerServices.miGetTypeFromHandle); + il.Emit (OpCodes.Call, miGetImplOp); + il.Emit (OpCodes.Stloc, lbMI); + il.Emit (OpCodes.Ldloc, lbMI); + convert = il.DefineLabel (); + il.Emit (OpCodes.Brtrue, convert); + //il.Emit (OpCodes.Ldloc, lbOrig); + il.Emit (OpCodes.Isinst, dstType); + il.Emit (OpCodes.Br, endConvert2); + + il.MarkLabel (convert); + //il.EmitWriteLine ($"implOp found, calling:{dstType}"); + il.Emit (OpCodes.Pop); + il.Emit (OpCodes.Ldloc, lbMI); + il.Emit (OpCodes.Ldnull);//null instance for invoke + il.Emit (OpCodes.Ldc_I4_1); + il.Emit (OpCodes.Newarr, typeof (object)); + il.Emit (OpCodes.Dup);//duplicate the array ref + il.Emit (OpCodes.Ldc_I4_0);//push the index 0 + il.Emit (OpCodes.Ldloc, lbOrig);//push the orig value to convert + il.Emit (OpCodes.Stelem, typeof (object));//set the array element at index 0 + il.Emit (OpCodes.Callvirt, miMIInvoke); + il.MarkLabel (endConvert2); il.Emit (OpCodes.Unbox_Any, dstType); } else{ - il.Emit (OpCodes.Stloc_0); //save orig value in loc0 + LocalBuilder lbOrig = il.DeclareLocal (typeof (object)); + il.Emit (OpCodes.Stloc, lbOrig); //save orig value in loc0 //first check if not null - il.Emit (OpCodes.Ldloc_0); + il.Emit (OpCodes.Ldloc, lbOrig); il.Emit (OpCodes.Dup); il.Emit (OpCodes.Brfalse, endConvert); il.Emit (OpCodes.Callvirt, miGetType); @@ -650,7 +701,7 @@ namespace Crow.IML convert = il.DefineLabel (); il.Emit (OpCodes.Brtrue, convert); il.Emit (OpCodes.Pop); - il.Emit (OpCodes.Ldloc_0); + il.Emit (OpCodes.Ldloc, lbOrig); il.Emit (OpCodes.Isinst, dstType); il.Emit (OpCodes.Br, endConvert); @@ -660,9 +711,13 @@ namespace Crow.IML il.Emit(OpCodes.Newarr, typeof (object)); il.Emit (OpCodes.Dup);//duplicate the array ref il.Emit (OpCodes.Ldc_I4_0);//push the index 0 - il.Emit (OpCodes.Ldloc_0);//push the orig value to convert + il.Emit (OpCodes.Ldloc, lbOrig);//push the orig value to convert il.Emit (OpCodes.Stelem, typeof (object));//set the array element at index 0 il.Emit (OpCodes.Callvirt, miMIInvoke); + + //if (dstType.IsValueType) + // il.Emit (OpCodes.Unbox_Any, dstType); + } il.MarkLabel (endConvert); diff --git a/Crow/src/Instantiator.cs b/Crow/src/Instantiator.cs index 20ca1ff8..760b5b1a 100644 --- a/Crow/src/Instantiator.cs +++ b/Crow/src/Instantiator.cs @@ -174,6 +174,19 @@ namespace Crow.IML { /// </summary> Delegate templateBinding; +#if DESIGN_MODE + public List<DynamicMethod> DsValueChangedDynMeths =>dsValueChangedDynMeths; + public List<Delegate> CachedDelegates => cachedDelegates; + /// <summary> + /// store indices of template delegate to be handled by root parentChanged event + /// </summary> + public List<int> TemplateCachedDelegateIndices => templateCachedDelegateIndices; + /// <summary> + /// Store template bindings in the instantiator + /// </summary> + public Delegate TemplateBinding => templateBinding; + +#endif #region IML parsing /// <summary> /// Parses IML and build a dynamic method that will be used to instantiate one or multiple occurences of the IML file or fragment @@ -446,7 +459,7 @@ namespace Crow.IML { ctx.SetDataSourceTypeForCurrentNode(CompilerServices.getTypeFromName (dataSourceType)); } ctx.il.Emit (OpCodes.Ldloc_0); - ctx.il.Emit (OpCodes.Callvirt, CompilerServices.miLoadDefaultVals); + ctx.il.Emit (OpCodes.Call, CompilerServices.miLoadDefaultVals); #endregion @@ -811,12 +824,12 @@ namespace Crow.IML { } void emitTemplateBindings(IMLContext ctx, Dictionary<string, List<MemberAddress>> bindings){ //value changed dyn method - DynamicMethod dm = new DynamicMethod ("dyn_tmpValueChanged", + DynamicMethod dm = new DynamicMethod ("dyn_tmpValueChanged" + NewId, typeof (void), CompilerServices.argsValueChange, true); ILGenerator il = dm.GetILGenerator (256); //create parentchanged dyn meth in parallel to have only one loop over bindings - DynamicMethod dmPC = new DynamicMethod ("dyn_InitAndLogicalParentChanged", + DynamicMethod dmPC = new DynamicMethod ("dyn_InitAndLogicalParentChanged" + NewId, typeof (void), CompilerServices.argsBoundDSChange, true); ILGenerator ilPC = dmPC.GetILGenerator (256); @@ -1108,6 +1121,10 @@ namespace Crow.IML { //store dschange delegate in instatiator instance for access while instancing graphic object int delDSIndex = cachedDelegates.Count; + + //Int32 fiLength = (Int32)il.GetType ().GetField ("code_len", BindingFlags.Instance | BindingFlags.NonPublic).GetValue (il); + //byte [] bytes = (byte[])il.GetType ().GetField ("code", BindingFlags.Instance | BindingFlags.NonPublic).GetValue (il); + cachedDelegates.Add (dm.CreateDelegate (CompilerServices.ehTypeDSChange, this)); #endregion @@ -1199,7 +1216,7 @@ namespace Crow.IML { #endregion } -#region emit dataSourceChanged event handler + #region emit dataSourceChanged event handler //now we create the datasource changed method that will init the destination member with //the actual value of the origin member of the datasource and then will bind the value changed //dyn methode. @@ -1413,7 +1430,7 @@ namespace Crow.IML { EventHandler<ValueChangeEventArgs> tmp = (EventHandler<ValueChangeEventArgs>)dm.CreateDelegate (typeof (EventHandler<ValueChangeEventArgs>), dest); orig.ValueChanged += tmp; } -#endregion + #endregion /// <summary> /// search for graphic object type in crow assembly, if not found, diff --git a/Crow/src/Interface.cs b/Crow/src/Interface.cs index a71e4825..5fc2c2fb 100644 --- a/Crow/src/Interface.cs +++ b/Crow/src/Interface.cs @@ -495,11 +495,11 @@ namespace Crow /// <param name="path">path of the iml file to load</param> public virtual Widget CreateInstance (string path) { - try { + //try { return GetInstantiator (path).CreateInstance (); - } catch (Exception ex) { - throw new Exception ("Error loading <" + path + ">:", ex); - } + //} catch (Exception ex) { + // throw new Exception ("Error loading <" + path + ">:", ex); + //} } /// <summary> /// Create an instance of a GraphicObject linked to this interface but not added to the GraphicTree @@ -508,13 +508,13 @@ namespace Crow /// <param name="path">path of the iml file to load</param> public virtual Widget CreateTemplateInstance (string path, Type declaringType) { - try { +// try { if (!Templates.ContainsKey (path)) Templates [path] = new Instantiator (this, GetTemplateStreamFromPath(path, declaringType), path); return Templates [path].CreateInstance (); - } catch (Exception ex) { - throw new Exception ("Error loading Template <" + path + ">:", ex); - } + //} catch (Exception ex) { + // throw new Exception ("Error loading Template <" + path + ">:", ex); + //} } /// <summary> /// Fetch instantiator from cache or create it. diff --git a/Crow/src/Measure.cs b/Crow/src/Measure.cs index c40c6703..c77d66bd 100644 --- a/Crow/src/Measure.cs +++ b/Crow/src/Measure.cs @@ -1,28 +1,6 @@ -// -// Measure.cs +// Copyright (c) 2013-2020 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> // -// Author: -// Jean-Philippe Bruyère <jp.bruyere@hotmail.com> -// -// Copyright (c) 2013-2017 Jean-Philippe Bruyère -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) using System; diff --git a/Crow/src/Point.cs b/Crow/src/Point.cs index 83ae7651..02f12e2f 100644 --- a/Crow/src/Point.cs +++ b/Crow/src/Point.cs @@ -53,7 +53,7 @@ namespace Crow public static bool operator <= (Point p1, Point p2) => p1.X <= p2.X && p1.Y <= p2.Y; public static bool operator <= (Point s, int i) => s.X <= i && s.Y <= i; - public override string ToString () => string.Format ("({0},{1})", X, Y); + public override string ToString () => string.Format ("{0},{1}", X, Y); public override bool Equals (object obj) => obj is Point ? this == (Point)obj : obj is Point && (Point)this == (Point)obj; public static Point Parse (string s) diff --git a/Crow/src/PointD.cs b/Crow/src/PointD.cs index 9db0a184..d70e5b82 100644 --- a/Crow/src/PointD.cs +++ b/Crow/src/PointD.cs @@ -46,7 +46,7 @@ namespace Crow { public static bool operator <= (PointD p1, PointD p2) => p1.X <= p2.X && p1.Y <= p2.Y; public static bool operator <= (PointD s, double i) => s.X <= i && s.Y <= i; - public override string ToString () => string.Format ("({0},{1})", X, Y); + public override string ToString () => string.Format ("{0},{1}", X, Y); public override bool Equals (object obj) => obj is PointD ? this == (PointD)obj : obj is Point && (Point)this == (Point)obj; public static PointD Parse (string s) diff --git a/Crow/src/Widgets/Group.cs b/Crow/src/Widgets/Group.cs index 6db541d6..b2f6f418 100644 --- a/Crow/src/Widgets/Group.cs +++ b/Crow/src/Widgets/Group.cs @@ -97,6 +97,7 @@ namespace Crow Children.Remove(child); child.Parent = null; + child.LogicalParent = null; childrenRWLock.ExitWriteLock (); diff --git a/Crow/src/Widgets/TemplatedGroup.cs b/Crow/src/Widgets/TemplatedGroup.cs index 54e3e760..da2c1f87 100644 --- a/Crow/src/Widgets/TemplatedGroup.cs +++ b/Crow/src/Widgets/TemplatedGroup.cs @@ -339,13 +339,13 @@ namespace Crow { /// Items loading thread /// </summary> void loading(){ - try { + //try { loadPage (data, items, dataTest); - } catch { + /*} catch (Exception ex) { if (Monitor.IsEntered (IFace.LayoutMutex)) Monitor.Exit (IFace.LayoutMutex); - Console.WriteLine ("loading thread aborted"); - } + Console.WriteLine ("loading thread aborted: " + ex.ToString()); + }*/ } // //if (!ItemTemplates.ContainsKey ("default")) @@ -363,10 +363,13 @@ namespace Crow { void cancelLoadingThread(){ if (loadingThread == null) return; - bool updateMx = Monitor.IsEntered (IFace.UpdateMutex); bool layoutMx = Monitor.IsEntered (IFace.LayoutMutex); +#if DEBUG_LOG + DebugLog.AddEvent (DbgEvtType.TGCancelLoadingThread, this); +#endif + if (layoutMx) Monitor.Exit (IFace.LayoutMutex); if (updateMx) diff --git a/Crow/src/Widgets/Widget.cs b/Crow/src/Widgets/Widget.cs index 0ca6598b..8596a86f 100644 --- a/Crow/src/Widgets/Widget.cs +++ b/Crow/src/Widgets/Widget.cs @@ -951,7 +951,7 @@ namespace Crow rootDataLevel = true; #if DEBUG_LOG - DbgEvent dbgEvt = DebugLog.AddEvent(DbgEvtType.GOLockLayouting, this); + DbgEvent dbgEvt = DebugLog.AddEvent(DbgEvtType.GOLockUpdate, this); #endif lock (IFace.UpdateMutex) { OnDataSourceChanged (this, dse); @@ -1156,12 +1156,12 @@ namespace Crow il.Emit(OpCodes.Ret); #endregion - try { + //try { IFace.DefaultValuesLoader[styleKey] = (Interface.LoaderInvoker)dm.CreateDelegate(typeof(Interface.LoaderInvoker)); IFace.DefaultValuesLoader[styleKey] (this); - } catch (Exception ex) { + /*} catch (Exception ex) { throw new Exception ("Error applying style <" + styleKey + ">:", ex); - } + }*/ #if DEBUG_LOG dbgEvt.end = DebugLog.chrono.ElapsedTicks; @@ -1457,6 +1457,9 @@ namespace Crow #endif if (Parent == null) return; +#if DEBUG_LOG + DbgEvent dbgEvt = DebugLog.AddEvent (DbgEvtType.GOLockLayouting, this); +#endif lock (IFace.LayoutMutex) { //prevent queueing same LayoutingType for this layoutType &= (~RegisteredLayoutings); @@ -1494,6 +1497,9 @@ namespace Crow if (layoutType.HasFlag (LayoutingType.ArrangeChildren)) IFace.LayoutingQueue.Enqueue (new LayoutingQueueItem (LayoutingType.ArrangeChildren, this)); } +#if DEBUG_LOG + dbgEvt.end = DebugLog.chrono.ElapsedTicks; +#endif } /// <summary> trigger dependant sizing component update </summary> @@ -1594,7 +1600,7 @@ namespace Crow else if (Width == Measure.Stretched) Slot.Width = Parent.ClientRectangle.Width; else - Slot.Width = (int)Math.Round ((double)(Parent.ClientRectangle.Width * Width) / 100.0); + Slot.Width = (int)Math.Round ((double)(Parent.ClientRectangle.Width * Width) / 100.0); if (Slot.Width < 0) return false; diff --git a/Crow/src/debug/DbgLogViewer.cs b/Crow/src/debug/DbgLogViewer.cs index 4ff6082e..dad155c7 100644 --- a/Crow/src/debug/DbgLogViewer.cs +++ b/Crow/src/debug/DbgLogViewer.cs @@ -130,7 +130,7 @@ namespace Crow long currentTick = 0, selStart = -1, selEnd = -1, minTicks = 0, maxTicks = 0, visibleTicks = 0; int currentLine = -1; - int visibleLines; + int visibleLines = 1; public string LogFile { get { return logFile; } @@ -141,7 +141,6 @@ namespace Crow loadDebugFile (); - NotifyValueChanged ("LogFile", logFile); RegisterForGraphicUpdate (); } @@ -230,8 +229,6 @@ namespace Crow leftMargin = 2.5 + maxNameWidth; - fe = gr.FontExtents; - topMargin = 2.0 * fe.Height; updateVisibleLines (); @@ -241,7 +238,7 @@ namespace Crow } void updateVisibleLines(){ - visibleLines = (int)Math.Floor (((double)ClientRectangle.Height - topMargin) / fe.Height); + visibleLines = fe.Height < 1 ? 1 : (int)Math.Floor (((double)ClientRectangle.Height - topMargin) / fe.Height); NotifyValueChanged ("VisibleLines", visibleLines); updateMaxScrollY (); } @@ -280,10 +277,15 @@ namespace Crow get { return base.Font; } set { base.Font = value; + using (Context gr = new Context (IFace.surf)) { + gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight); + gr.SetFontSize (Font.Size); + + fe = gr.FontExtents; + } loadDebugFile (); } } - public override int ScrollY { get { return base.ScrollY; @@ -359,7 +361,7 @@ namespace Crow Color c = Color.Black; - if (evt.type == DbgEvtType.GOProcessLayouting) { + if (evt.type == DbgEvtType.GOProcessLayouting) { switch (evt.data.result) { case LayoutingQueueItem.Result.Success: c = Crow.Color.Green; @@ -374,11 +376,13 @@ namespace Crow c = Crow.Color.Orange; break; } - } else if (colors.ContainsKey (evt.type)) + } else if (evt.type.HasFlag (DbgEvtType.GOLock)) + c = Color.BlueViolet; + else if (colors.ContainsKey (evt.type)) c = colors [evt.type]; - else - System.Diagnostics.Debugger.Break (); - + //else + // System.Diagnostics.Debugger.Break (); + c = c.AdjustAlpha (0.2); gr.SetSourceColor (c); gr.Rectangle (x, penY, w, fe.Height); diff --git a/Crow/src/debug/DebugLogger.cs b/Crow/src/debug/DebugLogger.cs index bfe1948f..37842e22 100644 --- a/Crow/src/debug/DebugLogger.cs +++ b/Crow/src/debug/DebugLogger.cs @@ -49,27 +49,34 @@ namespace Crow IFaceEndDrawing = 0x0106, IFaceUpdate = 0x0107, //10 nth bit set for graphic obj - GraphicObject = 0x0200, - GOClassCreation = 0x0201, - GOInitialization = 0x0202, - GOClippingRegistration = 0x0203, - GORegisterClip = 0x0204, - GORegisterForGraphicUpdate = 0x0205, - GOEnqueueForRepaint = 0x0206, - GOLayouting = 0x0400, - GORegisterLayouting = 0x0607, - GOProcessLayoutingWithNoParent = 0x0608, - GOProcessLayouting = 0x0609, - GODraw = 0x020a, - GORecreateCache = 0x020b, - GOUpdateCacheAndPaintOnCTX = 0x020c, - GOPaint = 0x020d, - GONewDataSource = 0x020e, + GraphicObject = 0x0100, + Warning = 0x4000, + Error = 0x8000, + GOClassCreation = GraphicObject | 0x01, + GOInitialization = GraphicObject | 0x02, + GOClippingRegistration = GraphicObject | 0x03, + GORegisterClip = GraphicObject | 0x04, + GORegisterForGraphicUpdate = GraphicObject | 0x05, + GOEnqueueForRepaint = GraphicObject | 0x06, + GONewDataSource = GraphicObject | 0x07, + GOLayouting = 0x0200, + Drawing = 0x0400, GOLock = 0x0800, - GOLockUpdate = 0x0a01, - GOLockClipping = 0x0a02, - GOLockRender = 0x0a03, - GOLockLayouting = 0x0a04, + TemplatedGroup = 0x1000, + GORegisterLayouting = GraphicObject | GOLayouting | 0x01, + GOProcessLayouting = GraphicObject | GOLayouting | 0x02, + GOProcessLayoutingWithNoParent = Warning | GraphicObject | GOLayouting | 0x01, + GODraw = GraphicObject | Drawing | 0x01, + GORecreateCache = GraphicObject | Drawing | 0x02, + GOUpdateCacheAndPaintOnCTX = GraphicObject | Drawing | 0x03, + GOPaint = GraphicObject | Drawing | 0x04, + + GOLockUpdate = GraphicObject | GOLock | 0x01, + GOLockClipping = GraphicObject | GOLock | 0x02, + GOLockRender = GraphicObject | GOLock | 0x03, + GOLockLayouting = GraphicObject | GOLock | 0x04, + + TGCancelLoadingThread = GraphicObject | TemplatedGroup | 0x01, } /// <summary> diff --git a/Samples/HelloWorld/HelloWorld.csproj b/Samples/HelloWorld/HelloWorld.csproj index 448fb435..908af2fc 100644 --- a/Samples/HelloWorld/HelloWorld.csproj +++ b/Samples/HelloWorld/HelloWorld.csproj @@ -7,7 +7,8 @@ </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> - <DefineConstants>TRACE;DEBUG;NETFRAMEWORK;NET471</DefineConstants> + <DebugType>full</DebugType> + <DefineConstants>TRACE;DEBUG</DefineConstants> </PropertyGroup> <ItemGroup Condition="$(TargetFramework.StartsWith('net4'))"> <Reference Include="System" /> @@ -22,4 +23,7 @@ <LogicalName>HelloWorld.%(Filename)%(Extension)</LogicalName> </EmbeddedResource> </ItemGroup> + <ItemGroup> + <PackageReference Include="Mono.Cecil" Version="0.11.1" /> + </ItemGroup> </Project> diff --git a/Samples/HelloWorld/ILView.cs b/Samples/HelloWorld/ILView.cs new file mode 100644 index 00000000..9bac2299 --- /dev/null +++ b/Samples/HelloWorld/ILView.cs @@ -0,0 +1,15 @@ +// Copyright (c) 2020 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) +using System; +using Crow; + +namespace HelloWorld +{ + public class ILView : Widget + { + public ILView () + { + } + } +} diff --git a/Samples/HelloWorld/main.cs b/Samples/HelloWorld/main.cs index 14a1a2ad..c407b04e 100644 --- a/Samples/HelloWorld/main.cs +++ b/Samples/HelloWorld/main.cs @@ -1,5 +1,9 @@ using System; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; using Crow; +using Crow.IML; namespace HelloWorld { @@ -10,6 +14,7 @@ namespace HelloWorld vke.Run (); } } + protected override void Startup () { CMDQuit = new Command (new Action (() => running = false)) { Caption = "Quit", Icon = new SvgPicture ("#Crow.Icons.exit-symbol.svg") }; @@ -19,6 +24,17 @@ namespace HelloWorld w.DataSource = this; } + public SolidColor testColor = Color.Red; + public SolidColor TestColor { + get => testColor; + set { + if (testColor == value) + return; + testColor = value; + NotifyValueChanged ("TestColor", testColor); + } + } + Color [] colors = { Color.Blue, Color.DarkGoldenRod, Color.Red, Color.Azure, Color.Brown, Color.Black, Color.White, Color.Pink }; int ptr = 0; @@ -37,6 +53,48 @@ namespace HelloWorld if (ptr == colors.Length) ptr = 0; } + public override bool OnKeyDown (Key key) + { + switch (key) { + case Key.d: + dump (); + break; + case Key.space: + TestColor = Color.Green; + break; + default: + return base.OnKeyDown (key); + } + return true; + } + + void dump () + { + Instantiator inst = Instantiators ["#HelloWorld.helloworld.crow"]; + + foreach (Delegate cd in inst.CachedDelegates) { + FieldInfo mb = typeof(Delegate).GetField("original_method_info", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField); + + DynamicMethod dynMethod = mb.GetValue (cd) as DynamicMethod; + /*Console.WriteLine (typeof (ILGenerator).GetFields (BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField)); + + var ilgen = dynMethod.GetILGenerator (); + + + +*/ + + MethodBody body = dynMethod.GetMethodBody (); + + byte [] il = body.GetILAsByteArray (); + foreach (byte b in il) { + Console.Write ($"{b:x2} "); + //Console.WriteLine (b); + } + + } + + } } } diff --git a/Samples/HelloWorld/ui/helloworld.crow b/Samples/HelloWorld/ui/helloworld.crow index d150136e..1bc9601f 100644 --- a/Samples/HelloWorld/ui/helloworld.crow +++ b/Samples/HelloWorld/ui/helloworld.crow @@ -1,9 +1,6 @@ <?xml version="1.0"?> - - <VerticalStack> - <Label Text="Hello World" Font="mono, 20"/> - <Image Path="#Crow.Icons.crow.svg"/> - <CheckBox/> - </VerticalStack> - - +<VerticalStack> + <TextBox Text="{TestColor}"/> + <ColorPicker CurrentColor="{²TestColor}" /> +</VerticalStack> +<!--<ScrollBar Orientation="Vertical" Height="Stretched" Width="10" />-->
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Divers/0.crow b/Samples/common/ui/Interfaces/Divers/0.crow index d083946c..4b6c50fb 100644 --- a/Samples/common/ui/Interfaces/Divers/0.crow +++ b/Samples/common/ui/Interfaces/Divers/0.crow @@ -1,162 +1,108 @@ -<?xml version="1.0"?> -<Window Caption="Showcase" Height="90%" Width="90%"> - <HorizontalStack > +<?xml version="1.0" encoding="UTF-8"?> +<Window Caption="Showcase" Height="90%" Width="90%" Background="Jet"> + <HorizontalStack> <VerticalStack Width="30%" Margin="5"> <GroupBox Caption="Performance" Height="Fit"> - <VerticalStack DataSource="{drawingMeasure}" Width="90%" Height="Fit" Spacing="2" > + <VerticalStack DataSource="{drawingMeasure}" Width="90%" Height="Fit" Spacing="2"> <HorizontalStack Height="Fit" Tooltip="Frame per second"> - <Label Text="Fps:" Style="FpsLabel"/> - <Label Text="{minimum}" Style="FpsDisp"/> + <Label Style="FpsLabel" Text="Fps:" /> + <Label Style="FpsDisp" Text="{minimum}" /> </HorizontalStack> <HorizontalStack Height="Fit" Tooltip="Minimum Frame per second"> - <Label Text="Min:" Style="FpsLabel"/> - <Label Text="{fpsMin}" Style="FpsDisp"/> + <Label Style="FpsLabel" Text="Min:" /> + <Label Style="FpsDisp" Text="{fpsMin}" /> </HorizontalStack> <HorizontalStack Height="Fit" Tooltip="Maximum Frame per second"> - <Label Text="Max:" Style="FpsLabel"/> - <Label Text="{fpsMax}" Style="FpsDisp"/> + <Label Style="FpsLabel" Text="Max:" /> + <Label Style="FpsDisp" Text="{fpsMax}" /> </HorizontalStack> <HorizontalStack Height="Fit" Tooltip="Update loop duration"> - <Label Text="Update:" Style="FpsLabel"/> - <Label Text="{update}" Style="FpsDisp"/> + <Label Style="FpsLabel" Text="Update:" /> + <Label Style="FpsDisp" Text="{update}" /> </HorizontalStack> <HorizontalStack Height="Fit" Tooltip="Layouting process duration"> - <Label Text="Layouting:" Style="FpsLabel"/> - <Label Text="{layouting}" Style="FpsDisp"/> + <Label Style="FpsLabel" Text="Layouting:" /> + <Label Style="FpsDisp" Text="{layouting}" /> </HorizontalStack> <HorizontalStack Height="Fit" Tooltip="Clipping duration"> - <Label Text="Clipping:" Style="FpsLabel"/> - <Label Text="{clipping}" Style="FpsDisp"/> + <Label Style="FpsLabel" Text="Clipping:" /> + <Label Style="FpsDisp" Text="{clipping}" /> </HorizontalStack> <HorizontalStack Height="Fit"> - <Label Text="Drawing:" Style="FpsLabel"/> - <Label Text="{drawing}" Style="FpsDisp"/> + <Label Style="FpsLabel" Text="Drawing:" /> + <Label Style="FpsDisp" Text="{drawing}" /> </HorizontalStack> </VerticalStack> </GroupBox> - <Label Width="Stretched" Margin="3" Background="DimGrey"/> - <TextBox Text="TextBox" Multiline="true" Margin="3"/> + <Label Width="Stretched" Margin="3" Background="DimGrey" /> + <TextBox Text="TextBox" Multiline="true" Margin="3" /> <HorizontalStack Height="Fit" Margin="5" Background="DimGrey" CornerRadius="10"> <VerticalStack Spacing="5" Width="50%"> - <CheckBox Fit="true" Caption="test"/> - <CheckBox Fit="true"/> - <CheckBox Fit="true"/> - <CheckBox Fit="true" IsChecked="true"/> + <CheckBox Fit="true" Caption="test" /> + <CheckBox Fit="true" /> + <CheckBox Fit="true" /> + <CheckBox Fit="true" IsChecked="true" /> </VerticalStack> <VerticalStack Spacing="5" Width="50%"> - <RadioButton Fit="true"/> - <RadioButton Fit="true" IsChecked="true"/> - <RadioButton Fit="true"/> - <RadioButton Fit="true"/> + <RadioButton Fit="true" /> + <RadioButton Fit="true" IsChecked="true" /> + <RadioButton Fit="true" /> + <RadioButton Fit="true" /> </VerticalStack> </HorizontalStack> <HorizontalStack Height="Fit" Margin="5"> - <Label Text="MouseEvents" Width="50%" Margin="3" Focusable="true" - Background="Jet" - Foreground="DimGrey" - TextAlignment="Center" - MouseEnter="{Foreground=White}" - MouseLeave="{Foreground=DimGrey}" - MouseDown="{Background=DarkRed}" - MouseClick="{Foreground=Green}" - MouseDoubleClick="{Foreground=Yellow}" - MouseUp="{Background=Jet}"/> - <Label Text="MouseEvents" Width="50%" Margin="3" - Background="Jet" - Foreground="DimGrey" - TextAlignment="Center" - MouseClick="{Foreground=Green}" - MouseDoubleClick="{Foreground=Yellow}" - MouseEnter="{Foreground=White}" - MouseLeave="{Foreground=DimGrey}" - MouseDown="{Background=SeaGreen}" - MouseUp="{Background=DimGrey}"/> + <Label Text="MouseEvents" Width="50%" Margin="3" Focusable="true" Background="Jet" Foreground="DimGrey" TextAlignment="Center" MouseEnter="{Foreground=White}" MouseLeave="{Foreground=DimGrey}" MouseDown="{Background=DarkRed}" MouseClick="{Foreground=Green}" MouseDoubleClick="{Foreground=Yellow}" MouseUp="{Background=Jet}" /> + <Label Text="MouseEvents" Width="50%" Margin="3" Background="Jet" Foreground="DimGrey" TextAlignment="Center" MouseClick="{Foreground=Green}" MouseDoubleClick="{Foreground=Yellow}" MouseEnter="{Foreground=White}" MouseLeave="{Foreground=DimGrey}" MouseDown="{Background=SeaGreen}" MouseUp="{Background=DimGrey}" /> </HorizontalStack> <GroupBox Caption="Templated controls" Height="Fit" Margin="5"> <HorizontalStack Height="Fit"> <VerticalStack Width="50%"> - <CheckBox IsChecked="true" Style="CheckBox2"/> - <CheckBox Style="CheckBox2"/> - <CheckBox Style="CheckBox2"/> - <CheckBox Style="CheckBox2"/> + <CheckBox Style="CheckBox2" IsChecked="true" /> + <CheckBox Style="CheckBox2" /> + <CheckBox Style="CheckBox2" /> + <CheckBox Style="CheckBox2" /> </VerticalStack> - <Splitter/> + <Splitter /> <VerticalStack Width="50%"> - <RadioButton Style="RadioButton2"/> - <RadioButton Style="RadioButton2"/> - <RadioButton Style="RadioButton2"/> - <RadioButton Style="RadioButton2"/> + <RadioButton Style="RadioButton2" /> + <RadioButton Style="RadioButton2" /> + <RadioButton Style="RadioButton2" /> + <RadioButton Style="RadioButton2" /> </VerticalStack> </HorizontalStack> </GroupBox> <HorizontalStack Height="Fit"> - <Label Text="Spinner"/> - <Spinner Fit="true"/> + <Label Text="Spinner" /> + <Spinner Fit="true" /> </HorizontalStack> <HorizontalStack Height="Fit"> - <Button Caption="Button"/> - <Button Caption="Button" IsEnabled="false"/> + <Button Caption="Button"> + <Label Font="{./Font}" Name="caption" Margin="3" Foreground="LightGrey" Text="{./Caption}" /> + </Button> + <Button Caption="Button" IsEnabled="false"> + <Label Font="{./Font}" Name="caption" Margin="3" Foreground="LightGrey" Text="{./Caption}" /> + </Button> </HorizontalStack> </VerticalStack> - <Splitter/> + <Splitter /> <VerticalStack Width="40%" Margin="5" Spacing="5"> <Expandable> - <Image Path="#Crow.Icons.crow.svg"/> + <Image Path="#Crow.Icons.crow.svg" /> </Expandable> - <Popper> - <Border Fit="True" Background="DimGrey" CornerRadius="0" BorderWidth="1"> - <Image Path="#Crow.Icons.crow.svg" Width="100" Height="100" Margin="10" - MouseEnter="{Background=LightGrey}" - MouseLeave="{Background=Transparent}"/> - </Border> - </Popper> - <Slider Height="10" Width="90%"/> + <Popper /> + <Slider Height="10" Width="90%" /> <Container Height="Fit" Width="200" Background="DimGrey" Margin="2" CornerRadius="5"> - <ProgressBar Background="DimGrey" Height="10" Value="50"/> + <ProgressBar Background="DimGrey" Height="10" Value="50" /> </Container> <Image Path="#Crow.Icons.crow.svg" Width="60" Height="60" Background="LightGrey" /> -<!-- <TabView Name="tabview1" - Height="120" Orientation="Horizontal" Spacing="15"> - <TabItem Name="TabItem1" Caption="Tab 1" Margin="0"> - <VerticalStack Fit="true"> - <CheckBox/> - <CheckBox/> - <CheckBox/> - <CheckBox/> - </VerticalStack> - </TabItem> - <TabItem Name="TabItem2" Caption="Tab 2" Background="Grey"> - <VerticalStack Fit="true"> - <RadioButton/> - <RadioButton/> - <RadioButton/> - <RadioButton/> - </VerticalStack> - </TabItem> - <TabItem Name="TabItem3" Caption="Tab 3" Background="Grey"> - <Container Margin="5" CornerRadius="2"> - <TextBox Height="Stretched" Margin="5" Multiline="true" TextAlignment="TopLeft"/> - </Container> - </TabItem> - </TabView>--> - <MessageBox Movable="false"/> + <MessageBox Movable="false" /> <ColorPicker CurrentColor="{²../go.Background}" Name="colorPicker" Margin="5" /> - <Widget Name="go" Width="100" Height="60" Background="{../../colorList.SelectedItem}"/> - <Label Text="{../colorPicker.CurrentColor}"/> + <Widget Name="go" Width="100" Height="60" Background="{../../colorList.SelectedItem}" /> + <Label Text="{../colorPicker.CurrentColor}" /> </VerticalStack> - <Splitter/> + <Splitter /> <VerticalStack Width="30%" Margin="5"> -<!-- <Border Margin="5" Height="Fit"> - <Label Width="Stretched" Margin="1" Text="{../../dv.SelectedItem}"/> - </Border> - <Border Margin="5" Height="30%"> - <DirectoryView Name="dv" CurrentDirectory="/" Margin="1"/> - </Border> - <Splitter/>--> - <ListBox Name="colorList" Data="{TestList}" Margin="5" - ItemTemplate="Interfaces/colorItem.crow" - Template="#Crow.ScrollingListBox.template" - /> + <ListBox Name="colorList" Data="{TestList}" Margin="5" ItemTemplate="Interfaces/colorItem.crow" /> </VerticalStack> </HorizontalStack> </Window>
\ No newline at end of file |