diff options
| author | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2020-07-06 08:18:33 +0200 |
|---|---|---|
| committer | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2020-07-06 08:18:33 +0200 |
| commit | 819371cd4b13b34a3a3d68e73d2481d1cbb5d1dc (patch) | |
| tree | e8f48fe0bfa792d18ace84e8604130354cf4a0bc /Samples | |
| parent | 5f689a331911b6115f298cc56c89b9e188095f46 (diff) | |
list item
Diffstat (limited to 'Samples')
22 files changed, 1301 insertions, 225 deletions
diff --git a/Samples/BasicTests/BasicTests.cs b/Samples/BasicTests/BasicTests.cs index bfebafcd..2e42052a 100644 --- a/Samples/BasicTests/BasicTests.cs +++ b/Samples/BasicTests/BasicTests.cs @@ -39,7 +39,8 @@ namespace tests //testFiles = new string [] { @"Interfaces/TemplatedControl/testEnumSelector.crow" }; //testFiles = new string [] { @"Interfaces/Divers/all.crow" }; //testFiles = new string [] { @"Interfaces/Divers/gauge.crow" }; - testFiles = new string [] { @"Interfaces/Divers/testSlider.crow" }; + //testFiles = new string [] { @"Interfaces/Stack/StretchedInFit4.crow" }; + testFiles = new string [] { @"Interfaces/TemplatedGroup/1.crow" }; //testFiles = new string [] { @"Interfaces/Divers/colorPicker2.crow" }; testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/GraphicObject", "*.crow")).ToArray (); testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/Container", "*.crow")).ToArray (); @@ -69,18 +70,20 @@ namespace tests Quit (); break; case Key.F2: + //if (IsKeyDown (Key.LeftShift)) + //DbgLogger.Reset (); + //DbgLogger.save (this); + return false; + case Key.F3: idx--; break; - case Key.F3: + case Key.F4: idx++; break; case Key.F1: //TestList.Add ("new string"); NotifyValueChanged ("TestList", TestList); break; - case Key.F4: - Load ("Interfaces/TemplatedContainer/testWindow.goml").DataSource = this; - return false; case Key.F5: Load ("Interfaces/Divers/testFileDialog.crow").DataSource = this; return false; diff --git a/Samples/DebugLogAnalyzer/DbgEventWidget.cs b/Samples/DebugLogAnalyzer/DbgEventWidget.cs new file mode 100644 index 00000000..1528e205 --- /dev/null +++ b/Samples/DebugLogAnalyzer/DbgEventWidget.cs @@ -0,0 +1,143 @@ +// Copyright (c) 2013-2020 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) +using System; +using System.Collections.Generic; +using System.ComponentModel; +using Crow.Cairo; + +namespace Crow +{ + public class DbgEventWidget : Widget + { + public DbgEventWidget (){} + + DbgEvent evt, hoverEvt; + long ticksPerPixel; + double pixelPerTick; + + public DbgEvent Event { + get => evt; + set { + if (evt == value) + return; + evt = value; + updatePixelPerTicks (); + NotifyValueChangedAuto (evt); + RegisterForRedraw (); + } + } + public DbgEvent HoverEvent { + get => hoverEvt; + private set { + if (hoverEvt == value) + return; + hoverEvt = value; + NotifyValueChangedAuto (hoverEvt); + } + } + + [DefaultValue ("1000")] + public long TicksPerPixel { + get => ticksPerPixel; + set { + if (ticksPerPixel == value) + return; + ticksPerPixel = value; + NotifyValueChangedAuto (ticksPerPixel); + if (Width == Measure.Fit) + RegisterForLayouting (LayoutingType.Width); + } + } + + public override int measureRawSize (LayoutingType lt) + { + updatePixelPerTicks (); + if (lt == LayoutingType.Width) + contentSize.Width = Event == null ? 0 : (int)Math.Max(pixelPerTick * Event.Duration, 2); + + return base.measureRawSize (lt); + } + + public override void OnLayoutChanges (LayoutingType layoutType) + { + if (layoutType == LayoutingType.Width) + updatePixelPerTicks (); + + base.OnLayoutChanges (layoutType); + } + + protected override void onDraw (Context gr) + { + if (Event == null) { + base.onDraw (gr); + return; + } + + gr.LineWidth = 1; + gr.SetDash (new double [] { 1.0, 3.0 }, 0); + + Rectangle cb = ClientRectangle; + + if (Event.Duration == 0) { + gr.SetSource (Event.Color); + gr.Rectangle (cb); + gr.Fill (); + return; + } + + drawEvent (gr, cb.Height, Event); + } + void drawEvent (Context ctx, int h, DbgEvent dbge) + { + double w = Math.Max(dbge.Duration * pixelPerTick, 2.0); + double x = (dbge.begin - Event.begin) * pixelPerTick; + + ctx.Rectangle (x, Margin, w, h); + ctx.SetSource (dbge.Color); + if (dbge.IsSelected) { + ctx.FillPreserve (); + ctx.SetSourceRGB (1, 1, 1); + ctx.Stroke (); + }else + ctx.Fill (); + + if (dbge.Events == null) + return; + foreach (DbgEvent e in dbge.Events) + drawEvent (ctx, h, e); + } + + public override void onMouseMove (object sender, MouseMoveEventArgs e) + { + if (Event != null) { + Point m = ScreenPointToLocal (e.Position); + long curTick = (long)(m.X / pixelPerTick) + Event.begin; + /*if (Width == Measure.Fit) + NotifyValueChanged ("HoverEvent", Event); + else*/ + HoverEvent = hoverEvent (Event, curTick); + + e.Handled = true; + } + base.onMouseMove (sender, e); + } + + DbgEvent hoverEvent (DbgEvent hevt, long curTick){ + if (hevt.Events != null) { + foreach (DbgEvent e in hevt.Events) { + if (curTick >= e.begin && curTick <= e.end) + return hoverEvent (e, curTick); + } + } + return hevt; + } + void updatePixelPerTicks () + { + if (Width == Measure.Fit) + pixelPerTick = 1.0 / ticksPerPixel; + else + pixelPerTick = Event == null ? 0 : (double)ClientRectangle.Width / Event.Duration; + } + } +}
\ No newline at end of file diff --git a/Samples/DebugLogAnalyzer/DbgLogViewer.cs b/Samples/DebugLogAnalyzer/DbgLogViewer.cs new file mode 100644 index 00000000..4b7a108a --- /dev/null +++ b/Samples/DebugLogAnalyzer/DbgLogViewer.cs @@ -0,0 +1,637 @@ +// Copyright (c) 2013-2020 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Crow.Cairo; + +namespace Crow +{ + public class DbgLogViewer : ScrollingObject + { + public static Dictionary<DbgEvtType, Color> colors; + + public static Configuration colorsConf = new Configuration ("dbgcolor.conf");//, Interface.GetStreamFromPath("#Crow.dbgcolor.conf")); + + public static void reloadColors () { + colors = new Dictionary<DbgEvtType, Color>(); + foreach (string n in colorsConf.Names) { + DbgEvtType t = (DbgEvtType)Enum.Parse (typeof(DbgEvtType), n); + Color c = colorsConf.Get<Color> (n); + colors.Add (t, c); + } + + } + #region CTOR + static DbgLogViewer() { + reloadColors (); + } + protected DbgLogViewer () : base(){} + public DbgLogViewer (Interface iface, string style = null) : base(iface, style){} + #endregion + + FontExtents fe; + + double xScale = 1.0/1024.0, yScale = 1.0, leftMargin, topMargin = 0.0; + DbgWidgetRecord curWidget, hoverWidget; + DbgEvent curEvent, hoverEvent; + + List<DbgEvent> events = new List<DbgEvent> (); + List<DbgWidgetRecord> widgets = new List<DbgWidgetRecord> (); + + public List<DbgEvent> Events { + get => events; + set { + if (events == value) + return; + events = value; + NotifyValueChanged (nameof (Events), events); + if (events == null) + return; + + maxTicks = 0; + minTicks = long.MaxValue; + foreach (DbgEvent e in events) { + if (e.begin < minTicks) + minTicks = e.begin; + if (e.end > maxTicks) + maxTicks = e.end; + } + + visibleTicks = maxTicks - minTicks; + XScale = (ClientRectangle.Width - leftMargin)/visibleTicks; + ScrollX = 0; + ScrollY = 0; + + RegisterForGraphicUpdate (); + } + } + public List<DbgWidgetRecord> Widgets { + get => widgets; + set { + if (widgets == value) + return; + widgets = value; + NotifyValueChanged (nameof (Widgets), widgets); + updateMargins (); + updateMaxScrollX (); + updateMaxScrollY (); + } + } + public DbgWidgetRecord CurrentWidget { + get => curWidget; + set { + if (curWidget == value) + return; + curWidget = value; + NotifyValueChanged (nameof (CurrentWidget), curWidget); + } + } + public DbgEvent CurrentEvent { + get => curEvent; + set { + if (curEvent == value) + return; + if (curEvent != null) + curEvent.IsSelected = false; + curEvent = value; + if (curEvent != null) { + curEvent.IsSelected = true; + if (curEvent is DbgWidgetEvent we) { + //CurrentWidget = Widgets [we.InstanceIndex]; + currentLine = we.InstanceIndex; + } + currentTick = curEvent.begin; + if (curEvent.begin > minTicks + ScrollX + visibleTicks || + curEvent.end < minTicks + ScrollX) { + ScrollX = (int)(currentTick - visibleTicks / 2); + } + } + NotifyValueChanged (nameof (CurrentEvent), curEvent); + RegisterForRedraw (); + } + } + public DbgWidgetRecord HoverWidget { + get => hoverWidget; + internal set { + if (hoverWidget == value) + return; + hoverWidget = value; + NotifyValueChanged (nameof (HoverWidget), hoverWidget); + } + } + + public DbgEvent HoverEvent { + get => hoverEvent; + set { + if (hoverEvent == value) + return; + hoverEvent = value; + NotifyValueChanged (nameof (HoverEvent), hoverEvent); + } + } + + long currentTick = 0, selStart = -1, selEnd = -1, minTicks = 0, maxTicks = 0, visibleTicks = 0; + int currentLine = -1; + int visibleLines = 1; + Point mousePos; + + public double XScale { + get { return xScale; } + set { + if (xScale == value) + return; + xScale = value; + NotifyValueChanged ("XScale", xScale); + updateVisibleTicks (); + RegisterForGraphicUpdate (); + } + } + public double YScale { + get => yScale; + set { + if (yScale == value) + return; + yScale = value; + NotifyValueChanged ("YScale", yScale); + RegisterForGraphicUpdate (); + } + } + public override Font Font { + get { return base.Font; } + set { + base.Font = value; + using (Context gr = new Context (IFace.surf)) { + gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight); + gr.SetFontSize (Font.Size); + + fe = gr.FontExtents; + } + updateMargins (); + } + } + public override int ScrollY { + get => base.ScrollY; + set { + base.ScrollY = value; + + if (widgets == null) + return; + + Rectangle cb = ClientRectangle; + cb.Left += (int)leftMargin; + cb.Width -= (int)leftMargin; + cb.Y += (int)topMargin; + cb.Height -= (int)topMargin; + + if (mousePos.Y < cb.Top || mousePos.Y > cb.Bottom) + currentLine = -1; + else + currentLine = (int)((double)(mousePos.Y - cb.Top) / fe.Height) + ScrollY; + + NotifyValueChanged ("CurrentLine", currentLine); + } + } + + void drawEvents (Context ctx, List<DbgEvent> evts) + { + if (evts == null || evts.Count == 0) + return; + Rectangle cb = ClientRectangle; + + foreach (DbgEvent evt in evts) { + if (evt.end - minTicks <= ScrollX) + continue; + if (evt.begin - minTicks > ScrollX + visibleTicks) + break; + double penY = topMargin + ClientRectangle.Top; + if (evt.type.HasFlag (DbgEvtType.Widget)) { + DbgWidgetEvent eW = evt as DbgWidgetEvent; + int lIdx = eW.InstanceIndex - ScrollY; + if (lIdx < 0 || lIdx > visibleLines) + continue; + penY += (lIdx) * fe.Height; + + ctx.SetSource (evt.Color); + + double x = xScale * (evt.begin - minTicks - ScrollX); + double w = Math.Max (Math.Max (2.0, 2.0 * xScale), (double)(evt.end - evt.begin) * xScale); + if (x < 0.0) { + w += x; + x = 0.0; + } + x += leftMargin + cb.Left; + double rightDiff = x + w - cb.Right; + if (rightDiff > 0) + w -= rightDiff; + + ctx.Rectangle (x, penY, w, fe.Height); + ctx.Fill (); + } else { + /*double x = xScale * (evt.begin - minTicks - ScrollX); + x += leftMargin + cb.Left; + + double trunc = Math.Truncate (x); + if (x - trunc > 0.5) + x = trunc + 0.5; + else + x = trunc - 0.5; + + + ctx.SetSource (Colors.Yellow); + ctx.MoveTo (x, penY); + ctx.LineTo (x, cb.Bottom); + ctx.Stroke (); + string s = evt.type.ToString () [5].ToString (); + TextExtents te = ctx.TextExtents (s); + ctx.Rectangle (x - 0.5 * te.Width, penY - te.Height, te.Width, te.Height); + ctx.Fill (); + ctx.MoveTo (x - 0.5 * te.Width, penY - ctx.FontExtents.Descent); + ctx.SetSource (Colors.Jet); + ctx.ShowText (s);*/ + + } + drawEvents (ctx, evt.Events); + } + } + + protected override void onDraw (Cairo.Context gr) + { + base.onDraw (gr); + + gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight); + gr.SetFontSize (Font.Size); + gr.FontOptions = Interface.FontRenderingOptions; + gr.Antialias = Cairo.Antialias.None; + + if (widgets == null) + return; + + gr.LineWidth = 1.0; + + Rectangle cb = ClientRectangle; + + double penY = topMargin + ClientRectangle.Top; + + for (int i = 0; i < visibleLines; i++) { + if (i + ScrollY >= widgets.Count) + break; + int gIdx = i + ScrollY; + DbgWidgetRecord g = widgets [gIdx]; + + penY += fe.Height; + + gr.SetSource (Crow.Colors.Jet); + gr.MoveTo (cb.X, penY - 0.5); + gr.LineTo (cb.Right, penY - 0.5); + gr.Stroke (); + + double penX = 5.0 * g.xLevel + cb.Left; + + if (g.yIndex == 0) + gr.SetSource (Crow.Colors.LightSalmon); + else + Foreground.SetAsSource (gr); + + gr.MoveTo (penX, penY - gr.FontExtents.Descent); + gr.ShowText (g.name + gIdx); + } + + drawEvents (gr, events); + /* + for (int i = 0; i < visibleLines; i++) { + foreach (DbgEvent evt in events) { + if (evt.end - minTicks <= ScrollX) + continue; + if (evt.begin - minTicks > ScrollX + visibleTicks) + break; + + + } + + + } + */ + + gr.MoveTo (cb.Left, topMargin - 0.5 + cb.Top); + gr.LineTo (cb.Right, topMargin - 0.5 + cb.Top); + + gr.MoveTo (leftMargin + cb.Left, cb.Top); + gr.LineTo (leftMargin + cb.Left, cb.Bottom); + gr.SetSource (Crow.Colors.Grey); + + penY = topMargin + ClientRectangle.Top; + + //graduation + int largeGrad = int.Parse ("1" + new string ('0', visibleTicks.ToString ().Length - 1)); + int smallGrad = Math.Max (1, largeGrad / 10); + + long firstVisibleTicks = minTicks + ScrollX; + long curGrad = firstVisibleTicks - firstVisibleTicks % smallGrad + smallGrad; + + long gg = curGrad - ScrollX - minTicks; + while (gg < visibleTicks ) { + double x = (double)gg * xScale + leftMargin + cb.Left; + + gr.MoveTo (x, penY - 0.5); + if (curGrad % largeGrad == 0) { + gr.LineTo (x, penY - 8.5); + string str = curGrad.ToString (); + TextExtents te = gr.TextExtents (str); + gr.RelMoveTo (-0.5 * te.Width, -2.0); + gr.ShowText (str); + }else + gr.LineTo (x, penY - 2.5); + + curGrad += smallGrad; + gg = curGrad - ScrollX - minTicks; + } + + gr.Stroke (); + + //global events +/* foreach (DbgEvent evt in events) { + if (evt.begin - minTicks <= ScrollX) + continue; + double x = xScale * (evt.begin - minTicks - ScrollX) ; + x += leftMargin + cb.Left; + + + }*/ + + } + public override void Paint (ref Cairo.Context ctx) + { + base.Paint (ref ctx); + + Rectangle r = new Rectangle(mousePos.X, 0, 1, Slot.Height); + Rectangle ctxR = ContextCoordinates (r); + Rectangle cb = ClientRectangle; + ctx.LineWidth = 1.0; + double x = xScale * (currentTick - minTicks - ScrollX) + leftMargin; + if (x - Math.Truncate (x) > 0.5) + x = Math.Truncate (x) + 0.5; + else + x = Math.Truncate (x) - 0.5; + ctx.MoveTo (x, cb.Top + topMargin - 4.0); + ctx.LineTo (x, cb.Bottom); + + //ctx.Rectangle (ctxR); + ctx.SetSource (Colors.CornflowerBlue); + ctx.Stroke(); + + ctx.SelectFontFace (Font.Name, Font.Slant, Font.Wheight); + ctx.SetFontSize (Font.Size); + ctx.FontOptions = Interface.FontRenderingOptions; + ctx.Antialias = Interface.Antialias; + + ctx.MoveTo (ctxR.X - ctx.TextExtents (currentTick.ToString ()).Width / 2, ctxR.Y + fe.Height); + ctx.ShowText (currentTick.ToString ()); + + ctx.Operator = Cairo.Operator.Add; + + if (currentLine >= 0) { + double y = fe.Height * (currentLine - ScrollY) + topMargin + cb.Top; + r = new Rectangle (cb.Left, (int)y, cb.Width, (int)fe.Height); + + ctx.Operator = Cairo.Operator.Add; + ctx.SetSourceRGBA (0.1, 0.1, 0.1, 0.4); + ctx.Rectangle (ContextCoordinates (r)); + ctx.Fill (); + } + + if (CurrentWidget != null) { + + } + + if (selStart < 0 || selEnd < 0) { + ctx.Operator = Cairo.Operator.Over; + return; + } + double selStartX = (double)(selStart - ScrollX - minTicks) * xScale + leftMargin + cb.Left; + double selEndX = (double)(selEnd - ScrollX - minTicks) * xScale + leftMargin + cb.Left; + + if (selStartX < selEndX) { + ctxR.X = (int)selStartX; + ctxR.Width = (int)(selEndX - selStartX); + } else { + ctxR.X = (int)selEndX; + ctxR.Width = (int)(selStartX - selEndX); + } + + ctxR.Width = Math.Max (1, ctxR.Width); + ctx.Rectangle (ctxR); + //ctx.SetSourceColor (Color.LightYellow); + ctx.SetSource (Colors.Jet); + ctx.Fill(); + ctx.Operator = Cairo.Operator.Over; + + } + public override void OnLayoutChanges (LayoutingType layoutType) + { + base.OnLayoutChanges (layoutType); + switch (layoutType) { + case LayoutingType.Width: + if (xScale < 0) { + visibleTicks = maxTicks - minTicks; + XScale = (ClientRectangle.Width - leftMargin) / visibleTicks; + } + updateVisibleTicks (); + break; + case LayoutingType.Height: + updateVisibleLines (); + break; + } + } + + public override void onMouseLeave (object sender, MouseMoveEventArgs e) + { + base.onMouseLeave (sender, e); + currentLine = -1; + currentTick = 0; + } + public override void onMouseMove (object sender, MouseMoveEventArgs e) + { + base.onMouseMove (sender, e); + + long lastTick = currentTick; + updateMouseLocalPos (e.Position); + + if (IFace.IsDown (Glfw.MouseButton.Left) && selStart >= 0) + selEnd = currentTick; + else if (IFace.IsDown(Glfw.MouseButton.Right)) { + ScrollX += (int)(lastTick - currentTick); + updateMouseLocalPos (e.Position); + } else { + HoverWidget = (currentLine < 0 || currentLine >= widgets.Count) ? null : widgets [currentLine]; + HoverEvent = hoverWidget?.Events.FirstOrDefault (ev => ev.begin <= currentTick && ev.end >= currentTick); + } + + if (RegisteredLayoutings == LayoutingType.None && !IsDirty) + IFace.EnqueueForRepaint (this); + + } + public override void onMouseDown (object sender, MouseButtonEventArgs e) + { + base.onMouseDown (sender, e); + + if (e.Button == Glfw.MouseButton.Left) { + CurrentWidget = hoverWidget; + CurrentEvent = hoverEvent; + selStart = currentTick; + selEnd = -1; + } + + RegisterForRedraw (); + } + public override void onMouseUp (object sender, MouseButtonEventArgs e) + { + base.onMouseUp (sender, e); + + if (e.Button == Glfw.MouseButton.Left && selEnd > 0 && selEnd != selStart) { + long scrX = 0; + if (selStart < selEnd) { + visibleTicks = selEnd - selStart; + scrX = selStart - minTicks; + } else { + visibleTicks = selStart - selEnd; + scrX = selEnd - minTicks; + } + XScale = (ClientRectangle.Width - leftMargin) / visibleTicks; + ScrollX = (int)scrX; + } + selStart = -1; + selEnd = -1; + + RegisterForRedraw (); + } + + /// <summary> Process scrolling vertically, or if shift is down, vertically </summary> + public override void onMouseWheel (object sender, MouseWheelEventArgs e) + { + base.onMouseWheel (sender, e); + + if (IFace.Shift) + ScrollX -= (int)((double)(e.Delta * MouseWheelSpeed) / xScale); + else if (IFace.Ctrl) { + if (e.Delta > 0) { + XScale *= 2.0; + } else { + if (MaxScrollX > 0) + XScale *= 0.5; + } + ScrollX = (int)(currentTick - (int)((double)Math.Max(0, mousePos.X - (int)leftMargin) / xScale) - minTicks); + }else + ScrollY -= e.Delta * MouseWheelSpeed; + } + + public override void onKeyDown (object sender, KeyEventArgs e) + { + base.onKeyDown (sender, e); + + if (e.Key == Glfw.Key.F3) { + if (selEnd < 0) + return; + if (selEnd < selStart) + zoom (selEnd, selStart); + else + zoom (selStart, selEnd); + selEnd = selStart = -1; + } + } + + void updateMargins () + { + leftMargin = topMargin = 0.0; + + if (widgets == null) + return; + + using (Context gr = new Context (IFace.surf)) { + double maxNameWidth = 0.0; + + gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight); + gr.SetFontSize (Font.Size); + + foreach (DbgWidgetRecord o in widgets) { + double nameWidth = gr.TextExtents (o.name).Width + 5.0 * o.xLevel; + if (nameWidth > maxNameWidth) + maxNameWidth = nameWidth; + } + + leftMargin = 10.5 + maxNameWidth; + topMargin = 2.0 * fe.Height; + + RegisterForGraphicUpdate (); + } + } + + void updateVisibleLines () + { + visibleLines = fe.Height < 1 ? 1 : (int)Math.Floor (((double)ClientRectangle.Height - topMargin) / fe.Height); + NotifyValueChanged ("VisibleLines", visibleLines); + updateMaxScrollY (); + } + void updateVisibleTicks () + { + visibleTicks = Math.Max (0, (long)((double)(ClientRectangle.Width - leftMargin) / XScale)); + NotifyValueChanged ("VisibleTicks", visibleTicks); + updateMaxScrollX (); + } + + void updateMaxScrollX () + { + if (widgets == null) + MaxScrollX = 0; + else + MaxScrollX = (int)Math.Max (0L, maxTicks - minTicks - visibleTicks); + } + void updateMaxScrollY () + { + if (widgets == null) + MaxScrollY = 0; + else + MaxScrollY = Math.Max (0, widgets.Count - visibleLines); + } + + void updateMouseLocalPos (Point mPos) + { + Rectangle r = ScreenCoordinates (Slot); + Rectangle cb = ClientRectangle; + cb.Left += (int)leftMargin; + cb.Width -= (int)leftMargin; + cb.Y += (int)topMargin; + cb.Height -= (int)topMargin; + + mousePos = mPos - r.Position; + + mousePos.X = Math.Max (cb.X, mousePos.X); + mousePos.X = Math.Min (cb.Right, mousePos.X); + + if (mousePos.Y < cb.Top || mousePos.Y > cb.Bottom) + currentLine = -1; + else + currentLine = (int)((double)(mousePos.Y - cb.Top) / fe.Height) + ScrollY; + + NotifyValueChanged ("CurrentLine", currentLine); + + mousePos.Y = Math.Max (cb.Y, mousePos.Y); + mousePos.Y = Math.Min (cb.Bottom, mousePos.Y); + + currentTick = (int)((double)(mousePos.X - cb.X) / xScale) + minTicks + ScrollX; + RegisterForRedraw (); + } + void zoom (long start, long end) { + //Rectangle cb = ClientRectangle; + //cb.X += (int)leftMargin; + XScale = ((double)ClientRectangle.Width - leftMargin)/(end - start); + ScrollX = (int)(start - minTicks); + } + } +} + + diff --git a/Samples/DebugLogAnalyzer/DebugLogAnalyzer.csproj b/Samples/DebugLogAnalyzer/DebugLogAnalyzer.csproj new file mode 100644 index 00000000..df93e686 --- /dev/null +++ b/Samples/DebugLogAnalyzer/DebugLogAnalyzer.csproj @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project Sdk="Microsoft.NET.Sdk"> + <ItemGroup> + <EmbeddedResource Include="ui\**\*.*"> + <LogicalName>Dbg.%(Filename)%(Extension)</LogicalName> + </EmbeddedResource> +</ItemGroup> + +</Project>
\ No newline at end of file diff --git a/Samples/DebugLogAnalyzer/Program.cs b/Samples/DebugLogAnalyzer/Program.cs new file mode 100644 index 00000000..6be26ced --- /dev/null +++ b/Samples/DebugLogAnalyzer/Program.cs @@ -0,0 +1,178 @@ +// Copyright (c) 2013-2020 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) +using System; +using System.Collections.Generic; +using System.IO; +using Crow; +using Crow.Cairo; + +namespace DebugLogAnalyzer +{ + public class Program : SampleBase + { + static void Main (string [] args) + { +#if NETCOREAPP3_1 + DllMapCore.Resolve.Enable (true); +#endif + using (Program app = new Program ()) + app.Run (); + } + + List<DbgEvent> events = new List<DbgEvent>(); + List<DbgWidgetRecord> widgets = new List<DbgWidgetRecord>(); + DbgEvent curEvent = new DbgEvent(); + DbgWidgetRecord curWidget = new DbgWidgetRecord(); + + public List<DbgEvent> Events { + get => events; + set { + if (events == value) + return; + events = value; + NotifyValueChanged (nameof (Events), events); + } + } + public List<DbgWidgetRecord> Widgets { + get => widgets; + set { + if (widgets == value) + return; + widgets = value; + NotifyValueChanged (nameof (Widgets), widgets); + } + } + public DbgEvent CurrentEvent { + get => curEvent; + set { + if (curEvent == value) + return; + + if (curEvent != null) + curEvent.IsSelected = false; + curEvent = value; + if (curEvent != null) { + curEvent.IsSelected = true; + if (curEvent.parentEvent != null) + curEvent.parentEvent.IsExpanded = true; + } + + NotifyValueChanged (nameof (CurrentEvent), curEvent); + } + } + public DbgWidgetRecord CurrentWidget { + get => curWidget; + set { + if (curWidget == value) + return; + curWidget = value; + NotifyValueChanged (nameof (CurrentWidget), curWidget); + NotifyValueChanged ("CurWidgetRootEvents", CurWidgetRootEvents); + } + } + public List<DbgWidgetEvent> CurWidgetRootEvents => curWidget == null? new List<DbgWidgetEvent>() : curWidget.RootEvents; + + Scroller dbgTreeViewScroller; + + protected override void OnInitialized () + { + Load ("#Dbg.dbglog.crow").DataSource = this; + + TreeView tv = FindByName("dbgTV") as TreeView; + dbgTreeViewScroller = tv.FindByNameInTemplate ("scroller1") as Scroller; + + loadDebugFile ("/var/tmp/debug.log"); + } + + void loadDebugFile (string logFile) + { + if (!File.Exists (logFile)) + return; + + List<DbgEvent> evts = new List<DbgEvent> (); + List<DbgWidgetRecord> objs = new List<DbgWidgetRecord> (); + + using (StreamReader s = new StreamReader (logFile)) { + if (s.ReadLine () != "[GraphicObjects]") + return; + while (!s.EndOfStream) { + string l = s.ReadLine (); + if (l == "[Events]") + break; + DbgWidgetRecord o = DbgWidgetRecord.Parse (l); + objs.Add (o); + } + + Stack<DbgEvent> startedEvents = new Stack<DbgEvent> (); + + if (!s.EndOfStream) { + while (!s.EndOfStream) { + int level = 0; + while (s.Peek () == (int)'\t') { + s.Read (); + level++; + } + DbgEvent evt = DbgEvent.Parse (s.ReadLine ()); + if (level == 0) { + startedEvents.Clear (); + evts.Add (evt); + } else { + int levelDiff = level - startedEvents.Count + 1; + if (levelDiff > 0) { + if (levelDiff > 1) + System.Diagnostics.Debugger.Break (); + startedEvents.Peek ().AddEvent (evt); + } else { + startedEvents.Pop (); + if (-levelDiff > startedEvents.Count) + System.Diagnostics.Debugger.Break (); + while (startedEvents.Count > level) + startedEvents.Pop (); + startedEvents.Peek ().AddEvent (evt); + } + } + startedEvents.Push (evt); + if (evt.type.HasFlag (DbgEvtType.Widget)) + objs [(evt as DbgWidgetEvent).InstanceIndex].Events.Add (evt); + } + } + } + Widgets = objs; + Events = evts; + } + + int targetTvScroll = -1; + + void onTvPainted (object sender, EventArgs e) + { + if (targetTvScroll < 0 || targetTvScroll > dbgTreeViewScroller.MaxScrollY + dbgTreeViewScroller.Slot.Height) + return; + dbgTreeViewScroller.MaxScrollY = targetTvScroll; + targetTvScroll = -1; + } + + void onSelectedItemContainerChanged (object sender, SelectionChangeEventArgs e) + { + TreeView tv = sender as TreeView; + Group it = tv.FindByNameInTemplate ("ItemsContainer") as Group; + + ListItem li = e.NewValue as ListItem; + Rectangle selRect = li.RelativeSlot (it); + + if (selRect.Y > dbgTreeViewScroller.ScrollY && selRect.Y < dbgTreeViewScroller.Slot.Height + dbgTreeViewScroller.ScrollY) + return; + + Console.WriteLine ($"Scroll={dbgTreeViewScroller.ScrollY} selRectY={selRect.Y} MaxScrollY={dbgTreeViewScroller.MaxScrollY} ScrollerH={dbgTreeViewScroller.Slot.Height}"); + targetTvScroll = selRect.Y; + if (selRect.Y > dbgTreeViewScroller.MaxScrollY + dbgTreeViewScroller.Slot.Height) + targetTvScroll = selRect.Y; + else { + targetTvScroll = -1; + dbgTreeViewScroller.ScrollY = selRect.Y; + } + } + + } +} + diff --git a/Samples/DebugLogAnalyzer/Properties/AssemblyInfo.cs b/Samples/DebugLogAnalyzer/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..d8646524 --- /dev/null +++ b/Samples/DebugLogAnalyzer/Properties/AssemblyInfo.cs @@ -0,0 +1,5 @@ +// Copyright (c) 2013-2020 Jean-Philippe Bruyère <jp_bruyere@hotmail.com> +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) +[assembly: Crow.Crow ] + diff --git a/Samples/DebugLogAnalyzer/ui/DbgEventTreeItems.itemp b/Samples/DebugLogAnalyzer/ui/DbgEventTreeItems.itemp new file mode 100644 index 00000000..2f6fbfbf --- /dev/null +++ b/Samples/DebugLogAnalyzer/ui/DbgEventTreeItems.itemp @@ -0,0 +1,70 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<ItemTemplate Data="Events"> + <ListItem IsSelected="{²IsSelected}" Height="Fit" + Selected="{/exp.Background=${ControlHighlight}}" + Unselected="{/exp.Background=Transparent}"> + <Expandable Name="exp" Caption="{type}" MouseDoubleClick="/onClickForExpand" CacheEnabled="true" IsExpanded="{²IsExpanded}"> + <Template> + <VerticalStack> + <Border CornerRadius="2" Margin="0" Height="Fit" MouseDoubleClick="./onClickForExpand" + Foreground="Transparent" + Background="{./Background}" + MouseEnter="{Foreground=DimGrey}" + MouseLeave="{Foreground=Transparent}"> + <HorizontalStack Spacing="2" > + <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"/> + <DbgEventWidget Event="{}" Tooltip="#Dbg.DbgEvtTooltip.crow" Width="Stretched" 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> + </ListItem> +</ItemTemplate> +<ItemTemplate Data="Events" DataType="DbgWidgetEvent"> + <ListItem IsSelected="{²IsSelected}" Height="Fit" + Selected="{/exp.Background=${ControlHighlight}}" + Unselected="{/exp.Background=Transparent}"> + <Expandable Name="exp" Caption="{type}" MouseDoubleClick="/onClickForExpand" CacheEnabled="true" IsExpanded="{²IsExpanded}"> + <Template> + <VerticalStack> + <Border CornerRadius="2" Margin="0" Height="Fit" MouseDoubleClick="./onClickForExpand" + Foreground="Transparent" + Background="{./Background}" + MouseEnter="{Foreground=DimGrey}" + MouseLeave="{Foreground=Transparent}"> + <HorizontalStack Spacing="2" > + <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="#Dbg.DbgEvtTooltip.crow" Width="Stretched" 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> + </ListItem> +</ItemTemplate>
\ No newline at end of file diff --git a/Samples/DebugLogAnalyzer/ui/DbgEvtTooltip.crow b/Samples/DebugLogAnalyzer/ui/DbgEvtTooltip.crow new file mode 100644 index 00000000..9d40f45d --- /dev/null +++ b/Samples/DebugLogAnalyzer/ui/DbgEvtTooltip.crow @@ -0,0 +1,37 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<Border Fit="true" Foreground="${TooltipForeground}" Background="${TooltipBackground}"> + <VerticalStack Fit="true" Margin="${TooltipMargin}" DataSource="{HoverEvent}"> + <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="{Duration}" 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="{begin}" Foreground="${TooltipForeground}" Width="Stretched" TextAlignment="Right"/> + </HorizontalStack> + <HorizontalStack Height="Fit" Width="Stretched" Spacing="2"> + <Label Text="End:" Foreground="${TooltipForeground}" Width="50%"/> + <Label Text="{end}" Foreground="${TooltipForeground}" Width="Stretched" TextAlignment="Right"/> + </HorizontalStack> + <VerticalStack Height="Fit" Width="Stretched" > + <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> + <!--<Label Text="{}" Foreground="${TooltipForeground}"/>--> + </VerticalStack> +</Border>
\ No newline at end of file diff --git a/Samples/DebugLogAnalyzer/ui/dbglog.crow b/Samples/DebugLogAnalyzer/ui/dbglog.crow new file mode 100644 index 00000000..72d96bf0 --- /dev/null +++ b/Samples/DebugLogAnalyzer/ui/dbglog.crow @@ -0,0 +1,98 @@ +<?xml version="1.0" encoding="UTF-8"?> +<VerticalStack> + <VerticalStack Height="40%"> + <DbgLogViewer Visible="true" Name="dbv" Events="{Events}" Widgets="{Widgets}" MouseWheelSpeed="10" Font="mono, 8" + CurrentEvent="{²CurrentEvent}" CurrentWidget="{²CurrentWidget}" Background="Onyx"/> + <ScrollBar Style="HScrollBar" Maximum="{../dbv.MaxScrollX}" Value="{²../dbv.ScrollX}"/> + <HorizontalStack Height="Fit" DataSource="{CurrentWidget}"> + <Label Text="{name}"/> + <Label Text="{listIndex}"/> + <Label Text="{treeIndex}"/> + <Label Text="{yIndex}"/> + <Label Text="{xLevel}"/> + <Label Text="Width:"/> + <Label Text="{Width}"/> + <Label Text="Height:"/> + <Label Text="{Height}"/> + <Label Text="ScrollX"/> + <Label Text="{../../dbv.ScrollX}"/> + </HorizontalStack> + </VerticalStack> + <Splitter/> + <HorizontalStack Height="40%"> + <VerticalStack Width="Stretched"> + <TreeView Height="Stretched" Name="dbgTV" Data="{Events}" SelectedItem="{²CurrentEvent}" Background="DarkGrey" + SelectedItemContainerChanged="onSelectedItemContainerChanged" Painted="onTvPainted" + ItemTemplate="#Dbg.DbgEventTreeItems.itemp"/> + <ListBox Data="{CurWidgetRootEvents}" Height="100" SelectedItem="{²CurrentEvent}"> + <ItemTemplate> + <ListItem Margin="0" Height="16" IsSelected="{²IsSelected}" Width="Fit" + Selected="{Background=${ControlHighlight}}" + Unselected="{Background=Transparent}"> + <DbgEventWidget Height="10" Width="Fit" Event="{}" Tooltip="#Dbg.DbgEvtTooltip.crow" TicksPerPixel="20" VerticalAlignment="Center"/> + </ListItem> + </ItemTemplate> + <Template> + <Wrapper Name="ItemsContainer" Spacing="0" Background="DarkGrey"/> + </Template> + </ListBox> + </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="{Duration}" 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="{begin}" Foreground="${TooltipForeground}" Width="Stretched" TextAlignment="Right"/> + </HorizontalStack> + <HorizontalStack Height="Fit" Width="Stretched" Spacing="2"> + <Label Text="End:" Foreground="${TooltipForeground}" Width="50%"/> + <Label Text="{end}" Foreground="${TooltipForeground}" Width="Stretched" TextAlignment="Right"/> + </HorizontalStack> + <VerticalStack Height="Fit" Width="Stretched" > + <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> + <!--<Label Text="{}" Foreground="${TooltipForeground}"/>--> + </VerticalStack> + </HorizontalStack> + <Splitter/> + <VerticalStack Name="vs"> + + <VerticalStack DataSource="{CurrentEvent}"> + <ListBox Data="{Events}" Height="100" SelectedItem="{²CurrentEvent}"> + <ItemTemplate> + <ListItem Margin="0" IsSelected="{²IsSelected}" Height="12" + Selected="{Background=${ControlHighlight}}" + Unselected="{Background=Transparent}"> + <HorizontalStack> + <Label Text="{type}" Width="80"/> + <DbgEventWidget Height="8" Width="Stretched" Event="{}"/> + </HorizontalStack> + </ListItem> + </ItemTemplate> + </ListBox> + </VerticalStack> + </VerticalStack> +</VerticalStack>
\ No newline at end of file diff --git a/Samples/HelloWorld/HelloWorld.csproj b/Samples/HelloWorld/HelloWorld.csproj index 253e0eb1..b19bb1c6 100644 --- a/Samples/HelloWorld/HelloWorld.csproj +++ b/Samples/HelloWorld/HelloWorld.csproj @@ -1,7 +1,8 @@ -<Project Sdk="Microsoft.NET.Sdk"> - <ItemGroup> - <EmbeddedResource Include="ui\**\*.*"> - <LogicalName>HelloWorld.%(Filename)%(Extension)</LogicalName> - </EmbeddedResource> - </ItemGroup> -</Project> +<?xml version="1.0" encoding="UTF-8"?> +<Project Sdk="Microsoft.NET.Sdk"> + <ItemGroup> + <EmbeddedResource Include="ui\**\*.*"> + <LogicalName>HelloWorld.%(Filename)%(Extension)</LogicalName> + </EmbeddedResource> + </ItemGroup> +</Project>
\ No newline at end of file diff --git a/Samples/HelloWorld/main.cs b/Samples/HelloWorld/main.cs index 743419ee..1aa90bbe 100644 --- a/Samples/HelloWorld/main.cs +++ b/Samples/HelloWorld/main.cs @@ -11,6 +11,8 @@ namespace HelloWorld using (Interface app = new Interface ()) { app.Initialized += (sender, e) => (sender as Interface).Load ("#HelloWorld.helloworld.crow"); app.Run (); + + DbgLogger.save (app); } } } diff --git a/Samples/ShowCase/ShowCase.cs b/Samples/ShowCase/ShowCase.cs index dd0b77c9..f3aba2b5 100644 --- a/Samples/ShowCase/ShowCase.cs +++ b/Samples/ShowCase/ShowCase.cs @@ -8,6 +8,7 @@ using System.IO; using System.Text; using Crow.IML; using System.Runtime.CompilerServices; +using Glfw; namespace ShowCase { @@ -175,18 +176,17 @@ namespace ShowCase reloadFromFile (); } - - static void App_KeyboardKeyDown (object sender, KeyEventArgs e) + public override bool OnKeyDown (Key key) { -#if DEBUG_LOG - switch (e.Key) { + switch (key) { case Key.F2: - DebugLog.save (sender as Interface); - break; + //DbgLogger.save (this); + return true; } -#endif + return base.OnKeyDown (key); } + public void goUpDirClick (object sender, MouseButtonEventArgs e) { string root = Directory.GetDirectoryRoot (CurrentDir); diff --git a/Samples/common/SampleBase.cs b/Samples/common/SampleBase.cs index aea139c3..93aec907 100644 --- a/Samples/common/SampleBase.cs +++ b/Samples/common/SampleBase.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; +using System.Runtime.CompilerServices; using System.Threading; using Crow; @@ -81,6 +82,79 @@ namespace Crow => $"{Prop1}, {Prop2}"; } + public class TestClassVC : IValueChange + { + public event EventHandler<ValueChangeEventArgs> ValueChanged; + public void NotifyValueChanged (object _value, [CallerMemberName] string caller = null) + => ValueChanged.Raise (this, new ValueChangeEventArgs (caller, _value)); + string prop1, prop2; + public string Prop1 { + get => prop1; + set { + if (prop1 == value) + return; + prop1 = value; + NotifyValueChanged (prop1); + } + } + public string Prop2 { + get => prop2; + set { + if (prop2 == value) + return; + prop2 = value; + NotifyValueChanged (prop2); + } + + + + } + + public override string ToString () + => $"{Prop1}, {Prop2}"; + + } + TestClass tcInstance;// = new TestClass () { Prop1 = "instance 0 prop1 value", Prop2 = "instance 0 prop2 value" }; + TestClassVC tcVCInstance;// = new TestClassVC () { Prop1 = "instance 0 prop1 value", Prop2 = "instance 0 prop2 value" }; + TestClass tcInstance1 = new TestClass () { Prop1 = "instance 1 prop1 value", Prop2 = "instance 1 prop2 value" }; + TestClassVC tcVCInstance1 = new TestClassVC () { Prop1 = "instance 1 prop1 value", Prop2 = "instance 1 prop2 value" }; + TestClass tcInstance2 = new TestClass () { Prop1 = "instance 2 prop1 value", Prop2 = "instance 2 prop2 value" }; + TestClassVC tcVCInstance2 = new TestClassVC () { Prop1 = "instance 2 prop1 value", Prop2 = "instance 2 prop2 value" }; + + public TestClass TcInstance { + get => tcInstance; + set { + if (tcInstance == value) + return; + tcInstance = value; + NotifyValueChanged (tcInstance); + } + } + public TestClassVC TcVCInstance { + get => tcVCInstance; + set { + if (tcVCInstance == value) + return; + tcVCInstance = value; + NotifyValueChanged (tcVCInstance); + } + } + + void tcInstance_ChangeProperties_MouseClick (object sender, MouseButtonEventArgs e) + { + } + public void tcInstance_ChangeInstance_MouseClick (object sender, MouseButtonEventArgs e) + { + if (TcInstance == tcInstance1) + TcInstance = tcInstance2; + else + TcInstance = tcInstance1; + } + void tcVCInstance_ChangeInstance_MouseClick (object sender, MouseButtonEventArgs e) + { + TcVCInstance = new TestClassVC () { Prop1 = "prop1 value changed", Prop2 = "prop2 value changed" }; + } + public IEnumerable<TestClass> List3 = new List<TestClass> (new TestClass[] { new TestClass { Prop1 = "string1", Prop2="prop2-1" }, diff --git a/Samples/common/samples.style b/Samples/common/samples.style index 9c382e6a..124cfcf4 100644 --- a/Samples/common/samples.style +++ b/Samples/common/samples.style @@ -24,7 +24,7 @@ CheckBox2 { Template= "Interfaces/CheckBox2.imlt"; Background = "Jet"; Checked="{Background=MediumSeaGreen}"; - Unchecked = "{Background=Jet}"; + Unchecked = "{Background=Jet}"; } CheckBox3 { Template= "Interfaces/CheckBox2.imlt"; @@ -44,7 +44,7 @@ labPerfVal{ Width = "50%"; } DbgLogViewer{ - Background = "Onyx"; + //Background = "Onyx"; Font = "mono, 8"; Foreground = "LightGrey"; Focusable = "true"; diff --git a/Samples/common/ui/Interfaces/CheckBox2.imlt b/Samples/common/ui/Interfaces/CheckBox2.imlt index c2bfe8da..84ec22b3 100644 --- a/Samples/common/ui/Interfaces/CheckBox2.imlt +++ b/Samples/common/ui/Interfaces/CheckBox2.imlt @@ -1,5 +1,5 @@ -<Label Font="{./Font}" Text="{./Caption}" Height="{./HeightPolicy}" Width="{./WidthPolicy}" - Margin="3" +<Label Font="{./Font}" Text="{./Caption}" Width="Stretched" + Margin="5" Background="{./Background}" Foreground="DimGrey" TextAlignment="Center" diff --git a/Samples/common/ui/Interfaces/Divers/classBindings.crow b/Samples/common/ui/Interfaces/Divers/classBindings.crow new file mode 100644 index 00000000..72144e8e --- /dev/null +++ b/Samples/common/ui/Interfaces/Divers/classBindings.crow @@ -0,0 +1,9 @@ +<VerticalStack Fit="true"> + <VerticalStack DataSourceType="Crow.TestClass" DataSource="{TcInstance}" Margin="10" Background="Onyx" Fit="true"> + <Label Text="{Prop1}"/> + <Label Text="{Prop2}"/> + </VerticalStack> + <HorizontalStack> + <Button Caption="Change Instance" MouseClick="tcInstance_ChangeInstance_MouseClick"/> + </HorizontalStack> +</VerticalStack>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Divers/dbglog.crow b/Samples/common/ui/Interfaces/Divers/dbglog.crow deleted file mode 100644 index 16f6c35e..00000000 --- a/Samples/common/ui/Interfaces/Divers/dbglog.crow +++ /dev/null @@ -1,99 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<HorizontalStack> - <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" - 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"/> - <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"/> - </VerticalStack> - </Template> - <HorizontalStack Height="Fit"> - <Widget Width="12" Height="10"/> - <VerticalStack Height="Fit" Name="ItemsContainer"/> - </HorizontalStack> - </Expandable> - </ItemTemplate> - </TreeView> - <Splitter/> - <VerticalStack> - <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="{instanceNum}"/> - <Label Text="{treeIndex}"/> - <Label Text="{yIndex}"/> - <Label Text="{xLevel}"/> - </HorizontalStack> - <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}"/> - <Label Text="{begin}"/> - <Label Text="{end}"/> - <Label Text="{Duration}"/> - </HorizontalStack> - <ListBox Data="{events}" Height="100"> - <ItemTemplate> - <DbgEventWidget Height="20" Width="Stretched" Event="{}"/> - </ItemTemplate> - </ListBox> - </VerticalStack> - </VerticalStack> -</HorizontalStack>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/Divers/splitter0.crow b/Samples/common/ui/Interfaces/Divers/splitter0.crow new file mode 100644 index 00000000..218ba621 --- /dev/null +++ b/Samples/common/ui/Interfaces/Divers/splitter0.crow @@ -0,0 +1,7 @@ +<HorizontalStack Margin="50"> + <Widget Background="SeaGreen" Width="33%"/> + <Splitter/> + <Widget Background="SeaGreen" Width="33%"/> + <Splitter/> + <Widget Background="SeaGreen"/> +</HorizontalStack> diff --git a/Samples/common/ui/Interfaces/Splitter/1.crow b/Samples/common/ui/Interfaces/Splitter/1.crow deleted file mode 100644 index 48c1ea1e..00000000 --- a/Samples/common/ui/Interfaces/Splitter/1.crow +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0"?> -<HorizontalStack Width="80%" Height="50%"> - <Border Width="45%" CornerRadius="10" BorderWidth="1"> - <VerticalStack> - <VerticalStack Height="45%"> - <CheckBox Height="25%" IsChecked="false" Caption="Check 1" Background="hgradient|0:LimeGreen|1:Transparent"/> - <CheckBox Height="25%" IsChecked="false" Caption="Check 2" Background="hgradient|0:LimeGreen|1:Transparent"/> - <CheckBox Height="25%" IsChecked="true" Caption="Check 3" Background="hgradient|0:LimeGreen|1:Transparent"/> - <CheckBox Height="25%" IsChecked="false" Caption="Check 4" Background="hgradient|0:LimeGreen|1:Transparent"/> - </VerticalStack> - <Splitter Thickness="3"/> - <VerticalStack Height="45%"> - <CheckBox Height="25%" IsChecked="false" Caption="Check 1" Background="hgradient|0:LimeGreen|1:Transparent"/> - <CheckBox Height="25%" IsChecked="false" Caption="Check 2" Background="hgradient|0:LimeGreen|1:Transparent"/> - <CheckBox Height="25%" IsChecked="true" Caption="Check 3" Background="hgradient|0:LimeGreen|1:Transparent"/> - <CheckBox Height="25%" IsChecked="false" Caption="Check 4" Background="hgradient|0:LimeGreen|1:Transparent"/> - </VerticalStack> - </VerticalStack> - </Border> - <Splitter Thickness="3"/> - <Border Width="45%" CornerRadius="10" BorderWidth="1"> - <VerticalStack Width="50%" Height="50%" Background="DimGrey"> - <RadioButton IsChecked="false" Caption="Choice 1" Background="hgradient|0:DarkRed|1:Transparent"/> - <RadioButton IsChecked="false" Caption="Choice 2" Background="hgradient|0:DarkRed|1:Transparent"/> - <RadioButton IsChecked="true" Caption="Choice 3" Background="hgradient|0:DarkRed|1:Transparent"/> - <RadioButton IsChecked="false" Caption="Choice 4" Background="hgradient|0:DarkRed|1:Transparent"/> - </VerticalStack> - </Border> - <Splitter Thickness="3"/> -</HorizontalStack> diff --git a/Samples/common/ui/Interfaces/Splitter/3.crow b/Samples/common/ui/Interfaces/Splitter/3.crow deleted file mode 100644 index 9a288963..00000000 --- a/Samples/common/ui/Interfaces/Splitter/3.crow +++ /dev/null @@ -1,44 +0,0 @@ -<?xml version="1.0"?> -<VerticalStack Fit="true"> - <Widget CornerRadius="5" Height="10" Width="600" Background="vgradient|0:Transparent|0.5:White|1:Transparent"/> - <HorizontalStack Fit="true" HorizontalAlignment="Left"> - <Border Fit="true" CornerRadius="10" BorderWidth="1"> - <VerticalStack Margin="10"> - <CheckBox IsChecked="false" Caption="Check 1" Background="hgradient|0:LimeGreen|1:Transparent"/> - <CheckBox IsChecked="false" Caption="Check 2" Background="hgradient|0:LimeGreen|1:Transparent"/> - <CheckBox IsChecked="true" Caption="Check 3" Background="hgradient|0:LimeGreen|1:Transparent"/> - <CheckBox IsChecked="false" Caption="Check 4" Background="hgradient|0:LimeGreen|1:Transparent"/> - </VerticalStack> - </Border> - <Splitter/> - <Border Fit="true" CornerRadius="10" BorderWidth="1"> - <VerticalStack Margin="10"> - <RadioButton IsChecked="false" Caption="Choice 1" Background="hgradient|0:DarkRed|1:Transparent"/> - <Splitter/> - <RadioButton Width="Stretched" IsChecked="false" Caption="Choice 2" Background="hgradient|0:DarkRed|1:Transparent"/> - <RadioButton IsChecked="true" Caption="Choice 3" Background="hgradient|0:DarkRed|1:Transparent"/> - <RadioButton IsChecked="false" Caption="Choice 4" Background="hgradient|0:DarkRed|1:Transparent"/> - </VerticalStack> - </Border> - <Splitter Thickness="3" /> - <Border Fit="true" CornerRadius="10" BorderWidth="1" MaximumSize="150,150" MinimumSize="50,50"> - <VerticalStack Margin="10"> - <Label Text="label 1" Background="hgradient|0:Blue|1:Transparent"/> - <Label Text="label 2" Background="hgradient|0:Blue|1:Transparent"/> - <Label Text="label 3" Background="hgradient|0:Blue|1:Transparent"/> - <Label Text="label 4" Width="Stretched" Background="hgradient|0:Blue|1:Transparent"/> - </VerticalStack> - </Border> - <Splitter/> - <Border Fit="true" CornerRadius="10" BorderWidth="1"> - <VerticalStack Margin="10"> - <Button Caption="Button 1" Background="hgradient|0:Red|1:DarkRed" CornerRadius="5"/> - <Button Caption="Button 2" Background="hgradient|0:Green|1:Blue" CornerRadius="3"/> - <Button Caption="Button 3" Background="hgradient|0:DarkRed|1:Transparent" CornerRadius="0"/> - <Button Caption="Button 4" Background="hgradient|0:DarkRed|1:Transparent" CornerRadius="8"/> - </VerticalStack> - </Border> - <Splitter/> - </HorizontalStack> - <Widget CornerRadius="5" Height="10" Width="600" Background="vgradient|0:Transparent|0.5:White|1:Transparent"/> -</VerticalStack>
\ No newline at end of file diff --git a/Samples/common/ui/Interfaces/TabItem.template b/Samples/common/ui/Interfaces/TabItem.template deleted file mode 100644 index fd0f310d..00000000 --- a/Samples/common/ui/Interfaces/TabItem.template +++ /dev/null @@ -1,24 +0,0 @@ -<?xml version="1.0"?> -<GenericStack Orientation="Vertical" Spacing="0" - Background="{./Background}" - MouseEnter="{/caption.Foreground=White}" - MouseLeave="{/caption.Foreground=Grey}"> - <HorizontalStack Left="{./TabOffset}" - Name="TabTitle" - HorizontalAlignment="Left" - Height="{./TabHeight}" - Width="{./TabWidth}"> - <Label Name="caption" Text="{./Caption}" Foreground="Grey" Width="Stretched"/> - <Label Text="{./ViewIndex}" Foreground="Green"/> - <Label Text="{./TabOffset}" Foreground="Red"/> - <Border CornerRadius="5" BorderWidth="1" Foreground="Transparent" Height="12" Width="12" - MouseEnter="{Foreground=White}" MouseLeave="{Foreground=Transparent}"> - <Image Focusable="true" Name="Image" Margin="0" Width="Stretched" Height="Stretched" Path="#Crow.Icons.exit2.svg" - MouseClick="./butCloseTabClick"/> - </Border> - </HorizontalStack> - <Container Margin="20"> - <Container Background="DimGrey" Name="Content"/> - </Container> -</GenericStack> - diff --git a/Samples/common/ui/Interfaces/colorItem.crow b/Samples/common/ui/Interfaces/colorItem.crow index 06169f2b..1def3811 100644 --- a/Samples/common/ui/Interfaces/colorItem.crow +++ b/Samples/common/ui/Interfaces/colorItem.crow @@ -1,10 +1,10 @@ <?xml version="1.0"?> -<Border Foreground="Transparent" Focusable="true" HorizontalAlignment="Left" Height="Fit"> - <HorizontalStack Margin="1" Spacing="3" - MouseEnter="{Background=LightBlue}" - MouseLeave="{Background=Transparent}"> +<ListItem HorizontalAlignment="Left" Height="Fit" + Selected = "{Background=${ControlHighlight}}" + Unselected = "{Background=Transparent}"> + <HorizontalStack Margin="1" Spacing="3"> <Widget Height="12" Width="20" Background="{}" Margin="0" CornerRadius="5"/> <Label Text="{}" Margin="0" Width="Stretched"/> </HorizontalStack> -</Border> +</ListItem> |