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