..
This commit is contained in:
@@ -115,6 +115,7 @@ namespace AGVMapEditor.Forms
|
||||
_mapCanvas.NodesSelected += OnNodesSelected; // 다중 선택 이벤트
|
||||
_mapCanvas.NodeMoved += OnNodeMoved;
|
||||
_mapCanvas.NodeDeleted += OnNodeDeleted;
|
||||
_mapCanvas.ConnectionCreated += OnConnectionCreated;
|
||||
_mapCanvas.ConnectionDeleted += OnConnectionDeleted;
|
||||
_mapCanvas.ImageDoubleClicked += OnImageDoubleClicked;
|
||||
_mapCanvas.MapChanged += OnMapChanged;
|
||||
@@ -144,9 +145,8 @@ namespace AGVMapEditor.Forms
|
||||
btnAddLabel.Click += (s, e) => _mapCanvas.CurrentEditMode = UnifiedAGVCanvas.EditMode.AddLabel;
|
||||
btnAddImage.Click += (s, e) => _mapCanvas.CurrentEditMode = UnifiedAGVCanvas.EditMode.AddImage;
|
||||
|
||||
btnConnect.Click += (s, e) => _mapCanvas.CurrentEditMode = UnifiedAGVCanvas.EditMode.Connect;
|
||||
btnConnNode.Click += (s, e) => _mapCanvas.CurrentEditMode = UnifiedAGVCanvas.EditMode.Connect;
|
||||
btnDelete.Click += (s, e) => _mapCanvas.CurrentEditMode = UnifiedAGVCanvas.EditMode.Delete;
|
||||
btnDeleteConnection.Click += (s, e) => _mapCanvas.CurrentEditMode = UnifiedAGVCanvas.EditMode.DeleteConnection;
|
||||
|
||||
// 그리드 토글 버튼
|
||||
btnToggleGrid.Click += (s, e) => _mapCanvas.ShowGrid = !_mapCanvas.ShowGrid;
|
||||
@@ -182,6 +182,7 @@ namespace AGVMapEditor.Forms
|
||||
_hasChanges = true;
|
||||
UpdateTitle();
|
||||
RefreshNodeList();
|
||||
RefreshMagnetList(); // 추가
|
||||
// RFID 자동 할당
|
||||
}
|
||||
|
||||
@@ -215,6 +216,20 @@ namespace AGVMapEditor.Forms
|
||||
{
|
||||
// 단일 선택은 기존 방식 사용
|
||||
_selectedNode = nodes[0];
|
||||
|
||||
// Sync with lstMagnet
|
||||
if (_selectedNode is MapMagnet magnet)
|
||||
{
|
||||
lstMagnet.SelectedItem = magnet;
|
||||
}
|
||||
else
|
||||
{
|
||||
lstMagnet.SelectedItem = null;
|
||||
}
|
||||
|
||||
//this._mapCanvas.SelectedNode = nodes;
|
||||
//this._mapCanvas.Invalidate();
|
||||
|
||||
UpdateNodeProperties();
|
||||
UpdateImageEditButton();
|
||||
}
|
||||
@@ -242,17 +257,20 @@ namespace AGVMapEditor.Forms
|
||||
_hasChanges = true;
|
||||
UpdateTitle();
|
||||
RefreshNodeList();
|
||||
RefreshMagnetList(); // 추가
|
||||
ClearNodeProperties();
|
||||
// RFID 자동 할당
|
||||
}
|
||||
|
||||
private void OnConnectionCreated(object sender, (MapNode From, MapNode To) connection)
|
||||
{
|
||||
_hasChanges = true;
|
||||
UpdateTitle();
|
||||
RefreshNodeConnectionList();
|
||||
UpdateNodeProperties(); // 연결 정보 업데이트
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void OnConnectionDeleted(object sender, (MapNode From, MapNode To) connection)
|
||||
{
|
||||
_hasChanges = true;
|
||||
@@ -261,6 +279,8 @@ namespace AGVMapEditor.Forms
|
||||
UpdateNodeProperties(); // 연결 정보 업데이트
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void OnImageDoubleClicked(object sender, MapImage image)
|
||||
{
|
||||
// 이미지 노드 더블클릭 시 이미지 편집창 표시
|
||||
@@ -280,6 +300,7 @@ namespace AGVMapEditor.Forms
|
||||
{
|
||||
_hasChanges = true;
|
||||
UpdateTitle();
|
||||
RefreshMagnetDirectionList(); // 방향 정보 업데이트
|
||||
}
|
||||
|
||||
private void OnBackgroundClicked(object sender, Point location)
|
||||
@@ -621,7 +642,7 @@ namespace AGVMapEditor.Forms
|
||||
private void LoadMapFromFile(string filePath)
|
||||
{
|
||||
var result = MapLoader.LoadMapFromFile(filePath);
|
||||
|
||||
sbFile.Text = filePath;
|
||||
if (result.Success)
|
||||
{
|
||||
// 맵 캔버스에 데이터 설정
|
||||
@@ -637,6 +658,7 @@ namespace AGVMapEditor.Forms
|
||||
UpdateTitle();
|
||||
UpdateNodeList();
|
||||
RefreshNodeConnectionList();
|
||||
RefreshMagnetList(); // 추가
|
||||
|
||||
|
||||
|
||||
@@ -767,6 +789,7 @@ namespace AGVMapEditor.Forms
|
||||
{
|
||||
RefreshNodeList();
|
||||
RefreshNodeConnectionList();
|
||||
RefreshMagnetList(); // 추가
|
||||
RefreshMapCanvas();
|
||||
ClearNodeProperties();
|
||||
}
|
||||
@@ -829,7 +852,7 @@ namespace AGVMapEditor.Forms
|
||||
var item = node as MapNode;
|
||||
if (item.StationType == StationType.Normal)
|
||||
foreColor = Color.DimGray;
|
||||
else if (item.StationType == StationType.Charger1 || item.StationType == StationType.Charger2)
|
||||
else if (item.StationType == StationType.Charger)
|
||||
foreColor = Color.Red;
|
||||
else
|
||||
foreColor = Color.DarkGreen;
|
||||
@@ -945,13 +968,21 @@ namespace AGVMapEditor.Forms
|
||||
_mapCanvas?.HighlightConnection(connectionInfo.FromNodeId, connectionInfo.ToNodeId);
|
||||
|
||||
// 연결된 노드들을 맵에서 하이라이트 표시 (선택적)
|
||||
var fromNode = this._mapCanvas.Nodes.FirstOrDefault(n => n.Id == connectionInfo.FromNodeId);
|
||||
if (fromNode != null)
|
||||
{
|
||||
_selectedNode = fromNode;
|
||||
UpdateNodeProperties();
|
||||
_mapCanvas?.Invalidate();
|
||||
}
|
||||
//var fromNode = this._mapCanvas.Nodes.FirstOrDefault(n => n.Id == connectionInfo.FromNodeId);
|
||||
//if (fromNode != null)
|
||||
//{
|
||||
// if (_selectedNode != fromNode)
|
||||
// {
|
||||
// _selectedNode = fromNode;
|
||||
// _mapCanvas.SelectedNode = fromNode; // 캔버스 선택 상태 동기화
|
||||
|
||||
// // 속성창 업데이트 (리스트 리프레시 포함)
|
||||
// // 주의: RefreshMagnetDirectionList()가 호출되어도 lstNodeConnection에는 영향이 없으므로 안전함
|
||||
// UpdateNodeProperties();
|
||||
|
||||
// _mapCanvas?.Invalidate();
|
||||
// }
|
||||
//}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1303,9 +1334,9 @@ namespace AGVMapEditor.Forms
|
||||
{
|
||||
foreach (var node in this._mapCanvas.Nodes)
|
||||
{
|
||||
node.CanTurnLeft = true;
|
||||
node.CanTurnRight = true;
|
||||
node.DisableCross = false;
|
||||
node.CanTurnLeft = false;
|
||||
node.CanTurnRight = false;
|
||||
node.DisableCross = true;
|
||||
node.ModifiedDate = DateTime.Now;
|
||||
}
|
||||
|
||||
@@ -1367,6 +1398,9 @@ namespace AGVMapEditor.Forms
|
||||
|
||||
private void RefreshMagnetDirectionList()
|
||||
{
|
||||
// 이벤트 임시 제거 (DataSource 변경 시 불필요한 이벤트 발생 방지)
|
||||
lstMagnetDirection.SelectedIndexChanged -= LstMagnetDirection_SelectedIndexChanged;
|
||||
|
||||
// 현재 선택된 항목 기억
|
||||
int selectedIndex = lstMagnetDirection.SelectedIndex;
|
||||
|
||||
@@ -1374,7 +1408,12 @@ namespace AGVMapEditor.Forms
|
||||
lstMagnetDirection.DataSource = null;
|
||||
lstMagnetDirection.Items.Clear();
|
||||
|
||||
if (this._mapCanvas.Nodes == null) return;
|
||||
if (this._mapCanvas.Nodes == null)
|
||||
{
|
||||
// 이벤트 다시 연결 (빠른 리턴 시에도 연결 필요)
|
||||
lstMagnetDirection.SelectedIndexChanged += LstMagnetDirection_SelectedIndexChanged;
|
||||
return;
|
||||
}
|
||||
|
||||
var directions = new List<MagnetDirectionInfo>();
|
||||
|
||||
@@ -1410,8 +1449,7 @@ namespace AGVMapEditor.Forms
|
||||
lstMagnetDirection.DataSource = directions;
|
||||
}
|
||||
|
||||
// 이벤트 연결
|
||||
lstMagnetDirection.SelectedIndexChanged -= LstMagnetDirection_SelectedIndexChanged;
|
||||
// 이벤트 다시 연결
|
||||
lstMagnetDirection.SelectedIndexChanged += LstMagnetDirection_SelectedIndexChanged;
|
||||
|
||||
lstMagnetDirection.DoubleClick -= LstMagnetDirection_DoubleClick;
|
||||
@@ -1420,7 +1458,15 @@ namespace AGVMapEditor.Forms
|
||||
// 선택 항목 복원 (가능한 경우) -> 선택된 객체가 다르게 생성되므로 인덱스로 복원 시도
|
||||
if (selectedIndex >= 0 && selectedIndex < lstMagnetDirection.Items.Count)
|
||||
{
|
||||
lstMagnetDirection.SelectedIndex = selectedIndex;
|
||||
try
|
||||
{
|
||||
lstMagnetDirection.SelectedIndex = selectedIndex;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1430,6 +1476,44 @@ namespace AGVMapEditor.Forms
|
||||
{
|
||||
// 버튼 상태 업데이트
|
||||
UpdateDirectionButtons(info);
|
||||
|
||||
// 캔버스에서 해당 연결선 강조 표시
|
||||
if (info.FromNode != null && info.ToNode != null)
|
||||
{
|
||||
_mapCanvas.HighlightConnection(info.FromNode.Id, info.ToNode.Id);
|
||||
|
||||
// FromNode 선택 (속성창 갱신 루프 방지 위해 _propertyGrid 직접 설정 고려)
|
||||
// 하지만 _selectedNode 변경 시 RefreshMagnetDirectionList()가 호출되어 리스트가 재생성되면 선택이 풀릴 수 있음
|
||||
// 따라서 여기서는 캔버스 상의 선택 표시만 변경하고, 전체 속성 업데이트(리스트 리프레시 포함)는 건너뛰거나
|
||||
// 리스트 리프레시 로직에서 선택 상태 유지를 보완해야 함.
|
||||
|
||||
// 일단 _selectedNode를 변경하되, RefreshMagnetDirectionList에서 선택 인덱스 복원을 하므로 괜찮을 것으로 예상됨.
|
||||
// 만약 깜빡임이나 끊김이 심하면 UpdateNodeProperties 내의 RefreshMagnetDirectionList 호출을 조건부로 변경해야 함.
|
||||
|
||||
if (_selectedNode != info.FromNode)
|
||||
{
|
||||
var prevSelected = _selectedNode;
|
||||
_selectedNode = info.FromNode;
|
||||
|
||||
// _mapCanvas.SelectedNode 설정 (이것만으로는 PropertyGrid 갱신 안됨)
|
||||
_mapCanvas.SelectedNode = info.FromNode;
|
||||
|
||||
// PropertyGrid 갱신 (리스트 리프레시 포함)
|
||||
// 주의: 여기서 UpdateNodeProperties()를 부르면 리스트가 다시 그려지면서 선택 이벤트가 다시 발생할 수 있음.
|
||||
// 하지만 인덱스 복원 로직이 있으므로 무한루프는 아닐 수 있으나, 비효율적임.
|
||||
|
||||
// 해결책: 리스트 리프레시 없이 속성창만 갱신
|
||||
_propertyGrid.SelectedObject = _selectedNode;
|
||||
UpdateImageEditButton();
|
||||
|
||||
// 캔버스 다시 그리기
|
||||
_mapCanvas.Invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_mapCanvas.ClearHighlightedConnection();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1670,8 +1754,8 @@ namespace AGVMapEditor.Forms
|
||||
}
|
||||
}
|
||||
|
||||
// 현재 선택된 노드의 속성창 및 리스트 갱신
|
||||
UpdateNodeProperties();
|
||||
// 현재 선택된 노드의 속성창 및 리스트 갱신
|
||||
UpdateNodeProperties();
|
||||
}
|
||||
|
||||
private void btAddMagnet_Click(object sender, EventArgs e)
|
||||
@@ -1695,11 +1779,11 @@ namespace AGVMapEditor.Forms
|
||||
string id = _mapCanvas.GenerateUniqueNodeId();
|
||||
|
||||
var magnet = new MapMagnet { Id = id };
|
||||
|
||||
|
||||
// 점 생성 시 정규화(Snap) 처리
|
||||
int cx = (int)worldCX;
|
||||
int cy = (int)worldCY;
|
||||
|
||||
|
||||
magnet.StartPoint = new Point(cx - 50, cy);
|
||||
magnet.EndPoint = new Point(cx + 50, cy);
|
||||
|
||||
@@ -1711,14 +1795,118 @@ namespace AGVMapEditor.Forms
|
||||
// 캔버스에 추가
|
||||
_mapCanvas.Magnets.Add(magnet);
|
||||
_hasChanges = true;
|
||||
|
||||
|
||||
UpdateTitle();
|
||||
RefreshMapCanvas();
|
||||
RefreshNodeList();
|
||||
|
||||
RefreshMagnetList(); // 추가
|
||||
|
||||
// 추가된 마그넷 선택
|
||||
//_mapCanvas.SelectedNode = magnet;
|
||||
UpdateNodeProperties();
|
||||
}
|
||||
|
||||
private void btDelMagnet_Click(object sender, EventArgs e)
|
||||
{
|
||||
//선택한 마그넷라인을 삭제 (삭제 후 맵에 바로 반영되도록 업데이트필요)
|
||||
if (lstMagnet.SelectedItem is MapMagnet magnet)
|
||||
{
|
||||
_mapCanvas.RemoveMagnet(magnet);
|
||||
RefreshMagnetList();
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshMagnetList()
|
||||
{
|
||||
lstMagnet.DataSource = null;
|
||||
lstMagnet.Items.Clear();
|
||||
|
||||
if (_mapCanvas.Magnets != null && _mapCanvas.Magnets.Count > 0)
|
||||
{
|
||||
lstMagnet.DataSource = _mapCanvas.Magnets;
|
||||
}
|
||||
|
||||
// 이벤트 연결
|
||||
lstMagnet.SelectedIndexChanged -= LstMagnet_SelectedIndexChanged;
|
||||
lstMagnet.SelectedIndexChanged += LstMagnet_SelectedIndexChanged;
|
||||
|
||||
lstMagnet.DoubleClick -= LstMagnet_DoubleClick;
|
||||
lstMagnet.DoubleClick += LstMagnet_DoubleClick;
|
||||
|
||||
lstMagnet.DrawMode = DrawMode.OwnerDrawFixed;
|
||||
lstMagnet.DrawItem -= LstMagnet_DrawItem;
|
||||
lstMagnet.DrawItem += LstMagnet_DrawItem;
|
||||
}
|
||||
|
||||
private void LstMagnet_DrawItem(object sender, DrawItemEventArgs e)
|
||||
{
|
||||
e.DrawBackground();
|
||||
|
||||
if (e.Index >= 0 && e.Index < lstMagnet.Items.Count)
|
||||
{
|
||||
var magnet = lstMagnet.Items[e.Index] as MapMagnet;
|
||||
if (magnet != null)
|
||||
{
|
||||
Brush brush = Brushes.Black;
|
||||
if (magnet.ControlPoint != null) // Curve
|
||||
{
|
||||
brush = Brushes.Blue; // Curve는 파란색
|
||||
}
|
||||
|
||||
// 선택된 항목은 흰색 글씨 (배경이 파란색이므로)
|
||||
if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
|
||||
{
|
||||
brush = Brushes.White;
|
||||
}
|
||||
|
||||
e.Graphics.DrawString(magnet.ToString(), e.Font, brush, e.Bounds);
|
||||
}
|
||||
}
|
||||
|
||||
e.DrawFocusRectangle();
|
||||
}
|
||||
|
||||
private void LstMagnet_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (lstMagnet.SelectedItem is MapMagnet magnet)
|
||||
{
|
||||
_mapCanvas.SelectedNode = magnet;
|
||||
//UpdateNodeProperties(); // SelectedNode setter에서 Invalidate 호출됨
|
||||
}
|
||||
}
|
||||
|
||||
private void LstMagnet_DoubleClick(object sender, EventArgs e)
|
||||
{
|
||||
if (lstMagnet.SelectedItem is MapMagnet magnet)
|
||||
{
|
||||
_mapCanvas.PanTo(magnet.Position);
|
||||
}
|
||||
}
|
||||
|
||||
private void btnAddNode_ButtonClick(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void btnAddNode_BackColorChanged(object sender, EventArgs e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private void btnDeleteConnection_Click(object sender, EventArgs e)
|
||||
{
|
||||
_mapCanvas.CurrentEditMode = UnifiedAGVCanvas.EditMode.DeleteConnection;
|
||||
}
|
||||
|
||||
private void btnConnDir_Click(object sender, EventArgs e)
|
||||
{
|
||||
//방향연결(노드연결과 유사), 두 노드간의 방향을 생성한다 기본값 straight
|
||||
_mapCanvas.CurrentEditMode = UnifiedAGVCanvas.EditMode.ConnectDirection;
|
||||
}
|
||||
|
||||
private void toolStripButton3_Click_1(object sender, EventArgs e)
|
||||
{
|
||||
RefreshMagnetList();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user