forked from bartvdbraak/blender
2.5
Make local and make single user are back for ID template. Internally these calls got unified, id_make_local and id_copy are now used to do these operations for all types that support it. Also reveals that for some ID types the implementation is still missing. Further, some small changes: * unlink_text is now in blenkernel. * copy_group was implemented. * ID template now has an open operator again. * fix preview to not change material reference count, even if temporary it shows up with threaded preview. * id_unlink unifies unlink for text, object and group.
This commit is contained in:
parent
670296dabe
commit
5dd9f7635a
@ -74,7 +74,6 @@ struct bArmature *add_armature(char *name);
|
||||
struct bArmature *get_armature(struct Object *ob);
|
||||
void free_boneChildren(struct Bone *bone);
|
||||
void free_bones (struct bArmature *arm);
|
||||
void unlink_armature(struct bArmature *arm);
|
||||
void free_armature(struct bArmature *arm);
|
||||
void make_local_armature(struct bArmature *arm);
|
||||
struct bArmature *copy_armature(struct bArmature *arm);
|
||||
|
@ -41,6 +41,7 @@ void free_group_object(struct GroupObject *go);
|
||||
void free_group(struct Group *group);
|
||||
void unlink_group(struct Group *group);
|
||||
struct Group *add_group(char *name);
|
||||
struct Group *copy_group(struct Group *group);
|
||||
void add_to_group(struct Group *group, struct Object *ob);
|
||||
int rem_from_group(struct Group *group, struct Object *ob);
|
||||
struct Group *find_group(struct Object *ob, struct Group *group);
|
||||
|
@ -46,6 +46,9 @@ void *copy_libblock(void *rt);
|
||||
void id_lib_extern(struct ID *id);
|
||||
void id_us_plus(struct ID *id);
|
||||
void id_us_min(struct ID *id);
|
||||
int id_make_local(struct ID *id, int test);
|
||||
int id_copy(struct ID *id, struct ID **newid, int test);
|
||||
int id_unlink(struct ID *id, int test);
|
||||
|
||||
int check_for_dupid(struct ListBase *lb, struct ID *id, char *name);
|
||||
int new_id(struct ListBase *lb, struct ID *id, const char *name);
|
||||
|
@ -47,7 +47,6 @@ void unlink_actuators(struct ListBase *lb);
|
||||
void free_actuator(struct bActuator *act);
|
||||
void free_actuators(struct ListBase *lb);
|
||||
|
||||
void free_text_controllers(struct Text *txt);
|
||||
void free_sensor(struct bSensor *sens);
|
||||
void free_sensors(struct ListBase *lb);
|
||||
struct bSensor *copy_sensor(struct bSensor *sens);
|
||||
|
@ -84,7 +84,5 @@ int get_render_child_particle_number(struct RenderData *r, int num);
|
||||
int get_render_shadow_samples(struct RenderData *r, int samples);
|
||||
float get_render_aosss_error(struct RenderData *r, float error);
|
||||
|
||||
void free_dome_warp_text(struct Text *txt);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -35,6 +35,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct Main;
|
||||
struct Text;
|
||||
struct TextLine;
|
||||
struct SpaceText;
|
||||
@ -46,6 +47,7 @@ struct Text* add_empty_text (char *name);
|
||||
int reopen_text (struct Text *text);
|
||||
struct Text* add_text (char *file, const char *relpath);
|
||||
struct Text* copy_text (struct Text *ta);
|
||||
void unlink_text (struct Main *bmain, struct Text *text);
|
||||
|
||||
char* txt_to_buf (struct Text *text);
|
||||
void txt_clean_text (struct Text *text);
|
||||
|
@ -142,6 +142,16 @@ Group *add_group(char *name)
|
||||
return group;
|
||||
}
|
||||
|
||||
Group *copy_group(Group *group)
|
||||
{
|
||||
Group *groupn;
|
||||
|
||||
groupn= MEM_dupallocN(group);
|
||||
BLI_duplicatelist(&groupn->gobject, &group->gobject);
|
||||
|
||||
return groupn;
|
||||
}
|
||||
|
||||
/* external */
|
||||
void add_to_group(Group *group, Object *ob)
|
||||
{
|
||||
|
@ -119,6 +119,13 @@
|
||||
|
||||
#define MAX_IDPUP 60 /* was 24 */
|
||||
|
||||
/* GS reads the memory pointed at in a specific ordering.
|
||||
only use this definition, makes little and big endian systems
|
||||
work fine, in conjunction with MAKE_ID */
|
||||
|
||||
/* from blendef: */
|
||||
#define GS(a) (*((short *)(a)))
|
||||
|
||||
/* ************* general ************************ */
|
||||
|
||||
void id_lib_extern(ID *id)
|
||||
@ -148,6 +155,217 @@ void id_us_min(ID *id)
|
||||
id->us--;
|
||||
}
|
||||
|
||||
int id_make_local(ID *id, int test)
|
||||
{
|
||||
if(id->flag & LIB_INDIRECT)
|
||||
return 0;
|
||||
|
||||
switch(GS(id->name)) {
|
||||
case ID_SCE:
|
||||
return 0; /* not implemented */
|
||||
case ID_LI:
|
||||
return 0; /* can't be linked */
|
||||
case ID_OB:
|
||||
if(!test) make_local_object((Object*)id);
|
||||
return 1;
|
||||
case ID_ME:
|
||||
if(!test) {
|
||||
make_local_mesh((Mesh*)id);
|
||||
make_local_key(((Mesh*)id)->key);
|
||||
}
|
||||
return 1;
|
||||
case ID_CU:
|
||||
if(!test) {
|
||||
make_local_curve((Curve*)id);
|
||||
make_local_key(((Curve*)id)->key);
|
||||
}
|
||||
return 1;
|
||||
case ID_MB:
|
||||
if(!test) make_local_mball((MetaBall*)id);
|
||||
return 1;
|
||||
case ID_MA:
|
||||
if(!test) make_local_material((Material*)id);
|
||||
return 1;
|
||||
case ID_TE:
|
||||
if(!test) make_local_texture((Tex*)id);
|
||||
return 1;
|
||||
case ID_IM:
|
||||
return 0; /* not implemented */
|
||||
case ID_WV:
|
||||
return 0; /* deprecated */
|
||||
case ID_LT:
|
||||
if(!test) make_local_lattice((Lattice*)id);
|
||||
return 1;
|
||||
case ID_LA:
|
||||
if(!test) make_local_lamp((Lamp*)id);
|
||||
return 1;
|
||||
case ID_CA:
|
||||
if(!test) make_local_camera((Camera*)id);
|
||||
return 1;
|
||||
case ID_IP:
|
||||
return 0; /* deprecated */
|
||||
case ID_KE:
|
||||
if(!test) make_local_key((Key*)id);
|
||||
return 1;
|
||||
case ID_WO:
|
||||
if(!test) make_local_world((World*)id);
|
||||
return 1;
|
||||
case ID_SCR:
|
||||
return 0; /* can't be linked */
|
||||
case ID_VF:
|
||||
return 0; /* not implemented */
|
||||
case ID_TXT:
|
||||
return 0; /* not implemented */
|
||||
case ID_SCRIPT:
|
||||
return 0; /* deprecated */
|
||||
case ID_SO:
|
||||
return 0; /* not implemented */
|
||||
case ID_GR:
|
||||
return 0; /* not implemented */
|
||||
case ID_AR:
|
||||
if(!test) make_local_armature((bArmature*)id);
|
||||
return 1;
|
||||
case ID_AC:
|
||||
if(!test) make_local_action((bAction*)id);
|
||||
return 1;
|
||||
case ID_NT:
|
||||
return 0; /* not implemented */
|
||||
case ID_BR:
|
||||
if(!test) make_local_brush((Brush*)id);
|
||||
return 1;
|
||||
case ID_PA:
|
||||
if(!test) make_local_particlesettings((ParticleSettings*)id);
|
||||
return 1;
|
||||
case ID_WM:
|
||||
return 0; /* can't be linked */
|
||||
case ID_GD:
|
||||
return 0; /* not implemented */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int id_copy(ID *id, ID **newid, int test)
|
||||
{
|
||||
if(!test) *newid= NULL;
|
||||
|
||||
/* conventions:
|
||||
* - make shallow copy, only this ID block
|
||||
* - id.us of the new ID is set to 1 */
|
||||
switch(GS(id->name)) {
|
||||
case ID_SCE:
|
||||
return 0; /* can't be copied from here */
|
||||
case ID_LI:
|
||||
return 0; /* can't be copied from here */
|
||||
case ID_OB:
|
||||
if(!test) *newid= (ID*)copy_object((Object*)id);
|
||||
return 1;
|
||||
case ID_ME:
|
||||
if(!test) *newid= (ID*)copy_mesh((Mesh*)id);
|
||||
return 1;
|
||||
case ID_CU:
|
||||
if(!test) *newid= (ID*)copy_curve((Curve*)id);
|
||||
return 1;
|
||||
case ID_MB:
|
||||
if(!test) *newid= (ID*)copy_mball((MetaBall*)id);
|
||||
return 1;
|
||||
case ID_MA:
|
||||
if(!test) *newid= (ID*)copy_material((Material*)id);
|
||||
return 1;
|
||||
case ID_TE:
|
||||
if(!test) *newid= (ID*)copy_texture((Tex*)id);
|
||||
return 1;
|
||||
case ID_IM:
|
||||
return 0; /* not implemented */
|
||||
case ID_WV:
|
||||
return 0; /* deprecated */
|
||||
case ID_LT:
|
||||
if(!test) *newid= (ID*)copy_lattice((Lattice*)id);
|
||||
return 1;
|
||||
case ID_LA:
|
||||
if(!test) *newid= (ID*)copy_lamp((Lamp*)id);
|
||||
return 1;
|
||||
case ID_CA:
|
||||
if(!test) *newid= (ID*)copy_camera((Camera*)id);
|
||||
return 1;
|
||||
case ID_IP:
|
||||
return 0; /* deprecated */
|
||||
case ID_KE:
|
||||
if(!test) *newid= (ID*)copy_key((Key*)id);
|
||||
return 1;
|
||||
case ID_WO:
|
||||
if(!test) *newid= (ID*)copy_world((World*)id);
|
||||
return 1;
|
||||
case ID_SCR:
|
||||
return 0; /* can't be copied from here */
|
||||
case ID_VF:
|
||||
return 0; /* not implemented */
|
||||
case ID_TXT:
|
||||
if(!test) *newid= (ID*)copy_text((Text*)id);
|
||||
return 1;
|
||||
case ID_SCRIPT:
|
||||
return 0; /* deprecated */
|
||||
case ID_SO:
|
||||
return 0; /* not implemented */
|
||||
case ID_GR:
|
||||
if(!test) *newid= (ID*)copy_group((Group*)id);
|
||||
return 1;
|
||||
case ID_AR:
|
||||
if(!test) *newid= (ID*)copy_armature((bArmature*)id);
|
||||
return 1;
|
||||
case ID_AC:
|
||||
if(!test) *newid= (ID*)copy_action((bAction*)id);
|
||||
return 1;
|
||||
case ID_NT:
|
||||
if(!test) *newid= (ID*)ntreeCopyTree((bNodeTree*)id, 0);
|
||||
return 1;
|
||||
case ID_BR:
|
||||
if(!test) *newid= (ID*)copy_brush((Brush*)id);
|
||||
return 1;
|
||||
case ID_PA:
|
||||
if(!test) *newid= (ID*)psys_copy_settings((ParticleSettings*)id);
|
||||
return 1;
|
||||
case ID_WM:
|
||||
return 0; /* can't be copied from here */
|
||||
case ID_GD:
|
||||
return 0; /* not implemented */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int id_unlink(ID *id, int test)
|
||||
{
|
||||
Main *mainlib= G.main;
|
||||
ListBase *lb;
|
||||
|
||||
switch(GS(id->name)) {
|
||||
case ID_TXT:
|
||||
if(test) return 1;
|
||||
unlink_text(mainlib, (Text*)id);
|
||||
break;
|
||||
case ID_GR:
|
||||
if(test) return 1;
|
||||
unlink_group((Group*)id);
|
||||
break;
|
||||
case ID_OB:
|
||||
if(test) return 1;
|
||||
unlink_object(NULL, (Object*)id);
|
||||
break;
|
||||
}
|
||||
|
||||
if(id->us == 0) {
|
||||
if(test) return 1;
|
||||
|
||||
lb= wich_libbase(mainlib, GS(id->name));
|
||||
free_libblock(lb, id);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ListBase *wich_libbase(Main *mainlib, short type)
|
||||
{
|
||||
switch( type ) {
|
||||
@ -409,13 +627,6 @@ void *alloc_libblock(ListBase *lb, short type, const char *name)
|
||||
return id;
|
||||
}
|
||||
|
||||
/* GS reads the memory pointed at in a specific ordering.
|
||||
only use this definition, makes little and big endian systems
|
||||
work fine, in conjunction with MAKE_ID */
|
||||
|
||||
/* from blendef: */
|
||||
#define GS(a) (*((short *)(a)))
|
||||
|
||||
/* by spec, animdata is first item after ID */
|
||||
/* we still read ->adt itself, to ensure compiler warns when it doesnt exist */
|
||||
static void id_copy_animdata(ID *id)
|
||||
|
@ -52,30 +52,6 @@
|
||||
#include "BKE_blender.h"
|
||||
#include "BKE_sca.h"
|
||||
|
||||
//#include "wm_event_types.h"
|
||||
|
||||
void free_text_controllers(Text *txt)
|
||||
{
|
||||
Object *ob;
|
||||
bController *cont;
|
||||
|
||||
ob= G.main->object.first;
|
||||
while(ob) {
|
||||
cont= ob->controllers.first;
|
||||
while(cont) {
|
||||
if(cont->type==CONT_PYTHON) {
|
||||
bPythonCont *pc;
|
||||
|
||||
pc= cont->data;
|
||||
if(pc->text==txt) pc->text= NULL;
|
||||
}
|
||||
cont= cont->next;
|
||||
}
|
||||
ob= ob->id.next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ******************* SENSORS ************************ */
|
||||
|
||||
void free_sensor(bSensor *sens)
|
||||
|
@ -860,14 +860,3 @@ float get_render_aosss_error(RenderData *r, float error)
|
||||
return error;
|
||||
}
|
||||
|
||||
void free_dome_warp_text(struct Text *txt)
|
||||
{
|
||||
Scene *scene;
|
||||
|
||||
scene = G.main->scene.first;
|
||||
while(scene) {
|
||||
if (scene->r.dometext == txt)
|
||||
scene->r.dometext = NULL;
|
||||
scene = scene->id.next;
|
||||
}
|
||||
}
|
||||
|
@ -37,14 +37,22 @@
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
|
||||
#include "DNA_action_types.h"
|
||||
#include "DNA_armature_types.h"
|
||||
#include "DNA_constraint_types.h"
|
||||
#include "DNA_controller_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_space_types.h"
|
||||
#include "DNA_text_types.h"
|
||||
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BKE_text.h"
|
||||
#include "BKE_library.h"
|
||||
#include "BKE_depsgraph.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_library.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_text.h"
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
#include "BPY_extern.h"
|
||||
@ -451,6 +459,85 @@ Text *copy_text(Text *ta)
|
||||
return tan;
|
||||
}
|
||||
|
||||
void unlink_text(Main *bmain, Text *text)
|
||||
{
|
||||
bScreen *scr;
|
||||
ScrArea *area;
|
||||
SpaceLink *sl;
|
||||
Scene *scene;
|
||||
Object *ob;
|
||||
bController *cont;
|
||||
bConstraint *con;
|
||||
short update;
|
||||
|
||||
/* dome */
|
||||
for(scene=bmain->scene.first; scene; scene=scene->id.next)
|
||||
if(scene->r.dometext == text)
|
||||
scene->r.dometext = NULL;
|
||||
|
||||
for(ob=bmain->object.first; ob; ob=ob->id.next) {
|
||||
/* game controllers */
|
||||
for(cont=ob->controllers.first; cont; cont=cont->next) {
|
||||
if(cont->type==CONT_PYTHON) {
|
||||
bPythonCont *pc;
|
||||
|
||||
pc= cont->data;
|
||||
if(pc->text==text) pc->text= NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* pyconstraints */
|
||||
update = 0;
|
||||
|
||||
if(ob->type==OB_ARMATURE && ob->pose) {
|
||||
bPoseChannel *pchan;
|
||||
for(pchan= ob->pose->chanbase.first; pchan; pchan= pchan->next) {
|
||||
for(con = pchan->constraints.first; con; con=con->next) {
|
||||
if(con->type==CONSTRAINT_TYPE_PYTHON) {
|
||||
bPythonConstraint *data = con->data;
|
||||
if (data->text==text) data->text = NULL;
|
||||
update = 1;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(con = ob->constraints.first; con; con=con->next) {
|
||||
if(con->type==CONSTRAINT_TYPE_PYTHON) {
|
||||
bPythonConstraint *data = con->data;
|
||||
if (data->text==text) data->text = NULL;
|
||||
update = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(update)
|
||||
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
|
||||
}
|
||||
|
||||
/* pynodes */
|
||||
// XXX nodeDynamicUnlinkText(&text->id);
|
||||
|
||||
/* text space */
|
||||
for(scr= bmain->screen.first; scr; scr= scr->id.next) {
|
||||
for(area= scr->areabase.first; area; area= area->next) {
|
||||
for(sl= area->spacedata.first; sl; sl= sl->next) {
|
||||
if(sl->spacetype==SPACE_TEXT) {
|
||||
SpaceText *st= (SpaceText*) sl;
|
||||
|
||||
if(st->text==text) {
|
||||
st->text= NULL;
|
||||
st->top= 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
text->id.us= 0;
|
||||
}
|
||||
|
||||
|
||||
/*****************************/
|
||||
/* Editing utility functions */
|
||||
/*****************************/
|
||||
|
@ -238,7 +238,7 @@ static void draw_gpencil_panel (bContext *C, uiLayout *layout, bGPdata *gpd, Poi
|
||||
col= uiLayoutColumn(layout, 0);
|
||||
/* current Grease Pencil block */
|
||||
// TODO: show some info about who owns this?
|
||||
uiTemplateID(col, C, ctx_ptr, "grease_pencil", "GPENCIL_OT_data_add", "GPENCIL_OT_data_unlink");
|
||||
uiTemplateID(col, C, ctx_ptr, "grease_pencil", "GPENCIL_OT_data_add", NULL, "GPENCIL_OT_data_unlink");
|
||||
|
||||
/* add new layer button - can be used even when no data, since it can add a new block too */
|
||||
uiItemO(col, NULL, 0, "GPENCIL_OT_layer_add");
|
||||
|
@ -633,7 +633,7 @@ uiBlock *uiLayoutFreeBlock(uiLayout *layout);
|
||||
/* templates */
|
||||
void uiTemplateHeader(uiLayout *layout, struct bContext *C, int menus);
|
||||
void uiTemplateID(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname,
|
||||
char *newop, char *unlinkop);
|
||||
char *newop, char *openop, char *unlinkop);
|
||||
uiLayout *uiTemplateModifier(uiLayout *layout, struct PointerRNA *ptr);
|
||||
uiLayout *uiTemplateConstraint(uiLayout *layout, struct PointerRNA *ptr);
|
||||
void uiTemplatePreview(uiLayout *layout, struct ID *id, struct ID *parent, struct MTex *slot);
|
||||
|
@ -157,7 +157,7 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
|
||||
{
|
||||
TemplateID *template= (TemplateID*)arg_litem;
|
||||
PointerRNA idptr= RNA_property_pointer_get(&template->ptr, template->prop);
|
||||
ID *id= idptr.data;
|
||||
ID *id= idptr.data, *newid;
|
||||
int event= GET_INT_FROM_POINTER(arg_event);
|
||||
|
||||
switch(event) {
|
||||
@ -185,28 +185,48 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
|
||||
}
|
||||
else return;
|
||||
break;
|
||||
#if 0
|
||||
case UI_ID_ALONE:
|
||||
if(!id || id->us < 1)
|
||||
return;
|
||||
break;
|
||||
case UI_ID_LOCAL:
|
||||
if(!id || id->us < 1)
|
||||
return;
|
||||
if(id) {
|
||||
if(id_make_local(id, 0)) {
|
||||
/* reassign to get get proper updates/notifiers */
|
||||
idptr= RNA_property_pointer_get(&template->ptr, template->prop);
|
||||
RNA_property_pointer_set(&template->ptr, template->prop, idptr);
|
||||
RNA_property_update(C, &template->ptr, template->prop);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case UI_ID_ALONE:
|
||||
if(id) {
|
||||
/* make copy */
|
||||
if(id_copy(id, &newid, 0) && newid) {
|
||||
/* us is 1 by convention, but RNA_property_pointer_set
|
||||
will also incremement it, so set it to zero */
|
||||
newid->us= 0;
|
||||
|
||||
/* assign copy */
|
||||
RNA_id_pointer_create(newid, &idptr);
|
||||
RNA_property_pointer_set(&template->ptr, template->prop, idptr);
|
||||
RNA_property_update(C, &template->ptr, template->prop);
|
||||
}
|
||||
}
|
||||
break;
|
||||
#if 0
|
||||
case UI_ID_AUTO_NAME:
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void template_ID(bContext *C, uiBlock *block, TemplateID *template, StructRNA *type, int flag, char *newop, char *unlinkop)
|
||||
static void template_ID(bContext *C, uiBlock *block, TemplateID *template, StructRNA *type, int flag, char *newop, char *openop, char *unlinkop)
|
||||
{
|
||||
uiBut *but;
|
||||
PointerRNA idptr;
|
||||
ListBase *lb;
|
||||
ID *id, *idfrom;
|
||||
|
||||
idptr= RNA_property_pointer_get(&template->ptr, template->prop);
|
||||
id= idptr.data;
|
||||
idfrom= template->ptr.id.data;
|
||||
lb= template->idlb;
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
@ -221,33 +241,86 @@ static void template_ID(bContext *C, uiBlock *block, TemplateID *template, Struc
|
||||
but->flag|= UI_HAS_ICON;
|
||||
but->flag|= UI_ICON_LEFT;
|
||||
}
|
||||
|
||||
if((idfrom && idfrom->lib))
|
||||
uiButSetFlag(but, UI_BUT_DISABLED);
|
||||
}
|
||||
|
||||
/* text button with name */
|
||||
if(idptr.data) {
|
||||
if(id) {
|
||||
char name[64];
|
||||
|
||||
//text_idbutton(idptr.data, name);
|
||||
//text_idbutton(id, name);
|
||||
name[0]= '\0';
|
||||
but= uiDefButR(block, TEX, 0, name, 0, 0, UI_UNIT_X*6, UI_UNIT_Y, &idptr, "name", -1, 0, 0, -1, -1, NULL);
|
||||
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_RENAME));
|
||||
|
||||
if(id->lib) {
|
||||
if(id->flag & LIB_INDIRECT) {
|
||||
but= uiDefIconBut(block, BUT, 0, ICON_LIBRARY_DATA_INDIRECT, 0,0,UI_UNIT_X,UI_UNIT_Y, 0, 0, 0, 0, 0,
|
||||
"Indirect library datablock, cannot change.");
|
||||
uiButSetFlag(but, UI_BUT_DISABLED);
|
||||
}
|
||||
else {
|
||||
but= uiDefIconBut(block, BUT, 0, ICON_LIBRARY_DATA_DIRECT, 0,0,UI_UNIT_X,UI_UNIT_Y, 0, 0, 0, 0, 0,
|
||||
"Direct linked library datablock, click to make local.");
|
||||
if(!id_make_local(id, 1 /* test */) || (idfrom && idfrom->lib))
|
||||
uiButSetFlag(but, UI_BUT_DISABLED);
|
||||
}
|
||||
|
||||
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_LOCAL));
|
||||
}
|
||||
|
||||
if(id->us > 1) {
|
||||
char str[32];
|
||||
|
||||
sprintf(str, "%d", id->us);
|
||||
|
||||
if(id->us<10)
|
||||
but= uiDefBut(block, BUT, 0, str, 0,0,UI_UNIT_X,UI_UNIT_Y, 0, 0, 0, 0, 0, "Displays number of users of this data. Click to make a single-user copy.");
|
||||
else
|
||||
but= uiDefBut(block, BUT, 0, str, 0,0,UI_UNIT_X+10,UI_UNIT_Y, 0, 0, 0, 0, 0, "Displays number of users of this data. Click to make a single-user copy.");
|
||||
|
||||
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ALONE));
|
||||
if(!id_copy(id, NULL, 1 /* test only */) || (idfrom && idfrom->lib))
|
||||
uiButSetFlag(but, UI_BUT_DISABLED);
|
||||
}
|
||||
}
|
||||
|
||||
if(flag & UI_ID_ADD_NEW) {
|
||||
int w= idptr.data?UI_UNIT_X:UI_UNIT_X*6;
|
||||
int w= id?UI_UNIT_X: (flag & UI_ID_OPEN)? UI_UNIT_X*3: UI_UNIT_X*6;
|
||||
|
||||
if(newop) {
|
||||
but= uiDefIconTextButO(block, BUT, newop, WM_OP_INVOKE_REGION_WIN, ICON_ZOOMIN, (idptr.data)? "": "Add New", 0, 0, w, UI_UNIT_Y, NULL);
|
||||
but= uiDefIconTextButO(block, BUT, newop, WM_OP_INVOKE_REGION_WIN, ICON_ZOOMIN, (id)? "": "New", 0, 0, w, UI_UNIT_Y, NULL);
|
||||
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW));
|
||||
}
|
||||
else {
|
||||
but= uiDefIconTextBut(block, BUT, 0, ICON_ZOOMIN, (idptr.data)? "": "Add New", 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
|
||||
but= uiDefIconTextBut(block, BUT, 0, ICON_ZOOMIN, (id)? "": "New", 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
|
||||
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_ADD_NEW));
|
||||
}
|
||||
|
||||
if((idfrom && idfrom->lib))
|
||||
uiButSetFlag(but, UI_BUT_DISABLED);
|
||||
}
|
||||
|
||||
if(flag & UI_ID_OPEN) {
|
||||
int w= id?UI_UNIT_X: (flag & UI_ID_ADD_NEW)? UI_UNIT_X*3: UI_UNIT_X*6;
|
||||
|
||||
if(openop) {
|
||||
but= uiDefIconTextButO(block, BUT, openop, WM_OP_INVOKE_REGION_WIN, ICON_FILESEL, (id)? "": "Open", 0, 0, w, UI_UNIT_Y, NULL);
|
||||
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_OPEN));
|
||||
}
|
||||
else {
|
||||
but= uiDefIconTextBut(block, BUT, 0, ICON_FILESEL, (id)? "": "Open", 0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
|
||||
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_OPEN));
|
||||
}
|
||||
|
||||
if((idfrom && idfrom->lib))
|
||||
uiButSetFlag(but, UI_BUT_DISABLED);
|
||||
}
|
||||
|
||||
/* delete button */
|
||||
if(idptr.data && (flag & UI_ID_DELETE)) {
|
||||
if(id && (flag & UI_ID_DELETE)) {
|
||||
if(unlinkop) {
|
||||
but= uiDefIconButO(block, BUT, unlinkop, WM_OP_INVOKE_REGION_WIN, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL);
|
||||
}
|
||||
@ -255,12 +328,15 @@ static void template_ID(bContext *C, uiBlock *block, TemplateID *template, Struc
|
||||
but= uiDefIconBut(block, BUT, 0, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
|
||||
uiButSetNFunc(but, template_id_cb, MEM_dupallocN(template), SET_INT_IN_POINTER(UI_ID_DELETE));
|
||||
}
|
||||
|
||||
if((idfrom && idfrom->lib))
|
||||
uiButSetFlag(but, UI_BUT_DISABLED);
|
||||
}
|
||||
|
||||
uiBlockEndAlign(block);
|
||||
}
|
||||
|
||||
void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *unlinkop)
|
||||
void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, char *newop, char *openop, char *unlinkop)
|
||||
{
|
||||
TemplateID *template;
|
||||
uiBlock *block;
|
||||
@ -286,6 +362,8 @@ void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname
|
||||
|
||||
if(newop)
|
||||
flag |= UI_ID_ADD_NEW;
|
||||
if(openop)
|
||||
flag |= UI_ID_OPEN;
|
||||
|
||||
type= RNA_property_pointer_type(ptr, prop);
|
||||
template->idlb= wich_libbase(CTX_data_main(C), RNA_type_to_ID_code(type));
|
||||
@ -293,7 +371,7 @@ void uiTemplateID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname
|
||||
if(template->idlb) {
|
||||
uiLayoutRow(layout, 1);
|
||||
block= uiLayoutGetBlock(layout);
|
||||
template_ID(C, block, template, type, flag, newop, unlinkop);
|
||||
template_ID(C, block, template, type, flag, newop, openop, unlinkop);
|
||||
}
|
||||
|
||||
MEM_freeN(template);
|
||||
|
@ -2951,10 +2951,10 @@ static int make_proxy_invoke (bContext *C, wmOperator *op, wmEvent *evt)
|
||||
else if (ob->id.lib) {
|
||||
uiPopupMenu *pup= uiPupMenuBegin(C, "OK?", ICON_QUESTION);
|
||||
uiLayout *layout= uiPupMenuLayout(pup);
|
||||
PointerRNA props_ptr = {0};
|
||||
PointerRNA props_ptr;
|
||||
|
||||
/* create operator menu item with relevant properties filled in */
|
||||
props_ptr= uiItemFullO(layout, op->type->name, 0, op->idname, props_ptr.data, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS);
|
||||
props_ptr= uiItemFullO(layout, op->type->name, 0, op->idname, NULL, WM_OP_EXEC_REGION_WIN, UI_ITEM_O_RETURN_PROPS);
|
||||
RNA_string_set(&props_ptr, "object", ob->id.name+2);
|
||||
|
||||
/* present the menu and be done... */
|
||||
|
@ -349,8 +349,14 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
|
||||
|
||||
for(base= sce->base.first; base; base= base->next) {
|
||||
if(base->object->id.name[2]=='p') {
|
||||
if(ELEM4(base->object->type, OB_MESH, OB_CURVE, OB_SURF, OB_MBALL))
|
||||
assign_material(base->object, mat, base->object->actcol);
|
||||
if(ELEM4(base->object->type, OB_MESH, OB_CURVE, OB_SURF, OB_MBALL)) {
|
||||
/* don't use assign_material, it changed mat->id.us, which shows in the UI */
|
||||
Material ***matar= give_matarar(base->object);
|
||||
int actcol= MAX2(base->object->actcol > 0, 1) - 1;
|
||||
|
||||
if(matar && actcol < base->object->totcol)
|
||||
(*matar)[actcol]= mat;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ static void nla_panel_animdata (const bContext *C, Panel *pa)
|
||||
/* Active Action Properties ------------------------------------- */
|
||||
/* action */
|
||||
row= uiLayoutRow(layout, 1);
|
||||
uiTemplateID(row, (bContext *)C, &adt_ptr, "action", NULL, NULL/*"ACT_OT_new", "ACT_OT_unlink"*/); // XXX: need to make these operators
|
||||
uiTemplateID(row, (bContext *)C, &adt_ptr, "action", NULL /*"ACT_OT_new"*/, NULL, NULL /*"ACT_OT_unlink"*/); // XXX: need to make these operators
|
||||
|
||||
/* extrapolation */
|
||||
row= uiLayoutRow(layout, 1);
|
||||
|
@ -83,8 +83,6 @@ typedef struct FlattenString {
|
||||
int flatten_string(struct SpaceText *st, FlattenString *fs, char *in);
|
||||
void flatten_string_free(FlattenString *fs);
|
||||
|
||||
void unlink_text(struct Text *text);
|
||||
|
||||
int wrap_width(struct SpaceText *st, struct ARegion *ar);
|
||||
void wrap_offset(struct SpaceText *st, struct ARegion *ar, struct TextLine *linein, int cursin, int *offl, int *offc);
|
||||
|
||||
|
@ -273,48 +273,9 @@ void TEXT_OT_reload(wmOperatorType *ot)
|
||||
|
||||
/******************* delete operator *********************/
|
||||
|
||||
static void text_unlink(Main *bmain, Text *text)
|
||||
{
|
||||
bScreen *scr;
|
||||
ScrArea *area;
|
||||
SpaceLink *sl;
|
||||
|
||||
/* XXX this ifdef is in fact dangerous, if python is
|
||||
* disabled it will leave invalid pointers in files! */
|
||||
|
||||
#ifndef DISABLE_PYTHON
|
||||
// XXX BPY_free_pyconstraint_links(text);
|
||||
// XXX free_text_controllers(text);
|
||||
// XXX free_dome_warp_text(text);
|
||||
|
||||
/* equivalently for pynodes: */
|
||||
if(0) // XXX nodeDynamicUnlinkText ((ID*)text))
|
||||
; // XXX notifier: allqueue(REDRAWNODE, 0);
|
||||
#endif
|
||||
|
||||
for(scr= bmain->screen.first; scr; scr= scr->id.next) {
|
||||
for(area= scr->areabase.first; area; area= area->next) {
|
||||
for(sl= area->spacedata.first; sl; sl= sl->next) {
|
||||
if(sl->spacetype==SPACE_TEXT) {
|
||||
SpaceText *st= (SpaceText*) sl;
|
||||
|
||||
if(st->text==text) {
|
||||
st->text= NULL;
|
||||
st->top= 0;
|
||||
|
||||
if(st==area->spacedata.first)
|
||||
ED_area_tag_redraw(area);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free_libblock(&bmain->text, text);
|
||||
}
|
||||
|
||||
static int unlink_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Main *bmain= CTX_data_main(C);
|
||||
SpaceText *st= CTX_wm_space_text(C);
|
||||
Text *text= CTX_data_edit_text(C);
|
||||
|
||||
@ -330,7 +291,8 @@ static int unlink_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
}
|
||||
|
||||
text_unlink(CTX_data_main(C), text);
|
||||
unlink_text(bmain, text);
|
||||
free_libblock(&bmain->text, text);
|
||||
WM_event_add_notifier(C, NC_TEXT|NA_REMOVED, text);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
|
@ -247,6 +247,7 @@ void RNA_api_ui_layout(StructRNA *srna)
|
||||
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
|
||||
api_ui_item_rna_common(func);
|
||||
RNA_def_string(func, "new", "", 0, "", "Operator identifier to create a new ID block.");
|
||||
RNA_def_string(func, "open", "", 0, "", "Operator identifier to open a file for creating a new ID block.");
|
||||
RNA_def_string(func, "unlink", "", 0, "", "Operator identifier to unlink the ID block.");
|
||||
|
||||
func= RNA_def_function(srna, "template_modifier", "uiTemplateModifier");
|
||||
|
Loading…
Reference in New Issue
Block a user