Big commit in orange: Interface icons for materials, textures
[blender.git] / source / blender / src / interface_draw.c
1
2 /**
3  * $Id$
4  *
5  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version. The Blender
11  * Foundation also sells licenses for use in proprietary software under
12  * the Blender License.  See http://www.blender.org/BL/ for information
13  * about this.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software Foundation,
22  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  *
24  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
25  * All rights reserved.
26  *
27  * The Original Code is: all of this file.
28  *
29  * Contributor(s): none yet.
30  *
31  * ***** END GPL/BL DUAL LICENSE BLOCK *****
32  */
33
34 /* 
35      a full doc with API notes can be found in bf-blender/blender/doc/interface_API.txt
36
37  */
38  
39
40 #include <math.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <ctype.h>
44
45 #ifndef WIN32
46 #include <unistd.h>
47 #else
48 #include <io.h>
49 #endif   
50
51 #include "MEM_guardedalloc.h"
52
53 #include "PIL_time.h"
54
55 #include "BLI_blenlib.h"
56 #include "BLI_arithb.h"
57
58 #include "DNA_screen_types.h"
59 #include "DNA_space_types.h"
60 #include "DNA_userdef_types.h"
61 #include "DNA_vec_types.h"
62 #include "DNA_vfont_types.h"
63 #include "DNA_packedFile_types.h"
64
65 #include "BKE_blender.h"
66 #include "BKE_utildefines.h"
67 #include "BKE_font.h"
68 #include "BKE_global.h"
69 #include "datatoc.h"            /* std font */
70
71 #include "BIF_gl.h"
72 #include "BIF_graphics.h"
73 #include "BIF_keyval.h"
74 #include "BIF_mainqueue.h"
75
76 #include "BIF_screen.h"
77 #include "BIF_toolbox.h"
78 #include "BIF_mywindow.h"
79 #include "BIF_space.h"
80 #include "BIF_glutil.h"
81 #include "BIF_interface.h"
82 #include "BIF_interface_icons.h"
83 #include "BIF_butspace.h"
84 #include "BIF_language.h"
85
86 #include "BSE_view.h"
87
88 #ifdef INTERNATIONAL
89 #include "FTF_Api.h"
90 #endif
91
92 #include "mydevice.h"
93 #include "interface.h"
94 #include "blendef.h"
95
96 // globals
97 extern float UIwinmat[4][4];
98
99
100 /* ************** safe rasterpos for pixmap alignment with pixels ************* */
101
102 void ui_rasterpos_safe(float x, float y, float aspect)
103 {
104         float vals[4], remainder;
105         int doit=0;
106         
107         glRasterPos2f(x, y);
108         glGetFloatv(GL_CURRENT_RASTER_POSITION, vals);
109
110         remainder= vals[0] - floor(vals[0]);
111         if(remainder > 0.4 && remainder < 0.6) {
112                 if(remainder < 0.5) x -= 0.1*aspect;
113                 else x += 0.1*aspect;
114                 doit= 1;
115         }
116         remainder= vals[1] - floor(vals[1]);
117         if(remainder > 0.4 && remainder < 0.6) {
118                 if(remainder < 0.5) y -= 0.1*aspect;
119                 else y += 0.1*aspect;
120                 doit= 1;
121         }
122         
123         if(doit) glRasterPos2f(x, y);
124
125         BIF_RasterPos(x, y);
126         BIF_SetScale(aspect);
127 }
128
129 /* ************** generic embossed rect, for window sliders etc ************* */
130
131 void uiEmboss(float x1, float y1, float x2, float y2, int sel)
132 {
133         
134         /* below */
135         if(sel) glColor3ub(200,200,200);
136         else glColor3ub(50,50,50);
137         fdrawline(x1, y1, x2, y1);
138
139         /* right */
140         fdrawline(x2, y1, x2, y2);
141         
142         /* top */
143         if(sel) glColor3ub(50,50,50);
144         else glColor3ub(200,200,200);
145         fdrawline(x1, y2, x2, y2);
146
147         /* left */
148         fdrawline(x1, y1, x1, y2);
149         
150 }
151
152 /* ************** GENERIC ICON DRAW, NO THEME HERE ************* */
153
154 static void ui_draw_icon(uiBut *but, BIFIconID icon)
155 {
156         // void BIF_icon_pos(float xs, float ys);
157         int blend= 0;
158         float xs=0, ys=0;
159
160         // this icon doesn't need draw...
161         if(icon==ICON_BLANK1) return;
162
163         if(but->flag & UI_ICON_LEFT) {
164                 if (but->type==BUTM) {
165                         xs= but->x1+1.0;
166                 }
167                 else if ((but->type==ICONROW) || (but->type==ICONTEXTROW)) {
168                         xs= but->x1+4.0;
169                 }
170                 else {
171                         xs= but->x1+6.0;
172                 }
173                 ys= (but->y1+but->y2- BIF_icon_get_height(icon))/2.0;
174         }
175         if(but->flag & UI_ICON_RIGHT) {
176                 xs= but->x2-17.0;
177                 ys= (but->y1+but->y2- BIF_icon_get_height(icon))/2.0;
178         }
179         if (!((but->flag & UI_ICON_RIGHT) || (but->flag & UI_ICON_LEFT))) {
180                 xs= (but->x1+but->x2- BIF_icon_get_width(icon))/2.0;
181                 ys= (but->y1+but->y2- BIF_icon_get_height(icon))/2.0;
182         }
183
184         if(but->aspect>1.1) glPixelZoom(1.0/but->aspect, 1.0/but->aspect);
185         else if(but->aspect<0.9) glPixelZoom(1.0/but->aspect, 1.0/but->aspect);
186
187         glEnable(GL_BLEND);
188         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
189
190         /* calculate blend color */
191         if ELEM4(but->type, ICONTOG, TOG, ROW, TOGN) {
192                 if(but->flag & UI_SELECT);
193                 else if(but->flag & UI_ACTIVE);
194                 else blend= -60;
195         }
196         BIF_icon_draw_blended(xs, ys, icon, but->themecol, blend);
197         
198         glBlendFunc(GL_ONE, GL_ZERO);
199         glDisable(GL_BLEND);
200
201         glPixelZoom(1.0, 1.0);
202 }
203
204
205 /* ************** DEFAULT THEME, SHADED BUTTONS ************* */
206
207
208 #define M_WHITE         BIF_ThemeColorShade(colorid, 80)
209
210 #define M_ACT_LIGHT     BIF_ThemeColorShade(colorid, 55)
211 #define M_LIGHT         BIF_ThemeColorShade(colorid, 45)
212 #define M_HILITE        BIF_ThemeColorShade(colorid, 25)
213 #define M_LMEDIUM       BIF_ThemeColorShade(colorid, 10)
214 #define M_MEDIUM        BIF_ThemeColor(colorid)
215 #define M_LGREY         BIF_ThemeColorShade(colorid, -20)
216 #define M_GREY          BIF_ThemeColorShade(colorid, -45)
217 #define M_DARK          BIF_ThemeColorShade(colorid, -80)
218
219 #define M_NUMTEXT                               BIF_ThemeColorShade(colorid, 25)
220 #define M_NUMTEXT_ACT_LIGHT             BIF_ThemeColorShade(colorid, 35)
221
222 #define MM_WHITE        BIF_ThemeColorShade(TH_BUT_NEUTRAL, 120)
223
224 /* Used for the subtle sunken effect around buttons.
225  * One option is to hardcode to white, with alpha, however it causes a 
226  * weird 'building up' efect, so it's commented out for now.
227  */
228  
229 /*
230 #define MM_WHITE_OP     glColor4ub(255, 255, 255, 60)
231 #define MM_WHITE_TR     glColor4ub(255, 255, 255, 0)
232  */
233
234 #define MM_WHITE_OP     BIF_ThemeColorShadeAlpha(TH_BACK, 55, -100)
235 #define MM_WHITE_TR     BIF_ThemeColorShadeAlpha(TH_BACK, 55, -255)
236
237 #define MM_LIGHT        BIF_ThemeColorShade(TH_BUT_OUTLINE, 45)
238 #define MM_MEDIUM       BIF_ThemeColor(TH_BUT_OUTLINE)
239 #define MM_GREY         BIF_ThemeColorShade(TH_BUT_OUTLINE, -45)
240 #define MM_DARK         BIF_ThemeColorShade(TH_BUT_OUTLINE, -80)
241
242 /* base shaded button */
243 static void shaded_button(float x1, float y1, float x2, float y2, float asp, int colorid, int flag, int mid)
244 {
245         /* 'mid' arg determines whether the button is in the middle of
246          * an alignment group or not. 0 = not middle, 1 = is in the middle.
247          * Done to allow cleaner drawing
248          */
249          
250         /* *** SHADED BUTTON BASE *** */
251         glShadeModel(GL_SMOOTH);
252         glBegin(GL_QUADS);
253         
254         if(flag & UI_SELECT) {
255                 if(flag & UI_ACTIVE) M_MEDIUM;
256                 else M_LGREY;
257         } else {
258                 if(flag & UI_ACTIVE) M_LIGHT;
259                 else M_HILITE;
260         }
261
262         glVertex2f(x1,y1);
263         glVertex2f(x2,y1);
264
265         if(flag & UI_SELECT) {
266                 if(flag & UI_ACTIVE) M_LGREY;
267                 else M_GREY;
268         } else {
269                 if(flag & UI_ACTIVE) M_ACT_LIGHT;
270                 else M_LIGHT;
271         }
272
273         glVertex2f(x2,(y2-(y2-y1)/3));
274         glVertex2f(x1,(y2-(y2-y1)/3));
275         glEnd();
276         
277
278         glShadeModel(GL_FLAT);
279         glBegin(GL_QUADS);
280         
281         if(flag & UI_SELECT) {
282                 if(flag & UI_ACTIVE) M_LGREY;
283                 else M_GREY;
284         } else {
285                 if(flag & UI_ACTIVE) M_ACT_LIGHT;
286                 else M_LIGHT;
287         }
288         
289         glVertex2f(x1,(y2-(y2-y1)/3));
290         glVertex2f(x2,(y2-(y2-y1)/3));
291         glVertex2f(x2,y2);
292         glVertex2f(x1,y2);
293
294         glEnd();
295         /* *** END SHADED BUTTON BASE *** */
296         
297         /* *** INNER OUTLINE *** */
298         /* left */
299         if(!(flag & UI_SELECT)) {
300                 glShadeModel(GL_SMOOTH);
301                 glBegin(GL_LINES);
302                 M_MEDIUM;
303                 glVertex2f(x1+1,y1+2);
304                 M_WHITE;
305                 glVertex2f(x1+1,y2);
306                 glEnd();
307         }
308         
309         /* right */
310                 if(!(flag & UI_SELECT)) {
311                 glShadeModel(GL_SMOOTH);
312                 glBegin(GL_LINES);
313                 M_MEDIUM;
314                 glVertex2f(x2-1,y1+2);
315                 M_WHITE;
316                 glVertex2f(x2-1,y2);
317                 glEnd();
318         }
319         
320         glShadeModel(GL_FLAT);
321         
322         /* top */
323         if(flag & UI_SELECT) {
324                 if(flag & UI_ACTIVE) M_LGREY;
325                 else M_GREY;
326         } else {
327                 if(flag & UI_ACTIVE) M_WHITE;
328                 else M_WHITE;
329         }
330
331         fdrawline(x1, (y2-1), x2, (y2-1));
332         
333         /* bottom */
334         if(flag & UI_SELECT) {
335                 if(flag & UI_ACTIVE) M_MEDIUM;
336                 else M_LGREY;
337         } else {
338                 if(flag & UI_ACTIVE) M_LMEDIUM;
339                 else M_MEDIUM;
340         }
341         fdrawline(x1, (y1+1), x2, (y1+1));
342         /* *** END INNER OUTLINE *** */
343         
344         /* *** OUTER OUTLINE *** */
345         if (mid) {
346                 // we draw full outline, its not AA, and it works better button mouse-over hilite
347                 MM_DARK;
348                 
349                 // left right
350                 fdrawline(x1, y1, x1, y2);
351                 fdrawline(x2, y1, x2, y2);
352         
353                 // top down
354                 fdrawline(x1, y2, x2, y2);
355                 fdrawline(x1, y1, x2, y1); 
356         } else {
357                 MM_DARK;
358                 gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, 1.5);
359         }
360         /* END OUTER OUTLINE */
361 }
362
363 /* base flat button */
364 static void flat_button(float x1, float y1, float x2, float y2, float asp, int colorid, int flag, int mid)
365 {
366         /* 'mid' arg determines whether the button is in the middle of
367          * an alignment group or not. 0 = not middle, 1 = is in the middle.
368          * Done to allow cleaner drawing
369          */
370          
371         /* *** FLAT TEXT/NUM FIELD *** */
372         glShadeModel(GL_FLAT);
373         if(flag & UI_SELECT) {
374                 if(flag & UI_ACTIVE) M_LGREY;
375                 else M_GREY;
376         }
377         else {
378                 if(flag & UI_ACTIVE) M_NUMTEXT_ACT_LIGHT;
379                 else M_NUMTEXT;
380         }
381
382         glRectf(x1, y1, x2, y2);
383         /* *** END FLAT TEXT/NUM FIELD *** */
384         
385         /* *** OUTER OUTLINE *** */
386         if (mid) {
387                 // we draw full outline, its not AA, and it works better button mouse-over hilite
388                 MM_DARK;
389                 
390                 // left right
391                 fdrawline(x1, y1, x1, y2);
392                 fdrawline(x2, y1, x2, y2);
393         
394                 // top down
395                 fdrawline(x1, y2, x2, y2);
396                 fdrawline(x1, y1, x2, y1); 
397         } else {
398                 MM_DARK;
399                 gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, 1.5);
400         }
401         /* END OUTER OUTLINE */
402 }
403
404 /* small side double arrow for iconrow */
405 static void ui_default_iconrow_arrows(float x1, float y1, float x2, float y2)
406 {
407         glEnable( GL_POLYGON_SMOOTH );
408         glEnable( GL_BLEND );
409         glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
410         
411         glShadeModel(GL_FLAT);
412         glBegin(GL_TRIANGLES);
413         glVertex2f((short)x2-2,(short)(y2-(y2-y1)/2)+1);
414         glVertex2f((short)x2-6,(short)(y2-(y2-y1)/2)+1);
415         glVertex2f((short)x2-4,(short)(y2-(y2-y1)/2)+4);
416         glEnd();
417                 
418         glBegin(GL_TRIANGLES);
419         glVertex2f((short)x2-2,(short)(y2-(y2-y1)/2) -1);
420         glVertex2f((short)x2-6,(short)(y2-(y2-y1)/2) -1);
421         glVertex2f((short)x2-4,(short)(y2-(y2-y1)/2) -4);
422         glEnd();
423         
424         glDisable( GL_BLEND );
425         glDisable( GL_POLYGON_SMOOTH );
426 }
427
428 /* side double arrow for menu */
429 static void ui_default_menu_arrows(float x1, float y1, float x2, float y2)
430 {
431         glEnable( GL_POLYGON_SMOOTH );
432         glEnable( GL_BLEND );
433         glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
434         
435         glShadeModel(GL_FLAT);
436         glBegin(GL_TRIANGLES);
437         glVertex2f((short)x2-4,(short)(y2-(y2-y1)/2)+1);
438         glVertex2f((short)x2-12,(short)(y2-(y2-y1)/2)+1);
439         glVertex2f((short)x2-8,(short)(y2-(y2-y1)/2)+4);
440         glEnd();
441                 
442         glBegin(GL_TRIANGLES);
443         glVertex2f((short)x2-4,(short)(y2-(y2-y1)/2) -1);
444         glVertex2f((short)x2-12,(short)(y2-(y2-y1)/2) -1);
445         glVertex2f((short)x2-8,(short)(y2-(y2-y1)/2) -4);
446         glEnd();
447         
448         glDisable( GL_BLEND );
449         glDisable( GL_POLYGON_SMOOTH );
450 }
451
452 /* left/right arrows for number fields */
453 static void ui_default_num_arrows(float x1, float y1, float x2, float y2)
454 {
455         if( x2-x1 > 25) {       // 25 is a bit arbitrary, but small buttons cant have arrows
456
457                 glEnable( GL_POLYGON_SMOOTH );
458                 glEnable( GL_BLEND );
459                 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
460                 
461                 glShadeModel(GL_FLAT);
462                 glBegin(GL_TRIANGLES);
463                 
464                 glVertex2f((short)x1+5,(short)(y2-(y2-y1)/2));
465                 glVertex2f((short)x1+10,(short)(y2-(y2-y1)/2)+4);
466                 glVertex2f((short)x1+10,(short)(y2-(y2-y1)/2)-4);
467                 glEnd();
468
469                 /* right */
470                 glShadeModel(GL_FLAT);
471                 glBegin(GL_TRIANGLES);
472
473                 glVertex2f((short)x2-5,(short)(y2-(y2-y1)/2));
474                 glVertex2f((short)x2-10,(short)(y2-(y2-y1)/2)-4);
475                 glVertex2f((short)x2-10,(short)(y2-(y2-y1)/2)+4);
476                 glEnd();
477                 
478                 glDisable( GL_BLEND );
479                 glDisable( GL_POLYGON_SMOOTH );
480         }
481 }
482
483 /* changing black/white for TOG3 buts */
484 static void ui_tog3_invert(float x1, float y1, float x2, float y2, int seltype)
485 {
486         short alpha = 30;
487         
488         if (seltype == 0) {
489                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
490                 glEnable(GL_BLEND);
491                 
492                 glColor4ub(0, 0, 0, alpha);
493                 glRectf(x2-6, y1, x2, (y1+(y2-y1)/2));
494                 
495                 glColor4ub(255, 255, 255, alpha);
496                 glRectf(x2-6, (y1+(y2-y1)/2), x2, y2);
497                 
498                 glDisable(GL_BLEND);
499         } else {
500                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
501                 glEnable(GL_BLEND);
502                 
503                 glColor4ub(255, 255, 255, alpha);
504                 glRectf(x2-6, y1, x2, (y1+(y2-y1)/2));
505                 
506                 glColor4ub(0, 0, 0, alpha);
507                 glRectf(x2-6, (y1+(y2-y1)/2), x2, y2);
508                 
509                 glDisable(GL_BLEND);
510         }
511 }
512
513 /* button/popup menu/iconrow drawing code */
514 static void ui_default_button(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
515 {
516         int align= (flag & UI_BUT_ALIGN);
517
518         if(align) {
519         
520                 /* *** BOTTOM OUTER SUNKEN EFFECT *** */
521                 if (!((align == UI_BUT_ALIGN_DOWN) ||
522                         (align == (UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT)) ||
523                         (align == (UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT)))) {
524                         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
525                         glEnable(GL_BLEND);
526                         MM_WHITE_OP;
527                         fdrawline(x1, y1-1, x2, y1-1);  
528                         glDisable(GL_BLEND);
529                 }
530                 /* *** END BOTTOM OUTER SUNKEN EFFECT *** */
531                 
532                 switch(align) {
533                 case UI_BUT_ALIGN_TOP:
534                         uiSetRoundBox(12);
535                         
536                         /* last arg in shaded_button() determines whether the button is in the middle of
537                          * an alignment group or not. 0 = not middle, 1 = is in the middle.
538                          * Done to allow cleaner drawing
539                          */
540                          
541                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
542                         break;
543                 case UI_BUT_ALIGN_DOWN:
544                         uiSetRoundBox(3);
545                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
546                         break;
547                 case UI_BUT_ALIGN_LEFT:
548                         
549                         /* RIGHT OUTER SUNKEN EFFECT */
550                         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
551                         glEnable(GL_BLEND);
552                         glShadeModel(GL_SMOOTH);
553                         glBegin(GL_LINES);
554                         MM_WHITE_OP;
555                         glVertex2f(x2+1,y1);
556                         MM_WHITE_TR;
557                         glVertex2f(x2+1,y2);
558                         glEnd();
559                         glDisable(GL_BLEND);
560                         
561                         uiSetRoundBox(6);
562                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
563                         break;
564                 case UI_BUT_ALIGN_RIGHT:
565                 
566                         /* LEFT OUTER SUNKEN EFFECT */
567                         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
568                         glEnable(GL_BLEND);
569                         glShadeModel(GL_SMOOTH);
570                         glBegin(GL_LINES);
571                         MM_WHITE_OP;
572                         glVertex2f(x1-1,y1);
573                         MM_WHITE_TR;
574                         glVertex2f(x1-1,y2);
575                         glEnd();
576                         glDisable(GL_BLEND);
577                 
578                         uiSetRoundBox(9);
579                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
580                         break;
581                         
582                 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT:
583                         uiSetRoundBox(1);
584                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
585                         break;
586                 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT:
587                         uiSetRoundBox(2);
588                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
589                         break;
590                 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_RIGHT:
591                 
592                         /* LEFT OUTER SUNKEN EFFECT */
593                         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
594                         glEnable(GL_BLEND);
595                         glShadeModel(GL_SMOOTH);
596                         glBegin(GL_LINES);
597                         MM_WHITE_OP;
598                         glVertex2f(x1-1,y1);
599                         MM_WHITE_TR;
600                         glVertex2f(x1-1,y2);
601                         glEnd();
602                         glDisable(GL_BLEND);
603                 
604                         uiSetRoundBox(8);
605                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
606                         break;
607                 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_LEFT:
608                 
609                         /* RIGHT OUTER SUNKEN EFFECT */
610                         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
611                         glEnable(GL_BLEND);
612                         glShadeModel(GL_SMOOTH);
613                         glBegin(GL_LINES);
614                         MM_WHITE_OP;
615                         glVertex2f(x2+1,y1);
616                         MM_WHITE_TR;
617                         glVertex2f(x2+1,y2);
618                         glEnd();
619                         glDisable(GL_BLEND);
620                         
621                         uiSetRoundBox(4);
622                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
623                         break;
624                         
625                 default:
626                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 1);
627                         break;
628                 }
629         } 
630         else {  
631                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
632                 glEnable(GL_BLEND);
633                 glShadeModel(GL_SMOOTH);
634                 
635                 /* BOTTOM OUTER SUNKEN EFFECT */
636                 MM_WHITE_OP;
637                 fdrawline(x1, y1-1, x2, y1-1);  
638                 
639                 /* LEFT OUTER SUNKEN EFFECT */
640                 glBegin(GL_LINES);
641                 MM_WHITE_OP;
642                 glVertex2f(x1-1,y1);
643                 MM_WHITE_TR;
644                 glVertex2f(x1-1,y2);
645                 glEnd();
646                 
647                 /* RIGHT OUTER SUNKEN EFFECT */
648                 glBegin(GL_LINES);
649                 MM_WHITE_OP;
650                 glVertex2f(x2+1,y1);
651                 MM_WHITE_TR;
652                 glVertex2f(x2+1,y2);
653                 glEnd();
654                 
655                 glDisable(GL_BLEND);
656         
657                 uiSetRoundBox(15);
658                 shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
659         }
660         
661         /* *** EXTRA DRAWING FOR SPECIFIC CONTROL TYPES *** */
662         switch(type) {
663         case ICONROW:
664         case ICONTEXTROW:
665                 /* DARKENED AREA */
666                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
667                 glEnable(GL_BLEND);
668                 
669                 glColor4ub(0, 0, 0, 30);
670                 glRectf(x2-9, y1, x2, y2);
671         
672                 glDisable(GL_BLEND);
673                 /* END DARKENED AREA */
674         
675                 /* ICONROW DOUBLE-ARROW  */
676                 M_DARK;
677                 ui_default_iconrow_arrows(x1, y1, x2, y2);
678                 /* END ICONROW DOUBLE-ARROW */
679                 break;
680         case MENU:
681                 /* DARKENED AREA */
682                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
683                 glEnable(GL_BLEND);
684                 
685                 glColor4ub(0, 0, 0, 30);
686                 glRectf(x2-18, y1, x2, y2);
687         
688                 glDisable(GL_BLEND);
689                 /* END DARKENED AREA */
690         
691                 /* MENU DOUBLE-ARROW  */
692                 M_DARK;
693                 ui_default_menu_arrows(x1, y1, x2, y2);
694                 /* MENU DOUBLE-ARROW */
695                 break;
696         }       
697 }
698
699
700 /* number/text field drawing code */
701 static void ui_default_flat(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
702 {
703         int align= (flag & UI_BUT_ALIGN);
704
705         if(align) {
706         
707                 /* *** BOTTOM OUTER SUNKEN EFFECT *** */
708                 if (!((align == UI_BUT_ALIGN_DOWN) ||
709                         (align == (UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT)) ||
710                         (align == (UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT)))) {
711                         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
712                         glEnable(GL_BLEND);
713                         MM_WHITE_OP;
714                         fdrawline(x1, y1-1, x2, y1-1);  
715                         glDisable(GL_BLEND);
716                 }
717                 /* *** END BOTTOM OUTER SUNKEN EFFECT *** */
718                 
719                 switch(align) {
720                 case UI_BUT_ALIGN_TOP:
721                         uiSetRoundBox(12);
722                         
723                         /* last arg in shaded_button() determines whether the button is in the middle of
724                          * an alignment group or not. 0 = not middle, 1 = is in the middle.
725                          * Done to allow cleaner drawing
726                          */
727                          
728                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
729                         break;
730                 case UI_BUT_ALIGN_DOWN:
731                         uiSetRoundBox(3);
732                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
733                         break;
734                 case UI_BUT_ALIGN_LEFT:
735                         
736                         /* RIGHT OUTER SUNKEN EFFECT */
737                         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
738                         glEnable(GL_BLEND);
739                         glShadeModel(GL_SMOOTH);
740                         glBegin(GL_LINES);
741                         MM_WHITE_OP;
742                         glVertex2f(x2+1,y1);
743                         MM_WHITE_TR;
744                         glVertex2f(x2+1,y2);
745                         glEnd();
746                         glDisable(GL_BLEND);
747                         
748                         uiSetRoundBox(6);
749                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
750                         break;
751                 case UI_BUT_ALIGN_RIGHT:
752                 
753                         /* LEFT OUTER SUNKEN EFFECT */
754                         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
755                         glEnable(GL_BLEND);
756                         glShadeModel(GL_SMOOTH);
757                         glBegin(GL_LINES);
758                         MM_WHITE_OP;
759                         glVertex2f(x1-1,y1);
760                         MM_WHITE_TR;
761                         glVertex2f(x1-1,y2);
762                         glEnd();
763                         glDisable(GL_BLEND);
764                 
765                         uiSetRoundBox(9);
766                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
767                         break;
768                         
769                 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT:
770                         uiSetRoundBox(1);
771                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
772                         break;
773                 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT:
774                         uiSetRoundBox(2);
775                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
776                         break;
777                 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_RIGHT:
778                 
779                         /* LEFT OUTER SUNKEN EFFECT */
780                         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
781                         glEnable(GL_BLEND);
782                         glShadeModel(GL_SMOOTH);
783                         glBegin(GL_LINES);
784                         MM_WHITE_OP;
785                         glVertex2f(x1-1,y1);
786                         MM_WHITE_TR;
787                         glVertex2f(x1-1,y2);
788                         glEnd();
789                         glDisable(GL_BLEND);
790                 
791                         uiSetRoundBox(8);
792                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
793                         break;
794                 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_LEFT:
795                 
796                         /* RIGHT OUTER SUNKEN EFFECT */
797                         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
798                         glEnable(GL_BLEND);
799                         glShadeModel(GL_SMOOTH);
800                         glBegin(GL_LINES);
801                         MM_WHITE_OP;
802                         glVertex2f(x2+1,y1);
803                         MM_WHITE_TR;
804                         glVertex2f(x2+1,y2);
805                         glEnd();
806                         glDisable(GL_BLEND);
807                         
808                         uiSetRoundBox(4);
809                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
810                         break;
811                         
812                 default:
813                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 1);
814                         break;
815                 }
816         } 
817         else {
818         
819                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
820                 glEnable(GL_BLEND);
821                 glShadeModel(GL_SMOOTH);
822                 
823                 /* BOTTOM OUTER SUNKEN EFFECT */
824                 MM_WHITE_OP;
825                 fdrawline(x1, y1-1, x2, y1-1);  
826                 
827                 /* LEFT OUTER SUNKEN EFFECT */
828                 glBegin(GL_LINES);
829                 MM_WHITE_OP;
830                 glVertex2f(x1-1,y1);
831                 MM_WHITE_TR;
832                 glVertex2f(x1-1,y2);
833                 glEnd();
834                 
835                 /* RIGHT OUTER SUNKEN EFFECT */
836                 glBegin(GL_LINES);
837                 MM_WHITE_OP;
838                 glVertex2f(x2+1,y1);
839                 MM_WHITE_TR;
840                 glVertex2f(x2+1,y2);
841                 glEnd();
842                 
843                 glDisable(GL_BLEND);
844
845                 uiSetRoundBox(15);
846                 flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
847         }
848         
849         /* *** EXTRA DRAWING FOR SPECIFIC CONTROL TYPES *** */
850         switch(type) {
851         case NUM:
852                 /* SIDE ARROWS */
853                 /* left */
854                 if(flag & UI_SELECT) {
855                         if(flag & UI_ACTIVE) M_DARK;
856                         else M_DARK;
857                 } else {
858                         if(flag & UI_ACTIVE) M_GREY;
859                         else M_LGREY;
860                 }
861                 
862                 ui_default_num_arrows(x1, y1, x2, y2);
863                 /* END SIDE ARROWS */
864         }
865 }
866
867 static void ui_default_slider(int colorid, float fac, float aspect, float x1, float y1, float x2, float y2, int flag)
868 {
869         float ymid, yc;
870
871         /* the slider background line */
872         ymid= (y1+y2)/2.0;
873         //yc= 2.5*aspect;       // height of center line
874         yc = 2.3; // height of center line
875         
876         if(flag & UI_SELECT) 
877                         BIF_ThemeColorShade(TH_BUT_NUM, -5);
878         else
879                 if(flag & UI_ACTIVE) 
880                         BIF_ThemeColorShade(TH_BUT_NUM, +35); 
881                 else
882                         BIF_ThemeColorShade(TH_BUT_NUM, +25); 
883
884         glRectf(x1, ymid-yc, x2, ymid+yc);
885         
886         /* top inner bevel */
887         if(flag & UI_SELECT) BIF_ThemeColorShade(TH_BUT_NUM, -40); 
888         else BIF_ThemeColorShade(TH_BUT_NUM, -5); 
889         fdrawline(x1+1, ymid+yc, x2, ymid+yc);
890         
891         /* bottom inner bevel */
892         if(flag & UI_SELECT) BIF_ThemeColorShade(TH_BUT_NUM, +15); 
893         else BIF_ThemeColorShade(TH_BUT_NUM, +45); 
894         fdrawline(x1+1, ymid-yc, x2, ymid-yc);
895         
896         
897         /* the movable slider */
898         if(flag & UI_SELECT) BIF_ThemeColorShade(TH_BUT_NUM, +80); 
899         else BIF_ThemeColorShade(TH_BUT_NUM, -45); 
900
901         glShadeModel(GL_SMOOTH);
902         glBegin(GL_QUADS);
903
904         BIF_ThemeColorShade(TH_BUT_NUM, -45); 
905
906         glVertex2f(x1,     y1+2.5);
907         glVertex2f(x1+fac, y1+2.5);
908
909         BIF_ThemeColor(TH_BUT_NUM); 
910
911         glVertex2f(x1+fac, y2-2.5);
912         glVertex2f(x1,     y2-2.5);
913
914         glEnd();
915         
916
917         /* slider handle center */
918         glShadeModel(GL_SMOOTH);
919         glBegin(GL_QUADS);
920
921         BIF_ThemeColor(TH_BUT_NUM); 
922         glVertex2f(x1+fac-3, y1+2);
923         glVertex2f(x1+fac, y1+4);
924         BIF_ThemeColorShade(TH_BUT_NUM, +80); 
925         glVertex2f(x1+fac, y2-2);
926         glVertex2f(x1+fac-3, y2-2);
927
928         glEnd();
929         
930         /* slider handle left bevel */
931         BIF_ThemeColorShade(TH_BUT_NUM, +70); 
932         fdrawline(x1+fac-3, y2-2, x1+fac-3, y1+2);
933         
934         /* slider handle right bevel */
935         BIF_ThemeColorShade(TH_BUT_NUM, -35); 
936         fdrawline(x1+fac, y2-2, x1+fac, y1+2);
937
938         glShadeModel(GL_FLAT);
939 }
940
941 /* default theme callback */
942 static void ui_draw_default(int type, int colorid, float aspect, float x1, float y1, float x2, float y2, int flag)
943 {
944
945         switch(type) {
946         case TEX:
947         case IDPOIN:
948         case NUM:
949                 ui_default_flat(type, colorid, aspect, x1, y1, x2, y2, flag);
950                 break;
951         case ICONROW: 
952         case ICONTEXTROW: 
953         case MENU: 
954         default: 
955                 ui_default_button(type, colorid, aspect, x1, y1, x2, y2, flag);
956         }
957
958 }
959
960
961 /* *************** OLDSKOOL THEME ***************** */
962
963 static void ui_draw_outlineX(float x1, float y1, float x2, float y2, float asp1)
964 {
965         float vec[2];
966         
967         glBegin(GL_LINE_LOOP);
968         vec[0]= x1+asp1; vec[1]= y1-asp1;
969         glVertex2fv(vec);
970         vec[0]= x2-asp1; 
971         glVertex2fv(vec);
972         vec[0]= x2+asp1; vec[1]= y1+asp1;
973         glVertex2fv(vec);
974         vec[1]= y2-asp1;
975         glVertex2fv(vec);
976         vec[0]= x2-asp1; vec[1]= y2+asp1;
977         glVertex2fv(vec);
978         vec[0]= x1+asp1;
979         glVertex2fv(vec);
980         vec[0]= x1-asp1; vec[1]= y2-asp1;
981         glVertex2fv(vec);
982         vec[1]= y1+asp1;
983         glVertex2fv(vec);
984         glEnd();                
985         
986 }
987
988
989 static void ui_draw_oldskool(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
990 {
991         /* paper */
992         if(flag & UI_SELECT) {
993                 if(flag & UI_ACTIVE) BIF_ThemeColorShade(colorid, -40);
994                 else BIF_ThemeColorShade(colorid, -30);
995         }
996         else {
997                 if(flag & UI_ACTIVE) BIF_ThemeColorShade(colorid, +30);
998                 else BIF_ThemeColorShade(colorid, +20);
999         }
1000         
1001         glRectf(x1+1, y1+1, x2-1, y2-1);
1002
1003         x1+= asp;
1004         x2-= asp;
1005         y1+= asp;
1006         y2-= asp;
1007
1008         /* below */
1009         if(flag & UI_SELECT) BIF_ThemeColorShade(colorid, 0);
1010         else BIF_ThemeColorShade(colorid, -30);
1011         fdrawline(x1, y1, x2, y1);
1012
1013         /* right */
1014         fdrawline(x2, y1, x2, y2);
1015         
1016         /* top */
1017         if(flag & UI_SELECT) BIF_ThemeColorShade(colorid, -30);
1018         else BIF_ThemeColorShade(colorid, 0);
1019         fdrawline(x1, y2, x2, y2);
1020
1021         /* left */
1022         fdrawline(x1, y1, x1, y2);
1023         
1024         /* outline */
1025         glColor3ub(0,0,0);
1026         ui_draw_outlineX(x1, y1, x2, y2, asp);
1027         
1028         
1029         /* special type decorations */
1030         switch(type) {
1031         case NUM:
1032                 if(flag & UI_SELECT) BIF_ThemeColorShade(colorid, -60);
1033                 else BIF_ThemeColorShade(colorid, -30);
1034                 ui_default_num_arrows(x1, y1, x2, y2);
1035                 break;
1036
1037         case ICONROW: 
1038         case ICONTEXTROW: 
1039                 if(flag & UI_ACTIVE) BIF_ThemeColorShade(colorid, 0);
1040                 else BIF_ThemeColorShade(colorid, -10);
1041                 glRectf(x2-9, y1+asp, x2-asp, y2-asp);
1042
1043                 BIF_ThemeColorShade(colorid, -50);
1044                 ui_default_iconrow_arrows(x1, y1, x2, y2);
1045                 break;
1046                 
1047         case MENU: 
1048                 if(flag & UI_ACTIVE) BIF_ThemeColorShade(colorid, 0);
1049                 else BIF_ThemeColorShade(colorid, -10);
1050                 glRectf(x2-17, y1+asp, x2-asp, y2-asp);
1051
1052                 BIF_ThemeColorShade(colorid, -50);
1053                 ui_default_menu_arrows(x1, y1, x2, y2);
1054                 break;
1055         }
1056         
1057 }
1058
1059 /* *************** BASIC ROUNDED THEME ***************** */
1060
1061 static void round_button(float x1, float y1, float x2, float y2, float asp, 
1062                                                  int colorid, int round, int menudeco, int curshade)
1063 {
1064         float rad;
1065         char col[4];
1066         
1067         rad= (y2-y1)/2.0;
1068         if(rad>7.0) rad= 7.0;
1069         
1070         uiSetRoundBox(round);
1071         gl_round_box(GL_POLYGON, x1, y1, x2, y2, rad);
1072
1073         if(menudeco) {
1074                 uiSetRoundBox(round & ~9);
1075                 BIF_ThemeColorShade(colorid, curshade-20);
1076                 gl_round_box(GL_POLYGON, x2-menudeco, y1, x2, y2, rad);
1077         }
1078         
1079         /* fake AA */
1080         uiSetRoundBox(round);
1081         glEnable( GL_BLEND );
1082         glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
1083
1084         BIF_GetThemeColor3ubv(colorid, col);
1085                 
1086         if(col[0]<100) col[0]= 0; else col[0]-= 100;
1087         if(col[1]<100) col[1]= 0; else col[1]-= 100;
1088         if(col[2]<100) col[2]= 0; else col[2]-= 100;
1089         col[3]= 80;
1090         glColor4ubv(col);
1091         gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, rad - asp);
1092         gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, rad + asp);
1093         col[3]= 180;
1094         glColor4ubv(col);
1095         gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, rad);
1096
1097         glDisable( GL_BLEND );
1098 }
1099
1100 /* button in midst of alignment row */
1101 static void round_button_mid(float x1, float y1, float x2, float y2, float asp, 
1102                                                          int colorid, int align, int menudeco, int curshade)
1103 {
1104         glRectf(x1, y1, x2, y2);
1105         
1106         if(menudeco) {
1107                 BIF_ThemeColorShade(colorid, curshade-20);
1108                 glRectf(x2-menudeco, y1, x2, y2);
1109         }
1110         
1111         BIF_ThemeColorBlendShade(colorid, TH_BACK, 0.5, -70);
1112         // we draw full outline, its not AA, and it works better button mouse-over hilite
1113         
1114         // left right
1115         fdrawline(x1, y1, x1, y2);
1116         fdrawline(x2, y1, x2, y2);
1117
1118         // top down
1119         fdrawline(x1, y2, x2, y2);
1120         fdrawline(x1, y1, x2, y1);   
1121 }
1122
1123 static void ui_draw_round(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1124 {
1125         int align= (flag & UI_BUT_ALIGN);
1126         int curshade= 0, menudeco= 0;
1127         
1128         if(type==ICONROW || type==ICONTEXTROW) menudeco= 9;
1129         else if((type==MENU || type==BLOCK) && x2-x1>24) menudeco= 16;
1130         
1131         /* paper */
1132         if(flag & UI_SELECT) {
1133                 if(flag & UI_ACTIVE) curshade= -40;
1134                 else curshade= -30;
1135         }
1136         else {
1137                 if(flag & UI_ACTIVE) curshade= 30;
1138                 else curshade= +20;
1139         }
1140         
1141         BIF_ThemeColorShade(colorid, curshade);
1142
1143         if(align) {
1144                 switch(align) {
1145                 case UI_BUT_ALIGN_TOP:
1146                         round_button(x1, y1, x2, y2, asp, colorid, 12, menudeco, curshade);
1147                         break;
1148                 case UI_BUT_ALIGN_DOWN:
1149                         round_button(x1, y1, x2, y2, asp, colorid, 3, menudeco, curshade);
1150                         break;
1151                 case UI_BUT_ALIGN_LEFT:
1152                         round_button(x1, y1, x2, y2, asp, colorid, 6, menudeco, curshade);
1153                         break;
1154                 case UI_BUT_ALIGN_RIGHT:
1155                         round_button(x1, y1, x2, y2, asp, colorid, 9, menudeco, curshade);
1156                         break;
1157                         
1158                 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT:
1159                         round_button(x1, y1, x2, y2, asp, colorid, 1, menudeco, curshade);
1160                         break;
1161                 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT:
1162                         round_button(x1, y1, x2, y2, asp, colorid, 2, menudeco, curshade);
1163                         break;
1164                 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_RIGHT:
1165                         round_button(x1, y1, x2, y2, asp, colorid, 8, menudeco, curshade);
1166                         break;
1167                 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_LEFT:
1168                         round_button(x1, y1, x2, y2, asp, colorid, 4, menudeco, curshade);
1169                         break;
1170                         
1171                 default:
1172                         round_button_mid(x1, y1, x2, y2, asp, colorid, align, menudeco, curshade);
1173                         break;
1174                 }
1175         } 
1176         else {
1177                 round_button(x1, y1, x2, y2, asp, colorid, 15, menudeco, curshade);
1178         }
1179
1180         /* special type decorations */
1181         switch(type) {
1182         case NUM:
1183                 BIF_ThemeColorShade(colorid, curshade-60);
1184                 ui_default_num_arrows(x1, y1, x2, y2);
1185                 break;
1186
1187         case ICONROW: 
1188         case ICONTEXTROW: 
1189                 BIF_ThemeColorShade(colorid, curshade-60);
1190                 ui_default_iconrow_arrows(x1, y1, x2, y2);
1191                 break;
1192                 
1193         case MENU: 
1194         case BLOCK: 
1195                 BIF_ThemeColorShade(colorid, curshade-60);
1196                 ui_default_menu_arrows(x1, y1, x2, y2);
1197                 break;
1198         }
1199 }
1200
1201 /* *************** MINIMAL THEME ***************** */
1202
1203 // theme can define an embosfunc and sliderfunc, text+icon drawing is standard, no theme.
1204
1205
1206
1207 /* super minimal button as used in logic menu */
1208 static void ui_draw_minimal(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1209 {
1210         
1211         x1+= asp;
1212         x2-= asp;
1213         y1+= asp;
1214         y2-= asp;
1215
1216         /* paper */
1217         if(flag & UI_SELECT) {
1218                 if(flag & UI_ACTIVE) BIF_ThemeColorShade(colorid, -40);
1219                 else BIF_ThemeColorShade(colorid, -30);
1220         }
1221         else {
1222                 if(flag & UI_ACTIVE) BIF_ThemeColorShade(colorid, +20);
1223                 else BIF_ThemeColorShade(colorid, +10);
1224         }
1225         
1226         glRectf(x1, y1, x2, y2);
1227
1228         if(flag & UI_SELECT) {
1229                 BIF_ThemeColorShade(colorid, -60);
1230
1231                 /* top */
1232                 fdrawline(x1, y2, x2, y2);
1233                 /* left */
1234                 fdrawline(x1, y1, x1, y2);
1235                 BIF_ThemeColorShade(colorid, +40);
1236
1237                 /* below */
1238                 fdrawline(x1, y1, x2, y1);
1239                 /* right */
1240                 fdrawline(x2, y1, x2, y2);
1241         }
1242         else {
1243                 BIF_ThemeColorShade(colorid, +40);
1244
1245                 /* top */
1246                 fdrawline(x1, y2, x2, y2);
1247                 /* left */
1248                 fdrawline(x1, y1, x1, y2);
1249                 
1250                 BIF_ThemeColorShade(colorid, -60);
1251                 /* below */
1252                 fdrawline(x1, y1, x2, y1);
1253                 /* right */
1254                 fdrawline(x2, y1, x2, y2);
1255         }
1256         
1257         /* special type decorations */
1258         switch(type) {
1259         case NUM:
1260                 if(flag & UI_SELECT) BIF_ThemeColorShade(colorid, -60);
1261                 else BIF_ThemeColorShade(colorid, -30);
1262                 ui_default_num_arrows(x1, y1, x2, y2);
1263                 break;
1264
1265         case ICONROW: 
1266         case ICONTEXTROW: 
1267                 if(flag & UI_ACTIVE) BIF_ThemeColorShade(colorid, 0);
1268                 else BIF_ThemeColorShade(colorid, -10);
1269                 glRectf(x2-9, y1+asp, x2-asp, y2-asp);
1270
1271                 BIF_ThemeColorShade(colorid, -50);
1272                 ui_default_iconrow_arrows(x1, y1, x2, y2);
1273                 break;
1274                 
1275         case MENU: 
1276         case BLOCK: 
1277                 if(flag & UI_ACTIVE) BIF_ThemeColorShade(colorid, 0);
1278                 else BIF_ThemeColorShade(colorid, -10);
1279                 glRectf(x2-17, y1+asp, x2-asp, y2-asp);
1280
1281                 BIF_ThemeColorShade(colorid, -50);
1282                 ui_default_menu_arrows(x1, y1, x2, y2);
1283                 break;
1284         }
1285         
1286         
1287 }
1288
1289
1290 /* fac is the slider handle position between x1 and x2 */
1291 static void ui_draw_slider(int colorid, float fac, float aspect, float x1, float y1, float x2, float y2, int flag)
1292 {
1293         float ymid, yc;
1294
1295         /* the slider background line */
1296         ymid= (y1+y2)/2.0;
1297         yc= 1.7*aspect; 
1298
1299         if(flag & UI_ACTIVE) 
1300                 BIF_ThemeColorShade(colorid, -50); 
1301         else 
1302                 BIF_ThemeColorShade(colorid, -40); 
1303
1304         /* left part */
1305         glRectf(x1, ymid-2.0*yc, x1+fac, ymid+2.0*yc);
1306         /* right part */
1307         glRectf(x1+fac, ymid-yc, x2, ymid+yc);
1308
1309         /* the movable slider */
1310         
1311         BIF_ThemeColorShade(colorid, +70); 
1312         glRectf(x1+fac-aspect, ymid-2.0*yc, x1+fac+aspect, ymid+2.0*yc);
1313
1314 }
1315
1316 /* ************** STANDARD MENU DRAWING FUNCTION ************* */
1317
1318
1319 static void ui_shadowbox(float minx, float miny, float maxx, float maxy, float shadsize, unsigned char alpha)
1320 {
1321         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1322         glEnable(GL_BLEND);
1323         glShadeModel(GL_SMOOTH);
1324         
1325         /* right quad */
1326         glBegin(GL_POLYGON);
1327         glColor4ub(0, 0, 0, alpha);
1328         glVertex2f(maxx, miny);
1329         glVertex2f(maxx, maxy-shadsize);
1330         glColor4ub(0, 0, 0, 0);
1331         glVertex2f(maxx+shadsize, maxy-shadsize-shadsize);
1332         glVertex2f(maxx+shadsize, miny);
1333         glEnd();
1334         
1335         /* corner shape */
1336         glBegin(GL_POLYGON);
1337         glColor4ub(0, 0, 0, alpha);
1338         glVertex2f(maxx, miny);
1339         glColor4ub(0, 0, 0, 0);
1340         glVertex2f(maxx+shadsize, miny);
1341         glVertex2f(maxx+0.7*shadsize, miny-0.7*shadsize);
1342         glVertex2f(maxx, miny-shadsize);
1343         glEnd();
1344         
1345         /* bottom quad */               
1346         glBegin(GL_POLYGON);
1347         glColor4ub(0, 0, 0, alpha);
1348         glVertex2f(minx+shadsize, miny);
1349         glVertex2f(maxx, miny);
1350         glColor4ub(0, 0, 0, 0);
1351         glVertex2f(maxx, miny-shadsize);
1352         glVertex2f(minx+shadsize+shadsize, miny-shadsize);
1353         glEnd();
1354         
1355         glDisable(GL_BLEND);
1356         glShadeModel(GL_FLAT);
1357 }
1358
1359 void uiDrawBoxShadow(unsigned char alpha, float minx, float miny, float maxx, float maxy)
1360 {
1361         /* accumulated outline boxes to make shade not linear, is more pleasant */
1362         ui_shadowbox(minx, miny, maxx, maxy, 6.0, (30*alpha)>>8);
1363         ui_shadowbox(minx, miny, maxx, maxy, 4.0, (70*alpha)>>8);
1364         ui_shadowbox(minx, miny, maxx, maxy, 2.0, (100*alpha)>>8);
1365         
1366 }
1367
1368 // background for pulldowns, pullups, and other drawing temporal menus....
1369 // has to be made themable still (now only color)
1370
1371 void uiDrawMenuBox(float minx, float miny, float maxx, float maxy, short flag)
1372 {
1373         char col[4];
1374         BIF_GetThemeColor4ubv(TH_MENU_BACK, col);
1375         
1376         if( (flag & UI_BLOCK_NOSHADOW)==0) {
1377                 /* accumulated outline boxes to make shade not linear, is more pleasant */
1378                 ui_shadowbox(minx, miny, maxx, maxy, 6.0, (30*col[3])>>8);
1379                 ui_shadowbox(minx, miny, maxx, maxy, 4.0, (70*col[3])>>8);
1380                 ui_shadowbox(minx, miny, maxx, maxy, 2.0, (100*col[3])>>8);
1381                 
1382                 glEnable(GL_BLEND);
1383                 glColor4ubv(col);
1384                 glRectf(minx-1, miny, minx, maxy);      // 1 pixel on left, to distinguish sublevel menus
1385         }
1386         glEnable(GL_BLEND);
1387         glColor4ubv(col);
1388         glRectf(minx, miny, maxx, maxy);
1389         glDisable(GL_BLEND);
1390 }
1391
1392
1393
1394 /* pulldown menu item */
1395 static void ui_draw_pulldown_item(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1396 {
1397         char col[4];
1398         
1399         BIF_GetThemeColor4ubv(TH_MENU_BACK, col);
1400         if(col[3]!=255) {
1401                 glEnable(GL_BLEND);
1402                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1403         }
1404         
1405         if((flag & UI_ACTIVE) && type!=LABEL) {
1406                 BIF_ThemeColor4(TH_MENU_HILITE);
1407                 glRectf(x1, y1, x2, y2);
1408         
1409
1410         } else {
1411                 BIF_ThemeColor4(colorid);       // is set at TH_MENU_ITEM when pulldown opened.
1412                 glRectf(x1, y1, x2, y2);
1413         }
1414
1415         glDisable(GL_BLEND);
1416 }
1417
1418 /* pulldown menu calling button */
1419 static void ui_draw_pulldown_round(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1420 {
1421         
1422         if(flag & UI_ACTIVE) {
1423                 BIF_ThemeColor(TH_MENU_HILITE);
1424
1425                 uiSetRoundBox(15);
1426                 gl_round_box(GL_POLYGON, x1, y1+3, x2, y2-3, 7.0);
1427
1428                 glEnable( GL_LINE_SMOOTH );
1429                 glEnable( GL_BLEND );
1430                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1431                 gl_round_box(GL_LINE_LOOP, x1, y1+3, x2, y2-3, 7.0);
1432                 glDisable( GL_LINE_SMOOTH );
1433                 glDisable( GL_BLEND );
1434                 
1435         } else {
1436                 BIF_ThemeColor(colorid);        // is set at TH_MENU_ITEM when pulldown opened.
1437                 glRectf(x1-1, y1+2, x2+1, y2-2);
1438         }
1439         
1440 }
1441
1442
1443 /* ************** TEXT AND ICON DRAWING FUNCTIONS ************* */
1444
1445
1446
1447 /* draws text and icons for buttons */
1448 static void ui_draw_text_icon(uiBut *but)
1449 {
1450         float x;
1451         int len;
1452         char *cpoin;
1453         short t, pos, ch;
1454         short selsta_tmp, selend_tmp, selsta_draw, selwidth_draw;
1455         
1456         /* check for button text label */
1457         if (but->type == ICONTEXTROW) {
1458                 ui_draw_icon(but, (BIFIconID) (but->icon+but->iconadd));
1459         }
1460         else {
1461
1462                 /* text button selection and cursor */
1463                 if(but->pos != -1) {
1464                 
1465                         if (SELWIDTH > 0) {
1466                                 /* text button selection */
1467                                 selsta_tmp = but->selsta + strlen(but->str);
1468                                 selend_tmp = but->selend + strlen(but->str);
1469                                 if (but->ofs >= strlen(but->str))
1470                                         selsta_tmp += (but->ofs - strlen(but->str));
1471                                         
1472                                 if(but->drawstr[0]!=0) {
1473                                         ch= but->drawstr[selsta_tmp];
1474                                         but->drawstr[selsta_tmp]= 0;
1475                                         
1476                                         selsta_draw = but->aspect*BIF_GetStringWidth(but->font, but->drawstr+but->ofs, (U.transopts & USER_TR_BUTTONS)) + 3;
1477                                         
1478                                         but->drawstr[selsta_tmp]= ch;
1479                                         
1480                                         
1481                                         ch= but->drawstr[selend_tmp];
1482                                         but->drawstr[selend_tmp]= 0;
1483                                         
1484                                         selwidth_draw = but->aspect*BIF_GetStringWidth(but->font, but->drawstr+but->ofs, (U.transopts & USER_TR_BUTTONS)) + 3;
1485                                         
1486                                         but->drawstr[selend_tmp]= ch;
1487                                         
1488                                         BIF_ThemeColor(TH_BUT_TEXTFIELD_HI);
1489                                         glRects(but->x1+selsta_draw+1, but->y1+2, but->x1+selwidth_draw+1, but->y2-2);
1490                                 }
1491                         } else {
1492                                 /* text cursor */
1493                                 pos= but->pos+strlen(but->str);
1494                                 if(pos >= but->ofs) {
1495                                         if(but->drawstr[0]!=0) {
1496                                                 ch= but->drawstr[pos];
1497                                                 but->drawstr[pos]= 0;
1498                         
1499                                                 t= but->aspect*BIF_GetStringWidth(but->font, but->drawstr+but->ofs, (U.transopts & USER_TR_BUTTONS)) + 3;
1500                                                 
1501                                                 but->drawstr[pos]= ch;
1502                                         }
1503                                         else t= 3;
1504                                         
1505                                         glColor3ub(255,0,0);
1506                                         glRects(but->x1+t, but->y1+2, but->x1+t+2, but->y2-2);
1507                                 }
1508                         }
1509                 }
1510                 if(but->drawstr[0]!=0) {
1511                         int transopts;
1512                         int tog3= 0;
1513                         
1514                         // cut string in 2 parts
1515                         cpoin= strchr(but->drawstr, '|');
1516                         if(cpoin) *cpoin= 0;
1517
1518                         /* If there's an icon too (made with uiDefIconTextBut) then draw the icon
1519                         and offset the text label to accomodate it */
1520                         
1521                         if ( (but->flag & UI_HAS_ICON) && (but->flag & UI_ICON_LEFT) ) {
1522                                 ui_draw_icon(but, but->icon);
1523
1524                                 if(but->flag & UI_TEXT_LEFT) x= but->x1 + BIF_icon_get_width(but->icon)+4.0;
1525                                 else x= (but->x1+but->x2-but->strwidth+1)/2.0;
1526                         }
1527                         else {
1528                                 if(but->flag & UI_TEXT_LEFT) x= but->x1+4.0;
1529                                 else x= (but->x1+but->x2-but->strwidth+1)/2.0;
1530                         }
1531                         
1532                         /* tog3 button exception; draws with glColor! */
1533                         if(but->type==TOG3 && (but->flag & UI_SELECT)) {
1534                                 
1535                                 if( but->pointype==CHA ) {
1536                                         if( BTST( *(but->poin+2), but->bitnr )) tog3= 1;
1537                                 }
1538                                 else if( but->pointype ==SHO ) {
1539                                         short *sp= (short *)but->poin;
1540                                         if( BTST( sp[1], but->bitnr )) tog3= 1;
1541                                 }
1542                                 
1543                                 ui_tog3_invert(but->x1,but->y1,but->x2,but->y2, tog3);
1544                                 if (tog3) glColor3ub(255, 255, 0);
1545                         }
1546                         
1547                         /* text color, with pulldown item exception */
1548                         if(tog3);       // color already set
1549                         else if(but->dt==UI_EMBOSSP) {
1550                                 if((but->flag & (UI_SELECT|UI_ACTIVE)) && but->type!=LABEL) {   // LABEL = title in pulldowns
1551                                         BIF_ThemeColor(TH_MENU_TEXT_HI);
1552                                 } else {
1553                                         BIF_ThemeColor(TH_MENU_TEXT);
1554                                 }
1555                         }
1556                         else {
1557                                 if(but->flag & UI_SELECT) {             
1558                                         BIF_ThemeColor(TH_BUT_TEXT_HI);
1559                                 } else {
1560                                         BIF_ThemeColor(TH_BUT_TEXT);
1561                                 }
1562                         }
1563
1564                         /* LABEL button exception */
1565                         if(but->type==LABEL && but->min!=0.0) BIF_ThemeColor(TH_BUT_TEXT_HI);
1566                 
1567                         ui_rasterpos_safe(x, (but->y1+but->y2- 9.0)/2.0, but->aspect);
1568                         if(but->type==TEX || but->type==IDPOIN) transopts= 0;   // no translation, of course!
1569                         else transopts= (U.transopts & USER_TR_BUTTONS);
1570                         BIF_DrawString(but->font, but->drawstr+but->ofs, transopts);
1571
1572                         /* part text right aligned */
1573                         if(cpoin) {
1574                                 len= BIF_GetStringWidth(but->font, cpoin+1, (U.transopts & USER_TR_BUTTONS));
1575                                 ui_rasterpos_safe( but->x2 - len*but->aspect-3, (but->y1+but->y2- 9.0)/2.0, but->aspect);
1576                                 BIF_DrawString(but->font, cpoin+1, (U.transopts & USER_TR_BUTTONS));
1577                                 *cpoin= '|';
1578                         }
1579                 }
1580                 /* if there's no text label, then check to see if there's an icon only and draw it */
1581                 else if( but->flag & UI_HAS_ICON ) {
1582                         ui_draw_icon(but, (BIFIconID) (but->icon+but->iconadd));
1583                 }
1584         }
1585 }
1586
1587 static void ui_draw_but_COL(uiBut *but)
1588 {
1589         float *fp;
1590         char colr, colg, colb;
1591         
1592         if( but->pointype==FLO ) {
1593                 fp= (float *)but->poin;
1594                 colr= floor(255.0*fp[0]+0.5);
1595                 colg= floor(255.0*fp[1]+0.5);
1596                 colb= floor(255.0*fp[2]+0.5);
1597         }
1598         else {
1599                 char *cp= (char *)but->poin;
1600                 colr= cp[0];
1601                 colg= cp[1];
1602                 colb= cp[2];
1603         }
1604         
1605         /* exception... hrms, but can't simply use the emboss callback for this now. */
1606         /* this button type needs review, and nice integration with rest of API here */
1607         if(but->embossfunc == ui_draw_round) {
1608                 char *cp= BIF_ThemeGetColorPtr(U.themes.first, 0, TH_CUSTOM);
1609                 cp[0]= colr; cp[1]= colg; cp[2]= colb;
1610                 but->flag &= ~UI_SELECT;
1611                 but->embossfunc(but->type, TH_CUSTOM, but->aspect, but->x1, but->y1, but->x2, but->y2, but->flag);
1612         }
1613         else {
1614                 
1615                 glColor3ub(colr,  colg,  colb);
1616                 glRectf((but->x1), (but->y1), (but->x2), (but->y2));
1617                 glColor3ub(0,  0,  0);
1618                 fdrawbox((but->x1), (but->y1), (but->x2), (but->y2));
1619         }
1620 }
1621
1622 /* draws in resolution of 20x4 colors */
1623 static void ui_draw_but_HSVCUBE(uiBut *but)
1624 {
1625         int a;
1626         float h,s,v;
1627         float dx, dy, sx1, sx2, sy, x, y;
1628         float col0[4][3];       // left half, rect bottom to top
1629         float col1[4][3];       // right half, rect bottom to top
1630         
1631         h= but->hsv[0];
1632         s= but->hsv[1];
1633         v= but->hsv[2];
1634         
1635         /* draw series of gouraud rects */
1636         glShadeModel(GL_SMOOTH);
1637         
1638         if(but->a1==0) {        // H and V vary
1639                 hsv_to_rgb(0.0, s, 0.0,   &col1[0][0], &col1[0][1], &col1[0][2]);
1640                 hsv_to_rgb(0.0, s, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]);
1641                 hsv_to_rgb(0.0, s, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]);
1642                 hsv_to_rgb(0.0, s, 1.0,   &col1[3][0], &col1[3][1], &col1[3][2]);
1643                 x= h; y= v;
1644         }
1645         else if(but->a1==1) {   // H and S vary
1646                 hsv_to_rgb(0.0, 0.0, v,   &col1[0][0], &col1[0][1], &col1[0][2]);
1647                 hsv_to_rgb(0.0, 0.333, v, &col1[1][0], &col1[1][1], &col1[1][2]);
1648                 hsv_to_rgb(0.0, 0.666, v, &col1[2][0], &col1[2][1], &col1[2][2]);
1649                 hsv_to_rgb(0.0, 1.0, v,   &col1[3][0], &col1[3][1], &col1[3][2]);
1650                 x= h; y= s;
1651         }
1652         else if(but->a1==2) {   // S and V vary
1653                 hsv_to_rgb(h, 0.0, 0.0,   &col1[0][0], &col1[0][1], &col1[0][2]);
1654                 hsv_to_rgb(h, 0.333, 0.0, &col1[1][0], &col1[1][1], &col1[1][2]);
1655                 hsv_to_rgb(h, 0.666, 0.0, &col1[2][0], &col1[2][1], &col1[2][2]);
1656                 hsv_to_rgb(h, 1.0, 0.0,   &col1[3][0], &col1[3][1], &col1[3][2]);
1657                 x= v; y= s;
1658         }
1659         else {          // only hue slider
1660                 hsv_to_rgb(0.0, 1.0, 1.0,   &col1[0][0], &col1[0][1], &col1[0][2]);
1661                 VECCOPY(col1[1], col1[0]);
1662                 VECCOPY(col1[2], col1[0]);
1663                 VECCOPY(col1[3], col1[0]);
1664                 x= h; y= 0.5;
1665         }
1666         
1667         for(dx=0.0; dx<1.0; dx+= 0.05) {
1668                 // previous color
1669                 VECCOPY(col0[0], col1[0]);
1670                 VECCOPY(col0[1], col1[1]);
1671                 VECCOPY(col0[2], col1[2]);
1672                 VECCOPY(col0[3], col1[3]);
1673
1674                 // new color
1675                 if(but->a1==0) {        // H and V vary
1676                         hsv_to_rgb(dx, s, 0.0,   &col1[0][0], &col1[0][1], &col1[0][2]);
1677                         hsv_to_rgb(dx, s, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]);
1678                         hsv_to_rgb(dx, s, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]);
1679                         hsv_to_rgb(dx, s, 1.0,   &col1[3][0], &col1[3][1], &col1[3][2]);
1680                 }
1681                 else if(but->a1==1) {   // H and S vary
1682                         hsv_to_rgb(dx, 0.0, v,   &col1[0][0], &col1[0][1], &col1[0][2]);
1683                         hsv_to_rgb(dx, 0.333, v, &col1[1][0], &col1[1][1], &col1[1][2]);
1684                         hsv_to_rgb(dx, 0.666, v, &col1[2][0], &col1[2][1], &col1[2][2]);
1685                         hsv_to_rgb(dx, 1.0, v,   &col1[3][0], &col1[3][1], &col1[3][2]);
1686                 }
1687                 else if(but->a1==2) {   // S and V vary
1688                         hsv_to_rgb(h, 0.0, dx,   &col1[0][0], &col1[0][1], &col1[0][2]);
1689                         hsv_to_rgb(h, 0.333, dx, &col1[1][0], &col1[1][1], &col1[1][2]);
1690                         hsv_to_rgb(h, 0.666, dx, &col1[2][0], &col1[2][1], &col1[2][2]);
1691                         hsv_to_rgb(h, 1.0, dx,   &col1[3][0], &col1[3][1], &col1[3][2]);
1692                 }
1693                 else {  // only H
1694                         hsv_to_rgb(dx, 1.0, 1.0,   &col1[0][0], &col1[0][1], &col1[0][2]);
1695                         VECCOPY(col1[1], col1[0]);
1696                         VECCOPY(col1[2], col1[0]);
1697                         VECCOPY(col1[3], col1[0]);
1698                 }
1699                 
1700                 // rect
1701                 sx1= but->x1 + dx*(but->x2-but->x1);
1702                 sx2= but->x1 + (dx+0.05)*(but->x2-but->x1);
1703                 sy= but->y1;
1704                 dy= (but->y2-but->y1)/3.0;
1705                 
1706                 glBegin(GL_QUADS);
1707                 for(a=0; a<3; a++, sy+=dy) {
1708                         glColor3fv(col0[a]);
1709                         glVertex2f(sx1, sy);
1710
1711                         glColor3fv(col1[a]);
1712                         glVertex2f(sx2, sy);
1713                         
1714                         glColor3fv(col1[a+1]);
1715                         glVertex2f(sx2, sy+dy);
1716                         
1717                         glColor3fv(col0[a+1]);
1718                         glVertex2f(sx1, sy+dy);
1719                 }
1720                 glEnd();
1721         }
1722
1723         glShadeModel(GL_FLAT);
1724
1725         /* cursor */
1726         x= but->x1 + x*(but->x2-but->x1);
1727         y= but->y1 + y*(but->y2-but->y1);
1728         CLAMP(x, but->x1+3.0, but->x2-3.0);
1729         CLAMP(y, but->y1+3.0, but->y2-3.0);
1730         
1731         fdrawXORcirc(x, y, 3.1);
1732
1733         /* outline */
1734         glColor3ub(0,  0,  0);
1735         fdrawbox((but->x1), (but->y1), (but->x2), (but->y2));
1736 }
1737
1738 #ifdef INTERNATIONAL
1739 static void ui_draw_but_CHARTAB(uiBut *but)
1740 {
1741         /* Some local variables */
1742         float sx, sy, ex, ey;
1743         float width, height;
1744         float butw, buth;
1745         int x, y, cs;
1746         wchar_t wstr[2];
1747         unsigned char ustr[16];
1748         PackedFile *pf;
1749         int result = 0;
1750
1751         /* Calculate the size of the button */
1752         width = abs(but->x2 - but->x1);
1753         height = abs(but->y2 - but->y1);
1754         
1755         butw = floor(width / 12);
1756         buth = floor(height / 6);
1757         
1758         /* Initialize variables */
1759         sx = but->x1;
1760         ex = but->x1 + butw;
1761         sy = but->y1 + height - buth;
1762         ey = but->y1 + height;
1763
1764         cs = G.charstart;
1765
1766         /* Set the font */
1767         if(G.selfont && strcmp(G.selfont->name, "<builtin>"))
1768         {
1769                 char tmpStr[256];
1770
1771                 // Is the font file packed, if so then use the packed file
1772                 if(G.selfont->packedfile)
1773                 {
1774                         pf = G.selfont->packedfile;             
1775                         FTF_SetFont(pf->data, pf->size, 14.0);
1776                 }
1777                 else
1778                 {
1779                         int err;
1780
1781                         strcpy(tmpStr, G.selfont->name);
1782                         BLI_convertstringcode(tmpStr, G.sce, 0);
1783                         err = FTF_SetFont(tmpStr, 0, 14.0);
1784                 }
1785         }
1786
1787         /* Start drawing the button itself */
1788         glShadeModel(GL_SMOOTH);
1789
1790         glColor3ub(200,  200,  200);
1791         glRectf((but->x1), (but->y1), (but->x2), (but->y2));
1792
1793         glColor3ub(0,  0,  0);
1794         for(y = 0; y < 6; y++)
1795         {
1796                 // Do not draw more than the category allows
1797                 if(cs > G.charmax) break;
1798
1799                 for(x = 0; x < 12; x++)
1800                 {
1801                         // Do not draw more than the category allows
1802                         if(cs > G.charmax) break;
1803
1804                         // Draw one grid cell
1805                         glBegin(GL_LINE_LOOP);
1806                                 glVertex2f(sx, sy);
1807                                 glVertex2f(ex, sy);
1808                                 glVertex2f(ex, ey);
1809                                 glVertex2f(sx, ey);                             
1810                         glEnd();        
1811
1812                         // Draw character inside the cell
1813                         memset(wstr, 0, sizeof(wchar_t)*2);
1814                         memset(ustr, 0, 16);
1815                         
1816                         wstr[0] = cs;
1817                         wcs2utf8s(ustr, wstr);
1818
1819                         if(G.selfont && strcmp(G.selfont->name, "<builtin>"))
1820                         {
1821                                 float wid;
1822                                 float llx, lly, llz, urx, ury, urz;
1823                                 float dx, dy;
1824                                 float px, py;
1825         
1826                                 // Calculate the position
1827                                 wid = FTF_GetStringWidth(ustr, FTF_USE_GETTEXT | FTF_INPUT_UTF8);
1828                                 FTF_GetBoundingBox(ustr, &llx,&lly,&llz,&urx,&ury,&urz, FTF_USE_GETTEXT | FTF_INPUT_UTF8);
1829                                 dx = urx-llx;
1830                                 dy = ury-lly;
1831
1832                                 // This isn't fully functional since the but->aspect isn't working like I suspected
1833                                 px = sx + ((butw/but->aspect)-dx)/2;
1834                                 py = sy + ((buth/but->aspect)-dy)/2;
1835
1836                                 // Set the position and draw the character
1837                                 ui_rasterpos_safe(px, py, but->aspect);
1838                                 FTF_DrawString(ustr, FTF_USE_GETTEXT | FTF_INPUT_UTF8);
1839                         }
1840                         else
1841                         {
1842                                 ui_rasterpos_safe(sx + butw/2, sy + buth/2, but->aspect);
1843                                 BIF_DrawString(but->font, ustr, 0);
1844                         }
1845         
1846                         // Calculate the next position and character
1847                         sx += butw; ex +=butw;
1848                         cs++;
1849                 }
1850                 /* Add the y position and reset x position */
1851                 sy -= buth; 
1852                 ey -= buth;
1853                 sx = but->x1;
1854                 ex = but->x1 + butw;
1855         }       
1856         glShadeModel(GL_FLAT);
1857
1858         /* Return Font Settings to original */
1859         if(U.fontsize && U.fontname[0])
1860         {
1861                 result = FTF_SetFont(U.fontname, 0, U.fontsize);
1862         }
1863         else if (U.fontsize)
1864         {
1865                 result = FTF_SetFont(datatoc_bfont_ttf, datatoc_bfont_ttf_size, U.fontsize);
1866         }
1867
1868         if (result == 0)
1869         {
1870                 result = FTF_SetFont(datatoc_bfont_ttf, datatoc_bfont_ttf_size, 11);
1871         }
1872 }
1873
1874 #endif // INTERNATIONAL
1875
1876 static void ui_draw_roundbox(uiBut *but)
1877 {
1878         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1879         glEnable(GL_BLEND);
1880         
1881         BIF_ThemeColorShadeAlpha(TH_PANEL, but->a2, but->a2);
1882
1883         uiSetRoundBox(but->a1);
1884         gl_round_box(GL_POLYGON, but->x1, but->y1, but->x2, but->y2, but->min);
1885
1886         glDisable(GL_BLEND);
1887 }
1888
1889
1890 /* nothing! */
1891 static void ui_draw_nothing(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1892 {
1893 }
1894
1895
1896 /* ************** EXTERN, called from interface.c ************* */
1897 /* ************** MAIN CALLBACK FUNCTION          ************* */
1898
1899 void ui_set_embossfunc(uiBut *but, int drawtype)
1900 {
1901         // this aded for evaluating textcolor for example
1902         but->dt= drawtype;
1903         
1904         // not really part of standard minimal themes, just make sure it is set
1905         but->sliderfunc= ui_draw_slider;
1906
1907         // standard builtin first:
1908         if(but->type==LABEL || but->type==ROUNDBOX) but->embossfunc= ui_draw_nothing;
1909         else if(but->type==PULLDOWN) but->embossfunc= ui_draw_pulldown_round;
1910         else if(drawtype==UI_EMBOSSM) but->embossfunc= ui_draw_minimal;
1911         else if(drawtype==UI_EMBOSSN) but->embossfunc= ui_draw_nothing;
1912         else if(drawtype==UI_EMBOSSP) but->embossfunc= ui_draw_pulldown_item;
1913         else if(drawtype==UI_EMBOSSR) but->embossfunc= ui_draw_round;
1914         else {
1915                 int theme= BIF_GetThemeValue(TH_BUT_DRAWTYPE);
1916                 
1917                 // and the themes
1918                 if(theme==1) {
1919                         but->embossfunc= ui_draw_default;
1920                         but->sliderfunc= ui_default_slider;
1921                 }
1922                 else if(theme==2) {
1923                         but->embossfunc= ui_draw_round;
1924                 }
1925                 else if(theme==3) {
1926                         but->embossfunc= ui_draw_oldskool;
1927                 }
1928                 else {
1929                         but->embossfunc= ui_draw_minimal;
1930                 }
1931         }
1932         
1933         // note: if you want aligning, adapt the call uiBlockEndAlign in interface.c 
1934 }
1935
1936 void ui_draw_but(uiBut *but)
1937 {
1938         double value;
1939         float x1, x2, y1, y2, fac;
1940         
1941         if(but==NULL) return;
1942
1943         /* signal for frontbuf flush buttons and menus, not when normal drawing */
1944         if(but->block->in_use) ui_block_set_flush(but->block, but);
1945                 
1946         switch (but->type) {
1947
1948         case NUMSLI:
1949         case HSVSLI:
1950         
1951                 but->embossfunc(but->type, but->themecol, but->aspect, but->x1, but->y1, but->x2, but->y2, but->flag);
1952                 ui_draw_text_icon(but);
1953
1954                 x1= (but->x1+but->x2)/2;
1955                 x2= but->x2 - 5.0*but->aspect;
1956                 y1= but->y1 + 2.0*but->aspect;
1957                 y2= but->y2 - 2.0*but->aspect;
1958                 
1959                 value= ui_get_but_val(but);
1960                 fac= (value-but->min)*(x2-x1)/(but->max - but->min);
1961                 
1962                 but->sliderfunc(but->themecol, fac, but->aspect, x1, y1, x2, y2, but->flag);
1963                 break;
1964                 
1965         case SEPR:
1966                 //  only background
1967                 break;
1968                 
1969         case COL:
1970                 ui_draw_but_COL(but);  // black box with color
1971                 break;
1972
1973         case HSVCUBE:
1974                 ui_draw_but_HSVCUBE(but);  // box for colorpicker, three types
1975                 break;
1976
1977 #ifdef INTERNATIONAL
1978         case CHARTAB:
1979                 value= ui_get_but_val(but);
1980                 ui_draw_but_CHARTAB(but);
1981                 break;
1982 #endif
1983
1984         case LINK:
1985         case INLINK:
1986                 ui_draw_icon(but, but->icon);
1987                 break;
1988                 
1989         case ROUNDBOX:
1990                 ui_draw_roundbox(but);
1991
1992         default:
1993                 but->embossfunc(but->type, but->themecol, but->aspect, but->x1, but->y1, but->x2, but->y2, but->flag);
1994                 ui_draw_text_icon(but);
1995         
1996         }
1997 }
1998