레이어 패널을 [200]SheetMe 아웃라인으로 교체 — 페이지 노드·선택 밴드·드래그 재정렬
[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>
This commit is contained in:
co-authored by
Claude Opus 5
parent
a30421f9b5
commit
76584e5004
@@ -93,6 +93,35 @@ public sealed class TypeToIconConverter : IValueConverter
|
||||
=> throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <c>"아이콘명|크기|브러시키"</c> 한 문자열 → Lucide 아이콘 비주얼.
|
||||
///
|
||||
/// 색이 <b>행 상태에 따라 달라져야</b> 할 때 쓴다. 보통은 색을 ConverterParameter 에 적지만
|
||||
/// ConverterParameter 는 바인딩할 수 없어서, 색이 변하는 순간 아이콘이 이전 색에 굳어 버린다
|
||||
/// (선택 밴드 위에서 파란 아이콘이 사라지는 식). 그래서 사양 전체를 값 쪽으로 옮겼다.
|
||||
/// </summary>
|
||||
public sealed class IconSpecConverter : IValueConverter
|
||||
{
|
||||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
{
|
||||
if (value is not string spec)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
var first = spec.IndexOf('|');
|
||||
if (first < 0)
|
||||
{
|
||||
return LucideIcons.Icon(spec, 14, "B.Muted");
|
||||
}
|
||||
var name = spec[..first];
|
||||
var (size, brushKey) = IconParam.Parse(spec[(first + 1)..], 14);
|
||||
return LucideIcons.Icon(name, size, brushKey);
|
||||
}
|
||||
|
||||
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||
=> throw new NotSupportedException();
|
||||
}
|
||||
|
||||
/// <summary>팔레트 타입명 → 카테고리명 컨버터(CollectionViewSource 그룹핑용)</summary>
|
||||
public sealed class TypeToCategoryConverter : IValueConverter
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user