io commander
This commit is contained in:
@@ -0,0 +1,218 @@
|
||||
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(280, 450); // Made wider to accommodate labels
|
||||
this.BackColor = Color.FromArgb(64, 64, 64);
|
||||
this.MinimizeBox = false;
|
||||
this.MaximizeBox = false;
|
||||
|
||||
// Create pin indicators for input pins 1-20 and output pins 1-20 (20 rows, 2 columns)
|
||||
int pinSize = 18;
|
||||
int spacing = 2;
|
||||
int centerX = 140; // Center the graphics in the wider form
|
||||
int startY = 10;
|
||||
|
||||
// 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 < 20; row++)
|
||||
{
|
||||
int inputPin = row + 1; // Input pins numbered 1-20
|
||||
int outputPin = row + 1; // Output pins numbered 1-20
|
||||
|
||||
// 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)) + 2),
|
||||
Size = new Size(centerX - pinSize - spacing * 3 - 5, 14),
|
||||
Font = new Font("Arial", 6, FontStyle.Bold),
|
||||
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)) + 2),
|
||||
Size = new Size(this.Width - (centerX + pinSize + spacing * 3) - 10, 14),
|
||||
Font = new Font("Arial", 6, FontStyle.Bold),
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user