Files
imajviewer/lib/widgets/custom_title_bar.dart
T
Alhan 168e087c8b
Build & Release / build-linux (push) Has been cancelled
Build & Release / build-windows (push) Has been cancelled
Build & Release / create-release (push) Has been cancelled
feat: crop save (save visible area at original resolution) v1.4.0
- Save visible area at original resolution as JPEG q90 (title bar button or Ctrl+S)
- Output name: original name + _HHmmss suffix; no overwrite, warning shown
- Active color effects baked in; rotation saves bounding box
- New: crop_save_service, l10n strings TR/EN, docs/plan-crop-save.md
2026-10-11 21:36:20 +03:00

110 lines
2.9 KiB
Dart

import 'package:flutter/material.dart';
import 'package:window_manager/window_manager.dart';
class CustomTitleBar extends StatelessWidget {
final VoidCallback? onSettings;
final VoidCallback? onSaveCrop;
final bool visible;
const CustomTitleBar({super.key, this.onSettings, this.onSaveCrop, this.visible = true});
@override
Widget build(BuildContext context) {
return Positioned(
top: 0,
left: 0,
right: 0,
child: AnimatedOpacity(
opacity: visible ? 1.0 : 0.0,
duration: const Duration(milliseconds: 150),
child: DragToMoveArea(
child: SizedBox(
height: 24,
child: Stack(
children: [
if (onSettings != null)
Positioned(
left: 0,
top: 0,
bottom: 0,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
_BarButton(
icon: Icons.settings,
onTap: onSettings!,
),
],
),
),
Positioned(
right: 0,
top: 0,
bottom: 0,
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (onSaveCrop != null)
_BarButton(
icon: Icons.save_outlined,
onTap: onSaveCrop!,
),
_BarButton(
icon: Icons.horizontal_rule,
onTap: () => windowManager.minimize(),
),
_BarButton(
icon: Icons.close,
onTap: () => windowManager.close(),
),
],
),
),
],
),
),
),
),
);
}
}
class _BarButton extends StatefulWidget {
final IconData icon;
final VoidCallback onTap;
const _BarButton({
required this.icon,
required this.onTap,
});
@override
State<_BarButton> createState() => _BarButtonState();
}
class _BarButtonState extends State<_BarButton> {
bool _hovered = false;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: widget.onTap,
child: MouseRegion(
cursor: SystemMouseCursors.click,
onEnter: (_) => setState(() => _hovered = true),
onExit: (_) => setState(() => _hovered = false),
child: Container(
width: 32,
height: 24,
color: _hovered ? Colors.red.withValues(alpha: 0.8) : Colors.transparent,
child: Icon(
widget.icon,
color: Colors.white,
size: 14,
),
),
),
);
}
}