4차 C-4: 색 구분 범례를 이동 도구로
개수를 누르면 그 갈래 줄로 가고 다시 누르면 다음 줄로 간다. 차이 이동과 같은 방식이다. 0건은 흐리게만 하고 숨기지 않는다. 자리가 움직이면 다시 찾아야 한다.
This commit is contained in:
parent
06d018742a
commit
bc92676a49
@ -465,3 +465,42 @@ Gitea 계정 · 토큰 · Fetch · Pull · Push 가 세 줄로 있었다. **원
|
||||
- **글자가 무슨 일이 나는지 말한다** - `▸ 원격 저장소 · 계정 펴기` / `▾ … 접기`.
|
||||
무엇이 숨어 있고 누르면 어떻게 되는지가 한 줄에 다 있다.
|
||||
- **누르는 것으로 읽히게** - 12px 굵게, 강조색, 손 모양 커서, 폭을 190 으로.
|
||||
|
||||
---
|
||||
|
||||
## C-4. 색 구분 범례를 읽는 것에서 쓰는 것으로 — **완료** (2026-09-10)
|
||||
|
||||
**무엇이 문제였나** - 범례 여덟 칸이 늘 한 줄을 차지하는데 <b>읽기만 하는 설명</b>이었다.
|
||||
0건인 갈래도 있는 갈래와 똑같은 무게로 자리를 잡고 있었다.
|
||||
|
||||
**두 가지를 했다.**
|
||||
|
||||
**① 0건은 흐리게.** `ZeroToDimConverter` 로 투명도를 0.35 로 낮춘다.
|
||||
<b>숨기지 않는 까닭</b> - 항목이 나타났다 사라지면 자리가 매번 움직여 같은 것을 다시 찾아야 한다.
|
||||
자리는 그대로 두고 무게만 뺀다. 있는 것과 없는 것이 한눈에 갈린다.
|
||||
|
||||
**② 개수를 누르면 그 갈래로 간다.** `추가 1` 을 누르면 추가된 줄로 가고, 다시 누르면 다음 추가 줄로 간다.
|
||||
"추가된 줄만 훑고 싶다"는 일이 잦은데 차이 이동(`Alt+↑↓`)은 갈래를 가리지 않는다.
|
||||
이제 <b>색 이름을 외울 필요도 없다</b> - 색을 보고 그 자리를 누르면 된다.
|
||||
|
||||
지금 자리 다음부터 찾고 끝에 닿으면 처음으로 돌아온다. **차이 이동과 같은 방식이라 새로 외울 규칙이 없다.**
|
||||
한 줄도 없으면 조용히 넘어가지 않고 `삭제 줄이 없습니다` 로 알린다 -
|
||||
아무 일도 안 일어나면 기능이 없는 줄 안다.
|
||||
|
||||
**단추처럼 보이지 않게 했다.** 테두리와 배경을 지우고 손 모양 커서와 마우스 올렸을 때의 옅은 배경만 남겼다.
|
||||
범례 줄이 단추 여덟 개로 보이면 시끄럽다.
|
||||
|
||||
**화면에서 확인한 것** (차이 2줄 · 추가 1줄인 파일)
|
||||
|
||||
| 누른 것 | 캐럿 |
|
||||
|---|---|
|
||||
| 시작 | 1행 |
|
||||
| `추가 1` | **7행** (추가된 줄) |
|
||||
| `BASE와 다름 2` | **12행** |
|
||||
| 다시 | **5행** |
|
||||
| 또 다시 | **12행** (한 바퀴 돌아옴) |
|
||||
| `삭제 0` | 그대로 · "삭제 줄이 없습니다" |
|
||||
|
||||
0건 갈래(`머지 반영함` · `직접 수정` · `삭제` · `무시` · `자리 옮김`)가 눈에 띄게 흐리다.
|
||||
|
||||
검사 571건 통과 · 빌드 경고 0 · 오류 0.
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
| 날짜 | 항목 | 커밋 |
|
||||
|---|---|---|
|
||||
| 2026-09-10 | **4차 C-4** — 범례를 눌러 그 갈래로 이동. 0건은 흐리게 | 아래 |
|
||||
| 2026-09-10 | **4차 C-3** — Git 탭의 원격 칸을 접을 수 있게. 로컬 경로 한 줄만 남고 세로 128px 가 목록으로 간다 | 아래 |
|
||||
| 2026-09-10 | **엔터 고침의 되돌이 문제** — TextChanged 안에서 편집기 글을 갈아 끼워 캐럿이 엉켰다. 한 차례 뒤로 물림 | 아래 |
|
||||
| 2026-09-10 | **엔터 반응 지연** — 줄 수가 바뀌면 0.6초 타이머만 기다리느라 화면이 비어 있었다. 그 자리에서 다시 맞추게 고침 | 아래 |
|
||||
@ -37,6 +38,7 @@
|
||||
|
||||
| 날짜 | 문서 | 내용 |
|
||||
|---|---|---|
|
||||
| 2026-09-10 | **4차 C-4** — 범례를 눌러 그 갈래로 이동. 0건은 흐리게 | 아래 |
|
||||
| 2026-09-10 | **4차 C-3** — Git 탭의 원격 칸을 접을 수 있게. 로컬 경로 한 줄만 남고 세로 128px 가 목록으로 간다 | 아래 |
|
||||
| 2026-09-10 | **엔터 고침의 되돌이 문제** — TextChanged 안에서 편집기 글을 갈아 끼워 캐럿이 엉켰다. 한 차례 뒤로 물림 | 아래 |
|
||||
| 2026-09-10 | **엔터 반응 지연** — 줄 수가 바뀌면 0.6초 타이머만 기다리느라 화면이 비어 있었다. 그 자리에서 다시 맞추게 고침 | 아래 |
|
||||
|
||||
@ -41,7 +41,7 @@
|
||||
| **완료** | C-1 같은 경로가 세 군데 나온다 |
|
||||
| **완료** | C-2 아래쪽 정보가 세 군데로 흩어져 있다 |
|
||||
| **완료** | C-3 Git 탭의 원격 블록을 접는다 |
|
||||
| 대기 | C-4 색 구분 범례를 이동 도구로 |
|
||||
| **완료** | C-4 색 구분 범례를 이동 도구로 |
|
||||
| 대기 | C-5 ACTIONS 칸을 자주 쓰는 것과 한 번 정하는 것으로 나눈다 |
|
||||
|
||||
### D. 변경 이력을 전용 폴더로
|
||||
|
||||
@ -2795,6 +2795,48 @@ namespace MergeHub.ViewModels
|
||||
/// 줄 하나만 반영해도 곧바로 범례 숫자가 바뀌도록, 편집이 끝날 때마다 다시 센다.
|
||||
/// (UpdateSummaries 가 AfterEdit / 파일 로드 양쪽에서 호출된다)
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// 범례에서 고른 갈래의 <b>다음 줄</b>로 옮긴다.
|
||||
///
|
||||
/// 범례는 지금까지 읽기만 하는 설명이었다. 그런데 "추가된 줄만 훑고 싶다" 는 일이 잦은데
|
||||
/// 차이 이동(Alt+↑↓)은 갈래를 가리지 않는다. 개수를 누르면 그 갈래만 딛게 해서
|
||||
/// <b>범례를 도구로</b> 바꾼다. 색 이름을 외울 필요도 없어진다.
|
||||
///
|
||||
/// 지금 자리 다음부터 찾고 끝에 닿으면 처음으로 돌아온다 - 차이 이동과 같은 방식이라
|
||||
/// 새 규칙을 외울 것이 없다.
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
private void GoToKind(LineHighlight kind)
|
||||
{
|
||||
if (Lines.Count == 0) return;
|
||||
|
||||
for (var step = 1; step <= Lines.Count; step++)
|
||||
{
|
||||
var at = (CaretRow + step) % Lines.Count;
|
||||
if (Lines[at].Highlight != kind) continue;
|
||||
|
||||
GoToRow(at);
|
||||
return;
|
||||
}
|
||||
|
||||
// 한 줄도 없으면 조용히 넘어가는 대신 왜 아무 일도 없는지 알려 준다.
|
||||
MessageUtil.ShowToast($"{KindName(kind)} 줄이 없습니다.");
|
||||
}
|
||||
|
||||
private static string KindName(LineHighlight kind) => kind switch
|
||||
{
|
||||
LineHighlight.Changed => "BASE와 다름",
|
||||
LineHighlight.Applied => "머지 반영함",
|
||||
LineHighlight.Edited => "직접 수정",
|
||||
LineHighlight.Added => "추가",
|
||||
LineHighlight.Removed => "삭제",
|
||||
LineHighlight.Ignored => "무시",
|
||||
LineHighlight.Moved => "자리 옮김",
|
||||
LineHighlight.RemoteChange => "Theirs only",
|
||||
LineHighlight.Conflict => "Conflict",
|
||||
_ => "그"
|
||||
};
|
||||
|
||||
private void UpdateLegendCounts()
|
||||
{
|
||||
int changed = 0, applied = 0, edited = 0, added = 0, removed = 0, moved = 0, ignored = 0, same = 0;
|
||||
|
||||
24
src/MergeHub/Views/Controls/ZeroToDimConverter.cs
Normal file
24
src/MergeHub/Views/Controls/ZeroToDimConverter.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace MergeHub.Views.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// 개수가 0 이면 흐리게. 범례에서 <b>있는 것과 없는 것</b>을 한눈에 가르려는 것이다.
|
||||
///
|
||||
/// 숨기지 않고 흐리게만 하는 까닭 - 항목이 나타났다 사라지면 자리가 매번 움직여
|
||||
/// 같은 것을 다시 찾아야 한다. 자리는 그대로 두고 무게만 뺀다.
|
||||
/// </summary>
|
||||
public sealed class ZeroToDimConverter : IValueConverter
|
||||
{
|
||||
/// <summary>0 일 때의 흐리기. 읽히기는 하되 눈이 먼저 가지는 않는 정도.</summary>
|
||||
private const double Dim = 0.35;
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
|
||||
value is int count && count == 0 ? Dim : 1.0;
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
|
||||
Binding.DoNothing;
|
||||
}
|
||||
}
|
||||
@ -6,6 +6,7 @@
|
||||
xmlns:local="clr-namespace:MergeHub.Views"
|
||||
xmlns:ctl="clr-namespace:MergeHub.Views.Controls"
|
||||
xmlns:system="clr-namespace:System;assembly=mscorlib"
|
||||
xmlns:models="clr-namespace:MergeHub.Models"
|
||||
mc:Ignorable="d"
|
||||
PreviewKeyDown="View_PreviewKeyDown"
|
||||
AllowDrop="True" DragOver="View_DragOver" Drop="View_Drop">
|
||||
@ -44,6 +45,39 @@
|
||||
<Setter Property="VerticalAlignment" Value="Center"/>
|
||||
</Style>
|
||||
|
||||
<ctl:ZeroToDimConverter x:Key="ZeroToDim"/>
|
||||
|
||||
<!--
|
||||
범례 한 칸(4차 C-4). 읽기만 하던 설명을 <b>누르면 그 갈래로 가는 도구</b>로 바꿨다.
|
||||
단추처럼 보이지 않게 테두리와 배경을 지운다 - 줄이 단추 열 개로 보이면 시끄럽다.
|
||||
대신 손 모양 커서와 마우스를 올렸을 때의 옅은 배경으로 "누르는 것"임을 알린다.
|
||||
-->
|
||||
<Style x:Key="LegendButton" TargetType="Button">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="Padding" Value="3,1"/>
|
||||
<Setter Property="Margin" Value="0"/>
|
||||
<Setter Property="MinWidth" Value="0"/>
|
||||
<Setter Property="MinHeight" Value="0"/>
|
||||
<Setter Property="Cursor" Value="Hand"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border x:Name="Back" Background="{TemplateBinding Background}"
|
||||
Padding="{TemplateBinding Padding}" CornerRadius="3">
|
||||
<ContentPresenter VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
<ControlTemplate.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter TargetName="Back" Property="Background"
|
||||
Value="{DynamicResource Ubisam.Brush.Sidebar.Background}"/>
|
||||
</Trigger>
|
||||
</ControlTemplate.Triggers>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="LegendText" TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="11"/>
|
||||
<Setter Property="Margin" Value="0,0,3,0"/>
|
||||
@ -526,60 +560,119 @@
|
||||
FontSize="11" Margin="0,0,12,0"/>
|
||||
|
||||
<!-- 각 항목 뒤의 숫자는 지금 화면에 있는 줄 수. 한 줄만 반영해도 즉시 바뀐다. -->
|
||||
<Button Style="{StaticResource LegendButton}" Command="{Binding GoToKindCommand}"
|
||||
CommandParameter="{x:Static models:LineHighlight.Changed}"
|
||||
Opacity="{Binding ChangedCount, Converter={StaticResource ZeroToDim}}"
|
||||
ToolTip="누르면 'BASE와 다름' 줄로 갑니다. 다시 누르면 다음 줄">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Border Style="{StaticResource LegendChip}"
|
||||
Background="{Binding Source=Changed, Converter={StaticResource HighlightByName}, ConverterParameter=Changed}"/>
|
||||
<TextBlock Text="BASE와 다름" Style="{StaticResource LegendText}"/>
|
||||
<TextBlock Text="{Binding ChangedCount}" Style="{StaticResource LegendCount}"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
<Button Style="{StaticResource LegendButton}" Command="{Binding GoToKindCommand}"
|
||||
CommandParameter="{x:Static models:LineHighlight.Applied}"
|
||||
Opacity="{Binding AppliedCount, Converter={StaticResource ZeroToDim}}"
|
||||
ToolTip="누르면 '머지 반영함' 줄로 갑니다. 다시 누르면 다음 줄">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Border Style="{StaticResource LegendChip}"
|
||||
Background="{Binding Source=Applied, Converter={StaticResource HighlightByName}, ConverterParameter=Applied}"/>
|
||||
<TextBlock Text="머지 반영함" Style="{StaticResource LegendText}"/>
|
||||
<TextBlock Text="{Binding AppliedCount}" Style="{StaticResource LegendCount}"
|
||||
Foreground="{DynamicResource Ubisam.Brush.Success}"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
<Button Style="{StaticResource LegendButton}" Command="{Binding GoToKindCommand}"
|
||||
CommandParameter="{x:Static models:LineHighlight.Edited}"
|
||||
Opacity="{Binding EditedCount, Converter={StaticResource ZeroToDim}}"
|
||||
ToolTip="누르면 '직접 수정' 줄로 갑니다. 다시 누르면 다음 줄">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Border Style="{StaticResource LegendChip}"
|
||||
Background="{Binding Source=Edited, Converter={StaticResource HighlightByName}, ConverterParameter=Edited}"/>
|
||||
<TextBlock Text="직접 수정" Style="{StaticResource LegendText}"/>
|
||||
<TextBlock Text="{Binding EditedCount}" Style="{StaticResource LegendCount}"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
<Button Style="{StaticResource LegendButton}" Command="{Binding GoToKindCommand}"
|
||||
CommandParameter="{x:Static models:LineHighlight.Added}"
|
||||
Opacity="{Binding AddedCount, Converter={StaticResource ZeroToDim}}"
|
||||
ToolTip="누르면 '추가' 줄로 갑니다. 다시 누르면 다음 줄">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Border Style="{StaticResource LegendChip}"
|
||||
Background="{Binding Source=Added, Converter={StaticResource HighlightByName}, ConverterParameter=Added}"/>
|
||||
<TextBlock Text="추가" Style="{StaticResource LegendText}"/>
|
||||
<TextBlock Text="{Binding AddedCount}" Style="{StaticResource LegendCount}"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
<Button Style="{StaticResource LegendButton}" Command="{Binding GoToKindCommand}"
|
||||
CommandParameter="{x:Static models:LineHighlight.Removed}"
|
||||
Opacity="{Binding RemovedCount, Converter={StaticResource ZeroToDim}}"
|
||||
ToolTip="누르면 '삭제' 줄로 갑니다. 다시 누르면 다음 줄">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Border Style="{StaticResource LegendChip}"
|
||||
Background="{Binding Source=Removed, Converter={StaticResource HighlightByName}, ConverterParameter=Removed}"/>
|
||||
<TextBlock Text="삭제" Style="{StaticResource LegendText}"/>
|
||||
<TextBlock Text="{Binding RemovedCount}" Style="{StaticResource LegendCount}"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
<!-- 무시 규칙에 걸린 줄. 차이로 세지 않는다. -->
|
||||
<Button Style="{StaticResource LegendButton}" Command="{Binding GoToKindCommand}"
|
||||
CommandParameter="{x:Static models:LineHighlight.Ignored}"
|
||||
Opacity="{Binding IgnoredCount, Converter={StaticResource ZeroToDim}}"
|
||||
ToolTip="누르면 '무시' 줄로 갑니다. 다시 누르면 다음 줄">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Border Style="{StaticResource LegendChip}"
|
||||
Background="{Binding Source=Ignored, Converter={StaticResource HighlightByName}, ConverterParameter=Ignored}"/>
|
||||
<TextBlock Text="무시" Style="{StaticResource LegendText}"/>
|
||||
<TextBlock Text="{Binding IgnoredCount}" Style="{StaticResource LegendCount}"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
<!-- 자리만 옮긴 줄. 삭제+추가로 두 번 세지 않도록 따로 표시한다. -->
|
||||
<Button Style="{StaticResource LegendButton}" Command="{Binding GoToKindCommand}"
|
||||
CommandParameter="{x:Static models:LineHighlight.Moved}"
|
||||
Opacity="{Binding MovedCount, Converter={StaticResource ZeroToDim}}"
|
||||
ToolTip="누르면 '자리 옮김' 줄로 갑니다. 다시 누르면 다음 줄">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Border Style="{StaticResource LegendChip}"
|
||||
Background="{Binding Source=Moved, Converter={StaticResource HighlightByName}, ConverterParameter=Moved}"/>
|
||||
<TextBlock Text="자리 옮김" Style="{StaticResource LegendText}"/>
|
||||
<TextBlock Text="{Binding MovedCount}" Style="{StaticResource LegendCount}"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
<!-- 3-Way 일 때만 뜻이 있는 두 가지. 2-Way 에서는 늘 0 이라 자리만 차지한다. -->
|
||||
<Border Style="{StaticResource LegendChip}"
|
||||
<Button Style="{StaticResource LegendButton}" Command="{Binding GoToKindCommand}"
|
||||
CommandParameter="{x:Static models:LineHighlight.RemoteChange}"
|
||||
Opacity="{Binding RemoteChangeCount, Converter={StaticResource ZeroToDim}}"
|
||||
Visibility="{Binding IsThreeWay, Converter={StaticResource BoolToVis}}"
|
||||
ToolTip="누르면 '저쪽만 고친 줄'로 갑니다. 다시 누르면 다음 줄">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Border Style="{StaticResource LegendChip}"
|
||||
Background="{Binding Source=RemoteChange, Converter={StaticResource HighlightByName}, ConverterParameter=RemoteChange}"/>
|
||||
<TextBlock Text="Theirs only" Style="{StaticResource LegendText}"
|
||||
Visibility="{Binding IsThreeWay, Converter={StaticResource BoolToVis}}"/>
|
||||
<TextBlock Text="{Binding RemoteChangeCount}" Style="{StaticResource LegendCount}"
|
||||
Visibility="{Binding IsThreeWay, Converter={StaticResource BoolToVis}}"/>
|
||||
<TextBlock Text="Theirs only" Style="{StaticResource LegendText}"/>
|
||||
<TextBlock Text="{Binding RemoteChangeCount}" Style="{StaticResource LegendCount}"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
<Border Style="{StaticResource LegendChip}"
|
||||
<Button Style="{StaticResource LegendButton}" Command="{Binding GoToKindCommand}"
|
||||
CommandParameter="{x:Static models:LineHighlight.Conflict}"
|
||||
Opacity="{Binding ConflictCount, Converter={StaticResource ZeroToDim}}"
|
||||
Visibility="{Binding IsThreeWay, Converter={StaticResource BoolToVis}}"
|
||||
ToolTip="누르면 충돌 줄로 갑니다. 다시 누르면 다음 줄">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Border Style="{StaticResource LegendChip}"
|
||||
Background="{Binding Source=Conflict, Converter={StaticResource HighlightByName}, ConverterParameter=Conflict}"/>
|
||||
<TextBlock Text="Conflict" Style="{StaticResource LegendText}"
|
||||
Visibility="{Binding IsThreeWay, Converter={StaticResource BoolToVis}}"/>
|
||||
<TextBlock Text="{Binding ConflictCount}" Style="{StaticResource LegendCount}"
|
||||
Visibility="{Binding IsThreeWay, Converter={StaticResource BoolToVis}}"/>
|
||||
<TextBlock Text="Conflict" Style="{StaticResource LegendText}"/>
|
||||
<TextBlock Text="{Binding ConflictCount}" Style="{StaticResource LegendCount}"/>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
|
||||
<Border Style="{StaticResource LegendChip}" Background="#66E0A020"/>
|
||||
<TextBlock Text="줄 안에서 바뀐 부분" Style="{StaticResource LegendText}" Margin="0,0,14,0"/>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user