Blender V2.61 - r43446

icons.c

Go to the documentation of this file.
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 }