forked from bartvdbraak/blender
OUTLINER_OT_scene_drop -- "Drag object to scene in Outliner" operator
Refactored the two (well, three now) other places where an object is linked to a scene into ED_object_scene_link()
This commit is contained in:
parent
a537355426
commit
e0c2ddb886
@ -86,7 +86,7 @@ extern struct EnumPropertyItem prop_make_parent_types[];
|
||||
|
||||
int ED_object_parent_set(struct ReportList *reports, struct Main *bmain, struct Scene *scene, struct Object *ob, struct Object *par, int partype);
|
||||
void ED_object_parent_clear(struct bContext *C, int type);
|
||||
|
||||
struct Base *ED_object_scene_link(struct ReportList *reports, struct Scene *scene, struct Object *ob);
|
||||
|
||||
/* generic editmode keys like pet
|
||||
* do_pet
|
||||
|
@ -1195,33 +1195,45 @@ static void link_to_scene(Main *UNUSED(bmain), unsigned short UNUSED(nr))
|
||||
}
|
||||
#endif
|
||||
|
||||
Base *ED_object_scene_link(ReportList *reports, Scene *scene, Object *ob)
|
||||
{
|
||||
Base *base;
|
||||
|
||||
if (ELEM(NULL, ob, scene)) {
|
||||
BKE_report(reports, RPT_ERROR, "Couldn't find scene");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (BKE_scene_base_find(scene, ob)) {
|
||||
BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is already in scene \"%s\"", ob->id.name + 2, scene->id.name + 2);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (scene->id.lib) {
|
||||
BKE_report(reports, RPT_ERROR, "Can't link objects into a linked scene");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
base = BKE_scene_base_add(scene, ob);
|
||||
id_us_plus(&ob->id);
|
||||
|
||||
return base;
|
||||
}
|
||||
|
||||
static int make_links_scene_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
Scene *scene_to = BLI_findlink(&CTX_data_main(C)->scene, RNA_enum_get(op->ptr, "scene"));
|
||||
|
||||
if (scene_to == NULL) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Scene not found");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
if (scene_to == CTX_data_scene(C)) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Can't link objects into the same scene");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
if (scene_to->id.lib) {
|
||||
BKE_report(op->reports, RPT_ERROR, "Can't link objects into a linked scene");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
CTX_DATA_BEGIN (C, Base *, base, selected_bases)
|
||||
{
|
||||
if (!BKE_scene_base_find(scene_to, base->object)) {
|
||||
Base *nbase = MEM_mallocN(sizeof(Base), "newbase");
|
||||
*nbase = *base;
|
||||
BLI_addhead(&(scene_to->base), nbase);
|
||||
id_us_plus((ID *)base->object);
|
||||
if (ED_object_scene_link(op->reports, scene_to, base->object) == NULL) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
}
|
||||
CTX_DATA_END;
|
||||
|
@ -1426,8 +1426,7 @@ TreeElement *outliner_dropzone_parent(bContext *C, wmEvent *event, TreeElement *
|
||||
/* name and first icon */
|
||||
if ((fmval[0] > te->xs + UI_UNIT_X) && (fmval[0] < te->xend)) {
|
||||
/* always makes active object */
|
||||
if (te->idcode == ID_OB &&
|
||||
!ELEM4(tselem->type, TSE_MODIFIER_BASE, TSE_MODIFIER, TSE_CONSTRAINT_BASE, TSE_CONSTRAINT)) {
|
||||
if (te->idcode == ID_OB && tselem->type == 0) {
|
||||
return te;
|
||||
}
|
||||
else {
|
||||
@ -1690,3 +1689,92 @@ void OUTLINER_OT_parent_clear(wmOperatorType *ot)
|
||||
RNA_def_string(ot->srna, "dragged_obj", "Object", MAX_ID_NAME, "Child", "Child Object");
|
||||
RNA_def_enum(ot->srna, "type", prop_clear_parent_types, 0, "Type", "");
|
||||
}
|
||||
|
||||
TreeElement *outliner_dropzone_scene(bContext *C, wmEvent *UNUSED(event), TreeElement *te, float *fmval)
|
||||
{
|
||||
SpaceOops *soops = CTX_wm_space_outliner(C);
|
||||
TreeStoreElem *tselem = TREESTORE(te);
|
||||
|
||||
if ((fmval[1] > te->ys) && (fmval[1] < (te->ys + UI_UNIT_Y))) {
|
||||
/* name and first icon */
|
||||
if ((fmval[0] > te->xs + UI_UNIT_X) && (fmval[0] < te->xend)) {
|
||||
if (te->idcode == ID_SCE && tselem->type == 0) {
|
||||
return te;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int scene_drop_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
{
|
||||
Scene *scene = NULL;
|
||||
Object *ob = NULL;
|
||||
SpaceOops *soops = CTX_wm_space_outliner(C);
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
Main *bmain = CTX_data_main(C);
|
||||
TreeElement *te = NULL;
|
||||
TreeElement *te_found = NULL;
|
||||
char obname[MAX_ID_NAME];
|
||||
float fmval[2];
|
||||
|
||||
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
|
||||
|
||||
/* Find object hovered over */
|
||||
for (te = soops->tree.first; te; te = te->next) {
|
||||
te_found = outliner_dropzone_scene(C, event, te, fmval);
|
||||
if (te_found)
|
||||
break;
|
||||
}
|
||||
|
||||
if (te_found) {
|
||||
Base *base;
|
||||
|
||||
RNA_string_set(op->ptr, "scene", te_found->name);
|
||||
scene = (Scene *)BKE_libblock_find_name(ID_SCE, te_found->name);
|
||||
|
||||
RNA_string_get(op->ptr, "object", obname);
|
||||
ob = (Object *)BKE_libblock_find_name(ID_OB, obname);
|
||||
|
||||
base = ED_object_scene_link(op->reports, scene, ob);
|
||||
|
||||
if (base == NULL) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
if (scene == CTX_data_scene(C)) {
|
||||
/* when linking to an inactive scene don't touch the layer */
|
||||
ob->lay = base->lay;
|
||||
ED_base_object_select(base, BA_SELECT);
|
||||
}
|
||||
|
||||
DAG_scene_sort(bmain, scene);
|
||||
DAG_ids_flush_update(bmain, 0);
|
||||
|
||||
WM_main_add_notifier(NC_SCENE | ND_OB_SELECT, scene);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
void OUTLINER_OT_scene_drop(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Drop Object to Scene";
|
||||
ot->description = "Drag object to scene in Outliner";
|
||||
ot->idname = "OUTLINER_OT_scene_drop";
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke = scene_drop_invoke;
|
||||
|
||||
ot->poll = ED_operator_outliner_active;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
/* properties */
|
||||
RNA_def_string(ot->srna, "object", "Object", MAX_ID_NAME, "Object", "Target Object");
|
||||
RNA_def_string(ot->srna, "scene", "Scene", MAX_ID_NAME, "Scene", "Target Scene");
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ void item_rename_cb(struct bContext *C, struct Scene *scene, TreeElement *te, st
|
||||
|
||||
TreeElement *outliner_dropzone_parent(struct bContext *C, struct wmEvent *event, struct TreeElement *te, float *fmval);
|
||||
int outliner_dropzone_parent_clear(struct bContext *C, struct wmEvent *event, struct TreeElement *te, float *fmval);
|
||||
|
||||
TreeElement *outliner_dropzone_scene(struct bContext *C, struct wmEvent *event, struct TreeElement *te, float *fmval);
|
||||
/* ...................................................... */
|
||||
|
||||
void OUTLINER_OT_item_activate(struct wmOperatorType *ot);
|
||||
@ -220,6 +220,7 @@ void OUTLINER_OT_drivers_delete_selected(struct wmOperatorType *ot);
|
||||
|
||||
void OUTLINER_OT_parent_drop(struct wmOperatorType *ot);
|
||||
void OUTLINER_OT_parent_clear(struct wmOperatorType *ot);
|
||||
void OUTLINER_OT_scene_drop(struct wmOperatorType *ot);
|
||||
|
||||
/* outliner_tools.c ---------------------------------------------- */
|
||||
|
||||
|
@ -76,6 +76,7 @@ void outliner_operatortypes(void)
|
||||
|
||||
WM_operatortype_append(OUTLINER_OT_parent_drop);
|
||||
WM_operatortype_append(OUTLINER_OT_parent_clear);
|
||||
WM_operatortype_append(OUTLINER_OT_scene_drop);
|
||||
}
|
||||
|
||||
void outliner_keymap(wmKeyConfig *keyconf)
|
||||
|
@ -144,6 +144,35 @@ static void outliner_parent_clear_copy(wmDrag *drag, wmDropBox *drop)
|
||||
RNA_enum_set(drop->ptr, "type", 0);
|
||||
}
|
||||
|
||||
static int outliner_scene_drop_poll(bContext *C, wmDrag *drag, wmEvent *event)
|
||||
{
|
||||
ARegion *ar = CTX_wm_region(C);
|
||||
SpaceOops *soops = CTX_wm_space_outliner(C);
|
||||
TreeElement *te = NULL;
|
||||
float fmval[2];
|
||||
UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]);
|
||||
|
||||
if (drag->type == WM_DRAG_ID) {
|
||||
ID *id = (ID *)drag->poin;
|
||||
if (GS(id->name) == ID_OB) {
|
||||
/* Ensure item under cursor is valid drop target */
|
||||
/* Find object hovered over */
|
||||
for (te = soops->tree.first; te; te = te->next) {
|
||||
if (outliner_dropzone_scene(C, event, te, fmval))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void outliner_scene_drop_copy(wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
ID *id = (ID *)drag->poin;
|
||||
|
||||
RNA_string_set(drop->ptr, "object", id->name + 2);
|
||||
}
|
||||
|
||||
/* region dropbox definition */
|
||||
static void outliner_dropboxes(void)
|
||||
{
|
||||
@ -151,6 +180,7 @@ static void outliner_dropboxes(void)
|
||||
|
||||
WM_dropbox_add(lb, "OUTLINER_OT_parent_drop", outliner_parent_drop_poll, outliner_parent_drop_copy);
|
||||
WM_dropbox_add(lb, "OUTLINER_OT_parent_clear", outliner_parent_clear_poll, outliner_parent_clear_copy);
|
||||
WM_dropbox_add(lb, "OUTLINER_OT_scene_drop", outliner_scene_drop_poll, outliner_scene_drop_copy);
|
||||
}
|
||||
|
||||
static void outliner_main_area_draw(const bContext *C, ARegion *ar)
|
||||
|
@ -304,6 +304,7 @@ EnumPropertyItem image_color_depth_items[] = {
|
||||
#include "ED_mesh.h"
|
||||
#include "ED_keyframing.h"
|
||||
#include "ED_image.h"
|
||||
#include "ED_object.h"
|
||||
|
||||
#include "RE_engine.h"
|
||||
|
||||
@ -338,24 +339,17 @@ static PointerRNA rna_Scene_objects_get(CollectionPropertyIterator *iter)
|
||||
static Base *rna_Scene_object_link(Scene *scene, bContext *C, ReportList *reports, Object *ob)
|
||||
{
|
||||
Scene *scene_act = CTX_data_scene(C);
|
||||
Base *base;
|
||||
Base *base = ED_object_scene_link(reports, scene, ob);
|
||||
|
||||
if (BKE_scene_base_find(scene, ob)) {
|
||||
BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is already in scene \"%s\"", ob->id.name + 2, scene->id.name + 2);
|
||||
if (base == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
base = BKE_scene_base_add(scene, ob);
|
||||
id_us_plus(&ob->id);
|
||||
|
||||
/* this is similar to what object_add_type and BKE_object_add do */
|
||||
base->lay = scene->lay;
|
||||
|
||||
/* when linking to an inactive scene don't touch the layer */
|
||||
if (scene == scene_act)
|
||||
ob->lay = base->lay;
|
||||
|
||||
ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
|
||||
/* ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME; */
|
||||
|
||||
/* slows down importers too much, run scene.update() */
|
||||
/* DAG_scene_sort(G.main, scene); */
|
||||
|
Loading…
Reference in New Issue
Block a user