1#ifndef FILE_CHOOSER_CPP_INCLUDED
2#define FILE_CHOOSER_CPP_INCLUDED
3
4#include <allegro5/allegro.h>
5#include <allegro5/allegro_native_dialog.h>
6#include <allegro5/allegro_font.h> //needed by input_output.hpp
7
8
9#include "graphics_functions.hpp"
10#include "miscellaneous.hpp"
11#include <iostream>
12#include <fstream>
13#include <vector>
14#include "font_manager.hpp"
15#include "GUI_bitmaps.hpp"
16#include "data_class.hpp"
17
18#include <sstream>
19
20#include "input_output.hpp"
21
22#include <allegro5/allegro_primitives.h>
23
24#include "up_and_down.hpp"
25#include "files_list_box.hpp"
26#include "modes_and_menu_ids.hpp"
27
28
29#include "file_loader.hpp"
30
31
32
33/* To communicate from a separate thread, we need a user event. */
34#define ASYNC_DIALOG_EVENT1 ALLEGRO_GET_EVENT_TYPE('e', 'N', 'F', '1')
35
36
37
38
39typedef struct
40{
41 ALLEGRO_DISPLAY *display
;
42 ALLEGRO_FILECHOOSER *file_dialog
;
43 ALLEGRO_EVENT_SOURCE event_source
;
44 ALLEGRO_THREAD *thread
;
45} AsyncDialog
;
46
47
48/* async_file_dialog_thread_func() : Our thread to show the native file dialog. */
49static void *async_file_dialog_thread_func
(ALLEGRO_THREAD *thread,
void *arg
)
50{
51 AsyncDialog
*data
= (AsyncDialog
*) arg
;
52 ALLEGRO_EVENT event
;
53 (void)thread
;
54
55 al_show_native_file_dialog(data->display, data->file_dialog
);
56
57 event.user.type
= ASYNC_DIALOG_EVENT1
;
58 al_emit_user_event(&data->event_source,
&event, NULL
);
59
60 return NULL
;
61}
62
63
64/* spawn_async_file_dialog() : opens up a dialog for choosing a file. */
65static AsyncDialog
*spawn_async_file_dialog
(ALLEGRO_DISPLAY *display,
const char *initial_path
)
66{
67 AsyncDialog
*data
= (AsyncDialog
*) malloc(sizeof *data
);
68
69 data->file_dialog
= al_create_native_file_dialog(initial_path,
"Choose Black and White Image.", NULL, ALLEGRO_FILECHOOSER_PICTURES
);
70 al_init_user_event_source(&data->event_source
);
71 data->display
= display
;
72 data->thread
= al_create_thread(async_file_dialog_thread_func, data
);
73
74 al_start_thread(data->thread
);
75
76 return data
;
77}
78
79
80
81
82
83
84/* stop_async_dialog() : ends the dialog for choosing a file. */
85static void stop_async_dialog
(AsyncDialog
*data
)
86{
87 if (data
) {
88 al_destroy_thread(data->thread
);
89 al_destroy_user_event_source(&data->event_source
);
90 if (data->file_dialog
)
91 al_destroy_native_file_dialog(data->file_dialog
);
92 free(data
);
93 }
94}
95
96
97
98
99/* load_image() : gui mode for loading an image from harddrive. */
100int load_image
(int mode_id, InputOutput
*IO, DataClass
& data
)
101{
102 ALLEGRO_EVENT event
;
103 AsyncDialog
*cur_dialog
= NULL
;
104 const char *last_path
= NULL
;
105
106 //al_destroy_display(IO->display);
107 //cout << "In load image." << endl;
108 //system("PAUSE");
109 //return -1;
110
111
112 if(IO->queue
== NULL
)
113 {
114 al_destroy_display(IO->display
);
115 cout
<< "In load image. IO->queue is NULL." << endl
;
116 system("PAUSE");
117 return -1;
118 }
119 else
120 {
121 cout
<< "In load image. IO->queue is not NULL." << endl
;
122 }
123
124 al_flush_event_queue(IO->queue
);
125
126 //al_clear_to_color(al_map_rgb(60, 60, 200));
127 if(data.static_menu_background
== NULL
)
128 {
129 al_destroy_display(IO->display
);
130 cout
<< "In load image. data.static_menu_background is NULL." << endl
;
131 system("PAUSE");
132 return -1;
133 }
134 al_draw_bitmap(data.static_menu_background,
0,
0,
0);
135
136
137 al_flip_display();
138
139
140 cur_dialog
= spawn_async_file_dialog
(IO->display, last_path
);
141 al_register_event_source(IO->queue,
&cur_dialog->event_source
);
142
143 //al_destroy_display(IO->display);
144 cout
<< "In load image. About to go into while loop." << endl
;
145 //system("PAUSE");
146 //return -1;
147
148
149
150
151 while(1)
152 {
153 cout
<< "Waiting for event." << endl
;
154
155 if(IO->queue
== NULL
)
156 {
157 al_destroy_display(IO->display
);
158 cout
<< "IO->queue is NULL." << endl
;
159 system("PAUSE");
160 return -1;
161 }
162 al_wait_for_event(IO->queue,
&event
);
163
164 cout
<< "Got event." << endl
;
165 if(event.type
== 30)
166 {
167 cout
<< "event type was timer event.\n";
168 }
169 else if(event.type
>= 10 && event.type
<= 25)
170 {
171 cout
<< "event type was mouse event.\n";
172
173 }
174 else if(event.type
== 12)
175 {
176 cout
<< "event type is key up." << endl
;
177 }
178 else
179 {
180 cout
<< "event type is " << event.type
<< endl
;
181 cout
<< "ASYNC_DIALOG_EVENT1 is " << ASYNC_DIALOG_EVENT1
<< endl
;
182
183 }
184
185 if(event.type
== ASYNC_DIALOG_EVENT1
) /* dialogue was closed */
186 {
187 al_unregister_event_source(IO->queue,
&cur_dialog->event_source
);
188
189 /* If a file was chosen, put the path to it in the FilesListBox class of the DataClass data. */
190
191 if(al_get_native_file_dialog_count(cur_dialog->file_dialog
) == 1)
192 {
193 int index = ((FilesListBox
*) data.vp
)->index_for_next_filename
;
194
195
196
197 ((FilesListBox
*) data.vp
)->file_paths
[index] = al_create_path(al_get_native_file_dialog_path(cur_dialog->file_dialog,
0));
198
199 ((FilesListBox
*) data.vp
)->file_names
[index] = al_get_path_filename(((FilesListBox
*) data.vp
)->file_paths
[index]);
200
201 /* Load the file. */
202 if((((FilesListBox
*) data.vp
)->bitmaps
[index] = al_load_bitmap( al_path_cstr(((FilesListBox
*) data.vp
)->file_paths
[index], ALLEGRO_NATIVE_PATH_SEP
) )) == NULL
)
203 {
204 /* Set error_data.mode_number to LOAD_IMAGE_MODE so that after error
205 has been reported, user can load another file. */
206 //data.error_data.mode_number = LOAD_IMAGE_MODE;
207 //data.error_data.mode_number = FILE_LOADING_PROBLEM;
208 //return ERROR_LOG_MODE;
209 al_destroy_display(IO->display
);
210 printf("load_image_mode() : Couldn't load file %s.\n",
((FilesListBox
*) data.vp
)->file_names
[index]);
211 printf("filename was : %s",
((FilesListBox
*) data.vp
)->file_names
[index]);
212 //printf("current working directory = %s", );
213 system("PAUSE");
214 exit(1);
215 }
216
217
218
219 if(((FilesListBox
*) data.vp
)->index_for_next_filename
< ((FilesListBox
*) data.vp
)->max_files
() - 1)
220 {
221 ++((FilesListBox
*) data.vp
)->index_for_next_filename
;
222 ++((FilesListBox
*) data.vp
)->num_files_in_files_list_box
;
223 break;
224 }
225
226 }
227 else
228 {
229 cout
<< "0 or more than 1 file selected.\n";
230
231 if(data.file_loader_calling_mode
== MAIN_MENU_MODE
)
232 {
233 if(cur_dialog
!= NULL
)
234 {
235 stop_async_dialog
(cur_dialog
);
236 }
237 else
238 {
239 al_destroy_display(IO->display
);
240 cout
<< "load_image : 0 or more than 1 file selected. cur_dialog is NULL.\n";
241 system("PAUSE");
242 exit(1);
243 }
244 return MAIN_MENU_MODE
;
245 }
246 }
247
248 stop_async_dialog
(cur_dialog
);
249 break;
250 }
251
252 }
253
254 if(data.file_loader_calling_mode
== MAIN_MENU_MODE
)
255 {
256 return AFTER_FILE_LOAD_MENU_MODE
;
257 }
258 else if(data.file_loader_calling_mode
== LOAD_FILES_PROMPT_MODE
)
259 {
260 if(((FilesListBox
*) data.vp
)->num_files_in_files_list_box
< data.num_files_needed
)
261 {
262 return LOAD_FILES_PROMPT_MODE
;
263 }
264 else
265 {
266 data.select_files
= true;
267 return data.mode_after_selector
;
268 }
269 //data.select_files = true;
270 //data.user_info_strings = Menu.GetButtonUserInfoStrings();
271
272 }
273 else
274 {
275
276 cout
<< "Returning -1 from load_image." << endl
;
277 return -1;
278 }
279}
280
281
282
283
284
285#endif // FILE_CHOOSER_CPP_INCLUDED