2.5 - Start of filebrowser.
[blender-staging.git] / source / blender / editors / space_file / space_file.c
1 /**
2  * $Id:
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2008 Blender Foundation.
21  * All rights reserved.
22  *
23  * 
24  * Contributor(s): Blender Foundation
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 #include <string.h>
30 #include <stdio.h>
31
32 #include "DNA_object_types.h"
33 #include "DNA_space_types.h"
34 #include "DNA_scene_types.h"
35 #include "DNA_screen_types.h"
36
37 #include "MEM_guardedalloc.h"
38
39 #include "BLO_readfile.h"
40
41 #include "BLI_blenlib.h"
42 #include "BLI_arithb.h"
43 #include "BLI_rand.h"
44
45 #include "BKE_colortools.h"
46 #include "BKE_context.h"
47 #include "BKE_screen.h"
48
49 #include "ED_space_api.h"
50 #include "ED_screen.h"
51 #include "ED_fileselect.h"
52
53 #include "BIF_gl.h"
54
55 #include "WM_api.h"
56 #include "WM_types.h"
57
58 #include "UI_interface.h"
59 #include "UI_resources.h"
60 #include "UI_view2d.h"
61
62 #include "ED_markers.h"
63 #include "ED_fileselect.h"
64
65 #include "file_intern.h"        // own include
66 #include "fsmenu.h"
67 #include "filelist.h"
68
69 /* ******************** default callbacks for file space ***************** */
70
71 static SpaceLink *file_new(const bContext *C)
72 {
73         ARegion *ar;
74         SpaceFile *sfile;
75         
76         sfile= MEM_callocN(sizeof(SpaceFile), "initfile");
77         sfile->spacetype= SPACE_FILE;   
78         sfile->params= MEM_callocN(sizeof(FileSelectParams), "fileselparams");
79         sfile->params->files = filelist_new();
80
81         // ED_fileselect_set_params(C, FILE_UNIX, "Load File", "F:\\photos\\2008_Kos", NULL, NULL, 0, 0, 0);
82
83         /* XXX move to context
84         sfile->dir[0]= '/';
85         strcpy(sfile->dir, "F:\\photos\\2008_Kos");
86         sfile->type= FILE_UNIX;
87         strcpy(sfile->title, "Load");
88         sfile->prv_h = 96;
89         sfile->prv_w = 96;
90         sfile->files = NULL;
91         */
92
93         /* header */
94         ar= MEM_callocN(sizeof(ARegion), "header for file");
95         BLI_addtail(&sfile->regionbase, ar);
96         ar->regiontype= RGN_TYPE_HEADER;
97         ar->alignment= RGN_ALIGN_BOTTOM;
98
99         /* channel list region */
100         ar= MEM_callocN(sizeof(ARegion), "channel area for file");
101         BLI_addtail(&sfile->regionbase, ar);
102         ar->regiontype= RGN_TYPE_CHANNELS;
103         ar->alignment= RGN_ALIGN_LEFT;
104
105         /* ui list region */
106         ar= MEM_callocN(sizeof(ARegion), "ui area for file");
107         BLI_addtail(&sfile->regionbase, ar);
108         ar->regiontype= RGN_TYPE_UI;
109         ar->alignment= RGN_ALIGN_TOP;
110
111         /* main area */
112         ar= MEM_callocN(sizeof(ARegion), "main area for file");
113         BLI_addtail(&sfile->regionbase, ar);
114         ar->regiontype= RGN_TYPE_WINDOW;
115         ar->v2d.scroll = (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM);
116         ar->v2d.align = (V2D_ALIGN_NO_NEG_X|V2D_ALIGN_NO_POS_Y);
117         ar->v2d.keepzoom = (V2D_LOCKZOOM_X|V2D_LOCKZOOM_Y|V2D_KEEPZOOM|V2D_KEEPASPECT);
118         ar->v2d.keeptot= V2D_KEEPTOT_STRICT;
119         ar->v2d.minzoom= ar->v2d.maxzoom= 1.0f;
120
121         return (SpaceLink *)sfile;
122 }
123
124 /* not spacelink itself */
125 static void file_free(SpaceLink *sl)
126 {       
127         SpaceFile *sfile= (SpaceFile *) sl;
128         
129         if (sfile->params) {
130                 if(sfile->params->files) {
131                         filelist_free(sfile->params->files);
132                         filelist_freelib(sfile->params->files);
133                         MEM_freeN(sfile->params->files);
134                         sfile->params->files = 0;
135                 }
136                 if(sfile->params->pupmenu)
137                         MEM_freeN(sfile->params->pupmenu);
138                 MEM_freeN(sfile->params);
139                 sfile->params = 0;
140         }
141         
142 }
143
144
145 /* spacetype; init callback */
146 static void file_init(struct wmWindowManager *wm, ScrArea *sa)
147 {       
148 }
149
150 static SpaceLink *file_duplicate(SpaceLink *sl)
151 {
152         SpaceFile *sfilen= MEM_dupallocN(sl);
153         
154         /* clear or remove stuff from old */
155         
156         return (SpaceLink *)sfilen;
157 }
158
159
160
161 /* add handlers, stuff you only do once or on area/region changes */
162 static void file_main_area_init(wmWindowManager *wm, ARegion *ar)
163 {
164         ListBase *keymap;
165         
166         UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
167         
168         /* own keymap */
169         keymap= WM_keymap_listbase(wm, "File", SPACE_FILE, 0);  /* XXX weak? */
170         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
171 }
172
173 static void file_main_area_draw(const bContext *C, ARegion *ar)
174 {
175         /* draw entirely, view changes should be handled here */
176         SpaceFile *sfile= (SpaceFile*)CTX_wm_space_data(C);
177         FileSelectParams* params = ED_fileselect_get_params(C);
178         View2D *v2d= &ar->v2d;
179         View2DScrollers *scrollers;
180         float col[3];
181         
182         if (!params->files) {
183                 params->files = filelist_new();
184                 filelist_setdir(params->files, params->dir);
185                 filelist_settype(params->files, params->type);
186         }
187
188         if (filelist_empty(params->files))
189         {
190                 unsigned int filter = 0;
191                 filelist_hidedot(params->files, params->flag & FILE_HIDE_DOT);
192                 if (params->flag & FILE_FILTER) {
193                         filter = params->filter ;
194                 } else {
195                         filter = 0;
196                 }
197
198                 filelist_setfilter(params->files, filter);
199                 filelist_readdir(params->files);
200                 
201                 if(params->sort!=FILE_SORTALPHA) filelist_sort(params->files, params->sort);            
202         }
203
204
205         /* clear and setup matrix */
206         UI_GetThemeColor3fv(TH_BACK, col);
207         glClearColor(col[0], col[1], col[2], 0.0);
208         glClear(GL_COLOR_BUFFER_BIT);
209         
210         file_calc_previews(C,ar);
211
212
213         /* data... */
214         UI_view2d_view_ortho(C, v2d);
215         
216         if (params->display) {
217                 file_draw_previews(C, ar);
218         } else {
219                 file_draw_list(C, ar);
220         }
221         
222         
223         /* reset view matrix */
224         UI_view2d_view_restore(C);
225         
226         /* scrollers */
227         scrollers= UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
228         UI_view2d_scrollers_draw(C, v2d, scrollers);
229         UI_view2d_scrollers_free(scrollers);
230
231 }
232
233 void file_operatortypes(void)
234 {
235         WM_operatortype_append(ED_FILE_OT_select);
236         WM_operatortype_append(ED_FILE_OT_select_bookmark);
237 }
238
239 void file_keymap(struct wmWindowManager *wm)
240 {
241         ListBase *keymap= WM_keymap_listbase(wm, "File", SPACE_FILE, 0);
242         WM_keymap_add_item(keymap, "ED_FILE_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
243
244         keymap= WM_keymap_listbase(wm, "FileBookmark", SPACE_FILE, 0);
245         WM_keymap_add_item(keymap, "ED_FILE_OT_select_bookmark", SELECTMOUSE, KM_PRESS, 0, 0);
246 }
247
248
249 static void file_channel_area_init(wmWindowManager *wm, ARegion *ar)
250 {
251         ListBase *keymap;
252
253         UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
254
255         /* own keymap */
256         keymap= WM_keymap_listbase(wm, "FileBookmark", SPACE_FILE, 0);
257         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, NULL, NULL);
258 }
259
260 static void file_channel_area_draw(const bContext *C, ARegion *ar)
261 {
262         View2D *v2d= &ar->v2d;
263         float col[3];
264
265         UI_GetThemeColor3fv(TH_BACK, col);
266         glClearColor(col[0], col[1], col[2], 0.0);
267         glClear(GL_COLOR_BUFFER_BIT);
268
269         /* data... */
270         UI_view2d_view_ortho(C, v2d);
271
272         file_draw_fsmenu(C, ar);
273 }
274
275 /* add handlers, stuff you only do once or on area/region changes */
276 static void file_header_area_init(wmWindowManager *wm, ARegion *ar)
277 {
278         UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy);
279 }
280
281 static void file_header_area_draw(const bContext *C, ARegion *ar)
282 {
283         float col[3];
284         
285         /* clear */
286         if(ED_screen_area_active(C))
287                 UI_GetThemeColor3fv(TH_HEADER, col);
288         else
289                 UI_GetThemeColor3fv(TH_HEADERDESEL, col);
290         
291         glClearColor(col[0], col[1], col[2], 0.0);
292         glClear(GL_COLOR_BUFFER_BIT);
293         
294         /* set view2d view matrix for scrolling (without scrollers) */
295         UI_view2d_view_ortho(C, &ar->v2d);
296         
297         file_header_buttons(C, ar);
298         
299         /* restore view matrix? */
300         UI_view2d_view_restore(C);
301 }
302
303 /* add handlers, stuff you only do once or on area/region changes */
304 static void file_ui_area_init(wmWindowManager *wm, ARegion *ar)
305 {
306         UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy);
307 }
308
309 static void file_ui_area_draw(const bContext *C, ARegion *ar)
310 {
311         float col[3];
312         /* clear */
313         UI_GetThemeColor3fv(TH_BACK, col);
314         glClearColor(col[0], col[1], col[2], 0.0);
315         glClear(GL_COLOR_BUFFER_BIT);
316
317         /* set view2d view matrix for scrolling (without scrollers) */
318         UI_view2d_view_ortho(C, &ar->v2d);
319
320         file_draw_buttons(C, ar);
321
322         UI_view2d_view_restore(C);
323 }
324
325 static void file_main_area_listener(ARegion *ar, wmNotifier *wmn)
326 {
327         /* context changes */
328 }
329
330 /* only called once, from space/spacetypes.c */
331 void ED_spacetype_file(void)
332 {
333         SpaceType *st= MEM_callocN(sizeof(SpaceType), "spacetype file");
334         ARegionType *art;
335         
336         st->spaceid= SPACE_FILE;
337         
338         st->new= file_new;
339         st->free= file_free;
340         st->init= file_init;
341         st->duplicate= file_duplicate;
342         st->operatortypes= file_operatortypes;
343         st->keymap= file_keymap;
344         
345         /* regions: main window */
346         art= MEM_callocN(sizeof(ARegionType), "spacetype file region");
347         art->regionid = RGN_TYPE_WINDOW;
348         art->init= file_main_area_init;
349         art->draw= file_main_area_draw;
350         // art->listener= file_main_area_listener;
351         art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
352         BLI_addhead(&st->regiontypes, art);
353         
354         /* regions: header */
355         art= MEM_callocN(sizeof(ARegionType), "spacetype file region");
356         art->regionid = RGN_TYPE_HEADER;
357         art->minsizey= HEADERY;
358         art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
359         art->init= file_header_area_init;
360         art->draw= file_header_area_draw;
361         BLI_addhead(&st->regiontypes, art);
362         
363         /* regions: ui */
364         art= MEM_callocN(sizeof(ARegionType), "spacetype file region");
365         art->regionid = RGN_TYPE_UI;
366         art->minsizey= 100;
367         art->keymapflag= ED_KEYMAP_UI;
368         art->init= file_ui_area_init;
369         art->draw= file_ui_area_draw;
370         BLI_addhead(&st->regiontypes, art);
371
372         /* regions: channels (directories) */
373         art= MEM_callocN(sizeof(ARegionType), "spacetype file region");
374         art->regionid = RGN_TYPE_CHANNELS;
375         art->minsizex= 200;
376         art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
377         art->init= file_channel_area_init;
378         art->draw= file_channel_area_draw;
379         BLI_addhead(&st->regiontypes, art);
380         
381         BKE_spacetype_register(st);
382
383 }
384
385 void ED_file_init(void)
386 {
387         char name[FILE_MAX];
388         BLI_make_file_string("/", name, BLI_gethome(), ".Bfs");
389         fsmenu_read_file(name);
390         filelist_init_icons();
391 }
392
393 void ED_file_exit(void)
394 {
395         fsmenu_free();
396         filelist_free_icons();
397 }