veilidchat/lib/theme/views/preferences/display_scale_preferences.dart
2025-05-25 13:09:41 -04:00

109 lines
3.2 KiB
Dart

import 'dart:math';
import 'package:animated_theme_switcher/animated_theme_switcher.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_translate/flutter_translate.dart';
import '../../../settings/settings.dart';
import '../../models/models.dart';
import '../views.dart';
const _scales = [
1 / (1 + 1 / 2),
1 / (1 + 1 / 3),
1 / (1 + 1 / 4),
1,
1 + (1 / 4),
1 + (1 / 2),
1 + (1 / 1),
];
const _scaleNames = [
'-3',
'-2',
'-1',
'0',
'1',
'2',
'3',
];
const _scaleNumMult = <double>[
1,
1,
1,
1,
1 + 1 / 4,
1 + 1 / 2,
1 + 1 / 1,
];
int displayScaleToIndex(double displayScale) {
final idx = _scales.indexWhere((elem) => elem > displayScale);
final currentScaleIdx = idx == -1 ? _scales.length - 1 : max(0, idx - 1);
return currentScaleIdx;
}
double indexToDisplayScale(int scaleIdx) {
final displayScale =
_scales[max(min(scaleIdx, _scales.length - 1), 0)].toDouble();
return displayScale;
}
String indexToDisplayScaleName(int scaleIdx) =>
_scaleNames[max(min(scaleIdx, _scales.length - 1), 0)];
final maxDisplayScaleIndex = _scales.length - 1;
Widget buildSettingsPageDisplayScalePreferences(
{required BuildContext context, required ThemeSwitcherState switcher}) {
final preferencesRepository = PreferencesRepository.instance;
final themePreferences = preferencesRepository.value.themePreference;
final currentScaleIdx = displayScaleToIndex(themePreferences.displayScale);
final currentScaleName = indexToDisplayScaleName(currentScaleIdx);
return StyledSlider(
value: currentScaleIdx.toDouble(),
label: currentScaleName,
decoratorLabel: translate('settings_page.display_scale'),
max: _scales.length - 1.toDouble(),
divisions: _scales.length - 1,
leftWidget: const Icon(Icons.text_decrease),
rightWidget: const Icon(Icons.text_increase),
onChanged: (value) async {
final scaleIdx = value.toInt();
final displayScale = indexToDisplayScale(scaleIdx);
final newThemePrefs =
themePreferences.copyWith(displayScale: displayScale);
final newPrefs = preferencesRepository.value
.copyWith(themePreference: newThemePrefs);
await preferencesRepository.set(newPrefs);
switcher.changeTheme(theme: newThemePrefs.themeData());
});
}
extension DisplayScaledNum on num {
double scaled(BuildContext context) {
final prefs = context.watch<PreferencesCubit>().state.asData?.value ??
PreferencesRepository.instance.value;
final currentScaleIdx =
displayScaleToIndex(prefs.themePreference.displayScale);
return this * _scaleNumMult[currentScaleIdx];
}
}
extension DisplayScaledEdgeInsets on EdgeInsets {
EdgeInsets scaled(BuildContext context) {
final prefs = context.watch<PreferencesCubit>().state.asData?.value ??
PreferencesRepository.instance.value;
final currentScaleIdx =
displayScaleToIndex(prefs.themePreference.displayScale);
return EdgeInsets.fromLTRB(
left * _scaleNumMult[currentScaleIdx],
top * _scaleNumMult[currentScaleIdx],
right * _scaleNumMult[currentScaleIdx],
bottom * _scaleNumMult[currentScaleIdx]);
}
}