Commit 3c06869a authored by m-spi's avatar m-spi
parents 24644fd1 85a332db
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"camera_avfoundation","path":"/home/spinelli/.pub-cache/hosted/pub.dev/camera_avfoundation-0.9.14/","native_build":true,"dependencies":[]}],"android":[{"name":"camera_android","path":"/home/spinelli/.pub-cache/hosted/pub.dev/camera_android-0.9.8+3/","native_build":true,"dependencies":["flutter_plugin_android_lifecycle"]},{"name":"flutter_plugin_android_lifecycle","path":"/home/spinelli/.pub-cache/hosted/pub.dev/flutter_plugin_android_lifecycle-2.0.17/","native_build":true,"dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[{"name":"camera_web","path":"/home/spinelli/.pub-cache/hosted/pub.dev/camera_web-0.2.1+6/","dependencies":[]}]},"dependencyGraph":[{"name":"camera","dependencies":["camera_android","camera_avfoundation","camera_web","flutter_plugin_android_lifecycle"]},{"name":"camera_android","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"camera_avfoundation","dependencies":[]},{"name":"camera_web","dependencies":[]},{"name":"flutter_plugin_android_lifecycle","dependencies":[]}],"date_created":"2024-02-26 09:34:33.635082","version":"3.20.0-13.0.pre.28"}
\ No newline at end of file
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"camera_avfoundation","path":"/home/timothe/.pub-cache/hosted/pub.dev/camera_avfoundation-0.9.14/","native_build":true,"dependencies":[]}],"android":[{"name":"camera_android","path":"/home/timothe/.pub-cache/hosted/pub.dev/camera_android-0.9.8+3/","native_build":true,"dependencies":["flutter_plugin_android_lifecycle"]},{"name":"flutter_plugin_android_lifecycle","path":"/home/timothe/.pub-cache/hosted/pub.dev/flutter_plugin_android_lifecycle-2.0.17/","native_build":true,"dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[{"name":"camera_web","path":"/home/timothe/.pub-cache/hosted/pub.dev/camera_web-0.2.1+6/","dependencies":[]}]},"dependencyGraph":[{"name":"camera","dependencies":["camera_android","camera_avfoundation","camera_web","flutter_plugin_android_lifecycle"]},{"name":"camera_android","dependencies":["flutter_plugin_android_lifecycle"]},{"name":"camera_avfoundation","dependencies":[]},{"name":"camera_web","dependencies":[]},{"name":"flutter_plugin_android_lifecycle","dependencies":[]}],"date_created":"2024-02-20 05:55:40.136688","version":"3.20.0-2.0.pre.7"}
......@@ -10,6 +10,7 @@
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:requestLegacyExternalStorage="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
......
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'package:image_picker/image_picker.dart';
List<CameraDescription> cameras = [];
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
cameras = await availableCameras();
void main() {
runApp(Exo10());
}
class Exo10 extends StatefulWidget {
const Exo10({Key? key}) : super(key: key);
class Exo10 extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_Exo10State createState() => _Exo10State();
_MyHomePageState createState() => _MyHomePageState();
}
class _Exo10State extends State<Exo10> {
late CameraController _controller;
late Future<void> _initializeControllerFuture;
class _MyHomePageState extends State<MyHomePage> {
File? _image;
final picker = ImagePicker();
List<Widget> tiles = <Widget>[];
int colNb = 3;
int emptyTileIndex = 0;
@override
void initState() {
super.initState();
_initializeControllerFuture = _initializeCamera();
tiles = buildImage(Image.asset('assets/placeholder_image.jpg'));
}
List<Widget> buildImage(Image image) {
int imageCount = 0;
List<Widget> res = <Widget>[];
emptyTileIndex = colNb * colNb - 1;
for (int i = 0; i < colNb; i++) {
for (int j = 0; j < colNb; j++) {
int indexcopy = imageCount;
Tile tile = Tile(
image: image,
alignment: Alignment(
-1 + 2 * j.toDouble() / (colNb.toDouble() - 1),
-1 + 2 * i.toDouble() / (colNb.toDouble() - 1),
),
);
Key k = UniqueKey();
res.add(
Flexible(
key: k,
child: Container(
margin: EdgeInsets.all(2),
child: InkWell(
child: tile.croppedImageTile(1 / colNb),
onTap: () {
setState(() {
swapTiles(k);
});
},
),
),
),
);
imageCount++;
}
}
res.shuffle();
res[emptyTileIndex] = Flexible(child: Container(margin: EdgeInsets.all(2)));
return res;
}
Future<void> _initializeCamera() async {
final CameraDescription camera = cameras.first;
_controller = CameraController(camera, ResolutionPreset.medium);
return _controller.initialize();
void swapTiles(Key k) {
Widget t = tiles.singleWhere((element) => element.key == k);
int i = tiles.indexOf(t);
// If tile is neighbor of empty tile => move
if (i + 1 == emptyTileIndex && i % colNb != colNb - 1 ||
i - 1 == emptyTileIndex && i % colNb != 0 ||
i - colNb == emptyTileIndex ||
i + colNb == emptyTileIndex) {
tiles[emptyTileIndex] = t;
tiles[i] = Flexible(child: Container(margin: EdgeInsets.all(2)));
emptyTileIndex = i;
}
}
@override
void dispose() {
_controller.dispose();
super.dispose();
Future getImage() async {
final pickedFile = await picker.pickImage(source: ImageSource.gallery);
setState(() {
if (pickedFile != null) {
_image = File(pickedFile.path);
tiles = buildImage(Image.file(_image!));
}
});
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Take a Picture and Display'),
),
body: FutureBuilder<void>(
future: _initializeControllerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (_controller != null && _controller.value.isInitialized) {
return CameraPreview(_controller);
} else {
return Center(child: Text('Camera initialization failed'));
}
} else {
return Center(child: CircularProgressIndicator());
}
},
),
floatingActionButton: FloatingActionButton(
onPressed: () async {
try {
await _initializeControllerFuture;
final XFile picture = await _controller.takePicture();
// Display the picture using a new page
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DisplayPictureScreen(imagePath: picture.path),
return Scaffold(
appBar: AppBar(
title: Text('Image Picker Example'),
),
body: Column(
children: [
TextButton(
child: Text('Select Image'),
onPressed: getImage,
),
Slider(
value: colNb.toDouble(),
min: 2,
max: 6,
divisions: 5,
label: colNb.toString(),
onChanged: (double value) {
setState(() {
colNb = value.toInt();
tiles = buildImage(_image == null ? Image.asset('assets/placeholder_image.jpg') : Image.file(_image!));
});
},
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: colNb,
),
);
} catch (e) {
print("Error taking picture: $e");
}
},
child: Icon(Icons.camera),
),
itemCount: colNb * colNb,
itemBuilder: (BuildContext context, int index) {
return tiles.elementAt(index);
},
),
),
),
],
),
);
}
}
class DisplayPictureScreen extends StatelessWidget {
final String imagePath;
class Tile {
Image image;
Alignment alignment;
const DisplayPictureScreen({Key? key, required this.imagePath}) : super(key: key);
Tile({required this.image, required this.alignment});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Display the Picture')),
body: Center(
child: Image.file(File(imagePath)),
Widget croppedImageTile(double widthFactor) {
return FittedBox(
fit: BoxFit.fill,
child: ClipRect(
child: Container(
child: Align(
alignment: alignment,
widthFactor: widthFactor,
heightFactor: widthFactor,
child: image,
),
),
),
);
}
......
import 'package:flutter/material.dart';
import 'exo7_taquin.dart';
class Exo7 extends StatelessWidget {
const Exo7({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Jeu du Taquin !'),
centerTitle: true,
),
body: Column(children: [
const Text.rich(
TextSpan(
text: 'Sélectionner la difficulté', // default text style
style: TextStyle()
)
),
Center(
child: TextButton(
style: TextButton.styleFrom(
textStyle: const TextStyle(fontSize: 20),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SizeChoose(difficulty: 10)),
);
},
child: const Text('Easy'),
),
),
Center(
child: TextButton(
style: TextButton.styleFrom(
textStyle: const TextStyle(fontSize: 20),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SizeChoose(difficulty: 20)),
);
},
child: const Text('Medium'),
),
),
Center(
child: TextButton(
style: TextButton.styleFrom(
textStyle: const TextStyle(fontSize: 20),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SizeChoose(difficulty: 30)),
);
},
child: const Text('Hard'),
),
),
])
);
}
}
class SizeChoose extends StatelessWidget {
final int difficulty;
const SizeChoose({required this.difficulty, super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Jeu du Taquin !'),
centerTitle: true,
),
body: Column(children: [
const Text.rich(
TextSpan(
text: 'Sélectionner la taille', // default text style
style: TextStyle()
)
),
Center(
child: TextButton(
style: TextButton.styleFrom(
textStyle: const TextStyle(fontSize: 20),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Taquin(difficulty: difficulty, colNb: 2)),
);
},
child: const Text('2 par 2'),
),
),
Center(
child: TextButton(
style: TextButton.styleFrom(
textStyle: const TextStyle(fontSize: 20),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Taquin(difficulty: difficulty, colNb: 3)),
);
},
child: const Text('3 par 3'),
),
),
Center(
child: TextButton(
style: TextButton.styleFrom(
textStyle: const TextStyle(fontSize: 20),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Taquin(difficulty: difficulty, colNb: 4)),
);
},
child: const Text('4 par 4'),
),
),
Center(
child: TextButton(
style: TextButton.styleFrom(
textStyle: const TextStyle(fontSize: 20),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Taquin(difficulty: difficulty, colNb: 5)),
);
},
child: const Text('5 par 5'),
),
)
])
);
}
}
\ No newline at end of file
import 'dart:async';
import 'dart:math' as math;
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
class Taquin extends StatefulWidget {
final int difficulty;
final int colNb;
const Taquin({required this.difficulty, required this.colNb, super.key});
@override
State<Taquin> createState() => _Taquin();
}
class _Taquin extends State<Taquin> {
File? _image;
final picker = ImagePicker();
List<Widget> tiles = <Widget>[];
List<Key> initialOrder = <Key>[];
double? size = 300;
int emptyTileIndex = 0;
late int score;
late String imageUrl;
late Image image;
late int colNb;
late int difficulty;
Duration stopwatch = const Duration();
Timer? stopwatchTimer;
@override
void initState(){
super.initState();
image = Image.network('https://picsum.photos/512');
colNb = widget.colNb;
difficulty = widget.difficulty;
score = difficulty * colNb ;
tiles = buildImage();
moveTiles();
}
List<Widget> buildImage(){
var res = <Widget>[];
initialOrder = <Key>[];
emptyTileIndex = 0;
for(int i = 0; i < colNb; i++){
for(int j = 0; j < colNb; j++){
Tile tile = Tile(image: image, alignment:
Alignment(-1 + 2 * j.toDouble() / (colNb.toDouble() - 1),
-1 + 2 * i.toDouble() / (colNb.toDouble() - 1))
);
Key k = UniqueKey();
initialOrder.add(k);
res.add(
Flexible(key: k, child: Container(
margin: const EdgeInsets.all(2),
child: Material(
child: InkWell(
child: tile.croppedImageTile(1 / colNb),
onTap: () {
setState(() {
swapTiles(k);
isWon();
if(isValidTile(tiles.indexOf(tiles.singleWhere((element) => element.key == k)))){
score--;
}
});
}
),
)
))
);
}
}
res[emptyTileIndex] = Flexible(child: Container(margin: const EdgeInsets.all(2)));
return res;
}
void moveTiles(){
for(int i=0; i < colNb * difficulty; i++) {
var validTiles = getValidTiles();
swapTiles(
validTiles[math.Random().nextInt(validTiles.length)].key!
);
}
}
void _showWinDialog(BuildContext context, int winscore){
showDialog(
context: context,
builder: (BuildContext context){
return AlertDialog(
title: const Text('Congratulations !'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text('You won ! With a score of $winscore'),
SizedBox(height: 20), // Add some space between text and image
image,
],
),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text('Close'),
),TextButton(
onPressed: () { setState(() {
stopwatch = const Duration();
stopwatchTimer?.cancel();
stopwatchTimer = null;
score = difficulty * colNb;
image.image.evict();
image = new Image.network('https://picsum.photos/512');
tiles = buildImage();
moveTiles();
});
Navigator.pop(context);
},
child: const Text('Restart'),
)
],
);
},
);
}
void _showHintDialog(BuildContext context){
showDialog(
context: context,
builder: (BuildContext context){
return AlertDialog(
title: const Text('Good luck !'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text('This is the image you are trying to recompose :'),
SizedBox(height: 20), // Add some space between text and image
image,
],
),
actions: <Widget>[
TextButton(
onPressed: () {
Navigator.pop(context);
},
child: const Text('Close'),
),
],
);
},
);
}
bool isWon(){
for(int i = 1; i < tiles.length; i++){
if (tiles[i].key != initialOrder[i]){
return false;
}
}
//print("It's a win");
stopwatch = const Duration();
stopwatchTimer?.cancel();
stopwatchTimer = null;
final winscore = score - 1;
_showWinDialog(context, winscore);
return true;
}
bool isValidTile(int index) {
return (index+1 == emptyTileIndex && index%colNb != colNb-1 ||
index-1 == emptyTileIndex && index%colNb != 0 ||
index-colNb == emptyTileIndex ||
index+colNb == emptyTileIndex);
}
List<Widget> getValidTiles() {
return tiles.where(
(element) => isValidTile(tiles.indexOf(element))
).toList();
}
void swapTiles(Key k){
Widget t = tiles.singleWhere((element) => element.key == k);
int i = tiles.indexOf(t);
// If tile is neighbor of empty tile => move
if(isValidTile(i)){
tiles[emptyTileIndex] = t;
tiles[i] = Flexible(child: Container(margin: const EdgeInsets.all(2)));
emptyTileIndex = i;
}
}
Future getImageFromCamera() async {
final pickedFile = await picker.pickImage(source: ImageSource.camera);
if (pickedFile != null) {
_image = File(pickedFile.path);
image = Image.file(_image!);
tiles = buildImage();
moveTiles();
}
}
Future getImage() async {
final pickedFile = await picker.pickImage(source: ImageSource.gallery);
if (pickedFile != null) {
_image = File(pickedFile.path);
image = Image.file(_image!);
tiles = buildImage();
moveTiles();
}
}
@override
Widget build(BuildContext context) {
Widget timeWidget;
timeWidget = stopwatchTimer != null ? Center(
child: Text.rich(
TextSpan(
text: stopwatch.toString().substring(0, 9), // default text style
style: const TextStyle()
)
)
) : const SizedBox.shrink();
return Scaffold(
appBar: AppBar(
title: const Text('Jeu du Taquin !'),
centerTitle: true,
),
body: Column(children: [
Text(
'Score: $score',
style: const TextStyle(fontSize: 20),
),
const SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
onPressed: () {
setState(() {
stopwatch = const Duration();
stopwatchTimer?.cancel();
stopwatchTimer = null;
score = difficulty * colNb;
image.image.evict();
image = new Image.network('https://picsum.photos/512');
tiles = buildImage();
moveTiles();
});
},
child: const Text('Restart'),
),
ElevatedButton(
onPressed: () {
setState(() {
_showHintDialog(context);
});
},
child: const Text('HINT'),
),
ElevatedButton(
onPressed: () {
const d = Duration(milliseconds: 100);
setState(() {
stopwatchTimer = Timer.periodic(d, (timer) {
setState(() {
stopwatch = stopwatch + d;
});
});
});
},
child: const Text('Stopwatch'),
),
// TODO : PLUS DE BOUTO
],
),
const SizedBox(height: 5),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
ElevatedButton(
onPressed: () {
getImage().then((_) {
setState(() {});
});
score = difficulty * colNb;
},
child: const Text('Image From Galeria'),
),
ElevatedButton(
onPressed: () {
getImageFromCamera().then((_) {
setState(() {});
});
score = difficulty * colNb;
},
child: const Text('Image from camera'),
),
],
),
const SizedBox(height: 5),
Container(
margin: const EdgeInsets.all(10.0),
child: SizedBox(
height: MediaQuery.of(context).size.height * 0.5,
width: MediaQuery.of(context).size.height * 0.5,
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: colNb,
),
itemCount: colNb * colNb,
itemBuilder: (BuildContext context, int index) {
return tiles.elementAt(index);
}
)
)
),
timeWidget
]),
);
}
}
class Tile {
Image image;
Alignment alignment;
Tile({required this.image, required this.alignment});
Widget croppedImageTile(double widthFactor) {
return FittedBox(
fit: BoxFit.fill,
child: ClipRect(
child: Container(
child: Align(
alignment: alignment,
widthFactor: widthFactor,
heightFactor: widthFactor,
child: image,
),
),
),
);
}
}
\ No newline at end of file
......@@ -4,6 +4,7 @@ import 'package:tp2/exo2.dart';
import 'package:tp2/exo4.dart';
import 'package:tp2/exo5.dart';
import 'package:tp2/exo6.dart';
import 'package:tp2/exo7.dart';
import 'package:tp2/exo10.dart';
......@@ -28,7 +29,7 @@ void main() {
'A description of what needs to be done for Todo ',
Exo1()
),
Exos(
const Exos(
'Exercice 2',
'A description of what needs to be done for Todo ',
Exo2()
......@@ -38,19 +39,23 @@ void main() {
'desc',
Exo4()
),
Exos(
const Exos(
'Exercice 5',
'aaaaa',
Exo5()
),
Exos(
const Exos(
'Exercice 6',
'desc',
Exo6()
),Exos(
'Exercice 6',
'Exercice 10',
'desc',
Exo10()
), Exos(
'Exercice 7',
'desc',
Exo7()
)
// Next exo
],
......
......@@ -6,6 +6,10 @@
#include "generated_plugin_registrant.h"
#include <file_selector_linux/file_selector_plugin.h>
void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
file_selector_plugin_register_with_registrar(file_selector_linux_registrar);
}
......@@ -3,6 +3,7 @@
#
list(APPEND FLUTTER_PLUGIN_LIST
file_selector_linux
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST
......
......@@ -5,6 +5,8 @@
import FlutterMacOS
import Foundation
import file_selector_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
}
......@@ -34,6 +34,8 @@ dependencies:
sdk: flutter
camera: ^0.9.4+5 # or the latest version available
image_picker: ^0.8.3
......
......@@ -6,6 +6,9 @@
#include "generated_plugin_registrant.h"
#include <file_selector_windows/file_selector_windows.h>
void RegisterPlugins(flutter::PluginRegistry* registry) {
FileSelectorWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FileSelectorWindows"));
}
......@@ -3,6 +3,7 @@
#
list(APPEND FLUTTER_PLUGIN_LIST
file_selector_windows
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment