MKV 화면 맨 위 줄: 다른 언어에서 버튼 글이 잘리던 것 (61)
줄이기 순서 (제목 → 버튼 글 → …) 를 정할 때 버튼 너비를 한국어 글로 잰 고정 값으로 셈해, 글이 긴 일본어
("字幕作成 & MKV 作成") 에서는 줄이기 전에 잘렸다 (S10 Ultra 가로). 지금 언어의 글 너비를 재어 차이를 더한다
(한국어는 그대로). 캡처 시험: 실제 서비스로 일본어 1644 · 1480 · 1280 · 1138 · 960, 체크 0 · 50개.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
묶음4
parent
c986690b3c
commit
26f6389f02
|
|
@ -8,6 +8,7 @@ import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:integration_test/integration_test.dart';
|
import 'package:integration_test/integration_test.dart';
|
||||||
import 'package:jj_mkvmaker/app/app_controller.dart';
|
import 'package:jj_mkvmaker/app/app_controller.dart';
|
||||||
import 'package:jj_mkvmaker/app/i18n_controller.dart';
|
import 'package:jj_mkvmaker/app/i18n_controller.dart';
|
||||||
|
import 'package:jj_mkvmaker/core/models.dart';
|
||||||
import 'package:jj_mkvmaker/main.dart';
|
import 'package:jj_mkvmaker/main.dart';
|
||||||
import 'package:jj_mkvmaker/platform/windows/desktop_storage_service.dart';
|
import 'package:jj_mkvmaker/platform/windows/desktop_storage_service.dart';
|
||||||
import 'package:jj_mkvmaker/platform/windows/process_media_tool.dart';
|
import 'package:jj_mkvmaker/platform/windows/process_media_tool.dart';
|
||||||
|
|
@ -78,18 +79,26 @@ void main() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 61: 일본어 가로 (태블릿 크기) 에서 맨 위 버튼 글이 잘리는지 - 첫 화면 (MKV) 과 각 화면의 맨 위 줄
|
// 61: 일본어 가로 (태블릿 크기) 에서 맨 위 버튼 글이 잘리는지 - MKV 첫 화면의 맨 위 줄.
|
||||||
for (final size in [const Size(1280, 800), const Size(1138, 712), const Size(960, 600)]) {
|
// 실제 서비스 (AI 자막 · 플레이어 버튼이 보이게), 체크 0개 · 50개 ("(50)" 이 붙으면 더 좁다). S10 Ultra 가로 ≈ 1480 · 앱 크기 90% ≈ 1644
|
||||||
testWidgets('61: 일본어 가로 ${size.width.toInt()}x${size.height.toInt()} - 맨 위 버튼', (t) async {
|
for (final (w, h) in [(1644, 1027), (1480, 924), (1280, 800), (1138, 712), (960, 600)]) {
|
||||||
t.view.physicalSize = size;
|
for (final checked in [0, 50]) {
|
||||||
t.view.devicePixelRatio = 1;
|
testWidgets('61: 일본어 가로 ${w}x$h · 체크 $checked - 맨 위 버튼', (t) async {
|
||||||
addTearDown(t.view.reset);
|
t.view.physicalSize = Size(w.toDouble(), h.toDouble());
|
||||||
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
t.view.devicePixelRatio = 1;
|
||||||
await t.runAsync(() => i18n.apply('ja', save: false));
|
addTearDown(t.view.reset);
|
||||||
await t.runAsync(() => t.pumpWidget(RepaintBoundary(key: shotKey, child: JjMkvMakerApp(controller: c, navigatorKey: navKey))));
|
final c = AppController(PlatformServices.create());
|
||||||
await settle(t, 20);
|
for (var i = 0; i < checked; i++) {
|
||||||
await shot(t, 'i18n_ja_home_${size.width.toInt()}');
|
final v = VideoItem(p.join(Directory.systemTemp.path, 'jj_i18n_none', 'v$i.mp4'));
|
||||||
await t.runAsync(() => i18n.apply('ko', save: false));
|
c.videos.add(v);
|
||||||
});
|
c.checked.add(v);
|
||||||
|
}
|
||||||
|
await t.runAsync(() => i18n.apply('ja', save: false));
|
||||||
|
await t.runAsync(() => t.pumpWidget(RepaintBoundary(key: shotKey, child: JjMkvMakerApp(controller: c, navigatorKey: navKey))));
|
||||||
|
await settle(t, 20);
|
||||||
|
await shot(t, 'i18n_ja_home_${w}_c$checked');
|
||||||
|
await t.runAsync(() => i18n.apply('ko', save: false));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'dart:math' as math;
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
|
@ -216,15 +217,23 @@ class _TopBar extends StatelessWidget {
|
||||||
var title = true, leftText = true, rightText = true, usage = c.usage != null, jobText = true;
|
var title = true, leftText = true, rightText = true, usage = c.usage != null, jobText = true;
|
||||||
// 아주 좁을 때: 다운로드 상자 숨김 (왼쪽 공통 버튼으로 열 수 있음) → MKV 만들기도 아이콘만
|
// 아주 좁을 때: 다운로드 상자 숨김 (왼쪽 공통 버튼으로 열 수 있음) → MKV 만들기도 아이콘만
|
||||||
var dlBox = downloads != null, mkvText = true;
|
var dlBox = downloads != null, mkvText = true;
|
||||||
// 각 부분의 너비 (실제 화면에서 잰 값)
|
// 각 부분의 너비 (실제 화면에서 잰 값 - 한국어 글 기준)
|
||||||
|
// 61: 다른 언어는 버튼 글이 더 길 수 있어 (일본어 "字幕作成 & MKV 作成") 그 차이를 재어 더한다 - 안 하면 줄이기 전에 잘렸다
|
||||||
|
final style = Theme.of(context).textTheme.labelLarge ?? const TextStyle(fontSize: 14);
|
||||||
|
double textW(String s) => (TextPainter(text: TextSpan(text: s, style: style), textDirection: TextDirection.ltr, maxLines: 1)
|
||||||
|
..layout())
|
||||||
|
.width;
|
||||||
|
double more(String ko) => uiLanguage == 'ko' ? 0 : math.max(0, textW(tr(ko).replaceAll('{0}', '').replaceAll('{1}', '')) - textW(ko.replaceAll('{0}', '').replaceAll('{1}', '')));
|
||||||
|
final leftMore = more('동영상 추가') + (hasAi ? more('자막 만들기{0}') + more('자막 만들기 & MKV 만들기{0}') : 0);
|
||||||
|
final playMore = more('선택한 파일 재생{0}'), mkvMore = more('MKV 만들기{0}{1}'), outMore = more('결과 폴더');
|
||||||
// 좁은 화면: 이동 버튼 · 설정 · 종료는 첫 줄에 있으므로 둘째 줄 (가운데 도구) 만 잰다
|
// 좁은 화면: 이동 버튼 · 설정 · 종료는 첫 줄에 있으므로 둘째 줄 (가운데 도구) 만 잰다
|
||||||
double need() =>
|
double need() =>
|
||||||
(compact ? 0 : 8 + appBarRightPadding + AppNavButtons.width + 8) + (title ? 126 : 0) + 24 +
|
(compact ? 0 : 8 + appBarRightPadding + AppNavButtons.width + 8) + (title ? 126 : 0) + 24 +
|
||||||
(leftText ? 153 + (hasAi ? 161 + 298 : 0) : 40 + (hasAi ? 96 : 0)) + 8 +
|
(leftText ? 153 + (hasAi ? 161 + 298 : 0) + leftMore : 40 + (hasAi ? 96 : 0)) + 8 +
|
||||||
(c.busy ? (jobText ? 350 : 60) : 0) +
|
(c.busy ? (jobText ? 350 : 60) : 0) +
|
||||||
(hasPlayer ? (rightText ? 201 : 48) : 0) +
|
(hasPlayer ? (rightText ? 201 + playMore : 48) : 0) +
|
||||||
(mkvText ? 166 + (c.busy && jobText ? 60 : 0) : 48) +
|
(mkvText ? 166 + mkvMore + (c.busy && jobText ? 60 : 0) : 48) +
|
||||||
(rightText ? 166 : 48) + // 결과 폴더
|
(rightText ? 166 + outMore : 48) + // 결과 폴더
|
||||||
(dlBox ? 162 : 0) +
|
(dlBox ? 162 : 0) +
|
||||||
(compact ? 0 : (usage ? 220 : 0) + 96 + 92) +
|
(compact ? 0 : (usage ? 220 : 0) + 96 + 92) +
|
||||||
(c.checked.isEmpty ? 0 : 3 * 26) +
|
(c.checked.isEmpty ? 0 : 3 * 26) +
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue