초기 커밋: SheetMe 서식생성기 (P0~P5 완료 상태)
레거시 서식생성기(VB.NET WinForms) 대체용 C#/.NET 10 WPF 디자이너. 기준선: 실DB 활성 디자인 1,271건 왕복 의미론 diff 0 / 예외 0, 단위 테스트 49/49. 이 커밋에 함께 포함된 자격증명 분리: - appsettings.json 을 __HOST__/__PASSWORD__ 플레이스홀더로 전환 - 실접속 정보는 appsettings.Development.json 으로 분리(.gitignore 제외, csproj Debug 조건부 복사라 Release 산출물에 실리지 않음) - ConfigLoader 를 환경변수 > Development > appsettings 순 레이어링으로 변경, 미치환 플레이스홀더는 '미설정'으로 간주 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,258 @@
|
||||
namespace SheetMe.Core.Catalog;
|
||||
|
||||
/// <summary>
|
||||
/// 팔레트 컨트롤 카탈로그 — 팔레트 목록·기본 크기·필드 생성 규칙의 단일 출처.
|
||||
/// 속성 편집 스키마(PropertyDef)는 P3(인스펙터)에서 확장한다.
|
||||
/// </summary>
|
||||
public static class ControlRegistry
|
||||
{
|
||||
#region Member Fields
|
||||
private static readonly List<ControlDescriptor> all = new()
|
||||
{
|
||||
new()
|
||||
{
|
||||
Type = "Label", DisplayName = "라벨", DefaultW = 120, DefaultH = 22,
|
||||
Properties = new PropertyDef[]
|
||||
{
|
||||
new() { Key = "Text", Label = "텍스트", Editor = PropEditorKind.MultilineText },
|
||||
new() { Key = "TextAlign", Label = "정렬", Editor = PropEditorKind.Choice, Choices = new[] { "TopLeft", "TopCenter", "TopRight", "MiddleLeft", "MiddleCenter", "MiddleRight" } },
|
||||
new() { Key = "ForeColor", Label = "글자색", Editor = PropEditorKind.Color },
|
||||
new() { Key = "BackColor", Label = "배경색", Editor = PropEditorKind.Color },
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Type = "TextBox", DisplayName = "텍스트박스", DefaultW = 160, DefaultH = 22, CreatesField = true,
|
||||
Properties = new PropertyDef[]
|
||||
{
|
||||
new() { Key = "Text", Label = "텍스트", Editor = PropEditorKind.Text },
|
||||
new() { Key = "Multiline", Label = "여러 줄", Editor = PropEditorKind.Toggle },
|
||||
new() { Key = "TextAlign", Label = "정렬", Editor = PropEditorKind.Choice, Choices = new[] { "Left", "Center", "Right" } },
|
||||
new() { Key = "IsRequiredValue", Label = "필수 입력", Editor = PropEditorKind.Choice, Choices = new[] { "No", "Yes" } },
|
||||
new() { Key = "InitialValue", Label = "초기값", Editor = PropEditorKind.Text },
|
||||
new() { Key = "DataInterfaceTag", Label = "데이터 태그", Editor = PropEditorKind.DataInterfaceTag },
|
||||
new() { Key = "DataActionTag", Label = "액션 태그", Editor = PropEditorKind.DataActionTag },
|
||||
new() { Key = "DataActionTagControl", Label = "액션 대상 컨트롤", Editor = PropEditorKind.Text },
|
||||
new() { Key = "RwdRsvWrdYon", Label = "상용구 사용", Editor = PropEditorKind.Toggle },
|
||||
new() { Key = "RwdOrderAutYon", Label = "처방연동 상용구", Editor = PropEditorKind.Toggle },
|
||||
new() { Key = "BackColor", Label = "배경색", Editor = PropEditorKind.Color },
|
||||
new() { Key = "BorderStyle", Label = "테두리", Editor = PropEditorKind.Choice, Choices = new[] { "None", "FixedSingle", "Fixed3D" } },
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Type = "MaskedTextBox", DisplayName = "마스크입력", DefaultW = 160, DefaultH = 22, CreatesField = true,
|
||||
Properties = new PropertyDef[]
|
||||
{
|
||||
new() { Key = "Mask", Label = "마스크", Editor = PropEditorKind.Text },
|
||||
new() { Key = "IsRequiredValue", Label = "필수 입력", Editor = PropEditorKind.Choice, Choices = new[] { "No", "Yes" } },
|
||||
new() { Key = "DataInterfaceTag", Label = "데이터 태그", Editor = PropEditorKind.DataInterfaceTag },
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Type = "CheckBox", DisplayName = "체크박스", DefaultW = 110, DefaultH = 20, CreatesField = true, DefaultDataType = "bool",
|
||||
Properties = new PropertyDef[]
|
||||
{
|
||||
new() { Key = "Text", Label = "텍스트", Editor = PropEditorKind.Text },
|
||||
new() { Key = "Checked", Label = "기본 체크", Editor = PropEditorKind.Toggle },
|
||||
new() { Key = "Score", Label = "점수", Editor = PropEditorKind.Number },
|
||||
new() { Key = "IsRequiredValue", Label = "필수 입력", Editor = PropEditorKind.Choice, Choices = new[] { "No", "Yes" } },
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Type = "RadioButton", DisplayName = "라디오버튼", DefaultW = 110, DefaultH = 20, CreatesField = true,
|
||||
Properties = new PropertyDef[]
|
||||
{
|
||||
new() { Key = "Text", Label = "텍스트", Editor = PropEditorKind.Text },
|
||||
new() { Key = "Checked", Label = "기본 선택", Editor = PropEditorKind.Toggle },
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Type = "ComboBox", DisplayName = "콤보박스", DefaultW = 140, DefaultH = 22, CreatesField = true,
|
||||
Properties = new PropertyDef[]
|
||||
{
|
||||
new() { Key = "Items", Label = "선택지(줄바꿈 구분)", Editor = PropEditorKind.StringList },
|
||||
new() { Key = "IsRequiredValue", Label = "필수 입력", Editor = PropEditorKind.Choice, Choices = new[] { "No", "Yes" } },
|
||||
new() { Key = "DataTableField", Label = "데이터 필드", Editor = PropEditorKind.Text },
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Type = "ListBox", DisplayName = "리스트박스", DefaultW = 140, DefaultH = 90, CreatesField = true,
|
||||
Properties = new PropertyDef[]
|
||||
{
|
||||
new() { Key = "Items", Label = "항목(줄바꿈 구분)", Editor = PropEditorKind.StringList },
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Type = "CheckList", DisplayName = "체크리스트", DefaultW = 160, DefaultH = 90, CreatesField = true,
|
||||
Properties = new PropertyDef[]
|
||||
{
|
||||
new() { Key = "Items", Label = "항목(줄바꿈 구분)", Editor = PropEditorKind.StringList },
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Type = "DateTimePicker", DisplayName = "날짜선택", DefaultW = 140, DefaultH = 22, CreatesField = true, DefaultDataType = "datetime",
|
||||
Properties = new PropertyDef[]
|
||||
{
|
||||
new() { Key = "Format", Label = "형식", Editor = PropEditorKind.Choice, Choices = new[] { "Long", "Short", "Time", "Custom" } },
|
||||
new() { Key = "CustomFormat", Label = "사용자 형식", Editor = PropEditorKind.Text },
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Type = "Panel", DisplayName = "패널", DefaultW = 240, DefaultH = 140, IsContainer = true,
|
||||
Properties = new PropertyDef[]
|
||||
{
|
||||
new() { Key = "BackColor", Label = "배경색", Editor = PropEditorKind.Color },
|
||||
new() { Key = "BorderStyle", Label = "테두리", Editor = PropEditorKind.Choice, Choices = new[] { "None", "FixedSingle", "Fixed3D" } },
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Type = "GroupBox", DisplayName = "그룹박스", DefaultW = 240, DefaultH = 140, IsContainer = true,
|
||||
Properties = new PropertyDef[]
|
||||
{
|
||||
new() { Key = "Text", Label = "제목", Editor = PropEditorKind.Text },
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Type = "Line", DisplayName = "선", DefaultW = 200, DefaultH = 1,
|
||||
Properties = new PropertyDef[]
|
||||
{
|
||||
new() { Key = "LineColor", Label = "선 색", Editor = PropEditorKind.Color },
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Type = "PictureBox", DisplayName = "이미지", DefaultW = 120, DefaultH = 90,
|
||||
Properties = new PropertyDef[]
|
||||
{
|
||||
new() { Key = "DataInterfaceTag", Label = "데이터 태그", Editor = PropEditorKind.DataInterfaceTag },
|
||||
new() { Key = "SizeMode", Label = "크기 모드", Editor = PropEditorKind.Choice, Choices = new[] { "Normal", "StretchImage", "AutoSize", "CenterImage", "Zoom" } },
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Type = "CalcBox", DisplayName = "계산박스", DefaultW = 100, DefaultH = 22, CreatesField = true, DefaultDataType = "decimal",
|
||||
Properties = new PropertyDef[]
|
||||
{
|
||||
new() { Key = "Formula", Label = "수식", Editor = PropEditorKind.MultilineText },
|
||||
new() { Key = "Text", Label = "텍스트", Editor = PropEditorKind.Text },
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Type = "Button", DisplayName = "버튼", DefaultW = 90, DefaultH = 26,
|
||||
Properties = new PropertyDef[]
|
||||
{
|
||||
new() { Key = "Text", Label = "텍스트", Editor = PropEditorKind.Text },
|
||||
new() { Key = "DataActionTag", Label = "액션 태그", Editor = PropEditorKind.DataActionTag },
|
||||
new() { Key = "DataActionTagControl", Label = "액션 대상 컨트롤", Editor = PropEditorKind.Text },
|
||||
new() { Key = "GetDataActionTagControl", Label = "입력 파라미터 컨트롤", Editor = PropEditorKind.Text },
|
||||
new() { Key = "KeyboardShortcut", Label = "단축키", Editor = PropEditorKind.Text },
|
||||
new() { Key = "BackColor", Label = "배경색", Editor = PropEditorKind.Color },
|
||||
},
|
||||
},
|
||||
new()
|
||||
{
|
||||
Type = "DataTable", DisplayName = "데이터소스", DefaultW = 34, DefaultH = 34,
|
||||
Properties = new PropertyDef[]
|
||||
{
|
||||
new() { Key = "Query", Label = "쿼리(SQL)", Editor = PropEditorKind.SqlQuery },
|
||||
new() { Key = "DataInterfaceTag", Label = "데이터 태그", Editor = PropEditorKind.DataInterfaceTag },
|
||||
new() { Key = "ExcuteQuery", Label = "쿼리 실행", Editor = PropEditorKind.Toggle },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
private static readonly Dictionary<string, ControlDescriptor> byType =
|
||||
all.ToDictionary(d => d.Type, StringComparer.Ordinal);
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
/// <summary>팔레트에 노출할 전체 컨트롤 목록</summary>
|
||||
public static IReadOnlyList<ControlDescriptor> All => all;
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
/// <summary>타입명으로 기술자 조회 — 미지원 타입(Placeholder 포함)은 null</summary>
|
||||
public static ControlDescriptor? Find(string type)
|
||||
=> byType.TryGetValue(type, out var descriptor) ? descriptor : null;
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>팔레트 컨트롤 1종의 기술자</summary>
|
||||
public sealed class ControlDescriptor
|
||||
{
|
||||
/// <summary>중립 타입명(LegacyTypeCatalog 와 공유하는 키)</summary>
|
||||
public string Type { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>팔레트 표시명(한글)</summary>
|
||||
public string DisplayName { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>드롭 시 기본 너비(px)</summary>
|
||||
public double DefaultW { get; init; }
|
||||
|
||||
/// <summary>드롭 시 기본 높이(px)</summary>
|
||||
public double DefaultH { get; init; }
|
||||
|
||||
/// <summary>컨테이너 여부(Panel/GroupBox — 자식 배치 가능)</summary>
|
||||
public bool IsContainer { get; init; }
|
||||
|
||||
/// <summary>배치 시 데이터 필드를 만드는 입력 컨트롤인지</summary>
|
||||
public bool CreatesField { get; init; }
|
||||
|
||||
/// <summary>필드 기본 데이터 타입</summary>
|
||||
public string DefaultDataType { get; init; } = "string";
|
||||
|
||||
/// <summary>인스펙터 속성 편집 스키마(타입 전용 — 공통 X/Y/W/H/Id/폰트는 인스펙터가 별도 제공)</summary>
|
||||
public IReadOnlyList<PropertyDef> Properties { get; init; } = Array.Empty<PropertyDef>();
|
||||
}
|
||||
|
||||
/// <summary>속성 편집기 종류</summary>
|
||||
public enum PropEditorKind
|
||||
{
|
||||
/// <summary>문자열</summary>
|
||||
Text,
|
||||
/// <summary>여러 줄 문자열</summary>
|
||||
MultilineText,
|
||||
/// <summary>숫자</summary>
|
||||
Number,
|
||||
/// <summary>참/거짓</summary>
|
||||
Toggle,
|
||||
/// <summary>선택지</summary>
|
||||
Choice,
|
||||
/// <summary>색(레거시 invariant 문자열)</summary>
|
||||
Color,
|
||||
/// <summary>문자열 목록(콤보 items 등 — 줄바꿈 구분 편집)</summary>
|
||||
StringList,
|
||||
/// <summary>데이터 태그 피커(bzDataInterface 메서드 — 자동 채움 원천)</summary>
|
||||
DataInterfaceTag,
|
||||
/// <summary>액션 태그 피커(EN_DataActionTyp — 더블클릭/버튼 액션)</summary>
|
||||
DataActionTag,
|
||||
/// <summary>SQL 쿼리 — 전용 편집기 창(치환 변수 삽입 지원)</summary>
|
||||
SqlQuery,
|
||||
}
|
||||
|
||||
/// <summary>인스펙터 속성 정의 1건 — PropBag 의 레거시 Property 를 편집</summary>
|
||||
public sealed class PropertyDef
|
||||
{
|
||||
/// <summary>PropBag 키(레거시 Property 이름)</summary>
|
||||
public string Key { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>표시 라벨(한글)</summary>
|
||||
public string Label { get; init; } = string.Empty;
|
||||
|
||||
/// <summary>편집기 종류</summary>
|
||||
public PropEditorKind Editor { get; init; }
|
||||
|
||||
/// <summary>Choice 편집기의 선택지</summary>
|
||||
public string[]? Choices { get; init; }
|
||||
}
|
||||
Reference in New Issue
Block a user