From 356ab943736e8a2434a8ff5845873482597ba5e2 Mon Sep 17 00:00:00 2001 From: Andrea Weikert Date: Sun, 2 Sep 2007 17:25:03 +0000 Subject: == imagebrowser == 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! --- projectfiles_vc7/blender/imbuf/BL_imbuf.vcproj | 15 + projectfiles_vc7/blender/src/BL_src.vcproj | 12 + release/datafiles/prvicons | Bin 0 -> 13732 bytes source/blender/blenkernel/BKE_icons.h | 75 +- .../blenkernel/bad_level_call_stubs/stubs.c | 4 + source/blender/blenkernel/intern/icons.c | 169 ++- source/blender/blenkernel/intern/image.c | 11 +- source/blender/blenkernel/intern/material.c | 5 + source/blender/blenkernel/intern/object.c | 7 +- source/blender/blenkernel/intern/texture.c | 5 + source/blender/blenkernel/intern/world.c | 7 +- source/blender/blenlib/BLI_blenlib.h | 5 + source/blender/blenlib/BLI_storage_types.h | 3 + source/blender/blenlib/intern/util.c | 32 + source/blender/blenloader/BLO_readfile.h | 19 + source/blender/blenloader/intern/readblenentry.c | 66 + source/blender/blenloader/intern/readfile.c | 144 ++- source/blender/blenloader/intern/writefile.c | 42 +- source/blender/imbuf/IMB_imbuf.h | 7 + source/blender/imbuf/IMB_imbuf_types.h | 4 + source/blender/imbuf/IMB_thumbs.h | 73 ++ source/blender/imbuf/intern/IMB_imginfo.h | 78 ++ source/blender/imbuf/intern/allocimbuf.c | 5 + source/blender/imbuf/intern/anim.c | 12 + source/blender/imbuf/intern/imginfo.c | 108 ++ source/blender/imbuf/intern/md5.c | 360 ++++++ source/blender/imbuf/intern/md5.h | 115 ++ source/blender/imbuf/intern/png.c | 38 + source/blender/imbuf/intern/thumbs.c | 457 +++++++ source/blender/include/BIF_filelist.h | 87 ++ source/blender/include/BIF_fsmenu.h | 7 +- source/blender/include/BIF_imasel.h | 25 +- source/blender/include/BIF_interface_icons.h | 3 + source/blender/include/BIF_resources.h | 2 +- source/blender/include/BIF_space.h | 3 + source/blender/include/BSE_drawimasel.h | 35 +- source/blender/include/BSE_filesel.h | 2 - source/blender/include/blendef.h | 5 +- source/blender/include/datatoc.h | 3 + source/blender/include/interface.h | 2 +- source/blender/makesdna/DNA_ID.h | 12 + source/blender/makesdna/DNA_image_types.h | 5 - source/blender/makesdna/DNA_lamp_types.h | 3 + source/blender/makesdna/DNA_material_types.h | 3 +- source/blender/makesdna/DNA_space_types.h | 132 +- source/blender/makesdna/DNA_texture_types.h | 3 +- source/blender/makesdna/DNA_userdef_types.h | 1 + source/blender/makesdna/DNA_world_types.h | 3 + source/blender/python/api2_2x/Window.c | 1 + source/blender/quicktime/apple/quicktime_import.c | 19 +- source/blender/src/buttons_scene.c | 1 + source/blender/src/buttons_shading.c | 8 +- source/blender/src/drawimasel.c | 1338 +++++++++----------- source/blender/src/drawnode.c | 35 +- source/blender/src/editimasel.c | 1297 ++++++++++++++----- source/blender/src/editscreen.c | 5 + source/blender/src/editsima.c | 1 + source/blender/src/filelist.c | 1093 ++++++++++++++++ source/blender/src/filesel.c | 191 +-- source/blender/src/fsmenu.c | 260 ++++ source/blender/src/glutil.c | 21 +- source/blender/src/header_imasel.c | 114 +- source/blender/src/header_info.c | 5 + source/blender/src/headerbuttons.c | 7 +- source/blender/src/imasel.c | 861 +------------ source/blender/src/interface_draw.c | 30 + source/blender/src/interface_icons.c | 320 +++-- source/blender/src/prvicons.c | 436 +++++++ source/blender/src/resources.c | 17 +- source/blender/src/space.c | 130 +- source/blender/src/toets.c | 14 + source/blender/src/usiblender.c | 23 +- 72 files changed, 5829 insertions(+), 2612 deletions(-) create mode 100644 release/datafiles/prvicons create mode 100644 source/blender/imbuf/IMB_thumbs.h create mode 100644 source/blender/imbuf/intern/IMB_imginfo.h create mode 100644 source/blender/imbuf/intern/imginfo.c create mode 100644 source/blender/imbuf/intern/md5.c create mode 100644 source/blender/imbuf/intern/md5.h create mode 100644 source/blender/imbuf/intern/thumbs.c create mode 100644 source/blender/include/BIF_filelist.h create mode 100644 source/blender/src/filelist.c create mode 100644 source/blender/src/fsmenu.c create mode 100644 source/blender/src/prvicons.c diff --git a/projectfiles_vc7/blender/imbuf/BL_imbuf.vcproj b/projectfiles_vc7/blender/imbuf/BL_imbuf.vcproj index 61c0a857da1..a214ed3055b 100644 --- a/projectfiles_vc7/blender/imbuf/BL_imbuf.vcproj +++ b/projectfiles_vc7/blender/imbuf/BL_imbuf.vcproj @@ -382,12 +382,18 @@ + + + + @@ -418,6 +424,9 @@ + + @@ -533,6 +542,9 @@ + + @@ -548,6 +560,9 @@ + + diff --git a/projectfiles_vc7/blender/src/BL_src.vcproj b/projectfiles_vc7/blender/src/BL_src.vcproj index c788fb44cab..b3a92ed98bd 100644 --- a/projectfiles_vc7/blender/src/BL_src.vcproj +++ b/projectfiles_vc7/blender/src/BL_src.vcproj @@ -328,12 +328,18 @@ + + + + @@ -463,6 +469,9 @@ + + @@ -680,6 +689,9 @@ + + diff --git a/release/datafiles/prvicons b/release/datafiles/prvicons new file mode 100644 index 00000000000..de3980f9676 Binary files /dev/null and b/release/datafiles/prvicons differ diff --git a/source/blender/blenkernel/BKE_icons.h b/source/blender/blenkernel/BKE_icons.h index 315c7dc7a53..737adea78be 100644 --- a/source/blender/blenkernel/BKE_icons.h +++ b/source/blender/blenkernel/BKE_icons.h @@ -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 */ diff --git a/source/blender/blenkernel/bad_level_call_stubs/stubs.c b/source/blender/blenkernel/bad_level_call_stubs/stubs.c index 4521f1d1dea..04fac832cc4 100644 --- a/source/blender/blenkernel/bad_level_call_stubs/stubs.c +++ b/source/blender/blenkernel/bad_level_call_stubs/stubs.c @@ -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) {}; + diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c index ee37a4ec9f9..f144d2badd1 100644 --- a/source/blender/blenkernel/intern/icons.c +++ b/source/blender/blenkernel/intern/icons.c @@ -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 #include @@ -41,6 +39,11 @@ #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; ichanged[i] = 1; + } + return prv_img; +} + +void BKE_previewimg_free(PreviewImage **prv) +{ + if(prv && (*prv)) { + int i; + + for (i=0; irect[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; ichanged[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); diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 2c91c6cb0be..3a64c3504cb 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -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 */ diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 56b8307020a..f5f726b1745 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -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 */ } diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 3f26501db6f..349ccda8126 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -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; } diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index bda933802ee..d41ceb5a4b7 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -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; } diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index 612c095aac7..ce41720cb9d 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -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); diff --git a/source/blender/blenlib/BLI_blenlib.h b/source/blender/blenlib/BLI_blenlib.h index 6e51d171461..aaa50206ddb 100644 --- a/source/blender/blenlib/BLI_blenlib.h +++ b/source/blender/blenlib/BLI_blenlib.h @@ -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. diff --git a/source/blender/blenlib/BLI_storage_types.h b/source/blender/blenlib/BLI_storage_types.h index 825a8bc9cbd..ebce33852a1 100644 --- a/source/blender/blenlib/BLI_storage_types.h +++ b/source/blender/blenlib/BLI_storage_types.h @@ -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 diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c index cfce8e3dafa..2a47dcc300b 100644 --- a/source/blender/blenlib/intern/util.c +++ b/source/blender/blenlib/intern/util.c @@ -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 */ diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h index 7f621410a4f..09edfe90d02 100644 --- a/source/blender/blenloader/BLO_readfile.h +++ b/source/blender/blenloader/BLO_readfile.h @@ -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); diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c index 5f67c060c04..dfa06ebdeb8 100644 --- a/source/blender/blenloader/intern/readblenentry.c +++ b/source/blender/blenloader/intern/readblenentry.c @@ -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; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index fa21161f8eb..1f1dd84f49c 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -137,6 +137,7 @@ #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; amtex[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; amtex[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; atotfile; a++) { - if(sfile->filelist[a].flags & ACTIVE) { - append_named_part(fd, mainl, scene, sfile->filelist[a].relname, idcode, sfile->flag); + for(a=0; amainlist); - 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; atotfile; a++) { - if(sfile->filelist[a].flags & ACTIVE) { + for(a=0; afile[0]) { - for(a=0; atotfile; a++) { - if( strcmp(sfile->filelist[a].relname, sfile->file)==0) break; + if(file[0]) { + for(a=0; atotfile) { + 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; diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index ee914954b90..90873efb5b9 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -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; } diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index 840d39ea0bd..3e8aaea4f3c 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -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 diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h index d43b78df0b6..91ffa188fcc 100644 --- a/source/blender/imbuf/IMB_imbuf_types.h +++ b/source/blender/imbuf/IMB_imbuf_types.h @@ -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 index 00000000000..22565dac688 --- /dev/null +++ b/source/blender/imbuf/IMB_thumbs.h @@ -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 index 00000000000..91073ec9575 --- /dev/null +++ b/source/blender/imbuf/intern/IMB_imginfo.h @@ -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 */ diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c index 003d377389b..a5d404740cf 100644 --- a/source/blender/imbuf/intern/allocimbuf.c +++ b/source/blender/imbuf/intern/allocimbuf.c @@ -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){ diff --git a/source/blender/imbuf/intern/anim.c b/source/blender/imbuf/intern/anim.c index a1ef735ffdb..24ea79ee90d 100644 --- a/source/blender/imbuf/intern/anim.c +++ b/source/blender/imbuf/intern/anim.c @@ -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 index 00000000000..c443b1be885 --- /dev/null +++ b/source/blender/imbuf/intern/imginfo.c @@ -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 +#include + +#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 index 00000000000..3119dd1fe7d --- /dev/null +++ b/source/blender/imbuf/intern/md5.c @@ -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 . */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +# include +# include + +#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 index 00000000000..ed38c192d2b --- /dev/null +++ b/source/blender/imbuf/intern/md5.h @@ -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 + +#if defined HAVE_LIMITS_H || _LIBC +# include +#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 ) 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 diff --git a/source/blender/imbuf/intern/png.c b/source/blender/imbuf/intern/png.c index 46c5232a61a..bb48ff71bff 100644 --- a/source/blender/imbuf/intern/png.c +++ b/source/blender/imbuf/intern/png.c @@ -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 index 00000000000..6976aff6b39 --- /dev/null +++ b/source/blender/imbuf/intern/thumbs.c @@ -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 /* 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 /* for SHGetSpecialFolderPath, has to be done before BLI_winstuff because 'near' is disabled through BLI_windstuff */ +#include "BLI_winstuff.h" +#include /* getpid */ +#else +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#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 index 00000000000..a8d8e6f9445 --- /dev/null +++ b/source/blender/include/BIF_filelist.h @@ -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 + diff --git a/source/blender/include/BIF_fsmenu.h b/source/blender/include/BIF_fsmenu.h index b32dee01854..1c5280c14f8 100644 --- a/source/blender/include/BIF_fsmenu.h +++ b/source/blender/include/BIF_fsmenu.h @@ -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); diff --git a/source/blender/include/BIF_imasel.h b/source/blender/include/BIF_imasel.h index d6a1800730b..0e92abe14e4 100644 --- a/source/blender/include/BIF_imasel.h +++ b/source/blender/include/BIF_imasel.h @@ -33,28 +33,19 @@ #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 diff --git a/source/blender/include/BIF_interface_icons.h b/source/blender/include/BIF_interface_icons.h index c69fa122099..c628d68e9db 100644 --- a/source/blender/include/BIF_interface_icons.h +++ b/source/blender/include/BIF_interface_icons.h @@ -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(); diff --git a/source/blender/include/BIF_resources.h b/source/blender/include/BIF_resources.h index 77c0f5861e3..d734e59046f 100644 --- a/source/blender/include/BIF_resources.h +++ b/source/blender/include/BIF_resources.h @@ -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, diff --git a/source/blender/include/BIF_space.h b/source/blender/include/BIF_space.h index 884f0459abf..12f1e1586a0 100644 --- a/source/blender/include/BIF_space.h +++ b/source/blender/include/BIF_space.h @@ -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 diff --git a/source/blender/include/BSE_drawimasel.h b/source/blender/include/BSE_drawimasel.h index f412ca08584..6c68ba79bb9 100644 --- a/source/blender/include/BSE_drawimasel.h +++ b/source/blender/include/BSE_drawimasel.h @@ -33,27 +33,28 @@ #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 */ diff --git a/source/blender/include/BSE_filesel.h b/source/blender/include/BSE_filesel.h index 6934899062e..a41eea32040 100644 --- a/source/blender/include/BSE_filesel.h +++ b/source/blender/include/BSE_filesel.h @@ -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); diff --git a/source/blender/include/blendef.h b/source/blender/include/blendef.h index 596b11c609c..349685a5d8a 100644 --- a/source/blender/include/blendef.h +++ b/source/blender/include/blendef.h @@ -344,7 +344,10 @@ #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 diff --git a/source/blender/include/datatoc.h b/source/blender/include/datatoc.h index d7a1aa5c78c..7afd4428d70 100644 --- a/source/blender/include/datatoc.h +++ b/source/blender/include/datatoc.h @@ -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[]; diff --git a/source/blender/include/interface.h b/source/blender/include/interface.h index d7be02c6fc5..d8e779b9af8 100644 --- a/source/blender/include/interface.h +++ b/source/blender/include/interface.h @@ -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 diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index f8ad5399af3..d939d0dc879 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -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. * diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h index cf13a1116a9..694279d4605 100644 --- a/source/blender/makesdna/DNA_image_types.h +++ b/source/blender/makesdna/DNA_image_types.h @@ -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. */ diff --git a/source/blender/makesdna/DNA_lamp_types.h b/source/blender/makesdna/DNA_lamp_types.h index 104b13ea24c..5d998ccca6e 100644 --- a/source/blender/makesdna/DNA_lamp_types.h +++ b/source/blender/makesdna/DNA_lamp_types.h @@ -79,6 +79,9 @@ typedef struct Lamp { struct MTex *mtex[10]; struct Ipo *ipo; + /* preview */ + struct PreviewImage *preview; + ScriptLink scriptlink; } Lamp; diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index 0fad110d64b..b6bc475fb28 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -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; diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index e70c8baaa78..42f08e3795e 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -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 */ diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h index 4ad92f9f33d..064cfe39d45 100644 --- a/source/blender/makesdna/DNA_texture_types.h +++ b/source/blender/makesdna/DNA_texture_types.h @@ -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; diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 2e83e773ce8..945fe5e00d3 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -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 diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h index 4b8dfe3812a..7349e37f3b7 100644 --- a/source/blender/makesdna/DNA_world_types.h +++ b/source/blender/makesdna/DNA_world_types.h @@ -108,6 +108,9 @@ typedef struct World { struct Ipo *ipo; struct MTex *mtex[10]; + /* previews */ + struct PreviewImage *preview; + ScriptLink scriptlink; } World; diff --git a/source/blender/python/api2_2x/Window.c b/source/blender/python/api2_2x/Window.c index 22ae5586e2c..cf128ec8dd2 100644 --- a/source/blender/python/api2_2x/Window.c +++ b/source/blender/python/api2_2x/Window.c @@ -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() */ diff --git a/source/blender/quicktime/apple/quicktime_import.c b/source/blender/quicktime/apple/quicktime_import.c index c701d4d41d0..862b20b5260 100644 --- a/source/blender/quicktime/apple/quicktime_import.c +++ b/source/blender/quicktime/apple/quicktime_import.c @@ -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; diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index 951a4ac25e4..ee5e194bd35 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -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" diff --git a/source/blender/src/buttons_shading.c b/source/blender/src/buttons_shading.c index 1e1a9b1e01f..ab0c1cb3ad2 100644 --- a/source/blender/src/buttons_shading.c +++ b/source/blender/src/buttons_shading.c @@ -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... */ diff --git a/source/blender/src/drawimasel.c b/source/blender/src/drawimasel.c index 45757170f78..00917233109 100644 --- a/source/blender/src/drawimasel.c +++ b/source/blender/src/drawimasel.c @@ -47,811 +47,613 @@ #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; ablockhandler[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; } - diff --git a/source/blender/src/drawnode.c b/source/blender/src/drawnode.c index d9878d40d8e..d903d74681b 100644 --- a/source/blender/src/drawnode.c +++ b/source/blender/src/drawnode.c @@ -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); diff --git a/source/blender/src/editimasel.c b/source/blender/src/editimasel.c index f3f9aa31d07..bb56eb37288 100644 --- a/source/blender/src/editimasel.c +++ b/source/blender/src/editimasel.c @@ -43,411 +43,1080 @@ #include #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 +#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; afiles, 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; afiles, 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; afiles, 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]v2d.vert.xmax && mval[1]>simasel->v2d.vert.ymin && mval[1]v2d.vert.ymax) { + do_filescroll(simasel); + } + else if(mval[0]>simasel->viewrect.xmin && mval[0]viewrect.xmax + && mval[1]>simasel->viewrect.ymin && mval[1]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]bookmarkrect.xmax && mval[1]>simasel->bookmarkrect.ymin && mval[1]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]viewrect.xmax + && mval[1]>simasel->viewrect.ymin && mval[1]viewrect.ymax) { + set_active_file(simasel, mval[0], mval[1]); + if(simasel->active_file >=0 && simasel->active_fileselstate = 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]viewrect.xmax && mval[1]>simasel->viewrect.ymin && mval[1]viewrect.ymax) { + set_active_file(simasel, mval[0], mval[1]); + if(simasel->active_file >=0 && simasel->active_filefiles, 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]bookmarkrect.xmax && mval[1]>simasel->bookmarkrect.ymin && mval[1]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]bookmarkrect.xmax && mval[1]>simasel->bookmarkrect.ymin && mval[1]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); } } diff --git a/source/blender/src/editscreen.c b/source/blender/src/editscreen.c index 814985cb165..44069beaf43 100644 --- a/source/blender/src/editscreen.c +++ b/source/blender/src/editscreen.c @@ -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; } diff --git a/source/blender/src/editsima.c b/source/blender/src/editsima.c index 94990b8a393..06593227dbf 100644 --- a/source/blender/src/editsima.c +++ b/source/blender/src/editsima.c @@ -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 index 00000000000..6dc97faca4e --- /dev/null +++ b/source/blender/src/filelist.c @@ -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 +#include +#include + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifndef WIN32 +#include +#else +#include +#include +#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) +{ + char buf[32]; + char *lslash; + + BLI_strncpy(buf, group, 31); + lslash= BLI_last_slash(buf); + if (lslash) + lslash[0]= '\0'; + + return BLO_idcode_from_name(buf); +} + + +#define SPECIAL_IMG_SIZE 48 +#define SPECIAL_IMG_ROWS 4 +#define SPECIAL_IMG_COLS 4 + +#define SPECIAL_IMG_FOLDER 0 +#define SPECIAL_IMG_PARENT 1 +#define SPECIAL_IMG_REFRESH 2 +#define SPECIAL_IMG_BLENDFILE 3 +#define SPECIAL_IMG_SOUNDFILE 4 +#define SPECIAL_IMG_MOVIEFILE 5 +#define SPECIAL_IMG_PYTHONFILE 6 +#define SPECIAL_IMG_TEXTFILE 7 +#define SPECIAL_IMG_FONTFILE 8 +#define SPECIAL_IMG_UNKNOWNFILE 9 +#define SPECIAL_IMG_MAX SPECIAL_IMG_UNKNOWNFILE + 1 + +static ImBuf* gSpecialFileImages[SPECIAL_IMG_MAX]; + + +/* ******************* SORT ******************* */ + +static int compare_name(const void *a1, const void *a2) +{ + const struct direntry *entry1=a1, *entry2=a2; + + /* type is is equal to stat.st_mode */ + + if (S_ISDIR(entry1->type)){ + if (S_ISDIR(entry2->type)==0) return (-1); + } else{ + if (S_ISDIR(entry2->type)) return (1); + } + if (S_ISREG(entry1->type)){ + if (S_ISREG(entry2->type)==0) return (-1); + } else{ + if (S_ISREG(entry2->type)) return (1); + } + if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1); + if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1); + + /* make sure "." and ".." are always first */ + if( strcmp(entry1->relname, ".")==0 ) return (-1); + if( strcmp(entry2->relname, ".")==0 ) return (1); + if( strcmp(entry1->relname, "..")==0 ) return (-1); + + return (BLI_strcasecmp(entry1->relname,entry2->relname)); +} + +static int compare_date(const void *a1, const void *a2) +{ + const struct direntry *entry1=a1, *entry2=a2; + + /* type is equal to stat.st_mode */ + + if (S_ISDIR(entry1->type)){ + if (S_ISDIR(entry2->type)==0) return (-1); + } else{ + if (S_ISDIR(entry2->type)) return (1); + } + if (S_ISREG(entry1->type)){ + if (S_ISREG(entry2->type)==0) return (-1); + } else{ + if (S_ISREG(entry2->type)) return (1); + } + if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1); + if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1); + + /* make sure "." and ".." are always first */ + if( strcmp(entry1->relname, ".")==0 ) return (-1); + if( strcmp(entry2->relname, ".")==0 ) return (1); + if( strcmp(entry1->relname, "..")==0 ) return (-1); + + if ( entry1->s.st_mtime < entry2->s.st_mtime) return 1; + if ( entry1->s.st_mtime > entry2->s.st_mtime) return -1; + + else return BLI_strcasecmp(entry1->relname,entry2->relname); +} + +static int compare_size(const void *a1, const void *a2) +{ + const struct direntry *entry1=a1, *entry2=a2; + + /* type is equal to stat.st_mode */ + + if (S_ISDIR(entry1->type)){ + if (S_ISDIR(entry2->type)==0) return (-1); + } else{ + if (S_ISDIR(entry2->type)) return (1); + } + if (S_ISREG(entry1->type)){ + if (S_ISREG(entry2->type)==0) return (-1); + } else{ + if (S_ISREG(entry2->type)) return (1); + } + if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1); + if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1); + + /* make sure "." and ".." are always first */ + if( strcmp(entry1->relname, ".")==0 ) return (-1); + if( strcmp(entry2->relname, ".")==0 ) return (1); + if( strcmp(entry1->relname, "..")==0 ) return (-1); + + if ( entry1->s.st_size < entry2->s.st_size) return 1; + if ( entry1->s.st_size > entry2->s.st_size) return -1; + else return BLI_strcasecmp(entry1->relname,entry2->relname); +} + +static int compare_extension(const void *a1, const void *a2) { + const struct direntry *entry1=a1, *entry2=a2; + char *sufix1, *sufix2; + char *nil=""; + + if (!(sufix1= strstr (entry1->relname, ".blend.gz"))) + sufix1= strrchr (entry1->relname, '.'); + if (!(sufix2= strstr (entry2->relname, ".blend.gz"))) + sufix2= strrchr (entry2->relname, '.'); + if (!sufix1) sufix1= nil; + if (!sufix2) sufix2= nil; + + /* type is is equal to stat.st_mode */ + + if (S_ISDIR(entry1->type)){ + if (S_ISDIR(entry2->type)==0) return (-1); + } else{ + if (S_ISDIR(entry2->type)) return (1); + } + if (S_ISREG(entry1->type)){ + if (S_ISREG(entry2->type)==0) return (-1); + } else{ + if (S_ISREG(entry2->type)) return (1); + } + if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1); + if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1); + + /* make sure "." and ".." are always first */ + if( strcmp(entry1->relname, ".")==0 ) return (-1); + if( strcmp(entry2->relname, ".")==0 ) return (1); + if( strcmp(entry1->relname, "..")==0 ) return (-1); + if( strcmp(entry2->relname, "..")==0 ) return (-1); + + return (BLI_strcasecmp(sufix1, sufix2)); +} + +void BIF_filelist_filter(FileList* filelist) +{ + int num_files = 0; + int num_filtered = 0; + struct direntry *old_filelist; + int i, j; + + if (!filelist->filelist) + return; + + if (!filelist->filter) { + if (filelist->unfiltered) { + old_filelist = filelist->filelist; + filelist->filelist = filelist->unfiltered; + filelist->numfiles = filelist->numunfiltered; + filelist->unfiltered = 0; + filelist->numunfiltered = 0; + free (old_filelist); + } + return; + } + + if (!filelist->unfiltered) { + filelist->unfiltered = filelist->filelist; + filelist->numunfiltered = filelist->numfiles; + } + + old_filelist = filelist->unfiltered; + num_files = filelist->numunfiltered; + + filelist->filelist = 0; + + // How many files are left after filter ? + for (i = 0; i < num_files; ++i) { + if (old_filelist[i].flags & filelist->filter) { + num_filtered++; + } + else if (old_filelist[i].type & S_IFDIR) { + if (filelist->filter & FOLDERFILE) { + num_filtered++; + } + } + } + + filelist->filelist = (struct direntry *)malloc(num_filtered * sizeof(struct direntry)); + filelist->numfiles = num_filtered; + + for (i = 0, j=0; i < num_files; ++i) { + if (old_filelist[i].flags & filelist->filter) { + filelist->filelist[j++] = old_filelist[i]; + } + else if (old_filelist[i].type & S_IFDIR) { + if (filelist->filter & FOLDERFILE) { + filelist->filelist[j++] = old_filelist[i]; + } + } + } +} + +void BIF_filelist_init_icons() +{ + short x, y, k; + ImBuf *bbuf; + ImBuf *ibuf; + bbuf = IMB_ibImageFromMemory((int *)datatoc_prvicons, datatoc_prvicons_size, IB_rect); + if (bbuf) { + for (y=0; yrect[k*SPECIAL_IMG_SIZE], &bbuf->rect[(k+y*SPECIAL_IMG_SIZE)*SPECIAL_IMG_SIZE*SPECIAL_IMG_COLS+x*SPECIAL_IMG_SIZE], SPECIAL_IMG_SIZE*sizeof(int)); + } + gSpecialFileImages[tile] = ibuf; + } + } + } + IMB_freeImBuf(bbuf); + } + +} + +void BIF_filelist_free_icons() +{ + int i; + for (i=0; i < SPECIAL_IMG_MAX; ++i) { + IMB_freeImBuf(gSpecialFileImages[i]); + gSpecialFileImages[i] = NULL; + } +} + +struct FileList* BIF_filelist_new() +{ + FileList* p = MEM_callocN( sizeof(FileList), "filelist" ); + p->filelist = 0; + p->numfiles = 0; + p->dir[0] = '\0'; + p->libfiledata = 0; + p->type = 0; + p->has_func = 0; + p->filter = 0; + return p; +} + +struct FileList* BIF_filelist_copy(struct FileList* filelist) +{ + FileList* p = BIF_filelist_new(); + BLI_strncpy(p->dir, filelist->dir, FILE_MAXDIR); + p->filelist = NULL; + p->unfiltered = NULL; + p->type = filelist->type; + p->ipotype = filelist->ipotype; + p->has_func = filelist->has_func; + + return p; +} + +void BIF_filelist_free(struct FileList* filelist) +{ + int i; + + if (!filelist) { + printf("Attemtping to delete empty filelist.\n"); + return; + } + + if (filelist->unfiltered) { + struct direntry* filtered_files = filelist->filelist; + filelist->filelist = filelist->unfiltered; + filelist->numfiles = filelist->numunfiltered; + filelist->numunfiltered = 0; + free (filtered_files); + filelist->unfiltered = 0; + } + + for (i = 0; i < filelist->numfiles; ++i) { + if (filelist->filelist[i].image) + IMB_freeImBuf(filelist->filelist[i].image); + filelist->filelist[i].image = 0; + if (filelist->filelist[i].relname) + MEM_freeN(filelist->filelist[i].relname); + filelist->filelist[i].relname = 0; + if (filelist->filelist[i].string) + MEM_freeN(filelist->filelist[i].string); + filelist->filelist[i].string = 0; + } + + filelist->numfiles = 0; + free(filelist->filelist); + filelist->filelist = 0; +} + +void BIF_filelist_freelib(struct FileList* filelist) +{ + if(filelist->libfiledata) + BLO_blendhandle_close(filelist->libfiledata); + filelist->libfiledata= 0; +} + +struct BlendHandle *BIF_filelist_lib(struct FileList* filelist) +{ + return filelist->libfiledata; +} + +int BIF_filelist_numfiles(struct FileList* filelist) +{ + return filelist->numfiles; +} + +const char * BIF_filelist_dir(struct FileList* filelist) +{ + return filelist->dir; +} + +void BIF_filelist_setdir(struct FileList* filelist, const char *dir) +{ + BLI_strncpy(filelist->dir, dir, FILE_MAXDIR); +} + +void BIF_filelist_appenddir(struct FileList* filelist, const char *relname) +{ + strcat(filelist->dir, relname); + BLI_cleanup_dir(G.sce, filelist->dir); +} + +void BIF_filelist_imgsize(struct FileList* filelist, short w, short h) +{ + filelist->prv_w = w; + filelist->prv_h = h; +} + +void BIF_filelist_loadimage(struct FileList* filelist, int index) +{ + ImBuf *imb = NULL; + int imgwidth = filelist->prv_w; + int imgheight = filelist->prv_h; + short ex, ey, dx, dy; + float scaledx, scaledy; + + if (!filelist->filelist[index].image) + { + if (filelist->type != FILE_MAIN) + { + if ( filelist->filelist[index].flags & IMAGEFILE ) { + imb = IMB_thumb_manage(filelist->dir, filelist->filelist[index].relname, THB_NORMAL, THB_SOURCE_IMAGE); + } else if ( filelist->filelist[index].flags & MOVIEFILE ) { + imb = IMB_thumb_manage(filelist->dir, filelist->filelist[index].relname, THB_NORMAL, THB_SOURCE_MOVIE); + if (!imb) { + /* remember that file can't be loaded via IMB_open_anim */ + filelist->filelist[index].flags &= ~MOVIEFILE; + filelist->filelist[index].flags |= MOVIEFILE_ICON; + } + } + if (imb) { + if (imb->x > imb->y) { + scaledx = (float)imgwidth; + scaledy = ( (float)imb->y/(float)imb->x )*imgwidth; + } + else { + scaledy = imgheight; + scaledx = ( (float)imb->x/(float)imb->y )*imgheight; + } + ex = (short)scaledx; + ey = (short)scaledy; + + dx = imgwidth - ex; + dy = imgheight - ey; + + IMB_scaleImBuf(imb, ex, ey); + + } + filelist->filelist[index].image = imb; + + } + } +} + +struct ImBuf * BIF_filelist_getimage(struct FileList* filelist, int index) +{ + ImBuf* ibuf = filelist->filelist[index].image; + if (ibuf == NULL) { + struct direntry *file = &filelist->filelist[index]; + if (file->type & S_IFDIR) { + if ( strcmp(filelist->filelist[index].relname, "..") == 0) { + ibuf = gSpecialFileImages[SPECIAL_IMG_PARENT]; + } else if ( strcmp(filelist->filelist[index].relname, ".") == 0) { + ibuf = gSpecialFileImages[SPECIAL_IMG_REFRESH]; + } else { + ibuf = gSpecialFileImages[SPECIAL_IMG_FOLDER]; + } + } else { + ibuf = gSpecialFileImages[SPECIAL_IMG_UNKNOWNFILE]; + } + + if (file->flags & BLENDERFILE) { + ibuf = gSpecialFileImages[SPECIAL_IMG_BLENDFILE]; + } else if ( (file->flags & MOVIEFILE) || (file->flags & MOVIEFILE_ICON) ) { + ibuf = gSpecialFileImages[SPECIAL_IMG_MOVIEFILE]; + } else if (file->flags & SOUNDFILE) { + ibuf = gSpecialFileImages[SPECIAL_IMG_SOUNDFILE]; + } else if (file->flags & PYSCRIPTFILE) { + ibuf = gSpecialFileImages[SPECIAL_IMG_PYTHONFILE]; + } else if (file->flags & FTFONTFILE) { + ibuf = gSpecialFileImages[SPECIAL_IMG_FONTFILE]; + } else if (file->flags & TEXTFILE) { + ibuf = gSpecialFileImages[SPECIAL_IMG_TEXTFILE]; + } + } + return ibuf; +} + +struct direntry * BIF_filelist_file(struct FileList* filelist, int index) +{ + return &filelist->filelist[index]; +} + +int BIF_filelist_find(struct FileList* filelist, char *file) +{ + int index = -1; + int i; + + for (i = 0; i < filelist->numfiles; ++i) { + if ( strcmp(filelist->filelist[i].relname, file) == 0) { + index = i; + break; + } + } + return index; +} + +void BIF_filelist_hidedot(struct FileList* filelist, short hide) +{ + filelist->hide_dot = hide; +} + +void BIF_filelist_setfilter(struct FileList* filelist, unsigned int filter) +{ + filelist->filter = filter; +} + +void BIF_filelist_readdir(struct FileList* filelist) +{ + char wdir[FILE_MAXDIR]; + int finished = 0; + + if (!filelist) return; + filelist->unfiltered = 0; + filelist->filelist = 0; + + if(filelist->type==FILE_MAIN) { + BIF_filelist_from_main(filelist); + finished = 1; + } else if(filelist->type==FILE_LOADLIB) { + BLI_cleanup_dir(G.sce, filelist->dir); + BIF_filelist_from_library(filelist); + if(filelist->libfiledata) { + finished = 1; + } + } + + if (!finished) { + BLI_getwdN(wdir); + + BLI_cleanup_dir(G.sce, filelist->dir); + BLI_hide_dot_files(filelist->hide_dot); + filelist->numfiles = BLI_getdir(filelist->dir, &(filelist->filelist)); + + chdir(wdir); + BIF_filelist_setfiletypes(filelist, G.have_quicktime); + BIF_filelist_filter(filelist); + + } +} + +int BIF_filelist_empty(struct FileList* filelist) +{ + return filelist->filelist == 0; +} + +void BIF_filelist_parent(struct FileList* filelist) +{ +#ifdef WIN32 + char c = '\\'; +#else + char c = '/'; +#endif + char *dir = filelist->dir; + size_t len = strlen(dir); + + while( (len > 0) && (dir[len-1] == c) ) + { + --len; + dir[len] = '\0'; + } + while ( (len > 0) && (dir[len-1] != c) ) + { + --len; + dir[len] = '\0'; + } + if (len == 0) + { + dir[0] = c; dir[1] = '\0'; + } +#ifdef WIN32 + strcat(filelist->dir, "\\"); +#else + strcat(filelist->dir, "/"); +#endif + + BLI_cleanup_dir(G.sce, filelist->dir); + BLI_make_exist(filelist->dir); + BIF_filelist_readdir(filelist); +} + +void BIF_filelist_setfiletypes(struct FileList* filelist, short has_quicktime) +{ + struct direntry *file; + int num; + + file= filelist->filelist; + + for(num=0; numnumfiles; num++, file++) { + file->flags= 0; + file->type= file->s.st_mode; /* restore the mess below */ + + /* Don't check extensions for directories */ + if (file->type & S_IFDIR) + continue; + + + + if(BLO_has_bfile_extension(file->relname)) { + file->flags |= BLENDERFILE; + if(filelist->type==FILE_LOADLIB) { + char name[FILE_MAXDIR+FILE_MAXFILE]; + BLI_strncpy(name, filelist->dir, sizeof(name)); + strcat(name, file->relname); + + /* prevent current file being used as acceptable dir */ + if (BLI_streq(G.main->name, name)==0) { + file->type &= ~S_IFMT; + file->type |= S_IFDIR; + } + } + } else if(BLI_testextensie(file->relname, ".py")) { + file->flags |= PYSCRIPTFILE; + } else if(BLI_testextensie(file->relname, ".txt")) { + file->flags |= TEXTFILE; + } else if( BLI_testextensie(file->relname, ".ttf") + || BLI_testextensie(file->relname, ".ttc") + || BLI_testextensie(file->relname, ".pfb") + || BLI_testextensie(file->relname, ".otf") + || BLI_testextensie(file->relname, ".otc")) { + file->flags |= FTFONTFILE; + } else if (has_quicktime){ + if( BLI_testextensie(file->relname, ".jpg") + || BLI_testextensie(file->relname, ".jpeg") + || BLI_testextensie(file->relname, ".tga") + || BLI_testextensie(file->relname, ".rgb") + || BLI_testextensie(file->relname, ".bmp") + || BLI_testextensie(file->relname, ".png") + || BLI_testextensie(file->relname, ".iff") + || BLI_testextensie(file->relname, ".lbm") + || BLI_testextensie(file->relname, ".gif") + || BLI_testextensie(file->relname, ".psd") + || BLI_testextensie(file->relname, ".tif") + || BLI_testextensie(file->relname, ".tiff") + || BLI_testextensie(file->relname, ".pct") + || BLI_testextensie(file->relname, ".pict") + || BLI_testextensie(file->relname, ".pntg") //macpaint + || BLI_testextensie(file->relname, ".qtif") + || BLI_testextensie(file->relname, ".sgi") +#ifdef WITH_OPENEXR + || BLI_testextensie(file->relname, ".exr") +#endif + ) { + file->flags |= IMAGEFILE; + } + else if(BLI_testextensie(file->relname, ".avi") + || BLI_testextensie(file->relname, ".flc") + || BLI_testextensie(file->relname, ".mov") + || BLI_testextensie(file->relname, ".movie") + || BLI_testextensie(file->relname, ".mp4") + || BLI_testextensie(file->relname, ".m4v") + || BLI_testextensie(file->relname, ".mv")) { + file->flags |= MOVIEFILE; + } + else if(BLI_testextensie(file->relname, ".wav")) { + file->flags |= SOUNDFILE; + } + } else { // no quicktime + if(BLI_testextensie(file->relname, ".jpg") + || BLI_testextensie(file->relname, ".tga") + || BLI_testextensie(file->relname, ".rgb") + || BLI_testextensie(file->relname, ".bmp") + || BLI_testextensie(file->relname, ".png") + || BLI_testextensie(file->relname, ".iff") + || BLI_testextensie(file->relname, ".tif") + || BLI_testextensie(file->relname, ".tiff") +#ifdef WITH_OPENEXR + || BLI_testextensie(file->relname, ".exr") +#endif + || BLI_testextensie(file->relname, ".lbm") + || BLI_testextensie(file->relname, ".sgi")) { + file->flags |= IMAGEFILE; + } + else if(BLI_testextensie(file->relname, ".avi") + || BLI_testextensie(file->relname, ".mp4") + || BLI_testextensie(file->relname, ".mv")) { + file->flags |= MOVIEFILE; + } + else if(BLI_testextensie(file->relname, ".wav")) { + file->flags |= SOUNDFILE; + } + } + } +} + +void BIF_filelist_swapselect(struct FileList* filelist) +{ + struct direntry *file; + int num, act= 0; + + file= filelist->filelist; + for(num=0; numnumfiles; num++, file++) { + if(file->flags & ACTIVE) { + act= 1; + break; + } + } + file= filelist->filelist+2; + for(num=2; numnumfiles; num++, file++) { + if(act) file->flags &= ~ACTIVE; + else file->flags |= ACTIVE; + } +} + +int BIF_filelist_islibrary(struct FileList* filelist, char* dir, char* group) +{ + /* return ok when a blenderfile, in dir is the filename, + * in group the type of libdata + */ + int len; + char *fd; + + strcpy(dir, filelist->dir); + len= strlen(dir); + if(len<7) return 0; + if( dir[len-1] != '/' && dir[len-1] != '\\') return 0; + + group[0]= 0; + dir[len-1]= 0; + + /* Find the last slash */ + fd= (strrchr(dir, '/')>strrchr(dir, '\\'))?strrchr(dir, '/'):strrchr(dir, '\\'); + + if(fd==0) return 0; + *fd= 0; + if(BLO_has_bfile_extension(fd+1)) { + *fd= '/'; + } + else { + char *gp = fd+1; // in case we have a .blend file, gp points to the group + + /* Find the last slash */ + fd= (strrchr(dir, '/')>strrchr(dir, '\\'))?strrchr(dir, '/'):strrchr(dir, '\\'); + if (!fd || !BLO_has_bfile_extension(fd+1)) return 0; + + /* now we know that we are in a blend file and it is safe to + assume that gp actually points to a group */ + BLI_strncpy(group, gp, GROUP_MAX); + } + return 1; +} + +void BIF_filelist_from_library(struct FileList* filelist) +{ + LinkNode *l, *names, *previews; + struct ImBuf* ima; + int ok, i, nnames, idcode; + char filename[FILE_MAXDIR+FILE_MAXFILE]; + char dir[FILE_MAXDIR], group[GROUP_MAX]; + + filelist->type = FILE_LOADLIB; + + /* name test */ + ok= BIF_filelist_islibrary(filelist, dir, group); + if (!ok) { + /* free */ + if(filelist->libfiledata) BLO_blendhandle_close(filelist->libfiledata); + filelist->libfiledata= 0; + return; + } + + BLI_strncpy(filename, G.sce, sizeof(filename)); // G.sce = last file loaded, for UI + + /* there we go */ + /* for the time being only read filedata when libfiledata==0 */ + if (filelist->libfiledata==0) { + filelist->libfiledata= BLO_blendhandle_from_file(dir); + if(filelist->libfiledata==0) return; + } + + idcode= BIF_groupname_to_code(group); + + // memory for strings is passed into filelist[i].relname + // and free'd in freefilelist + previews = NULL; + if (idcode) { + previews= BLO_blendhandle_get_previews(filelist->libfiledata, idcode); + names= BLO_blendhandle_get_datablock_names(filelist->libfiledata, idcode); + /* ugh, no rewind, need to reopen */ + BLO_blendhandle_close(filelist->libfiledata); + filelist->libfiledata= BLO_blendhandle_from_file(dir); + + } else { + names= BLO_blendhandle_get_linkable_groups(filelist->libfiledata); + } + + nnames= BLI_linklist_length(names); + + filelist->numfiles= nnames + 2; + filelist->filelist= malloc(filelist->numfiles * sizeof(*filelist->filelist)); + memset(filelist->filelist, 0, filelist->numfiles * sizeof(*filelist->filelist)); + + filelist->filelist[0].relname= BLI_strdup("."); + filelist->filelist[0].type |= S_IFDIR; + filelist->filelist[1].relname= BLI_strdup(".."); + filelist->filelist[1].type |= S_IFDIR; + + for (i=0, l= names; inext) { + char *blockname= l->link; + + filelist->filelist[i + 2].relname= BLI_strdup(blockname); + if (!idcode) + filelist->filelist[i + 2].type |= S_IFDIR; + } + + if(previews) { + for (i=0, l= previews; inext) { + PreviewImage *img= l->link; + + if (img) { + unsigned int w = img->w[PREVIEW_MIPMAP_LARGE]; + unsigned int h = img->h[PREVIEW_MIPMAP_LARGE]; + unsigned int *rect = img->rect[PREVIEW_MIPMAP_LARGE]; + + /* first allocate imbuf for copying preview into it */ + if (w > 0 && h > 0 && rect) { + ima = IMB_allocImBuf(w, h, 32, IB_rect, 0); + memcpy(ima->rect, rect, w*h*sizeof(unsigned int)); + filelist->filelist[i + 2].image = ima; + filelist->filelist[i + 2].flags = IMAGEFILE; + } + } + } + } + + BLI_linklist_free(names, free); + if (previews) BLI_linklist_free(previews, MEM_freeN); + + BIF_filelist_sort(filelist, FILE_SORTALPHA); + + BLI_strncpy(G.sce, filename, sizeof(filename)); // prevent G.sce to change +} + +void BIF_filelist_append_library(struct FileList *filelist, char *dir, char *file, short flag, int idcode) +{ + BLO_library_append_(&filelist->libfiledata, filelist->filelist, filelist->numfiles, dir, file, flag, idcode); +} + +void BIF_filelist_from_main(struct FileList *filelist) +{ + ID *id; + struct direntry *files, *firstlib = NULL; + ListBase *lb; + int a, fake, idcode, ok, totlib, totbl; + + filelist->type = FILE_MAIN; + + if(filelist->dir[0]=='/') filelist->dir[0]= 0; + + if(filelist->dir[0]) { + idcode= BIF_groupname_to_code(filelist->dir); + if(idcode==0) filelist->dir[0]= 0; + } + + if( filelist->dir[0]==0) { + + /* make directories */ + filelist->numfiles= 23; + filelist->filelist= (struct direntry *)malloc(filelist->numfiles * sizeof(struct direntry)); + + for(a=0; anumfiles; a++) { + memset( &(filelist->filelist[a]), 0 , sizeof(struct direntry)); + filelist->filelist[a].type |= S_IFDIR; + } + + filelist->filelist[0].relname= BLI_strdup(".."); + filelist->filelist[1].relname= BLI_strdup("."); + filelist->filelist[2].relname= BLI_strdup("Scene"); + filelist->filelist[3].relname= BLI_strdup("Object"); + filelist->filelist[4].relname= BLI_strdup("Mesh"); + filelist->filelist[5].relname= BLI_strdup("Curve"); + filelist->filelist[6].relname= BLI_strdup("Metaball"); + filelist->filelist[7].relname= BLI_strdup("Material"); + filelist->filelist[8].relname= BLI_strdup("Texture"); + filelist->filelist[9].relname= BLI_strdup("Image"); + filelist->filelist[10].relname= BLI_strdup("Ika"); + filelist->filelist[11].relname= BLI_strdup("Wave"); + filelist->filelist[12].relname= BLI_strdup("Lattice"); + filelist->filelist[13].relname= BLI_strdup("Lamp"); + filelist->filelist[14].relname= BLI_strdup("Camera"); + filelist->filelist[15].relname= BLI_strdup("Ipo"); + filelist->filelist[16].relname= BLI_strdup("World"); + filelist->filelist[17].relname= BLI_strdup("Screen"); + filelist->filelist[18].relname= BLI_strdup("VFont"); + filelist->filelist[19].relname= BLI_strdup("Text"); + filelist->filelist[20].relname= BLI_strdup("Armature"); + filelist->filelist[21].relname= BLI_strdup("Action"); + filelist->filelist[22].relname= BLI_strdup("NodeTree"); + BIF_filelist_sort(filelist, FILE_SORTALPHA); + } + else { + + /* make files */ + idcode= BIF_groupname_to_code(filelist->dir); + + lb= wich_libbase(G.main, idcode ); + if(lb==0) return; + + id= lb->first; + filelist->numfiles= 0; + while(id) { + + if(filelist->has_func && idcode==ID_IP) { + if(filelist->ipotype== ((Ipo *)id)->blocktype) filelist->numfiles++; + } + else if (!filelist->hide_dot || id->name[2] != '.') { + filelist->numfiles++; + } + + id= id->next; + } + + if(!filelist->has_func) filelist->numfiles+= 2; + filelist->filelist= (struct direntry *)malloc(filelist->numfiles * sizeof(struct direntry)); + + files = filelist->filelist; + + if(!filelist->has_func) { + memset( &(filelist->filelist[0]), 0 , sizeof(struct direntry)); + filelist->filelist[0].relname= BLI_strdup("."); + filelist->filelist[0].type |= S_IFDIR; + memset( &(filelist->filelist[1]), 0 , sizeof(struct direntry)); + filelist->filelist[1].relname= BLI_strdup(".."); + filelist->filelist[1].type |= S_IFDIR; + + files+= 2; + } + + id= lb->first; + totlib= totbl= 0; + + while(id) { + + ok= 0; + if(filelist->has_func && idcode==ID_IP) { + if(filelist->ipotype== ((Ipo *)id)->blocktype) ok= 1; + } + else ok= 1; + + if(ok) { + /* TODO: hide dot files - elubie */ + memset( files, 0 , sizeof(struct direntry)); + if(id->lib==NULL) + files->relname= BLI_strdup(id->name+2); + else { + files->relname= MEM_mallocN(FILE_MAXDIR+FILE_MAXFILE+32, "filename for lib"); + sprintf(files->relname, "%s | %s", id->lib->name, id->name+2); + } + /* files->type |= S_IFDIR; */ + if(!filelist->has_func) { /* F4 DATA BROWSE */ + if(idcode==ID_OB) { + if( ((Object *)id)->flag & SELECT) files->flags |= ACTIVE; + } + else if(idcode==ID_SCE) { + if( ((Scene *)id)->r.scemode & R_BG_RENDER) files->flags |= ACTIVE; + } + } + files->nr= totbl+1; + files->poin= id; + fake= id->flag & LIB_FAKEUSER; + if(idcode == ID_MA || idcode == ID_TE || idcode == ID_LA || idcode == ID_WO || idcode == ID_IM) { + files->flags |= IMAGEFILE; + } + if(id->lib && fake) sprintf(files->extra, "LF %d", id->us); + else if(id->lib) sprintf(files->extra, "L %d", id->us); + else if(fake) sprintf(files->extra, "F %d", id->us); + else sprintf(files->extra, " %d", id->us); + + if(id->lib) { + if(totlib==0) firstlib= files; + totlib++; + } + + files++; + totbl++; + } + + id= id->next; + } + + /* only qsort of library blocks */ + if(totlib>1) { + qsort(firstlib, totlib, sizeof(struct direntry), compare_name); + } + } +} + + +void BIF_filelist_settype(struct FileList* filelist, int type) +{ + filelist->type = type; +} + +short BIF_filelist_gettype(struct FileList* filelist) +{ + return filelist->type; +} + +void BIF_filelist_sort(struct FileList* filelist, short sort) +{ + struct direntry *file; + int num;/* , act= 0; */ + + switch(sort) { + case FILE_SORTALPHA: + qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_name); + break; + case FILE_SORTDATE: + qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_date); + break; + case FILE_SORTSIZE: + qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_size); + break; + case FILE_SORTEXTENS: + qsort(filelist->filelist, filelist->numfiles, sizeof(struct direntry), compare_extension); + } + + file= filelist->filelist; + for(num=0; numnumfiles; num++, file++) { + file->flags &= ~HILITE; + } +} + + +void BIF_filelist_setipotype(struct FileList* filelist, short ipotype) +{ + filelist->ipotype = ipotype; +} + +void BIF_filelist_hasfunc(struct FileList* filelist, int has_func) +{ + filelist->has_func = has_func; +} + diff --git a/source/blender/src/filesel.c b/source/blender/src/filesel.c index 036e13f3f3b..242c7c0a12c 100644 --- a/source/blender/src/filesel.c +++ b/source/blender/src/filesel.c @@ -86,6 +86,7 @@ #include "BKE_utildefines.h" #include "BIF_editview.h" +#include "BIF_filelist.h" #include "BIF_gl.h" #include "BIF_interface.h" #include "BIF_language.h" @@ -116,7 +117,7 @@ #endif #if defined WIN32 || defined __BeOS -int fnmatch(const char *pattern, const char *string, int flags) +static int fnmatch(const char *pattern, const char *string, int flags) { return 0; } @@ -170,155 +171,6 @@ static float pixels_to_ofs; static char otherdir[FILE_MAX]; static ScrArea *otherarea; -/* FSMENU HANDLING */ - - /* FSMenuEntry's without paths indicate seperators */ -typedef struct _FSMenuEntry FSMenuEntry; -struct _FSMenuEntry { - FSMenuEntry *next; - - char *path; -}; - -static FSMenuEntry *fsmenu= 0; - -int fsmenu_get_nentries(void) -{ - FSMenuEntry *fsme; - int count= 0; - - for (fsme= fsmenu; fsme; fsme= fsme->next) - count++; - - return count; -} -int fsmenu_is_entry_a_seperator(int idx) -{ - FSMenuEntry *fsme; - - for (fsme= fsmenu; fsme && idx; fsme= fsme->next) - idx--; - - return (fsme && !fsme->path)?1:0; -} -char *fsmenu_get_entry(int idx) -{ - FSMenuEntry *fsme; - - for (fsme= fsmenu; fsme && idx; fsme= fsme->next) - idx--; - - return fsme?fsme->path:NULL; -} -char *fsmenu_build_menu(void) -{ - DynStr *ds= BLI_dynstr_new(); - FSMenuEntry *fsme; - char *menustr; - - for (fsme= fsmenu; fsme; fsme= fsme->next) { - if (!fsme->path) { - /* clean consecutive seperators and ignore trailing ones */ - if (fsme->next) { - if (fsme->next->path) { - BLI_dynstr_append(ds, "%l|"); - } else { - FSMenuEntry *next= fsme->next; - fsme->next= next->next; - MEM_freeN(next); - } - } - } else { - BLI_dynstr_append(ds, fsme->path); - if (fsme->next) BLI_dynstr_append(ds, "|"); - } - } - - menustr= BLI_dynstr_get_cstring(ds); - BLI_dynstr_free(ds); - return menustr; -} -static FSMenuEntry *fsmenu_get_last_separator(void) -{ - FSMenuEntry *fsme, *lsep=NULL; - - for (fsme= fsmenu; fsme; fsme= fsme->next) - if (!fsme->path) - lsep= fsme; - - return lsep; -} -void fsmenu_insert_entry(char *path, int sorted) -{ - FSMenuEntry *prev= fsmenu_get_last_separator(); - FSMenuEntry *fsme= prev?prev->next:fsmenu; - - for (; fsme; prev= fsme, fsme= fsme->next) { - if (fsme->path) { - if (BLI_streq(path, fsme->path)) { - return; - } else if (sorted && strcmp(path, fsme->path)<0) { - break; - } - } - } - - fsme= MEM_mallocN(sizeof(*fsme), "fsme"); - fsme->path= BLI_strdup(path); - - if (prev) { - fsme->next= prev->next; - prev->next= fsme; - } else { - fsme->next= fsmenu; - fsmenu= fsme; - } -} -void fsmenu_append_seperator(void) -{ - if (fsmenu) { - FSMenuEntry *fsme= fsmenu; - - while (fsme->next) fsme= fsme->next; - - fsme->next= MEM_mallocN(sizeof(*fsme), "fsme"); - fsme->next->next= NULL; - fsme->next->path= NULL; - } -} -void fsmenu_remove_entry(int idx) -{ - FSMenuEntry *prev= NULL, *fsme= fsmenu; - - for (fsme= fsmenu; fsme && idx; prev= fsme, fsme= fsme->next) - if (fsme->path) - idx--; - - if (fsme) { - if (prev) { - prev->next= fsme->next; - } else { - fsmenu= fsme->next; - } - - MEM_freeN(fsme->path); - MEM_freeN(fsme); - } -} -void fsmenu_free(void) -{ - FSMenuEntry *fsme= fsmenu; - - while (fsme) { - FSMenuEntry *n= fsme->next; - - if (fsme->path) MEM_freeN(fsme->path); - MEM_freeN(fsme); - - fsme= n; - } -} - /* ******************* SORT ******************* */ static int compare_name(const void *a1, const void *a2) @@ -1399,41 +1251,6 @@ void activate_fileselect_args(int type, char *title, char *file, void (*func)(ch activate_fileselect_(type, title, file, NULL, NULL, NULL, NULL, func, arg1, arg2); } - -void activate_imageselect(int type, char *title, char *file, void (*func)(char *)) -{ - SpaceImaSel *simasel; - char dir[FILE_MAX], name[FILE_MAX]; - - if(curarea==NULL) return; - if(curarea->win==0) return; - - newspace(curarea, SPACE_IMASEL); - - /* sometimes double, when area is already SPACE_FILE with a different file name */ - addqueue(curarea->headwin, CHANGED, 1); - addqueue(curarea->win, CHANGED, 1); - - name[2]= 0; - BLI_strncpy(name, file, sizeof(name)); - - simasel= curarea->spacedata.first; - simasel->returnfunc= func; - - if(BLI_convertstringcode(name, G.sce, G.scene->r.cfra)) simasel->mode |= IMS_STRINGCODE; - else simasel->mode &= ~IMS_STRINGCODE; - - BLI_split_dirfile(name, dir, simasel->file); - BLI_cleanup_dir(G.sce, simasel->dir); - if(strcmp(dir, simasel->dir)!=0) simasel->fase= 0; - - BLI_strncpy(simasel->dir, dir, sizeof(simasel->dir)); - BLI_strncpy(simasel->title, title, sizeof(simasel->title)); - - /* filetoname= 1; */ -} - - void activate_databrowse(ID *id, int idcode, int fromcode, int retval, short *menup, void (*func)(unsigned short)) { ListBase *lb; @@ -1603,7 +1420,7 @@ static void filesel_execute(SpaceFile *sfile) allqueue(REDRAWALL, 1); } else if(filesel_has_func(sfile)) { - fsmenu_insert_entry(sfile->dir, 1); + fsmenu_insert_entry(sfile->dir, 1, 0); if(sfile->type==FILE_MAIN) { /* DATABROWSE */ if (sfile->menup) { /* with value pointing to ID block index */ @@ -2017,7 +1834,7 @@ void winqreadfilespace(ScrArea *sa, void *spacedata, BWinEvent *evt) strcat(sfile->dir, sfile->filelist[act].relname); strcat(sfile->dir,"/"); BLI_cleanup_dir(G.sce, sfile->dir); - freefilelist(sfile); + freefilelist(sfile); sfile->ofs= 0; do_draw= 1; } diff --git a/source/blender/src/fsmenu.c b/source/blender/src/fsmenu.c new file mode 100644 index 00000000000..1d03291b135 --- /dev/null +++ b/source/blender/src/fsmenu.c @@ -0,0 +1,260 @@ +/** + * $Id: fsmenu.c 11698 2007-08-19 12:22:51Z elubie $ + * + * ***** 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 ***** + */ + +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BMF_Api.h" + +#include "BLI_blenlib.h" +#include "BLI_linklist.h" +#include "BLI_dynstr.h" +#include "BIF_usiblender.h" + + +#include "BIF_fsmenu.h" /* include ourselves */ + + +/* FSMENU HANDLING */ + + /* FSMenuEntry's without paths indicate seperators */ +typedef struct _FSMenuEntry FSMenuEntry; +struct _FSMenuEntry { + FSMenuEntry *next; + + char *path; + short save; +}; + +static FSMenuEntry *fsmenu= 0; + +int fsmenu_get_nentries(void) +{ + FSMenuEntry *fsme; + int count= 0; + + for (fsme= fsmenu; fsme; fsme= fsme->next) + count++; + + return count; +} +int fsmenu_is_entry_a_seperator(int idx) +{ + FSMenuEntry *fsme; + + for (fsme= fsmenu; fsme && idx; fsme= fsme->next) + idx--; + + return (fsme && !fsme->path)?1:0; +} +char *fsmenu_get_entry(int idx) +{ + FSMenuEntry *fsme; + + for (fsme= fsmenu; fsme && idx; fsme= fsme->next) + idx--; + + return fsme?fsme->path:NULL; +} +char *fsmenu_build_menu(void) +{ + DynStr *ds= BLI_dynstr_new(); + FSMenuEntry *fsme; + char *menustr; + + for (fsme= fsmenu; fsme; fsme= fsme->next) { + if (!fsme->path) { + /* clean consecutive seperators and ignore trailing ones */ + if (fsme->next) { + if (fsme->next->path) { + BLI_dynstr_append(ds, "%l|"); + } else { + FSMenuEntry *next= fsme->next; + fsme->next= next->next; + MEM_freeN(next); + } + } + } else { + if (fsme->save) { + BLI_dynstr_append(ds, "o "); + } else { + BLI_dynstr_append(ds, " "); + } + BLI_dynstr_append(ds, fsme->path); + if (fsme->next) BLI_dynstr_append(ds, "|"); + } + } + + menustr= BLI_dynstr_get_cstring(ds); + BLI_dynstr_free(ds); + return menustr; +} +static FSMenuEntry *fsmenu_get_last_separator(void) +{ + FSMenuEntry *fsme, *lsep=NULL; + + for (fsme= fsmenu; fsme; fsme= fsme->next) + if (!fsme->path) + lsep= fsme; + + return lsep; +} + +static FSMenuEntry *fsmenu_get_first_separator(void) +{ + FSMenuEntry *fsme, *lsep=NULL; + + for (fsme= fsmenu; fsme; fsme= fsme->next) + if (!fsme->path) { + lsep= fsme; + break; + } + + return lsep; +} + +void fsmenu_insert_entry(char *path, int sorted, short save) +{ + FSMenuEntry *prev; + FSMenuEntry *fsme; + + if (save) { + prev = fsmenu_get_first_separator(); + } else { + prev = fsmenu_get_last_separator(); + } + fsme= prev?prev->next:fsmenu; + + for (; fsme; prev= fsme, fsme= fsme->next) { + if (fsme->path) { + if (BLI_streq(path, fsme->path)) { + return; + } else if (sorted && strcmp(path, fsme->path)<0) { + break; + } + } else { + // if we're bookmarking this, file should come + // before the last separator, only automatically added + // current dir go after the last sep. + if (save) { + break; + } + } + } + + fsme= MEM_mallocN(sizeof(*fsme), "fsme"); + fsme->path= BLI_strdup(path); + fsme->save = save; + + if (prev) { + fsme->next= prev->next; + prev->next= fsme; + } else { + fsme->next= fsmenu; + fsmenu= fsme; + } +} +void fsmenu_append_separator(void) +{ + if (fsmenu) { + FSMenuEntry *fsme= fsmenu; + + while (fsme->next) fsme= fsme->next; + + fsme->next= MEM_mallocN(sizeof(*fsme), "fsme"); + fsme->next->next= NULL; + fsme->next->path= NULL; + } +} +void fsmenu_remove_entry(int idx) +{ + FSMenuEntry *prev= NULL, *fsme= fsmenu; + + for (fsme= fsmenu; fsme && idx; prev= fsme, fsme= fsme->next) + idx--; + + if (fsme) { + if (prev) { + prev->next= fsme->next; + } else { + fsmenu= fsme->next; + if (fsme->save) { + if (prev) { + prev->next= fsme->next; + } else { + fsmenu= fsme->next; + } + // you should only be able to remove entries that were + // not added by default + if (fsme->path) { + MEM_freeN(fsme->path); + } + MEM_freeN(fsme); + } + } + } +} + +void fsmenu_write_file(const char *filename) +{ + FSMenuEntry *fsme= fsmenu; + + FILE *fp = fopen(filename, "w"); + if (!fp) return; + + for (fsme= fsmenu; fsme; fsme= fsme->next) { + if (fsme->path && fsme->save) { + fprintf(fp, "%s\n", fsme->path); + } + } + fclose(fp); +} + +void fsmenu_free(void) +{ + FSMenuEntry *fsme= fsmenu; + + while (fsme) { + FSMenuEntry *n= fsme->next; + + if (fsme->path) MEM_freeN(fsme->path); + MEM_freeN(fsme); + + fsme= n; + } +} + + + diff --git a/source/blender/src/glutil.c b/source/blender/src/glutil.c index 248d36dcb1e..13922bb7eef 100644 --- a/source/blender/src/glutil.c +++ b/source/blender/src/glutil.c @@ -50,6 +50,11 @@ #include "BIF_glutil.h" #include "BIF_mywindow.h" +#ifndef GL_CLAMP_TO_EDGE +#define GL_CLAMP_TO_EDGE 0x812F +#endif + + /* Invert line handling */ #define glToggle(mode, onoff) (((onoff)?glEnable:glDisable)(mode)) @@ -263,10 +268,17 @@ void glaDrawPixelsTex(float x, float y, int img_w, int img_h, int format, void * int nsubparts_x= (img_w+(tex_w-1))/tex_w; int nsubparts_y= (img_h+(tex_h-1))/tex_h; - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + /* Specify the color outside this function, and tex will modulate it. + * This is useful for changing alpha without using glPixelTransferf() + */ + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glPixelStorei(GL_UNPACK_ROW_LENGTH, img_w); glBindTexture(GL_TEXTURE_2D, texid); + /* don't want nasty border artifacts */ + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + for (subpart_y=0; subpart_yspacedata.first; if(curarea->win==0) return; switch(event) { - case B_IMASELHOME: + case B_SORTIMASELLIST: + BIF_filelist_sort(simasel->files, simasel->sort); + scrarea_queue_winredraw(curarea); break; - case B_IMASELREMOVEBIP: - - if(bitset(simasel->fase, IMS_FOUND_BIP)){ - - strcpy(name, simasel->dir); - strcat(name, ".Bpib"); - - remove(name); - - simasel->fase &= ~ IMS_FOUND_BIP; + case B_RELOADIMASELDIR: + BIF_filelist_free(simasel->files); + scrarea_queue_winredraw(curarea); + break; + case B_FILTERIMASELDIR: + if (simasel->flag & FILE_FILTER) { + BIF_filelist_setfilter(simasel->files,simasel->filter); + BIF_filelist_filter(simasel->files); + scrarea_queue_winredraw(curarea); + } else { + BIF_filelist_setfilter(simasel->files,0); + BIF_filelist_filter(simasel->files); + scrarea_queue_winredraw(curarea); } break; } @@ -94,9 +100,9 @@ void imasel_buttons(void) { SpaceImaSel *simasel; uiBlock *block; - short xco; + short xco, xcotitle; char naam[256]; - + simasel= curarea->spacedata.first; sprintf(naam, "header %d", curarea->headwin); @@ -117,26 +123,76 @@ void imasel_buttons(void) if(curarea->full) uiDefIconBut(block, BUT,B_FULL, ICON_SPLITSCREEN, xco,0,XIC,YIC, 0, 0, 0, 0, 0, ""); else uiDefIconBut(block, BUT,B_FULL, ICON_FULLSCREEN, xco,0,XIC,YIC, 0, 0, 0, 0, 0, ""); + /* SORT TYPE */ xco+=XIC; - if (simasel->title){ - xco+=25; - glRasterPos2i(xco, 4); - BMF_DrawString(G.font, simasel->title); - xco+=BMF_GetStringWidth(G.fonts, simasel->title); - xco+=25; - } - uiBlockBeginAlign(block); - uiDefIconBut(block, BUT, B_IMASELREMOVEBIP, ICON_BPIBFOLDER_X, xco+=XIC,0,XIC,YIC, 0, 0, 0, 0, 0, "");/* remove */ + uiDefIconButS(block, ROW, B_SORTIMASELLIST, ICON_SORTALPHA, xco+=XIC,0,XIC,YIC, &simasel->sort, 1.0, 0.0, 0, 0, "Sorts files alphabetically"); + uiDefIconButS(block, ROW, B_SORTIMASELLIST, ICON_SORTBYEXT, xco+=XIC,0,XIC,YIC, &simasel->sort, 1.0, 3.0, 0, 0, "Sorts files by extension"); + uiDefIconButS(block, ROW, B_SORTIMASELLIST, ICON_SORTTIME, xco+=XIC,0,XIC,YIC, &simasel->sort, 1.0, 1.0, 0, 0, "Sorts files by time"); + uiDefIconButS(block, ROW, B_SORTIMASELLIST, ICON_SORTSIZE, xco+=XIC,0,XIC,YIC, &simasel->sort, 1.0, 2.0, 0, 0, "Sorts files by size"); + uiBlockEndAlign(block); + + cpack(0x0); + xco+=XIC+10; + uiDefIconButBitS(block, TOG, FILE_BOOKMARKS, B_RELOADIMASELDIR, ICON_BOOKMARKS,xco+=XIC,0,XIC,YIC, &simasel->flag, 0, 0, 0, 0, "Toggles Bookmarks on/off"); + xco+=XIC+10; + + xcotitle= xco; + xco+= BIF_GetStringWidth(G.font, simasel->title, (U.transopts & USER_TR_BUTTONS)); - uiDefIconButS(block, TOG|BIT|0, B_REDR, ICON_BPIBFOLDERGREY, xco+=XIC,0,XIC,YIC, &simasel->mode, 0, 0, 0, 0, "Toggles display of directory information");/* dir */ - uiDefIconButS(block, TOG|BIT|1, B_REDR, ICON_INFO, xco+=XIC,0,XIC,YIC, &simasel->mode, 0, 0, 0, 0, "Toggles display of selected image information");/* info */ - uiDefIconButS(block, TOG|BIT|2, B_REDR, ICON_IMAGE_COL, xco+=XIC,0,XIC,YIC, &simasel->mode, 0, 0, 0, 0, "");/* image */ - uiDefIconButS(block, TOG|BIT|3, B_REDR, ICON_MAGNIFY, xco+=XIC,0,XIC,YIC, &simasel->mode, 0, 0, 0, 0, "Toggles magnified view of thumbnail of images under mouse pointer");/* magnify */ + if(simasel->pupmenu && simasel->menup) { + uiDefButS(block, MENU, B_NOP, simasel->pupmenu, xco+10,0,90,20, simasel->menup, 0, 0, 0, 0, ""); + xco+= 100; + } + uiBlockBeginAlign(block); + uiDefIconButBitS(block, TOG, FILE_HIDE_DOT, B_RELOADIMASELDIR, ICON_GHOST,xco+=XIC,0,XIC,YIC, &simasel->flag, 0, 0, 0, 0, "Hides dot files"); uiBlockEndAlign(block); + xco+=20; + + uiDefIconButBitS(block, TOG, FILE_FILTER, B_FILTERIMASELDIR, ICON_SORTBYEXT,xco+=XIC,0,XIC,YIC, &simasel->flag, 0, 0, 0, 0, "Filter files"); + if (simasel->flag & FILE_FILTER) { + xco+=4; + uiBlockBeginAlign(block); + uiDefIconButBitS(block, TOG, IMAGEFILE, B_FILTERIMASELDIR, ICON_IMAGE_COL,xco+=XIC,0,XIC,YIC, &simasel->filter, 0, 0, 0, 0, "Show images"); + uiDefIconButBitS(block, TOG, BLENDERFILE, B_FILTERIMASELDIR, ICON_BLENDER,xco+=XIC,0,XIC,YIC, &simasel->filter, 0, 0, 0, 0, "Show .blend files"); + uiDefIconButBitS(block, TOG, MOVIEFILE, B_FILTERIMASELDIR, ICON_SEQUENCE,xco+=XIC,0,XIC,YIC, &simasel->filter, 0, 0, 0, 0, "Show movies"); + uiDefIconButBitS(block, TOG, PYSCRIPTFILE, B_FILTERIMASELDIR, ICON_PYTHON,xco+=XIC,0,XIC,YIC, &simasel->filter, 0, 0, 0, 0, "Show python scripts"); + uiDefIconButBitS(block, TOG, FTFONTFILE, B_FILTERIMASELDIR, ICON_SYNTAX,xco+=XIC,0,XIC,YIC, &simasel->filter, 0, 0, 0, 0, "Show fonts"); + uiDefIconButBitS(block, TOG, SOUNDFILE, B_FILTERIMASELDIR, ICON_SOUND,xco+=XIC,0,XIC,YIC, &simasel->filter, 0, 0, 0, 0, "Show sound files"); + uiDefIconButBitS(block, TOG, TEXTFILE, B_FILTERIMASELDIR, ICON_TEXT,xco+=XIC,0,XIC,YIC, &simasel->filter, 0, 0, 0, 0, "Show text files"); + uiDefIconButBitS(block, TOG, FOLDERFILE, B_FILTERIMASELDIR, ICON_FILESEL,xco+=XIC,0,XIC,YIC, &simasel->filter, 0, 0, 0, 0, "Show folders"); + uiBlockEndAlign(block); + } + + uiDefButBitS(block, TOG, FILE_STRINGCODE, 0, "Relative Paths", xco+=XIC+20,0,100,YIC, &simasel->flag, 0, 0, 0, 0, "Makes sure returned paths are relative to the current .blend file"); + xco+=90; + + if(simasel->type==FILE_LOADLIB) { + uiBlockBeginAlign(block); + uiDefButBitS(block, TOGN, FILE_LINK, B_REDR, "Append", xco+=XIC,0,100,YIC, &simasel->flag, 0, 0, 0, 0, "Copies selected data into current project"); + uiDefButBitS(block, TOG, FILE_LINK, B_REDR, "Link", xco+=100,0,100,YIC, &simasel->flag, 0, 0, 0, 0, "Creates a link to selected data from current project"); + uiBlockEndAlign(block); + uiBlockBeginAlign(block); + uiDefButBitS(block, TOG, FILE_AUTOSELECT, B_REDR, "Autosel", xco+=125,0,65,YIC, &simasel->flag, 0, 0, 0, 0, "Autoselect imported objects"); + uiDefButBitS(block, TOG, FILE_ACTIVELAY, B_REDR, "Active Layer", xco+=65,0,80,YIC, &simasel->flag, 0, 0, 0, 0, "Append object(s) in active layer"); + uiDefButBitS(block, TOG, FILE_ATCURSOR, B_REDR, "At Cursor", xco+=80,0,65,YIC, &simasel->flag, 0, 0, 0, 0, "Append object(s) at cursor, use centroid if more than one object is selected"); + uiBlockEndAlign(block); + + xco+= 100; // scroll + + } else if(simasel->type==FILE_BLENDER) { + uiDefButBitI(block, TOGN, G_FILE_NO_UI, B_REDR, "Load UI", xco+=XIC,0,80,YIC, &G.fileflags, 0, 0, 0, 0, "Load the UI setup as well as the scene data"); + xco+= 100; // scroll + } + + glRasterPos2f((float)xcotitle, 5.0); + BIF_RasterPos((float)xcotitle, 5.0); // stupid texture fonts + BIF_ThemeColor(TH_TEXT); + BIF_DrawString(uiBlockGetCurFont(block), simasel->title, (U.transopts & USER_TR_BUTTONS)); + /* always do as last */ curarea->headbutlen= xco+2*XIC; uiDrawBlock(block); -} +} \ No newline at end of file diff --git a/source/blender/src/header_info.c b/source/blender/src/header_info.c index aee2e2c620f..685da07f88f 100644 --- a/source/blender/src/header_info.c +++ b/source/blender/src/header_info.c @@ -105,6 +105,7 @@ #include "BSE_editipo.h" #include "BSE_filesel.h" +#include "BIF_imasel.h" #include "BSE_headerbuttons.h" #include "BSE_node.h" #include "BSE_sequence.h" @@ -839,6 +840,9 @@ static void do_info_filemenu(void *arg, int event) case 6: /* save image */ BIF_save_rendered_image_fs(); break; + case 7: + activate_imageselect(FILE_LOADLIB, "Load Library", G.lib, 0); + break; case 22: /* save runtime */ activate_fileselect(FILE_SPECIAL, "Save Runtime", "", write_runtime_check); break; @@ -991,6 +995,7 @@ static uiBlock *info_filemenu(void *arg_unused) uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, ""); uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Append or Link|Shift F1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, ""); + uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Append or Link (Image Browser)|Ctrl F1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, ""); uiDefIconTextBlockBut(block, info_file_importmenu, NULL, ICON_RIGHTARROW_THIN, "Import", 0, yco-=20, menuwidth, 19, ""); uiDefIconTextBlockBut(block, info_file_exportmenu, NULL, ICON_RIGHTARROW_THIN, "Export", 0, yco-=20, menuwidth, 19, ""); diff --git a/source/blender/src/headerbuttons.c b/source/blender/src/headerbuttons.c index 3d03adbc4bb..adc40683bc0 100644 --- a/source/blender/src/headerbuttons.c +++ b/source/blender/src/headerbuttons.c @@ -709,7 +709,12 @@ void do_global_buttons(unsigned short event) else return; if(*menunr== -2) { - activate_databrowse((ID *)lockpoin, ID_MA, 0, B_MATBROWSE, menunr, do_global_buttons); + if(G.qual & LR_CTRLKEY) { + activate_databrowse_imasel((ID *)lockpoin, ID_MA, 0, B_MATBROWSE, menunr, do_global_buttons); + } + else { + activate_databrowse((ID *)lockpoin, ID_MA, 0, B_MATBROWSE, menunr, do_global_buttons); + } return; } diff --git a/source/blender/src/imasel.c b/source/blender/src/imasel.c index 6c232ea6464..78fc3f1be2a 100644 --- a/source/blender/src/imasel.c +++ b/source/blender/src/imasel.c @@ -57,864 +57,29 @@ #include "BKE_global.h" #include "BIF_imasel.h" +#include "BIF_filelist.h" #include "BIF_space.h" #include "BIF_screen.h" #include "blendef.h" #include "mydevice.h" -#ifndef WIN32 -#include -#endif - -#include -#include "datatoc.h" - -/* locals */ -void longtochar(char *des, unsigned int *src, int size); -void chartolong(unsigned int *des, char *src, int size); -int dir_compare(const void *a1, const void *a2); -void issort( int te, ImaDir **firstentry); -int ima_compare(const void *a1, const void *a2); -void imsort(OneSelectableIma **firstentry); -void append_pib(SpaceImaSel *simasel, OneSelectableIma *ima); -void add_ima(int who, SpaceImaSel *simasel, ImaDir *direntry); - -/* implementation */ -int bitset(int l, int bit) -{ return (( l & bit) == bit); } - -void longtochar(char *des, unsigned int *src, int size) -{ int i;for (i = 0; iname, use2->name); -} - -void issort( int te, ImaDir **firstentry) -{ - ImaDir **sort; - ImaDir *use; - int i = 0; - - sort = MEM_mallocN(te * sizeof(void *), "dir Sorteer temp"); - use = *firstentry; - - while (use){ - sort[i++] = use; - use = use->next; - } - - qsort (sort, te, sizeof(void *), dir_compare); - - *firstentry = sort[0]; - use = *firstentry; - - - for (i=0; iprev = sort[i-1]; else use->prev = 0; - if (i != te-1) use->next = sort[i+1]; else use->next = 0; - - use = use->next; - } - - MEM_freeN(sort); -} - - -int ima_compare(const void *a1, const void *a2) -{ - OneSelectableIma **in1, **in2; - OneSelectableIma *use1, *use2; - - in1= (OneSelectableIma **)a1; - in2= (OneSelectableIma **)a2; - - use1 = *in1; use2 = *in2; - return BLI_strcasecmp(use1->file_name, use2->file_name); -} - -void imsort(OneSelectableIma **firstentry) -{ - OneSelectableIma **sort; - OneSelectableIma *use; - int tot = 0, i = 0; - - use = *firstentry; - while (use){ - tot++; - use = use->next; - } - - if (tot){ - sort = MEM_mallocN(tot * sizeof(void *), "Sorteer imsort temp"); - use = *firstentry; - while (use){ - sort[i++] = use; - use = use->next; - } - - qsort (sort, tot, sizeof(void *), ima_compare); - - *firstentry = sort[0]; - use = *firstentry; - for (i=0; iprev = sort[i-1]; else use->prev = 0; - if (i != tot-1) use->next = sort[i+1]; else use->next = 0; - - use = use->next; - } - MEM_freeN(sort); - } -} - -static int write_msb_int(int fd, int i) { - unsigned int ui= (unsigned int) i; - unsigned char buf[4]; - buf[0]= (ui>>24)&0xFF; - buf[1]= (ui>>16)&0xFF; - buf[2]= (ui>>8)&0xFF; - buf[3]= (ui>>0)&0xFF; - return write(fd, buf, 4); -} -static int write_msb_short(int fd, short s) { - unsigned short us= (unsigned short) s; - unsigned char buf[2]; - buf[0]= (us>>8)&0xFF; - buf[1]= (us>>0)&0xFF; - return write(fd, buf, 2); -} - -static int read_msb_int(int fd, int *i_r) { - unsigned char buf[4]; - int rcount= read(fd, buf, 4); - - if (i_r) - *i_r= (buf[0]<<24)|(buf[1]<<16)|(buf[2]<<8)|(buf[3]<<0); - - return rcount; -} -static int read_msb_short(int fd, short *s_r) { - unsigned char buf[2]; - int rcount= read(fd, buf, 2); - - if (s_r) - *s_r= (buf[0]<<8)|(buf[1]<<0); - - return rcount; -} - -void append_pib(SpaceImaSel *simasel, OneSelectableIma *ima) -{ - int file; - char name[FILE_MAXDIR+FILE_MAXFILE]; - - if ( bitset (simasel->fase, IMS_WRITE_NO_BIP)) return; - - strcpy(name, simasel->dir); - strcat(name, ".Bpib"); - - file = open(name, O_BINARY|O_APPEND | O_RDWR | O_CREAT, 0666); - if (file == -1) { - /* printf("Could not write .Bpib file in dir %s\n", simasel->dir); */ - simasel->fase |= IMS_WRITE_NO_BIP; - return; - } - - lseek(file, 0, SEEK_END); - - write(file, "BIP2", 4); - write_msb_int(file, ima->ibuf_type); - write_msb_int(file, 0); - write_msb_int(file, 0); - write_msb_int(file, 0); - write_msb_short(file, ima->cmap); - write_msb_short(file, ima->image); - write_msb_short(file, ima->draw_me); - write_msb_short(file, ima->rt); - write_msb_short(file, ima->sx); - write_msb_short(file, ima->sy); - write_msb_short(file, ima->ex); - write_msb_short(file, ima->ey); - write_msb_short(file, ima->dw); - write_msb_short(file, ima->dh); - write_msb_short(file, ima->selectable); - write_msb_short(file, ima->selected); - write_msb_int(file, ima->mtime); - write_msb_int(file, ima->disksize); - write(file, ima->file_name, 64); - write_msb_short(file, ima->orgx); - write_msb_short(file, ima->orgy); - write_msb_short(file, ima->orgd); - write_msb_short(file, ima->anim); - write_msb_int(file, 0); /* pad to 128 boundary */ - write(file, ima->pict_rect, 3968); - - close(file); -} - -void write_new_pib(SpaceImaSel *simasel) -{ - OneSelectableIma *ima; - char name[FILE_MAXDIR+FILE_MAXFILE]; - - strcpy(name, simasel->dir); - strcat(name, ".Bpib"); - remove(name); - - ima = simasel->first_sel_ima; - while (ima) { - append_pib(simasel, ima); - ima = ima->next; - } -} - -void free_ima_dir(ImaDir *firstdir) -{ - ImaDir *n; - - while(firstdir){ - n = firstdir->next; - MEM_freeN(firstdir); - firstdir = n; - } -} -void free_sel_ima(OneSelectableIma *firstima) -{ - OneSelectableIma *n; - - while(firstima){ - - if (firstima->pict) { - IMB_freeImBuf(firstima->pict); - } - n = firstima->next; - MEM_freeN(firstima); - firstima = n; - } -} - -void check_for_pib(SpaceImaSel *simasel) -{ - ImaDir *direntry; - - direntry = simasel->firstfile; - while(direntry){ - if ((strlen(direntry->name) > 4) && (0==strcmp(direntry->name, ".Bpib")) ){ - simasel->fase |= IMS_FOUND_BIP; - direntry = 0; - }else{ - direntry = direntry->next; - } - } -} - -void clear_ima_dir(SpaceImaSel *simasel) -{ - if(simasel->first_sel_ima) free_sel_ima(simasel->first_sel_ima); - if(simasel->firstdir) free_ima_dir(simasel->firstdir); - if(simasel->firstfile) free_ima_dir(simasel->firstfile); - - simasel->first_sel_ima = 0; - simasel->firstdir = 0; - simasel->firstfile = 0; - - simasel->totaldirs = 0; - simasel->totalfiles = 0; - simasel->totalima = 0; - simasel->topdir = -1; - simasel->topfile = -1; - simasel->topima = 0; - simasel->image_slider = 0.0; - simasel->slider_height = 0.0; - simasel->slider_space = 0.0; - simasel->hilite = -1; - simasel->curimax = 0; - simasel->curimay = 0; - - simasel->total_selected = 0; - simasel->fase = 0; - simasel->subfase = 0; - simasel->imafase = 0; - simasel->ima_redraw = 0; -} - -int get_ima_dir(char *dirname, int dtype, int *td, ImaDir **first) -{ - DIR *dirp; - struct dirent *dep; - struct ImaDir *temp; - struct ImaDir *dnext = NULL, *fnext; - struct stat status; - char olddir[FILE_MAXDIR+FILE_MAXFILE]; - char getdirname[FILE_MAXDIR+FILE_MAXFILE]; - int /* i=0, */ tot=0; - int isdir; - - if(!BLI_getwdN(olddir)) return -1; - - if (chdir(dirname) == -1) return(-1); - - strcpy(getdirname, "."); - - dirp = (DIR *) opendir(getdirname); - if (dirp == NULL) return (-1); - - waitcursor(1); - - while((dep = (struct dirent*) readdir(dirp)) != NULL){ - - strcpy(getdirname, dirname); - strcat(getdirname,dep->d_name); - - stat(getdirname, &status); - isdir = S_ISDIR(status.st_mode); - - if ( ((dtype == IMS_DIR) && isdir) || ((dtype == IMS_FILE) && !isdir)){ - /* yes, searching for this type */ - tot++; - if (tot == 1){ - dnext = MEM_callocN(sizeof(struct ImaDir), "get first"); - *first = dnext; - - dnext->prev = 0; - dnext->next = 0; - }else{ - fnext = MEM_callocN(sizeof(struct ImaDir), "get nextdir"); - dnext->next = fnext; - - temp = dnext; - dnext = fnext; - - dnext ->prev = temp; - dnext ->next = 0; - } - - dnext->type = dtype; - dnext->selected = 0; - dnext->hilite = 0; - - dnext->mtime = status.st_ctime; - dnext->size = (int)status.st_size; - strcpy(dnext->name, dep->d_name); - } - } - closedir(dirp); - - if (tot) issort(tot, first); - - waitcursor(0); - - *td = tot; - - chdir (olddir); - - return (tot); -} - -void imadir_parent(SpaceImaSel *simasel) -{ - -#ifdef WIN32 - if (strlen(simasel->dir) > 1){ - simasel->dir[strlen(simasel->dir)-1] = 0; - while(simasel->dir[strlen(simasel->dir)-1] != '\\'){ - if(strlen(simasel->dir)==0) break; - simasel->dir[strlen(simasel->dir)-1] = 0; - } - } -#else - if (strlen(simasel->dir) > 1){ - simasel->dir[strlen(simasel->dir)-1] = 0; - while(simasel->dir[strlen(simasel->dir)-1] != '/') { - if(strlen(simasel->dir)==0) break; - simasel->dir[strlen(simasel->dir)-1] = 0; - } - } -#endif -} - - -void get_next_image(SpaceImaSel *simasel) -{ - OneSelectableIma * ima; - ImBuf * ibuf; - struct anim * anim; - int i = 0, size; - char name[FILE_MAXDIR+FILE_MAXFILE]; - - ima = simasel->first_sel_ima; - if (ima == 0){ - simasel->imafase = 0; - simasel->fase |= IMS_KNOW_IMA; - simasel->fase &= ~IMS_DOTHE_IMA; - return; - } - if (simasel->imafase > simasel->totalima){ - simasel->imafase = 0; - simasel->fase &= ~IMS_DOTHE_IMA; - simasel->fase |= IMS_KNOW_IMA; - } - - ima = simasel->first_sel_ima; - i = 0; - while(i < simasel->imafase){ - if ((ima) && (ima->next)) ima = ima->next; - i++; - } - - if (ima->image == 0) { - if (ima->anim == 1) { - /* open movie, get len, get middle picture */ - - strcpy(name, simasel->dir); - strcat(name, ima->file_name); - - anim = IMB_open_anim(name, IB_rect); - - if (anim == 0) { - // ibuf= IMB_loadiffmem((int*)datatoc_cmovie_tga, IB_rect); - ibuf= IMB_ibImageFromMemory((int *)datatoc_cmovie_tga, datatoc_cmovie_tga_size, IB_rect); - } - else{ - int animlen; - - ibuf = IMB_anim_nextpic(anim); - IMB_freeImBuf(ibuf); - - animlen= IMB_anim_get_duration(anim); - ibuf = IMB_anim_absolute(anim, animlen / 2); - - if(ibuf) { - //get icon dimensions for movie - ima->orgx = ibuf->x; - ima->orgy = ibuf->y; -// ima->orgd = ibuf->depth; - - if (ima->orgx > ima->orgy){ - ima->dw = 64; - ima->dh = (short)(62 * ((float)ima->orgy / (float)ima->orgx)); - }else{ - ima->dw = (short)(64 * ((float)ima->orgx / (float)ima->orgy)); - ima->dh = 62; - } - } - - IMB_free_anim(anim); - } - } - else { - - strcpy(name, simasel->dir); - strcat(name, ima->file_name); - - ibuf = IMB_loadiffname(name, IB_rect); - if(ibuf && ibuf->zbuf) IMB_freezbufImBuf(ibuf); - } - - if (ibuf){ - if (ima->dw < 4) ima->dw = 4; - if (ima->dh < 4) ima->dh = 4; - - IMB_scaleImBuf(ibuf, ima->dw, ima->dh); - /* the whole cmap system is wacko */ - - if (G.order==B_ENDIAN) - IMB_convert_rgba_to_abgr(ibuf); - - ibuf->mincol = 0; - ibuf->maxcol = 256; - ibuf->cbits = 5; - ibuf->depth = 8; - - IMB_freecmapImBuf(ibuf); - ibuf->cmap = simasel->cmap->cmap; - - IMB_converttocmap(ibuf); - - /* copy ibuf->rect to ima->pict_rect */ - size = ima->dw * ima->dh; if (size > 3968) size = 3968; - longtochar(ima->pict_rect, ibuf->rect, size); - - IMB_applycmap(ibuf); - IMB_convert_rgba_to_abgr(ibuf); - - if (ima->pict) IMB_freeImBuf(ima->pict); - ima->pict = ibuf; - ibuf = 0; - ima->cmap = 1; - ima->image = 1; - - append_pib(simasel, ima); - } - } - simasel->ima_redraw++; - simasel->imafase ++; - if (simasel->imafase == simasel->totalima){ - simasel->imafase = 0; - simasel->fase &= ~IMS_DOTHE_IMA; - simasel->fase |= IMS_KNOW_IMA; - } -} - -void add_ima(int who, SpaceImaSel *simasel, ImaDir *direntry) -{ - OneSelectableIma *ima, *prev_ima; - ImBuf *ibuf; - char name[FILE_MAXDIR+FILE_MAXFILE]; - - strcpy(name , simasel->dir); - strcat(name , direntry->name); - - prev_ima = simasel->first_sel_ima; - while((prev_ima)&&(prev_ima->next)){ - prev_ima = prev_ima->next; - } - - ima = MEM_callocN(sizeof(OneSelectableIma), "OSIbip"); - if (direntry->type == IMS_IMA){ - /* Picture is an Image */ - ibuf = IMB_loadiffname(name, IB_test); - if (ibuf){ - ima->anim = 0; - ima->pict = ibuf; - ima->ibuf_type= ibuf->ftype; - ima->orgx = ibuf->x; - ima->orgy = ibuf->y; - ima->orgd = ibuf->depth; - - ima->dw = 64; - ima->dh = 51; - ima->cmap = 0; - ima->image = 0; - if (ima->orgx > ima->orgy){ - ima->dw = 64; - ima->dh = (short)(62 * ((float)ima->orgy / (float)ima->orgx)); - }else{ - ima->dw = (short)(64 * ((float)ima->orgx / (float)ima->orgy)); - ima->dh = 62; - } - }else{ - printf("%s image with no imbuf ???\n", name); - } - ibuf = 0; - }else{ - /* Picture is an Animation */ - - ima->pict = 0; - ima->anim = 1; - ima->ibuf_type= 0; - ima->orgx = 64; - ima->orgy = 51; - ima->orgd = 24; - - ima->dw = 64; - ima->dh = 51; - ima->cmap = 0; - ima->image = 0; - } - - strcpy(name, direntry->name); name[63] = 0; - strcpy(ima->file_name, name); - ima->disksize = (int)direntry->size; - ima->mtime = (int)direntry->mtime; - - ima->next = 0; - ima->prev = prev_ima; - - if (prev_ima) { - prev_ima->next = ima; - }else{ - simasel->first_sel_ima = ima; - } - - simasel->ima_redraw++; - simasel->totalima++; -} - - -void get_file_info(SpaceImaSel *simasel) -{ - OneSelectableIma *prev_ima; - ImaDir *direntry; - char name[FILE_MAXDIR+FILE_MAXFILE]; - int i = 0; - - if (!simasel->firstfile){ - simasel->subfase = 0; - simasel->fase |= IMS_KNOW_INF; - simasel->fase &= ~IMS_DOTHE_INF; - return; - } - if (simasel->subfase > simasel->totalfiles){ - simasel->subfase = 0; - simasel->fase |= IMS_KNOW_INF; - simasel->fase &= ~IMS_DOTHE_INF; - } - - direntry = simasel->firstfile; - while(i < simasel->subfase){ - direntry = direntry->next; - i++; - } - - prev_ima = simasel->first_sel_ima; - while((prev_ima)&&(prev_ima->next)){ - prev_ima = prev_ima->next; - } - - strcpy(name , simasel->dir); - strcat(name , direntry->name); - - if(direntry->name[0] == '.') { - direntry->type = IMS_NOIMA; - } else { - if (IMB_ispic(name)) { - direntry->type = IMS_IMA; - }else{ - if (IMB_isanim(name)) { - direntry->type = IMS_ANIM; - }else{ - direntry->type = IMS_NOIMA; - } - } - } - - if (direntry->type != IMS_NOIMA){ - add_ima(1, simasel, direntry); - } - - simasel->subfase++; - - if (simasel->subfase == simasel->totalfiles){ - simasel->subfase = 0; - simasel->fase |= IMS_KNOW_INF; - simasel->fase &= ~IMS_DOTHE_INF; - } -} - -/* Note: the thumbnails are saved in ABGR format in the .Bpib -cache file */ - -void get_pib_file(SpaceImaSel *simasel) -{ - ImaDir *direntry, *prev_dir, *next_dir; - OneSelectableIma *ima, *prev_ima; - int flen; - int dl, file, first, trd=0, rd, size, found, ima_added = 0; - char name[FILE_MAXDIR+FILE_MAXFILE]; - - if (bitset(simasel->fase , IMS_KNOW_BIP)) return; - - waitcursor(1); - - strcpy(name, simasel->dir); - strcat(name, ".Bpib"); - - file = open(name, O_BINARY|O_RDONLY); - - flen = BLI_filesize(file); - - simasel->totalima = 0; - prev_ima = 0; - first = 1; - trd = 0; - - while(trd < flen){ - char header[5]; - - ima = MEM_callocN(sizeof(OneSelectableIma), "Ima"); - - rd= 0; - rd+= read(file, header, 4); - rd+= read_msb_int(file, &ima->ibuf_type); - rd+= read_msb_int(file, NULL); - rd+= read_msb_int(file, NULL); - rd+= read_msb_int(file, NULL); - rd+= read_msb_short(file, &ima->cmap); - rd+= read_msb_short(file, &ima->image); - rd+= read_msb_short(file, &ima->draw_me); - rd+= read_msb_short(file, &ima->rt); - rd+= read_msb_short(file, &ima->sx); - rd+= read_msb_short(file, &ima->sy); - rd+= read_msb_short(file, &ima->ex); - rd+= read_msb_short(file, &ima->ey); - rd+= read_msb_short(file, &ima->dw); - rd+= read_msb_short(file, &ima->dh); - rd+= read_msb_short(file, &ima->selectable); - rd+= read_msb_short(file, &ima->selected); - rd+= read_msb_int(file, &ima->mtime); - rd+= read_msb_int(file, &ima->disksize); - rd+= read(file, ima->file_name, 64); - rd+= read_msb_short(file, &ima->orgx); - rd+= read_msb_short(file, &ima->orgy); - rd+= read_msb_short(file, &ima->orgd); - rd+= read_msb_short(file, &ima->anim); - rd+= read_msb_int(file, NULL); - rd+= read(file, ima->pict_rect, 3968); - - found = 0; - - if (rd != sizeof(OneSelectableIma) || memcmp(header, "BIP2", 4)!=0) { - printf("Error in Bpib file\n"); - strcpy(name, simasel->dir); - strcat(name, ".Bpib"); - dl = remove(name); - if (dl == 0) printf("corrupt Bpib file removed\n"); - trd = flen; - } else { - /* find matching direntry (if possible) */ - for (direntry= simasel->firstfile; direntry; direntry= direntry->next) - if (BLI_streq(direntry->name, ima->file_name)) - break; - - if (direntry) { - if (direntry->mtime == ima->mtime) { - /* ima found and same, load pic */ - size = ima->dw * ima->dh; - if (size > 3968) size = 3968; - if (size) { - ima->pict = IMB_allocImBuf(ima->dw, ima->dh, 24, IB_rect | IB_cmap, 0); - chartolong(ima->pict->rect, ima->pict_rect, size); - ima->pict->cmap = simasel->cmap->cmap; - ima->pict->maxcol = 256; - IMB_applycmap(ima->pict); - IMB_convert_rgba_to_abgr(ima->pict); - } - ima->selected = 0; - ima->selectable = 0; - - if(prev_ima) prev_ima->next = ima; - ima->next = 0; - ima->prev = prev_ima; - - prev_ima = ima; - - if (first){ first = 0;simasel->first_sel_ima = ima; } - simasel->totalima++; - found = 1; - } - - /* remove direntry */ - prev_dir = direntry->prev; - next_dir = direntry->next; - - if(prev_dir) prev_dir->next = next_dir; - if(next_dir) next_dir->prev = prev_dir; - - MEM_freeN(direntry); - } - } - if (!found) MEM_freeN(ima); - - trd+=rd; - } - close(file); - - direntry = simasel->firstfile; - - while(direntry){ - - strcpy(name , simasel->dir); - strcat(name , direntry->name); - - if (IMB_ispic(name)) { - direntry->type = IMS_IMA; - }else{ - if (IMB_isanim(name)) { - direntry->type = IMS_ANIM; - }else{ - direntry->type = IMS_NOIMA; - } - } - - if (direntry->type != IMS_NOIMA){ - prev_ima = simasel->first_sel_ima; - while((prev_ima)&&(prev_ima->next)){ - prev_ima = prev_ima->next; - } - add_ima(2, simasel, direntry); - ima_added = 1; - } - direntry = direntry->next; - } - - imsort(&simasel->first_sel_ima); - - simasel->fase |= IMS_KNOW_BIP; - simasel->fase |= IMS_KNOW_INF; - simasel->fase |= IMS_KNOW_IMA; - - if (ima_added){ - simasel->fase |= IMS_DOTHE_IMA; - simasel->fase &= ~IMS_KNOW_IMA; - addafterqueue(curarea->win, AFTERIMASELGET, 1); - }else{ - write_new_pib(simasel); - } - - waitcursor(0); -} - -void change_imadir(SpaceImaSel *simasel) +void free_imasel(SpaceImaSel *simasel) { - ImaDir *direntry; - int i; - - direntry = simasel->firstdir; - for (i=0; ihilite; i++){ - direntry = direntry->next; + /* do not free imasel itself */ + if(simasel->files) { + BIF_filelist_freelib(simasel->files); + BIF_filelist_free(simasel->files); + MEM_freeN(simasel->files); + simasel->files = NULL; } - - if(direntry==NULL); - else if (direntry->name[0] != '.'){ - strcat(simasel->dir, direntry->name); - strcat(simasel->dir, "/"); + if (simasel->img) { + IMB_freeImBuf(simasel->img); } - else { - if (direntry->name[1] == '.'){ - imadir_parent(simasel); - } + if(simasel->pupmenu) { + MEM_freeN(simasel->pupmenu); + simasel->pupmenu = NULL; } - - clear_ima_dir(simasel); -} - -void check_imasel_copy(SpaceImaSel *simasel) -{ - - /* WATCH IT: also used when reading blender file */ - /* initialize stuff, malloc, etc */ - simasel->first_sel_ima = 0; - simasel->hilite_ima = 0; - simasel->firstdir = 0; - simasel->firstfile = 0; - simasel->cmap = 0; - clear_ima_dir(simasel); - - // simasel->cmap= IMB_loadiffmem((int*)datatoc_cmap_tga, IB_rect|IB_cmap); - simasel->cmap= IMB_ibImageFromMemory((int *)datatoc_cmap_tga, datatoc_cmap_tga_size, IB_rect|IB_cmap); -} - -void free_imasel(SpaceImaSel *simasel) -{ - /* do not free imasel itself */ - - clear_ima_dir(simasel); - IMB_freeImBuf(simasel->cmap); } diff --git a/source/blender/src/interface_draw.c b/source/blender/src/interface_draw.c index 2af1892de1c..1a64f28d982 100644 --- a/source/blender/src/interface_draw.c +++ b/source/blender/src/interface_draw.c @@ -2431,3 +2431,33 @@ void ui_draw_but(uiBut *but) } } +void ui_dropshadow(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= 12.0f*aspect; else a= 12.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); +} diff --git a/source/blender/src/interface_icons.c b/source/blender/src/interface_icons.c index d257f2f37f8..610ad09ca34 100644 --- a/source/blender/src/interface_icons.c +++ b/source/blender/src/interface_icons.c @@ -90,11 +90,6 @@ #include "datatoc.h" #include "mydevice.h" -/* OpenGL textures have to be size 2n+2 x 2m+2 for some n,m */ -/* choose ICON_RENDERSIZE accordingly */ -#define ICON_RENDERSIZE 32 -#define ICON_MIPMAPS 8 - #define ICON_IMAGE_W 512 #define ICON_IMAGE_H 256 @@ -105,52 +100,60 @@ #define ICON_GRID_W 15 #define ICON_GRID_H 16 +typedef struct IconImage { + int w; + int h; + unsigned int *rect; +} IconImage; + typedef struct DrawInfo { int w; int h; - int rw; - int rh; - VectorDrawFunc drawFunc; /* If drawFunc is defined then it is a vector icon, otherwise use rect */ float aspect; - unsigned int *rect; + VectorDrawFunc drawFunc; /* If drawFunc is defined then it is a vector icon, otherwise use rect */ + IconImage* icon; } DrawInfo; - /* ******************* STATIC LOCAL VARS ******************* */ /* static here to cache results of icon directory scan, so it's not * scanning the filesystem each time the menu is drawn */ static struct ListBase iconfilelist = {0, 0}; +static int preview_render_size(int miplevel); + /* **************************************************** */ static void def_internal_icon(ImBuf *bbuf, int icon_id, int xofs, int yofs) { Icon *new_icon = NULL; + IconImage *iimg = NULL; DrawInfo *di; int y = 0; new_icon = MEM_callocN(sizeof(Icon), "texicon"); new_icon->obj = 0; /* icon is not for library object */ - new_icon->type = 0; - new_icon->changed = 0; - + new_icon->type = 0; di = MEM_callocN(sizeof(DrawInfo), "drawinfo"); di->drawFunc = 0; di->w = ICON_DEFAULT_HEIGHT; di->h = ICON_DEFAULT_HEIGHT; - di->rw = ICON_DEFAULT_HEIGHT; - di->rh = ICON_DEFAULT_HEIGHT; di->aspect = 1.0f; - di->rect = MEM_mallocN(ICON_DEFAULT_HEIGHT*ICON_DEFAULT_HEIGHT*sizeof(unsigned int), "icon_rect"); + iimg = MEM_mallocN(sizeof(IconImage), "icon_img"); + iimg->rect = MEM_mallocN(ICON_DEFAULT_HEIGHT*ICON_DEFAULT_HEIGHT*sizeof(unsigned int), "icon_rect"); + iimg->w = ICON_DEFAULT_HEIGHT; + iimg->h = ICON_DEFAULT_HEIGHT; + /* Here we store the rect in the icon - same as before */ for (y=0; yrect[y*ICON_DEFAULT_HEIGHT], &bbuf->rect[(y+yofs)*512+xofs], ICON_DEFAULT_HEIGHT*sizeof(int)); + memcpy(&iimg->rect[y*ICON_DEFAULT_HEIGHT], &bbuf->rect[(y+yofs)*512+xofs], ICON_DEFAULT_HEIGHT*sizeof(int)); } + di->icon = iimg; + new_icon->drawinfo_free = BIF_icons_free_drawinfo; new_icon->drawinfo = di; @@ -166,17 +169,14 @@ static void def_internal_vicon( int icon_id, VectorDrawFunc drawFunc) new_icon->obj = 0; /* icon is not for library object */ new_icon->type = 0; - new_icon->changed = 0; - + di = MEM_callocN(sizeof(DrawInfo), "drawinfo"); di->drawFunc =drawFunc; di->w = ICON_DEFAULT_HEIGHT; di->h = ICON_DEFAULT_HEIGHT; - di->rw = ICON_DEFAULT_HEIGHT; - di->rh = ICON_DEFAULT_HEIGHT; di->aspect = 1.0f; - di->rect = NULL; - + di->icon = NULL; + new_icon->drawinfo_free = 0; new_icon->drawinfo = di; @@ -693,7 +693,10 @@ void BIF_icons_free_drawinfo(void *drawinfo) if (di) { - MEM_freeN(di->rect); + if (di->icon) { + MEM_freeN(di->icon->rect); + MEM_freeN(di->icon); + } MEM_freeN(di); } } @@ -705,11 +708,9 @@ static DrawInfo *icon_create_drawinfo() di = MEM_callocN(sizeof(DrawInfo), "di_icon"); di->drawFunc = 0; - di->w = 16; - di->h = 16; - di->rw = ICON_RENDERSIZE; - di->rh = ICON_RENDERSIZE; - di->rect = 0; + di->w = ICON_DEFAULT_HEIGHT; + di->h = ICON_DEFAULT_HEIGHT; + di->icon = NULL; di->aspect = 1.0f; return di; @@ -771,7 +772,7 @@ void BIF_icons_init(int first_dyn_id) init_internal_icons(); } -static void icon_copy_rect(ImBuf *ibuf, RenderInfo *ri) +static void icon_copy_rect(ImBuf *ibuf, unsigned int w, unsigned int h, unsigned int *rect) { struct ImBuf *ima; unsigned int *drect, *srect; @@ -789,19 +790,19 @@ static void icon_copy_rect(ImBuf *ibuf, RenderInfo *ri) return; if (ima->x > ima->y) { - scaledx = (float)ri->pr_rectx; - scaledy = ( (float)ima->y/(float)ima->x )*(float)ri->pr_rectx; + scaledx = (float)w; + scaledy = ( (float)ima->y/(float)ima->x )*(float)w; } else { - scaledx = ( (float)ima->x/(float)ima->y )*(float)ri->pr_recty; - scaledy = (float)ri->pr_recty; + scaledx = ( (float)ima->x/(float)ima->y )*(float)h; + scaledy = (float)h; } ex = (short)scaledx; ey = (short)scaledy; - dx = (ri->pr_rectx - ex) / 2; - dy = (ri->pr_recty - ey) / 2; + dx = (w - ex) / 2; + dy = (h - ey) / 2; IMB_scalefastImBuf(ima, ex, ey); @@ -810,61 +811,66 @@ static void icon_copy_rect(ImBuf *ibuf, RenderInfo *ri) IMB_rect_from_float(ima); srect = ima->rect; - drect = ri->rect; + drect = rect; - drect+= dy*ri->pr_rectx+dx; + drect+= dy*w+dx; for (;ey > 0; ey--){ memcpy(drect,srect, ex * sizeof(int)); - drect += ri->pr_rectx; + drect += w; srect += ima->x; } IMB_freeImBuf(ima); } +static void icon_create_mipmap(struct PreviewImage* prv_img, int miplevel) +{ + unsigned int size = preview_render_size(miplevel); + + if (!prv_img) { + printf("Error: requested preview image does not exist"); + } + if (!prv_img->rect[miplevel]) { + prv_img->w[miplevel] = size; + prv_img->h[miplevel] = size; + prv_img->changed[miplevel] = 1; + prv_img->rect[miplevel] = MEM_callocN(size*size*sizeof(unsigned int), "prv_rect"); + } +} + /* create single icon from jpg, png etc. */ -static void icon_from_image(Image *img, RenderInfo *ri) +static void icon_from_image(Image *img, int miplevel) { - unsigned int pr_size = ri->pr_rectx*ri->pr_recty*sizeof(unsigned int); + unsigned int pr_size; + short image_loaded = 0; + struct ImBuf* ibuf=NULL; + PreviewImage* pi; /* img->ok is zero when Image cannot load */ if (img==NULL || img->ok==0) return; - - if (!ri->rect) { - ri->rect= MEM_callocN(pr_size, "butsrect"); - memset(ri->rect, 0x00, pr_size); + + /* elubie: this needs to be changed: here image is always loaded if not + already there. Very expensive for large images. Need to find a way to + only get existing ibuf */ + ibuf = BKE_image_get_ibuf(img, NULL); + if(ibuf==NULL || ibuf->rect==NULL) { + return; } - /* we only load image if there's no preview saved already ... - always loading and reducing images is too expensive */ - /* new rule: never read images, so icons get created while user works, - not always on first use of a menu */ - if(!img->preview) { - ImBuf *ibuf; - if(img->ok!=IMA_OK_LOADED) { - return; - } - ibuf= BKE_image_get_ibuf(img, NULL); - icon_copy_rect(ibuf, ri); - - /* now copy the created preview to the DNA struct to be saved in file */ - img->preview = MEM_callocN(sizeof(PreviewImage), "img_prv"); - if (img->preview) { - printf("created image prv\n"); - img->preview->w = ri->pr_rectx; - img->preview->h = ri->pr_recty; - img->preview->rect = MEM_callocN(pr_size, "prv_rect"); - memcpy(img->preview->rect, ri->rect, pr_size); - } - } - else { - unsigned int img_prv_size = img->preview->w*img->preview->h*sizeof(unsigned int); - if (!img->preview->rect || img_prv_size != pr_size) { - printf("Missing preview or wrong preview size!\n"); - return; - } - memcpy(ri->rect, img->preview->rect, pr_size); + pi = BKE_previewimg_get((ID*)img); + + if(!pi) { + printf("preview image could'nt be allocated"); + return; } + /* we can only create the preview rect here, since loading possibly deallocated + old preview */ + icon_create_mipmap(pi, miplevel); + + pr_size = img->preview->w[miplevel]*img->preview->h[miplevel]*sizeof(unsigned int); + + image_loaded = 1; + icon_copy_rect(ibuf, img->preview->w[miplevel], img->preview->h[miplevel], img->preview->rect[miplevel]); } static void set_alpha(char* cp, int sizex, int sizey, char alpha) @@ -879,27 +885,36 @@ static void set_alpha(char* cp, int sizex, int sizey, char alpha) /* only called when icon has changed */ /* only call with valid pointer from BIF_icon_draw */ -static void icon_set_image(ID *id, DrawInfo *di) +static void icon_set_image(ID *id, DrawInfo *di, PreviewImage* prv_img, int miplevel) { RenderInfo ri; - - if (!di) return; - - if (!di->rect) - di->rect = MEM_callocN(di->rw*di->rh*sizeof(unsigned int), "laprevrect"); + unsigned int pr_size = 0; + + if (!di) return; - ri.curtile= 0; - ri.tottile= 0; - ri.rect = NULL; - ri.pr_rectx = di->rw; - ri.pr_recty = di->rh; + if (!prv_img) { + printf("No preview image for this ID: %s\n", id->name); + return; + } /* no drawing (see last parameter doDraw, just calculate preview image - hopefully small enough to be fast */ if (GS(id->name) == ID_IM) - icon_from_image((struct Image*)id, &ri); - else { + icon_from_image((struct Image*)id, miplevel); + else { + /* create the preview rect */ + icon_create_mipmap(prv_img, miplevel); + + ri.curtile= 0; + ri.tottile= 0; + ri.rect = NULL; + ri.pr_rectx = prv_img->w[miplevel]; + ri.pr_recty = prv_img->h[miplevel]; + + pr_size = ri.pr_rectx*ri.pr_recty*sizeof(unsigned int); + BIF_previewrender(id, &ri, NULL, PR_ICON_RENDER); + /* world is rendered with alpha=0, so it wasn't displayed this could be render option for sky to, for later */ if (GS(id->name) == ID_WO) { @@ -909,25 +924,74 @@ static void icon_set_image(ID *id, DrawInfo *di) Material* mat = (Material*)id; if (mat->mode & MA_HALO) { set_alpha( (char*) ri.rect, ri.pr_rectx, ri.pr_recty, 255); - } + } + } + + if (ri.rect) { + memcpy(prv_img->rect[miplevel], ri.rect, pr_size); + + /* and clean up */ + MEM_freeN(ri.rect); + ri.rect = 0; } } +} - /* and copy the image into the icon */ - if (ri.rect) { - memcpy(di->rect, ri.rect,di->rw*di->rh*sizeof(unsigned int)); +static void icon_draw_rect(float x, float y, int w, int h, float aspect, int rw, int rh, unsigned int *rect) +{ + ui_rasterpos_safe(x, y, aspect); + + if(w<1 || h<1) { + printf("what the heck!\n"); + } + /* rect contains image in 'rendersize', we only scale if needed */ + else if(rw!=w && rh!=h) { + ImBuf *ima; + if(w>2000 || h>2000) { /* something has gone wrong! */ + printf("insane icon size w=%d h=%d\n",w,h); + return; + } + /* first allocate imbuf for scaling and copy preview into it */ + ima = IMB_allocImBuf(rw, rh, 32, IB_rect, 0); + memcpy(ima->rect, rect, rw*rh*sizeof(unsigned int)); + + /* scale it */ + IMB_scaleImBuf(ima, w, h); + glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, ima->rect); + + IMB_freeImBuf(ima); + } + else + glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_BYTE, rect); +} - /* and clean up */ - MEM_freeN(ri.rect); - ri.rect = 0; +/* Render size for preview images at level miplevel */ +static int preview_render_size(int miplevel) +{ + switch (miplevel) { + case 0: return 32; + case 1: return PREVIEW_DEFAULT_HEIGHT; } + return 0; } -void BIF_icon_draw_aspect(float x, float y, int icon_id, float aspect) +/* Drawing size for preview images at level miplevel */ +static int preview_size(int miplevel) +{ + switch (miplevel) { + case 0: return ICON_DEFAULT_HEIGHT; + case 1: return PREVIEW_DEFAULT_HEIGHT; + } + return 0; +} + + +static void icon_draw_mipmap(float x, float y, int icon_id, float aspect, int miplevel, int nocreate) { Icon *icon = NULL; DrawInfo *di = NULL; - + int draw_size = preview_size(miplevel); + icon = BKE_icon_get(icon_id); if (!icon) { @@ -939,65 +1003,61 @@ void BIF_icon_draw_aspect(float x, float y, int icon_id, float aspect) if (!di) { di = icon_create_drawinfo(); - - icon->changed = 1; + icon->drawinfo = di; icon->drawinfo_free = BIF_icons_free_drawinfo; } di->aspect = aspect; /* scale width and height according to aspect */ - di->w = (int)(ICON_DEFAULT_HEIGHT/di->aspect + 0.5f); - di->h = (int)(ICON_DEFAULT_HEIGHT/di->aspect + 0.5f); + di->w = (int)(draw_size/di->aspect + 0.5f); + di->h = (int)(draw_size/di->aspect + 0.5f); if (di->drawFunc) { /* vector icons use the uiBlock transformation, they are not drawn with untransformed coordinates like the other icons */ di->drawFunc(x, y, ICON_DEFAULT_HEIGHT, ICON_DEFAULT_HEIGHT, 1.0f); + } + else if (di->icon) { + /* it is a builtin icon */ + if (!di->icon->rect) return; /* something has gone wrong! */ + + icon_draw_rect(x,y,di->w, di->h, di->aspect, di->icon->w, di->icon->h, di->icon->rect); } else { - if (icon->changed) /* changed only ever set by dynamic icons */ - { - waitcursor(1); - icon_set_image((ID*)icon->obj, icon->drawinfo); - icon->changed = 0; - waitcursor(0); - } - - if (!di->rect) return; /* something has gone wrong! */ - - ui_rasterpos_safe(x, y, di->aspect); - - if(di->w<1 || di->h<1) { - printf("what the heck!\n"); - } - /* di->rect contains image in 'rendersize', we only scale if needed */ - else if(di->rw!=di->w && di->rh!=di->h) { - ImBuf *ima; - if(di->w>2000 || di->h>2000) { /* something has gone wrong! */ - printf("insane icon size di->w %d di->h %d\n",di->w,di->h); - return; + PreviewImage* pi = BKE_previewimg_get((ID*)icon->obj); + + if (pi) { + if (!nocreate && pi->changed[miplevel]) /* changed only ever set by dynamic icons */ + { + waitcursor(1); + /* create the preview rect if necessary */ + icon_set_image((ID*)icon->obj, icon->drawinfo, pi, miplevel); + pi->changed[miplevel] = 0; + waitcursor(0); } - /* first allocate imbuf for scaling and copy preview into it */ - ima = IMB_allocImBuf(di->rw, di->rh, 32, IB_rect, 0); - memcpy(ima->rect, di->rect, di->rw*di->rh*sizeof(unsigned int)); - /* scale it */ - IMB_scaleImBuf(ima, di->w, di->h); - glDrawPixels(di->w, di->h, GL_RGBA, GL_UNSIGNED_BYTE, ima->rect); + if (!pi->rect[miplevel]) return; /* something has gone wrong! */ - IMB_freeImBuf(ima); + icon_draw_rect(x,y,di->w, di->h, di->aspect, pi->w[miplevel], pi->h[miplevel], pi->rect[miplevel]); } - else - glDrawPixels(di->w, di->h, GL_RGBA, GL_UNSIGNED_BYTE, di->rect); } } +void BIF_icon_draw_aspect(float x, float y, int icon_id, float aspect) +{ + icon_draw_mipmap(x,y,icon_id, aspect, PREVIEW_MIPMAP_ZERO, 0); +} + void BIF_icon_draw(float x, float y, int icon_id) { BIF_icon_draw_aspect(x, y, icon_id, 1.0f); } +void BIF_icon_draw_preview(float x, float y, int icon_id, int nocreate) +{ + icon_draw_mipmap(x,y,icon_id, 1.0f, PREVIEW_MIPMAP_LARGE, nocreate); +} void BIF_icon_draw_aspect_blended(float x, float y, int icon_id, float aspect, int shade) { diff --git a/source/blender/src/prvicons.c b/source/blender/src/prvicons.c new file mode 100644 index 00000000000..6222090705a --- /dev/null +++ b/source/blender/src/prvicons.c @@ -0,0 +1,436 @@ +/* DataToC output of file */ + +int datatoc_prvicons_size= 13732; +char datatoc_prvicons[]= { +137, 80, 78, 71, + 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0,192, 0, 0, 0,192, 8, 6, 0, 0, 0, 82,220,108, 7, 0, 0, 0, + 6, 98, 75, 71, 68, 0, 0, 0, 0, 0, 0,249, 67,187,127, 0, 0, 0, 9,112, 72, 89,115, 0, 0, 11, 19, 0, 0, 11, 19, 1, + 0,154,156, 24, 0, 0, 0, 7,116, 73, 77, 69, 7,215, 8, 27, 17, 57, 33, 43,142, 73,203, 0, 0, 0, 29,116, 69, 88,116, 67, +111,109,109,101,110,116, 0, 67,114,101, 97,116,101,100, 32,119,105,116,104, 32, 84,104,101, 32, 71, 73, 77, 80,239,100, 37,110, + 0, 0, 32, 0, 73, 68, 65, 84,120,218,237,125,121,124, 84,213,249,254,115,238,189, 51,147,201,158, 12, 73, 72,216, 3,200, 98, + 88, 69, 66, 38, 65, 16, 20,165, 40,213,162, 32, 45,138,203, 79,176,223, 42,180,110, 72,235,190, 97, 91, 91, 21,181,149,182, 90, + 20, 42, 10, 66, 80,164, 34, 59,146, 5,194, 30, 18, 8, 75, 2,201,144,144,201, 62, 73,102,189,247,158,243,251, 35,235, 36, 51, +217,200,100, 38,229, 62,159,207,124,146,123,239,153, 59,207, 61,247,125,207,121,223,247,156,243, 30, 64,129, 2, 5, 10, 20, 40, + 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, + 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80, +160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, + 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, + 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,160, 64,129, 2, 5, 10, 20, 40, 80,208, 18, 36, 41, 41,105, +180, 32, 8,143, 16, 66, 72,119,223,156, 49, 22, 46,203,242,112,198,216,203, 41, 41, 41,251, 60,241, 0,189,157,191, 2,239, 43, +192, 61, 49, 49, 49, 27,230,204,153,227,215,157, 55,206,206,206,198,169, 83,167, 16, 25, 25, 9,131,193, 64, 37, 73,154,150,146, +146,146,226, 1, 5,232,213,252, 21,120, 23, 2, 0, 68, 71, 71,219, 23, 46, 92,216,109, 2,180,105,211, 38, 24, 12, 6, 60,250, +232,163,224, 56, 14, 7, 15, 30,228, 50, 51, 51, 15, 36, 38, 38, 38,164,166,166,102,116,247, 67,244,118,254, 10,188, 7,174,187, +111, 40, 73, 18,214,175, 95,143, 5, 11, 22,160,111,223,190,240,247,247, 71, 98, 98, 34,226,226,226, 56,149, 74,149,174,215,235, + 39,250,114,133,244,118,254, 10,188,172, 0, 6,131, 1,193,193,193,136,136,136,128, 32, 8,208,106,181,208,106,181,208,235,245, + 24, 57,114, 36,167, 86,171, 51,244,122,125,156,175, 86, 72,111,231,175,192,203, 10, 80, 88, 88, 8,157, 78,215,120,172,209,104, + 26,133, 40, 49, 49, 17,195,135, 15,231,213,106,245,137,132,132,132, 27,124,177, 66,122, 59,127, 5, 94, 86,128,192,192, 64, 88, +173, 86,167,115,254,254,254,141,159,164,164, 36,196,198,198, 10,126,126,126, 89,122,189, 62,214,215, 42,164,183,243, 87,224,101, + 5,208,233,116, 48,153, 76,173,206, 55,180,162, 90,173, 22, 73, 73, 73, 24, 56,112,160, 74,163,209,156,213,235,245, 3,124,169, + 66,122, 59,127, 5,157,131,208,221, 55,140,138,138, 66, 77, 77, 13,172, 86, 43,180, 90, 45, 0,160,170,170, 10,165,165,165, 40, + 47, 47, 71,105,105, 41, 44, 22, 11, 6, 15, 30, 12, 81, 20,213, 87,175, 94, 61,175,215,235,135,164,165,165, 21,251, 66,133,244, +118,254, 10,188,172, 0,106,181, 26,227,199,143, 71, 78, 78, 14,116, 58, 29, 14, 28, 56,128,130,130, 2,196,198,198, 34, 42, 42, + 10, 67,135, 14, 5,207,243, 72, 77, 77,133,209,104,132, 40,138,126, 26,141, 38, 79,175,215, 15, 74, 75, 75, 43,245,118,133,244, +118,254, 10,188,172, 0, 0, 48,109,218, 52,124,250,233,167, 16, 69, 17,143, 63,254, 56,102,206,156, 9,181, 90,237, 84,102,209, +162, 69, 48,153, 76, 88,183,110, 29,182,108,217,162,165,148,190, 9,224, 9, 0,204,219,149,210,219,249, 43,240,162, 15, 0, 0, + 9, 9, 9, 8, 12, 12,196, 71, 31,125,132,217,179,103,183, 18,158, 6,132,132,132,224,201, 39,159,132, 70,163, 97, 86,171,117, +108,104,104,104,127, 0,196,219,149,210,219,249, 43,240,178, 2, 4, 5, 5, 97,205,154, 53,136,137,137,233, 80,249, 33, 67,134, + 72, 86,171,213,204,243,252,253,190, 32, 64,189,157,191, 2, 47, 43, 0, 0, 8, 66,199,173, 43, 63, 63, 63, 70, 41,149, 24, 99, + 26, 95, 17,160,222,206, 95,129,151, 21,160,139,144,123,121,125,202,138, 72, 41, 10,208, 37, 16, 66,100, 66, 72,175, 21,160,222, +206,255,122,133,208, 19, 63, 98,178,216,193, 24,131, 74,224, 17,160, 81,185,109, 61, 25, 99, 50,122,111, 20,165,183,243, 87, 20, +192, 19,200, 45,174,194,152,103, 62, 5, 0, 68,135, 5,226,252,234, 37,224,185,122, 51,153, 81, 56,142,252, 11,183, 71, 92,225, + 39,223, 22, 56, 50, 88,173,213,234, 99,111,136,134, 64,254, 25,249,155,244,139,158,230,166, 82,185, 85, 70,136,162,216,217, 30, +128, 2,160,138, 15,160, 40,128, 19, 62, 63,112,186,241,255,171,149,181,248,241,100, 30,126, 54,113, 40, 0,128,154,174,192,126, +124, 61,146,194,192, 35, 76, 51, 28,192,112, 0,183, 17,137,255,216,155,194,223,145,235, 45,148,132, 1,104, 48,129,148, 30, 64, +241, 1,234,109, 2,202,240,159,159,178,157,206,125,113, 32,171,241,127, 90,118,190,213,119, 24, 80, 30,190, 60,165,192,155,194, +223,197,251, 80,197, 9, 86, 20,192, 9, 59, 79, 93,194,213, 42, 51,180,234,166,142,230,135, 19,121, 40,173,182,212, 41, 72,217, + 5,184,208,128, 19,189,169, 2,155, 41, 1,173,247, 1, 20, 40, 10,224,220,218,191,255,240, 76, 52, 44, 89, 23,101,138, 13, 41, +103,234, 36,166,212,101, 15,112,220,215, 43, 77, 20, 69,167, 15, 0, 13,165, 20, 0,244, 0,120, 69,172, 20, 5, 64,105,181, 5, +255, 61,158,139, 65, 17, 33, 88,116, 75, 28,102,196, 13,106,230, 23,100,213,247, 0, 46, 20,128,178,227,189,173, 18, 25, 99, 0, + 16, 7,160, 76,241, 1, 20, 39, 24, 0,176, 33,229, 12, 68,153,226,161,105, 55,130, 16,224,161,105, 99,176,231,116, 62, 0,224, +236,149,114,100,100,102, 97,148,189,166,213,247,204,140,157, 0,128,146,143,167, 7,242,212, 54, 7,192, 72, 70,137,131,227,113, + 90,148,232,145,168,223, 30, 54,250,168, 2,252, 4,160, 90, 17, 41,165, 7,104,108,229, 57, 66,240,224,180,186,229,179,115, 39, + 13, 67, 88, 64, 83,226,134,181,123, 91,155,250,162,204, 44,187,114,228, 75,229,171,227,159,225,101, 91, 49, 24,190, 2,195,171, +132,176,183, 25,101,219, 4,142,228, 85,172, 78, 88,234,139, 21,233,112, 56,202, 25, 99,134,122,103, 88,193,245,172, 0, 71,115, +139,113,246, 74, 57,102,142, 25,132,254,225, 65, 0, 0,141,138,199,130,196, 81,141,101, 54,159, 42,133, 85,118, 54,151,171,172, +180,224, 23,113,170,117, 0,121, 23, 64,128,139, 91,251, 51,176, 79,202, 62, 72, 88,229,131,117, 25, 98,179,217,250,195,247,166, +151, 40,232,105, 5, 88,187,191, 46,246,191,120,250, 24,167,243, 15, 79,111, 74,166, 80,227, 96,216, 86,230, 60,219, 82, 23,192, + 15, 35,192,130,246,238, 79, 8,123,166,236,189, 41,163,188, 85,105, 42,149,170, 85, 40,149, 16, 2, 74,169, 77, 81,128,235, 92, + 1, 44,118, 17,223,164,159,131, 46, 72,139,187,110, 26,234,116,109,236,160, 72,140, 27, 28,217,228, 39, 24, 7, 57,147, 33, 16, + 24, 96, 7,240, 79, 2,242, 75, 2,242, 75, 6, 28,112, 37,131,132,195,115,222,170,180,102,209,159, 70,225,231, 56, 14, 42,149, +234, 40,234,162, 64,202,104,240,245,170, 0, 91,143, 92, 64,181,213,142, 7, 18, 71, 65, 45,180,142, 8, 62,220,172, 87, 72,175, + 14,199,101, 91,147,165, 67, 41,236,162,204,238,214, 45, 59,180, 36,124, 89,250,134,240,101,233, 27,116, 21,126,183, 1,200,105, +221, 13,224,198,107, 17, 96, 15, 33,166,222, 7, 96, 0, 84,138,120, 93,135, 10,208, 16,251, 95, 60,205,117,238,168,249,250,145, +240, 19,184,250,232, 9,193,134,226,129,141,215, 14, 92, 52,255, 43,250,119,135,247, 56,201,249,171,251, 37, 66, 88,178,139,216, +139, 79,229,229,169,207,205, 43,212,127, 72,125,221,106, 20, 17,187,142, 20,224, 82,137, 9, 7,207, 26, 48, 49, 54, 10,113, 3, + 35, 92,150, 9, 11,240,195, 93,195,154,150, 24,126,109, 28, 8,153, 17, 88, 37, 88, 95,218,102,220,233, 70,188,170, 92,156,243, +243,149, 74,164,148,130, 82, 10, 73,146, 56, 0, 13,221,139, 31,234,204, 57, 5, 62,140,110, 29, 7,248,226, 64, 22, 24, 3,146, + 70, 14, 64,102,126,137,219,114, 19,131, 42,241, 13,234, 82,142, 92,117,248, 97,127,101, 36, 2,107, 11, 47, 24,107, 36,171,171, +242,140,161,159,139,211, 62,149,129,161,190, 7, 16,209, 52, 16,102, 82,196,235, 58, 82, 0,202, 24,214,255, 84,103,254,172,254, +239, 81,172,254,239,209, 54, 74,107,157,142, 54, 24, 7,226, 94,114,165,202,221,130, 18, 2, 50,136,181, 30, 96,205,242, 86,165, + 53, 68,128,154,251, 18,140, 49,112, 28, 39,214,215,169,168,136,214,117,166, 0,187, 78, 93, 70, 97, 69, 45,166,142, 26,128,219, +199, 14,118, 95, 80,118,192,126,116, 45, 14,155,194,177,187, 50, 10, 0,240, 99,121, 95,220,168,209, 88, 40,165,173,166, 19,151, +175,142, 15,102, 96,183,182,234, 21, 0,175,231,234, 87,169, 84, 78, 74,192,113,156, 67, 49,123,174, 83, 5,104,112,126, 95,186, + 79,143,164,145,253,221,150,147,138, 78,192,106, 60,143,139,186, 64,236, 62, 86,167, 0, 14,198,225, 44, 63,108, 24, 33, 57,178, + 11,211,226, 9,198, 16,220,178,195,225,101,124,233, 11, 21,216,208, 27,168, 84, 42,155, 90,173,110,112,128, 21, 92, 79, 78,112, +121,141, 21,219,143,231, 98, 72,100, 8, 18, 71,244,111,219, 84,170,159, 1, 58,204,191, 22, 55, 7, 87, 52,158, 63, 45,247, 31, + 76,235,167, 84, 54,160,236,195,201, 51, 24,195, 75, 46,140,162, 45, 97,191, 59,116,217,135,236,255, 82, 65, 16,120, 40, 19,225, +174,207, 30,224,171,212,179,112, 72, 50, 22,221,114, 35,218,219,169,171,249, 26,128, 95, 70,229,227, 72,117, 56, 0, 32,207, 22, + 36,124,241,127,250, 79,110,139,170,120,141,112, 40,231, 25,110,167, 12,207,160,117, 40,209,194,113,228, 89, 95,170, 68,158,231, + 3,120,158,175, 97,140, 29,135, 50, 23,232,250,235, 1,214,238, 63, 13,142, 16, 44,186,165,253,125, 35,154,175, 2,251,121, 68, + 33,252, 57,169,241,120,111,109,255, 49, 60,193, 55, 28,195, 62, 6,252,158,180, 22,126, 10, 66, 30, 14,123, 50, 45,223,199,234, +145, 17, 66,168, 39, 54,234, 83,224,163, 61, 64, 65, 89, 53,118,158,186,132,242, 26, 43,178, 13,101,232, 23, 30,136, 31, 79,230, + 1, 0,126, 54,113, 40, 98,194, 2, 91, 75,137,100, 3,173, 42, 64,165,164,198,119,165,117,243,128, 6,105, 45, 56,107,174, 51, +241,183,148,246,199,232,128,186, 25,197,183,134,149, 96,160,159,197,201,125, 32,192,178,240,167,210, 55,249, 82, 5,138,162,216, + 16, 2,149, 91,154,112, 10,254,135, 21, 32,203, 80,134,101,159,237,110, 60, 46,172,168,109, 60, 30,214, 55,204,165, 2,208,242, + 92,128, 81, 20,219,253,240,252,197,113,173,174, 87, 75,170,198,243,159,141,202,104,174, 0, 57,132,224,255,133, 63,117, 40,181, + 59, 5,247, 90,215, 6, 55, 68,128, 24, 99,168,239, 1, 20, 5,184, 94, 20, 32,126, 88, 52,118,252, 97,190,203,107, 99, 7,185, + 30, 5,230,130,251, 65, 59,247, 3,140,112,200,216, 62,185,166,222,129,228,177,230,235, 31,109,135,207,228,173, 11, 12,208,156, +126,112, 28, 25, 30,161,178, 15, 25, 27,100,178, 1,200, 97,132,238,235,243, 84,198, 94, 79,181,222,157, 77,141, 34, 73, 82,171, +180,137,132, 16, 48,198,168, 44,203, 65,138, 72, 93, 39, 10,160, 11,210,226,150,209,157,219, 28,133,104, 67, 33,104, 39, 32, 4, +192,173,131,155,206,127,191,245, 59, 57,220,116,225, 66,126,102,254,174, 63,236, 48,125,212,147,209,148,206, 78,140,115,151, 51, + 84,201, 12,119, 29, 59,193,221,132,222, 46, 64,138, 2,244,214, 30,192,100, 50, 9, 25, 25,222,219,255,217,100, 50,241,132, 16, + 42,203,178,220,197,239,247,106,254, 10,188,171, 0,198,226,226,226, 83,171, 86,173,226,237,118,123, 52, 99, 76,141,186,176, 30, +234, 77, 17,214,204, 36, 97,132,144,198,255, 91, 94,115,119,189,197,189, 90,150,101,178, 44,203,146, 36,149,212, 59,145,157, 53, +127,122, 59,127, 5, 94, 68,243,184, 53,167,211,233,150, 3,232,139,166, 44,103, 50, 99, 76, 34,132,200,140, 49,153, 16, 34, 53, + 59, 71,155, 93,107, 56, 47, 19, 66,164,250, 4, 81,114,195, 53, 66,136, 76, 41,149, 90, 28,203, 13,118, 51,165, 84,146,101, 89, + 98,140, 89,204,102,243,149,174,154,115,189,156,191, 2, 47, 43, 0, 9, 12, 12,140,230, 56, 78, 77, 8, 97,245, 19,189, 26, 91, +185,134, 86,176,249,113,125,232,143, 1,128,195,225,112,106, 65, 9, 33,172,217,167,161, 44, 44, 22,139,211, 61, 56,142, 99,132, + 16, 86, 89, 89,201,234,133,182,171, 51, 41,123, 59,127, 5, 94, 86, 0, 87,199, 29, 5,243,209,231,233,109,252, 21,244,180,192, + 36, 37, 37,141, 22, 4,225, 17, 79, 12,227, 51,198,194,101, 89, 30,206, 24,123, 57, 37, 37,101,159, 39, 30, 64,225,175,240,191, + 86, 5,184, 39, 38, 38,102,195,156, 57,115,186,117,137, 97,118,118, 54, 78,157, 58,133,200,200, 72, 24, 12, 6, 42, 73,210,180, +148,148,148, 20, 15,188, 0,133,191,194,255,154,162, 64,136,142,142,182, 47, 92,184,176,219, 30, 96,211,166, 77, 48, 24, 12,120, +244,209, 71,193,113, 28, 14, 30, 60,200,101,102,102, 30, 72, 76, 76, 76, 72, 77, 77,237,246,120,165,194, 95,225,223, 85,116,251, + 64,152, 36, 73, 88,191,126, 61, 22, 44, 88,128,190,125,251,194,223,223, 31,137,137,137,136,139,139,227, 84, 42, 85,186, 94,175, +159,232,203, 54,161,194,255,250,226,223,237, 10, 96, 48, 24, 16, 28, 28,140,136,136, 8, 8,130, 0,173, 86, 11,173, 86, 11,189, + 94,143,145, 35, 71,114,106,181, 58, 67,175,215,199,249,234, 11, 80,248, 95, 95,252,187, 93, 1, 10, 11, 11,161,211,233, 26,143, + 53, 26, 77,227, 67, 36, 38, 38, 98,248,240,225,188, 90,173, 62,145,144,144,112,131, 47,190, 0,133,255,245,197,191,219, 21, 32, + 48, 48, 16, 86,171,115,118, 19,127,127,255,198, 79, 82, 82, 18, 98, 99, 99, 5, 63, 63,191, 44,189, 94, 31,235,107, 47, 64,225, +127,125,241,239,118, 5,208,233,116, 48,153, 90,167,196,105,208, 98,173, 86,139,164,164, 36, 12, 28, 56, 80,165,209,104,206,234, +245,250, 1,190,244, 2, 20,254,215, 23,255,110,223, 32, 35, 42, 42, 10, 53, 53, 53,176, 90,173,208,106,235,242,255, 84, 85, 85, +161,180,180, 20,229,229,229, 40, 45, 45,133,197, 98,193,224,193,131, 33,138,162,250,234,213,171,231,245,122,253,144,180,180,180, + 98, 95,120, 1, 10,255,235,139,127,183, 43,128, 90,173,198,248,241,227,145,147,147, 3,157, 78,135, 3, 7, 14,160,160,160, 0, +177,177,177,136,138,138,194,208,161, 67,193,243, 60, 82, 83, 83, 97, 52, 26, 33,138,162,159, 70,163,201,211,235,245,131,210,210, +210,188,158,237, 77,225,127,125,241,247,200, 22, 73,211,166, 77,195,167,159,126, 10, 81, 20,241,248,227,143, 99,230,204,153, 80, +171,213, 78,101, 22, 45, 90, 4,147,201,132,117,235,214, 97,203,150, 45, 90, 74,233,155, 0,158,128, 15, 76, 75, 80,248, 95, 63, +252, 61,178, 32, 38, 33, 33, 1,129,129,129,248,232,163,143, 48,123,246,108,183,171,168, 66, 66, 66,240,228,147, 79, 66,163,209, + 48,171,213, 58, 54, 52, 52,180, 63,124, 32,177, 84, 75,254, 45, 43, 95,225,255,191,195,223, 35, 10, 16, 20, 20,132, 53,107,214, + 32, 38, 38, 6,207, 62,251, 44,102,204,152, 1,135,195,225,182,252,144, 33, 67, 36,171,213,106,230,121,254,126, 95,120, 1,205, +249,119, 4,189,141,191,217, 46,225, 82,105, 45,142, 95,174,192,190, 51,197,136,136,155, 70, 73,212, 40,191,136,184,169,207,196, +175,248, 79,191,235,169,254, 61,182, 75,164, 32, 8,248,252,243,207,177,122,245,106, 0, 64,114,114, 50, 22, 44,112,189,251,145, +159,159, 31,163,148, 74,140, 49, 13,124, 36,181,160,187, 94,171, 55,243, 63,122,169, 2,155, 50, 12,200, 41, 50,129,202, 82, 99, + 90,119, 22, 54,158, 15,157, 50,118,124, 8,165,227, 41,149,151, 37,190,240,245, 22,202,196,215,210,255,184,232,244,255,122,253, + 11,158,124,136, 63,252,225, 15, 0,128,216,216, 88,124,241,197, 23,110, 21,160, 25,122,251,146, 66,159,229,127,185,204,140, 55, +191,205,134,192, 1, 49, 33, 26, 20,148,137, 96,148,130,177, 86, 31, 2, 70,231,129,146, 95, 76,126,118,253,188,140,119, 23, 37, +119,250,189,111,248, 9, 89, 5,158,245,167,191,121,246, 94,168,120,238,154,235,223, 99, 10, 80, 84, 84,132,146,146, 18,188,249, +230,155,120,238,185,231,176,120,241,226, 54,203,247,246,172, 10,190,206,255, 68,126, 37, 24,163,120,235,254, 9, 24, 17, 29,140, + 63,109, 59,141,189, 89, 69, 96, 13,189, 64,227, 95,214,112, 76, 64,233, 59, 0, 58,173, 0,207,220, 61, 25, 14,201,179, 85,209, + 82,248,187, 90,255, 30, 83,128,236,236,108, 68, 68, 68,224,217,103,159, 5, 33, 4,185,185,185, 46,115,234, 52,215,222,250,165, +136,189,117,113,138, 79,243, 63, 83,104, 2,165, 20, 2, 87,103, 33,168, 56, 82,215, 3,180,248,180, 80,130, 27,110, 90,178,198, +255,216, 63,150, 90, 58,243, 91, 57,133,229, 40,175,181, 94, 51,103,209, 97,119,235, 59,206, 26, 59, 24, 92,253, 18, 4,187,221, + 14, 89,150, 57, 89,150,213, 0, 66,208,118,126,214,234,230,215, 59,164, 0,159,237,205,196,165,146,206,109,120,146,157,150,138, +232, 81,147,240,202,198, 84, 72, 14, 59,206,156,191,136, 87,190, 78, 1,199,183,222, 56,239, 80, 77, 8, 95, 54,112,234, 72,235, + 0,149, 86, 8, 31, 20, 13,144,118,133, 72, 82,227,143,248,114,101,165, 15,245, 0,180,190, 98,125, 50, 63,168, 67,148,193, 40, +195,138, 47,143,162, 95,152, 22, 57,133,149,117, 2,207, 24, 24,163,160,204,165, 57, 4,217, 95,173, 6,208, 41, 5,200, 51, 86, + 33,191,172,250,154, 57,239, 92,247, 49,210,183,111,236, 72, 81, 53,128, 59,235, 63,111,183, 83,246, 70, 0,103, 58,165, 0,250, + 17,253,220,238,249,229, 14, 17, 86, 3,138,250,248,225,238, 73,195,240,233, 71,239, 33,208,223, 31, 63,143, 31,225,186,194, 82, +183,211, 98, 83,126,161,228, 96,167,164,240,129,223, 18,158,111, 63,197, 96,165,214,210, 93,194, 65,171, 12,224, 66, 59, 54,162, +110, 50,153, 96,179,217, 16, 21, 21,213,252, 52, 67, 83, 94, 32, 31,237,193,234, 4,221,108,151,113,174,200,214, 36,244,148,130, + 82,230,214, 20, 2,215,249, 64,225,162, 91,110,236, 22,198,166, 67,201, 72,175,139,242, 32, 34,194,181,252,157, 57,115, 6,181, +181,181, 13,141, 80, 25, 99, 44,215,205,237, 70, 1,173,246,153,232,152, 2,140,236,167,235,188, 61, 80, 58, 4, 63, 92,202, 65, +148,202,129, 13,159,125,130, 25, 51,102, 96,242,176,104,151,101,163, 84, 14,234, 95,109, 40,179,150,151, 95,172,201,220,123, 8, + 61,156, 98,220,113, 98, 61,184,136, 17, 80,199,253,162,221,178, 85, 85, 85,152, 59,119, 46,118,239,222,221,242,165, 80, 95,115, +130, 25, 99, 16,229, 58,125, 92,126,199, 72,136,242, 8,103,253,100,117,255, 63,248,167,173,204, 14,129,184, 50,133, 0,128, 93, +125,186, 97,177,139, 68,162,255, 42,181,247,187,203,255,189, 27, 39, 47,151, 92,187,227,158, 86,183, 59, 46, 55,106, 6,248,113, + 83,157,174,237,122,105, 1,212, 2,143,105,211,166, 33, 61, 61, 29, 0,160,209,104,126,176,217,108, 15,187,145,159, 61, 0,102, +244,152, 15, 48, 96,192, 0, 28, 59,118, 12,219,183,111,135,205,102,195,252,249,243,219,109,136,235,109,104,175,180,142,246,148, + 15, 64, 56, 30,170,209, 63,111,183,244,217,179,103,113,199, 29,119, 96,231,206,157,232,211,167,143, 15,240,119,150,233,140,188, + 10,164,158, 47, 65, 70, 94, 57,204, 86, 7, 40,149, 91,181,240, 78,231,160, 34, 13, 38, 80, 75, 83,232,181,159, 93,137, 4,112, +174,241, 25,175,254,238, 44,152,188,140,196,172,118,155,175,245,131, 71,110,235,150,103,121,222,122, 18,239,103,236,192,138,123, +226,241,240,195,191,236,136,194,119,186,225,236,144, 2, 56, 36, 25,148,117,174,103, 55,219,108,216,187,119, 47,100, 89, 70,100, +100, 36,102,205,254, 25,108,162,228, 38,118, 72, 64,121, 1,208,104, 57,220,189,212, 15,186,232,246, 31,100,237, 43,246,142,248, + 10,157, 81, 2,219, 79,127, 5, 8, 15,213,168,187,218, 45,157,149,149,133, 59,239,188, 19, 59,119, 54,238,236,234, 19, 81,160, + 79,246,229,226,199,204,162, 38, 97,111, 33,216, 77, 2,206,156,237,125, 23,166, 80,235, 42,162, 28,152,116, 35,152,252, 29, 51, + 44, 25, 72, 6,252,163,194, 21,135,175,211,114, 96,232, 6, 31,224,104,110,221,252,182, 31, 79, 94, 66,217,119,206, 43, 33,127, +119,215,205,224,185, 86,238,150,103, 20,224,181, 77,169,157,138,235, 58,204,213, 72, 91,243, 18, 26, 50, 5, 14,152,181, 24,143, +253, 99,143,251, 22,181, 50, 92, 85, 26, 59,123,170, 72, 84,163, 4, 77,240, 47, 96,110,223,142,150, 22,190,189, 24, 27, 96,236, +238,158,192,118,224,207, 0,199, 67, 53, 98,118,187,165, 51, 51, 51, 49,123,246,108, 76,154, 52, 9,245,137,182,188,170, 0, 57, + 87,107,240,227,233,171,237, 10,182,187,191,172,222,236,113, 45,252, 18,192,228,186, 15,149, 2,192,228,223, 0,120,195,165, 73, + 27,226,223, 24,161,185, 22,204,152, 53, 27, 67, 6, 13, 68,220,164,201,232, 31, 17,210, 34,232,224,218,138,104,227,118, 31, 3, +216, 6,160,184,211, 10,240,214,194, 91, 58, 69,124,225,194,133,176, 86,214,217,128, 43, 86,172,192, 27,111,188,209,102,249,167, +159,126,218,177,235,232,174, 93,165,165,165,187, 42, 42, 42,190,132, 87,183, 25, 98,176,237,255, 35, 8,199, 67, 24, 62,171,221, +210, 39, 78,156, 64, 97, 97,161, 42, 40, 40,136,247,182, 15,176,247,140,177, 93,193,102, 45,206, 57,149,173,239, 33,154,161,118, +214,232,138, 64, 48, 9,160,178,179, 18, 48,233,255,220, 41,192,164,161,125, 33,201,215,254, 10,111, 31, 59, 8,192,189, 46,175, +185, 81,176,182, 26,206, 45, 93,238, 1, 58,131, 77,155, 54, 97,243,230,205, 0,128,233,211,167, 99,220,184,113, 29, 14, 35,250, +130, 13, 93,223,213,195,186,247,109,104, 9, 15, 97,216,204,118,139,151,148,148,112, 85, 85, 85, 51,181, 90,237, 78,111,210, 46, + 40, 51,183, 22,108, 39,211,135,181,109, 10, 81,218,232, 24,215,139,211, 14, 63, 34,198,131,214, 11,190,179, 18,244,101,185,247, + 69, 76, 93, 92,236,210, 98,200,204,247,236, 72,240,182, 23,230, 65, 45,240, 61,227, 3,116, 20, 70,163, 17,203,150, 45, 3, 0, + 60,245,212, 83, 88,190,124, 57,222,127,255,125,220,119,223,125,237, 9,191,207,216,208, 78, 74,176,231, 13,104, 57, 30, 66,236, +244,246,205, 62,135, 35, 66,146,164, 21, 0, 54,163,110,176,165,199, 81,108,178,180, 22,236, 86,145,157, 54, 76, 32,103, 63,239, +220,188,201,149,175,129,138, 59,235, 91,252,230, 38, 80,195,255,195, 93,241,248,243,131,183,122,235,173,121, 70, 1, 58, 58, 16, +182,229,253,151, 80, 94, 94,142,126,195,227,224, 55,241,110,124,188,247, 44, 54,126,247, 3, 28, 3, 39, 35,172,175,251, 73,134, +233, 53,193, 66,241,128, 91, 38, 89, 7,106,116, 66,112,244, 77, 62, 51, 16,198, 40,172,187, 95,131,246,118, 30,194,144,169,237, +215, 62,165, 35,234,237,204,159, 1, 48,247,228,155,183,139, 50,202,170,173,109, 10, 56, 24,197,168,126, 97, 24, 30, 19, 10,127, + 53, 95,175, 36, 12,187,247,236,145, 10,140,101,217, 18,175,189,164, 14, 31,144, 77,128,172,111,127,115,246,252,128, 80,219, 23, + 96, 82,180,139,214, 31,245,102,209, 48, 87,202,254,238,119, 25, 56, 95, 84,225,209,231,253,248,241, 89,174,230, 2,121, 70, 1, +166,223, 56, 16,147,134, 58,218,142,138,156, 58,129, 11,199,211,160,235, 19,129,127,253,123, 45, 34,162,250,226,245,149,207,162, +164, 32, 23,255,120,254, 33, 68,247,235,143, 71,150, 62,137, 95, 44, 92,212,186,235, 78,219, 78, 75,170, 46, 94,144,236, 72,167, +129,186,253,224, 85,237, 63,136, 40,246,140,128, 81, 25,214, 93,175, 64,123,199, 27, 16, 6, 37,118,228, 27,183,212, 43,193, 28, + 0,214,158, 82, 0,158, 35, 0, 99,110,109,252,176, 64, 53,126, 63,111, 18,110, 30, 80, 14, 34, 93, 6, 88,211,134,246, 55,251, +149, 18,201, 94,174,234, 19, 74,252, 71, 13,171,138, 38,160,119,130, 74,227, 65,101,190,141,214, 31, 96, 82,128, 43, 5, 88,144, + 56, 10, 86,187,103,115, 4, 11,174, 7,232,152, 71, 20, 32, 54, 42,180,221, 50, 23,143,213,201,227,250,117, 95, 96,230,228,177, + 88,191,126, 61,190,251,230,171,198,235, 87, 11,175,224,237,151, 95,192,200,193, 49,120,224,129, 7,156,190,219, 71, 37,202, 1, +181, 87, 75,106,141,198,139,181,153,123, 79,194,215,246,218,165, 18,172, 59, 95,134,118,214,155, 0, 58, 52, 71,253, 86, 0,223, + 1,184, 27,128,173, 39, 40, 10, 60,135,240, 0, 21, 74, 76, 98, 43, 27,159,128,225,181, 7,166, 96, 92,216, 15,224,106,178, 90, +125, 87, 63, 30, 60, 88,232,104, 80,121,180,139, 86, 30,173,148,160, 73, 17,114, 80, 55,247,198, 9,102,155, 3,213, 86,199,255, +142, 9,212, 17,148,151,151, 35, 52, 52, 20, 51,103,214, 57,141,111,189,245, 22,198,141, 27,135,249,243,231, 35, 47, 47, 15, 35, + 71,142,196, 59,239,188,131, 23, 95,124,177,149, 2, 52,115, 96,124,119, 54,168, 44,194,150,242, 30,144,240,118, 71,191,113, 27, +128,135, 0,252,163,167, 40,246, 13,209,194, 88, 89,219,202,244,153,114, 67, 20,198, 70, 21,128,171,205,114,209,102,182, 16,112, + 87,166,142,203,243, 50, 64,165,179, 0,166,180,188,229,206, 83,151,112,161,216,179,214,233,196, 33, 81, 16,122,202, 4,170,181, + 57,218, 13,107,197, 12, 28,140, 81,163,111, 68,149,217,134,146, 18, 35,114,115,115,241,205,214,239, 16, 63, 37, 1,143, 62,180, + 8,171,222,125, 15, 34, 5,126,191,226, 57,100,229, 92, 64,255, 1, 77,115,111,236,148, 16, 89,229,175,146, 2,250,248,225,230, +135, 67,161, 13,110,255, 65,198,163, 26,175,190,218, 99, 61, 5,231,175,131,118,206,187, 40, 55,117,184,151,125,191, 39,133, 31, + 0,134, 68, 4,226,100, 94, 73,171,112,231,232, 1,225, 32,226,233,214,214, 66, 91,173, 60,117,161, 4,206,231,175,144,184,148, +226,164,164,164, 86, 60,150,253,108,146,119,226, 22,158,138, 2,253,101,219, 17,100, 27,218, 14,107,201, 14, 59, 78, 95,184,132, + 37,107,118,128,202, 18,180, 33, 58,124,145, 85,131,245, 57,251,144,117,165, 2, 75,214,236,128,100,139, 0, 39,168,240,252,231, + 59, 17, 24,209,228, 20,103, 85,135,169,138, 7,207,184,205, 65,212, 99, 4, 77,224, 67, 29,114,130, 79, 9, 75, 0,148,244,152, +240,207,253, 0, 92,232, 64,192,148,223, 81,225,255, 93, 79, 11,192,188,248,193,248,238, 72, 30,100,217, 57,220, 25,232,167, 2, +161,181, 78,206,125,199, 90,249,230,202,209,226, 26,240, 23,119, 60,126,253,207,157, 56,158,231,217, 44, 43, 7,223,248, 85,171, + 48,168,199,122,128, 87,238,239,144,243,135,249,199, 55,227, 47,247,223,132, 1, 3, 6,224, 29,249, 34,180,154, 34, 44, 95,190, + 28,203,243,247,225,165,135,146,224,231,231,135, 81,127, 95,129,109,111, 62, 1,190,217,180,232,103,158, 57,232,216,115,108, 79, +178,209,104,252,161,188,188,124,191, 47,249, 0, 78,194,223, 49,124,224, 13,225, 7,128,200, 16, 45,102,143, 31,128,173,135,115, +157, 28, 96,231, 9,112,157,106,229, 91, 40,135,220,240,106, 74,219,234,221,254,254,248, 44,175,188,171,102,251,187,245,188, 15, + 0, 0,127,255,251,223,241,252,243,207,227,239,127,255, 59, 94,120,225, 5, 36, 39, 39, 67,146, 36,140, 27, 55, 14,199,143, 31, + 71,126,126, 62,238,184,227, 14, 39,225,111,230,189,203,148, 82,159,154, 78,220, 89,225,231,121,254, 27, 89,150,127,231, 77,206, +191,190, 35, 14,126, 42, 14, 7, 78, 27, 80, 92, 89, 11, 6, 82, 63,106, 74, 1, 38,186,108,229,101, 81, 6,152, 36, 19, 34, 83, + 14, 50,117,171, 4,117, 14,253, 81, 0,207,146,184, 84,183,211,209,119,158,186,132, 18,147,197,163,207,185, 48,105,116,171,185, + 64,245, 38, 16,243,154, 2,232,116, 58,188,248,226,139, 88,185,114, 37,238,186,235, 46,220,123,111,221, 48,246,152, 49, 99,240, +250,235,175,227,198, 27,111,196,154, 53,107,220,105, 47,245,165,129,176,206, 10,127, 80, 80,208, 17,149, 74,245, 65, 69, 69,133, + 87,121,171, 4, 14, 75,102,197, 97,201,172, 22, 9,148, 77,123, 1, 42,186, 52,117,254,181, 45,216,158,113,228,196,231,209, 97, +214,159, 94,249, 77,255,227, 42,158,177,102,189,193,121, 18,119,176, 83, 61,178, 40, 83,183, 19, 31,123,101, 20,232,147,157, 39, +144,107,172,234, 56,139,209,183,227,131,173, 7,241,202,223,214,163,232, 66, 54,170,203,141,144, 28,118,140,184,255,183,120,225, +203,159, 90,219,115,213, 33,234, 43, 3,111,157,105, 25,172, 29, 42,248,135,221,215,145, 69, 85, 18, 52,175, 99,211,211, 21,190, + 32,252,227,198,141,147, 36, 73,218, 89, 88, 88,232, 91,225,219, 22,161,220,186, 86,189,181,169,179,244,238, 18,205,210,187,162, +150,128,201, 75, 90,181,254, 96, 97, 0,170, 58,243, 83,115, 38, 14,245,150, 19,236, 25, 19,104,214,184, 33,168,181,117, 50,174, +123,155,243, 62, 6, 75, 23,221,143,135,166,141,113, 89,180,228,200,143, 82, 85,213,197,147,146,168, 74,113, 12,158,156, 5,194, +117,224, 65,170,107,125, 65,248,151, 45, 91, 6,198,152, 99,223,190,125, 62,190,168, 95,114,107, 2, 57, 69,129, 84,209,102, 16, +129,192,122,222,191,203,102, 88, 39,157,224,221, 47, 63,128, 32,173,218,119,123,128,142, 12,132,181,135, 49,163, 70, 96,236,160, + 72,151,215,250,168, 68, 57,168,182,176,168,186,176,240,172,249,232,182,147,222,242, 3,186, 34,252,239,190,251, 46,158,121,230, + 25,230,107, 38, 92,235,214,145, 7,105, 48,129,220,216,248,148,105,109, 92,236,218, 0, 16, 14,184,176,160, 22,142, 66,127, 0, +246, 78,251,130, 94,114,130,225,205,129,176,230, 56,113,226, 4,190,252,242, 75, 76,157, 58, 21,115,231,206, 5, 0, 12, 29, 58, + 20,178, 44,187,114,128, 27, 39,195,213, 59,193,232, 77,194,239, 43,252,219, 85, 0,213, 96,192,156,222,102,180,135, 48,137,135, + 92, 13,112, 26, 64,174, 38, 0, 78,146,184, 84,171,175, 61,203,246,237,219, 81, 88, 88, 8, 0, 40, 46,110,234,105, 40,165, 19, +209,148, 31,116, 63,128,156, 30, 87, 0, 74, 41,230,205,155,135, 43, 87,174,224,227,143, 63,198,241,227,199, 49,114,228, 72,132, +132,132,192,106,181, 34, 48, 48,208,149,237,230, 85, 39,152,248,247,233,178,240,251, 2,255, 14,189,151,192, 89,224, 44,135, 64, +172,103, 93,155, 64,160, 32,128, 10,231,127,110, 7, 56, 6, 38,137, 0,150,250,226,179,172, 94,189, 26,251,246,237,115, 37,123, +115, 80, 55, 7, 11, 0, 30,243,138, 2,212,214,214,226,202,149, 43,141,202,208,208,226, 23, 23, 23, 67, 20, 69,119, 17, 32, 48, +198,168,220,176,132,172,135,161,185,249, 49,128,227, 59, 84,182, 95,191,126, 78,194,239, 11,252, 59,166,229, 42, 72, 81,175,131, + 51,167,129,171, 88, 7, 98,191,220,220,209,109,214, 26,201,118, 64,126, 15,192,123, 36, 46,213,228,139,143,242,231, 63,255, 25, +149,149, 77, 83, 45,254,246,183,191,217, 14, 31, 62,188,174,180,180, 52, 77, 20,197,252,250, 7,202,233,200,189,186, 93, 1,130, +131,131,113,251,237,183, 35, 59, 59, 27,159,127,254, 57,134, 15, 31,142,140,140, 12, 24,141, 70,132,133,133,185,127, 63,222,204, +172,214, 65,225, 7,220,231,172,236, 29,153,237, 8,104, 64, 34,104, 64, 34, 32, 87,129, 56, 10, 64, 28, 6,108,217,188,209,158, +151,119,225,115,115,109,229, 87, 99,134, 9, 63,205,127,250,156, 79, 63,199,216,177, 99,157,142,183,109,219, 38,231,230,230, 94, + 48,155,205,135, 76, 38,211,185,206,248,144, 30,241, 1, 54,110,220,136,215, 94,123, 13,159,125,246, 25,190,255,254,123,232,116, + 58,124,240,193, 7,237,125,173, 87,167, 70,236,117,252,249, 80, 48,109, 40,152,118, 44, 82,206,236,147,246,239,207, 62, 87, 80, + 80,126,165,170,170,138, 94, 79,245, 47, 0,128,201,100, 18, 50, 50,186,119,255,228,150,171,192, 78,158, 60,233,182,172,201,100, +226, 9, 33, 93, 54, 33, 60,193,191,147,191,175,240,239,165,252, 5, 0,198,226,226,226, 83,171, 86,173,226,237,118,123, 52, 99, + 76, 13,128,213, 71, 54, 88,179, 15,234,207, 55,254,223,242,154,187,235, 45,238,213,178, 44,147,101, 89,150, 36,169,164, 62,189, + 96,103, 67,160, 10,127,133,127,151,249, 55, 31,114,229,116, 58,221,114, 0,125,209,148,229, 76,102,140, 73,132, 16,153, 49, 38, + 19, 66,164,102,231,104,179,107, 13,231,101, 66,136, 84,191,184, 93,110,184, 70, 8,145, 41,165, 82,139, 99,185,193,110,166,148, + 74,178, 44, 75,140, 49,139,217,108,190,210, 85, 75, 94,225,175,240,239, 44,255,230, 10, 64, 2, 3, 3,163, 57,142, 83, 19, 66, +152, 74,165,130, 40,138,141, 90,214,160,133,205,143,235, 67,127, 12, 0, 28, 14,135,147, 6, 19, 66, 88,179, 79, 67, 89, 88, 44, + 22,167,123,112, 28,199, 8, 33,172,178,178,146,213, 87, 90, 87,215,210, 41,252, 21,254,157,230, 79,218, 57,238, 40,124,101, 6, +167,194, 95,225,223, 35,132,187, 5, 73, 73, 73, 2,128,217, 28,199,221,247,211, 79, 63, 45,238,109, 97, 7,133, 63,144,148,148, + 52, 90, 16,132, 71, 8, 33,221, 46, 75,140,177,112, 89,150,135, 51,198, 94, 78, 73, 73,217,231,137, 58, 16,186,169, 34,251, 1, + 40, 79, 73, 73,177,117,176,252,120,181, 90,189,132, 49,246, 43,157, 78,199,149,149,149, 9, 0, 22,123, 81, 16, 20,254, 93,231, +127, 67,100,100,228,147,115,230,204,241,235,206,103,202,206,206,198,169, 83,167, 16, 25, 25, 9,131,193,176, 59, 41, 41,105, 90, + 74, 74, 74,138,207, 40, 64, 82, 82, 82, 8,128,121, 90,173,246,215, 14,135, 99,188, 32, 8, 59,146,146,146,230,166,164,164, 48, + 55,229, 35, 57,142,123, 80,173, 86,255,159, 32, 8, 81,241,241,241,154, 73,147, 38, 9, 90,173, 22,111,190,249,166,205, 11, 66, +163,240,239, 38,254,209,209,209,246,133, 11, 23,118,155, 2,108,218,180, 9, 6,131, 1,143, 62,250, 40, 56,142,195,193,131, 7, +185,204,204,204, 3,137,137,137, 9,169,169,169, 25, 94, 83,128,164,164, 36, 53,128,217,126,126,126, 75,101, 89,158, 62,108,216, + 48, 41, 62, 62, 62,104,232,208,161, 88,179,102,205,173, 37, 37, 37,239, 2,120,166, 69,249,185, 90,173,246, 73, 73,146,226,227, +226,226,104,124,124,188,255,224,193,131, 27, 38,144,193,106,181,246,164,208, 40,252,189,200,191, 35,144, 36, 9,235,215,175,199, +210,165, 75, 17, 22, 22,134,218,218, 90, 36, 38, 38,130, 82,202,101,101,101,165,235,245,250,155,211,210,210,142,247,152, 2, 36, + 37, 37, 17, 0, 73, 26,141,230, 49, 74,233,188,190,125,251,202, 83,166, 76, 9,137,139,139,131,159, 95,147,210, 63,246,216, 99, + 1,239,189,247,222, 19,183,220,114, 75, 14,165,244,148, 70,163, 89, 74, 41,157, 31, 19, 19, 67, 19, 18, 18,130,227,226,226,160, + 82,169,188, 97, 30, 40,252,189,200,191,179, 48, 24, 12, 8, 14, 14,110,220,124, 68,171,213, 66,150,101,232,245,122, 72,146,196, +229,228,228,100,232,245,250,241,105,105,105, 89, 30, 85,128,122,231,102, 49,199,113,143, 6, 6, 6,170,227,227,227, 3, 38, 76, +152,192,135,132,132,184, 44,239,239,239,143, 37, 75,150,248,175, 94,189,250, 35,173, 86,235,152, 50,101,138,118,226,196,137,124, +104,104,104,183, 85,206,244,233,211,251,216,237,118,154,158,158, 94,209, 1,193, 81,248,123,145,127, 87, 81, 88, 88, 8,157,174, +105, 71, 34,141, 70, 3, 89,150, 33,203, 50, 18, 19, 19, 33,203, 50,127,225,194,133, 19, 9, 9, 9, 55,166,167,167,159,239, 86, + 5, 72, 74, 74,138,225, 56,238, 87,106,181,122, 9,199,113, 49,147, 38, 77, 18,110,186,233, 38,117,223,190,125, 59,116,179,136, +136, 8,172, 92,185, 82,237,239,239,175,238,206, 74, 73, 76, 76, 28, 17, 16, 16,176,210,110,183,223, 86, 93, 93, 29,219,134,208, + 40,252,189,200,191, 59, 16, 24, 24,216,202, 44,243,247,247,111,220,212, 59, 41, 41, 9,178, 44, 11,151, 46, 93,202,210,235,245, + 35,211,210,210,242,186, 69, 1,146,146,146, 18, 4, 65,216, 59,102,204, 24,122,243,205, 55,251,199,198,198,162, 43,145, 45,127, +127,255,110,171,140,169, 83,167, 78, 11, 8, 8,120,153, 82,154, 16, 16, 16,160,150,101,249,163,236,236,108,135, 27,225, 81,248, +123,145,127,119, 65,167,211,193,100,106, 61, 11,187,193, 20,146,101,185, 65, 9, 84, 5, 5, 5,103,245,122,253,176,180,180, 52, +195, 53, 43,128,159,159,223,107,208,238,250,153, 0, 0, 20,252, 73, 68, 65, 84,119,222,121,167, 58, 33, 33,129,131, 23, 49,125, +250,116, 65,150,229,251,252,253,253, 95,241,247,247,239,255,224,131, 15, 6, 76,159, 62,157, 44, 88,176,192,102,177, 88, 62,114, +247, 61,133,191,119,249,119, 23,162,162,162, 80, 83, 83, 3,171,213, 10,173, 86, 11,160,110, 99,194,210,210, 82,148,151,151,163, +180,180, 20, 22,139, 5,131, 7, 15,134, 40,138,234,171, 87,175,158,215,235,245, 67,210,210,210,138,187,172, 0, 73, 73, 73, 35, + 1, 36, 77,154, 52,201,107,149, 31, 31, 31, 31,172,209,104,150, 8,130,176, 98,232,208,161,154,135, 30,122, 40,104,202,148, 41, + 32,132, 96,247,238,221, 16, 4,225, 84,122,122,250, 69, 55,173,167,194,223,139,252,187, 19,106,181, 26,227,199,143, 71, 78, 78, + 14,116, 58, 29, 14, 28, 56,128,130,130, 2,196,198,198, 34, 42, 42, 10, 67,135, 14, 5,207,243, 72, 77, 77,133,209,104,132, 40, +138,126, 26,141, 38, 79,175,215, 15, 74, 75, 75, 43,237,146, 2,104, 52,154,151,166, 78,157,170,242, 70,148,160,186,186, 26, 28, +199,169, 2, 3, 3,139, 38, 79,158,140, 95,253,234, 87, 1, 55,220,112,131, 83,153,111,190,249,166,166,182,182,246,207,238,238, +161,240,119,195,205, 38,225,167,139,165, 40,169,113, 64, 45,112, 80,243, 4,106,158,131, 70,224, 48, 97, 64, 40,250, 6,251,117, + 11,255,238,198,180,105,211,240,233,167,159, 66, 20, 69, 60,254,248,227,152, 57,115, 38,212,106,103,183,102,209,162, 69, 48,153, + 76, 88,183,110, 29,182,108,217,162,165,148,190,137,166,245,192, 29, 87,128,164,164,164,104, 74,233,189,122,189, 94,232, 73,193, + 41, 44, 44, 68, 74, 74, 10,206,157, 59,135, 57,115,230,240, 11, 22, 44, 8,136,140,108,157, 53, 34, 63, 63, 31, 5, 5, 5,148, +231,249,111,221,180,158, 94,231, 63,243,206,159,241,139,127,249,128, 79,240,183, 75, 20,169,121,229,216,157, 83,130,140,252, 74, +136,110,146, 26, 19, 0, 3, 53,118,220,104,207,198, 67,119, 37,240,183,205,127, 34, 32, 50, 50,170,211,252, 61,129,132,132, 4, +124,253,245,215,120,227,141, 55, 16, 19,227, 62, 29,125, 72, 72, 8,158,124,242, 73,108,223,190,157,213,212,212,140, 13, 13, 13, +237, 95, 85, 85,117,165, 51, 74, 32,168,213,234,231,110,186,233, 38,174, 59,157, 39,119, 96,140, 33, 39, 39, 7,169,169,169,168, +172,172,196,125,247,221,135,215, 95,127,189, 77,199, 45, 57, 57,217,193, 24, 91,179,127,255,126,201, 77,151,233, 85,254,137,243, + 30,197,211,235,126,194, 61,178, 10,145, 94,228,207, 24,240,245,113, 3,214, 30, 42,128, 85,108,127, 93, 8, 3,144,111,215,224, +151,131,181,184, 91,216, 3,203,119,199, 96, 31, 57, 3,252,144,169, 16,162,199, 55, 46, 19,109,143,191, 39, 16, 20, 20,132, 53, +107,214,184, 93,126,218, 18, 67,134, 12,145, 12, 6,131,153,231,249,251, 81,151,152,184,227, 10,192,243,252,207, 39, 77,154,164, +241,228, 3, 73,146,132, 99,199,142, 33, 45, 45, 13, 1, 1, 1, 88,184,112, 33,166, 77,155,230, 50, 69,138, 83,107,102,183, 99, +231,206,157,212,106,181,254,205, 93, 25,111,242,207,200, 45,198, 93,171,190,129,213, 33,225,238,119,190,193,190, 87, 23, 34, 58, + 44,176,199,249,151,155, 29,120,251,199,115, 56, 90,208,249,156,252, 19, 2,235,190,227, 47, 85,193,145,181, 5,200,218, 2,226, + 23, 12, 97,144, 30,108,128, 30,251,246,180,205,223, 83,232,168,240,215, 7, 16, 24,165, 84, 98,140,105,208,201, 9,158, 2, 0, +194,113,158,241,189,204,102, 51,210,211,211,113,248,240, 97,140, 26, 53, 10, 43, 86,172,232,240,174,145, 0,176,111,223, 62, 8, +130,112, 36, 45, 45,173,173,156,228, 94,225,159,109, 40,195,188,119,183,194,234,168,107, 24, 11,202,170,113,239,159,147,177,243, +165,249, 8,214,106,122,140,191,201, 38,225,183,155, 51, 81, 80,209,249,100,180, 4,192,248,160,214, 89, 15,153,173, 26,226,185, + 29,192,185, 29,248,247,108,162, 82, 17,246, 23,242,192,148,100,104,196,239,195,151, 30,243,201, 76, 17,245,232,218,154,224,238, + 70,105,105, 41, 82, 83, 83,145,153,153,137,105,211,166,225,195, 15, 63,196,128,102, 27, 98,116, 20, 61,237,124,117,148,127, 65, + 89, 53,230,190,243, 13,170,204,206,115,200, 50,243, 75,176,240,253,109, 72,126,238, 94,168, 5,222,227,252,173,162,140,231,147, + 79,119, 73,248, 1, 32, 86, 91,139, 16,161,237,245, 35, 42,142,241, 0,230, 49, 96, 58,236,170,229,229, 31, 76,249, 74,144,201, +218,144,167,211,189,155, 5,152, 81,128, 52, 53, 28, 93,205,202,209,173, 10,144,151,151,135,148,148, 20, 20, 22, 22, 98,238,220, +185,120,238,185,231,208,213,161,248,220,220, 92, 92,189,122, 85,140,142,142,254,111, 79,213,105, 71,248,151,152, 44,152,179,106, + 19,174, 86,185,222,163,111, 95, 86, 62,150,124,178, 3, 47,222, 57,210,227,252,255,153,122, 25, 57,198,154,182, 91,121, 2,232, + 71,244, 71, 76, 88, 0,204, 54, 17,149,102, 59, 14, 95, 40, 2,101, 12, 19,130, 42,219,234,151,144,122,133,179,199,199,208, 39, + 52, 4, 7, 67,151,165,229,250, 66, 19, 79, 45,229,176,253,176, 18,204, 82, 6,245,228, 37, 80,141,184,163,177,245,175, 95, 74, +217,233,244,232,215,180, 26,135, 82,138,204,204, 76,164,166,166, 66,150,101, 60,240,192, 3,184,253,246,219, 91,133,173, 58,139, +173, 91,183,218, 41,165, 31,111,218,180,169, 61,173,238, 49,254, 53, 86, 7,238,249,211, 22,228, 22,183,157, 44,121, 99,122, 14, + 12,185, 57,178,218,131,252, 47,150,214, 34,249, 84,161,219,235,129,126,106,172,184, 39, 30, 11, 18, 71,161,127,120,144,211,181, +203, 37, 38,124,180,227, 56, 6, 95,106, 61,159,204, 6, 13,252, 96, 7, 24,197,153, 50, 97,227,220, 63,166,172,245, 37, 27,135, + 85, 23, 65,174,200,173,219,179,109,223,219, 16,179,147, 17,227, 7, 82,191, 32,158,118,197, 7,232, 18, 28, 14, 7, 14, 29, 58, +132,244,244,116,244,239,223, 31, 79, 60,241, 4,226,227,227,209, 29, 11,131,108, 54, 27,246,236,217,195,108, 54,219, 39,158,170, +200,206,242,183,139, 50, 22,188,247, 45, 78, 94, 54,118,232,254,233, 37,224, 53, 33,137, 20,216,227, 17,254,255, 72,201, 3,117, +163, 58,209, 97,129,216,242,236,189, 24, 55,216,117, 50,226,193,145, 33,120,247,161, 91, 81,242,229, 23, 78,155,156,214,112, 65, + 8,162, 77, 61,202,226, 56,199,224, 23,124,204,200,231,251,142,129,118,214, 27,176,238,124, 9,144, 69,200, 37,103,241,255, 6, + 16,149,223, 20,255,193,111,109, 39, 93,234, 1,186,132,109,219,182,129, 82,138, 85,171, 86, 97,248,240,225,221,250,144,123,246, +236,129, 32, 8,169,169,169,169, 69,158,170,200,206,240,167,140,225,145,143,183, 99,127,118, 65,167,126,195,206,107, 95,230,231, +175, 58, 39,111, 92,185,161, 59,185,151,155, 29,200,200,175,116,217,216, 13,208, 5, 97,247, 43, 11, 49, 64, 23,212,142,187, 40, + 66,107,174,123, 30, 17, 2,100,162,114, 18,126, 0, 80,243,152, 90,249,158,126,124,216,239,210, 78,250,146, 18, 8,131,244,208, +206,122, 3,182,157, 47,131,201, 14,240,132, 97,241, 36,191,113, 83, 6, 14,122, 88, 16,134,173,155,252,234,225,234,142,222,139, + 67, 23,246, 21, 48,155,205,200,204,204,196,202,149, 43,187, 93,248, 27,156, 95,179,217,220, 81,231,209,227,252,151,125,182, 27, + 91,143, 92,232,202,163, 16,194,176, 86,184,127,213,140,238,228,191, 35,171, 16,204, 77, 79,255,135,121,250,246,133, 31,128, 92, + 94,103, 70,128, 87, 33, 48,225, 9,248, 49,215, 11, 99, 40, 47,223,235,139,225, 30, 97,144, 30,126,179,255, 8,162,210, 54,158, + 27, 17,169,158, 52, 52,156, 28, 42,251, 48, 97,164, 71,123,128,163, 71,143, 34, 33, 33,161,205, 92,159, 93,197,185,115,231, 80, + 82, 82, 98, 59,120,240,224, 78, 79, 85, 94,103,248,191,254, 77, 42, 62,219,155,121, 45, 63,167, 6,144,172, 90,240,206, 45,226, +215, 47,156,234, 14,254,169,103, 93, 79,126, 28,216, 39, 24, 11,147, 70,119, 44, 94, 88,114, 6, 32, 28,180,183,191, 6, 97,112, + 18,196,236,100,208,106, 23, 62, 5, 35, 9, 61,102,223,215,150, 64, 42, 60, 6, 72,118, 48, 89, 4,100, 7, 24, 21, 65,168, 4, +230,176,130, 57,106,193, 28,181,128,104, 1,179,155,235,254,111,189, 51,234, 40,194,216,225,242, 15, 19,230,235,158, 74,255,177, +219, 21,128, 82,138,140,140, 12,188,252,242,203, 30,169,132,173, 91,183,218, 68, 81,252, 0, 30, 74,149,209, 25,254,127,251,241, + 56,222, 73, 62,212,120, 28,164, 85, 99, 70,220, 32,216, 68, 9, 63,158,188,228,186, 66, 9, 16,224,168, 56,100, 82,133,107, 0, + 76,168, 63, 29,204, 40,251,193,239,129, 85,122,219, 87, 43, 47, 95, 43,255,203,149, 86,128,104, 91, 93, 91,116,203,141, 80,241, + 29, 27, 83,160, 37,103,161,137, 95, 10, 97,112,221, 62,191,170,225, 51, 97, 63,246,133,139, 62, 12, 61,178,233,175,116, 97, 39, +172,123,223,118, 37,208, 93, 65, 48, 24,219, 94,241, 97,252,178,240,167, 14,255,173, 61, 19,168, 83, 56,127,254, 60,130,130,130, + 16, 23, 23,215,237,149, 96,177, 88,176,127,255,126, 56, 28,142,127,122,170,162, 59,202,255,235,180, 28, 60,183,110, 31,162,195, + 2,241,248,109,227,240,237,138,121, 48,124,242,127,216,240,219,185,109,239,129, 69, 37,140, 40, 73,253,185,180,105,229, 68, 9, +100, 16, 1,158, 2,176, 27, 64,164, 36, 99, 7,238,125, 91,119,173,252, 45,196,245,250,243,168,144,128,142,219,102,234, 0,168, +199, 63,208, 36, 8, 49, 19,221, 21, 13,233, 9, 5, 16,207,239,236, 46,225,111,244,151, 25, 35, 31,151,127,144,240, 62,123,213, +189,156, 11,157,221, 91,245,240,225,195,248,197, 47,126,225,145, 74,216,181,107, 23, 83,171,213,123,247,236,217,211,225, 13,176, + 61,193,127, 87,230,101,252,117, 91, 6,214, 44,189, 19, 11,244,163, 58,220,170, 2, 0, 3,145,210,210,210,234,248,111,122,161, + 64, 4, 62, 2,240,145,102,193,159,134, 74,178,252,172, 32,112,155,164,251,255, 58, 7,155,158,182,118,149,191,138,143,133, 67, +110,253,181,176, 64,103,197, 56,124,161, 8,195,163,195, 17,222,226, 60, 24,133,122,226,131,206, 78,180,228, 54, 49, 4,199, 54, +222,207,147,249,155, 60,154,249,218,111,198,139,144, 75,178, 1,209, 10, 38, 90,193, 28, 22,192, 81, 3,106, 53,129,150,157,131, + 92,226, 58,221, 63, 31, 58, 16,124,248, 96, 64,208,128, 89, 42, 32, 22,157,172,223,240,163, 65, 64,216,242,242,176, 41, 67, 75, + 62,246, 91, 24,249,155,253,181, 93, 54,129, 24, 99, 40, 47, 47, 71, 65, 65, 1,110,187,237, 54,143, 84,194,166, 77,155,204,213, +213,213,239,122,196,190,236, 32,127,179, 93,132,192, 17, 28,122,251, 33,116, 37,162, 75, 9,231,114, 79, 45,251,215,207,231, 2, +248, 53, 22,190, 21, 37,136,142, 9, 18,144,214, 85,254, 1,125, 71,194, 97,110,253, 51,205,103,126,214,218, 28,120,107, 75, 58, +190, 91, 49,207, 69,171,193,129,248, 59,119, 68,204,230, 54,112, 34,226,204, 38,143,103,110, 35,218, 80, 8,131, 90,111,200, 46, + 95,205,132, 53,111,127,171,243,170,126, 19,161,141,127, 28, 66,191,241,173,158,195,126,126, 39, 44, 41,171,235,156,124, 0,132, +224, 46, 94,182,165,148,175,142,191, 75,183,236,240,149, 78, 41, 0, 99,245, 59,142, 51,134,195,135, 15, 99,214,172, 89,208,104, +186,127,238,217,153, 51,103, 80, 85, 85, 85,147,154,154,186,175,187, 5,191, 51,252, 3, 52, 42,220, 26, 55,168,235,191, 7,210, +246,172,201, 13,127, 48, 74,128,241, 90,248, 27, 11,131, 81,105,110,189,246, 99,219,145, 11, 88,152, 56, 10,140, 1,203, 63,219, +141, 62, 65,218, 14,243, 46,185,120, 28,193,174, 47, 93, 32,175,194, 43,123, 6, 72, 23,247,192,186,239,237, 70, 65,110,236, 45, +110,122, 8,254, 9, 75, 27,167, 66,156, 59,127, 6,102,179, 25,186,112, 29, 6, 13,138,133,223,216,251, 32, 68,220,128,154,237, + 43,192,172,141,131,150,227, 0,238, 61, 0,247,119,216, 7,160,148, 54,174,195,180,217,108, 56,126,252, 56,238,185,231, 30,143, + 60,236,150, 45, 91,172,162, 40,190,215,221, 14,111, 79,241,247,148,195,238,138,255,228,225,209, 46,203,239,204,188, 12,139, 93, +196,239, 55, 28,192,134,212,179,152, 60, 44,186, 99, 74,230,176, 64,147,191,219, 77, 43, 79,206,244,248,131, 51, 10,251,225, 53, +176,238,126,189,149,240,171,135,205,128,191,254,215, 0,225,112, 56, 35, 29,241, 79,188,138,184, 23,191, 67,252,170, 61, 24,246, +220, 70,252,252,153, 55,112,241, 98, 14,132,232,177, 8,185,255, 95, 32,126,205,167,178,176,123,171, 62,156, 60,164,165, 2,180, +138, 67, 55,175,248,134, 79,102,102, 38,134, 13, 27,134,254,253,251,119,251,243,214,212,212, 32, 53, 53,149,216,108,182, 79,187, +214,200,123,151,255,181,119, 82,157,227, 63,101,120, 63,215, 65, 4,187,136,121,127,217,138, 15,182, 31, 5, 0, 76, 30, 22,211, + 33, 2,181,199,191,130,134,147,220, 24,124,108,103,143, 42,189,185, 12,150,109,203,225, 56,241,159,214,129, 64, 65, 3,255,233, +207, 2, 0,242,242,206,227,231,171,119,227,120,133,179,127,243, 95,131, 10,243,255,244, 21, 36, 81, 4, 23,210, 15,234, 33,122, + 39,151, 65,166,252,114,183, 61, 0, 99,172,177,194, 37, 73,130, 36, 73,141,199,199,143, 31,199,188,121,243, 60,242,208, 59,119, +238,132, 90,173,222,113,173,249,102,188,197,191, 59,205,181,142,240,159, 59,105, 24, 66,252, 93,155,113, 7,234, 71,171,181,106, + 1, 99, 6, 69,180,111,102,228,167, 65, 62,245, 31,119,151,109, 68, 35,110,236, 49,147,231,202, 49, 88,191,121, 12,114,145,235, +225, 18, 85,244, 88,112,218,186,177,155, 15,191,254, 14,229, 14,215, 75, 72, 79, 87,249,225,207,255,168, 11, 36,170, 6, 76,110, +209,161,177, 71, 13,127, 77,208, 58, 41, 64,131,157,217,178,213,105,120, 17, 6,131, 1, 22,139, 5, 9, 9,221, 59, 38, 66, 41, +197,158, 61,123,176,118,237, 90,212,214,214,190,123, 45,130,227, 13,254,221,237,167,116,148,127,144, 86,141, 71,110, 29,219,230, + 61,199,235, 36,168,218,153, 30,239,200,254, 22,150, 31, 86,130,103,110,167, 68,127,213, 35,243,255, 25,133,253,216, 90, 88,183, + 63, 3,106,117, 63, 67, 85,136,106, 26,228, 59,125,213,220,230, 45,243, 74,235,156,122, 97,192,205, 45, 47, 5,169,180, 36,168, +185, 19,204, 26, 42,186,193,217,106, 72, 66,212,240, 57,113,226, 4,238,185,231, 30,116,215,194, 19, 89,150,177,107,215, 46,124, +246,217,103,176, 88, 44,142,226,226,226, 45, 6,131, 33, 60, 56, 56,248,230,234,234,234, 35,157,173,190,158,230, 79,105,183,250, +132, 93,226,255,200,140, 49, 88,179,235, 68,227,130,156,150,152,192, 95,132,121,227, 98, 8, 35,102, 67,125,195, 29, 32,129,117, + 19,227,152,104,133,227,226, 62,148, 30,222,128, 16, 91,126, 91, 83, 39, 77, 50, 47,175,244,184,236,139, 86,216,118,189, 2,169, +224,144,115, 67,205,171,193,192,156,124, 0, 90,219, 20, 29, 31, 18,174,193,129, 54, 18,161,140,111,152, 8,232, 98,108,193,223, +108,111, 60, 41, 52,111,125, 26, 42,188,249, 75,176, 88, 44, 56,127,254, 60, 94,121,229,149,107,239,226, 36, 9, 63,252,240, 3, +214,174, 93, 11,155,205,102,191,122,245,234,214,162,162,162,100, 74,105, 49,207,243, 70, 89,150, 75,174,165,245,236, 41,254,255, + 90,191, 3, 16, 98,187,189,245,119,197,223, 84,107,198,169,220, 43,184,243, 87, 75,177,249,240,121, 28,207, 43, 70,218,185, 66, +156,184,100,132, 67,114,223,194,223, 20, 84, 9,106, 42,130, 35,227,159,112,100,252,179, 46, 98, 66, 56, 48, 42,131,128,181, 59, +186, 69, 8, 94,136,252,205,145, 98,143, 10,191,189, 22,214,255, 62, 7,217,152,237,252,219,193, 49,240,159,245, 38,236, 71,254, + 5, 41,191, 41, 90, 44,149,158,107,252,255,233, 7,238,194,127, 94,217, 6,145,181, 86,225, 80,149,132,217,183,212,141,112,203, +165,173,179, 39, 50, 78, 77,157,194,160, 45, 95, 64,243, 23,113,234,212, 41, 36, 36, 36,224, 90,114, 76, 58, 28, 14,124,255,253, +247, 88,183,110, 29, 28, 14,135,173,168,168, 40,185,168,168,232,123,142,227,140,140, 49,163, 36, 73,198,170,170,170,210,107,105, +145,123,146,255, 85, 41,226, 52,250,224,230,238,142,246,184,226,159,125,250, 52,134,198, 77,192, 15, 89,133,216,118,244, 34,174, + 86,214,118,232,158, 55, 5, 87,180, 50, 51,192,104,135, 38,203, 51,134,191,233,150, 29,250,196,147,194, 79,173,149,117, 38, 79, +153,115,170, 33, 97,144, 30,126, 51, 94, 4,209, 4, 66, 24,156,232,164, 0,114,121, 30,236,103,191,135,102,212, 93, 24, 53, 50, + 14,219,127, 99,196, 67,255, 76, 69,177,189,105,237,198,208, 0, 59, 62, 91, 58, 3,177,177,117,169, 93,172, 39,190,108,249,211, +162, 57,192, 97,115, 82,128, 6,123,179,229, 11,144,101, 25, 89, 89, 89,120,253,245,215,187,244,144,118,187, 29,223,126,251, 45, +214,175, 95, 15, 89,150,109,133,133,133,155,141, 70,227, 14,198,152, 17,128,145,231,121, 99,121,121,185,241, 90, 43,179,167,249, + 91,198,207,187, 25,232, 62, 5,104,139,127,118,214,105,188,254,250,235, 24, 61,122, 52,254,186,120, 6, 14,157, 47, 66,114,198, +121,108,205, 56,143,194, 10,215,202, 16,163,177, 34, 90,109,235, 98,143,132, 47,117,149,135,158,242,104,203,111,173,130,245,219, + 39, 65,171,154, 77,234,227, 4,104,110,126, 12,234, 9,191, 68,195, 8, 53, 63, 48,161,254,255,166,104,144, 53,245, 35,168, 98, + 38,128, 11,233,135, 91,111,153,137,203,137,211,177,231,192, 30, 20,149,150, 33, 38,162, 15,110,155, 62, 19, 28,199, 3,140,194, +146,178, 26,210,149, 99, 45,186, 54,124, 25,179,244,152,197,165, 15,208,210,254,204,203,203, 67,104,104, 40, 70,143, 30,221,169, + 7,180, 88, 44, 72, 78, 78,198,134, 13, 27, 64, 41,181, 22, 20, 20,108, 46, 47, 47,223,205, 24, 51, 82, 74,141,130, 32, 24,203, +202,202,140,232,194, 34,230,182,108,232,158,226, 79,253,195,251,121,194, 7,104,143, 63, 71, 8,244, 35,250, 65, 63,162, 31,254, +180,232, 86, 28,201,189,138,228,140,243, 72, 62,124, 30, 5,101,213, 78,230, 79, 23, 32,130,177,223,235,150, 29,254, 11, 33,158, +221,179, 75, 46, 60,234, 36,252, 92,200, 0,248,221,246, 50,248,136, 17, 78,229,184,128, 62,224,251,222, 8,185, 56,171, 89,207, + 97,130,233,171,135, 17,112,219, 31,160, 30, 58, 29, 60,207, 99,214,140, 89,173, 76,171,218, 29, 47, 66, 44, 56,220,170,174,193, +216,159,156,122,156,230,161,183,150, 54,232,153, 51,103, 58, 21, 58,172,173,173,197,230,205,155,177,113,227, 70, 80, 74, 45, 6, +131,225,155,178,178,178,253,140, 49, 35,207,243, 70,198,152,177,170,170,202,136,174,239, 68,216,102,232,176,167,248,171,180, 33, +241,221, 37, 34, 93,229, 79, 8, 48,121, 88, 52, 38, 15,139,198,170, 95, 78,195,241, 60, 35, 54,238,203, 64,114,250,105,140, 15, +236,148, 2, 72,140, 97, 7,227,232,107, 17,203, 50,142, 98,185,231,163, 94,252,160, 68,240,125,199, 64, 46, 57, 11,213,136,217, +208,232,159,116,154,215,223, 28,154,164,223,194,178,229, 9,128, 54, 57,251,204, 81,139,218,255,174,132,122,232,116, 8, 81,163, +193,135, 15, 1, 9,208, 65,174,184, 12,185,236, 2, 28,185, 7, 64,171, 91,175,165, 98,192,247,125,150, 29,118, 26,216,115,235, + 3,152, 76, 38, 20, 23, 23, 99,198,140, 25,237, 62, 80,117,117, 53,190,254,250,107, 36, 39, 39,131, 82,106,190,114,229,202,230, +178,178,178,131,140, 49, 99,189,157, 95, 28, 26, 26,106,188,120,241,162,221, 35,246,164,194, 31,199,246,124,135,204,228,100, 12, +161,212,188, 35,219,184,189,223, 56,106,191,101,120,224, 68,157, 63, 63, 26,196,133,233, 79,112,152, 49,178, 94,237,112,124, 21, +252,236,177,178,158, 12,251, 18,149, 22,254,247,124,220,184, 32,167, 77,101,233,115, 3,212,147, 30,169,115,228, 91,250,102,185, +251,225,200,221,223,193, 31, 37,121, 2,228, 86,234,237,214, 7,200,206,206,198,157,119,222,217,230,188,153,170,170, 42,124,249, +229,151, 13,203, 11,107, 13, 6,195,230,170,170,170,180, 6, 27,159, 82,106,212,106,181,198,162,162, 34, 75,101,101,165,199, 42, + 84,225,223,154,255,243,151,152, 81,150,139,140,235, 31, 25, 64, 18, 6, 5,106,136, 74,230,136,172, 34, 96, 50, 7,162,170, 10, + 95,150, 82, 0,111,131,239, 88, 46, 84,205,132, 95, 1,142, 90, 56, 78,118,121,101,233, 41,153,147,238,212,185,136,106, 53, 42, + 64,115, 27, 84, 20, 69,156, 63,127, 30,207, 60,243,140,203,187,149,151,151, 99,253,250,245,216,177, 99, 7,100, 89,174,169,175, +248,140, 6,161, 81,169, 84,197,140, 49, 99, 69, 69, 69,173,171, 92,239,158, 16, 32,133,191,107,254,119,191,239,203,121,172, 58, +218,101,112,208, 76,249, 53,248, 62, 55,192,182,255,143, 96, 82,167, 28,252, 20,162, 17,239,138,116, 51,160,215,202, 4, 98,140, +225,226,197,139, 24, 49, 98, 4,250,245,115,246,245, 74, 74, 74,240,197, 23, 95, 96,247,238,221,144, 36,169,218, 96, 48,108,169, +174,174, 62,202, 24, 51, 54,216,201, 0,140, 37, 37, 37, 61, 90,235, 10,127,239,242,239, 41, 8,195,102,194,191,223, 68,136,103, +190,131,120,230, 91, 48,179, 91,203,205, 0, 32,153, 3,217, 18,218,183,127, 74, 91,107, 25, 4,198, 24,107,217, 5, 95,184,112, + 1, 79, 61,213, 20, 9, 43, 42, 42,194,231,159,127,142, 3, 7, 14, 64,146, 36, 83,126,126,254,150,218,218,218,147, 13, 81, 17, +158,231,141,146, 36, 25, 43, 43, 43,123, 60, 91,152, 87,248,203,220, 81,240,244, 53,215,132,136,205,231,249,247, 98,112,218, 48, +104,110, 90, 12,205,132, 69,117,249,129, 28, 22,124,182,230, 67, 27, 45, 57,179,121, 76, 31,122,118,100,140,176,179,239,242, 35, + 29,158, 77, 32, 16, 66,242,171,171,171, 71,134,133,133,129, 82,138,210,210, 82,136,162,136, 41, 83,166,192, 96, 48,224,223,255, +254, 55,210,210,210, 32,138, 98,229,229,203,151,183,154,205,230,204, 6,231, 16,128, 81,150,101, 99, 85, 85, 85,153,183, 42,196, + 27,252,197,205, 43,142, 2, 56,218, 91,249,255,111,104, 2, 15,190, 79,221, 96,215, 57,115,152,188,255,136,120,188,160,160, 96, + 91, 85, 85, 85,167, 54,241, 16,236,118,123,106, 73, 73,201,204,254,253,251, 11,148, 82, 92,188,120, 17, 19, 38, 76,192,203, 47, +191,140, 35, 71,142,192,110,183, 87, 24, 12,134,111,107,107,107,179, 8, 33, 37,168, 91,204, 97,228,121,222, 88, 82, 82, 98,244, +118, 61, 40,252,189, 15,147,201, 36,100,100,100,120,243,247,121, 66, 8,149,101,185,243,185, 65, 25, 99, 25,121,121,121,246, 33, + 67,134, 8,118,187, 29,121,121,121,200,207,207,135,205,102,107,168,248,179,205, 91,155,102,131, 88,212, 23, 42, 95,225,239,117, + 24,139,139,139, 79,173, 90,181,138,183,219,237,209,140, 49, 53, 0, 86,159, 97,143, 53,251,160,254, 60,107, 10,203, 59, 95,115, +119,189,197,189, 90,150,101,178, 44,203,146, 36,149,212,167, 71,236,212, 8, 13, 1,128,105,211,166, 61, 79, 41,125, 11,128,236, +112, 56,106,138,138,138,182,213,214,214,158,227, 56,174,193,198, 44, 97,140, 21,215, 79, 91,144,224, 99, 80,248,251,134, 81,162, +211,233,150, 3,232, 91,175,156, 50,234, 18,214, 74,132, 16,153, 49, 38, 19, 66,164,102,231,104,179,107, 13,231,101, 66,136, 84, +159,228, 86,110,184, 70, 8,145, 41,165, 82,139, 99,185, 33, 35, 52,165, 84,146,101, 89, 98,140, 89,204,102,243,149, 78, 43, 64, + 61, 84,225,225,225, 81,140,177, 48,142,227,180, 0,136, 44,203,118,142,227,202,195,195,195, 75, 60, 53, 8,212,141, 80,248,123, + 57, 88, 25, 24, 24, 24,205,113,156,154, 16,194, 84, 42, 21, 68, 81,108,108,165, 27, 90,241,230,199,132, 16,218,208,226, 59, 28, + 14,167, 30,128, 16,194,154,125, 26,202,194, 98,177, 56,221,131,227, 56, 70, 8, 97,149,149,149,172, 94,233,196,174, 42,128, 2, + 5,215,172, 4, 93,181, 4,189, 69,248,255, 3,212, 21,184,121, 66,226, 69,162, 0, 0, 0, 0, 73, 69, 78, 68,174, 66, 96,130, +}; + diff --git a/source/blender/src/resources.c b/source/blender/src/resources.c index 65f44027aee..526cbfab292 100644 --- a/source/blender/src/resources.c +++ b/source/blender/src/resources.c @@ -486,8 +486,16 @@ void BIF_InitTheme(void) /* space imageselect */ btheme->timasel= btheme->tv3d; + SETCOL(btheme->timasel.active, 195, 195, 195, 255); /* active tile */ + SETCOL(btheme->timasel.grid, 94, 94, 94, 255); /* active file text */ SETCOL(btheme->timasel.back, 110, 110, 110, 255); - SETCOL(btheme->timasel.shade1, 0xaa, 0xaa, 0xba, 255); + SETCOL(btheme->timasel.header, 195, 195, 195, 255); + SETCOL(btheme->timasel.shade1, 94, 94, 94, 255); /* bar */ + SETCOL(btheme->timasel.shade2, 172, 172, 172, 255); /* sliders */ + SETCOL(btheme->timasel.hilite, 17, 27, 60, 100); /* selected tile */ + SETCOL(btheme->timasel.text, 0, 0, 0, 255); + SETCOL(btheme->timasel.text_hi, 255, 255, 255, 255); + SETCOL(btheme->timasel.panel, 132, 132, 132, 255); /* space text */ btheme->text= btheme->tv3d; @@ -658,7 +666,12 @@ char *BIF_ThemeColorsPup(int spacetype) str += sprintf(str, "Panel %%x%d|", TH_PANEL); break; case SPACE_IMASEL: - str += sprintf(str, "Main Shade %%x%d|", TH_SHADE1); + str += sprintf(str, "Tiles %%x%d|", TH_PANEL); + str += sprintf(str, "Scrollbar %%x%d|", TH_SHADE1); + str += sprintf(str, "Scroll Handle %%x%d|", TH_SHADE2); + str += sprintf(str, "Selected File %%x%d|", TH_HILITE); + str += sprintf(str, "Active File %%x%d|", TH_ACTIVE); + str += sprintf(str, "Active File Text%%x%d|", TH_GRID); break; case SPACE_TEXT: str += sprintf(str, "Scroll Bar %%x%d|", TH_SHADE1); diff --git a/source/blender/src/space.c b/source/blender/src/space.c index e69ed9bf70f..0ec3538abc1 100644 --- a/source/blender/src/space.c +++ b/source/blender/src/space.c @@ -110,6 +110,7 @@ #include "BIF_editsima.h" #include "BIF_editsound.h" #include "BIF_editview.h" +#include "BIF_filelist.h" #include "BIF_gl.h" #include "BIF_imasel.h" #include "BIF_interface.h" @@ -3673,6 +3674,11 @@ void drawinfospace(ScrArea *sa, void *spacedata) (xpos+edgsp+(2*mpref)+(3*midsp)),y3,(mpref),buth, &U.recent_files, 0, 30, 0, 0, "Maximum number of recently opened files to remember"); + + uiDefButBitI(block, TOG, USER_SAVE_PREVIEWS, 0, "Save Preview Images", + (xpos+edgsp+(3*mpref)+(4*midsp)),y3,mpref,buth, + &(U.flag), 0, 0, 0, 0, + "Enables automatic saving of preview images in the .blend file"); } else if (U.userpref == 4) { /* system & opengl */ @@ -4657,39 +4663,6 @@ static void init_filespace(ScrArea *sa) sfile->spacetype= SPACE_FILE; } -static void init_imaselspace(ScrArea *sa) -{ - SpaceImaSel *simasel; - - simasel= MEM_callocN(sizeof(SpaceImaSel), "initimaselspace"); - BLI_addhead(&sa->spacedata, simasel); - - simasel->spacetype= SPACE_IMASEL; - simasel->blockscale= 0.7; - simasel->mode = 7; - strcpy (simasel->dir, U.textudir); /* TON */ - strcpy (simasel->file, ""); - strcpy(simasel->fole, simasel->file); - strcpy(simasel->dor, simasel->dir); - - simasel->first_sel_ima = 0; - simasel->hilite_ima = 0; - simasel->firstdir = 0; - simasel->firstfile = 0; - simasel->cmap = 0; - simasel->returnfunc = NULL; - - simasel->title[0] = 0; - - clear_ima_dir(simasel); - - /* simasel->cmap= IMB_loadiffmem((int*)datatoc_cmap_tga, IB_rect|IB_cmap); */ - simasel->cmap= IMB_ibImageFromMemory((int *)datatoc_cmap_tga, datatoc_cmap_tga_size, IB_rect|IB_cmap); - if (!simasel->cmap) { - error("in console"); - printf("Image select cmap file not found \n"); - } -} /* ******************** SPACE: SOUND ********************** */ @@ -5009,9 +4982,61 @@ static void init_imagespace(ScrArea *sa) extern void drawimaselspace(ScrArea *sa, void *spacedata); extern void winqreadimaselspace(struct ScrArea *sa, void *spacedata, struct BWinEvent *evt); +static void changeimaselspace(ScrArea *sa, void *spacedata) +{ + if(G.v2d==0) return; -/* everything to imasel.c */ + test_view2d(G.v2d, curarea->winx, curarea->winy); + myortho2(G.v2d->cur.xmin, G.v2d->cur.xmax, G.v2d->cur.ymin, G.v2d->cur.ymax); +} +static void init_imaselspace(ScrArea *sa) +{ + SpaceImaSel *simasel; + + simasel= MEM_callocN(sizeof(SpaceImaSel), "init imaselspace"); + BLI_addhead(&sa->spacedata, simasel); + + simasel->spacetype= SPACE_IMASEL; + 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; + simasel->type = FILE_UNIX; + simasel->files = BIF_filelist_new(); +} /* ******************** SPACE: OOPS ********************** */ @@ -5496,11 +5521,7 @@ void newspace(ScrArea *sa, int type) scrarea_queue_headredraw(sa); addqueue(sa->win, CHANGED, 1); - scrarea_queue_winredraw(sa); - - areawinset(sa->win); - - bwin_clear_viewmat(sa->win); + scrarea_queue_winredraw(sa); for (sl= sa->spacedata.first; sl; sl= sl->next) if(sl->spacetype==type) @@ -5546,6 +5567,9 @@ void newspace(ScrArea *sa, int type) sl= sa->spacedata.first; sl->area= sa; } + + areawinset(sa->win); + bwin_clear_viewmat(sa->win); } } @@ -5567,6 +5591,17 @@ void newspace(ScrArea *sa, int type) /* exception: imasel space */ else if(sa->spacetype==SPACE_IMASEL) { SpaceImaSel *simasel= sa->spacedata.first; + if(simasel->type==FILE_MAIN) { + if (simasel->files) { + BIF_filelist_free(simasel->files); + BIF_filelist_settype(simasel->files, FILE_MAIN); + } + } else { + if (simasel->files) { + simasel->type= FILE_UNIX; + BIF_filelist_settype(simasel->files, simasel->type); + } + } simasel->returnfunc= NULL; simasel->title[0]= 0; } @@ -5634,7 +5669,8 @@ void freespacelist(ScrArea *sa) free_oopspace(so); } else if(sl->spacetype==SPACE_IMASEL) { - free_imasel((SpaceImaSel *)sl); + SpaceImaSel *simasel= (SpaceImaSel*) sl; + free_imasel(simasel); } else if(sl->spacetype==SPACE_ACTION) { free_actionspace((SpaceAction*)sl); @@ -5701,11 +5737,13 @@ void duplicatespacelist(ScrArea *newarea, ListBase *lb1, ListBase *lb2) so->treestore= NULL; } else if(sl->spacetype==SPACE_IMASEL) { - check_imasel_copy((SpaceImaSel *) sl); - } - else if(sl->spacetype==SPACE_IMAGE) { - SpaceImage *sima= (SpaceImage *)sl; - sima->spare= NULL; + SpaceImaSel *simasel= (SpaceImaSel*) sl; + simasel->pupmenu= NULL; + simasel->menup= NULL; + simasel->files = BIF_filelist_new(); + BIF_filelist_setdir(simasel->files, simasel->dir); + BIF_filelist_settype(simasel->files, simasel->type); + /* see SPACE_FILE - elubie */ } else if(sl->spacetype==SPACE_NODE) { SpaceNode *snode= (SpaceNode *)sl; @@ -6177,7 +6215,7 @@ SpaceType *spaceimasel_get_type(void) if (!st) { st= spacetype_new("Imasel"); - spacetype_set_winfuncs(st, drawimaselspace, NULL, winqreadimaselspace); + spacetype_set_winfuncs(st, drawimaselspace, changeimaselspace, winqreadimaselspace); } return st; diff --git a/source/blender/src/toets.c b/source/blender/src/toets.c index 626aec10a2e..6cbc732b847 100644 --- a/source/blender/src/toets.c +++ b/source/blender/src/toets.c @@ -73,6 +73,7 @@ #include "BIF_editseq.h" #include "BIF_editsound.h" #include "BIF_editmesh.h" +#include "BIF_imasel.h" #include "BIF_interface.h" #include "BKE_object.h" #include "BIF_poseobject.h" @@ -466,6 +467,10 @@ int blenderqread(unsigned short event, short val) activate_fileselect(FILE_LOADLIB, "Load Library", G.lib, 0); return 0; } + else if(G.qual==LR_CTRLKEY) { + activate_imageselect(FILE_LOADLIB, "Load Library", G.lib, 0); + return 0; + } break; case F2KEY: if(G.qual==0) { @@ -506,6 +511,15 @@ int blenderqread(unsigned short event, short val) activate_fileselect(FILE_MAIN, "Data Select", str, NULL); return 0; } + else if(G.qual==LR_CTRLKEY) { + + memset(str, 0, 16); + ob= OBACT; + if(ob) strcpy(str, ob->id.name); + + activate_imageselect(FILE_MAIN, "Data Select", str, 0); + return 0; + } else if(G.qual==0) { extern_set_butspace(event, 1); } diff --git a/source/blender/src/usiblender.c b/source/blender/src/usiblender.c index 10fcfeb45aa..38e54d7e456 100644 --- a/source/blender/src/usiblender.c +++ b/source/blender/src/usiblender.c @@ -100,6 +100,7 @@ #include "BIF_editmesh.h" #include "BIF_editmode_undo.h" #include "BIF_editsound.h" +#include "BIF_filelist.h" #include "BIF_poseobject.h" #include "BIF_previewrender.h" #include "BIF_renderwin.h" @@ -626,19 +627,19 @@ static void readBlog(void) tmps[2]='\\'; tmps[3]=0; - fsmenu_insert_entry(tmps, 0); + fsmenu_insert_entry(tmps, 0, 0); } } /* Adding Desktop and My Documents */ - fsmenu_append_seperator(); + fsmenu_append_separator(); SHGetSpecialFolderPath(0, folder, CSIDL_PERSONAL, 0); - fsmenu_insert_entry(folder, 0); + fsmenu_insert_entry(folder, 0, 0); SHGetSpecialFolderPath(0, folder, CSIDL_DESKTOPDIRECTORY, 0); - fsmenu_insert_entry(folder, 0); + fsmenu_insert_entry(folder, 0, 0); - fsmenu_append_seperator(); + fsmenu_append_separator(); } #endif @@ -649,16 +650,16 @@ static void readBlog(void) char *line= l->link; if (!BLI_streq(line, "")) { - fsmenu_insert_entry(line, 0); + fsmenu_insert_entry(line, 0, 1); } } - fsmenu_append_seperator(); + fsmenu_append_separator(); /* add last saved file */ BLI_split_dirfile(G.sce, name, filename); /* G.sce shouldn't be relative */ - fsmenu_insert_entry(name, 0); + fsmenu_insert_entry(name, 0, 0); BLI_free_file_lines(lines); } @@ -884,6 +885,8 @@ void BIF_init(void) BIF_resources_init(); /* after homefile, to dynamically load an icon file based on theme settings */ + BIF_filelist_init_icons(); + init_gl_stuff(); /* drawview.c, after homefile */ readBlog(); BLI_strncpy(G.lib, G.sce, FILE_MAX); @@ -965,7 +968,9 @@ void exit_usiblender(void) if (!G.background) { BIF_resources_free(); - + + BIF_filelist_free_icons(); + BIF_close_render_display(); mainwindow_close(); } -- cgit v1.2.3