트리 화살표 누르는 영역: 줄 높이 전체 · Android 는 폭 44 (189 보충)

189 로 접기 · 펼치기를 화살표로만 하게 되어, 아이콘 크기 (18px) 만 눌리던 것을 넓혔다 (관리자 지시: 손가락으로 누르기 충분히).
Windows 는 폭 20 그대로 (배치가 바뀌지 않게). 시험: Android 흉내로 영역 크기 · 가장자리를 눌러도 펼침.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fix_mkv
RyuJongJin 2026-10-11 19:50:21 +09:00
parent a7632a9bed
commit 7df43a750e
2 changed files with 34 additions and 5 deletions

View File

@ -4,6 +4,7 @@ import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:crypto/crypto.dart'; import 'package:crypto/crypto.dart';
import 'package:flutter/foundation.dart' show defaultTargetPlatform;
import 'package:flutter/gestures.dart' show kBackMouseButton, kForwardMouseButton; import 'package:flutter/gestures.dart' show kBackMouseButton, kForwardMouseButton;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -52,6 +53,10 @@ import 'explorer_bookmarks.dart';
/// ///
/// [rsync] 면 Rsync 화면: 같은 모양이지만 늘 좌우 두 창 · 폴더만 · 창마다 폴더 하나만 고른다. /// [rsync] 면 Rsync 화면: 같은 모양이지만 늘 좌우 두 창 · 폴더만 · 창마다 폴더 하나만 고른다.
/// 가운데 → (왼쪽 → 오른쪽) · ← (오른쪽 → 왼쪽) · ⇄ (둘 다 함께) 로 rsync, [모니터링] 에 실행한 것이 남는다. /// 가운데 → (왼쪽 → 오른쪽) · ← (오른쪽 → 왼쪽) · ⇄ (둘 다 함께) 로 rsync, [모니터링] 에 실행한 것이 남는다.
/// 189: 트리 화살표 칸의 폭 - 손가락으로 누르는 기기 (Android · iOS) 는 넓게 (줄 높이와 함께 누르는 영역)
double treeChevronWidth(TargetPlatform platform) =>
platform == TargetPlatform.android || platform == TargetPlatform.iOS ? 44 : 20;
class ExplorerPage extends StatefulWidget { class ExplorerPage extends StatefulWidget {
final AppController c; final AppController c;
final bool rsync; final bool rsync;
@ -3189,24 +3194,29 @@ class _ExplorerPageState extends State<ExplorerPage> {
color: isCurrent ? JjColors.accent : null, color: isCurrent ? JjColors.accent : null,
); );
// 트리의 펼치기 화살표 (따로 누름) final chevronWidth = treeChevronWidth(defaultTargetPlatform);
// 트리의 펼치기 화살표 (따로 누름). 189: 접기 · 펼치기는 이것으로만 하므로 줄 높이 전체를 누를 수 있게,
// 손가락으로 누르는 기기 (Android) 는 폭도 넓게
Widget chevron() => SizedBox( Widget chevron() => SizedBox(
width: 20, width: chevronWidth,
height: look.rowHeight,
child: e.isDir && !list && !row.isUp child: e.isDir && !list && !row.isUp
? (loading ? (loading
? const Center( ? const Center(
child: SizedBox(width: 12, height: 12, child: CircularProgressIndicator(strokeWidth: 1.5))) child: SizedBox(width: 12, height: 12, child: CircularProgressIndicator(strokeWidth: 1.5)))
: InkResponse( : InkResponse(
radius: 16, radius: chevronWidth / 2 + 4,
containedInkWell: false,
onTap: () => _toggle(pane, e), onTap: () => _toggle(pane, e),
child: Icon(open ? Icons.expand_more : Icons.chevron_right, size: 18, color: JjColors.textDim), child: Center(
child: Icon(open ? Icons.expand_more : Icons.chevron_right, size: 18, color: JjColors.textDim)),
)) ))
: null, : null,
); );
// 좁은 창 (폰 세로의 좌우 두 창) 에서 깊은 폴더: 들여쓰기는 이름 자리를 남기는 만큼만 (넘치지 않게) // 좁은 창 (폰 세로의 좌우 두 창) 에서 깊은 폴더: 들여쓰기는 이름 자리를 남기는 만큼만 (넘치지 않게)
Widget nameCell() => LayoutBuilder(builder: (context, box) { Widget nameCell() => LayoutBuilder(builder: (context, box) {
final fixed = (list ? 0 : 20) + (look.rich ? 64 : look.iconSize + 12) + 48.0; final fixed = (list ? 0 : chevronWidth) + (look.rich ? 64 : look.iconSize + 12) + 48.0;
final indent = list ? 0.0 : (row.depth * look.indent).clamp(0.0, (box.maxWidth - fixed).clamp(0.0, double.infinity)); final indent = list ? 0.0 : (row.depth * look.indent).clamp(0.0, (box.maxWidth - fixed).clamp(0.0, double.infinity));
return Row(children: [ return Row(children: [
SizedBox(width: indent), SizedBox(width: indent),

View File

@ -1,5 +1,6 @@
import 'dart:io'; import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
@ -497,6 +498,24 @@ void main() {
await tester.pump(); await tester.pump();
}); });
testWidgets('189: Android 는 트리 화살표를 손가락으로 누를 수 있게 넓게 (줄 높이 전체 · 폭 44)', (tester) async {
debugDefaultTargetPlatformOverride = TargetPlatform.android;
addTearDown(() => debugDefaultTargetPlatformOverride = null);
await open(tester);
final area = find.ancestor(of: find.descendant(
of: find.ancestor(of: find.text('sub'), matching: find.byType(InkWell)).first, matching: find.byIcon(Icons.chevron_right)),
matching: find.byType(InkResponse)).first;
final size = tester.getSize(area);
expect(size.width, greaterThanOrEqualTo(44));
expect(size.height, greaterThanOrEqualTo(34));
// 아이콘이 아니라 누르는 영역의 가장자리를 눌러도 펼친다
final r = tester.getRect(area);
await act(tester, () => tester.tapAt(Offset(r.left + 3, r.top + 3)));
await settle(tester, () => find.text('inner.txt').evaluate().isNotEmpty);
expect(find.text('inner.txt'), findsOneWidget);
debugDefaultTargetPlatformOverride = null;
});
test('74: 패턴 (* · ? · 여러 개 · 대소문자 무시)', () { test('74: 패턴 (* · ? · 여러 개 · 대소문자 무시)', () {
final re = globToRegExp('*.srt; ep??.mkv'); final re = globToRegExp('*.srt; ep??.mkv');
expect(['a.srt', 'A.SRT', 'ep01.mkv'].every(re.hasMatch), isTrue); expect(['a.srt', 'A.SRT', 'ep01.mkv'].every(re.hasMatch), isTrue);