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