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