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: linter:
rules: rules:
avoid_positional_boolean_parameters: false
constant_identifier_names: false constant_identifier_names: false
avoid_escaping_inner_quotes: false
use_build_context_synchronously: false
depend_on_referenced_packages: false depend_on_referenced_packages: false
analyzer: analyzer:

View File

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

View File

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

View File

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

View File

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

View File

@ -115,7 +115,7 @@ class GameRecorder {
} }
bool isDalmaxMoveList(String text) { 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; return true;
} }

View File

@ -18,7 +18,7 @@
import 'package:sanmill/services/language_info.dart'; 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 { class Rule {
String name = "Default Rule"; String name = "Default Rule";
String description = ""; String description = "";

View File

@ -17,17 +17,15 @@
*/ */
import 'package:copy_with_extension/copy_with_extension.dart'; 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' import 'package:hive_flutter/adapters.dart'
show HiveField, HiveType, BinaryReader, BinaryWriter, TypeAdapter; show HiveField, HiveType, BinaryReader, BinaryWriter, TypeAdapter;
import 'package:json_annotation/json_annotation.dart'; import 'package:json_annotation/json_annotation.dart';
import 'package:sanmill/services/storage/adapters/color_adapter.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'; part 'color.g.dart';
// TODO: make AppTheme colors const so this file can be cleaner
/// Color data model /// Color data model
/// ///
/// holds the data needed for the Color Settings /// holds the data needed for the Color Settings
@ -36,152 +34,128 @@ part 'color.g.dart';
@CopyWith() @CopyWith()
@immutable @immutable
class ColorSettings { class ColorSettings {
ColorSettings({ const ColorSettings({
Color? boardLineColor, this.boardLineColor = const Color(0x996D000D),
Color? darkBackgroundColor, this.darkBackgroundColor = UIColors.crusoe,
Color? boardBackgroundColor, this.boardBackgroundColor = UIColors.burlyWood,
Color? whitePieceColor, this.whitePieceColor = UIColors.white,
Color? blackPieceColor, this.blackPieceColor = const Color(0xFF000000),
Color? pieceHighlightColor, this.pieceHighlightColor = Colors.red,
Color? messageColor, this.messageColor = Colors.white,
Color? drawerColor, this.drawerColor = Colors.white,
Color? drawerBackgroundColor, this.drawerBackgroundColor = const Color(0x80EDF0F2),
Color? drawerTextColor, this.drawerTextColor = UIColors.nearlyBlack,
Color? drawerHighlightItemColor, this.drawerHighlightItemColor = const Color(0x3309f911),
Color? mainToolbarBackgroundColor, this.mainToolbarBackgroundColor = UIColors.burlyWood,
Color? mainToolbarIconColor, this.mainToolbarIconColor = const Color(0x99461220),
Color? navigationToolbarBackgroundColor, this.navigationToolbarBackgroundColor = UIColors.burlyWood,
Color? navigationToolbarIconColor, this.navigationToolbarIconColor = const Color(0x99461220),
}) { });
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;
}
@JsonKey( @JsonKey(
fromJson: ColorAdapter.colorFromJson, fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson, toJson: ColorAdapter.colorToJson,
) )
@HiveField(0) @HiveField(0)
late final Color boardLineColor; final Color boardLineColor;
@JsonKey( @JsonKey(
fromJson: ColorAdapter.colorFromJson, fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson, toJson: ColorAdapter.colorToJson,
) )
@HiveField(1) @HiveField(1)
late final Color darkBackgroundColor; final Color darkBackgroundColor;
@JsonKey( @JsonKey(
fromJson: ColorAdapter.colorFromJson, fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson, toJson: ColorAdapter.colorToJson,
) )
@HiveField(2) @HiveField(2)
late final Color boardBackgroundColor; final Color boardBackgroundColor;
@JsonKey( @JsonKey(
fromJson: ColorAdapter.colorFromJson, fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson, toJson: ColorAdapter.colorToJson,
) )
@HiveField(3) @HiveField(3)
late final Color whitePieceColor; final Color whitePieceColor;
@JsonKey( @JsonKey(
fromJson: ColorAdapter.colorFromJson, fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson, toJson: ColorAdapter.colorToJson,
) )
@HiveField(4) @HiveField(4)
late final Color blackPieceColor; final Color blackPieceColor;
@JsonKey( @JsonKey(
fromJson: ColorAdapter.colorFromJson, fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson, toJson: ColorAdapter.colorToJson,
) )
@HiveField(5) @HiveField(5)
late final Color pieceHighlightColor; final Color pieceHighlightColor;
@JsonKey( @JsonKey(
fromJson: ColorAdapter.colorFromJson, fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson, toJson: ColorAdapter.colorToJson,
) )
@HiveField(6) @HiveField(6)
late final Color messageColor; final Color messageColor;
@JsonKey( @JsonKey(
fromJson: ColorAdapter.colorFromJson, fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson, toJson: ColorAdapter.colorToJson,
) )
@HiveField(7) @HiveField(7)
late final Color drawerColor; final Color drawerColor;
@JsonKey( @JsonKey(
fromJson: ColorAdapter.colorFromJson, fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson, toJson: ColorAdapter.colorToJson,
) )
@HiveField(8) @HiveField(8)
late final Color drawerBackgroundColor; final Color drawerBackgroundColor;
@JsonKey( @JsonKey(
fromJson: ColorAdapter.colorFromJson, fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson, toJson: ColorAdapter.colorToJson,
) )
@HiveField(9) @HiveField(9)
late final Color drawerTextColor; final Color drawerTextColor;
@JsonKey( @JsonKey(
fromJson: ColorAdapter.colorFromJson, fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson, toJson: ColorAdapter.colorToJson,
) )
@HiveField(10) @HiveField(10)
late final Color drawerHighlightItemColor; final Color drawerHighlightItemColor;
@JsonKey( @JsonKey(
fromJson: ColorAdapter.colorFromJson, fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson, toJson: ColorAdapter.colorToJson,
) )
@HiveField(11) @HiveField(11)
late final Color mainToolbarBackgroundColor; final Color mainToolbarBackgroundColor;
@JsonKey( @JsonKey(
fromJson: ColorAdapter.colorFromJson, fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson, toJson: ColorAdapter.colorToJson,
) )
@HiveField(12) @HiveField(12)
late final Color mainToolbarIconColor; final Color mainToolbarIconColor;
@JsonKey( @JsonKey(
fromJson: ColorAdapter.colorFromJson, fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson, toJson: ColorAdapter.colorToJson,
) )
@HiveField(13) @HiveField(13)
late final Color navigationToolbarBackgroundColor; final Color navigationToolbarBackgroundColor;
@JsonKey( @JsonKey(
fromJson: ColorAdapter.colorFromJson, fromJson: ColorAdapter.colorFromJson,
toJson: ColorAdapter.colorToJson, toJson: ColorAdapter.colorToJson,
) )
@HiveField(14) @HiveField(14)
late final Color navigationToolbarIconColor; final Color navigationToolbarIconColor;
/// encodes a Json style map Color a [ColorSettings] object /// encodes a Json style map Color a [ColorSettings] object
factory ColorSettings.fromJson(Map<String, dynamic> json) => 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:hive_flutter/adapters.dart';
import 'package:json_annotation/json_annotation.dart'; import 'package:json_annotation/json_annotation.dart';
import 'package:sanmill/services/storage/adapters/locale_adapter.dart'; import 'package:sanmill/services/storage/adapters/locale_adapter.dart';
import 'package:sanmill/shared/constants.dart';
part 'display.g.dart'; part 'display.g.dart';
@ -33,7 +32,7 @@ part 'display.g.dart';
@CopyWith(generateCopyWithNull: true) @CopyWith(generateCopyWithNull: true)
@immutable @immutable
class Display { class Display {
Display({ const Display({
this.languageCode, this.languageCode,
this.standardNotationEnabled = true, this.standardNotationEnabled = true,
this.isPieceCountInHandShown = true, this.isPieceCountInHandShown = true,
@ -45,11 +44,9 @@ class Display {
this.pointWidth = 10.0, this.pointWidth = 10.0,
this.pieceWidth = 0.9, this.pieceWidth = 0.9,
this.fontSize = 16.0, this.fontSize = 16.0,
double? boardTop, this.boardTop = 36.0,
this.animationDuration = 0.0, this.animationDuration = 0.0,
}) { });
this.boardTop = boardTop ?? (isLargeScreen ? 75.0 : 36.0);
}
/// the uses locale /// the uses locale
@HiveField(0) @HiveField(0)
@ -90,7 +87,7 @@ class Display {
final double fontSize; final double fontSize;
@HiveField(11) @HiveField(11)
late final double boardTop; final double boardTop;
@HiveField(12) @HiveField(12)
final double animationDuration; 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/custom_drawer/custom_drawer.dart';
import 'package:sanmill/shared/list_item_divider.dart'; import 'package:sanmill/shared/list_item_divider.dart';
import 'package:sanmill/shared/settings/settings_list_tile.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:sanmill/shared/theme/app_theme.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
@ -250,20 +251,17 @@ class _VersionDialog extends StatelessWidget {
return AlertDialog( return AlertDialog(
title: Text( title: Text(
S.of(context).appName, S.of(context).appName,
style: const TextStyle(color: AppTheme.dialogTitleColor), style: AppTheme.dialogTitleTextStyle,
), ),
content: Column( content: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: <Widget>[
Text("${S.of(context).version}: $version"), Text(S.of(context).version(version)),
const SizedBox(height: AppTheme.sizedBoxHeight), const CustomSpacer(),
const SizedBox(height: AppTheme.sizedBoxHeight),
Text( Text(
S.of(context).copyright, S.of(context).copyright,
style: TextStyle( style: AppTheme.copyrightTextStyle,
fontSize: AppTheme.copyrightFontSize,
),
), ),
], ],
), ),
@ -294,7 +292,7 @@ class _VersionDialog extends StatelessWidget {
return AlertDialog( return AlertDialog(
title: Text( title: Text(
S.of(context).more, S.of(context).more,
style: const TextStyle(color: AppTheme.dialogTitleColor), style: AppTheme.dialogTitleTextStyle,
), ),
content: Column( content: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,

View File

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

View File

@ -18,7 +18,7 @@
part of 'package:sanmill/screens/game_page/game_page.dart'; 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 { class Board extends StatelessWidget {
final double width; final double width;
@ -36,9 +36,9 @@ class Board extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final padding = AppTheme.boardPadding; const padding = AppTheme.boardPadding;
buildSquareDescription(context); _buildSquareDescription(context);
final grid = GridView( final grid = GridView(
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
@ -51,7 +51,7 @@ class Board extends StatelessWidget {
child: Text( child: Text(
squareDesc[index], squareDesc[index],
style: TextStyle( 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 color: LocalDatabaseService.preferences.developerMode
? Colors.red ? Colors.red
: Colors.transparent, : Colors.transparent,
@ -84,14 +84,8 @@ class Board extends StatelessWidget {
); );
return GestureDetector( return GestureDetector(
/*
child: Semantics(
label: S.of(context).board,
child: boardContainer,
),
*/
child: boardContainer, child: boardContainer,
onTapUp: (d) { onTapUp: (d) async {
final gridWidth = width - padding * 2; final gridWidth = width - padding * 2;
final squareWidth = gridWidth / 7; final squareWidth = gridWidth / 7;
final dx = d.localPosition.dx; final dx = d.localPosition.dx;
@ -113,12 +107,12 @@ class Board extends StatelessWidget {
debugPrint("$_tag Tap on ($row, $column) <$index>"); 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> coordinates = [];
final List<String> pieceDesc = []; final List<String> pieceDesc = [];
@ -263,22 +257,18 @@ class Board extends StatelessWidget {
switch (gameInstance.position.pieceOnGrid(i)) { switch (gameInstance.position.pieceOnGrid(i)) {
case PieceColor.white: case PieceColor.white:
pieceDesc.add(S.of(context).whitePiece); pieceDesc.add(S.of(context).whitePiece);
break; break;
case PieceColor.black: case PieceColor.black:
pieceDesc.add(S.of(context).blackPiece); pieceDesc.add(S.of(context).blackPiece);
break; break;
case PieceColor.ban: case PieceColor.ban:
pieceDesc.add(S.of(context).banPoint); pieceDesc.add(S.of(context).banPoint);
break; break;
case PieceColor.none: case PieceColor.none:
pieceDesc.add(S.of(context).emptyPoint); pieceDesc.add(S.of(context).emptyPoint);
break; break;
default: 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. This file is part of Sanmill.
Copyright (C) 2019-2021 The Sanmill developers (see AUTHORS file) 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/engine.dart';
import 'package:sanmill/services/engine/native_engine.dart'; import 'package:sanmill/services/engine/native_engine.dart';
import 'package:sanmill/services/storage/storage.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/custom_drawer/custom_drawer.dart';
import 'package:sanmill/shared/dialog.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/snackbar.dart';
import 'package:sanmill/shared/theme/app_theme.dart'; import 'package:sanmill/shared/theme/app_theme.dart';
import 'package:stack_trace/stack_trace.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/painter_base.dart';
part 'package:sanmill/shared/painters/pieces_painter.dart'; part 'package:sanmill/shared/painters/pieces_painter.dart';
// TODO: [Leptopoda] remove variables that are not part of an object
double boardWidth = 0.0; double boardWidth = 0.0;
class GamePage extends StatefulWidget { class GamePage extends StatefulWidget {
final EngineType engineType; final EngineType engineType;
// TODO: use gameInstance.engineType // TODO: [Leptopoda] use gameInstance.engineType
const GamePage(this.engineType, {Key? key}) : super(key: key); const GamePage(this.engineType, {Key? key}) : super(key: key);
@override @override
@ -64,7 +69,7 @@ class _GamePageState extends State<GamePage>
double screenPaddingH = AppTheme.boardScreenPaddingH; double screenPaddingH = AppTheme.boardScreenPaddingH;
final double boardMargin = AppTheme.boardMargin; final double boardMargin = AppTheme.boardMargin;
String? _tip = ''; late String _tip;
bool isReady = false; bool isReady = false;
bool isGoingToHistory = false; bool isGoingToHistory = false;
late Timer timer; late Timer timer;
@ -120,44 +125,37 @@ class _GamePageState extends State<GamePage>
} }
} }
void showTip(String? tip) { void showTip(String tip) {
if (!mounted) return; if (!mounted) return;
if (tip != null) {
debugPrint("[tip] $tip"); debugPrint("[tip] $tip");
if (LocalDatabaseService.preferences.screenReaderSupport) { if (LocalDatabaseService.preferences.screenReaderSupport) {
//showSnackBar(context, tip); //showSnackBar(context, tip);
}
} }
setState(() => _tip = tip); setState(() => _tip = tip);
} }
void showTips() { void showTips() {
if (!mounted) { if (!mounted) return;
return;
}
final winner = gameInstance.position.winner; final winner = gameInstance.position.winner;
final Map<String, String> colorWinStrings = { switch (winner) {
PieceColor.white: S.of(context).whiteWin, case PieceColor.white:
PieceColor.black: S.of(context).blackWin, return showTip(S.of(context).whiteWin);
PieceColor.draw: S.of(context).isDraw case PieceColor.black:
}; return showTip(S.of(context).blackWin);
case PieceColor.draw:
if (winner == PieceColor.nobody) { return showTip(S.of(context).isDraw);
if (gameInstance.position.phase == Phase.placing) { case PieceColor.nobody:
if (mounted) { switch (gameInstance.position.phase) {
showTip(S.of(context).tipPlace); case Phase.placing:
return showTip(S.of(context).tipPlace);
case Phase.moving:
return showTip(S.of(context).tipMove);
default:
} }
} else if (gameInstance.position.phase == Phase.moving) {
if (mounted) {
showTip(S.of(context).tipMove);
}
}
} else {
if (mounted) {
showTip(colorWinStrings[winner]);
}
} }
if (!LocalDatabaseService.preferences.isAutoRestart) { if (!LocalDatabaseService.preferences.isAutoRestart) {
@ -194,9 +192,6 @@ class _GamePageState extends State<GamePage>
} }
// If nobody has placed, start to go. // If nobody has placed, start to go.
// TODO
// WAR: Fix first tap response slow when piece count changed
if (position.phase == Phase.placing && if (position.phase == Phase.placing &&
position.pieceOnBoardCount[PieceColor.white] == 0 && position.pieceOnBoardCount[PieceColor.white] == 0 &&
position.pieceOnBoardCount[PieceColor.black] == 0) { position.pieceOnBoardCount[PieceColor.black] == 0) {
@ -255,7 +250,7 @@ class _GamePageState extends State<GamePage>
final side = gameInstance.sideToMove == PieceColor.white final side = gameInstance.sideToMove == PieceColor.white
? S.of(context).black ? S.of(context).black
: S.of(context).white; : 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).black
: S.of(context).white; : S.of(context).white;
if (mounted) { 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 && if (LocalDatabaseService.preferences.screenReaderSupport &&
gameInstance.position.action != Act.remove && gameInstance.position.action != Act.remove &&
m != null && m?.notation != null) {
m.notation != null) { showSnackBar(context, "${S.of(context).human}: ${m!.notation!}");
showSnackBar(context, "${S.of(context).human}: ${m.notation!}");
} }
} }
} }
@ -592,14 +586,9 @@ class _GamePageState extends State<GamePage>
showSnackBar(context, S.of(context).timeout); showSnackBar(context, S.of(context).timeout);
} }
} }
//if (LocalDatabaseService.developerMode) {
//assert(false);
//}
return; return;
default: default:
showTip('Error: ${response.type}'); showTip(S.of(context).error(response.type));
break;
} }
if (LocalDatabaseService.preferences.isAutoRestart == true && if (LocalDatabaseService.preferences.isAutoRestart == true &&
@ -654,10 +643,10 @@ class _GamePageState extends State<GamePage>
final importFailedStr = gameInstance.position.recorder.import(text); final importFailedStr = gameInstance.position.recorder.import(text);
if (importFailedStr != "") { if (importFailedStr != "") {
showTip("${S.of(context).cannotImport} $importFailedStr"); showTip(S.of(context).cannotImport(importFailedStr));
if (LocalDatabaseService.preferences.screenReaderSupport) { if (LocalDatabaseService.preferences.screenReaderSupport) {
ScaffoldMessenger.of(context).clearSnackBars(); ScaffoldMessenger.of(context).clearSnackBars();
showSnackBar(context, "${S.of(context).cannotImport} $importFailedStr"); showSnackBar(context, S.of(context).cannotImport(importFailedStr));
} }
return; return;
} }
@ -706,7 +695,7 @@ class _GamePageState extends State<GamePage>
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
), ),
const SizedBox(height: AppTheme.sizedBoxHeight), const CustomSpacer(),
SimpleDialogOption( SimpleDialogOption(
onPressed: onImportGameButtonPressed, onPressed: onImportGameButtonPressed,
child: Text( child: Text(
@ -715,7 +704,7 @@ class _GamePageState extends State<GamePage>
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
), ),
const SizedBox(height: AppTheme.sizedBoxHeight), const CustomSpacer(),
SimpleDialogOption( SimpleDialogOption(
onPressed: onExportGameButtonPressed, onPressed: onExportGameButtonPressed,
child: Text( child: Text(
@ -724,7 +713,7 @@ class _GamePageState extends State<GamePage>
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
), ),
const SizedBox(height: AppTheme.sizedBoxHeight), const CustomSpacer(),
if (LocalDatabaseService.preferences.screenReaderSupport) if (LocalDatabaseService.preferences.screenReaderSupport)
SimpleDialogOption( SimpleDialogOption(
child: Text( child: Text(
@ -755,7 +744,7 @@ class _GamePageState extends State<GamePage>
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
), ),
const SizedBox(height: AppTheme.sizedBoxHeight), const CustomSpacer(),
SimpleDialogOption( SimpleDialogOption(
onPressed: onStepForwardButtonPressed, onPressed: onStepForwardButtonPressed,
child: Text( child: Text(
@ -764,7 +753,7 @@ class _GamePageState extends State<GamePage>
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
), ),
const SizedBox(height: AppTheme.sizedBoxHeight), const CustomSpacer(),
SimpleDialogOption( SimpleDialogOption(
onPressed: onTakeBackAllButtonPressed, onPressed: onTakeBackAllButtonPressed,
child: Text( child: Text(
@ -773,7 +762,7 @@ class _GamePageState extends State<GamePage>
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
), ),
const SizedBox(height: AppTheme.sizedBoxHeight), const CustomSpacer(),
SimpleDialogOption( SimpleDialogOption(
onPressed: onStepForwardAllButtonPressed, onPressed: onStepForwardAllButtonPressed,
child: Text( child: Text(
@ -782,13 +771,13 @@ class _GamePageState extends State<GamePage>
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
), ),
const SizedBox(height: AppTheme.sizedBoxHeight), const CustomSpacer(),
]; ];
showModalBottomSheet( showModalBottomSheet(
context: context, context: context,
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
builder: (context) => Semantics( builder: (context) => Semantics(
label: S.of(context).move, label: S.of(context).move_number(0),
child: SimpleDialog( child: SimpleDialog(
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
children: <Widget>[ children: <Widget>[
@ -802,7 +791,7 @@ class _GamePageState extends State<GamePage>
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
), ),
const SizedBox(height: AppTheme.sizedBoxHeight), const CustomSpacer(),
SimpleDialogOption( SimpleDialogOption(
onPressed: onMoveNowButtonPressed, onPressed: onMoveNowButtonPressed,
child: Text( child: Text(
@ -811,7 +800,7 @@ class _GamePageState extends State<GamePage>
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
), ),
const SizedBox(height: AppTheme.sizedBoxHeight), const CustomSpacer(),
if (LocalDatabaseService.preferences.screenReaderSupport) if (LocalDatabaseService.preferences.screenReaderSupport)
SimpleDialogOption( SimpleDialogOption(
child: Text( child: Text(
@ -873,8 +862,8 @@ class _GamePageState extends State<GamePage>
late final String text; late final String text;
final lastEffectiveMove = pos.recorder.lastEffectiveMove; final lastEffectiveMove = pos.recorder.lastEffectiveMove;
if (lastEffectiveMove != null && lastEffectiveMove.notation != null) { if (lastEffectiveMove?.notation != null) {
text = "${S.of(context).lastMove}: ${lastEffectiveMove.notation}"; text = S.of(context).lastMove(lastEffectiveMove!.notation!);
} else { } else {
text = S.of(context).atEnd; text = S.of(context).atEnd;
} }
@ -934,10 +923,7 @@ class _GamePageState extends State<GamePage>
backgroundColor: AppTheme.moveHistoryDialogBackgroundColor, backgroundColor: AppTheme.moveHistoryDialogBackgroundColor,
title: Text( title: Text(
S.of(context).moveList, S.of(context).moveList,
style: TextStyle( style: AppTheme.moveHistoryTextStyle,
color: AppTheme.moveHistoryTextColor,
fontSize: LocalDatabaseService.display.fontSize + 2.0,
),
), ),
content: SingleChildScrollView( content: SingleChildScrollView(
child: Text( child: Text(
@ -954,15 +940,12 @@ class _GamePageState extends State<GamePage>
style: AppTheme.moveHistoryTextStyle, style: AppTheme.moveHistoryTextStyle,
), ),
onPressed: () async { onPressed: () async {
final int selectValue = await showPickerNumber( final selectValue = await showDialog<int?>(
context, context: context,
1, builder: (context) => NumberPicker(end: end),
end,
1,
S.of(context).moves,
); );
if (selectValue != 0) { if (selectValue != null) {
onTakeBackNButtonPressed(selectValue); onTakeBackNButtonPressed(selectValue);
} }
}, },
@ -1042,14 +1025,13 @@ class _GamePageState extends State<GamePage>
final Map<GameOverReason, String> reasonMap = { final Map<GameOverReason, String> reasonMap = {
GameOverReason.loseReasonlessThanThree: GameOverReason.loseReasonlessThanThree:
loserStr + S.of(context).loseReasonlessThanThree, S.of(context).loseReasonlessThanThree(loserStr),
GameOverReason.loseReasonResign: GameOverReason.loseReasonResign: S.of(context).loseReasonResign(loserStr),
loserStr + S.of(context).loseReasonResign, GameOverReason.loseReasonNoWay: S.of(context).loseReasonNoWay(loserStr),
GameOverReason.loseReasonNoWay: loserStr + S.of(context).loseReasonNoWay,
GameOverReason.loseReasonBoardIsFull: GameOverReason.loseReasonBoardIsFull:
loserStr + S.of(context).loseReasonBoardIsFull, S.of(context).loseReasonBoardIsFull(loserStr),
GameOverReason.loseReasonTimeOver: GameOverReason.loseReasonTimeOver:
loserStr + S.of(context).loseReasonTimeOver, S.of(context).loseReasonTimeOver(loserStr),
GameOverReason.drawReasonRule50: S.of(context).drawReasonRule50, GameOverReason.drawReasonRule50: S.of(context).drawReasonRule50,
GameOverReason.drawReasonEndgameRule50: GameOverReason.drawReasonEndgameRule50:
S.of(context).drawReasonEndgameRule50, S.of(context).drawReasonEndgameRule50,
@ -1103,23 +1085,11 @@ class _GamePageState extends State<GamePage>
return GameResult.none; return GameResult.none;
} }
// TODO: [Leptopoda] deduplicate the code
void showGameResult(String winner) { void showGameResult(String winner) {
final GameResult result = getGameResult(winner); final GameResult result = getGameResult(winner);
gameInstance.position.result = result; 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 = { final Map<GameResult, String> retMap = {
GameResult.win: gameInstance.engineType == EngineType.humanVsAi GameResult.win: gameInstance.engineType == EngineType.humanVsAi
? S.of(context).youWin ? S.of(context).youWin
@ -1130,9 +1100,7 @@ class _GamePageState extends State<GamePage>
final dialogTitle = retMap[result]; final dialogTitle = retMap[result];
if (dialogTitle == null) { if (dialogTitle == null) return;
return;
}
final bool isTopLevel = final bool isTopLevel =
LocalDatabaseService.preferences.skillLevel == 30; // TODO: 30 LocalDatabaseService.preferences.skillLevel == 30; // TODO: 30
@ -1140,14 +1108,21 @@ class _GamePageState extends State<GamePage>
if (result == GameResult.win && if (result == GameResult.win &&
!isTopLevel && !isTopLevel &&
gameInstance.engineType == EngineType.humanVsAi) { gameInstance.engineType == EngineType.humanVsAi) {
var contentStr = getGameOverReasonString( final contentStr = StringBuffer(
gameInstance.position.gameOverReason, getGameOverReasonString(
gameInstance.position.winner, gameInstance.position.gameOverReason,
gameInstance.position.winner,
),
); );
if (!isTopLevel) { if (!isTopLevel) {
contentStr += contentStr.writeln();
"\n\n${S.of(context).challengeHarderLevel}${LocalDatabaseService.preferences.skillLevel + 1}!"; contentStr.writeln();
contentStr.writeln(
S.of(context).challengeHarderLevel(
LocalDatabaseService.preferences.skillLevel + 1,
),
);
} }
showDialog( showDialog(
@ -1157,24 +1132,13 @@ class _GamePageState extends State<GamePage>
return AlertDialog( return AlertDialog(
title: Text( title: Text(
dialogTitle, dialogTitle,
style: TextStyle( style: AppTheme.dialogTitleTextStyle,
color: AppTheme.dialogTitleColor,
fontSize: LocalDatabaseService.display.fontSize + 4,
),
),
content: Text(
contentStr,
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
),
), ),
content: Text(contentStr.toString()),
actions: <Widget>[ actions: <Widget>[
TextButton( TextButton(
child: Text( child: Text(
S.of(context).yes, S.of(context).yes,
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
),
), ),
onPressed: () async { onPressed: () async {
if (!isTopLevel) { if (!isTopLevel) {
@ -1189,12 +1153,7 @@ class _GamePageState extends State<GamePage>
}, },
), ),
TextButton( TextButton(
child: Text( child: Text(S.of(context).no),
S.of(context).no,
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
),
),
onPressed: () => Navigator.pop(context), onPressed: () => Navigator.pop(context),
), ),
], ],
@ -1209,28 +1168,17 @@ class _GamePageState extends State<GamePage>
return AlertDialog( return AlertDialog(
title: Text( title: Text(
dialogTitle, dialogTitle,
style: TextStyle( style: AppTheme.dialogTitleTextStyle,
color: AppTheme.dialogTitleColor,
fontSize: LocalDatabaseService.display.fontSize + 4,
),
), ),
content: Text( content: Text(
getGameOverReasonString( getGameOverReasonString(
gameInstance.position.gameOverReason, gameInstance.position.gameOverReason,
gameInstance.position.winner, gameInstance.position.winner,
), ),
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
),
), ),
actions: <Widget>[ actions: <Widget>[
TextButton( TextButton(
child: Text( child: Text(S.of(context).restart),
S.of(context).restart,
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
),
),
onPressed: () { onPressed: () {
Navigator.pop(context); Navigator.pop(context);
gameInstance.newGame(); gameInstance.newGame();
@ -1249,12 +1197,7 @@ class _GamePageState extends State<GamePage>
}, },
), ),
TextButton( TextButton(
child: Text( child: Text(S.of(context).cancel),
S.of(context).cancel,
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
),
),
onPressed: () => Navigator.pop(context), onPressed: () => Navigator.pop(context),
), ),
], ],
@ -1265,13 +1208,12 @@ class _GamePageState extends State<GamePage>
} }
double get _screenPaddingH { double get _screenPaddingH {
//
// when screen's height/width rate is less than 16/9, limit width of board // when screen's height/width rate is less than 16/9, limit width of board
final windowSize = MediaQuery.of(context).size; final windowSize = MediaQuery.of(context).size;
final double height = windowSize.height; final double height = windowSize.height;
double width = windowSize.width; double width = windowSize.width;
// TODO: maybe use windowSize.aspectRatio // TODO: [Leptopoda] maybe use windowSize.aspectRatio
if (height / width < 16.0 / 9.0) { if (height / width < 16.0 / 9.0) {
width = height * 9 / 16; width = height * 9 / 16;
return (windowSize.width - width) / 2 - AppTheme.boardMargin; return (windowSize.width - width) / 2 - AppTheme.boardMargin;
@ -1315,7 +1257,10 @@ class _GamePageState extends State<GamePage>
); );
return Container( return Container(
margin: EdgeInsets.only(top: LocalDatabaseService.display.boardTop), margin: EdgeInsets.only(
top: LocalDatabaseService.display.boardTop +
(isLargeScreen ? 39.0 : 0.0),
),
child: Column( child: Column(
children: <Widget>[ children: <Widget>[
iconRow, iconRow,
@ -1331,14 +1276,13 @@ class _GamePageState extends State<GamePage>
Padding( Padding(
padding: const EdgeInsets.symmetric(horizontal: 16), padding: const EdgeInsets.symmetric(horizontal: 16),
child: Text( child: Text(
_tip!, _tip,
maxLines: 1, maxLines: 1,
style: TextStyle( style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
color: LocalDatabaseService.colorSettings.messageColor, color: LocalDatabaseService.colorSettings.messageColor,
), ),
), ),
), // TODO: Font Size ),
], ],
), ),
); );
@ -1385,76 +1329,100 @@ class _GamePageState extends State<GamePage>
} }
String get infoText { String get infoText {
String phase = ""; final buffer = StringBuffer();
final String period =
LocalDatabaseService.preferences.screenReaderSupport ? "." : "";
final String comma =
LocalDatabaseService.preferences.screenReaderSupport ? "," : "";
final pos = gameInstance.position; 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) { switch (pos.phase) {
case Phase.placing: case Phase.placing:
phase = S.of(context).placingPhase; buffer.writeln(S.of(context).placingPhase);
break; break;
case Phase.moving: case Phase.moving:
phase = S.of(context).movingPhase; buffer.writeln(S.of(context).movingPhase);
break; break;
default: default:
break;
} }
// last Move information
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 = "";
if (pos.recorder.lastMove?.notation != null) { if (pos.recorder.lastMove?.notation != null) {
final String n1 = pos.recorder.lastMove!.notation!; 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")) { if (n1.startsWith("x")) {
final String n2 = buffer.writeln(
pos.recorder.moveAt(pos.recorder.movesCount - 2).notation!; 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.writePeriod(n1);
} }
String addedPeriod = ""; buffer.writePeriod(S.of(context).sideToMove(us));
// the tip
if (LocalDatabaseService.preferences.screenReaderSupport && if (LocalDatabaseService.preferences.screenReaderSupport &&
tip.isNotEmpty && _tip[_tip.length - 1] != '.' &&
tip[tip.length - 1] != '.' && _tip[_tip.length - 1] != '!') {
tip[tip.length - 1] != '!') { buffer.writePeriod(_tip);
addedPeriod = ".";
} }
final String ret = buffer.writeln();
"$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"; buffer.writeln(S.of(context).pieceCount);
return ret; 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 { Widget get toolbar {
final _iconColor = LocalDatabaseService.colorSettings.mainToolbarIconColor;
final gameButton = TextButton( final gameButton = TextButton(
onPressed: onGameButtonPressed, onPressed: onGameButtonPressed,
child: Column( child: Column(
@ -1462,13 +1430,11 @@ class _GamePageState extends State<GamePage>
children: <Widget>[ children: <Widget>[
Icon( Icon(
FluentIcons.table_simple_24_regular, FluentIcons.table_simple_24_regular,
color: LocalDatabaseService.colorSettings.mainToolbarIconColor, color: _iconColor,
), ),
Text( Text(
S.of(context).game, S.of(context).game,
style: TextStyle( style: AppTheme.mainToolbarTextStyle,
color: LocalDatabaseService.colorSettings.mainToolbarIconColor,
),
), ),
], ],
), ),
@ -1481,13 +1447,11 @@ class _GamePageState extends State<GamePage>
children: <Widget>[ children: <Widget>[
Icon( Icon(
FluentIcons.settings_24_regular, FluentIcons.settings_24_regular,
color: LocalDatabaseService.colorSettings.mainToolbarIconColor, color: _iconColor,
), ),
Text( Text(
S.of(context).options, S.of(context).options,
style: TextStyle( style: AppTheme.mainToolbarTextStyle,
color: LocalDatabaseService.colorSettings.mainToolbarIconColor,
),
), ),
], ],
), ),
@ -1500,13 +1464,11 @@ class _GamePageState extends State<GamePage>
children: <Widget>[ children: <Widget>[
Icon( Icon(
FluentIcons.calendar_agenda_24_regular, FluentIcons.calendar_agenda_24_regular,
color: LocalDatabaseService.colorSettings.mainToolbarIconColor, color: _iconColor,
), ),
Text( Text(
S.of(context).move, S.of(context).move_number(0),
style: TextStyle( style: AppTheme.mainToolbarTextStyle,
color: LocalDatabaseService.colorSettings.mainToolbarIconColor,
),
), ),
], ],
), ),
@ -1519,13 +1481,11 @@ class _GamePageState extends State<GamePage>
children: <Widget>[ children: <Widget>[
Icon( Icon(
FluentIcons.book_information_24_regular, FluentIcons.book_information_24_regular,
color: LocalDatabaseService.colorSettings.mainToolbarIconColor, color: _iconColor,
), ),
Text( Text(
S.of(context).info, S.of(context).info,
style: TextStyle( style: AppTheme.mainToolbarTextStyle,
color: LocalDatabaseService.colorSettings.mainToolbarIconColor,
),
), ),
], ],
), ),
@ -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 { Widget get historyNavToolbar {
final _iconColor =
LocalDatabaseService.colorSettings.navigationToolbarIconColor;
final takeBackAllButton = TextButton( final takeBackAllButton = TextButton(
child: Semantics( child: Semantics(
label: S.of(context).takeBackAll, label: S.of(context).takeBackAll,
@ -1550,7 +1514,7 @@ class _GamePageState extends State<GamePage>
ltr ltr
? FluentIcons.arrow_previous_24_regular ? FluentIcons.arrow_previous_24_regular
: FluentIcons.arrow_next_24_regular, : FluentIcons.arrow_next_24_regular,
color: LocalDatabaseService.colorSettings.navigationToolbarIconColor, color: _iconColor,
), ),
), ),
onPressed: () => onTakeBackAllButtonPressed(false), onPressed: () => onTakeBackAllButtonPressed(false),
@ -1563,7 +1527,7 @@ class _GamePageState extends State<GamePage>
ltr ltr
? FluentIcons.chevron_left_24_regular ? FluentIcons.chevron_left_24_regular
: FluentIcons.chevron_right_24_regular, : FluentIcons.chevron_right_24_regular,
color: LocalDatabaseService.colorSettings.navigationToolbarIconColor, color: _iconColor,
), ),
), ),
onPressed: () async => onTakeBackButtonPressed(false), onPressed: () async => onTakeBackButtonPressed(false),
@ -1576,7 +1540,7 @@ class _GamePageState extends State<GamePage>
ltr ltr
? FluentIcons.chevron_right_24_regular ? FluentIcons.chevron_right_24_regular
: FluentIcons.chevron_left_24_regular, : FluentIcons.chevron_left_24_regular,
color: LocalDatabaseService.colorSettings.navigationToolbarIconColor, color: _iconColor,
), ),
), ),
onPressed: () async => onStepForwardButtonPressed(false), onPressed: () async => onStepForwardButtonPressed(false),
@ -1589,21 +1553,26 @@ class _GamePageState extends State<GamePage>
ltr ltr
? FluentIcons.arrow_next_24_regular ? FluentIcons.arrow_next_24_regular
: FluentIcons.arrow_previous_24_regular, : FluentIcons.arrow_previous_24_regular,
color: LocalDatabaseService.colorSettings.navigationToolbarIconColor, color: _iconColor,
), ),
), ),
onPressed: () async => onStepForwardAllButtonPressed(false), onPressed: () async => onStepForwardAllButtonPressed(false),
); );
return GamePageToolBar( return IconTheme(
color: data: IconThemeData(
LocalDatabaseService.colorSettings.navigationToolbarBackgroundColor, color: LocalDatabaseService.colorSettings.navigationToolbarIconColor,
children: <Widget>[ ),
takeBackAllButton, child: GamePageToolBar(
takeBackButton, color:
stepForwardButton, LocalDatabaseService.colorSettings.navigationToolbarBackgroundColor,
stepForwardAllButton, children: <Widget>[
], takeBackAllButton,
takeBackButton,
stepForwardButton,
stepForwardAllButton,
],
),
); );
} }
@ -1637,20 +1606,17 @@ class _GamePageState extends State<GamePage>
super.didChangeDependencies(); super.didChangeDependencies();
screenPaddingH = _screenPaddingH; screenPaddingH = _screenPaddingH;
ltr = Directionality.of(context) == TextDirection.ltr; ltr = Directionality.of(context) == TextDirection.ltr;
_tip = S.of(context).welcome;
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (_tip == '') {
_tip = S.of(context).welcome;
}
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
leading: DrawerIcon.of(context)?.icon, leading: DrawerIcon.of(context)?.icon,
backgroundColor: Colors.transparent, backgroundColor: Colors.transparent,
elevation: 0.0, elevation: 0.0,
iconTheme: IconThemeData( iconTheme: const IconThemeData(
color: AppTheme.drawerAnimationIconColor, color: AppTheme.drawerAnimationIconColor,
), ),
), ),
@ -1681,3 +1647,21 @@ class _GamePageState extends State<GamePage>
super.dispose(); 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, mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
RadioListTile( RadioListTile(
activeColor: AppTheme.switchListTileActiveColor,
title: const Text('Alpha-Beta'), title: const Text('Alpha-Beta'),
groupValue: algorithm, groupValue: algorithm,
value: 0, value: 0,
onChanged: onChanged, onChanged: onChanged,
), ),
RadioListTile( RadioListTile(
activeColor: AppTheme.switchListTileActiveColor,
title: const Text('PVS'), title: const Text('PVS'),
groupValue: algorithm, groupValue: algorithm,
value: 1, value: 1,
onChanged: onChanged, onChanged: onChanged,
), ),
RadioListTile( RadioListTile(
activeColor: AppTheme.switchListTileActiveColor,
title: const Text('MTD(f)'), title: const Text('MTD(f)'),
groupValue: algorithm, groupValue: algorithm,
value: 2, 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_card.dart';
import 'package:sanmill/shared/settings/settings_list_tile.dart'; import 'package:sanmill/shared/settings/settings_list_tile.dart';
import 'package:sanmill/shared/settings/settings_switch_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'; import 'package:sanmill/shared/theme/app_theme.dart';
part 'package:sanmill/screens/game_settings/algorithm_modal.dart'; part 'package:sanmill/screens/game_settings/algorithm_modal.dart';
@ -162,7 +163,7 @@ class GameSettingsPage extends StatelessWidget {
)!; )!;
final _widowsSettings = [ final _widowsSettings = [
const SizedBox(height: AppTheme.sizedBoxHeight), const CustomSpacer(),
Text(S.of(context).playSounds, style: AppTheme.settingsHeaderStyle), Text(S.of(context).playSounds, style: AppTheme.settingsHeaderStyle),
SettingsCard( SettingsCard(
children: <Widget>[ children: <Widget>[
@ -181,7 +182,7 @@ class GameSettingsPage extends StatelessWidget {
]; ];
final _developerSettings = [ final _developerSettings = [
const SizedBox(height: AppTheme.sizedBoxHeight), const CustomSpacer(),
Text(S.of(context).forDevelopers, style: AppTheme.settingsHeaderStyle), Text(S.of(context).forDevelopers, style: AppTheme.settingsHeaderStyle),
SettingsCard( SettingsCard(
children: <Widget>[ 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), Text(S.of(context).difficulty, style: AppTheme.settingsHeaderStyle),
SettingsCard( SettingsCard(
children: <Widget>[ 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), Text(S.of(context).aisPlayStyle, style: AppTheme.settingsHeaderStyle),
SettingsCard( SettingsCard(
children: <Widget>[ children: <Widget>[
@ -275,7 +276,7 @@ class GameSettingsPage extends StatelessWidget {
], ],
), ),
if (!Platform.isWindows) ..._widowsSettings, if (!Platform.isWindows) ..._widowsSettings,
const SizedBox(height: AppTheme.sizedBoxHeight), const CustomSpacer(),
Text(S.of(context).accessibility, style: AppTheme.settingsHeaderStyle), Text(S.of(context).accessibility, style: AppTheme.settingsHeaderStyle),
SettingsCard( SettingsCard(
children: <Widget>[ 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), Text(S.of(context).restore, style: AppTheme.settingsHeaderStyle),
SettingsCard( SettingsCard(
children: <Widget>[ children: <Widget>[

View File

@ -23,32 +23,29 @@ class _MoveTimeSlider extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SliderTheme( return Semantics(
data: AppTheme.sliderThemeData, label: S.of(context).moveTime,
child: Semantics( child: ValueListenableBuilder(
label: S.of(context).moveTime, valueListenable: LocalDatabaseService.listenPreferences,
child: ValueListenableBuilder( builder: (context, Box<Preferences> prefBox, _) {
valueListenable: LocalDatabaseService.listenPreferences, final Preferences _preferences = prefBox.get(
builder: (context, Box<Preferences> prefBox, _) { LocalDatabaseService.preferencesKey,
final Preferences _preferences = prefBox.get( defaultValue: const Preferences(),
LocalDatabaseService.preferencesKey, )!;
defaultValue: const Preferences(),
)!;
return Slider( return Slider(
value: LocalDatabaseService.preferences.moveTime.toDouble(), value: LocalDatabaseService.preferences.moveTime.toDouble(),
max: 60, max: 60,
divisions: 60, divisions: 60,
label: LocalDatabaseService.preferences.moveTime.toString(), label: LocalDatabaseService.preferences.moveTime.toString(),
onChanged: (value) { onChanged: (value) {
LocalDatabaseService.preferences = LocalDatabaseService.preferences =
_preferences.copyWith(moveTime: value.toInt()); _preferences.copyWith(moveTime: value.toInt());
debugPrint("Move time Slider value: $value"); debugPrint("Move time Slider value: $value");
}, },
); );
}, },
),
), ),
); );
} }

View File

@ -21,12 +21,12 @@ part of 'package:sanmill/screens/game_settings/game_settings_page.dart';
class _ResetSettingsAlert extends StatelessWidget { class _ResetSettingsAlert extends StatelessWidget {
const _ResetSettingsAlert({Key? key}) : super(key: key); 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 { Future<void> _restore(BuildContext context) async {
Navigator.pop(context); 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 //as the new storage backend supports deletion without needing an app restart
if (!EnvironmentConfig.monkeyTest) { if (!EnvironmentConfig.monkeyTest) {
await LocalDatabaseService.resetStorage(); await LocalDatabaseService.resetStorage();
@ -35,43 +35,25 @@ class _ResetSettingsAlert extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// TODO: remove these strings as they aren't needed anymore
//S.of(context).exitApp;
//S.of(context).exitAppManually
return AlertDialog( return AlertDialog(
title: Text( title: Text(
S.of(context).restore, S.of(context).restore,
style: TextStyle( style: AppTheme.dialogTitleTextStyle,
color: AppTheme.dialogTitleColor,
fontSize: LocalDatabaseService.display.fontSize + 4,
),
), ),
content: SingleChildScrollView( content: SingleChildScrollView(
child: Text( child: Text("${S.of(context).restoreDefaultSettings}?"),
"${S.of(context).restoreDefaultSettings}?",
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
),
),
), ),
actions: <Widget>[ actions: <Widget>[
TextButton( TextButton(
onPressed: () => _restore(context), onPressed: () => _restore(context),
child: Text( child: Text(
S.of(context).ok, S.of(context).ok,
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
),
), ),
), ),
TextButton( TextButton(
onPressed: () => cancel(context), onPressed: () => _cancel(context),
child: Text( child: Text(
S.of(context).cancel, S.of(context).cancel,
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
),
), ),
), ),
], ],

View File

@ -23,32 +23,29 @@ class _SkillLevelSlider extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SliderTheme( return Semantics(
data: AppTheme.sliderThemeData, label: S.of(context).skillLevel,
child: Semantics( child: ValueListenableBuilder(
label: S.of(context).skillLevel, valueListenable: LocalDatabaseService.listenPreferences,
child: ValueListenableBuilder( builder: (context, Box<Preferences> prefBox, _) {
valueListenable: LocalDatabaseService.listenPreferences, final Preferences _preferences = prefBox.get(
builder: (context, Box<Preferences> prefBox, _) { LocalDatabaseService.preferencesKey,
final Preferences _preferences = prefBox.get( defaultValue: const Preferences(),
LocalDatabaseService.preferencesKey, )!;
defaultValue: const Preferences(),
)!;
return Slider( return Slider(
value: _preferences.skillLevel.toDouble(), value: _preferences.skillLevel.toDouble(),
min: 1, min: 1,
max: 30, max: 30,
divisions: 29, divisions: 29,
label: _preferences.skillLevel.toString(), label: _preferences.skillLevel.toString(),
onChanged: (value) { onChanged: (value) {
LocalDatabaseService.preferences = LocalDatabaseService.preferences =
_preferences.copyWith(skillLevel: value.toInt()); _preferences.copyWith(skillLevel: value.toInt());
debugPrint("Skill level Slider value: $value"); debugPrint("Skill level Slider value: $value");
}, },
); );
}, },
),
), ),
); );
} }

View File

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

View File

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

View File

@ -23,31 +23,28 @@ class _AnimationDurationSlider extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SliderTheme( return Semantics(
data: AppTheme.sliderThemeData, label: S.of(context).animationDuration,
child: Semantics( child: ValueListenableBuilder(
label: S.of(context).animationDuration, valueListenable: LocalDatabaseService.listenDisplay,
child: ValueListenableBuilder( builder: (context, Box<Display> displayBox, _) {
valueListenable: LocalDatabaseService.listenDisplay, final Display _display = displayBox.get(
builder: (context, Box<Display> displayBox, _) { LocalDatabaseService.colorSettingsKey,
final Display _display = displayBox.get( defaultValue: const Display(),
LocalDatabaseService.colorSettingsKey, )!;
defaultValue: Display(),
)!;
return Slider( return Slider(
value: _display.animationDuration, value: _display.animationDuration,
max: 5.0, max: 5.0,
divisions: 50, divisions: 50,
label: _display.animationDuration.toStringAsFixed(1), label: _display.animationDuration.toStringAsFixed(1),
onChanged: (value) { onChanged: (value) {
debugPrint("[config] AnimationDuration value: $value"); debugPrint("[config] AnimationDuration value: $value");
LocalDatabaseService.display = LocalDatabaseService.display =
_display.copyWith(animationDuration: value); _display.copyWith(animationDuration: value);
}, },
); );
}, },
),
), ),
); );
} }

View File

@ -23,31 +23,28 @@ class _BoardBorderWidthSlider extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SliderTheme( return Semantics(
data: AppTheme.sliderThemeData, label: S.of(context).boardBorderLineWidth,
child: Semantics( child: ValueListenableBuilder(
label: S.of(context).boardBorderLineWidth, valueListenable: LocalDatabaseService.listenDisplay,
child: ValueListenableBuilder( builder: (context, Box<Display> displayBox, _) {
valueListenable: LocalDatabaseService.listenDisplay, final Display _display = displayBox.get(
builder: (context, Box<Display> displayBox, _) { LocalDatabaseService.colorSettingsKey,
final Display _display = displayBox.get( defaultValue: const Display(),
LocalDatabaseService.colorSettingsKey, )!;
defaultValue: Display(),
)!;
return Slider( return Slider(
value: _display.boardBorderLineWidth, value: _display.boardBorderLineWidth,
max: 20.0, max: 20.0,
divisions: 200, divisions: 200,
label: _display.boardBorderLineWidth.toStringAsFixed(1), label: _display.boardBorderLineWidth.toStringAsFixed(1),
onChanged: (value) { onChanged: (value) {
debugPrint("[config] BoardBorderLineWidth value: $value"); debugPrint("[config] BoardBorderLineWidth value: $value");
LocalDatabaseService.display = LocalDatabaseService.display =
_display.copyWith(boardBorderLineWidth: value); _display.copyWith(boardBorderLineWidth: value);
}, },
); );
}, },
),
), ),
); );
} }

View File

@ -23,31 +23,28 @@ class _BoardInnerWidthSlider extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SliderTheme( return Semantics(
data: AppTheme.sliderThemeData, label: S.of(context).boardInnerLineWidth,
child: Semantics( child: ValueListenableBuilder(
label: S.of(context).boardInnerLineWidth, valueListenable: LocalDatabaseService.listenDisplay,
child: ValueListenableBuilder( builder: (context, Box<Display> displayBox, _) {
valueListenable: LocalDatabaseService.listenDisplay, final Display _display = displayBox.get(
builder: (context, Box<Display> displayBox, _) { LocalDatabaseService.colorSettingsKey,
final Display _display = displayBox.get( defaultValue: const Display(),
LocalDatabaseService.colorSettingsKey, )!;
defaultValue: Display(),
)!;
return Slider( return Slider(
value: _display.boardInnerLineWidth, value: _display.boardInnerLineWidth,
max: 20, max: 20,
divisions: 200, divisions: 200,
label: _display.boardInnerLineWidth.toStringAsFixed(1), label: _display.boardInnerLineWidth.toStringAsFixed(1),
onChanged: (value) { onChanged: (value) {
debugPrint("[config] BoardInnerLineWidth value: $value"); debugPrint("[config] BoardInnerLineWidth value: $value");
LocalDatabaseService.display = LocalDatabaseService.display =
_display.copyWith(boardInnerLineWidth: value); _display.copyWith(boardInnerLineWidth: value);
}, },
); );
}, },
),
), ),
); );
} }

View File

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

View File

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

View File

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

View File

@ -34,7 +34,6 @@ class _LanguagePicker extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
RadioListTile<Locale?>( RadioListTile<Locale?>(
activeColor: AppTheme.switchListTileActiveColor,
title: Text(S.of(context).defaultLanguage), title: Text(S.of(context).defaultLanguage),
groupValue: currentLocale, groupValue: currentLocale,
value: null, value: null,
@ -43,7 +42,6 @@ class _LanguagePicker extends StatelessWidget {
const ListItemDivider(), const ListItemDivider(),
for (var i in languageCodeToStrings.keys) for (var i in languageCodeToStrings.keys)
RadioListTile<Locale>( RadioListTile<Locale>(
activeColor: AppTheme.switchListTileActiveColor,
title: Text(languageCodeToStrings[i]!), title: Text(languageCodeToStrings[i]!),
groupValue: currentLocale, groupValue: currentLocale,
value: i, 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_card.dart';
import 'package:sanmill/shared/settings/settings_list_tile.dart'; import 'package:sanmill/shared/settings/settings_list_tile.dart';
import 'package:sanmill/shared/settings/settings_switch_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'; import 'package:sanmill/shared/theme/app_theme.dart';
part 'package:sanmill/screens/personalization_settings/animation_duration_slider.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, _) { Widget _buildColor(BuildContext context, Box<ColorSettings> colorBox, _) {
final ColorSettings _colorSettings = colorBox.get( final ColorSettings _colorSettings = colorBox.get(
LocalDatabaseService.colorSettingsKey, LocalDatabaseService.colorSettingsKey,
defaultValue: ColorSettings(), defaultValue: const ColorSettings(),
)!; )!;
return SettingsCard( return SettingsCard(
children: <Widget>[ children: <Widget>[
_ColorSelectorListTile( _ColorSelectorListTile(
title: S.of(context).boardColor, title: S.of(context).boardColor,
value: _colorSettings.boardBackgroundColor, value: LocalDatabaseService.colorSettings.boardBackgroundColor,
onChanged: (val) => LocalDatabaseService.colorSettings = onChanged: (val) => LocalDatabaseService.colorSettings =
_colorSettings.copyWith(boardBackgroundColor: val), _colorSettings.copyWith(boardBackgroundColor: val),
), ),
_ColorSelectorListTile( _ColorSelectorListTile(
title: S.of(context).backgroundColor, title: S.of(context).backgroundColor,
value: _colorSettings.darkBackgroundColor, value: LocalDatabaseService.colorSettings.darkBackgroundColor,
onChanged: (val) => LocalDatabaseService.colorSettings = onChanged: (val) => LocalDatabaseService.colorSettings =
_colorSettings.copyWith(darkBackgroundColor: val), _colorSettings.copyWith(darkBackgroundColor: val),
), ),
_ColorSelectorListTile( _ColorSelectorListTile(
title: S.of(context).lineColor, title: S.of(context).lineColor,
value: _colorSettings.boardLineColor, value: LocalDatabaseService.colorSettings.boardLineColor,
onChanged: (val) => LocalDatabaseService.colorSettings = onChanged: (val) => LocalDatabaseService.colorSettings =
_colorSettings.copyWith(boardLineColor: val), _colorSettings.copyWith(boardLineColor: val),
), ),
_ColorSelectorListTile( _ColorSelectorListTile(
title: S.of(context).whitePieceColor, title: S.of(context).whitePieceColor,
value: _colorSettings.whitePieceColor, value: LocalDatabaseService.colorSettings.whitePieceColor,
onChanged: (val) => LocalDatabaseService.colorSettings = onChanged: (val) => LocalDatabaseService.colorSettings =
_colorSettings.copyWith(whitePieceColor: val), _colorSettings.copyWith(whitePieceColor: val),
), ),
_ColorSelectorListTile( _ColorSelectorListTile(
title: S.of(context).blackPieceColor, title: S.of(context).blackPieceColor,
value: _colorSettings.blackPieceColor, value: LocalDatabaseService.colorSettings.blackPieceColor,
onChanged: (val) => LocalDatabaseService.colorSettings = onChanged: (val) => LocalDatabaseService.colorSettings =
_colorSettings.copyWith(blackPieceColor: val), _colorSettings.copyWith(blackPieceColor: val),
), ),
_ColorSelectorListTile( _ColorSelectorListTile(
title: S.of(context).pieceHighlightColor, title: S.of(context).pieceHighlightColor,
value: _colorSettings.pieceHighlightColor, value: LocalDatabaseService.colorSettings.pieceHighlightColor,
onChanged: (val) => LocalDatabaseService.colorSettings = onChanged: (val) => LocalDatabaseService.colorSettings =
_colorSettings.copyWith(pieceHighlightColor: val), _colorSettings.copyWith(pieceHighlightColor: val),
), ),
_ColorSelectorListTile( _ColorSelectorListTile(
title: S.of(context).messageColor, title: S.of(context).messageColor,
value: _colorSettings.messageColor, value: LocalDatabaseService.colorSettings.messageColor,
onChanged: (val) => LocalDatabaseService.colorSettings = onChanged: (val) => LocalDatabaseService.colorSettings =
_colorSettings.copyWith(messageColor: val), _colorSettings.copyWith(messageColor: val),
), ),
_ColorSelectorListTile( _ColorSelectorListTile(
title: S.of(context).drawerColor, title: S.of(context).drawerColor,
value: _colorSettings.drawerColor, value: LocalDatabaseService.colorSettings.drawerColor,
onChanged: (val) => LocalDatabaseService.colorSettings = onChanged: (val) => LocalDatabaseService.colorSettings =
_colorSettings.copyWith(drawerColor: val), _colorSettings.copyWith(drawerColor: val),
), ),
_ColorSelectorListTile( _ColorSelectorListTile(
title: S.of(context).drawerBackgroundColor, title: S.of(context).drawerBackgroundColor,
value: _colorSettings.drawerBackgroundColor, value: LocalDatabaseService.colorSettings.drawerBackgroundColor,
onChanged: (val) => LocalDatabaseService.colorSettings = onChanged: (val) => LocalDatabaseService.colorSettings =
_colorSettings.copyWith(drawerBackgroundColor: val), _colorSettings.copyWith(drawerBackgroundColor: val),
), ),
_ColorSelectorListTile( _ColorSelectorListTile(
title: S.of(context).drawerTextColor, title: S.of(context).drawerTextColor,
value: _colorSettings.drawerTextColor, value: LocalDatabaseService.colorSettings.drawerTextColor,
onChanged: (val) => LocalDatabaseService.colorSettings = onChanged: (val) => LocalDatabaseService.colorSettings =
_colorSettings.copyWith(drawerTextColor: val), _colorSettings.copyWith(drawerTextColor: val),
), ),
_ColorSelectorListTile( _ColorSelectorListTile(
title: S.of(context).drawerHighlightItemColor, title: S.of(context).drawerHighlightItemColor,
value: _colorSettings.drawerHighlightItemColor, value: LocalDatabaseService.colorSettings.drawerHighlightItemColor,
onChanged: (val) => onChanged: (val) =>
LocalDatabaseService.colorSettings = _colorSettings.copyWith( LocalDatabaseService.colorSettings = _colorSettings.copyWith(
drawerHighlightItemColor: val, drawerHighlightItemColor: val,
@ -188,7 +189,7 @@ class PersonalizationSettingsPage extends StatelessWidget {
), ),
_ColorSelectorListTile( _ColorSelectorListTile(
title: S.of(context).mainToolbarBackgroundColor, title: S.of(context).mainToolbarBackgroundColor,
value: _colorSettings.mainToolbarBackgroundColor, value: LocalDatabaseService.colorSettings.mainToolbarBackgroundColor,
onChanged: (val) => onChanged: (val) =>
LocalDatabaseService.colorSettings = _colorSettings.copyWith( LocalDatabaseService.colorSettings = _colorSettings.copyWith(
mainToolbarBackgroundColor: val, mainToolbarBackgroundColor: val,
@ -196,13 +197,14 @@ class PersonalizationSettingsPage extends StatelessWidget {
), ),
_ColorSelectorListTile( _ColorSelectorListTile(
title: S.of(context).mainToolbarIconColor, title: S.of(context).mainToolbarIconColor,
value: _colorSettings.mainToolbarIconColor, value: LocalDatabaseService.colorSettings.mainToolbarIconColor,
onChanged: (val) => LocalDatabaseService.colorSettings = onChanged: (val) => LocalDatabaseService.colorSettings =
_colorSettings.copyWith(mainToolbarIconColor: val), _colorSettings.copyWith(mainToolbarIconColor: val),
), ),
_ColorSelectorListTile( _ColorSelectorListTile(
title: S.of(context).navigationToolbarBackgroundColor, title: S.of(context).navigationToolbarBackgroundColor,
value: _colorSettings.navigationToolbarBackgroundColor, value: LocalDatabaseService
.colorSettings.navigationToolbarBackgroundColor,
onChanged: (val) => onChanged: (val) =>
LocalDatabaseService.colorSettings = _colorSettings.copyWith( LocalDatabaseService.colorSettings = _colorSettings.copyWith(
navigationToolbarBackgroundColor: val, navigationToolbarBackgroundColor: val,
@ -210,7 +212,7 @@ class PersonalizationSettingsPage extends StatelessWidget {
), ),
_ColorSelectorListTile( _ColorSelectorListTile(
title: S.of(context).navigationToolbarIconColor, title: S.of(context).navigationToolbarIconColor,
value: _colorSettings.navigationToolbarIconColor, value: LocalDatabaseService.colorSettings.navigationToolbarIconColor,
onChanged: (val) => onChanged: (val) =>
LocalDatabaseService.colorSettings = _colorSettings.copyWith( LocalDatabaseService.colorSettings = _colorSettings.copyWith(
navigationToolbarIconColor: val, navigationToolbarIconColor: val,
@ -223,7 +225,7 @@ class PersonalizationSettingsPage extends StatelessWidget {
Widget _buildDisplay(BuildContext context, Box<Display> displayBox, _) { Widget _buildDisplay(BuildContext context, Box<Display> displayBox, _) {
final Display _display = displayBox.get( final Display _display = displayBox.get(
LocalDatabaseService.colorSettingsKey, LocalDatabaseService.colorSettingsKey,
defaultValue: Display(), defaultValue: const Display(),
)!; )!;
return SettingsCard( return SettingsCard(
children: <Widget>[ children: <Widget>[
@ -318,8 +320,9 @@ class PersonalizationSettingsPage extends StatelessWidget {
valueListenable: LocalDatabaseService.listenDisplay, valueListenable: LocalDatabaseService.listenDisplay,
builder: _buildDisplay, builder: _buildDisplay,
), ),
const SizedBox(height: AppTheme.sizedBoxHeight), const CustomSpacer(),
Text(S.of(context).color, style: AppTheme.settingsHeaderStyle), Text(S.of(context).color, style: AppTheme.settingsHeaderStyle),
// TODO: [Leptopoda] remove the value listenable as we access the ColorSettings via Them.of(constant)
ValueListenableBuilder( ValueListenableBuilder(
valueListenable: LocalDatabaseService.listenColorSettings, valueListenable: LocalDatabaseService.listenColorSettings,
builder: _buildColor, builder: _buildColor,

View File

@ -23,31 +23,28 @@ class _PieceWidthSlider extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SliderTheme( return Semantics(
data: AppTheme.sliderThemeData, label: S.of(context).pieceWidth,
child: Semantics( child: ValueListenableBuilder(
label: S.of(context).pieceWidth, valueListenable: LocalDatabaseService.listenDisplay,
child: ValueListenableBuilder( builder: (context, Box<Display> displayBox, _) {
valueListenable: LocalDatabaseService.listenDisplay, final Display _display = displayBox.get(
builder: (context, Box<Display> displayBox, _) { LocalDatabaseService.colorSettingsKey,
final Display _display = displayBox.get( defaultValue: const Display(),
LocalDatabaseService.colorSettingsKey, )!;
defaultValue: Display(),
)!;
return Slider( return Slider(
value: _display.pieceWidth, value: _display.pieceWidth,
min: 0.5, min: 0.5,
divisions: 50, divisions: 50,
label: _display.pieceWidth.toStringAsFixed(1), label: _display.pieceWidth.toStringAsFixed(1),
onChanged: (value) { onChanged: (value) {
debugPrint("[config] pieceWidth value: $value"); debugPrint("[config] pieceWidth value: $value");
LocalDatabaseService.display = LocalDatabaseService.display =
_display.copyWith(pieceWidth: value); _display.copyWith(pieceWidth: value);
}, },
); );
}, },
),
), ),
); );
} }

View File

@ -36,14 +36,12 @@ class _PointStyleModal extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
RadioListTile( RadioListTile(
activeColor: AppTheme.switchListTileActiveColor,
title: Text(S.of(context).none), title: Text(S.of(context).none),
groupValue: pointStyle, groupValue: pointStyle,
value: 0, value: 0,
onChanged: onChanged, onChanged: onChanged,
), ),
RadioListTile( RadioListTile(
activeColor: AppTheme.switchListTileActiveColor,
title: Text(S.of(context).solid), title: Text(S.of(context).solid),
groupValue: pointStyle, groupValue: pointStyle,
value: 1, value: 1,

View File

@ -23,31 +23,28 @@ class _PointWidthSlider extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return SliderTheme( return Semantics(
data: AppTheme.sliderThemeData, label: S.of(context).pointWidth,
child: Semantics( child: ValueListenableBuilder(
label: S.of(context).pointWidth, valueListenable: LocalDatabaseService.listenDisplay,
child: ValueListenableBuilder( builder: (context, Box<Display> displayBox, _) {
valueListenable: LocalDatabaseService.listenDisplay, final Display _display = displayBox.get(
builder: (context, Box<Display> displayBox, _) { LocalDatabaseService.colorSettingsKey,
final Display _display = displayBox.get( defaultValue: const Display(),
LocalDatabaseService.colorSettingsKey, )!;
defaultValue: Display(),
)!;
return Slider( return Slider(
value: _display.pointWidth, value: _display.pointWidth,
max: 30.0, max: 30.0,
divisions: 30, divisions: 30,
label: _display.pointWidth.toStringAsFixed(1), label: _display.pointWidth.toStringAsFixed(1),
onChanged: (value) { onChanged: (value) {
debugPrint("[config] pointWidth value: $value"); debugPrint("[config] pointWidth value: $value");
LocalDatabaseService.display = LocalDatabaseService.display =
_display.copyWith(pointWidth: value); _display.copyWith(pointWidth: value);
}, },
); );
}, },
),
), ),
); );
} }

View File

@ -37,56 +37,48 @@ class _EndGameNMoveRuleModal extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
RadioListTile( RadioListTile(
activeColor: AppTheme.switchListTileActiveColor,
title: const Text('5'), title: const Text('5'),
groupValue: endgameNMoveRule, groupValue: endgameNMoveRule,
value: 5, value: 5,
onChanged: onChanged, onChanged: onChanged,
), ),
RadioListTile( RadioListTile(
activeColor: AppTheme.switchListTileActiveColor,
title: const Text('10'), title: const Text('10'),
groupValue: endgameNMoveRule, groupValue: endgameNMoveRule,
value: 10, value: 10,
onChanged: onChanged, onChanged: onChanged,
), ),
RadioListTile( RadioListTile(
activeColor: AppTheme.switchListTileActiveColor,
title: const Text('20'), title: const Text('20'),
groupValue: endgameNMoveRule, groupValue: endgameNMoveRule,
value: 20, value: 20,
onChanged: onChanged, onChanged: onChanged,
), ),
RadioListTile( RadioListTile(
activeColor: AppTheme.switchListTileActiveColor,
title: const Text('30'), title: const Text('30'),
groupValue: endgameNMoveRule, groupValue: endgameNMoveRule,
value: 30, value: 30,
onChanged: onChanged, onChanged: onChanged,
), ),
RadioListTile( RadioListTile(
activeColor: AppTheme.switchListTileActiveColor,
title: const Text('50'), title: const Text('50'),
groupValue: endgameNMoveRule, groupValue: endgameNMoveRule,
value: 50, value: 50,
onChanged: onChanged, onChanged: onChanged,
), ),
RadioListTile( RadioListTile(
activeColor: AppTheme.switchListTileActiveColor,
title: const Text('60'), title: const Text('60'),
groupValue: endgameNMoveRule, groupValue: endgameNMoveRule,
value: 60, value: 60,
onChanged: onChanged, onChanged: onChanged,
), ),
RadioListTile( RadioListTile(
activeColor: AppTheme.switchListTileActiveColor,
title: const Text('100'), title: const Text('100'),
groupValue: endgameNMoveRule, groupValue: endgameNMoveRule,
value: 100, value: 100,
onChanged: onChanged, onChanged: onChanged,
), ),
RadioListTile( RadioListTile(
activeColor: AppTheme.switchListTileActiveColor,
title: const Text('200'), title: const Text('200'),
groupValue: endgameNMoveRule, groupValue: endgameNMoveRule,
value: 200, value: 200,

View File

@ -36,14 +36,12 @@ class _FlyPieceCountModal extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
RadioListTile( RadioListTile(
activeColor: AppTheme.switchListTileActiveColor,
title: const Text('3'), title: const Text('3'),
groupValue: flyPieceCount, groupValue: flyPieceCount,
value: 3, value: 3,
onChanged: onChanged, onChanged: onChanged,
), ),
RadioListTile( RadioListTile(
activeColor: AppTheme.switchListTileActiveColor,
title: const Text('4'), title: const Text('4'),
groupValue: flyPieceCount, groupValue: flyPieceCount,
value: 4, value: 4,

View File

@ -36,35 +36,30 @@ class _NMoveRuleModal extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
RadioListTile( RadioListTile(
activeColor: AppTheme.switchListTileActiveColor,
title: const Text('30'), title: const Text('30'),
groupValue: nMoveRule, groupValue: nMoveRule,
value: 30, value: 30,
onChanged: onChanged, onChanged: onChanged,
), ),
RadioListTile( RadioListTile(
activeColor: AppTheme.switchListTileActiveColor,
title: const Text('50'), title: const Text('50'),
groupValue: nMoveRule, groupValue: nMoveRule,
value: 50, value: 50,
onChanged: onChanged, onChanged: onChanged,
), ),
RadioListTile( RadioListTile(
activeColor: AppTheme.switchListTileActiveColor,
title: const Text('60'), title: const Text('60'),
groupValue: nMoveRule, groupValue: nMoveRule,
value: 60, value: 60,
onChanged: onChanged, onChanged: onChanged,
), ),
RadioListTile( RadioListTile(
activeColor: AppTheme.switchListTileActiveColor,
title: const Text('100'), title: const Text('100'),
groupValue: nMoveRule, groupValue: nMoveRule,
value: 100, value: 100,
onChanged: onChanged, onChanged: onChanged,
), ),
RadioListTile( RadioListTile(
activeColor: AppTheme.switchListTileActiveColor,
title: const Text('200'), title: const Text('200'),
groupValue: nMoveRule, groupValue: nMoveRule,
value: 200, value: 200,

View File

@ -36,28 +36,24 @@ class _PieceCountModal extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: <Widget>[
RadioListTile( RadioListTile(
activeColor: AppTheme.switchListTileActiveColor,
title: const Text('9'), title: const Text('9'),
groupValue: piecesCount, groupValue: piecesCount,
value: 9, value: 9,
onChanged: onChanged, onChanged: onChanged,
), ),
RadioListTile( RadioListTile(
activeColor: AppTheme.switchListTileActiveColor,
title: const Text('10'), title: const Text('10'),
groupValue: piecesCount, groupValue: piecesCount,
value: 10, value: 10,
onChanged: onChanged, onChanged: onChanged,
), ),
RadioListTile( RadioListTile(
activeColor: AppTheme.switchListTileActiveColor,
title: const Text('11'), title: const Text('11'),
groupValue: piecesCount, groupValue: piecesCount,
value: 11, value: 11,
onChanged: onChanged, onChanged: onChanged,
), ),
RadioListTile( RadioListTile(
activeColor: AppTheme.switchListTileActiveColor,
title: const Text('12'), title: const Text('12'),
groupValue: piecesCount, groupValue: piecesCount,
value: 12, 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_card.dart';
import 'package:sanmill/shared/settings/settings_list_tile.dart'; import 'package:sanmill/shared/settings/settings_list_tile.dart';
import 'package:sanmill/shared/settings/settings_switch_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/snackbar.dart';
import 'package:sanmill/shared/theme/app_theme.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), Text(S.of(context).placing, style: AppTheme.settingsHeaderStyle),
SettingsCard( SettingsCard(
children: <Widget>[ 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), Text(S.of(context).moving, style: AppTheme.settingsHeaderStyle),
SettingsCard( SettingsCard(
children: <Widget>[ 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), Text(S.of(context).mayFly, style: AppTheme.settingsHeaderStyle),
SettingsCard( SettingsCard(
children: <Widget>[ 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), Text(S.of(context).removing, style: AppTheme.settingsHeaderStyle),
SettingsCard( SettingsCard(
children: <Widget>[ children: <Widget>[

View File

@ -181,7 +181,7 @@ class Audios {
assert(false); 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 { try {
await _stopSound(); await _stopSound();

View File

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

View File

@ -75,6 +75,7 @@ class Constants {
static final windowAspectRatio = windowHeight / windowWidth; 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 isSmallScreen => Constants.windowHeight <= 800;
bool get isLargeScreen => !isSmallScreen; bool get isLargeScreen => !isSmallScreen;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -22,7 +22,7 @@ class PiecePaintParam {
final String piece; final String piece;
final Offset pos; final Offset pos;
final bool animated; final bool animated;
PiecePaintParam({ const PiecePaintParam({
required this.piece, required this.piece,
required this.pos, required this.pos,
required this.animated, required this.animated,
@ -55,52 +55,21 @@ class PiecesPainter extends PiecesBasePainter {
} }
@override @override
void paint(Canvas canvas, Size size) { void paint(Canvas canvas, Size size) => _doPaint(canvas, thePaint);
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,
);
}
@override @override
bool shouldRepaint(CustomPainter oldDelegate) { bool shouldRepaint(CustomPainter oldDelegate) => true;
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;
void _doPaint(Canvas canvas, Paint paint) {
final shadowPath = Path(); final shadowPath = Path();
final piecesToDraw = <PiecePaintParam>[]; final piecesToDraw = <PiecePaintParam>[];
final offset = Offset(
AppTheme.boardPadding + squareWidth / 2,
AppTheme.boardPadding + squareWidth / 2,
);
late Color blurPositionColor; late Color blurPositionColor;
Color focusPositionColor;
// Draw pieces on board // Draw pieces on board
for (var row = 0; row < 7; row++) { for (var row = 0; row < 7; row++) {
@ -110,7 +79,7 @@ class PiecesPainter extends PiecesBasePainter {
if (piece == Piece.noPiece) continue; 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; final animated = focusIndex == index;
piecesToDraw piecesToDraw
@ -171,27 +140,20 @@ class PiecesPainter extends PiecesBasePainter {
case Piece.ban: case Piece.ban:
//print("pps.piece is Ban"); //print("pps.piece is Ban");
break; break;
default:
assert(false);
break;
} }
} }
// draw focus and blur position // draw focus and blur position
final int row = focusIndex ~/ 7; final int row = focusIndex ~/ 7;
final int column = focusIndex % 7; final int column = focusIndex % 7;
if (focusIndex != invalidIndex) { if (focusIndex != invalidIndex) {
focusPositionColor = paint.color = LocalDatabaseService.colorSettings.pieceHighlightColor;
LocalDatabaseService.colorSettings.pieceHighlightColor;
paint.color = focusPositionColor;
paint.style = PaintingStyle.stroke; paint.style = PaintingStyle.stroke;
paint.strokeWidth = 2; paint.strokeWidth = 2;
canvas.drawCircle( canvas.drawCircle(
Offset(left + column * squareWidth, top + row * squareWidth), offset.translate(column * squareWidth, row * squareWidth),
animatedPieceWidth / 2, animatedPieceWidth / 2,
paint, paint,
); );
@ -205,7 +167,7 @@ class PiecesPainter extends PiecesBasePainter {
paint.style = PaintingStyle.fill; paint.style = PaintingStyle.fill;
canvas.drawCircle( canvas.drawCircle(
Offset(left + column * squareWidth, top + row * squareWidth), offset.translate(column * squareWidth, row * squareWidth),
animatedPieceWidth / 2 * 0.8, animatedPieceWidth / 2 * 0.8,
paint, 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:flutter/material.dart';
import 'package:sanmill/shared/list_item_divider.dart'; import 'package:sanmill/shared/list_item_divider.dart';
import 'package:sanmill/shared/theme/app_theme.dart';
class SettingsCard extends StatelessWidget { class SettingsCard extends StatelessWidget {
const SettingsCard({ const SettingsCard({
@ -31,8 +30,6 @@ class SettingsCard extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Card( return Card(
color: AppTheme.cardColor,
margin: AppTheme.cardMargin,
child: ListView.separated( child: ListView.separated(
physics: const NeverScrollableScrollPhysics(), physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true, shrinkWrap: true,

View File

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

View File

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

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( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text( content: Text(message),
message,
style: TextStyle(
fontSize: LocalDatabaseService.display.fontSize,
),
),
duration: duration, 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:flutter/material.dart';
import 'package:sanmill/services/storage/storage.dart'; import 'package:sanmill/services/storage/storage.dart';
import 'package:sanmill/shared/constants.dart';
import 'package:sanmill/shared/theme/colors.dart'; import 'package:sanmill/shared/theme/colors.dart';
/// The Apps Theme
@immutable
class AppTheme { class AppTheme {
const 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( static final lightThemeData = ThemeData(
primarySwatch: AppTheme.appPrimaryColor,
brightness: Brightness.light, brightness: Brightness.light,
primarySwatch: _appPrimaryColor,
sliderTheme: _sliderThemeData,
textTheme: _textTheme,
dividerColor: _listItemDividerColor,
cardTheme: _cardTheme,
); );
/// dark theme
static final darkThemeData = ThemeData( static final darkThemeData = ThemeData(
primarySwatch: AppTheme.appPrimaryColor,
brightness: Brightness.dark, brightness: Brightness.dark,
primarySwatch: _appPrimaryColor,
toggleableActiveColor: _appPrimaryColor,
sliderTheme: _sliderThemeData,
textTheme: _textTheme,
dividerColor: _listItemDividerColor,
cardTheme: _cardTheme,
); );
// Color // Color
static const appPrimaryColor = Colors.green; // App bar & Dialog button 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?
// Theme // Theme
static const _sliderThemeData = SliderThemeData(
static const sliderThemeData = SliderThemeData(
trackHeight: 20, trackHeight: 20,
activeTrackColor: Colors.green, activeTrackColor: Colors.green,
inactiveTrackColor: Colors.grey, inactiveTrackColor: Colors.grey,
@ -96,9 +60,7 @@ class AppTheme {
disabledInactiveTrackColor: Colors.cyan, disabledInactiveTrackColor: Colors.cyan,
activeTickMarkColor: Colors.black, activeTickMarkColor: Colors.black,
inactiveTickMarkColor: Colors.green, inactiveTickMarkColor: Colors.green,
//overlayColor: Colors.yellow,
overlappingShapeStrokeColor: Colors.black, overlappingShapeStrokeColor: Colors.black,
//overlayShape: RoundSliderOverlayShape(),
valueIndicatorColor: Colors.green, valueIndicatorColor: Colors.green,
showValueIndicator: ShowValueIndicator.always, showValueIndicator: ShowValueIndicator.always,
minThumbSeparation: 100, minThumbSeparation: 100,
@ -111,36 +73,111 @@ class AppTheme {
valueIndicatorTextStyle: TextStyle(fontSize: 24), 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( static TextStyle simpleDialogOptionTextStyle = TextStyle(
fontSize: LocalDatabaseService.display.fontSize + 4.0, fontSize: LocalDatabaseService.display.fontSize + 4.0,
color: AppTheme.simpleDialogOptionTextColor, color: _simpleDialogOptionTextColor,
); );
static TextStyle moveHistoryTextStyle = TextStyle( static TextStyle moveHistoryTextStyle = TextStyle(
fontSize: LocalDatabaseService.display.fontSize + 2.0, fontSize: LocalDatabaseService.display.fontSize + 2.0,
height: 1.5, height: 1.5,
color: moveHistoryTextColor, color: _moveHistoryTextColor,
); );
static double boardTop = isLargeScreen ? 75.0 : 36.0; static TextStyle drawerHeaderTextStyle = TextStyle(
static double boardMargin = 10.0; fontSize: LocalDatabaseService.display.fontSize + 16,
static double boardScreenPaddingH = 10.0; fontWeight: FontWeight.w600,
static double boardBorderRadius = 5.0; );
static double boardPadding = 5.0;
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( static TextStyle settingsHeaderStyle = TextStyle(
color: settingsHeaderTextColor, color: _settingsHeaderTextColor,
fontSize: LocalDatabaseService.display.fontSize + 4, fontSize: LocalDatabaseService.display.fontSize + 4,
); );
static TextStyle settingsTextStyle = static TextStyle settingsTextStyle = TextStyle(
TextStyle(fontSize: LocalDatabaseService.display.fontSize); fontSize: LocalDatabaseService.display.fontSize,
);
static const cardMargin = EdgeInsets.symmetric(vertical: 4.0);
static const double drawerWidth = 250.0;
static const double sizedBoxHeight = 16.0; 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'; import 'package:flutter/material.dart';
/// Color Palate
///
/// gathered from https://www.htmlcsscolor.com
class UIColors { class UIColors {
// https://www.htmlcsscolor.com
const UIColors._(); const UIColors._();
static const Color white = Color(0xFFFFFFFF); static const Color white = Color(0xFFFFFFFF);
@ -33,14 +35,14 @@ class UIColors {
static const Color darkGrey = Color(0xFF313A44); static const Color darkGrey = Color(0xFF313A44);
static const Color burlyWood = Color(0xFFDEB887); static const Color burlyWood = Color(0xFFDEB887);
static const Color cottonCandy = Color.fromARGB(0xFF, 255, 189, 219); static const Color cottonCandy = Color(0xffffbddb);
static const Color turkishRose = Color.fromARGB(0xFF, 163, 109, 173); static const Color turkishRose = Color(0xffa36dad);
static const Color crusoe = Color(0xFF165B31); static const Color crusoe = Color(0xFF165B31);
static const Color forestGreen = Color(0xFF228B22); static const Color forestGreen = Color(0xFF228B22);
static const Color freeSpeechGreen = Color(0xFF09F911); 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 papayaWhip = Color(0xFFFFEFD5);
static const Color stormGrey = Color.fromARGB(0xFF, 119, 121, 131); static const Color stormGrey = Color(0xff777983);
static const Color turmeric = Color.fromARGB(0xFF, 186, 202, 68); static const Color turmeric = Color(0xffbaca44);
static const Color LavenderBlush = Color.fromARGB(0xFF, 255, 240, 246); static const Color LavenderBlush = Color(0xfffff0f6);
} }

View File

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