|
Blender
V2.59
|
00001 /* 00002 * ***** BEGIN GPL LICENSE BLOCK ***** 00003 * 00004 * This program is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU General Public License 00006 * as published by the Free Software Foundation; either version 2 00007 * of the License, or (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program; if not, write to the Free Software Foundation, 00016 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 * 00018 * The Original Code is Copyright (C) 2009 Blender Foundation. 00019 * All rights reserved. 00020 * 00021 * Contributor(s): Blender Foundation 00022 * 00023 * ***** END GPL LICENSE BLOCK ***** 00024 */ 00025 00031 #include <limits.h> 00032 #include <stdlib.h> 00033 #include <string.h> 00034 #include <assert.h> 00035 00036 00037 #include "DNA_screen_types.h" 00038 #include "DNA_userdef_types.h" 00039 00040 #include "BLI_math.h" 00041 #include "BLI_listbase.h" 00042 #include "BLI_rect.h" 00043 #include "BLI_string.h" 00044 #include "BLI_utildefines.h" 00045 00046 #include "BKE_context.h" 00047 #include "BKE_curve.h" 00048 #include "BKE_utildefines.h" 00049 00050 #include "RNA_access.h" 00051 00052 #include "BIF_gl.h" 00053 #include "BIF_glutil.h" 00054 00055 #include "BLF_api.h" 00056 00057 #include "UI_interface.h" 00058 #include "UI_interface_icons.h" 00059 00060 00061 #include "interface_intern.h" 00062 00063 /* ************** widget base functions ************** */ 00064 /* 00065 - in: roundbox codes for corner types and radius 00066 - return: array of [size][2][x,y] points, the edges of the roundbox, + UV coords 00067 00068 - draw black box with alpha 0 on exact button boundbox 00069 - for ever AA step: 00070 - draw the inner part for a round filled box, with color blend codes or texture coords 00071 - draw outline in outline color 00072 - draw outer part, bottom half, extruded 1 pixel to bottom, for emboss shadow 00073 - draw extra decorations 00074 - draw background color box with alpha 1 on exact button boundbox 00075 00076 */ 00077 00078 /* fill this struct with polygon info to draw AA'ed */ 00079 /* it has outline, back, and two optional tria meshes */ 00080 00081 typedef struct uiWidgetTrias { 00082 int tot; 00083 00084 float vec[32][2]; 00085 int (*index)[3]; 00086 00087 } uiWidgetTrias; 00088 00089 typedef struct uiWidgetBase { 00090 00091 int totvert, halfwayvert; 00092 float outer_v[64][2]; 00093 float inner_v[64][2]; 00094 float inner_uv[64][2]; 00095 00096 short inner, outline, emboss; /* set on/off */ 00097 short shadedir; 00098 00099 uiWidgetTrias tria1; 00100 uiWidgetTrias tria2; 00101 00102 } uiWidgetBase; 00103 00104 /* uiWidgetType: for time being only for visual appearance, 00105 later, a handling callback can be added too 00106 */ 00107 typedef struct uiWidgetType { 00108 00109 /* pointer to theme color definition */ 00110 uiWidgetColors *wcol_theme; 00111 uiWidgetStateColors *wcol_state; 00112 00113 /* converted colors for state */ 00114 uiWidgetColors wcol; 00115 00116 void (*state)(struct uiWidgetType *, int state); 00117 void (*draw)(uiWidgetColors *, rcti *, int state, int roundboxalign); 00118 void (*custom)(uiBut *, uiWidgetColors *, rcti *, int state, int roundboxalign); 00119 void (*text)(uiFontStyle *, uiWidgetColors *, uiBut *, rcti *); 00120 00121 } uiWidgetType; 00122 00123 00124 /* *********************** draw data ************************** */ 00125 00126 static float cornervec[9][2]= {{0.0, 0.0}, {0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, 00127 {0.707, 0.293}, {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}, {1.0, 1.0}}; 00128 00129 static float jit[8][2]= {{0.468813 , -0.481430}, {-0.155755 , -0.352820}, 00130 {0.219306 , -0.238501}, {-0.393286 , -0.110949}, {-0.024699 , 0.013908}, 00131 {0.343805 , 0.147431}, {-0.272855 , 0.269918}, {0.095909 , 0.388710}}; 00132 00133 static float num_tria_vert[3][2]= { 00134 {-0.352077, 0.532607}, {-0.352077, -0.549313}, {0.330000, -0.008353}}; 00135 00136 static int num_tria_face[1][3]= { 00137 {0, 1, 2}}; 00138 00139 static float scroll_circle_vert[16][2]= { 00140 {0.382684, 0.923879}, {0.000001, 1.000000}, {-0.382683, 0.923880}, {-0.707107, 0.707107}, 00141 {-0.923879, 0.382684}, {-1.000000, 0.000000}, {-0.923880, -0.382684}, {-0.707107, -0.707107}, 00142 {-0.382683, -0.923880}, {0.000000, -1.000000}, {0.382684, -0.923880}, {0.707107, -0.707107}, 00143 {0.923880, -0.382684}, {1.000000, -0.000000}, {0.923880, 0.382683}, {0.707107, 0.707107}}; 00144 00145 static int scroll_circle_face[14][3]= { 00146 {0, 1, 2}, {2, 0, 3}, {3, 0, 15}, {3, 15, 4}, {4, 15, 14}, {4, 14, 5}, {5, 14, 13}, {5, 13, 6}, 00147 {6, 13, 12}, {6, 12, 7}, {7, 12, 11}, {7, 11, 8}, {8, 11, 10}, {8, 10, 9}}; 00148 00149 static float menu_tria_vert[6][2]= { 00150 {-0.41, 0.16}, {0.41, 0.16}, {0, 0.82}, 00151 {0, -0.82}, {-0.41, -0.16}, {0.41, -0.16}}; 00152 00153 static int menu_tria_face[2][3]= {{2, 0, 1}, {3, 5, 4}}; 00154 00155 static float check_tria_vert[6][2]= { 00156 {-0.578579, 0.253369}, {-0.392773, 0.412794}, {-0.004241, -0.328551}, 00157 {-0.003001, 0.034320}, {1.055313, 0.864744}, {0.866408, 1.026895}}; 00158 00159 static int check_tria_face[4][3]= { 00160 {3, 2, 4}, {3, 4, 5}, {1, 0, 3}, {0, 2, 3}}; 00161 00162 GLubyte checker_stipple_sml[32*32/8] = 00163 { 00164 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \ 00165 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \ 00166 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \ 00167 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \ 00168 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \ 00169 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \ 00170 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \ 00171 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \ 00172 }; 00173 00174 /* ************************************************* */ 00175 00176 void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3) 00177 { 00178 float color[4]; 00179 int j; 00180 00181 glEnable(GL_BLEND); 00182 glGetFloatv(GL_CURRENT_COLOR, color); 00183 color[3]*= 0.125; 00184 glColor4fv(color); 00185 00186 /* for each AA step */ 00187 for(j=0; j<8; j++) { 00188 glTranslatef(1.0f * jit[j][0], 1.0f * jit[j][1], 0.0f); 00189 00190 glBegin(GL_POLYGON); 00191 glVertex2f(x1, y1); 00192 glVertex2f(x2, y2); 00193 glVertex2f(x3, y3); 00194 glEnd(); 00195 00196 glTranslatef(-1.0f * jit[j][0], -1.0f * jit[j][1], 0.0f); 00197 } 00198 00199 glDisable(GL_BLEND); 00200 00201 } 00202 00203 static void widget_init(uiWidgetBase *wtb) 00204 { 00205 wtb->totvert= wtb->halfwayvert= 0; 00206 wtb->tria1.tot= 0; 00207 wtb->tria2.tot= 0; 00208 00209 wtb->inner= 1; 00210 wtb->outline= 1; 00211 wtb->emboss= 1; 00212 wtb->shadedir= 1; 00213 } 00214 00215 /* helper call, makes shadow rect, with 'sun' above menu, so only shadow to left/right/bottom */ 00216 /* return tot */ 00217 static int round_box_shadow_edges(float (*vert)[2], rcti *rect, float rad, int roundboxalign, float step) 00218 { 00219 float vec[9][2]; 00220 float minx, miny, maxx, maxy; 00221 int a, tot= 0; 00222 00223 rad+= step; 00224 00225 if(2.0f*rad > rect->ymax-rect->ymin) 00226 rad= 0.5f*(rect->ymax-rect->ymin); 00227 00228 minx= rect->xmin-step; 00229 miny= rect->ymin-step; 00230 maxx= rect->xmax+step; 00231 maxy= rect->ymax+step; 00232 00233 /* mult */ 00234 for(a=0; a<9; a++) { 00235 vec[a][0]= rad*cornervec[a][0]; 00236 vec[a][1]= rad*cornervec[a][1]; 00237 } 00238 00239 /* start with left-top, anti clockwise */ 00240 if(roundboxalign & 1) { 00241 for(a=0; a<9; a++, tot++) { 00242 vert[tot][0]= minx+rad-vec[a][0]; 00243 vert[tot][1]= maxy-vec[a][1]; 00244 } 00245 } 00246 else { 00247 for(a=0; a<9; a++, tot++) { 00248 vert[tot][0]= minx; 00249 vert[tot][1]= maxy; 00250 } 00251 } 00252 00253 if(roundboxalign & 8) { 00254 for(a=0; a<9; a++, tot++) { 00255 vert[tot][0]= minx+vec[a][1]; 00256 vert[tot][1]= miny+rad-vec[a][0]; 00257 } 00258 } 00259 else { 00260 for(a=0; a<9; a++, tot++) { 00261 vert[tot][0]= minx; 00262 vert[tot][1]= miny; 00263 } 00264 } 00265 00266 if(roundboxalign & 4) { 00267 for(a=0; a<9; a++, tot++) { 00268 vert[tot][0]= maxx-rad+vec[a][0]; 00269 vert[tot][1]= miny+vec[a][1]; 00270 } 00271 } 00272 else { 00273 for(a=0; a<9; a++, tot++) { 00274 vert[tot][0]= maxx; 00275 vert[tot][1]= miny; 00276 } 00277 } 00278 00279 if(roundboxalign & 2) { 00280 for(a=0; a<9; a++, tot++) { 00281 vert[tot][0]= maxx-vec[a][1]; 00282 vert[tot][1]= maxy-rad+vec[a][0]; 00283 } 00284 } 00285 else { 00286 for(a=0; a<9; a++, tot++) { 00287 vert[tot][0]= maxx; 00288 vert[tot][1]= maxy; 00289 } 00290 } 00291 return tot; 00292 } 00293 00294 /* this call has 1 extra arg to allow mask outline */ 00295 static void round_box__edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, float rad, float radi) 00296 { 00297 float vec[9][2], veci[9][2]; 00298 float minx= rect->xmin, miny= rect->ymin, maxx= rect->xmax, maxy= rect->ymax; 00299 float minxi= minx + 1.0f; /* boundbox inner */ 00300 float maxxi= maxx - 1.0f; 00301 float minyi= miny + 1.0f; 00302 float maxyi= maxy - 1.0f; 00303 float facxi= (maxxi!=minxi) ? 1.0f/(maxxi-minxi) : 0.0f; /* for uv, can divide by zero */ 00304 float facyi= (maxyi!=minyi) ? 1.0f/(maxyi-minyi) : 0.0f; 00305 int a, tot= 0, minsize; 00306 const int hnum= ((roundboxalign & (1|2))==(1|2) || (roundboxalign & (4|8))==(4|8)) ? 1 : 2; 00307 const int vnum= ((roundboxalign & (1|8))==(1|8) || (roundboxalign & (2|4))==(2|4)) ? 1 : 2; 00308 00309 minsize= MIN2((rect->xmax-rect->xmin)*hnum, (rect->ymax-rect->ymin)*vnum); 00310 00311 if(2.0f*rad > minsize) 00312 rad= 0.5f*minsize; 00313 00314 if(2.0f*(radi+1.0f) > minsize) 00315 radi= 0.5f*minsize - 1.0f; 00316 00317 /* mult */ 00318 for(a=0; a<9; a++) { 00319 veci[a][0]= radi*cornervec[a][0]; 00320 veci[a][1]= radi*cornervec[a][1]; 00321 vec[a][0]= rad*cornervec[a][0]; 00322 vec[a][1]= rad*cornervec[a][1]; 00323 } 00324 00325 /* corner left-bottom */ 00326 if(roundboxalign & 8) { 00327 00328 for(a=0; a<9; a++, tot++) { 00329 wt->inner_v[tot][0]= minxi+veci[a][1]; 00330 wt->inner_v[tot][1]= minyi+radi-veci[a][0]; 00331 00332 wt->outer_v[tot][0]= minx+vec[a][1]; 00333 wt->outer_v[tot][1]= miny+rad-vec[a][0]; 00334 00335 wt->inner_uv[tot][0]= facxi*(wt->inner_v[tot][0] - minxi); 00336 wt->inner_uv[tot][1]= facyi*(wt->inner_v[tot][1] - minyi); 00337 } 00338 } 00339 else { 00340 wt->inner_v[tot][0]= minxi; 00341 wt->inner_v[tot][1]= minyi; 00342 00343 wt->outer_v[tot][0]= minx; 00344 wt->outer_v[tot][1]= miny; 00345 00346 wt->inner_uv[tot][0]= 0.0f; 00347 wt->inner_uv[tot][1]= 0.0f; 00348 00349 tot++; 00350 } 00351 00352 /* corner right-bottom */ 00353 if(roundboxalign & 4) { 00354 00355 for(a=0; a<9; a++, tot++) { 00356 wt->inner_v[tot][0]= maxxi-radi+veci[a][0]; 00357 wt->inner_v[tot][1]= minyi+veci[a][1]; 00358 00359 wt->outer_v[tot][0]= maxx-rad+vec[a][0]; 00360 wt->outer_v[tot][1]= miny+vec[a][1]; 00361 00362 wt->inner_uv[tot][0]= facxi*(wt->inner_v[tot][0] - minxi); 00363 wt->inner_uv[tot][1]= facyi*(wt->inner_v[tot][1] - minyi); 00364 } 00365 } 00366 else { 00367 wt->inner_v[tot][0]= maxxi; 00368 wt->inner_v[tot][1]= minyi; 00369 00370 wt->outer_v[tot][0]= maxx; 00371 wt->outer_v[tot][1]= miny; 00372 00373 wt->inner_uv[tot][0]= 1.0f; 00374 wt->inner_uv[tot][1]= 0.0f; 00375 00376 tot++; 00377 } 00378 00379 wt->halfwayvert= tot; 00380 00381 /* corner right-top */ 00382 if(roundboxalign & 2) { 00383 00384 for(a=0; a<9; a++, tot++) { 00385 wt->inner_v[tot][0]= maxxi-veci[a][1]; 00386 wt->inner_v[tot][1]= maxyi-radi+veci[a][0]; 00387 00388 wt->outer_v[tot][0]= maxx-vec[a][1]; 00389 wt->outer_v[tot][1]= maxy-rad+vec[a][0]; 00390 00391 wt->inner_uv[tot][0]= facxi*(wt->inner_v[tot][0] - minxi); 00392 wt->inner_uv[tot][1]= facyi*(wt->inner_v[tot][1] - minyi); 00393 } 00394 } 00395 else { 00396 wt->inner_v[tot][0]= maxxi; 00397 wt->inner_v[tot][1]= maxyi; 00398 00399 wt->outer_v[tot][0]= maxx; 00400 wt->outer_v[tot][1]= maxy; 00401 00402 wt->inner_uv[tot][0]= 1.0f; 00403 wt->inner_uv[tot][1]= 1.0f; 00404 00405 tot++; 00406 } 00407 00408 /* corner left-top */ 00409 if(roundboxalign & 1) { 00410 00411 for(a=0; a<9; a++, tot++) { 00412 wt->inner_v[tot][0]= minxi+radi-veci[a][0]; 00413 wt->inner_v[tot][1]= maxyi-veci[a][1]; 00414 00415 wt->outer_v[tot][0]= minx+rad-vec[a][0]; 00416 wt->outer_v[tot][1]= maxy-vec[a][1]; 00417 00418 wt->inner_uv[tot][0]= facxi*(wt->inner_v[tot][0] - minxi); 00419 wt->inner_uv[tot][1]= facyi*(wt->inner_v[tot][1] - minyi); 00420 } 00421 00422 } 00423 else { 00424 00425 wt->inner_v[tot][0]= minxi; 00426 wt->inner_v[tot][1]= maxyi; 00427 00428 wt->outer_v[tot][0]= minx; 00429 wt->outer_v[tot][1]= maxy; 00430 00431 wt->inner_uv[tot][0]= 0.0f; 00432 wt->inner_uv[tot][1]= 1.0f; 00433 00434 tot++; 00435 } 00436 00437 wt->totvert= tot; 00438 } 00439 00440 static void round_box_edges(uiWidgetBase *wt, int roundboxalign, rcti *rect, float rad) 00441 { 00442 round_box__edges(wt, roundboxalign, rect, rad, rad-1.0f); 00443 } 00444 00445 00446 /* based on button rect, return scaled array of triangles */ 00447 static void widget_num_tria(uiWidgetTrias *tria, rcti *rect, float triasize, char where) 00448 { 00449 float centx, centy, sizex, sizey, minsize; 00450 int a, i1=0, i2=1; 00451 00452 minsize= MIN2(rect->xmax-rect->xmin, rect->ymax-rect->ymin); 00453 00454 /* center position and size */ 00455 centx= (float)rect->xmin + 0.5f*minsize; 00456 centy= (float)rect->ymin + 0.5f*minsize; 00457 sizex= sizey= -0.5f*triasize*minsize; 00458 00459 if(where=='r') { 00460 centx= (float)rect->xmax - 0.5f*minsize; 00461 sizex= -sizex; 00462 } 00463 else if(where=='t') { 00464 centy= (float)rect->ymax - 0.5f*minsize; 00465 sizey= -sizey; 00466 i2=0; i1= 1; 00467 } 00468 else if(where=='b') { 00469 sizex= -sizex; 00470 i2=0; i1= 1; 00471 } 00472 00473 for(a=0; a<3; a++) { 00474 tria->vec[a][0]= sizex*num_tria_vert[a][i1] + centx; 00475 tria->vec[a][1]= sizey*num_tria_vert[a][i2] + centy; 00476 } 00477 00478 tria->tot= 1; 00479 tria->index= num_tria_face; 00480 } 00481 00482 static void widget_scroll_circle(uiWidgetTrias *tria, rcti *rect, float triasize, char where) 00483 { 00484 float centx, centy, sizex, sizey, minsize; 00485 int a, i1=0, i2=1; 00486 00487 minsize= MIN2(rect->xmax-rect->xmin, rect->ymax-rect->ymin); 00488 00489 /* center position and size */ 00490 centx= (float)rect->xmin + 0.5f*minsize; 00491 centy= (float)rect->ymin + 0.5f*minsize; 00492 sizex= sizey= -0.5f*triasize*minsize; 00493 00494 if(where=='r') { 00495 centx= (float)rect->xmax - 0.5f*minsize; 00496 sizex= -sizex; 00497 } 00498 else if(where=='t') { 00499 centy= (float)rect->ymax - 0.5f*minsize; 00500 sizey= -sizey; 00501 i2=0; i1= 1; 00502 } 00503 else if(where=='b') { 00504 sizex= -sizex; 00505 i2=0; i1= 1; 00506 } 00507 00508 for(a=0; a<16; a++) { 00509 tria->vec[a][0]= sizex*scroll_circle_vert[a][i1] + centx; 00510 tria->vec[a][1]= sizey*scroll_circle_vert[a][i2] + centy; 00511 } 00512 00513 tria->tot= 14; 00514 tria->index= scroll_circle_face; 00515 } 00516 00517 static void widget_trias_draw(uiWidgetTrias *tria) 00518 { 00519 int a; 00520 00521 glBegin(GL_TRIANGLES); 00522 for(a=0; a<tria->tot; a++) { 00523 glVertex2fv(tria->vec[ tria->index[a][0] ]); 00524 glVertex2fv(tria->vec[ tria->index[a][1] ]); 00525 glVertex2fv(tria->vec[ tria->index[a][2] ]); 00526 } 00527 glEnd(); 00528 00529 } 00530 00531 static void widget_menu_trias(uiWidgetTrias *tria, rcti *rect) 00532 { 00533 float centx, centy, size, asp; 00534 int a; 00535 00536 /* center position and size */ 00537 centx= rect->xmax - 0.5f*(rect->ymax-rect->ymin); 00538 centy= rect->ymin + 0.5f*(rect->ymax-rect->ymin); 00539 size= 0.4f*(rect->ymax-rect->ymin); 00540 00541 /* XXX exception */ 00542 asp= ((float)rect->xmax-rect->xmin)/((float)rect->ymax-rect->ymin); 00543 if(asp > 1.2f && asp < 2.6f) 00544 centx= rect->xmax - 0.3f*(rect->ymax-rect->ymin); 00545 00546 for(a=0; a<6; a++) { 00547 tria->vec[a][0]= size*menu_tria_vert[a][0] + centx; 00548 tria->vec[a][1]= size*menu_tria_vert[a][1] + centy; 00549 } 00550 00551 tria->tot= 2; 00552 tria->index= menu_tria_face; 00553 } 00554 00555 static void widget_check_trias(uiWidgetTrias *tria, rcti *rect) 00556 { 00557 float centx, centy, size; 00558 int a; 00559 00560 /* center position and size */ 00561 centx= rect->xmin + 0.5f*(rect->ymax-rect->ymin); 00562 centy= rect->ymin + 0.5f*(rect->ymax-rect->ymin); 00563 size= 0.5f*(rect->ymax-rect->ymin); 00564 00565 for(a=0; a<6; a++) { 00566 tria->vec[a][0]= size*check_tria_vert[a][0] + centx; 00567 tria->vec[a][1]= size*check_tria_vert[a][1] + centy; 00568 } 00569 00570 tria->tot= 4; 00571 tria->index= check_tria_face; 00572 } 00573 00574 00575 /* prepares shade colors */ 00576 static void shadecolors4(char *coltop, char *coldown, const char *color, short shadetop, short shadedown) 00577 { 00578 00579 coltop[0]= CLAMPIS(color[0]+shadetop, 0, 255); 00580 coltop[1]= CLAMPIS(color[1]+shadetop, 0, 255); 00581 coltop[2]= CLAMPIS(color[2]+shadetop, 0, 255); 00582 coltop[3]= color[3]; 00583 00584 coldown[0]= CLAMPIS(color[0]+shadedown, 0, 255); 00585 coldown[1]= CLAMPIS(color[1]+shadedown, 0, 255); 00586 coldown[2]= CLAMPIS(color[2]+shadedown, 0, 255); 00587 coldown[3]= color[3]; 00588 } 00589 00590 static void round_box_shade_col4(const char col1[4], const char col2[4], const float fac) 00591 { 00592 unsigned char col[4]; 00593 const int faci= FTOCHAR(fac); 00594 const int facm= 255-faci; 00595 00596 col[0]= (faci*col1[0] + facm*col2[0])>>8; 00597 col[1]= (faci*col1[1] + facm*col2[1])>>8; 00598 col[2]= (faci*col1[2] + facm*col2[2])>>8; 00599 col[3]= (faci*col1[3] + facm*col2[3])>>8; 00600 00601 glColor4ubv(col); 00602 } 00603 00604 static void widgetbase_outline(uiWidgetBase *wtb) 00605 { 00606 int a; 00607 00608 /* outline */ 00609 glBegin(GL_QUAD_STRIP); 00610 for(a=0; a<wtb->totvert; a++) { 00611 glVertex2fv(wtb->outer_v[a]); 00612 glVertex2fv(wtb->inner_v[a]); 00613 } 00614 glVertex2fv(wtb->outer_v[0]); 00615 glVertex2fv(wtb->inner_v[0]); 00616 glEnd(); 00617 } 00618 00619 static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol) 00620 { 00621 int j, a; 00622 00623 glEnable(GL_BLEND); 00624 00625 /* backdrop non AA */ 00626 if(wtb->inner) { 00627 if(wcol->shaded==0) { 00628 if (wcol->alpha_check) { 00629 float x_mid= 0.0f; /* used for dumb clamping of values */ 00630 00631 /* dark checkers */ 00632 glColor4ub(UI_TRANSP_DARK, UI_TRANSP_DARK, UI_TRANSP_DARK, 255); 00633 glBegin(GL_POLYGON); 00634 for(a=0; a<wtb->totvert; a++) { 00635 glVertex2fv(wtb->inner_v[a]); 00636 } 00637 glEnd(); 00638 00639 /* light checkers */ 00640 glEnable(GL_POLYGON_STIPPLE); 00641 glColor4ub(UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, 255); 00642 glPolygonStipple(checker_stipple_sml); 00643 glBegin(GL_POLYGON); 00644 for(a=0; a<wtb->totvert; a++) { 00645 glVertex2fv(wtb->inner_v[a]); 00646 } 00647 glEnd(); 00648 glDisable(GL_POLYGON_STIPPLE); 00649 00650 /* alpha fill */ 00651 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 00652 00653 glColor4ubv((unsigned char*)wcol->inner); 00654 glBegin(GL_POLYGON); 00655 for(a=0; a<wtb->totvert; a++) { 00656 glVertex2fv(wtb->inner_v[a]); 00657 x_mid += wtb->inner_v[a][0]; 00658 } 00659 x_mid /= wtb->totvert; 00660 glEnd(); 00661 00662 /* 1/2 solid color */ 00663 glColor4ub(wcol->inner[0], wcol->inner[1], wcol->inner[2], 255); 00664 glBegin(GL_POLYGON); 00665 for(a=0; a<wtb->totvert; a++) 00666 glVertex2f(MIN2(wtb->inner_v[a][0], x_mid), wtb->inner_v[a][1]); 00667 glEnd(); 00668 } 00669 else { 00670 /* simple fill */ 00671 glColor4ubv((unsigned char*)wcol->inner); 00672 glBegin(GL_POLYGON); 00673 for(a=0; a<wtb->totvert; a++) 00674 glVertex2fv(wtb->inner_v[a]); 00675 glEnd(); 00676 } 00677 } 00678 else { 00679 char col1[4], col2[4]; 00680 00681 shadecolors4(col1, col2, wcol->inner, wcol->shadetop, wcol->shadedown); 00682 00683 glShadeModel(GL_SMOOTH); 00684 glBegin(GL_POLYGON); 00685 for(a=0; a<wtb->totvert; a++) { 00686 round_box_shade_col4(col1, col2, wtb->inner_uv[a][wtb->shadedir]); 00687 glVertex2fv(wtb->inner_v[a]); 00688 } 00689 glEnd(); 00690 glShadeModel(GL_FLAT); 00691 } 00692 } 00693 00694 /* for each AA step */ 00695 if(wtb->outline) { 00696 for(j=0; j<8; j++) { 00697 glTranslatef(1.0f * jit[j][0], 1.0f * jit[j][1], 0.0f); 00698 00699 /* outline */ 00700 glColor4ub(wcol->outline[0], wcol->outline[1], wcol->outline[2], 32); 00701 glBegin(GL_QUAD_STRIP); 00702 for(a=0; a<wtb->totvert; a++) { 00703 glVertex2fv(wtb->outer_v[a]); 00704 glVertex2fv(wtb->inner_v[a]); 00705 } 00706 glVertex2fv(wtb->outer_v[0]); 00707 glVertex2fv(wtb->inner_v[0]); 00708 glEnd(); 00709 00710 /* emboss bottom shadow */ 00711 if(wtb->emboss) { 00712 glColor4f(1.0f, 1.0f, 1.0f, 0.02f); 00713 glBegin(GL_QUAD_STRIP); 00714 for(a=0; a<wtb->halfwayvert; a++) { 00715 glVertex2fv(wtb->outer_v[a]); 00716 glVertex2f(wtb->outer_v[a][0], wtb->outer_v[a][1]-1.0f); 00717 } 00718 glEnd(); 00719 } 00720 00721 glTranslatef(-1.0f * jit[j][0], -1.0f * jit[j][1], 0.0f); 00722 } 00723 } 00724 00725 /* decoration */ 00726 if(wtb->tria1.tot || wtb->tria2.tot) { 00727 /* for each AA step */ 00728 for(j=0; j<8; j++) { 00729 glTranslatef(1.0f * jit[j][0], 1.0f * jit[j][1], 0.0f); 00730 00731 if(wtb->tria1.tot) { 00732 glColor4ub(wcol->item[0], wcol->item[1], wcol->item[2], 32); 00733 widget_trias_draw(&wtb->tria1); 00734 } 00735 if(wtb->tria2.tot) { 00736 glColor4ub(wcol->item[0], wcol->item[1], wcol->item[2], 32); 00737 widget_trias_draw(&wtb->tria2); 00738 } 00739 00740 glTranslatef(-1.0f * jit[j][0], -1.0f * jit[j][1], 0.0f); 00741 } 00742 } 00743 00744 glDisable(GL_BLEND); 00745 00746 } 00747 00748 /* *********************** text/icon ************************************** */ 00749 00750 #define PREVIEW_PAD 4 00751 00752 static void widget_draw_preview(BIFIconID icon, float UNUSED(alpha), rcti *rect) 00753 { 00754 int w, h, size; 00755 00756 if(icon==ICON_NONE) 00757 return; 00758 00759 w = rect->xmax - rect->xmin; 00760 h = rect->ymax - rect->ymin; 00761 size = MIN2(w, h); 00762 size -= PREVIEW_PAD*2; /* padding */ 00763 00764 if(size > 0) { 00765 int x = rect->xmin + w/2 - size/2; 00766 int y = rect->ymin + h/2 - size/2; 00767 00768 UI_icon_draw_preview_aspect_size(x, y, icon, 1.0f, size); 00769 } 00770 } 00771 00772 00773 /* icons have been standardized... and this call draws in untransformed coordinates */ 00774 00775 static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect) 00776 { 00777 int xs=0, ys=0; 00778 float aspect, height; 00779 00780 if (but->flag & UI_ICON_PREVIEW) { 00781 widget_draw_preview(icon, alpha, rect); 00782 return; 00783 } 00784 00785 /* this icon doesn't need draw... */ 00786 if(icon==ICON_BLANK1 && (but->flag & UI_ICON_SUBMENU)==0) return; 00787 00788 /* we need aspect from block, for menus... these buttons are scaled in uiPositionBlock() */ 00789 aspect= but->block->aspect; 00790 if(aspect != but->aspect) { 00791 /* prevent scaling up icon in pupmenu */ 00792 if (aspect < 1.0f) { 00793 height= UI_DPI_ICON_SIZE; 00794 aspect = 1.0f; 00795 00796 } 00797 else 00798 height= UI_DPI_ICON_SIZE/aspect; 00799 } 00800 else 00801 height= UI_DPI_ICON_SIZE; 00802 00803 /* calculate blend color */ 00804 if ELEM4(but->type, TOG, ROW, TOGN, LISTROW) { 00805 if(but->flag & UI_SELECT); 00806 else if(but->flag & UI_ACTIVE); 00807 else alpha= 0.5f; 00808 } 00809 00810 /* extra feature allows more alpha blending */ 00811 if(but->type==LABEL && but->a1==1.0f) alpha *= but->a2; 00812 00813 glEnable(GL_BLEND); 00814 00815 if(icon && icon!=ICON_BLANK1) { 00816 if(but->flag & UI_ICON_LEFT) { 00817 if (but->type==BUT_TOGDUAL) { 00818 if (but->drawstr[0]) { 00819 xs= rect->xmin-1; 00820 } else { 00821 xs= (rect->xmin+rect->xmax- height)/2; 00822 } 00823 } 00824 else if (but->block->flag & UI_BLOCK_LOOP) { 00825 if(but->type==SEARCH_MENU) 00826 xs= rect->xmin+4; 00827 else 00828 xs= rect->xmin+1; 00829 } 00830 else if ((but->type==ICONROW) || (but->type==ICONTEXTROW)) { 00831 xs= rect->xmin+3; 00832 } 00833 else { 00834 xs= rect->xmin+4; 00835 } 00836 ys= (rect->ymin+rect->ymax- height)/2; 00837 } 00838 else { 00839 xs= (rect->xmin+rect->xmax- height)/2; 00840 ys= (rect->ymin+rect->ymax- height)/2; 00841 } 00842 00843 /* to indicate draggable */ 00844 if(but->dragpoin && (but->flag & UI_ACTIVE)) { 00845 float rgb[3]= {1.25f, 1.25f, 1.25f}; 00846 UI_icon_draw_aspect_color(xs, ys, icon, aspect, rgb); 00847 } 00848 else 00849 UI_icon_draw_aspect(xs, ys, icon, aspect, alpha); 00850 } 00851 00852 if(but->flag & UI_ICON_SUBMENU) { 00853 xs= rect->xmax-17; 00854 ys= (rect->ymin+rect->ymax- height)/2; 00855 00856 UI_icon_draw_aspect(xs, ys, ICON_RIGHTARROW_THIN, aspect, alpha); 00857 } 00858 00859 glDisable(GL_BLEND); 00860 } 00861 00862 /* sets but->ofs to make sure text is correctly visible */ 00863 static void ui_text_leftclip(uiFontStyle *fstyle, uiBut *but, rcti *rect) 00864 { 00865 int border= (but->flag & UI_BUT_ALIGN_RIGHT)? 8: 10; 00866 int okwidth= rect->xmax-rect->xmin - border; 00867 00868 if (but->flag & UI_HAS_ICON) okwidth -= UI_DPI_ICON_SIZE; 00869 00870 /* need to set this first */ 00871 uiStyleFontSet(fstyle); 00872 00873 if (fstyle->kerning==1) /* for BLF_width */ 00874 BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT); 00875 00876 /* if text editing we define ofs dynamically */ 00877 if(but->editstr && but->pos >= 0) { 00878 if(but->ofs > but->pos) 00879 but->ofs= but->pos; 00880 } 00881 else but->ofs= 0; 00882 00883 but->strwidth= BLF_width(fstyle->uifont_id, but->drawstr + but->ofs); 00884 00885 while(but->strwidth > okwidth) { 00886 00887 /* textbut exception, clip right when... */ 00888 if(but->editstr && but->pos >= 0) { 00889 float width; 00890 char buf[UI_MAX_DRAW_STR]; 00891 00892 /* copy draw string */ 00893 BLI_strncpy(buf, but->drawstr, sizeof(buf)); 00894 /* string position of cursor */ 00895 buf[but->pos]= 0; 00896 width= BLF_width(fstyle->uifont_id, buf+but->ofs); 00897 00898 /* if cursor is at 20 pixels of right side button we clip left */ 00899 if(width > okwidth-20) 00900 but->ofs++; 00901 else { 00902 /* shift string to the left */ 00903 if(width < 20 && but->ofs > 0) 00904 but->ofs--; 00905 but->drawstr[ strlen(but->drawstr)-1 ]= 0; 00906 } 00907 } 00908 else 00909 but->ofs++; 00910 00911 but->strwidth= BLF_width(fstyle->uifont_id, but->drawstr+but->ofs); 00912 00913 if(but->strwidth < 10) break; 00914 } 00915 00916 if (fstyle->kerning==1) 00917 BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT); 00918 } 00919 00920 static void ui_text_label_rightclip(uiFontStyle *fstyle, uiBut *but, rcti *rect) 00921 { 00922 int border= (but->flag & UI_BUT_ALIGN_RIGHT)? 8: 10; 00923 int okwidth= rect->xmax-rect->xmin - border; 00924 char *cpoin=NULL; 00925 char *cpend = but->drawstr + strlen(but->drawstr); 00926 00927 /* need to set this first */ 00928 uiStyleFontSet(fstyle); 00929 00930 if (fstyle->kerning==1) /* for BLF_width */ 00931 BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT); 00932 00933 but->strwidth= BLF_width(fstyle->uifont_id, but->drawstr); 00934 but->ofs= 0; 00935 00936 /* find the space after ':' separator */ 00937 cpoin= strrchr(but->drawstr, ':'); 00938 00939 if (cpoin && (cpoin < cpend-2)) { 00940 char *cp2 = cpoin; 00941 00942 /* chop off the leading text, starting from the right */ 00943 while (but->strwidth > okwidth && cp2 > but->drawstr) { 00944 /* shift the text after and including cp2 back by 1 char, +1 to include null terminator */ 00945 memmove(cp2-1, cp2, strlen(cp2)+1); 00946 cp2--; 00947 00948 but->strwidth= BLF_width(fstyle->uifont_id, but->drawstr+but->ofs); 00949 if(but->strwidth < 10) break; 00950 } 00951 00952 00953 /* after the leading text is gone, chop off the : and following space, with ofs */ 00954 while ((but->strwidth > okwidth) && (but->ofs < 2)) 00955 { 00956 but->ofs++; 00957 but->strwidth= BLF_width(fstyle->uifont_id, but->drawstr+but->ofs); 00958 if(but->strwidth < 10) break; 00959 } 00960 00961 } 00962 00963 /* once the label's gone, chop off the least significant digits */ 00964 while(but->strwidth > okwidth ) { 00965 int pos= strlen(but->drawstr); 00966 00967 but->drawstr[ pos-1 ] = 0; 00968 pos--; 00969 00970 but->strwidth= BLF_width(fstyle->uifont_id, but->drawstr+but->ofs); 00971 if(but->strwidth < 10) break; 00972 } 00973 00974 if (fstyle->kerning==1) 00975 BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT); 00976 } 00977 00978 00979 static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *but, rcti *rect) 00980 { 00981 // int transopts; 00982 char *cpoin = NULL; 00983 00984 /* for underline drawing */ 00985 float font_xofs, font_yofs; 00986 00987 uiStyleFontSet(fstyle); 00988 00989 if(but->editstr || (but->flag & UI_TEXT_LEFT)) 00990 fstyle->align= UI_STYLE_TEXT_LEFT; 00991 else 00992 fstyle->align= UI_STYLE_TEXT_CENTER; 00993 00994 if (fstyle->kerning==1) /* for BLF_width */ 00995 BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT); 00996 00997 /* text button selection and cursor */ 00998 if(but->editstr && but->pos != -1) { 00999 short t=0, pos=0, ch; 01000 short selsta_tmp, selend_tmp, selsta_draw, selwidth_draw; 01001 01002 if ((but->selend - but->selsta) > 0) { 01003 /* text button selection */ 01004 selsta_tmp = but->selsta; 01005 selend_tmp = but->selend; 01006 01007 if(but->drawstr[0]!=0) { 01008 01009 if (but->selsta >= but->ofs) { 01010 ch= but->drawstr[selsta_tmp]; 01011 but->drawstr[selsta_tmp]= 0; 01012 01013 selsta_draw = BLF_width(fstyle->uifont_id, but->drawstr+but->ofs); 01014 01015 but->drawstr[selsta_tmp]= ch; 01016 } else 01017 selsta_draw = 0; 01018 01019 ch= but->drawstr[selend_tmp]; 01020 but->drawstr[selend_tmp]= 0; 01021 01022 selwidth_draw = BLF_width(fstyle->uifont_id, but->drawstr+but->ofs); 01023 01024 but->drawstr[selend_tmp]= ch; 01025 01026 glColor3ubv((unsigned char*)wcol->item); 01027 glRects(rect->xmin+selsta_draw, rect->ymin+2, rect->xmin+selwidth_draw, rect->ymax-2); 01028 } 01029 } else { 01030 /* text cursor */ 01031 pos= but->pos; 01032 if(pos >= but->ofs) { 01033 if(but->drawstr[0]!=0) { 01034 ch= but->drawstr[pos]; 01035 but->drawstr[pos]= 0; 01036 01037 t= BLF_width(fstyle->uifont_id, but->drawstr+but->ofs) / but->aspect; 01038 01039 but->drawstr[pos]= ch; 01040 } 01041 01042 glColor3f(0.20, 0.6, 0.9); 01043 glRects(rect->xmin+t, rect->ymin+2, rect->xmin+t+2, rect->ymax-2); 01044 } 01045 } 01046 } 01047 01048 if (fstyle->kerning == 1) 01049 BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT); 01050 01051 // ui_rasterpos_safe(x, y, but->aspect); 01052 // if(but->type==IDPOIN) transopts= 0; // no translation, of course! 01053 // else transopts= ui_translate_buttons(); 01054 01055 /* cut string in 2 parts - only for menu entries */ 01056 if((but->block->flag & UI_BLOCK_LOOP)) { 01057 if(ELEM5(but->type, SLI, NUM, TEX, NUMSLI, NUMABS)==0) { 01058 cpoin= strchr(but->drawstr, '|'); 01059 if(cpoin) *cpoin= 0; 01060 } 01061 } 01062 01063 glColor3ubv((unsigned char*)wcol->text); 01064 01065 uiStyleFontDrawExt(fstyle, rect, but->drawstr+but->ofs, &font_xofs, &font_yofs); 01066 01067 if(but->menu_key != '\0') { 01068 char fixedbuf[128]; 01069 char *str; 01070 01071 BLI_strncpy(fixedbuf, but->drawstr + but->ofs, sizeof(fixedbuf)); 01072 01073 str= strchr(fixedbuf, but->menu_key-32); /* upper case */ 01074 if(str==NULL) 01075 str= strchr(fixedbuf, but->menu_key); 01076 01077 if(str) { 01078 int ul_index= -1; 01079 float ul_advance; 01080 01081 ul_index= (int)(str - fixedbuf); 01082 01083 if (fstyle->kerning == 1) { 01084 BLF_enable(fstyle->uifont_id, BLF_KERNING_DEFAULT); 01085 } 01086 01087 fixedbuf[ul_index]= '\0'; 01088 ul_advance= BLF_width(fstyle->uifont_id, fixedbuf); 01089 01090 BLF_position(fstyle->uifont_id, rect->xmin+font_xofs + ul_advance, rect->ymin+font_yofs, 0.0f); 01091 BLF_draw(fstyle->uifont_id, "_", 2); 01092 01093 if (fstyle->kerning == 1) { 01094 BLF_disable(fstyle->uifont_id, BLF_KERNING_DEFAULT); 01095 } 01096 } 01097 } 01098 01099 /* part text right aligned */ 01100 if(cpoin) { 01101 fstyle->align= UI_STYLE_TEXT_RIGHT; 01102 rect->xmax-=5; 01103 uiStyleFontDraw(fstyle, rect, cpoin+1); 01104 *cpoin= '|'; 01105 } 01106 } 01107 01108 /* draws text and icons for buttons */ 01109 static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *but, rcti *rect) 01110 { 01111 01112 if(but==NULL) return; 01113 01114 /* clip but->drawstr to fit in available space */ 01115 if (but->editstr && but->pos >= 0) { 01116 ui_text_leftclip(fstyle, but, rect); 01117 } 01118 else if (ELEM4(but->type, NUM, NUMABS, NUMSLI, SLI)) { 01119 ui_text_label_rightclip(fstyle, but, rect); 01120 } 01121 else if (ELEM(but->type, TEX, SEARCH_MENU)) { 01122 ui_text_leftclip(fstyle, but, rect); 01123 } 01124 else if ((but->block->flag & UI_BLOCK_LOOP) && (but->type == BUT)) { 01125 ui_text_leftclip(fstyle, but, rect); 01126 } 01127 else but->ofs= 0; 01128 01129 /* check for button text label */ 01130 if (but->type == ICONTEXTROW) { 01131 widget_draw_icon(but, (BIFIconID) (but->icon+but->iconadd), 1.0f, rect); 01132 } 01133 else { 01134 01135 if(but->type==BUT_TOGDUAL) { 01136 int dualset= 0; 01137 if(but->pointype==SHO) 01138 dualset= BTST( *(((short *)but->poin)+1), but->bitnr); 01139 else if(but->pointype==INT) 01140 dualset= BTST( *(((int *)but->poin)+1), but->bitnr); 01141 01142 widget_draw_icon(but, ICON_DOT, dualset?1.0f:0.25f, rect); 01143 } 01144 01145 /* If there's an icon too (made with uiDefIconTextBut) then draw the icon 01146 and offset the text label to accommodate it */ 01147 01148 if (but->flag & UI_HAS_ICON) { 01149 widget_draw_icon(but, but->icon+but->iconadd, 1.0f, rect); 01150 01151 rect->xmin += (int)((float)UI_icon_get_width(but->icon+but->iconadd) * UI_DPI_ICON_FAC); 01152 01153 if(but->editstr || (but->flag & UI_TEXT_LEFT)) 01154 rect->xmin += 5; 01155 } 01156 else if((but->flag & UI_TEXT_LEFT)) 01157 rect->xmin += 5; 01158 01159 /* always draw text for textbutton cursor */ 01160 widget_draw_text(fstyle, wcol, but, rect); 01161 01162 } 01163 } 01164 01165 01166 01167 /* *********************** widget types ************************************* */ 01168 01169 01170 /* uiWidgetStateColors 01171 char inner_anim[4]; 01172 char inner_anim_sel[4]; 01173 char inner_key[4]; 01174 char inner_key_sel[4]; 01175 char inner_driven[4]; 01176 char inner_driven_sel[4]; 01177 float blend; 01178 01179 */ 01180 01181 static struct uiWidgetStateColors wcol_state_colors= { 01182 {115, 190, 76, 255}, 01183 {90, 166, 51, 255}, 01184 {240, 235, 100, 255}, 01185 {215, 211, 75, 255}, 01186 {180, 0, 255, 255}, 01187 {153, 0, 230, 255}, 01188 0.5f, 0.0f 01189 }; 01190 01191 /* uiWidgetColors 01192 float outline[3]; 01193 float inner[4]; 01194 float inner_sel[4]; 01195 float item[3]; 01196 float text[3]; 01197 float text_sel[3]; 01198 01199 short shaded; 01200 float shadetop, shadedown; 01201 */ 01202 01203 static struct uiWidgetColors wcol_num= { 01204 {25, 25, 25, 255}, 01205 {180, 180, 180, 255}, 01206 {153, 153, 153, 255}, 01207 {90, 90, 90, 255}, 01208 01209 {0, 0, 0, 255}, 01210 {255, 255, 255, 255}, 01211 01212 1, 01213 -20, 0 01214 }; 01215 01216 static struct uiWidgetColors wcol_numslider= { 01217 {25, 25, 25, 255}, 01218 {180, 180, 180, 255}, 01219 {153, 153, 153, 255}, 01220 {128, 128, 128, 255}, 01221 01222 {0, 0, 0, 255}, 01223 {255, 255, 255, 255}, 01224 01225 1, 01226 -20, 0 01227 }; 01228 01229 static struct uiWidgetColors wcol_text= { 01230 {25, 25, 25, 255}, 01231 {153, 153, 153, 255}, 01232 {153, 153, 153, 255}, 01233 {90, 90, 90, 255}, 01234 01235 {0, 0, 0, 255}, 01236 {255, 255, 255, 255}, 01237 01238 1, 01239 0, 25 01240 }; 01241 01242 static struct uiWidgetColors wcol_option= { 01243 {0, 0, 0, 255}, 01244 {70, 70, 70, 255}, 01245 {70, 70, 70, 255}, 01246 {255, 255, 255, 255}, 01247 01248 {0, 0, 0, 255}, 01249 {255, 255, 255, 255}, 01250 01251 1, 01252 15, -15 01253 }; 01254 01255 /* button that shows popup */ 01256 static struct uiWidgetColors wcol_menu= { 01257 {0, 0, 0, 255}, 01258 {70, 70, 70, 255}, 01259 {70, 70, 70, 255}, 01260 {255, 255, 255, 255}, 01261 01262 {255, 255, 255, 255}, 01263 {204, 204, 204, 255}, 01264 01265 1, 01266 15, -15 01267 }; 01268 01269 /* button that starts pulldown */ 01270 static struct uiWidgetColors wcol_pulldown= { 01271 {0, 0, 0, 255}, 01272 {63, 63, 63, 255}, 01273 {86, 128, 194, 255}, 01274 {255, 255, 255, 255}, 01275 01276 {0, 0, 0, 255}, 01277 {0, 0, 0, 255}, 01278 01279 0, 01280 25, -20 01281 }; 01282 01283 /* button inside menu */ 01284 static struct uiWidgetColors wcol_menu_item= { 01285 {0, 0, 0, 255}, 01286 {0, 0, 0, 0}, 01287 {86, 128, 194, 255}, 01288 {255, 255, 255, 255}, 01289 01290 {255, 255, 255, 255}, 01291 {0, 0, 0, 255}, 01292 01293 1, 01294 38, 0 01295 }; 01296 01297 /* backdrop menu + title text color */ 01298 static struct uiWidgetColors wcol_menu_back= { 01299 {0, 0, 0, 255}, 01300 {25, 25, 25, 230}, 01301 {45, 45, 45, 230}, 01302 {100, 100, 100, 255}, 01303 01304 {160, 160, 160, 255}, 01305 {255, 255, 255, 255}, 01306 01307 0, 01308 25, -20 01309 }; 01310 01311 01312 static struct uiWidgetColors wcol_radio= { 01313 {0, 0, 0, 255}, 01314 {70, 70, 70, 255}, 01315 {86, 128, 194, 255}, 01316 {255, 255, 255, 255}, 01317 01318 {255, 255, 255, 255}, 01319 {0, 0, 0, 255}, 01320 01321 1, 01322 15, -15 01323 }; 01324 01325 static struct uiWidgetColors wcol_regular= { 01326 {25, 25, 25, 255}, 01327 {153, 153, 153, 255}, 01328 {100, 100, 100, 255}, 01329 {25, 25, 25, 255}, 01330 01331 {0, 0, 0, 255}, 01332 {255, 255, 255, 255}, 01333 01334 0, 01335 0, 0 01336 }; 01337 01338 static struct uiWidgetColors wcol_tool= { 01339 {25, 25, 25, 255}, 01340 {153, 153, 153, 255}, 01341 {100, 100, 100, 255}, 01342 {25, 25, 25, 255}, 01343 01344 {0, 0, 0, 255}, 01345 {255, 255, 255, 255}, 01346 01347 1, 01348 15, -15 01349 }; 01350 01351 static struct uiWidgetColors wcol_box= { 01352 {25, 25, 25, 255}, 01353 {128, 128, 128, 255}, 01354 {100, 100, 100, 255}, 01355 {25, 25, 25, 255}, 01356 01357 {0, 0, 0, 255}, 01358 {255, 255, 255, 255}, 01359 01360 0, 01361 0, 0 01362 }; 01363 01364 static struct uiWidgetColors wcol_toggle= { 01365 {25, 25, 25, 255}, 01366 {153, 153, 153, 255}, 01367 {100, 100, 100, 255}, 01368 {25, 25, 25, 255}, 01369 01370 {0, 0, 0, 255}, 01371 {255, 255, 255, 255}, 01372 01373 0, 01374 0, 0 01375 }; 01376 01377 static struct uiWidgetColors wcol_scroll= { 01378 {50, 50, 50, 180}, 01379 {80, 80, 80, 180}, 01380 {100, 100, 100, 180}, 01381 {128, 128, 128, 255}, 01382 01383 {0, 0, 0, 255}, 01384 {255, 255, 255, 255}, 01385 01386 1, 01387 5, -5 01388 }; 01389 01390 static struct uiWidgetColors wcol_progress= { 01391 {0, 0, 0, 255}, 01392 {190, 190, 190, 255}, 01393 {100, 100, 100, 180}, 01394 {68, 68, 68, 255}, 01395 01396 {0, 0, 0, 255}, 01397 {255, 255, 255, 255}, 01398 01399 0, 01400 0, 0 01401 }; 01402 01403 static struct uiWidgetColors wcol_list_item= { 01404 {0, 0, 0, 255}, 01405 {0, 0, 0, 0}, 01406 {86, 128, 194, 255}, 01407 {0, 0, 0, 255}, 01408 01409 {0, 0, 0, 255}, 01410 {0, 0, 0, 255}, 01411 01412 0, 01413 0, 0 01414 }; 01415 01416 /* free wcol struct to play with */ 01417 static struct uiWidgetColors wcol_tmp= { 01418 {0, 0, 0, 255}, 01419 {128, 128, 128, 255}, 01420 {100, 100, 100, 255}, 01421 {25, 25, 25, 255}, 01422 01423 {0, 0, 0, 255}, 01424 {255, 255, 255, 255}, 01425 01426 0, 01427 0, 0 01428 }; 01429 01430 01431 /* called for theme init (new theme) and versions */ 01432 void ui_widget_color_init(ThemeUI *tui) 01433 { 01434 tui->wcol_regular= wcol_regular; 01435 tui->wcol_tool= wcol_tool; 01436 tui->wcol_text= wcol_text; 01437 tui->wcol_radio= wcol_radio; 01438 tui->wcol_option= wcol_option; 01439 tui->wcol_toggle= wcol_toggle; 01440 tui->wcol_num= wcol_num; 01441 tui->wcol_numslider= wcol_numslider; 01442 tui->wcol_menu= wcol_menu; 01443 tui->wcol_pulldown= wcol_pulldown; 01444 tui->wcol_menu_back= wcol_menu_back; 01445 tui->wcol_menu_item= wcol_menu_item; 01446 tui->wcol_box= wcol_box; 01447 tui->wcol_scroll= wcol_scroll; 01448 tui->wcol_list_item= wcol_list_item; 01449 tui->wcol_progress= wcol_progress; 01450 01451 tui->wcol_state= wcol_state_colors; 01452 } 01453 01454 /* ************ button callbacks, state ***************** */ 01455 01456 static void widget_state_blend(char *cp, const char *cpstate, const float fac) 01457 { 01458 if(fac != 0.0f) { 01459 cp[0]= (int)((1.0f-fac)*cp[0] + fac*cpstate[0]); 01460 cp[1]= (int)((1.0f-fac)*cp[1] + fac*cpstate[1]); 01461 cp[2]= (int)((1.0f-fac)*cp[2] + fac*cpstate[2]); 01462 } 01463 } 01464 01465 /* copy colors from theme, and set changes in it based on state */ 01466 static void widget_state(uiWidgetType *wt, int state) 01467 { 01468 uiWidgetStateColors *wcol_state= wt->wcol_state; 01469 01470 wt->wcol= *(wt->wcol_theme); 01471 01472 if(state & UI_SELECT) { 01473 QUATCOPY(wt->wcol.inner, wt->wcol.inner_sel) 01474 01475 if(state & UI_BUT_ANIMATED_KEY) 01476 widget_state_blend(wt->wcol.inner, wcol_state->inner_key_sel, wcol_state->blend); 01477 else if(state & UI_BUT_ANIMATED) 01478 widget_state_blend(wt->wcol.inner, wcol_state->inner_anim_sel, wcol_state->blend); 01479 else if(state & UI_BUT_DRIVEN) 01480 widget_state_blend(wt->wcol.inner, wcol_state->inner_driven_sel, wcol_state->blend); 01481 01482 VECCOPY(wt->wcol.text, wt->wcol.text_sel); 01483 01484 if(state & UI_SELECT) 01485 SWAP(short, wt->wcol.shadetop, wt->wcol.shadedown); 01486 } 01487 else { 01488 if(state & UI_BUT_ANIMATED_KEY) 01489 widget_state_blend(wt->wcol.inner, wcol_state->inner_key, wcol_state->blend); 01490 else if(state & UI_BUT_ANIMATED) 01491 widget_state_blend(wt->wcol.inner, wcol_state->inner_anim, wcol_state->blend); 01492 else if(state & UI_BUT_DRIVEN) 01493 widget_state_blend(wt->wcol.inner, wcol_state->inner_driven, wcol_state->blend); 01494 01495 if(state & UI_ACTIVE) { /* mouse over? */ 01496 wt->wcol.inner[0]= wt->wcol.inner[0]>=240? 255 : wt->wcol.inner[0]+15; 01497 wt->wcol.inner[1]= wt->wcol.inner[1]>=240? 255 : wt->wcol.inner[1]+15; 01498 wt->wcol.inner[2]= wt->wcol.inner[2]>=240? 255 : wt->wcol.inner[2]+15; 01499 } 01500 } 01501 01502 if(state & UI_BUT_REDALERT) { 01503 char red[4]= {255, 0, 0}; 01504 widget_state_blend(wt->wcol.inner, red, 0.4f); 01505 } 01506 } 01507 01508 /* sliders use special hack which sets 'item' as inner when drawing filling */ 01509 static void widget_state_numslider(uiWidgetType *wt, int state) 01510 { 01511 uiWidgetStateColors *wcol_state= wt->wcol_state; 01512 float blend= wcol_state->blend - 0.2f; // XXX special tweak to make sure that bar will still be visible 01513 01514 /* call this for option button */ 01515 widget_state(wt, state); 01516 01517 /* now, set the inner-part so that it reflects state settings too */ 01518 // TODO: maybe we should have separate settings for the blending colors used for this case? 01519 if(state & UI_SELECT) { 01520 01521 if(state & UI_BUT_ANIMATED_KEY) 01522 widget_state_blend(wt->wcol.item, wcol_state->inner_key_sel, blend); 01523 else if(state & UI_BUT_ANIMATED) 01524 widget_state_blend(wt->wcol.item, wcol_state->inner_anim_sel, blend); 01525 else if(state & UI_BUT_DRIVEN) 01526 widget_state_blend(wt->wcol.item, wcol_state->inner_driven_sel, blend); 01527 01528 if(state & UI_SELECT) 01529 SWAP(short, wt->wcol.shadetop, wt->wcol.shadedown); 01530 } 01531 else { 01532 if(state & UI_BUT_ANIMATED_KEY) 01533 widget_state_blend(wt->wcol.item, wcol_state->inner_key, blend); 01534 else if(state & UI_BUT_ANIMATED) 01535 widget_state_blend(wt->wcol.item, wcol_state->inner_anim, blend); 01536 else if(state & UI_BUT_DRIVEN) 01537 widget_state_blend(wt->wcol.item, wcol_state->inner_driven, blend); 01538 } 01539 } 01540 01541 /* labels use theme colors for text */ 01542 static void widget_state_label(uiWidgetType *wt, int state) 01543 { 01544 /* call this for option button */ 01545 widget_state(wt, state); 01546 01547 if(state & UI_SELECT) 01548 UI_GetThemeColor4ubv(TH_TEXT_HI, (unsigned char *)wt->wcol.text); 01549 else 01550 UI_GetThemeColor4ubv(TH_TEXT, (unsigned char *)wt->wcol.text); 01551 01552 } 01553 01554 /* labels use theme colors for text */ 01555 static void widget_state_option_menu(uiWidgetType *wt, int state) 01556 { 01557 01558 /* call this for option button */ 01559 widget_state(wt, state); 01560 01561 /* if not selected we get theme from menu back */ 01562 if(state & UI_SELECT) 01563 UI_GetThemeColor4ubv(TH_TEXT_HI, (unsigned char *)wt->wcol.text); 01564 else { 01565 bTheme *btheme= U.themes.first; /* XXX */ 01566 01567 VECCOPY(wt->wcol.text, btheme->tui.wcol_menu_back.text); 01568 } 01569 } 01570 01571 01572 static void widget_state_nothing(uiWidgetType *wt, int UNUSED(state)) 01573 { 01574 wt->wcol= *(wt->wcol_theme); 01575 } 01576 01577 /* special case, button that calls pulldown */ 01578 static void widget_state_pulldown(uiWidgetType *wt, int state) 01579 { 01580 wt->wcol= *(wt->wcol_theme); 01581 01582 QUATCOPY(wt->wcol.inner, wt->wcol.inner_sel); 01583 VECCOPY(wt->wcol.outline, wt->wcol.inner); 01584 01585 if(state & UI_ACTIVE) 01586 VECCOPY(wt->wcol.text, wt->wcol.text_sel); 01587 } 01588 01589 /* special case, menu items */ 01590 static void widget_state_menu_item(uiWidgetType *wt, int state) 01591 { 01592 wt->wcol= *(wt->wcol_theme); 01593 01594 if(state & (UI_BUT_DISABLED|UI_BUT_INACTIVE)) { 01595 wt->wcol.text[0]= 0.5f*(wt->wcol.text[0]+wt->wcol.text_sel[0]); 01596 wt->wcol.text[1]= 0.5f*(wt->wcol.text[1]+wt->wcol.text_sel[1]); 01597 wt->wcol.text[2]= 0.5f*(wt->wcol.text[2]+wt->wcol.text_sel[2]); 01598 } 01599 else if(state & UI_ACTIVE) { 01600 QUATCOPY(wt->wcol.inner, wt->wcol.inner_sel); 01601 VECCOPY(wt->wcol.text, wt->wcol.text_sel); 01602 } 01603 } 01604 01605 01606 /* ************ menu backdrop ************************* */ 01607 01608 /* outside of rect, rad to left/bottom/right */ 01609 static void widget_softshadow(rcti *rect, int roundboxalign, float radin, float radout) 01610 { 01611 uiWidgetBase wtb; 01612 rcti rect1= *rect; 01613 float alpha, alphastep; 01614 int step, tot, a; 01615 01616 /* prevent tooltips to not show round shadow */ 01617 if( 2.0f*radout > 0.2f*(rect1.ymax-rect1.ymin) ) 01618 rect1.ymax -= 0.2f*(rect1.ymax-rect1.ymin); 01619 else 01620 rect1.ymax -= 2.0f*radout; 01621 01622 /* inner part */ 01623 tot= round_box_shadow_edges(wtb.inner_v, &rect1, radin, roundboxalign & 12, 0.0f); 01624 01625 /* inverse linear shadow alpha */ 01626 alpha= 0.15; 01627 alphastep= 0.67; 01628 01629 for(step= 1; step<=radout; step++, alpha*=alphastep) { 01630 round_box_shadow_edges(wtb.outer_v, &rect1, radin, 15, (float)step); 01631 01632 glColor4f(0.0f, 0.0f, 0.0f, alpha); 01633 01634 glBegin(GL_QUAD_STRIP); 01635 for(a=0; a<tot; a++) { 01636 glVertex2fv(wtb.outer_v[a]); 01637 glVertex2fv(wtb.inner_v[a]); 01638 } 01639 glEnd(); 01640 } 01641 01642 } 01643 01644 static void widget_menu_back(uiWidgetColors *wcol, rcti *rect, int flag, int direction) 01645 { 01646 uiWidgetBase wtb; 01647 int roundboxalign= 15; 01648 01649 widget_init(&wtb); 01650 01651 /* menu is 2nd level or deeper */ 01652 if (flag & UI_BLOCK_POPUP) { 01653 //rect->ymin -= 4.0; 01654 //rect->ymax += 4.0; 01655 } 01656 else if (direction == UI_DOWN) { 01657 roundboxalign= 12; 01658 rect->ymin -= 4.0; 01659 } 01660 else if (direction == UI_TOP) { 01661 roundboxalign= 3; 01662 rect->ymax += 4.0; 01663 } 01664 01665 glEnable(GL_BLEND); 01666 widget_softshadow(rect, roundboxalign, 5.0f, 8.0f); 01667 01668 round_box_edges(&wtb, roundboxalign, rect, 5.0f); 01669 wtb.emboss= 0; 01670 widgetbase_draw(&wtb, wcol); 01671 01672 glDisable(GL_BLEND); 01673 } 01674 01675 01676 static void ui_hsv_cursor(float x, float y) 01677 { 01678 01679 glPushMatrix(); 01680 glTranslatef(x, y, 0.0f); 01681 01682 glColor3f(1.0f, 1.0f, 1.0f); 01683 glutil_draw_filled_arc(0.0f, M_PI*2.0, 3.0f, 8); 01684 01685 glEnable(GL_BLEND); 01686 glEnable(GL_LINE_SMOOTH ); 01687 glColor3f(0.0f, 0.0f, 0.0f); 01688 glutil_draw_lined_arc(0.0f, M_PI*2.0, 3.0f, 12); 01689 glDisable(GL_BLEND); 01690 glDisable(GL_LINE_SMOOTH ); 01691 01692 glPopMatrix(); 01693 01694 } 01695 01696 void ui_hsvcircle_vals_from_pos(float *valrad, float *valdist, rcti *rect, float mx, float my) 01697 { 01698 /* duplication of code... well, simple is better now */ 01699 float centx= (float)(rect->xmin + rect->xmax)/2; 01700 float centy= (float)(rect->ymin + rect->ymax)/2; 01701 float radius, dist; 01702 01703 if( rect->xmax-rect->xmin > rect->ymax-rect->ymin ) 01704 radius= (float)(rect->ymax - rect->ymin)/2; 01705 else 01706 radius= (float)(rect->xmax - rect->xmin)/2; 01707 01708 mx-= centx; 01709 my-= centy; 01710 dist= sqrt( mx*mx + my*my); 01711 if(dist < radius) 01712 *valdist= dist/radius; 01713 else 01714 *valdist= 1.0f; 01715 01716 *valrad= atan2f(mx, my)/(2.0f*(float)M_PI) + 0.5f; 01717 } 01718 01719 static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, rcti *rect) 01720 { 01721 /* gouraud triangle fan */ 01722 float radstep, ang= 0.0f; 01723 float centx, centy, radius; 01724 float rgb[3], hsvo[3], hsv[3], col[3], colcent[3]; 01725 int a, tot= 32; 01726 int color_profile = but->block->color_profile; 01727 01728 if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) 01729 color_profile = BLI_PR_NONE; 01730 01731 radstep= 2.0f*(float)M_PI/(float)tot; 01732 centx= (float)(rect->xmin + rect->xmax)/2; 01733 centy= (float)(rect->ymin + rect->ymax)/2; 01734 01735 if( rect->xmax-rect->xmin > rect->ymax-rect->ymin ) 01736 radius= (float)(rect->ymax - rect->ymin)/2; 01737 else 01738 radius= (float)(rect->xmax - rect->xmin)/2; 01739 01740 /* color */ 01741 ui_get_but_vectorf(but, rgb); 01742 copy_v3_v3(hsv, ui_block_hsv_get(but->block)); 01743 rgb_to_hsv_compat(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); 01744 copy_v3_v3(hsvo, hsv); 01745 01746 /* exception: if 'lock' is set 01747 * lock the value of the color wheel to 1. 01748 * Useful for color correction tools where you're only interested in hue. */ 01749 if (but->flag & UI_BUT_COLOR_LOCK) 01750 hsv[2] = 1.f; 01751 else if (color_profile) 01752 hsv[2] = linearrgb_to_srgb(hsv[2]); 01753 01754 hsv_to_rgb(0.f, 0.f, hsv[2], colcent, colcent+1, colcent+2); 01755 01756 glShadeModel(GL_SMOOTH); 01757 01758 glBegin(GL_TRIANGLE_FAN); 01759 glColor3fv(colcent); 01760 glVertex2f( centx, centy); 01761 01762 for(a=0; a<=tot; a++, ang+=radstep) { 01763 float si= sin(ang); 01764 float co= cos(ang); 01765 01766 ui_hsvcircle_vals_from_pos(hsv, hsv+1, rect, centx + co*radius, centy + si*radius); 01767 CLAMP(hsv[2], 0.0f, 1.0f); /* for display only */ 01768 01769 hsv_to_rgb(hsv[0], hsv[1], hsv[2], col, col+1, col+2); 01770 glColor3fv(col); 01771 glVertex2f( centx + co*radius, centy + si*radius); 01772 } 01773 glEnd(); 01774 01775 glShadeModel(GL_FLAT); 01776 01777 /* fully rounded outline */ 01778 glPushMatrix(); 01779 glTranslatef(centx, centy, 0.0f); 01780 glEnable(GL_BLEND); 01781 glEnable(GL_LINE_SMOOTH ); 01782 glColor3ubv((unsigned char*)wcol->outline); 01783 glutil_draw_lined_arc(0.0f, M_PI*2.0, radius, tot + 1); 01784 glDisable(GL_BLEND); 01785 glDisable(GL_LINE_SMOOTH ); 01786 glPopMatrix(); 01787 01788 /* cursor */ 01789 ang= 2.0f*(float)M_PI*hsvo[0] + 0.5f*(float)M_PI; 01790 01791 if(but->flag & UI_BUT_COLOR_CUBIC) 01792 radius= (1.0f - powf(1.0f - hsvo[1], 3.0f)) *radius; 01793 else 01794 radius= hsvo[1] * radius; 01795 01796 ui_hsv_cursor(centx + cosf(-ang)*radius, centy + sinf(-ang)*radius); 01797 01798 } 01799 01800 /* ************ custom buttons, old stuff ************** */ 01801 01802 /* draws in resolution of 20x4 colors */ 01803 void ui_draw_gradient(rcti *rect, float *hsv, int type, float alpha) 01804 { 01805 int a; 01806 float h= hsv[0], s= hsv[1], v= hsv[2]; 01807 float dx, dy, sx1, sx2, sy; 01808 float col0[4][3]; // left half, rect bottom to top 01809 float col1[4][3]; // right half, rect bottom to top 01810 01811 /* draw series of gouraud rects */ 01812 glShadeModel(GL_SMOOTH); 01813 01814 switch(type) { 01815 case UI_GRAD_SV: 01816 hsv_to_rgb(h, 0.0, 0.0, &col1[0][0], &col1[0][1], &col1[0][2]); 01817 hsv_to_rgb(h, 0.333, 0.0, &col1[1][0], &col1[1][1], &col1[1][2]); 01818 hsv_to_rgb(h, 0.666, 0.0, &col1[2][0], &col1[2][1], &col1[2][2]); 01819 hsv_to_rgb(h, 1.0, 0.0, &col1[3][0], &col1[3][1], &col1[3][2]); 01820 break; 01821 case UI_GRAD_HV: 01822 hsv_to_rgb(0.0, s, 0.0, &col1[0][0], &col1[0][1], &col1[0][2]); 01823 hsv_to_rgb(0.0, s, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]); 01824 hsv_to_rgb(0.0, s, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]); 01825 hsv_to_rgb(0.0, s, 1.0, &col1[3][0], &col1[3][1], &col1[3][2]); 01826 break; 01827 case UI_GRAD_HS: 01828 hsv_to_rgb(0.0, 0.0, v, &col1[0][0], &col1[0][1], &col1[0][2]); 01829 hsv_to_rgb(0.0, 0.333, v, &col1[1][0], &col1[1][1], &col1[1][2]); 01830 hsv_to_rgb(0.0, 0.666, v, &col1[2][0], &col1[2][1], &col1[2][2]); 01831 hsv_to_rgb(0.0, 1.0, v, &col1[3][0], &col1[3][1], &col1[3][2]); 01832 break; 01833 case UI_GRAD_H: 01834 hsv_to_rgb(0.0, 1.0, 1.0, &col1[0][0], &col1[0][1], &col1[0][2]); 01835 VECCOPY(col1[1], col1[0]); 01836 VECCOPY(col1[2], col1[0]); 01837 VECCOPY(col1[3], col1[0]); 01838 break; 01839 case UI_GRAD_S: 01840 hsv_to_rgb(1.0, 0.0, 1.0, &col1[1][0], &col1[1][1], &col1[1][2]); 01841 VECCOPY(col1[0], col1[1]); 01842 VECCOPY(col1[2], col1[1]); 01843 VECCOPY(col1[3], col1[1]); 01844 break; 01845 case UI_GRAD_V: 01846 hsv_to_rgb(1.0, 1.0, 0.0, &col1[2][0], &col1[2][1], &col1[2][2]); 01847 VECCOPY(col1[0], col1[2]); 01848 VECCOPY(col1[1], col1[2]); 01849 VECCOPY(col1[3], col1[2]); 01850 break; 01851 default: 01852 assert(!"invalid 'type' argument"); 01853 hsv_to_rgb(1.0, 1.0, 1.0, &col1[2][0], &col1[2][1], &col1[2][2]); 01854 VECCOPY(col1[0], col1[2]); 01855 VECCOPY(col1[1], col1[2]); 01856 VECCOPY(col1[3], col1[2]); 01857 } 01858 01859 /* old below */ 01860 01861 for(dx=0.0f; dx<1.0f; dx+= 0.05f) { 01862 // previous color 01863 VECCOPY(col0[0], col1[0]); 01864 VECCOPY(col0[1], col1[1]); 01865 VECCOPY(col0[2], col1[2]); 01866 VECCOPY(col0[3], col1[3]); 01867 01868 // new color 01869 switch(type) { 01870 case UI_GRAD_SV: 01871 hsv_to_rgb(h, 0.0, dx, &col1[0][0], &col1[0][1], &col1[0][2]); 01872 hsv_to_rgb(h, 0.333, dx, &col1[1][0], &col1[1][1], &col1[1][2]); 01873 hsv_to_rgb(h, 0.666, dx, &col1[2][0], &col1[2][1], &col1[2][2]); 01874 hsv_to_rgb(h, 1.0, dx, &col1[3][0], &col1[3][1], &col1[3][2]); 01875 break; 01876 case UI_GRAD_HV: 01877 hsv_to_rgb(dx, s, 0.0, &col1[0][0], &col1[0][1], &col1[0][2]); 01878 hsv_to_rgb(dx, s, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]); 01879 hsv_to_rgb(dx, s, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]); 01880 hsv_to_rgb(dx, s, 1.0, &col1[3][0], &col1[3][1], &col1[3][2]); 01881 break; 01882 case UI_GRAD_HS: 01883 hsv_to_rgb(dx, 0.0, v, &col1[0][0], &col1[0][1], &col1[0][2]); 01884 hsv_to_rgb(dx, 0.333, v, &col1[1][0], &col1[1][1], &col1[1][2]); 01885 hsv_to_rgb(dx, 0.666, v, &col1[2][0], &col1[2][1], &col1[2][2]); 01886 hsv_to_rgb(dx, 1.0, v, &col1[3][0], &col1[3][1], &col1[3][2]); 01887 break; 01888 case UI_GRAD_H: 01889 hsv_to_rgb(dx, 1.0, 1.0, &col1[0][0], &col1[0][1], &col1[0][2]); 01890 VECCOPY(col1[1], col1[0]); 01891 VECCOPY(col1[2], col1[0]); 01892 VECCOPY(col1[3], col1[0]); 01893 break; 01894 case UI_GRAD_S: 01895 hsv_to_rgb(h, dx, 1.0, &col1[1][0], &col1[1][1], &col1[1][2]); 01896 VECCOPY(col1[0], col1[1]); 01897 VECCOPY(col1[2], col1[1]); 01898 VECCOPY(col1[3], col1[1]); 01899 break; 01900 case UI_GRAD_V: 01901 hsv_to_rgb(h, 1.0, dx, &col1[2][0], &col1[2][1], &col1[2][2]); 01902 VECCOPY(col1[0], col1[2]); 01903 VECCOPY(col1[1], col1[2]); 01904 VECCOPY(col1[3], col1[2]); 01905 break; 01906 } 01907 01908 // rect 01909 sx1= rect->xmin + dx*(rect->xmax-rect->xmin); 01910 sx2= rect->xmin + (dx+0.05f)*(rect->xmax-rect->xmin); 01911 sy= rect->ymin; 01912 dy= (rect->ymax-rect->ymin)/3.0; 01913 01914 glBegin(GL_QUADS); 01915 for(a=0; a<3; a++, sy+=dy) { 01916 glColor4f(col0[a][0], col0[a][1], col0[a][2], alpha); 01917 glVertex2f(sx1, sy); 01918 01919 glColor4f(col1[a][0], col1[a][1], col1[a][2], alpha); 01920 glVertex2f(sx2, sy); 01921 01922 glColor4f(col1[a+1][0], col1[a+1][1], col1[a+1][2], alpha); 01923 glVertex2f(sx2, sy+dy); 01924 01925 glColor4f(col0[a+1][0], col0[a+1][1], col0[a+1][2], alpha); 01926 glVertex2f(sx1, sy+dy); 01927 } 01928 glEnd(); 01929 } 01930 01931 glShadeModel(GL_FLAT); 01932 01933 } 01934 01935 01936 01937 static void ui_draw_but_HSVCUBE(uiBut *but, rcti *rect) 01938 { 01939 float rgb[3], h,s,v; 01940 float x=0.0f, y=0.0f; 01941 float *hsv= ui_block_hsv_get(but->block); 01942 float hsvn[3]; 01943 01944 h= hsv[0]; 01945 s= hsv[1]; 01946 v= hsv[2]; 01947 01948 ui_get_but_vectorf(but, rgb); 01949 rgb_to_hsv_compat(rgb[0], rgb[1], rgb[2], &h, &s, &v); 01950 01951 hsvn[0]= h; 01952 hsvn[1]= s; 01953 hsvn[2]= v; 01954 01955 ui_draw_gradient(rect, hsvn, but->a1, 1.f); 01956 01957 switch((int)but->a1) { 01958 case UI_GRAD_SV: 01959 x= v; y= s; break; 01960 case UI_GRAD_HV: 01961 x= h; y= v; break; 01962 case UI_GRAD_HS: 01963 x= h; y= s; break; 01964 case UI_GRAD_H: 01965 x= h; y= 0.5; break; 01966 case UI_GRAD_S: 01967 x= s; y= 0.5; break; 01968 case UI_GRAD_V: 01969 x= v; y= 0.5; break; 01970 } 01971 01972 /* cursor */ 01973 x= rect->xmin + x*(rect->xmax-rect->xmin); 01974 y= rect->ymin + y*(rect->ymax-rect->ymin); 01975 CLAMP(x, rect->xmin+3.0f, rect->xmax-3.0f); 01976 CLAMP(y, rect->ymin+3.0f, rect->ymax-3.0f); 01977 01978 ui_hsv_cursor(x, y); 01979 01980 /* outline */ 01981 glColor3ub(0, 0, 0); 01982 fdrawbox((rect->xmin), (rect->ymin), (rect->xmax), (rect->ymax)); 01983 } 01984 01985 /* vertical 'value' slider, using new widget code */ 01986 static void ui_draw_but_HSV_v(uiBut *but, rcti *rect) 01987 { 01988 uiWidgetBase wtb; 01989 float rad= 0.5f*(rect->xmax - rect->xmin); 01990 float x, y; 01991 float rgb[3], hsv[3], v, range; 01992 int color_profile = but->block->color_profile; 01993 01994 if (but->rnaprop && RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) 01995 color_profile = BLI_PR_NONE; 01996 01997 ui_get_but_vectorf(but, rgb); 01998 rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2); 01999 v = hsv[2]; 02000 02001 if (color_profile) 02002 v = linearrgb_to_srgb(v); 02003 02004 /* map v from property range to [0,1] */ 02005 range = but->softmax - but->softmin; 02006 v = (v - but->softmin)/range; 02007 02008 widget_init(&wtb); 02009 02010 /* fully rounded */ 02011 round_box_edges(&wtb, 15, rect, rad); 02012 02013 /* setup temp colors */ 02014 wcol_tmp.outline[0]= wcol_tmp.outline[1]= wcol_tmp.outline[2]= 0; 02015 wcol_tmp.inner[0]= wcol_tmp.inner[1]= wcol_tmp.inner[2]= 128; 02016 wcol_tmp.shadetop= 127; 02017 wcol_tmp.shadedown= -128; 02018 wcol_tmp.shaded= 1; 02019 02020 widgetbase_draw(&wtb, &wcol_tmp); 02021 02022 /* cursor */ 02023 x= rect->xmin + 0.5f * (rect->xmax-rect->xmin); 02024 y= rect->ymin + v * (rect->ymax-rect->ymin); 02025 CLAMP(y, rect->ymin+3.0f, rect->ymax-3.0f); 02026 02027 ui_hsv_cursor(x, y); 02028 02029 } 02030 02031 02032 /* ************ separator, for menus etc ***************** */ 02033 static void ui_draw_separator(rcti *rect, uiWidgetColors *wcol) 02034 { 02035 int y = rect->ymin + (rect->ymax - rect->ymin)/2 - 1; 02036 unsigned char col[4]; 02037 02038 col[0] = wcol->text[0]; 02039 col[1] = wcol->text[1]; 02040 col[2] = wcol->text[2]; 02041 col[3] = 7; 02042 02043 glEnable(GL_BLEND); 02044 glColor4ubv(col); 02045 sdrawline(rect->xmin, y, rect->xmax, y); 02046 glDisable(GL_BLEND); 02047 } 02048 02049 /* ************ button callbacks, draw ***************** */ 02050 02051 static void widget_numbut(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign) 02052 { 02053 uiWidgetBase wtb; 02054 float rad= 0.5f*(rect->ymax - rect->ymin); 02055 float textofs = rad*0.75f; 02056 02057 if(state & UI_SELECT) 02058 SWAP(short, wcol->shadetop, wcol->shadedown); 02059 02060 widget_init(&wtb); 02061 02062 /* fully rounded */ 02063 round_box_edges(&wtb, roundboxalign, rect, rad); 02064 02065 /* decoration */ 02066 if(!(state & UI_TEXTINPUT)) { 02067 widget_num_tria(&wtb.tria1, rect, 0.6f, 'l'); 02068 widget_num_tria(&wtb.tria2, rect, 0.6f, 'r'); 02069 } 02070 02071 widgetbase_draw(&wtb, wcol); 02072 02073 /* text space */ 02074 rect->xmin += textofs; 02075 rect->xmax -= textofs; 02076 } 02077 02078 //static int ui_link_bezier_points(rcti *rect, float coord_array[][2], int resol) 02079 int ui_link_bezier_points(rcti *rect, float coord_array[][2], int resol) 02080 { 02081 float dist, vec[4][2]; 02082 02083 vec[0][0]= rect->xmin; 02084 vec[0][1]= rect->ymin; 02085 vec[3][0]= rect->xmax; 02086 vec[3][1]= rect->ymax; 02087 02088 dist= 0.5f*ABS(vec[0][0] - vec[3][0]); 02089 02090 vec[1][0]= vec[0][0]+dist; 02091 vec[1][1]= vec[0][1]; 02092 02093 vec[2][0]= vec[3][0]-dist; 02094 vec[2][1]= vec[3][1]; 02095 02096 forward_diff_bezier(vec[0][0], vec[1][0], vec[2][0], vec[3][0], coord_array[0], resol, sizeof(float)*2); 02097 forward_diff_bezier(vec[0][1], vec[1][1], vec[2][1], vec[3][1], coord_array[0]+1, resol, sizeof(float)*2); 02098 02099 return 1; 02100 } 02101 02102 #define LINK_RESOL 24 02103 void ui_draw_link_bezier(rcti *rect) 02104 { 02105 float coord_array[LINK_RESOL+1][2]; 02106 02107 if(ui_link_bezier_points(rect, coord_array, LINK_RESOL)) { 02108 /* we can reuse the dist variable here to increment the GL curve eval amount*/ 02109 // const float dist= 1.0f/(float)LINK_RESOL; // UNUSED 02110 int i; 02111 02112 glEnable(GL_BLEND); 02113 glEnable(GL_LINE_SMOOTH); 02114 02115 glBegin(GL_LINE_STRIP); 02116 for(i=0; i<=LINK_RESOL; i++) { 02117 glVertex2fv(coord_array[i]); 02118 } 02119 glEnd(); 02120 02121 glDisable(GL_BLEND); 02122 glDisable(GL_LINE_SMOOTH); 02123 02124 } 02125 } 02126 02127 /* function in use for buttons and for view2d sliders */ 02128 void uiWidgetScrollDraw(uiWidgetColors *wcol, rcti *rect, rcti *slider, int state) 02129 { 02130 uiWidgetBase wtb; 02131 float rad; 02132 int horizontal; 02133 short outline=0; 02134 02135 widget_init(&wtb); 02136 02137 /* determine horizontal/vertical */ 02138 horizontal= (rect->xmax - rect->xmin > rect->ymax - rect->ymin); 02139 02140 if(horizontal) 02141 rad= 0.5f*(rect->ymax - rect->ymin); 02142 else 02143 rad= 0.5f*(rect->xmax - rect->xmin); 02144 02145 wtb.shadedir= (horizontal)? 1: 0; 02146 02147 /* draw back part, colors swapped and shading inverted */ 02148 if(horizontal) 02149 SWAP(short, wcol->shadetop, wcol->shadedown); 02150 02151 round_box_edges(&wtb, 15, rect, rad); 02152 widgetbase_draw(&wtb, wcol); 02153 02154 /* slider */ 02155 if(slider->xmax-slider->xmin<2 || slider->ymax-slider->ymin<2); 02156 else { 02157 02158 SWAP(short, wcol->shadetop, wcol->shadedown); 02159 02160 QUATCOPY(wcol->inner, wcol->item); 02161 02162 if(wcol->shadetop>wcol->shadedown) 02163 wcol->shadetop+= 20; /* XXX violates themes... */ 02164 else wcol->shadedown+= 20; 02165 02166 if(state & UI_SCROLL_PRESSED) { 02167 wcol->inner[0]= wcol->inner[0]>=250? 255 : wcol->inner[0]+5; 02168 wcol->inner[1]= wcol->inner[1]>=250? 255 : wcol->inner[1]+5; 02169 wcol->inner[2]= wcol->inner[2]>=250? 255 : wcol->inner[2]+5; 02170 } 02171 02172 /* draw */ 02173 wtb.emboss= 0; /* only emboss once */ 02174 02175 /* exception for progress bar */ 02176 if (state & UI_SCROLL_NO_OUTLINE) 02177 SWAP(short, outline, wtb.outline); 02178 02179 round_box_edges(&wtb, 15, slider, rad); 02180 02181 if(state & UI_SCROLL_ARROWS) { 02182 if(wcol->item[0] > 48) wcol->item[0]-= 48; 02183 if(wcol->item[1] > 48) wcol->item[1]-= 48; 02184 if(wcol->item[2] > 48) wcol->item[2]-= 48; 02185 wcol->item[3]= 255; 02186 02187 if(horizontal) { 02188 widget_scroll_circle(&wtb.tria1, slider, 0.6f, 'l'); 02189 widget_scroll_circle(&wtb.tria2, slider, 0.6f, 'r'); 02190 } 02191 else { 02192 widget_scroll_circle(&wtb.tria1, slider, 0.6f, 'b'); 02193 widget_scroll_circle(&wtb.tria2, slider, 0.6f, 't'); 02194 } 02195 } 02196 widgetbase_draw(&wtb, wcol); 02197 02198 if (state & UI_SCROLL_NO_OUTLINE) 02199 SWAP(short, outline, wtb.outline); 02200 } 02201 } 02202 02203 static void widget_scroll(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int UNUSED(roundboxalign)) 02204 { 02205 rcti rect1; 02206 double value; 02207 float fac, size, min; 02208 int horizontal; 02209 02210 /* calculate slider part */ 02211 value= ui_get_but_val(but); 02212 02213 size= (but->softmax + but->a1 - but->softmin); 02214 size= MAX2(size, 2); 02215 02216 /* position */ 02217 rect1= *rect; 02218 02219 /* determine horizontal/vertical */ 02220 horizontal= (rect->xmax - rect->xmin > rect->ymax - rect->ymin); 02221 02222 if(horizontal) { 02223 fac= (rect->xmax - rect->xmin)/(size); 02224 rect1.xmin= rect1.xmin + ceilf(fac*((float)value - but->softmin)); 02225 rect1.xmax= rect1.xmin + ceilf(fac*(but->a1 - but->softmin)); 02226 02227 /* ensure minimium size */ 02228 min= rect->ymax - rect->ymin; 02229 02230 if(rect1.xmax - rect1.xmin < min) { 02231 rect1.xmax= rect1.xmin + min; 02232 02233 if(rect1.xmax > rect->xmax) { 02234 rect1.xmax= rect->xmax; 02235 rect1.xmin= MAX2(rect1.xmax - min, rect->xmin); 02236 } 02237 } 02238 } 02239 else { 02240 fac= (rect->ymax - rect->ymin)/(size); 02241 rect1.ymax= rect1.ymax - ceilf(fac*((float)value - but->softmin)); 02242 rect1.ymin= rect1.ymax - ceilf(fac*(but->a1 - but->softmin)); 02243 02244 /* ensure minimium size */ 02245 min= rect->xmax - rect->xmin; 02246 02247 if(rect1.ymax - rect1.ymin < min) { 02248 rect1.ymax= rect1.ymin + min; 02249 02250 if(rect1.ymax > rect->ymax) { 02251 rect1.ymax= rect->ymax; 02252 rect1.ymin= MAX2(rect1.ymax - min, rect->ymin); 02253 } 02254 } 02255 } 02256 02257 if(state & UI_SELECT) 02258 state= UI_SCROLL_PRESSED; 02259 else 02260 state= 0; 02261 uiWidgetScrollDraw(wcol, rect, &rect1, state); 02262 } 02263 02264 static void widget_progressbar(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign)) 02265 { 02266 rcti rect_prog = *rect, rect_bar = *rect; 02267 float value = but->a1; 02268 float w, min; 02269 02270 /* make the progress bar a proportion of the original height */ 02271 /* hardcoded 4px high for now */ 02272 rect_prog.ymax = rect_prog.ymin + 4; 02273 rect_bar.ymax = rect_bar.ymin + 4; 02274 02275 w = value * (rect_prog.xmax - rect_prog.xmin); 02276 02277 /* ensure minimium size */ 02278 min= rect_prog.ymax - rect_prog.ymin; 02279 w = MAX2(w, min); 02280 02281 rect_bar.xmax = rect_bar.xmin + w; 02282 02283 uiWidgetScrollDraw(wcol, &rect_prog, &rect_bar, UI_SCROLL_NO_OUTLINE); 02284 02285 /* raise text a bit */ 02286 rect->ymin += 6; 02287 rect->xmin -= 6; 02288 } 02289 02290 static void widget_link(uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *rect, int UNUSED(state), int UNUSED(roundboxalign)) 02291 { 02292 02293 if(but->flag & UI_SELECT) { 02294 rcti rectlink; 02295 02296 UI_ThemeColor(TH_TEXT_HI); 02297 02298 rectlink.xmin= (rect->xmin+rect->xmax)/2; 02299 rectlink.ymin= (rect->ymin+rect->ymax)/2; 02300 rectlink.xmax= but->linkto[0]; 02301 rectlink.ymax= but->linkto[1]; 02302 02303 ui_draw_link_bezier(&rectlink); 02304 } 02305 } 02306 02307 static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign) 02308 { 02309 uiWidgetBase wtb, wtb1; 02310 rcti rect1; 02311 double value; 02312 float offs, toffs, fac; 02313 char outline[3]; 02314 02315 widget_init(&wtb); 02316 widget_init(&wtb1); 02317 02318 /* backdrop first */ 02319 02320 /* fully rounded */ 02321 offs= 0.5f*(rect->ymax - rect->ymin); 02322 toffs = offs*0.75f; 02323 round_box_edges(&wtb, roundboxalign, rect, offs); 02324 02325 wtb.outline= 0; 02326 widgetbase_draw(&wtb, wcol); 02327 02328 /* draw left/right parts only when not in text editing */ 02329 if(!(state & UI_TEXTINPUT)) { 02330 02331 /* slider part */ 02332 VECCOPY(outline, wcol->outline); 02333 VECCOPY(wcol->outline, wcol->item); 02334 VECCOPY(wcol->inner, wcol->item); 02335 02336 if(!(state & UI_SELECT)) 02337 SWAP(short, wcol->shadetop, wcol->shadedown); 02338 02339 rect1= *rect; 02340 02341 value= ui_get_but_val(but); 02342 fac= ((float)value-but->softmin)*(rect1.xmax - rect1.xmin - offs)/(but->softmax - but->softmin); 02343 02344 /* left part of slider, always rounded */ 02345 rect1.xmax= rect1.xmin + ceil(offs+1.0f); 02346 round_box_edges(&wtb1, roundboxalign & ~6, &rect1, offs); 02347 wtb1.outline= 0; 02348 widgetbase_draw(&wtb1, wcol); 02349 02350 /* right part of slider, interpolate roundness */ 02351 rect1.xmax= rect1.xmin + fac + offs; 02352 rect1.xmin+= floor(offs-1.0f); 02353 if(rect1.xmax + offs > rect->xmax) 02354 offs*= (rect1.xmax + offs - rect->xmax)/offs; 02355 else 02356 offs= 0.0f; 02357 round_box_edges(&wtb1, roundboxalign & ~9, &rect1, offs); 02358 02359 widgetbase_draw(&wtb1, wcol); 02360 VECCOPY(wcol->outline, outline); 02361 02362 if(!(state & UI_SELECT)) 02363 SWAP(short, wcol->shadetop, wcol->shadedown); 02364 } 02365 02366 /* outline */ 02367 wtb.outline= 1; 02368 wtb.inner= 0; 02369 widgetbase_draw(&wtb, wcol); 02370 02371 /* text space */ 02372 rect->xmin += toffs; 02373 rect->xmax -= toffs; 02374 } 02375 02376 /* I think 3 is sufficient border to indicate keyed status */ 02377 #define SWATCH_KEYED_BORDER 3 02378 02379 static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign) 02380 { 02381 uiWidgetBase wtb; 02382 float col[4]; 02383 int color_profile = but->block->color_profile; 02384 02385 col[3]= 1.0f; 02386 02387 if (but->rnaprop) { 02388 if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) 02389 color_profile = BLI_PR_NONE; 02390 02391 if(RNA_property_array_length(&but->rnapoin, but->rnaprop)==4) { 02392 col[3]= RNA_property_float_get_index(&but->rnapoin, but->rnaprop, 3); 02393 } 02394 } 02395 02396 widget_init(&wtb); 02397 02398 /* half rounded */ 02399 round_box_edges(&wtb, roundboxalign, rect, 5.0f); 02400 02401 ui_get_but_vectorf(but, col); 02402 02403 if(state & (UI_BUT_ANIMATED|UI_BUT_ANIMATED_KEY|UI_BUT_DRIVEN|UI_BUT_REDALERT)) { 02404 // draw based on state - color for keyed etc 02405 widgetbase_draw(&wtb, wcol); 02406 02407 // inset to draw swatch color 02408 rect->xmin+= SWATCH_KEYED_BORDER; 02409 rect->xmax-= SWATCH_KEYED_BORDER; 02410 rect->ymin+= SWATCH_KEYED_BORDER; 02411 rect->ymax-= SWATCH_KEYED_BORDER; 02412 02413 round_box_edges(&wtb, roundboxalign, rect, 5.0f); 02414 } 02415 02416 if (color_profile) 02417 linearrgb_to_srgb_v3_v3(col, col); 02418 02419 wcol->inner[0]= FTOCHAR(col[0]); 02420 wcol->inner[1]= FTOCHAR(col[1]); 02421 wcol->inner[2]= FTOCHAR(col[2]); 02422 wcol->inner[3]= FTOCHAR(col[3]); 02423 wcol->shaded = 0; 02424 wcol->alpha_check = (wcol->inner[3] < 255); 02425 02426 widgetbase_draw(&wtb, wcol); 02427 02428 } 02429 02430 static void widget_icon_has_anim(uiBut *UNUSED(but), uiWidgetColors *wcol, rcti *rect, int state, int UNUSED(roundboxalign)) 02431 { 02432 if(state & (UI_BUT_ANIMATED|UI_BUT_ANIMATED_KEY|UI_BUT_DRIVEN|UI_BUT_REDALERT)) { 02433 uiWidgetBase wtb; 02434 02435 widget_init(&wtb); 02436 wtb.outline= 0; 02437 02438 /* rounded */ 02439 round_box_edges(&wtb, 15, rect, 10.0f); 02440 widgetbase_draw(&wtb, wcol); 02441 } 02442 } 02443 02444 02445 static void widget_textbut(uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign) 02446 { 02447 uiWidgetBase wtb; 02448 02449 if(state & UI_SELECT) 02450 SWAP(short, wcol->shadetop, wcol->shadedown); 02451 02452 widget_init(&wtb); 02453 02454 /* half rounded */ 02455 round_box_edges(&wtb, roundboxalign, rect, 4.0f); 02456 02457 widgetbase_draw(&wtb, wcol); 02458 02459 } 02460 02461 02462 static void widget_menubut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign) 02463 { 02464 uiWidgetBase wtb; 02465 02466 widget_init(&wtb); 02467 02468 /* half rounded */ 02469 round_box_edges(&wtb, roundboxalign, rect, 4.0f); 02470 02471 /* decoration */ 02472 widget_menu_trias(&wtb.tria1, rect); 02473 02474 widgetbase_draw(&wtb, wcol); 02475 02476 /* text space */ 02477 rect->xmax -= (rect->ymax-rect->ymin); 02478 } 02479 02480 static void widget_menuiconbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign) 02481 { 02482 uiWidgetBase wtb; 02483 02484 widget_init(&wtb); 02485 02486 /* half rounded */ 02487 round_box_edges(&wtb, roundboxalign, rect, 4.0f); 02488 02489 /* decoration */ 02490 widgetbase_draw(&wtb, wcol); 02491 } 02492 02493 static void widget_pulldownbut(uiWidgetColors *wcol, rcti *rect, int state, int UNUSED(roundboxalign)) 02494 { 02495 if(state & UI_ACTIVE) { 02496 uiWidgetBase wtb; 02497 float rad= 0.5f*(rect->ymax - rect->ymin); // 4.0f 02498 02499 widget_init(&wtb); 02500 02501 /* half rounded */ 02502 round_box_edges(&wtb, 15, rect, rad); 02503 02504 widgetbase_draw(&wtb, wcol); 02505 } 02506 } 02507 02508 static void widget_menu_itembut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign)) 02509 { 02510 uiWidgetBase wtb; 02511 02512 widget_init(&wtb); 02513 02514 /* not rounded, no outline */ 02515 wtb.outline= 0; 02516 round_box_edges(&wtb, 0, rect, 0.0f); 02517 02518 widgetbase_draw(&wtb, wcol); 02519 } 02520 02521 static void widget_list_itembut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int UNUSED(roundboxalign)) 02522 { 02523 uiWidgetBase wtb; 02524 02525 widget_init(&wtb); 02526 02527 /* rounded, but no outline */ 02528 wtb.outline= 0; 02529 round_box_edges(&wtb, 15, rect, 4.0f); 02530 02531 widgetbase_draw(&wtb, wcol); 02532 } 02533 02534 static void widget_optionbut(uiWidgetColors *wcol, rcti *rect, int state, int UNUSED(roundboxalign)) 02535 { 02536 uiWidgetBase wtb; 02537 rcti recttemp= *rect; 02538 int delta; 02539 02540 widget_init(&wtb); 02541 02542 /* square */ 02543 recttemp.xmax= recttemp.xmin + (recttemp.ymax-recttemp.ymin); 02544 02545 /* smaller */ 02546 delta= 1 + (recttemp.ymax-recttemp.ymin)/8; 02547 recttemp.xmin+= delta; 02548 recttemp.ymin+= delta; 02549 recttemp.xmax-= delta; 02550 recttemp.ymax-= delta; 02551 02552 /* half rounded */ 02553 round_box_edges(&wtb, 15, &recttemp, 4.0f); 02554 02555 /* decoration */ 02556 if(state & UI_SELECT) { 02557 widget_check_trias(&wtb.tria1, &recttemp); 02558 } 02559 02560 widgetbase_draw(&wtb, wcol); 02561 02562 /* text space */ 02563 rect->xmin += (rect->ymax-rect->ymin)*0.7 + delta; 02564 } 02565 02566 02567 static void widget_radiobut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign) 02568 { 02569 uiWidgetBase wtb; 02570 02571 widget_init(&wtb); 02572 02573 /* half rounded */ 02574 round_box_edges(&wtb, roundboxalign, rect, 4.0f); 02575 02576 widgetbase_draw(&wtb, wcol); 02577 02578 } 02579 02580 static void widget_box(uiBut *but, uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign) 02581 { 02582 uiWidgetBase wtb; 02583 char old_col[3]; 02584 02585 widget_init(&wtb); 02586 02587 VECCOPY(old_col, wcol->inner); 02588 02589 /* abuse but->hsv - if it's non-zero, use this color as the box's background */ 02590 if (but->col[3]) { 02591 wcol->inner[0] = but->col[0]; 02592 wcol->inner[1] = but->col[1]; 02593 wcol->inner[2] = but->col[2]; 02594 } 02595 02596 /* half rounded */ 02597 round_box_edges(&wtb, roundboxalign, rect, 4.0f); 02598 02599 widgetbase_draw(&wtb, wcol); 02600 02601 /* store the box bg as gl clearcolor, to retrieve later when drawing semi-transparent rects 02602 * over the top to indicate disabled buttons */ 02603 /* XXX, this doesnt work right since the color applies to buttons outside the box too. */ 02604 glClearColor(wcol->inner[0]/255.0, wcol->inner[1]/255.0, wcol->inner[2]/255.0, 1.0); 02605 02606 VECCOPY(wcol->inner, old_col); 02607 } 02608 02609 static void widget_but(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign) 02610 { 02611 uiWidgetBase wtb; 02612 02613 widget_init(&wtb); 02614 02615 /* half rounded */ 02616 round_box_edges(&wtb, roundboxalign, rect, 4.0f); 02617 02618 widgetbase_draw(&wtb, wcol); 02619 02620 } 02621 02622 static void widget_roundbut(uiWidgetColors *wcol, rcti *rect, int UNUSED(state), int roundboxalign) 02623 { 02624 uiWidgetBase wtb; 02625 float rad= 5.0f; //0.5f*(rect->ymax - rect->ymin); 02626 02627 widget_init(&wtb); 02628 02629 /* half rounded */ 02630 round_box_edges(&wtb, roundboxalign, rect, rad); 02631 02632 widgetbase_draw(&wtb, wcol); 02633 } 02634 02635 static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType *wt, rcti *rect) 02636 { 02637 uiWidgetBase wtb; 02638 unsigned char col[4]; 02639 02640 /* state copy! */ 02641 wt->wcol= *(wt->wcol_theme); 02642 02643 widget_init(&wtb); 02644 02645 if(but->block->drawextra) { 02646 /* note: drawextra can change rect +1 or -1, to match round errors of existing previews */ 02647 but->block->drawextra(C, but->poin, but->block->drawextra_arg1, but->block->drawextra_arg2, rect); 02648 02649 /* make mask to draw over image */ 02650 UI_GetThemeColor3ubv(TH_BACK, col); 02651 glColor3ubv(col); 02652 02653 round_box__edges(&wtb, 15, rect, 0.0f, 4.0); 02654 widgetbase_outline(&wtb); 02655 } 02656 02657 /* outline */ 02658 round_box_edges(&wtb, 15, rect, 5.0f); 02659 wtb.outline= 1; 02660 wtb.inner= 0; 02661 widgetbase_draw(&wtb, &wt->wcol); 02662 02663 } 02664 02665 02666 static void widget_disabled(rcti *rect) 02667 { 02668 float col[4]; 02669 02670 glEnable(GL_BLEND); 02671 02672 /* can't use theme TH_BACK or TH_PANEL... undefined */ 02673 glGetFloatv(GL_COLOR_CLEAR_VALUE, col); 02674 glColor4f(col[0], col[1], col[2], 0.5f); 02675 02676 /* need -1 and +1 to make it work right for aligned buttons, 02677 * but problem may be somewhere else? */ 02678 glRectf(rect->xmin-1, rect->ymin-1, rect->xmax, rect->ymax+1); 02679 02680 glDisable(GL_BLEND); 02681 } 02682 02683 static uiWidgetType *widget_type(uiWidgetTypeEnum type) 02684 { 02685 bTheme *btheme= U.themes.first; 02686 static uiWidgetType wt; 02687 02688 /* defaults */ 02689 wt.wcol_theme= &btheme->tui.wcol_regular; 02690 wt.wcol_state= &btheme->tui.wcol_state; 02691 wt.state= widget_state; 02692 wt.draw= widget_but; 02693 wt.custom= NULL; 02694 wt.text= widget_draw_text_icon; 02695 02696 switch(type) { 02697 case UI_WTYPE_REGULAR: 02698 break; 02699 02700 case UI_WTYPE_LABEL: 02701 wt.draw= NULL; 02702 wt.state= widget_state_label; 02703 break; 02704 02705 case UI_WTYPE_TOGGLE: 02706 wt.wcol_theme= &btheme->tui.wcol_toggle; 02707 break; 02708 02709 case UI_WTYPE_OPTION: 02710 wt.wcol_theme= &btheme->tui.wcol_option; 02711 wt.draw= widget_optionbut; 02712 break; 02713 02714 case UI_WTYPE_RADIO: 02715 wt.wcol_theme= &btheme->tui.wcol_radio; 02716 wt.draw= widget_radiobut; 02717 break; 02718 02719 case UI_WTYPE_NUMBER: 02720 wt.wcol_theme= &btheme->tui.wcol_num; 02721 wt.draw= widget_numbut; 02722 break; 02723 02724 case UI_WTYPE_SLIDER: 02725 wt.wcol_theme= &btheme->tui.wcol_numslider; 02726 wt.custom= widget_numslider; 02727 wt.state= widget_state_numslider; 02728 break; 02729 02730 case UI_WTYPE_EXEC: 02731 wt.wcol_theme= &btheme->tui.wcol_tool; 02732 wt.draw= widget_roundbut; 02733 break; 02734 02735 02736 /* strings */ 02737 case UI_WTYPE_NAME: 02738 wt.wcol_theme= &btheme->tui.wcol_text; 02739 wt.draw= widget_textbut; 02740 break; 02741 02742 case UI_WTYPE_NAME_LINK: 02743 break; 02744 02745 case UI_WTYPE_POINTER_LINK: 02746 break; 02747 02748 case UI_WTYPE_FILENAME: 02749 break; 02750 02751 02752 /* start menus */ 02753 case UI_WTYPE_MENU_RADIO: 02754 wt.wcol_theme= &btheme->tui.wcol_menu; 02755 wt.draw= widget_menubut; 02756 break; 02757 02758 case UI_WTYPE_MENU_ICON_RADIO: 02759 wt.wcol_theme= &btheme->tui.wcol_menu; 02760 wt.draw= widget_menuiconbut; 02761 break; 02762 02763 case UI_WTYPE_MENU_POINTER_LINK: 02764 wt.wcol_theme= &btheme->tui.wcol_menu; 02765 wt.draw= widget_menubut; 02766 break; 02767 02768 case UI_WTYPE_PULLDOWN: 02769 wt.wcol_theme= &btheme->tui.wcol_pulldown; 02770 wt.draw= widget_pulldownbut; 02771 wt.state= widget_state_pulldown; 02772 break; 02773 02774 /* in menus */ 02775 case UI_WTYPE_MENU_ITEM: 02776 wt.wcol_theme= &btheme->tui.wcol_menu_item; 02777 wt.draw= widget_menu_itembut; 02778 wt.state= widget_state_menu_item; 02779 break; 02780 02781 case UI_WTYPE_MENU_BACK: 02782 wt.wcol_theme= &btheme->tui.wcol_menu_back; 02783 wt.draw= widget_menu_back; 02784 break; 02785 02786 /* specials */ 02787 case UI_WTYPE_ICON: 02788 wt.custom= widget_icon_has_anim; 02789 break; 02790 02791 case UI_WTYPE_SWATCH: 02792 wt.custom= widget_swatch; 02793 break; 02794 02795 case UI_WTYPE_BOX: 02796 wt.custom= widget_box; 02797 wt.wcol_theme= &btheme->tui.wcol_box; 02798 break; 02799 02800 case UI_WTYPE_RGB_PICKER: 02801 break; 02802 02803 case UI_WTYPE_NORMAL: 02804 break; 02805 02806 case UI_WTYPE_SCROLL: 02807 wt.wcol_theme= &btheme->tui.wcol_scroll; 02808 wt.state= widget_state_nothing; 02809 wt.custom= widget_scroll; 02810 break; 02811 02812 case UI_WTYPE_LISTITEM: 02813 wt.wcol_theme= &btheme->tui.wcol_list_item; 02814 wt.draw= widget_list_itembut; 02815 break; 02816 02817 case UI_WTYPE_PROGRESSBAR: 02818 wt.wcol_theme= &btheme->tui.wcol_progress; 02819 wt.custom= widget_progressbar; 02820 break; 02821 } 02822 02823 return &wt; 02824 } 02825 02826 02827 static int widget_roundbox_set(uiBut *but, rcti *rect) 02828 { 02829 /* alignment */ 02830 if(but->flag & UI_BUT_ALIGN) { 02831 02832 if(but->flag & UI_BUT_ALIGN_TOP) 02833 rect->ymax+= 1; 02834 if(but->flag & UI_BUT_ALIGN_LEFT) 02835 rect->xmin-= 1; 02836 02837 switch(but->flag & UI_BUT_ALIGN) { 02838 case UI_BUT_ALIGN_TOP: 02839 return (12); 02840 break; 02841 case UI_BUT_ALIGN_DOWN: 02842 return (3); 02843 break; 02844 case UI_BUT_ALIGN_LEFT: 02845 return (6); 02846 break; 02847 case UI_BUT_ALIGN_RIGHT: 02848 return (9); 02849 break; 02850 02851 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_RIGHT: 02852 return (1); 02853 break; 02854 case UI_BUT_ALIGN_DOWN|UI_BUT_ALIGN_LEFT: 02855 return (2); 02856 break; 02857 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_RIGHT: 02858 return (8); 02859 break; 02860 case UI_BUT_ALIGN_TOP|UI_BUT_ALIGN_LEFT: 02861 return (4); 02862 break; 02863 02864 default: 02865 return (0); 02866 break; 02867 } 02868 } 02869 return 15; 02870 } 02871 02872 /* conversion from old to new buttons, so still messy */ 02873 void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rcti *rect) 02874 { 02875 bTheme *btheme= U.themes.first; 02876 ThemeUI *tui= &btheme->tui; 02877 uiFontStyle *fstyle= &style->widget; 02878 uiWidgetType *wt= NULL; 02879 02880 /* handle menus separately */ 02881 if(but->dt==UI_EMBOSSP) { 02882 switch (but->type) { 02883 case LABEL: 02884 widget_draw_text_icon(&style->widgetlabel, &tui->wcol_menu_back, but, rect); 02885 break; 02886 case SEPR: 02887 ui_draw_separator(rect, &tui->wcol_menu_item); 02888 break; 02889 02890 default: 02891 wt= widget_type(UI_WTYPE_MENU_ITEM); 02892 } 02893 } 02894 else if(but->dt==UI_EMBOSSN) { 02895 /* "nothing" */ 02896 wt= widget_type(UI_WTYPE_ICON); 02897 } 02898 else { 02899 02900 switch (but->type) { 02901 case LABEL: 02902 if(but->block->flag & UI_BLOCK_LOOP) 02903 widget_draw_text_icon(&style->widgetlabel, &tui->wcol_menu_back, but, rect); 02904 else { 02905 wt= widget_type(UI_WTYPE_LABEL); 02906 fstyle= &style->widgetlabel; 02907 } 02908 break; 02909 02910 case SEPR: 02911 break; 02912 02913 case BUT: 02914 wt= widget_type(UI_WTYPE_EXEC); 02915 break; 02916 02917 case NUM: 02918 wt= widget_type(UI_WTYPE_NUMBER); 02919 break; 02920 02921 case NUMSLI: 02922 case HSVSLI: 02923 wt= widget_type(UI_WTYPE_SLIDER); 02924 break; 02925 02926 case ROW: 02927 wt= widget_type(UI_WTYPE_RADIO); 02928 break; 02929 02930 case LISTROW: 02931 wt= widget_type(UI_WTYPE_LISTITEM); 02932 break; 02933 02934 case TEX: 02935 wt= widget_type(UI_WTYPE_NAME); 02936 break; 02937 02938 case SEARCH_MENU: 02939 wt= widget_type(UI_WTYPE_NAME); 02940 if(but->block->flag & UI_BLOCK_LOOP) 02941 wt->wcol_theme= &btheme->tui.wcol_menu_back; 02942 break; 02943 02944 case TOGBUT: 02945 case TOG: 02946 case TOGN: 02947 case TOG3: 02948 wt= widget_type(UI_WTYPE_TOGGLE); 02949 break; 02950 02951 case OPTION: 02952 case OPTIONN: 02953 if (!(but->flag & UI_HAS_ICON)) { 02954 wt= widget_type(UI_WTYPE_OPTION); 02955 but->flag |= UI_TEXT_LEFT; 02956 } 02957 else 02958 wt= widget_type(UI_WTYPE_TOGGLE); 02959 02960 /* option buttons have strings outside, on menus use different colors */ 02961 if(but->block->flag & UI_BLOCK_LOOP) 02962 wt->state= widget_state_option_menu; 02963 02964 break; 02965 02966 case MENU: 02967 case BLOCK: 02968 case ICONTEXTROW: 02969 if(!but->str[0] && but->icon) 02970 wt= widget_type(UI_WTYPE_MENU_ICON_RADIO); 02971 else 02972 wt= widget_type(UI_WTYPE_MENU_RADIO); 02973 break; 02974 02975 case PULLDOWN: 02976 wt= widget_type(UI_WTYPE_PULLDOWN); 02977 break; 02978 02979 case BUTM: 02980 wt= widget_type(UI_WTYPE_MENU_ITEM); 02981 break; 02982 02983 case COL: 02984 wt= widget_type(UI_WTYPE_SWATCH); 02985 break; 02986 02987 case ROUNDBOX: 02988 case LISTBOX: 02989 wt= widget_type(UI_WTYPE_BOX); 02990 break; 02991 02992 case LINK: 02993 case INLINK: 02994 wt= widget_type(UI_WTYPE_ICON); 02995 wt->custom= widget_link; 02996 02997 break; 02998 02999 case BUT_EXTRA: 03000 widget_draw_extra_mask(C, but, widget_type(UI_WTYPE_BOX), rect); 03001 break; 03002 03003 case HSVCUBE: 03004 if(but->a1 == UI_GRAD_V_ALT) // vertical V slider, uses new widget draw now 03005 ui_draw_but_HSV_v(but, rect); 03006 else // other HSV pickers... 03007 ui_draw_but_HSVCUBE(but, rect); 03008 break; 03009 03010 case HSVCIRCLE: 03011 ui_draw_but_HSVCIRCLE(but, &tui->wcol_regular, rect); 03012 break; 03013 03014 case BUT_COLORBAND: 03015 ui_draw_but_COLORBAND(but, &tui->wcol_regular, rect); 03016 break; 03017 03018 case BUT_NORMAL: 03019 ui_draw_but_NORMAL(but, &tui->wcol_regular, rect); 03020 break; 03021 03022 case BUT_IMAGE: 03023 ui_draw_but_IMAGE(ar, but, &tui->wcol_regular, rect); 03024 break; 03025 03026 case HISTOGRAM: 03027 ui_draw_but_HISTOGRAM(ar, but, &tui->wcol_regular, rect); 03028 break; 03029 03030 case WAVEFORM: 03031 ui_draw_but_WAVEFORM(ar, but, &tui->wcol_regular, rect); 03032 break; 03033 03034 case VECTORSCOPE: 03035 ui_draw_but_VECTORSCOPE(ar, but, &tui->wcol_regular, rect); 03036 break; 03037 03038 case BUT_CURVE: 03039 ui_draw_but_CURVE(ar, but, &tui->wcol_regular, rect); 03040 break; 03041 03042 case PROGRESSBAR: 03043 wt= widget_type(UI_WTYPE_PROGRESSBAR); 03044 fstyle= &style->widgetlabel; 03045 break; 03046 03047 case SCROLL: 03048 wt= widget_type(UI_WTYPE_SCROLL); 03049 break; 03050 03051 default: 03052 wt= widget_type(UI_WTYPE_REGULAR); 03053 } 03054 } 03055 03056 if(wt) { 03057 rcti disablerect= *rect; /* rect gets clipped smaller for text */ 03058 int roundboxalign, state; 03059 03060 roundboxalign= widget_roundbox_set(but, rect); 03061 03062 state= but->flag; 03063 if(but->editstr) state |= UI_TEXTINPUT; 03064 03065 wt->state(wt, state); 03066 if(wt->custom) 03067 wt->custom(but, &wt->wcol, rect, state, roundboxalign); 03068 else if(wt->draw) 03069 wt->draw(&wt->wcol, rect, state, roundboxalign); 03070 wt->text(fstyle, &wt->wcol, but, rect); 03071 03072 if(state & (UI_BUT_DISABLED|UI_BUT_INACTIVE)) 03073 if(but->dt!=UI_EMBOSSP) 03074 widget_disabled(&disablerect); 03075 } 03076 } 03077 03078 void ui_draw_menu_back(uiStyle *UNUSED(style), uiBlock *block, rcti *rect) 03079 { 03080 uiWidgetType *wt= widget_type(UI_WTYPE_MENU_BACK); 03081 03082 wt->state(wt, 0); 03083 if(block) 03084 wt->draw(&wt->wcol, rect, block->flag, block->direction); 03085 else 03086 wt->draw(&wt->wcol, rect, 0, 0); 03087 03088 if(block) { 03089 if(block->flag & UI_BLOCK_CLIPTOP) { 03090 /* XXX no scaling for UI here yet */ 03091 glColor3ubv((unsigned char*)wt->wcol.text); 03092 UI_DrawTriIcon((rect->xmax+rect->xmin)/2, rect->ymax-8, 't'); 03093 } 03094 if(block->flag & UI_BLOCK_CLIPBOTTOM) { 03095 /* XXX no scaling for UI here yet */ 03096 glColor3ubv((unsigned char*)wt->wcol.text); 03097 UI_DrawTriIcon((rect->xmax+rect->xmin)/2, rect->ymin+10, 'v'); 03098 } 03099 } 03100 } 03101 03102 void ui_draw_search_back(uiStyle *UNUSED(style), uiBlock *block, rcti *rect) 03103 { 03104 uiWidgetType *wt= widget_type(UI_WTYPE_BOX); 03105 03106 glEnable(GL_BLEND); 03107 widget_softshadow(rect, 15, 5.0f, 8.0f); 03108 glDisable(GL_BLEND); 03109 03110 wt->state(wt, 0); 03111 if(block) 03112 wt->draw(&wt->wcol, rect, block->flag, 15); 03113 else 03114 wt->draw(&wt->wcol, rect, 0, 15); 03115 03116 } 03117 03118 03119 /* helper call to draw a menu item without button */ 03120 /* state: UI_ACTIVE or 0 */ 03121 void ui_draw_menu_item(uiFontStyle *fstyle, rcti *rect, const char *name, int iconid, int state) 03122 { 03123 uiWidgetType *wt= widget_type(UI_WTYPE_MENU_ITEM); 03124 rcti _rect= *rect; 03125 char *cpoin; 03126 03127 wt->state(wt, state); 03128 wt->draw(&wt->wcol, rect, 0, 0); 03129 03130 uiStyleFontSet(fstyle); 03131 fstyle->align= UI_STYLE_TEXT_LEFT; 03132 03133 /* text location offset */ 03134 rect->xmin+=5; 03135 if(iconid) rect->xmin+= UI_DPI_ICON_SIZE; 03136 03137 /* cut string in 2 parts? */ 03138 cpoin= strchr(name, '|'); 03139 if(cpoin) { 03140 *cpoin= 0; 03141 rect->xmax -= BLF_width(fstyle->uifont_id, cpoin+1) + 10; 03142 } 03143 03144 glColor3ubv((unsigned char*)wt->wcol.text); 03145 uiStyleFontDraw(fstyle, rect, name); 03146 03147 /* part text right aligned */ 03148 if(cpoin) { 03149 fstyle->align= UI_STYLE_TEXT_RIGHT; 03150 rect->xmax= _rect.xmax - 5; 03151 uiStyleFontDraw(fstyle, rect, cpoin+1); 03152 *cpoin= '|'; 03153 } 03154 03155 /* restore rect, was messed with */ 03156 *rect= _rect; 03157 03158 if(iconid) { 03159 int xs= rect->xmin+4; 03160 int ys= 1 + (rect->ymin+rect->ymax- UI_DPI_ICON_SIZE)/2; 03161 glEnable(GL_BLEND); 03162 UI_icon_draw_aspect(xs, ys, iconid, 1.2f, 0.5f); /* XXX scale weak get from fstyle? */ 03163 glDisable(GL_BLEND); 03164 } 03165 } 03166 03167 void ui_draw_preview_item(uiFontStyle *fstyle, rcti *rect, const char *name, int iconid, int state) 03168 { 03169 rcti trect = *rect; 03170 03171 uiWidgetType *wt= widget_type(UI_WTYPE_MENU_ITEM); 03172 03173 wt->state(wt, state); 03174 wt->draw(&wt->wcol, rect, 0, 0); 03175 03176 widget_draw_preview(iconid, 1.0f, rect); 03177 03178 if (state == UI_ACTIVE) 03179 glColor3ubv((unsigned char*)wt->wcol.text); 03180 else 03181 glColor3ubv((unsigned char*)wt->wcol.text_sel); 03182 03183 trect.xmin += 0; 03184 trect.xmax = trect.xmin + BLF_width(fstyle->uifont_id, name) + 10; 03185 trect.ymin += 10; 03186 trect.ymax = trect.ymin + BLF_height(fstyle->uifont_id, name); 03187 uiStyleFontDraw(fstyle, &trect, name); 03188 }