NLA - Bugfix:
[blender.git] / source / blender / src / interface_draw.c
1
2 /**
3  * $Id$
4  *
5  * ***** BEGIN GPL 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.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software Foundation,
19  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20  *
21  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
22  * All rights reserved.
23  *
24  * The Original Code is: all of this file.
25  *
26  * Contributor(s): none yet.
27  *
28  * ***** END GPL LICENSE BLOCK *****
29  */
30
31 /* 
32      a full doc with API notes can be found in bf-blender/blender/doc/interface_API.txt
33
34  */
35  
36
37 #include <math.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <ctype.h>
41
42 #ifndef WIN32
43 #include <unistd.h>
44 #else
45 #include <io.h>
46 #endif   
47
48 #include "MEM_guardedalloc.h"
49
50 #include "PIL_time.h"
51
52 #include "BLI_blenlib.h"
53 #include "BLI_arithb.h"
54
55 #include "DNA_color_types.h"
56 #include "DNA_key_types.h"
57 #include "DNA_packedFile_types.h"
58 #include "DNA_screen_types.h"
59 #include "DNA_space_types.h"
60 #include "DNA_texture_types.h"
61 #include "DNA_userdef_types.h"
62 #include "DNA_vec_types.h"
63 #include "DNA_vfont_types.h"
64
65 #include "BKE_blender.h"
66 #include "BKE_colortools.h"
67 #include "BKE_font.h"
68 #include "BKE_global.h"
69 #include "BKE_key.h"
70 #include "BKE_utildefines.h"
71
72 #include "datatoc.h"            /* std font */
73
74 #include "BIF_gl.h"
75 #include "BIF_graphics.h"
76 #include "BIF_keyval.h"
77 #include "BIF_mainqueue.h"
78
79 #include "BIF_screen.h"
80 #include "BIF_toolbox.h"
81 #include "BIF_mywindow.h"
82 #include "BIF_space.h"
83 #include "BIF_glutil.h"
84 #include "BIF_interface.h"
85 #include "BIF_interface_icons.h"
86 #include "BIF_butspace.h"
87 #include "BIF_language.h"
88
89 #include "BSE_view.h"
90
91 #ifdef INTERNATIONAL
92 #include "FTF_Api.h"
93 #endif
94
95 #include "mydevice.h"
96 #include "interface.h"
97 #include "blendef.h"
98
99 // globals
100 extern float UIwinmat[4][4];
101
102
103 /* ************** safe rasterpos for pixmap alignment with pixels ************* */
104
105 void ui_rasterpos_safe(float x, float y, float aspect)
106 {
107         float vals[4], remainder;
108         int doit=0;
109         
110         glRasterPos2f(x, y);
111         glGetFloatv(GL_CURRENT_RASTER_POSITION, vals);
112
113         remainder= vals[0] - floor(vals[0]);
114         if(remainder > 0.4 && remainder < 0.6) {
115                 if(remainder < 0.5) x -= 0.1*aspect;
116                 else x += 0.1*aspect;
117                 doit= 1;
118         }
119         remainder= vals[1] - floor(vals[1]);
120         if(remainder > 0.4 && remainder < 0.6) {
121                 if(remainder < 0.5) y -= 0.1*aspect;
122                 else y += 0.1*aspect;
123                 doit= 1;
124         }
125         
126         if(doit) glRasterPos2f(x, y);
127
128         BIF_RasterPos(x, y);
129         BIF_SetScale(aspect);
130 }
131
132 /* ************** generic embossed rect, for window sliders etc ************* */
133
134 void uiEmboss(float x1, float y1, float x2, float y2, int sel)
135 {
136         
137         /* below */
138         if(sel) glColor3ub(200,200,200);
139         else glColor3ub(50,50,50);
140         fdrawline(x1, y1, x2, y1);
141
142         /* right */
143         fdrawline(x2, y1, x2, y2);
144         
145         /* top */
146         if(sel) glColor3ub(50,50,50);
147         else glColor3ub(200,200,200);
148         fdrawline(x1, y2, x2, y2);
149
150         /* left */
151         fdrawline(x1, y1, x1, y2);
152         
153 }
154
155 /* ************** GENERIC ICON DRAW, NO THEME HERE ************* */
156
157 /* icons have been standardized... and this call draws in untransformed coordinates */
158 #define ICON_HEIGHT             16.0f
159
160 static void ui_draw_icon(uiBut *but, BIFIconID icon, int blend)
161 {
162         float xs=0, ys=0, aspect, height;
163
164         /* this icon doesn't need draw... */
165         if(icon==ICON_BLANK1) return;
166         
167         /* we need aspect from block, for menus... these buttons are scaled in uiPositionBlock() */
168         aspect= but->block->aspect;
169         if(aspect != but->aspect) {
170                 /* prevent scaling up icon in pupmenu */
171                 if (aspect < 1.0f) {                    
172                         height= ICON_HEIGHT;
173                         aspect = 1.0f;
174                         
175                 }
176                 else 
177                         height= ICON_HEIGHT/aspect;
178         }
179         else
180                 height= ICON_HEIGHT;
181         
182         if(but->flag & UI_ICON_LEFT) {
183                 if (but->type==BUT_TOGDUAL && but->drawstr[0]) {
184                         xs= but->x1-1.0;
185                 }
186                 else if (but->type==BUTM ) {
187                         xs= but->x1+1.0;
188                 }
189                 else if ((but->type==ICONROW) || (but->type==ICONTEXTROW)) {
190                         xs= but->x1+3.0;
191                 }
192                 else {
193                         xs= but->x1+4.0;
194                 }
195                 ys= (but->y1+but->y2- height)/2.0;
196         }
197         if(but->flag & UI_ICON_RIGHT) {
198                 xs= but->x2-17.0;
199                 ys= (but->y1+but->y2- height)/2.0;
200         }
201         if (!((but->flag & UI_ICON_RIGHT) || (but->flag & UI_ICON_LEFT))) {
202                 xs= (but->x1+but->x2- height)/2.0;
203                 ys= (but->y1+but->y2- height)/2.0;
204         }
205
206         glEnable(GL_BLEND);
207
208         /* calculate blend color */
209         if ELEM3(but->type, TOG, ROW, TOGN) {
210                 if(but->flag & UI_SELECT);
211                 else if(but->flag & UI_ACTIVE);
212                 else blend= -60;
213         }
214         BIF_icon_draw_aspect_blended(xs, ys, icon, aspect, blend);
215         
216         glDisable(GL_BLEND);
217
218 }
219
220
221 /* ************** DEFAULT THEME, SHADED BUTTONS ************* */
222
223
224 #define M_WHITE         BIF_ThemeColorShade(colorid, 80)
225
226 #define M_ACT_LIGHT     BIF_ThemeColorShade(colorid, 55)
227 #define M_LIGHT         BIF_ThemeColorShade(colorid, 45)
228 #define M_HILITE        BIF_ThemeColorShade(colorid, 25)
229 #define M_LMEDIUM       BIF_ThemeColorShade(colorid, 10)
230 #define M_MEDIUM        BIF_ThemeColor(colorid)
231 #define M_LGREY         BIF_ThemeColorShade(colorid, -20)
232 #define M_GREY          BIF_ThemeColorShade(colorid, -45)
233 #define M_DARK          BIF_ThemeColorShade(colorid, -80)
234
235 #define M_NUMTEXT                               BIF_ThemeColorShade(colorid, 25)
236 #define M_NUMTEXT_ACT_LIGHT             BIF_ThemeColorShade(colorid, 35)
237
238 #define MM_WHITE        BIF_ThemeColorShade(TH_BUT_NEUTRAL, 120)
239
240 /* Used for the subtle sunken effect around buttons.
241  * One option is to hardcode to white, with alpha, however it causes a 
242  * weird 'building up' efect, so it's commented out for now.
243  */
244  
245 /*
246 #define MM_WHITE_OP     glColor4ub(255, 255, 255, 60)
247 #define MM_WHITE_TR     glColor4ub(255, 255, 255, 0)
248  */
249
250 #define MM_WHITE_OP     BIF_ThemeColorShadeAlpha(TH_BACK, 55, -100)
251 #define MM_WHITE_TR     BIF_ThemeColorShadeAlpha(TH_BACK, 55, -255)
252
253 #define MM_LIGHT        BIF_ThemeColorShade(TH_BUT_OUTLINE, 45)
254 #define MM_MEDIUM       BIF_ThemeColor(TH_BUT_OUTLINE)
255 #define MM_GREY         BIF_ThemeColorShade(TH_BUT_OUTLINE, -45)
256 #define MM_DARK         BIF_ThemeColorShade(TH_BUT_OUTLINE, -80)
257
258 /* base shaded button */
259 static void shaded_button(float x1, float y1, float x2, float y2, float asp, int colorid, int flag, int mid)
260 {
261         /* 'mid' arg determines whether the button is in the middle of
262          * an alignment group or not. 0 = not middle, 1 = is in the middle.
263          * Done to allow cleaner drawing
264          */
265          
266         /* *** SHADED BUTTON BASE *** */
267         glShadeModel(GL_SMOOTH);
268         glBegin(GL_QUADS);
269         
270         if(flag & UI_SELECT) {
271                 if(flag & UI_ACTIVE) M_MEDIUM;
272                 else M_LGREY;
273         } else {
274                 if(flag & UI_ACTIVE) M_LIGHT;
275                 else M_HILITE;
276         }
277
278         glVertex2f(x1,y1);
279         glVertex2f(x2,y1);
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(x2,(y2-(y2-y1)/3));
290         glVertex2f(x1,(y2-(y2-y1)/3));
291         glEnd();
292         
293
294         glShadeModel(GL_FLAT);
295         glBegin(GL_QUADS);
296         
297         if(flag & UI_SELECT) {
298                 if(flag & UI_ACTIVE) M_LGREY;
299                 else M_GREY;
300         } else {
301                 if(flag & UI_ACTIVE) M_ACT_LIGHT;
302                 else M_LIGHT;
303         }
304         
305         glVertex2f(x1,(y2-(y2-y1)/3));
306         glVertex2f(x2,(y2-(y2-y1)/3));
307         glVertex2f(x2,y2);
308         glVertex2f(x1,y2);
309
310         glEnd();
311         /* *** END SHADED BUTTON BASE *** */
312         
313         /* *** INNER OUTLINE *** */
314         /* left */
315         if(!(flag & UI_SELECT)) {
316                 glShadeModel(GL_SMOOTH);
317                 glBegin(GL_LINES);
318                 M_MEDIUM;
319                 glVertex2f(x1+1,y1+2);
320                 M_WHITE;
321                 glVertex2f(x1+1,y2);
322                 glEnd();
323         }
324         
325         /* right */
326                 if(!(flag & UI_SELECT)) {
327                 glShadeModel(GL_SMOOTH);
328                 glBegin(GL_LINES);
329                 M_MEDIUM;
330                 glVertex2f(x2-1,y1+2);
331                 M_WHITE;
332                 glVertex2f(x2-1,y2);
333                 glEnd();
334         }
335         
336         glShadeModel(GL_FLAT);
337         
338         /* top */
339         if(flag & UI_SELECT) {
340                 if(flag & UI_ACTIVE) M_LGREY;
341                 else M_GREY;
342         } else {
343                 if(flag & UI_ACTIVE) M_WHITE;
344                 else M_WHITE;
345         }
346
347         fdrawline(x1, (y2-1), x2, (y2-1));
348         
349         /* bottom */
350         if(flag & UI_SELECT) {
351                 if(flag & UI_ACTIVE) M_MEDIUM;
352                 else M_LGREY;
353         } else {
354                 if(flag & UI_ACTIVE) M_LMEDIUM;
355                 else M_MEDIUM;
356         }
357         fdrawline(x1, (y1+1), x2, (y1+1));
358         /* *** END INNER OUTLINE *** */
359         
360         /* *** OUTER OUTLINE *** */
361         if (mid) {
362                 // we draw full outline, its not AA, and it works better button mouse-over hilite
363                 MM_DARK;
364                 
365                 // left right
366                 fdrawline(x1, y1, x1, y2);
367                 fdrawline(x2, y1, x2, y2);
368         
369                 // top down
370                 fdrawline(x1, y2, x2, y2);
371                 fdrawline(x1, y1, x2, y1); 
372         } else {
373                 MM_DARK;
374                 gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, 1.5);
375         }
376         /* END OUTER OUTLINE */
377 }
378
379 /* base flat button */
380 static void flat_button(float x1, float y1, float x2, float y2, float asp, int colorid, int flag, int mid)
381 {
382         /* 'mid' arg determines whether the button is in the middle of
383          * an alignment group or not. 0 = not middle, 1 = is in the middle.
384          * Done to allow cleaner drawing
385          */
386          
387         /* *** FLAT TEXT/NUM FIELD *** */
388         glShadeModel(GL_FLAT);
389         if(flag & UI_SELECT) {
390                 if(flag & UI_ACTIVE) M_LGREY;
391                 else M_GREY;
392         }
393         else {
394                 if(flag & UI_ACTIVE) M_NUMTEXT_ACT_LIGHT;
395                 else M_NUMTEXT;
396         }
397
398         glRectf(x1, y1, x2, y2);
399         /* *** END FLAT TEXT/NUM FIELD *** */
400         
401         /* *** OUTER OUTLINE *** */
402         if (mid) {
403                 // we draw full outline, its not AA, and it works better button mouse-over hilite
404                 MM_DARK;
405                 
406                 // left right
407                 fdrawline(x1, y1, x1, y2);
408                 fdrawline(x2, y1, x2, y2);
409         
410                 // top down
411                 fdrawline(x1, y2, x2, y2);
412                 fdrawline(x1, y1, x2, y1); 
413         } else {
414                 MM_DARK;
415                 gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, 1.5);
416         }
417         /* END OUTER OUTLINE */
418 }
419
420 /* small side double arrow for iconrow */
421 static void ui_default_iconrow_arrows(float x1, float y1, float x2, float y2)
422 {
423         glEnable( GL_POLYGON_SMOOTH );
424         glEnable( GL_BLEND );
425         
426         glShadeModel(GL_FLAT);
427         glBegin(GL_TRIANGLES);
428         glVertex2f((short)x2-2,(short)(y2-(y2-y1)/2)+1);
429         glVertex2f((short)x2-6,(short)(y2-(y2-y1)/2)+1);
430         glVertex2f((short)x2-4,(short)(y2-(y2-y1)/2)+4);
431         glEnd();
432                 
433         glBegin(GL_TRIANGLES);
434         glVertex2f((short)x2-2,(short)(y2-(y2-y1)/2) -1);
435         glVertex2f((short)x2-6,(short)(y2-(y2-y1)/2) -1);
436         glVertex2f((short)x2-4,(short)(y2-(y2-y1)/2) -4);
437         glEnd();
438         
439         glDisable( GL_BLEND );
440         glDisable( GL_POLYGON_SMOOTH );
441 }
442
443 /* side double arrow for menu */
444 static void ui_default_menu_arrows(float x1, float y1, float x2, float y2)
445 {
446         glEnable( GL_POLYGON_SMOOTH );
447         glEnable( GL_BLEND );
448         
449         glShadeModel(GL_FLAT);
450         glBegin(GL_TRIANGLES);
451         glVertex2f((short)x2-4,(short)(y2-(y2-y1)/2)+1);
452         glVertex2f((short)x2-12,(short)(y2-(y2-y1)/2)+1);
453         glVertex2f((short)x2-8,(short)(y2-(y2-y1)/2)+4);
454         glEnd();
455                 
456         glBegin(GL_TRIANGLES);
457         glVertex2f((short)x2-4,(short)(y2-(y2-y1)/2) -1);
458         glVertex2f((short)x2-12,(short)(y2-(y2-y1)/2) -1);
459         glVertex2f((short)x2-8,(short)(y2-(y2-y1)/2) -4);
460         glEnd();
461         
462         glDisable( GL_BLEND );
463         glDisable( GL_POLYGON_SMOOTH );
464 }
465
466 /* left/right arrows for number fields */
467 static void ui_default_num_arrows(float x1, float y1, float x2, float y2)
468 {
469         if( x2-x1 > 25) {       // 25 is a bit arbitrary, but small buttons cant have arrows
470
471                 glEnable( GL_POLYGON_SMOOTH );
472                 glEnable( GL_BLEND );
473                 
474                 glShadeModel(GL_FLAT);
475                 glBegin(GL_TRIANGLES);
476                 
477                 glVertex2f((short)x1+5,(short)(y2-(y2-y1)/2));
478                 glVertex2f((short)x1+10,(short)(y2-(y2-y1)/2)+4);
479                 glVertex2f((short)x1+10,(short)(y2-(y2-y1)/2)-4);
480                 glEnd();
481
482                 /* right */
483                 glShadeModel(GL_FLAT);
484                 glBegin(GL_TRIANGLES);
485
486                 glVertex2f((short)x2-5,(short)(y2-(y2-y1)/2));
487                 glVertex2f((short)x2-10,(short)(y2-(y2-y1)/2)-4);
488                 glVertex2f((short)x2-10,(short)(y2-(y2-y1)/2)+4);
489                 glEnd();
490                 
491                 glDisable( GL_BLEND );
492                 glDisable( GL_POLYGON_SMOOTH );
493         }
494 }
495
496 /* changing black/white for TOG3 buts */
497 static void ui_tog3_invert(float x1, float y1, float x2, float y2, int seltype)
498 {
499         short alpha = 30;
500         
501         if (seltype == 0) {
502                 glEnable(GL_BLEND);
503                 
504                 glColor4ub(0, 0, 0, alpha);
505                 glRectf(x2-6, y1, x2, (y1+(y2-y1)/2));
506                 
507                 glColor4ub(255, 255, 255, alpha);
508                 glRectf(x2-6, (y1+(y2-y1)/2), x2, y2);
509                 
510                 glDisable(GL_BLEND);
511         } else {
512                 glEnable(GL_BLEND);
513                 
514                 glColor4ub(255, 255, 255, alpha);
515                 glRectf(x2-6, y1, x2, (y1+(y2-y1)/2));
516                 
517                 glColor4ub(0, 0, 0, alpha);
518                 glRectf(x2-6, (y1+(y2-y1)/2), x2, y2);
519                 
520                 glDisable(GL_BLEND);
521         }
522 }
523
524 /* button/popup menu/iconrow drawing code */
525 static void ui_default_button(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
526 {
527         int align= (flag & UI_BUT_ALIGN);
528
529         if(align) {
530         
531                 /* *** BOTTOM OUTER SUNKEN EFFECT *** */
532                 if (!((align == UI_BUT_ALIGN_DOWN) ||
533                         (align == (UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT)) ||
534                         (align == (UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT)))) {
535                         glEnable(GL_BLEND);
536                         MM_WHITE_OP;
537                         fdrawline(x1, y1-1, x2, y1-1);  
538                         glDisable(GL_BLEND);
539                 }
540                 /* *** END BOTTOM OUTER SUNKEN EFFECT *** */
541                 
542                 switch(align) {
543                 case UI_BUT_ALIGN_TOP:
544                         uiSetRoundBox(12);
545                         
546                         /* last arg in shaded_button() determines whether the button is in the middle of
547                          * an alignment group or not. 0 = not middle, 1 = is in the middle.
548                          * Done to allow cleaner drawing
549                          */
550                          
551                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
552                         break;
553                 case UI_BUT_ALIGN_DOWN:
554                         uiSetRoundBox(3);
555                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
556                         break;
557                 case UI_BUT_ALIGN_LEFT:
558                         
559                         /* RIGHT OUTER SUNKEN EFFECT */
560                         glEnable(GL_BLEND);
561                         glShadeModel(GL_SMOOTH);
562                         glBegin(GL_LINES);
563                         MM_WHITE_OP;
564                         glVertex2f(x2+1,y1);
565                         MM_WHITE_TR;
566                         glVertex2f(x2+1,y2);
567                         glEnd();
568                         glDisable(GL_BLEND);
569                         
570                         uiSetRoundBox(6);
571                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
572                         break;
573                 case UI_BUT_ALIGN_RIGHT:
574                 
575                         /* LEFT OUTER SUNKEN EFFECT */
576                         glEnable(GL_BLEND);
577                         glShadeModel(GL_SMOOTH);
578                         glBegin(GL_LINES);
579                         MM_WHITE_OP;
580                         glVertex2f(x1-1,y1);
581                         MM_WHITE_TR;
582                         glVertex2f(x1-1,y2);
583                         glEnd();
584                         glDisable(GL_BLEND);
585                 
586                         uiSetRoundBox(9);
587                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
588                         break;
589                         
590                 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT:
591                         uiSetRoundBox(1);
592                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
593                         break;
594                 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT:
595                         uiSetRoundBox(2);
596                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
597                         break;
598                 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_RIGHT:
599                 
600                         /* LEFT OUTER SUNKEN EFFECT */
601                         glEnable(GL_BLEND);
602                         glShadeModel(GL_SMOOTH);
603                         glBegin(GL_LINES);
604                         MM_WHITE_OP;
605                         glVertex2f(x1-1,y1);
606                         MM_WHITE_TR;
607                         glVertex2f(x1-1,y2);
608                         glEnd();
609                         glDisable(GL_BLEND);
610                 
611                         uiSetRoundBox(8);
612                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
613                         break;
614                 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_LEFT:
615                 
616                         /* RIGHT OUTER SUNKEN EFFECT */
617                         glEnable(GL_BLEND);
618                         glShadeModel(GL_SMOOTH);
619                         glBegin(GL_LINES);
620                         MM_WHITE_OP;
621                         glVertex2f(x2+1,y1);
622                         MM_WHITE_TR;
623                         glVertex2f(x2+1,y2);
624                         glEnd();
625                         glDisable(GL_BLEND);
626                         
627                         uiSetRoundBox(4);
628                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
629                         break;
630                         
631                 default:
632                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 1);
633                         break;
634                 }
635         } 
636         else {  
637                 glEnable(GL_BLEND);
638                 glShadeModel(GL_SMOOTH);
639                 
640                 /* BOTTOM OUTER SUNKEN EFFECT */
641                 MM_WHITE_OP;
642                 fdrawline(x1, y1-1, x2, y1-1);  
643                 
644                 /* LEFT OUTER SUNKEN EFFECT */
645                 glBegin(GL_LINES);
646                 MM_WHITE_OP;
647                 glVertex2f(x1-1,y1);
648                 MM_WHITE_TR;
649                 glVertex2f(x1-1,y2);
650                 glEnd();
651                 
652                 /* RIGHT OUTER SUNKEN EFFECT */
653                 glBegin(GL_LINES);
654                 MM_WHITE_OP;
655                 glVertex2f(x2+1,y1);
656                 MM_WHITE_TR;
657                 glVertex2f(x2+1,y2);
658                 glEnd();
659                 
660                 glDisable(GL_BLEND);
661         
662                 uiSetRoundBox(15);
663                 shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
664         }
665         
666         /* *** EXTRA DRAWING FOR SPECIFIC CONTROL TYPES *** */
667         switch(type) {
668         case ICONROW:
669         case ICONTEXTROW:
670                 /* DARKENED AREA */
671                 glEnable(GL_BLEND);
672                 
673                 glColor4ub(0, 0, 0, 30);
674                 glRectf(x2-9, y1, x2, y2);
675         
676                 glDisable(GL_BLEND);
677                 /* END DARKENED AREA */
678         
679                 /* ICONROW DOUBLE-ARROW  */
680                 M_DARK;
681                 ui_default_iconrow_arrows(x1, y1, x2, y2);
682                 /* END ICONROW DOUBLE-ARROW */
683                 break;
684         case MENU:
685                 /* DARKENED AREA */
686                 glEnable(GL_BLEND);
687                 
688                 glColor4ub(0, 0, 0, 30);
689                 glRectf(x2-18, y1, x2, y2);
690         
691                 glDisable(GL_BLEND);
692                 /* END DARKENED AREA */
693         
694                 /* MENU DOUBLE-ARROW  */
695                 M_DARK;
696                 ui_default_menu_arrows(x1, y1, x2, y2);
697                 /* MENU DOUBLE-ARROW */
698                 break;
699         }       
700 }
701
702
703 /* number/text field drawing code */
704 static void ui_default_flat(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
705 {
706         int align= (flag & UI_BUT_ALIGN);
707
708         if(align) {
709         
710                 /* *** BOTTOM OUTER SUNKEN EFFECT *** */
711                 if (!((align == UI_BUT_ALIGN_DOWN) ||
712                         (align == (UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT)) ||
713                         (align == (UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT)))) {
714                         glEnable(GL_BLEND);
715                         MM_WHITE_OP;
716                         fdrawline(x1, y1-1, x2, y1-1);  
717                         glDisable(GL_BLEND);
718                 }
719                 /* *** END BOTTOM OUTER SUNKEN EFFECT *** */
720                 
721                 switch(align) {
722                 case UI_BUT_ALIGN_TOP:
723                         uiSetRoundBox(12);
724                         
725                         /* last arg in shaded_button() determines whether the button is in the middle of
726                          * an alignment group or not. 0 = not middle, 1 = is in the middle.
727                          * Done to allow cleaner drawing
728                          */
729                          
730                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
731                         break;
732                 case UI_BUT_ALIGN_DOWN:
733                         uiSetRoundBox(3);
734                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
735                         break;
736                 case UI_BUT_ALIGN_LEFT:
737                         
738                         /* RIGHT OUTER SUNKEN EFFECT */
739                         glEnable(GL_BLEND);
740                         glShadeModel(GL_SMOOTH);
741                         glBegin(GL_LINES);
742                         MM_WHITE_OP;
743                         glVertex2f(x2+1,y1);
744                         MM_WHITE_TR;
745                         glVertex2f(x2+1,y2);
746                         glEnd();
747                         glDisable(GL_BLEND);
748                         
749                         uiSetRoundBox(6);
750                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
751                         break;
752                 case UI_BUT_ALIGN_RIGHT:
753                 
754                         /* LEFT OUTER SUNKEN EFFECT */
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                         glEnable(GL_BLEND);
781                         glShadeModel(GL_SMOOTH);
782                         glBegin(GL_LINES);
783                         MM_WHITE_OP;
784                         glVertex2f(x1-1,y1);
785                         MM_WHITE_TR;
786                         glVertex2f(x1-1,y2);
787                         glEnd();
788                         glDisable(GL_BLEND);
789                 
790                         uiSetRoundBox(8);
791                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
792                         break;
793                 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_LEFT:
794                 
795                         /* RIGHT OUTER SUNKEN EFFECT */
796                         glEnable(GL_BLEND);
797                         glShadeModel(GL_SMOOTH);
798                         glBegin(GL_LINES);
799                         MM_WHITE_OP;
800                         glVertex2f(x2+1,y1);
801                         MM_WHITE_TR;
802                         glVertex2f(x2+1,y2);
803                         glEnd();
804                         glDisable(GL_BLEND);
805                         
806                         uiSetRoundBox(4);
807                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
808                         break;
809                         
810                 default:
811                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 1);
812                         break;
813                 }
814         } 
815         else {
816         
817                 glEnable(GL_BLEND);
818                 glShadeModel(GL_SMOOTH);
819                 
820                 /* BOTTOM OUTER SUNKEN EFFECT */
821                 MM_WHITE_OP;
822                 fdrawline(x1, y1-1, x2, y1-1);  
823                 
824                 /* LEFT OUTER SUNKEN EFFECT */
825                 glBegin(GL_LINES);
826                 MM_WHITE_OP;
827                 glVertex2f(x1-1,y1);
828                 MM_WHITE_TR;
829                 glVertex2f(x1-1,y2);
830                 glEnd();
831                 
832                 /* RIGHT OUTER SUNKEN EFFECT */
833                 glBegin(GL_LINES);
834                 MM_WHITE_OP;
835                 glVertex2f(x2+1,y1);
836                 MM_WHITE_TR;
837                 glVertex2f(x2+1,y2);
838                 glEnd();
839                 
840                 glDisable(GL_BLEND);
841
842                 uiSetRoundBox(15);
843                 flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
844         }
845         
846         /* *** EXTRA DRAWING FOR SPECIFIC CONTROL TYPES *** */
847         switch(type) {
848         case NUM:
849         case NUMABS:
850                 /* SIDE ARROWS */
851                 /* left */
852                 if(flag & UI_SELECT) {
853                         if(flag & UI_ACTIVE) M_DARK;
854                         else M_DARK;
855                 } else {
856                         if(flag & UI_ACTIVE) M_GREY;
857                         else M_LGREY;
858                 }
859                 
860                 ui_default_num_arrows(x1, y1, x2, y2);
861                 /* END SIDE ARROWS */
862         }
863 }
864
865 static void ui_default_slider(int colorid, float fac, float aspect, float x1, float y1, float x2, float y2, int flag)
866 {
867         float ymid, yc;
868
869         /* the slider background line */
870         ymid= (y1+y2)/2.0;
871         //yc= 2.5*aspect;       // height of center line
872         yc = 2.3; // height of center line
873         
874         if(flag & UI_SELECT) 
875                         BIF_ThemeColorShade(TH_BUT_NUM, -5);
876         else {
877                 if(flag & UI_ACTIVE) 
878                         BIF_ThemeColorShade(TH_BUT_NUM, +35); 
879                 else
880                         BIF_ThemeColorShade(TH_BUT_NUM, +25); 
881         }
882
883         glRectf(x1, ymid-yc, x2, ymid+yc);
884         
885         /* top inner bevel */
886         if(flag & UI_SELECT) BIF_ThemeColorShade(TH_BUT_NUM, -40); 
887         else BIF_ThemeColorShade(TH_BUT_NUM, -5); 
888         fdrawline(x1+1, ymid+yc, x2, ymid+yc);
889         
890         /* bottom inner bevel */
891         if(flag & UI_SELECT) BIF_ThemeColorShade(TH_BUT_NUM, +15); 
892         else BIF_ThemeColorShade(TH_BUT_NUM, +45); 
893         fdrawline(x1+1, ymid-yc, x2, ymid-yc);
894         
895         
896         /* the movable slider */
897         if(flag & UI_SELECT) BIF_ThemeColorShade(TH_BUT_NUM, +80); 
898         else BIF_ThemeColorShade(TH_BUT_NUM, -45); 
899
900         glShadeModel(GL_SMOOTH);
901         glBegin(GL_QUADS);
902
903         BIF_ThemeColorShade(TH_BUT_NUM, -45); 
904
905         glVertex2f(x1,     y1+2.5);
906         glVertex2f(x1+fac, y1+2.5);
907
908         BIF_ThemeColor(TH_BUT_NUM); 
909
910         glVertex2f(x1+fac, y2-2.5);
911         glVertex2f(x1,     y2-2.5);
912
913         glEnd();
914         
915
916         /* slider handle center */
917         glShadeModel(GL_SMOOTH);
918         glBegin(GL_QUADS);
919
920         BIF_ThemeColor(TH_BUT_NUM); 
921         glVertex2f(x1+fac-3, y1+2);
922         glVertex2f(x1+fac, y1+4);
923         BIF_ThemeColorShade(TH_BUT_NUM, +80); 
924         glVertex2f(x1+fac, y2-2);
925         glVertex2f(x1+fac-3, y2-2);
926
927         glEnd();
928         
929         /* slider handle left bevel */
930         BIF_ThemeColorShade(TH_BUT_NUM, +70); 
931         fdrawline(x1+fac-3, y2-2, x1+fac-3, y1+2);
932         
933         /* slider handle right bevel */
934         BIF_ThemeColorShade(TH_BUT_NUM, -35); 
935         fdrawline(x1+fac, y2-2, x1+fac, y1+2);
936
937         glShadeModel(GL_FLAT);
938 }
939
940 /* default theme callback */
941 static void ui_draw_default(int type, int colorid, float aspect, float x1, float y1, float x2, float y2, int flag)
942 {
943
944         switch(type) {
945         case TEX:
946         case IDPOIN:
947         case NUM:
948         case NUMABS:
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         case NUMABS:
1033                 if(flag & UI_SELECT) BIF_ThemeColorShade(colorid, -60);
1034                 else BIF_ThemeColorShade(colorid, -30);
1035                 ui_default_num_arrows(x1, y1, x2, y2);
1036                 break;
1037
1038         case ICONROW: 
1039         case ICONTEXTROW: 
1040                 if(flag & UI_ACTIVE) BIF_ThemeColorShade(colorid, 0);
1041                 else BIF_ThemeColorShade(colorid, -10);
1042                 glRectf(x2-9, y1+asp, x2-asp, y2-asp);
1043
1044                 BIF_ThemeColorShade(colorid, -50);
1045                 ui_default_iconrow_arrows(x1, y1, x2, y2);
1046                 break;
1047                 
1048         case MENU: 
1049                 if(flag & UI_ACTIVE) BIF_ThemeColorShade(colorid, 0);
1050                 else BIF_ThemeColorShade(colorid, -10);
1051                 glRectf(x2-17, y1+asp, x2-asp, y2-asp);
1052
1053                 BIF_ThemeColorShade(colorid, -50);
1054                 ui_default_menu_arrows(x1, y1, x2, y2);
1055                 break;
1056         }
1057         
1058 }
1059
1060 /* *************** BASIC ROUNDED THEME ***************** */
1061
1062 static void round_button(float x1, float y1, float x2, float y2, float asp, 
1063                                                  int colorid, int round, int menudeco, int curshade)
1064 {
1065         float rad;
1066         char col[4];
1067         
1068         rad= (y2-y1)/2.0;
1069         if(rad>7.0) rad= 7.0;
1070         
1071         uiSetRoundBox(round);
1072         gl_round_box(GL_POLYGON, x1, y1, x2, y2, rad);
1073
1074         if(menudeco) {
1075                 uiSetRoundBox(round & ~9);
1076                 BIF_ThemeColorShade(colorid, curshade-20);
1077                 gl_round_box(GL_POLYGON, x2-menudeco, y1, x2, y2, rad);
1078         }
1079         
1080         /* fake AA */
1081         uiSetRoundBox(round);
1082         glEnable( GL_BLEND );
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((GLubyte *)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((GLubyte *)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         case NUMABS:
1184                 BIF_ThemeColorShade(colorid, curshade-60);
1185                 ui_default_num_arrows(x1, y1, x2, y2);
1186                 break;
1187
1188         case ICONROW: 
1189         case ICONTEXTROW: 
1190                 BIF_ThemeColorShade(colorid, curshade-60);
1191                 ui_default_iconrow_arrows(x1, y1, x2, y2);
1192                 break;
1193                 
1194         case MENU: 
1195         case BLOCK: 
1196                 BIF_ThemeColorShade(colorid, curshade-60);
1197                 ui_default_menu_arrows(x1, y1, x2, y2);
1198                 break;
1199         }
1200 }
1201
1202 /* *************** MINIMAL THEME ***************** */
1203
1204 // theme can define an embosfunc and sliderfunc, text+icon drawing is standard, no theme.
1205
1206
1207
1208 /* super minimal button as used in logic menu */
1209 static void ui_draw_minimal(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1210 {
1211         /* too much space between buttons */
1212         
1213         if (type==TEX || type==IDPOIN) {
1214                 x1+= asp;
1215                 x2-= (asp*2);
1216                 //y1+= asp;
1217                 y2-= asp;
1218         } else {
1219                 /* Less space between buttons looks nicer */
1220                 y2-= asp;
1221                 x2-= asp;
1222         }
1223         
1224         /* paper */
1225         if(flag & UI_SELECT) {
1226                 if(flag & UI_ACTIVE) BIF_ThemeColorShade(colorid, -40);
1227                 else BIF_ThemeColorShade(colorid, -30);
1228         }
1229         else {
1230                 if(flag & UI_ACTIVE) BIF_ThemeColorShade(colorid, +20);
1231                 else BIF_ThemeColorShade(colorid, +10);
1232         }
1233         
1234         glRectf(x1, y1, x2, y2);
1235         
1236         if (type==TEX || type==IDPOIN) {
1237                 BIF_ThemeColorShade(colorid, -60);
1238
1239                 /* top */
1240                 fdrawline(x1, y2, x2, y2);
1241                 /* left */
1242                 fdrawline(x1, y1, x1, y2);
1243                 
1244                 
1245                 /* text underline, some  */ 
1246                 BIF_ThemeColorShade(colorid, +50);
1247                 glEnable(GL_LINE_STIPPLE);
1248                 glLineStipple(1, 0x8888);
1249                 fdrawline(x1+(asp*2), y1+(asp*3), x2-(asp*2), y1+(asp*3));
1250                 glDisable(GL_LINE_STIPPLE);
1251                 
1252                 
1253                 BIF_ThemeColorShade(colorid, +60);
1254                 /* below */
1255                 fdrawline(x1, y1, x2, y1);
1256                 /* right */
1257                 fdrawline(x2, y1, x2, y2);
1258                 
1259         } else {
1260                 if(flag & UI_SELECT) {
1261                         BIF_ThemeColorShade(colorid, -60);
1262
1263                         /* top */
1264                         fdrawline(x1, y2, x2, y2);
1265                         /* left */
1266                         fdrawline(x1, y1, x1, y2);
1267                         BIF_ThemeColorShade(colorid, +40);
1268
1269                         /* below */
1270                         fdrawline(x1, y1, x2, y1);
1271                         /* right */
1272                         fdrawline(x2, y1, x2, y2);
1273                 }
1274                 else {
1275                         BIF_ThemeColorShade(colorid, +40);
1276
1277                         /* top */
1278                         fdrawline(x1, y2, x2, y2);
1279                         /* left */
1280                         fdrawline(x1, y1, x1, y2);
1281                         
1282                         BIF_ThemeColorShade(colorid, -60);
1283                         /* below */
1284                         fdrawline(x1, y1, x2, y1);
1285                         /* right */
1286                         fdrawline(x2, y1, x2, y2);
1287                 }
1288         }
1289         
1290         /* special type decorations */
1291         switch(type) {
1292         case NUM:
1293         case NUMABS:
1294                 if(flag & UI_SELECT) BIF_ThemeColorShade(colorid, -60);
1295                 else BIF_ThemeColorShade(colorid, -30);
1296                 ui_default_num_arrows(x1, y1, x2, y2);
1297                 break;
1298
1299         case ICONROW: 
1300         case ICONTEXTROW: 
1301                 if(flag & UI_ACTIVE) BIF_ThemeColorShade(colorid, 0);
1302                 else BIF_ThemeColorShade(colorid, -10);
1303                 glRectf(x2-9, y1+asp, x2-asp, y2-asp);
1304
1305                 BIF_ThemeColorShade(colorid, -50);
1306                 ui_default_iconrow_arrows(x1, y1, x2, y2);
1307                 break;
1308                 
1309         case MENU: 
1310         case BLOCK: 
1311                 if(flag & UI_ACTIVE) BIF_ThemeColorShade(colorid, 0);
1312                 else BIF_ThemeColorShade(colorid, -10);
1313                 glRectf(x2-17, y1+asp, x2-asp, y2-asp);
1314
1315                 BIF_ThemeColorShade(colorid, -50);
1316                 ui_default_menu_arrows(x1, y1, x2, y2);
1317                 break;
1318         }
1319         
1320         
1321 }
1322
1323
1324 /* fac is the slider handle position between x1 and x2 */
1325 static void ui_draw_slider(int colorid, float fac, float aspect, float x1, float y1, float x2, float y2, int flag)
1326 {
1327         float ymid, yc;
1328
1329         /* the slider background line */
1330         ymid= (y1+y2)/2.0;
1331         yc= 1.7*aspect; 
1332
1333         if(flag & UI_ACTIVE) 
1334                 BIF_ThemeColorShade(colorid, -50); 
1335         else 
1336                 BIF_ThemeColorShade(colorid, -40); 
1337
1338         /* left part */
1339         glRectf(x1, ymid-2.0*yc, x1+fac, ymid+2.0*yc);
1340         /* right part */
1341         glRectf(x1+fac, ymid-yc, x2, ymid+yc);
1342
1343         /* the movable slider */
1344         
1345         BIF_ThemeColorShade(colorid, +70); 
1346         glRectf(x1+fac-aspect, ymid-2.0*yc, x1+fac+aspect, ymid+2.0*yc);
1347
1348 }
1349
1350 /* ************** STANDARD MENU DRAWING FUNCTION ************* */
1351
1352
1353 static void ui_shadowbox(float minx, float miny, float maxx, float maxy, float shadsize, unsigned char alpha)
1354 {
1355         glEnable(GL_BLEND);
1356         glShadeModel(GL_SMOOTH);
1357         
1358         /* right quad */
1359         glBegin(GL_POLYGON);
1360         glColor4ub(0, 0, 0, alpha);
1361         glVertex2f(maxx, miny);
1362         glVertex2f(maxx, maxy-shadsize);
1363         glColor4ub(0, 0, 0, 0);
1364         glVertex2f(maxx+shadsize, maxy-shadsize-shadsize);
1365         glVertex2f(maxx+shadsize, miny);
1366         glEnd();
1367         
1368         /* corner shape */
1369         glBegin(GL_POLYGON);
1370         glColor4ub(0, 0, 0, alpha);
1371         glVertex2f(maxx, miny);
1372         glColor4ub(0, 0, 0, 0);
1373         glVertex2f(maxx+shadsize, miny);
1374         glVertex2f(maxx+0.7*shadsize, miny-0.7*shadsize);
1375         glVertex2f(maxx, miny-shadsize);
1376         glEnd();
1377         
1378         /* bottom quad */               
1379         glBegin(GL_POLYGON);
1380         glColor4ub(0, 0, 0, alpha);
1381         glVertex2f(minx+shadsize, miny);
1382         glVertex2f(maxx, miny);
1383         glColor4ub(0, 0, 0, 0);
1384         glVertex2f(maxx, miny-shadsize);
1385         glVertex2f(minx+shadsize+shadsize, miny-shadsize);
1386         glEnd();
1387         
1388         glDisable(GL_BLEND);
1389         glShadeModel(GL_FLAT);
1390 }
1391
1392 void uiDrawBoxShadow(unsigned char alpha, float minx, float miny, float maxx, float maxy)
1393 {
1394         /* accumulated outline boxes to make shade not linear, is more pleasant */
1395         ui_shadowbox(minx, miny, maxx, maxy, 6.0, (30*alpha)>>8);
1396         ui_shadowbox(minx, miny, maxx, maxy, 4.0, (70*alpha)>>8);
1397         ui_shadowbox(minx, miny, maxx, maxy, 2.0, (100*alpha)>>8);
1398         
1399 }
1400
1401 // background for pulldowns, pullups, and other drawing temporal menus....
1402 // has to be made themable still (now only color)
1403
1404 void uiDrawMenuBox(float minx, float miny, float maxx, float maxy, short flag)
1405 {
1406         char col[4];
1407         BIF_GetThemeColor4ubv(TH_MENU_BACK, col);
1408         
1409         if( (flag & UI_BLOCK_NOSHADOW)==0) {
1410                 /* accumulated outline boxes to make shade not linear, is more pleasant */
1411                 ui_shadowbox(minx, miny, maxx, maxy, 6.0, (30*col[3])>>8);
1412                 ui_shadowbox(minx, miny, maxx, maxy, 4.0, (70*col[3])>>8);
1413                 ui_shadowbox(minx, miny, maxx, maxy, 2.0, (100*col[3])>>8);
1414                 
1415                 glEnable(GL_BLEND);
1416                 glColor4ubv((GLubyte *)col);
1417                 glRectf(minx-1, miny, minx, maxy);      // 1 pixel on left, to distinguish sublevel menus
1418         }
1419         glEnable(GL_BLEND);
1420         glColor4ubv((GLubyte *)col);
1421         glRectf(minx, miny, maxx, maxy);
1422         glDisable(GL_BLEND);
1423 }
1424
1425
1426
1427 /* pulldown menu item */
1428 static void ui_draw_pulldown_item(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1429 {
1430         char col[4];
1431         
1432         BIF_GetThemeColor4ubv(TH_MENU_BACK, col);
1433         if(col[3]!=255) {
1434                 glEnable(GL_BLEND);
1435         }
1436         
1437         if((flag & UI_ACTIVE) && type!=LABEL) {
1438                 BIF_ThemeColor4(TH_MENU_HILITE);
1439                 glRectf(x1, y1, x2, y2);
1440         
1441
1442         } else {
1443                 BIF_ThemeColor4(colorid);       // is set at TH_MENU_ITEM when pulldown opened.
1444                 glRectf(x1, y1, x2, y2);
1445         }
1446
1447         glDisable(GL_BLEND);
1448 }
1449
1450 /* pulldown menu calling button */
1451 static void ui_draw_pulldown_round(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1452 {
1453         
1454         if(flag & UI_ACTIVE) {
1455                 BIF_ThemeColor(TH_MENU_HILITE);
1456
1457                 uiSetRoundBox(15);
1458                 gl_round_box(GL_POLYGON, x1, y1+3, x2, y2-3, 7.0);
1459
1460                 glEnable( GL_LINE_SMOOTH );
1461                 glEnable( GL_BLEND );
1462                 gl_round_box(GL_LINE_LOOP, x1, y1+3, x2, y2-3, 7.0);
1463                 glDisable( GL_LINE_SMOOTH );
1464                 glDisable( GL_BLEND );
1465                 
1466         } else {
1467                 BIF_ThemeColor(colorid);        // is set at TH_MENU_ITEM when pulldown opened.
1468                 glRectf(x1-1, y1+2, x2+1, y2-2);
1469         }
1470         
1471 }
1472
1473
1474 /* ************** TEXT AND ICON DRAWING FUNCTIONS ************* */
1475
1476
1477
1478 /* draws text and icons for buttons */
1479 static void ui_draw_text_icon(uiBut *but)
1480 {
1481         float x;
1482         int len;
1483         char *cpoin;
1484         short t, pos, ch;
1485         short selsta_tmp, selend_tmp, selsta_draw, selwidth_draw;
1486         
1487         /* check for button text label */
1488         if (but->type == ICONTEXTROW) {
1489                 ui_draw_icon(but, (BIFIconID) (but->icon+but->iconadd), 0);
1490         }
1491         else {
1492
1493                 /* text button selection and cursor */
1494                 if(but->pos != -1) {
1495                 
1496                         if ((but->selend - but->selsta) > 0) {
1497                                 /* text button selection */
1498                                 selsta_tmp = but->selsta + strlen(but->str);
1499                                 selend_tmp = but->selend + strlen(but->str);
1500                                         
1501                                 if(but->drawstr[0]!=0) {
1502                                         ch= but->drawstr[selsta_tmp];
1503                                         but->drawstr[selsta_tmp]= 0;
1504                                         
1505                                         selsta_draw = but->aspect*BIF_GetStringWidth(but->font, but->drawstr+but->ofs, (U.transopts & USER_TR_BUTTONS)) + 3;
1506                                         
1507                                         but->drawstr[selsta_tmp]= ch;
1508                                         
1509                                         
1510                                         ch= but->drawstr[selend_tmp];
1511                                         but->drawstr[selend_tmp]= 0;
1512                                         
1513                                         selwidth_draw = but->aspect*BIF_GetStringWidth(but->font, but->drawstr+but->ofs, (U.transopts & USER_TR_BUTTONS)) + 3;
1514                                         
1515                                         but->drawstr[selend_tmp]= ch;
1516                                         
1517                                         BIF_ThemeColor(TH_BUT_TEXTFIELD_HI);
1518                                         glRects(but->x1+selsta_draw+1, but->y1+2, but->x1+selwidth_draw+1, but->y2-2);
1519                                 }
1520                         } else {
1521                                 /* text cursor */
1522                                 pos= but->pos+strlen(but->str);
1523                                 if(pos >= but->ofs) {
1524                                         if(but->drawstr[0]!=0) {
1525                                                 ch= but->drawstr[pos];
1526                                                 but->drawstr[pos]= 0;
1527                         
1528                                                 t= but->aspect*BIF_GetStringWidth(but->font, but->drawstr+but->ofs, (U.transopts & USER_TR_BUTTONS)) + 3;
1529                                                 
1530                                                 but->drawstr[pos]= ch;
1531                                         }
1532                                         else t= 3;
1533                                         
1534                                         glColor3ub(255,0,0);
1535                                         glRects(but->x1+t, but->y1+2, but->x1+t+2, but->y2-2);
1536                                 }
1537                         }
1538                 }
1539                 
1540                 if(but->type==BUT_TOGDUAL) {
1541                         int dualset= 0;
1542                         if(but->pointype==SHO)
1543                                 dualset= BTST( *(((short *)but->poin)+1), but->bitnr);
1544                         else if(but->pointype==INT)
1545                                 dualset= BTST( *(((int *)but->poin)+1), but->bitnr);
1546                         
1547                         ui_draw_icon(but, ICON_DOT, dualset?0:-100);
1548                 }
1549                 
1550                 if(but->drawstr[0]!=0) {
1551                         int transopts;
1552                         int tog3= 0;
1553                         
1554                         // cut string in 2 parts
1555                         cpoin= strchr(but->drawstr, '|');
1556                         if(cpoin) *cpoin= 0;
1557
1558                         /* If there's an icon too (made with uiDefIconTextBut) then draw the icon
1559                         and offset the text label to accomodate it */
1560                         
1561                         if ( (but->flag & UI_HAS_ICON) && (but->flag & UI_ICON_LEFT) ) {
1562                                 ui_draw_icon(but, but->icon, 0);
1563
1564                                 if(but->flag & UI_TEXT_LEFT) x= but->x1 + but->aspect*BIF_icon_get_width(but->icon)+5.0;
1565                                 else x= (but->x1+but->x2-but->strwidth+1)/2.0;
1566                         }
1567                         else {
1568                                 if(but->flag & UI_TEXT_LEFT) x= but->x1+4.0;
1569                                 else x= (but->x1+but->x2-but->strwidth+1)/2.0;
1570                         }
1571                         
1572                         /* tog3 button exception; draws with glColor! */
1573                         if(but->type==TOG3 && (but->flag & UI_SELECT)) {
1574                                 
1575                                 if( but->pointype==CHA ) {
1576                                         if( BTST( *(but->poin+2), but->bitnr )) tog3= 1;
1577                                 }
1578                                 else if( but->pointype ==SHO ) {
1579                                         short *sp= (short *)but->poin;
1580                                         if( BTST( sp[1], but->bitnr )) tog3= 1;
1581                                 }
1582                                 
1583                                 ui_tog3_invert(but->x1,but->y1,but->x2,but->y2, tog3);
1584                                 if (tog3) glColor3ub(255, 255, 0);
1585                         }
1586                         
1587                         /* text color, with pulldown item exception */
1588                         if(tog3);       // color already set
1589                         else if(but->dt==UI_EMBOSSP) {
1590                                 if((but->flag & (UI_SELECT|UI_ACTIVE)) && but->type!=LABEL) {   // LABEL = title in pulldowns
1591                                         BIF_ThemeColor(TH_MENU_TEXT_HI);
1592                                 } else {
1593                                         BIF_ThemeColor(TH_MENU_TEXT);
1594                                 }
1595                         }
1596                         else {
1597                                 if(but->flag & UI_SELECT) {             
1598                                         BIF_ThemeColor(TH_BUT_TEXT_HI);
1599                                 } else {
1600                                         BIF_ThemeColor(TH_BUT_TEXT);
1601                                 }
1602                         }
1603
1604                         /* LABEL button exception */
1605                         if(but->type==LABEL && but->min!=0.0) BIF_ThemeColor(TH_BUT_TEXT_HI);
1606                 
1607                         ui_rasterpos_safe(x, (but->y1+but->y2- 9.0)/2.0, but->aspect);
1608                         if(but->type==IDPOIN) transopts= 0;     // no translation, of course!
1609                         else transopts= (U.transopts & USER_TR_BUTTONS);
1610                         
1611                 #ifdef INTERNATIONAL
1612                         if (but->type == FTPREVIEW)
1613                                 FTF_DrawNewFontString (but->drawstr+but->ofs, FTF_INPUT_UTF8);
1614                         else
1615                                 BIF_DrawString(but->font, but->drawstr+but->ofs, transopts);
1616                 #else
1617                         BIF_DrawString(but->font, but->drawstr+but->ofs, transopts);
1618                 #endif
1619
1620                         /* part text right aligned */
1621                         if(cpoin) {
1622                                 len= BIF_GetStringWidth(but->font, cpoin+1, (U.transopts & USER_TR_BUTTONS));
1623                                 ui_rasterpos_safe( but->x2 - len*but->aspect-3, (but->y1+but->y2- 9.0)/2.0, but->aspect);
1624                                 BIF_DrawString(but->font, cpoin+1, (U.transopts & USER_TR_BUTTONS));
1625                                 *cpoin= '|';
1626                         }
1627                 }
1628                 /* if there's no text label, then check to see if there's an icon only and draw it */
1629                 else if( but->flag & UI_HAS_ICON ) {
1630                         ui_draw_icon(but, (BIFIconID) (but->icon+but->iconadd), 0);
1631                 }
1632         }
1633 }
1634
1635 static void ui_draw_but_COL(uiBut *but)
1636 {
1637         float *fp;
1638         char colr, colg, colb;
1639         
1640         if( but->pointype==FLO ) {
1641                 fp= (float *)but->poin;
1642                 colr= floor(255.0*fp[0]+0.5);
1643                 colg= floor(255.0*fp[1]+0.5);
1644                 colb= floor(255.0*fp[2]+0.5);
1645         }
1646         else {
1647                 char *cp= (char *)but->poin;
1648                 colr= cp[0];
1649                 colg= cp[1];
1650                 colb= cp[2];
1651         }
1652         
1653         /* exception... hrms, but can't simply use the emboss callback for this now. */
1654         /* this button type needs review, and nice integration with rest of API here */
1655         if(but->embossfunc == ui_draw_round) {
1656                 char *cp= BIF_ThemeGetColorPtr(U.themes.first, 0, TH_CUSTOM);
1657                 cp[0]= colr; cp[1]= colg; cp[2]= colb;
1658                 but->flag &= ~UI_SELECT;
1659                 but->embossfunc(but->type, TH_CUSTOM, but->aspect, but->x1, but->y1, but->x2, but->y2, but->flag);
1660         }
1661         else {
1662                 
1663                 glColor3ub(colr,  colg,  colb);
1664                 glRectf((but->x1), (but->y1), (but->x2), (but->y2));
1665                 glColor3ub(0,  0,  0);
1666                 fdrawbox((but->x1), (but->y1), (but->x2), (but->y2));
1667         }
1668 }
1669
1670 /* draws in resolution of 20x4 colors */
1671 static void ui_draw_but_HSVCUBE(uiBut *but)
1672 {
1673         int a;
1674         float h,s,v;
1675         float dx, dy, sx1, sx2, sy, x, y;
1676         float col0[4][3];       // left half, rect bottom to top
1677         float col1[4][3];       // right half, rect bottom to top
1678         
1679         h= but->hsv[0];
1680         s= but->hsv[1];
1681         v= but->hsv[2];
1682         
1683         /* draw series of gouraud rects */
1684         glShadeModel(GL_SMOOTH);
1685         
1686         if(but->a1==0) {        // H and V vary
1687                 hsv_to_rgb(0.0, s, 0.0,   &col1[0][0], &col1[0][1], &col1[0][2]);
1688                 hsv_to_rgb(0.0, s, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]);
1689                 hsv_to_rgb(0.0, s, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]);
1690                 hsv_to_rgb(0.0, s, 1.0,   &col1[3][0], &col1[3][1], &col1[3][2]);
1691                 x= h; y= v;
1692         }
1693         else if(but->a1==1) {   // H and S vary
1694                 hsv_to_rgb(0.0, 0.0, v,   &col1[0][0], &col1[0][1], &col1[0][2]);
1695                 hsv_to_rgb(0.0, 0.333, v, &col1[1][0], &col1[1][1], &col1[1][2]);
1696                 hsv_to_rgb(0.0, 0.666, v, &col1[2][0], &col1[2][1], &col1[2][2]);
1697                 hsv_to_rgb(0.0, 1.0, v,   &col1[3][0], &col1[3][1], &col1[3][2]);
1698                 x= h; y= s;
1699         }
1700         else if(but->a1==2) {   // S and V vary
1701                 hsv_to_rgb(h, 0.0, 0.0,   &col1[0][0], &col1[0][1], &col1[0][2]);
1702                 hsv_to_rgb(h, 0.333, 0.0, &col1[1][0], &col1[1][1], &col1[1][2]);
1703                 hsv_to_rgb(h, 0.666, 0.0, &col1[2][0], &col1[2][1], &col1[2][2]);
1704                 hsv_to_rgb(h, 1.0, 0.0,   &col1[3][0], &col1[3][1], &col1[3][2]);
1705                 x= v; y= s;
1706         }
1707         else {          // only hue slider
1708                 hsv_to_rgb(0.0, 1.0, 1.0,   &col1[0][0], &col1[0][1], &col1[0][2]);
1709                 VECCOPY(col1[1], col1[0]);
1710                 VECCOPY(col1[2], col1[0]);
1711                 VECCOPY(col1[3], col1[0]);
1712                 x= h; y= 0.5;
1713         }
1714         
1715         for(dx=0.0; dx<1.0; dx+= 0.05) {
1716                 // previous color
1717                 VECCOPY(col0[0], col1[0]);
1718                 VECCOPY(col0[1], col1[1]);
1719                 VECCOPY(col0[2], col1[2]);
1720                 VECCOPY(col0[3], col1[3]);
1721
1722                 // new color
1723                 if(but->a1==0) {        // H and V vary
1724                         hsv_to_rgb(dx, s, 0.0,   &col1[0][0], &col1[0][1], &col1[0][2]);
1725                         hsv_to_rgb(dx, s, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]);
1726                         hsv_to_rgb(dx, s, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]);
1727                         hsv_to_rgb(dx, s, 1.0,   &col1[3][0], &col1[3][1], &col1[3][2]);
1728                 }
1729                 else if(but->a1==1) {   // H and S vary
1730                         hsv_to_rgb(dx, 0.0, v,   &col1[0][0], &col1[0][1], &col1[0][2]);
1731                         hsv_to_rgb(dx, 0.333, v, &col1[1][0], &col1[1][1], &col1[1][2]);
1732                         hsv_to_rgb(dx, 0.666, v, &col1[2][0], &col1[2][1], &col1[2][2]);
1733                         hsv_to_rgb(dx, 1.0, v,   &col1[3][0], &col1[3][1], &col1[3][2]);
1734                 }
1735                 else if(but->a1==2) {   // S and V vary
1736                         hsv_to_rgb(h, 0.0, dx,   &col1[0][0], &col1[0][1], &col1[0][2]);
1737                         hsv_to_rgb(h, 0.333, dx, &col1[1][0], &col1[1][1], &col1[1][2]);
1738                         hsv_to_rgb(h, 0.666, dx, &col1[2][0], &col1[2][1], &col1[2][2]);
1739                         hsv_to_rgb(h, 1.0, dx,   &col1[3][0], &col1[3][1], &col1[3][2]);
1740                 }
1741                 else {  // only H
1742                         hsv_to_rgb(dx, 1.0, 1.0,   &col1[0][0], &col1[0][1], &col1[0][2]);
1743                         VECCOPY(col1[1], col1[0]);
1744                         VECCOPY(col1[2], col1[0]);
1745                         VECCOPY(col1[3], col1[0]);
1746                 }
1747                 
1748                 // rect
1749                 sx1= but->x1 + dx*(but->x2-but->x1);
1750                 sx2= but->x1 + (dx+0.05)*(but->x2-but->x1);
1751                 sy= but->y1;
1752                 dy= (but->y2-but->y1)/3.0;
1753                 
1754                 glBegin(GL_QUADS);
1755                 for(a=0; a<3; a++, sy+=dy) {
1756                         glColor3fv(col0[a]);
1757                         glVertex2f(sx1, sy);
1758
1759                         glColor3fv(col1[a]);
1760                         glVertex2f(sx2, sy);
1761                         
1762                         glColor3fv(col1[a+1]);
1763                         glVertex2f(sx2, sy+dy);
1764                         
1765                         glColor3fv(col0[a+1]);
1766                         glVertex2f(sx1, sy+dy);
1767                 }
1768                 glEnd();
1769         }
1770
1771         glShadeModel(GL_FLAT);
1772
1773         /* cursor */
1774         x= but->x1 + x*(but->x2-but->x1);
1775         y= but->y1 + y*(but->y2-but->y1);
1776         CLAMP(x, but->x1+3.0, but->x2-3.0);
1777         CLAMP(y, but->y1+3.0, but->y2-3.0);
1778         
1779         fdrawXORcirc(x, y, 3.1);
1780
1781         /* outline */
1782         glColor3ub(0,  0,  0);
1783         fdrawbox((but->x1), (but->y1), (but->x2), (but->y2));
1784 }
1785
1786 #ifdef INTERNATIONAL
1787 static void ui_draw_but_CHARTAB(uiBut *but)
1788 {
1789         /* Some local variables */
1790         float sx, sy, ex, ey;
1791         float width, height;
1792         float butw, buth;
1793         int x, y, cs;
1794         wchar_t wstr[2];
1795         unsigned char ustr[16];
1796         PackedFile *pf;
1797         int result = 0;
1798         int charmax = G.charmax;
1799         
1800         /* <builtin> font in use. There are TTF <builtin> and non-TTF <builtin> fonts */
1801         if(!strcmp(G.selfont->name, "<builtin>"))
1802         {
1803                 if(G.ui_international == TRUE)
1804                 {
1805                         charmax = 0xff;
1806                 }
1807                 else
1808                 {
1809                         charmax = 0xff;
1810                 }
1811         }
1812
1813         /* Category list exited without selecting the area */
1814         if(G.charmax == 0)
1815                 charmax = G.charmax = 0xffff;
1816
1817         /* Calculate the size of the button */
1818         width = abs(but->x2 - but->x1);
1819         height = abs(but->y2 - but->y1);
1820         
1821         butw = floor(width / 12);
1822         buth = floor(height / 6);
1823         
1824         /* Initialize variables */
1825         sx = but->x1;
1826         ex = but->x1 + butw;
1827         sy = but->y1 + height - buth;
1828         ey = but->y1 + height;
1829
1830         cs = G.charstart;
1831
1832         /* Set the font, in case it is not <builtin> font */
1833         if(G.selfont && strcmp(G.selfont->name, "<builtin>"))
1834         {
1835                 char tmpStr[256];
1836
1837                 // Is the font file packed, if so then use the packed file
1838                 if(G.selfont->packedfile)
1839                 {
1840                         pf = G.selfont->packedfile;             
1841                         FTF_SetFont(pf->data, pf->size, 14.0);
1842                 }
1843                 else
1844                 {
1845                         int err;
1846
1847                         strcpy(tmpStr, G.selfont->name);
1848                         BLI_convertstringcode(tmpStr, G.sce);
1849                         err = FTF_SetFont((unsigned char *)tmpStr, 0, 14.0);
1850                 }
1851         }
1852         else
1853         {
1854                 if(G.ui_international == TRUE)
1855                 {
1856                         FTF_SetFont((unsigned char *) datatoc_bfont_ttf, datatoc_bfont_ttf_size, 14.0);
1857                 }
1858         }
1859
1860         /* Start drawing the button itself */
1861         glShadeModel(GL_SMOOTH);
1862
1863         glColor3ub(200,  200,  200);
1864         glRectf((but->x1), (but->y1), (but->x2), (but->y2));
1865
1866         glColor3ub(0,  0,  0);
1867         for(y = 0; y < 6; y++)
1868         {
1869                 // Do not draw more than the category allows
1870                 if(cs > charmax) break;
1871
1872                 for(x = 0; x < 12; x++)
1873                 {
1874                         // Do not draw more than the category allows
1875                         if(cs > charmax) break;
1876
1877                         // Draw one grid cell
1878                         glBegin(GL_LINE_LOOP);
1879                                 glVertex2f(sx, sy);
1880                                 glVertex2f(ex, sy);
1881                                 glVertex2f(ex, ey);
1882                                 glVertex2f(sx, ey);                             
1883                         glEnd();        
1884
1885                         // Draw character inside the cell
1886                         memset(wstr, 0, sizeof(wchar_t)*2);
1887                         memset(ustr, 0, 16);
1888
1889                         // Set the font to be either unicode or <builtin>                               
1890                         wstr[0] = cs;
1891                         if(strcmp(G.selfont->name, "<builtin>"))
1892                         {
1893                                 wcs2utf8s((char *)ustr, (wchar_t *)wstr);
1894                         }
1895                         else
1896                         {
1897                                 if(G.ui_international == TRUE)
1898                                 {
1899                                         wcs2utf8s((char *)ustr, (wchar_t *)wstr);
1900                                 }
1901                                 else
1902                                 {
1903                                         ustr[0] = cs;
1904                                         ustr[1] = 0;
1905                                 }
1906                         }
1907
1908                         if((G.selfont && strcmp(G.selfont->name, "<builtin>")) || (G.selfont && !strcmp(G.selfont->name, "<builtin>") && G.ui_international == TRUE))
1909                         {
1910                                 float wid;
1911                                 float llx, lly, llz, urx, ury, urz;
1912                                 float dx, dy;
1913                                 float px, py;
1914         
1915                                 // Calculate the position
1916                                 wid = FTF_GetStringWidth((char *) ustr, FTF_USE_GETTEXT | FTF_INPUT_UTF8);
1917                                 FTF_GetBoundingBox((char *) ustr, &llx,&lly,&llz,&urx,&ury,&urz, FTF_USE_GETTEXT | FTF_INPUT_UTF8);
1918                                 dx = urx-llx;
1919                                 dy = ury-lly;
1920
1921                                 // This isn't fully functional since the but->aspect isn't working like I suspected
1922                                 px = sx + ((butw/but->aspect)-dx)/2;
1923                                 py = sy + ((buth/but->aspect)-dy)/2;
1924
1925                                 // Set the position and draw the character
1926                                 ui_rasterpos_safe(px, py, but->aspect);
1927                                 FTF_DrawString((char *) ustr, FTF_USE_GETTEXT | FTF_INPUT_UTF8);
1928                         }
1929                         else
1930                         {
1931                                 ui_rasterpos_safe(sx + butw/2, sy + buth/2, but->aspect);
1932                                 BIF_DrawString(but->font, (char *) ustr, 0);
1933                         }
1934         
1935                         // Calculate the next position and character
1936                         sx += butw; ex +=butw;
1937                         cs++;
1938                 }
1939                 /* Add the y position and reset x position */
1940                 sy -= buth; 
1941                 ey -= buth;
1942                 sx = but->x1;
1943                 ex = but->x1 + butw;
1944         }       
1945         glShadeModel(GL_FLAT);
1946
1947         /* Return Font Settings to original */
1948         if(U.fontsize && U.fontname[0])
1949         {
1950                 result = FTF_SetFont((unsigned char *)U.fontname, 0, U.fontsize);
1951         }
1952         else if (U.fontsize)
1953         {
1954                 result = FTF_SetFont((unsigned char *) datatoc_bfont_ttf, datatoc_bfont_ttf_size, U.fontsize);
1955         }
1956
1957         if (result == 0)
1958         {
1959                 result = FTF_SetFont((unsigned char *) datatoc_bfont_ttf, datatoc_bfont_ttf_size, 11);
1960         }
1961         
1962         /* resets the font size */
1963         if(G.ui_international == TRUE)
1964         {
1965                 uiSetCurFont(but->block, UI_HELV);
1966         }
1967 }
1968
1969 #endif // INTERNATIONAL
1970
1971 static void ui_draw_but_COLORBAND(uiBut *but)
1972 {
1973         ColorBand *coba= (ColorBand *)but->poin;
1974         CBData *cbd;
1975         float x1, y1, sizex, sizey;
1976         float dx, v3[2], v1[2], v2[2], v1a[2], v2a[2];
1977         int a;
1978                 
1979         if(coba==NULL) return;
1980         
1981         x1= but->x1;
1982         y1= but->y1;
1983         sizex= but->x2-x1;
1984         sizey= but->y2-y1;
1985         
1986         /* first background, to show tranparency */
1987         dx= sizex/12.0;
1988         v1[0]= x1;
1989         for(a=0; a<12; a++) {
1990                 if(a & 1) glColor3f(0.3, 0.3, 0.3); else glColor3f(0.8, 0.8, 0.8);
1991                 glRectf(v1[0], y1, v1[0]+dx, y1+0.5*sizey);
1992                 if(a & 1) glColor3f(0.8, 0.8, 0.8); else glColor3f(0.3, 0.3, 0.3);
1993                 glRectf(v1[0], y1+0.5*sizey, v1[0]+dx, y1+sizey);
1994                 v1[0]+= dx;
1995         }
1996         
1997         glShadeModel(GL_SMOOTH);
1998         glEnable(GL_BLEND);
1999         
2000         cbd= coba->data;
2001         
2002         v1[0]= v2[0]= x1;
2003         v1[1]= y1;
2004         v2[1]= y1+sizey;
2005         
2006         glBegin(GL_QUAD_STRIP);
2007         
2008         glColor4fv( &cbd->r );
2009         glVertex2fv(v1); glVertex2fv(v2);
2010         
2011         for(a=0; a<coba->tot; a++, cbd++) {
2012                 
2013                 v1[0]=v2[0]= x1+ cbd->pos*sizex;
2014                 
2015                 glColor4fv( &cbd->r );
2016                 glVertex2fv(v1); glVertex2fv(v2);
2017         }
2018         
2019         v1[0]=v2[0]= x1+ sizex;
2020         glVertex2fv(v1); glVertex2fv(v2);
2021         
2022         glEnd();
2023         glShadeModel(GL_FLAT);
2024         glDisable(GL_BLEND);
2025         
2026         /* outline */
2027         v1[0]= x1; v1[1]= y1;
2028         
2029         cpack(0x0);
2030         glBegin(GL_LINE_LOOP);
2031         glVertex2fv(v1);
2032         v1[0]+= sizex;
2033         glVertex2fv(v1);
2034         v1[1]+= sizey;
2035         glVertex2fv(v1);
2036         v1[0]-= sizex;
2037         glVertex2fv(v1);
2038         glEnd();
2039         
2040         
2041         /* help lines */
2042         v1[0]= v2[0]=v3[0]= x1;
2043         v1[1]= y1;
2044         v1a[1]= y1+0.25*sizey;
2045         v2[1]= y1+0.5*sizey;
2046         v2a[1]= y1+0.75*sizey;
2047         v3[1]= y1+sizey;
2048         
2049         
2050         cbd= coba->data;
2051         glBegin(GL_LINES);
2052         for(a=0; a<coba->tot; a++, cbd++) {
2053                 v1[0]=v2[0]=v3[0]=v1a[0]=v2a[0]= x1+ cbd->pos*sizex;
2054                 
2055                 if(a==coba->cur) {
2056                         glColor3ub(0, 0, 0);
2057                         glVertex2fv(v1);
2058                         glVertex2fv(v3);
2059                         glEnd();
2060                         
2061                         setlinestyle(2);
2062                         glBegin(GL_LINES);
2063                         glColor3ub(255, 255, 255);
2064                         glVertex2fv(v1);
2065                         glVertex2fv(v3);
2066                         glEnd();
2067                         setlinestyle(0);
2068                         glBegin(GL_LINES);
2069                         
2070                         /* glColor3ub(0, 0, 0);
2071                         glVertex2fv(v1);
2072                         glVertex2fv(v1a);
2073                         glColor3ub(255, 255, 255);
2074                         glVertex2fv(v1a);
2075                         glVertex2fv(v2);
2076                         glColor3ub(0, 0, 0);
2077                         glVertex2fv(v2);
2078                         glVertex2fv(v2a);
2079                         glColor3ub(255, 255, 255);
2080                         glVertex2fv(v2a);
2081                         glVertex2fv(v3);
2082                         */
2083                 }
2084                 else {
2085                         glColor3ub(0, 0, 0);
2086                         glVertex2fv(v1);
2087                         glVertex2fv(v2);
2088                         
2089                         glColor3ub(255, 255, 255);
2090                         glVertex2fv(v2);
2091                         glVertex2fv(v3);
2092                 }       
2093         }
2094         glEnd();
2095 }
2096
2097 static void ui_draw_but_NORMAL(uiBut *but)
2098 {
2099         static GLuint displist=0;
2100         int a, old[8];
2101         GLfloat diff[4], diffn[4]={1.0f, 1.0f, 1.0f, 1.0f};
2102         float vec0[4]={0.0f, 0.0f, 0.0f, 0.0f};
2103         float dir[4], size;
2104         
2105         /* store stuff */
2106         glGetMaterialfv(GL_FRONT, GL_DIFFUSE, diff);
2107                 
2108         /* backdrop */
2109         BIF_ThemeColor(TH_BUT_NEUTRAL);
2110         uiSetRoundBox(15);
2111         gl_round_box(GL_POLYGON, but->x1, but->y1, but->x2, but->y2, 5.0f);
2112         
2113         /* sphere color */
2114         glMaterialfv(GL_FRONT, GL_DIFFUSE, diffn);
2115         glCullFace(GL_BACK); glEnable(GL_CULL_FACE);
2116         
2117         /* disable blender light */
2118         for(a=0; a<8; a++) {
2119                 old[a]= glIsEnabled(GL_LIGHT0+a);
2120                 glDisable(GL_LIGHT0+a);
2121         }
2122         
2123         /* own light */
2124         glEnable(GL_LIGHT7);
2125         glEnable(GL_LIGHTING);
2126         
2127         VECCOPY(dir, (float *)but->poin);
2128         dir[3]= 0.0f;   /* glLight needs 4 args, 0.0 is sun */
2129         glLightfv(GL_LIGHT7, GL_POSITION, dir); 
2130         glLightfv(GL_LIGHT7, GL_DIFFUSE, diffn); 
2131         glLightfv(GL_LIGHT7, GL_SPECULAR, vec0); 
2132         glLightf(GL_LIGHT7, GL_CONSTANT_ATTENUATION, 1.0f);
2133         glLightf(GL_LIGHT7, GL_LINEAR_ATTENUATION, 0.0f);
2134         
2135         /* transform to button */
2136         glPushMatrix();
2137         glTranslatef(but->x1 + 0.5f*(but->x2-but->x1), but->y1+ 0.5f*(but->y2-but->y1), 0.0f);
2138         size= (but->x2-but->x1)/200.f;
2139         glScalef(size, size, size);
2140                          
2141         if(displist==0) {
2142                 GLUquadricObj   *qobj;
2143                 
2144                 displist= glGenLists(1);
2145                 glNewList(displist, GL_COMPILE_AND_EXECUTE);
2146                 
2147                 qobj= gluNewQuadric();
2148                 gluQuadricDrawStyle(qobj, GLU_FILL); 
2149                 glShadeModel(GL_SMOOTH);
2150                 gluSphere( qobj, 100.0, 32, 24);
2151                 glShadeModel(GL_FLAT);
2152                 gluDeleteQuadric(qobj);  
2153                 
2154                 glEndList();
2155         }
2156         else glCallList(displist);
2157         
2158         /* restore */
2159         glPopMatrix();
2160         glDisable(GL_LIGHTING);
2161         glDisable(GL_CULL_FACE);
2162         glMaterialfv(GL_FRONT, GL_DIFFUSE, diff); 
2163         
2164         glDisable(GL_LIGHT7);
2165         
2166         /* enable blender light */
2167         for(a=0; a<8; a++) {
2168                 if(old[a])
2169                         glEnable(GL_LIGHT0+a);
2170         }
2171 }
2172
2173 static void ui_draw_but_curve_grid(uiBut *but, float zoomx, float zoomy, float offsx, float offsy, float step)
2174 {
2175         float dx, dy, fx, fy;
2176         
2177         glBegin(GL_LINES);
2178         dx= step*zoomx;
2179         fx= but->x1 + zoomx*(-offsx);
2180         if(fx > but->x1) fx -= dx*( floor(fx-but->x1));
2181         while(fx < but->x2) {
2182                 glVertex2f(fx, but->y1); 
2183                 glVertex2f(fx, but->y2);
2184                 fx+= dx;
2185         }
2186         
2187         dy= step*zoomy;
2188         fy= but->y1 + zoomy*(-offsy);
2189         if(fy > but->y1) fy -= dy*( floor(fy-but->y1));
2190         while(fy < but->y2) {
2191                 glVertex2f(but->x1, fy); 
2192                 glVertex2f(but->x2, fy);
2193                 fy+= dy;
2194         }
2195         glEnd();
2196         
2197 }
2198
2199 static void ui_draw_but_CURVE(uiBut *but)
2200 {
2201         CurveMapping *cumap= (CurveMapping *)but->poin;
2202         CurveMap *cuma= cumap->cm+cumap->cur;
2203         CurveMapPoint *cmp;
2204         float fx, fy, dx, dy, fac[2], zoomx, zoomy, offsx, offsy;
2205         GLint scissor[4];
2206         int a;
2207         
2208         /* need scissor test, curve can draw outside of boundary */
2209         glGetIntegerv(GL_VIEWPORT, scissor);
2210         fx= but->x1; fy= but->y1;
2211         ui_graphics_to_window(but->win, &fx, &fy);
2212         dx= but->x2; dy= but->y2;
2213         ui_graphics_to_window(but->win, &dx, &dy);
2214         glScissor((int)floor(fx), (int)floor(fy), (int)ceil(dx-fx), (int)ceil(dy-fy));
2215         
2216         /* calculate offset and zoom */
2217         zoomx= (but->x2-but->x1-2.0*but->aspect)/(cumap->curr.xmax - cumap->curr.xmin);
2218         zoomy= (but->y2-but->y1-2.0*but->aspect)/(cumap->curr.ymax - cumap->curr.ymin);
2219         offsx= cumap->curr.xmin-but->aspect/zoomx;
2220         offsy= cumap->curr.ymin-but->aspect/zoomy;
2221         
2222         /* backdrop */
2223         if(cumap->flag & CUMA_DO_CLIP) {
2224                 BIF_ThemeColorShade(TH_BUT_NEUTRAL, -20);
2225                 glRectf(but->x1, but->y1, but->x2, but->y2);
2226                 BIF_ThemeColor(TH_BUT_NEUTRAL);
2227                 glRectf(but->x1 + zoomx*(cumap->clipr.xmin-offsx),
2228                                 but->y1 + zoomy*(cumap->clipr.ymin-offsy),
2229                                 but->x1 + zoomx*(cumap->clipr.xmax-offsx),
2230                                 but->y1 + zoomy*(cumap->clipr.ymax-offsy));
2231         }
2232         else {
2233                 BIF_ThemeColor(TH_BUT_NEUTRAL);
2234                 glRectf(but->x1, but->y1, but->x2, but->y2);
2235         }
2236         
2237         /* grid, every .25 step */
2238         BIF_ThemeColorShade(TH_BUT_NEUTRAL, -16);
2239         ui_draw_but_curve_grid(but, zoomx, zoomy, offsx, offsy, 0.25f);
2240         /* grid, every 1.0 step */
2241         BIF_ThemeColorShade(TH_BUT_NEUTRAL, -24);
2242         ui_draw_but_curve_grid(but, zoomx, zoomy, offsx, offsy, 1.0f);
2243         /* axes */
2244         BIF_ThemeColorShade(TH_BUT_NEUTRAL, -50);
2245         glBegin(GL_LINES);
2246         glVertex2f(but->x1, but->y1 + zoomy*(-offsy));
2247         glVertex2f(but->x2, but->y1 + zoomy*(-offsy));
2248         glVertex2f(but->x1 + zoomx*(-offsx), but->y1);
2249         glVertex2f(but->x1 + zoomx*(-offsx), but->y2);
2250         glEnd();
2251         
2252         /* cfra option */
2253         if(cumap->flag & CUMA_DRAW_CFRA) {
2254                 glColor3ub(0x60, 0xc0, 0x40);
2255                 glBegin(GL_LINES);
2256                 glVertex2f(but->x1 + zoomx*(cumap->sample[0]-offsx), but->y1);
2257                 glVertex2f(but->x1 + zoomx*(cumap->sample[0]-offsx), but->y2);
2258                 glEnd();
2259         }
2260         /* sample option */
2261         if(cumap->flag & CUMA_DRAW_SAMPLE) {
2262                 if(cumap->cur==3) {
2263                         float lum= cumap->sample[0]*0.35f + cumap->sample[1]*0.45f + cumap->sample[2]*0.2f;
2264                         glColor3ub(240, 240, 240);
2265                         
2266                         glBegin(GL_LINES);
2267                         glVertex2f(but->x1 + zoomx*(lum-offsx), but->y1);
2268                         glVertex2f(but->x1 + zoomx*(lum-offsx), but->y2);
2269                         glEnd();
2270                 }
2271                 else {
2272                         if(cumap->cur==0)
2273                                 glColor3ub(240, 100, 100);
2274                         else if(cumap->cur==1)
2275                                 glColor3ub(100, 240, 100);
2276                         else
2277                                 glColor3ub(100, 100, 240);
2278                         
2279                         glBegin(GL_LINES);
2280                         glVertex2f(but->x1 + zoomx*(cumap->sample[cumap->cur]-offsx), but->y1);
2281                         glVertex2f(but->x1 + zoomx*(cumap->sample[cumap->cur]-offsx), but->y2);
2282                         glEnd();
2283                 }
2284         }
2285         
2286         /* the curve */
2287         BIF_ThemeColorBlend(TH_TEXT, TH_BUT_NEUTRAL, 0.35);
2288         glEnable(GL_LINE_SMOOTH);
2289         glEnable(GL_BLEND);
2290         glBegin(GL_LINE_STRIP);
2291         
2292         if(cuma->table==NULL)
2293                 curvemapping_changed(cumap, 0); /* 0 = no remove doubles */
2294         cmp= cuma->table;
2295         
2296         /* first point */
2297         if((cuma->flag & CUMA_EXTEND_EXTRAPOLATE)==0)
2298                 glVertex2f(but->x1, but->y1 + zoomy*(cmp[0].y-offsy));
2299         else {
2300                 fx= but->x1 + zoomx*(cmp[0].x-offsx + cuma->ext_in[0]);
2301                 fy= but->y1 + zoomy*(cmp[0].y-offsy + cuma->ext_in[1]);
2302                 glVertex2f(fx, fy);
2303         }
2304         for(a=0; a<=CM_TABLE; a++) {
2305                 fx= but->x1 + zoomx*(cmp[a].x-offsx);
2306                 fy= but->y1 + zoomy*(cmp[a].y-offsy);
2307                 glVertex2f(fx, fy);
2308         }
2309         /* last point */
2310         if((cuma->flag & CUMA_EXTEND_EXTRAPOLATE)==0)
2311                 glVertex2f(but->x2, but->y1 + zoomy*(cmp[CM_TABLE].y-offsy));   
2312         else {
2313                 fx= but->x1 + zoomx*(cmp[CM_TABLE].x-offsx - cuma->ext_out[0]);
2314                 fy= but->y1 + zoomy*(cmp[CM_TABLE].y-offsy - cuma->ext_out[1]);
2315                 glVertex2f(fx, fy);
2316         }
2317         glEnd();
2318         glDisable(GL_LINE_SMOOTH);
2319         glDisable(GL_BLEND);
2320
2321         /* the points, use aspect to make them visible on edges */
2322         cmp= cuma->curve;
2323         glPointSize(3.0f);
2324         bglBegin(GL_POINTS);
2325         for(a=0; a<cuma->totpoint; a++) {
2326                 if(cmp[a].flag & SELECT)
2327                         BIF_ThemeColor(TH_TEXT_HI);
2328                 else
2329                         BIF_ThemeColor(TH_TEXT);
2330                 fac[0]= but->x1 + zoomx*(cmp[a].x-offsx);
2331                 fac[1]= but->y1 + zoomy*(cmp[a].y-offsy);
2332                 bglVertex2fv(fac);
2333         }
2334         bglEnd();
2335         glPointSize(1.0f);
2336         
2337         /* restore scissortest */
2338         glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
2339
2340         /* outline */
2341         BIF_ThemeColor(TH_BUT_OUTLINE);
2342         fdrawbox(but->x1, but->y1, but->x2, but->y2);
2343
2344 }
2345
2346 static void ui_draw_roundbox(uiBut *but)
2347 {
2348         glEnable(GL_BLEND);
2349         
2350         BIF_ThemeColorShadeAlpha(TH_PANEL, but->a2, but->a2);
2351
2352         uiSetRoundBox(but->a1);
2353         gl_round_box(GL_POLYGON, but->x1, but->y1, but->x2, but->y2, but->min);
2354
2355         glDisable(GL_BLEND);
2356 }
2357
2358
2359 /* nothing! */
2360 static void ui_draw_nothing(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
2361 {
2362 }
2363
2364
2365 /* ************** EXTERN, called from interface.c ************* */
2366 /* ************** MAIN CALLBACK FUNCTION          ************* */
2367
2368 void ui_set_embossfunc(uiBut *but, int drawtype)
2369 {
2370         // this aded for evaluating textcolor for example
2371         but->dt= drawtype;
2372         
2373         // not really part of standard minimal themes, just make sure it is set
2374         but->sliderfunc= ui_draw_slider;
2375
2376         // standard builtin first:
2377         if(but->type==LABEL || but->type==ROUNDBOX) but->embossfunc= ui_draw_nothing;
2378         else if(but->type==PULLDOWN) but->embossfunc= ui_draw_pulldown_round;
2379         else if(drawtype==UI_EMBOSSM) but->embossfunc= ui_draw_minimal;
2380         else if(drawtype==UI_EMBOSSN) but->embossfunc= ui_draw_nothing;
2381         else if(drawtype==UI_EMBOSSP) but->embossfunc= ui_draw_pulldown_item;
2382         else if(drawtype==UI_EMBOSSR) but->embossfunc= ui_draw_round;
2383         else {
2384                 int theme= BIF_GetThemeValue(TH_BUT_DRAWTYPE);
2385                 
2386                 switch(theme) {
2387                 
2388                 case TH_ROUNDED:
2389                         but->embossfunc= ui_draw_round;
2390                         break;
2391                 case TH_OLDSKOOL:
2392                         but->embossfunc= ui_draw_oldskool;
2393                         break;
2394                 case TH_MINIMAL:
2395                         but->embossfunc= ui_draw_minimal;
2396                         break;
2397                 case TH_SHADED:
2398                 default:
2399                         but->embossfunc= ui_draw_default;
2400                         but->sliderfunc= ui_default_slider;
2401                         break;
2402                 }
2403         }
2404         
2405         // note: if you want aligning, adapt the call uiBlockEndAlign in interface.c 
2406 }
2407
2408 void ui_draw_but(uiBut *but)
2409 {
2410         double value;
2411         float x1, x2, y1, y2, fac;
2412         
2413         if(but==NULL) return;
2414
2415         /* signal for frontbuf flush buttons and menus, not when normal drawing */
2416         if(but->block->in_use) ui_block_set_flush(but->block, but);
2417                 
2418         switch (but->type) {
2419
2420         case NUMSLI:
2421         case HSVSLI:
2422         
2423                 but->embossfunc(but->type, but->themecol, but->aspect, but->x1, but->y1, but->x2, but->y2, but->flag);
2424                 ui_draw_text_icon(but);
2425
2426                 x1= (but->x1+but->x2)/2;
2427                 x2= but->x2 - 5.0*but->aspect;
2428                 y1= but->y1 + 2.0*but->aspect;
2429                 y2= but->y2 - 2.0*but->aspect;
2430                 
2431                 value= ui_get_but_val(but);
2432                 fac= (value-but->min)*(x2-x1)/(but->max - but->min);
2433                 
2434                 but->sliderfunc(but->themecol, fac, but->aspect, x1, y1, x2, y2, but->flag);
2435                 break;
2436                 
2437         case SEPR:
2438                 //  only background
2439                 break;
2440                 
2441         case COL:
2442                 ui_draw_but_COL(but);  // black box with color
2443                 break;
2444
2445         case HSVCUBE:
2446                 ui_draw_but_HSVCUBE(but);  // box for colorpicker, three types
2447                 break;
2448
2449 #ifdef INTERNATIONAL
2450         case CHARTAB:
2451                 value= ui_get_but_val(but);
2452                 ui_draw_but_CHARTAB(but);
2453                 break;
2454 #endif
2455
2456         case LINK:
2457         case INLINK:
2458                 ui_draw_icon(but, but->icon, 0);
2459                 break;
2460                 
2461         case ROUNDBOX:
2462                 ui_draw_roundbox(but);
2463                 break;
2464                 
2465         case BUT_COLORBAND:
2466                 ui_draw_but_COLORBAND(but);
2467                 break;
2468         case BUT_NORMAL:
2469                 ui_draw_but_NORMAL(but);
2470                 break;
2471         case BUT_CURVE:
2472                 ui_draw_but_CURVE(but);
2473                 break;
2474                 
2475         default:
2476                 but->embossfunc(but->type, but->themecol, but->aspect, but->x1, but->y1, but->x2, but->y2, but->flag);
2477                 ui_draw_text_icon(but);
2478         
2479         }
2480 }
2481
2482 void ui_dropshadow(rctf *rct, float radius, float aspect, int select)
2483 {
2484         float rad;
2485         float a;
2486         char alpha= 2;
2487         
2488         glEnable(GL_BLEND);
2489         
2490         if(radius > (rct->ymax-rct->ymin-10.0f)/2.0f)
2491                 rad= (rct->ymax-rct->ymin-10.0f)/2.0f;
2492         else
2493                 rad= radius;
2494         
2495         if(select) a= 12.0f*aspect; else a= 12.0f*aspect;
2496         for(; a>0.0f; a-=aspect) {
2497                 /* alpha ranges from 2 to 20 or so */
2498                 glColor4ub(0, 0, 0, alpha);
2499                 alpha+= 2;
2500                 
2501                 gl_round_box(GL_POLYGON, rct->xmin - a, rct->ymin - a, rct->xmax + a, rct->ymax-10.0f + a, rad+a);
2502         }
2503         
2504         /* outline emphasis */
2505         glEnable( GL_LINE_SMOOTH );
2506         glColor4ub(0, 0, 0, 100);
2507         gl_round_box(GL_LINE_LOOP, rct->xmin-0.5f, rct->ymin-0.5f, rct->xmax+0.5f, rct->ymax+0.5f, radius);
2508         glDisable( GL_LINE_SMOOTH );
2509         
2510         glDisable(GL_BLEND);
2511 }