1 /*
2 * uiimagefilereq.c - Functions to select a file inside a D64/T64 Image
3 *
4 * Written by
5 * groepaz <groepaz@gmx.net>
6 *
7 * This file is part of VICE, the Versatile Commodore Emulator.
8 * See README for copyright notice.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
23 * 02111-1307 USA.
24 *
25 */
26
27 #include "vice.h"
28 #include "types.h"
29
30 #include "vice_sdl.h"
31 #include <string.h>
32
33 #include "archdep.h"
34 #include "diskcontents.h"
35 #include "tapecontents.h"
36 #include "imagecontents.h"
37 #include "ioutil.h"
38 #include "lib.h"
39 #include "ui.h"
40 #include "uimenu.h"
41 #include "uifilereq.h"
42 #include "util.h"
43 #include "menu_common.h"
44
45 #define SDL_FILEREQ_META_NUM 0
46
47 #define IMAGE_FIRST_Y 1
48
49 static menu_draw_t *menu_draw;
50
sdl_ui_image_file_selector_redraw(image_contents_t * contents,const char * title,int offset,int num_items,int more,ui_menu_filereq_mode_t mode,int cur_offset)51 static void sdl_ui_image_file_selector_redraw(image_contents_t *contents, const char *title, int offset, int num_items, int more, ui_menu_filereq_mode_t mode, int cur_offset)
52 {
53 int i, j;
54 char* title_string;
55 char* name;
56 uint8_t oldbg;
57 image_contents_file_list_t *entry;
58
59 title_string = image_contents_to_string(contents, 0);
60
61 sdl_ui_clear();
62 sdl_ui_display_title(title_string);
63 lib_free(title_string);
64
65 entry = contents->file_list;
66 for (i = 0; i < offset; ++i) {
67 entry = entry->next;
68 }
69 for (i = 0; i < num_items; ++i) {
70 if (i == cur_offset) {
71 oldbg = sdl_ui_set_cursor_colors();
72 }
73
74 j = MENU_FIRST_X;
75 name = image_contents_file_to_string(entry, IMAGE_CONTENTS_STRING_PETSCII);
76 j += sdl_ui_print(name, j, i + IMAGE_FIRST_Y + SDL_FILEREQ_META_NUM);
77
78 if (i == cur_offset) {
79 sdl_ui_print_eol(j, i + IMAGE_FIRST_Y + SDL_FILEREQ_META_NUM);
80 sdl_ui_reset_cursor_colors(oldbg);
81 }
82 entry = entry->next;
83 }
84 name = lib_msprintf("%d BLOCKS FREE.", contents->blocks_free);
85 sdl_ui_print(name, MENU_FIRST_X, i + IMAGE_FIRST_Y + SDL_FILEREQ_META_NUM);
86 lib_free(name);
87 }
88
sdl_ui_image_file_selector_redraw_cursor(image_contents_t * contents,int offset,int num_items,ui_menu_filereq_mode_t mode,int cur_offset,int old_offset)89 static void sdl_ui_image_file_selector_redraw_cursor(image_contents_t *contents, int offset, int num_items, ui_menu_filereq_mode_t mode, int cur_offset, int old_offset)
90 {
91 int i, j;
92 char* name;
93 uint8_t oldbg = 0;
94 image_contents_file_list_t *entry;
95
96 entry = contents->file_list;
97 for (i = 0; i < offset; ++i) {
98 entry = entry->next;
99 }
100 for (i = 0; i < num_items; ++i) {
101 if ((i == cur_offset) || (i == old_offset)){
102 if (i == cur_offset) {
103 oldbg = sdl_ui_set_cursor_colors();
104 }
105 j = MENU_FIRST_X;
106 name = image_contents_file_to_string(entry, IMAGE_CONTENTS_STRING_PETSCII);
107 j += sdl_ui_print(name, j, i + IMAGE_FIRST_Y + SDL_FILEREQ_META_NUM);
108
109 sdl_ui_print_eol(j, i + IMAGE_FIRST_Y + SDL_FILEREQ_META_NUM);
110 if (i == cur_offset) {
111 sdl_ui_reset_cursor_colors(oldbg);
112 }
113 }
114 entry = entry->next;
115 }
116 }
117
118 /* ------------------------------------------------------------------ */
119 /* External UI interface */
120
sdl_ui_image_file_selection_dialog(const char * filename,ui_menu_filereq_mode_t mode)121 int sdl_ui_image_file_selection_dialog(const char* filename, ui_menu_filereq_mode_t mode)
122 {
123 int total, dirs = 0, files, menu_max;
124 int active = 1;
125 int offset = 0;
126 int redraw = 1;
127 int cur = 0, cur_old = -1;
128
129 image_contents_t *contents = NULL;
130 image_contents_file_list_t *entry;
131 int retval = -1;
132
133 menu_draw = sdl_ui_get_menu_param();
134
135 /* FIXME: it might be a good idea to wrap this into a common imagecontents_read */
136 contents = tapecontents_read(filename);
137 if (contents == NULL) {
138 contents = diskcontents_read(filename, 0);
139 if (contents == NULL) {
140 return 0;
141 }
142 }
143
144 /* count files in the list */
145 files = 0;
146 for (entry = contents->file_list; entry != NULL; entry = entry->next) {
147 files++;
148 }
149
150 total = dirs + files + SDL_FILEREQ_META_NUM;
151 menu_max = menu_draw->max_text_y - (IMAGE_FIRST_Y + SDL_FILEREQ_META_NUM);
152 if (menu_max > 0) { menu_max--; } /* make room for BLOCKS FREE */
153
154 while (active) {
155
156 sdl_ui_set_active_font(MENU_FONT_IMAGES);
157
158 if (redraw) {
159 sdl_ui_image_file_selector_redraw(contents, filename, offset,
160 (total - offset > menu_max) ? menu_max : total - offset,
161 (total - offset > menu_max) ? 1 : 0, mode, cur);
162 redraw = 0;
163 } else {
164 sdl_ui_image_file_selector_redraw_cursor(contents, offset,
165 (total - offset > menu_max) ? menu_max : total - offset,
166 mode, cur, cur_old);
167 }
168
169 sdl_ui_set_active_font(MENU_FONT_ASCII);
170
171 sdl_ui_refresh();
172
173 switch (sdl_ui_menu_poll_input()) {
174 case MENU_ACTION_HOME:
175 cur_old = cur;
176 cur = 0;
177 offset = 0;
178 redraw = 1;
179 break;
180
181 case MENU_ACTION_END:
182 cur_old = cur;
183 if (total < (menu_max - 1)) {
184 cur = total - 1;
185 offset = 0;
186 } else {
187 cur = menu_max - 1;
188 offset = total - menu_max;
189 }
190 redraw = 1;
191 break;
192
193 case MENU_ACTION_UP:
194 if (cur > 0) {
195 cur_old = cur;
196 --cur;
197 } else {
198 if (offset > 0) {
199 offset--;
200 redraw = 1;
201 }
202 }
203 break;
204
205 case MENU_ACTION_PAGEUP:
206 case MENU_ACTION_LEFT:
207 offset -= menu_max;
208 if (offset < 0) {
209 offset = 0;
210 cur_old = -1;
211 cur = 0;
212 }
213 redraw = 1;
214 break;
215
216 case MENU_ACTION_DOWN:
217 if (cur < (menu_max - 1)) {
218 if ((cur + offset) < total - 1) {
219 cur_old = cur;
220 ++cur;
221 }
222 } else {
223 if (offset < (total - menu_max)) {
224 offset++;
225 redraw = 1;
226 }
227 }
228 break;
229
230 case MENU_ACTION_PAGEDOWN:
231 case MENU_ACTION_RIGHT:
232 offset += menu_max;
233 if (offset >= total) {
234 offset = total - 1;
235 cur_old = -1;
236 cur = 0;
237 } else if ((cur + offset) >= total) {
238 cur_old = -1;
239 cur = total - offset - 1;
240 }
241 redraw = 1;
242 break;
243
244 case MENU_ACTION_SELECT:
245 active = 0;
246 retval = offset + cur - dirs - SDL_FILEREQ_META_NUM + 1;
247 break;
248
249 case MENU_ACTION_CANCEL:
250 case MENU_ACTION_EXIT:
251 active = 0;
252 break;
253
254 default:
255 SDL_Delay(10);
256 break;
257 }
258 }
259
260 return retval;
261 }
262