레이어 검색을 접어 두고 머리로 올린다

검색칩이 항상 한 줄을 먹고 있었다. 컨트롤이 몇 개뿐인 서식이 대부분이라 그 줄은 대개 빈 상자다.
돋보기·필터·필터해제를 '레이어' 글씨 오른쪽으로 올리고, 검색바는 돋보기를 눌러야 나오게 했다.

돋보기를 끌 때 검색어를 지운다. 상자가 접힌 채 필터만 살아 있으면 목록이 통째로 비어 보이는데
원인을 찾을 단서가 화면에 하나도 없다 — 열어 봐야 비로소 "아, 검색어가 남아 있었구나"가 된다.

켤 때는 한 틱 뒤에 포커스를 준다. 상자가 실제로 보이게 된 다음이어야 캐럿이 들어간다
(그룹 이름 편집 상자가 같은 이유로 같은 방식을 쓴다).

필터 버튼 둘은 위치만 옮겼다 — 활성 표시(파란 깔때기)와 해제 버튼을 흐리게 두는 규칙은 그대로다.

게이트: 테스트 267/267, --edit-smoke 236건 0실패, --query-popup 17/17, --maxrect 10/10,
--db-smoke 3000 diff 0·예외 0, --db-render P062 md5 8d683835f5d81e7bb41c79071d6bf954 동일,
--dialog-shots 57파일.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Msystech
2026-08-14 11:38:11 +09:00
co-authored by Claude Opus 5
parent 6ee4435575
commit d474937837
2 changed files with 58 additions and 29 deletions
+38 -29
View File
@@ -83,35 +83,44 @@
<!-- ══ 레이어 ══ --> <!-- ══ 레이어 ══ -->
<DockPanel Grid.Row="2"> <DockPanel Grid.Row="2">
<Border DockPanel.Dock="Top" Style="{StaticResource SectionHead}"> <Border DockPanel.Dock="Top" Style="{StaticResource SectionHead}">
<TextBlock Style="{StaticResource SectionHeadText}" Text="레이어"/> <DockPanel>
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal" VerticalAlignment="Center">
<!-- 검색은 접어 둔다 — 컨트롤이 몇 개뿐인 서식이 대부분이라 검색칩이 상시 자리를 먹을 이유가 없다.
끌 때 검색어를 지운다: 상자가 접힌 채 필터만 살아 있으면 목록이 고장난 것처럼 보인다. -->
<ToggleButton x:Name="LayerSearchToggle" Style="{StaticResource MiniToggle}"
Checked="OnLayerSearchOpened" Unchecked="OnLayerSearchClosed"
ToolTip="레이어 검색" AutomationProperties.Name="레이어 검색"
Content="{Binding Source=search, Converter={StaticResource IconName}, ConverterParameter=13|B.Muted}"/>
<!-- 타입 필터 — 이름을 몰라도 "체크박스만" 처럼 종류로 좁힐 수 있어야 한다 -->
<Button Width="24" Height="22" Padding="0" Margin="1,0,0,0"
Click="OnLayerFilterClick"
ToolTip="{Binding CurrentDesigner.LayerTypeFilterTip}">
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource Subtle}">
<Setter Property="Content"
Value="{Binding Source=filter, Converter={StaticResource IconName}, ConverterParameter=13|B.Muted}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding CurrentDesigner.HasLayerTypeFilter}" Value="True">
<Setter Property="Content"
Value="{Binding Source=filter, Converter={StaticResource IconName}, ConverterParameter=13|B.Accent}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<!-- 초기화는 숨기지 않고 흐리게 둔다 — 버튼이 사라지면 옆 버튼 위치가 흔들린다 -->
<Button Style="{StaticResource Subtle}" Width="24" Height="22" Padding="0" Margin="1,0,0,0"
Click="OnLayerFilterClearClick" ToolTip="타입 필터 해제"
IsEnabled="{Binding CurrentDesigner.HasLayerTypeFilter}"
Content="{Binding Source=filter-x, Converter={StaticResource IconName}, ConverterParameter=13|B.Muted}"/>
</StackPanel>
<TextBlock Style="{StaticResource SectionHeadText}" Text="레이어"/>
</DockPanel>
</Border> </Border>
<!-- 검색줄 — 검색칩(가변폭) + 우측 타입 필터 버튼 2개 -->
<DockPanel DockPanel.Dock="Top"> <!-- 검색줄 — 위 돋보기를 눌러야 나온다 -->
<StackPanel DockPanel.Dock="Right" Orientation="Horizontal" <DockPanel DockPanel.Dock="Top"
VerticalAlignment="Center" Margin="0,8,8,6"> Visibility="{Binding IsChecked, ElementName=LayerSearchToggle, Converter={StaticResource BoolToVisibility}}">
<!-- 타입 필터 — 이름을 몰라도 "체크박스만" 처럼 종류로 좁힐 수 있어야 한다 -->
<Button Width="26" Height="22" Padding="0"
Margin="0,0,2,0" Click="OnLayerFilterClick"
ToolTip="{Binding CurrentDesigner.LayerTypeFilterTip}">
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource Subtle}">
<Setter Property="Content"
Value="{Binding Source=filter, Converter={StaticResource IconName}, ConverterParameter=13|B.Muted}"/>
<Style.Triggers>
<DataTrigger Binding="{Binding CurrentDesigner.HasLayerTypeFilter}" Value="True">
<Setter Property="Content"
Value="{Binding Source=filter, Converter={StaticResource IconName}, ConverterParameter=13|B.Accent}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<!-- 초기화는 숨기지 않고 흐리게 둔다 — 버튼이 사라지면 옆 버튼 위치가 흔들린다 -->
<Button Style="{StaticResource Subtle}" Width="26" Height="22" Padding="0"
Click="OnLayerFilterClearClick" ToolTip="타입 필터 해제"
IsEnabled="{Binding CurrentDesigner.HasLayerTypeFilter}"
Content="{Binding Source=filter-x, Converter={StaticResource IconName}, ConverterParameter=13|B.Muted}"/>
</StackPanel>
<!-- <!--
레이어 검색칩 — 컨트롤이 수백 개인 서식에서 이름으로 좁혀 찾는다. 레이어 검색칩 — 컨트롤이 수백 개인 서식에서 이름으로 좁혀 찾는다.
@@ -119,7 +128,7 @@
BorderBrush 도 필수: 라이트에서 B.Input 과 B.Panel 이 둘 다 흰색이라 BorderBrush 도 필수: 라이트에서 B.Input 과 B.Panel 이 둘 다 흰색이라
테두리가 없으면 칩 경계 대비가 정확히 1.00:1 — 입력란이 거기 있다는 것 자체가 안 보인다. 테두리가 없으면 칩 경계 대비가 정확히 1.00:1 — 입력란이 거기 있다는 것 자체가 안 보인다.
--> -->
<Border Height="32" CornerRadius="7" Margin="8,8,0,6" <Border Height="32" CornerRadius="7" Margin="8,6,8,6"
Background="{DynamicResource B.Input}" BorderThickness="1"> Background="{DynamicResource B.Input}" BorderThickness="1">
<Border.Style> <Border.Style>
<Style TargetType="Border"> <Style TargetType="Border">
@@ -113,6 +113,26 @@ public partial class LayerPanelView : System.Windows.Controls.UserControl
e.Handled = handled; e.Handled = handled;
} }
/// <summary>돋보기를 켰다 — 상자가 실제로 보이게 된 뒤에 포커스를 준다(한 틱 뒤)</summary>
private void OnLayerSearchOpened(object sender, RoutedEventArgs e)
=> Dispatcher.BeginInvoke(new Action(() =>
{
LayerSearchBox.Focus();
System.Windows.Input.Keyboard.Focus(LayerSearchBox);
}), System.Windows.Threading.DispatcherPriority.Input);
/// <summary>
/// 돋보기를 껐다 — 검색어를 지운다.
/// 상자가 접힌 채 필터만 살아 있으면 목록이 통째로 비어 보이고 원인을 찾을 단서가 화면에 없다.
/// </summary>
private void OnLayerSearchClosed(object sender, RoutedEventArgs e)
{
if (Designer is { } designer)
{
designer.LayerFilter = string.Empty;
}
}
/// <summary>페이지 구획의 — 트리 안에 있던 '페이지 추가' 행을 대신한다</summary> /// <summary>페이지 구획의 — 트리 안에 있던 '페이지 추가' 행을 대신한다</summary>
private void OnPageAddClick(object sender, RoutedEventArgs e) => Designer?.AddPage(); private void OnPageAddClick(object sender, RoutedEventArgs e) => Designer?.AddPage();