~diresu/blender/blender-command-port

« back to all changes in this revision

Viewing changes to source/blender/blenkernel/intern/icons.c

  • Committer: theeth
  • Date: 2008-10-14 16:52:04 UTC
  • Revision ID: vcs-imports@canonical.com-20081014165204-r32w2gm6s0osvdhn
copy back trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
* $Id: icons.c 16148 2008-08-17 17:11:00Z genscher $
 
3
*
 
4
* ***** BEGIN GPL LICENSE BLOCK *****
 
5
*
 
6
* This program is free software; you can redistribute it and/or
 
7
* modify it under the terms of the GNU General Public License
 
8
* as published by the Free Software Foundation; either version 2
 
9
* of the License, or (at your option) any later version. 
 
10
*
 
11
* This program is distributed in the hope that it will be useful,
 
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
* GNU General Public License for more details.
 
15
 
16
* You should have received a copy of the GNU General Public License
 
17
* along with this program; if not, write to the Free Software Foundation,
 
18
* Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
19
 
20
* The Original Code is Copyright (C) 2006-2007 Blender Foundation.
 
21
* All rights reserved.
 
22
 
23
* The Original Code is: all of this file.
 
24
 
25
* Contributor(s): none yet.
 
26
 
27
* ***** END GPL LICENSE BLOCK *****
 
28
*
 
29
*/
 
30
 
 
31
#include <math.h>
 
32
#include <stdlib.h>
 
33
#include <string.h>
 
34
 
 
35
#ifdef HAVE_CONFIG_H
 
36
#include <config.h>
 
37
#endif
 
38
 
 
39
#include "MEM_guardedalloc.h"
 
40
 
 
41
#include "DNA_ID.h"
 
42
#include "DNA_image_types.h"
 
43
#include "DNA_lamp_types.h"
 
44
#include "DNA_material_types.h"
 
45
#include "DNA_texture_types.h"
 
46
#include "DNA_world_types.h"
 
47
 
 
48
#include "BLI_ghash.h"
 
49
 
 
50
#include "BKE_icons.h"
 
51
#include "BKE_utildefines.h"
 
52
 
 
53
#include "BLO_sys_types.h" // for intptr_t support
 
54
 
 
55
#define GS(a)   (*((short *)(a)))
 
56
 
 
57
/* GLOBALS */
 
58
 
 
59
static GHash* gIcons = NULL;
 
60
 
 
61
static int gNextIconId = 1;
 
62
 
 
63
static int gFirstIconId = 1;
 
64
 
 
65
 
 
66
static void icon_free(void *val)
 
67
{
 
68
        Icon* icon = val;
 
69
 
 
70
        if (icon)
 
71
        {
 
72
                if (icon->drawinfo_free) {              
 
73
                        icon->drawinfo_free(icon->drawinfo);
 
74
                }
 
75
                else if (icon->drawinfo) {
 
76
                        MEM_freeN(icon->drawinfo);
 
77
                }
 
78
                MEM_freeN(icon);
 
79
        }
 
80
}
 
81
 
 
82
/* create an id for a new icon and make sure that ids from deleted icons get reused
 
83
   after the integer number range is used up */
 
84
static int get_next_free_id()
 
85
{
 
86
        int startId = gFirstIconId;
 
87
 
 
88
        /* if we haven't used up the int number range, we just return the next int */
 
89
        if (gNextIconId>=gFirstIconId)
 
90
                return gNextIconId++;
 
91
        
 
92
        /* now we try to find the smallest icon id not stored in the gIcons hash */
 
93
        while (BLI_ghash_lookup(gIcons, SET_INT_IN_POINTER(startId)) && startId>=gFirstIconId) 
 
94
                startId++;
 
95
 
 
96
        /* if we found a suitable one that isnt used yet, return it */
 
97
        if (startId>=gFirstIconId)
 
98
                return startId;
 
99
 
 
100
        /* fail */
 
101
        return 0;
 
102
}
 
103
 
 
104
void BKE_icons_init(int first_dyn_id)
 
105
{
 
106
        gNextIconId = first_dyn_id;
 
107
        gFirstIconId = first_dyn_id;
 
108
 
 
109
        if (!gIcons)
 
110
                gIcons = BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp);
 
111
}
 
112
 
 
113
void BKE_icons_free()
 
114
{
 
115
        if(gIcons)
 
116
                BLI_ghash_free(gIcons, 0, icon_free);
 
117
        gIcons = NULL;
 
118
}
 
119
 
 
120
struct PreviewImage* BKE_previewimg_create() 
 
121
{
 
122
        PreviewImage* prv_img = NULL;
 
123
        int i;
 
124
 
 
125
        prv_img = MEM_callocN(sizeof(PreviewImage), "img_prv");
 
126
 
 
127
        for (i=0; i<PREVIEW_MIPMAPS; ++i) {
 
128
                prv_img->changed[i] = 1;
 
129
        }
 
130
        return prv_img;
 
131
}
 
132
 
 
133
void BKE_previewimg_free(PreviewImage **prv)
 
134
{
 
135
        if(prv && (*prv)) {
 
136
                int i;
 
137
                
 
138
                for (i=0; i<PREVIEW_MIPMAPS;++i) {
 
139
                        if ((*prv)->rect[i]) {
 
140
                                MEM_freeN((*prv)->rect[i]);
 
141
                                (*prv)->rect[i] = NULL;
 
142
                        }
 
143
                }
 
144
                MEM_freeN((*prv));
 
145
                *prv = NULL;
 
146
        }
 
147
}
 
148
 
 
149
struct PreviewImage* BKE_previewimg_copy(PreviewImage *prv) 
 
150
{
 
151
        PreviewImage* prv_img = NULL;
 
152
        int i;
 
153
 
 
154
        if (prv) {
 
155
                prv_img = MEM_dupallocN(prv);
 
156
                for (i=0; i < PREVIEW_MIPMAPS; ++i) {
 
157
                        if (prv->rect[i]) {
 
158
                                prv_img->rect[i] = MEM_dupallocN(prv->rect[i]);
 
159
                        } else {
 
160
                                prv_img->rect[i] = NULL;
 
161
                        }
 
162
                }
 
163
        }
 
164
        return prv_img;
 
165
}
 
166
 
 
167
void BKE_previewimg_free_id(ID *id) 
 
168
{
 
169
        if (GS(id->name) == ID_MA) {
 
170
                Material *mat = (Material*)id;  
 
171
                BKE_previewimg_free(&mat->preview);
 
172
        } else if (GS(id->name) == ID_TE) {
 
173
                Tex *tex = (Tex*)id;
 
174
                BKE_previewimg_free(&tex->preview);
 
175
        } else if (GS(id->name) == ID_WO) {
 
176
                World *wo = (World*)id;
 
177
                BKE_previewimg_free(&wo->preview);
 
178
        } else if (GS(id->name) == ID_LA) {
 
179
                Lamp *la  = (Lamp*)id;
 
180
                BKE_previewimg_free(&la->preview);
 
181
        } else if (GS(id->name) == ID_IM) {
 
182
                Image *img  = (Image*)id;
 
183
                BKE_previewimg_free(&img->preview);
 
184
        }
 
185
}
 
186
 
 
187
PreviewImage* BKE_previewimg_get(ID *id) 
 
188
{
 
189
        PreviewImage* prv_img = NULL;
 
190
 
 
191
        if (GS(id->name) == ID_MA) {
 
192
                Material *mat = (Material*)id;  
 
193
                if (!mat->preview) mat->preview = BKE_previewimg_create();
 
194
                prv_img = mat->preview;
 
195
        } else if (GS(id->name) == ID_TE) {
 
196
                Tex *tex = (Tex*)id;
 
197
                if (!tex->preview) tex->preview = BKE_previewimg_create();
 
198
                prv_img = tex->preview;
 
199
        } else if (GS(id->name) == ID_WO) {
 
200
                World *wo = (World*)id;
 
201
                if (!wo->preview) wo->preview = BKE_previewimg_create();
 
202
                prv_img = wo->preview;
 
203
        } else if (GS(id->name) == ID_LA) {
 
204
                Lamp *la  = (Lamp*)id;
 
205
                if (!la->preview) la->preview = BKE_previewimg_create();
 
206
                prv_img = la->preview;
 
207
        } else if (GS(id->name) == ID_IM) {
 
208
                Image *img  = (Image*)id;
 
209
                if (!img->preview) img->preview = BKE_previewimg_create();
 
210
                prv_img = img->preview;
 
211
        } 
 
212
 
 
213
        return prv_img;
 
214
}
 
215
 
 
216
void BKE_icon_changed(int id)
 
217
{
 
218
        Icon* icon = 0;
 
219
        
 
220
        if (!id) return;
 
221
 
 
222
        icon = BLI_ghash_lookup(gIcons, SET_INT_IN_POINTER(id));
 
223
        
 
224
        if (icon)
 
225
        {
 
226
                PreviewImage *prv = BKE_previewimg_get((ID*)icon->obj);
 
227
 
 
228
                /* all previews changed */
 
229
                if (prv) {
 
230
                        int i;
 
231
                        for (i=0; i<PREVIEW_MIPMAPS; ++i) {
 
232
                                prv->changed[i] = 1;
 
233
                        }
 
234
                }
 
235
        }       
 
236
}
 
237
 
 
238
int BKE_icon_getid(struct ID* id)
 
239
{
 
240
        Icon* new_icon = 0;
 
241
 
 
242
        if (!id)
 
243
                return 0;
 
244
 
 
245
        if (id->icon_id)
 
246
                return id->icon_id;
 
247
 
 
248
        id->icon_id = get_next_free_id();
 
249
 
 
250
        if (!id->icon_id){
 
251
                printf("BKE_icon_getid: Internal error - not enough IDs\n");
 
252
                return 0;
 
253
        }
 
254
 
 
255
        new_icon = MEM_callocN(sizeof(Icon), "texicon");
 
256
 
 
257
        new_icon->obj = id;
 
258
        new_icon->type = GS(id->name);
 
259
        
 
260
        /* next two lines make sure image gets created */
 
261
        new_icon->drawinfo = 0;
 
262
        new_icon->drawinfo_free = 0;
 
263
 
 
264
        BLI_ghash_insert(gIcons, SET_INT_IN_POINTER(id->icon_id), new_icon);
 
265
        
 
266
        return id->icon_id;
 
267
}
 
268
 
 
269
Icon* BKE_icon_get(int icon_id)
 
270
{
 
271
        Icon* icon = 0;
 
272
 
 
273
        icon = BLI_ghash_lookup(gIcons, SET_INT_IN_POINTER(icon_id));
 
274
        
 
275
        if (!icon) {
 
276
                printf("BKE_icon_get: Internal error, no icon for icon ID: %d\n", icon_id);
 
277
                return 0;
 
278
        }
 
279
 
 
280
        return icon;
 
281
}
 
282
 
 
283
void BKE_icon_set(int icon_id, struct Icon* icon)
 
284
{
 
285
        Icon* old_icon = 0;
 
286
 
 
287
        old_icon = BLI_ghash_lookup(gIcons, SET_INT_IN_POINTER(icon_id));
 
288
 
 
289
        if (old_icon)
 
290
        {
 
291
                printf("BKE_icon_set: Internal error, icon already set: %d\n", icon_id);
 
292
                return;
 
293
        }
 
294
 
 
295
        BLI_ghash_insert(gIcons, SET_INT_IN_POINTER(icon_id), icon);
 
296
}
 
297
 
 
298
void BKE_icon_delete(struct ID* id)
 
299
{
 
300
 
 
301
        if (!id->icon_id) return; /* no icon defined for library object */
 
302
 
 
303
        BLI_ghash_remove(gIcons, SET_INT_IN_POINTER(id->icon_id), 0, icon_free);
 
304
        id->icon_id = 0;
 
305
}