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