2023-07-29 23:37:10 +05:30

317 lines
9.5 KiB
C#

using System;
using System.Drawing;
using System.Windows.Forms;
namespace Server.Helper.HexEditor;
public class HexViewHandler
{
private bool _isEditing;
private string _hexType = "X2";
private Rectangle _recHexValue;
private StringFormat _stringFormat;
private HexEditor _editor;
public int MaxWidth => _recHexValue.X + _recHexValue.Width * _editor.BytesPerLine;
public HexViewHandler(HexEditor editor)
{
_editor = editor;
_stringFormat = new StringFormat(StringFormat.GenericTypographic);
_stringFormat.Alignment = StringAlignment.Center;
_stringFormat.LineAlignment = StringAlignment.Center;
}
public void OnKeyPress(KeyPressEventArgs e)
{
if (IsHex(e.KeyChar))
{
HandleUserInput(e.KeyChar);
}
}
public void OnKeyDown(KeyEventArgs e)
{
if (e.KeyCode == Keys.Delete || e.KeyCode == Keys.Back)
{
if (_editor.SelectionLength > 0)
{
HandleUserRemove();
int caretIndex = _editor.CaretIndex;
Point caretLocation = GetCaretLocation(caretIndex);
_editor.SetCaretStart(caretIndex, caretLocation);
}
else if (_editor.CaretIndex < _editor.LastVisibleByte && e.KeyCode == Keys.Delete)
{
_editor.RemoveByteAt(_editor.CaretIndex);
Point caretLocation2 = GetCaretLocation(_editor.CaretIndex);
_editor.SetCaretStart(_editor.CaretIndex, caretLocation2);
}
else if (_editor.CaretIndex > 0 && e.KeyCode == Keys.Back)
{
int index = _editor.CaretIndex - 1;
if (_isEditing)
{
index = _editor.CaretIndex;
}
_editor.RemoveByteAt(index);
Point caretLocation3 = GetCaretLocation(index);
_editor.SetCaretStart(index, caretLocation3);
}
_isEditing = false;
}
else if (e.KeyCode == Keys.Up && _editor.CaretIndex - _editor.BytesPerLine >= 0)
{
int num = _editor.CaretIndex - _editor.BytesPerLine;
if (num % _editor.BytesPerLine == 0 && _editor.CaretPosX >= _recHexValue.X + _recHexValue.Width * _editor.BytesPerLine)
{
Point location = new Point(_editor.CaretPosX, _editor.CaretPosY - _recHexValue.Height);
if (num == 0)
{
location = new Point(_editor.CaretPosX, _editor.CaretPosY);
num = _editor.BytesPerLine;
}
if (e.Shift)
{
_editor.SetCaretEnd(num, location);
}
else
{
_editor.SetCaretStart(num, location);
}
_isEditing = false;
}
else
{
HandleArrowKeys(num, e.Shift);
}
}
else if (e.KeyCode == Keys.Down && (_editor.CaretIndex - 1) / _editor.BytesPerLine < _editor.HexTableLength / _editor.BytesPerLine)
{
int num2 = _editor.CaretIndex + _editor.BytesPerLine;
if (num2 > _editor.HexTableLength)
{
num2 = _editor.HexTableLength;
HandleArrowKeys(num2, e.Shift);
return;
}
Point location2 = new Point(_editor.CaretPosX, _editor.CaretPosY + _recHexValue.Height);
if (e.Shift)
{
_editor.SetCaretEnd(num2, location2);
}
else
{
_editor.SetCaretStart(num2, location2);
}
_isEditing = false;
}
else if (e.KeyCode == Keys.Left && _editor.CaretIndex - 1 >= 0)
{
int index2 = _editor.CaretIndex - 1;
HandleArrowKeys(index2, e.Shift);
}
else if (e.KeyCode == Keys.Right && _editor.CaretIndex + 1 <= _editor.HexTableLength)
{
int index3 = _editor.CaretIndex + 1;
HandleArrowKeys(index3, e.Shift);
}
}
public void HandleArrowKeys(int index, bool isShiftDown)
{
Point caretLocation = GetCaretLocation(index);
if (isShiftDown)
{
_editor.SetCaretEnd(index, caretLocation);
}
else
{
_editor.SetCaretStart(index, caretLocation);
}
_isEditing = false;
}
public void OnMouseDown(int x, int y)
{
int num = (x - _recHexValue.X) / _recHexValue.Width;
int num2 = (y - _recHexValue.Y) / _recHexValue.Height;
num = ((num > _editor.BytesPerLine) ? _editor.BytesPerLine : num);
num = ((num >= 0) ? num : 0);
num2 = ((num2 > _editor.MaxBytesV) ? _editor.MaxBytesV : num2);
num2 = ((num2 >= 0) ? num2 : 0);
if ((_editor.LastVisibleByte - _editor.FirstVisibleByte) / _editor.BytesPerLine <= num2)
{
if ((_editor.LastVisibleByte - _editor.FirstVisibleByte) % _editor.BytesPerLine <= num)
{
num = (_editor.LastVisibleByte - _editor.FirstVisibleByte) % _editor.BytesPerLine;
}
num2 = (_editor.LastVisibleByte - _editor.FirstVisibleByte) / _editor.BytesPerLine;
}
int index = Math.Min(_editor.LastVisibleByte, _editor.FirstVisibleByte + num + num2 * _editor.BytesPerLine);
int x2 = num * _recHexValue.Width + _recHexValue.X;
int y2 = num2 * _recHexValue.Height + _recHexValue.Y;
_editor.SetCaretStart(index, new Point(x2, y2));
_isEditing = false;
}
public void OnMouseDragged(int x, int y)
{
int num = (x - _recHexValue.X) / _recHexValue.Width;
int num2 = (y - _recHexValue.Y) / _recHexValue.Height;
num = ((num > _editor.BytesPerLine) ? _editor.BytesPerLine : num);
num = ((num >= 0) ? num : 0);
num2 = ((num2 > _editor.MaxBytesV) ? _editor.MaxBytesV : num2);
num2 = ((_editor.FirstVisibleByte <= 0) ? ((num2 >= 0) ? num2 : 0) : ((num2 < 0) ? (-1) : num2));
if ((_editor.LastVisibleByte - _editor.FirstVisibleByte) / _editor.BytesPerLine <= num2)
{
if ((_editor.LastVisibleByte - _editor.FirstVisibleByte) % _editor.BytesPerLine <= num)
{
num = (_editor.LastVisibleByte - _editor.FirstVisibleByte) % _editor.BytesPerLine;
}
num2 = (_editor.LastVisibleByte - _editor.FirstVisibleByte) / _editor.BytesPerLine;
}
int index = Math.Min(_editor.LastVisibleByte, _editor.FirstVisibleByte + num + num2 * _editor.BytesPerLine);
int x2 = num * _recHexValue.Width + _recHexValue.X;
int y2 = num2 * _recHexValue.Height + _recHexValue.Y;
_editor.SetCaretEnd(index, new Point(x2, y2));
}
public void OnMouseDoubleClick()
{
if (_editor.CaretIndex < _editor.LastVisibleByte)
{
int index = _editor.CaretIndex + 1;
Point caretLocation = GetCaretLocation(index);
_editor.SetCaretEnd(index, caretLocation);
}
}
public void Update(int startPositionX, Rectangle area)
{
_recHexValue = new Rectangle(startPositionX, area.Y, (int)(_editor.CharSize.Width * 3f), (int)_editor.CharSize.Height - 2);
_recHexValue.X += _editor.EntityMargin;
}
public void Paint(Graphics g, int index, int startIndex)
{
Point byteColumnAndRow = GetByteColumnAndRow(index);
if (_editor.IsSelected(index + startIndex))
{
PaintByteAsSelected(g, byteColumnAndRow, index + startIndex);
}
else
{
PaintByte(g, byteColumnAndRow, index + startIndex);
}
}
private void PaintByteAsSelected(Graphics g, Point point, int index)
{
SolidBrush brush = new SolidBrush(_editor.SelectionBackColor);
SolidBrush brush2 = new SolidBrush(_editor.SelectionForeColor);
RectangleF bound = GetBound(point);
string s = _editor.GetByte(index).ToString(_hexType);
g.FillRectangle(brush, bound);
g.DrawString(s, _editor.Font, brush2, bound, _stringFormat);
}
private void PaintByte(Graphics g, Point point, int index)
{
SolidBrush brush = new SolidBrush(_editor.ForeColor);
RectangleF bound = GetBound(point);
string s = _editor.GetByte(index).ToString(_hexType);
g.DrawString(s, _editor.Font, brush, bound, _stringFormat);
}
public void SetLowerCase()
{
_hexType = "x2";
}
public void SetUpperCase()
{
_hexType = "X2";
}
public void Focus()
{
int caretIndex = _editor.CaretIndex;
Point caretLocation = GetCaretLocation(caretIndex);
_editor.SetCaretStart(caretIndex, caretLocation);
}
private Point GetCaretLocation(int index)
{
int x = _recHexValue.X + _recHexValue.Width * (index % _editor.BytesPerLine);
int y = _recHexValue.Y + _recHexValue.Height * ((index - (_editor.FirstVisibleByte + index % _editor.BytesPerLine)) / _editor.BytesPerLine);
return new Point(x, y);
}
private void HandleUserRemove()
{
int selectionStart = _editor.SelectionStart;
Point caretLocation = GetCaretLocation(selectionStart);
_editor.RemoveSelectedBytes();
_editor.SetCaretStart(selectionStart, caretLocation);
}
private void HandleUserInput(char key)
{
if (!_editor.CaretFocused)
{
return;
}
HandleUserRemove();
if (_isEditing)
{
_isEditing = false;
byte @byte = _editor.GetByte(_editor.CaretIndex);
@byte = (byte)(@byte + Convert.ToByte(key.ToString(), 16));
_editor.SetByte(_editor.CaretIndex, @byte);
int index = _editor.CaretIndex + 1;
Point caretLocation = GetCaretLocation(index);
_editor.SetCaretStart(index, caretLocation);
return;
}
_isEditing = true;
byte item = Convert.ToByte(key + "0", 16);
if (_editor.HexTable.Length == 0)
{
_editor.AppendByte(item);
}
else
{
_editor.InsertByte(_editor.CaretIndex, item);
}
int x = _recHexValue.X + _recHexValue.Width * (_editor.CaretIndex % _editor.BytesPerLine) + _recHexValue.Width / 2;
int y = _recHexValue.Y + _recHexValue.Height * ((_editor.CaretIndex - (_editor.FirstVisibleByte + _editor.CaretIndex % _editor.BytesPerLine)) / _editor.BytesPerLine);
_editor.SetCaretStart(_editor.CaretIndex, new Point(x, y));
}
private Point GetByteColumnAndRow(int index)
{
int x = index % _editor.BytesPerLine;
int y = index / _editor.BytesPerLine;
return new Point(x, y);
}
private RectangleF GetBound(Point point)
{
return new RectangleF(_recHexValue.X + point.X * _recHexValue.Width, _recHexValue.Y + point.Y * _recHexValue.Height, _recHexValue.Width, _recHexValue.Height);
}
private bool IsHex(char c)
{
if ((c < 'a' || c > 'f') && (c < 'A' || c > 'F'))
{
return char.IsDigit(c);
}
return true;
}
}