diff --git a/src/ui/flutter_app/lib/l10n/intl_en.arb b/src/ui/flutter_app/lib/l10n/intl_en.arb index 70e5b5ff..c8017cca 100644 --- a/src/ui/flutter_app/lib/l10n/intl_en.arb +++ b/src/ui/flutter_app/lib/l10n/intl_en.arb @@ -744,4 +744,9 @@ "@timeout": { "description": "Timeout" } + , + "personalization": "Personalization", + "@personalization": { + "description": "Personalization" + } } diff --git a/src/ui/flutter_app/lib/l10n/intl_zh.arb b/src/ui/flutter_app/lib/l10n/intl_zh.arb index 94147134..85fbccec 100644 --- a/src/ui/flutter_app/lib/l10n/intl_zh.arb +++ b/src/ui/flutter_app/lib/l10n/intl_zh.arb @@ -185,5 +185,6 @@ "aisPlayStyle": "机器的棋风", "passive": "消极被动", "automaticBehavior": "自动行为", - "timeout": "超时" + "timeout": "超时", + "personalization": "外观设置" } \ No newline at end of file diff --git a/src/ui/flutter_app/lib/widgets/game_settings_page.dart b/src/ui/flutter_app/lib/widgets/game_settings_page.dart index ccf0fcc0..8b60c7f2 100644 --- a/src/ui/flutter_app/lib/widgets/game_settings_page.dart +++ b/src/ui/flutter_app/lib/widgets/game_settings_page.dart @@ -19,7 +19,6 @@ import 'dart:io'; import 'package:flutter/material.dart'; -import 'package:flutter_colorpicker/flutter_colorpicker.dart'; import 'package:sanmill/common/config.dart'; import 'package:sanmill/common/settings.dart'; import 'package:sanmill/generated/l10n.dart'; @@ -46,69 +45,6 @@ class _GameSettingsPageState extends State { super.initState(); } - // ValueChanged callback - void changeColor(Color color) { - setState(() => pickerColor = color); - } - - showColorDialog(String colorString) async { - Map colorStrToVal = { - S.of(context).boardColor: Config.boardBackgroundColor, - S.of(context).backgroudColor: Config.darkBackgroundColor, - S.of(context).lineColor: Config.boardLineColor, - S.of(context).blackPieceColor: Config.blackPieceColor, - S.of(context).whitePieceColor: Config.whitePieceColor, - }; - - AlertDialog alert = AlertDialog( - title: Text(S.of(context).pick + colorString), - content: SingleChildScrollView( - child: ColorPicker( - pickerColor: Color(colorStrToVal[colorString]!), - onColorChanged: changeColor, - showLabel: true, - ), - ), - actions: [ - TextButton( - child: Text(S.of(context).confirm), - onPressed: () { - setState(() => currentColor = pickerColor); - - if (colorString == S.of(context).boardColor) { - Config.boardBackgroundColor = pickerColor.value; - } else if (colorString == S.of(context).backgroudColor) { - Config.darkBackgroundColor = pickerColor.value; - } else if (colorString == S.of(context).lineColor) { - Config.boardLineColor = pickerColor.value; - } else if (colorString == S.of(context).blackPieceColor) { - Config.blackPieceColor = pickerColor.value; - } else if (colorString == S.of(context).whitePieceColor) { - Config.whitePieceColor = pickerColor.value; - } - - Config.save(); - Navigator.of(context).pop(); - }, - ), - TextButton( - child: Text(S.of(context).cancel), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - ], - ); - - // show the dialog - showDialog( - context: context, - builder: (BuildContext context) { - return alert; - }, - ); - } - SliderTheme _skillLevelSliderTheme(context, setState) { return SliderTheme( data: AppTheme.sliderThemeData, @@ -129,68 +65,6 @@ class _GameSettingsPageState extends State { ); } - SliderTheme _boardBorderLineWidthSliderTheme(context, setState) { - return SliderTheme( - data: AppTheme.sliderThemeData, - child: Slider( - value: Config.boardBorderLineWidth.toDouble(), - min: 0.0, - max: 20.0, - divisions: 200, - label: Config.boardBorderLineWidth.toStringAsFixed(1), - onChanged: (value) { - setState(() { - print("BoardBorderLineWidth value: $value"); - Config.boardBorderLineWidth = value; - Config.save(); - }); - }, - ), - ); - } - - setBoardBorderLineWidth() async { - showModalBottomSheet( - context: context, - builder: (BuildContext context) => StatefulBuilder( - builder: (context, setState) { - return _boardBorderLineWidthSliderTheme(context, setState); - }, - ), - ); - } - - SliderTheme _boardInnerLineWidthSliderTheme(context, setState) { - return SliderTheme( - data: AppTheme.sliderThemeData, - child: Slider( - value: Config.boardInnerLineWidth.toDouble(), - min: 0.0, - max: 20.0, - divisions: 200, - label: Config.boardInnerLineWidth.toStringAsFixed(1), - onChanged: (value) { - setState(() { - print("BoardInnerLineWidth value: $value"); - Config.boardInnerLineWidth = value; - Config.save(); - }); - }, - ), - ); - } - - setBoardInnerLineWidth() async { - showModalBottomSheet( - context: context, - builder: (BuildContext context) => StatefulBuilder( - builder: (context, setState) { - return _boardInnerLineWidthSliderTheme(context, setState); - }, - ), - ); - } - // Restore restoreFactoryDefaultSettings() async { @@ -316,71 +190,6 @@ class _GameSettingsPageState extends State { ], ), AppTheme.sizedBox, - Text(S.of(context).display, style: AppTheme.settingsHeaderStyle), - SettingsCard( - context: context, - children: [ - SettingsSwitchListTile( - context: context, - value: Config.isPieceCountInHandShown, - onChanged: setIsPieceCountInHandShown, - titleString: S.of(context).isPieceCountInHandShown, - ), - ListItemDivider(), - SettingsListTile( - context: context, - titleString: S.of(context).boardBorderLineWidth, - onTap: setBoardBorderLineWidth), - ListItemDivider(), - SettingsListTile( - context: context, - titleString: S.of(context).boardInnerLineWidth, - onTap: setBoardInnerLineWidth, - ), - ], - ), - AppTheme.sizedBox, - Text(S.of(context).color, style: AppTheme.settingsHeaderStyle), - SettingsCard( - context: context, - children: [ - SettingsListTile( - context: context, - titleString: S.of(context).boardColor, - trailingColor: Config.boardBackgroundColor, - onTap: () => showColorDialog(S.of(context).boardColor), - ), - ListItemDivider(), - SettingsListTile( - context: context, - titleString: S.of(context).backgroudColor, - trailingColor: Config.darkBackgroundColor, - onTap: () => showColorDialog(S.of(context).backgroudColor), - ), - ListItemDivider(), - SettingsListTile( - context: context, - titleString: S.of(context).lineColor, - trailingColor: Config.boardLineColor, - onTap: () => showColorDialog(S.of(context).lineColor), - ), - ListItemDivider(), - SettingsListTile( - context: context, - titleString: S.of(context).blackPieceColor, - trailingColor: Config.blackPieceColor, - onTap: () => showColorDialog(S.of(context).blackPieceColor), - ), - ListItemDivider(), - SettingsListTile( - context: context, - titleString: S.of(context).whitePieceColor, - trailingColor: Config.whitePieceColor, - onTap: () => showColorDialog(S.of(context).whitePieceColor), - ), - ], - ), - AppTheme.sizedBox, Text(S.of(context).restore, style: AppTheme.settingsHeaderStyle), SettingsCard( context: context, diff --git a/src/ui/flutter_app/lib/widgets/home_drawer.dart b/src/ui/flutter_app/lib/widgets/home_drawer.dart index 13c308c9..147ee877 100644 --- a/src/ui/flutter_app/lib/widgets/home_drawer.dart +++ b/src/ui/flutter_app/lib/widgets/home_drawer.dart @@ -56,6 +56,11 @@ class _HomeDrawerState extends State { labelName: S.of(context).ruleSettings, icon: Icon(Icons.rule), ), + DrawerList( + index: DrawerIndex.personalization, + labelName: S.of(context).personalization, + icon: Icon(Icons.color_lens), + ), DrawerList( index: DrawerIndex.Help, labelName: S.of(context).help, @@ -331,6 +336,7 @@ enum DrawerIndex { aiVsAi, settings, ruleSettings, + personalization, Help, About } diff --git a/src/ui/flutter_app/lib/widgets/navigation_home_screen.dart b/src/ui/flutter_app/lib/widgets/navigation_home_screen.dart index 34940b9e..ca675c46 100644 --- a/src/ui/flutter_app/lib/widgets/navigation_home_screen.dart +++ b/src/ui/flutter_app/lib/widgets/navigation_home_screen.dart @@ -10,6 +10,7 @@ import 'package:sanmill/widgets/home_drawer.dart'; import 'game_page.dart'; import 'game_settings_page.dart'; import 'rule_settings_page.dart'; +import 'personalization_settings_page.dart'; class NavigationHomeScreen extends StatefulWidget { @override @@ -81,6 +82,10 @@ class _NavigationHomeScreenState extends State { setState(() { screenView = RuleSettingsPage(); }); + } else if (drawerIndex == DrawerIndex.personalization) { + setState(() { + screenView = PersonalizationSettingsPage(); + }); } else if (drawerIndex == DrawerIndex.Help) { setState(() { screenView = HelpScreen(); diff --git a/src/ui/flutter_app/lib/widgets/personalization_settings_page.dart b/src/ui/flutter_app/lib/widgets/personalization_settings_page.dart new file mode 100644 index 00000000..e5b2bc25 --- /dev/null +++ b/src/ui/flutter_app/lib/widgets/personalization_settings_page.dart @@ -0,0 +1,269 @@ +/* + This file is part of Sanmill. + Copyright (C) 2019-2021 The Sanmill developers (see AUTHORS file) + + Sanmill is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Sanmill is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +import 'package:flutter/material.dart'; +import 'package:flutter_colorpicker/flutter_colorpicker.dart'; +import 'package:sanmill/common/config.dart'; +import 'package:sanmill/generated/l10n.dart'; +import 'package:sanmill/style/app_theme.dart'; +import 'package:sanmill/style/colors.dart'; +import 'package:sanmill/widgets/settings_card.dart'; +import 'package:sanmill/widgets/settings_list_tile.dart'; +import 'package:sanmill/widgets/settings_switch_list_tile.dart'; + +import 'list_item_divider.dart'; + +class PersonalizationSettingsPage extends StatefulWidget { + @override + _PersonalizationSettingsPageState createState() => + _PersonalizationSettingsPageState(); +} + +class _PersonalizationSettingsPageState + extends State { + // create some values + Color pickerColor = Color(0xFF808080); + Color currentColor = Color(0xFF808080); + + @override + void initState() { + super.initState(); + } + + // ValueChanged callback + void changeColor(Color color) { + setState(() => pickerColor = color); + } + + showColorDialog(String colorString) async { + Map colorStrToVal = { + S.of(context).boardColor: Config.boardBackgroundColor, + S.of(context).backgroudColor: Config.darkBackgroundColor, + S.of(context).lineColor: Config.boardLineColor, + S.of(context).blackPieceColor: Config.blackPieceColor, + S.of(context).whitePieceColor: Config.whitePieceColor, + }; + + AlertDialog alert = AlertDialog( + title: Text(S.of(context).pick + colorString), + content: SingleChildScrollView( + child: ColorPicker( + pickerColor: Color(colorStrToVal[colorString]!), + onColorChanged: changeColor, + showLabel: true, + ), + ), + actions: [ + TextButton( + child: Text(S.of(context).confirm), + onPressed: () { + setState(() => currentColor = pickerColor); + + if (colorString == S.of(context).boardColor) { + Config.boardBackgroundColor = pickerColor.value; + } else if (colorString == S.of(context).backgroudColor) { + Config.darkBackgroundColor = pickerColor.value; + } else if (colorString == S.of(context).lineColor) { + Config.boardLineColor = pickerColor.value; + } else if (colorString == S.of(context).blackPieceColor) { + Config.blackPieceColor = pickerColor.value; + } else if (colorString == S.of(context).whitePieceColor) { + Config.whitePieceColor = pickerColor.value; + } + + Config.save(); + Navigator.of(context).pop(); + }, + ), + TextButton( + child: Text(S.of(context).cancel), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ); + + // show the dialog + showDialog( + context: context, + builder: (BuildContext context) { + return alert; + }, + ); + } + + SliderTheme _boardBorderLineWidthSliderTheme(context, setState) { + return SliderTheme( + data: AppTheme.sliderThemeData, + child: Slider( + value: Config.boardBorderLineWidth.toDouble(), + min: 0.0, + max: 20.0, + divisions: 200, + label: Config.boardBorderLineWidth.toStringAsFixed(1), + onChanged: (value) { + setState(() { + print("BoardBorderLineWidth value: $value"); + Config.boardBorderLineWidth = value; + Config.save(); + }); + }, + ), + ); + } + + setBoardBorderLineWidth() async { + showModalBottomSheet( + context: context, + builder: (BuildContext context) => StatefulBuilder( + builder: (context, setState) { + return _boardBorderLineWidthSliderTheme(context, setState); + }, + ), + ); + } + + SliderTheme _boardInnerLineWidthSliderTheme(context, setState) { + return SliderTheme( + data: AppTheme.sliderThemeData, + child: Slider( + value: Config.boardInnerLineWidth.toDouble(), + min: 0.0, + max: 20.0, + divisions: 200, + label: Config.boardInnerLineWidth.toStringAsFixed(1), + onChanged: (value) { + setState(() { + print("BoardInnerLineWidth value: $value"); + Config.boardInnerLineWidth = value; + Config.save(); + }); + }, + ), + ); + } + + setBoardInnerLineWidth() async { + showModalBottomSheet( + context: context, + builder: (BuildContext context) => StatefulBuilder( + builder: (context, setState) { + return _boardInnerLineWidthSliderTheme(context, setState); + }, + ), + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: UIColors.lightBackgroundColor, + appBar: AppBar( + centerTitle: true, + title: Text(S.of(context).personalization), + backgroundColor: UIColors.primaryColor), + body: SingleChildScrollView( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: children(context), + ), + ), + ); + } + + List children(BuildContext context) { + return [ + Text(S.of(context).display, style: AppTheme.settingsHeaderStyle), + SettingsCard( + context: context, + children: [ + SettingsSwitchListTile( + context: context, + value: Config.isPieceCountInHandShown, + onChanged: setIsPieceCountInHandShown, + titleString: S.of(context).isPieceCountInHandShown, + ), + ListItemDivider(), + SettingsListTile( + context: context, + titleString: S.of(context).boardBorderLineWidth, + onTap: setBoardBorderLineWidth), + ListItemDivider(), + SettingsListTile( + context: context, + titleString: S.of(context).boardInnerLineWidth, + onTap: setBoardInnerLineWidth, + ), + ], + ), + AppTheme.sizedBox, + Text(S.of(context).color, style: AppTheme.settingsHeaderStyle), + SettingsCard( + context: context, + children: [ + SettingsListTile( + context: context, + titleString: S.of(context).boardColor, + trailingColor: Config.boardBackgroundColor, + onTap: () => showColorDialog(S.of(context).boardColor), + ), + ListItemDivider(), + SettingsListTile( + context: context, + titleString: S.of(context).backgroudColor, + trailingColor: Config.darkBackgroundColor, + onTap: () => showColorDialog(S.of(context).backgroudColor), + ), + ListItemDivider(), + SettingsListTile( + context: context, + titleString: S.of(context).lineColor, + trailingColor: Config.boardLineColor, + onTap: () => showColorDialog(S.of(context).lineColor), + ), + ListItemDivider(), + SettingsListTile( + context: context, + titleString: S.of(context).blackPieceColor, + trailingColor: Config.blackPieceColor, + onTap: () => showColorDialog(S.of(context).blackPieceColor), + ), + ListItemDivider(), + SettingsListTile( + context: context, + titleString: S.of(context).whitePieceColor, + trailingColor: Config.whitePieceColor, + onTap: () => showColorDialog(S.of(context).whitePieceColor), + ), + ], + ), + ]; + } + + // Display + + setIsPieceCountInHandShown(bool value) async { + setState(() { + Config.isPieceCountInHandShown = value; + }); + + Config.save(); + } +}