Blender V2.61 - r43446
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2006-2007 Blender Foundation. 00019 * All rights reserved. 00020 * 00021 * The Original Code is: all of this file. 00022 * 00023 * Contributor(s): none yet. 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 * 00027 */ 00028 00034 #include <math.h> 00035 #include <stdlib.h> 00036 #include <string.h> 00037 00038 #include "MEM_guardedalloc.h" 00039 00040 #include "DNA_lamp_types.h" 00041 #include "DNA_material_types.h" 00042 #include "DNA_texture_types.h" 00043 #include "DNA_world_types.h" 00044 #include "DNA_brush_types.h" 00045 00046 #include "BLI_utildefines.h" 00047 #include "BLI_ghash.h" 00048 00049 #include "BKE_icons.h" 00050 #include "BKE_global.h" /* only for G.background test */ 00051 00052 #include "BLO_sys_types.h" // for intptr_t support 00053 00054 #define GS(a) (*((short *)(a))) 00055 00056 /* GLOBALS */ 00057 00058 static GHash* gIcons = NULL; 00059 00060 static int gNextIconId = 1; 00061 00062 static int gFirstIconId = 1; 00063 00064 00065 static void icon_free(void *val) 00066 { 00067 Icon* icon = val; 00068 00069 if (icon) 00070 { 00071 if (icon->drawinfo_free) { 00072 icon->drawinfo_free(icon->drawinfo); 00073 } 00074 else if (icon->drawinfo) { 00075 MEM_freeN(icon->drawinfo); 00076 } 00077 MEM_freeN(icon); 00078 } 00079 } 00080 00081 /* create an id for a new icon and make sure that ids from deleted icons get reused 00082 after the integer number range is used up */ 00083 static int get_next_free_id(void) 00084 { 00085 int startId = gFirstIconId; 00086 00087 /* if we haven't used up the int number range, we just return the next int */ 00088 if (gNextIconId>=gFirstIconId) 00089 return gNextIconId++; 00090 00091 /* now we try to find the smallest icon id not stored in the gIcons hash */ 00092 while (BLI_ghash_lookup(gIcons, SET_INT_IN_POINTER(startId)) && startId>=gFirstIconId) 00093 startId++; 00094 00095 /* if we found a suitable one that isnt used yet, return it */ 00096 if (startId>=gFirstIconId) 00097 return startId; 00098 00099 /* fail */ 00100 return 0; 00101 } 00102 00103 void BKE_icons_init(int first_dyn_id) 00104 { 00105 gNextIconId = first_dyn_id; 00106 gFirstIconId = first_dyn_id; 00107 00108 if (!gIcons) 00109 gIcons = BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "icons_init gh"); 00110 } 00111 00112 void BKE_icons_free(void) 00113 { 00114 if(gIcons) 00115 BLI_ghash_free(gIcons, NULL, icon_free); 00116 gIcons = NULL; 00117 } 00118 00119 struct PreviewImage* BKE_previewimg_create(void) 00120 { 00121 PreviewImage* prv_img = NULL; 00122 int i; 00123 00124 prv_img = MEM_callocN(sizeof(PreviewImage), "img_prv"); 00125 00126 for (i=0; i<NUM_ICON_SIZES; ++i) { 00127 prv_img->changed[i] = 1; 00128 prv_img->changed_timestamp[i] = 0; 00129 } 00130 return prv_img; 00131 } 00132 00133 void BKE_previewimg_freefunc(void *link) 00134 { 00135 PreviewImage *prv = (PreviewImage *)link; 00136 if (prv) { 00137 int i; 00138 00139 for (i=0; i<NUM_ICON_SIZES;++i) { 00140 if (prv->rect[i]) { 00141 MEM_freeN(prv->rect[i]); 00142 prv->rect[i] = NULL; 00143 } 00144 } 00145 MEM_freeN(prv); 00146 } 00147 } 00148 00149 void BKE_previewimg_free(PreviewImage **prv) 00150 { 00151 if(prv && (*prv)) { 00152 BKE_previewimg_freefunc(*prv); 00153 *prv = NULL; 00154 } 00155 } 00156 00157 struct PreviewImage* BKE_previewimg_copy(PreviewImage *prv) 00158 { 00159 PreviewImage* prv_img = NULL; 00160 int i; 00161 00162 if (prv) { 00163 prv_img = MEM_dupallocN(prv); 00164 for (i=0; i < NUM_ICON_SIZES; ++i) { 00165 if (prv->rect[i]) { 00166 prv_img->rect[i] = MEM_dupallocN(prv->rect[i]); 00167 } else { 00168 prv_img->rect[i] = NULL; 00169 } 00170 } 00171 } 00172 return prv_img; 00173 } 00174 00175 void BKE_previewimg_free_id(ID *id) 00176 { 00177 if (GS(id->name) == ID_MA) { 00178 Material *mat = (Material*)id; 00179 BKE_previewimg_free(&mat->preview); 00180 } else if (GS(id->name) == ID_TE) { 00181 Tex *tex = (Tex*)id; 00182 BKE_previewimg_free(&tex->preview); 00183 } else if (GS(id->name) == ID_WO) { 00184 World *wo = (World*)id; 00185 BKE_previewimg_free(&wo->preview); 00186 } else if (GS(id->name) == ID_LA) { 00187 Lamp *la = (Lamp*)id; 00188 BKE_previewimg_free(&la->preview); 00189 } else if (GS(id->name) == ID_IM) { 00190 Image *img = (Image*)id; 00191 BKE_previewimg_free(&img->preview); 00192 } else if (GS(id->name) == ID_BR) { 00193 Brush *br = (Brush*)id; 00194 BKE_previewimg_free(&br->preview); 00195 } 00196 } 00197 00198 PreviewImage* BKE_previewimg_get(ID *id) 00199 { 00200 PreviewImage* prv_img = NULL; 00201 00202 if (GS(id->name) == ID_MA) { 00203 Material *mat = (Material*)id; 00204 if (!mat->preview) mat->preview = BKE_previewimg_create(); 00205 prv_img = mat->preview; 00206 } else if (GS(id->name) == ID_TE) { 00207 Tex *tex = (Tex*)id; 00208 if (!tex->preview) tex->preview = BKE_previewimg_create(); 00209 prv_img = tex->preview; 00210 } else if (GS(id->name) == ID_WO) { 00211 World *wo = (World*)id; 00212 if (!wo->preview) wo->preview = BKE_previewimg_create(); 00213 prv_img = wo->preview; 00214 } else if (GS(id->name) == ID_LA) { 00215 Lamp *la = (Lamp*)id; 00216 if (!la->preview) la->preview = BKE_previewimg_create(); 00217 prv_img = la->preview; 00218 } else if (GS(id->name) == ID_IM) { 00219 Image *img = (Image*)id; 00220 if (!img->preview) img->preview = BKE_previewimg_create(); 00221 prv_img = img->preview; 00222 } else if (GS(id->name) == ID_BR) { 00223 Brush *br = (Brush*)id; 00224 if (!br->preview) br->preview = BKE_previewimg_create(); 00225 prv_img = br->preview; 00226 } 00227 00228 return prv_img; 00229 } 00230 00231 void BKE_icon_changed(int id) 00232 { 00233 Icon* icon = NULL; 00234 00235 if (!id || G.background) return; 00236 00237 icon = BLI_ghash_lookup(gIcons, SET_INT_IN_POINTER(id)); 00238 00239 if (icon) 00240 { 00241 PreviewImage *prv = BKE_previewimg_get((ID*)icon->obj); 00242 00243 /* all previews changed */ 00244 if (prv) { 00245 int i; 00246 for (i=0; i<NUM_ICON_SIZES; ++i) { 00247 prv->changed[i] = 1; 00248 prv->changed_timestamp[i]++; 00249 } 00250 } 00251 } 00252 } 00253 00254 int BKE_icon_getid(struct ID* id) 00255 { 00256 Icon* new_icon = NULL; 00257 00258 if (!id || G.background) 00259 return 0; 00260 00261 if (id->icon_id) 00262 return id->icon_id; 00263 00264 id->icon_id = get_next_free_id(); 00265 00266 if (!id->icon_id){ 00267 printf("BKE_icon_getid: Internal error - not enough IDs\n"); 00268 return 0; 00269 } 00270 00271 new_icon = MEM_callocN(sizeof(Icon), "texicon"); 00272 00273 new_icon->obj = id; 00274 new_icon->type = GS(id->name); 00275 00276 /* next two lines make sure image gets created */ 00277 new_icon->drawinfo = NULL; 00278 new_icon->drawinfo_free = NULL; 00279 00280 BLI_ghash_insert(gIcons, SET_INT_IN_POINTER(id->icon_id), new_icon); 00281 00282 return id->icon_id; 00283 } 00284 00285 Icon* BKE_icon_get(int icon_id) 00286 { 00287 Icon* icon = NULL; 00288 00289 icon = BLI_ghash_lookup(gIcons, SET_INT_IN_POINTER(icon_id)); 00290 00291 if (!icon) { 00292 printf("BKE_icon_get: Internal error, no icon for icon ID: %d\n", icon_id); 00293 return NULL; 00294 } 00295 00296 return icon; 00297 } 00298 00299 void BKE_icon_set(int icon_id, struct Icon* icon) 00300 { 00301 Icon* old_icon = NULL; 00302 00303 old_icon = BLI_ghash_lookup(gIcons, SET_INT_IN_POINTER(icon_id)); 00304 00305 if (old_icon) 00306 { 00307 printf("BKE_icon_set: Internal error, icon already set: %d\n", icon_id); 00308 return; 00309 } 00310 00311 BLI_ghash_insert(gIcons, SET_INT_IN_POINTER(icon_id), icon); 00312 } 00313 00314 void BKE_icon_delete(struct ID* id) 00315 { 00316 00317 if (!id->icon_id) return; /* no icon defined for library object */ 00318 00319 BLI_ghash_remove(gIcons, SET_INT_IN_POINTER(id->icon_id), NULL, icon_free); 00320 id->icon_id = 0; 00321 }