import 'dart:convert'; import 'dart:async'; import 'dart:io'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:manager_api_new/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 'package:tablet_app/constants.dart'; import 'puzzle_piece.dart'; const IMAGE_PATH = 'image_path'; class PuzzleView extends StatefulWidget { final PuzzleDTO section; PuzzleView({required this.section}); @override _PuzzleView createState() => _PuzzleView(); } class _PuzzleView extends State { PuzzleDTO puzzleDTO = PuzzleDTO(); int allInPlaceCount = 0; bool isFinished = false; GlobalKey _widgetKey = GlobalKey(); Size? realWidgetSize; List pieces = []; bool isSplittingImage = true; @override void initState() { //puzzleDTO = PuzzleDTO.fromJson(jsonDecode(widget.section!.data!))!; puzzleDTO = widget.section; 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(); print(puzzleDTO.messageDebut); TranslationAndResourceDTO? messageDebut = puzzleDTO.messageDebut != null && puzzleDTO.messageDebut!.length > 0 ? puzzleDTO.messageDebut!.where((message) => message.language!.toUpperCase() == tabletAppContext.language!.toUpperCase()).firstOrNull : null; if(messageDebut != null) { showMessage(messageDebut, appContext, context, size); } getRealWidgetSize(); if(puzzleDTO.puzzleImage != null && puzzleDTO.puzzleImage!.url != null) { //splitImage(Image.network(puzzleDTO.image!.resourceUrl!)); splitImage(CachedNetworkImage( imageUrl: puzzleDTO.puzzleImage!.url!, fit: BoxFit.fill, errorWidget: (context, url, error) => Icon(Icons.error), )); } else { setState(() { isSplittingImage = false; }); } }); super.initState(); } 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(CachedNetworkImage image) async { Completer completer = Completer(); /*image.image .resolve(const ImageConfiguration()) .addListener(ImageStreamListener((ImageInfo info, bool _) { completer.complete( Size(info.image.width.toDouble(), info.image.height.toDouble())); }));*/ CachedNetworkImage( imageUrl: 'https://example.com/image.jpg', placeholder: (context, url) => CircularProgressIndicator(), errorWidget: (context, url, error) => Icon(Icons.error), imageBuilder: (BuildContext context, ImageProvider imageProvider) { Completer completer = Completer(); imageProvider .resolve(const ImageConfiguration()) .addListener(ImageStreamListener((ImageInfo info, bool _) { completer.complete( Size(info.image.width.toDouble(), info.image.height.toDouble())); })); return CachedNetworkImage( imageUrl: 'https://example.com/image.jpg', placeholder: (context, url) => CircularProgressIndicator(), errorWidget: (context, url, error) => Icon(Icons.error), imageBuilder: (context, imageProvider) { return Image( image: imageProvider, loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent? loadingProgress) { if (loadingProgress == null) { return child; } else { return Center( child: CircularProgressIndicator( value: loadingProgress.expectedTotalBytes != null ? loadingProgress.cumulativeBytesLoaded / (loadingProgress.expectedTotalBytes ?? 1) : null, ), ); } }, ); }, ); }, ); 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(CachedNetworkImage image) async { //Size imageSize = await getImageSize(image); //imageSize = realWidgetSize!; Size 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!.length > 0 ? puzzleDTO.messageFin!.where((message) => message.language!.toUpperCase() == tabletAppContext.language!.toUpperCase()).firstOrNull : null; if(messageFin != null) { showMessage(messageFin, appContext, context, size); } } }); } @override Widget build(BuildContext context) { final appContext = Provider.of(context); TabletAppContext tabletAppContext = appContext.getContext(); return Container( //color: Colors.green, child: Padding( key: _widgetKey, padding: const EdgeInsets.all(0.0), child: isSplittingImage ? Center(child: LoadingCommon()) : puzzleDTO.puzzleImage == null || puzzleDTO.puzzleImage!.url == null || realWidgetSize == null ? Center(child: Text("Aucune image à afficher", style: TextStyle(fontSize: kNoneInfoOrIncorrect))) : Center( child: Padding( padding: const EdgeInsets.all(0.0), child: Container( width: tabletAppContext.puzzleSize != null && tabletAppContext.puzzleSize!.width > 0 ? tabletAppContext.puzzleSize!.width : realWidgetSize!.width * 0.8, height: tabletAppContext.puzzleSize != null && tabletAppContext.puzzleSize!.height > 0 ? tabletAppContext.puzzleSize!.height +1.5 : realWidgetSize!.height * 0.85, child: Stack( children: pieces, ), ), ), ), ), ); } }