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