Compare commits

...

3 Commits

Author SHA1 Message Date
Leptopoda-GitHub 944c0c7935
cleanup painters 2021-11-08 17:15:06 +01:00
Leptopoda-GitHub 49709772e0 better utilize arb localization features
no concatenation enymore :)
2021-11-08 17:10:15 +01:00
Leptopoda-GitHub ea3ac68cc7
better utilize theming
This will move more stuff into the ThemeData class. 
It also cleans up the ColorSettings class

fix spelling
2021-11-08 17:04:38 +01:00
56 changed files with 1024 additions and 1144 deletions

View File

@ -2,10 +2,7 @@ include: package:lint/analysis_options.yaml
linter:
rules:
avoid_positional_boolean_parameters: false
constant_identifier_names: false
avoid_escaping_inner_quotes: false
use_build_context_synchronously: false
depend_on_referenced_packages: false
analyzer:

View File

@ -44,13 +44,15 @@
"@testViaLAN": {
"description": "Test Via LAN"
},
"move": "Move",
"@move": {
"description": "Move"
},
"moves": " Moves",
"@moves": {
"description": " Moves"
"move_number": "{count,plural, =0{Move}=1{{count} Move}other{{count} Moves}}",
"@move_number": {
"description": "moves to take back",
"placeholders": {
"count": {
"description": "number of Moves",
"example": "3"
}
}
},
"showMoveList": "Move list",
"@showMoveList": {
@ -160,9 +162,15 @@
"@tipCanMoveToAnyPoint": {
"description": "You can move to any point you like."
},
"tipToMove": " to move.",
"tipToMove": "{player} to move.",
"@tipToMove": {
"description": " to move."
"description": "Tip that the given player is to move",
"placeholders": {
"player": {
"description": "The player who's turn it is",
"example": "Player 1"
}
}
},
"whiteWin": "Player 1 wins!",
"@whiteWin": {
@ -204,9 +212,15 @@
"@gameImported": {
"description": "Game imported from the clipboard."
},
"cannotImport": "Cannot import",
"cannotImport": "Cannot import {error}",
"@cannotImport": {
"description": "Cannot import"
"description": "Cannot import",
"placeholders": {
"error": {
"description": "the error causing this message",
"example": "insufficient permissions"
}
}
},
"movesAndRulesNotMatch": "Moves and rules do not match.",
"@movesAndRulesNotMatch": {
@ -252,15 +266,21 @@
"@analyzing": {
"description": "Analyzing ..."
},
"error": "Error",
"error": "Error: {message}",
"@error": {
"description": "Error"
"description": "Error",
"placeholders": {
"message": {
"description": "the Error message",
"example": "x was not ready yet"
}
}
},
"winRate": "Win Rate",
"@winRate": {
"description": "Win Rate"
},
"score": "Score",
"score": "Score:",
"@score": {
"description": "Score"
},
@ -272,25 +292,55 @@
"@black": {
"description": "Player 2"
},
"loseReasonlessThanThree": " piece count is less than three.",
"loseReasonlessThanThree": "{player} piece count is less than three.",
"@loseReasonlessThanThree": {
"description": " piece count is less than three."
"description": "Indicate that the player lost because they had less then three pieces left",
"placeholders": {
"player": {
"description": "The player who lost",
"example": "Player 1"
}
}
},
"loseReasonResign": " resign.",
"loseReasonResign": "{player} resigned.",
"@loseReasonResign": {
"description": " resign."
"description": "Indicate that the player resigned",
"placeholders": {
"player": {
"description": "The player who resigns",
"example": "Player 1"
}
}
},
"loseReasonNoWay": " is no way to go.",
"loseReasonNoWay": "{player} has no way to go.",
"@loseReasonNoWay": {
"description": " is no way to go."
"description": "Indicate that the player has no way to go",
"placeholders": {
"player": {
"description": "The player who lost",
"example": "Player 1"
}
}
},
"loseReasonBoardIsFull": "The board is full, and no way to go.",
"loseReasonBoardIsFull": "The board is full, and {player} has no way to go.",
"@loseReasonBoardIsFull": {
"description": "The board is full, no way to go."
"description": "The board is full, no way to go.",
"placeholders": {
"player": {
"description": "The player who lost",
"example": "Player 1"
}
}
},
"loseReasonTimeOver": "Time Over",
"loseReasonTimeOver": "Time Over, {player} lost",
"@loseReasonTimeOver": {
"description": "Time Over"
"description": "Time Over",
"placeholders": {
"player": {
"description": "The player who lost",
"example": "Player 1"
}
}
},
"drawReasonRule50": "In the moving phase, no piece has been removed in the last specific number of moves.",
"@drawReasonRule50": {
@ -316,9 +366,15 @@
"@youWin": {
"description": "You win! Congratulations!"
},
"challengeHarderLevel": "Challenge harder level? The new level will be level ",
"challengeHarderLevel": "Challenge harder level? The new level will be level {level}!",
"@challengeHarderLevel": {
"description": "Challenge harder level?"
"description": "Challenge harder level?",
"placeholders": {
"level": {
"description": "The new level",
"example": "5"
}
}
},
"youLose": "You Lose!",
"@youLose": {
@ -336,9 +392,15 @@
"@about": {
"description": "About"
},
"version": "Version",
"version": "Version: {version_number}",
"@version": {
"description": "Version"
"description": "Version",
"placeholders": {
"version_number": {
"description": "the current Sanmill version",
"example": "1.38.1"
}
}
},
"thanks": "Thanks",
"@thanks": {
@ -636,17 +698,15 @@
"@restoreDefaultSettings": {
"description": "Restore Default Settings"
},
"exitApp": "The app will exit.",
"@exitApp": {
"description": "The app will exit."
},
"exitAppManually": "You have to close immediately and reopen the app to take effect.",
"@exitAppManually": {
"description": "You have to close immediately and reopen the app to take effect."
},
"pick": "Pick",
"pick": "Pick {element}",
"@pick": {
"description": "Pick "
"description": "Used in the color picker",
"placeholders": {
"element": {
"description": "The element to pick the color for",
"example": "Background color"
}
}
},
"info": "Info",
"@info": {
@ -881,17 +941,37 @@
"@considerMobility": {
"description": "Consider mobility of pieces"
},
"pieceCount": "Piece count",
"pieceCount": "Piece count:",
"@pieceCount": {
"description": "Piece count"
},
"inHand": "in hand",
"inHand": "{player} in hand: {amount}",
"@inHand": {
"description": "in hand"
"description": "The pieces a player has in their board",
"placeholders": {
"player": {
"description": "The specified player",
"example": "White"
},
"onBoard": "on board",
"amount": {
"description": "The amount of pieces",
"example": "5"
}
}
},
"onBoard": "{player} on board: {amount}",
"@onBoard": {
"description": "on board"
"description": "The pieces a player has on the board",
"placeholders": {
"player": {
"description": "The specified player",
"example": "White"
},
"amount": {
"description": "The amount of pieces",
"example": "5"
}
}
},
"boardTop": "Board offset from the top",
"@boardTop": {
@ -1161,22 +1241,30 @@
"@flyingPhase": {
"description": "Flying phase"
},
"sideToMove": "Side to move",
"sideToMove": "Side to move: {player}",
"@sideToMove": {
"description": "Side to move"
"description": "The player whos turn it is",
"placeholders": {
"player": {
"description": "The player to move",
"example": "Player 1"
}
}
},
"lastMove": "Last move",
"lastMove": "Last move: {move}",
"@lastMove": {
"description": "Last move"
"description": "Last move",
"placeholders": {
"move": {
"description": "The last move",
"example": "f4"
}
}
},
"selected": "Selected",
"@selected": {
"description": "Selected"
},
"mainMenu": "Main menu",
"@mainMenu": {
"description": "Main menu"
},
"accessibility": "Accessibility",
"@accessibility": {
"description": "Accessibility"

View File

@ -78,7 +78,7 @@ class SanmillApp extends StatelessWidget {
builder: (BuildContext context, Box<Display> displayBox, child) {
final Display _display = displayBox.get(
LocalDatabaseService.displayKey,
defaultValue: Display(),
defaultValue: const Display(),
)!;
return MaterialApp(
/// Add navigator key from Catcher.

View File

@ -25,14 +25,14 @@ import 'package:sanmill/services/storage/storage.dart';
enum PlayerType { human, AI }
Map<String, bool> isAi = {PieceColor.white: false, PieceColor.black: true};
// TODO: add constructor
// TODO: [Leptopoda] add constructor
Game gameInstance = Game();
class Game {
static const String _tag = "[game]";
void init() {
// TODO: _position is already initialized with Position(). seems like duplicate code
// TODO: [Leptopoda] _position is already initialized with Position(). seems like duplicate code
_position = Position();
focusIndex = blurIndex = invalidIndex;
}

View File

@ -471,7 +471,7 @@ class Position {
start();
}
// TODO: use switch case
// TODO: [Leptopoda] use switch case
if (phase == Phase.placing) {
piece = sideToMove;
if (pieceInHandCount[us] != null) {

View File

@ -115,7 +115,7 @@ class GameRecorder {
}
bool isDalmaxMoveList(String text) {
if (text.length >= 15 && text.substring(0, 14) == "[Event \"Dalmax") {
if (text.length >= 15 && text.substring(0, 14) == '[Event "Dalmax') {
return true;
}

View File

@ -18,7 +18,7 @@
import 'package:sanmill/services/language_info.dart';
// TODO: deprecate this thingy. No reason to keep it
// TODO: [Leptopoda] deprecate this thingy. No reason to keep it
class Rule {
String name = "Default Rule";
String description = "";

View File

@ -17,17 +17,15 @@
*/
import 'package:copy_with_extension/copy_with_extension.dart';
import 'package:flutter/widgets.dart' show Color, immutable;
import 'package:flutter/material.dart' show Colors, Color, immutable;
import 'package:hive_flutter/adapters.dart'
show HiveField, HiveType, BinaryReader, BinaryWriter, TypeAdapter;
import 'package:json_annotation/json_annotation.dart';
import 'package:sanmill/services/storage/adapters/color_adapter.dart';
import 'package:sanmill/shared/theme/app_theme.dart';
import 'package:sanmill/shared/theme/colors.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
@ -36,152 +34,128 @@ part 'color.g.dart';
@CopyWith()
@immutable
class ColorSettings {
ColorSettings({
Color? boardLineColor,
Color? darkBackgroundColor,
Color? boardBackgroundColor,
Color? whitePieceColor,
Color? blackPieceColor,
Color? pieceHighlightColor,
Color? messageColor,
Color? drawerColor,
Color? drawerBackgroundColor,
Color? drawerTextColor,
Color? drawerHighlightItemColor,
Color? mainToolbarBackgroundColor,
Color? mainToolbarIconColor,
Color? navigationToolbarBackgroundColor,
Color? navigationToolbarIconColor,
}) {
this.boardLineColor = boardLineColor ?? AppTheme.boardLineColor;
this.darkBackgroundColor =
darkBackgroundColor ?? AppTheme.darkBackgroundColor;
this.boardBackgroundColor =
boardBackgroundColor ?? AppTheme.boardBackgroundColor;
this.whitePieceColor = whitePieceColor ?? AppTheme.whitePieceColor;
this.blackPieceColor = blackPieceColor ?? AppTheme.blackPieceColor;
this.pieceHighlightColor =
pieceHighlightColor ?? AppTheme.pieceHighlightColor;
this.messageColor = messageColor ?? AppTheme.messageColor;
this.drawerColor = drawerColor ?? AppTheme.drawerColor;
this.drawerBackgroundColor =
drawerBackgroundColor ?? AppTheme.drawerBackgroundColor;
this.drawerTextColor = drawerTextColor ?? AppTheme.drawerTextColor;
this.drawerHighlightItemColor =
drawerHighlightItemColor ?? AppTheme.drawerHighlightItemColor;
this.mainToolbarBackgroundColor =
mainToolbarBackgroundColor ?? AppTheme.mainToolbarBackgroundColor;
this.mainToolbarIconColor =
mainToolbarIconColor ?? AppTheme.mainToolbarIconColor;
this.navigationToolbarBackgroundColor = navigationToolbarBackgroundColor ??
AppTheme.navigationToolbarBackgroundColor;
this.navigationToolbarIconColor =
navigationToolbarIconColor ?? AppTheme.navigationToolbarIconColor;
}
const ColorSettings({
this.boardLineColor = const Color(0x996D000D),
this.darkBackgroundColor = UIColors.crusoe,
this.boardBackgroundColor = UIColors.burlyWood,
this.whitePieceColor = UIColors.white,
this.blackPieceColor = const Color(0xFF000000),
this.pieceHighlightColor = Colors.red,
this.messageColor = Colors.white,
this.drawerColor = Colors.white,
this.drawerBackgroundColor = const Color(0x80EDF0F2),
this.drawerTextColor = UIColors.nearlyBlack,
this.drawerHighlightItemColor = const Color(0x3309f911),
this.mainToolbarBackgroundColor = UIColors.burlyWood,
this.mainToolbarIconColor = const Color(0x99461220),
this.navigationToolbarBackgroundColor = UIColors.burlyWood,
this.navigationToolbarIconColor = const Color(0x99461220),
});
@JsonKey(
fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson,
)
@HiveField(0)
late final Color boardLineColor;
final Color boardLineColor;
@JsonKey(
fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson,
)
@HiveField(1)
late final Color darkBackgroundColor;
final Color darkBackgroundColor;
@JsonKey(
fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson,
)
@HiveField(2)
late final Color boardBackgroundColor;
final Color boardBackgroundColor;
@JsonKey(
fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson,
)
@HiveField(3)
late final Color whitePieceColor;
final Color whitePieceColor;
@JsonKey(
fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson,
)
@HiveField(4)
late final Color blackPieceColor;
final Color blackPieceColor;
@JsonKey(
fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson,
)
@HiveField(5)
late final Color pieceHighlightColor;
final Color pieceHighlightColor;
@JsonKey(
fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson,
)
@HiveField(6)
late final Color messageColor;
final Color messageColor;
@JsonKey(
fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson,
)
@HiveField(7)
late final Color drawerColor;
final Color drawerColor;
@JsonKey(
fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson,
)
@HiveField(8)
late final Color drawerBackgroundColor;
final Color drawerBackgroundColor;
@JsonKey(
fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson,
)
@HiveField(9)
late final Color drawerTextColor;
final Color drawerTextColor;
@JsonKey(
fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson,
)
@HiveField(10)
late final Color drawerHighlightItemColor;
final Color drawerHighlightItemColor;
@JsonKey(
fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson,
)
@HiveField(11)
late final Color mainToolbarBackgroundColor;
final Color mainToolbarBackgroundColor;
@JsonKey(
fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson,
)
@HiveField(12)
late final Color mainToolbarIconColor;
final Color mainToolbarIconColor;
@JsonKey(
fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson,
)
@HiveField(13)
late final Color navigationToolbarBackgroundColor;
final Color navigationToolbarBackgroundColor;
@JsonKey(
fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson,
)
@HiveField(14)
late final Color navigationToolbarIconColor;
final Color navigationToolbarIconColor;
/// encodes a Json style map Color a [ColorSettings] object
factory ColorSettings.fromJson(Map<String, dynamic> json) =>

View File

@ -21,7 +21,6 @@ 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';
import 'package:sanmill/shared/constants.dart';
part 'display.g.dart';
@ -33,7 +32,7 @@ part 'display.g.dart';
@CopyWith(generateCopyWithNull: true)
@immutable
class Display {
Display({
const Display({
this.languageCode,
this.standardNotationEnabled = true,
this.isPieceCountInHandShown = true,
@ -45,11 +44,9 @@ class Display {
this.pointWidth = 10.0,
this.pieceWidth = 0.9,
this.fontSize = 16.0,
double? boardTop,
this.boardTop = 36.0,
this.animationDuration = 0.0,
}) {
this.boardTop = boardTop ?? (isLargeScreen ? 75.0 : 36.0);
}
});
/// the uses locale
@HiveField(0)
@ -90,7 +87,7 @@ class Display {
final double fontSize;
@HiveField(11)
late final double boardTop;
final double boardTop;
@HiveField(12)
final double animationDuration;

View File

@ -29,6 +29,7 @@ import 'package:sanmill/shared/constants.dart';
import 'package:sanmill/shared/custom_drawer/custom_drawer.dart';
import 'package:sanmill/shared/list_item_divider.dart';
import 'package:sanmill/shared/settings/settings_list_tile.dart';
import 'package:sanmill/shared/sized_spacer.dart';
import 'package:sanmill/shared/theme/app_theme.dart';
import 'package:url_launcher/url_launcher.dart';
@ -250,20 +251,17 @@ class _VersionDialog extends StatelessWidget {
return AlertDialog(
title: Text(
S.of(context).appName,
style: const TextStyle(color: AppTheme.dialogTitleColor),
style: AppTheme.dialogTitleTextStyle,
),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text("${S.of(context).version}: $version"),
const SizedBox(height: AppTheme.sizedBoxHeight),
const SizedBox(height: AppTheme.sizedBoxHeight),
Text(S.of(context).version(version)),
const CustomSpacer(),
Text(
S.of(context).copyright,
style: TextStyle(
fontSize: AppTheme.copyrightFontSize,
),
style: AppTheme.copyrightTextStyle,
),
],
),
@ -294,7 +292,7 @@ class _VersionDialog extends StatelessWidget {
return AlertDialog(
title: Text(
S.of(context).more,
style: const TextStyle(color: AppTheme.dialogTitleColor),
style: AppTheme.dialogTitleTextStyle,
),
content: Column(
mainAxisSize: MainAxisSize.min,

View File

@ -20,6 +20,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:sanmill/generated/assets/assets.gen.dart';
import 'package:sanmill/generated/intl/l10n.dart';
import 'package:sanmill/shared/theme/app_theme.dart';
class EnvironmentVariablesPage extends StatelessWidget {
const EnvironmentVariablesPage({Key? key}) : super(key: key);
@ -44,7 +45,7 @@ class EnvironmentVariablesPage extends StatelessWidget {
padding: const EdgeInsets.all(16),
child: Text(
_data,
style: const TextStyle(fontFamily: 'Monospace', fontSize: 12),
style: AppTheme.licenseTextStyle,
textAlign: TextAlign.left,
),
),

View File

@ -18,7 +18,7 @@
part of 'package:sanmill/screens/game_page/game_page.dart';
typedef BoardTapCallback = dynamic Function(int index);
typedef BoardTapCallback = Future<void> Function(int index);
class Board extends StatelessWidget {
final double width;
@ -36,9 +36,9 @@ class Board extends StatelessWidget {
@override
Widget build(BuildContext context) {
final padding = AppTheme.boardPadding;
const padding = AppTheme.boardPadding;
buildSquareDescription(context);
_buildSquareDescription(context);
final grid = GridView(
scrollDirection: Axis.horizontal,
@ -51,7 +51,7 @@ class Board extends StatelessWidget {
child: Text(
squareDesc[index],
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
// TODO: [Leptopoda] instead of making it transparent when not needed we should not show it in the first place
color: LocalDatabaseService.preferences.developerMode
? Colors.red
: Colors.transparent,
@ -84,14 +84,8 @@ class Board extends StatelessWidget {
);
return GestureDetector(
/*
child: Semantics(
label: S.of(context).board,
child: boardContainer,
),
*/
child: boardContainer,
onTapUp: (d) {
onTapUp: (d) async {
final gridWidth = width - padding * 2;
final squareWidth = gridWidth / 7;
final dx = d.localPosition.dx;
@ -113,12 +107,12 @@ class Board extends StatelessWidget {
debugPrint("$_tag Tap on ($row, $column) <$index>");
onBoardTap(index);
await onBoardTap(index);
},
);
}
void buildSquareDescription(BuildContext context) {
void _buildSquareDescription(BuildContext context) {
final List<String> coordinates = [];
final List<String> pieceDesc = [];
@ -263,22 +257,18 @@ class Board extends StatelessWidget {
switch (gameInstance.position.pieceOnGrid(i)) {
case PieceColor.white:
pieceDesc.add(S.of(context).whitePiece);
break;
case PieceColor.black:
pieceDesc.add(S.of(context).blackPiece);
break;
case PieceColor.ban:
pieceDesc.add(S.of(context).banPoint);
break;
case PieceColor.none:
pieceDesc.add(S.of(context).emptyPoint);
break;
default:
assert(false);
}
}
}

View File

@ -1,3 +1,5 @@
// ignore_for_file: use_build_context_synchronously, avoid_positional_boolean_parameters
/*
This file is part of Sanmill.
Copyright (C) 2019-2021 The Sanmill developers (see AUTHORS file)
@ -32,9 +34,11 @@ import 'package:sanmill/services/audios.dart';
import 'package:sanmill/services/engine/engine.dart';
import 'package:sanmill/services/engine/native_engine.dart';
import 'package:sanmill/services/storage/storage.dart';
import 'package:sanmill/shared/constants.dart';
import 'package:sanmill/shared/custom_drawer/custom_drawer.dart';
import 'package:sanmill/shared/dialog.dart';
import 'package:sanmill/shared/picker.dart';
import 'package:sanmill/shared/number_picker.dart';
import 'package:sanmill/shared/sized_spacer.dart';
import 'package:sanmill/shared/snackbar.dart';
import 'package:sanmill/shared/theme/app_theme.dart';
import 'package:stack_trace/stack_trace.dart';
@ -45,12 +49,13 @@ part 'package:sanmill/shared/painters/board_painter.dart';
part 'package:sanmill/shared/painters/painter_base.dart';
part 'package:sanmill/shared/painters/pieces_painter.dart';
// TODO: [Leptopoda] remove variables that are not part of an object
double boardWidth = 0.0;
class GamePage extends StatefulWidget {
final EngineType engineType;
// TODO: use gameInstance.engineType
// TODO: [Leptopoda] use gameInstance.engineType
const GamePage(this.engineType, {Key? key}) : super(key: key);
@override
@ -64,7 +69,7 @@ class _GamePageState extends State<GamePage>
double screenPaddingH = AppTheme.boardScreenPaddingH;
final double boardMargin = AppTheme.boardMargin;
String? _tip = '';
late String _tip;
bool isReady = false;
bool isGoingToHistory = false;
late Timer timer;
@ -120,43 +125,36 @@ class _GamePageState extends State<GamePage>
}
}
void showTip(String? tip) {
void showTip(String tip) {
if (!mounted) return;
if (tip != null) {
debugPrint("[tip] $tip");
if (LocalDatabaseService.preferences.screenReaderSupport) {
//showSnackBar(context, tip);
}
}
setState(() => _tip = tip);
}
void showTips() {
if (!mounted) {
return;
}
if (!mounted) return;
final winner = gameInstance.position.winner;
final Map<String, String> colorWinStrings = {
PieceColor.white: S.of(context).whiteWin,
PieceColor.black: S.of(context).blackWin,
PieceColor.draw: S.of(context).isDraw
};
if (winner == PieceColor.nobody) {
if (gameInstance.position.phase == Phase.placing) {
if (mounted) {
showTip(S.of(context).tipPlace);
}
} else if (gameInstance.position.phase == Phase.moving) {
if (mounted) {
showTip(S.of(context).tipMove);
}
}
} else {
if (mounted) {
showTip(colorWinStrings[winner]);
switch (winner) {
case PieceColor.white:
return showTip(S.of(context).whiteWin);
case PieceColor.black:
return showTip(S.of(context).blackWin);
case PieceColor.draw:
return showTip(S.of(context).isDraw);
case PieceColor.nobody:
switch (gameInstance.position.phase) {
case Phase.placing:
return showTip(S.of(context).tipPlace);
case Phase.moving:
return showTip(S.of(context).tipMove);
default:
}
}
@ -194,9 +192,6 @@ class _GamePageState extends State<GamePage>
}
// If nobody has placed, start to go.
// TODO
// WAR: Fix first tap response slow when piece count changed
if (position.phase == Phase.placing &&
position.pieceOnBoardCount[PieceColor.white] == 0 &&
position.pieceOnBoardCount[PieceColor.black] == 0) {
@ -255,7 +250,7 @@ class _GamePageState extends State<GamePage>
final side = gameInstance.sideToMove == PieceColor.white
? S.of(context).black
: S.of(context).white;
showTip(side + S.of(context).tipToMove);
showTip(S.of(context).tipToMove(side));
}
}
}
@ -392,7 +387,7 @@ class _GamePageState extends State<GamePage>
? S.of(context).black
: S.of(context).white;
if (mounted) {
showTip(them + S.of(context).tipToMove);
showTip(S.of(context).tipToMove(them));
}
}
}
@ -540,9 +535,8 @@ class _GamePageState extends State<GamePage>
if (LocalDatabaseService.preferences.screenReaderSupport &&
gameInstance.position.action != Act.remove &&
m != null &&
m.notation != null) {
showSnackBar(context, "${S.of(context).human}: ${m.notation!}");
m?.notation != null) {
showSnackBar(context, "${S.of(context).human}: ${m!.notation!}");
}
}
}
@ -592,14 +586,9 @@ class _GamePageState extends State<GamePage>
showSnackBar(context, S.of(context).timeout);
}
}
//if (LocalDatabaseService.developerMode) {
//assert(false);
//}
return;
default:
showTip('Error: ${response.type}');
break;
showTip(S.of(context).error(response.type));
}
if (LocalDatabaseService.preferences.isAutoRestart == true &&
@ -654,10 +643,10 @@ class _GamePageState extends State<GamePage>
final importFailedStr = gameInstance.position.recorder.import(text);
if (importFailedStr != "") {
showTip("${S.of(context).cannotImport} $importFailedStr");
showTip(S.of(context).cannotImport(importFailedStr));
if (LocalDatabaseService.preferences.screenReaderSupport) {
ScaffoldMessenger.of(context).clearSnackBars();
showSnackBar(context, "${S.of(context).cannotImport} $importFailedStr");
showSnackBar(context, S.of(context).cannotImport(importFailedStr));
}
return;
}
@ -706,7 +695,7 @@ class _GamePageState extends State<GamePage>
textAlign: TextAlign.center,
),
),
const SizedBox(height: AppTheme.sizedBoxHeight),
const CustomSpacer(),
SimpleDialogOption(
onPressed: onImportGameButtonPressed,
child: Text(
@ -715,7 +704,7 @@ class _GamePageState extends State<GamePage>
textAlign: TextAlign.center,
),
),
const SizedBox(height: AppTheme.sizedBoxHeight),
const CustomSpacer(),
SimpleDialogOption(
onPressed: onExportGameButtonPressed,
child: Text(
@ -724,7 +713,7 @@ class _GamePageState extends State<GamePage>
textAlign: TextAlign.center,
),
),
const SizedBox(height: AppTheme.sizedBoxHeight),
const CustomSpacer(),
if (LocalDatabaseService.preferences.screenReaderSupport)
SimpleDialogOption(
child: Text(
@ -755,7 +744,7 @@ class _GamePageState extends State<GamePage>
textAlign: TextAlign.center,
),
),
const SizedBox(height: AppTheme.sizedBoxHeight),
const CustomSpacer(),
SimpleDialogOption(
onPressed: onStepForwardButtonPressed,
child: Text(
@ -764,7 +753,7 @@ class _GamePageState extends State<GamePage>
textAlign: TextAlign.center,
),
),
const SizedBox(height: AppTheme.sizedBoxHeight),
const CustomSpacer(),
SimpleDialogOption(
onPressed: onTakeBackAllButtonPressed,
child: Text(
@ -773,7 +762,7 @@ class _GamePageState extends State<GamePage>
textAlign: TextAlign.center,
),
),
const SizedBox(height: AppTheme.sizedBoxHeight),
const CustomSpacer(),
SimpleDialogOption(
onPressed: onStepForwardAllButtonPressed,
child: Text(
@ -782,13 +771,13 @@ class _GamePageState extends State<GamePage>
textAlign: TextAlign.center,
),
),
const SizedBox(height: AppTheme.sizedBoxHeight),
const CustomSpacer(),
];
showModalBottomSheet(
context: context,
backgroundColor: Colors.transparent,
builder: (context) => Semantics(
label: S.of(context).move,
label: S.of(context).move_number(0),
child: SimpleDialog(
backgroundColor: Colors.transparent,
children: <Widget>[
@ -802,7 +791,7 @@ class _GamePageState extends State<GamePage>
textAlign: TextAlign.center,
),
),
const SizedBox(height: AppTheme.sizedBoxHeight),
const CustomSpacer(),
SimpleDialogOption(
onPressed: onMoveNowButtonPressed,
child: Text(
@ -811,7 +800,7 @@ class _GamePageState extends State<GamePage>
textAlign: TextAlign.center,
),
),
const SizedBox(height: AppTheme.sizedBoxHeight),
const CustomSpacer(),
if (LocalDatabaseService.preferences.screenReaderSupport)
SimpleDialogOption(
child: Text(
@ -873,8 +862,8 @@ class _GamePageState extends State<GamePage>
late final String text;
final lastEffectiveMove = pos.recorder.lastEffectiveMove;
if (lastEffectiveMove != null && lastEffectiveMove.notation != null) {
text = "${S.of(context).lastMove}: ${lastEffectiveMove.notation}";
if (lastEffectiveMove?.notation != null) {
text = S.of(context).lastMove(lastEffectiveMove!.notation!);
} else {
text = S.of(context).atEnd;
}
@ -934,10 +923,7 @@ class _GamePageState extends State<GamePage>
backgroundColor: AppTheme.moveHistoryDialogBackgroundColor,
title: Text(
S.of(context).moveList,
style: TextStyle(
color: AppTheme.moveHistoryTextColor,
fontSize: LocalDatabaseService.display.fontSize + 2.0,
),
style: AppTheme.moveHistoryTextStyle,
),
content: SingleChildScrollView(
child: Text(
@ -954,15 +940,12 @@ class _GamePageState extends State<GamePage>
style: AppTheme.moveHistoryTextStyle,
),
onPressed: () async {
final int selectValue = await showPickerNumber(
context,
1,
end,
1,
S.of(context).moves,
final selectValue = await showDialog<int?>(
context: context,
builder: (context) => NumberPicker(end: end),
);
if (selectValue != 0) {
if (selectValue != null) {
onTakeBackNButtonPressed(selectValue);
}
},
@ -1042,14 +1025,13 @@ class _GamePageState extends State<GamePage>
final Map<GameOverReason, String> reasonMap = {
GameOverReason.loseReasonlessThanThree:
loserStr + S.of(context).loseReasonlessThanThree,
GameOverReason.loseReasonResign:
loserStr + S.of(context).loseReasonResign,
GameOverReason.loseReasonNoWay: loserStr + S.of(context).loseReasonNoWay,
S.of(context).loseReasonlessThanThree(loserStr),
GameOverReason.loseReasonResign: S.of(context).loseReasonResign(loserStr),
GameOverReason.loseReasonNoWay: S.of(context).loseReasonNoWay(loserStr),
GameOverReason.loseReasonBoardIsFull:
loserStr + S.of(context).loseReasonBoardIsFull,
S.of(context).loseReasonBoardIsFull(loserStr),
GameOverReason.loseReasonTimeOver:
loserStr + S.of(context).loseReasonTimeOver,
S.of(context).loseReasonTimeOver(loserStr),
GameOverReason.drawReasonRule50: S.of(context).drawReasonRule50,
GameOverReason.drawReasonEndgameRule50:
S.of(context).drawReasonEndgameRule50,
@ -1103,23 +1085,11 @@ class _GamePageState extends State<GamePage>
return GameResult.none;
}
// TODO: [Leptopoda] deduplicate the code
void showGameResult(String winner) {
final GameResult result = getGameResult(winner);
gameInstance.position.result = result;
switch (result) {
case GameResult.win:
//Audios.playTone(Audios.win);
break;
case GameResult.lose:
//Audios.playTone(Audios.lose);
break;
case GameResult.draw:
break;
default:
break;
}
final Map<GameResult, String> retMap = {
GameResult.win: gameInstance.engineType == EngineType.humanVsAi
? S.of(context).youWin
@ -1130,9 +1100,7 @@ class _GamePageState extends State<GamePage>
final dialogTitle = retMap[result];
if (dialogTitle == null) {
return;
}
if (dialogTitle == null) return;
final bool isTopLevel =
LocalDatabaseService.preferences.skillLevel == 30; // TODO: 30
@ -1140,14 +1108,21 @@ class _GamePageState extends State<GamePage>
if (result == GameResult.win &&
!isTopLevel &&
gameInstance.engineType == EngineType.humanVsAi) {
var contentStr = getGameOverReasonString(
final contentStr = StringBuffer(
getGameOverReasonString(
gameInstance.position.gameOverReason,
gameInstance.position.winner,
),
);
if (!isTopLevel) {
contentStr +=
"\n\n${S.of(context).challengeHarderLevel}${LocalDatabaseService.preferences.skillLevel + 1}!";
contentStr.writeln();
contentStr.writeln();
contentStr.writeln(
S.of(context).challengeHarderLevel(
LocalDatabaseService.preferences.skillLevel + 1,
),
);
}
showDialog(
@ -1157,24 +1132,13 @@ class _GamePageState extends State<GamePage>
return AlertDialog(
title: Text(
dialogTitle,
style: TextStyle(
color: AppTheme.dialogTitleColor,
fontSize: LocalDatabaseService.display.fontSize + 4,
),
),
content: Text(
contentStr,
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
),
style: AppTheme.dialogTitleTextStyle,
),
content: Text(contentStr.toString()),
actions: <Widget>[
TextButton(
child: Text(
S.of(context).yes,
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
),
),
onPressed: () async {
if (!isTopLevel) {
@ -1189,12 +1153,7 @@ class _GamePageState extends State<GamePage>
},
),
TextButton(
child: Text(
S.of(context).no,
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
),
),
child: Text(S.of(context).no),
onPressed: () => Navigator.pop(context),
),
],
@ -1209,28 +1168,17 @@ class _GamePageState extends State<GamePage>
return AlertDialog(
title: Text(
dialogTitle,
style: TextStyle(
color: AppTheme.dialogTitleColor,
fontSize: LocalDatabaseService.display.fontSize + 4,
),
style: AppTheme.dialogTitleTextStyle,
),
content: Text(
getGameOverReasonString(
gameInstance.position.gameOverReason,
gameInstance.position.winner,
),
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
),
),
actions: <Widget>[
TextButton(
child: Text(
S.of(context).restart,
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
),
),
child: Text(S.of(context).restart),
onPressed: () {
Navigator.pop(context);
gameInstance.newGame();
@ -1249,12 +1197,7 @@ class _GamePageState extends State<GamePage>
},
),
TextButton(
child: Text(
S.of(context).cancel,
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
),
),
child: Text(S.of(context).cancel),
onPressed: () => Navigator.pop(context),
),
],
@ -1265,13 +1208,12 @@ class _GamePageState extends State<GamePage>
}
double get _screenPaddingH {
//
// when screen's height/width rate is less than 16/9, limit width of board
final windowSize = MediaQuery.of(context).size;
final double height = windowSize.height;
double width = windowSize.width;
// TODO: maybe use windowSize.aspectRatio
// TODO: [Leptopoda] maybe use windowSize.aspectRatio
if (height / width < 16.0 / 9.0) {
width = height * 9 / 16;
return (windowSize.width - width) / 2 - AppTheme.boardMargin;
@ -1315,7 +1257,10 @@ class _GamePageState extends State<GamePage>
);
return Container(
margin: EdgeInsets.only(top: LocalDatabaseService.display.boardTop),
margin: EdgeInsets.only(
top: LocalDatabaseService.display.boardTop +
(isLargeScreen ? 39.0 : 0.0),
),
child: Column(
children: <Widget>[
iconRow,
@ -1331,14 +1276,13 @@ class _GamePageState extends State<GamePage>
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: Text(
_tip!,
_tip,
maxLines: 1,
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
color: LocalDatabaseService.colorSettings.messageColor,
),
),
), // TODO: Font Size
),
],
),
);
@ -1385,76 +1329,100 @@ class _GamePageState extends State<GamePage>
}
String get infoText {
String phase = "";
final String period =
LocalDatabaseService.preferences.screenReaderSupport ? "." : "";
final String comma =
LocalDatabaseService.preferences.screenReaderSupport ? "," : "";
final buffer = StringBuffer();
final pos = gameInstance.position;
late final String us;
late final String them;
switch (pos.side) {
case PieceColor.white:
us = S.of(context).player1;
them = S.of(context).player2;
break;
case PieceColor.black:
us = S.of(context).player2;
them = S.of(context).player1;
break;
default:
assert(false);
}
switch (pos.phase) {
case Phase.placing:
phase = S.of(context).placingPhase;
buffer.writeln(S.of(context).placingPhase);
break;
case Phase.moving:
phase = S.of(context).movingPhase;
buffer.writeln(S.of(context).movingPhase);
break;
default:
break;
}
final String pieceCountInHand = pos.phase == Phase.placing
? "${S.of(context).player1} ${S.of(context).inHand}: ${pos.pieceInHandCount[PieceColor.white]}$comma\n${S.of(context).player2} ${S.of(context).inHand}: ${pos.pieceInHandCount[PieceColor.black]}$comma\n"
: "";
String us = "";
String them = "";
if (pos.side == PieceColor.white) {
us = S.of(context).player1;
them = S.of(context).player2;
} else if (pos.side == PieceColor.black) {
us = S.of(context).player2;
them = S.of(context).player1;
}
final String tip =
(_tip == null || !LocalDatabaseService.preferences.screenReaderSupport)
? ""
: "\n$_tip";
String lastMove = "";
// last Move information
if (pos.recorder.lastMove?.notation != null) {
final String n1 = pos.recorder.lastMove!.notation!;
// TODO: [Leptopdoa] why is $them only shown with the screen reader?
if (LocalDatabaseService.preferences.screenReaderSupport) {
buffer.write(S.of(context).lastMove("$them, "));
} else {
buffer.write(S.of(context).lastMove(""));
}
if (n1.startsWith("x")) {
final String n2 =
pos.recorder.moveAt(pos.recorder.movesCount - 2).notation!;
lastMove = n2 + n1;
} else {
lastMove = n1;
}
if (LocalDatabaseService.preferences.screenReaderSupport) {
lastMove = "${S.of(context).lastMove}: $them, $lastMove$period\n";
} else {
lastMove = "${S.of(context).lastMove}: $lastMove$period\n";
buffer.writeln(
pos.recorder.moveAt(pos.recorder.movesCount - 2).notation,
);
}
buffer.writePeriod(n1);
}
String addedPeriod = "";
buffer.writePeriod(S.of(context).sideToMove(us));
// the tip
if (LocalDatabaseService.preferences.screenReaderSupport &&
tip.isNotEmpty &&
tip[tip.length - 1] != '.' &&
tip[tip.length - 1] != '!') {
addedPeriod = ".";
_tip[_tip.length - 1] != '.' &&
_tip[_tip.length - 1] != '!') {
buffer.writePeriod(_tip);
}
final String ret =
"$phase$period\n$lastMove${S.of(context).sideToMove}: $us$period$tip$addedPeriod\n\n${S.of(context).pieceCount}:\n$pieceCountInHand${S.of(context).player1} ${S.of(context).onBoard}: ${pos.pieceOnBoardCount[PieceColor.white]}$comma\n${S.of(context).player2} ${S.of(context).onBoard}: ${pos.pieceOnBoardCount[PieceColor.black]}$period\n\n${S.of(context).score}:\n${S.of(context).player1}: ${pos.score[PieceColor.white]}$comma\n${S.of(context).player2}: ${pos.score[PieceColor.black]}$comma\n${S.of(context).draw}: ${pos.score[PieceColor.draw]}$period";
return ret;
buffer.writeln();
buffer.writeln(S.of(context).pieceCount);
buffer.writeComma(
S.of(context).inHand(
S.of(context).player1,
pos.pieceInHandCount[PieceColor.white]!,
),
);
buffer.writeComma(
S.of(context).inHand(
S.of(context).player2,
pos.pieceInHandCount[PieceColor.black]!,
),
);
buffer.writeComma(
S.of(context).onBoard(
S.of(context).player1,
pos.pieceOnBoardCount[PieceColor.white]!,
),
);
buffer.writePeriod(
S.of(context).onBoard(
S.of(context).player2,
pos.pieceOnBoardCount[PieceColor.black]!,
),
);
buffer.writeln();
buffer.writeln(S.of(context).score);
buffer
.writeComma("${S.of(context).player1}: ${pos.score[PieceColor.white]}");
buffer
.writeComma("${S.of(context).player2}: ${pos.score[PieceColor.black]}");
buffer.writePeriod("${S.of(context).draw}: ${pos.score[PieceColor.draw]}");
return buffer.toString();
}
Widget get toolbar {
final _iconColor = LocalDatabaseService.colorSettings.mainToolbarIconColor;
final gameButton = TextButton(
onPressed: onGameButtonPressed,
child: Column(
@ -1462,13 +1430,11 @@ class _GamePageState extends State<GamePage>
children: <Widget>[
Icon(
FluentIcons.table_simple_24_regular,
color: LocalDatabaseService.colorSettings.mainToolbarIconColor,
color: _iconColor,
),
Text(
S.of(context).game,
style: TextStyle(
color: LocalDatabaseService.colorSettings.mainToolbarIconColor,
),
style: AppTheme.mainToolbarTextStyle,
),
],
),
@ -1481,13 +1447,11 @@ class _GamePageState extends State<GamePage>
children: <Widget>[
Icon(
FluentIcons.settings_24_regular,
color: LocalDatabaseService.colorSettings.mainToolbarIconColor,
color: _iconColor,
),
Text(
S.of(context).options,
style: TextStyle(
color: LocalDatabaseService.colorSettings.mainToolbarIconColor,
),
style: AppTheme.mainToolbarTextStyle,
),
],
),
@ -1500,13 +1464,11 @@ class _GamePageState extends State<GamePage>
children: <Widget>[
Icon(
FluentIcons.calendar_agenda_24_regular,
color: LocalDatabaseService.colorSettings.mainToolbarIconColor,
color: _iconColor,
),
Text(
S.of(context).move,
style: TextStyle(
color: LocalDatabaseService.colorSettings.mainToolbarIconColor,
),
S.of(context).move_number(0),
style: AppTheme.mainToolbarTextStyle,
),
],
),
@ -1519,13 +1481,11 @@ class _GamePageState extends State<GamePage>
children: <Widget>[
Icon(
FluentIcons.book_information_24_regular,
color: LocalDatabaseService.colorSettings.mainToolbarIconColor,
color: _iconColor,
),
Text(
S.of(context).info,
style: TextStyle(
color: LocalDatabaseService.colorSettings.mainToolbarIconColor,
),
style: AppTheme.mainToolbarTextStyle,
),
],
),
@ -1542,7 +1502,11 @@ class _GamePageState extends State<GamePage>
);
}
// TODO: [Leptopoda] why is Theme() or IconTheme() not working ¿? (even with a builder)
Widget get historyNavToolbar {
final _iconColor =
LocalDatabaseService.colorSettings.navigationToolbarIconColor;
final takeBackAllButton = TextButton(
child: Semantics(
label: S.of(context).takeBackAll,
@ -1550,7 +1514,7 @@ class _GamePageState extends State<GamePage>
ltr
? FluentIcons.arrow_previous_24_regular
: FluentIcons.arrow_next_24_regular,
color: LocalDatabaseService.colorSettings.navigationToolbarIconColor,
color: _iconColor,
),
),
onPressed: () => onTakeBackAllButtonPressed(false),
@ -1563,7 +1527,7 @@ class _GamePageState extends State<GamePage>
ltr
? FluentIcons.chevron_left_24_regular
: FluentIcons.chevron_right_24_regular,
color: LocalDatabaseService.colorSettings.navigationToolbarIconColor,
color: _iconColor,
),
),
onPressed: () async => onTakeBackButtonPressed(false),
@ -1576,7 +1540,7 @@ class _GamePageState extends State<GamePage>
ltr
? FluentIcons.chevron_right_24_regular
: FluentIcons.chevron_left_24_regular,
color: LocalDatabaseService.colorSettings.navigationToolbarIconColor,
color: _iconColor,
),
),
onPressed: () async => onStepForwardButtonPressed(false),
@ -1589,13 +1553,17 @@ class _GamePageState extends State<GamePage>
ltr
? FluentIcons.arrow_next_24_regular
: FluentIcons.arrow_previous_24_regular,
color: LocalDatabaseService.colorSettings.navigationToolbarIconColor,
color: _iconColor,
),
),
onPressed: () async => onStepForwardAllButtonPressed(false),
);
return GamePageToolBar(
return IconTheme(
data: IconThemeData(
color: LocalDatabaseService.colorSettings.navigationToolbarIconColor,
),
child: GamePageToolBar(
color:
LocalDatabaseService.colorSettings.navigationToolbarBackgroundColor,
children: <Widget>[
@ -1604,6 +1572,7 @@ class _GamePageState extends State<GamePage>
stepForwardButton,
stepForwardAllButton,
],
),
);
}
@ -1637,20 +1606,17 @@ class _GamePageState extends State<GamePage>
super.didChangeDependencies();
screenPaddingH = _screenPaddingH;
ltr = Directionality.of(context) == TextDirection.ltr;
_tip = S.of(context).welcome;
}
@override
Widget build(BuildContext context) {
if (_tip == '') {
_tip = S.of(context).welcome;
}
return Scaffold(
appBar: AppBar(
leading: DrawerIcon.of(context)?.icon,
backgroundColor: Colors.transparent,
elevation: 0.0,
iconTheme: IconThemeData(
iconTheme: const IconThemeData(
color: AppTheme.drawerAnimationIconColor,
),
),
@ -1681,3 +1647,21 @@ class _GamePageState extends State<GamePage>
super.dispose();
}
}
extension CustomStringBuffer on StringBuffer {
void writeComma([Object? obj = ""]) {
if (LocalDatabaseService.preferences.screenReaderSupport) {
writeln("$obj,");
} else {
writeln(obj);
}
}
void writePeriod([Object? obj = ""]) {
if (LocalDatabaseService.preferences.screenReaderSupport) {
writeln("$obj.");
} else {
writeln(obj);
}
}
}

View File

@ -36,21 +36,18 @@ class _AlgorithmModal extends StatelessWidget {
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,

View File

@ -31,6 +31,7 @@ import 'package:sanmill/shared/custom_drawer/custom_drawer.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/sized_spacer.dart';
import 'package:sanmill/shared/theme/app_theme.dart';
part 'package:sanmill/screens/game_settings/algorithm_modal.dart';
@ -162,7 +163,7 @@ class GameSettingsPage extends StatelessWidget {
)!;
final _widowsSettings = [
const SizedBox(height: AppTheme.sizedBoxHeight),
const CustomSpacer(),
Text(S.of(context).playSounds, style: AppTheme.settingsHeaderStyle),
SettingsCard(
children: <Widget>[
@ -181,7 +182,7 @@ class GameSettingsPage extends StatelessWidget {
];
final _developerSettings = [
const SizedBox(height: AppTheme.sizedBoxHeight),
const CustomSpacer(),
Text(S.of(context).forDevelopers, style: AppTheme.settingsHeaderStyle),
SettingsCard(
children: <Widget>[
@ -228,7 +229,7 @@ class GameSettingsPage extends StatelessWidget {
),
],
),
const SizedBox(height: AppTheme.sizedBoxHeight),
const CustomSpacer(),
Text(S.of(context).difficulty, style: AppTheme.settingsHeaderStyle),
SettingsCard(
children: <Widget>[
@ -243,7 +244,7 @@ class GameSettingsPage extends StatelessWidget {
),
],
),
const SizedBox(height: AppTheme.sizedBoxHeight),
const CustomSpacer(),
Text(S.of(context).aisPlayStyle, style: AppTheme.settingsHeaderStyle),
SettingsCard(
children: <Widget>[
@ -275,7 +276,7 @@ class GameSettingsPage extends StatelessWidget {
],
),
if (!Platform.isWindows) ..._widowsSettings,
const SizedBox(height: AppTheme.sizedBoxHeight),
const CustomSpacer(),
Text(S.of(context).accessibility, style: AppTheme.settingsHeaderStyle),
SettingsCard(
children: <Widget>[
@ -286,7 +287,7 @@ class GameSettingsPage extends StatelessWidget {
),
],
),
const SizedBox(height: AppTheme.sizedBoxHeight),
const CustomSpacer(),
Text(S.of(context).restore, style: AppTheme.settingsHeaderStyle),
SettingsCard(
children: <Widget>[

View File

@ -23,9 +23,7 @@ class _MoveTimeSlider extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SliderTheme(
data: AppTheme.sliderThemeData,
child: Semantics(
return Semantics(
label: S.of(context).moveTime,
child: ValueListenableBuilder(
valueListenable: LocalDatabaseService.listenPreferences,
@ -49,7 +47,6 @@ class _MoveTimeSlider extends StatelessWidget {
);
},
),
),
);
}
}

View File

@ -21,12 +21,12 @@ 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);
void _cancel(BuildContext context) => Navigator.pop(context);
Future<void> _restore(BuildContext context) async {
Navigator.pop(context);
// TODO: we should probably enable database deletion in monkey tests
// TODO: [Leptopoda] we should probably enable database deletion in monkey tests
//as the new storage backend supports deletion without needing an app restart
if (!EnvironmentConfig.monkeyTest) {
await LocalDatabaseService.resetStorage();
@ -35,43 +35,25 @@ class _ResetSettingsAlert extends StatelessWidget {
@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,
),
style: AppTheme.dialogTitleTextStyle,
),
content: SingleChildScrollView(
child: Text(
"${S.of(context).restoreDefaultSettings}?",
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
),
),
child: Text("${S.of(context).restoreDefaultSettings}?"),
),
actions: <Widget>[
TextButton(
onPressed: () => _restore(context),
child: Text(
S.of(context).ok,
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
),
),
),
TextButton(
onPressed: () => cancel(context),
onPressed: () => _cancel(context),
child: Text(
S.of(context).cancel,
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
),
),
),
],

View File

@ -23,9 +23,7 @@ class _SkillLevelSlider extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SliderTheme(
data: AppTheme.sliderThemeData,
child: Semantics(
return Semantics(
label: S.of(context).skillLevel,
child: ValueListenableBuilder(
valueListenable: LocalDatabaseService.listenPreferences,
@ -49,7 +47,6 @@ class _SkillLevelSlider extends StatelessWidget {
);
},
),
),
);
}
}

View File

@ -16,11 +16,9 @@ class HelpScreen extends StatelessWidget {
leading: DrawerIcon.of(context)?.icon,
title: Text(
S.of(context).howToPlay,
style: TextStyle(
color: AppTheme.helpTextColor,
style: AppTheme.helpTextStyle,
),
),
iconTheme: IconThemeData(
iconTheme: const IconThemeData(
color: AppTheme.helpTextColor,
),
),
@ -29,10 +27,7 @@ class HelpScreen extends StatelessWidget {
padding: const EdgeInsets.all(16),
child: Text(
S.of(context).helpContent,
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
color: AppTheme.helpTextColor,
),
style: AppTheme.helpTextStyle,
),
),
);

View File

@ -20,6 +20,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:sanmill/generated/assets/assets.gen.dart';
import 'package:sanmill/generated/intl/l10n.dart';
import 'package:sanmill/shared/theme/app_theme.dart';
class LicenseAgreementPage extends StatelessWidget {
@override
@ -42,7 +43,7 @@ class LicenseAgreementPage extends StatelessWidget {
padding: const EdgeInsets.all(16),
child: Text(
_data,
style: const TextStyle(fontFamily: 'Monospace', fontSize: 12),
style: AppTheme.licenseTextStyle,
textAlign: TextAlign.left,
),
),

View File

@ -23,16 +23,14 @@ class _AnimationDurationSlider extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SliderTheme(
data: AppTheme.sliderThemeData,
child: Semantics(
return Semantics(
label: S.of(context).animationDuration,
child: ValueListenableBuilder(
valueListenable: LocalDatabaseService.listenDisplay,
builder: (context, Box<Display> displayBox, _) {
final Display _display = displayBox.get(
LocalDatabaseService.colorSettingsKey,
defaultValue: Display(),
defaultValue: const Display(),
)!;
return Slider(
@ -48,7 +46,6 @@ class _AnimationDurationSlider extends StatelessWidget {
);
},
),
),
);
}
}

View File

@ -23,16 +23,14 @@ class _BoardBorderWidthSlider extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SliderTheme(
data: AppTheme.sliderThemeData,
child: Semantics(
return Semantics(
label: S.of(context).boardBorderLineWidth,
child: ValueListenableBuilder(
valueListenable: LocalDatabaseService.listenDisplay,
builder: (context, Box<Display> displayBox, _) {
final Display _display = displayBox.get(
LocalDatabaseService.colorSettingsKey,
defaultValue: Display(),
defaultValue: const Display(),
)!;
return Slider(
@ -48,7 +46,6 @@ class _BoardBorderWidthSlider extends StatelessWidget {
);
},
),
),
);
}
}

View File

@ -23,16 +23,14 @@ class _BoardInnerWidthSlider extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SliderTheme(
data: AppTheme.sliderThemeData,
child: Semantics(
return Semantics(
label: S.of(context).boardInnerLineWidth,
child: ValueListenableBuilder(
valueListenable: LocalDatabaseService.listenDisplay,
builder: (context, Box<Display> displayBox, _) {
final Display _display = displayBox.get(
LocalDatabaseService.colorSettingsKey,
defaultValue: Display(),
defaultValue: const Display(),
)!;
return Slider(
@ -48,7 +46,6 @@ class _BoardInnerWidthSlider extends StatelessWidget {
);
},
),
),
);
}
}

View File

@ -23,16 +23,14 @@ class _BoardTopSlider extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SliderTheme(
data: AppTheme.sliderThemeData,
child: Semantics(
return Semantics(
label: S.of(context).boardTop,
child: ValueListenableBuilder(
valueListenable: LocalDatabaseService.listenDisplay,
builder: (context, Box<Display> displayBox, _) {
final Display _display = displayBox.get(
LocalDatabaseService.colorSettingsKey,
defaultValue: Display(),
defaultValue: const Display(),
)!;
return Slider(
@ -42,13 +40,11 @@ class _BoardTopSlider extends StatelessWidget {
label: _display.boardTop.toStringAsFixed(1),
onChanged: (value) {
debugPrint("[config] AnimationDuration value: $value");
LocalDatabaseService.display =
_display.copyWith(boardTop: value);
LocalDatabaseService.display = _display.copyWith(boardTop: value);
},
);
},
),
),
);
}
}

View File

@ -83,10 +83,8 @@ class _ColorPickerAlertState extends State<_ColorPickerAlert> {
Widget build(BuildContext context) {
return AlertDialog(
title: Text(
"${S.of(context).pick} ${widget.title}",
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize + 4,
),
S.of(context).pick(widget.title),
style: AppTheme.dialogTitleTextStyle,
),
content: SingleChildScrollView(
child: ColorPicker(
@ -98,9 +96,6 @@ class _ColorPickerAlertState extends State<_ColorPickerAlert> {
TextButton(
child: Text(
S.of(context).confirm,
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
),
),
onPressed: () {
debugPrint("[config] pickerColor.value: ${pickedColor.value}");
@ -111,9 +106,6 @@ class _ColorPickerAlertState extends State<_ColorPickerAlert> {
TextButton(
child: Text(
S.of(context).cancel,
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
),
),
onPressed: () => Navigator.pop(context),
),

View File

@ -23,16 +23,14 @@ class _FontSizeSlider extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SliderTheme(
data: AppTheme.sliderThemeData,
child: Semantics(
return Semantics(
label: S.of(context).fontSize,
child: ValueListenableBuilder(
valueListenable: LocalDatabaseService.listenDisplay,
builder: (context, Box<Display> displayBox, _) {
final Display _display = displayBox.get(
LocalDatabaseService.colorSettingsKey,
defaultValue: Display(),
defaultValue: const Display(),
)!;
return Slider(
@ -43,13 +41,11 @@ class _FontSizeSlider extends StatelessWidget {
label: _display.fontSize.toStringAsFixed(1),
onChanged: (value) {
debugPrint("[config] fontSize value: $value");
LocalDatabaseService.display =
_display.copyWith(fontSize: value);
LocalDatabaseService.display = _display.copyWith(fontSize: value);
},
);
},
),
),
);
}
}

View File

@ -34,7 +34,6 @@ class _LanguagePicker extends StatelessWidget {
mainAxisSize: MainAxisSize.min,
children: <Widget>[
RadioListTile<Locale?>(
activeColor: AppTheme.switchListTileActiveColor,
title: Text(S.of(context).defaultLanguage),
groupValue: currentLocale,
value: null,
@ -43,7 +42,6 @@ class _LanguagePicker extends StatelessWidget {
const ListItemDivider(),
for (var i in languageCodeToStrings.keys)
RadioListTile<Locale>(
activeColor: AppTheme.switchListTileActiveColor,
title: Text(languageCodeToStrings[i]!),
groupValue: currentLocale,
value: i,

View File

@ -29,6 +29,7 @@ import 'package:sanmill/shared/list_item_divider.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/sized_spacer.dart';
import 'package:sanmill/shared/theme/app_theme.dart';
part 'package:sanmill/screens/personalization_settings/animation_duration_slider.dart';
@ -113,74 +114,74 @@ class PersonalizationSettingsPage extends StatelessWidget {
Widget _buildColor(BuildContext context, Box<ColorSettings> colorBox, _) {
final ColorSettings _colorSettings = colorBox.get(
LocalDatabaseService.colorSettingsKey,
defaultValue: ColorSettings(),
defaultValue: const ColorSettings(),
)!;
return SettingsCard(
children: <Widget>[
_ColorSelectorListTile(
title: S.of(context).boardColor,
value: _colorSettings.boardBackgroundColor,
value: LocalDatabaseService.colorSettings.boardBackgroundColor,
onChanged: (val) => LocalDatabaseService.colorSettings =
_colorSettings.copyWith(boardBackgroundColor: val),
),
_ColorSelectorListTile(
title: S.of(context).backgroundColor,
value: _colorSettings.darkBackgroundColor,
value: LocalDatabaseService.colorSettings.darkBackgroundColor,
onChanged: (val) => LocalDatabaseService.colorSettings =
_colorSettings.copyWith(darkBackgroundColor: val),
),
_ColorSelectorListTile(
title: S.of(context).lineColor,
value: _colorSettings.boardLineColor,
value: LocalDatabaseService.colorSettings.boardLineColor,
onChanged: (val) => LocalDatabaseService.colorSettings =
_colorSettings.copyWith(boardLineColor: val),
),
_ColorSelectorListTile(
title: S.of(context).whitePieceColor,
value: _colorSettings.whitePieceColor,
value: LocalDatabaseService.colorSettings.whitePieceColor,
onChanged: (val) => LocalDatabaseService.colorSettings =
_colorSettings.copyWith(whitePieceColor: val),
),
_ColorSelectorListTile(
title: S.of(context).blackPieceColor,
value: _colorSettings.blackPieceColor,
value: LocalDatabaseService.colorSettings.blackPieceColor,
onChanged: (val) => LocalDatabaseService.colorSettings =
_colorSettings.copyWith(blackPieceColor: val),
),
_ColorSelectorListTile(
title: S.of(context).pieceHighlightColor,
value: _colorSettings.pieceHighlightColor,
value: LocalDatabaseService.colorSettings.pieceHighlightColor,
onChanged: (val) => LocalDatabaseService.colorSettings =
_colorSettings.copyWith(pieceHighlightColor: val),
),
_ColorSelectorListTile(
title: S.of(context).messageColor,
value: _colorSettings.messageColor,
value: LocalDatabaseService.colorSettings.messageColor,
onChanged: (val) => LocalDatabaseService.colorSettings =
_colorSettings.copyWith(messageColor: val),
),
_ColorSelectorListTile(
title: S.of(context).drawerColor,
value: _colorSettings.drawerColor,
value: LocalDatabaseService.colorSettings.drawerColor,
onChanged: (val) => LocalDatabaseService.colorSettings =
_colorSettings.copyWith(drawerColor: val),
),
_ColorSelectorListTile(
title: S.of(context).drawerBackgroundColor,
value: _colorSettings.drawerBackgroundColor,
value: LocalDatabaseService.colorSettings.drawerBackgroundColor,
onChanged: (val) => LocalDatabaseService.colorSettings =
_colorSettings.copyWith(drawerBackgroundColor: val),
),
_ColorSelectorListTile(
title: S.of(context).drawerTextColor,
value: _colorSettings.drawerTextColor,
value: LocalDatabaseService.colorSettings.drawerTextColor,
onChanged: (val) => LocalDatabaseService.colorSettings =
_colorSettings.copyWith(drawerTextColor: val),
),
_ColorSelectorListTile(
title: S.of(context).drawerHighlightItemColor,
value: _colorSettings.drawerHighlightItemColor,
value: LocalDatabaseService.colorSettings.drawerHighlightItemColor,
onChanged: (val) =>
LocalDatabaseService.colorSettings = _colorSettings.copyWith(
drawerHighlightItemColor: val,
@ -188,7 +189,7 @@ class PersonalizationSettingsPage extends StatelessWidget {
),
_ColorSelectorListTile(
title: S.of(context).mainToolbarBackgroundColor,
value: _colorSettings.mainToolbarBackgroundColor,
value: LocalDatabaseService.colorSettings.mainToolbarBackgroundColor,
onChanged: (val) =>
LocalDatabaseService.colorSettings = _colorSettings.copyWith(
mainToolbarBackgroundColor: val,
@ -196,13 +197,14 @@ class PersonalizationSettingsPage extends StatelessWidget {
),
_ColorSelectorListTile(
title: S.of(context).mainToolbarIconColor,
value: _colorSettings.mainToolbarIconColor,
value: LocalDatabaseService.colorSettings.mainToolbarIconColor,
onChanged: (val) => LocalDatabaseService.colorSettings =
_colorSettings.copyWith(mainToolbarIconColor: val),
),
_ColorSelectorListTile(
title: S.of(context).navigationToolbarBackgroundColor,
value: _colorSettings.navigationToolbarBackgroundColor,
value: LocalDatabaseService
.colorSettings.navigationToolbarBackgroundColor,
onChanged: (val) =>
LocalDatabaseService.colorSettings = _colorSettings.copyWith(
navigationToolbarBackgroundColor: val,
@ -210,7 +212,7 @@ class PersonalizationSettingsPage extends StatelessWidget {
),
_ColorSelectorListTile(
title: S.of(context).navigationToolbarIconColor,
value: _colorSettings.navigationToolbarIconColor,
value: LocalDatabaseService.colorSettings.navigationToolbarIconColor,
onChanged: (val) =>
LocalDatabaseService.colorSettings = _colorSettings.copyWith(
navigationToolbarIconColor: val,
@ -223,7 +225,7 @@ class PersonalizationSettingsPage extends StatelessWidget {
Widget _buildDisplay(BuildContext context, Box<Display> displayBox, _) {
final Display _display = displayBox.get(
LocalDatabaseService.colorSettingsKey,
defaultValue: Display(),
defaultValue: const Display(),
)!;
return SettingsCard(
children: <Widget>[
@ -318,8 +320,9 @@ class PersonalizationSettingsPage extends StatelessWidget {
valueListenable: LocalDatabaseService.listenDisplay,
builder: _buildDisplay,
),
const SizedBox(height: AppTheme.sizedBoxHeight),
const CustomSpacer(),
Text(S.of(context).color, style: AppTheme.settingsHeaderStyle),
// TODO: [Leptopoda] remove the value listenable as we access the ColorSettings via Them.of(constant)
ValueListenableBuilder(
valueListenable: LocalDatabaseService.listenColorSettings,
builder: _buildColor,

View File

@ -23,16 +23,14 @@ class _PieceWidthSlider extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SliderTheme(
data: AppTheme.sliderThemeData,
child: Semantics(
return Semantics(
label: S.of(context).pieceWidth,
child: ValueListenableBuilder(
valueListenable: LocalDatabaseService.listenDisplay,
builder: (context, Box<Display> displayBox, _) {
final Display _display = displayBox.get(
LocalDatabaseService.colorSettingsKey,
defaultValue: Display(),
defaultValue: const Display(),
)!;
return Slider(
@ -48,7 +46,6 @@ class _PieceWidthSlider extends StatelessWidget {
);
},
),
),
);
}
}

View File

@ -36,14 +36,12 @@ class _PointStyleModal extends StatelessWidget {
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,

View File

@ -23,16 +23,14 @@ class _PointWidthSlider extends StatelessWidget {
@override
Widget build(BuildContext context) {
return SliderTheme(
data: AppTheme.sliderThemeData,
child: Semantics(
return Semantics(
label: S.of(context).pointWidth,
child: ValueListenableBuilder(
valueListenable: LocalDatabaseService.listenDisplay,
builder: (context, Box<Display> displayBox, _) {
final Display _display = displayBox.get(
LocalDatabaseService.colorSettingsKey,
defaultValue: Display(),
defaultValue: const Display(),
)!;
return Slider(
@ -48,7 +46,6 @@ class _PointWidthSlider extends StatelessWidget {
);
},
),
),
);
}
}

View File

@ -37,56 +37,48 @@ class _EndGameNMoveRuleModal extends StatelessWidget {
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,

View File

@ -36,14 +36,12 @@ class _FlyPieceCountModal extends StatelessWidget {
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,

View File

@ -36,35 +36,30 @@ class _NMoveRuleModal extends StatelessWidget {
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,

View File

@ -36,28 +36,24 @@ class _PieceCountModal extends StatelessWidget {
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,

View File

@ -25,6 +25,7 @@ import 'package:sanmill/shared/custom_drawer/custom_drawer.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/sized_spacer.dart';
import 'package:sanmill/shared/snackbar.dart';
import 'package:sanmill/shared/theme/app_theme.dart';
@ -237,7 +238,7 @@ class RuleSettingsPage extends StatelessWidget {
),
],
),
const SizedBox(height: AppTheme.sizedBoxHeight),
const CustomSpacer(),
Text(S.of(context).placing, style: AppTheme.settingsHeaderStyle),
SettingsCard(
children: <Widget>[
@ -264,7 +265,7 @@ class RuleSettingsPage extends StatelessWidget {
),
],
),
const SizedBox(height: AppTheme.sizedBoxHeight),
const CustomSpacer(),
Text(S.of(context).moving, style: AppTheme.settingsHeaderStyle),
SettingsCard(
children: <Widget>[
@ -293,7 +294,7 @@ class RuleSettingsPage extends StatelessWidget {
),
],
),
const SizedBox(height: AppTheme.sizedBoxHeight),
const CustomSpacer(),
Text(S.of(context).mayFly, style: AppTheme.settingsHeaderStyle),
SettingsCard(
children: <Widget>[
@ -311,7 +312,7 @@ class RuleSettingsPage extends StatelessWidget {
),
],
),
const SizedBox(height: AppTheme.sizedBoxHeight),
const CustomSpacer(),
Text(S.of(context).removing, style: AppTheme.settingsHeaderStyle),
SettingsCard(
children: <Widget>[

View File

@ -181,7 +181,7 @@ class Audios {
assert(false);
}
// TODO: isn't debug chain meant to catch errors? so why catching them in here and not in onError??
// TODO: [Leptopoda] isn't debug chain meant to catch errors? so why catching them in here and not in onError??
try {
await _stopSound();

View File

@ -91,7 +91,7 @@ class LocalDatabaseService {
/// gets the given [ColorSettings] from the settings Box
static ColorSettings get colorSettings =>
_colorSettingsBox.get(colorSettingsKey) ?? ColorSettings();
_colorSettingsBox.get(colorSettingsKey) ?? const ColorSettings();
/// initialize the [Display] reference
static Future<void> _initDisplay() async {
@ -108,7 +108,7 @@ class LocalDatabaseService {
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) ?? const Display();
/// initialize the [Preferences] reference
static Future<void> _initPreferences() async {

View File

@ -75,6 +75,7 @@ class Constants {
static final windowAspectRatio = windowHeight / windowWidth;
}
// TODO: [Leptopoda] we should only save the threshold and compute the bool right in place with MediaQuery.of(context)
bool get isSmallScreen => Constants.windowHeight <= 800;
bool get isLargeScreen => !isSmallScreen;

View File

@ -54,10 +54,7 @@ class CustomDrawerHeader extends StatelessWidget {
animatedTexts: [
ColorizeAnimatedText(
title,
textStyle: TextStyle(
fontSize: LocalDatabaseService.display.fontSize + 16,
fontWeight: FontWeight.w600,
),
textStyle: AppTheme.drawerHeaderTextStyle,
colors: _animatedTextsColors,
speed: const Duration(seconds: 3),
),

View File

@ -58,7 +58,6 @@ class CustomDrawerItem<T> extends StatelessWidget {
title,
style: TextStyle(
fontWeight: selected ? FontWeight.w700 : FontWeight.w500,
fontSize: LocalDatabaseService.display.fontSize,
color: _color,
),
),
@ -67,7 +66,7 @@ class CustomDrawerItem<T> extends StatelessWidget {
return InkWell(
splashColor: AppTheme.drawerSplashColor,
highlightColor: AppTheme.drawerHighlightColor,
highlightColor: Colors.transparent,
onTap: () => onChanged(value),
child: _drawerItem,
);

View File

@ -108,7 +108,7 @@ class _CustomDrawerState extends State<CustomDrawer>
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
widget.header,
Divider(height: 1, color: AppTheme.drawerDividerColor),
const Divider(height: 1, color: AppTheme.drawerDividerColor),
ListView.builder(
padding: const EdgeInsets.only(top: 4.0),
physics: const BouncingScrollPhysics(),
@ -129,8 +129,6 @@ class _CustomDrawerState extends State<CustomDrawer>
progress: ReverseAnimation(_animationController),
),
tooltip: MaterialLocalizations.of(context).openAppDrawerTooltip,
// TODO: [Leptopoda] remove this unused string
//S.of(context).mainMenu,
onPressed: () => _controller.toggleDrawer(),
);
@ -151,7 +149,7 @@ class _CustomDrawerState extends State<CustomDrawer>
child: DecoratedBox(
decoration: BoxDecoration(
color: LocalDatabaseService.colorSettings.drawerColor,
boxShadow: [
boxShadow: const [
BoxShadow(
color: AppTheme.drawerBoxerShadowColor,
blurRadius: 24,

View File

@ -24,7 +24,6 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:sanmill/generated/intl/l10n.dart';
import 'package:sanmill/services/storage/storage.dart';
import 'package:sanmill/shared/constants.dart';
import 'package:url_launcher/url_launcher.dart';
@ -70,9 +69,8 @@ void showCountdownDialog(
child: Center(
child: Text(
S.of(ctx).cancel,
style: TextStyle(
style: const TextStyle(
color: Colors.black,
fontSize: LocalDatabaseService.display.fontSize,
fontWeight: FontWeight.bold,
),
),
@ -111,6 +109,11 @@ Future<void> showPrivacyDialog(
BuildContext context,
Function(bool value) setPrivacyPolicyAccepted,
) async {
final ThemeData themeData = Theme.of(context);
final TextStyle? aboutTextStyle = themeData.textTheme.bodyText1;
final TextStyle linkStyle = themeData.textTheme.bodyText1!
.copyWith(color: themeData.colorScheme.secondary);
String? locale = "en_US";
late String eulaURL;
late String privacyPolicyURL;
@ -127,11 +130,6 @@ Future<void> showPrivacyDialog(
privacyPolicyURL = Constants.githubPrivacyPolicyURL;
}
final ThemeData themeData = Theme.of(context);
final TextStyle? aboutTextStyle = themeData.textTheme.bodyText1;
final TextStyle linkStyle = themeData.textTheme.bodyText1!
.copyWith(color: themeData.colorScheme.secondary);
showDialog(
context: context,
barrierDismissible: false,

View File

@ -17,7 +17,6 @@
*/
import 'package:flutter/material.dart';
import 'package:sanmill/shared/theme/app_theme.dart';
class ListItemDivider extends StatelessWidget {
const ListItemDivider({
@ -26,12 +25,11 @@ class ListItemDivider extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Divider(
return const Divider(
indent: 16,
endIndent: 16,
height: 1.0,
thickness: 1.0,
color: AppTheme.listItemDividerColor,
);
}
}

View File

@ -0,0 +1,73 @@
/*
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/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:sanmill/generated/intl/l10n.dart';
import 'package:sanmill/shared/theme/app_theme.dart';
class NumberPicker extends StatelessWidget {
const NumberPicker({
Key? key,
this.start = 1,
required this.end,
}) : super(key: key);
final int start;
final int end;
@override
Widget build(BuildContext context) {
final _size = Theme.of(context).textTheme.bodyText1!.fontSize!;
late int _selectValue;
final List<Widget> _items = List.generate(
end - start,
(index) => Text(S.of(context).move_number(start + index)),
);
return AlertDialog(
title: Text(
S.of(context).pleaseSelect,
style: AppTheme.dialogTitleTextStyle,
),
content: ConstrainedBox(
constraints: const BoxConstraints(maxHeight: 150),
child: CupertinoPicker(
itemExtent: _size + 12,
children: _items,
onSelectedItemChanged: (numb) => _selectValue = numb + 1,
),
),
actions: [
TextButton(
child: Text(
S.of(context).cancel,
),
onPressed: () => Navigator.pop(context),
),
TextButton(
child: Text(
S.of(context).confirm,
),
onPressed: () => Navigator.pop(context, _selectValue),
),
],
);
}
}

View File

@ -22,51 +22,30 @@ class BoardPainter extends PiecesBasePainter {
BoardPainter({required double width}) : super(width: width);
@override
void paint(Canvas canvas, Size size) {
doPaint(
canvas,
thePaint,
gridWidth,
squareWidth,
offsetX: AppTheme.boardPadding + squareWidth / 2,
offsetY: AppTheme.boardPadding + squareWidth / 2,
);
}
void paint(Canvas canvas, Size size) => _doPaint(canvas, thePaint);
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
bool shouldRepaint(CustomPainter oldDelegate) => false;
static void doPaint(
Canvas canvas,
Paint paint,
double gridWidth,
double squareWidth, {
required double offsetX,
required double offsetY,
}) {
void _doPaint(Canvas canvas, Paint paint) {
final offset = Offset(
AppTheme.boardPadding + squareWidth / 2,
AppTheme.boardPadding + squareWidth / 2,
);
paint.strokeWidth = LocalDatabaseService.display.boardBorderLineWidth;
paint.color = LocalDatabaseService.colorSettings.boardLineColor;
paint.style = PaintingStyle.stroke;
final left = offsetX;
final top = offsetY;
paint.strokeWidth = LocalDatabaseService.display.boardBorderLineWidth;
if (LocalDatabaseService.display.isPieceCountInHandShown) {
var pieceInHandCount =
gameInstance.position.pieceInHandCount[PieceColor.black];
if (LocalDatabaseService.display.isPieceCountInHandShown &&
gameInstance.position.phase == Phase.placing) {
final int pieceInHandCountStr;
if (gameInstance.position.pieceOnBoardCount[PieceColor.white] == 0 &&
gameInstance.position.pieceOnBoardCount[PieceColor.black] == 0) {
pieceInHandCount = LocalDatabaseService.rules.piecesCount;
}
var pieceInHandCountStr = "";
if (gameInstance.position.phase == Phase.placing) {
pieceInHandCountStr = pieceInHandCount.toString();
pieceInHandCountStr = LocalDatabaseService.rules.piecesCount;
} else {
pieceInHandCountStr =
gameInstance.position.pieceInHandCount[PieceColor.black]!;
}
final TextSpan textSpan = TextSpan(
@ -74,7 +53,7 @@ class BoardPainter extends PiecesBasePainter {
fontSize: 48,
color: LocalDatabaseService.colorSettings.boardLineColor,
), // TODO
text: pieceInHandCountStr,
text: pieceInHandCountStr.toString(),
);
final TextPainter textPainter = TextPainter(
@ -87,9 +66,9 @@ class BoardPainter extends PiecesBasePainter {
textPainter.paint(
canvas,
Offset(
left + squareWidth * 3 - textPainter.width / 2,
top + squareWidth * 3 - textPainter.height / 2,
offset.translate(
squareWidth * 3 - textPainter.width / 2,
squareWidth * 3 - textPainter.height / 2,
),
);
}
@ -97,26 +76,18 @@ class BoardPainter extends PiecesBasePainter {
if (LocalDatabaseService.display.isNotationsShown) {
const String verticalNotations = "abcdefg";
const String horizontalNotations = "7654321";
String notationV = "";
String notationH = "";
for (int i = 0; i < 7; i++) {
notationV = verticalNotations[i];
notationH = horizontalNotations[i];
final String notationV = verticalNotations[i];
final String notationH = horizontalNotations[i];
final TextSpan notationSpanV = TextSpan(
style: TextStyle(
fontSize: 20,
color: AppTheme.boardLineColor,
), // TODO
style: AppTheme.notationTextStyle, // TODO
text: notationV,
);
final TextSpan notationSpanH = TextSpan(
style: TextStyle(
fontSize: 20,
color: AppTheme.boardLineColor,
), // TODO
style: AppTheme.notationTextStyle, // TODO
text: notationH,
);
@ -135,53 +106,78 @@ class BoardPainter extends PiecesBasePainter {
notationPainterV.layout();
notationPainterH.layout();
final offset = (boardWidth - squareWidth * 6) / 4;
final _offset = (boardWidth - squareWidth * 6) / 4;
// Show notations "a b c d e f" on board
if (LocalDatabaseService.preferences.developerMode) {
notationPainterV.paint(
canvas,
Offset(
left + squareWidth * i - notationPainterV.width / 2,
top - offset - notationPainterV.height / 2,
offset.translate(
squareWidth * i - notationPainterV.width / 2,
-_offset - notationPainterV.height / 2,
),
);
}
notationPainterV.paint(
canvas,
Offset(
left + squareWidth * i - notationPainterV.width / 2,
top + squareWidth * 6 + offset - notationPainterV.height / 2,
offset.translate(
squareWidth * i - notationPainterV.width / 2,
squareWidth * 6 + _offset - notationPainterV.height / 2,
),
);
// Show notations "1 2 3 4 5 6 7" on board
notationPainterH.paint(
canvas,
Offset(
left - offset - notationPainterH.width / 2,
top + squareWidth * i - notationPainterH.height / 2,
offset.translate(
-_offset - notationPainterH.width / 2,
squareWidth * i - notationPainterH.height / 2,
),
);
if (LocalDatabaseService.preferences.developerMode) {
notationPainterH.paint(
canvas,
Offset(
left + squareWidth * 6 + offset - notationPainterH.width / 2,
top + squareWidth * i - notationPainterH.height / 2,
offset.translate(
squareWidth * 6 + _offset - notationPainterH.width / 2,
squareWidth * i - notationPainterH.height / 2,
),
);
}
}
}
final points = [
offset + Offset(squareWidth * 0, squareWidth * 0), // 0
offset + Offset(squareWidth * 0, squareWidth * 3), // 1
offset + Offset(squareWidth * 0, squareWidth * 6), // 2
offset + Offset(squareWidth * 1, squareWidth * 1), // 3
offset + Offset(squareWidth * 1, squareWidth * 3), // 4
offset + Offset(squareWidth * 1, squareWidth * 5), // 5
offset + Offset(squareWidth * 2, squareWidth * 2), // 6
offset + Offset(squareWidth * 2, squareWidth * 3), // 7
offset + Offset(squareWidth * 2, squareWidth * 4), // 8
offset + Offset(squareWidth * 3, squareWidth * 0), // 9
offset + Offset(squareWidth * 3, squareWidth * 1), // 10
offset + Offset(squareWidth * 3, squareWidth * 2), // 11
offset + Offset(squareWidth * 3, squareWidth * 4), // 12
offset + Offset(squareWidth * 3, squareWidth * 5), // 13
offset + Offset(squareWidth * 3, squareWidth * 6), // 14
offset + Offset(squareWidth * 4, squareWidth * 2), // 15
offset + Offset(squareWidth * 4, squareWidth * 3), // 16
offset + Offset(squareWidth * 4, squareWidth * 4), // 17
offset + Offset(squareWidth * 5, squareWidth * 1), // 18
offset + Offset(squareWidth * 5, squareWidth * 3), // 19
offset + Offset(squareWidth * 5, squareWidth * 5), // 20
offset + Offset(squareWidth * 6, squareWidth * 0), // 21
offset + Offset(squareWidth * 6, squareWidth * 3), // 22
offset + Offset(squareWidth * 6, squareWidth * 6), // 23
];
// File C
canvas.drawRect(
Rect.fromLTWH(left, top, squareWidth * 6, squareWidth * 6),
Rect.fromLTWH(offset.dx, offset.dy, squareWidth * 6, squareWidth * 6),
paint,
);
@ -191,8 +187,8 @@ class BoardPainter extends PiecesBasePainter {
// File B
canvas.drawRect(
Rect.fromLTWH(
left + squareWidth * 1,
top + squareWidth * 1,
offset.dx + squareWidth * 1,
offset.dy + squareWidth * 1,
squareWidth * 4,
squareWidth * 4,
),
@ -202,118 +198,73 @@ class BoardPainter extends PiecesBasePainter {
// File A
canvas.drawRect(
Rect.fromLTWH(
left + squareWidth * 2,
top + squareWidth * 2,
offset.dx + squareWidth * 2,
offset.dy + squareWidth * 2,
squareWidth * 2,
squareWidth * 2,
),
paint,
);
// Middle horizontal lines (Left to Right)
// Middle horizontal lines (offsetX to Right)
canvas.drawLine(
Offset(left - bias, top + squareWidth * 3),
Offset(left + squareWidth * 2 + bias, top + squareWidth * 3),
points[1].translate(-bias, 0),
points[7].translate(bias, 0),
paint,
);
canvas.drawLine(
Offset(left + squareWidth * 4 - bias, top + squareWidth * 3),
Offset(left + squareWidth * 6 + bias, top + squareWidth * 3),
points[16].translate(-bias, 0),
points[22].translate(bias, 0),
paint,
);
// Middle horizontal lines (Top to Bottom)
// Middle horizontal lines (offsetY to Bottom)
canvas.drawLine(
Offset(left + squareWidth * 3, top - bias),
Offset(left + squareWidth * 3, top + squareWidth * 2 + bias),
points[9].translate(0, -bias),
points[11].translate(0, bias),
paint,
);
canvas.drawLine(
Offset(left + squareWidth * 3, top + squareWidth * 4 - bias),
Offset(left + squareWidth * 3, top + squareWidth * 6 + bias),
points[12].translate(0, -bias),
points[14].translate(0, bias),
paint,
);
// Point
if (LocalDatabaseService.display.pointStyle != 0) {
if (LocalDatabaseService.display.pointStyle == 1) {
switch (LocalDatabaseService.display.pointStyle) {
case 0:
break;
case 1:
paint.style = PaintingStyle.fill;
} else if (LocalDatabaseService.display.pointStyle == 2) {
paint.style = PaintingStyle.stroke; // TODO: WIP
_drawPoint(points, canvas, paint);
break;
case 2:
paint.style = PaintingStyle.stroke;
_drawPoint(points, canvas, paint);
}
final double pointRadius = LocalDatabaseService.display.pointWidth;
final points = [
[0, 0],
[0, 3],
[0, 6],
[1, 1],
[1, 3],
[1, 5],
[2, 2],
[2, 3],
[2, 4],
[3, 0],
[3, 1],
[3, 2],
[3, 4],
[3, 5],
[3, 6],
[4, 2],
[4, 3],
[4, 4],
[5, 1],
[5, 3],
[5, 5],
[6, 0],
[6, 3],
[6, 6],
];
for (final point in points) {
canvas.drawCircle(
Offset(left + squareWidth * point[0], top + squareWidth * point[1]),
pointRadius,
paint,
);
}
}
if (!LocalDatabaseService.rules.hasDiagonalLines) {
return;
}
// top left diagonal line
canvas.drawLine(
Offset(left + 0, top),
Offset(left + squareWidth * 2, top + squareWidth * 2),
paint,
);
if (LocalDatabaseService.rules.hasDiagonalLines) {
// offsetY offsetX diagonal line
canvas.drawLine(points[0], points[6], paint);
// lower right diagonal line
canvas.drawLine(
Offset(left + squareWidth * 4, top + squareWidth * 4),
Offset(left + squareWidth * 6, top + squareWidth * 6),
paint,
);
canvas.drawLine(points[17], points[23], paint);
// top right diagonal line
canvas.drawLine(
Offset(left + squareWidth * 6, top),
Offset(left + squareWidth * 4, top + squareWidth * 2),
paint,
);
// offsetY right diagonal line
canvas.drawLine(points[21], points[15], paint);
// lower left diagonal line
canvas.drawLine(
Offset(left + squareWidth * 2, top + squareWidth * 4),
Offset(left + squareWidth * 0, top + squareWidth * 6),
paint,
);
// lower offsetX diagonal line
canvas.drawLine(points[8], points[2], paint);
}
}
static void _drawPoint(List<Offset> points, Canvas canvas, Paint paint) {
final double pointRadius = LocalDatabaseService.display.pointWidth;
for (final point in points) {
canvas.drawCircle(point, pointRadius, paint);
}
}
}

View File

@ -22,7 +22,7 @@ class PiecePaintParam {
final String piece;
final Offset pos;
final bool animated;
PiecePaintParam({
const PiecePaintParam({
required this.piece,
required this.pos,
required this.animated,
@ -55,52 +55,21 @@ class PiecesPainter extends PiecesBasePainter {
}
@override
void paint(Canvas canvas, Size size) {
doPaint(
canvas,
thePaint,
position: position,
gridWidth: gridWidth,
squareWidth: squareWidth,
pointStyle: pointStyle,
pointWidth: pointWidth,
pieceWidth: pieceWidth,
animatedPieceWidth: animatedPieceWidth,
offsetX: AppTheme.boardPadding + squareWidth / 2,
offsetY: AppTheme.boardPadding + squareWidth / 2,
focusIndex: focusIndex,
blurIndex: blurIndex,
);
}
void paint(Canvas canvas, Size size) => _doPaint(canvas, thePaint);
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
static void doPaint(
Canvas canvas,
Paint paint, {
required Position position,
required double gridWidth,
required double squareWidth,
required int pointStyle,
required double pointWidth,
required double pieceWidth,
required double animatedPieceWidth,
required double offsetX,
required double offsetY,
int focusIndex = invalidIndex,
int blurIndex = invalidIndex,
}) {
final left = offsetX;
final top = offsetY;
bool shouldRepaint(CustomPainter oldDelegate) => true;
void _doPaint(Canvas canvas, Paint paint) {
final shadowPath = Path();
final piecesToDraw = <PiecePaintParam>[];
final offset = Offset(
AppTheme.boardPadding + squareWidth / 2,
AppTheme.boardPadding + squareWidth / 2,
);
late Color blurPositionColor;
Color focusPositionColor;
// Draw pieces on board
for (var row = 0; row < 7; row++) {
@ -110,7 +79,7 @@ class PiecesPainter extends PiecesBasePainter {
if (piece == Piece.noPiece) continue;
final pos = Offset(left + squareWidth * col, top + squareWidth * row);
final pos = offset.translate(squareWidth * col, squareWidth * row);
final animated = focusIndex == index;
piecesToDraw
@ -171,27 +140,20 @@ class PiecesPainter extends PiecesBasePainter {
case Piece.ban:
//print("pps.piece is Ban");
break;
default:
assert(false);
break;
}
}
// draw focus and blur position
final int row = focusIndex ~/ 7;
final int column = focusIndex % 7;
if (focusIndex != invalidIndex) {
focusPositionColor =
LocalDatabaseService.colorSettings.pieceHighlightColor;
paint.color = focusPositionColor;
paint.color = LocalDatabaseService.colorSettings.pieceHighlightColor;
paint.style = PaintingStyle.stroke;
paint.strokeWidth = 2;
canvas.drawCircle(
Offset(left + column * squareWidth, top + row * squareWidth),
offset.translate(column * squareWidth, row * squareWidth),
animatedPieceWidth / 2,
paint,
);
@ -205,7 +167,7 @@ class PiecesPainter extends PiecesBasePainter {
paint.style = PaintingStyle.fill;
canvas.drawCircle(
Offset(left + column * squareWidth, top + row * squareWidth),
offset.translate(column * squareWidth, row * squareWidth),
animatedPieceWidth / 2 * 0.8,
paint,
);

View File

@ -1,81 +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_picker/flutter_picker.dart';
import 'package:sanmill/generated/intl/l10n.dart';
import 'package:sanmill/services/storage/storage.dart';
import 'package:sanmill/shared/theme/app_theme.dart';
Future<int> showPickerNumber(
BuildContext context,
int begin,
int end,
int initValue,
String suffixString,
) async {
int selectValue = 0;
await Picker(
adapter: NumberPickerAdapter(
data: [
NumberPickerColumn(
begin: begin,
end: end,
initValue: initValue,
suffix: Text(
suffixString,
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
),
),
),
],
),
hideHeader: true,
title: Text(
S.of(context).pleaseSelect,
style: TextStyle(
color: AppTheme.appPrimaryColor,
fontSize: LocalDatabaseService.display.fontSize + 4.0,
),
),
textStyle: TextStyle(
color: Colors.black,
fontSize: LocalDatabaseService.display.fontSize,
),
selectedTextStyle: const TextStyle(color: AppTheme.appPrimaryColor),
cancelText: S.of(context).cancel,
cancelTextStyle: TextStyle(
color: AppTheme.appPrimaryColor,
fontSize: LocalDatabaseService.display.fontSize,
),
confirmText: S.of(context).confirm,
confirmTextStyle: TextStyle(
color: AppTheme.appPrimaryColor,
fontSize: LocalDatabaseService.display.fontSize,
),
onConfirm: (Picker picker, List value) async {
debugPrint(value.toString());
final List selectValues = picker.getSelectedValues();
debugPrint(selectValues.toString());
selectValue = selectValues[0] as int;
},
).showDialog(context);
return selectValue;
}

View File

@ -18,7 +18,6 @@
import 'package:flutter/material.dart';
import 'package:sanmill/shared/list_item_divider.dart';
import 'package:sanmill/shared/theme/app_theme.dart';
class SettingsCard extends StatelessWidget {
const SettingsCard({
@ -31,8 +30,6 @@ class SettingsCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Card(
color: AppTheme.cardColor,
margin: AppTheme.cardMargin,
child: ListView.separated(
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true,

View File

@ -18,7 +18,6 @@
import 'package:fluentui_system_icons/fluentui_system_icons.dart';
import 'package:flutter/material.dart';
import 'package:sanmill/services/storage/storage.dart';
import 'package:sanmill/shared/theme/app_theme.dart';
class SettingsListTile extends StatelessWidget {
@ -44,30 +43,18 @@ class SettingsListTile extends StatelessWidget {
return ListTile(
title: Text(
titleString,
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
color: AppTheme.switchListTileTitleColor,
),
),
subtitle: subtitleString == null
? null
: Text(
subtitleString!,
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
color: AppTheme.listTileSubtitleColor,
),
style: AppTheme.listTileTitleStyle,
),
subtitle: subtitleString != null
? Text(subtitleString!, style: AppTheme.listTileSubtitleStyle)
: null,
// TODO: [Leptopoda] fix the trailing widget
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
trailingColor?.value.toRadixString(16) ?? trailingString ?? '',
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
backgroundColor: trailingColor,
),
style: TextStyle(backgroundColor: trailingColor),
),
Icon(
ltr

View File

@ -17,7 +17,6 @@
*/
import 'package:flutter/material.dart';
import 'package:sanmill/services/storage/storage.dart';
import 'package:sanmill/shared/theme/app_theme.dart';
class SettingsSwitchListTile extends StatelessWidget {
@ -39,23 +38,13 @@ class SettingsSwitchListTile extends StatelessWidget {
return SwitchListTile(
value: value,
onChanged: onChanged,
activeColor: AppTheme.switchListTileActiveColor,
title: Text(
titleString,
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
color: AppTheme.switchListTileTitleColor,
),
),
subtitle: subtitleString == null
? null
: Text(
subtitleString!,
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
color: AppTheme.listTileSubtitleColor,
),
style: AppTheme.listTileTitleStyle,
),
subtitle: subtitleString != null
? Text(subtitleString!, style: AppTheme.listTileSubtitleStyle)
: null,
);
}
}

View File

@ -0,0 +1,29 @@
/*
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/shared/theme/app_theme.dart';
class CustomSpacer extends StatelessWidget {
const CustomSpacer({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const SizedBox(height: AppTheme.sizedBoxHeight);
}
}

View File

@ -30,12 +30,7 @@ void showSnackBar(
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
message,
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
),
),
content: Text(message),
duration: duration,
),
);

View File

@ -1,94 +1,58 @@
/*
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/services/storage/storage.dart';
import 'package:sanmill/shared/constants.dart';
import 'package:sanmill/shared/theme/colors.dart';
/// The Apps Theme
@immutable
class AppTheme {
const AppTheme._();
// TODO: restructure theming. Some theme Elements should be accessed via Theme.of(context)
// Theme data
// TODO: [Leptopoda] when using a base theme the darkMode is somehow broken ¿?
/// light theme
static final lightThemeData = ThemeData(
primarySwatch: AppTheme.appPrimaryColor,
brightness: Brightness.light,
primarySwatch: _appPrimaryColor,
sliderTheme: _sliderThemeData,
textTheme: _textTheme,
dividerColor: _listItemDividerColor,
cardTheme: _cardTheme,
);
/// dark theme
static final darkThemeData = ThemeData(
primarySwatch: AppTheme.appPrimaryColor,
brightness: Brightness.dark,
primarySwatch: _appPrimaryColor,
toggleableActiveColor: _appPrimaryColor,
sliderTheme: _sliderThemeData,
textTheme: _textTheme,
dividerColor: _listItemDividerColor,
cardTheme: _cardTheme,
);
// Color
static const appPrimaryColor = Colors.green; // App bar & Dialog button
static const dialogTitleColor = appPrimaryColor;
/// Game page
static Color boardBackgroundColor = UIColors.burlyWood;
static Color mainToolbarBackgroundColor = UIColors.burlyWood;
static Color navigationToolbarBackgroundColor = UIColors.burlyWood;
static Color boardLineColor = const Color(0x996D000D);
static Color whitePieceColor = const Color.fromARGB(0xFF, 0xFF, 0xFF, 0xFF);
static Color whitePieceBorderColor =
const Color.fromARGB(0xFF, 0x66, 0x00, 0x00);
static Color blackPieceColor = const Color.fromARGB(0xFF, 0x00, 0x00, 0x00);
static Color blackPieceBorderColor =
const Color.fromARGB(0xFF, 0x22, 0x22, 0x22);
static Color pieceHighlightColor = Colors.red;
static Color messageColor = Colors.white;
static Color banColor =
const Color.fromARGB(0xFF, 0xFF, 0x00, 0x00); // unused
static Color banBorderColor =
const Color.fromARGB(0x80, 0xFF, 0x00, 0x00); // unused
static Color mainToolbarIconColor = listTileSubtitleColor;
static Color navigationToolbarIconColor = listTileSubtitleColor;
static Color toolbarTextColor = mainToolbarIconColor;
static Color moveHistoryTextColor = Colors.yellow;
static Color moveHistoryDialogBackgroundColor = Colors.transparent;
static Color infoDialogBackgroundColor = moveHistoryDialogBackgroundColor;
static Color infoTextColor = moveHistoryTextColor;
static Color simpleDialogOptionTextColor = Colors.yellow;
/// Settings page
static Color darkBackgroundColor = UIColors.crusoe;
static Color lightBackgroundColor = UIColors.papayaWhip;
static Color listTileSubtitleColor = const Color(0x99461220);
static Color listItemDividerColor = const Color(0x336D000D);
static Color switchListTileActiveColor = dialogTitleColor;
static Color switchListTileTitleColor = UIColors.crusoe;
static Color cardColor = UIColors.floralWhite;
static Color settingsHeaderTextColor = UIColors.crusoe;
/// Help page
static Color helpBackgroundColor = boardBackgroundColor;
static Color helpTextColor = boardBackgroundColor;
/// About
static Color aboutPageBackgroundColor = lightBackgroundColor;
/// Drawer
static Color drawerColor = Colors.white;
static Color drawerBackgroundColor =
UIColors.notWhite.withOpacity(0.5); // TODO
static Color drawerHighlightItemColor =
UIColors.freeSpeechGreen.withOpacity(0.2);
static Color drawerDividerColor = UIColors.grey.withOpacity(0.6);
static Color drawerBoxerShadowColor = UIColors.grey.withOpacity(0.6);
static Color drawerTextColor = UIColors.nearlyBlack;
static Color drawerHighlightTextColor = UIColors.nearlyBlack;
static Color exitTextColor = UIColors.nearlyBlack;
static Color drawerIconColor = drawerTextColor;
static Color drawerHighlightIconColor = drawerHighlightTextColor;
static Color drawerAnimationIconColor = Colors.white;
static Color exitIconColor = Colors.red;
static Color drawerSplashColor =
Colors.grey.withOpacity(0.1); // TODO: no use?
static Color drawerHighlightColor = Colors.transparent; // TODO: no use?
static Color navigationHomeScreenBackgroundColor =
UIColors.nearlyWhite; // TODO: no use?
static const _appPrimaryColor = Colors.green; // App bar & Dialog button
// Theme
static const sliderThemeData = SliderThemeData(
static const _sliderThemeData = SliderThemeData(
trackHeight: 20,
activeTrackColor: Colors.green,
inactiveTrackColor: Colors.grey,
@ -96,9 +60,7 @@ class AppTheme {
disabledInactiveTrackColor: Colors.cyan,
activeTickMarkColor: Colors.black,
inactiveTickMarkColor: Colors.green,
//overlayColor: Colors.yellow,
overlappingShapeStrokeColor: Colors.black,
//overlayShape: RoundSliderOverlayShape(),
valueIndicatorColor: Colors.green,
showValueIndicator: ShowValueIndicator.always,
minThumbSeparation: 100,
@ -111,36 +73,111 @@ class AppTheme {
valueIndicatorTextStyle: TextStyle(fontSize: 24),
);
static const _cardTheme = CardTheme(
margin: EdgeInsets.symmetric(vertical: 4.0),
color: _cardColor,
);
static final _textTheme = TextTheme(
bodyText1: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
),
);
static TextStyle simpleDialogOptionTextStyle = TextStyle(
fontSize: LocalDatabaseService.display.fontSize + 4.0,
color: AppTheme.simpleDialogOptionTextColor,
color: _simpleDialogOptionTextColor,
);
static TextStyle moveHistoryTextStyle = TextStyle(
fontSize: LocalDatabaseService.display.fontSize + 2.0,
height: 1.5,
color: moveHistoryTextColor,
color: _moveHistoryTextColor,
);
static double boardTop = isLargeScreen ? 75.0 : 36.0;
static double boardMargin = 10.0;
static double boardScreenPaddingH = 10.0;
static double boardBorderRadius = 5.0;
static double boardPadding = 5.0;
static TextStyle drawerHeaderTextStyle = TextStyle(
fontSize: LocalDatabaseService.display.fontSize + 16,
fontWeight: FontWeight.w600,
);
static TextStyle dialogTitleTextStyle = TextStyle(
fontSize: LocalDatabaseService.display.fontSize + 4,
color: _appPrimaryColor,
);
static const TextStyle copyrightTextStyle = TextStyle(
fontSize: _copyrightFontSize,
);
static final TextStyle notationTextStyle = TextStyle(
fontSize: 20,
color: LocalDatabaseService.colorSettings.boardLineColor,
);
static const listTileSubtitleStyle = TextStyle(
color: listTileSubtitleColor,
);
static const listTileTitleStyle = TextStyle(
color: _switchListTileTitleColor,
);
static final mainToolbarTextStyle = TextStyle(
color: LocalDatabaseService.colorSettings.mainToolbarIconColor,
);
static const helpTextStyle = TextStyle(
color: helpTextColor,
);
static const licenseTextStyle = TextStyle(
fontFamily: 'Monospace',
fontSize: 12,
);
static const double boardMargin = 10.0;
static const double boardScreenPaddingH = 10.0;
static const double boardBorderRadius = 5.0;
static const double boardPadding = 5.0;
static TextStyle settingsHeaderStyle = TextStyle(
color: settingsHeaderTextColor,
color: _settingsHeaderTextColor,
fontSize: LocalDatabaseService.display.fontSize + 4,
);
static TextStyle settingsTextStyle =
TextStyle(fontSize: LocalDatabaseService.display.fontSize);
static const cardMargin = EdgeInsets.symmetric(vertical: 4.0);
static const double drawerWidth = 250.0;
static TextStyle settingsTextStyle = TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
);
static const double sizedBoxHeight = 16.0;
static double copyrightFontSize = 12;
static const double _copyrightFontSize = 12;
/// Game page
static const Color _moveHistoryTextColor = Colors.yellow;
static const Color _simpleDialogOptionTextColor = Colors.yellow;
static const Color whitePieceBorderColor = Color(0xFF660000);
static const Color blackPieceBorderColor = Color(0xFF222222);
static const Color moveHistoryDialogBackgroundColor = Colors.transparent;
static const Color infoDialogBackgroundColor = Colors.transparent;
/// Settings page
static const Color _listItemDividerColor = Color(0x336D000D);
static const Color _switchListTileTitleColor = UIColors.crusoe;
static const Color _cardColor = UIColors.floralWhite;
static const Color _settingsHeaderTextColor = UIColors.crusoe;
static const Color lightBackgroundColor = UIColors.papayaWhip;
static const Color listTileSubtitleColor = Color(0x99461220);
/// Help page
static const Color helpTextColor = UIColors.burlyWood;
/// About
static const Color aboutPageBackgroundColor = UIColors.papayaWhip;
/// Drawer
static const Color drawerDividerColor = Color(0x993A5160);
static const Color drawerBoxerShadowColor = Color(0x993A5160);
static const Color drawerAnimationIconColor = Colors.white;
static const Color drawerSplashColor = Color(0x1a9e9e9e);
}

View File

@ -18,8 +18,10 @@
import 'package:flutter/material.dart';
/// Color Palate
///
/// gathered from https://www.htmlcsscolor.com
class UIColors {
// https://www.htmlcsscolor.com
const UIColors._();
static const Color white = Color(0xFFFFFFFF);
@ -33,14 +35,14 @@ class UIColors {
static const Color darkGrey = Color(0xFF313A44);
static const Color burlyWood = Color(0xFFDEB887);
static const Color cottonCandy = Color.fromARGB(0xFF, 255, 189, 219);
static const Color turkishRose = Color.fromARGB(0xFF, 163, 109, 173);
static const Color cottonCandy = Color(0xffffbddb);
static const Color turkishRose = Color(0xffa36dad);
static const Color crusoe = Color(0xFF165B31);
static const Color forestGreen = Color(0xFF228B22);
static const Color freeSpeechGreen = Color(0xFF09F911);
static const Color oasis = Color.fromARGB(0xFF, 253, 239, 194);
static const Color oasis = Color(0xfffdefc2);
static const Color papayaWhip = Color(0xFFFFEFD5);
static const Color stormGrey = Color.fromARGB(0xFF, 119, 121, 131);
static const Color turmeric = Color.fromARGB(0xFF, 186, 202, 68);
static const Color LavenderBlush = Color.fromARGB(0xFF, 255, 240, 246);
static const Color stormGrey = Color(0xff777983);
static const Color turmeric = Color(0xffbaca44);
static const Color LavenderBlush = Color(0xfffff0f6);
}

View File

@ -23,7 +23,6 @@ dependencies:
flutter_email_sender: ^5.0.2
flutter_localizations:
sdk: flutter
flutter_picker: ^2.0.2
# local storage
hive: ^2.0.4