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