11차 F-5: 코드 글자 크기 조절(8~24)
- 한 값을 모든 모니터에(모니터 배율은 플랫폼), 코드 칸만(사용자 결정) - CodeFontMetrics: 줄 높이 · 번호 칸 · 여백 단추를 같은 비율로, 12 에서 지금 값 그대로 - 화면은 DynamicResource 한 벌, MergeLine.MinimumRowHeight 도 따라감 - Ctrl+휠 · Ctrl++/- · Ctrl+0 · 설정 "보기 > 코드 글자 크기" · 상태 줄 글자 N - 줄 번호 기준선을 코드와 맞춤 - FontTest 110 · ShortcutTest +14(1,538건) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
bc97a2d2e5
commit
a7b4a728d3
@ -163,6 +163,7 @@ A-1 에서 값으로 확인한 것 — 지운 파일은 "삭제되어 건너뜀
|
||||
- F-2: [이 메서드 반영](C# · C/C++, 클래스 멤버 통째, 단추 아래 한 줄에 잡은 범위 · 못 잡은 까닭), 덩어리 · 메서드 반영은 주석 한 줄 · 로그 한 줄 · Undo 한 번. 매뉴얼의 반영 단추 설명에. 숫자 23벌 1,395건.
|
||||
- F-3: 매뉴얼 "탐색기에서 열기" — 여러 개를 골라 보내면 앞의 둘(3개 이상은 알림), 폴더 둘은 바로 폴더 비교, 260자 넘는 경로는 열지 못함(알림), 배포 묶음을 옮겨도 켜면 보내기 바로가기가 따라옴, 설치 파일 필요 없음. 알아 둘 한계에 "떠 있어도 새 창". 숫자 23벌 1,411건.
|
||||
- F-4: 매뉴얼 파일 비교 화면 — [ACTIONS 감추기] · F9, 아래 탭 줄 [탭 접기] · 띠 · F11(플랫폼), 단축키 표에 F9 · F11. 숫자 23벌 1,414건 · 플랫폼 31건.
|
||||
- F-5: 매뉴얼 설정 표 "보기 > 코드 글자 크기", 파일 비교 화면 Ctrl+휠 · Ctrl++/- · Ctrl+0 · 상태 줄 `글자 N`, 단축키 표. 숫자 24벌 1,538건.
|
||||
|
||||
## B-1. 배포 묶음을 다시 만들고 꼭 필요한 파일을 가림 (2026-09-22, 완료)
|
||||
|
||||
@ -691,6 +692,40 @@ libgit2 의 다듬기(`PrettifyMessages`)를 켜면 **손대지 않은 뒤 커
|
||||
- ~~플랫폼 배포~~ — 사용자 "배포해줘" 뒤 `publish-platform.ps1`(16:22, 경고 0 · 오류 0, 48개 가운데 Core · Shell · README 셋 바뀜). MergeHub Debug 를 다시 빌드해 두 파일 해시가 배포본과 같음, 배포본으로 [탭 접기] → 24px 띠 → 띠로 펴기 확인(`f4-deployed.ps1`, 화면 설정 · MergeHub 설정 바이트 그대로 되돌림).
|
||||
- F-6(넓게 보기)에서 몇 줄이 늘었는지 1920 × 1080 기준으로 다시 잰다.
|
||||
|
||||
## F-5. 코드 글자 크기 조절 (2026-09-22, 완료)
|
||||
|
||||
사용자: "모니터 해상도와 관계없이 모든 모니터에 적용될 수 있도록 하면 좋겠는데".
|
||||
|
||||
### 먼저 본 것
|
||||
|
||||
- 코드 칸은 `Consolas 12` · 줄 높이 20 으로 박혀 있었다 — 행 템플릿 넷 · 편집기 · `CodeLineHeight` 리소스(StaticResource) · `MergeLine.MinimumRowHeight = 20` 상수. 여백도 번호 46(LOCAL 은 표식 6 + 번호 40) + 단추 20 = 66, 단추 높이 14 · 글자 9 로 박혀 있어 글자만 키우면 번호가 잘리고, 줄이면 단추가 줄보다 커지고 행이 20 아래로 줄지 않는다.
|
||||
- 플랫폼은 PerMonitorV2 라 WPF 단위(1/96 인치)의 크기는 창이 있는 모니터의 Windows 배율에 맞춰 다시 그려진다.
|
||||
|
||||
### 정한 것 (2026-09-22 사용자)
|
||||
|
||||
**한 값을 모든 모니터에**(모니터 배율은 플랫폼이 맞춤), **코드 칸만**(앱 전체는 이미 UI Setting 화면 배율), **Ctrl+휠 · Ctrl++/- · Ctrl+0 + 설정**, 8~24.
|
||||
|
||||
### 만든 것
|
||||
|
||||
- `CodeFontMetrics`(새) — 글자 크기 하나에서 줄 높이 · 여백 · 번호 칸 · 좁은 번호 칸 · 표식 · 단추 칸 · 단추 높이 · 단추 글자를 같은 비율로. 12 에서 지금 값과 정확히 같다(20 · 66 · 46 · 40 · 6 · 20 · 14 · 9).
|
||||
- 화면: 이 값들을 **DynamicResource** 로(행 템플릿 넷 · 편집기 · 줄 컨테이너 · 편집기 여백), `ApplyCodeFont` 가 한 벌로 갈아 끼운다. `MergeLine.MinimumRowHeight` 를 설정할 수 있는 값으로 바꾸고 바뀌면 모든 행을 다시 잰다.
|
||||
- 줄 번호에 코드와 같은 줄 높이 규칙(`LineHeight` · `BlockLineHeight`) — 원래 번호가 코드보다 몇 px 위에 떠 있었는데(12 에서 약 6px), 글자를 키우면 그만큼 커져 24 에서 눈에 띄었다. 이제 기준선이 같다.
|
||||
- 설정 "보기 > 코드 글자 크기 (8~24, 기본 12)"(`CodeFontSize`). 바꿀 때마다 저장, 설정 화면에서 바꾸고 돌아오면 따라감. 단축키 Ctrl+= · Ctrl+숫자판 + · Ctrl+- · Ctrl+숫자판 - · Ctrl+0 · Ctrl+숫자판 0, Ctrl+휠. 상태 줄 커서 위치 옆에 기본이 아닐 때만 `글자 14`(누르면 기본).
|
||||
|
||||
### 확인한 것
|
||||
|
||||
- 하네스 **FontTest**(새, 110건 — 8~24 모든 크기에서 여백 합 · 단추 ≤ 줄 · 번호 다섯 자리 · 정수 줄 높이, 끝에서 멈춤, NaN · 0 은 기본) · ShortcutTest +14(85건 — 새 키 · 수식키 없는 +/- 는 편집기 몫). 24벌 **1,538건** · 빌드 경고 0 · 오류 0.
|
||||
- 화면(`f5-verify.ps1`, 1440p · 150%, 코드 칸만 창 그림(PrintWindow)으로 — 다른 창이 찍히지 않게):
|
||||
|
||||
| 크기 | 두 칸 행 높이(BASE · LOCAL) | 네 칸 행 높이(Mine · BASE · REMOTE · MERGED) | 여백 단추 |
|
||||
|---|---|---|---|
|
||||
| 8 | 19 · 20 번갈아(13 DIP × 1.5) — 두 칸 같음 | 넷 모두 같은 순서로 19 · 20 | 행 안 |
|
||||
| 12 | 30 | — | 행 안 |
|
||||
| 24 | 60 | 넷 모두 60 | 행 안 |
|
||||
|
||||
- 상태 줄 `글자 8` · `글자 24`, 12 는 비움. 그림: 줄 번호 · 여백 단추 · 코드 · 편집기 글자가 행마다 맞음(24 에서 번호가 뜨던 것을 고친 뒤 다시 찍음).
|
||||
- **키 시험은 못 함** — 시험 도구가 앱 창을 앞으로 올리지 못했다(사용 중인 다른 창이 있으면 Windows 가 막는다). 키 → 명령은 ShortcutTest, 설정 → 화면은 위 표로 확인. Ctrl+휠 · 키로 바꾼 값이 남는지는 사용자가 한 번 눌러 보는 것으로.
|
||||
|
||||
## F-12. C# 코드 스타일 맞춤의 기본값을 AURORA 로 (2026-09-18, 완료)
|
||||
|
||||
사용자: "기본값은 원본형태를 따르고 C#인 경우에 AURORA 스타일로 하자" → 물어서 정한 것은 **제품 기본값 AURORA · C# 파일만 · 저장 동작은 지금 그대로**(켜져 있으면 저장도 그 스타일로 쓴다).
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
| 날짜 | 항목 | 커밋 |
|
||||
|---|---|---|
|
||||
| 2026-09-22 | **11차 F-5 (추가 요청)** — 코드 칸 글자 크기 8~24(기본 12). 한 값을 모든 모니터에(사용자 결정 — 모니터마다 다른 Windows 배율은 플랫폼 PerMonitorV2 가 맞춤), 코드 칸만. `CodeFontMetrics` 가 줄 높이 · 번호 칸 · 여백 단추를 같은 비율로 내고(12 에서 지금 값 그대로) 화면이 DynamicResource 로 한 벌 갈아 끼움, `MergeLine.MinimumRowHeight` 도 따라감. Ctrl+휠 · Ctrl++/- · Ctrl+0 · 설정 "보기 > 코드 글자 크기", 상태 줄 `글자 N`. 줄 번호가 코드보다 몇 px 위에 뜨던 것(24 에서 커짐)도 같은 줄 높이 규칙으로 맞춤. 8 · 12 · 24 에서 네 칸 행 높이 같음. FontTest 110 · ShortcutTest +14(1,538건) | 아래 |
|
||||
| 2026-09-22 | **11차 F-4 (추가 요청)** — 파일 비교 오른쪽 ACTIONS 칸을 감추는 단추 · F9(사용자 결정). 감추면 칸과 구분선 폭을 0 으로 해 코드 칸이 넓어지고, 펴면 끌어 둔 폭 그대로. 설정 `ActionsHidden` 에 기억. 감춘 채 Ctrl+S · Alt+←/→ 그대로. **덧(사용자 요청)**: 아래 탭 줄 접기 — 플랫폼에 [탭 접기] · 띠 · F11 을 넣음(플랫폼 changelog 참고, 사용자 확인 뒤 배포 09-22 16:22). 1440p 150% 에서 코드 칸 폭 +163px · 높이 +71px. ShortcutTest +3 · 플랫폼 PlatformCfgTest +7 | 아래 |
|
||||
| 2026-09-22 | **11차 F-3 뒤 (사용자 발견)** — 탐색기에서 폴더 둘을 보내면 왼쪽 칸이 설정의 기본 저장소(`plain-compare`)로 덮여 비교가 "왼쪽만" 투성이였다. `FolderViewModel` 이 넘어온 요청을 받은 뒤 "열어 둔 저장소를 왼쪽 기본값으로" 가 덮어쓴 것(비교는 비동기라 덮인 값을 읽음) — 기본값을 먼저, 요청을 나중에. 켤 때 받은 인자를 파일 로그에 남김. 앞선 시험은 로그만 보고 칸 값을 제대로 읽지 않아 지나쳤다 | c35280a |
|
||||
| 2026-09-22 | **11차 F-3 (추가 요청)** — 탐색기 [보내기] 가 여러 개를 어떻게 넘기는지 셸의 같은 길(바로가기에 Drop)로 일곱 경우를 잼: **프로세스 하나에 인자로 모두**, 폴더 둘은 창 하나에서 폴더 비교까지 됨. 고친 것(사용자 결정): 3개 이상은 앞의 둘 + 알림(예전엔 말없이 버림), 260자 넘는 경로(탐색기가 8.3 이름으로 넘기고 net48 이 긴 이름으로 펼쳐 못 찾음 — 예전엔 아무것도 안 열림)는 열지 않고 까닭 알림, 알림은 이름 창 뒤로 지나가지 않게 본 창이 활성이 된 뒤에. 배포 묶음을 옮기면 켤 때 보내기 바로가기를 지금 실행 파일로 고침(등록한 사람만 · 바로가기 파일만 · 레지스트리 안 씀). 설치 파일 필요 없음 확인. 떠 있을 때 새 창은 그대로(플랫폼 일). ArgsTest +16(1,411건) | 아래 |
|
||||
|
||||
@ -374,7 +374,7 @@
|
||||
| **완료** | F-2 메서드 단위로 골라 반영 — [이 메서드 반영](C# + C/C++, 클래스 멤버 전부 · 사용자 결정), 캐럿이 놓인 멤버를 반영해 올 쪽에서 중괄호 짝으로 잡음(`MemberRanges` — 문자열 · 주석 · raw · `#if` 갈래에 안 속음, 못 잡으면 단추 끄고 까닭 한 줄). 덩어리 · 메서드 반영은 주석 한 줄(메서드 이름 위) · 로그 한 줄 · Undo 한 번 — 덩어리가 줄마다 주석을 달던 것도 고침. 메서드 반영 = 같은 줄 줄 단위 반영 바이트 같음. MemberTest 83건(C# 29 · C++ 13 멤버) · 1,395건 |
|
||||
| **완료** | F-3 탐색기 [보내기] 로 폴더 두 개 바로 비교 — 탐색기는 여러 개를 프로세스 하나에 인자로 모두 넘김(일곱 경우 값으로 잼), 폴더 둘은 창 하나에서 폴더 비교까지. 사용자 결정대로 3개 이상은 앞의 둘 + 알림, 260자 넘는 경로(탐색기가 8.3 이름으로 넘김 · net48 이 못 찾음)는 열지 않고 알림, 옮긴 배포 묶음은 켤 때 보내기 바로가기를 저절로 고침(바로가기 파일만 · 레지스트리 안 씀), 떠 있을 때는 새 창 그대로. 설치 파일 필요 없음. ArgsTest +16 · 1,411건. **사용자가 실제 탐색기에서 찾은 것**: 보낸 왼쪽 폴더를 기본 저장소가 덮어써 "왼쪽만" 투성이 → 기본값을 먼저 두고 요청을 나중에 받게 고침, 켤 때 받은 인자를 파일 로그에 남김 |
|
||||
| **완료** | F-4 ACTIONS 칸 감추기(단추 · F9, 끌어 둔 폭 기억, 감춰도 Ctrl+S · Alt+←/→ 그대로) + **덧: 아래 탭 줄 접기**(사용자 요청 — 플랫폼 [탭 접기] · 16 DIP 띠 · F11, 그 항목만 기억, 다른 소비 프로그램도 쓰되 기본 펼침). 1440p 150% 에서 코드 칸 폭 +163px · 높이 +71px. 플랫폼 배포함(09-22 16:22) |
|
||||
| 대기 | F-5 글자 크기 조절 (지금은 Consolas 12 고정) |
|
||||
| **완료** | F-5 코드 글자 크기(8~24, 기본 12) — 한 값을 모든 모니터에(모니터 배율은 플랫폼), 코드 칸만, Ctrl+휠 · Ctrl++/- · Ctrl+0 + 설정 "보기 > 코드 글자 크기"(사용자 결정). 줄 높이 · 번호 칸 · 여백 단추가 같은 비율로(`CodeFontMetrics`, 12 에서 지금 값 그대로), 줄 번호 기준선을 코드와 맞춤. 8 · 12 · 24 에서 네 칸 행 높이 같음 · 단추 행 안. FontTest 110 · 1,538건. 키로 바꾸기는 사용자 확인 남음 |
|
||||
| 대기 | F-6 글자를 되도록 많이 보이게 — 넓게 보기 한 단추, 늘어난 줄 수로 잼 |
|
||||
| 대기 | F-7 어느 모니터에서든 제대로 뜨게 — 증상부터 적고 플랫폼 영향 확인 |
|
||||
| 대기 | F-8 저장한 뒤에도 되돌리기 (지금은 저장 네 길이 스택을 비움) |
|
||||
|
||||
@ -94,6 +94,15 @@ namespace MergeHub
|
||||
[DisplayName("커밋 조회 개수")]
|
||||
public int CommitPageSize { get; set; } = 200;
|
||||
|
||||
/// <summary>
|
||||
/// 코드 칸 글자 크기(11차 F-5). 코드 · 줄 번호 · 여백 단추 · 줄 높이가 같은 비율로 따라간다.
|
||||
/// 한 값이 모든 모니터에 쓰인다 - 모니터마다 다른 Windows 배율은 플랫폼이 맞춘다.
|
||||
/// 파일 비교 화면에서 Ctrl+휠 · Ctrl++/- · Ctrl+0 으로도 바꾸고, 그 값이 여기 남는다.
|
||||
/// </summary>
|
||||
[Category("보기")]
|
||||
[DisplayName("코드 글자 크기 (8~24, 기본 12)")]
|
||||
public int CodeFontSize { get; set; } = 12;
|
||||
|
||||
[Category("머지 주석")]
|
||||
[DisplayName("반영한 줄에 주석 남기기")]
|
||||
public bool InsertMergeComment { get; set; } = true;
|
||||
|
||||
@ -201,8 +201,15 @@ namespace MergeHub.Models
|
||||
/// <summary>읽기 전용 원본 칸들의 행 높이. 2-Way 에서는 RowHeight 와 같다.</summary>
|
||||
[ObservableProperty] private double _sourceRowHeight = MinimumRowHeight;
|
||||
|
||||
/// <summary>접히지 않은 보통 줄의 높이. HomeView 의 CodeLineHeight 와 같은 값이어야 한다.</summary>
|
||||
private const double MinimumRowHeight = 20;
|
||||
/// <summary>
|
||||
/// 접히지 않은 보통 줄의 높이. HomeView 의 CodeLineHeight 와 같은 값이어야 한다.
|
||||
/// 코드 글자 크기를 바꾸면 화면이 이 값을 함께 바꾸고 <see cref="RefreshRowHeight"/> 를 부른다(11차 F-5) -
|
||||
/// 예전에는 20 으로 박혀 있어 글자를 줄여도 행이 20 아래로 줄지 않았다.
|
||||
/// </summary>
|
||||
public static double MinimumRowHeight { get; set; } = 20;
|
||||
|
||||
/// <summary>줄 높이 기준이 바뀌었을 때 알던 글 높이로 다시 잰다.</summary>
|
||||
public void RefreshRowHeight() => ApplyRowHeights();
|
||||
|
||||
/// <summary>각 패널이 자기 글이 실제로 얼마나 높은지 알려 준다.</summary>
|
||||
public void ReportTextHeight(TextPane pane, double height)
|
||||
@ -217,6 +224,11 @@ namespace MergeHub.Models
|
||||
case TextPane.OriginalLocal: _originalLocalTextHeight = height; break;
|
||||
}
|
||||
|
||||
ApplyRowHeights();
|
||||
}
|
||||
|
||||
private void ApplyRowHeights()
|
||||
{
|
||||
if (IsThreeWay)
|
||||
{
|
||||
RowHeight = Math.Max(MinimumRowHeight, _localTextHeight);
|
||||
|
||||
57
src/MergeHub/Services/CodeFontMetrics.cs
Normal file
57
src/MergeHub/Services/CodeFontMetrics.cs
Normal file
@ -0,0 +1,57 @@
|
||||
using System;
|
||||
|
||||
namespace MergeHub.Services
|
||||
{
|
||||
/// <summary>
|
||||
/// 코드 칸 글자 크기 하나에서 나오는 크기들(11차 F-5). 줄 높이 · 줄 번호 칸 · 여백 단추가 같은 비율로 따라간다.
|
||||
///
|
||||
/// 기본 12 에서 지금까지의 값(줄 20 · 여백 66 = 번호 46 + 단추 20 · LOCAL 은 표식 6 + 번호 40 + 단추 20 · 단추 14 · 단추 글자 9)과
|
||||
/// 정확히 같다. 네 칸이 모두 이 값을 쓰므로 어느 크기에서나 행이 같은 눈높이에 온다.
|
||||
///
|
||||
/// 크기는 WPF 단위(1/96 인치)다. 모니터마다 Windows 배율은 플랫폼(PerMonitorV2)이 맞추므로
|
||||
/// 한 값이 어느 모니터에서나 같은 눈 크기로 보인다(사용자 결정 "한 값을 모든 모니터에").
|
||||
/// </summary>
|
||||
public sealed record CodeFontMetrics(
|
||||
double FontSize,
|
||||
double LineHeight,
|
||||
double GutterWidth,
|
||||
double NumberWidth,
|
||||
double NarrowNumberWidth,
|
||||
double MarkWidth,
|
||||
double ButtonWidth,
|
||||
double ButtonHeight,
|
||||
double ButtonFontSize)
|
||||
{
|
||||
public const double Default = 12;
|
||||
public const double Min = 8;
|
||||
public const double Max = 24;
|
||||
|
||||
public static double Clamp(double size) =>
|
||||
double.IsNaN(size) || size <= 0 ? Default : Math.Max(Min, Math.Min(Max, Math.Round(size)));
|
||||
|
||||
/// <summary>한 칸(1) 키우거나 줄인다. 끝에서는 그대로.</summary>
|
||||
public static double Step(double current, int delta) => Clamp(Math.Round(Clamp(current)) + delta);
|
||||
|
||||
public static CodeFontMetrics For(double size)
|
||||
{
|
||||
var f = Clamp(size);
|
||||
var k = f / Default;
|
||||
|
||||
var mark = Math.Round(6 * k);
|
||||
var narrow = Math.Round(40 * k);
|
||||
var button = Math.Round(20 * k);
|
||||
var number = mark + narrow;
|
||||
|
||||
return new CodeFontMetrics(
|
||||
FontSize: f,
|
||||
LineHeight: Math.Round(20 * k),
|
||||
GutterWidth: number + button,
|
||||
NumberWidth: number,
|
||||
NarrowNumberWidth: narrow,
|
||||
MarkWidth: mark,
|
||||
ButtonWidth: button,
|
||||
ButtonHeight: Math.Round(14 * k),
|
||||
ButtonFontSize: Math.Round(9 * k, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -35,6 +35,9 @@ namespace MergeHub.Services
|
||||
CloseFind,
|
||||
ShowHelp,
|
||||
ToggleActions,
|
||||
FontBigger,
|
||||
FontSmaller,
|
||||
FontReset,
|
||||
}
|
||||
|
||||
/// <summary>단축키 한 줄. 키 처리와 설명 창이 <b>둘 다 이 목록만</b> 본다.</summary>
|
||||
@ -147,6 +150,12 @@ namespace MergeHub.Services
|
||||
new ShortcutEntry(ShortcutAction.Recompare, Key.F5, ModifierKeys.None, "파일·보기", "다시 비교(새로고침)"),
|
||||
new ShortcutEntry(ShortcutAction.Recompare, Key.R, ModifierKeys.Control, "파일·보기", "다시 비교 (대체 키)"),
|
||||
new ShortcutEntry(ShortcutAction.Save, Key.S, ModifierKeys.Control, "파일·보기", "저장"),
|
||||
new ShortcutEntry(ShortcutAction.FontBigger, Key.OemPlus, ModifierKeys.Control, "파일·보기", "코드 글자 크게 (Ctrl+휠 위로도)"),
|
||||
new ShortcutEntry(ShortcutAction.FontBigger, Key.Add, ModifierKeys.Control, "파일·보기", "코드 글자 크게 (숫자판)"),
|
||||
new ShortcutEntry(ShortcutAction.FontSmaller, Key.OemMinus, ModifierKeys.Control, "파일·보기", "코드 글자 작게 (Ctrl+휠 아래로도)"),
|
||||
new ShortcutEntry(ShortcutAction.FontSmaller, Key.Subtract, ModifierKeys.Control, "파일·보기", "코드 글자 작게 (숫자판)"),
|
||||
new ShortcutEntry(ShortcutAction.FontReset, Key.D0, ModifierKeys.Control, "파일·보기", "코드 글자 기본 크기(12)"),
|
||||
new ShortcutEntry(ShortcutAction.FontReset, Key.NumPad0, ModifierKeys.Control, "파일·보기", "코드 글자 기본 크기 (숫자판)"),
|
||||
new ShortcutEntry(ShortcutAction.ToggleActions, Key.F9, ModifierKeys.None, "파일·보기", "오른쪽 ACTIONS 칸 감추기 · 보이기",
|
||||
"감춰도 저장 · 반영 · 차이 이동 키는 그대로 듣는다. 아래 탭 줄 접기(F11)는 플랫폼 몫이라 이 표에 없다."),
|
||||
|
||||
|
||||
@ -49,6 +49,7 @@ namespace MergeHub.ViewModels
|
||||
_workspace.CommitChosen += OnCommitChosenElsewhere;
|
||||
_isRulesOpen = _workspace.Settings.ActionsRulesExpanded;
|
||||
_isActionsHidden = _workspace.Settings.ActionsHidden;
|
||||
_codeFontSize = CodeFontMetrics.Clamp(_workspace.Settings.CodeFontSize);
|
||||
_reflowTimer.Tick += (_, _) => Reflow();
|
||||
|
||||
RefreshRecent();
|
||||
@ -409,6 +410,34 @@ namespace MergeHub.ViewModels
|
||||
/// <summary>단추 글자 - 누르면 무엇이 되는지와 키를 함께(RulesToggleLabel 과 같은 까닭).</summary>
|
||||
public string ActionsToggleLabel => IsActionsHidden ? "◀ ACTIONS 보이기 (F9)" : "ACTIONS 감추기 ▶ (F9)";
|
||||
|
||||
/// <summary>
|
||||
/// 코드 칸 글자 크기(11차 F-5, 8~24). 화면이 줄 높이 · 여백을 함께 맞춘다(<see cref="CodeFontMetrics"/>).
|
||||
/// 바꿀 때마다 설정에 남긴다 - 한 값이 모든 모니터에 쓰인다.
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
[NotifyPropertyChangedFor(nameof(CodeFontLabel))]
|
||||
private double _codeFontSize = CodeFontMetrics.Default;
|
||||
|
||||
/// <summary>상태 줄에 보일 글. 기본이면 비운다 - 늘 보이면 자리만 먹는다.</summary>
|
||||
public string CodeFontLabel => CodeFontSize == CodeFontMetrics.Default ? string.Empty : $"글자 {CodeFontSize:0}";
|
||||
|
||||
partial void OnCodeFontSizeChanged(double value)
|
||||
{
|
||||
var size = (int)CodeFontMetrics.Clamp(value);
|
||||
if (_workspace.Settings.CodeFontSize == size) return;
|
||||
_workspace.Settings.CodeFontSize = size;
|
||||
_workspace.SaveSettings();
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
private void FontBigger() => CodeFontSize = CodeFontMetrics.Step(CodeFontSize, +1);
|
||||
|
||||
[RelayCommand]
|
||||
private void FontSmaller() => CodeFontSize = CodeFontMetrics.Step(CodeFontSize, -1);
|
||||
|
||||
[RelayCommand]
|
||||
private void FontReset() => CodeFontSize = CodeFontMetrics.Default;
|
||||
|
||||
[RelayCommand]
|
||||
private void ToggleActions()
|
||||
{
|
||||
@ -3013,6 +3042,9 @@ namespace MergeHub.ViewModels
|
||||
/// </summary>
|
||||
public void RecompareIfSettingsChanged()
|
||||
{
|
||||
var font = CodeFontMetrics.Clamp(_workspace.Settings.CodeFontSize);
|
||||
if (font != CodeFontSize) CodeFontSize = font;
|
||||
|
||||
// C# 스타일은 원본부터 다시 읽어야 맞춰진다(편집 칸만 다시 정렬하면 BASE 가 옛 스타일로 남는다).
|
||||
if (_workspace.Settings.CSharpBraceStyle != _appliedStyle && Lines.Count > 0)
|
||||
{
|
||||
|
||||
@ -22,6 +22,18 @@
|
||||
<!-- 코드 한 줄의 높이. BASE/LOCAL 이 이 값을 똑같이 써야 두 패널의 같은 행이 같은 눈높이에 온다. -->
|
||||
<system:Double x:Key="CodeLineHeight">20</system:Double>
|
||||
|
||||
<!-- 코드 글자 크기와 그에 따르는 여백(11차 F-5). 기본 12 의 값이다 - 화면(ApplyCodeFont)이
|
||||
CodeFontMetrics 로 함께 바꾼다. DynamicResource 로 읽어야 바뀐 값이 바로 그려진다. -->
|
||||
<system:Double x:Key="CodeFontSize">12</system:Double>
|
||||
<GridLength x:Key="GutterWidth">66</GridLength>
|
||||
<GridLength x:Key="GutterNumberWidth">46</GridLength>
|
||||
<GridLength x:Key="GutterNarrowNumberWidth">40</GridLength>
|
||||
<GridLength x:Key="GutterMarkWidth">6</GridLength>
|
||||
<GridLength x:Key="GutterButtonWidth">20</GridLength>
|
||||
<system:Double x:Key="GutterButtonHeight">14</system:Double>
|
||||
<system:Double x:Key="GutterButtonFontSize">9</system:Double>
|
||||
<Thickness x:Key="EditorGutterMargin">66,0,0,0</Thickness>
|
||||
|
||||
<!-- BASE / LOCAL 하단 요약 칸 공통 높이. 두 패널의 코드 영역이 같은 크기여야 나란히 읽힌다. -->
|
||||
<system:Double x:Key="PaneFooterHeight">54</system:Double>
|
||||
|
||||
@ -113,7 +125,7 @@
|
||||
|
||||
<Style x:Key="Mono" TargetType="TextBlock">
|
||||
<Setter Property="FontFamily" Value="Consolas"/>
|
||||
<Setter Property="FontSize" Value="12"/>
|
||||
<Setter Property="FontSize" Value="{DynamicResource CodeFontSize}"/>
|
||||
</Style>
|
||||
|
||||
<!--
|
||||
@ -122,8 +134,8 @@
|
||||
워드랩일 때만 풀어 준다 - 그때는 줄마다 높이가 달라야 하기 때문이다.
|
||||
-->
|
||||
<Style x:Key="CodeLineItem" TargetType="ListBoxItem" BasedOn="{StaticResource {x:Type ListBoxItem}}">
|
||||
<Setter Property="Height" Value="{StaticResource CodeLineHeight}"/>
|
||||
<Setter Property="MinHeight" Value="{StaticResource CodeLineHeight}"/>
|
||||
<Setter Property="Height" Value="{DynamicResource CodeLineHeight}"/>
|
||||
<Setter Property="MinHeight" Value="{DynamicResource CodeLineHeight}"/>
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="Margin" Value="0"/>
|
||||
<Setter Property="VerticalContentAlignment" Value="Top"/>
|
||||
@ -143,10 +155,10 @@
|
||||
66 인 까닭은 LocalLineTemplate 에 적었다(6차 B-4). -->
|
||||
<Grid MinHeight="{Binding SourceRowHeight}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="66"/>
|
||||
<ColumnDefinition Width="{DynamicResource GutterWidth}"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Text="{Binding BaseNumberText}" Style="{StaticResource Mono}"
|
||||
<TextBlock Grid.Column="0" Text="{Binding BaseNumberText}" Style="{StaticResource Mono}" LineHeight="{DynamicResource CodeLineHeight}" LineStackingStrategy="BlockLineHeight"
|
||||
Foreground="{DynamicResource Ubisam.Brush.Muted}" TextAlignment="Right"
|
||||
VerticalAlignment="Top" Margin="0,0,8,0"/>
|
||||
<Border Grid.Column="1" Padding="2,0"
|
||||
@ -160,8 +172,8 @@
|
||||
RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
TextWrapping="{Binding WrapMode,
|
||||
RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
FontFamily="Consolas" FontSize="12"
|
||||
LineHeight="{StaticResource CodeLineHeight}"
|
||||
FontFamily="Consolas" FontSize="{DynamicResource CodeFontSize}"
|
||||
LineHeight="{DynamicResource CodeLineHeight}"
|
||||
LineStackingStrategy="BlockLineHeight"
|
||||
VerticalAlignment="Top"
|
||||
SizeChanged="BaseText_SizeChanged">
|
||||
@ -182,17 +194,17 @@
|
||||
<DataTemplate x:Key="OriginalLocalLineTemplate">
|
||||
<Grid MinHeight="{Binding SourceRowHeight}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="46"/>
|
||||
<ColumnDefinition Width="20"/>
|
||||
<ColumnDefinition Width="{DynamicResource GutterNumberWidth}"/>
|
||||
<ColumnDefinition Width="{DynamicResource GutterButtonWidth}"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock Grid.Column="0" Text="{Binding OriginalLocalNumberText}" Style="{StaticResource Mono}"
|
||||
<TextBlock Grid.Column="0" Text="{Binding OriginalLocalNumberText}" Style="{StaticResource Mono}" LineHeight="{DynamicResource CodeLineHeight}" LineStackingStrategy="BlockLineHeight"
|
||||
Foreground="{DynamicResource Ubisam.Brush.Muted}" TextAlignment="Right"
|
||||
VerticalAlignment="Top" Margin="0,0,4,0"/>
|
||||
|
||||
<Button Grid.Column="1" Content="<" Padding="0" Margin="0" MinWidth="16"
|
||||
Height="14" MinHeight="14" FontSize="9" VerticalAlignment="Top"
|
||||
Height="{DynamicResource GutterButtonHeight}" MinHeight="{DynamicResource GutterButtonHeight}" FontSize="{DynamicResource GutterButtonFontSize}" VerticalAlignment="Top"
|
||||
Visibility="{Binding CanTakeLocal, Converter={StaticResource BoolToVis}}"
|
||||
Command="{Binding DataContext.TakeLocalLineCommand,
|
||||
RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
@ -210,8 +222,8 @@
|
||||
RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
TextWrapping="{Binding WrapMode,
|
||||
RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
FontFamily="Consolas" FontSize="12"
|
||||
LineHeight="{StaticResource CodeLineHeight}"
|
||||
FontFamily="Consolas" FontSize="{DynamicResource CodeFontSize}"
|
||||
LineHeight="{DynamicResource CodeLineHeight}"
|
||||
LineStackingStrategy="BlockLineHeight"
|
||||
VerticalAlignment="Top"
|
||||
SizeChanged="OriginalLocalText_SizeChanged">
|
||||
@ -232,17 +244,17 @@
|
||||
<DataTemplate x:Key="RemoteLineTemplate">
|
||||
<Grid MinHeight="{Binding SourceRowHeight}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="46"/>
|
||||
<ColumnDefinition Width="20"/>
|
||||
<ColumnDefinition Width="{DynamicResource GutterNumberWidth}"/>
|
||||
<ColumnDefinition Width="{DynamicResource GutterButtonWidth}"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock Grid.Column="0" Text="{Binding RemoteNumberText}" Style="{StaticResource Mono}"
|
||||
<TextBlock Grid.Column="0" Text="{Binding RemoteNumberText}" Style="{StaticResource Mono}" LineHeight="{DynamicResource CodeLineHeight}" LineStackingStrategy="BlockLineHeight"
|
||||
Foreground="{DynamicResource Ubisam.Brush.Muted}" TextAlignment="Right"
|
||||
VerticalAlignment="Top" Margin="0,0,4,0"/>
|
||||
|
||||
<Button Grid.Column="1" Content="<" Padding="0" Margin="0" MinWidth="16"
|
||||
Height="14" MinHeight="14" FontSize="9" VerticalAlignment="Top"
|
||||
Height="{DynamicResource GutterButtonHeight}" MinHeight="{DynamicResource GutterButtonHeight}" FontSize="{DynamicResource GutterButtonFontSize}" VerticalAlignment="Top"
|
||||
Visibility="{Binding CanTakeRemote, Converter={StaticResource BoolToVis}}"
|
||||
Command="{Binding DataContext.TakeRemoteLineCommand,
|
||||
RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
@ -260,8 +272,8 @@
|
||||
RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
TextWrapping="{Binding WrapMode,
|
||||
RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
FontFamily="Consolas" FontSize="12"
|
||||
LineHeight="{StaticResource CodeLineHeight}"
|
||||
FontFamily="Consolas" FontSize="{DynamicResource CodeFontSize}"
|
||||
LineHeight="{DynamicResource CodeLineHeight}"
|
||||
LineStackingStrategy="BlockLineHeight"
|
||||
VerticalAlignment="Top"
|
||||
SizeChanged="RemoteText_SizeChanged">
|
||||
@ -295,25 +307,25 @@
|
||||
MinHeight="{Binding RowHeight}"
|
||||
MouseLeftButtonDown="Gutter_MouseLeftButtonDown">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="6"/>
|
||||
<ColumnDefinition Width="40"/>
|
||||
<ColumnDefinition Width="20"/>
|
||||
<ColumnDefinition Width="{DynamicResource GutterMarkWidth}"/>
|
||||
<ColumnDefinition Width="{DynamicResource GutterNarrowNumberWidth}"/>
|
||||
<ColumnDefinition Width="{DynamicResource GutterButtonWidth}"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- 북마크 표식. 켜진 줄만 색 막대가 보인다. -->
|
||||
<Border Grid.Column="0" Width="4" HorizontalAlignment="Left" CornerRadius="1"
|
||||
Margin="1,3" VerticalAlignment="Top" Height="14"
|
||||
Margin="1,3" VerticalAlignment="Top" Height="{DynamicResource GutterButtonHeight}"
|
||||
Background="{DynamicResource Ubisam.Brush.Accent}"
|
||||
Visibility="{Binding IsBookmarked, Converter={StaticResource BoolToVis}}"/>
|
||||
|
||||
<TextBlock Grid.Column="1" Text="{Binding LocalNumberText}" Style="{StaticResource Mono}"
|
||||
<TextBlock Grid.Column="1" Text="{Binding LocalNumberText}" Style="{StaticResource Mono}" LineHeight="{DynamicResource CodeLineHeight}" LineStackingStrategy="BlockLineHeight"
|
||||
Foreground="{DynamicResource Ubisam.Brush.Muted}" TextAlignment="Right"
|
||||
VerticalAlignment="Top" Margin="0,0,4,0"
|
||||
ToolTip="더블클릭하면 북마크를 켜고 끕니다 (F2 로 이동)"/>
|
||||
|
||||
<Button Grid.Column="2" Content=">" Padding="0" Margin="0" MinWidth="16"
|
||||
Height="14" MinHeight="14" FontSize="9" VerticalAlignment="Top"
|
||||
Height="{DynamicResource GutterButtonHeight}" MinHeight="{DynamicResource GutterButtonHeight}" FontSize="{DynamicResource GutterButtonFontSize}" VerticalAlignment="Top"
|
||||
Visibility="{Binding CanTakeBase, Converter={StaticResource BoolToVis}}"
|
||||
Command="{Binding DataContext.TakeLineCommand,
|
||||
RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
@ -357,8 +369,8 @@
|
||||
RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
TextWrapping="{Binding WrapMode,
|
||||
RelativeSource={RelativeSource AncestorType=UserControl}}"
|
||||
FontFamily="Consolas" FontSize="12"
|
||||
LineHeight="{StaticResource CodeLineHeight}"
|
||||
FontFamily="Consolas" FontSize="{DynamicResource CodeFontSize}"
|
||||
LineHeight="{DynamicResource CodeLineHeight}"
|
||||
LineStackingStrategy="BlockLineHeight"
|
||||
VerticalAlignment="Top"
|
||||
SizeChanged="LocalText_SizeChanged">
|
||||
@ -1252,9 +1264,9 @@
|
||||
세로 스크롤 막대를 늘 띄워 두는 이유 - 나타났다 사라지면 글 너비가 바뀌어
|
||||
워드랩 접히는 자리가 아래층과 어긋난다.
|
||||
-->
|
||||
<TextBox x:Name="LocalEditor" Style="{x:Null}" Margin="66,0,0,0"
|
||||
FontFamily="Consolas" FontSize="12"
|
||||
TextBlock.LineHeight="{StaticResource CodeLineHeight}"
|
||||
<TextBox x:Name="LocalEditor" Style="{x:Null}" Margin="{DynamicResource EditorGutterMargin}"
|
||||
FontFamily="Consolas" FontSize="{DynamicResource CodeFontSize}"
|
||||
TextBlock.LineHeight="{DynamicResource CodeLineHeight}"
|
||||
TextBlock.LineStackingStrategy="BlockLineHeight"
|
||||
AcceptsReturn="True" AcceptsTab="True"
|
||||
TextWrapping="{Binding WrapMode,
|
||||
@ -1729,6 +1741,13 @@
|
||||
<!-- 왼쪽: 지금 어디 -->
|
||||
<StackPanel Grid.Column="0" Orientation="Horizontal" VerticalAlignment="Center">
|
||||
<TextBlock Text="{Binding CaretPosition}" Style="{StaticResource Mono}" FontSize="11"/>
|
||||
<!-- 11차 F-5: 기본(12)이 아닐 때만 보인다. 누르면 기본으로(Ctrl+0 과 같음). -->
|
||||
<TextBlock Text="{Binding CodeFontLabel}" FontSize="11" Margin="10,0,0,0" Cursor="Hand"
|
||||
Style="{StaticResource Muted}" ToolTip="코드 글자 크기 - Ctrl+휠 · Ctrl++/- 로 바꾸고, 누르거나 Ctrl+0 이면 기본(12)">
|
||||
<TextBlock.InputBindings>
|
||||
<MouseBinding MouseAction="LeftClick" Command="{Binding FontResetCommand}"/>
|
||||
</TextBlock.InputBindings>
|
||||
</TextBlock>
|
||||
<Border Width="1" Margin="10,1" Background="{DynamicResource Ubisam.Brush.Input.Border}"/>
|
||||
<!--
|
||||
차이 이동을 개수 바로 옆에 둔다(4차 C-5).
|
||||
|
||||
@ -238,6 +238,15 @@ namespace MergeHub.Views
|
||||
|
||||
DataContextChanged += OnDataContextChanged;
|
||||
|
||||
// Ctrl+휠로 코드 글자 크기(11차 F-5). 휠 한 칸에 1씩. 목록 · 편집기의 스크롤보다 먼저 가로챈다.
|
||||
PreviewMouseWheel += (_, e) =>
|
||||
{
|
||||
if (Keyboard.Modifiers != ModifierKeys.Control || DataContext is not HomeViewModel vm) return;
|
||||
var command = e.Delta > 0 ? vm.FontBiggerCommand : vm.FontSmallerCommand;
|
||||
if (command.CanExecute(null)) command.Execute(null);
|
||||
e.Handled = true;
|
||||
};
|
||||
|
||||
// 설정 화면에서 비교 규칙을 고치고 돌아오면 그때 다시 비교한다.
|
||||
IsVisibleChanged += (_, e) =>
|
||||
{
|
||||
@ -378,6 +387,7 @@ namespace MergeHub.Views
|
||||
now.ScrollToRowRequested += OnScrollToRowRequested;
|
||||
now.PropertyChanged += OnViewModelPropertyChanged;
|
||||
ApplyActionsHidden(now.IsActionsHidden);
|
||||
ApplyCodeFont(now.CodeFontSize);
|
||||
|
||||
// 편집기 글은 이 컨트롤이 들고 있고, ViewModel 은 필요할 때만 읽어 간다.
|
||||
// 바인딩으로 매 글자마다 문서 전체를 넘기면 큰 파일에서 눈에 띄게 느리다.
|
||||
@ -391,6 +401,12 @@ namespace MergeHub.Views
|
||||
/// </summary>
|
||||
private void OnViewModelPropertyChanged(object? sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
if (e.PropertyName == nameof(HomeViewModel.CodeFontSize) && sender is HomeViewModel fontVm)
|
||||
{
|
||||
ApplyCodeFont(fontVm.CodeFontSize);
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.PropertyName == nameof(HomeViewModel.IsActionsHidden) && sender is HomeViewModel hideVm)
|
||||
{
|
||||
ApplyActionsHidden(hideVm.IsActionsHidden);
|
||||
@ -456,6 +472,38 @@ namespace MergeHub.Views
|
||||
/// <summary>칸 폭을 사용자가 끌어 놓을 수 있는 세 칸.</summary>
|
||||
private ColumnDefinition[] PaneColumns => new[] { LocalColumn, BaseColumn, RemoteColumn };
|
||||
|
||||
/// <summary>
|
||||
/// 코드 칸 글자 크기를 화면에 건다(11차 F-5). 글자 · 줄 높이 · 줄 번호 칸 · 여백 단추 · 편집기 여백을
|
||||
/// <see cref="CodeFontMetrics"/> 한 벌로 바꾼다 - 넷 가운데 하나라도 따로 놀면 행이 어긋난다.
|
||||
/// 행 높이의 하한(<see cref="MergeLine.MinimumRowHeight"/>)도 같이 옮겨야 글자를 줄였을 때 행이 준다.
|
||||
/// </summary>
|
||||
private void ApplyCodeFont(double size)
|
||||
{
|
||||
var m = CodeFontMetrics.For(size);
|
||||
|
||||
Resources["CodeFontSize"] = m.FontSize;
|
||||
Resources["CodeLineHeight"] = m.LineHeight;
|
||||
Resources["GutterWidth"] = new GridLength(m.GutterWidth);
|
||||
Resources["GutterNumberWidth"] = new GridLength(m.NumberWidth);
|
||||
Resources["GutterNarrowNumberWidth"] = new GridLength(m.NarrowNumberWidth);
|
||||
Resources["GutterMarkWidth"] = new GridLength(m.MarkWidth);
|
||||
Resources["GutterButtonWidth"] = new GridLength(m.ButtonWidth);
|
||||
Resources["GutterButtonHeight"] = m.ButtonHeight;
|
||||
Resources["GutterButtonFontSize"] = m.ButtonFontSize;
|
||||
Resources["EditorGutterMargin"] = new Thickness(m.GutterWidth, 0, 0, 0);
|
||||
|
||||
if (MergeLine.MinimumRowHeight != m.LineHeight)
|
||||
{
|
||||
MergeLine.MinimumRowHeight = m.LineHeight;
|
||||
if (DataContext is HomeViewModel vm)
|
||||
{
|
||||
foreach (var line in vm.Lines) line.RefreshRowHeight();
|
||||
}
|
||||
}
|
||||
|
||||
Dispatcher.BeginInvoke(new Action(MatchTextWidths), System.Windows.Threading.DispatcherPriority.Loaded);
|
||||
}
|
||||
|
||||
/// <summary>감추기 전 ACTIONS 칸 폭. 구분선을 끌어 바꿔 뒀으면 그 폭으로 돌아온다.</summary>
|
||||
private GridLength _actionsWidth = new GridLength(214);
|
||||
|
||||
@ -942,6 +990,10 @@ namespace MergeHub.Views
|
||||
|
||||
case ShortcutAction.ToggleActions: return Run(vm.ToggleActionsCommand);
|
||||
|
||||
case ShortcutAction.FontBigger: return Run(vm.FontBiggerCommand);
|
||||
case ShortcutAction.FontSmaller: return Run(vm.FontSmallerCommand);
|
||||
case ShortcutAction.FontReset: return Run(vm.FontResetCommand);
|
||||
|
||||
case ShortcutAction.OpenFolderCompare:
|
||||
UbisamBase.Core.Modules.TabManager.Activate(ViewIds.Folder);
|
||||
return true;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user