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 = [ 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().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().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]); } }