]> O.S.I.I.S - jp/crow.git/commitdiff
DbgLogger
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Mon, 22 Jun 2020 12:49:45 +0000 (14:49 +0200)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Mon, 22 Jun 2020 12:49:45 +0000 (14:49 +0200)
18 files changed:
Crow/Crow.csproj
Crow/src/IML/Instantiator.cs
Crow/src/Interface.cs
Crow/src/LayoutingQueueItem.cs
Crow/src/Widgets/GenericStack.cs
Crow/src/Widgets/Group.cs
Crow/src/Widgets/MenuItem.cs
Crow/src/Widgets/PrivateContainer.cs
Crow/src/Widgets/Widget.cs
Crow/src/Widgets/Wrapper.cs
Crow/src/debug/DbgEventTypeColors.cs
Crow/src/debug/DbgLogViewer.cs
Crow/src/debug/DebugLogger.cs
Samples/common/ui/Interfaces/Divers/dbglog.crow
Samples/common/ui/Interfaces/TemplatedContainer/win0.crow [new file with mode: 0644]
Samples/common/ui/Interfaces/TemplatedGroup/1.crow
Samples/common/ui/Interfaces/TemplatedGroup/11.crow [new file with mode: 0644]
Samples/common/ui/Interfaces/TemplatedGroup/3.crow

index 2cfa12fd2d4eaf8aae30ffb00ff2b649e28ecef5..38082c372b3f6ac51a2e38dfd4bab88c9154544d 100644 (file)
@@ -32,7 +32,7 @@
        </PropertyGroup>
        <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
                <DebugType>full</DebugType>
-               <DefineConstants>$(DefineConstants);DEBUG;TRACE;MEASURE_TIME;_DEBUG_DISPOSE;_DEBUG_BINDING;_DEBUG_CLIP_RECTANGLE;_DEBUG_FOCUS;DEBUG_DRAGNDROP;_DEBUG_LOG</DefineConstants>
+               <DefineConstants>$(DefineConstants);DEBUG_LOG;DEBUG;TRACE;DEBUG_LAYOUTING;DEBUG_DISPOSE;_DEBUG_BINDING;_DEBUG_CLIP_RECTANGLE</DefineConstants>
                <CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
        </PropertyGroup>
        <ItemGroup Condition="$(TargetFramework.StartsWith('netstandard'))">
index ca41eec10de6a96464dc1aefecc681c037f83b3c..2f9aa94a0a3d3d576eb7d04128596d91f8377a87 100644 (file)
@@ -78,9 +78,9 @@ namespace Crow.IML {
                        #endif
                        iface = _iface;
                        sourcePath = srcPath;
-                       #if DEBUG_LOAD
-                       Stopwatch loadingTime = Stopwatch.StartNew ();
-                       #endif
+#if DEBUG_LOG
+                       DbgEvent de = DbgLogger.StartEvent (DbgEvtType.CreateITor, sourcePath);
+#endif
                        try {
                                using (XmlReader itr = XmlReader.Create (stream)) {
                                        parseIML (itr);
@@ -89,11 +89,8 @@ namespace Crow.IML {
                                throw new InstantiatorException(sourcePath, ex);
                        } finally {
                                stream?.Dispose ();
-#if DEBUG_LOAD
-                               loadingTime.Stop ();
-                               using (StreamWriter sw = new StreamWriter ("loading.log", true)) {
-                                       sw.WriteLine ($"ITOR;{sourcePath,-50};{loadingTime.ElapsedTicks,8};{loadingTime.ElapsedMilliseconds,8}");
-                               }
+#if DEBUG_LOG
+                       DbgLogger.EndEvent (DbgEvtType.CreateITor, de);
 #endif
                        }
                }
@@ -136,17 +133,7 @@ namespace Crow.IML {
                /// </summary>
                /// <returns>The new graphic object instance</returns>
                public Widget CreateInstance(){
-#if DEBUG_LOAD
-                       Stopwatch loadingTime = Stopwatch.StartNew ();
-                       GraphicObject o = loader (iface) as GraphicObject;
-                       loadingTime.Stop ();
-                       using (StreamWriter sw = new StreamWriter ("loading.log", true)) {
-                               sw.WriteLine ($"NEW ;{sourcePath,-50};{loadingTime.ElapsedTicks,8};{loadingTime.ElapsedMilliseconds,8}");
-                       }
-                       return o;
-#else
                        return loader (iface) as Widget;
-#endif
                }
                /// <summary>
                /// Creates a new instance of T compiled in the instantiator
@@ -154,17 +141,7 @@ namespace Crow.IML {
                /// </summary>
                /// <returns>The new T instance</returns>
                public T CreateInstance<T>(){
-#if DEBUG_LOAD
-                       Stopwatch loadingTime = Stopwatch.StartNew ();
-                       T i = (T)loader (iface);
-                       loadingTime.Stop ();
-                       using (StreamWriter sw = new StreamWriter ("loading.log", true)) {
-                               sw.WriteLine ($"NEW ;{sourcePath,-50};{loadingTime.ElapsedTicks,8};{loadingTime.ElapsedMilliseconds,8}");
-                       }
-                       return i;
-#else
                        return (T)loader (iface);
-#endif
                }
                List<DynamicMethod> dsValueChangedDynMeths = new List<DynamicMethod>();
                List<Delegate> cachedDelegates = new List<Delegate>();
index 8d4766ff58d9daebeef2508a7d998e3f89b496ef..87e8a1f1d0dee776b0214416d0c5e637dde27b3b 100644 (file)
@@ -685,11 +685,14 @@ namespace Crow
                        lock (ClippingMutex) {
                                if (g.IsQueueForClipping)
                                        return;
-                               #if DEBUG_LOG
-                               DbgLogger.AddEvent(DbgEvtType.GOEnqueueForRepaint, g);
-                               #endif  
+#if DEBUG_LOG
+                               DbgLogger.StartEvent (DbgEvtType.GOEnqueueForRepaint, g);
+#endif 
                                ClippingQueue.Enqueue (g);
                                g.IsQueueForClipping = true;
+#if DEBUG_LOG
+                               DbgLogger.EndEvent (DbgEvtType.GOEnqueueForRepaint);
+#endif
                        }
                }
                /// <summary>Main Update loop, executed in this interface thread, protected by the UpdateMutex
@@ -723,7 +726,7 @@ namespace Crow
                                return;
                                
 #if DEBUG_LOG
-                       DbgLogger.StartEvent (DbgEvtType.IFaceUpdate);
+                       DbgLogger.StartEvent (DbgEvtType.Update);
 #endif
 
                        processLayouting ();
@@ -737,7 +740,7 @@ namespace Crow
                                processDrawing (ctx);
 
 #if DEBUG_LOG
-                       DbgLogger.EndEvent (DbgEvtType.IFaceUpdate, true);
+                       DbgLogger.EndEvent (DbgEvtType.Update, true);
 #endif
 
                        Monitor.Exit (UpdateMutex);
@@ -748,7 +751,7 @@ namespace Crow
                protected virtual void processLayouting(){
                        if (Monitor.TryEnter (LayoutMutex)) {
 #if DEBUG_LOG
-                               DbgLogger.StartEvent (DbgEvtType.IFaceLayouting);
+                               DbgLogger.StartEvent (DbgEvtType.Layouting);
 #endif
                                DiscardQueue = new Queue<LayoutingQueueItem> ();
                                //Debug.WriteLine ("======= Layouting queue start =======");
@@ -759,7 +762,7 @@ namespace Crow
                                }
                                LayoutingQueue = DiscardQueue;
 #if DEBUG_LOG
-                               DbgLogger.EndEvent (DbgEvtType.IFaceLayouting, true);
+                               DbgLogger.EndEvent (DbgEvtType.Layouting, true);
 #endif
                                Monitor.Exit (LayoutMutex);
                                DiscardQueue = null;
@@ -770,7 +773,7 @@ namespace Crow
                /// operation to known if it should go down in the tree for further graphic updates and repaints</summary>
                void clippingRegistration(){
 #if DEBUG_LOG
-                       DbgLogger.StartEvent (DbgEvtType.IFaceClipping);
+                       DbgLogger.StartEvent (DbgEvtType.Clipping);
 #endif
                        Widget g = null;
                        while (ClippingQueue.Count > 0) {
@@ -781,14 +784,14 @@ namespace Crow
                                g.ClippingRegistration ();
                        }
 #if DEBUG_LOG
-                       DbgLogger.EndEvent (DbgEvtType.IFaceClipping, true);
+                       DbgLogger.EndEvent (DbgEvtType.Clipping, true);
 #endif
                }
                /// <summary>Clipping Rectangles drive the drawing process. For compositing, each object under a clip rectangle should be
                /// repainted. If it contains also clip rectangles, its cache will be update, or if not cached a full redraw will take place</summary>
                void processDrawing(Context ctx){
 #if DEBUG_LOG
-                       DbgLogger.StartEvent (DbgEvtType.IFaceDrawing);
+                       DbgLogger.StartEvent (DbgEvtType.Drawing);
 #endif
                        if (DragImage != null)
                                clipping.UnionRectangle(new Rectangle (DragImageX, DragImageY, DragImageWidth, DragImageHeight));
@@ -852,7 +855,7 @@ namespace Crow
                                }
                        
 #if DEBUG_LOG
-                       DbgLogger.EndEvent (DbgEvtType.IFaceDrawing, true);
+                       DbgLogger.EndEvent (DbgEvtType.Drawing, true);
 #endif
                }
                #endregion
@@ -922,12 +925,6 @@ namespace Crow
                                        g.Dispose ();
                                }
                        }
-                       #if DEBUG_LAYOUTING
-                       LQIsTries = new List<LQIList>();
-                       curLQIsTries = new LQIList();
-                       LQIs = new List<LQIList>();
-                       curLQIs = new LQIList();
-                       #endif
                }
                /// <summary> Put widget on top of other root widgets</summary>
                public void PutOnTop(Widget g, bool isOverlay = false)
@@ -1436,20 +1433,6 @@ namespace Crow
                }
                public Rectangle getSlot () { return ClientRectangle; }
                #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;
-#else
-               public List<LQIList> LQIs = null;//still create the var for CrowIDE
-#endif
        }
 }
 
index f1568db3a1c6f735bd29df61c4e72645917c05f5..4fc22d1a2621f046a40a2aee14920f9b0e8d9098 100644 (file)
@@ -35,7 +35,7 @@ namespace Crow
                /// <summary> Unsuccessfull UpdateLayout and requeueing count </summary>
                public int LayoutingTries, DiscardCount;
 
-               #if DEBUG_LOG
+
                public enum Result : byte {
                        Unknown,
                        Register,
@@ -44,6 +44,7 @@ namespace Crow
                        Discarded,
                        Deleted,
                }
+#if DEBUG_LOG
                public Result result;
                public Widget graphicObject {
                        get { return Layoutable as Widget; }
@@ -101,7 +102,7 @@ namespace Crow
                                return;
                        }
                        #if DEBUG_LOG
-                       DbgLogger.DbgEvent dbgEvt = DbgLogger.StartEvent (DbgEvtType.GOProcessLayouting, this);
+                       DbgLogger.StartEvent (DbgEvtType.GOProcessLayouting, this);
                        #endif
                        LayoutingTries++;
                        if (!Layoutable.UpdateLayout (LayoutType)) {
@@ -130,7 +131,9 @@ namespace Crow
                        else{
                                result = Result.Success;
                        }
-                       DbgLogger.EndEvent (DbgEvtType.GOProcessLayouting).data = this;
+                       Slot = graphicObject.LastSlots;
+                       NewSlot = graphicObject.Slot;
+                       (DbgLogger.EndEvent (DbgEvtType.GOProcessLayouting) as DbgLayoutEvent).SetLQI (this);
                        #endif
                        go.parentRWLock.ExitReadLock ();
                }
@@ -144,22 +147,7 @@ namespace Crow
                        return lqi.LayoutType;
                }
                public override string ToString ()
-               {
-                       #if DEBUG_LAYOUTING
-                       return string.Format ("{2};{3} {1}->{0}", LayoutType,Layoutable.ToString(),
-                               LayoutingTries,DiscardCount);
-                       #else
-                       return string.Format ("{2};{3} {1}->{0}", LayoutType,Layoutable.ToString(),
-                               LayoutingTries, DiscardCount);
-                       #endif
-               }
-       }
-       public class LQIList : List<LayoutingQueueItem>{
-//             #if DEBUG_LAYOUTING
-//             public List<LayoutingQueueItem> GetRootLQIs(){
-//                     return this.Where (lqi => lqi.wasTriggeredBy == null).ToList ();
-//             }
-//             #endif
+                       => $"{LayoutType};{Layoutable.ToString ()};{LayoutingTries};{DiscardCount}";
        }
 }
 
index 2fd86466e1ce551ae6e47d798a34f5f7ca55a08d..de33aa2aa93fbcf8564cf228c9d5c6fb31b982ce 100644 (file)
@@ -117,9 +117,6 @@ namespace Crow {
                                if (newW != stretchedGO.Slot.Width) {
                                        stretchedGO.Slot.Width = newW;
                                        stretchedGO.IsDirty = true;
-#if DEBUG_LAYOUTING
-                                       LOG ($"width: {stretchedGO.ToString()}");
-#endif
                                        stretchedGO.LayoutChanged -= OnChildLayoutChanges;
                                        stretchedGO.OnLayoutChanges (LayoutingType.Width);
                                        stretchedGO.LayoutChanged += OnChildLayoutChanges;
@@ -134,9 +131,6 @@ namespace Crow {
                                if (newH != stretchedGO.Slot.Height) {
                                        stretchedGO.Slot.Height = newH;
                                        stretchedGO.IsDirty = true;
-#if DEBUG_LAYOUTING
-                                       LOG ($"height: {stretchedGO.ToString ()}");
-#endif
                                        stretchedGO.LayoutChanged -= OnChildLayoutChanges;
                                        stretchedGO.OnLayoutChanges (LayoutingType.Height);
                                        stretchedGO.LayoutChanged += OnChildLayoutChanges;
index 6731d7bebaf6de3e3496e220cdac1a206640aa39..419479b579393f1b35a34fbbab887281a5098236 100644 (file)
@@ -67,9 +67,9 @@ namespace Crow
             set { _multiSelect = value; }
         }
                public virtual void AddChild(Widget g){
-#if DEBUG
+#if DEBUG_LOG
                        if (disposed) {
-                               System.Diagnostics.Debug.WriteLine ($"AddChild ({g}) in disposed Widget: {this}\n{System.Environment.StackTrace}");
+                               DbgLogger.AddEvent (DbgEvtType.AlreadyDisposed | DbgEvtType.GOAddChild);
                                return;
                        }
 #endif
@@ -116,9 +116,9 @@ namespace Crow
                        child.Dispose ();
         }
                public virtual void InsertChild (int idx, Widget g) {
-#if DEBUG
+#if DEBUG_LOG
                        if (disposed) {
-                               System.Diagnostics.Debug.WriteLine ($"InsertChild ({idx},{g}) in disposed Widget: {this}\n{System.Environment.StackTrace}");
+                               DbgLogger.AddEvent (DbgEvtType.AlreadyDisposed | DbgEvtType.GOAddChild);
                                return;
                        }
 #endif
@@ -344,10 +344,6 @@ namespace Crow
                {
                        Widget g = sender as Widget;
 
-#if DEBUG_LAYOUTING
-                       LOG ($"{arg.LayoutType}:{g}->{g.Slot}");
-#endif
-
                        switch (arg.LayoutType) {
                        case LayoutingType.Width:
                                if (Width != Measure.Fit)
@@ -381,9 +377,9 @@ namespace Crow
                }
                void searchLargestChild (bool forceMeasure = false)
                {
-                       #if DEBUG_LAYOUTING
-                       LOG (this.ToString());
-                       #endif
+#if DEBUG_LOG
+                       DbgLogger.StartEvent (DbgEvtType.GOSearchLargestChild, this);
+#endif
                        largestChild = null;
                        contentSize.Width = 0;
                        for (int i = 0; i < Children.Count; i++) {
@@ -401,12 +397,15 @@ namespace Crow
                                        largestChild = Children [i];
                                }
                        }
+#if DEBUG_LOG
+                       DbgLogger.EndEvent (DbgEvtType.GOSearchLargestChild);
+#endif
                }
                void searchTallestChild (bool forceMeasure = false)
                {
-                       #if DEBUG_LAYOUTING
-                       LOG (this.ToString());
-                       #endif
+#if DEBUG_LOG
+                       DbgLogger.StartEvent (DbgEvtType.GOSearchTallestChild, this);
+#endif
                        tallestChild = null;
                        contentSize.Height = 0;
                        for (int i = 0; i < Children.Count; i++) {
@@ -424,6 +423,9 @@ namespace Crow
                                        tallestChild = Children [i];
                                }
                        }
+#if DEBUG_LOG
+                       DbgLogger.EndEvent (DbgEvtType.GOSearchTallestChild);
+#endif
                }
 
 
index be7d4b3332f7d5360c9b9d2e32d6162f8d22c9d5..eb49147e4a2ed3c06e302a4193564b4060081cae 100644 (file)
@@ -146,9 +146,6 @@ namespace Crow
                }
                public override void onMouseClick (object sender, MouseButtonEventArgs e)
                {
-#if DEBUG_FOCUS
-                       System.Diagnostics.Debug.WriteLine ("MENU CLICK => " + this.ToString ());
-#endif
                        if (command != null) {
                                command.Execute ();
                                closeMenu ();
index bd49c1b40aa25bb2740b64f3324a4ecb2b22bf3d..4972ab962dd5022ecc490682f3aae6602a2eb8b8 100644 (file)
@@ -159,9 +159,6 @@ namespace Crow
                public virtual void OnChildLayoutChanges (object sender, LayoutingEventArgs arg)
                {                       
                        Widget g = sender as Widget;
-#if DEBUG_LAYOUTING
-                       LOG ($"{arg.LayoutType}:{g}->{child.Slot}");
-#endif
                        if (arg.LayoutType == LayoutingType.Width) {
                                contentSize.Width = g.Slot.Width;
                                if (Width != Measure.Fit)
index ca693cde8f7a384fb1a18279bbc3e4bc0ab7b003..0ca6e92a54e4ac600100564aaa8e0e6c68c677f2 100644 (file)
@@ -32,6 +32,7 @@ namespace Crow
                //0 is the main graphic tree, for other obj tree not added to main tree, it range from 1->n
                //useful to track events for obj shown later, not on start, or never added to main tree
                public int treeIndex;
+               public int instanceIndex;//index in the GraphicObjects list
                public int yIndex;//absolute index in the graphic tree for debug draw
                public int xLevel;//x increment for debug draw
                #endif
@@ -146,18 +147,16 @@ namespace Crow
                }
                protected virtual void Dispose(bool disposing){
                        if (disposed){
-                               #if DEBUG_DISPOSE
-                               Debug.WriteLine ("Trying to dispose already disposed obj: {0}", this.ToString());
-                               #endif
+#if DEBUG_LOG
+                               DbgLogger.AddEvent (DbgEvtType.AlreadyDisposed, this);
+#endif
                                return;
                        }
 
+#if DEBUG_LOG
+                       DbgLogger.StartEvent (DbgEvtType.Disposing, this);
+#endif
                        if (disposing) {
-                               #if DEBUG_DISPOSE
-                               System.Diagnostics.Debug.WriteLine ("Disposing: {0}", this.ToString());
-                               //if ()
-                               //throw new Exception("Trying to dispose an object queued for Redraw: " + this.ToString());
-                               #endif
 
                                unshownPostActions ();
 
@@ -167,15 +166,21 @@ namespace Crow
                                parentRWLock.EnterWriteLock();
                                parent = null;
                                parentRWLock.ExitWriteLock();
-                       } else
-                               Debug.WriteLine ("!!! Finalized by GC: {0}", this.ToString ());
+                       }
+#if DEBUG_LOG
+                        else
+                               DbgLogger.AddEvent (DbgEvtType.DisposedByGC, this);
+#endif
                        Clipping?.Dispose ();
                        bmp?.Dispose ();
                        disposed = true;
-               }  
+#if DEBUG_LOG
+                       DbgLogger.EndEvent (DbgEvtType.Disposing);
+#endif
+               }
                #endregion
 
-               #if DEBUG_LOG
+#if DEBUG_LOG
                internal static List<Widget> GraphicObjects = new List<Widget>();
                #endif
 
@@ -226,10 +231,11 @@ namespace Crow
                /// </summary>
                protected Widget () {
                        Clipping = new Region ();
-                       #if DEBUG_LOG
+#if DEBUG_LOG
+                       instanceIndex = GraphicObjects.Count;
                        GraphicObjects.Add (this);
                        DbgLogger.AddEvent(DbgEvtType.GOClassCreation, this);
-                       #endif                  
+#endif
                }
                /// <summary>
                /// This constructor **must** be used when creating widget from code.
@@ -1420,9 +1426,9 @@ namespace Crow
                [MethodImpl(MethodImplOptions.AggressiveInlining)]
                public void RegisterForGraphicUpdate ()
                {
-#if DEBUG
+#if DEBUG_LOG
                        if (disposed) {
-//                             System.Diagnostics.Debug.WriteLine ($"RegisterForGraphicUpdate for disposed Widget: {this}\n{System.Environment.StackTrace}");
+                               DbgLogger.AddEvent (DbgEvtType.GORegisterForGraphicUpdate | DbgEvtType.AlreadyDisposed, this);
                                return;
                        }
 #endif
@@ -1438,7 +1444,7 @@ namespace Crow
                {
 #if DEBUG
                        if (disposed) {
-                               System.Diagnostics.Debug.WriteLine ($"RegisterForRedraw for disposed Widget: {this}\n{System.Environment.StackTrace}");
+                               DbgLogger.AddEvent (DbgEvtType.GORegisterForRedraw | DbgEvtType.AlreadyDisposed, this);
                                return;
                        }
 #endif
@@ -1913,9 +1919,6 @@ namespace Crow
 
                }
                public virtual void onMouseDown(object sender, MouseButtonEventArgs e){
-#if DEBUG_FOCUS
-                       Debug.WriteLine("MOUSE DOWN => " + this.ToString());
-#endif
                        if (Focusable) {
                                IFace.FocusedWidget = this;
                                e.Handled = true;
@@ -1932,9 +1935,6 @@ namespace Crow
                                FocusParent?.onMouseDown (sender, e);
                }
                public virtual void onMouseUp(object sender, MouseButtonEventArgs e){
-#if DEBUG_FOCUS
-                       Debug.WriteLine("MOUSE UP => " + this.ToString());
-#endif
 
                        if (IFace.DragAndDropOperation != null){
                                if (IFace.DragAndDropOperation.DragSource == this) {
@@ -1951,18 +1951,12 @@ namespace Crow
                                FocusParent?.onMouseUp (sender, e);
                }
                public virtual void onMouseClick(object sender, MouseButtonEventArgs e){
-#if DEBUG_FOCUS
-                       Debug.WriteLine("CLICK => " + this.ToString());
-#endif
                        if (MouseClick != null)
                                MouseClick.Invoke (this, e);
                        else if (!e.Handled)
                                FocusParent?.onMouseClick (sender, e);
                }
                public virtual void onMouseDoubleClick(object sender, MouseButtonEventArgs e){
-#if DEBUG_FOCUS
-                       Debug.WriteLine("DOUBLE CLICK => " + this.ToString());
-#endif
                        if (MouseDoubleClick != null)                   
                                MouseDoubleClick.Invoke (this, e);
                        else if (!e.Handled)
@@ -1976,10 +1970,6 @@ namespace Crow
                }
                public virtual void onMouseEnter(object sender, MouseMoveEventArgs e)
                {
-                       #if DEBUG_FOCUS
-                       Debug.WriteLine("MouseEnter => " + this.ToString());
-                       #endif
-
                        IFace.MouseCursor = MouseCursor;
 
                        if (IFace.DragAndDropOperation != null) {
@@ -2001,10 +1991,6 @@ namespace Crow
                }
                public virtual void onMouseLeave(object sender, MouseMoveEventArgs e)
                {
-                       #if DEBUG_FOCUS
-                       Debug.WriteLine("MouseLeave => " + this.ToString());
-                       #endif
-
                        MouseLeave.Raise (this, e);
                }
 
@@ -2030,17 +2016,23 @@ namespace Crow
                        Disabled.Raise (this, e);
                }
                protected virtual void onParentChanged(object sender, DataSourceChangeEventArgs e) {
+#if DEBUG_LOG
+                       DbgLogger.AddEvent (DbgEvtType.GONewParent, this, e);
+#endif
                        ParentChanged.Raise (this, e);
                        if (logicalParent == null)
                                LogicalParentChanged.Raise (this, e);
                }
                protected virtual void onLogicalParentChanged(object sender, DataSourceChangeEventArgs e) {
+#if DEBUG_LOG
+                       DbgLogger.AddEvent (DbgEvtType.GONewLogicalParent, this, e);
+#endif
                        LogicalParentChanged.Raise (this, e);
                }
                internal void ClearTemplateBinding(){
-                       #if DEBUG_UPDATE
+#if DEBUG_UPDATE
                        Debug.WriteLine (string.Format("ClearTemplateBinding: {0}", this.ToString()));
-                       #endif
+#endif
                        if (ValueChanged == null)
                                return;
                        EventInfo eiEvt = this.GetType().GetEvent ("ValueChanged");
index 13443fae3bf91a91d32fdb73bc0f32f72f270aa5..6d792d259740231c9706f59917c4f44b8cc6ee1b 100644 (file)
@@ -192,9 +192,6 @@ namespace Crow
                }
                public override void OnLayoutChanges (LayoutingType layoutType)
                {
-#if DEBUG_LAYOUTING
-                       LOG ($"{layoutType}: {LastSlots}->{Slot}");
-#endif
                        switch (layoutType) {
                        case LayoutingType.Width:
                                foreach (Widget c in Children) {
index c05ffbbc1f73ac032bb41f27a6e904a48c3dbe4a..3be2c2094c8206c6c7a717f300e1de0bcc58f116 100644 (file)
@@ -1,35 +1,13 @@
-//
-// DbgEventTypeColors.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 Crow.Cairo;
 using System.Linq;
 
 namespace Crow
 {
-       #if DEBUG_LOG
        public class DbgEventTypeColors : Widget
        {
                protected override void onDraw (Context gr)
@@ -72,6 +50,5 @@ namespace Crow
                        }
                }
        }
-       #endif
 }
 
index 1a0d5db2b9d95043742a3d6915b62ca2a7943a52..57bd8e301331c79b6d19704acd689edb0e33859e 100644 (file)
@@ -9,7 +9,6 @@ using System.Linq;
 using System.Threading.Tasks;
 using Crow.Cairo;
 
-#if DEBUG_LOG
 namespace Crow
 {
        public class DbgLogViewer : ScrollingObject
@@ -18,182 +17,6 @@ namespace Crow
 
                public static Configuration colorsConf = new Configuration ("dbgcolor.conf");//, Interface.GetStreamFromPath("#Crow.dbgcolor.conf"));
 
-               #region debug viewer private classes
-               public class DbgLayoutEvent : DbgWidgetEvent
-               {
-                       public LayoutingType layouting;
-                       public LayoutingQueueItem.Result result;
-                       public override Color Color {
-                               get {
-                                       if (type == DbgEvtType.GORegisterLayouting)
-                                               return Colors.GreenYellow;
-                                       if (type == DbgEvtType.GOProcessLayoutingWithNoParent)
-                                               return Colors.DarkRed;
-                                       switch (result) {
-                                       case LayoutingQueueItem.Result.Success:
-                                               return Colors.Green;
-                                       case LayoutingQueueItem.Result.Deleted:
-                                               return Colors.Red;
-                                       case LayoutingQueueItem.Result.Discarded:
-                                               return Colors.OrangeRed;
-                                       default:
-                                               return Colors.Orange;
-                                       }
-                               }
-                       }
-               }
-               public class DbgWidgetEvent : DbgEvent
-               {
-                       public int widgetInstanceId;
-                       public override Color Color {
-                               get {
-                                       switch (type) {
-                                       case DbgEvtType.GOClassCreation:
-                                               return Colors.DarkSlateGrey;
-                                       case DbgEvtType.GOInitialization:
-                                               return Colors.DarkOliveGreen;
-                                       case DbgEvtType.GOClippingRegistration:
-                                               return Colors.MediumTurquoise;
-                                       case DbgEvtType.GORegisterClip:
-                                               return Colors.Turquoise;
-                                       case DbgEvtType.GORegisterForGraphicUpdate:
-                                               return Colors.LightPink;
-                                       case DbgEvtType.GOEnqueueForRepaint:
-                                               return Colors.LightSalmon;
-                                       case DbgEvtType.GONewDataSource:
-                                               return Colors.MediumVioletRed;
-                                       case DbgEvtType.GODraw:
-                                               return Colors.SteelBlue;
-                                       case DbgEvtType.GORecreateCache:
-                                               return Colors.CornflowerBlue;
-                                       case DbgEvtType.GOUpdateCache:
-                                               return Colors.SteelBlue;
-                                       case DbgEvtType.GOPaint:
-                                               return Colors.RoyalBlue;
-                                       case DbgEvtType.GOLockUpdate:
-                                               return Colors.SaddleBrown;
-                                       case DbgEvtType.GOLockClipping:
-                                               return Colors.Sienna;
-                                       case DbgEvtType.GOLockRender:
-                                               return Colors.BurlyWood;
-                                       case DbgEvtType.GOLockLayouting:
-                                               return Colors.GoldenRod;
-                                       case DbgEvtType.TGCancelLoadingThread:
-                                               return Colors.Maroon;
-                                       default:
-                                               return Colors.Crimson;
-                                       }
-                                       if (type.HasFlag (DbgEvtType.GOLock))
-                                               return Colors.DarkMagenta;
-                                       return Colors.White;
-                               }
-                       }
-               }
-               public class DbgEvent {
-                       public long begin, end;
-                       public int threadId;
-                       public DbgEvtType type;
-                       public DbgEvent parentEvent;
-                       public List<DbgEvent> events;
-                       public bool HasChildEvents => events != null && events.Count > 0;
-                       public long Duration => end - begin;
-
-                       public virtual Color Color {
-                               get {
-                                       switch (type) {
-                                       case DbgEvtType.IFaceLayouting:
-                                               return Colors.Yellow;
-                                       case DbgEvtType.IFaceClipping:
-                                               return Colors.DarkTurquoise;
-                                       case DbgEvtType.IFaceDrawing:
-                                               return Colors.MidnightBlue;
-                                       case DbgEvtType.IFaceUpdate:
-                                               return Colors.Grey;
-                                       case DbgEvtType.IFaceLoad:
-                                               return Colors.Teal;
-                                       default:
-                                               return Colors.White;
-                                       }
-
-                               }
-                       }
-
-                       public void AddEvent (DbgEvent evt)
-                       {
-                               if (events == null)
-                                       events = new List<DbgEvent> () { evt };
-                               else
-                                       events.Add (evt);
-                               evt.parentEvent = this;
-                       }
-
-                       public DbgEvent() {}
-
-                       public static DbgEvent Parse (string str) {
-                               if (str == null)
-                                       return null;
-                               string[] tmp = str.Trim().Split(';');
-
-                               DbgEvtType evtType = (DbgEvtType)Enum.Parse (typeof (DbgEvtType), tmp [3]);
-
-                               if (evtType.HasFlag (DbgEvtType.GraphicObject)) {
-                                       if (evtType.HasFlag (DbgEvtType.GOLayouting))
-                                               return new DbgLayoutEvent () {
-                                                       begin = long.Parse (tmp [0]),
-                                                       end = long.Parse (tmp [1]),
-                                                       threadId = int.Parse (tmp [2]),
-                                                       type = evtType,
-                                                       widgetInstanceId = int.Parse (tmp [4]),
-                                                       layouting = (LayoutingType)Enum.Parse (typeof (LayoutingType), tmp [5]),
-                                                       result = evtType == DbgEvtType.GOProcessLayouting ?
-                                                               (LayoutingQueueItem.Result)Enum.Parse (typeof (LayoutingQueueItem.Result), tmp [6])
-                                                               : LayoutingQueueItem.Result.Unknown
-                                               };
-                                       return new DbgWidgetEvent () {
-                                               begin = long.Parse (tmp [0]),
-                                               end = long.Parse (tmp [1]),
-                                               threadId = int.Parse (tmp [2]),
-                                               type = evtType,
-                                               widgetInstanceId = int.Parse (tmp [4]),
-                                       };
-                               }
-                               return new DbgEvent () {
-                                       begin = long.Parse (tmp [0]),
-                                       end = long.Parse (tmp [1]),
-                                       threadId = int.Parse (tmp [2]),
-                                       type = evtType,
-                               };
-                       }
-                       public override string ToString ()
-                               => $"{begin}:{end}:{type}";
-               }
-               public class DbgGo {
-                       public int listIndex;//prevent doing an IndexOf on list for each event to know y pos on screen
-                       public int instanceNum;//class instantiation order, used to bind events to objs
-                       public string name;
-                       //0 is the main graphic tree, for other obj tree not added to main tree, it range from 1->n
-                       //useful to track events for obj shown later, not on start
-                       public int treeIndex;
-                       public int yIndex;//index in parenting, the whole main graphic tree is one continuous suite
-                       public int xLevel;//depth
-
-                       public List<DbgEvent> events = new List<DbgEvent>();//flattened event list of this widget
-
-                       public static DbgGo Parse (string str) {
-                               DbgGo g = new DbgGo ();
-                               if (str == null)
-                                       return null;
-                               string[] tmp = str.Trim().Split(';');
-                               g.instanceNum = int.Parse (tmp [0]);
-                               g.name = tmp [1];
-                               g.yIndex = int.Parse (tmp [2]);
-                               g.xLevel = int.Parse (tmp [3]);
-                               return g;
-                       }
-
-               }
-               #endregion
-
                public static void reloadColors () {
                        colors = new Dictionary<DbgEvtType, Color>();
                        foreach (string n in colorsConf.Names) {
@@ -215,14 +38,14 @@ namespace Crow
 
                double xScale = 1.0/512.0, yScale = 1.0, leftMargin, topMargin = 0.0;
                string logFile;
-               DbgGo curWidget;
+               DbgWidgetRecord curWidget;
                DbgEvent curEvent;
 
                List<DbgEvent> events;
-               List<DbgGo> objs;
+               List<DbgWidgetRecord> objs;
 
                public List<DbgEvent> Events => events;
-               public List<DbgGo> Widgets => objs;
+               public List<DbgWidgetRecord> Widgets => objs;
 
 
                long currentTick = 0, selStart = -1, selEnd = -1, minTicks = 0, maxTicks = 0, visibleTicks = 0;
@@ -302,7 +125,7 @@ namespace Crow
                        }
                }
 
-               public DbgGo CurrentWidget {
+               public DbgWidgetRecord CurrentWidget {
                        get => curWidget;
                        internal set {
                                if (curWidget == value)
@@ -316,7 +139,15 @@ namespace Crow
                        internal set {
                                if (curEvent == value)
                                        return;
+
+                               if (curEvent != null)
+                                       curEvent.IsSelected = false;
                                curEvent = value;
+                               if (curEvent != null) {
+                                       curEvent.IsSelected = true;
+                                       curEvent.IsExpanded = true;
+                               }
+
                                NotifyValueChanged (nameof (CurrentEvent), curEvent);
                        }
                }
@@ -334,9 +165,9 @@ namespace Crow
                                if (evt.begin - minTicks > ScrollX + visibleTicks)
                                        break;
                                double penY = topMargin + ClientRectangle.Top;
-                               if (evt.type.HasFlag (DbgEvtType.GraphicObject)) {
+                               if (evt.type.HasFlag (DbgEvtType.Widget)) {
                                        DbgWidgetEvent eW = evt as DbgWidgetEvent;
-                                       int lIdx = eW.widgetInstanceId - ScrollY;
+                                       int lIdx = eW.InstanceIndex - ScrollY;
                                        if (lIdx < 0 || lIdx > visibleLines)
                                                continue;
                                        penY += (lIdx) * fe.Height; 
@@ -380,7 +211,7 @@ namespace Crow
                                        ctx.ShowText (s);
 
                                }
-                               drawEvents (ctx, evt.events);
+                               drawEvents (ctx, evt.Events);
                        }
                }
 
@@ -405,7 +236,8 @@ namespace Crow
                        for (int i = 0; i < visibleLines; i++) {
                                if (i + ScrollY >= objs.Count)
                                        break;
-                               DbgGo g = objs [i + ScrollY];
+                               int gIdx = i + ScrollY;
+                               DbgWidgetRecord g = objs [gIdx];
 
                                penY += fe.Height;
 
@@ -422,7 +254,7 @@ namespace Crow
                                        Foreground.SetAsSource (gr);
 
                                gr.MoveTo (penX, penY - gr.FontExtents.Descent);
-                               gr.ShowText (g.name + g.instanceNum);
+                               gr.ShowText (g.name + gIdx);
 
                                gr.SetSource (Crow.Colors.White);
                                gr.MoveTo (cb.X, penY - gr.FontExtents.Descent);
@@ -589,6 +421,8 @@ namespace Crow
                        base.onMouseDown (sender, e);
 
                        if (e.Button == Glfw.MouseButton.Left) {
+                               CurrentWidget = (currentLine < 0 || currentLine >= objs.Count) ? null : objs [currentLine];
+                               CurrentEvent = curWidget?.Events.FirstOrDefault (ev => ev.begin <= currentTick && ev.end >= currentTick);
                                selStart = currentTick;
                                selEnd = -1;
                        }
@@ -651,7 +485,7 @@ namespace Crow
                                return;
 
                        events = new List<DbgEvent> ();
-                       objs = new List<DbgGo> ();
+                       objs = new List<DbgWidgetRecord> ();
                        minTicks = maxTicks = 0;
                        leftMargin = topMargin = 0.0;
 
@@ -668,7 +502,7 @@ namespace Crow
                                                string l = s.ReadLine ();
                                                if (l == "[Events]")
                                                        break;
-                                               DbgGo o = DbgGo.Parse (l);
+                                               DbgWidgetRecord o = DbgWidgetRecord.Parse (l);
                                                objs.Add (o);
                                                double nameWidth = gr.TextExtents (o.name).Width + 5.0 * o.xLevel;
                                                if (nameWidth > maxNameWidth)
@@ -706,8 +540,8 @@ namespace Crow
                                                                }
                                                        }
                                                        startedEvents.Push (evt);
-                                                       if (evt.type.HasFlag(DbgEvtType.GraphicObject))
-                                                               objs [(evt as DbgWidgetEvent).widgetInstanceId].events.Add (evt);
+                                                       if (evt.type.HasFlag(DbgEvtType.Widget))
+                                                               objs [(evt as DbgWidgetEvent).InstanceIndex].Events.Add (evt);
                                                }
                                                if (events.Count > 0)
                                                        minTicks = events [0].begin;
@@ -777,8 +611,6 @@ namespace Crow
                        mousePos.Y = Math.Min (cb.Bottom, mousePos.Y);
 
                        currentTick = (int)((double)(mousePos.X - cb.X) / xScale) + minTicks + ScrollX;
-                       CurrentWidget = (currentLine < 0 || currentLine >= objs.Count) ? null : objs [currentLine];
-                       CurrentEvent = curWidget?.events.FirstOrDefault (e => e.begin <= currentTick && e.end >= currentTick);
                }
                void zoom (long start, long end) {                                              
                        //Rectangle cb = ClientRectangle;
@@ -788,5 +620,5 @@ namespace Crow
                }
        }
 }
-#endif
+
 
index 61ca14af512ea6f3387c2227cf4674bd6b3e8f2f..1c188737bed9d327d4bb320b98f4191b663c4880 100644 (file)
@@ -10,133 +10,110 @@ using System.IO;
 using System.Linq;
 using System.Threading;
 
-#if DEBUG_LOG
+
 namespace Crow
 {
-       /*public class LayoutingEvent : DbgEvent {
-               public List<LayoutingQueueItem> lqis = new List<LayoutingQueueItem>();
-
-       }*/
        [Flags]
        public enum DbgEvtType {
                ////9 nth bit set for iface event
                IFace                                                   = 0x10000,
-               IFaceFocus                                              = 0x20000,
-               GraphicObject                                   = 0x00100,
-               GOLayouting                                     = 0x00200,
-               Drawing                                                 = 0x00400,
-               GOLock                                                  = 0x00800,
-               IFaceLayouting                                  = IFace | 0x01,
-               IFaceClipping                                   = IFace | 0x02,
-               IFaceDrawing                                    = IFace | 0x03,
-               IFaceUpdate                                             = IFace | 0x04,
+               Focus                                                   = 0x20000,
+               Override                                                = 0x40000,
+               Widget                                                  = 0x00100,
+               //GOLayouting                                   = 0x00200,
+               //Drawing                                               = 0x00400,
+               Lock                                                    = 0x00800,
+               Layouting                                               = IFace | 0x01000,
+               Clipping                                                = IFace | 0x02000,
+               Drawing                                                 = IFace | 0x04000,
+               Update                                                  = IFace | 0x08000,
                IFaceLoad                                               = IFace | 0x05,
                IFaceInit                                               = IFace | 0x06,
+               CreateITor                                              = IFace | 0x07,
 
-               HoverWidget                                             = IFaceFocus | 0x01,
-               FocusedWidget                                   = IFaceFocus | 0x02,
-               ActiveWidget                                    = IFaceFocus | 0x03,
+               HoverWidget                                             = Focus | 0x01,
+               FocusedWidget                                   = Focus | 0x02,
+               ActiveWidget                                    = Focus | 0x03,
 
                //10 nth bit set for graphic obj
-               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,
                TemplatedGroup                                  = 0x1000,
-               GORegisterLayouting                     = GraphicObject | GOLayouting | 0x01,
-               GOProcessLayouting                              = GraphicObject | GOLayouting | 0x02,
-               GOProcessLayoutingWithNoParent  = Warning | GraphicObject | GOLayouting | 0x01,
-               GODraw                                                  = GraphicObject | Drawing | 0x01,
-               GORecreateCache                                 = GraphicObject | Drawing | 0x02,
-               GOUpdateCache           = GraphicObject | Drawing | 0x03,
-               GOPaint                                                 = GraphicObject | Drawing | 0x04,
-
-               GOLockUpdate                                    = GraphicObject | GOLock | 0x01,
-               GOLockClipping                                  = GraphicObject | GOLock | 0x02,
-               GOLockRender                                    = GraphicObject | GOLock | 0x03,
-               GOLockLayouting                                 = GraphicObject | GOLock | 0x04,
-
-               TGLoadingThread                                 = GraphicObject | TemplatedGroup | 0x01,
-               TGCancelLoadingThread                   = GraphicObject | TemplatedGroup | 0x02,
+               Dispose                                                 = 0x2000,
+               Warning                                                 = 0x4000,
+               Error                                                   = 0x8000,
+               GOClassCreation                                 = Widget | 0x01,
+               GOInitialization                                = Widget | 0x02,
+               GORegisterForGraphicUpdate              = Widget | 0x03,
+               GOEnqueueForRepaint                             = Widget | 0x04,
+               GONewDataSource                                 = Widget | 0x05,
+               GONewParent                                             = Widget | 0x06,
+               GONewLogicalParent                              = Widget | 0x07,
+               GOAddChild                                              = Widget | 0x08,
+
+               GOSearchLargestChild                    = Widget | 0x09,
+               GOSearchTallestChild                    = Widget | 0x10,
+               GORegisterForRedraw                             = Widget | 0x11,
+
+               AlreadyDisposed                                 = Dispose | Widget | Error | 0x01,
+               DisposedByGC                                    = Dispose | Widget | Error | 0x02,
+               Disposing                                               = Dispose | Widget | 0x01,
+
+               GOClippingRegistration                  = Clipping | Widget | 0x01,
+               GORegisterClip                                  = Clipping | Widget | 0x02,
+               GORegisterLayouting                     = Layouting | Widget | 0x01,
+               GOProcessLayouting                              = Layouting | Widget | 0x02,
+               GOProcessLayoutingWithNoParent  = Layouting | Widget | Warning | 0x01,
+               GODraw                                                  = Drawing | Widget | 0x01,
+               GORecreateCache                                 = Drawing | Widget | 0x02,
+               GOUpdateCache                                   = Drawing | Widget | 0x03,
+               GOPaint                                                 = Drawing | Widget | 0x04,
+
+               GOLockUpdate                                    = Widget | Lock | 0x01,
+               GOLockClipping                                  = Widget | Lock | 0x02,
+               GOLockRender                                    = Widget | Lock | 0x03,
+               GOLockLayouting                                 = Widget | Lock | 0x04,
+
+               TGLoadingThread                                 = Widget | TemplatedGroup | 0x01,
+               TGCancelLoadingThread                   = Widget | TemplatedGroup | 0x02,
 
                All = 0x0FFFFFFF
        }
-
-
-
+#if DEBUG_LOG
        public static class DbgLogger
        {
                public static DbgEvtType IncludeEvents = DbgEvtType.All;
-               public static DbgEvtType DiscardEvents = DbgEvtType.IFaceFocus;
+               public static DbgEvtType DiscardEvents = DbgEvtType.Focus;
 
                static bool logevt (DbgEvtType evtType)
-               {
-                       return (evtType & DiscardEvents) == 0 && (evtType & IncludeEvents) != 0;
-               }
+                       => (evtType & DiscardEvents) == 0 && (evtType & IncludeEvents) != 0;
 
-               /// <summary>
-               /// debug events as recorded, another class is used in the viewer
-               /// </summary>
-               public class DbgEvent
-               {
-                       public long begin, end;
-                       public DbgEvtType type;
-                       public object data = null;
-                       public int threadId;
-                       public List<DbgEvent> Events = new List<DbgEvent> ();
-
-                       public DbgEvent () { }
-
-                       public DbgEvent (long timeStamp, DbgEvtType evt, object _data = null)
-                       {
-                               data = _data;
-                               type = evt;
-                               begin = timeStamp;
-                               end = timeStamp;
-                               threadId = Thread.CurrentThread.ManagedThreadId;
-                       }
 
-                       public override string ToString ()
-                       {
-                               string tmp = $"{begin};{end};{threadId};{type}";
-                               if (type.HasFlag (DbgEvtType.GraphicObject)) {
-                                       if (type.HasFlag (DbgEvtType.GOLayouting)) {
-                                               LayoutingQueueItem lqi = (LayoutingQueueItem)data;
-                                               tmp += $";{Widget.GraphicObjects.IndexOf (lqi.graphicObject).ToString ()};{lqi.LayoutType}";
-                                               if (type == DbgEvtType.GOProcessLayouting)
-                                                       tmp += $";{lqi.result}";
-                                       } else
-                                               tmp += $";{Widget.GraphicObjects.IndexOf (data as Widget).ToString ()}";
+               static object logMutex = new object ();
+               static Stopwatch chrono = Stopwatch.StartNew ();
+               static List<DbgEvent> events = new List<DbgEvent> ();
+               //started events per thread
+               static Dictionary<int, Stack<DbgEvent>> startedEvents = new Dictionary<int, Stack<DbgEvent>> ();
+               //helper for fetching current event list to add next event to while recording
+               static List<DbgEvent> curEventList {
+                       get {
+                               if (startedEvents.ContainsKey (Thread.CurrentThread.ManagedThreadId)) {
+                                       if (startedEvents [Thread.CurrentThread.ManagedThreadId].Count == 0)
+                                               return events;
+                                       DbgEvent e = startedEvents [Thread.CurrentThread.ManagedThreadId].Peek ();
+                                       if (e.Events == null) 
+                                               e.Events = new List<DbgEvent> ();
+                                       return e.Events;
                                }
-                               return tmp;
+                               return events;
                        }
                }
 
-               public static Stopwatch chrono = Stopwatch.StartNew();
-
-               static List<DbgEvent> events = new List<DbgEvent>();
-               static Dictionary<int, Stack<DbgEvent>> startedEvents = new Dictionary<int, Stack<DbgEvent>> ();
-
-               static object logMutex = new object ();
-
-
-               static List<DbgEvent> curEventList =>
-                       startedEvents.ContainsKey(Thread.CurrentThread.ManagedThreadId) ?
-                       startedEvents[Thread.CurrentThread.ManagedThreadId].Count == 0 ? events : startedEvents[Thread.CurrentThread.ManagedThreadId].Peek ().Events : events;
-
-               public static DbgEvent StartEvent (DbgEvtType evtType, object data = null)
+               public static DbgEvent StartEvent (DbgEvtType evtType, params object[] data)
                {
                        if (!logevt (evtType))
                                return null;
                        lock (logMutex) {
                                chrono.Stop ();
-                               DbgEvent evt = new DbgEvent (chrono.ElapsedTicks, evtType, data);
-                               curEventList.Add (evt);
+                               DbgEvent evt = addEventInternal (evtType, data);
                                if (!startedEvents.ContainsKey (Thread.CurrentThread.ManagedThreadId))
                                        startedEvents [Thread.CurrentThread.ManagedThreadId] = new Stack<DbgEvent> ();
                                startedEvents [Thread.CurrentThread.ManagedThreadId].Push (evt);
@@ -156,7 +133,7 @@ namespace Crow
                                DbgEvent e = startedEvents [Thread.CurrentThread.ManagedThreadId].Pop ();
                                if (e.type != evtType)
                                        throw new Exception ($"Begin/end event logging mismatch: {e.type}/{evtType}");
-                               if (discardIfNoChildEvents && e.Events.Count == 0)
+                               if (discardIfNoChildEvents && (e.Events == null || e.Events.Count == 0))
                                        curEventList.Remove (e);
                                else
                                        e.end = chrono.ElapsedTicks;
@@ -164,40 +141,76 @@ namespace Crow
                                return e;
                        }
                }
-               public static DbgEvent AddEvent (DbgEvtType evtType, object data = null) {
+               /// <summary>
+               /// End event by reference to cancel unended events on failure
+               /// </summary>
+               public static DbgEvent EndEvent (DbgEvtType evtType, DbgEvent evt)
+               {
                        if (!logevt (evtType))
                                return null;
 
                        lock (logMutex) {
                                chrono.Stop ();
-                               DbgEvent evt = new DbgEvent (chrono.ElapsedTicks, evtType, data);
-                               curEventList.Add (evt);
+                               if (!startedEvents.ContainsKey (Thread.CurrentThread.ManagedThreadId))
+                                       throw new Exception ("Current thread has no event started");
+                               DbgEvent e = startedEvents [Thread.CurrentThread.ManagedThreadId].Pop ();
+                               while (e != evt)
+                                       e = startedEvents [Thread.CurrentThread.ManagedThreadId].Pop ();
+                               e.end = chrono.ElapsedTicks;
+                               chrono.Start ();
+                               return e;
+                       }
+               }
+
+               public static DbgEvent AddEvent (DbgEvtType evtType, params object [] data) { 
+                       if (!logevt (evtType))
+                               return null;
+
+                       lock (logMutex) {
+                               chrono.Stop ();
+                               DbgEvent evt = addEventInternal (evtType, data);
                                chrono.Start ();
                                return evt;
                        }
                }
 
-               static int y, level;
+               static DbgEvent addEventInternal (DbgEvtType evtType, params object [] data)
+               {
+                       DbgEvent evt = null;
+                       if (data == null || data.Length == 0)
+                               evt = new DbgEvent (chrono.ElapsedTicks, evtType);
+                       else if (data [0] is Widget w)
+                               evt = new DbgWidgetEvent (chrono.ElapsedTicks, evtType, w);
+                       else if (data [0] is LayoutingQueueItem lqi)
+                               evt = new DbgLayoutEvent (chrono.ElapsedTicks, evtType, lqi);
+                       else
+                               evt = new DbgEvent (chrono.ElapsedTicks, evtType);
+
+                       curEventList.Add (evt);
+                       return evt;
+               }
 
-               static void parseTree (Widget go) {
+               static void parseTree (Widget go, int level = 0, int y = 1) {
                        if (go == null)
                                return;
 
-                       go.yIndex = y++;
-                       go.xLevel = level++;
+                       go.yIndex = y;
+                       go.xLevel = level;
 
                        Group gr = go as Group;
                        if (gr != null) {
-                               foreach (Widget g in gr.Children) {
-                                       parseTree (g);
-                               }
+                               foreach (Widget g in gr.Children) 
+                                       parseTree (g, level + 1, y + 1);
+
                        } else {
                                PrivateContainer pc = go as PrivateContainer;
                                if (pc != null)
-                                       parseTree (pc.getTemplateRoot);                         
+                                       parseTree (pc.getTemplateRoot, level + 1, y + 1);                               
                        }
-                       level--;                
                }
+               /// <summary>
+               /// Clear all recorded events from logger.
+               /// </summary>
                public static void Reset ()
                {
                        lock (logMutex) {
@@ -206,21 +219,23 @@ namespace Crow
                                chrono.Restart ();
                        }
                }
-               public static void save(Interface iface) {
+               /// <summary>
+               /// Save recorded events to disk
+               /// </summary>
+               /// <param name="iface">Iface.</param>
+               public static void save(Interface iface, string dbgLogFilePath = "debug.log") {
                        lock (logMutex) {
-                               y = 1;
-                               level = 0;
 
                                foreach (Widget go in iface.GraphicTree)
                                        parseTree (go);
 
-                               using (StreamWriter s = new StreamWriter ("debug.log")) {
+                               using (StreamWriter s = new StreamWriter (dbgLogFilePath)) {
                                        s.WriteLine ("[GraphicObjects]");
                                        lock (Widget.GraphicObjects) {
-                                               Widget.GraphicObjects = Widget.GraphicObjects.OrderBy (o => o.yIndex).ToList ();
+                                               //Widget.GraphicObjects = Widget.GraphicObjects.OrderBy (o => o.yIndex).ToList ();
                                                for (int i = 0; i < Widget.GraphicObjects.Count; i++) {
                                                        Widget g = Widget.GraphicObjects [i];
-                                                       s.WriteLine ("{0};{1};{2};{3}", i, g.GetType ().Name, g.yIndex, g.xLevel);
+                                                       s.WriteLine ($"{g.GetType ().Name};{g.yIndex};{g.xLevel}");
                                                }
                                        }
                                        s.WriteLine ("[Events]");
@@ -229,17 +244,19 @@ namespace Crow
                        }
                }
 
-               static void saveEventList (StreamWriter s, List<DbgEvent> events, int level = 0)
+               static void saveEventList (StreamWriter s, List<DbgEvent> evts, int level = 0)
                {
-                       foreach (DbgEvent e in events) {
+                       foreach (DbgEvent e in evts) {
                                if (e == null)
                                        continue;
-                               s.WriteLine (new string ('\t', level) + e.ToString ());
-                               saveEventList (s, e.Events, level + 1);
+                               s.WriteLine (new string ('\t', level) + e);
+                               if (e.Events != null)
+                                       saveEventList (s, e.Events, level + 1);
                        }
                }
 
        }
-}
 #endif
+}
+
 
index 02147b6208a191f8c2a99d3a841ba3e576a76cce..16f6c35e33dc69b414baa9dcadd7163899da52db 100644 (file)
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <HorizontalStack>
-       <TreeView Width="20%" Data="{../dbv.Events}"> 
-               <ItemTemplate Data="events">
-                       <Expandable Caption="{type}" MouseDoubleClick="/onClickForExpand" CacheEnabled="true">
+       <TreeView Width="20%" Data="{../dbv.Events}" SelectedItemChanged="onSelectedItemChanged"
+               <ItemTemplate Data="Events">
+                       <Expandable Caption="{type}" MouseDoubleClick="/onClickForExpand" CacheEnabled="true" IsExpanded="{²IsExpanded}">
                                <Template>
                                        <VerticalStack>
                                                <Border CornerRadius="2" Margin="0" Height="Fit" MouseDoubleClick="./onClickForExpand"
                                                                        MouseLeave="{Background=Transparent}"/>
                                                                <Label Text="{./Caption}" Width="80" Font="mono, 8" />
                                                                <Label Text="{Duration}" Width="40" Font="mono, 8" TextAlignment="Center" Background="DimGrey"/>
-                                                               <Group Height="5">
-                                                                       <DbgEventWidget Event="{}" />
-                                                               </Group>
+                                                               <DbgEventWidget Event="{}" Tooltip="{/HoverEvent}" TicksPerPixel="200" Width="Fit" Height="5"/>
+                                                       </HorizontalStack>
+                                               </Border>
+                                               <Container Name="Content" Visible="false"/>
+                                       </VerticalStack>
+                               </Template>
+                               <HorizontalStack Height="Fit">
+                                       <Widget Width="12" Height="10"/>
+                                       <VerticalStack Height="Fit" Name="ItemsContainer"/>
+                               </HorizontalStack>
+                       </Expandable>
+               </ItemTemplate>         
+               <ItemTemplate Data="Events" DataType="DbgWidgetEvent">
+                       <Expandable Caption="{type}" MouseDoubleClick="/onClickForExpand" CacheEnabled="true" IsExpanded="{²IsExpanded}">
+                               <Template>
+                                       <VerticalStack>
+                                               <Border CornerRadius="2" Margin="0" Height="Fit" MouseDoubleClick="./onClickForExpand"
+                                                               Foreground="Transparent"
+                                                               MouseEnter="{Foreground=DimGrey}"
+                                                               MouseLeave="{Foreground=Transparent}">
+                                                       <HorizontalStack Spacing="2" Background="Onyx">
+                                                               <Image Margin="1" Width="9" Height="9" Focusable="true" MouseDown="./onClickForExpand"
+                                                                       Path="{./Image}"
+                                                                       Visible="{HasChildEvents}"
+                                                                       SvgSub="{./IsExpanded}"
+                                                                       MouseEnter="{Background=LightGrey}"
+                                                                       MouseLeave="{Background=Transparent}"/>
+                                                               <Label Text="{./Caption}" Width="80" Font="mono, 8" />
+                                                               <Label Text="{Duration}" Width="40" Font="mono, 8" TextAlignment="Center" Background="DimGrey"/>
+                                                               <Label Text="{InstanceIndex}" Width="40" Font="mono, 8" TextAlignment="Center" Background="DimGrey"/>
+                                                               <DbgEventWidget Event="{}" Tooltip="{/HoverEvent}" TicksPerPixel="200" Width="Fit" Height="5"/>
                                                        </HorizontalStack>
                                                </Border>
                                                <Container Name="Content" Visible="false"/>
@@ -35,8 +63,8 @@
        </TreeView>
        <Splitter/>
        <VerticalStack>
-               <DbgLogViewer Visible="false" Name="dbv" LogFile="debug.log" MouseWheelSpeed="10" Font="mono, 8"/>
-               <!--<ScrollBar Style="HScrollBar" Maximum="{../dbv.MaxScrollX}" Value="{²../dbv.ScrollX}"/>
+               <DbgLogViewer Visible="true" Name="dbv" LogFile="debug.log" MouseWheelSpeed="10" Font="mono, 8"/>
+               <ScrollBar Style="HScrollBar" Maximum="{../dbv.MaxScrollX}" Value="{²../dbv.ScrollX}"/>
                <HorizontalStack Height="Fit" DataSource="{../../dbv.CurrentWidget}">
                        <Label Text="{name}"/>
                        <Label Text="{listIndex}"/>
                        <Label Text="{yIndex}"/>
                        <Label Text="{xLevel}"/>
                </HorizontalStack>
-               <DbgEventWidget Height="20" Width="Stretched" Event="{../../dbv.CurrentEvent}"/>
+               <ListBox Data="{RootEvents}" Height="100" DataSource="{../../dbv.CurrentWidget}">
+                       <ItemTemplate>
+                               <DbgEventWidget Height="10" Width="Fit" Event="{}" Tooltip="{/HoverEvent}" TicksPerPixel="100"/>
+                       </ItemTemplate>
+                       <Template>
+                               <Wrapper Name="ItemsContainer" Spacing="2" Background="DarkGrey"/>
+                       </Template>
+               </ListBox>      
+               <!--<DbgEventWidget Height="20" Width="Stretched" Event="{../../dbv.CurrentEvent}"/>-->
                <VerticalStack DataSource="{../../dbv.CurrentEvent}">
                        <HorizontalStack>
                                <Label Text="{type}"/>
@@ -58,6 +94,6 @@
                                        <DbgEventWidget Height="20" Width="Stretched" Event="{}"/>
                                </ItemTemplate>
                        </ListBox>
-               </VerticalStack>-->
+               </VerticalStack>
        </VerticalStack>
 </HorizontalStack>
\ No newline at end of file
diff --git a/Samples/common/ui/Interfaces/TemplatedContainer/win0.crow b/Samples/common/ui/Interfaces/TemplatedContainer/win0.crow
new file mode 100644 (file)
index 0000000..3b08653
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<Window Width="400" Height="240">
+       <Template>
+               <Group >
+                       <Shape StrokeWidth="1" Foreground="0.1,0.3,0.7,0.7" KeepProportions="false" Size="100,60" Path="M 5.5,15 L 15,5 L 95.5,5.5 L 95.5,50 L 70,55.5 L 5.5,55.5 Z g O 1,1,1,1 S 0.25 G"/>
+
+               </Group>
+       </Template>
+</Window>
\ No newline at end of file
index f47e7aa0362c994553fd149e33b418ba216717d3..c74bcedd031abc9ba11390d523b8026e118ac73b 100644 (file)
@@ -1,9 +1,31 @@
 <?xml version="1.0"?>
 <Menu>
-       <MenuItem Caption="File">
-               <MenuItem Caption="New"/>
-               <MenuItem Caption="Open"/>
-               <MenuItem Caption="Save"/>
-               <MenuItem Caption="Quit"/>
-       </MenuItem>
+       <MenuItem Caption="File" Fit="true">
+               <MenuItem Caption="New">
+                       <Template>
+<Popper Font="{./Font}" Caption="{./Caption}"  Background="{./Background}" PopDirection="{./PopDirection}"
+       Foreground = "{./Foreground}" CanPop="{./HasChildren}"
+       IsPopped="{²./IsOpened}" PopWidth="{./PopWidth}" PopHeight="{./PopHeight}">
+       <Template>
+               <CheckBox IsChecked="{²./IsPopped}" Caption="{./Caption}" Background="{./Background}" Foreground="{./Foreground}">
+                       <Template>              
+                               <Border Name="border1"
+                                               MinimumSize = "60,0"
+                                               Foreground="Transparent"
+                                               Background="{./Background}">
+                                               <Label Text="{./Caption}"
+                                                       Foreground="{./Foreground}"
+                                                       Margin="2" HorizontalAlignment="Left"
+                                                       Font="{./Font}" />
+                               </Border>
+                       </Template>             
+               </CheckBox>
+       </Template>
+       <Border Foreground="DimGrey" Width="{../PopWidth}" Height="{../PopHeight}" Background="${MenuBackground}">
+               <VerticalStack Name="ItemsContainer"/>
+       </Border>
+</Popper>
+                       </Template>
+               </MenuItem>
+       </MenuItem>     
 </Menu>
diff --git a/Samples/common/ui/Interfaces/TemplatedGroup/11.crow b/Samples/common/ui/Interfaces/TemplatedGroup/11.crow
new file mode 100644 (file)
index 0000000..6e58800
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<Menu>
+       <MenuItem Caption="File" >
+               <MenuItem Caption="New">
+                       <Template>
+                               <Popper Font="{./Font}" Caption="{./Caption}"  Background="{./Background}" PopDirection="{./PopDirection}"
+                                       Foreground = "{./Foreground}" CanPop="{./HasChildren}"
+                                       IsPopped="{²./IsOpened}" PopWidth="{./PopWidth}" PopHeight="{./PopHeight}">
+                                       <Template>
+                                               <CheckBox IsChecked="{²./IsPopped}" Caption="{./Caption}" Background="{./Background}" Foreground="{./Foreground}">
+                                                       <Template>              
+                                                               <Label Text="{./Caption}"
+                                                                       Foreground="{./Foreground}"
+                                                                       Margin="2" HorizontalAlignment="Left"
+                                                                       Font="{./Font}" />
+                                                       </Template>             
+                                               </CheckBox>
+                                       </Template>
+                                       <Border Foreground="DimGrey" Height="{../PopHeight}" Background="FireBrick" Margin="3">
+                                               <VerticalStack Name="ItemsContainer"/>
+                                       </Border>
+                               </Popper>
+                       </Template>
+               </MenuItem>
+       </MenuItem>     
+</Menu>
index c2192a9b035e6a3375e128f76e665b5402268f0e..a9bf578934e731c979f32e700e8fe9c75ddfee57 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<VerticalStack Width="60%" Height="60%" Spacing="10" Background="DimGrey" Margin="20" ClipToClientRect="false" CornerRadius="10">
+<VerticalStack Width="60%" Height="60%" Spacing="10" Background="DarkGrey" Margin="20" ClipToClientRect="false" CornerRadius="10">
        <Label Background="Jet" Text="{TestList3SelProp1}"/>    
        <ComboBox Data="{TestList3Props1}">             
        </ComboBox>