Patch by Matt Ebb: upgraded usablitiy of text button.
[blender.git] / source / blender / src / resources.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL 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. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 #include <math.h>
34 #include <stdlib.h>
35 #include <string.h>
36
37 #ifdef HAVE_CONFIG_H
38 #include <config.h>
39 #endif
40
41 #include "MEM_guardedalloc.h"
42
43 #include "DNA_listBase.h"
44 #include "DNA_userdef_types.h"
45 #include "DNA_screen_types.h"
46 #include "DNA_space_types.h"
47
48 #include "IMB_imbuf.h"
49 #include "IMB_imbuf_types.h"
50
51 #include "BKE_utildefines.h"
52
53 #include "BIF_gl.h"
54 #include "BIF_resources.h"
55
56 #include "BLI_blenlib.h"
57 #include "blendef.h"    // CLAMP
58 #include "datatoc.h"
59
60 /* global for themes */
61 typedef void (*VectorDrawFunc)(int x, int y, int w, int h, float alpha);
62
63 static bTheme *theme_active=NULL;
64 static int theme_spacetype= SPACE_VIEW3D;
65
66 typedef struct {
67                 /* If drawFunc is defined then it is a vector icon, otherwise use data */
68         VectorDrawFunc drawFunc;
69
70         int w, h;
71
72                 /* Data for image icons */
73         unsigned char *data;
74         float uv[4][2];
75         GLuint texid;
76 } Icon;
77
78 static Icon *icon_new_vector(VectorDrawFunc drawFunc, int w, int h)
79 {
80         Icon *icon= MEM_callocN(sizeof(*icon), "internicon");
81         icon->drawFunc = drawFunc;
82         icon->w = w;
83         icon->h = h;
84
85         return icon;
86 }
87
88 static Icon *icon_from_data(unsigned char *rect, GLuint texid, int xofs, int yofs, int w, int h, int rowstride)
89 {
90         Icon *icon= MEM_mallocN(sizeof(*icon), "internicon");
91         int y;
92
93         icon->drawFunc = NULL;
94         icon->texid= texid;
95         icon->uv[0][0]= ((float)xofs)/512.0;
96         icon->uv[0][1]= ((float)yofs)/256.0;
97         icon->uv[1][0]= icon->uv[0][0] + ((float)w)/512.0;
98         icon->uv[1][1]= icon->uv[0][1];
99         icon->uv[2][0]= icon->uv[0][0] + ((float)w)/512.0;
100         icon->uv[2][1]= icon->uv[0][1] + ((float)w)/256.0;
101         icon->uv[3][0]= icon->uv[0][0];
102         icon->uv[3][1]= icon->uv[0][1] + ((float)w)/256.0;
103         
104         icon->w= w;
105         icon->h= h;
106         
107         icon->data= MEM_mallocN(w*h*4, "icon->data");
108         for (y=0; y<h; y++)
109                 memcpy(&icon->data[y*w*4], &rect[y*rowstride], w*4);
110
111         return icon;
112 }
113
114 #if 0
115 static float icon_x=0.0, icon_y=0.0;
116 void BIF_icon_pos(float xs, float ys)
117 {
118         icon_x= xs; icon_y= ys;
119 }
120
121 static GLuint init_icon_texture(ImBuf *bbuf)
122 {
123         GLuint texid;
124
125         glGenTextures(1, &texid);
126         glBindTexture(GL_TEXTURE_2D, texid);
127
128         glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bbuf->x, bbuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, bbuf->rect);
129
130         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
131         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
132         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
133
134         return texid;
135 }
136
137 /* texture version for drawpixels */
138 static void icon_draw_tex(Icon *icon)
139 {
140         glBindTexture(GL_TEXTURE_2D, icon->texid);
141
142         /* drawing it */
143         glColor3ub(255, 255, 255);
144         glEnable(GL_TEXTURE_2D);
145         glBegin(GL_QUADS);
146         
147         glTexCoord2fv(icon->uv[0]);
148         glVertex2f(icon_x, icon_y);
149         glTexCoord2fv(icon->uv[1]);
150         glVertex2f(icon_x+icon->w, icon_y);
151         glTexCoord2fv(icon->uv[2]);
152         glVertex2f(icon_x+icon->w, icon_y+icon->h);
153         glTexCoord2fv(icon->uv[3]);
154         glVertex2f(icon_x, icon_y+icon->h);
155
156         glEnd();
157         glDisable(GL_TEXTURE_2D);
158 }
159 #endif
160
161
162 static void icon_draw(float x, float y, Icon *icon)
163 {
164         if (icon->drawFunc) {
165                 icon->drawFunc(x, y, icon->w, icon->h, 1.0);
166         } else {
167                 glRasterPos2f(x, y);
168                 glDrawPixels(icon->w, icon->h, GL_RGBA, GL_UNSIGNED_BYTE, icon->data);
169         }
170 }
171
172
173 static void icon_draw_blended(float x, float y, Icon *icon, char *blendcol, int shade)
174 {
175         if (icon->drawFunc) {
176                 icon->drawFunc(x, y, icon->w, icon->h, shade<0?((128+shade)/128.0):1.0);
177         } else {
178                 if(shade < 0) {
179                         float r= (128+shade)/128.0;
180                         glPixelTransferf(GL_ALPHA_SCALE, r);
181                 }
182                 glRasterPos2f(x, y);
183                 glDrawPixels(icon->w, icon->h, GL_RGBA, GL_UNSIGNED_BYTE, icon->data);
184                 glPixelTransferf(GL_ALPHA_SCALE, 1.0);
185         }
186 }
187
188
189 static void icon_free(Icon *icon)
190 {
191         if (icon->data) MEM_freeN(icon->data);
192         MEM_freeN(icon);
193 }
194
195
196 static Icon **common_icons_arr= NULL;
197
198 static Icon *get_icon(BIFIconID icon)
199 {
200         int iconidx= icon-BIFICONID_FIRST;
201         if (iconidx>=0 && iconidx<BIFNICONIDS) {
202                 return common_icons_arr[iconidx];
203         } else {
204                 return common_icons_arr[ICON_ERROR-BIFICONID_FIRST];
205         }
206 }
207 static void free_common_icons(void)
208 {
209         int i;
210
211         for (i=0; i<BIFNICONIDS; i++) {
212                 icon_free(common_icons_arr[i+BIFICONID_FIRST]);
213         }
214 }
215
216 void BIF_draw_icon(float x, float y, BIFIconID icon)
217 {
218         icon_draw(x, y, get_icon(icon));
219 }
220
221 void BIF_draw_icon_blended(float x, float y, BIFIconID icon, int colorid, int shade)
222 {
223         char *cp= BIF_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
224         icon_draw_blended(x, y, get_icon(icon), cp, shade);
225         // icon_draw_tex(get_icon(icon));
226 }
227
228 int BIF_get_icon_width(BIFIconID icon)
229 {
230         return get_icon(icon)->w;
231 }
232
233 int BIF_get_icon_height(BIFIconID icon)
234 {
235         return get_icon(icon)->h;
236 }
237
238 static void def_icon(ImBuf *bbuf, GLuint texid, BIFIconID icon, int xidx, int yidx, int w, int h, int offsx, int offsy)
239 {
240         int iconidx= icon-BIFICONID_FIRST;
241         
242         if (iconidx>=0 && iconidx<BIFNICONIDS) {
243                 int rowstride= bbuf->x*4;
244                 unsigned char *start= ((unsigned char*) bbuf->rect) + (yidx*21 + 3 + offsy)*rowstride + (xidx*20 + 3 + offsx)*4;
245
246                 common_icons_arr[iconidx]= 
247                         icon_from_data(start, texid, (xidx*20 + 3 + offsx), (yidx*21 + 3 + offsy), w, h, rowstride);
248                 
249         } else {
250                 printf("def_icon: Internal error, bad icon ID: %d\n", icon);
251         }
252 }
253
254 static void def_vicon(BIFIconID icon, int w, int h, VectorDrawFunc drawFunc)
255 {
256         int iconidx= icon-BIFICONID_FIRST;
257         
258         if (iconidx>=0 && iconidx<BIFNICONIDS) {
259                 common_icons_arr[iconidx]= icon_new_vector(drawFunc, w, h);
260         } else {
261                 printf("def_icon: Internal error, bad icon ID: %d\n", icon);
262         }
263 }
264
265 /* this only works for the hardcoded buttons image, turning the grey AA pixels to alpha, and slight off-grey to half alpha */
266
267 static void clear_transp_rect_soft(unsigned char *transp, unsigned char *rect, int w, int h, int rowstride)
268 {
269         int x, y, val;
270         
271         for (y=1; y<h-1; y++) {
272                 unsigned char *row0= &rect[(y-1)*rowstride];
273                 unsigned char *row= &rect[y*rowstride];
274                 unsigned char *row1= &rect[(y+1)*rowstride];
275                 for (x=1; x<w-1; x++) {
276                         unsigned char *pxl0= &row0[x*4];
277                         unsigned char *pxl= &row[x*4];
278                         unsigned char *pxl1= &row1[x*4];
279                         
280                         if(pxl[3]!=0) {
281                                 val= (abs(pxl[0]-transp[0]) + abs(pxl[1]-transp[1]) + abs(pxl[2]-transp[2]))/3;
282                                 if(val<20) {
283                                         pxl[3]= 128;
284                                 }
285                                 else if(val<50) {
286                                         // one of pixels surrounding has alpha null?
287                                         if(pxl[3-4]==0 || pxl[3+4]==0 || pxl0[3]==0 || pxl1[3]==0) {
288                                 
289                                                 if(pxl[0]>val) pxl[0]-= val; else pxl[0]= 0;
290                                                 if(pxl[1]>val) pxl[1]-= val; else pxl[1]= 0;
291                                                 if(pxl[2]>val) pxl[2]-= val; else pxl[2]= 0;
292                                                 
293                                                 pxl[3]= 128;
294                                         }
295                                 }
296                         }
297                 }
298         }
299 }
300
301
302 static void clear_transp_rect(unsigned char *transp, unsigned char *rect, int w, int h, int rowstride)
303 {
304         int x,y;
305         for (y=0; y<h; y++) {
306                 unsigned char *row= &rect[y*rowstride];
307                 for (x=0; x<w; x++) {
308                         unsigned char *pxl= &row[x*4];
309                         if (*((unsigned int*) pxl)==*((unsigned int*) transp)) {
310                                 pxl[3]= 0;
311                         }
312                 }
313         }
314 }
315
316 /* Vector Icon Drawing Routines */
317
318         /* Utilities */
319
320 static void viconutil_set_point(GLint pt[2], int x, int y)
321 {
322         pt[0] = x;
323         pt[1] = y;
324 }
325
326 static void viconutil_draw_tri(GLint (*pts)[2])
327 {
328         glBegin(GL_TRIANGLES);
329         glVertex2iv(pts[0]);
330         glVertex2iv(pts[1]);
331         glVertex2iv(pts[2]);
332         glEnd();
333 }
334
335 #if 0
336 static void viconutil_draw_quad(GLint (*pts)[2])
337 {
338         glBegin(GL_QUADS);
339         glVertex2iv(pts[0]);
340         glVertex2iv(pts[1]);
341         glVertex2iv(pts[2]);
342         glVertex2iv(pts[3]);
343         glEnd();
344 }
345 #endif
346
347 static void viconutil_draw_lineloop(GLint (*pts)[2], int numPoints)
348 {
349         int i;
350
351         glBegin(GL_LINE_LOOP);
352         for (i=0; i<numPoints; i++) {
353                 glVertex2iv(pts[i]);
354         }
355         glEnd();
356 }
357
358 static void viconutil_draw_lineloop_smooth(GLint (*pts)[2], int numPoints)
359 {
360         glEnable(GL_LINE_SMOOTH);
361         viconutil_draw_lineloop(pts, numPoints);
362         glDisable(GL_LINE_SMOOTH);
363 }
364
365 static void viconutil_draw_points(GLint (*pts)[2], int numPoints, int pointSize)
366 {
367         int i;
368
369         glBegin(GL_QUADS);
370         for (i=0; i<numPoints; i++) {
371                 int x = pts[i][0], y = pts[i][1];
372
373                 glVertex2i(x-pointSize,y-pointSize);
374                 glVertex2i(x+pointSize,y-pointSize);
375                 glVertex2i(x+pointSize,y+pointSize);
376                 glVertex2i(x-pointSize,y+pointSize);
377         }
378         glEnd();
379 }
380
381         /* Drawing functions */
382
383 static void vicon_x_draw(int x, int y, int w, int h, float alpha)
384 {
385         x += 3;
386         y += 3;
387         w -= 6;
388         h -= 6;
389
390         glEnable( GL_LINE_SMOOTH );
391
392         glLineWidth(2.5);
393         
394         glColor4f(0.0, 0.0, 0.0, alpha);
395         glBegin(GL_LINES);
396         glVertex2i(x  ,y  );
397         glVertex2i(x+w,y+h);
398         glVertex2i(x+w,y  );
399         glVertex2i(x  ,y+h);
400         glEnd();
401
402         glLineWidth(1.0);
403         
404         glDisable( GL_LINE_SMOOTH );
405 }
406
407 static void vicon_view3d_draw(int x, int y, int w, int h, float alpha)
408 {
409         int cx = x + w/2;
410         int cy = y + h/2;
411         int d = MAX2(2, h/3);
412
413         glColor4f(0.5, 0.5, 0.5, alpha);
414         glBegin(GL_LINES);
415         glVertex2i(x  , cy-d);
416         glVertex2i(x+w, cy-d);
417         glVertex2i(x  , cy+d);
418         glVertex2i(x+w, cy+d);
419
420         glVertex2i(cx-d, y  );
421         glVertex2i(cx-d, y+h);
422         glVertex2i(cx+d, y  );
423         glVertex2i(cx+d, y+h);
424         glEnd();
425         
426         glColor4f(0.0, 0.0, 0.0, alpha);
427         glBegin(GL_LINES);
428         glVertex2i(x  , cy);
429         glVertex2i(x+w, cy);
430         glVertex2i(cx, y  );
431         glVertex2i(cx, y+h);
432         glEnd();
433 }
434
435 static void vicon_edit_draw(int x, int y, int w, int h, float alpha)
436 {
437         GLint pts[4][2];
438
439         viconutil_set_point(pts[0], x+3  , y+3  );
440         viconutil_set_point(pts[1], x+w-3, y+3  );
441         viconutil_set_point(pts[2], x+w-3, y+h-3);
442         viconutil_set_point(pts[3], x+3  , y+h-3);
443
444         glColor4f(0.0, 0.0, 0.0, alpha);
445         viconutil_draw_lineloop(pts, 4);
446
447         glColor3f(1, 1, 0.0);
448         viconutil_draw_points(pts, 4, 1);
449 }
450
451 static void vicon_editmode_hlt_draw(int x, int y, int w, int h, float alpha)
452 {
453         GLint pts[3][2];
454
455         viconutil_set_point(pts[0], x+w/2, y+h-2);
456         viconutil_set_point(pts[1], x+3, y+4);
457         viconutil_set_point(pts[2], x+w-3, y+4);
458
459         glColor4f(0.5, 0.5, 0.5, alpha);
460         viconutil_draw_tri(pts);
461
462         glColor4f(0.0, 0.0, 0.0, 1);
463         viconutil_draw_lineloop_smooth(pts, 3);
464
465         glColor3f(1, 1, 0.0);
466         viconutil_draw_points(pts, 3, 1);
467 }
468
469 static void vicon_editmode_dehlt_draw(int x, int y, int w, int h, float alpha)
470 {
471         GLint pts[3][2];
472
473         viconutil_set_point(pts[0], x+w/2, y+h-2);
474         viconutil_set_point(pts[1], x+3, y+4);
475         viconutil_set_point(pts[2], x+w-3, y+4);
476
477         glColor4f(0.0, 0.0, 0.0, 1);
478         viconutil_draw_lineloop_smooth(pts, 3);
479
480         glColor3f(.9, .9, .9);
481         viconutil_draw_points(pts, 3, 1);
482 }
483
484 static void vicon_disclosure_tri_right_draw(int x, int y, int w, int h, float alpha)
485 {
486         GLint pts[3][2];
487         int cx = x+w/2;
488         int cy = y+w/2;
489         int d = w/3, d2 = w/5;
490
491         viconutil_set_point(pts[0], cx-d2, cy+d);
492         viconutil_set_point(pts[1], cx-d2, cy-d);
493         viconutil_set_point(pts[2], cx+d2, cy);
494
495         glShadeModel(GL_SMOOTH);
496         glBegin(GL_TRIANGLES);
497         glColor4f(0.8, 0.8, 0.8, alpha);
498         glVertex2iv(pts[0]);
499         glVertex2iv(pts[1]);
500         glColor4f(0.3, 0.3, 0.3, alpha);
501         glVertex2iv(pts[2]);
502         glEnd();
503         glShadeModel(GL_FLAT);
504
505         glColor4f(0.0, 0.0, 0.0, 1);
506         viconutil_draw_lineloop_smooth(pts, 3);
507 }
508
509 static void vicon_disclosure_tri_down_draw(int x, int y, int w, int h, float alpha)
510 {
511         GLint pts[3][2];
512         int cx = x+w/2;
513         int cy = y+w/2;
514         int d = w/3, d2 = w/5;
515
516         viconutil_set_point(pts[0], cx+d, cy+d2);
517         viconutil_set_point(pts[1], cx-d, cy+d2);
518         viconutil_set_point(pts[2], cx, cy-d2);
519
520         glShadeModel(GL_SMOOTH);
521         glBegin(GL_TRIANGLES);
522         glColor4f(0.8, 0.8, 0.8, alpha);
523         glVertex2iv(pts[0]);
524         glVertex2iv(pts[1]);
525         glColor4f(0.3, 0.3, 0.3, alpha);
526         glVertex2iv(pts[2]);
527         glEnd();
528         glShadeModel(GL_FLAT);
529
530         glColor4f(0.0, 0.0, 0.0, 1);
531         viconutil_draw_lineloop_smooth(pts, 3);
532 }
533
534 static void vicon_move_up_draw(int x, int y, int w, int h, float alpha)
535 {
536         int d=-2;
537
538         glEnable(GL_LINE_SMOOTH);
539         glLineWidth(1);
540         glColor3f(0.0, 0.0, 0.0);
541
542         glBegin(GL_LINE_STRIP);
543         glVertex2i(x+w/2-d*2, y+h/2+d);
544         glVertex2i(x+w/2, y+h/2-d + 1);
545         glVertex2i(x+w/2+d*2, y+h/2+d);
546         glEnd();
547
548         glLineWidth(1.0);
549         glDisable(GL_LINE_SMOOTH);
550 }
551
552 static void vicon_move_down_draw(int x, int y, int w, int h, float alpha)
553 {
554         int d=2;
555
556         glEnable(GL_LINE_SMOOTH);
557         glLineWidth(1);
558         glColor3f(0.0, 0.0, 0.0);
559
560         glBegin(GL_LINE_STRIP);
561         glVertex2i(x+w/2-d*2, y+h/2+d);
562         glVertex2i(x+w/2, y+h/2-d - 1);
563         glVertex2i(x+w/2+d*2, y+h/2+d);
564         glEnd();
565
566         glLineWidth(1.0);
567         glDisable(GL_LINE_SMOOTH);
568 }
569
570 /***/
571
572 void BIF_resources_init(void)
573 {
574         ImBuf *bbuf= IMB_ibImageFromMemory((int *)datatoc_blenderbuttons, datatoc_blenderbuttons_size, IB_rect);
575         GLuint texid=0;
576         int x, y;
577
578         common_icons_arr= MEM_mallocN(sizeof(*common_icons_arr)*BIFNICONIDS, "common_icons");
579
580         /* hack! */
581         for (y=0; y<12; y++) {
582                 for (x=0; x<21; x++) {
583                         int rowstride= bbuf->x*4;
584                         unsigned char *start= ((unsigned char*) bbuf->rect) + (y*21 + 3)*rowstride + (x*20 + 3)*4;
585                         unsigned char transp[4];
586                         /* this sets backdrop of icon to zero alpha */
587                         transp[0]= start[0];
588                         transp[1]= start[1];
589                         transp[2]= start[2];
590                         transp[3]= start[3];
591                         clear_transp_rect(transp, start, 20, 21, rowstride);
592                         clear_transp_rect_soft(transp, start, 20, 21, rowstride);
593                                 
594                         /* this sets outside of icon to zero alpha */
595                         start= ((unsigned char*) bbuf->rect) + (y*21)*rowstride + (x*20)*4;
596                         QUATCOPY(transp, start);
597                         clear_transp_rect(transp, start, 20, 21, rowstride);
598                         
599                         
600                 }
601         } 
602
603         // disabled for now (ton)
604         // texid= init_icon_texture(bbuf);
605
606                 /* hack! */
607         for (y=0; y<12; y++) {
608                 for (x=0; x<21; x++) {
609                         if (x==11 && y==6) {
610                                 def_icon(bbuf, texid, ICON_BEVELBUT_HLT,                        x, y, 7, 13, 4, 2);
611                         } else if (x==12 && y==6) {
612                                 def_icon(bbuf, texid, ICON_BEVELBUT_DEHLT,                      x, y, 7, 13, 4, 2);
613                         } else {
614                                 def_icon(bbuf, texid, BIFICONID_FIRST + y*21 + x,       x, y, 15, 16, 0, 0);
615                         }
616                 }
617         }
618
619         def_vicon(VICON_VIEW3D, 16, 16, vicon_view3d_draw);
620         def_vicon(VICON_EDIT, 16, 16, vicon_edit_draw);
621         def_vicon(VICON_EDITMODE_DEHLT, 16, 16, vicon_editmode_dehlt_draw);
622         def_vicon(VICON_EDITMODE_HLT, 16, 16, vicon_editmode_hlt_draw);
623         def_vicon(VICON_DISCLOSURE_TRI_RIGHT, 16, 16, vicon_disclosure_tri_right_draw);
624         def_vicon(VICON_DISCLOSURE_TRI_DOWN, 16, 16, vicon_disclosure_tri_down_draw);
625         def_vicon(VICON_MOVE_UP, 16, 16, vicon_move_up_draw);
626         def_vicon(VICON_MOVE_DOWN, 16, 16, vicon_move_down_draw);
627         def_vicon(VICON_X, 16, 16, vicon_x_draw);
628
629         IMB_freeImBuf(bbuf);    
630 }
631
632 void BIF_resources_free(void)
633 {
634         free_common_icons();
635
636         MEM_freeN(common_icons_arr);
637         
638 }
639
640
641 /* ******************************************************** */
642 /*    THEMES */
643 /* ******************************************************** */
644
645 char *BIF_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colorid)
646 {
647         ThemeSpace *ts= NULL;
648         static char error[4]={240, 0, 240, 255};
649         static char alert[4]={240, 60, 60, 255};
650         static char headerdesel[4]={0,0,0,255};
651         static char custom[4]={0,0,0,255};
652         
653         char *cp= error;
654         
655         if(btheme) {
656         
657                 // first check for ui buttons theme
658                 if(colorid < TH_THEMEUI) {
659                 
660                         switch(colorid) {
661                         case TH_BUT_OUTLINE:
662                                 cp= btheme->tui.outline; break;
663                         case TH_BUT_NEUTRAL:
664                                 cp= btheme->tui.neutral; break;
665                         case TH_BUT_ACTION:
666                                 cp= btheme->tui.action; break;
667                         case TH_BUT_SETTING:
668                                 cp= btheme->tui.setting; break;
669                         case TH_BUT_SETTING1:
670                                 cp= btheme->tui.setting1; break;
671                         case TH_BUT_SETTING2:
672                                 cp= btheme->tui.setting2; break;
673                         case TH_BUT_NUM:
674                                 cp= btheme->tui.num; break;
675                         case TH_BUT_TEXTFIELD:
676                                 cp= btheme->tui.textfield; break;
677                         case TH_BUT_TEXTFIELD_HI:
678                                 cp= btheme->tui.textfield_hi; break;
679                         case TH_BUT_POPUP:
680                                 cp= btheme->tui.popup; break;
681                         case TH_BUT_TEXT:
682                                 cp= btheme->tui.text; break;
683                         case TH_BUT_TEXT_HI:
684                                 cp= btheme->tui.text_hi; break;
685                         case TH_MENU_BACK:
686                                 cp= btheme->tui.menu_back; break;
687                         case TH_MENU_ITEM:
688                                 cp= btheme->tui.menu_item; break;
689                         case TH_MENU_HILITE:
690                                 cp= btheme->tui.menu_hilite; break;
691                         case TH_MENU_TEXT:
692                                 cp= btheme->tui.menu_text; break;
693                         case TH_MENU_TEXT_HI:
694                                 cp= btheme->tui.menu_text_hi; break;
695                         
696                         case TH_BUT_DRAWTYPE:
697                                 cp= &btheme->tui.but_drawtype; break;
698                         
699                         case TH_REDALERT:
700                                 cp= alert; break;
701                         case TH_CUSTOM:
702                                 cp= custom; break;
703                         }
704                 }
705                 else {
706                 
707                         switch(spacetype) {
708                         case SPACE_BUTS:
709                                 ts= &btheme->tbuts;
710                                 break;
711                         case SPACE_VIEW3D:
712                                 ts= &btheme->tv3d;
713                                 break;
714                         case SPACE_IPO:
715                                 ts= &btheme->tipo;
716                                 break;
717                         case SPACE_FILE:
718                                 ts= &btheme->tfile;
719                                 break;
720                         case SPACE_NLA:
721                                 ts= &btheme->tnla;
722                                 break;
723                         case SPACE_ACTION:
724                                 ts= &btheme->tact;
725                                 break;
726                         case SPACE_SEQ:
727                                 ts= &btheme->tseq;
728                                 break;
729                         case SPACE_IMAGE:
730                                 ts= &btheme->tima;
731                                 break;
732                         case SPACE_IMASEL:
733                                 ts= &btheme->timasel;
734                                 break;
735                         case SPACE_TEXT:
736                                 ts= &btheme->text;
737                                 break;
738                         case SPACE_OOPS:
739                                 ts= &btheme->toops;
740                                 break;
741                         case SPACE_SOUND:
742                                 ts= &btheme->tsnd;
743                                 break;
744                         case SPACE_INFO:
745                                 ts= &btheme->tinfo;
746                                 break;
747                         case SPACE_TIME:
748                                 ts= &btheme->ttime;
749                                 break;
750                         default:
751                                 ts= &btheme->tv3d;
752                                 break;
753                         }
754                         
755                         switch(colorid) {
756                         case TH_BACK:
757                                 cp= ts->back; break;
758                         case TH_TEXT:
759                                 cp= ts->text; break;
760                         case TH_TEXT_HI:
761                                 cp= ts->text_hi; break;
762                         case TH_HEADER:
763                                 cp= ts->header; break;
764                         case TH_HEADERDESEL:
765                                 /* we calculate a dynamic builtin header deselect color, also for pulldowns... */
766                                 cp= ts->header; 
767                                 headerdesel[0]= cp[0]>10?cp[0]-10:0;
768                                 headerdesel[1]= cp[1]>10?cp[1]-10:0;
769                                 headerdesel[2]= cp[2]>10?cp[2]-10:0;
770                                 cp= headerdesel;
771                                 break;
772                         case TH_PANEL:
773                                 cp= ts->panel; break;
774                         case TH_SHADE1:
775                                 cp= ts->shade1; break;
776                         case TH_SHADE2:
777                                 cp= ts->shade2; break;
778                         case TH_HILITE:
779                                 cp= ts->hilite; break;
780                                 
781                         case TH_GRID:
782                                 cp= ts->grid; break;
783                         case TH_WIRE:
784                                 cp= ts->wire; break;
785                         case TH_LAMP:
786                                 cp= ts->lamp; break;
787                         case TH_SELECT:
788                                 cp= ts->select; break;
789                         case TH_ACTIVE:
790                                 cp= ts->active; break;
791                         case TH_TRANSFORM:
792                                 cp= ts->transform; break;
793                         case TH_VERTEX:
794                                 cp= ts->vertex; break;
795                         case TH_VERTEX_SELECT:
796                                 cp= ts->vertex_select; break;
797                         case TH_VERTEX_SIZE:
798                                 cp= &ts->vertex_size; break;
799                         case TH_EDGE:
800                                 cp= ts->edge; break;
801                         case TH_EDGE_SELECT:
802                                 cp= ts->edge_select; break;
803                         case TH_EDGE_SEAM:
804                                 cp= ts->edge_seam; break;
805                         case TH_EDGE_FACESEL:
806                                 cp= ts->edge_facesel; break;
807                         case TH_FACE:
808                                 cp= ts->face; break;
809                         case TH_FACE_SELECT:
810                                 cp= ts->face_select; break;
811                         case TH_FACE_DOT:
812                                 cp= ts->face_dot; break;
813                         case TH_FACEDOT_SIZE:
814                                 cp= &ts->facedot_size; break;
815                         case TH_NORMAL:
816                                 cp= ts->normal; break;
817                         case TH_BONE_SOLID:
818                                 cp= ts->bone_solid; break;
819                         case TH_BONE_POSE:
820                                 cp= ts->bone_pose; break;
821                         case TH_STRIP:
822                                 cp= ts->strip; break;
823                         case TH_STRIP_SELECT:
824                                 cp= ts->strip_select; break;
825                                 
826                         case TH_SYNTAX_B:
827                                 cp= ts->syntaxb; break;
828                         case TH_SYNTAX_V:
829                                 cp= ts->syntaxv; break;
830                         case TH_SYNTAX_C:
831                                 cp= ts->syntaxc; break;
832                         case TH_SYNTAX_L:
833                                 cp= ts->syntaxl; break;
834                         case TH_SYNTAX_N:
835                                 cp= ts->syntaxn; break;
836
837                         }
838
839                 }
840         }
841         
842         return cp;
843 }
844
845 #define SETCOL(col, r, g, b, a)  col[0]=r; col[1]=g; col[2]= b; col[3]= a;
846
847 /* initialize
848    Note: when you add new colors, created & saved themes need initialized
849    in usiblender.c, search for "versionfile"
850 */
851 void BIF_InitTheme(void)
852 {
853         bTheme *btheme= U.themes.first;
854         
855         /* we search for the theme with name Default */
856         for(btheme= U.themes.first; btheme; btheme= btheme->next) {
857                 if(strcmp("Default", btheme->name)==0) break;
858         }
859         
860         if(btheme==NULL) {
861                 btheme= MEM_callocN(sizeof(bTheme), "theme");
862                 BLI_addtail(&U.themes, btheme);
863                 strcpy(btheme->name, "Default");
864         }
865         
866         BIF_SetTheme(NULL);     // make sure the global used in this file is set
867
868         /* UI buttons (todo) */
869         SETCOL(btheme->tui.outline,     0xA0,0xA0,0xA0, 255);
870         SETCOL(btheme->tui.neutral,     0xA0,0xA0,0xA0, 255);
871         SETCOL(btheme->tui.action,              0xAD,0xA0,0x93, 255);
872         SETCOL(btheme->tui.setting,     0x8A,0x9E,0xA1, 255);
873         SETCOL(btheme->tui.setting1,    0xA1,0xA1,0xAE, 255);
874         SETCOL(btheme->tui.setting2,    0xA1,0x99,0xA7, 255);
875         SETCOL(btheme->tui.num,                 0x90,0x90,0x90, 255);
876         SETCOL(btheme->tui.textfield,   0x90,0x90,0x90, 255);
877         SETCOL(btheme->tui.textfield_hi,0xc6,0x77,0x77, 255);
878         SETCOL(btheme->tui.popup,               0xA0,0xA0,0xA0, 255);
879         
880         SETCOL(btheme->tui.text,                0,0,0, 255);
881         SETCOL(btheme->tui.text_hi,     255, 255, 255, 255);
882         
883         SETCOL(btheme->tui.menu_back,   0xD2,0xD2,0xD2, 255);
884         SETCOL(btheme->tui.menu_item,   0xDA,0xDA,0xDA, 255);
885         SETCOL(btheme->tui.menu_hilite, 0x7F,0x7F,0x7F, 255);
886         SETCOL(btheme->tui.menu_text,   0, 0, 0, 255);
887         SETCOL(btheme->tui.menu_text_hi, 255, 255, 255, 255);
888         btheme->tui.but_drawtype= 1;
889         
890         /* space view3d */
891         SETCOL(btheme->tv3d.back,       115, 115, 115, 255);
892         SETCOL(btheme->tv3d.text,       0, 0, 0, 255);
893         SETCOL(btheme->tv3d.text_hi, 255, 255, 255, 255);
894         SETCOL(btheme->tv3d.header, 195, 195, 195, 255);
895         SETCOL(btheme->tv3d.panel,      165, 165, 165, 127);
896         
897         SETCOL(btheme->tv3d.shade1,  160, 160, 160, 100);
898         SETCOL(btheme->tv3d.shade2,  0x7f, 0x70, 0x70, 100);
899
900         SETCOL(btheme->tv3d.grid,       92, 92, 92, 255);
901         SETCOL(btheme->tv3d.wire,       0x0, 0x0, 0x0, 255);
902         SETCOL(btheme->tv3d.lamp,       0, 0, 0, 40);
903         SETCOL(btheme->tv3d.select, 0xff, 0x88, 0xff, 255);
904         SETCOL(btheme->tv3d.active, 0xff, 0xbb, 0xff, 255);
905         SETCOL(btheme->tv3d.transform, 0xff, 0xff, 0xff, 255);
906         SETCOL(btheme->tv3d.vertex, 0xff, 0x70, 0xff, 255);
907         SETCOL(btheme->tv3d.vertex_select, 0xff, 0xff, 0x70, 255);
908         btheme->tv3d.vertex_size= 2;
909         SETCOL(btheme->tv3d.edge,       0x0, 0x0, 0x0, 255);
910         SETCOL(btheme->tv3d.edge_select, 0xb0, 0xb0, 0x30, 255);
911         SETCOL(btheme->tv3d.edge_seam, 230, 150, 50, 255);
912         SETCOL(btheme->tv3d.edge_facesel, 75, 75, 75, 255);
913         SETCOL(btheme->tv3d.face,       0, 50, 150, 30);
914         SETCOL(btheme->tv3d.face_select, 200, 100, 200, 60);
915         SETCOL(btheme->tv3d.normal, 0x22, 0xDD, 0xDD, 255);
916         SETCOL(btheme->tv3d.face_dot, 255, 138, 48, 255);
917         btheme->tv3d.facedot_size= 4;
918         
919         SETCOL(btheme->tv3d.bone_solid, 200, 200, 200, 255);
920         SETCOL(btheme->tv3d.bone_pose, 80, 200, 255, 80);               // alpha 80 is not meant editable, used for wire+action draw
921         
922         
923         /* space buttons */
924         /* to have something initialized */
925         btheme->tbuts= btheme->tv3d;
926
927         SETCOL(btheme->tbuts.back,      180, 180, 180, 255);
928         SETCOL(btheme->tbuts.header, 195, 195, 195, 255);
929         SETCOL(btheme->tbuts.panel,  255, 255, 255, 40);
930
931         /* space ipo */
932         /* to have something initialized */
933         btheme->tipo= btheme->tv3d;
934
935         SETCOL(btheme->tipo.grid,       94, 94, 94, 255);
936         SETCOL(btheme->tipo.back,       120, 120, 120, 255);
937         SETCOL(btheme->tipo.header, 195, 195, 195, 255);
938         SETCOL(btheme->tipo.panel,  255, 255, 255, 150);
939         SETCOL(btheme->tipo.shade1,  172, 172, 172, 100);
940         SETCOL(btheme->tipo.shade2,  0x70, 0x70, 0x70, 100);
941         SETCOL(btheme->tipo.vertex, 0xff, 0x70, 0xff, 255);
942         SETCOL(btheme->tipo.vertex_select, 0xff, 0xff, 0x70, 255);
943         SETCOL(btheme->tipo.hilite, 0x60, 0xc0, 0x40, 255); 
944
945         /* space file */
946         /* to have something initialized */
947         btheme->tfile= btheme->tv3d;
948         SETCOL(btheme->tfile.back,      128, 128, 128, 255);
949         SETCOL(btheme->tfile.text,      0, 0, 0, 255);
950         SETCOL(btheme->tfile.text_hi, 255, 255, 255, 255);
951         SETCOL(btheme->tfile.header, 182, 182, 182, 255);
952         SETCOL(btheme->tfile.hilite, 0xA0, 0xA0, 0xD0, 255); // selected files
953
954         
955         /* space action */
956         btheme->tact= btheme->tv3d;
957         SETCOL(btheme->tact.back,       116, 116, 116, 255);
958         SETCOL(btheme->tact.text,       0, 0, 0, 255);
959         SETCOL(btheme->tact.text_hi, 255, 255, 255, 255);
960         SETCOL(btheme->tact.header, 182, 182, 182, 255);
961         SETCOL(btheme->tact.grid,  94, 94, 94, 255);
962         SETCOL(btheme->tact.face,  166, 166, 166, 255); // RVK
963         SETCOL(btheme->tact.shade1,  172, 172, 172, 255);               // sliders
964         SETCOL(btheme->tact.shade2,  84, 44, 31, 100);  // bar
965         SETCOL(btheme->tact.hilite,  17, 27, 60, 100);  // bar
966
967         /* space nla */
968         btheme->tnla= btheme->tv3d;
969         SETCOL(btheme->tnla.back,       116, 116, 116, 255);
970         SETCOL(btheme->tnla.text,       0, 0, 0, 255);
971         SETCOL(btheme->tnla.text_hi, 255, 255, 255, 255);
972         SETCOL(btheme->tnla.header, 182, 182, 182, 255);
973         SETCOL(btheme->tnla.grid,  94, 94, 94, 255);    
974         SETCOL(btheme->tnla.shade1,  172, 172, 172, 255);               // sliders
975         SETCOL(btheme->tnla.shade2,  84, 44, 31, 100);  // bar
976         SETCOL(btheme->tnla.hilite,  17, 27, 60, 100);  // bar
977         SETCOL(btheme->tnla.strip_select,       0xff, 0xff, 0xaa, 255);
978         SETCOL(btheme->tnla.strip, 0xe4, 0x9c, 0xc6, 255);
979         
980         /* space seq */
981         btheme->tseq= btheme->tv3d;
982         SETCOL(btheme->tnla.back,       116, 116, 116, 255);
983
984         /* space image */
985         btheme->tima= btheme->tv3d;
986         SETCOL(btheme->tima.back,       53, 53, 53, 255);
987         SETCOL(btheme->tima.vertex, 0xff, 0x70, 0xff, 255);
988         SETCOL(btheme->tima.vertex_select, 0xff, 0xff, 0x70, 255);
989         btheme->tima.vertex_size= 2;
990         SETCOL(btheme->tima.face,   0, 50, 150, 40);
991         SETCOL(btheme->tima.face_select, 200, 100, 200, 80);
992
993         /* space imageselect */
994         btheme->timasel= btheme->tv3d;
995         SETCOL(btheme->timasel.back,    110, 110, 110, 255);
996         SETCOL(btheme->timasel.shade1,  0xaa, 0xaa, 0xba, 255);
997
998         /* space text */
999         btheme->text= btheme->tv3d;
1000         SETCOL(btheme->text.back,       153, 153, 153, 255);
1001         SETCOL(btheme->text.shade1,     143, 143, 143, 255);
1002         SETCOL(btheme->text.shade2,     0xc6, 0x77, 0x77, 255);
1003         SETCOL(btheme->text.hilite,     255, 0, 0, 255);
1004         
1005         /* syntax highlighting */
1006         SETCOL(btheme->text.syntaxn,    0, 0, 200, 255);        /* Numbers  Blue*/
1007         SETCOL(btheme->text.syntaxl,    100, 0, 0, 255);        /* Strings  red */
1008         SETCOL(btheme->text.syntaxc,    0, 100, 50, 255);       /* Comments greenish */
1009         SETCOL(btheme->text.syntaxv,    95, 95, 0, 255);        /* Special */
1010         SETCOL(btheme->text.syntaxb,    128, 0, 80, 255);       /* Builtin, red-purple */
1011         
1012         /* space oops */
1013         btheme->toops= btheme->tv3d;
1014         SETCOL(btheme->toops.back,      153, 153, 153, 255);
1015
1016         /* space info */
1017         btheme->tinfo= btheme->tv3d;
1018         SETCOL(btheme->tinfo.back,      153, 153, 153, 255);
1019
1020         /* space sound */
1021         btheme->tsnd= btheme->tv3d;
1022         SETCOL(btheme->tsnd.back,       153, 153, 153, 255);
1023         SETCOL(btheme->tsnd.shade1,  173, 173, 173, 255);               // sliders
1024         SETCOL(btheme->tsnd.grid, 140, 140, 140, 255);
1025         
1026         /* space time */
1027         btheme->ttime= btheme->tsnd;    // same as sound space
1028 }
1029
1030 char *BIF_ThemeColorsPup(int spacetype)
1031 {
1032         char *cp= MEM_callocN(32*32, "theme pup");
1033         char str[32];
1034         
1035         if(spacetype==0) {
1036                 sprintf(str, "Outline %%x%d|", TH_BUT_OUTLINE); strcat(cp, str);
1037                 sprintf(str, "Neutral %%x%d|", TH_BUT_NEUTRAL); strcat(cp, str);
1038                 sprintf(str, "Action %%x%d|", TH_BUT_ACTION); strcat(cp, str);
1039                 sprintf(str, "Setting %%x%d|", TH_BUT_SETTING); strcat(cp, str);
1040                 sprintf(str, "Special Setting 1%%x%d|", TH_BUT_SETTING1); strcat(cp, str);
1041                 sprintf(str, "Special Setting 2 %%x%d|", TH_BUT_SETTING2); strcat(cp, str);
1042                 sprintf(str, "Number Input %%x%d|", TH_BUT_NUM); strcat(cp, str);
1043                 sprintf(str, "Text Input %%x%d|", TH_BUT_TEXTFIELD); strcat(cp, str);
1044                 sprintf(str, "Text Input Highlight %%x%d|", TH_BUT_TEXTFIELD_HI); strcat(cp, str);
1045                 sprintf(str, "Popup %%x%d|", TH_BUT_POPUP); strcat(cp, str);
1046                 sprintf(str, "Text %%x%d|", TH_BUT_TEXT); strcat(cp, str);
1047                 sprintf(str, "Text Highlight %%x%d|", TH_BUT_TEXT_HI); strcat(cp, str);
1048                         strcat(cp,"%l|");
1049                 sprintf(str, "Menu Background %%x%d|", TH_MENU_BACK); strcat(cp, str);
1050                 sprintf(str, "Menu Item %%x%d|", TH_MENU_ITEM); strcat(cp, str);
1051                 sprintf(str, "Menu Item Highlight %%x%d|", TH_MENU_HILITE); strcat(cp, str);
1052                 sprintf(str, "Menu Text %%x%d|", TH_MENU_TEXT); strcat(cp, str);
1053                 sprintf(str, "Menu Text Highlight %%x%d|", TH_MENU_TEXT_HI); strcat(cp, str);
1054                 strcat(cp,"%l|");
1055                 sprintf(str, "Drawtype %%x%d|", TH_BUT_DRAWTYPE); strcat(cp, str);
1056         }
1057         else {
1058                 // first defaults for each space
1059                 sprintf(str, "Background %%x%d|", TH_BACK); strcat(cp, str);
1060                 sprintf(str, "Text %%x%d|", TH_TEXT); strcat(cp, str);
1061                 sprintf(str, "Text Highlight %%x%d|", TH_TEXT_HI); strcat(cp, str);
1062                 sprintf(str, "Header %%x%d|", TH_HEADER); strcat(cp, str);
1063                 
1064                 if(spacetype==SPACE_VIEW3D) {
1065                         sprintf(str, "Panel %%x%d|", TH_PANEL); strcat(cp, str);
1066                         strcat(cp,"%l|");
1067                         sprintf(str, "Grid %%x%d|", TH_GRID); strcat(cp, str);
1068                         sprintf(str, "Wire %%x%d|", TH_WIRE); strcat(cp, str);
1069                         sprintf(str, "Lamp %%x%d|", TH_LAMP); strcat(cp, str);
1070                         sprintf(str, "Object Selected %%x%d|", TH_SELECT); strcat(cp, str);
1071                         sprintf(str, "Object Active %%x%d|", TH_ACTIVE); strcat(cp, str);
1072                         sprintf(str, "Transform %%x%d|", TH_TRANSFORM); strcat(cp, str);
1073                         strcat(cp,"%l|");
1074                         sprintf(str, "Vertex %%x%d|", TH_VERTEX); strcat(cp, str);
1075                         sprintf(str, "Vertex Selected %%x%d|", TH_VERTEX_SELECT); strcat(cp, str);
1076                         sprintf(str, "Vertex Size %%x%d|", TH_VERTEX_SIZE); strcat(cp, str);
1077                         sprintf(str, "Edge Selected %%x%d|", TH_EDGE_SELECT); strcat(cp, str);
1078                         sprintf(str, "Edge Seam %%x%d|", TH_EDGE_SEAM); strcat(cp, str);
1079                         sprintf(str, "Edge UV Face Select %%x%d|", TH_EDGE_FACESEL); strcat(cp, str);
1080                         sprintf(str, "Face (transp) %%x%d|", TH_FACE); strcat(cp, str);
1081                         sprintf(str, "Face Selected (transp) %%x%d|", TH_FACE_SELECT); strcat(cp, str);
1082                         sprintf(str, "Face Dot Selected %%x%d|", TH_FACE_DOT); strcat(cp, str);
1083                         sprintf(str, "Face Dot Size %%x%d|", TH_FACEDOT_SIZE); strcat(cp, str);
1084                         sprintf(str, "Normal %%x%d|", TH_NORMAL); strcat(cp, str);
1085                         sprintf(str, "Bone Solid %%x%d|", TH_BONE_SOLID); strcat(cp, str);
1086                         sprintf(str, "Bone Pose %%x%d", TH_BONE_POSE); strcat(cp, str);
1087                 }
1088                 else if(spacetype==SPACE_IPO) {
1089                         sprintf(str, "Panel %%x%d|", TH_PANEL); strcat(cp, str);
1090                         strcat(cp,"%l|");
1091                         sprintf(str, "Grid %%x%d|", TH_GRID); strcat(cp, str);
1092                         sprintf(str, "Window Sliders %%x%d|", TH_SHADE1); strcat(cp, str);
1093                         sprintf(str, "Ipo Channels %%x%d|", TH_SHADE2); strcat(cp, str);
1094                         sprintf(str, "Vertex %%x%d|", TH_VERTEX); strcat(cp, str);
1095                         sprintf(str, "Vertex Selected %%x%d|", TH_VERTEX_SELECT); strcat(cp, str);
1096                 }
1097                 else if(spacetype==SPACE_FILE) {
1098                         sprintf(str, "Selected file %%x%d", TH_HILITE); strcat(cp, str);
1099                 }
1100                 else if(spacetype==SPACE_NLA) {
1101                         //sprintf(str, "Panel %%x%d|", TH_PANEL); strcat(cp, str);
1102                         strcat(cp,"%l|");
1103                         sprintf(str, "Grid %%x%d|", TH_GRID); strcat(cp, str);
1104                         sprintf(str, "View Sliders %%x%d|", TH_SHADE1); strcat(cp, str);
1105                         sprintf(str, "Bars %%x%d|", TH_SHADE2); strcat(cp, str);
1106                         sprintf(str, "Bars selected %%x%d|", TH_HILITE); strcat(cp, str);
1107                         sprintf(str, "Strips %%x%d|", TH_STRIP); strcat(cp, str);
1108                         sprintf(str, "Strips selected %%x%d|", TH_STRIP_SELECT); strcat(cp, str);
1109                 }
1110                 else if(spacetype==SPACE_ACTION) {
1111                         //sprintf(str, "Panel %%x%d|", TH_PANEL); strcat(cp, str);
1112                         strcat(cp,"%l|");
1113                         sprintf(str, "Grid %%x%d|", TH_GRID); strcat(cp, str);
1114                         sprintf(str, "RVK Sliders %%x%d|", TH_FACE); strcat(cp, str);
1115                         sprintf(str, "View Sliders %%x%d|", TH_SHADE1); strcat(cp, str);
1116                         sprintf(str, "Channels %%x%d|", TH_SHADE2); strcat(cp, str);
1117                         sprintf(str, "Channels Selected %%x%d|", TH_HILITE); strcat(cp, str);
1118                 }
1119                 else if(spacetype==SPACE_IMAGE) {
1120                         strcat(cp,"%l|");
1121                         sprintf(str, "Vertex %%x%d|", TH_VERTEX); strcat(cp, str);
1122                         sprintf(str, "Vertex Selected %%x%d|", TH_VERTEX_SELECT); strcat(cp, str);
1123                         sprintf(str, "Vertex Size %%x%d|", TH_VERTEX_SIZE); strcat(cp, str);
1124                         sprintf(str, "Face %%x%d|", TH_FACE); strcat(cp, str);
1125                         sprintf(str, "Face Selected %%x%d", TH_FACE_SELECT); strcat(cp, str);
1126                 }
1127                 else if(spacetype==SPACE_SEQ) {
1128                         sprintf(str, "Grid %%x%d|", TH_GRID); strcat(cp, str);
1129                         sprintf(str, "Window Sliders %%x%d|", TH_SHADE1); strcat(cp, str);
1130                 }
1131                 else if(spacetype==SPACE_SOUND) {
1132                         sprintf(str, "Grid %%x%d|", TH_GRID); strcat(cp, str);
1133                         sprintf(str, "Window Slider %%x%d|", TH_SHADE1); strcat(cp, str);
1134                 }
1135                 else if(spacetype==SPACE_BUTS) {
1136                         sprintf(str, "Panel %%x%d|", TH_PANEL); strcat(cp, str);
1137                 }
1138                 else if(spacetype==SPACE_IMASEL) {
1139                         sprintf(str, "Main Shade %%x%d|", TH_SHADE1); strcat(cp, str);
1140                 }
1141                 else if(spacetype==SPACE_TEXT) {
1142                         sprintf(str, "Scroll Bar %%x%d|", TH_SHADE1); strcat(cp, str);
1143                         sprintf(str, "Selected Text %%x%d|", TH_SHADE2); strcat(cp, str);
1144                         sprintf(str, "Cursor %%x%d|", TH_HILITE); strcat(cp, str);
1145                         strcat(cp,"%l|");
1146                         sprintf(str, "Syntax Builtin %%x%d|", TH_SYNTAX_B); strcat(cp, str);
1147                         sprintf(str, "Syntax Special %%x%d|", TH_SYNTAX_V); strcat(cp, str);
1148                         sprintf(str, "Syntax Comment %%x%d|", TH_SYNTAX_C); strcat(cp, str);
1149                         sprintf(str, "Syntax Strings %%x%d|", TH_SYNTAX_L); strcat(cp, str);
1150                         sprintf(str, "Syntax Numbers %%x%d|", TH_SYNTAX_N); strcat(cp, str);
1151                 }
1152                 else if(spacetype==SPACE_TIME) {
1153                         sprintf(str, "Grid %%x%d|", TH_GRID); strcat(cp, str);
1154                 }
1155         }
1156         return cp;
1157 }
1158
1159 void BIF_SetTheme(ScrArea *sa)
1160 {
1161         if(sa==NULL) {  // called for safety, when delete themes
1162                 theme_active= U.themes.first;
1163                 theme_spacetype= SPACE_VIEW3D;
1164         }
1165         else {
1166                 // later on, a local theme can be found too
1167                 theme_active= U.themes.first;
1168                 theme_spacetype= sa->spacetype;
1169         
1170         }
1171 }
1172
1173 // for space windows only
1174 void BIF_ThemeColor(int colorid)
1175 {
1176         char *cp;
1177         
1178         cp= BIF_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
1179         glColor3ub(cp[0], cp[1], cp[2]);
1180
1181 }
1182
1183 // plus alpha
1184 void BIF_ThemeColor4(int colorid)
1185 {
1186         char *cp;
1187         
1188         cp= BIF_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
1189         glColor4ub(cp[0], cp[1], cp[2], cp[3]);
1190
1191 }
1192
1193 // set the color with offset for shades
1194 void BIF_ThemeColorShade(int colorid, int offset)
1195 {
1196         int r, g, b;
1197         char *cp;
1198         
1199         cp= BIF_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
1200         r= offset + (int) cp[0];
1201         CLAMP(r, 0, 255);
1202         g= offset + (int) cp[1];
1203         CLAMP(g, 0, 255);
1204         b= offset + (int) cp[2];
1205         CLAMP(b, 0, 255);
1206         //glColor3ub(r, g, b);
1207         glColor4ub(r, g, b, cp[3]);
1208 }
1209 void BIF_ThemeColorShadeAlpha(int colorid, int coloffset, int alphaoffset)
1210 {
1211         int r, g, b, a;
1212         char *cp;
1213         
1214         cp= BIF_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
1215         r= coloffset + (int) cp[0];
1216         CLAMP(r, 0, 255);
1217         g= coloffset + (int) cp[1];
1218         CLAMP(g, 0, 255);
1219         b= coloffset + (int) cp[2];
1220         CLAMP(b, 0, 255);
1221         a= alphaoffset + (int) cp[3];
1222         CLAMP(a, 0, 255);
1223         glColor4ub(r, g, b, a);
1224 }
1225
1226 // blend between to theme colors, and set it
1227 void BIF_ThemeColorBlend(int colorid1, int colorid2, float fac)
1228 {
1229         int r, g, b;
1230         char *cp1, *cp2;
1231         
1232         cp1= BIF_ThemeGetColorPtr(theme_active, theme_spacetype, colorid1);
1233         cp2= BIF_ThemeGetColorPtr(theme_active, theme_spacetype, colorid2);
1234
1235         if(fac<0.0) fac=0.0; else if(fac>1.0) fac= 1.0;
1236         r= floor((1.0-fac)*cp1[0] + fac*cp2[0]);
1237         g= floor((1.0-fac)*cp1[1] + fac*cp2[1]);
1238         b= floor((1.0-fac)*cp1[2] + fac*cp2[2]);
1239         
1240         glColor3ub(r, g, b);
1241 }
1242
1243 // blend between to theme colors, shade it, and set it
1244 void BIF_ThemeColorBlendShade(int colorid1, int colorid2, float fac, int offset)
1245 {
1246         int r, g, b;
1247         char *cp1, *cp2;
1248         
1249         cp1= BIF_ThemeGetColorPtr(theme_active, theme_spacetype, colorid1);
1250         cp2= BIF_ThemeGetColorPtr(theme_active, theme_spacetype, colorid2);
1251
1252         if(fac<0.0) fac=0.0; else if(fac>1.0) fac= 1.0;
1253         r= offset+floor((1.0-fac)*cp1[0] + fac*cp2[0]);
1254         g= offset+floor((1.0-fac)*cp1[1] + fac*cp2[1]);
1255         b= offset+floor((1.0-fac)*cp1[2] + fac*cp2[2]);
1256         
1257         r= r<0?0:(r>255?255:r);
1258         g= g<0?0:(g>255?255:g);
1259         b= b<0?0:(b>255?255:b);
1260         
1261         glColor3ub(r, g, b);
1262 }
1263
1264
1265 // get individual values, not scaled
1266 float BIF_GetThemeValuef(int colorid)
1267 {
1268         char *cp;
1269         
1270         cp= BIF_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
1271         return ((float)cp[0]);
1272
1273 }
1274
1275 // get individual values, not scaled
1276 int BIF_GetThemeValue(int colorid)
1277 {
1278         char *cp;
1279         
1280         cp= BIF_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
1281         return ((int) cp[0]);
1282
1283 }
1284
1285
1286 // get the color, range 0.0-1.0
1287 void BIF_GetThemeColor3fv(int colorid, float *col)
1288 {
1289         char *cp;
1290         
1291         cp= BIF_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
1292         col[0]= ((float)cp[0])/255.0;
1293         col[1]= ((float)cp[1])/255.0;
1294         col[2]= ((float)cp[2])/255.0;
1295 }
1296
1297 // get the color, in char pointer
1298 void BIF_GetThemeColor3ubv(int colorid, char *col)
1299 {
1300         char *cp;
1301         
1302         cp= BIF_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
1303         col[0]= cp[0];
1304         col[1]= cp[1];
1305         col[2]= cp[2];
1306 }
1307
1308 // get the color, in char pointer
1309 void BIF_GetThemeColor4ubv(int colorid, char *col)
1310 {
1311         char *cp;
1312         
1313         cp= BIF_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
1314         col[0]= cp[0];
1315         col[1]= cp[1];
1316         col[2]= cp[2];
1317         col[3]= cp[3];
1318 }
1319
1320 void BIF_GetThemeColorType4ubv(int colorid, int spacetype, char *col)
1321 {
1322         char *cp;
1323         
1324         cp= BIF_ThemeGetColorPtr(theme_active, spacetype, colorid);
1325         col[0]= cp[0];
1326         col[1]= cp[1];
1327         col[2]= cp[2];
1328         col[3]= cp[3];
1329 }