TestResult.xml
*.swp
*.perf
-.vscode
+*.vscode
+*.diagsession
public override string ToString () => $"{Width},{Height}";
public static Size Parse(string s)
{
- string[] d = s.Split(new char[] { ',' });
+ string[] d = s.Split(',');
return d.Length == 1 ? new Size(int.Parse(d[0])) : new Size(
int.Parse(d[0]),
int.Parse(d[1]));
Font f = new Font ();
if (!string.IsNullOrEmpty (s)) {
- string[] c = s.TrimStart().TrimEnd().Split (new char[] { ',' });
+ string[] c = s.TrimStart().TrimEnd().Split (',');
if (c.Length == 2)
f.Size = int.Parse (c [1].TrimStart());
- string[] n = c [0].TrimEnd().Split (new char[] { ' ' });
+ string[] n = c [0].TrimEnd().Split (' ');
f.Name = n [0];
using System.Text;
using System.Diagnostics;
using Glfw;
+using System.Collections;
namespace Crow {
internal struct TextSpan
HashCode.Combine (Line, Column);
}
}
- internal struct LineSpan
+ internal class LineCollection : ICollection<LineSpan>
{
- public readonly int Start;
- public readonly int End;
- public readonly int EndIncludingLineBreak;
+ LineSpan[] lines;
+
+ public int Count => throw new NotImplementedException ();
+
+ public bool IsReadOnly => throw new NotImplementedException ();
+
+ public void Add (LineSpan item) {
+ throw new NotImplementedException ();
+ }
+
+ public void Clear () {
+ throw new NotImplementedException ();
+ }
+
+ public bool Contains (LineSpan item) {
+ throw new NotImplementedException ();
+ }
+
+ public void CopyTo (LineSpan[] array, int arrayIndex) {
+ throw new NotImplementedException ();
+ }
+
+ public IEnumerator<LineSpan> GetEnumerator () {
+ throw new NotImplementedException ();
+ }
+
+ public bool Remove (LineSpan item) {
+ throw new NotImplementedException ();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator () {
+ throw new NotImplementedException ();
+ }
+
+ /*public LineSpan this[int index] {
+ get => lines[index];
+ set => lines[index] = value;
+ }
+ public int Count => lines.Length;
+ public bool IsReadOnly => false;
+
+ public void Add (LineSpan item) {
+
+ }
+
+ public void Clear () {
+ throw new NotImplementedException ();
+ }
+
+ public bool Contains (LineSpan item) {
+ throw new NotImplementedException ();
+ }
+
+ public void CopyTo (LineSpan[] array, int arrayIndex) {
+ throw new NotImplementedException ();
+ }
+
+ public IEnumerator<LineSpan> GetEnumerator () {
+ throw new NotImplementedException ();
+ }
+
+ public int IndexOf (LineSpan item) {
+ throw new NotImplementedException ();
+ }
+
+ public void Insert (int index, LineSpan item) {
+ throw new NotImplementedException ();
+ }
+
+ public bool Remove (LineSpan item) {
+ throw new NotImplementedException ();
+ }
+
+ public void RemoveAt (int index) {
+ throw new NotImplementedException ();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator () {
+ throw new NotImplementedException ();
+ }*/
+ }
+ internal struct LineSpan
+ {
+ public int Start;
+ public int Length;
+ public int LengthIncludingLineBreak;
public int LengthInPixel;
- public int Length => End - Start;
- public int LengthIncludingLineBreak => EndIncludingLineBreak - Start;
- public int LineBreakLength => EndIncludingLineBreak - End;
+ public int End => Start + Length;
+ public int EndIncludingLineBreak => Start + LengthIncludingLineBreak;
+ public int LineBreakLength => LengthIncludingLineBreak - Length;
public bool HasLineBreak => LineBreakLength > 0;
public LineSpan (int start, int end, int endIncludingLineBreak) {
Start = start;
- End = end;
- EndIncludingLineBreak = endIncludingLineBreak;
+ Length = end - start;
+ LengthIncludingLineBreak = endIncludingLineBreak - start;
LengthInPixel = -1;
}
public LineSpan WithStartOffset (int start) => new LineSpan (Start + start, End, EndIncludingLineBreak);
#endregion
#region Keyboard handling
- void checkShift () {
- if (IFace.Shift) {
- if (!selectionStart.HasValue)
- selectionStart = currentLoc;
- } else
- selectionStart = null;
- }
public override void onKeyDown (object sender, KeyEventArgs e) {
switch (e.Key) {
e.Handled = true;
}
- #endregion
- /// <summary>
- /// Update Current Column, line and TextCursorPos
- /// from mouseLocalPos
- /// </summary>
- void updateLocation (Context gr, int clientWidth, ref CharLocation? location)
+ void checkShift () {
+ if (IFace.Shift) {
+ if (!selectionStart.HasValue)
+ selectionStart = currentLoc;
+ } else
+ selectionStart = null;
+ }
+
+ #endregion
+ /// <summary>
+ /// location column from
+ /// </summary>
+ void updateLocation (Context gr, int clientWidth, ref CharLocation? location)
{
if (location == null)
return;
--- /dev/null
+// 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 Crow.Cairo;
+using Glfw;
+
+namespace Crow
+{
+ public class OldTextBox : OldLabel
+ {
+ #region CTOR
+ protected OldTextBox() {}
+ public OldTextBox(Interface iface, string style = null) : base (iface, style) { }
+ #endregion
+
+ #region GraphicObject overrides
+ [XmlIgnore]public override bool HasFocus //trigger update when lost focus to errase text beam
+ {
+ get => base.HasFocus;
+ set {
+ if (base.HasFocus == value)
+ return;
+ base.HasFocus = value;
+ RegisterForRedraw();
+ }
+ }
+
+ protected override void onDraw (Context gr)
+ {
+ base.onDraw (gr);
+ }
+ #endregion
+
+ #region Keyboard handling
+ public override void onKeyDown (object sender, KeyEventArgs e)
+ {
+ Key key = e.Key;
+
+ switch (key)
+ {
+ case Key.Backspace:
+ if (CurrentPosition == 0)
+ return;
+ DeleteChar();
+ break;
+ case Key.Delete:
+ if (selectionIsEmpty) {
+ if (!MoveRight ())
+ return;
+ }else if (IFace.Shift)
+ IFace.Clipboard = SelectedText;
+ DeleteChar ();
+ break;
+ case Key.KeypadEnter:
+ case Key.Enter:
+ if (!selectionIsEmpty)
+ DeleteChar ();
+ if (Multiline)
+ InsertLineBreak ();
+ else
+ OnTextChanged(this,new TextChangeEventArgs(Text));
+ break;
+ case Key.Escape:
+ Text = "";
+ CurrentColumn = 0;
+ SelRelease = -1;
+ break;
+ case Key.Home:
+ if (IFace.Shift) {
+ if (selectionIsEmpty)
+ SelBegin = new Point (CurrentColumn, CurrentLine);
+ if (IFace.Ctrl)
+ CurrentLine = 0;
+ CurrentColumn = 0;
+ SelRelease = new Point (CurrentColumn, CurrentLine);
+ break;
+ }
+ SelRelease = -1;
+ if (IFace.Ctrl)
+ CurrentLine = 0;
+ CurrentColumn = 0;
+ break;
+ case Key.End:
+ if (IFace.Shift) {
+ if (selectionIsEmpty)
+ SelBegin = CurrentPosition;
+ if (IFace.Ctrl)
+ CurrentLine = int.MaxValue;
+ CurrentColumn = int.MaxValue;
+ SelRelease = CurrentPosition;
+ break;
+ }
+ SelRelease = -1;
+ if (IFace.Ctrl)
+ CurrentLine = int.MaxValue;
+ CurrentColumn = int.MaxValue;
+ break;
+ case Key.Insert:
+ if (IFace.Shift)
+ this.Insert (IFace.Clipboard);
+ else if (IFace.Ctrl && !selectionIsEmpty)
+ IFace.Clipboard = this.SelectedText;
+ break;
+ case Key.Left:
+ if (IFace.Shift) {
+ if (selectionIsEmpty)
+ SelBegin = new Point(CurrentColumn, CurrentLine);
+ if (IFace.Ctrl)
+ GotoWordStart ();
+ else if (!MoveLeft ())
+ return;
+ SelRelease = CurrentPosition;
+ break;
+ }
+ SelRelease = -1;
+ if (IFace.Ctrl)
+ GotoWordStart ();
+ else
+ MoveLeft();
+ break;
+ case Key.Right:
+ if (IFace.Shift) {
+ if (selectionIsEmpty)
+ SelBegin = CurrentPosition;
+ if (IFace.Ctrl)
+ GotoWordEnd ();
+ else if (!MoveRight ())
+ return;
+ SelRelease = CurrentPosition;
+ break;
+ }
+ SelRelease = -1;
+ if (IFace.Ctrl)
+ GotoWordEnd ();
+ else
+ MoveRight ();
+ break;
+ case Key.Up:
+ if (IFace.Shift) {
+ if (selectionIsEmpty)
+ SelBegin = CurrentPosition;
+ CurrentLine--;
+ SelRelease = CurrentPosition;
+ break;
+ }
+ SelRelease = -1;
+ CurrentLine--;
+ break;
+ case Key.Down:
+ if (IFace.Shift) {
+ if (selectionIsEmpty)
+ SelBegin = CurrentPosition;
+ CurrentLine++;
+ SelRelease = CurrentPosition;
+ break;
+ }
+ SelRelease = -1;
+ CurrentLine++;
+ break;
+ case Key.Tab:
+ this.Insert ("\t");
+ break;
+ default:
+ break;
+ }
+ e.Handled = true;
+ base.onKeyDown (sender, e);
+ RegisterForGraphicUpdate ();
+ }
+ public override void onKeyPress (object sender, KeyPressEventArgs e)
+ {
+ base.onKeyPress (sender, e);
+
+ this.Insert (e.KeyChar.ToString());
+
+ SelRelease = -1;
+ SelBegin = new Point(CurrentColumn, SelBegin.Y);
+
+ RegisterForGraphicUpdate();
+ }
+ #endregion
+ }
+}
namespace Crow
{
- public class TextBox : OldLabel
+ public class TextBox : Label
{
#region CTOR
protected TextBox() {}
public TextBox(Interface iface, string style = null) : base (iface, style) { }
#endregion
- #region GraphicObject overrides
- [XmlIgnore]public override bool HasFocus //trigger update when lost focus to errase text beam
- {
- get => base.HasFocus;
- set {
- if (base.HasFocus == value)
- return;
- base.HasFocus = value;
- RegisterForRedraw();
- }
- }
-
- protected override void onDraw (Context gr)
- {
- base.onDraw (gr);
- }
- #endregion
#region Keyboard handling
public override void onKeyDown (object sender, KeyEventArgs e)
switch (key)
{
- case Key.Backspace:
+ /*case Key.Backspace:
if (CurrentPosition == 0)
return;
DeleteChar();
break;
case Key.Tab:
this.Insert ("\t");
- break;
+ break;*/
default:
+ base.onKeyDown (sender, e);
break;
}
e.Handled = true;
- base.onKeyDown (sender, e);
- RegisterForGraphicUpdate ();
}
public override void onKeyPress (object sender, KeyPressEventArgs e)
{
base.onKeyPress (sender, e);
- this.Insert (e.KeyChar.ToString());
+ /*Insert (e.KeyChar.ToString());
SelRelease = -1;
SelBegin = new Point(CurrentColumn, SelBegin.Y);
- RegisterForGraphicUpdate();
+ RegisterForGraphicUpdate();*/
}
#endregion
}
public virtual void NotifyValueChanged(string MemberName, object _value)
{
//Debug.WriteLine ("Value changed: {0}->{1} = {2}", this, MemberName, _value);
- ValueChanged.Raise(this, new ValueChangeEventArgs(MemberName, _value));
+ if (ValueChanged != null)
+ ValueChanged.Invoke(this, new ValueChangeEventArgs(MemberName, _value));
}
public void NotifyValueChangedAuto (object _value, [CallerMemberName] string caller = null)
{
- NotifyValueChanged (caller, _value);
+ if (ValueChanged != null)
+ NotifyValueChanged (caller, _value);
}
#endregion
RegisterForLayouting (LayoutingType.Y);
break;
}
- LayoutChanged.Raise (this, new LayoutingEventArgs (layoutType));
+ if (LayoutChanged != null)
+ LayoutChanged.Invoke (this, new LayoutingEventArgs (layoutType));
}
internal protected void raiseLayoutChanged(LayoutingEventArgs e){
- LayoutChanged.Raise (this, e);
+ if (LayoutChanged != null)
+ LayoutChanged.Raise (this, e);
}
/// <summary> Update layout component only one at a time, this is where the computation of alignement
/// and size take place.
using System.IO;
using System.Reflection;
using System.Text.RegularExpressions;
+using System.Globalization;
using Crow.Coding;
namespace Crow
/// Parser for style files.
/// </summary>
//TODO: style key shared by different class may use only first encouneter class setter, which can cause bug.
- public class StyleReader : StreamReader
- {
+ public class StyleReader : StreamReader {
enum States { classNames, members, value, endOfStatement }
States curState = States.classNames;
int line = 1;
#region Character ValidityCheck
- static Regex rxValidChar = new Regex(@"\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}|\p{Nl}|\p{Mn}|\p{Mc}|\p{Nd}|\p{Pc}|\p{Cf}");
- static Regex rxNameStartChar = new Regex(@"_|\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}");
- static Regex rxNameChar = new Regex(@"\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}|\p{Nl}|\p{Mn}|\p{Mc}|\p{Nd}|\p{Pc}|\p{Cf}");
- static Regex rxDecimal = new Regex(@"[0-9]+");
- static Regex rxHexadecimal = new Regex(@"[0-9a-fA-F]+");
+ /*static Regex rxValidChar = new Regex (@"\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}|\p{Nl}|\p{Mn}|\p{Mc}|\p{Nd}|\p{Pc}|\p{Cf}");
+ static Regex rxNameStartChar = new Regex (@"_|\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}");
+ static Regex rxNameChar = new Regex (@"\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}|\p{Nl}|\p{Mn}|\p{Mc}|\p{Nd}|\p{Pc}|\p{Cf}");
+ static Regex rxDecimal = new Regex (@"[0-9]+");
+ static Regex rxHexadecimal = new Regex (@"[0-9a-fA-F]+");*/
- bool nextCharIsValidCharStartName {
- get => rxNameStartChar.IsMatch(new string(new char[]{PeekChar()}));
- }
+ bool nextCharIsValidCharStartName => Char.IsLetter (PeekChar ()) || PeekChar () == '_';
bool nextCharIsValidCharName {
- get => rxNameChar.IsMatch(new string(new char[]{PeekChar()}));
+ get {
+ if (Char.IsLetterOrDigit (PeekChar ()))
+ return true;
+ UnicodeCategory uc = Char.GetUnicodeCategory (PeekChar ());
+ return
+ uc == UnicodeCategory.NonSpacingMark ||
+ uc == UnicodeCategory.SpacingCombiningMark ||
+ uc == UnicodeCategory.ConnectorPunctuation ||
+ uc == UnicodeCategory.Format;
+ }
}
#endregion
namespace HelloWorld
{
- class Program {
+ class Program : SampleBase {
static void Main (string[] args) {
- using (Interface app = new Interface ()) {
- app.Initialized += (sender, e) => (sender as Interface).Load ("#HelloWorld.helloworld.crow");
+ using (Interface app = new Program ()) {
+ app.Initialized += (sender, e) => (sender as Interface).Load ("#HelloWorld.helloworld.crow").DataSource = sender;
app.Run ();
}
}
<?xml version="1.0"?>
-<Label Text="Hello World"/>
\ No newline at end of file
+<HorizontalStack >
+ <VerticalStack Background="Jet" Height="Stretched" Width="50%" Margin="10" >
+ <TextBox Margin="0" Text="Hello World this is a test string" Focusable="true" Font="serif,14"/>
+ <TextBox Margin="15" Text="Hello World this is a test string" Focusable="true" Font="serif,14"
+ Background="Grey" Focused="{Background=White}" Unfocused="{Background=Grey}"/>
+ <TextBox Width="300" Height="50" Text="Hello World this is a test string" Focusable="true" Font="serif,14"
+ Background="Grey" Focused="{Background=White}" Unfocused="{Background=Grey}"/>
+ <TextBox TextAlignment="Right" Width="300" Height="50" Text="Hello World this is a test string" Focusable="true" Font="serif,14"
+ Background="Grey" Focused="{Background=White}" Unfocused="{Background=Grey}"/>
+ <TextBox Name="lab" TextAlignment="Center" Width="Fit" Height="50" Text="Hello World this is a test string" Focusable="true" Font="serif,14"
+ Background="Grey" Focused="{Background=White}" Unfocused="{Background=Grey}"/>
+ </VerticalStack>
+ <VerticalStack Background="Jet" Height="Stretched" Margin="10">
+ <TextBox Multiline="true" TextAlignment="{TextAlignment}" Width="320" Height="Fit"
+ Text="{MultilineText}" Focusable="true" Font="consolas,12"
+ Background="Grey" Focused="{Background=White}" Unfocused="{Background=Grey}"/>
+ <EnumSelector RadioButtonStyle="CheckBox2" Caption="Text Alignment" EnumValue="{²TextAlignment}" >
+ <Template>
+ <GroupBox Caption="{./Caption}" CornerRadius="{./CornerRadius}" Foreground="{./Foreground}" Background="{./Background}">
+ <VerticalStack Name="Content"/>
+ </GroupBox>
+ </Template>
+ </EnumSelector>
+ </VerticalStack>
+</HorizontalStack>
\ No newline at end of file
"profiles": {
"PerfTests": {
"commandName": "Project",
- "commandLineArgs": "-c 20 -u 99 -s -i Interfaces/PerfLabels"
+ "commandLineArgs": "-c 20 -i Interfaces/PerfLabels"
}
}
}
\ No newline at end of file
<Scroller Name="scroller1" Background="White"
Margin="2" ScrollY="{../scrollbar1.Value}">
<TextBox VerticalAlignment="Top"
- Text="{²Source}" Multiline="true" TextAlignment="TopLeft"
+ Text="{²Source}" Multiline="true"
Font="mono 10"/>
</Scroller>
<ScrollBar Name="scrollbar1" Value="{../scroller1.ScrollY}"
DirectoryInfo curDir = new DirectoryInfo (Path.GetDirectoryName (Assembly.GetEntryAssembly ().Location));
public FileSystemInfo[] CurDirectory => curDir.GetFileSystemInfos ();
public string MultilineText =
- $"Lorem ipsum dolor sit amet,\nconsectetur adipiscing elit. Sed non risus.\n\nSuspendisse lectus tortor,";
+ $"Lorem ipsum dolor sit amet,\nconsectetur adipiscing elit. Sed non risus.\n\nSuspendisse lectus tortor,\nLorem ipsum dolor sit amet,\nconsectetur adipiscing elit. Sed non risus.\n\nSuspendisse lectus tortor,";
//public string MultilineText = $"a\n";
TextAlignment textAlignment = TextAlignment.Left;
public TextAlignment TextAlignment {