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