New: color picker!

With a click on the 'COL' buttons (the ones showing RGB) a menu pops up
with three colorpicking fields and a palette.
The fields are the three planar intersections of a HSV cube, each allowing
choosing in the field without the field changing.

The palette is 'modal' unfortunately (couldn't find a simple working other
method) where the button "paste to color" denotes the state that click in
palette copies to edited color, and "copy to palette" means the active
color is copied into the palette...

Todo:
- saving of palette in file
- decide whether ESC leaves without changes...
This commit is contained in:
Ton Roosendaal 2004-07-05 08:48:17 +00:00
parent c1ce82bd67
commit cd47cfd3d1
10 changed files with 454 additions and 54 deletions

@ -2188,7 +2188,7 @@ void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b)
h *= 360.0f;
if(s==0 && 0) {
if(s==0.0) {
*r = v;
*g = v;
*b = v;

@ -74,6 +74,8 @@ struct ScrArea;
#define UI_BLOCK_BUSY 8
#define UI_BLOCK_NUMSELECT 16
#define UI_BLOCK_ENTER_OK 32
#define UI_BLOCK_NOSHADOW 64
/* block->flag bits 12-15 are identical to but->flag bits */
/* block->font, for now: bold = medium+1 */
@ -144,6 +146,7 @@ struct ScrArea;
#define INLINK (23<<9)
#define KEYEVT (24<<9)
#define ICONTEXTROW (25<<9)
#define HSVCUBE (26<<9)
#define BUTTYPE (31<<9)
@ -158,7 +161,7 @@ void uiRoundBox(float minx, float miny, float maxx, float maxy, float rad);
void uiSetRoundBox(int type);
void uiRoundRect(float minx, float miny, float maxx, float maxy, float rad);
void uiDrawMenuBox(float minx, float miny, float maxx, float maxy);
void uiDrawMenuBox(float minx, float miny, float maxx, float maxy, short flag);
void uiTextBoundsBlock(uiBlock *block, int addval);
void uiBoundsBlock(struct uiBlock *block, int addval);
void uiDrawBlock(struct uiBlock *block);

@ -200,6 +200,8 @@ struct uiBlock {
/* interface.c */
extern void ui_check_but(uiBut *but);
extern double ui_get_but_val(uiBut *but);
extern void ui_get_but_vectorf(uiBut *but, float *vec);
extern void ui_set_but_vectorf(uiBut *but, float *vec);
extern void ui_autofill(uiBlock *block);
extern void ui_graphics_to_window(int win, float *x, float *y);
extern void ui_window_to_graphics(int win, float *x, float *y);

@ -2107,7 +2107,7 @@ static void editing_panel_links(Object *ob)
if(ma) uiDefBut(block, LABEL, 0, ma->id.name+2, 318,153, 103, 20, 0, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
if(ma) uiDefButF(block, COL, 0, "", 291,123,24,30, &(ma->r), 0, 0, 0, 0, "");
if(ma) uiDefButF(block, COL, B_REDR, "", 291,123,24,30, &(ma->r), 0, 0, 0, 0, "");
uiDefButC(block, NUM, B_REDR, str, 318,123,103,30, &ob->actcol, min, (float)(ob->totcol), 0, 0, "Displays total number of material indices and the current index");
uiDefBut(block, BUT,B_MATWICH, "?", 423,123,31,30, 0, 0, 0, 0, 0, "In EditMode, sets the active material index from selected faces");
@ -2314,7 +2314,7 @@ static void editing_panel_mesh_paint(void)
uiDefButF(block, NUMSLI, 0, "Opacity ", 979,100,194,19, &Gvp.a, 0.0, 1.0, 0, 0, "The amount of pressure on the brush");
uiDefButF(block, NUMSLI, 0, "Size ", 979,80,194,19, &Gvp.size, 2.0, 64.0, 0, 0, "The size of the brush");
uiDefButF(block, COL, B_VPCOLSLI, "", 1176,100,28,80, &(Gvp.r), 0, 0, 0, 0, "");
uiDefButF(block, COL, B_REDR, "", 1176,100,28,80, &(Gvp.r), 0, 0, 0, B_VPCOLSLI, "");
uiBlockBeginAlign(block);
uiDefButS(block, ROW, B_DIFF, "Mix", 1212,160,63,19, &Gvp.mode, 1.0, 0.0, 0, 0, "Mix the vertex colours");
uiDefButS(block, ROW, B_DIFF, "Add", 1212,140,63,19, &Gvp.mode, 1.0, 1.0, 0, 0, "Add the vertex colour");

@ -949,10 +949,10 @@ void object_panel_draw(Object *ob)
uiBlockEndAlign(block);
uiDefBut(block, LABEL, 0, "Drawtype", 28,200,100,18, 0, 0, 0, 0, 0, "");
uiDefBut(block, LABEL, 0, "Drawtype", 28,200,100,18, NULL, 0, 0, 0, 0, "");
uiDefButC(block, MENU, REDRAWVIEW3D, "Drawtype%t|Bounds %x1|Wire %x2|Solid %x3|Shaded %x4",
28,180,100,18, &ob->dt, 0, 0, 0, 0, "Sets the drawing type of the active object");
uiDefBut(block, LABEL, 0, "Draw Extra", 28,160,100,18, 0, 0, 0, 0, 0, "");
uiDefBut(block, LABEL, 0, "Draw Extra", 28,160,100,18, NULL, 0, 0, 0, 0, "");
uiBlockBeginAlign(block);
uiDefButC(block, TOG|BIT|0, REDRAWVIEW3D, "Bounds", 28, 140, 100, 18, &ob->dtx, 0, 0, 0, 0, "Displays the active object's bounds");
uiDefButS(block, MENU, REDRAWVIEW3D, "Boundary Display%t|Box%x0|Sphere%x1|Cylinder%x2|Cone%x3|Polyheder%x4",
@ -1080,7 +1080,7 @@ static void object_panel_anim(Object *ob)
uiBlockEndAlign(block);
sprintf(str, "%.4f", prspeed);
uiDefBut(block, LABEL, 0, str, 247,40,63,31, 0, 1.0, 0, 0, 0, "");
uiDefBut(block, LABEL, 0, str, 247,40,63,31, NULL, 1.0, 0, 0, 0, "");
}
@ -1397,13 +1397,13 @@ void effects_panel_effects(Object *ob)
uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_CALCEFFECT, "X:", 550,31,72,20, paf->force, -1.0, 1.0, 1, 0, "Specify the X axis of a continues force");
uiDefButF(block, NUM, B_CALCEFFECT, "Y:", 624,31,78,20, paf->force+1,-1.0, 1.0, 1, 0, "Specify the Y axis of a continues force");
uiDefBut(block, LABEL, 0, "Force:", 550,9,72,20, 0, 1.0, 0, 0, 0, "");
uiDefBut(block, LABEL, 0, "Force:", 550,9,72,20, NULL, 1.0, 0, 0, 0, "");
uiDefButF(block, NUM, B_CALCEFFECT, "Z:", 623,9,79,20, paf->force+2, -1.0, 1.0, 1, 0, "Specify the Z axis of a continues force");
uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_CALCEFFECT, "X:", 722,31,74,20, paf->defvec, -1.0, 1.0, 1, 0, "Specify the X axis of a force, determined by the texture");
uiDefButF(block, NUM, B_CALCEFFECT, "Y:", 798,31,74,20, paf->defvec+1,-1.0, 1.0, 1, 0, "Specify the Y axis of a force, determined by the texture");
uiDefBut(block, LABEL, 0, "Texture:", 722,9,74,20, 0, 1.0, 0, 0, 0, "");
uiDefBut(block, LABEL, 0, "Texture:", 722,9,74,20, NULL, 1.0, 0, 0, 0, "");
uiDefButF(block, NUM, B_CALCEFFECT, "Z:", 797,9,75,20, paf->defvec+2, -1.0, 1.0, 1, 0, "Specify the Z axis of a force, determined by the texture");
uiBlockEndAlign(block);

@ -796,7 +796,7 @@ static uiBlock *edge_render_menu(void *arg_unused)
"For unified renderer: also consider transparent faces for toon shading");
/* colour settings for the toon shading */
uiDefButF(block, COL, B_EDGECOLSLI, "", 295,-10,30,60, &(G.scene->r.edgeR), 0, 0, 0, 0, "");
uiDefButF(block, COL, 0, "", 295,-10,30,60, &(G.scene->r.edgeR), 0, 0, 0, B_EDGECOLSLI, "");
uiDefButF(block, NUMSLI, 0, "R ", 325, 30, 180,19, &G.scene->r.edgeR, 0.0, 1.0, B_EDGECOLSLI, 0,
"For unified renderer: Colour for edges in toon shading mode.");
@ -852,7 +852,7 @@ static uiBlock *framing_render_menu(void *arg_unused)
yco -= 20;
xco = 35;
uiDefButF(block, COL, randomcolorindex, "", 0, yco - 58 + 18, 33, 58, &G.scene->framing.col[0], 0, 0, 0, 0, "");
uiDefButF(block, COL, 0, "", 0, yco - 58 + 18, 33, 58, &G.scene->framing.col[0], 0, 0, 0, randomcolorindex, "");
uiDefButF(block, NUMSLI, 0, "R ", xco,yco,243,18, &G.scene->framing.col[0], 0.0, 1.0, randomcolorindex, 0, "Set the red component of the bars");
yco -= 20;

@ -1213,7 +1213,7 @@ static void draw_colorband_buts(uiBlock *block, ColorBand *coba, int offs, int r
uiBlockBeginAlign(block);
uiDefButF(block, NUM, B_CALCCBAND, "Pos", 10,125+offs,110,20, &cbd->pos, 0.0, 1.0, 10, 0, "Sets the position of the active colour");
uiDefButF(block, COL, B_BANDCOL, "", 10,105+offs,110,20, &(cbd->r), 0, 0, 0, 0, "");
uiDefButF(block, COL, B_TEXREDR_PRV, "", 10,105+offs,110,20, &(cbd->r), 0, 0, 0, B_BANDCOL, "");
uiDefButF(block, NUMSLI, B_TEXREDR_PRV, "A ", 10,85+offs,110,20, &cbd->a, 0.0, 1.0, 0, 0, "Sets the alpha value for this position");
uiBlockBeginAlign(block);
@ -1618,7 +1618,7 @@ static void world_panel_mapto(World *wrld)
uiDefButS(block, TOG|BIT|0, B_MATPRV, "No RGB", 1014,130,69,19, &(mtex->texflag), 0, 0, 0, 0, "Converts texture RGB values to intensity (gray) values");
uiBlockEndAlign(block);
uiDefButF(block, COL, B_MTEXCOL, "", 920,105,163,19, &(mtex->r), 0, 0, 0, 0, "");
uiDefButF(block, COL, B_MATPRV_DRAW, "", 920,105,163,19, &(mtex->r), 0, 0, 0, B_MTEXCOL, "");
uiBlockBeginAlign(block);
uiDefButF(block, NUMSLI, B_MATPRV, "R ", 920,80,163,19, &(mtex->r), 0.0, 1.0, B_MTEXCOL, 0, "The default color for textures that don't return RGB");
uiDefButF(block, NUMSLI, B_MATPRV, "G ", 920,60,163,19, &(mtex->g), 0.0, 1.0, B_MTEXCOL, 0, "The default color for textures that don't return RGB");
@ -1845,8 +1845,8 @@ static void world_panel_world(World *wrld)
uiSetButLock(wrld->id.lib!=0, "Can't edit library data");
uiBlockSetCol(block, TH_AUTO);
uiDefButF(block, COL, B_COLHOR, "", 10,150,145,19, &wrld->horr, 0, 0, 0, 0, "");
uiDefButF(block, COL, B_COLZEN, "", 160,150,145,19, &wrld->zenr, 0, 0, 0, 0, "");
uiDefButF(block, COL, B_MATPRV_DRAW, "", 10,150,145,19, &wrld->horr, 0, 0, 0, B_COLHOR, "");
uiDefButF(block, COL, B_MATPRV_DRAW, "", 160,150,145,19, &wrld->zenr, 0, 0, 0, B_COLZEN, "");
uiBlockBeginAlign(block);
uiDefButF(block, NUMSLI,B_MATPRV,"HoR ", 10,130,145,19, &(wrld->horr), 0.0, 1.0, B_COLHOR,0, "Sets the amount of red colour at the horizon");
@ -1969,7 +1969,7 @@ static void lamp_panel_mapto(Object *ob, Lamp *la)
uiDefButS(block, TOG|BIT|0, B_MATPRV, "RGBtoInt", 1014,130,69,19, &(mtex->texflag), 0, 0, 0, 0, "Converts texture RGB values to intensity (gray) values");
uiBlockEndAlign(block);
uiDefButF(block, COL, B_MTEXCOL, "", 920,105,163,19, &(mtex->r), 0, 0, 0, 0, "");
uiDefButF(block, COL, B_MATPRV_DRAW, "", 920,105,163,19, &(mtex->r), 0, 0, 0, B_MTEXCOL, "");
uiBlockBeginAlign(block);
uiDefButF(block, NUMSLI, B_MATPRV, "R ", 920,80,163,19, &(mtex->r), 0.0, 1.0, B_MTEXCOL, 0, "The default color for textures that don't return RGB");
uiDefButF(block, NUMSLI, B_MATPRV, "G ", 920,60,163,19, &(mtex->g), 0.0, 1.0, B_MTEXCOL, 0, "The default color for textures that don't return RGB");
@ -2213,7 +2213,7 @@ static void lamp_panel_lamp(Object *ob, Lamp *la)
uiDefButF(block, NUMSLI,B_MATPRV,"B ", 120,80,180,20,&la->b, 0.0, 1.0, B_COLLAMP, 0, "Sets the blue component of the light");
uiBlockEndAlign(block);
uiDefButF(block, COL, B_COLLAMP, "", 120,52,180,24, &la->r, 0, 0, 0, 0, "");
uiDefButF(block, COL, B_MATPRV_DRAW, "", 120,52,180,24, &la->r, 0, 0, 0, B_COLLAMP, "");
uiBlockBeginAlign(block);
if ELEM(la->type, LA_LOCAL, LA_SPOT) {
@ -2384,7 +2384,7 @@ static void material_panel_map_to(Material *ma)
uiBlockEndAlign(block);
uiBlockBeginAlign(block);
uiDefButF(block, COL, B_MTEXCOL, "", 900,100,168,20, &(mtex->r), 0, 0, 0, 0, "");
uiDefButF(block, COL, B_MATPRV_DRAW, "", 900,100,168,20, &(mtex->r), 0, 0, 0, B_MTEXCOL, "");
if(ma->colormodel==MA_HSV) {
uiBlockSetCol(block, TH_BUT_SETTING1);
@ -2849,9 +2849,9 @@ static void material_panel_material(Object *ob, Material *ma)
}
uiBlockSetCol(block, TH_AUTO);
uiBlockBeginAlign(block);
uiDefButF(block, COL, B_MATCOL, "", 8,97,72,20, &(ma->r), 0, 0, 0, 0, "");
uiDefButF(block, COL, B_SPECCOL, "", 8,77,72,20, &(ma->specr), 0, 0, 0, 0, "");
uiDefButF(block, COL, B_MIRCOL, "", 8,57,72,20, &(ma->mirr), 0, 0, 0, 0, "");
uiDefButF(block, COL, B_MATPRV_DRAW, "", 8,97,72,20, &(ma->r), 0, 0, 0, B_MATCOL, "");
uiDefButF(block, COL, B_MATPRV_DRAW, "", 8,77,72,20, &(ma->specr), 0, 0, 0, B_SPECCOL, "");
uiDefButF(block, COL, B_MATPRV_DRAW, "", 8,57,72,20, &(ma->mirr), 0, 0, 0, B_MIRCOL, "");
uiBlockBeginAlign(block);
if(ma->mode & MA_HALO) {

@ -647,7 +647,7 @@ void uiDrawBlock(uiBlock *block)
uiPanelPush(block); // panel matrix
if(block->flag & UI_BLOCK_LOOP) {
uiDrawMenuBox(block->minx, block->miny, block->maxx, block->maxy);
uiDrawMenuBox(block->minx, block->miny, block->maxx, block->maxy, block->flag);
}
else if(block->panel) ui_draw_panel(block);
@ -1485,6 +1485,8 @@ static int ui_do_but_NUM(uiBut *but)
ui_draw_but(but);
glFlush(); // flush display in subloops
uibut_do_func(but);
return but->retval;
}
@ -1717,12 +1719,12 @@ static int ui_do_but_SLI(uiBut *but)
if(but->a1) { /* color number */
uiBut *bt= but->prev;
while(bt) {
if(bt->retval == but->a1) ui_draw_but(bt);
if(bt->a2 == but->a1) ui_draw_but(bt);
bt= bt->prev;
}
bt= but->next;
while(bt) {
if(bt->retval == but->a1) ui_draw_but(bt);
if(bt->a2 == but->a1) ui_draw_but(bt);
bt= bt->next;
}
}
@ -1861,6 +1863,7 @@ static int ui_do_but_BUTM(uiBut *but)
static int ui_do_but_LABEL(uiBut *but)
{
uibut_do_func(but);
return but->retval;
}
@ -2058,6 +2061,234 @@ static int ui_do_but_LINK(uiBlock *block, uiBut *but)
return 0;
}
/* picker sizes S size, D spacer, B button/pallette height */
#define SPICK 100.0
#define DPICK 6.0
#define BPICK 24.0
static short pick_mode=0;
#define UI_PALETTE_TOT 16
static float palette[UI_PALETTE_TOT][3]= {
{0.0, 0.0, 0.0}, {1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, 1.0},
{1.0, 1.0, 0.0}, {1.0, 0.0, 1.0}, {0.0, 1.0, 1.0}, {1.0, 1.0, 1.0},
{0.85, 0.85, 0.85}, {0.7, 0.7, 0.7}, {0.6, 0.6, 0.6}, {0.5, 0.5, 0.5},
{0.4, 0.4, 0.4}, {0.3, 0.3, 0.3}, {0.2, 0.2, 0.2}, {0.1, 0.1, 0.1}
};
static void update_picker_buts(uiBlock *block, float *col)
{
uiBut *bt;
float h, s, v;
// this updates button strings, is hackish... but button pointers are on stack of caller function
rgb_to_hsv(col[0], col[1], col[2], &h, &s, &v);
for(bt= block->buttons.first; bt; bt= bt->next) {
if(bt->str[0]=='R') {
ui_set_but_val(bt, col[0]);
ui_check_but(bt);
}
else if(bt->str[0]=='G') {
ui_set_but_val(bt, col[1]);
ui_check_but(bt);
}
else if(bt->str[0]=='B') {
ui_set_but_val(bt, col[2]);
ui_check_but(bt);
}
else if(bt->str[0]=='H') {
ui_set_but_val(bt, h);
ui_check_but(bt);
}
else if(bt->str[0]=='S') {
ui_set_but_val(bt, s);
ui_check_but(bt);
}
else if(bt->str[0]=='V') {
ui_set_but_val(bt, v);
ui_check_but(bt);
}
}
}
/* bt1 is palette but, bt2 is the parent button of the picker */
static void do_palette_cb(void *bt1, void *bt2)
{
uiBut *but1= (uiBut *)bt1;
uiBut *but2= (uiBut *)bt2;
float col[3], *fp;
ui_get_but_vectorf(but2, col);
fp= (float *)but1->poin;
if(pick_mode) {
VECCOPY(fp, col);
}
else {
VECCOPY(col, fp);
ui_set_but_vectorf(but2, col);
}
but1->block->flag |= UI_BLOCK_NOSHADOW;
uiDrawBlock(but1->block);
glFlush(); // flush display in subloops
}
/* bt1 is num but, bt2 is the parent button of the picker */
static void do_palette1_cb(void *bt1, void *bt2)
{
uiBut *but1= (uiBut *)bt1;
uiBut *but2= (uiBut *)bt2;
float *fp= NULL, col[3];
if(but1->str[0]=='H') fp= (float *)but1->poin;
else if(but1->str[0]=='S') fp= ((float *)but1->poin)-1;
else if(but1->str[0]=='V') fp= ((float *)but1->poin)-2;
if(fp) {
hsv_to_rgb(fp[0], fp[1], fp[2], col, col+1, col+2);
ui_set_but_vectorf(but2, col);
}
else {
if(but1->str[0]=='R') fp= (float *)but1->poin;
else if(but1->str[0]=='G') fp= ((float *)but1->poin)-1;
else if(but1->str[0]=='B') fp= ((float *)but1->poin)-2;
if(fp) {
ui_set_but_vectorf(but2, fp);
VECCOPY(col, fp);
}
}
update_picker_buts(but2->block, col);
but1->block->flag |= UI_BLOCK_NOSHADOW;
uiDrawBlock(but1->block);
glFlush(); // flush display in subloops
}
/* color picker */
static int ui_do_but_COL(uiBut *but)
{
uiBlock *block;
uiBut *bt;
ListBase listb={NULL, NULL};
float col[3], hsv[3], h;
int a;
short event;
// signal to prevent calling up color picker
if(but->a1 == -1 || but->pointype!=FLO) {
uibut_do_func(but);
return 0;
}
block= uiNewBlock(&listb, "colorpicker", UI_EMBOSSP, UI_HELV, but->win);
block->flag= UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_NUMSELECT;
block->themecol= TH_BUT_NUM;
// the cube intersections
bt= uiDefButF(block, HSVCUBE, 0, "", 0,DPICK+BPICK,SPICK,SPICK, (float *)but->poin, 0.0, 0.0, 0, 0, "");
uiButSetFlag(bt, UI_NO_HILITE);
bt= uiDefButF(block, HSVCUBE, 0, "", 0,2*DPICK+BPICK+SPICK,SPICK,SPICK, (float *)but->poin, 0.0, 0.0, 1, 0, "");
uiButSetFlag(bt, UI_NO_HILITE);
bt= uiDefButF(block, HSVCUBE, 0, "", DPICK+SPICK,2*DPICK+BPICK+SPICK,SPICK,SPICK, (float *)but->poin, 0.0, 0.0, 2, 0, "");
uiButSetFlag(bt, UI_NO_HILITE);
// palette
uiDefButF(block, COL, 0, "", 0,0,60,BPICK, (float *)but->poin, 0.0, 0.0, -1, 0, "");
h= (DPICK+2*SPICK-64)/(UI_PALETTE_TOT/2.0);
for(a=0; a<UI_PALETTE_TOT/2; a++) {
bt= uiDefButF(block, COL, 0, "", 65.0+(float)a*h, BPICK/2, h, BPICK/2, palette[a+UI_PALETTE_TOT/2], 0.0, 0.0, -1, 0, "");
uiButSetFunc(bt, do_palette_cb, bt, but);
bt= uiDefButF(block, COL, 0, "", 65.0+(float)a*h, 0, h, BPICK/2, palette[a], 0.0, 0.0, -1, 0, "");
uiButSetFunc(bt, do_palette_cb, bt, but);
}
// buttons
ui_get_but_vectorf(but, col);
rgb_to_hsv(col[0], col[1], col[2], hsv, hsv+1, hsv+2);
bt= uiDefButF(block, NUM, 0, "R ", DPICK+SPICK,BPICK+DPICK+SPICK-20,SPICK/2,20, col, 0.0, 1.0, 10, 2, "");
uiButSetFunc(bt, do_palette1_cb, bt, but);
bt= uiDefButF(block, NUM, 0, "G ", DPICK+SPICK,BPICK+DPICK+SPICK-40,SPICK/2,20, col+1, 0.0, 1.0, 10, 2, "");
uiButSetFunc(bt, do_palette1_cb, bt, but);
bt= uiDefButF(block, NUM, 0, "B ", DPICK+SPICK,BPICK+DPICK+SPICK-60,SPICK/2,20, col+2, 0.0, 1.0, 10, 2, "");
uiButSetFunc(bt, do_palette1_cb, bt, but);
bt= uiDefButF(block, NUM, 0, "H ", DPICK+1.5*SPICK,BPICK+DPICK+SPICK-20,SPICK/2,20, hsv, 0.0, 1.0, 10, 2, "");
uiButSetFunc(bt, do_palette1_cb, bt, but);
bt= uiDefButF(block, NUM, 0, "S ", DPICK+1.5*SPICK,BPICK+DPICK+SPICK-40,SPICK/2,20, hsv+1, 0.0, 1.0, 10, 2, "");
uiButSetFunc(bt, do_palette1_cb, bt, but);
bt= uiDefButF(block, NUM, 0, "V ", DPICK+1.5*SPICK,BPICK+DPICK+SPICK-60,SPICK/2,20, hsv+2, 0.0, 1.0, 10, 2, "");
uiButSetFunc(bt, do_palette1_cb, bt, but);
uiBlockBeginAlign(block);
uiDefButS(block, ROW, 0, "Paste to color", DPICK+SPICK, BPICK+DPICK+20, SPICK,20, &pick_mode, 0.0, 0.0, 0, 0, "Clicks in palette pastes to active color");
uiDefButS(block, ROW, 0, "Copy to palette",DPICK+SPICK, BPICK+DPICK, SPICK,20, &pick_mode, 0.0, 1.0, 0, 0, "Clicks in palette copies from active color");
uiBlockEndAlign(block);
// safety
uiDefBut(block, LABEL, 0, "", -DPICK,-DPICK,2*SPICK+3*DPICK,2*SPICK+4*DPICK+BPICK, NULL, 0.0, 0.0, 0, 0, "");
/* and lets go */
block->direction= UI_TOP;
ui_positionblock(block, but);
block->win= G.curscreen->mainwin;
event= uiDoBlocks(&listb, 0);
return but->retval;
}
static int ui_do_but_HSVCUBE(uiBut *but)
{
float x, y, col[3], h,s,v;
short mval[2], mvalo[2];
mvalo[0]= mvalo[1]= -32000;
while (get_mbut() & L_MOUSE) {
uiGetMouse(mywinget(), mval);
if(mval[0]!=mvalo[0] || mval[1]!=mvalo[1]) {
mvalo[0]= mval[0];
mvalo[1]= mval[1];
/* relative position within box */
x= ((float)mval[0]-but->x1)/(but->x2-but->x1);
y= ((float)mval[1]-but->y1)/(but->x2-but->x1);
CLAMP(x, 0.001, 0.999);
CLAMP(y, 0.001, 0.999);
/* assign position to color */
ui_get_but_vectorf(but, col);
rgb_to_hsv(col[0], col[1], col[2], &h, &s, &v);
if(but->a1==0) hsv_to_rgb(x, s, y, col, col+1, col+2);
else if(but->a1==1) hsv_to_rgb(x, y, v, col, col+1, col+2);
else hsv_to_rgb(h, y, x, col, col+1, col+2);
ui_set_but_vectorf(but, col);
// update button values and strings
update_picker_buts(but->block, col);
/* we redraw the entire block, but without transparent shadow */
but->block->flag |= UI_BLOCK_NOSHADOW;
uiDrawBlock(but->block);
glFlush(); // flush display in subloops
}
else BIF_wait_for_statechange();
}
return 0;
}
/* ************************************************ */
@ -2178,6 +2409,7 @@ static void edit_but(uiBlock *block, uiBut *but, uiEvent *uevent)
if(didit) setup_file(block);
}
/* is called when LEFTMOUSE is pressed or released
* return: butval or zero
*/
@ -2288,6 +2520,14 @@ static int ui_do_button(uiBlock *block, uiBut *but, uiEvent *uevent)
case INLINK:
retval= ui_do_but_LINK(block, but);
break;
case COL:
if(uevent->val) retval= ui_do_but_COL(but);
break;
case HSVCUBE:
retval= ui_do_but_HSVCUBE(but);
break;
}
block->flag &= ~UI_BLOCK_BUSY;
@ -3129,6 +3369,42 @@ int uiDoBlocks(ListBase *lb, int event)
/* ************** DATA *************** */
/* for buttons pointing to color for example */
void ui_get_but_vectorf(uiBut *but, float *vec)
{
void *poin;
poin= but->poin;
if( but->pointype == CHA ) {
char *cp= (char *)poin;
vec[0]= ((float)cp[0])/255.0;
vec[1]= ((float)cp[1])/255.0;
vec[2]= ((float)cp[2])/255.0;
}
else if( but->pointype == FLO ) {
float *fp= (float *)poin;
VECCOPY(vec, fp);
}
}
/* for buttons pointing to color for example */
void ui_set_but_vectorf(uiBut *but, float *vec)
{
void *poin;
poin= but->poin;
if( but->pointype == CHA ) {
char *cp= (char *)poin;
cp[0]= (char)(0.5 +vec[0]*255.0);
cp[1]= (char)(0.5 +vec[1]*255.0);
cp[2]= (char)(0.5 +vec[2]*255.0);
}
else if( but->pointype == FLO ) {
float *fp= (float *)poin;
VECCOPY(fp, vec);
}
}
double ui_get_but_val(uiBut *but)
{
@ -3441,6 +3717,23 @@ void ui_check_but(uiBut *but)
}
break;
case LABEL:
if( but->pointype==FLO && but->poin) {
value= ui_get_but_val(but);
if(but->a2) { /* amount of digits defined */
if(but->a2==1) sprintf(but->drawstr, "%s%.1f", but->str, value);
else if(but->a2==2) sprintf(but->drawstr, "%s%.2f", but->str, value);
else if(but->a2==3) sprintf(but->drawstr, "%s%.3f", but->str, value);
else sprintf(but->drawstr, "%s%.4f", but->str, value);
}
else {
sprintf(but->drawstr, "%s%.2f", but->str, value);
}
}
else strcpy(but->drawstr, but->str);
break;
case IDPOIN:
id= *(but->idpoin_idpp);
strcpy(but->drawstr, but->str);

@ -1294,39 +1294,41 @@ static void ui_draw_slider(int colorid, float fac, float aspect, float x1, float
// background for pulldowns, pullups, and other frontbuffer drawing temporal menus....
// has to be made themable still (now only color)
void uiDrawMenuBox(float minx, float miny, float maxx, float maxy)
void uiDrawMenuBox(float minx, float miny, float maxx, float maxy, short flag)
{
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glColor4ub(0, 0, 0, 20);
/* to prevent gaps being drawn between box and shadow (rounding errors?) */
fdrawline(minx+3, miny+0.25, maxx+0.25, miny+0.25);
fdrawline(maxx+0.25, miny+0.25, maxx+0.25, maxy-3);
glColor4ub(0, 0, 0, 70);
fdrawline(minx+3, miny, maxx+1, miny);
fdrawline(maxx+1, miny, maxx+1, maxy-3);
glColor4ub(0, 0, 0, 70);
fdrawline(minx+3, miny-1, maxx+1, miny-1);
fdrawline(maxx+1, miny-1, maxx+1, maxy-3);
glColor4ub(0, 0, 0, 55);
fdrawline(minx+3, miny-2, maxx+2, miny-2);
fdrawline(maxx+2, miny-2, maxx+2, maxy-3);
glColor4ub(0, 0, 0, 35);
fdrawline(minx+3, miny-3, maxx+3, miny-3);
fdrawline(maxx+3, miny-3, maxx+3, maxy-3);
glColor4ub(0, 0, 0, 20);
fdrawline(minx+3, miny-4, maxx+4, miny-4);
fdrawline(maxx+4, miny-4, maxx+4, maxy-3);
if( (flag & UI_BLOCK_NOSHADOW)==0) {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
glColor4ub(0, 0, 0, 20);
/* to prevent gaps being drawn between box and shadow (rounding errors?) */
fdrawline(minx+3, miny+0.25, maxx+0.25, miny+0.25);
fdrawline(maxx+0.25, miny+0.25, maxx+0.25, maxy-3);
glColor4ub(0, 0, 0, 70);
fdrawline(minx+3, miny, maxx+1, miny);
fdrawline(maxx+1, miny, maxx+1, maxy-3);
glColor4ub(0, 0, 0, 70);
fdrawline(minx+3, miny-1, maxx+1, miny-1);
fdrawline(maxx+1, miny-1, maxx+1, maxy-3);
glDisable(GL_BLEND);
glColor4ub(0, 0, 0, 55);
fdrawline(minx+3, miny-2, maxx+2, miny-2);
fdrawline(maxx+2, miny-2, maxx+2, maxy-3);
glColor4ub(0, 0, 0, 35);
fdrawline(minx+3, miny-3, maxx+3, miny-3);
fdrawline(maxx+3, miny-3, maxx+3, maxy-3);
glColor4ub(0, 0, 0, 20);
fdrawline(minx+3, miny-4, maxx+4, miny-4);
fdrawline(maxx+4, miny-4, maxx+4, maxy-3);
glDisable(GL_BLEND);
}
BIF_ThemeColor(TH_MENU_BACK);
glRectf(minx, miny, maxx, maxy);
@ -1487,7 +1489,103 @@ static void ui_draw_but_COL(uiBut *but)
}
}
/* draws in resolution of 20x4 colors */
static void ui_draw_but_HSVCUBE(uiBut *but)
{
int a;
float col[3], h,s,v;
float dx, dy, sx1, sx2, sy, x, y;
float col0[4][3]; // left half, rect bottom to top
float col1[4][3]; // right half, rect bottom to top
ui_get_but_vectorf(but, col);
rgb_to_hsv(col[0], col[1], col[2], &h, &s, &v);
/* draw series of gouraud rects */
glShadeModel(GL_SMOOTH);
if(but->a1==0) { // H and V vary
hsv_to_rgb(0.0, s, 0.0, &col1[0][0], &col1[0][1], &col1[0][2]);
hsv_to_rgb(0.0, s, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]);
hsv_to_rgb(0.0, s, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]);
hsv_to_rgb(0.0, s, 1.0, &col1[3][0], &col1[3][1], &col1[3][2]);
x= h; y= v;
}
else if(but->a1==1) { // H and S vary
hsv_to_rgb(0.0, 0.0, v, &col1[0][0], &col1[0][1], &col1[0][2]);
hsv_to_rgb(0.0, 0.333, v, &col1[1][0], &col1[1][1], &col1[1][2]);
hsv_to_rgb(0.0, 0.666, v, &col1[2][0], &col1[2][1], &col1[2][2]);
hsv_to_rgb(0.0, 1.0, v, &col1[3][0], &col1[3][1], &col1[3][2]);
x= h; y= s;
}
else { // S and V vary
hsv_to_rgb(h, 0.0, 0.0, &col1[0][0], &col1[0][1], &col1[0][2]);
hsv_to_rgb(h, 0.333, 0.0, &col1[1][0], &col1[1][1], &col1[1][2]);
hsv_to_rgb(h, 0.666, 0.0, &col1[2][0], &col1[2][1], &col1[2][2]);
hsv_to_rgb(h, 1.0, 0.0, &col1[3][0], &col1[3][1], &col1[3][2]);
x= v; y= s;
}
for(dx=0.0; dx<1.0; dx+= 0.05) {
// previous color
VECCOPY(col0[0], col1[0]);
VECCOPY(col0[1], col1[1]);
VECCOPY(col0[2], col1[2]);
VECCOPY(col0[3], col1[3]);
// new color
if(but->a1==0) { // H and V vary
hsv_to_rgb(dx, s, 0.0, &col1[0][0], &col1[0][1], &col1[0][2]);
hsv_to_rgb(dx, s, 0.333, &col1[1][0], &col1[1][1], &col1[1][2]);
hsv_to_rgb(dx, s, 0.666, &col1[2][0], &col1[2][1], &col1[2][2]);
hsv_to_rgb(dx, s, 1.0, &col1[3][0], &col1[3][1], &col1[3][2]);
}
else if(but->a1==1) { // H and S vary
hsv_to_rgb(dx, 0.0, v, &col1[0][0], &col1[0][1], &col1[0][2]);
hsv_to_rgb(dx, 0.333, v, &col1[1][0], &col1[1][1], &col1[1][2]);
hsv_to_rgb(dx, 0.666, v, &col1[2][0], &col1[2][1], &col1[2][2]);
hsv_to_rgb(dx, 1.0, v, &col1[3][0], &col1[3][1], &col1[3][2]);
}
else { // S and V vary
hsv_to_rgb(h, 0.0, dx, &col1[0][0], &col1[0][1], &col1[0][2]);
hsv_to_rgb(h, 0.333, dx, &col1[1][0], &col1[1][1], &col1[1][2]);
hsv_to_rgb(h, 0.666, dx, &col1[2][0], &col1[2][1], &col1[2][2]);
hsv_to_rgb(h, 1.0, dx, &col1[3][0], &col1[3][1], &col1[3][2]);
}
// rect
sx1= but->x1 + dx*(but->x2-but->x1);
sx2= but->x1 + (dx+0.05)*(but->x2-but->x1);
sy= but->y1;
dy= (but->y2-but->y1)/3.0;
glBegin(GL_QUADS);
for(a=0; a<3; a++, sy+=dy) {
glColor3fv(col0[a]);
glVertex2f(sx1, sy);
glColor3fv(col1[a]);
glVertex2f(sx2, sy);
glColor3fv(col1[a+1]);
glVertex2f(sx2, sy+dy);
glColor3fv(col0[a+1]);
glVertex2f(sx1, sy+dy);
}
glEnd();
}
glShadeModel(GL_FLAT);
/* cursor */
sdrawXORcirc((short)(but->x1 + x*(but->x2-but->x1)),
(short)(but->y1 + y*(but->y2-but->y1)), 3.0);
/* outline */
glColor3ub(0, 0, 0);
fdrawbox((but->x1), (but->y1), (but->x2), (but->y2));
}
/* nothing! */
static void ui_draw_nothing(int type, int colorid, float asp, float x1, float y1, float x2, float y2, int flag)
@ -1574,6 +1672,10 @@ void ui_draw_but(uiBut *but)
ui_draw_but_COL(but); // black box with color
break;
case HSVCUBE:
ui_draw_but_HSVCUBE(but); // box for colorpicker, three types
break;
case LINK:
case INLINK:
ui_draw_icon(but, but->icon);

@ -952,7 +952,7 @@ void toolbox(void)
bgntoolbox();
glColor3ub(0xB0, 0xB0, 0xB0);
uiDrawMenuBox((float)tbx1, (float)tby1-1, (float)tbx2, (float)tby2);
uiDrawMenuBox((float)tbx1, (float)tby1-1, (float)tbx2, (float)tby2, 0);
drawtoolbox();
/*