열리는 창들의 결을 통일한다 — 타이틀바와 강조 버튼
## 창 열둘 중 하나만 우리 옷을 입고 있었다 커스텀 크롬을 가진 것은 메인 셸과 MessageDialogView 둘뿐이었고, 나머지 열한 창(서식 이력·데이터소스 배선·글꼴 관리자·태그 선택·쿼리 편집기·마스크· 환자 선택·데이터소스 결과·레이어 필터·서식 등록·미리보기)은 <b>윈도우 기본 타이틀바</b>를 달고 떴다. 다크 테마에서 어두운 앱 위에 OS 바가 얹히고, 높이·글자·모서리·닫기 버튼 모양이 전부 달라 "다른 프로그램이 열렸다"로 보였다. 열한 창이 이미 전부 ThemedWindow 를 걸고 있었으므로, 그 옆에 템플릿을 가진 ThemedDialogWindow 를 만들고 각 창은 <b>스타일 이름 한 줄</b>만 바꿨다. 창마다 타이틀바 markup 을 복사했다면 다음에 또 갈라진다. ## WindowChrome 은 스타일로 줄 수 없었다 두 번 막혔고 둘 다 같은 뿌리다 — WindowChrome 은 Freezable 인데 창에 붙으면서 스스로 속성을 고친다. Setter.Value 에 두면 열한 창이 <b>한 인스턴스를 나눠 쓰다</b> 두 번째 창부터 "읽기 전용 상태라 속성을 설정할 수 없습니다"로 죽었다. x:Shared="False" 로도 안 됐다 — 공유되는 것은 리소스가 아니라 Setter 가 이미 붙든 값이다. 그래서 ctl:DialogChrome 첨부 속성이 창마다 새 인스턴스를 만들어 붙인다. 템플릿 안 닫기 버튼은 Click 핸들러를 가질 수 없으므로(템플릿에 코드비하인드가 없다) 표준 SystemCommands.CloseWindowCommand 를 쓰고 그 CommandBinding 도 여기서 단다. DialogResult 를 건드리지 않으므로 ShowDialog 는 false 를 돌려주고 호출부의 '취소' 경로가 그대로 탄다. 최대화 보정도 같이 건다. WindowStyle=None 인 창은 최대화하는 순간 작업표시줄을 덮는데 (메인 창에서 겪은 결함이다) 대화상자 열 개가 크기 조절 가능이라 타이틀바 더블클릭으로 그 상태에 들어갈 수 있다. ## 진단이 바로 그 부분에 눈이 없었다 --dialog-shots 는 window.Content 만 찍고 있었다. 그래서 이 결함을 <b>한 번도 보여 준 적이 없다</b> — MessageDialogView 만 타이틀바가 사진에 나왔는데, 그건 그 창의 바가 Content 안에 있어서였다. 창 전체를 찍도록 바꿨다(템플릿의 PART_Root). 고칠 대상이 사진에 안 나오는 진단은 있으나 마나였고, 실제로 이번에도 첫 캡처가 "고쳤는데 그대로"로 보여 한 번 헛짚게 만들었다. ## 강조 버튼 — 규칙은 이미 있었다 Primary 스타일을 열한 창 중 넷만 쓰고 있었다. 그런데 IsDefault="True" 는 대부분의 창이 이미 주 동작에 달아 두었다 — 규칙을 새로 만들 필요가 없었다. <b>기본 버튼 = 강조</b>로 맞춘다(서식 이력·서식 등록·마스크·레이어 필터·데이터소스 결과·환자 선택). 글꼴 관리자만 예외로 손으로 골랐다. IsDefault 가 없고 버튼이 셋인데, 강조는 <b>고른 것만</b> 바꾸는 '선택 조합에 적용'에 준다. '전체에 적용'은 문서 전체를 한 번에 바꾸므로 눈이 먼저 가는 자리에 두지 않았다 — 되돌리기가 있어도 되돌릴 생각을 하려면 먼저 알아채야 한다. 환자 선택의 '선택'에는 Primary 만 주고 IsDefault 는 건드리지 않았다 — 검색칸에서 Enter 는 '찾기'여야 한다. ## 판정 - 단위 시험 388 · edit-smoke 376건 전건 통과 - --dialog-shots 69장 전건 통과(창 전체 캡처로 바뀐 뒤에도) - --modal-check · --maxrect · --scale-budget 전건 통과 - --db-render P062 md5 8d683835f5d81e7bb41c79071d6bf954 불변 ## 남은 것 내용 여백은 아직 창마다 다르다 — 설명 문장이 창 위쪽 가장자리에 바짝 붙는 창이 여럿이다. 타이틀바가 생겨 덜 도드라지지만 통일된 것은 아니다. 별도로 잡을 것. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
020595f8d4
commit
12e5ec6452
@@ -1404,4 +1404,68 @@
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<!-- ============================================================
|
||||
대화상자 크롬 — 앱 셸·알림창과 같은 타이틀바를 <b>모든</b> 창에 준다.
|
||||
|
||||
<b>왜 필요했나.</b> 커스텀 크롬을 가진 창은 메인 셸과 MessageDialogView 둘뿐이었고,
|
||||
나머지 열한 창(서식 이력·데이터소스 배선·글꼴 관리자·태그 선택·쿼리 편집기·환자 선택 …)은
|
||||
윈도우 <b>기본</b> 타이틀바를 달고 떴다. 다크 테마에서 어두운 앱 위에 OS 바가 얹히고,
|
||||
모서리·높이·글자 크기·닫기 버튼 모양이 전부 달라 "다른 프로그램이 열렸다"로 보였다.
|
||||
|
||||
<b>왜 스타일 하나로 하나.</b> 열한 창은 이미 전부 ThemedWindow 를 걸고 있었다 —
|
||||
템플릿을 여기 한 번 두면 각 창은 스타일 이름 한 줄만 바꾸면 된다.
|
||||
창마다 타이틀바 markup 을 복사하면 다음에 또 갈라진다.
|
||||
|
||||
AllowsTransparency 는 켜지 않는다: 레이어드 윈도우가 되면 ClearType 이 꺼져
|
||||
13px 한글이 뭉개지고 진단이 찍는 PNG 배경이 알파가 된다.
|
||||
닫기 버튼의 명령 배선과 최대화 보정은 ctl:DialogChrome 이 붙여 준다.
|
||||
============================================================ -->
|
||||
<Style x:Key="ThemedDialogWindow" TargetType="Window" BasedOn="{StaticResource ThemedWindow}">
|
||||
<Setter Property="WindowStyle" Value="None" />
|
||||
<Setter Property="Background" Value="{DynamicResource B.Surface}" />
|
||||
<!--
|
||||
WindowChrome 은 여기서 못 준다. Freezable 인 데다 창에 붙는 순간 스스로 속성을 고치는데,
|
||||
Style 의 Setter.Value 는 <b>한 번 평가돼 공유</b>되므로 두 번째 창부터
|
||||
"읽기 전용 상태라 속성을 설정할 수 없습니다"로 죽는다(x:Shared="False" 로도 안 된다 —
|
||||
공유되는 것은 리소스가 아니라 Setter 가 이미 붙든 값이다).
|
||||
그래서 ctl:DialogChrome 이 <b>창마다 새 인스턴스</b>를 만들어 붙인다.
|
||||
-->
|
||||
<Setter Property="ctl:DialogChrome.Enabled" Value="True" />
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Window">
|
||||
<!-- PART_Root — 진단(dialog-shots)이 창 전체를 찍을 때 잡는 이름.
|
||||
이 이름이 없으면 Content 만 찍혀 타이틀바가 사진에서 빠진다. -->
|
||||
<Border x:Name="PART_Root"
|
||||
BorderBrush="{DynamicResource B.Line2}" BorderThickness="1"
|
||||
Background="{DynamicResource B.Surface}">
|
||||
<DockPanel>
|
||||
<!-- 타이틀바 — 드래그는 WindowChrome 의 CaptionHeight 가 처리한다 -->
|
||||
<Border DockPanel.Dock="Top" Height="36" Background="{DynamicResource B.Titlebar}"
|
||||
BorderBrush="{DynamicResource B.Line}" BorderThickness="0,0,0,1">
|
||||
<Grid>
|
||||
<TextBlock Text="{TemplateBinding Title}" Margin="14,0,52,0"
|
||||
VerticalAlignment="Center" FontSize="12"
|
||||
Foreground="{DynamicResource B.Muted}"
|
||||
TextTrimming="CharacterEllipsis" />
|
||||
<!-- IsHitTestVisibleInChrome 필수 — 빠지면 클릭이 창 드래그로 먹혀 닫을 수 없다 -->
|
||||
<Button Style="{StaticResource CloseBtn}" Height="36"
|
||||
HorizontalAlignment="Right" IsTabStop="False" ToolTip="닫기"
|
||||
Command="{x:Static SystemCommands.CloseWindowCommand}"
|
||||
shell:WindowChrome.IsHitTestVisibleInChrome="True">
|
||||
<TextBlock Text="" FontFamily="Segoe MDL2 Assets" FontSize="10" />
|
||||
</Button>
|
||||
</Grid>
|
||||
</Border>
|
||||
<!-- AdornerDecorator 가 있어야 검증 오류 표시·툴팁 어도너가 정상 동작한다 -->
|
||||
<AdornerDecorator>
|
||||
<ContentPresenter />
|
||||
</AdornerDecorator>
|
||||
</DockPanel>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
</ResourceDictionary>
|
||||
|
||||
Reference in New Issue
Block a user