This commit is contained in:
backuppc
2026-02-12 09:58:01 +09:00
parent 2b3a9b3d1d
commit d6aed58516
17 changed files with 914 additions and 402 deletions

View File

@@ -31,6 +31,7 @@ namespace AGVMapEditor.Forms
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
this.statusStrip1 = new System.Windows.Forms.StatusStrip();
this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel();
this.sbFile = new System.Windows.Forms.ToolStripStatusLabel();
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.tabControl1 = new System.Windows.Forms.TabControl();
this.tabPageNodes = new System.Windows.Forms.TabPage();
@@ -50,6 +51,10 @@ namespace AGVMapEditor.Forms
this.btDirDelete = new System.Windows.Forms.ToolStripButton();
this.btMakeDirdata = new System.Windows.Forms.ToolStripButton();
this.toolStripButton2 = new System.Windows.Forms.ToolStripButton();
this.tabPage3 = new System.Windows.Forms.TabPage();
this.lstMagnet = new System.Windows.Forms.ListBox();
this.toolStrip5 = new System.Windows.Forms.ToolStrip();
this.btDelMagnet = new System.Windows.Forms.ToolStripButton();
this._propertyGrid = new System.Windows.Forms.PropertyGrid();
this.panel1 = new System.Windows.Forms.Panel();
this.toolStrip3 = new System.Windows.Forms.ToolStrip();
@@ -61,11 +66,12 @@ namespace AGVMapEditor.Forms
this.btnDelete = new System.Windows.Forms.ToolStripButton();
this.btnEditImage = new System.Windows.Forms.ToolStripButton();
this.separator1 = new System.Windows.Forms.ToolStripSeparator();
this.btnConnect = new System.Windows.Forms.ToolStripButton();
this.btnDeleteConnection = new System.Windows.Forms.ToolStripButton();
this.btnConnNode = new System.Windows.Forms.ToolStripButton();
this.btnConnDir = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
this.btnToggleGrid = new System.Windows.Forms.ToolStripButton();
this.btnFitMap = new System.Windows.Forms.ToolStripButton();
this.btAddMagnet = new System.Windows.Forms.ToolStripButton();
this.toolStrip2 = new System.Windows.Forms.ToolStrip();
this.btnNew = new System.Windows.Forms.ToolStripButton();
this.btnOpen = new System.Windows.Forms.ToolStripButton();
@@ -77,7 +83,7 @@ namespace AGVMapEditor.Forms
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
this.toolStripButton1 = new System.Windows.Forms.ToolStripDropDownButton();
this.allTurnLeftRightCrossOnToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.btAddMagnet = new System.Windows.Forms.ToolStripButton();
this.toolStripButton3 = new System.Windows.Forms.ToolStripButton();
this.statusStrip1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
this.splitContainer1.Panel1.SuspendLayout();
@@ -90,6 +96,8 @@ namespace AGVMapEditor.Forms
this.tabPage2.SuspendLayout();
this.tableLayoutPanel1.SuspendLayout();
this.toolStrip4.SuspendLayout();
this.tabPage3.SuspendLayout();
this.toolStrip5.SuspendLayout();
this.toolStrip3.SuspendLayout();
this.toolStrip2.SuspendLayout();
this.SuspendLayout();
@@ -97,7 +105,8 @@ namespace AGVMapEditor.Forms
// statusStrip1
//
this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripStatusLabel1});
this.toolStripStatusLabel1,
this.sbFile});
this.statusStrip1.Location = new System.Drawing.Point(0, 751);
this.statusStrip1.Name = "statusStrip1";
this.statusStrip1.Size = new System.Drawing.Size(1200, 22);
@@ -110,6 +119,12 @@ namespace AGVMapEditor.Forms
this.toolStripStatusLabel1.Size = new System.Drawing.Size(39, 17);
this.toolStripStatusLabel1.Text = "Ready";
//
// sbFile
//
this.sbFile.Name = "sbFile";
this.sbFile.Size = new System.Drawing.Size(17, 17);
this.sbFile.Text = "--";
//
// splitContainer1
//
this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
@@ -135,6 +150,7 @@ namespace AGVMapEditor.Forms
this.tabControl1.Controls.Add(this.tabPageNodes);
this.tabControl1.Controls.Add(this.tabPage1);
this.tabControl1.Controls.Add(this.tabPage2);
this.tabControl1.Controls.Add(this.tabPage3);
this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabControl1.Location = new System.Drawing.Point(0, 0);
this.tabControl1.Name = "tabControl1";
@@ -330,6 +346,47 @@ namespace AGVMapEditor.Forms
this.toolStripButton2.Text = "Clear";
this.toolStripButton2.Click += new System.EventHandler(this.toolStripButton2_Click);
//
// tabPage3
//
this.tabPage3.Controls.Add(this.lstMagnet);
this.tabPage3.Controls.Add(this.toolStrip5);
this.tabPage3.Location = new System.Drawing.Point(4, 22);
this.tabPage3.Name = "tabPage3";
this.tabPage3.Size = new System.Drawing.Size(292, 309);
this.tabPage3.TabIndex = 3;
this.tabPage3.Text = "마그넷라인";
this.tabPage3.UseVisualStyleBackColor = true;
//
// lstMagnet
//
this.lstMagnet.Dock = System.Windows.Forms.DockStyle.Fill;
this.lstMagnet.FormattingEnabled = true;
this.lstMagnet.ItemHeight = 12;
this.lstMagnet.Location = new System.Drawing.Point(0, 25);
this.lstMagnet.Name = "lstMagnet";
this.lstMagnet.Size = new System.Drawing.Size(292, 284);
this.lstMagnet.TabIndex = 2;
//
// toolStrip5
//
this.toolStrip5.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.btDelMagnet,
this.toolStripButton3});
this.toolStrip5.Location = new System.Drawing.Point(0, 0);
this.toolStrip5.Name = "toolStrip5";
this.toolStrip5.Size = new System.Drawing.Size(292, 25);
this.toolStrip5.TabIndex = 6;
this.toolStrip5.Text = "toolStrip5";
//
// btDelMagnet
//
this.btDelMagnet.Image = ((System.Drawing.Image)(resources.GetObject("btDelMagnet.Image")));
this.btDelMagnet.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btDelMagnet.Name = "btDelMagnet";
this.btDelMagnet.Size = new System.Drawing.Size(61, 22);
this.btDelMagnet.Text = "Delete";
this.btDelMagnet.Click += new System.EventHandler(this.btDelMagnet_Click);
//
// _propertyGrid
//
this._propertyGrid.Dock = System.Windows.Forms.DockStyle.Bottom;
@@ -355,8 +412,8 @@ namespace AGVMapEditor.Forms
this.btnDelete,
this.btnEditImage,
this.separator1,
this.btnConnect,
this.btnDeleteConnection,
this.btnConnNode,
this.btnConnDir,
this.toolStripSeparator1,
this.btnToggleGrid,
this.btnFitMap,
@@ -394,6 +451,8 @@ namespace AGVMapEditor.Forms
this.btnAddNode.Size = new System.Drawing.Size(111, 22);
this.btnAddNode.Text = "노드 추가 (A)";
this.btnAddNode.ToolTipText = "노드 추가 (A)";
this.btnAddNode.ButtonClick += new System.EventHandler(this.btnAddNode_ButtonClick);
this.btnAddNode.BackColorChanged += new System.EventHandler(this.btnAddNode_BackColorChanged);
//
// btnAddLabel
//
@@ -438,21 +497,20 @@ namespace AGVMapEditor.Forms
this.separator1.Name = "separator1";
this.separator1.Size = new System.Drawing.Size(6, 25);
//
// btnConnect
// btnConnNode
//
this.btnConnect.Image = ((System.Drawing.Image)(resources.GetObject("btnConnect.Image")));
this.btnConnect.Name = "btnConnect";
this.btnConnect.Size = new System.Drawing.Size(95, 22);
this.btnConnect.Text = "노드연결 (C)";
this.btnConnNode.Image = ((System.Drawing.Image)(resources.GetObject("btnConnNode.Image")));
this.btnConnNode.Name = "btnConnNode";
this.btnConnNode.Size = new System.Drawing.Size(95, 22);
this.btnConnNode.Text = "노드연결 (C)";
//
// btnDeleteConnection
// btnConnDir
//
this.btnDeleteConnection.Image = ((System.Drawing.Image)(resources.GetObject("btnDeleteConnection.Image")));
this.btnDeleteConnection.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btnDeleteConnection.Name = "btnDeleteConnection";
this.btnDeleteConnection.Size = new System.Drawing.Size(94, 22);
this.btnDeleteConnection.Text = "연결삭제 (X)";
this.btnDeleteConnection.ToolTipText = "연결 삭제 (X)";
this.btnConnDir.Image = ((System.Drawing.Image)(resources.GetObject("btnConnDir.Image")));
this.btnConnDir.Name = "btnConnDir";
this.btnConnDir.Size = new System.Drawing.Size(95, 22);
this.btnConnDir.Text = "방향연결 (C)";
this.btnConnDir.Click += new System.EventHandler(this.btnConnDir_Click);
//
// toolStripSeparator1
//
@@ -475,6 +533,15 @@ namespace AGVMapEditor.Forms
this.btnFitMap.Text = "맵 맞춤";
this.btnFitMap.ToolTipText = "맵 전체 보기";
//
// btAddMagnet
//
this.btAddMagnet.Image = ((System.Drawing.Image)(resources.GetObject("btAddMagnet.Image")));
this.btAddMagnet.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btAddMagnet.Name = "btAddMagnet";
this.btAddMagnet.Size = new System.Drawing.Size(87, 22);
this.btAddMagnet.Text = "마그넷추가";
this.btAddMagnet.Click += new System.EventHandler(this.btAddMagnet_Click);
//
// toolStrip2
//
this.toolStrip2.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
@@ -574,14 +641,15 @@ namespace AGVMapEditor.Forms
this.allTurnLeftRightCrossOnToolStripMenuItem.Text = "All TurnLeft/Right/Cross On";
this.allTurnLeftRightCrossOnToolStripMenuItem.Click += new System.EventHandler(this.allTurnLeftRightCrossOnToolStripMenuItem_Click);
//
// btAddMagnet
// toolStripButton3
//
this.btAddMagnet.Image = ((System.Drawing.Image)(resources.GetObject("btAddMagnet.Image")));
this.btAddMagnet.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btAddMagnet.Name = "btAddMagnet";
this.btAddMagnet.Size = new System.Drawing.Size(87, 22);
this.btAddMagnet.Text = "마그넷추가";
this.btAddMagnet.Click += new System.EventHandler(this.btAddMagnet_Click);
this.toolStripButton3.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
this.toolStripButton3.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton3.Image")));
this.toolStripButton3.ImageTransparentColor = System.Drawing.Color.Magenta;
this.toolStripButton3.Name = "toolStripButton3";
this.toolStripButton3.Size = new System.Drawing.Size(66, 22);
this.toolStripButton3.Text = "Refresh";
this.toolStripButton3.Click += new System.EventHandler(this.toolStripButton3_Click_1);
//
// MainForm
//
@@ -615,6 +683,10 @@ namespace AGVMapEditor.Forms
this.tableLayoutPanel1.ResumeLayout(false);
this.toolStrip4.ResumeLayout(false);
this.toolStrip4.PerformLayout();
this.tabPage3.ResumeLayout(false);
this.tabPage3.PerformLayout();
this.toolStrip5.ResumeLayout(false);
this.toolStrip5.PerformLayout();
this.toolStrip3.ResumeLayout(false);
this.toolStrip3.PerformLayout();
this.toolStrip2.ResumeLayout(false);
@@ -650,9 +722,8 @@ namespace AGVMapEditor.Forms
private System.Windows.Forms.ToolStripButton btnSelect;
private System.Windows.Forms.ToolStripButton btnMove;
private System.Windows.Forms.ToolStripButton btnEditImage;
private System.Windows.Forms.ToolStripButton btnConnect;
private System.Windows.Forms.ToolStripButton btnConnNode;
private System.Windows.Forms.ToolStripButton btnDelete;
private System.Windows.Forms.ToolStripButton btnDeleteConnection;
private System.Windows.Forms.ToolStripSeparator separator1;
private System.Windows.Forms.ToolStripButton btnToggleGrid;
private System.Windows.Forms.ToolStripButton btnFitMap;
@@ -675,5 +746,12 @@ namespace AGVMapEditor.Forms
private System.Windows.Forms.Button button3;
private System.Windows.Forms.ToolStripButton toolStripButton2;
private System.Windows.Forms.ToolStripButton btAddMagnet;
private System.Windows.Forms.TabPage tabPage3;
private System.Windows.Forms.ListBox lstMagnet;
private System.Windows.Forms.ToolStrip toolStrip5;
private System.Windows.Forms.ToolStripButton btDelMagnet;
private System.Windows.Forms.ToolStripStatusLabel sbFile;
private System.Windows.Forms.ToolStripButton btnConnDir;
private System.Windows.Forms.ToolStripButton toolStripButton3;
}
}

View File

@@ -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();
}
}
}

View File

@@ -123,7 +123,49 @@
<metadata name="toolStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>249, 17</value>
</metadata>
<metadata name="toolStrip4.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 56</value>
</metadata>
<metadata name="toolStrip5.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>123, 56</value>
</metadata>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="btDelMagnet.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIFSURBVDhPpZLtS1NhGMbPPxJmmlYSgqHiKzGU1EDxg4iK
YKyG2WBogqMYJQOtCEVRFBGdTBCJfRnkS4VaaWNT5sqx1BUxRXxDHYxAJLvkusEeBaPAB+5z4Jzn+t3X
/aLhnEfjo8m+dCoa+7/C3O2Hqe0zDC+8KG+cRZHZhdzaaWTVTCLDMIY0vfM04Nfh77/G/sEhwpEDbO3t
I7TxE8urEVy99fT/AL5gWDLrTB/hnF4XsW0khCu5ln8DmJliT2AXrcNBsU1gj/MH4nMeKwBrPktM28xM
cX79DFKrHHD5d9D26hvicx4pABt2lpg10zYzU0zr7+e3xXGcrkEB2O2TNec9nJFwB3alZn5jZorfeDZh
6Q3g8s06BeCoKF4MRURoH1+BY2oNCbeb0TIclIYxOhzf8frTOuo7FxCbbVIAzpni0iceEc8vhzEwGkJD
lx83ymxifejdKjRNk/8PWnyIyTQqAJek0jqHwfEVscu31baIu8+90sTE4nY025dQ2/5FIPpnXlzKuK8A
HBUzHot52djqQ6HZhfR7IwK4mKpHtvEDMqvfCiQ6zaAAXM8x94aIWTNrLLG4kVUzgaTSPlzLtyJOZxbb
1wtfyg4Q+AfA3aZlButjSfxGcUJBk4g5tuP3haQKRKXcUQDOmbvNTpPOJeFFjordZmbWTNvMTHFUcpUC
nOccAdABIDXXE1nzAAAAAElFTkSuQmCC
</value>
</data>
<data name="toolStripButton3.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAIFSURBVDhPpZLtS1NhGMbPPxJmmlYSgqHiKzGU1EDxg4iK
YKyG2WBogqMYJQOtCEVRFBGdTBCJfRnkS4VaaWNT5sqx1BUxRXxDHYxAJLvkusEeBaPAB+5z4Jzn+t3X
/aLhnEfjo8m+dCoa+7/C3O2Hqe0zDC+8KG+cRZHZhdzaaWTVTCLDMIY0vfM04Nfh77/G/sEhwpEDbO3t
I7TxE8urEVy99fT/AL5gWDLrTB/hnF4XsW0khCu5ln8DmJliT2AXrcNBsU1gj/MH4nMeKwBrPktM28xM
cX79DFKrHHD5d9D26hvicx4pABt2lpg10zYzU0zr7+e3xXGcrkEB2O2TNec9nJFwB3alZn5jZorfeDZh
6Q3g8s06BeCoKF4MRURoH1+BY2oNCbeb0TIclIYxOhzf8frTOuo7FxCbbVIAzpni0iceEc8vhzEwGkJD
lx83ymxifejdKjRNk/8PWnyIyTQqAJek0jqHwfEVscu31baIu8+90sTE4nY025dQ2/5FIPpnXlzKuK8A
HBUzHot52djqQ6HZhfR7IwK4mKpHtvEDMqvfCiQ6zaAAXM8x94aIWTNrLLG4kVUzgaTSPlzLtyJOZxbb
1wtfyg4Q+AfA3aZlButjSfxGcUJBk4g5tuP3haQKRKXcUQDOmbvNTpPOJeFFjordZmbWTNvMTHFUcpUC
nOccAdABIDXXE1nzAAAAAElFTkSuQmCC
</value>
</data>
<metadata name="toolStrip3.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>462, 17</value>
</metadata>
<metadata name="toolStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>249, 17</value>
</metadata>
<data name="btNodeRemove.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
@@ -187,21 +229,18 @@
nOccAdABIDXXE1nzAAAAAElFTkSuQmCC
</value>
</data>
<metadata name="toolStrip3.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>462, 17</value>
</metadata>
<data name="btnSelect.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHrSURBVDhPldBLaBNBHMfx/0kUVBBJ0lxWPIhihBJKyAqS
pHkQIS+9hXg3RhQviicrITnmJqFnQQ8RqiamRqkhj6VCQtuIQaVQc7dg3d3s61Dy0w002KnU9nP67+x8
h2GIDmD0kT+mLk/fZNf3pQkznCrM3DFnZflSRG05euast7izcpM72GGqMP1ZFRw1tXm+qq9dg9LiHgwb
dnFYP51i9/6T0r4wp39Kwfh2F8bGI2irEYjvTmo/Gpbj7N4JpXNxShUcdbV1DvpaHMb3HNrP4uiVb2Cj
cQtadxbSh6OQ3tM82+6iNLk5rXcd7ecJGIaB0WiE1dcp6F9v41eNvmxV6QzbTMjtKYtct9Wi0Si63S50
XUe/30fjaQTG+n1IVRpKb4lnuzFtyc4Nl06VE4kE0uk0CoUCSqUSqvOzMNYfYnORtqVFWhEr9JhtJ+Lx
+DjmeR5+vx+xWAzqSgRy3Q65dgJbFeLYZmIndrvd8Pl8sFqt5pWfbL6hbalCl6Uy9cSXlGG7sWQyiXw+
P469Xi8sFgvMdblCV6RXVDNnvKAjPxfoKttSOBxGLpfbE+8QFyj09/cugUAA2WwWLpcLHo9nT7yvTCaD
wWAAp9OJUCh0uNhkHtDpdFAsFscPxv7/r2AweM+8ts1mO3z8x29G9wsX9Ki7DgAAAABJRU5ErkJggg==
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHsSURBVDhPldBLaBNBHMfx/0kUVBBJ0lxWPIhihBJKyAqS
pHkQIS+9hXg3RhQviicrITnmJqFnQQ8RqiamRqkhj6VCQtuIQaVQc64H6+5mX4eSn26gwU6ltp/Tf2fn
OwxDdACjj/wxdXn6Jru+L02Y4VRh5o45K8uXImrL0TNnvcWdlZvcwQ5ThenPquCoqc3zVX3tGpQW92DY
sIvD+ukUu/eflPaFOf1TCsa3uzA2HkFbjUB8d1L70bAcZ/dOKJ2LU6rgqKutc9DX4jC+59B+FkevfAMb
jVvQurOQPhyF9J7m2XYXpcnNab3raD9PwDAMjEYjrL5OQf96G79q9GWrSmfYZkJuT1nkuq0WjUbR7Xah
6zr6/T4aTyMw1u9DqtJQeks8241pS3ZuuHSqnEgkkE6nUSgUUCqVUJ2fhbH+EJuLtC0t0opYocdsOxGP
x8cxz/Pw+/2IxWJQVyKQ63bItRPYqhDHNhM7sdvths/ng9VqNa/8ZPMNbUsVuiyVqSe+pAzbjSWTSeTz
+XHs9XphsVhgrssVuiK9opo54wUd+blAV9mWwuEwcrncnniHuEChv793CQQCyGazcLlc8Hg8e+J9ZTIZ
DAYDOJ1OhEKhw8Um84BOp4NisTh+MPb/fwWDwXvmtW022+HjP34DP4sLE797GZoAAAAASUVORK5CYII=
</value>
</data>
<data name="btnMove.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
@@ -217,83 +256,83 @@
YIGDKaeH7rEGFFd1IN1M4c5nAYIcIXLXvmW+uOKfXMvpRO9rFnzJi9lqBKPZYVCedzYsH6SQ2l+Eu2SD
bfNyWeHqqhbxahSCGIM2MwSKrYzDWboBx5sxIsP6yvTPH0lk3YoGI9lhaB8NQZO+gl8Dj7SN1tpAvgAA
AABJRU5ErkJggg==
</value>
</data>
<data name="btnAddNode.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHZSURBVDhPnZJda9NwFMb3JbxV/BaD4ufZjcwhejsdiqig
8+1u8w2vUprNrE3axDWmKW1aQ0rbtPaFUkra2paCotWU9YVHzh8SidMVfSCEnHOe33MgZ61araJSqaBc
LqNUKqFYLKJQKMCyLHqfW1sl27axXC5PPb1ej0F0XT8bQslkcByHJXc6HR9CNdM0z4bQyjRMafSdz+et
yWSC+XzO6gQ0DOPvEEr1BlOp1Ekmk3Gm0ylGX7pI2Yes1263kU6n/wyhZG/lxWIBMo+/fsKj6BbuHWxA
sw9Yr9VqQdM0SJIUhJim6Y7HYzY0m80w/NzFbvQK9t5t46V6C4+jWz6k2WwimUwGIblc7pJhGO5oNGJD
H50PuH+4gefHN/FGu4tX6u0ApNFoQJblICSbzYYURXGHwyEbqncLeChs4sXxjg/ZPdpEshRm/VqtBlEU
wXHcL4iu66FEIuEOBoNTkNfv7+CZdA1Pj65jvpixLeLxOCKRyAUfQFJVlUH6/b4PefD2Mp7ErmJf2cH3
H998M8dxFwNmT7IsMwhdIlvXsbCv3MD0xF1t9iSKYigWi7l0id4vJrMkSavNngRBWBcEwaUDq9fr/2b2
xPP8Os/z7n+ZPREkHA6f/73u6SfD/w8v3D5c0gAAAABJRU5ErkJggg==
</value>
</data>
<data name="btnAddLabel.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHHSURBVDhPnZJva9pQFMb7JfZ2Y9+iIPtke7OujL7sWopr
2bt2bETMi4CJXlCROI0SFP/OJDqXiladgw7cks0ozzhXbopzq2wPhHDPOc/vOSR3r91uo9VqodFooF6v
o1aroVqtolKp0PvB3i41m02sVqutZzgccoiu6/dDKJkMg8GAJ7uuG0KoZprm/RBamYYpjc7lcrkyn88R
BAGvE9AwjL9DKFUM5vP5n4VCYeD7Pj7ffEeBTXmv3+9T788QShYrL5dLkPnL1MerQwcnT228T60hvV4P
uVwOmqZtQkzT9GazGR9aLBY8OfrcweVxH2/PXJwfdkOI4zjIZDKbkFKp9MQwDG86XQ9Z9VuefHXyCdL5
9RbEtm0wxjYhxWIxkk6nvclkwoe6ra+IHth4c3oHiR440LV1v9PpQFVVSJJ0B9F1PcIY88bj8RbkXdTF
66MeLo4+IAiWfItkMol4PP4oBJCy2WwklUp5o9EohJw9s3Dxoour0y6+zf3QLEnS4w2zEGOMQ+gm8g/X
vMXly4/44Qe7zUKqqkYSiYRHN1H8YjJrmrbbLKQoyr6iKB5dMMuy/s0sJMvyvizL3n+ZhQgSi8Ue/l4X
+gV3kBaRV83skgAAAABJRU5ErkJggg==
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHGSURBVDhPnZJfa9pgFMb7JXa7sm9RkH2y3awro5dbS3Et
u2vHRsRcBEw0gqJxGiUo/q1JdDYVnVoLLbglm1GecV55U5xbZXsghPe85/k9h+TstFotNJtN1Ot11Go1
VKtVVCoVlMtlej/Z2aZGo4HlcrnxDAYDBtE07XEIJZOh3++zZMdxAgjVDMN4HEIjUzOl0blUKpVnsxl8
32d1Auq6/ncIpfLGbDb7M5/P9z3Pw83X78irE3bX6/WQy+X+DKFkPvJisQCZbyce3h3YOHph4XNiBel2
u8hkMlAUZR1iGIY7nU5Z03w+Z8nhVzbO3/Tw8cTB6UEngNi2jVQqtQ4pFovPdV13J5NVk1m7Y8kXR1cQ
Tq83IJZlQVXVdUihUAglk0l3PB6zpk7zHuF9Cx+OHyDhfRuasrpvt9uQZRmCIDxANE0LJRIJdzQabUA+
hR28P+zi7PASvr9gU8TjcUSj0d0AQEqn0wwyHA4DyMlLE2evO7g47uDbzAvMgiA8WzNzqarKILSJ7MM1
7nD+9gt+eP52M5csy6FYLObSJvJfTGZFUbabuSRJ2pMkyaUFM03z38xcoijuiaLo/peZiyCRSOTp73Wu
X1R9FoLvbSO9AAAAAElFTkSuQmCC
</value>
</data>
<data name="btnAddImage.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAG4SURBVDhPnZLditpQFIXnJXrb0rcYkD5YL4pMYS7bKaX0
HSLmIiV/BzRjIxolKGoM/iAijlbFizLIJOjJYZV9hmSwtiPtghCy917f2pB9EYYh+v0+er0eut0uOp0O
2u02Wq0WvV9cnFMQBBBCnDyLxUJCXNd9HkLJZJjP5zJ5NptlEKr5vv88hFamYUqj72az2drtduCcyzoB
Pc/7O4RS08Fqtbqv1WrzOI7Bf/4AD23Zm06n1PszhJLTlZMkAZnF/QaJdYXk21vw0JK9yWSCSqUC0zSP
Ib7vR9vtVg4dDgeZnJh5COcDxPfPENZVBhmPxyiXy8eQRqPxxvO8aLPZPELuOjJZ3N5AVL+eQEajERhj
x5B6vZ4rlUrRer1+hCwDcCMPcfvpCWLmwQNd9geDAQzDgKIoTxDXdXOMsWi1Wp1C3C8Q7BoPxjVEwuUW
lmWhWCy+ygAkx3Fytm1Hy+Uygxz0dxD2e8TlG+yjXWZWFOX1kTkVY0xC6BIlZNEDdz5C7OPz5lSGYeR0
XY/oEtNfTGbTNM+bU2madqlpWkQHNhwO/82cSlXVS1VVo/8ypyJIoVB4+Xs91S9svB2DRfl8BwAAAABJ
RU5ErkJggg==
</value>
</data>
<data name="btnAddNode.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHaSURBVDhPnZJda9NwFMb3Jbx1+C0Gxc+zG5lD9FY3FFFB
59udUze8Smk2szZpM9MsprRpDSlt09oXSilpa1sKilZT1hceOX9IJE5X9IEQcs55fs+BnJVKpYJyuYxS
qYRisYhCoYB8Pg/Lsuh9YWWZbNvGYrE483S7XQbRdf18CCWTwXEcltxut30I1UzTPB9CK9MwpdF3Lpez
xuMxZrMZqxPQMIy/QyjVG0ylUqfpdNqZTCYYfungvX3Ieq1Wi3p/hlCyt/J8PgeZR18/4XF0E/cP1qHZ
B6zXbDahaRokSQpCTNN0R6MRG5pOpxh87mAnehUv3t3Ea/U2nkQ3fUij0UAymQxCstnsZcMw3OFwyIY+
Oh/w4HAdL5UtvNHuYU+9E4DU63XIshyEZDKZkKIo7mAwYEO1Th6PhA28UrZ9yM7RBpLFMOtXq1WIogiO
435BdF0PybLs9vv9M5D9k7t4Ll3Hs6MbmM2nbIt4PI5IJLLqA0iqqoYSiYTb6/V8yMO3V/A0dg27x9v4
/uObb+Y47lLA7EmWZQahS2TrOhZ2j29hcuouN3sSRTEUi8VcukTvF5NZkqTlZk+CIKwJguDSgdVqtX8z
e+J5fo3nefe/zJ4IEg6HL/5e9/QT5xIPPuD/DmQAAAAASUVORK5CYII=
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAG3SURBVDhPnZLditpQFIXnJXrb0rcYkD5YL4pMYS7bKaX0
HSLmIiW/ghmNaJSgqDH4g4hYrYoXpUgT9OSwyj7DyWBtR9oFIWTvvb61IfsqiiIMBgP0+330ej10u110
Oh202216P7u6pDAMwTk/e5bLpYB4nvc0hJLJsFgsRPJ8Ps8gVAuC4GkIrUzDlEbfrVarvd/vwRgTdQL6
vv93CKXKwWq1eqjX64skScC+fwOLbNGbzWao1Wp/hlCyXDlNU5CZ/9gitW6QfnkNFlmiN51OUalUYJrm
KSQIgni324mh4/EoklMzD+6+A69+BLduMshkMkG5XD6FNJvNV77vx9vt9gHytSuS+f0deO3zGWQ8HsNx
nFNIo9HIlUqleLPZPEBWIZiRB7//8Agx82ChLvrD4RCGYUBRlEeI53k527bj9Xp9DvE+gTu3+GncgqdM
bGFZForF4osMQHJdV0BWq1UGOepvwO23SMp3OMT7zKwoyssTs5TjOAJClyggyz6Y+x78kFw2SxmGkdN1
PaZLlL+YzKZpXjZLaZp2rWlaTAc2Go3+zSylquq1qqrxf5mlCFIoFJ7/Xpf6BUmpHXRPK0SnAAAAAElF
TkSuQmCC
</value>
</data>
<data name="btnDelete.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGuSURBVDhP7Y+/TxphGMdp0T+gU3EwhsHZf6BDU9DNxsFE
B42DHTowdYC2gzg5aFy6kCb4sjiogxsW02pDD+447o7jgGAMUor8Og+FxV+Jhq953wghp1b/AL/JZ3nz
fL7v81gsz2EJBAIOQkiMEIInkvf7/e87BYSQrKIIKJdzjEqFcsCoVvOMWu0vdL0AXf+HdFqhJaXuAqNQ
yILnIwiHwwyO4xCJRBCNRsHzPGKxGERRhKIorMTn812YCvYgigITzVI8Hocsy0zWtCQMo3S3oFjchyxL
EASBiVSSJIlJiUQCyWQSmqYhk0mjXq/cLTg8zEFVFSbR36ikqioTU6kU5O9z+DM9iF+OXvye7Meqa/yq
LWN39yeOj6s4OaHU0GjoaDaPbjGQW19Cyv0GF8FltLIhnK19guQawoZnCqzgMYJjNpwHl4Fvo4DnFbBg
R33xLbbGXqNzxv8SfNfTaimb6E7TawN9N8/em22ntXS6Mgt4bbh0W9BwW1D8aEVo2Fo2z94bbqJvXpwZ
uKp67DC+9CL/4QV2RnqufzhffjXPPhhuov/ztsNaoGvTjdryDdsIqhi2ZmdsAAAAAElFTkSuQmCC
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVDhP7Y89S1thGIZToz+gk+kg4uDsH3CQJh0VB0EH
pUM7iDh1SNRBnRwqLkKGQvoGnKxDF0lV6gfxJOfk5JyT8xGJlDSmMV+nJ5osVguR3OV9MRKOae0P8IZr
eXmu+30eh+MpLMFg0E0IiRFC8J9kAoHAyH0BISSlKAIKhTSjWKR8Z5RKGUa5fAbTzMI0fyCZVGhJvrXA
ymZT4PkIwuEwg+M4RCIRRKNR8DyPWCwGURShKAor8fv9N7aCU4iiwES7FI/HIcsyk3Vdg2XlHxbkct8g
yxIEQWAilSRJYlIikYCmadB1HScnSVQqxYcF5+dpqKrCJPoblVRVZaJhGJA/LOJ4qh/77i4cTfRgY2as
3pRxePgVFxclXF5SyqhWTdRqP++wkP60CsM7iJvQGhqpXfzafAdpdgBbvkmwgscIjbpwHVoD1ocB33Ng
pQ+V90P4MtqN+zP+le2XnY2G8hmtqS25QN/ts22z53Hmrz6+AZZc+O11oOp1IDftxO4rZ8E+2zbc+Itl
8XVvveTrgzXfhczbZzjwdN7ueDoW7LN/DTfeM7fndmbp2nSjpvwHq8ip+rkEjbgAAAAASUVORK5CYII=
</value>
</data>
<data name="btnEditImage.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAL3SURBVDhPhdLfV9N1HMdx/oPuO93U6XTj6dRN3XasLC1P
lmlRHrfT4Vgno+PppA1HJGL6FRbjK4PD2IBvc6m0qSTDgeGmDgknfmEwQisMERZwYO67fbd95BA+O9up
pZx+vM55X33en8fnnM/7XaT4hmoVrzone1XN6vr/kj2q5jyt1hX9lZbOq/Mzsdg9PZ0mnRH/WYu6YD6R
ounEQKIA5F5O6Wkau6ap7YpQefZbXNdseEa+5HikioaQhQ/bHHza2oepdZyFlED2DmsFoM6lajm96ew0
UncPrkEb7aO7cQ5+QNOVEuzhnVh6D7Cz+Rhm5Trz2j8AqYyguXuGSr+bE5Eq7OEdHPlhO5bQO0iXirGG
PsFY/xUVR39iTssie4ceBLSMwNkTY5/PxddqBXK/AeniW+wPbuaL85uRAqUY5GqUdjc3jhXzy5mDRFpf
ItK4xpAHEmlB67nfkHx+bKHD1PWXUBl8E/P3m9gXKObz78poPLqH2aAJbbQL9BiJ0ZOEatbP5YE7ukDp
ncXmH6HMoyB17qImsAOp9z3KvR9hbStlYaySpelOZi9ayEZP8/utywzb3xdFudnGUwJXYC6P1PsifFZl
4JD1RSTLWlrq1xMfq2Ale5nszVLiVz/muruEiOPtxbDt9SfywGJSYPa8hql9I7uPv4Kj/BmiyhbGvlnH
neheVsQAmQkj4vY2UuNmRhs23huuW/d0/hNrXde0eFIQmrhQqP5oB31ndjE7aPrzsgEx9S7JsXJuNr+K
opzSC1Ow5oHsA0DwQjXj5/awkg0hJku4e3s7WnQvP9tfZmZqEtlz3xgbvOpUPJEkqQuS6bsMB9386Dcz
0i0zE95KZnIb8UgZEy1vsBj7lYX8Kl/5e5WdHWqN4+RQX245crKn+gVI3eKGYwtB88P02zcQOPTcSpvi
03Pn8qkhzdmhygVgdQ4YH19eGmhgKXyE8MG1uI2P6D2mNU+t7vvXbHr2ISEZH132H96w3Fv7/KWusicf
W91zf/4A4AuLF1bhN90AAAAASUVORK5CYII=
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAALySURBVDhPhdLfT1tlHMdx/gPvjYnJLrxZjF7otZk63XRx
OjdFl7UxZBonZjFulhVxyNzOoFLOKAi0wLHDbdhuw9EOmNhuK0PWsQMHimwqk0FBIND1tKftM4Lsbdpo
sxF/fJLv1fN9Xk/yfL8Fim+oWvGq87JX1e3u/y/Zo+qus2pNwd9p7ry2MB2N3jNSKVJp8Z+1ZAgW4kka
Tg3E80D25aSRot4fpdqvUX7+W9zXHXhGvuCkVkFdyMb7rU4+bunD0jLOYlIge4f1PFDjVvWs3nA+itTd
g3vQQfvoPlyD79FwtYjG8B5svYfY03QCq3KDBf0fgGRa0NQ9Q3lXG6e0ChrDuzn24y5sobeQLhdiD32E
ufZLyo7/zLyeQfYOPQjoaYGrZ5aDPjdfq2XI/SakS2/weXAbn/2wDSlQjEmuRGlv4+aJQn49dxit5QW0
+vWmHBBPCVou/I7k68IROkpNfxHlwdexfr+Vg4FCPv2uhPrj+5kLWtBH/WDMEh89Tahq03wOuGMIlN45
HF0jlHgUpM69VAV2I/W+Q6n3A+ytxSyOlbMc7WTuko1M5Cx/3L7C8FfvioLsbGNJgTswn0NqfRqfVJg4
Yn8eybaB5tpNxMbKWM1cIXOrmNi1D7nRVoTmfHMp7Hj1sRywlBBYPa9gad/CvpMv4Sx9moiynbFvNnIn
coBVMUB6woyY3kly3IpWu+XecM3GJ3OfWO2+rscSgtDExXz1RzroO7eXuUHLX5dNiKm3SYyVcqvpZRTl
jJGfgj0HZB4AghcrGb+wn9VMCDFZxN3pXeiRA/zS+CIzU5PInvvGWOdVp2LxBAlDkEjdZTjYxk9dVka6
ZWbCO0hP7iSmlTDR/BpLs7+xuHaVXR1qlfP0UF92ObKyp/I5SN7mpnM7QevD9DduJnDkmdVWxWdkz+Uz
Q7qrQ5XzwNocMq9bWR6oYzl8jPDhDbjNjxg9lvVPrO3712x96iEhmR9d8R/dvNJb/exlf8nj69b23J8/
AbuKiwBr5ZOIAAAAAElFTkSuQmCC
</value>
</data>
<data name="btnConnect.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<data name="btnConnNode.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29m
dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHrSURBVDhPY/j//z8DJRhDgFSMIUAqxhAgFcMZdnZ2
@@ -308,19 +347,19 @@
gg==
</value>
</data>
<data name="btnDeleteConnection.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<data name="btnConnDir.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHvSURBVDhP7Y7Ni1JhGMVvXadgWrWzRQyzTEFyla0cx6sL
P6K7USGoRYr1SoJ9zGh3YbgYQZjAC+YqIURoo61slDLQcRORgWCt7gxShBRp0JQ2mSeegS4mzn/QgRce
zvmdw8tx/6XKZrOdYIzdicfj/VwuB0mSuoyxc4wxrSRJCnmUEUPsP2WdTnfM6XSm0uk0er0eFEVBvV6n
wo4kSY12uz0ir9lsghhiqaMOGI3GC+Fw+Gun0+n7fL6ngiCMA4EAZFlGLBYD3eRRVigUusRSZ3oglUgk
hrIsB10u16LJZPpWq9XQarXQaDRQLBZBHmXEEEsddcBgMFwPBoODTCZzWxTFqsVi2bfb7RBF8eDRTR5l
xBBLHXVAr9efcbvd75LJ5CCfz38plUrIZrOIRCKIRqMHd2WD4cXFpd/PVxfwxL64/2jl+H11gOM43mw2
n3U4HLt+v38vFAoNGWM/PR7PZa/Xa31wyTx6c+s8huVNTN5W8P3xTbwK6cbPrJob0yOHakvglR/lTUB2
A+sngY1lfE6toGzhd2bZuSqvaiaT1yVMaxDXgvxZdq6qAv9+7+FVIK7FaI1Df41D9xqPio3/MMvO1bb3
1L2XV5Z+fVxfxqfYAhT/EdTsmvGWcPTuLHuotr2no1Urv0vfph/9Lf8B0zIZ8W7n4ScAAAAASUVORK5C
YII=
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29m
dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHrSURBVDhPY/j//z8DJRhDgFSMIUAqxhAgFcMZdnZ2
3FlZWaWtra3v5s2b97+mpuZhTk6OeU5OjkRNTc1dkBhIDqQGpBbFACMjIzYfH5+uiRMn/n/x4sX/u3fv
/j948OD/xsbGe9XV1Ydu3rz5AyR25MiR/yA1ILUgPXADDA0N/YqLiz9cvXr1XURExDZvb+8/qamp/ydN
mvS/srLyP4gNEgPJrVix4iFILUgPsgu6mpqavk+ePDnd39+fy97e/vPevXv/nzt37v+hQ4f+r1279j9I
DCQHUgNSC9IDN0BXVzczPT39/bRp00qCgoJ2Ojo6/nJzc/sfGBgIxiA2SAwkB1IDUgvSAzdAU1NT09fX
93pvb+/7VatWvV23bt3/6dOn/y8sLPxfUVEBZvcvbP1fODXmX1qf//+IJse/Lrm6E+EGqKmpMdvb2xt4
eXndT0lJ+ZKdnf09Ozv7Z3h4eFx4eLhzZm3cz8bVif+3XJn6/8KzXf/7d2f9D+/X/W+eLdmDEa/YcGy7
y/eNlyf833ht0n8Q6NmT+r9/TzrIgO8YirFhn2rD/9uuzAFrhoFNl6aCDMBUjA1b5kh/796V9L99VwJY
c/vOBNJcYJ4t2RLco/G/d1cK2GYQDeITHQZQQzrMsyU/gZwNpTtA4gBRO5Y8lpxI5AAAAABJRU5ErkJg
gg==
</value>
</data>
<data name="btnToggleGrid.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
@@ -335,18 +374,18 @@
<data name="btnFitMap.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
</value>
</data>
<data name="btAddMagnet.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">