Modified interface texture font support, which should work nicely with the freshly...
[blender.git] / source / blender / src / interface_draw.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
24  * All rights reserved.
25  *
26  * The Original Code is: all of this file.
27  *
28  * Contributor(s): none yet.
29  *
30  * ***** END GPL/BL DUAL LICENSE BLOCK *****
31  */
32
33 /* 
34      a full doc with API notes can be found in bf-blender/blender/doc/interface_API.txt
35
36  */
37  
38
39 #include <math.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include <ctype.h>
43
44 #ifdef HAVE_CONFIG_H
45 #include <config.h>
46 #endif
47
48 #ifndef WIN32
49 #include <unistd.h>
50 #else
51 #include <io.h>
52 #include "BLI_winstuff.h"
53 #endif   
54
55 #include "MEM_guardedalloc.h"
56
57 #include "PIL_time.h"
58
59 #include "BLI_blenlib.h"
60 #include "BLI_arithb.h"
61
62 #include "DNA_screen_types.h"
63 #include "DNA_space_types.h"
64 #include "DNA_userdef_types.h"
65 #include "DNA_vec_types.h"
66
67 #include "BKE_blender.h"
68 #include "BKE_utildefines.h"
69 #include "BKE_global.h"
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 #include "mydevice.h"
88 #include "interface.h"
89 #include "blendef.h"
90
91 // globals
92 extern float UIwinmat[4][4];
93
94 /* ************** safe rasterpos for pixmap alignment with pixels ************* */
95
96 void ui_rasterpos_safe(float x, float y, float aspect)
97 {
98         float vals[4], remainder;
99         int doit=0;
100         
101         glRasterPos2f(x, y);
102         glGetFloatv(GL_CURRENT_RASTER_POSITION, vals);
103
104         remainder= vals[0] - floor(vals[0]);
105         if(remainder > 0.4 && remainder < 0.6) {
106                 if(remainder < 0.5) x -= 0.1*aspect;
107                 else x += 0.1*aspect;
108                 doit= 1;
109         }
110         remainder= vals[1] - floor(vals[1]);
111         if(remainder > 0.4 && remainder < 0.6) {
112                 if(remainder < 0.5) y -= 0.1*aspect;
113                 else y += 0.1*aspect;
114                 doit= 1;
115         }
116         
117         if(doit) glRasterPos2f(x, y);
118
119         BIF_RasterPos(x, y);
120         BIF_SetScale(aspect);
121 }
122
123 /* ************** generic embossed rect, for window sliders etc ************* */
124
125 void uiEmboss(float x1, float y1, float x2, float y2, int sel)
126 {
127         
128         /* below */
129         if(sel) glColor3ub(200,200,200);
130         else glColor3ub(50,50,50);
131         fdrawline(x1, y1, x2, y1);
132
133         /* right */
134         fdrawline(x2, y1, x2, y2);
135         
136         /* top */
137         if(sel) glColor3ub(50,50,50);
138         else glColor3ub(200,200,200);
139         fdrawline(x1, y2, x2, y2);
140
141         /* left */
142         fdrawline(x1, y1, x1, y2);
143         
144 }
145
146 /* ************** GENERIC ICON DRAW, NO THEME HERE ************* */
147
148 static void ui_draw_icon(uiBut *but, BIFIconID icon)
149 {
150         void BIF_icon_pos(float xs, float ys);
151         int blend= 0;
152         float xs=0, ys=0;
153
154         // this icon doesn't need draw...
155         if(icon==ICON_BLANK1) return;
156
157         if(but->flag & UI_ICON_LEFT) {
158                 if (but->type==BUTM) {
159                         xs= but->x1+1.0;
160                 }
161                 else if ((but->type==ICONROW) || (but->type==ICONTEXTROW)) {
162                         xs= but->x1+4.0;
163                 }
164                 else {
165                         xs= but->x1+6.0;
166                 }
167                 ys= (but->y1+but->y2- BIF_get_icon_height(icon))/2.0;
168         }
169         if(but->flag & UI_ICON_RIGHT) {
170                 xs= but->x2-17.0;
171                 ys= (but->y1+but->y2- BIF_get_icon_height(icon))/2.0;
172         }
173         if (!((but->flag & UI_ICON_RIGHT) || (but->flag & UI_ICON_LEFT))) {
174                 xs= (but->x1+but->x2- BIF_get_icon_width(icon))/2.0;
175                 ys= (but->y1+but->y2- BIF_get_icon_height(icon))/2.0;
176         }
177
178         glRasterPos2f(xs, ys);
179         // BIF_icon_pos(xs, ys);
180
181         if(but->aspect>1.1) glPixelZoom(1.0/but->aspect, 1.0/but->aspect);
182         else if(but->aspect<0.9) glPixelZoom(1.0/but->aspect, 1.0/but->aspect);
183
184         glEnable(GL_BLEND);
185         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
186
187         /* calculate blend color */
188         if ELEM4(but->type, ICONTOG, TOG, ROW, TOGN) {
189                 if(but->flag & UI_SELECT);
190                 else if(but->flag & UI_ACTIVE);
191                 else blend= -60;
192         }
193         BIF_draw_icon_blended(icon, but->themecol, blend);
194         
195         glBlendFunc(GL_ONE, GL_ZERO);
196         glDisable(GL_BLEND);
197
198         glPixelZoom(1.0, 1.0);
199 }
200
201
202 /* ************** DEFAULT THEME, SHADED BUTTONS ************* */
203
204
205 #define M_WHITE         BIF_ThemeColorShade(colorid, 80)
206
207 #define M_ACT_LIGHT     BIF_ThemeColorShade(colorid, 55)
208 #define M_LIGHT         BIF_ThemeColorShade(colorid, 45)
209 #define M_HILITE        BIF_ThemeColorShade(colorid, 25)
210 #define M_LMEDIUM       BIF_ThemeColorShade(colorid, 10)
211 #define M_MEDIUM        BIF_ThemeColor(colorid)
212 #define M_LGREY         BIF_ThemeColorShade(colorid, -20)
213 #define M_GREY          BIF_ThemeColorShade(colorid, -45)
214 #define M_DARK          BIF_ThemeColorShade(colorid, -80)
215
216 #define M_NUMTEXT                               BIF_ThemeColorShade(colorid, 25)
217 #define M_NUMTEXT_ACT_LIGHT             BIF_ThemeColorShade(colorid, 35)
218
219 #define MM_WHITE        BIF_ThemeColorShade(TH_BUT_NEUTRAL, 120)
220
221 /* Used for the subtle sunken effect around buttons.
222  * One option is to hardcode to white, with alpha, however it causes a 
223  * weird 'building up' efect, so it's commented out for now.
224  */
225  
226 /*
227 #define MM_WHITE_OP     glColor4ub(255, 255, 255, 60)
228 #define MM_WHITE_TR     glColor4ub(255, 255, 255, 0)
229  */
230
231 #define MM_WHITE_OP     BIF_ThemeColorShadeAlpha(TH_BACK, 55, -100)
232 #define MM_WHITE_TR     BIF_ThemeColorShadeAlpha(TH_BACK, 55, -255)
233
234 #define MM_LIGHT        BIF_ThemeColorShade(TH_BUT_OUTLINE, 45)
235 #define MM_MEDIUM       BIF_ThemeColor(TH_BUT_OUTLINE)
236 #define MM_GREY         BIF_ThemeColorShade(TH_BUT_OUTLINE, -45)
237 #define MM_DARK         BIF_ThemeColorShade(TH_BUT_OUTLINE, -80)
238
239 /* base shaded button */
240 static void shaded_button(float x1, float y1, float x2, float y2, float asp, int colorid, int flag, int mid)
241 {
242         /* 'mid' arg determines whether the button is in the middle of
243          * an alignment group or not. 0 = not middle, 1 = is in the middle.
244          * Done to allow cleaner drawing
245          */
246          
247         /* *** SHADED BUTTON BASE *** */
248         glShadeModel(GL_SMOOTH);
249         glBegin(GL_QUADS);
250         
251         if(flag & UI_SELECT) {
252                 if(flag & UI_ACTIVE) M_MEDIUM;
253                 else M_LGREY;
254         } else {
255                 if(flag & UI_ACTIVE) M_LIGHT;
256                 else M_HILITE;
257         }
258
259         glVertex2f(x1,y1);
260         glVertex2f(x2,y1);
261
262         if(flag & UI_SELECT) {
263                 if(flag & UI_ACTIVE) M_LGREY;
264                 else M_GREY;
265         } else {
266                 if(flag & UI_ACTIVE) M_ACT_LIGHT;
267                 else M_LIGHT;
268         }
269
270         glVertex2f(x2,(y2-(y2-y1)/3));
271         glVertex2f(x1,(y2-(y2-y1)/3));
272         glEnd();
273         
274
275         glShadeModel(GL_FLAT);
276         glBegin(GL_QUADS);
277         
278         if(flag & UI_SELECT) {
279                 if(flag & UI_ACTIVE) M_LGREY;
280                 else M_GREY;
281         } else {
282                 if(flag & UI_ACTIVE) M_ACT_LIGHT;
283                 else M_LIGHT;
284         }
285         
286         glVertex2f(x1,(y2-(y2-y1)/3));
287         glVertex2f(x2,(y2-(y2-y1)/3));
288         glVertex2f(x2,y2);
289         glVertex2f(x1,y2);
290
291         glEnd();
292         /* *** END SHADED BUTTON BASE *** */
293         
294         /* *** INNER OUTLINE *** */
295         /* left */
296         if(!(flag & UI_SELECT)) {
297                 glShadeModel(GL_SMOOTH);
298                 glBegin(GL_LINES);
299                 M_MEDIUM;
300                 glVertex2f(x1+1,y1+2);
301                 M_WHITE;
302                 glVertex2f(x1+1,y2);
303                 glEnd();
304         }
305         
306         /* right */
307                 if(!(flag & UI_SELECT)) {
308                 glShadeModel(GL_SMOOTH);
309                 glBegin(GL_LINES);
310                 M_MEDIUM;
311                 glVertex2f(x2-1,y1+2);
312                 M_WHITE;
313                 glVertex2f(x2-1,y2);
314                 glEnd();
315         }
316         
317         glShadeModel(GL_FLAT);
318         
319         /* top */
320         if(flag & UI_SELECT) {
321                 if(flag & UI_ACTIVE) M_LGREY;
322                 else M_GREY;
323         } else {
324                 if(flag & UI_ACTIVE) M_WHITE;
325                 else M_WHITE;
326         }
327
328         fdrawline(x1, (y2-1), x2, (y2-1));
329         
330         /* bottom */
331         if(flag & UI_SELECT) {
332                 if(flag & UI_ACTIVE) M_MEDIUM;
333                 else M_LGREY;
334         } else {
335                 if(flag & UI_ACTIVE) M_LMEDIUM;
336                 else M_MEDIUM;
337         }
338         fdrawline(x1, (y1+1), x2, (y1+1));
339         /* *** END INNER OUTLINE *** */
340         
341         /* *** OUTER OUTLINE *** */
342         if (mid) {
343                 // we draw full outline, its not AA, and it works better button mouse-over hilite
344                 MM_DARK;
345                 
346                 // left right
347                 fdrawline(x1, y1, x1, y2);
348                 fdrawline(x2, y1, x2, y2);
349         
350                 // top down
351                 fdrawline(x1, y2, x2, y2);
352                 fdrawline(x1, y1, x2, y1); 
353         } else {
354                 MM_DARK;
355                 gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, 1.5);
356         }
357         /* END OUTER OUTLINE */
358 }
359
360 /* base flat button */
361 static void flat_button(float x1, float y1, float x2, float y2, float asp, int colorid, int flag, int mid)
362 {
363         /* 'mid' arg determines whether the button is in the middle of
364          * an alignment group or not. 0 = not middle, 1 = is in the middle.
365          * Done to allow cleaner drawing
366          */
367          
368         /* *** FLAT TEXT/NUM FIELD *** */
369         glShadeModel(GL_FLAT);
370         if(flag & UI_SELECT) {
371                 if(flag & UI_ACTIVE) M_LGREY;
372                 else M_GREY;
373         }
374         else {
375                 if(flag & UI_ACTIVE) M_NUMTEXT_ACT_LIGHT;
376                 else M_NUMTEXT;
377         }
378
379         glRectf(x1, y1, x2, y2);
380         /* *** END FLAT TEXT/NUM FIELD *** */
381         
382         /* *** OUTER OUTLINE *** */
383         if (mid) {
384                 // we draw full outline, its not AA, and it works better button mouse-over hilite
385                 MM_DARK;
386                 
387                 // left right
388                 fdrawline(x1, y1, x1, y2);
389                 fdrawline(x2, y1, x2, y2);
390         
391                 // top down
392                 fdrawline(x1, y2, x2, y2);
393                 fdrawline(x1, y1, x2, y1); 
394         } else {
395                 MM_DARK;
396                 gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, 1.5);
397         }
398         /* END OUTER OUTLINE */
399 }
400
401 /* small side double arrow for iconrow */
402 static void ui_default_iconrow_arrows(float x1, float y1, float x2, float y2)
403 {
404         glEnable( GL_POLYGON_SMOOTH );
405         glEnable( GL_BLEND );
406         glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
407         
408         glShadeModel(GL_FLAT);
409         glBegin(GL_TRIANGLES);
410         glVertex2f((short)x2-2,(short)(y2-(y2-y1)/2)+1);
411         glVertex2f((short)x2-6,(short)(y2-(y2-y1)/2)+1);
412         glVertex2f((short)x2-4,(short)(y2-(y2-y1)/2)+4);
413         glEnd();
414                 
415         glBegin(GL_TRIANGLES);
416         glVertex2f((short)x2-2,(short)(y2-(y2-y1)/2) -1);
417         glVertex2f((short)x2-6,(short)(y2-(y2-y1)/2) -1);
418         glVertex2f((short)x2-4,(short)(y2-(y2-y1)/2) -4);
419         glEnd();
420         
421         glDisable( GL_BLEND );
422         glDisable( GL_POLYGON_SMOOTH );
423 }
424
425 /* side double arrow for menu */
426 static void ui_default_menu_arrows(float x1, float y1, float x2, float y2)
427 {
428         glEnable( GL_POLYGON_SMOOTH );
429         glEnable( GL_BLEND );
430         glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
431         
432         glShadeModel(GL_FLAT);
433         glBegin(GL_TRIANGLES);
434         glVertex2f((short)x2-4,(short)(y2-(y2-y1)/2)+1);
435         glVertex2f((short)x2-12,(short)(y2-(y2-y1)/2)+1);
436         glVertex2f((short)x2-8,(short)(y2-(y2-y1)/2)+4);
437         glEnd();
438                 
439         glBegin(GL_TRIANGLES);
440         glVertex2f((short)x2-4,(short)(y2-(y2-y1)/2) -1);
441         glVertex2f((short)x2-12,(short)(y2-(y2-y1)/2) -1);
442         glVertex2f((short)x2-8,(short)(y2-(y2-y1)/2) -4);
443         glEnd();
444         
445         glDisable( GL_BLEND );
446         glDisable( GL_POLYGON_SMOOTH );
447 }
448
449 /* left/right arrows for number fields */
450 static void ui_default_num_arrows(float x1, float y1, float x2, float y2)
451 {
452         if( x2-x1 > 25) {       // 25 is a bit arbitrary, but small buttons cant have arrows
453
454                 glEnable( GL_POLYGON_SMOOTH );
455                 glEnable( GL_BLEND );
456                 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
457                 
458                 glShadeModel(GL_FLAT);
459                 glBegin(GL_TRIANGLES);
460                 
461                 glVertex2f((short)x1+5,(short)(y2-(y2-y1)/2));
462                 glVertex2f((short)x1+10,(short)(y2-(y2-y1)/2)+4);
463                 glVertex2f((short)x1+10,(short)(y2-(y2-y1)/2)-4);
464                 glEnd();
465
466                 /* right */
467                 glShadeModel(GL_FLAT);
468                 glBegin(GL_TRIANGLES);
469
470                 glVertex2f((short)x2-5,(short)(y2-(y2-y1)/2));
471                 glVertex2f((short)x2-10,(short)(y2-(y2-y1)/2)-4);
472                 glVertex2f((short)x2-10,(short)(y2-(y2-y1)/2)+4);
473                 glEnd();
474                 
475                 glDisable( GL_BLEND );
476                 glDisable( GL_POLYGON_SMOOTH );
477         }
478 }
479
480 /* changing black/white for TOG3 buts */
481 static void ui_tog3_invert(float x1, float y1, float x2, float y2, int seltype)
482 {
483         short alpha = 30;
484         
485         if (seltype == 0) {
486                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
487                 glEnable(GL_BLEND);
488                 
489                 glColor4ub(0, 0, 0, alpha);
490                 glRectf(x2-6, y1, x2, (y1+(y2-y1)/2));
491                 
492                 glColor4ub(255, 255, 255, alpha);
493                 glRectf(x2-6, (y1+(y2-y1)/2), x2, y2);
494                 
495                 glDisable(GL_BLEND);
496         } else {
497                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
498                 glEnable(GL_BLEND);
499                 
500                 glColor4ub(255, 255, 255, alpha);
501                 glRectf(x2-6, y1, x2, (y1+(y2-y1)/2));
502                 
503                 glColor4ub(0, 0, 0, alpha);
504                 glRectf(x2-6, (y1+(y2-y1)/2), x2, y2);
505                 
506                 glDisable(GL_BLEND);
507         }
508 }
509
510 /* button/popup menu/iconrow drawing code */
511 static void ui_default_button(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
512 {
513         int align= (flag & UI_BUT_ALIGN);
514
515         if(align) {
516         
517                 /* *** BOTTOM OUTER SUNKEN EFFECT *** */
518                 if (!((align == UI_BUT_ALIGN_DOWN) ||
519                         (align == (UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT)) ||
520                         (align == (UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT)))) {
521                         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
522                         glEnable(GL_BLEND);
523                         MM_WHITE_OP;
524                         fdrawline(x1, y1-1, x2, y1-1);  
525                         glDisable(GL_BLEND);
526                 }
527                 /* *** END BOTTOM OUTER SUNKEN EFFECT *** */
528                 
529                 switch(align) {
530                 case UI_BUT_ALIGN_TOP:
531                         uiSetRoundBox(12);
532                         
533                         /* last arg in shaded_button() determines whether the button is in the middle of
534                          * an alignment group or not. 0 = not middle, 1 = is in the middle.
535                          * Done to allow cleaner drawing
536                          */
537                          
538                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
539                         break;
540                 case UI_BUT_ALIGN_DOWN:
541                         uiSetRoundBox(3);
542                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
543                         break;
544                 case UI_BUT_ALIGN_LEFT:
545                         
546                         /* RIGHT OUTER SUNKEN EFFECT */
547                         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
548                         glEnable(GL_BLEND);
549                         glShadeModel(GL_SMOOTH);
550                         glBegin(GL_LINES);
551                         MM_WHITE_OP;
552                         glVertex2f(x2+1,y1);
553                         MM_WHITE_TR;
554                         glVertex2f(x2+1,y2);
555                         glEnd();
556                         glDisable(GL_BLEND);
557                         
558                         uiSetRoundBox(6);
559                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
560                         break;
561                 case UI_BUT_ALIGN_RIGHT:
562                 
563                         /* LEFT OUTER SUNKEN EFFECT */
564                         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
565                         glEnable(GL_BLEND);
566                         glShadeModel(GL_SMOOTH);
567                         glBegin(GL_LINES);
568                         MM_WHITE_OP;
569                         glVertex2f(x1-1,y1);
570                         MM_WHITE_TR;
571                         glVertex2f(x1-1,y2);
572                         glEnd();
573                         glDisable(GL_BLEND);
574                 
575                         uiSetRoundBox(9);
576                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
577                         break;
578                         
579                 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT:
580                         uiSetRoundBox(1);
581                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
582                         break;
583                 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT:
584                         uiSetRoundBox(2);
585                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
586                         break;
587                 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_RIGHT:
588                 
589                         /* LEFT OUTER SUNKEN EFFECT */
590                         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
591                         glEnable(GL_BLEND);
592                         glShadeModel(GL_SMOOTH);
593                         glBegin(GL_LINES);
594                         MM_WHITE_OP;
595                         glVertex2f(x1-1,y1);
596                         MM_WHITE_TR;
597                         glVertex2f(x1-1,y2);
598                         glEnd();
599                         glDisable(GL_BLEND);
600                 
601                         uiSetRoundBox(8);
602                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
603                         break;
604                 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_LEFT:
605                 
606                         /* RIGHT OUTER SUNKEN EFFECT */
607                         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
608                         glEnable(GL_BLEND);
609                         glShadeModel(GL_SMOOTH);
610                         glBegin(GL_LINES);
611                         MM_WHITE_OP;
612                         glVertex2f(x2+1,y1);
613                         MM_WHITE_TR;
614                         glVertex2f(x2+1,y2);
615                         glEnd();
616                         glDisable(GL_BLEND);
617                         
618                         uiSetRoundBox(4);
619                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
620                         break;
621                         
622                 default:
623                         shaded_button(x1, y1, x2, y2, asp, colorid, flag, 1);
624                         break;
625                 }
626         } 
627         else {  
628                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
629                 glEnable(GL_BLEND);
630                 glShadeModel(GL_SMOOTH);
631                 
632                 /* BOTTOM OUTER SUNKEN EFFECT */
633                 MM_WHITE_OP;
634                 fdrawline(x1, y1-1, x2, y1-1);  
635                 
636                 /* LEFT OUTER SUNKEN EFFECT */
637                 glBegin(GL_LINES);
638                 MM_WHITE_OP;
639                 glVertex2f(x1-1,y1);
640                 MM_WHITE_TR;
641                 glVertex2f(x1-1,y2);
642                 glEnd();
643                 
644                 /* RIGHT OUTER SUNKEN EFFECT */
645                 glBegin(GL_LINES);
646                 MM_WHITE_OP;
647                 glVertex2f(x2+1,y1);
648                 MM_WHITE_TR;
649                 glVertex2f(x2+1,y2);
650                 glEnd();
651                 
652                 glDisable(GL_BLEND);
653         
654                 uiSetRoundBox(15);
655                 shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
656         }
657         
658         /* *** EXTRA DRAWING FOR SPECIFIC CONTROL TYPES *** */
659         switch(type) {
660         case ICONROW:
661         case ICONTEXTROW:
662                 /* DARKENED AREA */
663                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
664                 glEnable(GL_BLEND);
665                 
666                 glColor4ub(0, 0, 0, 30);
667                 glRectf(x2-9, y1, x2, y2);
668         
669                 glDisable(GL_BLEND);
670                 /* END DARKENED AREA */
671         
672                 /* ICONROW DOUBLE-ARROW  */
673                 M_DARK;
674                 ui_default_iconrow_arrows(x1, y1, x2, y2);
675                 /* END ICONROW DOUBLE-ARROW */
676                 break;
677         case MENU:
678                 /* DARKENED AREA */
679                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
680                 glEnable(GL_BLEND);
681                 
682                 glColor4ub(0, 0, 0, 30);
683                 glRectf(x2-18, y1, x2, y2);
684         
685                 glDisable(GL_BLEND);
686                 /* END DARKENED AREA */
687         
688                 /* MENU DOUBLE-ARROW  */
689                 M_DARK;
690                 ui_default_menu_arrows(x1, y1, x2, y2);
691                 /* MENU DOUBLE-ARROW */
692                 break;
693         }       
694 }
695
696
697 /* number/text field drawing code */
698 static void ui_default_flat(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
699 {
700         int align= (flag & UI_BUT_ALIGN);
701
702         if(align) {
703         
704                 /* *** BOTTOM OUTER SUNKEN EFFECT *** */
705                 if (!((align == UI_BUT_ALIGN_DOWN) ||
706                         (align == (UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT)) ||
707                         (align == (UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT)))) {
708                         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
709                         glEnable(GL_BLEND);
710                         MM_WHITE_OP;
711                         fdrawline(x1, y1-1, x2, y1-1);  
712                         glDisable(GL_BLEND);
713                 }
714                 /* *** END BOTTOM OUTER SUNKEN EFFECT *** */
715                 
716                 switch(align) {
717                 case UI_BUT_ALIGN_TOP:
718                         uiSetRoundBox(12);
719                         
720                         /* last arg in shaded_button() determines whether the button is in the middle of
721                          * an alignment group or not. 0 = not middle, 1 = is in the middle.
722                          * Done to allow cleaner drawing
723                          */
724                          
725                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
726                         break;
727                 case UI_BUT_ALIGN_DOWN:
728                         uiSetRoundBox(3);
729                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
730                         break;
731                 case UI_BUT_ALIGN_LEFT:
732                         
733                         /* RIGHT OUTER SUNKEN EFFECT */
734                         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
735                         glEnable(GL_BLEND);
736                         glShadeModel(GL_SMOOTH);
737                         glBegin(GL_LINES);
738                         MM_WHITE_OP;
739                         glVertex2f(x2+1,y1);
740                         MM_WHITE_TR;
741                         glVertex2f(x2+1,y2);
742                         glEnd();
743                         glDisable(GL_BLEND);
744                         
745                         uiSetRoundBox(6);
746                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
747                         break;
748                 case UI_BUT_ALIGN_RIGHT:
749                 
750                         /* LEFT OUTER SUNKEN EFFECT */
751                         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
752                         glEnable(GL_BLEND);
753                         glShadeModel(GL_SMOOTH);
754                         glBegin(GL_LINES);
755                         MM_WHITE_OP;
756                         glVertex2f(x1-1,y1);
757                         MM_WHITE_TR;
758                         glVertex2f(x1-1,y2);
759                         glEnd();
760                         glDisable(GL_BLEND);
761                 
762                         uiSetRoundBox(9);
763                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
764                         break;
765                         
766                 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT:
767                         uiSetRoundBox(1);
768                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
769                         break;
770                 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT:
771                         uiSetRoundBox(2);
772                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
773                         break;
774                 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_RIGHT:
775                 
776                         /* LEFT OUTER SUNKEN EFFECT */
777                         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
778                         glEnable(GL_BLEND);
779                         glShadeModel(GL_SMOOTH);
780                         glBegin(GL_LINES);
781                         MM_WHITE_OP;
782                         glVertex2f(x1-1,y1);
783                         MM_WHITE_TR;
784                         glVertex2f(x1-1,y2);
785                         glEnd();
786                         glDisable(GL_BLEND);
787                 
788                         uiSetRoundBox(8);
789                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
790                         break;
791                 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_LEFT:
792                 
793                         /* RIGHT OUTER SUNKEN EFFECT */
794                         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
795                         glEnable(GL_BLEND);
796                         glShadeModel(GL_SMOOTH);
797                         glBegin(GL_LINES);
798                         MM_WHITE_OP;
799                         glVertex2f(x2+1,y1);
800                         MM_WHITE_TR;
801                         glVertex2f(x2+1,y2);
802                         glEnd();
803                         glDisable(GL_BLEND);
804                         
805                         uiSetRoundBox(4);
806                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
807                         break;
808                         
809                 default:
810                         flat_button(x1, y1, x2, y2, asp, colorid, flag, 1);
811                         break;
812                 }
813         } 
814         else {
815         
816                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
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         glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
1080
1081         BIF_GetThemeColor3ubv(colorid, col);
1082                 
1083         if(col[0]<100) col[0]= 0; else col[0]-= 100;
1084         if(col[1]<100) col[1]= 0; else col[1]-= 100;
1085         if(col[2]<100) col[2]= 0; else col[2]-= 100;
1086         col[3]= 80;
1087         glColor4ubv(col);
1088         gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, rad - asp);
1089         gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, rad + asp);
1090         col[3]= 180;
1091         glColor4ubv(col);
1092         gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, rad);
1093
1094         glDisable( GL_BLEND );
1095 }
1096
1097 /* button in midst of alignment row */
1098 static void round_button_mid(float x1, float y1, float x2, float y2, float asp, 
1099                                                          int colorid, int align, int menudeco, int curshade)
1100 {
1101         glRectf(x1, y1, x2, y2);
1102         
1103         if(menudeco) {
1104                 BIF_ThemeColorShade(colorid, curshade-20);
1105                 glRectf(x2-menudeco, y1, x2, y2);
1106         }
1107         
1108         BIF_ThemeColorBlendShade(colorid, TH_BACK, 0.5, -70);
1109         // we draw full outline, its not AA, and it works better button mouse-over hilite
1110         
1111         // left right
1112         fdrawline(x1, y1, x1, y2);
1113         fdrawline(x2, y1, x2, y2);
1114
1115         // top down
1116         fdrawline(x1, y2, x2, y2);
1117         fdrawline(x1, y1, x2, y1);   
1118 }
1119
1120 static void ui_draw_round(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1121 {
1122         int align= (flag & UI_BUT_ALIGN);
1123         int curshade= 0, menudeco= 0;
1124         
1125         if(type==ICONROW || type==ICONTEXTROW) menudeco= 9;
1126         else if((type==MENU || type==BLOCK) && x2-x1>24) menudeco= 16;
1127         
1128         /* paper */
1129         if(flag & UI_SELECT) {
1130                 if(flag & UI_ACTIVE) curshade= -40;
1131                 else curshade= -30;
1132         }
1133         else {
1134                 if(flag & UI_ACTIVE) curshade= 30;
1135                 else curshade= +20;
1136         }
1137         
1138         BIF_ThemeColorShade(colorid, curshade);
1139
1140         if(align) {
1141                 switch(align) {
1142                 case UI_BUT_ALIGN_TOP:
1143                         round_button(x1, y1, x2, y2, asp, colorid, 12, menudeco, curshade);
1144                         break;
1145                 case UI_BUT_ALIGN_DOWN:
1146                         round_button(x1, y1, x2, y2, asp, colorid, 3, menudeco, curshade);
1147                         break;
1148                 case UI_BUT_ALIGN_LEFT:
1149                         round_button(x1, y1, x2, y2, asp, colorid, 6, menudeco, curshade);
1150                         break;
1151                 case UI_BUT_ALIGN_RIGHT:
1152                         round_button(x1, y1, x2, y2, asp, colorid, 9, menudeco, curshade);
1153                         break;
1154                         
1155                 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT:
1156                         round_button(x1, y1, x2, y2, asp, colorid, 1, menudeco, curshade);
1157                         break;
1158                 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT:
1159                         round_button(x1, y1, x2, y2, asp, colorid, 2, menudeco, curshade);
1160                         break;
1161                 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_RIGHT:
1162                         round_button(x1, y1, x2, y2, asp, colorid, 8, menudeco, curshade);
1163                         break;
1164                 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_LEFT:
1165                         round_button(x1, y1, x2, y2, asp, colorid, 4, menudeco, curshade);
1166                         break;
1167                         
1168                 default:
1169                         round_button_mid(x1, y1, x2, y2, asp, colorid, align, menudeco, curshade);
1170                         break;
1171                 }
1172         } 
1173         else {
1174                 round_button(x1, y1, x2, y2, asp, colorid, 15, menudeco, curshade);
1175         }
1176
1177         /* special type decorations */
1178         switch(type) {
1179         case NUM:
1180                 BIF_ThemeColorShade(colorid, curshade-60);
1181                 ui_default_num_arrows(x1, y1, x2, y2);
1182                 break;
1183
1184         case ICONROW: 
1185         case ICONTEXTROW: 
1186                 BIF_ThemeColorShade(colorid, curshade-60);
1187                 ui_default_iconrow_arrows(x1, y1, x2, y2);
1188                 break;
1189                 
1190         case MENU: 
1191         case BLOCK: 
1192                 BIF_ThemeColorShade(colorid, curshade-60);
1193                 ui_default_menu_arrows(x1, y1, x2, y2);
1194                 break;
1195         }
1196 }
1197
1198 /* *************** MINIMAL THEME ***************** */
1199
1200 // theme can define an embosfunc and sliderfunc, text+icon drawing is standard, no theme.
1201
1202
1203
1204 /* super minimal button as used in logic menu */
1205 static void ui_draw_minimal(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1206 {
1207         
1208         x1+= asp;
1209         x2-= asp;
1210         y1+= asp;
1211         y2-= asp;
1212
1213         /* paper */
1214         if(flag & UI_SELECT) {
1215                 if(flag & UI_ACTIVE) BIF_ThemeColorShade(colorid, -40);
1216                 else BIF_ThemeColorShade(colorid, -30);
1217         }
1218         else {
1219                 if(flag & UI_ACTIVE) BIF_ThemeColorShade(colorid, +20);
1220                 else BIF_ThemeColorShade(colorid, +10);
1221         }
1222         
1223         glRectf(x1, y1, x2, y2);
1224
1225         if(flag & UI_SELECT) {
1226                 BIF_ThemeColorShade(colorid, -60);
1227
1228                 /* top */
1229                 fdrawline(x1, y2, x2, y2);
1230                 /* left */
1231                 fdrawline(x1, y1, x1, y2);
1232                 BIF_ThemeColorShade(colorid, +40);
1233
1234                 /* below */
1235                 fdrawline(x1, y1, x2, y1);
1236                 /* right */
1237                 fdrawline(x2, y1, x2, y2);
1238         }
1239         else {
1240                 BIF_ThemeColorShade(colorid, +40);
1241
1242                 /* top */
1243                 fdrawline(x1, y2, x2, y2);
1244                 /* left */
1245                 fdrawline(x1, y1, x1, y2);
1246                 
1247                 BIF_ThemeColorShade(colorid, -60);
1248                 /* below */
1249                 fdrawline(x1, y1, x2, y1);
1250                 /* right */
1251                 fdrawline(x2, y1, x2, y2);
1252         }
1253         
1254         /* special type decorations */
1255         switch(type) {
1256         case NUM:
1257                 if(flag & UI_SELECT) BIF_ThemeColorShade(colorid, -60);
1258                 else BIF_ThemeColorShade(colorid, -30);
1259                 ui_default_num_arrows(x1, y1, x2, y2);
1260                 break;
1261
1262         case ICONROW: 
1263         case ICONTEXTROW: 
1264                 if(flag & UI_ACTIVE) BIF_ThemeColorShade(colorid, 0);
1265                 else BIF_ThemeColorShade(colorid, -10);
1266                 glRectf(x2-9, y1+asp, x2-asp, y2-asp);
1267
1268                 BIF_ThemeColorShade(colorid, -50);
1269                 ui_default_iconrow_arrows(x1, y1, x2, y2);
1270                 break;
1271                 
1272         case MENU: 
1273         case BLOCK: 
1274                 if(flag & UI_ACTIVE) BIF_ThemeColorShade(colorid, 0);
1275                 else BIF_ThemeColorShade(colorid, -10);
1276                 glRectf(x2-17, y1+asp, x2-asp, y2-asp);
1277
1278                 BIF_ThemeColorShade(colorid, -50);
1279                 ui_default_menu_arrows(x1, y1, x2, y2);
1280                 break;
1281         }
1282         
1283         
1284 }
1285
1286
1287 /* fac is the slider handle position between x1 and x2 */
1288 static void ui_draw_slider(int colorid, float fac, float aspect, float x1, float y1, float x2, float y2, int flag)
1289 {
1290         float ymid, yc;
1291
1292         /* the slider background line */
1293         ymid= (y1+y2)/2.0;
1294         yc= 1.7*aspect; 
1295
1296         if(flag & UI_ACTIVE) 
1297                 BIF_ThemeColorShade(colorid, -50); 
1298         else 
1299                 BIF_ThemeColorShade(colorid, -40); 
1300
1301         /* left part */
1302         glRectf(x1, ymid-2.0*yc, x1+fac, ymid+2.0*yc);
1303         /* right part */
1304         glRectf(x1+fac, ymid-yc, x2, ymid+yc);
1305
1306         /* the movable slider */
1307         
1308         BIF_ThemeColorShade(colorid, +70); 
1309         glRectf(x1+fac-aspect, ymid-2.0*yc, x1+fac+aspect, ymid+2.0*yc);
1310
1311 }
1312
1313 /* ************** STANDARD MENU DRAWING FUNCTION ************* */
1314
1315
1316 static void ui_shadowbox(float minx, float miny, float maxx, float maxy, float shadsize, unsigned char alpha)
1317 {
1318         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1319         glEnable(GL_BLEND);
1320         glShadeModel(GL_SMOOTH);
1321         
1322         /* right quad */
1323         glBegin(GL_POLYGON);
1324         glColor4ub(0, 0, 0, alpha);
1325         glVertex2f(maxx, miny);
1326         glVertex2f(maxx, maxy-shadsize);
1327         glColor4ub(0, 0, 0, 0);
1328         glVertex2f(maxx+shadsize, maxy-shadsize-shadsize);
1329         glVertex2f(maxx+shadsize, miny);
1330         glEnd();
1331         
1332         /* corner shape */
1333         glBegin(GL_POLYGON);
1334         glColor4ub(0, 0, 0, alpha);
1335         glVertex2f(maxx, miny);
1336         glColor4ub(0, 0, 0, 0);
1337         glVertex2f(maxx+shadsize, miny);
1338         glVertex2f(maxx+0.7*shadsize, miny-0.7*shadsize);
1339         glVertex2f(maxx, miny-shadsize);
1340         glEnd();
1341         
1342         /* bottom quad */               
1343         glBegin(GL_POLYGON);
1344         glColor4ub(0, 0, 0, alpha);
1345         glVertex2f(minx+shadsize, miny);
1346         glVertex2f(maxx, miny);
1347         glColor4ub(0, 0, 0, 0);
1348         glVertex2f(maxx, miny-shadsize);
1349         glVertex2f(minx+shadsize+shadsize, miny-shadsize);
1350         glEnd();
1351         
1352         glDisable(GL_BLEND);
1353         glShadeModel(GL_FLAT);
1354 }
1355
1356 void uiDrawBoxShadow(unsigned char alpha, float minx, float miny, float maxx, float maxy)
1357 {
1358         /* accumulated outline boxes to make shade not linear, is more pleasant */
1359         ui_shadowbox(minx, miny, maxx, maxy, 6.0, (30*alpha)>>8);
1360         ui_shadowbox(minx, miny, maxx, maxy, 4.0, (70*alpha)>>8);
1361         ui_shadowbox(minx, miny, maxx, maxy, 2.0, (100*alpha)>>8);
1362         
1363 }
1364
1365 // background for pulldowns, pullups, and other drawing temporal menus....
1366 // has to be made themable still (now only color)
1367
1368 void uiDrawMenuBox(float minx, float miny, float maxx, float maxy, short flag)
1369 {
1370         char col[4];
1371         BIF_GetThemeColor4ubv(TH_MENU_BACK, col);
1372         
1373         if( (flag & UI_BLOCK_NOSHADOW)==0) {
1374                 /* accumulated outline boxes to make shade not linear, is more pleasant */
1375                 ui_shadowbox(minx, miny, maxx, maxy, 6.0, (30*col[3])>>8);
1376                 ui_shadowbox(minx, miny, maxx, maxy, 4.0, (70*col[3])>>8);
1377                 ui_shadowbox(minx, miny, maxx, maxy, 2.0, (100*col[3])>>8);
1378                 
1379                 glEnable(GL_BLEND);
1380                 glColor4ubv(col);
1381                 glRectf(minx-1, miny, minx, maxy);      // 1 pixel on left, to distinguish sublevel menus
1382         }
1383         glEnable(GL_BLEND);
1384         glColor4ubv(col);
1385         glRectf(minx, miny, maxx, maxy);
1386         glDisable(GL_BLEND);
1387 }
1388
1389
1390
1391 /* pulldown menu item */
1392 static void ui_draw_pulldown_item(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1393 {
1394         char col[4];
1395         
1396         BIF_GetThemeColor4ubv(TH_MENU_BACK, col);
1397         if(col[3]!=255) {
1398                 glEnable(GL_BLEND);
1399                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1400         }
1401         
1402         if((flag & UI_ACTIVE) && type!=LABEL) {
1403                 BIF_ThemeColor4(TH_MENU_HILITE);
1404                 glRectf(x1, y1, x2, y2);
1405         
1406
1407         } else {
1408                 BIF_ThemeColor4(colorid);       // is set at TH_MENU_ITEM when pulldown opened.
1409                 glRectf(x1, y1, x2, y2);
1410         }
1411
1412         glDisable(GL_BLEND);
1413 }
1414
1415 /* pulldown menu calling button */
1416 static void ui_draw_pulldown_round(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1417 {
1418         
1419         if(flag & UI_ACTIVE) {
1420                 BIF_ThemeColor(TH_MENU_HILITE);
1421
1422                 uiSetRoundBox(15);
1423                 gl_round_box(GL_POLYGON, x1, y1+3, x2, y2-3, 7.0);
1424
1425                 glEnable( GL_LINE_SMOOTH );
1426                 glEnable( GL_BLEND );
1427                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1428                 gl_round_box(GL_LINE_LOOP, x1, y1+3, x2, y2-3, 7.0);
1429                 glDisable( GL_LINE_SMOOTH );
1430                 glDisable( GL_BLEND );
1431                 
1432         } else {
1433                 BIF_ThemeColor(colorid);        // is set at TH_MENU_ITEM when pulldown opened.
1434                 glRectf(x1-1, y1+2, x2+1, y2-2);
1435         }
1436         
1437 }
1438
1439
1440 /* ************** TEXT AND ICON DRAWING FUNCTIONS ************* */
1441
1442
1443
1444 /* draws text and icons for buttons */
1445 static void ui_draw_text_icon(uiBut *but)
1446 {
1447         float x;
1448         int len;
1449         char *cpoin;
1450         
1451         /* check for button text label */
1452         if (but->type == ICONTEXTROW) {
1453                 ui_draw_icon(but, (BIFIconID) (but->icon+but->iconadd));
1454         }
1455         else {
1456
1457                 // text button cursor
1458                 if(but->pos != -1) {
1459                         short t, pos, ch;
1460                         
1461                         pos= but->pos+strlen(but->str);
1462                         if(pos >= but->ofs) {
1463                                 if(but->drawstr[0]!=0) {
1464                                         ch= but->drawstr[pos];
1465                                         but->drawstr[pos]= 0;
1466                 
1467                                         t= but->aspect*BIF_GetStringWidth(but->font, but->drawstr+but->ofs, (U.transopts & USER_TR_BUTTONS)) + 3;
1468                 
1469                                         but->drawstr[pos]= ch;
1470                                 }
1471                                 else t= 3;
1472                                 
1473                                 glColor3ub(255,0,0);
1474                                 glRects(but->x1+t, but->y1+2, but->x1+t+3, but->y2-2);
1475                         }       
1476                 }
1477                 if(but->drawstr[0]!=0) {
1478                         int transopts;
1479                         
1480                         // cut string in 2 parts
1481                         cpoin= strchr(but->drawstr, '|');
1482                         if(cpoin) *cpoin= 0;
1483
1484                         /* If there's an icon too (made with uiDefIconTextBut) then draw the icon
1485                         and offset the text label to accomodate it */
1486                         
1487                         if ( (but->flag & UI_HAS_ICON) && (but->flag & UI_ICON_LEFT) ) {
1488                                 ui_draw_icon(but, but->icon);
1489
1490                                 if(but->flag & UI_TEXT_LEFT) x= but->x1+24.0;
1491                                 else x= (but->x1+but->x2-but->strwidth+1)/2.0;
1492                         }
1493                         else {
1494                                 if(but->flag & UI_TEXT_LEFT) x= but->x1+4.0;
1495                                 else x= (but->x1+but->x2-but->strwidth+1)/2.0;
1496                         }
1497                         
1498                         /* text color, with pulldown item exception */
1499                         if(but->dt==UI_EMBOSSP) {
1500                                 if((but->flag & (UI_SELECT|UI_ACTIVE)) && but->type!=LABEL) {   // LABEL = title in pulldowns
1501                                         BIF_ThemeColor(TH_MENU_TEXT_HI);
1502                                 } else {
1503                                         BIF_ThemeColor(TH_MENU_TEXT);
1504                                 }
1505                         }
1506                         else {
1507                                 if(but->flag & UI_SELECT) {             
1508                                         BIF_ThemeColor(TH_BUT_TEXT_HI);
1509                                 } else {
1510                                         BIF_ThemeColor(TH_BUT_TEXT);
1511                                 }
1512                         }
1513
1514                         /* tog3 button exception */
1515                         if(but->type==TOG3 && (but->flag & UI_SELECT)) {
1516                                 int ok= 0;
1517                                 
1518                                 if( but->pointype==CHA ) {
1519                                         if( BTST( *(but->poin+2), but->bitnr )) ok= 1;
1520                                 }
1521                                 else if( but->pointype ==SHO ) {
1522                                         short *sp= (short *)but->poin;
1523                                         if( BTST( sp[1], but->bitnr )) ok= 1;
1524                                 }
1525                                 
1526                                 ui_tog3_invert(but->x1,but->y1,but->x2,but->y2, ok);
1527                                 if (ok) glColor3ub(255, 255, 0);
1528                         }
1529                         
1530                         /* LABEL button exception */
1531                         if(but->type==LABEL && but->min!=0.0) BIF_ThemeColor(TH_BUT_TEXT_HI);
1532                 
1533                         ui_rasterpos_safe(x, (but->y1+but->y2- 9.0)/2.0, but->aspect);
1534                         if(but->type==TEX || but->type==IDPOIN) transopts= 0;   // no translation, of course!
1535                         else transopts= (U.transopts & USER_TR_BUTTONS);
1536                         BIF_DrawString(but->font, but->drawstr+but->ofs, transopts);
1537
1538                         /* part text right aligned */
1539                         if(cpoin) {
1540                                 len= BIF_GetStringWidth(but->font, cpoin+1, (U.transopts & USER_TR_BUTTONS));
1541                                 ui_rasterpos_safe( but->x2 - len*but->aspect-3, (but->y1+but->y2- 9.0)/2.0, but->aspect);
1542                                 BIF_DrawString(but->font, cpoin+1, (U.transopts & USER_TR_BUTTONS));
1543                                 *cpoin= '|';
1544                         }
1545                 }
1546                 /* if there's no text label, then check to see if there's an icon only and draw it */
1547                 else if( but->flag & UI_HAS_ICON ) {
1548                         ui_draw_icon(but, (BIFIconID) (but->icon+but->iconadd));
1549                 }
1550         }
1551 }
1552
1553 static void ui_draw_but_COL(uiBut *but)
1554 {
1555         float *fp;
1556         char colr, colg, colb;
1557         
1558         if( but->pointype==FLO ) {
1559                 fp= (float *)but->poin;
1560                 colr= floor(255.0*fp[0]+0.5);
1561                 colg= floor(255.0*fp[1]+0.5);
1562                 colb= floor(255.0*fp[2]+0.5);
1563         }
1564         else {
1565                 char *cp= (char *)but->poin;
1566                 colr= cp[0];
1567                 colg= cp[1];
1568                 colb= cp[2];
1569         }
1570         
1571         /* exception... hrms, but can't simply use the emboss callback for this now. */
1572         /* this button type needs review, and nice integration with rest of API here */
1573         if(but->embossfunc == ui_draw_round) {
1574                 char *cp= BIF_ThemeGetColorPtr(U.themes.first, 0, TH_CUSTOM);
1575                 cp[0]= colr; cp[1]= colg; cp[2]= colb;
1576                 but->flag &= ~UI_SELECT;
1577                 but->embossfunc(but->type, TH_CUSTOM, but->aspect, but->x1, but->y1, but->x2, but->y2, but->flag);
1578         }
1579         else {
1580                 
1581                 glColor3ub(colr,  colg,  colb);
1582                 glRectf((but->x1), (but->y1), (but->x2), (but->y2));
1583                 glColor3ub(0,  0,  0);
1584                 fdrawbox((but->x1), (but->y1), (but->x2), (but->y2));
1585         }
1586 }
1587
1588 /* draws in resolution of 20x4 colors */
1589 static void ui_draw_but_HSVCUBE(uiBut *but)
1590 {
1591         int a;
1592         float h,s,v;
1593         float dx, dy, sx1, sx2, sy, x, y;
1594         float col0[4][3];       // left half, rect bottom to top
1595         float col1[4][3];       // right half, rect bottom to top
1596         
1597         h= but->hsv[0];
1598         s= but->hsv[1];
1599         v= but->hsv[2];
1600         
1601         /* draw series of gouraud rects */
1602         glShadeModel(GL_SMOOTH);
1603         
1604         if(but->a1==0) {        // H and V vary
1605                 hsv_to_rgb(0.0, s, 0.0,   &col1[0][0], &col1[0][1], &col1[0][2]);
1606                 hsv_to_rgb(0.0, s, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]);
1607                 hsv_to_rgb(0.0, s, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]);
1608                 hsv_to_rgb(0.0, s, 1.0,   &col1[3][0], &col1[3][1], &col1[3][2]);
1609                 x= h; y= v;
1610         }
1611         else if(but->a1==1) {   // H and S vary
1612                 hsv_to_rgb(0.0, 0.0, v,   &col1[0][0], &col1[0][1], &col1[0][2]);
1613                 hsv_to_rgb(0.0, 0.333, v, &col1[1][0], &col1[1][1], &col1[1][2]);
1614                 hsv_to_rgb(0.0, 0.666, v, &col1[2][0], &col1[2][1], &col1[2][2]);
1615                 hsv_to_rgb(0.0, 1.0, v,   &col1[3][0], &col1[3][1], &col1[3][2]);
1616                 x= h; y= s;
1617         }
1618         else if(but->a1==2) {   // S and V vary
1619                 hsv_to_rgb(h, 0.0, 0.0,   &col1[0][0], &col1[0][1], &col1[0][2]);
1620                 hsv_to_rgb(h, 0.333, 0.0, &col1[1][0], &col1[1][1], &col1[1][2]);
1621                 hsv_to_rgb(h, 0.666, 0.0, &col1[2][0], &col1[2][1], &col1[2][2]);
1622                 hsv_to_rgb(h, 1.0, 0.0,   &col1[3][0], &col1[3][1], &col1[3][2]);
1623                 x= v; y= s;
1624         }
1625         else {          // only hue slider
1626                 hsv_to_rgb(0.0, 1.0, 1.0,   &col1[0][0], &col1[0][1], &col1[0][2]);
1627                 VECCOPY(col1[1], col1[0]);
1628                 VECCOPY(col1[2], col1[0]);
1629                 VECCOPY(col1[3], col1[0]);
1630                 x= h; y= 0.5;
1631         }
1632         
1633         for(dx=0.0; dx<1.0; dx+= 0.05) {
1634                 // previous color
1635                 VECCOPY(col0[0], col1[0]);
1636                 VECCOPY(col0[1], col1[1]);
1637                 VECCOPY(col0[2], col1[2]);
1638                 VECCOPY(col0[3], col1[3]);
1639
1640                 // new color
1641                 if(but->a1==0) {        // H and V vary
1642                         hsv_to_rgb(dx, s, 0.0,   &col1[0][0], &col1[0][1], &col1[0][2]);
1643                         hsv_to_rgb(dx, s, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]);
1644                         hsv_to_rgb(dx, s, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]);
1645                         hsv_to_rgb(dx, s, 1.0,   &col1[3][0], &col1[3][1], &col1[3][2]);
1646                 }
1647                 else if(but->a1==1) {   // H and S vary
1648                         hsv_to_rgb(dx, 0.0, v,   &col1[0][0], &col1[0][1], &col1[0][2]);
1649                         hsv_to_rgb(dx, 0.333, v, &col1[1][0], &col1[1][1], &col1[1][2]);
1650                         hsv_to_rgb(dx, 0.666, v, &col1[2][0], &col1[2][1], &col1[2][2]);
1651                         hsv_to_rgb(dx, 1.0, v,   &col1[3][0], &col1[3][1], &col1[3][2]);
1652                 }
1653                 else if(but->a1==2) {   // S and V vary
1654                         hsv_to_rgb(h, 0.0, dx,   &col1[0][0], &col1[0][1], &col1[0][2]);
1655                         hsv_to_rgb(h, 0.333, dx, &col1[1][0], &col1[1][1], &col1[1][2]);
1656                         hsv_to_rgb(h, 0.666, dx, &col1[2][0], &col1[2][1], &col1[2][2]);
1657                         hsv_to_rgb(h, 1.0, dx,   &col1[3][0], &col1[3][1], &col1[3][2]);
1658                 }
1659                 else {  // only H
1660                         hsv_to_rgb(dx, 1.0, 1.0,   &col1[0][0], &col1[0][1], &col1[0][2]);
1661                         VECCOPY(col1[1], col1[0]);
1662                         VECCOPY(col1[2], col1[0]);
1663                         VECCOPY(col1[3], col1[0]);
1664                 }
1665                 
1666                 // rect
1667                 sx1= but->x1 + dx*(but->x2-but->x1);
1668                 sx2= but->x1 + (dx+0.05)*(but->x2-but->x1);
1669                 sy= but->y1;
1670                 dy= (but->y2-but->y1)/3.0;
1671                 
1672                 glBegin(GL_QUADS);
1673                 for(a=0; a<3; a++, sy+=dy) {
1674                         glColor3fv(col0[a]);
1675                         glVertex2f(sx1, sy);
1676
1677                         glColor3fv(col1[a]);
1678                         glVertex2f(sx2, sy);
1679                         
1680                         glColor3fv(col1[a+1]);
1681                         glVertex2f(sx2, sy+dy);
1682                         
1683                         glColor3fv(col0[a+1]);
1684                         glVertex2f(sx1, sy+dy);
1685                 }
1686                 glEnd();
1687         }
1688
1689         glShadeModel(GL_FLAT);
1690
1691         /* cursor */
1692         x= but->x1 + x*(but->x2-but->x1);
1693         y= but->y1 + y*(but->y2-but->y1);
1694         CLAMP(x, but->x1+3.0, but->x2-3.0);
1695         CLAMP(y, but->y1+3.0, but->y2-3.0);
1696         
1697         fdrawXORcirc(x, y, 3.1);
1698
1699         /* outline */
1700         glColor3ub(0,  0,  0);
1701         fdrawbox((but->x1), (but->y1), (but->x2), (but->y2));
1702 }
1703
1704 /* nothing! */
1705 static void ui_draw_nothing(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1706 {
1707 }
1708
1709
1710 /* ************** EXTERN, called from interface.c ************* */
1711 /* ************** MAIN CALLBACK FUNCTION          ************* */
1712
1713 void ui_set_embossfunc(uiBut *but, int drawtype)
1714 {
1715         // this aded for evaluating textcolor for example
1716         but->dt= drawtype;
1717         
1718         // not really part of standard minimal themes, just make sure it is set
1719         but->sliderfunc= ui_draw_slider;
1720
1721         // standard builtin first:
1722         if(but->type==LABEL) but->embossfunc= ui_draw_nothing;
1723         else if(but->type==PULLDOWN) but->embossfunc= ui_draw_pulldown_round;
1724         else if(drawtype==UI_EMBOSSM) but->embossfunc= ui_draw_minimal;
1725         else if(drawtype==UI_EMBOSSN) but->embossfunc= ui_draw_nothing;
1726         else if(drawtype==UI_EMBOSSP) but->embossfunc= ui_draw_pulldown_item;
1727         else {
1728                 int theme= BIF_GetThemeValue(TH_BUT_DRAWTYPE);
1729                 
1730                 // and the themes
1731                 if(theme==1) {
1732                         but->embossfunc= ui_draw_default;
1733                         but->sliderfunc= ui_default_slider;
1734                 }
1735                 else if(theme==2) {
1736                         but->embossfunc= ui_draw_round;
1737                 }
1738                 else if(theme==3) {
1739                         but->embossfunc= ui_draw_oldskool;
1740                 }
1741                 else {
1742                         but->embossfunc= ui_draw_minimal;
1743                 }
1744         }
1745         
1746         // note: if you want aligning, adapt the call uiBlockEndAlign in interface.c 
1747 }
1748
1749
1750 void ui_draw_but(uiBut *but)
1751 {
1752         double value;
1753         float x1, x2, y1, y2, fac;
1754         
1755         if(but==NULL) return;
1756
1757         /* signal for frontbuf flush buttons and menus, not when normal drawing */
1758         if(but->block->in_use) ui_block_set_flush(but->block, but);
1759                 
1760         switch (but->type) {
1761
1762         case NUMSLI:
1763         case HSVSLI:
1764         
1765                 but->embossfunc(but->type, but->themecol, but->aspect, but->x1, but->y1, but->x2, but->y2, but->flag);
1766                 ui_draw_text_icon(but);
1767
1768                 x1= (but->x1+but->x2)/2;
1769                 x2= but->x2 - 5.0*but->aspect;
1770                 y1= but->y1 + 2.0*but->aspect;
1771                 y2= but->y2 - 2.0*but->aspect;
1772                 
1773                 value= ui_get_but_val(but);
1774                 fac= (value-but->min)*(x2-x1)/(but->max - but->min);
1775                 
1776                 but->sliderfunc(but->themecol, fac, but->aspect, x1, y1, x2, y2, but->flag);
1777                 break;
1778                 
1779         case SEPR:
1780                 //  only background
1781                 break;
1782                 
1783         case COL:
1784                 ui_draw_but_COL(but);  // black box with color
1785                 break;
1786
1787         case HSVCUBE:
1788                 ui_draw_but_HSVCUBE(but);  // box for colorpicker, three types
1789                 break;
1790
1791         case LINK:
1792         case INLINK:
1793                 ui_draw_icon(but, but->icon);
1794                 break;
1795
1796         default:
1797                 but->embossfunc(but->type, but->themecol, but->aspect, but->x1, but->y1, but->x2, but->y2, but->flag);
1798                 ui_draw_text_icon(but);
1799         
1800         }
1801 }
1802