diff --git a/integration_test/windows_i18n_shot_test.dart b/integration_test/windows_i18n_shot_test.dart index 2359cd4..61615fd 100644 --- a/integration_test/windows_i18n_shot_test.dart +++ b/integration_test/windows_i18n_shot_test.dart @@ -8,6 +8,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:integration_test/integration_test.dart'; import 'package:jj_mkvmaker/app/app_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/platform/windows/desktop_storage_service.dart'; import 'package:jj_mkvmaker/platform/windows/process_media_tool.dart'; @@ -78,18 +79,26 @@ void main() { }); } - // 61: 일본어 가로 (태블릿 크기) 에서 맨 위 버튼 글이 잘리는지 - 첫 화면 (MKV) 과 각 화면의 맨 위 줄 - for (final size in [const Size(1280, 800), const Size(1138, 712), const Size(960, 600)]) { - testWidgets('61: 일본어 가로 ${size.width.toInt()}x${size.height.toInt()} - 맨 위 버튼', (t) async { - t.view.physicalSize = size; - t.view.devicePixelRatio = 1; - addTearDown(t.view.reset); - final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService())); - 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_${size.width.toInt()}'); - await t.runAsync(() => i18n.apply('ko', save: false)); - }); + // 61: 일본어 가로 (태블릿 크기) 에서 맨 위 버튼 글이 잘리는지 - MKV 첫 화면의 맨 위 줄. + // 실제 서비스 (AI 자막 · 플레이어 버튼이 보이게), 체크 0개 · 50개 ("(50)" 이 붙으면 더 좁다). S10 Ultra 가로 ≈ 1480 · 앱 크기 90% ≈ 1644 + for (final (w, h) in [(1644, 1027), (1480, 924), (1280, 800), (1138, 712), (960, 600)]) { + for (final checked in [0, 50]) { + testWidgets('61: 일본어 가로 ${w}x$h · 체크 $checked - 맨 위 버튼', (t) async { + t.view.physicalSize = Size(w.toDouble(), h.toDouble()); + t.view.devicePixelRatio = 1; + addTearDown(t.view.reset); + final c = AppController(PlatformServices.create()); + for (var i = 0; i < checked; i++) { + final v = VideoItem(p.join(Directory.systemTemp.path, 'jj_i18n_none', 'v$i.mp4')); + 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)); + }); + } } } diff --git a/lib/ui/home_page.dart b/lib/ui/home_page.dart index c981379..4a4b885 100644 --- a/lib/ui/home_page.dart +++ b/lib/ui/home_page.dart @@ -1,3 +1,4 @@ +import 'dart:math' as math; import 'dart:async'; import 'dart:io'; @@ -216,15 +217,23 @@ class _TopBar extends StatelessWidget { var title = true, leftText = true, rightText = true, usage = c.usage != null, jobText = true; // 아주 좁을 때: 다운로드 상자 숨김 (왼쪽 공통 버튼으로 열 수 있음) → MKV 만들기도 아이콘만 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() => (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) + - (hasPlayer ? (rightText ? 201 : 48) : 0) + - (mkvText ? 166 + (c.busy && jobText ? 60 : 0) : 48) + - (rightText ? 166 : 48) + // 결과 폴더 + (hasPlayer ? (rightText ? 201 + playMore : 48) : 0) + + (mkvText ? 166 + mkvMore + (c.busy && jobText ? 60 : 0) : 48) + + (rightText ? 166 + outMore : 48) + // 결과 폴더 (dlBox ? 162 : 0) + (compact ? 0 : (usage ? 220 : 0) + 96 + 92) + (c.checked.isEmpty ? 0 : 3 * 26) +