From: Jean-Philippe Bruyère Date: Wed, 28 Mar 2018 12:39:21 +0000 (+0200) Subject: debug viewer resizable columns, window checks on close (Hover, Active, Focused) X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=a0bec6014939d54178b79d1bc8b70fbc86662e77;p=jp%2Fcrow.git debug viewer resizable columns, window checks on close (Hover, Active, Focused) --- diff --git a/CrowIDE/CrowIDE.csproj b/CrowIDE/CrowIDE.csproj index 2c50d684..db41eeb3 100644 --- a/CrowIDE/CrowIDE.csproj +++ b/CrowIDE/CrowIDE.csproj @@ -60,6 +60,7 @@ $(SolutionDir)packages\OpenTK.2.0.0\lib\net20\OpenTK.dll + diff --git a/CrowIDE/src/CrowIDE.cs b/CrowIDE/src/CrowIDE.cs index e371379b..8e390473 100644 --- a/CrowIDE/src/CrowIDE.cs +++ b/CrowIDE/src/CrowIDE.cs @@ -33,6 +33,7 @@ using System.Xml; using System.Linq; using Crow.Coding; using System.Threading; +using Mono.CSharp; namespace Crow.Coding { diff --git a/CrowIDE/src/DbgEventViewer.cs b/CrowIDE/src/DbgEventViewer.cs index b49ee608..74a5eed3 100644 --- a/CrowIDE/src/DbgEventViewer.cs +++ b/CrowIDE/src/DbgEventViewer.cs @@ -29,9 +29,25 @@ using Cairo; 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); @@ -39,6 +55,10 @@ namespace Crow.Coding int visibleLines = 1; int visibleColumns = 1; int hoverLine = -1; + int columnMargin = 4; + List Columns = new List(); + int hoverColIdx = -1; + bool sizingCol = false; //true during resize of column with mouse List selectedLines = new List(); Point mouseLocalPos; Color selBackground, selForeground, hoverBackground; @@ -107,7 +127,10 @@ namespace Crow.Coding if (debugEvents == value) return; evtsMTX.EnterWriteLock (); - debugEvents = value; + if (value == null) + debugEvents = null; + else + debugEvents = value.ToList(); evtsMTX.ExitWriteLock (); NotifyValueChanged ("DebugEvent", debugEvents); @@ -204,41 +227,90 @@ namespace Crow.Coding 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 (); } @@ -246,12 +318,46 @@ namespace Crow.Coding { 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)) @@ -274,11 +380,20 @@ namespace Crow.Coding 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 { @@ -317,7 +432,7 @@ namespace Crow.Coding 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 (); @@ -363,6 +478,18 @@ namespace Crow.Coding 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)); + } } } diff --git a/CrowIDE/src/Editors/CodeBuffer/CodeBuffer.cs b/CrowIDE/src/Editors/CodeBuffer/CodeBuffer.cs index 7d5efec9..cf11d109 100644 --- a/CrowIDE/src/Editors/CodeBuffer/CodeBuffer.cs +++ b/CrowIDE/src/Editors/CodeBuffer/CodeBuffer.cs @@ -149,14 +149,16 @@ namespace Crow.Coding 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 (); } /// diff --git a/CrowIDE/src/Editors/CodeBuffer/TextBuffer.cs b/CrowIDE/src/Editors/CodeBuffer/TextBuffer.cs index e8c87182..806e9064 100644 --- a/CrowIDE/src/Editors/CodeBuffer/TextBuffer.cs +++ b/CrowIDE/src/Editors/CodeBuffer/TextBuffer.cs @@ -29,7 +29,7 @@ using System.Text; namespace Crow.Text { /// - /// Code buffer, lines are arranged in a List, new line chars are removed during string.split on '\n...', + /// text buffer in single piece with lines /// public class TextBuffer { @@ -54,6 +54,8 @@ namespace Crow.Text /// int _currentLine = 0; int _currentCol = 0; + Point selStartPos = -1; //selection start (row,column) + Point selEndPos = -1; //selection end (row,column) /// /// Gets the total line count. @@ -103,9 +105,8 @@ namespace Crow.Text 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; } @@ -116,18 +117,6 @@ namespace Crow.Text 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; - } - } /// /// remove line number i /// @@ -146,7 +135,7 @@ namespace Crow.Text /// linebreak free string 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)); @@ -178,7 +167,7 @@ namespace Crow.Text } 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; @@ -187,7 +176,7 @@ namespace Crow.Text } 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); @@ -207,7 +196,7 @@ namespace Crow.Text 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; @@ -242,7 +231,7 @@ namespace Crow.Text 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; @@ -261,7 +250,7 @@ namespace Crow.Text 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; @@ -275,11 +264,11 @@ namespace Crow.Text 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 ) { @@ -303,10 +292,14 @@ namespace Crow.Text 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 @@ -321,19 +314,11 @@ namespace Crow.Text 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; @@ -422,12 +407,12 @@ namespace Crow.Text /// Current position in buffer coordinate, tabulation = 1 char /// public Point CurrentPosition { - get { return new Point(CurrentColumn, CurrentLine); } + get { return new Point(_currentCol, _currentLine); } } /// /// get char at current position in buffer /// - protected Char CurrentChar { get { return buffer[this [CurrentLine]]; } } + protected Char CurrentChar { get { return buffer[GetBufferIndexOfLine (_currentLine)+_currentCol]; } } public string SelectedText { get { if (SelectionIsEmpty) @@ -435,7 +420,7 @@ namespace Crow.Text 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]; diff --git a/CrowIDE/src/Editors/CodeBuffer/TextEditor.cs b/CrowIDE/src/Editors/CodeBuffer/TextEditor.cs index 81abe482..d743e149 100644 --- a/CrowIDE/src/Editors/CodeBuffer/TextEditor.cs +++ b/CrowIDE/src/Editors/CodeBuffer/TextEditor.cs @@ -54,18 +54,16 @@ namespace Crow.Text 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; @@ -88,15 +86,11 @@ namespace Crow.Text 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); @@ -109,16 +103,12 @@ namespace Crow.Text 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; @@ -267,7 +257,6 @@ namespace Crow.Text } #endregion - void loadSource () { buffer.Load (projFile.Source); projFile.RegisteredEditors [this] = true; @@ -276,7 +265,7 @@ namespace Crow.Text } 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) { @@ -296,7 +285,7 @@ namespace Crow.Text 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; @@ -422,7 +411,7 @@ namespace Crow.Text 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; diff --git a/CrowIDE/src/Editors/SourceEditor.cs b/CrowIDE/src/Editors/SourceEditor.cs index 7e949451..ceea83f7 100644 --- a/CrowIDE/src/Editors/SourceEditor.cs +++ b/CrowIDE/src/Editors/SourceEditor.cs @@ -79,6 +79,8 @@ namespace Crow.Coding buffer.PositionChanged += Buffer_PositionChanged; buffer.FoldingEvent += Buffer_FoldingEvent; buffer.Add (new CodeLine("")); + + } #endregion @@ -214,9 +216,7 @@ namespace Crow.Coding { Debug.WriteLine("\t\tSourceEditor updateEditorFromProjFile"); - buffer.editMutex.EnterWriteLock (); loadSource (); - buffer.editMutex.ExitWriteLock (); isDirty = false; oldSource = projFile.Source; diff --git a/CrowIDE/ui/DockWindows/winDbgEvts.crow b/CrowIDE/ui/DockWindows/winDbgEvts.crow index 1e314a13..ae07fbc5 100644 --- a/CrowIDE/ui/DockWindows/winDbgEvts.crow +++ b/CrowIDE/ui/DockWindows/winDbgEvts.crow @@ -26,7 +26,7 @@ - + - [DesignCategory ("Divers")][DefaultValue(null)] + [DesignCategory ("Divers")] public virtual string Name { get { #if DEBUG diff --git a/src/GraphicObjects/Window.cs b/src/GraphicObjects/Window.cs index fe033cc2..e18b4a49 100644 --- a/src/GraphicObjects/Window.cs +++ b/src/GraphicObjects/Window.cs @@ -439,6 +439,18 @@ namespace Crow 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 {