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