Commit Graph
3 Commits
Author SHA1 Message Date
MsystechandClaude Opus 5 a30421f9b5 레이어 패널에 [200]SheetMe 그룹 기능 이식 — 폴더 행·계층·타입 필터·다중선택
[200] 의 그룹도 컨테이너가 아니라 GroupId 태그 + 이름 사전이었다. SheetMe 가 이미
같은 구조(ControlElement.GroupId, JsonIgnore)를 갖고 있어 저장 포맷은 그대로 두고
표시·조작 계층만 얹는다 — 왕복 XML 에는 아무 흔적도 남지 않는다.

레이어 목록을 평탄화 결과(LayerRows)로 바꿨다. 그룹 폴더 행과 컨트롤 행이 한
시퀀스로 섞이고, 계층은 들여쓰기 여백으로만 표현한다(TreeView 를 쓰면 가상화와
기존 행 템플릿을 다 버려야 한다 — 인스펙터 섹션이 쓰는 방식과 같게 맞췄다).

새로 되는 것
- 그룹 폴더 행: 접기/펼치기, 멤버 수, 이름 인라인 편집(더블클릭), 그룹 전체 눈·자물쇠
- 그룹 이름 — FormDocument.GroupNames(편집 전용). 비우면 기본 그룹 으로 복귀
- 컨테이너(패널/그룹박스) 자식이 레이어에 보인다. 지금까지는 아예 접근할 수 없었다
- 목록 다중선택(Shift/Ctrl) — 캔버스 선택과 양방향 동기
- 타입 필터: 그 페이지에 실제로 있는 타입만 후보로 띄운다
- 검색 0건·빈 페이지 안내 문구

함께 고친 결함
- 붙여넣기가 원본 그룹에 끼어들었다(Clone 이 GroupId 를 그대로 복사) → 복제본끼리 새 그룹
- 그룹 해제가 선택된 멤버만 풀어 1개짜리 반쪽 그룹이 남았다 → 그룹 전 멤버를 푼다
- 멤버가 1개 이하로 줄어든 그룹이 계속 남았다 → CleanupGroups 자가치유
- 셰브론이 늘 눌린 것처럼 보였다(IsChecked 채움) → MiniChevron 스타일 분리

--edit-smoke 에 레이어 검사 19건 추가(그룹 위생·평탄화·필터·XML 무영향).
회귀: 테스트 124/124, edit-smoke 실패 0, db-smoke 1,271건 diff 0/예외 0,
종이 렌더 P062 바이트 동일.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 15:43:37 +09:00
MsystechandClaude Opus 5 e18ad87100 피그마식 속성 조작 — Enter 확정·화살표 증감·정렬 격자
사용자 지적: "피그마같은 도구처럼 보기 편하게, 특히 속성 사용하기 불편해".
불편의 핵심은 밀도가 아니라 **조작**이었다. 모든 칸이 UpdateSourceTrigger=LostFocus 하나라
값을 고치고 나서 **다른 곳을 눌러야** 반영됐다 — 캔버스를 보며 숫자를 맞춰 가는 작업이
성립하지 않는다.

[Enter 확정] 즉시 커밋하고 결과를 전체 선택한다(확정 신호이자 곧바로 덮어 칠 수 있는 상태).
여러 줄 입력은 Enter 가 줄바꿈이어야 하므로 AcceptsReturn 으로 코드에서 가른다 — 스타일 예외로
빼면 새 여러 줄 칸이 생길 때마다 잊는다.

[Esc 되돌리기] **편집 전 값을 따로 보관하지 않는다.** LostFocus 트리거라 소스는 아직 손대지 않은
상태이고 소스가 곧 백업이다 — UpdateTarget() 으로 화면만 다시 읽는다.
(초안은 포커스 시점 문자열을 기억했는데, 그러면 칸에 포커스를 둔 채 캔버스에서 컨트롤을 끌었을 때
Esc 가 낡은 값을 되살리고 LostFocus 가 그걸 커밋해 **컨트롤이 원위치로 돌아간다**. 검증에서 잡았다.)

[↑/↓ 증감] 1씩, Shift 10씩. 증분은 칸마다 지정한다 — **Ctrl 미세조정은 기본 끔**이다.
X/Y/너비/높이는 읽기·쓰기 양쪽에서 반올림하므로 0.1 을 더해도 모델은 그대로인데 문자열만 바뀌어,
화면은 그대로면서 Undo 스냅샷과 '수정됨' 표시만 남는다. 소수를 실제로 받는 글꼴 크기에서만 켠다.
그리고 **글꼴 크기는 NumberRow 가 아니라 TextRow 였다** — 정작 가장 미세조정하고 싶은 칸이 스핀
대상에서 빠져 있었다. NumberRow 로 승격했다.

[Undo 폭주 차단] 커밋 1회 = 문서 전체 딥클론 1회다. ↑ 를 스무 번 누르면 스냅샷 스무 개가 쌓여
용량(100)을 갉아먹고, 저장 지점이 밀려나면 영구 '수정됨'이 된다. 행에 CoalesceUndo 플래그를 두고
경계·크기 행만 기존 SnapshotForNudge(400ms 코얼레스)로 보낸다. 값이 아니라 **커밋 방식만** 바꾸므로
Initialize/Commit 규약은 그대로다.

[정렬 격자] 콤보에 "MiddleCenter" 같은 레거시 원문 열거값이 그대로 떴다. 무슨 뜻인지 알려면 아홉 개를
다 열어 봐야 하고 고르고 나서도 글자로만 확인된다. 3열 격자로 바꿔 9값은 3×3 방향 화살표,
3값은 1×3 정렬 아이콘으로 접힌다(같은 템플릿이 값 개수에 따라 알아서).
**ToggleButton 이 아니라 Button 을 쓴다** — 토글이면 켜진 칸을 다시 눌러 해제되고, 그때 값이 빈
문자열이 되어 Set 이 속성을 **삭제**한다. ControlRegistry 주석이 경고하는 '선택만으로 속성이
사라지는' 사고(운영 249건)와 같은 계열이다.

[바꾸지 않은 것] UpdateSourceTrigger 는 그대로 둔다. PropertyChanged 로 바꾸면 한 글자마다 딥클론이
쌓이고, 이름 행은 글자마다 RenameControl 이 돌며, 경계 행은 커밋 결과가 정규화 값으로 되쓰여 캐럿이
튄다. 피그마식 사용감은 트리거가 아니라 명시적 확정 제스처로 얻는다.

[다음 후보 — 이번엔 넣지 않았다] 라벨을 끌어서 값을 바꾸는 스크럽은 UndoService 에
BeginBatch/EndBatch 를 넣어야 안전하다(지금 구조면 드래그 프레임마다 스냅샷 1개). 캡처 해제 처리도
이 저장소에 사고 선례가 있어 별도 작업으로 남긴다.

검증: 테스트 124/124, edit-smoke 실패 0, 왕복 1,271건 diff 0/예외 0, 종이 렌더 P062 픽셀 차이 0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-12 14:35:16 +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