using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using AGVNavigationCore.Models; using AGVNavigationCore.Controls; namespace Project.Dialog { public partial class fSetCurrentPosition : Form { private UnifiedAGVCanvas _canvas; private MapNode _selectedNode; private AgvDirection _selectedDirection = AgvDirection.Forward; private AGVTurn _selectedTurn = AGVTurn.None; public MapNode SelectedNode => _selectedNode; public AgvDirection SelectedDirection => _selectedDirection; public AGVTurn SelectedTurn => _selectedTurn; public fSetCurrentPosition() { InitializeComponent(); if (PUB.setting.FullScreen) this.WindowState = FormWindowState.Maximized; SetupCanvas(); WireEvents(); this.Load += FSetCurrentPosition_Load; } private void SetupCanvas() { _canvas = new UnifiedAGVCanvas { Dock = DockStyle.Fill, Mode = UnifiedAGVCanvas.CanvasMode.Run, BackColor = Color.FromArgb(45, 45, 48), ShowGrid=false, }; mainLayout.Controls.Add(_canvas, 1, 0); } private void WireEvents() { _canvas.NodeSelect += _canvas_NodeSelect; btnForward.Click += (s, e) => { _selectedDirection = AgvDirection.Forward; UpdateStatus(); }; btnBackward.Click += (s, e) => { _selectedDirection = AgvDirection.Backward; UpdateStatus(); }; btnTurnNone.Click += (s, e) => { _selectedTurn = AGVTurn.None; UpdateStatus(); }; btnTurnL90.Click += (s, e) => { _selectedTurn = AGVTurn.L90; UpdateStatus(); }; btnTurnR90.Click += (s, e) => { _selectedTurn = AGVTurn.R90; UpdateStatus(); }; btnOK.Click += BtnOK_Click; btnCancel.Click += (s, e) => { this.DialogResult = DialogResult.Cancel; this.Close(); }; } private void FSetCurrentPosition_Load(object sender, EventArgs e) { // 맵 데이터 강제 복사 (PUB과 동일한 맵 사용) if (PUB._mapCanvas != null) { _canvas.SetMapData(PUB._mapCanvas.Nodes, PUB._mapCanvas.Labels, PUB._mapCanvas.Images, PUB._mapCanvas.Marks, PUB._mapCanvas.Magnets); } // 마지막 위치 로드 var lastPos = PUB.LoadLastPosition(); if (lastPos != null) { _selectedNode = _canvas.Nodes.FirstOrDefault(n => n.Id == lastPos.NodeId); _selectedDirection = lastPos.Direction; _selectedTurn = lastPos.Turn; if (_selectedNode != null) { _canvas.SelectedNode = _selectedNode; _canvas.PanToNode(_selectedNode.Id); UpdateStatus(isRestore: true); } } this.Show(); _canvas.ResetZoom(); } private void _canvas_NodeSelect(object sender, NodeBase node, MouseEventArgs e) { if (node is MapNode mapNode && mapNode.IsNavigationNode()) { _selectedNode = mapNode; _canvas.SelectedNode = mapNode; UpdateStatus(); } } private void UpdateStatus(bool isRestore = false) { if (_selectedNode == null) { _lblStatus.Text = "위치를 선택해 주세요."; _lblStatus.ForeColor = Color.White; return; } string dirStr = _selectedDirection == AgvDirection.Forward ? "전진" : "후진"; _lblStatus.Text = $"{(isRestore ? "[복원됨] " : "")}위치: {_selectedNode.Id} ({_selectedNode.ID2}) | 방향: {dirStr} | Turn: {_selectedTurn}"; _lblStatus.ForeColor = isRestore ? Color.Yellow : Color.Cyan; // 캔버스에 가상 AGV 미리보기 (선택 사항) _canvas.Invalidate(); } private void BtnOK_Click(object sender, EventArgs e) { if (_selectedNode == null) { MessageBox.Show("AGV의 현재 위치를 맵에서 클릭하여 선택해 주세요.", "알림", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } this.DialogResult = DialogResult.OK; this.Close(); } } }