Shift+휠 가로 · Ctrl+↓ 와 아래 "지금 줄" 칸 · Ctrl+W 로 폴더 비교 · 다크 모드
- Shift+휠을 가로 스크롤로(파일 비교 · 메모). 파일 비교는 가로 휠(틸트)과 같은 길로 보내 마우스가 놓인 칸이 움직이고 나머지가 따라온다. 휠 아래 = 오른쪽. - Ctrl+↓ / Ctrl+↑ 를 다음 · 이전 차이의 대체 키로. 칸과 상태 줄 사이에 캐럿 행의 BASE(변경 전) · LOCAL(변경 후)을 위아래로 보이는 칸 - 칸과 같은 CodeTextBlock (문법 색 · 바뀐 글자 칠하기 · 줄 색), 긴 줄은 접는다. HomeViewModel.CaretLine. - 폴더 비교에서 연 문서 탭을 닫으면(Ctrl+W) 폴더 비교 탭으로 간다. RequestPlainCompare(fromFolder:) 로 표시를 보내 DocTab.FromFolder 에 붙이고, ◀ 이전 파일 · 다음 파일 ▶ 로 짝을 바꿔도 이어 받는다. 다른 길로 연 탭은 그대로. - 어두운 테마에서 폴더 비교 목록만 흰 바탕 · 검은 글자였다 - 플랫폼 테마가 TreeView 는 칠하지 않는다. 바탕 · 글자색(항목 포함)을 테마에서 받는다. 색 구분의 0 항목 흐리기 0.35 -> 0.55(어두운 바탕에서 묻혔다). 시험: 빌드 경고 0 · 오류 0. 화면 g27-five(새, 어두운 테마) - Shift+휠 편집기 가로 0 -> 20% · 세로 그대로 · BASE 칸 위에서도 · 메모, Ctrl+↓ 로 차이 이동 · 아래 칸 표시, 폴더 비교에서 연 탭만 Ctrl+W 뒤 폴더 비교로, 사진으로 폴더 목록 · 아래 칸 확인. 실패 0. 기존 회귀는 돌리지 않았다. Agent: main (claude-opus-5-5) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
18b05d6b38
commit
df06947afc
@ -2,6 +2,23 @@
|
||||
|
||||
지시서: [../작업지시/12차.md](../작업지시/12차.md)
|
||||
|
||||
## Shift+휠 가로 · Ctrl+↓ 와 아래 "지금 줄" 칸 · Ctrl+W 로 폴더 비교 · 다크 모드 (2026-10-01, 사용자 요청 · 결정 · 완료)
|
||||
|
||||
1. **Shift+휠 = 가로 스크롤**(파일 비교 · 메모, 사용자 결정). 예전에는 Ctrl+휠(글자 크기)만 따로 받고 Shift+휠은 세로로 굴렀다.
|
||||
파일 비교는 가로 휠(틸트)과 같은 길(`ScrollSourcePanes` · `ScrollEditor`)로 보낸다 — 마우스가 놓인 칸이 움직이고 나머지는 지금처럼 따라온다. 휠 아래 = 오른쪽.
|
||||
2. **Ctrl+↓ / Ctrl+↑ = 다음 · 이전 차이**(대체 키, 단축키 표에 더함 — 설명 창에도 나온다). 그리고 **아래 "지금 줄" 칸**(사용자 결정: 캐럿 줄 두 줄) —
|
||||
칸과 상태 줄 사이에 캐럿 행의 BASE(변경 전) · LOCAL(변경 후)을 위아래로. 칸과 같은 `CodeTextBlock`(문법 색 · 바뀐 글자 칠하기 · 줄 색), 긴 줄은 접어 끝까지,
|
||||
한쪽에 없는 줄이면 `(이 줄 없음 …)`. `HomeViewModel.CaretLine` — 캐럿이 옮겨지거나 행이 다시 만들어지면(`UpdateSummaries`) 다시 알린다.
|
||||
3. **Ctrl+W 로 닫으면 폴더 비교로**(사용자 결정: 폴더 비교에서 연 파일일 때만). `RequestPlainCompare(fromFolder:)` 로 표시를 실어 보내고
|
||||
(폴더 비교 두 번 누르기 · 폴더 검색 결과), 파일 비교가 문서 탭(`DocTab.FromFolder`)에 붙인다. ◀ 이전 파일 · 다음 파일 ▶ 로 짝을 바꿔도(탭을 새로 만드는 `Replace`) 이어 받는다.
|
||||
그 탭을 닫으면 `TabManager.Activate(ViewIds.Folder)`. 남은 탭은 그대로 다음 탭을 띄워 둔다.
|
||||
"폴더 비교에서 파일을 열면 하단 탭도 파일 비교로" 는 플랫폼 `8158bbf`(배포본 `2026-10-01 13:37:46`)에서 이미 고쳤다 — 그 전 플랫폼인 PC 에서 보인 것.
|
||||
4. **다크 모드 가독성** — 어두운 테마로 켜서 찍어 봤다. 가장 큰 것은 **폴더 비교 목록만 흰 바탕**: 플랫폼 테마가 ListBox · ListView · DataGrid 는 칠하지만
|
||||
TreeView 는 칠하지 않아 WPF 기본(흰 바탕 · 검은 글자)으로 남았다 → 바탕 · 글자색을 테마에서 받고 항목(TreeViewItem) 글자색도 준다(줄 상태 색은 반투명이라 그대로 맞는다).
|
||||
색 구분의 0 항목 흐리기 0.35 → 0.55(어두운 바탕에서 거의 묻혔다). 차이 줄 바탕색 대비는 두 테마가 비슷해(1.2~1.5) 그대로. 꺼진 단추 글자가 흐린 것은 플랫폼 테마 몫이라 손대지 않았다.
|
||||
|
||||
시험(이것만): `g27-five`(새, 어두운 테마) — Shift+휠 편집기 가로 0 → 20%(세로 그대로) · BASE 칸 위에서도 · 메모 0 → 5.7%, Ctrl+↓ 로 차이 2/2 → 1/2 · 아래 칸 BASE · LOCAL 이름표,
|
||||
기본 짝은 Ctrl+W 뒤 파일 비교 그대로 · 폴더 비교에서 연 alpha 는 하단 탭 파일 비교(1) → Ctrl+W 뒤 폴더 비교(0), 사진으로 폴더 목록 어두운 바탕 · 아래 칸 확인. 실패 0. 기존 회귀는 돌리지 않았다.
|
||||
## 전체 반영 · 자동 병합의 주석이 너무 많다 (2026-10-01, 사용자 요청 · 결정 · 완료)
|
||||
|
||||
[전체 반영] 은 반영할 줄마다 `Apply` 를 따로 불러 **바뀐 줄마다 머지 주석 한 줄**, 되돌리기도 줄마다 한 걸음이었다.
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
| 날짜 | 항목 | 커밋 |
|
||||
|---|---|---|
|
||||
| 2026-10-01 | **Shift+휠 가로 · Ctrl+↓ 와 아래 "지금 줄" 칸 · Ctrl+W 로 폴더 비교 · 다크 모드(사용자 요청 · 결정)** — ① Shift+휠 = 가로(파일 비교는 가로 휠과 같은 길, 메모도) ② Ctrl+↓/↑ = 다음 · 이전 차이(대체 키) + 칸과 상태 줄 사이에 캐럿 행의 BASE(변경 전) · LOCAL(변경 후)을 위아래로(같은 `CodeTextBlock`, 긴 줄은 접음, `CaretLine`) ③ 폴더 비교에서 연 탭(`DocTab.FromFolder`, `RequestPlainCompare(fromFolder:)`, ◀ ▶ 로 바꿔도 이어 받음)을 닫으면 폴더 비교로 ④ 폴더 비교 목록이 어두운 테마에서도 흰 바탕 · 검은 글자 — 플랫폼 테마가 TreeView 는 안 칠함 → 테마 바탕 · 글자색, 색 구분 0 항목 흐리기 0.35 → 0.55. 하단 탭이 파일 비교로 안 바뀌던 것은 플랫폼 `8158bbf` 에서 이미 고침. 화면 `g27-five`(새, 어두운 테마) 실패 0. 기존 회귀는 돌리지 않음. 빌드 경고 0 · 오류 0 | 아래 |
|
||||
| 2026-10-01 | **배포 묶음 스크립트를 런처 기준으로(사용자 요청)** — `scripts\make-bundle.ps1` 은 11차(셸을 켜던 때) 것이라 새 플랫폼의 `UbisamBase.Launcher.exe` · 그 설정 · `platform-version.json` 을 "까닭 미상" 으로 경고했다. 셋에 까닭을 적고, 런처와 런처 설정을 꼭 있어야 하는 파일로, 런처 설정의 바인딩 리디렉트 검사를 더함(없으면 켜자마자 죽는다 - 플랫폼 `publish-platform.ps1` 과 같은 검사). `배포묶음.txt` 는 "런처를 켠다" · 런처가 켤 때 하는 일 · 플랫폼 버전. 확인: `-NoBuild` 로 44개 · 경고 없음, 묶음에서 런처로 켜고 끔. 같은 날 알파판 ZIP(`배포\MergeHub_v0.12_alpha_20261001.zip`, 커밋 `b717f4e` · 플랫폼 `2026-10-01 13:37:46`)은 지난번 알파판 구성(Release 출력 + `UbisamPlatform\bin` + 설치안내)으로 따로 만들었다 | 아래 |
|
||||
| 2026-10-01 | **전체 반영 · 자동 병합의 주석을 구간마다 한 줄로(사용자 요청 · 결정)** — 줄마다 머지 주석이 붙던 것. ① 두 파일 비교 [전체 반영]: 반영할 수 있는 줄이 이어진 구간마다 [구간 반영] 과 같게(`ApplyGroup`), 지우는 반영은 `삭제 N줄`, 모든 구간을 한 묶음으로 Undo 한 번 ② 3-Way [전체 반영] 끔 — 차이 나는 모든 줄을 공통 조상으로 바꾸던 동작(꺼져도 툴팁으로 까닭) ③ 3-Way [자동 병합]: 저쪽만 고친 줄 구간마다 주석 한 줄 · Undo 한 번(충돌 · 내 줄은 구간을 끊고 그대로). 화면 `g22-accept-all` 주석 7 → 3, `g23-three-way`(`--merge`) 5 → 2, 실패 0. 기존 회귀는 돌리지 않음. 빌드 경고 0 · 오류 0 | 아래 |
|
||||
| 2026-10-01 | **스크롤을 내리면 프로그램이 뻗던 것(사용자 보고)** — 어제 칸 맞추기(`f105bab`) 뒤 응답 없음. ① 사람이 BASE 를 굴려도 LOCAL 기준으로 되돌려 초당 32번 밀고 당김 → 손이 닿은 칸(휠 · 누름 · 키)을 기준으로, LOCAL 쪽일 때만 BASE 를 맞춤 ② 따라 굴러가는 도중에 재서 보정값이 휠 한 칸씩 6,619px 까지 쌓임 → 메아리 막기 중이면 큰 맞추기는 앱이 한가할 때 한 번, 못 굴리면 실제로 움직인 만큼만 ③ 칸 목록(그 칸에 있는 줄만)의 항목 번호를 정렬 행 번호로 써 엉뚱한 줄끼리 견줌 → 줄 객체로 오감 ④ 빠르게 굴리면 사람의 스크롤이 메아리로 버려져 따라가는 칸이 멈춤 → 멈춘 뒤 한 번 따라잡기, BASE 를 굴릴 때 보정값을 보이는 줄에서 다시 잼. 화면 `g20-scroll-end` · `g21-blocks-fast`(새) 응답 · 따라옴, `g7` 실패 0, `g17` 통과. 사용자 파일로는 확인 안 함 · 기존 회귀는 돌리지 않음. 빌드 경고 0 · 오류 0 | 아래 |
|
||||
|
||||
@ -446,6 +446,7 @@
|
||||
|
||||
| 상태 | 항목 |
|
||||
|---|---|
|
||||
| **완료** | **Shift+휠 가로 · Ctrl+↓ 와 아래 "지금 줄" 칸 · Ctrl+W 로 폴더 비교 · 다크 모드**(사용자 요청 · 결정) — Shift+휠 가로(파일 비교 · 메모), Ctrl+↓/↑ 차이 이동 대체 키 + 캐럿 행의 BASE · LOCAL 을 아래에 위아래로, 폴더 비교에서 연 탭을 닫으면 폴더 비교로, 폴더 비교 목록이 어두운 테마에서도 흰 바탕이던 것(TreeView 는 플랫폼 테마가 안 칠함) · 0 항목 흐리기 완화. 화면 `g27-five` 실패 0 |
|
||||
| **완료** | **전체 반영 · 자동 병합의 주석이 너무 많다**(사용자 요청 · 결정) — 두 파일 비교 [전체 반영] 을 구간 반영처럼(구간마다 주석 한 줄 · Undo 한 번), 3-Way [전체 반영] 은 끔(공통 조상으로 되돌리는 동작이었다), 3-Way [자동 병합] 도 구간마다 주석 한 줄 · Undo 한 번. 화면 `g22` 주석 7 → 3, `g23` 5 → 2, 실패 0 |
|
||||
| **완료** | **스크롤을 내리면 프로그램이 뻗는다**(사용자 보고, 어제 `f105bab` 뒤) — 응답 없음(AppHang). 원인 넷: BASE 를 굴려도 LOCAL 쪽으로 되돌려 밀고 당김 · 따라 굴러가는 도중에 재서 보정값이 6,619px 까지 쌓임 · 칸 목록 항목 번호를 정렬 행 번호로 씀(한쪽에만 있는 줄만큼 엉뚱한 줄끼리 견줌) · 빠르게 굴리면 사람의 스크롤이 버려짐. 손이 닿은 칸을 기준으로, 큰 맞추기는 한가할 때 한 번, 줄 객체로 오가기, 버려지면 멈춘 뒤 따라잡기. 화면 `g20` · `g21`(새) 응답, `g7` 실패 0, `g17` 통과 |
|
||||
| **완료** | **끌 때 저장하지 않은 편집을 묻는다**(사용자 요청 · 결정) — 파일 비교의 모든 탭(Git 모드 · 뒤 탭 · 닫은 탭 포함, 메모 제외)에 편집이 있으면 [저장하고 종료] · [저장하지 않고 종료] · [취소]. 버리면 보관본도 비워 다음에 안 살아남. 플랫폼 `ICloseGuard` 를 그대로 씀(플랫폼 수정 없음). 화면 `g19-exit-confirm` 실패 0. Git 모드는 화면 시험 안 함 · 기존 회귀는 사용자 지시로 안 돌림 |
|
||||
|
||||
@ -68,6 +68,9 @@ namespace MergeHub.Services
|
||||
/// <summary>화면에 없는 동안 맡아 둔 편집. 떠 있는 탭은 화면이 주인이라 비어 있다.</summary>
|
||||
public DocTabState? Parked { get; set; }
|
||||
|
||||
/// <summary>폴더 비교에서 연 탭. 닫으면 폴더 비교로 돌아간다(2026-10-01 사용자 요청).</summary>
|
||||
public bool FromFolder { get; set; }
|
||||
|
||||
private bool _isDirty;
|
||||
|
||||
/// <summary>저장하지 않은 편집이 있는가. 탭 이름 앞 · 표시에 쓴다.</summary>
|
||||
|
||||
@ -653,11 +653,13 @@ namespace MergeHub.Services
|
||||
/// 찾은 줄을 눈으로 다시 찾아야 한다.
|
||||
/// </param>
|
||||
/// <param name="lineIsLeft">그 번호가 왼쪽 파일 기준인지. 아니면 오른쪽 기준이다.</param>
|
||||
public void RequestPlainCompare(string leftFile, string rightFile, int line = 0, bool lineIsLeft = true)
|
||||
/// <param name="fromFolder">폴더 비교에서 열었는지. 파일 비교가 그 문서 탭에 적어 두고, 탭을 닫으면 폴더 비교로 돌려보낸다.</param>
|
||||
public void RequestPlainCompare(string leftFile, string rightFile, int line = 0, bool lineIsLeft = true, bool fromFolder = false)
|
||||
{
|
||||
_pendingPlainCompare = (leftFile, rightFile);
|
||||
RequestedLine = line;
|
||||
RequestedLineIsLeft = lineIsLeft;
|
||||
RequestedFromFolder = fromFolder;
|
||||
OnUi(DeliverPendingPlainCompare);
|
||||
}
|
||||
|
||||
@ -695,6 +697,17 @@ namespace MergeHub.Services
|
||||
/// <summary>그 번호가 왼쪽 파일 기준인지.</summary>
|
||||
public bool RequestedLineIsLeft { get; private set; }
|
||||
|
||||
/// <summary>넘긴 짝을 폴더 비교에서 열었는지.</summary>
|
||||
public bool RequestedFromFolder { get; private set; }
|
||||
|
||||
/// <summary>폴더 비교에서 열었는지를 한 번 쓰고 지운다 - 다음에 다른 길로 연 짝까지 끌려가지 않게.</summary>
|
||||
public bool TakeRequestedFromFolder()
|
||||
{
|
||||
var one = RequestedFromFolder;
|
||||
RequestedFromFolder = false;
|
||||
return one;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 짚어 줄 자리를 한 번 쓰고 지운다.
|
||||
/// 지우지 않으면 그 다음에 연 파일까지 같은 줄로 끌려간다.
|
||||
|
||||
@ -114,6 +114,8 @@ namespace MergeHub.Services
|
||||
new ShortcutEntry(ShortcutAction.PrevDiff, Key.Up, ModifierKeys.Alt, "차이 이동", "이전 차이"),
|
||||
new ShortcutEntry(ShortcutAction.NextDiff, Key.F4, ModifierKeys.None, "차이 이동", "다음 차이 (대체 키)"),
|
||||
new ShortcutEntry(ShortcutAction.PrevDiff, Key.F4, ModifierKeys.Shift, "차이 이동", "이전 차이 (대체 키)"),
|
||||
new ShortcutEntry(ShortcutAction.NextDiff, Key.Down, ModifierKeys.Control, "차이 이동", "다음 차이 (대체 키)"),
|
||||
new ShortcutEntry(ShortcutAction.PrevDiff, Key.Up, ModifierKeys.Control, "차이 이동", "이전 차이 (대체 키)"),
|
||||
new ShortcutEntry(ShortcutAction.FirstDiff, Key.Home, ModifierKeys.Alt, "차이 이동", "파일의 첫 차이"),
|
||||
new ShortcutEntry(ShortcutAction.LastDiff, Key.End, ModifierKeys.Alt, "차이 이동", "파일의 마지막 차이"),
|
||||
new ShortcutEntry(ShortcutAction.FirstDiff, Key.Home, ModifierKeys.Control, "차이 이동", "첫 차이 (대체 키)"),
|
||||
|
||||
@ -650,7 +650,7 @@ namespace MergeHub.ViewModels
|
||||
|
||||
// 오른쪽에서만 나온 줄이면 오른쪽 파일 기준 번호다.
|
||||
_workspace.RequestPlainCompare(hit.LeftPath, hit.RightPath, hit.LineNumber,
|
||||
lineIsLeft: hit.Side != SearchSide.Right);
|
||||
lineIsLeft: hit.Side != SearchSide.Right, fromFolder: true);
|
||||
UbisamBase.Core.Modules.TabManager.Activate(ViewIds.Home);
|
||||
}
|
||||
|
||||
@ -762,7 +762,7 @@ namespace MergeHub.ViewModels
|
||||
|
||||
// 요청을 먼저 걸고 탭을 연다. 파일 비교 화면이 아직 없으면 그 화면이 만들어지면서
|
||||
// 남아 있는 요청을 직접 집어 간다(GitWorkspace.RequestPlainCompare 설명 참고).
|
||||
_workspace.RequestPlainCompare(node.LeftPath, node.RightPath);
|
||||
_workspace.RequestPlainCompare(node.LeftPath, node.RightPath, fromFolder: true);
|
||||
UbisamBase.Core.Modules.TabManager.Activate(ViewIds.Home);
|
||||
}
|
||||
|
||||
|
||||
@ -319,6 +319,10 @@ namespace MergeHub.ViewModels
|
||||
SyncTabItems();
|
||||
SaveSession(); // 12차 E-1 - 닫아도 글은 남는다. 그 자리에서 적어 둔다.
|
||||
|
||||
// 폴더 비교에서 연 파일을 닫았으면 폴더 비교로 돌아간다(2026-10-01 사용자 요청 - 목록에서 하나씩 열어 보고 닫는 손버릇).
|
||||
// 남은 탭은 그대로 다음 탭을 띄워 둔다 - 파일 비교 탭으로 돌아오면 거기서 이어진다.
|
||||
if (tab.FromFolder) UbisamBase.Core.Modules.TabManager.Activate(ViewIds.Folder);
|
||||
|
||||
if (next is null || ReferenceEquals(next, tab)) return;
|
||||
|
||||
_resumeTab = next;
|
||||
|
||||
@ -133,7 +133,12 @@ namespace MergeHub.ViewModels
|
||||
// 탭을 먼저 잡아 둔다. 아래 LoadPlainFilesAsync 가 다 읽은 뒤 맡겨 둔 편집을 되살린다.
|
||||
var replaceTab = _replaceTab;
|
||||
_replaceTab = false;
|
||||
|
||||
// 폴더 비교에서 연 짝이면 탭에 적어 둔다 - 닫으면 폴더 비교로 돌아간다. ◀ 이전 파일 · 다음 파일 ▶ 은 폴더 목록을
|
||||
// 훑는 것이라 탭을 새로 만들어도(Replace) 그 표시를 이어 받는다.
|
||||
var fromFolder = _workspace.TakeRequestedFromFolder() || (replaceTab && Tabs.Current?.FromFolder == true);
|
||||
OpenPairInTab(leftFile, rightFile, replaceTab);
|
||||
if (fromFolder && Tabs.Current is { } openedTab) openedTab.FromFolder = true;
|
||||
|
||||
// 3-Way 를 끄되 그 때문에 본문을 다시 읽지는 않게 한다 - 그 재로드가 작업 게이트를
|
||||
// 먼저 잡으면 바로 아래 파일 비교가 "다른 작업 진행 중"으로 건너뛰어진다.
|
||||
@ -3668,8 +3673,15 @@ namespace MergeHub.ViewModels
|
||||
AcceptBlockToBaseCommand.NotifyCanExecuteChanged(); // 12차 G-2 - 왼쪽으로 보내는 짝
|
||||
AcceptMemberCommand.NotifyCanExecuteChanged();
|
||||
OnPropertyChanged(nameof(MemberHint));
|
||||
OnPropertyChanged(nameof(CaretLine));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 캐럿이 있는 행. 화면 아래 "지금 줄" 칸이 이 행의 BASE · LOCAL 을 위아래로 보여 준다(2026-10-01 사용자 요청 -
|
||||
/// 다음 차이로 옮겨 가면 무엇이 바뀌었는지 아래에서 한 줄씩 견줘 보고 싶다). 행이 다시 만들어지면 <see cref="UpdateSummaries"/> 가 다시 알린다.
|
||||
/// </summary>
|
||||
public MergeLine? CaretLine => CaretRow >= 0 && CaretRow < Lines.Count ? Lines[CaretRow] : null;
|
||||
|
||||
/// <summary>상태바에 띄우는 "차이 3 / 15".</summary>
|
||||
[ObservableProperty] private string _diffPosition = "차이 -";
|
||||
|
||||
@ -4233,6 +4245,8 @@ namespace MergeHub.ViewModels
|
||||
|
||||
private void UpdateSummaries()
|
||||
{
|
||||
OnPropertyChanged(nameof(CaretLine)); // 행이 다시 만들어지면 아래 "지금 줄" 칸이 옛 행을 붙들지 않게
|
||||
|
||||
// 줄을 고르거나 머지 주석이 끼어들면 결과 줄 수가 바뀐다. 그릴 때마다 번호를 다시 매긴다(8차 B-3).
|
||||
RenumberMerged(Lines);
|
||||
RenumberBase(Lines); // 왼쪽도 마찬가지다(12차 B-1 로 왼쪽이 바뀔 수 있게 됐다)
|
||||
|
||||
@ -12,8 +12,11 @@ namespace MergeHub.Views.Controls
|
||||
/// </summary>
|
||||
public sealed class ZeroToDimConverter : IValueConverter
|
||||
{
|
||||
/// <summary>0 일 때의 흐리기. 읽히기는 하되 눈이 먼저 가지는 않는 정도.</summary>
|
||||
private const double Dim = 0.35;
|
||||
/// <summary>
|
||||
/// 0 일 때의 흐리기. 읽히기는 하되 눈이 먼저 가지는 않는 정도.
|
||||
/// 0.35 는 어두운 테마에서 바탕에 거의 묻혔다(2026-10-01 사용자 보고) - 두 테마 모두 읽히는 0.55 로.
|
||||
/// </summary>
|
||||
private const double Dim = 0.55;
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
|
||||
value is int count && count == 0 ? Dim : 1.0;
|
||||
|
||||
@ -107,6 +107,8 @@
|
||||
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}"/>
|
||||
<!-- 줄 배경이 오른쪽 끝까지 가도록 항목을 가로로 늘린다. -->
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||
<!-- WPF 기본 TreeViewItem 은 글자색을 시스템 검정으로 박아 둔다 - 테마 글자색으로(어두운 테마). -->
|
||||
<Setter Property="Foreground" Value="{DynamicResource Ubisam.Brush.ContentForeground}"/>
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
@ -366,8 +368,12 @@
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- 바탕 · 글자색을 테마에서 받는다(2026-10-01 사용자 보고 "다크 모드에서 잘 안 보인다"). 플랫폼 테마는 ListBox · ListView ·
|
||||
DataGrid 는 칠하지만 TreeView 는 칠하지 않아, 어두운 테마에서도 이 목록만 WPF 기본(흰 바탕 · 검은 글자)으로 남았다. -->
|
||||
<TreeView Grid.Row="0" x:Name="Tree" BorderThickness="1"
|
||||
BorderBrush="{DynamicResource Ubisam.Brush.Input.Border}"
|
||||
Background="{DynamicResource Ubisam.Brush.ContentBackground}"
|
||||
Foreground="{DynamicResource Ubisam.Brush.ContentForeground}"
|
||||
ItemsSource="{Binding Nodes}"
|
||||
ItemTemplate="{StaticResource NodeTemplate}"
|
||||
ItemContainerStyle="{StaticResource NodeItemStyle}"
|
||||
|
||||
@ -555,6 +555,8 @@
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="*"/>
|
||||
<!-- 지금 줄 전/후(2026-10-01). 캐럿이 있는 행의 BASE · LOCAL 을 위아래로. -->
|
||||
<RowDefinition Height="Auto"/>
|
||||
<!-- 상태바. 패널 안이 아니라 창 아래 한 줄로 둔다(4차 C-2). -->
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
@ -1991,6 +1993,94 @@
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
<!--
|
||||
③-1 지금 줄 전/후 (2026-10-01 사용자 요청).
|
||||
다음 차이(Alt+↓ · Ctrl+↓)로 옮겨 가면 그 행의 BASE(변경 전) · LOCAL(변경 후)을 위아래 두 줄로 견줘 보인다 -
|
||||
나란한 두 칸에서는 긴 줄의 바뀐 곳이 옆으로 멀리 떨어져 눈이 오가야 했다(WinMerge 의 아래 비교 칸과 같은 뜻).
|
||||
칸과 같은 그리기(CodeTextBlock: 문법 색 · 바뀐 글자 칠하기 · 줄 색)를 쓴다. 긴 줄은 접어 끝까지 보인다.
|
||||
-->
|
||||
<Border Grid.Row="3" Padding="8,3" BorderThickness="1,1,1,0" Margin="0,2,0,0"
|
||||
Background="{DynamicResource Ubisam.Brush.Sidebar.Background}"
|
||||
BorderBrush="{DynamicResource Ubisam.Brush.Input.Border}"
|
||||
DataContext="{Binding CaretLine}">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding}" Value="{x:Null}">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="Auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto"/>
|
||||
<RowDefinition Height="Auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" Text="BASE" Style="{StaticResource PanelTitle}" FontSize="11"
|
||||
VerticalAlignment="Top" Margin="0,1,8,0" ToolTip="변경 전 (왼쪽 칸)"/>
|
||||
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding BaseNumberText}" Style="{StaticResource Mono}"
|
||||
Foreground="{DynamicResource Ubisam.Brush.Muted}" MinWidth="36" TextAlignment="Right"
|
||||
VerticalAlignment="Top" Margin="0,0,8,0"/>
|
||||
<Border Grid.Row="0" Grid.Column="2" Padding="2,0"
|
||||
Background="{Binding Highlight, Converter={StaticResource HighlightBrush}}">
|
||||
<Grid>
|
||||
<ctl:CodeTextBlock Code="{Binding BaseText}" Words="{Binding BaseWords}"
|
||||
InBlockComment="{Binding BaseInComment}"
|
||||
CodeLanguage="{Binding DataContext.Language, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
HighlightSyntax="{Binding DataContext.SyntaxHighlight, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
TextWrapping="Wrap" FontFamily="Consolas" FontSize="{DynamicResource CodeFontSize}"/>
|
||||
<TextBlock Text="(이 줄 없음 - LOCAL 에만 있다)" FontSize="11">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock" BasedOn="{StaticResource Muted}">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding HasBase}" Value="False">
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" Text="LOCAL" Style="{StaticResource PanelTitle}" FontSize="11"
|
||||
VerticalAlignment="Top" Margin="0,3,8,0" ToolTip="변경 후 (오른쪽 칸 · 편집하는 글)"/>
|
||||
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding LocalNumberText}" Style="{StaticResource Mono}"
|
||||
Foreground="{DynamicResource Ubisam.Brush.Muted}" MinWidth="36" TextAlignment="Right"
|
||||
VerticalAlignment="Top" Margin="0,2,8,0"/>
|
||||
<Border Grid.Row="1" Grid.Column="2" Padding="2,0" Margin="0,2,0,0"
|
||||
Background="{Binding Highlight, Converter={StaticResource HighlightBrush}}">
|
||||
<Grid>
|
||||
<ctl:CodeTextBlock Code="{Binding LocalText}" Words="{Binding LocalWords}"
|
||||
InBlockComment="{Binding LocalInComment}"
|
||||
CodeLanguage="{Binding DataContext.Language, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
HighlightSyntax="{Binding DataContext.SyntaxHighlight, RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
TextWrapping="Wrap" FontFamily="Consolas" FontSize="{DynamicResource CodeFontSize}"/>
|
||||
<TextBlock Text="(이 줄 없음 - BASE 에만 있다)" FontSize="11">
|
||||
<TextBlock.Style>
|
||||
<Style TargetType="TextBlock" BasedOn="{StaticResource Muted}">
|
||||
<Setter Property="Visibility" Value="Collapsed"/>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding HasLocal}" Value="False">
|
||||
<Setter Property="Visibility" Value="Visible"/>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</TextBlock.Style>
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!--
|
||||
④ 상태바 — 창 아래 한 줄.
|
||||
|
||||
@ -2002,7 +2092,7 @@
|
||||
<b>자리 규칙</b> - 왼쪽은 지금 어디에 있는지, 가운데는 얼마나 남았는지, 오른쪽은 이 파일이 무엇인지.
|
||||
패널 밖으로 나오면서 두 패널의 코드 영역 높이가 저절로 같아진다.
|
||||
-->
|
||||
<Border Grid.Row="3" Padding="8,4" BorderThickness="1,1,1,1" Margin="0,2,0,0"
|
||||
<Border Grid.Row="4" Padding="8,4" BorderThickness="1,1,1,1" Margin="0,2,0,0"
|
||||
Background="{DynamicResource Ubisam.Brush.Sidebar.Background}"
|
||||
BorderBrush="{DynamicResource Ubisam.Brush.Input.Border}">
|
||||
<Grid>
|
||||
|
||||
@ -241,6 +241,15 @@ namespace MergeHub.Views
|
||||
// Ctrl+휠로 코드 글자 크기(11차 F-5). 휠 한 칸에 1씩. 목록 · 편집기의 스크롤보다 먼저 가로챈다.
|
||||
PreviewMouseWheel += (_, e) =>
|
||||
{
|
||||
// Shift+휠은 가로로(2026-10-01 사용자 요청 - VS · 브라우저와 같은 손버릇). 가로 휠(틸트)과 같은 길로 보낸다 -
|
||||
// 마우스가 놓인 칸이 움직이고 나머지는 지금처럼 따라온다. 휠을 아래로 굴리면 오른쪽으로 간다.
|
||||
if (Keyboard.Modifiers == ModifierKeys.Shift)
|
||||
{
|
||||
var step = -e.Delta / 120.0 * 48;
|
||||
if (ScrollSourcePanes(step) || ScrollEditor(step)) e.Handled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Keyboard.Modifiers != ModifierKeys.Control || DataContext is not HomeViewModel vm) return;
|
||||
var command = e.Delta > 0 ? vm.FontBiggerCommand : vm.FontSmallerCommand;
|
||||
_scrollDriver = MergeLine.TextPane.Local; // 확대 뒤에는 BASE 를 LOCAL 에 맞춘다
|
||||
|
||||
@ -68,6 +68,14 @@ namespace MergeHub.Views
|
||||
// Ctrl+휠로 글자 크기(파일 비교 F-5 와 같은 손버릇).
|
||||
PreviewMouseWheel += (_, e) =>
|
||||
{
|
||||
// Shift+휠은 가로로(2026-10-01 사용자 요청, 파일 비교와 같게). 휠을 아래로 굴리면 오른쪽으로.
|
||||
if (Keyboard.Modifiers == ModifierKeys.Shift)
|
||||
{
|
||||
Editor.ScrollToHorizontalOffset(Math.Max(0, Editor.HorizontalOffset - e.Delta / 120.0 * 48));
|
||||
e.Handled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (Keyboard.Modifiers != ModifierKeys.Control) return;
|
||||
var size = Editor.FontSize + (e.Delta > 0 ? 1 : -1);
|
||||
Editor.FontSize = Math.Max(8, Math.Min(28, size));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user