<Reference Include="OpenTK">
<HintPath>$(SolutionDir)packages\OpenTK.2.0.0\lib\net20\OpenTK.dll</HintPath>
</Reference>
+ <Reference Include="Mono.CSharp" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
using System.Linq;
using Crow.Coding;
using System.Threading;
+using Mono.CSharp;
namespace Crow.Coding
{
using System.Linq;
using System.Threading;
using System.ComponentModel;
+using System.Reflection;
namespace Crow.Coding
{
+ public struct Column {
+ public string Data;
+ public string Title;
+ public int Width;
+ public bool Visible;
+ public Alignment TextAlign;
+
+ public Column (string data, string caption, int width = -1, Alignment textAlign = Alignment.Left) {
+ Data = data;
+ Title = caption;
+ Width = width;
+ Visible = true;
+ TextAlign = textAlign;
+ }
+ }
public class DbgEventViewer : ScrollingObject
{
protected ReaderWriterLockSlim evtsMTX = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
int visibleLines = 1;
int visibleColumns = 1;
int hoverLine = -1;
+ int columnMargin = 4;
+ List<Column> Columns = new List<Column>();
+ int hoverColIdx = -1;
+ bool sizingCol = false; //true during resize of column with mouse
List<int> selectedLines = new List<int>();
Point mouseLocalPos;
Color selBackground, selForeground, hoverBackground;
if (debugEvents == value)
return;
evtsMTX.EnterWriteLock ();
- debugEvents = value;
+ if (value == null)
+ debugEvents = null;
+ else
+ debugEvents = value.ToList();
evtsMTX.ExitWriteLock ();
NotifyValueChanged ("DebugEvent", debugEvents);
evtsMTX.EnterReadLock ();
- int filteredCount = filteredEvts.Count;
+ try {
+
+ int filteredCount = filteredEvts.Count;
- gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
- gr.SetFontSize (Font.Size);
- gr.FontOptions = Interface.FontRenderingOptions;
- gr.Antialias = Interface.Antialias;
+ gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
+ gr.SetFontSize (Font.Size);
+ gr.FontOptions = Interface.FontRenderingOptions;
+ gr.Antialias = Interface.Antialias;
- Rectangle cb = ClientRectangle;
+ Rectangle cb = ClientRectangle;
+ double y = cb.Y, x = cb.X;
- for (int i = 0; i < visibleLines; i++) {
- int lineIndex = i + ScrollY;
- if (lineIndex >= filteredCount)
- break;
- string str = filteredEvts [i + ScrollY].ToString ();
- double y = cb.Y + (fe.Ascent+fe.Descent) * i, x = cb.X;
-
- gr.Operator = Operator.Multiply;
- if (selectedLines.Contains (lineIndex)) {
- gr.SetSourceColor (selBackground);
- gr.Rectangle (x, y, cb.Width, fe.Ascent + fe.Descent);
- gr.Fill ();
- gr.SetSourceColor (selForeground);
+ gr.SetSourceColor (Color.Gray);
+ gr.Rectangle (x, y, cb.Width, fe.Ascent + fe.Descent);
+ gr.FillPreserve ();
+ gr.SetSourceColor (Color.Black);
+ gr.LineWidth = 1;
+ gr.Stroke ();
+
+ foreach (Column c in Columns) {
+ TextExtents te = gr.TextExtents (c.Title);
+ gr.MoveTo (x + columnMargin + (c.Width-2*columnMargin) / 2 - te.Width / 2, y + fe.Ascent);
+ gr.ShowText (c.Title);
+ x += c.Width;
+ gr.MoveTo (x + 0.5, cb.Y);
+ gr.LineTo (x + 0.5, cb.Bottom);
}
- if (lineIndex == hoverLine) {
- gr.SetSourceColor (hoverBackground);
- gr.Rectangle (x, y, cb.Width, fe.Ascent + fe.Descent);
- gr.Fill ();
- gr.SetSourceColor (selForeground);
- }else
- Foreground.SetAsSource (gr);
- gr.Operator = Operator.Over;
- gr.MoveTo (x, y + fe.Ascent);
- gr.ShowText (str);
gr.Stroke ();
+
+ for (int i = 0; i < visibleLines; i++) {
+ int lineIndex = i + ScrollY;
+ if (lineIndex >= filteredCount)
+ break;
+ y += (fe.Ascent + fe.Descent);
+ x = cb.X;
+
+ gr.Operator = Operator.Multiply;
+ if (selectedLines.Contains (lineIndex)) {
+ gr.SetSourceColor (selBackground);
+ gr.Rectangle (x, y, cb.Width, fe.Ascent + fe.Descent);
+ gr.Fill ();
+ gr.SetSourceColor (selForeground);
+ }
+ if (lineIndex == hoverLine) {
+ gr.SetSourceColor (hoverBackground);
+ gr.Rectangle (x, y, cb.Width, fe.Ascent + fe.Descent);
+ gr.Fill ();
+ gr.SetSourceColor (selForeground);
+ }else
+ Foreground.SetAsSource (gr);
+ gr.Operator = Operator.Over;
+
+ object obj = filteredEvts [i + ScrollY];
+ Type t = obj.GetType ();
+ foreach (Column c in Columns) {
+ MemberInfo mi = t.GetMember (c.Data).FirstOrDefault();
+ if (mi != null) {
+ string str = "";
+ if (mi.MemberType == MemberTypes.Field) {
+ FieldInfo fi = mi as FieldInfo;
+ str = fi.GetValue (obj).ToString ();
+ } else if (mi.MemberType == MemberTypes.Property) {
+ MethodInfo pmi = (mi as PropertyInfo).GetGetMethod ();
+ str = pmi.Invoke (obj, null).ToString();
+ }
+
+ TextExtents te = gr.TextExtents (str);
+
+ if (c.TextAlign == Alignment.Right)
+ gr.MoveTo (x + columnMargin + Math.Max (0,(c.Width - 2*columnMargin) - te.Width), y + fe.Ascent);
+ else
+ gr.MoveTo (x + columnMargin, y + fe.Ascent);
+
+ gr.ShowText (str);
+ gr.Stroke ();
+
+ }
+ x += c.Width;
+ }
+ }
+ } catch (Exception ex) {
+ System.Diagnostics.Debug.WriteLine (ex);
}
+
evtsMTX.ExitReadLock ();
}
{
base.onMouseMove (sender, e);
mouseLocalPos = e.Position - ScreenCoordinates(Slot).TopLeft - ClientRectangle.TopLeft;
- HoverLine = ScrollY + (int)Math.Max (0, Math.Floor (mouseLocalPos.Y / (fe.Ascent+fe.Descent)));
+
+ if (sizingCol) {
+ Column c = Columns[hoverColIdx];
+ c.Width += e.XDelta;
+ if (c.Width < 1)
+ c.Width = 1;
+ Columns[hoverColIdx] = c;
+ RegisterForGraphicUpdate ();
+ return;
+ }
+
+ hoverColIdx = -1;
+ int x = 0;
+ for (int i = 0; i < Columns.Count; i++) {
+ x += Columns[i].Width;
+ if (mouseLocalPos.X > x - columnMargin) {
+ if (mouseLocalPos.X < x + columnMargin) {
+ hoverColIdx = i;
+ break;
+ }
+ } else
+ break;
+ }
+
+ if (hoverColIdx < 0)
+ IFace.MouseCursor = XCursor.Default;
+ else
+ IFace.MouseCursor = XCursor.H;
+
+ HoverLine = ScrollY + (int)Math.Max (0, Math.Floor (mouseLocalPos.Y / (fe.Ascent+fe.Descent))- 1);
}
public override void onMouseDown (object sender, MouseButtonEventArgs e)
{
base.onMouseDown (sender, e);
+ if (hoverColIdx >= 0) {
+ sizingCol = true;
+ return;
+ }
+
if (IFace.Keyboard [Key.ControlLeft]) {
if (hoverLine >= 0) {
if (selectedLines.Contains (hoverLine))
RegisterForGraphicUpdate ();
}
+ public override void onMouseUp (object sender, MouseButtonEventArgs e)
+ {
+ base.onMouseUp (sender, e);
+ if (sizingCol)
+ sizingCol = false;
+ }
+
void updateFilteredEvents () {
evtsMTX.EnterWriteLock();
try {
-
+ hoverLine = -1;
+ selectedLines.Clear ();
+
if (debugEvents == null)
filteredEvts = null;
else {
RegisterForGraphicUpdate ();
}
void updateVisibleLines(){
- visibleLines = (int)Math.Floor ((double)ClientRectangle.Height / (fe.Ascent+fe.Descent));
+ visibleLines = (int)Math.Max(0, Math.Floor ((double)ClientRectangle.Height / (fe.Ascent+fe.Descent)) - 1);
NotifyValueChanged ("VisibleLines", visibleLines);
updateMaxScrollY ();
RegisterForGraphicUpdate ();
break;
}
}
+
+ protected override void onInitialized (object sender, EventArgs e)
+ {
+ base.onInitialized (sender, e);
+
+ Columns.Add (new Column ("ThreadId", "T", 16, Alignment.Right));
+ Columns.Add (new Column ("Ticks", "tks", 60, Alignment.Right));
+ Columns.Add (new Column ("EventType", "Event", 120));
+ Columns.Add (new Column ("Name", "Widget Name", 120));
+ Columns.Add (new Column ("Slot", "Slot", 100, Alignment.Right));
+ Columns.Add (new Column ("Message", "Message", 400));
+ }
}
}
FoldingEvent.Raise (this, new CodeBufferEventArgs (line));
}
public void Load(string rawSource, string lineBrkRegex = @"\r\n|\r|\n|\\\n") {
- this.Clear();
+ editMutex.EnterWriteLock ();
- if (string.IsNullOrEmpty (rawSource))
- return;
+ this.Clear();
- AddRange (Regex.Split (rawSource, lineBrkRegex));
+ if (!string.IsNullOrEmpty (rawSource)) {
+ AddRange (Regex.Split (rawSource, lineBrkRegex));
+ lineBreak = detectLineBreakKind (rawSource);
+ }
- lineBreak = detectLineBreakKind (rawSource);
+ editMutex.ExitWriteLock ();
}
/// <summary>
namespace Crow.Text
{
/// <summary>
- /// Code buffer, lines are arranged in a List<string>, new line chars are removed during string.split on '\n...',
+ /// text buffer in single piece with lines
/// </summary>
public class TextBuffer
{
/// </summary>
int _currentLine = 0;
int _currentCol = 0;
+ Point selStartPos = -1; //selection start (row,column)
+ Point selEndPos = -1; //selection end (row,column)
/// <summary>
/// Gets the total line count.
public int GetBufferIndexOfLine (int i) {
int ptr = 0;
editMutex.EnterReadLock ();
- for (int j = 0; j < i; j++) {
+ for (int j = 0; j < i; j++)
ptr += lineLength [j];
- }
editMutex.ExitReadLock ();
return ptr;
}
public int BufferIndexOfCurrentPosition {
get {return GetBufferIndexOfLine (_currentLine) + _currentCol;}
}
- public int this[int i]
- {
- get {
- int ptr = 0;
- editMutex.EnterReadLock ();
- for (int j = 0; j < i; j++) {
- ptr += lineLength [j];
- }
- editMutex.ExitReadLock ();
- return ptr;
- }
- }
/// <summary>
/// remove line number i
/// </summary>
/// <param name="str">linebreak free string</param>
public void InsertAt(int i, string str){
editMutex.EnterWriteLock ();
- buffer.Insert (this [i], str);
+ buffer.Insert (GetBufferIndexOfLine (i), str);
lineLength.Insert (i, str.Length);
editMutex.ExitWriteLock ();
LineAdditionEvent.Raise (this, new TextBufferEventArgs (i));
}
public void UpdateLine(int i, string newContent){
editMutex.EnterWriteLock ();
- int ptrL = this [i];
+ int ptrL = GetBufferIndexOfLine (i);
buffer.Remove (ptrL, lineLength [i]);
buffer.Insert (ptrL, newContent);
lineLength [i] = newContent.Length;
}
public void AppenedLine(int i, string newContent){
editMutex.EnterWriteLock ();
- int ptr = this [i] + lineLength [i];
+ int ptr = GetBufferIndexOfLine (i) + lineLength [i];
if (i < LineCount - 1)
ptr--;
buffer.Insert(ptr, newContent);
editMutex.EnterWriteLock ();
string tmp = reghexLineBrk.Replace (str, "\n");//use single char line break in buffer
- int buffPtr = this [CurrentLine] + CurrentColumn;
+ int buffPtr = GetBufferIndexOfLine (CurrentLine) + CurrentColumn;
buffer.Insert (buffPtr, tmp);
int lPtr = CurrentLine, strPtr = 0;
public void InsertLineBreak()
{
editMutex.EnterWriteLock ();
- buffer.Insert (this [CurrentLine] + CurrentColumn, '\n');
+ buffer.Insert (GetBufferIndexOfLine (CurrentLine) + CurrentColumn, '\n');
int lgdiff = lineLength [CurrentLine] - CurrentColumn;
lineLength.Insert (CurrentLine + 1, lineLength [CurrentLine] - CurrentColumn);
lineLength [CurrentLine] = CurrentColumn + 1;
return;
}
- buffer.Remove (this [CurrentLine] - 1, 1);
+ buffer.Remove (GetBufferIndexOfLine (CurrentLine) - 1, 1);
int col = lineLength [CurrentLine - 1] - 1;
lineLength [CurrentLine - 1] += lineLength [CurrentLine] - 1;
return;
}
CurrentColumn--;
- buffer.Remove (this [CurrentLine] + CurrentColumn, 1);
+ buffer.Remove (GetBufferIndexOfLine (CurrentLine) + CurrentColumn, 1);
lineLength [CurrentLine]--;
} else {
int linesToRemove = SelectionEnd.Y - SelectionStart.Y;
- int ptr = this [SelectionStart.Y] + SelectionStart.X;
+ int ptr = GetBufferIndexOfLine (SelectionStart.Y) + SelectionStart.X;
int length = lineLength [SelectionStart.Y] - SelectionStart.X;
int l = 1;
while (l <= linesToRemove ) {
editMutex.ExitWriteLock ();
}
public void Load(string rawSource) {
+ editMutex.EnterWriteLock ();
+
this.Clear();
- if (string.IsNullOrEmpty (rawSource))
+ if (string.IsNullOrEmpty (rawSource)) {
+ editMutex.ExitWriteLock ();
return;
+ }
lineBreak = reghexLineBrk.Match (rawSource).Value;//store original line break
string tmp = reghexLineBrk.Replace (rawSource, "\n");//use single char line break in buffer
lineLength.Add (0);
buffer = new StringBuilder (tmp);
- }
-// public int CurrentTabulatedColumn {
-// get {
-//// return lines [_currentLine].Content.Substring (0, _currentCol).
-//// Replace ("\t", new String (' ', Interface.TabSize)).Length;
-// }
-// }
+ editMutex.ExitWriteLock ();
+ }
#region moving cursor an selection
- Point selStartPos = -1; //selection start (row,column)
- Point selEndPos = -1; //selection end (row,column)
-
public bool SelectionInProgress { get { return selStartPos >= 0; }}
public void SetSelStartPos () {
selStartPos = selEndPos = CurrentPosition;
/// Current position in buffer coordinate, tabulation = 1 char
/// </summary>
public Point CurrentPosition {
- get { return new Point(CurrentColumn, CurrentLine); }
+ get { return new Point(_currentCol, _currentLine); }
}
/// <summary>
/// get char at current position in buffer
/// </summary>
- protected Char CurrentChar { get { return buffer[this [CurrentLine]]; } }
+ protected Char CurrentChar { get { return buffer[GetBufferIndexOfLine (_currentLine)+_currentCol]; } }
public string SelectedText {
get {
if (SelectionIsEmpty)
Point selStart = SelectionStart;
Point selEnd = SelectionEnd;
- int ptr = this [selStart.Y] + selStart.X;
+ int ptr = GetBufferIndexOfLine (selStart.Y) + selStart.X;
int length = lineLength[selStart.Y] - selStart.X;
for (int i = selStart.Y+1; i <= selEnd.Y; i++)
length += lineLength [i];
buffer.BufferCleared += Buffer_BufferCleared;
buffer.SelectionChanged += Buffer_SelectionChanged;
buffer.PositionChanged += Buffer_PositionChanged;
- //buffer.Add ("");
}
#endregion
- string oldSource = "";
- volatile bool isDirty = false;
-
#region private and protected fields
int visibleLines = 1;
int visibleColumns = 1;
TextBuffer buffer;
+ string oldSource = "";
+ volatile bool isDirty = false;
Color selBackground;
Color selForeground;
NotifyValueChanged ("VisibleLines", visibleLines);
updateMaxScrollY ();
RegisterForGraphicUpdate ();
-// System.Diagnostics.Debug.WriteLine ("update visible lines: " + visibleLines);
-// System.Diagnostics.Debug.WriteLine ("update MaxScrollY: " + MaxScrollY);
}
void updateVisibleColumns(){
visibleColumns = (int)Math.Floor ((double)(ClientRectangle.Width)/ fe.MaxXAdvance);
NotifyValueChanged ("VisibleColumns", visibleColumns);
RegisterForGraphicUpdate ();
-// System.Diagnostics.Debug.WriteLine ("update visible columns: {0} leftMargin:{1}",visibleColumns, leftMargin);
-// System.Diagnostics.Debug.WriteLine ("update MaxScrollX: " + MaxScrollX);
}
void updateMaxScrollX (int longestTabulatedLineLength) {
MaxScrollX = Math.Max (0, longestTabulatedLineLength - visibleColumns);
if (lc > 0)
NotifyValueChanged ("ChildHeightRatio", Slot.Height * visibleLines / lc);
- }
-
-
+ }
#region Editor overrides
protected override void updateEditorFromProjFile ()
- {
- buffer.editMutex.EnterWriteLock ();
+ {
loadSource ();
- buffer.editMutex.ExitWriteLock ();
isDirty = false;
oldSource = projFile.Source;
}
#endregion
-
void loadSource () {
buffer.Load (projFile.Source);
projFile.RegisteredEditors [this] = true;
}
int getTabulatedColumn (int col, int line) {
- return buffer.GetSubString (buffer [line],
+ return buffer.GetSubString (buffer.GetBufferIndexOfLine (line),
buffer.GetLineLength (line)).Substring(0,col).Replace ("\t", new String (' ', Interface.TabSize)).Length;
}
int getTabulatedColumn (Point pos) {
int lineLength = buffer.GetLineLength (lineIndex);
if (lineIndex < buffer.LineCount - 1)//dont print line break
lineLength--;
- string lstr = buffer.GetSubString (buffer [lineIndex],
+ string lstr = buffer.GetSubString (buffer.GetBufferIndexOfLine (lineIndex),
lineLength).Replace ("\t", new String (' ', Interface.TabSize));
int lstrLength = lstr.Length;
int getBufferColFromVisualCol (int line, int column) {
int i = 0;
int buffCol = 0;
- int buffPtr = buffer [line];
+ int buffPtr = buffer.GetBufferIndexOfLine (line);
while (i < column && buffCol < buffer.GetLineLength(line)) {
if (buffer.GetCharAt(buffPtr + buffCol) == '\t')
i += Interface.TabSize;
buffer.PositionChanged += Buffer_PositionChanged;
buffer.FoldingEvent += Buffer_FoldingEvent;
buffer.Add (new CodeLine(""));
+
+
}
#endregion
{
Debug.WriteLine("\t\tSourceEditor updateEditorFromProjFile");
- buffer.editMutex.EnterWriteLock ();
loadSource ();
- buffer.editMutex.ExitWriteLock ();
isDirty = false;
oldSource = projFile.Source;
</HorizontalStack>
</Expandable>
<HorizontalStack DataSource="{CurrentSolution}">
- <DbgEventViewer Font="mono, 8" Focusable="true" Name="viewer" DataSource="{SelectedItem}" DebugEvents="{DebugEvents}"/>
+ <DbgEventViewer Font="mono, 10" Background="White" Foreground="Black" Focusable="true" Name="viewer" DataSource="{SelectedItem}" DebugEvents="{DebugEvents}"/>
<ScrollBar
Name="scrollbar1"
LargeIncrement="{../viewer.PageHeight}" SmallIncrement="30"
/// and by template controls to find special element in their template implementation such
/// as a container or a group to put children in.
/// </summary>
- [DesignCategory ("Divers")][DefaultValue(null)]
+ [DesignCategory ("Divers")]
public virtual string Name {
get {
#if DEBUG
protected virtual void close(){
Closing.Raise (this, null);
+ if (IFace.HoverWidget != null) {
+ if (IFace.HoverWidget.IsOrIsInside(this))
+ IFace.HoverWidget = null;
+ }
+ if (IFace.ActiveWidget != null) {
+ if (IFace.ActiveWidget.IsOrIsInside (this))
+ IFace.ActiveWidget = null;
+ }
+ if (IFace.FocusedWidget != null) {
+ if (IFace.FocusedWidget.IsOrIsInside (this))
+ IFace.FocusedWidget = null;
+ }
if (Parent is Interface)
(Parent as Interface).DeleteWidget (this);
else {