2
0
Tig 9 сар өмнө
parent
commit
fbacbcea0e

+ 110 - 93
Terminal.Gui/Views/HexView.cs

@@ -31,12 +31,8 @@ public class HexView : View, IDesignable
     private const int BSIZE = 4;
     private const int BSIZE = 4;
     private const int DISPLAY_WIDTH = 9;
     private const int DISPLAY_WIDTH = 9;
 
 
-    private int _bpl;
-    private long _displayStart, _pos;
-    private SortedDictionary<long, byte> _edits = [];
     private bool _firstNibble;
     private bool _firstNibble;
     private bool _leftSide;
     private bool _leftSide;
-    private Stream? _source;
     private static readonly Rune _spaceCharRune = new (' ');
     private static readonly Rune _spaceCharRune = new (' ');
     private static readonly Rune _periodCharRune = new ('.');
     private static readonly Rune _periodCharRune = new ('.');
 
 
@@ -60,21 +56,21 @@ public class HexView : View, IDesignable
         // Things this view knows how to do
         // Things this view knows how to do
         AddCommand (Command.Left, () => MoveLeft ());
         AddCommand (Command.Left, () => MoveLeft ());
         AddCommand (Command.Right, () => MoveRight ());
         AddCommand (Command.Right, () => MoveRight ());
-        AddCommand (Command.Down, () => MoveDown (bytesPerLine));
-        AddCommand (Command.Up, () => MoveUp (bytesPerLine));
+        AddCommand (Command.Down, () => MoveDown (BytesPerLine));
+        AddCommand (Command.Up, () => MoveUp (BytesPerLine));
         AddCommand (Command.Tab, () => Navigate (NavigationDirection.Forward));
         AddCommand (Command.Tab, () => Navigate (NavigationDirection.Forward));
         AddCommand (Command.BackTab, () => Navigate (NavigationDirection.Backward));
         AddCommand (Command.BackTab, () => Navigate (NavigationDirection.Backward));
-        AddCommand (Command.PageUp, () => MoveUp (bytesPerLine * Frame.Height));
-        AddCommand (Command.PageDown, () => MoveDown (bytesPerLine * Frame.Height));
+        AddCommand (Command.PageUp, () => MoveUp (BytesPerLine * Frame.Height));
+        AddCommand (Command.PageDown, () => MoveDown (BytesPerLine * Frame.Height));
         AddCommand (Command.Start, () => MoveHome ());
         AddCommand (Command.Start, () => MoveHome ());
         AddCommand (Command.End, () => MoveEnd ());
         AddCommand (Command.End, () => MoveEnd ());
         AddCommand (Command.LeftStart, () => MoveLeftStart ());
         AddCommand (Command.LeftStart, () => MoveLeftStart ());
         AddCommand (Command.RightEnd, () => MoveEndOfLine ());
         AddCommand (Command.RightEnd, () => MoveEndOfLine ());
-        AddCommand (Command.StartOfPage, () => MoveUp (bytesPerLine * ((int)(position - _displayStart) / bytesPerLine)));
+        AddCommand (Command.StartOfPage, () => MoveUp (BytesPerLine * ((int)(position - _displayStart) / BytesPerLine)));
 
 
         AddCommand (
         AddCommand (
                     Command.EndOfPage,
                     Command.EndOfPage,
-                    () => MoveDown (bytesPerLine * (Frame.Height - 1 - (int)(position - _displayStart) / bytesPerLine))
+                    () => MoveDown (BytesPerLine * (Frame.Height - 1 - (int)(position - _displayStart) / BytesPerLine))
                    );
                    );
 
 
         // Default keybindings for this view
         // Default keybindings for this view
@@ -112,9 +108,6 @@ public class HexView : View, IDesignable
     /// <value><c>true</c> if allow edits; otherwise, <c>false</c>.</value>
     /// <value><c>true</c> if allow edits; otherwise, <c>false</c>.</value>
     public bool AllowEdits { get; set; } = true;
     public bool AllowEdits { get; set; } = true;
 
 
-    /// <summary>The bytes length per line.</summary>
-    public int BytesPerLine => bytesPerLine;
-
     /// <summary>Gets the current cursor position starting at one for both, line and column.</summary>
     /// <summary>Gets the current cursor position starting at one for both, line and column.</summary>
     public Point CursorPosition
     public Point CursorPosition
     {
     {
@@ -126,28 +119,14 @@ public class HexView : View, IDesignable
             }
             }
 
 
             var delta = (int)position;
             var delta = (int)position;
-            int line = delta / bytesPerLine + 1;
-            int item = delta % bytesPerLine + 1;
+            int line = delta / BytesPerLine + 1;
+            int item = delta % BytesPerLine + 1;
 
 
             return new (item, line);
             return new (item, line);
         }
         }
     }
     }
 
 
-    /// <summary>
-    ///     Sets or gets the offset into the <see cref="Stream"/> that will be displayed at the top of the
-    ///     <see cref="HexView"/>
-    /// </summary>
-    /// <value>The display start.</value>
-    public long DisplayStart
-    {
-        get => _displayStart;
-        set
-        {
-            position = value;
-
-            SetDisplayStart (value);
-        }
-    }
+    private SortedDictionary<long, byte> _edits = [];
 
 
     /// <summary>
     /// <summary>
     ///     Gets a <see cref="SortedDictionary{TKey, TValue}"/> describing the edits done to the <see cref="HexView"/>.
     ///     Gets a <see cref="SortedDictionary{TKey, TValue}"/> describing the edits done to the <see cref="HexView"/>.
@@ -156,8 +135,8 @@ public class HexView : View, IDesignable
     /// <value>The edits.</value>
     /// <value>The edits.</value>
     public IReadOnlyDictionary<long, byte> Edits => _edits;
     public IReadOnlyDictionary<long, byte> Edits => _edits;
 
 
-    /// <summary>Gets the current character position starting at one, related to the <see cref="Stream"/>.</summary>
-    public long Position => position + 1;
+
+    private Stream? _source;
 
 
     /// <summary>
     /// <summary>
     ///     Sets or gets the <see cref="Stream"/> the <see cref="HexView"/> is operating on; the stream must support
     ///     Sets or gets the <see cref="Stream"/> the <see cref="HexView"/> is operating on; the stream must support
@@ -169,14 +148,11 @@ public class HexView : View, IDesignable
         get => _source;
         get => _source;
         set
         set
         {
         {
-            if (value is null)
-            {
-                throw new ArgumentNullException ("source");
-            }
+            ArgumentNullException.ThrowIfNull (value);
 
 
-            if (!value.CanSeek)
+            if (!value!.CanSeek)
             {
             {
-                throw new ArgumentException ("The source stream must be seekable (CanSeek property)", "source");
+                throw new ArgumentException (@"The source stream must be seekable (CanSeek property)");
             }
             }
 
 
             _source = value;
             _source = value;
@@ -195,7 +171,10 @@ public class HexView : View, IDesignable
         }
         }
     }
     }
 
 
-    private int bytesPerLine
+    private int _bpl;
+
+    /// <summary>The bytes length per line.</summary>
+    public int BytesPerLine
     {
     {
         get => _bpl;
         get => _bpl;
         set
         set
@@ -205,6 +184,13 @@ public class HexView : View, IDesignable
         }
         }
     }
     }
 
 
+
+    private long _pos;
+
+    // TODO: Why is this "starting at one"? How does that make sense?
+    /// <summary>Gets the current character position starting at one, related to the <see cref="Stream"/>.</summary>
+    public long Position => position + 1;
+
     private long position
     private long position
     {
     {
         get => _pos;
         get => _pos;
@@ -215,17 +201,55 @@ public class HexView : View, IDesignable
         }
         }
     }
     }
 
 
+    private long _displayStart;
+
+    // TODO: Use Viewport content scrolling instead
     /// <summary>
     /// <summary>
-    ///     This method applies and edits made to the <see cref="Stream"/> and resets the contents of the
+    ///     Sets or gets the offset into the <see cref="Stream"/> that will be displayed at the top of the
+    ///     <see cref="HexView"/>.
+    /// </summary>
+    /// <value>The display start.</value>
+    public long DisplayStart
+    {
+        get => _displayStart;
+        set
+        {
+            position = value;
+
+            SetDisplayStart (value);
+        }
+    }
+
+    internal void SetDisplayStart (long value)
+    {
+        if (value > 0 && value >= _source.Length)
+        {
+            _displayStart = _source.Length - 1;
+        }
+        else if (value < 0)
+        {
+            _displayStart = 0;
+        }
+        else
+        {
+            _displayStart = value;
+        }
+
+        SetNeedsDisplay ();
+    }
+
+
+    /// <summary>
+    ///     Applies and edits made to the <see cref="Stream"/> and resets the contents of the
     ///     <see cref="Edits"/> property.
     ///     <see cref="Edits"/> property.
     /// </summary>
     /// </summary>
-    /// <param name="stream">If provided also applies the changes to the passed <see cref="Stream"/></param>
+    /// <param name="stream">If provided also applies the changes to the passed <see cref="Stream"/>.</param>
     /// .
     /// .
-    public void ApplyEdits (Stream stream = null)
+    public void ApplyEdits (Stream? stream = null)
     {
     {
         foreach (KeyValuePair<long, byte> kv in _edits)
         foreach (KeyValuePair<long, byte> kv in _edits)
         {
         {
-            _source.Position = kv.Key;
+            _source!.Position = kv.Key;
             _source.WriteByte (kv.Value);
             _source.WriteByte (kv.Value);
             _source.Flush ();
             _source.Flush ();
 
 
@@ -242,14 +266,11 @@ public class HexView : View, IDesignable
     }
     }
 
 
     /// <summary>
     /// <summary>
-    ///     This method discards the edits made to the <see cref="Stream"/> by resetting the contents of the
+    ///     Discards the edits made to the <see cref="Stream"/> by resetting the contents of the
     ///     <see cref="Edits"/> property.
     ///     <see cref="Edits"/> property.
     /// </summary>
     /// </summary>
     public void DiscardEdits () { _edits = new (); }
     public void DiscardEdits () { _edits = new (); }
 
 
-    /// <summary>Event to be invoked when an edit is made on the <see cref="Stream"/>.</summary>
-    public event EventHandler<HexViewEditEventArgs>? Edited;
-
     /// <inheritdoc/>
     /// <inheritdoc/>
     protected internal override bool OnMouseEvent (MouseEvent me)
     protected internal override bool OnMouseEvent (MouseEvent me)
     {
     {
@@ -268,14 +289,14 @@ public class HexView : View, IDesignable
 
 
         if (me.Flags == MouseFlags.WheeledDown)
         if (me.Flags == MouseFlags.WheeledDown)
         {
         {
-            DisplayStart = Math.Min (DisplayStart + bytesPerLine, _source.Length);
+            DisplayStart = Math.Min (DisplayStart + BytesPerLine, _source.Length);
 
 
             return true;
             return true;
         }
         }
 
 
         if (me.Flags == MouseFlags.WheeledUp)
         if (me.Flags == MouseFlags.WheeledUp)
         {
         {
-            DisplayStart = Math.Max (DisplayStart - bytesPerLine, 0);
+            DisplayStart = Math.Max (DisplayStart - BytesPerLine, 0);
 
 
             return true;
             return true;
         }
         }
@@ -285,17 +306,17 @@ public class HexView : View, IDesignable
             return true;
             return true;
         }
         }
 
 
-        int nblocks = bytesPerLine / BSIZE;
+        int nblocks = BytesPerLine / BSIZE;
         int blocksSize = nblocks * 14;
         int blocksSize = nblocks * 14;
         int blocksRightOffset = DISPLAY_WIDTH + blocksSize - 1;
         int blocksRightOffset = DISPLAY_WIDTH + blocksSize - 1;
 
 
-        if (me.Position.X > blocksRightOffset + bytesPerLine - 1)
+        if (me.Position.X > blocksRightOffset + BytesPerLine - 1)
         {
         {
             return true;
             return true;
         }
         }
 
 
         _leftSide = me.Position.X >= blocksRightOffset;
         _leftSide = me.Position.X >= blocksRightOffset;
-        long lineStart = me.Position.Y * bytesPerLine + _displayStart;
+        long lineStart = me.Position.Y * BytesPerLine + _displayStart;
         int x = me.Position.X - DISPLAY_WIDTH + 1;
         int x = me.Position.X - DISPLAY_WIDTH + 1;
         int block = x / 14;
         int block = x / 14;
         x -= block * 2;
         x -= block * 2;
@@ -345,7 +366,7 @@ public class HexView : View, IDesignable
         Driver.SetAttribute (current);
         Driver.SetAttribute (current);
         Move (0, 0);
         Move (0, 0);
 
 
-        int nblocks = bytesPerLine / BSIZE;
+        int nblocks = BytesPerLine / BSIZE;
         var data = new byte [nblocks * BSIZE * viewport.Height];
         var data = new byte [nblocks * BSIZE * viewport.Height];
         Source.Position = _displayStart;
         Source.Position = _displayStart;
         int n = _source.Read (data, 0, data.Length);
         int n = _source.Read (data, 0, data.Length);
@@ -444,7 +465,21 @@ public class HexView : View, IDesignable
 
 
     /// <summary>Method used to invoke the <see cref="Edited"/> event passing the <see cref="KeyValuePair{TKey, TValue}"/>.</summary>
     /// <summary>Method used to invoke the <see cref="Edited"/> event passing the <see cref="KeyValuePair{TKey, TValue}"/>.</summary>
     /// <param name="e">The key value pair.</param>
     /// <param name="e">The key value pair.</param>
-    public virtual void OnEdited (HexViewEditEventArgs e) { Edited?.Invoke (this, e); }
+    protected void RaiseEdited (HexViewEditEventArgs e)
+    {
+        OnEditied(e);
+        Edited?.Invoke (this, e);
+    }
+
+
+    /// <summary>Event to be invoked when an edit is made on the <see cref="Stream"/>.</summary>
+    public event EventHandler<HexViewEditEventArgs>? Edited;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="e"></param>
+    protected virtual void OnEditied (HexViewEditEventArgs e) { }
 
 
     /// <summary>
     /// <summary>
     ///     Method used to invoke the <see cref="PositionChanged"/> event passing the <see cref="HexViewEventArgs"/>
     ///     Method used to invoke the <see cref="PositionChanged"/> event passing the <see cref="HexViewEventArgs"/>
@@ -503,13 +538,13 @@ public class HexView : View, IDesignable
                 _firstNibble = false;
                 _firstNibble = false;
                 b = (byte)((b & 0xf) | (value << BSIZE));
                 b = (byte)((b & 0xf) | (value << BSIZE));
                 _edits [position] = b;
                 _edits [position] = b;
-                OnEdited (new (position, _edits [position]));
+                RaiseEdited (new (position, _edits [position]));
             }
             }
             else
             else
             {
             {
                 b = (byte)((b & 0xf0) | value);
                 b = (byte)((b & 0xf0) | value);
                 _edits [position] = b;
                 _edits [position] = b;
-                OnEdited (new (position, _edits [position]));
+                RaiseEdited (new (position, _edits [position]));
                 MoveRight ();
                 MoveRight ();
             }
             }
 
 
@@ -526,8 +561,8 @@ public class HexView : View, IDesignable
     public override Point? PositionCursor ()
     public override Point? PositionCursor ()
     {
     {
         var delta = (int)(position - _displayStart);
         var delta = (int)(position - _displayStart);
-        int line = delta / bytesPerLine;
-        int item = delta % bytesPerLine;
+        int line = delta / BytesPerLine;
+        int item = delta % BytesPerLine;
         int block = item / BSIZE;
         int block = item / BSIZE;
         int column = item % BSIZE * 3;
         int column = item % BSIZE * 3;
 
 
@@ -536,7 +571,7 @@ public class HexView : View, IDesignable
 
 
         if (!_leftSide)
         if (!_leftSide)
         {
         {
-            x = DISPLAY_WIDTH + bytesPerLine / BSIZE * 14 + item - 1;
+            x = DISPLAY_WIDTH + BytesPerLine / BSIZE * 14 + item - 1;
         }
         }
 
 
         Move (x, y);
         Move (x, y);
@@ -544,24 +579,6 @@ public class HexView : View, IDesignable
         return new (x, y);
         return new (x, y);
     }
     }
 
 
-    internal void SetDisplayStart (long value)
-    {
-        if (value > 0 && value >= _source.Length)
-        {
-            _displayStart = _source.Length - 1;
-        }
-        else if (value < 0)
-        {
-            _displayStart = 0;
-        }
-        else
-        {
-            _displayStart = value;
-        }
-
-        SetNeedsDisplay ();
-    }
-
     //
     //
     // This is used to support editing of the buffer on a peer List<>,
     // This is used to support editing of the buffer on a peer List<>,
     // the offset corresponds to an offset relative to DisplayStart, and
     // the offset corresponds to an offset relative to DisplayStart, and
@@ -588,11 +605,11 @@ public class HexView : View, IDesignable
     private void HexView_LayoutComplete (object? sender, LayoutEventArgs e)
     private void HexView_LayoutComplete (object? sender, LayoutEventArgs e)
     {
     {
         // Small buffers will just show the position, with the bsize field value (4 bytes)
         // Small buffers will just show the position, with the bsize field value (4 bytes)
-        bytesPerLine = BSIZE;
+        BytesPerLine = BSIZE;
 
 
         if (Viewport.Width - DISPLAY_WIDTH > 17)
         if (Viewport.Width - DISPLAY_WIDTH > 17)
         {
         {
-            bytesPerLine = BSIZE * ((Viewport.Width - DISPLAY_WIDTH) / 18);
+            BytesPerLine = BSIZE * ((Viewport.Width - DISPLAY_WIDTH) / 18);
         }
         }
     }
     }
 
 
@@ -604,21 +621,21 @@ public class HexView : View, IDesignable
         {
         {
             position += bytes;
             position += bytes;
         }
         }
-        else if ((bytes == bytesPerLine * Viewport.Height && _source.Length >= DisplayStart + bytesPerLine * Viewport.Height)
-                 || (bytes <= bytesPerLine * Viewport.Height - bytesPerLine
-                     && _source.Length <= DisplayStart + bytesPerLine * Viewport.Height))
+        else if ((bytes == BytesPerLine * Viewport.Height && _source.Length >= DisplayStart + BytesPerLine * Viewport.Height)
+                 || (bytes <= BytesPerLine * Viewport.Height - BytesPerLine
+                     && _source.Length <= DisplayStart + BytesPerLine * Viewport.Height))
         {
         {
             long p = position;
             long p = position;
 
 
-            while (p + bytesPerLine < _source.Length)
+            while (p + BytesPerLine < _source.Length)
             {
             {
-                p += bytesPerLine;
+                p += BytesPerLine;
             }
             }
 
 
             position = p;
             position = p;
         }
         }
 
 
-        if (position >= DisplayStart + bytesPerLine * Viewport.Height)
+        if (position >= DisplayStart + BytesPerLine * Viewport.Height)
         {
         {
             SetDisplayStart (DisplayStart + bytes);
             SetDisplayStart (DisplayStart + bytes);
             SetNeedsDisplay ();
             SetNeedsDisplay ();
@@ -635,7 +652,7 @@ public class HexView : View, IDesignable
     {
     {
         position = _source.Length;
         position = _source.Length;
 
 
-        if (position >= DisplayStart + bytesPerLine * Viewport.Height)
+        if (position >= DisplayStart + BytesPerLine * Viewport.Height)
         {
         {
             SetDisplayStart (position);
             SetDisplayStart (position);
             SetNeedsDisplay ();
             SetNeedsDisplay ();
@@ -650,7 +667,7 @@ public class HexView : View, IDesignable
 
 
     private bool MoveEndOfLine ()
     private bool MoveEndOfLine ()
     {
     {
-        position = Math.Min (position / bytesPerLine * bytesPerLine + bytesPerLine - 1, _source.Length);
+        position = Math.Min (position / BytesPerLine * BytesPerLine + BytesPerLine - 1, _source.Length);
         SetNeedsDisplay ();
         SetNeedsDisplay ();
 
 
         return true;
         return true;
@@ -687,7 +704,7 @@ public class HexView : View, IDesignable
 
 
         if (position - 1 < DisplayStart)
         if (position - 1 < DisplayStart)
         {
         {
-            SetDisplayStart (_displayStart - bytesPerLine);
+            SetDisplayStart (_displayStart - BytesPerLine);
             SetNeedsDisplay ();
             SetNeedsDisplay ();
         }
         }
         else
         else
@@ -721,9 +738,9 @@ public class HexView : View, IDesignable
             position++;
             position++;
         }
         }
 
 
-        if (position >= DisplayStart + bytesPerLine * Viewport.Height)
+        if (position >= DisplayStart + BytesPerLine * Viewport.Height)
         {
         {
-            SetDisplayStart (DisplayStart + bytesPerLine);
+            SetDisplayStart (DisplayStart + BytesPerLine);
             SetNeedsDisplay ();
             SetNeedsDisplay ();
         }
         }
         else
         else
@@ -736,7 +753,7 @@ public class HexView : View, IDesignable
 
 
     private bool MoveLeftStart ()
     private bool MoveLeftStart ()
     {
     {
-        position = position / bytesPerLine * bytesPerLine;
+        position = position / BytesPerLine * BytesPerLine;
         SetNeedsDisplay ();
         SetNeedsDisplay ();
 
 
         return true;
         return true;
@@ -766,13 +783,13 @@ public class HexView : View, IDesignable
 
 
     private void RedisplayLine (long pos)
     private void RedisplayLine (long pos)
     {
     {
-        if (bytesPerLine == 0)
+        if (BytesPerLine == 0)
         {
         {
             return;
             return;
         }
         }
 
 
         var delta = (int)(pos - DisplayStart);
         var delta = (int)(pos - DisplayStart);
-        int line = delta / bytesPerLine;
+        int line = delta / BytesPerLine;
 
 
         SetNeedsDisplay (new (0, line, Viewport.Width, 1));
         SetNeedsDisplay (new (0, line, Viewport.Width, 1));
     }
     }