219 lines
8.2 KiB
C#
219 lines
8.2 KiB
C#
using System.Drawing;
|
|
using System.Windows.Forms;
|
|
using VisionBuilder.UI.IOCommander.Interfaces;
|
|
|
|
namespace VisionBuilder.UI.IOCommander.Windows
|
|
{
|
|
public partial class WindowsIOCommanderDebugViewService : Form, IIOCommanderDebugViewService
|
|
{
|
|
private readonly WindowsIOCommanderDebugViewSettings _settings;
|
|
private readonly Dictionary<int, PinIndicator> _inputPins = new();
|
|
private readonly Dictionary<int, PinIndicator> _outputPins = new();
|
|
private readonly object _lockObject = new object();
|
|
private bool _isVisible = false;
|
|
|
|
public WindowsIOCommanderDebugViewService(WindowsIOCommanderDebugViewSettings settings)
|
|
{
|
|
_settings = settings;
|
|
InitializeComponent();
|
|
InitializePinDisplay();
|
|
|
|
}
|
|
|
|
|
|
protected override void OnShown(EventArgs e)
|
|
{
|
|
this.TopMost = true;
|
|
this.Focus();
|
|
this.TopMost = true;
|
|
}
|
|
|
|
private void InitializePinDisplay()
|
|
{
|
|
// Configure form properties
|
|
this.Text = "IOCommander Debug View";
|
|
this.FormBorderStyle = FormBorderStyle.FixedToolWindow;
|
|
this.TopMost = true;
|
|
this.TopLevel = true;
|
|
this.ShowInTaskbar = false;
|
|
this.StartPosition = FormStartPosition.Manual;
|
|
this.Location = new Point(50, 50);
|
|
this.Size = new Size(400, 350); // Made wider and adjusted height for 10 rows
|
|
this.BackColor = Color.FromArgb(64, 64, 64);
|
|
this.MinimizeBox = false;
|
|
this.MaximizeBox = false;
|
|
|
|
// Create pin indicators for input pins 1-10 and output pins 1-10 (10 rows, 2 columns)
|
|
int pinSize = 24; // Increased from 18
|
|
int spacing = 4; // Increased from 2
|
|
int centerX = 200; // Center the graphics in the wider form
|
|
int startY = 15; // Slightly more margin
|
|
|
|
// Get label dictionaries for quick lookup
|
|
var inputLabelDict = _settings.InputPinLabels?.ToDictionary(pl => pl.Pin, pl => pl.Label) ?? new Dictionary<int, string>();
|
|
var outputLabelDict = _settings.OutputPinLabels?.ToDictionary(pl => pl.Pin, pl => pl.Label) ?? new Dictionary<int, string>();
|
|
|
|
for (int row = 0; row < 10; row++) // Changed from 20 to 10
|
|
{
|
|
int inputPin = row + 1; // Input pins numbered 1-10
|
|
int outputPin = row + 1; // Output pins numbered 1-10
|
|
|
|
// Left column (input pins)
|
|
var leftIndicator = new PinIndicator(inputPin, true)
|
|
{
|
|
Location = new Point(centerX - pinSize - spacing * 2, startY + (row * (pinSize + spacing))),
|
|
Size = new Size(pinSize, pinSize)
|
|
};
|
|
_inputPins[inputPin] = leftIndicator;
|
|
this.Controls.Add(leftIndicator);
|
|
|
|
// Right column (output pins)
|
|
var rightIndicator = new PinIndicator(outputPin, false)
|
|
{
|
|
Location = new Point(centerX + spacing * 2, startY + (row * (pinSize + spacing))),
|
|
Size = new Size(pinSize, pinSize)
|
|
};
|
|
_outputPins[outputPin] = rightIndicator;
|
|
this.Controls.Add(rightIndicator);
|
|
|
|
// Input pin label (left side - label before pin number)
|
|
string inputLabelText = inputLabelDict.ContainsKey(inputPin) ? $"{inputLabelDict[inputPin]} {inputPin}" : inputPin.ToString();
|
|
var leftLabel = new Label
|
|
{
|
|
Text = inputLabelText,
|
|
Location = new Point(5, startY + (row * (pinSize + spacing)) + 4), // Adjusted vertical alignment
|
|
Size = new Size(centerX - pinSize - spacing * 3 - 5, 16), // Increased height from 14
|
|
Font = new Font("Arial", 8, FontStyle.Bold), // Increased from 6
|
|
ForeColor = Color.White,
|
|
BackColor = Color.Transparent,
|
|
TextAlign = ContentAlignment.MiddleRight
|
|
};
|
|
this.Controls.Add(leftLabel);
|
|
|
|
// Output pin label (right side - pin number followed by label)
|
|
string outputLabelText = outputLabelDict.ContainsKey(outputPin) ? $"{outputPin} {outputLabelDict[outputPin]}" : outputPin.ToString();
|
|
var rightLabel = new Label
|
|
{
|
|
Text = outputLabelText,
|
|
Location = new Point(centerX + pinSize + spacing * 3, startY + (row * (pinSize + spacing)) + 4), // Adjusted vertical alignment
|
|
Size = new Size(this.Width - (centerX + pinSize + spacing * 3) - 10, 16), // Increased height from 14
|
|
Font = new Font("Arial", 8, FontStyle.Bold), // Increased from 6
|
|
ForeColor = Color.White,
|
|
BackColor = Color.Transparent,
|
|
TextAlign = ContentAlignment.MiddleLeft
|
|
};
|
|
this.Controls.Add(rightLabel);
|
|
}
|
|
}
|
|
|
|
public void SetInputPinStatus(int pin, bool state)
|
|
{
|
|
if (this.InvokeRequired)
|
|
{
|
|
this.Invoke(new Action(() => SetInputPinStatus(pin, state)));
|
|
return;
|
|
}
|
|
|
|
lock (_lockObject)
|
|
{
|
|
if (_inputPins.ContainsKey(pin))
|
|
{
|
|
_inputPins[pin].SetState(state);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void SetOutputPinStatus(int pin, bool state)
|
|
{
|
|
if (this.InvokeRequired)
|
|
{
|
|
this.Invoke(new Action(() => SetOutputPinStatus(pin, state)));
|
|
return;
|
|
}
|
|
|
|
lock (_lockObject)
|
|
{
|
|
if (_outputPins.ContainsKey(pin))
|
|
{
|
|
_outputPins[pin].SetState(state);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void ShowDebugView()
|
|
{
|
|
if (this.InvokeRequired)
|
|
{
|
|
this.Invoke(new Action(ShowDebugView));
|
|
return;
|
|
}
|
|
|
|
lock (_lockObject)
|
|
{
|
|
if (!_isVisible)
|
|
{
|
|
this.Show();
|
|
_isVisible = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private class PinIndicator : Control
|
|
{
|
|
private readonly int _pinNumber;
|
|
private readonly bool _isInput;
|
|
private bool _state = false;
|
|
private readonly SolidBrush _activeBrush;
|
|
private readonly SolidBrush _inactiveBrush;
|
|
|
|
public PinIndicator(int pinNumber, bool isInput)
|
|
{
|
|
_pinNumber = pinNumber;
|
|
_isInput = isInput;
|
|
|
|
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true);
|
|
|
|
// Input pins: Green when active, dark gray when inactive
|
|
// Output pins: Red when active, dark gray when inactive
|
|
if (_isInput)
|
|
{
|
|
_activeBrush = new SolidBrush(Color.Lime);
|
|
_inactiveBrush = new SolidBrush(Color.DarkGray);
|
|
}
|
|
else
|
|
{
|
|
_activeBrush = new SolidBrush(Color.Red);
|
|
_inactiveBrush = new SolidBrush(Color.DarkGray);
|
|
}
|
|
}
|
|
|
|
public void SetState(bool state)
|
|
{
|
|
if (_state != state)
|
|
{
|
|
_state = state;
|
|
this.Invalidate();
|
|
}
|
|
}
|
|
|
|
protected override void OnPaint(PaintEventArgs e)
|
|
{
|
|
var brush = _state ? _activeBrush : _inactiveBrush;
|
|
e.Graphics.FillEllipse(brush, 0, 0, Width - 1, Height - 1);
|
|
e.Graphics.DrawEllipse(Pens.Black, 0, 0, Width - 1, Height - 1);
|
|
}
|
|
|
|
protected override void Dispose(bool disposing)
|
|
{
|
|
if (disposing)
|
|
{
|
|
_activeBrush?.Dispose();
|
|
_inactiveBrush?.Dispose();
|
|
}
|
|
base.Dispose(disposing);
|
|
}
|
|
}
|
|
}
|
|
}
|