diff --git a/src/ui/flutter_app/analysis_options.yaml b/src/ui/flutter_app/analysis_options.yaml index d1a1d79b..5ce91844 100644 --- a/src/ui/flutter_app/analysis_options.yaml +++ b/src/ui/flutter_app/analysis_options.yaml @@ -1,6 +1,5 @@ include: package:lint/analysis_options.yaml - linter: rules: avoid_positional_boolean_parameters: false diff --git a/src/ui/flutter_app/lib/mill/game.dart b/src/ui/flutter_app/lib/mill/game.dart index b9b0e3b0..eb28357d 100644 --- a/src/ui/flutter_app/lib/mill/game.dart +++ b/src/ui/flutter_app/lib/mill/game.dart @@ -26,14 +26,11 @@ import 'types.dart'; enum PlayerType { human, AI } Map isAi = {PieceColor.white: false, PieceColor.black: true}; -class Game { - static Game? _instance; - final String tag = "[game]"; +// TODO: add constructor +Game gameInstance = Game(); - // TODO: use constructor - static Game get instance { - return _instance ??= Game(); - } +class Game { + final String tag = "[game]"; void init() { _position = Position(); @@ -131,7 +128,7 @@ class Game { moveHistory.add(move); - sideToMove = position.sideToMove() ?? PieceColor.nobody; + sideToMove = position.sideToMove; printStat(); diff --git a/src/ui/flutter_app/lib/mill/position.dart b/src/ui/flutter_app/lib/mill/position.dart index 7a2e5fb2..8cd06f69 100644 --- a/src/ui/flutter_app/lib/mill/position.dart +++ b/src/ui/flutter_app/lib/mill/position.dart @@ -133,11 +133,9 @@ class Position { bool empty(int sq) => pieceOn(sq) == Piece.noPiece; - String sideToMove() => _sideToMove; + String get sideToMove => _sideToMove; - String movedPiece(int move) { - return pieceOn(fromSq(move)); - } + String movedPiece(int move) => pieceOn(fromSq(move)); bool movePiece(int from, int to) { if (selectPiece(from) == 0) { @@ -477,7 +475,7 @@ class Position { } if (phase == Phase.placing) { - piece = sideToMove(); + piece = sideToMove; if (pieceInHandCount[us] != null) { pieceInHandCount[us] = pieceInHandCount[us]! - 1; } @@ -526,7 +524,7 @@ class Position { } else { changeSideToMove(); } - Game.instance.focusIndex = squareToIndex[s] ?? invalidIndex; + gameInstance.focusIndex = squareToIndex[s] ?? invalidIndex; Audios.playTone(Audios.placeSoundId); } else { pieceToRemoveCount = rule.mayRemoveMultiple ? n : 1; @@ -562,7 +560,7 @@ class Position { action = Act.remove; } - Game.instance.focusIndex = squareToIndex[s] ?? invalidIndex; + gameInstance.focusIndex = squareToIndex[s] ?? invalidIndex; Audios.playTone(Audios.millSoundId); } } else if (phase == Phase.moving) { @@ -571,8 +569,7 @@ class Position { } // if illegal - if (pieceOnBoardCount[sideToMove()]! > rule.flyPieceCount || - !rule.mayFly) { + if (pieceOnBoardCount[sideToMove]! > rule.flyPieceCount || !rule.mayFly) { int md; for (md = 0; md < moveDirectionNumber; md++) { @@ -611,14 +608,14 @@ class Position { if (checkIfGameIsOver()) { return true; } else { - Game.instance.focusIndex = squareToIndex[s] ?? invalidIndex; + gameInstance.focusIndex = squareToIndex[s] ?? invalidIndex; Audios.playTone(Audios.placeSoundId); } } else { pieceToRemoveCount = rule.mayRemoveMultiple ? n : 1; updateKeyMisc(); action = Act.remove; - Game.instance.focusIndex = squareToIndex[s] ?? invalidIndex; + gameInstance.focusIndex = squareToIndex[s] ?? invalidIndex; Audios.playTone(Audios.millSoundId); } } else { @@ -636,11 +633,11 @@ class Position { if (pieceToRemoveCount <= 0) return -1; // if piece is not their - if (!(PieceColor.opponent(sideToMove()) == board[s])) return -2; + if (!(PieceColor.opponent(sideToMove) == board[s])) return -2; if (!rule.mayRemoveFromMillsAlways && potentialMillsCount(s, PieceColor.nobody) > 0 && - !isAllInMills(PieceColor.opponent(sideToMove()))) { + !isAllInMills(PieceColor.opponent(sideToMove))) { return -3; } @@ -666,7 +663,7 @@ class Position { if (pieceOnBoardCount[them]! + pieceInHandCount[them]! < rule.piecesAtLeastCount) { - setGameOver(sideToMove(), GameOverReason.loseReasonlessThanThree); + setGameOver(sideToMove, GameOverReason.loseReasonlessThanThree); return 0; } @@ -715,13 +712,13 @@ class Position { return -3; } - if (!(board[sq] == sideToMove())) { + if (!(board[sq] == sideToMove)) { return -4; } currentSquare = sq; action = Act.place; - Game.instance.blurIndex = squareToIndex[sq]!; + gameInstance.blurIndex = squareToIndex[sq]!; return 0; } @@ -808,7 +805,7 @@ class Position { if (phase == Phase.moving && action == Act.select && isAllSurrounded()) { if (rule.isLoseButNotChangeSideWhenNoWay) { setGameOver( - PieceColor.opponent(sideToMove()), + PieceColor.opponent(sideToMove), GameOverReason.loseReasonNoWay, ); return true; @@ -864,9 +861,7 @@ class Position { int updateKey(int s) { final String pieceType = colorOn(s); - st.key ^= Zobrist.psq[pieceColorIndex[pieceType]!][s]; - - return st.key; + return st.key ^= Zobrist.psq[pieceColorIndex[pieceType]!][s]; } int revertKey(int s) { @@ -890,11 +885,12 @@ class Position { int potentialMillsCount(int to, String c, {int from = 0}) { int n = 0; String locbak = Piece.noPiece; + String _c = c; assert(0 <= from && from < sqNumber); - if (c == PieceColor.nobody) { - c = colorOn(to); + if (_c == PieceColor.nobody) { + _c = colorOn(to); } if (from != 0 && from >= sqBegin && from < sqEnd) { @@ -903,7 +899,8 @@ class Position { } for (int l = 0; l < lineDirectionNumber; l++) { - if (c == board[millTable[to][l][0]] && c == board[millTable[to][l][1]]) { + if (_c == board[millTable[to][l][0]] && + _c == board[millTable[to][l][1]]) { n++; } } @@ -978,12 +975,12 @@ class Position { } // Can fly - if (pieceOnBoardCount[sideToMove()]! <= rule.flyPieceCount && rule.mayFly) { + if (pieceOnBoardCount[sideToMove]! <= rule.flyPieceCount && rule.mayFly) { return false; } for (int s = sqBegin; s < sqEnd; s++) { - if (!(sideToMove() == colorOn(s))) { + if (!(sideToMove == colorOn(s))) { continue; } @@ -1112,21 +1109,21 @@ class Position { } // Backup context - final engineTypeBackup = Game.instance.engineType; + final engineTypeBackup = gameInstance.engineType; - Game.instance.engineType = EngineType.humanVsHuman; - Game.instance.setWhoIsAi(EngineType.humanVsHuman); + gameInstance.engineType = EngineType.humanVsHuman; + gameInstance.setWhoIsAi(EngineType.humanVsHuman); final historyBack = history; - Game.instance.newGame(); + gameInstance.newGame(); if (moveIndex == -1) { errString = ""; } for (var i = 0; i <= moveIndex; i++) { - if (Game.instance.doMove(history[i].move!) == false) { + if (gameInstance.doMove(history[i].move!) == false) { errString = history[i].move!; break; } @@ -1136,8 +1133,8 @@ class Position { } // Restore context - Game.instance.engineType = engineTypeBackup; - Game.instance.setWhoIsAi(engineTypeBackup); + gameInstance.engineType = engineTypeBackup; + gameInstance.setWhoIsAi(engineTypeBackup); recorder!.history = historyBack; recorder!.cur = moveIndex; diff --git a/src/ui/flutter_app/lib/screens/about_page.dart b/src/ui/flutter_app/lib/screens/about_page.dart index 42ed09c3..905f6c65 100644 --- a/src/ui/flutter_app/lib/screens/about_page.dart +++ b/src/ui/flutter_app/lib/screens/about_page.dart @@ -294,14 +294,14 @@ class _VersionDialog extends StatelessWidget { ), TextButton( child: Text(S.of(context).ok), - onPressed: () => Navigator.of(context).pop(), + onPressed: () => Navigator.pop(context), ), ], ); } void _showFlutterVersionInfo(BuildContext context) { - Navigator.of(context).pop(); + Navigator.pop(context); showDialog( context: context, @@ -332,7 +332,7 @@ class _VersionDialog extends StatelessWidget { actions: [ TextButton( child: Text(S.of(context).ok), - onPressed: () => Navigator.of(context).pop(), + onPressed: () => Navigator.pop(context), ), ], ); diff --git a/src/ui/flutter_app/lib/screens/board.dart b/src/ui/flutter_app/lib/screens/board.dart index 6be66aa1..b01ab97c 100644 --- a/src/ui/flutter_app/lib/screens/board.dart +++ b/src/ui/flutter_app/lib/screens/board.dart @@ -26,7 +26,7 @@ import 'package:sanmill/shared/painters/board_painter.dart'; import 'package:sanmill/shared/painters/pieces_painter.dart'; import 'package:sanmill/shared/theme/app_theme.dart'; -typedef BoardTapCallback = void Function(int index); +typedef BoardTapCallback = dynamic Function(int index); class Board extends StatelessWidget { final double width; @@ -71,9 +71,9 @@ class Board extends StatelessWidget { painter: BoardPainter(width: width), foregroundPainter: PiecesPainter( width: width, - position: Game.instance.position, - focusIndex: Game.instance.focusIndex, - blurIndex: Game.instance.blurIndex, + position: gameInstance.position, + focusIndex: gameInstance.focusIndex, + blurIndex: gameInstance.blurIndex, animationValue: animationValue, ), child: grid, @@ -267,7 +267,7 @@ class Board extends StatelessWidget { if (checkPoints[i] == 0) { pieceDesc.add(S.of(context).noPoint); } else { - switch (Game.instance.position.pieceOnGrid(i)) { + switch (gameInstance.position.pieceOnGrid(i)) { case PieceColor.white: pieceDesc.add(S.of(context).whitePiece); diff --git a/src/ui/flutter_app/lib/screens/game_page.dart b/src/ui/flutter_app/lib/screens/game_page.dart index 6ed876b3..eb6ced0c 100644 --- a/src/ui/flutter_app/lib/screens/game_page.dart +++ b/src/ui/flutter_app/lib/screens/game_page.dart @@ -84,10 +84,10 @@ class _GamePageState extends State void initState() { debugPrint("$tag Engine type: ${widget.engineType}"); - Game.instance.setWhoIsAi(widget.engineType); + gameInstance.setWhoIsAi(widget.engineType); super.initState(); - Game.instance.init(); + gameInstance.init(); _engine.startup(); timer = Timer.periodic(const Duration(microseconds: 100), (Timer t) { @@ -159,7 +159,7 @@ class _GamePageState extends State return; } - final winner = Game.instance.position.winner; + final winner = gameInstance.position.winner; final Map colorWinStrings = { PieceColor.white: S.of(context).whiteWin, @@ -168,11 +168,11 @@ class _GamePageState extends State }; if (winner == PieceColor.nobody) { - if (Game.instance.position.phase == Phase.placing) { + if (gameInstance.position.phase == Phase.placing) { if (mounted) { showTip(S.of(context).tipPlace); } - } else if (Game.instance.position.phase == Phase.moving) { + } else if (gameInstance.position.phase == Phase.moving) { if (mounted) { showTip(S.of(context).tipMove); } @@ -199,13 +199,13 @@ class _GamePageState extends State Duration(milliseconds: (Config.animationDuration * 1000).toInt()); _animationController.reset(); - if (Game.instance.engineType == EngineType.aiVsAi || - Game.instance.engineType == EngineType.testViaLAN) { + if (gameInstance.engineType == EngineType.aiVsAi || + gameInstance.engineType == EngineType.testViaLAN) { debugPrint("$tag Engine type is no human, ignore tapping."); return false; } - final position = Game.instance.position; + final position = gameInstance.position; final int? sq = indexToSquare[index]; @@ -221,10 +221,10 @@ class _GamePageState extends State if (position.phase == Phase.placing && position.pieceOnBoardCount[PieceColor.white] == 0 && position.pieceOnBoardCount[PieceColor.black] == 0) { - Game.instance.newGame(); + gameInstance.newGame(); - if (Game.instance.isAiToMove()!) { - if (Game.instance.aiIsSearching()) { + if (gameInstance.isAiToMove()!) { + if (gameInstance.aiIsSearching()) { debugPrint("$tag AI is thinking, skip tapping."); return false; } else { @@ -235,13 +235,13 @@ class _GamePageState extends State } } - if (Game.instance.isAiToMove()! || Game.instance.aiIsSearching()) { + if (gameInstance.isAiToMove()! || gameInstance.aiIsSearching()) { debugPrint("[tap] AI's turn, skip tapping."); return false; } if (position.phase == Phase.ready) { - Game.instance.start(); + gameInstance.start(); } // Human to go @@ -261,7 +261,7 @@ class _GamePageState extends State } } else { //Audios.playTone(Audios.placeSoundId); - if (Game.instance.engineType == EngineType.humanVsAi && mounted) { + if (gameInstance.engineType == EngineType.humanVsAi && mounted) { if (rule.mayOnlyRemoveUnplacedPieceInPlacingPhase) { showTip(S.of(context).continueToMakeMove); } else { @@ -273,7 +273,7 @@ class _GamePageState extends State S.of(context).tipPlaced, ); // TODO: HumanVsHuman - Change tip } else { - final side = Game.instance.sideToMove == PieceColor.white + final side = gameInstance.sideToMove == PieceColor.white ? S.of(context).black : S.of(context).white; showTip(side + S.of(context).tipToMove); @@ -313,16 +313,16 @@ class _GamePageState extends State switch (selectRet) { case 0: Audios.playTone(Audios.selectSoundId); - Game.instance.select(index); + gameInstance.select(index); ret = true; debugPrint("[tap] selectPiece: [$sq]"); - final us = Game.instance.sideToMove; + final us = gameInstance.sideToMove; if (position.phase == Phase.moving && rule.mayFly && - (Game.instance.position.pieceOnBoardCount[us] == + (gameInstance.position.pieceOnBoardCount[us] == Config.flyPieceCount || - Game.instance.position.pieceOnBoardCount[us] == 3)) { + gameInstance.position.pieceOnBoardCount[us] == 3)) { debugPrint("[tap] May fly."); if (mounted) { showTip(S.of(context).tipCanMoveToAnyPoint); @@ -395,7 +395,7 @@ class _GamePageState extends State //Audios.playTone(Audios.removeSoundId); ret = true; debugPrint("[tap] removePiece: [$sq]"); - if (Game.instance.position.pieceToRemoveCount >= 1) { + if (gameInstance.position.pieceToRemoveCount >= 1) { if (mounted) { showTip(S.of(context).tipContinueMill); if (Config.screenReaderSupport) { @@ -403,13 +403,13 @@ class _GamePageState extends State } } } else { - if (Game.instance.engineType == EngineType.humanVsAi) { + if (gameInstance.engineType == EngineType.humanVsAi) { if (mounted) { showTip(S.of(context).tipRemoved); } } else { if (mounted) { - final them = Game.instance.sideToMove == PieceColor.white + final them = gameInstance.sideToMove == PieceColor.white ? S.of(context).black : S.of(context).white; if (mounted) { @@ -466,8 +466,8 @@ class _GamePageState extends State } if (ret) { - Game.instance.sideToMove = position.sideToMove() ?? PieceColor.nobody; - Game.instance.moveHistory.add(position.record!); + gameInstance.sideToMove = position.sideToMove; + gameInstance.moveHistory.add(position.record!); // TODO: Need Others? // Increment ply counters. In particular, @@ -514,7 +514,7 @@ class _GamePageState extends State } } - Game.instance.sideToMove = position.sideToMove() ?? PieceColor.nobody; + gameInstance.sideToMove = position.sideToMove; setState(() {}); }); // Chain.capture @@ -523,6 +523,8 @@ class _GamePageState extends State } Future engineToGo(bool isMoveNow) async { + bool _isMoveNow = isMoveNow; + if (!mounted) { debugPrint("[engineToGo] !mounted, skip engineToGo."); return; @@ -531,14 +533,14 @@ class _GamePageState extends State // TODO debugPrint("[engineToGo] engine type is ${widget.engineType}"); - if (isMoveNow == true) { - if (!Game.instance.isAiToMove()!) { + if (_isMoveNow) { + if (!gameInstance.isAiToMove()!) { debugPrint("[engineToGo] Human to Move. Cannot get search result now."); ScaffoldMessenger.of(context).clearSnackBars(); showSnackBar(context, S.of(context).notAIsTurn); return; } - if (!Game.instance.position.recorder!.isClean()) { + if (!gameInstance.position.recorder!.isClean()) { debugPrint( "[engineToGo] History is not clean. Cannot get search result now.", ); @@ -549,22 +551,22 @@ class _GamePageState extends State } while ((Config.isAutoRestart == true || - Game.instance.position.winner == PieceColor.nobody) && - Game.instance.isAiToMove()! && + gameInstance.position.winner == PieceColor.nobody) && + gameInstance.isAiToMove()! && mounted) { if (widget.engineType == EngineType.aiVsAi) { final String score = - "${Game.instance.position.score[PieceColor.white]} : ${Game.instance.position.score[PieceColor.black]} : ${Game.instance.position.score[PieceColor.draw]}"; + "${gameInstance.position.score[PieceColor.white]} : ${gameInstance.position.score[PieceColor.black]} : ${gameInstance.position.score[PieceColor.draw]}"; showTip(score); } else { if (mounted) { showTip(S.of(context).thinking); - final Move? m = Game.instance.position.recorder!.lastMove; + final Move? m = gameInstance.position.recorder!.lastMove; if (Config.screenReaderSupport && - Game.instance.position.action != Act.remove && + gameInstance.position.action != Act.remove && m != null && m.notation != null) { showSnackBar(context, "${S.of(context).human}: ${m.notation!}"); @@ -574,13 +576,13 @@ class _GamePageState extends State late EngineResponse response; - if (!isMoveNow) { + if (!_isMoveNow) { debugPrint("[engineToGo] Searching..."); - response = await _engine.search(Game.instance.position); + response = await _engine.search(gameInstance.position); } else { debugPrint("[engineToGo] Get search result now..."); response = await _engine.search(null); - isMoveNow = false; + _isMoveNow = false; } debugPrint("[engineToGo] Engine response type: ${response.type}"); @@ -601,7 +603,7 @@ class _GamePageState extends State ); } - Game.instance.doMove(move.move!); + gameInstance.doMove(move.move!); showTips(); if (Config.screenReaderSupport && move.notation != null) { showSnackBar(context, "${S.of(context).ai}: ${move.notation!}"); @@ -625,22 +627,22 @@ class _GamePageState extends State } if (Config.isAutoRestart == true && - Game.instance.position.winner != PieceColor.nobody) { - Game.instance.newGame(); + gameInstance.position.winner != PieceColor.nobody) { + gameInstance.newGame(); } } } Future onStartNewGameButtonPressed() async { - Navigator.of(context).pop(); + Navigator.pop(context); - if (Game.instance.isAiToMove()!) { + if (gameInstance.isAiToMove()!) { // TODO: Move now //debugPrint("$tag New game, AI to move, move now."); //await engineToGo(true); } - Game.instance.newGame(); + gameInstance.newGame(); if (mounted) { showTip(S.of(context).gameStarted); @@ -650,14 +652,14 @@ class _GamePageState extends State } } - if (Game.instance.isAiToMove()!) { + if (gameInstance.isAiToMove()!) { debugPrint("$tag New game, AI to move."); engineToGo(false); } } Future onImportGameButtonPressed() async { - Navigator.of(context).pop(); + Navigator.pop(context); ScaffoldMessenger.of(context).clearSnackBars(); final ClipboardData? data = await Clipboard.getData(Clipboard.kTextPlain); @@ -672,8 +674,8 @@ class _GamePageState extends State debugPrint(text); await onTakeBackAllButtonPressed(pop: false); - Game.instance.position.recorder!.clear(); - final importFailedStr = Game.instance.position.recorder!.import(text); + gameInstance.position.recorder!.clear(); + final importFailedStr = gameInstance.position.recorder!.import(text); if (importFailedStr != "") { showTip("${S.of(context).cannotImport} $importFailedStr"); @@ -694,9 +696,9 @@ class _GamePageState extends State } Future onExportGameButtonPressed() async { - Navigator.of(context).pop(); + Navigator.pop(context); - final moveHistoryText = Game.instance.position.moveHistoryText; + final moveHistoryText = gameInstance.position.moveHistoryText; Clipboard.setData(ClipboardData(text: moveHistoryText)).then((_) { showSnackBar(context, S.of(context).moveHistoryCopied); @@ -705,7 +707,7 @@ class _GamePageState extends State /* onStartRecordingButtonPressed() async { - Navigator.of(context).pop(); + Navigator.pop(context); showDialog( context: context, barrierDismissible: true, @@ -737,7 +739,7 @@ class _GamePageState extends State fontSize: Config.fontSize, ), ), - onPressed: () => Navigator.of(context).pop(), + onPressed: () => Navigator.pop(context), ), ], ), @@ -751,7 +753,7 @@ class _GamePageState extends State } onStopRecordingButtonPressed() async { - Navigator.of(context).pop(); + Navigator.pop(context); screenRecorderController.stop(); showSnackBar( S.of(context).stopRecording, @@ -760,7 +762,7 @@ class _GamePageState extends State } onShowRecordingButtonPressed() async { - Navigator.of(context).pop(); + Navigator.pop(context); showSnackBar( S.of(context).pleaseWait, duration: Duration(seconds: 1 << 31), @@ -786,7 +788,7 @@ class _GamePageState extends State */ Future onAutoReplayButtonPressed() async { - Navigator.of(context).pop(); + Navigator.pop(context); await onTakeBackAllButtonPressed(pop: false); await onStepForwardAllButtonPressed(pop: false); @@ -836,10 +838,8 @@ class _GamePageState extends State style: AppTheme.simpleDialogOptionTextStyle, textAlign: TextAlign.center, ), - onPressed: () => Navigator.of(context).pop(), - ) - else - const SizedBox(height: 1), + onPressed: () => Navigator.pop(context), + ), /* SizedBox(height: AppTheme.sizedBoxHeight), Config.experimentsEnabled @@ -912,9 +912,7 @@ class _GamePageState extends State child: SimpleDialog( backgroundColor: Colors.transparent, children: [ - if (Config.isHistoryNavigationToolbarShown) - const SizedBox(height: 1) - else + if (!Config.isHistoryNavigationToolbarShown) SimpleDialogOption( onPressed: onTakeBackButtonPressed, child: Text( @@ -923,13 +921,9 @@ class _GamePageState extends State textAlign: TextAlign.center, ), ), - if (Config.isHistoryNavigationToolbarShown) - const SizedBox(height: 1) - else + if (!Config.isHistoryNavigationToolbarShown) const SizedBox(height: AppTheme.sizedBoxHeight), - if (Config.isHistoryNavigationToolbarShown) - const SizedBox(height: 1) - else + if (!Config.isHistoryNavigationToolbarShown) SimpleDialogOption( onPressed: onStepForwardButtonPressed, child: Text( @@ -938,13 +932,9 @@ class _GamePageState extends State textAlign: TextAlign.center, ), ), - if (Config.isHistoryNavigationToolbarShown) - const SizedBox(height: 1) - else + if (!Config.isHistoryNavigationToolbarShown) const SizedBox(height: AppTheme.sizedBoxHeight), - if (Config.isHistoryNavigationToolbarShown) - const SizedBox(height: 1) - else + if (!Config.isHistoryNavigationToolbarShown) SimpleDialogOption( onPressed: onTakeBackAllButtonPressed, child: Text( @@ -953,13 +943,9 @@ class _GamePageState extends State textAlign: TextAlign.center, ), ), - if (Config.isHistoryNavigationToolbarShown) - const SizedBox(height: 1) - else + if (!Config.isHistoryNavigationToolbarShown) const SizedBox(height: AppTheme.sizedBoxHeight), - if (Config.isHistoryNavigationToolbarShown) - const SizedBox(height: 1) - else + if (!Config.isHistoryNavigationToolbarShown) SimpleDialogOption( onPressed: onStepForwardAllButtonPressed, child: Text( @@ -968,9 +954,7 @@ class _GamePageState extends State textAlign: TextAlign.center, ), ), - if (Config.isHistoryNavigationToolbarShown) - const SizedBox(height: 1) - else + if (!Config.isHistoryNavigationToolbarShown) const SizedBox(height: AppTheme.sizedBoxHeight), SimpleDialogOption( onPressed: onMoveListButtonPressed, @@ -997,10 +981,8 @@ class _GamePageState extends State style: AppTheme.simpleDialogOptionTextStyle, textAlign: TextAlign.center, ), - onPressed: () => Navigator.of(context).pop(), - ) - else - const SizedBox(height: 1), + onPressed: () => Navigator.pop(context), + ), ], ), ), @@ -1012,7 +994,7 @@ class _GamePageState extends State bool pop = true, }) async { if (pop == true) { - Navigator.of(context).pop(); + Navigator.pop(context); } if (mounted) { @@ -1053,7 +1035,7 @@ class _GamePageState extends State if (mounted) { String text = ""; - final pos = Game.instance.position; + final pos = gameInstance.position; /* String us = ""; @@ -1084,32 +1066,32 @@ class _GamePageState extends State } Future onTakeBackButtonPressed({bool pop = true}) async { - onGotoHistoryButtonsPressed(Game.instance.position.takeBack(), pop: pop); + onGotoHistoryButtonsPressed(gameInstance.position.takeBack(), pop: pop); } Future onStepForwardButtonPressed({bool pop = true}) async { - onGotoHistoryButtonsPressed(Game.instance.position.stepForward(), pop: pop); + onGotoHistoryButtonsPressed(gameInstance.position.stepForward(), pop: pop); } Future onTakeBackAllButtonPressed({bool pop = true}) async { - onGotoHistoryButtonsPressed(Game.instance.position.takeBackAll(), pop: pop); + onGotoHistoryButtonsPressed(gameInstance.position.takeBackAll(), pop: pop); } Future onStepForwardAllButtonPressed({bool pop = true}) async { onGotoHistoryButtonsPressed( - Game.instance.position.stepForwardAll(), + gameInstance.position.stepForwardAll(), pop: pop, ); } Future onTakeBackNButtonPressed(int n, {bool pop = true}) async { - onGotoHistoryButtonsPressed(Game.instance.position.takeBackN(n), pop: pop); + onGotoHistoryButtonsPressed(gameInstance.position.takeBackN(n), pop: pop); } void onMoveListButtonPressed() { - final moveHistoryText = Game.instance.position.moveHistoryText; - final end = Game.instance.moveHistory.length - 1; - Navigator.of(context).pop(); + final moveHistoryText = gameInstance.position.moveHistoryText; + final end = gameInstance.moveHistory.length - 1; + Navigator.pop(context); ScaffoldMessenger.of(context).clearSnackBars(); showDialog( @@ -1156,7 +1138,7 @@ class _GamePageState extends State else TextButton( child: const Text(""), - onPressed: () => Navigator.of(context).pop(), + onPressed: () => Navigator.pop(context), ), TextButton( child: Text( @@ -1175,7 +1157,7 @@ class _GamePageState extends State S.of(context).cancel, style: AppTheme.moveHistoryTextStyle, ), - onPressed: () => Navigator.of(context).pop(), + onPressed: () => Navigator.pop(context), ), ], ); @@ -1184,7 +1166,7 @@ class _GamePageState extends State } Future onMoveNowButtonPressed() async { - Navigator.of(context).pop(); + Navigator.pop(context); await engineToGo(true); } @@ -1203,7 +1185,7 @@ class _GamePageState extends State TextButton( child: Text(S.of(context).ok, style: AppTheme.moveHistoryTextStyle), - onPressed: () => Navigator.of(context).pop(), + onPressed: () => Navigator.pop(context), ), ], ); @@ -1212,9 +1194,7 @@ class _GamePageState extends State } Future setPrivacyPolicyAccepted(bool value) async { - setState(() { - Config.isPrivacyPolicyAccepted = value; - }); + setState(() => Config.isPrivacyPolicyAccepted = value); debugPrint("[config] isPrivacyPolicyAccepted: $value"); @@ -1250,10 +1230,10 @@ class _GamePageState extends State }; debugPrint( - "$tag Game over reason: ${Game.instance.position.gameOverReason}", + "$tag Game over reason: ${gameInstance.position.gameOverReason}", ); - String? loseReasonStr = reasonMap[Game.instance.position.gameOverReason]; + String? loseReasonStr = reasonMap[gameInstance.position.gameOverReason]; if (loseReasonStr == null) { loseReasonStr = S.of(context).gameOverUnknownReason; @@ -1296,7 +1276,7 @@ class _GamePageState extends State void showGameResult(String winner) { final GameResult result = getGameResult(winner); - Game.instance.position.result = result; + gameInstance.position.result = result; switch (result) { case GameResult.win: @@ -1312,7 +1292,7 @@ class _GamePageState extends State } final Map retMap = { - GameResult.win: Game.instance.engineType == EngineType.humanVsAi + GameResult.win: gameInstance.engineType == EngineType.humanVsAi ? S.of(context).youWin : S.of(context).gameOver, GameResult.lose: S.of(context).gameOver, @@ -1329,10 +1309,10 @@ class _GamePageState extends State if (result == GameResult.win && !isTopLevel && - Game.instance.engineType == EngineType.humanVsAi) { + gameInstance.engineType == EngineType.humanVsAi) { var contentStr = getGameOverReasonString( - Game.instance.position.gameOverReason, - Game.instance.position.winner, + gameInstance.position.gameOverReason, + gameInstance.position.winner, ); if (!isTopLevel) { @@ -1371,7 +1351,7 @@ class _GamePageState extends State Config.save(); await _engine.setOptions(context); debugPrint("[config] skillLevel: ${Config.skillLevel}"); - Navigator.of(context).pop(); + Navigator.pop(context); }, ), TextButton( @@ -1381,7 +1361,7 @@ class _GamePageState extends State fontSize: Config.fontSize, ), ), - onPressed: () => Navigator.of(context).pop(), + onPressed: () => Navigator.pop(context), ), ], ); @@ -1402,8 +1382,8 @@ class _GamePageState extends State ), content: Text( getGameOverReasonString( - Game.instance.position.gameOverReason, - Game.instance.position.winner, + gameInstance.position.gameOverReason, + gameInstance.position.winner, ), style: TextStyle( fontSize: Config.fontSize, @@ -1418,8 +1398,8 @@ class _GamePageState extends State ), ), onPressed: () { - Navigator.of(context).pop(); - Game.instance.newGame(); + Navigator.pop(context); + gameInstance.newGame(); if (mounted) { showTip(S.of(context).gameStarted); if (Config.screenReaderSupport) { @@ -1428,7 +1408,7 @@ class _GamePageState extends State } } - if (Game.instance.isAiToMove()!) { + if (gameInstance.isAiToMove()!) { debugPrint("$tag New game, AI to move."); engineToGo(false); } @@ -1441,7 +1421,7 @@ class _GamePageState extends State fontSize: Config.fontSize, ), ), - onPressed: () => Navigator.of(context).pop(), + onPressed: () => Navigator.pop(context), ), ], ); @@ -1534,8 +1514,8 @@ class _GamePageState extends State IconData getIconArrow() { IconData iconArrow = FluentIcons.code_24_regular; - if (Game.instance.position.phase == Phase.gameOver) { - switch (Game.instance.position.winner) { + if (gameInstance.position.phase == Phase.gameOver) { + switch (gameInstance.position.winner) { case PieceColor.white: iconArrow = ltr ? FluentIcons.toggle_left_24_regular @@ -1551,7 +1531,7 @@ class _GamePageState extends State break; } } else { - switch (Game.instance.sideToMove) { + switch (gameInstance.sideToMove) { case PieceColor.white: iconArrow = FluentIcons.chevron_left_24_regular; break; @@ -1589,7 +1569,7 @@ class _GamePageState extends State final String period = Config.screenReaderSupport ? "." : ""; final String comma = Config.screenReaderSupport ? "," : ""; - final pos = Game.instance.position; + final pos = gameInstance.position; switch (pos.phase) { case Phase.placing: @@ -1870,11 +1850,7 @@ class _GamePageState extends State children: [ BlockSemantics(child: header), board, - if (Config.isHistoryNavigationToolbarShown) - historyNavToolbar - else - const SizedBox(height: 0), - const SizedBox(height: 1), + if (Config.isHistoryNavigationToolbarShown) historyNavToolbar, toolbar, ], ), diff --git a/src/ui/flutter_app/lib/screens/game_settings_page.dart b/src/ui/flutter_app/lib/screens/game_settings_page.dart index 5d734ac8..0092b4e2 100644 --- a/src/ui/flutter_app/lib/screens/game_settings_page.dart +++ b/src/ui/flutter_app/lib/screens/game_settings_page.dart @@ -30,7 +30,6 @@ import 'package:sanmill/shared/theme/app_theme.dart'; import '../shared/dialog.dart'; import 'env_page.dart'; -import 'list_item_divider.dart'; class Developer { const Developer._(); @@ -109,7 +108,7 @@ class _GameSettingsPageState extends State { Future restoreFactoryDefaultSettings() async { Future confirm() async { - Navigator.of(context).pop(); + Navigator.pop(context); if (Platform.isAndroid) { showCountdownDialog(context, 10, _events, _restore); } else { @@ -121,7 +120,7 @@ class _GameSettingsPageState extends State { } } - void cancel() => Navigator.of(context).pop(); + void cancel() => Navigator.pop(context); var prompt = ""; @@ -216,7 +215,6 @@ class _GameSettingsPageState extends State { //trailingString: "L" + Config.skillLevel.toString(), onTap: setSkillLevel, ), - const ListItemDivider(), SettingsListTile( titleString: S.of(context).moveTime, onTap: setMoveTime, @@ -233,28 +231,24 @@ class _GameSettingsPageState extends State { trailingString: algorithmNames[Config.algorithm], onTap: setAlgorithm, ), - const ListItemDivider(), SettingsSwitchListTile( context: context, value: Config.drawOnHumanExperience, onChanged: setDrawOnHumanExperience, titleString: S.of(context).drawOnHumanExperience, ), - const ListItemDivider(), SettingsSwitchListTile( context: context, value: Config.considerMobility, onChanged: setConsiderMobility, titleString: S.of(context).considerMobility, ), - const ListItemDivider(), SettingsSwitchListTile( context: context, value: Config.aiIsLazy, onChanged: setAiIsLazy, titleString: S.of(context).passive, ), - const ListItemDivider(), SettingsSwitchListTile( context: context, value: Config.shufflingEnabled, @@ -281,7 +275,6 @@ class _GameSettingsPageState extends State { onChanged: setTone, titleString: S.of(context).playSoundsInTheGame, ), - const ListItemDivider(), SettingsSwitchListTile( context: context, value: Config.keepMuteWhenTakingBack, @@ -314,7 +307,6 @@ class _GameSettingsPageState extends State { titleString: S.of(context).restoreDefaultSettings, onTap: restoreFactoryDefaultSettings, ), - const ListItemDivider(), ], ), const SizedBox(height: AppTheme.sizedBoxHeight), @@ -322,9 +314,7 @@ class _GameSettingsPageState extends State { Text( S.of(context).forDevelopers, style: AppTheme.settingsHeaderStyle, - ) - else - const SizedBox(height: 1), + ), if (Developer.developerModeEnabled) SettingsCard( context: context, @@ -335,21 +325,18 @@ class _GameSettingsPageState extends State { onChanged: setDeveloperMode, titleString: S.of(context).developerMode, ), - const ListItemDivider(), SettingsSwitchListTile( context: context, value: Config.experimentsEnabled, onChanged: setExperimentsEnabled, titleString: S.of(context).experiments, ), - const ListItemDivider(), SettingsSwitchListTile( context: context, value: Config.isAutoRestart, onChanged: setIsAutoRestart, titleString: S.of(context).isAutoRestart, ), - const ListItemDivider(), SettingsListTile( titleString: S.of(context).environmentVariables, onTap: () { @@ -362,9 +349,7 @@ class _GameSettingsPageState extends State { }, ), ], - ) - else - const SizedBox(height: 1), + ), ]; } @@ -387,9 +372,7 @@ class _GameSettingsPageState extends State { } Future setWhoMovesFirst(bool value) async { - setState(() { - Config.aiMovesFirst = !value; - }); + setState(() => Config.aiMovesFirst = !value); debugPrint("[config] aiMovesFirst: ${Config.aiMovesFirst}"); @@ -397,9 +380,7 @@ class _GameSettingsPageState extends State { } Future setAiIsLazy(bool value) async { - setState(() { - Config.aiIsLazy = value; - }); + setState(() => Config.aiIsLazy = value); debugPrint("[config] aiMovesFirst: $value"); @@ -410,11 +391,9 @@ class _GameSettingsPageState extends State { Future callback(int? algorithm) async { debugPrint("[config] algorithm = $algorithm"); - Navigator.of(context).pop(); + Navigator.pop(context); - setState(() { - Config.algorithm = algorithm ?? 2; - }); + setState(() => Config.algorithm = algorithm ?? 2); debugPrint("[config] Config.algorithm: ${Config.algorithm}"); @@ -435,7 +414,6 @@ class _GameSettingsPageState extends State { value: 0, onChanged: callback, ), - const ListItemDivider(), RadioListTile( activeColor: AppTheme.switchListTileActiveColor, title: const Text('PVS'), @@ -443,7 +421,6 @@ class _GameSettingsPageState extends State { value: 1, onChanged: callback, ), - const ListItemDivider(), RadioListTile( activeColor: AppTheme.switchListTileActiveColor, title: const Text('MTD(f)'), @@ -451,7 +428,6 @@ class _GameSettingsPageState extends State { value: 2, onChanged: callback, ), - const ListItemDivider(), ], ), ), @@ -459,9 +435,7 @@ class _GameSettingsPageState extends State { } Future setDrawOnHumanExperience(bool value) async { - setState(() { - Config.drawOnHumanExperience = value; - }); + setState(() => Config.drawOnHumanExperience = value); debugPrint("[config] drawOnHumanExperience: $value"); @@ -469,9 +443,7 @@ class _GameSettingsPageState extends State { } Future setConsiderMobility(bool value) async { - setState(() { - Config.considerMobility = value; - }); + setState(() => Config.considerMobility = value); debugPrint("[config] considerMobility: $value"); @@ -479,9 +451,7 @@ class _GameSettingsPageState extends State { } Future setIsAutoRestart(bool value) async { - setState(() { - Config.isAutoRestart = value; - }); + setState(() => Config.isAutoRestart = value); debugPrint("[config] isAutoRestart: $value"); @@ -489,9 +459,7 @@ class _GameSettingsPageState extends State { } Future setIsAutoChangeFirstMove(bool value) async { - setState(() { - Config.isAutoChangeFirstMove = value; - }); + setState(() => Config.isAutoChangeFirstMove = value); debugPrint("[config] isAutoChangeFirstMove: $value"); @@ -499,9 +467,7 @@ class _GameSettingsPageState extends State { } Future setResignIfMostLose(bool value) async { - setState(() { - Config.resignIfMostLose = value; - }); + setState(() => Config.resignIfMostLose = value); debugPrint("[config] resignIfMostLose: $value"); @@ -509,9 +475,7 @@ class _GameSettingsPageState extends State { } Future setShufflingEnabled(bool value) async { - setState(() { - Config.shufflingEnabled = value; - }); + setState(() => Config.shufflingEnabled = value); debugPrint("[config] shufflingEnabled: $value"); @@ -519,9 +483,7 @@ class _GameSettingsPageState extends State { } Future setLearnEndgame(bool value) async { - setState(() { - Config.learnEndgame = value; - }); + setState(() => Config.learnEndgame = value); debugPrint("[config] learnEndgame: $value"); @@ -529,9 +491,7 @@ class _GameSettingsPageState extends State { } Future setOpeningBook(bool value) async { - setState(() { - Config.openingBook = value; - }); + setState(() => Config.openingBook = value); debugPrint("[config] openingBook: $value"); @@ -539,9 +499,7 @@ class _GameSettingsPageState extends State { } Future setTone(bool value) async { - setState(() { - Config.toneEnabled = value; - }); + setState(() => Config.toneEnabled = value); debugPrint("[config] toneEnabled: $value"); @@ -549,9 +507,7 @@ class _GameSettingsPageState extends State { } Future setKeepMuteWhenTakingBack(bool value) async { - setState(() { - Config.keepMuteWhenTakingBack = value; - }); + setState(() => Config.keepMuteWhenTakingBack = value); debugPrint("[config] keepMuteWhenTakingBack: $value"); @@ -559,9 +515,7 @@ class _GameSettingsPageState extends State { } Future setScreenReaderSupport(bool value) async { - setState(() { - Config.screenReaderSupport = value; - }); + setState(() => Config.screenReaderSupport = value); debugPrint("[config] screenReaderSupport: $value"); @@ -569,9 +523,7 @@ class _GameSettingsPageState extends State { } Future setDeveloperMode(bool value) async { - setState(() { - Config.developerMode = value; - }); + setState(() => Config.developerMode = value); debugPrint("[config] developerMode: $value"); @@ -579,9 +531,7 @@ class _GameSettingsPageState extends State { } Future setExperimentsEnabled(bool value) async { - setState(() { - Config.experimentsEnabled = value; - }); + setState(() => Config.experimentsEnabled = value); debugPrint("[config] experimentsEnabled: $value"); @@ -591,9 +541,7 @@ class _GameSettingsPageState extends State { // Display Future setLanguage(String value) async { - setState(() { - Config.languageCode = value; - }); + setState(() => Config.languageCode = value); debugPrint("[config] languageCode: $value"); @@ -601,9 +549,7 @@ class _GameSettingsPageState extends State { } Future setIsPieceCountInHandShown(bool value) async { - setState(() { - Config.isPieceCountInHandShown = value; - }); + setState(() => Config.isPieceCountInHandShown = value); debugPrint("[config] isPieceCountInHandShown: $value"); @@ -611,9 +557,7 @@ class _GameSettingsPageState extends State { } Future setIsNotationsShown(bool value) async { - setState(() { - Config.isNotationsShown = value; - }); + setState(() => Config.isNotationsShown = value); debugPrint("[config] isNotationsShown: $value"); @@ -621,9 +565,7 @@ class _GameSettingsPageState extends State { } Future setIsHistoryNavigationToolbarShown(bool value) async { - setState(() { - Config.isHistoryNavigationToolbarShown = value; - }); + setState(() => Config.isHistoryNavigationToolbarShown = value); debugPrint("[config] isHistoryNavigationToolbarShown: $value"); @@ -631,9 +573,7 @@ class _GameSettingsPageState extends State { } Future setStandardNotationEnabled(bool value) async { - setState(() { - Config.standardNotationEnabled = value; - }); + setState(() => Config.standardNotationEnabled = value); debugPrint("[config] standardNotationEnabled: $value"); diff --git a/src/ui/flutter_app/lib/screens/home_drawer.dart b/src/ui/flutter_app/lib/screens/home_drawer.dart index 9334a960..4c3fecdf 100644 --- a/src/ui/flutter_app/lib/screens/home_drawer.dart +++ b/src/ui/flutter_app/lib/screens/home_drawer.dart @@ -301,7 +301,7 @@ class HomeDrawer extends StatelessWidget { padding: const EdgeInsets.symmetric(vertical: 8.0), child: Row( children: [ - const SizedBox(width: 6.0, height: 46.0), + const SizedBox(height: 46.0, width: 6.0), const Padding( padding: EdgeInsets.all(4.0), ), diff --git a/src/ui/flutter_app/lib/screens/navigation_home_screen.dart b/src/ui/flutter_app/lib/screens/navigation_home_screen.dart index 917e3c91..242225b3 100644 --- a/src/ui/flutter_app/lib/screens/navigation_home_screen.dart +++ b/src/ui/flutter_app/lib/screens/navigation_home_screen.dart @@ -89,25 +89,17 @@ class _NavigationHomeScreenState extends State { // TODO: use switch case final engineType = drawerMap[drawerIndex!]; - if (engineType != null) { - setState(() { - Game.instance.setWhoIsAi(engineType); + setState(() { + if (engineType != null) { + gameInstance.setWhoIsAi(engineType); screenView = GamePage(engineType); - }); - } else if (drawerIndex == DrawerIndex.preferences) { - setState(() { + } else if (drawerIndex == DrawerIndex.preferences) { screenView = GameSettingsPage(); - }); - } else if (drawerIndex == DrawerIndex.ruleSettings) { - setState(() { + } else if (drawerIndex == DrawerIndex.ruleSettings) { screenView = RuleSettingsPage(); - }); - } else if (drawerIndex == DrawerIndex.personalization) { - setState(() { + } else if (drawerIndex == DrawerIndex.personalization) { screenView = PersonalizationSettingsPage(); - }); - } else if (drawerIndex == DrawerIndex.feedback && !Config.developerMode) { - setState(() { + } else if (drawerIndex == DrawerIndex.feedback && !Config.developerMode) { if (Platform.isWindows) { debugPrint("flutter_email_sender does not support Windows."); //_launchFeedback(); @@ -131,18 +123,14 @@ class _NavigationHomeScreenState extends State { await FlutterEmailSender.send(email); }); } - }); - } else if (drawerIndex == DrawerIndex.Help && !Config.developerMode) { - setState(() { + } else if (drawerIndex == DrawerIndex.Help && !Config.developerMode) { screenView = HelpScreen(); - }); - } else if (drawerIndex == DrawerIndex.About && !Config.developerMode) { - setState(() { + } else if (drawerIndex == DrawerIndex.About && !Config.developerMode) { screenView = AboutPage(); - }); - } else { - //do in your way...... - } + } else { + //do in your way...... + } + }); } Future writeImageToStorage(Uint8List feedbackScreenshot) async { diff --git a/src/ui/flutter_app/lib/screens/oss_license_page.dart b/src/ui/flutter_app/lib/screens/oss_license_page.dart index fdf6b315..101b105b 100644 --- a/src/ui/flutter_app/lib/screens/oss_license_page.dart +++ b/src/ui/flutter_app/lib/screens/oss_license_page.dart @@ -86,7 +86,8 @@ class OssLicensesPage extends StatelessWidget { title: Text('$key $version'), subtitle: desc != null ? Text(desc) : null, trailing: const Icon(FluentIcons.chevron_right_24_regular), - onTap: () => Navigator.of(context).push( + onTap: () => Navigator.push( + context, MaterialPageRoute( builder: (_) => MiscOssLicenseSingle(name: key, json: ossl), ), diff --git a/src/ui/flutter_app/lib/screens/personalization_settings_page.dart b/src/ui/flutter_app/lib/screens/personalization_settings_page.dart index 5b8c7299..b5e289a9 100644 --- a/src/ui/flutter_app/lib/screens/personalization_settings_page.dart +++ b/src/ui/flutter_app/lib/screens/personalization_settings_page.dart @@ -27,8 +27,6 @@ import 'package:sanmill/shared/common/config.dart'; import 'package:sanmill/shared/common/constants.dart'; import 'package:sanmill/shared/theme/app_theme.dart'; -import 'list_item_divider.dart'; - class PersonalizationSettingsPage extends StatefulWidget { @override _PersonalizationSettingsPageState createState() => @@ -130,7 +128,7 @@ class _PersonalizationSettingsPageState } Config.save(); - Navigator.of(context).pop(); + Navigator.pop(context); }, ), TextButton( @@ -141,7 +139,7 @@ class _PersonalizationSettingsPageState ), ), onPressed: () { - Navigator.of(context).pop(); + Navigator.pop(context); }, ), ], @@ -374,7 +372,7 @@ class _PersonalizationSettingsPageState Future langCallback([String? langCode]) async { debugPrint("[config] languageCode = $langCode"); - Navigator.of(context).pop(); + Navigator.pop(context); setState(() { Config.languageCode = langCode ?? Constants.defaultLanguageCodeName; @@ -394,63 +392,53 @@ class _PersonalizationSettingsPageState SettingsListTile( titleString: S.of(context).language, trailingString: - Config.languageCode == Constants.defaultLanguageCodeName - ? "" - : languageCodeToStrings[Config.languageCode]!.languageName, + Config.languageCode != Constants.defaultLanguageCodeName + ? languageCodeToStrings[Config.languageCode]!.languageName + : "", onTap: () => setLanguage(context, langCallback), ), - const ListItemDivider(), SettingsSwitchListTile( context: context, value: Config.isPieceCountInHandShown, onChanged: setIsPieceCountInHandShown, titleString: S.of(context).isPieceCountInHandShown, ), - const ListItemDivider(), SettingsSwitchListTile( context: context, value: Config.isNotationsShown, onChanged: setIsNotationsShown, titleString: S.of(context).isNotationsShown, ), - const ListItemDivider(), SettingsSwitchListTile( context: context, value: Config.isHistoryNavigationToolbarShown, onChanged: setIsHistoryNavigationToolbarShown, titleString: S.of(context).isHistoryNavigationToolbarShown, ), - const ListItemDivider(), SettingsListTile( titleString: S.of(context).boardBorderLineWidth, onTap: setBoardBorderLineWidth, ), - const ListItemDivider(), SettingsListTile( titleString: S.of(context).boardInnerLineWidth, onTap: setBoardInnerLineWidth, ), - const ListItemDivider(), SettingsListTile( titleString: S.of(context).pieceWidth, onTap: setPieceWidth, ), - const ListItemDivider(), SettingsListTile( titleString: S.of(context).fontSize, onTap: setFontSize, ), - const ListItemDivider(), SettingsListTile( titleString: S.of(context).boardTop, onTap: setBoardTop, ), - const ListItemDivider(), SettingsListTile( titleString: S.of(context).animationDuration, onTap: setAnimationDuration, ), - const ListItemDivider(), SettingsSwitchListTile( context: context, value: Config.standardNotationEnabled, @@ -469,88 +457,74 @@ class _PersonalizationSettingsPageState trailingColor: Config.boardBackgroundColor, onTap: () => showColorDialog(S.of(context).boardColor), ), - const ListItemDivider(), SettingsListTile( titleString: S.of(context).backgroundColor, trailingColor: Config.darkBackgroundColor, onTap: () => showColorDialog(S.of(context).backgroundColor), ), - const ListItemDivider(), SettingsListTile( titleString: S.of(context).lineColor, trailingColor: Config.boardLineColor, onTap: () => showColorDialog(S.of(context).lineColor), ), - const ListItemDivider(), SettingsListTile( titleString: S.of(context).whitePieceColor, trailingColor: Config.whitePieceColor, onTap: () => showColorDialog(S.of(context).whitePieceColor), ), - const ListItemDivider(), SettingsListTile( titleString: S.of(context).blackPieceColor, trailingColor: Config.blackPieceColor, onTap: () => showColorDialog(S.of(context).blackPieceColor), ), - const ListItemDivider(), SettingsListTile( titleString: S.of(context).pieceHighlightColor, trailingColor: Config.pieceHighlightColor, onTap: () => showColorDialog(S.of(context).pieceHighlightColor), ), - const ListItemDivider(), SettingsListTile( titleString: S.of(context).messageColor, trailingColor: Config.messageColor, onTap: () => showColorDialog(S.of(context).messageColor), ), - const ListItemDivider(), SettingsListTile( titleString: S.of(context).drawerColor, trailingColor: Config.drawerColor, onTap: () => showColorDialog(S.of(context).drawerColor), ), - const ListItemDivider(), SettingsListTile( titleString: S.of(context).drawerBackgroundColor, trailingColor: Config.drawerBackgroundColor, onTap: () => showColorDialog(S.of(context).drawerBackgroundColor), ), - const ListItemDivider(), SettingsListTile( titleString: S.of(context).drawerTextColor, trailingColor: Config.drawerTextColor, onTap: () => showColorDialog(S.of(context).drawerTextColor), ), - const ListItemDivider(), SettingsListTile( titleString: S.of(context).drawerHighlightItemColor, trailingColor: Config.drawerHighlightItemColor, onTap: () => showColorDialog(S.of(context).drawerHighlightItemColor), ), - const ListItemDivider(), SettingsListTile( titleString: S.of(context).mainToolbarBackgroundColor, trailingColor: Config.mainToolbarBackgroundColor, onTap: () => showColorDialog(S.of(context).mainToolbarBackgroundColor), ), - const ListItemDivider(), SettingsListTile( titleString: S.of(context).mainToolbarIconColor, trailingColor: Config.mainToolbarIconColor, onTap: () => showColorDialog(S.of(context).mainToolbarIconColor), ), - const ListItemDivider(), SettingsListTile( titleString: S.of(context).navigationToolbarBackgroundColor, trailingColor: Config.navigationToolbarBackgroundColor, onTap: () => showColorDialog(S.of(context).navigationToolbarBackgroundColor), ), - const ListItemDivider(), SettingsListTile( titleString: S.of(context).navigationToolbarIconColor, trailingColor: Config.navigationToolbarIconColor, @@ -565,33 +539,25 @@ class _PersonalizationSettingsPageState // Display Future setIsPieceCountInHandShown(bool value) async { - setState(() { - Config.isPieceCountInHandShown = value; - }); + setState(() => Config.isPieceCountInHandShown = value); Config.save(); } Future setIsNotationsShown(bool value) async { - setState(() { - Config.isNotationsShown = value; - }); + setState(() => Config.isNotationsShown = value); Config.save(); } Future setIsHistoryNavigationToolbarShown(bool value) async { - setState(() { - Config.isHistoryNavigationToolbarShown = value; - }); + setState(() => Config.isHistoryNavigationToolbarShown = value); Config.save(); } Future setStandardNotationEnabled(bool value) async { - setState(() { - Config.standardNotationEnabled = value; - }); + setState(() => Config.standardNotationEnabled = value); debugPrint("[config] standardNotationEnabled: $value"); diff --git a/src/ui/flutter_app/lib/screens/rule_settings_page.dart b/src/ui/flutter_app/lib/screens/rule_settings_page.dart index 4e3ecc29..05e25d10 100644 --- a/src/ui/flutter_app/lib/screens/rule_settings_page.dart +++ b/src/ui/flutter_app/lib/screens/rule_settings_page.dart @@ -27,7 +27,6 @@ import 'package:sanmill/shared/common/config.dart'; import 'package:sanmill/shared/theme/app_theme.dart'; import '../shared/snack_bar.dart'; -import 'list_item_divider.dart'; class RuleSettingsPage extends StatefulWidget { @override @@ -63,7 +62,6 @@ class _RuleSettingsPageState extends State { trailingString: Config.piecesCount.toString(), onTap: setNTotalPiecesEachSide, ), - const ListItemDivider(), SettingsSwitchListTile( context: context, value: Config.hasDiagonalLines, @@ -71,21 +69,18 @@ class _RuleSettingsPageState extends State { titleString: S.of(context).hasDiagonalLines, subtitleString: S.of(context).hasDiagonalLines_Detail, ), - const ListItemDivider(), SettingsListTile( titleString: S.of(context).nMoveRule, subtitleString: S.of(context).nMoveRule_Detail, trailingString: Config.nMoveRule.toString(), onTap: setNMoveRule, ), - const ListItemDivider(), SettingsListTile( titleString: S.of(context).endgameNMoveRule, subtitleString: S.of(context).endgameNMoveRule_Detail, trailingString: Config.endgameNMoveRule.toString(), onTap: setEndgameNMoveRule, ), - const ListItemDivider(), SettingsSwitchListTile( context: context, value: Config.threefoldRepetitionRule, @@ -93,7 +88,6 @@ class _RuleSettingsPageState extends State { titleString: S.of(context).threefoldRepetitionRule, subtitleString: S.of(context).threefoldRepetitionRule_Detail, ), - const ListItemDivider(), ], ), const SizedBox(height: AppTheme.sizedBoxHeight), @@ -108,7 +102,6 @@ class _RuleSettingsPageState extends State { titleString: S.of(context).hasBannedLocations, subtitleString: S.of(context).hasBannedLocations_Detail, ), - const ListItemDivider(), SettingsSwitchListTile( context: context, value: Config.isWhiteLoseButNotDrawWhenBoardFull, @@ -117,7 +110,6 @@ class _RuleSettingsPageState extends State { subtitleString: S.of(context).isWhiteLoseButNotDrawWhenBoardFull_Detail, ), - const ListItemDivider(), SettingsSwitchListTile( context: context, value: Config.mayOnlyRemoveUnplacedPieceInPlacingPhase, @@ -141,19 +133,13 @@ class _RuleSettingsPageState extends State { subtitleString: S.of(context).mayMoveInPlacingPhase_Detail, ) else - const SizedBox(height: 1), - if (Config.experimentsEnabled) - const ListItemDivider() - else - const SizedBox(height: 1), - SettingsSwitchListTile( - context: context, - value: Config.isDefenderMoveFirst, - onChanged: setIsDefenderMoveFirst, - titleString: S.of(context).isDefenderMoveFirst, - subtitleString: S.of(context).isDefenderMoveFirst_Detail, - ), - const ListItemDivider(), + SettingsSwitchListTile( + context: context, + value: Config.isDefenderMoveFirst, + onChanged: setIsDefenderMoveFirst, + titleString: S.of(context).isDefenderMoveFirst, + subtitleString: S.of(context).isDefenderMoveFirst_Detail, + ), SettingsSwitchListTile( context: context, value: Config.isLoseButNotChangeSideWhenNoWay, @@ -176,7 +162,6 @@ class _RuleSettingsPageState extends State { titleString: S.of(context).mayFly, subtitleString: S.of(context).mayFly_Detail, ), - const ListItemDivider(), SettingsListTile( titleString: S.of(context).flyPieceCount, subtitleString: S.of(context).flyPieceCount_Detail, @@ -197,7 +182,6 @@ class _RuleSettingsPageState extends State { titleString: S.of(context).mayRemoveFromMillsAlways, subtitleString: S.of(context).mayRemoveFromMillsAlways_Detail, ), - const ListItemDivider(), SettingsSwitchListTile( context: context, value: Config.mayRemoveMultiple, @@ -205,7 +189,6 @@ class _RuleSettingsPageState extends State { titleString: S.of(context).mayRemoveMultiple, subtitleString: S.of(context).mayRemoveMultiple_Detail, ), - const ListItemDivider(), ], ), ]; @@ -217,12 +200,12 @@ class _RuleSettingsPageState extends State { Future callback(int? piecesCount) async { debugPrint("[config] piecesCount = $piecesCount"); - Navigator.of(context).pop(); + Navigator.pop(context); - setState(() { - rule.piecesCount = Config.piecesCount = - piecesCount ?? (specialCountryAndRegion == "Iran" ? 12 : 9); - }); + setState( + () => rule.piecesCount = Config.piecesCount = + piecesCount ?? (specialCountryAndRegion == "Iran" ? 12 : 9), + ); debugPrint("[config] rule.piecesCount: ${rule.piecesCount}"); @@ -243,7 +226,6 @@ class _RuleSettingsPageState extends State { value: 9, onChanged: callback, ), - const ListItemDivider(), RadioListTile( activeColor: AppTheme.switchListTileActiveColor, title: const Text('10'), @@ -251,7 +233,6 @@ class _RuleSettingsPageState extends State { value: 10, onChanged: callback, ), - const ListItemDivider(), RadioListTile( activeColor: AppTheme.switchListTileActiveColor, title: const Text('11'), @@ -259,7 +240,6 @@ class _RuleSettingsPageState extends State { value: 11, onChanged: callback, ), - const ListItemDivider(), RadioListTile( activeColor: AppTheme.switchListTileActiveColor, title: const Text('12'), @@ -267,7 +247,6 @@ class _RuleSettingsPageState extends State { value: 12, onChanged: callback, ), - const ListItemDivider(), ], ), ), @@ -278,11 +257,9 @@ class _RuleSettingsPageState extends State { Future callback(int? nMoveRule) async { debugPrint("[config] nMoveRule = $nMoveRule"); - Navigator.of(context).pop(); + Navigator.pop(context); - setState(() { - rule.nMoveRule = Config.nMoveRule = nMoveRule ?? 100; - }); + setState(() => rule.nMoveRule = Config.nMoveRule = nMoveRule ?? 100); debugPrint("[config] rule.nMoveRule: ${rule.nMoveRule}"); @@ -303,7 +280,6 @@ class _RuleSettingsPageState extends State { value: 30, onChanged: callback, ), - const ListItemDivider(), RadioListTile( activeColor: AppTheme.switchListTileActiveColor, title: const Text('50'), @@ -311,7 +287,6 @@ class _RuleSettingsPageState extends State { value: 50, onChanged: callback, ), - const ListItemDivider(), RadioListTile( activeColor: AppTheme.switchListTileActiveColor, title: const Text('60'), @@ -319,7 +294,6 @@ class _RuleSettingsPageState extends State { value: 60, onChanged: callback, ), - const ListItemDivider(), RadioListTile( activeColor: AppTheme.switchListTileActiveColor, title: const Text('100'), @@ -327,7 +301,6 @@ class _RuleSettingsPageState extends State { value: 100, onChanged: callback, ), - const ListItemDivider(), RadioListTile( activeColor: AppTheme.switchListTileActiveColor, title: const Text('200'), @@ -335,7 +308,6 @@ class _RuleSettingsPageState extends State { value: 200, onChanged: callback, ), - const ListItemDivider(), ], ), ), @@ -346,12 +318,12 @@ class _RuleSettingsPageState extends State { Future callback(int? endgameNMoveRule) async { debugPrint("[config] endgameNMoveRule = $endgameNMoveRule"); - Navigator.of(context).pop(); + Navigator.pop(context); - setState(() { - rule.endgameNMoveRule = - Config.endgameNMoveRule = endgameNMoveRule ?? 100; - }); + setState( + () => rule.endgameNMoveRule = + Config.endgameNMoveRule = endgameNMoveRule ?? 100, + ); debugPrint("[config] rule.endgameNMoveRule: ${rule.endgameNMoveRule}"); @@ -372,7 +344,6 @@ class _RuleSettingsPageState extends State { value: 5, onChanged: callback, ), - const ListItemDivider(), RadioListTile( activeColor: AppTheme.switchListTileActiveColor, title: const Text('10'), @@ -380,7 +351,6 @@ class _RuleSettingsPageState extends State { value: 10, onChanged: callback, ), - const ListItemDivider(), RadioListTile( activeColor: AppTheme.switchListTileActiveColor, title: const Text('20'), @@ -388,7 +358,6 @@ class _RuleSettingsPageState extends State { value: 20, onChanged: callback, ), - const ListItemDivider(), RadioListTile( activeColor: AppTheme.switchListTileActiveColor, title: const Text('30'), @@ -396,7 +365,6 @@ class _RuleSettingsPageState extends State { value: 30, onChanged: callback, ), - const ListItemDivider(), RadioListTile( activeColor: AppTheme.switchListTileActiveColor, title: const Text('50'), @@ -404,7 +372,6 @@ class _RuleSettingsPageState extends State { value: 50, onChanged: callback, ), - const ListItemDivider(), RadioListTile( activeColor: AppTheme.switchListTileActiveColor, title: const Text('60'), @@ -412,7 +379,6 @@ class _RuleSettingsPageState extends State { value: 60, onChanged: callback, ), - const ListItemDivider(), RadioListTile( activeColor: AppTheme.switchListTileActiveColor, title: const Text('100'), @@ -420,7 +386,6 @@ class _RuleSettingsPageState extends State { value: 100, onChanged: callback, ), - const ListItemDivider(), RadioListTile( activeColor: AppTheme.switchListTileActiveColor, title: const Text('200'), @@ -428,7 +393,6 @@ class _RuleSettingsPageState extends State { value: 200, onChanged: callback, ), - const ListItemDivider(), ], ), ), @@ -439,11 +403,11 @@ class _RuleSettingsPageState extends State { Future callback(int? flyPieceCount) async { debugPrint("[config] flyPieceCount = $flyPieceCount"); - Navigator.of(context).pop(); + Navigator.pop(context); - setState(() { - rule.flyPieceCount = Config.flyPieceCount = flyPieceCount ?? 3; - }); + setState( + () => rule.flyPieceCount = Config.flyPieceCount = flyPieceCount ?? 3, + ); debugPrint("[config] rule.flyPieceCount: ${rule.flyPieceCount}"); @@ -464,7 +428,6 @@ class _RuleSettingsPageState extends State { value: 3, onChanged: callback, ), - const ListItemDivider(), RadioListTile( activeColor: AppTheme.switchListTileActiveColor, title: const Text('4'), @@ -472,7 +435,6 @@ class _RuleSettingsPageState extends State { value: 4, onChanged: callback, ), - const ListItemDivider(), ], ), ), @@ -480,9 +442,7 @@ class _RuleSettingsPageState extends State { } Future setHasDiagonalLines(bool value) async { - setState(() { - rule.hasDiagonalLines = Config.hasDiagonalLines = value; - }); + setState(() => rule.hasDiagonalLines = Config.hasDiagonalLines = value); debugPrint("[config] rule.hasDiagonalLines: $value"); @@ -490,9 +450,7 @@ class _RuleSettingsPageState extends State { } Future setAllowFlyingAllowed(bool value) async { - setState(() { - rule.mayFly = Config.mayFly = value; - }); + setState(() => rule.mayFly = Config.mayFly = value); debugPrint("[config] rule.mayFly: $value"); @@ -500,9 +458,10 @@ class _RuleSettingsPageState extends State { } Future setThreefoldRepetitionRule(bool value) async { - setState(() { - rule.threefoldRepetitionRule = Config.threefoldRepetitionRule = value; - }); + setState( + () => + rule.threefoldRepetitionRule = Config.threefoldRepetitionRule = value, + ); debugPrint("[config] rule.threefoldRepetitionRule: $value"); @@ -512,9 +471,7 @@ class _RuleSettingsPageState extends State { // Placing Future setHasBannedLocations(bool value) async { - setState(() { - rule.hasBannedLocations = Config.hasBannedLocations = value; - }); + setState(() => rule.hasBannedLocations = Config.hasBannedLocations = value); debugPrint("[config] rule.hasBannedLocations: $value"); @@ -522,10 +479,10 @@ class _RuleSettingsPageState extends State { } Future setIsWhiteLoseButNotDrawWhenBoardFull(bool value) async { - setState(() { - rule.isWhiteLoseButNotDrawWhenBoardFull = - Config.isWhiteLoseButNotDrawWhenBoardFull = value; - }); + setState( + () => rule.isWhiteLoseButNotDrawWhenBoardFull = + Config.isWhiteLoseButNotDrawWhenBoardFull = value, + ); debugPrint("[config] rule.isWhiteLoseButNotDrawWhenBoardFull: $value"); @@ -533,10 +490,10 @@ class _RuleSettingsPageState extends State { } Future setMayOnlyRemoveUnplacedPieceInPlacingPhase(bool value) async { - setState(() { - rule.mayOnlyRemoveUnplacedPieceInPlacingPhase = - Config.mayOnlyRemoveUnplacedPieceInPlacingPhase = value; - }); + setState( + () => rule.mayOnlyRemoveUnplacedPieceInPlacingPhase = + Config.mayOnlyRemoveUnplacedPieceInPlacingPhase = value, + ); debugPrint( "[config] rule.mayOnlyRemoveUnplacedPieceInPlacingPhase: $value", @@ -548,9 +505,9 @@ class _RuleSettingsPageState extends State { // Moving Future setMayMoveInPlacingPhase(bool value) async { - setState(() { - rule.mayMoveInPlacingPhase = Config.mayMoveInPlacingPhase = value; - }); + setState( + () => rule.mayMoveInPlacingPhase = Config.mayMoveInPlacingPhase = value, + ); debugPrint("[config] rule.mayMoveInPlacingPhase: $value"); @@ -563,9 +520,9 @@ class _RuleSettingsPageState extends State { } Future setIsDefenderMoveFirst(bool value) async { - setState(() { - rule.isDefenderMoveFirst = Config.isDefenderMoveFirst = value; - }); + setState( + () => rule.isDefenderMoveFirst = Config.isDefenderMoveFirst = value, + ); debugPrint("[config] rule.isDefenderMoveFirst: $value"); @@ -573,10 +530,10 @@ class _RuleSettingsPageState extends State { } Future setIsLoseButNotChangeSideWhenNoWay(bool value) async { - setState(() { - rule.isLoseButNotChangeSideWhenNoWay = - Config.isLoseButNotChangeSideWhenNoWay = value; - }); + setState( + () => rule.isLoseButNotChangeSideWhenNoWay = + Config.isLoseButNotChangeSideWhenNoWay = value, + ); debugPrint("[config] rule.isLoseButNotChangeSideWhenNoWay: $value"); @@ -586,9 +543,10 @@ class _RuleSettingsPageState extends State { // Removing Future setAllowRemovePieceInMill(bool value) async { - setState(() { - rule.mayRemoveFromMillsAlways = Config.mayRemoveFromMillsAlways = value; - }); + setState( + () => rule.mayRemoveFromMillsAlways = + Config.mayRemoveFromMillsAlways = value, + ); debugPrint("[config] rule.mayRemoveFromMillsAlways: $value"); @@ -596,9 +554,9 @@ class _RuleSettingsPageState extends State { } Future setAllowRemoveMultiPiecesWhenCloseMultiMill(bool value) async { - setState(() { - rule.mayRemoveMultiple = Config.mayRemoveMultiple = value; - }); + setState( + () => rule.mayRemoveMultiple = Config.mayRemoveMultiple = value, + ); debugPrint("[config] rule.mayRemoveMultiple: $value"); @@ -608,9 +566,7 @@ class _RuleSettingsPageState extends State { // Unused Future setNPiecesAtLeast(int value) async { - setState(() { - rule.piecesAtLeastCount = Config.piecesAtLeastCount = value; - }); + setState(() => rule.piecesAtLeastCount = Config.piecesAtLeastCount = value); debugPrint("[config] rule.piecesAtLeastCount: $value"); diff --git a/src/ui/flutter_app/lib/screens/settings/settings_card.dart b/src/ui/flutter_app/lib/screens/settings/settings_card.dart index 078d3764..efae523f 100644 --- a/src/ui/flutter_app/lib/screens/settings/settings_card.dart +++ b/src/ui/flutter_app/lib/screens/settings/settings_card.dart @@ -17,6 +17,7 @@ */ import 'package:flutter/material.dart'; +import 'package:sanmill/screens/list_item_divider.dart'; import 'package:sanmill/shared/theme/app_theme.dart'; class SettingsCard extends StatelessWidget { @@ -34,7 +35,13 @@ class SettingsCard extends StatelessWidget { return Card( color: AppTheme.cardColor, margin: AppTheme.cardMargin, - child: Column(children: children), + child: ListView.separated( + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemBuilder: (_, index) => children[index], + separatorBuilder: (_, __) => const ListItemDivider(), + itemCount: children.length, + ), ); } } diff --git a/src/ui/flutter_app/lib/shared/dialog.dart b/src/ui/flutter_app/lib/shared/dialog.dart index bdabcd83..9380567a 100644 --- a/src/ui/flutter_app/lib/shared/dialog.dart +++ b/src/ui/flutter_app/lib/shared/dialog.dart @@ -72,7 +72,7 @@ void showCountdownDialog( const SizedBox(height: 20), InkWell( onTap: () { - Navigator.of(context).pop(); + Navigator.pop(context); }, child: Center( child: Text( @@ -179,7 +179,7 @@ Future showPrivacyDialog( child: Text(S.of(context).accept), onPressed: () { setPrivacyPolicyAccepted(true); - Navigator.of(context).pop(); + Navigator.pop(context); }, ), if (Platform.isAndroid) diff --git a/src/ui/flutter_app/lib/shared/painters/board_painter.dart b/src/ui/flutter_app/lib/shared/painters/board_painter.dart index e72f1b15..90d364c3 100644 --- a/src/ui/flutter_app/lib/shared/painters/board_painter.dart +++ b/src/ui/flutter_app/lib/shared/painters/board_painter.dart @@ -63,16 +63,16 @@ class BoardPainter extends PiecesBasePainter { if (Config.isPieceCountInHandShown) { var pieceInHandCount = - Game.instance.position.pieceInHandCount[PieceColor.black]; + gameInstance.position.pieceInHandCount[PieceColor.black]; - if (Game.instance.position.pieceOnBoardCount[PieceColor.white] == 0 && - Game.instance.position.pieceOnBoardCount[PieceColor.black] == 0) { + if (gameInstance.position.pieceOnBoardCount[PieceColor.white] == 0 && + gameInstance.position.pieceOnBoardCount[PieceColor.black] == 0) { pieceInHandCount = Config.piecesCount; } var pieceInHandCountStr = ""; - if (Game.instance.position.phase == Phase.placing) { + if (gameInstance.position.phase == Phase.placing) { pieceInHandCountStr = pieceInHandCount.toString(); }