Color Picker work:
authorMatt Ebb <matt@mke3.net>
Thu, 7 Jan 2010 09:55:11 +0000 (09:55 +0000)
committerMatt Ebb <matt@mke3.net>
Thu, 7 Jan 2010 09:55:11 +0000 (09:55 +0000)
Restored the old Eyedropper tool from the 2.4 colour picker. Now it's an operator,
working nicely using rna properties (fixes #19475 and some todo items)

This ended up being a bit more work than expected, it involved converting the
colour picker to use RNA properties directly, rather than temporary values. This has
several advantages, including being able to type in RGB values greater than 1,
however there are still some redraw issues with sliders.

Also removed the alternate color pickers after this time spent testing, the current one
should be sufficient, or alternatives to the wheel can possibly become preferences
in the current design.

Converting the picker to RNA also made it very trivial to make a cool new
ColorWheel template, which can be embedded in UI layouts. I've enabled it already
in texture/vertex paint brush properties and the sequence editor color correction:
http://mke3.net/blender/devel/2.5/colorwheels.jpg

14 files changed:
release/scripts/ui/space_image.py
release/scripts/ui/space_sequencer.py
release/scripts/ui/space_view3d_toolbar.py
source/blender/editors/include/UI_interface.h
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_anim.c
source/blender/editors/interface/interface_handlers.c
source/blender/editors/interface/interface_intern.h
source/blender/editors/interface/interface_layout.c
source/blender/editors/interface/interface_ops.c
source/blender/editors/interface/interface_regions.c
source/blender/editors/interface/interface_templates.c
source/blender/editors/interface/interface_widgets.c
source/blender/makesrna/intern/rna_ui_api.c

index 27d0aa913496180e465806d55a7ddc1baf42b264..5d6bc70dd35ca61b9d7330fd3b0a74343a685c98 100644 (file)
@@ -475,6 +475,7 @@ class IMAGE_PT_paint(bpy.types.Panel):
 
         if brush:
             col = layout.column()
+            col.template_color_wheel(brush, "color", value_slider=True)
             col.prop(brush, "color", text="")
 
             row = col.row(align=True)
index 8edadb96de3b3b64296d7ea25cbc7cc5a6a496c7..99298cc3988104acf0a0d13de5e7bf70a88d352f 100644 (file)
@@ -606,13 +606,16 @@ class SEQUENCER_PT_filter(SequencerButtonsPanel):
             row = layout.row()
             row.active = strip.use_color_balance
             col = row.column()
-            col.prop(strip.color_balance, "lift")
+            col.template_color_wheel(strip.color_balance, "lift", value_slider=False)
+            col.row().prop(strip.color_balance, "lift")
             col.prop(strip.color_balance, "inverse_lift", text="Inverse")
             col = row.column()
-            col.prop(strip.color_balance, "gamma")
+            col.template_color_wheel(strip.color_balance, "gamma", value_slider=False)
+            col.row().prop(strip.color_balance, "gamma")
             col.prop(strip.color_balance, "inverse_gamma", text="Inverse")
             col = row.column()
-            col.prop(strip.color_balance, "gain")
+            col.template_color_wheel(strip.color_balance, "gain", value_slider=False)
+            col.row().prop(strip.color_balance, "gain")
             col.prop(strip.color_balance, "inverse_gain", text="Inverse")
 
 
index 07500f6cc7cce228f96547fe0362c5d513d54fe5..52b0cf3d0f8fc0a4d1db73cc1997a676d2ee81b2 100644 (file)
@@ -571,6 +571,7 @@ class VIEW3D_PT_tools_brush(PaintPanel):
 
         elif context.texture_paint_object and brush:
             col = layout.column()
+            col.template_color_wheel(brush, "color", value_slider=True)
             col.prop(brush, "color", text="")
 
             row = col.row(align=True)
@@ -610,6 +611,7 @@ class VIEW3D_PT_tools_brush(PaintPanel):
 
         elif context.vertex_paint_object and brush:
             col = layout.column()
+            col.template_color_wheel(brush, "color", value_slider=True)
             col.prop(brush, "color", text="")
 
             row = col.row(align=True)
index 243e55b851a45e9a4292784ca3581bc9e8ce1992..0b7499b947a23a5e72ff457b8025685d29eae06c 100644 (file)
@@ -456,7 +456,6 @@ uiBut *uiDefHotKeyevtButS(uiBlock *block, int retval, char *str, short x1, short
 uiBut *uiDefSearchBut(uiBlock *block, void *arg, int retval, int icon, int maxlen, short x1, short y1, short x2, short y2, float a1, float a2, char *tip);
 
 void uiBlockPickerButtons(struct uiBlock *block, float *col, float *hsv, float *old, char *hexcol, char mode, short retval);
-void uiBlockColorbandButtons(struct uiBlock *block, struct ColorBand *coba, struct rctf *butr, int event);
 
 uiBut *uiDefAutoButR(uiBlock *block, struct PointerRNA *ptr, struct PropertyRNA *prop, int index, char *name, int icon, int x1, int y1, int x2, int y2);
 void uiDefAutoButsRNA(const struct bContext *C, uiLayout *layout, struct PointerRNA *ptr, int columns);
@@ -654,6 +653,7 @@ uiLayout *uiTemplateConstraint(uiLayout *layout, struct PointerRNA *ptr);
 void uiTemplatePreview(uiLayout *layout, struct ID *id, struct ID *parent, struct MTex *slot);
 void uiTemplateColorRamp(uiLayout *layout, struct PointerRNA *ptr, char *propname, int expand);
 void uiTemplateCurveMapping(uiLayout *layout, struct PointerRNA *ptr, char *propname, int type, int levels, int brush);
+void uiTemplateColorWheel(uiLayout *layout, struct PointerRNA *ptr, char *propname, int value_slider);
 void uiTemplateTriColorSet(uiLayout *layout, struct PointerRNA *ptr, char *propname);
 void uiTemplateLayers(uiLayout *layout, struct PointerRNA *ptr, char *propname,
                      PointerRNA *used_ptr, char *used_propname, int active_layer);
index 56157386d4bb6be843686143642e8f9c9bd31da0..5c91a91e447cdb954ff9f04a1d7069c46be10426 100644 (file)
@@ -1116,7 +1116,6 @@ void ui_get_but_vectorf(uiBut *but, float *vec)
 
        if(but->editvec) {
                VECCOPY(vec, but->editvec);
-               return;
        }
 
        if(but->rnaprop) {
@@ -1152,7 +1151,6 @@ void ui_set_but_vectorf(uiBut *but, float *vec)
 
        if(but->editvec) {
                VECCOPY(but->editvec, vec);
-               return;
        }
 
        if(but->rnaprop) {
index acfd48e02699e8ce5f159c7fc0ffe54d533f0f73..e35ffade342ba01f2f4fcc111559f80f4226328c 100644 (file)
@@ -168,7 +168,7 @@ void uiAnimContextProperty(const bContext *C, struct PointerRNA *ptr, struct Pro
        if(ar) {
                for(block=ar->uiblocks.first; block; block=block->next) {
                        for(but=block->buttons.first; but; but= but->next) {
-                               if(but->active && but->rnapoin.id.data) {
+                               if((but->active || but->flag & UI_BUT_LAST_ACTIVE) && but->rnapoin.id.data) {
                                        *ptr= but->rnapoin;
                                        *prop= but->rnaprop;
                                        *index= but->rnaindex;
index fa5d60a20f6f5a24f7ac55ae90fcb9a2221de5d1..4c40f37e1953e47daf22658c776967c8009eb0d9 100644 (file)
@@ -402,11 +402,7 @@ static void ui_apply_but_BUTM(bContext *C, uiBut *but, uiHandleButtonData *data)
 
 static void ui_apply_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data)
 {
-       if(but->type == COL) {
-               if(but->a1 != -1) // this is not a color picker (weak!)
-                       ui_set_but_vectorf(but, data->vec);
-       }
-       else if(ELEM3(but->type, MENU, ICONROW, ICONTEXTROW))
+       if(ELEM3(but->type, MENU, ICONROW, ICONTEXTROW))
                ui_set_but_val(but, data->value);
 
        ui_check_but(but);
@@ -2586,6 +2582,7 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, wm
                                        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);
+                               ui_set_but_vectorf(but, data->vec);
                                
                                button_activate_state(C, but, BUTTON_STATE_EXIT);
                                ui_apply_button(C, but->block, but, data, 1);
@@ -2694,6 +2691,7 @@ static int ui_do_but_NORMAL(bContext *C, uiBlock *block, uiBut *but, uiHandleBut
 
 static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx, int my)
 {
+       float rgb[3], hsv[3];
        float x, y;
        int changed= 1;
        int color_profile = but->block->color_profile;
@@ -2702,6 +2700,9 @@ static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx,
                if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA)
                        color_profile = BLI_PR_NONE;
        }
+       
+       ui_get_but_vectorf(but, rgb);
+       rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
                
        /* relative position within box */
        x= ((float)mx-but->x1)/(but->x2-but->x1);
@@ -2710,31 +2711,29 @@ static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx,
        CLAMP(y, 0.0, 1.0);
        
        if(but->a1==0) {
-               but->hsv[0]= x; 
-               but->hsv[2]= y; 
+               hsv[0]= x; 
+               hsv[2]= y; 
        }
        else if(but->a1==1) {
-               but->hsv[0]= x;                                 
-               but->hsv[1]= y;                                 
+               hsv[0]= x;                              
+               hsv[1]= y;                              
        }
        else if(but->a1==2) {
-               but->hsv[2]= x; 
-               but->hsv[1]= y; 
+               hsv[2]= x; 
+               hsv[1]= y; 
        }
        else if(but->a1==3) {
-               but->hsv[0]= x; 
+               hsv[0]= x; 
        }
        else {
                /* vertical 'value' strip */
-               but->hsv[2]= y; 
+               hsv[2]= y; 
                if (color_profile)
-                       but->hsv[2] = srgb_to_linearrgb(but->hsv[2]);
+                       hsv[2] = srgb_to_linearrgb(hsv[2]);
        }
 
-       ui_set_but_hsv(but);    // converts to rgb
-       
-       // update button values and strings
-       ui_update_block_buts_hsv(but->block, but->hsv);
+       hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2);
+       ui_set_but_vectorf(but, rgb);
 
        data->draglastx= mx;
        data->draglasty= my;
@@ -2785,16 +2784,18 @@ static int ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, int mx
 {
        rcti rect;
        int changed= 1;
-
+       float rgb[3], hsv[3];
+       
        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_get_but_vectorf(but, rgb);
+       rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
        
-       ui_set_but_hsv(but);    // converts to rgb
+       ui_hsvcircle_vals_from_pos(hsv, hsv+1, &rect, (float)mx, (float)my);
        
-       // update button values and strings
-       // XXX ui_update_block_buts_hsv(but->block, but->hsv);
+       hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2);
+       ui_set_but_vectorf(but, rgb);
        
        data->draglastx= mx;
        data->draglasty= my;
index 72fa949c2b84c01eec58568298cd834db4adfa7d..5dec1e7f075621c2fff225d4c0a2b55c11551684 100644 (file)
@@ -348,7 +348,6 @@ extern void ui_set_but_soft_range(uiBut *but, double value);
 extern void ui_check_but(uiBut *but);
 extern int  ui_is_but_float(uiBut *but);
 extern int  ui_is_but_unit(uiBut *but);
-extern void ui_update_block_buts_hsv(uiBlock *block, float *hsv);
 
 extern void ui_bounds_block(uiBlock *block);
 extern void ui_block_translate(uiBlock *block, int x, int y);
index 14f8c2c531fe5351ebe1785008a1031670f5250c..57102f4ad50846ae53d36b35ba6b15e55cfa1a71 100644 (file)
@@ -409,7 +409,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, char *name, int icon
                }
        }
        else {
-               if(ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA))
+               if(ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA) && !expand)
                        uiDefAutoButR(block, ptr, prop, -1, "", 0, 0, 0, w, UI_UNIT_Y);
 
                if(!ELEM(subtype, PROP_COLOR, PROP_COLOR_GAMMA) || expand) {
index f016ffe19aeba1e75e3b81c3af3f3559e263f4c5..c66dd998fd4e0111d6e60ee1e3180eb531ef4d73 100644 (file)
@@ -40,6 +40,7 @@
 #include "DNA_view2d_types.h"
 
 #include "BLI_blenlib.h"
+#include "BLI_math_color.h"
 
 #include "BKE_context.h"
 #include "BKE_utildefines.h"
 
 /* ********************************************************** */
 
+typedef struct Eyedropper {
+       PointerRNA ptr;
+       PropertyRNA *prop;
+       int index;
+} Eyedropper;
+
+static int eyedropper_init(bContext *C, wmOperator *op)
+{
+       Eyedropper *eye;
+       
+       op->customdata= eye= MEM_callocN(sizeof(Eyedropper), "Eyedropper");
+       
+       uiAnimContextProperty(C, &eye->ptr, &eye->prop, &eye->index);
+       
+       return (eye->ptr.data && eye->prop && RNA_property_editable(&eye->ptr, eye->prop));
+}
+static void eyedropper_exit(bContext *C, wmOperator *op)
+{
+       WM_cursor_restore(CTX_wm_window(C));
+       
+       if(op->customdata)
+               MEM_freeN(op->customdata);
+       op->customdata= NULL;
+}
+
+static int eyedropper_cancel(bContext *C, wmOperator *op)
+{
+       eyedropper_exit(C, op);
+       return OPERATOR_CANCELLED;
+}
+
+static void eyedropper_sample(Eyedropper *eye, short mx, short my)
+{
+       float col[3];
+               
+       glReadBuffer(GL_FRONT);
+       glReadPixels(mx, my, 1, 1, GL_RGBA, GL_FLOAT, col);
+       glReadBuffer(GL_BACK);
+       
+       if(RNA_property_type(eye->prop) == PROP_FLOAT) {
+
+               if (RNA_property_array_length(&eye->ptr, eye->prop) < 3) return;
+
+               /* convert from screen (srgb) space to linear rgb space */
+               if (RNA_property_subtype(eye->prop) == PROP_COLOR)
+                       srgb_to_linearrgb_v3_v3(col, col);
+               
+               RNA_property_float_set_array(&eye->ptr, eye->prop, col);
+       }
+}
+
+static void eyedropper_notify(bContext *C, wmOperator *op)
+{
+       Eyedropper *eye = (Eyedropper *)op->customdata;
+       ID *id;
+       
+       id= eye->ptr.id.data;
+       
+       if (!id) return;
+       
+       switch (GS(id->name)) {
+               case ID_OB:
+                       WM_event_add_notifier(C, NC_OBJECT, NULL);
+                       break;
+               case ID_MA:
+                       WM_event_add_notifier(C, NC_MATERIAL|ND_SHADING_DRAW, NULL);
+                       break;
+               case ID_TE:
+                       WM_event_add_notifier(C, NC_TEXTURE, NULL);
+                       break;
+               case ID_LA:
+                       WM_event_add_notifier(C, NC_LAMP, NULL);
+                       break;
+               case ID_WO:
+                       WM_event_add_notifier(C, NC_WORLD, NULL);
+                       break;
+               case ID_SCE:
+                       WM_event_add_notifier(C, NC_SCENE, NULL);
+                       break;
+               case ID_BR:
+                       WM_event_add_notifier(C, NC_BRUSH, NULL);
+                       break;
+               case ID_NT:
+                       WM_event_add_notifier(C, NC_NODE, NULL);
+                       break;
+       }
+}
+
+/* main modal status check */
+static int eyedropper_modal(bContext *C, wmOperator *op, wmEvent *event)
+{
+       Eyedropper *eye = (Eyedropper *)op->customdata;
+       
+       switch(event->type) {
+               case ESCKEY:
+               case RIGHTMOUSE:
+                       return eyedropper_cancel(C, op);
+               case LEFTMOUSE:
+                       if(event->val==KM_RELEASE) {
+                               eyedropper_sample(eye, event->x, event->y);
+                               eyedropper_notify(C, op);
+                               eyedropper_exit(C, op);
+                               return OPERATOR_FINISHED;
+                       }
+                       break;
+       }
+       
+       return OPERATOR_RUNNING_MODAL;
+}
+
+/* Modal Operator init */
+static int eyedropper_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+       /* init */
+       if (eyedropper_init(C, op)) {
+               WM_cursor_modal(CTX_wm_window(C), BC_EYEDROPPER_CURSOR);
+
+               /* add temp handler */
+               WM_event_add_modal_handler(C, op);
+               
+               return OPERATOR_RUNNING_MODAL;
+       } else {
+               eyedropper_exit(C, op);
+               return OPERATOR_CANCELLED;
+       }
+}
+
+/* Repeat operator */
+static int eyedropper_exec (bContext *C, wmOperator *op)
+{
+       /* init */
+       if (eyedropper_init(C, op)) {
+               
+               /* do something */
+               
+               /* cleanup */
+               eyedropper_exit(C, op);
+               
+               return OPERATOR_FINISHED;
+       } else {
+               return OPERATOR_CANCELLED;
+       }
+}
+
+static int eyedropper_poll(bContext *C)
+{
+       if (!CTX_wm_window(C)) return 0;
+       else return 1;
+}
+
+void UI_OT_eyedropper(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Eyedropper";
+       ot->idname= "UI_OT_eyedropper";
+       ot->description= "Sample a color from the Blender Window to store in a property";
+       
+       /* api callbacks */
+       ot->invoke= eyedropper_invoke;
+       ot->modal= eyedropper_modal;
+       ot->cancel= eyedropper_cancel;
+       ot->exec= eyedropper_exec;
+       ot->poll= eyedropper_poll;
+       
+       /* flags */
+       ot->flag= OPTYPE_BLOCKING;
+       
+       /* properties */
+}
+
+
 /* Copy Data Path Operator ------------------------ */
 
 static int copy_data_path_button_exec(bContext *C, wmOperator *op)
@@ -248,6 +421,7 @@ void UI_OT_copy_to_selected_button(wmOperatorType *ot)
 
 void UI_buttons_operatortypes(void)
 {
+       WM_operatortype_append(UI_OT_eyedropper);
        WM_operatortype_append(UI_OT_copy_data_path_button);
        WM_operatortype_append(UI_OT_reset_default_button);
        WM_operatortype_append(UI_OT_copy_to_selected_button);
index b6956f840002ba1e01fe01049eea20ae006553f1..d4302aa9c52fb16c4d515e7a84c73d748a3bd74d 100644 (file)
@@ -1535,15 +1535,6 @@ static void ui_warp_pointer(short x, short y)
 #define DPICK  6.0
 #define BPICK  24.0
 
-#define UI_PALETTE_TOT 16
-/* note; in tot+1 the old color is stored */
-static float palette[UI_PALETTE_TOT+1][3]= {
-{0.93, 0.83, 0.81}, {0.88, 0.89, 0.73}, {0.69, 0.81, 0.57}, {0.51, 0.76, 0.64}, 
-{0.37, 0.56, 0.61}, {0.33, 0.29, 0.55}, {0.46, 0.21, 0.51}, {0.40, 0.12, 0.18}, 
-{1.0, 1.0, 1.0}, {0.85, 0.85, 0.85}, {0.7, 0.7, 0.7}, {0.56, 0.56, 0.56}, 
-{0.42, 0.42, 0.42}, {0.28, 0.28, 0.28}, {0.14, 0.14, 0.14}, {0.0, 0.0, 0.0}
-};  
-
 /* for picker, while editing hsv */
 void ui_set_but_hsv(uiBut *but)
 {
@@ -1553,50 +1544,37 @@ void ui_set_but_hsv(uiBut *but)
        ui_set_but_vectorf(but, col);
 }
 
-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_rgb(uiBlock *block, float *rgb)
 {
        uiBut *bt;
-       char col[16];
+       float hsv[3];
        
-       sprintf(col, "%02X%02X%02X", (unsigned int)(rgb[0]*255.0), (unsigned int)(rgb[1]*255.0), (unsigned int)(rgb[2]*255.0));
+       rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
        
        // this updates button strings, is hackish... but button pointers are on stack of caller function
-
        for(bt= block->buttons.first; bt; bt= bt->next) {
-               if(strcmp(bt->str, "Hex: ")==0)
+               if (bt->rnaprop) {
+                       
+                       ui_set_but_vectorf(bt, rgb);
+                       
+               }
+               else if(strcmp(bt->str, "Hex: ")==0) {
+                       char col[16];
+                       
+                       sprintf(col, "%02X%02X%02X", (unsigned int)(rgb[0]*255.0), (unsigned int)(rgb[1]*255.0), (unsigned int)(rgb[2]*255.0));
+                       
                        strcpy(bt->poin, col);
-
-               ui_check_but(bt);
-       }
-}
-
-/* also used by small picker, be careful with name checks below... */
-void ui_update_block_buts_hsv(uiBlock *block, float *hsv)
-{
-       uiBut *bt;
-       float r, g, b;
-       float rgb[3];
-       
-       // this updates button strings, is hackish... but button pointers are on stack of caller function
-       hsv_to_rgb(hsv[0], hsv[1], hsv[2], &r, &g, &b);
-       
-       rgb[0] = r; rgb[1] = g; rgb[2] = b;
-       update_picker_hex(block, rgb);
-
-       for(bt= block->buttons.first; bt; bt= bt->next) {
-               if(ELEM(bt->type, HSVCUBE, HSVCIRCLE)) {
-                       VECCOPY(bt->hsv, hsv);
-                       ui_set_but_hsv(bt);
                }
                else if(bt->str[1]==' ') {
                        if(bt->str[0]=='R') {
-                               ui_set_but_val(bt, r);
+                               ui_set_but_val(bt, rgb[0]);
                        }
                        else if(bt->str[0]=='G') {
-                               ui_set_but_val(bt, g);
+                               ui_set_but_val(bt, rgb[1]);
                        }
                        else if(bt->str[0]=='B') {
-                               ui_set_but_val(bt, b);
+                               ui_set_but_val(bt, rgb[2]);
                        }
                        else if(bt->str[0]=='H') {
                                ui_set_but_val(bt, hsv[0]);
@@ -1613,315 +1591,66 @@ void ui_update_block_buts_hsv(uiBlock *block, float *hsv)
        }
 }
 
-static void ui_update_block_buts_hex(uiBlock *block, char *hexcol)
-{
-       uiBut *bt;
-       float r=0, g=0, b=0;
-       float h, s, v;
-       
-       
-       // this updates button strings, is hackish... but button pointers are on stack of caller function
-       hex_to_rgb(hexcol, &r, &g, &b);
-       rgb_to_hsv(r, g, b, &h, &s, &v);
-
-       for(bt= block->buttons.first; bt; bt= bt->next) {
-               if(bt->type==HSVCUBE) {
-                       bt->hsv[0] = h;
-                       bt->hsv[1] = s;                 
-                       bt->hsv[2] = v;
-                       ui_set_but_hsv(bt);
-               }
-               else if(bt->str[1]==' ') {
-                       if(bt->str[0]=='R') {
-                               ui_set_but_val(bt, r);
-                       }
-                       else if(bt->str[0]=='G') {
-                               ui_set_but_val(bt, g);
-                       }
-                       else if(bt->str[0]=='B') {
-                               ui_set_but_val(bt, b);
-                       }
-                       else if(bt->str[0]=='H') {
-                               ui_set_but_val(bt, h);
-                       }
-                       else if(bt->str[0]=='S') {
-                               ui_set_but_val(bt, s);
-                       }
-                       else if(bt->str[0]=='V') {
-                               ui_set_but_val(bt, v);
-                       }
-               }
-
-               ui_check_but(bt);
-       }
-}
-
-/* bt1 is palette but, col1 is original color */
-/* callback to copy from/to palette */
-static void do_palette_cb(bContext *C, void *bt1, void *col1)
+static void do_picker_rna_cb(bContext *C, void *bt1, void *unused)
 {
-       wmWindow *win= CTX_wm_window(C);
-       uiBut *but1= (uiBut *)bt1;
-       uiPopupBlockHandle *popup= but1->block->handle;
-       float *col= (float *)col1;
-       float *fp, hsv[3];
-       
-       fp= (float *)but1->poin;
+       uiBut *but= (uiBut *)bt1;
+       uiPopupBlockHandle *popup= but->block->handle;
+       PropertyRNA *prop = but->rnaprop;
+       PointerRNA ptr = but->rnapoin;
+       float rgb[3];
        
-       if(win->eventstate->ctrl) {
-               VECCOPY(fp, col);
-       }
-       else {
-               VECCOPY(col, fp);
+       if (&ptr && prop) {
+               RNA_property_float_get_array(&ptr, prop, rgb);
+               ui_update_block_buts_rgb(but->block, rgb);
        }
        
-       rgb_to_hsv(col[0], col[1], col[2], hsv, hsv+1, hsv+2);
-       ui_update_block_buts_hsv(but1->block, hsv);
-       update_picker_hex(but1->block, col);
-
        if(popup)
                popup->menuretval= UI_RETURN_UPDATE;
 }
 
-static void do_hsv_cb(bContext *C, void *bt1, void *unused)
+static void do_hsv_rna_cb(bContext *C, void *bt1, void *hsv_arg)
 {
-       uiBut *but1= (uiBut *)bt1;
-       uiPopupBlockHandle *popup= but1->block->handle;
-
-       if(popup)
-               popup->menuretval= UI_RETURN_UPDATE;
-}
-
-/* bt1 is num but, hsv1 is pointer to original color in hsv space*/
-/* callback to handle changes in num-buts in picker */
-static void do_palette1_cb(bContext *C, void *bt1, void *hsv1)
-{
-       uiBut *but1= (uiBut *)bt1;
-       uiPopupBlockHandle *popup= but1->block->handle;
-       float *hsv= (float *)hsv1;
-       float *fp= NULL;
+       uiBut *but= (uiBut *)bt1;
+       uiPopupBlockHandle *popup= but->block->handle;
+       float *hsv = (float *)hsv_arg;
+       float rgb[3];
        
-       if(but1->str[1]==' ') {
-               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) {
-               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;
-}
-
-/* bt1 is num but, col1 is pointer to original color */
-/* callback to handle changes in num-buts in picker */
-static void do_palette2_cb(bContext *C, void *bt1, void *col1)
-{
-       uiBut *but1= (uiBut *)bt1;
-       uiPopupBlockHandle *popup= but1->block->handle;
-       float *rgb= (float *)col1;
-       float *fp= NULL;
+       hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb+1, rgb+2);
        
-       if(but1->str[1]==' ') {
-               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], rgb, rgb+1, rgb+2);
-       } 
-       ui_update_block_buts_hsv(but1->block, fp);
-
-       if(popup)
-               popup->menuretval= UI_RETURN_UPDATE;
-}
-
-static void do_palette_hex_cb(bContext *C, void *bt1, void *hexcl)
-{
-       uiBut *but1= (uiBut *)bt1;
-       uiPopupBlockHandle *popup= but1->block->handle;
-       char *hexcol= (char *)hexcl;
+       ui_update_block_buts_rgb(but->block, rgb);
        
-       ui_update_block_buts_hex(but1->block, hexcol);  
-
        if(popup)
                popup->menuretval= UI_RETURN_UPDATE;
 }
 
-/* used for both 3d view and image window */
-static void do_palette_sample_cb(bContext *C, void *bt1, void *col1)   /* frontbuf */
+static void do_hex_rna_cb(bContext *C, void *bt1, void *hexcl)
 {
-       /* XXX 2.50 this should become an operator? */
-#if 0
-       uiBut *but1= (uiBut *)bt1;
-       uiBut *but;
-       float tempcol[4];
-       int x=0, y=0;
-       short mval[2];
-       float hsv[3];
-       short capturing;
-       int oldcursor;
-       Window *win;
-       unsigned short dev;
-       
-       oldcursor=get_cursor();
-       win=winlay_get_active_window();
-       
-       while (get_mbut() & L_MOUSE) UI_wait_for_statechange();
-       
-       SetBlenderCursor(BC_EYEDROPPER_CURSOR);
-       
-       /* loop and wait for a mouse click */
-       capturing = TRUE;
-       while(capturing) {
-               char ascii;
-               short val;
-               
-               dev = extern_qread_ext(&val, &ascii);
-               
-               if(dev==INPUTCHANGE) break;
-               if(get_mbut() & R_MOUSE) break;
-               else if(get_mbut() & L_MOUSE) {
-                       uiGetMouse(mywinget(), mval);
-                       x= mval[0]; y= mval[1];
-                       
-                       capturing = FALSE;
-                       break;
-               }
-               else if(dev==ESCKEY) break;
-       }
-       window_set_cursor(win, oldcursor);
-       
-       if(capturing) return;
-       
-       if(x<0 || y<0) return;
-       
-       /* if we've got a glick, use OpenGL to sample the color under the mouse pointer */
-       glReadBuffer(GL_FRONT);
-       glReadPixels(x, y, 1, 1, GL_RGBA, GL_FLOAT, tempcol);
-       glReadBuffer(GL_BACK);
-       
-       /* and send that color back to the picker */
-       rgb_to_hsv(tempcol[0], tempcol[1], tempcol[2], hsv, hsv+1, hsv+2);
-       ui_update_block_buts_hsv(but1->block, hsv);
-       update_picker_hex(but1->block, tempcol);
-       
-       for (but= but1->block->buttons.first; but; but= but->next) {
-               ui_check_but(but);
-               ui_draw_but(but);
-       }
-       
-       but= but1->block->buttons.first;
-       ui_block_flush_back(but->block);
-#endif
-}
-
-/* color picker, Gimp version. mode: 'f' = floating panel, 'p' =  popup */
-/* col = read/write to, hsv/old/hexcol = memory for temporal use */
-void uiBlockPickerButtons(uiBlock *block, float *col, float *hsv, float *old, char *hexcol, char mode, short retval)
-{
-       uiBut *bt;
-       float h, offs;
-       int a;
-
-       VECCOPY(old, col);      // old color stored there, for palette_cb to work
-       
-       // the cube intersection
-       bt= uiDefButF(block, HSVCUBE, retval, "",       0,DPICK+BPICK,FPICK,FPICK, col, 0.0, 0.0, 2, 0, "");
-       uiButSetFunc(bt, do_hsv_cb, bt, NULL);
-
-       bt= uiDefButF(block, HSVCUBE, retval, "",       0,0,FPICK,BPICK, col, 0.0, 0.0, 3, 0, "");
-       uiButSetFunc(bt, do_hsv_cb, bt, NULL);
-
-       // palette
-       
-       bt=uiDefButF(block, COL, retval, "",            FPICK+DPICK, 0, BPICK,BPICK, old, 0.0, 0.0, -1, 0, "Old color, click to restore");
-       uiButSetFunc(bt, do_palette_cb, bt, col);
-       uiDefButF(block, COL, retval, "",               FPICK+DPICK, BPICK+DPICK, BPICK,60-BPICK-DPICK, col, 0.0, 0.0, -1, 0, "Active color");
-
-       h= (DPICK+BPICK+FPICK-64)/(UI_PALETTE_TOT/2.0);
-       uiBlockBeginAlign(block);
-       for(a= -1+UI_PALETTE_TOT/2; a>=0; a--) {
-               bt= uiDefButF(block, COL, retval, "",   FPICK+DPICK, 65.0+(float)a*h, BPICK/2, h, palette[a+UI_PALETTE_TOT/2], 0.0, 0.0, -1, 0, "Click to choose, hold CTRL to store in palette");
-               uiButSetFunc(bt, do_palette_cb, bt, col);
-               bt= uiDefButF(block, COL, retval, "",   FPICK+DPICK+BPICK/2, 65.0+(float)a*h, BPICK/2, h, palette[a], 0.0, 0.0, -1, 0, "Click to choose, hold CTRL to store in palette");               
-               uiButSetFunc(bt, do_palette_cb, bt, col);
-       }
-       uiBlockEndAlign(block);
+       uiBut *but= (uiBut *)bt1;
+       uiPopupBlockHandle *popup= but->block->handle;
+       char *hexcol= (char *)hexcl;
+       float rgb[3];
        
-       // buttons
-       rgb_to_hsv(col[0], col[1], col[2], hsv, hsv+1, hsv+2);
-       sprintf(hexcol, "%02X%02X%02X", (unsigned int)(col[0]*255.0), (unsigned int)(col[1]*255.0), (unsigned int)(col[2]*255.0));      
-
-       offs= FPICK+2*DPICK+BPICK;
-
-       /* note; made this a TOG now, with NULL pointer. Is because BUT now gets handled with a afterfunc */
-       bt= uiDefIconTextBut(block, TOG, UI_RETURN_OK, ICON_EYEDROPPER, "Sample", offs+55, 170, 85, 20, NULL, 0, 0, 0, 0, "Sample the color underneath the following mouse click (ESC or RMB to cancel)");
-       uiButSetFunc(bt, do_palette_sample_cb, bt, col);
-       uiButSetFlag(bt, UI_TEXT_LEFT);
+       hex_to_rgb(hexcol, rgb, rgb+1, rgb+2);
        
-       bt= uiDefBut(block, TEX, retval, "Hex: ", offs, 140, 140, 20, hexcol, 0, 8, 0, 0, "Hex triplet for color (#RRGGBB)");
-       uiButSetFunc(bt, do_palette_hex_cb, bt, hexcol);
-
-       uiBlockBeginAlign(block);
-       bt= uiDefButF(block, NUMSLI, retval, "R ",      offs, 110, 140,20, col, 0.0, 1.0, 10, 3, "");
-       uiButSetFunc(bt, do_palette1_cb, bt, hsv);
-       bt= uiDefButF(block, NUMSLI, retval, "G ",      offs, 90, 140,20, col+1, 0.0, 1.0, 10, 3, "");
-       uiButSetFunc(bt, do_palette1_cb, bt, hsv);
-       bt= uiDefButF(block, NUMSLI, retval, "B ",      offs, 70, 140,20, col+2, 0.0, 1.0, 10, 3, "");
-       uiButSetFunc(bt, do_palette1_cb, bt, hsv);
+       ui_update_block_buts_rgb(but->block, rgb);
        
-       uiBlockBeginAlign(block);
-       bt= uiDefButF(block, NUMSLI, retval, "H ",      offs, 40, 140,20, hsv, 0.0, 1.0, 10, 3, "");
-       uiButSetFunc(bt, do_palette2_cb, bt, col);
-       bt= uiDefButF(block, NUMSLI, retval, "S ",      offs, 20, 140,20, hsv+1, 0.0, 1.0, 10, 3, "");
-       uiButSetFunc(bt, do_palette2_cb, bt, col);
-       bt= uiDefButF(block, NUMSLI, retval, "V ",      offs, 0, 140,20, hsv+2, 0.0, 1.0, 10, 3, "");
-       uiButSetFunc(bt, do_palette2_cb, bt, col);
-       uiBlockEndAlign(block);
+       if(popup)
+               popup->menuretval= UI_RETURN_UPDATE;
 }
 
-/* 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)
+static void close_popup_cb(bContext *C, void *bt1, void *arg)
 {
-       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);
+       uiBut *but= (uiBut *)bt1;
+       uiPopupBlockHandle *popup= but->block->handle;
        
        if(popup)
-               popup->menuretval= UI_RETURN_UPDATE;
+               popup->menuretval= UI_RETURN_OK;
 }
 
 /* picker sizes S hsize, F full size, D spacer, B button/pallette height  */
 #define SPICK1 150.0
 #define DPICK1 6.0
 
-/* only the color, a HS circle and V slider */
-static 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,SPICK1,SPICK1, col, 0.0, 0.0, 0, 0, "");
-       uiButSetFunc(bt, do_picker_small_cb, bt, hsv);
-
-       /* value */
-       bt= uiDefButF(block, HSVCUBE, retval, "",       SPICK1+DPICK1,0,14,SPICK1, col, 0.0, 0.0, 4, 0, "");
-       uiButSetFunc(bt, do_picker_small_cb, bt, hsv);
-}
-
-
 static void picker_new_hide_reveal(uiBlock *block, short colormode)
 {
        uiBut *bt;
@@ -1950,20 +1679,22 @@ static void do_picker_new_mode_cb(bContext *C, void *bt1, void *colv)
 {
        uiBut *bt= bt1;
        short colormode= ui_get_but_val(bt);
-
        picker_new_hide_reveal(bt->block, colormode);
 }
 
-
 /* a HS circle, V slider, rgb/hsv/hex sliders */
-static void uiBlockPickerNew(uiBlock *block, float *col, float *hsv, float *old, char *hexcol, char mode, short retval)
+static void uiBlockPicker(uiBlock *block, float *rgb, PointerRNA *ptr, PropertyRNA *prop)
 {
        static short colormode= 0;      /* temp? 0=rgb, 1=hsv, 2=hex */
        uiBut *bt;
-       int width;
+       int width, butwidth;
        static char tip[50];
+       static float hsv[3];
+       static char hexcol[128];
+       const char *propname = RNA_property_identifier(prop);
        
-       VECCOPY(old, col);      // old color stored there, for palette_cb to work
+       width= (SPICK1+DPICK1+14);
+       butwidth = width - UI_UNIT_X - 10;
        
        /* existence of profile means storage is in linear colour space, with display correction */
        if (block->color_profile == BLI_PR_NONE)
@@ -1971,50 +1702,56 @@ static void uiBlockPickerNew(uiBlock *block, float *col, float *hsv, float *old,
        else
                sprintf(tip, "Value in Linear RGB Color Space");
        
+       RNA_property_float_get_array(ptr, prop, rgb);
+       rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
+       
        /* HS circle */
-       bt= uiDefButF(block, HSVCIRCLE, retval, "",     0, 0,SPICK1,SPICK1, col, 0.0, 0.0, 0, 0, "");
-       uiButSetFunc(bt, do_picker_small_cb, bt, hsv);
+       bt= uiDefButR(block, HSVCIRCLE, 0, "",  0, 0, SPICK1, SPICK1, ptr, propname, -1, 0.0, 0.0, 0, 0, "");
+       uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
        
        /* value */
-       bt= uiDefButF(block, HSVCUBE, retval, "",       SPICK1+DPICK1,0,14,SPICK1, col, 0.0, 0.0, 4, 0, "");
-       uiButSetFunc(bt, do_picker_small_cb, bt, hsv);
+       uiDefButR(block, HSVCUBE, 0, "", SPICK1+DPICK1,0,14,SPICK1, ptr, propname, -1, 0.0, 0.0, 4, 0, "");
+       uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
        
        /* mode */
-       width= (SPICK1+DPICK1+14)/3;
        uiBlockBeginAlign(block);
-       bt= uiDefButS(block, ROW, retval, "RGB",        0, -30, width, 19, &colormode, 0.0, 0.0, 0, 0, "");
-       uiButSetFunc(bt, do_picker_new_mode_cb, bt, col);
-       bt= uiDefButS(block, ROW, retval, "HSV",        width, -30, width, 19, &colormode, 0.0, 1.0, 0, 0, "");
+       bt= uiDefButS(block, ROW, 0, "RGB",     0, -30, width/3, UI_UNIT_Y, &colormode, 0.0, 0.0, 0, 0, "");
+       uiButSetFunc(bt, do_picker_new_mode_cb, bt, rgb);
+       bt= uiDefButS(block, ROW, 0, "HSV",     width/3, -30, width/3, UI_UNIT_Y, &colormode, 0.0, 1.0, 0, 0, "");
        uiButSetFunc(bt, do_picker_new_mode_cb, bt, hsv);
-       bt= uiDefButS(block, ROW, retval, "Hex",        2*width, -30, width, 19, &colormode, 0.0, 2.0, 0, 0, "");
+       bt= uiDefButS(block, ROW, 0, "Hex",     2*width/3, -30, width/3, UI_UNIT_Y, &colormode, 0.0, 2.0, 0, 0, "");
        uiButSetFunc(bt, do_picker_new_mode_cb, bt, hexcol);
        uiBlockEndAlign(block);
-       
-       /* sliders or hex */
-       width= (SPICK1+DPICK1+14);
-       rgb_to_hsv(col[0], col[1], col[2], hsv, hsv+1, hsv+2);
-       sprintf(hexcol, "%02X%02X%02X", (unsigned int)(col[0]*255.0), (unsigned int)(col[1]*255.0), (unsigned int)(col[2]*255.0));      
 
+       bt= uiDefIconButO(block, BUT, "UI_OT_eyedropper", WM_OP_INVOKE_DEFAULT, ICON_EYEDROPPER, butwidth+10, -60, UI_UNIT_X, UI_UNIT_Y, NULL);
+       uiButSetFunc(bt, close_popup_cb, bt, NULL);
+       
+       /* RGB values */
        uiBlockBeginAlign(block);
-       bt= uiDefButF(block, NUMSLI, 0, "R ",   0, -60, width, 19, col, 0.0, 1.0, 10, 3, tip);
-       uiButSetFunc(bt, do_palette1_cb, bt, hsv);
-       bt= uiDefButF(block, NUMSLI, 0, "G ",   0, -80, width, 19, col+1, 0.0, 1.0, 10, 3, tip);
-       uiButSetFunc(bt, do_palette1_cb, bt, hsv);
-       bt= uiDefButF(block, NUMSLI, 0, "B ",   0, -100, width, 19, col+2, 0.0, 1.0, 10, 3, tip);
-       uiButSetFunc(bt, do_palette1_cb, bt, hsv);
-       uiBlockEndAlign(block);
-
+       bt= uiDefButR(block, NUMSLI, 0, "R ",   0, -60, butwidth, UI_UNIT_Y, ptr, propname, 0, 0.0, 0.0, 0, 0, "");
+       uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
+       bt= uiDefButR(block, NUMSLI, 0, "G ",   0, -80, butwidth, UI_UNIT_Y, ptr, propname, 1, 0.0, 0.0, 0, 0, "");
+       uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
+       bt= uiDefButR(block, NUMSLI, 0, "B ",   0, -100, butwidth, UI_UNIT_Y, ptr, propname, 2, 0.0, 0.0, 0, 0, "");
+       uiButSetFunc(bt, do_picker_rna_cb, bt, NULL);
+       // could use uiItemFullR(col, "", 0, ptr, prop, -1, 0, UI_ITEM_R_EXPAND|UI_ITEM_R_SLIDER);
+       // but need to use uiButSetFunc for updating other fake buttons
+       
+       /* HSV values */
        uiBlockBeginAlign(block);
-       bt= uiDefButF(block, NUMSLI, 0, "H ",   0, -60, width, 19, hsv, 0.0, 1.0, 10, 3, "");
-       uiButSetFunc(bt, do_palette2_cb, bt, col);
-       bt= uiDefButF(block, NUMSLI, 0, "S ",   0, -80, width, 19, hsv+1, 0.0, 1.0, 10, 3, "");
-       uiButSetFunc(bt, do_palette2_cb, bt, col);
-       bt= uiDefButF(block, NUMSLI, 0, "V ",   0, -100, width, 19, hsv+2, 0.0, 1.0, 10, 3, "");
-       uiButSetFunc(bt, do_palette2_cb, bt, col);
+       bt= uiDefButF(block, NUMSLI, 0, "H ",   0, -60, butwidth, UI_UNIT_Y, hsv, 0.0, 1.0, 10, 3, "");
+       uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
+       bt= uiDefButF(block, NUMSLI, 0, "S ",   0, -80, butwidth, UI_UNIT_Y, hsv+1, 0.0, 1.0, 10, 3, "");
+       uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
+       bt= uiDefButF(block, NUMSLI, 0, "V ",   0, -100, butwidth, UI_UNIT_Y, hsv+2, 0.0, 1.0, 10, 3, "");
+       uiButSetFunc(bt, do_hsv_rna_cb, bt, hsv);
        uiBlockEndAlign(block);
+       
+       rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
+       sprintf(hexcol, "%02X%02X%02X", (unsigned int)(rgb[0]*255.0), (unsigned int)(rgb[1]*255.0), (unsigned int)(rgb[2]*255.0));      
 
-       bt= uiDefBut(block, TEX, 0, "Hex: ", 0, -80, width, 19, hexcol, 0, 8, 0, 0, "Hex triplet for color (#RRGGBB)");
-       uiButSetFunc(bt, do_palette_hex_cb, bt, hexcol);
+       bt= uiDefBut(block, TEX, 0, "Hex: ", 0, -60, butwidth, UI_UNIT_Y, hexcol, 0, 8, 0, 0, "Hex triplet for color (#RRGGBB)");
+       uiButSetFunc(bt, do_hex_rna_cb, bt, hexcol);
 
        picker_new_hide_reveal(block, colormode);
 }
@@ -2045,7 +1782,7 @@ static int ui_picker_small_wheel(const bContext *C, uiBlock *block, wmEvent *eve
 
                                ui_set_but_vectorf(but, col);
                                
-                               ui_update_block_buts_hsv(block, but->hsv);
+                               ui_update_block_buts_rgb(block, col);
                                if(popup)
                                        popup->menuretval= UI_RETURN_UPDATE;
                                
@@ -2058,15 +1795,11 @@ static int ui_picker_small_wheel(const bContext *C, uiBlock *block, wmEvent *eve
 
 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);
        
-       /* XXX ideally the colour picker buttons would reference the rna property itself */
        if (but->rnaprop) {
                if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
                        block->color_profile = BLI_PR_NONE;
@@ -2076,26 +1809,12 @@ uiBlock *ui_block_func_COL(bContext *C, uiPopupBlockHandle *handle, void *arg_bu
        uiBlockSetFlag(block, UI_BLOCK_MOVEMOUSE_QUIT);
        
        VECCOPY(handle->retvec, but->editvec);
-       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 if(win->eventstate->alt) {
-               uiBlockPickerSmall(block, handle->retvec, hsvcol, oldcol, hexcol, 'p', 0);
-               block->flag= UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1|UI_BLOCK_OUT_1;
-               uiBoundsBlock(block, 10);
-               
-               block->block_event_func= ui_picker_small_wheel;
-       }
-       else {
-               uiBlockPickerNew(block, handle->retvec, hsvcol, oldcol, hexcol, 'p', 0);
-               block->flag= UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_KEEP_OPEN;
-               uiBoundsBlock(block, 10);
-               
-               block->block_event_func= ui_picker_small_wheel;
-       }
+
+       uiBlockPicker(block, handle->retvec, &but->rnapoin, but->rnaprop);
+       block->flag= UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_KEEP_OPEN;
+       uiBoundsBlock(block, 10);
        
+       block->block_event_func= ui_picker_small_wheel;
        
        /* and lets go */
        block->direction= UI_TOP;
@@ -2103,90 +1822,6 @@ uiBlock *ui_block_func_COL(bContext *C, uiPopupBlockHandle *handle, void *arg_bu
        return block;
 }
 
-/* ******************** Color band *************** */
-
-static int vergcband(const void *a1, const void *a2)
-{
-       const CBData *x1=a1, *x2=a2;
-       
-       if( x1->pos > x2->pos ) return 1;
-       else if( x1->pos < x2->pos) return -1;
-       return 0;
-}
-
-static void colorband_pos_cb(bContext *C, void *coba_v, void *unused_v)
-{
-       ColorBand *coba= coba_v;
-       int a;
-       
-       if(coba->tot<2) return;
-       
-       for(a=0; a<coba->tot; a++) coba->data[a].cur= a;
-       qsort(coba->data, coba->tot, sizeof(CBData), vergcband);
-       for(a=0; a<coba->tot; a++) {
-               if(coba->data[a].cur==coba->cur) {
-                       /* if(coba->cur!=a) addqueue(curarea->win, REDRAW, 0); */       /* button cur */
-                       coba->cur= a;
-                       break;
-               }
-       }
-}
-
-static void colorband_add_cb(bContext *C, void *coba_v, void *unused_v)
-{
-       ColorBand *coba= coba_v;
-       
-       if(coba->tot < MAXCOLORBAND-1) coba->tot++;
-       coba->cur= coba->tot-1;
-       
-       colorband_pos_cb(C, coba, NULL);
-//     BIF_undo_push("Add colorband");
-       
-}
-
-static void colorband_del_cb(bContext *C, void *coba_v, void *unused_v)
-{
-       ColorBand *coba= coba_v;
-       int a;
-       
-       if(coba->tot<2) return;
-       
-       for(a=coba->cur; a<coba->tot; a++) {
-               coba->data[a]= coba->data[a+1];
-       }
-       if(coba->cur) coba->cur--;
-       coba->tot--;
-       
-//     BIF_undo_push("Delete colorband");
-//     BIF_preview_changed(ID_TE);
-}
-
-void uiBlockColorbandButtons(uiBlock *block, ColorBand *coba, rctf *butr, int event)
-{
-       CBData *cbd;
-       uiBut *bt;
-       float unit= (butr->xmax-butr->xmin)/14.0f;
-       float xs= butr->xmin;
-       
-       cbd= coba->data + coba->cur;
-       
-       uiBlockBeginAlign(block);
-       uiDefButF(block, COL, event,            "",                     xs,butr->ymin+20.0f,2.0f*unit,20,                               &(cbd->r), 0, 0, 0, 0, "");
-       uiDefButF(block, NUM, event,            "A:",           xs+2.0f*unit,butr->ymin+20.0f,4.0f*unit,20,     &(cbd->a), 0.0f, 1.0f, 10, 2, "");
-       bt= uiDefBut(block, BUT, event, "Add",          xs+6.0f*unit,butr->ymin+20.0f,2.0f*unit,20,     NULL, 0, 0, 0, 0, "Adds a new color position to the colorband");
-       uiButSetFunc(bt, colorband_add_cb, coba, NULL);
-       bt= uiDefBut(block, BUT, event, "Del",          xs+8.0f*unit, butr->ymin+20.0f, 2.0f*unit, 20,  NULL, 0, 0, 0, 0, "Deletes the active position");
-       uiButSetFunc(bt, colorband_del_cb, coba, NULL);
-       
-       uiDefButS(block, MENU, event,           "Interpolation %t|Ease %x1|Cardinal %x3|Linear %x0|B-Spline %x2|Constant %x4",
-                         xs + 10.0f*unit, butr->ymin+20.0f, unit*4.0f, 20,             &coba->ipotype, 0.0, 0.0, 0, 0, "Sets interpolation type");
-       
-       uiDefBut(block, BUT_COLORBAND, event, "",               xs, butr->ymin, butr->xmax-butr->xmin, 20.0f, coba, 0, 0, 0, 0, "");
-       uiBlockEndAlign(block);
-       
-}
-
-
 /************************ Popup Menu Memory ****************************/
 
 static int ui_popup_menu_hash(char *str)
index 6b36e60fa6cd6c86cd8fa06ce8372c99b20fb9d8..b22fb279f37c346fae7c06358732bf45c3a04e8a 100644 (file)
@@ -1449,7 +1449,7 @@ static void colorband_buttons_large(uiLayout *layout, uiBlock *block, ColorBand
 
        if(coba->tot) {
                CBData *cbd= coba->data + coba->cur;
-#if 1
+
                /* better to use rna so we can animate them */
                PointerRNA ptr;
                RNA_pointer_create(cb->ptr.id.data, &RNA_ColorRampElement, cbd, &ptr);
@@ -1457,15 +1457,6 @@ static void colorband_buttons_large(uiLayout *layout, uiBlock *block, ColorBand
                //uiItemR(layout, NULL, 0, &ptr, "position", 0);
                bt= uiDefButF(block, NUM, 0, "Pos:",                    0+xoffs,40+yoffs,100, 20, &cbd->pos, 0.0, 1.0, 10, 0, "The position of the active color stop");
                uiButSetNFunc(bt, colorband_pos_cb, MEM_dupallocN(cb), coba);
-
-#else
-               bt= uiDefButF(block, NUM, 0, "Pos:",                    0+xoffs,40+yoffs,100, 20, &cbd->pos, 0.0, 1.0, 10, 0, "The position of the active color stop");
-               uiButSetNFunc(bt, colorband_pos_cb, MEM_dupallocN(cb), coba);
-               bt= uiDefButF(block, COL, 0,            "",                             110+xoffs,40+yoffs,80,20, &(cbd->r), 0, 0, 0, B_BANDCOL, "The color value for the active color stop");
-               uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
-               bt= uiDefButF(block, NUMSLI, 0, "A ",                   200+xoffs,40+yoffs,100,20, &cbd->a, 0.0, 1.0, 10, 0, "The alpha value of the active color stop");
-               uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
-#endif
        }
 
 }
@@ -1484,16 +1475,9 @@ static void colorband_buttons_small(uiLayout *layout, uiBlock *block, ColorBand
 
        if(coba->tot) {
                CBData *cbd= coba->data + coba->cur;
-#if 1
                PointerRNA ptr;
                RNA_pointer_create(cb->ptr.id.data, &RNA_ColorRampElement, cbd, &ptr);
                uiItemR(layout, "", 0, &ptr, "color", 0);
-#else
-               bt= uiDefButF(block, COL, 0,            "",                     xs+4.0f*unit,butr->ymin+20.0f,2.0f*unit,20,                             &(cbd->r), 0, 0, 0, B_BANDCOL, "The color value for the active color stop");
-               uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
-               bt= uiDefButF(block, NUMSLI, 0,         "A:",           xs+6.0f*unit,butr->ymin+20.0f,4.0f*unit,20,     &(cbd->a), 0.0f, 1.0f, 10, 2, "The alpha value of the active color stop");
-               uiButSetNFunc(bt, rna_update_cb, MEM_dupallocN(cb), NULL);
-#endif
        }
 
        bt= uiDefButS(block, MENU, 0,           "Interpolation %t|Ease %x1|Cardinal %x3|Linear %x0|B-Spline %x2|Constant %x4",
@@ -1876,6 +1860,33 @@ void uiTemplateCurveMapping(uiLayout *layout, PointerRNA *ptr, char *propname, i
        MEM_freeN(cb);
 }
 
+/********************* ColorWheel Template ************************/
+
+#define WHEEL_SIZE     100
+
+void uiTemplateColorWheel(uiLayout *layout, PointerRNA *ptr, char *propname, int value_slider)
+{
+       PropertyRNA *prop= RNA_struct_find_property(ptr, propname);
+       uiBlock *block= uiLayoutGetBlock(layout);
+       uiLayout *row;
+       
+       if (!prop) {
+               printf("uiTemplateColorWheel: property not found: %s\n", propname);
+               return;
+       }
+       
+       row= uiLayoutRow(layout, 1);
+       
+       uiDefButR(block, HSVCIRCLE, 0, "",      0, 0, WHEEL_SIZE, WHEEL_SIZE, ptr, propname, -1, 0.0, 0.0, 0, 0, "");
+       
+       uiItemS(row);
+       
+       if (value_slider)
+               uiDefButR(block, HSVCUBE, 0, "", WHEEL_SIZE+6, 0, 14, WHEEL_SIZE, ptr, propname, -1, 0.0, 0.0, 4, 0, "");
+
+}
+
+
 /********************* TriColor (ThemeWireColorSet) Template ************************/
 
 void uiTemplateTriColorSet(uiLayout *layout, PointerRNA *ptr, char *propname)
index 9e23530be4f43ee679c0406e8c5dad0e40cbb00f..7b251b2d22e13b3e338e1a435739060485dc8d59 100644 (file)
@@ -1538,12 +1538,12 @@ void ui_hsvcircle_vals_from_pos(float *valrad, float *valdist, rcti *rect, float
        *valrad= atan2(mx, my)/(2.0f*M_PI) + 0.5f;
 }
 
-void ui_draw_but_HSVCIRCLE(uiBut *but, rcti *rect)
+void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, rcti *rect)
 {
        /* gouraud triangle fan */
        float radstep, ang= 0.0f;
        float centx, centy, radius;
-       float hsv[3], col[3], colcent[3];
+       float rgb[3], hsv[3], hsvo[3], col[3], colcent[3];
        int a, tot= 32;
        
        radstep= 2.0f*M_PI/(float)tot;
@@ -1556,9 +1556,11 @@ void ui_draw_but_HSVCIRCLE(uiBut *but, rcti *rect)
                radius= (float)(rect->xmax - rect->xmin)/2; 
        
        /* color */
-       VECCOPY(hsv, but->hsv);
-       hsv[0]= hsv[1]= 0.0f;
-       hsv_to_rgb(hsv[0], hsv[1], hsv[2], colcent, colcent+1, colcent+2);
+       ui_get_but_vectorf(but, rgb);
+       rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
+       copy_v3_v3(hsvo, hsv);
+       
+       hsv_to_rgb(0.f, 0.f, hsv[2], colcent, colcent+1, colcent+2);
        
        glShadeModel(GL_SMOOTH);
 
@@ -1584,15 +1586,15 @@ void ui_draw_but_HSVCIRCLE(uiBut *but, rcti *rect)
        glTranslatef(centx, centy, 0.0f);
        glEnable(GL_BLEND);
        glEnable(GL_LINE_SMOOTH );
-       glColor3f(0.0f, 0.0f, 0.0f);
+       glColor3ubv((unsigned char*)wcol->outline);
        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;
+       ang= 2.0f*M_PI*hsvo[0] + 0.5f*M_PI;
+       radius= hsvo[1]*radius;
        ui_hsv_cursor(centx + cos(-ang)*radius, centy + sin(-ang)*radius);
        
 }
@@ -1603,14 +1605,13 @@ void ui_draw_but_HSVCIRCLE(uiBut *but, rcti *rect)
 static void ui_draw_but_HSVCUBE(uiBut *but, rcti *rect)
 {
        int a;
-       float h,s,v;
+       float rgb[3], h,s,v;
        float dx, dy, sx1, sx2, sy, x=0.0f, y=0.0f;
        float col0[4][3];       // left half, rect bottom to top
        float col1[4][3];       // right half, rect bottom to top
        
-       h= but->hsv[0];
-       s= but->hsv[1];
-       v= but->hsv[2];
+       ui_get_but_vectorf(but, rgb);
+       rgb_to_hsv(rgb[0], rgb[1], rgb[2], &h, &s, &v);
        
        /* draw series of gouraud rects */
        glShadeModel(GL_SMOOTH);
@@ -1721,7 +1722,7 @@ static void ui_draw_but_HSV_v(uiBut *but, rcti *rect)
        uiWidgetBase wtb;
        float rad= 0.5f*(rect->xmax - rect->xmin);
        float x, y;
-       float v = but->hsv[2];
+       float rgb[3], hsv[3], v;
        int color_profile = but->block->color_profile;
        
        if (but->rnaprop) {
@@ -1730,6 +1731,10 @@ static void ui_draw_but_HSV_v(uiBut *but, rcti *rect)
                }
        }
 
+       ui_get_but_vectorf(but, rgb);
+       rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv+1, hsv+2);
+       v = hsv[2];
+       
        if (color_profile)
                v = linearrgb_to_srgb(v);
        
@@ -2591,7 +2596,7 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
                                break;
                                
                        case HSVCIRCLE:
-                               ui_draw_but_HSVCIRCLE(but, rect);
+                               ui_draw_but_HSVCIRCLE(but, &tui->wcol_regular, rect);
                                break;
                                
                        case BUT_COLORBAND:
index de20da0c0ca71bc8b5b3091d79e6e487c2a2a99b..011235c862f717b8fcc5795b3fdbed11513539d4 100644 (file)
@@ -335,6 +335,10 @@ void RNA_api_ui_layout(StructRNA *srna)
        parm= RNA_def_int(func, "active_layer", 0, 0, INT_MAX, "Active Layer", "", 0, INT_MAX);
        RNA_def_property_flag(parm, PROP_REQUIRED);
        
+       func= RNA_def_function(srna, "template_color_wheel", "uiTemplateColorWheel");
+       api_ui_item_rna_common(func);
+       RNA_def_boolean(func, "value_slider", 0, "", "Display the value slider to the right of the color wheel");
+       
        func= RNA_def_function(srna, "template_triColorSet", "uiTemplateTriColorSet");
        api_ui_item_rna_common(func);