diff options
author | Ton Roosendaal <ton@blender.org> | 2009-06-12 18:22:27 +0400 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2009-06-12 18:22:27 +0400 |
commit | a62bec6667c7ae0df7d0003b566a466b1047d728 (patch) | |
tree | 40e2baf1b662083d27a0f2dc5ccee310594a4ee0 /source/blender/editors | |
parent | 32b34f82fd782d45ee4b5389a1f961bc1f463631 (diff) |
2.5
Quick Color picker alternative!
- only a color circle + value slider
- exits immediate after use, or slight mouse move outside picker
- use scrollwheel to change HSV 'value'. Also works while picking.
- added nicer AA'ed cursor in picker
- All color swatches change 'value' on ALT+Wheel mouse-over
Old picker is still there, under SHIFT+click on swatch. Needs
evaluation... part of UI keymap? Per button type? Or divide
picker in left/right? Or just have all those old picker buttons
in another panel... I'm not to fond of this giant old popup.
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/include/UI_interface.h | 1 | ||||
-rw-r--r-- | source/blender/editors/interface/interface.c | 2 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_handlers.c | 107 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_intern.h | 5 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_regions.c | 92 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_widgets.c | 115 | ||||
-rw-r--r-- | source/blender/editors/preview/previewrender.c | 1 |
7 files changed, 305 insertions, 18 deletions
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 7b18380b54f..dea408f818a 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -195,6 +195,7 @@ typedef struct uiLayout uiLayout; #define OPTIONN (39<<9) #define SEARCH_MENU (40<<9) #define BUT_EXTRA (41<<9) +#define HSVCIRCLE (42<<9) #define BUTTYPE (63<<9) /* Drawing diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 79e32d4a5f1..e37f7d2158c 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -2232,7 +2232,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, char *str, short } } - if(but->type==HSVCUBE) { /* hsv buttons temp storage */ + if(ELEM(but->type, HSVCUBE, HSVCIRCLE)) { /* hsv buttons temp storage */ float rgb[3]; ui_get_but_vectorf(but, rgb); rgb_to_hsv(rgb[0], rgb[1], rgb[2], but->hsv, but->hsv+1, but->hsv+2); diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 6eddb564945..bda16584811 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -621,6 +621,7 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut break; case BUT_NORMAL: case HSVCUBE: + case HSVCIRCLE: ui_apply_but_VEC(C, but, data); break; case BUT_COLORBAND: @@ -1432,7 +1433,7 @@ static void ui_numedit_begin(uiBut *but, uiHandleButtonData *data) data->coba= (ColorBand*)but->poin; but->editcoba= data->coba; } - else if(ELEM(but->type, BUT_NORMAL, HSVCUBE)) { + else if(ELEM3(but->type, BUT_NORMAL, HSVCUBE, HSVCIRCLE)) { ui_get_but_vectorf(but, data->origvec); VECCOPY(data->vec, data->origvec); but->editvec= data->vec; @@ -2100,6 +2101,25 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, wm return WM_UI_HANDLER_BREAK; } } + else if(but->type==COL) { + if( ELEM(event->type, WHEELDOWNMOUSE, WHEELUPMOUSE) && event->alt) { + float col[3]; + + ui_get_but_vectorf(but, col); + rgb_to_hsv(col[0], col[1], col[2], but->hsv, but->hsv+1, but->hsv+2); + + if(event->type==WHEELDOWNMOUSE) + but->hsv[2]= CLAMPIS(but->hsv[2]-0.05f, 0.0f, 1.0f); + else + but->hsv[2]= CLAMPIS(but->hsv[2]+0.05f, 0.0f, 1.0f); + + hsv_to_rgb(but->hsv[0], but->hsv[1], but->hsv[2], data->vec, data->vec+1, data->vec+2); + + button_activate_state(C, but, BUTTON_STATE_EXIT); + ui_apply_button(C, but->block, but, data, 1); + return WM_UI_HANDLER_BREAK; + } + } } return WM_UI_HANDLER_CONTINUE; @@ -2223,8 +2243,11 @@ static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx, but->hsv[2]= x; but->hsv[1]= y; } - else + else if(but->a1==3) { but->hsv[0]= x; + } + else + but->hsv[2]= y; ui_set_but_hsv(but); // converts to rgb @@ -2276,6 +2299,79 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu return WM_UI_HANDLER_CONTINUE; } +static int ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, int mx, int my) +{ + rcti rect; + int changed= 1; + + rect.xmin= but->x1; rect.xmax= but->x2; + rect.ymin= but->y1; rect.ymax= but->y2; + + ui_hsvcircle_vals_from_pos(but->hsv, but->hsv+1, &rect, (float)mx, (float)my); + + ui_set_but_hsv(but); // converts to rgb + + // update button values and strings + // XXX ui_update_block_buts_hsv(but->block, but->hsv); + + data->draglastx= mx; + data->draglasty= my; + + return changed; +} + + +static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, wmEvent *event) +{ + int mx, my; + + mx= event->x; + my= event->y; + ui_window_to_block(data->region, block, &mx, &my); + + if(data->state == BUTTON_STATE_HIGHLIGHT) { + if(event->type==LEFTMOUSE && event->val==KM_PRESS) { + data->dragstartx= mx; + data->dragstarty= my; + data->draglastx= mx; + data->draglasty= my; + button_activate_state(C, but, BUTTON_STATE_NUM_EDITING); + + /* also do drag the first time */ + if(ui_numedit_but_HSVCIRCLE(but, data, mx, my)) + ui_numedit_apply(C, block, but, data); + + return WM_UI_HANDLER_BREAK; + } + } + else if(data->state == BUTTON_STATE_NUM_EDITING) { + /* XXX hardcoded keymap check.... */ + if(event->type == WHEELDOWNMOUSE) { + but->hsv[2]= CLAMPIS(but->hsv[2]-0.05f, 0.0f, 1.0f); + ui_set_but_hsv(but); // converts to rgb + ui_numedit_apply(C, block, but, data); + } + else if(event->type == WHEELUPMOUSE) { + but->hsv[2]= CLAMPIS(but->hsv[2]+0.05f, 0.0f, 1.0f); + ui_set_but_hsv(but); // converts to rgb + ui_numedit_apply(C, block, but, data); + } + else if(event->type == MOUSEMOVE) { + if(mx!=data->draglastx || my!=data->draglasty) { + if(ui_numedit_but_HSVCIRCLE(but, data, mx, my)) + ui_numedit_apply(C, block, but, data); + } + } + else if(event->type==LEFTMOUSE && event->val!=KM_PRESS) + button_activate_state(C, but, BUTTON_STATE_EXIT); + + return WM_UI_HANDLER_BREAK; + } + + return WM_UI_HANDLER_CONTINUE; +} + + static int verg_colorband(const void *a1, const void *a2) { const CBData *x1=a1, *x2=a2; @@ -2847,6 +2943,9 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event) case HSVCUBE: retval= ui_do_but_HSVCUBE(C, block, but, data, event); break; + case HSVCIRCLE: + retval= ui_do_but_HSVCIRCLE(C, block, but, data, event); + break; #ifdef INTERNATIONAL case CHARTAB: retval= ui_do_but_CHARTAB(C, block, but, data, event); @@ -3545,8 +3644,10 @@ int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle *menu, if(event->type == MOUSEMOVE) ui_mouse_motion_towards_init(menu, mx, my, 0); + /* first block own event func */ + if(block->block_event_func && block->block_event_func(C, block, event)); /* events not for active search menu button */ - if(but==NULL || but->type!=SEARCH_MENU) { + else if(but==NULL || but->type!=SEARCH_MENU) { switch(event->type) { /* closing sublevels of pulldowns */ case LEFTARROWKEY: diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 08fa6434aa8..83d3ec7fc46 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -254,6 +254,9 @@ struct uiBlock { uiBlockHandleFunc handle_func; void *handle_func_arg; + /* custom extra handling */ + int (*block_event_func)(const struct bContext *C, struct uiBlock *, struct wmEvent *); + /* extra draw function for custom blocks */ void (*drawextra)(const struct bContext *C, void *idv, rcti *rect); @@ -306,6 +309,8 @@ extern void ui_set_but_hsv(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_hsvcircle_vals_from_pos(float *valrad, float *valdist, rcti *rect, float mx, float my); + extern void ui_get_but_string(uiBut *but, char *str, int maxlen); extern int ui_set_but_string(struct bContext *C, uiBut *but, const char *str); extern int ui_get_but_string_max_length(uiBut *but); diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 5d562805b51..89654f0ffab 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -1393,6 +1393,7 @@ static void update_picker_hex(uiBlock *block, float *rgb) } } +/* also used by small picker, be careful with name checks below... */ void ui_update_block_buts_hsv(uiBlock *block, float *hsv) { uiBut *bt; @@ -1406,7 +1407,7 @@ void ui_update_block_buts_hsv(uiBlock *block, float *hsv) update_picker_hex(block, rgb); for(bt= block->buttons.first; bt; bt= bt->next) { - if(bt->type==HSVCUBE) { + if(ELEM(bt->type, HSVCUBE, HSVCIRCLE)) { VECCOPY(bt->hsv, hsv); ui_set_but_hsv(bt); } @@ -1701,22 +1702,103 @@ void uiBlockPickerButtons(uiBlock *block, float *col, float *hsv, float *old, ch uiBlockEndAlign(block); } +/* bt1 is num but, hsv1 is pointer to original color in hsv space*/ +/* callback to handle changes */ +static void do_picker_small_cb(bContext *C, void *bt1, void *hsv1) +{ + uiBut *but1= (uiBut *)bt1; + uiPopupBlockHandle *popup= but1->block->handle; + float *hsv= (float *)hsv1; + float *fp= NULL; + + fp= (float *)but1->poin; + rgb_to_hsv(fp[0], fp[1], fp[2], hsv, hsv+1, hsv+2); + + ui_update_block_buts_hsv(but1->block, hsv); + + if(popup) + popup->menuretval= UI_RETURN_UPDATE; +} + + +/* only the color, a circle, slider */ +void uiBlockPickerSmall(uiBlock *block, float *col, float *hsv, float *old, char *hexcol, char mode, short retval) +{ + uiBut *bt; + + VECCOPY(old, col); // old color stored there, for palette_cb to work + + /* HS circle */ + bt= uiDefButF(block, HSVCIRCLE, retval, "", 0, 0,SPICK,SPICK, col, 0.0, 0.0, 0, 0, ""); + uiButSetFunc(bt, do_picker_small_cb, bt, hsv); + + /* value */ + bt= uiDefButF(block, HSVCUBE, retval, "", SPICK+DPICK,0,14,SPICK, col, 0.0, 0.0, 4, 0, ""); + uiButSetFunc(bt, do_picker_small_cb, bt, hsv); + +} + +static int ui_picker_small_wheel(const bContext *C, uiBlock *block, wmEvent *event) +{ + float add= 0.0f; + + if(event->type==WHEELUPMOUSE) + add= 0.05f; + else if(event->type==WHEELDOWNMOUSE) + add= -0.05f; + + if(add!=0.0f) { + uiBut *but; + + for(but= block->buttons.first; but; but= but->next) { + if(but->type==HSVCUBE && but->active==NULL) { + uiPopupBlockHandle *popup= block->handle; + float col[3]; + + ui_get_but_vectorf(but, col); + + rgb_to_hsv(col[0], col[1], col[2], but->hsv, but->hsv+1, but->hsv+2); + but->hsv[2]= CLAMPIS(but->hsv[2]+add, 0.0f, 1.0f); + hsv_to_rgb(but->hsv[0], but->hsv[1], but->hsv[2], col, col+1, col+2); + + ui_set_but_vectorf(but, col); + + ui_update_block_buts_hsv(block, but->hsv); + if(popup) + popup->menuretval= UI_RETURN_UPDATE; + + return 1; + } + } + } + return 0; +} + uiBlock *ui_block_func_COL(bContext *C, uiPopupBlockHandle *handle, void *arg_but) { + wmWindow *win= CTX_wm_window(C); // XXX temp, needs to become keymap to detect type? uiBut *but= arg_but; uiBlock *block; static float hsvcol[3], oldcol[3]; static char hexcol[128]; block= uiBeginBlock(C, handle->region, "colorpicker", UI_EMBOSS); - block->flag= UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_KEEP_OPEN; VECCOPY(handle->retvec, but->editvec); - uiBlockPickerButtons(block, handle->retvec, hsvcol, oldcol, hexcol, 'p', 0); - + if(win->eventstate->shift) { + uiBlockPickerButtons(block, handle->retvec, hsvcol, oldcol, hexcol, 'p', 0); + block->flag= UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_KEEP_OPEN; + uiBoundsBlock(block, 3); + } + else { + uiBlockPickerSmall(block, handle->retvec, hsvcol, oldcol, hexcol, 'p', 0); + block->flag= UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1; + uiBoundsBlock(block, 10); + + block->block_event_func= ui_picker_small_wheel; + } /* and lets go */ block->direction= UI_TOP; - uiBoundsBlock(block, 3); return block; } diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index ab8569bf47e..27f42da9fa0 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -1087,6 +1087,20 @@ static struct uiWidgetColors wcol_box= { 0, 0 }; +/* free wcol struct to play with */ +static struct uiWidgetColors wcol_tmp= { + {0, 0, 0, 255}, + {128, 128, 128, 255}, + {100, 100, 100, 255}, + {25, 25, 25, 255}, + + {0, 0, 0, 255}, + {255, 255, 255, 255}, + + 0, + 0, 0 +}; + /* called for theme init (new theme) and versions */ void ui_widget_color_init(ThemeUI *tui) @@ -1262,9 +1276,28 @@ static void widget_menu_back(uiWidgetColors *wcol, rcti *rect, int flag, int dir glDisable(GL_BLEND); } -/* ************ custom buttons, old stuff ************** */ -static void ui_hsvcircle_to_val(float *valrad, float *valdist, rcti *rect, float mx, float my) +static void ui_hsv_cursor(float x, float y) +{ + + glPushMatrix(); + glTranslatef(x, y, 0.0f); + + glColor3f(1.0f, 1.0f, 1.0f); + glutil_draw_filled_arc(0.0f, M_PI*2.0, 3.0f, 8); + + glEnable(GL_BLEND); + glEnable(GL_LINE_SMOOTH ); + glColor3f(0.0f, 0.0f, 0.0f); + glutil_draw_lined_arc(0.0f, M_PI*2.0, 3.0f, 12); + glDisable(GL_BLEND); + glDisable(GL_LINE_SMOOTH ); + + glPopMatrix(); + +} + +void ui_hsvcircle_vals_from_pos(float *valrad, float *valdist, rcti *rect, float mx, float my) { /* duplication of code... well, simple is better now */ float centx= (float)(rect->xmin + rect->xmax)/2; @@ -1319,7 +1352,7 @@ void ui_draw_but_HSVCIRCLE(uiBut *but, rcti *rect) float si= sin(ang); float co= cos(ang); - ui_hsvcircle_to_val(hsv, hsv+1, rect, centx + co*radius, centy + si*radius); + ui_hsvcircle_vals_from_pos(hsv, hsv+1, rect, centx + co*radius, centy + si*radius); hsv_to_rgb(hsv[0], hsv[1], hsv[2], col, col+1, col+2); glColor3fv(col); glVertex2f( centx + co*radius, centy + si*radius); @@ -1327,8 +1360,27 @@ void ui_draw_but_HSVCIRCLE(uiBut *but, rcti *rect) glEnd(); glShadeModel(GL_FLAT); + + /* fully rounded outline */ + glPushMatrix(); + glTranslatef(centx, centy, 0.0f); + glEnable(GL_BLEND); + glEnable(GL_LINE_SMOOTH ); + glColor3f(0.0f, 0.0f, 0.0f); + glutil_draw_lined_arc(0.0f, M_PI*2.0, radius, tot); + glDisable(GL_BLEND); + glDisable(GL_LINE_SMOOTH ); + glPopMatrix(); + + /* cursor */ + ang= 2.0f*M_PI*but->hsv[0] + 0.5f*M_PI; + radius= but->hsv[1]*radius; + ui_hsv_cursor(centx + cos(-ang)*radius, centy + sin(-ang)*radius); + } +/* ************ custom buttons, old stuff ************** */ + /* draws in resolution of 20x4 colors */ static void ui_draw_but_HSVCUBE(uiBut *but, rcti *rect) { @@ -1366,7 +1418,7 @@ static void ui_draw_but_HSVCUBE(uiBut *but, rcti *rect) hsv_to_rgb(h, 1.0, 0.0, &col1[3][0], &col1[3][1], &col1[3][2]); x= v; y= s; } - else { // only hue slider + else if(but->a1==3) { // only hue slider hsv_to_rgb(0.0, 1.0, 1.0, &col1[0][0], &col1[0][1], &col1[0][2]); VECCOPY(col1[1], col1[0]); VECCOPY(col1[2], col1[0]); @@ -1400,7 +1452,7 @@ static void ui_draw_but_HSVCUBE(uiBut *but, rcti *rect) 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]); } - else { // only H + else if(but->a1==3) { // only H hsv_to_rgb(dx, 1.0, 1.0, &col1[0][0], &col1[0][1], &col1[0][2]); VECCOPY(col1[1], col1[0]); VECCOPY(col1[2], col1[0]); @@ -1438,13 +1490,42 @@ static void ui_draw_but_HSVCUBE(uiBut *but, rcti *rect) CLAMP(x, rect->xmin+3.0, rect->xmax-3.0); CLAMP(y, rect->ymin+3.0, rect->ymax-3.0); - fdrawXORcirc(x, y, 3.1); + ui_hsv_cursor(x, y); /* outline */ glColor3ub(0, 0, 0); fdrawbox((rect->xmin), (rect->ymin), (rect->xmax), (rect->ymax)); } +/* vertical 'value' slider, using new widget code */ +static void ui_draw_but_HSV_v(uiBut *but, rcti *rect) +{ + uiWidgetBase wtb; + float rad= 0.5f*(rect->xmax - rect->xmin); + float x, y; + + widget_init(&wtb); + + /* fully rounded */ + round_box_edges(&wtb, 15, rect, rad); + + /* setup temp colors */ + wcol_tmp.outline[0]= wcol_tmp.outline[1]= wcol_tmp.outline[2]= 0; + wcol_tmp.inner[0]= wcol_tmp.inner[1]= wcol_tmp.inner[2]= 128; + wcol_tmp.shadetop= 127; + wcol_tmp.shadedown= -128; + wcol_tmp.shaded= 1; + + widgetbase_draw(&wtb, &wcol_tmp); + + /* cursor */ + x= rect->xmin + 0.5f*(rect->xmax-rect->xmin); + y= rect->ymin + but->hsv[2]*(rect->ymax-rect->ymin); + CLAMP(y, rect->ymin+3.0, rect->ymax-3.0); + + ui_hsv_cursor(x, y); + +} /* ************ button callbacks, draw ***************** */ @@ -1930,35 +2011,43 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct fstyle= &style->widgetlabel; } break; + case SEPR: break; + case BUT: wt= widget_type(UI_WTYPE_EXEC); break; case NUM: wt= widget_type(UI_WTYPE_NUMBER); break; + case NUMSLI: case HSVSLI: wt= widget_type(UI_WTYPE_SLIDER); break; + case ROW: wt= widget_type(UI_WTYPE_RADIO); break; + case TEX: wt= widget_type(UI_WTYPE_NAME); break; + case SEARCH_MENU: wt= widget_type(UI_WTYPE_NAME); if(but->block->flag & UI_BLOCK_LOOP) wt->wcol_theme= &btheme->tui.wcol_menu_back; break; + case TOGBUT: case TOG: case TOGN: case TOG3: wt= widget_type(UI_WTYPE_TOGGLE); break; + case OPTION: case OPTIONN: if (!(but->flag & UI_HAS_ICON)) { @@ -1968,6 +2057,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct else wt= widget_type(UI_WTYPE_TOGGLE); break; + case MENU: case BLOCK: case ICONTEXTROW: @@ -1994,16 +2084,25 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct widget_draw_extra_mask(C, but, widget_type(UI_WTYPE_BOX), rect); break; - // XXX four old button types case HSVCUBE: - ui_draw_but_HSVCUBE(but, rect); + if(but->a1==4) // vertical V slider, uses new widget draw now + ui_draw_but_HSV_v(but, rect); + else // other HSV pickers... + ui_draw_but_HSVCUBE(but, rect); + break; + + case HSVCIRCLE: + ui_draw_but_HSVCIRCLE(but, rect); break; + case BUT_COLORBAND: ui_draw_but_COLORBAND(but, &tui->wcol_regular, rect); break; + case BUT_NORMAL: ui_draw_but_NORMAL(but, &tui->wcol_regular, rect); break; + case BUT_CURVE: ui_draw_but_CURVE(ar, but, &tui->wcol_regular, rect); break; diff --git a/source/blender/editors/preview/previewrender.c b/source/blender/editors/preview/previewrender.c index 1435ca7290b..1ce20fcb0af 100644 --- a/source/blender/editors/preview/previewrender.c +++ b/source/blender/editors/preview/previewrender.c @@ -665,7 +665,6 @@ void ED_preview_draw(const bContext *C, void *idp, rcti *rect) } if(ok==0) { - printf("added shader job\n"); ED_preview_shader_job(C, sa, idp, newx, newy); } } |