mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-09-29 21:02:09 +02:00
fix(mornye): improve frosted menu contrast and readability
This commit is contained in:
@@ -131,6 +131,7 @@ class MornyeGlassPanel extends ConsumerWidget {
|
||||
this.strongTint = false,
|
||||
this.tintOpacity,
|
||||
this.tintColor,
|
||||
this.backdropFilter,
|
||||
this.liquidGlass = false,
|
||||
this.blurEnabled = true,
|
||||
});
|
||||
@@ -144,6 +145,7 @@ class MornyeGlassPanel extends ConsumerWidget {
|
||||
this.lastInGroup = true,
|
||||
this.tintOpacity = 0.78,
|
||||
this.tintColor,
|
||||
this.backdropFilter,
|
||||
this.liquidGlass = false,
|
||||
this.blurEnabled = true,
|
||||
}) : strongTint = false;
|
||||
@@ -155,6 +157,7 @@ class MornyeGlassPanel extends ConsumerWidget {
|
||||
final bool strongTint;
|
||||
final double? tintOpacity;
|
||||
final Color? tintColor;
|
||||
final ImageFilter? backdropFilter;
|
||||
final bool liquidGlass;
|
||||
|
||||
/// Disable backdrop sampling for surfaces that scroll over a plain page.
|
||||
@@ -172,6 +175,7 @@ class MornyeGlassPanel extends ConsumerWidget {
|
||||
radius: radius,
|
||||
tintOpacity: tintOpacity,
|
||||
tintColor: tintColor,
|
||||
backdropFilter: backdropFilter,
|
||||
blurEnabled: blur,
|
||||
child: Material(color: Colors.transparent, child: child),
|
||||
);
|
||||
@@ -183,6 +187,7 @@ class MornyeGlassPanel extends ConsumerWidget {
|
||||
strongTint: strongTint,
|
||||
tintOpacity: tintOpacity,
|
||||
tintColor: tintColor,
|
||||
backdropFilter: backdropFilter,
|
||||
blurEnabled: blur,
|
||||
child: Material(
|
||||
color: strongTint
|
||||
@@ -203,6 +208,7 @@ class MornyeGlass extends StatelessWidget {
|
||||
this.strongTint = false,
|
||||
this.tintOpacity,
|
||||
this.tintColor,
|
||||
this.backdropFilter,
|
||||
}) : _useLens = true,
|
||||
firstInGroup = true,
|
||||
lastInGroup = true;
|
||||
@@ -218,6 +224,7 @@ class MornyeGlass extends StatelessWidget {
|
||||
this.strongTint = false,
|
||||
this.tintOpacity,
|
||||
this.tintColor,
|
||||
this.backdropFilter,
|
||||
}) : _useLens = false;
|
||||
|
||||
final Widget child;
|
||||
@@ -233,6 +240,7 @@ class MornyeGlass extends StatelessWidget {
|
||||
/// Uses a single tint instead of layered highlights for translucent surfaces.
|
||||
final double? tintOpacity;
|
||||
final Color? tintColor;
|
||||
final ImageFilter? backdropFilter;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -248,6 +256,7 @@ class MornyeGlass extends StatelessWidget {
|
||||
strongTint: strongTint,
|
||||
tintOpacity: tintOpacity,
|
||||
tintColor: tintColor,
|
||||
backdropFilter: backdropFilter,
|
||||
child: useGlass
|
||||
? NativeGlassMetrics(
|
||||
child: LiquidGlassLens(
|
||||
@@ -299,6 +308,7 @@ class _MornyeGlassSurface extends StatelessWidget {
|
||||
this.strongTint = false,
|
||||
this.tintOpacity,
|
||||
this.tintColor,
|
||||
this.backdropFilter,
|
||||
});
|
||||
|
||||
final Widget child;
|
||||
@@ -309,6 +319,7 @@ class _MornyeGlassSurface extends StatelessWidget {
|
||||
final bool strongTint;
|
||||
final double? tintOpacity;
|
||||
final Color? tintColor;
|
||||
final ImageFilter? backdropFilter;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -321,7 +332,7 @@ class _MornyeGlassSurface extends StatelessWidget {
|
||||
);
|
||||
final rim = BorderSide(
|
||||
color: dark
|
||||
? Colors.white.withValues(alpha: 0.16)
|
||||
? Colors.white.withValues(alpha: tintColor == null ? 0.16 : 0.28)
|
||||
: Colors.black.withValues(alpha: 0.17),
|
||||
width: 0.75,
|
||||
);
|
||||
@@ -390,7 +401,10 @@ class _MornyeGlassSurface extends StatelessWidget {
|
||||
child: ClipRRect(
|
||||
borderRadius: shape,
|
||||
child: useBlur
|
||||
? BackdropFilter(filter: _backdropBlur, child: surface)
|
||||
? BackdropFilter(
|
||||
filter: backdropFilter ?? _backdropBlur,
|
||||
child: surface,
|
||||
)
|
||||
: surface,
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'dart:math' as math;
|
||||
import 'dart:ui' show ImageFilter;
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -153,6 +154,67 @@ class MornyeMenuAction {
|
||||
|
||||
/// One frosted popover, with compact shortcuts and separated action groups.
|
||||
class MornyeContextMenu extends StatelessWidget {
|
||||
// Compress bright artwork after blurring it, preserving more backdrop
|
||||
// detail in the midtones than a thick, opaque gray fill would allow.
|
||||
static final _darkBackdrop = ImageFilter.compose(
|
||||
outer: const ColorFilter.matrix([
|
||||
0.22,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
54,
|
||||
0,
|
||||
0.22,
|
||||
0,
|
||||
0,
|
||||
54,
|
||||
0,
|
||||
0,
|
||||
0.22,
|
||||
0,
|
||||
56,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
]),
|
||||
inner: _frostedBackdrop(1.8),
|
||||
);
|
||||
static final _lightBackdrop = _frostedBackdrop(1);
|
||||
|
||||
static ImageFilter _frostedBackdrop(double brightness) {
|
||||
const saturation = 0.45;
|
||||
const r = 0.2126 * (1 - saturation);
|
||||
const g = 0.7152 * (1 - saturation);
|
||||
const b = 0.0722 * (1 - saturation);
|
||||
return ImageFilter.compose(
|
||||
outer: ColorFilter.matrix([
|
||||
(r + saturation) * brightness,
|
||||
g * brightness,
|
||||
b * brightness,
|
||||
0,
|
||||
0,
|
||||
r * brightness,
|
||||
(g + saturation) * brightness,
|
||||
b * brightness,
|
||||
0,
|
||||
0,
|
||||
r * brightness,
|
||||
g * brightness,
|
||||
(b + saturation) * brightness,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
]),
|
||||
inner: ImageFilter.blur(sigmaX: 32, sigmaY: 32),
|
||||
);
|
||||
}
|
||||
|
||||
const MornyeContextMenu({
|
||||
super.key,
|
||||
this.quickActions = const [],
|
||||
@@ -171,6 +233,7 @@ class MornyeContextMenu extends StatelessWidget {
|
||||
final theme = inheritSurface
|
||||
? Theme.of(context)
|
||||
: MornyeTheme.fromContext(context);
|
||||
final dark = theme.brightness == Brightness.dark;
|
||||
final visibleGroups = groups.where((group) => group.isNotEmpty).toList();
|
||||
final shortcuts = quickActions.isEmpty
|
||||
? null
|
||||
@@ -193,11 +256,14 @@ class MornyeContextMenu extends StatelessWidget {
|
||||
if (i > 0 || quickActions.isNotEmpty)
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: i == 0 ? 0 : 8),
|
||||
child: const Divider(
|
||||
child: Divider(
|
||||
height: 0.5,
|
||||
thickness: 0.5,
|
||||
indent: 20,
|
||||
endIndent: 20,
|
||||
color: theme.colorScheme.onSurface.withValues(
|
||||
alpha: dark ? 0.18 : 0.12,
|
||||
),
|
||||
),
|
||||
),
|
||||
for (final action in visibleGroups[i]) _action(theme, action),
|
||||
@@ -211,8 +277,11 @@ class MornyeContextMenu extends StatelessWidget {
|
||||
radius: 28,
|
||||
// Keep one local, clipped backdrop. A second screen-space lens pass
|
||||
// can shift its outline inside an offset/scaled popover on Impeller.
|
||||
// Soften artwork colors and bright lyrics before the neutral tint,
|
||||
// keeping white menu text readable even over a near-white cover.
|
||||
backdropFilter: dark ? _darkBackdrop : _lightBackdrop,
|
||||
tintColor: Colors.white,
|
||||
tintOpacity: theme.brightness == Brightness.dark ? 0.12 : 0.50,
|
||||
tintOpacity: dark ? 0.025 : 0.72,
|
||||
child: LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
// Let the entire menu scroll when pinning the shortcuts would
|
||||
@@ -249,16 +318,16 @@ class MornyeContextMenu extends StatelessWidget {
|
||||
: action.destructive || action.selected
|
||||
? theme.colorScheme.primary
|
||||
: theme.colorScheme.onSurface;
|
||||
final icon = Icon(action.icon, size: compact ? 23 : 21, color: color);
|
||||
final icon = Icon(action.icon, size: compact ? 24 : 22, color: color);
|
||||
final label = Text(
|
||||
action.label,
|
||||
textAlign: compact ? TextAlign.center : TextAlign.start,
|
||||
style: theme.textTheme.bodyLarge?.copyWith(
|
||||
color: color,
|
||||
fontSize: compact
|
||||
? 13
|
||||
? 14
|
||||
: dense
|
||||
? 15
|
||||
? 16
|
||||
: 17,
|
||||
fontWeight: compact ? FontWeight.w600 : FontWeight.w400,
|
||||
),
|
||||
@@ -289,8 +358,9 @@ class MornyeContextMenu extends StatelessWidget {
|
||||
Text(
|
||||
action.subtitle!,
|
||||
style: theme.textTheme.bodySmall?.copyWith(
|
||||
fontSize: 14,
|
||||
color: theme.colorScheme.onSurface.withValues(
|
||||
alpha: 0.78,
|
||||
alpha: 0.96,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -92,7 +92,6 @@ class MornyePlayerActionsSheet extends ConsumerWidget {
|
||||
),
|
||||
);
|
||||
return MornyeContextMenu(
|
||||
dense: true,
|
||||
quickActions: [
|
||||
_action(
|
||||
context,
|
||||
|
||||
Reference in New Issue
Block a user