mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2024-11-23 16:00:41 +00:00
wip
This commit is contained in:
parent
cb4e91cb0a
commit
8a4f141cf2
10 changed files with 195 additions and 10 deletions
|
@ -1,3 +1,4 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import 'models/ev_source_type.dart';
|
||||
|
@ -15,33 +16,43 @@ class UserPreferencesService {
|
|||
|
||||
static const _hapticsKey = "haptics";
|
||||
static const _themeTypeKey = "themeType";
|
||||
static const _primaryColorKey = "primaryColor";
|
||||
static const _dynamicColorKey = "dynamicColor";
|
||||
|
||||
final SharedPreferences _sharedPreferences;
|
||||
|
||||
UserPreferencesService(this._sharedPreferences);
|
||||
|
||||
IsoValue get iso => isoValues.firstWhere((v) => v.value == (_sharedPreferences.getInt(_isoKey) ?? 100));
|
||||
IsoValue get iso =>
|
||||
isoValues.firstWhere((v) => v.value == (_sharedPreferences.getInt(_isoKey) ?? 100));
|
||||
set iso(IsoValue value) => _sharedPreferences.setInt(_isoKey, value.value);
|
||||
|
||||
NdValue get ndFilter => ndValues.firstWhere((v) => v.value == (_sharedPreferences.getInt(_ndFilterKey) ?? 0));
|
||||
NdValue get ndFilter =>
|
||||
ndValues.firstWhere((v) => v.value == (_sharedPreferences.getInt(_ndFilterKey) ?? 0));
|
||||
set ndFilter(NdValue value) => _sharedPreferences.setInt(_ndFilterKey, value.value);
|
||||
|
||||
EvSourceType get evSourceType => EvSourceType.values[_sharedPreferences.getInt(_evSourceTypeKey) ?? 0];
|
||||
EvSourceType get evSourceType =>
|
||||
EvSourceType.values[_sharedPreferences.getInt(_evSourceTypeKey) ?? 0];
|
||||
set evSourceType(EvSourceType value) => _sharedPreferences.setInt(_evSourceTypeKey, value.index);
|
||||
|
||||
bool get haptics => _sharedPreferences.getBool(_hapticsKey) ?? false;
|
||||
set haptics(bool value) => _sharedPreferences.setBool(_hapticsKey, value);
|
||||
|
||||
double get cameraEvCalibration => _sharedPreferences.getDouble(_cameraEvCalibrationKey) ?? 0.0;
|
||||
set cameraEvCalibration(double value) => _sharedPreferences.setDouble(_cameraEvCalibrationKey, value);
|
||||
set cameraEvCalibration(double value) =>
|
||||
_sharedPreferences.setDouble(_cameraEvCalibrationKey, value);
|
||||
|
||||
double get lightSensorEvCalibration => _sharedPreferences.getDouble(_lightSensorEvCalibrationKey) ?? 0.0;
|
||||
set lightSensorEvCalibration(double value) => _sharedPreferences.setDouble(_lightSensorEvCalibrationKey, value);
|
||||
double get lightSensorEvCalibration =>
|
||||
_sharedPreferences.getDouble(_lightSensorEvCalibrationKey) ?? 0.0;
|
||||
set lightSensorEvCalibration(double value) =>
|
||||
_sharedPreferences.setDouble(_lightSensorEvCalibrationKey, value);
|
||||
|
||||
ThemeType get themeType => ThemeType.values[_sharedPreferences.getInt(_themeTypeKey) ?? 0];
|
||||
set themeType(ThemeType value) => _sharedPreferences.setInt(_themeTypeKey, value.index);
|
||||
|
||||
Color get primaryColor => Color(_sharedPreferences.getInt(_primaryColorKey) ?? 0xff2196f3);
|
||||
set primaryColor(Color value) => _sharedPreferences.setInt(_primaryColorKey, value.value);
|
||||
|
||||
bool get dynamicColor => _sharedPreferences.getBool(_dynamicColorKey) ?? false;
|
||||
set dynamicColor(bool value) => _sharedPreferences.setBool(_dynamicColorKey, value);
|
||||
}
|
||||
|
|
|
@ -36,10 +36,12 @@
|
|||
"haptics": "Haptics",
|
||||
"theme": "Theme",
|
||||
"chooseTheme": "Choose theme",
|
||||
"dynamicColor": "Dynamic color",
|
||||
"themeLight": "Light",
|
||||
"themeDark": "Dark",
|
||||
"themeSystemDefault": "System default",
|
||||
"dynamicColor": "Dynamic color",
|
||||
"primaryColor": "Primary color",
|
||||
"choosePrimaryColor": "Choose primary color",
|
||||
"about": "About",
|
||||
"sourceCode": "Source code",
|
||||
"reportIssue": "Report an issue",
|
||||
|
|
|
@ -20,6 +20,25 @@ class ThemeProvider extends StatefulWidget {
|
|||
return context.findAncestorStateOfType<ThemeProviderState>()!;
|
||||
}
|
||||
|
||||
static const primaryColorsList = [
|
||||
Color(0xfff44336),
|
||||
Color(0xffe91e63),
|
||||
Color(0xff9c27b0),
|
||||
Color(0xff673ab7),
|
||||
Color(0xff3f51b5),
|
||||
Color(0xff2196f3),
|
||||
Color(0xff03a9f4),
|
||||
Color(0xff00bcd4),
|
||||
Color(0xff009688),
|
||||
Color(0xff4caf50),
|
||||
Color(0xff8bc34a),
|
||||
Color(0xffcddc39),
|
||||
Color(0xffffeb3b),
|
||||
Color(0xffffc107),
|
||||
Color(0xffff9800),
|
||||
Color(0xffff5722),
|
||||
];
|
||||
|
||||
@override
|
||||
State<ThemeProvider> createState() => ThemeProviderState();
|
||||
}
|
||||
|
@ -29,7 +48,7 @@ class ThemeProviderState extends State<ThemeProvider> {
|
|||
|
||||
late final _themeTypeNotifier = ValueNotifier<ThemeType>(_prefs.themeType);
|
||||
late final _dynamicColorNotifier = ValueNotifier<bool>(_prefs.dynamicColor);
|
||||
late final _primaryColorNotifier = ValueNotifier<Color>(const Color(0xFF2196f3));
|
||||
late final _primaryColorNotifier = ValueNotifier<Color>(_prefs.primaryColor);
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
|
@ -80,6 +99,11 @@ class ThemeProviderState extends State<ThemeProvider> {
|
|||
}
|
||||
}
|
||||
|
||||
void setPrimaryColor(Color color) {
|
||||
_primaryColorNotifier.value = color;
|
||||
_prefs.primaryColor = color;
|
||||
}
|
||||
|
||||
void enableDynamicColor(bool enable) {
|
||||
_dynamicColorNotifier.value = enable;
|
||||
_prefs.dynamicColor = enable;
|
||||
|
@ -148,6 +172,7 @@ class _ThemeDataProvider extends StatelessWidget {
|
|||
return ThemeData(
|
||||
useMaterial3: true,
|
||||
brightness: scheme.brightness,
|
||||
primaryColor: primaryColor,
|
||||
colorScheme: scheme,
|
||||
dialogBackgroundColor: scheme.surface,
|
||||
dialogTheme: DialogTheme(backgroundColor: scheme.surface),
|
||||
|
|
|
@ -13,6 +13,7 @@ class Dimens {
|
|||
static const double grid56 = 56;
|
||||
static const double grid168 = 168;
|
||||
|
||||
static const double paddingS = 8;
|
||||
static const double paddingM = 16;
|
||||
static const double paddingL = 24;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:lightmeter/res/dimens.dart';
|
||||
import 'package:lightmeter/screens/metering/components/bottom_controls/components/shared/widget_circle_filled.dart';
|
||||
import 'package:lightmeter/screens/shared/filled_circle/widget_circle_filled.dart';
|
||||
|
||||
class MeteringMeasureButton extends StatefulWidget {
|
||||
final double size;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:lightmeter/res/dimens.dart';
|
||||
import 'package:lightmeter/screens/metering/components/bottom_controls/components/shared/widget_circle_filled.dart';
|
||||
import 'package:lightmeter/screens/shared/filled_circle/widget_circle_filled.dart';
|
||||
|
||||
class MeteringSecondaryButton extends StatelessWidget {
|
||||
final IconData icon;
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:lightmeter/generated/l10n.dart';
|
||||
import 'package:lightmeter/providers/theme_provider.dart';
|
||||
import 'package:lightmeter/res/dimens.dart';
|
||||
import 'package:lightmeter/screens/shared/filled_circle/widget_circle_filled.dart';
|
||||
|
||||
class PrimaryColorDialogPicker extends StatefulWidget {
|
||||
const PrimaryColorDialogPicker({super.key});
|
||||
|
||||
@override
|
||||
State<PrimaryColorDialogPicker> createState() => _PrimaryColorDialogPickerState();
|
||||
}
|
||||
|
||||
class _PrimaryColorDialogPickerState extends State<PrimaryColorDialogPicker> {
|
||||
late Color _selected = Theme.of(context).primaryColor;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AlertDialog(
|
||||
titlePadding: const EdgeInsets.fromLTRB(
|
||||
Dimens.paddingL,
|
||||
Dimens.paddingL,
|
||||
Dimens.paddingL,
|
||||
Dimens.paddingM,
|
||||
),
|
||||
title: Text(S.of(context).choosePrimaryColor),
|
||||
contentPadding: EdgeInsets.zero,
|
||||
content: SizedBox(
|
||||
height: Dimens.grid48,
|
||||
width: double.maxFinite,
|
||||
child: ListView.separated(
|
||||
scrollDirection: Axis.horizontal,
|
||||
padding: const EdgeInsets.symmetric(horizontal: Dimens.paddingL),
|
||||
separatorBuilder: (_, __) => const SizedBox(width: Dimens.grid8),
|
||||
itemCount: ThemeProvider.primaryColorsList.length,
|
||||
itemBuilder: (_, index) {
|
||||
final color = ThemeProvider.primaryColorsList[index];
|
||||
return _SelectableColorItem(
|
||||
color: color,
|
||||
selected: color.value == _selected.value,
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_selected = color;
|
||||
});
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
actionsPadding: const EdgeInsets.fromLTRB(
|
||||
Dimens.paddingL,
|
||||
Dimens.paddingM,
|
||||
Dimens.paddingL,
|
||||
Dimens.paddingL,
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: Navigator.of(context).pop,
|
||||
child: Text(S.of(context).cancel),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(_selected);
|
||||
},
|
||||
child: Text(S.of(context).save),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _SelectableColorItem extends StatelessWidget {
|
||||
final Color color;
|
||||
final bool selected;
|
||||
final VoidCallback onTap;
|
||||
|
||||
_SelectableColorItem({
|
||||
required this.color,
|
||||
required this.selected,
|
||||
required this.onTap,
|
||||
}) : super(key: ValueKey(color));
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: onTap,
|
||||
child: FilledCircle(
|
||||
size: Dimens.grid48,
|
||||
color: color,
|
||||
child: AnimatedSwitcher(
|
||||
duration: Dimens.durationS,
|
||||
child: selected
|
||||
? Icon(
|
||||
Icons.check,
|
||||
color: ThemeData.estimateBrightnessForColor(color) == Brightness.light
|
||||
? Colors.black
|
||||
: Colors.white,
|
||||
)
|
||||
: null,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:lightmeter/data/models/dynamic_colors_state.dart';
|
||||
import 'package:lightmeter/generated/l10n.dart';
|
||||
import 'package:lightmeter/providers/theme_provider.dart';
|
||||
|
||||
import 'components/primary_color_picker_dialog/widget_dialog_picker_primary_color.dart';
|
||||
|
||||
class PrimaryColorListTile extends StatelessWidget {
|
||||
const PrimaryColorListTile({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (context.watch<DynamicColorState>() == DynamicColorState.enabled) {
|
||||
return Opacity(
|
||||
opacity: 0.5,
|
||||
child: IgnorePointer(
|
||||
child: ListTile(
|
||||
leading: const Icon(Icons.palette),
|
||||
title: Text(S.of(context).primaryColor),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return ListTile(
|
||||
leading: const Icon(Icons.palette),
|
||||
title: Text(S.of(context).primaryColor),
|
||||
onTap: () {
|
||||
showDialog<Color>(
|
||||
context: context,
|
||||
builder: (_) => const PrimaryColorDialogPicker(),
|
||||
).then((value) {
|
||||
if (value != null) {
|
||||
ThemeProvider.of(context).setPrimaryColor(value);
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import 'package:lightmeter/res/dimens.dart';
|
|||
|
||||
import 'components/calibration/widget_list_tile_calibration.dart';
|
||||
import 'components/haptics/provider_list_tile_haptics.dart';
|
||||
import 'components/primary_color/widget_list_tile_primary_color.dart';
|
||||
import 'components/report_issue/widget_list_tile_report_issue.dart';
|
||||
import 'components/shared/settings_section/widget_settings_section.dart';
|
||||
import 'components/source_code/widget_list_tile_source_code.dart';
|
||||
|
@ -65,6 +66,7 @@ class SettingsScreen extends StatelessWidget {
|
|||
title: S.of(context).theme,
|
||||
children: const [
|
||||
ThemeTypeListTile(),
|
||||
PrimaryColorListTile(),
|
||||
DynamicColorListTile(),
|
||||
],
|
||||
),
|
||||
|
|
Loading…
Reference in a new issue