JJ_MKVMaker/lib/ui/jj_header_row.dart

70 lines
3.0 KiB
Dart

/// 약속 (W 공용 위젯, 설계 7-2 JjTitleBar - 창 · 판 안의 제목 줄): 아이콘 · 제목 · 설명 · 단추들 → 한 줄.
/// 입력: 제목 ([titleLines] 줄까지 - 처음 1, 넘치면 "…") · 앞 아이콘 · 설명 (넓으면 제목 옆, 좁으면 제목 아래 2줄까지 - 숨기지 않음) · 단추들 (늘 오른쪽 끝에 다 보임) ·
/// [narrowBelow] (이 폭보다 좁으면 좁은 꼴) · [narrowActions] (좁을 때 쓸 단추들 - 예: 글 단추 → 같은 이름의 아이콘 단추) · 제목 글꼴.
/// 출력: Row (넘치지 않음 - 줄이는 것은 제목 · 설명뿐). 오류 없음.
/// 쓰는 곳: 다운로드 창 · 재생 목록 판 · 즐겨찾기 판 · 작업 현황 판 · 저장 공간 정리 창 · 화면 · 색 보정. 화면은 부르기만 한다.
/// 쪽 전체의 위 막대는 [jjTitleBar]
library;
import 'package:flutter/material.dart';
import 'theme.dart';
class JjHeaderRow extends StatelessWidget {
const JjHeaderRow({
super.key,
required this.title,
this.icon,
this.subtitle,
this.actions = const [],
this.narrowActions,
this.narrowBelow = 0,
this.style,
this.titleLines = 1,
});
final String title;
/// 제목 앞 아이콘 (크기 · 색은 부르는 쪽이 정한다)
final Widget? icon;
final String? subtitle;
final List<Widget> actions;
final List<Widget>? narrowActions;
final double narrowBelow;
/// 제목 글꼴 (null 이면 둘레의 글꼴 - 창 제목이면 창 제목 글꼴)
final TextStyle? style;
final int titleLines;
static TextStyle get _subStyle => TextStyle(fontSize: 12, color: JjColors.textDim);
// 좁은 꼴 · 설명이 없으면 LayoutBuilder 없이 (창 제목은 Flutter 가 내재 폭을 재는데, LayoutBuilder 는 그것을 못 한다)
@override
Widget build(BuildContext context) => narrowBelow <= 0 && subtitle == null
? _row(false, double.infinity)
: LayoutBuilder(builder: (context, box) => _row(box.maxWidth < narrowBelow, box.maxWidth));
Widget _row(bool narrow, double width) {
final head = Text(title, maxLines: titleLines, overflow: TextOverflow.ellipsis, style: style);
return Row(children: [
if (icon != null) ...[icon!, const SizedBox(width: 8)],
if (subtitle == null)
Expanded(child: head)
else if (narrow)
Expanded(
child: Column(mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [
head,
Text(subtitle!, maxLines: 2, overflow: TextOverflow.ellipsis, style: _subStyle),
]),
)
else ...[
// 제목은 쓰는 만큼 (반까지), 설명이 나머지 - 단추는 오른쪽 끝에 붙는다
ConstrainedBox(constraints: BoxConstraints(maxWidth: width / 2), child: head),
const SizedBox(width: 12),
Expanded(child: Text(subtitle!, maxLines: 1, overflow: TextOverflow.ellipsis, style: _subStyle)),
],
...(narrow ? narrowActions ?? actions : actions),
]);
}
}