mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-10-22 07:18:38 +02:00
The Material theme now draws its main surfaces with rounded Material Symbols: navigation, player, mini player, queue, settings, sheets, dialogs and shared controls. AppIcon maps legacy Icons to their symbol and keeps outlined glyphs unfilled. Mornye keeps its original icons. Icon buttons, text and filled buttons, dialog actions, sliders, the setup FAB and indeterminate spinners use the Material 3 Expressive components. Each wrapper falls back to the standard Flutter widget for Mornye, reduced motion and custom sizing, so existing layouts and hit areas stay intact.
96 lines
3.0 KiB
Dart
96 lines
3.0 KiB
Dart
import 'package:flutter/cupertino.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:spotiflac_android/theme/mornye_icons.dart';
|
|
import 'package:spotiflac_android/theme/mornye_theme.dart';
|
|
import 'package:spotiflac_android/widgets/app_icon.dart';
|
|
import 'package:spotiflac_android/widgets/mornye_chrome.dart';
|
|
import 'package:spotiflac_android/widgets/expressive_button.dart';
|
|
|
|
/// Shared sheet actions follow the selected design on every platform.
|
|
class AppActionButton extends StatelessWidget {
|
|
const AppActionButton({
|
|
super.key,
|
|
required this.onPressed,
|
|
required this.icon,
|
|
required this.label,
|
|
this.style,
|
|
this.outlined = false,
|
|
this.glass = true,
|
|
this.tonal = false,
|
|
this.isDestructive = false,
|
|
this.fontSize = 17,
|
|
});
|
|
|
|
final VoidCallback? onPressed;
|
|
final Widget icon;
|
|
final Widget label;
|
|
final ButtonStyle? style;
|
|
final bool outlined;
|
|
final bool glass;
|
|
final bool tonal;
|
|
final bool isDestructive;
|
|
final double fontSize;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
if (!context.isMornye) {
|
|
return ExpressiveButton(
|
|
onPressed: onPressed,
|
|
icon: icon,
|
|
style: style,
|
|
outlined: outlined,
|
|
tonal: tonal,
|
|
child: label,
|
|
);
|
|
}
|
|
final scheme = Theme.of(context).colorScheme;
|
|
final prominent = isDestructive || !outlined;
|
|
final foreground = onPressed == null
|
|
? scheme.onSurfaceVariant.withValues(alpha: 0.5)
|
|
: prominent
|
|
? scheme.onPrimary
|
|
: scheme.primary;
|
|
final action = CupertinoButton(
|
|
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
|
|
borderRadius: BorderRadius.circular(28),
|
|
color: prominent
|
|
? scheme.primary
|
|
: tonal
|
|
? MornyeTheme.controlFill(context)
|
|
: Colors.transparent,
|
|
disabledColor: !prominent && !tonal && !glass
|
|
? Colors.transparent
|
|
: tonal && !prominent
|
|
? MornyeTheme.controlFill(context, enabled: false)
|
|
: scheme.surfaceContainerHighest,
|
|
onPressed: onPressed,
|
|
child: DefaultTextStyle(
|
|
style: Theme.of(context).textTheme.bodyLarge!.copyWith(
|
|
color: foreground,
|
|
fontSize: fontSize,
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
child: IconTheme(
|
|
data: IconThemeData(color: foreground, size: 20),
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
if (icon case Icon(:final icon?) || AppIcon(:final icon?))
|
|
Icon(mornyeIconFor(icon), size: 20)
|
|
else
|
|
icon,
|
|
const SizedBox(width: 8),
|
|
Flexible(child: label),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
// These buttons sit inside glass sheets/groups; avoid another blur pass.
|
|
return prominent || tonal || !glass
|
|
? action
|
|
: MornyeGlass.navigation(radius: 28, blurEnabled: false, child: action);
|
|
}
|
|
}
|