78 lines
3.2 KiB
Dart
78 lines
3.2 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
import '../l10n/tr.dart';
|
|
import 'theme.dart';
|
|
|
|
/// 확인 창 하나 (E4 U7, 관리자 승인 10/22). 화면은 내용만 넘긴다.
|
|
///
|
|
/// 약속
|
|
/// - 돌려주는 값: [확인] 을 누른 때만 true. [취소] · Esc · 바깥 누르기 · 뒤로는 false.
|
|
/// - Enter = 첫 초점 단추. 되돌릴 수 없는 일 ([danger] 가 창을 열 때 true) 은 첫 초점이 [취소] (실수 막기),
|
|
/// 그 밖은 [확인] (관리자 결정 10/22).
|
|
/// - [cancelFirst] 를 주면 첫 초점을 따로 정한다 (빨강이 아니어도 되돌리기 어려운 일 - 루트 · 시스템 폴더 · 보관함 비밀번호 바꾸기는 true).
|
|
/// - [canConfirm] 이 false 인 동안 [확인] 은 꺼져 있다 (체크해야 켜짐 · 두 비밀번호가 같아야 켜짐 - 창 안에서 [set] 으로 다시 봄).
|
|
/// - [danger] 가 창 안에서 바뀌면 (예: "영구 삭제" 체크) [확인] 단추만 빨강으로 바뀐다. 첫 초점은 연 때 그대로.
|
|
/// - [title] · [body] · [confirmLabel] 은 창 안에서 [set] 으로 다시 그려진다 (체크 상자 등).
|
|
/// - 빨강은 테마의 위험 색 (JjColors.danger - 다른 지우기 단추와 같음). 글만 묻는 곳은 [confirmAction] (같은 창).
|
|
Future<bool> confirmDialog(
|
|
BuildContext context, {
|
|
required String Function() title,
|
|
required Widget Function(BuildContext ctx, StateSetter set) body,
|
|
required String Function() confirmLabel,
|
|
String? cancelLabel,
|
|
bool Function()? danger,
|
|
bool? cancelFirst,
|
|
bool Function()? canConfirm,
|
|
Widget? icon,
|
|
}) async {
|
|
final cancelAtOpen = cancelFirst ?? danger?.call() ?? false;
|
|
final ok = await showDialog<bool>(
|
|
context: context,
|
|
builder: (ctx) => StatefulBuilder(
|
|
builder: (ctx, set) {
|
|
final red = danger?.call() ?? false;
|
|
return AlertDialog(
|
|
scrollable: true,
|
|
icon: icon,
|
|
title: Text(title()),
|
|
content: body(ctx, set),
|
|
actions: [
|
|
TextButton(
|
|
autofocus: cancelAtOpen,
|
|
onPressed: () => Navigator.pop(ctx, false),
|
|
child: Text(cancelLabel ?? tr('취소')),
|
|
),
|
|
FilledButton(
|
|
autofocus: !cancelAtOpen,
|
|
style: red ? FilledButton.styleFrom(backgroundColor: JjColors.danger) : null,
|
|
onPressed: canConfirm?.call() ?? true ? () => Navigator.pop(ctx, true) : null,
|
|
child: Text(confirmLabel()),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
),
|
|
);
|
|
return ok == true;
|
|
}
|
|
|
|
/// 글만으로 묻는 확인 창 ([confirmDialog] 와 같은 창 - W DangerDialog 로 하나로 모음, 예전 confirm.dart).
|
|
/// 되돌리기 어려운 일 전에 한 번 묻는다 (46 · 47 등). [danger] 면 [확인] 이 빨강 · 첫 초점은 [취소]. 확인하면 true.
|
|
/// [cancel]: 하지 않는 쪽 단추 이름 (처음 값 "취소" - 확인 단추가 "… 취소" 면 헷갈리므로 바꾼다, 185)
|
|
Future<bool> confirmAction(
|
|
BuildContext context, {
|
|
required String title,
|
|
required String body,
|
|
required String ok,
|
|
bool danger = true,
|
|
String? cancel,
|
|
}) =>
|
|
confirmDialog(
|
|
context,
|
|
title: () => title,
|
|
body: (_, _) => Text(body),
|
|
confirmLabel: () => ok,
|
|
cancelLabel: cancel,
|
|
danger: () => danger,
|
|
);
|