컨트롤 행의 눈·자물쇠는 호버 규칙으로 바꿔 놓고 페이지 행 버튼만 상시 노출이라
목록 우측이 들쭉날쭉했다. 같은 규칙으로 맞춘다.
버튼 각각이 아니라 묶음(StackPanel)에 거는 이유가 있다 — 삭제 버튼은 CanDelete 에
Visibility 를 물려 있는데 인스턴스의 지역 값이 스타일 트리거를 이기므로, 버튼마다 걸면
삭제만 상시 노출된다. 바깥을 접으면 둘 다 숨고, 펴지면 삭제는 원래대로 CanDelete 를 따른다.
되돌리기가 번거로운 '페이지 삭제'가 항상 노출돼 있지 않게 되는 부수 효과도 있다.
회귀: 테스트 124/124, 편집 스모크 실패 0, DB 왕복 1,271건 diff 0/예외 0,
종이 렌더 P062 바이트 동일.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
이름이 잘려 행을 구분할 수 없었다
눈·자물쇠가 48px 를 상시 차지해 이름 칸이 한글 11자로 줄었다. 운영 서식에는
'입원일 복용약-전립선약' 처럼 앞이 같고 끝에서 갈리는 이름이 흔해 전부
'입원일 복용약-…' 로 잘렸다 — 목록만 보고는 어느 행인지 알 수 없었다.
두 토글을 평소엔 숨기고 마우스를 올린 행에서만 띄운다. 잠김·숨김이 켜진 행에서는
계속 띄운다(거기서까지 숨기면 마우스를 올리기 전에는 상태를 알 방법이 없다).
[200] 은 항상 띄우지만 여기서만 갈라선다 — 폭이 곧 가독성이라서.
라이트 모드 선택 밴드가 너무 무거웠다
양 테마 모두 짙은 파랑(#0F6FBF)에 흰 글자를 쓰다 보니, 흰 배경에 짙은 슬라브가
얹혀 선택 몇 줄이 패널 전체를 짓눌렀다. 라이트만 방향을 뒤집는다 —
연한 채움(#A8D3F7, 흰 패널 대비 1.58:1) + 진한 글자(10.1:1).
서브트리도 한 단계 옅게(#DCEBFB) 해서 '폴더가 주인, 멤버는 딸림'이 색 세기로 읽힌다.
밴드 위 글자색을 B.OnAccent(흰색 고정)에서 신설 토큰 B.OnLayerSel 로 바꿔
테마별로 갈라지게 했다(다크 흰색 / 라이트 #222222). 보조 텍스트도 라이트만
#35536C 로(연한 채움 위 5.12:1 — 기존 #E6F1FB 는 라이트에서 사라진다).
회귀: 테스트 124/124, 편집 스모크 실패 0(레이어 검사 45건), DB 왕복 1,271건
diff 0/예외 0, 종이 렌더 P062 바이트 동일.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
1) 목록에서 단축키가 안 먹었다
CanvasKeyboardBehavior 는 캔버스에 붙어 있어 포커스가 레이어 목록에 있으면 이벤트가
거기까지 가지 않는다. 여러 행을 골라 놓고 Ctrl+G 를 눌러도 아무 일이 없던 이유다.
목록에 KeyDown 을 달아 그룹·삭제·복사·되돌리기를 처리한다. 방향키·Home/End·문자 입력은
넘기지 않는다(목록 자체의 이동과 형식 검색이 우선). 이름 편집 중에는 통과시킨다.
2) 세로 스크롤바가 오른쪽이 잘려 보였다 — 앱 전체 공통 결함
Thumb 스타일의 MinWidth/MinHeight 24 가 폭 9 짜리 막대 안에서 썸을 24 폭으로 강제해
오른쪽이 통째로 잘렸다(둥근 모서리가 사라지고 수직으로 싹둑 잘린 막대). 가로 막대는
아래쪽이 같은 식으로 잘렸다. 최소 '길이'는 MinThumbTrack.MinThumbLength=44 가 이미
보장하므로 최소 '두께'는 지운다.
화살표 글리프도 7 단위 + 스트로크 1.4 = 8.4 라 폭 9 에서 캡이 경계에 닿아 오른팔이
잘렸다 — 막대 폭을 11 로 올려 양옆 여유를 준다.
3) 검색칩 안에 상자가 하나 더 그려졌다
전역 TextBox 템플릿은 BorderThickness=1 이 하드코딩돼 있어 인스턴스에서 0 을 줘도
무시된다. 칩 전용 ChipTextBox 스타일(테두리 없는 템플릿)을 만들고, 포커스 표시는
칩 쪽 IsKeyboardFocusWithin 으로 옮겼다.
회귀: 테스트 124/124, 편집 스모크 실패 0, DB 왕복 1,271건 diff 0/예외 0,
종이 렌더 P062 바이트 동일.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
[200] 의 패널은 코드로 Border 를 쌓는 비가상화 렌더고 SheetMe 는 가상화 ListBox 다.
골격은 SheetMe 것을 지키고 겉모습과 조작 표면만 옮겼다 — 통째로 베끼면 1,067 컨트롤
서식에서 검색어 한 글자마다 수천 비주얼을 다시 만들게 되고, [200] 에 대응물이 없는
컨테이너 자식 재귀 표시가 사라진다.
구조
- 페이지를 별도 섹션이 아니라 아웃라인의 최상위 노드로. 접기·복제·삭제·컨트롤 수·현재 강조
- 맨 아래 '+ 페이지 추가' 행
- 목록 순서를 뒤집었다 — 이제 맨 위가 z-order 최상위(캔버스에서 위에 겹쳐 보이는 것이 목록 위)
- 들여쓰기 12 / 32 / +16
- 레이어 패널을 LayerPanelView 로 분리(MainView.xaml 이 1,000줄을 넘겼고, 진단 렌더러가
이 패널만 따로 찍어 라이트·다크·선택 상태를 검사할 수 있어야 한다)
선택 표시
- IsSelected 가 아니라 Highlight 3상태(None/Blue/Navy)가 배경을 그린다. 그룹 전원 선택 시
폴더는 파랑, 멤버는 서브트리 배경이 되고 맞닿는 모서리를 각지게 해 하나의 블록으로 이어진다
- 밴드 위에서는 아이콘·보조 텍스트 색도 함께 뒤집는다. 안 그러면 눈·자물쇠가 1.6:1 로 묻혀
선택한 행에서만 잠금 상태가 안 보이는 상태가 된다
- 신설 토큰 3종(B.LayerSel / B.LayerSubtree / B.OnSelMuted) — [200] 원본값은 각각
흰 글자 3.00:1, 다크 밴드 1.03:1, 라이트 밴드 1.14:1 로 이 저장소가 이미 기각한 값이다
기능
- 드래그로 z-order 재정렬(삽입선 어도너). 임의 index 이동 연산 MoveWithinParent 신설
- 페이지 복제 — 컨트롤 이름을 전부 새로 발급하고 그룹도 복제본끼리 다시 묶는다
([200] 은 GroupId 를 그대로 둬서 복제 그룹이 원본과 gid 를 공유한다)
- 페이지 헤더 클릭 → 캔버스가 그 페이지로 이동(ScrollToPage)
- 데이터 배선 배지 — 값이 조회·데이터소스에서 오는 컨트롤 표시
- 검색칩에 테두리(라이트에서 B.Input=B.Panel 이라 경계 대비가 1.00:1 이었다)
이식하지 않은 것: 컨트롤 행 인라인 개명. [200] 이 고치는 값은 표시 전용 별칭이지만
SheetMe 의 컨트롤 이름은 외부 참조 키라 목록에서 무심코 고치면 배선이 끊긴다.
더블클릭은 요청대로 캔버스 이동을 유지하고, 그룹 행에서만 이름 편집으로 간다.
동반 수정: 눈·자물쇠 토글에 되돌리기 지점 추가(400ms 코얼레스), 그룹 이름 비우기 경로가
스냅숏 없이 지워지던 것, 숨김 흐리기를 행 전체가 아니라 이름 줄에만.
편집 스모크의 레이어 검사 19 → 42건. 회귀: 테스트 124/124, 편집 스모크 실패 0,
DB 왕복 1,271건 diff 0/예외 0, 종이 렌더 P062 바이트 동일.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>