2 * $Id: interface_draw.c 15733 2008-07-24 09:23:13Z aligorith $
4 * ***** BEGIN GPL LICENSE BLOCK *****
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.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
23 * The Original Code is: all of this file.
25 * Contributor(s): none yet.
27 * ***** END GPL LICENSE BLOCK *****
33 #include "DNA_color_types.h"
34 #include "DNA_listBase.h"
35 #include "DNA_object_types.h"
36 #include "DNA_screen_types.h"
37 #include "DNA_texture_types.h"
38 #include "DNA_userdef_types.h"
40 #include "BLI_arithb.h"
42 #include "BKE_colortools.h"
43 #include "BKE_texture.h"
44 #include "BKE_utildefines.h"
47 #include "BIF_glutil.h"
49 #include "UI_interface.h"
50 #include "UI_interface_icons.h"
58 #include "interface_intern.h"
60 #define UI_RB_ALPHA 16
61 #define UI_DISABLED_ALPHA_OFFS -160
63 static int roundboxtype= 15;
65 void uiSetRoundBox(int type)
67 /* Not sure the roundbox function is the best place to change this
68 * if this is undone, its not that big a deal, only makes curves edges
70 if (UI_GetThemeValue(TH_BUT_DRAWTYPE) == TH_MINIMAL)
75 /* flags to set which corners will become rounded:
84 int uiGetRoundBox(void)
86 if (ELEM3(UI_GetThemeValue(TH_BUT_DRAWTYPE), TH_MINIMAL, TH_SHADED, TH_OLDSKOOL))
92 void gl_round_box(int mode, float minx, float miny, float maxx, float maxy, float rad)
94 float vec[7][2]= {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
95 {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
100 vec[a][0]*= rad; vec[a][1]*= rad;
105 /* start with corner right-bottom */
106 if(roundboxtype & 4) {
107 glVertex2f(maxx-rad, miny);
109 glVertex2f(maxx-rad+vec[a][0], miny+vec[a][1]);
111 glVertex2f(maxx, miny+rad);
113 else glVertex2f(maxx, miny);
115 /* corner right-top */
116 if(roundboxtype & 2) {
117 glVertex2f(maxx, maxy-rad);
119 glVertex2f(maxx-vec[a][1], maxy-rad+vec[a][0]);
121 glVertex2f(maxx-rad, maxy);
123 else glVertex2f(maxx, maxy);
125 /* corner left-top */
126 if(roundboxtype & 1) {
127 glVertex2f(minx+rad, maxy);
129 glVertex2f(minx+rad-vec[a][0], maxy-vec[a][1]);
131 glVertex2f(minx, maxy-rad);
133 else glVertex2f(minx, maxy);
135 /* corner left-bottom */
136 if(roundboxtype & 8) {
137 glVertex2f(minx, miny+rad);
139 glVertex2f(minx+vec[a][1], miny+rad-vec[a][0]);
141 glVertex2f(minx+rad, miny);
143 else glVertex2f(minx, miny);
148 static void round_box_shade_col(float *col1, float *col2, float fac)
152 col[0]= (fac*col1[0] + (1.0-fac)*col2[0]);
153 col[1]= (fac*col1[1] + (1.0-fac)*col2[1]);
154 col[2]= (fac*col1[2] + (1.0-fac)*col2[2]);
159 /* only for headers */
160 static void gl_round_box_topshade(float minx, float miny, float maxx, float maxy, float rad)
162 float vec[7][2]= {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
163 {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
164 char col[7]= {140, 165, 195, 210, 230, 245, 255};
168 if(roundboxtype & UI_RB_ALPHA) alpha= 128;
172 vec[a][0]*= rad; vec[a][1]*= rad;
175 /* shades from grey->white->grey */
176 glBegin(GL_LINE_STRIP);
178 if(roundboxtype & 3) {
179 /* corner right-top */
180 glColor4ub(140, 140, 140, alpha);
181 glVertex2f( maxx, maxy-rad);
183 glColor4ub(col[a], col[a], col[a], alpha);
184 glVertex2f( maxx-vec[a][1], maxy-rad+vec[a][0]);
186 glColor4ub(225, 225, 225, alpha);
187 glVertex2f( maxx-rad, maxy);
190 /* corner left-top */
191 glVertex2f( minx+rad, maxy);
193 glColor4ub(col[6-a], col[6-a], col[6-a], alpha);
194 glVertex2f( minx+rad-vec[a][0], maxy-vec[a][1]);
196 glVertex2f( minx, maxy-rad);
199 glColor4ub(225, 225, 225, alpha);
200 glVertex2f( minx, maxy);
201 glVertex2f( maxx, maxy);
207 /* linear horizontal shade within button or in outline */
208 void gl_round_box_shade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadetop, float shadedown)
210 float vec[7][2]= {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
211 {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
212 float div= maxy-miny;
213 float coltop[3], coldown[3], color[4];
218 vec[a][0]*= rad; vec[a][1]*= rad;
220 /* get current color, needs to be outside of glBegin/End */
221 glGetFloatv(GL_CURRENT_COLOR, color);
223 /* 'shade' defines strength of shading */
224 coltop[0]= color[0]+shadetop; if(coltop[0]>1.0) coltop[0]= 1.0;
225 coltop[1]= color[1]+shadetop; if(coltop[1]>1.0) coltop[1]= 1.0;
226 coltop[2]= color[2]+shadetop; if(coltop[2]>1.0) coltop[2]= 1.0;
227 coldown[0]= color[0]+shadedown; if(coldown[0]<0.0) coldown[0]= 0.0;
228 coldown[1]= color[1]+shadedown; if(coldown[1]<0.0) coldown[1]= 0.0;
229 coldown[2]= color[2]+shadedown; if(coldown[2]<0.0) coldown[2]= 0.0;
231 if (UI_GetThemeValue(TH_BUT_DRAWTYPE) != TH_MINIMAL) {
232 glShadeModel(GL_SMOOTH);
236 /* start with corner right-bottom */
237 if(roundboxtype & 4) {
239 round_box_shade_col(coltop, coldown, 0.0);
240 glVertex2f(maxx-rad, miny);
243 round_box_shade_col(coltop, coldown, vec[a][1]/div);
244 glVertex2f(maxx-rad+vec[a][0], miny+vec[a][1]);
247 round_box_shade_col(coltop, coldown, rad/div);
248 glVertex2f(maxx, miny+rad);
251 round_box_shade_col(coltop, coldown, 0.0);
252 glVertex2f(maxx, miny);
255 /* corner right-top */
256 if(roundboxtype & 2) {
258 round_box_shade_col(coltop, coldown, (div-rad)/div);
259 glVertex2f(maxx, maxy-rad);
262 round_box_shade_col(coltop, coldown, (div-rad+vec[a][1])/div);
263 glVertex2f(maxx-vec[a][1], maxy-rad+vec[a][0]);
265 round_box_shade_col(coltop, coldown, 1.0);
266 glVertex2f(maxx-rad, maxy);
269 round_box_shade_col(coltop, coldown, 1.0);
270 glVertex2f(maxx, maxy);
273 /* corner left-top */
274 if(roundboxtype & 1) {
276 round_box_shade_col(coltop, coldown, 1.0);
277 glVertex2f(minx+rad, maxy);
280 round_box_shade_col(coltop, coldown, (div-vec[a][1])/div);
281 glVertex2f(minx+rad-vec[a][0], maxy-vec[a][1]);
284 round_box_shade_col(coltop, coldown, (div-rad)/div);
285 glVertex2f(minx, maxy-rad);
288 round_box_shade_col(coltop, coldown, 1.0);
289 glVertex2f(minx, maxy);
292 /* corner left-bottom */
293 if(roundboxtype & 8) {
295 round_box_shade_col(coltop, coldown, rad/div);
296 glVertex2f(minx, miny+rad);
299 round_box_shade_col(coltop, coldown, (rad-vec[a][1])/div);
300 glVertex2f(minx+vec[a][1], miny+rad-vec[a][0]);
303 round_box_shade_col(coltop, coldown, 0.0);
304 glVertex2f(minx+rad, miny);
307 round_box_shade_col(coltop, coldown, 0.0);
308 glVertex2f(minx, miny);
312 glShadeModel(GL_FLAT);
315 /* linear vertical shade within button or in outline */
316 void gl_round_box_vertical_shade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadeLeft, float shadeRight)
318 float vec[7][2]= {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
319 {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
320 float div= maxx-minx;
321 float colLeft[3], colRight[3], color[4];
326 vec[a][0]*= rad; vec[a][1]*= rad;
328 /* get current color, needs to be outside of glBegin/End */
329 glGetFloatv(GL_CURRENT_COLOR, color);
331 /* 'shade' defines strength of shading */
332 colLeft[0]= color[0]+shadeLeft; if(colLeft[0]>1.0) colLeft[0]= 1.0;
333 colLeft[1]= color[1]+shadeLeft; if(colLeft[1]>1.0) colLeft[1]= 1.0;
334 colLeft[2]= color[2]+shadeLeft; if(colLeft[2]>1.0) colLeft[2]= 1.0;
335 colRight[0]= color[0]+shadeRight; if(colRight[0]<0.0) colRight[0]= 0.0;
336 colRight[1]= color[1]+shadeRight; if(colRight[1]<0.0) colRight[1]= 0.0;
337 colRight[2]= color[2]+shadeRight; if(colRight[2]<0.0) colRight[2]= 0.0;
339 if (UI_GetThemeValue(TH_BUT_DRAWTYPE) != TH_MINIMAL) {
340 glShadeModel(GL_SMOOTH);
344 /* start with corner right-bottom */
345 if(roundboxtype & 4) {
346 round_box_shade_col(colLeft, colRight, 0.0);
347 glVertex2f(maxx-rad, miny);
350 round_box_shade_col(colLeft, colRight, vec[a][0]/div);
351 glVertex2f(maxx-rad+vec[a][0], miny+vec[a][1]);
354 round_box_shade_col(colLeft, colRight, rad/div);
355 glVertex2f(maxx, miny+rad);
358 round_box_shade_col(colLeft, colRight, 0.0);
359 glVertex2f(maxx, miny);
362 /* corner right-top */
363 if(roundboxtype & 2) {
364 round_box_shade_col(colLeft, colRight, 0.0);
365 glVertex2f(maxx, maxy-rad);
369 round_box_shade_col(colLeft, colRight, (div-rad-vec[a][0])/div);
370 glVertex2f(maxx-vec[a][1], maxy-rad+vec[a][0]);
372 round_box_shade_col(colLeft, colRight, (div-rad)/div);
373 glVertex2f(maxx-rad, maxy);
376 round_box_shade_col(colLeft, colRight, 0.0);
377 glVertex2f(maxx, maxy);
380 /* corner left-top */
381 if(roundboxtype & 1) {
382 round_box_shade_col(colLeft, colRight, (div-rad)/div);
383 glVertex2f(minx+rad, maxy);
386 round_box_shade_col(colLeft, colRight, (div-rad+vec[a][0])/div);
387 glVertex2f(minx+rad-vec[a][0], maxy-vec[a][1]);
390 round_box_shade_col(colLeft, colRight, 1.0);
391 glVertex2f(minx, maxy-rad);
394 round_box_shade_col(colLeft, colRight, 1.0);
395 glVertex2f(minx, maxy);
398 /* corner left-bottom */
399 if(roundboxtype & 8) {
400 round_box_shade_col(colLeft, colRight, 1.0);
401 glVertex2f(minx, miny+rad);
404 round_box_shade_col(colLeft, colRight, (vec[a][0])/div);
405 glVertex2f(minx+vec[a][1], miny+rad-vec[a][0]);
408 round_box_shade_col(colLeft, colRight, 1.0);
409 glVertex2f(minx+rad, miny);
412 round_box_shade_col(colLeft, colRight, 1.0);
413 glVertex2f(minx, miny);
417 glShadeModel(GL_FLAT);
420 /* plain antialiased unfilled rectangle */
421 void uiRoundRect(float minx, float miny, float maxx, float maxy, float rad)
425 if(roundboxtype & UI_RB_ALPHA) {
426 glGetFloatv(GL_CURRENT_COLOR, color);
429 glEnable( GL_BLEND );
432 /* set antialias line */
433 if (UI_GetThemeValue(TH_BUT_DRAWTYPE) != TH_MINIMAL) {
434 glEnable( GL_LINE_SMOOTH );
435 glEnable( GL_BLEND );
438 gl_round_box(GL_LINE_LOOP, minx, miny, maxx, maxy, rad);
440 glDisable( GL_BLEND );
441 glDisable( GL_LINE_SMOOTH );
444 /* plain fake antialiased unfilled round rectangle */
445 void uiRoundRectFakeAA(float minx, float miny, float maxx, float maxy, float rad, float asp)
447 float color[4], alpha;
451 /* get the colour and divide up the alpha */
452 glGetFloatv(GL_CURRENT_COLOR, color);
454 color[3]= alpha/(float)passes;
457 /* set the 'jitter amount' */
458 raddiff = (1/(float)passes) * asp;
460 glEnable( GL_BLEND );
462 /* draw lots of lines on top of each other */
463 for (i=passes; i>=(-passes); i--) {
464 gl_round_box(GL_LINE_LOOP, minx, miny, maxx, maxy, rad+(i*raddiff));
467 glDisable( GL_BLEND );
473 /* (old, used in outliner) plain antialiased filled box */
474 void uiRoundBox(float minx, float miny, float maxx, float maxy, float rad)
478 if(roundboxtype & UI_RB_ALPHA) {
479 glGetFloatv(GL_CURRENT_COLOR, color);
482 glEnable( GL_BLEND );
486 gl_round_box(GL_POLYGON, minx, miny, maxx, maxy, rad);
488 /* set antialias line */
489 if (UI_GetThemeValue(TH_BUT_DRAWTYPE) != TH_MINIMAL) {
490 glEnable( GL_LINE_SMOOTH );
491 glEnable( GL_BLEND );
494 gl_round_box(GL_LINE_LOOP, minx, miny, maxx, maxy, rad);
496 glDisable( GL_BLEND );
497 glDisable( GL_LINE_SMOOTH );
500 void uiTriangleFakeAA(float x1, float y1, float x2, float y2, float x3, float y3, float asp)
502 float color[4], alpha;
506 /* get the colour and divide up the alpha */
507 glGetFloatv(GL_CURRENT_COLOR, color);
509 color[3]= alpha/(float)passes;
512 /* set the 'jitter amount' */
513 jitter = 0.65/(float)passes * asp;
515 glEnable( GL_BLEND );
517 /* draw lots of lines on top of each other */
518 for (i=passes; i>=(-passes); i--) {
519 glBegin(GL_TRIANGLES);
521 /* 'point' first, then two base vertices */
522 glVertex2f(x1, y1+(i*jitter));
523 glVertex2f(x2, y2+(i*jitter));
524 glVertex2f(x3, y3+(i*jitter));
528 glDisable( GL_BLEND );
534 /* for headers and floating panels */
535 void uiRoundBoxEmboss(float minx, float miny, float maxx, float maxy, float rad, int active)
539 if(roundboxtype & UI_RB_ALPHA) {
540 glGetFloatv(GL_CURRENT_COLOR, color);
543 glEnable( GL_BLEND );
548 // gl_round_box_shade(GL_POLYGON, minx, miny, maxx, maxy, rad, 0.10, -0.05);
550 /* shading doesnt work for certain buttons yet (pulldown) need smarter buffer caching (ton) */
551 gl_round_box(GL_POLYGON, minx, miny, maxx, maxy, rad);
553 /* set antialias line */
554 if (UI_GetThemeValue(TH_BUT_DRAWTYPE) != TH_MINIMAL) {
555 glEnable( GL_LINE_SMOOTH );
556 glEnable( GL_BLEND );
560 gl_round_box_topshade(minx+1, miny+1, maxx-1, maxy-1, rad);
563 if(roundboxtype & UI_RB_ALPHA) glColor4ub(0,0,0, 128); else glColor4ub(0,0,0, 200);
564 gl_round_box(GL_LINE_LOOP, minx, miny, maxx, maxy, rad);
566 glDisable( GL_LINE_SMOOTH );
568 /* bottom shade for header down */
569 if((roundboxtype & 12)==12) {
570 glColor4ub(0,0,0, 80);
571 fdrawline(minx+rad-1.0, miny+1.0, maxx-rad+1.0, miny+1.0);
573 glDisable( GL_BLEND );
576 /* ************** safe rasterpos for pixmap alignment with pixels ************* */
578 void ui_rasterpos_safe(float x, float y, float aspect)
580 float vals[4], remainder;
584 glGetFloatv(GL_CURRENT_RASTER_POSITION, vals);
586 remainder= vals[0] - floor(vals[0]);
587 if(remainder > 0.4 && remainder < 0.6) {
588 if(remainder < 0.5) x -= 0.1*aspect;
589 else x += 0.1*aspect;
592 remainder= vals[1] - floor(vals[1]);
593 if(remainder > 0.4 && remainder < 0.6) {
594 if(remainder < 0.5) y -= 0.1*aspect;
595 else y += 0.1*aspect;
599 if(doit) glRasterPos2f(x, y);
605 /* ************** generic embossed rect, for window sliders etc ************* */
607 void uiEmboss(float x1, float y1, float x2, float y2, int sel)
611 if(sel) glColor3ub(200,200,200);
612 else glColor3ub(50,50,50);
613 fdrawline(x1, y1, x2, y1);
616 fdrawline(x2, y1, x2, y2);
619 if(sel) glColor3ub(50,50,50);
620 else glColor3ub(200,200,200);
621 fdrawline(x1, y2, x2, y2);
624 fdrawline(x1, y1, x1, y2);
628 /* ************** GENERIC ICON DRAW, NO THEME HERE ************* */
630 /* icons have been standardized... and this call draws in untransformed coordinates */
631 #define ICON_HEIGHT 16.0f
633 static void ui_draw_icon(uiBut *but, BIFIconID icon, int blend)
635 float xs=0, ys=0, aspect, height;
637 /* this icon doesn't need draw... */
638 if(icon==ICON_BLANK1) return;
640 /* we need aspect from block, for menus... these buttons are scaled in uiPositionBlock() */
641 aspect= but->block->aspect;
642 if(aspect != but->aspect) {
643 /* prevent scaling up icon in pupmenu */
650 height= ICON_HEIGHT/aspect;
655 if(but->flag & UI_ICON_LEFT) {
656 if (but->type==BUT_TOGDUAL) {
657 if (but->drawstr[0]) {
660 xs= (but->x1+but->x2- height)/2.0;
663 else if (but->block->flag & UI_BLOCK_LOOP) {
666 else if ((but->type==ICONROW) || (but->type==ICONTEXTROW)) {
672 ys= (but->y1+but->y2- height)/2.0;
674 if(but->flag & UI_ICON_RIGHT) {
676 ys= (but->y1+but->y2- height)/2.0;
678 if (!((but->flag & UI_ICON_RIGHT) || (but->flag & UI_ICON_LEFT))) {
679 xs= (but->x1+but->x2- height)/2.0;
680 ys= (but->y1+but->y2- height)/2.0;
685 /* calculate blend color */
686 if ELEM3(but->type, TOG, ROW, TOGN) {
687 if(but->flag & UI_SELECT);
688 else if(but->flag & UI_ACTIVE);
691 if (but->flag & UI_BUT_DISABLED) blend = -100;
693 UI_icon_draw_aspect_blended(xs, ys, icon, aspect, blend);
699 /* ************** DEFAULT THEME, SHADED BUTTONS ************* */
702 #define M_WHITE UI_ThemeColorShade(colorid, 80)
704 #define M_ACT_LIGHT UI_ThemeColorShade(colorid, 55)
705 #define M_LIGHT UI_ThemeColorShade(colorid, 45)
706 #define M_HILITE UI_ThemeColorShade(colorid, 25)
707 #define M_LMEDIUM UI_ThemeColorShade(colorid, 10)
708 #define M_MEDIUM UI_ThemeColor(colorid)
709 #define M_LGREY UI_ThemeColorShade(colorid, -20)
710 #define M_GREY UI_ThemeColorShade(colorid, -45)
711 #define M_DARK UI_ThemeColorShade(colorid, -80)
713 #define M_NUMTEXT UI_ThemeColorShade(colorid, 25)
714 #define M_NUMTEXT_ACT_LIGHT UI_ThemeColorShade(colorid, 35)
716 #define MM_WHITE UI_ThemeColorShade(TH_BUT_NEUTRAL, 120)
718 /* Used for the subtle sunken effect around buttons.
719 * One option is to hardcode to white, with alpha, however it causes a
720 * weird 'building up' efect, so it's commented out for now.
723 #define MM_WHITE_OP UI_ThemeColorShadeAlpha(TH_BACK, 55, -100)
724 #define MM_WHITE_TR UI_ThemeColorShadeAlpha(TH_BACK, 55, -255)
726 #define MM_LIGHT UI_ThemeColorShade(TH_BUT_OUTLINE, 45)
727 #define MM_MEDIUM UI_ThemeColor(TH_BUT_OUTLINE)
728 #define MM_GREY UI_ThemeColorShade(TH_BUT_OUTLINE, -45)
729 #define MM_DARK UI_ThemeColorShade(TH_BUT_OUTLINE, -80)
731 /* base shaded button */
732 static void shaded_button(float x1, float y1, float x2, float y2, float asp, int colorid, int flag, int mid)
734 /* 'mid' arg determines whether the button is in the middle of
735 * an alignment group or not. 0 = not middle, 1 = is in the middle.
736 * Done to allow cleaner drawing
739 /* *** SHADED BUTTON BASE *** */
740 glShadeModel(GL_SMOOTH);
743 if(flag & UI_SELECT) {
744 if(flag & UI_ACTIVE) M_MEDIUM;
747 if(flag & UI_ACTIVE) M_LIGHT;
754 if(flag & UI_SELECT) {
755 if(flag & UI_ACTIVE) M_LGREY;
758 if(flag & UI_ACTIVE) M_ACT_LIGHT;
762 glVertex2f(x2,(y2-(y2-y1)/3));
763 glVertex2f(x1,(y2-(y2-y1)/3));
767 glShadeModel(GL_FLAT);
770 if(flag & UI_SELECT) {
771 if(flag & UI_ACTIVE) M_LGREY;
774 if(flag & UI_ACTIVE) M_ACT_LIGHT;
778 glVertex2f(x1,(y2-(y2-y1)/3));
779 glVertex2f(x2,(y2-(y2-y1)/3));
784 /* *** END SHADED BUTTON BASE *** */
786 /* *** INNER OUTLINE *** */
788 if(!(flag & UI_SELECT)) {
789 glShadeModel(GL_SMOOTH);
792 glVertex2f(x1+1,y1+2);
799 if(!(flag & UI_SELECT)) {
800 glShadeModel(GL_SMOOTH);
803 glVertex2f(x2-1,y1+2);
809 glShadeModel(GL_FLAT);
812 if(flag & UI_SELECT) {
813 if(flag & UI_ACTIVE) M_LGREY;
816 if(flag & UI_ACTIVE) M_WHITE;
820 fdrawline(x1, (y2-1), x2, (y2-1));
823 if(flag & UI_SELECT) {
824 if(flag & UI_ACTIVE) M_MEDIUM;
827 if(flag & UI_ACTIVE) M_LMEDIUM;
830 fdrawline(x1, (y1+1), x2, (y1+1));
831 /* *** END INNER OUTLINE *** */
833 /* *** OUTER OUTLINE *** */
835 // we draw full outline, its not AA, and it works better button mouse-over hilite
839 fdrawline(x1, y1, x1, y2);
840 fdrawline(x2, y1, x2, y2);
843 fdrawline(x1, y2, x2, y2);
844 fdrawline(x1, y1, x2, y1);
847 gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, 1.5);
849 /* END OUTER OUTLINE */
852 /* base flat button */
853 static void flat_button(float x1, float y1, float x2, float y2, float asp, int colorid, int flag, int mid)
855 /* 'mid' arg determines whether the button is in the middle of
856 * an alignment group or not. 0 = not middle, 1 = is in the middle.
857 * Done to allow cleaner drawing
860 /* *** FLAT TEXT/NUM FIELD *** */
861 glShadeModel(GL_FLAT);
862 if(flag & UI_SELECT) {
863 if(flag & UI_ACTIVE) M_LGREY;
867 if(flag & UI_ACTIVE) M_NUMTEXT_ACT_LIGHT;
871 glRectf(x1, y1, x2, y2);
872 /* *** END FLAT TEXT/NUM FIELD *** */
874 /* *** OUTER OUTLINE *** */
876 // we draw full outline, its not AA, and it works better button mouse-over hilite
880 fdrawline(x1, y1, x1, y2);
881 fdrawline(x2, y1, x2, y2);
884 fdrawline(x1, y2, x2, y2);
885 fdrawline(x1, y1, x2, y1);
888 gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, 1.5);
890 /* END OUTER OUTLINE */
893 /* shaded round button */
894 static void round_button_shaded(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag, int rad)
896 int alpha_offs= (flag & UI_BUT_DISABLED)?UI_DISABLED_ALPHA_OFFS:0;
900 glColor4f(1.0f, 1.0f, 1.0f, 0.08f);
901 uiRoundRectFakeAA(x1+1, y1-1, x2, y2-1, rad, asp);
904 if (flag & UI_SELECT) {
906 if(flag & UI_ACTIVE) UI_ThemeColorShade(colorid, -40);
907 else UI_ThemeColorShade(colorid, -30);
910 if(flag & UI_ACTIVE) UI_ThemeColorShade(colorid, +30);
911 else UI_ThemeColorShade(colorid, +20);
913 /* end colour shading */
916 /* the shaded base */
917 gl_round_box_shade(GL_POLYGON, x1, y1, x2, y2, rad, shadefac, -shadefac);
920 UI_ThemeColorBlendShadeAlpha(TH_BUT_OUTLINE, TH_BACK, 0.1, -40, alpha_offs);
922 uiRoundRectFakeAA(x1, y1, x2, y2, rad, asp);
926 /* base round flat button */
927 static void round_button_flat(int colorid, float asp, float x1, float y1, float x2, float y2, int flag, float rad)
929 int alpha_offs= (flag & UI_BUT_DISABLED)?UI_DISABLED_ALPHA_OFFS:0;
932 glColor4f(1.0f, 1.0f, 1.0f, 0.08f);
933 uiRoundRectFakeAA(x1+1, y1-1, x2, y2-1, rad, asp);
936 if(flag & UI_SELECT) {
937 if (flag & UI_ACTIVE) UI_ThemeColorShade(colorid, -30);
938 else UI_ThemeColorShade(colorid, -45);
941 if(flag & UI_ACTIVE) UI_ThemeColorShade(colorid, 35);
942 else UI_ThemeColorShade(colorid, 25);
946 gl_round_box(GL_POLYGON, x1, y1, x2, y2, rad);
949 UI_ThemeColorBlendShadeAlpha(TH_BUT_OUTLINE, TH_BACK, 0.1, -30, alpha_offs);
950 uiRoundRectFakeAA(x1, y1, x2, y2, rad, asp);
953 static void ui_checkmark_box(int colorid, float x1, float y1, float x2, float y2)
956 UI_ThemeColorShade(colorid, -5);
957 gl_round_box_shade(GL_POLYGON, x1+4, (y1+(y2-y1)/2)-5, x1+14, (y1+(y2-y1)/2)+4, 2, -0.04, 0.03);
959 UI_ThemeColorShade(colorid, -30);
960 gl_round_box(GL_LINE_LOOP, x1+4, (y1+(y2-y1)/2)-5, x1+14, (y1+(y2-y1)/2)+4, 2);
963 static void ui_checkmark(float x1, float y1, float x2, float y2)
965 glEnable( GL_LINE_SMOOTH );
966 glEnable( GL_BLEND );
967 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
970 glBegin( GL_LINE_STRIP );
971 glVertex2f(x1+5, (y1+(y2-y1)/2)-1);
972 glVertex2f(x1+8, (y1+(y2-y1)/2)-4);
973 glVertex2f(x1+13, (y1+(y2-y1)/2)+5);
977 glDisable( GL_BLEND );
978 glDisable( GL_LINE_SMOOTH );
981 static void ui_draw_toggle_checkbox(int flag, int type, int colorid, float x1, float y1, float x2, float y2)
983 if (!(flag & UI_HAS_ICON)) {
984 /* check to see that there's room for the check mark
985 * draw a check mark, or if it's a TOG3, draw a + or - */
987 ui_checkmark_box(colorid, x1, y1, x2, y2);
989 /* TOG3 is handled with ui_tog3_invert()
990 * remember to update checkmark drawing there too*/
991 if((flag & UI_SELECT) && (type != TOG3)) {
992 UI_ThemeColorShade(colorid, -140);
994 ui_checkmark(x1, y1, x2, y2);
996 /* draw a dot: alternate, for layers etc. */
997 } else if(flag & UI_SELECT) {
999 UI_ThemeColorShade(colorid, -60);
1002 glTranslatef((x1+(x2-x1)/2), (y1+(y2-y1)/2), 0.0);
1005 glutil_draw_filled_arc(0.0, M_PI*2.0, 2, 16);
1007 glEnable( GL_LINE_SMOOTH );
1008 glEnable( GL_BLEND );
1009 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
1011 /* smooth outline */
1012 glutil_draw_lined_arc(0.0, M_PI*2.0, 2, 16);
1014 glDisable( GL_BLEND );
1015 glDisable( GL_LINE_SMOOTH );
1023 /* small side double arrow for iconrow */
1024 static void ui_iconrow_arrows(float x1, float y1, float x2, float y2)
1026 glEnable( GL_POLYGON_SMOOTH );
1027 glEnable( GL_BLEND );
1029 glShadeModel(GL_FLAT);
1030 glBegin(GL_TRIANGLES);
1031 glVertex2f((short)x2-2,(short)(y2-(y2-y1)/2)+1);
1032 glVertex2f((short)x2-6,(short)(y2-(y2-y1)/2)+1);
1033 glVertex2f((short)x2-4,(short)(y2-(y2-y1)/2)+4);
1036 glBegin(GL_TRIANGLES);
1037 glVertex2f((short)x2-2,(short)(y2-(y2-y1)/2) -1);
1038 glVertex2f((short)x2-6,(short)(y2-(y2-y1)/2) -1);
1039 glVertex2f((short)x2-4,(short)(y2-(y2-y1)/2) -4);
1042 glDisable( GL_BLEND );
1043 glDisable( GL_POLYGON_SMOOTH );
1046 /* side double arrow for menu */
1047 static void ui_menu_arrows(float x1, float y1, float x2, float y2, float asp)
1049 /* 'point' first, then two base vertices */
1050 uiTriangleFakeAA(x2-9, (y2-(y2-y1)/2)+6,
1051 x2-6, (y2-(y2-y1)/2)+2,
1052 x2-12, (y2-(y2-y1)/2)+2, asp);
1054 uiTriangleFakeAA(x2-9, (y2-(y2-y1)/2)-6,
1055 x2-6, (y2-(y2-y1)/2)-2,
1056 x2-12, (y2-(y2-y1)/2)-2, asp);
1059 /* left/right arrows for number fields */
1060 static void ui_num_arrows(float x1, float y1, float x2, float y2, float asp)
1062 if( x2-x1 > 25) { // 25 is a bit arbitrary, but small buttons cant have arrows
1064 /* 'point' first, then two base vertices */
1065 uiTriangleFakeAA(x1+4, y2-(y2-y1)/2,
1066 x1+9, y2-(y2-y1)/2+3,
1067 x1+9, y2-(y2-y1)/2-3, asp);
1069 uiTriangleFakeAA(x2-4, y2-(y2-y1)/2,
1070 x2-9, y2-(y2-y1)/2+3,
1071 x2-9, y2-(y2-y1)/2-3, asp);
1076 /* changing black/white for TOG3 buts */
1077 static void ui_tog3_invert(float x1, float y1, float x2, float y2, int seltype)
1081 UI_ThemeColorShade(TH_BUT_SETTING, -120);
1083 glEnable( GL_LINE_SMOOTH );
1084 glEnable( GL_BLEND );
1085 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
1088 fdrawline(x1+10, (y1+(y2-y1)/2+4), x1+10, (y1+(y2-y1)/2)-4);
1089 fdrawline(x1+6, (y1+(y2-y1)/2), x1+14, (y1+(y2-y1)/2));
1092 glDisable( GL_BLEND );
1093 glDisable( GL_LINE_SMOOTH );
1096 UI_ThemeColorShade(TH_BUT_SETTING, -120);
1098 glEnable( GL_LINE_SMOOTH );
1099 glEnable( GL_BLEND );
1100 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
1103 fdrawline(x1+6, (y1+(y2-y1)/2), x1+14, (y1+(y2-y1)/2));
1106 glDisable( GL_BLEND );
1107 glDisable( GL_LINE_SMOOTH );
1112 /* roundshaded button/popup menu/iconrow drawing code */
1113 static void ui_roundshaded_button(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1116 int align= (flag & UI_BUT_ALIGN);
1117 int alpha_offs= (flag & UI_BUT_DISABLED)?UI_DISABLED_ALPHA_OFFS:0;
1119 /* rounded corners */
1120 if (ELEM4(type, MENU, ROW, ICONROW, ICONTEXTROW)) maxrad = 5.0;
1124 if (rad>(x2-x1)/2) rad = (x2-x1)/2;
1125 if (rad > maxrad) rad = maxrad;
1127 /* end rounded corners */
1132 case UI_BUT_ALIGN_TOP:
1135 case UI_BUT_ALIGN_DOWN:
1138 case UI_BUT_ALIGN_LEFT:
1141 case UI_BUT_ALIGN_RIGHT:
1145 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT:
1148 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT:
1151 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_RIGHT:
1154 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_LEFT:
1169 /* draw the base button */
1170 round_button_shaded(type, colorid, asp, x1, y1, x2, y2, flag, rad);
1172 /* *** EXTRA DRAWING FOR SPECIFIC CONTROL TYPES *** */
1176 /* iconrow double arrow */
1177 if(flag & UI_SELECT) {
1178 UI_ThemeColorShadeAlpha(colorid, -80, alpha_offs);
1180 UI_ThemeColorShadeAlpha(colorid, -45, alpha_offs);
1182 ui_iconrow_arrows(x1, y1, x2, y2);
1183 /* end iconrow double arrow */
1186 /* menu double arrow */
1187 if(flag & UI_SELECT) {
1188 UI_ThemeColorShadeAlpha(colorid, -110, alpha_offs);
1190 UI_ThemeColorShadeAlpha(colorid, -80, alpha_offs);
1192 ui_menu_arrows(x1, y1, x2, y2, asp);
1193 /* end menu double arrow */
1198 static void ui_roundshaded_flat(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1201 int align= (flag & UI_BUT_ALIGN);
1202 int alpha_offs= (flag & UI_BUT_DISABLED)?UI_DISABLED_ALPHA_OFFS:0;
1204 /* rounded corners */
1205 if (type == TEX) maxrad = 5.0;
1209 if (rad>(x2-x1)/2) rad = (x2-x1)/2;
1211 if (rad > maxrad) rad = maxrad;
1213 /* end rounded corners */
1218 case UI_BUT_ALIGN_TOP:
1221 case UI_BUT_ALIGN_DOWN:
1224 case UI_BUT_ALIGN_LEFT:
1227 case UI_BUT_ALIGN_RIGHT:
1231 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT:
1234 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT:
1237 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_RIGHT:
1240 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_LEFT:
1254 /* draw the base button */
1255 round_button_flat(colorid, asp, x1, y1, x2, y2, flag, rad);
1257 /* *** EXTRA DRAWING FOR SPECIFIC CONTROL TYPES *** */
1262 ui_draw_toggle_checkbox(flag, type, colorid, x1, y1, x2, y2);
1266 if(flag & UI_SELECT) {
1267 if(flag & UI_ACTIVE) UI_ThemeColorShadeAlpha(colorid, -70, alpha_offs);
1268 else UI_ThemeColorShadeAlpha(colorid, -70, alpha_offs);
1270 if(flag & UI_ACTIVE) UI_ThemeColorShadeAlpha(colorid, -40, alpha_offs);
1271 else UI_ThemeColorShadeAlpha(colorid, -20, alpha_offs);
1274 ui_num_arrows(x1, y1, x2, y2, asp);
1275 /* end side arrows */
1280 /* roundshaded theme callback */
1281 static void ui_draw_roundshaded(int type, int colorid, float aspect, float x1, float y1, float x2, float y2, int flag)
1294 ui_roundshaded_flat(type, colorid, aspect, x1, y1, x2, y2, flag);
1300 ui_roundshaded_button(type, colorid, aspect, x1, y1, x2, y2, flag);
1305 /* button/popup menu/iconrow drawing code */
1306 static void ui_default_button(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1308 int align= (flag & UI_BUT_ALIGN);
1309 int alpha_offs= (flag & UI_BUT_DISABLED)?UI_DISABLED_ALPHA_OFFS:0;
1313 /* *** BOTTOM OUTER SUNKEN EFFECT *** */
1314 if (!((align == UI_BUT_ALIGN_DOWN) ||
1315 (align == (UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT)) ||
1316 (align == (UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT)))) {
1319 fdrawline(x1, y1-1, x2, y1-1);
1320 glDisable(GL_BLEND);
1322 /* *** END BOTTOM OUTER SUNKEN EFFECT *** */
1325 case UI_BUT_ALIGN_TOP:
1328 /* last arg in shaded_button() determines whether the button is in the middle of
1329 * an alignment group or not. 0 = not middle, 1 = is in the middle.
1330 * Done to allow cleaner drawing
1333 shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1335 case UI_BUT_ALIGN_DOWN:
1337 shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1339 case UI_BUT_ALIGN_LEFT:
1341 /* RIGHT OUTER SUNKEN EFFECT */
1343 glShadeModel(GL_SMOOTH);
1346 glVertex2f(x2+1,y1);
1348 glVertex2f(x2+1,y2);
1350 glDisable(GL_BLEND);
1353 shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1355 case UI_BUT_ALIGN_RIGHT:
1357 /* LEFT OUTER SUNKEN EFFECT */
1359 glShadeModel(GL_SMOOTH);
1362 glVertex2f(x1-1,y1);
1364 glVertex2f(x1-1,y2);
1366 glDisable(GL_BLEND);
1369 shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1372 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT:
1374 shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1376 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT:
1378 shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1380 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_RIGHT:
1382 /* LEFT OUTER SUNKEN EFFECT */
1384 glShadeModel(GL_SMOOTH);
1387 glVertex2f(x1-1,y1);
1389 glVertex2f(x1-1,y2);
1391 glDisable(GL_BLEND);
1394 shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1396 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_LEFT:
1398 /* RIGHT OUTER SUNKEN EFFECT */
1400 glShadeModel(GL_SMOOTH);
1403 glVertex2f(x2+1,y1);
1405 glVertex2f(x2+1,y2);
1407 glDisable(GL_BLEND);
1410 shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1414 shaded_button(x1, y1, x2, y2, asp, colorid, flag, 1);
1420 glShadeModel(GL_SMOOTH);
1422 /* BOTTOM OUTER SUNKEN EFFECT */
1424 fdrawline(x1, y1-1, x2, y1-1);
1426 /* LEFT OUTER SUNKEN EFFECT */
1429 glVertex2f(x1-1,y1);
1431 glVertex2f(x1-1,y2);
1434 /* RIGHT OUTER SUNKEN EFFECT */
1437 glVertex2f(x2+1,y1);
1439 glVertex2f(x2+1,y2);
1442 glDisable(GL_BLEND);
1445 shaded_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1448 /* *** EXTRA DRAWING FOR SPECIFIC CONTROL TYPES *** */
1455 glColor4ub(0, 0, 0, 30);
1456 glRectf(x2-9, y1, x2, y2);
1458 glDisable(GL_BLEND);
1459 /* END DARKENED AREA */
1461 /* ICONROW DOUBLE-ARROW */
1462 UI_ThemeColorShadeAlpha(colorid, -80, alpha_offs);
1463 ui_iconrow_arrows(x1, y1, x2, y2);
1464 /* END ICONROW DOUBLE-ARROW */
1470 glColor4ub(0, 0, 0, 30);
1471 glRectf(x2-18, y1, x2, y2);
1473 glDisable(GL_BLEND);
1474 /* END DARKENED AREA */
1476 /* MENU DOUBLE-ARROW */
1477 UI_ThemeColorShadeAlpha(colorid, -80, alpha_offs);
1478 ui_menu_arrows(x1, y1, x2, y2, asp);
1479 /* MENU DOUBLE-ARROW */
1484 /* number/text field drawing code */
1485 static void ui_default_flat(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1487 int align= (flag & UI_BUT_ALIGN);
1488 int alpha_offs= (flag & UI_BUT_DISABLED)?UI_DISABLED_ALPHA_OFFS:0;
1492 /* *** BOTTOM OUTER SUNKEN EFFECT *** */
1493 if (!((align == UI_BUT_ALIGN_DOWN) ||
1494 (align == (UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT)) ||
1495 (align == (UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT)))) {
1498 fdrawline(x1, y1-1, x2, y1-1);
1499 glDisable(GL_BLEND);
1501 /* *** END BOTTOM OUTER SUNKEN EFFECT *** */
1504 case UI_BUT_ALIGN_TOP:
1507 /* last arg in shaded_button() determines whether the button is in the middle of
1508 * an alignment group or not. 0 = not middle, 1 = is in the middle.
1509 * Done to allow cleaner drawing
1512 flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1514 case UI_BUT_ALIGN_DOWN:
1516 flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1518 case UI_BUT_ALIGN_LEFT:
1520 /* RIGHT OUTER SUNKEN EFFECT */
1522 glShadeModel(GL_SMOOTH);
1525 glVertex2f(x2+1,y1);
1527 glVertex2f(x2+1,y2);
1529 glDisable(GL_BLEND);
1532 flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1534 case UI_BUT_ALIGN_RIGHT:
1536 /* LEFT OUTER SUNKEN EFFECT */
1538 glShadeModel(GL_SMOOTH);
1541 glVertex2f(x1-1,y1);
1543 glVertex2f(x1-1,y2);
1545 glDisable(GL_BLEND);
1548 flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1551 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT:
1553 flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1555 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT:
1557 flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1559 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_RIGHT:
1561 /* LEFT OUTER SUNKEN EFFECT */
1563 glShadeModel(GL_SMOOTH);
1566 glVertex2f(x1-1,y1);
1568 glVertex2f(x1-1,y2);
1570 glDisable(GL_BLEND);
1573 flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1575 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_LEFT:
1577 /* RIGHT OUTER SUNKEN EFFECT */
1579 glShadeModel(GL_SMOOTH);
1582 glVertex2f(x2+1,y1);
1584 glVertex2f(x2+1,y2);
1586 glDisable(GL_BLEND);
1589 flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1593 flat_button(x1, y1, x2, y2, asp, colorid, flag, 1);
1600 glShadeModel(GL_SMOOTH);
1602 /* BOTTOM OUTER SUNKEN EFFECT */
1604 fdrawline(x1, y1-1, x2, y1-1);
1606 /* LEFT OUTER SUNKEN EFFECT */
1609 glVertex2f(x1-1,y1);
1611 glVertex2f(x1-1,y2);
1614 /* RIGHT OUTER SUNKEN EFFECT */
1617 glVertex2f(x2+1,y1);
1619 glVertex2f(x2+1,y2);
1622 glDisable(GL_BLEND);
1625 flat_button(x1, y1, x2, y2, asp, colorid, flag, 0);
1628 /* *** EXTRA DRAWING FOR SPECIFIC CONTROL TYPES *** */
1634 if(flag & UI_SELECT) {
1635 if(flag & UI_ACTIVE) UI_ThemeColorShadeAlpha(colorid, -80, alpha_offs);
1636 else UI_ThemeColorShadeAlpha(colorid, -80, alpha_offs);
1638 if(flag & UI_ACTIVE) UI_ThemeColorShadeAlpha(colorid, -45, alpha_offs);
1639 else UI_ThemeColorShadeAlpha(colorid, -20, alpha_offs);
1642 ui_num_arrows(x1, y1, x2, y2, asp);
1643 /* END SIDE ARROWS */
1647 /* default theme callback */
1648 static void ui_draw_default(int type, int colorid, float aspect, float x1, float y1, float x2, float y2, int flag)
1656 ui_default_flat(type, colorid, aspect, x1, y1, x2, y2, flag);
1662 ui_default_button(type, colorid, aspect, x1, y1, x2, y2, flag);
1668 /* *************** OLDSKOOL THEME ***************** */
1670 static void ui_draw_outlineX(float x1, float y1, float x2, float y2, float asp1)
1674 glBegin(GL_LINE_LOOP);
1675 vec[0]= x1+asp1; vec[1]= y1-asp1;
1679 vec[0]= x2+asp1; vec[1]= y1+asp1;
1683 vec[0]= x2-asp1; vec[1]= y2+asp1;
1687 vec[0]= x1-asp1; vec[1]= y2-asp1;
1696 static void ui_draw_oldskool(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1698 int alpha_offs= (flag & UI_BUT_DISABLED)?UI_DISABLED_ALPHA_OFFS:0;
1700 if(flag & UI_SELECT) {
1701 if(flag & UI_ACTIVE) UI_ThemeColorShade(colorid, -40);
1702 else UI_ThemeColorShade(colorid, -30);
1705 if(flag & UI_ACTIVE) UI_ThemeColorShade(colorid, +30);
1706 else UI_ThemeColorShade(colorid, +20);
1709 glRectf(x1+1, y1+1, x2-1, y2-1);
1717 if(flag & UI_SELECT) UI_ThemeColorShade(colorid, 0);
1718 else UI_ThemeColorShade(colorid, -30);
1719 fdrawline(x1, y1, x2, y1);
1722 fdrawline(x2, y1, x2, y2);
1725 if(flag & UI_SELECT) UI_ThemeColorShade(colorid, -30);
1726 else UI_ThemeColorShade(colorid, 0);
1727 fdrawline(x1, y2, x2, y2);
1730 fdrawline(x1, y1, x1, y2);
1734 ui_draw_outlineX(x1, y1, x2, y2, asp);
1737 /* special type decorations */
1741 if(flag & UI_SELECT) UI_ThemeColorShadeAlpha(colorid, -60, alpha_offs);
1742 else UI_ThemeColorShadeAlpha(colorid, -30, alpha_offs);
1743 ui_num_arrows(x1, y1, x2, y2, asp);
1748 if(flag & UI_ACTIVE) UI_ThemeColorShadeAlpha(colorid, 0, alpha_offs);
1749 else UI_ThemeColorShadeAlpha(colorid, -10, alpha_offs);
1750 glRectf(x2-9, y1+asp, x2-asp, y2-asp);
1752 UI_ThemeColorShadeAlpha(colorid, -50, alpha_offs);
1753 ui_iconrow_arrows(x1, y1, x2, y2);
1757 if(flag & UI_ACTIVE) UI_ThemeColorShadeAlpha(colorid, 0, alpha_offs);
1758 else UI_ThemeColorShadeAlpha(colorid, -10, alpha_offs);
1759 glRectf(x2-17, y1+asp, x2-asp, y2-asp);
1761 UI_ThemeColorShadeAlpha(colorid, -50, alpha_offs);
1762 ui_menu_arrows(x1, y1, x2, y2, asp);
1768 static void ui_draw_round(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1770 float rad, maxrad=7.0;
1771 int align= (flag & UI_BUT_ALIGN), curshade;
1772 int alpha_offs= (flag & UI_BUT_DISABLED)?UI_DISABLED_ALPHA_OFFS:0;
1774 /* rounded corners */
1776 if (rad>(x2-x1)/2) rad = (x2-x1)/2;
1778 if (rad > maxrad) rad = maxrad;
1780 /* end rounded corners */
1783 if(flag & UI_SELECT) {
1784 if(flag & UI_ACTIVE) curshade= -40;
1788 if(flag & UI_ACTIVE) curshade= 30;
1792 UI_ThemeColorShade(colorid, curshade);
1797 case UI_BUT_ALIGN_TOP:
1800 case UI_BUT_ALIGN_DOWN:
1803 case UI_BUT_ALIGN_LEFT:
1806 case UI_BUT_ALIGN_RIGHT:
1810 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT:
1813 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT:
1816 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_RIGHT:
1819 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_LEFT:
1833 /* draw the base button */
1834 round_button_flat(colorid, asp, x1, y1, x2, y2, flag, rad);
1836 /* special type decorations */
1841 ui_draw_toggle_checkbox(flag, type, colorid, x1, y1, x2, y2);
1845 UI_ThemeColorShadeAlpha(colorid, curshade-60, alpha_offs);
1846 ui_num_arrows(x1, y1, x2, y2, asp);
1851 UI_ThemeColorShadeAlpha(colorid, curshade-60, alpha_offs);
1852 ui_iconrow_arrows(x1, y1, x2, y2);
1857 UI_ThemeColorShadeAlpha(colorid, curshade-60, alpha_offs);
1858 ui_menu_arrows(x1, y1, x2, y2, asp);
1863 /* *************** MINIMAL THEME ***************** */
1865 // theme can define an embosfunc and sliderfunc, text+icon drawing is standard, no theme.
1869 /* super minimal button as used in logic menu */
1870 static void ui_draw_minimal(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
1872 int alpha_offs= (flag & UI_BUT_DISABLED)?UI_DISABLED_ALPHA_OFFS:0;
1874 /* too much space between buttons */
1876 if (type==TEX || type==IDPOIN) {
1882 /* Less space between buttons looks nicer */
1888 if(flag & UI_SELECT) {
1889 if(flag & UI_ACTIVE) UI_ThemeColorShade(colorid, -40);
1890 else UI_ThemeColorShade(colorid, -30);
1893 if(flag & UI_ACTIVE) UI_ThemeColorShade(colorid, +20);
1894 else UI_ThemeColorShade(colorid, +10);
1897 glRectf(x1, y1, x2, y2);
1899 if (type==TEX || type==IDPOIN) {
1900 UI_ThemeColorShade(colorid, -60);
1903 fdrawline(x1, y2, x2, y2);
1905 fdrawline(x1, y1, x1, y2);
1908 /* text underline, some */
1909 UI_ThemeColorShade(colorid, +50);
1910 glEnable(GL_LINE_STIPPLE);
1911 glLineStipple(1, 0x8888);
1912 fdrawline(x1+(asp*2), y1+(asp*3), x2-(asp*2), y1+(asp*3));
1913 glDisable(GL_LINE_STIPPLE);
1916 UI_ThemeColorShade(colorid, +60);
1918 fdrawline(x1, y1, x2, y1);
1920 fdrawline(x2, y1, x2, y2);
1923 if(flag & UI_SELECT) {
1924 UI_ThemeColorShade(colorid, -60);
1927 fdrawline(x1, y2, x2, y2);
1929 fdrawline(x1, y1, x1, y2);
1930 UI_ThemeColorShade(colorid, +40);
1933 fdrawline(x1, y1, x2, y1);
1935 fdrawline(x2, y1, x2, y2);
1938 UI_ThemeColorShade(colorid, +40);
1941 fdrawline(x1, y2, x2, y2);
1943 fdrawline(x1, y1, x1, y2);
1945 UI_ThemeColorShade(colorid, -60);
1947 fdrawline(x1, y1, x2, y1);
1949 fdrawline(x2, y1, x2, y2);
1953 /* special type decorations */
1957 if(flag & UI_SELECT) UI_ThemeColorShadeAlpha(colorid, -60, alpha_offs);
1958 else UI_ThemeColorShadeAlpha(colorid, -30, alpha_offs);
1959 ui_num_arrows(x1, y1, x2, y2, asp);
1964 if(flag & UI_ACTIVE) UI_ThemeColorShadeAlpha(colorid, 0, alpha_offs);
1965 else UI_ThemeColorShadeAlpha(colorid, -10, alpha_offs);
1966 glRectf(x2-9, y1+asp, x2-asp, y2-asp);
1968 UI_ThemeColorShadeAlpha(colorid, -50, alpha_offs);
1969 ui_iconrow_arrows(x1, y1, x2, y2);
1974 if(flag & UI_ACTIVE) UI_ThemeColorShadeAlpha(colorid, 0, alpha_offs);
1975 else UI_ThemeColorShadeAlpha(colorid, -10, alpha_offs);
1976 glRectf(x2-17, y1+asp, x2-asp, y2-asp);
1978 UI_ThemeColorShadeAlpha(colorid, -50, alpha_offs);
1979 ui_menu_arrows(x1, y1, x2, y2, asp);
1987 /* fac is the slider handle position between x1 and x2 */
1988 static void ui_draw_slider(int colorid, float fac, float aspect, float x1, float y1, float x2, float y2, int flag)
1990 int alpha_offs= (flag & UI_BUT_DISABLED)?UI_DISABLED_ALPHA_OFFS:0;
1993 int origround, round = uiGetRoundBox();
1996 if (rad>(x2-x1)/2) rad = (x2-x1)/2;
1997 if (rad > maxrad) rad = maxrad;
1999 if(flag & UI_ACTIVE) UI_ThemeColorShade(colorid, -75);
2000 else UI_ThemeColorShade(colorid, -45);
2004 uiSetRoundBox(round);
2007 /* if slider end is in the left end cap */
2012 ofsy = (origround!=0) ? ((rad - fac) * 0.5) : 0.f; /* shrink in Y if rounded but */
2014 gl_round_box(GL_POLYGON, x1, y1+ofsy, x1+fac, y2-ofsy, start_rad);
2016 } else if ( (fac >= rad) && (x1+fac < x2 - rad) ) {
2017 /* if the slider is in the middle */
2019 gl_round_box(GL_POLYGON, x1, y1, x1+fac, y2, rad);
2021 } else if (x1+fac >= x2-rad) {
2022 /* if the slider is in the right end cap */
2026 /* draw the full slider area at 100% */
2027 uiSetRoundBox(origround);
2028 gl_round_box(GL_POLYGON, x1, y1, x2, y2, rad);
2030 /* don't draw anything else if the slider is completely full */
2031 if (x2 - (x1+fac) < 0.05f)
2034 /* tricky to trim off right end curve by drawing over it */
2035 extx = ((x1 + fac) - (x2 - rad)) * aspect; /* width of extension bit */
2036 end_rad = rad - extx - 1.0;
2037 ofsy = (origround!=0) ? (extx * 0.4) : 0.f; /* shrink in Y if rounded but */
2039 if (end_rad > 1.0) {
2041 if(flag & UI_SELECT) UI_ThemeColorShade(colorid, -20);
2042 else UI_ThemeColorShade(colorid, -0);
2046 uiSetRoundBox(round);
2047 gl_round_box(GL_POLYGON, x1+fac-1.0, y1+ofsy, x2-1.0, y2-ofsy, end_rad);
2050 /* trace over outline again, to cover up inaccuracies */
2051 UI_ThemeColorBlendShadeAlpha(TH_BUT_OUTLINE, TH_BACK, 0.1, -30, alpha_offs);
2052 uiSetRoundBox(origround);
2053 uiRoundRectFakeAA(x1, y1, x2, y2, rad, aspect);
2060 /* ************** STANDARD MENU DRAWING FUNCTION ************* */
2063 static void ui_shadowbox(float minx, float miny, float maxx, float maxy, float shadsize, unsigned char alpha)
2066 glShadeModel(GL_SMOOTH);
2069 glBegin(GL_POLYGON);
2070 glColor4ub(0, 0, 0, alpha);
2071 glVertex2f(maxx, miny);
2072 glVertex2f(maxx, maxy-0.3*shadsize);
2073 glColor4ub(0, 0, 0, 0);
2074 glVertex2f(maxx+shadsize, maxy-0.75*shadsize);
2075 glVertex2f(maxx+shadsize, miny);
2079 glBegin(GL_POLYGON);
2080 glColor4ub(0, 0, 0, alpha);
2081 glVertex2f(maxx, miny);
2082 glColor4ub(0, 0, 0, 0);
2083 glVertex2f(maxx+shadsize, miny);
2084 glVertex2f(maxx+0.7*shadsize, miny-0.7*shadsize);
2085 glVertex2f(maxx, miny-shadsize);
2089 glBegin(GL_POLYGON);
2090 glColor4ub(0, 0, 0, alpha);
2091 glVertex2f(minx+0.3*shadsize, miny);
2092 glVertex2f(maxx, miny);
2093 glColor4ub(0, 0, 0, 0);
2094 glVertex2f(maxx, miny-shadsize);
2095 glVertex2f(minx+0.5*shadsize, miny-shadsize);
2098 glDisable(GL_BLEND);
2099 glShadeModel(GL_FLAT);
2102 void uiDrawBoxShadow(unsigned char alpha, float minx, float miny, float maxx, float maxy)
2104 /* accumulated outline boxes to make shade not linear, is more pleasant */
2105 ui_shadowbox(minx, miny, maxx, maxy, 11.0, (20*alpha)>>8);
2106 ui_shadowbox(minx, miny, maxx, maxy, 7.0, (40*alpha)>>8);
2107 ui_shadowbox(minx, miny, maxx, maxy, 5.0, (80*alpha)>>8);
2111 // background for pulldowns, pullups, and other drawing temporal menus....
2112 // has to be made themable still (now only color)
2114 void uiDrawMenuBox(float minx, float miny, float maxx, float maxy, short flag, short direction)
2117 int rounded = ELEM(UI_GetThemeValue(TH_BUT_DRAWTYPE), TH_ROUNDED, TH_ROUNDSHADED);
2119 UI_GetThemeColor4ubv(TH_MENU_BACK, col);
2122 if (flag & UI_BLOCK_POPUP) {
2127 else if (direction == UI_DOWN) {
2130 } else if (direction == UI_TOP) {
2138 if( (flag & UI_BLOCK_NOSHADOW)==0) {
2139 /* accumulated outline boxes to make shade not linear, is more pleasant */
2140 ui_shadowbox(minx, miny, maxx, maxy, 11.0, (20*col[3])>>8);
2141 ui_shadowbox(minx, miny, maxx, maxy, 7.0, (40*col[3])>>8);
2142 ui_shadowbox(minx, miny, maxx, maxy, 5.0, (80*col[3])>>8);
2145 glColor4ubv((GLubyte *)col);
2148 gl_round_box(GL_POLYGON, minx, miny, maxx, maxy, 4.0);
2150 glRectf(minx, miny, maxx, maxy);
2152 glDisable(GL_BLEND);
2157 /* pulldown menu item */
2158 static void ui_draw_pulldown_item(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
2162 UI_GetThemeColor4ubv(TH_MENU_BACK, col);
2167 if((flag & UI_ACTIVE) && type!=LABEL) {
2168 UI_ThemeColor4(TH_MENU_HILITE);
2169 glRectf(x1, y1, x2, y2);
2173 UI_ThemeColor4(colorid); // is set at TH_MENU_ITEM when pulldown opened.
2174 glRectf(x1, y1, x2, y2);
2177 glDisable(GL_BLEND);
2180 /* pulldown menu calling button */
2181 static void ui_draw_pulldown_round(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
2184 if(flag & UI_ACTIVE) {
2185 UI_ThemeColor(TH_MENU_HILITE);
2188 gl_round_box(GL_POLYGON, x1, y1+3, x2, y2-3, 7.0);
2190 glEnable( GL_LINE_SMOOTH );
2191 glEnable( GL_BLEND );
2192 gl_round_box(GL_LINE_LOOP, x1, y1+3, x2, y2-3, 7.0);
2193 glDisable( GL_LINE_SMOOTH );
2194 glDisable( GL_BLEND );
2197 UI_ThemeColor(colorid); // is set at TH_MENU_ITEM when pulldown opened.
2198 glRectf(x1-1, y1+2, x2+1, y2-2);
2203 /* ************** TEXT AND ICON DRAWING FUNCTIONS ************* */
2205 #define BUT_TEXT_NORMAL 0
2206 #define BUT_TEXT_SUNKEN 1
2208 static void ui_draw_text(uiBut *but, float x, float y, int sunken)
2210 int alpha_offs= (but->flag & UI_BUT_DISABLED)?UI_DISABLED_ALPHA_OFFS:0;
2213 float ypos = (sunken==BUT_TEXT_SUNKEN) ? (y-1) : y;
2216 if(but->type==LABEL && but->min!=0.0) {
2217 UI_ThemeColor(TH_BUT_TEXT_HI);
2219 else if(but->dt==UI_EMBOSSP) {
2220 if((but->flag & UI_ACTIVE) && but->type!=LABEL) { // LABEL = title in pulldowns
2221 UI_ThemeColorShadeAlpha(TH_MENU_TEXT_HI, 0, alpha_offs);
2223 UI_ThemeColorShadeAlpha(TH_MENU_TEXT, 0, alpha_offs);
2227 if(but->flag & UI_SELECT) {
2228 UI_ThemeColorShadeAlpha(TH_BUT_TEXT_HI, 0, alpha_offs);
2230 UI_ThemeColorShadeAlpha(TH_BUT_TEXT, 0, alpha_offs);
2234 if (sunken == BUT_TEXT_SUNKEN) {
2237 glGetFloatv(GL_CURRENT_COLOR, curcol); /* returns four components: r,g,b,a */
2239 /* only draw embossed text if the text color is darker than 0.5 mid-grey */
2240 if ((curcol[0] + curcol[1] + curcol[2]) * 0.3f < 0.5f)
2241 glColor4f(0.6f, 0.6f, 0.6f, 0.3f);
2246 ui_rasterpos_safe(x, ypos, but->aspect);
2247 if(but->type==IDPOIN) transopts= 0; // no translation, of course!
2248 else transopts= ui_translate_buttons();
2250 /* cut string in 2 parts */
2251 cpoin= strchr(but->drawstr, '|');
2252 if(cpoin) *cpoin= 0;
2254 #ifdef INTERNATIONAL
2255 if (but->type == FTPREVIEW)
2256 FTF_DrawNewFontString (but->drawstr+but->ofs, FTF_INPUT_UTF8);
2258 UI_DrawString(but->font, but->drawstr+but->ofs, transopts);
2260 UI_DrawString(but->font, but->drawstr+but->ofs, transopts);
2263 /* part text right aligned */
2265 len= UI_GetStringWidth(but->font, cpoin+1, ui_translate_buttons());
2266 ui_rasterpos_safe( but->x2 - len*but->aspect-3, ypos, but->aspect);
2267 UI_DrawString(but->font, cpoin+1, ui_translate_buttons());
2272 /* draws text and icons for buttons */
2273 static void ui_draw_text_icon(uiBut *but)
2277 short selsta_tmp, selend_tmp, selsta_draw, selwidth_draw;
2279 /* check for button text label */
2280 if (but->type == ICONTEXTROW) {
2281 ui_draw_icon(but, (BIFIconID) (but->icon+but->iconadd), 0);
2285 /* text button selection and cursor */
2286 if(but->editstr && but->pos != -1) {
2288 if ((but->selend - but->selsta) > 0) {
2289 /* text button selection */
2290 selsta_tmp = but->selsta + strlen(but->str);
2291 selend_tmp = but->selend + strlen(but->str);
2293 if(but->drawstr[0]!=0) {
2294 ch= but->drawstr[selsta_tmp];
2295 but->drawstr[selsta_tmp]= 0;
2297 selsta_draw = but->aspect*UI_GetStringWidth(but->font, but->drawstr+but->ofs, ui_translate_buttons()) + 3;
2299 but->drawstr[selsta_tmp]= ch;
2302 ch= but->drawstr[selend_tmp];
2303 but->drawstr[selend_tmp]= 0;
2305 selwidth_draw = but->aspect*UI_GetStringWidth(but->font, but->drawstr+but->ofs, ui_translate_buttons()) + 3;
2307 but->drawstr[selend_tmp]= ch;
2309 UI_ThemeColor(TH_BUT_TEXTFIELD_HI);
2310 glRects(but->x1+selsta_draw+1, but->y1+2, but->x1+selwidth_draw+1, but->y2-2);
2314 pos= but->pos+strlen(but->str);
2315 if(pos >= but->ofs) {
2316 if(but->drawstr[0]!=0) {
2317 ch= but->drawstr[pos];
2318 but->drawstr[pos]= 0;
2320 t= but->aspect*UI_GetStringWidth(but->font, but->drawstr+but->ofs, ui_translate_buttons()) + 3;
2322 but->drawstr[pos]= ch;
2326 glColor3ub(255,0,0);
2327 glRects(but->x1+t, but->y1+2, but->x1+t+2, but->y2-2);
2332 if(but->type==BUT_TOGDUAL) {
2334 if(but->pointype==SHO)
2335 dualset= BTST( *(((short *)but->poin)+1), but->bitnr);
2336 else if(but->pointype==INT)
2337 dualset= BTST( *(((int *)but->poin)+1), but->bitnr);
2339 ui_draw_icon(but, ICON_DOT, dualset?0:-100);
2342 if(but->drawstr[0]!=0) {
2345 /* If there's an icon too (made with uiDefIconTextBut) then draw the icon
2346 and offset the text label to accomodate it */
2348 if ( (but->flag & UI_HAS_ICON) && (but->flag & UI_ICON_LEFT) )
2350 ui_draw_icon(but, but->icon, 0);
2352 if(but->editstr || (but->flag & UI_TEXT_LEFT)) x= but->x1 + but->aspect*UI_icon_get_width(but->icon)+5.0;
2353 else x= (but->x1+but->x2-but->strwidth+1)/2.0;
2357 if(but->editstr || (but->flag & UI_TEXT_LEFT))
2359 else if ELEM3(but->type, TOG, TOGN, TOG3)
2360 x= but->x1+18.0; /* offset for checkmark */
2362 x= (but->x1+but->x2-but->strwidth+1)/2.0;
2365 /* tog3 button exception; draws with glColor! */
2366 if(but->type==TOG3 && (but->flag & UI_SELECT)) {
2368 if( but->pointype==CHA ) {
2369 if( BTST( *(but->poin+2), but->bitnr )) tog3= 1;
2371 else if( but->pointype ==SHO ) {
2372 short *sp= (short *)but->poin;
2373 if( BTST( sp[1], but->bitnr )) tog3= 1;
2376 ui_tog3_invert(but->x1,but->y1,but->x2,but->y2, tog3);
2377 if (tog3) glColor3ub(255, 255, 0);
2380 /* position and draw */
2381 y = (but->y1+but->y2- 9.0)/2.0;
2383 if (ELEM(but->type, LABEL, PULLDOWN) && !(but->flag & UI_ACTIVE))
2384 ui_draw_text(but, x, y, BUT_TEXT_SUNKEN);
2386 ui_draw_text(but, x, y, BUT_TEXT_NORMAL);
2389 /* if there's no text label, then check to see if there's an icon only and draw it */
2390 else if( but->flag & UI_HAS_ICON ) {
2391 ui_draw_icon(but, (BIFIconID) (but->icon+but->iconadd), 0);
2396 static void ui_draw_but_COL(uiBut *but)
2399 char colr, colg, colb;
2401 ui_get_but_vectorf(but, col);
2403 colr= floor(255.0*col[0]+0.5);
2404 colg= floor(255.0*col[1]+0.5);
2405 colb= floor(255.0*col[2]+0.5);
2407 /* exception... hrms, but can't simply use the emboss callback for this now. */
2408 /* this button type needs review, and nice integration with rest of API here */
2409 /* XXX 2.50 bad U global access */
2410 if(but->embossfunc == ui_draw_round) {
2411 char *cp= UI_ThemeGetColorPtr(U.themes.first, 0, TH_CUSTOM);
2412 cp[0]= colr; cp[1]= colg; cp[2]= colb;
2413 but->flag &= ~UI_SELECT;
2414 but->embossfunc(but->type, TH_CUSTOM, but->aspect, but->x1, but->y1, but->x2, but->y2, but->flag);
2419 glColor3ub(colr, colg, colb);
2420 glRectf((but->x1), (but->y1), (but->x2), (but->y2));
2421 glColor3ub(0, 0, 0);
2422 fdrawbox((but->x1), (but->y1), (but->x2), (but->y2));
2426 /* draws in resolution of 20x4 colors */
2427 static void ui_draw_but_HSVCUBE(uiBut *but)
2431 float dx, dy, sx1, sx2, sy, x, y;
2432 float col0[4][3]; // left half, rect bottom to top
2433 float col1[4][3]; // right half, rect bottom to top
2439 /* draw series of gouraud rects */
2440 glShadeModel(GL_SMOOTH);
2442 if(but->a1==0) { // H and V vary
2443 hsv_to_rgb(0.0, s, 0.0, &col1[0][0], &col1[0][1], &col1[0][2]);
2444 hsv_to_rgb(0.0, s, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]);
2445 hsv_to_rgb(0.0, s, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]);
2446 hsv_to_rgb(0.0, s, 1.0, &col1[3][0], &col1[3][1], &col1[3][2]);
2449 else if(but->a1==1) { // H and S vary
2450 hsv_to_rgb(0.0, 0.0, v, &col1[0][0], &col1[0][1], &col1[0][2]);
2451 hsv_to_rgb(0.0, 0.333, v, &col1[1][0], &col1[1][1], &col1[1][2]);
2452 hsv_to_rgb(0.0, 0.666, v, &col1[2][0], &col1[2][1], &col1[2][2]);
2453 hsv_to_rgb(0.0, 1.0, v, &col1[3][0], &col1[3][1], &col1[3][2]);
2456 else if(but->a1==2) { // S and V vary
2457 hsv_to_rgb(h, 0.0, 0.0, &col1[0][0], &col1[0][1], &col1[0][2]);
2458 hsv_to_rgb(h, 0.333, 0.0, &col1[1][0], &col1[1][1], &col1[1][2]);
2459 hsv_to_rgb(h, 0.666, 0.0, &col1[2][0], &col1[2][1], &col1[2][2]);
2460 hsv_to_rgb(h, 1.0, 0.0, &col1[3][0], &col1[3][1], &col1[3][2]);
2463 else { // only hue slider
2464 hsv_to_rgb(0.0, 1.0, 1.0, &col1[0][0], &col1[0][1], &col1[0][2]);
2465 VECCOPY(col1[1], col1[0]);
2466 VECCOPY(col1[2], col1[0]);
2467 VECCOPY(col1[3], col1[0]);
2471 for(dx=0.0; dx<1.0; dx+= 0.05) {
2473 VECCOPY(col0[0], col1[0]);
2474 VECCOPY(col0[1], col1[1]);
2475 VECCOPY(col0[2], col1[2]);
2476 VECCOPY(col0[3], col1[3]);
2479 if(but->a1==0) { // H and V vary
2480 hsv_to_rgb(dx, s, 0.0, &col1[0][0], &col1[0][1], &col1[0][2]);
2481 hsv_to_rgb(dx, s, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]);
2482 hsv_to_rgb(dx, s, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]);
2483 hsv_to_rgb(dx, s, 1.0, &col1[3][0], &col1[3][1], &col1[3][2]);
2485 else if(but->a1==1) { // H and S vary
2486 hsv_to_rgb(dx, 0.0, v, &col1[0][0], &col1[0][1], &col1[0][2]);
2487 hsv_to_rgb(dx, 0.333, v, &col1[1][0], &col1[1][1], &col1[1][2]);
2488 hsv_to_rgb(dx, 0.666, v, &col1[2][0], &col1[2][1], &col1[2][2]);
2489 hsv_to_rgb(dx, 1.0, v, &col1[3][0], &col1[3][1], &col1[3][2]);
2491 else if(but->a1==2) { // S and V vary
2492 hsv_to_rgb(h, 0.0, dx, &col1[0][0], &col1[0][1], &col1[0][2]);
2493 hsv_to_rgb(h, 0.333, dx, &col1[1][0], &col1[1][1], &col1[1][2]);
2494 hsv_to_rgb(h, 0.666, dx, &col1[2][0], &col1[2][1], &col1[2][2]);
2495 hsv_to_rgb(h, 1.0, dx, &col1[3][0], &col1[3][1], &col1[3][2]);
2498 hsv_to_rgb(dx, 1.0, 1.0, &col1[0][0], &col1[0][1], &col1[0][2]);
2499 VECCOPY(col1[1], col1[0]);
2500 VECCOPY(col1[2], col1[0]);
2501 VECCOPY(col1[3], col1[0]);
2505 sx1= but->x1 + dx*(but->x2-but->x1);
2506 sx2= but->x1 + (dx+0.05)*(but->x2-but->x1);
2508 dy= (but->y2-but->y1)/3.0;
2511 for(a=0; a<3; a++, sy+=dy) {
2512 glColor3fv(col0[a]);
2513 glVertex2f(sx1, sy);
2515 glColor3fv(col1[a]);
2516 glVertex2f(sx2, sy);
2518 glColor3fv(col1[a+1]);
2519 glVertex2f(sx2, sy+dy);
2521 glColor3fv(col0[a+1]);
2522 glVertex2f(sx1, sy+dy);
2527 glShadeModel(GL_FLAT);
2530 x= but->x1 + x*(but->x2-but->x1);
2531 y= but->y1 + y*(but->y2-but->y1);
2532 CLAMP(x, but->x1+3.0, but->x2-3.0);
2533 CLAMP(y, but->y1+3.0, but->y2-3.0);
2535 fdrawXORcirc(x, y, 3.1);
2538 glColor3ub(0, 0, 0);
2539 fdrawbox((but->x1), (but->y1), (but->x2), (but->y2));
2542 #ifdef INTERNATIONAL
2543 static void ui_draw_but_CHARTAB(uiBut *but)
2545 /* XXX 2.50 bad global access */
2547 /* Some local variables */
2548 float sx, sy, ex, ey;
2549 float width, height;
2553 unsigned char ustr[16];
2556 int charmax = G.charmax;
2558 /* <builtin> font in use. There are TTF <builtin> and non-TTF <builtin> fonts */
2559 if(!strcmp(G.selfont->name, "<builtin>"))
2561 if(G.ui_international == TRUE)
2571 /* Category list exited without selecting the area */
2573 charmax = G.charmax = 0xffff;
2575 /* Calculate the size of the button */
2576 width = abs(but->x2 - but->x1);
2577 height = abs(but->y2 - but->y1);
2579 butw = floor(width / 12);
2580 buth = floor(height / 6);
2582 /* Initialize variables */
2584 ex = but->x1 + butw;
2585 sy = but->y1 + height - buth;
2586 ey = but->y1 + height;
2590 /* Set the font, in case it is not <builtin> font */
2591 if(G.selfont && strcmp(G.selfont->name, "<builtin>"))
2595 // Is the font file packed, if so then use the packed file
2596 if(G.selfont->packedfile)
2598 pf = G.selfont->packedfile;
2599 FTF_SetFont(pf->data, pf->size, 14.0);
2605 strcpy(tmpStr, G.selfont->name);
2606 BLI_convertstringcode(tmpStr, G.sce);
2607 err = FTF_SetFont((unsigned char *)tmpStr, 0, 14.0);
2612 if(G.ui_international == TRUE)
2614 FTF_SetFont((unsigned char *) datatoc_bfont_ttf, datatoc_bfont_ttf_size, 14.0);
2618 /* Start drawing the button itself */
2619 glShadeModel(GL_SMOOTH);
2621 glColor3ub(200, 200, 200);
2622 glRectf((but->x1), (but->y1), (but->x2), (but->y2));
2624 glColor3ub(0, 0, 0);
2625 for(y = 0; y < 6; y++)
2627 // Do not draw more than the category allows
2628 if(cs > charmax) break;
2630 for(x = 0; x < 12; x++)
2632 // Do not draw more than the category allows
2633 if(cs > charmax) break;
2635 // Draw one grid cell
2636 glBegin(GL_LINE_LOOP);
2643 // Draw character inside the cell
2644 memset(wstr, 0, sizeof(wchar_t)*2);
2645 memset(ustr, 0, 16);
2647 // Set the font to be either unicode or <builtin>
2649 if(strcmp(G.selfont->name, "<builtin>"))
2651 wcs2utf8s((char *)ustr, (wchar_t *)wstr);
2655 if(G.ui_international == TRUE)
2657 wcs2utf8s((char *)ustr, (wchar_t *)wstr);
2666 if((G.selfont && strcmp(G.selfont->name, "<builtin>")) || (G.selfont && !strcmp(G.selfont->name, "<builtin>") && G.ui_international == TRUE))
2669 float llx, lly, llz, urx, ury, urz;
2673 // Calculate the position
2674 wid = FTF_GetStringWidth((char *) ustr, FTF_USE_GETTEXT | FTF_INPUT_UTF8);
2675 FTF_GetBoundingBox((char *) ustr, &llx,&lly,&llz,&urx,&ury,&urz, FTF_USE_GETTEXT | FTF_INPUT_UTF8);
2679 // This isn't fully functional since the but->aspect isn't working like I suspected
2680 px = sx + ((butw/but->aspect)-dx)/2;
2681 py = sy + ((buth/but->aspect)-dy)/2;
2683 // Set the position and draw the character
2684 ui_rasterpos_safe(px, py, but->aspect);
2685 FTF_DrawString((char *) ustr, FTF_USE_GETTEXT | FTF_INPUT_UTF8);
2689 ui_rasterpos_safe(sx + butw/2, sy + buth/2, but->aspect);
2690 UI_DrawString(but->font, (char *) ustr, 0);
2693 // Calculate the next position and character
2694 sx += butw; ex +=butw;
2697 /* Add the y position and reset x position */
2701 ex = but->x1 + butw;
2703 glShadeModel(GL_FLAT);
2705 /* Return Font Settings to original */
2706 if(U.fontsize && U.fontname[0])
2708 result = FTF_SetFont((unsigned char *)U.fontname, 0, U.fontsize);
2710 else if (U.fontsize)
2712 result = FTF_SetFont((unsigned char *) datatoc_bfont_ttf, datatoc_bfont_ttf_size, U.fontsize);
2717 result = FTF_SetFont((unsigned char *) datatoc_bfont_ttf, datatoc_bfont_ttf_size, 11);
2720 /* resets the font size */
2721 if(G.ui_international == TRUE)
2723 uiSetCurFont(but->block, UI_HELV);
2728 #endif // INTERNATIONAL
2730 static void ui_draw_but_COLORBAND(uiBut *but)
2734 float x1, y1, sizex, sizey;
2735 float dx, v3[2], v1[2], v2[2], v1a[2], v2a[2];
2738 coba= (ColorBand *)(but->editcoba? but->editcoba: but->poin);
2739 if(coba==NULL) return;
2746 /* first background, to show tranparency */
2749 for(a=0; a<12; a++) {
2750 if(a & 1) glColor3f(0.3, 0.3, 0.3); else glColor3f(0.8, 0.8, 0.8);
2751 glRectf(v1[0], y1, v1[0]+dx, y1+0.5*sizey);
2752 if(a & 1) glColor3f(0.8, 0.8, 0.8); else glColor3f(0.3, 0.3, 0.3);
2753 glRectf(v1[0], y1+0.5*sizey, v1[0]+dx, y1+sizey);
2757 glShadeModel(GL_SMOOTH);
2766 glBegin(GL_QUAD_STRIP);
2768 glColor4fv( &cbd->r );
2769 glVertex2fv(v1); glVertex2fv(v2);
2771 for(a=0; a<coba->tot; a++, cbd++) {
2773 v1[0]=v2[0]= x1+ cbd->pos*sizex;
2775 glColor4fv( &cbd->r );
2776 glVertex2fv(v1); glVertex2fv(v2);
2779 v1[0]=v2[0]= x1+ sizex;
2780 glVertex2fv(v1); glVertex2fv(v2);
2783 glShadeModel(GL_FLAT);
2784 glDisable(GL_BLEND);
2787 v1[0]= x1; v1[1]= y1;
2790 glBegin(GL_LINE_LOOP);
2802 v1[0]= v2[0]=v3[0]= x1;
2804 v1a[1]= y1+0.25*sizey;
2805 v2[1]= y1+0.5*sizey;
2806 v2a[1]= y1+0.75*sizey;
2812 for(a=0; a<coba->tot; a++, cbd++) {
2813 v1[0]=v2[0]=v3[0]=v1a[0]=v2a[0]= x1+ cbd->pos*sizex;
2816 glColor3ub(0, 0, 0);
2823 glColor3ub(255, 255, 255);
2830 /* glColor3ub(0, 0, 0);
2833 glColor3ub(255, 255, 255);
2836 glColor3ub(0, 0, 0);
2839 glColor3ub(255, 255, 255);
2845 glColor3ub(0, 0, 0);
2849 glColor3ub(255, 255, 255);
2857 static void ui_draw_but_NORMAL(uiBut *but)
2859 static GLuint displist=0;
2861 GLfloat diff[4], diffn[4]={1.0f, 1.0f, 1.0f, 1.0f};
2862 float vec0[4]={0.0f, 0.0f, 0.0f, 0.0f};
2866 glGetMaterialfv(GL_FRONT, GL_DIFFUSE, diff);
2869 UI_ThemeColor(TH_BUT_NEUTRAL);
2871 gl_round_box(GL_POLYGON, but->x1, but->y1, but->x2, but->y2, 5.0f);
2874 glMaterialfv(GL_FRONT, GL_DIFFUSE, diffn);
2875 glCullFace(GL_BACK); glEnable(GL_CULL_FACE);
2877 /* disable blender light */
2878 for(a=0; a<8; a++) {
2879 old[a]= glIsEnabled(GL_LIGHT0+a);
2880 glDisable(GL_LIGHT0+a);
2884 glEnable(GL_LIGHT7);
2885 glEnable(GL_LIGHTING);
2887 VECCOPY(dir, (float *)but->poin);
2888 dir[3]= 0.0f; /* glLight needs 4 args, 0.0 is sun */
2889 glLightfv(GL_LIGHT7, GL_POSITION, dir);
2890 glLightfv(GL_LIGHT7, GL_DIFFUSE, diffn);
2891 glLightfv(GL_LIGHT7, GL_SPECULAR, vec0);
2892 glLightf(GL_LIGHT7, GL_CONSTANT_ATTENUATION, 1.0f);
2893 glLightf(GL_LIGHT7, GL_LINEAR_ATTENUATION, 0.0f);
2895 /* transform to button */
2897 glTranslatef(but->x1 + 0.5f*(but->x2-but->x1), but->y1+ 0.5f*(but->y2-but->y1), 0.0f);
2898 size= (but->x2-but->x1)/200.f;
2899 glScalef(size, size, size);
2902 GLUquadricObj *qobj;
2904 displist= glGenLists(1);
2905 glNewList(displist, GL_COMPILE_AND_EXECUTE);
2907 qobj= gluNewQuadric();
2908 gluQuadricDrawStyle(qobj, GLU_FILL);
2909 glShadeModel(GL_SMOOTH);
2910 gluSphere( qobj, 100.0, 32, 24);
2911 glShadeModel(GL_FLAT);
2912 gluDeleteQuadric(qobj);
2916 else glCallList(displist);
2920 glDisable(GL_LIGHTING);
2921 glDisable(GL_CULL_FACE);
2922 glMaterialfv(GL_FRONT, GL_DIFFUSE, diff);
2924 glDisable(GL_LIGHT7);
2926 /* enable blender light */
2927 for(a=0; a<8; a++) {
2929 glEnable(GL_LIGHT0+a);
2933 static void ui_draw_but_curve_grid(uiBut *but, float zoomx, float zoomy, float offsx, float offsy, float step)
2935 float dx, dy, fx, fy;
2939 fx= but->x1 + zoomx*(-offsx);
2940 if(fx > but->x1) fx -= dx*( floor(fx-but->x1));
2941 while(fx < but->x2) {
2942 glVertex2f(fx, but->y1);
2943 glVertex2f(fx, but->y2);
2948 fy= but->y1 + zoomy*(-offsy);
2949 if(fy > but->y1) fy -= dy*( floor(fy-but->y1));
2950 while(fy < but->y2) {
2951 glVertex2f(but->x1, fy);
2952 glVertex2f(but->x2, fy);
2959 static void ui_draw_but_CURVE(ARegion *ar, uiBut *but)
2961 CurveMapping *cumap;
2964 float fx, fy, dx, dy, fac[2], zoomx, zoomy, offsx, offsy;
2968 cumap= (CurveMapping *)(but->editcumap? but->editcumap: but->poin);
2969 cuma= cumap->cm+cumap->cur;
2971 /* need scissor test, curve can draw outside of boundary */
2972 glGetIntegerv(GL_VIEWPORT, scissor);
2973 fx= but->x1; fy= but->y1;
2974 ui_block_to_window_fl(ar, but->block, &fx, &fy);
2975 dx= but->x2; dy= but->y2;
2976 ui_block_to_window_fl(ar, but->block, &dx, &dy);
2977 glScissor((int)floor(fx), (int)floor(fy), (int)ceil(dx-fx), (int)ceil(dy-fy));
2979 /* calculate offset and zoom */
2980 zoomx= (but->x2-but->x1-2.0*but->aspect)/(cumap->curr.xmax - cumap->curr.xmin);
2981 zoomy= (but->y2-but->y1-2.0*but->aspect)/(cumap->curr.ymax - cumap->curr.ymin);
2982 offsx= cumap->curr.xmin-but->aspect/zoomx;
2983 offsy= cumap->curr.ymin-but->aspect/zoomy;
2986 if(cumap->flag & CUMA_DO_CLIP) {
2987 UI_ThemeColorShade(TH_BUT_NEUTRAL, -20);
2988 glRectf(but->x1, but->y1, but->x2, but->y2);
2989 UI_ThemeColor(TH_BUT_NEUTRAL);
2990 glRectf(but->x1 + zoomx*(cumap->clipr.xmin-offsx),
2991 but->y1 + zoomy*(cumap->clipr.ymin-offsy),
2992 but->x1 + zoomx*(cumap->clipr.xmax-offsx),
2993 but->y1 + zoomy*(cumap->clipr.ymax-offsy));
2996 UI_ThemeColor(TH_BUT_NEUTRAL);
2997 glRectf(but->x1, but->y1, but->x2, but->y2);
3000 /* grid, every .25 step */
3001 UI_ThemeColorShade(TH_BUT_NEUTRAL, -16);
3002 ui_draw_but_curve_grid(but, zoomx, zoomy, offsx, offsy, 0.25f);
3003 /* grid, every 1.0 step */
3004 UI_ThemeColorShade(TH_BUT_NEUTRAL, -24);
3005 ui_draw_but_curve_grid(but, zoomx, zoomy, offsx, offsy, 1.0f);
3007 UI_ThemeColorShade(TH_BUT_NEUTRAL, -50);
3009 glVertex2f(but->x1, but->y1 + zoomy*(-offsy));
3010 glVertex2f(but->x2, but->y1 + zoomy*(-offsy));
3011 glVertex2f(but->x1 + zoomx*(-offsx), but->y1);
3012 glVertex2f(but->x1 + zoomx*(-offsx), but->y2);
3017 if(cumap->flag & CUMA_DRAW_CFRA) {
3018 glColor3ub(0x60, 0xc0, 0x40);
3020 glVertex2f(but->x1 + zoomx*(cumap->sample[0]-offsx), but->y1);
3021 glVertex2f(but->x1 + zoomx*(cumap->sample[0]-offsx), but->y2);
3026 * if(cumap->flag & CUMA_DRAW_SAMPLE) {
3028 float lum= cumap->sample[0]*0.35f + cumap->sample[1]*0.45f + cumap->sample[2]*0.2f;
3029 glColor3ub(240, 240, 240);
3032 glVertex2f(but->x1 + zoomx*(lum-offsx), but->y1);
3033 glVertex2f(but->x1 + zoomx*(lum-offsx), but->y2);
3038 glColor3ub(240, 100, 100);
3039 else if(cumap->cur==1)
3040 glColor3ub(100, 240, 100);
3042 glColor3ub(100, 100, 240);
3045 glVertex2f(but->x1 + zoomx*(cumap->sample[cumap->cur]-offsx), but->y1);
3046 glVertex2f(but->x1 + zoomx*(cumap->sample[cumap->cur]-offsx), but->y2);
3052 UI_ThemeColorBlend(TH_TEXT, TH_BUT_NEUTRAL, 0.35);
3053 glEnable(GL_LINE_SMOOTH);
3055 glBegin(GL_LINE_STRIP);
3057 if(cuma->table==NULL)
3058 curvemapping_changed(cumap, 0); /* 0 = no remove doubles */
3062 if((cuma->flag & CUMA_EXTEND_EXTRAPOLATE)==0)
3063 glVertex2f(but->x1, but->y1 + zoomy*(cmp[0].y-offsy));
3065 fx= but->x1 + zoomx*(cmp[0].x-offsx + cuma->ext_in[0]);
3066 fy= but->y1 + zoomy*(cmp[0].y-offsy + cuma->ext_in[1]);
3069 for(a=0; a<=CM_TABLE; a++) {
3070 fx= but->x1 + zoomx*(cmp[a].x-offsx);
3071 fy= but->y1 + zoomy*(cmp[a].y-offsy);
3075 if((cuma->flag & CUMA_EXTEND_EXTRAPOLATE)==0)
3076 glVertex2f(but->x2, but->y1 + zoomy*(cmp[CM_TABLE].y-offsy));
3078 fx= but->x1 + zoomx*(cmp[CM_TABLE].x-offsx - cuma->ext_out[0]);
3079 fy= but->y1 + zoomy*(cmp[CM_TABLE].y-offsy - cuma->ext_out[1]);
3083 glDisable(GL_LINE_SMOOTH);
3084 glDisable(GL_BLEND);
3086 /* the points, use aspect to make them visible on edges */
3089 bglBegin(GL_POINTS);
3090 for(a=0; a<cuma->totpoint; a++) {
3091 if(cmp[a].flag & SELECT)
3092 UI_ThemeColor(TH_TEXT_HI);
3094 UI_ThemeColor(TH_TEXT);
3095 fac[0]= but->x1 + zoomx*(cmp[a].x-offsx);
3096 fac[1]= but->y1 + zoomy*(cmp[a].y-offsy);