Frosted bottom bar: adjustable blur and opacity with Less/Default/More presets
Settings > Appearance shows a preset control plus Blur and Opacity sliders (new NooSlider) while frosted glass is on; values persist and feed NooBottomBar.frostedBlur/frostedOpacity. Default matches the old fixed look. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
0c063c1fb4
commit
0cda4a1241
@@ -21,6 +21,30 @@ enum FabStyle { auto, mini, expanded }
|
||||
/// animated wave with a tick-mark thumb ([squiggly]).
|
||||
enum MediaProgressBarStyle { classic, wavy, slim, squiggly }
|
||||
|
||||
/// The frosted-glass bottom bar's blur sigma and surface opacity, in three
|
||||
/// ready-made strengths (Settings, Appearance). Moving either slider off all
|
||||
/// three leaves no preset selected (a custom mix).
|
||||
enum FrostedGlassPreset {
|
||||
less(blur: 10, opacity: 0.88, label: 'Less'),
|
||||
standard(blur: 20, opacity: 0.72, label: 'Default'),
|
||||
more(blur: 32, opacity: 0.55, label: 'More');
|
||||
|
||||
final double blur;
|
||||
final double opacity;
|
||||
final String label;
|
||||
|
||||
const FrostedGlassPreset({
|
||||
required this.blur,
|
||||
required this.opacity,
|
||||
required this.label,
|
||||
});
|
||||
}
|
||||
|
||||
const double minFrostedBlur = 0;
|
||||
const double maxFrostedBlur = 40;
|
||||
const double minFrostedOpacity = 0.3;
|
||||
const double maxFrostedOpacity = 1.0;
|
||||
|
||||
/// Global (not per-account) UI settings: theme, bottom-nav appearance, tab
|
||||
/// configuration, swipe actions. Independent of login state - these mean
|
||||
/// the same thing whether any account is signed in or not, unlike
|
||||
@@ -39,6 +63,8 @@ class SettingsController extends ChangeNotifier {
|
||||
static const _prefFabStyle = 'ui_fab_style';
|
||||
static const _prefBottomBarStyle = 'ui_bottom_bar_style';
|
||||
static const _prefBottomBarFrosted = 'ui_bottom_bar_frosted';
|
||||
static const _prefFrostedBlur = 'ui_bottom_bar_frosted_blur';
|
||||
static const _prefFrostedOpacity = 'ui_bottom_bar_frosted_opacity';
|
||||
static const _prefNavMenuStyle = 'ui_nav_menu_style';
|
||||
static const _prefSearchInBottomBar = 'ui_search_in_bottom_bar';
|
||||
static const _prefAmoledDark = 'ui_amoled_dark';
|
||||
@@ -53,6 +79,8 @@ class SettingsController extends ChangeNotifier {
|
||||
NooBottomBarStyle _bottomBarStyle = NooBottomBarStyle.attached;
|
||||
NooNavMenuStyle _navMenuStyle = NooNavMenuStyle.drawer;
|
||||
bool _bottomBarFrosted = false;
|
||||
double _frostedBlur = FrostedGlassPreset.standard.blur;
|
||||
double _frostedOpacity = FrostedGlassPreset.standard.opacity;
|
||||
bool _searchInBottomBar = false;
|
||||
bool _useDynamicColor = true;
|
||||
bool _amoledDark = false;
|
||||
@@ -98,6 +126,14 @@ class SettingsController extends ChangeNotifier {
|
||||
ThemeMode get themeMode => _themeMode;
|
||||
NooBottomBarStyle get bottomBarStyle => _bottomBarStyle;
|
||||
bool get bottomBarFrosted => _bottomBarFrosted;
|
||||
double get bottomBarFrostedBlur => _frostedBlur;
|
||||
double get bottomBarFrostedOpacity => _frostedOpacity;
|
||||
|
||||
/// The preset the current blur/opacity match exactly, or null when the
|
||||
/// sliders have been moved to something custom.
|
||||
FrostedGlassPreset? get frostedPreset => FrostedGlassPreset.values
|
||||
.where((p) => p.blur == _frostedBlur && p.opacity == _frostedOpacity)
|
||||
.firstOrNull;
|
||||
NooNavMenuStyle get navMenuStyle => _navMenuStyle;
|
||||
bool get searchInBottomBar => _searchInBottomBar;
|
||||
bool get useDynamicColor => _useDynamicColor;
|
||||
@@ -160,6 +196,15 @@ class SettingsController extends ChangeNotifier {
|
||||
}
|
||||
_bottomBarFrosted =
|
||||
prefs.getBool(_prefBottomBarFrosted) ?? _bottomBarFrosted;
|
||||
_frostedBlur = (prefs.getDouble(_prefFrostedBlur) ?? _frostedBlur).clamp(
|
||||
minFrostedBlur,
|
||||
maxFrostedBlur,
|
||||
);
|
||||
_frostedOpacity =
|
||||
(prefs.getDouble(_prefFrostedOpacity) ?? _frostedOpacity).clamp(
|
||||
minFrostedOpacity,
|
||||
maxFrostedOpacity,
|
||||
);
|
||||
_searchInBottomBar =
|
||||
prefs.getBool(_prefSearchInBottomBar) ?? _searchInBottomBar;
|
||||
_useDynamicColor =
|
||||
@@ -318,6 +363,27 @@ class SettingsController extends ChangeNotifier {
|
||||
_prefsFuture.then((p) => p.setString(_prefBottomBarStyle, style.name));
|
||||
}
|
||||
|
||||
void setFrostedBlur(double value) {
|
||||
final v = value.clamp(minFrostedBlur, maxFrostedBlur);
|
||||
if (_frostedBlur == v) return;
|
||||
_frostedBlur = v;
|
||||
notifyListeners();
|
||||
_prefsFuture.then((p) => p.setDouble(_prefFrostedBlur, v));
|
||||
}
|
||||
|
||||
void setFrostedOpacity(double value) {
|
||||
final v = value.clamp(minFrostedOpacity, maxFrostedOpacity);
|
||||
if (_frostedOpacity == v) return;
|
||||
_frostedOpacity = v;
|
||||
notifyListeners();
|
||||
_prefsFuture.then((p) => p.setDouble(_prefFrostedOpacity, v));
|
||||
}
|
||||
|
||||
void setFrostedPreset(FrostedGlassPreset preset) {
|
||||
setFrostedBlur(preset.blur);
|
||||
setFrostedOpacity(preset.opacity);
|
||||
}
|
||||
|
||||
void setBottomBarFrosted(bool value) {
|
||||
if (_bottomBarFrosted == value) return;
|
||||
_bottomBarFrosted = value;
|
||||
|
||||
Reference in New Issue
Block a user