private void HandleRunModeClick(MapNode targetNode) { if (targetNode == null) return; ENIGProtocol.AGVCommandHE targetCmd = ENIGProtocol.AGVCommandHE.Move; string confirmMsg = ""; if (targetNode.StationType == StationType.Charger) { if (MessageBox.Show($"[{targetNode.Id}] 충전기로 이동하여 충전을 진행하시겠습니까?", "작업 확인", MessageBoxButtons.YesNo) == DialogResult.Yes) { targetCmd = ENIGProtocol.AGVCommandHE.Charger; ExecuteManualCommand(targetNode, targetCmd); } return; } else if (targetNode.isDockingNode) { // Loader, Unloader, Buffer, Cleaner // Custom Dialog needed for PickOn / PickOff // For now, let's use a simple MessageBox or just a ContextMenu like logic? // User said: "click -> PickOn/Off selection -> Execute" // A context menu at cursor position is good for selection. ContextMenuStrip menu = new ContextMenuStrip(); var pickOn = new ToolStripMenuItem("Pick On (Move & Pick)"); pickOn.Click += (s, args) => ExecuteManualCommand(targetNode, ENIGProtocol.AGVCommandHE.PickOn); menu.Items.Add(pickOn); var pickOff = new ToolStripMenuItem("Pick Off (Move & Drop)"); pickOff.Click += (s, args) => ExecuteManualCommand(targetNode, ENIGProtocol.AGVCommandHE.PickOff); menu.Items.Add(pickOff); menu.Show(Cursor.Position); return; } else { // Normal Node if (MessageBox.Show($"[{targetNode.Id}] 노드로 이동하시겠습니까?", "이동 확인", MessageBoxButtons.YesNo) == DialogResult.Yes) { targetCmd = ENIGProtocol.AGVCommandHE.Move; // Or PickOff as default move? usually just Move logic inside ExecuteManualCommand handles GOTO. // But ExecuteManualCommand takes AGVCommandHE. // Let's check ENIGProtocol.AGVCommandHE. // If not present, we might need to modify ExecuteManualCommand or just pass PickOff as dummy? // Actually ExecuteManualCommand uses 'cmd' for log and 'PUB.NextWorkCmd'. // If 'Move', just GOTO. // Let's assume 'Move' exists or we use 'PickOff' (Move & Drop often implies MoveTo). // Or we check `ENIGProtocol.AGVCommandHE`. ExecuteManualCommand(targetNode, ENIGProtocol.AGVCommandHE.Move); } return; } }