2.5: ID datablock button back, previously known as std_libbuttons. The
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Fri, 6 Feb 2009 16:40:14 +0000 (16:40 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Fri, 6 Feb 2009 16:40:14 +0000 (16:40 +0000)
way this worked in 2.4x wasn't really clean, with events going all over
the place and using dubious variables such as G.but->lockpoin or
G.sima->menunr. It works as follows now, for example:

xco= uiDefIDPoinButs(block, CTX_data_main(C), NULL, (ID**)&sima->image, ID_IM, &sima->pin, xco, yco,
sima_idpoin_handle, UI_ID_BROWSE|UI_ID_RENAME|UI_ID_ADD_NEW|UI_ID_OPEN|UI_ID_DELETE|UI_ID_ALONE|UI_ID_PIN);

The last two parameters are a callback function, and a list of events
or functionalities that are supported. The callback function will then
get the ID pointer + event to handle.

source/blender/editors/include/UI_interface.h
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_handlers.c
source/blender/editors/interface/interface_intern.h
source/blender/editors/interface/interface_utils.c
source/blender/editors/space_image/image_header.c
source/blender/editors/space_image/space_image.c
source/blender/editors/transform/transform_orientations.c

index a81d956f01e16cd61a5a2b6c3763fd1ce1ffda27..9f832a3db309df02c443813974d7598cd7b7bd21 100644 (file)
@@ -33,6 +33,7 @@
 /* Struct Declarations */
 
 struct ID;
+struct Main;
 struct ListBase;
 struct ARegion;
 struct wmWindow;
@@ -395,10 +396,25 @@ struct PointerRNA *uiButGetOperatorPtrRNA(uiBut *but);
  * - PickerButtons: buttons like the color picker (for code sharing).
  * - AutoButR: RNA property button with type automatically defined. */
 
-typedef void     (*uiIDPoinFuncFP)(struct bContext *C, char *str, struct ID **idpp);
-
-uiBut *uiDefIDPoinBut(struct uiBlock *block, uiIDPoinFuncFP func, short blocktype, int retval, char *str,
+#define UI_ID_RENAME           1
+#define UI_ID_BROWSE           2
+#define UI_ID_ADD_NEW          4
+#define UI_ID_OPEN                     8
+#define UI_ID_ALONE                    16
+#define UI_ID_DELETE           32
+#define UI_ID_LOCAL                    64
+#define UI_ID_AUTO_NAME                128
+#define UI_ID_FAKE_USER                256
+#define UI_ID_PIN                      512
+#define UI_ID_BROWSE_RENDER    1024
+#define UI_ID_FULL                     (UI_ID_RENAME|UI_ID_BROWSE|UI_ID_ADD_NEW|UI_ID_OPEN|UI_ID_ALONE|UI_ID_DELETE|UI_ID_LOCAL)
+
+typedef void (*uiIDPoinFuncFP)(struct bContext *C, char *str, struct ID **idpp);
+typedef void (*uiIDPoinFunc)(struct bContext *C, struct ID *id, int event);
+
+uiBut *uiDefIDPoinBut(uiBlock *block, uiIDPoinFuncFP func, short blocktype, int retval, char *str,
                                                short x1, short y1, short x2, short y2, void *idpp, char *tip);
+int uiDefIDPoinButs(uiBlock *block, struct Main *main, struct ID *parid, struct ID **id_p, int id_code, short *pin_p, int x, int y, uiIDPoinFunc func, int events);
 
 uiBut *uiDefPulldownBut(uiBlock *block, uiBlockCreateFunc func, void *arg, char *str, short x1, short y1, short x2, short y2, char *tip);
 uiBut *uiDefMenuBut(uiBlock *block, uiMenuCreateFunc func, void *arg, char *str, short x1, short y1, short x2, short y2, char *tip);
@@ -434,9 +450,12 @@ uiBut *uiFindInlink(uiBlock *block, void *poin);
  * uiButSetCompleteFunc is for tab completion.
  *
  * uiBlockSetFunc and uiButSetFunc are callbacks run when a button is used,
- * in case events, operators or RNA are not sufficient to handle the button. */
+ * in case events, operators or RNA are not sufficient to handle the button.
+ *
+ * uiButSetNFunc will free the argument with MEM_freeN. */
 
 typedef void (*uiButHandleFunc)(struct bContext *C, void *arg1, void *arg2);
+typedef void (*uiButHandleNFunc)(struct bContext *C, void *argN, void *arg2);
 typedef void (*uiButCompleteFunc)(struct bContext *C, char *str, void *arg);
 typedef void (*uiBlockHandleFunc)(struct bContext *C, void *arg, int event);
 
@@ -445,6 +464,7 @@ void        uiBlockSetButmFunc      (uiBlock *block,        uiMenuHandleFunc func, void *arg);
 
 void   uiBlockSetFunc          (uiBlock *block,        uiButHandleFunc func, void *arg1, void *arg2);
 void   uiButSetFunc            (uiBut *but,            uiButHandleFunc func, void *arg1, void *arg2);
+void   uiButSetNFunc           (uiBut *but,            uiButHandleNFunc func, void *argN, void *arg2);
 
 void   uiButSetCompleteFunc(uiBut *but,                uiButCompleteFunc func, void *arg);
 
index 032aa952c5e8b9038d5eeca850d0920dd5bd1aad..a2f272767cbbdb39de45eef6603e7de280286188 100644 (file)
@@ -503,13 +503,14 @@ static int ui_but_equals_old(uiBut *but, uiBut *oldbut)
        /* various properties are being compared here, hopfully sufficient
         * to catch all cases, but it is simple to add more checks later */
        if(but->retval != oldbut->retval) return 0;
-       if(but->poin != oldbut->poin || but->pointype != oldbut->pointype) return 0;
        if(but->rnapoin.data != oldbut->rnapoin.data) return 0;
        if(but->rnaprop != oldbut->rnaprop)
        if(but->rnaindex != oldbut->rnaindex) return 0;
        if(but->func != oldbut->func) return 0;
+       if(but->funcN != oldbut->funcN) return 0;
        if(oldbut->func_arg1 != oldbut && but->func_arg1 != oldbut->func_arg1) return 0;
        if(oldbut->func_arg2 != oldbut && but->func_arg2 != oldbut->func_arg2) return 0;
+       if(!but->funcN && (but->poin != oldbut->poin || but->pointype != oldbut->pointype)) return 0;
 
        return 1;
 }
@@ -902,8 +903,10 @@ static int ui_do_but_LINK(uiBlock *block, uiBut *but)
 
 void uiBlockSetButLock(uiBlock *block, int val, char *lockstr)
 {
-       block->lock |= val;
-       if(val) block->lockstr= lockstr;
+       if(val) {
+               block->lock |= val;
+               block->lockstr= lockstr;
+       }
 }
 
 void uiBlockClearButLock(uiBlock *block)
@@ -1496,6 +1499,7 @@ static void ui_free_but(const bContext *C, uiBut *but)
                WM_operator_properties_free(but->opptr);
                MEM_freeN(but->opptr);
        }
+       if(but->func_argN) MEM_freeN(but->func_argN);
        if(but->active) ui_button_active_cancel(C, but);
        if(but->str && but->str != but->strdata) MEM_freeN(but->str);
        ui_free_link(but->link);
@@ -2852,19 +2856,19 @@ PointerRNA *uiButGetOperatorPtrRNA(uiBut *but)
        return but->opptr;
 }
 
-void uiBlockSetHandleFunc(uiBlock *block, void (*func)(struct bContext *C, void *arg, int event), void *arg)
+void uiBlockSetHandleFunc(uiBlock *block, uiBlockHandleFunc func, void *arg)
 {
        block->handle_func= func;
        block->handle_func_arg= arg;
 }
 
-void uiBlockSetButmFunc(uiBlock *block, void (*func)(struct bContext *C, void *arg, int but_a2), void *arg)
+void uiBlockSetButmFunc(uiBlock *block, uiMenuHandleFunc func, void *arg)
 {
        block->butm_func= func;
        block->butm_func_arg= arg;
 }
 
-void uiBlockSetFunc(uiBlock *block, void (*func)(struct bContext *C, void *arg1, void *arg2), void *arg1, void *arg2)
+void uiBlockSetFunc(uiBlock *block, uiButHandleFunc func, void *arg1, void *arg2)
 {
        block->func= func;
        block->func_arg1= arg1;
@@ -2876,14 +2880,21 @@ void uiBlockSetDrawExtraFunc(uiBlock *block, void (*func)())
        block->drawextra= func;
 }
 
-void uiButSetFunc(uiBut *but, void (*func)(struct bContext *C, void *arg1, void *arg2), void *arg1, void *arg2)
+void uiButSetFunc(uiBut *but, uiButHandleFunc func, void *arg1, void *arg2)
 {
        but->func= func;
        but->func_arg1= arg1;
        but->func_arg2= arg2;
 }
 
-void uiButSetCompleteFunc(uiBut *but, void (*func)(struct bContext *C, char *str, void *arg), void *arg)
+void uiButSetNFunc(uiBut *but, uiButHandleNFunc funcN, void *argN, void *arg2)
+{
+       but->funcN= funcN;
+       but->func_argN= argN;
+       but->func_arg2= arg2;
+}
+
+void uiButSetCompleteFunc(uiBut *but, uiButCompleteFunc func, void *arg)
 {
        but->autocomplete_func= func;
        but->autofunc_arg= arg;
index ac5e64c80a53de6fae93241239d0b2ebab3bde51..c7a2e46cecb2483a865dc5a0cedb61a546950087 100644 (file)
@@ -134,15 +134,18 @@ typedef struct uiHandleButtonData {
 typedef struct uiAfterFunc {
        struct uiAfterFunc *next, *prev;
 
-       void (*func)(struct bContext*, void *, void *);
+       uiButHandleFunc func;
        void *func_arg1;
        void *func_arg2;
 
-       void (*handle_func)(struct bContext*, void *arg, int event);
+       uiButHandleNFunc funcN;
+       void *func_argN;
+
+       uiBlockHandleFunc handle_func;
        void *handle_func_arg;
        int retval;
 
-       void (*butm_func)(struct bContext*, void *arg, int event);
+       uiMenuHandleFunc butm_func;
        void *butm_func_arg;
        int a2;
 
@@ -217,13 +220,16 @@ static void ui_apply_but_func(bContext *C, uiBut *but)
         * handling is done, i.e. menus are closed, in order to avoid conflicts
         * with these functions removing the buttons we are working with */
 
-       if(but->func || block->handle_func || (but->type == BUTM && block->butm_func) || but->opname || but->rnaprop) {
+       if(but->func || but->funcN || block->handle_func || (but->type == BUTM && block->butm_func) || but->opname || but->rnaprop) {
                after= MEM_callocN(sizeof(uiAfterFunc), "uiAfterFunc");
 
                after->func= but->func;
                after->func_arg1= but->func_arg1;
                after->func_arg2= but->func_arg2;
 
+               after->funcN= but->funcN;
+               after->func_argN= but->func_argN;
+
                after->handle_func= block->handle_func;
                after->handle_func_arg= block->handle_func_arg;
                after->retval= but->retval;
@@ -264,6 +270,8 @@ static void ui_apply_but_funcs_after(bContext *C)
 
                if(after.func)
                        after.func(C, after.func_arg1, after.func_arg2);
+               if(after.funcN)
+                       after.funcN(C, after.func_argN, after.func_arg2);
                
                if(after.handle_func)
                        after.handle_func(C, after.handle_func_arg, after.retval);
@@ -2611,6 +2619,9 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
        data= but->active;
        retval= WM_UI_HANDLER_CONTINUE;
 
+       if(but->flag & UI_BUT_DISABLED)
+               return WM_UI_HANDLER_BREAK;
+
        /* handle copy-paste */
        if(data->state == BUTTON_STATE_HIGHLIGHT) {
                if(ELEM(event->type, CKEY, VKEY) && event->val==KM_PRESS && (event->ctrl || event->oskey)) {
index ce6410765542a15f6a4ed0fa9dd768f446abcd20..07c8ad04c6fae1c201a612fb9253c3311f7e3db9 100644 (file)
@@ -125,6 +125,9 @@ struct uiBut {
        void *func_arg1;
        void *func_arg2;
 
+       uiButHandleNFunc funcN;
+       void *func_argN;
+
        void (*embossfunc)(int , int , float, float, float, float, float, int);
        void (*sliderfunc)(int , float, float, float, float, float, float, int);
 
index 3ccd88f0cc23570ffe95ee60e567c54b79f20f66..898115cdbbd9293cbdeb50854c1ecbf3e98d9af9 100644 (file)
 #include "MEM_guardedalloc.h"
 
 #include "DNA_listBase.h"
+#include "DNA_material_types.h"
 #include "DNA_screen_types.h"
 #include "DNA_windowmanager_types.h"
 
 #include "BKE_context.h"
 #include "BKE_idprop.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
 #include "BKE_utildefines.h"
 
 #include "RNA_access.h"
 #include "WM_api.h"
 #include "WM_types.h"
 
+#define DEF_BUT_WIDTH          150
+#define DEF_ICON_BUT_WIDTH     20
+#define DEF_BUT_HEIGHT         20
+
 /*************************** RNA Utilities ******************************/
 
 int UI_GetIconRNA(PointerRNA *ptr)
@@ -287,9 +294,6 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
        return but;
 }
 
-#define RNA_BUT_WIDTH 150
-#define RNA_BUT_HEIGHT 20
-
 int uiDefAutoButsRNA(uiBlock *block, PointerRNA *ptr)
 {
        CollectionPropertyIterator iter;
@@ -303,8 +307,8 @@ int uiDefAutoButsRNA(uiBlock *block, PointerRNA *ptr)
 
        /* create buttons */
        uiSetCurFont(block, UI_HELVB);
-       uiDefBut(block, LABEL, 0, (char*)RNA_struct_ui_name(ptr), x, y, RNA_BUT_WIDTH, RNA_BUT_HEIGHT-1, NULL, 0, 0, 0, 0, "");
-       y -= RNA_BUT_HEIGHT;
+       uiDefBut(block, LABEL, 0, (char*)RNA_struct_ui_name(ptr), x, y, DEF_BUT_WIDTH, DEF_BUT_HEIGHT-1, NULL, 0, 0, 0, 0, "");
+       y -= DEF_BUT_HEIGHT;
        uiSetCurFont(block, UI_HELV);
 
        iterprop= RNA_struct_iterator_property(ptr);
@@ -318,7 +322,7 @@ int uiDefAutoButsRNA(uiBlock *block, PointerRNA *ptr)
 
                if((length= RNA_property_array_length(ptr, prop))) {
                        name= (char*)RNA_property_ui_name(ptr, prop);
-                       uiDefBut(block, LABEL, 0, name, x, y, RNA_BUT_WIDTH, RNA_BUT_HEIGHT-1, NULL, 0, 0, 0, 0, "");
+                       uiDefBut(block, LABEL, 0, name, x, y, DEF_BUT_WIDTH, DEF_BUT_HEIGHT-1, NULL, 0, 0, 0, 0, "");
                }
                else
                        length= 1;
@@ -326,7 +330,7 @@ int uiDefAutoButsRNA(uiBlock *block, PointerRNA *ptr)
                subtype= RNA_property_subtype(ptr, prop);
 
                name= (char*)RNA_property_ui_name(ptr, prop);
-               uiDefBut(block, LABEL, 0, name, x, y, RNA_BUT_WIDTH, RNA_BUT_HEIGHT-1, NULL, 0, 0, 0, 0, "");
+               uiDefBut(block, LABEL, 0, name, x, y, DEF_BUT_WIDTH, DEF_BUT_HEIGHT-1, NULL, 0, 0, 0, 0, "");
 
                uiBlockBeginAlign(block);
 
@@ -335,17 +339,17 @@ int uiDefAutoButsRNA(uiBlock *block, PointerRNA *ptr)
                        int size, row, col, butwidth;
 
                        size= ceil(sqrt(length));
-                       butwidth= RNA_BUT_WIDTH*2/size;
-                       y -= RNA_BUT_HEIGHT;
+                       butwidth= DEF_BUT_WIDTH*2/size;
+                       y -= DEF_BUT_HEIGHT;
 
                        for(a=0; a<length; a++) {
                                col= a%size;
                                row= a/size;
 
-                               uiDefAutoButR(block, ptr, prop, a, "", x+butwidth*col, y-row*RNA_BUT_HEIGHT, butwidth, RNA_BUT_HEIGHT-1);
+                               uiDefAutoButR(block, ptr, prop, a, "", x+butwidth*col, y-row*DEF_BUT_HEIGHT, butwidth, DEF_BUT_HEIGHT-1);
                        }
 
-                       y -= RNA_BUT_HEIGHT*(length/size);
+                       y -= DEF_BUT_HEIGHT*(length/size);
                }
                else if(length <= 4 && ELEM3(subtype, PROP_ROTATION, PROP_VECTOR, PROP_COLOR)) {
                        static char *vectoritem[4]= {"X:", "Y:", "Z:", "W:"};
@@ -353,8 +357,8 @@ int uiDefAutoButsRNA(uiBlock *block, PointerRNA *ptr)
                        static char *coloritem[4]= {"R:", "G:", "B:", "A:"};
                        int butwidth;
 
-                       butwidth= RNA_BUT_WIDTH*2/length;
-                       y -= RNA_BUT_HEIGHT;
+                       butwidth= DEF_BUT_WIDTH*2/length;
+                       y -= DEF_BUT_HEIGHT;
 
                        for(a=0; a<length; a++) {
                                if(length == 4 && subtype == PROP_ROTATION)
@@ -364,9 +368,9 @@ int uiDefAutoButsRNA(uiBlock *block, PointerRNA *ptr)
                                else
                                        name= coloritem[a];
 
-                               uiDefAutoButR(block, ptr, prop, a, name, x+butwidth*a, y, butwidth, RNA_BUT_HEIGHT-1);
+                               uiDefAutoButR(block, ptr, prop, a, name, x+butwidth*a, y, butwidth, DEF_BUT_HEIGHT-1);
                        }
-                       y -= RNA_BUT_HEIGHT;
+                       y -= DEF_BUT_HEIGHT;
                }
                else {
                        if(RNA_property_array_length(ptr, prop)) {
@@ -376,8 +380,8 @@ int uiDefAutoButsRNA(uiBlock *block, PointerRNA *ptr)
                        else
                                name= "";
 
-                       uiDefAutoButR(block, ptr, prop, a, name, x+RNA_BUT_WIDTH, y, RNA_BUT_WIDTH, RNA_BUT_HEIGHT-1);
-                       y -= RNA_BUT_HEIGHT;
+                       uiDefAutoButR(block, ptr, prop, a, name, x+DEF_BUT_WIDTH, y, DEF_BUT_WIDTH, DEF_BUT_HEIGHT-1);
+                       y -= DEF_BUT_HEIGHT;
                }
 
                uiBlockEndAlign(block);
@@ -388,6 +392,281 @@ int uiDefAutoButsRNA(uiBlock *block, PointerRNA *ptr)
        return -y;
 }
 
-#if 0
-#endif
+/***************************** ID Utilities *******************************/
+
+typedef struct uiIDPoinParams {
+       uiIDPoinFunc func;
+       ID **id_p;
+       short id_code;
+       short browsenr;
+} uiIDPoinParams;
+
+static void idpoin_cb(bContext *C, void *arg_params, void *arg_event)
+{
+       Main *bmain;
+       ListBase *lb;
+       uiIDPoinParams *params= (uiIDPoinParams*)arg_params;
+       uiIDPoinFunc func= params->func;
+       ID **id_p= params->id_p;
+       ID *id= *id_p, *idtest;
+       int nr, event= GET_INT_FROM_POINTER(arg_event);
+
+       bmain= CTX_data_main(C);
+       lb= wich_libbase(bmain, params->id_code);
+
+       switch(event) {
+               case UI_ID_RENAME:
+                       if(id) test_idbutton(id->name+2);
+                       else return;
+                       break;
+               case UI_ID_BROWSE: {
+                       if(id==0) id= lb->first;
+                       if(id==0) return;
+
+                       if(params->browsenr== -2) {
+                               /* XXX implement or find a replacement
+                                * activate_databrowse((ID *)G.buts->lockpoin, GS(id->name), 0, B_MESHBROWSE, &params->browsenr, do_global_buttons); */
+                               return;
+                       }
+                       if(params->browsenr < 0)
+                               return;
+
+                       for(idtest=lb->first, nr=1; idtest; idtest=idtest->next, nr++) {
+                               if(nr==params->browsenr) {
+                                       if(id == idtest)
+                                               return;
+
+                                       *id_p= idtest;
+                                       break;
+                               }
+                       }
+                       break;
+               }
+               case UI_ID_DELETE:
+                       *id_p= NULL;
+                       break;
+               case UI_ID_FAKE_USER:
+                       if(id) {
+                               if(id->flag & LIB_FAKEUSER) id->us++;
+                               else id->us--;
+                       }
+                       else return;
+                       break;
+               case UI_ID_PIN:
+                       break;
+               case UI_ID_ADD_NEW:
+                       break;
+               case UI_ID_OPEN:
+                       break;
+               case UI_ID_ALONE:
+                       if(!id || id->us < 1)
+                               return;
+                       break;
+               case UI_ID_LOCAL:
+                       if(!id || id->us < 1)
+                               return;
+                       break;
+               case UI_ID_AUTO_NAME:
+                       break;
+       }
+
+       if(func)
+               func(C, *id_p, event);
+}
+
+int uiDefIDPoinButs(uiBlock *block, Main *bmain, ID *parid, ID **id_p, int id_code, short *pin_p, int x, int y, uiIDPoinFunc func, int events)
+{
+       ListBase *lb;
+       uiBut *but;
+       ID *id= *id_p;
+       uiIDPoinParams *params, *dup_params;
+       char *str=NULL, str1[10];
+       int len, oldcol, add_addbutton=0;
+
+       /* setup struct that we will pass on with the buttons */
+       params= MEM_callocN(sizeof(uiIDPoinParams), "uiIDPoinParams");
+       params->id_p= id_p;
+       params->id_code= id_code;
+       params->func= func;
+
+       lb= wich_libbase(bmain, id_code);
+
+       /* create buttons */
+       uiBlockBeginAlign(block);
+       oldcol= uiBlockGetCol(block);
+
+       if(id && id->us>1)
+               uiBlockSetCol(block, TH_BUT_SETTING1);
+
+       if((events & UI_ID_PIN) && *pin_p)
+               uiBlockSetCol(block, TH_BUT_SETTING2);
+
+       /* pin button */
+       if(id && (events & UI_ID_PIN)) {
+               but= uiDefIconButS(block, ICONTOG, (events & UI_ID_PIN), 0 /* XXX ICON_PIN_DEHLT */, x, y ,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, pin_p, 0, 0, 0, 0, "Keeps this view displaying the current data regardless of what object is selected");
+               uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_PIN));
+               x+= DEF_ICON_BUT_WIDTH;
+       }
+
+       /* browse menu */
+       if(events & UI_ID_BROWSE) {
+               char *extrastr= NULL;
+               
+               if(ELEM4(id_code, ID_MA, ID_TE, ID_BR, ID_PA))
+                       add_addbutton= 1;
+               
+               if(ELEM8(id_code, ID_SCE, ID_SCR, ID_MA, ID_TE, ID_WO, ID_IP, ID_AC, ID_BR) || id_code == ID_PA)
+                       extrastr= "ADD NEW %x 32767";
+               else if(id_code==ID_TXT)
+                       extrastr= "OPEN NEW %x 32766 |ADD NEW %x 32767";
+               else if(id_code==ID_SO)
+                       extrastr= "OPEN NEW %x 32766";
+
+               /* XXX should be moved out of this function
+               uiBlockSetButLock(block, G.scene->id.lib!=0, "Can't edit external libdata");
+               if( id_code==ID_SCE || id_code==ID_SCR ) uiBlockClearButLock(block); */
+               
+               /* XXX should be moved out of this function
+               if(curarea->spacetype==SPACE_BUTS)
+                       uiBlockSetButLock(block, id_code!=ID_SCR && G.obedit!=0 && G.buts->mainb==CONTEXT_EDITING, "Cannot perform in EditMode"); */
+               
+               if(parid)
+                       uiBlockSetButLock(block, parid->lib!=0, "Can't edit external libdata");
+
+               if(lb) {
+                       if(id_code!=ID_IM || (events & UI_ID_BROWSE_RENDER))
+                               IDnames_to_pupstring(&str, NULL, extrastr, lb, id, &params->browsenr);
+                       else
+                               IMAnames_to_pupstring(&str, NULL, extrastr, lb, id, &params->browsenr);
+               }
+
+               dup_params= MEM_dupallocN(params);
+               but= uiDefButS(block, MENU, 0, str, x, y, DEF_ICON_BUT_WIDTH, DEF_BUT_HEIGHT, &dup_params->browsenr, 0, 0, 0, 0, "Browse existing choices, or add new");
+               uiButSetNFunc(but, idpoin_cb, dup_params, SET_INT_IN_POINTER(UI_ID_BROWSE));
+               x+= DEF_ICON_BUT_WIDTH;
+               
+               uiBlockClearButLock(block);
+       
+               MEM_freeN(str);
+       }
+
+       uiBlockSetCol(block, oldcol);
+
+       /* text button with name */
+       if(id) {
+               /* name */
+               if(id->us > 1)
+                       uiBlockSetCol(block, TH_BUT_SETTING1);
+
+               /* pinned data? */
+               if((events & UI_ID_PIN) && *pin_p)
+                       uiBlockSetCol(block, TH_BUT_SETTING2);
+
+               /* redalert overrides pin color */
+               if(id->us<=0)
+                       uiBlockSetCol(block, TH_REDALERT);
+
+               uiBlockSetButLock(block, id->lib!=0, "Can't edit external libdata");
+               
+               /* name button */
+               if(GS(id->name)==ID_SCE)
+                       strcpy(str1, "SCE:");
+               else if(GS(id->name)==ID_SCE)
+                       strcpy(str1, "SCR:");
+               else if(GS(id->name)==ID_MA && ((Material*)id)->use_nodes)
+                       strcpy(str1, "NT:");
+               else {
+                       str1[0]= id->name[0];
+                       str1[1]= id->name[1];
+                       str1[2]= ':';
+                       str1[3]= 0;
+               }
+               
+               if(GS(id->name)==ID_IP) len= 110;
+               else if((y) && (GS(id->name)==ID_AC)) len= 100; // comes from button panel (poselib)
+               else if(y) len= 140;    // comes from button panel
+               else len= 120;
+               
+               but= uiDefBut(block, TEX, 0, str1,x, y, (short)len, DEF_BUT_HEIGHT, id->name+2, 0.0, 21.0, 0, 0, "Displays current Datablock name. Click to change.");
+               uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_RENAME));
+
+               x+= len;
+
+               uiBlockClearButLock(block);
+               
+               /* lib make local button */
+               if(id->lib) {
+                       if(id->flag & LIB_INDIRECT) uiDefIconBut(block, BUT, 0, 0 /* XXX ICON_DATALIB */,x,y,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, 0, 0, 0, 0, 0, "Indirect Library Datablock. Cannot change.");
+                       else {
+                               but= uiDefIconBut(block, BUT, 0, 0 /* XXX ICON_PARLIB */, x,y,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, 0, 0, 0, 0, 0, 
+                                                         (events & UI_ID_LOCAL)? "Direct linked Library Datablock. Click to make local.": "Direct linked Library Datablock, cannot make local.");
+                               uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_ALONE));
+                       }
+                       
+                       x+= DEF_ICON_BUT_WIDTH;
+               }
+               
+               /* number of users / make local button */
+               if((events & UI_ID_ALONE) && id->us>1) {
+                       int butwidth;
+
+                       uiBlockSetButLock(block, (events & UI_ID_PIN) && *pin_p, "Can't make pinned data single-user");
+                       
+                       sprintf(str1, "%d", id->us);
+                       butwidth= (id->us<10)? DEF_ICON_BUT_WIDTH: DEF_ICON_BUT_WIDTH+10;
+
+                       but= uiDefBut(block, BUT, 0, str1, x, y, butwidth, DEF_BUT_HEIGHT, 0, 0, 0, 0, 0, "Displays number of users of this data. Click to make a single-user copy.");
+                       uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_ALONE));
+                       x+= butwidth;
+                       
+                       uiBlockClearButLock(block);
+               }
+               
+               /* delete button */
+               if(events & UI_ID_DELETE) {
+                       uiBlockSetButLock(block, (events & UI_ID_PIN) && *pin_p, "Can't unlink pinned data");
+                       if(parid && parid->lib);
+                       else {
+                               but= uiDefIconBut(block, BUT, 0, ICON_X, x,y,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, 0, 0, 0, 0, 0, "Deletes link to this Datablock");
+                               uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_DELETE));
+                               x+= DEF_ICON_BUT_WIDTH;
+                       }
+                       
+                       uiBlockClearButLock(block);
+               }
+
+               /* auto name button */
+               if(events & UI_ID_AUTO_NAME) {
+                       if(parid && parid->lib);
+                       else {
+                               but= uiDefIconBut(block, BUT, 0, ICON_AUTO,x,y,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, 0, 0, 0, 0, 0, "Generates an automatic name");
+                               uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_AUTO_NAME));
+                               x+= DEF_ICON_BUT_WIDTH;
+                       }
+               }
+
+               /* fake user button */
+               if(events & UI_ID_FAKE_USER) {
+                       but= uiDefButBitS(block, TOG, LIB_FAKEUSER, 0, "F", x,y,DEF_ICON_BUT_WIDTH,DEF_BUT_HEIGHT, &id->flag, 0, 0, 0, 0, "Saves this datablock even if it has no users");
+                       uiButSetNFunc(but, idpoin_cb, MEM_dupallocN(params), SET_INT_IN_POINTER(UI_ID_FAKE_USER));
+                       x+= DEF_ICON_BUT_WIDTH;
+               }
+       }
+       /* add new button */
+       else if(add_addbutton) {
+               uiBlockSetCol(block, oldcol);
+               if(parid) uiBlockSetButLock(block, parid->lib!=0, "Can't edit external libdata");
+               dup_params= MEM_dupallocN(params);
+               but= uiDefButS(block, TOG, 0, "Add New", x, y, 110, DEF_BUT_HEIGHT, &dup_params->browsenr, params->browsenr, 32767.0, 0, 0, "Add new data block");
+               uiButSetNFunc(but, idpoin_cb, dup_params, SET_INT_IN_POINTER(UI_ID_ADD_NEW));
+               x+= 110;
+       }
+       
+       uiBlockSetCol(block, oldcol);
+       uiBlockEndAlign(block);
+
+       MEM_freeN(params);
+
+       return x;
+}
 
index 38f9883bdc7e5bcb62ae63ee0be2df848642958a..f1c80ed8531f782828a44adbeb816172eb6bab12 100644 (file)
@@ -885,6 +885,39 @@ static void do_image_buttons_set_uvlayer_callback(void *act, void *data)
 }
 #endif
 
+static void sima_idpoin_handle(bContext *C, ID *id, int event)
+{
+       SpaceImage *sima= (SpaceImage*)CTX_wm_space_data(C);
+       Scene *scene= CTX_data_scene(C);
+       Object *obedit= CTX_data_edit_object(C);
+
+       switch(event) {
+               case UI_ID_BROWSE:
+               case UI_ID_DELETE:
+                       set_space_image(sima, scene, obedit, sima->image);
+
+                       if(sima->image && sima->image->id.us==0)
+                               sima->image->id.us= 1;
+
+                       ED_area_tag_redraw(CTX_wm_area(C));
+                       ED_undo_push(C, "Assign Image UV");
+                       break;
+               case UI_ID_RENAME:
+                       break;
+               case UI_ID_ADD_NEW:
+                       /* XXX not implemented */
+                       break;
+               case UI_ID_OPEN:
+                       /* XXX not implemented */
+                       break;
+               case UI_ID_ALONE:
+                       /* XXX not implemented */
+                       break;
+               case UI_ID_PIN:
+                       break;
+       }
+}
+
 void image_header_buttons(const bContext *C, ARegion *ar)
 {
        bScreen *sc= CTX_wm_screen(C);
@@ -948,6 +981,11 @@ void image_header_buttons(const bContext *C, ARegion *ar)
        uiBlockSetEmboss(block, UI_EMBOSS);
 
        /* image select */
+
+       xco= uiDefIDPoinButs(block, CTX_data_main(C), NULL, (ID**)&sima->image, ID_IM, &sima->pin, xco, yco,
+               sima_idpoin_handle, UI_ID_BROWSE|UI_ID_BROWSE_RENDER|UI_ID_RENAME|UI_ID_ADD_NEW|UI_ID_OPEN|UI_ID_DELETE|UI_ID_ALONE|UI_ID_PIN);
+       xco += 8;
+
 #if 0
        char naam[256];
        
index 7929fcff716881d45573c61a1e59fc8891326ad0..0b42fb0d621a4f80370da6ed9a7ff2d3be0fdae6 100644 (file)
@@ -487,6 +487,9 @@ void set_space_image(SpaceImage *sima, Scene *scene, Object *obedit, Image *ima)
 
        if(ima == NULL || ima->type==IMA_TYPE_R_RESULT || ima->type==IMA_TYPE_COMPOSITE)
                sima->flag &= ~SI_DRAWTOOL;
+
+       if(sima->image)
+               BKE_image_signal(sima->image, &sima->iuser, IMA_SIGNAL_USER_NEW_IMAGE);
 }
 
 ImBuf *get_space_image_buffer(SpaceImage *sima)
index 35d7cb3634368250cb477b998a79d4ed5577c371..ec64d1483a1b1e09b09f0cb205ca7003280ee425 100644 (file)
@@ -356,7 +356,6 @@ void BIF_selectTransformOrientationValue(bContext *C, int orientation) {
 
 void BIF_menuTransformOrientation(bContext *C, uiMenuItem *head, void *arg)
 {
-       char menu[] = "%t|Global%x0|Local%x1|Normal%x2|View%x3";
        ListBase *transform_spaces = &CTX_data_scene(C)->transform_spaces;
        TransformOrientation *ts;
        int i= V3D_MANIP_CUSTOM;