aboutsummaryrefslogtreecommitdiffstatsci
diff options
context:
space:
mode:
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>2021-01-14 08:07:43 +0100
committerj-p <jp_bruyere@hotmail.com>2021-02-06 20:28:02 +0100
commit2ab44f600bd0ecab04d03ba08fdc17ea195babf2 (patch)
tree916e61f3a6776ea97f73d77ea8b601684c2ad5f2
parent0f08742ef206f006db97a8d2bc67b1c4cae34deb (diff)
label, cached line width in pixel in LineSpan struct, use stackalloc for a single utf8 conversion for size and print, perfs and samplebase
-rw-r--r--Crow/Crow.csproj4
-rw-r--r--Crow/Default.style5
-rw-r--r--Crow/src/DebugUtils/DebugLogger.cs22
-rw-r--r--Crow/src/Mono.Cairo/Context.cs5
-rw-r--r--Crow/src/Widgets/FileDialog.cs7
-rw-r--r--Crow/src/Widgets/Label.cs130
-rw-r--r--Crow/src/Widgets/OldLabel.cs842
-rw-r--r--Samples/BasicTests/BasicTests.cs22
-rw-r--r--Samples/BasicTests/BasicTests.csproj3
-rw-r--r--Samples/DebugLogAnalyzer/Program.cs2
-rw-r--r--Samples/PerfTests/Program.cs14
-rw-r--r--Samples/PerfTests/Properties/launchSettings.json2
-rw-r--r--Samples/ShowCase/ShowCase.cs9
-rw-r--r--Samples/common/SampleBase.cs21
-rw-r--r--Samples/common/ui/Interfaces/Divers/testVisibility.crow4
-rw-r--r--Samples/common/ui/Interfaces/Experimental/testDock2.crow26
-rw-r--r--Samples/common/ui/Interfaces/PerfLabels/0_single_Label.crow (renamed from Samples/common/ui/Interfaces/PerfLabels/0.crow)0
-rw-r--r--Samples/common/ui/Interfaces/PerfLabels/0_single_oldLabel.crow3
-rw-r--r--Samples/common/ui/Interfaces/PerfLabels/1.crow3
-rw-r--r--Samples/common/ui/Interfaces/PerfLabels/1_single_lab_update.crow (renamed from Samples/common/ui/Interfaces/PerfLabels/2.crow)0
-rw-r--r--Samples/common/ui/Interfaces/PerfLabels/1_single_old_update.crow3
-rw-r--r--Samples/common/ui/Interfaces/PerfLabels/2_labels_update.crow (renamed from Samples/common/ui/Interfaces/PerfLabels/labels.crow)24
-rw-r--r--Samples/common/ui/Interfaces/PerfLabels/2_old_labels_update.crow29
23 files changed, 1029 insertions, 151 deletions
diff --git a/Crow/Crow.csproj b/Crow/Crow.csproj
index 792794aa..ce2bd530 100644
--- a/Crow/Crow.csproj
+++ b/Crow/Crow.csproj
@@ -23,14 +23,14 @@
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591;1587;1570;1572;1573;1574</NoWarn>
- <DefineConstants>DESIGN_MODE;_MEASURE_TIME</DefineConstants>
+ <DefineConstants>DESIGN_MODE;MEASURE_TIME</DefineConstants>
<EnableDefaultItems>false</EnableDefaultItems>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<AppConfig>App.config</AppConfig>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugType>full</DebugType>
- <DefineConstants>$(DefineConstants);_DEBUG_LOG;DEBUG;TRACE;_DEBUG_DISPOSE;_DEBUG_BINDING;_DEBUG_CLIP_RECTANGLE</DefineConstants>
+ <DefineConstants>$(DefineConstants);_DEBUG;_DEBUG_LOG;TRACE;_DEBUG_DISPOSE;_DEBUG_BINDING;_DEBUG_CLIP_RECTANGLE</DefineConstants>
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
</PropertyGroup>
<ItemGroup Condition="$(TargetFramework.StartsWith('netstandard'))">
diff --git a/Crow/Default.style b/Crow/Default.style
index ae09ec1c..104b303c 100644
--- a/Crow/Default.style
+++ b/Crow/Default.style
@@ -74,6 +74,11 @@ Label {
Width = "Fit";
Margin = "0";
}
+OldLabel {
+ Height = "Fit";
+ Width = "Fit";
+ Margin = "0";
+}
TextBox {
Background = "White";
Foreground = "Black";
diff --git a/Crow/src/DebugUtils/DebugLogger.cs b/Crow/src/DebugUtils/DebugLogger.cs
index 0c3f38dc..ce0fa214 100644
--- a/Crow/src/DebugUtils/DebugLogger.cs
+++ b/Crow/src/DebugUtils/DebugLogger.cs
@@ -232,22 +232,29 @@ namespace Crow
parseTree (pc.getTemplateRoot, level + 1, y + 1);
}
}
+
+#endif
/// <summary>
/// Clear all recorded events from logger.
/// </summary>
- public static void Reset ()
- {
+ public static void Reset () {
+#if DEBUG_LOG
lock (logMutex) {
- startedEvents.Clear ();
+ startedEvents.Clear ();
events.Clear ();
chrono.Restart ();
}
+ Console.WriteLine ($"Crow Debug Log reseted");
+#else
+ Console.WriteLine ($"Logging disabled, compile Crow with DEBUG and DEBUG_LOG defined to enable logging.");
+#endif
}
/// <summary>
/// Save recorded events to disk
/// </summary>
- /// <param name="iface">Iface.</param>
- public static void save(Interface iface, string dbgLogFilePath = "debug.log") {
+ /// <param name="iface">Iface.</param>
+ public static void Save(Interface iface, string dbgLogFilePath = "debug.log") {
+#if DEBUG_LOG
lock (logMutex) {
foreach (Widget go in iface.GraphicTree)
@@ -266,6 +273,10 @@ namespace Crow
saveEventList (s, events);
}
}
+ Console.WriteLine ($"Crow Debug Log saved to: {dbgLogFilePath}");
+#else
+ Console.WriteLine ($"Compile Crow with DEBUG and DEBUG_LOG defined to enable logging. No log saved.");
+#endif
}
static void saveEventList (StreamWriter s, List<DbgEvent> evts, int level = 0)
@@ -278,7 +289,6 @@ namespace Crow
saveEventList (s, e.Events, level + 1);
}
}
-#endif
}
}
diff --git a/Crow/src/Mono.Cairo/Context.cs b/Crow/src/Mono.Cairo/Context.cs
index 57f6c517..9ac41f9f 100644
--- a/Crow/src/Mono.Cairo/Context.cs
+++ b/Crow/src/Mono.Cairo/Context.cs
@@ -907,6 +907,11 @@ namespace Crow.Cairo {
NativeMethods.cairo_text_extents (handle, ref bytes.Slice(0, encodedBytes + 1).GetPinnableReference(), out extents);
}
+ public void ShowText (Span<byte> bytes) =>
+ NativeMethods.cairo_show_text (handle, ref bytes.GetPinnableReference ());
+ public void TextExtents (Span<byte> bytes, out TextExtents extents) =>
+ NativeMethods.cairo_text_extents (handle, ref bytes.GetPinnableReference (), out extents);
+
public TextExtents GlyphExtents (Glyph[] glyphs)
{
diff --git a/Crow/src/Widgets/FileDialog.cs b/Crow/src/Widgets/FileDialog.cs
index 8c58e632..1a7ec842 100644
--- a/Crow/src/Widgets/FileDialog.cs
+++ b/Crow/src/Widgets/FileDialog.cs
@@ -106,10 +106,11 @@ namespace Crow
SelectedDirectory = e.NewValue.ToString();
}
public void goUpDirClick (object sender, MouseButtonEventArgs e){
- string root = Directory.GetDirectoryRoot(CurrentDirectory);
- if (CurrentDirectory == root)
+ string root = Directory.GetDirectoryRoot(CurrentDirectory);
+ DirectoryInfo parentDir = Directory.GetParent (CurrentDirectory);
+ if (parentDir == null)
return;
- CurrentDirectory = Directory.GetParent(CurrentDirectory).FullName;
+ CurrentDirectory = parentDir.FullName;
}
void onFileSelect(object sender, MouseButtonEventArgs e){
if (string.IsNullOrEmpty (SelectedFile))
diff --git a/Crow/src/Widgets/Label.cs b/Crow/src/Widgets/Label.cs
index 4d4f7f02..5724c7ff 100644
--- a/Crow/src/Widgets/Label.cs
+++ b/Crow/src/Widgets/Label.cs
@@ -16,13 +16,15 @@ namespace Crow {
public readonly int Start;
public readonly int End;
public readonly int EndIncludingLineBreak;
+ public int LengthInPixel;
public int Length => End - Start;
public int LengthIncludingLineBreak => EndIncludingLineBreak - Start;
public int LineBreakLength => EndIncludingLineBreak - End;
public LineSpan (int start, int end, int endIncludingLineBreak) {
Start = start;
End = end;
- EndIncludingLineBreak = endIncludingLineBreak;
+ EndIncludingLineBreak = endIncludingLineBreak;
+ LengthInPixel = -1;
}
public LineSpan WithStartOffset (int start) => new LineSpan (Start + start, End, EndIncludingLineBreak);
/*public ReadOnlySpan<char> GetSubString (string str) {
@@ -150,7 +152,7 @@ namespace Crow {
_text = value;
- lines = getLines;
+ getLines ();
OnTextChanged (this, new TextChangeEventArgs (Text));
RegisterForGraphicUpdate ();
@@ -242,8 +244,8 @@ namespace Crow {
set {
if (value == _currentLine)
return;
- if (value >= lines.Count)
- _currentLine = lines.Count-1;
+ if (value >= lines.Length)
+ _currentLine = lines.Length-1;
else if (value < 0)
_currentLine = 0;
else
@@ -329,30 +331,33 @@ namespace Crow {
[XmlIgnore]public bool selectionIsEmpty
{ get { return SelRelease < 0; } }
- List<LineSpan> lines;
- List<LineSpan> getLines {
- get {
- if (string.IsNullOrEmpty(_text))
- return new List<LineSpan> (new LineSpan[] { new LineSpan (0, 0, 0) });
- if (!_multiline)
- return new List<LineSpan> (new LineSpan[] { new LineSpan (0, _text.Length, _text.Length) });
- List<LineSpan> lines = new List<LineSpan> ();
- bool lineBreak = false;
- int start = 0, end = 0;
- for (int i = 0; i < _text.Length; i++) {
- if (_text[i].IsAnyLineBreakCharacter()) {
- if (lineBreak)
- continue;
- lineBreak = true;
- end = i;
- }else if (lineBreak) {
- lines.Add (new LineSpan (start, end, i));
- start = end = i;
- lineBreak = false;
- }
- }
- return lines;
+ LineSpan[] lines;
+ void getLines () {
+ if (string.IsNullOrEmpty (_text)) {
+ lines = new LineSpan[] { new LineSpan (0, 0, 0) };
+ return;
}
+ if (!_multiline) {
+ lines = new LineSpan[] { new LineSpan (0, _text.Length, _text.Length) };
+ return;
+ }
+
+ List<LineSpan> _lines = new List<LineSpan> ();
+ bool lineBreak = false;
+ int start = 0, end = 0;
+ for (int i = 0; i < _text.Length; i++) {
+ if (_text[i].IsAnyLineBreakCharacter()) {
+ if (lineBreak)
+ continue;
+ lineBreak = true;
+ end = i;
+ }else if (lineBreak) {
+ _lines.Add (new LineSpan (start, end, i));
+ start = end = i;
+ lineBreak = false;
+ }
+ }
+ lines = _lines.ToArray();
}
/// <summary>
/// Moves cursor one char to the left.
@@ -376,7 +381,7 @@ namespace Crow {
public bool MoveRight(){
int tmp = _currentCol + 1;
if (tmp > lines [_currentLine].Length){
- if (CurrentLine == lines.Count - 1)
+ if (CurrentLine == lines.Length - 1)
return false;
CurrentLine++;
CurrentColumn = 0;
@@ -409,7 +414,7 @@ namespace Crow {
{
if (selectionIsEmpty) {
if (CurrentColumn == 0) {
- if (CurrentLine == 0 && lines.Count == 1)
+ if (CurrentLine == 0 && lines.Length == 1)
return;
CurrentLine--;
CurrentColumn = lines [CurrentLine].Length;
@@ -485,7 +490,8 @@ namespace Crow {
public override int measureRawSize(LayoutingType lt)
{
if (lines == null)
- lines = getLines;
+ getLines ();
+
if (!textMeasureIsUpToDate) {
using (Context gr = new Context (IFace.surf)) {
//Cairo.FontFace cf = gr.GetContextFontFace ();
@@ -498,12 +504,14 @@ namespace Crow {
fe = gr.FontExtents;
te = new TextExtents ();
- cachedTextSize.Height = (int)Math.Ceiling ((fe.Ascent+fe.Descent) * Math.Max (1, lines.Count));
+ cachedTextSize.Height = (int)Math.Ceiling ((fe.Ascent+fe.Descent) * Math.Max (1, lines.Length));
try {
TextExtents tmp = default;
- for (int i = 0; i < lines.Count; i++) {
+ for (int i = 0; i < lines.Length; i++) {
gr.TextExtents (_text.GetLine (lines[i]), Interface.TAB_SIZE, out tmp);
+ if (lines[i].LengthInPixel < 0)
+ lines[i].LengthInPixel = (int)tmp.XAdvance;
if (tmp.XAdvance > te.XAdvance)
te = tmp;
}
@@ -659,33 +667,47 @@ namespace Crow {
gr.Restore ();
return;
}
- for (int i = 0; i < lines.Count; i++) {
+
+ Foreground.SetAsSource (IFace, gr);
+
+ TextExtents extents;
+ Span<byte> bytes = stackalloc byte[128];
+
+ for (int i = 0; i < lines.Length; i++) {
if (lines[i].Length == 0)
continue;
- ReadOnlySpan<char> chars = _text.GetLine (lines[i]);
+
+ int size = lines[i].Length * 4 + 1;
+ if (bytes.Length < size)
+ bytes = size > 512 ? new byte[size] : stackalloc byte[size];
+
+ int encodedBytes = Encoding.UTF8.GetBytes (_text.GetLine (lines[i]), bytes);
+ bytes[encodedBytes] = 0;
+ if (lines[i].LengthInPixel < 0) {
+ gr.TextExtents (bytes.Slice (0, encodedBytes), out extents);
+ lines[i].LengthInPixel = (int)extents.XAdvance;
+ }
//string l = lines [i].Replace ("\t", new String (' ', Interface.TAB_SIZE));
- int lineLength = (int)gr.TextExtents (chars, Interface.TAB_SIZE).XAdvance;
+
Rectangle lineRect = new Rectangle (
rText.X,
rText.Y + i * (int)(fe.Ascent+fe.Descent),
- lineLength,
+ lines[i].LengthInPixel,
(int)(fe.Ascent+fe.Descent));
-// if (TextAlignment == Alignment.Center ||
-// TextAlignment == Alignment.Top ||
-// TextAlignment == Alignment.Bottom)
-// lineRect.X += (rText.Width - lineLength) / 2;
-// else if (TextAlignment == Alignment.Right ||
-// TextAlignment == Alignment.TopRight ||
-// TextAlignment == Alignment.BottomRight)
-// lineRect.X += (rText.Width - lineLength);
+ // if (TextAlignment == Alignment.Center ||
+ // TextAlignment == Alignment.Top ||
+ // TextAlignment == Alignment.Bottom)
+ // lineRect.X += (rText.Width - lineLength) / 2;
+ // else if (TextAlignment == Alignment.Right ||
+ // TextAlignment == Alignment.TopRight ||
+ // TextAlignment == Alignment.BottomRight)
+ // lineRect.X += (rText.Width - lineLength);
- Foreground.SetAsSource (IFace, gr);
gr.MoveTo (lineRect.X,(double)rText.Y + fe.Ascent + (fe.Ascent+fe.Descent) * i) ;
-
- gr.ShowText (chars, Interface.TAB_SIZE);
- gr.Fill ();
+ gr.ShowText (bytes.Slice (0, encodedBytes));
+ //gr.Fill ();
if (Selectable) {
if (SelRelease >= 0 && i >= selectionStart.Y && i <= selectionEnd.Y) {
@@ -706,7 +728,7 @@ namespace Crow {
selRect.Left += cpStart;
}
if (i == selectionEnd.Y)
- selRect.Width -= (lineLength - cpEnd);
+ selRect.Width -= (lines[i].LengthInPixel - cpEnd);
gr.Rectangle (selRect);
gr.FillPreserve ();
@@ -714,9 +736,11 @@ namespace Crow {
gr.Clip ();
gr.SetSource (SelectionForeground);
gr.MoveTo (lineRect.X, rText.Y + fe.Ascent + (fe.Ascent+fe.Descent) * i);
- gr.ShowText (chars, Interface.TAB_SIZE);
+ gr.ShowText (bytes.Slice (0, encodedBytes));
gr.Fill ();
gr.Restore ();
+
+ Foreground.SetAsSource (IFace, gr);
}
}
}
@@ -741,7 +765,7 @@ namespace Crow {
if (!_selectable)
return;
SelBegin = new Point(0,0);
- SelRelease = new Point (lines.LastOrDefault ().Length, lines.Count-1);
+ SelRelease = new Point (lines.LastOrDefault ().Length, lines.Length-1);
RegisterForRedraw ();
}
protected override void onUnfocused (object sender, EventArgs e)
@@ -818,8 +842,8 @@ namespace Crow {
CurrentLine = (int)(mouseLocalPos.Y / (fe.Ascent+fe.Descent));
//fix cu
- if (CurrentLine >= lines.Count)
- CurrentLine = lines.Count - 1;
+ if (CurrentLine >= lines.Length)
+ CurrentLine = lines.Length - 1;
LineSpan ls = lines[CurrentLine];
ReadOnlySpan<char> curLine = _text.GetLine (lines[CurrentLine]);
diff --git a/Crow/src/Widgets/OldLabel.cs b/Crow/src/Widgets/OldLabel.cs
new file mode 100644
index 00000000..080bc5a0
--- /dev/null
+++ b/Crow/src/Widgets/OldLabel.cs
@@ -0,0 +1,842 @@
+// Copyright (c) 2013-2019 Bruyère Jean-Philippe 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.Linq;
+using Crow.Cairo;
+using System.Text.RegularExpressions;
+using System.ComponentModel;
+
+namespace Crow {
+ public class OldLabel : Widget
+ {
+ #region CTOR
+ protected OldLabel () {}
+ public OldLabel(Interface iface, string style = null) : base (iface, style) { }
+ #endregion
+
+ public event EventHandler<TextChangeEventArgs> TextChanged;
+
+ public virtual void OnTextChanged(Object sender, TextChangeEventArgs e)
+ {
+ textMeasureIsUpToDate = false;
+ NotifyValueChanged ("Text", Text);
+ TextChanged.Raise (this, e);
+ }
+ //TODO:change protected to private
+
+ #region private and protected fields
+ string _text = "label";
+ Alignment _textAlignment;
+ bool horizontalStretch;
+ bool verticalStretch;
+ bool _selectable;
+ bool _multiline;
+ Color selBackground;
+ Color selForeground;
+ Point mouseLocalPos = -1;//mouse coord in widget space, filled only when clicked
+ int _currentCol; //0 based cursor position in string
+ int _currentLine;
+ Point _selBegin = -1; //selection start (row,column)
+ Point _selRelease = -1; //selection end (row,column)
+ double textCursorPos; //cursor position in cairo units in widget client coord.
+ double SelStartCursorPos = -1;
+ double SelEndCursorPos = -1;
+ bool SelectionInProgress = false;
+
+ protected Rectangle rText;
+ protected float widthRatio = 1f;
+ protected float heightRatio = 1f;
+ protected FontExtents fe;
+ protected TextExtents te;
+ #endregion
+
+ [DefaultValue("SteelBlue")]
+ public virtual Color SelectionBackground {
+ get { return selBackground; }
+ set {
+ if (selBackground == value)
+ return;
+ selBackground = value;
+ NotifyValueChangedAuto (selBackground);
+ RegisterForRedraw ();
+ }
+ }
+ [DefaultValue("White")]
+ public virtual Color SelectionForeground {
+ get { return selForeground; }
+ set {
+ if (selForeground == value)
+ return;
+ selForeground = value;
+ NotifyValueChangedAuto (selForeground);
+ RegisterForRedraw ();
+ }
+ }
+ [DefaultValue(Alignment.Left)]
+ public Alignment TextAlignment
+ {
+ get { return _textAlignment; }
+ set {
+ if (value == _textAlignment)
+ return;
+ _textAlignment = value;
+ RegisterForRedraw ();
+ NotifyValueChangedAuto (_textAlignment);
+ }
+ }
+ [DefaultValue(false)]
+ public virtual bool HorizontalStretch {
+ get { return horizontalStretch; }
+ set {
+ if (horizontalStretch == value)
+ return;
+ horizontalStretch = value;
+ RegisterForRedraw ();
+ NotifyValueChangedAuto (horizontalStretch);
+ }
+ }
+ [DefaultValue(false)]
+ public virtual bool VerticalStretch {
+ get { return verticalStretch; }
+ set {
+ if (verticalStretch == value)
+ return;
+ verticalStretch = value;
+ RegisterForRedraw ();
+ NotifyValueChangedAuto (verticalStretch);
+ }
+ }
+ [DefaultValue("label")]
+ public string Text
+ {
+ get {
+ return lines == null ?
+ _text : lines.Aggregate((i, j) => i + Interface.LineBreak + j);
+ }
+ set
+ {
+ if (string.Equals (value, _text, StringComparison.Ordinal))
+ return;
+
+ _text = value;
+
+ if (string.IsNullOrEmpty(_text))
+ _text = "";
+
+ lines = getLines;
+
+ OnTextChanged (this, new TextChangeEventArgs (Text));
+ RegisterForGraphicUpdate ();
+ }
+ }
+ [DefaultValue(false)]
+ public bool Selectable
+ {
+ get { return _selectable; }
+ set
+ {
+ if (value == _selectable)
+ return;
+ _selectable = value;
+ NotifyValueChangedAuto (_selectable);
+ SelBegin = -1;
+ SelRelease = -1;
+ RegisterForRedraw ();
+ }
+ }
+ [DefaultValue(false)]
+ public bool Multiline
+ {
+ get { return _multiline; }
+ set
+ {
+ if (value == _multiline)
+ return;
+ _multiline = value;
+ NotifyValueChangedAuto (_multiline);
+ RegisterForGraphicUpdate();
+ }
+ }
+ [DefaultValue(0)]
+ public int CurrentColumn{
+ get { return _currentCol; }
+ set {
+ if (value == _currentCol)
+ return;
+ if (value < 0)
+ _currentCol = 0;
+ else if (value > lines [_currentLine].Length)
+ _currentCol = lines [_currentLine].Length;
+ else
+ _currentCol = value;
+ NotifyValueChangedAuto (_currentCol);
+
+ Rectangle cb = ClientRectangle;
+
+ if (Width == Measure.Fit || cb.Width >= cachedTextSize.Width) {
+ xTranslation = 0;
+ return;
+ }
+ int xpos = xposition;
+ if (xTranslation + xpos > cb.Width)
+ xTranslation = cb.Width - xpos;
+ else if (xpos < -xTranslation)
+ xTranslation = -xpos;
+ RegisterForRedraw ();
+ }
+ }
+ int xTranslation = 0;
+ int xposition {
+ get {
+ using (Context gr = new Context (IFace.surf)) {
+ //Cairo.FontFace cf = gr.GetContextFontFace ();
+ gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
+ gr.SetFontSize (Font.Size);
+ gr.FontOptions = Interface.FontRenderingOptions;
+ gr.Antialias = Interface.Antialias;
+ try {
+ string l = lines [_currentLine];
+ if (_currentCol < l.Length)
+ l = l.Remove (Math.Min (_currentCol, l.Length));
+ l = l.Replace ("\t", new String (' ', Interface.TAB_SIZE));
+ return (int)Math.Ceiling (gr.TextExtents (l).XAdvance);
+ } catch {
+ System.Diagnostics.Debug.WriteLine ("xpos measuring fault in label");
+ return 0;
+ }
+ }
+ }
+ }
+
+ [DefaultValue(0)]
+ public int CurrentLine{
+ get { return _currentLine; }
+ set {
+ if (value == _currentLine)
+ return;
+ if (value >= lines.Count)
+ _currentLine = lines.Count-1;
+ else if (value < 0)
+ _currentLine = 0;
+ else
+ _currentLine = value;
+ //force recheck of currentCol for bounding
+ int cc = _currentCol;
+ _currentCol = 0;
+ CurrentColumn = cc;
+ NotifyValueChangedAuto (_currentLine);
+ }
+ }
+ [XmlIgnore]public Point CurrentPosition {
+ get { return new Point(_currentCol, CurrentLine); }
+ }
+ //TODO:using HasFocus for drawing selection cause SelBegin and Release binding not to work
+ /// <summary>
+ /// Selection begin position in char units
+ /// </summary>
+ [DefaultValue("-1")]
+ public Point SelBegin {
+ get {
+ return _selBegin;
+ }
+ set {
+ if (value == _selBegin)
+ return;
+ _selBegin = value;
+ NotifyValueChangedAuto (_selBegin);
+ NotifyValueChanged ("SelectedText", SelectedText);
+ }
+ }
+ [DefaultValue("-1")]
+ public Point SelRelease {
+ get {
+ return _selRelease;
+ }
+ set {
+ if (value == _selRelease)
+ return;
+ _selRelease = value;
+ NotifyValueChangedAuto (_selRelease);
+ NotifyValueChanged ("SelectedText", SelectedText);
+ }
+ }
+ /// <summary>
+ /// return char at CurrentLine, CurrentColumn
+ /// </summary>
+ [XmlIgnore]protected Char CurrentChar
+ {
+ get {
+ return lines [CurrentLine][CurrentColumn];
+ }
+ }
+ /// <summary>
+ /// ordered selection start and end positions in char units
+ /// </summary>
+ [XmlIgnore]protected Point selectionStart
+ {
+ get {
+ return SelRelease < 0 || SelBegin.Y < SelRelease.Y ? SelBegin :
+ SelBegin.Y > SelRelease.Y ? SelRelease :
+ SelBegin.X < SelRelease.X ? SelBegin : SelRelease;
+ }
+ }
+ [XmlIgnore]public Point selectionEnd
+ {
+ get {
+ return SelRelease < 0 || SelBegin.Y > SelRelease.Y ? SelBegin :
+ SelBegin.Y < SelRelease.Y ? SelRelease :
+ SelBegin.X > SelRelease.X ? SelBegin : SelRelease;
+ }
+ }
+ [XmlIgnore]public string SelectedText
+ {
+ get {
+ if (SelRelease < 0 || SelBegin < 0)
+ return "";
+ if (selectionStart.Y == selectionEnd.Y)
+ return lines [selectionStart.Y].Substring (selectionStart.X, selectionEnd.X - selectionStart.X);
+ string tmp = "";
+ tmp = lines [selectionStart.Y].Substring (selectionStart.X);
+ for (int l = selectionStart.Y + 1; l < selectionEnd.Y; l++) {
+ tmp += Interface.LineBreak + lines [l];
+ }
+ tmp += Interface.LineBreak + lines [selectionEnd.Y].Substring (0, selectionEnd.X);
+ return tmp;
+ }
+ }
+ [XmlIgnore]public bool selectionIsEmpty
+ { get { return SelRelease < 0; } }
+
+ List<string> lines;
+ List<string> getLines {
+ get {
+ return _multiline ?
+ Regex.Split (_text, "\r\n|\r|\n|\\\\n").ToList() :
+ new List<string>(new string[] { _text });
+ }
+ }
+ /// <summary>
+ /// Moves cursor one char to the left.
+ /// </summary>
+ /// <returns><c>true</c> if move succeed</returns>
+ public bool MoveLeft(){
+ int tmp = _currentCol - 1;
+ if (tmp < 0) {
+ if (_currentLine == 0)
+ return false;
+ CurrentLine--;
+ CurrentColumn = int.MaxValue;
+ } else
+ CurrentColumn = tmp;
+ return true;
+ }
+ /// <summary>
+ /// Moves cursor one char to the right.
+ /// </summary>
+ /// <returns><c>true</c> if move succeed</returns>
+ public bool MoveRight(){
+ int tmp = _currentCol + 1;
+ if (tmp > lines [_currentLine].Length){
+ if (CurrentLine == lines.Count - 1)
+ return false;
+ CurrentLine++;
+ CurrentColumn = 0;
+ } else
+ CurrentColumn = tmp;
+ return true;
+ }
+ public void GotoWordStart(){
+ CurrentColumn--;
+ //skip white spaces
+ while (!char.IsLetterOrDigit (this.CurrentChar) && CurrentColumn > 0)
+ CurrentColumn--;
+ while (char.IsLetterOrDigit (lines [CurrentLine] [CurrentColumn]) && CurrentColumn > 0)
+ CurrentColumn--;
+ if (!char.IsLetterOrDigit (this.CurrentChar))
+ CurrentColumn++;
+ }
+ public void GotoWordEnd(){
+ //skip white spaces
+ if (CurrentColumn >= lines [CurrentLine].Length - 1)
+ return;
+ while (!char.IsLetterOrDigit (this.CurrentChar) && CurrentColumn < lines [CurrentLine].Length-1)
+ CurrentColumn++;
+ while (char.IsLetterOrDigit (this.CurrentChar) && CurrentColumn < lines [CurrentLine].Length-1)
+ CurrentColumn++;
+ if (char.IsLetterOrDigit (this.CurrentChar))
+ CurrentColumn++;
+ }
+ public void DeleteChar()
+ {
+ if (selectionIsEmpty) {
+ if (CurrentColumn == 0) {
+ if (CurrentLine == 0 && lines.Count == 1)
+ return;
+ CurrentLine--;
+ CurrentColumn = lines [CurrentLine].Length;
+ lines [CurrentLine] += lines [CurrentLine + 1];
+ lines.RemoveAt (CurrentLine + 1);
+
+ OnTextChanged (this, new TextChangeEventArgs (Text));
+ return;
+ }
+ CurrentColumn--;
+ lines [CurrentLine] = lines [CurrentLine].Remove (CurrentColumn, 1);
+ } else {
+ int linesToRemove = selectionEnd.Y - selectionStart.Y + 1;
+ int l = selectionStart.Y;
+
+ if (linesToRemove > 0) {
+ lines [l] = lines [l].Remove (selectionStart.X, lines [l].Length - selectionStart.X) +
+ lines [selectionEnd.Y].Substring (selectionEnd.X, lines [selectionEnd.Y].Length - selectionEnd.X);
+ l++;
+ for (int c = 0; c < linesToRemove-1; c++)
+ lines.RemoveAt (l);
+ CurrentLine = selectionStart.Y;
+ CurrentColumn = selectionStart.X;
+ } else
+ lines [l] = lines [l].Remove (selectionStart.X, selectionEnd.X - selectionStart.X);
+ CurrentColumn = selectionStart.X;
+ SelBegin = -1;
+ SelRelease = -1;
+ }
+ OnTextChanged (this, new TextChangeEventArgs (Text));
+ }
+ /// <summary>
+ /// Insert new string at caret position, should be sure no line break is inside.
+ /// </summary>
+ /// <param name="str">String.</param>
+ protected void Insert(string str)
+ {
+ if (!selectionIsEmpty)
+ this.DeleteChar ();
+ if (_multiline) {
+ string[] strLines = Regex.Split (str, "\r\n|\r|\n|" + @"\\n").ToArray();
+ lines [CurrentLine] = lines [CurrentLine].Insert (CurrentColumn, strLines[0]);
+ CurrentColumn += strLines[0].Length;
+ for (int i = 1; i < strLines.Length; i++) {
+ InsertLineBreak ();
+ lines [CurrentLine] = lines [CurrentLine].Insert (CurrentColumn, strLines[i]);
+ CurrentColumn += strLines[i].Length;
+ }
+ } else {
+ lines [CurrentLine] = lines [CurrentLine].Insert (CurrentColumn, str);
+ CurrentColumn += str.Length;
+ }
+ OnTextChanged (this, new TextChangeEventArgs (Text));
+ }
+ /// <summary>
+ /// Insert a line break.
+ /// </summary>
+ protected void InsertLineBreak()
+ {
+ lines.Insert(CurrentLine + 1, lines[CurrentLine].Substring(CurrentColumn));
+ lines [CurrentLine] = lines [CurrentLine].Substring (0, CurrentColumn);
+ CurrentLine++;
+ CurrentColumn = 0;
+ OnTextChanged (this, new TextChangeEventArgs (Text));
+ }
+ bool textMeasureIsUpToDate = false;
+ Size cachedTextSize = default(Size);
+
+ #region GraphicObject overrides
+ public override int measureRawSize(LayoutingType lt)
+ {
+ if (lines == null)
+ lines = getLines;
+ if (!textMeasureIsUpToDate) {
+ using (Context gr = new Context (IFace.surf)) {
+ //Cairo.FontFace cf = gr.GetContextFontFace ();
+
+ gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
+ gr.SetFontSize (Font.Size);
+ gr.FontOptions = Interface.FontRenderingOptions;
+ gr.Antialias = Interface.Antialias;
+
+ fe = gr.FontExtents;
+ te = new TextExtents ();
+
+ cachedTextSize.Height = (int)Math.Ceiling ((fe.Ascent+fe.Descent) * Math.Max (1, lines.Count));
+
+ try {
+ for (int i = 0; i < lines.Count; i++) {
+ string l = lines[i].Replace ("\t", new String (' ', Interface.TAB_SIZE));
+
+ TextExtents tmp = gr.TextExtents (l);
+
+ if (tmp.XAdvance > te.XAdvance)
+ te = tmp;
+ }
+ cachedTextSize.Width = (int)Math.Ceiling (te.XAdvance);
+ textMeasureIsUpToDate = true;
+ } catch {
+ return -1;
+ }
+ }
+ }
+ return Margin * 2 + (lt == LayoutingType.Height ? cachedTextSize.Height : cachedTextSize.Width);
+ }
+ protected override void onDraw (Context gr)
+ {
+ base.onDraw (gr);
+
+ gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
+ gr.SetFontSize (Font.Size);
+ gr.FontOptions = Interface.FontRenderingOptions;
+ gr.Antialias = Interface.Antialias;
+
+ gr.Save ();
+ gr.Translate (xTranslation, 0);
+
+ rText = new Rectangle(new Size(
+ measureRawSize(LayoutingType.Width), measureRawSize(LayoutingType.Height)));
+ rText.Width -= 2 * Margin;
+ rText.Height -= 2 * Margin;
+
+ widthRatio = 1f;
+ heightRatio = 1f;
+
+ Rectangle cb = ClientRectangle;
+
+ rText.X = cb.X;
+ rText.Y = cb.Y;
+
+ if (horizontalStretch) {
+ widthRatio = (float)cb.Width / (float)rText.Width;
+ if (!verticalStretch)
+ heightRatio = widthRatio;
+ }
+
+ if (verticalStretch) {
+ heightRatio = (float)cb.Height / (float)rText.Height;
+ if (!horizontalStretch)
+ widthRatio = heightRatio;
+ }
+
+ rText.Width = (int)(widthRatio * (float)rText.Width);
+ rText.Height = (int)(heightRatio * (float)rText.Height);
+
+ switch (TextAlignment)
+ {
+ case Alignment.TopLeft: //ok
+ rText.X = cb.X;
+ rText.Y = cb.Y;
+ break;
+ case Alignment.Top: //ok
+ rText.Y = cb.Y;
+ rText.X = cb.X + cb.Width / 2 - rText.Width / 2;
+ break;
+ case Alignment.TopRight: //ok
+ rText.Y = cb.Y;
+ rText.X = cb.Right - rText.Width;
+ break;
+ case Alignment.Left://ok
+ rText.X = cb.X;
+ rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
+ break;
+ case Alignment.Right://ok
+ rText.X = cb.X + cb.Width - rText.Width;
+ rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
+ break;
+ case Alignment.Bottom://ok
+ rText.X = cb.Width / 2 - rText.Width / 2;
+ rText.Y = cb.Height - rText.Height;
+ break;
+ case Alignment.BottomLeft://ok
+ rText.X = cb.X;
+ rText.Y = cb.Bottom - rText.Height;
+ break;
+ case Alignment.BottomRight://ok
+ rText.Y = cb.Bottom - rText.Height;
+ rText.X = cb.Right - rText.Width;
+ break;
+ case Alignment.Center://ok
+ rText.X = cb.X + cb.Width / 2 - rText.Width / 2;
+ //rText.Y = cb.Y + cb.Height / 2 - rText.Height / 2;
+ rText.Y = cb.Y + (int)Math.Floor((double)cb.Height / 2.0 - (double)rText.Height / 2.0);
+ break;
+ }
+
+ //gr.FontMatrix = new Matrix(widthRatio * (float)Font.Size, 0, 0, heightRatio * (float)Font.Size, 0, 0);
+ fe = gr.FontExtents;
+
+ #region draw text cursor
+ if (HasFocus && Selectable)
+ {
+ if (mouseLocalPos >= 0)
+ {
+ computeTextCursor(gr);
+
+ if (SelectionInProgress)
+ {
+ if (SelBegin < 0){
+ SelBegin = new Point(CurrentColumn, CurrentLine);
+ SelStartCursorPos = textCursorPos;
+ SelRelease = -1;
+ }else{
+ SelRelease = new Point(CurrentColumn, CurrentLine);
+ if (SelRelease == SelBegin)
+ SelRelease = -1;
+ else
+ SelEndCursorPos = textCursorPos;
+ }
+ }else
+ computeTextCursorPosition(gr);
+ }else
+ computeTextCursorPosition(gr);
+
+ Foreground.SetAsSource (IFace, gr);
+ gr.LineWidth = 1.0;
+ gr.MoveTo (0.5 + textCursorPos + rText.X, rText.Y + CurrentLine * (fe.Ascent+fe.Descent));
+ gr.LineTo (0.5 + textCursorPos + rText.X, rText.Y + (CurrentLine + 1) * (fe.Ascent+fe.Descent));
+ gr.Stroke();
+ }
+ #endregion
+
+ //****** debug selection *************
+// if (SelRelease >= 0) {
+// new SolidColor(Color.DarkGreen).SetAsSource(gr);
+// Rectangle R = new Rectangle (
+// rText.X + (int)SelEndCursorPos - 3,
+// rText.Y + (int)(SelRelease.Y * (fe.Ascent+fe.Descent)),
+// 6,
+// (int)(fe.Ascent+fe.Descent));
+// gr.Rectangle (R);
+// gr.Fill ();
+// }
+// if (SelBegin >= 0) {
+// new SolidColor(Color.DarkRed).SetAsSource(gr);
+// Rectangle R = new Rectangle (
+// rText.X + (int)SelStartCursorPos - 3,
+// rText.Y + (int)(SelBegin.Y * (fe.Ascent+fe.Descent)),
+// 6,
+// (int)(fe.Ascent+fe.Descent));
+// gr.Rectangle (R);
+// gr.Fill ();
+// }
+ //*******************
+
+ for (int i = 0; i < lines.Count; i++) {
+ string l = lines [i].Replace ("\t", new String (' ', Interface.TAB_SIZE));
+ int lineLength = (int)gr.TextExtents (l).XAdvance;
+ Rectangle lineRect = new Rectangle (
+ rText.X,
+ rText.Y + i * (int)(fe.Ascent+fe.Descent),
+ lineLength,
+ (int)(fe.Ascent+fe.Descent));
+
+// if (TextAlignment == Alignment.Center ||
+// TextAlignment == Alignment.Top ||
+// TextAlignment == Alignment.Bottom)
+// lineRect.X += (rText.Width - lineLength) / 2;
+// else if (TextAlignment == Alignment.Right ||
+// TextAlignment == Alignment.TopRight ||
+// TextAlignment == Alignment.BottomRight)
+// lineRect.X += (rText.Width - lineLength);
+ if (string.IsNullOrWhiteSpace (l))
+ continue;
+
+ Foreground.SetAsSource (IFace, gr);
+ gr.MoveTo (lineRect.X,(double)rText.Y + fe.Ascent + (fe.Ascent+fe.Descent) * i) ;
+
+ gr.ShowText (l);
+ gr.Fill ();
+
+ if (Selectable) {
+ if (SelRelease >= 0 && i >= selectionStart.Y && i <= selectionEnd.Y) {
+ gr.SetSource (selBackground);
+
+ Rectangle selRect = lineRect;
+
+ int cpStart = (int)SelStartCursorPos,
+ cpEnd = (int)SelEndCursorPos;
+
+ if (SelBegin.Y > SelRelease.Y) {
+ cpStart = cpEnd;
+ cpEnd = (int)SelStartCursorPos;
+ }
+
+ if (i == selectionStart.Y) {
+ selRect.Width -= cpStart;
+ selRect.Left += cpStart;
+ }
+ if (i == selectionEnd.Y)
+ selRect.Width -= (lineLength - cpEnd);
+
+ gr.Rectangle (selRect);
+ gr.FillPreserve ();
+ gr.Save ();
+ gr.Clip ();
+ gr.SetSource (SelectionForeground);
+ gr.MoveTo (lineRect.X, rText.Y + fe.Ascent + (fe.Ascent+fe.Descent) * i);
+ gr.ShowText (l);
+ gr.Fill ();
+ gr.Restore ();
+ }
+ }
+ }
+
+ gr.Restore ();
+ }
+ #endregion
+
+ #region Mouse handling
+ void updatemouseLocalPos(Point mpos){
+ mouseLocalPos = mpos - ScreenCoordinates(Slot).TopLeft - ClientRectangle.TopLeft;
+ mouseLocalPos.X -= xTranslation;
+ if (mouseLocalPos.X < 0)
+ mouseLocalPos.X = 0;
+ if (mouseLocalPos.Y < 0)
+ mouseLocalPos.Y = 0;
+ }
+ protected override void onFocused (object sender, EventArgs e)
+ {
+ base.onFocused (sender, e);
+
+ if (!_selectable)
+ return;
+ SelBegin = new Point(0,0);
+ SelRelease = new Point (lines.LastOrDefault ().Length, lines.Count-1);
+ RegisterForRedraw ();
+ }
+ protected override void onUnfocused (object sender, EventArgs e)
+ {
+ base.onUnfocused (sender, e);
+
+ SelBegin = -1;
+ SelRelease = -1;
+ RegisterForRedraw ();
+ }
+ public override void onMouseMove (object sender, MouseMoveEventArgs e)
+ {
+ base.onMouseMove (sender, e);
+
+ if (!(SelectionInProgress && HasFocus && _selectable))
+ return;
+
+ updatemouseLocalPos (e.Position);
+
+ RegisterForRedraw();
+ }
+ public override void onMouseDown (object sender, MouseButtonEventArgs e)
+ {
+ if (HasFocus) {
+ if (_selectable) {
+ updatemouseLocalPos (e.Position);
+ SelBegin = -1;
+ SelRelease = -1;
+ SelectionInProgress = true;
+ RegisterForRedraw ();//TODO:should put it in properties
+ }
+ }
+
+ //done at the end to set 'hasFocus' value after testing it
+ base.onMouseDown (sender, e);
+ }
+ public override void onMouseUp (object sender, MouseButtonEventArgs e)
+ {
+ base.onMouseUp (sender, e);
+ if (!(HasFocus || _selectable))
+ return;
+ if (!SelectionInProgress)
+ return;
+
+ updatemouseLocalPos (e.Position);
+ SelectionInProgress = false;
+ RegisterForRedraw ();
+ }
+ public override void onMouseDoubleClick (object sender, MouseButtonEventArgs e)
+ {
+ base.onMouseDoubleClick (sender, e);
+ if (!(this.HasFocus || _selectable))
+ return;
+
+ GotoWordStart ();
+ SelBegin = CurrentPosition;
+ GotoWordEnd ();
+ SelRelease = CurrentPosition;
+ SelectionInProgress = false;
+ RegisterForRedraw ();
+ }
+ #endregion
+
+ /// <summary>
+ /// Update Current Column, line and TextCursorPos
+ /// from mouseLocalPos
+ /// </summary>
+ void computeTextCursor(Context gr)
+ {
+ TextExtents te;
+
+ double cPos = 0f;
+
+ CurrentLine = (int)(mouseLocalPos.Y / (fe.Ascent+fe.Descent));
+
+ //fix cu
+ if (CurrentLine >= lines.Count)
+ CurrentLine = lines.Count - 1;
+
+ switch (TextAlignment) {
+ case Alignment.Center:
+ case Alignment.Top:
+ case Alignment.Bottom:
+ cPos+= ClientRectangle.Width - gr.TextExtents(lines [CurrentLine]).Width/2.0;
+ break;
+ case Alignment.Right:
+ case Alignment.TopRight:
+ case Alignment.BottomRight:
+ cPos += ClientRectangle.Width - gr.TextExtents(lines [CurrentLine]).Width;
+ break;
+ }
+
+ for (int i = 0; i < lines[CurrentLine].Length; i++)
+ {
+ string c = lines [CurrentLine].Substring (i, 1);
+ if (c == "\t")
+ c = new string (' ', Interface.TAB_SIZE);
+
+ te = gr.TextExtents(c);
+
+ double halfWidth = te.XAdvance / 2;
+
+ if (mouseLocalPos.X <= cPos + halfWidth)
+ {
+ CurrentColumn = i;
+ textCursorPos = cPos;
+ mouseLocalPos = -1;
+ return;
+ }
+
+ cPos += te.XAdvance;
+ }
+ CurrentColumn = lines[CurrentLine].Length;
+ textCursorPos = cPos;
+
+ //reset mouseLocalPos
+ mouseLocalPos = -1;
+ }
+ /// <summary> Computes offsets in cairo units </summary>
+ void computeTextCursorPosition(Context gr)
+ {
+ if (SelBegin >= 0)
+ SelStartCursorPos = GetXFromTextPointer (gr, SelBegin);
+ if (SelRelease >= 0)
+ SelEndCursorPos = GetXFromTextPointer (gr, SelRelease);
+ textCursorPos = GetXFromTextPointer (gr, new Point(CurrentColumn, CurrentLine));
+ }
+ /// <summary> Compute x offset in cairo unit from text position </summary>
+ double GetXFromTextPointer(Context gr, Point pos)
+ {
+ try {
+ string l = lines [pos.Y].Substring (0, pos.X).
+ Replace ("\t", new String (' ', Interface.TAB_SIZE));
+ return gr.TextExtents (l).XAdvance;
+ } catch{
+ return -1;
+ }
+ }
+ }
+}
diff --git a/Samples/BasicTests/BasicTests.cs b/Samples/BasicTests/BasicTests.cs
index 755c4a0b..dcf38db4 100644
--- a/Samples/BasicTests/BasicTests.cs
+++ b/Samples/BasicTests/BasicTests.cs
@@ -28,14 +28,14 @@ namespace tests
// += KeyboardKeyDown1;
//testFiles = new string [] { @"Interfaces/Experimental/testDock.crow" };
- //testFiles = new string [] { @"Interfaces/Divers/welcome.crow" };
+ testFiles = new string [] { @"Interfaces/Divers/welcome.crow" };
//testFiles = new string [] { @"Interfaces/TemplatedGroup/3.crow" };
//testFiles = new string [] { @"Interfaces/Divers/testShape.crow" };
//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/Stack/StretchedInFit4.crow" };
- testFiles = new string [] { @"Interfaces/TemplatedGroup/1.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 ();
@@ -62,12 +62,7 @@ namespace tests
switch (key) {
case Key.Escape:
Quit ();
- break;
- case Key.F2:
- //if (IsKeyDown (Key.LeftShift))
- //DbgLogger.Reset ();
- //DbgLogger.save (this);
- return false;
+ break;
case Key.F3:
idx--;
break;
@@ -78,15 +73,6 @@ namespace tests
//TestList.Add ("new string");
NotifyValueChanged ("TestList", TestList);
break;
- case Key.F5:
- Load ("Interfaces/Divers/testFileDialog.crow").DataSource = this;
- return false;
- case Key.F6:
- Load ("Interfaces/Divers/0.crow").DataSource = this;
- return false;
- case Key.F7:
- Load ("Interfaces/Divers/perfMeasures.crow").DataSource = this;
- return false;
default:
return base.OnKeyDown (key);
}
@@ -105,7 +91,7 @@ namespace tests
#endif
Load (testFiles [idx]).DataSource = this;
} catch (Exception ex) {
- (LoadIMLFragment ($"<Label Background='Red' Foreground='White' Height='Fit' Width='Stretched' Multiline='true' VerticalAlignment='Bottom' Margin='5' />") as Label).Text = ex.ToString();
+ (LoadIMLFragment ($"<Label Background='Red' Foreground='White' Height='Fit' Width='Stretched' Multiline='true' VerticalAlignment='Bottom' Margin='5' />") as OldLabel).Text = ex.ToString();
Console.WriteLine (ex.Message + "\n" + ex.InnerException);
//MessageBox.Show (CurrentInterface, MessageBox.Type.Error, ex.Message + "\n" + ex.InnerException.Message).Modal = true;
}
diff --git a/Samples/BasicTests/BasicTests.csproj b/Samples/BasicTests/BasicTests.csproj
index b92bf102..63d93cc3 100644
--- a/Samples/BasicTests/BasicTests.csproj
+++ b/Samples/BasicTests/BasicTests.csproj
@@ -8,4 +8,7 @@
<LogicalName>ShowCase.%(Filename)%(Extension)</LogicalName>
</EmbeddedResource>
</ItemGroup>
+ <ItemGroup>
+ <None Remove="C:\Users\Jean-Philippe\source\Crow\Samples\common\ui\Interfaces\Experimental\testDock2.crow" />
+ </ItemGroup>
</Project> \ No newline at end of file
diff --git a/Samples/DebugLogAnalyzer/Program.cs b/Samples/DebugLogAnalyzer/Program.cs
index bb793da3..7493a842 100644
--- a/Samples/DebugLogAnalyzer/Program.cs
+++ b/Samples/DebugLogAnalyzer/Program.cs
@@ -79,7 +79,7 @@ namespace DebugLogAnalyzer
TreeView tv = FindByName("dbgTV") as TreeView;
dbgTreeViewScroller = tv.FindByNameInTemplate ("scroller1") as Scroller;
- loadDebugFile ("/var/tmp/debug.log");
+ loadDebugFile ("debug.log");
}
void loadDebugFile (string logFile)
diff --git a/Samples/PerfTests/Program.cs b/Samples/PerfTests/Program.cs
index 7a62fd8c..73b97448 100644
--- a/Samples/PerfTests/Program.cs
+++ b/Samples/PerfTests/Program.cs
@@ -16,6 +16,7 @@ namespace PerfTests
readonly bool resetItors = false;
readonly bool screenOutput = false;
readonly string inDirectory = "Interfaces";//directory to test
+ readonly string outFilePath;
Stream outStream;
@@ -24,7 +25,8 @@ namespace PerfTests
bool logToDisk => writer != null;
void writeHeader (TextWriter txtWriter) {
- txtWriter.WriteLine ($"Crow perf test ({clientRectangle.Width} X {clientRectangle.Height}), repeat count = {count}, reset style and templates = {resetItors}");
+ txtWriter.WriteLine ($"Crow perf test ({clientRectangle.Width} X {clientRectangle.Height}), output to screen = { screenOutput }");
+ txtWriter.WriteLine ($"repeat = {count}, update cycles = {updateCycles} reset Instantiators = {resetItors}");
txtWriter.WriteLine ($"git:{ThisAssembly.Git.Commit} {ThisAssembly.Git.Branch} {ThisAssembly.Git.SemVer.Major}.{ThisAssembly.Git.SemVer.Minor}.{ThisAssembly.Git.SemVer.Patch} {ThisAssembly.Git.SemVer.Label}");
}
@@ -39,6 +41,7 @@ namespace PerfTests
Console.WriteLine ("-r,--reset:\n\tenable clear iterators after each test file.");
Console.WriteLine ("-u,--update:\n\tmeasure 'n' update cycle with DateTime.Now string notified.");
Console.WriteLine ("-s,--screen:\n\tenable output to screen.");
+ Console.WriteLine ("--help:\n\tthis help message.");
}
public TestInterface (string[] args, int width = 800, int height = 600)
@@ -86,7 +89,7 @@ namespace PerfTests
case "--screen":
screenOutput = true;
break;
-
+ case "--help":
default:
throw new Exception ();
}
@@ -107,7 +110,8 @@ namespace PerfTests
Directory.CreateDirectory (dirName);
string filename = "crow-" + DateTime.Now.ToString ("yyyy-MM-dd-HH-mm") +".perflog";
- outStream = new FileStream (Path.Combine (dirName, filename), FileMode.Create);
+ outFilePath = Path.Combine (dirName, filename);
+ outStream = new FileStream (outFilePath, FileMode.Create);
writer = new StreamWriter (outStream);
writeHeader (writer);
writer.WriteLine ("Path;Min;Mean;Max;Allocated;LostMem");
@@ -127,6 +131,9 @@ namespace PerfTests
throw new FileNotFoundException ("Input directory not found: " + dirName);
testDir (dirName);
+
+ if (logToDisk)
+ Console.WriteLine ($"\ntest log written to: {outFilePath}");
}
protected override void Dispose (bool disposing) {
@@ -222,6 +229,7 @@ namespace PerfTests
double lostMem = (double)(totMemAfter - totMemBefore) / 1024.0;
if (logToDisk) {
writer.WriteLine ($"{f};{min};{mean};{max};{allocAfter - allocBefore};{totMemAfter - totMemBefore}");
+ Console.Write (".");
} else {
if (miliseconds)
Console.WriteLine ($"{label,-50}|{min,10}|{mean,10}|{max,10}| {allocated,8:0.0} | {lostMem,8:0.0} |");
diff --git a/Samples/PerfTests/Properties/launchSettings.json b/Samples/PerfTests/Properties/launchSettings.json
index c5470b40..278f5ab3 100644
--- a/Samples/PerfTests/Properties/launchSettings.json
+++ b/Samples/PerfTests/Properties/launchSettings.json
@@ -2,7 +2,7 @@
"profiles": {
"PerfTests": {
"commandName": "Project",
- "commandLineArgs": "-c 5 -u 99 -s -i Interfaces/PerfLabels"
+ "commandLineArgs": "-c 20 -u 99 -s -i Interfaces/PerfLabels"
}
}
} \ No newline at end of file
diff --git a/Samples/ShowCase/ShowCase.cs b/Samples/ShowCase/ShowCase.cs
index 8af2c002..d3b40d6f 100644
--- a/Samples/ShowCase/ShowCase.cs
+++ b/Samples/ShowCase/ShowCase.cs
@@ -175,15 +175,6 @@ namespace ShowCase
reloadFromFile ();
}
- public override bool OnKeyDown (Key key)
- {
- switch (key) {
- case Key.F2:
- //DbgLogger.save (this);
- return true;
- }
- return base.OnKeyDown (key);
- }
public void goUpDirClick (object sender, MouseButtonEventArgs e)
diff --git a/Samples/common/SampleBase.cs b/Samples/common/SampleBase.cs
index 65345be7..bdc6608b 100644
--- a/Samples/common/SampleBase.cs
+++ b/Samples/common/SampleBase.cs
@@ -8,6 +8,7 @@ using System.Reflection;
using System.Runtime.CompilerServices;
using System.Threading;
using Crow;
+using Glfw;
namespace Crow
{
@@ -261,5 +262,25 @@ namespace Crow
base.OnInitialized ();
}
+ public override bool OnKeyDown (Key key) {
+
+ switch (key) {
+ case Key.F5:
+ Load ("Interfaces/Divers/testFileDialog.crow").DataSource = this;
+ return true;
+ case Key.F6:
+ Load ("Interfaces/Divers/0.crow").DataSource = this;
+ return true;
+ case Key.F7:
+ Load ("Interfaces/Divers/perfMeasures.crow").DataSource = this;
+ return true;
+ case Key.F2:
+ if (IsKeyDown (Key.LeftShift))
+ DbgLogger.Reset ();
+ DbgLogger.Save (this);
+ return true;
+ }
+ return base.OnKeyDown (key);
+ }
}
} \ No newline at end of file
diff --git a/Samples/common/ui/Interfaces/Divers/testVisibility.crow b/Samples/common/ui/Interfaces/Divers/testVisibility.crow
index 9f9464c9..581bab06 100644
--- a/Samples/common/ui/Interfaces/Divers/testVisibility.crow
+++ b/Samples/common/ui/Interfaces/Divers/testVisibility.crow
@@ -1,8 +1,8 @@
<?xml version="1.0"?>
<Container Margin="20" Background="Red" >
- <Container Margin="20" Background="Green" MouseDown="{../go1.Visible=True}" >
+ <!--<Container Margin="20" Background="Green" MouseDown="{../go1.Visible=True}" >
<Widget Name="go1" Margin="20" Background="DimGrey" Visible="false" MouseDown="{Visible=false}"
MouseEnter="{Background=Blue}"
MouseLeave="{Background=DimGrey}"/>
- </Container>
+ </Container>-->
</Container>
diff --git a/Samples/common/ui/Interfaces/Experimental/testDock2.crow b/Samples/common/ui/Interfaces/Experimental/testDock2.crow
deleted file mode 100644
index d4eb29ac..00000000
--- a/Samples/common/ui/Interfaces/Experimental/testDock2.crow
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0"?>
-<Docker >
- <DockWindow Left="100" Top="100" Width="150" Height="150" Background="DarkRed"/>
- <DockWindow Left="200" Top="200" Width="150" Height="150" Background="DarkGreen"/>
- <DockWindow Left="300" Top="300" Width="150" Height="150" Background="Blue"/>
- <DockWindow Left="400" Top="400" Width="150" Height="150" Background="Yellow"/>
- <DockWindow Left="500" Top="500" Width="150" Height="150" Background="Yellow"/>
-</Docker>
-<!--<Group Background="DimGrey" Margin = "0" Focusable="true" >
- <Window Top="100" Left="100" Focusable="true" Caption="View 1" Width="300" Height="300"><Widget Background="Green" Focusable="true" MouseEnter="{Background=Grey}" MouseLeave="{Background=Green}"/></Window>
- <Window Top="200" Left="200" Focusable="true" Caption="View 2" Resizable = "true" Width="300" Height="300"><Widget Focusable="true" Background="Blue" MouseEnter="{Background=Grey}" MouseLeave="{Background=Blue}"/></Window>
- <Window Top="300" Left="300" Focusable="true" Caption="View 3" Resizable = "true" Width="300" Height="300"><Widget Focusable="true" Background="Yellow" MouseEnter="{Background=Grey}" MouseLeave="{Background=Yellow}"/></Window>
- <Window Top="400" Left="400" Focusable="true" Caption="View 4" Resizable = "true" Width="300" Height="300"><Widget Focusable="true" Background="Black" MouseEnter="{Background=Grey}" MouseLeave="{Background=Black}"/></Window>
-</Group>-->
-<!--<Docker >
- <DockWindow Resizable = "true" Top="100" Left="100" Caption="View 1" Width="300" Height="300">
- <VerticalStack Background="DarkGreen" Focusable="true">
- <Label Text="{../../Left}" Background="Black" Width="Stretched"/>
- <Label Text="{../../Top}" Background="Black"/>
- <Label Text="{../../LogicalParent}" Background="Black"/>
- </VerticalStack>
- </DockWindow>
- <DockWindow Top="200" Left="200" Focusable="true" Caption="View 2" Resizable = "true" Width="300" Height="300"><Widget Focusable="true" Background="Blue" MouseEnter="{Background=Grey}" MouseLeave="{Background=Blue}"/></DockWindow>
- <DockWindow Top="300" Left="300" Focusable="true" Caption="View 3" Resizable = "true" Width="300" Height="300"><Widget Focusable="true" Background="Yellow" MouseEnter="{Background=Grey}" MouseLeave="{Background=Yellow}"/></DockWindow>
- <DockWindow Top="400" Left="400" Focusable="true" Caption="View 4" Resizable = "true" Width="300" Height="300"><Widget Focusable="true" Background="Black" MouseEnter="{Background=Grey}" MouseLeave="{Background=Black}"/></DockWindow>
-</Docker>--> \ No newline at end of file
diff --git a/Samples/common/ui/Interfaces/PerfLabels/0.crow b/Samples/common/ui/Interfaces/PerfLabels/0_single_Label.crow
index 14304360..14304360 100644
--- a/Samples/common/ui/Interfaces/PerfLabels/0.crow
+++ b/Samples/common/ui/Interfaces/PerfLabels/0_single_Label.crow
diff --git a/Samples/common/ui/Interfaces/PerfLabels/0_single_oldLabel.crow b/Samples/common/ui/Interfaces/PerfLabels/0_single_oldLabel.crow
new file mode 100644
index 00000000..4157b6a7
--- /dev/null
+++ b/Samples/common/ui/Interfaces/PerfLabels/0_single_oldLabel.crow
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<OldLabel Text="no update in this file"/>
+
diff --git a/Samples/common/ui/Interfaces/PerfLabels/1.crow b/Samples/common/ui/Interfaces/PerfLabels/1.crow
deleted file mode 100644
index 155e5188..00000000
--- a/Samples/common/ui/Interfaces/PerfLabels/1.crow
+++ /dev/null
@@ -1,3 +0,0 @@
-<?xml version="1.0"?>
-<TextRun Text="{elapsed}" Fit="true" Background="Onyx"/>
-
diff --git a/Samples/common/ui/Interfaces/PerfLabels/2.crow b/Samples/common/ui/Interfaces/PerfLabels/1_single_lab_update.crow
index 034518cb..034518cb 100644
--- a/Samples/common/ui/Interfaces/PerfLabels/2.crow
+++ b/Samples/common/ui/Interfaces/PerfLabels/1_single_lab_update.crow
diff --git a/Samples/common/ui/Interfaces/PerfLabels/1_single_old_update.crow b/Samples/common/ui/Interfaces/PerfLabels/1_single_old_update.crow
new file mode 100644
index 00000000..1a02ce7e
--- /dev/null
+++ b/Samples/common/ui/Interfaces/PerfLabels/1_single_old_update.crow
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<OldLabel Text="{elapsed}" Fit="true" Background="Onyx"/>
+
diff --git a/Samples/common/ui/Interfaces/PerfLabels/labels.crow b/Samples/common/ui/Interfaces/PerfLabels/2_labels_update.crow
index 57c49ad5..8d944f01 100644
--- a/Samples/common/ui/Interfaces/PerfLabels/labels.crow
+++ b/Samples/common/ui/Interfaces/PerfLabels/2_labels_update.crow
@@ -24,30 +24,6 @@
<Label Text="{elapsed}" />
<Label Text="{elapsed}" />
</VerticalStack>
- <VerticalStack Width="20%" Height="Fit">
- <Label Text="{elapsed}" />
- <Label Text="{elapsed}" />
- <Label Text="{elapsed}" />
- <Label Text="{elapsed}" />
- <Label Text="{elapsed}" />
- <Label Text="{elapsed}" />
- <Label Text="{elapsed}" />
- <Label Text="{elapsed}" />
- <Label Text="{elapsed}" />
- <Label Text="{elapsed}" />
- </VerticalStack>
- <VerticalStack Width="20%" Height="Fit">
- <Label Text="{elapsed}" />
- <Label Text="{elapsed}" />
- <Label Text="{elapsed}" />
- <Label Text="{elapsed}" />
- <Label Text="{elapsed}" />
- <Label Text="{elapsed}" />
- <Label Text="{elapsed}" />
- <Label Text="{elapsed}" />
- <Label Text="{elapsed}" />
- <Label Text="{elapsed}" />
- </VerticalStack>
</HorizontalStack>
diff --git a/Samples/common/ui/Interfaces/PerfLabels/2_old_labels_update.crow b/Samples/common/ui/Interfaces/PerfLabels/2_old_labels_update.crow
new file mode 100644
index 00000000..f55bedc3
--- /dev/null
+++ b/Samples/common/ui/Interfaces/PerfLabels/2_old_labels_update.crow
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+<HorizontalStack>
+ <VerticalStack Width="20%" Height="Fit">
+ <OldLabel Text="{elapsed}" />
+ <OldLabel Text="{elapsed}" />
+ <OldLabel Text="{elapsed}" />
+ <OldLabel Text="{elapsed}" />
+ <OldLabel Text="{elapsed}" />
+ <OldLabel Text="{elapsed}" />
+ <OldLabel Text="{elapsed}" />
+ <OldLabel Text="{elapsed}" />
+ <OldLabel Text="{elapsed}" />
+ <OldLabel Text="{elapsed}" />
+ </VerticalStack>
+ <VerticalStack Width="20%" Height="Fit">
+ <OldLabel Text="{elapsed}" />
+ <OldLabel Text="{elapsed}" />
+ <OldLabel Text="{elapsed}" />
+ <OldLabel Text="{elapsed}" />
+ <OldLabel Text="{elapsed}" />
+ <OldLabel Text="{elapsed}" />
+ <OldLabel Text="{elapsed}" />
+ <OldLabel Text="{elapsed}" />
+ <OldLabel Text="{elapsed}" />
+ <OldLabel Text="{elapsed}" />
+ </VerticalStack>
+</HorizontalStack>
+
+