Made the minimal theme align, and buttons now sit close together.
[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         /* too much space between buttons */
1213         /* 
1214         x1+= asp;
1215         x2-= asp;
1216         y1+= asp;
1217         y2-= asp;
1218         */
1219         
1220         /* Less space between buttons looks nicer */
1221         y2-= asp;
1222         x2-= asp;
1223         
1224         /* paper */
1225         if(flag & UI_SELECT) {
1226                 if(flag & UI_ACTIVE) BIF_ThemeColorShade(colorid, -40);
1227                 else BIF_ThemeColorShade(colorid, -30);
1228         }
1229         else {
1230                 if(flag & UI_ACTIVE) BIF_ThemeColorShade(colorid, +20);
1231                 else BIF_ThemeColorShade(colorid, +10);
1232         }
1233         
1234         glRectf(x1, y1, x2, y2);
1235
1236         if(flag & UI_SELECT) {
1237                 BIF_ThemeColorShade(colorid, -60);
1238
1239                 /* top */
1240                 fdrawline(x1, y2, x2, y2);
1241                 /* left */
1242                 fdrawline(x1, y1, x1, y2);
1243                 BIF_ThemeColorShade(colorid, +40);
1244
1245                 /* below */
1246                 fdrawline(x1, y1, x2, y1);
1247                 /* right */
1248                 fdrawline(x2, y1, x2, y2);
1249         }
1250         else {
1251                 BIF_ThemeColorShade(colorid, +40);
1252
1253                 /* top */
1254                 fdrawline(x1, y2, x2, y2);
1255                 /* left */
1256                 fdrawline(x1, y1, x1, y2);
1257                 
1258                 BIF_ThemeColorShade(colorid, -60);
1259                 /* below */
1260                 fdrawline(x1, y1, x2, y1);
1261                 /* right */
1262                 fdrawline(x2, y1, x2, y2);
1263         }
1264         
1265         /* special type decorations */
1266         switch(type) {
1267         case NUM:
1268                 if(flag & UI_SELECT) BIF_ThemeColorShade(colorid, -60);
1269                 else BIF_ThemeColorShade(colorid, -30);
1270                 ui_default_num_arrows(x1, y1, x2, y2);
1271                 break;
1272
1273         case ICONROW: 
1274         case ICONTEXTROW: 
1275                 if(flag & UI_ACTIVE) BIF_ThemeColorShade(colorid, 0);
1276                 else BIF_ThemeColorShade(colorid, -10);
1277                 glRectf(x2-9, y1+asp, x2-asp, y2-asp);
1278
1279                 BIF_ThemeColorShade(colorid, -50);
1280                 ui_default_iconrow_arrows(x1, y1, x2, y2);
1281                 break;
1282                 
1283         case MENU: 
1284         case BLOCK: 
1285                 if(flag & UI_ACTIVE) BIF_ThemeColorShade(colorid, 0);
1286                 else BIF_ThemeColorShade(colorid, -10);
1287                 glRectf(x2-17, y1+asp, x2-asp, y2-asp);
1288
1289                 BIF_ThemeColorShade(colorid, -50);
1290                 ui_default_menu_arrows(x1, y1, x2, y2);
1291                 break;
1292         }
1293         
1294         
1295 }
1296
1297
1298 /* fac is the slider handle position between x1 and x2 */
1299 static void ui_draw_slider(int colorid, float fac, float aspect, float x1, float y1, float x2, float y2, int flag)
1300 {
1301         float ymid, yc;
1302
1303         /* the slider background line */
1304         ymid= (y1+y2)/2.0;
1305         yc= 1.7*aspect; 
1306
1307         if(flag & UI_ACTIVE) 
1308                 BIF_ThemeColorShade(colorid, -50); 
1309         else 
1310                 BIF_ThemeColorShade(colorid, -40); 
1311
1312         /* left part */
1313         glRectf(x1, ymid-2.0*yc, x1+fac, ymid+2.0*yc);
1314         /* right part */
1315         glRectf(x1+fac, ymid-yc, x2, ymid+yc);
1316
1317         /* the movable slider */
1318         
1319         BIF_ThemeColorShade(colorid, +70); 
1320         glRectf(x1+fac-aspect, ymid-2.0*yc, x1+fac+aspect, ymid+2.0*yc);
1321
1322 }
1323
1324 /* ************** STANDARD MENU DRAWING FUNCTION ************* */
1325
1326
1327 static void ui_shadowbox(float minx, float miny, float maxx, float maxy, float shadsize, unsigned char alpha)
1328 {
1329         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1330         glEnable(GL_BLEND);
1331         glShadeModel(GL_SMOOTH);
1332         
1333         /* right quad */
1334         glBegin(GL_POLYGON);
1335         glColor4ub(0, 0, 0, alpha);
1336         glVertex2f(maxx, miny);
1337         glVertex2f(maxx, maxy-shadsize);
1338         glColor4ub(0, 0, 0, 0);
1339         glVertex2f(maxx+shadsize, maxy-shadsize-shadsize);
1340         glVertex2f(maxx+shadsize, miny);
1341         glEnd();
1342         
1343         /* corner shape */
1344         glBegin(GL_POLYGON);
1345         glColor4ub(0, 0, 0, alpha);
1346         glVertex2f(maxx, miny);
1347         glColor4ub(0, 0, 0, 0);
1348         glVertex2f(maxx+shadsize, miny);
1349         glVertex2f(maxx+0.7*shadsize, miny-0.7*shadsize);
1350         glVertex2f(maxx, miny-shadsize);
1351         glEnd();
1352         
1353         /* bottom quad */               
1354         glBegin(GL_POLYGON);
1355         glColor4ub(0, 0, 0, alpha);
1356         glVertex2f(minx+shadsize, miny);
1357         glVertex2f(maxx, miny);
1358         glColor4ub(0, 0, 0, 0);
1359         glVertex2f(maxx, miny-shadsize);
1360         glVertex2f(minx+shadsize+shadsize, miny-shadsize);
1361         glEnd();
1362         
1363         glDisable(GL_BLEND);
1364         glShadeModel(GL_FLAT);
1365 }
1366
1367 void uiDrawBoxShadow(unsigned char alpha, float minx, float miny, float maxx, float maxy)
1368 {
1369         /* accumulated outline boxes to make shade not linear, is more pleasant */
1370         ui_shadowbox(minx, miny, maxx, maxy, 6.0, (30*alpha)>>8);
1371         ui_shadowbox(minx, miny, maxx, maxy, 4.0, (70*alpha)>>8);
1372         ui_shadowbox(minx, miny, maxx, maxy, 2.0, (100*alpha)>>8);
1373         
1374 }
1375
1376 // background for pulldowns, pullups, and other drawing temporal menus....
1377 // has to be made themable still (now only color)
1378
1379 void uiDrawMenuBox(float minx, float miny, float maxx, float maxy, short flag)
1380 {
1381         char col[4];
1382         BIF_GetThemeColor4ubv(TH_MENU_BACK, col);
1383         
1384         if( (flag & UI_BLOCK_NOSHADOW)==0) {
1385                 /* accumulated outline boxes to make shade not linear, is more pleasant */
1386                 ui_shadowbox(minx, miny, maxx, maxy, 6.0, (30*col[3])>>8);
1387                 ui_shadowbox(minx, miny, maxx, maxy, 4.0, (70*col[3])>>8);
1388                 ui_shadowbox(minx, miny, maxx, maxy, 2.0, (100*col[3])>>8);
1389                 
1390                 glEnable(GL_BLEND);
1391                 glColor4ubv(col);
1392                 glRectf(minx-1, miny, minx, maxy);      // 1 pixel on left, to distinguish sublevel menus
1393         }
1394         glEnable(GL_BLEND);
1395         glColor4ubv(col);
1396         glRectf(minx, miny, maxx, maxy);
1397         glDisable(GL_BLEND);
1398 }
1399
1400
1401
1402 /* pulldown menu item */
1403 static void ui_draw_pulldown_item(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1404 {
1405         char col[4];
1406         
1407         BIF_GetThemeColor4ubv(TH_MENU_BACK, col);
1408         if(col[3]!=255) {
1409                 glEnable(GL_BLEND);
1410                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1411         }
1412         
1413         if((flag & UI_ACTIVE) && type!=LABEL) {
1414                 BIF_ThemeColor4(TH_MENU_HILITE);
1415                 glRectf(x1, y1, x2, y2);
1416         
1417
1418         } else {
1419                 BIF_ThemeColor4(colorid);       // is set at TH_MENU_ITEM when pulldown opened.
1420                 glRectf(x1, y1, x2, y2);
1421         }
1422
1423         glDisable(GL_BLEND);
1424 }
1425
1426 /* pulldown menu calling button */
1427 static void ui_draw_pulldown_round(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1428 {
1429         
1430         if(flag & UI_ACTIVE) {
1431                 BIF_ThemeColor(TH_MENU_HILITE);
1432
1433                 uiSetRoundBox(15);
1434                 gl_round_box(GL_POLYGON, x1, y1+3, x2, y2-3, 7.0);
1435
1436                 glEnable( GL_LINE_SMOOTH );
1437                 glEnable( GL_BLEND );
1438                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1439                 gl_round_box(GL_LINE_LOOP, x1, y1+3, x2, y2-3, 7.0);
1440                 glDisable( GL_LINE_SMOOTH );
1441                 glDisable( GL_BLEND );
1442                 
1443         } else {
1444                 BIF_ThemeColor(colorid);        // is set at TH_MENU_ITEM when pulldown opened.
1445                 glRectf(x1-1, y1+2, x2+1, y2-2);
1446         }
1447         
1448 }
1449
1450
1451 /* ************** TEXT AND ICON DRAWING FUNCTIONS ************* */
1452
1453
1454
1455 /* draws text and icons for buttons */
1456 static void ui_draw_text_icon(uiBut *but)
1457 {
1458         float x;
1459         int len;
1460         char *cpoin;
1461         short t, pos, ch;
1462         short selsta_tmp, selend_tmp, selsta_draw, selwidth_draw;
1463         
1464         /* check for button text label */
1465         if (but->type == ICONTEXTROW) {
1466                 ui_draw_icon(but, (BIFIconID) (but->icon+but->iconadd));
1467         }
1468         else {
1469
1470                 /* text button selection and cursor */
1471                 if(but->pos != -1) {
1472                 
1473                         if (SELWIDTH > 0) {
1474                                 /* text button selection */
1475                                 selsta_tmp = but->selsta + strlen(but->str);
1476                                 selend_tmp = but->selend + strlen(but->str);
1477                                 if (but->ofs >= strlen(but->str))
1478                                         selsta_tmp += (but->ofs - strlen(but->str));
1479                                         
1480                                 if(but->drawstr[0]!=0) {
1481                                         ch= but->drawstr[selsta_tmp];
1482                                         but->drawstr[selsta_tmp]= 0;
1483                                         
1484                                         selsta_draw = but->aspect*BIF_GetStringWidth(but->font, but->drawstr+but->ofs, (U.transopts & USER_TR_BUTTONS)) + 3;
1485                                         
1486                                         but->drawstr[selsta_tmp]= ch;
1487                                         
1488                                         
1489                                         ch= but->drawstr[selend_tmp];
1490                                         but->drawstr[selend_tmp]= 0;
1491                                         
1492                                         selwidth_draw = but->aspect*BIF_GetStringWidth(but->font, but->drawstr+but->ofs, (U.transopts & USER_TR_BUTTONS)) + 3;
1493                                         
1494                                         but->drawstr[selend_tmp]= ch;
1495                                         
1496                                         BIF_ThemeColor(TH_BUT_TEXTFIELD_HI);
1497                                         glRects(but->x1+selsta_draw+1, but->y1+2, but->x1+selwidth_draw+1, but->y2-2);
1498                                 }
1499                         } else {
1500                                 /* text cursor */
1501                                 pos= but->pos+strlen(but->str);
1502                                 if(pos >= but->ofs) {
1503                                         if(but->drawstr[0]!=0) {
1504                                                 ch= but->drawstr[pos];
1505                                                 but->drawstr[pos]= 0;
1506                         
1507                                                 t= but->aspect*BIF_GetStringWidth(but->font, but->drawstr+but->ofs, (U.transopts & USER_TR_BUTTONS)) + 3;
1508                                                 
1509                                                 but->drawstr[pos]= ch;
1510                                         }
1511                                         else t= 3;
1512                                         
1513                                         glColor3ub(255,0,0);
1514                                         glRects(but->x1+t, but->y1+2, but->x1+t+2, but->y2-2);
1515                                 }
1516                         }
1517                 }
1518                 if(but->drawstr[0]!=0) {
1519                         int transopts;
1520                         int tog3= 0;
1521                         
1522                         // cut string in 2 parts
1523                         cpoin= strchr(but->drawstr, '|');
1524                         if(cpoin) *cpoin= 0;
1525
1526                         /* If there's an icon too (made with uiDefIconTextBut) then draw the icon
1527                         and offset the text label to accomodate it */
1528                         
1529                         if ( (but->flag & UI_HAS_ICON) && (but->flag & UI_ICON_LEFT) ) {
1530                                 ui_draw_icon(but, but->icon);
1531
1532                                 if(but->flag & UI_TEXT_LEFT) x= but->x1+24.0;
1533                                 else x= (but->x1+but->x2-but->strwidth+1)/2.0;
1534                         }
1535                         else {
1536                                 if(but->flag & UI_TEXT_LEFT) x= but->x1+4.0;
1537                                 else x= (but->x1+but->x2-but->strwidth+1)/2.0;
1538                         }
1539                         
1540                         /* tog3 button exception; draws with glColor! */
1541                         if(but->type==TOG3 && (but->flag & UI_SELECT)) {
1542                                 
1543                                 if( but->pointype==CHA ) {
1544                                         if( BTST( *(but->poin+2), but->bitnr )) tog3= 1;
1545                                 }
1546                                 else if( but->pointype ==SHO ) {
1547                                         short *sp= (short *)but->poin;
1548                                         if( BTST( sp[1], but->bitnr )) tog3= 1;
1549                                 }
1550                                 
1551                                 ui_tog3_invert(but->x1,but->y1,but->x2,but->y2, tog3);
1552                                 if (tog3) glColor3ub(255, 255, 0);
1553                         }
1554                         
1555                         /* text color, with pulldown item exception */
1556                         if(tog3);       // color already set
1557                         else if(but->dt==UI_EMBOSSP) {
1558                                 if((but->flag & (UI_SELECT|UI_ACTIVE)) && but->type!=LABEL) {   // LABEL = title in pulldowns
1559                                         BIF_ThemeColor(TH_MENU_TEXT_HI);
1560                                 } else {
1561                                         BIF_ThemeColor(TH_MENU_TEXT);
1562                                 }
1563                         }
1564                         else {
1565                                 if(but->flag & UI_SELECT) {             
1566                                         BIF_ThemeColor(TH_BUT_TEXT_HI);
1567                                 } else {
1568                                         BIF_ThemeColor(TH_BUT_TEXT);
1569                                 }
1570                         }
1571
1572                         /* LABEL button exception */
1573                         if(but->type==LABEL && but->min!=0.0) BIF_ThemeColor(TH_BUT_TEXT_HI);
1574                 
1575                         ui_rasterpos_safe(x, (but->y1+but->y2- 9.0)/2.0, but->aspect);
1576                         if(but->type==TEX || but->type==IDPOIN) transopts= 0;   // no translation, of course!
1577                         else transopts= (U.transopts & USER_TR_BUTTONS);
1578                         BIF_DrawString(but->font, but->drawstr+but->ofs, transopts);
1579
1580                         /* part text right aligned */
1581                         if(cpoin) {
1582                                 len= BIF_GetStringWidth(but->font, cpoin+1, (U.transopts & USER_TR_BUTTONS));
1583                                 ui_rasterpos_safe( but->x2 - len*but->aspect-3, (but->y1+but->y2- 9.0)/2.0, but->aspect);
1584                                 BIF_DrawString(but->font, cpoin+1, (U.transopts & USER_TR_BUTTONS));
1585                                 *cpoin= '|';
1586                         }
1587                 }
1588                 /* if there's no text label, then check to see if there's an icon only and draw it */
1589                 else if( but->flag & UI_HAS_ICON ) {
1590                         ui_draw_icon(but, (BIFIconID) (but->icon+but->iconadd));
1591                 }
1592         }
1593 }
1594
1595 static void ui_draw_but_COL(uiBut *but)
1596 {
1597         float *fp;
1598         char colr, colg, colb;
1599         
1600         if( but->pointype==FLO ) {
1601                 fp= (float *)but->poin;
1602                 colr= floor(255.0*fp[0]+0.5);
1603                 colg= floor(255.0*fp[1]+0.5);
1604                 colb= floor(255.0*fp[2]+0.5);
1605         }
1606         else {
1607                 char *cp= (char *)but->poin;
1608                 colr= cp[0];
1609                 colg= cp[1];
1610                 colb= cp[2];
1611         }
1612         
1613         /* exception... hrms, but can't simply use the emboss callback for this now. */
1614         /* this button type needs review, and nice integration with rest of API here */
1615         if(but->embossfunc == ui_draw_round) {
1616                 char *cp= BIF_ThemeGetColorPtr(U.themes.first, 0, TH_CUSTOM);
1617                 cp[0]= colr; cp[1]= colg; cp[2]= colb;
1618                 but->flag &= ~UI_SELECT;
1619                 but->embossfunc(but->type, TH_CUSTOM, but->aspect, but->x1, but->y1, but->x2, but->y2, but->flag);
1620         }
1621         else {
1622                 
1623                 glColor3ub(colr,  colg,  colb);
1624                 glRectf((but->x1), (but->y1), (but->x2), (but->y2));
1625                 glColor3ub(0,  0,  0);
1626                 fdrawbox((but->x1), (but->y1), (but->x2), (but->y2));
1627         }
1628 }
1629
1630 /* draws in resolution of 20x4 colors */
1631 static void ui_draw_but_HSVCUBE(uiBut *but)
1632 {
1633         int a;
1634         float h,s,v;
1635         float dx, dy, sx1, sx2, sy, x, y;
1636         float col0[4][3];       // left half, rect bottom to top
1637         float col1[4][3];       // right half, rect bottom to top
1638         
1639         h= but->hsv[0];
1640         s= but->hsv[1];
1641         v= but->hsv[2];
1642         
1643         /* draw series of gouraud rects */
1644         glShadeModel(GL_SMOOTH);
1645         
1646         if(but->a1==0) {        // H and V vary
1647                 hsv_to_rgb(0.0, s, 0.0,   &col1[0][0], &col1[0][1], &col1[0][2]);
1648                 hsv_to_rgb(0.0, s, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]);
1649                 hsv_to_rgb(0.0, s, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]);
1650                 hsv_to_rgb(0.0, s, 1.0,   &col1[3][0], &col1[3][1], &col1[3][2]);
1651                 x= h; y= v;
1652         }
1653         else if(but->a1==1) {   // H and S vary
1654                 hsv_to_rgb(0.0, 0.0, v,   &col1[0][0], &col1[0][1], &col1[0][2]);
1655                 hsv_to_rgb(0.0, 0.333, v, &col1[1][0], &col1[1][1], &col1[1][2]);
1656                 hsv_to_rgb(0.0, 0.666, v, &col1[2][0], &col1[2][1], &col1[2][2]);
1657                 hsv_to_rgb(0.0, 1.0, v,   &col1[3][0], &col1[3][1], &col1[3][2]);
1658                 x= h; y= s;
1659         }
1660         else if(but->a1==2) {   // S and V vary
1661                 hsv_to_rgb(h, 0.0, 0.0,   &col1[0][0], &col1[0][1], &col1[0][2]);
1662                 hsv_to_rgb(h, 0.333, 0.0, &col1[1][0], &col1[1][1], &col1[1][2]);
1663                 hsv_to_rgb(h, 0.666, 0.0, &col1[2][0], &col1[2][1], &col1[2][2]);
1664                 hsv_to_rgb(h, 1.0, 0.0,   &col1[3][0], &col1[3][1], &col1[3][2]);
1665                 x= v; y= s;
1666         }
1667         else {          // only hue slider
1668                 hsv_to_rgb(0.0, 1.0, 1.0,   &col1[0][0], &col1[0][1], &col1[0][2]);
1669                 VECCOPY(col1[1], col1[0]);
1670                 VECCOPY(col1[2], col1[0]);
1671                 VECCOPY(col1[3], col1[0]);
1672                 x= h; y= 0.5;
1673         }
1674         
1675         for(dx=0.0; dx<1.0; dx+= 0.05) {
1676                 // previous color
1677                 VECCOPY(col0[0], col1[0]);
1678                 VECCOPY(col0[1], col1[1]);
1679                 VECCOPY(col0[2], col1[2]);
1680                 VECCOPY(col0[3], col1[3]);
1681
1682                 // new color
1683                 if(but->a1==0) {        // H and V vary
1684                         hsv_to_rgb(dx, s, 0.0,   &col1[0][0], &col1[0][1], &col1[0][2]);
1685                         hsv_to_rgb(dx, s, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]);
1686                         hsv_to_rgb(dx, s, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]);
1687                         hsv_to_rgb(dx, s, 1.0,   &col1[3][0], &col1[3][1], &col1[3][2]);
1688                 }
1689                 else if(but->a1==1) {   // H and S vary
1690                         hsv_to_rgb(dx, 0.0, v,   &col1[0][0], &col1[0][1], &col1[0][2]);
1691                         hsv_to_rgb(dx, 0.333, v, &col1[1][0], &col1[1][1], &col1[1][2]);
1692                         hsv_to_rgb(dx, 0.666, v, &col1[2][0], &col1[2][1], &col1[2][2]);
1693                         hsv_to_rgb(dx, 1.0, v,   &col1[3][0], &col1[3][1], &col1[3][2]);
1694                 }
1695                 else if(but->a1==2) {   // S and V vary
1696                         hsv_to_rgb(h, 0.0, dx,   &col1[0][0], &col1[0][1], &col1[0][2]);
1697                         hsv_to_rgb(h, 0.333, dx, &col1[1][0], &col1[1][1], &col1[1][2]);
1698                         hsv_to_rgb(h, 0.666, dx, &col1[2][0], &col1[2][1], &col1[2][2]);
1699                         hsv_to_rgb(h, 1.0, dx,   &col1[3][0], &col1[3][1], &col1[3][2]);
1700                 }
1701                 else {  // only H
1702                         hsv_to_rgb(dx, 1.0, 1.0,   &col1[0][0], &col1[0][1], &col1[0][2]);
1703                         VECCOPY(col1[1], col1[0]);
1704                         VECCOPY(col1[2], col1[0]);
1705                         VECCOPY(col1[3], col1[0]);
1706                 }
1707                 
1708                 // rect
1709                 sx1= but->x1 + dx*(but->x2-but->x1);
1710                 sx2= but->x1 + (dx+0.05)*(but->x2-but->x1);
1711                 sy= but->y1;
1712                 dy= (but->y2-but->y1)/3.0;
1713                 
1714                 glBegin(GL_QUADS);
1715                 for(a=0; a<3; a++, sy+=dy) {
1716                         glColor3fv(col0[a]);
1717                         glVertex2f(sx1, sy);
1718
1719                         glColor3fv(col1[a]);
1720                         glVertex2f(sx2, sy);
1721                         
1722                         glColor3fv(col1[a+1]);
1723                         glVertex2f(sx2, sy+dy);
1724                         
1725                         glColor3fv(col0[a+1]);
1726                         glVertex2f(sx1, sy+dy);
1727                 }
1728                 glEnd();
1729         }
1730
1731         glShadeModel(GL_FLAT);
1732
1733         /* cursor */
1734         x= but->x1 + x*(but->x2-but->x1);
1735         y= but->y1 + y*(but->y2-but->y1);
1736         CLAMP(x, but->x1+3.0, but->x2-3.0);
1737         CLAMP(y, but->y1+3.0, but->y2-3.0);
1738         
1739         fdrawXORcirc(x, y, 3.1);
1740
1741         /* outline */
1742         glColor3ub(0,  0,  0);
1743         fdrawbox((but->x1), (but->y1), (but->x2), (but->y2));
1744 }
1745
1746 #ifdef INTERNATIONAL
1747 static void ui_draw_but_CHARTAB(uiBut *but)
1748 {
1749         /* Some local variables */
1750         float sx, sy, ex, ey;
1751         float width, height;
1752         float butw, buth;
1753         int x, y, cs;
1754         wchar_t wstr[2];
1755         unsigned char ustr[16];
1756         PackedFile *pf;
1757         int result = 0;
1758
1759         /* Calculate the size of the button */
1760         width = abs(but->x2 - but->x1);
1761         height = abs(but->y2 - but->y1);
1762         
1763         butw = floor(width / 12);
1764         buth = floor(height / 6);
1765         
1766         /* Initialize variables */
1767         sx = but->x1;
1768         ex = but->x1 + butw;
1769         sy = but->y1 + height - buth;
1770         ey = but->y1 + height;
1771
1772         cs = G.charstart;
1773
1774         /* Set the font */
1775         if(G.selfont && strcmp(G.selfont->name, "<builtin>"))
1776         {
1777                 char tmpStr[256];
1778
1779                 // Is the font file packed, if so then use the packed file
1780                 if(G.selfont->packedfile)
1781                 {
1782                         pf = G.selfont->packedfile;             
1783                         FTF_SetFont(pf->data, pf->size, 14.0);
1784                 }
1785                 else
1786                 {
1787                         int err;
1788
1789                         strcpy(tmpStr, G.selfont->name);
1790                         BLI_convertstringcode(tmpStr, G.sce, 0);
1791                         err = FTF_SetFont(tmpStr, 0, 14.0);
1792                 }
1793         }
1794
1795         /* Start drawing the button itself */
1796         glShadeModel(GL_SMOOTH);
1797
1798         glColor3ub(200,  200,  200);
1799         glRectf((but->x1), (but->y1), (but->x2), (but->y2));
1800
1801         glColor3ub(0,  0,  0);
1802         for(y = 0; y < 6; y++)
1803         {
1804                 // Do not draw more than the category allows
1805                 if(cs > G.charmax) break;
1806
1807                 for(x = 0; x < 12; x++)
1808                 {
1809                         // Do not draw more than the category allows
1810                         if(cs > G.charmax) break;
1811
1812                         // Draw one grid cell
1813                         glBegin(GL_LINE_LOOP);
1814                                 glVertex2f(sx, sy);
1815                                 glVertex2f(ex, sy);
1816                                 glVertex2f(ex, ey);
1817                                 glVertex2f(sx, ey);                             
1818                         glEnd();        
1819
1820                         // Draw character inside the cell
1821                         memset(wstr, 0, sizeof(wchar_t)*2);
1822                         memset(ustr, 0, 16);
1823                         
1824                         wstr[0] = cs;
1825                         wcs2utf8s(ustr, wstr);
1826
1827                         if(G.selfont && strcmp(G.selfont->name, "<builtin>"))
1828                         {
1829                                 float wid;
1830                                 float llx, lly, llz, urx, ury, urz;
1831                                 float dx, dy;
1832                                 float px, py;
1833         
1834                                 // Calculate the position
1835                                 wid = FTF_GetStringWidth(ustr, FTF_USE_GETTEXT | FTF_INPUT_UTF8);
1836                                 FTF_GetBoundingBox(ustr, &llx,&lly,&llz,&urx,&ury,&urz, FTF_USE_GETTEXT | FTF_INPUT_UTF8);
1837                                 dx = urx-llx;
1838                                 dy = ury-lly;
1839
1840                                 // This isn't fully functional since the but->aspect isn't working like I suspected
1841                                 px = sx + ((butw/but->aspect)-dx)/2;
1842                                 py = sy + ((buth/but->aspect)-dy)/2;
1843
1844                                 // Set the position and draw the character
1845                                 ui_rasterpos_safe(px, py, but->aspect);
1846                                 FTF_DrawString(ustr, FTF_USE_GETTEXT | FTF_INPUT_UTF8);
1847                         }
1848                         else
1849                         {
1850                                 ui_rasterpos_safe(sx + butw/2, sy + buth/2, but->aspect);
1851                                 BIF_DrawString(but->font, ustr, 0);
1852                         }
1853         
1854                         // Calculate the next position and character
1855                         sx += butw; ex +=butw;
1856                         cs++;
1857                 }
1858                 /* Add the y position and reset x position */
1859                 sy -= buth; 
1860                 ey -= buth;
1861                 sx = but->x1;
1862                 ex = but->x1 + butw;
1863         }       
1864         glShadeModel(GL_FLAT);
1865
1866         /* Return Font Settings to original */
1867         if(U.fontsize && U.fontname[0])
1868         {
1869                 result = FTF_SetFont(U.fontname, 0, U.fontsize);
1870         }
1871         else if (U.fontsize)
1872         {
1873                 result = FTF_SetFont(datatoc_bfont_ttf, datatoc_bfont_ttf_size, U.fontsize);
1874         }
1875
1876         if (result == 0)
1877         {
1878                 result = FTF_SetFont(datatoc_bfont_ttf, datatoc_bfont_ttf_size, 11);
1879         }
1880 }
1881
1882 #endif // INTERNATIONAL
1883
1884 static void ui_draw_roundbox(uiBut *but)
1885 {
1886         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1887         glEnable(GL_BLEND);
1888         
1889         BIF_ThemeColorShadeAlpha(TH_PANEL, but->a2, but->a2);
1890
1891         uiSetRoundBox(but->a1);
1892         gl_round_box(GL_POLYGON, but->x1, but->y1, but->x2, but->y2, but->min);
1893
1894         glDisable(GL_BLEND);
1895 }
1896
1897
1898 /* nothing! */
1899 static void ui_draw_nothing(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1900 {
1901 }
1902
1903
1904 /* ************** EXTERN, called from interface.c ************* */
1905 /* ************** MAIN CALLBACK FUNCTION          ************* */
1906
1907 void ui_set_embossfunc(uiBut *but, int drawtype)
1908 {
1909         // this aded for evaluating textcolor for example
1910         but->dt= drawtype;
1911         
1912         // not really part of standard minimal themes, just make sure it is set
1913         but->sliderfunc= ui_draw_slider;
1914
1915         // standard builtin first:
1916         if(but->type==LABEL || but->type==ROUNDBOX) but->embossfunc= ui_draw_nothing;
1917         else if(but->type==PULLDOWN) but->embossfunc= ui_draw_pulldown_round;
1918         else if(drawtype==UI_EMBOSSM) but->embossfunc= ui_draw_minimal;
1919         else if(drawtype==UI_EMBOSSN) but->embossfunc= ui_draw_nothing;
1920         else if(drawtype==UI_EMBOSSP) but->embossfunc= ui_draw_pulldown_item;
1921         else if(drawtype==UI_EMBOSSR) but->embossfunc= ui_draw_round;
1922         else {
1923                 int theme= BIF_GetThemeValue(TH_BUT_DRAWTYPE);
1924                 
1925                 // and the themes
1926                 if(theme==1) {
1927                         but->embossfunc= ui_draw_default;
1928                         but->sliderfunc= ui_default_slider;
1929                 }
1930                 else if(theme==2) {
1931                         but->embossfunc= ui_draw_round;
1932                 }
1933                 else if(theme==3) {
1934                         but->embossfunc= ui_draw_oldskool;
1935                 }
1936                 else {
1937                         but->embossfunc= ui_draw_minimal;
1938                 }
1939         }
1940         
1941         // note: if you want aligning, adapt the call uiBlockEndAlign in interface.c 
1942 }
1943
1944 void ui_draw_but(uiBut *but)
1945 {
1946         double value;
1947         float x1, x2, y1, y2, fac;
1948         
1949         if(but==NULL) return;
1950
1951         /* signal for frontbuf flush buttons and menus, not when normal drawing */
1952         if(but->block->in_use) ui_block_set_flush(but->block, but);
1953                 
1954         switch (but->type) {
1955
1956         case NUMSLI:
1957         case HSVSLI:
1958         
1959                 but->embossfunc(but->type, but->themecol, but->aspect, but->x1, but->y1, but->x2, but->y2, but->flag);
1960                 ui_draw_text_icon(but);
1961
1962                 x1= (but->x1+but->x2)/2;
1963                 x2= but->x2 - 5.0*but->aspect;
1964                 y1= but->y1 + 2.0*but->aspect;
1965                 y2= but->y2 - 2.0*but->aspect;
1966                 
1967                 value= ui_get_but_val(but);
1968                 fac= (value-but->min)*(x2-x1)/(but->max - but->min);
1969                 
1970                 but->sliderfunc(but->themecol, fac, but->aspect, x1, y1, x2, y2, but->flag);
1971                 break;
1972                 
1973         case SEPR:
1974                 //  only background
1975                 break;
1976                 
1977         case COL:
1978                 ui_draw_but_COL(but);  // black box with color
1979                 break;
1980
1981         case HSVCUBE:
1982                 ui_draw_but_HSVCUBE(but);  // box for colorpicker, three types
1983                 break;
1984
1985 #ifdef INTERNATIONAL
1986         case CHARTAB:
1987                 value= ui_get_but_val(but);
1988                 ui_draw_but_CHARTAB(but);
1989                 break;
1990 #endif
1991
1992         case LINK:
1993         case INLINK:
1994                 ui_draw_icon(but, but->icon);
1995                 break;
1996                 
1997         case ROUNDBOX:
1998                 ui_draw_roundbox(but);
1999
2000         default:
2001                 but->embossfunc(but->type, but->themecol, but->aspect, but->x1, but->y1, but->x2, but->y2, but->flag);
2002                 ui_draw_text_icon(but);
2003         
2004         }
2005 }
2006