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