120 lines
4.9 KiB
Dart
120 lines
4.9 KiB
Dart
import 'package:flutter/material.dart';
|
||
|
||
import '../app/app_controller.dart';
|
||
import '../app/settings.dart';
|
||
import 'settings_page.dart';
|
||
import 'theme.dart';
|
||
import '../l10n/tr.dart';
|
||
import 'app_bar/app_top_bar.dart';
|
||
import 'app_bar/app_nav_buttons.dart';
|
||
import 'app_bar/usage_view.dart';
|
||
|
||
export 'app_bar/app_nav_buttons.dart';
|
||
export 'app_bar/app_top_bar.dart';
|
||
export 'app_bar/swipe_nav.dart';
|
||
export 'app_bar/usage_view.dart';
|
||
|
||
/// 환경 설정 · 종료 버튼. 모든 화면의 위쪽 막대 맨 오른쪽에 같은 크기로 놓는다.
|
||
class AppActions extends StatelessWidget {
|
||
/// 직접 주지 않으면 [AppScope] 의 것을 쓴다
|
||
final AppController? c;
|
||
final VoidCallback? onExit;
|
||
|
||
/// 환경 설정 화면 자신: 설정 버튼을 "지금 여기" 로 표시하고 누를 수 없게
|
||
final bool onSettingsPage;
|
||
|
||
/// 창이 좁을 때 CPU · MEM · DISK 를 숨긴다 (버튼 자리는 그대로)
|
||
final bool showUsage;
|
||
|
||
const AppActions({super.key, this.c, this.onExit, this.onSettingsPage = false, this.showUsage = true});
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
final scope = AppScope.maybeOf(context);
|
||
final controller = c ?? scope?.controller;
|
||
final exit = onExit ?? scope?.onExit;
|
||
if (controller == null && exit == null) return const SizedBox();
|
||
final usage = controller?.usage;
|
||
final compact = isCompact(context);
|
||
if (compact) {
|
||
return Row(mainAxisSize: MainAxisSize.min, children: [
|
||
if (controller != null)
|
||
IconButton(
|
||
tooltip: tr('환경 설정'),
|
||
icon: Icon(onSettingsPage ? Icons.settings : Icons.settings_outlined,
|
||
color: onSettingsPage ? JjColors.accent : null),
|
||
onPressed: onSettingsPage
|
||
? null
|
||
: () => Navigator.push(context, MaterialPageRoute<void>(builder: (_) => SettingsPage(c: controller))),
|
||
),
|
||
PopupMenuButton<String>(
|
||
tooltip: tr('화면 크기 · 종료'),
|
||
icon: const Icon(Icons.more_vert),
|
||
onSelected: (v) {
|
||
final s = controller?.settings;
|
||
switch (v) {
|
||
case 'bigger' when s != null:
|
||
controller!.updateSettings((x) => x.display.scale = DisplaySettings.clampScale(s.display.scale + 0.1));
|
||
case 'smaller' when s != null:
|
||
controller!.updateSettings((x) => x.display.scale = DisplaySettings.clampScale(s.display.scale - 0.1));
|
||
case 'default' when s != null:
|
||
controller!.updateSettings((x) => x.display.scale = s.display.scaleDefault);
|
||
case 'exit':
|
||
exit?.call();
|
||
}
|
||
},
|
||
itemBuilder: (_) => [
|
||
if (controller != null) ...[
|
||
PopupMenuItem(
|
||
value: 'bigger',
|
||
child: ListTile(leading: const Icon(Icons.zoom_in), title: Text(tr('화면 크게')), dense: true)),
|
||
PopupMenuItem(
|
||
value: 'smaller',
|
||
child: ListTile(leading: const Icon(Icons.zoom_out), title: Text(tr('화면 작게')), dense: true)),
|
||
PopupMenuItem(
|
||
value: 'default',
|
||
child: ListTile(
|
||
leading: const Icon(Icons.fit_screen_outlined),
|
||
title: Text(trf('기본 크기 ({0}%)', [(controller.settings.display.scaleDefault * 100).round()])),
|
||
subtitle: Text(trf('지금 {0}%', [(controller.settings.display.scale * 100).round()])),
|
||
dense: true)),
|
||
],
|
||
if (exit != null) ...[
|
||
const PopupMenuDivider(),
|
||
PopupMenuItem(
|
||
value: 'exit',
|
||
child: ListTile(
|
||
leading: Icon(Icons.power_settings_new, color: JjColors.danger),
|
||
title: Text(tr('종료')),
|
||
dense: true)),
|
||
],
|
||
],
|
||
),
|
||
]);
|
||
}
|
||
return Row(mainAxisSize: MainAxisSize.min, children: [
|
||
// CPU · MEM: 변환 · AI 작업이 PC 를 얼마나 쓰는지 (PC 전체 기준)
|
||
if (usage != null && showUsage && !compact) UsageView(usage: usage),
|
||
// 화면 크기: − 100% +
|
||
if (controller != null) ScaleButtons(c: controller),
|
||
const SizedBox(width: 4),
|
||
if (controller != null)
|
||
IconButton(
|
||
tooltip: tr('환경 설정'),
|
||
icon: Icon(onSettingsPage ? Icons.settings : Icons.settings_outlined,
|
||
color: onSettingsPage ? JjColors.accent : null),
|
||
onPressed: onSettingsPage
|
||
? null
|
||
: () => Navigator.push(
|
||
context, MaterialPageRoute<void>(builder: (_) => SettingsPage(c: controller))),
|
||
),
|
||
if (exit != null)
|
||
IconButton(
|
||
tooltip: tr('종료'),
|
||
icon: Icon(Icons.power_settings_new, color: JjColors.danger),
|
||
onPressed: exit,
|
||
),
|
||
]);
|
||
}
|
||
}
|