feat: Add configurable Padding and display nodes without RFID in gray

MapNode.cs:
- Padding 속성 추가 (기본값 8px, 텍스트 주변 여백)
- Clone 메서드에 Padding 복사 추가

NodePropertyWrapper.cs:
- LabelNodePropertyWrapper에 Padding 속성 추가
- PropertyGrid에서 0~50px 범위로 조정 가능

UnifiedAGVCanvas.Events.cs:
- DrawLabelNode: 하드코딩된 패딩을 node.Padding 사용
- GetNodeBrush: RFID 없는 노드를 회색 계통으로 표시
  * Normal: Blue → LightGray
  * Rotation: Orange → DarkGray
  * Docking: Green → Gray
  * Charging: Red → Silver

UnifiedAGVCanvas.Mouse.cs:
- HandleLabelNodeDoubleClick: node.Name → node.LabelText 사용

이제 라벨 노드 패딩을 속성창에서 조정 가능하고,
RFID 미할당 노드를 시각적으로 쉽게 구분 가능

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
backuppc
2025-10-30 17:32:13 +09:00
parent 0e8a452b54
commit 5e14907f1c
7 changed files with 89 additions and 25 deletions

View File

@@ -45,6 +45,8 @@ namespace AGVMapEditor.Controls
this.DoubleBuffered = true; this.DoubleBuffered = true;
this.BackColor = Color.White; this.BackColor = Color.White;
this.AutoScroll = true; this.AutoScroll = true;
} }
#region Properties #region Properties

View File

@@ -25,6 +25,11 @@ namespace AGVMapEditor.Forms
{ {
LoadImageFromNode(imageNode); LoadImageFromNode(imageNode);
} }
this.KeyPreview = true;
this.KeyDown += (s1, e1) => {
if (e1.KeyCode == Keys.Escape) this.Close();
};
} }
private void SetupUI() private void SetupUI()

View File

@@ -154,6 +154,19 @@ namespace AGVMapEditor.Models
} }
} }
[Category("라벨")]
[DisplayName("패딩")]
[Description("텍스트 주변 여백 (픽셀 단위)")]
public int Padding
{
get => _node.Padding;
set
{
_node.Padding = Math.Max(0, Math.Min(50, value));
_node.ModifiedDate = DateTime.Now;
}
}
[Category("위치")] [Category("위치")]
[DisplayName("X 좌표")] [DisplayName("X 좌표")]
[Description("맵에서의 X 좌표")] [Description("맵에서의 X 좌표")]

View File

@@ -743,10 +743,10 @@ namespace AGVNavigationCore.Controls
{ {
var backgroundBrush = new SolidBrush(node.BackColor); var backgroundBrush = new SolidBrush(node.BackColor);
var backgroundRect = new Rectangle( var backgroundRect = new Rectangle(
textPoint.X - 2, textPoint.X - node.Padding,
textPoint.Y - 2, textPoint.Y - node.Padding,
(int)textSize.Width + 4, (int)textSize.Width + (node.Padding * 2),
(int)textSize.Height + 4 (int)textSize.Height + (node.Padding * 2)
); );
g.FillRectangle(backgroundBrush, backgroundRect); g.FillRectangle(backgroundBrush, backgroundRect);
g.DrawRectangle(Pens.Black, backgroundRect); g.DrawRectangle(Pens.Black, backgroundRect);
@@ -759,11 +759,12 @@ namespace AGVNavigationCore.Controls
// 선택된 노드 강조 // 선택된 노드 강조
if (node == _selectedNode) if (node == _selectedNode)
{ {
var selectionPadding = node.Padding + 2;
var selectionRect = new Rectangle( var selectionRect = new Rectangle(
textPoint.X - 4, textPoint.X - selectionPadding,
textPoint.Y - 4, textPoint.Y - selectionPadding,
(int)textSize.Width + 8, (int)textSize.Width + (selectionPadding * 2),
(int)textSize.Height + 8 (int)textSize.Height + (selectionPadding * 2)
); );
g.DrawRectangle(_selectedNodePen, selectionRect); g.DrawRectangle(_selectedNodePen, selectionRect);
} }
@@ -771,11 +772,12 @@ namespace AGVNavigationCore.Controls
// 호버된 노드 강조 // 호버된 노드 강조
if (node == _hoveredNode) if (node == _hoveredNode)
{ {
var hoverPadding = node.Padding + 4;
var hoverRect = new Rectangle( var hoverRect = new Rectangle(
textPoint.X - 6, textPoint.X - hoverPadding,
textPoint.Y - 6, textPoint.Y - hoverPadding,
(int)textSize.Width + 12, (int)textSize.Width + (hoverPadding * 2),
(int)textSize.Height + 12 (int)textSize.Height + (hoverPadding * 2)
); );
g.DrawRectangle(new Pen(Color.Orange, 2), hoverRect); g.DrawRectangle(new Pen(Color.Orange, 2), hoverRect);
} }
@@ -908,22 +910,25 @@ namespace AGVNavigationCore.Controls
private Brush GetNodeBrush(MapNode node) private Brush GetNodeBrush(MapNode node)
{ {
// RFID가 없는 노드는 회색 계통으로 표시
bool hasRfid = node.HasRfid();
switch (node.Type) switch (node.Type)
{ {
case NodeType.Normal: case NodeType.Normal:
return _normalNodeBrush; return hasRfid ? _normalNodeBrush : new SolidBrush(Color.LightGray);
case NodeType.Rotation: case NodeType.Rotation:
return _rotationNodeBrush; return hasRfid ? _rotationNodeBrush : new SolidBrush(Color.DarkGray);
case NodeType.Docking: case NodeType.Docking:
return _dockingNodeBrush; return hasRfid ? _dockingNodeBrush : new SolidBrush(Color.Gray);
case NodeType.Charging: case NodeType.Charging:
return _chargingNodeBrush; return hasRfid ? _chargingNodeBrush : new SolidBrush(Color.Silver);
case NodeType.Label: case NodeType.Label:
return new SolidBrush(Color.Purple); return new SolidBrush(Color.Purple);
case NodeType.Image: case NodeType.Image:
return new SolidBrush(Color.Brown); return new SolidBrush(Color.Brown);
default: default:
return _normalNodeBrush; return hasRfid ? _normalNodeBrush : new SolidBrush(Color.LightGray);
} }
} }

View File

@@ -105,7 +105,7 @@ namespace AGVNavigationCore.Controls
private void HandleLabelNodeDoubleClick(MapNode node) private void HandleLabelNodeDoubleClick(MapNode node)
{ {
// 라벨 텍스트 입력창 표시 // 라벨 텍스트 입력창 표시
string currentText = node.Name ?? "새 라벨"; string currentText = node.LabelText ?? "새 라벨";
string newText = Microsoft.VisualBasic.Interaction.InputBox( string newText = Microsoft.VisualBasic.Interaction.InputBox(
"라벨 텍스트를 입력하세요:", "라벨 텍스트를 입력하세요:",
"라벨 편집", "라벨 편집",
@@ -113,7 +113,7 @@ namespace AGVNavigationCore.Controls
if (!string.IsNullOrWhiteSpace(newText) && newText != currentText) if (!string.IsNullOrWhiteSpace(newText) && newText != currentText)
{ {
node.Name = newText.Trim(); node.LabelText = newText.Trim();
MapChanged?.Invoke(this, EventArgs.Empty); MapChanged?.Invoke(this, EventArgs.Empty);
Invalidate(); Invalidate();
} }

View File

@@ -138,6 +138,11 @@ namespace AGVNavigationCore.Models
/// </summary> /// </summary>
public bool ShowBackground { get; set; } = false; public bool ShowBackground { get; set; } = false;
/// <summary>
/// 라벨 패딩 (NodeType.Label인 경우 사용, 픽셀 단위)
/// </summary>
public int Padding { get; set; } = 8;
/// <summary> /// <summary>
/// 이미지 파일 경로 (편집용, 저장시엔 사용되지 않음) /// 이미지 파일 경로 (편집용, 저장시엔 사용되지 않음)
/// </summary> /// </summary>
@@ -343,6 +348,7 @@ namespace AGVNavigationCore.Models
ForeColor = ForeColor, ForeColor = ForeColor,
BackColor = BackColor, BackColor = BackColor,
ShowBackground = ShowBackground, ShowBackground = ShowBackground,
Padding = Padding,
ImagePath = ImagePath, ImagePath = ImagePath,
ImageBase64 = ImageBase64, ImageBase64 = ImageBase64,
Scale = Scale, Scale = Scale,

File diff suppressed because one or more lines are too long