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