diff options
| author | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2021-04-15 06:28:27 +0200 |
|---|---|---|
| committer | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2021-04-15 06:28:27 +0200 |
| commit | 412e93ade521562145cf602cd340c4485fa15e37 (patch) | |
| tree | 3f62500e2698bce844937ec36349dc2dc917dd50 /Samples/DebugLogAnalyzer | |
| parent | a08929b22ac6b6371585beec221c3efebc3b8a71 (diff) | |
wip
Diffstat (limited to 'Samples/DebugLogAnalyzer')
| -rw-r--r-- | Samples/DebugLogAnalyzer/DebugLogAnalyzer.csproj | 2 | ||||
| -rw-r--r-- | Samples/DebugLogAnalyzer/src/DbgEventWidget.cs | 12 | ||||
| -rw-r--r-- | Samples/DebugLogAnalyzer/src/DbgLogViewer.cs | 57 | ||||
| -rw-r--r-- | Samples/DebugLogAnalyzer/src/DebugInterfaceWidget.cs | 131 | ||||
| -rw-r--r-- | Samples/DebugLogAnalyzer/src/Program.cs | 137 | ||||
| -rw-r--r-- | Samples/DebugLogAnalyzer/ui/ComboBox.template | 30 | ||||
| -rw-r--r-- | Samples/DebugLogAnalyzer/ui/DbgEventTreeItems.itemp | 2 | ||||
| -rw-r--r-- | Samples/DebugLogAnalyzer/ui/DbgEventView.template | 43 | ||||
| -rw-r--r-- | Samples/DebugLogAnalyzer/ui/DebugLog.crow | 89 | ||||
| -rw-r--r-- | Samples/DebugLogAnalyzer/ui/WidgetRecord.itemp | 11 | ||||
| -rw-r--r-- | Samples/DebugLogAnalyzer/ui/dbg.style | 21 | ||||
| -rw-r--r-- | Samples/DebugLogAnalyzer/ui/dockWindows/winLogGraph.crow | 15 | ||||
| -rw-r--r-- | Samples/DebugLogAnalyzer/ui/main.crow | 12 |
13 files changed, 447 insertions, 115 deletions
diff --git a/Samples/DebugLogAnalyzer/DebugLogAnalyzer.csproj b/Samples/DebugLogAnalyzer/DebugLogAnalyzer.csproj index 057ee24c..54413ba6 100644 --- a/Samples/DebugLogAnalyzer/DebugLogAnalyzer.csproj +++ b/Samples/DebugLogAnalyzer/DebugLogAnalyzer.csproj @@ -7,7 +7,7 @@ <Compile Include="src\**\*.cs"/> </ItemGroup> <ItemGroup> - <EmbeddedResource Include="ui\*.*"> + <EmbeddedResource Include="ui\**\*.*"> <LogicalName>Dbg.%(Filename)%(Extension)</LogicalName> </EmbeddedResource> </ItemGroup> diff --git a/Samples/DebugLogAnalyzer/src/DbgEventWidget.cs b/Samples/DebugLogAnalyzer/src/DbgEventWidget.cs index 19666ee2..6af3f6df 100644 --- a/Samples/DebugLogAnalyzer/src/DbgEventWidget.cs +++ b/Samples/DebugLogAnalyzer/src/DbgEventWidget.cs @@ -10,6 +10,18 @@ using DebugLogAnalyzer; namespace Crow { + public class DbgEventView : TemplatedContainer { + DbgEvent evt; + public DbgEvent Event { + get => evt; + set { + if (evt == value) + return; + evt = value; + NotifyValueChangedAuto (evt); + } + } + } public class DbgEventWidget : Widget { public DbgEventWidget (){} diff --git a/Samples/DebugLogAnalyzer/src/DbgLogViewer.cs b/Samples/DebugLogAnalyzer/src/DbgLogViewer.cs index 1273c9e6..d39cc62a 100644 --- a/Samples/DebugLogAnalyzer/src/DbgLogViewer.cs +++ b/Samples/DebugLogAnalyzer/src/DbgLogViewer.cs @@ -300,7 +300,7 @@ namespace Crow double penX = 5.0 * g.xLevel + cb.Left; - if (g.yIndex == 0) + if (g.xLevel == 0) gr.SetSource (Crow.Colors.LightSalmon); else if (currentLine == g.listIndex) gr.SetSource(Colors.RoyalBlue); @@ -434,11 +434,17 @@ namespace Crow ctxR.Width = Math.Max (1, ctxR.Width); ctx.Rectangle (ctxR); - //ctx.SetSourceColor (Color.LightYellow); - ctx.SetSource (Colors.Jet); + ctx.SetSource (0.0,0.2,0.8,0.15); + //ctx.SetSource (Colors.Jet); ctx.Fill(); ctx.Operator = Cairo.Operator.Over; + str = $"{ticksToMS(Math.Abs (selEnd - selStart))} (ms)"; + + ctx.MoveTo (ctxR.Center.X - ctx.TextExtents (str).Width / 2, ctxR.Y + fe.Height); + ctx.SetSource (Colors.Black); + ctx.ShowText (str); + } public override void OnLayoutChanges (LayoutingType layoutType) { @@ -469,7 +475,7 @@ namespace Crow int lastLine = hoverLine; updateMouseLocalPos (e.Position); - if (IFace.IsDown (Glfw.MouseButton.Left) && selStart >= 0) + if ((IFace.IsDown (Glfw.MouseButton.Left) || IFace.IsDown (Glfw.MouseButton.Middle)) && selStart >= 0) selEnd = hoverTick; else if (IFace.IsDown(Glfw.MouseButton.Right)) { if (lastTick >= 0 && hoverTick >= 0) @@ -479,28 +485,30 @@ namespace Crow updateMouseLocalPos (e.Position); } else { HoverWidget = (hoverLine < 0 || hoverLine >= widgets.Count) ? null : widgets [hoverLine]; - HoverEvent = hoverWidget?.Events.FirstOrDefault (ev => ev.begin <= hoverTick && ev.end >= hoverTick); - Task.Run (() => findHoverEvent (hoverWidget, hoverTick)); + //HoverEvent = hoverWidget?.Events.FirstOrDefault (ev => ev.begin <= hoverTick && ev.end >= hoverTick); + double tickPerPixel = (double)visibleTicks / ClientRectangle.Width; + //Console.WriteLine ($"ticks per pixel: {tickPerPixel}"); + Task.Run (() => findHoverEvent (hoverWidget, hoverTick, (int)tickPerPixel)); } RegisterForRepaint(); e.Handled = true; base.onMouseMove (sender, e); - } - void findHoverEvent (DbgWidgetRecord widget, long tick) { - DbgEvent tmp = widget?.Events.FirstOrDefault (ev => ev.begin <= tick && ev.end >= tick); + } + void findHoverEvent (DbgWidgetRecord widget, long tick, long precision = 0) { + DbgEvent tmp = widget?.Events.FirstOrDefault (ev => ev.begin - precision <= tick && ev.end + precision >= tick); if (tmp == null) { - tmp = Events.Where(e=>e.type.HasFlag(DbgEvtType.IFace)).Where (ev => ev.begin <= tick && ev.end >= tick).FirstOrDefault(); + tmp = Events.Where(e=>e.type.HasFlag(DbgEvtType.IFace)).Where (ev => ev.begin - precision <= tick && ev.end + precision >= tick).FirstOrDefault(); while(tmp != null) { - DbgEvent che = tmp.Events?.Where(e=>e.type.HasFlag(DbgEvtType.IFace)).Where (ev => ev.begin <= tick && ev.end >= tick).FirstOrDefault(); + DbgEvent che = tmp.Events?.Where(e=>e.type.HasFlag(DbgEvtType.IFace)).Where (ev => ev.begin - precision <= tick && ev.end + precision >= tick).FirstOrDefault(); if (che == null) break; tmp = che; } } else { while(tmp != null) { - DbgEvent che = tmp.Events?.OfType<DbgWidgetEvent>()?.Where(ev=>ev.InstanceIndex == widget.listIndex && ev.begin <= tick && ev.end >= tick).FirstOrDefault(); + DbgEvent che = tmp.Events?.OfType<DbgWidgetEvent>()?.Where(ev=>ev.InstanceIndex == widget.listIndex && ev.begin - precision <= tick && ev.end + precision >= tick).FirstOrDefault(); if (che == null) break; tmp = che; @@ -510,21 +518,23 @@ namespace Crow } public override void onMouseClick(object sender, MouseButtonEventArgs e) { - if (e.Button == Glfw.MouseButton.Left && selEnd < 0) { - currentTick = hoverTick; - currentLine = hoverLine; - CurrentWidget = hoverWidget; - CurrentEvent = hoverEvent; + if (e.Button == Glfw.MouseButton.Left) { + if (selEnd < 0) { + currentTick = hoverTick; + currentLine = hoverLine; + CurrentWidget = hoverWidget; + CurrentEvent = hoverEvent; + } + selStart = -1; + selEnd = -1; } - selStart = -1; - selEnd = -1; e.Handled = true; base.onMouseClick(sender, e); } public override void onMouseDown (object sender, MouseButtonEventArgs e) { - if (e.Button == Glfw.MouseButton.Left) { + if (e.Button == Glfw.MouseButton.Left || e.Button == Glfw.MouseButton.Middle) { selStart = hoverTick; selEnd = -1; } @@ -561,7 +571,9 @@ namespace Crow if (IFace.Shift) ScrollX -= (int)((double)(e.Delta * MouseWheelSpeed) / xScale); - else if (IFace.Ctrl) { + else if (IFace.Ctrl) + ScrollY -= e.Delta * MouseWheelSpeed; + else { if (e.Delta > 0) { XScale *= 2.0; } else { @@ -569,8 +581,7 @@ namespace Crow XScale *= 0.5; } ScrollX = (long)(hoverTick - (long)((double)Math.Max(0, mousePos.X - (long)leftMargin) / xScale) - minTicks); - }else - ScrollY -= e.Delta * MouseWheelSpeed; + } } public override void onKeyDown (object sender, KeyEventArgs e) diff --git a/Samples/DebugLogAnalyzer/src/DebugInterfaceWidget.cs b/Samples/DebugLogAnalyzer/src/DebugInterfaceWidget.cs index 5432b05e..c6920ca5 100644 --- a/Samples/DebugLogAnalyzer/src/DebugInterfaceWidget.cs +++ b/Samples/DebugLogAnalyzer/src/DebugInterfaceWidget.cs @@ -12,6 +12,7 @@ using System.Diagnostics; using CrowDbgShared; using System.Collections.Generic; using Crow.DebugLogger; +using System.Linq; namespace Crow { @@ -27,7 +28,10 @@ namespace Crow Type dbgIfaceType; Action<int, int> delResize; Func<int, int, bool> delMouseMove; + Func<float, bool> delMouseWheelChanged; Func<MouseButton, bool> delMouseDown, delMouseUp; + Func<char, bool> delKeyPress; + Func<Key, bool> delKeyDown, delKeyUp; Action delResetDirtyState; Action delResetDebugger; Action<object, string> delSaveDebugLog; @@ -178,12 +182,24 @@ namespace Crow delMouseMove = (Func<int, int, bool>)Delegate.CreateDelegate(typeof(Func<int, int, bool>), dbgIFace, dbgIfaceType.GetMethod("OnMouseMove")); + delMouseWheelChanged = (Func<float, bool>)Delegate.CreateDelegate(typeof(Func<float, bool>), + dbgIFace, dbgIfaceType.GetMethod("OnMouseWheelChanged")); + + delMouseDown = (Func<MouseButton, bool>)Delegate.CreateDelegate(typeof(Func<MouseButton, bool>), dbgIFace, dbgIfaceType.GetMethod("OnMouseButtonDown")); delMouseUp = (Func<MouseButton, bool>)Delegate.CreateDelegate(typeof(Func<MouseButton, bool>), dbgIFace, dbgIfaceType.GetMethod("OnMouseButtonUp")); + delKeyDown = (Func<Key, bool>)Delegate.CreateDelegate(typeof(Func<Key, bool>), + dbgIFace, dbgIfaceType.GetMethod("OnKeyDown")); + delKeyUp = (Func<Key, bool>)Delegate.CreateDelegate(typeof(Func<Key, bool>), + dbgIFace, dbgIfaceType.GetMethod("OnKeyUp")); + delKeyPress = (Func<char, bool>)Delegate.CreateDelegate(typeof(Func<char, bool>), + dbgIFace, dbgIfaceType.GetMethod("OnKeyPress")); + + delGetSurfacePointer = (IntPtrGetterDelegate)Delegate.CreateDelegate(typeof(IntPtrGetterDelegate), dbgIFace, dbgIfaceType.GetProperty("SurfacePointer").GetGetMethod()); delSetSource = (Action<string>)Delegate.CreateDelegate(typeof(Action<string>), @@ -218,19 +234,60 @@ namespace Crow } public override bool CacheEnabled { get => true; set => base.CacheEnabled = true; } + public override void onKeyDown(object sender, KeyEventArgs e) + { + if (initialized) { + try + { + e.Handled = delKeyDown (e.Key); + } + catch (System.Exception ex) + { + Console.WriteLine($"[Error][DebugIFace key down]{ex}"); + } + } + base.onKeyDown(sender, e); + } + public override void onKeyUp(object sender, KeyEventArgs e) + { + if (initialized) { + try + { + e.Handled = delKeyUp (e.Key); + } + catch (System.Exception ex) + { + Console.WriteLine($"[Error][DebugIFace key up]{ex}"); + } + } + base.onKeyUp(sender, e); + } + public override void onKeyPress(object sender, KeyPressEventArgs e) + { + if (initialized) { + try + { + e.Handled = delKeyPress (e.KeyChar); + } + catch (System.Exception ex) + { + Console.WriteLine($"[Error][DebugIFace key press]{ex}"); + } + } + base.onKeyPress(sender, e); + } public override void onMouseMove(object sender, MouseMoveEventArgs e) { if (initialized) { try { Point m = ScreenPointToLocal (e.Position); - delMouseMove (m.X, m.Y); + e.Handled = delMouseMove (m.X, m.Y); } catch (System.Exception ex) { Console.WriteLine($"[Error][DebugIFace mouse move]{ex}"); - } - e.Handled = true; + } } base.onMouseMove(sender, e); } @@ -239,13 +296,12 @@ namespace Crow if (initialized) { try { - delMouseDown (e.Button); + e.Handled = delMouseDown (e.Button); } catch (System.Exception ex) { Console.WriteLine($"[Error][DebugIFace mouse down]{ex}"); - } - e.Handled=true; + } } base.onMouseDown (sender, e); } @@ -254,16 +310,29 @@ namespace Crow if (initialized) { try { - delMouseUp (e.Button); + e.Handled = delMouseUp (e.Button); } catch (System.Exception ex) { Console.WriteLine($"[Error][DebugIFace mouse up]{ex}"); - } - e.Handled=true; + } } base.onMouseUp (sender, e); } + public override void onMouseWheel(object sender, MouseWheelEventArgs e) + { + if (initialized) { + try + { + e.Handled = delMouseWheelChanged (e.Delta); + } + catch (System.Exception ex) + { + Console.WriteLine($"[Error][DebugIFace mouse wheel change]{ex}"); + } + } + base.onMouseWheel(sender, e); + } protected override void RecreateCache() { @@ -286,22 +355,52 @@ namespace Crow } + int firstWidgetIndexToGet = 0; void getLog () { + DebugLogAnalyzer.Program dla = IFace as DebugLogAnalyzer.Program; + using (Stream stream = new MemoryStream (1024)) { Type debuggerType = crowAssembly.GetType("Crow.DbgLogger"); - debuggerType.GetMethod("Save", new Type[] {dbgIfaceType, typeof(Stream)}).Invoke(null, new object[] {dbgIFace, stream}); + MethodInfo miSave = debuggerType.GetMethod("Save", + new Type[] { + dbgIfaceType, + typeof(Stream), + typeof(int), + typeof(bool) + }); + + + widgets = new List<DbgWidgetRecord>(); + events = new List<DbgEvent>(); + miSave.Invoke(null, new object[] {dbgIFace, stream, firstWidgetIndexToGet, true}); //debuggerType.GetMethod("Save", new Type[] {dbgIfaceType, typeof(string)}).Invoke(null, new object[] {dbgIFace, "debug.log"}); //delSaveDebugLog(dbgIFace, "debug.log"); stream.Seek(0, SeekOrigin.Begin); - events = new List<DbgEvent>(); - widgets = new List<DbgWidgetRecord>(); DbgLogger.Load (stream, events, widgets); - //DbgLogger.Load ("debug.log", events, widgets); - DebugLogAnalyzer.Program dla = IFace as DebugLogAnalyzer.Program; - dla.Widgets = widgets; - dla.Events = events; + + lock (dla.UpdateMutex) { + for (int i = 0; i < widgets.Count; i++) { + widgets[i].listIndex = dla.Widgets.Count; + dla.Widgets.Add (widgets[i]); + } + for (int i = 0; i < events.Count; i++) { + dla.Events.Add (events[i]); + updateWidgetEvents (dla.Widgets, events[i]); + } + } + firstWidgetIndexToGet += widgets.Count; + if (widgets.Count > 0 && firstWidgetIndexToGet != widgets.Last().InstanceIndex + 1) + Debugger.Break (); } } + void updateWidgetEvents (List<DbgWidgetRecord> widgets, DbgEvent evt) { + if (evt is DbgWidgetEvent we) + widgets.FirstOrDefault (w => w.InstanceIndex == we.InstanceIndex)?.Events.Add (we); + if (evt.Events == null) + return; + foreach (DbgEvent e in evt.Events) + updateWidgetEvents (widgets, e); + } public virtual object GetScreenCoordinates () => ScreenCoordinates(Slot).TopLeft; } diff --git a/Samples/DebugLogAnalyzer/src/Program.cs b/Samples/DebugLogAnalyzer/src/Program.cs index 7da9f5a1..a2711dda 100644 --- a/Samples/DebugLogAnalyzer/src/Program.cs +++ b/Samples/DebugLogAnalyzer/src/Program.cs @@ -11,6 +11,7 @@ using Crow.Text; using System.Collections.Generic; using Encoding = System.Text.Encoding; using Crow.DebugLogger; +using System.Linq; namespace DebugLogAnalyzer { @@ -41,7 +42,8 @@ namespace DebugLogAnalyzer /*TreeView tv = FindByName("dbgTV") as TreeView; dbgTreeViewScroller = tv.FindByNameInTemplate ("scroller1") as Scroller;*/ - + if (DebugLogOnStartup) + DebugLogRecording = true; if (!File.Exists (CurrentFile)) newFile (); @@ -50,20 +52,52 @@ namespace DebugLogAnalyzer reloadFromFile (); } + + public override void UpdateFrame() + { + base.UpdateFrame(); + + } + - List<DbgEvent> events = new List<DbgEvent>(); - List<DbgWidgetRecord> widgets = new List<DbgWidgetRecord>(); - DbgEvent curEvent = new DbgEvent(); + ObservableList<DbgEvent> events = new ObservableList<DbgEvent>(); + ObservableList<DbgWidgetRecord> widgets = new ObservableList<DbgWidgetRecord>(); + DbgEvent curEvent; + bool disableCurrentEventHistory; + Stack<DbgEvent> CurrentEventHistoryForward = new Stack<DbgEvent>(); + Stack<DbgEvent> CurrentEventHistoryBackward = new Stack<DbgEvent>(); DbgWidgetRecord curWidget = new DbgWidgetRecord(); bool debugLogRecording; - Scroller dbgTreeViewScroller; int targetTvScroll = -1; + public string[] AllEventTypes => Enum.GetNames (typeof(DbgEvtType)); + string searchEventType; + DbgWidgetRecord searchWidget; + public string SearchEventType { + get => searchEventType; + set { + if (searchEventType == value) + return; + searchEventType = value; + NotifyValueChanged (searchEventType); + } + } + + public DbgWidgetRecord SearchWidget { + get => searchWidget; + set { + if (searchWidget == value) + return; + searchWidget = value; + NotifyValueChanged (searchWidget); + } + } public Command CMDNew, CMDOpen, CMDSave, CMDSaveAs, CMDQuit, CMDShowLeftPane, - CMDUndo, CMDRedo, CMDCut, CMDCopy, CMDPaste, CMDHelp, CMDAbout, CMDOptions; + CMDUndo, CMDRedo, CMDCut, CMDCopy, CMDPaste, CMDHelp, CMDAbout, CMDOptions, + CMDGotoParentEvent, CMDEventHistoryForward, CMDEventHistoryBackward; public CommandGroup EventCommands, DirectoryCommands; public CommandGroup EditorCommands => new CommandGroup (CMDUndo, CMDRedo, CMDCut, CMDCopy, CMDPaste, CMDSave, CMDSaveAs); void initCommands () @@ -78,8 +112,12 @@ namespace DebugLogAnalyzer CMDCopy = new Command ("Copy", new Action (() => copy ()), "#Icons.copy-file.svg", false); CMDPaste= new Command ("Paste", new Action (() => paste ()), "#Icons.paste-on-document.svg", false); + CMDGotoParentEvent = new Command("parent", ()=> { CurrentEvent = CurrentEvent?.parentEvent; }, null, false); + CMDEventHistoryBackward = new Command("back.", currentEventHistoryGoBack, null, false); + CMDEventHistoryForward = new Command("forw.", currentEventHistoryGoForward, null, false); + EventCommands = new CommandGroup( - new Command("Goto parent event", ()=> { CurrentEvent = CurrentEvent?.parentEvent; }) + CMDGotoParentEvent, CMDEventHistoryBackward, CMDEventHistoryForward ); DirectoryCommands = new CommandGroup( new Command("Set as root directory", ()=> { CurrentEvent = CurrentEvent?.parentEvent; }) @@ -100,7 +138,7 @@ namespace DebugLogAnalyzer NotifyValueChanged(CrowDbgAssemblyLocation); } } - public List<DbgEvent> Events { + public ObservableList<DbgEvent> Events { get => events; set { if (events == value) @@ -109,7 +147,7 @@ namespace DebugLogAnalyzer NotifyValueChanged (nameof (Events), events); } } - public List<DbgWidgetRecord> Widgets { + public ObservableList<DbgWidgetRecord> Widgets { get => widgets; set { if (widgets == value) @@ -118,18 +156,83 @@ namespace DebugLogAnalyzer NotifyValueChanged (nameof (Widgets), widgets); } } + /*IEnumerable<DbgWidgetEvent> widgetEvents (DbgWidgetRecord wr, DbgEvent evt) { + if (evt is DbgWidgetEvent we && we.InstanceIndex == wr.InstanceIndex) + yield return we; + if (evt.Events != null) { + foreach (DbgEvent e in evt.Events) + foreach (DbgWidgetEvent ye in widgetEvents (wr, e)) + yield return ye; + } + } + IEnumerable<DbgWidgetEvent> currentWidgetEvents; + + public IEnumerable<DbgWidgetEvent> CurrentWidgetEvents { + get => currentWidgetEvents; + set { + currentWidgetEvents = value; + NotifyValueChanged (currentWidgetEvents); + curWidget.Events = new List<DbgEvent> (currentWidgetEvents); + } + } + IEnumerable<DbgWidgetEvent> getCurrentWidgetEvents () { + if (CurrentWidget == null) + yield return null; + else { + foreach (DbgEvent evt in Events) + foreach (DbgWidgetEvent dwe in widgetEvents (CurrentWidget, evt)) + yield return dwe; + } + }*/ + + public DbgEvent CurrentEvent { get => curEvent; set { if (curEvent == value) return; + + if (!disableCurrentEventHistory) { + CurrentEventHistoryForward.Clear (); + CMDEventHistoryForward.CanExecute = false; + if (!(value == null || curEvent == null)) { + CurrentEventHistoryBackward.Push (curEvent); + CMDEventHistoryBackward.CanExecute = true; + } + } curEvent = value; + NotifyValueChanged (nameof (CurrentEvent), curEvent); NotifyValueChanged ("CurEventChildEvents", curEvent?.Events); - + if (CurrentEvent != null && CurrentEvent.parentEvent != null) + CMDGotoParentEvent.CanExecute = true; + else + CMDGotoParentEvent.CanExecute = false; + } + } + void currentEventHistoryGoBack () { + disableCurrentEventHistory = true; + if (CurrentEvent != null) { + CurrentEventHistoryForward.Push (CurrentEvent); + CMDEventHistoryForward.CanExecute = true; } + CurrentEvent = CurrentEventHistoryBackward.Pop (); + CMDEventHistoryBackward.CanExecute = CurrentEventHistoryBackward.Count > 0; + + disableCurrentEventHistory = false; + } + + void currentEventHistoryGoForward () { + disableCurrentEventHistory = true; + CurrentEventHistoryBackward.Push (CurrentEvent); + CMDEventHistoryBackward.CanExecute = true; + CurrentEvent = CurrentEventHistoryForward.Pop (); + CMDEventHistoryForward.CanExecute = CurrentEventHistoryForward.Count > 0; + + disableCurrentEventHistory = false; } + public DbgWidgetRecord CurrentWidget { get => curWidget; set { @@ -138,8 +241,7 @@ namespace DebugLogAnalyzer curWidget = value; NotifyValueChanged (nameof (CurrentWidget), curWidget); NotifyValueChanged ("CurWidgetRootEvents", curWidget?.RootEvents); - NotifyValueChanged ("CurWidgetEvents", curWidget?.Events); - + NotifyValueChanged ("CurrentWidgetEvents", curWidget?.Events); } } public List<DbgWidgetEvent> CurWidgetRootEvents => curWidget == null? new List<DbgWidgetEvent>() : curWidget.RootEvents; @@ -192,7 +294,16 @@ namespace DebugLogAnalyzer debugLogRecording = value; NotifyValueChanged(debugLogRecording); } - } + } + public bool DebugLogOnStartup { + get => Configuration.Global.Get<bool> (nameof(DebugLogOnStartup)); + set { + if (DbgLogger.ConsoleOutput != value) + return; + Configuration.Global.Set (nameof(DebugLogOnStartup), value); + NotifyValueChanged(DebugLogOnStartup); + } + } const string _defaultFileName = "unnamed.txt"; diff --git a/Samples/DebugLogAnalyzer/ui/ComboBox.template b/Samples/DebugLogAnalyzer/ui/ComboBox.template new file mode 100644 index 00000000..1b8e439c --- /dev/null +++ b/Samples/DebugLogAnalyzer/ui/ComboBox.template @@ -0,0 +1,30 @@ +<?xml version="1.0"?> +<HorizontalStack Spacing="5" Background="{./Background}"> + <Label Text="{./Caption}"/> + <Popper Caption="{./SelectedItem}" Name="popper" PopDirection="Bottom" Foreground="{./Foreground}" Background="{./Background}"> + <Template> + <CheckBox Caption="{./Caption}" IsChecked="{²./IsPopped}" Foreground="{./Foreground}" Background="{./Background}"> + <Template> + <Border Style="ControlBorder" Background="{./Background}"> + <HorizontalStack Margin="0" Spacing="1"> + <TextBox Style="ControlEditableText" Text="{./Caption}"/> + <Shape Style="ArrowBut" MouseDown="./onScrollForth" Width="10" Height="Stretched" + Size="10,10" Path="M 0.5,0.5 L 9.5,0.5 L 4.5,9.5 Z F"/> + </HorizontalStack> + </Border> + </Template> + </CheckBox> + </Template> + <Border Background="Onyx" Foreground="DimGrey" BorderWidth="1" Margin="1" Height="Fit" Width="Fit" + MinimumSize="{../../MinimumPopupSize}" > + <Scroller Name="scroller1" Margin="1" + MaximumSize="0,200" + HorizontalAlignment="Left"> + <VerticalStack + Height="Fit" Name="ItemsContainer" Margin="0" + HorizontalAlignment="Left" + VerticalAlignment="Top"/> + </Scroller> + </Border> + </Popper> +</HorizontalStack> diff --git a/Samples/DebugLogAnalyzer/ui/DbgEventTreeItems.itemp b/Samples/DebugLogAnalyzer/ui/DbgEventTreeItems.itemp index 96de2dc6..0dd44c74 100644 --- a/Samples/DebugLogAnalyzer/ui/DbgEventTreeItems.itemp +++ b/Samples/DebugLogAnalyzer/ui/DbgEventTreeItems.itemp @@ -19,7 +19,7 @@ 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="{DurationMS}" Width="40" Font="mono, 8" TextAlignment="Center" Background="DimGrey"/> <DbgEventWidget Event="{}" Tooltip="#Dbg.DbgEvtTooltip.crow" Width="Stretched" Height="5"/> </HorizontalStack> </Border> diff --git a/Samples/DebugLogAnalyzer/ui/DbgEventView.template b/Samples/DebugLogAnalyzer/ui/DbgEventView.template new file mode 100644 index 00000000..6679f150 --- /dev/null +++ b/Samples/DebugLogAnalyzer/ui/DbgEventView.template @@ -0,0 +1,43 @@ +<?xml version="1.0"?> +<VerticalStack Margin="${TooltipMargin}" DataSource="{./Event}"> + <Label Text="{type}" Background="{Color}" Foreground="Black" Width="200" TextAlignment="Center" Margin="6"/> + <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Visible="{IsWidgetEvent}" Background="DimGrey" Margin="2"> + <Label Text="Instance:" Foreground="White" Width="50%" /> + <Label Text="{InstanceIndex}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/> + </HorizontalStack> + <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2"> + <Label Text="Duration(ms):" Foreground="White" Width="50%" /> + <Label Text="{DurationMS}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Right"/> + </HorizontalStack> + <HorizontalStack Height="Fit" Width="Stretched" Spacing="2"> + <Label Text="Begin(s):" Foreground="${TooltipForeground}" Width="50%"/> + <Label Text="{BeginMS}" Foreground="${TooltipForeground}" Width="Stretched" TextAlignment="Right"/> + </HorizontalStack> + <HorizontalStack Height="Fit" Width="Stretched" Spacing="2"> + <Label Text="End(s):" Foreground="${TooltipForeground}" Width="50%"/> + <Label Text="{EndMS}" Foreground="${TooltipForeground}" Width="Stretched" TextAlignment="Right"/> + </HorizontalStack> + <VerticalStack Height="Fit" Width="Stretched" IsVisible="{IsLayoutEvent}" > + <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2"> + <Label Text="Layout:" Foreground="White" Width="50%" /> + <Label Text="{layouting}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/> + </HorizontalStack> + <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2"> + <Label Text="Result:" Foreground="White" Width="50%" /> + <Label Text="{result}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/> + </HorizontalStack> + <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2"> + <Label Text="Old Slot:" Foreground="White" Width="50%" /> + <Label Text="{OldSlot}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/> + </HorizontalStack> + <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2"> + <Label Text="New Slot:" Foreground="White" Width="50%" /> + <Label Text="{NewSlot}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/> + </HorizontalStack> + </VerticalStack> + <DbgEventWidget Height="10" Width="Stretched" Event="{}" Tooltip="#Dbg.DbgEvtTooltip.crow" /> + <GroupBox Caption="Parent Event" Height="Fit" > + <DbgEventWidget Height="10" Width="Stretched" Event="{parentEvent}" Tooltip="#Dbg.DbgEvtTooltip.crow" /> + </GroupBox> + <!--<Label Text="{}" Foreground="${TooltipForeground}"/>--> +</VerticalStack>
\ No newline at end of file diff --git a/Samples/DebugLogAnalyzer/ui/DebugLog.crow b/Samples/DebugLogAnalyzer/ui/DebugLog.crow index 26839642..2b5ab978 100644 --- a/Samples/DebugLogAnalyzer/ui/DebugLog.crow +++ b/Samples/DebugLogAnalyzer/ui/DebugLog.crow @@ -6,8 +6,8 @@ <EnumSelector RadioButtonStyle="CheckBox2" Template="#Dbg.EnumSelector.template" Caption="Discarded Events" EnumValue="{²../dbv.Filter}" BitFieldExcludeMask="255" /> <HorizontalStack> - <DbgLogViewer Visible="true" Name="dbv" Events="{Events}" Widgets="{Widgets}" MouseWheelSpeed="3" Font="mono, 8" - CurrentEvent="{²CurrentEvent}" CurrentWidget="{²CurrentWidget}" Background="Onyx"/> + <DbgLogViewer Visible="true" Name="dbv" Events="{Events}" Widgets="{Widgets}" + CurrentEvent="{²CurrentEvent}" CurrentWidget="{²CurrentWidget}" /> <ScrollBar Maximum="{../dbv.MaxScrollY}" Value="{²../dbv.ScrollY}" SmallIncrement="1" LargeIncrement="10" CursorRatio="{../dbv.ChildHeightRatio}"/> </HorizontalStack> @@ -15,10 +15,10 @@ CursorRatio="{../dbv.ChildWidthRatio}"/> <HorizontalStack Height="Fit" DataSource="{CurrentWidget}" Spacing="3"> <Label Style="smallLabValue" Text="{name}"/> - <Label Style="smallLabValue" Text="{listIndex}"/> - <Label Style="smallLabValue" Text="{treeIndex}"/> - <Label Style="smallLabValue" Text="{yIndex}"/> - <Label Style="smallLabValue" Text="{xLevel}"/> + <Label Style="smallLabValue" Text="{listIndex}" Tooltip="List index"/> + <Label Style="smallLabValue" Text="{treeIndex}" Tooltip="tree index"/> + <Label Style="smallLabValue" Text="{yIndex}" Tooltip="yIndex"/> + <Label Style="smallLabValue" Text="{xLevel}" Tooltip="xLevel"/> <Label Style="smallLabCaption" Text="Width:"/> <Label Style="smallLabValue" Text="{Width}"/> <Label Style="smallLabCaption" Text="Height:" /> @@ -31,7 +31,7 @@ <Label Style="smallLabValue" Tooltip="VisibleTicks" Text="{../../dbv.VisibleTicks}"/> </HorizontalStack> </VerticalStack> - <VerticalStack Name="AllEvents" Width="Stretched" IsVisible="false"> + <!--<VerticalStack Name="AllEvents" Width="Stretched" IsVisible="false"> <TreeView Height="Stretched" Name="dbgTV" Data="{Events}" SelectedItem="{²CurrentEvent}" Background="DarkGrey" ItemTemplate="#Dbg.DbgEventTreeItems.itemp"/> <ListBox Data="{CurWidgetEvents}" Height="100" SelectedItem="{²CurrentEvent}"> @@ -48,15 +48,14 @@ </ListBox> </VerticalStack> <VerticalStack Name="CurWidgetEvents" Width="Stretched" IsVisible="false"> - <TreeView Height="Stretched" Data="{CurWidgetEvents}" SelectedItem="{²CurrentEvent}" Background="DarkGrey" + <TreeView Height="Stretched" Data="{CurrentWidgetEvents}" Background="DarkGrey" ItemTemplate="#Dbg.DbgEventTreeItems.itemp"/> - </VerticalStack> + </VerticalStack>--> </TabView> <Splitter/> <HorizontalStack Height="30%"> - <ListBox Data="{Widgets}" Width="50%" SelectedItem="{²CurrentWidget}"> - <Template> - </Template> + <ListBox Data="{Widgets}" Width="200" SelectedItem="{²CurrentWidget}" + ItemTemplate="#Dbg.WidgetRecord.itemp"> </ListBox> <Splitter/> <VerticalStack> @@ -64,12 +63,12 @@ <Label Text="{CurrentWidget}"/> <Label Text="events"/> </HorizontalStack> - <ListBox Data="{CurWidgetEvents}" Background="Black" SelectedItem="{²CurrentEvent}"> + <ListBox Data="{CurrentWidgetEvents}" Background="Black" SelectedItem="{²CurrentEvent}"> <ItemTemplate> <ListItem Margin="0" Height="16" IsSelected="{²IsSelected}" Width="Fit" - Selected="{Background=${ControlHighlight}}" + Selected="{Background=${ControlHighlight}}" Template="Crow.ScrollingListBox.template" Unselected="{Background=Transparent}"> - <DbgEventWidget Height="10" Width="Fit" Event="{}" Tooltip="#Dbg.DbgEvtTooltip.crow" TicksPerPixel="300" VerticalAlignment="Center"/> + <DbgEventWidget Height="10" Width="Fit" Event="{}" Tooltip="#Dbg.DbgEvtTooltip.crow" TicksPerPixel="50" VerticalAlignment="Center"/> </ListItem> </ItemTemplate> <Template> @@ -80,48 +79,26 @@ ItemTemplate="#Dbg.DbgEventTreeItems.itemp"/>--> </VerticalStack> <Splitter/> - <VerticalStack Height="Stretched" Width="20%" Margin="${TooltipMargin}" DataSource="{CurrentEvent}"> - <Label Text="{type}" Background="{Color}" Foreground="Black" Width="200" TextAlignment="Center" Margin="6"/> - <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Visible="{IsWidgetEvent}" Background="DimGrey" Margin="2"> - <Label Text="Instance:" Foreground="White" Width="50%" /> - <Label Text="{InstanceIndex}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/> - </HorizontalStack> - <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2"> - <Label Text="Duration:" Foreground="White" Width="50%" /> - <Label Text="{DurationMS}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Right"/> - </HorizontalStack> - <HorizontalStack Height="Fit" Width="Stretched" Spacing="2"> - <Label Text="Begin:" Foreground="${TooltipForeground}" Width="50%"/> - <Label Text="{BeginMS}" Foreground="${TooltipForeground}" Width="Stretched" TextAlignment="Right"/> - </HorizontalStack> - <HorizontalStack Height="Fit" Width="Stretched" Spacing="2"> - <Label Text="End:" Foreground="${TooltipForeground}" Width="50%"/> - <Label Text="{EndMS}" Foreground="${TooltipForeground}" Width="Stretched" TextAlignment="Right"/> - </HorizontalStack> - <VerticalStack Height="Fit" Width="Stretched" IsVisible="{IsLayoutEvent}" > - <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2"> - <Label Text="Layout:" Foreground="White" Width="50%" /> - <Label Text="{layouting}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/> - </HorizontalStack> - <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2"> - <Label Text="Result:" Foreground="White" Width="50%" /> - <Label Text="{result}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/> - </HorizontalStack> - <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2"> - <Label Text="Old Slot:" Foreground="White" Width="50%" /> - <Label Text="{OldSlot}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/> - </HorizontalStack> - <HorizontalStack Height="Fit" Width="Stretched" Spacing="2" Background="DimGrey" Margin="2"> - <Label Text="New Slot:" Foreground="White" Width="50%" /> - <Label Text="{NewSlot}" Foreground="White" Background="Onyx" Width="Stretched" TextAlignment="Center"/> - </HorizontalStack> + <DbgEventView Template="#Dbg.DbgEventView.template" Event="{../../dbv.HoverEvent}"/> + <Splitter/> + <DbgEventView Template="#Dbg.DbgEventView.template" Event="{CurrentEvent}"/> + </HorizontalStack> + <HorizontalStack Height="Fit" Background="Onyx" Margin="1"> + <HorizontalStack Height="Fit" DataSource="{CurrentEvent}"> + <Label Foreground="Black" Text="Current Event:" Background="{Color}" Margin="2" /> + <DbgEventWidget Height="14" Width="Stretched" Event="{}" Tooltip="#Dbg.DbgEvtTooltip.crow" /> + </HorizontalStack> + <Menu Fit="true" Data="{EventCommands}"> + <ItemTemplate> + <Button Command="{}"/> + </ItemTemplate> + </Menu> + <Popper Caption="Search..."> + <VerticalStack Fit="true" Background="Onyx" Margin="10"> + <ComboBox Caption="Event Type" Data="{AllEventTypes}" SelectedItem="{²SearchEventType}"/> + <ComboBox Caption="Widget" Data="{Widgets}" SelectedItem="{²SearchWidget}"/> </VerticalStack> - <DbgEventWidget Height="10" Width="Stretched" Event="{}" Tooltip="#Dbg.DbgEvtTooltip.crow" /> - <GroupBox Caption="Parent Event" Height="Fit" > - <DbgEventWidget Height="10" Width="Stretched" Event="{parentEvent}" Tooltip="#Dbg.DbgEvtTooltip.crow" /> - </GroupBox> - <!--<Label Text="{}" Foreground="${TooltipForeground}"/>--> - </VerticalStack> + </Popper> </HorizontalStack> </VerticalStack> </Window>
\ No newline at end of file diff --git a/Samples/DebugLogAnalyzer/ui/WidgetRecord.itemp b/Samples/DebugLogAnalyzer/ui/WidgetRecord.itemp new file mode 100644 index 00000000..2b1297d3 --- /dev/null +++ b/Samples/DebugLogAnalyzer/ui/WidgetRecord.itemp @@ -0,0 +1,11 @@ +<ListItem Height="Fit" Margin="1" Focusable="true" HorizontalAlignment="Left" + Selected = "{Background=${ControlHighlight}}" + Unselected = "{Background=Transparent}"> + <HorizontalStack> + <Label Text="{name}" Width="Stretched"/> + <Label Style="labWidgetRecordList" Text="{listIndex}" Tooltip="List index"/> + <Label Style="labWidgetRecordList" Text="{treeIndex}" Tooltip="tree index"/> + <Label Style="labWidgetRecordList" Text="{yIndex}" Tooltip="yIndex"/> + <Label Style="labWidgetRecordList" Text="{xLevel}" Tooltip="xLevel"/> + </HorizontalStack> +</ListItem>
\ No newline at end of file diff --git a/Samples/DebugLogAnalyzer/ui/dbg.style b/Samples/DebugLogAnalyzer/ui/dbg.style index 77772f10..90ec61da 100644 --- a/Samples/DebugLogAnalyzer/ui/dbg.style +++ b/Samples/DebugLogAnalyzer/ui/dbg.style @@ -12,4 +12,25 @@ smallLabCaption { smallLabValue { Font="mono, 10"; Foreground="White"; +} +DbgLogViewer { + MouseWheelSpeed="3"; + Font="mono, 8"; + Background="Onyx"; +} +DbgEventView { + Height="Fit"; + Width="150"; +} +ComboBox { + Template="#Dbg.ComboBox.template"; + Background="Jet"; +} +labWidgetRecordList { + Font="mono, 11"; + Background="Grey"; + Foreground="Jet"; + Margin="0"; + Width="24"; + TextAlignment="Right"; }
\ No newline at end of file diff --git a/Samples/DebugLogAnalyzer/ui/dockWindows/winLogGraph.crow b/Samples/DebugLogAnalyzer/ui/dockWindows/winLogGraph.crow new file mode 100644 index 00000000..7e6a11b8 --- /dev/null +++ b/Samples/DebugLogAnalyzer/ui/dockWindows/winLogGraph.crow @@ -0,0 +1,15 @@ +<?xml version="1.0"?> +<DockWindow Caption="Debug Log" Background="0.05,0.05,0.1,0.9" Width="80%" Height="80%"> + <VerticalStack Name="LogGraph" Background="DarkGrey"> + <EnumSelector RadioButtonStyle="CheckBox2" Template="#Dbg.EnumSelector.template" + Caption="Discarded Events" EnumValue="{²../dbv.Filter}" BitFieldExcludeMask="255" /> + <HorizontalStack> + <DbgLogViewer Visible="true" Name="dbv" Events="{Events}" Widgets="{Widgets}" + CurrentEvent="{²CurrentEvent}" CurrentWidget="{²CurrentWidget}" /> + <ScrollBar Maximum="{../dbv.MaxScrollY}" Value="{²../dbv.ScrollY}" SmallIncrement="1" LargeIncrement="10" + CursorRatio="{../dbv.ChildHeightRatio}"/> + </HorizontalStack> + <ScrollBar Style="HScrollBar" Maximum="{../dbv.MaxScrollX}" Value="{²../dbv.ScrollX}" SmallIncrement="1" LargeIncrement="10" + CursorRatio="{../dbv.ChildWidthRatio}"/> + </VerticalStack> +</Window>
\ No newline at end of file diff --git a/Samples/DebugLogAnalyzer/ui/main.crow b/Samples/DebugLogAnalyzer/ui/main.crow index 913220db..22d0920d 100644 --- a/Samples/DebugLogAnalyzer/ui/main.crow +++ b/Samples/DebugLogAnalyzer/ui/main.crow @@ -1,8 +1,8 @@ <?xml version="1.0"?> <VerticalStack Background="DarkGrey"> <HorizontalStack > - <TabView Width="25%" > - <VerticalStack Name="Explorer" Background="Onyx"> + <HorizontalStack Width="25%" > + <VerticalStack Width="50%" Name="Explorer" Background="Onyx"> <HorizontalStack Height="Fit" Margin="2" > <Image Margin="2" Width="16" Height="16" Path="#Crow.Icons.level-up.svg" MouseClick="goUpDirClick" Background="Jet" MouseEnter="{Background=Grey}" MouseLeave="{Background=Jet}" /> @@ -60,7 +60,8 @@ </Template> </DirectoryView> </VerticalStack> - <VerticalStack Name="DebugLogger" Margin="5" IsVisible="false" Background="Onyx"> + <Splitter/> + <VerticalStack Name="DebugLogger" Margin="5" IsVisible="true" Background="Onyx"> <HorizontalStack Height="Fit"> <Image Width="30" Height="20" Path="#Crow.Icons.IconAlerte.svg" Visible="{../../../../dbgIfaceWidget.CrowDebuggerNOK}"/> <Label Fit="true" Text="Crow debug assembly path:"/> @@ -80,7 +81,8 @@ Caption="Recorded Events" EnumValue="{²RecordedEvents}" BitFieldExcludeMask="255" /> <EnumSelector RadioButtonStyle="CheckBox2" Template="#Dbg.EnumSelector.template" Background="Onyx" - Caption="Discarded Events" EnumValue="{²DiscardedEvents}" BitFieldExcludeMask="255" /> + Caption="Discarded Events" EnumValue="{²DiscardedEvents}" BitFieldExcludeMask="255" /> + <CheckBox Caption="Begin recording on startup" IsChecked="{²DebugLogOnStartup}" Background="Onyx"/> <HorizontalStack Height="Fit"> <CheckBox Caption="Recording" IsChecked="{²DebugLogRecording}" Height="40" Width="60" Checked="{sh.Path='A 8,8,7.5,0,6.3 O 0.8,0,0,1 f O 0,0,0,0.5 G'}" @@ -98,7 +100,7 @@ </Menu> </HorizontalStack> </VerticalStack> - </TabView> + </HorizontalStack> <Splitter Width="6" /> <VerticalStack> <DebugInterfaceWidget Name="dbgIfaceWidget" Height="60%" Background="Black" Focusable="true" |