== imagebrowser ==
authorAndrea Weikert <elubie@gmx.net>
Sun, 2 Sep 2007 17:25:03 +0000 (17:25 +0000)
committerAndrea Weikert <elubie@gmx.net>
Sun, 2 Sep 2007 17:25:03 +0000 (17:25 +0000)
Initial commit of imagebrowser in trunk.
BIG COMMIT!

Main changes:
* completely reworked imasel space
* creation and storage of the preview images for materials, textures, world and lamp
* thumbnails of images and movie files when browsing in the file system
* loading previews from external .blend when linking or appending
* thumbnail caching according to the Thumbnail Managing Standard: http://jens.triq.net/thumbnail-spec/
* for now just kept imasel access mostly as old imgbrowser (CTRL+F4, CTRL+F1) a bit hidden still.
* filtering of file types (images, movies, .blend, py,...)
* preliminary managing of bookmarks ('B' button to add, XKEY while bookmark active to delete)

More detailed info which will be updated here: http://wiki.blender.org/index.php/User:Elubie/PreviewImageBrowser

Places that need special review (and probably fixes):
* BLO_blendhandle_get_previews in readblenentry
* readfile.c: do_version and refactorings of do_library_append
* UI integration

TODO and known issues still:
* Accented characters do not display correctly with international fonts
* Crash was reported when browsing in directory with movie files
* Bookmark management still needs some UI work (second scrollbar?), feedback here is welcome!

Credits:
Samir Bharadwaj (samirbharadwaj@yahoo.com) for the icon images.

Many thanks to everyone who gave feedback and helped so far!

72 files changed:
projectfiles_vc7/blender/imbuf/BL_imbuf.vcproj
projectfiles_vc7/blender/src/BL_src.vcproj
release/datafiles/prvicons [new file with mode: 0644]
source/blender/blenkernel/BKE_icons.h
source/blender/blenkernel/bad_level_call_stubs/stubs.c
source/blender/blenkernel/intern/icons.c
source/blender/blenkernel/intern/image.c
source/blender/blenkernel/intern/material.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/texture.c
source/blender/blenkernel/intern/world.c
source/blender/blenlib/BLI_blenlib.h
source/blender/blenlib/BLI_storage_types.h
source/blender/blenlib/intern/util.c
source/blender/blenloader/BLO_readfile.h
source/blender/blenloader/intern/readblenentry.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/writefile.c
source/blender/imbuf/IMB_imbuf.h
source/blender/imbuf/IMB_imbuf_types.h
source/blender/imbuf/IMB_thumbs.h [new file with mode: 0644]
source/blender/imbuf/intern/IMB_imginfo.h [new file with mode: 0644]
source/blender/imbuf/intern/allocimbuf.c
source/blender/imbuf/intern/anim.c
source/blender/imbuf/intern/imginfo.c [new file with mode: 0644]
source/blender/imbuf/intern/md5.c [new file with mode: 0644]
source/blender/imbuf/intern/md5.h [new file with mode: 0644]
source/blender/imbuf/intern/png.c
source/blender/imbuf/intern/thumbs.c [new file with mode: 0644]
source/blender/include/BIF_filelist.h [new file with mode: 0644]
source/blender/include/BIF_fsmenu.h
source/blender/include/BIF_imasel.h
source/blender/include/BIF_interface_icons.h
source/blender/include/BIF_resources.h
source/blender/include/BIF_space.h
source/blender/include/BSE_drawimasel.h
source/blender/include/BSE_filesel.h
source/blender/include/blendef.h
source/blender/include/datatoc.h
source/blender/include/interface.h
source/blender/makesdna/DNA_ID.h
source/blender/makesdna/DNA_image_types.h
source/blender/makesdna/DNA_lamp_types.h
source/blender/makesdna/DNA_material_types.h
source/blender/makesdna/DNA_space_types.h
source/blender/makesdna/DNA_texture_types.h
source/blender/makesdna/DNA_userdef_types.h
source/blender/makesdna/DNA_world_types.h
source/blender/python/api2_2x/Window.c
source/blender/quicktime/apple/quicktime_import.c
source/blender/src/buttons_scene.c
source/blender/src/buttons_shading.c
source/blender/src/drawimasel.c
source/blender/src/drawnode.c
source/blender/src/editimasel.c
source/blender/src/editscreen.c
source/blender/src/editsima.c
source/blender/src/filelist.c [new file with mode: 0644]
source/blender/src/filesel.c
source/blender/src/fsmenu.c [new file with mode: 0644]
source/blender/src/glutil.c
source/blender/src/header_imasel.c
source/blender/src/header_info.c
source/blender/src/headerbuttons.c
source/blender/src/imasel.c
source/blender/src/interface_draw.c
source/blender/src/interface_icons.c
source/blender/src/prvicons.c [new file with mode: 0644]
source/blender/src/resources.c
source/blender/src/space.c
source/blender/src/toets.c
source/blender/src/usiblender.c

index 61c0a857da130dd37253624cde4494db215692ac..a214ed3055b40532b1810d402c2b4ca48d5e2858 100644 (file)
                        <File
                                RelativePath="..\..\..\source\blender\imbuf\intern\imageprocess.c">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\blender\imbuf\intern\imginfo.c">
+                       </File>
                        <File
                                RelativePath="..\..\..\source\blender\imbuf\intern\iris.c">
                        </File>
                        <File
                                RelativePath="..\..\..\source\blender\imbuf\intern\jpeg.c">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\blender\imbuf\intern\md5.c">
+                       </File>
                        <File
                                RelativePath="..\..\..\source\blender\imbuf\intern\openexr\openexr_api.cpp">
                        </File>
                        <File
                                RelativePath="..\..\..\source\blender\imbuf\intern\targa.c">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\blender\imbuf\intern\thumbs.c">
+                       </File>
                        <File
                                RelativePath="..\..\..\source\blender\imbuf\intern\tiff.c">
                        </File>
                        <File
                                RelativePath="..\..\..\source\blender\imbuf\IMB_imbuf_types.h">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\blender\imbuf\intern\IMB_imginfo.h">
+                       </File>
                        <File
                                RelativePath="..\..\..\source\blender\imbuf\intern\IMB_iris.h">
                        </File>
                        <File
                                RelativePath="..\..\..\source\blender\imbuf\intern\IMB_targa.h">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\blender\imbuf\IMB_thumbs.h">
+                       </File>
                        <File
                                RelativePath="..\..\..\source\blender\imbuf\intern\IMB_tiff.h">
                        </File>
index c788fb44cab42c914c108e046ac2ff3200db1bd9..b3a92ed98bd3700e4c3223cb59501d2b005ca7fc 100644 (file)
                        <File
                                RelativePath="..\..\..\source\blender\src\eventdebug.c">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\blender\src\filelist.c">
+                       </File>
                        <File
                                RelativePath="..\..\..\source\blender\src\filesel.c">
                        </File>
                        <File
                                RelativePath="..\..\..\source\blender\src\fluidsim.c">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\blender\src\fsmenu.c">
+                       </File>
                        <File
                                RelativePath="..\..\..\source\blender\src\ghostwinlay.c">
                        </File>
                        <File
                                RelativePath="..\..\..\source\blender\src\previewrender.c">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\blender\src\prvicons.c">
+                       </File>
                        <File
                                RelativePath="..\..\..\source\blender\src\renderwin.c">
                        </File>
                        <File
                                RelativePath="..\..\..\source\blender\include\BIF_editview.h">
                        </File>
+                       <File
+                               RelativePath="..\..\..\source\blender\include\BIF_filelist.h">
+                       </File>
                        <File
                                RelativePath="..\..\..\source\blender\include\BIF_fsmenu.h">
                        </File>
diff --git a/release/datafiles/prvicons b/release/datafiles/prvicons
new file mode 100644 (file)
index 0000000..de3980f
Binary files /dev/null and b/release/datafiles/prvicons differ
index 315c7dc7a534c4225cfb2428545a086baa716d83..737adea78bea64aae777d2a9687bcb4da9cac86c 100644 (file)
@@ -1,34 +1,32 @@
 /**
- * $Id$
- *
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License.  See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- * 
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
+* $Id$
+*
+* ***** BEGIN GPL LICENSE BLOCK *****
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version. 
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+* 
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+* 
+* The Original Code is Copyright (C) 2006-2007 Blender Foundation.
+* All rights reserved.
+* 
+* The Original Code is: all of this file.
+* 
+* Contributor(s): none yet.
+* 
+* ***** END GPL LICENSE BLOCK *****
+*
+*/
 
 #ifndef BKE_ICONS_H
 #define BKE_ICONS_H
@@ -44,12 +42,13 @@ struct Icon
        void *drawinfo;
        void *obj;
        short type;
-       short changed;
        DrawInfoFreeFP drawinfo_free;
 };
 
 typedef struct Icon Icon;
 
+struct PreviewImage;
+
 void BKE_icons_init(int first_dyn_id);
 
 /* return icon id for library object or create new icon if not found */
@@ -71,5 +70,19 @@ void BKE_icon_changed(int icon_id);
 /* free all icons */
 void BKE_icons_free();
 
+/* free the preview image */
+void BKE_previewimg_free(struct PreviewImage **prv);
+
+/* free the preview image belonging to the id */
+void BKE_previewimg_free_id(ID *id);
+
+/* create a new preview image */
+struct PreviewImage* BKE_previewimg_create() ;
+
+/* create a copy of the preview image */
+struct PreviewImage* BKE_previewimg_copy(struct PreviewImage *prv);
+
+/* retrieve existing or create new preview image */
+PreviewImage* BKE_previewimg_get(ID *id);
 
 #endif /*  BKE_ICONS_H */
index 4521f1d1dea8637dc6f0e8517053142cd355a6d9..04fac832cc405c6ab7cc92096daf18197756075d 100644 (file)
@@ -324,3 +324,7 @@ void antialias_tagbuf(int xsize, int ysize, char *rectmove) {}
 void ibuf_sample(struct ImBuf *ibuf, float fx, float fy, float dx, float dy, float *result) {}
 
 void update_for_newframe() {}
+
+struct FileList;
+void BIF_filelist_freelib(struct FileList* filelist) {};
+
index ee37a4ec9f985ecec4031a0abb2e63c30d8be25f..f144d2badd1cee419f2cc78e7ba505495913a7d3 100644 (file)
@@ -1,34 +1,32 @@
 /**
- * $Id$
- *
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License.  See http://www.blender.org/BL/ for information
- * about this.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
- */
+* $Id$
+*
+* ***** BEGIN GPL LICENSE BLOCK *****
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version. 
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+* 
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software Foundation,
+* Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+* 
+* The Original Code is Copyright (C) 2006-2007 Blender Foundation.
+* All rights reserved.
+* 
+* The Original Code is: all of this file.
+* 
+* Contributor(s): none yet.
+* 
+* ***** END GPL LICENSE BLOCK *****
+*
+*/
 
 #include <math.h>
 #include <stdlib.h>
 #include "MEM_guardedalloc.h"
 
 #include "DNA_ID.h"
+#include "DNA_image_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_material_types.h"
+#include "DNA_texture_types.h"
+#include "DNA_world_types.h"
 
 #include "BLI_ghash.h"
 
@@ -111,6 +114,101 @@ void BKE_icons_free()
        gIcons = NULL;
 }
 
+struct PreviewImage* BKE_previewimg_create() 
+{
+       PreviewImage* prv_img = NULL;
+       int i;
+
+       prv_img = MEM_callocN(sizeof(PreviewImage), "img_prv");
+
+       for (i=0; i<PREVIEW_MIPMAPS; ++i) {
+               prv_img->changed[i] = 1;
+       }
+       return prv_img;
+}
+
+void BKE_previewimg_free(PreviewImage **prv)
+{
+       if(prv && (*prv)) {
+               int i;
+               
+               for (i=0; i<PREVIEW_MIPMAPS;++i) {
+                       if ((*prv)->rect[i]) {
+                               MEM_freeN((*prv)->rect[i]);
+                               (*prv)->rect[i] = NULL;
+                       }
+               }
+               MEM_freeN((*prv));
+               *prv = NULL;
+       }
+}
+
+struct PreviewImage* BKE_previewimg_copy(PreviewImage *prv) 
+{
+       PreviewImage* prv_img = NULL;
+       int i;
+
+       if (prv) {
+               prv_img = MEM_dupallocN(prv);
+               for (i=0; i < PREVIEW_MIPMAPS; ++i) {
+                       if (prv->rect[i]) {
+                               prv_img->rect[i] = MEM_dupallocN(prv->rect[i]);
+                       } else {
+                               prv_img->rect[i] = NULL;
+                       }
+               }
+       }
+       return prv_img;
+}
+
+void BKE_previewimg_free_id(ID *id) 
+{
+       if (GS(id->name) == ID_MA) {
+               Material *mat = (Material*)id;  
+               BKE_previewimg_free(&mat->preview);
+       } else if (GS(id->name) == ID_TE) {
+               Tex *tex = (Tex*)id;
+               BKE_previewimg_free(&tex->preview);
+       } else if (GS(id->name) == ID_WO) {
+               World *wo = (World*)id;
+               BKE_previewimg_free(&wo->preview);
+       } else if (GS(id->name) == ID_LA) {
+               Lamp *la  = (Lamp*)id;
+               BKE_previewimg_free(&la->preview);
+       } else if (GS(id->name) == ID_IM) {
+               Image *img  = (Image*)id;
+               BKE_previewimg_free(&img->preview);
+       }
+}
+
+PreviewImage* BKE_previewimg_get(ID *id) 
+{
+       PreviewImage* prv_img = NULL;
+
+       if (GS(id->name) == ID_MA) {
+               Material *mat = (Material*)id;  
+               if (!mat->preview) mat->preview = BKE_previewimg_create();
+               prv_img = mat->preview;
+       } else if (GS(id->name) == ID_TE) {
+               Tex *tex = (Tex*)id;
+               if (!tex->preview) tex->preview = BKE_previewimg_create();
+               prv_img = tex->preview;
+       } else if (GS(id->name) == ID_WO) {
+               World *wo = (World*)id;
+               if (!wo->preview) wo->preview = BKE_previewimg_create();
+               prv_img = wo->preview;
+       } else if (GS(id->name) == ID_LA) {
+               Lamp *la  = (Lamp*)id;
+               if (!la->preview) la->preview = BKE_previewimg_create();
+               prv_img = la->preview;
+       } else if (GS(id->name) == ID_IM) {
+               Image *img  = (Image*)id;
+               if (!img->preview) img->preview = BKE_previewimg_create();
+               prv_img = img->preview;
+       } 
+
+       return prv_img;
+}
 
 void BKE_icon_changed(int id)
 {
@@ -122,7 +220,15 @@ void BKE_icon_changed(int id)
        
        if (icon)
        {
-               icon->changed = 1;
+               PreviewImage *prv = BKE_previewimg_get((ID*)icon->obj);
+
+               /* all previews changed */
+               if (prv) {
+                       int i;
+                       for (i=0; i<PREVIEW_MIPMAPS; ++i) {
+                               prv->changed[i] = 1;
+                       }
+               }
        }       
 }
 
@@ -151,7 +257,6 @@ int BKE_icon_getid(struct ID* id)
        /* next two lines make sure image gets created */
        new_icon->drawinfo = 0;
        new_icon->drawinfo_free = 0;
-       new_icon->changed = 1; 
 
        BLI_ghash_insert(gIcons, (void *)id->icon_id, new_icon);
        
index 2c91c6cb0be9fe323906b5e8e56e3a2ed61d375f..3a64c3504cb96833940b0786cab2c21f3b42ddca 100644 (file)
@@ -206,13 +206,6 @@ static void image_free_buffers(Image *ima)
        if(ima->anim) IMB_free_anim(ima->anim);
        ima->anim= NULL;
        
-       if (ima->preview) {
-               if (ima->preview->rect)
-                       MEM_freeN(ima->preview->rect);
-               MEM_freeN(ima->preview);
-               ima->preview = NULL;
-       }
-       
        if(ima->rr) {
                RE_FreeRenderResult(ima->rr);
                ima->rr= NULL;
@@ -234,6 +227,10 @@ void free_image(Image *ima)
        }
        BKE_icon_delete(&ima->id);
        ima->id.icon_id = 0;
+       if (ima->preview) {
+               BKE_previewimg_free(&ima->preview);
+       }
+       
 }
 
 /* only image block itself */
index 56b8307020aeb1856571b2d26a7a6e93b88fa28d..f5f726b1745012beb52a31543386eee9fef64735 100644 (file)
@@ -90,6 +90,7 @@ void free_material(Material *ma)
        if(ma->ramp_col) MEM_freeN(ma->ramp_col);
        if(ma->ramp_spec) MEM_freeN(ma->ramp_spec);
        
+       BKE_previewimg_free(&ma->preview);
        BKE_icon_delete((struct ID*)ma);
        ma->id.icon_id = 0;
        
@@ -159,6 +160,8 @@ void init_material(Material *ma)
        ma->sss_back= 1.0f;
 
        ma->mode= MA_TRACEBLE|MA_SHADBUF|MA_SHADOW|MA_RADIO|MA_RAYBIAS|MA_TANGENT_STR;
+
+       ma->preview = NULL;
 }
 
 Material *add_material(char *name)
@@ -196,6 +199,8 @@ Material *copy_material(Material *ma)
        if(ma->ramp_col) man->ramp_col= MEM_dupallocN(ma->ramp_col);
        if(ma->ramp_spec) man->ramp_spec= MEM_dupallocN(ma->ramp_spec);
        
+       if (ma->preview) man->preview = BKE_previewimg_copy(ma->preview);
+
        if(ma->nodetree) {
                man->nodetree= ntreeCopyTree(ma->nodetree, 0);  /* 0 == full new tree */
        }
index 3f26501db6fc7e1766c744e24a508690782b11b0..349ccda812637f9a0e124e8b7d00eb95e40d71ef 100644 (file)
@@ -598,7 +598,7 @@ void *add_lamp(char *name)
        la->area_size=la->area_sizey=la->area_sizez= 1.0; 
        la->buffers= 1;
        la->buftype= LA_SHADBUF_HALFWAY;
-       
+       la->preview=NULL;
        return la;
 }
 
@@ -619,6 +619,8 @@ Lamp *copy_lamp(Lamp *la)
        
        id_us_plus((ID *)lan->ipo);
 
+       if (la->preview) lan->preview = BKE_previewimg_copy(la->preview);
+
        BPY_copy_scriptlink(&la->scriptlink);
        
        return lan;
@@ -696,7 +698,8 @@ void free_lamp(Lamp *la)
                if(mtex) MEM_freeN(mtex);
        }
        la->ipo= 0;
-
+       
+       BKE_previewimg_free(&la->preview);
        BKE_icon_delete(&la->id);
        la->id.icon_id = 0;
 }
index bda933802ee289469bfeafa132b46b107559c709..d41ceb5a4b7e172291c08b9bfeba16b2aa66e1de 100644 (file)
@@ -390,6 +390,7 @@ void free_texture(Tex *tex)
        free_plugin_tex(tex->plugin);
        if(tex->coba) MEM_freeN(tex->coba);
        if(tex->env) BKE_free_envmap(tex->env);
+       BKE_previewimg_free(&tex->preview);
        BKE_icon_delete((struct ID*)tex);
        tex->id.icon_id = 0;
 }
@@ -462,6 +463,8 @@ void default_tex(Tex *tex)
        tex->iuser.fie_ima= 2;
        tex->iuser.ok= 1;
        tex->iuser.frames= 100;
+       
+       tex->preview = NULL;
 }
 
 /* ------------------------------------------------------------------------- */
@@ -541,6 +544,8 @@ Tex *copy_texture(Tex *tex)
        if(texn->coba) texn->coba= MEM_dupallocN(texn->coba);
        if(texn->env) texn->env= BKE_copy_envmap(texn->env);
        
+       if(tex->preview) texn->preview = BKE_previewimg_copy(tex->preview);
+
        return texn;
 }
 
index 612c095aac744dfb53316442a4ee18651898094e..ce41720cb9d0baa8e264e2df7b30f921c14db59b 100644 (file)
@@ -75,6 +75,8 @@ void free_world(World *wrld)
                if(mtex && mtex->tex) mtex->tex->id.us--;
                if(mtex) MEM_freeN(mtex);
        }
+       BKE_previewimg_free(&wrld->preview);
+
        wrld->ipo= 0;
        BKE_icon_delete((struct ID*)wrld);
        wrld->id.icon_id = 0;
@@ -102,7 +104,8 @@ World *add_world(char *name)
        wrld->aobias= 0.05;
        
        wrld->physicsEngine= WOPHY_BULLET;//WOPHY_SUMO; Bullet by default
-       
+       wrld->preview = NULL;
+
        return wrld;
 }
 
@@ -121,6 +124,8 @@ World *copy_world(World *wrld)
                }
        }
        
+       if (wrld->preview) wrldn->preview = BKE_previewimg_copy(wrld->preview);
+
        BPY_copy_scriptlink(&wrld->scriptlink);
 
        id_us_plus((ID *)wrldn->ipo);
index 6e51d171461dab6adb0de4e3cbd091c0e6042eaa..aaa50206ddbc63815a1c10cfedacf9567273a851 100644 (file)
@@ -217,6 +217,11 @@ int BLI_streq(char *a, char *b);
         */
 int BLI_strcaseeq(char *a, char *b);
 
+/* in util.c */
+#ifdef WITH_ICONV
+void BLI_string_to_utf8(char *original, char *utf_8, char *code);
+#endif
+
        /**
         * Read a file as ASCII lines. An empty list is
         * returned if the file cannot be opened or read.
index 825a8bc9cbda31b598524b9b3b19edcf52ad0709..ebce33852a1254cb010387d8f5ff6005b40f928c 100644 (file)
@@ -52,6 +52,8 @@ struct header{
 typedef unsigned int mode_t;
 #endif
 
+struct ImBuf;
+
 struct direntry{
        char    *string;
        mode_t  type;
@@ -68,6 +70,7 @@ struct direntry{
        char    extra[16];
        void    *poin;
        int             nr;
+       struct ImBuf *image;
 };
 
 struct dirlink
index cfce8e3dafaaa1d6dd20e59907eab3aaad1e88d0..2a47dcc300bad5d9b11f3593f1dd685711c9fd95 100644 (file)
@@ -1491,6 +1491,38 @@ int BLI_strncasecmp(const char *s1, const char *s2, int n) {
        return 0;
 }
 
+
+#ifdef WITH_ICONV
+#include "iconv.h"
+#include "localcharset.h"
+
+void BLI_string_to_utf8(char *original, char *utf_8, char *code)
+{
+       size_t inbytesleft=strlen(original);
+       size_t outbytesleft=512;
+       size_t rv=0;
+       iconv_t cd;
+       
+       if (NULL == code) {
+               code = locale_charset();
+       }
+       cd=iconv_open("UTF-8", code);
+
+       if (cd == (iconv_t)(-1)) {
+               printf("iconv_open Error");
+               *utf_8='\0';
+               return ;
+       }
+       rv=iconv(cd, &original, &inbytesleft, &utf_8, &outbytesleft);
+       if (rv == (size_t) -1) {
+               printf("iconv Error\n");
+               return ;
+       }
+       *utf_8 = '\0';
+       iconv_close(cd);
+}
+#endif // WITH_ICONV
+
 void BLI_timestr(double time, char *str)
 {
        /* format 00:00:00.00 (hr:min:sec) string has to be 12 long */
index 7f621410a4faa443d5336706c92788c17a5f51f1..09edfe90d02b79c58e061306e06cb9dd9e9cd8c7 100644 (file)
@@ -38,12 +38,15 @@ extern "C" {
 #endif
 
 struct SpaceFile;
+struct SpaceImaSel;
+struct FileList;
 struct LinkNode;
 struct Main;
 struct UserDef;
 struct bScreen;
 struct Scene;
 struct MemFile;
+struct direntry;
 
 typedef struct BlendHandle     BlendHandle;
 
@@ -191,6 +194,21 @@ BLO_blendhandle_get_datablock_names(
        BlendHandle *bh, 
        int ofblocktype);
 
+/**
+ * Gets the previews of all the datablocks in a file
+ * of a certain type (ie. All the scene names in
+ * a file).
+ * 
+ * @param bh The blendhandle to access.
+ * @param ofblocktype The type of names to get.
+ * @return A BLI_linklist of PreviewImage. The PreviewImage links
+ * should be freed with malloc.
+ */
+       struct LinkNode*
+BLO_blendhandle_get_previews(
+       BlendHandle *bh, 
+       int ofblocktype);
+
 /**
  * Gets the names of all the datablock groups in a
  * file. (ie. file contains Scene, Mesh, and Lamp
@@ -219,6 +237,7 @@ BLO_blendhandle_close(
 char *BLO_gethome(void);
 int BLO_has_bfile_extension(char *str);
 void BLO_library_append(struct SpaceFile *sfile, char *dir, int idcode);
+void BLO_library_append_(BlendHandle **libfiledata, struct direntry* filelist, int totfile, char *dir, char* file, short flag, int idcode);
 void BLO_script_library_append(BlendHandle *bh, char *dir, char *name, int idcode, short flag, struct Scene *scene);
 
 BlendFileData* blo_read_blendafterruntime(int file, int actualsize, BlendReadError *error_r);
index 5f67c060c040dd144f2bc4487922616612e0b13f..dfa06ebdeb8465b7289a7afadcd3f18c351d9833 100644 (file)
@@ -50,6 +50,7 @@
 #include "DNA_space_types.h"
 #include "DNA_userdef_types.h"
 #include "DNA_ID.h"
+#include "DNA_material_types.h"
 
 #include "BKE_utildefines.h" // for ENDB
 
@@ -61,6 +62,7 @@
 #include "BLO_undofile.h"
 
 #include "readfile.h"
+#include "genfile.h"
 
 #include "BLO_readblenfile.h"
 
@@ -218,6 +220,70 @@ LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh, int ofblocktype)
        return names;
 }
 
+LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype) 
+{
+       FileData *fd= (FileData*) bh;
+       LinkNode *previews= NULL;
+       BHead *bhead;
+       int looking=0;
+       int npreviews = 0;
+       PreviewImage* prv = NULL;
+       PreviewImage* new_prv = NULL;
+       
+       for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead)) {
+               if (bhead->code==ofblocktype) {
+                       ID *id= (ID*) (bhead+1);
+                       if (GS(id->name) == ID_MA) {
+                               new_prv = MEM_callocN(sizeof(PreviewImage), "newpreview");
+                               BLI_linklist_prepend(&previews, new_prv);
+                               looking = 1;
+                       }
+               } else if (bhead->code==DATA) {
+                       if (looking) {
+                               if (bhead->SDNAnr == dna_findstruct_nr(fd->filesdna, "PreviewImage") ) {
+                                       prv = (PreviewImage*) (bhead+1);
+                                       npreviews = 0;                          
+                                       memcpy(new_prv, prv, sizeof(PreviewImage));
+                                       if (prv->rect[0]) {
+                                               unsigned int *rect = NULL;
+                                               int rectlen = 0;
+                                               new_prv->rect[0] = MEM_callocN(new_prv->w[0]*new_prv->h[0]*sizeof(unsigned int), "prvrect");
+                                               bhead= blo_nextbhead(fd, bhead);
+                                               rect = (unsigned int*)(bhead+1);
+                                               rectlen = new_prv->w[0]*new_prv->h[0]*sizeof(unsigned int);
+                                               memcpy(new_prv->rect[0], rect, bhead->len);                                     
+                                       } else {
+                                               new_prv->rect[0] = NULL;
+                                       }
+                                       
+                                       if (prv->rect[1]) {
+                                               unsigned int *rect = NULL;
+                                               int rectlen = 0;
+                                               new_prv->rect[1] = MEM_callocN(new_prv->w[1]*new_prv->h[1]*sizeof(unsigned int), "prvrect");
+                                               bhead= blo_nextbhead(fd, bhead);
+                                               rect = (unsigned int*)(bhead+1);
+                                               rectlen = new_prv->w[1]*new_prv->h[1]*sizeof(unsigned int);                                     
+                                               memcpy(new_prv->rect[1], rect, bhead->len);                                                     
+                                       } else {
+                                               new_prv->rect[1] = NULL;
+                                       }
+                               }
+                       }
+               } else if (bhead->code==ENDB) {
+                       break;
+               } else if (bhead->code==DATA) {
+                       /* DATA blocks between IDBlock and Preview */
+               } else {
+                       looking = 0;
+                       new_prv = NULL;
+                       prv = NULL;
+               }
+               
+       }
+       
+       return previews;
+}
+
 LinkNode *BLO_blendhandle_get_linkable_groups(BlendHandle *bh) 
 {
        FileData *fd= (FileData*) bh;
index fa21161f8eb6a9d2319eacffee838f6e5925c30f..1f1dd84f49cc68dd58f707022b71e52be45196f9 100644 (file)
 #include "BKE_idprop.h"
 
 #include "BIF_butspace.h" // badlevel, for do_versions, patching event codes
+#include "BIF_filelist.h" // badlevel too, where to move this? - elubie
 #include "BIF_previewrender.h" // bedlelvel, for struct RenderInfo
 #include "BLO_readfile.h"
 #include "BLO_undofile.h"
@@ -1541,7 +1542,12 @@ static PreviewImage *direct_link_preview_image(FileData *fd, PreviewImage *old_p
        PreviewImage *prv= newdataadr(fd, old_prv);
 
        if (prv) {
-               prv->rect = newdataadr(fd, prv->rect);
+               int i;
+               for (i=0; i < PREVIEW_MIPMAPS; ++i) {
+                       if (prv->rect[i]) {
+                               prv->rect[i] = newdataadr(fd, prv->rect[i]);
+                       }
+               }
        }
 
        return prv;
@@ -1911,6 +1917,7 @@ static void direct_link_lamp(FileData *fd, Lamp *la)
        for(a=0; a<MAX_MTEX; a++) {
                la->mtex[a]= newdataadr(fd, la->mtex[a]);
        }
+       la->preview = direct_link_preview_image(fd, la->preview);
 }
 
 /* ************ READ keys ***************** */
@@ -2058,6 +2065,7 @@ static void direct_link_world(FileData *fd, World *wrld)
        for(a=0; a<MAX_MTEX; a++) {
                wrld->mtex[a]= newdataadr(fd, wrld->mtex[a]);
        }
+       wrld->preview = direct_link_preview_image(fd, wrld->preview);
 }
 
 
@@ -2367,6 +2375,8 @@ static void direct_link_texture(FileData *fd, Tex *tex)
                memset(tex->env->cube, 0, 6*sizeof(void *));
                tex->env->ok= 0;
        }
+       tex->preview = direct_link_preview_image(fd, tex->preview);
+
        tex->iuser.ok= 1;
 }
 
@@ -2424,6 +2434,8 @@ static void direct_link_material(FileData *fd, Material *ma)
        ma->nodetree= newdataadr(fd, ma->nodetree);
        if(ma->nodetree)
                direct_link_nodetree(fd, ma->nodetree);
+
+       ma->preview = direct_link_preview_image(fd, ma->preview);
 }
 
 /* ************ READ MESH ***************** */
@@ -3448,7 +3460,13 @@ static void lib_link_screen(FileData *fd, Main *main)
                                                sfile->pupmenu= NULL;
                                        }
                                        else if(sl->spacetype==SPACE_IMASEL) {
-                                               check_imasel_copy((SpaceImaSel *)sl);
+                                               SpaceImaSel *simasel= (SpaceImaSel *)sl;
+
+                                               simasel->files = NULL;                                          
+                                               simasel->returnfunc= NULL;
+                                               simasel->menup= NULL;
+                                               simasel->pupmenu= NULL;
+                                               simasel->img= NULL;
                                        }
                                        else if(sl->spacetype==SPACE_ACTION) {
                                                SpaceAction *saction= (SpaceAction *)sl;
@@ -3618,7 +3636,10 @@ void lib_link_screen_restore(Main *newmain, Scene *curscene)
                                        sfile->libfiledata= 0;
                                }
                                else if(sl->spacetype==SPACE_IMASEL) {
-                                       ;
+                    SpaceImaSel *simasel= (SpaceImaSel *)sl;
+                                       if (simasel->files) {
+                                               BIF_filelist_freelib(simasel->files);
+                                       }
                                }
                                else if(sl->spacetype==SPACE_ACTION) {
                                        SpaceAction *saction= (SpaceAction *)sl;
@@ -6481,6 +6502,62 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
                        Mesh *me;
                        for(me=main->mesh.first; me; me=me->id.next)
                                customdata_version_243(me);
+               }               
+
+       }
+
+
+       if (main->versionfile < 244) {
+               bScreen *sc;
+               Image* ima;
+
+               /* repair preview from 242 */
+               for(ima= main->image.first; ima; ima= ima->id.next) {
+                       ima->preview = NULL;
+               }
+               
+               /* repair imasel space - completely reworked */
+               for(sc= main->screen.first; sc; sc= sc->id.next) {
+                       ScrArea *sa;
+                       sa= sc->areabase.first;
+                       while(sa) {
+                               SpaceLink *sl;
+
+                               for (sl= sa->spacedata.first; sl; sl= sl->next) {
+                                       if(sl->spacetype==SPACE_IMASEL) {
+                                               SpaceImaSel *simasel= (SpaceImaSel*) sl;
+                                               simasel->blockscale= 0.7;
+                                               /* view 2D */
+                                               simasel->v2d.tot.xmin=  -10.0;
+                                               simasel->v2d.tot.ymin=  -10.0;
+                                               simasel->v2d.tot.xmax= (float)sa->winx + 10.0f;
+                                               simasel->v2d.tot.ymax= (float)sa->winy + 10.0f;                                         
+                                               simasel->v2d.cur.xmin=  0.0;
+                                               simasel->v2d.cur.ymin=  0.0;
+                                               simasel->v2d.cur.xmax= (float)sa->winx;
+                                               simasel->v2d.cur.ymax= (float)sa->winy;                                         
+                                               simasel->v2d.min[0]= 1.0;
+                                               simasel->v2d.min[1]= 1.0;                                               
+                                               simasel->v2d.max[0]= 32000.0f;
+                                               simasel->v2d.max[1]= 32000.0f;                                          
+                                               simasel->v2d.minzoom= 0.5f;
+                                               simasel->v2d.maxzoom= 1.21f;                                            
+                                               simasel->v2d.scroll= 0;
+                                               simasel->v2d.keepaspect= 1;
+                                               simasel->v2d.keepzoom= 1;
+                                               simasel->v2d.keeptot= 0;
+                                               simasel->prv_h = 96;
+                                               simasel->prv_w = 96;
+                                               simasel->flag = 7; /* ??? elubie */
+                                               strcpy (simasel->dir,  U.textudir);     /* TON */
+                                               strcpy (simasel->file, "");
+
+                                               simasel->returnfunc     =  0;   
+                                               simasel->title[0]       =  0;
+                                       }
+                               }
+                               sa = sa->next;
+                       }
                }
        }
        if(main->versionfile <= 244) {
@@ -7550,8 +7627,8 @@ static void append_id_part(FileData *fd, Main *mainvar, ID *id, ID **id_r)
 
 /* common routine to append/link something from a library */
 
-static Library* library_append( Scene *scene, SpaceFile *sfile, char *dir, int idcode,
-               int totsel, FileData *fd)
+static Library* library_append( Scene *scene, char* file, char *dir, int idcode,
+               int totsel, FileData *fd, struct direntry* filelist, int totfile, short flag)
 {
        Main *mainl;
        Library *curlib;
@@ -7567,13 +7644,13 @@ static Library* library_append( Scene *scene, SpaceFile *sfile, char *dir, int i
        curlib= mainl->curlib;
        
        if(totsel==0) {
-               append_named_part(fd, mainl, scene, sfile->file, idcode, sfile->flag);
+               append_named_part(fd, mainl, scene, file, idcode, flag);
        }
        else {
                int a;
-               for(a=0; a<sfile->totfile; a++) {
-                       if(sfile->filelist[a].flags & ACTIVE) {
-                               append_named_part(fd, mainl, scene, sfile->filelist[a].relname, idcode, sfile->flag);
+               for(a=0; a<totfile; a++) {
+                       if(filelist[a].flags & ACTIVE) {
+                               append_named_part(fd, mainl, scene, filelist[a].relname, idcode, flag);
                        }
                }
        }
@@ -7584,7 +7661,7 @@ static Library* library_append( Scene *scene, SpaceFile *sfile, char *dir, int i
        /* do this when expand found other libs */
        read_libraries(fd, &fd->mainlist);
 
-       if(sfile->flag & FILE_STRINGCODE) {
+       if(flag & FILE_STRINGCODE) {
 
                /* use the full path, this could have been read by other library even */
                BLI_strncpy(mainl->curlib->name, mainl->curlib->filename, sizeof(mainl->curlib->name));
@@ -7601,7 +7678,7 @@ static Library* library_append( Scene *scene, SpaceFile *sfile, char *dir, int i
 
        /* give a base to loose objects. If group append, do it for objects too */
        if(idcode==ID_GR)
-               give_base_to_objects(scene, &(G.main->object), (sfile->flag & FILE_LINK)?NULL:curlib);
+               give_base_to_objects(scene, &(G.main->object), (flag & FILE_LINK)?NULL:curlib);
        else
                give_base_to_objects(scene, &(G.main->object), NULL);
        
@@ -7612,8 +7689,7 @@ static Library* library_append( Scene *scene, SpaceFile *sfile, char *dir, int i
        /* patch to prevent switch_endian happens twice */
        if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
                blo_freefiledata( fd );
-               sfile->libfiledata= 0;
-       }
+       }       
 
        return curlib;
 }
@@ -7626,16 +7702,8 @@ static Library* library_append( Scene *scene, SpaceFile *sfile, char *dir, int i
 void BLO_script_library_append(BlendHandle *bh, char *dir, char *name, 
                int idcode, short flag, Scene *scene )
 {
-       SpaceFile sfile;
-
-       /* build a minimal "fake" SpaceFile object */
-       sfile.flag = flag;
-       sfile.totfile = 0;
-       strcpy(sfile.file, name);
-
        /* try to append the requested object */
-
-       library_append( scene, &sfile, dir, idcode, 0, (FileData *)bh );
+       library_append( scene, name, dir, idcode, 0, (FileData *)bh, NULL, 0, flag );
 
        /* do we need to do this? */
        DAG_scene_sort(G.scene);
@@ -7645,26 +7713,31 @@ void BLO_script_library_append(BlendHandle *bh, char *dir, char *name,
 /* dir is a full path */       
 void BLO_library_append(SpaceFile *sfile, char *dir, int idcode)
 {
-       FileData *fd= (FileData*) sfile->libfiledata;
+       BLO_library_append_(&sfile->libfiledata, sfile->filelist, sfile->totfile, dir, sfile->file, sfile->flag, idcode);
+}
+
+void BLO_library_append_(BlendHandle** libfiledata, struct direntry* filelist, int totfile, char *dir, char* file, short flag, int idcode)
+{
+       FileData *fd= (FileData*) (*libfiledata);
        Library *curlib;
        Base *centerbase;
        Object *ob;
        int a, totsel=0;
        
        /* are there files selected? */
-       for(a=0; a<sfile->totfile; a++) {
-               if(sfile->filelist[a].flags & ACTIVE) {
+       for(a=0; a<totfile; a++) {
+               if(filelist[a].flags & ACTIVE) {
                        totsel++;
                }
        }
 
        if(totsel==0) {
                /* is the indicated file in the filelist? */
-               if(sfile->file[0]) {
-                       for(a=0; a<sfile->totfile; a++) {
-                               if( strcmp(sfile->filelist[a].relname, sfile->file)==0) break;
+               if(file[0]) {
+                       for(a=0; a<totfile; a++) {
+                               if( strcmp(filelist[a].relname, file)==0) break;
                        }
-                       if(a==sfile->totfile) {
+                       if(a==totfile) {
                                error("Wrong indicated name");
                                return;
                        }
@@ -7676,13 +7749,18 @@ void BLO_library_append(SpaceFile *sfile, char *dir, int idcode)
        }
        /* now we have or selected, or an indicated file */
        
-       if(sfile->flag & FILE_AUTOSELECT) scene_deselect_all(G.scene);
+       if(flag & FILE_AUTOSELECT) scene_deselect_all(G.scene);
+
+       curlib = library_append( G.scene, file, dir, idcode, totsel, fd, filelist, totfile,flag );
 
-       curlib = library_append( G.scene, sfile, dir, idcode, totsel, fd );
+       /* patch to prevent switch_endian happens twice */
+       if(fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
+               (*libfiledata)= 0;
+       }       
 
        /* when not linking (appending)... */
-       if((sfile->flag & FILE_LINK)==0) {
-               if(sfile->flag & FILE_ATCURSOR) {
+       if((flag & FILE_LINK)==0) {
+               if(flag & FILE_ATCURSOR) {
                        float *curs, centerloc[3], vec[3], min[3], max[3];
                        int count= 0;
                        
index ee914954b90a584e3b01a346c13b215c1d2af34e..90873efb5b9714e3a208fb86f1532931d3cd6ca1 100644 (file)
@@ -1222,6 +1222,31 @@ static void write_lattices(WriteData *wd, ListBase *idbase)
        }
 }
 
+static void write_previews(WriteData *wd, PreviewImage *prv)
+{
+       if (prv) {
+               short w = prv->w[1];
+               short h = prv->h[1];
+               unsigned int *rect = prv->rect[1];
+               /* don't write out large previews if not requested */
+               if (!(U.flag & USER_SAVE_PREVIEWS) ) {
+                       prv->w[1] = 0;
+                       prv->h[1] = 0;
+                       prv->rect[1] = NULL;
+               }
+               writestruct(wd, DATA, "PreviewImage", 1, prv);
+               if (prv->rect[0]) writedata(wd, DATA, prv->w[0]*prv->h[0]*sizeof(unsigned int), prv->rect[0]);
+               if (prv->rect[1]) writedata(wd, DATA, prv->w[1]*prv->h[1]*sizeof(unsigned int), prv->rect[1]);
+
+               /* restore preview, we still want to keep it in memory even if not saved to file */
+               if (!(U.flag & USER_SAVE_PREVIEWS) ) {
+                       prv->w[1] = w;
+                       prv->h[1] = h;
+                       prv->rect[1] = rect;
+               }
+       }
+}
+
 static void write_images(WriteData *wd, ListBase *idbase)
 {
        Image *ima;
@@ -1241,12 +1266,9 @@ static void write_images(WriteData *wd, ListBase *idbase)
                                writedata(wd, DATA, pf->size, pf->data);
                        }
 
-                       if (ima->preview) {
-                               PreviewImage *prv = ima->preview;
-                               writestruct(wd, DATA, "PreviewImage", 1, prv);
-                               writedata(wd, DATA, prv->w*prv->h*sizeof(unsigned int), prv->rect);
+                       write_previews(wd, ima->preview);
+
                        }
-               }
                ima= ima->id.next;
        }
        /* flush helps the compression for undo-save */
@@ -1268,6 +1290,8 @@ static void write_textures(WriteData *wd, ListBase *idbase)
                        if(tex->plugin) writestruct(wd, DATA, "PluginTex", 1, tex->plugin);
                        if(tex->coba) writestruct(wd, DATA, "ColorBand", 1, tex->coba);
                        if(tex->env) writestruct(wd, DATA, "EnvMap", 1, tex->env);
+                       
+                       write_previews(wd, tex->preview);
                }
                tex= tex->id.next;
        }
@@ -1307,6 +1331,8 @@ static void write_materials(WriteData *wd, ListBase *idbase)
                                writestruct(wd, DATA, "bNodeTree", 1, ma->nodetree);
                                write_nodetree(wd, ma->nodetree);
                        }
+
+                       write_previews(wd, ma->preview);                        
                }
                ma= ma->id.next;
        }
@@ -1329,6 +1355,9 @@ static void write_worlds(WriteData *wd, ListBase *idbase)
                        }
 
                        write_scriptlink(wd, &wrld->scriptlink);
+
+                       write_previews(wd, wrld->preview);
+
                }
                wrld= wrld->id.next;
        }
@@ -1352,6 +1381,9 @@ static void write_lamps(WriteData *wd, ListBase *idbase)
                        }
 
                        write_scriptlink(wd, &la->scriptlink);
+
+                       write_previews(wd, la->preview);
+
                }
                la= la->id.next;
        }
index 840d39ea0bdf30fae0aa343e75ae36c63628d97a..3e8aaea4f3cfc8a1af09522b717dbc4d6e0a9c49 100644 (file)
@@ -277,6 +277,13 @@ int IMB_anim_get_preseek(struct anim * anim);
 
 struct ImBuf * IMB_anim_absolute(struct anim * anim, int position);
 
+/**
+ *
+ * @attention Defined in anim.c
+ * fetches a define previewframe, usually half way into the movie
+ */
+struct ImBuf * IMB_anim_previewframe(struct anim * anim);
+
 /**
  *
  * @attention Defined in anim.c
index d43b78df0b6d6bb4c404b58b8cfed12980c3306f..91ffa188fcc707e4ccf7a468958112d3ec3dd55f 100644 (file)
@@ -56,6 +56,8 @@
 struct _AviMovie;
 struct Mdec;
 
+struct ImgInfo;
+
 #define IB_MIPMAP_LEVELS       10
 
 /**
@@ -103,6 +105,7 @@ typedef struct ImBuf {
        float dither;                   /**< random dither value, for conversion from float -> byte rect */
        
        struct MEM_CacheLimiterHandle_s * c_handle; /**< handle for cache limiter */
+       struct ImgInfo * img_info;
        int refcounter;                 /**< Refcounter for multiple users */
        int index;                              /**< reference index for ImBuf lists */
        
@@ -148,6 +151,7 @@ typedef enum {
 #define IB_rectfloat   (1 << 15)
 #define IB_zbuffloat   (1 << 16)
 #define IB_multilayer  (1 << 17)
+#define IB_imginfo             (1 << 18)
 
 /*
  * The bit flag is stored in the ImBuf.ftype variable.
diff --git a/source/blender/imbuf/IMB_thumbs.h b/source/blender/imbuf/IMB_thumbs.h
new file mode 100644 (file)
index 0000000..22565da
--- /dev/null
@@ -0,0 +1,73 @@
+/**
+ * $Id: $ 
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. 
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Andrea Weikert.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef _IMB_THUMBS_H
+#define _IMB_THUMBS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ImBuf;
+
+/** Thumbnail creation and retrieval according to the 'Thumbnail Management Standard'
+ * supported by Gimp, Gnome (Nautilus), KDE etc.
+ * Reference: http://jens.triq.net/thumbnail-spec/index.html
+ */
+
+
+typedef enum ThumbSize {
+       THB_NORMAL,
+       THB_LARGE,
+       THB_FAIL
+} ThumbSize;
+
+typedef enum ThumbSource {
+       THB_SOURCE_IMAGE,
+       THB_SOURCE_MOVIE
+} ThumbSource;
+
+// IB_imginfo
+
+/* create thumbnail for file and returns new imbuf for thumbnail */
+ImBuf* IMB_thumb_create(const char* dir, const char* file, ThumbSize size, ThumbSource source);
+
+/* read thumbnail for file and returns new imbuf for thumbnail */
+ImBuf* IMB_thumb_read(const char* dir, const char* file, ThumbSize size);
+
+/* delete all thumbs for the file */
+void IMB_thumb_delete(const char* dir, const char* file, ThumbSize size);
+
+/* return the state of the thumb, needed to determine how to manage the thumb */
+ImBuf* IMB_thumb_manage(const char* dir, const char* file, ThumbSize size, ThumbSource source);
+
+
+
+
+#endif /* _IMB_THUMBS_H */
diff --git a/source/blender/imbuf/intern/IMB_imginfo.h b/source/blender/imbuf/intern/IMB_imginfo.h
new file mode 100644 (file)
index 0000000..91073ec
--- /dev/null
@@ -0,0 +1,78 @@
+/**
+ * $Id: $ 
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. 
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Austin Benesh. Ton Roosendaal.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef _IMB_IMGINFO_H
+#define _IMB_IMGINFO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ImBuf;
+
+typedef struct ImgInfo {
+       struct ImgInfo *next, *prev;
+       char* key;
+       char* value;
+       int len;
+} ImgInfo;
+
+/** The imginfo is a list of key/value pairs (both char*) that can me 
+    saved in the header of several image formats.
+       Apart from some common keys like 
+       'Software' and 'Description' (png standard) we'll use keys within the 
+       Blender namespace, so should be called 'Blender::StampInfo' or 'Blender::FrameNum'
+       etc... 
+*/
+
+
+/* free blender ImgInfo struct */
+void IMB_imginfo_free(struct ImBuf* img);
+
+/** read the field from the image info into the field 
+ *  @param img - the ImBuf that contains the image data
+ *  @param key - the key of the field
+ *  @param value - the data in the field, first one found with key is returned, 
+                  memory has to be allocated by user.
+ *  @param len - length of value buffer allocated by user.
+ *  @return    - 1 (true) if ImageInfo present and value for the key found, 0 (false) otherwise
+ */
+int IMB_imginfo_get_field(struct ImBuf* img, const char* key, char* value, int len);
+
+/** set user data in the ImgInfo struct, which has to be allocated with IMB_imginfo_create
+ *  before calling this function.
+ *  @param img - the ImBuf that contains the image data
+ *  @param key - the key of the field
+ *  @param value - the data to be written to the field. zero terminated string
+ *  @return    - 1 (true) if ImageInfo present, 0 (false) otherwise
+ */
+int IMB_imginfo_add_field(struct ImBuf* img, const char* key, const char* field);
+
+
+#endif /* _IMB_IMGINFO_H */
index 003d377389bfd43e0f591e2e297c32e2a5b12854..a5d404740cf5da4d9a6ede491f2a14a991db0484 100644 (file)
@@ -43,6 +43,7 @@
 
 #include "IMB_divers.h"
 #include "IMB_allocimbuf.h"
+#include "IMB_imginfo.h"
 #include "MEM_CacheLimiterC-Api.h"
 
 static unsigned int dfltcmap[16] = {
@@ -163,6 +164,7 @@ void IMB_freeImBuf(struct ImBuf * ibuf)
                        IMB_freecmapImBuf(ibuf);
                        freeencodedbufferImBuf(ibuf);
                        IMB_cache_limiter_unmanage(ibuf);
+                       IMB_imginfo_free(ibuf);
                        MEM_freeN(ibuf);
                }
        }
@@ -476,6 +478,9 @@ struct ImBuf *IMB_dupImBuf(struct ImBuf *ibuf1)
        tbuf.mall               = ibuf2->mall;
        tbuf.c_handle           = 0;
 
+       // for now don't duplicate image info
+       tbuf.img_info = 0;
+
        *ibuf2 = tbuf;
        
        if (ibuf1->cmap){
index a1ef735ffdb25f640fa84d1f8e477bf8f82c05a4..24ea79ee90d88e80650c52bd94046a4ff57bc386 100644 (file)
@@ -819,6 +819,18 @@ static struct ImBuf * anim_getnew(struct anim * anim) {
        return(ibuf);
 }
 
+struct ImBuf * IMB_anim_previewframe(struct anim * anim) {
+       struct ImBuf * ibuf = 0;
+       int position = 0;
+       
+       ibuf = IMB_anim_absolute(anim, 0);
+       if (ibuf) {
+               IMB_freeImBuf(ibuf);
+               position = anim->duration / 2;
+               ibuf = IMB_anim_absolute(anim, position);
+       }
+       return ibuf;
+}
 
 struct ImBuf * IMB_anim_absolute(struct anim * anim, int position) {
        struct ImBuf * ibuf = 0;
diff --git a/source/blender/imbuf/intern/imginfo.c b/source/blender/imbuf/intern/imginfo.c
new file mode 100644 (file)
index 0000000..c443b1b
--- /dev/null
@@ -0,0 +1,108 @@
+/**
+ * $Id: $ 
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. 
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Austin Benesh. Ton Roosendaal.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "BLI_blenlib.h"
+#include "MEM_guardedalloc.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+
+#include "IMB_imginfo.h"
+
+
+
+void IMB_imginfo_free(struct ImBuf* img)
+{
+       ImgInfo *info;
+
+       if (!img)
+               return;
+       if (!img->img_info) {
+               return;
+       }
+       info = img->img_info;
+       while (info) {
+               ImgInfo* next = info->next;
+               MEM_freeN(info->key);
+               MEM_freeN(info->value);
+               MEM_freeN(info);
+               info = next;
+       }
+}
+
+int IMB_imginfo_get_field(struct ImBuf* img, const char* key, char* field, int len)
+{
+       ImgInfo *info;
+       int retval = 0;
+
+       if (!img)
+               return 0;
+       if (!img->img_info) {
+               return 0;
+       }
+       info = img->img_info;
+       while (info) {
+               if (strcmp(key, info->key) == 0) {
+                       BLI_strncpy(field, info->value, len);
+                       retval = 1;
+                       break;
+               }
+               info = info->next;
+       }
+       return retval;
+}
+
+int IMB_imginfo_add_field(struct ImBuf* img, const char* key, const char* field)
+{
+       ImgInfo *info;
+       ImgInfo *last;
+
+       if (!img)
+               return 0;
+
+       if (!img->img_info) {
+               img->img_info = MEM_callocN(sizeof(ImgInfo), "ImgInfo");
+               info = img->img_info;
+       } else {
+               info = img->img_info;
+               last = info;
+               while (info) {
+                       last = info;
+                       info = info->next;
+               }
+               info = MEM_callocN(sizeof(ImgInfo), "ImgInfo");
+               last->next = info;
+       }
+       info->key = BLI_strdup(key);
+       info->value = BLI_strdup(field);
+       return 1;
+}
diff --git a/source/blender/imbuf/intern/md5.c b/source/blender/imbuf/intern/md5.c
new file mode 100644 (file)
index 0000000..3119dd1
--- /dev/null
@@ -0,0 +1,360 @@
+/* md5.c - Functions to compute MD5 message digest of files or memory blocks
+   according to the definition of MD5 in RFC 1321 from April 1992.
+   Copyright (C) 1995 Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+
+# include <stdlib.h>
+# include <string.h>
+
+#include "md5.h"
+
+#ifdef WORDS_BIGENDIAN
+# define SWAP(n)                                                       \
+    (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
+#else
+# define SWAP(n) (n)
+#endif
+
+
+/* This array contains the bytes used to pad the buffer to the next
+   64-byte boundary.  (RFC 1321, 3.1: Step 1)  */
+static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ...  */ };
+
+
+/* Initialize structure containing state of computation.
+   (RFC 1321, 3.3: Step 3)  */
+void
+md5_init_ctx (ctx)
+     struct md5_ctx *ctx;
+{
+  ctx->A = 0x67452301;
+  ctx->B = 0xefcdab89;
+  ctx->C = 0x98badcfe;
+  ctx->D = 0x10325476;
+}
+
+/* Put result from CTX in first 16 bytes following RESBUF.  The result must
+   be in little endian byte order.  */
+void *
+md5_read_ctx (ctx, resbuf)
+     const struct md5_ctx *ctx;
+     void *resbuf;
+{
+  ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A);
+  ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B);
+  ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C);
+  ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D);
+
+  return resbuf;
+}
+
+/* Compute MD5 message digest for bytes read from STREAM.  The
+   resulting message digest number will be written into the 16 bytes
+   beginning at RESBLOCK.  */
+int
+md5_stream (stream, resblock)
+     FILE *stream;
+     void *resblock;
+{
+  /* Important: BLOCKSIZE must be a multiple of 64.  */
+#define BLOCKSIZE 4096
+  struct md5_ctx ctx;
+  md5_uint32 len[2];
+  char buffer[BLOCKSIZE + 72];
+  size_t pad, sum;
+
+  /* Initialize the computation context.  */
+  md5_init_ctx (&ctx);
+
+  len[0] = 0;
+  len[1] = 0;
+
+  /* Iterate over full file contents.  */
+  while (1)
+    {
+      /* We read the file in blocks of BLOCKSIZE bytes.  One call of the
+        computation function processes the whole buffer so that with the
+        next round of the loop another block can be read.  */
+      size_t n;
+      sum = 0;
+
+      /* Read block.  Take care for partial reads.  */
+      do
+       {
+         n = fread (buffer, 1, BLOCKSIZE - sum, stream);
+
+         sum += n;
+       }
+      while (sum < BLOCKSIZE && n != 0);
+      if (n == 0 && ferror (stream))
+        return 1;
+
+      /* RFC 1321 specifies the possible length of the file up to 2^64 bits.
+        Here we only compute the number of bytes.  Do a double word
+         increment.  */
+      len[0] += sum;
+      if (len[0] < sum)
+       ++len[1];
+
+      /* If end of file is reached, end the loop.  */
+      if (n == 0)
+       break;
+
+      /* Process buffer with BLOCKSIZE bytes.  Note that
+                       BLOCKSIZE % 64 == 0
+       */
+      md5_process_block (buffer, BLOCKSIZE, &ctx);
+    }
+
+  /* We can copy 64 byte because the buffer is always big enough.  FILLBUF
+     contains the needed bits.  */
+  memcpy (&buffer[sum], fillbuf, 64);
+
+  /* Compute amount of padding bytes needed.  Alignment is done to
+               (N + PAD) % 64 == 56
+     There is always at least one byte padded.  I.e. even the alignment
+     is correctly aligned 64 padding bytes are added.  */
+  pad = sum & 63;
+  pad = pad >= 56 ? 64 + 56 - pad : 56 - pad;
+
+  /* Put the 64-bit file length in *bits* at the end of the buffer.  */
+  *(md5_uint32 *) &buffer[sum + pad] = SWAP (len[0] << 3);
+  *(md5_uint32 *) &buffer[sum + pad + 4] = SWAP ((len[1] << 3)
+                                                | (len[0] >> 29));
+
+  /* Process last bytes.  */
+  md5_process_block (buffer, sum + pad + 8, &ctx);
+
+  /* Construct result in desired memory.  */
+  md5_read_ctx (&ctx, resblock);
+  return 0;
+}
+
+/* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
+   result is always in little endian byte order, so that a byte-wise
+   output yields to the wanted ASCII representation of the message
+   digest.  */
+void *
+md5_buffer (buffer, len, resblock)
+     const char *buffer;
+     size_t len;
+     void *resblock;
+{
+  struct md5_ctx ctx;
+  char restbuf[64 + 72];
+  size_t blocks = len & ~63;
+  size_t pad, rest;
+
+  /* Initialize the computation context.  */
+  md5_init_ctx (&ctx);
+
+  /* Process whole buffer but last len % 64 bytes.  */
+  md5_process_block (buffer, blocks, &ctx);
+
+  /* REST bytes are not processed yet.  */
+  rest = len - blocks;
+  /* Copy to own buffer.  */
+  memcpy (restbuf, &buffer[blocks], rest);
+  /* Append needed fill bytes at end of buffer.  We can copy 64 byte
+     because the buffer is always big enough.  */
+  memcpy (&restbuf[rest], fillbuf, 64);
+
+  /* PAD bytes are used for padding to correct alignment.  Note that
+     always at least one byte is padded.  */
+  pad = rest >= 56 ? 64 + 56 - rest : 56 - rest;
+
+  /* Put length of buffer in *bits* in last eight bytes.  */
+  *(md5_uint32 *) &restbuf[rest + pad] = (md5_uint32) SWAP (len << 3);
+  *(md5_uint32 *) &restbuf[rest + pad + 4] = (md5_uint32) SWAP (len >> 29);
+
+  /* Process last bytes.  */
+  md5_process_block (restbuf, rest + pad + 8, &ctx);
+
+  /* Put result in desired memory area.  */
+  return md5_read_ctx (&ctx, resblock);
+}
+
+
+/* These are the four functions used in the four steps of the MD5 algorithm
+   and defined in the RFC 1321.  The first function is a little bit optimized
+   (as found in Colin Plumbs public domain implementation).  */
+/* #define FF(b, c, d) ((b & c) | (~b & d)) */
+#define FF(b, c, d) (d ^ (b & (c ^ d)))
+#define FG(b, c, d) FF (d, b, c)
+#define FH(b, c, d) (b ^ c ^ d)
+#define FI(b, c, d) (c ^ (b | ~d))
+
+/* Process LEN bytes of BUFFER, accumulating context into CTX.
+   It is assumed that LEN % 64 == 0.  */
+
+void
+md5_process_block (buffer, len, ctx)
+     const void *buffer;
+     size_t len;
+     struct md5_ctx *ctx;
+{
+  md5_uint32 correct_words[16];
+  const md5_uint32 *words = buffer;
+  size_t nwords = len / sizeof (md5_uint32);
+  const md5_uint32 *endp = words + nwords;
+  md5_uint32 A = ctx->A;
+  md5_uint32 B = ctx->B;
+  md5_uint32 C = ctx->C;
+  md5_uint32 D = ctx->D;
+
+  /* Process all bytes in the buffer with 64 bytes in each round of
+     the loop.  */
+  while (words < endp)
+    {
+      md5_uint32 *cwp = correct_words;
+      md5_uint32 A_save = A;
+      md5_uint32 B_save = B;
+      md5_uint32 C_save = C;
+      md5_uint32 D_save = D;
+
+      /* First round: using the given function, the context and a constant
+        the next context is computed.  Because the algorithms processing
+        unit is a 32-bit word and it is determined to work on words in
+        little endian byte order we perhaps have to change the byte order
+        before the computation.  To reduce the work for the next steps
+        we store the swapped words in the array CORRECT_WORDS.  */
+
+#define OP(a, b, c, d, s, T)                                           \
+      do                                                               \
+        {                                                              \
+         a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T;             \
+         ++words;                                                      \
+         CYCLIC (a, s);                                                \
+         a += b;                                                       \
+        }                                                              \
+      while (0)
+
+      /* It is unfortunate that C does not provide an operator for
+        cyclic rotation.  Hope the C compiler is smart enough.  */
+#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s)))
+
+      /* Before we start, one word to the strange constants.
+        They are defined in RFC 1321 as
+
+        T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64
+       */
+
+      /* Round 1.  */
+      OP (A, B, C, D,  7, 0xd76aa478);
+      OP (D, A, B, C, 12, 0xe8c7b756);
+      OP (C, D, A, B, 17, 0x242070db);
+      OP (B, C, D, A, 22, 0xc1bdceee);
+      OP (A, B, C, D,  7, 0xf57c0faf);
+      OP (D, A, B, C, 12, 0x4787c62a);
+      OP (C, D, A, B, 17, 0xa8304613);
+      OP (B, C, D, A, 22, 0xfd469501);
+      OP (A, B, C, D,  7, 0x698098d8);
+      OP (D, A, B, C, 12, 0x8b44f7af);
+      OP (C, D, A, B, 17, 0xffff5bb1);
+      OP (B, C, D, A, 22, 0x895cd7be);
+      OP (A, B, C, D,  7, 0x6b901122);
+      OP (D, A, B, C, 12, 0xfd987193);
+      OP (C, D, A, B, 17, 0xa679438e);
+      OP (B, C, D, A, 22, 0x49b40821);
+
+      /* For the second to fourth round we have the possibly swapped words
+        in CORRECT_WORDS.  Redefine the macro to take an additional first
+        argument specifying the function to use.  */
+#undef OP
+#define OP(f, a, b, c, d, k, s, T)                                     \
+      do                                                               \
+       {                                                               \
+         a += f (b, c, d) + correct_words[k] + T;                      \
+         CYCLIC (a, s);                                                \
+         a += b;                                                       \
+       }                                                               \
+      while (0)
+
+      /* Round 2.  */
+      OP (FG, A, B, C, D,  1,  5, 0xf61e2562);
+      OP (FG, D, A, B, C,  6,  9, 0xc040b340);
+      OP (FG, C, D, A, B, 11, 14, 0x265e5a51);
+      OP (FG, B, C, D, A,  0, 20, 0xe9b6c7aa);
+      OP (FG, A, B, C, D,  5,  5, 0xd62f105d);
+      OP (FG, D, A, B, C, 10,  9, 0x02441453);
+      OP (FG, C, D, A, B, 15, 14, 0xd8a1e681);
+      OP (FG, B, C, D, A,  4, 20, 0xe7d3fbc8);
+      OP (FG, A, B, C, D,  9,  5, 0x21e1cde6);
+      OP (FG, D, A, B, C, 14,  9, 0xc33707d6);
+      OP (FG, C, D, A, B,  3, 14, 0xf4d50d87);
+      OP (FG, B, C, D, A,  8, 20, 0x455a14ed);
+      OP (FG, A, B, C, D, 13,  5, 0xa9e3e905);
+      OP (FG, D, A, B, C,  2,  9, 0xfcefa3f8);
+      OP (FG, C, D, A, B,  7, 14, 0x676f02d9);
+      OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a);
+
+      /* Round 3.  */
+      OP (FH, A, B, C, D,  5,  4, 0xfffa3942);
+      OP (FH, D, A, B, C,  8, 11, 0x8771f681);
+      OP (FH, C, D, A, B, 11, 16, 0x6d9d6122);
+      OP (FH, B, C, D, A, 14, 23, 0xfde5380c);
+      OP (FH, A, B, C, D,  1,  4, 0xa4beea44);
+      OP (FH, D, A, B, C,  4, 11, 0x4bdecfa9);
+      OP (FH, C, D, A, B,  7, 16, 0xf6bb4b60);
+      OP (FH, B, C, D, A, 10, 23, 0xbebfbc70);
+      OP (FH, A, B, C, D, 13,  4, 0x289b7ec6);
+      OP (FH, D, A, B, C,  0, 11, 0xeaa127fa);
+      OP (FH, C, D, A, B,  3, 16, 0xd4ef3085);
+      OP (FH, B, C, D, A,  6, 23, 0x04881d05);
+      OP (FH, A, B, C, D,  9,  4, 0xd9d4d039);
+      OP (FH, D, A, B, C, 12, 11, 0xe6db99e5);
+      OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8);
+      OP (FH, B, C, D, A,  2, 23, 0xc4ac5665);
+
+      /* Round 4.  */
+      OP (FI, A, B, C, D,  0,  6, 0xf4292244);
+      OP (FI, D, A, B, C,  7, 10, 0x432aff97);
+      OP (FI, C, D, A, B, 14, 15, 0xab9423a7);
+      OP (FI, B, C, D, A,  5, 21, 0xfc93a039);
+      OP (FI, A, B, C, D, 12,  6, 0x655b59c3);
+      OP (FI, D, A, B, C,  3, 10, 0x8f0ccc92);
+      OP (FI, C, D, A, B, 10, 15, 0xffeff47d);
+      OP (FI, B, C, D, A,  1, 21, 0x85845dd1);
+      OP (FI, A, B, C, D,  8,  6, 0x6fa87e4f);
+      OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0);
+      OP (FI, C, D, A, B,  6, 15, 0xa3014314);
+      OP (FI, B, C, D, A, 13, 21, 0x4e0811a1);
+      OP (FI, A, B, C, D,  4,  6, 0xf7537e82);
+      OP (FI, D, A, B, C, 11, 10, 0xbd3af235);
+      OP (FI, C, D, A, B,  2, 15, 0x2ad7d2bb);
+      OP (FI, B, C, D, A,  9, 21, 0xeb86d391);
+
+      /* Add the starting values of the context.  */
+      A += A_save;
+      B += B_save;
+      C += C_save;
+      D += D_save;
+    }
+
+  /* Put checksum in context given as argument.  */
+  ctx->A = A;
+  ctx->B = B;
+  ctx->C = C;
+  ctx->D = D;
+}
diff --git a/source/blender/imbuf/intern/md5.h b/source/blender/imbuf/intern/md5.h
new file mode 100644 (file)
index 0000000..ed38c19
--- /dev/null
@@ -0,0 +1,115 @@
+/* md5.h - Declaration of functions and data types used for MD5 sum
+   computing library functions.
+   Copyright (C) 1995 Free Software Foundation, Inc.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#ifndef _MD5_H
+#define _MD5_H
+
+#include <stdio.h>
+
+#if defined HAVE_LIMITS_H || _LIBC
+# include <limits.h>
+#endif
+
+/* The following contortions are an attempt to use the C preprocessor
+   to determine an unsigned integral type that is 32 bits wide.  An
+   alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but
+   doing that would require that the configure script compile and *run*
+   the resulting executable.  Locally running cross-compiled executables
+   is usually not possible.  */
+
+#if defined __STDC__ && __STDC__
+# define UINT_MAX_32_BITS 4294967295U
+#else
+# define UINT_MAX_32_BITS 0xFFFFFFFF
+#endif
+
+/* If UINT_MAX isn't defined, assume it's a 32-bit type.
+   This should be valid for all systems GNU cares about because
+   that doesn't include 16-bit systems, and only modern systems
+   (that certainly have <limits.h>) have 64+-bit integral types.  */
+
+#ifndef UINT_MAX
+# define UINT_MAX UINT_MAX_32_BITS
+#endif
+
+#if UINT_MAX == UINT_MAX_32_BITS
+  typedef unsigned int md5_uint32;
+#else
+# if USHRT_MAX == UINT_MAX_32_BITS
+   typedef unsigned short md5_uint32;
+# else
+#  if ULONG_MAX == UINT_MAX_32_BITS
+    typedef unsigned long md5_uint32;
+#  else
+    /* The following line is intended to evoke an error.
+       Using #error is not portable enough.  */
+    "Cannot determine unsigned 32-bit data type."
+#  endif
+# endif
+#endif
+
+#undef __P
+#if defined (__STDC__) && __STDC__
+#define        __P(x) x
+#else
+#define        __P(x) ()
+#endif
+
+/* Structure to save state of computation between the single steps.  */
+struct md5_ctx
+{
+  md5_uint32 A;
+  md5_uint32 B;
+  md5_uint32 C;
+  md5_uint32 D;
+};
+
+/*
+ * The following three functions are build up the low level used in
+ * the functions `md5_stream' and `md5_buffer'.
+ */
+
+/* Initialize structure containing state of computation.
+   (RFC 1321, 3.3: Step 3)  */
+void md5_init_ctx __P ((struct md5_ctx *ctx));
+
+/* Starting with the result of former calls of this function (or the
+   initialzation function update the context for the next LEN bytes
+   starting at BUFFER.
+   It is necessary that LEN is a multiple of 64!!! */
+void md5_process_block __P ((const void *buffer, size_t len,
+                            struct md5_ctx *ctx));
+
+/* Put result from CTX in first 16 bytes following RESBUF.  The result is
+   always in little endian byte order, so that a byte-wise output yields
+   to the wanted ASCII representation of the message digest.  */
+void *md5_read_ctx __P ((const struct md5_ctx *ctx, void *resbuf));
+
+
+/* Compute MD5 message digest for bytes read from STREAM.  The
+   resulting message digest number will be written into the 16 bytes
+   beginning at RESBLOCK.  */
+int md5_stream __P ((FILE *stream, void *resblock));
+
+/* Compute MD5 message digest for LEN bytes beginning at BUFFER.  The
+   result is always in little endian byte order, so that a byte-wise
+   output yields to the wanted ASCII representation of the message
+   digest.  */
+void *md5_buffer __P ((const char *buffer, size_t len, void *resblock));
+
+#endif
index 46c5232a61a34f9c642c05148005af3a2354e706..bb48ff71bff6cadf9ad59ea973e90505db2243ab 100644 (file)
@@ -43,6 +43,7 @@
 
 #include "IMB_allocimbuf.h"
 #include "IMB_cmap.h"
+#include "IMB_imginfo.h"
 #include "IMB_png.h"
 
 typedef struct PNGReadStruct {
@@ -100,6 +101,7 @@ short imb_savepng(struct ImBuf *ibuf, char *name, int flags)
 {
        png_structp png_ptr;
        png_infop info_ptr;
+
        unsigned char *pixels = 0;
        unsigned char *from, *to;
        png_bytepp row_pointers = 0;
@@ -219,6 +221,33 @@ short imb_savepng(struct ImBuf *ibuf, char *name, int flags)
                 PNG_COMPRESSION_TYPE_DEFAULT,
                 PNG_FILTER_TYPE_DEFAULT);
 
+       /* image text info */
+       if (ibuf->img_info) {
+               png_text*  imginfo;
+               ImgInfo* iptr;
+               int  num_text = 0;
+               iptr = ibuf->img_info;
+               while (iptr) {
+                       num_text++;
+                       iptr = iptr->next;
+               }
+               
+               imginfo = MEM_callocN(num_text*sizeof(png_text), "png_imginfo");
+               iptr = ibuf->img_info;
+               num_text = 0;
+               while (iptr) {
+                       imginfo[num_text].compression = PNG_TEXT_COMPRESSION_NONE;
+                       imginfo[num_text].key = iptr->key;
+                       imginfo[num_text].text = iptr->value;
+                       num_text++;
+                       iptr = iptr->next;
+               }
+               
+               png_set_text(png_ptr, info_ptr, imginfo, num_text);
+               MEM_freeN(imginfo);
+
+       }
+
        // write the file header information
        png_write_info(png_ptr, info_ptr);
 
@@ -409,6 +438,15 @@ struct ImBuf *imb_loadpng(unsigned char *mem, int size, int flags)
                        break;
                }
 
+               if (flags & IB_imginfo) {
+                       png_text* text_chunks;
+                       int count = png_get_text(png_ptr, info_ptr, &text_chunks, NULL);
+                       for(i = 0; i < count; i++) {
+                               IMB_imginfo_add_field(ibuf, text_chunks[i].key, text_chunks[i].text);
+                               ibuf->flags |= IB_imginfo;                              
+                       }
+               }
+
                png_read_end(png_ptr, info_ptr);
        }
 
diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c
new file mode 100644 (file)
index 0000000..6976aff
--- /dev/null
@@ -0,0 +1,457 @@
+/**
+ * $Id: $ 
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. 
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 Blender Foundation
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): Andrea Weikert.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "BKE_global.h"
+#include "BKE_utildefines.h"
+#include "BLI_blenlib.h"
+#include "MEM_guardedalloc.h"
+
+#include "IMB_imbuf_types.h"
+#include "IMB_imbuf.h"
+#include "IMB_thumbs.h"
+#include "IMB_imginfo.h"
+
+
+#include "md5.h"
+
+#ifdef WIN32
+#include <windows.h> /* need to include windows.h so _WIN32_IE is defined  */
+#ifndef _WIN32_IE
+#define _WIN32_IE 0x0400 /* minimal requirements for SHGetSpecialFolderPath on MINGW MSVC has this defined already */
+#endif
+#include <shlobj.h> /* for SHGetSpecialFolderPath, has to be done before BLI_winstuff because 'near' is disabled through BLI_windstuff */
+#include "BLI_winstuff.h"
+#include <process.h> /* getpid */
+#else
+#include <unistd.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+
+#define URI_MAX FILE_MAX*3 + 8
+
+static int get_thumb_dir( char* dir , ThumbSize size)
+{
+       char* home;
+
+#ifdef WIN32
+       /* yes, applications shouldn't store data there, but so does GIMP :)*/
+       SHGetSpecialFolderPath(0, dir, CSIDL_PROFILE, 0);
+#else
+       home = getenv("HOME");
+       if (!home) return 0;
+       BLI_strncpy(dir, home, FILE_MAX);
+#endif
+       switch(size) {
+               case THB_NORMAL:
+                       strcat(dir, "/.thumbnails/normal");
+                       break;
+               case THB_LARGE:
+                       strcat(dir, "/.thumbnails/large");
+                       break;
+               case THB_FAIL:
+                       strcat(dir, "/.thumbnails/fail/blender");
+                       break;
+               default:
+                       return 0; /* unknown size */
+       }
+       BLI_cleanup_dir(G.sce, dir);
+       return 1;
+}
+
+/** ----- begin of adapted code from glib ---
+ * The following code is adapted from function g_escape_uri_string from the gnome glib
+ * Source: http://svn.gnome.org/viewcvs/glib/trunk/glib/gconvert.c?view=markup
+ * released under the Gnu General Public License.
+ */
+typedef enum {
+  UNSAFE_ALL        = 0x1,  /* Escape all unsafe characters   */
+  UNSAFE_ALLOW_PLUS = 0x2,  /* Allows '+'  */
+  UNSAFE_PATH       = 0x8,  /* Allows '/', '&', '=', ':', '@', '+', '$' and ',' */
+  UNSAFE_HOST       = 0x10, /* Allows '/' and ':' and '@' */
+  UNSAFE_SLASHES    = 0x20  /* Allows all characters except for '/' and '%' */
+} UnsafeCharacterSet;
+
+static const unsigned char acceptable[96] = {
+  /* A table of the ASCII chars from space (32) to DEL (127) */
+  /*      !    "    #    $    %    &    '    (    )    *    +    ,    -    .    / */ 
+  0x00,0x3F,0x20,0x20,0x28,0x00,0x2C,0x3F,0x3F,0x3F,0x3F,0x2A,0x28,0x3F,0x3F,0x1C,
+  /* 0    1    2    3    4    5    6    7    8    9    :    ;    <    =    >    ? */
+  0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x38,0x20,0x20,0x2C,0x20,0x20,
+  /* @    A    B    C    D    E    F    G    H    I    J    K    L    M    N    O */
+  0x38,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+  /* P    Q    R    S    T    U    V    W    X    Y    Z    [    \    ]    ^    _ */
+  0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x20,0x3F,
+  /* `    a    b    c    d    e    f    g    h    i    j    k    l    m    n    o */
+  0x20,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+  /* p    q    r    s    t    u    v    w    x    y    z    {    |    }    ~  DEL */
+  0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x3F,0x20
+};
+
+static const char hex[16] = "0123456789abcdef";
+
+/* Note: This escape function works on file: URIs, but if you want to
+ * escape something else, please read RFC-2396 */
+void escape_uri_string (const char *string, char* escaped_string, int len,UnsafeCharacterSet mask)
+{
+#define ACCEPTABLE(a) ((a)>=32 && (a)<128 && (acceptable[(a)-32] & use_mask))
+
+       const char *p;
+       char *q;
+       int c;
+       UnsafeCharacterSet use_mask;
+       use_mask = mask;
+
+       for (q = escaped_string, p = string; (*p != '\0') && len; p++) {
+               c = (unsigned char) *p;
+               len--;
+
+               if (!ACCEPTABLE (c)) {
+                       *q++ = '%'; /* means hex coming */
+                       *q++ = hex[c >> 4];
+                       *q++ = hex[c & 15];
+               } else {
+                       *q++ = *p;
+               }
+       }
+  
+       *q = '\0';
+}
+
+void to_hex_char(char* hexbytes, const unsigned char* bytes, int len)
+{
+       const unsigned char *p;
+       char *q;
+
+       for (q = hexbytes, p = bytes; len; p++) {
+               const unsigned char c = (unsigned char) *p;
+               len--;
+               *q++ = hex[c >> 4];
+               *q++ = hex[c & 15];
+       }
+}
+
+/** ----- end of adapted code from glib --- */
+
+static int uri_from_filename( const char *dir, const char *file, char *uri )
+{
+       char orig_uri[URI_MAX]; 
+       const char* dirstart = dir;
+       
+#ifdef WIN32
+       {
+               char vol[3];
+
+               BLI_strncpy(orig_uri, "file:///", FILE_MAX);
+               if (strlen(dir) < 2 && dir[1] != ':') {
+                       /* not a correct absolute path */
+                       return 0;
+               }
+               /* on windows, using always uppercase drive/volume letter in uri */
+               vol[0] = toupper(dir[0]);
+               vol[1] = ':';
+               vol[2] = '\0';
+               strcat(orig_uri, vol);
+               dirstart += 2;
+       }
+#else
+       BLI_strncpy(orig_uri, "file://", FILE_MAX);
+#endif
+       strcat(orig_uri, dirstart);
+       strcat(orig_uri, file);
+       BLI_char_switch(orig_uri, '\\', '/');
+       
+#ifdef WITH_ICONV
+       {
+               escape_uri_string(orig_uri, uri_utf8, FILE_MAX*3+8, UNSAFE_PATH);
+               BLI_string_to_utf8(uri_utf8, uri, NULL);
+               char uri_utf8[FILE_MAX*3+8];
+       }
+#else 
+       escape_uri_string(orig_uri, uri, FILE_MAX*3+8, UNSAFE_PATH);
+#endif
+       return 1;
+}
+
+static void thumbname_from_uri(const char* uri, char* thumb)
+{
+       char hexdigest[33];
+       unsigned char digest[16];
+
+       md5_buffer( uri, strlen(uri), digest);
+       hexdigest[0] = '\0';
+       to_hex_char(hexdigest, digest, 16);
+       hexdigest[32] = '\0';
+       sprintf(thumb, "%s.png", hexdigest);
+}
+
+static int thumbpath_from_uri(const char* uri, char* path, ThumbSize size)
+{
+       char tmppath[FILE_MAX];
+       int rv = 0;
+
+       if (get_thumb_dir(tmppath, size)) {
+               char thumb[40];
+               thumbname_from_uri(uri, thumb);
+               BLI_snprintf(path, FILE_MAX, "%s%s", tmppath, thumb);
+               rv = 1;
+       }
+       return rv;
+}
+
+
+/* create thumbnail for file and returns new imbuf for thumbnail */
+ImBuf* IMB_thumb_create(const char* dir, const char* file, ThumbSize size, ThumbSource source)
+{
+       ImBuf *img = 0;
+       char uri[URI_MAX];
+       char desc[URI_MAX+22];
+       char tpath[FILE_MAX];
+       char tdir[FILE_MAX];
+       char wdir[FILE_MAX];
+       char temp[FILE_MAX];
+       char mtime[40];
+       char cwidth[40];
+       char cheight[40];
+       char thumb[40];
+       short tsize = 128;
+       short ex, ey;
+       float scaledx, scaledy; 
+       struct stat info;
+
+       switch(size) {
+               case THB_NORMAL:
+                       tsize = 128;
+                       break;
+               case THB_LARGE:
+                       tsize = 256;
+                       break;
+               case THB_FAIL:
+                       tsize = 0;
+                       break;
+               default:
+                       return 0; /* unknown size */
+       }
+
+       uri_from_filename(dir, file,uri);
+       thumbname_from_uri(uri, thumb);
+       if (get_thumb_dir(tdir, size)) {
+               BLI_snprintf(tpath, FILE_MAX, "%s%s", tdir, thumb);
+               thumb[8] = '\0'; /* shorten for tempname, not needed anymore */
+               BLI_snprintf(temp, FILE_MAX, "%sblender_%d_%s.png", tdir, abs(getpid()), thumb);
+               if (strncmp(thumb, dir, strlen(dir)) == 0) {
+                       return NULL;
+               }
+               if (size == THB_FAIL) {
+                       img = IMB_allocImBuf(0,0,32, IB_rect | IB_imginfo, 0);
+                       if (!img) return 0;
+               } else {
+                       if (THB_SOURCE_IMAGE == source) {
+                               BLI_getwdN(wdir);
+                               chdir(dir);
+                               img = IMB_loadiffname(file, IB_rect);                           
+                               stat(file, &info);
+                               sprintf(mtime, "%ld", info.st_mtime);
+                               sprintf(cwidth, "%d", img->x);
+                               sprintf(cheight, "%d", img->y);
+                               chdir(wdir);
+                       } else if (THB_SOURCE_MOVIE == source) {
+                               struct anim * anim = NULL;
+                               BLI_getwdN(wdir);
+                               chdir(dir);
+                               anim = IMB_open_anim(file, IB_rect | IB_imginfo);
+                               if (anim != NULL) {
+                                       img = IMB_anim_absolute(anim, 0);
+                                       if (img == NULL) {
+                                               printf("not an anim; %s\n", file);
+                                       } else {
+                                               IMB_freeImBuf(img);
+                                               img = IMB_anim_previewframe(anim);                                              
+                                       }
+                                       IMB_free_anim(anim);
+                               }
+                               stat(file, &info);
+                               sprintf(mtime, "%ld", info.st_mtime);
+                               chdir(wdir);
+                       }
+                       if (!img) return 0;             
+
+                       if (img->x > img->y) {
+                               scaledx = (float)tsize;
+                               scaledy =  ( (float)img->y/(float)img->x )*tsize;
+                       }
+                       else {
+                               scaledy = (float)tsize;
+                               scaledx =  ( (float)img->x/(float)img->y )*tsize;
+                       }
+                       ex = (short)scaledx;
+                       ey = (short)scaledy;
+                       
+                       IMB_scaleImBuf(img, ex, ey);
+               }
+               sprintf(desc, "Thumbnail for %s", uri);
+               IMB_imginfo_add_field(img, "Description", desc);
+               IMB_imginfo_add_field(img, "Software", "Blender");
+               IMB_imginfo_add_field(img, "Thumb::URI", uri);
+               IMB_imginfo_add_field(img, "Thumb::MTime", mtime);
+               if (THB_SOURCE_IMAGE == source) {
+                       IMB_imginfo_add_field(img, "Thumb::Image::Width", cwidth);
+                       IMB_imginfo_add_field(img, "Thumb::Image::Height", cheight);
+               }
+               img->ftype = PNG;
+               img->depth = 32;                
+               if (IMB_saveiff(img, temp, IB_rect | IB_imginfo)) {
+#ifndef WIN32
+                       chmod(temp, S_IRUSR | S_IWUSR);
+#endif
+                       BLI_rename(temp, tpath);
+               }
+
+               return img;
+       }
+       return img;
+}
+
+/* read thumbnail for file and returns new imbuf for thumbnail */
+ImBuf* IMB_thumb_read(const char* dir, const char* file, ThumbSize size)
+{
+       char thumb[FILE_MAX];
+       char uri[FILE_MAX*3+8];
+       ImBuf *img = 0;
+
+       if (!uri_from_filename(dir, file,uri)) {
+               return NULL;
+       }
+       if (thumbpath_from_uri(uri, thumb, size)) {             
+               img = IMB_loadiffname(thumb, IB_rect | IB_imginfo);
+       }
+
+       return img;
+}
+
+/* delete all thumbs for the file */
+void IMB_thumb_delete(const char* dir, const char* file, ThumbSize size)
+{
+       char thumb[FILE_MAX];
+       char uri[FILE_MAX*3+8];
+
+       if (!uri_from_filename(dir, file,uri)) {
+               return;
+       }
+       if (thumbpath_from_uri(uri, thumb, size)) {
+               if (strncmp(thumb, dir, strlen(dir)) == 0) {
+                       return;
+               }
+               if (BLI_exists(thumb)) {
+                       BLI_delete(thumb, 0, 0);
+               }
+       }
+}
+
+
+/* create the thumb if necessary and manage failed and old thumbs */
+ImBuf* IMB_thumb_manage(const char* dir, const char* file, ThumbSize size, ThumbSource source)
+{
+       char path[FILE_MAX];
+       char thumb[FILE_MAX];
+       char uri[FILE_MAX*3+8];
+       struct stat st;
+       ImBuf* img = NULL;
+
+       BLI_join_dirfile(path, dir, file);
+       if (stat(path, &st)) {
+               return NULL;
+       }       
+       if (!uri_from_filename(dir, file,uri)) {
+               return NULL;
+       }
+       if (thumbpath_from_uri(uri, thumb, THB_FAIL)) {
+               /* failure thumb exists, don't try recreating */
+               if (BLI_exists(thumb)) {
+                       return NULL;
+               }
+       }
+
+       if (thumbpath_from_uri(uri, thumb, size)) {
+               if (strncmp(thumb, dir, strlen(dir)) == 0) {
+                       img = IMB_loadiffname(path, IB_rect);
+               } else {
+                       img = IMB_loadiffname(thumb, IB_rect | IB_imginfo);
+                       if (img) {
+                               char mtime[40];
+                               if (!IMB_imginfo_get_field(img, "Thumb::MTime", mtime, 40)) {
+                                       /* illegal thumb, forget it! */
+                                       IMB_freeImBuf(img);
+                                       img = 0;
+                               } else {
+                                       time_t t = atol(mtime);
+                                       if (st.st_mtime != t) {
+                                               /* recreate all thumbs */
+                                               IMB_freeImBuf(img);
+                                               img = 0;
+                                               IMB_thumb_delete(dir, file, THB_NORMAL);
+                                               IMB_thumb_delete(dir, file, THB_LARGE);
+                                               IMB_thumb_delete(dir, file, THB_FAIL);
+                                               img = IMB_thumb_create(dir, file, size, source);
+                                               if(!img){
+                                                       /* thumb creation failed, write fail thumb */
+                                                       img = IMB_thumb_create(dir, file, THB_FAIL, source);
+                                                       if (img) {
+                                                               /* we don't need failed thumb anymore */
+                                                               IMB_freeImBuf(img);
+                                                               img = 0;
+                                                       }
+                                               }
+                                       }
+                               }
+                       } else {
+                               img = IMB_thumb_create(dir, file, size, source);
+                               if(!img){
+                                       /* thumb creation failed, write fail thumb */
+                                       img = IMB_thumb_create(dir, file, THB_FAIL, source);
+                                       if (img) {
+                                               /* we don't need failed thumb anymore */
+                                               IMB_freeImBuf(img);
+                                               img = 0;
+                                       }
+                               }
+                       }
+               }
+       }
+
+       return img;
+}
+
+
diff --git a/source/blender/include/BIF_filelist.h b/source/blender/include/BIF_filelist.h
new file mode 100644 (file)
index 0000000..a8d8e6f
--- /dev/null
@@ -0,0 +1,87 @@
+/**
+ * $Id: $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License.  See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef BIF_FILELIST_H
+#define BIF_FILELIST_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct FileList;
+struct direntry;
+struct BlendHandle;
+
+struct FileList *      BIF_filelist_new();
+void                           BIF_filelist_init_icons();
+void                           BIF_filelist_free_icons();
+struct FileList *      BIF_filelist_copy(struct FileList* filelist);
+int                                    BIF_filelist_find(struct FileList* filelist, char *file);
+void                           BIF_filelist_free(struct FileList* filelist);
+void                           BIF_filelist_freelib(struct FileList* filelist);
+void                           BIF_filelist_sort(struct FileList* filelist, short sort);
+int                                    BIF_filelist_numfiles(struct FileList* filelist);
+const char *           BIF_filelist_dir(struct FileList* filelist);
+void                           BIF_filelist_setdir(struct FileList* filelist, const char *dir);
+void                           BIF_filelist_appenddir(struct FileList* filelist, const char *relname);
+struct direntry *      BIF_filelist_file(struct FileList* filelist, int index);
+void                           BIF_filelist_hidedot(struct FileList* filelist, short hide);
+void                           BIF_filelist_setfilter(struct FileList* filelist, unsigned int filter);
+void                           BIF_filelist_filter(struct FileList* filelist);
+void                           BIF_filelist_swapselect(struct FileList* filelist);
+void                           BIF_filelist_imgsize(struct FileList* filelist, short w, short h);
+void                           BIF_filelist_loadimage(struct FileList* filelist, int index);
+struct ImBuf *         BIF_filelist_getimage(struct FileList* filelist, int index);
+
+void                           BIF_filelist_readdir(struct FileList* filelist);
+
+int                                    BIF_filelist_empty(struct FileList* filelist);
+void                           BIF_filelist_parent(struct FileList* filelist);
+void                           BIF_filelist_setfiletypes(struct FileList* filelist, short has_quicktime);
+int                                    BIF_filelist_islibrary (struct FileList* filelist, char* dir, char* group);
+void                           BIF_filelist_from_main(struct FileList* filelist);
+void                           BIF_filelist_from_library(struct FileList* filelist);
+void                           BIF_filelist_append_library(struct FileList* filelist, char *dir, char* file, short flag, int idcode);
+void                           BIF_filelist_settype(struct FileList* filelist, int type);
+short                          BIF_filelist_gettype(struct FileList* filelist);
+void                           BIF_filelist_setipotype(struct FileList* filelist, short ipotype);
+void                           BIF_filelist_hasfunc(struct FileList* filelist, int has_func);
+
+struct BlendHandle *BIF_filelist_lib(struct FileList* filelist);
+int                                    BIF_groupname_to_code(char *group); /* TODO: where should this go */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
index b32dee0185497eb0a374b5fff3abbc41629a6ebf..1c5280c14f842161f9351699cb01be087f9b127b 100644 (file)
@@ -55,17 +55,20 @@ char*       fsmenu_build_menu               (void);
        /** Append a seperator to the FSMenu, inserts always follow the
         * last seperator.
         */
-void   fsmenu_append_seperator (void);
+void   fsmenu_append_separator (void);
 
        /** Inserts a new fsmenu entry with the given @a path.
         * Duplicate entries are not added.
         * @param sorted Should entry be inserted in sorted order?
         */
-void   fsmenu_insert_entry             (char *path, int sorted);
+void   fsmenu_insert_entry             (char *path, int sorted, short save);
 
        /** Removes the fsmenu entry at the given @a index. */
 void   fsmenu_remove_entry             (int index);
 
+       /** saves the 'favourites' to the specified file */
+void   fsmenu_write_file(const char *filename);
+
        /** Free's all the memory associated with the fsmenu */
 void   fsmenu_free                             (void);
 
index d6a1800730bfd4614444368fcc316ebc99432d13..0e92abe14e40f42c37e270ec4294a9e293d5d16f 100644 (file)
 #define BIF_IMASEL_H
 
 struct SpaceImaSel;
-struct OneSelectableIma;
 struct ScrArea;
-struct ImaDir;
 
-void imadir_parent(struct SpaceImaSel *simasel);
-int  bitset(int l,  int bit);
-void free_sel_ima(struct OneSelectableIma *firstima);
-
-void write_new_pib(struct SpaceImaSel *simasel);
-void free_ima_dir(struct ImaDir *firstdir);
-void check_for_pib(struct SpaceImaSel *simasel);
-void clear_ima_dir(struct SpaceImaSel *simasel);
-void check_ima_dir_name(char *dir);
-int get_ima_dir(char *dirname, int dtype, int *td, struct ImaDir **first);
-void get_next_image(struct SpaceImaSel *simasel);
-void get_file_info(struct SpaceImaSel *simasel);
-void get_pib_file(struct SpaceImaSel *simasel);
-void change_imadir(struct SpaceImaSel *simasel);
-void check_imasel_copy(struct SpaceImaSel *simasel);
 void free_imasel(struct SpaceImaSel *simasel);
 
 void clever_numbuts_imasel(void);
 
+void activate_imageselect(int type, char *title, char *file, void (*func)(char *));
+void activate_imageselect_menu(int type, char *title, char *file, char *pupmenu, short *menup, void (*func)(char *));
+void activate_imageselect_args(int type, char *title, char *file, void (*func)(char *, void *, void *), void *arg1, void *arg2);
+
+void activate_databrowse_imasel(struct ID *id, int idcode, int fromcode, int retval, short *menup, void (*func)(unsigned short));
+/*
+void activate_databrowse_imasel_args(struct ID *id, int idcode, int fromcode, short *menup, void (*func)(char *, void *, void *), void *arg1, void *arg2);
+*/
 #endif
 
index c69fa12209996be4f90259b1f8937663fab98af9..c628d68e9db6511d5f314717e81f138490850a4e 100644 (file)
@@ -48,6 +48,7 @@ typedef struct IconFile {
 
 
 #define ICON_DEFAULT_HEIGHT 16
+#define PREVIEW_DEFAULT_HEIGHT 96
 
 /*
  Resizable Icons for Blender
@@ -57,6 +58,8 @@ int BIF_icon_get_width(int icon_id);
 int BIF_icon_get_height(int icon_id);
 
 void BIF_icon_draw(float x, float y, int icon_id);
+void BIF_icon_draw_preview(float x, float y, int icon_id, int nocreate);
+
 void BIF_icon_draw_aspect(float x, float y, int icon_id, float aspect);
 void BIF_icon_draw_aspect_blended(float x, float y, int icon_id, float aspect, int shade);
 void BIF_icons_free();
index 77c0f5861e3c07139d740c64bd18248e918e43b1..d734e59046fe78767967eb269eb38fbf1dffacfb 100644 (file)
@@ -164,7 +164,7 @@ typedef enum {
        ICON_FACESEL_DEHLT,
        ICON_FACESEL_HLT,
        ICON_EDIT_DEHLT,
-       ICON_BLANK19,
+       ICON_BOOKMARKS,
        ICON_BLANK20,
        ICON_BLANK21,
        ICON_BLANK22,
index 884f0459abfc750c65f8c72f627d6e270a1dc438..12f1e1586a07a858e23dbbe55d096311411c7418 100644 (file)
@@ -75,6 +75,9 @@ struct SpaceOops;
 /* sequence handler codes */
 #define SEQ_HANDLER_PROPERTIES 60
 
+/* imasel handler codes */
+#define IMASEL_HANDLER_IMAGE   70
+
 /* theme codes */
 #define B_ADD_THEME    3301
 #define B_DEL_THEME    3302
index f412ca0858489f58caea1cd72c7ca88f3ce096b6..6c68ba79bb9450542afbf09db7ef0416df4d8cd3 100644 (file)
 #ifndef BSE_DRAWIMASEL_H
 #define BSE_DRAWIMASEL_H
 
+
+/* button events */
+#define B_FS_FILENAME  1
+#define B_FS_DIRNAME   2
+#define B_FS_DIR_MENU  3
+#define B_FS_PARDIR    4
+#define B_FS_LOAD      5
+#define B_FS_CANCEL    6
+#define B_FS_LIBNAME   7
+#define B_FS_BOOKMARK  8
+
+/* ui geometry */
+#define IMASEL_BUTTONS_HEIGHT 60
+#define TILE_BORDER_X 8
+#define TILE_BORDER_Y 8
+
 struct ScrArea;
 struct SpaceImaSel;
 
-void viewgate(short sx, short sy, short ex, short ey);
-void areaview (void);
-void calc_hilite(struct SpaceImaSel *simasel);
-void make_sima_area(struct SpaceImaSel *simasel);
-void draw_sima_area(struct SpaceImaSel *simasel);
-void select_ima_files(struct SpaceImaSel *simasel);
-void move_imadir_sli(struct SpaceImaSel *simasel);
-void move_imafile_sli(struct SpaceImaSel *simasel);
-void ima_select_all(struct SpaceImaSel *simasel);
-void pibplay(struct SpaceImaSel *simasel);
 void drawimaselspace(struct ScrArea *sa, void *spacedata);   
-
-/*  void calc_hilite(SpaceImaSel *simasel); */
-/*  void ima_select_all(SpaceImaSel *simasel); */
-/*  void move_imadir_sli(SpaceImaSel *simasel); */
-/*  void move_imafile_sli(SpaceImaSel *simasel); */
-/*  void pibplay(SpaceImaSel *simasel); */
-/*  void select_ima_files(SpaceImaSel *simasel); */
+void calc_imasel_rcts(SpaceImaSel *simasel, int winx, int winy);
+void do_imasel_buttonevents(short event, SpaceImaSel *simasel);
 
 #endif  /*  BSE_DRAWIMASEL_H */
 
index 6934899062e13d1f2e29e9c588ec70346de09534..a41eea32040b1f5213e556b8d9e5f6c782702da7 100644 (file)
@@ -53,8 +53,6 @@ void activate_fileselect(int type, char *title, char *file, void (*func)(char *)
 void activate_fileselect_menu(int type, char *title, char *file, char *pupmenu, short *menup, void (*func)(char *));
 void activate_fileselect_args(int type, char *title, char *file, void (*func)(char *, void *, void *), void *arg1, void *arg2);
 
-void activate_imageselect(int type, char *title, char *file, void (*func)(char *));
-
 void activate_databrowse(struct ID *id, int idcode, int fromcode, int retval, short *menup, void (*func)(unsigned short));
 void activate_databrowse_args(struct ID *id, int idcode, int fromcode, short *menup, void (*func)(char *, void *, void *), void *arg1, void *arg2);
 
index 596b11c609c9cd9ce37c11f57916c5281c45d6dd..349685a5d8a7b934ed0a8e3b3e21644531e1d068 100644 (file)
 #define B_CONTEXT_SWITCH       406
 
 /* IMASEL: 450 */
-/* in imasel.h */
+/* in imasel.h - not any more - elubie */
+#define B_SORTIMASELLIST       451
+#define B_RELOADIMASELDIR      452
+#define B_FILTERIMASELDIR      453
 
 /* TEXT: 500 */
 #define B_TEXTBROWSE           501
index d7a1aa5c78cf15852e790b0bd80ef4258d21b84a..7afd4428d702001fff8760fa5f478a83d3ea6c70 100644 (file)
@@ -44,6 +44,9 @@ extern char datatoc_Bfs[];
 extern int datatoc_blenderbuttons_size;
 extern char datatoc_blenderbuttons[];
 
+extern int datatoc_prvicons_size;
+extern char datatoc_prvicons[];
+
 extern int datatoc_Bfont_size;
 extern char datatoc_Bfont[];
 
index d7be02c6fc58039455d89862f462e4ff536fe9d7..d8e779b9af8349d2e05df503fc0334ed9b873267 100644 (file)
@@ -230,7 +230,7 @@ extern void ui_draw_but(uiBut *but);
 extern void ui_rasterpos_safe(float x, float y, float aspect);
 extern void ui_draw_tria_icon(float x, float y, float aspect, char dir);
 extern void ui_draw_anti_x(float x1, float y1, float x2, float y2);
-
+extern void ui_dropshadow(rctf *rct, float radius, float aspect, int select);
 
 #endif
 
index f8ad5399af3f808bbcfd2fc1459b3d4ea3c7d3ae..d939d0dc879fa2c031836a5475e2ed190ca2b503 100644 (file)
@@ -120,6 +120,18 @@ typedef struct Library {
        struct Library *parent; /* for outliner, showing dependency */
 } Library;
 
+#define PREVIEW_MIPMAPS 2
+#define PREVIEW_MIPMAP_ZERO 0
+#define PREVIEW_MIPMAP_LARGE 1
+
+typedef struct PreviewImage {
+       unsigned int w[2];
+       unsigned int h[2];      
+       short changed[2];
+       short pad0, pad1;
+       unsigned int * rect[2];
+} PreviewImage;
+
 /**
  * Defines for working with IDs.
  *
index cf13a1116a97911515cd5bde4af78b62b3d7ae97..694279d4605dc64c0731515a949345e80c0de6e9 100644 (file)
@@ -41,11 +41,6 @@ struct anim;
 struct ImBuf;
 struct RenderResult;
 
-typedef struct PreviewImage {
-       unsigned int w;
-       unsigned int h;
-       unsigned int * rect;
-} PreviewImage;
 
 /* ImageUser is in Texture, in Nodes, Background Image, Image Window, .... */
 /* should be used in conjunction with an ID * to Image. */
index 104b13ea24c4de114c8cee72d6c2e916a0763725..5d998ccca6eeed50234ba3a02aeee773025eaf13 100644 (file)
@@ -79,6 +79,9 @@ typedef struct Lamp {
        struct MTex *mtex[10];
        struct Ipo *ipo;
        
+       /* preview */
+       struct PreviewImage *preview;
+
        ScriptLink scriptlink;
 } Lamp;
 
index 0fad110d64b3dca4c2eb743e65eb22cf9ca1a7b3..b6bc475fb28c83a24f0976edf6e686d8017e9c75 100644 (file)
@@ -105,7 +105,8 @@ typedef struct Material {
        struct bNodeTree *nodetree;     
        struct Ipo *ipo;
        struct Group *group;    /* light group */
-       
+       struct PreviewImage * preview;
+
        /* dynamic properties */
        float friction, fh, reflect;
        float fhdist, xyfrict;
index e70c8baaa78f68e42071e793fccba87209c91e1b..42f08e3795ee2589a25a989ea4e12a00f668e617 100644 (file)
@@ -52,6 +52,7 @@ struct BlendHandle;
 struct RenderInfo;
 struct bNodeTree;
 struct uiBlock;
+struct FileList;
 
        /**
         * The base structure all the other spaces
@@ -336,89 +337,63 @@ typedef struct SpaceNode {
 #define SNODE_DO_PREVIEW       1
 #define SNODE_BACKDRAW         2
 
-#
-#
-typedef struct OneSelectableIma {
-       int   header;                                           
-       int   ibuf_type;
-       struct ImBuf *pict;                                     
-       struct OneSelectableIma *next;          
-       struct OneSelectableIma *prev;          
-       
-       short  cmap, image, draw_me, rt;
-       short  sx, sy, ex, ey, dw, dh;                          
-       short  selectable, selected;            
-       int   mtime, disksize;                          
-       char   file_name[64];
-       
-       short  orgx, orgy, orgd, anim;          /* same as ibuf->x...*/
-       char   dummy[4];                                        /* 128 */
-
-       char   pict_rect[3968];                         /* 4096   (RECT = 64 * 62) */
-       
-} OneSelectableIma;
-
-#
-#
-typedef struct ImaDir {
-       struct ImaDir *next, *prev;
-       int  selected, hilite; 
-       int  type,  size;
-       int mtime;
-       char name[100];
-} ImaDir;
-
 typedef struct SpaceImaSel {
        SpaceLink *next, *prev;
        int spacetype;
        float blockscale;
        struct ScrArea *area;
        
-       char   title[28];
-       
-       int   fase; 
-       short  mode, subfase;
-       short  mouse_move_redraw, imafase;
-       short  mx, my;
-       
-       short  dirsli, dirsli_lines;
-       short  dirsli_sx, dirsli_ey , dirsli_ex, dirsli_h;
-       short  imasli, fileselmenuitem;
-       short  imasli_sx, imasli_ey , imasli_ex, imasli_h;
-       
-       short  dssx, dssy, dsex, dsey; 
-       short  desx, desy, deex, deey; 
-       short  fssx, fssy, fsex, fsey; 
-       short  dsdh, fsdh; 
-       short  fesx, fesy, feex, feey; 
-       short  infsx, infsy, infex, infey; 
-       short  dnsx, dnsy, dnw, dnh;
-       short  fnsx, fnsy, fnw, fnh;
-
-       
-       char   fole[128], dor[128];
-       char   file[128], dir[128];
-       ImaDir *firstdir, *firstfile;
-       int    topdir,  totaldirs,  hilite; 
-       int    topfile, totalfiles;
-       
-       float  image_slider;
-       float  slider_height;
-       float  slider_space;
-       short  topima,  totalima;
-       short  curimax, curimay;
-       OneSelectableIma *first_sel_ima;
-       OneSelectableIma *hilite_ima;
-       short  total_selected, ima_redraw;
-       int pad2;
+       short blockhandler[8];
+
+       View2D v2d;
+
+       struct FileList *files;
+
+       /* specific stuff for drawing */
+       char title[24];
+       char dir[160];
+       char file[80];
+
+       short type, menu, flag, sort;
+
+       void *curfont;
+       int     active_file;
+
+       int numtilesx;
+       int numtilesy;
+
+       int selstate;
+
+       struct rcti viewrect;
+       struct rcti bookmarkrect;
+
+       float scrollpos; /* current position of scrollhandle */
+       float scrollheight; /* height of the scrollhandle */
+       float scrollarea; /* scroll region, scrollpos is from 0 to scrollarea */
+
+       float aspect;
+       unsigned short retval;          /* event */
+
+       short ipotype;
        
-       struct ImBuf  *cmap;
+       short filter;
+       short active_bookmark;
+       short pad, pad1;
+
+       /* view settings */
+       short prv_w;
+       short prv_h;
+
+       /* one day we'll add unions to dna */
+       void (*returnfunc)(char *);
+       void (*returnfunc_event)(unsigned short);
+       void (*returnfunc_args)(char *, void *, void *);
+       
+       void *arg1, *arg2;
+       short *menup;   /* pointer to menu result or ID browsing */
+       char *pupmenu;  /* optional menu in header */
 
-       /* Also fucked. Needs to change so things compile, but breaks sdna
-       * ... */        
-/*     void (*returnfunc)(void); */
-       void (*returnfunc)(char*);
-       void *arg1;
+       struct ImBuf *img;
 } SpaceImaSel;
 
 
@@ -447,7 +422,7 @@ typedef struct SpaceImaSel {
 #define FILE_MAIN                      2
 #define FILE_LOADFONT          3
 
-/* sfile->flag */
+/* sfile->flag and simasel->flag */
 #define FILE_SHOWSHORT         1
 #define FILE_STRINGCODE                2
 #define FILE_LINK                      4
@@ -456,6 +431,8 @@ typedef struct SpaceImaSel {
 #define FILE_ACTIVELAY         32
 #define FILE_ATCURSOR          64
 #define FILE_SYNCPOSE          128
+#define FILE_FILTER                    256
+#define FILE_BOOKMARKS         512
 
 /* sfile->sort */
 #define FILE_SORTALPHA         0
@@ -472,6 +449,9 @@ typedef struct SpaceImaSel {
 #define PYSCRIPTFILE           64
 #define FTFONTFILE                     128
 #define SOUNDFILE                      256
+#define TEXTFILE                       512
+#define MOVIEFILE_ICON         1024 /* movie file that preview can't load */
+#define FOLDERFILE                     2048 /* represents folders for filtering */
 
 #define SCROLLH        16                      /* height scrollbar */
 #define SCROLLB        16                      /* width scrollbar */
index 4ad92f9f33d57eb392f0632e4b6254892f070c4f..064cfe39d45bedfdd9e15b9f4922d9214572943b 100644 (file)
@@ -44,6 +44,7 @@ struct EnvMap;
 struct Object;
 struct Tex;
 struct Image;
+struct PreviewImage;
 struct ImBuf;
 
 typedef struct MTex {
@@ -171,7 +172,7 @@ typedef struct Tex {
        struct PluginTex *plugin;
        struct ColorBand *coba;
        struct EnvMap *env;
-       
+       struct PreviewImage * preview;
        
 } Tex;
 
index 2e83e773ce8fada6be5906dbf30adea446a2b2ec..945fe5e00d31c09373ff4d0bc19b8d8777770b8f 100644 (file)
@@ -205,6 +205,7 @@ extern UserDef U; /* from usiblender.c !!!! */
 #define USER_NONUMPAD                  8192
 #define USER_LMOUSESELECT              16384
 #define USER_FILECOMPRESS              32768
+#define USER_SAVE_PREVIEWS             65536
 
 /* viewzom */
 #define USER_ZOOM_CONT                 0
index 4b8dfe3812a5576ac57abf45cda57cf05f100aa4..7349e37f3b74b3c58ce35660bf5ec5ec0043885e 100644 (file)
@@ -108,6 +108,9 @@ typedef struct World {
        struct Ipo *ipo;
        struct MTex *mtex[10];
 
+       /* previews */
+       struct PreviewImage *preview;
+
        ScriptLink scriptlink;
 
 } World;
index 22ae5586e2c4a0de25a2d54510481b1a8d7bdf24..cf128ec8dd268051f4c8cccf18df0ad3ce735600 100644 (file)
@@ -40,6 +40,7 @@
 #include "BKE_scene.h"         /* scene_find_camera() */
 #include "BPI_script.h"
 #include "BIF_mywindow.h"
+#include "BIF_imasel.h"
 #include "BSE_headerbuttons.h"
 #include "BSE_filesel.h"
 #include "BIF_editmesh.h"      /* for undo_push_mesh() */
index c701d4d41d0f8081632fd35ed8bdf327abc88f94..862b20b5260b755b3a74a7137b94dd983859f061 100644 (file)
@@ -244,6 +244,7 @@ static OSErr QT_get_frameIndexes(struct anim *anim)
        TimeValue nextTime = 0;
        TimeValue       startPoint;
        TimeValue       tmpstartPoint;
+       long sampleCount = 0;
 
        startPoint = -1;
 
@@ -254,12 +255,12 @@ static OSErr QT_get_frameIndexes(struct anim *anim)
 
        anim->qtime->framecount = 0;
 
-       while(tmpstartPoint != -1) {
-               nextTime = 0;
-               GetMovieNextInterestingTime(anim->qtime->movie, nextTimeMediaSample, 1, &media, tmpstartPoint, 0, &nextTime, NULL);
-               tmpstartPoint = nextTime;
-               anim->qtime->framecount ++;
-       }
+       sampleCount = GetMediaSampleCount(anim->qtime->theMedia);
+       anErr = GetMoviesError();
+       if (anErr != noErr) return anErr;
+
+       anim->qtime->framecount = sampleCount;
+
        anim->qtime->frameIndex = (TimeValue *) MEM_callocN(sizeof(TimeValue) * anim->qtime->framecount, "qtframeindex");
 
        //rewind
@@ -403,6 +404,7 @@ int startquicktime (struct anim *anim)
        char            *qtname;
        Str255          dst;
 #endif
+       short depth = 0;
 
        anim->qtime = MEM_callocN (sizeof(QuicktimeMovie),"animqt");
        anim->qtime->have_gw = FALSE;
@@ -483,6 +485,9 @@ int startquicktime (struct anim *anim)
                                 anim->qtime->offscreenGWorld,
                                 GetGWorldDevice(anim->qtime->offscreenGWorld));
                SetMoviePlayHints(anim->qtime->movie, hintsHighQuality, hintsHighQuality);
+               
+               // sets Media and Track!
+               depth = GetFirstVideoTrackPixelDepth(anim);
 
                QT_get_frameIndexes(anim);
        }
@@ -491,7 +496,7 @@ int startquicktime (struct anim *anim)
        LockPixels(anim->qtime->offscreenPixMap);
 
        //fill blender's anim struct
-       anim->qtime->depth = GetFirstVideoTrackPixelDepth(anim);
+       anim->qtime->depth = depth;
        
        anim->duration = anim->qtime->framecount;
        anim->params = 0;
index 951a4ac25e4c989af4106951735e2022340081f4..ee5e194bd3504d0bb6ed3a1b48387d559c72be55 100644 (file)
@@ -61,6 +61,7 @@
 #include "BIF_graphics.h"
 #include "BIF_glutil.h"
 #include "BIF_interface.h"
+#include "BIF_imasel.h"
 #include "BIF_keyval.h"
 #include "BIF_mainqueue.h"
 #include "BIF_mywindow.h"
index 1e1a9b1e01fccc521246552b9007c5d7e35d7878..ab0c1cb3ad2a5ca9b6355b6e7c58f94e33c5bea6 100644 (file)
@@ -94,6 +94,7 @@
 #include "BIF_mywindow.h"
 #include "BIF_space.h"
 #include "BIF_glutil.h"
+#include "BIF_imasel.h"
 #include "BIF_interface.h"
 #include "BIF_toolbox.h"
 #include "BIF_space.h"
@@ -876,7 +877,12 @@ static void image_load_fs_cb(void *ima_pp_v, void *iuser_v)
 #else
        else name = U.textudir;
 #endif
-       activate_fileselect_args(FILE_SPECIAL, "SELECT IMAGE", name, load_image_cb, ima_pp_v, iuser_v);
+       if (G.qual & LR_CTRLKEY) {
+               activate_imageselect_args(FILE_SPECIAL, "SELECT IMAGE", name, load_image_cb, ima_pp_v, iuser_v);
+       }
+       else  {
+               activate_fileselect_args(FILE_SPECIAL, "SELECT IMAGE", name, load_image_cb, ima_pp_v, iuser_v);
+       }
 }
 
 /* 5 layer button callbacks... */
index 45757170f782a29cbd313898f6dc6eeb05c73e10..009172331095c57886f50e2335170c27bc9b77fb 100644 (file)
 #endif
 
 #include "MEM_guardedalloc.h"
-#include "BMF_Api.h"
-#include "BLI_blenlib.h"
-#include "IMB_imbuf_types.h"
+
+#include "DNA_ID.h"
 #include "DNA_screen_types.h"
 #include "DNA_space_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_userdef_types.h"
+#include "DNA_object_types.h"
+#include "DNA_material_types.h"
+
+#include "BLI_blenlib.h"
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+#include "BLI_storage_types.h"
+
 #include "BKE_global.h"
+#include "BKE_library.h"
+#include "BKE_icons.h"
+#include "BKE_utildefines.h"
+#include "BIF_filelist.h"
 
-#include "BIF_fsmenu.h"
 #include "BIF_gl.h"
-#include "BIF_resources.h"
+#include "BIF_glutil.h"
+#include "BIF_mywindow.h"
 #include "BIF_screen.h"
+#include "BIF_resources.h"
+#include "BIF_language.h"
+
 #include "BIF_interface.h"
 #include "BIF_interface_icons.h"
-#include "BIF_imasel.h"
-#include "BIF_mywindow.h"
+#include "BIF_previewrender.h"
+#include "BIF_fsmenu.h"
 #include "BIF_space.h"
-#include "BIF_resources.h"
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
 
 #include "BSE_drawimasel.h"
-#include "BSE_filesel.h"
+#include "BSE_drawipo.h" /* for v2d functions */ 
+#include "BSE_view.h"
 
-#include "blendef.h"
-#include "mydevice.h"
+#include "BLO_readfile.h"
 
-#define IMALINESIZE 16
-/* well, who would have thought ... */
-#define lrectwrite(a, b, c, d, rect)   {glRasterPos2i(a,  b);glDrawPixels((c)-(a)+1, (d)-(b)+1, GL_RGBA, GL_UNSIGNED_BYTE,  rect);}
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
 
-/* GLOBALS */
-extern char *fsmenu;
+#include "PIL_time.h"
 
-void rectwrite_imasel(int , int , int , int , int , int , int , int , float , float , unsigned int *);
+#include "blendef.h"
+#include "mydevice.h"
 
-void rectwrite_imasel(int winxmin, int winymin, int winxmax, int winymax, int x1, int y1, int xim, int yim, float zoomx, float zoomy, unsigned int *rect)
-{
-       int cx, cy, oldxim, x2, y2;
-       
-       oldxim= xim;
-               
-       /* coordinates how it will be put at screen */
-       x2= x1+ zoomx*xim;
-       y2= y1+ zoomy*yim;
-
-       /* partial clip */
-       if(x1<=winxmin) {
-               /* with OpenGL, rects are not allowed to start outside of the left/bottom window edge */
-               cx= winxmin-x1+(int)zoomx;
-               /* make sure the rect will be drawn pixel-exact */
-               cx/= zoomx;
-               cx++;
-               x1+= zoomx*cx;
-               xim-= cx;
-               rect+= cx;
-       }
-       if(y1<=winymin) {
-               cy= winymin-y1+(int)zoomy;
-               cy/= zoomy;
-               cy++;
-               y1+= zoomy*cy;
-               rect+= cy*oldxim;
-               yim-= cy;
+#include "interface.h" /* urm...  for rasterpos_safe, roundbox */
+
+#define BUTTONWIDTH 20
+#define BOOKMARKWIDTH_MAX 240
+
+void calc_imasel_rcts(SpaceImaSel *simasel, int winx, int winy)
+{      
+       int width = (int)16.0f*simasel->aspect;
+       int numtiles;
+       int numfiles = 0;
+       int tilewidth = simasel->prv_w + TILE_BORDER_X*4;
+       int tileheight = simasel->prv_h + TILE_BORDER_Y*4 + U.fontsize;
+
+       // complete area of the space
+       simasel->v2d.mask.xmin= simasel->v2d.mask.ymin = 0;
+       simasel->v2d.mask.xmax= winx;
+       simasel->v2d.mask.ymax= winy;
+
+       // vertical scroll bar
+       simasel->v2d.vert= simasel->v2d.mask;
+       simasel->v2d.vert.xmax -= TILE_BORDER_X + 2;
+       simasel->v2d.vert.xmin= simasel->v2d.vert.xmax- width - TILE_BORDER_X - 2;
+       simasel->v2d.vert.ymax -= IMASEL_BUTTONS_HEIGHT + TILE_BORDER_Y + 2;
+       simasel->v2d.vert.ymin += TILE_BORDER_Y + 2;
+       // simasel->v2d.mask.xmax= simasel->v2d.vert.xmin;
+       
+       if (simasel->flag & FILE_BOOKMARKS) {
+               int bmwidth = (simasel->v2d.vert.xmin - simasel->v2d.mask.xmin)/4.0f;
+               if (bmwidth > BOOKMARKWIDTH_MAX) bmwidth = BOOKMARKWIDTH_MAX;
+
+               simasel->bookmarkrect.xmin = simasel->v2d.mask.xmin + TILE_BORDER_X;
+               simasel->bookmarkrect.xmax = simasel->v2d.mask.xmin + bmwidth - TILE_BORDER_X;
+               simasel->bookmarkrect.ymax = simasel->v2d.mask.ymax - IMASEL_BUTTONS_HEIGHT - TILE_BORDER_Y;    
+               simasel->bookmarkrect.ymin = simasel->v2d.mask.ymin + TILE_BORDER_Y;
+
+               simasel->viewrect.xmin = simasel->bookmarkrect.xmax + TILE_BORDER_X;
+               simasel->viewrect.xmax = simasel->v2d.vert.xmin - TILE_BORDER_X;
+               simasel->viewrect.ymax = simasel->v2d.mask.ymax - IMASEL_BUTTONS_HEIGHT - TILE_BORDER_Y;        
+               simasel->viewrect.ymin = simasel->v2d.mask.ymin + TILE_BORDER_Y;        
+       } else {
+               simasel->viewrect.xmin = simasel->v2d.mask.xmin + TILE_BORDER_X;
+               simasel->viewrect.xmax = simasel->v2d.vert.xmin - TILE_BORDER_X;
+               simasel->viewrect.ymax = simasel->v2d.mask.ymax - IMASEL_BUTTONS_HEIGHT - TILE_BORDER_Y;        
+               simasel->viewrect.ymin = simasel->v2d.mask.ymin + TILE_BORDER_Y;                
        }
-       if(x2>=winxmax) {
-               cx= x2-winxmax;
-               cx/= zoomx;
-               xim-= cx+3;
+
+       simasel->numtilesx = (simasel->viewrect.xmax - simasel->viewrect.xmin) / tilewidth;
+       simasel->numtilesy = (simasel->viewrect.ymax - simasel->viewrect.ymin) / tileheight;
+       numtiles = simasel->numtilesx*simasel->numtilesy;
+
+       if (simasel->files) {
+               numfiles = BIF_filelist_numfiles(simasel->files);
        }
-       if(y2>=winymax) {
-               cy= y2-winymax;
-               cy/= zoomy;
-               yim-= cy+3;
+       if (numtiles > numfiles) numtiles = numfiles;
+
+       simasel->scrollarea = ((float)simasel->v2d.vert.ymax - (float)simasel->v2d.vert.ymin);
+       if (numtiles < numfiles) {
+               simasel->scrollheight = ((float)numtiles / (float)numfiles)*simasel->scrollarea;
+               simasel->scrollarea -= simasel->scrollheight;   
+       } else {
+               simasel->scrollheight = simasel->scrollarea;
        }
-       
-       if(xim<=0) return;
-       if(yim<=0) return;
+       if (simasel->scrollarea < 0) simasel->scrollarea = 0;
+}
 
-//     mywinset(curarea->win);
-       glScissor(winxmin, winymin, winxmax-winxmin+1, winymax-winymin+1);
-       
-       glPixelStorei(GL_UNPACK_ROW_LENGTH,  oldxim);
-       
-       glPixelZoom(zoomx,  zoomy);
+void draw_imasel_scroll(SpaceImaSel *simasel)
+{
+       rcti scrollbar;
+       rcti scrollhandle;
 
-       glRasterPos2i(x1, y1);
-       glDrawPixels(xim, yim, GL_RGBA, GL_UNSIGNED_BYTE,  rect);
+       scrollbar.xmin= simasel->v2d.cur.xmin + simasel->v2d.vert.xmin;         
+       scrollbar.ymin = simasel->v2d.cur.ymin + simasel->v2d.vert.ymin;
+       scrollbar.xmax= simasel->v2d.cur.xmin + simasel->v2d.vert.xmax;
+       scrollbar.ymax = simasel->v2d.cur.ymin + simasel->v2d.vert.ymax;
 
-       glPixelZoom(1.0,  1.0);
+       scrollhandle.xmin= scrollbar.xmin;              
+       scrollhandle.ymin = scrollbar.ymax - simasel->scrollpos -1;
+       scrollhandle.xmax= scrollbar.xmax-1;
+       scrollhandle.ymax = scrollbar.ymax - simasel->scrollpos - simasel->scrollheight;
 
-       glPixelStorei(GL_UNPACK_ROW_LENGTH,  0);
-}
+       BIF_ThemeColor(TH_SHADE1);
+       glRecti(scrollbar.xmin,  scrollbar.ymin, scrollbar.xmax, scrollbar.ymax);
+       uiEmboss(scrollbar.xmin-2,  scrollbar.ymin-2, scrollbar.xmax+2, scrollbar.ymax+2, 1);
 
-void viewgate(short sx, short sy, short ex, short ey) 
-{
-       short wx, wy;
-       wx = curarea->winrct.xmin; wy = curarea->winrct.ymin;
-       glViewport(wx+sx, wy+sy, (wx+ex )-(wx+sx)+1, (wy+ey )-(wy+sy)+1); 
-       glScissor(wx+sx, wy+sy, (wx+ex )-(wx+sx)+1, (wy+ey )-(wy+sy)+1);
-       myortho2((float)sx-0.375 , (float)ex-0.375, (float)sy-0.375, (float)ey-0.375);
-}      
+       BIF_ThemeColor(TH_SHADE2);
+       glRecti(scrollhandle.xmin,  scrollhandle.ymin,  scrollhandle.xmax,  scrollhandle.ymax);
        
-void areaview (void) 
-{
-       short wx, wy;
-       wx = curarea->winrct.xmin; wy = curarea->winrct.ymin;
-       glViewport(wx,  wy, curarea->winx, curarea->winy); 
-       glScissor(wx,  wy, curarea->winx, curarea->winy); 
-       myortho2(-0.375, (float)(curarea->winx)-0.375, -0.375, (float)(curarea->winy)-0.375);
-
+       uiEmboss(scrollhandle.xmin, scrollhandle.ymin, scrollhandle.xmax, scrollhandle.ymax, 1); 
 }
-               
-void calc_hilite(SpaceImaSel *simasel)
+
+static void draw_tile(SpaceImaSel *simasel, short sx, short sy, int colorid)
 {
-       OneSelectableIma *ima;
-       ImaDir  *direntry;
-       short   mx, my;
-       int     i, area_event;
-       
-       if (simasel->hilite > -1) {
-               direntry = simasel->firstdir; 
-               while(direntry){
-                       direntry->hilite = 0;
-                       direntry = direntry->next;
-               }       
-               simasel->hilite = -1;
-       }
-       
-       if (simasel->totalima){
-               simasel->hilite_ima =  0;
-               ima = simasel->first_sel_ima;
-               while (ima){
-                       ima->selectable = 0;
-                       ima = ima->next;
-               }
-       }
-               
-       area_event = 0;
-       mx = simasel->mx;
-       my = simasel->my;
-               
-       if (simasel->desx > 0){
-               if ( (mx > simasel->desx) && (mx < simasel->deex) && (my > simasel->desy) && (my < simasel->deey) ) area_event = IMS_INDIR;
-       }
-       if (simasel->fesx > 0){
-               if ( (mx > simasel->fesx) && (mx < simasel->feex) && (my > simasel->fesy) && (my < simasel->feey) ) area_event = IMS_INFILE;
-       }       
-       
-       switch(area_event){
-       case IMS_INDIR:
-               simasel->hilite = simasel->topdir + ((simasel->deey - my - 4) / IMALINESIZE);
-               
-               if (my >= simasel->deey)                                        simasel->hilite = -1;
-               if (simasel->hilite >= simasel->totaldirs)  simasel->hilite = -1;
-       
-               if (simasel->hilite > -1){
-                       direntry = simasel->firstdir; 
-                       for (i = simasel->hilite; i>0; i--){
-                               direntry = direntry->next;
-                       }
-                       direntry->hilite = 1;
-                       
-               }
-               simasel->mouse_move_redraw = 1;
-               break;
-       
-       case IMS_INFILE:
-               if (simasel->totalima){
-                       ima = simasel->first_sel_ima;
-                       while (ima){
-                               ima->selectable = 0;
-                               
-                               if (ima->draw_me) {
-                                       if ((mx > ima->sx) && (mx < ima->sx+76) && (my > ima->sy-16) && (my < ima->sy+76)) {
-                                               ima->selectable = 1;
-                                               simasel->hilite_ima = ima;
-                                               simasel->mouse_move_redraw = 1;
-                                       }
-                               }
-                               
-                               ima = ima->next;
-                       }       
-               }
-               break;
-       }
+       /* TODO: BIF_ThemeColor seems to need this to show the color, not sure why? - elubie */
+       glEnable(GL_BLEND);
+       glColor4ub(0, 0, 0, 100);
+       glDisable(GL_BLEND);
+       
+       BIF_ThemeColor4(colorid);
+       uiSetRoundBox(15);      
+       uiRoundBox(sx+TILE_BORDER_X, sy - simasel->prv_h - TILE_BORDER_Y*3 - U.fontsize, sx + simasel->prv_w + TILE_BORDER_X*3, sy, 6);
 }
 
-
-void make_sima_area(SpaceImaSel *simasel)
-{
-       OneSelectableIma *ima;
-       short rh, dm, sc;
-       short boxperline, boxlines, boxlinesinview, boxlinesleft;
-
-/*  ima slider  box */
-       simasel->fssx =  8; 
-       simasel->fssy = 8; 
-       simasel->fsex = 30; 
-       simasel->fsey = curarea->winy-64;
-/*  ima entry's  box */
-       simasel->fesx = simasel->fsex + 8; 
-       simasel->fesy = simasel->fssy; 
-       simasel->feex = curarea->winx- 8;  
-       simasel->feey = curarea->winy-64;
-/*  ima names */
-       simasel->dnsx = 38; 
-       simasel->dnsy = curarea->winy - 29; 
-       simasel->dnw  = curarea->winx - 8 - 38; 
-       simasel->dnh  = 21;
-       simasel->fnsx = simasel->fesx; 
-       simasel->fnsy = curarea->winy - 29 - 29; 
-       simasel->fnw  = curarea->winx - 8 - simasel->fnsx; 
-       simasel->fnh  = 21;
-       
-       if ((simasel->mode & 1)==1){
-       /*  dir slider  box */
-               simasel->dssx =   8; 
-               
-               simasel->dsex =  30; 
-               simasel->dsey = curarea->winy-64;
-       /*  dir entry's  box */
-               simasel->desx =  38;
-               simasel->desy =   8; 
-               
-               simasel->deex = 208; 
-               simasel->deey = curarea->winy-64;
-               simasel->dssy = simasel->desy; 
-               if (simasel->deex > (curarea->winx -8) ) simasel->deex = curarea->winx - 8;
-               if (simasel->deex <= simasel->desx ) simasel->dssx =  0;
-       /*  file slider & entry & name box ++ */
-               simasel->fssx += 216; 
-               simasel->fsex += 216;
-               simasel->fesx += 216;
-               simasel->fnsx += 216;
-               simasel->fnw  -= 216;
-       }else{
-               simasel->desx =  0;
-       }
-       
-       if ((simasel->mode & 2) == 2){  
-               simasel->fesy += 32;
-               simasel->infsx = simasel->fesx; simasel->infsy =  8;
-               simasel->infex = simasel->feex; simasel->infey = 28;
-       }else{
-               simasel->infsx = 0;
+static float shorten_string(SpaceImaSel *simasel, char* string, float w)
+{      
+       short shortened = 0;
+       float sw = 0;
+       
+       sw = BIF_GetStringWidth(simasel->curfont, string, 0);
+       while (sw>w) {
+               int slen = strlen(string);
+               string[slen-1] = '\0';
+               sw = BIF_GetStringWidth(simasel->curfont, string, 0);
+               shortened = 1;
        }
-       
-       simasel->dsdh = simasel->deey - simasel->desy - 4;
-       
-       if (simasel->dsdh  <= 16)  { simasel->desx  = 0; }
-       if ((simasel->feex-16)  <= simasel->fesx)  { simasel->fesx  = 0; }
-       if ((simasel->infex-16) <= simasel->infsx) { simasel->infsx = 0; }
-       
-       if ((simasel->deey  ) <= simasel->desy)    { simasel->desx  = 0; }
-       if ((simasel->feey  ) <= simasel->fesy)    { simasel->fesx  = 0; }
-       if ((simasel->infey )  > simasel->feey)    { simasel->infsx  = 0;}
-       
-       /* Dir Slider */
-       if (simasel->desx  != 0){
-               simasel->dirsli = 0;
-               
-               simasel->dirsli_lines = (simasel->dsdh / IMALINESIZE);
-               simasel->dirsli_h  = 0;
-               
-               if (simasel->topdir < 0) simasel->topdir = 0;
-               if (simasel->topdir > (simasel->totaldirs - simasel->dirsli_lines) ) simasel->topdir = (simasel->totaldirs - simasel->dirsli_lines);
-               
-               if ( (simasel->totaldirs * IMALINESIZE) >= simasel->dsdh ){
-                       simasel->dirsli = 1;
-                       simasel->dirsli_sx = simasel->dssx+2;
-                       simasel->dirsli_ex = simasel->dsex-2;   
-                       
-                       simasel->dirsli_h   = (simasel->dsdh) * (float)simasel->dirsli_lines / (float)simasel->totaldirs;
-                       simasel->dirsli_ey  = simasel->dsey - 2;
-                       if (simasel->topdir) {
-                               rh = (simasel->dsdh - simasel->dirsli_h);
-                               simasel->dirsli_ey -= rh * (float)((float)simasel->topdir / (float)(simasel->totaldirs - simasel->dirsli_lines ));
-                       }
-                       
-                       if (simasel->dirsli_h < 4) simasel->dirsli_h = 4;
-                       
-               }else{
-                       simasel->topdir = 0;
-               }
-       }
-       
-       if (simasel->totalima){
-               /* there are images */
-               
-               ima = simasel->first_sel_ima;
-               
-               
-               boxperline      =   (simasel->feex - simasel->fesx) /  80;
-               if (boxperline) boxlines = 1 + (simasel->totalima / boxperline); else boxlines = 1;
-               boxlinesinview  =   (simasel->feey - simasel->fesy) / 100;
-               boxlinesleft    =   boxlines - boxlinesinview;
-               
-               if (boxlinesleft > 0){
-                       /* slider needed */
-                       
-                       simasel->slider_height = boxlinesinview / (float)(boxlines+1);
-                       simasel->slider_space  = 1.0 - simasel->slider_height;
-                       
-                       simasel->imasli_sx = simasel->fssx+1; 
-                       simasel->imasli_ex = simasel->fsex-1; 
-                       simasel->fsdh      = simasel->fsey -  simasel->fssy - 4;
-               
-                       simasel->imasli_h  = simasel->fsdh * simasel->slider_height;
-                       if (simasel->imasli_h < 6) simasel->imasli_h = 6;
-                       simasel->imasli_ey = simasel->fsey - 2 - (simasel->fsdh * simasel->slider_space * simasel->image_slider);
-                       
-                       simasel->imasli = 1;
-               
-               }else{
-                       simasel->image_slider = 0;
-                       simasel->imasli = 0;
-               }
-               
-               sc = simasel->image_slider * (boxlinesleft * 100);
-               
-               simasel->curimax = simasel->fesx + 8;
-               simasel->curimay = simasel->feey - 90 + sc;
-               
-               dm = 1;
-               if (simasel->curimay-2  < simasel->fesy) dm = 0;
-               // let first row of icons remain selectable
-               if(OLD_IMASEL) if (simasel->curimay+80 > simasel->feey) dm = 0;
-               if (simasel->curimax+72 > simasel->feex) dm = 0;
-               
-               simasel->total_selected = 0;
-               while (ima){
-                       ima->draw_me = dm;
-                       
-                       if (ima->selected) simasel->total_selected++;
-       
-                       ima->sx = simasel->curimax;
-                       ima->sy = simasel->curimay+16;
-                       
-                       ima->ex = ima->sx + ima->dw;
-                       ima->ey = ima->sy + ima->dh;
-                       
-                       simasel->curimax += 80;
-                       if (simasel->curimax + 72 > simasel->feex){
-                               
-                               simasel->curimax  = simasel->fesx + 8;
-                               simasel->curimay -= 100;
-                               
-                               dm = 1;
-                               // let icons that fall off (top/bottom) be selectable
-                               if(OLD_IMASEL) {
-                                       if (simasel->curimay+80 > simasel->feey) dm = 0;
-                                       if (simasel->curimay-8  < simasel->fesy) dm = 0;
-                               }
-                               
-                       }
-                       ima = ima->next;
+       if (shortened) {
+               int slen = strlen(string);
+               if (slen > 3) {
+                       BLI_strncpy(string+slen-3, "...", 4);                           
                }
        }
+       return sw;
 }
 
-static void str_image_type(int ftype, char *name)
+static void draw_file(SpaceImaSel *simasel, short sx, short sy, struct direntry *file)
 {
-       strcpy(name, "");
-       
-       if((ftype & JPG_MSK) == JPG_STD) strcat(name, "std ");
-       if((ftype & JPG_MSK) == JPG_VID) strcat(name, "video ");
-       if((ftype & JPG_MSK) == JPG_JST) strcat(name, "amiga ");
-       if((ftype & JPG_MSK) == JPG_MAX) strcat(name, "max ");
-       
-       if( ftype == AN_hamx)   { strcat(name, "hamx "); return; }
+       short soffs;
+       char fname[FILE_MAXFILE];
+       float sw;
+
+       BLI_strncpy(fname,file->relname, FILE_MAXFILE);
+       sw = shorten_string(simasel, fname, simasel->prv_w );
+       soffs = (simasel->prv_w + TILE_BORDER_X*4 - sw) / 2;    
        
-       if( ftype == IMAGIC )   { strcat(name, "sgi ");  return; }
-       if( ftype & JPG )       { strcat(name, "jpeg ");  }
-       if( ftype & TGA )       { strcat(name, "targa "); }
-       if( ftype & PNG )       { strcat(name, "png "); }
-       if( ftype & BMP )       { strcat(name, "bmp "); }
-       if( ftype & AMI )       { strcat(name, "iff ");   }
-#ifdef WITH_QUICKTIME
-       if( ftype & QUICKTIME ) { strcat(name, "quicktime "); }
+       ui_rasterpos_safe(sx+soffs, sy - simasel->prv_h - TILE_BORDER_Y*2 - U.fontsize, simasel->aspect);
+#ifdef WIN32
+       BIF_DrawString(simasel->curfont, fname, ((U.transopts & USER_TR_MENUS) | CONVERT_TO_UTF8));
+#else
+       BIF_DrawString(simasel->curfont, fname, (U.transopts & USER_TR_MENUS));
 #endif
 }
 
-void draw_sima_area(SpaceImaSel *simasel)
-{              
-       uiBlock *block;
-       OneSelectableIma *ima;
-       ImaDir      *direntry;
-       float col[3];
-       int   i, info;
-       short sx, sy, ex, ey, sc;
-       char naam[256], infostr[256];
-       
-       BIF_GetThemeColor3fv(TH_BACK, col);
-       glClearColor(col[0], col[1], col[2], 0.0);
-       glClear(GL_COLOR_BUFFER_BIT);
-       
-       sprintf(naam, "win %d", curarea->win);
-       block= uiNewBlock(&curarea->uiblocks, naam, UI_EMBOSS, UI_HELV, curarea->win);
-       uiBlockSetCol(block, TH_BUT_SETTING1);
-       
-       if (simasel->desx >  0){
-               /*  DIR ENTRYS */
-               BIF_ThemeColorShade(TH_SHADE1, -70);
-               glRecti(simasel->dssx,  simasel->dssy,  simasel->dsex,  simasel->dsey);
-               glRecti(simasel->desx,  simasel->desy,  simasel->deex,  simasel->deey);
-       
-               uiEmboss(simasel->dssx, simasel->dssy, simasel->dsex, simasel->dsey,1);
-               uiEmboss(simasel->desx, simasel->desy, simasel->deex, simasel->deey,1);
+static void draw_imasel_bookmarks(ScrArea *sa, SpaceImaSel *simasel)
+{
+       char bookmark[FILE_MAX];
+       float sw;
+
+       if (simasel->flag & FILE_BOOKMARKS) {
+               int nentries = fsmenu_get_nentries();
+               int i;
+               short sx, sy;
+               int bmwidth;
+               int linestep = U.fontsize*3/2;
                
-               if (simasel->dirsli == 1) {
-                       sx = simasel->dirsli_sx+2;
-                       sy = simasel->dirsli_ey - simasel->dirsli_h+2;
-                       ex = simasel->dirsli_ex-2;
-                       ey = simasel->dirsli_ey-2;
+               sx = simasel->bookmarkrect.xmin + TILE_BORDER_X;
+               sy = simasel->bookmarkrect.ymax - TILE_BORDER_Y - linestep;
+               bmwidth = simasel->bookmarkrect.xmax - simasel->bookmarkrect.xmin - 2*TILE_BORDER_X;
+               
+               if (bmwidth < 0) return;
+
+               for (i=0; i< nentries && sy > linestep ;++i) {
+                       char *fname = fsmenu_get_entry(i);
+                       char *sname = NULL;
                        
-                       BIF_ThemeColor(TH_SHADE1); 
+                       if (fname) {
+                               int sl;
+                               BLI_strncpy(bookmark, fname, FILE_MAX);
                        
-                       glRecti(sx,  sy,  ex,  ey);
-                       uiEmboss(sx, sy, ex,ey,0);
-               }
-               if (simasel->totaldirs) {
-                       sx = simasel->desx+8;
-                       sy = simasel->deey-IMALINESIZE;
-                       
-                       direntry = simasel->firstdir; 
-                       if (simasel->topdir){
-                               for(i = simasel->topdir; i>0; i--){
-                                       direntry = direntry->next;
+                               sl = strlen(bookmark)-1;
+                               if (bookmark[sl] == '\\' || bookmark[sl] == '/') {
+                                       bookmark[sl] = '\0';
+                                       sl--;
                                }
-                       }
-                       viewgate(simasel->desx, simasel->desy, simasel->deex-4, simasel->deey);
-                       
-                       i = simasel->dirsli_lines;
-                       if (i > simasel->totaldirs) i = simasel->totaldirs;
-                       for(;i > 0; i--){
-                               strcpy(naam,  direntry->name);
-                               
-                               cpack(0xFFFFFF);
-                               if (direntry->selected == 1){
-                                       cpack(0x7777CC);
-                                       glRecti(simasel->desx+2,  sy-4,  simasel->deex-4,  sy+IMALINESIZE-4);
-                                       cpack(0xFFFFFF);
+                               while (sl) {
+                                       if (bookmark[sl] == '\\' || bookmark[sl] == '/'){
+                                               sl++;
+                                               break;
+                                       };
+                                       sl--;
                                }
-                               if (direntry->hilite == 1){
-                                       cpack(0x999999);
-                                       glRecti(simasel->desx+2,  sy-4,  simasel->deex-4,  sy+IMALINESIZE-4);
-                                       cpack(0xFFFFFF);
+                               sname = &bookmark[sl];
+                               sw = shorten_string(simasel, sname, bmwidth);
+                               if (simasel->active_bookmark == i ) {
+                                       BIF_ThemeColor(TH_TEXT_HI);
+                               } else {
+                                       BIF_ThemeColor(TH_TEXT);
                                }
-                               
-                               glRasterPos2i(sx,  sy);
-                               BMF_DrawString(G.font, naam);
-                               
-                               direntry = direntry->next;
-                               sy-=IMALINESIZE;
+                               ui_rasterpos_safe(sx, sy, simasel->aspect);
+#ifdef WIN32
+                               BIF_DrawString(simasel->curfont, sname, ((U.transopts & USER_TR_MENUS) | CONVERT_TO_UTF8));
+#else
+                               BIF_DrawString(simasel->curfont, sname, (U.transopts & USER_TR_MENUS));
+#endif
+                               sy -= linestep;
+                       } else {
+                               cpack(0xB0B0B0);
+                               sdrawline(sx,  sy + U.fontsize/2 ,  sx + bmwidth,  sy + U.fontsize/2); 
+                               cpack(0x303030);                                
+                               sdrawline(sx,  sy + 1 + U.fontsize/2 ,  sx + bmwidth,  sy + 1 + U.fontsize/2);
+                               sy -= linestep;
                        }
-                       areaview();
-                       
-               }
-               
-               /* status icons */
-               
-               sx = simasel->desx;
-               sy = simasel->deey+6;
-               
-               if (bitset(simasel->fase, IMS_FOUND_BIP)) {
-                       BIF_icon_draw(sx+16*0, sy, ICON_BPIBFOLDER_HLT);
-               } else if (bitset(simasel->fase, IMS_WRITE_NO_BIP)) {
-                       BIF_icon_draw(sx+16*0, sy, ICON_BPIBFOLDER_DEHLT);
-               } else {
-                       BIF_icon_draw(sx+16*0, sy, ICON_BPIBFOLDER_DEHLT);
                }
 
-               if (bitset(simasel->fase, IMS_KNOW_INF)) {
-                       BIF_icon_draw(sx+16*1, sy, ICON_FOLDER_HLT);
+               uiEmboss(simasel->bookmarkrect.xmin, simasel->bookmarkrect.ymin, simasel->bookmarkrect.xmax-1, simasel->bookmarkrect.ymax-1, 1);
+       }
+}
+
+static void draw_imasel_previews(ScrArea *sa, SpaceImaSel *simasel)
+{
+       static double lasttime= 0;
+       struct FileList* files = simasel->files;
+       int numfiles;
+       struct direntry *file;
+       int numtiles;
+       
+       int tilewidth = simasel->prv_w + TILE_BORDER_X*4;
+       int tileheight = simasel->prv_h + TILE_BORDER_Y*4 + U.fontsize;
+       short sx, sy;
+       int do_load = 1;
+       
+       ImBuf* imb=0;
+       int i,j;
+       short type;
+       int colorid = 0;
+       int todo;
+       int fileoffset, rowoffset, columnoffset;
+       float scrollofs;
+       
+
+       rcti viewrect = simasel->viewrect;
+
+       if (!files) return;
+       /* Reload directory */
+       BLI_strncpy(simasel->dir, BIF_filelist_dir(files), FILE_MAXDIR);        
+       
+       type = BIF_filelist_gettype(simasel->files);    
+       
+       if (BIF_filelist_empty(files))
+       {
+               unsigned int filter = 0;
+               BIF_filelist_hidedot(simasel->files, simasel->flag & FILE_HIDE_DOT);
+               if (simasel->flag & FILE_FILTER) {
+                       filter = simasel->filter ;
                } else {
-                       BIF_icon_draw(sx+16*1, sy, ICON_FOLDER_DEHLT);
+                       filter = 0;
                }
+
+               BIF_filelist_setfilter(simasel->files, filter);
+               BIF_filelist_readdir(files);
                
-               if (bitset(simasel->fase, IMS_KNOW_IMA)) {
-                       BIF_icon_draw(sx+16*2, sy, ICON_BLUEIMAGE_HLT);
-               } else {
-                       BIF_icon_draw(sx+16*2, sy, ICON_BLUEIMAGE_DEHLT);
-               }
+               if(simasel->sort!=FILE_SORTALPHA) BIF_filelist_sort(simasel->files, simasel->sort);             
        }
-       
-       if (simasel->fesx >  0) {
-               int extrabutsize;
-               
-               BIF_ThemeColorShade(TH_SHADE1, -80);
 
-               glRecti(simasel->fssx,  simasel->fssy,  simasel->fsex,  simasel->fsey);
+       BIF_filelist_imgsize(simasel->files,simasel->prv_w,simasel->prv_h);
 
-               glRecti(simasel->fesx,  simasel->fesy,  simasel->feex,  simasel->feey);
+       numfiles = BIF_filelist_numfiles(files);
+       numtiles = simasel->numtilesx*simasel->numtilesy;
 
-               uiEmboss(simasel->fssx-1, simasel->fssy-1, simasel->fsex+1, simasel->fsey+1,1);
-               uiEmboss(simasel->fesx-1, simasel->fesy-1, simasel->feex+1, simasel->feey+1,1);
-               
-               if (simasel->imasli == 1){
-                       sx = simasel->imasli_sx;
-                       sy = simasel->imasli_ey - simasel->imasli_h;
-                       ex = simasel->imasli_ex;
-                       ey = simasel->imasli_ey;
-                       
-                       BIF_ThemeColor(TH_SHADE1); 
+       if (numtiles > numfiles) numtiles = numfiles;
+       
+       todo = 0;
+       if (lasttime < 0.001) lasttime = PIL_check_seconds_timer();
 
-                       glRecti(sx,  sy,  ex,  ey);
-                       uiEmboss(sx, sy, ex, ey, 1);
-               }
        
-               info = 0;
-               strcpy(infostr, "");
-               if (simasel->totalima){
-                       viewgate(simasel->fesx, simasel->fesy, simasel->feex, simasel->feey);
-               
-                       ima = simasel->first_sel_ima;
-                       
-                       while (ima){
-                               sc = 0;
-                               
-                               sx = ima->sx- 6; sy = ima->sy-20 + sc; 
-                               ex = ima->sx+71; ey = ima->sy+70 + sc;  
-                               
-                               if(ima->selected == 1){
-                                       cpack(0xCC6666);
-                                       glRecti(sx, sy,  ex, ey);
-                               }
-                               if(ima->selectable == 1){
-                                       if (ima->selected ) cpack(0xEE8888); else cpack(0x999999);
-                                       
-                                       if (((simasel->mode & 8) != 8) && (simasel->hilite_ima == ima)){
-                                               glRecti(sx, sy,  ex, ey); uiEmboss(sx,sy, ex,ey, 1);
-                                       }
-                                       if (ima->disksize/1000 > 1000){ sprintf(infostr,  "%s  %.2fMb  x%i y%i  %i bits ",ima->file_name,(ima->disksize/1024)/1024.0, ima->orgx, ima->orgy, ima->orgd);
-                                       }else{ sprintf(infostr,  "%s  %dKb  %ix%i  %i bits ",  ima->file_name,ima->disksize/1024,          ima->orgx, ima->orgy, ima->orgd);
-                                       }       
-                                       if (ima->anim == 1){ strcat (infostr, "movie"); }else{
-                                               str_image_type(ima->ibuf_type, naam);
-                                               strcat (infostr, naam);
-                                       }
-                                       info = 1;
+       if (simasel->numtilesx > 0) {
+               /* calculate the offset to start drawing */
+               if ((numtiles < numfiles) && (simasel->scrollarea > 0)) {
+                       fileoffset = numfiles*( (simasel->scrollpos) / simasel->scrollarea) + 0.5;              
+               } else {
+                       fileoffset = 0;
+               }
+               rowoffset = (fileoffset / simasel->numtilesx)*simasel->numtilesx;
+               columnoffset = fileoffset % simasel->numtilesx;
+               scrollofs = (float)tileheight*(float)columnoffset/(float)simasel->numtilesx;
+       } else {
+               rowoffset = 0;
+               scrollofs = 0;
+       }
+       /* add partially visible row */
+       numtiles += simasel->numtilesx;
+       for (i=rowoffset, j=0 ; (i < numfiles) && (j < numtiles); ++i, ++j)
+       {
+               sx = simasel->v2d.cur.xmin + viewrect.xmin + (j % simasel->numtilesx)*tilewidth;
+               sy = simasel->v2d.cur.ymin + viewrect.ymax + (short)scrollofs - (viewrect.ymin + (j / simasel->numtilesx)*tileheight);
+
+               file = BIF_filelist_file(files, i);                             
+
+               if (simasel->active_file == i) {
+                       colorid = TH_ACTIVE;
+                       draw_tile(simasel, sx, sy, colorid);
+               } else if (file->flags & ACTIVE) {
+                       colorid = TH_HILITE;
+                       draw_tile(simasel, sx, sy, colorid);
+               } else {
+                       /*
+                       colorid = TH_PANEL;
+                       draw_tile(simasel, sx, sy, colorid);
+                       */
+               }
+
+               if ( type == FILE_MAIN) {
+                       ID *id;
+                       int icon_id = 0;
+                       int idcode;
+                       idcode= BIF_groupname_to_code(simasel->dir);
+                       if (idcode == ID_MA || idcode == ID_TE || idcode == ID_LA || idcode == ID_WO || idcode == ID_IM) {
+                               id = (ID *)file->poin;
+                               icon_id = BKE_icon_getid(id);
+                       }               
+                       if (icon_id) {
+                               glEnable(GL_BLEND);
+                               glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+                               if (do_load) {
+                                       BIF_icon_draw_preview(sx+2*TILE_BORDER_X, sy-simasel->prv_w-TILE_BORDER_X, icon_id, 0);                 
+                               } else {
+                                       BIF_icon_draw_preview(sx+2*TILE_BORDER_X, sy-simasel->prv_w-TILE_BORDER_X, icon_id, 1);
+                                       todo++;
                                }
                                
-                               sx = ima->sx; sy = ima->sy + sc;
-                               ex = ima->ex; ey = ima->ey + sc;
-                               
-                               if (ima->anim == 0) BIF_ThemeColorShade(TH_SHADE1, -80);
-                               else BIF_ThemeColorShade(TH_SHADE1, -70);
-                               
-                               glRecti(sx, sy,  ex, ey);
-                               uiEmboss(sx-1,sy-1, ex+1,ey+1, 1);
-                               
-                               cpack(0);
-                               strcpy(naam, ima->file_name);
-                               naam[11] = 0;
-                       
-                               glRasterPos2i(sx+32-BMF_GetStringWidth(G.fonts, naam) / 2  ,  sy-16);
-                               BMF_DrawString(G.fonts, naam);
-                               
-                               if ((ima) && (ima->pict) && (ima->pict->rect)){
-                                       if ( (ey > simasel->fesy) && (sy < simasel->feey)){
-                                               if(OLD_IMASEL) {
-                                                       lrectwrite(sx, sy, ex-1, ey-1, ima->pict->rect);
-                                               } else
-                                                       rectwrite_imasel(simasel->fesx, simasel->fesy,
-                                                               curarea->winrct.xmax, curarea->winrct.ymax - 64, //simasel->feey*1.5,
-                                                               sx, sy, ima->pict->x, ima->pict->y, 1.0, 1.0, ima->pict->rect);
-                                       }
+                               glDisable(GL_BLEND);
+                       }               
+               }
+               else {
+                       if ( (file->flags & IMAGEFILE) || (file->flags & MOVIEFILE))
+                       {
+                               if (do_load) {                                  
+                                       BIF_filelist_loadimage(simasel->files, i);                              
+                               } else {
+                                       todo++;
                                }
-                       
-                               ima = ima->next;
+                               imb = BIF_filelist_getimage(simasel->files, i);
+                       } else {
+                               imb = BIF_filelist_getimage(simasel->files, i);
                        }
-                       
-                       if ((simasel->mode & 8) == 8) {  /* if magnify */
-                               
-                               if (bitset(simasel->fase, IMS_KNOW_IMA) && (simasel->hilite_ima)) {
-                       
-                                       ima = simasel->hilite_ima;
-                                       glPixelZoom(2.0,  2.0);
-                                       
-                                       sx = ima->sx + (ima->ex - ima->sx)/2 - (ima->ex - ima->sx);
-                                       sy = ima->sy + (ima->ey - ima->sy)/2 - (ima->ey - ima->sy);
-                                       
-                                       ex = sx + 2*(ima->ex - ima->sx);
-                                       ey = sy + 2*(ima->ey - ima->sy);
-                                       
-                                       uiEmboss(sx-1,sy-1, ex+1,ey+1, 0);
-                               
-                                       if(OLD_IMASEL) {
-                                               lrectwrite(sx, sy, sx+ (ima->ex - ima->sx)-1, sy+ (ima->ey - ima->sy)-1, ima->pict->rect);
-                                       } else
-                                               rectwrite_imasel(simasel->fesx, simasel->fesy,
-                                                       curarea->winrct.xmax, curarea->winrct.ymax - 64, //simasel->feey*1.5,
-                                                       sx, sy, ima->pict->x, ima->pict->y, 2.0, 2.0, ima->pict->rect);
+
+                       if (imb) {              
+                                       float fx = ((float)simasel->prv_w - (float)imb->x)/2.0f;
+                                       float fy = ((float)simasel->prv_h - (float)imb->y)/2.0f;
+                                       short dx = (short)(fx + 0.5f);
+                                       short dy = (short)(fy + 0.5f);
                                        
-                                       glPixelZoom(1.0,  1.0);
+                                       glEnable(GL_BLEND);
+                                       glBlendFunc(GL_SRC_ALPHA,  GL_ONE_MINUS_SRC_ALPHA);                                                                                                     
+                                       // glaDrawPixelsSafe((float)sx+8 + dx, (float)sy - imgwidth + dy - 8, imb->x, imb->y, imb->x, GL_RGBA, GL_UNSIGNED_BYTE, imb->rect);
+                                       glColor4f(1.0, 1.0, 1.0, 1.0);
+                                       glaDrawPixelsTex((float)sx+2*TILE_BORDER_X + dx, (float)sy - simasel->prv_h + dy - 2*TILE_BORDER_Y, imb->x, imb->y,GL_UNSIGNED_BYTE, imb->rect);
+                                       // glDisable(GL_BLEND);
+                                       imb = 0;
+                       }                       
+               }               
+
+               if (type == FILE_MAIN) {
+                       glColor3f(1.0f, 1.0f, 1.0f);                    
+               }
+               else {
+                       if (S_ISDIR(file->type)) {
+                               glColor3f(1.0f, 1.0f, 0.9f);
+                       }
+                       else if (file->flags & IMAGEFILE) {
+                               BIF_ThemeColor(TH_SEQ_IMAGE);
+                       }
+                       else if (file->flags & MOVIEFILE) {
+                               BIF_ThemeColor(TH_SEQ_MOVIE);
+                       }
+                       else if (file->flags & BLENDERFILE) {
+                               BIF_ThemeColor(TH_SEQ_SCENE);
+                       }
+                       else {
+                               if (simasel->active_file == i) {
+                                       BIF_ThemeColor(TH_GRID); /* grid used for active text */
+                               } else if (file->flags & ACTIVE) {
+                                       BIF_ThemeColor(TH_TEXT_HI);                     
+                               } else {
+                                       BIF_ThemeColor(TH_TEXT);
                                }
                        }
-                       areaview();  /*  reset viewgate */
                }
-               
-               
-               /* INFO */
-               if (simasel->infsx > 0){
-                       BIF_ThemeColorShade(TH_SHADE1, -80);
-
-                       glRecti(simasel->infsx,  simasel->infsy,  simasel->infex,  simasel->infey);
-                       uiEmboss(simasel->infsx, simasel->infsy, simasel->infex, simasel->infey,1);
-               
-                       if ((info)&&(strlen(infostr) > 0)){
-                               
-                               sx = curarea->winrct.xmin;
-                               sy = curarea->winrct.ymin;
-                               
-                               viewgate(simasel->infsx, simasel->infsy, simasel->infex, simasel->infey);
                        
-                               cpack(0xAAAAAA);
-                               glRasterPos2i(simasel->infsx+4,  simasel->infsy+6);
-                               BMF_DrawString(G.font, infostr);
-                               
-                               areaview();  /*  reset viewgate */
-       
-                       }
-               }
-
-               extrabutsize= (simasel->returnfunc)?60:0;
-               if (simasel->dnw > extrabutsize+8) {
-                       simasel->dnw-= extrabutsize;
-                       uiDefBut(block, TEX, 1,"", simasel->dnsx, simasel->dnsy, simasel->dnw, simasel->dnh, simasel->dir,  0.0, (float)FILE_MAXFILE-1, 0, 0, "");
-                       if (extrabutsize)
-                               uiDefBut(block, BUT, 5, "Load", simasel->dnsx+simasel->dnw, simasel->dnsy, extrabutsize, 21, NULL, 0.0, 0.0, 0, 0, "Load the selected image");
-               }
-               if (simasel->fnw > extrabutsize+8) {
-                       simasel->fnw-= extrabutsize;
-                       uiDefBut(block, TEX, 2,"", simasel->fnsx, simasel->fnsy, simasel->fnw, simasel->fnh, simasel->file, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
-                       if (extrabutsize)
-                               uiDefBut(block, BUT, 6, "Cancel",       simasel->fnsx+simasel->fnw, simasel->fnsy, extrabutsize, 21, NULL, 0.0, 0.0, 0, 0, "Cancel image loading");
+               draw_file(simasel, sx, sy, file);
+               
+               if(do_load && (PIL_check_seconds_timer() - lasttime > 0.3)) {
+                       lasttime= PIL_check_seconds_timer();
+                       do_load = 0;
                }
        }
-       
-       if (curarea->winx > 16) {
-               char *menu= fsmenu_build_menu();
-
-               uiDefBut(block, BUT, 13, "P", 8, (short)(curarea->winy-29), 20, 21, 0, 0, 0, 0, 0, "");
-               uiDefButS(block, MENU, 3 , menu, 8, (short)(curarea->winy-58), 20, 21, &simasel->fileselmenuitem, 0, 0, 0, 0, "");
 
-               MEM_freeN(menu);
-       }
-       
-       uiDrawBlock(block);
+       if (!do_load && todo > 0) /* we broke off loading */
+               addafterqueue(sa->win, RENDERPREVIEW, 1);
 }
 
-void select_ima_files(SpaceImaSel *simasel)
+
+/* in panel space! */
+static void imasel_imgdraw(ScrArea *sa, uiBlock *block)
 {
-       short set_reset;
-       short mval[2], oval[2];
-       
-       set_reset =  1 - (simasel->hilite_ima->selected);
-       
-       getmouseco_areawin(mval);
-       oval[0] = mval[0] + 1;
-       oval[1] = 0; /* Just give it a value to stop warnings */
-       
-       while(get_mbut()&R_MOUSE) { 
-               getmouseco_areawin(mval);
-               if ((oval[0] != mval[0]) || (oval[1] != mval[1])){
-                       simasel->mx = mval[0];
-                       simasel->my = mval[1];
-                       
-                       calc_hilite(simasel);
-                       
-                       if (simasel->hilite_ima){
-                               simasel->hilite_ima->selected = set_reset;
-                               scrarea_do_windraw(curarea);
-                               screen_swapbuffers();   
+       SpaceImaSel *simasel= sa->spacedata.first;
+       rctf dispf;
+       rcti winrect;
+       struct direntry *file;
+       char path[FILE_MAX];
+       float tsize;
+       short ofsx=0;
+       short ofsy=0;
+       short ex, ey;
+       float scaledx, scaledy;
+       int index;      
+
+       BLI_init_rctf(&dispf, 0.0f, (block->maxx - block->minx)-0.0f, 0.0f, (block->maxy - block->miny)-0.0f);
+       ui_graphics_to_window_rct(sa->win, &dispf, &winrect);
+
+       if (!simasel->img) {
+               BLI_join_dirfile(path, simasel->dir, simasel->file);
+               if (!BLI_exists(path))
+                       return;
+       
+               index = BIF_filelist_find(simasel->files, simasel->file);
+               if (index >= 0) {
+                       file = BIF_filelist_file(simasel->files,index);
+                       if (file->flags & IMAGEFILE || file->flags & MOVIEFILE) {
+                               simasel->img = IMB_loadiffname(path, IB_rect);
+
+                               if (simasel->img) {
+                                       tsize = MIN2(winrect.xmax - winrect.xmin,winrect.ymax - winrect.ymin);
+                                       
+                                       if (simasel->img->x > simasel->img->y) {
+                                               scaledx = (float)tsize;
+                                               scaledy =  ( (float)simasel->img->y/(float)simasel->img->x )*tsize;
+                                               ofsy = (scaledx - scaledy) / 2.0;
+                                               ofsx = 0;
+                                       }
+                                       else {
+                                               scaledy = (float)tsize;
+                                               scaledx =  ( (float)simasel->img->x/(float)simasel->img->y )*tsize;
+                                               ofsx = (scaledy - scaledx) / 2.0;
+                                               ofsy = 0;
+                                       }
+                                       ex = (short)scaledx;
+                                       ey = (short)scaledy;
+
+                                       IMB_scaleImBuf(simasel->img, ex, ey);
+                               }
                        }
-                       oval[0] = mval[0];
-                       oval[1] = mval[1];
                }
        }
+       if (simasel->img == NULL) 
+               return;
+       if(simasel->img->rect==NULL)
+               return;
+
+       /* correction for gla draw */
+       BLI_translate_rcti(&winrect, -curarea->winrct.xmin, -curarea->winrct.ymin);
+               
+       glaDefine2DArea(&sa->winrct);
+       glaDrawPixelsSafe(winrect.xmin+ofsx, winrect.ymin+ofsy, simasel->img->x, simasel->img->y, simasel->img->x, GL_RGBA, GL_UNSIGNED_BYTE, simasel->img->rect);      
 }
 
-void move_imadir_sli(SpaceImaSel *simasel)
+static void imasel_panel_image(ScrArea *sa, short cntrl)
 {
-       
-       short mval[2], lval[2], fh;
-       float rh;
-       
-       getmouseco_areawin(mval);
-       
-       if ((mval[0] > simasel->dirsli_sx) && 
-           (mval[0] < simasel->dirsli_ex) && 
-               (mval[1] > simasel->dirsli_ey - simasel->dirsli_h) &&
-               (mval[1] < simasel->dirsli_ey) ){
-               
-               /*  extactly in the slider  */
-               fh = simasel->dirsli_ey - mval[1];
-               lval[1]=1;
-               while(get_mbut()&L_MOUSE) { 
-                       getmouseco_areawin(mval);
-                       if (mval[1] != lval[1]){
-                               
-                               rh = (float)(simasel->dsey - mval[1] - fh - simasel->dssy) / (simasel->dsdh - simasel->dirsli_h);
-                               
-                               simasel->topdir = 1 + rh * (simasel->totaldirs - simasel->dirsli_lines);
-                               
-                               scrarea_do_windraw(curarea);
-                               uiEmboss(simasel->dirsli_sx, simasel->dirsli_ey - simasel->dirsli_h, 
-                                                  simasel->dirsli_ex, simasel->dirsli_ey,1);
-                           screen_swapbuffers();
-                               lval[1] = mval[1];
-                       }
-               }       
-       }else{
-               if (mval[1] < simasel->dirsli_ey - simasel->dirsli_h)
-                       simasel->topdir += (simasel->dirsli_lines - 1); 
-               else
-                       simasel->topdir -= (simasel->dirsli_lines - 1); 
-                       
-               while(get_mbut()&L_MOUSE) {  }
+       uiBlock *block;
+       SpaceImaSel *simasel= sa->spacedata.first;
+       short w = 300;
+       short h = 300;
+       short offsx, offsy;
+
+       if (simasel->img) {
+               w = simasel->img->x;
+               h = simasel->img->y;
        }
+       
+       offsx = -150 + (simasel->v2d.mask.xmax - simasel->v2d.mask.xmin)/2;
+       offsy = -150 + (simasel->v2d.mask.ymax - simasel->v2d.mask.ymin)/2;
+
+       block= uiNewBlock(&curarea->uiblocks, "imasel_panel_image", UI_EMBOSS, UI_HELV, curarea->win);
+       uiPanelControl(UI_PNL_SOLID | UI_PNL_CLOSE | cntrl);
+       uiSetPanelHandler(IMASEL_HANDLER_IMAGE);  // for close and esc
+       if(uiNewPanel(curarea, block, "Image Preview", "Image Browser", offsx, offsy, w, h)==0) 
+               return;
+       uiBlockSetDrawExtraFunc(block, imasel_imgdraw); 
 }
 
-void move_imafile_sli(SpaceImaSel *simasel)
+static void imasel_blockhandlers(ScrArea *sa)
 {
-       short mval[2], cmy, omy = 0;
-       short ssl, sdh, ssv;
-       
-       getmouseco_areawin(mval);
-       cmy = mval[1];
-       
-       if ((mval[0] > simasel->imasli_sx) && 
-           (mval[0] < simasel->imasli_ex) && 
-               (mval[1] > simasel->imasli_ey - simasel->imasli_h) &&
-               (mval[1] < simasel->imasli_ey) ){
+       SpaceImaSel *simasel= sa->spacedata.first;
+       short a;
                
-               ssv = simasel->fsey - simasel->imasli_ey - 2;
+       for(a=0; a<SPACE_MAXHANDLER; a+=2) {
+               switch(simasel->blockhandler[a]) {
+
+               case IMASEL_HANDLER_IMAGE:
+                       imasel_panel_image(sa, simasel->blockhandler[a+1]);
+                       break;
                
-               while(get_mbut() & L_MOUSE) { 
-                       getmouseco_areawin(mval);
-                       if (mval[1] != omy){
-                               sdh = simasel->fsdh - simasel->imasli_h;
-                               ssl = cmy -  mval[1] + ssv;
-                               
-                               if (ssl < 0)   { ssl = 0; }
-                               if (ssl > sdh) { ssl = sdh; }
-                               
-                               simasel->image_slider = ssl / (float)sdh;
-                               
-                               scrarea_do_windraw(curarea);
-                               uiEmboss(simasel->imasli_sx, simasel->imasli_ey - simasel->imasli_h, 
-                                                  simasel->imasli_ex, simasel->imasli_ey, 1);
-                          
-                               screen_swapbuffers();
-                               omy = mval[1];
-                       }
                }
-       }else{
-               while(get_mbut() & L_MOUSE) {  }
+               /* clear action value for event */
+               simasel->blockhandler[a+1]= 0;
        }
+       uiDrawBlocksPanels(sa, 0);
 }
 
-void ima_select_all(SpaceImaSel *simasel)
+
+static void draw_imasel_buttons(ScrArea *sa, SpaceImaSel* simasel)
 {
-       OneSelectableIma *ima;
-       int reselect = 0;
-       
-       ima = simasel->first_sel_ima;
-       if (!ima) return;
-       
-       while(ima){
-               if (ima->selected == 1) reselect = 1;
-               ima = ima->next;
-       }
-       ima = simasel->first_sel_ima;
-       if (reselect == 1){
-               while(ima){
-                       ima->selected = 0;
-                       ima = ima->next;
-               }
-       }else{
-               while(ima){
-                       ima->selected = 1;
-                       ima = ima->next;
+       uiBlock *block;
+       int loadbutton;
+       char name[20];
+       char *menu;
+       float slen;
+       float parentbut_width = 20;
+       float bookmarkbut_width = 0.0f;
+       int filebuty1, filebuty2;
+
+       float xmin = simasel->v2d.mask.xmin + 10;
+       float xmax = simasel->v2d.mask.xmax - 10;
+
+       filebuty1= simasel->v2d.mask.ymax - IMASEL_BUTTONS_HEIGHT;
+       filebuty2= filebuty1+IMASEL_BUTTONS_HEIGHT/2 -6;
+
+       /* HEADER */
+       sprintf(name, "win %d", sa->win);
+       block = uiNewBlock(&sa->uiblocks, name, UI_EMBOSS, UI_HELV, sa->win);
+       
+       uiSetButLock( BIF_filelist_gettype(simasel->files)==FILE_MAIN && simasel->returnfunc, NULL); 
+
+       /* space available for load/save buttons? */
+       slen = BIF_GetStringWidth(G.font, simasel->title, simasel->aspect);
+       loadbutton= slen > 60 ? slen + 20 : 80; /* MAX2(80, 20+BIF_GetStringWidth(G.font, simasel->title)); */
+       if(simasel->v2d.mask.xmax-simasel->v2d.mask.xmin > loadbutton+20) {
+               if(simasel->title[0]==0) {
+                       loadbutton= 0;
                }
        }
-}
+       else {
+               loadbutton= 0;
+       }
 
-void pibplay(SpaceImaSel *simasel)
-{
-       OneSelectableIma *ima;
-       int sx= 8, sy= 8;
-       
-       ima = simasel->first_sel_ima;
-       if (!ima) return ;
-       
-       sx = curarea->winrct.xmin + 8; 
-       sy = curarea->winrct.ymin + 8;
-       
-       while(!(get_mbut()&L_MOUSE)){
-               scrarea_do_windraw(curarea);     
-               
-               lrectwrite(sx, sy, sx+ima->dw-1, sy+ima->dh-1, ima->pict->rect);
-               
-               ima = ima->next;
-               if (!ima) ima = simasel->first_sel_ima;
-               screen_swapbuffers();   
+       menu= fsmenu_build_menu();
+
+       if (menu[0]) {
+               bookmarkbut_width = parentbut_width;
+       }
+
+       uiDefBut(block, TEX, B_FS_FILENAME,"",  xmin+parentbut_width+bookmarkbut_width+2, filebuty1, xmax-xmin-loadbutton-parentbut_width-bookmarkbut_width, 21, simasel->file, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
+       uiDefBut(block, TEX, B_FS_DIRNAME,"",   xmin+parentbut_width, filebuty2, xmax-xmin-loadbutton-parentbut_width, 21, simasel->dir, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
+
+       if(loadbutton) {
+               uiSetCurFont(block, UI_HELV);
+               uiDefBut(block, BUT,B_FS_LOAD, simasel->title,  xmax-loadbutton, filebuty2, loadbutton, 21, simasel->dir, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
+               uiDefBut(block, BUT,B_FS_CANCEL, "Cancel",              xmax-loadbutton, filebuty1, loadbutton, 21, simasel->file, 0.0, (float)FILE_MAXFILE-1, 0, 0, "");
        }
+
+       if(menu[0])     { // happens when no .Bfs is there, and first time browse
+               uiDefButS(block, MENU,B_FS_DIR_MENU, menu, xmin, filebuty1, parentbut_width, 21, &simasel->menu, 0, 0, 0, 0, "");
+               uiDefBut(block, BUT, B_FS_BOOKMARK, "B", xmin+22, filebuty1, bookmarkbut_width, 21, 0, 0, 0, 0, 0, "Bookmark current directory");
+       }
+       MEM_freeN(menu);
+
+       uiDefBut(block, BUT, B_FS_PARDIR, "P", xmin, filebuty2, parentbut_width, 21, 0, 0, 0, 0, 0, "Move to the parent directory (PKEY)");     
+
+       uiDrawBlock(block);
 }
 
 
@@ -860,65 +662,71 @@ void pibplay(SpaceImaSel *simasel)
 
 void drawimaselspace(ScrArea *sa, void *spacedata)
 {
-       SpaceImaSel *simasel;
-       simasel= curarea->spacedata.first;
+       float col[3];
+       SpaceImaSel *simasel= curarea->spacedata.first;
        
-       /* ortho: xmin xmax, ymin, ymax! */
-       myortho2(-0.375, (float)(curarea->winx)-0.375, -0.375, (float)(curarea->winy)-0.375);
+       BIF_GetThemeColor3fv(TH_BACK, col);
+       glClearColor(col[0], col[1], col[2], 0.0);
+       glClear(GL_COLOR_BUFFER_BIT);   
        
-       if (simasel->fase == 0){
-               BLI_cleanup_dir(G.sce, simasel->dir);
-               clear_ima_dir(simasel);
-       }
+       /* HACK: somehow when going fullscreen, v2d isn't set correctly */
+       simasel->v2d.cur.xmin= simasel->v2d.cur.ymin= 0.0f;
+       simasel->v2d.cur.xmax= sa->winx;
+       simasel->v2d.cur.ymax= sa->winy;        
+       simasel->v2d.tot= simasel->v2d.cur;
+       test_view2d(G.v2d, sa->winx, sa->winy);
 
-       if (!bitset(simasel->fase, IMS_KNOW_DIR)){
-               if(simasel->firstdir)   free_ima_dir(simasel->firstdir);
-               if(simasel->firstfile)  free_ima_dir(simasel->firstfile);
-               simasel->firstdir   = 0;
-               simasel->firstfile  = 0;
+       calc_imasel_rcts(simasel, sa->winx, sa->winy);
+
+       myortho2(simasel->v2d.cur.xmin, simasel->v2d.cur.xmax, simasel->v2d.cur.ymin, simasel->v2d.cur.ymax);
+       bwin_clear_viewmat(sa->win);    /* clear buttons view */
+       glLoadIdentity();
        
-               if (get_ima_dir(simasel->dir, IMS_DIR,  &simasel->totaldirs,  &simasel->firstdir) < 0){
-                       /* error */
-                       strcpy(simasel->dir, simasel->dor);
-                       get_ima_dir(simasel->dir, IMS_DIR,  &simasel->totaldirs,  &simasel->firstdir);
-               }
-               
-               if (get_ima_dir(simasel->dir, IMS_FILE, &simasel->totalfiles, &simasel->firstfile) < 0){
-                       /* error */
-                       strcpy(simasel->file, simasel->fole);
-                       get_ima_dir(simasel->dir, IMS_FILE, &simasel->totalfiles, &simasel->firstfile);
-               }
-               
-               simasel->topdir  = 0;
-               simasel->topfile = 0;
-               simasel->fase |= IMS_KNOW_DIR;
-               
-               check_for_pib(simasel);
-               
-               strcpy(simasel->fole, simasel->file);
-               strcpy(simasel->dor,  simasel->dir);
-       }
-               
-       if (!bitset(simasel->fase, IMS_FOUND_BIP)){
-               /* Make the first Bip file ever in this directory */
-               if ( !bitset(simasel->fase, IMS_KNOW_INF)){
-                       if (!bitset(simasel->fase, IMS_DOTHE_INF)){
-                               if(simasel->first_sel_ima)      free_sel_ima(simasel->first_sel_ima);
-                               simasel->first_sel_ima   = 0;
-                               simasel->fase |= IMS_DOTHE_INF;
-                               addafterqueue(curarea->win, AFTERIMASELIMA, 1);
-                       }
-               }
-       }else{
-               if (!bitset(simasel->fase, IMS_KNOW_BIP)){
-                       addafterqueue(curarea->win, AFTERPIBREAD, 1);
-               }
+       /* warning; blocks need to be freed each time, handlers dont remove  */
+       uiFreeBlocksWin(&sa->uiblocks, sa->win); 
+
+       /* aspect+font, set each time */
+       simasel->aspect= (simasel->v2d.cur.xmax - simasel->v2d.cur.xmin)/((float)sa->winx);
+       simasel->curfont= uiSetCurFont_ext(simasel->aspect);    
+       
+       if (!simasel->files) {
+               simasel->files = BIF_filelist_new();
+               BIF_filelist_setdir(simasel->files, simasel->dir);
+               BIF_filelist_settype(simasel->files, simasel->type);
        }
+
+       /* Buttons */
+       draw_imasel_buttons(sa, simasel);       
        
-       make_sima_area(simasel);
-       calc_hilite(simasel);
-       draw_sima_area(simasel);
+       /* scrollbar */
+       draw_imasel_scroll(simasel);    
+
+       /* bookmarks */
+       draw_imasel_bookmarks(sa, simasel);
+
+       uiEmboss(simasel->viewrect.xmin, simasel->viewrect.ymin, simasel->v2d.mask.xmax-TILE_BORDER_X, simasel->viewrect.ymax, 1);
+
+
+       glScissor(sa->winrct.xmin + simasel->viewrect.xmin , 
+                         sa->winrct.ymin + simasel->viewrect.ymin, 
+                         simasel->viewrect.xmax - simasel->viewrect.xmin , 
+                         simasel->viewrect.ymax - simasel->viewrect.ymin);
+
+       /* previews */  
+       draw_imasel_previews(sa, simasel);
        
+       /* BIF_ThemeColor(TH_HEADER);*/
+       /* glRecti(simasel->viewrect.xmin,  simasel->viewrect.ymin,  simasel->viewrect.xmax,  simasel->viewrect.ymax);*/
+       
+       /* restore viewport (not needed yet) */
+       mywinset(sa->win);
+
+       /* ortho at pixel level curarea */
+       myortho2(-0.375, curarea->winx-0.375, -0.375, curarea->winy-0.375);
+
+       draw_area_emboss(sa);
+
+       imasel_blockhandlers(sa);
+
        curarea->win_swap= WIN_BACK_OK;
 }
-
index d9878d40d8ebc9f8b018f3825422ae175a04a235..d903d74681ba57bd29582bd0f15fa3b472a2ce98 100644 (file)
@@ -1773,37 +1773,6 @@ static void draw_nodespace_back(ScrArea *sa, SpaceNode *snode)
        }
 }
 
-static void nodeshadow(rctf *rct, float radius, float aspect, int select)
-{
-       float rad;
-       float a;
-       char alpha= 2;
-       
-       glEnable(GL_BLEND);
-       
-       if(radius > (rct->ymax-rct->ymin-10.0f)/2.0f)
-               rad= (rct->ymax-rct->ymin-10.0f)/2.0f;
-       else
-               rad= radius;
-       
-       if(select) a= 10.0f*aspect; else a= 7.0f*aspect;
-       for(; a>0.0f; a-=aspect) {
-               /* alpha ranges from 2 to 20 or so */
-               glColor4ub(0, 0, 0, alpha);
-               alpha+= 2;
-               
-               gl_round_box(GL_POLYGON, rct->xmin - a, rct->ymin - a, rct->xmax + a, rct->ymax-10.0f + a, rad+a);
-       }
-       
-       /* outline emphasis */
-       glEnable( GL_LINE_SMOOTH );
-       glColor4ub(0, 0, 0, 100);
-       gl_round_box(GL_LINE_LOOP, rct->xmin-0.5f, rct->ymin-0.5f, rct->xmax+0.5f, rct->ymax+0.5f, radius);
-       glDisable( GL_LINE_SMOOTH );
-       
-       glDisable(GL_BLEND);
-}
-
 /* nice AA filled circle */
 static void socket_circle_draw(float x, float y, float size, int type, int select)
 {
@@ -2148,7 +2117,7 @@ static void node_draw_basis(ScrArea *sa, SpaceNode *snode, bNode *node)
        int ofs, color_id= node_get_colorid(node);
        
        uiSetRoundBox(15-4);
-       nodeshadow(rct, BASIS_RAD, snode->aspect, node->flag & SELECT);
+       ui_dropshadow(rct, BASIS_RAD, snode->aspect, node->flag & SELECT);
        
        /* header */
        if(color_id==TH_NODE)
@@ -2352,7 +2321,7 @@ void node_draw_hidden(SpaceNode *snode, bNode *node)
        
        /* shadow */
        uiSetRoundBox(15);
-       nodeshadow(rct, hiddenrad, snode->aspect, node->flag & SELECT);
+       ui_dropshadow(rct, hiddenrad, snode->aspect, node->flag & SELECT);
 
        /* body */
        BIF_ThemeColor(color_id);       
index f3f9aa31d07abe2431c2fae045da080d92631dfa..bb56eb372881746bb87c1481e41db2a3c8e5deba 100644 (file)
 #include <sys/times.h>
 #endif
 
-#include "PIL_time.h"
+#include "MEM_guardedalloc.h"
+
+#include "BKE_global.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
+#include "BKE_depsgraph.h"
+#include "BKE_utildefines.h"
 
 #include "BLI_blenlib.h"
 #include "BLI_arithb.h"
+#include "BLI_storage_types.h"
 
-#include "DNA_screen_types.h"
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
+#include "DNA_armature_types.h"
+#include "DNA_action_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_image_types.h"
+#include "DNA_ipo_types.h"
+#include "DNA_material_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_object_types.h"
+#include "DNA_texture_types.h"
 #include "DNA_space_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
 #include "DNA_userdef_types.h"
+#include "DNA_vfont_types.h"
+#include "DNA_view3d_types.h"
 
-#include "BKE_global.h"
 
-#include "BIF_fsmenu.h"
+#include "BIF_filelist.h"
+#include "BIF_space.h"
 #include "BIF_screen.h"
 #include "BIF_interface.h"
-#include "BIF_imasel.h"
 #include "BIF_mywindow.h"
+#include "BIF_imasel.h"
+#include "BIF_gl.h"
+#include "BIF_fsmenu.h"
+#include "BIF_editview.h"
 #include "BIF_toolbox.h"
 
-#include "BSE_filesel.h"
+#include "BLO_readfile.h"
+
+#include "BPI_script.h"
+
+#include "BSE_drawipo.h"
 #include "BSE_drawimasel.h"
+#include "BSE_edit.h"
 
-#include "BDR_editcurve.h"
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
 
 #include "blendef.h"
 #include "mydevice.h"
 
-#define XIC 20
-#define YIC 21
+/* for events */
+#define NOTACTIVE                      0
+#define ACTIVATE                       1
+#define INACTIVATE                     2
+/* for state of file */
+#define ACTIVE                         2
 
-/* GLOBALS */
-extern char *fsmenu;
+static void imasel_select_objects(SpaceImaSel *simasel);
 
-void winqreadimaselspace(ScrArea *, void *, BWinEvent *);
+static int imasel_has_func(SpaceImaSel *simasel)
+{
+       if(simasel->returnfunc || simasel->returnfunc_event || simasel->returnfunc_args)
+               return 1;
+       return 0;
+}
 
-void winqreadimaselspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
+/* ugly, needs to be moved to platform specific files - elubie */
+#if defined WIN32 || defined __BeOS
+static int fnmatch(const char *pattern, const char *string, int flags)
+{
+       return 0;
+}
+#else
+       #include <fnmatch.h>
+#endif
+
+/**************** IMAGESELECT ******************************/
+
+/* the complete call; pulldown menu, and three callback types */
+static void activate_imageselect_(int type, char *title, char *file, short *menup, char *pupmenu,
+                                                                                void (*func)(char *),
+                                                                                void (*func_event)(unsigned short),
+                                                                                void (*func_args)(char *, void *arg1, void *arg2),
+                                                                                void *arg1, void *arg2)
 {
-       unsigned short event= evt->event;
-       short val= evt->val;
        SpaceImaSel *simasel;
+       char group[24], name[FILE_MAX], temp[FILE_MAX];
        
-       short mval[2];
-       short area_event;
-       short queredraw = 0;
-       int ret = 0;
-       char  name[256];
-       char *selname;
-       static double prevtime=0;
+       if(curarea==0) return;
+       if(curarea->win==0) return;
        
+       newspace(curarea, SPACE_IMASEL);
+       scrarea_queue_winredraw(curarea);
+       
+       /* sometime double, when area already is SPACE_IMASEL with a different file name */
+       if(curarea->headwin) addqueue(curarea->headwin, CHANGED, 1);
+
+       name[2]= 0;
+       BLI_strncpy(name, file, sizeof(name));
        
-       if(val==0) return;
        simasel= curarea->spacedata.first;
+
+       simasel->returnfunc= func;
+       simasel->returnfunc_event= func_event;
+       simasel->returnfunc_args= func_args;
+       simasel->arg1= arg1;
+       simasel->arg2= arg2;
        
-       area_event = 0;
-       getmouseco_areawin(mval);
-       simasel->mx= mval[0];
-       simasel->my= mval[1];
+       simasel->type= type;
+       simasel->scrollpos = 0.0f;
+
+       if(simasel->pupmenu)
+               MEM_freeN(simasel->pupmenu);
+       simasel->pupmenu= pupmenu;
+       simasel->menup= menup;
+       
+       /* sfile->act is used for databrowse: double names of library objects */
+       simasel->active_file= -1;
+
+       if(!simasel->files) {
+               simasel->files = BIF_filelist_new();
+       }
+
+       if(BLI_convertstringcode(name, G.sce, G.scene->r.cfra)) simasel->flag |= FILE_STRINGCODE;
+       else simasel->flag &= ~FILE_STRINGCODE;
+
+       if (U.uiflag & USER_HIDE_DOT)
+               simasel->flag |= FILE_HIDE_DOT;
+
+       if(type==FILE_MAIN) {
+               char *groupname;
+               
+               BLI_strncpy(simasel->file, name+2, sizeof(simasel->file));
+
+               groupname = BLO_idcode_to_name( GS(name) );
+               if (groupname) {
+                       BLI_strncpy(simasel->dir, groupname, sizeof(simasel->dir) - 1);
+                       strcat(simasel->dir, "/");
+               }
+
+               /* free all */
+               if (simasel->files) {
+                       BIF_filelist_freelib(simasel->files);                           
+                       BIF_filelist_free(simasel->files);
+                       BIF_filelist_setdir(simasel->files, simasel->dir);
+                       BIF_filelist_settype(simasel->files, type);
+               }
+       }
+       else if(type==FILE_LOADLIB) {
+               BLI_strncpy(simasel->dir, name, sizeof(simasel->dir));
+               BIF_filelist_setdir(simasel->files, simasel->dir);
+               if( BIF_filelist_islibrary(simasel->files, temp, group) ) {
+                       /* force a reload of the library-filelist */
+                       BIF_filelist_free(simasel->files);
+                       BIF_filelist_freelib(simasel->files);
+                       BIF_filelist_setdir(simasel->files, simasel->dir);
+                       BIF_filelist_settype(simasel->files, type);
+               }
+               else {
+                       BLI_split_dirfile(file, temp, name);
+                       BLI_strncpy(simasel->dir, temp, sizeof(simasel->dir));
+                       BIF_filelist_setdir(simasel->files, simasel->dir);
+                       BIF_filelist_free(simasel->files);
+                       BIF_filelist_freelib(simasel->files);
+                       BIF_filelist_settype(simasel->files, type);                     
+               }
+       }
+       else {  /* FILE_BLENDER */
+               BLI_split_dirfile(file, temp, name);
+               BIF_filelist_free(simasel->files);
+               BIF_filelist_setdir(simasel->files, temp);
+               BIF_filelist_settype(simasel->files, type);
+
+               BLI_cleanup_dir(G.sce, simasel->dir);
+
+               /* free: filelist and libfiledata became incorrect */
+               BIF_filelist_freelib(simasel->files);
+       }
+       BLI_strncpy(simasel->title, title, sizeof(simasel->title));
+       /* filetoname= 1; */ /* TODO: elubie - check what this means */
+}
+
+void activate_imageselect(int type, char *title, char *file, void (*func)(char *))
+{
+       activate_imageselect_(type, title, file, NULL, NULL, func, NULL, NULL, NULL, NULL);
+}
+
+void activate_imageselect_menu(int type, char *title, char *file, char *pupmenu, short *menup, void (*func)(char *))
+{
+       activate_imageselect_(type, title, file, menup, pupmenu, func, NULL, NULL, NULL, NULL);
+}
+
+void activate_imageselect_args(int type, char *title, char *file, void (*func)(char *, void *, void *), void *arg1, void *arg2)
+{
+       activate_imageselect_(type, title, file, NULL, NULL, NULL, NULL, func, arg1, arg2);
+}
+
+void activate_databrowse_imasel(ID *id, int idcode, int fromcode, int retval, short *menup, void (*func)(unsigned short))
+{
+       ListBase *lb;
+       SpaceImaSel *simasel;
+       char str[32];
        
-       if (simasel->desx > 0){
-               if ( (mval[0] > simasel->dssx) && (mval[0] < simasel->dsex) && (mval[1] > simasel->dssy) && (mval[1] < simasel->dsey) ) area_event = IMS_INDIRSLI;
-               if ( (mval[0] > simasel->desx) && (mval[0] < simasel->deex) && (mval[1] > simasel->desy) && (mval[1] < simasel->deey) ) area_event = IMS_INDIR;
+       if(id==NULL) {
+               lb= wich_libbase(G.main, idcode);
+               id= lb->first;
        }
-       if (simasel->fesx > 0){
-               if ( (mval[0] > simasel->fssx) && (mval[0] < simasel->fsex) && (mval[1] > simasel->fssy) && (mval[1] < simasel->fsey) ) area_event = IMS_INFILESLI;
-               if ( (mval[0] > simasel->fesx) && (mval[0] < simasel->feex) && (mval[1] > simasel->fesy) && (mval[1] < simasel->feey) ) area_event = IMS_INFILE;
-       }       
        
-       if( event!=RETKEY && event!=PADENTER)
-               if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0;
-
-       switch(event) {
-       case AFTERPIBREAD:      
-               get_pib_file(simasel);
-               queredraw = 1;
-               break;
-                       
-       case AFTERIMASELIMA:
-               if (bitset(simasel->fase, IMS_DOTHE_INF)){
-                       get_file_info(simasel);
-                       
-                       if (!bitset(simasel->fase, IMS_KNOW_INF)){
-                               addafterqueue(curarea->win, AFTERIMASELIMA, 1);
-                               
-                       }else{
-                               simasel->subfase = 0;
-                               simasel->imafase = 0;
-                               simasel->fase |= IMS_DOTHE_IMA;
-                               addafterqueue(curarea->win, AFTERIMASELGET, 1);
+       if(id) BLI_strncpy(str, id->name, sizeof(str));
+       else return;
+
+       activate_imageselect_(FILE_MAIN, "SELECT DATABLOCK", str, menup, NULL, NULL, func, NULL, NULL, NULL);
+       
+       simasel= curarea->spacedata.first;
+       simasel->retval= retval;
+       simasel->menup= menup;
+
+       BIF_filelist_setipotype(simasel->files, fromcode);
+       BIF_filelist_hasfunc(simasel->files, imasel_has_func(simasel));
+}
+
+
+static void set_active_file(SpaceImaSel *simasel, short x, short y)
+{
+       short tilex, tiley;
+       int active_tile;
+       int active_file;
+       int stridex;
+       struct direntry* file;
+       rcti viewrect = simasel->viewrect;
+       int fileoffset;
+       int rowoffset;
+       int rowleftover;
+       float scrollofs;
+       int numfiles;
+       int tilewidth = simasel->prv_w + TILE_BORDER_X*4;
+       int tileheight = simasel->prv_h + TILE_BORDER_Y*4 + U.fontsize;
+
+       numfiles = BIF_filelist_numfiles(simasel->files);
+       
+       if (simasel->numtilesx > 0) {
+               fileoffset = numfiles*(simasel->scrollpos / simasel->scrollarea) + 0.5;
+               rowoffset = (fileoffset / simasel->numtilesx)*simasel->numtilesx;
+               rowleftover = fileoffset % simasel->numtilesx;
+               scrollofs = (float)tileheight*(float)rowleftover/(float)simasel->numtilesx;
+       
+               stridex = (viewrect.xmax - viewrect.xmin) / (tilewidth);
+               tilex = ( (x-viewrect.xmin)) / (tilewidth);
+               tiley = (viewrect.ymax - viewrect.ymin + scrollofs - y) / (tileheight);
+               if (tilex >= simasel->numtilesx) tilex = simasel->numtilesx-1;
+               if (tiley >= simasel->numtilesy+1) tiley = simasel->numtilesy;
+               if (tilex < 0) tilex=0;
+               if (tiley < 0) tiley = 0;
+               active_tile = tilex + stridex*tiley;
+               active_file = rowoffset + active_tile;
+
+               if (active_file >= 0 && active_file < BIF_filelist_numfiles(simasel->files) )
+               {
+                       simasel->active_file = active_file;
+                       if (simasel->selstate & ACTIVATE) {
+                               file = BIF_filelist_file(simasel->files, simasel->active_file);
+                               file->flags |= ACTIVE;
                        }
+               } else {
+                       simasel->active_file = -1;
+               }
+       } else {
+               simasel->active_file = -1;
+       }
+}
+
+static void set_active_bookmark(SpaceImaSel *simasel, short y)
+{
+       int nentries = fsmenu_get_nentries();
+       short posy = simasel->bookmarkrect.ymax - U.fontsize*3/2 - TILE_BORDER_Y - y;
+       simasel->active_bookmark = ((float)posy / (U.fontsize*3.0f/2.0f)) + 0.5;        
+       if (simasel->active_bookmark < 0 || simasel->active_bookmark > nentries) {
+               simasel->active_bookmark = -1;
+       }
+}
+
+static void imasel_prevspace()
+{
+       SpaceImaSel *simasel;   
+
+       simasel= curarea->spacedata.first;
+
+       /* cleanup */
+       if(simasel->spacetype==SPACE_IMASEL) {
+               if(simasel->pupmenu) {
+                       MEM_freeN(simasel->pupmenu);
+                       simasel->pupmenu= NULL;
+               }
+       }
+
+       if(simasel->next) {
+       
+               BLI_remlink(&curarea->spacedata, simasel);
+               BLI_addtail(&curarea->spacedata, simasel);
+
+               simasel= curarea->spacedata.first;
+
+               if (simasel->spacetype == SPACE_SCRIPT) {
+                       SpaceScript *sc = (SpaceScript *)simasel;
+                       if (sc->script) sc->script->flags &=~SCRIPT_FILESEL;
                }
-               break;
-       case AFTERIMASELGET:
-               if (bitset(simasel->fase, IMS_DOTHE_IMA)){
-                       get_next_image(simasel);
-                       if (simasel->ima_redraw > 0){
-                               double newtime = PIL_check_seconds_timer();
-                               if ((newtime - prevtime) > 0.03) { 
-                                       simasel->ima_redraw = 0;
-                                       queredraw = 1;
-                                       prevtime = newtime;
+
+               newspace(curarea, simasel->spacetype);
+       }
+       else newspace(curarea, SPACE_INFO);
+}
+
+static void free_imasel_spec(char *dir)
+{
+       /* all filesels with 'dir' are freed */
+       bScreen *sc;
+               
+       sc= G.main->screen.first;
+       while(sc) {
+               ScrArea *sa= sc->areabase.first;
+               while(sa) {
+                       SpaceLink  *sl= sa->spacedata.first;
+                       while(sl) {
+                               if(sl->spacetype==SPACE_FILE) {
+                                       SpaceImaSel *simasel= (SpaceImaSel*) sl;
+                                       if (BLI_streq(simasel->dir, dir)) {
+                                               BIF_filelist_free(simasel->files);
+                                       }
                                }
-                               
+                               sl= sl->next;
                        }
-                       if (!bitset(simasel->fase, IMS_KNOW_IMA)){
-                               addafterqueue(curarea->win, AFTERIMASELGET, 1);
-                       }else{
-                               simasel->ima_redraw = 0;
-                               simasel->subfase    = 0;
-                               simasel->imafase    = 0;
-                               addqueue(curarea->win, AFTERIMAWRITE, 1);
-                               queredraw = 1;
+                       sa= sa->next;
+               }
+               sc= sc->id.next;
+       }
+}
+
+static void do_library_append(SpaceImaSel *simasel)
+{
+       Library *lib;
+       char dir[FILE_MAXDIR], group[32];
+       
+       if ( BIF_filelist_islibrary(simasel->files, dir, group)==0 ) {
+               error("Not a library");
+       } else if (!BIF_filelist_lib(simasel->files) ) {
+               error("Library not loaded");
+       } else if (group[0]==0) {
+               error("Nothing indicated");
+       } else if (BLI_streq(G.main->name, dir)) {
+               error("Cannot use current file as library");
+       } else {
+               Object *ob;
+               int idcode = BIF_groupname_to_code(group);
+                               
+               if((simasel->flag & FILE_LINK)==0) {
+                       /* tag everything, all untagged data can be made local */
+                       ID *id;
+                       ListBase *lbarray[MAX_LIBARRAY];
+                       int a;
+                       
+                       a= set_listbasepointers(G.main, lbarray);
+                       while(a--) {
+                               for(id= lbarray[a]->first; id; id= id->next) id->flag |= LIB_APPEND_TAG;
                        }
                }
-               break;
-       case  AFTERIMAWRITE:
-               if (bitset(simasel->fase, IMS_KNOW_IMA)){
-                       write_new_pib(simasel);
-                       queredraw = 1;
+
+               BIF_filelist_append_library(simasel->files, dir, simasel->file, simasel->flag, idcode);
+
+               /* DISPLISTS? */
+               ob= G.main->object.first;
+               while(ob) {
+                       if(ob->id.lib) {
+                               ob->recalc |= OB_RECALC;
+                       }
+                       ob= ob->id.next;
                }
-               break;  
        
-       case RIGHTMOUSE:
-               if ((area_event == IMS_INFILE) && (simasel->hilite_ima)){
-                       select_ima_files(simasel);
-                       queredraw = 1;
+               /* and now find the latest append lib file */
+               lib= G.main->library.first;
+               while(lib) {
+                       if (BLI_streq(dir, lib->filename)) break;
+                       lib= lib->id.next;
                }
-               break;
-       case UI_BUT_EVENT:
                
-               /* bug: blender's interface kit also returns a '4'... what is it! */
+               /* make local */
+               if(lib) {
+                       if((simasel->flag & FILE_LINK)==0) 
+                               all_local(lib,1);
+               }
                
-               switch(val) {
-               case 13:        /*  'P' */
-                       imadir_parent(simasel);
-                       queredraw = 1;
-                       
-               case 1: /* dir entry */
-                       BLI_cleanup_dir(G.sce, simasel->dir);
-                       clear_ima_dir(simasel);
-                       queredraw = 1;
-                       break;
+               DAG_scene_sort(G.scene);
+
+               /* in sfile->dir is the whole lib name */
+               BLI_strncpy(G.lib, simasel->dir, sizeof(G.lib) );
                
-               case 3: /* fsmenu */
-                       selname= fsmenu_get_entry(simasel->fileselmenuitem-1);
-                       if (selname) {
-                               strcpy(simasel->dir, selname);
-                               BLI_cleanup_dir(G.sce, simasel->dir);
-                               clear_ima_dir(simasel);
-                           queredraw = 1;
-                       }
-                       break;
+       }
+}
 
-               case 5:
-                       if (simasel->returnfunc) {
-                               char name[256];
-                               strcpy(name, simasel->dir);
-                               strcat(name, simasel->file);
-                               filesel_prevspace();
-                               simasel->returnfunc(name);
+/* NOTE: this is called for file read, after the execfunc no UI memory is valid! */
+static void imasel_execute(SpaceImaSel *simasel)
+{
+       struct direntry *file;
+       char name[FILE_MAX];
+       int a;
+       int n;
+       
+       imasel_prevspace();
+
+       if(simasel->type==FILE_LOADLIB) {
+               if(simasel->flag & FILE_STRINGCODE) {
+                       if (!G.relbase_valid) {
+                               okee("You have to save the .blend file before using relative paths! Using absolute path instead.");
+                               simasel->flag &= ~FILE_STRINGCODE;
                        }
-                       break;
-               case 6:
-                       filesel_prevspace();
-                       break;
-                                       
                }
-               break;
-               
-       case LEFTMOUSE:
-       case MIDDLEMOUSE:
+
+               do_library_append(simasel);
+               BIF_undo_push("Append from file");
+               allqueue(REDRAWALL, 1);
+       }
+       else if(imasel_has_func(simasel)) {
+               fsmenu_insert_entry(simasel->dir, 1, 0);
        
-               /* No button pressed */
-               switch (area_event){
-               case IMS_INDIRSLI:
-                       move_imadir_sli(simasel);
-                       queredraw = 1;
-                       break;
-               case IMS_INFILESLI:
-                       move_imafile_sli(simasel);
-                       queredraw = 1;
-                       break;
-               case IMS_INDIR:
-                       if (simasel->hilite > -1){
-                               change_imadir(simasel);
-                               queredraw = 1;
-                       }
-                       break;
-               case IMS_INFILE:
-                       if (simasel->hilite_ima){
-                               strcpy(simasel->fole, simasel->hilite_ima->file_name);
-                               strcpy(simasel->file, simasel->hilite_ima->file_name);
-                               
-                               if (event == LEFTMOUSE) addqueue(curarea->win, IMALEFTMOUSE, 1);        
-                               
-                               if ((event == MIDDLEMOUSE)&&(simasel->returnfunc)){
-                                       strcpy(name, simasel->dir);
-                                       strcat(name, simasel->file);
-                                       
-                                       if(simasel->mode & IMS_STRINGCODE) BLI_makestringcode(G.sce, name);
+               if(simasel->type==FILE_MAIN) { /* DATABROWSE */
+                       if (simasel->menup) {   /* with value pointing to ID block index */
+                               int notfound = 1;
+
+                               /*      Need special handling since hiding .* datablocks means that
+                                       simasel->active_file is no longer the same as files->nr.
+
+                                       Also, toggle HIDE_DOT on and off can make simasel->active_file not longer
+                                       correct (meaning it doesn't point to the correct item in the filelist.
                                        
-                                       filesel_prevspace();
-                                       simasel->returnfunc(name);
+                                       simasel->file is always correct, so first with check if, for the item
+                                       corresponding to simasel->active_file, the name is the same.
+
+                                       If it isn't (or if simasel->active_file is not good), go over filelist and take
+                                       the correct one.
+
+                                       This means that selecting a datablock than hiding it makes it
+                                       unselectable. Not really a problem.
+
+                                       - theeth
+                                */
+
+                               *simasel->menup= -1;
+                               n = BIF_filelist_numfiles(simasel->files);
+                               if(simasel->files) {
+                                       if( (simasel->active_file>=0) && (simasel->active_file < n) ) {
+                                               file = BIF_filelist_file(simasel->files, simasel->active_file);                                         
+                                               if ( strcmp(file->relname, simasel->file)==0) {
+                                                       notfound = 0;
+                                                       *simasel->menup= file->nr;
+                                               }
+                                       }
+                                       if (notfound) {                                 
+                                               for(a=0; a<n; a++) {
+                                                       file = BIF_filelist_file(simasel->files, a);    
+                                                       if( strcmp(file->relname, simasel->file)==0) {
+                                                               *simasel->menup= file->nr;
+                                                               break;
+                                                       }
+                                               }
+                                       }
                                }
-                               queredraw = 1;
                        }
-                       break;
+                       if(simasel->returnfunc_event)
+                               simasel->returnfunc_event(simasel->retval);
+                       else if(simasel->returnfunc_args)
+                               simasel->returnfunc_args(NULL, simasel->arg1, simasel->arg2);
+               }
+               else {
+                       if(strncmp(simasel->title, "Save", 4)==0) free_imasel_spec(simasel->dir);
+                       if(strncmp(simasel->title, "Export", 6)==0) free_imasel_spec(simasel->dir);
+                       
+                       BLI_strncpy(name, simasel->dir, sizeof(name));
+                       strcat(name, simasel->file);
+                       
+                       if(simasel->flag & FILE_STRINGCODE) {
+                               if (!G.relbase_valid) {
+                                       /* skip save */
+                                       if(strncmp(simasel->title, "Save", 4)) {
+                                               okee("You have to save the .blend file before using relative paths! Using absolute path instead.");
+                                               simasel->flag &= ~FILE_STRINGCODE;
+                                       }
+                               }
+                               else {
+                                       BLI_makestringcode(G.sce, name);
+                               }
+                       }
+                       if(simasel->returnfunc)
+                               simasel->returnfunc(name);
+                       else if(simasel->returnfunc_args)
+                               simasel->returnfunc_args(name, simasel->arg1, simasel->arg2);
                }
-               break;
+       }
+}
+
+static void do_imasel_buttons(short event, SpaceImaSel *simasel)
+{
+       char butname[FILE_MAX];
        
-       case MOUSEX:
-       case MOUSEY:
-               getmouseco_areawin(mval);       /* local screen coordinates */
-               calc_hilite(simasel);
-               if (simasel->mouse_move_redraw ){
-                       simasel->mouse_move_redraw = 0;
-                       queredraw = 1;
+       if (event == B_FS_FILENAME) {
+               if (strchr(simasel->file, '*') || strchr(simasel->file, '?') || strchr(simasel->file, '[')) {
+                       int i, match = FALSE;
+                       struct direntry *file;
+                       int n = BIF_filelist_numfiles(simasel->files);
+                       for (i = 2; i < n; i++) {
+                               file = BIF_filelist_file(simasel->files, i);
+                               if (fnmatch(simasel->file, file->relname, 0) == 0) {
+                                       file->flags |= ACTIVE;
+                                       match = TRUE;
+                               }
+                       }
+                       if (match) simasel->file[0] = '\0';
+                       if(simasel->type==FILE_MAIN) imasel_select_objects(simasel);
+                       scrarea_queue_winredraw(curarea);
                }
-               break;
+       }
+       else if(event== B_FS_DIRNAME) {
+               /* reuse the butname variable */
+               BLI_cleanup_dir(G.sce, simasel->dir);
+
+               BLI_make_file_string(G.sce, butname, simasel->dir, "");
+               BLI_strncpy(simasel->dir, butname, sizeof(simasel->dir));               
+
+               /* strip the trailing slash if its a real dir */
+               if (strlen(butname)!=1)
+                       butname[strlen(butname)-1]=0;
                
-       case WHEELUPMOUSE:
-       case WHEELDOWNMOUSE:
-               switch(area_event){
-               case IMS_INDIRSLI:
-               case IMS_INDIR:
-                       if (simasel->dirsli){
-                               if (event == WHEELUPMOUSE)      simasel->topdir -= U.wheellinescroll;
-                               if (event == WHEELDOWNMOUSE)    simasel->topdir += U.wheellinescroll;   
-                               queredraw = 1;
+               /* updating the directory in the filelist */
+               BIF_filelist_setdir(simasel->files, simasel->dir);
+
+               if(simasel->type & FILE_UNIX) {
+                       if (!BLI_exists(butname)) {
+                               if (okee("Makedir")) {
+                                       BLI_recurdir_fileops(butname);
+                                       if (!BLI_exists(butname)) {
+                                               BIF_filelist_parent(simasel->files);
+                                               BLI_strncpy(simasel->dir, BIF_filelist_dir(simasel->files), 80);
+                                       }
+                               } else {
+                                       BIF_filelist_parent(simasel->files);
+                                       BLI_strncpy(simasel->dir, BIF_filelist_dir(simasel->files), 80);
+                               }
                        }
-                       break;
-               case IMS_INFILESLI:
-               case IMS_INFILE:
-                       if(simasel->imasli){
-                               if (event == WHEELUPMOUSE)      simasel->image_slider -= 0.2 * simasel->slider_height;
-                               if (event == WHEELDOWNMOUSE)    simasel->image_slider += 0.2 * simasel->slider_height;
-                               
-                               if(simasel->image_slider < 0.0) simasel->image_slider = 0.0;
-                               if(simasel->image_slider > 1.0) simasel->image_slider = 1.0;
-                               queredraw = 1;
-                       }       
-                       break;
                }
-               break;
-
-       case PAGEUPKEY:
-       case PAGEDOWNKEY:
-               switch(area_event){
-               case IMS_INDIRSLI:
-               case IMS_INDIR:
-                       if (simasel->dirsli){
-                               if (event == PAGEUPKEY)   simasel->topdir -= (simasel->dirsli_lines - 1);
-                               if (event == PAGEDOWNKEY) simasel->topdir += (simasel->dirsli_lines - 1);       
-                               queredraw = 1;
-                       }
-                       break;
-               case IMS_INFILESLI:
-               case IMS_INFILE:
-                       if(simasel->imasli){
-                               if (event == PAGEUPKEY)   simasel->image_slider -= simasel->slider_height;
-                               if (event == PAGEDOWNKEY) simasel->image_slider += simasel->slider_height;
-                               
-                               if(simasel->image_slider < 0.0)  simasel->image_slider = 0.0;
-                               if(simasel->image_slider > 1.0)  simasel->image_slider = 1.0;
-                               queredraw = 1;
-                       }       
-                       break;
+               BIF_filelist_free(simasel->files);              
+               simasel->file[0] = '\0';                        
+               simasel->scrollpos = 0;
+               simasel->active_file = -1;
+               scrarea_queue_winredraw(curarea);
+       }
+       else if(event== B_FS_DIR_MENU) {
+               char *selected= fsmenu_get_entry(simasel->menu-1);
+               
+               /* which string */
+               if (selected) {
+                       BLI_strncpy(simasel->dir, selected, sizeof(simasel->dir));
+                       BLI_make_exist(simasel->dir);
+                       BLI_cleanup_dir(G.sce, simasel->dir);
+                       BIF_filelist_free(simasel->files);      
+                       BIF_filelist_setdir(simasel->files, simasel->dir);
+                       simasel->file[0] = '\0';                        
+                       simasel->scrollpos = 0;
+                       simasel->active_file = -1;
+                       scrarea_queue_winredraw(curarea);
                }
-               break;
+
+               simasel->active_file = -1;
+               
+       }
+       else if(event== B_FS_PARDIR) {
+               BIF_filelist_free(simasel->files);
+               BIF_filelist_parent(simasel->files);
+               BLI_strncpy(simasel->dir, BIF_filelist_dir(simasel->files), 80);
+               simasel->file[0] = '\0';
+               simasel->active_file = -1;
+               simasel->scrollpos = 0;
+               scrarea_queue_winredraw(curarea);
+       }
+       else if(event== B_FS_LOAD) {
+               if(simasel->type) 
+                       imasel_execute(simasel);
+       }
+       else if(event== B_FS_CANCEL) 
+               imasel_prevspace();
+       else if(event== B_FS_LIBNAME) {
+               Library *lib= BLI_findlink(&G.main->library, simasel->menu);
+               if(lib) {
+                       BLI_strncpy(simasel->dir, lib->filename, sizeof(simasel->dir));
+                       BLI_make_exist(simasel->dir);
+                       BLI_cleanup_dir(G.sce, simasel->dir);
+                       BIF_filelist_free(simasel->files);
+                       BIF_filelist_setdir(simasel->files, simasel->dir);
+                       simasel->file[0] = '\0';                        
+                       simasel->scrollpos = 0;
+                       simasel->active_file = -1;
+                       scrarea_queue_winredraw(curarea);
+               }
+       } else if(event== B_FS_BOOKMARK)  {
+               char name[FILE_MAX];
+               BLI_make_file_string(G.sce, name, BLI_gethome(), ".Bfs");
+               fsmenu_insert_entry(simasel->dir, 1, 1);
+               scrarea_queue_winredraw(curarea);
+               fsmenu_write_file(name);
+       }
+       
+}
+
+static void imasel_home(ScrArea *sa, SpaceImaSel *simasel)
+{
+       simasel->v2d.cur.xmin= simasel->v2d.cur.ymin= 0.0f;
+       simasel->v2d.cur.xmax= sa->winx;
+       simasel->v2d.cur.ymax= sa->winy;
        
-       case HOMEKEY:
-               simasel->image_slider = 0.0;
-               queredraw = 1;
-               break;
-
-       case ENDKEY:
-               simasel->image_slider = 1.0;
-               queredraw = 1;
-               break;
+       simasel->v2d.tot= simasel->v2d.cur;
+       test_view2d(G.v2d, sa->winx, sa->winy);
+       
+}
+
+static struct direntry* get_hilited_entry(SpaceImaSel *simasel)
+{
+       struct direntry *file;
+       file = BIF_filelist_file(simasel->files, simasel->active_file);
+       return file;
+}
+
+static void do_filescroll(SpaceImaSel *simasel)
+{
+       short mval[2], oldy, yo;
+       float scrollarea, scrollstep;
+
+       /* for beauty */
+       scrarea_do_windraw(curarea);
+       screen_swapbuffers();
+
+       getmouseco_areawin(mval);
+       oldy= yo= mval[1];
+       
+       while(get_mbut()&L_MOUSE) {
+               getmouseco_areawin(mval);
+               
+               if(yo!=mval[1]) {
+                       scrollarea = ((float)simasel->v2d.vert.ymax - (float)simasel->v2d.vert.ymin);
+                       scrollstep = yo - mval[1];      
+                       simasel->scrollpos += scrollstep;
                        
-       case AKEY:
-               if (G.qual == 0){
-                       ima_select_all(simasel);
-                       queredraw = 1;
-               }
-               break;
+                       if (simasel->scrollpos<0) 
+                               simasel->scrollpos=0;
+                       if (simasel->scrollpos > scrollarea - simasel->scrollheight) 
+                               simasel->scrollpos = scrollarea - simasel->scrollheight;
+                       scrarea_do_windraw(curarea);
+                       screen_swapbuffers();
 
-       case IKEY:
-               if ((G.qual == 0)&&(simasel->file)){
-                       sprintf(name, "$IMAGEEDITOR %s%s", simasel->dir, simasel->file);
-                       system(name);
-                       queredraw = 1;
+                       yo= mval[1];
                }
+               else BIF_wait_for_statechange();
+       }
 
-               break;
+       /* for beauty */
+       scrarea_do_windraw(curarea);
+       screen_swapbuffers();
        
-       case PKEY:
-               if(G.qual & LR_SHIFTKEY) {
-                       extern char bprogname[];        /* usiblender.c */
-#ifdef WIN32                   
-                       sprintf(name, "%s -a \"%s%s\"", bprogname, simasel->dir, simasel->file);
-#else
-                       sprintf(name, "\"%s\" -a \"%s%s\"", bprogname, simasel->dir, simasel->file);
-#endif
-                       system(name);
-               }
-               if(G.qual & LR_CTRLKEY) {
-                       if(bitset(simasel->fase, IMS_KNOW_IMA)) pibplay(simasel);
+}
+
+/* ******************* DATA SELECT ********************* */
+
+static void imasel_select_objects(SpaceImaSel *simasel)
+{
+       Object *ob;
+       Base *base;
+       Scene *sce;
+       struct direntry* file;
+       int a;
+       int totfile;
+
+       /* only when F4 DATABROWSE */
+       if(imasel_has_func(simasel)) return;
+       
+       totfile = BIF_filelist_numfiles(simasel->files);
+
+       if( strcmp(simasel->dir, "Object/")==0 ) {
+               for(a=0; a<totfile; a++) {
+                       file = BIF_filelist_file(simasel->files, a);
+                       ob= (Object *)file->poin;
+                       
+                       if(ob) {
+                               if(file->flags & ACTIVE) ob->flag |= SELECT;
+                               else ob->flag &= ~SELECT;
+                       }
+
                }
-               if (G.qual == 0){
-                       imadir_parent(simasel);
-                       BLI_cleanup_dir(G.sce, simasel->dir);
-                       clear_ima_dir(simasel);
-                       queredraw = 1;
+               base= FIRSTBASE;
+               while(base) {
+                       base->flag= base->object->flag;
+                       base= base->next;
                }
-               break;
+               countall();
+               allqueue(REDRAWVIEW3D, 0);
+               allqueue(REDRAWOOPS, 0);
+       }
+       else if( strcmp(simasel->dir, "Scene/")==0 ) {
                
-       case RKEY:
-       case XKEY:
-               if (simasel->hilite_ima){
-                       strcpy(name, simasel->dir);
-                       strcat(name, simasel->hilite_ima->file_name);
-
-                       if( okee("Delete %s", name) ) {
-                               ret = BLI_delete(name, 0, 0);
-                               if (ret) {
-                                       error("Command failed, see console");
-                               } else {
-                                       clear_ima_dir(simasel);
-                                       queredraw = 1;
-                               }
+               for(a=0; a<totfile; a++) {
+                       file = BIF_filelist_file(simasel->files, a);
+                       sce= (Scene *)file->poin;
+                       if(sce) {
+                               if(file->flags & ACTIVE) sce->r.scemode |= R_BG_RENDER;
+                               else sce->r.scemode &= ~R_BG_RENDER;
                        }
+
                }
-               break;
+               allqueue(REDRAWBUTSSCENE, 0);
+       }
+}
 
-       case PADPLUSKEY:
-       case EQUALKEY:
-               BLI_newname(simasel->file, +1);
-               queredraw = 1;
-               break;
-               
-       case PADMINUS:
-       case MINUSKEY:
-               BLI_newname(simasel->file, -1);
-               queredraw = 1;
-               break;
-               
-       case BACKSLASHKEY:
-       case SLASHKEY:
-#ifdef WIN32
-               strcpy(simasel->dir, "\\");
-#else
-               strcpy(simasel->dir, "/");
-#endif
-               clear_ima_dir(simasel);
-               simasel->image_slider = 0.0;
-               queredraw = 1;
-               break;
-               
-       case PERIODKEY:
-               clear_ima_dir(simasel);
-               queredraw = 1;
-               break;
+static void active_imasel_object(SpaceImaSel *simasel)
+{
+       Object *ob;
+       struct direntry* file;
+
+       /* only when F4 DATABROWSE */
+       if(imasel_has_func(simasel)) return;
        
-       case ESCKEY:
-               filesel_prevspace();
-               break;
-
-       case PADENTER:
-       case RETKEY:
-               if (simasel->returnfunc){
-                       strcpy(name, simasel->dir);
-                       strcat(name, simasel->file);
-                       filesel_prevspace();
-                       simasel->returnfunc(name);
+       if( strcmp(simasel->dir, "Object/")==0 ) {
+               int n = BIF_filelist_numfiles(simasel->files);
+               if(simasel->active_file >= 0 && simasel->active_file < n) {
+                       file = BIF_filelist_file(simasel->files, simasel->active_file);
+                       ob= (Object *)file->poin;
+                       
+                       if(ob) {
+                               set_active_object(ob);
+                               if(BASACT && BASACT->object==ob) {
+                                       BASACT->flag |= SELECT;
+                                       file->flags |= ACTIVE;
+                                       allqueue(REDRAWVIEW3D, 0);
+                                       allqueue(REDRAWOOPS, 0);
+                                       scrarea_queue_winredraw(curarea);
+                               }
+                       }
                }
-               break;
        }
+}
+
+
+
+void winqreadimaselspace(ScrArea *, void *, BWinEvent *);
+
+
+void winqreadimaselspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
+{
+       unsigned short event= evt->event;
+       short val= evt->val;
+       SpaceImaSel *simasel;
        
+       char str[FILE_MAXDIR+FILE_MAXFILE+12];
+       short mval[2];
+       short do_draw = 0;
+       int numfiles;
+       struct direntry *file;
+       float scrollstep = 0;
+       float scrollarea;
+
+       // if(val==0) return;
+       simasel= curarea->spacedata.first;
+
+       if (!simasel->files)
+               return;
+
+       if (BIF_filelist_empty(simasel->files))
+               return;
+
+       numfiles = BIF_filelist_numfiles(simasel->files);
+       
+       /* calc_scrollrcts(sa, &(simasel->v2d), sa->winx, sa->winy); */
+       calc_imasel_rcts(simasel, sa->winx, sa->winy);  
+
+       /* prevent looping */
+       if(simasel->selstate && !(get_mbut() & R_MOUSE)) simasel->selstate= 0;
+
+       if(val) {
+
+               if( event!=RETKEY && event!=PADENTER)
+                       if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0;
+
+               switch(event) {
                
-       if (queredraw) scrarea_queue_winredraw(curarea);
+               case UI_BUT_EVENT:
+                       do_imasel_buttons(val, simasel);
+                       break;          
+               case RENDERPREVIEW:
+                       do_draw= 1; 
+                       /* draw_imasel_previews(sa, simasel);  */
+                       break;
+               case REDRAWIMASEL:
+                       do_draw= 1;
+                       break;
+               case WHEELDOWNMOUSE:
+                       numfiles = BIF_filelist_numfiles(simasel->files);
+                       scrollarea = ((float)simasel->v2d.vert.ymax - (float)simasel->v2d.vert.ymin);
+                       scrollstep = ((scrollarea-simasel->scrollheight)/numfiles)*simasel->numtilesx;  
+                       simasel->scrollpos += scrollstep;
+                       if (simasel->scrollpos > scrollarea - simasel->scrollheight) 
+                               simasel->scrollpos = scrollarea - simasel->scrollheight;
+                       do_draw= 1;
+                       break;
+               case WHEELUPMOUSE:
+                       numfiles = BIF_filelist_numfiles(simasel->files);
+                       scrollarea = ((float)simasel->v2d.vert.ymax - (float)simasel->v2d.vert.ymin);
+                       scrollstep = ((scrollarea-simasel->scrollheight)/numfiles)*simasel->numtilesx;                  
+                       simasel->scrollpos -= scrollstep;
+                       if (simasel->scrollpos<0) 
+                               simasel->scrollpos=0;
+                       do_draw= 1;
+                       break;
+               case PAGEUPKEY:
+                       numfiles = BIF_filelist_numfiles(simasel->files);
+                       scrollarea = ((float)simasel->v2d.vert.ymax - (float)simasel->v2d.vert.ymin);
+                       scrollstep = ((scrollarea-simasel->scrollheight)/numfiles)
+                                                *simasel->numtilesx*simasel->numtilesy;
+                       simasel->scrollpos -= scrollstep;
+                       if (simasel->scrollpos<0) 
+                               simasel->scrollpos=0;
+                       do_draw= 1;
+                       break;
+               case PAGEDOWNKEY:
+                       numfiles = BIF_filelist_numfiles(simasel->files);
+                       scrollarea = ((float)simasel->v2d.vert.ymax - (float)simasel->v2d.vert.ymin);
+                       scrollstep = ((scrollarea-simasel->scrollheight)/numfiles)
+                                                * simasel->numtilesx*simasel->numtilesy;
+                       simasel->scrollpos += scrollstep;
+                       if (simasel->scrollpos > scrollarea - simasel->scrollheight) 
+                               simasel->scrollpos = scrollarea - simasel->scrollheight;
+                       do_draw= 1;                                             
+                       break;
+               case HOMEKEY:
+                       simasel->scrollpos=0;
+                       imasel_home(sa, simasel);
+                       do_draw= 1;
+                       break;
+               case ENDKEY:
+                       simasel->scrollpos = simasel->scrollarea;
+                       do_draw= 1;
+                       break;
+
+               case ESCKEY:
+                       BIF_filelist_free(simasel->files);
+                       imasel_prevspace();
+                       break;
+               case PERIODKEY:
+                       BIF_filelist_free(simasel->files);
+                       simasel->active_file = -1;
+                       do_draw = 1;
+                       break;
+               case LEFTMOUSE:
+               case MIDDLEMOUSE:                       
+                       getmouseco_areawin(mval);
+                       if(mval[0]>simasel->v2d.vert.xmin && mval[0]<simasel->v2d.vert.xmax && mval[1]>simasel->v2d.vert.ymin && mval[1]<simasel->v2d.vert.ymax) {
+                               do_filescroll(simasel);
+                       }
+                       else if(mval[0]>simasel->viewrect.xmin && mval[0]<simasel->viewrect.xmax 
+                               && mval[1]>simasel->viewrect.ymin && mval[1]<simasel->viewrect.ymax) {  
+                               set_active_file(simasel, mval[0], mval[1]);
+                               if (simasel->active_file >= 0 && simasel->active_file < numfiles) {
+                                       file = BIF_filelist_file(simasel->files, simasel->active_file);
+                                       
+                                       if(file && S_ISDIR(file->type)) {
+
+                                               BIF_filelist_appenddir(simasel->files, file->relname);                          
+                                               BLI_strncpy(simasel->dir, BIF_filelist_dir(simasel->files), FILE_MAXDIR);
+                                               strcat(simasel->dir,"/");
+                                               simasel->file[0] = '\0';
+                                               BLI_cleanup_dir(G.sce, simasel->dir);
+                                               BIF_filelist_free(simasel->files);
+                                               simasel->active_file = -1;
+                                               simasel->scrollpos = 0;
+                                               do_draw = 1;
+                                               
+                                       }
+                                       else if (file)
+                                       {
+                                               if (file->relname) {
+                                                       if (simasel->img) {
+                                                               IMB_freeImBuf(simasel->img);
+                                                               simasel->img = NULL;
+                                                       }
+                                                       BLI_strncpy(simasel->file, file->relname, FILE_MAXFILE);
+                                                       if(event==MIDDLEMOUSE && BIF_filelist_gettype(simasel->files)) 
+                                                               imasel_execute(simasel);
+                                               }
+                                               
+                                       }       
+                                       if(BIF_filelist_gettype(simasel->files)==FILE_MAIN) {
+                                               active_imasel_object(simasel);
+                                       }
+                               
+                                       do_draw = 1;
+                               }
+                       }
+                       else {
+                               simasel->active_file = -1;
+                               if (simasel->flag & FILE_BOOKMARKS) {
+                                       if(mval[0]>simasel->bookmarkrect.xmin && mval[0]<simasel->bookmarkrect.xmax && mval[1]>simasel->bookmarkrect.ymin && mval[1]<simasel->bookmarkrect.ymax) {
+                                               int nentries = fsmenu_get_nentries();
+                                               
+                                               set_active_bookmark(simasel, mval[1]);
+                                               if (simasel->active_bookmark >= 0 && simasel->active_bookmark < nentries) {
+                                                       char *selected= fsmenu_get_entry(simasel->active_bookmark);                     
+                                                       /* which string */
+                                                       if (selected) {
+                                                               BLI_strncpy(simasel->dir, selected, sizeof(simasel->dir));
+                                                               BLI_make_exist(simasel->dir);
+                                                               BLI_cleanup_dir(G.sce, simasel->dir);
+                                                               BIF_filelist_free(simasel->files);      
+                                                               BIF_filelist_setdir(simasel->files, simasel->dir);
+                                                               simasel->file[0] = '\0';                        
+                                                               simasel->scrollpos = 0;
+                                                               simasel->active_file = -1;
+                                                               scrarea_queue_winredraw(curarea);
+                                                       }
+                                               }
+                                       } else {
+                                               simasel->active_bookmark = -1;
+                                       }
+                                       do_draw= 1;
+                               }                               
+                       }
+                       break;
+               case RIGHTMOUSE:                        
+                       getmouseco_areawin(mval);
+                       if(mval[0]>simasel->viewrect.xmin && mval[0]<simasel->viewrect.xmax 
+                               && mval[1]>simasel->viewrect.ymin && mval[1]<simasel->viewrect.ymax) {
+                               set_active_file(simasel, mval[0], mval[1]);
+                               if(simasel->active_file >=0 && simasel->active_file<numfiles) {
+                                       simasel->selstate = NOTACTIVE;
+                                       file = BIF_filelist_file(simasel->files, simasel->active_file);
+                                       if (file->flags & ACTIVE) {
+                                               file->flags &= ~ACTIVE;
+                                               simasel->selstate = INACTIVATE;
+                                       }
+                                       else {
+                                               file->flags |= ACTIVE;
+                                               simasel->selstate = ACTIVATE;
+                                       }
+                                       do_draw= 1;
+                               }
+                       }
+                       break;
+               case MOUSEY:
+               case MOUSEX:
+                       getmouseco_areawin(mval);
+                       if(mval[0]>simasel->viewrect.xmin && mval[0]<simasel->viewrect.xmax && mval[1]>simasel->viewrect.ymin && mval[1]<simasel->viewrect.ymax) {
+                               set_active_file(simasel, mval[0], mval[1]);
+                               if(simasel->active_file >=0 && simasel->active_file<numfiles) {
+                                       file = BIF_filelist_file(simasel->files, simasel->active_file);
+                                       if (simasel->selstate == INACTIVATE) {
+                                               file->flags &= ~ACTIVE;
+                                       }
+                                       else if (simasel->selstate == ACTIVATE) {
+                                               file->flags |= ACTIVE;
+                                       }
+                                       do_draw= 1;
+                               }
+                       } else {
+                               simasel->active_file = -1;
+                               if (simasel->flag & FILE_BOOKMARKS) {
+                                       if(mval[0]>simasel->bookmarkrect.xmin && mval[0]<simasel->bookmarkrect.xmax && mval[1]>simasel->bookmarkrect.ymin && mval[1]<simasel->bookmarkrect.ymax) {
+                                               set_active_bookmark(simasel, mval[1]);
+                                               do_draw= 1;
+                                       } else {
+                                               simasel->active_bookmark = -1;
+                                       }                                       
+                               }                               
+                       }
+                       break;
+               case AKEY:
+                       BIF_filelist_swapselect(simasel->files);
+                       if(simasel->type==FILE_MAIN) imasel_select_objects(simasel);
+                       do_draw= 1;
+                       break;
+               case BKEY:
+                       toggle_blockhandler(sa, IMASEL_HANDLER_IMAGE, UI_PNL_UNSTOW);
+                       scrarea_queue_winredraw(sa);
+                       break;
+               case PKEY:
+                       if(G.qual & LR_SHIFTKEY) {
+                               extern char bprogname[];        /* usiblender.c */
+                       
+                               sprintf(str, "%s -a \"%s%s\"", bprogname, simasel->dir, simasel->file);
+                               system(str);
+                       }
+                       else 
+                       {
+                               BIF_filelist_free(simasel->files);
+                               BIF_filelist_parent(simasel->files);
+                               BLI_strncpy(simasel->dir, BIF_filelist_dir(simasel->files), 80);
+                               simasel->file[0] = '\0';
+                               simasel->active_file = -1;
+                               simasel->scrollpos = 0;
+                       }
+                       do_draw = 1;    
+                       break;
+               case XKEY:
+                       getmouseco_areawin(mval);                       
+                       if (simasel->flag & FILE_BOOKMARKS) {
+                                       if(mval[0]>simasel->bookmarkrect.xmin && mval[0]<simasel->bookmarkrect.xmax && mval[1]>simasel->bookmarkrect.ymin && mval[1]<simasel->bookmarkrect.ymax) {                      
+                                               int nentries = fsmenu_get_nentries();
+                                               set_active_bookmark(simasel, mval[1]);
+                                               if (simasel->active_bookmark >= 0 && simasel->active_bookmark < nentries) {
+                                                       fsmenu_remove_entry(simasel->active_bookmark);
+                                                       simasel->active_bookmark = -1;
+                                                       do_draw = 1;
+                                               }
+                                       }
+                       }                       
+                       break;
+               }               
+       }
+       else if(event==RIGHTMOUSE) {
+               simasel->selstate = NOTACTIVE;          
+               if(simasel->type==FILE_MAIN) imasel_select_objects(simasel);
+       }
+       else if(event==LEFTMOUSE) {
+               if(simasel->type==FILE_MAIN) {
+                       getmouseco_areawin(mval);
+                       set_active_file(simasel, mval[0], mval[1]);
+               }
+       }
+               /* XXX, stupid patch, curarea can become undone
+                * because of file loading... fixme zr
+                */
+       if(do_draw && curarea) scrarea_queue_winredraw(curarea);
 }
 
 
+/* copied from filesel.c */
 void clever_numbuts_imasel()
 {
        SpaceImaSel *simasel;
-       static char orgname[FILE_MAXDIR+FILE_MAXFILE+12];
-       static char filename[FILE_MAXDIR+FILE_MAXFILE+12];
-       static char newname[FILE_MAXDIR+FILE_MAXFILE+12];
+       char orgname[FILE_MAXDIR+FILE_MAXFILE+12];
+       char filename[FILE_MAXDIR+FILE_MAXFILE+12];
+       char newname[FILE_MAXDIR+FILE_MAXFILE+12];
+       struct direntry *file;
        int len;
        
        simasel= curarea->spacedata.first;
+
+       if(BIF_filelist_gettype(simasel->files)==FILE_MAIN) return;
+       
        len = 110;
+       file = get_hilited_entry(simasel);
+
+       if (file != NULL && !(S_ISDIR(file->type))){
+               
+               BLI_make_file_string(G.sce, orgname, simasel->dir, file->relname);
+               BLI_strncpy(filename, file->relname, sizeof(filename));
 
-       if (simasel->hilite_ima){
-               BLI_make_file_string(G.sce, orgname, simasel->dir, simasel->hilite_ima->file_name);
-               strcpy(filename, simasel->hilite_ima->file_name);
+               add_numbut(0, TEX, "", 0, len, filename, "Rename File");
 
-               add_numbut(0, TEX, "", 0, len, filename, "Rename Image");
-               if( do_clever_numbuts("Rename Image", 1, REDRAW) ) {
+               if( do_clever_numbuts("Rename File", 1, REDRAW) ) {
                        BLI_make_file_string(G.sce, newname, simasel->dir, filename);
 
                        if( strcmp(orgname, newname) != 0 ) {
                                BLI_rename(orgname, newname);
-
-                               clear_ima_dir(simasel);
+                               BIF_filelist_free(simasel->files);
                        }
                }
 
index 814985cb1653a80326b9aa84f7d7322461c4d03d..44069beaf43c56be0e0fc3f497a226c3e2b3bfc9 100644 (file)
@@ -358,6 +358,11 @@ void areawinset(short win)
                        G.v2d= &snode->v2d;
                }
                        break;
+               case SPACE_IMASEL:
+               {
+                       SpaceImaSel *simasel= curarea->spacedata.first;
+                       G.v2d= &simasel->v2d;
+               }
                default:
                        break;
                }
index 94990b8a3936daa212ae8d570d4964a0f82069e8..06593227dbf3ee0fd8301e52b75346d5574c2418 100644 (file)
@@ -79,6 +79,7 @@
 
 #include "BIF_gl.h"
 #include "BIF_glutil.h"
+#include "BIF_imasel.h"
 #include "BIF_interface.h"
 #include "BIF_drawimage.h"
 #include "BIF_editview.h"
diff --git a/source/blender/src/filelist.c b/source/blender/src/filelist.c
new file mode 100644 (file)
index 0000000..6dc97fa
--- /dev/null
@@ -0,0 +1,1093 @@
+/**
+ * $Id: $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. 
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2007 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+
+/* global includes */
+
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef WIN32
+#include <unistd.h>
+#else
+#include <io.h>
+#include <direct.h>
+#endif   
+#include "MEM_guardedalloc.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_linklist.h"
+#include "BLI_storage_types.h"
+
+#ifdef WIN32
+#include "BLI_winstuff.h"
+#endif
+
+#include "BKE_utildefines.h"
+#include "BKE_global.h"
+#include "BIF_filelist.h"
+#include "BKE_library.h"
+#include "BKE_global.h"
+#include "BKE_main.h"
+#include "BLO_readfile.h"
+
+#include "DNA_space_types.h"
+#include "DNA_ipo_types.h"
+#include "DNA_ID.h"
+#include "DNA_object_types.h"
+#include "DNA_lamp_types.h"
+#include "DNA_material_types.h"
+#include "DNA_texture_types.h"
+#include "DNA_world_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_userdef_types.h"
+
+#include "IMB_imbuf.h"
+#include "IMB_imbuf_types.h"
+#include "IMB_thumbs.h"
+
+#include "PIL_time.h"
+
+#include "datatoc.h"
+
+/* Elubie: VERY, really very ugly and evil! Remove asap!!! */
+/* for state of file */
+#define ACTIVE                         2
+
+/* max length of library group name within filesel */
+#define GROUP_MAX 32
+
+typedef struct FileList
+{
+       struct direntry *filelist;
+       struct direntry *unfiltered;
+
+       int numfiles;
+       int numunfiltered;
+       char dir[FILE_MAXDIR];
+       short type;
+       short ipotype;
+       struct BlendHandle *libfiledata;
+       int has_func;
+       short prv_w;
+       short prv_h;
+       short hide_dot;
+       unsigned int filter;
+} FileList;
+
+int BIF_groupname_to_code(char *group)
+{