@@ -8,6 +8,7 @@ import 'package:fluttertoast/fluttertoast.dart';
8
8
import 'package:iconsax/iconsax.dart' ;
9
9
import 'package:image_gallery_saver/image_gallery_saver.dart' ;
10
10
import 'package:lottie/lottie.dart' ;
11
+ import 'package:shared_preferences/shared_preferences.dart' ;
11
12
import 'package:text_to_image_gen/Pages/about_page.dart' ;
12
13
import 'package:text_to_image_gen/widgets/custom_drawer.dart' ;
13
14
import 'package:flutter/rendering.dart' ;
@@ -21,12 +22,157 @@ class HomePage extends StatefulWidget {
21
22
22
23
class _HomePageState extends State <HomePage > {
23
24
final TextEditingController _queryController = TextEditingController ();
24
-
25
+ AIStyle _selectedStyle = AIStyle .render3D;
25
26
final AI _ai = AI ();
26
27
Uint8List ? _generatedImage;
28
+ final _focusNode = FocusNode ();
29
+
30
+ @override
31
+ void initState () {
32
+ super .initState ();
33
+ _loadSelectedStyle ();
34
+ _focusNode.addListener (() {
35
+ if (! _focusNode.hasFocus) {
36
+ // Hide the keyboard when the user taps outside of the TextField
37
+ FocusScope .of (context).requestFocus (FocusNode ());
38
+ }
39
+ });
40
+ }
41
+
42
+ void _loadSelectedStyle () async {
43
+ SharedPreferences prefs = await SharedPreferences .getInstance ();
44
+ String ? selectedStyleString = prefs.getString ('selectedStyle' );
45
+ if (selectedStyleString != null ) {
46
+ setState (() {
47
+ _selectedStyle = AIStyle .values[int .parse (selectedStyleString)];
48
+ });
49
+ }
50
+ }
51
+
52
+ void _saveSelectedStyle () async {
53
+ SharedPreferences prefs = await SharedPreferences .getInstance ();
54
+ prefs.setString ('selectedStyle' , _selectedStyle.index.toString ());
55
+ }
56
+
57
+ Future <void > _showStyleSelectorDialog () async {
58
+ AIStyle ? newStyle = await showDialog <AIStyle >(
59
+ context: context,
60
+ builder: (BuildContext context) {
61
+ return SimpleDialog (
62
+ title: const Text ('Select a style' ),
63
+ children: < Widget > [
64
+ RadioListTile <AIStyle >(
65
+ title: const Text ('No style' ),
66
+ value: AIStyle .noStyle,
67
+ groupValue: _selectedStyle,
68
+ onChanged: (AIStyle ? value) {
69
+ Navigator .pop (context, value);
70
+ },
71
+ ),
72
+ RadioListTile <AIStyle >(
73
+ title: const Text ('3D render' ),
74
+ value: AIStyle .render3D,
75
+ groupValue: _selectedStyle,
76
+ onChanged: (AIStyle ? value) {
77
+ Navigator .pop (context, value);
78
+ },
79
+ ),
80
+ RadioListTile <AIStyle >(
81
+ title: const Text ('Anime' ),
82
+ value: AIStyle .anime,
83
+ groupValue: _selectedStyle,
84
+ onChanged: (AIStyle ? value) {
85
+ Navigator .pop (context, value);
86
+ },
87
+ ),
88
+ RadioListTile <AIStyle >(
89
+ title: const Text ('More Detailed' ),
90
+ value: AIStyle .moreDetails,
91
+ groupValue: _selectedStyle,
92
+ onChanged: (AIStyle ? value) {
93
+ Navigator .pop (context, value);
94
+ },
95
+ ),
96
+ RadioListTile <AIStyle >(
97
+ title: const Text ('CyberPunk' ),
98
+ value: AIStyle .cyberPunk,
99
+ groupValue: _selectedStyle,
100
+ onChanged: (AIStyle ? value) {
101
+ Navigator .pop (context, value);
102
+ },
103
+ ),
104
+ RadioListTile <AIStyle >(
105
+ title: const Text ('Cartoon' ),
106
+ value: AIStyle .cartoon,
107
+ groupValue: _selectedStyle,
108
+ onChanged: (AIStyle ? value) {
109
+ Navigator .pop (context, value);
110
+ },
111
+ ),
112
+ RadioListTile <AIStyle >(
113
+ title: const Text ('Picasso painter' ),
114
+ value: AIStyle .picassoPainter,
115
+ groupValue: _selectedStyle,
116
+ onChanged: (AIStyle ? value) {
117
+ Navigator .pop (context, value);
118
+ },
119
+ ),
120
+ RadioListTile <AIStyle >(
121
+ title: const Text ('Oil painting' ),
122
+ value: AIStyle .oilPainting,
123
+ groupValue: _selectedStyle,
124
+ onChanged: (AIStyle ? value) {
125
+ Navigator .pop (context, value);
126
+ },
127
+ ),
128
+ RadioListTile <AIStyle >(
129
+ title: const Text ('Digital painting' ),
130
+ value: AIStyle .digitalPainting,
131
+ groupValue: _selectedStyle,
132
+ onChanged: (AIStyle ? value) {
133
+ Navigator .pop (context, value);
134
+ },
135
+ ),
136
+ RadioListTile <AIStyle >(
137
+ title: const Text ('Portrait photo' ),
138
+ value: AIStyle .portraitPhoto,
139
+ groupValue: _selectedStyle,
140
+ onChanged: (AIStyle ? value) {
141
+ Navigator .pop (context, value);
142
+ },
143
+ ),
144
+ RadioListTile <AIStyle >(
145
+ title: const Text ('Picasso painter' ),
146
+ value: AIStyle .picassoPainter,
147
+ groupValue: _selectedStyle,
148
+ onChanged: (AIStyle ? value) {
149
+ Navigator .pop (context, value);
150
+ },
151
+ ),
152
+ RadioListTile <AIStyle >(
153
+ title: const Text ('Pencil drawing' ),
154
+ value: AIStyle .pencilDrawing,
155
+ groupValue: _selectedStyle,
156
+ onChanged: (AIStyle ? value) {
157
+ Navigator .pop (context, value);
158
+ },
159
+ ),
160
+ ],
161
+ );
162
+ },
163
+ );
164
+
165
+ if (newStyle != null ) {
166
+ setState (() {
167
+ _selectedStyle = newStyle;
168
+ });
169
+ _saveSelectedStyle ();
170
+ }
171
+ }
172
+
27
173
28
174
Future <Uint8List > _generate (String query) async {
29
- Uint8List image = await _ai.runAI (query, AIStyle .render3D );
175
+ Uint8List image = await _ai.runAI (query, _selectedStyle );
30
176
return image;
31
177
}
32
178
@@ -102,31 +248,37 @@ class _HomePageState extends State<HomePage> {
102
248
const SizedBox (
103
249
height: 10 ,
104
250
),
105
- Padding (
106
- padding: const EdgeInsets .all (6.0 ),
107
- child: TextField (
108
- style: TextStyle (
109
- fontSize: 16 ,
110
- color: Theme .of (context).colorScheme.secondary,
111
- ),
112
- keyboardType: TextInputType .multiline,
113
- minLines: 1 ,
114
- maxLines: 10 ,
115
- controller: _queryController,
116
- decoration: InputDecoration (
117
- hintText: 'Enter your imagination...' ,
118
- enabledBorder: OutlineInputBorder (
119
- borderRadius: BorderRadius .circular (8 ),
120
- borderSide: BorderSide (
121
- width: 1.5 ,
251
+ GestureDetector (
252
+ onTap: (){
253
+ FocusScope .of (context).requestFocus (FocusNode ());
254
+ },
255
+ child: Padding (
256
+ padding: const EdgeInsets .all (6.0 ),
257
+ child: TextField (
258
+ focusNode: _focusNode,
259
+ style: TextStyle (
260
+ fontSize: 16 ,
122
261
color: Theme .of (context).colorScheme.secondary,
262
+ ),
263
+ keyboardType: TextInputType .multiline,
264
+ minLines: 1 ,
265
+ maxLines: 10 ,
266
+ controller: _queryController,
267
+ decoration: InputDecoration (
268
+ hintText: 'Enter your imagination...' ,
269
+ enabledBorder: OutlineInputBorder (
270
+ borderRadius: BorderRadius .circular (8 ),
271
+ borderSide: BorderSide (
272
+ width: 1.5 ,
273
+ color: Theme .of (context).colorScheme.secondary,
274
+ ),
123
275
),
124
- ),
125
- focusedBorder : OutlineInputBorder (
126
- borderRadius : BorderRadius . circular ( 8 ),
127
- borderSide : BorderSide (
128
- width : 1.5 ,
129
- color : Theme . of (context).colorScheme.secondary ,
276
+ focusedBorder : OutlineInputBorder (
277
+ borderRadius : BorderRadius . circular ( 8 ),
278
+ borderSide : BorderSide (
279
+ width : 1.5 ,
280
+ color : Theme . of (context).colorScheme.secondary ,
281
+ ) ,
130
282
),
131
283
),
132
284
),
@@ -191,7 +343,7 @@ class _HomePageState extends State<HomePage> {
191
343
),
192
344
),
193
345
SizedBox (
194
- height: MediaQuery .of (context).size.width / 5 .5 ,
346
+ height: MediaQuery .of (context).size.width / 11 .5 ,
195
347
),
196
348
const Text (
197
349
'Click the image to save in Gallery.' ,
@@ -201,8 +353,18 @@ class _HomePageState extends State<HomePage> {
201
353
fontWeight: FontWeight .bold,
202
354
fontFamily: 'Nexa' ),
203
355
),
356
+ TextButton .icon (
357
+ icon: const Icon (Iconsax .colors_square),
358
+ label: Text ('Select Style' ,
359
+ style: TextStyle (
360
+ fontSize: 16 ,
361
+ color: Theme .of (context).colorScheme.secondary,
362
+ fontFamily: 'Nexa' ),
363
+ ),
364
+ onPressed: () => _showStyleSelectorDialog (),
365
+ ),
204
366
const SizedBox (
205
- height: 15 ,
367
+ height: 5 ,
206
368
),
207
369
Padding (
208
370
padding: const EdgeInsets .only (left: 80 , right: 80 ),
@@ -329,4 +491,4 @@ class _HomePageState extends State<HomePage> {
329
491
_isDownloadInitiated = false ;
330
492
_isDownloading = false ;
331
493
}
332
- }
494
+ }
0 commit comments