2.5: ID datablock button back, previously known as std_libbuttons. The
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.
This commit is contained in:
@@ -30,11 +30,14 @@
|
||||
#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"
|
||||
@@ -47,6 +50,10 @@
|
||||
#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, ¶ms->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, ¶ms->browsenr);
|
||||
else
|
||||
IMAnames_to_pupstring(&str, NULL, extrastr, lb, id, ¶ms->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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user