Commit Graph
4 Commits
Author SHA1 Message Date
MsystechandClaude Opus 5 9d20cc2971 [200] 디자인 동일화 2/2 — 좌측 패널·타이틀바·인스펙터 정보 밀도
1/2 가 껍데기(스크롤바·창 기본값)를 맞췄다면 이번은 그 안에 든 정보다. [200] 과의 실제 격차는
장식이 아니라 "한 화면에서 얼마나 읽히는가"였고, 그중 둘은 데이터 손상 경로이기도 했다.

[레이어] 행 라벨을 Model.Id → 신규 LayerName(Text 우선, 없으면 Id)으로. 운영 서식의 Id 는
대부분 Label12 꼴 자동 이름이라 291개짜리 목록이 아무것도 알려주지 않았다. Id 는 외부 참조
키이므로(DataTableField 대상명, EventHandlerMappingTag 의 ShtCod_컨트롤명 규약) 버리지 않고
툴팁 + 검색 대상으로 유지한다. 앞에 타입 아이콘(Accent), 뒤 숨김/잠금을 MiniToggle(eye/eye-off,
lock/unlock)로 — 사각 체크박스로는 상태가 안 읽혔다.
검색칩 신설(LayerFilter, 이름·Id 부분일치). 컨트롤 최대 1,067개 서식에서 스크롤만으로는 대상을
찾을 수 없다. 칩 안 TextBox 에 MinHeight=0 필수 — 전역 TextBox MinHeight 30 이 32px 칩에서
글자를 자른다.

[인스펙터·여러 값] IsMixed 가 설정만 되고 화면 어디에도 바인딩돼 있지 않았다. 다중선택에서 값이
갈리면 편집기가 빈 칸이 되는데 그 빈 칸은 "값 없음"과 구별되지 않는다. 무심코 입력하면 서로
달랐던 값이 전부 한 값으로 덮인다. 편집기 위에 비파괴 오버레이("여러 값")를 얹고, 포커스가
들어오면 감춘다 — 값은 LostFocus 에만 올라가므로 타이핑 중 ValueText 는 계속 "" 이고 안내가
방금 친 글자 위에 남는다.
토글 행은 IsOn 을 bool? 로 바꿔 3상태로. false 로 내리면 "전부 꺼짐"으로 보이고, 사용자가 한 번
켰다 끄면 전부 False 가 되어 조용히 뭉개진다.

[인스펙터·접이식] 섹션 헤더를 클릭 가능한 접기/펴기로(셰브런 + 소속 행 수). 고급 속성까지 켜면
수십 행이 된다. Rows 는 평면 컬렉션을 유지하고 섹션이 자기 행을 들고 있다가 컨테이너
Visibility 만 토글한다 — 행 VM 을 재생성하지 않아 편집 중 값·포커스가 보존되고, 다중선택
재구성이 잦은 이 화면에서 트리 재구축 비용도 피한다.

[타이틀바] 로고 메뉴 루트(셰브런) 아래로 5개 메뉴를 흡수하고, 편집 아이콘 스트립(실행취소·다시
실행 | 복사·삭제·그룹·해제)과 우측 액션(테마·저장·미리보기)을 배치. 중앙 제목은 뺐다 — 문서 탭이
같은 정보를 이미 들고 있다.

[빈 상태] 문서 0개 → 회색 허공 대신 다음 행동 3개(새 서식 / DB에서 열기 / 파일 열기).
선택 0개 → 인스펙터에 "선택 없음" 한 줄만 떠 패널이 고장 난 것처럼 보이던 것을 안내로 교체.

[그 외] 서식 목록에 하단 상태 한 줄(로딩·건수·DB 미접속) — 종전에는 목록 위에 "불러오는 중"
오버레이가 덮여 목록이 가려졌고 건수는 창 하단 전역 상태줄에만 있었다. 활성 문서 탭 아이콘을
Accent 로. 플로팅 바의 ±버튼 제거([200] 동일 — Ctrl+휠이 주 조작이고 배율 버튼이 플라이아웃을
겸한다), 대신 "화면 맞춤" 추가. ZoomFit 은 문서 전체가 아니라 활성 페이지 한 장 기준이다
(7페이지 서식을 통째로 맞추면 14% 가 되어 아무것도 안 보인다). 뷰포트 크기는 캔버스 뷰가
SizeChanged 에서 VM 에 통지 — VM 이 시각 트리를 몰라도 되게 한다.
열 기본 폭 232→248 / 280→300.

검증: 테스트 124/124, edit-smoke 실패 0, 왕복 1,271건 diff 0/예외 0.
**종이 렌더 P062 픽셀 대조 차이 0**(4,802바이트 전부 일치).
실 UI 확인: P062 레이어 행·인스펙터 접기, P093 291컨트롤에서 레이어 검색("알러지" → 10건),
116개 선택 시 X/Y/너비/높이 "여러 값" 표시.

남은 배치: E(선택 오버레이) · F(캔버스 크롬 — 종이에 닿는 유일한 배치) · G(토스트·ThemedDialog).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 10:33:48 +09:00
MsystechandClaude Fable 5 68f0fbd5a3 마스크 편집기 — 프리셋 목록 + 실시간 미리보기
레거시 MaskedTextBox 는 System.Windows.Forms.MaskedTextBox 를 상속하고 Mask 를 재정의하지 않아
WinForms 기본 마스크 디자이너(프리셋 목록 + 시험 입력)를 그대로 물려받는다. SheetMe 인스펙터는
평범한 텍스트 상자뿐이라 마스크 문법을 외워야 했다.

[프리셋] LegacyMaskCatalog — .NET 문화권 기본값(짧은 날짜/전화번호 등) 대신 운영 활성 디자인
전수 census 에서 실제로 쓰이는 마스크를 사용 건수와 함께 제공한다. 기존 서식과 같은 표기를
그대로 고를 수 있어 표기 흔들림이 줄어든다. 날짜/시간/날짜+시간/번호 그룹 + 표준 3종.

[미리보기] 두 줄로 보여준다.
  빈 값 표시 — 마스크만으로 화면에 어떻게 보이는지(ToPromptDisplay)
  시험 입력 — 값을 쳐 보면 어떻게 채워지는지(Apply, 신규)
인스펙터 행에도 '빈 값 표시'를 상시 노출해 편집기를 열지 않아도 확인된다.

[Apply 규칙] 구현 중 모호한 경우가 드러나 규칙을 단순하게 확정했다.
  1) 리터럴은 항상 그대로 출력되고 입력을 소비하지 않는다.
  2) 지시자는 입력에서 자기에게 맞는 첫 문자를 가져오며, 맞지 않는 문자와 공백은 건너뛴다.
값만 치든(20260812) 구분자를 같이 치든(2026-08-12, 2026년 08월 12일) 결과가 같아진다.
공백을 건너뛰는 이유는 '9' 가 공백도 받아들이기 때문이다 — 그대로 두면 구분자 공백이 데이터
자리를 먹어 한 칸씩 밀린다. '9' 의 공백 허용은 빈 자리를 위한 것이고 그건 프롬프트 문자가 이미
표현한다.
한계를 코드에 명시했다: 리터럴이 숫자인 마스크(2\000년 — 운영 460건 중 1건)는 사용자가
리터럴까지 치면 어디까지가 데이터인지 원리적으로 가릴 수 없다. 편집 가능한 자리만 치면 된다.
미리보기용이므로 휴리스틱을 쌓기보다 규칙을 단순하게 두는 편이 낫다고 판단했다.

안내문에서 백슬래시를 글리프로 보여주지 않는다 — 한글 글꼴에서 원화 기호로 렌더되어 오해를 부른다.

검증: 테스트 124/124(마스크 26건 추가 — Apply 자리 채움/구분자 무시/유효성 거부/대소문자 변환자/
이스케이프/공백 처리, 프리셋 형식·중복·운영 다빈도 포함 검사). edit-smoke 실패 0,
왕복 1,271건 diff 0/예외 0. 실제 UI 로 대화상자 열어 프리셋 그룹·건수·두 줄 미리보기 확인.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-12 09:38:05 +09:00
MsystechandClaude Fable 5 c445b851a1 인스펙터 기본값 도입 + Choice 콤보의 속성 삭제 버그 수정
[값 삭제 버그] InspectorView 의 ComboBox SelectedItem 은 TwoWay 기본이라, 저장된 값이
Choices 에 없으면 null 로 코어스한 뒤 그 null 을 소스에 되써서 속성을 삭제했다.
Label TextAlign Choices 에 Bottom* 3값이 빠져 있어, 해당 라벨을 선택하는 것만으로
발동했다(운영 활성 디자인 1,305건 census: BottomCenter 126 / BottomLeft 107 / BottomRight 16).
- ContentAlignment 9값 전체로 보정
- ChoiceRowViewModel.EnsureChoice — 목록 밖 값을 표시 전에 편입(사이트 커스텀 값 방어)

[기본값] PropertyDef.Default 추가. RowBinding.Get 한 곳에서만 주입하므로
Initialize(building=true) 경로를 타 Commit 이 발생하지 않는다 — 사용자가 건드리기 전까지
PropBag 에 아무것도 쓰이지 않아 왕복 무손실이 유지된다. 다중 선택 병합도 자동으로 옳아진다.
지정 대상(레거시 필드 초기값/WinForms DefaultValueAttribute 근거):
  TextBox.RwdRsvWrdYon=True (TextBox.vb:63, 2022-09-28 추가라 이전 서식엔 키 없음)
  DataTable.ExcuteQuery=True (MDataTable.vb:15)
  Label.TextAlign=TopLeft / TextBox.TextAlign=Left / TextBox.BorderStyle=Fixed3D
  Panel.BorderStyle=None / PictureBox.SizeMode=Normal / DateTimePicker.Format=Long
이게 없으면 기본 True 속성이 항상 '꺼짐'으로 보이고, 사용자가 껐다 켜는 순간
명시 False 가 기록돼 상용구 입력·데이터소스 자동 실행이 실제로 죽는다.

ControlRegistryTests 신설 — Default⊆Choices, Toggle 기본값 표기, 그리고 운영 실사용
열거값이 Choices 에 전부 포함되는지(census 근거) 검사.

검증: 테스트 59/59, edit-smoke 실패 0, 전수 왕복 1,271건 diff 0/예외 0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-11 17:30:28 +09:00
MsystechandClaude Fable 5 16c07f48dc 초기 커밋: 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>
2026-08-11 17:20:22 +09:00