using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using AGVNavigationCore.Models; namespace AGVMapEditor.Models { /// /// 노드 타입에 따른 PropertyWrapper 팩토리 /// public static class NodePropertyWrapperFactory { public static object CreateWrapper(MapNode node, List mapNodes) { switch (node.Type) { case NodeType.Label: return new LabelNodePropertyWrapper(node, mapNodes); case NodeType.Image: return new ImageNodePropertyWrapper(node, mapNodes); default: return new NodePropertyWrapper(node, mapNodes); } } } /// /// 라벨 노드 전용 PropertyWrapper /// public class LabelNodePropertyWrapper { private MapNode _node; private List _mapNodes; public LabelNodePropertyWrapper(MapNode node, List mapNodes) { _node = node; _mapNodes = mapNodes; } [Category("기본 정보")] [DisplayName("노드 ID")] [Description("노드의 고유 식별자")] [ReadOnly(true)] public string NodeId { get => _node.NodeId; } [Category("기본 정보")] [DisplayName("노드 타입")] [Description("노드의 타입")] [ReadOnly(true)] public NodeType Type { get => _node.Type; } [Category("라벨")] [DisplayName("텍스트")] [Description("표시할 텍스트")] public string LabelText { get => _node.LabelText; set { _node.LabelText = value ?? ""; _node.ModifiedDate = DateTime.Now; } } [Category("라벨")] [DisplayName("폰트 패밀리")] [Description("폰트 패밀리")] public string FontFamily { get => _node.FontFamily; set { _node.FontFamily = value ?? "Arial"; _node.ModifiedDate = DateTime.Now; } } [Category("라벨")] [DisplayName("폰트 크기")] [Description("폰트 크기")] public float FontSize { get => _node.FontSize; set { _node.FontSize = Math.Max(6, Math.Min(72, value)); _node.ModifiedDate = DateTime.Now; } } [Category("라벨")] [DisplayName("폰트 스타일")] [Description("폰트 스타일")] public FontStyle FontStyle { get => _node.FontStyle; set { _node.FontStyle = value; _node.ModifiedDate = DateTime.Now; } } [Category("라벨")] [DisplayName("전경색")] [Description("텍스트 색상")] public Color ForeColor { get => _node.ForeColor; set { _node.ForeColor = value; _node.ModifiedDate = DateTime.Now; } } [Category("라벨")] [DisplayName("배경색")] [Description("배경 색상")] public Color BackColor { get => _node.BackColor; set { _node.BackColor = value; _node.ModifiedDate = DateTime.Now; } } [Category("라벨")] [DisplayName("배경 표시")] [Description("배경을 표시할지 여부")] public bool ShowBackground { get => _node.ShowBackground; set { _node.ShowBackground = value; _node.ModifiedDate = DateTime.Now; } } [Category("위치")] [DisplayName("X 좌표")] [Description("맵에서의 X 좌표")] public int PositionX { get => _node.Position.X; set { _node.Position = new Point(value, _node.Position.Y); _node.ModifiedDate = DateTime.Now; } } [Category("위치")] [DisplayName("Y 좌표")] [Description("맵에서의 Y 좌표")] public int PositionY { get => _node.Position.Y; set { _node.Position = new Point(_node.Position.X, value); _node.ModifiedDate = DateTime.Now; } } [Category("정보")] [DisplayName("생성 일시")] [Description("노드가 생성된 일시")] [ReadOnly(true)] public DateTime CreatedDate { get => _node.CreatedDate; } [Category("정보")] [DisplayName("수정 일시")] [Description("노드가 마지막으로 수정된 일시")] [ReadOnly(true)] public DateTime ModifiedDate { get => _node.ModifiedDate; } } /// /// 이미지 노드 전용 PropertyWrapper /// public class ImageNodePropertyWrapper { private MapNode _node; private List _mapNodes; public ImageNodePropertyWrapper(MapNode node, List mapNodes) { _node = node; _mapNodes = mapNodes; } [Category("기본 정보")] [DisplayName("노드 ID")] [Description("노드의 고유 식별자")] [ReadOnly(true)] public string NodeId { get => _node.NodeId; } [Category("기본 정보")] [DisplayName("노드 타입")] [Description("노드의 타입")] [ReadOnly(true)] public NodeType Type { get => _node.Type; } [Category("이미지")] [DisplayName("이미지 경로")] [Description("이미지 파일 경로")] // 파일 선택 에디터는 나중에 구현 public string ImagePath { get => _node.ImagePath; set { _node.ImagePath = value ?? ""; _node.LoadImage(); // 이미지 다시 로드 _node.ModifiedDate = DateTime.Now; } } [Category("이미지")] [DisplayName("가로 배율")] [Description("가로 배율 (1.0 = 원본 크기)")] public float ScaleWidth { get => _node.Scale.Width; set { _node.Scale = new SizeF(Math.Max(0.1f, Math.Min(5.0f, value)), _node.Scale.Height); _node.ModifiedDate = DateTime.Now; } } [Category("이미지")] [DisplayName("세로 배율")] [Description("세로 배율 (1.0 = 원본 크기)")] public float ScaleHeight { get => _node.Scale.Height; set { _node.Scale = new SizeF(_node.Scale.Width, Math.Max(0.1f, Math.Min(5.0f, value))); _node.ModifiedDate = DateTime.Now; } } [Category("이미지")] [DisplayName("투명도")] [Description("투명도 (0.0 = 투명, 1.0 = 불투명)")] public float Opacity { get => _node.Opacity; set { _node.Opacity = Math.Max(0.0f, Math.Min(1.0f, value)); _node.ModifiedDate = DateTime.Now; } } [Category("이미지")] [DisplayName("회전각도")] [Description("회전 각도 (도 단위)")] public float Rotation { get => _node.Rotation; set { _node.Rotation = value % 360; _node.ModifiedDate = DateTime.Now; } } [Category("위치")] [DisplayName("X 좌표")] [Description("맵에서의 X 좌표")] public int PositionX { get => _node.Position.X; set { _node.Position = new Point(value, _node.Position.Y); _node.ModifiedDate = DateTime.Now; } } [Category("위치")] [DisplayName("Y 좌표")] [Description("맵에서의 Y 좌표")] public int PositionY { get => _node.Position.Y; set { _node.Position = new Point(_node.Position.X, value); _node.ModifiedDate = DateTime.Now; } } [Category("정보")] [DisplayName("생성 일시")] [Description("노드가 생성된 일시")] [ReadOnly(true)] public DateTime CreatedDate { get => _node.CreatedDate; } [Category("정보")] [DisplayName("수정 일시")] [Description("노드가 마지막으로 수정된 일시")] [ReadOnly(true)] public DateTime ModifiedDate { get => _node.ModifiedDate; } } /// /// PropertyGrid에서 사용할 노드 속성 래퍼 클래스 /// public class NodePropertyWrapper { private MapNode _node; private List _mapNodes; public NodePropertyWrapper(MapNode node, List mapNodes) { _node = node; _mapNodes = mapNodes; } [Category("기본 정보")] [DisplayName("노드 ID")] [Description("노드의 고유 식별자")] [ReadOnly(true)] public string NodeId { get => _node.NodeId; set => _node.NodeId = value; } [Category("기본 정보")] [DisplayName("노드 이름")] [Description("노드의 표시 이름")] public string Name { get => _node.Name; set { _node.Name = value; _node.ModifiedDate = DateTime.Now; } } [Category("기본 정보")] [DisplayName("노드 타입")] [Description("노드의 타입 (Normal, Rotation, Docking, Charging)")] public NodeType Type { get => _node.Type; set { _node.Type = value; _node.CanRotate = value == NodeType.Rotation; _node.SetDefaultColorByType(value); _node.ModifiedDate = DateTime.Now; } } [Category("위치")] [DisplayName("X 좌표")] [Description("맵에서의 X 좌표")] public int PositionX { get => _node.Position.X; set { _node.Position = new Point(value, _node.Position.Y); _node.ModifiedDate = DateTime.Now; } } [Category("위치")] [DisplayName("Y 좌표")] [Description("맵에서의 Y 좌표")] public int PositionY { get => _node.Position.Y; set { _node.Position = new Point(_node.Position.X, value); _node.ModifiedDate = DateTime.Now; } } [Category("고급")] [DisplayName("회전 가능")] [Description("이 노드에서 AGV가 회전할 수 있는지 여부")] public bool CanRotate { get => _node.CanRotate; set { _node.CanRotate = value; _node.ModifiedDate = DateTime.Now; } } [Category("고급")] [DisplayName("RFID")] [Description("RFID ID")] public string RFID { get => _node.RfidId; set { _node.RfidId = value; _node.ModifiedDate = DateTime.Now; } } [Category("고급")] [DisplayName("설명")] [Description("노드에 대한 추가 설명")] public string Description { get => _node.Description; set { _node.Description = value ?? ""; _node.ModifiedDate = DateTime.Now; } } [Category("고급")] [DisplayName("활성화")] [Description("노드 활성화 여부")] public bool IsActive { get => _node.IsActive; set { _node.IsActive = value; _node.ModifiedDate = DateTime.Now; } } [Category("정보")] [DisplayName("생성 일시")] [Description("노드가 생성된 일시")] [ReadOnly(true)] public DateTime CreatedDate { get => _node.CreatedDate; } [Category("정보")] [DisplayName("수정 일시")] [Description("노드가 마지막으로 수정된 일시")] [ReadOnly(true)] public DateTime ModifiedDate { get => _node.ModifiedDate; } } }