reactive storage and db migration
- make new storage reactive - add Database Migrator change how the developerMode reacts
This commit is contained in:
parent
ef2b888410
commit
e93f62b455
|
@ -13,4 +13,3 @@ analyzer:
|
|||
# generated code
|
||||
- lib/generated/**
|
||||
- lib/**/**.g.dart
|
||||
- lib/l10n/**
|
||||
|
|
|
@ -25,52 +25,52 @@ import 'package:sanmill/shared/constants.dart';
|
|||
import 'package:sanmill/shared/list_item_divider.dart';
|
||||
import 'package:sanmill/shared/theme/app_theme.dart';
|
||||
|
||||
Map<String, Strings> languageCodeToStrings = {
|
||||
"ar": ArabicStrings(),
|
||||
"bg": BulgarianStrings(),
|
||||
"bn": BengaliStrings(),
|
||||
"cs": CzechStrings(),
|
||||
"da": DanishStrings(),
|
||||
"de": GermanStrings(),
|
||||
"de_CH": SwissGermanStrings(),
|
||||
"el": GreekStrings(),
|
||||
"en": EnglishStrings(),
|
||||
"es": SpanishStrings(),
|
||||
"et": EstonianStrings(),
|
||||
"fa": FarsiStrings(),
|
||||
"fi": FinnishStrings(),
|
||||
"fr": FrenchStrings(),
|
||||
"gu": GujaratiStrings(),
|
||||
"hi": HindiStrings(),
|
||||
"hr": CroatianStrings(),
|
||||
"hu": HungarianStrings(),
|
||||
"id": IndonesianStrings(),
|
||||
"it": ItalianStrings(),
|
||||
"ja": JapaneseStrings(),
|
||||
"kn": KannadaStrings(),
|
||||
"ko": KoreanStrings(),
|
||||
"lt": LithuanianStrings(),
|
||||
"lv": LatvianStrings(),
|
||||
"mk": MacedonianStrings(),
|
||||
"ms": MalayStrings(),
|
||||
"nl": DutchStrings(),
|
||||
"nn": NorwegianStrings(),
|
||||
"pl": PolishStrings(),
|
||||
"pt": PortugueseStrings(),
|
||||
"ro": RomanianStrings(),
|
||||
"ru": RussianStrings(),
|
||||
"sk": SlovakStrings(),
|
||||
"sl": SlovenianStrings(),
|
||||
"sq": AlbanianStrings(),
|
||||
"sr": SerbianStrings(),
|
||||
"sv": SwedishStrings(),
|
||||
"te": TeluguStrings(),
|
||||
"th": ThaiStrings(),
|
||||
"tr": TurkishStrings(),
|
||||
"uz": UzbekStrings(),
|
||||
"vi": VietnameseStrings(),
|
||||
"zh": ChineseStrings(),
|
||||
"zh_Hant": TraditionalChineseStrings(),
|
||||
Map<Locale, Strings> languageCodeToStrings = {
|
||||
const Locale("ar"): ArabicStrings(),
|
||||
const Locale("bg"): BulgarianStrings(),
|
||||
const Locale("bn"): BengaliStrings(),
|
||||
const Locale("cs"): CzechStrings(),
|
||||
const Locale("da"): DanishStrings(),
|
||||
const Locale("de"): GermanStrings(),
|
||||
const Locale("de_CH"): SwissGermanStrings(),
|
||||
const Locale("el"): GreekStrings(),
|
||||
const Locale("en"): EnglishStrings(),
|
||||
const Locale("es"): SpanishStrings(),
|
||||
const Locale("et"): EstonianStrings(),
|
||||
const Locale("fa"): FarsiStrings(),
|
||||
const Locale("fi"): FinnishStrings(),
|
||||
const Locale("fr"): FrenchStrings(),
|
||||
const Locale("gu"): GujaratiStrings(),
|
||||
const Locale("hi"): HindiStrings(),
|
||||
const Locale("hr"): CroatianStrings(),
|
||||
const Locale("hu"): HungarianStrings(),
|
||||
const Locale("id"): IndonesianStrings(),
|
||||
const Locale("it"): ItalianStrings(),
|
||||
const Locale("ja"): JapaneseStrings(),
|
||||
const Locale("kn"): KannadaStrings(),
|
||||
const Locale("ko"): KoreanStrings(),
|
||||
const Locale("lt"): LithuanianStrings(),
|
||||
const Locale("lv"): LatvianStrings(),
|
||||
const Locale("mk"): MacedonianStrings(),
|
||||
const Locale("ms"): MalayStrings(),
|
||||
const Locale("nl"): DutchStrings(),
|
||||
const Locale("nn"): NorwegianStrings(),
|
||||
const Locale("pl"): PolishStrings(),
|
||||
const Locale("pt"): PortugueseStrings(),
|
||||
const Locale("ro"): RomanianStrings(),
|
||||
const Locale("ru"): RussianStrings(),
|
||||
const Locale("sk"): SlovakStrings(),
|
||||
const Locale("sl"): SlovenianStrings(),
|
||||
const Locale("sq"): AlbanianStrings(),
|
||||
const Locale("sr"): SerbianStrings(),
|
||||
const Locale("sv"): SwedishStrings(),
|
||||
const Locale("te"): TeluguStrings(),
|
||||
const Locale("th"): ThaiStrings(),
|
||||
const Locale("tr"): TurkishStrings(),
|
||||
const Locale("uz"): UzbekStrings(),
|
||||
const Locale("vi"): VietnameseStrings(),
|
||||
const Locale("zh"): ChineseStrings(),
|
||||
const Locale("zh_Hant"): TraditionalChineseStrings(),
|
||||
};
|
||||
|
||||
/// Interface strings
|
||||
|
@ -489,8 +489,8 @@ class TraditionalChineseStrings extends Strings {
|
|||
String get tapBackAgainToLeave => '再次按 Back 鍵退出';
|
||||
}
|
||||
|
||||
final supportedLocales = [
|
||||
for (var i in languageCodeToStrings.keys) Locale.fromSubtags(languageCode: i),
|
||||
final List<Locale> supportedLocales = [
|
||||
...languageCodeToStrings.keys,
|
||||
];
|
||||
|
||||
class Resources {
|
||||
|
@ -514,6 +514,7 @@ class Resources {
|
|||
return ret;
|
||||
}
|
||||
|
||||
// ignore: prefer_constructors_over_static_methods
|
||||
static Resources of() {
|
||||
return Resources();
|
||||
}
|
||||
|
@ -539,7 +540,7 @@ Future<void> setLanguage(
|
|||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: Text(languageCodeToStrings[i]!.languageName),
|
||||
groupValue: LocalDatabaseService.display.languageCode,
|
||||
value: Locale(i),
|
||||
value: i,
|
||||
onChanged: callback,
|
||||
),
|
||||
],
|
||||
|
@ -572,7 +573,7 @@ Bidirectionality getBidirectionality(BuildContext context) {
|
|||
currentLocale.languageCode == "he" ||
|
||||
currentLocale.languageCode == "ps" ||
|
||||
currentLocale.languageCode == "ur") {
|
||||
print("bidirectionality: RTL");
|
||||
debugPrint("bidirectionality: RTL");
|
||||
return Bidirectionality.rightToLeft;
|
||||
} else {
|
||||
return Bidirectionality.leftToRight;
|
||||
|
@ -593,5 +594,5 @@ void setSpecialCountryAndRegion(BuildContext context) {
|
|||
break;
|
||||
}
|
||||
|
||||
print("Set Special Country and Region to $specialCountryAndRegion.");
|
||||
debugPrint("Set Special Country and Region to $specialCountryAndRegion.");
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import 'package:sanmill/l10n/resources.dart';
|
|||
import 'package:sanmill/screens/navigation_home_screen.dart';
|
||||
import 'package:sanmill/services/audios.dart';
|
||||
import 'package:sanmill/services/storage/storage.dart';
|
||||
import 'package:sanmill/services/storage/storage_v1.dart';
|
||||
import 'package:sanmill/shared/constants.dart';
|
||||
import 'package:sanmill/shared/theme/app_theme.dart';
|
||||
|
||||
|
@ -38,8 +39,9 @@ part 'package:sanmill/services/catcher.dart';
|
|||
|
||||
Future<void> main() async {
|
||||
await LocalDatabaseService.initStorage();
|
||||
await DatabaseV1.migrateDB();
|
||||
final catcher = Catcher(
|
||||
rootWidget: BetterFeedback(
|
||||
rootWidget: const BetterFeedback(
|
||||
child: SanmillApp(),
|
||||
//localeOverride: Locale(Resources.of().languageCode),
|
||||
),
|
||||
|
@ -73,10 +75,11 @@ Future<void> main() async {
|
|||
RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>();
|
||||
|
||||
class SanmillApp extends StatelessWidget {
|
||||
final globalScaffoldKey = GlobalKey<ScaffoldState>();
|
||||
const SanmillApp({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final globalScaffoldKey = GlobalKey<ScaffoldState>();
|
||||
Audios.loadSounds();
|
||||
|
||||
setSpecialCountryAndRegion(context);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
import 'package:sanmill/l10n/resources.dart';
|
||||
|
||||
// TODO: deprecate this thingy. No reason to keep it
|
||||
class Rule {
|
||||
String name = "Default Rule";
|
||||
String description = "";
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:copy_with_extension/copy_with_extension.dart';
|
||||
import 'package:flutter/widgets.dart' show Color, immutable;
|
||||
import 'package:hive_flutter/adapters.dart'
|
||||
show HiveField, HiveType, BinaryReader, BinaryWriter, TypeAdapter;
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
@ -25,11 +26,15 @@ import 'package:sanmill/shared/theme/app_theme.dart';
|
|||
|
||||
part 'color.g.dart';
|
||||
|
||||
// TODO: make AppTheme colors const so this file can be cleaner
|
||||
|
||||
/// Color data model
|
||||
///
|
||||
/// holds the data needed for the Color Settings
|
||||
@HiveType(typeId: 0)
|
||||
@JsonSerializable()
|
||||
@CopyWith()
|
||||
@immutable
|
||||
class ColorSettings {
|
||||
ColorSettings({
|
||||
Color? boardLineColor,
|
||||
|
@ -67,7 +72,7 @@ class ColorSettings {
|
|||
this.mainToolbarBackgroundColor =
|
||||
mainToolbarBackgroundColor ?? AppTheme.mainToolbarBackgroundColor;
|
||||
this.mainToolbarIconColor =
|
||||
mainToolbarIconColor ?? AppTheme.mainToolbarBackgroundColor;
|
||||
mainToolbarIconColor ?? AppTheme.mainToolbarIconColor;
|
||||
this.navigationToolbarBackgroundColor = navigationToolbarBackgroundColor ??
|
||||
AppTheme.navigationToolbarBackgroundColor;
|
||||
this.navigationToolbarIconColor =
|
||||
|
@ -78,105 +83,105 @@ class ColorSettings {
|
|||
toJson: ColorAdapter.colorToJson,
|
||||
)
|
||||
@HiveField(0)
|
||||
late Color boardLineColor;
|
||||
late final Color boardLineColor;
|
||||
|
||||
@JsonKey(
|
||||
fromJson: ColorAdapter.colorFromJson,
|
||||
toJson: ColorAdapter.colorToJson,
|
||||
)
|
||||
@HiveField(1)
|
||||
late Color darkBackgroundColor;
|
||||
late final Color darkBackgroundColor;
|
||||
|
||||
@JsonKey(
|
||||
fromJson: ColorAdapter.colorFromJson,
|
||||
toJson: ColorAdapter.colorToJson,
|
||||
)
|
||||
@HiveField(2)
|
||||
late Color boardBackgroundColor;
|
||||
late final Color boardBackgroundColor;
|
||||
|
||||
@JsonKey(
|
||||
fromJson: ColorAdapter.colorFromJson,
|
||||
toJson: ColorAdapter.colorToJson,
|
||||
)
|
||||
@HiveField(3)
|
||||
late Color whitePieceColor;
|
||||
late final Color whitePieceColor;
|
||||
|
||||
@JsonKey(
|
||||
fromJson: ColorAdapter.colorFromJson,
|
||||
toJson: ColorAdapter.colorToJson,
|
||||
)
|
||||
@HiveField(4)
|
||||
late Color blackPieceColor;
|
||||
late final Color blackPieceColor;
|
||||
|
||||
@JsonKey(
|
||||
fromJson: ColorAdapter.colorFromJson,
|
||||
toJson: ColorAdapter.colorToJson,
|
||||
)
|
||||
@HiveField(5)
|
||||
late Color pieceHighlightColor;
|
||||
late final Color pieceHighlightColor;
|
||||
|
||||
@JsonKey(
|
||||
fromJson: ColorAdapter.colorFromJson,
|
||||
toJson: ColorAdapter.colorToJson,
|
||||
)
|
||||
@HiveField(6)
|
||||
late Color messageColor;
|
||||
late final Color messageColor;
|
||||
|
||||
@JsonKey(
|
||||
fromJson: ColorAdapter.colorFromJson,
|
||||
toJson: ColorAdapter.colorToJson,
|
||||
)
|
||||
@HiveField(7)
|
||||
late Color drawerColor;
|
||||
late final Color drawerColor;
|
||||
|
||||
@JsonKey(
|
||||
fromJson: ColorAdapter.colorFromJson,
|
||||
toJson: ColorAdapter.colorToJson,
|
||||
)
|
||||
@HiveField(8)
|
||||
late Color drawerBackgroundColor;
|
||||
late final Color drawerBackgroundColor;
|
||||
|
||||
@JsonKey(
|
||||
fromJson: ColorAdapter.colorFromJson,
|
||||
toJson: ColorAdapter.colorToJson,
|
||||
)
|
||||
@HiveField(9)
|
||||
late Color drawerTextColor;
|
||||
late final Color drawerTextColor;
|
||||
|
||||
@JsonKey(
|
||||
fromJson: ColorAdapter.colorFromJson,
|
||||
toJson: ColorAdapter.colorToJson,
|
||||
)
|
||||
@HiveField(10)
|
||||
late Color drawerHighlightItemColor;
|
||||
late final Color drawerHighlightItemColor;
|
||||
|
||||
@JsonKey(
|
||||
fromJson: ColorAdapter.colorFromJson,
|
||||
toJson: ColorAdapter.colorToJson,
|
||||
)
|
||||
@HiveField(11)
|
||||
late Color mainToolbarBackgroundColor;
|
||||
late final Color mainToolbarBackgroundColor;
|
||||
|
||||
@JsonKey(
|
||||
fromJson: ColorAdapter.colorFromJson,
|
||||
toJson: ColorAdapter.colorToJson,
|
||||
)
|
||||
@HiveField(12)
|
||||
late Color mainToolbarIconColor;
|
||||
late final Color mainToolbarIconColor;
|
||||
|
||||
@JsonKey(
|
||||
fromJson: ColorAdapter.colorFromJson,
|
||||
toJson: ColorAdapter.colorToJson,
|
||||
)
|
||||
@HiveField(13)
|
||||
late Color navigationToolbarBackgroundColor;
|
||||
late final Color navigationToolbarBackgroundColor;
|
||||
|
||||
@JsonKey(
|
||||
fromJson: ColorAdapter.colorFromJson,
|
||||
toJson: ColorAdapter.colorToJson,
|
||||
)
|
||||
@HiveField(14)
|
||||
late Color navigationToolbarIconColor;
|
||||
late final Color navigationToolbarIconColor;
|
||||
|
||||
/// encodes a Json style map Coloro a [ColorSettings] obbject
|
||||
factory ColorSettings.fromJson(Map<String, dynamic> json) =>
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:copy_with_extension/copy_with_extension.dart';
|
||||
import 'package:flutter/material.dart' show Locale, immutable;
|
||||
import 'package:hive_flutter/adapters.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:sanmill/services/storage/adapters/locale_adapter.dart';
|
||||
|
@ -29,6 +30,8 @@ part 'display.g.dart';
|
|||
/// holds the data needed for the Display Settings
|
||||
@HiveType(typeId: 1)
|
||||
@JsonSerializable()
|
||||
@CopyWith()
|
||||
@immutable
|
||||
class Display {
|
||||
Display({
|
||||
this.languageCode = Constants.defaultLocale,
|
||||
|
@ -54,43 +57,43 @@ class Display {
|
|||
fromJson: LocaleAdapter.colorFromJson,
|
||||
toJson: LocaleAdapter.colorToJson,
|
||||
)
|
||||
Locale languageCode;
|
||||
final Locale languageCode;
|
||||
|
||||
@HiveField(1)
|
||||
bool standardNotationEnabled;
|
||||
final bool standardNotationEnabled;
|
||||
|
||||
@HiveField(2)
|
||||
bool isPieceCountInHandShown;
|
||||
final bool isPieceCountInHandShown;
|
||||
|
||||
@HiveField(3)
|
||||
bool isNotationsShown;
|
||||
final bool isNotationsShown;
|
||||
|
||||
@HiveField(4)
|
||||
bool isHistoryNavigationToolbarShown;
|
||||
final bool isHistoryNavigationToolbarShown;
|
||||
|
||||
@HiveField(5)
|
||||
double boardBorderLineWidth;
|
||||
final double boardBorderLineWidth;
|
||||
|
||||
@HiveField(6)
|
||||
double boardInnerLineWidth;
|
||||
final double boardInnerLineWidth;
|
||||
|
||||
@HiveField(7)
|
||||
int pointStyle;
|
||||
final int pointStyle;
|
||||
|
||||
@HiveField(8)
|
||||
double pointWidth;
|
||||
final double pointWidth;
|
||||
|
||||
@HiveField(9)
|
||||
double pieceWidth;
|
||||
final double pieceWidth;
|
||||
|
||||
@HiveField(10)
|
||||
double fontSize;
|
||||
final double fontSize;
|
||||
|
||||
@HiveField(11)
|
||||
late double boardTop;
|
||||
late final double boardTop;
|
||||
|
||||
@HiveField(12)
|
||||
double animationDuration;
|
||||
final double animationDuration;
|
||||
|
||||
/// encodes a Json style map into a [Display] obbject
|
||||
factory Display.fromJson(Map<String, dynamic> json) =>
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import 'package:copy_with_extension/copy_with_extension.dart';
|
||||
import 'package:flutter/foundation.dart' show immutable;
|
||||
import 'package:hive_flutter/adapters.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
|
@ -26,8 +28,10 @@ part 'preferences.g.dart';
|
|||
/// holds the data needed for the normal Settings
|
||||
@HiveType(typeId: 2)
|
||||
@JsonSerializable()
|
||||
@CopyWith()
|
||||
@immutable
|
||||
class Preferences {
|
||||
Preferences({
|
||||
const Preferences({
|
||||
this.isPrivacyPolicyAccepted = false,
|
||||
this.usesHiveDB = false,
|
||||
this.toneEnabled = true,
|
||||
|
@ -51,46 +55,46 @@ class Preferences {
|
|||
});
|
||||
|
||||
@HiveField(0)
|
||||
bool isPrivacyPolicyAccepted;
|
||||
final bool isPrivacyPolicyAccepted;
|
||||
@HiveField(1)
|
||||
bool usesHiveDB;
|
||||
final bool usesHiveDB;
|
||||
|
||||
@HiveField(2)
|
||||
bool toneEnabled;
|
||||
final bool toneEnabled;
|
||||
@HiveField(3)
|
||||
bool keepMuteWhenTakingBack;
|
||||
final bool keepMuteWhenTakingBack;
|
||||
@HiveField(4)
|
||||
bool screenReaderSupport;
|
||||
final bool screenReaderSupport;
|
||||
@HiveField(5)
|
||||
bool aiMovesFirst;
|
||||
final bool aiMovesFirst;
|
||||
@HiveField(6)
|
||||
bool aiIsLazy;
|
||||
final bool aiIsLazy;
|
||||
@HiveField(7)
|
||||
int skillLevel;
|
||||
final int skillLevel;
|
||||
@HiveField(8)
|
||||
int moveTime;
|
||||
final int moveTime;
|
||||
@HiveField(9)
|
||||
bool isAutoRestart;
|
||||
final bool isAutoRestart;
|
||||
@HiveField(10)
|
||||
bool isAutoChangeFirstMove;
|
||||
final bool isAutoChangeFirstMove;
|
||||
@HiveField(11)
|
||||
bool resignIfMostLose;
|
||||
final bool resignIfMostLose;
|
||||
@HiveField(12)
|
||||
bool shufflingEnabled;
|
||||
final bool shufflingEnabled;
|
||||
@HiveField(13)
|
||||
bool learnEndgame;
|
||||
final bool learnEndgame;
|
||||
@HiveField(14)
|
||||
bool openingBook;
|
||||
final bool openingBook;
|
||||
@HiveField(15)
|
||||
int algorithm;
|
||||
final int algorithm;
|
||||
@HiveField(16)
|
||||
bool drawOnHumanExperience;
|
||||
final bool drawOnHumanExperience;
|
||||
@HiveField(17)
|
||||
bool considerMobility;
|
||||
final bool considerMobility;
|
||||
@HiveField(18)
|
||||
bool developerMode;
|
||||
final bool developerMode;
|
||||
@HiveField(19)
|
||||
bool experimentsEnabled;
|
||||
final bool experimentsEnabled;
|
||||
|
||||
/// encodes a Json style map into a [Preferences] obbject
|
||||
factory Preferences.fromJson(Map<String, dynamic> json) =>
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import 'package:copy_with_extension/copy_with_extension.dart';
|
||||
import 'package:flutter/foundation.dart' show immutable;
|
||||
import 'package:hive_flutter/adapters.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:sanmill/l10n/resources.dart';
|
||||
|
@ -27,6 +29,8 @@ part 'rules.g.dart';
|
|||
/// holds the data needed for the Rules Settings
|
||||
@HiveType(typeId: 3)
|
||||
@JsonSerializable()
|
||||
@CopyWith()
|
||||
@immutable
|
||||
class Rules {
|
||||
Rules({
|
||||
int? piecesCount,
|
||||
|
@ -53,37 +57,37 @@ class Rules {
|
|||
}
|
||||
|
||||
@HiveField(0)
|
||||
late int piecesCount;
|
||||
late final int piecesCount;
|
||||
@HiveField(1)
|
||||
int flyPieceCount;
|
||||
final int flyPieceCount;
|
||||
@HiveField(2)
|
||||
int piecesAtLeastCount;
|
||||
final int piecesAtLeastCount;
|
||||
@HiveField(3)
|
||||
late bool hasDiagonalLines;
|
||||
late final bool hasDiagonalLines;
|
||||
@HiveField(4)
|
||||
bool hasBannedLocations;
|
||||
final bool hasBannedLocations;
|
||||
@HiveField(5)
|
||||
bool mayMoveInPlacingPhase;
|
||||
final bool mayMoveInPlacingPhase;
|
||||
@HiveField(6)
|
||||
bool isDefenderMoveFirst;
|
||||
final bool isDefenderMoveFirst;
|
||||
@HiveField(7)
|
||||
bool mayRemoveMultiple;
|
||||
final bool mayRemoveMultiple;
|
||||
@HiveField(8)
|
||||
bool mayRemoveFromMillsAlways;
|
||||
final bool mayRemoveFromMillsAlways;
|
||||
@HiveField(9)
|
||||
bool mayOnlyRemoveUnplacedPieceInPlacingPhase;
|
||||
final bool mayOnlyRemoveUnplacedPieceInPlacingPhase;
|
||||
@HiveField(10)
|
||||
bool isWhiteLoseButNotDrawWhenBoardFull;
|
||||
final bool isWhiteLoseButNotDrawWhenBoardFull;
|
||||
@HiveField(11)
|
||||
bool isLoseButNotChangeSideWhenNoWay;
|
||||
final bool isLoseButNotChangeSideWhenNoWay;
|
||||
@HiveField(12)
|
||||
bool mayFly;
|
||||
final bool mayFly;
|
||||
@HiveField(13)
|
||||
int nMoveRule;
|
||||
final int nMoveRule;
|
||||
@HiveField(14)
|
||||
int endgameNMoveRule;
|
||||
final int endgameNMoveRule;
|
||||
@HiveField(15)
|
||||
bool threefoldRepetitionRule;
|
||||
final bool threefoldRepetitionRule;
|
||||
|
||||
/// encodes a Json style map into a [Rules] obbject
|
||||
factory Rules.fromJson(Map<String, dynamic> json) => _$RulesFromJson(json);
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/// Temporary data model
|
||||
///
|
||||
/// holds temporary runtime data that isn't yet or shouldn't be saved to the LocalDatabase
|
||||
class Temp {
|
||||
const Temp._();
|
||||
|
||||
/// represents a temporary value for Preferences.developerMode
|
||||
static bool developerMode = false;
|
||||
}
|
|
@ -22,6 +22,8 @@ import 'package:sanmill/generated/l10n.dart';
|
|||
import 'package:sanmill/shared/constants.dart';
|
||||
|
||||
class EnvironmentVariablesPage extends StatelessWidget {
|
||||
const EnvironmentVariablesPage({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FutureBuilder<String>(
|
||||
|
|
|
@ -30,7 +30,8 @@ import 'package:sanmill/mill/game.dart';
|
|||
import 'package:sanmill/mill/position.dart';
|
||||
import 'package:sanmill/mill/rule.dart';
|
||||
import 'package:sanmill/mill/types.dart';
|
||||
import 'package:sanmill/screens/game_settings_page.dart';
|
||||
import 'package:sanmill/models/preferences.dart';
|
||||
import 'package:sanmill/screens/game_settings/game_settings_page.dart';
|
||||
import 'package:sanmill/services/audios.dart';
|
||||
import 'package:sanmill/services/engine/engine.dart';
|
||||
import 'package:sanmill/services/engine/native_engine.dart';
|
||||
|
@ -1186,9 +1187,8 @@ class _GamePageState extends State<GamePage>
|
|||
}
|
||||
|
||||
Future<void> setPrivacyPolicyAccepted(bool value) async {
|
||||
setState(
|
||||
() => LocalDatabaseService.preferences.isPrivacyPolicyAccepted = value,
|
||||
);
|
||||
LocalDatabaseService.preferences = LocalDatabaseService.preferences
|
||||
.copyWith(isPrivacyPolicyAccepted: value);
|
||||
|
||||
debugPrint("[config] isPrivacyPolicyAccepted: $value");
|
||||
}
|
||||
|
@ -1341,12 +1341,13 @@ class _GamePageState extends State<GamePage>
|
|||
),
|
||||
onPressed: () async {
|
||||
if (!isTopLevel) {
|
||||
LocalDatabaseService.preferences.skillLevel++;
|
||||
final _pref = LocalDatabaseService.preferences;
|
||||
LocalDatabaseService.preferences =
|
||||
_pref.copyWith(skillLevel: _pref.skillLevel + 1);
|
||||
debugPrint(
|
||||
"[config] skillLevel: ${LocalDatabaseService.preferences.skillLevel}",
|
||||
);
|
||||
}
|
||||
await _engine.setOptions(context);
|
||||
debugPrint(
|
||||
"[config] skillLevel: ${LocalDatabaseService.preferences.skillLevel}",
|
||||
);
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
|
@ -1785,11 +1786,17 @@ class _GamePageState extends State<GamePage>
|
|||
gameInstance.init();
|
||||
_engine.startup();
|
||||
|
||||
timer = Timer.periodic(const Duration(microseconds: 100), (Timer t) {
|
||||
_setReadyState();
|
||||
});
|
||||
timer = Timer.periodic(
|
||||
const Duration(microseconds: 100),
|
||||
(_) => _setReadyState(),
|
||||
);
|
||||
|
||||
_initAnimation();
|
||||
|
||||
LocalDatabaseService.listenPreferences.addListener(() async {
|
||||
await _engine.setOptions();
|
||||
debugPrint("$tag reloaded engine options");
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1852,7 +1859,7 @@ class _GamePageState extends State<GamePage>
|
|||
Future<void> didPush() async {
|
||||
final route = ModalRoute.of(context)!.settings.name;
|
||||
debugPrint('$tag Game Page didPush route: $route');
|
||||
await _engine.setOptions(context);
|
||||
await _engine.setOptions();
|
||||
if (LocalDatabaseService.display.languageCode != Constants.defaultLocale) {
|
||||
S.load(LocalDatabaseService.display.languageCode);
|
||||
setState(() {});
|
||||
|
@ -1863,7 +1870,7 @@ class _GamePageState extends State<GamePage>
|
|||
Future<void> didPopNext() async {
|
||||
final route = ModalRoute.of(context)!.settings.name;
|
||||
debugPrint('$tag Game Page didPopNext route: $route');
|
||||
await _engine.setOptions(context);
|
||||
await _engine.setOptions();
|
||||
if (LocalDatabaseService.display.languageCode != Constants.defaultLocale) {
|
||||
S.load(LocalDatabaseService.display.languageCode);
|
||||
}
|
||||
|
@ -1873,7 +1880,7 @@ class _GamePageState extends State<GamePage>
|
|||
Future<void> didPushNext() async {
|
||||
final route = ModalRoute.of(context)!.settings.name;
|
||||
debugPrint('$tag Game Page didPushNext route: $route');
|
||||
await _engine.setOptions(context);
|
||||
await _engine.setOptions();
|
||||
if (LocalDatabaseService.display.languageCode != Constants.defaultLocale) {
|
||||
S.load(LocalDatabaseService.display.languageCode);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
part of 'package:sanmill/screens/game_settings/game_settings_page.dart';
|
||||
|
||||
class _AlgorithmModal extends StatelessWidget {
|
||||
const _AlgorithmModal({
|
||||
Key? key,
|
||||
required this.algorithm,
|
||||
required this.onChanged,
|
||||
}) : super(key: key);
|
||||
|
||||
final int algorithm;
|
||||
final Function(int?)? onChanged;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Semantics(
|
||||
label: S.of(context).algorithm,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('Alpha-Beta'),
|
||||
groupValue: algorithm,
|
||||
value: 0,
|
||||
onChanged: onChanged,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('PVS'),
|
||||
groupValue: algorithm,
|
||||
value: 1,
|
||||
onChanged: onChanged,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('MTD(f)'),
|
||||
groupValue: algorithm,
|
||||
value: 2,
|
||||
onChanged: onChanged,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,381 @@
|
|||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hive_flutter/hive_flutter.dart' show Box;
|
||||
import 'package:sanmill/generated/l10n.dart';
|
||||
import 'package:sanmill/models/display.dart';
|
||||
import 'package:sanmill/models/preferences.dart';
|
||||
import 'package:sanmill/models/temporary.dart';
|
||||
import 'package:sanmill/screens/env_page.dart';
|
||||
import 'package:sanmill/services/storage/storage.dart';
|
||||
import 'package:sanmill/shared/settings/settings_card.dart';
|
||||
import 'package:sanmill/shared/settings/settings_list_tile.dart';
|
||||
import 'package:sanmill/shared/settings/settings_switch_list_tile.dart';
|
||||
import 'package:sanmill/shared/theme/app_theme.dart';
|
||||
|
||||
part 'package:sanmill/screens/game_settings/algorithm_modal.dart';
|
||||
part 'package:sanmill/screens/game_settings/reset_settings_alert.dart';
|
||||
part 'package:sanmill/screens/game_settings/skill_level_slider.dart';
|
||||
part 'package:sanmill/screens/game_settings/move_time_slider.dart';
|
||||
|
||||
class GameSettingsPage extends StatelessWidget {
|
||||
static const List<String> _algorithmNames = ['Alpha-Beta', 'PVS', 'MTD(f)'];
|
||||
|
||||
static const String _tag = "[game_settings_page]";
|
||||
|
||||
// Restore
|
||||
void _restoreFactoryDefaultSettings(BuildContext context) => showDialog(
|
||||
context: context,
|
||||
builder: (_) => const _ResetSettingsAlert(),
|
||||
);
|
||||
|
||||
void _setSkillLevel(BuildContext context) => showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (_) => const _SkillLevelSlider(),
|
||||
);
|
||||
|
||||
void _setMoveTime(BuildContext context) => showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (_) => const _MoveTimeSlider(),
|
||||
);
|
||||
|
||||
void _setWhoMovesFirst(Preferences _preferences, bool value) {
|
||||
LocalDatabaseService.preferences =
|
||||
_preferences.copyWith(aiMovesFirst: value);
|
||||
|
||||
debugPrint("$_tag aiMovesFirst: $value");
|
||||
}
|
||||
|
||||
void _setAiIsLazy(Preferences _preferences, bool value) {
|
||||
LocalDatabaseService.preferences = _preferences.copyWith(aiIsLazy: value);
|
||||
|
||||
debugPrint("$_tag aiMovesFirst: $value");
|
||||
}
|
||||
|
||||
void _setAlgorithm(BuildContext context, Preferences _preferences) {
|
||||
void _callback(int? algorithm) {
|
||||
Navigator.pop(context);
|
||||
|
||||
LocalDatabaseService.preferences =
|
||||
_preferences.copyWith(algorithm: algorithm);
|
||||
|
||||
debugPrint("$_tag algorithm = $algorithm");
|
||||
}
|
||||
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (_) => _AlgorithmModal(
|
||||
algorithm: _preferences.algorithm,
|
||||
onChanged: _callback,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _setDrawOnHumanExperience(Preferences _preferences, bool value) {
|
||||
LocalDatabaseService.preferences =
|
||||
_preferences.copyWith(drawOnHumanExperience: value);
|
||||
|
||||
debugPrint("$_tag drawOnHumanExperience: $value");
|
||||
}
|
||||
|
||||
void _setConsiderMobility(Preferences _preferences, bool value) {
|
||||
LocalDatabaseService.preferences =
|
||||
_preferences.copyWith(considerMobility: value);
|
||||
|
||||
debugPrint("$_tag considerMobility: $value");
|
||||
}
|
||||
|
||||
void _setIsAutoRestart(Preferences _preferences, bool value) {
|
||||
LocalDatabaseService.preferences =
|
||||
_preferences.copyWith(isAutoRestart: value);
|
||||
|
||||
debugPrint("$_tag isAutoRestart: $value");
|
||||
}
|
||||
|
||||
void _setIsAutoChangeFirstMove(Preferences _preferences, bool value) {
|
||||
LocalDatabaseService.preferences =
|
||||
_preferences.copyWith(isAutoChangeFirstMove: value);
|
||||
|
||||
debugPrint("$_tag isAutoChangeFirstMove: $value");
|
||||
}
|
||||
|
||||
void _setResignIfMostLose(Preferences _preferences, bool value) {
|
||||
LocalDatabaseService.preferences =
|
||||
_preferences.copyWith(resignIfMostLose: value);
|
||||
|
||||
debugPrint("$_tag resignIfMostLose: $value");
|
||||
}
|
||||
|
||||
void _setShufflingEnabled(Preferences _preferences, bool value) {
|
||||
LocalDatabaseService.preferences =
|
||||
_preferences.copyWith(shufflingEnabled: value);
|
||||
|
||||
debugPrint("$_tag shufflingEnabled: $value");
|
||||
}
|
||||
|
||||
void _setLearnEndgame(Preferences _preferences, bool value) {
|
||||
LocalDatabaseService.preferences =
|
||||
_preferences.copyWith(learnEndgame: value);
|
||||
|
||||
debugPrint("$_tag learnEndgame: $value");
|
||||
}
|
||||
|
||||
void _setOpeningBook(Preferences _preferences, bool value) {
|
||||
LocalDatabaseService.preferences =
|
||||
_preferences.copyWith(openingBook: value);
|
||||
|
||||
debugPrint("$_tag openingBook: $value");
|
||||
}
|
||||
|
||||
void _setTone(Preferences _preferences, bool value) {
|
||||
LocalDatabaseService.preferences =
|
||||
_preferences.copyWith(toneEnabled: value);
|
||||
|
||||
debugPrint("$_tag toneEnabled: $value");
|
||||
}
|
||||
|
||||
void _setKeepMuteWhenTakingBack(Preferences _preferences, bool value) {
|
||||
LocalDatabaseService.preferences =
|
||||
_preferences.copyWith(keepMuteWhenTakingBack: value);
|
||||
|
||||
debugPrint("$_tag keepMuteWhenTakingBack: $value");
|
||||
}
|
||||
|
||||
void _setScreenReaderSupport(Preferences _preferences, bool value) {
|
||||
LocalDatabaseService.preferences =
|
||||
_preferences.copyWith(screenReaderSupport: value);
|
||||
|
||||
debugPrint("$_tag screenReaderSupport: $value");
|
||||
}
|
||||
|
||||
void _setDeveloperMode(Preferences _preferences, bool value) {
|
||||
LocalDatabaseService.preferences =
|
||||
_preferences.copyWith(developerMode: value);
|
||||
|
||||
debugPrint("$_tag developerMode: $value");
|
||||
}
|
||||
|
||||
void _setExperimentsEnabled(Preferences _preferences, bool value) {
|
||||
LocalDatabaseService.preferences =
|
||||
_preferences.copyWith(experimentsEnabled: value);
|
||||
|
||||
debugPrint("$_tag experimentsEnabled: $value");
|
||||
}
|
||||
|
||||
// Display
|
||||
void _setLanguage(Display _display, Locale value) {
|
||||
LocalDatabaseService.display = _display.copyWith(languageCode: value);
|
||||
|
||||
debugPrint("$_tag languageCode: $value");
|
||||
}
|
||||
|
||||
void _setIsPieceCountInHandShown(Display _display, bool value) {
|
||||
LocalDatabaseService.display =
|
||||
_display.copyWith(isPieceCountInHandShown: value);
|
||||
|
||||
debugPrint("$_tag isPieceCountInHandShown: $value");
|
||||
}
|
||||
|
||||
void _setIsNotationsShown(Display _display, bool value) {
|
||||
LocalDatabaseService.display = _display.copyWith(isNotationsShown: value);
|
||||
|
||||
debugPrint("$_tag isNotationsShown: $value");
|
||||
}
|
||||
|
||||
void _setIsHistoryNavigationToolbarShown(Display _display, bool value) {
|
||||
LocalDatabaseService.display =
|
||||
_display.copyWith(isHistoryNavigationToolbarShown: value);
|
||||
|
||||
debugPrint("$_tag isHistoryNavigationToolbarShown: $value");
|
||||
}
|
||||
|
||||
void _setStandardNotationEnabled(Display _display, bool value) {
|
||||
LocalDatabaseService.display =
|
||||
_display.copyWith(standardNotationEnabled: value);
|
||||
|
||||
debugPrint("$_tag standardNotationEnabled: $value");
|
||||
}
|
||||
|
||||
Column _buildPrefs(BuildContext context, Box<Preferences> prefBox, _) {
|
||||
final Preferences _preferences = prefBox.get(
|
||||
LocalDatabaseService.preferencesKey,
|
||||
defaultValue: const Preferences(),
|
||||
)!;
|
||||
|
||||
final _widowsSettings = [
|
||||
const SizedBox(height: AppTheme.sizedBoxHeight),
|
||||
Text(S.of(context).playSounds, style: AppTheme.settingsHeaderStyle),
|
||||
SettingsCard(
|
||||
children: <Widget>[
|
||||
SettingsSwitchListTile(
|
||||
value: _preferences.toneEnabled,
|
||||
onChanged: (val) => _setTone(_preferences, val),
|
||||
titleString: S.of(context).playSoundsInTheGame,
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: _preferences.keepMuteWhenTakingBack,
|
||||
onChanged: (val) => _setKeepMuteWhenTakingBack(_preferences, val),
|
||||
titleString: S.of(context).keepMuteWhenTakingBack,
|
||||
),
|
||||
],
|
||||
),
|
||||
];
|
||||
|
||||
final _developerSettings = [
|
||||
const SizedBox(height: AppTheme.sizedBoxHeight),
|
||||
Text(S.of(context).forDevelopers, style: AppTheme.settingsHeaderStyle),
|
||||
SettingsCard(
|
||||
children: <Widget>[
|
||||
SettingsSwitchListTile(
|
||||
value: _preferences.developerMode,
|
||||
onChanged: (val) => _setDeveloperMode(_preferences, val),
|
||||
titleString: S.of(context).developerMode,
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: _preferences.experimentsEnabled,
|
||||
onChanged: (val) => _setExperimentsEnabled(_preferences, val),
|
||||
titleString: S.of(context).experiments,
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: _preferences.isAutoRestart,
|
||||
onChanged: (val) => _setIsAutoRestart(_preferences, val),
|
||||
titleString: S.of(context).isAutoRestart,
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).environmentVariables,
|
||||
onTap: () => Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (_) => const EnvironmentVariablesPage(),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
];
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(S.of(context).whoMovesFirst, style: AppTheme.settingsHeaderStyle),
|
||||
SettingsCard(
|
||||
children: <Widget>[
|
||||
SettingsSwitchListTile(
|
||||
value: !_preferences.aiMovesFirst,
|
||||
onChanged: (val) => _setWhoMovesFirst(_preferences, !val),
|
||||
titleString: _preferences.aiMovesFirst
|
||||
? S.of(context).ai
|
||||
: S.of(context).human,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppTheme.sizedBoxHeight),
|
||||
Text(S.of(context).difficulty, style: AppTheme.settingsHeaderStyle),
|
||||
SettingsCard(
|
||||
children: <Widget>[
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).skillLevel,
|
||||
//trailingString: "L" + LocalDatabaseService.preferences.skillLevel.toString(),
|
||||
onTap: () => _setSkillLevel(context),
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).moveTime,
|
||||
onTap: () => _setMoveTime(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppTheme.sizedBoxHeight),
|
||||
Text(S.of(context).aisPlayStyle, style: AppTheme.settingsHeaderStyle),
|
||||
SettingsCard(
|
||||
children: <Widget>[
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).algorithm,
|
||||
trailingString: _algorithmNames[_preferences.algorithm],
|
||||
onTap: () => _setAlgorithm(context, _preferences),
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: _preferences.drawOnHumanExperience,
|
||||
onChanged: (val) => _setDrawOnHumanExperience(_preferences, val),
|
||||
titleString: S.of(context).drawOnHumanExperience,
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: _preferences.considerMobility,
|
||||
onChanged: (val) => _setConsiderMobility(_preferences, val),
|
||||
titleString: S.of(context).considerMobility,
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: _preferences.aiIsLazy,
|
||||
onChanged: (val) => _setAiIsLazy(_preferences, val),
|
||||
titleString: S.of(context).passive,
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: _preferences.shufflingEnabled,
|
||||
onChanged: (val) => _setShufflingEnabled(_preferences, val),
|
||||
titleString: S.of(context).shufflingEnabled,
|
||||
),
|
||||
],
|
||||
),
|
||||
if (!Platform.isWindows) ..._widowsSettings,
|
||||
const SizedBox(height: AppTheme.sizedBoxHeight),
|
||||
Text(S.of(context).accessibility, style: AppTheme.settingsHeaderStyle),
|
||||
SettingsCard(
|
||||
children: <Widget>[
|
||||
SettingsSwitchListTile(
|
||||
value: _preferences.screenReaderSupport,
|
||||
onChanged: (val) => _setScreenReaderSupport(_preferences, val),
|
||||
titleString: S.of(context).screenReaderSupport,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppTheme.sizedBoxHeight),
|
||||
Text(S.of(context).restore, style: AppTheme.settingsHeaderStyle),
|
||||
SettingsCard(
|
||||
children: <Widget>[
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).restoreDefaultSettings,
|
||||
onTap: () => _restoreFactoryDefaultSettings(context),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (Temp.developerMode) ..._developerSettings,
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: AppTheme.lightBackgroundColor,
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
title: Text(S.of(context).preferences),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: ValueListenableBuilder(
|
||||
valueListenable: LocalDatabaseService.listenPreferences,
|
||||
builder: _buildPrefs,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
part of 'package:sanmill/screens/game_settings/game_settings_page.dart';
|
||||
|
||||
class _MoveTimeSlider extends StatelessWidget {
|
||||
const _MoveTimeSlider({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SliderTheme(
|
||||
data: AppTheme.sliderThemeData,
|
||||
child: Semantics(
|
||||
label: S.of(context).moveTime,
|
||||
child: ValueListenableBuilder(
|
||||
valueListenable: LocalDatabaseService.listenPreferences,
|
||||
builder: (context, Box<Preferences> prefBox, _) {
|
||||
final Preferences _preferences = prefBox.get(
|
||||
LocalDatabaseService.preferencesKey,
|
||||
defaultValue: const Preferences(),
|
||||
)!;
|
||||
|
||||
return Slider(
|
||||
value: LocalDatabaseService.preferences.moveTime.toDouble(),
|
||||
max: 60,
|
||||
divisions: 60,
|
||||
label: LocalDatabaseService.preferences.moveTime.toString(),
|
||||
onChanged: (value) {
|
||||
LocalDatabaseService.preferences =
|
||||
_preferences.copyWith(moveTime: value.toInt());
|
||||
|
||||
debugPrint("Move time Slider value: $value");
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
part of 'package:sanmill/screens/game_settings/game_settings_page.dart';
|
||||
|
||||
class _ResetSettingsAlert extends StatelessWidget {
|
||||
const _ResetSettingsAlert({Key? key}) : super(key: key);
|
||||
|
||||
void cancel(BuildContext context) => Navigator.pop(context);
|
||||
|
||||
Future<void> _restore(BuildContext context) async {
|
||||
Navigator.pop(context);
|
||||
if (!LocalDatabaseService.preferences.developerMode) {
|
||||
await LocalDatabaseService.resetStorage();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// TODO: remove these strings as they aren't needed anymore
|
||||
//S.of(context).exitApp;
|
||||
//S.of(context).exitAppManually
|
||||
|
||||
return AlertDialog(
|
||||
title: Text(
|
||||
S.of(context).restore,
|
||||
style: TextStyle(
|
||||
color: AppTheme.dialogTitleColor,
|
||||
fontSize: LocalDatabaseService.display.fontSize + 4,
|
||||
),
|
||||
),
|
||||
content: SingleChildScrollView(
|
||||
child: Text(
|
||||
"${S.of(context).restoreDefaultSettings}?",
|
||||
style: TextStyle(
|
||||
fontSize: LocalDatabaseService.display.fontSize,
|
||||
),
|
||||
),
|
||||
),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
onPressed: () => _restore(context),
|
||||
child: Text(
|
||||
S.of(context).ok,
|
||||
style: TextStyle(
|
||||
fontSize: LocalDatabaseService.display.fontSize,
|
||||
),
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: () => cancel(context),
|
||||
child: Text(
|
||||
S.of(context).cancel,
|
||||
style: TextStyle(
|
||||
fontSize: LocalDatabaseService.display.fontSize,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
part of 'package:sanmill/screens/game_settings/game_settings_page.dart';
|
||||
|
||||
class _SkillLevelSlider extends StatelessWidget {
|
||||
const _SkillLevelSlider({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SliderTheme(
|
||||
data: AppTheme.sliderThemeData,
|
||||
child: Semantics(
|
||||
label: S.of(context).skillLevel,
|
||||
child: ValueListenableBuilder(
|
||||
valueListenable: LocalDatabaseService.listenPreferences,
|
||||
builder: (context, Box<Preferences> prefBox, _) {
|
||||
final Preferences _preferences = prefBox.get(
|
||||
LocalDatabaseService.preferencesKey,
|
||||
defaultValue: const Preferences(),
|
||||
)!;
|
||||
|
||||
return Slider(
|
||||
value: _preferences.skillLevel.toDouble(),
|
||||
min: 1,
|
||||
max: 30,
|
||||
divisions: 29,
|
||||
label: _preferences.skillLevel.toString(),
|
||||
onChanged: (value) {
|
||||
LocalDatabaseService.preferences =
|
||||
_preferences.copyWith(skillLevel: value.toInt());
|
||||
debugPrint("Skill level Slider value: $value");
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,535 +0,0 @@
|
|||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:sanmill/generated/l10n.dart';
|
||||
import 'package:sanmill/screens/env_page.dart';
|
||||
import 'package:sanmill/services/storage/storage.dart';
|
||||
import 'package:sanmill/services/storage/storage_v1.dart';
|
||||
import 'package:sanmill/shared/dialog.dart';
|
||||
import 'package:sanmill/shared/settings/settings_card.dart';
|
||||
import 'package:sanmill/shared/settings/settings_list_tile.dart';
|
||||
import 'package:sanmill/shared/settings/settings_switch_list_tile.dart';
|
||||
import 'package:sanmill/shared/theme/app_theme.dart';
|
||||
|
||||
class Developer {
|
||||
const Developer._();
|
||||
static bool developerModeEnabled = false;
|
||||
}
|
||||
|
||||
class GameSettingsPage extends StatefulWidget {
|
||||
@override
|
||||
_GameSettingsPageState createState() => _GameSettingsPageState();
|
||||
}
|
||||
|
||||
class _GameSettingsPageState extends State<GameSettingsPage> {
|
||||
Color pickerColor = const Color(0xFF808080);
|
||||
Color currentColor = const Color(0xFF808080);
|
||||
|
||||
late StreamController<int> _events;
|
||||
|
||||
List<String> algorithmNames = ['Alpha-Beta', 'PVS', 'MTD(f)'];
|
||||
|
||||
final String tag = "[game_settings_page]";
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_events = StreamController<int>.broadcast();
|
||||
_events.add(10);
|
||||
}
|
||||
|
||||
Future<void> _restore() async {
|
||||
final settings = await Settings.instance();
|
||||
await settings.restore();
|
||||
}
|
||||
|
||||
SliderTheme _skillLevelSliderTheme(BuildContext context, Function setState) {
|
||||
return SliderTheme(
|
||||
data: AppTheme.sliderThemeData,
|
||||
child: Semantics(
|
||||
label: S.of(context).skillLevel,
|
||||
child: Slider(
|
||||
value: LocalDatabaseService.preferences.skillLevel.toDouble(),
|
||||
min: 1,
|
||||
max: 30,
|
||||
divisions: 29,
|
||||
label: LocalDatabaseService.preferences.skillLevel.toString(),
|
||||
onChanged: (value) => setState(() {
|
||||
debugPrint("[config] Slider value: $value");
|
||||
LocalDatabaseService.preferences.skillLevel = value.toInt();
|
||||
}),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
SliderTheme _moveTimeSliderTheme(BuildContext context, Function setState) {
|
||||
return SliderTheme(
|
||||
data: AppTheme.sliderThemeData,
|
||||
child: Semantics(
|
||||
label: S.of(context).moveTime,
|
||||
child: Slider(
|
||||
value: LocalDatabaseService.preferences.moveTime.toDouble(),
|
||||
max: 60,
|
||||
divisions: 60,
|
||||
label: LocalDatabaseService.preferences.moveTime.toString(),
|
||||
onChanged: (value) => setState(() {
|
||||
debugPrint("[config] Slider value: $value");
|
||||
LocalDatabaseService.preferences.moveTime = value.toInt();
|
||||
}),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Restore
|
||||
|
||||
Future<void> restoreFactoryDefaultSettings() async {
|
||||
Future<void> confirm() async {
|
||||
Navigator.pop(context);
|
||||
if (Platform.isAndroid) {
|
||||
showCountdownDialog(context, 10, _events, _restore);
|
||||
} else {
|
||||
_restore();
|
||||
ScaffoldMessenger.of(context).clearSnackBars();
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(S.of(context).exitAppManually)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void cancel() => Navigator.pop(context);
|
||||
|
||||
var prompt = "";
|
||||
|
||||
if (Platform.isAndroid) {
|
||||
prompt = S.of(context).exitApp;
|
||||
}
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: Text(
|
||||
S.of(context).restore,
|
||||
style: TextStyle(
|
||||
color: AppTheme.dialogTitleColor,
|
||||
fontSize: LocalDatabaseService.display.fontSize + 4,
|
||||
),
|
||||
),
|
||||
content: SingleChildScrollView(
|
||||
child: Text(
|
||||
"${S.of(context).restoreDefaultSettings}?\n$prompt",
|
||||
style: TextStyle(
|
||||
fontSize: LocalDatabaseService.display.fontSize,
|
||||
),
|
||||
),
|
||||
),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
onPressed: confirm,
|
||||
child: Text(
|
||||
S.of(context).ok,
|
||||
style: TextStyle(
|
||||
fontSize: LocalDatabaseService.display.fontSize,
|
||||
),
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: cancel,
|
||||
child: Text(
|
||||
S.of(context).cancel,
|
||||
style: TextStyle(
|
||||
fontSize: LocalDatabaseService.display.fontSize,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: AppTheme.lightBackgroundColor,
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
title: Text(S.of(context).preferences),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: children(context),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> children(BuildContext context) {
|
||||
return <Widget>[
|
||||
Text(S.of(context).whoMovesFirst, style: AppTheme.settingsHeaderStyle),
|
||||
SettingsCard(
|
||||
children: <Widget>[
|
||||
SettingsSwitchListTile(
|
||||
value: !LocalDatabaseService.preferences.aiMovesFirst,
|
||||
onChanged: setWhoMovesFirst,
|
||||
titleString: LocalDatabaseService.preferences.aiMovesFirst
|
||||
? S.of(context).ai
|
||||
: S.of(context).human,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppTheme.sizedBoxHeight),
|
||||
Text(S.of(context).difficulty, style: AppTheme.settingsHeaderStyle),
|
||||
SettingsCard(
|
||||
children: <Widget>[
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).skillLevel,
|
||||
//trailingString: "L" + LocalDatabaseService.preferences.skillLevel.toString(),
|
||||
onTap: setSkillLevel,
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).moveTime,
|
||||
onTap: setMoveTime,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppTheme.sizedBoxHeight),
|
||||
Text(S.of(context).aisPlayStyle, style: AppTheme.settingsHeaderStyle),
|
||||
SettingsCard(
|
||||
children: <Widget>[
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).algorithm,
|
||||
trailingString:
|
||||
algorithmNames[LocalDatabaseService.preferences.algorithm],
|
||||
onTap: setAlgorithm,
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: LocalDatabaseService.preferences.drawOnHumanExperience,
|
||||
onChanged: setDrawOnHumanExperience,
|
||||
titleString: S.of(context).drawOnHumanExperience,
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: LocalDatabaseService.preferences.considerMobility,
|
||||
onChanged: setConsiderMobility,
|
||||
titleString: S.of(context).considerMobility,
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: LocalDatabaseService.preferences.aiIsLazy,
|
||||
onChanged: setAiIsLazy,
|
||||
titleString: S.of(context).passive,
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: LocalDatabaseService.preferences.shufflingEnabled,
|
||||
onChanged: setShufflingEnabled,
|
||||
titleString: S.of(context).shufflingEnabled,
|
||||
),
|
||||
],
|
||||
),
|
||||
if (!Platform.isWindows) const SizedBox(height: AppTheme.sizedBoxHeight),
|
||||
if (!Platform.isWindows)
|
||||
Text(S.of(context).playSounds, style: AppTheme.settingsHeaderStyle),
|
||||
if (!Platform.isWindows)
|
||||
SettingsCard(
|
||||
children: <Widget>[
|
||||
SettingsSwitchListTile(
|
||||
value: LocalDatabaseService.preferences.toneEnabled,
|
||||
onChanged: setTone,
|
||||
titleString: S.of(context).playSoundsInTheGame,
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: LocalDatabaseService.preferences.keepMuteWhenTakingBack,
|
||||
onChanged: setKeepMuteWhenTakingBack,
|
||||
titleString: S.of(context).keepMuteWhenTakingBack,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppTheme.sizedBoxHeight),
|
||||
Text(S.of(context).accessibility, style: AppTheme.settingsHeaderStyle),
|
||||
SettingsCard(
|
||||
children: <Widget>[
|
||||
SettingsSwitchListTile(
|
||||
value: LocalDatabaseService.preferences.screenReaderSupport,
|
||||
onChanged: setScreenReaderSupport,
|
||||
titleString: S.of(context).screenReaderSupport,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppTheme.sizedBoxHeight),
|
||||
Text(S.of(context).restore, style: AppTheme.settingsHeaderStyle),
|
||||
SettingsCard(
|
||||
children: <Widget>[
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).restoreDefaultSettings,
|
||||
onTap: restoreFactoryDefaultSettings,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppTheme.sizedBoxHeight),
|
||||
if (Developer.developerModeEnabled)
|
||||
Text(
|
||||
S.of(context).forDevelopers,
|
||||
style: AppTheme.settingsHeaderStyle,
|
||||
),
|
||||
if (Developer.developerModeEnabled)
|
||||
SettingsCard(
|
||||
children: <Widget>[
|
||||
SettingsSwitchListTile(
|
||||
value: LocalDatabaseService.preferences.developerMode,
|
||||
onChanged: setDeveloperMode,
|
||||
titleString: S.of(context).developerMode,
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: LocalDatabaseService.preferences.experimentsEnabled,
|
||||
onChanged: setExperimentsEnabled,
|
||||
titleString: S.of(context).experiments,
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: LocalDatabaseService.preferences.isAutoRestart,
|
||||
onChanged: setIsAutoRestart,
|
||||
titleString: S.of(context).isAutoRestart,
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).environmentVariables,
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => EnvironmentVariablesPage(),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
Future<void> setSkillLevel() async {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (_) => StatefulBuilder(
|
||||
builder: _skillLevelSliderTheme,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> setMoveTime() async {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (_) => StatefulBuilder(
|
||||
builder: _moveTimeSliderTheme,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> setWhoMovesFirst(bool value) async {
|
||||
setState(() => LocalDatabaseService.preferences.aiMovesFirst = !value);
|
||||
|
||||
debugPrint(
|
||||
"[config] aiMovesFirst: ${LocalDatabaseService.preferences.aiMovesFirst}",
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> setAiIsLazy(bool value) async {
|
||||
setState(() => LocalDatabaseService.preferences.aiIsLazy = value);
|
||||
|
||||
debugPrint("[config] aiMovesFirst: $value");
|
||||
}
|
||||
|
||||
void setAlgorithm() {
|
||||
Future<void> callback(int? algorithm) async {
|
||||
debugPrint("[config] algorithm = $algorithm");
|
||||
|
||||
Navigator.pop(context);
|
||||
|
||||
setState(
|
||||
() => LocalDatabaseService.preferences.algorithm = algorithm ?? 2,
|
||||
);
|
||||
|
||||
debugPrint(
|
||||
"[config] LocalDatabaseService.preferences.algorithm: ${LocalDatabaseService.preferences.algorithm}",
|
||||
);
|
||||
}
|
||||
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (BuildContext context) => Semantics(
|
||||
label: S.of(context).algorithm,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('Alpha-Beta'),
|
||||
groupValue: LocalDatabaseService.preferences.algorithm,
|
||||
value: 0,
|
||||
onChanged: callback,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('PVS'),
|
||||
groupValue: LocalDatabaseService.preferences.algorithm,
|
||||
value: 1,
|
||||
onChanged: callback,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('MTD(f)'),
|
||||
groupValue: LocalDatabaseService.preferences.algorithm,
|
||||
value: 2,
|
||||
onChanged: callback,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> setDrawOnHumanExperience(bool value) async {
|
||||
setState(
|
||||
() => LocalDatabaseService.preferences.drawOnHumanExperience = value,
|
||||
);
|
||||
|
||||
debugPrint("[config] drawOnHumanExperience: $value");
|
||||
}
|
||||
|
||||
Future<void> setConsiderMobility(bool value) async {
|
||||
setState(() => LocalDatabaseService.preferences.considerMobility = value);
|
||||
|
||||
debugPrint("[config] considerMobility: $value");
|
||||
}
|
||||
|
||||
Future<void> setIsAutoRestart(bool value) async {
|
||||
setState(() => LocalDatabaseService.preferences.isAutoRestart = value);
|
||||
|
||||
debugPrint("[config] isAutoRestart: $value");
|
||||
}
|
||||
|
||||
Future<void> setIsAutoChangeFirstMove(bool value) async {
|
||||
setState(
|
||||
() => LocalDatabaseService.preferences.isAutoChangeFirstMove = value,
|
||||
);
|
||||
|
||||
debugPrint("[config] isAutoChangeFirstMove: $value");
|
||||
}
|
||||
|
||||
Future<void> setResignIfMostLose(bool value) async {
|
||||
setState(() => LocalDatabaseService.preferences.resignIfMostLose = value);
|
||||
|
||||
debugPrint("[config] resignIfMostLose: $value");
|
||||
}
|
||||
|
||||
Future<void> setShufflingEnabled(bool value) async {
|
||||
setState(() => LocalDatabaseService.preferences.shufflingEnabled = value);
|
||||
|
||||
debugPrint("[config] shufflingEnabled: $value");
|
||||
}
|
||||
|
||||
Future<void> setLearnEndgame(bool value) async {
|
||||
setState(() => LocalDatabaseService.preferences.learnEndgame = value);
|
||||
|
||||
debugPrint("[config] learnEndgame: $value");
|
||||
}
|
||||
|
||||
Future<void> setOpeningBook(bool value) async {
|
||||
setState(() => LocalDatabaseService.preferences.openingBook = value);
|
||||
|
||||
debugPrint("[config] openingBook: $value");
|
||||
}
|
||||
|
||||
Future<void> setTone(bool value) async {
|
||||
setState(() => LocalDatabaseService.preferences.toneEnabled = value);
|
||||
|
||||
debugPrint("[config] toneEnabled: $value");
|
||||
}
|
||||
|
||||
Future<void> setKeepMuteWhenTakingBack(bool value) async {
|
||||
setState(
|
||||
() => LocalDatabaseService.preferences.keepMuteWhenTakingBack = value,
|
||||
);
|
||||
|
||||
debugPrint("[config] keepMuteWhenTakingBack: $value");
|
||||
}
|
||||
|
||||
Future<void> setScreenReaderSupport(bool value) async {
|
||||
setState(
|
||||
() => LocalDatabaseService.preferences.screenReaderSupport = value,
|
||||
);
|
||||
|
||||
debugPrint("[config] screenReaderSupport: $value");
|
||||
}
|
||||
|
||||
Future<void> setDeveloperMode(bool value) async {
|
||||
setState(() => LocalDatabaseService.preferences.developerMode = value);
|
||||
|
||||
debugPrint("[config] developerMode: $value");
|
||||
}
|
||||
|
||||
Future<void> setExperimentsEnabled(bool value) async {
|
||||
setState(() => LocalDatabaseService.preferences.experimentsEnabled = value);
|
||||
|
||||
debugPrint("[config] experimentsEnabled: $value");
|
||||
}
|
||||
|
||||
// Display
|
||||
|
||||
Future<void> setLanguage(Locale value) async {
|
||||
setState(() => LocalDatabaseService.display.languageCode = value);
|
||||
|
||||
debugPrint("[config] languageCode: $value");
|
||||
}
|
||||
|
||||
Future<void> setIsPieceCountInHandShown(bool value) async {
|
||||
setState(
|
||||
() => LocalDatabaseService.display.isPieceCountInHandShown = value,
|
||||
);
|
||||
|
||||
debugPrint("[config] isPieceCountInHandShown: $value");
|
||||
}
|
||||
|
||||
Future<void> setIsNotationsShown(bool value) async {
|
||||
setState(() => LocalDatabaseService.display.isNotationsShown = value);
|
||||
|
||||
debugPrint("[config] isNotationsShown: $value");
|
||||
}
|
||||
|
||||
Future<void> setIsHistoryNavigationToolbarShown(bool value) async {
|
||||
setState(
|
||||
() =>
|
||||
LocalDatabaseService.display.isHistoryNavigationToolbarShown = value,
|
||||
);
|
||||
|
||||
debugPrint("[config] isHistoryNavigationToolbarShown: $value");
|
||||
}
|
||||
|
||||
Future<void> setStandardNotationEnabled(bool value) async {
|
||||
setState(
|
||||
() => LocalDatabaseService.display.standardNotationEnabled = value,
|
||||
);
|
||||
|
||||
debugPrint("[config] standardNotationEnabled: $value");
|
||||
}
|
||||
}
|
|
@ -178,10 +178,16 @@ class _DrawerHeader extends StatelessWidget {
|
|||
|
||||
final AnimationController iconAnimationController;
|
||||
|
||||
static const String _tag = "[home_drawer]";
|
||||
|
||||
void _enableDeveloperMode() {
|
||||
Temp.developerMode = true;
|
||||
|
||||
debugPrint("$_tag Developer mode enabled.");
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
const String tag = "[home_drawer]";
|
||||
|
||||
final List<Color> animatedTextsColors = [
|
||||
LocalDatabaseService.colorSettings.drawerTextColor,
|
||||
Colors.black,
|
||||
|
@ -220,6 +226,7 @@ class _DrawerHeader extends StatelessWidget {
|
|||
);
|
||||
|
||||
final animation = GestureDetector(
|
||||
onDoubleTap: _enableDeveloperMode,
|
||||
child: AnimatedTextKit(
|
||||
animatedTexts: [
|
||||
ColorizeAnimatedText(
|
||||
|
@ -235,12 +242,8 @@ class _DrawerHeader extends StatelessWidget {
|
|||
pause: const Duration(seconds: 3),
|
||||
repeatForever: true,
|
||||
stopPauseOnTap: true,
|
||||
onTap: () => debugPrint("$tag DoubleTap to enable developer mode."),
|
||||
onTap: () => debugPrint("$_tag DoubleTap to enable developer mode."),
|
||||
),
|
||||
onDoubleTap: () {
|
||||
Developer.developerModeEnabled = true;
|
||||
debugPrint("$tag Developer mode enabled.");
|
||||
},
|
||||
);
|
||||
|
||||
return Padding(
|
||||
|
|
|
@ -29,12 +29,13 @@ import 'package:path_provider/path_provider.dart';
|
|||
import 'package:sanmill/generated/l10n.dart';
|
||||
import 'package:sanmill/l10n/resources.dart';
|
||||
import 'package:sanmill/mill/game.dart';
|
||||
import 'package:sanmill/models/temporary.dart';
|
||||
import 'package:sanmill/screens/about_page.dart';
|
||||
import 'package:sanmill/screens/game_page/game_page.dart';
|
||||
import 'package:sanmill/screens/game_settings_page.dart';
|
||||
import 'package:sanmill/screens/game_settings/game_settings_page.dart';
|
||||
import 'package:sanmill/screens/help_screen.dart';
|
||||
import 'package:sanmill/screens/personalization_settings_page.dart';
|
||||
import 'package:sanmill/screens/rule_settings_page.dart';
|
||||
import 'package:sanmill/screens/personalization_settings/personalization_settings_page.dart';
|
||||
import 'package:sanmill/screens/rule_settings/rule_settings_page.dart';
|
||||
import 'package:sanmill/services/engine/engine.dart';
|
||||
import 'package:sanmill/services/storage/storage.dart';
|
||||
import 'package:sanmill/shared/constants.dart';
|
||||
|
@ -98,7 +99,7 @@ class _NavigationHomeScreenState extends State<NavigationHomeScreen> {
|
|||
} else if (drawerIndex == DrawerIndex.preferences) {
|
||||
screenView = GameSettingsPage();
|
||||
} else if (drawerIndex == DrawerIndex.ruleSettings) {
|
||||
screenView = RuleSettingsPage();
|
||||
screenView = const RuleSettingsPage();
|
||||
} else if (drawerIndex == DrawerIndex.personalization) {
|
||||
screenView = PersonalizationSettingsPage();
|
||||
} else if (drawerIndex == DrawerIndex.feedback &&
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
part of 'package:sanmill/screens/personalization_settings/personalization_settings_page.dart';
|
||||
|
||||
class _AnimationDurationSlider extends StatelessWidget {
|
||||
const _AnimationDurationSlider({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SliderTheme(
|
||||
data: AppTheme.sliderThemeData,
|
||||
child: Semantics(
|
||||
label: S.of(context).animationDuration,
|
||||
child: ValueListenableBuilder(
|
||||
valueListenable: LocalDatabaseService.listenDisplay,
|
||||
builder: (context, Box<Display> displayaBox, _) {
|
||||
final Display _display = displayaBox.get(
|
||||
LocalDatabaseService.colorSettingsKey,
|
||||
defaultValue: Display(),
|
||||
)!;
|
||||
|
||||
return Slider(
|
||||
value: _display.animationDuration,
|
||||
max: 5.0,
|
||||
divisions: 50,
|
||||
label: _display.animationDuration.toStringAsFixed(1),
|
||||
onChanged: (value) {
|
||||
debugPrint("[config] AnimationDuration value: $value");
|
||||
LocalDatabaseService.display =
|
||||
_display.copyWith(animationDuration: value);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
part of 'package:sanmill/screens/personalization_settings/personalization_settings_page.dart';
|
||||
|
||||
class _BoardBorderWidthSlider extends StatelessWidget {
|
||||
const _BoardBorderWidthSlider({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SliderTheme(
|
||||
data: AppTheme.sliderThemeData,
|
||||
child: Semantics(
|
||||
label: S.of(context).boardBorderLineWidth,
|
||||
child: ValueListenableBuilder(
|
||||
valueListenable: LocalDatabaseService.listenDisplay,
|
||||
builder: (context, Box<Display> displayaBox, _) {
|
||||
final Display _display = displayaBox.get(
|
||||
LocalDatabaseService.colorSettingsKey,
|
||||
defaultValue: Display(),
|
||||
)!;
|
||||
|
||||
return Slider(
|
||||
value: _display.boardBorderLineWidth,
|
||||
max: 20.0,
|
||||
divisions: 200,
|
||||
label: _display.boardBorderLineWidth.toStringAsFixed(1),
|
||||
onChanged: (value) {
|
||||
debugPrint("[config] BoardBorderLineWidth value: $value");
|
||||
LocalDatabaseService.display =
|
||||
_display.copyWith(boardBorderLineWidth: value);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
part of 'package:sanmill/screens/personalization_settings/personalization_settings_page.dart';
|
||||
|
||||
class _BoardInnerWidthSlider extends StatelessWidget {
|
||||
const _BoardInnerWidthSlider({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SliderTheme(
|
||||
data: AppTheme.sliderThemeData,
|
||||
child: Semantics(
|
||||
label: S.of(context).boardInnerLineWidth,
|
||||
child: ValueListenableBuilder(
|
||||
valueListenable: LocalDatabaseService.listenDisplay,
|
||||
builder: (context, Box<Display> displayaBox, _) {
|
||||
final Display _display = displayaBox.get(
|
||||
LocalDatabaseService.colorSettingsKey,
|
||||
defaultValue: Display(),
|
||||
)!;
|
||||
|
||||
return Slider(
|
||||
value: _display.boardInnerLineWidth,
|
||||
max: 20,
|
||||
divisions: 200,
|
||||
label: _display.boardInnerLineWidth.toStringAsFixed(1),
|
||||
onChanged: (value) {
|
||||
debugPrint("[config] BoardInnerLineWidth value: $value");
|
||||
LocalDatabaseService.display =
|
||||
_display.copyWith(boardInnerLineWidth: value);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
part of 'package:sanmill/screens/personalization_settings/personalization_settings_page.dart';
|
||||
|
||||
class _BoardTopSlider extends StatelessWidget {
|
||||
const _BoardTopSlider({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SliderTheme(
|
||||
data: AppTheme.sliderThemeData,
|
||||
child: Semantics(
|
||||
label: S.of(context).boardTop,
|
||||
child: ValueListenableBuilder(
|
||||
valueListenable: LocalDatabaseService.listenDisplay,
|
||||
builder: (context, Box<Display> displayaBox, _) {
|
||||
final Display _display = displayaBox.get(
|
||||
LocalDatabaseService.colorSettingsKey,
|
||||
defaultValue: Display(),
|
||||
)!;
|
||||
|
||||
return Slider(
|
||||
value: _display.boardTop,
|
||||
max: 288.0,
|
||||
divisions: 288,
|
||||
label: _display.boardTop.toStringAsFixed(1),
|
||||
onChanged: (value) {
|
||||
debugPrint("[config] AnimationDuration value: $value");
|
||||
LocalDatabaseService.display =
|
||||
_display.copyWith(boardTop: value);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
part of 'package:sanmill/screens/personalization_settings/personalization_settings_page.dart';
|
||||
|
||||
class _ColorSelectorListTile extends StatelessWidget {
|
||||
const _ColorSelectorListTile({
|
||||
Key? key,
|
||||
required this.value,
|
||||
required this.title,
|
||||
required this.onChanged,
|
||||
}) : super(key: key);
|
||||
|
||||
final Color value;
|
||||
final String title;
|
||||
final Function(Color) onChanged;
|
||||
|
||||
Future<void> showColorDialog(BuildContext context) async {
|
||||
// show the dialog
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (_) => _ColorPickerAlert(
|
||||
title: title,
|
||||
value: value,
|
||||
onChanged: onChanged,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SettingsListTile(
|
||||
titleString: title,
|
||||
trailingColor: value,
|
||||
onTap: () => showColorDialog(context),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ColorPickerAlert extends StatefulWidget {
|
||||
const _ColorPickerAlert({
|
||||
Key? key,
|
||||
required this.value,
|
||||
required this.title,
|
||||
required this.onChanged,
|
||||
}) : super(key: key);
|
||||
|
||||
final Color value;
|
||||
final String title;
|
||||
final Function(Color) onChanged;
|
||||
|
||||
@override
|
||||
_ColorPickerAlertState createState() => _ColorPickerAlertState();
|
||||
}
|
||||
|
||||
class _ColorPickerAlertState extends State<_ColorPickerAlert> {
|
||||
late Color pickedColor;
|
||||
|
||||
void changeColor(Color color) => setState(() => pickedColor = color);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
pickedColor = widget.value;
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return AlertDialog(
|
||||
title: Text(
|
||||
"${S.of(context).pick} ${widget.title}",
|
||||
style: TextStyle(
|
||||
fontSize: LocalDatabaseService.display.fontSize + 4,
|
||||
),
|
||||
),
|
||||
content: SingleChildScrollView(
|
||||
child: ColorPicker(
|
||||
pickerColor: pickedColor,
|
||||
onColorChanged: changeColor,
|
||||
),
|
||||
),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: Text(
|
||||
S.of(context).confirm,
|
||||
style: TextStyle(
|
||||
fontSize: LocalDatabaseService.display.fontSize,
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
debugPrint("[config] pickerColor.value: ${pickedColor.value}");
|
||||
widget.onChanged(pickedColor);
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: Text(
|
||||
S.of(context).cancel,
|
||||
style: TextStyle(
|
||||
fontSize: LocalDatabaseService.display.fontSize,
|
||||
),
|
||||
),
|
||||
onPressed: () => Navigator.pop(context),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
part of 'package:sanmill/screens/personalization_settings/personalization_settings_page.dart';
|
||||
|
||||
class _FontSizeSlider extends StatelessWidget {
|
||||
const _FontSizeSlider({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SliderTheme(
|
||||
data: AppTheme.sliderThemeData,
|
||||
child: Semantics(
|
||||
label: S.of(context).fontSize,
|
||||
child: ValueListenableBuilder(
|
||||
valueListenable: LocalDatabaseService.listenDisplay,
|
||||
builder: (context, Box<Display> displayaBox, _) {
|
||||
final Display _display = displayaBox.get(
|
||||
LocalDatabaseService.colorSettingsKey,
|
||||
defaultValue: Display(),
|
||||
)!;
|
||||
|
||||
return Slider(
|
||||
value: _display.fontSize,
|
||||
min: 16,
|
||||
max: 32,
|
||||
divisions: 16,
|
||||
label: _display.fontSize.toStringAsFixed(1),
|
||||
onChanged: (value) {
|
||||
debugPrint("[config] fontSize value: $value");
|
||||
LocalDatabaseService.display =
|
||||
_display.copyWith(fontSize: value);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,322 @@
|
|||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
|
||||
import 'package:hive_flutter/hive_flutter.dart' show Box;
|
||||
import 'package:sanmill/generated/l10n.dart';
|
||||
import 'package:sanmill/l10n/resources.dart';
|
||||
import 'package:sanmill/models/color.dart';
|
||||
import 'package:sanmill/models/display.dart';
|
||||
import 'package:sanmill/services/storage/storage.dart';
|
||||
import 'package:sanmill/shared/constants.dart';
|
||||
import 'package:sanmill/shared/settings/settings_card.dart';
|
||||
import 'package:sanmill/shared/settings/settings_list_tile.dart';
|
||||
import 'package:sanmill/shared/settings/settings_switch_list_tile.dart';
|
||||
import 'package:sanmill/shared/theme/app_theme.dart';
|
||||
|
||||
part 'package:sanmill/screens/personalization_settings/color_selector_list_tile.dart';
|
||||
part 'package:sanmill/screens/personalization_settings/animation_duration_slider.dart';
|
||||
part 'package:sanmill/screens/personalization_settings/board_top_slider.dart';
|
||||
part 'package:sanmill/screens/personalization_settings/board_boarder_line_width_slider.dart';
|
||||
part 'package:sanmill/screens/personalization_settings/board_inner_line_width_slider.dart';
|
||||
part 'package:sanmill/screens/personalization_settings/font_size_slider.dart';
|
||||
part 'package:sanmill/screens/personalization_settings/point_width_slider.dart';
|
||||
part 'package:sanmill/screens/personalization_settings/piece_width_slider.dart';
|
||||
part 'package:sanmill/screens/personalization_settings/point_style_modal.dart';
|
||||
|
||||
class PersonalizationSettingsPage extends StatelessWidget {
|
||||
void setBoardBorderLineWidth(BuildContext context) => showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (_) => const _BoardBorderWidthSlider(),
|
||||
);
|
||||
|
||||
void setBoardInnerLineWidth(BuildContext context) => showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (_) => const _BoardInnerWidthSlider(),
|
||||
);
|
||||
|
||||
void setPointStyle(BuildContext context, Display _display) {
|
||||
void _callback(int? pointStyle) {
|
||||
Navigator.pop(context);
|
||||
|
||||
LocalDatabaseService.display = _display.copyWith(pointStyle: pointStyle);
|
||||
|
||||
debugPrint("[config] pointStyle: $pointStyle");
|
||||
}
|
||||
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (_) => _PointStyleModal(
|
||||
pointStyle: _display.pointStyle,
|
||||
onChanged: _callback,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void setPointWidth(BuildContext context) => showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (_) => const _PointWidthSlider(),
|
||||
);
|
||||
|
||||
void setPieceWidth(BuildContext context) => showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (_) => const _PieceWidthSlider(),
|
||||
);
|
||||
|
||||
void setFontSize(BuildContext context) => showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (_) => const _FontSizeSlider(),
|
||||
);
|
||||
|
||||
void setBoardTop(BuildContext context) => showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (_) => const _BoardTopSlider(),
|
||||
);
|
||||
|
||||
void setAnimationDuration(BuildContext context) => showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (_) => const _AnimationDurationSlider(),
|
||||
);
|
||||
|
||||
void langCallback(BuildContext context, Display _display, [Locale? locale]) {
|
||||
Navigator.pop(context);
|
||||
|
||||
LocalDatabaseService.display = _display.copyWith(languageCode: locale);
|
||||
|
||||
debugPrint("[config] languageCode = $locale");
|
||||
}
|
||||
|
||||
Widget _buildColor(BuildContext context, Box<ColorSettings> colorBox, _) {
|
||||
final ColorSettings _colorSettings = colorBox.get(
|
||||
LocalDatabaseService.colorSettingsKey,
|
||||
defaultValue: ColorSettings(),
|
||||
)!;
|
||||
|
||||
return SettingsCard(
|
||||
children: <Widget>[
|
||||
_ColorSelectorListTile(
|
||||
title: S.of(context).boardColor,
|
||||
value: _colorSettings.boardBackgroundColor,
|
||||
onChanged: (val) => LocalDatabaseService.colorSettings =
|
||||
_colorSettings.copyWith(boardBackgroundColor: val),
|
||||
),
|
||||
_ColorSelectorListTile(
|
||||
title: S.of(context).backgroundColor,
|
||||
value: _colorSettings.darkBackgroundColor,
|
||||
onChanged: (val) => LocalDatabaseService.colorSettings =
|
||||
_colorSettings.copyWith(darkBackgroundColor: val),
|
||||
),
|
||||
_ColorSelectorListTile(
|
||||
title: S.of(context).lineColor,
|
||||
value: _colorSettings.boardLineColor,
|
||||
onChanged: (val) => LocalDatabaseService.colorSettings =
|
||||
_colorSettings.copyWith(boardLineColor: val),
|
||||
),
|
||||
_ColorSelectorListTile(
|
||||
title: S.of(context).whitePieceColor,
|
||||
value: _colorSettings.whitePieceColor,
|
||||
onChanged: (val) => LocalDatabaseService.colorSettings =
|
||||
_colorSettings.copyWith(whitePieceColor: val),
|
||||
),
|
||||
_ColorSelectorListTile(
|
||||
title: S.of(context).blackPieceColor,
|
||||
value: _colorSettings.blackPieceColor,
|
||||
onChanged: (val) => LocalDatabaseService.colorSettings =
|
||||
_colorSettings.copyWith(blackPieceColor: val),
|
||||
),
|
||||
_ColorSelectorListTile(
|
||||
title: S.of(context).pieceHighlightColor,
|
||||
value: _colorSettings.pieceHighlightColor,
|
||||
onChanged: (val) => LocalDatabaseService.colorSettings =
|
||||
_colorSettings.copyWith(pieceHighlightColor: val),
|
||||
),
|
||||
_ColorSelectorListTile(
|
||||
title: S.of(context).messageColor,
|
||||
value: _colorSettings.messageColor,
|
||||
onChanged: (val) => LocalDatabaseService.colorSettings =
|
||||
_colorSettings.copyWith(messageColor: val),
|
||||
),
|
||||
_ColorSelectorListTile(
|
||||
title: S.of(context).drawerColor,
|
||||
value: _colorSettings.drawerColor,
|
||||
onChanged: (val) => LocalDatabaseService.colorSettings =
|
||||
_colorSettings.copyWith(drawerColor: val),
|
||||
),
|
||||
_ColorSelectorListTile(
|
||||
title: S.of(context).drawerBackgroundColor,
|
||||
value: _colorSettings.drawerBackgroundColor,
|
||||
onChanged: (val) => LocalDatabaseService.colorSettings =
|
||||
_colorSettings.copyWith(drawerBackgroundColor: val),
|
||||
),
|
||||
_ColorSelectorListTile(
|
||||
title: S.of(context).drawerTextColor,
|
||||
value: _colorSettings.drawerTextColor,
|
||||
onChanged: (val) => LocalDatabaseService.colorSettings =
|
||||
_colorSettings.copyWith(drawerTextColor: val),
|
||||
),
|
||||
_ColorSelectorListTile(
|
||||
title: S.of(context).drawerHighlightItemColor,
|
||||
value: _colorSettings.drawerHighlightItemColor,
|
||||
onChanged: (val) =>
|
||||
LocalDatabaseService.colorSettings = _colorSettings.copyWith(
|
||||
drawerHighlightItemColor: val,
|
||||
),
|
||||
),
|
||||
_ColorSelectorListTile(
|
||||
title: S.of(context).mainToolbarBackgroundColor,
|
||||
value: _colorSettings.mainToolbarBackgroundColor,
|
||||
onChanged: (val) =>
|
||||
LocalDatabaseService.colorSettings = _colorSettings.copyWith(
|
||||
mainToolbarBackgroundColor: val,
|
||||
),
|
||||
),
|
||||
_ColorSelectorListTile(
|
||||
title: S.of(context).mainToolbarIconColor,
|
||||
value: _colorSettings.mainToolbarIconColor,
|
||||
onChanged: (val) => LocalDatabaseService.colorSettings =
|
||||
_colorSettings.copyWith(mainToolbarIconColor: val),
|
||||
),
|
||||
_ColorSelectorListTile(
|
||||
title: S.of(context).navigationToolbarBackgroundColor,
|
||||
value: _colorSettings.navigationToolbarBackgroundColor,
|
||||
onChanged: (val) =>
|
||||
LocalDatabaseService.colorSettings = _colorSettings.copyWith(
|
||||
navigationToolbarBackgroundColor: val,
|
||||
),
|
||||
),
|
||||
_ColorSelectorListTile(
|
||||
title: S.of(context).navigationToolbarIconColor,
|
||||
value: _colorSettings.navigationToolbarIconColor,
|
||||
onChanged: (val) =>
|
||||
LocalDatabaseService.colorSettings = _colorSettings.copyWith(
|
||||
navigationToolbarIconColor: val,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDisplay(BuildContext context, Box<Display> displayaBox, _) {
|
||||
final Display _display = displayaBox.get(
|
||||
LocalDatabaseService.colorSettingsKey,
|
||||
defaultValue: Display(),
|
||||
)!;
|
||||
return SettingsCard(
|
||||
children: <Widget>[
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).language,
|
||||
trailingString: LocalDatabaseService.display.languageCode !=
|
||||
Constants.defaultLocale
|
||||
? languageCodeToStrings[_display.languageCode]!.languageName
|
||||
: '',
|
||||
onTap: () => setLanguage(
|
||||
context,
|
||||
(locale) => langCallback(context, _display, locale),
|
||||
),
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: _display.isPieceCountInHandShown,
|
||||
onChanged: (val) => LocalDatabaseService.display =
|
||||
_display.copyWith(isPieceCountInHandShown: val),
|
||||
titleString: S.of(context).isPieceCountInHandShown,
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: _display.isNotationsShown,
|
||||
onChanged: (val) => LocalDatabaseService.display =
|
||||
_display.copyWith(isNotationsShown: val),
|
||||
titleString: S.of(context).isNotationsShown,
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: _display.isHistoryNavigationToolbarShown,
|
||||
onChanged: (val) => LocalDatabaseService.display =
|
||||
_display.copyWith(isHistoryNavigationToolbarShown: val),
|
||||
titleString: S.of(context).isHistoryNavigationToolbarShown,
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).boardBorderLineWidth,
|
||||
onTap: () => setBoardBorderLineWidth(context),
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).boardInnerLineWidth,
|
||||
onTap: () => setBoardInnerLineWidth(context),
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).pointStyle,
|
||||
onTap: () => setPointStyle(context, _display),
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).pointWidth,
|
||||
onTap: () => setPointWidth(context),
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).pieceWidth,
|
||||
onTap: () => setPieceWidth(context),
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).fontSize,
|
||||
onTap: () => setFontSize(context),
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).boardTop,
|
||||
onTap: () => setBoardTop(context),
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).animationDuration,
|
||||
onTap: () => setAnimationDuration(context),
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: LocalDatabaseService.display.standardNotationEnabled,
|
||||
onChanged: (val) => LocalDatabaseService.display =
|
||||
_display.copyWith(standardNotationEnabled: val),
|
||||
titleString: S.of(context).standardNotation,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: AppTheme.lightBackgroundColor,
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
title: Text(S.of(context).personalization),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(S.of(context).display, style: AppTheme.settingsHeaderStyle),
|
||||
ValueListenableBuilder(
|
||||
valueListenable: LocalDatabaseService.listenDisplay,
|
||||
builder: _buildDisplay,
|
||||
),
|
||||
const SizedBox(height: AppTheme.sizedBoxHeight),
|
||||
Text(S.of(context).color, style: AppTheme.settingsHeaderStyle),
|
||||
ValueListenableBuilder(
|
||||
valueListenable: LocalDatabaseService.listenColorSettings,
|
||||
builder: _buildColor,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
part of 'package:sanmill/screens/personalization_settings/personalization_settings_page.dart';
|
||||
|
||||
class _PieceWidthSlider extends StatelessWidget {
|
||||
const _PieceWidthSlider({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SliderTheme(
|
||||
data: AppTheme.sliderThemeData,
|
||||
child: Semantics(
|
||||
label: S.of(context).pieceWidth,
|
||||
child: ValueListenableBuilder(
|
||||
valueListenable: LocalDatabaseService.listenDisplay,
|
||||
builder: (context, Box<Display> displayaBox, _) {
|
||||
final Display _display = displayaBox.get(
|
||||
LocalDatabaseService.colorSettingsKey,
|
||||
defaultValue: Display(),
|
||||
)!;
|
||||
|
||||
return Slider(
|
||||
value: _display.pieceWidth,
|
||||
min: 0.5,
|
||||
divisions: 50,
|
||||
label: _display.pieceWidth.toStringAsFixed(1),
|
||||
onChanged: (value) {
|
||||
debugPrint("[config] pieceWidth value: $value");
|
||||
LocalDatabaseService.display =
|
||||
_display.copyWith(pieceWidth: value);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
part of 'package:sanmill/screens/personalization_settings/personalization_settings_page.dart';
|
||||
|
||||
class _PointStyleModal extends StatelessWidget {
|
||||
const _PointStyleModal({
|
||||
Key? key,
|
||||
required this.pointStyle,
|
||||
required this.onChanged,
|
||||
}) : super(key: key);
|
||||
|
||||
final int pointStyle;
|
||||
final Function(int?)? onChanged;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Semantics(
|
||||
label: S.of(context).pointStyle,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: Text(S.of(context).none),
|
||||
groupValue: pointStyle,
|
||||
value: 0,
|
||||
onChanged: onChanged,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: Text(S.of(context).solid),
|
||||
groupValue: pointStyle,
|
||||
value: 1,
|
||||
onChanged: onChanged,
|
||||
),
|
||||
/*
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text(S.of(context).hollow),
|
||||
groupValue: LocalDatabaseService.display.pointStyle,
|
||||
value: 2,
|
||||
onChanged: callback,
|
||||
),
|
||||
*/
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
part of 'package:sanmill/screens/personalization_settings/personalization_settings_page.dart';
|
||||
|
||||
class _PointWidthSlider extends StatelessWidget {
|
||||
const _PointWidthSlider({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SliderTheme(
|
||||
data: AppTheme.sliderThemeData,
|
||||
child: Semantics(
|
||||
label: S.of(context).pointWidth,
|
||||
child: ValueListenableBuilder(
|
||||
valueListenable: LocalDatabaseService.listenDisplay,
|
||||
builder: (context, Box<Display> displayaBox, _) {
|
||||
final Display _display = displayaBox.get(
|
||||
LocalDatabaseService.colorSettingsKey,
|
||||
defaultValue: Display(),
|
||||
)!;
|
||||
|
||||
return Slider(
|
||||
value: _display.pointWidth,
|
||||
max: 30.0,
|
||||
divisions: 30,
|
||||
label: _display.pointWidth.toStringAsFixed(1),
|
||||
onChanged: (value) {
|
||||
debugPrint("[config] pointWidth value: $value");
|
||||
LocalDatabaseService.display =
|
||||
_display.copyWith(pointWidth: value);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,672 +0,0 @@
|
|||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
|
||||
import 'package:sanmill/generated/l10n.dart';
|
||||
import 'package:sanmill/l10n/resources.dart';
|
||||
import 'package:sanmill/services/storage/storage.dart';
|
||||
import 'package:sanmill/shared/constants.dart';
|
||||
import 'package:sanmill/shared/settings/settings_card.dart';
|
||||
import 'package:sanmill/shared/settings/settings_list_tile.dart';
|
||||
import 'package:sanmill/shared/settings/settings_switch_list_tile.dart';
|
||||
import 'package:sanmill/shared/theme/app_theme.dart';
|
||||
|
||||
class PersonalizationSettingsPage extends StatefulWidget {
|
||||
@override
|
||||
_PersonalizationSettingsPageState createState() =>
|
||||
_PersonalizationSettingsPageState();
|
||||
}
|
||||
|
||||
class _PersonalizationSettingsPageState
|
||||
extends State<PersonalizationSettingsPage> {
|
||||
// create some values
|
||||
Color pickerColor = const Color(0xFF808080);
|
||||
Color currentColor = const Color(0xFF808080);
|
||||
|
||||
// ValueChanged<Color> callback
|
||||
void changeColor(Color color) {
|
||||
setState(() => pickerColor = color);
|
||||
}
|
||||
|
||||
Future<void> showColorDialog(String colorString) async {
|
||||
final Map<String, Color> colorStrToVal = {
|
||||
S.of(context).boardColor:
|
||||
LocalDatabaseService.colorSettings.boardBackgroundColor,
|
||||
S.of(context).backgroundColor:
|
||||
LocalDatabaseService.colorSettings.darkBackgroundColor,
|
||||
S.of(context).lineColor:
|
||||
LocalDatabaseService.colorSettings.boardLineColor,
|
||||
S.of(context).whitePieceColor:
|
||||
LocalDatabaseService.colorSettings.whitePieceColor,
|
||||
S.of(context).blackPieceColor:
|
||||
LocalDatabaseService.colorSettings.blackPieceColor,
|
||||
S.of(context).pieceHighlightColor:
|
||||
LocalDatabaseService.colorSettings.pieceHighlightColor,
|
||||
S.of(context).messageColor:
|
||||
LocalDatabaseService.colorSettings.messageColor,
|
||||
S.of(context).drawerColor: LocalDatabaseService.colorSettings.drawerColor,
|
||||
S.of(context).drawerBackgroundColor:
|
||||
LocalDatabaseService.colorSettings.drawerBackgroundColor,
|
||||
S.of(context).drawerTextColor:
|
||||
LocalDatabaseService.colorSettings.drawerTextColor,
|
||||
S.of(context).drawerHighlightItemColor:
|
||||
LocalDatabaseService.colorSettings.drawerHighlightItemColor,
|
||||
S.of(context).mainToolbarBackgroundColor:
|
||||
LocalDatabaseService.colorSettings.mainToolbarBackgroundColor,
|
||||
S.of(context).mainToolbarIconColor:
|
||||
LocalDatabaseService.colorSettings.mainToolbarIconColor,
|
||||
S.of(context).navigationToolbarBackgroundColor:
|
||||
LocalDatabaseService.colorSettings.navigationToolbarBackgroundColor,
|
||||
S.of(context).navigationToolbarIconColor:
|
||||
LocalDatabaseService.colorSettings.navigationToolbarIconColor,
|
||||
};
|
||||
|
||||
final AlertDialog alert = AlertDialog(
|
||||
title: Text(
|
||||
"${S.of(context).pick} $colorString",
|
||||
style: TextStyle(
|
||||
fontSize: LocalDatabaseService.display.fontSize + 4,
|
||||
),
|
||||
),
|
||||
content: SingleChildScrollView(
|
||||
child: ColorPicker(
|
||||
pickerColor: colorStrToVal[colorString]!,
|
||||
onColorChanged: changeColor,
|
||||
),
|
||||
),
|
||||
actions: <Widget>[
|
||||
TextButton(
|
||||
child: Text(
|
||||
S.of(context).confirm,
|
||||
style: TextStyle(
|
||||
fontSize: LocalDatabaseService.display.fontSize,
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
setState(() => currentColor = pickerColor);
|
||||
|
||||
debugPrint("[config] pickerColor.value: ${pickerColor.value}");
|
||||
|
||||
if (colorString == S.of(context).boardColor) {
|
||||
LocalDatabaseService.colorSettings.boardBackgroundColor =
|
||||
pickerColor;
|
||||
} else if (colorString == S.of(context).backgroundColor) {
|
||||
LocalDatabaseService.colorSettings.darkBackgroundColor =
|
||||
pickerColor;
|
||||
} else if (colorString == S.of(context).lineColor) {
|
||||
LocalDatabaseService.colorSettings.boardLineColor = pickerColor;
|
||||
} else if (colorString == S.of(context).whitePieceColor) {
|
||||
LocalDatabaseService.colorSettings.whitePieceColor = pickerColor;
|
||||
} else if (colorString == S.of(context).blackPieceColor) {
|
||||
LocalDatabaseService.colorSettings.blackPieceColor = pickerColor;
|
||||
} else if (colorString == S.of(context).pieceHighlightColor) {
|
||||
LocalDatabaseService.colorSettings.pieceHighlightColor =
|
||||
pickerColor;
|
||||
} else if (colorString == S.of(context).messageColor) {
|
||||
LocalDatabaseService.colorSettings.messageColor = pickerColor;
|
||||
} else if (colorString == S.of(context).drawerColor) {
|
||||
LocalDatabaseService.colorSettings.drawerColor = pickerColor;
|
||||
} else if (colorString == S.of(context).drawerBackgroundColor) {
|
||||
LocalDatabaseService.colorSettings.drawerBackgroundColor =
|
||||
pickerColor;
|
||||
} else if (colorString == S.of(context).drawerTextColor) {
|
||||
LocalDatabaseService.colorSettings.drawerTextColor = pickerColor;
|
||||
} else if (colorString == S.of(context).drawerHighlightItemColor) {
|
||||
LocalDatabaseService.colorSettings.drawerHighlightItemColor =
|
||||
pickerColor;
|
||||
} else if (colorString ==
|
||||
S.of(context).mainToolbarBackgroundColor) {
|
||||
LocalDatabaseService.colorSettings.mainToolbarBackgroundColor =
|
||||
pickerColor;
|
||||
} else if (colorString == S.of(context).mainToolbarIconColor) {
|
||||
LocalDatabaseService.colorSettings.mainToolbarIconColor =
|
||||
pickerColor;
|
||||
} else if (colorString ==
|
||||
S.of(context).navigationToolbarBackgroundColor) {
|
||||
LocalDatabaseService
|
||||
.colorSettings.navigationToolbarBackgroundColor = pickerColor;
|
||||
} else if (colorString ==
|
||||
S.of(context).navigationToolbarIconColor) {
|
||||
LocalDatabaseService.colorSettings.navigationToolbarIconColor =
|
||||
pickerColor;
|
||||
}
|
||||
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
TextButton(
|
||||
child: Text(
|
||||
S.of(context).cancel,
|
||||
style: TextStyle(
|
||||
fontSize: LocalDatabaseService.display.fontSize,
|
||||
),
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
// show the dialog
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return alert;
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
SliderTheme _boardBorderLineWidthSliderTheme(
|
||||
BuildContext context,
|
||||
Function setState,
|
||||
) {
|
||||
return SliderTheme(
|
||||
data: AppTheme.sliderThemeData,
|
||||
child: Semantics(
|
||||
label: S.of(context).boardBorderLineWidth,
|
||||
child: Slider(
|
||||
value: LocalDatabaseService.display.boardBorderLineWidth,
|
||||
max: 20.0,
|
||||
divisions: 200,
|
||||
label: LocalDatabaseService.display.boardBorderLineWidth
|
||||
.toStringAsFixed(1),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
debugPrint("[config] BoardBorderLineWidth value: $value");
|
||||
LocalDatabaseService.display.boardBorderLineWidth = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> setBoardBorderLineWidth() async {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (_) => StatefulBuilder(
|
||||
builder: _boardBorderLineWidthSliderTheme,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
SliderTheme _boardInnerLineWidthSliderTheme(
|
||||
BuildContext context,
|
||||
Function setState,
|
||||
) {
|
||||
return SliderTheme(
|
||||
data: AppTheme.sliderThemeData,
|
||||
child: Semantics(
|
||||
label: S.of(context).boardInnerLineWidth,
|
||||
child: Slider(
|
||||
value: LocalDatabaseService.display.boardInnerLineWidth,
|
||||
max: 20.0,
|
||||
divisions: 200,
|
||||
label: LocalDatabaseService.display.boardInnerLineWidth
|
||||
.toStringAsFixed(1),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
debugPrint("[config] BoardInnerLineWidth value: $value");
|
||||
LocalDatabaseService.display.boardInnerLineWidth = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> setBoardInnerLineWidth() async {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (_) => StatefulBuilder(
|
||||
builder: _boardInnerLineWidthSliderTheme,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void setPointStyle() {
|
||||
Future<void> callback(int? pointStyle) async {
|
||||
Navigator.pop(context);
|
||||
|
||||
setState(
|
||||
() => LocalDatabaseService.display.pointStyle = pointStyle ?? 0,
|
||||
);
|
||||
|
||||
debugPrint("[config] pointStyle: $pointStyle");
|
||||
}
|
||||
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (BuildContext context) => Semantics(
|
||||
label: S.of(context).pointStyle,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: Text(S.of(context).none),
|
||||
groupValue: LocalDatabaseService.display.pointStyle,
|
||||
value: 0,
|
||||
onChanged: callback,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: Text(S.of(context).solid),
|
||||
groupValue: LocalDatabaseService.display.pointStyle,
|
||||
value: 1,
|
||||
onChanged: callback,
|
||||
),
|
||||
/*
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text(S.of(context).hollow),
|
||||
groupValue: LocalDatabaseService.display.pointStyle,
|
||||
value: 2,
|
||||
onChanged: callback,
|
||||
),
|
||||
*/
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
SliderTheme _pointWidthSliderTheme(BuildContext context, Function setState) {
|
||||
return SliderTheme(
|
||||
data: AppTheme.sliderThemeData,
|
||||
child: Semantics(
|
||||
label: S.of(context).pointWidth,
|
||||
child: Slider(
|
||||
value: LocalDatabaseService.display.pointWidth,
|
||||
max: 30.0,
|
||||
divisions: 30,
|
||||
label: LocalDatabaseService.display.pointWidth.toStringAsFixed(1),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
debugPrint("[config] pointWidth value: $value");
|
||||
LocalDatabaseService.display.pointWidth = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> setPointWidth() async {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (_) => StatefulBuilder(
|
||||
builder: _pointWidthSliderTheme,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
SliderTheme _pieceWidthSliderTheme(BuildContext context, Function setState) {
|
||||
return SliderTheme(
|
||||
data: AppTheme.sliderThemeData,
|
||||
child: Semantics(
|
||||
label: S.of(context).pieceWidth,
|
||||
child: Slider(
|
||||
value: LocalDatabaseService.display.pieceWidth,
|
||||
min: 0.5,
|
||||
divisions: 50,
|
||||
label: LocalDatabaseService.display.pieceWidth.toStringAsFixed(1),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
debugPrint("[config] pieceWidth value: $value");
|
||||
LocalDatabaseService.display.pieceWidth = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> setPieceWidth() async {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (_) => StatefulBuilder(
|
||||
builder: _pieceWidthSliderTheme,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
SliderTheme _fontSizeSliderTheme(BuildContext context, Function setState) {
|
||||
return SliderTheme(
|
||||
data: AppTheme.sliderThemeData,
|
||||
child: Semantics(
|
||||
label: S.of(context).fontSize,
|
||||
child: Slider(
|
||||
value: LocalDatabaseService.display.fontSize,
|
||||
min: 16,
|
||||
max: 32,
|
||||
divisions: 16,
|
||||
label: LocalDatabaseService.display.fontSize.toStringAsFixed(1),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
debugPrint("[config] fontSize value: $value");
|
||||
LocalDatabaseService.display.fontSize = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> setFontSize() async {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (_) => StatefulBuilder(
|
||||
builder: _fontSizeSliderTheme,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
SliderTheme _boardTopSliderTheme(BuildContext context, Function setState) {
|
||||
return SliderTheme(
|
||||
data: AppTheme.sliderThemeData,
|
||||
child: Semantics(
|
||||
label: S.of(context).boardTop,
|
||||
child: Slider(
|
||||
value: LocalDatabaseService.display.boardTop,
|
||||
max: 288.0,
|
||||
divisions: 288,
|
||||
label: LocalDatabaseService.display.boardTop.toStringAsFixed(1),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
debugPrint("[config] BoardTop value: $value");
|
||||
LocalDatabaseService.display.boardTop = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> setBoardTop() async {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (_) => StatefulBuilder(
|
||||
builder: _boardTopSliderTheme,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
SliderTheme _animationDurationSliderTheme(
|
||||
BuildContext context,
|
||||
Function setState,
|
||||
) {
|
||||
return SliderTheme(
|
||||
data: AppTheme.sliderThemeData,
|
||||
child: Semantics(
|
||||
label: S.of(context).animationDuration,
|
||||
child: Slider(
|
||||
value: LocalDatabaseService.display.animationDuration,
|
||||
max: 5.0,
|
||||
divisions: 50,
|
||||
label:
|
||||
LocalDatabaseService.display.animationDuration.toStringAsFixed(1),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
debugPrint("[config] AnimationDuration value: $value");
|
||||
LocalDatabaseService.display.animationDuration = value;
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> setAnimationDuration() async {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (_) => StatefulBuilder(
|
||||
builder: _animationDurationSliderTheme,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: AppTheme.lightBackgroundColor,
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
title: Text(S.of(context).personalization),
|
||||
),
|
||||
body: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: children(context),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> children(BuildContext context) {
|
||||
Future<void> langCallback([Locale? locale]) async {
|
||||
debugPrint("[config] languageCode = $locale");
|
||||
|
||||
Navigator.pop(context);
|
||||
|
||||
setState(() {
|
||||
LocalDatabaseService.display.languageCode =
|
||||
locale ?? Constants.defaultLocale;
|
||||
S.load(Locale(Resources.of().languageCode));
|
||||
});
|
||||
|
||||
debugPrint(
|
||||
"[config] LocalDatabaseService.display.languageCode: ${LocalDatabaseService.display.languageCode}",
|
||||
);
|
||||
}
|
||||
|
||||
return <Widget>[
|
||||
Text(S.of(context).display, style: AppTheme.settingsHeaderStyle),
|
||||
SettingsCard(
|
||||
children: <Widget>[
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).language,
|
||||
trailingString: LocalDatabaseService.display.languageCode !=
|
||||
Constants.defaultLocale
|
||||
? languageCodeToStrings[
|
||||
LocalDatabaseService.display.languageCode]!
|
||||
.languageName
|
||||
: "",
|
||||
onTap: () => setLanguage(context, langCallback),
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: LocalDatabaseService.display.isPieceCountInHandShown,
|
||||
onChanged: setIsPieceCountInHandShown,
|
||||
titleString: S.of(context).isPieceCountInHandShown,
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: LocalDatabaseService.display.isNotationsShown,
|
||||
onChanged: setIsNotationsShown,
|
||||
titleString: S.of(context).isNotationsShown,
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: LocalDatabaseService.display.isHistoryNavigationToolbarShown,
|
||||
onChanged: setIsHistoryNavigationToolbarShown,
|
||||
titleString: S.of(context).isHistoryNavigationToolbarShown,
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).boardBorderLineWidth,
|
||||
onTap: setBoardBorderLineWidth,
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).boardInnerLineWidth,
|
||||
onTap: setBoardInnerLineWidth,
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).pointStyle,
|
||||
onTap: setPointStyle,
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).pointWidth,
|
||||
onTap: setPointWidth,
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).pieceWidth,
|
||||
onTap: setPieceWidth,
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).fontSize,
|
||||
onTap: setFontSize,
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).boardTop,
|
||||
onTap: setBoardTop,
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).animationDuration,
|
||||
onTap: setAnimationDuration,
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: LocalDatabaseService.display.standardNotationEnabled,
|
||||
onChanged: setStandardNotationEnabled,
|
||||
titleString: S.of(context).standardNotation,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppTheme.sizedBoxHeight),
|
||||
Text(S.of(context).color, style: AppTheme.settingsHeaderStyle),
|
||||
SettingsCard(
|
||||
children: <Widget>[
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).boardColor,
|
||||
trailingColor:
|
||||
LocalDatabaseService.colorSettings.boardBackgroundColor,
|
||||
onTap: () => showColorDialog(S.of(context).boardColor),
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).backgroundColor,
|
||||
trailingColor:
|
||||
LocalDatabaseService.colorSettings.darkBackgroundColor,
|
||||
onTap: () => showColorDialog(S.of(context).backgroundColor),
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).lineColor,
|
||||
trailingColor: LocalDatabaseService.colorSettings.boardLineColor,
|
||||
onTap: () => showColorDialog(S.of(context).lineColor),
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).whitePieceColor,
|
||||
trailingColor: LocalDatabaseService.colorSettings.whitePieceColor,
|
||||
onTap: () => showColorDialog(S.of(context).whitePieceColor),
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).blackPieceColor,
|
||||
trailingColor: LocalDatabaseService.colorSettings.blackPieceColor,
|
||||
onTap: () => showColorDialog(S.of(context).blackPieceColor),
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).pieceHighlightColor,
|
||||
trailingColor:
|
||||
LocalDatabaseService.colorSettings.pieceHighlightColor,
|
||||
onTap: () => showColorDialog(S.of(context).pieceHighlightColor),
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).messageColor,
|
||||
trailingColor: LocalDatabaseService.colorSettings.messageColor,
|
||||
onTap: () => showColorDialog(S.of(context).messageColor),
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).drawerColor,
|
||||
trailingColor: LocalDatabaseService.colorSettings.drawerColor,
|
||||
onTap: () => showColorDialog(S.of(context).drawerColor),
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).drawerBackgroundColor,
|
||||
trailingColor:
|
||||
LocalDatabaseService.colorSettings.drawerBackgroundColor,
|
||||
onTap: () => showColorDialog(S.of(context).drawerBackgroundColor),
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).drawerTextColor,
|
||||
trailingColor: LocalDatabaseService.colorSettings.drawerTextColor,
|
||||
onTap: () => showColorDialog(S.of(context).drawerTextColor),
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).drawerHighlightItemColor,
|
||||
trailingColor:
|
||||
LocalDatabaseService.colorSettings.drawerHighlightItemColor,
|
||||
onTap: () =>
|
||||
showColorDialog(S.of(context).drawerHighlightItemColor),
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).mainToolbarBackgroundColor,
|
||||
trailingColor:
|
||||
LocalDatabaseService.colorSettings.mainToolbarBackgroundColor,
|
||||
onTap: () =>
|
||||
showColorDialog(S.of(context).mainToolbarBackgroundColor),
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).mainToolbarIconColor,
|
||||
trailingColor:
|
||||
LocalDatabaseService.colorSettings.mainToolbarIconColor,
|
||||
onTap: () => showColorDialog(S.of(context).mainToolbarIconColor),
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).navigationToolbarBackgroundColor,
|
||||
trailingColor: LocalDatabaseService
|
||||
.colorSettings.navigationToolbarBackgroundColor,
|
||||
onTap: () =>
|
||||
showColorDialog(S.of(context).navigationToolbarBackgroundColor),
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).navigationToolbarIconColor,
|
||||
trailingColor:
|
||||
LocalDatabaseService.colorSettings.navigationToolbarIconColor,
|
||||
onTap: () =>
|
||||
showColorDialog(S.of(context).navigationToolbarIconColor),
|
||||
),
|
||||
],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
// Display
|
||||
|
||||
Future<void> setIsPieceCountInHandShown(bool value) async {
|
||||
setState(
|
||||
() => LocalDatabaseService.display.isPieceCountInHandShown = value,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> setIsNotationsShown(bool value) async {
|
||||
setState(() => LocalDatabaseService.display.isNotationsShown = value);
|
||||
}
|
||||
|
||||
Future<void> setIsHistoryNavigationToolbarShown(bool value) async {
|
||||
setState(
|
||||
() =>
|
||||
LocalDatabaseService.display.isHistoryNavigationToolbarShown = value,
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> setStandardNotationEnabled(bool value) async {
|
||||
setState(
|
||||
() => LocalDatabaseService.display.standardNotationEnabled = value,
|
||||
);
|
||||
|
||||
debugPrint("[config] standardNotationEnabled: $value");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
part of 'package:sanmill/screens/rule_settings/rule_settings_page.dart';
|
||||
|
||||
class _EndGameNMoveRuleModal extends StatelessWidget {
|
||||
const _EndGameNMoveRuleModal({
|
||||
Key? key,
|
||||
required this.endgameNMoveRule,
|
||||
required this.onChanged,
|
||||
}) : super(key: key);
|
||||
|
||||
final int endgameNMoveRule;
|
||||
final Function(int?)? onChanged;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Semantics(
|
||||
label: S.of(context).endgameNMoveRule,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('5'),
|
||||
groupValue: endgameNMoveRule,
|
||||
value: 5,
|
||||
onChanged: onChanged,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('10'),
|
||||
groupValue: endgameNMoveRule,
|
||||
value: 10,
|
||||
onChanged: onChanged,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('20'),
|
||||
groupValue: endgameNMoveRule,
|
||||
value: 20,
|
||||
onChanged: onChanged,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('30'),
|
||||
groupValue: endgameNMoveRule,
|
||||
value: 30,
|
||||
onChanged: onChanged,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('50'),
|
||||
groupValue: endgameNMoveRule,
|
||||
value: 50,
|
||||
onChanged: onChanged,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('60'),
|
||||
groupValue: endgameNMoveRule,
|
||||
value: 60,
|
||||
onChanged: onChanged,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('100'),
|
||||
groupValue: endgameNMoveRule,
|
||||
value: 100,
|
||||
onChanged: onChanged,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('200'),
|
||||
groupValue: endgameNMoveRule,
|
||||
value: 200,
|
||||
onChanged: onChanged,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
part of 'package:sanmill/screens/rule_settings/rule_settings_page.dart';
|
||||
|
||||
class _FlyPieceCountModal extends StatelessWidget {
|
||||
const _FlyPieceCountModal({
|
||||
Key? key,
|
||||
required this.flyPieceCount,
|
||||
required this.onChanged,
|
||||
}) : super(key: key);
|
||||
|
||||
final int flyPieceCount;
|
||||
final Function(int?)? onChanged;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Semantics(
|
||||
label: S.of(context).flyPieceCount,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('3'),
|
||||
groupValue: flyPieceCount,
|
||||
value: 3,
|
||||
onChanged: onChanged,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('4'),
|
||||
groupValue: flyPieceCount,
|
||||
value: 4,
|
||||
onChanged: onChanged,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
part of 'package:sanmill/screens/rule_settings/rule_settings_page.dart';
|
||||
|
||||
class _NMoveRuleModal extends StatelessWidget {
|
||||
const _NMoveRuleModal({
|
||||
Key? key,
|
||||
required this.nMoveRule,
|
||||
required this.onChanged,
|
||||
}) : super(key: key);
|
||||
|
||||
final int nMoveRule;
|
||||
final Function(int?)? onChanged;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Semantics(
|
||||
label: S.of(context).nMoveRule,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('30'),
|
||||
groupValue: nMoveRule,
|
||||
value: 30,
|
||||
onChanged: onChanged,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('50'),
|
||||
groupValue: nMoveRule,
|
||||
value: 50,
|
||||
onChanged: onChanged,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('60'),
|
||||
groupValue: nMoveRule,
|
||||
value: 60,
|
||||
onChanged: onChanged,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('100'),
|
||||
groupValue: nMoveRule,
|
||||
value: 100,
|
||||
onChanged: onChanged,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('200'),
|
||||
groupValue: nMoveRule,
|
||||
value: 200,
|
||||
onChanged: onChanged,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
part of 'package:sanmill/screens/rule_settings/rule_settings_page.dart';
|
||||
|
||||
class _PieceCountModal extends StatelessWidget {
|
||||
const _PieceCountModal({
|
||||
Key? key,
|
||||
required this.piecesCount,
|
||||
required this.onChanged,
|
||||
}) : super(key: key);
|
||||
|
||||
final int piecesCount;
|
||||
final Function(int?)? onChanged;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Semantics(
|
||||
label: S.of(context).piecesCount,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('9'),
|
||||
groupValue: piecesCount,
|
||||
value: 9,
|
||||
onChanged: onChanged,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('10'),
|
||||
groupValue: piecesCount,
|
||||
value: 10,
|
||||
onChanged: onChanged,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('11'),
|
||||
groupValue: piecesCount,
|
||||
value: 11,
|
||||
onChanged: onChanged,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('12'),
|
||||
groupValue: piecesCount,
|
||||
value: 12,
|
||||
onChanged: onChanged,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,358 @@
|
|||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hive_flutter/hive_flutter.dart' show Box;
|
||||
import 'package:sanmill/generated/l10n.dart';
|
||||
import 'package:sanmill/models/rules.dart';
|
||||
import 'package:sanmill/services/storage/storage.dart';
|
||||
import 'package:sanmill/shared/settings/settings_card.dart';
|
||||
import 'package:sanmill/shared/settings/settings_list_tile.dart';
|
||||
import 'package:sanmill/shared/settings/settings_switch_list_tile.dart';
|
||||
import 'package:sanmill/shared/snack_bar.dart';
|
||||
import 'package:sanmill/shared/theme/app_theme.dart';
|
||||
|
||||
part 'package:sanmill/screens/rule_settings/fly_piece_count_modal.dart';
|
||||
part 'package:sanmill/screens/rule_settings/endgame_n_move_rule_modal.dart';
|
||||
part 'package:sanmill/screens/rule_settings/piece_count_modal.dart';
|
||||
part 'package:sanmill/screens/rule_settings/n_move_rule_modal.dart';
|
||||
|
||||
class RuleSettingsPage extends StatelessWidget {
|
||||
const RuleSettingsPage({Key? key}) : super(key: key);
|
||||
|
||||
// General
|
||||
void _setNTotalPiecesEachSide(BuildContext context, Rules _rules) {
|
||||
void _callback(int? piecesCount) {
|
||||
Navigator.pop(context);
|
||||
|
||||
LocalDatabaseService.rules = _rules.copyWith(piecesCount: piecesCount);
|
||||
|
||||
debugPrint("[config] piecesCount = $piecesCount");
|
||||
}
|
||||
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (_) => _PieceCountModal(
|
||||
piecesCount: _rules.piecesCount,
|
||||
onChanged: _callback,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _setNMoveRule(BuildContext context, Rules _rules) {
|
||||
void _callback(int? nMoveRule) {
|
||||
Navigator.pop(context);
|
||||
|
||||
LocalDatabaseService.rules = _rules.copyWith(nMoveRule: nMoveRule);
|
||||
|
||||
debugPrint("[config] nMoveRule = $nMoveRule");
|
||||
}
|
||||
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (_) => _NMoveRuleModal(
|
||||
nMoveRule: _rules.nMoveRule,
|
||||
onChanged: _callback,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _setEndgameNMoveRule(BuildContext context, Rules _rules) {
|
||||
void _callback(int? endgameNMoveRule) {
|
||||
Navigator.pop(context);
|
||||
|
||||
LocalDatabaseService.rules =
|
||||
_rules.copyWith(endgameNMoveRule: endgameNMoveRule);
|
||||
|
||||
debugPrint("[config] endgameNMoveRule = $endgameNMoveRule");
|
||||
}
|
||||
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (_) => _EndGameNMoveRuleModal(
|
||||
endgameNMoveRule: _rules.endgameNMoveRule,
|
||||
onChanged: _callback,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _setFlyPieceCount(BuildContext context, Rules _rules) {
|
||||
void _callback(int? flyPieceCount) {
|
||||
Navigator.pop(context);
|
||||
|
||||
LocalDatabaseService.rules =
|
||||
_rules.copyWith(flyPieceCount: flyPieceCount);
|
||||
|
||||
debugPrint("[config] flyPieceCount = $flyPieceCount");
|
||||
}
|
||||
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (_) => _FlyPieceCountModal(
|
||||
flyPieceCount: _rules.flyPieceCount,
|
||||
onChanged: _callback,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _setHasDiagonalLines(Rules _rules, bool value) {
|
||||
LocalDatabaseService.rules = _rules.copyWith(hasDiagonalLines: value);
|
||||
|
||||
debugPrint("[config] hasDiagonalLines: $value");
|
||||
}
|
||||
|
||||
void _setAllowFlyingAllowed(Rules _rules, bool value) {
|
||||
LocalDatabaseService.rules = _rules.copyWith(mayFly: value);
|
||||
|
||||
debugPrint("[config] mayFly: $value");
|
||||
}
|
||||
|
||||
void _setThreefoldRepetitionRule(Rules _rules, bool value) {
|
||||
LocalDatabaseService.rules =
|
||||
_rules.copyWith(threefoldRepetitionRule: value);
|
||||
|
||||
debugPrint("[config] threefoldRepetitionRule: $value");
|
||||
}
|
||||
|
||||
// Placing
|
||||
void _setHasBannedLocations(Rules _rules, bool value) {
|
||||
LocalDatabaseService.rules = _rules.copyWith(hasBannedLocations: value);
|
||||
|
||||
debugPrint("[config] hasBannedLocations: $value");
|
||||
}
|
||||
|
||||
void _setIsWhiteLoseButNotDrawWhenBoardFull(Rules _rules, bool value) {
|
||||
LocalDatabaseService.rules =
|
||||
_rules.copyWith(isWhiteLoseButNotDrawWhenBoardFull: value);
|
||||
|
||||
debugPrint("[config] isWhiteLoseButNotDrawWhenBoardFull: $value");
|
||||
}
|
||||
|
||||
void _setMayOnlyRemoveUnplacedPieceInPlacingPhase(Rules _rules, bool value) {
|
||||
LocalDatabaseService.rules =
|
||||
_rules.copyWith(mayOnlyRemoveUnplacedPieceInPlacingPhase: value);
|
||||
|
||||
debugPrint("[config] mayOnlyRemoveUnplacedPieceInPlacingPhase: $value");
|
||||
}
|
||||
|
||||
// Moving
|
||||
void _setMayMoveInPlacingPhase(
|
||||
BuildContext context,
|
||||
Rules _rules,
|
||||
bool value,
|
||||
) {
|
||||
LocalDatabaseService.rules = _rules.copyWith(mayMoveInPlacingPhase: value);
|
||||
|
||||
debugPrint("[config] mayMoveInPlacingPhase: $value");
|
||||
|
||||
if (value) {
|
||||
ScaffoldMessenger.of(context).clearSnackBars();
|
||||
showSnackBar(context, S.of(context).experimental);
|
||||
}
|
||||
}
|
||||
|
||||
void _setIsDefenderMoveFirst(Rules _rules, bool value) {
|
||||
LocalDatabaseService.rules = _rules.copyWith(isDefenderMoveFirst: value);
|
||||
|
||||
debugPrint("[config] isDefenderMoveFirst: $value");
|
||||
}
|
||||
|
||||
void _setIsLoseButNotChangeSideWhenNoWay(Rules _rules, bool value) {
|
||||
LocalDatabaseService.rules =
|
||||
_rules.copyWith(isLoseButNotChangeSideWhenNoWay: value);
|
||||
|
||||
debugPrint("[config] isLoseButNotChangeSideWhenNoWay: $value");
|
||||
}
|
||||
|
||||
// Removing
|
||||
void _setAllowRemovePieceInMill(Rules _rules, bool value) {
|
||||
LocalDatabaseService.rules =
|
||||
_rules.copyWith(mayRemoveFromMillsAlways: value);
|
||||
|
||||
debugPrint("[config] mayRemoveFromMillsAlways: $value");
|
||||
}
|
||||
|
||||
void _setAllowRemoveMultiPiecesWhenCloseMultiMill(Rules _rules, bool value) {
|
||||
LocalDatabaseService.rules = _rules.copyWith(mayRemoveMultiple: value);
|
||||
|
||||
debugPrint("[config] mayRemoveMultiple: $value");
|
||||
}
|
||||
|
||||
// Unused
|
||||
void _setNPiecesAtLeast(Rules _rules, int value) {
|
||||
LocalDatabaseService.rules = _rules.copyWith(piecesAtLeastCount: value);
|
||||
|
||||
debugPrint("[config] piecesAtLeastCount: $value");
|
||||
}
|
||||
|
||||
Widget _buildRules(BuildContext context, Box<Rules> rulesBox, _) {
|
||||
final Rules _rules = rulesBox.get(
|
||||
LocalDatabaseService.rulesKey,
|
||||
defaultValue: Rules(),
|
||||
)!;
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(S.of(context).general, style: AppTheme.settingsHeaderStyle),
|
||||
SettingsCard(
|
||||
children: <Widget>[
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).piecesCount,
|
||||
subtitleString: S.of(context).piecesCount_Detail,
|
||||
trailingString: _rules.piecesCount.toString(),
|
||||
onTap: () => _setNTotalPiecesEachSide(context, _rules),
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: _rules.hasDiagonalLines,
|
||||
onChanged: (val) => _setHasDiagonalLines(_rules, val),
|
||||
titleString: S.of(context).hasDiagonalLines,
|
||||
subtitleString: S.of(context).hasDiagonalLines_Detail,
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).nMoveRule,
|
||||
subtitleString: S.of(context).nMoveRule_Detail,
|
||||
trailingString: _rules.nMoveRule.toString(),
|
||||
onTap: () => _setNMoveRule(context, _rules),
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).endgameNMoveRule,
|
||||
subtitleString: S.of(context).endgameNMoveRule_Detail,
|
||||
trailingString: _rules.endgameNMoveRule.toString(),
|
||||
onTap: () => _setEndgameNMoveRule(context, _rules),
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: _rules.threefoldRepetitionRule,
|
||||
onChanged: (val) => _setThreefoldRepetitionRule(_rules, val),
|
||||
titleString: S.of(context).threefoldRepetitionRule,
|
||||
subtitleString: S.of(context).threefoldRepetitionRule_Detail,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppTheme.sizedBoxHeight),
|
||||
Text(S.of(context).placing, style: AppTheme.settingsHeaderStyle),
|
||||
SettingsCard(
|
||||
children: <Widget>[
|
||||
SettingsSwitchListTile(
|
||||
value: _rules.hasBannedLocations,
|
||||
onChanged: (val) => _setHasBannedLocations(_rules, val),
|
||||
titleString: S.of(context).hasBannedLocations,
|
||||
subtitleString: S.of(context).hasBannedLocations_Detail,
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: _rules.isWhiteLoseButNotDrawWhenBoardFull,
|
||||
onChanged: (val) =>
|
||||
_setIsWhiteLoseButNotDrawWhenBoardFull(_rules, val),
|
||||
titleString: S.of(context).isWhiteLoseButNotDrawWhenBoardFull,
|
||||
subtitleString:
|
||||
S.of(context).isWhiteLoseButNotDrawWhenBoardFull_Detail,
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: _rules.mayOnlyRemoveUnplacedPieceInPlacingPhase,
|
||||
onChanged: (val) =>
|
||||
_setMayOnlyRemoveUnplacedPieceInPlacingPhase(_rules, val),
|
||||
titleString: S.of(context).removeUnplacedPiece,
|
||||
subtitleString: S.of(context).removeUnplacedPiece_Detail,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppTheme.sizedBoxHeight),
|
||||
Text(S.of(context).moving, style: AppTheme.settingsHeaderStyle),
|
||||
SettingsCard(
|
||||
children: <Widget>[
|
||||
if (LocalDatabaseService.preferences.experimentsEnabled)
|
||||
SettingsSwitchListTile(
|
||||
value: _rules.mayMoveInPlacingPhase,
|
||||
onChanged: (val) =>
|
||||
_setMayMoveInPlacingPhase(context, _rules, val),
|
||||
titleString: S.of(context).mayMoveInPlacingPhase,
|
||||
subtitleString: S.of(context).mayMoveInPlacingPhase_Detail,
|
||||
)
|
||||
else
|
||||
SettingsSwitchListTile(
|
||||
value: _rules.isDefenderMoveFirst,
|
||||
onChanged: (val) => _setIsDefenderMoveFirst(_rules, val),
|
||||
titleString: S.of(context).isDefenderMoveFirst,
|
||||
subtitleString: S.of(context).isDefenderMoveFirst_Detail,
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: _rules.isLoseButNotChangeSideWhenNoWay,
|
||||
onChanged: (val) =>
|
||||
_setIsLoseButNotChangeSideWhenNoWay(_rules, val),
|
||||
titleString: S.of(context).isLoseButNotChangeSideWhenNoWay,
|
||||
subtitleString:
|
||||
S.of(context).isLoseButNotChangeSideWhenNoWay_Detail,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppTheme.sizedBoxHeight),
|
||||
Text(S.of(context).mayFly, style: AppTheme.settingsHeaderStyle),
|
||||
SettingsCard(
|
||||
children: <Widget>[
|
||||
SettingsSwitchListTile(
|
||||
value: _rules.mayFly,
|
||||
onChanged: (val) => _setAllowFlyingAllowed(_rules, val),
|
||||
titleString: S.of(context).mayFly,
|
||||
subtitleString: S.of(context).mayFly_Detail,
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).flyPieceCount,
|
||||
subtitleString: S.of(context).flyPieceCount_Detail,
|
||||
trailingString: _rules.flyPieceCount.toString(),
|
||||
onTap: () => _setFlyPieceCount(context, _rules),
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppTheme.sizedBoxHeight),
|
||||
Text(S.of(context).removing, style: AppTheme.settingsHeaderStyle),
|
||||
SettingsCard(
|
||||
children: <Widget>[
|
||||
SettingsSwitchListTile(
|
||||
value: _rules.mayRemoveFromMillsAlways,
|
||||
onChanged: (val) => _setAllowRemovePieceInMill(_rules, val),
|
||||
titleString: S.of(context).mayRemoveFromMillsAlways,
|
||||
subtitleString: S.of(context).mayRemoveFromMillsAlways_Detail,
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: _rules.mayRemoveMultiple,
|
||||
onChanged: (val) =>
|
||||
_setAllowRemoveMultiPiecesWhenCloseMultiMill(_rules, val),
|
||||
titleString: S.of(context).mayRemoveMultiple,
|
||||
subtitleString: S.of(context).mayRemoveMultiple_Detail,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: AppTheme.lightBackgroundColor,
|
||||
appBar:
|
||||
AppBar(centerTitle: true, title: Text(S.of(context).ruleSettings)),
|
||||
body: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: ValueListenableBuilder(
|
||||
valueListenable: LocalDatabaseService.listenRules,
|
||||
builder: _buildRules,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,545 +0,0 @@
|
|||
/*
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:sanmill/generated/l10n.dart';
|
||||
import 'package:sanmill/l10n/resources.dart';
|
||||
import 'package:sanmill/mill/rule.dart';
|
||||
import 'package:sanmill/services/storage/storage.dart';
|
||||
import 'package:sanmill/shared/settings/settings_card.dart';
|
||||
import 'package:sanmill/shared/settings/settings_list_tile.dart';
|
||||
import 'package:sanmill/shared/settings/settings_switch_list_tile.dart';
|
||||
import 'package:sanmill/shared/snack_bar.dart';
|
||||
import 'package:sanmill/shared/theme/app_theme.dart';
|
||||
|
||||
class RuleSettingsPage extends StatefulWidget {
|
||||
@override
|
||||
_RuleSettingsPageState createState() => _RuleSettingsPageState();
|
||||
}
|
||||
|
||||
class _RuleSettingsPageState extends State<RuleSettingsPage> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: AppTheme.lightBackgroundColor,
|
||||
appBar:
|
||||
AppBar(centerTitle: true, title: Text(S.of(context).ruleSettings)),
|
||||
body: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: children(context),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> children(BuildContext context) {
|
||||
return <Widget>[
|
||||
Text(S.of(context).general, style: AppTheme.settingsHeaderStyle),
|
||||
SettingsCard(
|
||||
children: <Widget>[
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).piecesCount,
|
||||
subtitleString: S.of(context).piecesCount_Detail,
|
||||
trailingString: LocalDatabaseService.rules.piecesCount.toString(),
|
||||
onTap: setNTotalPiecesEachSide,
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: LocalDatabaseService.rules.hasDiagonalLines,
|
||||
onChanged: setHasDiagonalLines,
|
||||
titleString: S.of(context).hasDiagonalLines,
|
||||
subtitleString: S.of(context).hasDiagonalLines_Detail,
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).nMoveRule,
|
||||
subtitleString: S.of(context).nMoveRule_Detail,
|
||||
trailingString: LocalDatabaseService.rules.nMoveRule.toString(),
|
||||
onTap: setNMoveRule,
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).endgameNMoveRule,
|
||||
subtitleString: S.of(context).endgameNMoveRule_Detail,
|
||||
trailingString:
|
||||
LocalDatabaseService.rules.endgameNMoveRule.toString(),
|
||||
onTap: setEndgameNMoveRule,
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: LocalDatabaseService.rules.threefoldRepetitionRule,
|
||||
onChanged: setThreefoldRepetitionRule,
|
||||
titleString: S.of(context).threefoldRepetitionRule,
|
||||
subtitleString: S.of(context).threefoldRepetitionRule_Detail,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppTheme.sizedBoxHeight),
|
||||
Text(S.of(context).placing, style: AppTheme.settingsHeaderStyle),
|
||||
SettingsCard(
|
||||
children: <Widget>[
|
||||
SettingsSwitchListTile(
|
||||
value: LocalDatabaseService.rules.hasBannedLocations,
|
||||
onChanged: setHasBannedLocations,
|
||||
titleString: S.of(context).hasBannedLocations,
|
||||
subtitleString: S.of(context).hasBannedLocations_Detail,
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value:
|
||||
LocalDatabaseService.rules.isWhiteLoseButNotDrawWhenBoardFull,
|
||||
onChanged: setIsWhiteLoseButNotDrawWhenBoardFull,
|
||||
titleString: S.of(context).isWhiteLoseButNotDrawWhenBoardFull,
|
||||
subtitleString:
|
||||
S.of(context).isWhiteLoseButNotDrawWhenBoardFull_Detail,
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: LocalDatabaseService
|
||||
.rules.mayOnlyRemoveUnplacedPieceInPlacingPhase,
|
||||
onChanged: setMayOnlyRemoveUnplacedPieceInPlacingPhase,
|
||||
titleString: S.of(context).removeUnplacedPiece,
|
||||
subtitleString: S.of(context).removeUnplacedPiece_Detail,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppTheme.sizedBoxHeight),
|
||||
Text(S.of(context).moving, style: AppTheme.settingsHeaderStyle),
|
||||
SettingsCard(
|
||||
children: <Widget>[
|
||||
if (LocalDatabaseService.preferences.experimentsEnabled)
|
||||
SettingsSwitchListTile(
|
||||
value: LocalDatabaseService.rules.mayMoveInPlacingPhase,
|
||||
onChanged: setMayMoveInPlacingPhase,
|
||||
titleString: S.of(context).mayMoveInPlacingPhase,
|
||||
subtitleString: S.of(context).mayMoveInPlacingPhase_Detail,
|
||||
)
|
||||
else
|
||||
SettingsSwitchListTile(
|
||||
value: LocalDatabaseService.rules.isDefenderMoveFirst,
|
||||
onChanged: setIsDefenderMoveFirst,
|
||||
titleString: S.of(context).isDefenderMoveFirst,
|
||||
subtitleString: S.of(context).isDefenderMoveFirst_Detail,
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: LocalDatabaseService.rules.isLoseButNotChangeSideWhenNoWay,
|
||||
onChanged: setIsLoseButNotChangeSideWhenNoWay,
|
||||
titleString: S.of(context).isLoseButNotChangeSideWhenNoWay,
|
||||
subtitleString:
|
||||
S.of(context).isLoseButNotChangeSideWhenNoWay_Detail,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppTheme.sizedBoxHeight),
|
||||
Text(S.of(context).mayFly, style: AppTheme.settingsHeaderStyle),
|
||||
SettingsCard(
|
||||
children: <Widget>[
|
||||
SettingsSwitchListTile(
|
||||
value: LocalDatabaseService.rules.mayFly,
|
||||
onChanged: setAllowFlyingAllowed,
|
||||
titleString: S.of(context).mayFly,
|
||||
subtitleString: S.of(context).mayFly_Detail,
|
||||
),
|
||||
SettingsListTile(
|
||||
titleString: S.of(context).flyPieceCount,
|
||||
subtitleString: S.of(context).flyPieceCount_Detail,
|
||||
trailingString: LocalDatabaseService.rules.flyPieceCount.toString(),
|
||||
onTap: setFlyPieceCount,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: AppTheme.sizedBoxHeight),
|
||||
Text(S.of(context).removing, style: AppTheme.settingsHeaderStyle),
|
||||
SettingsCard(
|
||||
children: <Widget>[
|
||||
SettingsSwitchListTile(
|
||||
value: LocalDatabaseService.rules.mayRemoveFromMillsAlways,
|
||||
onChanged: setAllowRemovePieceInMill,
|
||||
titleString: S.of(context).mayRemoveFromMillsAlways,
|
||||
subtitleString: S.of(context).mayRemoveFromMillsAlways_Detail,
|
||||
),
|
||||
SettingsSwitchListTile(
|
||||
value: LocalDatabaseService.rules.mayRemoveMultiple,
|
||||
onChanged: setAllowRemoveMultiPiecesWhenCloseMultiMill,
|
||||
titleString: S.of(context).mayRemoveMultiple,
|
||||
subtitleString: S.of(context).mayRemoveMultiple_Detail,
|
||||
),
|
||||
],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
// General
|
||||
|
||||
void setNTotalPiecesEachSide() {
|
||||
Future<void> callback(int? piecesCount) async {
|
||||
debugPrint("[config] piecesCount = $piecesCount");
|
||||
|
||||
Navigator.pop(context);
|
||||
|
||||
setState(
|
||||
() => rule.piecesCount = LocalDatabaseService.rules.piecesCount =
|
||||
piecesCount ?? (specialCountryAndRegion == "Iran" ? 12 : 9),
|
||||
);
|
||||
|
||||
debugPrint("[config] rule.piecesCount: ${rule.piecesCount}");
|
||||
}
|
||||
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (BuildContext context) => Semantics(
|
||||
label: S.of(context).piecesCount,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('9'),
|
||||
groupValue: LocalDatabaseService.rules.piecesCount,
|
||||
value: 9,
|
||||
onChanged: callback,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('10'),
|
||||
groupValue: LocalDatabaseService.rules.piecesCount,
|
||||
value: 10,
|
||||
onChanged: callback,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('11'),
|
||||
groupValue: LocalDatabaseService.rules.piecesCount,
|
||||
value: 11,
|
||||
onChanged: callback,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('12'),
|
||||
groupValue: LocalDatabaseService.rules.piecesCount,
|
||||
value: 12,
|
||||
onChanged: callback,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void setNMoveRule() {
|
||||
Future<void> callback(int? nMoveRule) async {
|
||||
debugPrint("[config] nMoveRule = $nMoveRule");
|
||||
|
||||
Navigator.pop(context);
|
||||
|
||||
setState(
|
||||
() => rule.nMoveRule =
|
||||
LocalDatabaseService.rules.nMoveRule = nMoveRule ?? 100,
|
||||
);
|
||||
|
||||
debugPrint("[config] rule.nMoveRule: ${rule.nMoveRule}");
|
||||
}
|
||||
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (BuildContext context) => Semantics(
|
||||
label: S.of(context).nMoveRule,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('30'),
|
||||
groupValue: LocalDatabaseService.rules.nMoveRule,
|
||||
value: 30,
|
||||
onChanged: callback,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('50'),
|
||||
groupValue: LocalDatabaseService.rules.nMoveRule,
|
||||
value: 50,
|
||||
onChanged: callback,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('60'),
|
||||
groupValue: LocalDatabaseService.rules.nMoveRule,
|
||||
value: 60,
|
||||
onChanged: callback,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('100'),
|
||||
groupValue: LocalDatabaseService.rules.nMoveRule,
|
||||
value: 100,
|
||||
onChanged: callback,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('200'),
|
||||
groupValue: LocalDatabaseService.rules.nMoveRule,
|
||||
value: 200,
|
||||
onChanged: callback,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void setEndgameNMoveRule() {
|
||||
Future<void> callback(int? endgameNMoveRule) async {
|
||||
debugPrint("[config] endgameNMoveRule = $endgameNMoveRule");
|
||||
|
||||
Navigator.pop(context);
|
||||
|
||||
setState(
|
||||
() => rule.endgameNMoveRule = LocalDatabaseService
|
||||
.rules.endgameNMoveRule = endgameNMoveRule ?? 100,
|
||||
);
|
||||
|
||||
debugPrint("[config] rule.endgameNMoveRule: ${rule.endgameNMoveRule}");
|
||||
}
|
||||
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (BuildContext context) => Semantics(
|
||||
label: S.of(context).endgameNMoveRule,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('5'),
|
||||
groupValue: LocalDatabaseService.rules.endgameNMoveRule,
|
||||
value: 5,
|
||||
onChanged: callback,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('10'),
|
||||
groupValue: LocalDatabaseService.rules.endgameNMoveRule,
|
||||
value: 10,
|
||||
onChanged: callback,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('20'),
|
||||
groupValue: LocalDatabaseService.rules.endgameNMoveRule,
|
||||
value: 20,
|
||||
onChanged: callback,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('30'),
|
||||
groupValue: LocalDatabaseService.rules.endgameNMoveRule,
|
||||
value: 30,
|
||||
onChanged: callback,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('50'),
|
||||
groupValue: LocalDatabaseService.rules.endgameNMoveRule,
|
||||
value: 50,
|
||||
onChanged: callback,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('60'),
|
||||
groupValue: LocalDatabaseService.rules.endgameNMoveRule,
|
||||
value: 60,
|
||||
onChanged: callback,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('100'),
|
||||
groupValue: LocalDatabaseService.rules.endgameNMoveRule,
|
||||
value: 100,
|
||||
onChanged: callback,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('200'),
|
||||
groupValue: LocalDatabaseService.rules.endgameNMoveRule,
|
||||
value: 200,
|
||||
onChanged: callback,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void setFlyPieceCount() {
|
||||
Future<void> callback(int? flyPieceCount) async {
|
||||
debugPrint("[config] flyPieceCount = $flyPieceCount");
|
||||
|
||||
Navigator.pop(context);
|
||||
|
||||
setState(
|
||||
() => rule.flyPieceCount =
|
||||
LocalDatabaseService.rules.flyPieceCount = flyPieceCount ?? 3,
|
||||
);
|
||||
|
||||
debugPrint("[config] rule.flyPieceCount: ${rule.flyPieceCount}");
|
||||
}
|
||||
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (BuildContext context) => Semantics(
|
||||
label: S.of(context).flyPieceCount,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: <Widget>[
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('3'),
|
||||
groupValue: LocalDatabaseService.rules.flyPieceCount,
|
||||
value: 3,
|
||||
onChanged: callback,
|
||||
),
|
||||
RadioListTile(
|
||||
activeColor: AppTheme.switchListTileActiveColor,
|
||||
title: const Text('4'),
|
||||
groupValue: LocalDatabaseService.rules.flyPieceCount,
|
||||
value: 4,
|
||||
onChanged: callback,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> setHasDiagonalLines(bool value) async {
|
||||
setState(
|
||||
() => rule.hasDiagonalLines =
|
||||
LocalDatabaseService.rules.hasDiagonalLines = value,
|
||||
);
|
||||
|
||||
debugPrint("[config] rule.hasDiagonalLines: $value");
|
||||
}
|
||||
|
||||
Future<void> setAllowFlyingAllowed(bool value) async {
|
||||
setState(() => rule.mayFly = LocalDatabaseService.rules.mayFly = value);
|
||||
|
||||
debugPrint("[config] rule.mayFly: $value");
|
||||
}
|
||||
|
||||
Future<void> setThreefoldRepetitionRule(bool value) async {
|
||||
setState(
|
||||
() => rule.threefoldRepetitionRule =
|
||||
LocalDatabaseService.rules.threefoldRepetitionRule = value,
|
||||
);
|
||||
|
||||
debugPrint("[config] rule.threefoldRepetitionRule: $value");
|
||||
}
|
||||
|
||||
// Placing
|
||||
|
||||
Future<void> setHasBannedLocations(bool value) async {
|
||||
setState(
|
||||
() => rule.hasBannedLocations =
|
||||
LocalDatabaseService.rules.hasBannedLocations = value,
|
||||
);
|
||||
|
||||
debugPrint("[config] rule.hasBannedLocations: $value");
|
||||
}
|
||||
|
||||
Future<void> setIsWhiteLoseButNotDrawWhenBoardFull(bool value) async {
|
||||
setState(
|
||||
() => rule.isWhiteLoseButNotDrawWhenBoardFull =
|
||||
LocalDatabaseService.rules.isWhiteLoseButNotDrawWhenBoardFull = value,
|
||||
);
|
||||
|
||||
debugPrint("[config] rule.isWhiteLoseButNotDrawWhenBoardFull: $value");
|
||||
}
|
||||
|
||||
Future<void> setMayOnlyRemoveUnplacedPieceInPlacingPhase(bool value) async {
|
||||
setState(
|
||||
() => rule.mayOnlyRemoveUnplacedPieceInPlacingPhase = LocalDatabaseService
|
||||
.rules.mayOnlyRemoveUnplacedPieceInPlacingPhase = value,
|
||||
);
|
||||
|
||||
debugPrint(
|
||||
"[config] rule.mayOnlyRemoveUnplacedPieceInPlacingPhase: $value",
|
||||
);
|
||||
}
|
||||
|
||||
// Moving
|
||||
|
||||
Future<void> setMayMoveInPlacingPhase(bool value) async {
|
||||
setState(
|
||||
() => rule.mayMoveInPlacingPhase =
|
||||
LocalDatabaseService.rules.mayMoveInPlacingPhase = value,
|
||||
);
|
||||
|
||||
debugPrint("[config] rule.mayMoveInPlacingPhase: $value");
|
||||
|
||||
if (value) {
|
||||
ScaffoldMessenger.of(context).clearSnackBars();
|
||||
showSnackBar(context, S.of(context).experimental);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> setIsDefenderMoveFirst(bool value) async {
|
||||
setState(
|
||||
() => rule.isDefenderMoveFirst =
|
||||
LocalDatabaseService.rules.isDefenderMoveFirst = value,
|
||||
);
|
||||
|
||||
debugPrint("[config] rule.isDefenderMoveFirst: $value");
|
||||
}
|
||||
|
||||
Future<void> setIsLoseButNotChangeSideWhenNoWay(bool value) async {
|
||||
setState(
|
||||
() => rule.isLoseButNotChangeSideWhenNoWay =
|
||||
LocalDatabaseService.rules.isLoseButNotChangeSideWhenNoWay = value,
|
||||
);
|
||||
|
||||
debugPrint("[config] rule.isLoseButNotChangeSideWhenNoWay: $value");
|
||||
}
|
||||
|
||||
// Removing
|
||||
|
||||
Future<void> setAllowRemovePieceInMill(bool value) async {
|
||||
setState(
|
||||
() => rule.mayRemoveFromMillsAlways =
|
||||
LocalDatabaseService.rules.mayRemoveFromMillsAlways = value,
|
||||
);
|
||||
|
||||
debugPrint("[config] rule.mayRemoveFromMillsAlways: $value");
|
||||
}
|
||||
|
||||
Future<void> setAllowRemoveMultiPiecesWhenCloseMultiMill(bool value) async {
|
||||
setState(
|
||||
() => rule.mayRemoveMultiple =
|
||||
LocalDatabaseService.rules.mayRemoveMultiple = value,
|
||||
);
|
||||
|
||||
debugPrint("[config] rule.mayRemoveMultiple: $value");
|
||||
}
|
||||
|
||||
// Unused
|
||||
|
||||
Future<void> setNPiecesAtLeast(int value) async {
|
||||
setState(
|
||||
() => rule.piecesAtLeastCount =
|
||||
LocalDatabaseService.rules.piecesAtLeastCount = value,
|
||||
);
|
||||
|
||||
debugPrint("[config] rule.piecesAtLeastCount: $value");
|
||||
}
|
||||
}
|
|
@ -36,7 +36,7 @@ class EngineResponse {
|
|||
}
|
||||
|
||||
abstract class Engine {
|
||||
Future<void> setOptions(BuildContext context) async {}
|
||||
Future<void> setOptions() async {}
|
||||
Future<void> startup() async {}
|
||||
Future<void> shutdown() async {}
|
||||
Future<EngineResponse> search(Position? position);
|
||||
|
|
|
@ -102,16 +102,18 @@ class NativeEngine extends Engine {
|
|||
int sleep = 100,
|
||||
int times = 0,
|
||||
}) async {
|
||||
var timeLimit = LocalDatabaseService.preferences.developerMode ? 100 : 6000;
|
||||
final _pref = LocalDatabaseService.preferences;
|
||||
|
||||
if (LocalDatabaseService.preferences.moveTime > 0) {
|
||||
var timeLimit = _pref.developerMode ? 100 : 6000;
|
||||
|
||||
if (_pref.moveTime > 0) {
|
||||
// TODO: Accurate timeLimit
|
||||
timeLimit = LocalDatabaseService.preferences.moveTime * 10 * 64 + 10;
|
||||
timeLimit = _pref.moveTime * 10 * 64 + 10;
|
||||
}
|
||||
|
||||
if (times > timeLimit) {
|
||||
debugPrint("[engine] Timeout. sleep = $sleep, times = $times");
|
||||
if (LocalDatabaseService.preferences.developerMode && isActive) {
|
||||
if (_pref.developerMode && isActive) {
|
||||
throw "Exception: waitResponse timeout.";
|
||||
}
|
||||
return '';
|
||||
|
@ -142,78 +144,81 @@ class NativeEngine extends Engine {
|
|||
}
|
||||
|
||||
@override
|
||||
Future<void> setOptions(BuildContext context) async {
|
||||
Future<void> setOptions() async {
|
||||
final _pref = LocalDatabaseService.preferences;
|
||||
final _rules = LocalDatabaseService.rules;
|
||||
|
||||
await send(
|
||||
'setoption name DeveloperMode value ${LocalDatabaseService.preferences.developerMode}',
|
||||
'setoption name DeveloperMode value ${_pref.developerMode}',
|
||||
);
|
||||
await send(
|
||||
'setoption name Algorithm value ${LocalDatabaseService.preferences.algorithm}',
|
||||
'setoption name Algorithm value ${_pref.algorithm}',
|
||||
);
|
||||
await send(
|
||||
'setoption name DrawOnHumanExperience value ${LocalDatabaseService.preferences.drawOnHumanExperience}',
|
||||
'setoption name DrawOnHumanExperience value ${_pref.drawOnHumanExperience}',
|
||||
);
|
||||
await send(
|
||||
'setoption name ConsiderMobility value ${LocalDatabaseService.preferences.considerMobility}',
|
||||
'setoption name ConsiderMobility value ${_pref.considerMobility}',
|
||||
);
|
||||
await send(
|
||||
'setoption name SkillLevel value ${LocalDatabaseService.preferences.skillLevel}',
|
||||
'setoption name SkillLevel value ${_pref.skillLevel}',
|
||||
);
|
||||
await send(
|
||||
'setoption name MoveTime value ${LocalDatabaseService.preferences.moveTime}',
|
||||
'setoption name MoveTime value ${_pref.moveTime}',
|
||||
);
|
||||
await send(
|
||||
'setoption name AiIsLazy value ${LocalDatabaseService.preferences.aiIsLazy}',
|
||||
'setoption name AiIsLazy value ${_pref.aiIsLazy}',
|
||||
);
|
||||
await send(
|
||||
'setoption name Shuffling value ${LocalDatabaseService.preferences.shufflingEnabled}',
|
||||
'setoption name Shuffling value ${_pref.shufflingEnabled}',
|
||||
);
|
||||
await send(
|
||||
'setoption name PiecesCount value ${LocalDatabaseService.rules.piecesCount}',
|
||||
'setoption name PiecesCount value ${_rules.piecesCount}',
|
||||
);
|
||||
await send(
|
||||
'setoption name FlyPieceCount value ${LocalDatabaseService.rules.flyPieceCount}',
|
||||
'setoption name FlyPieceCount value ${_rules.flyPieceCount}',
|
||||
);
|
||||
await send(
|
||||
'setoption name PiecesAtLeastCount value ${LocalDatabaseService.rules.piecesAtLeastCount}',
|
||||
'setoption name PiecesAtLeastCount value ${_rules.piecesAtLeastCount}',
|
||||
);
|
||||
await send(
|
||||
'setoption name HasDiagonalLines value ${LocalDatabaseService.rules.hasDiagonalLines}',
|
||||
'setoption name HasDiagonalLines value ${_rules.hasDiagonalLines}',
|
||||
);
|
||||
await send(
|
||||
'setoption name HasBannedLocations value ${LocalDatabaseService.rules.hasBannedLocations}',
|
||||
'setoption name HasBannedLocations value ${_rules.hasBannedLocations}',
|
||||
);
|
||||
await send(
|
||||
'setoption name MayMoveInPlacingPhase value ${LocalDatabaseService.rules.mayMoveInPlacingPhase}',
|
||||
'setoption name MayMoveInPlacingPhase value ${_rules.mayMoveInPlacingPhase}',
|
||||
);
|
||||
await send(
|
||||
'setoption name IsDefenderMoveFirst value ${LocalDatabaseService.rules.isDefenderMoveFirst}',
|
||||
'setoption name IsDefenderMoveFirst value ${_rules.isDefenderMoveFirst}',
|
||||
);
|
||||
await send(
|
||||
'setoption name MayRemoveMultiple value ${LocalDatabaseService.rules.mayRemoveMultiple}',
|
||||
'setoption name MayRemoveMultiple value ${_rules.mayRemoveMultiple}',
|
||||
);
|
||||
await send(
|
||||
'setoption name MayRemoveFromMillsAlways value ${LocalDatabaseService.rules.mayRemoveFromMillsAlways}',
|
||||
'setoption name MayRemoveFromMillsAlways value ${_rules.mayRemoveFromMillsAlways}',
|
||||
);
|
||||
await send(
|
||||
'setoption name MayOnlyRemoveUnplacedPieceInPlacingPhase value ${LocalDatabaseService.rules.mayOnlyRemoveUnplacedPieceInPlacingPhase}',
|
||||
'setoption name MayOnlyRemoveUnplacedPieceInPlacingPhase value ${_rules.mayOnlyRemoveUnplacedPieceInPlacingPhase}',
|
||||
);
|
||||
await send(
|
||||
'setoption name IsWhiteLoseButNotDrawWhenBoardFull value ${LocalDatabaseService.rules.isWhiteLoseButNotDrawWhenBoardFull}',
|
||||
'setoption name IsWhiteLoseButNotDrawWhenBoardFull value ${_rules.isWhiteLoseButNotDrawWhenBoardFull}',
|
||||
);
|
||||
await send(
|
||||
'setoption name IsLoseButNotChangeSideWhenNoWay value ${LocalDatabaseService.rules.isLoseButNotChangeSideWhenNoWay}',
|
||||
'setoption name IsLoseButNotChangeSideWhenNoWay value ${_rules.isLoseButNotChangeSideWhenNoWay}',
|
||||
);
|
||||
await send(
|
||||
'setoption name MayFly value ${LocalDatabaseService.rules.mayFly}',
|
||||
'setoption name MayFly value ${_rules.mayFly}',
|
||||
);
|
||||
await send(
|
||||
'setoption name NMoveRule value ${LocalDatabaseService.rules.nMoveRule}',
|
||||
'setoption name NMoveRule value ${_rules.nMoveRule}',
|
||||
);
|
||||
await send(
|
||||
'setoption name EndgameNMoveRule value ${LocalDatabaseService.rules.endgameNMoveRule}',
|
||||
'setoption name EndgameNMoveRule value ${_rules.endgameNMoveRule}',
|
||||
);
|
||||
await send(
|
||||
'setoption name ThreefoldRepetitionRule value ${LocalDatabaseService.rules.threefoldRepetitionRule}',
|
||||
'setoption name ThreefoldRepetitionRule value ${_rules.threefoldRepetitionRule}',
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ import 'package:sanmill/models/preferences.dart';
|
|||
import 'package:sanmill/models/rules.dart';
|
||||
import 'package:sanmill/services/storage/adapters/color_adapter.dart';
|
||||
import 'package:sanmill/services/storage/adapters/locale_adapter.dart';
|
||||
import 'package:sanmill/services/storage/storage_v1.dart';
|
||||
|
||||
/// Helpers to handle local data storage
|
||||
class LocalDatabaseService {
|
||||
|
@ -22,7 +23,7 @@ class LocalDatabaseService {
|
|||
static late Box<ColorSettings> _colorSettingsBox;
|
||||
|
||||
/// key at wich the [ColorSettings] will be saved in the [_colorSettingsBox]
|
||||
static const String _colorSettingsKey = 'settings';
|
||||
static const String colorSettingsKey = 'settings';
|
||||
|
||||
/// key at wich the [_colorSettingsBox] will be saved
|
||||
static const String _colorSettingsBoxName = 'colors';
|
||||
|
@ -31,7 +32,7 @@ class LocalDatabaseService {
|
|||
static late Box<Display> _displayBox;
|
||||
|
||||
/// key at wich the [Display] will be saved in the [_displayBox]
|
||||
static const String _displayKey = 'settings';
|
||||
static const String displayKey = 'settings';
|
||||
|
||||
/// key at wich the [_displayBox] will be saved
|
||||
static const String _displayBoxName = 'display';
|
||||
|
@ -40,7 +41,7 @@ class LocalDatabaseService {
|
|||
static late Box<Preferences> _preferencesBox;
|
||||
|
||||
/// key at wich the [Preferences] will be saved in the [_preferencesBox]
|
||||
static const String _preferencesKey = 'settings';
|
||||
static const String preferencesKey = 'settings';
|
||||
|
||||
/// key at wich the [_preferencesBox] will be saved
|
||||
static const String _preferencesBoxName = 'preferences';
|
||||
|
@ -49,7 +50,7 @@ class LocalDatabaseService {
|
|||
static late Box<Rules> _rulesBox;
|
||||
|
||||
/// key at wich the [Rules] will be saved in the [_rulesBox]
|
||||
static const String _rulesKey = 'settings';
|
||||
static const String rulesKey = 'settings';
|
||||
|
||||
/// key at wich the [_rulesBox] will be saved
|
||||
static const String _rulesBoxName = 'rules';
|
||||
|
@ -61,63 +62,71 @@ class LocalDatabaseService {
|
|||
await _initDisplay();
|
||||
await _initPreferences();
|
||||
await _initRules();
|
||||
DatabaseV1.initRules();
|
||||
}
|
||||
|
||||
/// resets the storage
|
||||
static Future<void> resetStorage() async {
|
||||
await _colorSettingsBox.delete(colorSettingsKey);
|
||||
await _displayBox.delete(displayKey);
|
||||
await _preferencesBox.delete(preferencesKey);
|
||||
await _rulesBox.delete(rulesKey);
|
||||
}
|
||||
|
||||
/// initilizes the [ColorSettings] reference
|
||||
static Future<void> _initColorSettings() async {
|
||||
Hive.registerAdapter<ColorSettings>(ColorSettingsAdapter());
|
||||
Hive.registerAdapter<Color>(ColorAdapter());
|
||||
Hive.registerAdapter<ColorSettings>(ColorSettingsAdapter());
|
||||
_colorSettingsBox =
|
||||
await Hive.openBox<ColorSettings>(_colorSettingsBoxName);
|
||||
}
|
||||
|
||||
/// listens to changes inside the settings Box
|
||||
static ValueListenable<Box<ColorSettings>> get listenColorSettings =>
|
||||
_colorSettingsBox.listenable(keys: [_colorSettingsKey]);
|
||||
_colorSettingsBox.listenable(keys: [colorSettingsKey]);
|
||||
|
||||
/// saves the given [settings] to the settings Box
|
||||
static set colorSettings(ColorSettings settings) =>
|
||||
_colorSettingsBox.put(_colorSettingsKey, settings);
|
||||
/// saves the given [colors] to the settings Box
|
||||
static set colorSettings(ColorSettings colors) =>
|
||||
_colorSettingsBox.put(colorSettingsKey, colors);
|
||||
|
||||
/// gets the given [ColorSettings] from the settings Box
|
||||
static ColorSettings get colorSettings =>
|
||||
_colorSettingsBox.get(_colorSettingsKey) ?? ColorSettings();
|
||||
_colorSettingsBox.get(colorSettingsKey) ?? ColorSettings();
|
||||
|
||||
/// initilizes the [Display] reference
|
||||
static Future<void> _initDisplay() async {
|
||||
Hive.registerAdapter<Locale>(LocaleAdapter());
|
||||
Hive.registerAdapter<Display>(DisplayAdapter());
|
||||
_displayBox = await Hive.openBox<Display>(_displayBoxName);
|
||||
}
|
||||
|
||||
/// listens to changes inside the settings Box
|
||||
static ValueListenable<Box<Display>> get listenDisplay =>
|
||||
_displayBox.listenable(keys: [_displayKey]);
|
||||
_displayBox.listenable(keys: [displayKey]);
|
||||
|
||||
/// saves the given [settings] to the settings Box
|
||||
static set display(Display settings) =>
|
||||
_displayBox.put(_displayKey, settings);
|
||||
/// saves the given [display] to the settings Box
|
||||
static set display(Display display) => _displayBox.put(displayKey, display);
|
||||
|
||||
/// gets the given [Display] from the settings Box
|
||||
static Display get display => _displayBox.get(_displayKey) ?? Display();
|
||||
static Display get display => _displayBox.get(displayKey) ?? Display();
|
||||
|
||||
/// initilizes the [Preferences] reference
|
||||
static Future<void> _initPreferences() async {
|
||||
Hive.registerAdapter<Preferences>(PreferencesAdapter());
|
||||
Hive.registerAdapter<Locale>(LocaleAdapter());
|
||||
_preferencesBox = await Hive.openBox<Preferences>(_preferencesBoxName);
|
||||
}
|
||||
|
||||
/// listens to changes inside the settings Box
|
||||
static ValueListenable<Box<Preferences>> get listenPreferences =>
|
||||
_preferencesBox.listenable(keys: [_preferencesKey]);
|
||||
_preferencesBox.listenable(keys: [preferencesKey]);
|
||||
|
||||
/// saves the given [settings] to the settings Box
|
||||
static set preferences(Preferences settings) =>
|
||||
_preferencesBox.put(_preferencesKey, settings);
|
||||
_preferencesBox.put(preferencesKey, settings);
|
||||
|
||||
/// gets the given [Preferences] from the settings Box
|
||||
static Preferences get preferences =>
|
||||
_preferencesBox.get(_preferencesKey) ?? Preferences();
|
||||
_preferencesBox.get(preferencesKey) ?? const Preferences();
|
||||
|
||||
/// initilizes the [Rules] reference
|
||||
static Future<void> _initRules() async {
|
||||
|
@ -127,11 +136,14 @@ class LocalDatabaseService {
|
|||
|
||||
/// listens to changes inside the settings Box
|
||||
static ValueListenable<Box<Rules>> get listenRules =>
|
||||
_rulesBox.listenable(keys: [_rulesKey]);
|
||||
_rulesBox.listenable(keys: [rulesKey]);
|
||||
|
||||
/// saves the given [settings] to the settings Box
|
||||
static set rules(Rules settings) => _rulesBox.put(_rulesKey, settings);
|
||||
/// saves the given [rules] to the settings Box
|
||||
static set rules(Rules rules) {
|
||||
_rulesBox.put(rulesKey, rules);
|
||||
DatabaseV1.initRules();
|
||||
}
|
||||
|
||||
/// gets the given [Rules] from the settings Box
|
||||
static Rules get rules => _rulesBox.get(_rulesKey) ?? Rules();
|
||||
static Rules get rules => _rulesBox.get(rulesKey) ?? Rules();
|
||||
}
|
||||
|
|
|
@ -22,90 +22,96 @@ import 'dart:io';
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:sanmill/mill/rule.dart';
|
||||
import 'package:sanmill/models/color.dart';
|
||||
import 'package:sanmill/models/display.dart';
|
||||
import 'package:sanmill/models/preferences.dart';
|
||||
import 'package:sanmill/models/rules.dart';
|
||||
import 'package:sanmill/services/storage/storage.dart';
|
||||
import 'package:sanmill/shared/constants.dart';
|
||||
|
||||
@Deprecated('use [LocalDatabaseService] instead')
|
||||
class Settings {
|
||||
static final settingsFileName = Constants.settingsFilename;
|
||||
static Settings? _instance;
|
||||
class Settings {}
|
||||
|
||||
late File _file;
|
||||
Map<String, dynamic>? _values = {};
|
||||
class DatabaseV1 {
|
||||
const DatabaseV1._();
|
||||
|
||||
// TODO: add constructor
|
||||
static Future<Settings> instance() async {
|
||||
if (_instance == null) {
|
||||
_instance = Settings();
|
||||
await _instance!._load(settingsFileName);
|
||||
debugPrint("[settings] $settingsFileName loaded.");
|
||||
}
|
||||
static const _tag = "[Database Migration]";
|
||||
|
||||
return _instance!;
|
||||
}
|
||||
|
||||
dynamic operator [](String key) => _values![key];
|
||||
|
||||
void operator []=(String key, dynamic value) => _values![key] = value;
|
||||
|
||||
/// migrates the deprecated [Settings] to the new [LocalDatabaseService]
|
||||
Future<void> migrate() async {}
|
||||
|
||||
Future<bool> _load(String fileName) async {
|
||||
// TODO: main() ExternalStorage
|
||||
// var docDir = await getExternalStorageDirectory();
|
||||
static Future<File> _getFile() async {
|
||||
final fileName = Constants.settingsFilename;
|
||||
final docDir = await getApplicationDocumentsDirectory();
|
||||
|
||||
_file = File('${docDir.path}/$fileName');
|
||||
return File('${docDir.path}/$fileName');
|
||||
}
|
||||
|
||||
debugPrint("[settings] Loading $_file ...");
|
||||
/// loads the preferences from the old datastore
|
||||
static Future<Map<String, dynamic>?> _loadFile(File _file) async {
|
||||
debugPrint("$_tag Loading $_file ...");
|
||||
|
||||
try {
|
||||
final contents = await _file.readAsString();
|
||||
_values = jsonDecode(contents) as Map<String, dynamic>?;
|
||||
final _values = jsonDecode(contents) as Map<String, dynamic>?;
|
||||
debugPrint(_values.toString());
|
||||
return _values;
|
||||
} catch (e) {
|
||||
debugPrint(e.toString());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Future<void> restore() async {
|
||||
debugPrint("[settings] Restoring Settings...");
|
||||
|
||||
if (_file.existsSync()) {
|
||||
_file.deleteSync();
|
||||
debugPrint("[settings] $_file deleted");
|
||||
/// migrates the deprecated Settings to the new [LocalDatabaseService]
|
||||
static Future<void> migrateDB() async {
|
||||
final _pref = LocalDatabaseService.preferences;
|
||||
if (!_pref.usesHiveDB) {
|
||||
debugPrint("$_tag migrate DB");
|
||||
final _file = await _getFile();
|
||||
final _json = await _loadFile(_file);
|
||||
if (_json != null) {
|
||||
LocalDatabaseService.colorSettings = ColorSettings.fromJson(_json);
|
||||
LocalDatabaseService.display = Display.fromJson(_json);
|
||||
LocalDatabaseService.preferences = Preferences.fromJson(_json);
|
||||
LocalDatabaseService.rules = Rules.fromJson(_json);
|
||||
}
|
||||
await _deleteFile(_file);
|
||||
LocalDatabaseService.preferences = _pref.copyWith(usesHiveDB: true);
|
||||
} else {
|
||||
debugPrint("[settings] $_file does not exist");
|
||||
debugPrint("$_tag we allready use HiveDB. Skipping migration.");
|
||||
}
|
||||
}
|
||||
|
||||
void initRules() {
|
||||
/// deletes the old settings file
|
||||
static Future<void> _deleteFile(File _file) async {
|
||||
debugPrint("$_tag deleting Settings...");
|
||||
|
||||
if (await _file.exists()) {
|
||||
await _file.delete();
|
||||
debugPrint("$_tag $_file deleted");
|
||||
} else {
|
||||
debugPrint("$_tag $_file does not exist");
|
||||
}
|
||||
}
|
||||
|
||||
/// initializes the [Rules] object with the contents of [LocalDatabaseService.rules]
|
||||
static void initRules() {
|
||||
final _rules = LocalDatabaseService.rules;
|
||||
// Rules
|
||||
rule.piecesCount = LocalDatabaseService.rules.piecesCount;
|
||||
rule.flyPieceCount = LocalDatabaseService.rules.flyPieceCount;
|
||||
rule.piecesAtLeastCount = LocalDatabaseService.rules.piecesAtLeastCount;
|
||||
rule.hasDiagonalLines = LocalDatabaseService.rules.hasDiagonalLines;
|
||||
rule.hasBannedLocations = LocalDatabaseService.rules.hasBannedLocations;
|
||||
rule.mayMoveInPlacingPhase =
|
||||
LocalDatabaseService.rules.mayMoveInPlacingPhase;
|
||||
rule.isDefenderMoveFirst = LocalDatabaseService.rules.isDefenderMoveFirst;
|
||||
rule.mayRemoveMultiple = LocalDatabaseService.rules.mayRemoveMultiple;
|
||||
rule.mayRemoveFromMillsAlways =
|
||||
LocalDatabaseService.rules.mayRemoveFromMillsAlways;
|
||||
rule.piecesCount = _rules.piecesCount;
|
||||
rule.flyPieceCount = _rules.flyPieceCount;
|
||||
rule.piecesAtLeastCount = _rules.piecesAtLeastCount;
|
||||
rule.hasDiagonalLines = _rules.hasDiagonalLines;
|
||||
rule.hasBannedLocations = _rules.hasBannedLocations;
|
||||
rule.mayMoveInPlacingPhase = _rules.mayMoveInPlacingPhase;
|
||||
rule.isDefenderMoveFirst = _rules.isDefenderMoveFirst;
|
||||
rule.mayRemoveMultiple = _rules.mayRemoveMultiple;
|
||||
rule.mayRemoveFromMillsAlways = _rules.mayRemoveFromMillsAlways;
|
||||
rule.mayOnlyRemoveUnplacedPieceInPlacingPhase =
|
||||
LocalDatabaseService.rules.mayOnlyRemoveUnplacedPieceInPlacingPhase;
|
||||
_rules.mayOnlyRemoveUnplacedPieceInPlacingPhase;
|
||||
rule.isWhiteLoseButNotDrawWhenBoardFull =
|
||||
LocalDatabaseService.rules.isWhiteLoseButNotDrawWhenBoardFull;
|
||||
_rules.isWhiteLoseButNotDrawWhenBoardFull;
|
||||
rule.isLoseButNotChangeSideWhenNoWay =
|
||||
LocalDatabaseService.rules.isLoseButNotChangeSideWhenNoWay;
|
||||
rule.mayFly = LocalDatabaseService.rules.mayFly;
|
||||
rule.nMoveRule = LocalDatabaseService.rules.nMoveRule;
|
||||
rule.endgameNMoveRule = LocalDatabaseService.rules.endgameNMoveRule;
|
||||
rule.threefoldRepetitionRule =
|
||||
LocalDatabaseService.rules.threefoldRepetitionRule;
|
||||
_rules.isLoseButNotChangeSideWhenNoWay;
|
||||
rule.mayFly = _rules.mayFly;
|
||||
rule.nMoveRule = _rules.nMoveRule;
|
||||
rule.endgameNMoveRule = _rules.endgameNMoveRule;
|
||||
rule.threefoldRepetitionRule = _rules.threefoldRepetitionRule;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,12 +54,7 @@ void showCountdownDialog(
|
|||
builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
|
||||
debugPrint("Count down: ${snapshot.data}");
|
||||
|
||||
if (snapshot.data == 0) {
|
||||
fun();
|
||||
if (Platform.isAndroid) {
|
||||
SystemChannels.platform.invokeMethod('SystemNavigator.pop');
|
||||
} else {}
|
||||
}
|
||||
if (snapshot.data == 0) fun();
|
||||
|
||||
return SizedBox(
|
||||
height: 128,
|
||||
|
@ -71,9 +66,7 @@ void showCountdownDialog(
|
|||
),
|
||||
const SizedBox(height: 20),
|
||||
InkWell(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
onTap: () => Navigator.pop(context),
|
||||
child: Center(
|
||||
child: Text(
|
||||
S.of(ctx).cancel,
|
||||
|
|
|
@ -10,6 +10,7 @@ environment:
|
|||
dependencies:
|
||||
animated_text_kit: ^4.1.1
|
||||
catcher: ^0.6.8
|
||||
copy_with_extension: ^2.0.2
|
||||
cupertino_icons: ^1.0.3
|
||||
device_info_plus_platform_interface: ^2.1.0
|
||||
devicelocale: ^0.4.3
|
||||
|
@ -45,12 +46,13 @@ dependencies:
|
|||
|
||||
dev_dependencies:
|
||||
build_runner: ^2.1.4
|
||||
copy_with_extension_gen: ^2.0.3
|
||||
flutter_oss_licenses: ^1.0.1
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
||||
|
||||
hive_generator: ^1.1.0
|
||||
|
||||
|
||||
json_serializable: ^5.0.2
|
||||
lint: ^1.7.2
|
||||
msix: ^2.1.3
|
||||
|
|
Loading…
Reference in New Issue