mirror of
https://bitbucket.org/FransoletThomas/tablet-app.git
synced 2025-12-06 08:31:19 +00:00
195 lines
6.3 KiB
Dart
195 lines
6.3 KiB
Dart
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<PuzzleView> {
|
|
PuzzleDTO puzzleDTO = PuzzleDTO();
|
|
|
|
int allInPlaceCount = 0;
|
|
bool isFinished = false;
|
|
|
|
GlobalKey _widgetKey = GlobalKey();
|
|
Size? realWidgetSize;
|
|
|
|
//File? _image;
|
|
String? _imagePath;
|
|
List<Widget> 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<AppContext>(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<void> 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<Size> getImageSize(Image image) async {
|
|
final Completer<Size> completer = Completer<Size>();
|
|
|
|
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<AppContext>(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<AppContext>(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<AppContext>(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,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
} |