diff --git a/android/gradle.properties b/android/gradle.properties index 621336f47b3be71128005116384f1c3636771131..518a71328fa72488a4d0435c21984a21b90946da 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -1,5 +1,5 @@ org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true android.enableJetifier=true -app.versionName=1.0.40 -app.versionCode=41 +app.versionName=1.0.41 +app.versionCode=42 diff --git a/lib/cubit/game_cubit.dart b/lib/cubit/game_cubit.dart index 231ed500fe9439775ae1ed1a07336c481052ba30..336c70ff15f76901a98ee556c2dfb489e64f445b 100644 --- a/lib/cubit/game_cubit.dart +++ b/lib/cubit/game_cubit.dart @@ -1,7 +1,8 @@ import 'package:equatable/equatable.dart'; import 'package:flutter/material.dart'; import 'package:hydrated_bloc/hydrated_bloc.dart'; -import 'package:random/models/game_data.dart'; + +import 'package:random/models/game/game.dart'; part 'game_state.dart'; @@ -12,13 +13,13 @@ class GameCubit extends HydratedCubit<GameState> { emit(gameState); } - void updateGameState(GameData gameData) { + void updateGameState(Game gameData) { emit(GameState(game: gameData)); } @override GameState? fromJson(Map<String, dynamic> json) { - GameData game = json['game'] as GameData; + Game game = json['game'] as Game; return GameState( game: game, diff --git a/lib/cubit/game_state.dart b/lib/cubit/game_state.dart index ea6c33cf1ce0150ac8b9c358005e42a64447ab0d..3e4d0d092cf5da751fd66f72dedea0501878acbd 100644 --- a/lib/cubit/game_state.dart +++ b/lib/cubit/game_state.dart @@ -6,7 +6,7 @@ class GameState extends Equatable { this.game, }); - final GameData? game; + final Game? game; @override List<Object?> get props => <Object?>[ diff --git a/lib/models/game/game.dart b/lib/models/game/game.dart new file mode 100644 index 0000000000000000000000000000000000000000..bf777d743a798124664fa152ab8121e5c694442f --- /dev/null +++ b/lib/models/game/game.dart @@ -0,0 +1,93 @@ +import 'dart:math'; + +import 'package:random/models/game/game_board.dart'; +import 'package:random/models/game/game_cell.dart'; +import 'package:random/models/game/game_settings.dart'; + +class Game { + GameBoard board; + GameSettings settings; + bool isRunning = false; + bool isFinished = false; + int availableBlocksCount = 0; + int movesCount = 0; + int score = 0; + + Game({ + required this.board, + required this.settings, + this.isRunning = false, + }); + + factory Game.createNull() { + return Game( + board: GameBoard.createNull(), + settings: GameSettings.createDefault(), + ); + } + + factory Game.createNew({GameSettings? gameSettings}) { + GameSettings settings = gameSettings ?? GameSettings.createDefault(); + + return Game( + board: GameBoard.createRandom(settings), + settings: settings, + isRunning: true, + ); + } + + void stop() { + this.isRunning = false; + this.isFinished = true; + } + + GameCell getCell(int x, int y) { + return this.board.cells[y][x]; + } + + int? getCellValue(int x, int y) { + return this.getCell(x, y).value; + } + + void updateCellValue(int x, int y, int? value) { + this.board.cells[y][x].value = value; + } + + void setRandomCellValue(int x, int y, GameSettings settings) { + final int maxValue = settings.colorsCount; + final rand = new Random(); + int value = 1 + rand.nextInt(maxValue); + + this.board.cells[y][x].value = value; + } + + void increaseMovesCount() { + this.movesCount += 1; + } + + void increaseScore(int? count) { + this.score += (count ?? 0); + } + + String toString() { + return 'Game(' + this.toJson().toString() + ')'; + } + + Map<String, dynamic>? toJson() { + return <String, dynamic>{ + 'board': this.board.toJson(), + 'settings': this.settings.toJson(), + 'isRunning': this.isRunning, + 'isFinished': this.isFinished, + 'availableBlocksCount': this.availableBlocksCount, + 'movesCount': this.movesCount, + 'score': this.score, + }; + } + + void dump() { + GameBoard.printGrid(this.board.cells); + print(this.settings.toJson()); + print(this.toJson()); + } +} diff --git a/lib/models/game/game_board.dart b/lib/models/game/game_board.dart new file mode 100644 index 0000000000000000000000000000000000000000..65654940e1fea58ca44dfaf290fab8d34a9d2806 --- /dev/null +++ b/lib/models/game/game_board.dart @@ -0,0 +1,61 @@ +import 'dart:math'; + +import 'package:random/models/game/game_cell.dart'; +import 'package:random/models/game/game_settings.dart'; + +class GameBoard { + final List<List<GameCell>> cells; + + GameBoard({ + required this.cells, + }); + + factory GameBoard.createNull() { + return GameBoard(cells: []); + } + + factory GameBoard.createRandom(GameSettings gameSettings) { + final int boardSizeHorizontal = gameSettings.boardSize; + final int boardSizeVertical = gameSettings.boardSize; + final int maxValue = gameSettings.colorsCount; + + final rand = new Random(); + + List<List<GameCell>> grid = []; + for (var rowIndex = 0; rowIndex < boardSizeVertical; rowIndex++) { + List<GameCell> row = []; + for (var colIndex = 0; colIndex < boardSizeHorizontal; colIndex++) { + int value = 1 + rand.nextInt(maxValue); + row.add(GameCell(value)); + } + grid.add(row); + } + printGrid(grid); + + return GameBoard(cells: grid); + } + + static printGrid(List<List<GameCell>> cells) { + print(''); + print('-------'); + for (var rowIndex = 0; rowIndex < cells.length; rowIndex++) { + String row = ''; + for (var colIndex = 0; colIndex < cells[rowIndex].length; colIndex++) { + row += cells[rowIndex][colIndex].value.toString(); + } + print(row); + } + print('-------'); + print(''); + } + + String toString() { + return 'Board(' + this.toJson().toString() + ')'; + } + + Map<String, dynamic>? toJson() { + return <String, dynamic>{ + 'cells': this.cells.toString(), + }; + } +} diff --git a/lib/models/game/game_cell.dart b/lib/models/game/game_cell.dart new file mode 100644 index 0000000000000000000000000000000000000000..25667ccf76bfbd4ef65f8651c120a7dbaab641b8 --- /dev/null +++ b/lib/models/game/game_cell.dart @@ -0,0 +1,17 @@ +class GameCell { + int? value; + + GameCell( + this.value, + ); + + String toString() { + return 'Cell(' + this.toJson().toString() + ')'; + } + + Map<String, dynamic>? toJson() { + return <String, dynamic>{ + 'value': this.value, + }; + } +} diff --git a/lib/models/game/game_settings.dart b/lib/models/game/game_settings.dart new file mode 100644 index 0000000000000000000000000000000000000000..4610c789c81b6f0d92745b45c089035c899c0772 --- /dev/null +++ b/lib/models/game/game_settings.dart @@ -0,0 +1,45 @@ +class DefaultGameSettings { + static const int defaultBoardSizeValue = 6; + static const List<int> allowedBoardSizeValues = [ + 5, + 6, + 10, + 15, + ]; + + static const int defaultColorsCountValue = 7; + static const List<int> allowedColorsCountValues = [ + 4, + 5, + 6, + 7, + ]; +} + +class GameSettings { + final int boardSize; + final int colorsCount; + + GameSettings({ + required this.boardSize, + required this.colorsCount, + }); + + factory GameSettings.createDefault() { + return GameSettings( + boardSize: DefaultGameSettings.defaultBoardSizeValue, + colorsCount: DefaultGameSettings.defaultColorsCountValue, + ); + } + + String toString() { + return 'GameSettings(' + this.toJson().toString() + ')'; + } + + Map<String, dynamic>? toJson() { + return <String, dynamic>{ + 'boardSize': this.boardSize, + 'colorsCount': this.colorsCount, + }; + } +} diff --git a/lib/models/game_data.dart b/lib/models/game_data.dart deleted file mode 100644 index 6a519d5bb925009b7cb338ad245eb00586130803..0000000000000000000000000000000000000000 --- a/lib/models/game_data.dart +++ /dev/null @@ -1,120 +0,0 @@ -import 'dart:convert'; -import 'dart:math'; - -class GameDataItem { - final int? value; - - const GameDataItem({ - required this.value, - }); - - factory GameDataItem.fromValue(int? value) { - return GameDataItem( - value: value, - ); - } - - factory GameDataItem.fromJson(Map<String, dynamic>? json) { - return GameDataItem( - value: (json?['value'] != null) ? (json?['value'] as int) : null, - ); - } - - Map<String, dynamic>? toJson() { - return <String, dynamic>{ - 'value': this.value, - }; - } - - String toString() { - return jsonEncode(this.toJson()); - } -} - -class GameData { - final bool isReady; - final int boardSize; - final List<List<GameDataItem>> board; - - const GameData({ - required this.isReady, - required this.boardSize, - required this.board, - }); - - factory GameData.createNew(int boardSize) { - final List<List<GameDataItem>> cells = []; - - for (var y = 0; y < boardSize; y++) { - final List<GameDataItem> line = []; - for (var x = 0; x < boardSize; x++) { - final GameDataItem item = new GameDataItem(value: null); - line.add(item); - } - - cells.add(line); - } - - return GameData( - isReady: true, - boardSize: boardSize, - board: cells, - ); - } - - factory GameData.createRandom(int boardSize) { - const allowedValues = [0, 1, 2, 3, 4, 5]; - final allowedValuesSize = allowedValues.length; - - final List<List<GameDataItem>> cells = []; - - for (var y = 0; y < boardSize; y++) { - final List<GameDataItem> line = []; - for (var x = 0; x < boardSize; x++) { - final value = allowedValues[Random().nextInt(allowedValuesSize)]; - final GameDataItem item = new GameDataItem(value: value); - line.add(item); - } - - cells.add(line); - } - - return GameData( - isReady: true, - boardSize: boardSize, - board: cells, - ); - } - - GameDataItem getCell(int x, int y) { - return this.board[y][x]; - } - - int? getCellValue(int x, int y) { - return this.getCell(x, y).value; - } - - void updateCellValue(int x, int y, int? value) { - this.board[y][x] = new GameDataItem.fromValue(value); - } - - factory GameData.fromJson(Map<String, dynamic>? json) { - return GameData( - isReady: (json?['isReady'] != null) ? (json?['isReady'] as bool) : false, - boardSize: (json?['boardSize'] != null) ? (json?['boardSize'] as int) : 0, - board: (json?['board'] != null) ? (json?['board'] as List<List<GameDataItem>>) : [], - ); - } - - Map<String, dynamic>? toJson() { - return <String, dynamic>{ - 'isReady': this.isReady, - 'boardSize': this.boardSize, - 'board': this.board, - }; - } - - String toString() { - return jsonEncode(this.toJson()); - } -} diff --git a/lib/ui/painters/cell_painter.dart b/lib/ui/painters/cell_painter.dart index e50ce3d26370860f7137b60613de5b44a375c7c9..a2cf510a27634d1d33f6b15d92c2ce843aff7f36 100644 --- a/lib/ui/painters/cell_painter.dart +++ b/lib/ui/painters/cell_painter.dart @@ -19,7 +19,6 @@ class CellPainter extends CustomPainter { AppColors.contentColorYellow, AppColors.contentColorPink, AppColors.contentColorWhite, - AppColors.mainTextColor3, ]; return availableColors[index % availableColors.length]; diff --git a/lib/ui/screens/game_page.dart b/lib/ui/screens/game_page.dart index 93cd8573714e6ecd1e1a31767cee758f05619302..7822504342cb02e8b352f05c080441c38e81fa57 100644 --- a/lib/ui/screens/game_page.dart +++ b/lib/ui/screens/game_page.dart @@ -3,8 +3,9 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:unicons/unicons.dart'; import 'package:random/cubit/game_cubit.dart'; -import 'package:random/models/game_data.dart'; -import 'package:random/ui/widgets/game_board.dart'; +import 'package:random/models/game/game.dart'; +import 'package:random/ui/widgets/game/game_settings.dart'; +import 'package:random/ui/widgets/game/game_board.dart'; class GamePage extends StatefulWidget { const GamePage({super.key}); @@ -13,133 +14,61 @@ class GamePage extends StatefulWidget { State<GamePage> createState() => _GamePageState(); } -class _GamePageState extends State<GamePage> with TickerProviderStateMixin { - static const boardSize = 6; - - List<List<Animation<double>?>> animations = List.generate( - boardSize, - (i) => List.generate( - boardSize, - (i) => null, - ), - ); - - void resetAnimations() { - animations = List.generate( - boardSize, - (i) => List.generate( - boardSize, - (i) => null, - ), - ); - } - - void createNewGame(GameCubit gameCubit) { - final GameData newGame = GameData.createRandom(boardSize); - gameCubit.updateGameState(newGame); - } - - void removeCell(GameCubit gameCubit, int x, int y) { - final GameData newGame = gameCubit.state.game ?? GameData.createRandom(boardSize); - - // "remove" cell - newGame.updateCellValue(x, y, null); - setState(() {}); - - // "move down" cells - final controller = AnimationController( - vsync: this, - duration: Duration(milliseconds: 750), - )..addListener(() { - if (mounted) { - setState(() {}); - } - }); - - if (mounted) { - setState(() {}); - } - - Animation<double> animation = Tween( - begin: 0.0, - end: 1.0, - ).animate(CurvedAnimation( - curve: Curves.bounceOut, - parent: controller, - )) - ..addStatusListener((status) { - if (status == AnimationStatus.completed) { - for (var i = 0; i < y; i++) { - newGame.updateCellValue(x, (y - i), newGame.getCellValue(x, (y - i) - 1)); - } - newGame.updateCellValue(x, 0, null); - - resetAnimations(); - setState(() {}); - - controller.dispose(); - } - }); - - for (var i = 0; i < y; i++) { - animations[(y - i) - 1][x] = animation; - } - - controller.forward().orCancel; - } - - void updateCellValue(GameCubit gameCubit, int x, int y, int value) { - final GameData newGame = gameCubit.state.game ?? GameData.createRandom(boardSize); - newGame.updateCellValue(x, y, value); - - gameCubit.updateGameState(newGame); - setState(() {}); +class _GamePageState extends State<GamePage> { + Widget buildGameActionsBloc(BuildContext context) { + return BlocBuilder<GameCubit, GameState>(builder: (context, gameState) { + final GameCubit gameCubit = BlocProvider.of<GameCubit>(context); + + final List<Widget> buttons = [ + IconButton( + onPressed: () { + gameCubit.updateGameState(Game.createNew()); + }, + icon: Icon(UniconsSolid.star), + color: Colors.white, + ) + ]; + + if (gameState.game?.isRunning == true) { + buttons.add(IconButton( + onPressed: () { + final Game currentGame = gameCubit.state.game!; + currentGame.stop(); + + gameCubit.updateGameState(currentGame); + setState(() {}); + }, + icon: Icon(UniconsLine.exit), + color: Colors.white, + )); + } + + return Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: buttons, + ); + }); } @override Widget build(BuildContext context) { + const double boardWidgetWidth = 300; + const double boardWidgetHeight = 300; + return BlocBuilder<GameCubit, GameState>( builder: (context, gameState) { - const boardSize = 6; - const double boardWidgetWidth = 300; - const double boardWidgetHeight = 300; - - final GameCubit gameCubit = BlocProvider.of<GameCubit>(context); - - if (gameState.game?.isReady != true) { - createNewGame(gameCubit); - } - return Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [ - GestureDetector( - child: gameState.game != null - ? GameBoardWidget( - gameData: gameState.game!, - size: Size(boardWidgetWidth, boardWidgetHeight), - animations: animations, - ) - : SizedBox.shrink(), - onTapUp: (details) { - double xTap = details.localPosition.dx; - double yTap = details.localPosition.dy; - - int x = (xTap / boardWidgetWidth * boardSize).toInt(); - int y = (yTap / boardWidgetHeight * boardSize).toInt(); - print('[' + x.toString() + ',' + y.toString() + ']'); - - removeCell(gameCubit, x, y); - }, - ), - IconButton( - onPressed: () { - createNewGame(gameCubit); - }, - icon: Icon(UniconsSolid.star), - color: Colors.white, - ), + gameState.game?.isRunning == true + ? GameBoardWidget( + game: gameState.game!, + widgetSize: Size(boardWidgetWidth, boardWidgetHeight), + ) + : GameSettingsWidget(), + buildGameActionsBloc(context), ], ); }, diff --git a/lib/ui/widgets/game/game_board.dart b/lib/ui/widgets/game/game_board.dart new file mode 100644 index 0000000000000000000000000000000000000000..47453badc4b525abc18890a3e0e360fa6eb79536 --- /dev/null +++ b/lib/ui/widgets/game/game_board.dart @@ -0,0 +1,177 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +import 'package:random/cubit/game_cubit.dart'; +import 'package:random/models/game/game.dart'; +import 'package:random/models/game/game_settings.dart'; +import 'package:random/ui/painters/cell_painter.dart'; +import 'package:random/ui/widgets/game/game_score.dart'; + +class GameBoardWidget extends StatefulWidget { + const GameBoardWidget({ + super.key, + required this.game, + required this.widgetSize, + }); + + final Game game; + final Size widgetSize; + + @override + State<GameBoardWidget> createState() => _GameBoardWidget(); +} + +class _GameBoardWidget extends State<GameBoardWidget> with TickerProviderStateMixin { + List<List<Animation<double>?>> animations = []; + + void resetAnimations(GameSettings gameSettings) { + final boardSize = gameSettings.boardSize; + + animations = List.generate( + boardSize, + (i) => List.generate( + boardSize, + (i) => null, + ), + ); + } + + void removeCell(BuildContext context, int x, int y) { + final GameCubit gameCubit = BlocProvider.of<GameCubit>(context); + final Game updatedGame = gameCubit.state.game ?? Game.createNew(); + + // "remove" cell, update counters + updatedGame.increaseScore(updatedGame.getCellValue(x, y)); + updatedGame.increaseMovesCount(); + updatedGame.updateCellValue(x, y, null); + setState(() {}); + + // "move down" cells + final controller = AnimationController( + vsync: this, + duration: Duration(milliseconds: 750), + )..addListener(() { + if (mounted) { + setState(() {}); + } + }); + + if (mounted) { + setState(() {}); + } + + Animation<double> animation = Tween( + begin: 0.0, + end: 1.0, + ).animate(CurvedAnimation( + curve: Curves.bounceOut, + parent: controller, + )) + ..addStatusListener((status) { + if (status == AnimationStatus.completed) { + // Update cell values + for (var i = 0; i < y; i++) { + updatedGame.updateCellValue(x, (y - i), updatedGame.getCellValue(x, (y - i) - 1)); + } + updatedGame.setRandomCellValue(x, 0, updatedGame.settings); + + resetAnimations(updatedGame.settings); + setState(() {}); + + controller.dispose(); + } + }); + + for (var i = 0; i < y; i++) { + animations[(y - i) - 1][x] = animation; + } + + controller.forward().orCancel; + } + + Widget buildBoard() { + final widgetWidth = widget.widgetSize.width; + final widgetHeight = widget.widgetSize.height; + + final rowsCount = widget.game.settings.boardSize; + final columnsCount = widget.game.settings.boardSize; + + final cellWidth = widgetWidth / columnsCount; + final cellHeight = widgetHeight / rowsCount; + + if (animations.length == 0) { + resetAnimations(widget.game.settings); + } + + final List<Widget> cells = []; + + for (var y = 0; y < rowsCount; y++) { + for (var x = 0; x < columnsCount; x++) { + final int? value = widget.game.getCellValue(x, y); + + if (value != null) { + final Animation<double>? translation = this.animations[y][x]; + + final Widget cellContent = CustomPaint( + size: Size(cellWidth, cellHeight), + willChange: false, + painter: CellPainter(value: value), + ); + + final Widget cellWidget = Positioned( + left: (x * cellWidth).toDouble(), + top: ((y + (translation?.value ?? 0)) * cellHeight).toDouble(), + child: Container( + width: cellWidth, + height: cellHeight, + child: cellContent, + ), + ); + + cells.add(cellWidget); + } + } + } + + return Container( + width: widgetWidth, + height: widgetHeight, + color: Colors.black, + child: Stack( + children: cells, + ), + ); + } + + Widget interactiveBoard(BuildContext context) { + final widgetWidth = widget.widgetSize.width; + final widgetHeight = widget.widgetSize.height; + + final rowsCount = widget.game.settings.boardSize; + final columnsCount = widget.game.settings.boardSize; + + return GestureDetector( + child: buildBoard(), + onTapUp: (details) { + double xTap = details.localPosition.dx; + double yTap = details.localPosition.dy; + + int x = (xTap / widgetWidth * columnsCount).toInt(); + int y = (yTap / widgetHeight * rowsCount).toInt(); + print('[' + x.toString() + ',' + y.toString() + ']'); + + removeCell(context, x, y); + }, + ); + } + + @override + Widget build(BuildContext context) { + return Column( + children: [ + interactiveBoard(context), + GameScoreWidget(game: widget.game), + ], + ); + } +} diff --git a/lib/ui/widgets/game/game_score.dart b/lib/ui/widgets/game/game_score.dart new file mode 100644 index 0000000000000000000000000000000000000000..e52193c8e551583a9432a22529bf26c705b9424e --- /dev/null +++ b/lib/ui/widgets/game/game_score.dart @@ -0,0 +1,34 @@ +import 'package:flutter/material.dart'; + +import 'package:random/models/game/game.dart'; + +class GameScoreWidget extends StatelessWidget { + const GameScoreWidget({ + super.key, + required this.game, + }); + + final Game game; + + @override + Widget build(BuildContext context) { + return Container( + width: MediaQuery.of(context).size.width, + padding: EdgeInsets.all(5), + child: Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text('Settings:'), + Text(' board size: ' + this.game.settings.boardSize.toString()), + Text(' colors count: ' + this.game.settings.colorsCount.toString()), + Text('Game:'), + Text(' isRunning: ' + this.game.isRunning.toString()), + Text(' isFinished: ' + this.game.isFinished.toString()), + Text(' movesCount: ' + this.game.movesCount.toString()), + Text(' score: ' + this.game.score.toString()), + ], + ), + ); + } +} diff --git a/lib/ui/widgets/game/game_settings.dart b/lib/ui/widgets/game/game_settings.dart new file mode 100644 index 0000000000000000000000000000000000000000..3170c695f5eb4fbb6b6cf8aa1b814c79d0b1420f --- /dev/null +++ b/lib/ui/widgets/game/game_settings.dart @@ -0,0 +1,12 @@ +import 'package:flutter/material.dart'; + +class GameSettingsWidget extends StatelessWidget { + const GameSettingsWidget({ + super.key, + }); + + @override + Widget build(BuildContext context) { + return Text('(fake settings block)'); + } +} diff --git a/lib/ui/widgets/game_board.dart b/lib/ui/widgets/game_board.dart deleted file mode 100644 index 32e980c2283e14547676784e17deb4a9e37113ff..0000000000000000000000000000000000000000 --- a/lib/ui/widgets/game_board.dart +++ /dev/null @@ -1,69 +0,0 @@ -import 'package:flutter/material.dart'; - -import 'package:random/models/game_data.dart'; -import 'package:random/ui/painters/cell_painter.dart'; - -class GameBoardWidget extends StatelessWidget { - const GameBoardWidget({ - super.key, - required this.gameData, - required this.size, - required this.animations, - }); - - final GameData gameData; - final Size size; - final List<List<Animation<double>?>> animations; - - @override - Widget build(BuildContext context) { - final widgetWidth = this.size.width; - final widgetHeight = this.size.height; - - final rowsCount = this.gameData.board.length; - final columnsCount = this.gameData.board[0].length; - - final cellWidth = widgetWidth / columnsCount; - final cellHeight = widgetHeight / rowsCount; - - final List<Widget> cells = []; - - for (var y = 0; y < rowsCount; y++) { - for (var x = 0; x < columnsCount; x++) { - final GameDataItem item = this.gameData.board[y][x]; - int? value = item.value; - - if (value != null) { - final Animation<double>? translation = this.animations[y][x]; - - final Widget cellContent = CustomPaint( - size: Size(cellWidth, cellHeight), - willChange: false, - painter: CellPainter(value: value), - ); - - final Widget cellWidget = Positioned( - left: (x * cellWidth).toDouble(), - top: ((y + (translation?.value ?? 0)) * cellHeight).toDouble(), - child: Container( - width: cellWidth, - height: cellHeight, - child: cellContent, - ), - ); - - cells.add(cellWidget); - } - } - } - - return Container( - width: widgetWidth, - height: widgetHeight, - color: Colors.black, - child: Stack( - children: cells, - ), - ); - } -} diff --git a/pubspec.lock b/pubspec.lock index 1b5533c24d0cf46bcaad81baa383d40e50b29b70..1505f2f3bab4e02e4b77d1b5d90e487a9eb593e5 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -61,10 +61,10 @@ packages: dependency: "direct main" description: name: dio - sha256: "417e2a6f9d83ab396ec38ff4ea5da6c254da71e4db765ad737a42af6930140b7" + sha256: "797e1e341c3dd2f69f2dad42564a6feff3bfb87187d05abb93b9609e6f1645c3" url: "https://pub.dev" source: hosted - version: "5.3.3" + version: "5.4.0" easy_localization: dependency: "direct main" description: @@ -148,10 +148,10 @@ packages: dependency: transitive description: name: http - sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" + sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba url: "https://pub.dev" source: hosted - version: "1.1.0" + version: "1.2.0" http_parser: dependency: transitive description: @@ -164,10 +164,10 @@ packages: dependency: "direct main" description: name: hydrated_bloc - sha256: "24994e61f64904d911683cce1a31dc4ef611619da5253f1de2b7b8fc6f79a118" + sha256: c925e49704c052a8f249226ae7603f86bfa776b910816390763b956c71d2cbaf url: "https://pub.dev" source: hosted - version: "9.1.2" + version: "9.1.3" intl: dependency: transitive description: @@ -228,26 +228,26 @@ packages: dependency: "direct main" description: name: path_provider - sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa + sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72 + sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668" url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.2.2" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d" + sha256: "5a7999be66e000916500be4f15a3633ebceb8302719b47b9cc49ce924125350f" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" path_provider_linux: dependency: transitive description: @@ -260,10 +260,10 @@ packages: dependency: transitive description: name: path_provider_platform_interface - sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c" + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" path_provider_windows: dependency: transitive description: @@ -276,18 +276,18 @@ packages: dependency: transitive description: name: platform - sha256: "0a279f0707af40c890e80b1e9df8bb761694c074ba7e1d4ab1bc4b728e200b59" + sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" url: "https://pub.dev" source: hosted - version: "3.1.3" + version: "3.1.4" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface - sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8 + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" url: "https://pub.dev" source: hosted - version: "2.1.7" + version: "2.1.8" provider: dependency: transitive description: @@ -316,10 +316,10 @@ packages: dependency: transitive description: name: shared_preferences_foundation - sha256: "7bf53a9f2d007329ee6f3df7268fd498f8373602f943c975598bbb34649b62a7" + sha256: "7708d83064f38060c7b39db12aefe449cb8cdc031d6062280087bc4cdb988f5c" url: "https://pub.dev" source: hosted - version: "2.3.4" + version: "2.3.5" shared_preferences_linux: dependency: transitive description: @@ -332,10 +332,10 @@ packages: dependency: transitive description: name: shared_preferences_platform_interface - sha256: d4ec5fc9ebb2f2e056c617112aa75dcf92fc2e4faaf2ae999caa297473f75d8a + sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" shared_preferences_web: dependency: transitive description: @@ -377,10 +377,10 @@ packages: dependency: transitive description: name: synchronized - sha256: "5fcbd27688af6082f5abd611af56ee575342c30e87541d0245f7ff99faa02c60" + sha256: "539ef412b170d65ecdafd780f924e5be3f60032a1128df156adad6c5b373d558" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.0+1" term_glyph: dependency: transitive description: @@ -425,18 +425,18 @@ packages: dependency: transitive description: name: win32 - sha256: "7c99c0e1e2fa190b48d25c81ca5e42036d5cac81430ef249027d97b0935c553f" + sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8" url: "https://pub.dev" source: hosted - version: "5.1.0" + version: "5.2.0" xdg_directories: dependency: transitive description: name: xdg_directories - sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2" + sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d url: "https://pub.dev" source: hosted - version: "1.0.3" + version: "1.0.4" sdks: dart: ">=3.2.0 <4.0.0" flutter: ">=3.16.0" diff --git a/pubspec.yaml b/pubspec.yaml index b0d6d8e00aee8565822bbc1ec0a993a2da234550..f5cb7122fe4613e95e7f1b613d540c3af2d7d38e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: A random application, for testing purpose only. publish_to: 'none' -version: 1.0.40+41 +version: 1.0.41+42 environment: sdk: '^3.0.0'