aboutsummaryrefslogtreecommitdiffstatsci
path: root/Samples
diff options
context:
space:
mode:
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>2020-07-06 08:18:33 +0200
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>2020-07-06 08:18:33 +0200
commit819371cd4b13b34a3a3d68e73d2481d1cbb5d1dc (patch)
treee8f48fe0bfa792d18ace84e8604130354cf4a0bc /Samples
parent5f689a331911b6115f298cc56c89b9e188095f46 (diff)
list item
Diffstat (limited to 'Samples')
-rw-r--r--Samples/BasicTests/BasicTests.cs13
-rw-r--r--Samples/DebugLogAnalyzer/DbgEventWidget.cs143
-rw-r--r--Samples/DebugLogAnalyzer/DbgLogViewer.cs637
-rw-r--r--Samples/DebugLogAnalyzer/DebugLogAnalyzer.csproj9
-rw-r--r--Samples/DebugLogAnalyzer/Program.cs178
-rw-r--r--Samples/DebugLogAnalyzer/Properties/AssemblyInfo.cs5
-rw-r--r--Samples/DebugLogAnalyzer/ui/DbgEventTreeItems.itemp70
-rw-r--r--Samples/DebugLogAnalyzer/ui/DbgEvtTooltip.crow37
-rw-r--r--Samples/DebugLogAnalyzer/ui/dbglog.crow98
-rw-r--r--Samples/HelloWorld/HelloWorld.csproj15
-rw-r--r--Samples/HelloWorld/main.cs2
-rw-r--r--Samples/ShowCase/ShowCase.cs14
-rw-r--r--Samples/common/SampleBase.cs74
-rw-r--r--Samples/common/samples.style4
-rw-r--r--Samples/common/ui/Interfaces/CheckBox2.imlt4
-rw-r--r--Samples/common/ui/Interfaces/Divers/classBindings.crow9
-rw-r--r--Samples/common/ui/Interfaces/Divers/dbglog.crow99
-rw-r--r--Samples/common/ui/Interfaces/Divers/splitter0.crow7
-rw-r--r--Samples/common/ui/Interfaces/Splitter/1.crow30
-rw-r--r--Samples/common/ui/Interfaces/Splitter/3.crow44
-rw-r--r--Samples/common/ui/Interfaces/TabItem.template24
-rw-r--r--Samples/common/ui/Interfaces/colorItem.crow10
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>