Bringing back icons:
[blender.git] / source / blender / editors / interface / interface_draw.c
1 /**
2  * $Id: interface_draw.c 15733 2008-07-24 09:23:13Z aligorith $
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 #include <math.h>
31 #include <string.h>
32
33 #include "DNA_color_types.h"
34 #include "DNA_listBase.h"
35 #include "DNA_object_types.h"
36 #include "DNA_screen_types.h"
37 #include "DNA_texture_types.h"
38 #include "DNA_userdef_types.h"
39
40 #include "BLI_arithb.h"
41
42 #include "BKE_colortools.h"
43 #include "BKE_texture.h"
44 #include "BKE_utildefines.h"
45
46 #include "BIF_gl.h"
47 #include "BIF_glutil.h"
48
49 #include "UI_interface.h"
50 #include "UI_interface_icons.h"
51 #include "UI_text.h"
52
53 #include "BMF_Api.h"
54 #ifdef INTERNATIONAL
55 #include "FTF_Api.h"
56 #endif
57
58 #include "interface.h"
59
60 #define UI_RB_ALPHA 16
61 static int roundboxtype= 15;
62
63 void uiSetRoundBox(int type)
64 {
65         /* Not sure the roundbox function is the best place to change this
66          * if this is undone, its not that big a deal, only makes curves edges
67          * square for the  */
68         if (UI_GetThemeValue(TH_BUT_DRAWTYPE) == TH_MINIMAL)
69                 roundboxtype= 0;
70         else
71                 roundboxtype= type;
72
73         /* flags to set which corners will become rounded:
74
75         1------2
76         |      |
77         8------4
78         */
79         
80 }
81
82 void gl_round_box(int mode, float minx, float miny, float maxx, float maxy, float rad)
83 {
84         float vec[7][2]= {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
85                           {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
86         int a;
87         
88         /* mult */
89         for(a=0; a<7; a++) {
90                 vec[a][0]*= rad; vec[a][1]*= rad;
91         }
92
93         glBegin(mode);
94
95         /* start with corner right-bottom */
96         if(roundboxtype & 4) {
97                 glVertex2f( maxx-rad, miny);
98                 for(a=0; a<7; a++) {
99                         glVertex2f( maxx-rad+vec[a][0], miny+vec[a][1]);
100                 }
101                 glVertex2f( maxx, miny+rad);
102         }
103         else glVertex2f( maxx, miny);
104         
105         /* corner right-top */
106         if(roundboxtype & 2) {
107                 glVertex2f( maxx, maxy-rad);
108                 for(a=0; a<7; a++) {
109                         glVertex2f( maxx-vec[a][1], maxy-rad+vec[a][0]);
110                 }
111                 glVertex2f( maxx-rad, maxy);
112         }
113         else glVertex2f( maxx, maxy);
114         
115         /* corner left-top */
116         if(roundboxtype & 1) {
117                 glVertex2f( minx+rad, maxy);
118                 for(a=0; a<7; a++) {
119                         glVertex2f( minx+rad-vec[a][0], maxy-vec[a][1]);
120                 }
121                 glVertex2f( minx, maxy-rad);
122         }
123         else glVertex2f( minx, maxy);
124         
125         /* corner left-bottom */
126         if(roundboxtype & 8) {
127                 glVertex2f( minx, miny+rad);
128                 for(a=0; a<7; a++) {
129                         glVertex2f( minx+vec[a][1], miny+rad-vec[a][0]);
130                 }
131                 glVertex2f( minx+rad, miny);
132         }
133         else glVertex2f( minx, miny);
134         
135         glEnd();
136 }
137
138 static void round_box_shade_col(float *col1, float *col2, float fac)
139 {
140         float col[3];
141
142         col[0]= (fac*col1[0] + (1.0-fac)*col2[0]);
143         col[1]= (fac*col1[1] + (1.0-fac)*col2[1]);
144         col[2]= (fac*col1[2] + (1.0-fac)*col2[2]);
145         
146         glColor3fv(col);
147 }
148
149 /* linear horizontal shade within button or in outline */
150 void gl_round_box_shade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadetop, float shadedown)
151 {
152         float vec[7][2]= {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
153                           {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
154         float div= maxy-miny;
155         float coltop[3], coldown[3], color[4];
156         int a;
157         
158         /* mult */
159         for(a=0; a<7; a++) {
160                 vec[a][0]*= rad; vec[a][1]*= rad;
161         }
162         /* get current color, needs to be outside of glBegin/End */
163         glGetFloatv(GL_CURRENT_COLOR, color);
164
165         /* 'shade' defines strength of shading */       
166         coltop[0]= color[0]+shadetop; if(coltop[0]>1.0) coltop[0]= 1.0;
167         coltop[1]= color[1]+shadetop; if(coltop[1]>1.0) coltop[1]= 1.0;
168         coltop[2]= color[2]+shadetop; if(coltop[2]>1.0) coltop[2]= 1.0;
169         coldown[0]= color[0]+shadedown; if(coldown[0]<0.0) coldown[0]= 0.0;
170         coldown[1]= color[1]+shadedown; if(coldown[1]<0.0) coldown[1]= 0.0;
171         coldown[2]= color[2]+shadedown; if(coldown[2]<0.0) coldown[2]= 0.0;
172
173         if (UI_GetThemeValue(TH_BUT_DRAWTYPE) != TH_MINIMAL) {
174                 glShadeModel(GL_SMOOTH);
175                 glBegin(mode);
176         }
177
178         /* start with corner right-bottom */
179         if(roundboxtype & 4) {
180                 
181                 round_box_shade_col(coltop, coldown, 0.0);
182                 glVertex2f( maxx-rad, miny);
183                 
184                 for(a=0; a<7; a++) {
185                         round_box_shade_col(coltop, coldown, vec[a][1]/div);
186                         glVertex2f( maxx-rad+vec[a][0], miny+vec[a][1]);
187                 }
188                 
189                 round_box_shade_col(coltop, coldown, rad/div);
190                 glVertex2f( maxx, miny+rad);
191         }
192         else {
193                 round_box_shade_col(coltop, coldown, 0.0);
194                 glVertex2f( maxx, miny);
195         }
196         
197         /* corner right-top */
198         if(roundboxtype & 2) {
199                 
200                 round_box_shade_col(coltop, coldown, (div-rad)/div);
201                 glVertex2f( maxx, maxy-rad);
202                 
203                 for(a=0; a<7; a++) {
204                         round_box_shade_col(coltop, coldown, (div-rad+vec[a][1])/div);
205                         glVertex2f( maxx-vec[a][1], maxy-rad+vec[a][0]);
206                 }
207                 round_box_shade_col(coltop, coldown, 1.0);
208                 glVertex2f( maxx-rad, maxy);
209         }
210         else {
211                 round_box_shade_col(coltop, coldown, 1.0);
212                 glVertex2f( maxx, maxy);
213         }
214         
215         /* corner left-top */
216         if(roundboxtype & 1) {
217                 
218                 round_box_shade_col(coltop, coldown, 1.0);
219                 glVertex2f( minx+rad, maxy);
220                 
221                 for(a=0; a<7; a++) {
222                         round_box_shade_col(coltop, coldown, (div-vec[a][1])/div);
223                         glVertex2f( minx+rad-vec[a][0], maxy-vec[a][1]);
224                 }
225                 
226                 round_box_shade_col(coltop, coldown, (div-rad)/div);
227                 glVertex2f( minx, maxy-rad);
228         }
229         else {
230                 round_box_shade_col(coltop, coldown, 1.0);
231                 glVertex2f( minx, maxy);
232         }
233         
234         /* corner left-bottom */
235         if(roundboxtype & 8) {
236                 
237                 round_box_shade_col(coltop, coldown, rad/div);
238                 glVertex2f( minx, miny+rad);
239                 
240                 for(a=0; a<7; a++) {
241                         round_box_shade_col(coltop, coldown, (rad-vec[a][1])/div);
242                         glVertex2f( minx+vec[a][1], miny+rad-vec[a][0]);
243                 }
244                 
245                 round_box_shade_col(coltop, coldown, 0.0);
246                 glVertex2f( minx+rad, miny);
247         }
248         else {
249                 round_box_shade_col(coltop, coldown, 0.0);
250                 glVertex2f( minx, miny);
251         }
252         
253         glEnd();
254         glShadeModel(GL_FLAT);
255 }
256
257 /* plain fake antialiased unfilled round rectangle */
258 void uiRoundRectFakeAA(float minx, float miny, float maxx, float maxy, float rad, float asp)
259 {
260         float color[4];
261         float raddiff;
262         int i, passes=4;
263         
264         /* get the colour and divide up the alpha */
265         glGetFloatv(GL_CURRENT_COLOR, color);
266         color[3]= 1/(float)passes;
267         glColor4fv(color);
268         
269         /* set the 'jitter amount' */
270         raddiff = (1/(float)passes) * asp;
271         
272         glEnable( GL_BLEND );
273         
274         /* draw lots of lines on top of each other */
275         for (i=passes; i>=(-passes); i--) {
276                 gl_round_box(GL_LINE_LOOP, minx, miny, maxx, maxy, rad+(i*raddiff));
277         }
278         
279         glDisable( GL_BLEND );
280 }
281
282
283 void uiTriangleFakeAA(float x1, float y1, float x2, float y2, float x3, float y3)
284 {
285         float color[4];
286         float jitter;
287         int i, passes=4;
288         
289         /* get the colour and divide up the alpha */
290         glGetFloatv(GL_CURRENT_COLOR, color);
291         color[3]= 1/(float)passes;
292         glColor4fv(color);
293         
294         /* set the 'jitter amount' */
295         jitter = 1/(float)passes;
296         
297         glEnable( GL_BLEND );
298         
299         /* draw lots of lines on top of each other */
300         for (i=passes; i>=(-passes); i--) {
301                 glBegin(GL_TRIANGLES);
302                 
303                 /* 'point' first, then two base vertices */
304                 glVertex2f(x1+(i*jitter), y1+(i*jitter));
305                 glVertex2f(x2, y2+(i*jitter));
306                 glVertex2f(x3, y3+(i*jitter));
307                 glEnd();
308         }
309         
310         glDisable( GL_BLEND );
311 }
312
313
314 /* ************** safe rasterpos for pixmap alignment with pixels ************* */
315
316 void ui_rasterpos_safe(float x, float y, float aspect)
317 {
318         float vals[4], remainder;
319         int doit=0;
320         
321         glRasterPos2f(x, y);
322         glGetFloatv(GL_CURRENT_RASTER_POSITION, vals);
323
324         remainder= vals[0] - floor(vals[0]);
325         if(remainder > 0.4 && remainder < 0.6) {
326                 if(remainder < 0.5) x -= 0.1*aspect;
327                 else x += 0.1*aspect;
328                 doit= 1;
329         }
330         remainder= vals[1] - floor(vals[1]);
331         if(remainder > 0.4 && remainder < 0.6) {
332                 if(remainder < 0.5) y -= 0.1*aspect;
333                 else y += 0.1*aspect;
334                 doit= 1;
335         }
336         
337         if(doit) glRasterPos2f(x, y);
338
339         UI_RasterPos(x, y);
340         UI_SetScale(aspect);
341 }
342
343 /* ************** generic embossed rect, for window sliders etc ************* */
344
345 void uiEmboss(float x1, float y1, float x2, float y2, int sel)
346 {
347         
348         /* below */
349         if(sel) glColor3ub(200,200,200);
350         else glColor3ub(50,50,50);
351         fdrawline(x1, y1, x2, y1);
352
353         /* right */
354         fdrawline(x2, y1, x2, y2);
355         
356         /* top */
357         if(sel) glColor3ub(50,50,50);
358         else glColor3ub(200,200,200);
359         fdrawline(x1, y2, x2, y2);
360
361         /* left */
362         fdrawline(x1, y1, x1, y2);
363         
364 }
365
366 /* ************** GENERIC ICON DRAW, NO THEME HERE ************* */
367
368 /* icons have been standardized... and this call draws in untransformed coordinates */
369 #define ICON_HEIGHT             16.0f
370
371 static void ui_draw_icon(uiBut *but, BIFIconID icon, int blend)
372 {
373         float xs=0, ys=0, aspect, height;
374
375         /* this icon doesn't need draw... */
376         if(icon==ICON_BLANK1) return;
377         
378         /* we need aspect from block, for menus... these buttons are scaled in uiPositionBlock() */
379         aspect= but->block->aspect;
380         if(aspect != but->aspect) {
381                 /* prevent scaling up icon in pupmenu */
382                 if (aspect < 1.0f) {                    
383                         height= ICON_HEIGHT;
384                         aspect = 1.0f;
385                         
386                 }
387                 else 
388                         height= ICON_HEIGHT/aspect;
389         }
390         else
391                 height= ICON_HEIGHT;
392         
393         if(but->flag & UI_ICON_LEFT) {
394                 if (but->type==BUT_TOGDUAL) {
395                         if (but->drawstr[0]) {
396                                 xs= but->x1-1.0;
397                         } else {
398                                 xs= (but->x1+but->x2- height)/2.0;
399                         }
400                 }
401                 else if (but->type==BUTM ) {
402                         xs= but->x1+1.0;
403                 }
404                 else if ((but->type==ICONROW) || (but->type==ICONTEXTROW)) {
405                         xs= but->x1+3.0;
406                 }
407                 else {
408                         xs= but->x1+4.0;
409                 }
410                 ys= (but->y1+but->y2- height)/2.0;
411         }
412         if(but->flag & UI_ICON_RIGHT) {
413                 xs= but->x2-17.0;
414                 ys= (but->y1+but->y2- height)/2.0;
415         }
416         if (!((but->flag & UI_ICON_RIGHT) || (but->flag & UI_ICON_LEFT))) {
417                 xs= (but->x1+but->x2- height)/2.0;
418                 ys= (but->y1+but->y2- height)/2.0;
419         }
420
421         glEnable(GL_BLEND);
422
423         /* calculate blend color */
424         if ELEM3(but->type, TOG, ROW, TOGN) {
425                 if(but->flag & UI_SELECT);
426                 else if(but->flag & UI_ACTIVE);
427                 else blend= -60;
428         }
429         UI_icon_draw_aspect_blended(xs, ys, icon, aspect, blend);
430         
431         glDisable(GL_BLEND);
432 }
433
434
435 /* ************** DEFAULT THEME, SHADED BUTTONS ************* */
436
437
438 #define M_WHITE         UI_ThemeColorShade(colorid, 80)
439
440 #define M_ACT_LIGHT     UI_ThemeColorShade(colorid, 55)
441 #define M_LIGHT         UI_ThemeColorShade(colorid, 45)
442 #define M_HILITE        UI_ThemeColorShade(colorid, 25)
443 #define M_LMEDIUM       UI_ThemeColorShade(colorid, 10)
444 #define M_MEDIUM        UI_ThemeColor(colorid)
445 #define M_LGREY         UI_ThemeColorShade(colorid, -20)
446 #define M_GREY          UI_ThemeColorShade(colorid, -45)
447 #define M_DARK          UI_ThemeColorShade(colorid, -80)
448
449 #define M_NUMTEXT                               UI_ThemeColorShade(colorid, 25)
450 #define M_NUMTEXT_ACT_LIGHT             UI_ThemeColorShade(colorid, 35)
451
452 #define MM_WHITE        UI_ThemeColorShade(TH_BUT_NEUTRAL, 120)
453
454 /* Used for the subtle sunken effect around buttons.
455  * One option is to hardcode to white, with alpha, however it causes a 
456  * weird 'building up' efect, so it's commented out for now.
457  */
458
459 #define MM_WHITE_OP     UI_ThemeColorShadeAlpha(TH_BACK, 55, -100)
460 #define MM_WHITE_TR     UI_ThemeColorShadeAlpha(TH_BACK, 55, -255)
461
462 #define MM_LIGHT        UI_ThemeColorShade(TH_BUT_OUTLINE, 45)
463 #define MM_MEDIUM       UI_ThemeColor(TH_BUT_OUTLINE)
464 #define MM_GREY         UI_ThemeColorShade(TH_BUT_OUTLINE, -45)
465 #define MM_DARK         UI_ThemeColorShade(TH_BUT_OUTLINE, -80)
466
467 /* base shaded button */
468 static void shaded_button(float x1, float y1, float x2, float y2, float asp, int colorid, int flag, int mid)
469 {
470         /* 'mid' arg determines whether the button is in the middle of
471          * an alignment group or not. 0 = not middle, 1 = is in the middle.
472          * Done to allow cleaner drawing
473          */
474          
475         /* *** SHADED BUTTON BASE *** */
476         glShadeModel(GL_SMOOTH);
477         glBegin(GL_QUADS);
478         
479         if(flag & UI_SELECT) {
480                 if(flag & UI_ACTIVE) M_MEDIUM;
481                 else M_LGREY;
482         } else {
483                 if(flag & UI_ACTIVE) M_LIGHT;
484                 else M_HILITE;
485         }
486
487         glVertex2f(x1,y1);
488         glVertex2f(x2,y1);
489
490         if(flag & UI_SELECT) {
491                 if(flag & UI_ACTIVE) M_LGREY;
492                 else M_GREY;
493         } else {
494                 if(flag & UI_ACTIVE) M_ACT_LIGHT;
495                 else M_LIGHT;
496         }
497
498         glVertex2f(x2,(y2-(y2-y1)/3));
499         glVertex2f(x1,(y2-(y2-y1)/3));
500         glEnd();
501         
502
503         glShadeModel(GL_FLAT);
504         glBegin(GL_QUADS);
505         
506         if(flag & UI_SELECT) {
507                 if(flag & UI_ACTIVE) M_LGREY;
508                 else M_GREY;
509         } else {
510                 if(flag & UI_ACTIVE) M_ACT_LIGHT;
511                 else M_LIGHT;
512         }
513         
514         glVertex2f(x1,(y2-(y2-y1)/3));
515         glVertex2f(x2,(y2-(y2-y1)/3));
516         glVertex2f(x2,y2);
517         glVertex2f(x1,y2);
518
519         glEnd();
520         /* *** END SHADED BUTTON BASE *** */
521         
522         /* *** INNER OUTLINE *** */
523         /* left */
524         if(!(flag & UI_SELECT)) {
525                 glShadeModel(GL_SMOOTH);
526                 glBegin(GL_LINES);
527                 M_MEDIUM;
528                 glVertex2f(x1+1,y1+2);
529                 M_WHITE;
530                 glVertex2f(x1+1,y2);
531                 glEnd();
532         }
533         
534         /* right */
535                 if(!(flag & UI_SELECT)) {
536                 glShadeModel(GL_SMOOTH);
537                 glBegin(GL_LINES);
538                 M_MEDIUM;
539                 glVertex2f(x2-1,y1+2);
540                 M_WHITE;
541                 glVertex2f(x2-1,y2);
542                 glEnd();
543         }
544         
545         glShadeModel(GL_FLAT);
546         
547         /* top */
548         if(flag & UI_SELECT) {
549                 if(flag & UI_ACTIVE) M_LGREY;
550                 else M_GREY;
551         } else {
552                 if(flag & UI_ACTIVE) M_WHITE;
553                 else M_WHITE;
554         }
555
556         fdrawline(x1, (y2-1), x2, (y2-1));
557         
558         /* bottom */
559         if(flag & UI_SELECT) {
560                 if(flag & UI_ACTIVE) M_MEDIUM;
561                 else M_LGREY;
562         } else {
563                 if(flag & UI_ACTIVE) M_LMEDIUM;
564                 else M_MEDIUM;
565         }
566         fdrawline(x1, (y1+1), x2, (y1+1));
567         /* *** END INNER OUTLINE *** */
568         
569         /* *** OUTER OUTLINE *** */
570         if (mid) {
571                 // we draw full outline, its not AA, and it works better button mouse-over hilite
572                 MM_DARK;
573                 
574                 // left right
575                 fdrawline(x1, y1, x1, y2);
576                 fdrawline(x2, y1, x2, y2);
577         
578                 // top down
579                 fdrawline(x1, y2, x2, y2);
580                 fdrawline(x1, y1, x2, y1); 
581         } else {
582                 MM_DARK;
583                 gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, 1.5);
584         }
585         /* END OUTER OUTLINE */
586 }
587
588 /* base flat button */
589 static void flat_button(float x1, float y1, float x2, float y2, float asp, int colorid, int flag, int mid)
590 {
591         /* 'mid' arg determines whether the button is in the middle of
592          * an alignment group or not. 0 = not middle, 1 = is in the middle.
593          * Done to allow cleaner drawing
594          */
595          
596         /* *** FLAT TEXT/NUM FIELD *** */
597         glShadeModel(GL_FLAT);
598         if(flag & UI_SELECT) {
599                 if(flag & UI_ACTIVE) M_LGREY;
600                 else M_GREY;
601         }
602         else {
603                 if(flag & UI_ACTIVE) M_NUMTEXT_ACT_LIGHT;
604                 else M_NUMTEXT;
605         }
606
607         glRectf(x1, y1, x2, y2);
608         /* *** END FLAT TEXT/NUM FIELD *** */
609         
610         /* *** OUTER OUTLINE *** */
611         if (mid) {
612                 // we draw full outline, its not AA, and it works better button mouse-over hilite
613                 MM_DARK;
614                 
615                 // left right
616                 fdrawline(x1, y1, x1, y2);
617                 fdrawline(x2, y1, x2, y2);
618         
619                 // top down
620                 fdrawline(x1, y2, x2, y2);
621                 fdrawline(x1, y1, x2, y1); 
622         } else {
623                 MM_DARK;
624                 gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, 1.5);
625         }
626         /* END OUTER OUTLINE */
627 }
628
629 /* shaded round button */
630 static void round_button_shaded(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag, int rad)
631 {
632         float shadefac;
633         
634         /* colour shading */
635         if (flag & UI_SELECT) {
636                 shadefac = -0.05;
637                 if(flag & UI_ACTIVE) UI_ThemeColorShade(colorid, -40);
638                 else UI_ThemeColorShade(colorid, -30);  
639         } else {
640                 shadefac = 0.05;
641                 if(flag & UI_ACTIVE) UI_ThemeColorShade(colorid, +30);
642                 else UI_ThemeColorShade(colorid, +20);                  
643         }
644         /* end colour shading */
645         
646         
647         /* the shaded base */
648         gl_round_box_shade(GL_POLYGON, x1, y1, x2, y2, rad, shadefac, -shadefac);
649         
650         /* outline */
651         UI_ThemeColorBlendShade(TH_BUT_OUTLINE, TH_BACK, 0.1, -40);
652         
653         uiRoundRectFakeAA(x1, y1, x2, y2, rad, asp);
654         /* end outline */       
655 }
656
657 /* base round flat button */
658 static void round_button_flat(int colorid, float asp, float x1, float y1, float x2, float y2, int flag, float rad)
659 {       
660         /* colour shading */
661         if(flag & UI_SELECT) {
662                 if (flag & UI_ACTIVE) UI_ThemeColorShade(colorid, -20);
663                 else UI_ThemeColorShade(colorid, -45);  
664         }
665         else {
666                 if(flag & UI_ACTIVE) UI_ThemeColorShade(colorid, 35);
667                 else UI_ThemeColorShade(colorid, 25);
668         }
669         /* end colour shading */
670         
671         /* the solid base */
672         gl_round_box(GL_POLYGON, x1, y1, x2, y2, rad);
673         
674         /* outline */
675         UI_ThemeColorBlendShade(TH_BUT_OUTLINE, TH_BACK, 0.1, -30);
676         
677         uiRoundRectFakeAA(x1, y1, x2, y2, rad, asp);
678         /* end outline */
679 }
680
681 /* small side double arrow for iconrow */
682 static void ui_default_iconrow_arrows(float x1, float y1, float x2, float y2)
683 {
684         glEnable( GL_POLYGON_SMOOTH );
685         glEnable( GL_BLEND );
686         
687         glShadeModel(GL_FLAT);
688         glBegin(GL_TRIANGLES);
689         glVertex2f((short)x2-2,(short)(y2-(y2-y1)/2)+1);
690         glVertex2f((short)x2-6,(short)(y2-(y2-y1)/2)+1);
691         glVertex2f((short)x2-4,(short)(y2-(y2-y1)/2)+4);
692         glEnd();
693                 
694         glBegin(GL_TRIANGLES);
695         glVertex2f((short)x2-2,(short)(y2-(y2-y1)/2) -1);
696         glVertex2f((short)x2-6,(short)(y2-(y2-y1)/2) -1);
697         glVertex2f((short)x2-4,(short)(y2-(y2-y1)/2) -4);
698         glEnd();
699         
700         glDisable( GL_BLEND );
701         glDisable( GL_POLYGON_SMOOTH );
702 }
703
704 /* side double arrow for menu */
705 static void ui_default_menu_arrows(float x1, float y1, float x2, float y2)
706 {
707         /* 'point' first, then two base vertices */
708         uiTriangleFakeAA(x2-9, (y2-(y2-y1)/2)+6,
709                                         x2-6, (y2-(y2-y1)/2)+2,
710                                         x2-11, (y2-(y2-y1)/2)+2);
711         
712         uiTriangleFakeAA(x2-8, (y2-(y2-y1)/2)-6,
713                                         x2-6, (y2-(y2-y1)/2)-2,
714                                         x2-11, (y2-(y2-y1)/2)-2);
715 }
716
717 /* left/right arrows for number fields */
718 static void ui_default_num_arrows(float x1, float y1, float x2, float y2)
719 {
720         if( x2-x1 > 25) {       // 25 is a bit arbitrary, but small buttons cant have arrows
721
722                 /* 'point' first, then two base vertices */
723                 uiTriangleFakeAA(x1+4, y2-(y2-y1)/2,
724                                                 x1+9, y2-(y2-y1)/2+3,
725                                                 x1+9, y2-(y2-y1)/2-3);
726
727                 uiTriangleFakeAA(x2-4, y2-(y2-y1)/2,
728                                                 x2-9, y2-(y2-y1)/2+3,
729                                                 x2-9, y2-(y2-y1)/2-3);
730         }
731 }
732
733
734 /* changing black/white for TOG3 buts */
735 static void ui_tog3_invert(float x1, float y1, float x2, float y2, int seltype)
736 {
737
738         if (seltype == 0) {
739                 UI_ThemeColorShade(TH_BUT_SETTING, -120); 
740                 
741                 glEnable( GL_LINE_SMOOTH );
742                 glEnable( GL_BLEND );
743                 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
744                 glLineWidth(1.0);
745                 
746                 fdrawline(x1+10, (y1+(y2-y1)/2+4), x1+10, (y1+(y2-y1)/2)-4);
747                 fdrawline(x1+6, (y1+(y2-y1)/2), x1+14, (y1+(y2-y1)/2));
748                 
749                 glLineWidth(1.0);
750                 glDisable( GL_BLEND );
751                 glDisable( GL_LINE_SMOOTH );
752         } else {
753                 /* horiz line */
754                 UI_ThemeColorShade(TH_BUT_SETTING, -120);
755                 
756                 glEnable( GL_LINE_SMOOTH );
757                 glEnable( GL_BLEND );
758                 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
759                 glLineWidth(1.0);
760                 
761                 fdrawline(x1+6, (y1+(y2-y1)/2), x1+14, (y1+(y2-y1)/2));
762                 
763                 glLineWidth(1.0);
764                 glDisable( GL_BLEND );
765                 glDisable( GL_LINE_SMOOTH );
766                 
767         }
768 }
769
770 /* roundshaded button/popup menu/iconrow drawing code */
771 static void ui_roundshaded_button(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
772 {
773         float rad, maxrad;
774         int align= (flag & UI_BUT_ALIGN);
775         int round_align_fix= 0;
776         
777         /* rounded corners */
778         if (ELEM4(type, MENU, ROW, ICONROW, ICONTEXTROW)) maxrad = 5.0;
779         else maxrad= 10.0;
780         
781         rad= (y2-y1)/2.0;
782         if (rad>(x2-x1)/2) rad = (x2-x1)/2;
783         if (rad > maxrad) rad = maxrad;
784
785         /* end rounded corners */
786         
787         /* alignment */
788         if(align) {
789                 switch(align) {
790                         case UI_BUT_ALIGN_TOP:
791                                 uiSetRoundBox(12);
792                                 round_align_fix= 4;
793                                 break;
794                         case UI_BUT_ALIGN_DOWN:
795                                 uiSetRoundBox(3);
796                                 round_align_fix= 2;
797                                 break;
798                         case UI_BUT_ALIGN_LEFT:
799                                 uiSetRoundBox(6);
800                                 round_align_fix= 6;
801                                 break;
802                         case UI_BUT_ALIGN_RIGHT:
803                                 uiSetRoundBox(9);
804                                 round_align_fix= 9;
805                                 break;
806                                 
807                         case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT:
808                                 uiSetRoundBox(1);
809                                 round_align_fix= 0;
810                                 break;
811                         case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT:
812                                 uiSetRoundBox(2);
813                                 round_align_fix= 2;
814                                 break;
815                         case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_RIGHT:
816                                 uiSetRoundBox(8);
817                                 round_align_fix= 0;
818                                 break;
819                         case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_LEFT:
820                                 uiSetRoundBox(4);
821                                 round_align_fix= 4;
822                                 break;
823                                 
824                         default:
825                                 uiSetRoundBox(0);
826                                 round_align_fix= 0;
827                                 break;
828                 }
829         } 
830         else {
831                 uiSetRoundBox(15);
832                 if (x2 - x1 > 19) {
833                         round_align_fix= 6;
834                 } else {
835                         round_align_fix= 15;
836                 }
837         }
838         /* end alignment */
839         
840         
841         /* draw the base button */
842         round_button_shaded(type, colorid, asp, x1, y1, x2, y2, flag, rad);
843         
844         /* *** EXTRA DRAWING FOR SPECIFIC CONTROL TYPES *** */
845         switch(type) {
846                 case ICONROW:
847                 case ICONTEXTROW:                       
848                         /* iconrow double arrow  */
849                         if(flag & UI_SELECT) {
850                                 UI_ThemeColorShade(colorid, -80);
851                         } else {
852                                 UI_ThemeColorShade(colorid, -45);
853                         }
854                                 ui_default_iconrow_arrows(x1, y1, x2, y2);
855                         /* end iconrow double arrow */
856                         break;
857                 case MENU:
858                         /* menu double arrow  */
859                         if(flag & UI_SELECT) {
860                                 UI_ThemeColorShade(colorid, -110);
861                         } else {
862                                 UI_ThemeColorShade(colorid, -80);
863                         }
864                         ui_default_menu_arrows(x1, y1, x2, y2);
865                         /* end menu double arrow */
866                         break;
867         }       
868 }
869
870 static void ui_roundshaded_flat(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
871 {
872         float rad, maxrad=10.0;
873         int align= (flag & UI_BUT_ALIGN);
874         
875         /* rounded corners */
876         rad= (y2-y1)/2.0;
877         if (rad>(x2-x1)/2) rad = (x2-x1)/2;
878         if (maxrad) {
879                 if (rad > maxrad) rad = maxrad;
880         }
881         /* end rounded corners */
882         
883         /* alignment */
884         if(align) {
885                 switch(align) {
886                         case UI_BUT_ALIGN_TOP:
887                                 uiSetRoundBox(12);
888                                 break;
889                         case UI_BUT_ALIGN_DOWN:
890                                 uiSetRoundBox(3);
891                                 break;
892                         case UI_BUT_ALIGN_LEFT:
893                                 uiSetRoundBox(6);
894                                 break;
895                         case UI_BUT_ALIGN_RIGHT:
896                                 uiSetRoundBox(9);
897                                 break;
898                                 
899                         case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT:
900                                 uiSetRoundBox(1);
901                                 break;
902                         case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT:
903                                 uiSetRoundBox(2);
904                                 break;
905                         case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_RIGHT:
906                                 uiSetRoundBox(8);
907                                 break;
908                         case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_LEFT:
909                                 uiSetRoundBox(4);
910                                 break;
911                                 
912                         default:
913                                 uiSetRoundBox(0);
914                                 break;
915                 }
916         } 
917         else {
918                 uiSetRoundBox(15);
919         }
920         /* end alignment */
921         
922         /* draw the base button */
923         round_button_flat(colorid, asp, x1, y1, x2, y2, flag, rad);
924         
925         /* *** EXTRA DRAWING FOR SPECIFIC CONTROL TYPES *** */
926         switch(type) {
927                 case TOG:
928                 case TOGN:
929                 case TOG3:
930                         if (!(flag & UI_HAS_ICON)) {
931                                 /* check to see that there's room for the check mark
932                                 * draw a check mark, or if it's a TOG3, draw a + or - */
933                                 if (x2 - x1 > 20) {
934                                         uiSetRoundBox(15);
935                                         UI_ThemeColorShade(colorid, -5);
936                                         gl_round_box_shade(GL_POLYGON, x1+4, (y1+(y2-y1)/2)-5, x1+14, (y1+(y2-y1)/2)+4, 2, -0.04, 0.03);
937                                         
938                                         UI_ThemeColorShade(colorid, -20);
939                                         gl_round_box(GL_LINE_LOOP, x1+4, (y1+(y2-y1)/2)-5, x1+14, (y1+(y2-y1)/2)+4, 2);
940                                         
941                                         /* TOG3 is handled with ui_tog3_invert() 
942                                                 *  remember to update checkmark drawing there too*/
943                                         if((flag & UI_SELECT) && (type != TOG3)) {
944                                                 UI_ThemeColorShade(colorid, -140);
945                                                 
946                                                 glEnable( GL_LINE_SMOOTH );
947                                                 glEnable( GL_BLEND );
948                                                 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
949                                                 glLineWidth(1.5);
950                                                 
951                                                 /* checkmark */
952                                                 glBegin( GL_LINE_STRIP );
953                                                 glVertex2f(x1+5, (y1+(y2-y1)/2)-1);
954                                                 glVertex2f(x1+8, (y1+(y2-y1)/2)-4);
955                                                 glVertex2f(x1+13, (y1+(y2-y1)/2)+5);
956                                                 glEnd();
957                                                 
958                                                 glLineWidth(1.0);
959                                                 glDisable( GL_BLEND );
960                                                 glDisable( GL_LINE_SMOOTH );            
961                                         }
962                                         /* draw a dot: alternate, for layers etc. */
963                                 } else if(flag & UI_SELECT) {
964                                         uiSetRoundBox(15);
965                                         UI_ThemeColorShade(colorid, -60);
966                                         
967                                         glPushMatrix();
968                                         glTranslatef((x1+(x2-x1)/2), (y1+(y2-y1)/2), 0.0);
969                                         
970                                         /* circle */
971                                         glutil_draw_filled_arc(0.0, M_PI*2.0, 2, 16);
972                                         
973                                         glEnable( GL_LINE_SMOOTH );
974                                         glEnable( GL_BLEND );
975                                         glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
976                                         
977                                         /* smooth outline */
978                                         glutil_draw_lined_arc(0.0, M_PI*2.0, 2, 16);
979                                         
980                                         glDisable( GL_BLEND );
981                                         glDisable( GL_LINE_SMOOTH );
982                                         
983                                         glPopMatrix();
984                                 }
985                         }
986                         break;
987                 case NUM:
988                         /* side arrows */
989                         if(flag & UI_SELECT) {
990                                 if(flag & UI_ACTIVE) UI_ThemeColorShade(colorid, -70);
991                                 else UI_ThemeColorShade(colorid, -70);
992                         } else {
993                                 if(flag & UI_ACTIVE) UI_ThemeColorShade(colorid, -40);
994                                 else UI_ThemeColorShade(colorid, -20);
995                         }
996                         
997                         ui_default_num_arrows(x1, y1, x2, y2);
998                         /* end side arrows */
999                         break;
1000         }       
1001 }
1002
1003 /* roundshaded theme callback */
1004 static void ui_draw_roundshaded(int type, int colorid, float aspect, float x1, float y1, float x2, float y2, int flag)
1005 {
1006         
1007         switch(type) {
1008                 case TOG:
1009                 case TOGN:
1010                 case TOG3:
1011                 case SLI:
1012                 case NUMSLI:
1013                 case HSVSLI:
1014                 case TEX:
1015                 case IDPOIN:
1016                 case NUM:
1017                         ui_roundshaded_flat(type, colorid, aspect, x1, y1, x2, y2, flag);
1018                         break;
1019                 case ICONROW: 
1020                 case ICONTEXTROW: 
1021                 case MENU: 
1022                 default: 
1023                         ui_roundshaded_button(type, colorid, aspect, x1, y1, x2, y2, flag);
1024         }
1025         
1026 }
1027
1028 /* button/popup menu/iconrow drawing code */
1029 static void ui_default_button(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1030 {
1031         int align= (flag & UI_BUT_ALIGN);
1032
1033         if(align) {
1034         
1035                 /* *** BOTTOM OUTER SUNKEN EFFECT *** */
1036                 if (!((align == UI_BUT_ALIGN_DOWN) ||
1037                         (align == (UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT)) ||
1038                         (align == (UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT)))) {
1039                         glEnable(GL_BLEND);
1040                         MM_WHITE_OP;
1041                         fdrawline(x1, y1-1, x2, y1-1);  
1042                         glDisable(GL_BLEND);
1043                 }
1044                 /* *** END BOTTOM OUTER SUNKEN EFFECT *** */
1045                 
1046                 switch(align) {
1047                 case UI_BUT_ALIGN_TOP:
1048                         uiSetRoundBox(12);
1049                         
1050                         /* last arg in shaded_button() determines whether the button is in the middle of
1051                          * an alignment group or not. 0 = not middle, 1 = is in the middle.
1052                          * Done to allow cleaner drawing
1053                          */
1054                          
1055                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1056                         break;
1057                 case UI_BUT_ALIGN_DOWN:
1058                         uiSetRoundBox(3);
1059                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1060                         break;
1061                 case UI_BUT_ALIGN_LEFT:
1062                         
1063                         /* RIGHT OUTER SUNKEN EFFECT */
1064                         glEnable(GL_BLEND);
1065                         glShadeModel(GL_SMOOTH);
1066                         glBegin(GL_LINES);
1067                         MM_WHITE_OP;
1068                         glVertex2f(x2+1,y1);
1069                         MM_WHITE_TR;
1070                         glVertex2f(x2+1,y2);
1071                         glEnd();
1072                         glDisable(GL_BLEND);
1073                         
1074                         uiSetRoundBox(6);
1075                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1076                         break;
1077                 case UI_BUT_ALIGN_RIGHT:
1078                 
1079                         /* LEFT OUTER SUNKEN EFFECT */
1080                         glEnable(GL_BLEND);
1081                         glShadeModel(GL_SMOOTH);
1082                         glBegin(GL_LINES);
1083                         MM_WHITE_OP;
1084                         glVertex2f(x1-1,y1);
1085                         MM_WHITE_TR;
1086                         glVertex2f(x1-1,y2);
1087                         glEnd();
1088                         glDisable(GL_BLEND);
1089                 
1090                         uiSetRoundBox(9);
1091                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1092                         break;
1093                         
1094                 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT:
1095                         uiSetRoundBox(1);
1096                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1097                         break;
1098                 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT:
1099                         uiSetRoundBox(2);
1100                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1101                         break;
1102                 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_RIGHT:
1103                 
1104                         /* LEFT OUTER SUNKEN EFFECT */
1105                         glEnable(GL_BLEND);
1106                         glShadeModel(GL_SMOOTH);
1107                         glBegin(GL_LINES);
1108                         MM_WHITE_OP;
1109                         glVertex2f(x1-1,y1);
1110                         MM_WHITE_TR;
1111                         glVertex2f(x1-1,y2);
1112                         glEnd();
1113                         glDisable(GL_BLEND);
1114                 
1115                         uiSetRoundBox(8);
1116                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1117                         break;
1118                 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_LEFT:
1119                 
1120                         /* RIGHT OUTER SUNKEN EFFECT */
1121                         glEnable(GL_BLEND);
1122                         glShadeModel(GL_SMOOTH);
1123                         glBegin(GL_LINES);
1124                         MM_WHITE_OP;
1125                         glVertex2f(x2+1,y1);
1126                         MM_WHITE_TR;
1127                         glVertex2f(x2+1,y2);
1128                         glEnd();
1129                         glDisable(GL_BLEND);
1130                         
1131                         uiSetRoundBox(4);
1132                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1133                         break;
1134                         
1135                 default:
1136                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 1);
1137                         break;
1138                 }
1139         } 
1140         else {  
1141                 glEnable(GL_BLEND);
1142                 glShadeModel(GL_SMOOTH);
1143                 
1144                 /* BOTTOM OUTER SUNKEN EFFECT */
1145                 MM_WHITE_OP;
1146                 fdrawline(x1, y1-1, x2, y1-1);  
1147                 
1148                 /* LEFT OUTER SUNKEN EFFECT */
1149                 glBegin(GL_LINES);
1150                 MM_WHITE_OP;
1151                 glVertex2f(x1-1,y1);
1152                 MM_WHITE_TR;
1153                 glVertex2f(x1-1,y2);
1154                 glEnd();
1155                 
1156                 /* RIGHT OUTER SUNKEN EFFECT */
1157                 glBegin(GL_LINES);
1158                 MM_WHITE_OP;
1159                 glVertex2f(x2+1,y1);
1160                 MM_WHITE_TR;
1161                 glVertex2f(x2+1,y2);
1162                 glEnd();
1163                 
1164                 glDisable(GL_BLEND);
1165         
1166                 uiSetRoundBox(15);
1167                 shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1168         }
1169         
1170         /* *** EXTRA DRAWING FOR SPECIFIC CONTROL TYPES *** */
1171         switch(type) {
1172         case ICONROW:
1173         case ICONTEXTROW:
1174                 /* DARKENED AREA */
1175                 glEnable(GL_BLEND);
1176                 
1177                 glColor4ub(0, 0, 0, 30);
1178                 glRectf(x2-9, y1, x2, y2);
1179         
1180                 glDisable(GL_BLEND);
1181                 /* END DARKENED AREA */
1182         
1183                 /* ICONROW DOUBLE-ARROW  */
1184                 M_DARK;
1185                 ui_default_iconrow_arrows(x1, y1, x2, y2);
1186                 /* END ICONROW DOUBLE-ARROW */
1187                 break;
1188         case MENU:
1189                 /* DARKENED AREA */
1190                 glEnable(GL_BLEND);
1191                 
1192                 glColor4ub(0, 0, 0, 30);
1193                 glRectf(x2-18, y1, x2, y2);
1194         
1195                 glDisable(GL_BLEND);
1196                 /* END DARKENED AREA */
1197         
1198                 /* MENU DOUBLE-ARROW  */
1199                 M_DARK;
1200                 ui_default_menu_arrows(x1, y1, x2, y2);
1201                 /* MENU DOUBLE-ARROW */
1202                 break;
1203         }       
1204 }
1205
1206 /* number/text field drawing code */
1207 static void ui_default_flat(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1208 {
1209         int align= (flag & UI_BUT_ALIGN);
1210
1211         if(align) {
1212         
1213                 /* *** BOTTOM OUTER SUNKEN EFFECT *** */
1214                 if (!((align == UI_BUT_ALIGN_DOWN) ||
1215                         (align == (UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT)) ||
1216                         (align == (UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT)))) {
1217                         glEnable(GL_BLEND);
1218                         MM_WHITE_OP;
1219                         fdrawline(x1, y1-1, x2, y1-1);  
1220                         glDisable(GL_BLEND);
1221                 }
1222                 /* *** END BOTTOM OUTER SUNKEN EFFECT *** */
1223                 
1224                 switch(align) {
1225                 case UI_BUT_ALIGN_TOP:
1226                         uiSetRoundBox(12);
1227                         
1228                         /* last arg in shaded_button() determines whether the button is in the middle of
1229                          * an alignment group or not. 0 = not middle, 1 = is in the middle.
1230                          * Done to allow cleaner drawing
1231                          */
1232                          
1233                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1234                         break;
1235                 case UI_BUT_ALIGN_DOWN:
1236                         uiSetRoundBox(3);
1237                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1238                         break;
1239                 case UI_BUT_ALIGN_LEFT:
1240                         
1241                         /* RIGHT OUTER SUNKEN EFFECT */
1242                         glEnable(GL_BLEND);
1243                         glShadeModel(GL_SMOOTH);
1244                         glBegin(GL_LINES);
1245                         MM_WHITE_OP;
1246                         glVertex2f(x2+1,y1);
1247                         MM_WHITE_TR;
1248                         glVertex2f(x2+1,y2);
1249                         glEnd();
1250                         glDisable(GL_BLEND);
1251                         
1252                         uiSetRoundBox(6);
1253                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1254                         break;
1255                 case UI_BUT_ALIGN_RIGHT:
1256                 
1257                         /* LEFT OUTER SUNKEN EFFECT */
1258                         glEnable(GL_BLEND);
1259                         glShadeModel(GL_SMOOTH);
1260                         glBegin(GL_LINES);
1261                         MM_WHITE_OP;
1262                         glVertex2f(x1-1,y1);
1263                         MM_WHITE_TR;
1264                         glVertex2f(x1-1,y2);
1265                         glEnd();
1266                         glDisable(GL_BLEND);
1267                 
1268                         uiSetRoundBox(9);
1269                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1270                         break;
1271                         
1272                 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT:
1273                         uiSetRoundBox(1);
1274                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1275                         break;
1276                 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT:
1277                         uiSetRoundBox(2);
1278                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1279                         break;
1280                 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_RIGHT:
1281                 
1282                         /* LEFT OUTER SUNKEN EFFECT */
1283                         glEnable(GL_BLEND);
1284                         glShadeModel(GL_SMOOTH);
1285                         glBegin(GL_LINES);
1286                         MM_WHITE_OP;
1287                         glVertex2f(x1-1,y1);
1288                         MM_WHITE_TR;
1289                         glVertex2f(x1-1,y2);
1290                         glEnd();
1291                         glDisable(GL_BLEND);
1292                 
1293                         uiSetRoundBox(8);
1294                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1295                         break;
1296                 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_LEFT:
1297                 
1298                         /* RIGHT OUTER SUNKEN EFFECT */
1299                         glEnable(GL_BLEND);
1300                         glShadeModel(GL_SMOOTH);
1301                         glBegin(GL_LINES);
1302                         MM_WHITE_OP;
1303                         glVertex2f(x2+1,y1);
1304                         MM_WHITE_TR;
1305                         glVertex2f(x2+1,y2);
1306                         glEnd();
1307                         glDisable(GL_BLEND);
1308                         
1309                         uiSetRoundBox(4);
1310                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1311                         break;
1312                         
1313                 default:
1314                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 1);
1315                         break;
1316                 }
1317         } 
1318         else {
1319         
1320                 glEnable(GL_BLEND);
1321                 glShadeModel(GL_SMOOTH);
1322                 
1323                 /* BOTTOM OUTER SUNKEN EFFECT */
1324                 MM_WHITE_OP;
1325                 fdrawline(x1, y1-1, x2, y1-1);  
1326                 
1327                 /* LEFT OUTER SUNKEN EFFECT */
1328                 glBegin(GL_LINES);
1329                 MM_WHITE_OP;
1330                 glVertex2f(x1-1,y1);
1331                 MM_WHITE_TR;
1332                 glVertex2f(x1-1,y2);
1333                 glEnd();
1334                 
1335                 /* RIGHT OUTER SUNKEN EFFECT */
1336                 glBegin(GL_LINES);
1337                 MM_WHITE_OP;
1338                 glVertex2f(x2+1,y1);
1339                 MM_WHITE_TR;
1340                 glVertex2f(x2+1,y2);
1341                 glEnd();
1342                 
1343                 glDisable(GL_BLEND);
1344
1345                 uiSetRoundBox(15);
1346                 flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1347         }
1348         
1349         /* *** EXTRA DRAWING FOR SPECIFIC CONTROL TYPES *** */
1350         switch(type) {
1351         case NUM:
1352         case NUMABS:
1353                 /* SIDE ARROWS */
1354                 /* left */
1355                 if(flag & UI_SELECT) {
1356                         if(flag & UI_ACTIVE) M_DARK;
1357                         else M_DARK;
1358                 } else {
1359                         if(flag & UI_ACTIVE) M_GREY;
1360                         else M_LGREY;
1361                 }
1362                 
1363                 ui_default_num_arrows(x1, y1, x2, y2);
1364                 /* END SIDE ARROWS */
1365         }
1366 }
1367
1368 static void ui_default_slider(int colorid, float fac, float aspect, float x1, float y1, float x2, float y2, int flag)
1369 {
1370         float ymid, yc;
1371
1372         /* the slider background line */
1373         ymid= (y1+y2)/2.0;
1374         //yc= 2.5*aspect;       // height of center line
1375         yc = 2.3; // height of center line
1376         
1377         if(flag & UI_SELECT) 
1378                         UI_ThemeColorShade(TH_BUT_NUM, -5);
1379         else {
1380                 if(flag & UI_ACTIVE) 
1381                         UI_ThemeColorShade(TH_BUT_NUM, +35); 
1382                 else
1383                         UI_ThemeColorShade(TH_BUT_NUM, +25); 
1384         }
1385
1386         glRectf(x1, ymid-yc, x2, ymid+yc);
1387         
1388         /* top inner bevel */
1389         if(flag & UI_SELECT) UI_ThemeColorShade(TH_BUT_NUM, -40); 
1390         else UI_ThemeColorShade(TH_BUT_NUM, -5); 
1391         fdrawline(x1+1, ymid+yc, x2, ymid+yc);
1392         
1393         /* bottom inner bevel */
1394         if(flag & UI_SELECT) UI_ThemeColorShade(TH_BUT_NUM, +15); 
1395         else UI_ThemeColorShade(TH_BUT_NUM, +45); 
1396         fdrawline(x1+1, ymid-yc, x2, ymid-yc);
1397         
1398         
1399         /* the movable slider */
1400         if(flag & UI_SELECT) UI_ThemeColorShade(TH_BUT_NUM, +80); 
1401         else UI_ThemeColorShade(TH_BUT_NUM, -45); 
1402
1403         glShadeModel(GL_SMOOTH);
1404         glBegin(GL_QUADS);
1405
1406         UI_ThemeColorShade(TH_BUT_NUM, -45); 
1407
1408         glVertex2f(x1,     y1+2.5);
1409         glVertex2f(x1+fac, y1+2.5);
1410
1411         UI_ThemeColor(TH_BUT_NUM); 
1412
1413         glVertex2f(x1+fac, y2-2.5);
1414         glVertex2f(x1,     y2-2.5);
1415
1416         glEnd();
1417         
1418
1419         /* slider handle center */
1420         glShadeModel(GL_SMOOTH);
1421         glBegin(GL_QUADS);
1422
1423         UI_ThemeColor(TH_BUT_NUM); 
1424         glVertex2f(x1+fac-3, y1+2);
1425         glVertex2f(x1+fac, y1+4);
1426         UI_ThemeColorShade(TH_BUT_NUM, +80); 
1427         glVertex2f(x1+fac, y2-2);
1428         glVertex2f(x1+fac-3, y2-2);
1429
1430         glEnd();
1431         
1432         /* slider handle left bevel */
1433         UI_ThemeColorShade(TH_BUT_NUM, +70); 
1434         fdrawline(x1+fac-3, y2-2, x1+fac-3, y1+2);
1435         
1436         /* slider handle right bevel */
1437         UI_ThemeColorShade(TH_BUT_NUM, -35); 
1438         fdrawline(x1+fac, y2-2, x1+fac, y1+2);
1439
1440         glShadeModel(GL_FLAT);
1441 }
1442
1443 /* default theme callback */
1444 static void ui_draw_default(int type, int colorid, float aspect, float x1, float y1, float x2, float y2, int flag)
1445 {
1446
1447         switch(type) {
1448         case TEX:
1449         case IDPOIN:
1450         case NUM:
1451         case NUMABS:
1452                 ui_default_flat(type, colorid, aspect, x1, y1, x2, y2, flag);
1453                 break;
1454         case ICONROW: 
1455         case ICONTEXTROW: 
1456         case MENU: 
1457         default: 
1458                 ui_default_button(type, colorid, aspect, x1, y1, x2, y2, flag);
1459         }
1460
1461 }
1462
1463
1464 /* *************** OLDSKOOL THEME ***************** */
1465
1466 static void ui_draw_outlineX(float x1, float y1, float x2, float y2, float asp1)
1467 {
1468         float vec[2];
1469         
1470         glBegin(GL_LINE_LOOP);
1471         vec[0]= x1+asp1; vec[1]= y1-asp1;
1472         glVertex2fv(vec);
1473         vec[0]= x2-asp1; 
1474         glVertex2fv(vec);
1475         vec[0]= x2+asp1; vec[1]= y1+asp1;
1476         glVertex2fv(vec);
1477         vec[1]= y2-asp1;
1478         glVertex2fv(vec);
1479         vec[0]= x2-asp1; vec[1]= y2+asp1;
1480         glVertex2fv(vec);
1481         vec[0]= x1+asp1;
1482         glVertex2fv(vec);
1483         vec[0]= x1-asp1; vec[1]= y2-asp1;
1484         glVertex2fv(vec);
1485         vec[1]= y1+asp1;
1486         glVertex2fv(vec);
1487         glEnd();                
1488         
1489 }
1490
1491
1492 static void ui_draw_oldskool(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1493 {
1494         /* paper */
1495         if(flag & UI_SELECT) {
1496                 if(flag & UI_ACTIVE) UI_ThemeColorShade(colorid, -40);
1497                 else UI_ThemeColorShade(colorid, -30);
1498         }
1499         else {
1500                 if(flag & UI_ACTIVE) UI_ThemeColorShade(colorid, +30);
1501                 else UI_ThemeColorShade(colorid, +20);
1502         }
1503         
1504         glRectf(x1+1, y1+1, x2-1, y2-1);
1505
1506         x1+= asp;
1507         x2-= asp;
1508         y1+= asp;
1509         y2-= asp;
1510
1511         /* below */
1512         if(flag & UI_SELECT) UI_ThemeColorShade(colorid, 0);
1513         else UI_ThemeColorShade(colorid, -30);
1514         fdrawline(x1, y1, x2, y1);
1515
1516         /* right */
1517         fdrawline(x2, y1, x2, y2);
1518         
1519         /* top */
1520         if(flag & UI_SELECT) UI_ThemeColorShade(colorid, -30);
1521         else UI_ThemeColorShade(colorid, 0);
1522         fdrawline(x1, y2, x2, y2);
1523
1524         /* left */
1525         fdrawline(x1, y1, x1, y2);
1526         
1527         /* outline */
1528         glColor3ub(0,0,0);
1529         ui_draw_outlineX(x1, y1, x2, y2, asp);
1530         
1531         
1532         /* special type decorations */
1533         switch(type) {
1534         case NUM:
1535         case NUMABS:
1536                 if(flag & UI_SELECT) UI_ThemeColorShade(colorid, -60);
1537                 else UI_ThemeColorShade(colorid, -30);
1538                 ui_default_num_arrows(x1, y1, x2, y2);
1539                 break;
1540
1541         case ICONROW: 
1542         case ICONTEXTROW: 
1543                 if(flag & UI_ACTIVE) UI_ThemeColorShade(colorid, 0);
1544                 else UI_ThemeColorShade(colorid, -10);
1545                 glRectf(x2-9, y1+asp, x2-asp, y2-asp);
1546
1547                 UI_ThemeColorShade(colorid, -50);
1548                 ui_default_iconrow_arrows(x1, y1, x2, y2);
1549                 break;
1550                 
1551         case MENU: 
1552                 if(flag & UI_ACTIVE) UI_ThemeColorShade(colorid, 0);
1553                 else UI_ThemeColorShade(colorid, -10);
1554                 glRectf(x2-17, y1+asp, x2-asp, y2-asp);
1555
1556                 UI_ThemeColorShade(colorid, -50);
1557                 ui_default_menu_arrows(x1, y1, x2, y2);
1558                 break;
1559         }
1560         
1561 }
1562
1563 /* *************** BASIC ROUNDED THEME ***************** */
1564
1565 static void round_button(float x1, float y1, float x2, float y2, float asp, 
1566                                                  int colorid, int round, int menudeco, int curshade)
1567 {
1568         float rad;
1569         char col[4];
1570         
1571         rad= (y2-y1)/2.0;
1572         if(rad>7.0) rad= 7.0;
1573         
1574         uiSetRoundBox(round);
1575         gl_round_box(GL_POLYGON, x1, y1, x2, y2, rad);
1576
1577         if(menudeco) {
1578                 uiSetRoundBox(round & ~9);
1579                 UI_ThemeColorShade(colorid, curshade-20);
1580                 gl_round_box(GL_POLYGON, x2-menudeco, y1, x2, y2, rad);
1581         }
1582         
1583         /* fake AA */
1584         uiSetRoundBox(round);
1585         glEnable( GL_BLEND );
1586
1587         UI_GetThemeColor3ubv(colorid, col);
1588                 
1589         if(col[0]<100) col[0]= 0; else col[0]-= 100;
1590         if(col[1]<100) col[1]= 0; else col[1]-= 100;
1591         if(col[2]<100) col[2]= 0; else col[2]-= 100;
1592         col[3]= 80;
1593         glColor4ubv((GLubyte *)col);
1594         gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, rad - asp);
1595         gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, rad + asp);
1596         col[3]= 180;
1597         glColor4ubv((GLubyte *)col);
1598         gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, rad);
1599
1600         glDisable( GL_BLEND );
1601 }
1602
1603 /* button in midst of alignment row */
1604 static void round_button_mid(float x1, float y1, float x2, float y2, float asp, 
1605                                                          int colorid, int align, int menudeco, int curshade)
1606 {
1607         glRectf(x1, y1, x2, y2);
1608         
1609         if(menudeco) {
1610                 UI_ThemeColorShade(colorid, curshade-20);
1611                 glRectf(x2-menudeco, y1, x2, y2);
1612         }
1613         
1614         UI_ThemeColorBlendShade(colorid, TH_BACK, 0.5, -70);
1615         // we draw full outline, its not AA, and it works better button mouse-over hilite
1616         
1617         // left right
1618         fdrawline(x1, y1, x1, y2);
1619         fdrawline(x2, y1, x2, y2);
1620
1621         // top down
1622         fdrawline(x1, y2, x2, y2);
1623         fdrawline(x1, y1, x2, y1);   
1624 }
1625
1626 static void ui_draw_round(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1627 {
1628         int align= (flag & UI_BUT_ALIGN);
1629         int curshade= 0, menudeco= 0;
1630         
1631         if(type==ICONROW || type==ICONTEXTROW) menudeco= 9;
1632         else if((type==MENU || type==BLOCK) && x2-x1>24) menudeco= 16;
1633         
1634         /* paper */
1635         if(flag & UI_SELECT) {
1636                 if(flag & UI_ACTIVE) curshade= -40;
1637                 else curshade= -30;
1638         }
1639         else {
1640                 if(flag & UI_ACTIVE) curshade= 30;
1641                 else curshade= +20;
1642         }
1643         
1644         UI_ThemeColorShade(colorid, curshade);
1645
1646         if(align) {
1647                 switch(align) {
1648                 case UI_BUT_ALIGN_TOP:
1649                         round_button(x1, y1, x2, y2, asp, colorid, 12, menudeco, curshade);
1650                         break;
1651                 case UI_BUT_ALIGN_DOWN:
1652                         round_button(x1, y1, x2, y2, asp, colorid, 3, menudeco, curshade);
1653                         break;
1654                 case UI_BUT_ALIGN_LEFT:
1655                         round_button(x1, y1, x2, y2, asp, colorid, 6, menudeco, curshade);
1656                         break;
1657                 case UI_BUT_ALIGN_RIGHT:
1658                         round_button(x1, y1, x2, y2, asp, colorid, 9, menudeco, curshade);
1659                         break;
1660                         
1661                 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT:
1662                         round_button(x1, y1, x2, y2, asp, colorid, 1, menudeco, curshade);
1663                         break;
1664                 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT:
1665                         round_button(x1, y1, x2, y2, asp, colorid, 2, menudeco, curshade);
1666                         break;
1667                 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_RIGHT:
1668                         round_button(x1, y1, x2, y2, asp, colorid, 8, menudeco, curshade);
1669                         break;
1670                 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_LEFT:
1671                         round_button(x1, y1, x2, y2, asp, colorid, 4, menudeco, curshade);
1672                         break;
1673                         
1674                 default:
1675                         round_button_mid(x1, y1, x2, y2, asp, colorid, align, menudeco, curshade);
1676                         break;
1677                 }
1678         } 
1679         else {
1680                 round_button(x1, y1, x2, y2, asp, colorid, 15, menudeco, curshade);
1681         }
1682
1683         /* special type decorations */
1684         switch(type) {
1685         case NUM:
1686         case NUMABS:
1687                 UI_ThemeColorShade(colorid, curshade-60);
1688                 ui_default_num_arrows(x1, y1, x2, y2);
1689                 break;
1690
1691         case ICONROW: 
1692         case ICONTEXTROW: 
1693                 UI_ThemeColorShade(colorid, curshade-60);
1694                 ui_default_iconrow_arrows(x1, y1, x2, y2);
1695                 break;
1696                 
1697         case MENU: 
1698         case BLOCK: 
1699                 UI_ThemeColorShade(colorid, curshade-60);
1700                 ui_default_menu_arrows(x1, y1, x2, y2);
1701                 break;
1702         }
1703 }
1704
1705 /* *************** MINIMAL THEME ***************** */
1706
1707 // theme can define an embosfunc and sliderfunc, text+icon drawing is standard, no theme.
1708
1709
1710
1711 /* super minimal button as used in logic menu */
1712 static void ui_draw_minimal(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1713 {
1714         /* too much space between buttons */
1715         
1716         if (type==TEX || type==IDPOIN) {
1717                 x1+= asp;
1718                 x2-= (asp*2);
1719                 //y1+= asp;
1720                 y2-= asp;
1721         } else {
1722                 /* Less space between buttons looks nicer */
1723                 y2-= asp;
1724                 x2-= asp;
1725         }
1726         
1727         /* paper */
1728         if(flag & UI_SELECT) {
1729                 if(flag & UI_ACTIVE) UI_ThemeColorShade(colorid, -40);
1730                 else UI_ThemeColorShade(colorid, -30);
1731         }
1732         else {
1733                 if(flag & UI_ACTIVE) UI_ThemeColorShade(colorid, +20);
1734                 else UI_ThemeColorShade(colorid, +10);
1735         }
1736         
1737         glRectf(x1, y1, x2, y2);
1738         
1739         if (type==TEX || type==IDPOIN) {
1740                 UI_ThemeColorShade(colorid, -60);
1741
1742                 /* top */
1743                 fdrawline(x1, y2, x2, y2);
1744                 /* left */
1745                 fdrawline(x1, y1, x1, y2);
1746                 
1747                 
1748                 /* text underline, some  */ 
1749                 UI_ThemeColorShade(colorid, +50);
1750                 glEnable(GL_LINE_STIPPLE);
1751                 glLineStipple(1, 0x8888);
1752                 fdrawline(x1+(asp*2), y1+(asp*3), x2-(asp*2), y1+(asp*3));
1753                 glDisable(GL_LINE_STIPPLE);
1754                 
1755                 
1756                 UI_ThemeColorShade(colorid, +60);
1757                 /* below */
1758                 fdrawline(x1, y1, x2, y1);
1759                 /* right */
1760                 fdrawline(x2, y1, x2, y2);
1761                 
1762         } else {
1763                 if(flag & UI_SELECT) {
1764                         UI_ThemeColorShade(colorid, -60);
1765
1766                         /* top */
1767                         fdrawline(x1, y2, x2, y2);
1768                         /* left */
1769                         fdrawline(x1, y1, x1, y2);
1770                         UI_ThemeColorShade(colorid, +40);
1771
1772                         /* below */
1773                         fdrawline(x1, y1, x2, y1);
1774                         /* right */
1775                         fdrawline(x2, y1, x2, y2);
1776                 }
1777                 else {
1778                         UI_ThemeColorShade(colorid, +40);
1779
1780                         /* top */
1781                         fdrawline(x1, y2, x2, y2);
1782                         /* left */
1783                         fdrawline(x1, y1, x1, y2);
1784                         
1785                         UI_ThemeColorShade(colorid, -60);
1786                         /* below */
1787                         fdrawline(x1, y1, x2, y1);
1788                         /* right */
1789                         fdrawline(x2, y1, x2, y2);
1790                 }
1791         }
1792         
1793         /* special type decorations */
1794         switch(type) {
1795         case NUM:
1796         case NUMABS:
1797                 if(flag & UI_SELECT) UI_ThemeColorShade(colorid, -60);
1798                 else UI_ThemeColorShade(colorid, -30);
1799                 ui_default_num_arrows(x1, y1, x2, y2);
1800                 break;
1801
1802         case ICONROW: 
1803         case ICONTEXTROW: 
1804                 if(flag & UI_ACTIVE) UI_ThemeColorShade(colorid, 0);
1805                 else UI_ThemeColorShade(colorid, -10);
1806                 glRectf(x2-9, y1+asp, x2-asp, y2-asp);
1807
1808                 UI_ThemeColorShade(colorid, -50);
1809                 ui_default_iconrow_arrows(x1, y1, x2, y2);
1810                 break;
1811                 
1812         case MENU: 
1813         case BLOCK: 
1814                 if(flag & UI_ACTIVE) UI_ThemeColorShade(colorid, 0);
1815                 else UI_ThemeColorShade(colorid, -10);
1816                 glRectf(x2-17, y1+asp, x2-asp, y2-asp);
1817
1818                 UI_ThemeColorShade(colorid, -50);
1819                 ui_default_menu_arrows(x1, y1, x2, y2);
1820                 break;
1821         }
1822         
1823         
1824 }
1825
1826
1827 /* fac is the slider handle position between x1 and x2 */
1828 static void ui_draw_slider(int colorid, float fac, float aspect, float x1, float y1, float x2, float y2, int flag)
1829 {
1830         float ymid, yc;
1831
1832         /* the slider background line */
1833         ymid= (y1+y2)/2.0;
1834         yc= 1.7*aspect; 
1835
1836         if(flag & UI_ACTIVE) 
1837                 UI_ThemeColorShade(colorid, -50); 
1838         else 
1839                 UI_ThemeColorShade(colorid, -40); 
1840
1841         /* left part */
1842         glRectf(x1, ymid-2.0*yc, x1+fac, ymid+2.0*yc);
1843         /* right part */
1844         glRectf(x1+fac, ymid-yc, x2, ymid+yc);
1845
1846         /* the movable slider */
1847         
1848         UI_ThemeColorShade(colorid, +70); 
1849         glRectf(x1+fac-aspect, ymid-2.0*yc, x1+fac+aspect, ymid+2.0*yc);
1850
1851 }
1852
1853 /* ************** STANDARD MENU DRAWING FUNCTION ************* */
1854
1855
1856 static void ui_shadowbox(float minx, float miny, float maxx, float maxy, float shadsize, unsigned char alpha)
1857 {
1858         glEnable(GL_BLEND);
1859         glShadeModel(GL_SMOOTH);
1860         
1861         /* right quad */
1862         glBegin(GL_POLYGON);
1863         glColor4ub(0, 0, 0, alpha);
1864         glVertex2f(maxx, miny);
1865         glVertex2f(maxx, maxy-shadsize);
1866         glColor4ub(0, 0, 0, 0);
1867         glVertex2f(maxx+shadsize, maxy-shadsize-shadsize);
1868         glVertex2f(maxx+shadsize, miny);
1869         glEnd();
1870         
1871         /* corner shape */
1872         glBegin(GL_POLYGON);
1873         glColor4ub(0, 0, 0, alpha);
1874         glVertex2f(maxx, miny);
1875         glColor4ub(0, 0, 0, 0);
1876         glVertex2f(maxx+shadsize, miny);
1877         glVertex2f(maxx+0.7*shadsize, miny-0.7*shadsize);
1878         glVertex2f(maxx, miny-shadsize);
1879         glEnd();
1880         
1881         /* bottom quad */               
1882         glBegin(GL_POLYGON);
1883         glColor4ub(0, 0, 0, alpha);
1884         glVertex2f(minx+shadsize, miny);
1885         glVertex2f(maxx, miny);
1886         glColor4ub(0, 0, 0, 0);
1887         glVertex2f(maxx, miny-shadsize);
1888         glVertex2f(minx+shadsize+shadsize, miny-shadsize);
1889         glEnd();
1890         
1891         glDisable(GL_BLEND);
1892         glShadeModel(GL_FLAT);
1893 }
1894
1895 void uiDrawBoxShadow(unsigned char alpha, float minx, float miny, float maxx, float maxy)
1896 {
1897         /* accumulated outline boxes to make shade not linear, is more pleasant */
1898         ui_shadowbox(minx, miny, maxx, maxy, 6.0, (30*alpha)>>8);
1899         ui_shadowbox(minx, miny, maxx, maxy, 4.0, (70*alpha)>>8);
1900         ui_shadowbox(minx, miny, maxx, maxy, 2.0, (100*alpha)>>8);
1901         
1902 }
1903
1904 // background for pulldowns, pullups, and other drawing temporal menus....
1905 // has to be made themable still (now only color)
1906
1907 void uiDrawMenuBox(float minx, float miny, float maxx, float maxy, short flag)
1908 {
1909         char col[4];
1910         UI_GetThemeColor4ubv(TH_MENU_BACK, col);
1911         
1912         if( (flag & UI_BLOCK_NOSHADOW)==0) {
1913                 /* accumulated outline boxes to make shade not linear, is more pleasant */
1914                 ui_shadowbox(minx, miny, maxx, maxy, 6.0, (30*col[3])>>8);
1915                 ui_shadowbox(minx, miny, maxx, maxy, 4.0, (70*col[3])>>8);
1916                 ui_shadowbox(minx, miny, maxx, maxy, 2.0, (100*col[3])>>8);
1917                 
1918                 glEnable(GL_BLEND);
1919                 glColor4ubv((GLubyte *)col);
1920                 glRectf(minx-1, miny, minx, maxy);      // 1 pixel on left, to distinguish sublevel menus
1921         }
1922         glEnable(GL_BLEND);
1923         glColor4ubv((GLubyte *)col);
1924         glRectf(minx, miny, maxx, maxy);
1925         glDisable(GL_BLEND);
1926 }
1927
1928
1929
1930 /* pulldown menu item */
1931 static void ui_draw_pulldown_item(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1932 {
1933         char col[4];
1934         
1935         UI_GetThemeColor4ubv(TH_MENU_BACK, col);
1936         if(col[3]!=255) {
1937                 glEnable(GL_BLEND);
1938         }
1939         
1940         if((flag & UI_ACTIVE) && type!=LABEL) {
1941                 UI_ThemeColor4(TH_MENU_HILITE);
1942                 glRectf(x1, y1, x2, y2);
1943         
1944
1945         } else {
1946                 UI_ThemeColor4(colorid);        // is set at TH_MENU_ITEM when pulldown opened.
1947                 glRectf(x1, y1, x2, y2);
1948         }
1949
1950         glDisable(GL_BLEND);
1951 }
1952
1953 /* pulldown menu calling button */
1954 static void ui_draw_pulldown_round(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1955 {
1956         
1957         if(flag & UI_ACTIVE) {
1958                 UI_ThemeColor(TH_MENU_HILITE);
1959
1960                 uiSetRoundBox(15);
1961                 gl_round_box(GL_POLYGON, x1, y1+3, x2, y2-3, 7.0);
1962
1963                 glEnable( GL_LINE_SMOOTH );
1964                 glEnable( GL_BLEND );
1965                 gl_round_box(GL_LINE_LOOP, x1, y1+3, x2, y2-3, 7.0);
1966                 glDisable( GL_LINE_SMOOTH );
1967                 glDisable( GL_BLEND );
1968                 
1969         } else {
1970                 UI_ThemeColor(colorid); // is set at TH_MENU_ITEM when pulldown opened.
1971                 glRectf(x1-1, y1+2, x2+1, y2-2);
1972         }
1973         
1974 }
1975
1976 /* ************** TEXT AND ICON DRAWING FUNCTIONS ************* */
1977
1978
1979
1980 /* draws text and icons for buttons */
1981 static void ui_draw_text_icon(uiBut *but)
1982 {
1983         float x;
1984         int len;
1985         char *cpoin;
1986         short t, pos, ch;
1987         short selsta_tmp, selend_tmp, selsta_draw, selwidth_draw;
1988         
1989         /* check for button text label */
1990         if (but->type == ICONTEXTROW) {
1991                 ui_draw_icon(but, (BIFIconID) (but->icon+but->iconadd), 0);
1992         }
1993         else {
1994
1995                 /* text button selection and cursor */
1996                 if(but->editstr && but->pos != -1) {
1997                 
1998                         if ((but->selend - but->selsta) > 0) {
1999                                 /* text button selection */
2000                                 selsta_tmp = but->selsta + strlen(but->str);
2001                                 selend_tmp = but->selend + strlen(but->str);
2002                                         
2003                                 if(but->drawstr[0]!=0) {
2004                                         ch= but->drawstr[selsta_tmp];
2005                                         but->drawstr[selsta_tmp]= 0;
2006                                         
2007                                         selsta_draw = but->aspect*UI_GetStringWidth(but->font, but->drawstr+but->ofs, ui_translate_buttons()) + 3;
2008                                         
2009                                         but->drawstr[selsta_tmp]= ch;
2010                                         
2011                                         
2012                                         ch= but->drawstr[selend_tmp];
2013                                         but->drawstr[selend_tmp]= 0;
2014                                         
2015                                         selwidth_draw = but->aspect*UI_GetStringWidth(but->font, but->drawstr+but->ofs, ui_translate_buttons()) + 3;
2016                                         
2017                                         but->drawstr[selend_tmp]= ch;
2018                                         
2019                                         UI_ThemeColor(TH_BUT_TEXTFIELD_HI);
2020                                         glRects(but->x1+selsta_draw+1, but->y1+2, but->x1+selwidth_draw+1, but->y2-2);
2021                                 }
2022                         } else {
2023                                 /* text cursor */
2024                                 pos= but->pos+strlen(but->str);
2025                                 if(pos >= but->ofs) {
2026                                         if(but->drawstr[0]!=0) {
2027                                                 ch= but->drawstr[pos];
2028                                                 but->drawstr[pos]= 0;
2029                         
2030                                                 t= but->aspect*UI_GetStringWidth(but->font, but->drawstr+but->ofs, ui_translate_buttons()) + 3;
2031                                                 
2032                                                 but->drawstr[pos]= ch;
2033                                         }
2034                                         else t= 3;
2035                                         
2036                                         glColor3ub(255,0,0);
2037                                         glRects(but->x1+t, but->y1+2, but->x1+t+2, but->y2-2);
2038                                 }
2039                         }
2040                 }
2041                 
2042                 if(but->type==BUT_TOGDUAL) {
2043                         int dualset= 0;
2044                         if(but->pointype==SHO)
2045                                 dualset= BTST( *(((short *)but->poin)+1), but->bitnr);
2046                         else if(but->pointype==INT)
2047                                 dualset= BTST( *(((int *)but->poin)+1), but->bitnr);
2048                         
2049                         ui_draw_icon(but, ICON_DOT, dualset?0:-100);
2050                 }
2051                 
2052                 if(but->drawstr[0]!=0) {
2053                         int transopts;
2054                         int tog3= 0;
2055                         
2056                         // cut string in 2 parts
2057                         cpoin= strchr(but->drawstr, '|');
2058                         if(cpoin) *cpoin= 0;
2059
2060                         /* If there's an icon too (made with uiDefIconTextBut) then draw the icon
2061                         and offset the text label to accomodate it */
2062                         
2063                         /* XXX 2.50 need interface_icons.c */
2064 #if 0
2065                         if ( (but->flag & UI_HAS_ICON) && (but->flag & UI_ICON_LEFT) ) {
2066                                 ui_draw_icon(but, but->icon, 0);
2067
2068                                 if(but->editstr || (but->flag & UI_TEXT_LEFT)) x= but->x1 + but->aspect*UI_icon_get_width(but->icon)+5.0;
2069                                 else x= (but->x1+but->x2-but->strwidth+1)/2.0;
2070                         }
2071                         else
2072 #endif
2073                         {
2074                                 if(but->editstr || (but->flag & UI_TEXT_LEFT))
2075                                         x= but->x1+4.0;
2076                                 else if ELEM3(but->type, TOG, TOGN, TOG3)
2077                                         x= but->x1+18.0;        /* offset for checkmark */
2078                                 else
2079                                         x= (but->x1+but->x2-but->strwidth+1)/2.0;
2080                         }
2081                         
2082                         /* tog3 button exception; draws with glColor! */
2083                         if(but->type==TOG3 && (but->flag & UI_SELECT)) {
2084                                 
2085                                 if( but->pointype==CHA ) {
2086                                         if( BTST( *(but->poin+2), but->bitnr )) tog3= 1;
2087                                 }
2088                                 else if( but->pointype ==SHO ) {
2089                                         short *sp= (short *)but->poin;
2090                                         if( BTST( sp[1], but->bitnr )) tog3= 1;
2091                                 }
2092                                 
2093                                 ui_tog3_invert(but->x1,but->y1,but->x2,but->y2, tog3);
2094                                 if (tog3) glColor3ub(255, 255, 0);
2095                         }
2096                         
2097                         /* text color, with pulldown item exception */
2098                         if(tog3);       // color already set
2099                         else if(but->dt==UI_EMBOSSP) {
2100                                 if((but->flag & (UI_SELECT|UI_ACTIVE)) && but->type!=LABEL) {   // LABEL = title in pulldowns
2101                                         UI_ThemeColor(TH_MENU_TEXT_HI);
2102                                 } else {
2103                                         UI_ThemeColor(TH_MENU_TEXT);
2104                                 }
2105                         }
2106                         else {
2107                                 if(but->flag & UI_SELECT) {             
2108                                         UI_ThemeColor(TH_BUT_TEXT_HI);
2109                                 } else {
2110                                         UI_ThemeColor(TH_BUT_TEXT);
2111                                 }
2112                         }
2113
2114                         /* LABEL button exception */
2115                         if(but->type==LABEL && but->min!=0.0) UI_ThemeColor(TH_BUT_TEXT_HI);
2116                 
2117                         ui_rasterpos_safe(x, (but->y1+but->y2- 9.0)/2.0, but->aspect);
2118                         if(but->type==IDPOIN) transopts= 0;     // no translation, of course!
2119                         else transopts= ui_translate_buttons();
2120                         
2121                 #ifdef INTERNATIONAL
2122                         if (but->type == FTPREVIEW)
2123                                 FTF_DrawNewFontString (but->drawstr+but->ofs, FTF_INPUT_UTF8);
2124                         else
2125                                 UI_DrawString(but->font, but->drawstr+but->ofs, transopts);
2126                 #else
2127                         UI_DrawString(but->font, but->drawstr+but->ofs, transopts);
2128                 #endif
2129
2130                         /* part text right aligned */
2131                         if(cpoin) {
2132                                 len= UI_GetStringWidth(but->font, cpoin+1, ui_translate_buttons());
2133                                 ui_rasterpos_safe( but->x2 - len*but->aspect-3, (but->y1+but->y2- 9.0)/2.0, but->aspect);
2134                                 UI_DrawString(but->font, cpoin+1, ui_translate_buttons());
2135                                 *cpoin= '|';
2136                         }
2137                 }
2138                 /* if there's no text label, then check to see if there's an icon only and draw it */
2139                 else if( but->flag & UI_HAS_ICON ) {
2140                         ui_draw_icon(but, (BIFIconID) (but->icon+but->iconadd), 0);
2141                 }
2142         }
2143 }
2144
2145 static void ui_draw_but_COL(uiBut *but)
2146 {
2147         float *fp;
2148         char colr, colg, colb;
2149         
2150         if( but->pointype==FLO ) {
2151                 fp= (float *)but->poin;
2152                 colr= floor(255.0*fp[0]+0.5);
2153                 colg= floor(255.0*fp[1]+0.5);
2154                 colb= floor(255.0*fp[2]+0.5);
2155         }
2156         else {
2157                 char *cp= (char *)but->poin;
2158                 colr= cp[0];
2159                 colg= cp[1];
2160                 colb= cp[2];
2161         }
2162         
2163         /* exception... hrms, but can't simply use the emboss callback for this now. */
2164         /* this button type needs review, and nice integration with rest of API here */
2165         /* XXX 2.50 bad U global access */
2166         if(but->embossfunc == ui_draw_round) {
2167                 char *cp= UI_ThemeGetColorPtr(U.themes.first, 0, TH_CUSTOM);
2168                 cp[0]= colr; cp[1]= colg; cp[2]= colb;
2169                 but->flag &= ~UI_SELECT;
2170                 but->embossfunc(but->type, TH_CUSTOM, but->aspect, but->x1, but->y1, but->x2, but->y2, but->flag);
2171         }
2172         else
2173         {
2174                 
2175                 glColor3ub(colr,  colg,  colb);
2176                 glRectf((but->x1), (but->y1), (but->x2), (but->y2));
2177                 glColor3ub(0,  0,  0);
2178                 fdrawbox((but->x1), (but->y1), (but->x2), (but->y2));
2179         }
2180 }
2181
2182 /* draws in resolution of 20x4 colors */
2183 static void ui_draw_but_HSVCUBE(uiBut *but)
2184 {
2185         int a;
2186         float h,s,v;
2187         float dx, dy, sx1, sx2, sy, x, y;
2188         float col0[4][3];       // left half, rect bottom to top
2189         float col1[4][3];       // right half, rect bottom to top
2190         
2191         h= but->hsv[0];
2192         s= but->hsv[1];
2193         v= but->hsv[2];
2194         
2195         /* draw series of gouraud rects */
2196         glShadeModel(GL_SMOOTH);
2197         
2198         if(but->a1==0) {        // H and V vary
2199                 hsv_to_rgb(0.0, s, 0.0,   &col1[0][0], &col1[0][1], &col1[0][2]);
2200                 hsv_to_rgb(0.0, s, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]);
2201                 hsv_to_rgb(0.0, s, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]);
2202                 hsv_to_rgb(0.0, s, 1.0,   &col1[3][0], &col1[3][1], &col1[3][2]);
2203                 x= h; y= v;
2204         }
2205         else if(but->a1==1) {   // H and S vary
2206                 hsv_to_rgb(0.0, 0.0, v,   &col1[0][0], &col1[0][1], &col1[0][2]);
2207                 hsv_to_rgb(0.0, 0.333, v, &col1[1][0], &col1[1][1], &col1[1][2]);
2208                 hsv_to_rgb(0.0, 0.666, v, &col1[2][0], &col1[2][1], &col1[2][2]);
2209                 hsv_to_rgb(0.0, 1.0, v,   &col1[3][0], &col1[3][1], &col1[3][2]);
2210                 x= h; y= s;
2211         }
2212         else if(but->a1==2) {   // S and V vary
2213                 hsv_to_rgb(h, 0.0, 0.0,   &col1[0][0], &col1[0][1], &col1[0][2]);
2214                 hsv_to_rgb(h, 0.333, 0.0, &col1[1][0], &col1[1][1], &col1[1][2]);
2215                 hsv_to_rgb(h, 0.666, 0.0, &col1[2][0], &col1[2][1], &col1[2][2]);
2216                 hsv_to_rgb(h, 1.0, 0.0,   &col1[3][0], &col1[3][1], &col1[3][2]);
2217                 x= v; y= s;
2218         }
2219         else {          // only hue slider
2220                 hsv_to_rgb(0.0, 1.0, 1.0,   &col1[0][0], &col1[0][1], &col1[0][2]);
2221                 VECCOPY(col1[1], col1[0]);
2222                 VECCOPY(col1[2], col1[0]);
2223                 VECCOPY(col1[3], col1[0]);
2224                 x= h; y= 0.5;
2225         }
2226         
2227         for(dx=0.0; dx<1.0; dx+= 0.05) {
2228                 // previous color
2229                 VECCOPY(col0[0], col1[0]);
2230                 VECCOPY(col0[1], col1[1]);
2231                 VECCOPY(col0[2], col1[2]);
2232                 VECCOPY(col0[3], col1[3]);
2233
2234                 // new color
2235                 if(but->a1==0) {        // H and V vary
2236                         hsv_to_rgb(dx, s, 0.0,   &col1[0][0], &col1[0][1], &col1[0][2]);
2237                         hsv_to_rgb(dx, s, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]);
2238                         hsv_to_rgb(dx, s, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]);
2239                         hsv_to_rgb(dx, s, 1.0,   &col1[3][0], &col1[3][1], &col1[3][2]);
2240                 }
2241                 else if(but->a1==1) {   // H and S vary
2242                         hsv_to_rgb(dx, 0.0, v,   &col1[0][0], &col1[0][1], &col1[0][2]);
2243                         hsv_to_rgb(dx, 0.333, v, &col1[1][0], &col1[1][1], &col1[1][2]);
2244                         hsv_to_rgb(dx, 0.666, v, &col1[2][0], &col1[2][1], &col1[2][2]);
2245                         hsv_to_rgb(dx, 1.0, v,   &col1[3][0], &col1[3][1], &col1[3][2]);
2246                 }
2247                 else if(but->a1==2) {   // S and V vary
2248                         hsv_to_rgb(h, 0.0, dx,   &col1[0][0], &col1[0][1], &col1[0][2]);
2249                         hsv_to_rgb(h, 0.333, dx, &col1[1][0], &col1[1][1], &col1[1][2]);
2250                         hsv_to_rgb(h, 0.666, dx, &col1[2][0], &col1[2][1], &col1[2][2]);
2251                         hsv_to_rgb(h, 1.0, dx,   &col1[3][0], &col1[3][1], &col1[3][2]);
2252                 }
2253                 else {  // only H
2254                         hsv_to_rgb(dx, 1.0, 1.0,   &col1[0][0], &col1[0][1], &col1[0][2]);
2255                         VECCOPY(col1[1], col1[0]);
2256                         VECCOPY(col1[2], col1[0]);
2257                         VECCOPY(col1[3], col1[0]);
2258                 }
2259                 
2260                 // rect
2261                 sx1= but->x1 + dx*(but->x2-but->x1);
2262                 sx2= but->x1 + (dx+0.05)*(but->x2-but->x1);
2263                 sy= but->y1;
2264                 dy= (but->y2-but->y1)/3.0;
2265                 
2266                 glBegin(GL_QUADS);
2267                 for(a=0; a<3; a++, sy+=dy) {
2268                         glColor3fv(col0[a]);
2269                         glVertex2f(sx1, sy);
2270
2271                         glColor3fv(col1[a]);
2272                         glVertex2f(sx2, sy);
2273                         
2274                         glColor3fv(col1[a+1]);
2275                         glVertex2f(sx2, sy+dy);
2276                         
2277                         glColor3fv(col0[a+1]);
2278                         glVertex2f(sx1, sy+dy);
2279                 }
2280                 glEnd();
2281         }
2282
2283         glShadeModel(GL_FLAT);
2284
2285         /* cursor */
2286         x= but->x1 + x*(but->x2-but->x1);
2287         y= but->y1 + y*(but->y2-but->y1);
2288         CLAMP(x, but->x1+3.0, but->x2-3.0);
2289         CLAMP(y, but->y1+3.0, but->y2-3.0);
2290         
2291         fdrawXORcirc(x, y, 3.1);
2292
2293         /* outline */
2294         glColor3ub(0,  0,  0);
2295         fdrawbox((but->x1), (but->y1), (but->x2), (but->y2));
2296 }
2297
2298 #ifdef INTERNATIONAL
2299 static void ui_draw_but_CHARTAB(uiBut *but)
2300 {
2301         /* XXX 2.50 bad global access */
2302 #if 0
2303         /* Some local variables */
2304         float sx, sy, ex, ey;
2305         float width, height;
2306         float butw, buth;
2307         int x, y, cs;
2308         wchar_t wstr[2];
2309         unsigned char ustr[16];
2310         PackedFile *pf;
2311         int result = 0;
2312         int charmax = G.charmax;
2313         
2314         /* <builtin> font in use. There are TTF <builtin> and non-TTF <builtin> fonts */
2315         if(!strcmp(G.selfont->name, "<builtin>"))
2316         {
2317                 if(G.ui_international == TRUE)
2318                 {
2319                         charmax = 0xff;
2320                 }
2321                 else
2322                 {
2323                         charmax = 0xff;
2324                 }
2325         }
2326
2327         /* Category list exited without selecting the area */
2328         if(G.charmax == 0)
2329                 charmax = G.charmax = 0xffff;
2330
2331         /* Calculate the size of the button */
2332         width = abs(but->x2 - but->x1);
2333         height = abs(but->y2 - but->y1);
2334         
2335         butw = floor(width / 12);
2336         buth = floor(height / 6);
2337         
2338         /* Initialize variables */
2339         sx = but->x1;
2340         ex = but->x1 + butw;
2341         sy = but->y1 + height - buth;
2342         ey = but->y1 + height;
2343
2344         cs = G.charstart;
2345
2346         /* Set the font, in case it is not <builtin> font */
2347         if(G.selfont && strcmp(G.selfont->name, "<builtin>"))
2348         {
2349                 char tmpStr[256];
2350
2351                 // Is the font file packed, if so then use the packed file
2352                 if(G.selfont->packedfile)
2353                 {
2354                         pf = G.selfont->packedfile;             
2355                         FTF_SetFont(pf->data, pf->size, 14.0);
2356                 }
2357                 else
2358                 {
2359                         int err;
2360
2361                         strcpy(tmpStr, G.selfont->name);
2362                         BLI_convertstringcode(tmpStr, G.sce);
2363                         err = FTF_SetFont((unsigned char *)tmpStr, 0, 14.0);
2364                 }
2365         }
2366         else
2367         {
2368                 if(G.ui_international == TRUE)
2369                 {
2370                         FTF_SetFont((unsigned char *) datatoc_bfont_ttf, datatoc_bfont_ttf_size, 14.0);
2371                 }
2372         }
2373
2374         /* Start drawing the button itself */
2375         glShadeModel(GL_SMOOTH);
2376
2377         glColor3ub(200,  200,  200);
2378         glRectf((but->x1), (but->y1), (but->x2), (but->y2));
2379
2380         glColor3ub(0,  0,  0);
2381         for(y = 0; y < 6; y++)
2382         {
2383                 // Do not draw more than the category allows
2384                 if(cs > charmax) break;
2385
2386                 for(x = 0; x < 12; x++)
2387                 {
2388                         // Do not draw more than the category allows
2389                         if(cs > charmax) break;
2390
2391                         // Draw one grid cell
2392                         glBegin(GL_LINE_LOOP);
2393                                 glVertex2f(sx, sy);
2394                                 glVertex2f(ex, sy);
2395                                 glVertex2f(ex, ey);
2396                                 glVertex2f(sx, ey);                             
2397                         glEnd();        
2398
2399                         // Draw character inside the cell
2400                         memset(wstr, 0, sizeof(wchar_t)*2);
2401                         memset(ustr, 0, 16);
2402
2403                         // Set the font to be either unicode or <builtin>                               
2404                         wstr[0] = cs;
2405                         if(strcmp(G.selfont->name, "<builtin>"))
2406                         {
2407                                 wcs2utf8s((char *)ustr, (wchar_t *)wstr);
2408                         }
2409                         else
2410                         {
2411                                 if(G.ui_international == TRUE)
2412                                 {
2413                                         wcs2utf8s((char *)ustr, (wchar_t *)wstr);
2414                                 }
2415                                 else
2416                                 {
2417                                         ustr[0] = cs;
2418                                         ustr[1] = 0;
2419                                 }
2420                         }
2421
2422                         if((G.selfont && strcmp(G.selfont->name, "<builtin>")) || (G.selfont && !strcmp(G.selfont->name, "<builtin>") && G.ui_international == TRUE))
2423                         {
2424                                 float wid;
2425                                 float llx, lly, llz, urx, ury, urz;
2426                                 float dx, dy;
2427                                 float px, py;
2428         
2429                                 // Calculate the position
2430                                 wid = FTF_GetStringWidth((char *) ustr, FTF_USE_GETTEXT | FTF_INPUT_UTF8);
2431                                 FTF_GetBoundingBox((char *) ustr, &llx,&lly,&llz,&urx,&ury,&urz, FTF_USE_GETTEXT | FTF_INPUT_UTF8);
2432                                 dx = urx-llx;
2433                                 dy = ury-lly;
2434
2435                                 // This isn't fully functional since the but->aspect isn't working like I suspected
2436                                 px = sx + ((butw/but->aspect)-dx)/2;
2437                                 py = sy + ((buth/but->aspect)-dy)/2;
2438
2439                                 // Set the position and draw the character
2440                                 ui_rasterpos_safe(px, py, but->aspect);
2441                                 FTF_DrawString((char *) ustr, FTF_USE_GETTEXT | FTF_INPUT_UTF8);
2442                         }
2443                         else
2444                         {
2445                                 ui_rasterpos_safe(sx + butw/2, sy + buth/2, but->aspect);
2446                                 UI_DrawString(but->font, (char *) ustr, 0);
2447                         }
2448         
2449                         // Calculate the next position and character
2450                         sx += butw; ex +=butw;
2451                         cs++;
2452                 }
2453                 /* Add the y position and reset x position */
2454                 sy -= buth; 
2455                 ey -= buth;
2456                 sx = but->x1;
2457                 ex = but->x1 + butw;
2458         }       
2459         glShadeModel(GL_FLAT);
2460
2461         /* Return Font Settings to original */
2462         if(U.fontsize && U.fontname[0])
2463         {
2464                 result = FTF_SetFont((unsigned char *)U.fontname, 0, U.fontsize);
2465         }
2466         else if (U.fontsize)
2467         {
2468                 result = FTF_SetFont((unsigned char *) datatoc_bfont_ttf, datatoc_bfont_ttf_size, U.fontsize);
2469         }
2470
2471         if (result == 0)
2472         {
2473                 result = FTF_SetFont((unsigned char *) datatoc_bfont_ttf, datatoc_bfont_ttf_size, 11);
2474         }
2475         
2476         /* resets the font size */
2477         if(G.ui_international == TRUE)
2478         {
2479                 uiSetCurFont(but->block, UI_HELV);
2480         }
2481 #endif
2482 }
2483
2484 #endif // INTERNATIONAL
2485
2486 static void ui_draw_but_COLORBAND(uiBut *but)
2487 {
2488         ColorBand *coba;
2489         CBData *cbd;
2490         float x1, y1, sizex, sizey;
2491         float dx, v3[2], v1[2], v2[2], v1a[2], v2a[2];
2492         int a;
2493                 
2494         coba= (ColorBand *)(but->editcoba? but->editcoba: but->poin);
2495         if(coba==NULL) return;
2496         
2497         x1= but->x1;
2498         y1= but->y1;
2499         sizex= but->x2-x1;
2500         sizey= but->y2-y1;
2501         
2502         /* first background, to show tranparency */
2503         dx= sizex/12.0;
2504         v1[0]= x1;
2505         for(a=0; a<12; a++) {
2506                 if(a & 1) glColor3f(0.3, 0.3, 0.3); else glColor3f(0.8, 0.8, 0.8);
2507                 glRectf(v1[0], y1, v1[0]+dx, y1+0.5*sizey);
2508                 if(a & 1) glColor3f(0.8, 0.8, 0.8); else glColor3f(0.3, 0.3, 0.3);
2509                 glRectf(v1[0], y1+0.5*sizey, v1[0]+dx, y1+sizey);
2510                 v1[0]+= dx;
2511         }
2512         
2513         glShadeModel(GL_SMOOTH);
2514         glEnable(GL_BLEND);
2515         
2516         cbd= coba->data;
2517         
2518         v1[0]= v2[0]= x1;
2519         v1[1]= y1;
2520         v2[1]= y1+sizey;
2521         
2522         glBegin(GL_QUAD_STRIP);
2523         
2524         glColor4fv( &cbd->r );
2525         glVertex2fv(v1); glVertex2fv(v2);
2526         
2527         for(a=0; a<coba->tot; a++, cbd++) {
2528                 
2529                 v1[0]=v2[0]= x1+ cbd->pos*sizex;
2530                 
2531                 glColor4fv( &cbd->r );
2532                 glVertex2fv(v1); glVertex2fv(v2);
2533         }
2534         
2535         v1[0]=v2[0]= x1+ sizex;
2536         glVertex2fv(v1); glVertex2fv(v2);
2537         
2538         glEnd();
2539         glShadeModel(GL_FLAT);
2540         glDisable(GL_BLEND);
2541         
2542         /* outline */
2543         v1[0]= x1; v1[1]= y1;
2544         
2545         cpack(0x0);
2546         glBegin(GL_LINE_LOOP);
2547         glVertex2fv(v1);
2548         v1[0]+= sizex;
2549         glVertex2fv(v1);
2550         v1[1]+= sizey;
2551         glVertex2fv(v1);
2552         v1[0]-= sizex;
2553         glVertex2fv(v1);
2554         glEnd();
2555         
2556         
2557         /* help lines */
2558         v1[0]= v2[0]=v3[0]= x1;
2559         v1[1]= y1;
2560         v1a[1]= y1+0.25*sizey;
2561         v2[1]= y1+0.5*sizey;
2562         v2a[1]= y1+0.75*sizey;
2563         v3[1]= y1+sizey;
2564         
2565         
2566         cbd= coba->data;
2567         glBegin(GL_LINES);
2568         for(a=0; a<coba->tot; a++, cbd++) {
2569                 v1[0]=v2[0]=v3[0]=v1a[0]=v2a[0]= x1+ cbd->pos*sizex;
2570                 
2571                 if(a==coba->cur) {
2572                         glColor3ub(0, 0, 0);
2573                         glVertex2fv(v1);
2574                         glVertex2fv(v3);
2575                         glEnd();
2576                         
2577                         setlinestyle(2);
2578                         glBegin(GL_LINES);
2579                         glColor3ub(255, 255, 255);
2580                         glVertex2fv(v1);
2581                         glVertex2fv(v3);
2582                         glEnd();
2583                         setlinestyle(0);
2584                         glBegin(GL_LINES);
2585                         
2586                         /* glColor3ub(0, 0, 0);
2587                         glVertex2fv(v1);
2588                         glVertex2fv(v1a);
2589                         glColor3ub(255, 255, 255);
2590                         glVertex2fv(v1a);
2591                         glVertex2fv(v2);
2592                         glColor3ub(0, 0, 0);
2593                         glVertex2fv(v2);
2594                         glVertex2fv(v2a);
2595                         glColor3ub(255, 255, 255);
2596                         glVertex2fv(v2a);
2597                         glVertex2fv(v3);
2598                         */
2599                 }
2600                 else {
2601                         glColor3ub(0, 0, 0);
2602                         glVertex2fv(v1);
2603                         glVertex2fv(v2);
2604                         
2605                         glColor3ub(255, 255, 255);
2606                         glVertex2fv(v2);
2607                         glVertex2fv(v3);
2608                 }       
2609         }
2610         glEnd();
2611 }
2612
2613 static void ui_draw_but_NORMAL(uiBut *but)
2614 {
2615         static GLuint displist=0;
2616         int a, old[8];
2617         GLfloat diff[4], diffn[4]={1.0f, 1.0f, 1.0f, 1.0f};
2618         float vec0[4]={0.0f, 0.0f, 0.0f, 0.0f};
2619         float dir[4], size;
2620         
2621         /* store stuff */
2622         glGetMaterialfv(GL_FRONT, GL_DIFFUSE, diff);
2623                 
2624         /* backdrop */
2625         UI_ThemeColor(TH_BUT_NEUTRAL);
2626         uiSetRoundBox(15);
2627         gl_round_box(GL_POLYGON, but->x1, but->y1, but->x2, but->y2, 5.0f);
2628         
2629         /* sphere color */
2630         glMaterialfv(GL_FRONT, GL_DIFFUSE, diffn);
2631         glCullFace(GL_BACK); glEnable(GL_CULL_FACE);
2632         
2633         /* disable blender light */
2634         for(a=0; a<8; a++) {
2635                 old[a]= glIsEnabled(GL_LIGHT0+a);
2636                 glDisable(GL_LIGHT0+a);
2637         }
2638         
2639         /* own light */
2640         glEnable(GL_LIGHT7);
2641         glEnable(GL_LIGHTING);
2642         
2643         VECCOPY(dir, (float *)but->poin);
2644         dir[3]= 0.0f;   /* glLight needs 4 args, 0.0 is sun */
2645         glLightfv(GL_LIGHT7, GL_POSITION, dir); 
2646         glLightfv(GL_LIGHT7, GL_DIFFUSE, diffn); 
2647         glLightfv(GL_LIGHT7, GL_SPECULAR, vec0); 
2648         glLightf(GL_LIGHT7, GL_CONSTANT_ATTENUATION, 1.0f);
2649         glLightf(GL_LIGHT7, GL_LINEAR_ATTENUATION, 0.0f);
2650         
2651         /* transform to button */
2652         glPushMatrix();
2653         glTranslatef(but->x1 + 0.5f*(but->x2-but->x1), but->y1+ 0.5f*(but->y2-but->y1), 0.0f);
2654         size= (but->x2-but->x1)/200.f;
2655         glScalef(size, size, size);
2656                          
2657         if(displist==0) {
2658                 GLUquadricObj   *qobj;
2659                 
2660                 displist= glGenLists(1);
2661                 glNewList(displist, GL_COMPILE_AND_EXECUTE);
2662                 
2663                 qobj= gluNewQuadric();
2664                 gluQuadricDrawStyle(qobj, GLU_FILL); 
2665                 glShadeModel(GL_SMOOTH);
2666                 gluSphere( qobj, 100.0, 32, 24);
2667                 glShadeModel(GL_FLAT);
2668                 gluDeleteQuadric(qobj);  
2669                 
2670                 glEndList();
2671         }
2672         else glCallList(displist);
2673         
2674         /* restore */
2675         glPopMatrix();
2676         glDisable(GL_LIGHTING);
2677         glDisable(GL_CULL_FACE);
2678         glMaterialfv(GL_FRONT, GL_DIFFUSE, diff); 
2679         
2680         glDisable(GL_LIGHT7);
2681         
2682         /* enable blender light */
2683         for(a=0; a<8; a++) {
2684                 if(old[a])
2685                         glEnable(GL_LIGHT0+a);
2686         }
2687 }
2688
2689 static void ui_draw_but_curve_grid(uiBut *but, float zoomx, float zoomy, float offsx, float offsy, float step)
2690 {
2691         float dx, dy, fx, fy;
2692         
2693         glBegin(GL_LINES);
2694         dx= step*zoomx;
2695         fx= but->x1 + zoomx*(-offsx);
2696         if(fx > but->x1) fx -= dx*( floor(fx-but->x1));
2697         while(fx < but->x2) {
2698                 glVertex2f(fx, but->y1); 
2699                 glVertex2f(fx, but->y2);
2700                 fx+= dx;
2701         }
2702         
2703         dy= step*zoomy;
2704         fy= but->y1 + zoomy*(-offsy);
2705         if(fy > but->y1) fy -= dy*( floor(fy-but->y1));
2706         while(fy < but->y2) {
2707                 glVertex2f(but->x1, fy); 
2708                 glVertex2f(but->x2, fy);
2709                 fy+= dy;
2710         }
2711         glEnd();
2712         
2713 }
2714
2715 static void ui_draw_but_CURVE(uiBut *but)
2716 {
2717         CurveMapping *cumap;
2718         CurveMap *cuma;
2719         CurveMapPoint *cmp;
2720         float fx, fy, dx, dy, fac[2], zoomx, zoomy, offsx, offsy;
2721         GLint scissor[4];
2722         int a;
2723
2724         cumap= (CurveMapping *)(but->editcumap? but->editcumap: but->poin);
2725         cuma= cumap->cm+cumap->cur;
2726         
2727         /* need scissor test, curve can draw outside of boundary */
2728         glGetIntegerv(GL_VIEWPORT, scissor);
2729         fx= but->x1; fy= but->y1;
2730         /* XXX 2.50 need context: ui_graphics_to_window(but->win, &fx, &fy); */
2731         dx= but->x2; dy= but->y2;
2732         /* XXX 2.50 need context: ui_graphics_to_window(but->win, &dx, &dy); */
2733         //glScissor((int)floor(fx), (int)floor(fy), (int)ceil(dx-fx), (int)ceil(dy-fy));
2734         
2735         /* calculate offset and zoom */
2736         zoomx= (but->x2-but->x1-2.0*but->aspect)/(cumap->curr.xmax - cumap->curr.xmin);
2737         zoomy= (but->y2-but->y1-2.0*but->aspect)/(cumap->curr.ymax - cumap->curr.ymin);
2738         offsx= cumap->curr.xmin-but->aspect/zoomx;
2739         offsy= cumap->curr.ymin-but->aspect/zoomy;
2740         
2741         /* backdrop */
2742         if(cumap->flag & CUMA_DO_CLIP) {
2743                 UI_ThemeColorShade(TH_BUT_NEUTRAL, -20);
2744                 glRectf(but->x1, but->y1, but->x2, but->y2);
2745                 UI_ThemeColor(TH_BUT_NEUTRAL);
2746                 glRectf(but->x1 + zoomx*(cumap->clipr.xmin-offsx),
2747                                 but->y1 + zoomy*(cumap->clipr.ymin-offsy),
2748                                 but->x1 + zoomx*(cumap->clipr.xmax-offsx),
2749                                 but->y1 + zoomy*(cumap->clipr.ymax-offsy));
2750         }
2751         else {
2752                 UI_ThemeColor(TH_BUT_NEUTRAL);
2753                 glRectf(but->x1, but->y1, but->x2, but->y2);
2754         }
2755         
2756         /* grid, every .25 step */
2757         UI_ThemeColorShade(TH_BUT_NEUTRAL, -16);
2758         ui_draw_but_curve_grid(but, zoomx, zoomy, offsx, offsy, 0.25f);
2759         /* grid, every 1.0 step */
2760         UI_ThemeColorShade(TH_BUT_NEUTRAL, -24);
2761         ui_draw_but_curve_grid(but, zoomx, zoomy, offsx, offsy, 1.0f);
2762         /* axes */
2763         UI_ThemeColorShade(TH_BUT_NEUTRAL, -50);
2764         glBegin(GL_LINES);
2765         glVertex2f(but->x1, but->y1 + zoomy*(-offsy));
2766         glVertex2f(but->x2, but->y1 + zoomy*(-offsy));
2767         glVertex2f(but->x1 + zoomx*(-offsx), but->y1);
2768         glVertex2f(but->x1 + zoomx*(-offsx), but->y2);
2769         glEnd();
2770         
2771         /* cfra option */
2772         /* XXX 2.48
2773         if(cumap->flag & CUMA_DRAW_CFRA) {
2774                 glColor3ub(0x60, 0xc0, 0x40);
2775                 glBegin(GL_LINES);
2776                 glVertex2f(but->x1 + zoomx*(cumap->sample[0]-offsx), but->y1);
2777                 glVertex2f(but->x1 + zoomx*(cumap->sample[0]-offsx), but->y2);
2778                 glEnd();
2779         }*/
2780         /* sample option */
2781         /* XXX 2.48
2782          * if(cumap->flag & CUMA_DRAW_SAMPLE) {
2783                 if(cumap->cur==3) {
2784                         float lum= cumap->sample[0]*0.35f + cumap->sample[1]*0.45f + cumap->sample[2]*0.2f;
2785                         glColor3ub(240, 240, 240);
2786                         
2787                         glBegin(GL_LINES);
2788                         glVertex2f(but->x1 + zoomx*(lum-offsx), but->y1);
2789                         glVertex2f(but->x1 + zoomx*(lum-offsx), but->y2);
2790                         glEnd();
2791                 }
2792                 else {
2793                         if(cumap->cur==0)
2794                                 glColor3ub(240, 100, 100);
2795                         else if(cumap->cur==1)
2796                                 glColor3ub(100, 240, 100);
2797                         else
2798                                 glColor3ub(100, 100, 240);
2799                         
2800                         glBegin(GL_LINES);
2801                         glVertex2f(but->x1 + zoomx*(cumap->sample[cumap->cur]-offsx), but->y1);
2802                         glVertex2f(but->x1 + zoomx*(cumap->sample[cumap->cur]-offsx), but->y2);
2803                         glEnd();
2804                 }
2805         }*/
2806         
2807         /* the curve */
2808         UI_ThemeColorBlend(TH_TEXT, TH_BUT_NEUTRAL, 0.35);
2809         glEnable(GL_LINE_SMOOTH);
2810         glEnable(GL_BLEND);
2811         glBegin(GL_LINE_STRIP);
2812         
2813         if(cuma->table==NULL)
2814                 curvemapping_changed(cumap, 0); /* 0 = no remove doubles */
2815         cmp= cuma->table;
2816         
2817         /* first point */
2818         if((cuma->flag & CUMA_EXTEND_EXTRAPOLATE)==0)
2819                 glVertex2f(but->x1, but->y1 + zoomy*(cmp[0].y-offsy));
2820         else {
2821                 fx= but->x1 + zoomx*(cmp[0].x-offsx + cuma->ext_in[0]);
2822                 fy= but->y1 + zoomy*(cmp[0].y-offsy + cuma->ext_in[1]);
2823                 glVertex2f(fx, fy);
2824         }
2825         for(a=0; a<=CM_TABLE; a++) {
2826                 fx= but->x1 + zoomx*(cmp[a].x-offsx);
2827                 fy= but->y1 + zoomy*(cmp[a].y-offsy);
2828                 glVertex2f(fx, fy);
2829         }
2830         /* last point */
2831         if((cuma->flag & CUMA_EXTEND_EXTRAPOLATE)==0)
2832                 glVertex2f(but->x2, but->y1 + zoomy*(cmp[CM_TABLE].y-offsy));   
2833         else {
2834                 fx= but->x1 + zoomx*(cmp[CM_TABLE].x-offsx - cuma->ext_out[0]);
2835                 fy= but->y1 + zoomy*(cmp[CM_TABLE].y-offsy - cuma->ext_out[1]);
2836                 glVertex2f(fx, fy);
2837         }
2838         glEnd();
2839         glDisable(GL_LINE_SMOOTH);
2840         glDisable(GL_BLEND);
2841
2842         /* the points, use aspect to make them visible on edges */
2843         cmp= cuma->curve;
2844         glPointSize(3.0f);
2845         bglBegin(GL_POINTS);
2846         for(a=0; a<cuma->totpoint; a++) {
2847                 if(cmp[a].flag & SELECT)
2848                         UI_ThemeColor(TH_TEXT_HI);
2849                 else
2850                         UI_ThemeColor(TH_TEXT);
2851                 fac[0]= but->x1 + zoomx*(cmp[a].x-offsx);
2852                 fac[1]= but->y1 + zoomy*(cmp[a].y-offsy);
2853                 bglVertex2fv(fac);
2854         }
2855         bglEnd();
2856         glPointSize(1.0f);
2857         
2858         /* restore scissortest */
2859         glScissor(scissor[0], scissor[1], scissor[2], scissor[3]);
2860
2861         /* outline */
2862         UI_ThemeColor(TH_BUT_OUTLINE);
2863         fdrawbox(but->x1, but->y1, but->x2, but->y2);
2864 }
2865
2866 static void ui_draw_roundbox(uiBut *but)
2867 {
2868         glEnable(GL_BLEND);
2869         
2870         UI_ThemeColorShadeAlpha(but->themecol, but->a2, but->a2);
2871
2872         uiSetRoundBox(but->a1);
2873         gl_round_box(GL_POLYGON, but->x1, but->y1, but->x2, but->y2, but->min);
2874
2875         glDisable(GL_BLEND);
2876 }
2877
2878
2879 /* nothing! */
2880 static void ui_draw_nothing(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
2881 {
2882 }
2883
2884 /* minimal drawing for table items */
2885 static void ui_draw_table(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
2886 {
2887         int background= 1;
2888
2889         /* paper */
2890         if(flag & UI_SELECT) {
2891                 if(flag & UI_ACTIVE) glColor4f(0, 0, 0, 0.2f);
2892                 else glColor4f(0, 0, 0, 0.1f);
2893         }
2894         else {
2895                 if(flag & UI_ACTIVE) glColor4f(1.0f, 1.0f, 1.0f, 0.2f);
2896                 else background= 0;
2897         }
2898         
2899         if(background) {
2900                 glEnable(GL_BLEND);
2901                 glRectf(x1, y1, x2, y2);
2902                 glDisable(GL_BLEND);
2903         }
2904         
2905         /* special type decorations */
2906         switch(type) {
2907         case NUM:
2908         case NUMABS:
2909                 if(flag & UI_SELECT) UI_ThemeColorShade(colorid, -120);
2910                 else UI_ThemeColorShade(colorid, -90);
2911                 ui_default_num_arrows(x1, y1, x2, y2);
2912                 break;
2913
2914         case ICONROW: 
2915         case ICONTEXTROW: 
2916                 if(flag & UI_ACTIVE) UI_ThemeColorShade(colorid, 0);
2917                 else UI_ThemeColorShade(colorid, -10);
2918                 glRectf(x2-9, y1+asp, x2-asp, y2-asp);
2919
2920                 UI_ThemeColorShade(colorid, -50);
2921                 ui_default_iconrow_arrows(x1, y1, x2, y2);
2922                 break;
2923                 
2924         case MENU: 
2925         case BLOCK: 
2926                 if(flag & UI_ACTIVE) UI_ThemeColorShade(colorid, 0);
2927                 else UI_ThemeColorShade(colorid, -10);
2928                 glRectf(x2-17, y1+asp, x2-asp, y2-asp);
2929
2930                 UI_ThemeColorShade(colorid, -50);
2931                 ui_default_menu_arrows(x1, y1, x2, y2);
2932                 break;
2933         }
2934 }
2935
2936 /* ************** EXTERN, called from interface.c ************* */
2937 /* ************** MAIN CALLBACK FUNCTION          ************* */
2938
2939 void ui_set_embossfunc(uiBut *but, int drawtype)
2940 {
2941         // this aded for evaluating textcolor for example
2942         but->dt= drawtype;
2943         
2944         // not really part of standard minimal themes, just make sure it is set
2945         but->sliderfunc= ui_draw_slider;
2946
2947         // standard builtin first:
2948         if(but->type==LABEL || but->type==ROUNDBOX) but->embossfunc= ui_draw_nothing;
2949         else if(but->type==PULLDOWN) but->embossfunc= ui_draw_pulldown_round;
2950         else if(drawtype==UI_EMBOSSM) but->embossfunc= ui_draw_minimal;
2951         else if(drawtype==UI_EMBOSSN) but->embossfunc= ui_draw_nothing;
2952         else if(drawtype==UI_EMBOSSP) but->embossfunc= ui_draw_pulldown_item;
2953         else if(drawtype==UI_EMBOSSR) but->embossfunc= ui_draw_round;
2954         else if(drawtype==UI_EMBOSST) but->embossfunc= ui_draw_table;
2955         else {
2956                 int theme= UI_GetThemeValue(TH_BUT_DRAWTYPE);
2957                 
2958                 switch(theme) {
2959                 
2960                 case TH_SHADED:
2961                         but->embossfunc= ui_draw_default;
2962                         break;
2963                 case TH_ROUNDED:
2964                         but->embossfunc= ui_draw_round;
2965                         break;
2966                 case TH_OLDSKOOL:
2967                         but->embossfunc= ui_draw_oldskool;
2968                         break;
2969                 case TH_MINIMAL:
2970                         but->embossfunc= ui_draw_minimal;
2971                         break;
2972                 case TH_ROUNDSHADED:
2973                 default:
2974                         but->embossfunc= ui_draw_roundshaded;
2975                         but->sliderfunc= ui_default_slider;
2976                         break;
2977                 }
2978         }
2979         
2980         // note: if you want aligning, adapt the call uiBlockEndAlign in interface.c 
2981 }
2982
2983 void ui_draw_but(uiBut *but)
2984 {
2985         double value;
2986         float x1, x2, y1, y2, fac;
2987         int type;
2988         
2989         if(but==NULL) return;
2990
2991         /* XXX 2.50 no frontbuffer drawing allowed */
2992 #if 0
2993         /* signal for frontbuf flush buttons and menus, not when normal drawing */
2994         if(but->block->in_use) ui_block_set_flush(but->block, but);
2995 #endif
2996                 
2997         switch (but->type) {
2998
2999         case NUMSLI:
3000         case HSVSLI:
3001                 type= (but->editstr)? TEX: but->type;
3002                 but->embossfunc(type, but->themecol, but->aspect, but->x1, but->y1, but->x2, but->y2, but->flag);
3003                 ui_draw_text_icon(but);
3004
3005                 x1= (but->x1+but->x2)/2;
3006                 x2= but->x2 - 5.0*but->aspect;
3007                 y1= but->y1 + 2.0*but->aspect;
3008                 y2= but->y2 - 2.0*but->aspect;
3009                 
3010                 value= ui_get_but_val(but);
3011                 fac= (value-but->min)*(x2-x1)/(but->max - but->min);
3012                 
3013                 but->sliderfunc(but->themecol, fac, but->aspect, x1, y1, x2, y2, but->flag);
3014                 break;
3015                 
3016         case SEPR:
3017                 //  only background
3018                 break;
3019                 
3020         case COL:
3021                 ui_draw_but_COL(but);  // black box with color
3022                 break;
3023
3024         case HSVCUBE:
3025                 ui_draw_but_HSVCUBE(but);  // box for colorpicker, three types
3026                 break;
3027
3028 #ifdef INTERNATIONAL
3029         case CHARTAB:
3030                 value= ui_get_but_val(but);
3031                 ui_draw_but_CHARTAB(but);
3032                 break;
3033 #endif
3034
3035         case LINK:
3036         case INLINK:
3037                 ui_draw_icon(but, but->icon, 0);
3038                 break;
3039                 
3040         case ROUNDBOX:
3041                 ui_draw_roundbox(but);
3042                 break;
3043                 
3044         case BUT_COLORBAND:
3045                 ui_draw_but_COLORBAND(but);
3046                 break;
3047         case BUT_NORMAL:
3048                 ui_draw_but_NORMAL(but);
3049                 break;
3050         case BUT_CURVE:
3051                 ui_draw_but_CURVE(but);
3052                 break;
3053                 
3054         default:
3055                 type= (but->editstr)? TEX: but->type;
3056                 but->embossfunc(type, but->themecol, but->aspect, but->x1, but->y1, but->x2, but->y2, but->flag);
3057                 ui_draw_text_icon(but);
3058         
3059         }
3060 }
3061
3062 void ui_dropshadow(rctf *rct, float radius, float aspect, int select)
3063 {
3064         float rad;
3065         float a;
3066         char alpha= 2;
3067         
3068         glEnable(GL_BLEND);
3069         
3070         if(radius > (rct->ymax-rct->ymin-10.0f)/2.0f)
3071                 rad= (rct->ymax-rct->ymin-10.0f)/2.0f;
3072         else
3073                 rad= radius;
3074         
3075         if(select) a= 12.0f*aspect; else a= 12.0f*aspect;
3076         for(; a>0.0f; a-=aspect) {
3077                 /* alpha ranges from 2 to 20 or so */
3078                 glColor4ub(0, 0, 0, alpha);
3079                 alpha+= 2;
3080                 
3081                 gl_round_box(GL_POLYGON, rct->xmin - a, rct->ymin - a, rct->xmax + a, rct->ymax-10.0f + a, rad+a);
3082         }
3083         
3084         /* outline e