import 'dart:convert'; import 'dart:async'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:manager_api/api.dart'; import 'package:provider/provider.dart'; import 'package:tablet_app/Components/loading_common.dart'; import 'package:tablet_app/Models/tabletContext.dart'; import 'package:tablet_app/Screens/Puzzle/message_dialog.dart'; import 'package:tablet_app/app_context.dart'; import 'puzzle_piece.dart'; import 'score_widget.dart'; const IMAGE_PATH = 'image_path'; class PuzzleView extends StatefulWidget { final SectionDTO? section; PuzzleView({this.section}); @override _PuzzleView createState() => _PuzzleView(); } class _PuzzleView extends State { PuzzleDTO puzzleDTO = PuzzleDTO(); int allInPlaceCount = 0; bool isFinished = false; GlobalKey _widgetKey = GlobalKey(); Size? realWidgetSize; //File? _image; String? _imagePath; List pieces = []; bool isSplittingImage = true; @override void initState() { puzzleDTO = PuzzleDTO.fromJson(jsonDecode(widget.section!.data!))!; puzzleDTO.rows = puzzleDTO.rows != null ? puzzleDTO.rows : 3; puzzleDTO.cols = puzzleDTO.cols != null ? puzzleDTO.cols : 3; WidgetsBinding.instance.addPostFrameCallback((_) { Size size = MediaQuery.of(context).size; final appContext = Provider.of(context, listen: false); TabletAppContext tabletAppContext = appContext.getContext(); TranslationAndResourceDTO? messageDebut = puzzleDTO.messageDebut != null ? puzzleDTO.messageDebut!.firstWhere((message) => message.language!.toUpperCase() == tabletAppContext.language!.toUpperCase()) : null; if(messageDebut != null) { showMessage(messageDebut, appContext, context, size); } getRealWidgetSize(); }); super.initState(); if(puzzleDTO.image != null && puzzleDTO.image!.resourceUrl != null) { splitImage(Image.network(puzzleDTO.image!.resourceUrl!)); } } Future getRealWidgetSize() async { RenderBox renderBox = _widgetKey.currentContext?.findRenderObject() as RenderBox; Size size = renderBox.size; setState(() { realWidgetSize = size; }); print("Taille réelle du widget : $size"); } // we need to find out the image size, to be used in the PuzzlePiece widget Future getImageSize(Image image) async { final Completer completer = Completer(); image.image .resolve(const ImageConfiguration()) .addListener(ImageStreamListener((ImageInfo info, bool _) { completer.complete( Size(info.image.width.toDouble(), info.image.height.toDouble())); })); final Size imageSize = await completer.future; return imageSize; } // here we will split the image into small pieces // using the rows and columns defined above; each piece will be added to a stack void splitImage(Image image) async { Size imageSize = await getImageSize(image); //imageSize = realWidgetSize!; imageSize = Size(realWidgetSize!.width * 1.25, realWidgetSize!.height * 1.25); for (int x = 0; x < puzzleDTO.rows!; x++) { for (int y = 0; y < puzzleDTO.cols!; y++) { setState(() { pieces.add( PuzzlePiece( key: GlobalKey(), image: image, imageSize: imageSize, row: x, col: y, maxRow: puzzleDTO.rows!, maxCol: puzzleDTO.cols!, bringToTop: this.bringToTop, sendToBack: this.sendToBack, ), ); }); } } setState(() { isSplittingImage = false; }); } // when the pan of a piece starts, we need to bring it to the front of the stack void bringToTop(Widget widget) { setState(() { pieces.remove(widget); pieces.add(widget); }); } // when a piece reaches its final position, // it will be sent to the back of the stack to not get in the way of other, still movable, pieces void sendToBack(Widget widget) { setState(() { allInPlaceCount++; isFinished = allInPlaceCount == puzzleDTO.rows! * puzzleDTO.cols!; pieces.remove(widget); pieces.insert(0, widget); if(isFinished) { Size size = MediaQuery.of(context).size; final appContext = Provider.of(context, listen: false); TabletAppContext tabletAppContext = appContext.getContext(); TranslationAndResourceDTO? messageFin = puzzleDTO.messageFin != null ? puzzleDTO.messageFin!.firstWhere((message) => message.language!.toUpperCase() == tabletAppContext.language!.toUpperCase()) : null; if(messageFin != null) { showMessage(messageFin, appContext, context, size); } } }); } @override Widget build(BuildContext context) { final appContext = Provider.of(context); TabletAppContext tabletAppContext = appContext.getContext(); return Padding( key: _widgetKey, padding: const EdgeInsets.all(10.0), child: isSplittingImage ? Center(child: LoadingCommon()) : puzzleDTO.image!.resourceUrl == null || realWidgetSize == null ? Container( width: 50, height: 50, color: Colors.cyan, child: InkWell(onTap: () { Size size = MediaQuery.of(context).size; final appContext = Provider.of(context, listen: false); TabletAppContext tabletAppContext = appContext.getContext(); TranslationAndResourceDTO? messageFin = puzzleDTO.messageFin != null ? puzzleDTO.messageFin!.firstWhere((message) => message.language!.toUpperCase() == tabletAppContext.language!.toUpperCase()) : null; if(messageFin != null) { // Alert dialog showMessage(messageFin, appContext, context, size); } },),)//Center(child: Text("Invalid image")) : Center( child: Padding( padding: const EdgeInsets.all(8.0), child: Container( width: tabletAppContext.puzzleSize != null ? tabletAppContext.puzzleSize!.width : realWidgetSize!.width * 0.8, height: tabletAppContext.puzzleSize != null ? tabletAppContext.puzzleSize!.height +1.5 : realWidgetSize!.height * 0.8, child: Stack( children: pieces, ), ), ), ), ); } }