mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-01-22 16:56:19 +01:00
Allow picking theme color from color wheel
This commit is contained in:
parent
a6bd406ce9
commit
91978a6cc8
7 changed files with 387 additions and 213 deletions
BIN
app/assets/2.0x/ic_custom_color_56dp.png
Normal file
BIN
app/assets/2.0x/ic_custom_color_56dp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.9 KiB |
BIN
app/assets/3.0x/ic_custom_color_56dp.png
Normal file
BIN
app/assets/3.0x/ic_custom_color_56dp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
BIN
app/assets/ic_custom_color_56dp.png
Normal file
BIN
app/assets/ic_custom_color_56dp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.6 KiB |
|
@ -13,7 +13,6 @@ import 'package:nc_photos/event/event.dart';
|
|||
import 'package:nc_photos/exception_util.dart' as exception_util;
|
||||
import 'package:nc_photos/k.dart' as k;
|
||||
import 'package:nc_photos/language_util.dart' as language_util;
|
||||
import 'package:nc_photos/mobile/android/android_info.dart';
|
||||
import 'package:nc_photos/mobile/platform.dart'
|
||||
if (dart.library.html) 'package:nc_photos/web/platform.dart' as platform;
|
||||
import 'package:nc_photos/platform/features.dart' as features;
|
||||
|
@ -22,13 +21,13 @@ import 'package:nc_photos/platform/notification.dart';
|
|||
import 'package:nc_photos/pref.dart';
|
||||
import 'package:nc_photos/service.dart';
|
||||
import 'package:nc_photos/snack_bar_manager.dart';
|
||||
import 'package:nc_photos/theme.dart';
|
||||
import 'package:nc_photos/url_launcher_util.dart';
|
||||
import 'package:nc_photos/widget/fancy_option_picker.dart';
|
||||
import 'package:nc_photos/widget/gps_map.dart';
|
||||
import 'package:nc_photos/widget/home.dart';
|
||||
import 'package:nc_photos/widget/list_tile_center_leading.dart';
|
||||
import 'package:nc_photos/widget/root_picker.dart';
|
||||
import 'package:nc_photos/widget/settings/theme_settings.dart';
|
||||
import 'package:nc_photos/widget/share_folder_picker.dart';
|
||||
import 'package:nc_photos/widget/simple_input_dialog.dart';
|
||||
import 'package:nc_photos/widget/stateful_slider.dart';
|
||||
|
@ -166,7 +165,7 @@ class _SettingsState extends State<Settings> {
|
|||
leading: const Icon(Icons.palette_outlined),
|
||||
label: L10n.global().settingsThemeTitle,
|
||||
description: L10n.global().settingsThemeDescription,
|
||||
builder: () => _ThemeSettings(),
|
||||
builder: () => const ThemeSettings(),
|
||||
),
|
||||
_buildSubSettings(
|
||||
context,
|
||||
|
@ -1463,216 +1462,6 @@ class _EnhanceResolutionSliderState extends State<_EnhanceResolutionSlider> {
|
|||
late int _height;
|
||||
}
|
||||
|
||||
class _ThemeSettings extends StatefulWidget {
|
||||
@override
|
||||
createState() => _ThemeSettingsState();
|
||||
}
|
||||
|
||||
class _ThemeSettingsState extends State<_ThemeSettings> {
|
||||
@override
|
||||
initState() {
|
||||
super.initState();
|
||||
_isFollowSystemTheme = Pref().isFollowSystemThemeOr(false);
|
||||
_isUseBlackInDarkTheme = Pref().isUseBlackInDarkThemeOr(false);
|
||||
_seedColor = getSeedColor();
|
||||
}
|
||||
|
||||
@override
|
||||
build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Builder(
|
||||
builder: (context) => _buildContent(context),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildContent(BuildContext context) {
|
||||
return CustomScrollView(
|
||||
slivers: [
|
||||
SliverAppBar(
|
||||
pinned: true,
|
||||
title: Text(L10n.global().settingsThemeTitle),
|
||||
),
|
||||
SliverList(
|
||||
delegate: SliverChildListDelegate(
|
||||
[
|
||||
ListTile(
|
||||
title: Text(L10n.global().settingsSeedColorTitle),
|
||||
trailing: Icon(
|
||||
Icons.circle,
|
||||
size: 32,
|
||||
color: _seedColor,
|
||||
),
|
||||
onTap: () => _onSeedColorPressed(context),
|
||||
),
|
||||
if (platform_k.isAndroid &&
|
||||
AndroidInfo().sdkInt >= AndroidVersion.Q)
|
||||
SwitchListTile(
|
||||
title: Text(L10n.global().settingsFollowSystemThemeTitle),
|
||||
value: _isFollowSystemTheme,
|
||||
onChanged: (value) => _onFollowSystemThemeChanged(value),
|
||||
),
|
||||
SwitchListTile(
|
||||
title: Text(L10n.global().settingsUseBlackInDarkThemeTitle),
|
||||
subtitle: Text(_isUseBlackInDarkTheme
|
||||
? L10n.global().settingsUseBlackInDarkThemeTrueDescription
|
||||
: L10n.global()
|
||||
.settingsUseBlackInDarkThemeFalseDescription),
|
||||
value: _isUseBlackInDarkTheme,
|
||||
onChanged: (value) =>
|
||||
_onUseBlackInDarkThemeChanged(context, value),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _onFollowSystemThemeChanged(bool value) async {
|
||||
final oldValue = _isFollowSystemTheme;
|
||||
setState(() {
|
||||
_isFollowSystemTheme = value;
|
||||
});
|
||||
if (await Pref().setFollowSystemTheme(value)) {
|
||||
KiwiContainer().resolve<EventBus>().fire(ThemeChangedEvent());
|
||||
} else {
|
||||
_log.severe("[_onFollowSystemThemeChanged] Failed writing pref");
|
||||
SnackBarManager().showSnackBar(SnackBar(
|
||||
content: Text(L10n.global().writePreferenceFailureNotification),
|
||||
duration: k.snackBarDurationNormal,
|
||||
));
|
||||
setState(() {
|
||||
_isFollowSystemTheme = oldValue;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onUseBlackInDarkThemeChanged(
|
||||
BuildContext context, bool value) async {
|
||||
final oldValue = _isUseBlackInDarkTheme;
|
||||
setState(() {
|
||||
_isUseBlackInDarkTheme = value;
|
||||
});
|
||||
if (await Pref().setUseBlackInDarkTheme(value)) {
|
||||
if (Theme.of(context).brightness == Brightness.dark) {
|
||||
KiwiContainer().resolve<EventBus>().fire(ThemeChangedEvent());
|
||||
}
|
||||
} else {
|
||||
_log.severe("[_onUseBlackInDarkThemeChanged] Failed writing pref");
|
||||
SnackBarManager().showSnackBar(SnackBar(
|
||||
content: Text(L10n.global().writePreferenceFailureNotification),
|
||||
duration: k.snackBarDurationNormal,
|
||||
));
|
||||
setState(() {
|
||||
_isUseBlackInDarkTheme = oldValue;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onSeedColorPressed(BuildContext context) async {
|
||||
final result = await showDialog<Color>(
|
||||
context: context,
|
||||
builder: (context) => const _SeedColorPicker(),
|
||||
);
|
||||
if (result == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final oldValue = _seedColor;
|
||||
setState(() {
|
||||
_seedColor = result;
|
||||
});
|
||||
if (await Pref().setSeedColor(result.withAlpha(0xFF).value)) {
|
||||
KiwiContainer().resolve<EventBus>().fire(ThemeChangedEvent());
|
||||
} else {
|
||||
_log.severe("[_onSeedColorPressed] Failed writing pref");
|
||||
SnackBarManager().showSnackBar(SnackBar(
|
||||
content: Text(L10n.global().writePreferenceFailureNotification),
|
||||
duration: k.snackBarDurationNormal,
|
||||
));
|
||||
setState(() {
|
||||
_seedColor = oldValue;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
late bool _isFollowSystemTheme;
|
||||
late bool _isUseBlackInDarkTheme;
|
||||
late Color _seedColor;
|
||||
|
||||
static final _log = Logger("widget.settings._ThemeSettingsState");
|
||||
}
|
||||
|
||||
class _SeedColorPicker extends StatefulWidget {
|
||||
const _SeedColorPicker();
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _SeedColorPickerState();
|
||||
}
|
||||
|
||||
class _SeedColorPickerState extends State<_SeedColorPicker> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: Text(L10n.global().settingsSeedColorPickerTitle),
|
||||
content: Wrap(
|
||||
children: const [
|
||||
Color(0xFFF44336),
|
||||
Color(0xFF9C27B0),
|
||||
Color(0xFF2196F3),
|
||||
Color(0xFF4CAF50),
|
||||
Color(0xFFFFC107),
|
||||
]
|
||||
.map((c) => _SeedColorPickerItem(
|
||||
seedColor: c,
|
||||
onSelected: () => _onItemSelected(context, c),
|
||||
))
|
||||
.toList(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _onItemSelected(BuildContext context, Color seedColor) {
|
||||
Navigator.of(context).pop(seedColor);
|
||||
}
|
||||
}
|
||||
|
||||
class _SeedColorPickerItem extends StatelessWidget {
|
||||
const _SeedColorPickerItem({
|
||||
required this.seedColor,
|
||||
this.onSelected,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final content = SizedBox.square(
|
||||
dimension: _size,
|
||||
child: Center(
|
||||
child: Icon(
|
||||
Icons.circle,
|
||||
size: _size - _size * .1,
|
||||
color: seedColor,
|
||||
),
|
||||
),
|
||||
);
|
||||
if (onSelected != null) {
|
||||
return InkWell(
|
||||
customBorder: const CircleBorder(),
|
||||
onTap: onSelected,
|
||||
child: content,
|
||||
);
|
||||
} else {
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
final Color seedColor;
|
||||
final VoidCallback? onSelected;
|
||||
|
||||
static const _size = 56.0;
|
||||
}
|
||||
|
||||
class _MiscSettings extends StatefulWidget {
|
||||
const _MiscSettings({Key? key}) : super(key: key);
|
||||
|
||||
|
|
377
app/lib/widget/settings/theme_settings.dart
Normal file
377
app/lib/widget/settings/theme_settings.dart
Normal file
|
@ -0,0 +1,377 @@
|
|||
import 'package:event_bus/event_bus.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
|
||||
import 'package:kiwi/kiwi.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:nc_photos/app_localizations.dart';
|
||||
import 'package:nc_photos/event/event.dart';
|
||||
import 'package:nc_photos/k.dart' as k;
|
||||
import 'package:nc_photos/mobile/android/android_info.dart';
|
||||
import 'package:nc_photos/platform/k.dart' as platform_k;
|
||||
import 'package:nc_photos/pref.dart';
|
||||
import 'package:nc_photos/snack_bar_manager.dart';
|
||||
import 'package:nc_photos/theme.dart';
|
||||
|
||||
class ThemeSettings extends StatefulWidget {
|
||||
const ThemeSettings({super.key});
|
||||
|
||||
@override
|
||||
createState() => _ThemeSettingsState();
|
||||
}
|
||||
|
||||
class _ThemeSettingsState extends State<ThemeSettings> {
|
||||
@override
|
||||
initState() {
|
||||
super.initState();
|
||||
_isFollowSystemTheme = Pref().isFollowSystemThemeOr(false);
|
||||
_isUseBlackInDarkTheme = Pref().isUseBlackInDarkThemeOr(false);
|
||||
_seedColor = getSeedColor();
|
||||
}
|
||||
|
||||
@override
|
||||
build(BuildContext context) {
|
||||
return Scaffold(
|
||||
body: Builder(
|
||||
builder: (context) => _buildContent(context),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildContent(BuildContext context) {
|
||||
return CustomScrollView(
|
||||
slivers: [
|
||||
SliverAppBar(
|
||||
pinned: true,
|
||||
title: Text(L10n.global().settingsThemeTitle),
|
||||
),
|
||||
SliverList(
|
||||
delegate: SliverChildListDelegate(
|
||||
[
|
||||
ListTile(
|
||||
title: Text(L10n.global().settingsSeedColorTitle),
|
||||
trailing: Icon(
|
||||
Icons.circle,
|
||||
size: 32,
|
||||
color: _seedColor,
|
||||
),
|
||||
onTap: () => _onSeedColorPressed(context),
|
||||
),
|
||||
if (platform_k.isAndroid &&
|
||||
AndroidInfo().sdkInt >= AndroidVersion.Q)
|
||||
SwitchListTile(
|
||||
title: Text(L10n.global().settingsFollowSystemThemeTitle),
|
||||
value: _isFollowSystemTheme,
|
||||
onChanged: (value) => _onFollowSystemThemeChanged(value),
|
||||
),
|
||||
SwitchListTile(
|
||||
title: Text(L10n.global().settingsUseBlackInDarkThemeTitle),
|
||||
subtitle: Text(_isUseBlackInDarkTheme
|
||||
? L10n.global().settingsUseBlackInDarkThemeTrueDescription
|
||||
: L10n.global()
|
||||
.settingsUseBlackInDarkThemeFalseDescription),
|
||||
value: _isUseBlackInDarkTheme,
|
||||
onChanged: (value) =>
|
||||
_onUseBlackInDarkThemeChanged(context, value),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _onFollowSystemThemeChanged(bool value) async {
|
||||
final oldValue = _isFollowSystemTheme;
|
||||
setState(() {
|
||||
_isFollowSystemTheme = value;
|
||||
});
|
||||
if (await Pref().setFollowSystemTheme(value)) {
|
||||
KiwiContainer().resolve<EventBus>().fire(ThemeChangedEvent());
|
||||
} else {
|
||||
_log.severe("[_onFollowSystemThemeChanged] Failed writing pref");
|
||||
SnackBarManager().showSnackBar(SnackBar(
|
||||
content: Text(L10n.global().writePreferenceFailureNotification),
|
||||
duration: k.snackBarDurationNormal,
|
||||
));
|
||||
setState(() {
|
||||
_isFollowSystemTheme = oldValue;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onUseBlackInDarkThemeChanged(
|
||||
BuildContext context, bool value) async {
|
||||
final oldValue = _isUseBlackInDarkTheme;
|
||||
setState(() {
|
||||
_isUseBlackInDarkTheme = value;
|
||||
});
|
||||
if (await Pref().setUseBlackInDarkTheme(value)) {
|
||||
if (Theme.of(context).brightness == Brightness.dark) {
|
||||
KiwiContainer().resolve<EventBus>().fire(ThemeChangedEvent());
|
||||
}
|
||||
} else {
|
||||
_log.severe("[_onUseBlackInDarkThemeChanged] Failed writing pref");
|
||||
SnackBarManager().showSnackBar(SnackBar(
|
||||
content: Text(L10n.global().writePreferenceFailureNotification),
|
||||
duration: k.snackBarDurationNormal,
|
||||
));
|
||||
setState(() {
|
||||
_isUseBlackInDarkTheme = oldValue;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onSeedColorPressed(BuildContext context) async {
|
||||
final result = await showDialog<Color>(
|
||||
context: context,
|
||||
builder: (context) => const _SeedColorPicker(),
|
||||
);
|
||||
if (result == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final oldValue = _seedColor;
|
||||
setState(() {
|
||||
_seedColor = result;
|
||||
});
|
||||
if (await Pref().setSeedColor(result.withAlpha(0xFF).value)) {
|
||||
KiwiContainer().resolve<EventBus>().fire(ThemeChangedEvent());
|
||||
} else {
|
||||
_log.severe("[_onSeedColorPressed] Failed writing pref");
|
||||
SnackBarManager().showSnackBar(SnackBar(
|
||||
content: Text(L10n.global().writePreferenceFailureNotification),
|
||||
duration: k.snackBarDurationNormal,
|
||||
));
|
||||
setState(() {
|
||||
_seedColor = oldValue;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
late bool _isFollowSystemTheme;
|
||||
late bool _isUseBlackInDarkTheme;
|
||||
late Color _seedColor;
|
||||
|
||||
static final _log =
|
||||
Logger("widget.settings.theme_settings._ThemeSettingsState");
|
||||
}
|
||||
|
||||
class _SeedColorPicker extends StatefulWidget {
|
||||
const _SeedColorPicker();
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _SeedColorPickerState();
|
||||
}
|
||||
|
||||
class _SeedColorPickerState extends State<_SeedColorPicker> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Visibility(
|
||||
visible: _isVisible,
|
||||
child: AlertDialog(
|
||||
title: Text(L10n.global().settingsSeedColorPickerTitle),
|
||||
content: Wrap(
|
||||
children: const [
|
||||
Color(0xFFF44336),
|
||||
Color(0xFF9C27B0),
|
||||
Color(0xFF2196F3),
|
||||
Color(0xFF4CAF50),
|
||||
Color(0xFFFFC107),
|
||||
null,
|
||||
]
|
||||
.map((c) => _SeedColorPickerItem(
|
||||
seedColor: c,
|
||||
onSelected: () => _onItemSelected(context, c),
|
||||
))
|
||||
.toList(),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _onItemSelected(BuildContext context, Color? seedColor) async {
|
||||
if (seedColor != null) {
|
||||
Navigator.of(context).pop(seedColor);
|
||||
return;
|
||||
}
|
||||
setState(() {
|
||||
_isVisible = false;
|
||||
});
|
||||
final color = await showDialog<Color>(
|
||||
context: context,
|
||||
builder: (context) => const _SeedColorCustomPicker(),
|
||||
barrierColor: Colors.transparent,
|
||||
);
|
||||
Navigator.of(context).pop(color);
|
||||
}
|
||||
|
||||
var _isVisible = true;
|
||||
}
|
||||
|
||||
class _SeedColorCustomPicker extends StatefulWidget {
|
||||
const _SeedColorCustomPicker();
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => _SeedColorCustomPickerState();
|
||||
}
|
||||
|
||||
class _SeedColorCustomPickerState extends State<_SeedColorCustomPicker> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: Text(L10n.global().settingsSeedColorPickerTitle),
|
||||
content: SingleChildScrollView(
|
||||
child: _HueRingPicker(
|
||||
pickerColor: _customColor,
|
||||
onColorChanged: (value) {
|
||||
setState(() {
|
||||
_customColor = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop(_customColor);
|
||||
},
|
||||
child: Text(L10n.global().applyButtonLabel),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
late Color _customColor = getSeedColor();
|
||||
}
|
||||
|
||||
class _SeedColorPickerItem extends StatelessWidget {
|
||||
const _SeedColorPickerItem({
|
||||
required this.seedColor,
|
||||
this.onSelected,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final content = SizedBox.square(
|
||||
dimension: _size,
|
||||
child: Center(
|
||||
child: seedColor != null
|
||||
? Icon(
|
||||
Icons.circle,
|
||||
size: _size * .9,
|
||||
color: seedColor,
|
||||
)
|
||||
: Transform.scale(
|
||||
scale: .9,
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Image.asset("assets/ic_custom_color_56dp.png"),
|
||||
const Icon(
|
||||
Icons.colorize_outlined,
|
||||
size: _size * .5,
|
||||
color: Colors.black87,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
if (onSelected != null) {
|
||||
return InkWell(
|
||||
customBorder: const CircleBorder(),
|
||||
onTap: onSelected,
|
||||
child: content,
|
||||
);
|
||||
} else {
|
||||
return content;
|
||||
}
|
||||
}
|
||||
|
||||
final Color? seedColor;
|
||||
final VoidCallback? onSelected;
|
||||
|
||||
static const _size = 56.0;
|
||||
}
|
||||
|
||||
/// Based on the original HueRingPicker
|
||||
class _HueRingPicker extends StatefulWidget {
|
||||
const _HueRingPicker({
|
||||
Key? key,
|
||||
required this.pickerColor,
|
||||
required this.onColorChanged,
|
||||
// ignore: unused_element
|
||||
this.colorPickerHeight = 250.0,
|
||||
// ignore: unused_element
|
||||
this.hueRingStrokeWidth = 20.0,
|
||||
// ignore: unused_element
|
||||
this.displayThumbColor = true,
|
||||
// ignore: unused_element
|
||||
this.pickerAreaBorderRadius = const BorderRadius.all(Radius.zero),
|
||||
}) : super(key: key);
|
||||
|
||||
final Color pickerColor;
|
||||
final ValueChanged<Color> onColorChanged;
|
||||
final double colorPickerHeight;
|
||||
final double hueRingStrokeWidth;
|
||||
final bool displayThumbColor;
|
||||
final BorderRadius pickerAreaBorderRadius;
|
||||
|
||||
@override
|
||||
_HueRingPickerState createState() => _HueRingPickerState();
|
||||
}
|
||||
|
||||
class _HueRingPickerState extends State<_HueRingPicker> {
|
||||
HSVColor currentHsvColor = const HSVColor.fromAHSV(0.0, 0.0, 0.0, 0.0);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
currentHsvColor = HSVColor.fromColor(widget.pickerColor);
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(_HueRingPicker oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
currentHsvColor = HSVColor.fromColor(widget.pickerColor);
|
||||
}
|
||||
|
||||
void onColorChanging(HSVColor color) {
|
||||
setState(() => currentHsvColor = color.withSaturation(1).withValue(1));
|
||||
widget.onColorChanged(currentHsvColor.toColor());
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Stack(
|
||||
children: <Widget>[
|
||||
ClipRRect(
|
||||
borderRadius: widget.pickerAreaBorderRadius,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(18),
|
||||
child: Stack(
|
||||
alignment: AlignmentDirectional.center,
|
||||
children: <Widget>[
|
||||
ColorIndicator(
|
||||
currentHsvColor,
|
||||
width: 128,
|
||||
height: 128,
|
||||
),
|
||||
SizedBox(
|
||||
width: widget.colorPickerHeight,
|
||||
height: widget.colorPickerHeight,
|
||||
child: ColorPickerHueRing(
|
||||
currentHsvColor,
|
||||
onColorChanging,
|
||||
displayThumbColor: widget.displayThumbColor,
|
||||
strokeWidth: 26,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -497,6 +497,13 @@ packages:
|
|||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "3.3.0"
|
||||
flutter_colorpicker:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_colorpicker
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.3"
|
||||
flutter_isolate:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
|
|
@ -58,6 +58,7 @@ dependencies:
|
|||
url: https://gitlab.com/nc-photos/flutter_background_service.git
|
||||
ref: v0.2.6-nc-photos-2
|
||||
flutter_bloc: ^8.0.0
|
||||
flutter_colorpicker: ^1.0.3
|
||||
flutter_isolate:
|
||||
git:
|
||||
url: https://gitlab.com/nc-photos/flutter_isolate.git
|
||||
|
|
Loading…
Reference in a new issue